blob: b0ec4bceec6b83f8a1b89ba59cbaead7b765285d [file] [log] [blame]
[email protected]de039882012-04-23 23:51:431// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]39422e32010-03-25 19:13:002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]4b559b4d2011-04-14 17:37:145#include "crypto/encryptor.h"
[email protected]39422e32010-03-25 19:13:006
7#include <string>
8
[email protected]3b63f8f42011-03-28 01:54:159#include "base/memory/scoped_ptr.h"
[email protected]25007102010-11-12 16:29:0610#include "base/string_number_conversions.h"
[email protected]4b559b4d2011-04-14 17:37:1411#include "crypto/symmetric_key.h"
[email protected]39422e32010-03-25 19:13:0012#include "testing/gtest/include/gtest/gtest.h"
13
[email protected]692033a2010-04-09 18:40:5014TEST(EncryptorTest, EncryptDecrypt) {
[email protected]4b559b4d2011-04-14 17:37:1415 scoped_ptr<crypto::SymmetricKey> key(
16 crypto::SymmetricKey::DeriveKeyFromPassword(
17 crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256));
[email protected]39422e32010-03-25 19:13:0018 EXPECT_TRUE(NULL != key.get());
19
[email protected]4b559b4d2011-04-14 17:37:1420 crypto::Encryptor encryptor;
[email protected]692033a2010-04-09 18:40:5021 // The IV must be exactly as long as the cipher block size.
[email protected]39422e32010-03-25 19:13:0022 std::string iv("the iv: 16 bytes");
[email protected]692033a2010-04-09 18:40:5023 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:1424 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CBC, iv));
[email protected]39422e32010-03-25 19:13:0025
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 decypted;
33 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
34
35 EXPECT_EQ(plaintext, decypted);
36}
[email protected]692033a2010-04-09 18:40:5037
[email protected]de039882012-04-23 23:51:4338TEST(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());
43
[email protected]4eac15e2012-05-11 03:17:4444 // A wrong key that can be detected by implementations that validate every
45 // byte in the padding.
[email protected]de039882012-04-23 23:51:4346 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());
50
[email protected]4eac15e2012-05-11 03:17:4451 // A wrong key that can't be detected by any implementation. The password
[email protected]31ab8662012-04-27 03:01:0952 // "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());
57
[email protected]4eac15e2012-05-11 03:17:4458 // 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());
63
[email protected]de039882012-04-23 23:51:4364 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
[email protected]4eac15e2012-05-11 03:17:4487 std::string decypted;
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
[email protected]45a445212012-06-15 08:11:5294 // (crbug.com/124434).
95#if !defined(USE_NSS) && !defined(OS_WIN) && !defined(OS_MACOSX)
[email protected]de039882012-04-23 23:51:4396 crypto::Encryptor decryptor;
97 EXPECT_TRUE(decryptor.Init(wrong_key.get(), crypto::Encryptor::CBC, iv));
[email protected]de039882012-04-23 23:51:4398 EXPECT_FALSE(decryptor.Decrypt(ciphertext, &decypted));
99#endif
[email protected]31ab8662012-04-27 03:01:09100
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));
[email protected]4eac15e2012-05-11 03:17:44107
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));
[email protected]de039882012-04-23 23:51:43113}
114
[email protected]2377cdee2011-06-24 20:46:06115// CTR mode encryption is only implemented using NSS.
[email protected]45a445212012-06-15 08:11:52116#if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
[email protected]2377cdee2011-06-24 20:46:06117
118TEST(EncryptorTest, EncryptDecryptCTR) {
119 scoped_ptr<crypto::SymmetricKey> key(
120 crypto::SymmetricKey::GenerateRandomKey(
121 crypto::SymmetricKey::AES, 128));
122
123 EXPECT_TRUE(NULL != key.get());
124 const std::string kInitialCounter = "0000000000000000";
125
126 crypto::Encryptor encryptor;
127 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CTR, ""));
128 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
129
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());
134
135 std::string decypted;
136 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
137 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
138 EXPECT_EQ(plaintext, decypted);
139
140 plaintext = "0123456789012345";
141 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
142 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
143 EXPECT_LT(0U, ciphertext.size());
144
145 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
146 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
147 EXPECT_EQ(plaintext, decypted);
148}
149
150TEST(EncryptorTest, CTRCounter) {
151 const int kCounterSize = 16;
[email protected]45a445212012-06-15 08:11:52152 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];
[email protected]2377cdee2011-06-24 20:46:06155
156 // Increment 10 times.
[email protected]45a445212012-06-15 08:11:52157 crypto::Encryptor::Counter counter1(
158 std::string(reinterpret_cast<const char*>(kTest1), kCounterSize));
[email protected]2377cdee2011-06-24 20:46:06159 for (int i = 0; i < 10; ++i)
160 counter1.Increment();
161 counter1.Write(buf);
162 EXPECT_EQ(0, memcmp(buf, kTest1, 15));
163 EXPECT_TRUE(buf[15] == 10);
164
165 // Check corner cases.
[email protected]45a445212012-06-15 08:11:52166 const unsigned char kTest2[] = {
167 0, 0, 0, 0, 0, 0, 0, 0,
168 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
169 };
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));
[email protected]2377cdee2011-06-24 20:46:06174 counter2.Increment();
175 counter2.Write(buf);
176 EXPECT_EQ(0, memcmp(buf, kExpect2, kCounterSize));
177
[email protected]45a445212012-06-15 08:11:52178 const unsigned char kTest3[] = {
179 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
180 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
181 };
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));
[email protected]2377cdee2011-06-24 20:46:06186 counter3.Increment();
187 counter3.Write(buf);
188 EXPECT_EQ(0, memcmp(buf, kExpect3, kCounterSize));
189}
190
191#endif
192
[email protected]692033a2010-04-09 18:40:50193// 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
198
[email protected]692033a2010-04-09 18:40:50199// NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
200TEST(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
207 };
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
211 };
212 static const unsigned char raw_plaintext[] = {
213 // Block #1
214 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
215 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
216 // Block #2
217 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
218 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
219 // Block #3
220 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
221 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
222 // Block #4
223 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
224 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
225 };
226 static const unsigned char raw_ciphertext[] = {
227 // Block #1
228 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
229 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
230 // Block #2
231 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
232 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
233 // Block #3
234 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
235 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
236 // Block #4
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
242 };
243
[email protected]896200b32010-07-20 19:21:18244 std::string key(reinterpret_cast<const char*>(raw_key), sizeof(raw_key));
[email protected]4b559b4d2011-04-14 17:37:14245 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
246 crypto::SymmetricKey::AES, key));
[email protected]896200b32010-07-20 19:21:18247 ASSERT_TRUE(NULL != sym_key.get());
[email protected]692033a2010-04-09 18:40:50248
[email protected]4b559b4d2011-04-14 17:37:14249 crypto::Encryptor encryptor;
[email protected]692033a2010-04-09 18:40:50250 // 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());
[email protected]4b559b4d2011-04-14 17:37:14253 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]692033a2010-04-09 18:40:50254
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));
259
260 EXPECT_EQ(sizeof(raw_ciphertext), ciphertext.size());
261 EXPECT_EQ(0, memcmp(ciphertext.data(), raw_ciphertext, ciphertext.size()));
262
263 std::string decypted;
264 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
265
266 EXPECT_EQ(plaintext, decypted);
267}
[email protected]25007102010-11-12 16:29:06268
269// Expected output derived from the NSS implementation.
270TEST(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";
277
[email protected]4b559b4d2011-04-14 17:37:14278 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
279 crypto::SymmetricKey::AES, key));
[email protected]25007102010-11-12 16:29:06280 ASSERT_TRUE(NULL != sym_key.get());
281
[email protected]4b559b4d2011-04-14 17:37:14282 crypto::Encryptor encryptor;
[email protected]25007102010-11-12 16:29:06283 // The IV must be exactly as long a the cipher block size.
284 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14285 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06286
287 std::string ciphertext;
288 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
289 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
290 ciphertext.size()));
291
292 std::string decypted;
293 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
294 EXPECT_EQ(plaintext, decypted);
295}
296
297// Expected output derived from the NSS implementation.
298TEST(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";
303
[email protected]4b559b4d2011-04-14 17:37:14304 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
305 crypto::SymmetricKey::AES, key));
[email protected]25007102010-11-12 16:29:06306 ASSERT_TRUE(NULL != sym_key.get());
307
[email protected]4b559b4d2011-04-14 17:37:14308 crypto::Encryptor encryptor;
[email protected]25007102010-11-12 16:29:06309 // The IV must be exactly as long a the cipher block size.
310 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14311 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06312
313 std::string ciphertext;
314 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
315 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
316 ciphertext.size()));
317
318 std::string decypted;
319 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
320 EXPECT_EQ(plaintext, decypted);
321}
322
323// Not all platforms allow import/generation of symmetric keys with an
324// unsupported size.
[email protected]45a445212012-06-15 08:11:52325#if !defined(USE_NSS) && !defined(OS_WIN) && !defined(OS_MACOSX)
[email protected]25007102010-11-12 16:29:06326TEST(EncryptorTest, UnsupportedKeySize) {
327 std::string key = "7 = bad";
328 std::string iv = "Sweet Sixteen IV";
[email protected]4b559b4d2011-04-14 17:37:14329 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
330 crypto::SymmetricKey::AES, key));
[email protected]25007102010-11-12 16:29:06331 ASSERT_TRUE(NULL != sym_key.get());
332
[email protected]4b559b4d2011-04-14 17:37:14333 crypto::Encryptor encryptor;
[email protected]25007102010-11-12 16:29:06334 // The IV must be exactly as long a the cipher block size.
335 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14336 EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06337}
338#endif // unsupported platforms.
339
340TEST(EncryptorTest, UnsupportedIV) {
341 std::string key = "128=SixteenBytes";
342 std::string iv = "OnlyForteen :(";
[email protected]4b559b4d2011-04-14 17:37:14343 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
344 crypto::SymmetricKey::AES, key));
[email protected]25007102010-11-12 16:29:06345 ASSERT_TRUE(NULL != sym_key.get());
346
[email protected]4b559b4d2011-04-14 17:37:14347 crypto::Encryptor encryptor;
348 EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06349}
350
351TEST(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";
356
[email protected]4b559b4d2011-04-14 17:37:14357 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
358 crypto::SymmetricKey::AES, key));
[email protected]25007102010-11-12 16:29:06359 ASSERT_TRUE(NULL != sym_key.get());
360
[email protected]4b559b4d2011-04-14 17:37:14361 crypto::Encryptor encryptor;
[email protected]25007102010-11-12 16:29:06362 // The IV must be exactly as long a the cipher block size.
363 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14364 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06365
366 std::string ciphertext;
367 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
368 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
369 ciphertext.size()));
370}