Home | History | Annotate | Download | only in crypto
      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.
      4 
      5 #include "net/quic/crypto/chacha20_poly1305_encrypter.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 five 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   const char* key;
     20   const char* pt;
     21   const char* iv;
     22   const char* aad;
     23   const char* ct;
     24 };
     25 
     26 const TestVector test_vectors[] = {
     27   { "4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd110"
     28         "0a1007",
     29     "86d09974840bded2a5ca",
     30     "cd7cf67be39c794a",
     31     "87e229d4500845a079c0",
     32     "e3e446f7ede9a19b62a4677dabf4e3d24b876bb28475"  // "3896e1d6" truncated.
     33   },
     34   { NULL }
     35 };
     36 
     37 }  // namespace
     38 
     39 namespace net {
     40 namespace test {
     41 
     42 // EncryptWithNonce wraps the |Encrypt| method of |encrypter| to allow passing
     43 // in an nonce and also to allocate the buffer needed for the ciphertext.
     44 QuicData* EncryptWithNonce(ChaCha20Poly1305Encrypter* encrypter,
     45                            StringPiece nonce,
     46                            StringPiece associated_data,
     47                            StringPiece plaintext) {
     48   size_t ciphertext_size = encrypter->GetCiphertextSize(plaintext.length());
     49   scoped_ptr<char[]> ciphertext(new char[ciphertext_size]);
     50 
     51   if (!encrypter->Encrypt(nonce, associated_data, plaintext,
     52                           reinterpret_cast<unsigned char*>(ciphertext.get()))) {
     53     return NULL;
     54   }
     55 
     56   return new QuicData(ciphertext.release(), ciphertext_size, true);
     57 }
     58 
     59 TEST(ChaCha20Poly1305EncrypterTest, Encrypt) {
     60   if (!ChaCha20Poly1305Encrypter::IsSupported()) {
     61     LOG(INFO) << "ChaCha20+Poly1305 not supported. Test skipped.";
     62     return;
     63   }
     64 
     65   for (size_t i = 0; test_vectors[i].key != NULL; i++) {
     66     // Decode the test vector.
     67     string key;
     68     string pt;
     69     string iv;
     70     string aad;
     71     string ct;
     72     ASSERT_TRUE(DecodeHexString(test_vectors[i].key, &key));
     73     ASSERT_TRUE(DecodeHexString(test_vectors[i].pt, &pt));
     74     ASSERT_TRUE(DecodeHexString(test_vectors[i].iv, &iv));
     75     ASSERT_TRUE(DecodeHexString(test_vectors[i].aad, &aad));
     76     ASSERT_TRUE(DecodeHexString(test_vectors[i].ct, &ct));
     77 
     78     ChaCha20Poly1305Encrypter encrypter;
     79     ASSERT_TRUE(encrypter.SetKey(key));
     80     scoped_ptr<QuicData> encrypted(EncryptWithNonce(
     81         &encrypter, iv,
     82         // This deliberately tests that the encrypter can handle an AAD that
     83         // is set to NULL, as opposed to a zero-length, non-NULL pointer.
     84         StringPiece(aad.length() ? aad.data() : NULL, aad.length()), pt));
     85     ASSERT_TRUE(encrypted.get());
     86 
     87     test::CompareCharArraysWithHexError("ciphertext", encrypted->data(),
     88                                         encrypted->length(), ct.data(),
     89                                         ct.length());
     90   }
     91 }
     92 
     93 TEST(ChaCha20Poly1305EncrypterTest, GetMaxPlaintextSize) {
     94   ChaCha20Poly1305Encrypter encrypter;
     95   EXPECT_EQ(1000u, encrypter.GetMaxPlaintextSize(1012));
     96   EXPECT_EQ(100u, encrypter.GetMaxPlaintextSize(112));
     97   EXPECT_EQ(10u, encrypter.GetMaxPlaintextSize(22));
     98 }
     99 
    100 TEST(ChaCha20Poly1305EncrypterTest, GetCiphertextSize) {
    101   ChaCha20Poly1305Encrypter encrypter;
    102   EXPECT_EQ(1012u, encrypter.GetCiphertextSize(1000));
    103   EXPECT_EQ(112u, encrypter.GetCiphertextSize(100));
    104   EXPECT_EQ(22u, encrypter.GetCiphertextSize(10));
    105 }
    106 
    107 }  // namespace test
    108 }  // namespace net
    109