1*3f729ba5Sjmcneill /* $NetBSD: aes_impl.c,v 1.10 2022/11/05 17:36:33 jmcneill Exp $ */
25dcdae41Sriastradh
35dcdae41Sriastradh /*-
45dcdae41Sriastradh * Copyright (c) 2020 The NetBSD Foundation, Inc.
55dcdae41Sriastradh * All rights reserved.
65dcdae41Sriastradh *
75dcdae41Sriastradh * Redistribution and use in source and binary forms, with or without
85dcdae41Sriastradh * modification, are permitted provided that the following conditions
95dcdae41Sriastradh * are met:
105dcdae41Sriastradh * 1. Redistributions of source code must retain the above copyright
115dcdae41Sriastradh * notice, this list of conditions and the following disclaimer.
125dcdae41Sriastradh * 2. Redistributions in binary form must reproduce the above copyright
135dcdae41Sriastradh * notice, this list of conditions and the following disclaimer in the
145dcdae41Sriastradh * documentation and/or other materials provided with the distribution.
155dcdae41Sriastradh *
165dcdae41Sriastradh * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
175dcdae41Sriastradh * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
185dcdae41Sriastradh * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
195dcdae41Sriastradh * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
205dcdae41Sriastradh * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
215dcdae41Sriastradh * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
225dcdae41Sriastradh * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
235dcdae41Sriastradh * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
245dcdae41Sriastradh * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
255dcdae41Sriastradh * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
265dcdae41Sriastradh * POSSIBILITY OF SUCH DAMAGE.
275dcdae41Sriastradh */
285dcdae41Sriastradh
295dcdae41Sriastradh #include <sys/cdefs.h>
30*3f729ba5Sjmcneill __KERNEL_RCSID(1, "$NetBSD: aes_impl.c,v 1.10 2022/11/05 17:36:33 jmcneill Exp $");
315dcdae41Sriastradh
325dcdae41Sriastradh #include <sys/types.h>
335dcdae41Sriastradh #include <sys/kernel.h>
345dcdae41Sriastradh #include <sys/module.h>
355dcdae41Sriastradh #include <sys/once.h>
361c86761fSriastradh #include <sys/sysctl.h>
375dcdae41Sriastradh #include <sys/systm.h>
385dcdae41Sriastradh
395dcdae41Sriastradh #include <crypto/aes/aes.h>
40820a30e5Sriastradh #include <crypto/aes/aes_cbc.h>
415dcdae41Sriastradh #include <crypto/aes/aes_bear.h> /* default implementation */
42518b19bbSriastradh #include <crypto/aes/aes_impl.h>
43820a30e5Sriastradh #include <crypto/aes/aes_xts.h>
445dcdae41Sriastradh
45776602aeSriastradh static int aes_selftest_stdkeysched(void);
46776602aeSriastradh
475dcdae41Sriastradh static const struct aes_impl *aes_md_impl __read_mostly;
485dcdae41Sriastradh static const struct aes_impl *aes_impl __read_mostly;
495dcdae41Sriastradh
501c86761fSriastradh static int
sysctl_kern_crypto_aes_selected(SYSCTLFN_ARGS)5115cabcb3Sriastradh sysctl_kern_crypto_aes_selected(SYSCTLFN_ARGS)
521c86761fSriastradh {
531c86761fSriastradh struct sysctlnode node;
541c86761fSriastradh
551c86761fSriastradh KASSERTMSG(aes_impl != NULL,
561c86761fSriastradh "sysctl ran before AES implementation was selected");
571c86761fSriastradh
581c86761fSriastradh node = *rnode;
591c86761fSriastradh node.sysctl_data = __UNCONST(aes_impl->ai_name);
601c86761fSriastradh node.sysctl_size = strlen(aes_impl->ai_name) + 1;
611c86761fSriastradh return sysctl_lookup(SYSCTLFN_CALL(&node));
621c86761fSriastradh }
631c86761fSriastradh
6415cabcb3Sriastradh SYSCTL_SETUP(sysctl_kern_crypto_aes_setup, "sysctl kern.crypto.aes setup")
651c86761fSriastradh {
6615cabcb3Sriastradh const struct sysctlnode *cnode;
6715cabcb3Sriastradh const struct sysctlnode *aes_node;
681c86761fSriastradh
6915cabcb3Sriastradh sysctl_createv(clog, 0, NULL, &cnode, 0, CTLTYPE_NODE, "crypto",
7015cabcb3Sriastradh SYSCTL_DESCR("Kernel cryptography"),
7115cabcb3Sriastradh NULL, 0, NULL, 0,
7215cabcb3Sriastradh CTL_KERN, CTL_CREATE, CTL_EOL);
7315cabcb3Sriastradh sysctl_createv(clog, 0, &cnode, &aes_node, 0, CTLTYPE_NODE, "aes",
7415cabcb3Sriastradh SYSCTL_DESCR("AES -- Advanced Encryption Standard"),
7515cabcb3Sriastradh NULL, 0, NULL, 0,
7615cabcb3Sriastradh CTL_CREATE, CTL_EOL);
7715cabcb3Sriastradh sysctl_createv(clog, 0, &aes_node, NULL,
7815cabcb3Sriastradh CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_STRING, "selected",
791c86761fSriastradh SYSCTL_DESCR("Selected AES implementation"),
8015cabcb3Sriastradh sysctl_kern_crypto_aes_selected, 0, NULL, 0,
8115cabcb3Sriastradh CTL_CREATE, CTL_EOL);
821c86761fSriastradh }
831c86761fSriastradh
845dcdae41Sriastradh /*
855dcdae41Sriastradh * The timing of AES implementation selection is finicky:
865dcdae41Sriastradh *
875dcdae41Sriastradh * 1. It has to be done _after_ cpu_attach for implementations,
885dcdae41Sriastradh * such as AES-NI, that rely on fpu initialization done by
895dcdae41Sriastradh * fpu_attach.
905dcdae41Sriastradh *
915dcdae41Sriastradh * 2. It has to be done _before_ the cgd self-tests or anything
925dcdae41Sriastradh * else that might call AES.
935dcdae41Sriastradh *
945dcdae41Sriastradh * For the moment, doing it in module init works. However, if a
955dcdae41Sriastradh * driver-class module depended on the aes module, that would break.
965dcdae41Sriastradh */
975dcdae41Sriastradh
985dcdae41Sriastradh static int
aes_select(void)995dcdae41Sriastradh aes_select(void)
1005dcdae41Sriastradh {
1015dcdae41Sriastradh
1025dcdae41Sriastradh KASSERT(aes_impl == NULL);
1035dcdae41Sriastradh
104776602aeSriastradh if (aes_selftest_stdkeysched())
105776602aeSriastradh panic("AES is busted");
106776602aeSriastradh
1075dcdae41Sriastradh if (aes_md_impl) {
1085dcdae41Sriastradh if (aes_selftest(aes_md_impl))
1095dcdae41Sriastradh aprint_error("aes: self-test failed: %s\n",
1105dcdae41Sriastradh aes_md_impl->ai_name);
1115dcdae41Sriastradh else
1125dcdae41Sriastradh aes_impl = aes_md_impl;
1135dcdae41Sriastradh }
1145dcdae41Sriastradh if (aes_impl == NULL) {
1155dcdae41Sriastradh if (aes_selftest(&aes_bear_impl))
1165dcdae41Sriastradh aprint_error("aes: self-test failed: %s\n",
1175dcdae41Sriastradh aes_bear_impl.ai_name);
1185dcdae41Sriastradh else
1195dcdae41Sriastradh aes_impl = &aes_bear_impl;
1205dcdae41Sriastradh }
1215dcdae41Sriastradh if (aes_impl == NULL)
1225dcdae41Sriastradh panic("AES self-tests failed");
1235dcdae41Sriastradh
124*3f729ba5Sjmcneill aprint_debug("aes: %s\n", aes_impl->ai_name);
1255dcdae41Sriastradh return 0;
1265dcdae41Sriastradh }
1275dcdae41Sriastradh
1285dcdae41Sriastradh MODULE(MODULE_CLASS_MISC, aes, NULL);
1295dcdae41Sriastradh
1305dcdae41Sriastradh static int
aes_modcmd(modcmd_t cmd,void * opaque)1315dcdae41Sriastradh aes_modcmd(modcmd_t cmd, void *opaque)
1325dcdae41Sriastradh {
1335dcdae41Sriastradh
1345dcdae41Sriastradh switch (cmd) {
1355dcdae41Sriastradh case MODULE_CMD_INIT:
1365dcdae41Sriastradh return aes_select();
1375dcdae41Sriastradh case MODULE_CMD_FINI:
1385dcdae41Sriastradh return 0;
1395dcdae41Sriastradh default:
1405dcdae41Sriastradh return ENOTTY;
1415dcdae41Sriastradh }
1425dcdae41Sriastradh }
1435dcdae41Sriastradh
1445dcdae41Sriastradh static void
aes_guarantee_selected(void)1455dcdae41Sriastradh aes_guarantee_selected(void)
1465dcdae41Sriastradh {
1475dcdae41Sriastradh #if 0
1485dcdae41Sriastradh static once_t once;
1495dcdae41Sriastradh int error;
1505dcdae41Sriastradh
1515dcdae41Sriastradh error = RUN_ONCE(&once, aes_select);
1525dcdae41Sriastradh KASSERT(error == 0);
1535dcdae41Sriastradh #endif
1545dcdae41Sriastradh }
1555dcdae41Sriastradh
1565dcdae41Sriastradh void
aes_md_init(const struct aes_impl * impl)1575dcdae41Sriastradh aes_md_init(const struct aes_impl *impl)
1585dcdae41Sriastradh {
1595dcdae41Sriastradh
1605dcdae41Sriastradh KASSERT(cold);
1615dcdae41Sriastradh KASSERTMSG(aes_impl == NULL,
1625dcdae41Sriastradh "AES implementation `%s' already chosen, can't offer `%s'",
1635dcdae41Sriastradh aes_impl->ai_name, impl->ai_name);
1645dcdae41Sriastradh KASSERTMSG(aes_md_impl == NULL,
1655dcdae41Sriastradh "AES implementation `%s' already offered, can't offer `%s'",
1665dcdae41Sriastradh aes_md_impl->ai_name, impl->ai_name);
1675dcdae41Sriastradh
1685dcdae41Sriastradh aes_md_impl = impl;
1695dcdae41Sriastradh }
1705dcdae41Sriastradh
1715dcdae41Sriastradh static void
aes_setenckey(struct aesenc * enc,const uint8_t key[static16],uint32_t nrounds)1725dcdae41Sriastradh aes_setenckey(struct aesenc *enc, const uint8_t key[static 16],
1735dcdae41Sriastradh uint32_t nrounds)
1745dcdae41Sriastradh {
1755dcdae41Sriastradh
1765dcdae41Sriastradh aes_guarantee_selected();
1775dcdae41Sriastradh aes_impl->ai_setenckey(enc, key, nrounds);
1785dcdae41Sriastradh }
1795dcdae41Sriastradh
1805dcdae41Sriastradh uint32_t
aes_setenckey128(struct aesenc * enc,const uint8_t key[static16])1815dcdae41Sriastradh aes_setenckey128(struct aesenc *enc, const uint8_t key[static 16])
1825dcdae41Sriastradh {
1835dcdae41Sriastradh uint32_t nrounds = AES_128_NROUNDS;
1845dcdae41Sriastradh
1855dcdae41Sriastradh aes_setenckey(enc, key, nrounds);
1865dcdae41Sriastradh return nrounds;
1875dcdae41Sriastradh }
1885dcdae41Sriastradh
1895dcdae41Sriastradh uint32_t
aes_setenckey192(struct aesenc * enc,const uint8_t key[static24])1905dcdae41Sriastradh aes_setenckey192(struct aesenc *enc, const uint8_t key[static 24])
1915dcdae41Sriastradh {
1925dcdae41Sriastradh uint32_t nrounds = AES_192_NROUNDS;
1935dcdae41Sriastradh
1945dcdae41Sriastradh aes_setenckey(enc, key, nrounds);
1955dcdae41Sriastradh return nrounds;
1965dcdae41Sriastradh }
1975dcdae41Sriastradh
1985dcdae41Sriastradh uint32_t
aes_setenckey256(struct aesenc * enc,const uint8_t key[static32])1995dcdae41Sriastradh aes_setenckey256(struct aesenc *enc, const uint8_t key[static 32])
2005dcdae41Sriastradh {
2015dcdae41Sriastradh uint32_t nrounds = AES_256_NROUNDS;
2025dcdae41Sriastradh
2035dcdae41Sriastradh aes_setenckey(enc, key, nrounds);
2045dcdae41Sriastradh return nrounds;
2055dcdae41Sriastradh }
2065dcdae41Sriastradh
2075dcdae41Sriastradh static void
aes_setdeckey(struct aesdec * dec,const uint8_t key[static16],uint32_t nrounds)2085dcdae41Sriastradh aes_setdeckey(struct aesdec *dec, const uint8_t key[static 16],
2095dcdae41Sriastradh uint32_t nrounds)
2105dcdae41Sriastradh {
2115dcdae41Sriastradh
2125dcdae41Sriastradh aes_guarantee_selected();
2135dcdae41Sriastradh aes_impl->ai_setdeckey(dec, key, nrounds);
2145dcdae41Sriastradh }
2155dcdae41Sriastradh
2165dcdae41Sriastradh uint32_t
aes_setdeckey128(struct aesdec * dec,const uint8_t key[static16])2175dcdae41Sriastradh aes_setdeckey128(struct aesdec *dec, const uint8_t key[static 16])
2185dcdae41Sriastradh {
2195dcdae41Sriastradh uint32_t nrounds = AES_128_NROUNDS;
2205dcdae41Sriastradh
2215dcdae41Sriastradh aes_setdeckey(dec, key, nrounds);
2225dcdae41Sriastradh return nrounds;
2235dcdae41Sriastradh }
2245dcdae41Sriastradh
2255dcdae41Sriastradh uint32_t
aes_setdeckey192(struct aesdec * dec,const uint8_t key[static24])2265dcdae41Sriastradh aes_setdeckey192(struct aesdec *dec, const uint8_t key[static 24])
2275dcdae41Sriastradh {
2285dcdae41Sriastradh uint32_t nrounds = AES_192_NROUNDS;
2295dcdae41Sriastradh
2305dcdae41Sriastradh aes_setdeckey(dec, key, nrounds);
2315dcdae41Sriastradh return nrounds;
2325dcdae41Sriastradh }
2335dcdae41Sriastradh
2345dcdae41Sriastradh uint32_t
aes_setdeckey256(struct aesdec * dec,const uint8_t key[static32])2355dcdae41Sriastradh aes_setdeckey256(struct aesdec *dec, const uint8_t key[static 32])
2365dcdae41Sriastradh {
2375dcdae41Sriastradh uint32_t nrounds = AES_256_NROUNDS;
2385dcdae41Sriastradh
2395dcdae41Sriastradh aes_setdeckey(dec, key, nrounds);
2405dcdae41Sriastradh return nrounds;
2415dcdae41Sriastradh }
2425dcdae41Sriastradh
2435dcdae41Sriastradh void
aes_enc(const struct aesenc * enc,const uint8_t in[static16],uint8_t out[static16],uint32_t nrounds)2445dcdae41Sriastradh aes_enc(const struct aesenc *enc, const uint8_t in[static 16],
2455dcdae41Sriastradh uint8_t out[static 16], uint32_t nrounds)
2465dcdae41Sriastradh {
2475dcdae41Sriastradh
2485dcdae41Sriastradh aes_guarantee_selected();
2495dcdae41Sriastradh aes_impl->ai_enc(enc, in, out, nrounds);
2505dcdae41Sriastradh }
2515dcdae41Sriastradh
2525dcdae41Sriastradh void
aes_dec(const struct aesdec * dec,const uint8_t in[static16],uint8_t out[static16],uint32_t nrounds)2535dcdae41Sriastradh aes_dec(const struct aesdec *dec, const uint8_t in[static 16],
2545dcdae41Sriastradh uint8_t out[static 16], uint32_t nrounds)
2555dcdae41Sriastradh {
2565dcdae41Sriastradh
2575dcdae41Sriastradh aes_guarantee_selected();
2585dcdae41Sriastradh aes_impl->ai_dec(dec, in, out, nrounds);
2595dcdae41Sriastradh }
2605dcdae41Sriastradh
2615dcdae41Sriastradh 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)2625dcdae41Sriastradh aes_cbc_enc(struct aesenc *enc, const uint8_t in[static 16],
2635dcdae41Sriastradh uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
2645dcdae41Sriastradh uint32_t nrounds)
2655dcdae41Sriastradh {
2665dcdae41Sriastradh
2675dcdae41Sriastradh aes_guarantee_selected();
2685dcdae41Sriastradh aes_impl->ai_cbc_enc(enc, in, out, nbytes, iv, nrounds);
2695dcdae41Sriastradh }
2705dcdae41Sriastradh
2715dcdae41Sriastradh 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)2725dcdae41Sriastradh aes_cbc_dec(struct aesdec *dec, const uint8_t in[static 16],
2735dcdae41Sriastradh uint8_t out[static 16], size_t nbytes, uint8_t iv[static 16],
2745dcdae41Sriastradh uint32_t nrounds)
2755dcdae41Sriastradh {
2765dcdae41Sriastradh
2775dcdae41Sriastradh aes_guarantee_selected();
2785dcdae41Sriastradh aes_impl->ai_cbc_dec(dec, in, out, nbytes, iv, nrounds);
2795dcdae41Sriastradh }
2805dcdae41Sriastradh
2815dcdae41Sriastradh 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)2825dcdae41Sriastradh aes_xts_enc(struct aesenc *enc, const uint8_t in[static 16],
2835dcdae41Sriastradh uint8_t out[static 16], size_t nbytes, uint8_t tweak[static 16],
2845dcdae41Sriastradh uint32_t nrounds)
2855dcdae41Sriastradh {
2865dcdae41Sriastradh
2875dcdae41Sriastradh aes_guarantee_selected();
2885dcdae41Sriastradh aes_impl->ai_xts_enc(enc, in, out, nbytes, tweak, nrounds);
2895dcdae41Sriastradh }
2905dcdae41Sriastradh
2915dcdae41Sriastradh 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)2925dcdae41Sriastradh aes_xts_dec(struct aesdec *dec, const uint8_t in[static 16],
2935dcdae41Sriastradh uint8_t out[static 16], size_t nbytes, uint8_t tweak[static 16],
2945dcdae41Sriastradh uint32_t nrounds)
2955dcdae41Sriastradh {
2965dcdae41Sriastradh
2975dcdae41Sriastradh aes_guarantee_selected();
2985dcdae41Sriastradh aes_impl->ai_xts_dec(dec, in, out, nbytes, tweak, nrounds);
2995dcdae41Sriastradh }
300776602aeSriastradh
301ebf44a5bSriastradh void
aes_cbcmac_update1(const struct aesenc * enc,const uint8_t in[static16],size_t nbytes,uint8_t auth[static16],uint32_t nrounds)302ebf44a5bSriastradh aes_cbcmac_update1(const struct aesenc *enc, const uint8_t in[static 16],
303ebf44a5bSriastradh size_t nbytes, uint8_t auth[static 16], uint32_t nrounds)
304ebf44a5bSriastradh {
305ebf44a5bSriastradh
306ebf44a5bSriastradh KASSERT(nbytes);
307ebf44a5bSriastradh KASSERT(nbytes % 16 == 0);
308ebf44a5bSriastradh
309ebf44a5bSriastradh aes_guarantee_selected();
310ebf44a5bSriastradh aes_impl->ai_cbcmac_update1(enc, in, nbytes, auth, nrounds);
311ebf44a5bSriastradh }
312ebf44a5bSriastradh
313ebf44a5bSriastradh 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)314ebf44a5bSriastradh aes_ccm_enc1(const struct aesenc *enc, const uint8_t in[static 16],
315ebf44a5bSriastradh uint8_t out[static 16], size_t nbytes, uint8_t authctr[static 32],
316ebf44a5bSriastradh uint32_t nrounds)
317ebf44a5bSriastradh {
318ebf44a5bSriastradh
319ebf44a5bSriastradh KASSERT(nbytes);
320ebf44a5bSriastradh KASSERT(nbytes % 16 == 0);
321ebf44a5bSriastradh
322ebf44a5bSriastradh aes_guarantee_selected();
323fe314d33Sriastradh aes_impl->ai_ccm_enc1(enc, in, out, nbytes, authctr, nrounds);
324ebf44a5bSriastradh }
325ebf44a5bSriastradh
326ebf44a5bSriastradh 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)327ebf44a5bSriastradh aes_ccm_dec1(const struct aesenc *enc, const uint8_t in[static 16],
328ebf44a5bSriastradh uint8_t out[static 16], size_t nbytes, uint8_t authctr[static 32],
329ebf44a5bSriastradh uint32_t nrounds)
330ebf44a5bSriastradh {
331ebf44a5bSriastradh
332ebf44a5bSriastradh KASSERT(nbytes);
333ebf44a5bSriastradh KASSERT(nbytes % 16 == 0);
334ebf44a5bSriastradh
335ebf44a5bSriastradh aes_guarantee_selected();
336fe314d33Sriastradh aes_impl->ai_ccm_dec1(enc, in, out, nbytes, authctr, nrounds);
337ebf44a5bSriastradh }
338ebf44a5bSriastradh
339776602aeSriastradh /*
340776602aeSriastradh * Known-answer self-tests for the standard key schedule.
341776602aeSriastradh */
342776602aeSriastradh static int
aes_selftest_stdkeysched(void)343776602aeSriastradh aes_selftest_stdkeysched(void)
344776602aeSriastradh {
345776602aeSriastradh static const uint8_t key[32] = {
346776602aeSriastradh 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
347776602aeSriastradh 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
348776602aeSriastradh 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
349776602aeSriastradh 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
350776602aeSriastradh };
351776602aeSriastradh static const uint32_t rk128enc[] = {
352776602aeSriastradh 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
353776602aeSriastradh 0xfd74aad6, 0xfa72afd2, 0xf178a6da, 0xfe76abd6,
354776602aeSriastradh 0x0bcf92b6, 0xf1bd3d64, 0x00c59bbe, 0xfeb33068,
355776602aeSriastradh 0x4e74ffb6, 0xbfc9c2d2, 0xbf0c596c, 0x41bf6904,
356776602aeSriastradh 0xbcf7f747, 0x033e3595, 0xbc326cf9, 0xfd8d05fd,
357776602aeSriastradh 0xe8a3aa3c, 0xeb9d9fa9, 0x57aff350, 0xaa22f6ad,
358776602aeSriastradh 0x7d0f395e, 0x9692a6f7, 0xc13d55a7, 0x6b1fa30a,
359776602aeSriastradh 0x1a70f914, 0x8ce25fe3, 0x4ddf0a44, 0x26c0a94e,
360776602aeSriastradh 0x35874347, 0xb9651ca4, 0xf4ba16e0, 0xd27abfae,
361776602aeSriastradh 0xd1329954, 0x685785f0, 0x9ced9310, 0x4e972cbe,
362776602aeSriastradh 0x7f1d1113, 0x174a94e3, 0x8ba707f3, 0xc5302b4d,
363776602aeSriastradh };
364776602aeSriastradh static const uint32_t rk192enc[] = {
365776602aeSriastradh 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
366776602aeSriastradh 0x13121110, 0x17161514, 0xf9f24658, 0xfef4435c,
367776602aeSriastradh 0xf5fe4a54, 0xfaf04758, 0xe9e25648, 0xfef4435c,
368776602aeSriastradh 0xb349f940, 0x4dbdba1c, 0xb843f048, 0x42b3b710,
369776602aeSriastradh 0xab51e158, 0x55a5a204, 0x41b5ff7e, 0x0c084562,
370776602aeSriastradh 0xb44bb52a, 0xf6f8023a, 0x5da9e362, 0x080c4166,
371776602aeSriastradh 0x728501f5, 0x7e8d4497, 0xcac6f1bd, 0x3c3ef387,
372776602aeSriastradh 0x619710e5, 0x699b5183, 0x9e7c1534, 0xe0f151a3,
373776602aeSriastradh 0x2a37a01e, 0x16095399, 0x779e437c, 0x1e0512ff,
374776602aeSriastradh 0x880e7edd, 0x68ff2f7e, 0x42c88f60, 0x54c1dcf9,
375776602aeSriastradh 0x235f9f85, 0x3d5a8d7a, 0x5229c0c0, 0x3ad6efbe,
376776602aeSriastradh 0x781e60de, 0x2cdfbc27, 0x0f8023a2, 0x32daaed8,
377776602aeSriastradh 0x330a97a4, 0x09dc781a, 0x71c218c4, 0x5d1da4e3,
378776602aeSriastradh };
379776602aeSriastradh static const uint32_t rk256enc[] = {
380776602aeSriastradh 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
381776602aeSriastradh 0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,
382776602aeSriastradh 0x9fc273a5, 0x98c476a1, 0x93ce7fa9, 0x9cc072a5,
383776602aeSriastradh 0xcda85116, 0xdabe4402, 0xc1a45d1a, 0xdeba4006,
384776602aeSriastradh 0xf0df87ae, 0x681bf10f, 0xfbd58ea6, 0x6715fc03,
385776602aeSriastradh 0x48f1e16d, 0x924fa56f, 0x53ebf875, 0x8d51b873,
386776602aeSriastradh 0x7f8256c6, 0x1799a7c9, 0xec4c296f, 0x8b59d56c,
387776602aeSriastradh 0x753ae23d, 0xe7754752, 0xb49ebf27, 0x39cf0754,
388776602aeSriastradh 0x5f90dc0b, 0x48097bc2, 0xa44552ad, 0x2f1c87c1,
389776602aeSriastradh 0x60a6f545, 0x87d3b217, 0x334d0d30, 0x0a820a64,
390776602aeSriastradh 0x1cf7cf7c, 0x54feb4be, 0xf0bbe613, 0xdfa761d2,
391776602aeSriastradh 0xfefa1af0, 0x7929a8e7, 0x4a64a5d7, 0x40e6afb3,
392776602aeSriastradh 0x71fe4125, 0x2500f59b, 0xd5bb1388, 0x0a1c725a,
393776602aeSriastradh 0x99665a4e, 0xe04ff2a9, 0xaa2b577e, 0xeacdf8cd,
394776602aeSriastradh 0xcc79fc24, 0xe97909bf, 0x3cc21a37, 0x36de686d,
395776602aeSriastradh };
396776602aeSriastradh static const uint32_t rk128dec[] = {
397776602aeSriastradh 0x7f1d1113, 0x174a94e3, 0x8ba707f3, 0xc5302b4d,
398776602aeSriastradh 0xbe29aa13, 0xf6af8f9c, 0x80f570f7, 0x03bff700,
399776602aeSriastradh 0x63a46213, 0x4886258f, 0x765aff6b, 0x834a87f7,
400776602aeSriastradh 0x74fc828d, 0x2b22479c, 0x3edcdae4, 0xf510789c,
401776602aeSriastradh 0x8d09e372, 0x5fdec511, 0x15fe9d78, 0xcbcca278,
402776602aeSriastradh 0x2710c42e, 0xd2d72663, 0x4a205869, 0xde323f00,
403776602aeSriastradh 0x04f5a2a8, 0xf5c7e24d, 0x98f77e0a, 0x94126769,
404776602aeSriastradh 0x91e3c6c7, 0xf13240e5, 0x6d309c47, 0x0ce51963,
405776602aeSriastradh 0x9902dba0, 0x60d18622, 0x9c02dca2, 0x61d58524,
406776602aeSriastradh 0xf0df568c, 0xf9d35d82, 0xfcd35a80, 0xfdd75986,
407776602aeSriastradh 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
408776602aeSriastradh };
409776602aeSriastradh static const uint32_t rk192dec[] = {
410776602aeSriastradh 0x330a97a4, 0x09dc781a, 0x71c218c4, 0x5d1da4e3,
411776602aeSriastradh 0x0dbdbed6, 0x49ea09c2, 0x8073b04d, 0xb91b023e,
412776602aeSriastradh 0xc999b98f, 0x3968b273, 0x9dd8f9c7, 0x728cc685,
413776602aeSriastradh 0xc16e7df7, 0xef543f42, 0x7f317853, 0x4457b714,
414776602aeSriastradh 0x90654711, 0x3b66cf47, 0x8dce0e9b, 0xf0f10bfc,
415776602aeSriastradh 0xb6a8c1dc, 0x7d3f0567, 0x4a195ccc, 0x2e3a42b5,
416776602aeSriastradh 0xabb0dec6, 0x64231e79, 0xbe5f05a4, 0xab038856,
417776602aeSriastradh 0xda7c1bdd, 0x155c8df2, 0x1dab498a, 0xcb97c4bb,
418776602aeSriastradh 0x08f7c478, 0xd63c8d31, 0x01b75596, 0xcf93c0bf,
419776602aeSriastradh 0x10efdc60, 0xce249529, 0x15efdb62, 0xcf20962f,
420776602aeSriastradh 0xdbcb4e4b, 0xdacf4d4d, 0xc7d75257, 0xdecb4949,
421776602aeSriastradh 0x1d181f1a, 0x191c1b1e, 0xd7c74247, 0xdecb4949,
422776602aeSriastradh 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
423776602aeSriastradh };
424776602aeSriastradh static const uint32_t rk256dec[] = {
425776602aeSriastradh 0xcc79fc24, 0xe97909bf, 0x3cc21a37, 0x36de686d,
426776602aeSriastradh 0xffd1f134, 0x2faacebf, 0x5fe2e9fc, 0x6e015825,
427776602aeSriastradh 0xeb48165e, 0x0a354c38, 0x46b77175, 0x84e680dc,
428776602aeSriastradh 0x8005a3c8, 0xd07b3f8b, 0x70482743, 0x31e3b1d9,
429776602aeSriastradh 0x138e70b5, 0xe17d5a66, 0x4c823d4d, 0xc251f1a9,
430776602aeSriastradh 0xa37bda74, 0x507e9c43, 0xa03318c8, 0x41ab969a,
431776602aeSriastradh 0x1597a63c, 0xf2f32ad3, 0xadff672b, 0x8ed3cce4,
432776602aeSriastradh 0xf3c45ff8, 0xf3054637, 0xf04d848b, 0xe1988e52,
433776602aeSriastradh 0x9a4069de, 0xe7648cef, 0x5f0c4df8, 0x232cabcf,
434776602aeSriastradh 0x1658d5ae, 0x00c119cf, 0x0348c2bc, 0x11d50ad9,
435776602aeSriastradh 0xbd68c615, 0x7d24e531, 0xb868c117, 0x7c20e637,
436776602aeSriastradh 0x0f85d77f, 0x1699cc61, 0x0389db73, 0x129dc865,
437776602aeSriastradh 0xc940282a, 0xc04c2324, 0xc54c2426, 0xc4482720,
438776602aeSriastradh 0x1d181f1a, 0x191c1b1e, 0x15101712, 0x11141316,
439776602aeSriastradh 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
440776602aeSriastradh };
441776602aeSriastradh static const struct {
442776602aeSriastradh unsigned len;
443776602aeSriastradh unsigned nr;
444776602aeSriastradh const uint32_t *enc, *dec;
445776602aeSriastradh } C[] = {
446776602aeSriastradh { 16, AES_128_NROUNDS, rk128enc, rk128dec },
447776602aeSriastradh { 24, AES_192_NROUNDS, rk192enc, rk192dec },
448776602aeSriastradh { 32, AES_256_NROUNDS, rk256enc, rk256dec },
449776602aeSriastradh };
450776602aeSriastradh uint32_t rk[60];
451776602aeSriastradh unsigned i;
452776602aeSriastradh
453776602aeSriastradh for (i = 0; i < __arraycount(C); i++) {
454776602aeSriastradh if (br_aes_ct_keysched_stdenc(rk, key, C[i].len) != C[i].nr)
455776602aeSriastradh return -1;
456776602aeSriastradh if (memcmp(rk, C[i].enc, 4*(C[i].nr + 1)))
457776602aeSriastradh return -1;
458776602aeSriastradh if (br_aes_ct_keysched_stddec(rk, key, C[i].len) != C[i].nr)
459776602aeSriastradh return -1;
460776602aeSriastradh if (memcmp(rk, C[i].dec, 4*(C[i].nr + 1)))
461776602aeSriastradh return -1;
462776602aeSriastradh }
463776602aeSriastradh
464776602aeSriastradh return 0;
465776602aeSriastradh }
466