• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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