Home | History | Annotate | Line # | Download | only in aes
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