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 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/351564777): Remove this and convert code to safer constructs.
7 #pragma allow_unsafe_buffers
8 #endif
9
10 #include "crypto/encryptor.h"
11
12 #include <stddef.h>
13
14 #include <memory>
15 #include <string>
16
17 #include "base/containers/heap_array.h"
18 #include "base/containers/span.h"
19 #include "base/strings/string_number_conversions.h"
20 #include "crypto/symmetric_key.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22
TEST(EncryptorTest,EncryptDecrypt)23 TEST(EncryptorTest, EncryptDecrypt) {
24 std::unique_ptr<crypto::SymmetricKey> key(
25 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
26 crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256));
27 EXPECT_TRUE(key.get());
28
29 crypto::Encryptor encryptor;
30 // The IV must be exactly as long as the cipher block size.
31 std::string iv("the iv: 16 bytes");
32 EXPECT_EQ(16U, iv.size());
33 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CBC, iv));
34
35 std::string plaintext("this is the plaintext");
36 std::string ciphertext;
37 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
38 EXPECT_LT(0U, ciphertext.size());
39
40 std::string decrypted;
41 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
42 EXPECT_EQ(plaintext, decrypted);
43
44 // Repeat the test with the bytes API.
45 std::vector<uint8_t> plaintext_vec(plaintext.begin(), plaintext.end());
46 std::vector<uint8_t> ciphertext_vec;
47 EXPECT_TRUE(encryptor.Encrypt(plaintext_vec, &ciphertext_vec));
48 EXPECT_LT(0U, ciphertext_vec.size());
49
50 std::vector<uint8_t> decrypted_vec;
51 EXPECT_TRUE(encryptor.Decrypt(ciphertext_vec, &decrypted_vec));
52 EXPECT_EQ(plaintext_vec, decrypted_vec);
53 }
54
TEST(EncryptorTest,DecryptWrongKey)55 TEST(EncryptorTest, DecryptWrongKey) {
56 std::unique_ptr<crypto::SymmetricKey> key(
57 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
58 crypto::SymmetricKey::AES, "password", "saltiest", 1000, 256));
59 EXPECT_TRUE(key.get());
60
61 // A wrong key that can be detected by implementations that validate every
62 // byte in the padding.
63 std::unique_ptr<crypto::SymmetricKey> wrong_key(
64 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
65 crypto::SymmetricKey::AES, "wrongword", "sweetest", 1000, 256));
66 EXPECT_TRUE(wrong_key.get());
67
68 // A wrong key that can't be detected by any implementation. The password
69 // "wrongword;" would also work.
70 std::unique_ptr<crypto::SymmetricKey> wrong_key2(
71 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
72 crypto::SymmetricKey::AES, "wrongword+", "sweetest", 1000, 256));
73 EXPECT_TRUE(wrong_key2.get());
74
75 // A wrong key that can be detected by all implementations.
76 std::unique_ptr<crypto::SymmetricKey> wrong_key3(
77 crypto::SymmetricKey::DeriveKeyFromPasswordUsingPbkdf2(
78 crypto::SymmetricKey::AES, "wrongwordx", "sweetest", 1000, 256));
79 EXPECT_TRUE(wrong_key3.get());
80
81 crypto::Encryptor encryptor;
82 // The IV must be exactly as long as the cipher block size.
83 std::string iv("the iv: 16 bytes");
84 EXPECT_EQ(16U, iv.size());
85 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CBC, iv));
86
87 std::string plaintext("this is the plaintext");
88 std::string ciphertext;
89 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
90
91 static const unsigned char expected_ciphertext[] = {
92 0x7D, 0x67, 0x5B, 0x53, 0xE6, 0xD8, 0x0F, 0x27,
93 0x74, 0xB1, 0x90, 0xFE, 0x6E, 0x58, 0x4A, 0xA0,
94 0x0E, 0x35, 0xE3, 0x01, 0xC0, 0xFE, 0x9A, 0xD8,
95 0x48, 0x1D, 0x42, 0xB0, 0xBA, 0x21, 0xB2, 0x0C
96 };
97
98 ASSERT_EQ(std::size(expected_ciphertext), ciphertext.size());
99 for (size_t i = 0; i < ciphertext.size(); ++i) {
100 ASSERT_EQ(expected_ciphertext[i],
101 static_cast<unsigned char>(ciphertext[i]));
102 }
103
104 std::string decrypted;
105
106 // This wrong key causes the last padding byte to be 5, which is a valid
107 // padding length, and the second to last padding byte to be 137, which is
108 // invalid. If an implementation simply uses the last padding byte to
109 // determine the padding length without checking every padding byte,
110 // Encryptor::Decrypt() will still return true. This is the case for NSS
111 // (crbug.com/124434).
112 crypto::Encryptor decryptor;
113 EXPECT_TRUE(decryptor.Init(wrong_key.get(), crypto::Encryptor::CBC, iv));
114 EXPECT_FALSE(decryptor.Decrypt(ciphertext, &decrypted));
115
116 // This demonstrates that not all wrong keys can be detected by padding
117 // error. This wrong key causes the last padding byte to be 1, which is
118 // a valid padding block of length 1.
119 crypto::Encryptor decryptor2;
120 EXPECT_TRUE(decryptor2.Init(wrong_key2.get(), crypto::Encryptor::CBC, iv));
121 EXPECT_TRUE(decryptor2.Decrypt(ciphertext, &decrypted));
122
123 // This wrong key causes the last padding byte to be 253, which should be
124 // rejected by all implementations.
125 crypto::Encryptor decryptor3;
126 EXPECT_TRUE(decryptor3.Init(wrong_key3.get(), crypto::Encryptor::CBC, iv));
127 EXPECT_FALSE(decryptor3.Decrypt(ciphertext, &decrypted));
128 }
129
130 namespace {
131
132 // From NIST SP 800-38a test cast:
133 // - F.5.1 CTR-AES128.Encrypt
134 // - F.5.6 CTR-AES256.Encrypt
135 // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
136 const unsigned char kAES128CTRKey[] = {
137 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
138 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
139 };
140
141 const unsigned char kAES256CTRKey[] = {
142 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
143 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
144 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
145 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
146 };
147
148 const unsigned char kAESCTRInitCounter[] = {
149 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
150 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
151 };
152
153 const unsigned char kAESCTRPlaintext[] = {
154 // Block #1
155 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
156 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
157 // Block #2
158 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
159 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
160 // Block #3
161 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
162 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
163 // Block #4
164 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
165 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10
166 };
167
168 const unsigned char kAES128CTRCiphertext[] = {
169 // Block #1
170 0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26,
171 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
172 // Block #2
173 0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff,
174 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff,
175 // Block #3
176 0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e,
177 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab,
178 // Block #4
179 0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1,
180 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee
181 };
182
183 const unsigned char kAES256CTRCiphertext[] = {
184 // Block #1
185 0x60, 0x1e, 0xc3, 0x13, 0x77, 0x57, 0x89, 0xa5,
186 0xb7, 0xa7, 0xf5, 0x04, 0xbb, 0xf3, 0xd2, 0x28,
187 // Block #2
188 0xf4, 0x43, 0xe3, 0xca, 0x4d, 0x62, 0xb5, 0x9a,
189 0xca, 0x84, 0xe9, 0x90, 0xca, 0xca, 0xf5, 0xc5,
190 // Block #3
191 0x2b, 0x09, 0x30, 0xda, 0xa2, 0x3d, 0xe9, 0x4c,
192 0xe8, 0x70, 0x17, 0xba, 0x2d, 0x84, 0x98, 0x8d,
193 // Block #4
194 0xdf, 0xc9, 0xc5, 0x8d, 0xb6, 0x7a, 0xad, 0xa6,
195 0x13, 0xc2, 0xdd, 0x08, 0x45, 0x79, 0x41, 0xa6
196 };
197
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)198 void TestAESCTREncrypt(
199 const unsigned char* key, size_t key_size,
200 const unsigned char* init_counter, size_t init_counter_size,
201 const unsigned char* plaintext, size_t plaintext_size,
202 const unsigned char* ciphertext, size_t ciphertext_size) {
203 std::string key_str(reinterpret_cast<const char*>(key), key_size);
204 std::unique_ptr<crypto::SymmetricKey> sym_key(
205 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key_str));
206 ASSERT_TRUE(sym_key.get());
207
208 crypto::Encryptor encryptor;
209 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
210
211 std::string_view init_counter_str(reinterpret_cast<const char*>(init_counter),
212 init_counter_size);
213 std::string_view plaintext_str(reinterpret_cast<const char*>(plaintext),
214 plaintext_size);
215
216 EXPECT_TRUE(encryptor.SetCounter(init_counter_str));
217 std::string encrypted;
218 EXPECT_TRUE(encryptor.Encrypt(plaintext_str, &encrypted));
219
220 EXPECT_EQ(ciphertext_size, encrypted.size());
221 EXPECT_EQ(0, memcmp(encrypted.data(), ciphertext, encrypted.size()));
222
223 std::string decrypted;
224 EXPECT_TRUE(encryptor.SetCounter(init_counter_str));
225 EXPECT_TRUE(encryptor.Decrypt(encrypted, &decrypted));
226
227 EXPECT_EQ(plaintext_str, decrypted);
228
229 // Repeat the test with the bytes API.
230 EXPECT_TRUE(
231 encryptor.SetCounter(base::span(init_counter, init_counter_size)));
232 std::vector<uint8_t> encrypted_vec;
233 EXPECT_TRUE(
234 encryptor.Encrypt(base::span(plaintext, plaintext_size), &encrypted_vec));
235
236 EXPECT_EQ(ciphertext_size, encrypted_vec.size());
237 EXPECT_EQ(0, memcmp(encrypted_vec.data(), ciphertext, encrypted_vec.size()));
238
239 std::vector<uint8_t> decrypted_vec;
240 EXPECT_TRUE(
241 encryptor.SetCounter(base::span(init_counter, init_counter_size)));
242 EXPECT_TRUE(encryptor.Decrypt(encrypted_vec, &decrypted_vec));
243
244 EXPECT_EQ(std::vector<uint8_t>(plaintext, plaintext + plaintext_size),
245 decrypted_vec);
246 }
247
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)248 void TestAESCTRMultipleDecrypt(
249 const unsigned char* key, size_t key_size,
250 const unsigned char* init_counter, size_t init_counter_size,
251 const unsigned char* plaintext, size_t plaintext_size,
252 const unsigned char* ciphertext, size_t ciphertext_size) {
253 std::string key_str(reinterpret_cast<const char*>(key), key_size);
254 std::unique_ptr<crypto::SymmetricKey> sym_key(
255 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key_str));
256 ASSERT_TRUE(sym_key.get());
257
258 crypto::Encryptor encryptor;
259 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
260
261 // Counter is set only once.
262 EXPECT_TRUE(encryptor.SetCounter(std::string_view(
263 reinterpret_cast<const char*>(init_counter), init_counter_size)));
264
265 std::string ciphertext_str(reinterpret_cast<const char*>(ciphertext),
266 ciphertext_size);
267
268 int kTestDecryptSizes[] = { 32, 16, 8 };
269
270 int offset = 0;
271 for (size_t i = 0; i < std::size(kTestDecryptSizes); ++i) {
272 std::string decrypted;
273 size_t len = kTestDecryptSizes[i];
274 EXPECT_TRUE(
275 encryptor.Decrypt(ciphertext_str.substr(offset, len), &decrypted));
276 EXPECT_EQ(len, decrypted.size());
277 EXPECT_EQ(0, memcmp(decrypted.data(), plaintext + offset, len));
278 offset += len;
279 }
280 }
281
282 } // namespace
283
TEST(EncryptorTest,EncryptAES128CTR)284 TEST(EncryptorTest, EncryptAES128CTR) {
285 TestAESCTREncrypt(kAES128CTRKey, std::size(kAES128CTRKey), kAESCTRInitCounter,
286 std::size(kAESCTRInitCounter), kAESCTRPlaintext,
287 std::size(kAESCTRPlaintext), kAES128CTRCiphertext,
288 std::size(kAES128CTRCiphertext));
289 }
290
TEST(EncryptorTest,EncryptAES256CTR)291 TEST(EncryptorTest, EncryptAES256CTR) {
292 TestAESCTREncrypt(kAES256CTRKey, std::size(kAES256CTRKey), kAESCTRInitCounter,
293 std::size(kAESCTRInitCounter), kAESCTRPlaintext,
294 std::size(kAESCTRPlaintext), kAES256CTRCiphertext,
295 std::size(kAES256CTRCiphertext));
296 }
297
TEST(EncryptorTest,EncryptAES128CTR_MultipleDecrypt)298 TEST(EncryptorTest, EncryptAES128CTR_MultipleDecrypt) {
299 TestAESCTRMultipleDecrypt(kAES128CTRKey, std::size(kAES128CTRKey),
300 kAESCTRInitCounter, std::size(kAESCTRInitCounter),
301 kAESCTRPlaintext, std::size(kAESCTRPlaintext),
302 kAES128CTRCiphertext,
303 std::size(kAES128CTRCiphertext));
304 }
305
TEST(EncryptorTest,EncryptAES256CTR_MultipleDecrypt)306 TEST(EncryptorTest, EncryptAES256CTR_MultipleDecrypt) {
307 TestAESCTRMultipleDecrypt(kAES256CTRKey, std::size(kAES256CTRKey),
308 kAESCTRInitCounter, std::size(kAESCTRInitCounter),
309 kAESCTRPlaintext, std::size(kAESCTRPlaintext),
310 kAES256CTRCiphertext,
311 std::size(kAES256CTRCiphertext));
312 }
313
TEST(EncryptorTest,EncryptDecryptCTR)314 TEST(EncryptorTest, EncryptDecryptCTR) {
315 std::unique_ptr<crypto::SymmetricKey> key(
316 crypto::SymmetricKey::GenerateRandomKey(crypto::SymmetricKey::AES, 128));
317
318 EXPECT_TRUE(key.get());
319 const std::string kInitialCounter = "0000000000000000";
320
321 crypto::Encryptor encryptor;
322 EXPECT_TRUE(encryptor.Init(key.get(), crypto::Encryptor::CTR, ""));
323 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
324
325 std::string plaintext("normal plaintext of random length");
326 std::string ciphertext;
327 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
328 EXPECT_LT(0U, ciphertext.size());
329
330 std::string decrypted;
331 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
332 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
333 EXPECT_EQ(plaintext, decrypted);
334
335 plaintext = "0123456789012345";
336 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
337 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
338 EXPECT_LT(0U, ciphertext.size());
339
340 EXPECT_TRUE(encryptor.SetCounter(kInitialCounter));
341 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
342 EXPECT_EQ(plaintext, decrypted);
343 }
344
345 // TODO(wtc): add more known-answer tests. Test vectors are available from
346 // http://www.ietf.org/rfc/rfc3602
347 // http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
348 // http://gladman.plushost.co.uk/oldsite/AES/index.php
349 // http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip
350
351 // NIST SP 800-38A test vector F.2.5 CBC-AES256.Encrypt.
TEST(EncryptorTest,EncryptAES256CBC)352 TEST(EncryptorTest, EncryptAES256CBC) {
353 // From NIST SP 800-38a test cast F.2.5 CBC-AES256.Encrypt.
354 static const unsigned char kRawKey[] = {
355 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe,
356 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81,
357 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7,
358 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4
359 };
360 static const unsigned char kRawIv[] = {
361 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
362 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
363 };
364 static const unsigned char kRawPlaintext[] = {
365 // Block #1
366 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
367 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
368 // Block #2
369 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
370 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
371 // Block #3
372 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
373 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
374 // Block #4
375 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
376 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10,
377 };
378 static const unsigned char kRawCiphertext[] = {
379 // Block #1
380 0xf5, 0x8c, 0x4c, 0x04, 0xd6, 0xe5, 0xf1, 0xba,
381 0x77, 0x9e, 0xab, 0xfb, 0x5f, 0x7b, 0xfb, 0xd6,
382 // Block #2
383 0x9c, 0xfc, 0x4e, 0x96, 0x7e, 0xdb, 0x80, 0x8d,
384 0x67, 0x9f, 0x77, 0x7b, 0xc6, 0x70, 0x2c, 0x7d,
385 // Block #3
386 0x39, 0xf2, 0x33, 0x69, 0xa9, 0xd9, 0xba, 0xcf,
387 0xa5, 0x30, 0xe2, 0x63, 0x04, 0x23, 0x14, 0x61,
388 // Block #4
389 0xb2, 0xeb, 0x05, 0xe2, 0xc3, 0x9b, 0xe9, 0xfc,
390 0xda, 0x6c, 0x19, 0x07, 0x8c, 0x6a, 0x9d, 0x1b,
391 // PKCS #5 padding, encrypted.
392 0x3f, 0x46, 0x17, 0x96, 0xd6, 0xb0, 0xd6, 0xb2,
393 0xe0, 0xc2, 0xa7, 0x2b, 0x4d, 0x80, 0xe6, 0x44
394 };
395
396 std::string key(reinterpret_cast<const char*>(kRawKey), sizeof(kRawKey));
397 std::unique_ptr<crypto::SymmetricKey> sym_key(
398 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
399 ASSERT_TRUE(sym_key.get());
400
401 crypto::Encryptor encryptor;
402 // The IV must be exactly as long a the cipher block size.
403 std::string iv(reinterpret_cast<const char*>(kRawIv), sizeof(kRawIv));
404 EXPECT_EQ(16U, iv.size());
405 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
406
407 std::string plaintext(reinterpret_cast<const char*>(kRawPlaintext),
408 sizeof(kRawPlaintext));
409 std::string ciphertext;
410 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
411
412 EXPECT_EQ(sizeof(kRawCiphertext), ciphertext.size());
413 EXPECT_EQ(0, memcmp(ciphertext.data(), kRawCiphertext, ciphertext.size()));
414
415 std::string decrypted;
416 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
417
418 EXPECT_EQ(plaintext, decrypted);
419 }
420
421 // Expected output derived from the NSS implementation.
TEST(EncryptorTest,EncryptAES128CBCRegression)422 TEST(EncryptorTest, EncryptAES128CBCRegression) {
423 std::string key = "128=SixteenBytes";
424 std::string iv = "Sweet Sixteen IV";
425 std::string plaintext = "Plain text with a g-clef U+1D11E \360\235\204\236";
426 std::string expected_ciphertext_hex =
427 "D4A67A0BA33C30F207344D81D1E944BBE65587C3D7D9939A"
428 "C070C62B9C15A3EA312EA4AD1BC7929F4D3C16B03AD5ADA8";
429
430 std::unique_ptr<crypto::SymmetricKey> sym_key(
431 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
432 ASSERT_TRUE(sym_key.get());
433
434 crypto::Encryptor encryptor;
435 // The IV must be exactly as long a the cipher block size.
436 EXPECT_EQ(16U, iv.size());
437 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
438
439 std::string ciphertext;
440 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
441 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext));
442
443 std::string decrypted;
444 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
445 EXPECT_EQ(plaintext, decrypted);
446 }
447
448 // Symmetric keys with an unsupported size should be rejected. Whether they are
449 // rejected by SymmetricKey::Import or Encryptor::Init depends on the platform.
TEST(EncryptorTest,UnsupportedKeySize)450 TEST(EncryptorTest, UnsupportedKeySize) {
451 std::string key = "7 = bad";
452 std::string iv = "Sweet Sixteen IV";
453 std::unique_ptr<crypto::SymmetricKey> sym_key(
454 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
455 if (!sym_key.get())
456 return;
457
458 crypto::Encryptor encryptor;
459 // The IV must be exactly as long as the cipher block size.
460 EXPECT_EQ(16U, iv.size());
461 EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
462 }
463
TEST(EncryptorTest,UnsupportedIV)464 TEST(EncryptorTest, UnsupportedIV) {
465 std::string key = "128=SixteenBytes";
466 std::string iv = "OnlyForteen :(";
467 std::unique_ptr<crypto::SymmetricKey> sym_key(
468 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
469 ASSERT_TRUE(sym_key.get());
470
471 crypto::Encryptor encryptor;
472 EXPECT_FALSE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
473 }
474
TEST(EncryptorTest,EmptyEncryptCBC)475 TEST(EncryptorTest, EmptyEncryptCBC) {
476 std::string key = "128=SixteenBytes";
477 std::string iv = "Sweet Sixteen IV";
478 std::string plaintext;
479 std::string expected_ciphertext_hex = "8518B8878D34E7185E300D0FCC426396";
480
481 std::unique_ptr<crypto::SymmetricKey> sym_key(
482 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
483 ASSERT_TRUE(sym_key.get());
484
485 crypto::Encryptor encryptor;
486 // The IV must be exactly as long as the cipher block size.
487 EXPECT_EQ(16U, iv.size());
488 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
489
490 std::string ciphertext;
491 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
492 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext));
493
494 std::string decrypted;
495 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
496 EXPECT_EQ(decrypted, plaintext);
497
498 // Decrypting the empty string should fail. Our formulation of CBC expects a
499 // full block of padding for CBC.
500 EXPECT_FALSE(encryptor.Decrypt(std::string(), &decrypted));
501
502 // Repeat the test with the byte-based API.
503 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
504 std::vector<uint8_t> ciphertext_bytes;
505 EXPECT_TRUE(
506 encryptor.Encrypt(base::span<const uint8_t>(), &ciphertext_bytes));
507 EXPECT_EQ(expected_ciphertext_hex, base::HexEncode(ciphertext_bytes));
508
509 std::vector<uint8_t> decrypted_bytes;
510 EXPECT_TRUE(encryptor.Decrypt(ciphertext_bytes, &decrypted_bytes));
511 EXPECT_EQ(decrypted_bytes.size(), 0u);
512
513 // Decrypting the empty string should fail. Our formulation of CBC expects a
514 // full block of padding for CBC.
515 EXPECT_FALSE(
516 encryptor.Decrypt(base::span<const uint8_t>(), &decrypted_bytes));
517 }
518
TEST(EncryptorTest,EmptyEncryptCTR)519 TEST(EncryptorTest, EmptyEncryptCTR) {
520 std::string key = "128=SixteenBytes";
521 std::string iv = "Sweet Sixteen IV";
522 std::string plaintext;
523 std::string expected_ciphertext;
524
525 std::unique_ptr<crypto::SymmetricKey> sym_key(
526 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
527 ASSERT_TRUE(sym_key.get());
528
529 crypto::Encryptor encryptor;
530 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CTR, ""));
531 ASSERT_TRUE(encryptor.SetCounter(iv));
532
533 std::string ciphertext;
534 EXPECT_TRUE(encryptor.Encrypt(plaintext, &ciphertext));
535 EXPECT_EQ(expected_ciphertext, ciphertext);
536
537 std::string decrypted;
538 EXPECT_TRUE(encryptor.Decrypt(ciphertext, &decrypted));
539 EXPECT_EQ(decrypted, plaintext);
540
541 // Repeat the test with the byte-based API.
542 ASSERT_TRUE(encryptor.SetCounter(iv));
543 std::vector<uint8_t> ciphertext_bytes;
544 EXPECT_TRUE(
545 encryptor.Encrypt(base::span<const uint8_t>(), &ciphertext_bytes));
546 EXPECT_EQ(ciphertext_bytes.size(), 0u);
547
548 std::vector<uint8_t> decrypted_bytes;
549 EXPECT_TRUE(encryptor.Decrypt(base::span<const uint8_t>(), &decrypted_bytes));
550 EXPECT_EQ(decrypted_bytes.size(), 0u);
551 }
552
TEST(EncryptorTest,CipherTextNotMultipleOfBlockSize)553 TEST(EncryptorTest, CipherTextNotMultipleOfBlockSize) {
554 std::string key = "128=SixteenBytes";
555 std::string iv = "Sweet Sixteen IV";
556
557 std::unique_ptr<crypto::SymmetricKey> sym_key(
558 crypto::SymmetricKey::Import(crypto::SymmetricKey::AES, key));
559 ASSERT_TRUE(sym_key.get());
560
561 crypto::Encryptor encryptor;
562 // The IV must be exactly as long a the cipher block size.
563 EXPECT_EQ(16U, iv.size());
564 EXPECT_TRUE(encryptor.Init(sym_key.get(), crypto::Encryptor::CBC, iv));
565
566 // Use a separately allocated array to improve the odds of the memory tools
567 // catching invalid accesses.
568 //
569 // Otherwise when using std::string as the other tests do, accesses several
570 // bytes off the end of the buffer may fall inside the reservation of
571 // the string and not be detected.
572 auto ciphertext = base::HeapArray<char>::Uninit(1);
573
574 std::string plaintext;
575 EXPECT_FALSE(
576 encryptor.Decrypt(base::as_string_view(ciphertext), &plaintext));
577 }
578