- add sources.
[platform/framework/web/crosswalk.git] / src / crypto / encryptor_unittest.cc
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
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
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
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
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
251 TEST(EncryptorTest, EncryptAES128CTR) {
252   TestAESCTREncrypt(
253       kAES128CTRKey, arraysize(kAES128CTRKey),
254       kAESCTRInitCounter, arraysize(kAESCTRInitCounter),
255       kAESCTRPlaintext, arraysize(kAESCTRPlaintext),
256       kAES128CTRCiphertext, arraysize(kAES128CTRCiphertext));
257 }
258
259 TEST(EncryptorTest, EncryptAES256CTR) {
260   TestAESCTREncrypt(
261       kAES256CTRKey, arraysize(kAES256CTRKey),
262       kAESCTRInitCounter, arraysize(kAESCTRInitCounter),
263       kAESCTRPlaintext, arraysize(kAESCTRPlaintext),
264       kAES256CTRCiphertext, arraysize(kAES256CTRCiphertext));
265 }
266
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
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
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
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.
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.
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.
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)
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
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
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
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 }