aes_impl.c revision 1.2 1 /* $NetBSD: aes_impl.c,v 1.2 2020/06/29 23:36:59 riastradh Exp $ */
2
3 /*-
4 * Copyright (c) 2020 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(1, "$NetBSD: aes_impl.c,v 1.2 2020/06/29 23:36:59 riastradh Exp $");
31
32 #include <sys/types.h>
33 #include <sys/kernel.h>
34 #include <sys/module.h>
35 #include <sys/once.h>
36 #include <sys/systm.h>
37
38 #include <crypto/aes/aes.h>
39 #include <crypto/aes/aes_bear.h> /* default implementation */
40
41 static int aes_selftest_stdkeysched(void);
42
43 static const struct aes_impl *aes_md_impl __read_mostly;
44 static const struct aes_impl *aes_impl __read_mostly;
45
46 /*
47 * The timing of AES implementation selection is finicky:
48 *
49 * 1. It has to be done _after_ cpu_attach for implementations,
50 * such as AES-NI, that rely on fpu initialization done by
51 * fpu_attach.
52 *
53 * 2. It has to be done _before_ the cgd self-tests or anything
54 * else that might call AES.
55 *
56 * For the moment, doing it in module init works. However, if a
57 * driver-class module depended on the aes module, that would break.
58 */
59
60 static int
61 aes_select(void)
62 {
63
64 KASSERT(aes_impl == NULL);
65
66 if (aes_selftest_stdkeysched())
67 panic("AES is busted");
68
69 if (aes_md_impl) {
70 if (aes_selftest(aes_md_impl))
71 aprint_error("aes: self-test failed: %s\n",
72 aes_md_impl->ai_name);
73 else
74 aes_impl = aes_md_impl;
75 }
76 if (aes_impl == NULL) {
77 if (aes_selftest(&aes_bear_impl))
78 aprint_error("aes: self-test failed: %s\n",
79 aes_bear_impl.ai_name);
80 else
81 aes_impl = &aes_bear_impl;
82 }
83 if (aes_impl == NULL)
84 panic("AES self-tests failed");
85
86 aprint_normal("aes: %s\n", aes_impl->ai_name);
87 return 0;
88 }
89
90 MODULE(MODULE_CLASS_MISC, aes, NULL);
91
92 static int
93 aes_modcmd(modcmd_t cmd, void *opaque)
94 {
95
96 switch (cmd) {
97 case MODULE_CMD_INIT:
98 return aes_select();
99 case MODULE_CMD_FINI:
100 return 0;
101 default:
102 return ENOTTY;
103 }
104 }
105
106 static void
107 aes_guarantee_selected(void)
108 {
109 #if 0
110 static once_t once;
111 int error;
112
113 error = RUN_ONCE(&once, aes_select);
114 KASSERT(error == 0);
115 #endif
116 }
117
118 void
119 aes_md_init(const struct aes_impl *impl)
120 {
121
122 KASSERT(cold);
123 KASSERTMSG(aes_impl == NULL,
124 "AES implementation `%s' already chosen, can't offer `%s'",
125 aes_impl->ai_name, impl->ai_name);
126 KASSERTMSG(aes_md_impl == NULL,
127 "AES implementation `%s' already offered, can't offer `%s'",
128 aes_md_impl->ai_name, impl->ai_name);
129
130 aes_md_impl = impl;
131 }
132
133 static void
134 aes_setenckey(struct aesenc *enc, const uint8_t key[static 16],
135 uint32_t nrounds)
136 {
137
138 aes_guarantee_selected();
139 aes_impl->ai_setenckey(enc, key, nrounds);
140 }
141
142 uint32_t
143 aes_setenckey128(struct aesenc *enc, const uint8_t key[static 16])
144 {
145 uint32_t nrounds = AES_128_NROUNDS;
146
147 aes_setenckey(enc, key, nrounds);
148 return nrounds;
149 }
150
151 uint32_t
152 aes_setenckey192(struct aesenc *enc, const uint8_t key[static 24])
153 {
154 uint32_t nrounds = AES_192_NROUNDS;
155
156 aes_setenckey(enc, key, nrounds);
157 return nrounds;
158 }
159
160 uint32_t
161 aes_setenckey256(struct aesenc *enc, const uint8_t key[static 32])
162 {
163 uint32_t nrounds = AES_256_NROUNDS;
164
165 aes_setenckey(enc, key, nrounds);
166 return nrounds;
167 }
168
169 static void
170 aes_setdeckey(struct aesdec *dec, const uint8_t key[static 16],
171 uint32_t nrounds)
172 {
173
174 aes_guarantee_selected();
175 aes_impl->ai_setdeckey(dec, key, nrounds);
176 }
177
178 uint32_t
179 aes_setdeckey128(struct aesdec *dec, const uint8_t key[static 16])
180 {
181 uint32_t nrounds = AES_128_NROUNDS;
182
183 aes_setdeckey(dec, key, nrounds);
184 return nrounds;
185 }
186
187 uint32_t
188 aes_setdeckey192(struct aesdec *dec, const uint8_t key[static 24])
189 {
190 uint32_t nrounds = AES_192_NROUNDS;
191
192 aes_setdeckey(dec, key, nrounds);
193 return nrounds;
194 }
195
196 uint32_t
197 aes_setdeckey256(struct aesdec *dec, const uint8_t key[static 32])
198 {
199 uint32_t nrounds = AES_256_NROUNDS;
200
201 aes_setdeckey(dec, key, nrounds);
202 return nrounds;
203 }
204
205 void
206 aes_enc(const struct aesenc *enc, const uint8_t in[static 16],
207 uint8_t out[static 16], uint32_t nrounds)
208 {
209
210 aes_guarantee_selected();
211 aes_impl->ai_enc(enc, in, out, nrounds);
212 }
213
214 void
215 aes_dec(const struct aesdec *dec, const uint8_t in[static 16],
216 uint8_t out[static 16], uint32_t nrounds)
217 {
218
219 aes_guarantee_selected();
220 aes_impl->ai_dec(dec, in, out, nrounds);
221 }
222
223 void
224 aes_cbc_enc(struct aesenc *enc, const uint8_t in[static 16],
225 uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
226 uint32_t nrounds)
227 {
228
229 aes_guarantee_selected();
230 aes_impl->ai_cbc_enc(enc, in, out, nbytes, iv, nrounds);
231 }
232
233 void
234 aes_cbc_dec(struct aesdec *dec, const uint8_t in[static 16],
235 uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
236 uint32_t nrounds)
237 {
238
239 aes_guarantee_selected();
240 aes_impl->ai_cbc_dec(dec, in, out, nbytes, iv, nrounds);
241 }
242
243 void
244 aes_xts_enc(struct aesenc *enc, const uint8_t in[static 16],
245 uint8_t out[static 16], size_t nbytes, uint8_t tweak[static 16],
246 uint32_t nrounds)
247 {
248
249 aes_guarantee_selected();
250 aes_impl->ai_xts_enc(enc, in, out, nbytes, tweak, nrounds);
251 }
252
253 void
254 aes_xts_dec(struct aesdec *dec, const uint8_t in[static 16],
255 uint8_t out[static 16], size_t nbytes, uint8_t tweak[static 16],
256 uint32_t nrounds)
257 {
258
259 aes_guarantee_selected();
260 aes_impl->ai_xts_dec(dec, in, out, nbytes, tweak, nrounds);
261 }
262
263 /*
264 * Known-answer self-tests for the standard key schedule.
265 */
266 static int
267 aes_selftest_stdkeysched(void)
268 {
269 static const uint8_t key[32] = {
270 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
271 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
272 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
273 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
274 };
275 static const uint32_t rk128enc[] = {
276 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
277 0xfd74aad6, 0xfa72afd2, 0xf178a6da, 0xfe76abd6,
278 0x0bcf92b6, 0xf1bd3d64, 0x00c59bbe, 0xfeb33068,
279 0x4e74ffb6, 0xbfc9c2d2, 0xbf0c596c, 0x41bf6904,
280 0xbcf7f747, 0x033e3595, 0xbc326cf9, 0xfd8d05fd,
281 0xe8a3aa3c, 0xeb9d9fa9, 0x57aff350, 0xaa22f6ad,
282 0x7d0f395e, 0x9692a6f7, 0xc13d55a7, 0x6b1fa30a,
283 0x1a70f914, 0x8ce25fe3, 0x4ddf0a44, 0x26c0a94e,
284 0x35874347, 0xb9651ca4, 0xf4ba16e0, 0xd27abfae,
285 0xd1329954, 0x685785f0, 0x9ced9310, 0x4e972cbe,
286 0x7f1d1113, 0x174a94e3, 0x8ba707f3, 0xc5302b4d,
287 };
288 static const uint32_t rk192enc[] = {
289 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
290 0x13121110, 0x17161514, 0xf9f24658, 0xfef4435c,
291 0xf5fe4a54, 0xfaf04758, 0xe9e25648, 0xfef4435c,
292 0xb349f940, 0x4dbdba1c, 0xb843f048, 0x42b3b710,
293 0xab51e158, 0x55a5a204, 0x41b5ff7e, 0x0c084562,
294 0xb44bb52a, 0xf6f8023a, 0x5da9e362, 0x080c4166,
295 0x728501f5, 0x7e8d4497, 0xcac6f1bd, 0x3c3ef387,
296 0x619710e5, 0x699b5183, 0x9e7c1534, 0xe0f151a3,
297 0x2a37a01e, 0x16095399, 0x779e437c, 0x1e0512ff,
298 0x880e7edd, 0x68ff2f7e, 0x42c88f60, 0x54c1dcf9,
299 0x235f9f85, 0x3d5a8d7a, 0x5229c0c0, 0x3ad6efbe,
300 0x781e60de, 0x2cdfbc27, 0x0f8023a2, 0x32daaed8,
301 0x330a97a4, 0x09dc781a, 0x71c218c4, 0x5d1da4e3,
302 };
303 static const uint32_t rk256enc[] = {
304 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
305 0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,
306 0x9fc273a5, 0x98c476a1, 0x93ce7fa9, 0x9cc072a5,
307 0xcda85116, 0xdabe4402, 0xc1a45d1a, 0xdeba4006,
308 0xf0df87ae, 0x681bf10f, 0xfbd58ea6, 0x6715fc03,
309 0x48f1e16d, 0x924fa56f, 0x53ebf875, 0x8d51b873,
310 0x7f8256c6, 0x1799a7c9, 0xec4c296f, 0x8b59d56c,
311 0x753ae23d, 0xe7754752, 0xb49ebf27, 0x39cf0754,
312 0x5f90dc0b, 0x48097bc2, 0xa44552ad, 0x2f1c87c1,
313 0x60a6f545, 0x87d3b217, 0x334d0d30, 0x0a820a64,
314 0x1cf7cf7c, 0x54feb4be, 0xf0bbe613, 0xdfa761d2,
315 0xfefa1af0, 0x7929a8e7, 0x4a64a5d7, 0x40e6afb3,
316 0x71fe4125, 0x2500f59b, 0xd5bb1388, 0x0a1c725a,
317 0x99665a4e, 0xe04ff2a9, 0xaa2b577e, 0xeacdf8cd,
318 0xcc79fc24, 0xe97909bf, 0x3cc21a37, 0x36de686d,
319 };
320 static const uint32_t rk128dec[] = {
321 0x7f1d1113, 0x174a94e3, 0x8ba707f3, 0xc5302b4d,
322 0xbe29aa13, 0xf6af8f9c, 0x80f570f7, 0x03bff700,
323 0x63a46213, 0x4886258f, 0x765aff6b, 0x834a87f7,
324 0x74fc828d, 0x2b22479c, 0x3edcdae4, 0xf510789c,
325 0x8d09e372, 0x5fdec511, 0x15fe9d78, 0xcbcca278,
326 0x2710c42e, 0xd2d72663, 0x4a205869, 0xde323f00,
327 0x04f5a2a8, 0xf5c7e24d, 0x98f77e0a, 0x94126769,
328 0x91e3c6c7, 0xf13240e5, 0x6d309c47, 0x0ce51963,
329 0x9902dba0, 0x60d18622, 0x9c02dca2, 0x61d58524,
330 0xf0df568c, 0xf9d35d82, 0xfcd35a80, 0xfdd75986,
331 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
332 };
333 static const uint32_t rk192dec[] = {
334 0x330a97a4, 0x09dc781a, 0x71c218c4, 0x5d1da4e3,
335 0x0dbdbed6, 0x49ea09c2, 0x8073b04d, 0xb91b023e,
336 0xc999b98f, 0x3968b273, 0x9dd8f9c7, 0x728cc685,
337 0xc16e7df7, 0xef543f42, 0x7f317853, 0x4457b714,
338 0x90654711, 0x3b66cf47, 0x8dce0e9b, 0xf0f10bfc,
339 0xb6a8c1dc, 0x7d3f0567, 0x4a195ccc, 0x2e3a42b5,
340 0xabb0dec6, 0x64231e79, 0xbe5f05a4, 0xab038856,
341 0xda7c1bdd, 0x155c8df2, 0x1dab498a, 0xcb97c4bb,
342 0x08f7c478, 0xd63c8d31, 0x01b75596, 0xcf93c0bf,
343 0x10efdc60, 0xce249529, 0x15efdb62, 0xcf20962f,
344 0xdbcb4e4b, 0xdacf4d4d, 0xc7d75257, 0xdecb4949,
345 0x1d181f1a, 0x191c1b1e, 0xd7c74247, 0xdecb4949,
346 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
347 };
348 static const uint32_t rk256dec[] = {
349 0xcc79fc24, 0xe97909bf, 0x3cc21a37, 0x36de686d,
350 0xffd1f134, 0x2faacebf, 0x5fe2e9fc, 0x6e015825,
351 0xeb48165e, 0x0a354c38, 0x46b77175, 0x84e680dc,
352 0x8005a3c8, 0xd07b3f8b, 0x70482743, 0x31e3b1d9,
353 0x138e70b5, 0xe17d5a66, 0x4c823d4d, 0xc251f1a9,
354 0xa37bda74, 0x507e9c43, 0xa03318c8, 0x41ab969a,
355 0x1597a63c, 0xf2f32ad3, 0xadff672b, 0x8ed3cce4,
356 0xf3c45ff8, 0xf3054637, 0xf04d848b, 0xe1988e52,
357 0x9a4069de, 0xe7648cef, 0x5f0c4df8, 0x232cabcf,
358 0x1658d5ae, 0x00c119cf, 0x0348c2bc, 0x11d50ad9,
359 0xbd68c615, 0x7d24e531, 0xb868c117, 0x7c20e637,
360 0x0f85d77f, 0x1699cc61, 0x0389db73, 0x129dc865,
361 0xc940282a, 0xc04c2324, 0xc54c2426, 0xc4482720,
362 0x1d181f1a, 0x191c1b1e, 0x15101712, 0x11141316,
363 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
364 };
365 static const struct {
366 unsigned len;
367 unsigned nr;
368 const uint32_t *enc, *dec;
369 } C[] = {
370 { 16, AES_128_NROUNDS, rk128enc, rk128dec },
371 { 24, AES_192_NROUNDS, rk192enc, rk192dec },
372 { 32, AES_256_NROUNDS, rk256enc, rk256dec },
373 };
374 uint32_t rk[60];
375 unsigned i;
376
377 for (i = 0; i < __arraycount(C); i++) {
378 if (br_aes_ct_keysched_stdenc(rk, key, C[i].len) != C[i].nr)
379 return -1;
380 if (memcmp(rk, C[i].enc, 4*(C[i].nr + 1)))
381 return -1;
382 if (br_aes_ct_keysched_stddec(rk, key, C[i].len) != C[i].nr)
383 return -1;
384 if (memcmp(rk, C[i].dec, 4*(C[i].nr + 1)))
385 return -1;
386 }
387
388 return 0;
389 }
390