OLD | NEW |
---|---|
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_encrypter.h" | 5 #include "net/quic/crypto/aes_128_gcm_12_encrypter.h" |
6 | 6 |
7 #include "net/quic/test_tools/quic_test_utils.h" | 7 #include "net/quic/test_tools/quic_test_utils.h" |
8 | 8 |
9 using base::StringPiece; | 9 using base::StringPiece; |
10 | 10 |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
194 | 194 |
195 const TestVector* const test_group_array[] = { | 195 const TestVector* const test_group_array[] = { |
196 test_group_0, | 196 test_group_0, |
197 test_group_1, | 197 test_group_1, |
198 test_group_2, | 198 test_group_2, |
199 test_group_3, | 199 test_group_3, |
200 test_group_4, | 200 test_group_4, |
201 test_group_5, | 201 test_group_5, |
202 }; | 202 }; |
203 | 203 |
204 // Returns true if |ch| is a lowercase hexadecimal digit. | |
205 bool IsHexDigit(char ch) { | |
206 return ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f'); | |
207 } | |
208 | |
209 // Converts a lowercase hexadecimal digit to its integer value. | |
210 int HexDigitToInt(char ch) { | |
211 if ('0' <= ch && ch <= '9') { | |
212 return ch - '0'; | |
213 } | |
214 return ch - 'a' + 10; | |
215 } | |
216 | |
217 // |in| is a string consisting of lowercase hexadecimal digits, where | |
218 // every two digits represent one byte. |out| is a buffer of size |max_len|. | |
219 // Converts |in| to bytes and stores the bytes in the |out| buffer. The | |
220 // number of bytes converted is returned in |*out_len|. Returns true on | |
221 // success, false on failure. | |
222 bool DecodeHexString(const char* in, | |
223 char* out, | |
224 size_t* out_len, | |
225 size_t max_len) { | |
226 *out_len = 0; | |
227 while (*in != '\0') { | |
228 if (!IsHexDigit(*in) || !IsHexDigit(*(in + 1))) { | |
229 return false; | |
230 } | |
231 if (*out_len >= max_len) { | |
232 return false; | |
233 } | |
234 out[*out_len] = HexDigitToInt(*in) * 16 + HexDigitToInt(*(in + 1)); | |
235 (*out_len)++; | |
236 in += 2; | |
237 } | |
238 return true; | |
239 } | |
240 | |
241 } // namespace | 204 } // namespace |
242 | 205 |
243 namespace net { | 206 namespace net { |
244 namespace test { | 207 namespace test { |
245 | 208 |
246 // EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing | 209 // EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing |
247 // in an nonce and also to allocate the buffer needed for the ciphertext. | 210 // in an nonce and also to allocate the buffer needed for the ciphertext. |
248 QuicData* EncryptWithNonce(Aes128Gcm12Encrypter* encrypter, | 211 QuicData* EncryptWithNonce(Aes128Gcm12Encrypter* encrypter, |
249 StringPiece nonce, | 212 StringPiece nonce, |
250 StringPiece associated_data, | 213 StringPiece associated_data, |
251 StringPiece plaintext) { | 214 StringPiece plaintext) { |
252 size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length()); | 215 size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length()); |
253 scoped_ptr<char[]> ciphertext(new char[ciphertext_size]); | 216 scoped_ptr<char[]> ciphertext(new char[ciphertext_size]); |
254 | 217 |
255 if (!encrypter->Encrypt(nonce, associated_data, plaintext, | 218 if (!encrypter->Encrypt(nonce, associated_data, plaintext, |
256 reinterpret_cast<unsigned char*>(ciphertext.get()))) { | 219 reinterpret_cast<unsigned char*>(ciphertext.get()))) { |
257 return NULL; | 220 return NULL; |
258 } | 221 } |
259 | 222 |
260 return new QuicData(ciphertext.release(), ciphertext_size, true); | 223 return new QuicData(ciphertext.release(), ciphertext_size, true); |
261 } | 224 } |
262 | 225 |
263 TEST(Aes128Gcm12EncrypterTest, Encrypt) { | 226 TEST(Aes128Gcm12EncrypterTest, Encrypt) { |
264 char key[1024]; | 227 string key; |
265 size_t key_len; | 228 string iv; |
266 char iv[1024]; | 229 string pt; |
267 size_t iv_len; | 230 string aad; |
268 char pt[1024]; | 231 string ct; |
269 size_t pt_len; | 232 string tag; |
270 char aad[1024]; | |
271 size_t aad_len; | |
272 char ct[1024]; | |
273 size_t ct_len; | |
274 char tag[1024]; | |
275 size_t tag_len; | |
276 | 233 |
277 for (size_t i = 0; i < arraysize(test_group_array); i++) { | 234 for (size_t i = 0; i < arraysize(test_group_array); i++) { |
278 SCOPED_TRACE(i); | 235 SCOPED_TRACE(i); |
279 const TestVector* test_vector = test_group_array[i]; | 236 const TestVector* test_vector = test_group_array[i]; |
280 const TestGroupInfo& test_info = test_group_info[i]; | 237 const TestGroupInfo& test_info = test_group_info[i]; |
281 for (size_t j = 0; test_vector[j].key != NULL; j++) { | 238 for (size_t j = 0; test_vector[j].key != NULL; j++) { |
282 // Decode the test vector. | 239 // Decode the test vector. |
283 ASSERT_TRUE( | 240 ASSERT_TRUE(DecodeHexString(test_vector[j].key, &key)); |
284 DecodeHexString(test_vector[j].key, key, &key_len, sizeof(key))); | 241 ASSERT_TRUE(DecodeHexString(test_vector[j].iv, &iv)); |
285 ASSERT_TRUE(DecodeHexString(test_vector[j].iv, iv, &iv_len, sizeof(iv))); | 242 ASSERT_TRUE(DecodeHexString(test_vector[j].pt, &pt)); |
286 ASSERT_TRUE(DecodeHexString(test_vector[j].pt, pt, &pt_len, sizeof(pt))); | 243 ASSERT_TRUE(DecodeHexString(test_vector[j].aad, &aad)); |
287 ASSERT_TRUE( | 244 ASSERT_TRUE(DecodeHexString(test_vector[j].ct, &ct)); |
288 DecodeHexString(test_vector[j].aad, aad, &aad_len, sizeof(aad))); | 245 ASSERT_TRUE(DecodeHexString(test_vector[j].tag, &tag)); |
289 ASSERT_TRUE(DecodeHexString(test_vector[j].ct, ct, &ct_len, sizeof(ct))); | |
290 ASSERT_TRUE( | |
291 DecodeHexString(test_vector[j].tag, tag, &tag_len, sizeof(tag))); | |
292 | 246 |
293 // The test vector's lengths should look sane. Note that the lengths | 247 // The test vector's lengths should look sane. Note that the lengths |
294 // in |test_info| are in bits. | 248 // in |test_info| are in bits. |
295 EXPECT_EQ(test_info.key_len, key_len * 8); | 249 EXPECT_EQ(test_info.key_len, key.size() * 8); |
296 EXPECT_EQ(test_info.iv_len, iv_len * 8); | 250 EXPECT_EQ(test_info.iv_len, iv.size() * 8); |
297 EXPECT_EQ(test_info.pt_len, pt_len * 8); | 251 EXPECT_EQ(test_info.pt_len, pt.size() * 8); |
298 EXPECT_EQ(test_info.aad_len, aad_len * 8); | 252 EXPECT_EQ(test_info.aad_len, aad.size() * 8); |
299 EXPECT_EQ(test_info.pt_len, ct_len * 8); | 253 EXPECT_EQ(test_info.pt_len, ct.size() * 8); |
300 EXPECT_EQ(test_info.tag_len, tag_len * 8); | 254 EXPECT_EQ(test_info.tag_len, tag.size() * 8); |
301 | 255 |
302 Aes128Gcm12Encrypter encrypter; | 256 Aes128Gcm12Encrypter encrypter; |
303 ASSERT_TRUE(encrypter.SetKey(StringPiece(key, key_len))); | 257 ASSERT_TRUE(encrypter.SetKey(key)); |
304 scoped_ptr<QuicData> encrypted(EncryptWithNonce( | 258 scoped_ptr<QuicData> encrypted(EncryptWithNonce( |
305 &encrypter, StringPiece(iv, iv_len), | 259 &encrypter, iv, |
306 // OpenSSL fails if NULL is set as the AAD, as opposed to a | 260 // OpenSSL fails if NULL is set as the AAD, as opposed to a |
307 // zero-length, non-NULL pointer. This deliberately tests that we | 261 // zero-length, non-NULL pointer. This deliberately tests that we |
308 // handle this case. | 262 // handle this case. |
309 StringPiece(aad_len ? aad : NULL, aad_len), StringPiece(pt, pt_len))); | 263 aad.size() ? aad : StringPiece(), pt)); |
wtc
2013/11/04 01:58:27
I assume you verified that StringPiece() initializ
| |
310 ASSERT_TRUE(encrypted.get()); | 264 ASSERT_TRUE(encrypted.get()); |
311 | 265 |
312 // The test vectors have 16 byte authenticators but this code only uses | 266 // The test vectors have 16 byte authenticators but this code only uses |
313 // the first 12. | 267 // the first 12. |
314 ASSERT_LE(static_cast<size_t>(Aes128Gcm12Encrypter::kAuthTagSize), | 268 ASSERT_LE(static_cast<size_t>(Aes128Gcm12Encrypter::kAuthTagSize), |
315 tag_len); | 269 tag.size()); |
316 tag_len = Aes128Gcm12Encrypter::kAuthTagSize; | 270 size_t tag_len = Aes128Gcm12Encrypter::kAuthTagSize; |
317 | 271 |
318 ASSERT_EQ(ct_len + tag_len, encrypted->length()); | 272 ASSERT_EQ(ct.size() + tag_len, encrypted->length()); |
319 test::CompareCharArraysWithHexError("ciphertext", encrypted->data(), | 273 test::CompareCharArraysWithHexError("ciphertext", encrypted->data(), |
320 ct_len, ct, ct_len); | 274 ct.size(), ct.data(), ct.size()); |
321 test::CompareCharArraysWithHexError( | 275 test::CompareCharArraysWithHexError( |
322 "authentication tag", encrypted->data() + ct_len, tag_len, tag, | 276 "authentication tag", encrypted->data() + ct.size(), tag_len, |
323 tag_len); | 277 tag.data(), tag_len); |
324 } | 278 } |
325 } | 279 } |
326 } | 280 } |
327 | 281 |
328 TEST(Aes128Gcm12EncrypterTest, GetMaxPlaintextSize) { | 282 TEST(Aes128Gcm12EncrypterTest, GetMaxPlaintextSize) { |
329 Aes128Gcm12Encrypter encrypter; | 283 Aes128Gcm12Encrypter encrypter; |
330 EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012)); | 284 EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012)); |
331 EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112)); | 285 EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112)); |
332 EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22)); | 286 EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22)); |
333 } | 287 } |
334 | 288 |
335 TEST(Aes128Gcm12EncrypterTest, GetCiphertextSize) { | 289 TEST(Aes128Gcm12EncrypterTest, GetCiphertextSize) { |
336 Aes128Gcm12Encrypter encrypter; | 290 Aes128Gcm12Encrypter encrypter; |
337 EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000)); | 291 EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000)); |
338 EXPECT_EQ(112u, encrypter.GetCiphertextSize(100)); | 292 EXPECT_EQ(112u, encrypter.GetCiphertextSize(100)); |
339 EXPECT_EQ(22u, encrypter.GetCiphertextSize(10)); | 293 EXPECT_EQ(22u, encrypter.GetCiphertextSize(10)); |
340 } | 294 } |
341 | 295 |
342 } // namespace test | 296 } // namespace test |
343 } // namespace net | 297 } // namespace net |
OLD | NEW |