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