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