1 // Copyright 2014 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.
5 #include "net/quic/crypto/chacha20_poly1305_encrypter.h"
7 #include "net/quic/test_tools/quic_test_utils.h"
9 using base::StringPiece
;
14 // The test vectors come from draft-agl-tls-chacha20poly1305-04 Section 7.
16 // Each test vector consists of five strings of lowercase hexadecimal digits.
17 // The strings may be empty (zero length). A test vector with a NULL |key|
18 // marks the end of an array of test vectors.
27 const TestVector test_vectors
[] = {
28 { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
30 "86d09974840bded2a5ca",
32 "87e229d4500845a079c0",
33 "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28475" // "3896e1d6" truncated.
43 // EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
44 // in an nonce and also to allocate the buffer needed for the ciphertext.
45 QuicData
* EncryptWithNonce(ChaCha20Poly1305Encrypter
* encrypter
,
47 StringPiece associated_data
,
48 StringPiece plaintext
) {
49 size_t ciphertext_size
= encrypter
->GetCiphertextSize(plaintext
.length());
50 scoped_ptr
<char[]> ciphertext(new char[ciphertext_size
]);
52 if (!encrypter
->Encrypt(nonce
, associated_data
, plaintext
,
53 reinterpret_cast<unsigned char*>(ciphertext
.get()))) {
57 return new QuicData(ciphertext
.release(), ciphertext_size
, true);
60 TEST(ChaCha20Poly1305EncrypterTest
, Encrypt
) {
61 if (!ChaCha20Poly1305Encrypter::IsSupported()) {
62 LOG(INFO
) << "ChaCha20+Poly1305 not supported. Test skipped.";
66 for (size_t i
= 0; test_vectors
[i
].key
!= nullptr; i
++) {
67 // Decode the test vector.
73 ASSERT_TRUE(DecodeHexString(test_vectors
[i
].key
, &key
));
74 ASSERT_TRUE(DecodeHexString(test_vectors
[i
].pt
, &pt
));
75 ASSERT_TRUE(DecodeHexString(test_vectors
[i
].iv
, &iv
));
76 ASSERT_TRUE(DecodeHexString(test_vectors
[i
].aad
, &aad
));
77 ASSERT_TRUE(DecodeHexString(test_vectors
[i
].ct
, &ct
));
79 ChaCha20Poly1305Encrypter encrypter
;
80 ASSERT_TRUE(encrypter
.SetKey(key
));
81 scoped_ptr
<QuicData
> encrypted(EncryptWithNonce(
83 // This deliberately tests that the encrypter can handle an AAD that
84 // is set to nullptr, as opposed to a zero-length, non-nullptr pointer.
85 StringPiece(aad
.length() ? aad
.data() : nullptr, aad
.length()), pt
));
86 ASSERT_TRUE(encrypted
.get());
88 test::CompareCharArraysWithHexError("ciphertext", encrypted
->data(),
89 encrypted
->length(), ct
.data(),
94 TEST(ChaCha20Poly1305EncrypterTest
, GetMaxPlaintextSize
) {
95 ChaCha20Poly1305Encrypter encrypter
;
96 EXPECT_EQ(1000u, encrypter
.GetMaxPlaintextSize(1012));
97 EXPECT_EQ(100u, encrypter
.GetMaxPlaintextSize(112));
98 EXPECT_EQ(10u, encrypter
.GetMaxPlaintextSize(22));
101 TEST(ChaCha20Poly1305EncrypterTest
, GetCiphertextSize
) {
102 ChaCha20Poly1305Encrypter encrypter
;
103 EXPECT_EQ(1012u, encrypter
.GetCiphertextSize(1000));
104 EXPECT_EQ(112u, encrypter
.GetCiphertextSize(100));
105 EXPECT_EQ(22u, encrypter
.GetCiphertextSize(10));