📄 aes.c
字号:
/* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * gurantee it works. * * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org *//* AES implementation by Tom St Denis * * Derived from the Public Domain source code by--- * rijndael-alg-fst.c * * @version 3.0 (December 2000) * * Optimised ANSI C code for the Rijndael cipher (now AES) * * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be> * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be> * @author Paulo Barreto <paulo.barreto@terra.com.br>--- modified by Stefan Scherrer to allow compilation under DDK */#include "tom.h"#define byte(x, n) ((unsigned char)((x) >> (8 * (n))))#if 0const struct _cipher_descriptor rijndael_desc ={ "rijndael", 6, 16, 32, 16, 10, &rijndael_setup, &rijndael_ecb_encrypt, &rijndael_ecb_decrypt, &rijndael_test, &rijndael_keysize};const struct _cipher_descriptor aes_desc ={ "aes", 6, 16, 32, 16, 10, &rijndael_setup, &rijndael_ecb_encrypt, &rijndael_ecb_decrypt, &rijndael_test, &rijndael_keysize};#endif#include "aes_tab.c"int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey){ int i, j; ulong32 temp, *rk, *rrk; _ARGCHK(key != NULL); _ARGCHK(skey != NULL); if (keylen != 16 && keylen != 24 && keylen != 32) { return CRYPT_INVALID_KEYSIZE; } if (rounds != 0 && rounds != (10 + ((keylen/8)-2)*2)) { return CRYPT_INVALID_ROUNDS; } skey->rijndael.Nr = 10 + ((keylen/8)-2)*2; /* setup the forward key */ i = 0; rk = skey->rijndael.eK; LOAD32H(rk[0], key ); LOAD32H(rk[1], key + 4); LOAD32H(rk[2], key + 8); LOAD32H(rk[3], key + 12); if (keylen == 16) { j = 44; for (;;) { temp = rk[3]; rk[4] = rk[0] ^ (Te4_3[byte(temp, 2)]) ^ (Te4_2[byte(temp, 1)]) ^ (Te4_1[byte(temp, 0)]) ^ (Te4_0[byte(temp, 3)]) ^ rcon[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; rk[7] = rk[3] ^ rk[6]; if (++i == 10) { break; } rk += 4; } } else if (keylen == 24) { j = 52; LOAD32H(rk[4], key + 16); LOAD32H(rk[5], key + 20); for (;;) { #ifdef _MSC_VER temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5]; #else temp = rk[5]; #endif rk[ 6] = rk[ 0] ^ (Te4_3[byte(temp, 2)]) ^ (Te4_2[byte(temp, 1)]) ^ (Te4_1[byte(temp, 0)]) ^ (Te4_0[byte(temp, 3)]) ^ rcon[i]; rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 8] = rk[ 2] ^ rk[ 7]; rk[ 9] = rk[ 3] ^ rk[ 8]; if (++i == 8) { break; } rk[10] = rk[ 4] ^ rk[ 9]; rk[11] = rk[ 5] ^ rk[10]; rk += 6; } } else if (keylen == 32) { j = 60; LOAD32H(rk[4], key + 16); LOAD32H(rk[5], key + 20); LOAD32H(rk[6], key + 24); LOAD32H(rk[7], key + 28); for (;;) { #ifdef _MSC_VER temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7]; #else temp = rk[7]; #endif rk[ 8] = rk[ 0] ^ (Te4_3[byte(temp, 2)]) ^ (Te4_2[byte(temp, 1)]) ^ (Te4_1[byte(temp, 0)]) ^ (Te4_0[byte(temp, 3)]) ^ rcon[i]; rk[ 9] = rk[ 1] ^ rk[ 8]; rk[10] = rk[ 2] ^ rk[ 9]; rk[11] = rk[ 3] ^ rk[10]; if (++i == 7) { break; } temp = rk[11]; rk[12] = rk[ 4] ^ (Te4_3[byte(temp, 3)]) ^ (Te4_2[byte(temp, 2)]) ^ (Te4_1[byte(temp, 1)]) ^ (Te4_0[byte(temp, 0)]); rk[13] = rk[ 5] ^ rk[12]; rk[14] = rk[ 6] ^ rk[13]; rk[15] = rk[ 7] ^ rk[14]; rk += 8; } } else { /* this can't happen */ j = 4; } /* setup the inverse key now */ rk = skey->rijndael.dK; rrk = skey->rijndael.eK + j - 4; /* apply the inverse MixColumn transform to all round keys but the first and the last: */ /* copy first */ *rk++ = *rrk++; *rk++ = *rrk++; *rk++ = *rrk++; *rk = *rrk; rk -= 3; rrk -= 3; for (i = 1; i < skey->rijndael.Nr; i++) { rrk -= 4; rk += 4; #ifdef SMALL_CODE temp = rrk[0]; rk[0] = Td0[255 & Te4[byte(temp, 3)]] ^ Td1[255 & Te4[byte(temp, 2)]] ^ Td2[255 & Te4[byte(temp, 1)]] ^ Td3[255 & Te4[byte(temp, 0)]]; temp = rrk[1]; rk[1] = Td0[255 & Te4[byte(temp, 3)]] ^ Td1[255 & Te4[byte(temp, 2)]] ^ Td2[255 & Te4[byte(temp, 1)]] ^ Td3[255 & Te4[byte(temp, 0)]]; temp = rrk[2]; rk[2] = Td0[255 & Te4[byte(temp, 3)]] ^ Td1[255 & Te4[byte(temp, 2)]] ^ Td2[255 & Te4[byte(temp, 1)]] ^ Td3[255 & Te4[byte(temp, 0)]]; temp = rrk[3]; rk[3] = Td0[255 & Te4[byte(temp, 3)]] ^ Td1[255 & Te4[byte(temp, 2)]] ^ Td2[255 & Te4[byte(temp, 1)]] ^ Td3[255 & Te4[byte(temp, 0)]]; #else temp = rrk[0]; rk[0] = Tks0[byte(temp, 3)] ^ Tks1[byte(temp, 2)] ^ Tks2[byte(temp, 1)] ^ Tks3[byte(temp, 0)]; temp = rrk[1]; rk[1] = Tks0[byte(temp, 3)] ^ Tks1[byte(temp, 2)] ^ Tks2[byte(temp, 1)] ^ Tks3[byte(temp, 0)]; temp = rrk[2]; rk[2] = Tks0[byte(temp, 3)] ^ Tks1[byte(temp, 2)] ^ Tks2[byte(temp, 1)] ^ Tks3[byte(temp, 0)]; temp = rrk[3]; rk[3] = Tks0[byte(temp, 3)] ^ Tks1[byte(temp, 2)] ^ Tks2[byte(temp, 1)] ^ Tks3[byte(temp, 0)]; #endif } /* copy last */ rrk -= 4; rk += 4; *rk++ = *rrk++; *rk++ = *rrk++; *rk++ = *rrk++; *rk = *rrk; return CRYPT_OK;}#ifdef CLEAN_STACKstatic void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)#elsevoid rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)#endif{ ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; int Nr, r; _ARGCHK(pt != NULL); _ARGCHK(ct != NULL); _ARGCHK(skey != NULL); Nr = skey->rijndael.Nr; rk = skey->rijndael.eK; /* * map byte array block to cipher state * and add initial round key: */ LOAD32H(s0, pt ); s0 ^= rk[0]; LOAD32H(s1, pt + 4); s1 ^= rk[1]; LOAD32H(s2, pt + 8); s2 ^= rk[2]; LOAD32H(s3, pt + 12); s3 ^= rk[3]; /* * Nr - 1 full rounds: */ r = Nr >> 1; for (;;) { t0 = Te0[byte(s0, 3)] ^ Te1[byte(s1, 2)] ^ Te2[byte(s2, 1)] ^ Te3[byte(s3, 0)] ^ rk[4]; t1 = Te0[byte(s1, 3)] ^ Te1[byte(s2, 2)] ^ Te2[byte(s3, 1)] ^ Te3[byte(s0, 0)] ^ rk[5]; t2 = Te0[byte(s2, 3)] ^ Te1[byte(s3, 2)] ^ Te2[byte(s0, 1)] ^ Te3[byte(s1, 0)] ^ rk[6]; t3 = Te0[byte(s3, 3)] ^ Te1[byte(s0, 2)] ^ Te2[byte(s1, 1)] ^
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -