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