• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "crypto/encryptor.h"
11 
12 #include <stddef.h>
13 
14 #include <memory>
15 #include <string>
16 
17 #include "base/containers/heap_array.h"
18 #include "base/containers/span.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "crypto/symmetric_key.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 
TEST(EncryptorTest,EncryptDecrypt)23 TEST(EncryptorTest, EncryptDecrypt) {
24   std::unique_ptr<crypto::SymmetricKey> key(
25       crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
26           crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256));
27   EXPECT_TRUE(key.get());
28 
29   crypto::Encryptor encryptor;
30   // The IV must be exactly as long as the cipher block size.
31   std::string iv("the iv: 16 bytes");
32   EXPECT_EQ(16U, iv.size());
33   EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CBC, iv));
34 
35   std::string plaintext("this is the plaintext");
36   std::string ciphertext;
37   EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
38   EXPECT_LT(0U, ciphertext.size());
39 
40   std::string decrypted;
41   EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
42   EXPECT_EQ(plaintext, decrypted);
43 
44   // Repeat the test with the bytes API.
45   std::vector<uint8_t> plaintext_vec(plaintext.begin(), plaintext.end());
46   std::vector<uint8_t> ciphertext_vec;
47   EXPECT_TRUE(encryptor.Encrypt(plaintext_vec, &ciphertext_vec));
48   EXPECT_LT(0U, ciphertext_vec.size());
49 
50   std::vector<uint8_t> decrypted_vec;
51   EXPECT_TRUE(encryptor.Decrypt(ciphertext_vec, &decrypted_vec));
52   EXPECT_EQ(plaintext_vec, decrypted_vec);
53 }
54 
TEST(EncryptorTest,DecryptWrongKey)55 TEST(EncryptorTest, DecryptWrongKey) {
56   std::unique_ptr<crypto::SymmetricKey> key(
57       crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
58           crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256));
59   EXPECT_TRUE(key.get());
60 
61   // A wrong key that can be detected by implementations that validate every
62   // byte in the padding.
63   std::unique_ptr<crypto::SymmetricKey> wrong_key(
64       crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
65           crypto::SymmetricKey::AES, "wrongword", "sweetest", 1000, 256));
66   EXPECT_TRUE(wrong_key.get());
67 
68   // A wrong key that can't be detected by any implementation.  The password
69   // "wrongword;" would also work.
70   std::unique_ptr<crypto::SymmetricKey> wrong_key2(
71       crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
72           crypto::SymmetricKey::AES, "wrongword+", "sweetest", 1000, 256));
73   EXPECT_TRUE(wrong_key2.get());
74 
75   // A wrong key that can be detected by all implementations.
76   std::unique_ptr<crypto::SymmetricKey> wrong_key3(
77       crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
78           crypto::SymmetricKey::AES, "wrongwordx", "sweetest", 1000, 256));
79   EXPECT_TRUE(wrong_key3.get());
80 
81   crypto::Encryptor encryptor;
82   // The IV must be exactly as long as the cipher block size.
83   std::string iv("the iv: 16 bytes");
84   EXPECT_EQ(16U, iv.size());
85   EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CBC, iv));
86 
87   std::string plaintext("this is the plaintext");
88   std::string ciphertext;
89   EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
90 
91   static const unsigned char expected_ciphertext[] = {
92     0x7D, 0x67, 0x5B, 0x53, 0xE6, 0xD8, 0x0F, 0x27,
93     0x74, 0xB1, 0x90, 0xFE, 0x6E, 0x58, 0x4A, 0xA0,
94     0x0E, 0x35, 0xE3, 0x01, 0xC0, 0xFE, 0x9A, 0xD8,
95     0x48, 0x1D, 0x42, 0xB0, 0xBA, 0x21, 0xB2, 0x0C
96   };
97 
98   ASSERT_EQ(std::size(expected_ciphertext), ciphertext.size());
99   for (size_t i = 0; i < ciphertext.size(); ++i) {
100     ASSERT_EQ(expected_ciphertext[i],
101               static_cast<unsigned char>(ciphertext[i]));
102   }
103 
104   std::string decrypted;
105 
106   // This wrong key causes the last padding byte to be 5, which is a valid
107   // padding length, and the second to last padding byte to be 137, which is
108   // invalid.  If an implementation simply uses the last padding byte to
109   // determine the padding length without checking every padding byte,
110   // Encryptor::Decrypt() will still return true.  This is the case for NSS
111   // (crbug.com/124434).
112   crypto::Encryptor decryptor;
113   EXPECT_TRUE(decryptor.Init(wrong_key.get(), crypto::Encryptor::CBC, iv));
114   EXPECT_FALSE(decryptor.Decrypt(ciphertext, &decrypted));
115 
116   // This demonstrates that not all wrong keys can be detected by padding
117   // error. This wrong key causes the last padding byte to be 1, which is
118   // a valid padding block of length 1.
119   crypto::Encryptor decryptor2;
120   EXPECT_TRUE(decryptor2.Init(wrong_key2.get(), crypto::Encryptor::CBC, iv));
121   EXPECT_TRUE(decryptor2.Decrypt(ciphertext, &decrypted));
122 
123   // This wrong key causes the last padding byte to be 253, which should be
124   // rejected by all implementations.
125   crypto::Encryptor decryptor3;
126   EXPECT_TRUE(decryptor3.Init(wrong_key3.get(), crypto::Encryptor::CBC, iv));
127   EXPECT_FALSE(decryptor3.Decrypt(ciphertext, &decrypted));
128 }
129 
130 namespace {
131 
132 // From NIST SP 800-38a test cast:
133 // - F.5.1 CTR-AES128.Encrypt
134 // - F.5.6 CTR-AES256.Encrypt
135 // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
136 const unsigned char kAES128CTRKey[] = {
137   0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
138   0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
139 };
140 
141 const unsigned char kAES256CTRKey[] = {
142   0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
143   0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
144   0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
145   0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
146 };
147 
148 const unsigned char kAESCTRInitCounter[] = {
149   0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
150   0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
151 };
152 
153 const unsigned char kAESCTRPlaintext[] = {
154   // Block #1
155   0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
156   0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
157   // Block #2
158   0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
159   0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
160   // Block #3
161   0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
162   0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
163   // Block #4
164   0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
165   0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
166 };
167 
168 const unsigned char kAES128CTRCiphertext[] = {
169   // Block #1
170   0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
171   0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
172   // Block #2
173   0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff,
174   0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff,
175   // Block #3
176   0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e,
177   0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab,
178   // Block #4
179   0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1,
180   0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee
181 };
182 
183 const unsigned char kAES256CTRCiphertext[] = {
184   // Block #1
185   0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5,
186   0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28,
187   // Block #2
188   0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a,
189   0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5,
190   // Block #3
191   0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c,
192   0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d,
193   // Block #4
194   0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6,
195   0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6
196 };
197 
TestAESCTREncrypt(const unsigned char * key,size_t key_size,const unsigned char * init_counter,size_t init_counter_size,const unsigned char * plaintext,size_t plaintext_size,const unsigned char * ciphertext,size_t ciphertext_size)198 void TestAESCTREncrypt(
199     const unsigned char* key, size_t key_size,
200     const unsigned char* init_counter, size_t init_counter_size,
201     const unsigned char* plaintext, size_t plaintext_size,
202     const unsigned char* ciphertext, size_t ciphertext_size) {
203   std::string key_str(reinterpret_cast<const char*>(key), key_size);
204   std::unique_ptr<crypto::SymmetricKey> sym_key(
205       crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key_str));
206   ASSERT_TRUE(sym_key.get());
207 
208   crypto::Encryptor encryptor;
209   EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
210 
211   std::string_view init_counter_str(reinterpret_cast<const char*>(init_counter),
212                                     init_counter_size);
213   std::string_view plaintext_str(reinterpret_cast<const char*>(plaintext),
214                                  plaintext_size);
215 
216   EXPECT_TRUE(encryptor.SetCounter(init_counter_str));
217   std::string encrypted;
218   EXPECT_TRUE(encryptor.Encrypt(plaintext_str, &encrypted));
219 
220   EXPECT_EQ(ciphertext_size, encrypted.size());
221   EXPECT_EQ(0, memcmp(encrypted.data(), ciphertext, encrypted.size()));
222 
223   std::string decrypted;
224   EXPECT_TRUE(encryptor.SetCounter(init_counter_str));
225   EXPECT_TRUE(encryptor.Decrypt(encrypted, &decrypted));
226 
227   EXPECT_EQ(plaintext_str, decrypted);
228 
229   // Repeat the test with the bytes API.
230   EXPECT_TRUE(
231       encryptor.SetCounter(base::span(init_counter, init_counter_size)));
232   std::vector<uint8_t> encrypted_vec;
233   EXPECT_TRUE(
234       encryptor.Encrypt(base::span(plaintext, plaintext_size), &encrypted_vec));
235 
236   EXPECT_EQ(ciphertext_size, encrypted_vec.size());
237   EXPECT_EQ(0, memcmp(encrypted_vec.data(), ciphertext, encrypted_vec.size()));
238 
239   std::vector<uint8_t> decrypted_vec;
240   EXPECT_TRUE(
241       encryptor.SetCounter(base::span(init_counter, init_counter_size)));
242   EXPECT_TRUE(encryptor.Decrypt(encrypted_vec, &decrypted_vec));
243 
244   EXPECT_EQ(std::vector<uint8_t>(plaintext, plaintext + plaintext_size),
245             decrypted_vec);
246 }
247 
TestAESCTRMultipleDecrypt(const unsigned char * key,size_t key_size,const unsigned char * init_counter,size_t init_counter_size,const unsigned char * plaintext,size_t plaintext_size,const unsigned char * ciphertext,size_t ciphertext_size)248 void TestAESCTRMultipleDecrypt(
249     const unsigned char* key, size_t key_size,
250     const unsigned char* init_counter, size_t init_counter_size,
251     const unsigned char* plaintext, size_t plaintext_size,
252     const unsigned char* ciphertext, size_t ciphertext_size) {
253   std::string key_str(reinterpret_cast<const char*>(key), key_size);
254   std::unique_ptr<crypto::SymmetricKey> sym_key(
255       crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key_str));
256   ASSERT_TRUE(sym_key.get());
257 
258   crypto::Encryptor encryptor;
259   EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
260 
261   // Counter is set only once.
262   EXPECT_TRUE(encryptor.SetCounter(std::string_view(
263       reinterpret_cast<const char*>(init_counter), init_counter_size)));
264 
265   std::string ciphertext_str(reinterpret_cast<const char*>(ciphertext),
266                              ciphertext_size);
267 
268   int kTestDecryptSizes[] = { 32, 16, 8 };
269 
270   int offset = 0;
271   for (size_t i = 0; i < std::size(kTestDecryptSizes); ++i) {
272     std::string decrypted;
273     size_t len = kTestDecryptSizes[i];
274     EXPECT_TRUE(
275         encryptor.Decrypt(ciphertext_str.substr(offset, len), &decrypted));
276     EXPECT_EQ(len, decrypted.size());
277     EXPECT_EQ(0, memcmp(decrypted.data(), plaintext + offset, len));
278     offset += len;
279   }
280 }
281 
282 }  // namespace
283 
TEST(EncryptorTest,EncryptAES128CTR)284 TEST(EncryptorTest, EncryptAES128CTR) {
285   TestAESCTREncrypt(kAES128CTRKey, std::size(kAES128CTRKey), kAESCTRInitCounter,
286                     std::size(kAESCTRInitCounter), kAESCTRPlaintext,
287                     std::size(kAESCTRPlaintext), kAES128CTRCiphertext,
288                     std::size(kAES128CTRCiphertext));
289 }
290 
TEST(EncryptorTest,EncryptAES256CTR)291 TEST(EncryptorTest, EncryptAES256CTR) {
292   TestAESCTREncrypt(kAES256CTRKey, std::size(kAES256CTRKey), kAESCTRInitCounter,
293                     std::size(kAESCTRInitCounter), kAESCTRPlaintext,
294                     std::size(kAESCTRPlaintext), kAES256CTRCiphertext,
295                     std::size(kAES256CTRCiphertext));
296 }
297 
TEST(EncryptorTest,EncryptAES128CTR_MultipleDecrypt)298 TEST(EncryptorTest, EncryptAES128CTR_MultipleDecrypt) {
299   TestAESCTRMultipleDecrypt(kAES128CTRKey, std::size(kAES128CTRKey),
300                             kAESCTRInitCounter, std::size(kAESCTRInitCounter),
301                             kAESCTRPlaintext, std::size(kAESCTRPlaintext),
302                             kAES128CTRCiphertext,
303                             std::size(kAES128CTRCiphertext));
304 }
305 
TEST(EncryptorTest,EncryptAES256CTR_MultipleDecrypt)306 TEST(EncryptorTest, EncryptAES256CTR_MultipleDecrypt) {
307   TestAESCTRMultipleDecrypt(kAES256CTRKey, std::size(kAES256CTRKey),
308                             kAESCTRInitCounter, std::size(kAESCTRInitCounter),
309                             kAESCTRPlaintext, std::size(kAESCTRPlaintext),
310                             kAES256CTRCiphertext,
311                             std::size(kAES256CTRCiphertext));
312 }
313 
TEST(EncryptorTest,EncryptDecryptCTR)314 TEST(EncryptorTest, EncryptDecryptCTR) {
315   std::unique_ptr<crypto::SymmetricKey> key(
316       crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 128));
317 
318   EXPECT_TRUE(key.get());
319   const std::string kInitialCounter = "0000000000000000";
320 
321   crypto::Encryptor encryptor;
322   EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CTR, ""));
323   EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
324 
325   std::string plaintext("normal plaintext of random length");
326   std::string ciphertext;
327   EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
328   EXPECT_LT(0U, ciphertext.size());
329 
330   std::string decrypted;
331   EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
332   EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
333   EXPECT_EQ(plaintext, decrypted);
334 
335   plaintext = "0123456789012345";
336   EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
337   EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
338   EXPECT_LT(0U, ciphertext.size());
339 
340   EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
341   EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
342   EXPECT_EQ(plaintext, decrypted);
343 }
344 
345 // TODO(wtc): add more known-answer tests.  Test vectors are available from
346 // http://www.ietf.org/rfc/rfc3602
347 // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
348 // http://gladman.plushost.co.uk/oldsite/AES/index.php
349 // http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
350 
351 // NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
TEST(EncryptorTest,EncryptAES256CBC)352 TEST(EncryptorTest, EncryptAES256CBC) {
353   // From NIST SP 800-38a test cast F.2.5 CBC-AES256.Encrypt.
354   static const unsigned char kRawKey[] = {
355     0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
356     0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
357     0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
358     0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
359   };
360   static const unsigned char kRawIv[] = {
361     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
362     0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
363   };
364   static const unsigned char kRawPlaintext[] = {
365     // Block #1
366     0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
367     0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
368     // Block #2
369     0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
370     0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
371     // Block #3
372     0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
373     0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
374     // Block #4
375     0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
376     0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
377   };
378   static const unsigned char kRawCiphertext[] = {
379     // Block #1
380     0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
381     0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
382     // Block #2
383     0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
384     0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
385     // Block #3
386     0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
387     0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
388     // Block #4
389     0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
390     0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
391     // PKCS #5 padding, encrypted.
392     0x3f, 0x46, 0x17, 0x96, 0xd6, 0xb0, 0xd6, 0xb2,
393     0xe0, 0xc2, 0xa7, 0x2b, 0x4d, 0x80, 0xe6, 0x44
394   };
395 
396   std::string key(reinterpret_cast<const char*>(kRawKey), sizeof(kRawKey));
397   std::unique_ptr<crypto::SymmetricKey> sym_key(
398       crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
399   ASSERT_TRUE(sym_key.get());
400 
401   crypto::Encryptor encryptor;
402   // The IV must be exactly as long a the cipher block size.
403   std::string iv(reinterpret_cast<const char*>(kRawIv), sizeof(kRawIv));
404   EXPECT_EQ(16U, iv.size());
405   EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
406 
407   std::string plaintext(reinterpret_cast<const char*>(kRawPlaintext),
408                         sizeof(kRawPlaintext));
409   std::string ciphertext;
410   EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
411 
412   EXPECT_EQ(sizeof(kRawCiphertext), ciphertext.size());
413   EXPECT_EQ(0, memcmp(ciphertext.data(), kRawCiphertext, ciphertext.size()));
414 
415   std::string decrypted;
416   EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
417 
418   EXPECT_EQ(plaintext, decrypted);
419 }
420 
421 // Expected output derived from the NSS implementation.
TEST(EncryptorTest,EncryptAES128CBCRegression)422 TEST(EncryptorTest, EncryptAES128CBCRegression) {
423   std::string key = "128=SixteenBytes";
424   std::string iv = "Sweet Sixteen IV";
425   std::string plaintext = "Plain text with a g-clef U+1D11E \360\235\204\236";
426   std::string expected_ciphertext_hex =
427       "D4A67A0BA33C30F207344D81D1E944BBE65587C3D7D9939A"
428       "C070C62B9C15A3EA312EA4AD1BC7929F4D3C16B03AD5ADA8";
429 
430   std::unique_ptr<crypto::SymmetricKey> sym_key(
431       crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
432   ASSERT_TRUE(sym_key.get());
433 
434   crypto::Encryptor encryptor;
435   // The IV must be exactly as long a the cipher block size.
436   EXPECT_EQ(16U, iv.size());
437   EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
438 
439   std::string ciphertext;
440   EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
441   EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext));
442 
443   std::string decrypted;
444   EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
445   EXPECT_EQ(plaintext, decrypted);
446 }
447 
448 // Symmetric keys with an unsupported size should be rejected. Whether they are
449 // rejected by SymmetricKey::Import or Encryptor::Init depends on the platform.
TEST(EncryptorTest,UnsupportedKeySize)450 TEST(EncryptorTest, UnsupportedKeySize) {
451   std::string key = "7 = bad";
452   std::string iv = "Sweet Sixteen IV";
453   std::unique_ptr<crypto::SymmetricKey> sym_key(
454       crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
455   if (!sym_key.get())
456     return;
457 
458   crypto::Encryptor encryptor;
459   // The IV must be exactly as long as the cipher block size.
460   EXPECT_EQ(16U, iv.size());
461   EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
462 }
463 
TEST(EncryptorTest,UnsupportedIV)464 TEST(EncryptorTest, UnsupportedIV) {
465   std::string key = "128=SixteenBytes";
466   std::string iv = "OnlyForteen :(";
467   std::unique_ptr<crypto::SymmetricKey> sym_key(
468       crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
469   ASSERT_TRUE(sym_key.get());
470 
471   crypto::Encryptor encryptor;
472   EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
473 }
474 
TEST(EncryptorTest,EmptyEncryptCBC)475 TEST(EncryptorTest, EmptyEncryptCBC) {
476   std::string key = "128=SixteenBytes";
477   std::string iv = "Sweet Sixteen IV";
478   std::string plaintext;
479   std::string expected_ciphertext_hex = "8518B8878D34E7185E300D0FCC426396";
480 
481   std::unique_ptr<crypto::SymmetricKey> sym_key(
482       crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
483   ASSERT_TRUE(sym_key.get());
484 
485   crypto::Encryptor encryptor;
486   // The IV must be exactly as long as the cipher block size.
487   EXPECT_EQ(16U, iv.size());
488   EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
489 
490   std::string ciphertext;
491   EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
492   EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext));
493 
494   std::string decrypted;
495   EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
496   EXPECT_EQ(decrypted, plaintext);
497 
498   // Decrypting the empty string should fail. Our formulation of CBC expects a
499   // full block of padding for CBC.
500   EXPECT_FALSE(encryptor.Decrypt(std::string(), &decrypted));
501 
502   // Repeat the test with the byte-based API.
503   EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
504   std::vector<uint8_t> ciphertext_bytes;
505   EXPECT_TRUE(
506       encryptor.Encrypt(base::span<const uint8_t>(), &ciphertext_bytes));
507   EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext_bytes));
508 
509   std::vector<uint8_t> decrypted_bytes;
510   EXPECT_TRUE(encryptor.Decrypt(ciphertext_bytes, &decrypted_bytes));
511   EXPECT_EQ(decrypted_bytes.size(), 0u);
512 
513   // Decrypting the empty string should fail. Our formulation of CBC expects a
514   // full block of padding for CBC.
515   EXPECT_FALSE(
516       encryptor.Decrypt(base::span<const uint8_t>(), &decrypted_bytes));
517 }
518 
TEST(EncryptorTest,EmptyEncryptCTR)519 TEST(EncryptorTest, EmptyEncryptCTR) {
520   std::string key = "128=SixteenBytes";
521   std::string iv = "Sweet Sixteen IV";
522   std::string plaintext;
523   std::string expected_ciphertext;
524 
525   std::unique_ptr<crypto::SymmetricKey> sym_key(
526       crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
527   ASSERT_TRUE(sym_key.get());
528 
529   crypto::Encryptor encryptor;
530   EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
531   ASSERT_TRUE(encryptor.SetCounter(iv));
532 
533   std::string ciphertext;
534   EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
535   EXPECT_EQ(expected_ciphertext, ciphertext);
536 
537   std::string decrypted;
538   EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
539   EXPECT_EQ(decrypted, plaintext);
540 
541   // Repeat the test with the byte-based API.
542   ASSERT_TRUE(encryptor.SetCounter(iv));
543   std::vector<uint8_t> ciphertext_bytes;
544   EXPECT_TRUE(
545       encryptor.Encrypt(base::span<const uint8_t>(), &ciphertext_bytes));
546   EXPECT_EQ(ciphertext_bytes.size(), 0u);
547 
548   std::vector<uint8_t> decrypted_bytes;
549   EXPECT_TRUE(encryptor.Decrypt(base::span<const uint8_t>(), &decrypted_bytes));
550   EXPECT_EQ(decrypted_bytes.size(), 0u);
551 }
552 
TEST(EncryptorTest,CipherTextNotMultipleOfBlockSize)553 TEST(EncryptorTest, CipherTextNotMultipleOfBlockSize) {
554   std::string key = "128=SixteenBytes";
555   std::string iv = "Sweet Sixteen IV";
556 
557   std::unique_ptr<crypto::SymmetricKey> sym_key(
558       crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
559   ASSERT_TRUE(sym_key.get());
560 
561   crypto::Encryptor encryptor;
562   // The IV must be exactly as long a the cipher block size.
563   EXPECT_EQ(16U, iv.size());
564   EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
565 
566   // Use a separately allocated array to improve the odds of the memory tools
567   // catching invalid accesses.
568   //
569   // Otherwise when using std::string as the other tests do, accesses several
570   // bytes off the end of the buffer may fall inside the reservation of
571   // the string and not be detected.
572   auto ciphertext = base::HeapArray<char>::Uninit(1);
573 
574   std::string plaintext;
575   EXPECT_FALSE(
576       encryptor.Decrypt(base::as_string_view(ciphertext), &plaintext));
577 }
578