blob: b4785cabe0a8a41ea503e962174deb580c912baa [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
avidd373b8b2015-12-21 21:34:437#include <stddef.h>
8
thakisd1a18472016-04-08 22:30:419#include <memory>
[email protected]39422e32010-03-25 19:13:0010#include <string>
11
Avi Drissman34f6b422018-12-25 20:29:3912#include "base/stl_util.h"
[email protected]0d8db082013-06-11 07:27:0113#include "base/strings/string_number_conversions.h"
[email protected]4b559b4d2011-04-14 17:37:1414#include "crypto/symmetric_key.h"
[email protected]39422e32010-03-25 19:13:0015#include "testing/gtest/include/gtest/gtest.h"
16
[email protected]692033a2010-04-09 18:40:5017TEST(EncryptorTest, EncryptDecrypt) {
thakisd1a18472016-04-08 22:30:4118 std::unique_ptr<crypto::SymmetricKey> key(
David Davidovićf8cd6a02018-08-27 14:02:5119 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
[email protected]4b559b4d2011-04-14 17:37:1420 crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256));
[email protected]a3f742692013-06-13 19:48:0121 EXPECT_TRUE(key.get());
[email protected]39422e32010-03-25 19:13:0022
[email protected]4b559b4d2011-04-14 17:37:1423 crypto::Encryptor encryptor;
[email protected]692033a2010-04-09 18:40:5024 // The IV must be exactly as long as the cipher block size.
[email protected]39422e32010-03-25 19:13:0025 std::string iv("the iv: 16 bytes");
[email protected]692033a2010-04-09 18:40:5026 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:1427 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CBC, iv));
[email protected]39422e32010-03-25 19:13:0028
29 std::string plaintext("this is the plaintext");
30 std::string ciphertext;
31 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
[email protected]39422e32010-03-25 19:13:0032 EXPECT_LT(0U, ciphertext.size());
33
[email protected]bd2d54c2013-09-30 09:08:4734 std::string decrypted;
35 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
[email protected]bd2d54c2013-09-30 09:08:4736 EXPECT_EQ(plaintext, decrypted);
David Benjamin3efdcb72020-06-16 22:33:0937
38 // Repeat the test with the bytes API.
39 std::vector<uint8_t> plaintext_vec(plaintext.begin(), plaintext.end());
40 std::vector<uint8_t> ciphertext_vec;
41 EXPECT_TRUE(encryptor.Encrypt(plaintext_vec, &ciphertext_vec));
42 EXPECT_LT(0U, ciphertext_vec.size());
43
44 std::vector<uint8_t> decrypted_vec;
45 EXPECT_TRUE(encryptor.Decrypt(ciphertext_vec, &decrypted_vec));
46 EXPECT_EQ(plaintext_vec, decrypted_vec);
[email protected]39422e32010-03-25 19:13:0047}
[email protected]692033a2010-04-09 18:40:5048
[email protected]de039882012-04-23 23:51:4349TEST(EncryptorTest, DecryptWrongKey) {
thakisd1a18472016-04-08 22:30:4150 std::unique_ptr<crypto::SymmetricKey> key(
David Davidovićf8cd6a02018-08-27 14:02:5151 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
[email protected]de039882012-04-23 23:51:4352 crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256));
[email protected]a3f742692013-06-13 19:48:0153 EXPECT_TRUE(key.get());
[email protected]de039882012-04-23 23:51:4354
[email protected]4eac15e2012-05-11 03:17:4455 // A wrong key that can be detected by implementations that validate every
56 // byte in the padding.
thakisd1a18472016-04-08 22:30:4157 std::unique_ptr<crypto::SymmetricKey> wrong_key(
David Davidovićf8cd6a02018-08-27 14:02:5158 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
thakisd1a18472016-04-08 22:30:4159 crypto::SymmetricKey::AES, "wrongword", "sweetest", 1000, 256));
[email protected]a3f742692013-06-13 19:48:0160 EXPECT_TRUE(wrong_key.get());
[email protected]de039882012-04-23 23:51:4361
[email protected]4eac15e2012-05-11 03:17:4462 // A wrong key that can't be detected by any implementation. The password
[email protected]31ab8662012-04-27 03:01:0963 // "wrongword;" would also work.
thakisd1a18472016-04-08 22:30:4164 std::unique_ptr<crypto::SymmetricKey> wrong_key2(
David Davidovićf8cd6a02018-08-27 14:02:5165 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
thakisd1a18472016-04-08 22:30:4166 crypto::SymmetricKey::AES, "wrongword+", "sweetest", 1000, 256));
[email protected]a3f742692013-06-13 19:48:0167 EXPECT_TRUE(wrong_key2.get());
[email protected]31ab8662012-04-27 03:01:0968
[email protected]4eac15e2012-05-11 03:17:4469 // A wrong key that can be detected by all implementations.
thakisd1a18472016-04-08 22:30:4170 std::unique_ptr<crypto::SymmetricKey> wrong_key3(
David Davidovićf8cd6a02018-08-27 14:02:5171 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
thakisd1a18472016-04-08 22:30:4172 crypto::SymmetricKey::AES, "wrongwordx", "sweetest", 1000, 256));
[email protected]a3f742692013-06-13 19:48:0173 EXPECT_TRUE(wrong_key3.get());
[email protected]4eac15e2012-05-11 03:17:4474
[email protected]de039882012-04-23 23:51:4375 crypto::Encryptor encryptor;
76 // The IV must be exactly as long as the cipher block size.
77 std::string iv("the iv: 16 bytes");
78 EXPECT_EQ(16U, iv.size());
79 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CBC, iv));
80
81 std::string plaintext("this is the plaintext");
82 std::string ciphertext;
83 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
84
85 static const unsigned char expected_ciphertext[] = {
86 0x7D, 0x67, 0x5B, 0x53, 0xE6, 0xD8, 0x0F, 0x27,
87 0x74, 0xB1, 0x90, 0xFE, 0x6E, 0x58, 0x4A, 0xA0,
88 0x0E, 0x35, 0xE3, 0x01, 0xC0, 0xFE, 0x9A, 0xD8,
89 0x48, 0x1D, 0x42, 0xB0, 0xBA, 0x21, 0xB2, 0x0C
90 };
91
Avi Drissman34f6b422018-12-25 20:29:3992 ASSERT_EQ(base::size(expected_ciphertext), ciphertext.size());
[email protected]de039882012-04-23 23:51:4393 for (size_t i = 0; i < ciphertext.size(); ++i) {
94 ASSERT_EQ(expected_ciphertext[i],
95 static_cast<unsigned char>(ciphertext[i]));
96 }
97
[email protected]bd2d54c2013-09-30 09:08:4798 std::string decrypted;
[email protected]4eac15e2012-05-11 03:17:4499
100 // This wrong key causes the last padding byte to be 5, which is a valid
101 // padding length, and the second to last padding byte to be 137, which is
102 // invalid. If an implementation simply uses the last padding byte to
103 // determine the padding length without checking every padding byte,
104 // Encryptor::Decrypt() will still return true. This is the case for NSS
[email protected]45a445212012-06-15 08:11:52105 // (crbug.com/124434).
[email protected]de039882012-04-23 23:51:43106 crypto::Encryptor decryptor;
107 EXPECT_TRUE(decryptor.Init(wrong_key.get(), crypto::Encryptor::CBC, iv));
[email protected]bd2d54c2013-09-30 09:08:47108 EXPECT_FALSE(decryptor.Decrypt(ciphertext, &decrypted));
[email protected]31ab8662012-04-27 03:01:09109
110 // This demonstrates that not all wrong keys can be detected by padding
111 // error. This wrong key causes the last padding byte to be 1, which is
112 // a valid padding block of length 1.
113 crypto::Encryptor decryptor2;
114 EXPECT_TRUE(decryptor2.Init(wrong_key2.get(), crypto::Encryptor::CBC, iv));
[email protected]bd2d54c2013-09-30 09:08:47115 EXPECT_TRUE(decryptor2.Decrypt(ciphertext, &decrypted));
[email protected]4eac15e2012-05-11 03:17:44116
117 // This wrong key causes the last padding byte to be 253, which should be
118 // rejected by all implementations.
119 crypto::Encryptor decryptor3;
120 EXPECT_TRUE(decryptor3.Init(wrong_key3.get(), crypto::Encryptor::CBC, iv));
[email protected]bd2d54c2013-09-30 09:08:47121 EXPECT_FALSE(decryptor3.Decrypt(ciphertext, &decrypted));
[email protected]de039882012-04-23 23:51:43122}
123
[email protected]a3f742692013-06-13 19:48:01124namespace {
125
126// From NIST SP 800-38a test cast:
127// - F.5.1 CTR-AES128.Encrypt
128// - F.5.6 CTR-AES256.Encrypt
129// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
130const unsigned char kAES128CTRKey[] = {
131 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
132 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
133};
134
135const unsigned char kAES256CTRKey[] = {
136 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
137 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
138 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
139 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
140};
141
142const unsigned char kAESCTRInitCounter[] = {
143 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
144 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
145};
146
147const unsigned char kAESCTRPlaintext[] = {
148 // Block #1
149 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
150 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
151 // Block #2
152 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
153 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
154 // Block #3
155 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
156 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
157 // Block #4
158 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
159 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
160};
161
162const unsigned char kAES128CTRCiphertext[] = {
163 // Block #1
164 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
165 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
166 // Block #2
167 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff,
168 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff,
169 // Block #3
170 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e,
171 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab,
172 // Block #4
173 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1,
174 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee
175};
176
177const unsigned char kAES256CTRCiphertext[] = {
178 // Block #1
179 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5,
180 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28,
181 // Block #2
182 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a,
183 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5,
184 // Block #3
185 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c,
186 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d,
187 // Block #4
188 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6,
189 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6
190};
191
192void TestAESCTREncrypt(
193 const unsigned char* key, size_t key_size,
194 const unsigned char* init_counter, size_t init_counter_size,
195 const unsigned char* plaintext, size_t plaintext_size,
196 const unsigned char* ciphertext, size_t ciphertext_size) {
197 std::string key_str(reinterpret_cast<const char*>(key), key_size);
thakisd1a18472016-04-08 22:30:41198 std::unique_ptr<crypto::SymmetricKey> sym_key(
199 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key_str));
[email protected]a3f742692013-06-13 19:48:01200 ASSERT_TRUE(sym_key.get());
201
202 crypto::Encryptor encryptor;
203 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
204
205 base::StringPiece init_counter_str(
206 reinterpret_cast<const char*>(init_counter), init_counter_size);
207 base::StringPiece plaintext_str(
208 reinterpret_cast<const char*>(plaintext), plaintext_size);
209
210 EXPECT_TRUE(encryptor.SetCounter(init_counter_str));
211 std::string encrypted;
212 EXPECT_TRUE(encryptor.Encrypt(plaintext_str, &encrypted));
213
214 EXPECT_EQ(ciphertext_size, encrypted.size());
215 EXPECT_EQ(0, memcmp(encrypted.data(), ciphertext, encrypted.size()));
216
[email protected]bd2d54c2013-09-30 09:08:47217 std::string decrypted;
[email protected]a3f742692013-06-13 19:48:01218 EXPECT_TRUE(encryptor.SetCounter(init_counter_str));
[email protected]bd2d54c2013-09-30 09:08:47219 EXPECT_TRUE(encryptor.Decrypt(encrypted, &decrypted));
[email protected]a3f742692013-06-13 19:48:01220
[email protected]bd2d54c2013-09-30 09:08:47221 EXPECT_EQ(plaintext_str, decrypted);
David Benjamin3efdcb72020-06-16 22:33:09222
223 // Repeat the test with the bytes API.
224 EXPECT_TRUE(
225 encryptor.SetCounter(base::make_span(init_counter, init_counter_size)));
226 std::vector<uint8_t> encrypted_vec;
227 EXPECT_TRUE(encryptor.Encrypt(base::make_span(plaintext, plaintext_size),
228 &encrypted_vec));
229
230 EXPECT_EQ(ciphertext_size, encrypted_vec.size());
231 EXPECT_EQ(0, memcmp(encrypted_vec.data(), ciphertext, encrypted_vec.size()));
232
233 std::vector<uint8_t> decrypted_vec;
234 EXPECT_TRUE(
235 encryptor.SetCounter(base::make_span(init_counter, init_counter_size)));
236 EXPECT_TRUE(encryptor.Decrypt(encrypted_vec, &decrypted_vec));
237
238 EXPECT_EQ(std::vector<uint8_t>(plaintext, plaintext + plaintext_size),
239 decrypted_vec);
[email protected]a3f742692013-06-13 19:48:01240}
241
242void TestAESCTRMultipleDecrypt(
243 const unsigned char* key, size_t key_size,
244 const unsigned char* init_counter, size_t init_counter_size,
245 const unsigned char* plaintext, size_t plaintext_size,
246 const unsigned char* ciphertext, size_t ciphertext_size) {
247 std::string key_str(reinterpret_cast<const char*>(key), key_size);
thakisd1a18472016-04-08 22:30:41248 std::unique_ptr<crypto::SymmetricKey> sym_key(
249 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key_str));
[email protected]a3f742692013-06-13 19:48:01250 ASSERT_TRUE(sym_key.get());
251
252 crypto::Encryptor encryptor;
253 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
254
255 // Counter is set only once.
256 EXPECT_TRUE(encryptor.SetCounter(base::StringPiece(
257 reinterpret_cast<const char*>(init_counter), init_counter_size)));
258
259 std::string ciphertext_str(reinterpret_cast<const char*>(ciphertext),
260 ciphertext_size);
261
262 int kTestDecryptSizes[] = { 32, 16, 8 };
263
264 int offset = 0;
Avi Drissman34f6b422018-12-25 20:29:39265 for (size_t i = 0; i < base::size(kTestDecryptSizes); ++i) {
[email protected]bd2d54c2013-09-30 09:08:47266 std::string decrypted;
[email protected]a3f742692013-06-13 19:48:01267 size_t len = kTestDecryptSizes[i];
268 EXPECT_TRUE(
[email protected]bd2d54c2013-09-30 09:08:47269 encryptor.Decrypt(ciphertext_str.substr(offset, len), &decrypted));
270 EXPECT_EQ(len, decrypted.size());
271 EXPECT_EQ(0, memcmp(decrypted.data(), plaintext + offset, len));
[email protected]a3f742692013-06-13 19:48:01272 offset += len;
273 }
274}
275
276} // namespace
277
278TEST(EncryptorTest, EncryptAES128CTR) {
Avi Drissman34f6b422018-12-25 20:29:39279 TestAESCTREncrypt(kAES128CTRKey, base::size(kAES128CTRKey),
280 kAESCTRInitCounter, base::size(kAESCTRInitCounter),
281 kAESCTRPlaintext, base::size(kAESCTRPlaintext),
282 kAES128CTRCiphertext, base::size(kAES128CTRCiphertext));
[email protected]a3f742692013-06-13 19:48:01283}
284
285TEST(EncryptorTest, EncryptAES256CTR) {
Avi Drissman34f6b422018-12-25 20:29:39286 TestAESCTREncrypt(kAES256CTRKey, base::size(kAES256CTRKey),
287 kAESCTRInitCounter, base::size(kAESCTRInitCounter),
288 kAESCTRPlaintext, base::size(kAESCTRPlaintext),
289 kAES256CTRCiphertext, base::size(kAES256CTRCiphertext));
[email protected]a3f742692013-06-13 19:48:01290}
291
292TEST(EncryptorTest, EncryptAES128CTR_MultipleDecrypt) {
Avi Drissman34f6b422018-12-25 20:29:39293 TestAESCTRMultipleDecrypt(kAES128CTRKey, base::size(kAES128CTRKey),
294 kAESCTRInitCounter, base::size(kAESCTRInitCounter),
295 kAESCTRPlaintext, base::size(kAESCTRPlaintext),
296 kAES128CTRCiphertext,
297 base::size(kAES128CTRCiphertext));
[email protected]a3f742692013-06-13 19:48:01298}
299
300TEST(EncryptorTest, EncryptAES256CTR_MultipleDecrypt) {
Avi Drissman34f6b422018-12-25 20:29:39301 TestAESCTRMultipleDecrypt(kAES256CTRKey, base::size(kAES256CTRKey),
302 kAESCTRInitCounter, base::size(kAESCTRInitCounter),
303 kAESCTRPlaintext, base::size(kAESCTRPlaintext),
304 kAES256CTRCiphertext,
305 base::size(kAES256CTRCiphertext));
[email protected]a3f742692013-06-13 19:48:01306}
[email protected]2377cdee2011-06-24 20:46:06307
308TEST(EncryptorTest, EncryptDecryptCTR) {
thakisd1a18472016-04-08 22:30:41309 std::unique_ptr<crypto::SymmetricKey> key(
[email protected]a3f742692013-06-13 19:48:01310 crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 128));
[email protected]2377cdee2011-06-24 20:46:06311
[email protected]a3f742692013-06-13 19:48:01312 EXPECT_TRUE(key.get());
[email protected]2377cdee2011-06-24 20:46:06313 const std::string kInitialCounter = "0000000000000000";
314
315 crypto::Encryptor encryptor;
316 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CTR, ""));
317 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
318
319 std::string plaintext("normal plaintext of random length");
320 std::string ciphertext;
321 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
322 EXPECT_LT(0U, ciphertext.size());
323
[email protected]bd2d54c2013-09-30 09:08:47324 std::string decrypted;
[email protected]2377cdee2011-06-24 20:46:06325 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
[email protected]bd2d54c2013-09-30 09:08:47326 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
327 EXPECT_EQ(plaintext, decrypted);
[email protected]2377cdee2011-06-24 20:46:06328
329 plaintext = "0123456789012345";
330 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
331 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
332 EXPECT_LT(0U, ciphertext.size());
333
334 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
[email protected]bd2d54c2013-09-30 09:08:47335 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
336 EXPECT_EQ(plaintext, decrypted);
[email protected]2377cdee2011-06-24 20:46:06337}
338
[email protected]692033a2010-04-09 18:40:50339// TODO(wtc): add more known-answer tests. Test vectors are available from
340// http://www.ietf.org/rfc/rfc3602
341// http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
342// http://gladman.plushost.co.uk/oldsite/AES/index.php
343// http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
344
[email protected]692033a2010-04-09 18:40:50345// NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
346TEST(EncryptorTest, EncryptAES256CBC) {
347 // From NIST SP 800-38a test cast F.2.5 CBC-AES256.Encrypt.
[email protected]a3f742692013-06-13 19:48:01348 static const unsigned char kRawKey[] = {
[email protected]692033a2010-04-09 18:40:50349 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
350 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
351 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
352 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
353 };
[email protected]a3f742692013-06-13 19:48:01354 static const unsigned char kRawIv[] = {
[email protected]692033a2010-04-09 18:40:50355 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
356 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
357 };
[email protected]a3f742692013-06-13 19:48:01358 static const unsigned char kRawPlaintext[] = {
[email protected]692033a2010-04-09 18:40:50359 // Block #1
360 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
361 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
362 // Block #2
363 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
364 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
365 // Block #3
366 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
367 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
368 // Block #4
369 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
370 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
371 };
[email protected]a3f742692013-06-13 19:48:01372 static const unsigned char kRawCiphertext[] = {
[email protected]692033a2010-04-09 18:40:50373 // Block #1
374 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
375 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
376 // Block #2
377 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
378 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
379 // Block #3
380 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
381 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
382 // Block #4
383 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
384 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
385 // PKCS #5 padding, encrypted.
386 0x3f, 0x46, 0x17, 0x96, 0xd6, 0xb0, 0xd6, 0xb2,
387 0xe0, 0xc2, 0xa7, 0x2b, 0x4d, 0x80, 0xe6, 0x44
388 };
389
[email protected]a3f742692013-06-13 19:48:01390 std::string key(reinterpret_cast<const char*>(kRawKey), sizeof(kRawKey));
thakisd1a18472016-04-08 22:30:41391 std::unique_ptr<crypto::SymmetricKey> sym_key(
392 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
[email protected]a3f742692013-06-13 19:48:01393 ASSERT_TRUE(sym_key.get());
[email protected]692033a2010-04-09 18:40:50394
[email protected]4b559b4d2011-04-14 17:37:14395 crypto::Encryptor encryptor;
[email protected]692033a2010-04-09 18:40:50396 // The IV must be exactly as long a the cipher block size.
[email protected]a3f742692013-06-13 19:48:01397 std::string iv(reinterpret_cast<const char*>(kRawIv), sizeof(kRawIv));
[email protected]692033a2010-04-09 18:40:50398 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14399 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]692033a2010-04-09 18:40:50400
[email protected]a3f742692013-06-13 19:48:01401 std::string plaintext(reinterpret_cast<const char*>(kRawPlaintext),
402 sizeof(kRawPlaintext));
[email protected]692033a2010-04-09 18:40:50403 std::string ciphertext;
404 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
405
[email protected]a3f742692013-06-13 19:48:01406 EXPECT_EQ(sizeof(kRawCiphertext), ciphertext.size());
407 EXPECT_EQ(0, memcmp(ciphertext.data(), kRawCiphertext, ciphertext.size()));
[email protected]692033a2010-04-09 18:40:50408
[email protected]bd2d54c2013-09-30 09:08:47409 std::string decrypted;
410 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
[email protected]692033a2010-04-09 18:40:50411
[email protected]bd2d54c2013-09-30 09:08:47412 EXPECT_EQ(plaintext, decrypted);
[email protected]692033a2010-04-09 18:40:50413}
[email protected]25007102010-11-12 16:29:06414
415// Expected output derived from the NSS implementation.
416TEST(EncryptorTest, EncryptAES128CBCRegression) {
417 std::string key = "128=SixteenBytes";
418 std::string iv = "Sweet Sixteen IV";
419 std::string plaintext = "Plain text with a g-clef U+1D11E \360\235\204\236";
420 std::string expected_ciphertext_hex =
421 "D4A67A0BA33C30F207344D81D1E944BBE65587C3D7D9939A"
422 "C070C62B9C15A3EA312EA4AD1BC7929F4D3C16B03AD5ADA8";
423
thakisd1a18472016-04-08 22:30:41424 std::unique_ptr<crypto::SymmetricKey> sym_key(
425 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
[email protected]a3f742692013-06-13 19:48:01426 ASSERT_TRUE(sym_key.get());
[email protected]25007102010-11-12 16:29:06427
[email protected]4b559b4d2011-04-14 17:37:14428 crypto::Encryptor encryptor;
[email protected]25007102010-11-12 16:29:06429 // The IV must be exactly as long a the cipher block size.
430 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14431 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06432
433 std::string ciphertext;
434 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
435 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
436 ciphertext.size()));
437
[email protected]bd2d54c2013-09-30 09:08:47438 std::string decrypted;
439 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
440 EXPECT_EQ(plaintext, decrypted);
[email protected]25007102010-11-12 16:29:06441}
442
[email protected]19702762014-07-31 01:03:05443// Symmetric keys with an unsupported size should be rejected. Whether they are
444// rejected by SymmetricKey::Import or Encryptor::Init depends on the platform.
[email protected]25007102010-11-12 16:29:06445TEST(EncryptorTest, UnsupportedKeySize) {
446 std::string key = "7 = bad";
447 std::string iv = "Sweet Sixteen IV";
thakisd1a18472016-04-08 22:30:41448 std::unique_ptr<crypto::SymmetricKey> sym_key(
449 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
[email protected]19702762014-07-31 01:03:05450 if (!sym_key.get())
451 return;
[email protected]25007102010-11-12 16:29:06452
[email protected]4b559b4d2011-04-14 17:37:14453 crypto::Encryptor encryptor;
[email protected]19702762014-07-31 01:03:05454 // The IV must be exactly as long as the cipher block size.
[email protected]25007102010-11-12 16:29:06455 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14456 EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06457}
[email protected]25007102010-11-12 16:29:06458
459TEST(EncryptorTest, UnsupportedIV) {
460 std::string key = "128=SixteenBytes";
461 std::string iv = "OnlyForteen :(";
thakisd1a18472016-04-08 22:30:41462 std::unique_ptr<crypto::SymmetricKey> sym_key(
463 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
[email protected]a3f742692013-06-13 19:48:01464 ASSERT_TRUE(sym_key.get());
[email protected]25007102010-11-12 16:29:06465
[email protected]4b559b4d2011-04-14 17:37:14466 crypto::Encryptor encryptor;
467 EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06468}
469
470TEST(EncryptorTest, EmptyEncrypt) {
471 std::string key = "128=SixteenBytes";
472 std::string iv = "Sweet Sixteen IV";
473 std::string plaintext;
474 std::string expected_ciphertext_hex = "8518B8878D34E7185E300D0FCC426396";
475
thakisd1a18472016-04-08 22:30:41476 std::unique_ptr<crypto::SymmetricKey> sym_key(
477 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
[email protected]a3f742692013-06-13 19:48:01478 ASSERT_TRUE(sym_key.get());
[email protected]25007102010-11-12 16:29:06479
[email protected]4b559b4d2011-04-14 17:37:14480 crypto::Encryptor encryptor;
[email protected]25007102010-11-12 16:29:06481 // The IV must be exactly as long a the cipher block size.
482 EXPECT_EQ(16U, iv.size());
[email protected]4b559b4d2011-04-14 17:37:14483 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
[email protected]25007102010-11-12 16:29:06484
485 std::string ciphertext;
486 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
487 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext.data(),
488 ciphertext.size()));
489}
[email protected]1a39c7b2013-10-01 10:34:27490
491TEST(EncryptorTest, CipherTextNotMultipleOfBlockSize) {
492 std::string key = "128=SixteenBytes";
493 std::string iv = "Sweet Sixteen IV";
494
thakisd1a18472016-04-08 22:30:41495 std::unique_ptr<crypto::SymmetricKey> sym_key(
496 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
[email protected]1a39c7b2013-10-01 10:34:27497 ASSERT_TRUE(sym_key.get());
498
499 crypto::Encryptor encryptor;
500 // The IV must be exactly as long a the cipher block size.
501 EXPECT_EQ(16U, iv.size());
502 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
503
504 // Use a separately allocated array to improve the odds of the memory tools
505 // catching invalid accesses.
506 //
507 // Otherwise when using std::string as the other tests do, accesses several
508 // bytes off the end of the buffer may fall inside the reservation of
509 // the string and not be detected.
thakisd1a18472016-04-08 22:30:41510 std::unique_ptr<char[]> ciphertext(new char[1]);
[email protected]1a39c7b2013-10-01 10:34:27511
512 std::string plaintext;
513 EXPECT_FALSE(
514 encryptor.Decrypt(base::StringPiece(ciphertext.get(), 1), &plaintext));
515}