aes_test.cc
Go to the documentation of this file.
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 
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.
50  AES_encrypt(plaintext.data(), block, &aes_key);
52 
53  // Test in-place encryption.
55  AES_encrypt(block, block, &aes_key);
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);
63 
64  // Test in-place decryption.
66  AES_decrypt(block, block, &aes_key);
68 }
69 
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 
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 
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 
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);
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);
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 
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);
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 
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 
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)
275 TEST(AESTest, ABI) {
276  for (int bits : {128, 192, 256}) {
278  const uint8_t kKey[256/8] = {0};
279  AES_KEY key;
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()) {
294  for (size_t blocks : block_counts) {
295  SCOPED_TRACE(blocks);
296  if (blocks != 0) {
298  }
299  }
300 
303  for (size_t blocks : block_counts) {
304  SCOPED_TRACE(blocks);
306  block, AES_DECRYPT);
307  }
308  }
309 
310  if (vpaes_capable()) {
313  for (size_t blocks : block_counts) {
314  SCOPED_TRACE(blocks);
315 #if defined(VPAES_CBC)
317  block, AES_ENCRYPT);
318 #endif
319 #if defined(VPAES_CTR32)
321 #endif
322  }
323 
326 #if defined(VPAES_CBC)
327  for (size_t blocks : block_counts) {
328  SCOPED_TRACE(blocks);
330  block, AES_DECRYPT);
331  }
332 #endif // VPAES_CBC
333  }
334 
335  if (hwaes_capable()) {
338  for (size_t blocks : block_counts) {
339  SCOPED_TRACE(blocks);
341  block, AES_ENCRYPT);
343 #if defined(HWAES_ECB)
345  AES_ENCRYPT);
346 #endif
347  }
348 
351  for (size_t blocks : block_counts) {
352  SCOPED_TRACE(blocks);
354  block, AES_DECRYPT);
355 #if defined(HWAES_ECB)
357  AES_DECRYPT);
358 #endif
359  }
360  }
361  }
362 }
363 #endif // SUPPORTS_ABI_TEST
364 
365 #if defined(BSAES) && !defined(BORINGSSL_SHARED_LIBRARY)
366 static Bytes AESKeyToBytes(const AES_KEY *key) {
367  return Bytes(reinterpret_cast<const uint8_t *>(key), sizeof(*key));
368 }
369 
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 
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 
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 
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 
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 
561 TEST(AESTest, VPAESToBSAESConvert) {
562  const int kNumIterations = 1000;
563  for (int i = 0; i < kNumIterations; i++) {
564  uint8_t key[256 / 8];
565  RAND_bytes(key, sizeof(key));
567  for (unsigned bits : {128u, 192u, 256u}) {
569  for (bool enc : {false, true}) {
570  SCOPED_TRACE(enc);
571  AES_KEY ref, vpaes, bsaes;
572  OPENSSL_memset(&ref, 0xaa, sizeof(ref));
573  OPENSSL_memset(&vpaes, 0xaa, sizeof(vpaes));
574  OPENSSL_memset(&bsaes, 0xaa, sizeof(bsaes));
575 
576  if (enc) {
577  ASSERT_EQ(0, aes_ref_set_encrypt_key(key, bits, &ref));
578  ASSERT_EQ(0, vpaes_set_encrypt_key(key, bits, &vpaes));
579  vpaes_encrypt_key_to_bsaes(&bsaes, &vpaes);
580  } else {
581  ASSERT_EQ(0, aes_ref_set_decrypt_key(key, bits, &ref));
582  ASSERT_EQ(0, vpaes_set_decrypt_key(key, bits, &vpaes));
583  vpaes_decrypt_key_to_bsaes(&bsaes, &vpaes);
584  }
585 
586  // Although not fatal, stop running if this fails, otherwise we'll spam
587  // the user's console.
588  ASSERT_EQ(AESKeyToBytes(&ref), AESKeyToBytes(&bsaes));
589 
590  // Repeat the test in-place.
591  OPENSSL_memcpy(&bsaes, &vpaes, sizeof(AES_KEY));
592  if (enc) {
593  vpaes_encrypt_key_to_bsaes(&bsaes, &bsaes);
594  } else {
595  vpaes_decrypt_key_to_bsaes(&bsaes, &bsaes);
596  }
597 
598  ASSERT_EQ(AESKeyToBytes(&ref), AESKeyToBytes(&bsaes));
599  }
600  }
601  }
602 }
603 #endif // BSAES && !SHARED_LIBRARY
AES_ENCRYPT
#define AES_ENCRYPT
Definition: aes.h:62
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
CRYPTO_rotr_u32
static uint32_t CRYPTO_rotr_u32(uint32_t value, int shift)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:907
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
RAND_bytes
#define RAND_bytes
Definition: boringssl_prefix_symbols.h:2060
kDefaultIV
static const uint8_t kDefaultIV[]
Definition: key_wrap.c:61
AES_set_encrypt_key
#define AES_set_encrypt_key
Definition: boringssl_prefix_symbols.h:603
Bytes
Definition: boringssl-with-bazel/src/crypto/test/test_util.h:38
vpaes_capable
OPENSSL_INLINE char vpaes_capable(void)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:193
WycheproofResult
Definition: wycheproof_util.h:34
vpaes_cbc_encrypt
OPENSSL_INLINE void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key, uint8_t *ivec, int enc)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:213
string.h
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
aes_hw_ctr32_encrypt_blocks
OPENSSL_INLINE void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, const AES_KEY *key, const uint8_t ivec[16])
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:122
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
ciphertext
const char * ciphertext
Definition: protobuf/src/google/protobuf/stubs/strutil_unittest.cc:86
aes_hw_set_encrypt_key
OPENSSL_INLINE int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits, AES_KEY *key)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:96
ASSERT_GE
#define ASSERT_GE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2072
u
OPENSSL_EXPORT pem_password_cb void * u
Definition: pem.h:351
words
std::vector< std::string > words
Definition: bloaty/third_party/protobuf/src/google/protobuf/repeated_field_unittest.cc:1787
bsaes_ctr32_encrypt_blocks
OPENSSL_INLINE void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, const AES_KEY *key, const uint8_t ivec[16])
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:157
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
OPENSSL_memset
static void * OPENSSL_memset(void *dst, int c, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:835
bsaes_cbc_encrypt
OPENSSL_INLINE void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key, uint8_t ivec[16], int enc)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:151
AES_wrap_key
#define AES_wrap_key
Definition: boringssl_prefix_symbols.h:606
aes_hw_ecb_encrypt
#define aes_hw_ecb_encrypt
Definition: boringssl_prefix_symbols.h:2811
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
AES_BLOCK_SIZE
#define AES_BLOCK_SIZE
Definition: aes.h:68
block
Block * block
Definition: protobuf/src/google/protobuf/descriptor.cc:1041
vpaes_decrypt_key_to_bsaes
OPENSSL_INLINE void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:168
uint32_t
unsigned int uint32_t
Definition: stdint-msvc2008.h:80
FileTestGTest
void FileTestGTest(const char *path, std::function< void(FileTest *)> run_test)
Definition: file_test_gtest.cc:68
hwaes_capable
OPENSSL_INLINE int hwaes_capable(void)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:94
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
SCOPED_TRACE
#define SCOPED_TRACE(message)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2264
a2
T::first_type a2
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:307
TestRaw
static void TestRaw(FileTest *t)
Definition: aes_test.cc:36
CRYPTO_bswap4
static uint32_t CRYPTO_bswap4(uint32_t x)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:753
aes.h
FileTest
Definition: file_test.h:90
OPENSSL_memcpy
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:819
bits
OPENSSL_EXPORT ASN1_BIT_STRING * bits
Definition: x509v3.h:482
GetWycheproofResult
bool GetWycheproofResult(FileTest *t, WycheproofResult *out)
Definition: wycheproof_util.cc:49
ref
unsigned ref
Definition: cxa_demangle.cpp:4909
std::swap
void swap(Json::Value &a, Json::Value &b)
Specialize std::swap() for Json::Value.
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:1226
vpaes_decrypt
OPENSSL_INLINE void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:209
AES_unwrap_key_padded
#define AES_unwrap_key_padded
Definition: boringssl_prefix_symbols.h:605
a1
T::first_type a1
Definition: abseil-cpp/absl/container/internal/hash_function_defaults_test.cc:305
b
uint64_t b
Definition: abseil-cpp/absl/container/internal/layout_test.cc:53
vpaes_ctr32_encrypt_blocks
#define vpaes_ctr32_encrypt_blocks
Definition: boringssl_prefix_symbols.h:3433
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
TEST
TEST(AESTest, TestVectors)
Definition: aes_test.cc:153
kKey
static const uint8_t kKey[32]
Definition: chacha_test.cc:32
AES_set_decrypt_key
#define AES_set_decrypt_key
Definition: boringssl_prefix_symbols.h:602
TestKeyWrap
static void TestKeyWrap(FileTest *t)
Definition: aes_test.cc:70
AES_encrypt
#define AES_encrypt
Definition: boringssl_prefix_symbols.h:600
vpaes_encrypt_key_to_bsaes
OPENSSL_INLINE void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:163
vpaes_set_decrypt_key
OPENSSL_INLINE int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:201
aes_hw_encrypt
OPENSSL_INLINE void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:106
vpaes_encrypt
OPENSSL_INLINE void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:205
rand.h
key
const char * key
Definition: hpack_parser_table.cc:164
vpaes_set_encrypt_key
OPENSSL_INLINE int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:197
TestKeyWrapWithPadding
static void TestKeyWrapWithPadding(FileTest *t)
Definition: aes_test.cc:127
AES_decrypt
#define AES_decrypt
Definition: boringssl_prefix_symbols.h:598
AES_DECRYPT
#define AES_DECRYPT
Definition: aes.h:63
EXPECT_LT
#define EXPECT_LT(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2032
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
ASSERT_FALSE
#define ASSERT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1976
internal.h
plaintext
const char * plaintext
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil_unittest.cc:85
CHECK_ABI
#define CHECK_ABI(...)
Definition: abi_test.h:472
aes_hw_cbc_encrypt
OPENSSL_INLINE void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, const AES_KEY *key, uint8_t *ivec, int enc)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:116
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
AES_unwrap_key
#define AES_unwrap_key
Definition: boringssl_prefix_symbols.h:604
aes_hw_set_decrypt_key
OPENSSL_INLINE int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:101
AES_wrap_key_padded
#define AES_wrap_key_padded
Definition: boringssl_prefix_symbols.h:607
aes_key_st
Definition: aes.h:72
if
if(p->owned &&p->wrapped !=NULL)
Definition: call.c:42
aes_hw_decrypt
OPENSSL_INLINE void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:111
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
bsaes_capable
OPENSSL_INLINE char bsaes_capable(void)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/aes/internal.h:147
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2056


grpc
Author(s):
autogenerated on Fri May 16 2025 02:57:40