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