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(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 ASSERT_EQ(CHECK_ABI(aes_hw_set_decrypt_key, kKey, bits, &key), 0);
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_set_encrypt_key(const uint8_t * key,int key_bits,AES_KEY * out)406 static int aes_ref_set_encrypt_key(const uint8_t *key, int key_bits,
407 AES_KEY *out) {
408 static const uint32_t kRCon[10] = {0x01, 0x02, 0x04, 0x08, 0x10,
409 0x20, 0x40, 0x80, 0x1b, 0x36};
410 switch (key_bits) {
411 case 128:
412 out->rounds = 10;
413 break;
414 case 192:
415 out->rounds = 12;
416 break;
417 case 256:
418 out->rounds = 14;
419 break;
420 default:
421 return 1;
422 }
423
424 size_t words = key_bits / 32;
425 size_t num_subkey_words = (out->rounds + 1) * 4;
426 OPENSSL_memcpy(out->rd_key, key, words * sizeof(uint32_t));
427 for (size_t i = words; i < num_subkey_words; i++) {
428 uint32_t tmp = out->rd_key[i - 1];
429 if (i % words == 0) {
430 tmp = aes_ref_sub_word(CRYPTO_rotr_u32(tmp, 8)) ^ kRCon[(i / words) - 1];
431 } else if (key_bits == 256 && i % 4 == 0) {
432 tmp = aes_ref_sub_word(tmp);
433 }
434 out->rd_key[i] = tmp ^ out->rd_key[i - words];
435 }
436
437 // The ARM bsaes implementation expects all the keys to be byteswapped.
438 for (size_t i = 0; i < num_subkey_words; i++) {
439 out->rd_key[i] = CRYPTO_bswap4(out->rd_key[i]);
440 }
441
442 return 0;
443 }
444
aes_ref_inv_mix_columns(uint32_t block[4])445 static void aes_ref_inv_mix_columns(uint32_t block[4]) {
446 // This tables was generated with the following Python script:
447 // clang-format off
448 /*
449 def mul_unreduced(a, b):
450 c = 0
451 for i in range(8):
452 if b & (1 << i):
453 c ^= a << i
454 return c
455
456 def mul(a, b):
457 c = mul_unreduced(a, b)
458 # c's highest term is at most x^14.
459 c = (c & 0xff) ^ mul_unreduced(c >> 8, 0b00011011)
460 # c's highest term is at most x^10.
461 c = (c & 0xff) ^ mul_unreduced(c >> 8, 0b00011011)
462 # c's highest term is at most x^7.
463 assert (c >> 8) == 0
464 return c
465
466 def inv_mix_column(a):
467 ret = 0
468 for b in [0x0e, 0x09, 0x0d, 0x0b]:
469 ret <<= 8
470 ret |= mul(a, b)
471 return ret
472
473 body = ", ".join("0x%08x" % inv_mix_column(a) for a in range(256))
474 print("static const uint32_t kTable[256] = {%s};\n" % body)
475 */
476 // clang-format on
477
478 // kInvMixColumn[i] is the result of InvMixColumns applied to a column
479 // containing [i, 0, 0, 0]. (The contributions of the other positions are
480 // computed by rotating bytes.)
481 static const uint32_t kInvMixColumn[256] = {
482 0x00000000, 0x0e090d0b, 0x1c121a16, 0x121b171d, 0x3824342c, 0x362d3927,
483 0x24362e3a, 0x2a3f2331, 0x70486858, 0x7e416553, 0x6c5a724e, 0x62537f45,
484 0x486c5c74, 0x4665517f, 0x547e4662, 0x5a774b69, 0xe090d0b0, 0xee99ddbb,
485 0xfc82caa6, 0xf28bc7ad, 0xd8b4e49c, 0xd6bde997, 0xc4a6fe8a, 0xcaaff381,
486 0x90d8b8e8, 0x9ed1b5e3, 0x8ccaa2fe, 0x82c3aff5, 0xa8fc8cc4, 0xa6f581cf,
487 0xb4ee96d2, 0xbae79bd9, 0xdb3bbb7b, 0xd532b670, 0xc729a16d, 0xc920ac66,
488 0xe31f8f57, 0xed16825c, 0xff0d9541, 0xf104984a, 0xab73d323, 0xa57ade28,
489 0xb761c935, 0xb968c43e, 0x9357e70f, 0x9d5eea04, 0x8f45fd19, 0x814cf012,
490 0x3bab6bcb, 0x35a266c0, 0x27b971dd, 0x29b07cd6, 0x038f5fe7, 0x0d8652ec,
491 0x1f9d45f1, 0x119448fa, 0x4be30393, 0x45ea0e98, 0x57f11985, 0x59f8148e,
492 0x73c737bf, 0x7dce3ab4, 0x6fd52da9, 0x61dc20a2, 0xad766df6, 0xa37f60fd,
493 0xb16477e0, 0xbf6d7aeb, 0x955259da, 0x9b5b54d1, 0x894043cc, 0x87494ec7,
494 0xdd3e05ae, 0xd33708a5, 0xc12c1fb8, 0xcf2512b3, 0xe51a3182, 0xeb133c89,
495 0xf9082b94, 0xf701269f, 0x4de6bd46, 0x43efb04d, 0x51f4a750, 0x5ffdaa5b,
496 0x75c2896a, 0x7bcb8461, 0x69d0937c, 0x67d99e77, 0x3daed51e, 0x33a7d815,
497 0x21bccf08, 0x2fb5c203, 0x058ae132, 0x0b83ec39, 0x1998fb24, 0x1791f62f,
498 0x764dd68d, 0x7844db86, 0x6a5fcc9b, 0x6456c190, 0x4e69e2a1, 0x4060efaa,
499 0x527bf8b7, 0x5c72f5bc, 0x0605bed5, 0x080cb3de, 0x1a17a4c3, 0x141ea9c8,
500 0x3e218af9, 0x302887f2, 0x223390ef, 0x2c3a9de4, 0x96dd063d, 0x98d40b36,
501 0x8acf1c2b, 0x84c61120, 0xaef93211, 0xa0f03f1a, 0xb2eb2807, 0xbce2250c,
502 0xe6956e65, 0xe89c636e, 0xfa877473, 0xf48e7978, 0xdeb15a49, 0xd0b85742,
503 0xc2a3405f, 0xccaa4d54, 0x41ecdaf7, 0x4fe5d7fc, 0x5dfec0e1, 0x53f7cdea,
504 0x79c8eedb, 0x77c1e3d0, 0x65daf4cd, 0x6bd3f9c6, 0x31a4b2af, 0x3fadbfa4,
505 0x2db6a8b9, 0x23bfa5b2, 0x09808683, 0x07898b88, 0x15929c95, 0x1b9b919e,
506 0xa17c0a47, 0xaf75074c, 0xbd6e1051, 0xb3671d5a, 0x99583e6b, 0x97513360,
507 0x854a247d, 0x8b432976, 0xd134621f, 0xdf3d6f14, 0xcd267809, 0xc32f7502,
508 0xe9105633, 0xe7195b38, 0xf5024c25, 0xfb0b412e, 0x9ad7618c, 0x94de6c87,
509 0x86c57b9a, 0x88cc7691, 0xa2f355a0, 0xacfa58ab, 0xbee14fb6, 0xb0e842bd,
510 0xea9f09d4, 0xe49604df, 0xf68d13c2, 0xf8841ec9, 0xd2bb3df8, 0xdcb230f3,
511 0xcea927ee, 0xc0a02ae5, 0x7a47b13c, 0x744ebc37, 0x6655ab2a, 0x685ca621,
512 0x42638510, 0x4c6a881b, 0x5e719f06, 0x5078920d, 0x0a0fd964, 0x0406d46f,
513 0x161dc372, 0x1814ce79, 0x322bed48, 0x3c22e043, 0x2e39f75e, 0x2030fa55,
514 0xec9ab701, 0xe293ba0a, 0xf088ad17, 0xfe81a01c, 0xd4be832d, 0xdab78e26,
515 0xc8ac993b, 0xc6a59430, 0x9cd2df59, 0x92dbd252, 0x80c0c54f, 0x8ec9c844,
516 0xa4f6eb75, 0xaaffe67e, 0xb8e4f163, 0xb6edfc68, 0x0c0a67b1, 0x02036aba,
517 0x10187da7, 0x1e1170ac, 0x342e539d, 0x3a275e96, 0x283c498b, 0x26354480,
518 0x7c420fe9, 0x724b02e2, 0x605015ff, 0x6e5918f4, 0x44663bc5, 0x4a6f36ce,
519 0x587421d3, 0x567d2cd8, 0x37a10c7a, 0x39a80171, 0x2bb3166c, 0x25ba1b67,
520 0x0f853856, 0x018c355d, 0x13972240, 0x1d9e2f4b, 0x47e96422, 0x49e06929,
521 0x5bfb7e34, 0x55f2733f, 0x7fcd500e, 0x71c45d05, 0x63df4a18, 0x6dd64713,
522 0xd731dcca, 0xd938d1c1, 0xcb23c6dc, 0xc52acbd7, 0xef15e8e6, 0xe11ce5ed,
523 0xf307f2f0, 0xfd0efffb, 0xa779b492, 0xa970b999, 0xbb6bae84, 0xb562a38f,
524 0x9f5d80be, 0x91548db5, 0x834f9aa8, 0x8d4697a3};
525
526 // Note |block| is byte-swapped so block[i] >> 24 is the first element of
527 // block[i]. (See |aes_ref_set_encrypt_key|).
528 for (size_t i = 0; i < 4; i++) {
529 uint32_t in = block[i];
530 block[i] = kInvMixColumn[in >> 24];
531 block[i] ^= CRYPTO_rotr_u32(kInvMixColumn[(in >> 16) & 0xff], 8);
532 block[i] ^= CRYPTO_rotr_u32(kInvMixColumn[(in >> 8) & 0xff], 16);
533 block[i] ^= CRYPTO_rotr_u32(kInvMixColumn[in & 0xff], 24);
534 }
535 }
536
aes_ref_set_decrypt_key(const uint8_t * key,int bits,AES_KEY * out)537 static int aes_ref_set_decrypt_key(const uint8_t *key, int bits, AES_KEY *out) {
538 if (aes_ref_set_encrypt_key(key, bits, out) != 0) {
539 return 1;
540 }
541
542 // bsaes expects the decryption round keys in reverse order. Note there are
543 // |out->rounds + 1| round keys.
544 for (size_t i = 0; i < out->rounds / 2; i++) {
545 std::swap(out->rd_key[4 * i], out->rd_key[4 * (out->rounds - i)]);
546 std::swap(out->rd_key[4 * i + 1], out->rd_key[4 * (out->rounds - i) + 1]);
547 std::swap(out->rd_key[4 * i + 2], out->rd_key[4 * (out->rounds - i) + 2]);
548 std::swap(out->rd_key[4 * i + 3], out->rd_key[4 * (out->rounds - i) + 3]);
549 }
550
551 // bsaes expects round keys other than the first and last to have
552 // InvMixColumns applied.
553 for (size_t i = 1; i < out->rounds; i++) {
554 aes_ref_inv_mix_columns(out->rd_key + 4 * i);
555 }
556
557 return 0;
558 }
559
560
TEST(AESTest,VPAESToBSAESConvert)561 TEST(AESTest, VPAESToBSAESConvert) {
562 if (!vpaes_capable()) {
563 GTEST_SKIP();
564 }
565
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