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 auto buf = std::make_unique<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 = std::make_unique<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 auto buf = std::make_unique<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 = std::make_unique<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 ASSERT_EQ(vpaes_set_encrypt_key(kKey, bits, &key), 0);
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 ASSERT_EQ(vpaes_set_decrypt_key(kKey, bits, &key), 0);
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 ASSERT_EQ(CHECK_ABI(vpaes_set_encrypt_key, kKey, bits, &key), 0);
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 ASSERT_EQ(CHECK_ABI(vpaes_set_decrypt_key, kKey, bits, &key), 0);
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 ASSERT_EQ(CHECK_ABI_SEH(aes_hw_set_encrypt_key, kKey, bits, &key), 0);
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 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
350 ASSERT_EQ(CHECK_ABI_SEH(aes_hw_set_encrypt_key_base, kKey, bits, &key), 0);
351 if (aes_hw_set_encrypt_key_alt_capable()) {
352 AES_KEY alt;
353 ASSERT_EQ(CHECK_ABI_SEH(aes_hw_set_encrypt_key_alt, kKey, bits, &alt),
354 0);
355 EXPECT_EQ(alt.rounds, key.rounds);
356 for (unsigned i = 0; i <= alt.rounds; i++) {
357 EXPECT_EQ(alt.rd_key[i], key.rd_key[i]);
358 }
359 }
360 CHECK_ABI_SEH(aes_hw_encrypt_key_to_decrypt_key, &key);
361 #else
362 ASSERT_EQ(CHECK_ABI_SEH(aes_hw_set_decrypt_key, kKey, bits, &key), 0);
363 #endif
364 CHECK_ABI(aes_hw_decrypt, block, block, &key);
365 for (size_t blocks : block_counts) {
366 SCOPED_TRACE(blocks);
367 CHECK_ABI(aes_hw_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
368 block, AES_DECRYPT);
369 #if defined(HWAES_ECB)
370 CHECK_ABI(aes_hw_ecb_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
371 AES_DECRYPT);
372 #endif
373 }
374 }
375 }
376 }
377 #endif // SUPPORTS_ABI_TEST
378
379 #if defined(BSAES) && !defined(BORINGSSL_SHARED_LIBRARY)
AESKeyToBytes(const AES_KEY * key)380 static Bytes AESKeyToBytes(const AES_KEY *key) {
381 return Bytes(reinterpret_cast<const uint8_t *>(key), sizeof(*key));
382 }
383
aes_ref_sub_byte(uint8_t b)384 static uint8_t aes_ref_sub_byte(uint8_t b) {
385 static const uint8_t kSBox[256] = {
386 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b,
387 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
388 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26,
389 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
390 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
391 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
392 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed,
393 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
394 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f,
395 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
396 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec,
397 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
398 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14,
399 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
400 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
401 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
402 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f,
403 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
404 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11,
405 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
406 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f,
407 0xb0, 0x54, 0xbb, 0x16,
408 };
409 return kSBox[b];
410 }
411
aes_ref_sub_word(uint32_t in)412 static uint32_t aes_ref_sub_word(uint32_t in) {
413 uint32_t a0 = aes_ref_sub_byte(in);
414 uint32_t a1 = aes_ref_sub_byte(in >> 8);
415 uint32_t a2 = aes_ref_sub_byte(in >> 16);
416 uint32_t a3 = aes_ref_sub_byte(in >> 24);
417 return a0 | (a1 << 8) | (a2 << 16) | (a3 << 24);
418 }
419
aes_ref_set_encrypt_key(const uint8_t * key,int key_bits,AES_KEY * out)420 static int aes_ref_set_encrypt_key(const uint8_t *key, int key_bits,
421 AES_KEY *out) {
422 static const uint32_t kRCon[10] = {0x01, 0x02, 0x04, 0x08, 0x10,
423 0x20, 0x40, 0x80, 0x1b, 0x36};
424 switch (key_bits) {
425 case 128:
426 out->rounds = 10;
427 break;
428 case 192:
429 out->rounds = 12;
430 break;
431 case 256:
432 out->rounds = 14;
433 break;
434 default:
435 return 1;
436 }
437
438 size_t words = key_bits / 32;
439 size_t num_subkey_words = (out->rounds + 1) * 4;
440 OPENSSL_memcpy(out->rd_key, key, words * sizeof(uint32_t));
441 for (size_t i = words; i < num_subkey_words; i++) {
442 uint32_t tmp = out->rd_key[i - 1];
443 if (i % words == 0) {
444 tmp = aes_ref_sub_word(CRYPTO_rotr_u32(tmp, 8)) ^ kRCon[(i / words) - 1];
445 } else if (key_bits == 256 && i % 4 == 0) {
446 tmp = aes_ref_sub_word(tmp);
447 }
448 out->rd_key[i] = tmp ^ out->rd_key[i - words];
449 }
450
451 // The ARM bsaes implementation expects all the keys to be byteswapped.
452 for (size_t i = 0; i < num_subkey_words; i++) {
453 out->rd_key[i] = CRYPTO_bswap4(out->rd_key[i]);
454 }
455
456 return 0;
457 }
458
aes_ref_inv_mix_columns(uint32_t block[4])459 static void aes_ref_inv_mix_columns(uint32_t block[4]) {
460 // This tables was generated with the following Python script:
461 // clang-format off
462 /*
463 def mul_unreduced(a, b):
464 c = 0
465 for i in range(8):
466 if b & (1 << i):
467 c ^= a << i
468 return c
469
470 def mul(a, b):
471 c = mul_unreduced(a, b)
472 # c's highest term is at most x^14.
473 c = (c & 0xff) ^ mul_unreduced(c >> 8, 0b00011011)
474 # c's highest term is at most x^10.
475 c = (c & 0xff) ^ mul_unreduced(c >> 8, 0b00011011)
476 # c's highest term is at most x^7.
477 assert (c >> 8) == 0
478 return c
479
480 def inv_mix_column(a):
481 ret = 0
482 for b in [0x0e, 0x09, 0x0d, 0x0b]:
483 ret <<= 8
484 ret |= mul(a, b)
485 return ret
486
487 body = ", ".join("0x%08x" % inv_mix_column(a) for a in range(256))
488 print("static const uint32_t kTable[256] = {%s};\n" % body)
489 */
490 // clang-format on
491
492 // kInvMixColumn[i] is the result of InvMixColumns applied to a column
493 // containing [i, 0, 0, 0]. (The contributions of the other positions are
494 // computed by rotating bytes.)
495 static const uint32_t kInvMixColumn[256] = {
496 0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927,
497 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45,
498 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb,
499 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381,
500 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf,
501 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66,
502 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28,
503 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012,
504 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec,
505 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e,
506 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd,
507 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7,
508 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89,
509 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b,
510 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815,
511 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f,
512 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa,
513 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8,
514 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36,
515 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c,
516 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742,
517 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea,
518 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4,
519 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e,
520 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360,
521 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502,
522 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87,
523 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd,
524 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3,
525 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621,
526 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f,
527 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55,
528 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26,
529 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844,
530 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba,
531 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480,
532 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce,
533 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67,
534 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929,
535 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713,
536 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed,
537 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f,
538 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3};
539
540 // Note |block| is byte-swapped so block[i] >> 24 is the first element of
541 // block[i]. (See |aes_ref_set_encrypt_key|).
542 for (size_t i = 0; i < 4; i++) {
543 uint32_t in = block[i];
544 block[i] = kInvMixColumn[in >> 24];
545 block[i] ^= CRYPTO_rotr_u32(kInvMixColumn[(in >> 16) & 0xff], 8);
546 block[i] ^= CRYPTO_rotr_u32(kInvMixColumn[(in >> 8) & 0xff], 16);
547 block[i] ^= CRYPTO_rotr_u32(kInvMixColumn[in & 0xff], 24);
548 }
549 }
550
aes_ref_set_decrypt_key(const uint8_t * key,int bits,AES_KEY * out)551 static int aes_ref_set_decrypt_key(const uint8_t *key, int bits, AES_KEY *out) {
552 if (aes_ref_set_encrypt_key(key, bits, out) != 0) {
553 return 1;
554 }
555
556 // bsaes expects the decryption round keys in reverse order. Note there are
557 // |out->rounds + 1| round keys.
558 for (size_t i = 0; i < out->rounds / 2; i++) {
559 std::swap(out->rd_key[4 * i], out->rd_key[4 * (out->rounds - i)]);
560 std::swap(out->rd_key[4 * i + 1], out->rd_key[4 * (out->rounds - i) + 1]);
561 std::swap(out->rd_key[4 * i + 2], out->rd_key[4 * (out->rounds - i) + 2]);
562 std::swap(out->rd_key[4 * i + 3], out->rd_key[4 * (out->rounds - i) + 3]);
563 }
564
565 // bsaes expects round keys other than the first and last to have
566 // InvMixColumns applied.
567 for (size_t i = 1; i < out->rounds; i++) {
568 aes_ref_inv_mix_columns(out->rd_key + 4 * i);
569 }
570
571 return 0;
572 }
573
574
TEST(AESTest,VPAESToBSAESConvert)575 TEST(AESTest, VPAESToBSAESConvert) {
576 if (!vpaes_capable()) {
577 GTEST_SKIP();
578 }
579
580 const int kNumIterations = 1000;
581 for (int i = 0; i < kNumIterations; i++) {
582 uint8_t key[256 / 8];
583 RAND_bytes(key, sizeof(key));
584 SCOPED_TRACE(Bytes(key));
585 for (unsigned bits : {128u, 192u, 256u}) {
586 SCOPED_TRACE(bits);
587 for (bool enc : {false, true}) {
588 SCOPED_TRACE(enc);
589 AES_KEY ref, vpaes, bsaes;
590 OPENSSL_memset(&ref, 0xaa, sizeof(ref));
591 OPENSSL_memset(&vpaes, 0xaa, sizeof(vpaes));
592 OPENSSL_memset(&bsaes, 0xaa, sizeof(bsaes));
593
594 if (enc) {
595 ASSERT_EQ(0, aes_ref_set_encrypt_key(key, bits, &ref));
596 ASSERT_EQ(0, vpaes_set_encrypt_key(key, bits, &vpaes));
597 vpaes_encrypt_key_to_bsaes(&bsaes, &vpaes);
598 } else {
599 ASSERT_EQ(0, aes_ref_set_decrypt_key(key, bits, &ref));
600 ASSERT_EQ(0, vpaes_set_decrypt_key(key, bits, &vpaes));
601 vpaes_decrypt_key_to_bsaes(&bsaes, &vpaes);
602 }
603
604 // Although not fatal, stop running if this fails, otherwise we'll spam
605 // the user's console.
606 ASSERT_EQ(AESKeyToBytes(&ref), AESKeyToBytes(&bsaes));
607
608 // Repeat the test in-place.
609 OPENSSL_memcpy(&bsaes, &vpaes, sizeof(AES_KEY));
610 if (enc) {
611 vpaes_encrypt_key_to_bsaes(&bsaes, &bsaes);
612 } else {
613 vpaes_decrypt_key_to_bsaes(&bsaes, &bsaes);
614 }
615
616 ASSERT_EQ(AESKeyToBytes(&ref), AESKeyToBytes(&bsaes));
617 }
618 }
619 }
620 }
621 #endif // BSAES && !SHARED_LIBRARY
622