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 <memory>
20 #include <vector>
21 
22 #include <gtest/gtest.h>
23 
24 #include <openssl/aes.h>
25 
26 #include "internal.h"
27 #include "../../internal.h"
28 #include "../../test/abi_test.h"
29 #include "../../test/file_test.h"
30 #include "../../test/test_util.h"
31 #include "../../test/wycheproof_util.h"
32 
33 
TestRaw(FileTest * t)34 static void TestRaw(FileTest *t) {
35   std::vector<uint8_t> key, plaintext, ciphertext;
36   ASSERT_TRUE(t->GetBytes(&key, "Key"));
37   ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
38   ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext"));
39 
40   ASSERT_EQ(static_cast<unsigned>(AES_BLOCK_SIZE), plaintext.size());
41   ASSERT_EQ(static_cast<unsigned>(AES_BLOCK_SIZE), ciphertext.size());
42 
43   AES_KEY aes_key;
44   ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key));
45 
46   // Test encryption.
47   uint8_t block[AES_BLOCK_SIZE];
48   AES_encrypt(plaintext.data(), block, &aes_key);
49   EXPECT_EQ(Bytes(ciphertext), Bytes(block));
50 
51   // Test in-place encryption.
52   OPENSSL_memcpy(block, plaintext.data(), AES_BLOCK_SIZE);
53   AES_encrypt(block, block, &aes_key);
54   EXPECT_EQ(Bytes(ciphertext), Bytes(block));
55 
56   ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key));
57 
58   // Test decryption.
59   AES_decrypt(ciphertext.data(), block, &aes_key);
60   EXPECT_EQ(Bytes(plaintext), Bytes(block));
61 
62   // Test in-place decryption.
63   OPENSSL_memcpy(block, ciphertext.data(), AES_BLOCK_SIZE);
64   AES_decrypt(block, block, &aes_key);
65   EXPECT_EQ(Bytes(plaintext), Bytes(block));
66 }
67 
TestKeyWrap(FileTest * t)68 static void TestKeyWrap(FileTest *t) {
69   // All test vectors use the default IV, so test both with implicit and
70   // explicit IV.
71   //
72   // TODO(davidben): Find test vectors that use a different IV.
73   static const uint8_t kDefaultIV[] = {
74       0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
75   };
76 
77   std::vector<uint8_t> key, plaintext, ciphertext;
78   ASSERT_TRUE(t->GetBytes(&key, "Key"));
79   ASSERT_TRUE(t->GetBytes(&plaintext, "Plaintext"));
80   ASSERT_TRUE(t->GetBytes(&ciphertext, "Ciphertext"));
81 
82   ASSERT_EQ(plaintext.size() + 8, ciphertext.size())
83       << "Invalid Plaintext and Ciphertext lengths.";
84 
85   // Test encryption.
86   AES_KEY aes_key;
87   ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes_key));
88 
89   // Test with implicit IV.
90   std::unique_ptr<uint8_t[]> buf(new uint8_t[ciphertext.size()]);
91   int len = AES_wrap_key(&aes_key, nullptr /* iv */, buf.get(),
92                          plaintext.data(), plaintext.size());
93   ASSERT_GE(len, 0);
94   EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len)));
95 
96   // Test with explicit IV.
97   OPENSSL_memset(buf.get(), 0, ciphertext.size());
98   len = AES_wrap_key(&aes_key, kDefaultIV, buf.get(), plaintext.data(),
99                      plaintext.size());
100   ASSERT_GE(len, 0);
101   EXPECT_EQ(Bytes(ciphertext), Bytes(buf.get(), static_cast<size_t>(len)));
102 
103   // Test decryption.
104   ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes_key));
105 
106   // Test with implicit IV.
107   buf.reset(new uint8_t[plaintext.size()]);
108   len = AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(), ciphertext.data(),
109                        ciphertext.size());
110   ASSERT_GE(len, 0);
111   EXPECT_EQ(Bytes(plaintext), Bytes(buf.get(), static_cast<size_t>(len)));
112 
113   // Test with explicit IV.
114   OPENSSL_memset(buf.get(), 0, plaintext.size());
115   len = AES_unwrap_key(&aes_key, kDefaultIV, buf.get(), ciphertext.data(),
116                        ciphertext.size());
117   ASSERT_GE(len, 0);
118 
119   // Test corrupted ciphertext.
120   ciphertext[0] ^= 1;
121   EXPECT_EQ(-1, AES_unwrap_key(&aes_key, nullptr /* iv */, buf.get(),
122                                ciphertext.data(), ciphertext.size()));
123 }
124 
TEST(AESTest,TestVectors)125 TEST(AESTest, TestVectors) {
126   FileTestGTest("crypto/fipsmodule/aes/aes_tests.txt", [](FileTest *t) {
127     if (t->GetParameter() == "Raw") {
128       TestRaw(t);
129     } else if (t->GetParameter() == "KeyWrap") {
130       TestKeyWrap(t);
131     } else {
132       ADD_FAILURE() << "Unknown mode " << t->GetParameter();
133     }
134   });
135 }
136 
TEST(AESTest,WycheproofKeyWrap)137 TEST(AESTest, WycheproofKeyWrap) {
138   FileTestGTest("third_party/wycheproof_testvectors/kw_test.txt",
139                 [](FileTest *t) {
140     std::string key_size;
141     ASSERT_TRUE(t->GetInstruction(&key_size, "keySize"));
142     std::vector<uint8_t> ct, key, msg;
143     ASSERT_TRUE(t->GetBytes(&ct, "ct"));
144     ASSERT_TRUE(t->GetBytes(&key, "key"));
145     ASSERT_TRUE(t->GetBytes(&msg, "msg"));
146     ASSERT_EQ(static_cast<unsigned>(atoi(key_size.c_str())), key.size() * 8);
147     WycheproofResult result;
148     ASSERT_TRUE(GetWycheproofResult(t, &result));
149 
150     if (result != WycheproofResult::kInvalid) {
151       ASSERT_GE(ct.size(), 8u);
152 
153       AES_KEY aes;
154       ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes));
155       std::vector<uint8_t> out(ct.size() - 8);
156       int len = AES_unwrap_key(&aes, nullptr, out.data(), ct.data(), ct.size());
157       ASSERT_EQ(static_cast<int>(out.size()), len);
158       EXPECT_EQ(Bytes(msg), Bytes(out));
159 
160       out.resize(msg.size() + 8);
161       ASSERT_EQ(0, AES_set_encrypt_key(key.data(), 8 * key.size(), &aes));
162       len = AES_wrap_key(&aes, nullptr, out.data(), msg.data(), msg.size());
163       ASSERT_EQ(static_cast<int>(out.size()), len);
164       EXPECT_EQ(Bytes(ct), Bytes(out));
165     } else {
166       AES_KEY aes;
167       ASSERT_EQ(0, AES_set_decrypt_key(key.data(), 8 * key.size(), &aes));
168       std::vector<uint8_t> out(ct.size() < 8 ? 0 : ct.size() - 8);
169       int len = AES_unwrap_key(&aes, nullptr, out.data(), ct.data(), ct.size());
170       EXPECT_EQ(-1, len);
171     }
172   });
173 }
174 
TEST(AESTest,WrapBadLengths)175 TEST(AESTest, WrapBadLengths) {
176   uint8_t key[128/8] = {0};
177   AES_KEY aes;
178   ASSERT_EQ(0, AES_set_encrypt_key(key, 128, &aes));
179 
180   // Input lengths to |AES_wrap_key| must be a multiple of 8 and at least 16.
181   static const size_t kLengths[] = {0, 1,  2,  3,  4,  5,  6,  7, 8,
182                                     9, 10, 11, 12, 13, 14, 15, 20};
183   for (size_t len : kLengths) {
184     SCOPED_TRACE(len);
185     std::vector<uint8_t> in(len);
186     std::vector<uint8_t> out(len + 8);
187     EXPECT_EQ(-1,
188               AES_wrap_key(&aes, nullptr, out.data(), in.data(), in.size()));
189   }
190 }
191 
192 #if defined(SUPPORTS_ABI_TEST)
TEST(AESTest,ABI)193 TEST(AESTest, ABI) {
194   for (int bits : {128, 192, 256}) {
195     SCOPED_TRACE(bits);
196     const uint8_t kKey[256/8] = {0};
197     AES_KEY key;
198     uint8_t block[AES_BLOCK_SIZE];
199     uint8_t buf[AES_BLOCK_SIZE * 64] = {0};
200     std::vector<int> block_counts;
201     if (bits == 128) {
202       block_counts = {0, 1, 2, 3, 4, 8, 16, 31};
203     } else {
204       // Unwind tests are very slow. Assume that the various input sizes do not
205       // differ significantly by round count for ABI purposes.
206       block_counts = {0, 1, 8};
207     }
208 
209     CHECK_ABI(aes_nohw_set_encrypt_key, kKey, bits, &key);
210     CHECK_ABI(aes_nohw_encrypt, block, block, &key);
211 #if defined(AES_NOHW_CBC)
212     for (size_t blocks : block_counts) {
213       SCOPED_TRACE(blocks);
214       CHECK_ABI(aes_nohw_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
215                 block, AES_ENCRYPT);
216     }
217 #endif
218 
219     CHECK_ABI(aes_nohw_set_decrypt_key, kKey, bits, &key);
220     CHECK_ABI(aes_nohw_decrypt, block, block, &key);
221 #if defined(AES_NOHW_CBC)
222     for (size_t blocks : block_counts) {
223       SCOPED_TRACE(blocks);
224       CHECK_ABI(aes_nohw_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
225                 block, AES_DECRYPT);
226     }
227 #endif
228 
229     if (bsaes_capable()) {
230       aes_nohw_set_encrypt_key(kKey, bits, &key);
231       for (size_t blocks : block_counts) {
232         SCOPED_TRACE(blocks);
233         if (blocks != 0) {
234           CHECK_ABI(bsaes_ctr32_encrypt_blocks, buf, buf, blocks, &key, block);
235         }
236       }
237 
238       aes_nohw_set_decrypt_key(kKey, bits, &key);
239       for (size_t blocks : block_counts) {
240         SCOPED_TRACE(blocks);
241         CHECK_ABI(bsaes_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
242                   block, AES_DECRYPT);
243       }
244     }
245 
246     if (vpaes_capable()) {
247       CHECK_ABI(vpaes_set_encrypt_key, kKey, bits, &key);
248       CHECK_ABI(vpaes_encrypt, block, block, &key);
249       for (size_t blocks : block_counts) {
250         SCOPED_TRACE(blocks);
251         CHECK_ABI(vpaes_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
252                   block, AES_ENCRYPT);
253 #if defined(VPAES_CTR32)
254         CHECK_ABI(vpaes_ctr32_encrypt_blocks, buf, buf, blocks, &key, block);
255 #endif
256       }
257 
258       CHECK_ABI(vpaes_set_decrypt_key, kKey, bits, &key);
259       CHECK_ABI(vpaes_decrypt, block, block, &key);
260       for (size_t blocks : block_counts) {
261         SCOPED_TRACE(blocks);
262         CHECK_ABI(vpaes_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
263                   block, AES_DECRYPT);
264       }
265     }
266 
267     if (hwaes_capable()) {
268       CHECK_ABI(aes_hw_set_encrypt_key, kKey, bits, &key);
269       CHECK_ABI(aes_hw_encrypt, block, block, &key);
270       for (size_t blocks : block_counts) {
271         SCOPED_TRACE(blocks);
272         CHECK_ABI(aes_hw_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
273                   block, AES_ENCRYPT);
274         CHECK_ABI(aes_hw_ctr32_encrypt_blocks, buf, buf, blocks, &key, block);
275 #if defined(HWAES_ECB)
276         CHECK_ABI(aes_hw_ecb_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
277                   AES_ENCRYPT);
278 #endif
279       }
280 
281       CHECK_ABI(aes_hw_set_decrypt_key, kKey, bits, &key);
282       CHECK_ABI(aes_hw_decrypt, block, block, &key);
283       for (size_t blocks : block_counts) {
284         SCOPED_TRACE(blocks);
285         CHECK_ABI(aes_hw_cbc_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
286                   block, AES_DECRYPT);
287 #if defined(HWAES_ECB)
288         CHECK_ABI(aes_hw_ecb_encrypt, buf, buf, AES_BLOCK_SIZE * blocks, &key,
289                   AES_DECRYPT);
290 #endif
291       }
292     }
293   }
294 }
295 #endif  // SUPPORTS_ABI_TEST
296