OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "net/quic/crypto/chacha20_poly1305_decrypter.h" |
| 6 |
| 7 #include "net/quic/test_tools/quic_test_utils.h" |
| 8 |
| 9 using base::StringPiece; |
| 10 |
| 11 namespace { |
| 12 |
| 13 // The test vectors come from draft-agl-tls-chacha20poly1305-04 Section 7. |
| 14 |
| 15 // Each test vector consists of six strings of lowercase hexadecimal digits. |
| 16 // The strings may be empty (zero length). A test vector with a NULL |key| |
| 17 // marks the end of an array of test vectors. |
| 18 struct TestVector { |
| 19 // Input: |
| 20 const char* key; |
| 21 const char* iv; |
| 22 const char* aad; |
| 23 const char* ct; |
| 24 |
| 25 // Expected output: |
| 26 const char* pt; // An empty string "" means decryption succeeded and |
| 27 // the plaintext is zero-length. NULL means decryption |
| 28 // failed. |
| 29 }; |
| 30 |
| 31 const TestVector test_vectors[] = { |
| 32 { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110" |
| 33 "0a1007", |
| 34 "cd7cf67be39c794a", |
| 35 "87e229d4500845a079c0", |
| 36 "e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6", |
| 37 "86d09974840bded2a5ca" |
| 38 }, |
| 39 // Modify the ciphertext (ChaCha20 encryption output). |
| 40 { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110" |
| 41 "0a1007", |
| 42 "cd7cf67be39c794a", |
| 43 "87e229d4500845a079c0", |
| 44 "f3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6", |
| 45 NULL // FAIL |
| 46 }, |
| 47 // Modify the ciphertext (Poly1305 authenticator). |
| 48 { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110" |
| 49 "0a1007", |
| 50 "cd7cf67be39c794a", |
| 51 "87e229d4500845a079c0", |
| 52 "e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d7", |
| 53 NULL // FAIL |
| 54 }, |
| 55 // Modify the associated data. |
| 56 { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110" |
| 57 "0a1007", |
| 58 "dd7cf67be39c794a", |
| 59 "87e229d4500845a079c0", |
| 60 "e3e446f7ede9a19b62a4677dabf4e3d24b876bb284753896e1d6", |
| 61 NULL // FAIL |
| 62 }, |
| 63 { NULL } |
| 64 }; |
| 65 |
| 66 } // namespace |
| 67 |
| 68 namespace net { |
| 69 namespace test { |
| 70 |
| 71 // DecryptWithNonce wraps the |Decrypt| method of |decrypter| to allow passing |
| 72 // in an nonce and also to allocate the buffer needed for the plaintext. |
| 73 QuicData* DecryptWithNonce(ChaCha20Poly1305Decrypter* decrypter, |
| 74 StringPiece nonce, |
| 75 StringPiece associated_data, |
| 76 StringPiece ciphertext) { |
| 77 size_t plaintext_size = ciphertext.length(); |
| 78 scoped_ptr<char[]> plaintext(new char[plaintext_size]); |
| 79 |
| 80 if (!decrypter->Decrypt(nonce, associated_data, ciphertext, |
| 81 reinterpret_cast<unsigned char*>(plaintext.get()), |
| 82 &plaintext_size)) { |
| 83 return NULL; |
| 84 } |
| 85 return new QuicData(plaintext.release(), plaintext_size, true); |
| 86 } |
| 87 |
| 88 TEST(ChaCha20Poly1305DecrypterTest, Decrypt) { |
| 89 if (!ChaCha20Poly1305Decrypter::IsSupported()) { |
| 90 LOG(INFO) << "ChaCha20+Poly1305 not supported. Test skipped."; |
| 91 return; |
| 92 } |
| 93 |
| 94 for (size_t i = 0; test_vectors[i].key != NULL; i++) { |
| 95 // Decode the test vector. |
| 96 string key; |
| 97 string iv; |
| 98 string aad; |
| 99 string ct; |
| 100 string pt; |
| 101 ASSERT_TRUE(DecodeHexString(test_vectors[i].key, &key)); |
| 102 ASSERT_TRUE(DecodeHexString(test_vectors[i].iv, &iv)); |
| 103 ASSERT_TRUE(DecodeHexString(test_vectors[i].aad, &aad)); |
| 104 ASSERT_TRUE(DecodeHexString(test_vectors[i].ct, &ct)); |
| 105 if (test_vectors[i].pt) { |
| 106 ASSERT_TRUE(DecodeHexString(test_vectors[i].pt, &pt)); |
| 107 } |
| 108 |
| 109 ChaCha20Poly1305Decrypter decrypter; |
| 110 ASSERT_TRUE(decrypter.SetKey(key)); |
| 111 scoped_ptr<QuicData> decrypted(DecryptWithNonce( |
| 112 &decrypter, iv, |
| 113 // This deliberately tests that the decrypter can handle an AAD that |
| 114 // is set to NULL, as opposed to a zero-length, non-NULL pointer. |
| 115 StringPiece(aad.length() ? aad.data() : NULL, aad.length()), ct)); |
| 116 if (!decrypted.get()) { |
| 117 EXPECT_FALSE(test_vectors[i].pt); |
| 118 continue; |
| 119 } |
| 120 EXPECT_TRUE(test_vectors[i].pt); |
| 121 |
| 122 ASSERT_EQ(pt.length(), decrypted->length()); |
| 123 test::CompareCharArraysWithHexError("plaintext", decrypted->data(), |
| 124 pt.length(), pt.data(), pt.length()); |
| 125 } |
| 126 } |
| 127 |
| 128 } // namespace test |
| 129 } // namespace net |
OLD | NEW |