1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
4 /* AES implementation by Tom St Denis
6 * Derived from the Public Domain source code by
11 * @version 3.0 (December 2000)
13 * Optimised ANSI C code for the Rijndael cipher (now AES)
15 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
16 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
17 * @author Paulo Barreto <paulo.barreto@terra.com.br>
25 #include "tomcrypt_private.h"
31 #define SETUP rijndael_setup
32 #define ECB_ENC rijndael_ecb_encrypt
33 #define ECB_DEC rijndael_ecb_decrypt
34 #define ECB_DONE rijndael_done
35 #define ECB_TEST rijndael_test
36 #define ECB_KS rijndael_keysize
38 const struct ltc_cipher_descriptor rijndael_desc
=
43 SETUP
, ECB_ENC
, ECB_DEC
, ECB_TEST
, ECB_DONE
, ECB_KS
,
44 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
47 const struct ltc_cipher_descriptor aes_desc
=
52 SETUP
, ECB_ENC
, ECB_DEC
, ECB_TEST
, ECB_DONE
, ECB_KS
,
53 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
58 #define SETUP rijndael_enc_setup
59 #define ECB_ENC rijndael_enc_ecb_encrypt
60 #define ECB_KS rijndael_enc_keysize
61 #define ECB_DONE rijndael_enc_done
63 const struct ltc_cipher_descriptor rijndael_enc_desc
=
68 SETUP
, ECB_ENC
, NULL
, NULL
, ECB_DONE
, ECB_KS
,
69 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
72 const struct ltc_cipher_descriptor aes_enc_desc
=
77 SETUP
, ECB_ENC
, NULL
, NULL
, ECB_DONE
, ECB_KS
,
78 NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
86 static ulong32
setup_mix(ulong32 temp
)
88 return (Te4_3
[LTC_BYTE(temp
, 2)]) ^
89 (Te4_2
[LTC_BYTE(temp
, 1)]) ^
90 (Te4_1
[LTC_BYTE(temp
, 0)]) ^
91 (Te4_0
[LTC_BYTE(temp
, 3)]);
96 static ulong32
setup_mix2(ulong32 temp
)
98 return Td0(255 & Te4
[LTC_BYTE(temp
, 3)]) ^
99 Td1(255 & Te4
[LTC_BYTE(temp
, 2)]) ^
100 Td2(255 & Te4
[LTC_BYTE(temp
, 1)]) ^
101 Td3(255 & Te4
[LTC_BYTE(temp
, 0)]);
107 Initialize the AES (Rijndael) block cipher
108 @param key The symmetric key you wish to pass
109 @param keylen The key length in bytes
110 @param num_rounds The number of rounds desired (0 for default)
111 @param skey The key in as scheduled by this function.
112 @return CRYPT_OK if successful
114 int SETUP(const unsigned char *key
, int keylen
, int num_rounds
, symmetric_key
*skey
)
121 LTC_ARGCHK(key
!= NULL
);
122 LTC_ARGCHK(skey
!= NULL
);
124 if (keylen
!= 16 && keylen
!= 24 && keylen
!= 32) {
125 return CRYPT_INVALID_KEYSIZE
;
128 if (num_rounds
!= 0 && num_rounds
!= (10 + ((keylen
/8)-2)*2)) {
129 return CRYPT_INVALID_ROUNDS
;
132 skey
->rijndael
.Nr
= 10 + ((keylen
/8)-2)*2;
134 /* setup the forward key */
136 rk
= skey
->rijndael
.eK
;
137 LOAD32H(rk
[0], key
);
138 LOAD32H(rk
[1], key
+ 4);
139 LOAD32H(rk
[2], key
+ 8);
140 LOAD32H(rk
[3], key
+ 12);
144 rk
[4] = rk
[0] ^ setup_mix(temp
) ^ rcon
[i
];
145 rk
[5] = rk
[1] ^ rk
[4];
146 rk
[6] = rk
[2] ^ rk
[5];
147 rk
[7] = rk
[3] ^ rk
[6];
153 } else if (keylen
== 24) {
154 LOAD32H(rk
[4], key
+ 16);
155 LOAD32H(rk
[5], key
+ 20);
158 temp
= skey
->rijndael
.eK
[rk
- skey
->rijndael
.eK
+ 5];
162 rk
[ 6] = rk
[ 0] ^ setup_mix(temp
) ^ rcon
[i
];
163 rk
[ 7] = rk
[ 1] ^ rk
[ 6];
164 rk
[ 8] = rk
[ 2] ^ rk
[ 7];
165 rk
[ 9] = rk
[ 3] ^ rk
[ 8];
169 rk
[10] = rk
[ 4] ^ rk
[ 9];
170 rk
[11] = rk
[ 5] ^ rk
[10];
173 } else if (keylen
== 32) {
174 LOAD32H(rk
[4], key
+ 16);
175 LOAD32H(rk
[5], key
+ 20);
176 LOAD32H(rk
[6], key
+ 24);
177 LOAD32H(rk
[7], key
+ 28);
180 temp
= skey
->rijndael
.eK
[rk
- skey
->rijndael
.eK
+ 7];
184 rk
[ 8] = rk
[ 0] ^ setup_mix(temp
) ^ rcon
[i
];
185 rk
[ 9] = rk
[ 1] ^ rk
[ 8];
186 rk
[10] = rk
[ 2] ^ rk
[ 9];
187 rk
[11] = rk
[ 3] ^ rk
[10];
192 rk
[12] = rk
[ 4] ^ setup_mix(RORc(temp
, 8));
193 rk
[13] = rk
[ 5] ^ rk
[12];
194 rk
[14] = rk
[ 6] ^ rk
[13];
195 rk
[15] = rk
[ 7] ^ rk
[14];
199 /* this can't happen */
200 /* coverity[dead_error_line] */
205 /* setup the inverse key now */
206 rk
= skey
->rijndael
.dK
;
207 rrk
= skey
->rijndael
.eK
+ (28 + keylen
) - 4;
209 /* apply the inverse MixColumn transform to all round keys but the first and the last: */
217 for (i
= 1; i
< skey
->rijndael
.Nr
; i
++) {
220 #ifdef LTC_SMALL_CODE
222 rk
[0] = setup_mix2(temp
);
224 rk
[1] = setup_mix2(temp
);
226 rk
[2] = setup_mix2(temp
);
228 rk
[3] = setup_mix2(temp
);
232 Tks0
[LTC_BYTE(temp
, 3)] ^
233 Tks1
[LTC_BYTE(temp
, 2)] ^
234 Tks2
[LTC_BYTE(temp
, 1)] ^
235 Tks3
[LTC_BYTE(temp
, 0)];
238 Tks0
[LTC_BYTE(temp
, 3)] ^
239 Tks1
[LTC_BYTE(temp
, 2)] ^
240 Tks2
[LTC_BYTE(temp
, 1)] ^
241 Tks3
[LTC_BYTE(temp
, 0)];
244 Tks0
[LTC_BYTE(temp
, 3)] ^
245 Tks1
[LTC_BYTE(temp
, 2)] ^
246 Tks2
[LTC_BYTE(temp
, 1)] ^
247 Tks3
[LTC_BYTE(temp
, 0)];
250 Tks0
[LTC_BYTE(temp
, 3)] ^
251 Tks1
[LTC_BYTE(temp
, 2)] ^
252 Tks2
[LTC_BYTE(temp
, 1)] ^
253 Tks3
[LTC_BYTE(temp
, 0)];
265 #endif /* ENCRYPT_ONLY */
271 Encrypts a block of text with AES
272 @param pt The input plaintext (16 bytes)
273 @param ct The output ciphertext (16 bytes)
274 @param skey The key as scheduled
275 @return CRYPT_OK if successful
277 #ifdef LTC_CLEAN_STACK
278 static int s_rijndael_ecb_encrypt(const unsigned char *pt
, unsigned char *ct
, const symmetric_key
*skey
)
280 int ECB_ENC(const unsigned char *pt
, unsigned char *ct
, const symmetric_key
*skey
)
283 ulong32 s0
, s1
, s2
, s3
, t0
, t1
, t2
, t3
;
287 LTC_ARGCHK(pt
!= NULL
);
288 LTC_ARGCHK(ct
!= NULL
);
289 LTC_ARGCHK(skey
!= NULL
);
291 Nr
= skey
->rijndael
.Nr
;
293 if (Nr
< 2 || Nr
> 16)
294 return CRYPT_INVALID_ROUNDS
;
296 rk
= skey
->rijndael
.eK
;
299 * map byte array block to cipher state
300 * and add initial round key:
302 LOAD32H(s0
, pt
); s0
^= rk
[0];
303 LOAD32H(s1
, pt
+ 4); s1
^= rk
[1];
304 LOAD32H(s2
, pt
+ 8); s2
^= rk
[2];
305 LOAD32H(s3
, pt
+ 12); s3
^= rk
[3];
307 #ifdef LTC_SMALL_CODE
312 Te0(LTC_BYTE(s0
, 3)) ^
313 Te1(LTC_BYTE(s1
, 2)) ^
314 Te2(LTC_BYTE(s2
, 1)) ^
315 Te3(LTC_BYTE(s3
, 0)) ^
318 Te0(LTC_BYTE(s1
, 3)) ^
319 Te1(LTC_BYTE(s2
, 2)) ^
320 Te2(LTC_BYTE(s3
, 1)) ^
321 Te3(LTC_BYTE(s0
, 0)) ^
324 Te0(LTC_BYTE(s2
, 3)) ^
325 Te1(LTC_BYTE(s3
, 2)) ^
326 Te2(LTC_BYTE(s0
, 1)) ^
327 Te3(LTC_BYTE(s1
, 0)) ^
330 Te0(LTC_BYTE(s3
, 3)) ^
331 Te1(LTC_BYTE(s0
, 2)) ^
332 Te2(LTC_BYTE(s1
, 1)) ^
333 Te3(LTC_BYTE(s2
, 0)) ^
338 s0
= t0
; s1
= t1
; s2
= t2
; s3
= t3
;
345 * Nr - 1 full rounds:
350 Te0(LTC_BYTE(s0
, 3)) ^
351 Te1(LTC_BYTE(s1
, 2)) ^
352 Te2(LTC_BYTE(s2
, 1)) ^
353 Te3(LTC_BYTE(s3
, 0)) ^
356 Te0(LTC_BYTE(s1
, 3)) ^
357 Te1(LTC_BYTE(s2
, 2)) ^
358 Te2(LTC_BYTE(s3
, 1)) ^
359 Te3(LTC_BYTE(s0
, 0)) ^
362 Te0(LTC_BYTE(s2
, 3)) ^
363 Te1(LTC_BYTE(s3
, 2)) ^
364 Te2(LTC_BYTE(s0
, 1)) ^
365 Te3(LTC_BYTE(s1
, 0)) ^
368 Te0(LTC_BYTE(s3
, 3)) ^
369 Te1(LTC_BYTE(s0
, 2)) ^
370 Te2(LTC_BYTE(s1
, 1)) ^
371 Te3(LTC_BYTE(s2
, 0)) ^
380 Te0(LTC_BYTE(t0
, 3)) ^
381 Te1(LTC_BYTE(t1
, 2)) ^
382 Te2(LTC_BYTE(t2
, 1)) ^
383 Te3(LTC_BYTE(t3
, 0)) ^
386 Te0(LTC_BYTE(t1
, 3)) ^
387 Te1(LTC_BYTE(t2
, 2)) ^
388 Te2(LTC_BYTE(t3
, 1)) ^
389 Te3(LTC_BYTE(t0
, 0)) ^
392 Te0(LTC_BYTE(t2
, 3)) ^
393 Te1(LTC_BYTE(t3
, 2)) ^
394 Te2(LTC_BYTE(t0
, 1)) ^
395 Te3(LTC_BYTE(t1
, 0)) ^
398 Te0(LTC_BYTE(t3
, 3)) ^
399 Te1(LTC_BYTE(t0
, 2)) ^
400 Te2(LTC_BYTE(t1
, 1)) ^
401 Te3(LTC_BYTE(t2
, 0)) ^
408 * apply last round and
409 * map cipher state to byte array block:
412 (Te4_3
[LTC_BYTE(t0
, 3)]) ^
413 (Te4_2
[LTC_BYTE(t1
, 2)]) ^
414 (Te4_1
[LTC_BYTE(t2
, 1)]) ^
415 (Te4_0
[LTC_BYTE(t3
, 0)]) ^
419 (Te4_3
[LTC_BYTE(t1
, 3)]) ^
420 (Te4_2
[LTC_BYTE(t2
, 2)]) ^
421 (Te4_1
[LTC_BYTE(t3
, 1)]) ^
422 (Te4_0
[LTC_BYTE(t0
, 0)]) ^
426 (Te4_3
[LTC_BYTE(t2
, 3)]) ^
427 (Te4_2
[LTC_BYTE(t3
, 2)]) ^
428 (Te4_1
[LTC_BYTE(t0
, 1)]) ^
429 (Te4_0
[LTC_BYTE(t1
, 0)]) ^
433 (Te4_3
[LTC_BYTE(t3
, 3)]) ^
434 (Te4_2
[LTC_BYTE(t0
, 2)]) ^
435 (Te4_1
[LTC_BYTE(t1
, 1)]) ^
436 (Te4_0
[LTC_BYTE(t2
, 0)]) ^
443 #ifdef LTC_CLEAN_STACK
444 int ECB_ENC(const unsigned char *pt
, unsigned char *ct
, const symmetric_key
*skey
)
446 int err
= s_rijndael_ecb_encrypt(pt
, ct
, skey
);
447 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
455 Decrypts a block of text with AES
456 @param ct The input ciphertext (16 bytes)
457 @param pt The output plaintext (16 bytes)
458 @param skey The key as scheduled
459 @return CRYPT_OK if successful
461 #ifdef LTC_CLEAN_STACK
462 static int s_rijndael_ecb_decrypt(const unsigned char *ct
, unsigned char *pt
, const symmetric_key
*skey
)
464 int ECB_DEC(const unsigned char *ct
, unsigned char *pt
, const symmetric_key
*skey
)
467 ulong32 s0
, s1
, s2
, s3
, t0
, t1
, t2
, t3
;
471 LTC_ARGCHK(pt
!= NULL
);
472 LTC_ARGCHK(ct
!= NULL
);
473 LTC_ARGCHK(skey
!= NULL
);
475 Nr
= skey
->rijndael
.Nr
;
477 if (Nr
< 2 || Nr
> 16)
478 return CRYPT_INVALID_ROUNDS
;
480 rk
= skey
->rijndael
.dK
;
483 * map byte array block to cipher state
484 * and add initial round key:
486 LOAD32H(s0
, ct
); s0
^= rk
[0];
487 LOAD32H(s1
, ct
+ 4); s1
^= rk
[1];
488 LOAD32H(s2
, ct
+ 8); s2
^= rk
[2];
489 LOAD32H(s3
, ct
+ 12); s3
^= rk
[3];
491 #ifdef LTC_SMALL_CODE
495 Td0(LTC_BYTE(s0
, 3)) ^
496 Td1(LTC_BYTE(s3
, 2)) ^
497 Td2(LTC_BYTE(s2
, 1)) ^
498 Td3(LTC_BYTE(s1
, 0)) ^
501 Td0(LTC_BYTE(s1
, 3)) ^
502 Td1(LTC_BYTE(s0
, 2)) ^
503 Td2(LTC_BYTE(s3
, 1)) ^
504 Td3(LTC_BYTE(s2
, 0)) ^
507 Td0(LTC_BYTE(s2
, 3)) ^
508 Td1(LTC_BYTE(s1
, 2)) ^
509 Td2(LTC_BYTE(s0
, 1)) ^
510 Td3(LTC_BYTE(s3
, 0)) ^
513 Td0(LTC_BYTE(s3
, 3)) ^
514 Td1(LTC_BYTE(s2
, 2)) ^
515 Td2(LTC_BYTE(s1
, 1)) ^
516 Td3(LTC_BYTE(s0
, 0)) ^
521 s0
= t0
; s1
= t1
; s2
= t2
; s3
= t3
;
528 * Nr - 1 full rounds:
534 Td0(LTC_BYTE(s0
, 3)) ^
535 Td1(LTC_BYTE(s3
, 2)) ^
536 Td2(LTC_BYTE(s2
, 1)) ^
537 Td3(LTC_BYTE(s1
, 0)) ^
540 Td0(LTC_BYTE(s1
, 3)) ^
541 Td1(LTC_BYTE(s0
, 2)) ^
542 Td2(LTC_BYTE(s3
, 1)) ^
543 Td3(LTC_BYTE(s2
, 0)) ^
546 Td0(LTC_BYTE(s2
, 3)) ^
547 Td1(LTC_BYTE(s1
, 2)) ^
548 Td2(LTC_BYTE(s0
, 1)) ^
549 Td3(LTC_BYTE(s3
, 0)) ^
552 Td0(LTC_BYTE(s3
, 3)) ^
553 Td1(LTC_BYTE(s2
, 2)) ^
554 Td2(LTC_BYTE(s1
, 1)) ^
555 Td3(LTC_BYTE(s0
, 0)) ^
565 Td0(LTC_BYTE(t0
, 3)) ^
566 Td1(LTC_BYTE(t3
, 2)) ^
567 Td2(LTC_BYTE(t2
, 1)) ^
568 Td3(LTC_BYTE(t1
, 0)) ^
571 Td0(LTC_BYTE(t1
, 3)) ^
572 Td1(LTC_BYTE(t0
, 2)) ^
573 Td2(LTC_BYTE(t3
, 1)) ^
574 Td3(LTC_BYTE(t2
, 0)) ^
577 Td0(LTC_BYTE(t2
, 3)) ^
578 Td1(LTC_BYTE(t1
, 2)) ^
579 Td2(LTC_BYTE(t0
, 1)) ^
580 Td3(LTC_BYTE(t3
, 0)) ^
583 Td0(LTC_BYTE(t3
, 3)) ^
584 Td1(LTC_BYTE(t2
, 2)) ^
585 Td2(LTC_BYTE(t1
, 1)) ^
586 Td3(LTC_BYTE(t0
, 0)) ^
592 * apply last round and
593 * map cipher state to byte array block:
596 (Td4
[LTC_BYTE(t0
, 3)] & 0xff000000) ^
597 (Td4
[LTC_BYTE(t3
, 2)] & 0x00ff0000) ^
598 (Td4
[LTC_BYTE(t2
, 1)] & 0x0000ff00) ^
599 (Td4
[LTC_BYTE(t1
, 0)] & 0x000000ff) ^
603 (Td4
[LTC_BYTE(t1
, 3)] & 0xff000000) ^
604 (Td4
[LTC_BYTE(t0
, 2)] & 0x00ff0000) ^
605 (Td4
[LTC_BYTE(t3
, 1)] & 0x0000ff00) ^
606 (Td4
[LTC_BYTE(t2
, 0)] & 0x000000ff) ^
610 (Td4
[LTC_BYTE(t2
, 3)] & 0xff000000) ^
611 (Td4
[LTC_BYTE(t1
, 2)] & 0x00ff0000) ^
612 (Td4
[LTC_BYTE(t0
, 1)] & 0x0000ff00) ^
613 (Td4
[LTC_BYTE(t3
, 0)] & 0x000000ff) ^
617 (Td4
[LTC_BYTE(t3
, 3)] & 0xff000000) ^
618 (Td4
[LTC_BYTE(t2
, 2)] & 0x00ff0000) ^
619 (Td4
[LTC_BYTE(t1
, 1)] & 0x0000ff00) ^
620 (Td4
[LTC_BYTE(t0
, 0)] & 0x000000ff) ^
628 #ifdef LTC_CLEAN_STACK
629 int ECB_DEC(const unsigned char *ct
, unsigned char *pt
, const symmetric_key
*skey
)
631 int err
= s_rijndael_ecb_decrypt(ct
, pt
, skey
);
632 burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
638 Performs a self-test of the AES block cipher
639 @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
647 static const struct {
649 unsigned char key
[32], pt
[16], ct
[16];
652 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
653 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
654 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
655 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
656 { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
657 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
660 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
661 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
662 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
663 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
664 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
665 { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
666 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
669 { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
670 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
671 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
672 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
673 { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
674 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
675 { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
676 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
681 unsigned char tmp
[2][16];
684 for (i
= 0; i
< (int)(sizeof(tests
)/sizeof(tests
[0])); i
++) {
685 zeromem(&key
, sizeof(key
));
686 if ((err
= rijndael_setup(tests
[i
].key
, tests
[i
].keylen
, 0, &key
)) != CRYPT_OK
) {
690 rijndael_ecb_encrypt(tests
[i
].pt
, tmp
[0], &key
);
691 rijndael_ecb_decrypt(tmp
[0], tmp
[1], &key
);
692 if (compare_testvector(tmp
[0], 16, tests
[i
].ct
, 16, "AES Encrypt", i
) ||
693 compare_testvector(tmp
[1], 16, tests
[i
].pt
, 16, "AES Decrypt", i
)) {
694 return CRYPT_FAIL_TESTVECTOR
;
697 /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
698 for (y
= 0; y
< 16; y
++) tmp
[0][y
] = 0;
699 for (y
= 0; y
< 1000; y
++) rijndael_ecb_encrypt(tmp
[0], tmp
[0], &key
);
700 for (y
= 0; y
< 1000; y
++) rijndael_ecb_decrypt(tmp
[0], tmp
[0], &key
);
701 for (y
= 0; y
< 16; y
++) if (tmp
[0][y
] != 0) return CRYPT_FAIL_TESTVECTOR
;
707 #endif /* ENCRYPT_ONLY */
710 /** Terminate the context
711 @param skey The scheduled key
713 void ECB_DONE(symmetric_key
*skey
)
715 LTC_UNUSED_PARAM(skey
);
720 Gets suitable key size
721 @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
722 @return CRYPT_OK if the input key size is acceptable.
724 int ECB_KS(int *keysize
)
726 LTC_ARGCHK(keysize
!= NULL
);
729 return CRYPT_INVALID_KEYSIZE
;