1 /* Copyright (c) 2015, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18
19 #include <algorithm>
20 #include <memory>
21 #include <vector>
22
23 #include <gtest/gtest.h>
24
25 #include <openssl/aes.h>
26 #include <openssl/rand.h>
27
28 #include "internal.h"
29 #include "../../internal.h"
30 #include "../../test/abi_test.h"
31 #include "../../test/file_test.h"
32 #include "../../test/test_util.h"
33 #include "../../test/wycheproof_util.h"
34
35
TestRaw(FileTest * t)36 static void TestRaw(FileTest *t) {
37 std::vector<uint8_t> key, plaintext, ciphertext;
38 ASSERT_TRUE(t->GetBytes(&key, "Key"));
39 ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
40 ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext"));
41
42 ASSERT_EQ(static_cast<unsigned>(AES_BLOCK_SIZE), plaintext.size());
43 ASSERT_EQ(static_cast<unsigned>(AES_BLOCK_SIZE), ciphertext.size());
44
45 AES_KEY aes_key;
46 ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key));
47
48 // Test encryption.
49 uint8_t block[AES_BLOCK_SIZE];
50 AES_encrypt(plaintext.data(), block, &aes_key);
51 EXPECT_EQ(Bytes(ciphertext), Bytes(block));
52
53 // Test in-place encryption.
54 OPENSSL_memcpy(block, plaintext.data(), AES_BLOCK_SIZE);
55 AES_encrypt(block, block, &aes_key);
56 EXPECT_EQ(Bytes(ciphertext), Bytes(block));
57
58 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key));
59
60 // Test decryption.
61 AES_decrypt(ciphertext.data(), block, &aes_key);
62 EXPECT_EQ(Bytes(plaintext), Bytes(block));
63
64 // Test in-place decryption.
65 OPENSSL_memcpy(block, ciphertext.data(), AES_BLOCK_SIZE);
66 AES_decrypt(block, block, &aes_key);
67 EXPECT_EQ(Bytes(plaintext), Bytes(block));
68 }
69
TestKeyWrap(FileTest * t)70 static void TestKeyWrap(FileTest *t) {
71 // All test vectors use the default IV, so test both with implicit and
72 // explicit IV.
73 //
74 // TODO(davidben): Find test vectors that use a different IV.
75 static const uint8_t kDefaultIV[] = {
76 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
77 };
78
79 std::vector<uint8_t> key, plaintext, ciphertext;
80 ASSERT_TRUE(t->GetBytes(&key, "Key"));
81 ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
82 ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext"));
83
84 ASSERT_EQ(plaintext.size() + 8, ciphertext.size())
85 << "Invalid Plaintext and Ciphertext lengths.";
86
87 // Test encryption.
88 AES_KEY aes_key;
89 ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key));
90
91 // Test with implicit IV.
92 std::unique_ptr<uint8_t[]> buf(new uint8_t[ciphertext.size()]);
93 int len = AES_wrap_key(&aes_key, nullptr /* iv */, buf.get(),
94 plaintext.data(), plaintext.size());
95 ASSERT_GE(len, 0);
96 EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len)));
97
98 // Test with explicit IV.
99 OPENSSL_memset(buf.get(), 0, ciphertext.size());
100 len = AES_wrap_key(&aes_key, kDefaultIV, buf.get(), plaintext.data(),
101 plaintext.size());
102 ASSERT_GE(len, 0);
103 EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len)));
104
105 // Test decryption.
106 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key));
107
108 // Test with implicit IV.
109 buf.reset(new uint8_t[plaintext.size()]);
110 len = AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(), ciphertext.data(),
111 ciphertext.size());
112 ASSERT_GE(len, 0);
113 EXPECT_EQ(Bytes(plaintext), Bytes(buf.get(), static_cast<size_t>(len)));
114
115 // Test with explicit IV.
116 OPENSSL_memset(buf.get(), 0, plaintext.size());
117 len = AES_unwrap_key(&aes_key, kDefaultIV, buf.get(), ciphertext.data(),
118 ciphertext.size());
119 ASSERT_GE(len, 0);
120
121 // Test corrupted ciphertext.
122 ciphertext[0] ^= 1;
123 EXPECT_EQ(-1, AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(),
124 ciphertext.data(), ciphertext.size()));
125 }
126
TestKeyWrapWithPadding(FileTest * t)127 static void TestKeyWrapWithPadding(FileTest *t) {
128 std::vector<uint8_t> key, plaintext, ciphertext;
129 ASSERT_TRUE(t->GetBytes(&key, "Key"));
130 ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
131 ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext"));
132
133 // Test encryption.
134 AES_KEY aes_key;
135 ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key));
136 std::unique_ptr<uint8_t[]> buf(new uint8_t[plaintext.size() + 15]);
137 size_t len;
138 ASSERT_TRUE(AES_wrap_key_padded(&aes_key, buf.get(), &len,
139 plaintext.size() + 15, plaintext.data(),
140 plaintext.size()));
141 EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len)));
142
143 // Test decryption
144 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key));
145 buf.reset(new uint8_t[ciphertext.size() - 8]);
146 ASSERT_TRUE(AES_unwrap_key_padded(&aes_key, buf.get(), &len,
147 ciphertext.size() - 8, ciphertext.data(),
148 ciphertext.size()));
149 ASSERT_EQ(len, plaintext.size());
150 EXPECT_EQ(Bytes(plaintext), Bytes(buf.get(), static_cast<size_t>(len)));
151 }
152
TEST(AESTest,TestVectors)153 TEST(AESTest, TestVectors) {
154 FileTestGTest("crypto/fipsmodule/aes/aes_tests.txt", [](FileTest *t) {
155 if (t->GetParameter() == "Raw") {
156 TestRaw(t);
157 } else if (t->GetParameter() == "KeyWrap") {
158 TestKeyWrap(t);
159 } else if (t->GetParameter() == "KeyWrapWithPadding") {
160 TestKeyWrapWithPadding(t);
161 } else {
162 ADD_FAILURE() << "Unknown mode " << t->GetParameter();
163 }
164 });
165 }
166
TEST(AESTest,WycheproofKeyWrap)167 TEST(AESTest, WycheproofKeyWrap) {
168 FileTestGTest("third_party/wycheproof_testvectors/kw_test.txt",
169 [](FileTest *t) {
170 std::string key_size;
171 ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
172 std::vector<uint8_t> ct, key, msg;
173 ASSERT_TRUE(t->GetBytes(&ct, "ct"));
174 ASSERT_TRUE(t->GetBytes(&key, "key"));
175 ASSERT_TRUE(t->GetBytes(&msg, "msg"));
176 ASSERT_EQ(static_cast<unsigned>(atoi(key_size.c_str())), key.size() * 8);
177 WycheproofResult result;
178 ASSERT_TRUE(GetWycheproofResult(t, &result));
179
180 if (result.IsValid()) {
181 ASSERT_GE(ct.size(), 8u);
182
183 AES_KEY aes;
184 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes));
185 std::vector<uint8_t> out(ct.size() - 8);
186 int len = AES_unwrap_key(&aes, nullptr, out.data(), ct.data(), ct.size());
187 ASSERT_EQ(static_cast<int>(out.size()), len);
188 EXPECT_EQ(Bytes(msg), Bytes(out));
189
190 out.resize(msg.size() + 8);
191 ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes));
192 len = AES_wrap_key(&aes, nullptr, out.data(), msg.data(), msg.size());
193 ASSERT_EQ(static_cast<int>(out.size()), len);
194 EXPECT_EQ(Bytes(ct), Bytes(out));
195 } else {
196 AES_KEY aes;
197 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes));
198 std::vector<uint8_t> out(ct.size() < 8 ? 0 : ct.size() - 8);
199 int len = AES_unwrap_key(&aes, nullptr, out.data(), ct.data(), ct.size());
200 EXPECT_EQ(-1, len);
201 }
202 });
203 }
204
TEST(AESTest,WycheproofKeyWrapWithPadding)205 TEST(AESTest, WycheproofKeyWrapWithPadding) {
206 FileTestGTest("third_party/wycheproof_testvectors/kwp_test.txt",
207 [](FileTest *t) {
208 std::string key_size;
209 ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
210 std::vector<uint8_t> ct, key, msg;
211 ASSERT_TRUE(t->GetBytes(&ct, "ct"));
212 ASSERT_TRUE(t->GetBytes(&key, "key"));
213 ASSERT_TRUE(t->GetBytes(&msg, "msg"));
214 ASSERT_EQ(static_cast<unsigned>(atoi(key_size.c_str())), key.size() * 8);
215 WycheproofResult result;
216 ASSERT_TRUE(GetWycheproofResult(t, &result));
217
218 // Wycheproof contains test vectors with empty messages that it believes
219 // should pass. However, both RFC 5649 and SP 800-38F section 5.3.1 say that
220 // the minimum length is one. Therefore we consider test cases with an empty
221 // message to be invalid.
222 //
223 // Wycheproof marks various weak parameters as acceptable. We do not enforce
224 // policy in the library, so we map those flags to valid.
225 if (result.IsValid({"SmallKey", "WeakWrapping"}) && !msg.empty()) {
226 AES_KEY aes;
227 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes));
228 std::vector<uint8_t> out(ct.size() - 8);
229 size_t len;
230 ASSERT_TRUE(AES_unwrap_key_padded(&aes, out.data(), &len, ct.size() - 8,
231 ct.data(), ct.size()));
232 EXPECT_EQ(Bytes(msg), Bytes(out.data(), len));
233
234 out.resize(msg.size() + 15);
235 ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes));
236 ASSERT_TRUE(AES_wrap_key_padded(&aes, out.data(), &len, msg.size() + 15,
237 msg.data(), msg.size()));
238 EXPECT_EQ(Bytes(ct), Bytes(out.data(), len));
239 } else {
240 AES_KEY aes;
241 ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes));
242 std::vector<uint8_t> out(ct.size());
243 size_t len;
244 ASSERT_FALSE(AES_unwrap_key_padded(&aes, out.data(), &len, ct.size(),
245 ct.data(), ct.size()));
246 }
247 });
248 }
249
TEST(AESTest,WrapBadLengths)250 TEST(AESTest, WrapBadLengths) {
251 uint8_t key[128/8] = {0};
252 AES_KEY aes;
253 ASSERT_EQ(0, AES_set_encrypt_key(key, 128, &aes));
254
255 // Input lengths to |AES_wrap_key| must be a multiple of 8 and at least 16.
256 static const size_t kLengths[] = {0, 1, 2, 3, 4, 5, 6, 7, 8,
257 9, 10, 11, 12, 13, 14, 15, 20};
258 for (size_t len : kLengths) {
259 SCOPED_TRACE(len);
260 std::vector<uint8_t> in(len);
261 std::vector<uint8_t> out(len + 8);
262 EXPECT_EQ(-1,
263 AES_wrap_key(&aes, nullptr, out.data(), in.data(), in.size()));
264 }
265 }
266
TEST(AESTest,InvalidKeySize)267 TEST(AESTest, InvalidKeySize) {
268 static const uint8_t kZero[8] = {0};
269 AES_KEY key;
270 EXPECT_LT(AES_set_encrypt_key(kZero, 42, &key), 0);
271 EXPECT_LT(AES_set_decrypt_key(kZero, 42, &key), 0);
272 }
273
274 #if defined(SUPPORTS_ABI_TEST)
TEST(AESTest,ABI)275 TEST(AESTest, ABI) {
276 for (int bits : {128, 192, 256}) {
277 SCOPED_TRACE(bits);
278 const uint8_t kKey[256/8] = {0};
279 AES_KEY key;
280 uint8_t block[AES_BLOCK_SIZE];
281 uint8_t buf[AES_BLOCK_SIZE * 64] = {0};
282 std::vector<int> block_counts;
283 if (bits == 128) {
284 block_counts = {0, 1, 2, 3, 4, 8, 16, 31};
285 } else {
286 // Unwind tests are very slow. Assume that the various input sizes do not
287 // differ significantly by round count for ABI purposes.
288 block_counts = {0, 1, 8};
289 }
290
291 if (bsaes_capable()) {
292 vpaes_set_encrypt_key(kKey, bits, &key);
293 CHECK_ABI(vpaes_encrypt_key_to_bsaes, &key, &key);
294 for (size_t blocks : block_counts) {
295 SCOPED_TRACE(blocks);
296 if (blocks != 0) {
297 CHECK_ABI(bsaes_ctr32_encrypt_blocks, buf, buf, blocks, &key, block);
298 }
299 }
300
301 vpaes_set_decrypt_key(kKey, bits, &key);
302 CHECK_ABI(vpaes_decrypt_key_to_bsaes, &key, &key);
303 for (size_t blocks : block_counts) {
304 SCOPED_TRACE(blocks);
305 CHECK_ABI(bsaes_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
306 block, AES_DECRYPT);
307 }
308 }
309
310 if (vpaes_capable()) {
311 CHECK_ABI(vpaes_set_encrypt_key, kKey, bits, &key);
312 CHECK_ABI(vpaes_encrypt, block, block, &key);
313 for (size_t blocks : block_counts) {
314 SCOPED_TRACE(blocks);
315 #if defined(VPAES_CBC)
316 CHECK_ABI(vpaes_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
317 block, AES_ENCRYPT);
318 #endif
319 #if defined(VPAES_CTR32)
320 CHECK_ABI(vpaes_ctr32_encrypt_blocks, buf, buf, blocks, &key, block);
321 #endif
322 }
323
324 CHECK_ABI(vpaes_set_decrypt_key, kKey, bits, &key);
325 CHECK_ABI(vpaes_decrypt, block, block, &key);
326 #if defined(VPAES_CBC)
327 for (size_t blocks : block_counts) {
328 SCOPED_TRACE(blocks);
329 CHECK_ABI(vpaes_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
330 block, AES_DECRYPT);
331 }
332 #endif // VPAES_CBC
333 }
334
335 if (hwaes_capable()) {
336 CHECK_ABI(aes_hw_set_encrypt_key, kKey, bits, &key);
337 CHECK_ABI(aes_hw_encrypt, block, block, &key);
338 for (size_t blocks : block_counts) {
339 SCOPED_TRACE(blocks);
340 CHECK_ABI(aes_hw_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
341 block, AES_ENCRYPT);
342 CHECK_ABI(aes_hw_ctr32_encrypt_blocks, buf, buf, blocks, &key, block);
343 #if defined(HWAES_ECB)
344 CHECK_ABI(aes_hw_ecb_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
345 AES_ENCRYPT);
346 #endif
347 }
348
349 CHECK_ABI(aes_hw_set_decrypt_key, kKey, bits, &key);
350 CHECK_ABI(aes_hw_decrypt, block, block, &key);
351 for (size_t blocks : block_counts) {
352 SCOPED_TRACE(blocks);
353 CHECK_ABI(aes_hw_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
354 block, AES_DECRYPT);
355 #if defined(HWAES_ECB)
356 CHECK_ABI(aes_hw_ecb_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
357 AES_DECRYPT);
358 #endif
359 }
360 }
361 }
362 }
363 #endif // SUPPORTS_ABI_TEST
364
365 #if defined(BSAES) && !defined(BORINGSSL_SHARED_LIBRARY)
AESKeyToBytes(const AES_KEY * key)366 static Bytes AESKeyToBytes(const AES_KEY *key) {
367 return Bytes(reinterpret_cast<const uint8_t *>(key), sizeof(*key));
368 }
369
aes_ref_sub_byte(uint8_t b)370 static uint8_t aes_ref_sub_byte(uint8_t b) {
371 static const uint8_t kSBox[256] = {
372 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
373 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
374 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
375 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
376 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
377 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
378 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
379 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
380 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
381 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
382 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
383 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
384 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
385 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
386 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
387 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
388 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
389 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
390 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
391 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
392 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
393 0xb0, 0x54, 0xbb, 0x16,
394 };
395 return kSBox[b];
396 }
397
aes_ref_sub_word(uint32_t in)398 static uint32_t aes_ref_sub_word(uint32_t in) {
399 uint32_t a0 = aes_ref_sub_byte(in);
400 uint32_t a1 = aes_ref_sub_byte(in >> 8);
401 uint32_t a2 = aes_ref_sub_byte(in >> 16);
402 uint32_t a3 = aes_ref_sub_byte(in >> 24);
403 return a0 | (a1 << 8) | (a2 << 16) | (a3 << 24);
404 }
405
aes_ref_rot_word(uint32_t in,uint32_t n)406 static uint32_t aes_ref_rot_word(uint32_t in, uint32_t n) {
407 return (in >> n) | (in << (32 - n));
408 }
409
aes_ref_set_encrypt_key(const uint8_t * key,int key_bits,AES_KEY * out)410 static int aes_ref_set_encrypt_key(const uint8_t *key, int key_bits,
411 AES_KEY *out) {
412 static const uint32_t kRCon[10] = {0x01, 0x02, 0x04, 0x08, 0x10,
413 0x20, 0x40, 0x80, 0x1b, 0x36};
414 switch (key_bits) {
415 case 128:
416 out->rounds = 10;
417 break;
418 case 192:
419 out->rounds = 12;
420 break;
421 case 256:
422 out->rounds = 14;
423 break;
424 default:
425 return 1;
426 }
427
428 size_t words = key_bits / 32;
429 size_t num_subkey_words = (out->rounds + 1) * 4;
430 OPENSSL_memcpy(out->rd_key, key, words * sizeof(uint32_t));
431 for (size_t i = words; i < num_subkey_words; i++) {
432 uint32_t tmp = out->rd_key[i - 1];
433 if (i % words == 0) {
434 tmp = aes_ref_sub_word(aes_ref_rot_word(tmp, 8)) ^ kRCon[(i / words) - 1];
435 } else if (key_bits == 256 && i % 4 == 0) {
436 tmp = aes_ref_sub_word(tmp);
437 }
438 out->rd_key[i] = tmp ^ out->rd_key[i - words];
439 }
440
441 // The ARM bsaes implementation expects all the keys to be byteswapped.
442 for (size_t i = 0; i < num_subkey_words; i++) {
443 out->rd_key[i] = CRYPTO_bswap4(out->rd_key[i]);
444 }
445
446 return 0;
447 }
448
aes_ref_inv_mix_columns(uint32_t block[4])449 static void aes_ref_inv_mix_columns(uint32_t block[4]) {
450 // This tables was generated with the following Python script:
451 // clang-format off
452 /*
453 def mul_unreduced(a, b):
454 c = 0
455 for i in range(8):
456 if b & (1 << i):
457 c ^= a << i
458 return c
459
460 def mul(a, b):
461 c = mul_unreduced(a, b)
462 # c's highest term is at most x^14.
463 c = (c & 0xff) ^ mul_unreduced(c >> 8, 0b00011011)
464 # c's highest term is at most x^10.
465 c = (c & 0xff) ^ mul_unreduced(c >> 8, 0b00011011)
466 # c's highest term is at most x^7.
467 assert (c >> 8) == 0
468 return c
469
470 def inv_mix_column(a):
471 ret = 0
472 for b in [0x0e, 0x09, 0x0d, 0x0b]:
473 ret <<= 8
474 ret |= mul(a, b)
475 return ret
476
477 body = ", ".join("0x%08x" % inv_mix_column(a) for a in range(256))
478 print("static const uint32_t kTable[256] = {%s};\n" % body)
479 */
480 // clang-format on
481
482 // kInvMixColumn[i] is the result of InvMixColumns applied to a column
483 // containing [i, 0, 0, 0]. (The contributions of the other positions are
484 // computed by rotating bytes.)
485 static const uint32_t kInvMixColumn[256] = {
486 0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927,
487 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45,
488 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb,
489 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381,
490 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf,
491 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66,
492 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28,
493 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012,
494 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec,
495 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e,
496 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd,
497 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7,
498 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89,
499 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b,
500 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815,
501 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f,
502 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa,
503 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8,
504 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36,
505 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c,
506 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742,
507 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea,
508 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4,
509 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e,
510 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360,
511 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502,
512 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87,
513 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd,
514 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3,
515 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621,
516 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f,
517 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55,
518 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26,
519 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844,
520 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba,
521 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480,
522 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce,
523 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67,
524 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929,
525 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713,
526 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed,
527 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f,
528 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3};
529
530 // Note |block| is byte-swapped so block[i] >> 24 is the first element of
531 // block[i]. (See |aes_ref_set_encrypt_key|).
532 for (size_t i = 0; i < 4; i++) {
533 uint32_t in = block[i];
534 block[i] = kInvMixColumn[in >> 24];
535 block[i] ^= aes_ref_rot_word(kInvMixColumn[(in >> 16) & 0xff], 8);
536 block[i] ^= aes_ref_rot_word(kInvMixColumn[(in >> 8) & 0xff], 16);
537 block[i] ^= aes_ref_rot_word(kInvMixColumn[in & 0xff], 24);
538 }
539 }
540
aes_ref_set_decrypt_key(const uint8_t * key,int bits,AES_KEY * out)541 static int aes_ref_set_decrypt_key(const uint8_t *key, int bits, AES_KEY *out) {
542 if (aes_ref_set_encrypt_key(key, bits, out) != 0) {
543 return 1;
544 }
545
546 // bsaes expects the decryption round keys in reverse order. Note there are
547 // |out->rounds + 1| round keys.
548 for (size_t i = 0; i < out->rounds / 2; i++) {
549 std::swap(out->rd_key[4 * i], out->rd_key[4 * (out->rounds - i)]);
550 std::swap(out->rd_key[4 * i + 1], out->rd_key[4 * (out->rounds - i) + 1]);
551 std::swap(out->rd_key[4 * i + 2], out->rd_key[4 * (out->rounds - i) + 2]);
552 std::swap(out->rd_key[4 * i + 3], out->rd_key[4 * (out->rounds - i) + 3]);
553 }
554
555 // bsaes expects round keys other than the first and last to have
556 // InvMixColumns applied.
557 for (size_t i = 1; i < out->rounds; i++) {
558 aes_ref_inv_mix_columns(out->rd_key + 4 * i);
559 }
560
561 return 0;
562 }
563
564
TEST(AESTest,VPAESToBSAESConvert)565 TEST(AESTest, VPAESToBSAESConvert) {
566 const int kNumIterations = 1000;
567 for (int i = 0; i < kNumIterations; i++) {
568 uint8_t key[256 / 8];
569 RAND_bytes(key, sizeof(key));
570 SCOPED_TRACE(Bytes(key));
571 for (unsigned bits : {128u, 192u, 256u}) {
572 SCOPED_TRACE(bits);
573 for (bool enc : {false, true}) {
574 SCOPED_TRACE(enc);
575 AES_KEY ref, vpaes, bsaes;
576 OPENSSL_memset(&ref, 0xaa, sizeof(ref));
577 OPENSSL_memset(&vpaes, 0xaa, sizeof(vpaes));
578 OPENSSL_memset(&bsaes, 0xaa, sizeof(bsaes));
579
580 if (enc) {
581 ASSERT_EQ(0, aes_ref_set_encrypt_key(key, bits, &ref));
582 ASSERT_EQ(0, vpaes_set_encrypt_key(key, bits, &vpaes));
583 vpaes_encrypt_key_to_bsaes(&bsaes, &vpaes);
584 } else {
585 ASSERT_EQ(0, aes_ref_set_decrypt_key(key, bits, &ref));
586 ASSERT_EQ(0, vpaes_set_decrypt_key(key, bits, &vpaes));
587 vpaes_decrypt_key_to_bsaes(&bsaes, &vpaes);
588 }
589
590 // Although not fatal, stop running if this fails, otherwise we'll spam
591 // the user's console.
592 ASSERT_EQ(AESKeyToBytes(&ref), AESKeyToBytes(&bsaes));
593
594 // Repeat the test in-place.
595 OPENSSL_memcpy(&bsaes, &vpaes, sizeof(AES_KEY));
596 if (enc) {
597 vpaes_encrypt_key_to_bsaes(&bsaes, &bsaes);
598 } else {
599 vpaes_decrypt_key_to_bsaes(&bsaes, &bsaes);
600 }
601
602 ASSERT_EQ(AESKeyToBytes(&ref), AESKeyToBytes(&bsaes));
603 }
604 }
605 }
606 }
607 #endif // BSAES && !SHARED_LIBRARY
608