added libtomcrypt-0.85

This commit is contained in:
Tom St Denis 2003-06-11 21:10:22 +00:00 committed by Steffen Jaeckel
parent d6071c6267
commit f5331baa9f
28 changed files with 7513 additions and 8092 deletions

783
aes.c
View File

@ -1,19 +1,19 @@
/* This is an independent implementation of the encryption algorithm: */ /* AES implementation by Tom St Denis
/* */ *
/* RIJNDAEL by Joan Daemen and Vincent Rijmen */ * Derived from the Public Domain source code by
/* */
/* which is a candidate algorithm in the Advanced Encryption Standard */ ---
/* programme of the US National Institute of Standards and Technology. */ * rijndael-alg-fst.c
/* */ *
/* Copyright in this implementation is held by Dr B R Gladman but I */ * @version 3.0 (December 2000)
/* hereby give permission for its free direct or derivative use subject */ *
/* to acknowledgment of its origin and compliance with any conditions */ * Optimised ANSI C code for the Rijndael cipher (now AES)
/* that the originators of the algorithm place on its exploitation. */ *
/* */ * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */ * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
* @author Paulo Barreto <paulo.barreto@terra.com.br>
---
/* This code has been modified by Tom St Denis for libtomcrypt.a */ */
#include "mycrypt.h" #include "mycrypt.h"
@ -45,285 +45,517 @@ const struct _cipher_descriptor aes_desc =
#include "aes_tab.c" #include "aes_tab.c"
#define byte(x, y) (((x)>>(8*(y)))&255) int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
#define f_rn(bo, bi, n, k) \
bo[n] = ft_tab[0][byte(bi[n],0)] ^ \
ft_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
ft_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
ft_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
#define i_rn(bo, bi, n, k) \
bo[n] = it_tab[0][byte(bi[n],0)] ^ \
it_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
it_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
it_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
#define ls_box(x) \
( fl_tab[0][byte(x, 0)] ^ \
fl_tab[1][byte(x, 1)] ^ \
fl_tab[2][byte(x, 2)] ^ \
fl_tab[3][byte(x, 3)] )
#define f_rl(bo, bi, n, k) \
bo[n] = fl_tab[0][byte(bi[n],0)] ^ \
fl_tab[1][byte(bi[(n + 1) & 3],1)] ^ \
fl_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
fl_tab[3][byte(bi[(n + 3) & 3],3)] ^ *(k + n)
#define i_rl(bo, bi, n, k) \
bo[n] = il_tab[0][byte(bi[n],0)] ^ \
il_tab[1][byte(bi[(n + 3) & 3],1)] ^ \
il_tab[2][byte(bi[(n + 2) & 3],2)] ^ \
il_tab[3][byte(bi[(n + 1) & 3],3)] ^ *(k + n)
#define star_x(x) (((x) & 0x7f7f7f7fUL) << 1) ^ ((((x) & 0x80808080UL) >> 7) * 0x1bUL)
#define imix_col(y,x) \
u = star_x(x); \
v = star_x(u); \
w = star_x(v); \
t = w ^ (x); \
(y) = u ^ v ^ w; \
(y) ^= ROR(u ^ t, 8) ^ \
ROR(v ^ t, 16) ^ \
ROR(t,24)
#ifdef CLEAN_STACK
static int _rijndael_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
#else
int rijndael_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
#endif
{ {
unsigned long t, u, v, w, in_key[8]; int i = 0, j;
int i, k_len; unsigned long temp, *rk;
/* check arguments */ _ARGCHK(key != NULL);
_ARGCHK(key != NULL);
_ARGCHK(skey != NULL); _ARGCHK(skey != NULL);
if (numrounds == 0) {
numrounds = 10 + (2 * ((keylen/8)-2));
}
if (keylen != 16 && keylen != 24 && keylen != 32) { if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE; return CRYPT_INVALID_KEYSIZE;
} }
if (numrounds != (10 + (2 * ((keylen/8)-2)))) { if (rounds != 0 && rounds != (10 + ((keylen/8)-2)*2)) {
return CRYPT_INVALID_ROUNDS; return CRYPT_INVALID_ROUNDS;
} }
k_len = keylen / 4; skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
for (i = 0; i < k_len; i++) {
LOAD32L(in_key[i], key+(4*i)); /* setup the forward key */
} rk = skey->rijndael.eK;
LOAD32H(rk[0], key );
skey->rijndael.k_len = k_len; LOAD32H(rk[1], key + 4);
skey->rijndael.eK[0] = in_key[0]; skey->rijndael.eK[1] = in_key[1]; LOAD32H(rk[2], key + 8);
skey->rijndael.eK[2] = in_key[2]; skey->rijndael.eK[3] = in_key[3]; LOAD32H(rk[3], key + 12);
if (keylen == 16) {
switch(k_len) { for (;;) {
case 4: t = skey->rijndael.eK[3]; temp = rk[3];
for(i = 0; i < 10; ++i) { rk[4] = rk[0] ^
t = ls_box(ROR(t, 8)) ^ rco_tab[i]; (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
t ^= skey->rijndael.eK[4 * i]; skey->rijndael.eK[4 * i + 4] = t; (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
t ^= skey->rijndael.eK[4 * i + 1]; skey->rijndael.eK[4 * i + 5] = t; (Te4[(temp ) & 0xff] & 0x0000ff00) ^
t ^= skey->rijndael.eK[4 * i + 2]; skey->rijndael.eK[4 * i + 6] = t; (Te4[(temp >> 24) ] & 0x000000ff) ^
t ^= skey->rijndael.eK[4 * i + 3]; skey->rijndael.eK[4 * i + 7] = t; rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
if (++i == 10) {
break;
} }
break; rk += 4;
case 6: skey->rijndael.eK[4] = in_key[4]; }
t = skey->rijndael.eK[5] = in_key[5]; } else if (keylen == 24) {
for(i = 0; i < 8; ++i) { LOAD32H(rk[4], key + 16);
t = ls_box(ROR(t, 8)) ^ rco_tab[i]; LOAD32H(rk[5], key + 20);
t ^= skey->rijndael.eK[6 * i]; skey->rijndael.eK[6 * i + 6] = t; for (;;) {
t ^= skey->rijndael.eK[6 * i + 1]; skey->rijndael.eK[6 * i + 7] = t; temp = rk[ 5];
t ^= skey->rijndael.eK[6 * i + 2]; skey->rijndael.eK[6 * i + 8] = t; rk[ 6] = rk[ 0] ^
t ^= skey->rijndael.eK[6 * i + 3]; skey->rijndael.eK[6 * i + 9] = t; (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
t ^= skey->rijndael.eK[6 * i + 4]; skey->rijndael.eK[6 * i + 10] = t; (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
t ^= skey->rijndael.eK[6 * i + 5]; skey->rijndael.eK[6 * i + 11] = t; (Te4[(temp ) & 0xff] & 0x0000ff00) ^
(Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8];
if (++i == 8) {
break;
} }
break; rk[10] = rk[ 4] ^ rk[ 9];
case 8: skey->rijndael.eK[4] = in_key[4]; rk[11] = rk[ 5] ^ rk[10];
skey->rijndael.eK[5] = in_key[5]; rk += 6;
skey->rijndael.eK[6] = in_key[6]; }
t = skey->rijndael.eK[7] = in_key[7]; } else if (keylen == 32) {
for(i = 0; i < 7; ++i) { LOAD32H(rk[4], key + 16);
t = ls_box(ROR(t, 8)) ^ rco_tab[i]; LOAD32H(rk[5], key + 20);
t ^= skey->rijndael.eK[8 * i]; skey->rijndael.eK[8 * i + 8] = t; LOAD32H(rk[6], key + 24);
t ^= skey->rijndael.eK[8 * i + 1]; skey->rijndael.eK[8 * i + 9] = t; LOAD32H(rk[7], key + 28);
t ^= skey->rijndael.eK[8 * i + 2]; skey->rijndael.eK[8 * i + 10] = t; for (;;) {
t ^= skey->rijndael.eK[8 * i + 3]; skey->rijndael.eK[8 * i + 11] = t; temp = rk[ 7];
rk[ 8] = rk[ 0] ^
t = skey->rijndael.eK[8 * i + 4] ^ ls_box(t); skey->rijndael.eK[8 * i + 12] = t; (Te4[(temp >> 16) & 0xff] & 0xff000000) ^
t ^= skey->rijndael.eK[8 * i + 5]; skey->rijndael.eK[8 * i + 13] = t; (Te4[(temp >> 8) & 0xff] & 0x00ff0000) ^
t ^= skey->rijndael.eK[8 * i + 6]; skey->rijndael.eK[8 * i + 14] = t; (Te4[(temp ) & 0xff] & 0x0000ff00) ^
t ^= skey->rijndael.eK[8 * i + 7]; skey->rijndael.eK[8 * i + 15] = t; (Te4[(temp >> 24) ] & 0x000000ff) ^
rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10];
if (++i == 7) {
break;
} }
break; temp = rk[11];
rk[12] = rk[ 4] ^
(Te4[(temp >> 24) ] & 0xff000000) ^
(Te4[(temp >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(temp >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(temp ) & 0xff] & 0x000000ff);
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
rk += 8;
}
} }
skey->rijndael.dK[0] = skey->rijndael.eK[0]; /* setup the inverse key now */
skey->rijndael.dK[1] = skey->rijndael.eK[1]; memcpy(skey->rijndael.dK, skey->rijndael.eK, sizeof(skey->rijndael.eK));
skey->rijndael.dK[2] = skey->rijndael.eK[2]; rk = skey->rijndael.dK;
skey->rijndael.dK[3] = skey->rijndael.eK[3];
for(i = 4; i < 4 * k_len + 24; ++i) { for (i = 0, j = 4*skey->rijndael.Nr; i < j; i += 4, j -= 4) {
imix_col(skey->rijndael.dK[i], skey->rijndael.eK[i]); temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
} }
return CRYPT_OK; /* apply the inverse MixColumn transform to all round keys but the first and the last: */
}; for (i = 1; i < skey->rijndael.Nr; i++) {
rk += 4;
#ifdef CLEAN_STACK rk[0] =
int rijndael_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) Td0[Te4[(rk[0] >> 24) ] & 0xff] ^
{ Td1[Te4[(rk[0] >> 16) & 0xff] & 0xff] ^
int x; Td2[Te4[(rk[0] >> 8) & 0xff] & 0xff] ^
x = _rijndael_setup(key, keylen, numrounds, skey); Td3[Te4[(rk[0] ) & 0xff] & 0xff];
burn_stack(sizeof(unsigned long) * 12 + sizeof(int) * 2); rk[1] =
return x; Td0[Te4[(rk[1] >> 24) ] & 0xff] ^
Td1[Te4[(rk[1] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[1] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[1] ) & 0xff] & 0xff];
rk[2] =
Td0[Te4[(rk[2] >> 24) ] & 0xff] ^
Td1[Te4[(rk[2] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[2] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[2] ) & 0xff] & 0xff];
rk[3] =
Td0[Te4[(rk[3] >> 24) ] & 0xff] ^
Td1[Te4[(rk[3] >> 16) & 0xff] & 0xff] ^
Td2[Te4[(rk[3] >> 8) & 0xff] & 0xff] ^
Td3[Te4[(rk[3] ) & 0xff] & 0xff];
}
return CRYPT_OK;
} }
#endif
/* encrypt a block of text */ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
#define f_nround(bo, bi, k) \ unsigned long s0, s1, s2, s3, t0, t1, t2, t3, *rk;
f_rn(bo, bi, 0, k); \ int Nr;
f_rn(bo, bi, 1, k); \
f_rn(bo, bi, 2, k); \
f_rn(bo, bi, 3, k); \
k += 4
#define f_lround(bo, bi, k) \
f_rl(bo, bi, 0, k); \
f_rl(bo, bi, 1, k); \
f_rl(bo, bi, 2, k); \
f_rl(bo, bi, 3, k)
#ifdef SMALL_CODE #ifdef SMALL_CODE
int r;
static void _fnround(unsigned long *bo, unsigned long *bi, unsigned long *k) #endif
{
f_nround(bo, bi, k);
}
static void _flround(unsigned long *bo, unsigned long *bi, unsigned long *k)
{
f_lround(bo, bi, k);
}
#undef f_nround
#define f_nround(bo, bi, k) { _fnround(bo, bi, k); k += 4; }
#undef f_lround
#define f_lround(bo, bi, k) _flround(bo, bi, k)
#endif
void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
unsigned long b0[4], b1[4], *kp;
_ARGCHK(pt != NULL); _ARGCHK(pt != NULL);
_ARGCHK(ct != NULL); _ARGCHK(ct != NULL);
_ARGCHK(skey != NULL); _ARGCHK(skey != NULL);
LOAD32L(b0[0], &pt[0]); LOAD32L(b0[1], &pt[4]);
LOAD32L(b0[2], &pt[8]); LOAD32L(b0[3], &pt[12]);
b0[0] ^= skey->rijndael.eK[0]; b0[1] ^= skey->rijndael.eK[1];
b0[2] ^= skey->rijndael.eK[2]; b0[3] ^= skey->rijndael.eK[3];
kp = skey->rijndael.eK + 4;
if (skey->rijndael.k_len > 6) {
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
} else if (skey->rijndael.k_len > 4) {
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
}
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_nround(b0, b1, kp);
f_nround(b1, b0, kp); f_lround(b0, b1, kp);
STORE32L(b0[0], &ct[0]); STORE32L(b0[1], &ct[4]);
STORE32L(b0[2], &ct[8]); STORE32L(b0[3], &ct[12]);
#ifdef CLEAN_STACK
zeromem(b0, sizeof(b0));
zeromem(b1, sizeof(b1));
#endif
};
/* decrypt a block of text */
#define i_nround(bo, bi, k) \
i_rn(bo, bi, 0, k); \
i_rn(bo, bi, 1, k); \
i_rn(bo, bi, 2, k); \
i_rn(bo, bi, 3, k); \
k -= 4
#define i_lround(bo, bi, k) \
i_rl(bo, bi, 0, k); \
i_rl(bo, bi, 1, k); \
i_rl(bo, bi, 2, k); \
i_rl(bo, bi, 3, k)
#ifdef SMALL_CODE 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];
#ifndef SMALL_CODE
/* round 1: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
/* round 2: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
/* round 3: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
/* round 4: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
/* round 5: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
/* round 6: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
/* round 7: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
/* round 8: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
/* round 9: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
if (Nr > 10) {
/* round 10: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43];
/* round 11: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47];
if (Nr > 12) {
/* round 12: */
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48];
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49];
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50];
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51];
/* round 13: */
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52];
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53];
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54];
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55];
}
}
rk += Nr << 2;
#else /* SMALL_CODE */
/*
* Nr - 1 full rounds:
*/
r = Nr >> 1;
for (;;) {
t0 =
Te0[(s0 >> 24) ] ^
Te1[(s1 >> 16) & 0xff] ^
Te2[(s2 >> 8) & 0xff] ^
Te3[(s3 ) & 0xff] ^
rk[4];
t1 =
Te0[(s1 >> 24) ] ^
Te1[(s2 >> 16) & 0xff] ^
Te2[(s3 >> 8) & 0xff] ^
Te3[(s0 ) & 0xff] ^
rk[5];
t2 =
Te0[(s2 >> 24) ] ^
Te1[(s3 >> 16) & 0xff] ^
Te2[(s0 >> 8) & 0xff] ^
Te3[(s1 ) & 0xff] ^
rk[6];
t3 =
Te0[(s3 >> 24) ] ^
Te1[(s0 >> 16) & 0xff] ^
Te2[(s1 >> 8) & 0xff] ^
Te3[(s2 ) & 0xff] ^
rk[7];
static void _inround(unsigned long *bo, unsigned long *bi, unsigned long *k) rk += 8;
{ if (--r == 0) {
i_nround(bo, bi, k); break;
}
s0 =
Te0[(t0 >> 24) ] ^
Te1[(t1 >> 16) & 0xff] ^
Te2[(t2 >> 8) & 0xff] ^
Te3[(t3 ) & 0xff] ^
rk[0];
s1 =
Te0[(t1 >> 24) ] ^
Te1[(t2 >> 16) & 0xff] ^
Te2[(t3 >> 8) & 0xff] ^
Te3[(t0 ) & 0xff] ^
rk[1];
s2 =
Te0[(t2 >> 24) ] ^
Te1[(t3 >> 16) & 0xff] ^
Te2[(t0 >> 8) & 0xff] ^
Te3[(t1 ) & 0xff] ^
rk[2];
s3 =
Te0[(t3 >> 24) ] ^
Te1[(t0 >> 16) & 0xff] ^
Te2[(t1 >> 8) & 0xff] ^
Te3[(t2 ) & 0xff] ^
rk[3];
}
#endif /* SMALL_CODE */
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Te4[(t0 >> 24) ] & 0xff000000) ^
(Te4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t3 ) & 0xff] & 0x000000ff) ^
rk[0];
STORE32H(s0, ct);
s1 =
(Te4[(t1 >> 24) ] & 0xff000000) ^
(Te4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t0 ) & 0xff] & 0x000000ff) ^
rk[1];
STORE32H(s1, ct+4);
s2 =
(Te4[(t2 >> 24) ] & 0xff000000) ^
(Te4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t1 ) & 0xff] & 0x000000ff) ^
rk[2];
STORE32H(s2, ct+8);
s3 =
(Te4[(t3 >> 24) ] & 0xff000000) ^
(Te4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Te4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Te4[(t2 ) & 0xff] & 0x000000ff) ^
rk[3];
STORE32H(s3, ct+12);
} }
static void _ilround(unsigned long *bo, unsigned long *bi, unsigned long *k) void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) {
{ unsigned long s0, s1, s2, s3, t0, t1, t2, t3, *rk;
i_lround(bo, bi, k); int Nr;
} #ifdef SMALL_CODE
int r;
#undef i_nround #endif /* SMALL_CODE */
#define i_nround(bo, bi, k) { _inround(bo, bi, k); k -= 4; }
#undef i_lround
#define i_lround(bo, bi, k) _ilround(bo, bi, k)
#endif
void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
unsigned long b0[4], b1[4], *kp;
_ARGCHK(pt != NULL); _ARGCHK(pt != NULL);
_ARGCHK(ct != NULL); _ARGCHK(ct != NULL);
_ARGCHK(skey != NULL); _ARGCHK(skey != NULL);
Nr = skey->rijndael.Nr;
rk = skey->rijndael.dK;
LOAD32L(b0[0], &ct[0]); LOAD32L(b0[1], &ct[4]); /*
LOAD32L(b0[2], &ct[8]); LOAD32L(b0[3], &ct[12]); * map byte array block to cipher state
b0[0] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 24]; * and add initial round key:
b0[1] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 25]; */
b0[2] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 26]; LOAD32H(s0, ct ); s0 ^= rk[0];
b0[3] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 27]; LOAD32H(s1, ct + 4); s1 ^= rk[1];
kp = skey->rijndael.dK + 4 * (skey->rijndael.k_len + 5); LOAD32H(s2, ct + 8); s2 ^= rk[2];
LOAD32H(s3, ct + 12); s3 ^= rk[3];
if(skey->rijndael.k_len > 6) { #ifndef SMALL_CODE
i_nround(b1, b0, kp); i_nround(b0, b1, kp); /* round 1: */
i_nround(b1, b0, kp); i_nround(b0, b1, kp); t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4];
} else if(skey->rijndael.k_len > 4) { t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5];
i_nround(b1, b0, kp); i_nround(b0, b1, kp); t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7];
/* round 2: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11];
/* round 3: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15];
/* round 4: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19];
/* round 5: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23];
/* round 6: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27];
/* round 7: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31];
/* round 8: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35];
/* round 9: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39];
if (Nr > 10) {
/* round 10: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43];
/* round 11: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47];
if (Nr > 12) {
/* round 12: */
s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48];
s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49];
s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50];
s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51];
/* round 13: */
t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52];
t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53];
t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54];
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
}
} }
rk += Nr << 2;
#else /* SMALL_CODE */
/*
* Nr - 1 full rounds:
*/
r = Nr >> 1;
for (;;) {
t0 =
Td0[(s0 >> 24) ] ^
Td1[(s3 >> 16) & 0xff] ^
Td2[(s2 >> 8) & 0xff] ^
Td3[(s1 ) & 0xff] ^
rk[4];
t1 =
Td0[(s1 >> 24) ] ^
Td1[(s0 >> 16) & 0xff] ^
Td2[(s3 >> 8) & 0xff] ^
Td3[(s2 ) & 0xff] ^
rk[5];
t2 =
Td0[(s2 >> 24) ] ^
Td1[(s1 >> 16) & 0xff] ^
Td2[(s0 >> 8) & 0xff] ^
Td3[(s3 ) & 0xff] ^
rk[6];
t3 =
Td0[(s3 >> 24) ] ^
Td1[(s2 >> 16) & 0xff] ^
Td2[(s1 >> 8) & 0xff] ^
Td3[(s0 ) & 0xff] ^
rk[7];
i_nround(b1, b0, kp); i_nround(b0, b1, kp); rk += 8;
i_nround(b1, b0, kp); i_nround(b0, b1, kp); if (--r == 0) {
i_nround(b1, b0, kp); i_nround(b0, b1, kp); break;
i_nround(b1, b0, kp); i_nround(b0, b1, kp); }
i_nround(b1, b0, kp); i_lround(b0, b1, kp);
STORE32L(b0[0], &pt[0]); STORE32L(b0[1], &pt[4]); s0 =
STORE32L(b0[2], &pt[8]); STORE32L(b0[3], &pt[12]); Td0[(t0 >> 24) ] ^
#ifdef CLEAN_STACK Td1[(t3 >> 16) & 0xff] ^
zeromem(b0, sizeof(b0)); Td2[(t2 >> 8) & 0xff] ^
zeromem(b1, sizeof(b1)); Td3[(t1 ) & 0xff] ^
#endif rk[0];
}; s1 =
Td0[(t1 >> 24) ] ^
Td1[(t0 >> 16) & 0xff] ^
Td2[(t3 >> 8) & 0xff] ^
Td3[(t2 ) & 0xff] ^
rk[1];
s2 =
Td0[(t2 >> 24) ] ^
Td1[(t1 >> 16) & 0xff] ^
Td2[(t0 >> 8) & 0xff] ^
Td3[(t3 ) & 0xff] ^
rk[2];
s3 =
Td0[(t3 >> 24) ] ^
Td1[(t2 >> 16) & 0xff] ^
Td2[(t1 >> 8) & 0xff] ^
Td3[(t0 ) & 0xff] ^
rk[3];
}
#endif /* SMALL_CODE */
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Td4[(t0 >> 24) ] & 0xff000000) ^
(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t1 ) & 0xff] & 0x000000ff) ^
rk[0];
STORE32H(s0, pt);
s1 =
(Td4[(t1 >> 24) ] & 0xff000000) ^
(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t2 ) & 0xff] & 0x000000ff) ^
rk[1];
STORE32H(s1, pt+4);
s2 =
(Td4[(t2 >> 24) ] & 0xff000000) ^
(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t3 ) & 0xff] & 0x000000ff) ^
rk[2];
STORE32H(s2, pt+8);
s3 =
(Td4[(t3 >> 24) ] & 0xff000000) ^
(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t0 ) & 0xff] & 0x000000ff) ^
rk[3];
STORE32H(s3, pt+12);
}
int rijndael_test(void) int rijndael_test(void)
{ {
@ -337,7 +569,7 @@ int rijndael_test(void)
} tests[] = { } tests[] = {
{ 16, { 16,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30, { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
@ -369,14 +601,31 @@ int rijndael_test(void)
int i; int i;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
if ((errno = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) { zeromem(&key, sizeof(key));
if ((errno = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return errno; return errno;
} }
rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key); rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
rijndael_ecb_decrypt(tmp[0], tmp[1], &key); rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) { if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) {
return CRYPT_FAIL_TESTVECTOR; #if 0
printf("\n\nTest %d failed\n", i);
if (memcmp(tmp[0], tests[i].ct, 16)) {
printf("CT: ");
for (i = 0; i < 16; i++) {
printf("%02x ", tmp[0][i]);
}
printf("\n");
} else {
printf("PT: ");
for (i = 0; i < 16; i++) {
printf("%02x ", tmp[1][i]);
}
printf("\n");
}
#endif
return CRYPT_FAIL_TESTVECTOR;
} }
} }
return CRYPT_OK; return CRYPT_OK;

1523
aes_tab.c

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,8 @@
Jun 11th, 2003
v0.85 -- Swapped in a new AES routine
-- Removed Serpent
-- Added TDCAL policy document
Jun 1st, 2003 Jun 1st, 2003
v0.84 -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more v0.84 -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more
-- Fixed another potential buffer problem. Not an overflow but could cause the -- Fixed another potential buffer problem. Not an overflow but could cause the

View File

@ -30,7 +30,6 @@
"RC2,Include RC2 block cipher,y", "RC2,Include RC2 block cipher,y",
"RC5,Include RC5 block cipher,y", "RC5,Include RC5 block cipher,y",
"RC6,Include RC6 block cipher,y", "RC6,Include RC6 block cipher,y",
"SERPENT,Include Serpent block cipher,y",
"SAFERP,Include Safer+ block cipher,y", "SAFERP,Include Safer+ block cipher,y",
"SAFER,Include Safer-64 block ciphers,y", "SAFER,Include Safer-64 block ciphers,y",
"RIJNDAEL,Include Rijndael (AES) block cipher,y", "RIJNDAEL,Include Rijndael (AES) block cipher,y",
@ -145,7 +144,7 @@ for (@settings) {
# output objects # output objects
print OUT "\ndefault: library\n\n"; print OUT "\ndefault: library\n\n";
print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o\n\n"; print OUT "OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o \n\n";
# some depends # some depends
print OUT "rsa.o: rsa_sys.c\ndh.o: dh_sys.c\necc.o: ecc_sys.c\n\n"; print OUT "rsa.o: rsa_sys.c\ndh.o: dh_sys.c\necc.o: ecc_sys.c\n\n";

View File

@ -384,9 +384,6 @@ const char *crypt_build_settings =
#if defined(RC6) #if defined(RC6)
" RC6\n" " RC6\n"
#endif #endif
#if defined(SERPENT)
" Serpent\n"
#endif
#if defined(SAFERP) #if defined(SAFERP)
" Safer+\n" " Safer+\n"
#endif #endif

76
crypt.out Normal file
View File

@ -0,0 +1,76 @@
\BOOKMARK [0][-]{chapter.1}{Introduction}{}
\BOOKMARK [1][-]{section.1.1}{What is the LibTomCrypt?}{chapter.1}
\BOOKMARK [2][-]{subsection.1.1.1}{What the library IS for?}{section.1.1}
\BOOKMARK [2][-]{subsection.1.1.2}{What the library IS NOT for?}{section.1.1}
\BOOKMARK [1][-]{section.1.2}{Why did I write it?}{chapter.1}
\BOOKMARK [2][-]{subsection.1.2.1}{Modular}{section.1.2}
\BOOKMARK [1][-]{section.1.3}{License}{chapter.1}
\BOOKMARK [1][-]{section.1.4}{Patent Disclosure}{chapter.1}
\BOOKMARK [1][-]{section.1.5}{Building the library}{chapter.1}
\BOOKMARK [1][-]{section.1.6}{Building against the library}{chapter.1}
\BOOKMARK [1][-]{section.1.7}{Thanks}{chapter.1}
\BOOKMARK [0][-]{chapter.2}{The Application Programming Interface \(API\)}{}
\BOOKMARK [1][-]{section.2.1}{Introduction}{chapter.2}
\BOOKMARK [1][-]{section.2.2}{Macros}{chapter.2}
\BOOKMARK [1][-]{section.2.3}{Functions with Variable Length Output}{chapter.2}
\BOOKMARK [1][-]{section.2.4}{Functions that need a PRNG}{chapter.2}
\BOOKMARK [1][-]{section.2.5}{Functions that use Arrays of Octets}{chapter.2}
\BOOKMARK [0][-]{chapter.3}{Symmetric Block Ciphers}{}
\BOOKMARK [1][-]{section.3.1}{Core Functions}{chapter.3}
\BOOKMARK [1][-]{section.3.2}{Key Sizes and Number of Rounds}{chapter.3}
\BOOKMARK [1][-]{section.3.3}{The Cipher Descriptors}{chapter.3}
\BOOKMARK [2][-]{subsection.3.3.1}{Notes}{section.3.3}
\BOOKMARK [1][-]{section.3.4}{Symmetric Modes of Operations}{chapter.3}
\BOOKMARK [2][-]{subsection.3.4.1}{Background}{section.3.4}
\BOOKMARK [2][-]{subsection.3.4.2}{Choice of Mode}{section.3.4}
\BOOKMARK [2][-]{subsection.3.4.3}{Implementation}{section.3.4}
\BOOKMARK [0][-]{chapter.4}{One-Way Cryptographic Hash Functions}{}
\BOOKMARK [1][-]{section.4.1}{Core Functions}{chapter.4}
\BOOKMARK [1][-]{section.4.2}{Hash Descriptors}{chapter.4}
\BOOKMARK [2][-]{subsection.4.2.1}{Notice}{section.4.2}
\BOOKMARK [1][-]{section.4.3}{Hash based Message Authenication Codes}{chapter.4}
\BOOKMARK [0][-]{chapter.5}{Pseudo-Random Number Generators}{}
\BOOKMARK [1][-]{section.5.1}{Core Functions}{chapter.5}
\BOOKMARK [2][-]{subsection.5.1.1}{Remarks}{section.5.1}
\BOOKMARK [2][-]{subsection.5.1.2}{Example}{section.5.1}
\BOOKMARK [1][-]{section.5.2}{PRNG Descriptors}{chapter.5}
\BOOKMARK [1][-]{section.5.3}{The Secure RNG}{chapter.5}
\BOOKMARK [2][-]{subsection.5.3.1}{The Secure PRNG Interface}{section.5.3}
\BOOKMARK [0][-]{chapter.6}{RSA Routines}{}
\BOOKMARK [1][-]{section.6.1}{Background}{chapter.6}
\BOOKMARK [1][-]{section.6.2}{Core Functions}{chapter.6}
\BOOKMARK [1][-]{section.6.3}{Packet Routines}{chapter.6}
\BOOKMARK [1][-]{section.6.4}{Remarks}{chapter.6}
\BOOKMARK [0][-]{chapter.7}{Diffie-Hellman Key Exchange}{}
\BOOKMARK [1][-]{section.7.1}{Background}{chapter.7}
\BOOKMARK [1][-]{section.7.2}{Core Functions}{chapter.7}
\BOOKMARK [2][-]{subsection.7.2.1}{Remarks on Usage}{section.7.2}
\BOOKMARK [2][-]{subsection.7.2.2}{Remarks on The Snippet}{section.7.2}
\BOOKMARK [1][-]{section.7.3}{Other Diffie-Hellman Functions}{chapter.7}
\BOOKMARK [1][-]{section.7.4}{DH Packet}{chapter.7}
\BOOKMARK [0][-]{chapter.8}{Elliptic Curve Cryptography}{}
\BOOKMARK [1][-]{section.8.1}{Background}{chapter.8}
\BOOKMARK [1][-]{section.8.2}{Core Functions}{chapter.8}
\BOOKMARK [1][-]{section.8.3}{ECC Packet}{chapter.8}
\BOOKMARK [1][-]{section.8.4}{ECC Keysizes}{chapter.8}
\BOOKMARK [0][-]{chapter.9}{Public Keyrings}{}
\BOOKMARK [1][-]{section.9.1}{Introduction}{chapter.9}
\BOOKMARK [1][-]{section.9.2}{The Keyring API}{chapter.9}
\BOOKMARK [0][-]{chapter.10}{GF\(2w\) Math Routines}{}
\BOOKMARK [0][-]{chapter.11}{Miscellaneous}{}
\BOOKMARK [1][-]{section.11.1}{Base64 Encoding and Decoding}{chapter.11}
\BOOKMARK [1][-]{section.11.2}{The Multiple Precision Integer Library \(MPI\)}{chapter.11}
\BOOKMARK [2][-]{subsection.11.2.1}{Binary Forms of ``mp\137int'' Variables}{section.11.2}
\BOOKMARK [2][-]{subsection.11.2.2}{Primality Testing}{section.11.2}
\BOOKMARK [0][-]{chapter.12}{Programming Guidelines}{}
\BOOKMARK [1][-]{section.12.1}{Secure Pseudo Random Number Generators}{chapter.12}
\BOOKMARK [1][-]{section.12.2}{Preventing Trivial Errors}{chapter.12}
\BOOKMARK [1][-]{section.12.3}{Registering Your Algorithms}{chapter.12}
\BOOKMARK [1][-]{section.12.4}{Key Sizes}{chapter.12}
\BOOKMARK [2][-]{subsection.12.4.1}{Symmetric Ciphers}{section.12.4}
\BOOKMARK [2][-]{subsection.12.4.2}{Assymetric Ciphers}{section.12.4}
\BOOKMARK [1][-]{section.12.5}{Thread Safety}{chapter.12}
\BOOKMARK [0][-]{chapter.13}{Configuring the Library}{}
\BOOKMARK [1][-]{section.13.1}{Introduction}{chapter.13}
\BOOKMARK [1][-]{section.13.2}{mycrypt\137cfg.h}{chapter.13}
\BOOKMARK [1][-]{section.13.3}{The Configure Script}{chapter.13}

BIN
crypt.pdf

Binary file not shown.

View File

@ -1,4 +1,5 @@
\documentclass{book} \documentclass{book}
\usepackage{hyperref}
\usepackage{makeidx} \usepackage{makeidx}
\usepackage{amssymb} \usepackage{amssymb}
\usepackage{color} \usepackage{color}
@ -41,14 +42,12 @@
\def\C{{\mathbb C}} \def\C{{\mathbb C}}
\def\Q{{\mathbb Q}} \def\Q{{\mathbb Q}}
\newcommand{\url}[1]{\mbox{$<${#1}$>$}}
\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}}
\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}} \def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}}
\def\gap{\vspace{0.5ex}} \def\gap{\vspace{0.5ex}}
\makeindex \makeindex
\begin{document} \begin{document}
\title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.84} \title{A Tiny Crypto Library, \\ LibTomCrypt \\ Version 0.85}
\author{Tom St Denis \\ \author{Tom St Denis \\
Algonquin College \\ Algonquin College \\
\\ \\
@ -162,14 +161,11 @@ All of the source code except for the following files have been written by the a
under the TDCAL license: under the TDCAL license:
\begin{enumerate} \begin{enumerate}
\item aes.c
\item rc2.c \item rc2.c
\item serpent.c
\item safer.c \item safer.c
\end{enumerate} \end{enumerate}
``aes.c'' and ``serpent.c'' were written by Brian Gladman (gladman@seven77.demon.co.uk). They are copyrighted works `mpi.c'' was originally written
but were both granted unrestricted usage in any project (commercial or otherwise). ``mpi.c'' was originally written
by Michael Fromberger (sting@linguist.dartmouth.edu) but has since been replaced with my LibTomMath library. by Michael Fromberger (sting@linguist.dartmouth.edu) but has since been replaced with my LibTomMath library.
``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. ``safer.c'' ``rc2.c'' is based on publicly available code that is not attributed to a person from the given source. ``safer.c''
was written by Richard De Moliner (demoliner@isi.ee.ethz.ch) and is public domain. was written by Richard De Moliner (demoliner@isi.ee.ethz.ch) and is public domain.
@ -512,7 +508,6 @@ As of this release the current cipher\_descriptors elements are
\hline Safer SK64 & safer\_sk64\_desc & 8 & 8 & 6 .. 13 \\ \hline Safer SK64 & safer\_sk64\_desc & 8 & 8 & 6 .. 13 \\
\hline Safer K128 & safer\_k128\_desc & 8 & 16 & 6 .. 13 \\ \hline Safer K128 & safer\_k128\_desc & 8 & 16 & 6 .. 13 \\
\hline Safer SK128 & safer\_sk128\_desc & 8 & 16 & 6 .. 13 \\ \hline Safer SK128 & safer\_sk128\_desc & 8 & 16 & 6 .. 13 \\
\hline Serpent & serpent\_desc & 16 & 16 .. 32 & 32 \\
\hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\ \hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 \\
\hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\ \hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 \\
\hline DES & des\_desc & 8 & 7 & 16 \\ \hline DES & des\_desc & 8 & 7 & 16 \\

View File

@ -506,7 +506,6 @@ pad_test (void)
} }
printf ("passed.\n"); printf ("passed.\n");
} }
void void
rsa_test (void) rsa_test (void)
{ {
@ -658,9 +657,6 @@ rsa_test (void)
rsa_free (&key); rsa_free (&key);
} }
} }
} }
#else #else
void void
@ -1296,6 +1292,9 @@ test_prime (void)
void void
register_all_algs (void) register_all_algs (void)
{ {
#ifdef RIJNDAEL
register_cipher (&aes_desc);
#endif
#ifdef BLOWFISH #ifdef BLOWFISH
register_cipher (&blowfish_desc); register_cipher (&blowfish_desc);
#endif #endif
@ -1311,12 +1310,6 @@ register_all_algs (void)
#ifdef SAFERP #ifdef SAFERP
register_cipher (&saferp_desc); register_cipher (&saferp_desc);
#endif #endif
#ifdef SERPENT
register_cipher (&serpent_desc);
#endif
#ifdef RIJNDAEL
register_cipher (&aes_desc);
#endif
#ifdef TWOFISH #ifdef TWOFISH
register_cipher (&twofish_desc); register_cipher (&twofish_desc);
#endif #endif
@ -1375,6 +1368,7 @@ register_all_algs (void)
#endif #endif
} }
#ifdef KR
void void
kr_display (pk_key * kr) kr_display (pk_key * kr)
{ {
@ -1664,8 +1658,8 @@ kr_test (void)
} }
kr_clear (&kr); kr_clear (&kr);
} }
#endif
void void
test_errs (void) test_errs (void)
@ -1715,7 +1709,7 @@ main (void)
#endif #endif
register_all_algs (); register_all_algs ();
if ((errnum = yarrow_start (&prng)) != CRYPT_OK) { if ((errnum = yarrow_start (&prng)) != CRYPT_OK) {
printf ("yarrow_start: %s\n", error_to_string (errnum)); printf ("yarrow_start: %s\n", error_to_string (errnum));
} }
@ -1746,7 +1740,9 @@ main (void)
rng_tests (); rng_tests ();
//test_prime(); //test_prime();
#ifdef KR
kr_test (); kr_test ();
#endif
rsa_test (); rsa_test ();
pad_test (); pad_test ();
ecc_tests (); ecc_tests ();

View File

@ -4,19 +4,6 @@ Tom St Denis
The bulk of the code was written or donated under the TDCAL "Tom Doesn't Care About License" license. It entitles the developer to free-reign on The bulk of the code was written or donated under the TDCAL "Tom Doesn't Care About License" license. It entitles the developer to free-reign on
the use and distribution of derived works, commercial or otherwise. Certain files are taken from public domain packages. the use and distribution of derived works, commercial or otherwise. Certain files are taken from public domain packages.
AES.C
-----
Author: Dr Brian Gladman
Email : gladman@seven77.demon.co.uk
Disclaimer (verbatim)
----
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
----
Status: Public Domain, modified [not original]
DES.C DES.C
----- -----
Author: Unknown, Submitted by Dobes Vandermeer Author: Unknown, Submitted by Dobes Vandermeer
@ -63,18 +50,4 @@ Author: [copied verbatim]
---- ----
Email: demoliner@isi.ee.ethz.ch Email: demoliner@isi.ee.ethz.ch
Disclaimer: Appears to be Public Domain [not quite sure] Disclaimer: Appears to be Public Domain [not quite sure]
Status: Public Domain, modified [not original] Status: Public Domain, modified [not original]
SERPENT.C
---------
Author: Dr. Brian Gladman
Email : gladman@seven77.demon.co.uk
Disclaimer (verbatim)
----
/* Copyright in this implementation is held by Dr B R Gladman but I */
/* hereby give permission for its free direct or derivative use subject */
/* to acknowledgment of its origin and compliance with any conditions */
/* that the originators of the algorithm place on its exploitation. */
----
Status: Public Domain, modified [not original]

View File

@ -9,7 +9,7 @@
# a build. This is easy to remedy though, for those that have problems. # a build. This is easy to remedy though, for those that have problems.
# The version # The version
VERSION=0.84 VERSION=0.85
#ch1-01-1 #ch1-01-1
# Compiler and Linker Names # Compiler and Linker Names
@ -55,9 +55,9 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf
#List of objects to compile. #List of objects to compile.
OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \ OBJECTS=keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o \
bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \ bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o \
md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o \ md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o \
safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \ safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o \
mpi.o prime.o twofish.o packet.o hmac.o strings.o mpi.o prime.o twofish.o packet.o hmac.o strings.o
TESTOBJECTS=demos/test.o TESTOBJECTS=demos/test.o
HASHOBJECTS=demos/hashsum.o HASHOBJECTS=demos/hashsum.o

View File

@ -2,16 +2,17 @@
# #
#Tom St Denis #Tom St Denis
CFLAGS = /I. /Ogiyb1s /Gs /DWIN32 /W3 # note optimizations are turned off because it causes a bug in aes.c that cannot be rectified [right away]
CFLAGS = /I. /Od /G3 /DWIN32 /W3
default: library default: library
#List of objects to compile. #List of objects to compile.
OBJECTS=keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj \ OBJECTS=keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj \
bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj \ bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj \
md5.obj md4.obj md2.obj sha256.obj sha512.obj xtea.obj aes.obj serpent.obj des.obj \ md5.obj md4.obj md2.obj sha256.obj sha512.obj xtea.obj aes.obj des.obj \
safer_tab.obj safer.obj safer+.obj rc4.obj rc2.obj rc6.obj rc5.obj cast5.obj noekeon.obj \ safer_tab.obj safer.obj safer+.obj rc4.obj rc2.obj rc6.obj rc5.obj cast5.obj noekeon.obj \
blowfish.obj crypt.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj blowfish.obj crypt.obj mpi.obj prime.obj twofish.obj packet.obj hmac.obj strings.obj
library: $(OBJECTS) library: $(OBJECTS)
lib /out:tomcrypt.lib $(OBJECTS) lib /out:tomcrypt.lib $(OBJECTS)

View File

@ -5,11 +5,11 @@
CC = gcc CC = gcc
AR = ar AR = ar
LD = ld LD = ld
CFLAGS += -O3 -Wall -Wsign-compare -W -Wno-unused -Werror -I./ CFLAGS += -Os -Wall -Wsign-compare -W -Wno-unused -Werror -I./
default: library default: library
OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o serpent.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o ampi.o mpi.o prime.o twofish.o packet.o hmac.o strings.o OBJECTS = keyring.o gf.o mem.o sprng.o ecc.o base64.o dh.o rsa.o bits.o yarrow.o cfb.o ofb.o ecb.o ctr.o cbc.o hash.o tiger.o sha1.o md5.o md4.o md2.o sha256.o sha512.o xtea.o aes.o des.o safer_tab.o safer.o safer+.o rc4.o rc2.o rc6.o rc5.o cast5.o noekeon.o blowfish.o crypt.o mpi.o prime.o twofish.o packet.o hmac.o strings.o
rsa.o: rsa_sys.c rsa.o: rsa_sys.c
dh.o: dh_sys.c dh.o: dh_sys.c

2
md4.c
View File

@ -29,7 +29,7 @@ const struct _hash_descriptor md4_desc =
#define S34 15 #define S34 15
/* F, G and H are basic MD4 functions. */ /* F, G and H are basic MD4 functions. */
#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define F(x, y, z) (z ^ (x & (y ^ z)))
#define G(x, y, z) ((x & y) | (z & (x | y))) #define G(x, y, z) ((x & y) | (z & (x | y)))
#define H(x, y, z) ((x) ^ (y) ^ (z)) #define H(x, y, z) ((x) ^ (y) ^ (z))

2
md5.c
View File

@ -14,7 +14,7 @@ const struct _hash_descriptor md5_desc =
&md5_test &md5_test
}; };
#define F(x,y,z) ((x&y)|((~x)&z)) #define F(x,y,z) (z ^ (x & (y ^ z)))
#define G(x,y,z) ((x&z)|(y&(~z))) #define G(x,y,z) ((x&z)|(y&(~z)))
#define H(x,y,z) (x^y^z) #define H(x,y,z) (x^y^z)
#define I(x,y,z) (y^(x|(~z))) #define I(x,y,z) (y^(x|(~z)))

12367
mpi.c

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,8 @@ extern "C" {
#endif #endif
/* version */ /* version */
#define CRYPT 0x0084 #define CRYPT 0x0085
#define SCRYPT "0.84" #define SCRYPT "0.85"
/* max size of either a cipher/hash block or symmetric key [largest of the two] */ /* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 128 #define MAXBLOCKSIZE 128

View File

@ -30,15 +30,10 @@ struct saferp_key {
}; };
#endif #endif
#ifdef SERPENT
struct serpent_key {
unsigned long K[132];
};
#endif
#ifdef RIJNDAEL #ifdef RIJNDAEL
struct rijndael_key { struct rijndael_key {
unsigned long eK[64], dK[64], k_len; unsigned long eK[64], dK[64];
int Nr;
}; };
#endif #endif
@ -96,7 +91,7 @@ struct cast5_key {
#ifdef NOEKEON #ifdef NOEKEON
struct noekeon_key { struct noekeon_key {
unsigned long K[4], dK[4]; unsigned long K[4], dK[4];
}; };
#endif #endif
@ -126,9 +121,6 @@ typedef union Symmetric_key {
#ifdef SAFERP #ifdef SAFERP
struct saferp_key saferp; struct saferp_key saferp;
#endif #endif
#ifdef SERPENT
struct serpent_key serpent;
#endif
#ifdef RIJNDAEL #ifdef RIJNDAEL
struct rijndael_key rijndael; struct rijndael_key rijndael;
#endif #endif
@ -251,23 +243,14 @@ extern int safer_128_keysize(int *desired_keysize);
extern const struct _cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc; extern const struct _cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc;
#endif #endif
#ifdef SERPENT
extern int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
extern void serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
extern void serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
extern int serpent_test(void);
extern int serpent_keysize(int *desired_keysize);
extern const struct _cipher_descriptor serpent_desc;
#endif
#ifdef RIJNDAEL #ifdef RIJNDAEL
/* make aes an alias */ /* make aes an alias */
#define aes_setup rijndael_setup #define aes_setup rijndael_setup
#define aes_ecb_encrypt rijndael_ecb_encrypt #define aes_ecb_encrypt rijndael_ecb_encrypt
#define aes_ecb_decrypt rijndael_ecb_decrypt #define aes_ecb_decrypt rijndael_ecb_decrypt
#define aes_test rijndael_test #define aes_test rijndael_test
#define aes_keysize rijndael_keysize #define aes_keysize rijndael_keysize
extern int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); extern int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
extern void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); extern void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
@ -363,7 +346,7 @@ extern int ctr_start(int cipher, const unsigned char *IV, const unsigned char *k
extern int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr); extern int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
extern int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); extern int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
#endif #endif
extern int find_cipher(const char *name); extern int find_cipher(const char *name);
extern int find_cipher_any(const char *name, int blocklen, int keylen); extern int find_cipher_any(const char *name, int blocklen, int keylen);
extern int find_cipher_id(unsigned char ID); extern int find_cipher_id(unsigned char ID);

View File

@ -1,16 +1,14 @@
/* This header is meant to be included before mycrypt.h in projects where /* This header is meant to be included before mycrypt.h in projects where
* you don't want to throw all the defines in a makefile. * you don't want to throw all the defines in a makefile.
*/ */
#ifndef MYCRYPT_CUSTOM_H_ #ifndef MYCRYPT_CUSTOM_H_
#define MYCRYPT_CUSTOM_H_ #define MYCRYPT_CUSTOM_H_
#ifdef CRYPT #ifdef CRYPT
#error mycrypt_custom.h should be included before mycrypt.h #error mycrypt_custom.h should be included before mycrypt.h
#endif #endif
#define LTC_TEST
#define XMALLOC malloc #define XMALLOC malloc
#define XREALLOC realloc #define XREALLOC realloc
#define XCALLOC calloc #define XCALLOC calloc
@ -18,11 +16,11 @@
#define XCLOCK clock #define XCLOCK clock
#define XCLOCKS_PER_SEC CLOCKS_PER_SEC #define XCLOCKS_PER_SEC CLOCKS_PER_SEC
#define SMALL_CODE #define SMALL_CODE
#define LTC_TEST
#define BLOWFISH #define BLOWFISH
#define RC2 #define RC2
#define RC5 #define RC5
#define RC6 #define RC6
#define SERPENT
#define SAFERP #define SAFERP
#define SAFER #define SAFER
#define RIJNDAEL #define RIJNDAEL

View File

@ -183,4 +183,3 @@ extern int hmac_file(int hash, const char *fname, const unsigned char *key,
unsigned long keylen, unsigned long keylen,
unsigned char *dst, unsigned long *dstlen); unsigned char *dst, unsigned long *dstlen);
#endif #endif

View File

@ -45,7 +45,7 @@ loop:
dist += step; x = -1; dist += step; x = -1;
} }
} }
/* recalc the total distance from where we started */ /* recalc the total distance from where we started */
total_dist += dist; total_dist += dist;

702
serpent.c
View File

@ -1,702 +0,0 @@
#include "mycrypt.h"
#ifdef SERPENT
const struct _cipher_descriptor serpent_desc =
{
"serpent",
5,
16, 32, 16, 32,
&serpent_setup,
&serpent_ecb_encrypt,
&serpent_ecb_decrypt,
&serpent_test,
&serpent_keysize
};
/* These defines are derived from Brian Gladman's work. Contact him at gladman@seven77.demon.co.uk
*
* Available on the web at http://fp.gladman.plus.com/cryptography_technology/aes/index.htm
*/
#define sb0(a,b,c,d,e,f,g,h) \
t1 = a ^ d; \
t2 = a & d; \
t3 = c ^ t1; \
t6 = b & t1; \
t4 = b ^ t3; \
t10 = ~t3; \
h = t2 ^ t4; \
t7 = a ^ t6; \
t14 = ~t7; \
t8 = c | t7; \
t11 = t3 ^ t7; \
g = t4 ^ t8; \
t12 = h & t11; \
f = t10 ^ t12; \
e = t12 ^ t14
/* 15 terms */
#define ib0(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ b; \
t3 = t1 | t2; \
t4 = d ^ t3; \
t7 = d & t2; \
t5 = c ^ t4; \
t8 = t1 ^ t7; \
g = t2 ^ t5; \
t11 = a & t4; \
t9 = g & t8; \
t14 = t5 ^ t8; \
f = t4 ^ t9; \
t12 = t5 | f; \
h = t11 ^ t12; \
e = h ^ t14
/* 14 terms! */
#define sb1(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = b ^ t1; \
t3 = a | t2; \
t4 = d | t2; \
t5 = c ^ t3; \
g = d ^ t5; \
t7 = b ^ t4; \
t8 = t2 ^ g; \
t9 = t5 & t7; \
h = t8 ^ t9; \
t11 = t5 ^ t7; \
f = h ^ t11; \
t13 = t8 & t11; \
e = t5 ^ t13
/* 17 terms */
#define ib1(a,b,c,d,e,f,g,h) \
t1 = a ^ d; \
t2 = a & b; \
t3 = b ^ c; \
t4 = a ^ t3; \
t5 = b | d; \
t7 = c | t1; \
h = t4 ^ t5; \
t8 = b ^ t7; \
t11 = ~t2; \
t9 = t4 & t8; \
f = t1 ^ t9; \
t13 = t9 ^ t11; \
t12 = h & f; \
g = t12 ^ t13; \
t15 = a & d; \
t16 = c ^ t13; \
e = t15 ^ t16
/* 16 terms */
#define sb2(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = b ^ d; \
t3 = c & t1; \
t13 = d | t1; \
e = t2 ^ t3; \
t5 = c ^ t1; \
t6 = c ^ e; \
t7 = b & t6; \
t10 = e | t5; \
h = t5 ^ t7; \
t9 = d | t7; \
t11 = t9 & t10; \
t14 = t2 ^ h; \
g = a ^ t11; \
t15 = g ^ t13; \
f = t14 ^ t15
/* 16 terms */
#define ib2(a,b,c,d,e,f,g,h) \
t1 = b ^ d; \
t2 = ~t1; \
t3 = a ^ c; \
t4 = c ^ t1; \
t7 = a | t2; \
t5 = b & t4; \
t8 = d ^ t7; \
t11 = ~t4; \
e = t3 ^ t5; \
t9 = t3 | t8; \
t14 = d & t11; \
h = t1 ^ t9; \
t12 = e | h; \
f = t11 ^ t12; \
t15 = t3 ^ t12; \
g = t14 ^ t15
/* 17 terms */
#define sb3(a,b,c,d,e,f,g,h) \
t1 = a ^ c; \
t2 = d ^ t1; \
t3 = a & t2; \
t4 = d ^ t3; \
t5 = b & t4; \
g = t2 ^ t5; \
t7 = a | g; \
t8 = b | d; \
t11 = a | d; \
t9 = t4 & t7; \
f = t8 ^ t9; \
t12 = b ^ t11; \
t13 = g ^ t9; \
t15 = t3 ^ t8; \
h = t12 ^ t13; \
t16 = c & t15; \
e = t12 ^ t16
/* 16 term solution that performs less well than 17 term one
in my environment (PPro/PII)
#define sb3(a,b,c,d,e,f,g,h) \
t1 = a ^ b; \
t2 = a & c; \
t3 = a | d; \
t4 = c ^ d; \
t5 = t1 & t3; \
t6 = t2 | t5; \
g = t4 ^ t6; \
t8 = b ^ t3; \
t9 = t6 ^ t8; \
t10 = t4 & t9; \
e = t1 ^ t10; \
t12 = g & e; \
f = t9 ^ t12; \
t14 = b | d; \
t15 = t4 ^ t12; \
h = t14 ^ t15
*/
/* 17 terms */
#define ib3(a,b,c,d,e,f,g,h) \
t1 = b ^ c; \
t2 = b | c; \
t3 = a ^ c; \
t7 = a ^ d; \
t4 = t2 ^ t3; \
t5 = d | t4; \
t9 = t2 ^ t7; \
e = t1 ^ t5; \
t8 = t1 | t5; \
t11 = a & t4; \
g = t8 ^ t9; \
t12 = e | t9; \
f = t11 ^ t12; \
t14 = a & g; \
t15 = t2 ^ t14; \
t16 = e & t15; \
h = t4 ^ t16
/* 15 terms */
#define sb4(a,b,c,d,e,f,g,h) \
t1 = a ^ d; \
t2 = d & t1; \
t3 = c ^ t2; \
t4 = b | t3; \
h = t1 ^ t4; \
t6 = ~b; \
t7 = t1 | t6; \
e = t3 ^ t7; \
t9 = a & e; \
t10 = t1 ^ t6; \
t11 = t4 & t10; \
g = t9 ^ t11; \
t13 = a ^ t3; \
t14 = t10 & g; \
f = t13 ^ t14
/* 17 terms */
#define ib4(a,b,c,d,e,f,g,h) \
t1 = c ^ d; \
t2 = c | d; \
t3 = b ^ t2; \
t4 = a & t3; \
f = t1 ^ t4; \
t6 = a ^ d; \
t7 = b | d; \
t8 = t6 & t7; \
h = t3 ^ t8; \
t10 = ~a; \
t11 = c ^ h; \
t12 = t10 | t11;\
e = t3 ^ t12; \
t14 = c | t4; \
t15 = t7 ^ t14; \
t16 = h | t10; \
g = t15 ^ t16
/* 16 terms */
#define sb5(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ b; \
t3 = a ^ d; \
t4 = c ^ t1; \
t5 = t2 | t3; \
e = t4 ^ t5; \
t7 = d & e; \
t8 = t2 ^ e; \
t10 = t1 | e; \
f = t7 ^ t8; \
t11 = t2 | t7; \
t12 = t3 ^ t10; \
t14 = b ^ t7; \
g = t11 ^ t12; \
t15 = f & t12; \
h = t14 ^ t15
/* 16 terms */
#define ib5(a,b,c,d,e,f,g,h) \
t1 = ~c; \
t2 = b & t1; \
t3 = d ^ t2; \
t4 = a & t3; \
t5 = b ^ t1; \
h = t4 ^ t5; \
t7 = b | h; \
t8 = a & t7; \
f = t3 ^ t8; \
t10 = a | d; \
t11 = t1 ^ t7; \
e = t10 ^ t11; \
t13 = a ^ c; \
t14 = b & t10; \
t15 = t4 | t13; \
g = t14 ^ t15
/* 15 terms */
#define sb6(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ d; \
t3 = b ^ t2; \
t4 = t1 | t2; \
t5 = c ^ t4; \
f = b ^ t5; \
t13 = ~t5; \
t7 = t2 | f; \
t8 = d ^ t7; \
t9 = t5 & t8; \
g = t3 ^ t9; \
t11 = t5 ^ t8; \
e = g ^ t11; \
t14 = t3 & t11; \
h = t13 ^ t14
/* 15 terms */
#define ib6(a,b,c,d,e,f,g,h) \
t1 = ~a; \
t2 = a ^ b; \
t3 = c ^ t2; \
t4 = c | t1; \
t5 = d ^ t4; \
t13 = d & t1; \
f = t3 ^ t5; \
t7 = t3 & t5; \
t8 = t2 ^ t7; \
t9 = b | t8; \
h = t5 ^ t9; \
t11 = b | h; \
e = t8 ^ t11; \
t14 = t3 ^ t11; \
g = t13 ^ t14
/* 17 terms */
#define sb7(a,b,c,d,e,f,g,h) \
t1 = ~c; \
t2 = b ^ c; \
t3 = b | t1; \
t4 = d ^ t3; \
t5 = a & t4; \
t7 = a ^ d; \
h = t2 ^ t5; \
t8 = b ^ t5; \
t9 = t2 | t8; \
t11 = d & t3; \
f = t7 ^ t9; \
t12 = t5 ^ f; \
t15 = t1 | t4; \
t13 = h & t12; \
g = t11 ^ t13; \
t16 = t12 ^ g; \
e = t15 ^ t16
/* 17 terms */
#define ib7(a,b,c,d,e,f,g,h) \
t1 = a & b; \
t2 = a | b; \
t3 = c | t1; \
t4 = d & t2; \
h = t3 ^ t4; \
t6 = ~d; \
t7 = b ^ t4; \
t8 = h ^ t6; \
t11 = c ^ t7; \
t9 = t7 | t8; \
f = a ^ t9; \
t12 = d | f; \
e = t11 ^ t12; \
t14 = a & h; \
t15 = t3 ^ f; \
t16 = e ^ t14; \
g = t15 ^ t16
#define k_xor(r,a,b,c,d) \
a ^= skey->serpent.K[4 * (r) + 0]; \
b ^= skey->serpent.K[4 * (r) + 1]; \
c ^= skey->serpent.K[4 * (r) + 2]; \
d ^= skey->serpent.K[4 * (r) + 3]
#define k_set(r,a,b,c,d) \
a = lkey[4 * (r) + 8]; \
b = lkey[4 * (r) + 9]; \
c = lkey[4 * (r) + 10]; \
d = lkey[4 * (r) + 11]
#define k_get(r,a,b,c,d) \
skey->serpent.K[4 * (r) + 0] = a; \
skey->serpent.K[4 * (r) + 1] = b; \
skey->serpent.K[4 * (r) + 2] = c; \
skey->serpent.K[4 * (r) + 3] = d
/* the linear transformation and its inverse */
#define rot(a,b,c,d) \
a = ROL(a, 13); \
c = ROL(c, 3); \
d ^= c ^ (a << 3); \
b ^= a ^ c; \
d = ROL(d, 7); \
b = ROL(b, 1); \
a ^= b ^ d; \
c ^= d ^ (b << 7); \
a = ROL(a, 5); \
c = ROL(c, 22)
#define irot(a,b,c,d) \
c = ROR(c, 22); \
a = ROR(a, 5); \
c ^= d ^ (b << 7); \
a ^= b ^ d; \
d = ROR(d, 7); \
b = ROR(b, 1); \
d ^= c ^ (a << 3); \
b ^= a ^ c; \
c = ROR(c, 3); \
a = ROR(a, 13)
#ifdef CLEAN_STACK
static int _serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#else
int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
#endif
{
unsigned long lkey[140], t, a, b, c, d, e, f, g, h, x;
unsigned long t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
unsigned char buf[32];
_ARGCHK(key != NULL);
_ARGCHK(skey != NULL);
/* check rounds */
if (num_rounds != 0 && num_rounds != 32) {
return CRYPT_INVALID_ROUNDS;
}
/* check keylen */
if (keylen < 16 || keylen > 32) {
return CRYPT_INVALID_KEYSIZE;
}
/* copy key and expand to 32bytes as required */
for (x = 0; x < (unsigned long)keylen; x++) {
buf[x] = key[x];
}
if (x < 32) {
buf[x++] = (unsigned char)0x01;
while (x < 32) {
buf[x++] = (unsigned char)0;
}
}
/* copy key into 32-bit words */
for (x = 0; x < 8; x++) {
LOAD32L(lkey[x], &buf[x*4]);
}
/* expand using the LFSR to 140 words */
for (x = 0; x < 132; x++) {
t = lkey[x] ^ lkey[x+3] ^ lkey[x+5] ^ lkey[x+7] ^ x ^ 0x9E3779B9UL;
lkey[x + 8] = ROL(t, 11);
}
/* perform the substituions */
for (x = 0; x < 32; ) {
k_set( x,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb2(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb1(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb0(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb7(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb6(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb5(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
k_set( x,a,b,c,d);sb4(a,b,c,d,e,f,g,h);k_get( x,e,f,g,h); ++x;
}
k_set(32,a,b,c,d);sb3(a,b,c,d,e,f,g,h);k_get(32,e,f,g,h);
return CRYPT_OK;
}
#ifdef CLEAN_STACK
int serpent_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int x;
x = _serpent_setup(key, keylen, num_rounds, skey);
burn_stack(sizeof(unsigned long)*166 + sizeof(unsigned char)*32);
return x;
}
#endif
#ifdef CLEAN_STACK
static void _serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
void serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
unsigned long a,b,c,d,e,f,g,h;
unsigned long t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(skey != NULL);
LOAD32L(a, &pt[0]);LOAD32L(b, &pt[4]);LOAD32L(c, &pt[8]);LOAD32L(d, &pt[12]);
k_xor( 0,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor( 1,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor( 2,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor( 3,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor( 4,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor( 5,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor( 6,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor( 7,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor( 8,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor( 9,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(10,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(11,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(12,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(13,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(14,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(15,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(16,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(17,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(18,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(19,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(20,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(21,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(22,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(23,e,f,g,h); sb7(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(24,a,b,c,d); sb0(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(25,e,f,g,h); sb1(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(26,a,b,c,d); sb2(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(27,e,f,g,h); sb3(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(28,a,b,c,d); sb4(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(29,e,f,g,h); sb5(e,f,g,h,a,b,c,d); rot(a,b,c,d);
k_xor(30,a,b,c,d); sb6(a,b,c,d,e,f,g,h); rot(e,f,g,h);
k_xor(31,e,f,g,h); sb7(e,f,g,h,a,b,c,d); k_xor(32,a,b,c,d);
STORE32L(a, &ct[0]);STORE32L(b, &ct[4]);STORE32L(c, &ct[8]);STORE32L(d, &ct[12]);
}
#ifdef CLEAN_STACK
void serpent_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
_serpent_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned long)*24);
}
#endif
#ifdef CLEAN_STACK
static void _serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
void serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
unsigned long a,b,c,d,e,f,g,h;
unsigned long t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16;
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
_ARGCHK(skey != NULL);
LOAD32L(a, &ct[0]);LOAD32L(b, &ct[4]);LOAD32L(c, &ct[8]);LOAD32L(d, &ct[12]);
k_xor(32,a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(31,e,f,g,h);
irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(30,a,b,c,d);
irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(29,e,f,g,h);
irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(28,a,b,c,d);
irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(27,e,f,g,h);
irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(26,a,b,c,d);
irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(25,e,f,g,h);
irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(24,a,b,c,d);
irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(23,e,f,g,h);
irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(22,a,b,c,d);
irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(21,e,f,g,h);
irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(20,a,b,c,d);
irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(19,e,f,g,h);
irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(18,a,b,c,d);
irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor(17,e,f,g,h);
irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor(16,a,b,c,d);
irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor(15,e,f,g,h);
irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor(14,a,b,c,d);
irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor(13,e,f,g,h);
irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor(12,a,b,c,d);
irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor(11,e,f,g,h);
irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor(10,a,b,c,d);
irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 9,e,f,g,h);
irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 8,a,b,c,d);
irot(a,b,c,d); ib7(a,b,c,d,e,f,g,h); k_xor( 7,e,f,g,h);
irot(e,f,g,h); ib6(e,f,g,h,a,b,c,d); k_xor( 6,a,b,c,d);
irot(a,b,c,d); ib5(a,b,c,d,e,f,g,h); k_xor( 5,e,f,g,h);
irot(e,f,g,h); ib4(e,f,g,h,a,b,c,d); k_xor( 4,a,b,c,d);
irot(a,b,c,d); ib3(a,b,c,d,e,f,g,h); k_xor( 3,e,f,g,h);
irot(e,f,g,h); ib2(e,f,g,h,a,b,c,d); k_xor( 2,a,b,c,d);
irot(a,b,c,d); ib1(a,b,c,d,e,f,g,h); k_xor( 1,e,f,g,h);
irot(e,f,g,h); ib0(e,f,g,h,a,b,c,d); k_xor( 0,a,b,c,d);
STORE32L(a, &pt[0]);STORE32L(b, &pt[4]);STORE32L(c, &pt[8]);STORE32L(d, &pt[12]);
}
#ifdef CLEAN_STACK
void serpent_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
_serpent_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned long)*24);
}
#endif
int serpent_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{
16,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xdd, 0xd2, 0x6b, 0x98, 0xa5, 0xff, 0xd8, 0x2c,
0x05, 0x34, 0x5a, 0x9d, 0xad, 0xbf, 0xaf, 0x49 }
},
{
16,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 },
{ 0x4a, 0xe9, 0xa2, 0x0b, 0x2b, 0x14, 0xa1, 0x02,
0x90, 0xcb, 0xb8, 0x20, 0xb7, 0xff, 0xb5, 0x10 }
},
{
24,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08 },
{ 0xe1, 0x1b, 0x01, 0x52, 0x4e, 0xa1, 0xf4, 0x65,
0xa2, 0xa2, 0x00, 0x43, 0xeb, 0x9f, 0x7e, 0x8a }
},
{
32,
{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xe0, 0x88, 0x5d, 0x44, 0x60, 0x37, 0x34, 0x69,
0xd1, 0xfa, 0x6c, 0x36, 0xa6, 0xe1, 0xc5, 0x2f }
},
{
32,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x17, 0xc6, 0x25, 0x8e, 0x60, 0x09, 0xe2, 0x82,
0x66, 0x18, 0x69, 0xd5, 0x25, 0xf7, 0xd2, 0x04 }
},
{
32,
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0x9f, 0xe1, 0x43, 0x25, 0x0d, 0x00, 0xe2, 0x56,
0x96, 0xb0, 0x1e, 0x0a, 0x2e, 0xd0, 0x5d, 0xb3 }
}
};
unsigned char buf[2][16];
int x, err;
symmetric_key key;
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
/* setup key */
if ((err = serpent_setup(tests[x].key, tests[x].keylen, 0, &key))!= CRYPT_OK) {
return err;
}
/* encrypt and decrypt */
serpent_ecb_encrypt(tests[x].pt, buf[0], &key);
serpent_ecb_decrypt(buf[0], buf[1], &key);
/* compare */
if (memcmp(buf[0], tests[x].ct, 16) != 0 || memcmp(buf[1], tests[x].pt, 16) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
int serpent_keysize(int *desired_keysize)
{
_ARGCHK(desired_keysize != NULL);
if (*desired_keysize < 16)
return CRYPT_INVALID_KEYSIZE;
if (*desired_keysize > 32)
*desired_keysize = 32;
return CRYPT_OK;
}
#endif

2
sha1.c
View File

@ -14,7 +14,7 @@ const struct _hash_descriptor sha1_desc =
&sha1_test &sha1_test
}; };
#define F0(x,y,z) ( (x&y) | ((~x)&z) ) #define F0(x,y,z) (z ^ (x & (y ^ z)))
#define F1(x,y,z) (x ^ y ^ z) #define F1(x,y,z) (x ^ y ^ z)
#define F2(x,y,z) ((x & y) | (z & (x | y))) #define F2(x,y,z) ((x & y) | (z & (x | y)))
#define F3(x,y,z) (x ^ y ^ z) #define F3(x,y,z) (x ^ y ^ z)

View File

@ -32,7 +32,7 @@ static const unsigned long K[64] = {
}; };
/* Various logical functions */ /* Various logical functions */
#define Ch(x,y,z) ((x & y) | (~x & z)) #define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y)) #define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR((x),(n)) #define S(x, n) ROR((x),(n))
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n)) #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))

View File

@ -59,7 +59,7 @@ CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
}; };
/* Various logical functions */ /* Various logical functions */
#define Ch(x,y,z) ((x & y) | (~x & z)) #define Ch(x,y,z) (z ^ (x & (y ^ z)))
#define Maj(x,y,z) (((x | y) & z) | (x & y)) #define Maj(x,y,z) (((x | y) & z) | (x & y))
#define S(x, n) ROR64((x),(n)) #define S(x, n) ROR64((x),(n))
#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n)) #define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))

BIN
tdcal.pdf Normal file

Binary file not shown.

View File

@ -397,9 +397,9 @@ static unsigned long g_func(unsigned long x, symmetric_key *key)
burn_stack(sizeof(unsigned char) * 4 + sizeof(unsigned long)); burn_stack(sizeof(unsigned char) * 4 + sizeof(unsigned long));
return y; return y;
} }
#endif #endif /* CLEAN_STACK */
#endif #endif /* TWOFISH_SMALL */
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)

View File

@ -28,8 +28,6 @@ int yarrow_start(prng_state *prng)
prng->yarrow.cipher = register_cipher(&twofish_desc); prng->yarrow.cipher = register_cipher(&twofish_desc);
#elif defined(CAST5) #elif defined(CAST5)
prng->yarrow.cipher = register_cipher(&cast5_desc); prng->yarrow.cipher = register_cipher(&cast5_desc);
#elif defined(SERPENT)
prng->yarrow.cipher = register_cipher(&serpent_desc);
#elif defined(SAFER) #elif defined(SAFER)
prng->yarrow.cipher = register_cipher(&saferp_desc); prng->yarrow.cipher = register_cipher(&saferp_desc);
#elif defined(RC5) #elif defined(RC5)