aes_selftest.c revision 1.7 1 1.7 msaitoh /* $NetBSD: aes_selftest.c,v 1.7 2021/12/05 04:48:35 msaitoh Exp $ */
2 1.1 riastrad
3 1.1 riastrad /*-
4 1.1 riastrad * Copyright (c) 2020 The NetBSD Foundation, Inc.
5 1.1 riastrad * All rights reserved.
6 1.1 riastrad *
7 1.1 riastrad * Redistribution and use in source and binary forms, with or without
8 1.1 riastrad * modification, are permitted provided that the following conditions
9 1.1 riastrad * are met:
10 1.1 riastrad * 1. Redistributions of source code must retain the above copyright
11 1.1 riastrad * notice, this list of conditions and the following disclaimer.
12 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 riastrad * notice, this list of conditions and the following disclaimer in the
14 1.1 riastrad * documentation and/or other materials provided with the distribution.
15 1.1 riastrad *
16 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 1.1 riastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 1.1 riastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 1.1 riastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 1.1 riastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 1.1 riastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 1.1 riastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 1.1 riastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 1.1 riastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 1.1 riastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 1.1 riastrad * POSSIBILITY OF SUCH DAMAGE.
27 1.1 riastrad */
28 1.1 riastrad
29 1.1 riastrad #include <sys/cdefs.h>
30 1.7 msaitoh __KERNEL_RCSID(1, "$NetBSD: aes_selftest.c,v 1.7 2021/12/05 04:48:35 msaitoh Exp $");
31 1.2 riastrad
32 1.2 riastrad #ifdef _KERNEL
33 1.1 riastrad
34 1.1 riastrad #include <sys/types.h>
35 1.1 riastrad #include <sys/systm.h>
36 1.1 riastrad
37 1.1 riastrad #include <lib/libkern/libkern.h>
38 1.1 riastrad
39 1.2 riastrad #else /* !_KERNEL */
40 1.2 riastrad
41 1.2 riastrad #include <stdint.h>
42 1.2 riastrad #include <stdio.h>
43 1.2 riastrad #include <string.h>
44 1.2 riastrad
45 1.2 riastrad static void
46 1.2 riastrad hexdump(int (*prf)(const char *, ...) __printflike(1,2), const char *prefix,
47 1.2 riastrad const void *buf, size_t len)
48 1.2 riastrad {
49 1.2 riastrad const uint8_t *p = buf;
50 1.2 riastrad size_t i;
51 1.2 riastrad
52 1.2 riastrad (*prf)("%s (%zu bytes)\n", prefix, len);
53 1.2 riastrad for (i = 0; i < len; i++) {
54 1.2 riastrad if (i % 16 == 8)
55 1.2 riastrad (*prf)(" ");
56 1.2 riastrad else
57 1.2 riastrad (*prf)(" ");
58 1.2 riastrad (*prf)("%02hhx", p[i]);
59 1.2 riastrad if ((i + 1) % 16 == 0)
60 1.2 riastrad (*prf)("\n");
61 1.2 riastrad }
62 1.2 riastrad if (i % 16)
63 1.2 riastrad (*prf)("\n");
64 1.2 riastrad }
65 1.2 riastrad
66 1.2 riastrad #endif /* _KERNEL */
67 1.2 riastrad
68 1.1 riastrad #include <crypto/aes/aes.h>
69 1.3 riastrad #include <crypto/aes/aes_impl.h>
70 1.1 riastrad
71 1.1 riastrad static const unsigned aes_keybytes[] __unused = { 16, 24, 32 };
72 1.1 riastrad static const unsigned aes_keybits[] __unused = { 128, 192, 256 };
73 1.1 riastrad static const unsigned aes_nrounds[] = { 10, 12, 14 };
74 1.1 riastrad
75 1.1 riastrad #define aes_selftest_fail(impl, actual, expected, nbytes, fmt, args...) \
76 1.1 riastrad ({ \
77 1.1 riastrad printf("%s "fmt": self-test failed\n", (impl)->ai_name, ##args); \
78 1.1 riastrad hexdump(printf, "was", (actual), (nbytes)); \
79 1.1 riastrad hexdump(printf, "expected", (expected), (nbytes)); \
80 1.1 riastrad -1; \
81 1.1 riastrad })
82 1.1 riastrad
83 1.1 riastrad static int
84 1.1 riastrad aes_selftest_encdec(const struct aes_impl *impl)
85 1.1 riastrad {
86 1.1 riastrad /*
87 1.1 riastrad * head -c 16 < /dev/zero | openssl enc -aes-{128,192,256}-ecb
88 1.1 riastrad * -nopad -K 000102030405060708090a0b0c0d... | hexdump -C
89 1.1 riastrad */
90 1.1 riastrad static const uint8_t expected[3][16] = {
91 1.1 riastrad [0] = {
92 1.1 riastrad 0xc6,0xa1,0x3b,0x37,0x87,0x8f,0x5b,0x82,
93 1.1 riastrad 0x6f,0x4f,0x81,0x62,0xa1,0xc8,0xd8,0x79,
94 1.1 riastrad },
95 1.1 riastrad [1] = {
96 1.1 riastrad 0x91,0x62,0x51,0x82,0x1c,0x73,0xa5,0x22,
97 1.1 riastrad 0xc3,0x96,0xd6,0x27,0x38,0x01,0x96,0x07,
98 1.1 riastrad },
99 1.1 riastrad [2] = {
100 1.1 riastrad 0xf2,0x90,0x00,0xb6,0x2a,0x49,0x9f,0xd0,
101 1.1 riastrad 0xa9,0xf3,0x9a,0x6a,0xdd,0x2e,0x77,0x80,
102 1.1 riastrad },
103 1.1 riastrad };
104 1.1 riastrad struct aesenc enc;
105 1.1 riastrad struct aesdec dec;
106 1.1 riastrad uint8_t key[32];
107 1.1 riastrad uint8_t in[16];
108 1.1 riastrad uint8_t outbuf[18] = { [0] = 0x1a, [17] = 0x1a }, *out = outbuf + 1;
109 1.1 riastrad unsigned i;
110 1.1 riastrad
111 1.1 riastrad for (i = 0; i < 32; i++)
112 1.1 riastrad key[i] = i;
113 1.1 riastrad for (i = 0; i < 16; i++)
114 1.1 riastrad in[i] = 0;
115 1.1 riastrad
116 1.1 riastrad for (i = 0; i < 3; i++) {
117 1.1 riastrad impl->ai_setenckey(&enc, key, aes_nrounds[i]);
118 1.1 riastrad impl->ai_setdeckey(&dec, key, aes_nrounds[i]);
119 1.1 riastrad impl->ai_enc(&enc, in, out, aes_nrounds[i]);
120 1.1 riastrad if (memcmp(out, expected[i], 16))
121 1.1 riastrad return aes_selftest_fail(impl, out, expected[i], 16,
122 1.1 riastrad "AES-%u enc", aes_keybits[i]);
123 1.1 riastrad impl->ai_dec(&dec, out, out, aes_nrounds[i]);
124 1.1 riastrad if (memcmp(out, in, 16))
125 1.1 riastrad return aes_selftest_fail(impl, out, in, 16,
126 1.1 riastrad "AES-%u dec", aes_keybits[i]);
127 1.1 riastrad }
128 1.1 riastrad
129 1.1 riastrad if (outbuf[0] != 0x1a)
130 1.1 riastrad return aes_selftest_fail(impl, outbuf,
131 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
132 1.1 riastrad "AES overrun preceding");
133 1.1 riastrad if (outbuf[17] != 0x1a)
134 1.1 riastrad return aes_selftest_fail(impl, outbuf + 17,
135 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
136 1.7 msaitoh "AES overrun following");
137 1.1 riastrad
138 1.1 riastrad /* Success! */
139 1.1 riastrad return 0;
140 1.1 riastrad }
141 1.1 riastrad
142 1.1 riastrad static int
143 1.1 riastrad aes_selftest_encdec_cbc(const struct aes_impl *impl)
144 1.1 riastrad {
145 1.1 riastrad static const uint8_t expected[3][144] = {
146 1.1 riastrad [0] = {
147 1.1 riastrad 0xfe,0xf1,0xa8,0xb6,0x25,0xf0,0xc4,0x3a,
148 1.1 riastrad 0x71,0x08,0xb6,0x23,0xa6,0xfb,0x90,0xca,
149 1.1 riastrad 0x9e,0x64,0x6d,0x95,0xb5,0xf5,0x41,0x24,
150 1.1 riastrad 0xd2,0xe6,0x60,0xda,0x6c,0x69,0xc4,0xa0,
151 1.1 riastrad 0x4d,0xaa,0x94,0xf6,0x66,0x1e,0xaa,0x85,
152 1.1 riastrad 0x68,0xc5,0x6b,0x2e,0x77,0x7a,0x68,0xff,
153 1.1 riastrad 0x45,0x15,0x45,0xc5,0x9c,0xbb,0x3a,0x23,
154 1.1 riastrad 0x08,0x3a,0x06,0xdd,0xc0,0x52,0xd2,0xb7,
155 1.1 riastrad 0x47,0xaa,0x1c,0xc7,0xb5,0xa9,0x7d,0x04,
156 1.1 riastrad 0x60,0x67,0x78,0xf6,0xb9,0xba,0x26,0x84,
157 1.1 riastrad 0x45,0x72,0x44,0xed,0xa3,0xd3,0xa0,0x3f,
158 1.1 riastrad 0x19,0xee,0x3f,0x94,0x59,0x52,0x4b,0x13,
159 1.1 riastrad 0xfd,0x81,0xcc,0xf9,0xf2,0x29,0xd7,0xec,
160 1.1 riastrad 0xde,0x03,0x56,0x01,0x4a,0x19,0x86,0xc0,
161 1.1 riastrad 0x87,0xce,0xe1,0xcc,0x13,0xf1,0x2e,0xda,
162 1.1 riastrad 0x3f,0xfe,0xa4,0x64,0xe7,0x48,0xb4,0x7b,
163 1.1 riastrad 0x73,0x62,0x5a,0x80,0x5e,0x01,0x20,0xa5,
164 1.1 riastrad 0x0a,0xd7,0x98,0xa7,0xd9,0x8b,0xff,0xc2,
165 1.1 riastrad },
166 1.1 riastrad [1] = {
167 1.1 riastrad 0xa6,0x87,0xf0,0x92,0x68,0xc8,0xd6,0x42,
168 1.1 riastrad 0xa8,0x83,0x1c,0x92,0x65,0x8c,0xd9,0xfe,
169 1.1 riastrad 0x0b,0x1a,0xc6,0x96,0x27,0x44,0xd4,0x14,
170 1.1 riastrad 0xfc,0xe7,0x85,0xb2,0x71,0xc7,0x11,0x39,
171 1.1 riastrad 0xed,0x36,0xd3,0x5c,0xa7,0xf7,0x3d,0xc9,
172 1.1 riastrad 0xa2,0x54,0x8b,0xb4,0xfa,0xe8,0x21,0xf9,
173 1.1 riastrad 0xfd,0x6a,0x42,0x85,0xde,0x66,0xd4,0xc0,
174 1.1 riastrad 0xa7,0xd3,0x5b,0xe1,0xe6,0xac,0xea,0xf9,
175 1.1 riastrad 0xa3,0x15,0x68,0xf4,0x66,0x4c,0x23,0x75,
176 1.1 riastrad 0x58,0xba,0x7f,0xca,0xbf,0x40,0x56,0x79,
177 1.1 riastrad 0x2f,0xbf,0xdf,0x5f,0x56,0xcb,0xa0,0xe4,
178 1.1 riastrad 0x22,0x65,0x6a,0x8f,0x4f,0xff,0x11,0x6b,
179 1.1 riastrad 0x57,0xeb,0x45,0xeb,0x9d,0x7f,0xfe,0x9c,
180 1.1 riastrad 0x8b,0x30,0xa8,0xb0,0x7e,0x27,0xf8,0xbc,
181 1.1 riastrad 0x1f,0xf8,0x15,0x34,0x36,0x4f,0x46,0x73,
182 1.1 riastrad 0x81,0x90,0x4b,0x4b,0x46,0x4d,0x01,0x45,
183 1.1 riastrad 0xa1,0xc3,0x0b,0xa8,0x5a,0xab,0xc1,0x88,
184 1.1 riastrad 0x66,0xc8,0x1a,0x94,0x17,0x64,0x6f,0xf4,
185 1.1 riastrad },
186 1.1 riastrad [2] = {
187 1.1 riastrad 0x22,0x4c,0x27,0xf4,0xba,0x37,0x8b,0x27,
188 1.1 riastrad 0xd3,0xd6,0x88,0x8a,0xdc,0xed,0x64,0x42,
189 1.1 riastrad 0x19,0x60,0x31,0x09,0xf3,0x72,0xd2,0xc2,
190 1.1 riastrad 0xd3,0xe3,0xff,0xce,0xc5,0x03,0x9f,0xce,
191 1.1 riastrad 0x99,0x49,0x8a,0xf2,0xe1,0xba,0xe2,0xa8,
192 1.1 riastrad 0xd7,0x32,0x07,0x2d,0xb0,0xb3,0xbc,0x67,
193 1.1 riastrad 0x32,0x9a,0x3e,0x7d,0x16,0x23,0xe7,0x24,
194 1.1 riastrad 0x84,0xe1,0x15,0x03,0x9c,0xa2,0x7a,0x95,
195 1.1 riastrad 0x34,0xa8,0x04,0x4e,0x79,0x31,0x50,0x26,
196 1.1 riastrad 0x76,0xd1,0x10,0xce,0xec,0x13,0xf7,0xfb,
197 1.1 riastrad 0x94,0x6b,0x76,0x50,0x5f,0xb2,0x3e,0x7c,
198 1.1 riastrad 0xbe,0x97,0xe7,0x13,0x06,0x9e,0x2d,0xc4,
199 1.1 riastrad 0x46,0x65,0xa7,0x69,0x37,0x07,0x25,0x37,
200 1.1 riastrad 0xe5,0x48,0x51,0xa8,0x58,0xe8,0x4d,0x7c,
201 1.1 riastrad 0xb5,0xbe,0x25,0x13,0xbc,0x11,0xc2,0xde,
202 1.1 riastrad 0xdb,0x00,0xef,0x1c,0x1d,0xeb,0xe3,0x49,
203 1.1 riastrad 0x1c,0xc0,0x78,0x29,0x76,0xc0,0xde,0x3a,
204 1.1 riastrad 0x0e,0x96,0x8f,0xea,0xd7,0x42,0x4e,0xb4,
205 1.1 riastrad },
206 1.1 riastrad };
207 1.1 riastrad struct aesenc enc;
208 1.1 riastrad struct aesdec dec;
209 1.1 riastrad uint8_t key[32];
210 1.1 riastrad uint8_t in[144];
211 1.1 riastrad uint8_t outbuf[146] = { [0] = 0x1a, [145] = 0x1a }, *out = outbuf + 1;
212 1.1 riastrad uint8_t iv0[16], iv[16];
213 1.6 riastrad unsigned i, j;
214 1.1 riastrad
215 1.1 riastrad for (i = 0; i < 32; i++)
216 1.1 riastrad key[i] = i;
217 1.1 riastrad for (i = 0; i < 16; i++)
218 1.1 riastrad iv0[i] = 0x20 ^ i;
219 1.1 riastrad for (i = 0; i < 144; i++)
220 1.1 riastrad in[i] = 0x80 ^ i;
221 1.1 riastrad
222 1.1 riastrad for (i = 0; i < 3; i++) {
223 1.1 riastrad impl->ai_setenckey(&enc, key, aes_nrounds[i]);
224 1.1 riastrad impl->ai_setdeckey(&dec, key, aes_nrounds[i]);
225 1.1 riastrad
226 1.1 riastrad /* Try one swell foop. */
227 1.1 riastrad memcpy(iv, iv0, 16);
228 1.1 riastrad impl->ai_cbc_enc(&enc, in, out, 144, iv, aes_nrounds[i]);
229 1.1 riastrad if (memcmp(out, expected[i], 144))
230 1.1 riastrad return aes_selftest_fail(impl, out, expected[i], 144,
231 1.1 riastrad "AES-%u-CBC enc", aes_keybits[i]);
232 1.1 riastrad
233 1.1 riastrad memcpy(iv, iv0, 16);
234 1.1 riastrad impl->ai_cbc_dec(&dec, out, out, 144, iv, aes_nrounds[i]);
235 1.1 riastrad if (memcmp(out, in, 144))
236 1.1 riastrad return aes_selftest_fail(impl, out, in, 144,
237 1.1 riastrad "AES-%u-CBC dec", aes_keybits[i]);
238 1.1 riastrad
239 1.1 riastrad /* Try incrementally, with IV update. */
240 1.6 riastrad for (j = 0; j < 144; j += 16) {
241 1.6 riastrad memcpy(iv, iv0, 16);
242 1.6 riastrad impl->ai_cbc_enc(&enc, in, out, j, iv, aes_nrounds[i]);
243 1.6 riastrad impl->ai_cbc_enc(&enc, in + j, out + j, 144 - j, iv,
244 1.6 riastrad aes_nrounds[i]);
245 1.6 riastrad if (memcmp(out, expected[i], 144))
246 1.6 riastrad return aes_selftest_fail(impl, out,
247 1.6 riastrad expected[i], 144, "AES-%u-CBC enc inc %u",
248 1.6 riastrad aes_keybits[i], j);
249 1.6 riastrad
250 1.6 riastrad memcpy(iv, iv0, 16);
251 1.6 riastrad impl->ai_cbc_dec(&dec, out, out, j, iv,
252 1.6 riastrad aes_nrounds[i]);
253 1.6 riastrad impl->ai_cbc_dec(&dec, out + j, out + j, 144 - j, iv,
254 1.6 riastrad aes_nrounds[i]);
255 1.6 riastrad if (memcmp(out, in, 144))
256 1.6 riastrad return aes_selftest_fail(impl, out,
257 1.6 riastrad in, 144, "AES-%u-CBC dec inc %u",
258 1.6 riastrad aes_keybits[i], j);
259 1.6 riastrad }
260 1.1 riastrad }
261 1.1 riastrad
262 1.1 riastrad if (outbuf[0] != 0x1a)
263 1.1 riastrad return aes_selftest_fail(impl, outbuf,
264 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
265 1.1 riastrad "AES-CBC overrun preceding");
266 1.1 riastrad if (outbuf[145] != 0x1a)
267 1.1 riastrad return aes_selftest_fail(impl, outbuf + 145,
268 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
269 1.1 riastrad "AES-CBC overrun following");
270 1.1 riastrad
271 1.1 riastrad /* Success! */
272 1.1 riastrad return 0;
273 1.1 riastrad }
274 1.1 riastrad
275 1.1 riastrad static int
276 1.1 riastrad aes_selftest_encdec_xts(const struct aes_impl *impl)
277 1.1 riastrad {
278 1.1 riastrad uint64_t blkno[3] = { 0, 1, 0xff };
279 1.1 riastrad static const uint8_t expected[3][144] = {
280 1.1 riastrad [0] = {
281 1.1 riastrad /* IEEE P1619-D16, XTS-AES-128, Vector 4, truncated */
282 1.1 riastrad 0x27,0xa7,0x47,0x9b,0xef,0xa1,0xd4,0x76,
283 1.1 riastrad 0x48,0x9f,0x30,0x8c,0xd4,0xcf,0xa6,0xe2,
284 1.1 riastrad 0xa9,0x6e,0x4b,0xbe,0x32,0x08,0xff,0x25,
285 1.1 riastrad 0x28,0x7d,0xd3,0x81,0x96,0x16,0xe8,0x9c,
286 1.1 riastrad 0xc7,0x8c,0xf7,0xf5,0xe5,0x43,0x44,0x5f,
287 1.1 riastrad 0x83,0x33,0xd8,0xfa,0x7f,0x56,0x00,0x00,
288 1.1 riastrad 0x05,0x27,0x9f,0xa5,0xd8,0xb5,0xe4,0xad,
289 1.1 riastrad 0x40,0xe7,0x36,0xdd,0xb4,0xd3,0x54,0x12,
290 1.1 riastrad 0x32,0x80,0x63,0xfd,0x2a,0xab,0x53,0xe5,
291 1.1 riastrad 0xea,0x1e,0x0a,0x9f,0x33,0x25,0x00,0xa5,
292 1.1 riastrad 0xdf,0x94,0x87,0xd0,0x7a,0x5c,0x92,0xcc,
293 1.1 riastrad 0x51,0x2c,0x88,0x66,0xc7,0xe8,0x60,0xce,
294 1.1 riastrad 0x93,0xfd,0xf1,0x66,0xa2,0x49,0x12,0xb4,
295 1.1 riastrad 0x22,0x97,0x61,0x46,0xae,0x20,0xce,0x84,
296 1.1 riastrad 0x6b,0xb7,0xdc,0x9b,0xa9,0x4a,0x76,0x7a,
297 1.1 riastrad 0xae,0xf2,0x0c,0x0d,0x61,0xad,0x02,0x65,
298 1.1 riastrad 0x5e,0xa9,0x2d,0xc4,0xc4,0xe4,0x1a,0x89,
299 1.1 riastrad 0x52,0xc6,0x51,0xd3,0x31,0x74,0xbe,0x51,
300 1.1 riastrad },
301 1.1 riastrad [1] = {
302 1.1 riastrad },
303 1.1 riastrad [2] = {
304 1.1 riastrad /* IEEE P1619-D16, XTS-AES-256, Vector 10, truncated */
305 1.1 riastrad 0x1c,0x3b,0x3a,0x10,0x2f,0x77,0x03,0x86,
306 1.1 riastrad 0xe4,0x83,0x6c,0x99,0xe3,0x70,0xcf,0x9b,
307 1.1 riastrad 0xea,0x00,0x80,0x3f,0x5e,0x48,0x23,0x57,
308 1.1 riastrad 0xa4,0xae,0x12,0xd4,0x14,0xa3,0xe6,0x3b,
309 1.1 riastrad 0x5d,0x31,0xe2,0x76,0xf8,0xfe,0x4a,0x8d,
310 1.1 riastrad 0x66,0xb3,0x17,0xf9,0xac,0x68,0x3f,0x44,
311 1.1 riastrad 0x68,0x0a,0x86,0xac,0x35,0xad,0xfc,0x33,
312 1.1 riastrad 0x45,0xbe,0xfe,0xcb,0x4b,0xb1,0x88,0xfd,
313 1.1 riastrad 0x57,0x76,0x92,0x6c,0x49,0xa3,0x09,0x5e,
314 1.1 riastrad 0xb1,0x08,0xfd,0x10,0x98,0xba,0xec,0x70,
315 1.1 riastrad 0xaa,0xa6,0x69,0x99,0xa7,0x2a,0x82,0xf2,
316 1.1 riastrad 0x7d,0x84,0x8b,0x21,0xd4,0xa7,0x41,0xb0,
317 1.1 riastrad 0xc5,0xcd,0x4d,0x5f,0xff,0x9d,0xac,0x89,
318 1.1 riastrad 0xae,0xba,0x12,0x29,0x61,0xd0,0x3a,0x75,
319 1.1 riastrad 0x71,0x23,0xe9,0x87,0x0f,0x8a,0xcf,0x10,
320 1.1 riastrad 0x00,0x02,0x08,0x87,0x89,0x14,0x29,0xca,
321 1.1 riastrad 0x2a,0x3e,0x7a,0x7d,0x7d,0xf7,0xb1,0x03,
322 1.1 riastrad 0x55,0x16,0x5c,0x8b,0x9a,0x6d,0x0a,0x7d,
323 1.1 riastrad },
324 1.1 riastrad };
325 1.1 riastrad static const uint8_t key1[32] = {
326 1.1 riastrad 0x27,0x18,0x28,0x18,0x28,0x45,0x90,0x45,
327 1.1 riastrad 0x23,0x53,0x60,0x28,0x74,0x71,0x35,0x26,
328 1.1 riastrad 0x62,0x49,0x77,0x57,0x24,0x70,0x93,0x69,
329 1.1 riastrad 0x99,0x59,0x57,0x49,0x66,0x96,0x76,0x27,
330 1.1 riastrad };
331 1.1 riastrad static const uint8_t key2[32] = {
332 1.1 riastrad 0x31,0x41,0x59,0x26,0x53,0x58,0x97,0x93,
333 1.1 riastrad 0x23,0x84,0x62,0x64,0x33,0x83,0x27,0x95,
334 1.1 riastrad 0x02,0x88,0x41,0x97,0x16,0x93,0x99,0x37,
335 1.1 riastrad 0x51,0x05,0x82,0x09,0x74,0x94,0x45,0x92,
336 1.1 riastrad };
337 1.1 riastrad struct aesenc enc;
338 1.1 riastrad struct aesdec dec;
339 1.1 riastrad uint8_t in[144];
340 1.1 riastrad uint8_t outbuf[146] = { [0] = 0x1a, [145] = 0x1a }, *out = outbuf + 1;
341 1.1 riastrad uint8_t blkno_buf[16];
342 1.1 riastrad uint8_t iv0[16], iv[16];
343 1.1 riastrad unsigned i;
344 1.1 riastrad
345 1.1 riastrad for (i = 0; i < 144; i++)
346 1.1 riastrad in[i] = i;
347 1.1 riastrad
348 1.1 riastrad for (i = 0; i < 3; i++) {
349 1.1 riastrad if (i == 1) /* XXX missing AES-192 test vector */
350 1.1 riastrad continue;
351 1.1 riastrad
352 1.1 riastrad /* Format the data unit sequence number. */
353 1.1 riastrad memset(blkno_buf, 0, sizeof blkno_buf);
354 1.1 riastrad le64enc(blkno_buf, blkno[i]);
355 1.1 riastrad
356 1.1 riastrad /* Generate the tweak. */
357 1.1 riastrad impl->ai_setenckey(&enc, key2, aes_nrounds[i]);
358 1.1 riastrad impl->ai_enc(&enc, blkno_buf, iv0, aes_nrounds[i]);
359 1.1 riastrad
360 1.1 riastrad /* Load the data encryption key. */
361 1.1 riastrad impl->ai_setenckey(&enc, key1, aes_nrounds[i]);
362 1.1 riastrad impl->ai_setdeckey(&dec, key1, aes_nrounds[i]);
363 1.1 riastrad
364 1.1 riastrad /* Try one swell foop. */
365 1.1 riastrad memcpy(iv, iv0, 16);
366 1.1 riastrad impl->ai_xts_enc(&enc, in, out, 144, iv, aes_nrounds[i]);
367 1.1 riastrad if (memcmp(out, expected[i], 144))
368 1.1 riastrad return aes_selftest_fail(impl, out, expected[i], 144,
369 1.1 riastrad "AES-%u-XTS enc", aes_keybits[i]);
370 1.1 riastrad
371 1.1 riastrad memcpy(iv, iv0, 16);
372 1.1 riastrad impl->ai_xts_dec(&dec, out, out, 144, iv, aes_nrounds[i]);
373 1.1 riastrad if (memcmp(out, in, 144))
374 1.1 riastrad return aes_selftest_fail(impl, out, in, 144,
375 1.1 riastrad "AES-%u-XTS dec", aes_keybits[i]);
376 1.1 riastrad
377 1.1 riastrad /* Try incrementally, with IV update. */
378 1.1 riastrad memcpy(iv, iv0, 16);
379 1.1 riastrad impl->ai_xts_enc(&enc, in, out, 16, iv, aes_nrounds[i]);
380 1.1 riastrad impl->ai_xts_enc(&enc, in + 16, out + 16, 128, iv,
381 1.1 riastrad aes_nrounds[i]);
382 1.1 riastrad if (memcmp(out, expected[i], 144))
383 1.1 riastrad return aes_selftest_fail(impl, out, expected[i], 144,
384 1.1 riastrad "AES-%u-XTS enc incremental", aes_keybits[i]);
385 1.1 riastrad
386 1.1 riastrad memcpy(iv, iv0, 16);
387 1.1 riastrad impl->ai_xts_dec(&dec, out, out, 128, iv, aes_nrounds[i]);
388 1.1 riastrad impl->ai_xts_dec(&dec, out + 128, out + 128, 16, iv,
389 1.1 riastrad aes_nrounds[i]);
390 1.1 riastrad if (memcmp(out, in, 144))
391 1.1 riastrad return aes_selftest_fail(impl, out, in, 144,
392 1.1 riastrad "AES-%u-XTS dec incremental", aes_keybits[i]);
393 1.1 riastrad }
394 1.1 riastrad
395 1.1 riastrad if (outbuf[0] != 0x1a)
396 1.1 riastrad return aes_selftest_fail(impl, outbuf,
397 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
398 1.1 riastrad "AES-XTS overrun preceding");
399 1.1 riastrad if (outbuf[145] != 0x1a)
400 1.1 riastrad return aes_selftest_fail(impl, outbuf + 145,
401 1.1 riastrad (const uint8_t[1]){0x1a}, 1,
402 1.1 riastrad "AES-XTS overrun following");
403 1.1 riastrad
404 1.1 riastrad /* Success! */
405 1.1 riastrad return 0;
406 1.1 riastrad }
407 1.1 riastrad
408 1.4 riastrad static int
409 1.4 riastrad aes_selftest_cbcmac(const struct aes_impl *impl)
410 1.4 riastrad {
411 1.4 riastrad static const uint8_t m[48] = {
412 1.4 riastrad 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
413 1.4 riastrad 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
414 1.4 riastrad 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
415 1.4 riastrad 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
416 1.4 riastrad 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
417 1.4 riastrad 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,
418 1.4 riastrad };
419 1.4 riastrad static uint8_t auth16[16] = {
420 1.4 riastrad 0x7a,0xca,0x0f,0xd9, 0xbc,0xd6,0xec,0x7c,
421 1.4 riastrad 0x9f,0x97,0x46,0x66, 0x16,0xe6,0xa2,0x82,
422 1.4 riastrad };
423 1.4 riastrad static uint8_t auth48[16] = {
424 1.4 riastrad 0x26,0x9a,0xe5,0xfc, 0x8c,0x53,0x0f,0xf7,
425 1.4 riastrad 0x6b,0xd9,0xec,0x05, 0x40,0xf7,0x35,0x13,
426 1.4 riastrad };
427 1.4 riastrad static const uint8_t key[16];
428 1.4 riastrad struct aesenc enc;
429 1.4 riastrad uint8_t auth[16];
430 1.4 riastrad const unsigned nr = AES_128_NROUNDS;
431 1.4 riastrad
432 1.4 riastrad memset(auth, 0, sizeof auth);
433 1.4 riastrad
434 1.4 riastrad impl->ai_setenckey(&enc, key, nr);
435 1.4 riastrad impl->ai_cbcmac_update1(&enc, m, 16, auth, nr);
436 1.4 riastrad if (memcmp(auth, auth16, 16))
437 1.4 riastrad return aes_selftest_fail(impl, auth, auth16, 16,
438 1.4 riastrad "AES-128 CBC-MAC (16)");
439 1.4 riastrad impl->ai_cbcmac_update1(&enc, m + 16, 32, auth, nr);
440 1.4 riastrad if (memcmp(auth, auth48, 16))
441 1.4 riastrad return aes_selftest_fail(impl, auth, auth48, 16,
442 1.4 riastrad "AES-128 CBC-MAC (48)");
443 1.4 riastrad
444 1.4 riastrad return 0;
445 1.4 riastrad }
446 1.4 riastrad
447 1.4 riastrad static int
448 1.4 riastrad aes_selftest_ccm(const struct aes_impl *impl)
449 1.4 riastrad {
450 1.4 riastrad static const uint8_t ptxt[48] = {
451 1.4 riastrad 0x00,0x01,0x02,0x03, 0x04,0x05,0x06,0x07,
452 1.4 riastrad 0x08,0x09,0x0a,0x0b, 0x0c,0x0d,0x0e,0x0f,
453 1.4 riastrad 0x10,0x11,0x12,0x13, 0x14,0x15,0x16,0x17,
454 1.4 riastrad 0x18,0x19,0x1a,0x1b, 0x1c,0x1d,0x1e,0x1f,
455 1.4 riastrad 0x20,0x21,0x22,0x23, 0x24,0x25,0x26,0x27,
456 1.4 riastrad 0x28,0x29,0x2a,0x2b, 0x2c,0x2d,0x2e,0x2f,
457 1.4 riastrad };
458 1.4 riastrad static uint8_t ctr0[16] = {
459 1.4 riastrad /* L - 1, #octets in counter */
460 1.4 riastrad [0] = 0x01,
461 1.4 riastrad /* nonce */
462 1.4 riastrad [1] = 0,1,2,3,4,5,6,7,8,9,10,11,12,
463 1.4 riastrad [14] = 0,
464 1.4 riastrad [15] = 254,
465 1.4 riastrad };
466 1.4 riastrad static uint8_t authctr16[32] = {
467 1.4 riastrad /* authentication tag */
468 1.4 riastrad 0x7a,0xca,0x0f,0xd9, 0xbc,0xd6,0xec,0x7c,
469 1.4 riastrad 0x9f,0x97,0x46,0x66, 0x16,0xe6,0xa2,0x82,
470 1.4 riastrad
471 1.4 riastrad /* L - 1, #octets in counter */
472 1.4 riastrad [16 + 0] = 0x01,
473 1.4 riastrad /* nonce */
474 1.4 riastrad [16 + 1] = 0,1,2,3,4,5,6,7,8,9,10,11,12,
475 1.4 riastrad [16 + 14] = 0,
476 1.4 riastrad [16 + 15] = 255,
477 1.4 riastrad };
478 1.4 riastrad static uint8_t authctr48[32] = {
479 1.4 riastrad /* authentication tag */
480 1.4 riastrad 0x26,0x9a,0xe5,0xfc, 0x8c,0x53,0x0f,0xf7,
481 1.4 riastrad 0x6b,0xd9,0xec,0x05, 0x40,0xf7,0x35,0x13,
482 1.4 riastrad
483 1.4 riastrad /* L - 1, #octets in counter */
484 1.4 riastrad [16 + 0] = 0x01,
485 1.4 riastrad /* nonce */
486 1.4 riastrad [16 + 1] = 0,1,2,3,4,5,6,7,8,9,10,11,12,
487 1.4 riastrad [16 + 14] = 1,
488 1.4 riastrad [16 + 15] = 1,
489 1.4 riastrad };
490 1.4 riastrad static uint8_t ctxt[48] = {
491 1.4 riastrad 0xa4,0x35,0x07,0x5c, 0xdf,0x2d,0x67,0xd3,
492 1.4 riastrad 0xbf,0x1f,0x36,0x93, 0xe4,0x43,0xcb,0x1e,
493 1.4 riastrad 0xa0,0x82,0x9c,0x2a, 0x0b,0x66,0x46,0x05,
494 1.4 riastrad 0x80,0x17,0x71,0xa1, 0x7b,0x09,0xa7,0xd5,
495 1.4 riastrad 0x91,0x0b,0xb3,0x96, 0xd1,0x5e,0x29,0x3e,
496 1.4 riastrad 0x74,0x94,0x74,0x6d, 0x6b,0x25,0x43,0x8c,
497 1.4 riastrad };
498 1.4 riastrad static const uint8_t key[16];
499 1.4 riastrad struct aesenc enc;
500 1.4 riastrad uint8_t authctr[32];
501 1.4 riastrad uint8_t buf[48];
502 1.4 riastrad const unsigned nr = AES_128_NROUNDS;
503 1.4 riastrad int result = 0;
504 1.4 riastrad
505 1.4 riastrad impl->ai_setenckey(&enc, key, nr);
506 1.4 riastrad
507 1.4 riastrad memset(authctr, 0, 16);
508 1.4 riastrad memcpy(authctr + 16, ctr0, 16);
509 1.4 riastrad
510 1.4 riastrad impl->ai_ccm_enc1(&enc, ptxt, buf, 16, authctr, nr);
511 1.4 riastrad if (memcmp(authctr, authctr16, 32))
512 1.4 riastrad result |= aes_selftest_fail(impl, authctr, authctr16, 32,
513 1.4 riastrad "AES-128 CCM encrypt auth/ctr (16)");
514 1.4 riastrad impl->ai_ccm_enc1(&enc, ptxt + 16, buf + 16, 32, authctr, nr);
515 1.4 riastrad if (memcmp(authctr, authctr48, 32))
516 1.4 riastrad result |= aes_selftest_fail(impl, authctr, authctr48, 32,
517 1.4 riastrad "AES-128 CCM encrypt auth/ctr (48)");
518 1.4 riastrad
519 1.4 riastrad if (memcmp(buf, ctxt, 32))
520 1.4 riastrad result |= aes_selftest_fail(impl, buf, ctxt, 48,
521 1.4 riastrad "AES-128 CCM ciphertext");
522 1.4 riastrad
523 1.4 riastrad memset(authctr, 0, 16);
524 1.4 riastrad memcpy(authctr + 16, ctr0, 16);
525 1.4 riastrad
526 1.4 riastrad impl->ai_ccm_dec1(&enc, ctxt, buf, 16, authctr, nr);
527 1.4 riastrad if (memcmp(authctr, authctr16, 32))
528 1.4 riastrad result |= aes_selftest_fail(impl, authctr, authctr16, 32,
529 1.4 riastrad "AES-128 CCM decrypt auth/ctr (16)");
530 1.4 riastrad impl->ai_ccm_dec1(&enc, ctxt + 16, buf + 16, 32, authctr, nr);
531 1.4 riastrad if (memcmp(authctr, authctr48, 32))
532 1.4 riastrad result |= aes_selftest_fail(impl, authctr, authctr48, 32,
533 1.4 riastrad "AES-128 CCM decrypt auth/ctr (48)");
534 1.4 riastrad
535 1.4 riastrad if (memcmp(buf, ptxt, 32))
536 1.4 riastrad result |= aes_selftest_fail(impl, buf, ptxt, 48,
537 1.4 riastrad "AES-128 CCM plaintext");
538 1.4 riastrad
539 1.4 riastrad return result;
540 1.4 riastrad }
541 1.4 riastrad
542 1.1 riastrad int
543 1.1 riastrad aes_selftest(const struct aes_impl *impl)
544 1.1 riastrad {
545 1.1 riastrad int result = 0;
546 1.1 riastrad
547 1.1 riastrad if (impl->ai_probe())
548 1.1 riastrad return -1;
549 1.1 riastrad
550 1.1 riastrad if (aes_selftest_encdec(impl))
551 1.1 riastrad result = -1;
552 1.1 riastrad if (aes_selftest_encdec_cbc(impl))
553 1.1 riastrad result = -1;
554 1.1 riastrad if (aes_selftest_encdec_xts(impl))
555 1.1 riastrad result = -1;
556 1.4 riastrad if (aes_selftest_cbcmac(impl))
557 1.4 riastrad result = -1;
558 1.4 riastrad if (aes_selftest_ccm(impl))
559 1.4 riastrad result = -1;
560 1.1 riastrad
561 1.1 riastrad return result;
562 1.1 riastrad }
563