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.
5 #include "crypto/encryptor.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/string_number_conversions.h"
11 #include "crypto/symmetric_key.h"
12 #include "testing/gtest/include/gtest/gtest.h"
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(NULL
!= key
.get());
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
));
26 std::string
plaintext("this is the plaintext");
27 std::string ciphertext
;
28 EXPECT_TRUE(encryptor
.Encrypt(plaintext
, &ciphertext
));
30 EXPECT_LT(0U, ciphertext
.size());
33 EXPECT_TRUE(encryptor
.Decrypt(ciphertext
, &decypted
));
35 EXPECT_EQ(plaintext
, decypted
);
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(NULL
!= key
.get());
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(NULL
!= wrong_key
.get());
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(NULL
!= wrong_key2
.get());
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(NULL
!= wrong_key3
.get());
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
));
70 std::string
plaintext("this is the plaintext");
71 std::string ciphertext
;
72 EXPECT_TRUE(encryptor
.Encrypt(plaintext
, &ciphertext
));
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
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
]));
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
, &decypted
));
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
, &decypted
));
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
, &decypted
));
115 // CTR mode encryption is only implemented using NSS.
116 #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
118 TEST(EncryptorTest
, EncryptDecryptCTR
) {
119 scoped_ptr
<crypto::SymmetricKey
> key(
120 crypto::SymmetricKey::GenerateRandomKey(
121 crypto::SymmetricKey::AES
, 128));
123 EXPECT_TRUE(NULL
!= key
.get());
124 const std::string kInitialCounter
= "0000000000000000";
126 crypto::Encryptor encryptor
;
127 EXPECT_TRUE(encryptor
.Init(key
.get(), crypto::Encryptor::CTR
, ""));
128 EXPECT_TRUE(encryptor
.SetCounter(kInitialCounter
));
130 std::string
plaintext("normal plaintext of random length");
131 std::string ciphertext
;
132 EXPECT_TRUE(encryptor
.Encrypt(plaintext
, &ciphertext
));
133 EXPECT_LT(0U, ciphertext
.size());
135 std::string decypted
;
136 EXPECT_TRUE(encryptor
.SetCounter(kInitialCounter
));
137 EXPECT_TRUE(encryptor
.Decrypt(ciphertext
, &decypted
));
138 EXPECT_EQ(plaintext
, decypted
);
140 plaintext
= "0123456789012345";
141 EXPECT_TRUE(encryptor
.SetCounter(kInitialCounter
));
142 EXPECT_TRUE(encryptor
.Encrypt(plaintext
, &ciphertext
));
143 EXPECT_LT(0U, ciphertext
.size());
145 EXPECT_TRUE(encryptor
.SetCounter(kInitialCounter
));
146 EXPECT_TRUE(encryptor
.Decrypt(ciphertext
, &decypted
));
147 EXPECT_EQ(plaintext
, decypted
);
150 TEST(EncryptorTest
, CTRCounter
) {
151 const int kCounterSize
= 16;
152 const unsigned char kTest1
[] =
153 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
154 unsigned char buf
[16];
156 // Increment 10 times.
157 crypto::Encryptor::Counter
counter1(
158 std::string(reinterpret_cast<const char*>(kTest1
), kCounterSize
));
159 for (int i
= 0; i
< 10; ++i
)
160 counter1
.Increment();
162 EXPECT_EQ(0, memcmp(buf
, kTest1
, 15));
163 EXPECT_TRUE(buf
[15] == 10);
165 // Check corner cases.
166 const unsigned char kTest2
[] = {
167 0, 0, 0, 0, 0, 0, 0, 0,
168 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
170 const unsigned char kExpect2
[] =
171 {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0};
172 crypto::Encryptor::Counter
counter2(
173 std::string(reinterpret_cast<const char*>(kTest2
), kCounterSize
));
174 counter2
.Increment();
176 EXPECT_EQ(0, memcmp(buf
, kExpect2
, kCounterSize
));
178 const unsigned char kTest3
[] = {
179 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
180 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
182 const unsigned char kExpect3
[] =
183 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
184 crypto::Encryptor::Counter
counter3(
185 std::string(reinterpret_cast<const char*>(kTest3
), kCounterSize
));
186 counter3
.Increment();
188 EXPECT_EQ(0, memcmp(buf
, kExpect3
, kCounterSize
));
193 // TODO(wtc): add more known-answer tests. Test vectors are available from
194 // http://www.ietf.org/rfc/rfc3602
195 // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
196 // http://gladman.plushost.co.uk/oldsite/AES/index.php
197 // http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
199 // NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
200 TEST(EncryptorTest
, EncryptAES256CBC
) {
201 // From NIST SP 800-38a test cast F.2.5 CBC-AES256.Encrypt.
202 static const unsigned char raw_key
[] = {
203 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
204 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
205 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
206 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
208 static const unsigned char raw_iv
[] = {
209 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
210 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
212 static const unsigned char raw_plaintext
[] = {
214 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
215 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
217 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
218 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
220 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
221 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
223 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
224 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
226 static const unsigned char raw_ciphertext
[] = {
228 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
229 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
231 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
232 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
234 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
235 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
237 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
238 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
239 // PKCS #5 padding, encrypted.
240 0x3f, 0x46, 0x17, 0x96, 0xd6, 0xb0, 0xd6, 0xb2,
241 0xe0, 0xc2, 0xa7, 0x2b, 0x4d, 0x80, 0xe6, 0x44
244 std::string
key(reinterpret_cast<const char*>(raw_key
), sizeof(raw_key
));
245 scoped_ptr
<crypto::SymmetricKey
> sym_key(crypto::SymmetricKey::Import(
246 crypto::SymmetricKey::AES
, key
));
247 ASSERT_TRUE(NULL
!= sym_key
.get());
249 crypto::Encryptor encryptor
;
250 // The IV must be exactly as long a the cipher block size.
251 std::string
iv(reinterpret_cast<const char*>(raw_iv
), sizeof(raw_iv
));
252 EXPECT_EQ(16U, iv
.size());
253 EXPECT_TRUE(encryptor
.Init(sym_key
.get(), crypto::Encryptor::CBC
, iv
));
255 std::string
plaintext(reinterpret_cast<const char*>(raw_plaintext
),
256 sizeof(raw_plaintext
));
257 std::string ciphertext
;
258 EXPECT_TRUE(encryptor
.Encrypt(plaintext
, &ciphertext
));
260 EXPECT_EQ(sizeof(raw_ciphertext
), ciphertext
.size());
261 EXPECT_EQ(0, memcmp(ciphertext
.data(), raw_ciphertext
, ciphertext
.size()));
263 std::string decypted
;
264 EXPECT_TRUE(encryptor
.Decrypt(ciphertext
, &decypted
));
266 EXPECT_EQ(plaintext
, decypted
);
269 // Expected output derived from the NSS implementation.
270 TEST(EncryptorTest
, EncryptAES128CBCRegression
) {
271 std::string key
= "128=SixteenBytes";
272 std::string iv
= "Sweet Sixteen IV";
273 std::string plaintext
= "Plain text with a g-clef U+1D11E \360\235\204\236";
274 std::string expected_ciphertext_hex
=
275 "D4A67A0BA33C30F207344D81D1E944BBE65587C3D7D9939A"
276 "C070C62B9C15A3EA312EA4AD1BC7929F4D3C16B03AD5ADA8";
278 scoped_ptr
<crypto::SymmetricKey
> sym_key(crypto::SymmetricKey::Import(
279 crypto::SymmetricKey::AES
, key
));
280 ASSERT_TRUE(NULL
!= sym_key
.get());
282 crypto::Encryptor encryptor
;
283 // The IV must be exactly as long a the cipher block size.
284 EXPECT_EQ(16U, iv
.size());
285 EXPECT_TRUE(encryptor
.Init(sym_key
.get(), crypto::Encryptor::CBC
, iv
));
287 std::string ciphertext
;
288 EXPECT_TRUE(encryptor
.Encrypt(plaintext
, &ciphertext
));
289 EXPECT_EQ(expected_ciphertext_hex
, base::HexEncode(ciphertext
.data(),
292 std::string decypted
;
293 EXPECT_TRUE(encryptor
.Decrypt(ciphertext
, &decypted
));
294 EXPECT_EQ(plaintext
, decypted
);
297 // Expected output derived from the NSS implementation.
298 TEST(EncryptorTest
, EncryptAES192CBCRegression
) {
299 std::string key
= "192bitsIsTwentyFourByte!";
300 std::string iv
= "Sweet Sixteen IV";
301 std::string plaintext
= "Small text";
302 std::string expected_ciphertext_hex
= "78DE5D7C2714FC5C61346C5416F6C89A";
304 scoped_ptr
<crypto::SymmetricKey
> sym_key(crypto::SymmetricKey::Import(
305 crypto::SymmetricKey::AES
, key
));
306 ASSERT_TRUE(NULL
!= sym_key
.get());
308 crypto::Encryptor encryptor
;
309 // The IV must be exactly as long a the cipher block size.
310 EXPECT_EQ(16U, iv
.size());
311 EXPECT_TRUE(encryptor
.Init(sym_key
.get(), crypto::Encryptor::CBC
, iv
));
313 std::string ciphertext
;
314 EXPECT_TRUE(encryptor
.Encrypt(plaintext
, &ciphertext
));
315 EXPECT_EQ(expected_ciphertext_hex
, base::HexEncode(ciphertext
.data(),
318 std::string decypted
;
319 EXPECT_TRUE(encryptor
.Decrypt(ciphertext
, &decypted
));
320 EXPECT_EQ(plaintext
, decypted
);
323 // Not all platforms allow import/generation of symmetric keys with an
325 #if !defined(USE_NSS) && !defined(OS_WIN) && !defined(OS_MACOSX)
326 TEST(EncryptorTest
, UnsupportedKeySize
) {
327 std::string key
= "7 = bad";
328 std::string iv
= "Sweet Sixteen IV";
329 scoped_ptr
<crypto::SymmetricKey
> sym_key(crypto::SymmetricKey::Import(
330 crypto::SymmetricKey::AES
, key
));
331 ASSERT_TRUE(NULL
!= sym_key
.get());
333 crypto::Encryptor encryptor
;
334 // The IV must be exactly as long a the cipher block size.
335 EXPECT_EQ(16U, iv
.size());
336 EXPECT_FALSE(encryptor
.Init(sym_key
.get(), crypto::Encryptor::CBC
, iv
));
338 #endif // unsupported platforms.
340 TEST(EncryptorTest
, UnsupportedIV
) {
341 std::string key
= "128=SixteenBytes";
342 std::string iv
= "OnlyForteen :(";
343 scoped_ptr
<crypto::SymmetricKey
> sym_key(crypto::SymmetricKey::Import(
344 crypto::SymmetricKey::AES
, key
));
345 ASSERT_TRUE(NULL
!= sym_key
.get());
347 crypto::Encryptor encryptor
;
348 EXPECT_FALSE(encryptor
.Init(sym_key
.get(), crypto::Encryptor::CBC
, iv
));
351 TEST(EncryptorTest
, EmptyEncrypt
) {
352 std::string key
= "128=SixteenBytes";
353 std::string iv
= "Sweet Sixteen IV";
354 std::string plaintext
;
355 std::string expected_ciphertext_hex
= "8518B8878D34E7185E300D0FCC426396";
357 scoped_ptr
<crypto::SymmetricKey
> sym_key(crypto::SymmetricKey::Import(
358 crypto::SymmetricKey::AES
, key
));
359 ASSERT_TRUE(NULL
!= sym_key
.get());
361 crypto::Encryptor encryptor
;
362 // The IV must be exactly as long a the cipher block size.
363 EXPECT_EQ(16U, iv
.size());
364 EXPECT_TRUE(encryptor
.Init(sym_key
.get(), crypto::Encryptor::CBC
, iv
));
366 std::string ciphertext
;
367 EXPECT_TRUE(encryptor
.Encrypt(plaintext
, &ciphertext
));
368 EXPECT_EQ(expected_ciphertext_hex
, base::HexEncode(ciphertext
.data(),