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