xref: /netbsd-src/sys/crypto/aes/aes_impl.c (revision 3f729ba5867bcb94e07999f992a0d193d35d3dbd)
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