blob: 09ec9682c0a125b3877d9f00328a2c906cc75556 [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
44 scoped_ptr<crypto::SymmetricKey> wrong_key(
45 crypto::SymmetricKey::DeriveKeyFromPassword(
46 crypto::SymmetricKey::AES, "wrongword", "sweetest", 1000, 256));
47 EXPECT_TRUE(NULL != wrong_key.get());
48
49 crypto::Encryptor encryptor;
50 // The IV must be exactly as long as the cipher block size.
51 std::string iv("the iv: 16 bytes");
52 EXPECT_EQ(16U, iv.size());
53 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CBC, iv));
54
55 std::string plaintext("this is the plaintext");
56 std::string ciphertext;
57 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
58
59 static const unsigned char expected_ciphertext[] = {
60 0x7D, 0x67, 0x5B, 0x53, 0xE6, 0xD8, 0x0F, 0x27,
61 0x74, 0xB1, 0x90, 0xFE, 0x6E, 0x58, 0x4A, 0xA0,
62 0x0E, 0x35, 0xE3, 0x01, 0xC0, 0xFE, 0x9A, 0xD8,
63 0x48, 0x1D, 0x42, 0xB0, 0xBA, 0x21, 0xB2, 0x0C
64 };
65
66 ASSERT_EQ(arraysize(expected_ciphertext), ciphertext.size());
67 for (size_t i = 0; i < ciphertext.size(); ++i) {
68 ASSERT_EQ(expected_ciphertext[i],
69 static_cast<unsigned char>(ciphertext[i]));
70 }
71
72 crypto::Encryptor decryptor;
73 EXPECT_TRUE(decryptor.Init(wrong_key.get(), crypto::Encryptor::CBC, iv));
74 std::string decypted;
75 // TODO(wtc): On Linux, Encryptor::Decrypt() doesn't always return false when
76 // wrong key is provided. See crbug.com/124434. Remove #if when bug is fixed.
77#if !defined(USE_NSS)
78 EXPECT_FALSE(decryptor.Decrypt(ciphertext, &decypted));
79#endif
80}
81
[email protected]2377cdee2011-06-24 20:46:0682// CTR mode encryption is only implemented using NSS.
83#if defined(USE_NSS)
84
85TEST(EncryptorTest, EncryptDecryptCTR) {
86 scoped_ptr<crypto::SymmetricKey> key(
87 crypto::SymmetricKey::GenerateRandomKey(
88 crypto::SymmetricKey::AES, 128));
89
90 EXPECT_TRUE(NULL != key.get());
91 const std::string kInitialCounter = "0000000000000000";
92
93 crypto::Encryptor encryptor;
94 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CTR, ""));
95 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
96
97 std::string plaintext("normal plaintext of random length");
98 std::string ciphertext;
99 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
100 EXPECT_LT(0U, ciphertext.size());
101
102 std::string decypted;
103 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
104 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
105 EXPECT_EQ(plaintext, decypted);
106
107 plaintext = "0123456789012345";
108 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
109 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
110 EXPECT_LT(0U, ciphertext.size());
111
112 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
113 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
114 EXPECT_EQ(plaintext, decypted);
115}
116
117TEST(EncryptorTest, CTRCounter) {
118 const int kCounterSize = 16;
119 const char kTest1[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
120 uint8 buf[16];
121
122 // Increment 10 times.
123 crypto::Encryptor::Counter counter1(std::string(kTest1, kCounterSize));
124 for (int i = 0; i < 10; ++i)
125 counter1.Increment();
126 counter1.Write(buf);
127 EXPECT_EQ(0, memcmp(buf, kTest1, 15));
128 EXPECT_TRUE(buf[15] == 10);
129
130 // Check corner cases.
131 const char kTest2[] = {0, 0, 0, 0, 0, 0, 0, 0,
132 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
133 const char kExpect2[] = {0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0};
134 crypto::Encryptor::Counter counter2(std::string(kTest2, kCounterSize));
135 counter2.Increment();
136 counter2.Write(buf);
137 EXPECT_EQ(0, memcmp(buf, kExpect2, kCounterSize));
138
139 const char kTest3[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
140 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
141 const char kExpect3[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
142 crypto::Encryptor::Counter counter3(std::string(kTest3, kCounterSize));
143 counter3.Increment();
144 counter3.Write(buf);
145 EXPECT_EQ(0, memcmp(buf, kExpect3, kCounterSize));
146}
147
148#endif
149
[email protected]692033a2010-04-09 18:40:50150// TODO(wtc): add more known-answer tests. Test vectors are available from
151// http://www.ietf.org/rfc/rfc3602
152// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
153// http://gladman.plushost.co.uk/oldsite/AES/index.php
154// http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
155
[email protected]692033a2010-04-09 18:40:50156// NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
157TEST(EncryptorTest, EncryptAES256CBC) {
158 // From NIST SP 800-38a test cast F.2.5 CBC-AES256.Encrypt.
159 static const unsigned char raw_key[] = {
160 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
161 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
162 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
163 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
164 };
165 static const unsigned char raw_iv[] = {
166 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
167 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
168 };
169 static const unsigned char raw_plaintext[] = {
170 // Block #1
171 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
172 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
173 // Block #2
174 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
175 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
176 // Block #3
177 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
178 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
179 // Block #4
180 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
181 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
182 };
183 static const unsigned char raw_ciphertext[] = {
184 // Block #1
185 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
186 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
187 // Block #2
188 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
189 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
190 // Block #3
191 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
192 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
193 // Block #4
194 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
195 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
196 // PKCS #5 padding, encrypted.
197 0x3f, 0x46, 0x17, 0x96, 0xd6, 0xb0, 0xd6, 0xb2,
198 0xe0, 0xc2, 0xa7, 0x2b, 0x4d, 0x80, 0xe6, 0x44
199 };
200
[email protected]896200b32010-07-20 19:21:18201 std::string key(reinterpret_cast<const char*>(raw_key), sizeof(raw_key));
[email protected]4b559b4d2011-04-14 17:37:14202 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
203 crypto::SymmetricKey::AES, key));
[email protected]896200b32010-07-20 19:21:18204 ASSERT_TRUE(NULL != sym_key.get());
[email protected]692033a2010-04-09 18:40:50205
[email protected]4b559b4d2011-04-14 17:37:14206 crypto::Encryptor encryptor;
[email protected]692033a2010-04-09 18:40:50207 // The IV must be exactly as long a the cipher block size.
208 std::string iv(reinterpret_cast<const char*>(raw_iv), sizeof(raw_iv));
209 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14210 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]692033a2010-04-09 18:40:50211
212 std::string plaintext(reinterpret_cast<const char*>(raw_plaintext),
213 sizeof(raw_plaintext));
214 std::string ciphertext;
215 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
216
217 EXPECT_EQ(sizeof(raw_ciphertext), ciphertext.size());
218 EXPECT_EQ(0, memcmp(ciphertext.data(), raw_ciphertext, ciphertext.size()));
219
220 std::string decypted;
221 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
222
223 EXPECT_EQ(plaintext, decypted);
224}
[email protected]25007102010-11-12 16:29:06225
226// Expected output derived from the NSS implementation.
227TEST(EncryptorTest, EncryptAES128CBCRegression) {
228 std::string key = "128=SixteenBytes";
229 std::string iv = "Sweet Sixteen IV";
230 std::string plaintext = "Plain text with a g-clef U+1D11E \360\235\204\236";
231 std::string expected_ciphertext_hex =
232 "D4A67A0BA33C30F207344D81D1E944BBE65587C3D7D9939A"
233 "C070C62B9C15A3EA312EA4AD1BC7929F4D3C16B03AD5ADA8";
234
[email protected]4b559b4d2011-04-14 17:37:14235 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
236 crypto::SymmetricKey::AES, key));
[email protected]25007102010-11-12 16:29:06237 ASSERT_TRUE(NULL != sym_key.get());
238
[email protected]4b559b4d2011-04-14 17:37:14239 crypto::Encryptor encryptor;
[email protected]25007102010-11-12 16:29:06240 // The IV must be exactly as long a the cipher block size.
241 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14242 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06243
244 std::string ciphertext;
245 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
246 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
247 ciphertext.size()));
248
249 std::string decypted;
250 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
251 EXPECT_EQ(plaintext, decypted);
252}
253
254// Expected output derived from the NSS implementation.
255TEST(EncryptorTest, EncryptAES192CBCRegression) {
256 std::string key = "192bitsIsTwentyFourByte!";
257 std::string iv = "Sweet Sixteen IV";
258 std::string plaintext = "Small text";
259 std::string expected_ciphertext_hex = "78DE5D7C2714FC5C61346C5416F6C89A";
260
[email protected]4b559b4d2011-04-14 17:37:14261 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
262 crypto::SymmetricKey::AES, key));
[email protected]25007102010-11-12 16:29:06263 ASSERT_TRUE(NULL != sym_key.get());
264
[email protected]4b559b4d2011-04-14 17:37:14265 crypto::Encryptor encryptor;
[email protected]25007102010-11-12 16:29:06266 // The IV must be exactly as long a the cipher block size.
267 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14268 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06269
270 std::string ciphertext;
271 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
272 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
273 ciphertext.size()));
274
275 std::string decypted;
276 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decypted));
277 EXPECT_EQ(plaintext, decypted);
278}
279
280// Not all platforms allow import/generation of symmetric keys with an
281// unsupported size.
282#if !defined(OS_WIN) && !defined(USE_NSS)
283TEST(EncryptorTest, UnsupportedKeySize) {
284 std::string key = "7 = bad";
285 std::string iv = "Sweet Sixteen IV";
[email protected]4b559b4d2011-04-14 17:37:14286 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
287 crypto::SymmetricKey::AES, key));
[email protected]25007102010-11-12 16:29:06288 ASSERT_TRUE(NULL != sym_key.get());
289
[email protected]4b559b4d2011-04-14 17:37:14290 crypto::Encryptor encryptor;
[email protected]25007102010-11-12 16:29:06291 // The IV must be exactly as long a the cipher block size.
292 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14293 EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06294}
295#endif // unsupported platforms.
296
297TEST(EncryptorTest, UnsupportedIV) {
298 std::string key = "128=SixteenBytes";
299 std::string iv = "OnlyForteen :(";
[email protected]4b559b4d2011-04-14 17:37:14300 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
301 crypto::SymmetricKey::AES, key));
[email protected]25007102010-11-12 16:29:06302 ASSERT_TRUE(NULL != sym_key.get());
303
[email protected]4b559b4d2011-04-14 17:37:14304 crypto::Encryptor encryptor;
305 EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06306}
307
308TEST(EncryptorTest, EmptyEncrypt) {
309 std::string key = "128=SixteenBytes";
310 std::string iv = "Sweet Sixteen IV";
311 std::string plaintext;
312 std::string expected_ciphertext_hex = "8518B8878D34E7185E300D0FCC426396";
313
[email protected]4b559b4d2011-04-14 17:37:14314 scoped_ptr<crypto::SymmetricKey> sym_key(crypto::SymmetricKey::Import(
315 crypto::SymmetricKey::AES, key));
[email protected]25007102010-11-12 16:29:06316 ASSERT_TRUE(NULL != sym_key.get());
317
[email protected]4b559b4d2011-04-14 17:37:14318 crypto::Encryptor encryptor;
[email protected]25007102010-11-12 16:29:06319 // The IV must be exactly as long a the cipher block size.
320 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14321 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06322
323 std::string ciphertext;
324 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
325 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
326 ciphertext.size()));
327}