1 // Copyright 2012 The Chromium Authors
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 <stddef.h>
8
9 #include <memory>
10 #include <string>
11
12 #include "base/containers/span.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "crypto/symmetric_key.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
TEST(EncryptorTest,EncryptDecrypt)17 TEST(EncryptorTest, EncryptDecrypt) {
18 std::unique_ptr<crypto::SymmetricKey> key(
19 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
20 crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256));
21 EXPECT_TRUE(key.get());
22
23 crypto::Encryptor encryptor;
24 // The IV must be exactly as long as the cipher block size.
25 std::string iv("the iv: 16 bytes");
26 EXPECT_EQ(16U, iv.size());
27 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CBC, iv));
28
29 std::string plaintext("this is the plaintext");
30 std::string ciphertext;
31 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
32 EXPECT_LT(0U, ciphertext.size());
33
34 std::string decrypted;
35 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
36 EXPECT_EQ(plaintext, decrypted);
37
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);
47 }
48
TEST(EncryptorTest,DecryptWrongKey)49 TEST(EncryptorTest, DecryptWrongKey) {
50 std::unique_ptr<crypto::SymmetricKey> key(
51 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
52 crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256));
53 EXPECT_TRUE(key.get());
54
55 // A wrong key that can be detected by implementations that validate every
56 // byte in the padding.
57 std::unique_ptr<crypto::SymmetricKey> wrong_key(
58 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
59 crypto::SymmetricKey::AES, "wrongword", "sweetest", 1000, 256));
60 EXPECT_TRUE(wrong_key.get());
61
62 // A wrong key that can't be detected by any implementation. The password
63 // "wrongword;" would also work.
64 std::unique_ptr<crypto::SymmetricKey> wrong_key2(
65 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
66 crypto::SymmetricKey::AES, "wrongword+", "sweetest", 1000, 256));
67 EXPECT_TRUE(wrong_key2.get());
68
69 // A wrong key that can be detected by all implementations.
70 std::unique_ptr<crypto::SymmetricKey> wrong_key3(
71 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
72 crypto::SymmetricKey::AES, "wrongwordx", "sweetest", 1000, 256));
73 EXPECT_TRUE(wrong_key3.get());
74
75 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
92 ASSERT_EQ(std::size(expected_ciphertext), ciphertext.size());
93 for (size_t i = 0; i < ciphertext.size(); ++i) {
94 ASSERT_EQ(expected_ciphertext[i],
95 static_cast<unsigned char>(ciphertext[i]));
96 }
97
98 std::string decrypted;
99
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
105 // (crbug.com/124434).
106 crypto::Encryptor decryptor;
107 EXPECT_TRUE(decryptor.Init(wrong_key.get(), crypto::Encryptor::CBC, iv));
108 EXPECT_FALSE(decryptor.Decrypt(ciphertext, &decrypted));
109
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));
115 EXPECT_TRUE(decryptor2.Decrypt(ciphertext, &decrypted));
116
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));
121 EXPECT_FALSE(decryptor3.Decrypt(ciphertext, &decrypted));
122 }
123
124 namespace {
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
130 const unsigned char kAES128CTRKey[] = {
131 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
132 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
133 };
134
135 const 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
142 const unsigned char kAESCTRInitCounter[] = {
143 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
144 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
145 };
146
147 const 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
162 const 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
177 const 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
TestAESCTREncrypt(const unsigned char * key,size_t key_size,const unsigned char * init_counter,size_t init_counter_size,const unsigned char * plaintext,size_t plaintext_size,const unsigned char * ciphertext,size_t ciphertext_size)192 void 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);
198 std::unique_ptr<crypto::SymmetricKey> sym_key(
199 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key_str));
200 ASSERT_TRUE(sym_key.get());
201
202 crypto::Encryptor encryptor;
203 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
204
205 std::string_view init_counter_str(reinterpret_cast<const char*>(init_counter),
206 init_counter_size);
207 std::string_view plaintext_str(reinterpret_cast<const char*>(plaintext),
208 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
217 std::string decrypted;
218 EXPECT_TRUE(encryptor.SetCounter(init_counter_str));
219 EXPECT_TRUE(encryptor.Decrypt(encrypted, &decrypted));
220
221 EXPECT_EQ(plaintext_str, decrypted);
222
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);
240 }
241
TestAESCTRMultipleDecrypt(const unsigned char * key,size_t key_size,const unsigned char * init_counter,size_t init_counter_size,const unsigned char * plaintext,size_t plaintext_size,const unsigned char * ciphertext,size_t ciphertext_size)242 void 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);
248 std::unique_ptr<crypto::SymmetricKey> sym_key(
249 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key_str));
250 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(std::string_view(
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;
265 for (size_t i = 0; i < std::size(kTestDecryptSizes); ++i) {
266 std::string decrypted;
267 size_t len = kTestDecryptSizes[i];
268 EXPECT_TRUE(
269 encryptor.Decrypt(ciphertext_str.substr(offset, len), &decrypted));
270 EXPECT_EQ(len, decrypted.size());
271 EXPECT_EQ(0, memcmp(decrypted.data(), plaintext + offset, len));
272 offset += len;
273 }
274 }
275
276 } // namespace
277
TEST(EncryptorTest,EncryptAES128CTR)278 TEST(EncryptorTest, EncryptAES128CTR) {
279 TestAESCTREncrypt(kAES128CTRKey, std::size(kAES128CTRKey), kAESCTRInitCounter,
280 std::size(kAESCTRInitCounter), kAESCTRPlaintext,
281 std::size(kAESCTRPlaintext), kAES128CTRCiphertext,
282 std::size(kAES128CTRCiphertext));
283 }
284
TEST(EncryptorTest,EncryptAES256CTR)285 TEST(EncryptorTest, EncryptAES256CTR) {
286 TestAESCTREncrypt(kAES256CTRKey, std::size(kAES256CTRKey), kAESCTRInitCounter,
287 std::size(kAESCTRInitCounter), kAESCTRPlaintext,
288 std::size(kAESCTRPlaintext), kAES256CTRCiphertext,
289 std::size(kAES256CTRCiphertext));
290 }
291
TEST(EncryptorTest,EncryptAES128CTR_MultipleDecrypt)292 TEST(EncryptorTest, EncryptAES128CTR_MultipleDecrypt) {
293 TestAESCTRMultipleDecrypt(kAES128CTRKey, std::size(kAES128CTRKey),
294 kAESCTRInitCounter, std::size(kAESCTRInitCounter),
295 kAESCTRPlaintext, std::size(kAESCTRPlaintext),
296 kAES128CTRCiphertext,
297 std::size(kAES128CTRCiphertext));
298 }
299
TEST(EncryptorTest,EncryptAES256CTR_MultipleDecrypt)300 TEST(EncryptorTest, EncryptAES256CTR_MultipleDecrypt) {
301 TestAESCTRMultipleDecrypt(kAES256CTRKey, std::size(kAES256CTRKey),
302 kAESCTRInitCounter, std::size(kAESCTRInitCounter),
303 kAESCTRPlaintext, std::size(kAESCTRPlaintext),
304 kAES256CTRCiphertext,
305 std::size(kAES256CTRCiphertext));
306 }
307
TEST(EncryptorTest,EncryptDecryptCTR)308 TEST(EncryptorTest, EncryptDecryptCTR) {
309 std::unique_ptr<crypto::SymmetricKey> key(
310 crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 128));
311
312 EXPECT_TRUE(key.get());
313 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
324 std::string decrypted;
325 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
326 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
327 EXPECT_EQ(plaintext, decrypted);
328
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));
335 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
336 EXPECT_EQ(plaintext, decrypted);
337 }
338
339 // 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
345 // NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
TEST(EncryptorTest,EncryptAES256CBC)346 TEST(EncryptorTest, EncryptAES256CBC) {
347 // From NIST SP 800-38a test cast F.2.5 CBC-AES256.Encrypt.
348 static const unsigned char kRawKey[] = {
349 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 };
354 static const unsigned char kRawIv[] = {
355 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
356 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
357 };
358 static const unsigned char kRawPlaintext[] = {
359 // 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 };
372 static const unsigned char kRawCiphertext[] = {
373 // 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
390 std::string key(reinterpret_cast<const char*>(kRawKey), sizeof(kRawKey));
391 std::unique_ptr<crypto::SymmetricKey> sym_key(
392 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
393 ASSERT_TRUE(sym_key.get());
394
395 crypto::Encryptor encryptor;
396 // The IV must be exactly as long a the cipher block size.
397 std::string iv(reinterpret_cast<const char*>(kRawIv), sizeof(kRawIv));
398 EXPECT_EQ(16U, iv.size());
399 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
400
401 std::string plaintext(reinterpret_cast<const char*>(kRawPlaintext),
402 sizeof(kRawPlaintext));
403 std::string ciphertext;
404 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
405
406 EXPECT_EQ(sizeof(kRawCiphertext), ciphertext.size());
407 EXPECT_EQ(0, memcmp(ciphertext.data(), kRawCiphertext, ciphertext.size()));
408
409 std::string decrypted;
410 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
411
412 EXPECT_EQ(plaintext, decrypted);
413 }
414
415 // Expected output derived from the NSS implementation.
TEST(EncryptorTest,EncryptAES128CBCRegression)416 TEST(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
424 std::unique_ptr<crypto::SymmetricKey> sym_key(
425 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
426 ASSERT_TRUE(sym_key.get());
427
428 crypto::Encryptor encryptor;
429 // The IV must be exactly as long a the cipher block size.
430 EXPECT_EQ(16U, iv.size());
431 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
432
433 std::string ciphertext;
434 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
435 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext));
436
437 std::string decrypted;
438 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
439 EXPECT_EQ(plaintext, decrypted);
440 }
441
442 // Symmetric keys with an unsupported size should be rejected. Whether they are
443 // rejected by SymmetricKey::Import or Encryptor::Init depends on the platform.
TEST(EncryptorTest,UnsupportedKeySize)444 TEST(EncryptorTest, UnsupportedKeySize) {
445 std::string key = "7 = bad";
446 std::string iv = "Sweet Sixteen IV";
447 std::unique_ptr<crypto::SymmetricKey> sym_key(
448 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
449 if (!sym_key.get())
450 return;
451
452 crypto::Encryptor encryptor;
453 // The IV must be exactly as long as the cipher block size.
454 EXPECT_EQ(16U, iv.size());
455 EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
456 }
457
TEST(EncryptorTest,UnsupportedIV)458 TEST(EncryptorTest, UnsupportedIV) {
459 std::string key = "128=SixteenBytes";
460 std::string iv = "OnlyForteen :(";
461 std::unique_ptr<crypto::SymmetricKey> sym_key(
462 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
463 ASSERT_TRUE(sym_key.get());
464
465 crypto::Encryptor encryptor;
466 EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
467 }
468
TEST(EncryptorTest,EmptyEncryptCBC)469 TEST(EncryptorTest, EmptyEncryptCBC) {
470 std::string key = "128=SixteenBytes";
471 std::string iv = "Sweet Sixteen IV";
472 std::string plaintext;
473 std::string expected_ciphertext_hex = "8518B8878D34E7185E300D0FCC426396";
474
475 std::unique_ptr<crypto::SymmetricKey> sym_key(
476 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
477 ASSERT_TRUE(sym_key.get());
478
479 crypto::Encryptor encryptor;
480 // The IV must be exactly as long as the cipher block size.
481 EXPECT_EQ(16U, iv.size());
482 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
483
484 std::string ciphertext;
485 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
486 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext));
487
488 std::string decrypted;
489 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
490 EXPECT_EQ(decrypted, plaintext);
491
492 // Decrypting the empty string should fail. Our formulation of CBC expects a
493 // full block of padding for CBC.
494 EXPECT_FALSE(encryptor.Decrypt(std::string(), &decrypted));
495
496 // Repeat the test with the byte-based API.
497 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
498 std::vector<uint8_t> ciphertext_bytes;
499 EXPECT_TRUE(
500 encryptor.Encrypt(base::span<const uint8_t>(), &ciphertext_bytes));
501 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext_bytes));
502
503 std::vector<uint8_t> decrypted_bytes;
504 EXPECT_TRUE(encryptor.Decrypt(ciphertext_bytes, &decrypted_bytes));
505 EXPECT_EQ(decrypted_bytes.size(), 0u);
506
507 // Decrypting the empty string should fail. Our formulation of CBC expects a
508 // full block of padding for CBC.
509 EXPECT_FALSE(
510 encryptor.Decrypt(base::span<const uint8_t>(), &decrypted_bytes));
511 }
512
TEST(EncryptorTest,EmptyEncryptCTR)513 TEST(EncryptorTest, EmptyEncryptCTR) {
514 std::string key = "128=SixteenBytes";
515 std::string iv = "Sweet Sixteen IV";
516 std::string plaintext;
517 std::string expected_ciphertext;
518
519 std::unique_ptr<crypto::SymmetricKey> sym_key(
520 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
521 ASSERT_TRUE(sym_key.get());
522
523 crypto::Encryptor encryptor;
524 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
525 ASSERT_TRUE(encryptor.SetCounter(iv));
526
527 std::string ciphertext;
528 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
529 EXPECT_EQ(expected_ciphertext, ciphertext);
530
531 std::string decrypted;
532 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
533 EXPECT_EQ(decrypted, plaintext);
534
535 // Repeat the test with the byte-based API.
536 ASSERT_TRUE(encryptor.SetCounter(iv));
537 std::vector<uint8_t> ciphertext_bytes;
538 EXPECT_TRUE(
539 encryptor.Encrypt(base::span<const uint8_t>(), &ciphertext_bytes));
540 EXPECT_EQ(ciphertext_bytes.size(), 0u);
541
542 std::vector<uint8_t> decrypted_bytes;
543 EXPECT_TRUE(encryptor.Decrypt(base::span<const uint8_t>(), &decrypted_bytes));
544 EXPECT_EQ(decrypted_bytes.size(), 0u);
545 }
546
TEST(EncryptorTest,CipherTextNotMultipleOfBlockSize)547 TEST(EncryptorTest, CipherTextNotMultipleOfBlockSize) {
548 std::string key = "128=SixteenBytes";
549 std::string iv = "Sweet Sixteen IV";
550
551 std::unique_ptr<crypto::SymmetricKey> sym_key(
552 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
553 ASSERT_TRUE(sym_key.get());
554
555 crypto::Encryptor encryptor;
556 // The IV must be exactly as long a the cipher block size.
557 EXPECT_EQ(16U, iv.size());
558 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
559
560 // Use a separately allocated array to improve the odds of the memory tools
561 // catching invalid accesses.
562 //
563 // Otherwise when using std::string as the other tests do, accesses several
564 // bytes off the end of the buffer may fall inside the reservation of
565 // the string and not be detected.
566 std::unique_ptr<char[]> ciphertext(new char[1]);
567
568 std::string plaintext;
569 EXPECT_FALSE(
570 encryptor.Decrypt(std::string_view(ciphertext.get(), 1), &plaintext));
571 }
572