Home | History | Annotate | Download | only in aes
      1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
      2  *
      3  * LibTomCrypt is a library that provides various cryptographic
      4  * algorithms in a highly modular and flexible manner.
      5  *
      6  * The library is free for all purposes without any express
      7  * guarantee it works.
      8  *
      9  * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com
     10  */
     11 
     12 /* AES implementation by Tom St Denis
     13  *
     14  * Derived from the Public Domain source code by
     15 
     16 ---
     17   * rijndael-alg-fst.c
     18   *
     19   * @version 3.0 (December 2000)
     20   *
     21   * Optimised ANSI C code for the Rijndael cipher (now AES)
     22   *
     23   * @author Vincent Rijmen <vincent.rijmen (at) esat.kuleuven.ac.be>
     24   * @author Antoon Bosselaers <antoon.bosselaers (at) esat.kuleuven.ac.be>
     25   * @author Paulo Barreto <paulo.barreto (at) terra.com.br>
     26 ---
     27  */
     28 /**
     29   @file aes.c
     30   Implementation of AES
     31 */
     32 
     33 #include "tomcrypt.h"
     34 
     35 #ifdef RIJNDAEL
     36 
     37 #ifndef ENCRYPT_ONLY
     38 
     39 #define SETUP    rijndael_setup
     40 #define ECB_ENC  rijndael_ecb_encrypt
     41 #define ECB_DEC  rijndael_ecb_decrypt
     42 #define ECB_DONE rijndael_done
     43 #define ECB_TEST rijndael_test
     44 #define ECB_KS   rijndael_keysize
     45 
     46 #if 0
     47 const struct ltc_cipher_descriptor rijndael_desc =
     48 {
     49     "rijndael",
     50     6,
     51     16, 32, 16, 10,
     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
     54 };
     55 #endif
     56 
     57 const struct ltc_cipher_descriptor aes_desc =
     58 {
     59     "aes",
     60     6,
     61     16, 32, 16, 10,
     62     SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
     63     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
     64 };
     65 
     66 #else
     67 
     68 #define SETUP    rijndael_enc_setup
     69 #define ECB_ENC  rijndael_enc_ecb_encrypt
     70 #define ECB_KS   rijndael_enc_keysize
     71 #define ECB_DONE rijndael_enc_done
     72 
     73 const struct ltc_cipher_descriptor rijndael_enc_desc =
     74 {
     75     "rijndael",
     76     6,
     77     16, 32, 16, 10,
     78     SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
     79     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
     80 };
     81 
     82 const struct ltc_cipher_descriptor aes_enc_desc =
     83 {
     84     "aes",
     85     6,
     86     16, 32, 16, 10,
     87     SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
     88     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
     89 };
     90 
     91 #endif
     92 
     93 #include "aes_tab.c"
     94 
     95 static ulong32 setup_mix(ulong32 temp)
     96 {
     97    return (Te4_3[byte(temp, 2)]) ^
     98           (Te4_2[byte(temp, 1)]) ^
     99           (Te4_1[byte(temp, 0)]) ^
    100           (Te4_0[byte(temp, 3)]);
    101 }
    102 
    103 #ifndef ENCRYPT_ONLY
    104 #ifdef LTC_SMALL_CODE
    105 static ulong32 setup_mix2(ulong32 temp)
    106 {
    107    return Td0(255 & Te4[byte(temp, 3)]) ^
    108           Td1(255 & Te4[byte(temp, 2)]) ^
    109           Td2(255 & Te4[byte(temp, 1)]) ^
    110           Td3(255 & Te4[byte(temp, 0)]);
    111 }
    112 #endif
    113 #endif
    114 
    115  /**
    116     Initialize the AES (Rijndael) block cipher
    117     @param key The symmetric key you wish to pass
    118     @param keylen The key length in bytes
    119     @param num_rounds The number of rounds desired (0 for default)
    120     @param skey The key in as scheduled by this function.
    121     @return CRYPT_OK if successful
    122  */
    123 int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
    124 {
    125     int i, j;
    126     ulong32 temp, *rk;
    127 #ifndef ENCRYPT_ONLY
    128     ulong32 *rrk;
    129 #endif
    130     LTC_ARGCHK(key  != NULL);
    131     LTC_ARGCHK(skey != NULL);
    132 
    133     if (keylen != 16 && keylen != 24 && keylen != 32) {
    134        return CRYPT_INVALID_KEYSIZE;
    135     }
    136 
    137     if (num_rounds != 0 && num_rounds != (10 + ((keylen/8)-2)*2)) {
    138        return CRYPT_INVALID_ROUNDS;
    139     }
    140 
    141     skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
    142 
    143     /* setup the forward key */
    144     i                 = 0;
    145     rk                = skey->rijndael.eK;
    146     LOAD32H(rk[0], key     );
    147     LOAD32H(rk[1], key +  4);
    148     LOAD32H(rk[2], key +  8);
    149     LOAD32H(rk[3], key + 12);
    150     if (keylen == 16) {
    151         j = 44;
    152         for (;;) {
    153             temp  = rk[3];
    154             rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
    155             rk[5] = rk[1] ^ rk[4];
    156             rk[6] = rk[2] ^ rk[5];
    157             rk[7] = rk[3] ^ rk[6];
    158             if (++i == 10) {
    159                break;
    160             }
    161             rk += 4;
    162         }
    163     } else if (keylen == 24) {
    164         j = 52;
    165         LOAD32H(rk[4], key + 16);
    166         LOAD32H(rk[5], key + 20);
    167         for (;;) {
    168         #ifdef _MSC_VER
    169             temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5];
    170         #else
    171             temp = rk[5];
    172         #endif
    173             rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
    174             rk[ 7] = rk[ 1] ^ rk[ 6];
    175             rk[ 8] = rk[ 2] ^ rk[ 7];
    176             rk[ 9] = rk[ 3] ^ rk[ 8];
    177             if (++i == 8) {
    178                 break;
    179             }
    180             rk[10] = rk[ 4] ^ rk[ 9];
    181             rk[11] = rk[ 5] ^ rk[10];
    182             rk += 6;
    183         }
    184     } else if (keylen == 32) {
    185         j = 60;
    186         LOAD32H(rk[4], key + 16);
    187         LOAD32H(rk[5], key + 20);
    188         LOAD32H(rk[6], key + 24);
    189         LOAD32H(rk[7], key + 28);
    190         for (;;) {
    191         #ifdef _MSC_VER
    192             temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7];
    193         #else
    194             temp = rk[7];
    195         #endif
    196             rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
    197             rk[ 9] = rk[ 1] ^ rk[ 8];
    198             rk[10] = rk[ 2] ^ rk[ 9];
    199             rk[11] = rk[ 3] ^ rk[10];
    200             if (++i == 7) {
    201                 break;
    202             }
    203             temp = rk[11];
    204             rk[12] = rk[ 4] ^ setup_mix(RORc(temp, 8));
    205             rk[13] = rk[ 5] ^ rk[12];
    206             rk[14] = rk[ 6] ^ rk[13];
    207             rk[15] = rk[ 7] ^ rk[14];
    208             rk += 8;
    209         }
    210     } else {
    211        /* this can't happen */
    212        return CRYPT_ERROR;
    213     }
    214 
    215 #ifndef ENCRYPT_ONLY
    216     /* setup the inverse key now */
    217     rk   = skey->rijndael.dK;
    218     rrk  = skey->rijndael.eK + j - 4;
    219 
    220     /* apply the inverse MixColumn transform to all round keys but the first and the last: */
    221     /* copy first */
    222     *rk++ = *rrk++;
    223     *rk++ = *rrk++;
    224     *rk++ = *rrk++;
    225     *rk   = *rrk;
    226     rk -= 3; rrk -= 3;
    227 
    228     for (i = 1; i < skey->rijndael.Nr; i++) {
    229         rrk -= 4;
    230         rk  += 4;
    231     #ifdef LTC_SMALL_CODE
    232         temp = rrk[0];
    233         rk[0] = setup_mix2(temp);
    234         temp = rrk[1];
    235         rk[1] = setup_mix2(temp);
    236         temp = rrk[2];
    237         rk[2] = setup_mix2(temp);
    238         temp = rrk[3];
    239         rk[3] = setup_mix2(temp);
    240      #else
    241         temp = rrk[0];
    242         rk[0] =
    243             Tks0[byte(temp, 3)] ^
    244             Tks1[byte(temp, 2)] ^
    245             Tks2[byte(temp, 1)] ^
    246             Tks3[byte(temp, 0)];
    247         temp = rrk[1];
    248         rk[1] =
    249             Tks0[byte(temp, 3)] ^
    250             Tks1[byte(temp, 2)] ^
    251             Tks2[byte(temp, 1)] ^
    252             Tks3[byte(temp, 0)];
    253         temp = rrk[2];
    254         rk[2] =
    255             Tks0[byte(temp, 3)] ^
    256             Tks1[byte(temp, 2)] ^
    257             Tks2[byte(temp, 1)] ^
    258             Tks3[byte(temp, 0)];
    259         temp = rrk[3];
    260         rk[3] =
    261             Tks0[byte(temp, 3)] ^
    262             Tks1[byte(temp, 2)] ^
    263             Tks2[byte(temp, 1)] ^
    264             Tks3[byte(temp, 0)];
    265       #endif
    266 
    267     }
    268 
    269     /* copy last */
    270     rrk -= 4;
    271     rk  += 4;
    272     *rk++ = *rrk++;
    273     *rk++ = *rrk++;
    274     *rk++ = *rrk++;
    275     *rk   = *rrk;
    276 #endif /* ENCRYPT_ONLY */
    277 
    278     return CRYPT_OK;
    279 }
    280 
    281 /**
    282   Encrypts a block of text with AES
    283   @param pt The input plaintext (16 bytes)
    284   @param ct The output ciphertext (16 bytes)
    285   @param skey The key as scheduled
    286   @return CRYPT_OK if successful
    287 */
    288 #ifdef LTC_CLEAN_STACK
    289 static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
    290 #else
    291 int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
    292 #endif
    293 {
    294     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
    295     int Nr, r;
    296 
    297     LTC_ARGCHK(pt != NULL);
    298     LTC_ARGCHK(ct != NULL);
    299     LTC_ARGCHK(skey != NULL);
    300 
    301     Nr = skey->rijndael.Nr;
    302     rk = skey->rijndael.eK;
    303 
    304     /*
    305      * map byte array block to cipher state
    306      * and add initial round key:
    307      */
    308     LOAD32H(s0, pt      ); s0 ^= rk[0];
    309     LOAD32H(s1, pt  +  4); s1 ^= rk[1];
    310     LOAD32H(s2, pt  +  8); s2 ^= rk[2];
    311     LOAD32H(s3, pt  + 12); s3 ^= rk[3];
    312 
    313 #ifdef LTC_SMALL_CODE
    314 
    315     for (r = 0; ; r++) {
    316         rk += 4;
    317         t0 =
    318             Te0(byte(s0, 3)) ^
    319             Te1(byte(s1, 2)) ^
    320             Te2(byte(s2, 1)) ^
    321             Te3(byte(s3, 0)) ^
    322             rk[0];
    323         t1 =
    324             Te0(byte(s1, 3)) ^
    325             Te1(byte(s2, 2)) ^
    326             Te2(byte(s3, 1)) ^
    327             Te3(byte(s0, 0)) ^
    328             rk[1];
    329         t2 =
    330             Te0(byte(s2, 3)) ^
    331             Te1(byte(s3, 2)) ^
    332             Te2(byte(s0, 1)) ^
    333             Te3(byte(s1, 0)) ^
    334             rk[2];
    335         t3 =
    336             Te0(byte(s3, 3)) ^
    337             Te1(byte(s0, 2)) ^
    338             Te2(byte(s1, 1)) ^
    339             Te3(byte(s2, 0)) ^
    340             rk[3];
    341         if (r == Nr-2) {
    342            break;
    343         }
    344         s0 = t0; s1 = t1; s2 = t2; s3 = t3;
    345     }
    346     rk += 4;
    347 
    348 #else
    349 
    350     /*
    351      * Nr - 1 full rounds:
    352      */
    353     r = Nr >> 1;
    354     for (;;) {
    355         t0 =
    356             Te0(byte(s0, 3)) ^
    357             Te1(byte(s1, 2)) ^
    358             Te2(byte(s2, 1)) ^
    359             Te3(byte(s3, 0)) ^
    360             rk[4];
    361         t1 =
    362             Te0(byte(s1, 3)) ^
    363             Te1(byte(s2, 2)) ^
    364             Te2(byte(s3, 1)) ^
    365             Te3(byte(s0, 0)) ^
    366             rk[5];
    367         t2 =
    368             Te0(byte(s2, 3)) ^
    369             Te1(byte(s3, 2)) ^
    370             Te2(byte(s0, 1)) ^
    371             Te3(byte(s1, 0)) ^
    372             rk[6];
    373         t3 =
    374             Te0(byte(s3, 3)) ^
    375             Te1(byte(s0, 2)) ^
    376             Te2(byte(s1, 1)) ^
    377             Te3(byte(s2, 0)) ^
    378             rk[7];
    379 
    380         rk += 8;
    381         if (--r == 0) {
    382             break;
    383         }
    384 
    385         s0 =
    386             Te0(byte(t0, 3)) ^
    387             Te1(byte(t1, 2)) ^
    388             Te2(byte(t2, 1)) ^
    389             Te3(byte(t3, 0)) ^
    390             rk[0];
    391         s1 =
    392             Te0(byte(t1, 3)) ^
    393             Te1(byte(t2, 2)) ^
    394             Te2(byte(t3, 1)) ^
    395             Te3(byte(t0, 0)) ^
    396             rk[1];
    397         s2 =
    398             Te0(byte(t2, 3)) ^
    399             Te1(byte(t3, 2)) ^
    400             Te2(byte(t0, 1)) ^
    401             Te3(byte(t1, 0)) ^
    402             rk[2];
    403         s3 =
    404             Te0(byte(t3, 3)) ^
    405             Te1(byte(t0, 2)) ^
    406             Te2(byte(t1, 1)) ^
    407             Te3(byte(t2, 0)) ^
    408             rk[3];
    409     }
    410 
    411 #endif
    412 
    413     /*
    414      * apply last round and
    415      * map cipher state to byte array block:
    416      */
    417     s0 =
    418         (Te4_3[byte(t0, 3)]) ^
    419         (Te4_2[byte(t1, 2)]) ^
    420         (Te4_1[byte(t2, 1)]) ^
    421         (Te4_0[byte(t3, 0)]) ^
    422         rk[0];
    423     STORE32H(s0, ct);
    424     s1 =
    425         (Te4_3[byte(t1, 3)]) ^
    426         (Te4_2[byte(t2, 2)]) ^
    427         (Te4_1[byte(t3, 1)]) ^
    428         (Te4_0[byte(t0, 0)]) ^
    429         rk[1];
    430     STORE32H(s1, ct+4);
    431     s2 =
    432         (Te4_3[byte(t2, 3)]) ^
    433         (Te4_2[byte(t3, 2)]) ^
    434         (Te4_1[byte(t0, 1)]) ^
    435         (Te4_0[byte(t1, 0)]) ^
    436         rk[2];
    437     STORE32H(s2, ct+8);
    438     s3 =
    439         (Te4_3[byte(t3, 3)]) ^
    440         (Te4_2[byte(t0, 2)]) ^
    441         (Te4_1[byte(t1, 1)]) ^
    442         (Te4_0[byte(t2, 0)]) ^
    443         rk[3];
    444     STORE32H(s3, ct+12);
    445 
    446     return CRYPT_OK;
    447 }
    448 
    449 #ifdef LTC_CLEAN_STACK
    450 int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
    451 {
    452    int err = _rijndael_ecb_encrypt(pt, ct, skey);
    453    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
    454    return err;
    455 }
    456 #endif
    457 
    458 #ifndef ENCRYPT_ONLY
    459 
    460 /**
    461   Decrypts a block of text with AES
    462   @param ct The input ciphertext (16 bytes)
    463   @param pt The output plaintext (16 bytes)
    464   @param skey The key as scheduled
    465   @return CRYPT_OK if successful
    466 */
    467 #ifdef LTC_CLEAN_STACK
    468 static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
    469 #else
    470 int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
    471 #endif
    472 {
    473     ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
    474     int Nr, r;
    475 
    476     LTC_ARGCHK(pt != NULL);
    477     LTC_ARGCHK(ct != NULL);
    478     LTC_ARGCHK(skey != NULL);
    479 
    480     Nr = skey->rijndael.Nr;
    481     rk = skey->rijndael.dK;
    482 
    483     /*
    484      * map byte array block to cipher state
    485      * and add initial round key:
    486      */
    487     LOAD32H(s0, ct      ); s0 ^= rk[0];
    488     LOAD32H(s1, ct  +  4); s1 ^= rk[1];
    489     LOAD32H(s2, ct  +  8); s2 ^= rk[2];
    490     LOAD32H(s3, ct  + 12); s3 ^= rk[3];
    491 
    492 #ifdef LTC_SMALL_CODE
    493     for (r = 0; ; r++) {
    494         rk += 4;
    495         t0 =
    496             Td0(byte(s0, 3)) ^
    497             Td1(byte(s3, 2)) ^
    498             Td2(byte(s2, 1)) ^
    499             Td3(byte(s1, 0)) ^
    500             rk[0];
    501         t1 =
    502             Td0(byte(s1, 3)) ^
    503             Td1(byte(s0, 2)) ^
    504             Td2(byte(s3, 1)) ^
    505             Td3(byte(s2, 0)) ^
    506             rk[1];
    507         t2 =
    508             Td0(byte(s2, 3)) ^
    509             Td1(byte(s1, 2)) ^
    510             Td2(byte(s0, 1)) ^
    511             Td3(byte(s3, 0)) ^
    512             rk[2];
    513         t3 =
    514             Td0(byte(s3, 3)) ^
    515             Td1(byte(s2, 2)) ^
    516             Td2(byte(s1, 1)) ^
    517             Td3(byte(s0, 0)) ^
    518             rk[3];
    519         if (r == Nr-2) {
    520            break;
    521         }
    522         s0 = t0; s1 = t1; s2 = t2; s3 = t3;
    523     }
    524     rk += 4;
    525 
    526 #else
    527 
    528     /*
    529      * Nr - 1 full rounds:
    530      */
    531     r = Nr >> 1;
    532     for (;;) {
    533 
    534         t0 =
    535             Td0(byte(s0, 3)) ^
    536             Td1(byte(s3, 2)) ^
    537             Td2(byte(s2, 1)) ^
    538             Td3(byte(s1, 0)) ^
    539             rk[4];
    540         t1 =
    541             Td0(byte(s1, 3)) ^
    542             Td1(byte(s0, 2)) ^
    543             Td2(byte(s3, 1)) ^
    544             Td3(byte(s2, 0)) ^
    545             rk[5];
    546         t2 =
    547             Td0(byte(s2, 3)) ^
    548             Td1(byte(s1, 2)) ^
    549             Td2(byte(s0, 1)) ^
    550             Td3(byte(s3, 0)) ^
    551             rk[6];
    552         t3 =
    553             Td0(byte(s3, 3)) ^
    554             Td1(byte(s2, 2)) ^
    555             Td2(byte(s1, 1)) ^
    556             Td3(byte(s0, 0)) ^
    557             rk[7];
    558 
    559         rk += 8;
    560         if (--r == 0) {
    561             break;
    562         }
    563 
    564 
    565         s0 =
    566             Td0(byte(t0, 3)) ^
    567             Td1(byte(t3, 2)) ^
    568             Td2(byte(t2, 1)) ^
    569             Td3(byte(t1, 0)) ^
    570             rk[0];
    571         s1 =
    572             Td0(byte(t1, 3)) ^
    573             Td1(byte(t0, 2)) ^
    574             Td2(byte(t3, 1)) ^
    575             Td3(byte(t2, 0)) ^
    576             rk[1];
    577         s2 =
    578             Td0(byte(t2, 3)) ^
    579             Td1(byte(t1, 2)) ^
    580             Td2(byte(t0, 1)) ^
    581             Td3(byte(t3, 0)) ^
    582             rk[2];
    583         s3 =
    584             Td0(byte(t3, 3)) ^
    585             Td1(byte(t2, 2)) ^
    586             Td2(byte(t1, 1)) ^
    587             Td3(byte(t0, 0)) ^
    588             rk[3];
    589     }
    590 #endif
    591 
    592     /*
    593      * apply last round and
    594      * map cipher state to byte array block:
    595      */
    596     s0 =
    597         (Td4[byte(t0, 3)] & 0xff000000) ^
    598         (Td4[byte(t3, 2)] & 0x00ff0000) ^
    599         (Td4[byte(t2, 1)] & 0x0000ff00) ^
    600         (Td4[byte(t1, 0)] & 0x000000ff) ^
    601         rk[0];
    602     STORE32H(s0, pt);
    603     s1 =
    604         (Td4[byte(t1, 3)] & 0xff000000) ^
    605         (Td4[byte(t0, 2)] & 0x00ff0000) ^
    606         (Td4[byte(t3, 1)] & 0x0000ff00) ^
    607         (Td4[byte(t2, 0)] & 0x000000ff) ^
    608         rk[1];
    609     STORE32H(s1, pt+4);
    610     s2 =
    611         (Td4[byte(t2, 3)] & 0xff000000) ^
    612         (Td4[byte(t1, 2)] & 0x00ff0000) ^
    613         (Td4[byte(t0, 1)] & 0x0000ff00) ^
    614         (Td4[byte(t3, 0)] & 0x000000ff) ^
    615         rk[2];
    616     STORE32H(s2, pt+8);
    617     s3 =
    618         (Td4[byte(t3, 3)] & 0xff000000) ^
    619         (Td4[byte(t2, 2)] & 0x00ff0000) ^
    620         (Td4[byte(t1, 1)] & 0x0000ff00) ^
    621         (Td4[byte(t0, 0)] & 0x000000ff) ^
    622         rk[3];
    623     STORE32H(s3, pt+12);
    624 
    625     return CRYPT_OK;
    626 }
    627 
    628 
    629 #ifdef LTC_CLEAN_STACK
    630 int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
    631 {
    632    int err = _rijndael_ecb_decrypt(ct, pt, skey);
    633    burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
    634    return err;
    635 }
    636 #endif
    637 
    638 /**
    639   Performs a self-test of the AES block cipher
    640   @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
    641 */
    642 int ECB_TEST(void)
    643 {
    644  #ifndef LTC_TEST
    645     return CRYPT_NOP;
    646  #else
    647  int err;
    648  static const struct {
    649      int keylen;
    650      unsigned char key[32], pt[16], ct[16];
    651  } tests[] = {
    652     { 16,
    653       { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    654         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
    655       { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    656         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
    657       { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
    658         0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
    659     }, {
    660       24,
    661       { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    662         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    663         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
    664       { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    665         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
    666       { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
    667         0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
    668     }, {
    669       32,
    670       { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    671         0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
    672         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
    673         0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
    674       { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    675         0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
    676       { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
    677         0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
    678     }
    679  };
    680 
    681  symmetric_key key;
    682  unsigned char tmp[2][16];
    683  int i, y;
    684 
    685  for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
    686     zeromem(&key, sizeof(key));
    687     if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
    688        return err;
    689     }
    690 
    691     rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
    692     rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
    693     if (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
    694 #if 0
    695        printf("\n\nTest %d failed\n", i);
    696        if (XMEMCMP(tmp[0], tests[i].ct, 16)) {
    697           printf("CT: ");
    698           for (i = 0; i < 16; i++) {
    699              printf("%02x ", tmp[0][i]);
    700           }
    701           printf("\n");
    702        } else {
    703           printf("PT: ");
    704           for (i = 0; i < 16; i++) {
    705              printf("%02x ", tmp[1][i]);
    706           }
    707           printf("\n");
    708        }
    709 #endif
    710         return CRYPT_FAIL_TESTVECTOR;
    711     }
    712 
    713       /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
    714       for (y = 0; y < 16; y++) tmp[0][y] = 0;
    715       for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
    716       for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
    717       for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
    718  }
    719  return CRYPT_OK;
    720  #endif
    721 }
    722 
    723 #endif /* ENCRYPT_ONLY */
    724 
    725 
    726 /** Terminate the context
    727    @param skey    The scheduled key
    728 */
    729 void ECB_DONE(symmetric_key *skey)
    730 {
    731 }
    732 
    733 
    734 /**
    735   Gets suitable key size
    736   @param keysize [in/out] The length of the recommended key (in bytes).  This function will store the suitable size back in this variable.
    737   @return CRYPT_OK if the input key size is acceptable.
    738 */
    739 int ECB_KS(int *keysize)
    740 {
    741    LTC_ARGCHK(keysize != NULL);
    742 
    743    if (*keysize < 16)
    744       return CRYPT_INVALID_KEYSIZE;
    745    if (*keysize < 24) {
    746       *keysize = 16;
    747       return CRYPT_OK;
    748    } else if (*keysize < 32) {
    749       *keysize = 24;
    750       return CRYPT_OK;
    751    } else {
    752       *keysize = 32;
    753       return CRYPT_OK;
    754    }
    755 }
    756 
    757 #endif
    758 
    759 
    760 /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/aes/aes.c,v $ */
    761 /* $Revision: 1.14 $ */
    762 /* $Date: 2006/11/08 23:01:06 $ */
    763