1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// found in the LICENSE file. 4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/quic/crypto/chacha20_poly1305_encrypter.h" 6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/quic/test_tools/quic_test_utils.h" 8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)using base::StringPiece; 10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace { 12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The test vectors come from draft-agl-tls-chacha20poly1305-04 Section 7. 14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Each test vector consists of five strings of lowercase hexadecimal digits. 16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// The strings may be empty (zero length). A test vector with a NULL |key| 17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// marks the end of an array of test vectors. 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)struct TestVector { 19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* key; 20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* pt; 21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* iv; 22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* aad; 23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const char* ct; 24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)const TestVector test_vectors[] = { 27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110" 28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "0a1007", 29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "86d09974840bded2a5ca", 30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "cd7cf67be39c794a", 31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) "87e229d4500845a079c0", 32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28475" // "3896e1d6" truncated. 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) }, 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) { NULL } 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}; 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace net { 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)namespace test { 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// in an nonce and also to allocate the buffer needed for the ciphertext. 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)QuicData* EncryptWithNonce(ChaCha20Poly1305Encrypter* encrypter, 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StringPiece nonce, 46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StringPiece associated_data, 47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StringPiece plaintext) { 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length()); 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<char[]> ciphertext(new char[ciphertext_size]); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!encrypter->Encrypt(nonce, associated_data, plaintext, 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) reinterpret_cast<unsigned char*>(ciphertext.get()))) { 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return NULL; 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return new QuicData(ciphertext.release(), ciphertext_size, true); 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(ChaCha20Poly1305EncrypterTest, Encrypt) { 60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (!ChaCha20Poly1305Encrypter::IsSupported()) { 61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) LOG(INFO) << "ChaCha20+Poly1305 not supported. Test skipped."; 62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return; 63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (size_t i = 0; test_vectors[i].key != NULL; i++) { 66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Decode the test vector. 67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) string key; 68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) string pt; 69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) string iv; 70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) string aad; 71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) string ct; 72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(DecodeHexString(test_vectors[i].key, &key)); 73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(DecodeHexString(test_vectors[i].pt, &pt)); 74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(DecodeHexString(test_vectors[i].iv, &iv)); 75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(DecodeHexString(test_vectors[i].aad, &aad)); 76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(DecodeHexString(test_vectors[i].ct, &ct)); 77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ChaCha20Poly1305Encrypter encrypter; 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(encrypter.SetKey(key)); 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<QuicData> encrypted(EncryptWithNonce( 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &encrypter, iv, 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // This deliberately tests that the encrypter can handle an AAD that 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // is set to NULL, as opposed to a zero-length, non-NULL pointer. 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) StringPiece(aad.length() ? aad.data() : NULL, aad.length()), pt)); 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ASSERT_TRUE(encrypted.get()); 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) test::CompareCharArraysWithHexError("ciphertext", encrypted->data(), 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) encrypted->length(), ct.data(), 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ct.length()); 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(ChaCha20Poly1305EncrypterTest, GetMaxPlaintextSize) { 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ChaCha20Poly1305Encrypter encrypter; 95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012)); 96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112)); 97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22)); 98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)TEST(ChaCha20Poly1305EncrypterTest, GetCiphertextSize) { 101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) ChaCha20Poly1305Encrypter encrypter; 102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000)); 103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(112u, encrypter.GetCiphertextSize(100)); 104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch EXPECT_EQ(22u, encrypter.GetCiphertextSize(10)); 105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace test 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} // namespace net 109