1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <limits.h>
6 #include <stddef.h>
7 #include <stdint.h>
8 
9 #include <crypto/aead.h>
10 #include <crypto/bytes.h>
11 #include <crypto/secret.h>
12 #include <unittest/unittest.h>
13 #include <zircon/errors.h>
14 #include <zircon/types.h>
15 
16 #include "utils.h"
17 
18 namespace crypto {
19 namespace testing {
20 namespace {
21 
22 // See utils.h; the following macros allow reusing tests for each of the supported AEADs.
23 #define EACH_PARAM(OP, Test)                                                                       \
24     OP(Test, AEAD, AES128_GCM)                                                                     \
25     OP(Test, AEAD, AES128_GCM_SIV)
26 
TestGetLengths_Uninitialized(void)27 bool TestGetLengths_Uninitialized(void) {
28     size_t key_len;
29     EXPECT_ZX(AEAD::GetKeyLen(AEAD::kUninitialized, &key_len), ZX_ERR_INVALID_ARGS);
30 
31     size_t iv_len;
32     EXPECT_ZX(AEAD::GetIVLen(AEAD::kUninitialized, &iv_len), ZX_ERR_INVALID_ARGS);
33     END_TEST;
34 }
35 
TestGetLengths_AES128_GCM(void)36 bool TestGetLengths_AES128_GCM(void) {
37     size_t key_len;
38     EXPECT_ZX(AEAD::GetKeyLen(AEAD::kAES128_GCM, nullptr), ZX_ERR_INVALID_ARGS);
39     EXPECT_OK(AEAD::GetKeyLen(AEAD::kAES128_GCM, &key_len));
40     EXPECT_EQ(key_len, 16U);
41 
42     size_t iv_len;
43     EXPECT_ZX(AEAD::GetIVLen(AEAD::kAES128_GCM, nullptr), ZX_ERR_INVALID_ARGS);
44     EXPECT_OK(AEAD::GetIVLen(AEAD::kAES128_GCM, &iv_len));
45     EXPECT_EQ(iv_len, 12U);
46 
47     size_t tag_len;
48     EXPECT_ZX(AEAD::GetTagLen(AEAD::kAES128_GCM, nullptr), ZX_ERR_INVALID_ARGS);
49     EXPECT_OK(AEAD::GetTagLen(AEAD::kAES128_GCM, &tag_len));
50     EXPECT_EQ(tag_len, 16U);
51     END_TEST;
52 }
53 
TestGetLengths_AES128_GCM_SIV(void)54 bool TestGetLengths_AES128_GCM_SIV(void) {
55     size_t key_len;
56     EXPECT_ZX(AEAD::GetKeyLen(AEAD::kAES128_GCM_SIV, nullptr), ZX_ERR_INVALID_ARGS);
57     EXPECT_OK(AEAD::GetKeyLen(AEAD::kAES128_GCM_SIV, &key_len));
58     EXPECT_EQ(key_len, 16U);
59 
60     size_t iv_len;
61     EXPECT_ZX(AEAD::GetIVLen(AEAD::kAES128_GCM_SIV, nullptr), ZX_ERR_INVALID_ARGS);
62     EXPECT_OK(AEAD::GetIVLen(AEAD::kAES128_GCM_SIV, &iv_len));
63     EXPECT_EQ(iv_len, 12U);
64 
65     size_t tag_len;
66     EXPECT_ZX(AEAD::GetTagLen(AEAD::kAES128_GCM_SIV, nullptr), ZX_ERR_INVALID_ARGS);
67     EXPECT_OK(AEAD::GetTagLen(AEAD::kAES128_GCM_SIV, &tag_len));
68     EXPECT_EQ(tag_len, 16U);
69     END_TEST;
70 }
71 
TestInitSeal_Uninitialized(void)72 bool TestInitSeal_Uninitialized(void) {
73     BEGIN_TEST;
74     AEAD sealer;
75     Secret key;
76     Bytes iv;
77     EXPECT_ZX(sealer.InitSeal(AEAD::kUninitialized, key, iv), ZX_ERR_INVALID_ARGS);
78     END_TEST;
79 }
80 
TestInitSeal(AEAD::Algorithm aead)81 bool TestInitSeal(AEAD::Algorithm aead) {
82     BEGIN_TEST;
83     AEAD sealer;
84     Secret key;
85     Bytes iv;
86     ASSERT_OK(GenerateKeyMaterial(aead, &key, &iv));
87 
88     // Bad key
89     Secret bad_key;
90     ASSERT_OK(bad_key.Generate(key.len() - 1));
91     EXPECT_ZX(sealer.InitSeal(aead, bad_key, iv), ZX_ERR_INVALID_ARGS);
92 
93     // Bad IV
94     Bytes bad_iv;
95     ASSERT_OK(iv.Copy(iv.get(), iv.len() - 1));
96     EXPECT_ZX(sealer.InitSeal(aead, key, bad_iv), ZX_ERR_INVALID_ARGS);
97 
98     // Valid
99     EXPECT_OK(sealer.InitSeal(aead, key, iv));
100 
101     END_TEST;
102 }
DEFINE_EACH(TestInitSeal)103 DEFINE_EACH(TestInitSeal)
104 
105 bool TestInitOpen_Uninitialized(void) {
106     BEGIN_TEST;
107     AEAD opener;
108     Secret key;
109     Bytes iv;
110     EXPECT_ZX(opener.InitOpen(AEAD::kUninitialized, key, iv), ZX_ERR_INVALID_ARGS);
111     END_TEST;
112 }
113 
TestInitOpen(AEAD::Algorithm aead)114 bool TestInitOpen(AEAD::Algorithm aead) {
115     BEGIN_TEST;
116     AEAD opener;
117     Secret key;
118     Bytes iv;
119     ASSERT_OK(GenerateKeyMaterial(aead, &key, &iv));
120 
121     // Bad key
122     Secret bad_key;
123     ASSERT_OK(bad_key.Generate(key.len() - 1));
124     EXPECT_ZX(opener.InitOpen(aead, bad_key, iv), ZX_ERR_INVALID_ARGS);
125 
126     // Bad IV
127     Bytes bad_iv;
128     ASSERT_OK(bad_iv.Copy(iv.get(), iv.len() - 1));
129     EXPECT_ZX(opener.InitOpen(aead, key, bad_iv), ZX_ERR_INVALID_ARGS);
130 
131     // Valid
132     EXPECT_OK(opener.InitOpen(aead, key, iv));
133 
134     END_TEST;
135 }
DEFINE_EACH(TestInitOpen)136 DEFINE_EACH(TestInitOpen)
137 
138 bool TestSealData(AEAD::Algorithm aead) {
139     BEGIN_TEST;
140     AEAD sealer;
141     Secret key;
142     Bytes iv, ptext, ctext;
143     uint64_t nonce;
144     ASSERT_OK(GenerateKeyMaterial(aead, &key, &iv));
145     ASSERT_OK(ptext.Randomize(PAGE_SIZE));
146 
147     // Not initialized
148     EXPECT_ZX(sealer.Seal(ptext, &nonce, &ctext), ZX_ERR_BAD_STATE);
149     ASSERT_OK(sealer.InitSeal(aead, key, iv));
150 
151     // Missing parameters
152     EXPECT_ZX(sealer.Seal(ptext, nullptr, &ctext), ZX_ERR_INVALID_ARGS);
153     EXPECT_ZX(sealer.Seal(ptext, &nonce, nullptr), ZX_ERR_INVALID_ARGS);
154 
155     // Wrong mode
156     EXPECT_ZX(sealer.Open(nonce, ctext, &ptext), ZX_ERR_BAD_STATE);
157 
158     // Valid
159     EXPECT_OK(sealer.Seal(ptext, &nonce, &ctext));
160     ASSERT_OK(ptext.Resize(0));
161     EXPECT_OK(sealer.Seal(ptext, &nonce, &ctext));
162 
163     // Reset
164     sealer.Reset();
165     EXPECT_ZX(sealer.Seal(ptext, &nonce, &ctext), ZX_ERR_BAD_STATE);
166     END_TEST;
167 }
DEFINE_EACH(TestSealData)168 DEFINE_EACH(TestSealData)
169 
170 bool TestOpenData(AEAD::Algorithm aead) {
171     BEGIN_TEST;
172     Secret key;
173     Bytes iv, ptext, ctext, result;
174     uint64_t nonce = 0;
175     ASSERT_OK(GenerateKeyMaterial(aead, &key, &iv));
176     ASSERT_OK(ptext.Randomize(PAGE_SIZE));
177 
178     AEAD sealer;
179     ASSERT_OK(sealer.InitSeal(aead, key, iv));
180     // ASSERT_OK(sealer.Seal(ptext, &nonce, &ctext));
181 
182     // Not initialized
183     AEAD opener;
184     EXPECT_ZX(opener.Open(nonce, ctext, &result), ZX_ERR_BAD_STATE);
185     ASSERT_OK(opener.InitOpen(aead, key, iv));
186 
187     // Missing parameters
188     EXPECT_ZX(opener.Open(nonce, ctext, nullptr), ZX_ERR_INVALID_ARGS);
189 
190     // Wrong IV
191     ASSERT_OK(sealer.Seal(ptext, &nonce, &ctext));
192     EXPECT_ZX(opener.Open(nonce + 1, ctext, &result), ZX_ERR_IO_DATA_INTEGRITY);
193 
194     // Wrong tag
195     size_t len;
196     ASSERT_OK(AEAD::GetTagLen(aead, &len));
197     ASSERT_OK(ctext.Resize(len - 1));
198     EXPECT_ZX(opener.Open(nonce, ctext, &result), ZX_ERR_INVALID_ARGS);
199 
200     ASSERT_OK(ctext.Resize(0));
201     ASSERT_OK(sealer.Seal(ptext, &nonce, &ctext));
202     len = ctext.len();
203     ctext[len - 1] ^= 1;
204     EXPECT_ZX(opener.Open(nonce, ctext, &result), ZX_ERR_IO_DATA_INTEGRITY);
205     ctext[len - 1] ^= 1;
206 
207     // Wrong data
208     ctext[0] ^= 1;
209     EXPECT_ZX(opener.Open(nonce, ctext, &result), ZX_ERR_IO_DATA_INTEGRITY);
210     ctext[0] ^= 1;
211 
212     // Wrong mode
213     EXPECT_ZX(opener.Seal(ptext, &nonce, &ctext), ZX_ERR_BAD_STATE);
214 
215     // Valid
216     ASSERT_OK(sealer.Seal(ptext, &nonce, &ctext));
217     EXPECT_OK(opener.Open(nonce, ctext, &result));
218 
219     ASSERT_OK(sealer.Seal(ptext, &nonce, &ctext));
220     EXPECT_OK(opener.Open(nonce, ctext, &result));
221     EXPECT_TRUE(ptext == result);
222 
223     // Reset
224     opener.Reset();
225     EXPECT_ZX(opener.Open(nonce, ctext, &result), ZX_ERR_BAD_STATE);
226     END_TEST;
227 }
DEFINE_EACH(TestOpenData)228 DEFINE_EACH(TestOpenData)
229 
230 // The following tests are taken from NIST's SP 800-38D.  The tests with non-byte non-standard IV
231 // and tag lengths are omitted.  Of those remaining, the first non-failing test of each combination
232 // of text and AAD length is selected as a representative sample.
233 bool TestAes128Gcm_TC(const char* xkey, const char* xiv, const char* xct, const char* xaad,
234                       const char* xtag, const char* xpt) {
235     BEGIN_TEST;
236     Secret key;
237     Bytes ptext, aad, iv, ctext, tag, result;
238     uint64_t nonce;
239     ASSERT_OK(HexToSecret(xkey, &key));
240     ASSERT_OK(HexToBytes(xiv, &iv));
241     ASSERT_OK(HexToBytes(xct, &ctext));
242     ASSERT_OK(HexToBytes(xaad, &aad));
243     ASSERT_OK(HexToBytes(xtag, &tag));
244     ASSERT_OK(HexToBytes(xpt, &ptext));
245     ASSERT_OK(ctext.Copy(tag.get(), tag.len(), ctext.len()));
246 
247     AEAD sealer;
248     EXPECT_OK(sealer.InitSeal(AEAD::kAES128_GCM, key, iv));
249     EXPECT_OK(sealer.Seal(ptext, aad, &nonce, &result));
250     EXPECT_TRUE(result == ctext);
251 
252     ASSERT_OK(result.Resize(0));
253     AEAD opener;
254     EXPECT_OK(opener.InitOpen(AEAD::kAES128_GCM, key, iv));
255     EXPECT_OK(opener.Open(nonce, ctext, aad, &result));
256     EXPECT_TRUE(result == ptext);
257     END_TEST;
258 }
259 
260 // clang-format off
TestAes128Gcm_TC01(void)261 bool TestAes128Gcm_TC01(void) {
262     return TestAes128Gcm_TC(
263         /* Key */ "cf063a34d4a9a76c2c86787d3f96db71",
264         /* IV */  "113b9785971864c83b01c787",
265         /* CT */  "",
266         /* AAD */ "",
267         /* Tag */ "72ac8493e3a5228b5d130a69d2510e42",
268         /* PT */  "");
269 }
270 
TestAes128Gcm_TC02(void)271 bool TestAes128Gcm_TC02(void) {
272     return TestAes128Gcm_TC(
273         /* Key */ "e98b72a9881a84ca6b76e0f43e68647a",
274         /* IV */  "8b23299fde174053f3d652ba",
275         /* CT */  "5a3c1cf1985dbb8bed818036fdd5ab42",
276         /* AAD */ "",
277         /* Tag */ "23c7ab0f952b7091cd324835043b5eb5",
278         /* PT */  "28286a321293253c3e0aa2704a278032");
279 }
280 
TestAes128Gcm_TC03(void)281 bool TestAes128Gcm_TC03(void) {
282     return TestAes128Gcm_TC(
283         /* Key */ "816e39070410cf2184904da03ea5075a",
284         /* IV */  "32c367a3362613b27fc3e67e",
285         /* CT */  "552ebe012e7bcf90fcef712f8344e8f1",
286         /* AAD */ "f2a30728ed874ee02983c294435d3c16",
287         /* Tag */ "ecaae9fc68276a45ab0ca3cb9dd9539f",
288         /* PT */  "ecafe96c67a1646744f1c891f5e69427");
289 }
290 
TestAes128Gcm_TC04(void)291 bool TestAes128Gcm_TC04(void) {
292     return TestAes128Gcm_TC(
293         /* Key */ "d9529840200e1c17725ab52c9c927637",
294         /* IV */  "6e9a639d4aecc25530a8ad75",
295         /* CT */  "6c779895e78179783c51ade1926436b9",
296         /* AAD */ "472a6f4e7771ca391e42065030db3ff418f3b636",
297         /* Tag */ "4522bfdef4a635a38db5784b27d43661",
298         /* PT */  "8ae823895ee4e7f08bc8bad04d63c220");
299 }
300 
TestAes128Gcm_TC05(void)301 bool TestAes128Gcm_TC05(void) {
302     return TestAes128Gcm_TC(
303         /* Key */ "abbc49ee0bbe3d81afc2b6b84f70b748",
304         /* IV */  "f11db9f7b99a59ed59ade66f",
305         /* CT */  "ce2d76f834942c022044eebc91b461c0",
306         /* AAD */ "d533cf7644a48da46fcdec47ae5c77b9b52db775d6c886896e4f4e00c51affd59499a0e572f324989df511c4ea5f93cd",
307         /* Tag */ "62df4b04f219554cd3e69d3c870032d2",
308         /* PT */  "5135ba1354cbb80478ecaf3db38a443f");
309 }
310 
TestAes128Gcm_TC06(void)311 bool TestAes128Gcm_TC06(void) {
312     return TestAes128Gcm_TC(
313         /* Key */ "300b8ffab4368cc90f6d4063e4279f2a",
314         /* IV */  "8e69fa64e871d0e98a183a49",
315         /* CT */  "2d2292da61c280aff86767d25b75e814",
316         /* AAD */ "5166309e153447b27c67051453abf441de3f4a7f6b633ec6122ff82dc132cfb422d36c5ec6e7cc90a9ad55caa1ccdcb82dc5022a20062a9c6e9238f34d085b1f554b5eac05eff25b5a5cb6e18e7827d70175dc0662d77033d118",
317         /* Tag */ "633ee657a8981a7682f87505594c95ad",
318         /* PT */  "4953b54859870631e818da71fc69c981");
319 }
320 
TestAes128Gcm_TC07(void)321 bool TestAes128Gcm_TC07(void) {
322     return TestAes128Gcm_TC(
323         /* Key */ "387218b246c1a8257748b56980e50c94",
324         /* IV */  "dd7e014198672be39f95b69d",
325         /* CT */  "cdba9e73eaf3d38eceb2b04a8d",
326         /* AAD */ "",
327         /* Tag */ "ecf90f4a47c9c626d6fb2c765d201556",
328         /* PT */  "48f5b426baca03064554cc2b30");
329 }
330 
TestAes128Gcm_TC08(void)331 bool TestAes128Gcm_TC08(void) {
332     return TestAes128Gcm_TC(
333         /* Key */ "660eb76f3d8b6ec54e01b8a36263124b",
334         /* IV */  "3d8cf16e262880ddfe0c86eb",
335         /* CT */  "b1ee05f1415a61d7637e97c5f3",
336         /* AAD */ "8560b10c011a1d4190eb46a3692daa17",
337         /* Tag */ "761cb84a963e1db1a4ab2c5f904c09db",
338         /* PT */  "2efbaedfec3cfe4ac32f201fa5");
339 }
340 
TestAes128Gcm_TC09(void)341 bool TestAes128Gcm_TC09(void) {
342     return TestAes128Gcm_TC(
343         /* Key */ "c62dc36b9230e739179f3c58e7270ff9",
344         /* IV */  "196a0572d8ff2fbd3522b6a5",
345         /* CT */  "958062b331f05b3acaa1836fc2",
346         /* AAD */ "4d10536cbdbd6f1d38b2bd10ab8c1c29ae68138e",
347         /* Tag */ "dc65a20d9a9aec2e7699eaead47afb42",
348         /* PT */  "6d8abcee45667e7a9443896cbf");
349 }
350 
TestAes128Gcm_TC10(void)351 bool TestAes128Gcm_TC10(void) {
352     return TestAes128Gcm_TC(
353         /* Key */ "ef1da9dd794219ebf8f717d5a98ab0af",
354         /* IV */  "3f3983dc63986e33d1b6bffc",
355         /* CT */  "95ea05701481e915c72446c876",
356         /* AAD */ "5abd0c1c52b687e9a1673b69137895e5025c2bd18cbeacdb9472e918fe1587da558c492cc708d270fd10572eea83d2de",
357         /* Tag */ "5c866992662005ca8886810e278c8ab4",
358         /* PT */  "5511872905436c7de38e9501e7");
359 }
360 
TestAes128Gcm_TC11(void)361 bool TestAes128Gcm_TC11(void) {
362     return TestAes128Gcm_TC(
363         /* Key */ "77b55a5b37690c9b1b01a05820838e3e",
364         /* IV */  "7a8e0d881f023a9954941037",
365         /* CT */  "e0eb3359e443e1108ed4068969",
366         /* AAD */ "0bb1ad1d294b927c24ee097d0a9afbaa6a62c8923627b50bd96e5ba852509a2e76f7a10ee3987e37a55b92d08531897e6cd76462403b39fb31508cc9fc7684ab5ec2ccc73e8a7f4104a277319bf207fcf263eceed13a76ca177f",
367         /* Tag */ "ea6383077d15d7d0a97220848a7616a9",
368         /* PT */  "d164aeccec7dbcadee4f41b6a9");
369 }
370 
TestAes128Gcm_TC12(void)371 bool TestAes128Gcm_TC12(void) {
372     return TestAes128Gcm_TC(
373         /* Key */ "bfd414a6212958a607a0f5d3ab48471d",
374         /* IV */  "86d8ea0ab8e40dcc481cd0e2",
375         /* CT */  "62171db33193292d930bf6647347652c1ef33316d7feca99d54f1db4fcf513f8",
376         /* AAD */ "",
377         /* Tag */ "c28280aa5c6c7a8bd366f28c1cfd1f6e",
378         /* PT */  "a6b76a066e63392c9443e60272ceaeb9d25c991b0f2e55e2804e168c05ea591a");
379 }
380 
TestAes128Gcm_TC13(void)381 bool TestAes128Gcm_TC13(void) {
382     return TestAes128Gcm_TC(
383         /* Key */ "95bcde70c094f04e3dd8259cafd88ce8",
384         /* IV */  "12cf097ad22380432ff40a5c",
385         /* CT */  "8a023ba477f5b809bddcda8f55e09064d6d88aaec99c1e141212ea5b08503660",
386         /* AAD */ "c783a0cca10a8d9fb8d27d69659463f2",
387         /* Tag */ "562f500dae635d60a769b466e15acd1e",
388         /* PT */  "32f51e837a9748838925066d69e87180f34a6437e6b396e5643b34cb2ee4f7b1");
389 }
390 
TestAes128Gcm_TC14(void)391 bool TestAes128Gcm_TC14(void) {
392     return TestAes128Gcm_TC(
393         /* Key */ "f3e60720c7eff3af96a0e7b2a359c322",
394         /* IV */  "8c9cb6af794f8c0fc4c8c06e",
395         /* CT */  "73e308d968ead96cefc9337dea6952ac3afbe39d7d14d063b9f59ab89c3f6acc",
396         /* AAD */ "5d15b60acc008f9308731ea0a3098644866fa862",
397         /* Tag */ "658e311f9c9816dbf2567f811e905ab8",
398         /* PT */  "7e299a25404311ee29eee9349f1e7f876dca42ba81f44295bb9b3a152a27a2af");
399 }
400 
TestAes128Gcm_TC15(void)401 bool TestAes128Gcm_TC15(void) {
402     return TestAes128Gcm_TC(
403         /* Key */ "8453cf505f22445634b18680c1f6b0f3",
404         /* IV */  "fab8e5ce90102286182ef690",
405         /* CT */  "5475442af3ba2bd865ae082bc5e92ad7f42cd84b8c64daadcf18f0d4863b6172",
406         /* AAD */ "ff76d2210f2caec37490a19352c3945be1c5facb89cb3e9947754cade47ec932d95c88d7d2299a8b6db76b5144ab9516",
407         /* Tag */ "972a7e85787ba26c626db1a1e7c13acb",
408         /* PT */  "e4abb4773f5cc51c9df6322612d75f70696c17733ce41e22427250ae61fd90d3");
409 }
410 
TestAes128Gcm_TC16(void)411 bool TestAes128Gcm_TC16(void) {
412     return TestAes128Gcm_TC(
413         /* Key */ "07a6be880a58f572dbc2ad74a56db8b6",
414         /* IV */  "95fc6654e6dc3a8adf5e7a69",
415         /* CT */  "095635c7e0eac0fc1059e67e1a936b6f72671121f96699fed520e5f8aff777f0",
416         /* AAD */ "de4269feea1a439d6e8990fd6f9f9d5bc67935294425255ea89b6f6772d680fd656b06581a5d8bc5c017ab532b4a9b83a55fde58cdfb3d2a8fef3aa426bc59d3e32f09d3cc20b1ceb9a9e349d1068a0aa3d39617fae0582ccef0",
417         /* Tag */ "b2235f6d4bdd7b9c0901711048859d47",
418         /* PT */  "7680b48b5d28f38cdeab2d5851769394a3e141b990ec4bdf79a33e5315ac0338");
419 }
420 
TestAes128Gcm_TC17(void)421 bool TestAes128Gcm_TC17(void) {
422     return TestAes128Gcm_TC(
423         /* Key */ "93ae114052b7985d409a39a40df8c7ee",
424         /* IV */  "8ad733a4a9b8330690238c42",
425         /* CT */  "bbb5b672a479afca2b11adb0a4c762b698dd565908fee1d101f6a01d63332c91b85d7f03ac48a477897d512b4572f9042cb7ea",
426         /* AAD */ "",
427         /* Tag */ "4d78bdcb1366fcba02fdccee57e1ff44",
428         /* PT */  "3f3bb0644eac878b97d990d257f5b36e1793490dbc13fea4efe9822cebba7444cce4dee5a7f5dfdf285f96785792812200c279");
429 }
430 
TestAes128Gcm_TC18(void)431 bool TestAes128Gcm_TC18(void) {
432     return TestAes128Gcm_TC(
433         /* Key */ "bc22f3f05cc40db9311e4192966fee92",
434         /* IV */  "134988e662343c06d3ab83db",
435         /* CT */  "4c0168ab95d3a10ef25e5924108389365c67d97778995892d9fd46897384af61fc559212b3267e90fe4df7bfd1fbed46f4b9ee",
436         /* AAD */ "10087e6ed81049b509c31d12fee88c64",
437         /* Tag */ "771357958a316f166bd0dacc98ea801a",
438         /* PT */  "337c1bc992386cf0f957617fe4d5ec1218ae1cc40369305518eb177e9b15c1646b142ff71237efaa58790080cd82e8848b295c");
439 }
440 
TestAes128Gcm_TC19(void)441 bool TestAes128Gcm_TC19(void) {
442     return TestAes128Gcm_TC(
443         /* Key */ "af57f42c60c0fc5a09adb81ab86ca1c3",
444         /* IV */  "a2dc01871f37025dc0fc9a79",
445         /* CT */  "b9a535864f48ea7b6b1367914978f9bfa087d854bb0e269bed8d279d2eea1210e48947338b22f9bad09093276a331e9c79c7f4",
446         /* AAD */ "41dc38988945fcb44faf2ef72d0061289ef8efd8",
447         /* Tag */ "4f71e72bde0018f555c5adcce062e005",
448         /* PT */  "3803a0727eeb0ade441e0ec107161ded2d425ec0d102f21f51bf2cf9947c7ec4aa72795b2f69b041596e8817d0a3c16f8fadeb");
449 }
450 
TestAes128Gcm_TC20(void)451 bool TestAes128Gcm_TC20(void) {
452     return TestAes128Gcm_TC(
453         /* Key */ "f0305c7b513960533519473976f02beb",
454         /* IV */  "1a7f6ea0e6c9aa5cf8b78b09",
455         /* CT */  "30043bcbe2177ab25e4b00a92ee1cd80e9daaea0bc0a827fc5fcb84e7b07be6395582a5a14e768dde80a20dae0a8b1d8d1d29b",
456         /* AAD */ "7e2071cc1c70719143981de543cd28dbceb92de0d6021bda4417e7b6417938b126632ecff6e00766e5d0aad3d6f06811",
457         /* Tag */ "796c41624f6c3cab762380d21ab6130b",
458         /* PT */  "e5fc990c0739e05bd4655871c7401128117737a11d520372239ab723f7fde78dc4212ac565ee5ee100a014dbb71ea13cdb08eb");
459 }
460 
TestAes128Gcm_TC21(void)461 bool TestAes128Gcm_TC21(void) {
462     return TestAes128Gcm_TC(
463         /* Key */ "da2bb7d581493d692380c77105590201",
464         /* IV */  "44aa3e7856ca279d2eb020c6",
465         /* CT */  "9290d430c9e89c37f0446dbd620c9a6b34b1274aeb6f911f75867efcf95b6feda69f1af4ee16c761b3c9aeac3da03aa9889c88",
466         /* AAD */ "4cd171b23bddb3a53cdf959d5c1710b481eb3785a90eb20a2345ee00d0bb7868c367ab12e6f4dd1dee72af4eee1d197777d1d6499cc541f34edbf45cda6ef90b3c024f9272d72ec1909fb8fba7db88a4d6f7d3d925980f9f9f72",
467         /* Tag */ "9e3ac938d3eb0cadd6f5c9e35d22ba38",
468         /* PT */  "9bbf4c1a2742f6ac80cb4e8a052e4a8f4f07c43602361355b717381edf9fabd4cb7e3ad65dbd1378b196ac270588dd0621f642");
469 }
470 // clang-format on
471 
472 // The following tests are taken from the draft AES-GCM RFC (version 6), appendix C.1.  They are
473 // intentionally formatted to be as close to the RFC's representation as possible.
TestAes128GcmSiv_TC(const char * xpt,const char * xaad,const char * xkey,const char * xnonce,const char * xresult)474 bool TestAes128GcmSiv_TC(const char* xpt, const char* xaad, const char* xkey, const char* xnonce,
475                          const char* xresult) {
476     BEGIN_TEST;
477     Secret key;
478     Bytes ptext, aad, iv, ctext, tag, result;
479     uint64_t nonce;
480     ASSERT_OK(HexToBytes(xpt, &ptext));
481     ASSERT_OK(HexToBytes(xaad, &aad));
482     ASSERT_OK(HexToSecret(xkey, &key));
483     ASSERT_OK(HexToBytes(xnonce, &iv));
484     ASSERT_OK(HexToBytes(xresult, &result));
485 
486     AEAD sealer;
487     EXPECT_OK(sealer.InitSeal(AEAD::kAES128_GCM_SIV, key, iv));
488     EXPECT_OK(sealer.Seal(ptext, aad, &nonce, &ctext));
489     EXPECT_TRUE(ctext == result);
490 
491     ASSERT_OK(result.Resize(0));
492     AEAD opener;
493     EXPECT_OK(opener.InitOpen(AEAD::kAES128_GCM_SIV, key, iv));
494     EXPECT_OK(opener.Open(nonce, ctext, aad, &result));
495     EXPECT_TRUE(ptext == result);
496     END_TEST;
497 }
498 
499 // clang-format off
TestAes128GcmSiv_TC01(void)500 bool TestAes128GcmSiv_TC01(void) {
501     return TestAes128GcmSiv_TC(
502         /* Plaintext (0 bytes) */  "",
503         /* AAD (0 bytes) */        "",
504         /* Key */                  "01000000000000000000000000000000",
505         /* Nonce */                "030000000000000000000000",
506         /* Result (16 bytes) */    "dc20e2d83f25705bb49e439eca56de25");
507 }
508 
TestAes128GcmSiv_TC02(void)509 bool TestAes128GcmSiv_TC02(void) {
510     return TestAes128GcmSiv_TC(
511         /* Plaintext (8 bytes) */  "0100000000000000",
512         /* AAD (0 bytes) */        "",
513         /* Key */                  "01000000000000000000000000000000",
514         /* Nonce */                "030000000000000000000000",
515         /* Result (24 bytes) */    "b5d839330ac7b786578782fff6013b81"
516                                    "5b287c22493a364c");
517 }
518 
TestAes128GcmSiv_TC03(void)519 bool TestAes128GcmSiv_TC03(void) {
520     return TestAes128GcmSiv_TC(
521         /* Plaintext (12 bytes) */ "010000000000000000000000",
522         /* AAD (0 bytes) */        "",
523         /* Key */                  "01000000000000000000000000000000",
524         /* Nonce */                "030000000000000000000000",
525         /* Result (28 bytes) */    "7323ea61d05932260047d942a4978db3"
526                                    "57391a0bc4fdec8b0d106639");
527 }
528 
TestAes128GcmSiv_TC04(void)529 bool TestAes128GcmSiv_TC04(void) {
530     return TestAes128GcmSiv_TC(
531         /* Plaintext (16 bytes) */ "01000000000000000000000000000000",
532         /* AAD (0 bytes) */        "",
533         /* Key */                  "01000000000000000000000000000000",
534         /* Nonce */                "030000000000000000000000",
535         /* Result (32 bytes) */    "743f7c8077ab25f8624e2e948579cf77"
536                                    "303aaf90f6fe21199c6068577437a0c4");
537 }
538 
TestAes128GcmSiv_TC05(void)539 bool TestAes128GcmSiv_TC05(void) {
540     return TestAes128GcmSiv_TC(
541         /* Plaintext (32 bytes) */ "01000000000000000000000000000000"
542                                    "02000000000000000000000000000000",
543         /* AAD (0 bytes) */        "",
544         /* Key */                  "01000000000000000000000000000000",
545         /* Nonce */                "030000000000000000000000",
546         /* Result (48 bytes) */    "84e07e62ba83a6585417245d7ec413a9"
547                                    "fe427d6315c09b57ce45f2e3936a9445"
548                                    "1a8e45dcd4578c667cd86847bf6155ff");
549 }
550 
TestAes128GcmSiv_TC06(void)551 bool TestAes128GcmSiv_TC06(void) {
552     return TestAes128GcmSiv_TC(
553         /* Plaintext (48 bytes) */ "01000000000000000000000000000000"
554                                    "02000000000000000000000000000000"
555                                    "03000000000000000000000000000000",
556         /* AAD (0 bytes) */        "",
557         /* Key */                  "01000000000000000000000000000000",
558         /* Nonce */                "030000000000000000000000",
559         /* Result (64 bytes) */    "3fd24ce1f5a67b75bf2351f181a475c7"
560                                    "b800a5b4d3dcf70106b1eea82fa1d64d"
561                                    "f42bf7226122fa92e17a40eeaac1201b"
562                                    "5e6e311dbf395d35b0fe39c2714388f8");
563 }
564 
TestAes128GcmSiv_TC07(void)565 bool TestAes128GcmSiv_TC07(void) {
566     return TestAes128GcmSiv_TC(
567         /* Plaintext (64 bytes) */ "01000000000000000000000000000000"
568                                    "02000000000000000000000000000000"
569                                    "03000000000000000000000000000000"
570                                    "04000000000000000000000000000000",
571         /* AAD (0 bytes) */        "",
572         /* Key */                  "01000000000000000000000000000000",
573         /* Nonce */                "030000000000000000000000",
574         /* Result (80 bytes) */    "2433668f1058190f6d43e360f4f35cd8"
575                                    "e475127cfca7028ea8ab5c20f7ab2af0"
576                                    "2516a2bdcbc08d521be37ff28c152bba"
577                                    "36697f25b4cd169c6590d1dd39566d3f"
578                                    "8a263dd317aa88d56bdf3936dba75bb8");
579 }
580 
TestAes128GcmSiv_TC08(void)581 bool TestAes128GcmSiv_TC08(void) {
582     return TestAes128GcmSiv_TC(
583         /* Plaintext (8 bytes) */  "0200000000000000",
584         /* AAD (1 bytes) */        "01",
585         /* Key */                  "01000000000000000000000000000000",
586         /* Nonce */                "030000000000000000000000",
587         /* Result (24 bytes) */    "1e6daba35669f4273b0a1a2560969cdf"
588                                    "790d99759abd1508");
589 }
590 
TestAes128GcmSiv_TC09(void)591 bool TestAes128GcmSiv_TC09(void) {
592     return TestAes128GcmSiv_TC(
593         /* Plaintext (12 bytes) */ "020000000000000000000000",
594         /* AAD (1 bytes) */        "01",
595         /* Key */                  "01000000000000000000000000000000",
596         /* Nonce */                "030000000000000000000000",
597         /* Result (28 bytes) */    "296c7889fd99f41917f4462008299c51"
598                                    "02745aaa3a0c469fad9e075a");
599 }
600 
TestAes128GcmSiv_TC10(void)601 bool TestAes128GcmSiv_TC10(void) {
602     return TestAes128GcmSiv_TC(
603         /* Plaintext (16 bytes) */ "02000000000000000000000000000000",
604         /* AAD (1 bytes) */        "01",
605         /* Key */                  "01000000000000000000000000000000",
606         /* Nonce */                "030000000000000000000000",
607         /* Result (32 bytes) */    "e2b0c5da79a901c1745f700525cb335b"
608                                    "8f8936ec039e4e4bb97ebd8c4457441f");
609 }
610 
TestAes128GcmSiv_TC11(void)611 bool TestAes128GcmSiv_TC11(void) {
612     return TestAes128GcmSiv_TC(
613         /* Plaintext (32 bytes) */ "02000000000000000000000000000000"
614                                    "03000000000000000000000000000000",
615         /* AAD (1 bytes) */        "01",
616         /* Key */                  "01000000000000000000000000000000",
617         /* Nonce */                "030000000000000000000000",
618         /* Result (48 bytes) */    "620048ef3c1e73e57e02bb8562c416a3"
619                                    "19e73e4caac8e96a1ecb2933145a1d71"
620                                    "e6af6a7f87287da059a71684ed3498e1");
621 }
622 
TestAes128GcmSiv_TC12(void)623 bool TestAes128GcmSiv_TC12(void) {
624     return TestAes128GcmSiv_TC(
625         /* Plaintext (48 bytes) */ "02000000000000000000000000000000"
626                                    "03000000000000000000000000000000"
627                                    "04000000000000000000000000000000",
628         /* AAD (1 bytes) */        "01",
629         /* Key */                  "01000000000000000000000000000000",
630         /* Nonce */                "030000000000000000000000",
631         /* Result (64 bytes) */    "50c8303ea93925d64090d07bd109dfd9"
632                                    "515a5a33431019c17d93465999a8b005"
633                                    "3201d723120a8562b838cdff25bf9d1e"
634                                    "6a8cc3865f76897c2e4b245cf31c51f2");
635 }
636 
TestAes128GcmSiv_TC13(void)637 bool TestAes128GcmSiv_TC13(void) {
638     return TestAes128GcmSiv_TC(
639         /* Plaintext (64 bytes) */ "02000000000000000000000000000000"
640                                    "03000000000000000000000000000000"
641                                    "04000000000000000000000000000000"
642                                    "05000000000000000000000000000000",
643         /* AAD (1 bytes) */        "01",
644         /* Key */                  "01000000000000000000000000000000",
645         /* Nonce */                "030000000000000000000000",
646         /* Result (80 bytes) */    "2f5c64059db55ee0fb847ed513003746"
647                                    "aca4e61c711b5de2e7a77ffd02da42fe"
648                                    "ec601910d3467bb8b36ebbaebce5fba3"
649                                    "0d36c95f48a3e7980f0e7ac299332a80"
650                                    "cdc46ae475563de037001ef84ae21744");
651 }
652 
TestAes128GcmSiv_TC14(void)653 bool TestAes128GcmSiv_TC14(void) {
654     return TestAes128GcmSiv_TC(
655         /* Plaintext (4 bytes) */  "02000000",
656         /* AAD (12 bytes) */       "010000000000000000000000",
657         /* Key */                  "01000000000000000000000000000000",
658         /* Nonce */                "030000000000000000000000",
659         /* Result (20 bytes) */    "a8fe3e8707eb1f84fb28f8cb73de8e99"
660                                    "e2f48a14");
661 }
662 
TestAes128GcmSiv_TC15(void)663 bool TestAes128GcmSiv_TC15(void) {
664     return TestAes128GcmSiv_TC(
665         /* Plaintext (20 bytes) */ "03000000000000000000000000000000"
666                                    "04000000",
667         /* AAD (18 bytes) */       "01000000000000000000000000000000"
668                                    "0200",
669         /* Key */                  "01000000000000000000000000000000",
670         /* Nonce */                "030000000000000000000000",
671         /* Result (36 bytes) */    "6bb0fecf5ded9b77f902c7d5da236a43"
672                                    "91dd029724afc9805e976f451e6d87f6"
673                                    "fe106514");
674 }
675 
TestAes128GcmSiv_TC16(void)676 bool TestAes128GcmSiv_TC16(void) {
677     return TestAes128GcmSiv_TC(
678         /* Plaintext (18 bytes) */ "03000000000000000000000000000000"
679                                    "0400",
680         /* AAD (20 bytes) */       "01000000000000000000000000000000"
681                                    "02000000",
682         /* Key */                  "01000000000000000000000000000000",
683         /* Nonce */                "030000000000000000000000",
684         /* Result (34 bytes) */    "44d0aaf6fb2f1f34add5e8064e83e12a"
685                                    "2adabff9b2ef00fb47920cc72a0c0f13"
686                                    "b9fd");
687 }
688 
TestAes128GcmSiv_TC17(void)689 bool TestAes128GcmSiv_TC17(void) {
690     return TestAes128GcmSiv_TC(
691         /* Plaintext (0 bytes) */  "",
692         /* AAD (0 bytes) */        "",
693         /* Key */                  "e66021d5eb8e4f4066d4adb9c33560e4",
694         /* Nonce */                "f46e44bb3da0015c94f70887",
695         /* Result (16 bytes) */    "a4194b79071b01a87d65f706e3949578");
696 }
697 
TestAes128GcmSiv_TC18(void)698 bool TestAes128GcmSiv_TC18(void) {
699     return TestAes128GcmSiv_TC(
700         /* Plaintext (3 bytes) */  "7a806c",
701         /* AAD (5 bytes) */        "46bb91c3c5",
702         /* Key */                  "36864200e0eaf5284d884a0e77d31646",
703         /* Nonce */                "bae8e37fc83441b16034566b",
704         /* Result (19 bytes) */    "af60eb711bd85bc1e4d3e0a462e074ee"
705                                    "a428a8");
706 }
707 
TestAes128GcmSiv_TC19(void)708 bool TestAes128GcmSiv_TC19(void) {
709     return TestAes128GcmSiv_TC(
710         /* Plaintext (6 bytes) */  "bdc66f146545",
711         /* AAD (10 bytes) */       "fc880c94a95198874296",
712         /* Key */                  "aedb64a6c590bc84d1a5e269e4b47801",
713         /* Nonce */                "afc0577e34699b9e671fdd4f",
714         /* Result (22 bytes) */    "bb93a3e34d3cd6a9c45545cfc11f03ad"
715                                    "743dba20f966");
716 }
717 
TestAes128GcmSiv_TC20(void)718 bool TestAes128GcmSiv_TC20(void) {
719     return TestAes128GcmSiv_TC(
720         /* Plaintext (9 bytes) */  "1177441f195495860f",
721         /* AAD (15 bytes) */       "046787f3ea22c127aaf195d1894728",
722         /* Key */                  "d5cc1fd161320b6920ce07787f86743b",
723         /* Nonce */                "275d1ab32f6d1f0434d8848c",
724         /* Result (25 bytes) */    "4f37281f7ad12949d01d02fd0cd174c8"
725                                    "4fc5dae2f60f52fd2b");
726 }
727 
TestAes128GcmSiv_TC21(void)728 bool TestAes128GcmSiv_TC21(void) {
729     return TestAes128GcmSiv_TC(
730         /* Plaintext (12 bytes) */ "9f572c614b4745914474e7c7",
731         /* AAD (20 bytes) */       "c9882e5386fd9f92ec489c8fde2be2cf"
732                                    "97e74e93",
733         /* Key */                  "b3fed1473c528b8426a582995929a149",
734         /* Nonce */                "9e9ad8780c8d63d0ab4149c0",
735         /* Result (28 bytes) */    "f54673c5ddf710c745641c8bc1dc2f87"
736                                    "1fb7561da1286e655e24b7b0");
737 }
738 
TestAes128GcmSiv_TC22(void)739 bool TestAes128GcmSiv_TC22(void) {
740     return TestAes128GcmSiv_TC(
741         /* Plaintext (15 bytes) */ "0d8c8451178082355c9e940fea2f58",
742         /* AAD (25 bytes) */       "2950a70d5a1db2316fd568378da107b5"
743                                    "2b0da55210cc1c1b0a",
744         /* Key */                  "2d4ed87da44102952ef94b02b805249b",
745         /* Nonce */                "ac80e6f61455bfac8308a2d4",
746         /* Result (31 bytes) */    "c9ff545e07b88a015f05b274540aa183"
747                                    "b3449b9f39552de99dc214a1190b0b");
748 }
749 
TestAes128GcmSiv_TC23(void)750 bool TestAes128GcmSiv_TC23(void) {
751     return TestAes128GcmSiv_TC(
752         /* Plaintext (18 bytes) */ "6b3db4da3d57aa94842b9803a96e07fb"
753                                    "6de7",
754         /* AAD (30 bytes) */       "1860f762ebfbd08284e421702de0de18"
755                                    "baa9c9596291b08466f37de21c7f",
756         /* Key */                  "bde3b2f204d1e9f8b06bc47f9745b3d1",
757         /* Nonce */                "ae06556fb6aa7890bebc18fe",
758         /* Result (34 bytes) */    "6298b296e24e8cc35dce0bed484b7f30"
759                                    "d5803e377094f04709f64d7b985310a4"
760                                    "db84");
761 }
762 
TestAes128GcmSiv_TC24(void)763 bool TestAes128GcmSiv_TC24(void) {
764     return TestAes128GcmSiv_TC(
765         /* Plaintext (21 bytes) */ "e42a3c02c25b64869e146d7b233987bd"
766                                    "dfc240871d",
767         /* AAD (35 bytes) */       "7576f7028ec6eb5ea7e298342a94d4b2"
768                                    "02b370ef9768ec6561c4fe6b7e7296fa"
769                                    "859c21",
770         /* Key */                  "f901cfe8a69615a93fdf7a98cad48179",
771         /* Nonce */                "6245709fb18853f68d833640",
772         /* Result (37 bytes) */    "391cc328d484a4f46406181bcd62efd9"
773                                    "b3ee197d052d15506c84a9edd65e13e9"
774                                    "d24a2a6e70");
775 }
776 // clang-format off
777 
778 BEGIN_TEST_CASE(AeadTest)
779 RUN_TEST(TestGetLengths_Uninitialized)
780 RUN_EACH(TestGetLengths)
781 RUN_TEST(TestInitSeal_Uninitialized)
782 RUN_EACH(TestInitSeal)
783 RUN_TEST(TestInitOpen_Uninitialized)
784 RUN_EACH(TestInitOpen)
785 RUN_EACH(TestSealData)
786 RUN_EACH(TestOpenData)
787 RUN_TEST(TestAes128Gcm_TC01)
788 RUN_TEST(TestAes128Gcm_TC02)
789 RUN_TEST(TestAes128Gcm_TC03)
790 RUN_TEST(TestAes128Gcm_TC04)
791 RUN_TEST(TestAes128Gcm_TC05)
792 RUN_TEST(TestAes128Gcm_TC06)
793 RUN_TEST(TestAes128Gcm_TC07)
794 RUN_TEST(TestAes128Gcm_TC08)
795 RUN_TEST(TestAes128Gcm_TC09)
796 RUN_TEST(TestAes128Gcm_TC10)
797 RUN_TEST(TestAes128Gcm_TC11)
798 RUN_TEST(TestAes128Gcm_TC12)
799 RUN_TEST(TestAes128Gcm_TC13)
800 RUN_TEST(TestAes128Gcm_TC14)
801 RUN_TEST(TestAes128Gcm_TC15)
802 RUN_TEST(TestAes128Gcm_TC16)
803 RUN_TEST(TestAes128Gcm_TC17)
804 RUN_TEST(TestAes128Gcm_TC18)
805 RUN_TEST(TestAes128Gcm_TC19)
806 RUN_TEST(TestAes128Gcm_TC20)
807 RUN_TEST(TestAes128Gcm_TC21)
808 RUN_TEST(TestAes128GcmSiv_TC01)
809 RUN_TEST(TestAes128GcmSiv_TC02)
810 RUN_TEST(TestAes128GcmSiv_TC03)
811 RUN_TEST(TestAes128GcmSiv_TC04)
812 RUN_TEST(TestAes128GcmSiv_TC05)
813 RUN_TEST(TestAes128GcmSiv_TC06)
814 RUN_TEST(TestAes128GcmSiv_TC07)
815 RUN_TEST(TestAes128GcmSiv_TC08)
816 RUN_TEST(TestAes128GcmSiv_TC09)
817 RUN_TEST(TestAes128GcmSiv_TC10)
818 RUN_TEST(TestAes128GcmSiv_TC11)
819 RUN_TEST(TestAes128GcmSiv_TC12)
820 RUN_TEST(TestAes128GcmSiv_TC13)
821 RUN_TEST(TestAes128GcmSiv_TC14)
822 RUN_TEST(TestAes128GcmSiv_TC15)
823 RUN_TEST(TestAes128GcmSiv_TC16)
824 RUN_TEST(TestAes128GcmSiv_TC17)
825 RUN_TEST(TestAes128GcmSiv_TC18)
826 RUN_TEST(TestAes128GcmSiv_TC19)
827 RUN_TEST(TestAes128GcmSiv_TC20)
828 RUN_TEST(TestAes128GcmSiv_TC21)
829 RUN_TEST(TestAes128GcmSiv_TC22)
830 RUN_TEST(TestAes128GcmSiv_TC23)
831 RUN_TEST(TestAes128GcmSiv_TC24)
832 END_TEST_CASE(AeadTest)
833 
834 } // namespace
835 } // namespace testing
836 } // namespace crypto
837