1 /* $NetBSD: aes_impl.c,v 1.10 2022/11/05 17:36:33 jmcneill 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.10 2022/11/05 17:36:33 jmcneill 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/sysctl.h>
37 #include <sys/systm.h>
38
39 #include <crypto/aes/aes.h>
40 #include <crypto/aes/aes_cbc.h>
41 #include <crypto/aes/aes_bear.h> /* default implementation */
42 #include <crypto/aes/aes_impl.h>
43 #include <crypto/aes/aes_xts.h>
44
45 static int aes_selftest_stdkeysched(void);
46
47 static const struct aes_impl *aes_md_impl __read_mostly;
48 static const struct aes_impl *aes_impl __read_mostly;
49
50 static int
sysctl_kern_crypto_aes_selected(SYSCTLFN_ARGS)51 sysctl_kern_crypto_aes_selected(SYSCTLFN_ARGS)
52 {
53 struct sysctlnode node;
54
55 KASSERTMSG(aes_impl != NULL,
56 "sysctl ran before AES implementation was selected");
57
58 node = *rnode;
59 node.sysctl_data = __UNCONST(aes_impl->ai_name);
60 node.sysctl_size = strlen(aes_impl->ai_name) + 1;
61 return sysctl_lookup(SYSCTLFN_CALL(&node));
62 }
63
64 SYSCTL_SETUP(sysctl_kern_crypto_aes_setup, "sysctl kern.crypto.aes setup")
65 {
66 const struct sysctlnode *cnode;
67 const struct sysctlnode *aes_node;
68
69 sysctl_createv(clog, 0, NULL, &cnode, 0, CTLTYPE_NODE, "crypto",
70 SYSCTL_DESCR("Kernel cryptography"),
71 NULL, 0, NULL, 0,
72 CTL_KERN, CTL_CREATE, CTL_EOL);
73 sysctl_createv(clog, 0, &cnode, &aes_node, 0, CTLTYPE_NODE, "aes",
74 SYSCTL_DESCR("AES -- Advanced Encryption Standard"),
75 NULL, 0, NULL, 0,
76 CTL_CREATE, CTL_EOL);
77 sysctl_createv(clog, 0, &aes_node, NULL,
78 CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_STRING, "selected",
79 SYSCTL_DESCR("Selected AES implementation"),
80 sysctl_kern_crypto_aes_selected, 0, NULL, 0,
81 CTL_CREATE, CTL_EOL);
82 }
83
84 /*
85 * The timing of AES implementation selection is finicky:
86 *
87 * 1. It has to be done _after_ cpu_attach for implementations,
88 * such as AES-NI, that rely on fpu initialization done by
89 * fpu_attach.
90 *
91 * 2. It has to be done _before_ the cgd self-tests or anything
92 * else that might call AES.
93 *
94 * For the moment, doing it in module init works. However, if a
95 * driver-class module depended on the aes module, that would break.
96 */
97
98 static int
aes_select(void)99 aes_select(void)
100 {
101
102 KASSERT(aes_impl == NULL);
103
104 if (aes_selftest_stdkeysched())
105 panic("AES is busted");
106
107 if (aes_md_impl) {
108 if (aes_selftest(aes_md_impl))
109 aprint_error("aes: self-test failed: %s\n",
110 aes_md_impl->ai_name);
111 else
112 aes_impl = aes_md_impl;
113 }
114 if (aes_impl == NULL) {
115 if (aes_selftest(&aes_bear_impl))
116 aprint_error("aes: self-test failed: %s\n",
117 aes_bear_impl.ai_name);
118 else
119 aes_impl = &aes_bear_impl;
120 }
121 if (aes_impl == NULL)
122 panic("AES self-tests failed");
123
124 aprint_debug("aes: %s\n", aes_impl->ai_name);
125 return 0;
126 }
127
128 MODULE(MODULE_CLASS_MISC, aes, NULL);
129
130 static int
aes_modcmd(modcmd_t cmd,void * opaque)131 aes_modcmd(modcmd_t cmd, void *opaque)
132 {
133
134 switch (cmd) {
135 case MODULE_CMD_INIT:
136 return aes_select();
137 case MODULE_CMD_FINI:
138 return 0;
139 default:
140 return ENOTTY;
141 }
142 }
143
144 static void
aes_guarantee_selected(void)145 aes_guarantee_selected(void)
146 {
147 #if 0
148 static once_t once;
149 int error;
150
151 error = RUN_ONCE(&once, aes_select);
152 KASSERT(error == 0);
153 #endif
154 }
155
156 void
aes_md_init(const struct aes_impl * impl)157 aes_md_init(const struct aes_impl *impl)
158 {
159
160 KASSERT(cold);
161 KASSERTMSG(aes_impl == NULL,
162 "AES implementation `%s' already chosen, can't offer `%s'",
163 aes_impl->ai_name, impl->ai_name);
164 KASSERTMSG(aes_md_impl == NULL,
165 "AES implementation `%s' already offered, can't offer `%s'",
166 aes_md_impl->ai_name, impl->ai_name);
167
168 aes_md_impl = impl;
169 }
170
171 static void
aes_setenckey(struct aesenc * enc,const uint8_t key[static16],uint32_t nrounds)172 aes_setenckey(struct aesenc *enc, const uint8_t key[static 16],
173 uint32_t nrounds)
174 {
175
176 aes_guarantee_selected();
177 aes_impl->ai_setenckey(enc, key, nrounds);
178 }
179
180 uint32_t
aes_setenckey128(struct aesenc * enc,const uint8_t key[static16])181 aes_setenckey128(struct aesenc *enc, const uint8_t key[static 16])
182 {
183 uint32_t nrounds = AES_128_NROUNDS;
184
185 aes_setenckey(enc, key, nrounds);
186 return nrounds;
187 }
188
189 uint32_t
aes_setenckey192(struct aesenc * enc,const uint8_t key[static24])190 aes_setenckey192(struct aesenc *enc, const uint8_t key[static 24])
191 {
192 uint32_t nrounds = AES_192_NROUNDS;
193
194 aes_setenckey(enc, key, nrounds);
195 return nrounds;
196 }
197
198 uint32_t
aes_setenckey256(struct aesenc * enc,const uint8_t key[static32])199 aes_setenckey256(struct aesenc *enc, const uint8_t key[static 32])
200 {
201 uint32_t nrounds = AES_256_NROUNDS;
202
203 aes_setenckey(enc, key, nrounds);
204 return nrounds;
205 }
206
207 static void
aes_setdeckey(struct aesdec * dec,const uint8_t key[static16],uint32_t nrounds)208 aes_setdeckey(struct aesdec *dec, const uint8_t key[static 16],
209 uint32_t nrounds)
210 {
211
212 aes_guarantee_selected();
213 aes_impl->ai_setdeckey(dec, key, nrounds);
214 }
215
216 uint32_t
aes_setdeckey128(struct aesdec * dec,const uint8_t key[static16])217 aes_setdeckey128(struct aesdec *dec, const uint8_t key[static 16])
218 {
219 uint32_t nrounds = AES_128_NROUNDS;
220
221 aes_setdeckey(dec, key, nrounds);
222 return nrounds;
223 }
224
225 uint32_t
aes_setdeckey192(struct aesdec * dec,const uint8_t key[static24])226 aes_setdeckey192(struct aesdec *dec, const uint8_t key[static 24])
227 {
228 uint32_t nrounds = AES_192_NROUNDS;
229
230 aes_setdeckey(dec, key, nrounds);
231 return nrounds;
232 }
233
234 uint32_t
aes_setdeckey256(struct aesdec * dec,const uint8_t key[static32])235 aes_setdeckey256(struct aesdec *dec, const uint8_t key[static 32])
236 {
237 uint32_t nrounds = AES_256_NROUNDS;
238
239 aes_setdeckey(dec, key, nrounds);
240 return nrounds;
241 }
242
243 void
aes_enc(const struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],uint32_t nrounds)244 aes_enc(const struct aesenc *enc, const uint8_t in[static 16],
245 uint8_t out[static 16], uint32_t nrounds)
246 {
247
248 aes_guarantee_selected();
249 aes_impl->ai_enc(enc, in, out, nrounds);
250 }
251
252 void
aes_dec(const struct aesdec * dec,const uint8_t in[static16],uint8_t out[static16],uint32_t nrounds)253 aes_dec(const struct aesdec *dec, const uint8_t in[static 16],
254 uint8_t out[static 16], uint32_t nrounds)
255 {
256
257 aes_guarantee_selected();
258 aes_impl->ai_dec(dec, in, out, nrounds);
259 }
260
261 void
aes_cbc_enc(struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t iv[static16],uint32_t nrounds)262 aes_cbc_enc(struct aesenc *enc, const uint8_t in[static 16],
263 uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
264 uint32_t nrounds)
265 {
266
267 aes_guarantee_selected();
268 aes_impl->ai_cbc_enc(enc, in, out, nbytes, iv, nrounds);
269 }
270
271 void
aes_cbc_dec(struct aesdec * dec,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t iv[static16],uint32_t nrounds)272 aes_cbc_dec(struct aesdec *dec, const uint8_t in[static 16],
273 uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
274 uint32_t nrounds)
275 {
276
277 aes_guarantee_selected();
278 aes_impl->ai_cbc_dec(dec, in, out, nbytes, iv, nrounds);
279 }
280
281 void
aes_xts_enc(struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t tweak[static16],uint32_t nrounds)282 aes_xts_enc(struct aesenc *enc, const uint8_t in[static 16],
283 uint8_t out[static 16], size_t nbytes, uint8_t tweak[static 16],
284 uint32_t nrounds)
285 {
286
287 aes_guarantee_selected();
288 aes_impl->ai_xts_enc(enc, in, out, nbytes, tweak, nrounds);
289 }
290
291 void
aes_xts_dec(struct aesdec * dec,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t tweak[static16],uint32_t nrounds)292 aes_xts_dec(struct aesdec *dec, const uint8_t in[static 16],
293 uint8_t out[static 16], size_t nbytes, uint8_t tweak[static 16],
294 uint32_t nrounds)
295 {
296
297 aes_guarantee_selected();
298 aes_impl->ai_xts_dec(dec, in, out, nbytes, tweak, nrounds);
299 }
300
301 void
aes_cbcmac_update1(const struct aesenc * enc,const uint8_t in[static16],size_t nbytes,uint8_t auth[static16],uint32_t nrounds)302 aes_cbcmac_update1(const struct aesenc *enc, const uint8_t in[static 16],
303 size_t nbytes, uint8_t auth[static 16], uint32_t nrounds)
304 {
305
306 KASSERT(nbytes);
307 KASSERT(nbytes % 16 == 0);
308
309 aes_guarantee_selected();
310 aes_impl->ai_cbcmac_update1(enc, in, nbytes, auth, nrounds);
311 }
312
313 void
aes_ccm_enc1(const struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t authctr[static32],uint32_t nrounds)314 aes_ccm_enc1(const struct aesenc *enc, const uint8_t in[static 16],
315 uint8_t out[static 16], size_t nbytes, uint8_t authctr[static 32],
316 uint32_t nrounds)
317 {
318
319 KASSERT(nbytes);
320 KASSERT(nbytes % 16 == 0);
321
322 aes_guarantee_selected();
323 aes_impl->ai_ccm_enc1(enc, in, out, nbytes, authctr, nrounds);
324 }
325
326 void
aes_ccm_dec1(const struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],size_t nbytes,uint8_t authctr[static32],uint32_t nrounds)327 aes_ccm_dec1(const struct aesenc *enc, const uint8_t in[static 16],
328 uint8_t out[static 16], size_t nbytes, uint8_t authctr[static 32],
329 uint32_t nrounds)
330 {
331
332 KASSERT(nbytes);
333 KASSERT(nbytes % 16 == 0);
334
335 aes_guarantee_selected();
336 aes_impl->ai_ccm_dec1(enc, in, out, nbytes, authctr, nrounds);
337 }
338
339 /*
340 * Known-answer self-tests for the standard key schedule.
341 */
342 static int
aes_selftest_stdkeysched(void)343 aes_selftest_stdkeysched(void)
344 {
345 static const uint8_t key[32] = {
346 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
347 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
348 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
349 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
350 };
351 static const uint32_t rk128enc[] = {
352 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
353 0xfd74aad6, 0xfa72afd2, 0xf178a6da, 0xfe76abd6,
354 0x0bcf92b6, 0xf1bd3d64, 0x00c59bbe, 0xfeb33068,
355 0x4e74ffb6, 0xbfc9c2d2, 0xbf0c596c, 0x41bf6904,
356 0xbcf7f747, 0x033e3595, 0xbc326cf9, 0xfd8d05fd,
357 0xe8a3aa3c, 0xeb9d9fa9, 0x57aff350, 0xaa22f6ad,
358 0x7d0f395e, 0x9692a6f7, 0xc13d55a7, 0x6b1fa30a,
359 0x1a70f914, 0x8ce25fe3, 0x4ddf0a44, 0x26c0a94e,
360 0x35874347, 0xb9651ca4, 0xf4ba16e0, 0xd27abfae,
361 0xd1329954, 0x685785f0, 0x9ced9310, 0x4e972cbe,
362 0x7f1d1113, 0x174a94e3, 0x8ba707f3, 0xc5302b4d,
363 };
364 static const uint32_t rk192enc[] = {
365 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
366 0x13121110, 0x17161514, 0xf9f24658, 0xfef4435c,
367 0xf5fe4a54, 0xfaf04758, 0xe9e25648, 0xfef4435c,
368 0xb349f940, 0x4dbdba1c, 0xb843f048, 0x42b3b710,
369 0xab51e158, 0x55a5a204, 0x41b5ff7e, 0x0c084562,
370 0xb44bb52a, 0xf6f8023a, 0x5da9e362, 0x080c4166,
371 0x728501f5, 0x7e8d4497, 0xcac6f1bd, 0x3c3ef387,
372 0x619710e5, 0x699b5183, 0x9e7c1534, 0xe0f151a3,
373 0x2a37a01e, 0x16095399, 0x779e437c, 0x1e0512ff,
374 0x880e7edd, 0x68ff2f7e, 0x42c88f60, 0x54c1dcf9,
375 0x235f9f85, 0x3d5a8d7a, 0x5229c0c0, 0x3ad6efbe,
376 0x781e60de, 0x2cdfbc27, 0x0f8023a2, 0x32daaed8,
377 0x330a97a4, 0x09dc781a, 0x71c218c4, 0x5d1da4e3,
378 };
379 static const uint32_t rk256enc[] = {
380 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
381 0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,
382 0x9fc273a5, 0x98c476a1, 0x93ce7fa9, 0x9cc072a5,
383 0xcda85116, 0xdabe4402, 0xc1a45d1a, 0xdeba4006,
384 0xf0df87ae, 0x681bf10f, 0xfbd58ea6, 0x6715fc03,
385 0x48f1e16d, 0x924fa56f, 0x53ebf875, 0x8d51b873,
386 0x7f8256c6, 0x1799a7c9, 0xec4c296f, 0x8b59d56c,
387 0x753ae23d, 0xe7754752, 0xb49ebf27, 0x39cf0754,
388 0x5f90dc0b, 0x48097bc2, 0xa44552ad, 0x2f1c87c1,
389 0x60a6f545, 0x87d3b217, 0x334d0d30, 0x0a820a64,
390 0x1cf7cf7c, 0x54feb4be, 0xf0bbe613, 0xdfa761d2,
391 0xfefa1af0, 0x7929a8e7, 0x4a64a5d7, 0x40e6afb3,
392 0x71fe4125, 0x2500f59b, 0xd5bb1388, 0x0a1c725a,
393 0x99665a4e, 0xe04ff2a9, 0xaa2b577e, 0xeacdf8cd,
394 0xcc79fc24, 0xe97909bf, 0x3cc21a37, 0x36de686d,
395 };
396 static const uint32_t rk128dec[] = {
397 0x7f1d1113, 0x174a94e3, 0x8ba707f3, 0xc5302b4d,
398 0xbe29aa13, 0xf6af8f9c, 0x80f570f7, 0x03bff700,
399 0x63a46213, 0x4886258f, 0x765aff6b, 0x834a87f7,
400 0x74fc828d, 0x2b22479c, 0x3edcdae4, 0xf510789c,
401 0x8d09e372, 0x5fdec511, 0x15fe9d78, 0xcbcca278,
402 0x2710c42e, 0xd2d72663, 0x4a205869, 0xde323f00,
403 0x04f5a2a8, 0xf5c7e24d, 0x98f77e0a, 0x94126769,
404 0x91e3c6c7, 0xf13240e5, 0x6d309c47, 0x0ce51963,
405 0x9902dba0, 0x60d18622, 0x9c02dca2, 0x61d58524,
406 0xf0df568c, 0xf9d35d82, 0xfcd35a80, 0xfdd75986,
407 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
408 };
409 static const uint32_t rk192dec[] = {
410 0x330a97a4, 0x09dc781a, 0x71c218c4, 0x5d1da4e3,
411 0x0dbdbed6, 0x49ea09c2, 0x8073b04d, 0xb91b023e,
412 0xc999b98f, 0x3968b273, 0x9dd8f9c7, 0x728cc685,
413 0xc16e7df7, 0xef543f42, 0x7f317853, 0x4457b714,
414 0x90654711, 0x3b66cf47, 0x8dce0e9b, 0xf0f10bfc,
415 0xb6a8c1dc, 0x7d3f0567, 0x4a195ccc, 0x2e3a42b5,
416 0xabb0dec6, 0x64231e79, 0xbe5f05a4, 0xab038856,
417 0xda7c1bdd, 0x155c8df2, 0x1dab498a, 0xcb97c4bb,
418 0x08f7c478, 0xd63c8d31, 0x01b75596, 0xcf93c0bf,
419 0x10efdc60, 0xce249529, 0x15efdb62, 0xcf20962f,
420 0xdbcb4e4b, 0xdacf4d4d, 0xc7d75257, 0xdecb4949,
421 0x1d181f1a, 0x191c1b1e, 0xd7c74247, 0xdecb4949,
422 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
423 };
424 static const uint32_t rk256dec[] = {
425 0xcc79fc24, 0xe97909bf, 0x3cc21a37, 0x36de686d,
426 0xffd1f134, 0x2faacebf, 0x5fe2e9fc, 0x6e015825,
427 0xeb48165e, 0x0a354c38, 0x46b77175, 0x84e680dc,
428 0x8005a3c8, 0xd07b3f8b, 0x70482743, 0x31e3b1d9,
429 0x138e70b5, 0xe17d5a66, 0x4c823d4d, 0xc251f1a9,
430 0xa37bda74, 0x507e9c43, 0xa03318c8, 0x41ab969a,
431 0x1597a63c, 0xf2f32ad3, 0xadff672b, 0x8ed3cce4,
432 0xf3c45ff8, 0xf3054637, 0xf04d848b, 0xe1988e52,
433 0x9a4069de, 0xe7648cef, 0x5f0c4df8, 0x232cabcf,
434 0x1658d5ae, 0x00c119cf, 0x0348c2bc, 0x11d50ad9,
435 0xbd68c615, 0x7d24e531, 0xb868c117, 0x7c20e637,
436 0x0f85d77f, 0x1699cc61, 0x0389db73, 0x129dc865,
437 0xc940282a, 0xc04c2324, 0xc54c2426, 0xc4482720,
438 0x1d181f1a, 0x191c1b1e, 0x15101712, 0x11141316,
439 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
440 };
441 static const struct {
442 unsigned len;
443 unsigned nr;
444 const uint32_t *enc, *dec;
445 } C[] = {
446 { 16, AES_128_NROUNDS, rk128enc, rk128dec },
447 { 24, AES_192_NROUNDS, rk192enc, rk192dec },
448 { 32, AES_256_NROUNDS, rk256enc, rk256dec },
449 };
450 uint32_t rk[60];
451 unsigned i;
452
453 for (i = 0; i < __arraycount(C); i++) {
454 if (br_aes_ct_keysched_stdenc(rk, key, C[i].len) != C[i].nr)
455 return -1;
456 if (memcmp(rk, C[i].enc, 4*(C[i].nr + 1)))
457 return -1;
458 if (br_aes_ct_keysched_stddec(rk, key, C[i].len) != C[i].nr)
459 return -1;
460 if (memcmp(rk, C[i].dec, 4*(C[i].nr + 1)))
461 return -1;
462 }
463
464 return 0;
465 }
466