Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(263)

Side by Side Diff: net/quic/crypto/aead_base_decrypter_nss.cc

Issue 189893002: Add ChaCha20Poly1305Encrypter, based on (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Export AeadBase*crypter Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/crypto/aes_128_gcm_12_decrypter.h" 5 #include "net/quic/crypto/aead_base_decrypter.h"
6 6
7 #include <nss.h> 7 #include <nss.h>
8 #include <pk11pub.h> 8 #include <pk11pub.h>
9 #include <secerr.h> 9 #include <secerr.h>
10 10
11 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "crypto/ghash.h" 13 #include "crypto/ghash.h"
14 #include "crypto/scoped_nss_types.h" 14 #include "crypto/scoped_nss_types.h"
15 15
16 #if defined(USE_NSS) 16 #if defined(USE_NSS)
17 #include <dlfcn.h> 17 #include <dlfcn.h>
18 #endif 18 #endif
19 19
20 using base::StringPiece; 20 using base::StringPiece;
21 21
22 namespace net { 22 namespace net {
23 23
24 namespace { 24 namespace {
25 25
26 // The pkcs11t.h header in NSS versions older than 3.14 does not have the CTR
27 // and GCM types, so define them here.
28 #if !defined(CKM_AES_CTR)
29 #define CKM_AES_CTR 0x00001086
30 #define CKM_AES_GCM 0x00001087
31
32 struct CK_AES_CTR_PARAMS {
33 CK_ULONG ulCounterBits;
34 CK_BYTE cb[16];
35 };
36
37 struct CK_GCM_PARAMS {
38 CK_BYTE_PTR pIv;
39 CK_ULONG ulIvLen;
40 CK_BYTE_PTR pAAD;
41 CK_ULONG ulAADLen;
42 CK_ULONG ulTagBits;
43 };
44 #endif // CKM_AES_CTR
45
46 typedef SECStatus 26 typedef SECStatus
47 (*PK11_DecryptFunction)( 27 (*PK11_DecryptFunction)(
48 PK11SymKey* symKey, CK_MECHANISM_TYPE mechanism, SECItem* param, 28 PK11SymKey* symKey, CK_MECHANISM_TYPE mechanism, SECItem* param,
49 unsigned char* out, unsigned int* outLen, unsigned int maxLen, 29 unsigned char* out, unsigned int* outLen, unsigned int maxLen,
50 const unsigned char* enc, unsigned encLen); 30 const unsigned char* enc, unsigned encLen);
51 31
52 // On Linux, dynamically link against the system version of libnss3.so. In 32 // On Linux, dynamically link against the system version of libnss3.so. In
53 // order to continue working on systems without up-to-date versions of NSS, 33 // order to continue working on systems without up-to-date versions of NSS,
54 // lookup PK11_Decrypt with dlsym. 34 // lookup PK11_Decrypt with dlsym.
55 35
56 // GcmSupportChecker is a singleton which caches the results of runtime symbol 36 // AeadSupportChecker is a singleton which caches the results of runtime symbol
57 // resolution of PK11_Decrypt. 37 // resolution of PK11_Decrypt.
58 class GcmSupportChecker { 38 class AeadSupportChecker {
59 public: 39 public:
60 static PK11_DecryptFunction pk11_decrypt_func() { 40 static PK11_DecryptFunction pk11_decrypt_func() {
61 return pk11_decrypt_func_; 41 return pk11_decrypt_func_;
62 } 42 }
63 43
64 static CK_MECHANISM_TYPE aes_key_mechanism() { 44 private:
65 return aes_key_mechanism_; 45 friend struct base::DefaultLazyInstanceTraits<AeadSupportChecker>;
66 }
67 46
68 private: 47 AeadSupportChecker() {
69 friend struct base::DefaultLazyInstanceTraits<GcmSupportChecker>;
70
71 GcmSupportChecker() {
72 #if !defined(USE_NSS) 48 #if !defined(USE_NSS)
73 // Using a bundled version of NSS that is guaranteed to have this symbol. 49 // Using a bundled version of NSS that is guaranteed to have this symbol.
74 pk11_decrypt_func_ = PK11_Decrypt; 50 pk11_decrypt_func_ = PK11_Decrypt;
75 #else 51 #else
76 // Using system NSS libraries and PCKS #11 modules, which may not have the 52 // Using system NSS libraries and PCKS #11 modules, which may not have the
77 // necessary function (PK11_Decrypt) or mechanism support (CKM_AES_GCM). 53 // necessary function (PK11_Decrypt) or mechanism support (CKM_AES_GCM).
78 54
79 // If PK11_Decrypt() was successfully resolved, then NSS will support 55 // If PK11_Decrypt() was successfully resolved, then NSS will support
80 // AES-GCM directly. This was introduced in NSS 3.15. 56 // AES-GCM directly. This was introduced in NSS 3.15.
81 pk11_decrypt_func_ = (PK11_DecryptFunction)dlsym(RTLD_DEFAULT, 57 pk11_decrypt_func_ = (PK11_DecryptFunction)dlsym(RTLD_DEFAULT,
82 "PK11_Decrypt"); 58 "PK11_Decrypt");
83 if (pk11_decrypt_func_ == NULL) {
84 aes_key_mechanism_ = CKM_AES_ECB;
85 }
86 #endif 59 #endif
87 } 60 }
88 61
89 // |pk11_decrypt_func_| stores the runtime symbol resolution of PK11_Decrypt. 62 // |pk11_decrypt_func_| stores the runtime symbol resolution of PK11_Decrypt.
90 static PK11_DecryptFunction pk11_decrypt_func_; 63 static PK11_DecryptFunction pk11_decrypt_func_;
91
92 // The correct value for |aes_key_mechanism_| is CKM_AES_GCM, but because of
93 // NSS bug https://bugzilla.mozilla.org/show_bug.cgi?id=853285 (to be fixed in
94 // NSS 3.15), use CKM_AES_ECB for NSS versions older than 3.15.
95 static CK_MECHANISM_TYPE aes_key_mechanism_;
96 }; 64 };
97 65
98 // static 66 // static
99 PK11_DecryptFunction GcmSupportChecker::pk11_decrypt_func_ = NULL; 67 PK11_DecryptFunction AeadSupportChecker::pk11_decrypt_func_ = NULL;
100 68
101 // static 69 base::LazyInstance<AeadSupportChecker>::Leaky g_gcm_support_checker =
102 CK_MECHANISM_TYPE GcmSupportChecker::aes_key_mechanism_ = CKM_AES_GCM;
103
104 base::LazyInstance<GcmSupportChecker>::Leaky g_gcm_support_checker =
105 LAZY_INSTANCE_INITIALIZER; 70 LAZY_INSTANCE_INITIALIZER;
106 71
107 const size_t kNoncePrefixSize = 4;
108 const size_t kAESNonceSize = 12;
109
110 // Calls PK11_Decrypt if it's available. Otherwise, emulates CKM_AES_GCM using 72 // Calls PK11_Decrypt if it's available. Otherwise, emulates CKM_AES_GCM using
111 // CKM_AES_CTR and the GaloisHash class. 73 // CKM_AES_CTR and the GaloisHash class.
112 SECStatus My_Decrypt(PK11SymKey* key, 74 SECStatus My_Decrypt(PK11SymKey* key,
113 CK_MECHANISM_TYPE mechanism, 75 CK_MECHANISM_TYPE mechanism,
114 SECItem* param, 76 SECItem* param,
115 unsigned char* out, 77 unsigned char* out,
116 unsigned int* out_len, 78 unsigned int* out_len,
117 unsigned int max_len, 79 unsigned int max_len,
118 const unsigned char* enc, 80 const unsigned char* enc,
119 unsigned int enc_len) { 81 unsigned int enc_len) {
120 // If PK11_Decrypt() was successfully resolved or if bundled version of NSS is 82 // If PK11_Decrypt() was successfully resolved or if bundled version of NSS is
121 // being used, then NSS will support AES-GCM directly. 83 // being used, use PK11_Decrypt().
122 PK11_DecryptFunction pk11_decrypt_func = 84 PK11_DecryptFunction pk11_decrypt_func =
123 GcmSupportChecker::pk11_decrypt_func(); 85 AeadSupportChecker::pk11_decrypt_func();
124 if (pk11_decrypt_func != NULL) { 86 if (pk11_decrypt_func != NULL) {
125 return pk11_decrypt_func(key, mechanism, param, out, out_len, max_len, enc, 87 return pk11_decrypt_func(key, mechanism, param, out, out_len, max_len, enc,
126 enc_len); 88 enc_len);
127 } 89 }
128 90
129 // Otherwise, the user has an older version of NSS. Regrettably, NSS 3.14.x 91 // Otherwise, the user has an older version of NSS. Regrettably, NSS 3.14.x
130 // has a bug in the AES GCM code 92 // has a bug in the AES GCM code
131 // (https://bugzilla.mozilla.org/show_bug.cgi?id=853285), as well as missing 93 // (https://bugzilla.mozilla.org/show_bug.cgi?id=853285), as well as missing
132 // the PK11_Decrypt function 94 // the PK11_Decrypt function
133 // (https://bugzilla.mozilla.org/show_bug.cgi?id=854063), both of which are 95 // (https://bugzilla.mozilla.org/show_bug.cgi?id=854063), both of which are
134 // resolved in NSS 3.15. 96 // resolved in NSS 3.15.
135 97
136 DCHECK_EQ(mechanism, static_cast<CK_MECHANISM_TYPE>(CKM_AES_GCM)); 98 DCHECK_EQ(mechanism, static_cast<CK_MECHANISM_TYPE>(CKM_AES_GCM));
137 DCHECK_EQ(param->len, sizeof(CK_GCM_PARAMS)); 99 DCHECK_EQ(param->len, sizeof(CK_GCM_PARAMS));
138 100
139 const CK_GCM_PARAMS* gcm_params = 101 const CK_GCM_PARAMS* gcm_params =
agl 2014/03/10 15:08:33 This is GCM specific code in the AEAD base class?
wtc 2014/03/11 04:02:02 OK, I figured out a way to keep the GCM-specific c
140 reinterpret_cast<CK_GCM_PARAMS*>(param->data); 102 reinterpret_cast<CK_GCM_PARAMS*>(param->data);
141 103
142 DCHECK_EQ(gcm_params->ulTagBits, 104 const unsigned int auth_tag_size = gcm_params->ulTagBits / 8;
143 static_cast<CK_ULONG>(Aes128Gcm12Decrypter::kAuthTagSize * 8)); 105 if (auth_tag_size > 16) {
106 PORT_SetError(SEC_ERROR_INPUT_LEN);
107 return SECFailure;
108 }
144 if (gcm_params->ulIvLen != 12u) { 109 if (gcm_params->ulIvLen != 12u) {
145 DVLOG(1) << "ulIvLen is not equal to 12"; 110 DVLOG(1) << "ulIvLen is not equal to 12";
146 PORT_SetError(SEC_ERROR_INPUT_LEN); 111 PORT_SetError(SEC_ERROR_INPUT_LEN);
147 return SECFailure; 112 return SECFailure;
148 } 113 }
149 114
150 SECItem my_param = { siBuffer, NULL, 0 }; 115 SECItem my_param = { siBuffer, NULL, 0 };
151 116
152 // Step 2. Let H = CIPH_K(128 '0' bits). 117 // Step 2. Let H = CIPH_K(128 '0' bits).
153 unsigned char ghash_key[16] = {0}; 118 unsigned char ghash_key[16] = {0};
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 tag_mask, sizeof(tag_mask)) != SECSuccess) { 163 tag_mask, sizeof(tag_mask)) != SECSuccess) {
199 DVLOG(1) << "PK11_CipherOp failed"; 164 DVLOG(1) << "PK11_CipherOp failed";
200 return SECFailure; 165 return SECFailure;
201 } 166 }
202 if (output_len != sizeof(tag_mask)) { 167 if (output_len != sizeof(tag_mask)) {
203 DVLOG(1) << "Wrong output length"; 168 DVLOG(1) << "Wrong output length";
204 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 169 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
205 return SECFailure; 170 return SECFailure;
206 } 171 }
207 172
208 if (enc_len < Aes128Gcm12Decrypter::kAuthTagSize) { 173 if (enc_len < auth_tag_size) {
209 PORT_SetError(SEC_ERROR_INPUT_LEN); 174 PORT_SetError(SEC_ERROR_INPUT_LEN);
210 return SECFailure; 175 return SECFailure;
211 } 176 }
212 177
213 // The const_cast for |enc| can be removed if system NSS libraries are 178 // The const_cast for |enc| can be removed if system NSS libraries are
214 // NSS 3.14.1 or later (NSS bug 179 // NSS 3.14.1 or later (NSS bug
215 // https://bugzilla.mozilla.org/show_bug.cgi?id=808218). 180 // https://bugzilla.mozilla.org/show_bug.cgi?id=808218).
216 if (PK11_CipherOp(ctx.get(), out, &output_len, max_len, 181 if (PK11_CipherOp(ctx.get(), out, &output_len, max_len,
217 const_cast<unsigned char*>(enc), 182 const_cast<unsigned char*>(enc),
218 enc_len - Aes128Gcm12Decrypter::kAuthTagSize) != SECSuccess) { 183 enc_len - auth_tag_size) != SECSuccess) {
219 DVLOG(1) << "PK11_CipherOp failed"; 184 DVLOG(1) << "PK11_CipherOp failed";
220 return SECFailure; 185 return SECFailure;
221 } 186 }
222 187
223 PK11_Finalize(ctx.get()); 188 PK11_Finalize(ctx.get());
224 189
225 if (static_cast<unsigned int>(output_len) != 190 if (static_cast<unsigned int>(output_len) != enc_len - auth_tag_size) {
226 enc_len - Aes128Gcm12Decrypter::kAuthTagSize) {
227 DVLOG(1) << "Wrong output length"; 191 DVLOG(1) << "Wrong output length";
228 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE); 192 PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
229 return SECFailure; 193 return SECFailure;
230 } 194 }
231 195
232 crypto::GaloisHash ghash(ghash_key); 196 crypto::GaloisHash ghash(ghash_key);
233 ghash.UpdateAdditional(gcm_params->pAAD, gcm_params->ulAADLen); 197 ghash.UpdateAdditional(gcm_params->pAAD, gcm_params->ulAADLen);
234 ghash.UpdateCiphertext(enc, output_len); 198 ghash.UpdateCiphertext(enc, output_len);
235 unsigned char auth_tag[Aes128Gcm12Decrypter::kAuthTagSize]; 199 unsigned char auth_tag[16];
236 ghash.Finish(auth_tag, Aes128Gcm12Decrypter::kAuthTagSize); 200 ghash.Finish(auth_tag, auth_tag_size);
237 for (unsigned int i = 0; i < Aes128Gcm12Decrypter::kAuthTagSize; i++) { 201 for (unsigned int i = 0; i < auth_tag_size; i++) {
238 auth_tag[i] ^= tag_mask[i]; 202 auth_tag[i] ^= tag_mask[i];
239 } 203 }
240 204
241 if (NSS_SecureMemcmp(auth_tag, enc + output_len, 205 if (NSS_SecureMemcmp(auth_tag, enc + output_len, auth_tag_size) != 0) {
242 Aes128Gcm12Decrypter::kAuthTagSize) != 0) {
243 PORT_SetError(SEC_ERROR_BAD_DATA); 206 PORT_SetError(SEC_ERROR_BAD_DATA);
244 return SECFailure; 207 return SECFailure;
245 } 208 }
246 209
247 *out_len = output_len; 210 *out_len = output_len;
248 return SECSuccess; 211 return SECSuccess;
249 } 212 }
250 213
251 } // namespace 214 } // namespace
252 215
253 Aes128Gcm12Decrypter::Aes128Gcm12Decrypter() { 216 AeadBaseDecrypter::AeadBaseDecrypter(CK_MECHANISM_TYPE aead_mechanism,
217 size_t key_size,
218 size_t auth_tag_size,
219 size_t nonce_prefix_size)
220 : aead_mechanism_(aead_mechanism),
221 key_size_(key_size),
222 auth_tag_size_(auth_tag_size),
223 nonce_prefix_size_(nonce_prefix_size) {
224 DCHECK_LE(key_size_, sizeof(key_));
225 DCHECK_LE(nonce_prefix_size_, sizeof(nonce_prefix_));
254 ignore_result(g_gcm_support_checker.Get()); 226 ignore_result(g_gcm_support_checker.Get());
255 } 227 }
256 228
257 Aes128Gcm12Decrypter::~Aes128Gcm12Decrypter() {} 229 AeadBaseDecrypter::~AeadBaseDecrypter() {}
258 230
259 // static 231 bool AeadBaseDecrypter::SetKey(StringPiece key) {
260 bool Aes128Gcm12Decrypter::IsSupported() { 232 DCHECK_EQ(key.size(), key_size_);
261 // NSS 3.15 supports CKM_AES_GCM directly. 233 if (key.size() != key_size_) {
262 // NSS 3.14 supports CKM_AES_CTR, which can be used to emulate CKM_AES_GCM.
263 // Versions earlier than NSS 3.14 are not supported.
264 return NSS_VersionCheck("3.14") != PR_FALSE;
265 }
266
267 bool Aes128Gcm12Decrypter::SetKey(StringPiece key) {
268 DCHECK_EQ(key.size(), sizeof(key_));
269 if (key.size() != sizeof(key_)) {
270 return false; 234 return false;
271 } 235 }
272 memcpy(key_, key.data(), key.size()); 236 memcpy(key_, key.data(), key.size());
273 return true; 237 return true;
274 } 238 }
275 239
276 bool Aes128Gcm12Decrypter::SetNoncePrefix(StringPiece nonce_prefix) { 240 bool AeadBaseDecrypter::SetNoncePrefix(StringPiece nonce_prefix) {
277 DCHECK_EQ(nonce_prefix.size(), kNoncePrefixSize); 241 DCHECK_EQ(nonce_prefix.size(), nonce_prefix_size_);
278 if (nonce_prefix.size() != kNoncePrefixSize) { 242 if (nonce_prefix.size() != nonce_prefix_size_) {
279 return false; 243 return false;
280 } 244 }
281 COMPILE_ASSERT(sizeof(nonce_prefix_) == kNoncePrefixSize, bad_nonce_length);
282 memcpy(nonce_prefix_, nonce_prefix.data(), nonce_prefix.size()); 245 memcpy(nonce_prefix_, nonce_prefix.data(), nonce_prefix.size());
283 return true; 246 return true;
284 } 247 }
285 248
286 bool Aes128Gcm12Decrypter::Decrypt(StringPiece nonce, 249 bool AeadBaseDecrypter::Decrypt(StringPiece nonce,
287 StringPiece associated_data, 250 StringPiece associated_data,
288 StringPiece ciphertext, 251 StringPiece ciphertext,
289 uint8* output, 252 uint8* output,
290 size_t* output_length) { 253 size_t* output_length) {
291 if (ciphertext.length() < kAuthTagSize || 254 if (ciphertext.length() < auth_tag_size_ ||
292 nonce.size() != kNoncePrefixSize + sizeof(QuicPacketSequenceNumber)) { 255 nonce.size() != nonce_prefix_size_ + sizeof(QuicPacketSequenceNumber)) {
293 return false; 256 return false;
294 } 257 }
295 // NSS 3.14.x incorrectly requires an output buffer at least as long as 258 // NSS 3.14.x incorrectly requires an output buffer at least as long as
296 // the ciphertext (NSS bug 259 // the ciphertext (NSS bug
297 // https://bugzilla.mozilla.org/show_bug.cgi?id= 853674). Fortunately 260 // https://bugzilla.mozilla.org/show_bug.cgi?id= 853674). Fortunately
298 // QuicDecrypter::Decrypt() specifies that |output| must be as long as 261 // QuicDecrypter::Decrypt() specifies that |output| must be as long as
299 // |ciphertext| on entry. 262 // |ciphertext| on entry.
300 size_t plaintext_size = ciphertext.length() - kAuthTagSize; 263 size_t plaintext_size = ciphertext.length() - auth_tag_size_;
301 264
302 // Import key_ into NSS. 265 // Import key_ into NSS.
303 SECItem key_item; 266 SECItem key_item;
304 key_item.type = siBuffer; 267 key_item.type = siBuffer;
305 key_item.data = key_; 268 key_item.data = key_;
306 key_item.len = sizeof(key_); 269 key_item.len = key_size_;
307 PK11SlotInfo* slot = PK11_GetInternalSlot(); 270 PK11SlotInfo* slot = PK11_GetInternalSlot();
271
272 // TODO(wtc): For an AES-GCM key, the correct value for |key_mechanism| is
273 // CKM_AES_GCM, but because of NSS bug
274 // https://bugzilla.mozilla.org/show_bug.cgi?id=853285, use CKM_AES_ECB as a
275 // workaround. Remove this when we require NSS 3.15.
276 CK_MECHANISM_TYPE key_mechanism = aead_mechanism_;
277 if (key_mechanism == CKM_AES_GCM) {
278 key_mechanism = CKM_AES_ECB;
279 }
280
308 // The exact value of the |origin| argument doesn't matter to NSS as long as 281 // The exact value of the |origin| argument doesn't matter to NSS as long as
309 // it's not PK11_OriginFortezzaHack, so pass PK11_OriginUnwrap as a 282 // it's not PK11_OriginFortezzaHack, so pass PK11_OriginUnwrap as a
310 // placeholder. 283 // placeholder.
311 crypto::ScopedPK11SymKey aes_key(PK11_ImportSymKey( 284 crypto::ScopedPK11SymKey aead_key(PK11_ImportSymKey(
312 slot, GcmSupportChecker::aes_key_mechanism(), PK11_OriginUnwrap, 285 slot, key_mechanism, PK11_OriginUnwrap, CKA_DECRYPT, &key_item, NULL));
313 CKA_DECRYPT, &key_item, NULL));
314 PK11_FreeSlot(slot); 286 PK11_FreeSlot(slot);
315 slot = NULL; 287 slot = NULL;
316 if (!aes_key) { 288 if (!aead_key) {
317 DVLOG(1) << "PK11_ImportSymKey failed"; 289 DVLOG(1) << "PK11_ImportSymKey failed";
318 return false; 290 return false;
319 } 291 }
320 292
321 CK_GCM_PARAMS gcm_params = {0}; 293 AeadParams aead_params = {0};
322 gcm_params.pIv = 294 FillAeadParams(nonce, associated_data, auth_tag_size_, &aead_params);
323 reinterpret_cast<CK_BYTE*>(const_cast<char*>(nonce.data()));
324 gcm_params.ulIvLen = nonce.size();
325 gcm_params.pAAD =
326 reinterpret_cast<CK_BYTE*>(const_cast<char*>(associated_data.data()));
327 gcm_params.ulAADLen = associated_data.size();
328 gcm_params.ulTagBits = kAuthTagSize * 8;
329 295
330 SECItem param; 296 SECItem param;
331 param.type = siBuffer; 297 param.type = siBuffer;
332 param.data = reinterpret_cast<unsigned char*>(&gcm_params); 298 param.data = reinterpret_cast<unsigned char*>(&aead_params.data);
333 param.len = sizeof(gcm_params); 299 param.len = aead_params.len;
334 300
335 unsigned int output_len; 301 unsigned int output_len;
336 if (My_Decrypt(aes_key.get(), CKM_AES_GCM, &param, 302 if (My_Decrypt(aead_key.get(), aead_mechanism_, &param,
337 output, &output_len, ciphertext.length(), 303 output, &output_len, ciphertext.length(),
338 reinterpret_cast<const unsigned char*>(ciphertext.data()), 304 reinterpret_cast<const unsigned char*>(ciphertext.data()),
339 ciphertext.length()) != SECSuccess) { 305 ciphertext.length()) != SECSuccess) {
340 return false; 306 return false;
341 } 307 }
342 308
343 if (output_len != plaintext_size) { 309 if (output_len != plaintext_size) {
344 DVLOG(1) << "Wrong output length"; 310 DVLOG(1) << "Wrong output length";
345 return false; 311 return false;
346 } 312 }
347 *output_length = output_len; 313 *output_length = output_len;
348 return true; 314 return true;
349 } 315 }
350 316
351 QuicData* Aes128Gcm12Decrypter::DecryptPacket( 317 QuicData* AeadBaseDecrypter::DecryptPacket(
352 QuicPacketSequenceNumber sequence_number, 318 QuicPacketSequenceNumber sequence_number,
353 StringPiece associated_data, 319 StringPiece associated_data,
354 StringPiece ciphertext) { 320 StringPiece ciphertext) {
355 if (ciphertext.length() < kAuthTagSize) { 321 if (ciphertext.length() < auth_tag_size_) {
356 return NULL; 322 return NULL;
357 } 323 }
358 size_t plaintext_size; 324 size_t plaintext_size;
359 scoped_ptr<char[]> plaintext(new char[ciphertext.length()]); 325 scoped_ptr<char[]> plaintext(new char[ciphertext.length()]);
360 326
361 uint8 nonce[kNoncePrefixSize + sizeof(sequence_number)]; 327 uint8 nonce[sizeof(nonce_prefix_) + sizeof(sequence_number)];
362 COMPILE_ASSERT(sizeof(nonce) == kAESNonceSize, bad_sequence_number_size); 328 const size_t nonce_size = nonce_prefix_size_ + sizeof(sequence_number);
363 memcpy(nonce, nonce_prefix_, kNoncePrefixSize); 329 DCHECK_LE(nonce_size, sizeof(nonce));
364 memcpy(nonce + kNoncePrefixSize, &sequence_number, sizeof(sequence_number)); 330 memcpy(nonce, nonce_prefix_, nonce_prefix_size_);
365 if (!Decrypt(StringPiece(reinterpret_cast<char*>(nonce), sizeof(nonce)), 331 memcpy(nonce + nonce_prefix_size_, &sequence_number, sizeof(sequence_number));
332 if (!Decrypt(StringPiece(reinterpret_cast<char*>(nonce), nonce_size),
366 associated_data, ciphertext, 333 associated_data, ciphertext,
367 reinterpret_cast<uint8*>(plaintext.get()), 334 reinterpret_cast<uint8*>(plaintext.get()),
368 &plaintext_size)) { 335 &plaintext_size)) {
369 return NULL; 336 return NULL;
370 } 337 }
371 return new QuicData(plaintext.release(), plaintext_size, true); 338 return new QuicData(plaintext.release(), plaintext_size, true);
372 } 339 }
373 340
374 StringPiece Aes128Gcm12Decrypter::GetKey() const { 341 StringPiece AeadBaseDecrypter::GetKey() const {
375 return StringPiece(reinterpret_cast<const char*>(key_), sizeof(key_)); 342 return StringPiece(reinterpret_cast<const char*>(key_), key_size_);
376 } 343 }
377 344
378 StringPiece Aes128Gcm12Decrypter::GetNoncePrefix() const { 345 StringPiece AeadBaseDecrypter::GetNoncePrefix() const {
346 if (nonce_prefix_size_ == 0) {
347 return StringPiece();
348 }
379 return StringPiece(reinterpret_cast<const char*>(nonce_prefix_), 349 return StringPiece(reinterpret_cast<const char*>(nonce_prefix_),
380 kNoncePrefixSize); 350 nonce_prefix_size_);
381 } 351 }
382 352
383 } // namespace net 353 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698