added libtomcrypt-0.75
This commit is contained in:
commit
a6a5fc648b
409
aes.c
Normal file
409
aes.c
Normal file
@ -0,0 +1,409 @@
|
||||
/* This is an independent implementation of the encryption algorithm: */
|
||||
/* */
|
||||
/* RIJNDAEL by Joan Daemen and Vincent Rijmen */
|
||||
/* */
|
||||
/* which is a candidate algorithm in the Advanced Encryption Standard */
|
||||
/* programme of the US National Institute of Standards and Technology. */
|
||||
/* */
|
||||
/* 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. */
|
||||
/* */
|
||||
/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 14th January 1999 */
|
||||
|
||||
|
||||
/* This code has been modified by Tom St Denis for libtomcrypt.a */
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef RIJNDAEL
|
||||
|
||||
const struct _cipher_descriptor rijndael_desc =
|
||||
{
|
||||
"rijndael",
|
||||
6,
|
||||
16, 32, 16, 10,
|
||||
&rijndael_setup,
|
||||
&rijndael_ecb_encrypt,
|
||||
&rijndael_ecb_decrypt,
|
||||
&rijndael_test,
|
||||
&rijndael_keysize
|
||||
};
|
||||
|
||||
#include "aes_tab.c"
|
||||
|
||||
#define byte(x, y) (((x)>>(8*(y)))&255)
|
||||
|
||||
#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, k_len;
|
||||
|
||||
/* check arguments */
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if (numrounds == 0)
|
||||
numrounds = 10 + (2 * ((keylen/8)-2));
|
||||
|
||||
if (keylen != 16 && keylen != 24 && keylen != 32) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
if (numrounds != (10 + (2 * ((keylen/8)-2)))) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
k_len = keylen / 4;
|
||||
for (i = 0; i < k_len; i++) {
|
||||
LOAD32L(in_key[i], key+(4*i));
|
||||
}
|
||||
|
||||
skey->rijndael.k_len = k_len;
|
||||
skey->rijndael.eK[0] = in_key[0]; skey->rijndael.eK[1] = in_key[1];
|
||||
skey->rijndael.eK[2] = in_key[2]; skey->rijndael.eK[3] = in_key[3];
|
||||
|
||||
switch(k_len) {
|
||||
case 4: t = skey->rijndael.eK[3];
|
||||
for(i = 0; i < 10; ++i) {
|
||||
t = ls_box(ROR(t, 8)) ^ rco_tab[i];
|
||||
t ^= skey->rijndael.eK[4 * i]; skey->rijndael.eK[4 * i + 4] = t;
|
||||
t ^= skey->rijndael.eK[4 * i + 1]; skey->rijndael.eK[4 * i + 5] = t;
|
||||
t ^= skey->rijndael.eK[4 * i + 2]; skey->rijndael.eK[4 * i + 6] = t;
|
||||
t ^= skey->rijndael.eK[4 * i + 3]; skey->rijndael.eK[4 * i + 7] = t;
|
||||
}
|
||||
break;
|
||||
case 6: skey->rijndael.eK[4] = in_key[4];
|
||||
t = skey->rijndael.eK[5] = in_key[5];
|
||||
for(i = 0; i < 8; ++i) {
|
||||
t = ls_box(ROR(t, 8)) ^ rco_tab[i];
|
||||
t ^= skey->rijndael.eK[6 * i]; skey->rijndael.eK[6 * i + 6] = t;
|
||||
t ^= skey->rijndael.eK[6 * i + 1]; skey->rijndael.eK[6 * i + 7] = t;
|
||||
t ^= skey->rijndael.eK[6 * i + 2]; skey->rijndael.eK[6 * i + 8] = t;
|
||||
t ^= skey->rijndael.eK[6 * i + 3]; skey->rijndael.eK[6 * i + 9] = t;
|
||||
t ^= skey->rijndael.eK[6 * i + 4]; skey->rijndael.eK[6 * i + 10] = t;
|
||||
t ^= skey->rijndael.eK[6 * i + 5]; skey->rijndael.eK[6 * i + 11] = t;
|
||||
}
|
||||
break;
|
||||
case 8: skey->rijndael.eK[4] = in_key[4];
|
||||
skey->rijndael.eK[5] = in_key[5];
|
||||
skey->rijndael.eK[6] = in_key[6];
|
||||
t = skey->rijndael.eK[7] = in_key[7];
|
||||
for(i = 0; i < 7; ++i) {
|
||||
t = ls_box(ROR(t, 8)) ^ rco_tab[i];
|
||||
t ^= skey->rijndael.eK[8 * i]; skey->rijndael.eK[8 * i + 8] = t;
|
||||
t ^= skey->rijndael.eK[8 * i + 1]; skey->rijndael.eK[8 * i + 9] = t;
|
||||
t ^= skey->rijndael.eK[8 * i + 2]; skey->rijndael.eK[8 * i + 10] = t;
|
||||
t ^= skey->rijndael.eK[8 * i + 3]; skey->rijndael.eK[8 * i + 11] = t;
|
||||
|
||||
t = skey->rijndael.eK[8 * i + 4] ^ ls_box(t); skey->rijndael.eK[8 * i + 12] = t;
|
||||
t ^= skey->rijndael.eK[8 * i + 5]; skey->rijndael.eK[8 * i + 13] = t;
|
||||
t ^= skey->rijndael.eK[8 * i + 6]; skey->rijndael.eK[8 * i + 14] = t;
|
||||
t ^= skey->rijndael.eK[8 * i + 7]; skey->rijndael.eK[8 * i + 15] = t;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
skey->rijndael.dK[0] = skey->rijndael.eK[0];
|
||||
skey->rijndael.dK[1] = skey->rijndael.eK[1];
|
||||
skey->rijndael.dK[2] = skey->rijndael.eK[2];
|
||||
skey->rijndael.dK[3] = skey->rijndael.eK[3];
|
||||
for(i = 4; i < 4 * k_len + 24; ++i) {
|
||||
imix_col(skey->rijndael.dK[i], skey->rijndael.eK[i]);
|
||||
}
|
||||
return CRYPT_OK;
|
||||
};
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
int rijndael_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
|
||||
{
|
||||
int x;
|
||||
x = _rijndael_setup(key, keylen, numrounds, skey);
|
||||
burn_stack(sizeof(unsigned long) * 12 + sizeof(int) * 2);
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* encrypt a block of text */
|
||||
|
||||
#define f_nround(bo, bi, k) \
|
||||
f_rn(bo, bi, 0, k); \
|
||||
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 RIJNDAEL_SMALL
|
||||
|
||||
static void _fnround(unsigned long *bo, unsigned long *bi, unsigned long *k)
|
||||
{
|
||||
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(ct != 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);
|
||||
}
|
||||
|
||||
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 RIJNDAEL_SMALL
|
||||
|
||||
static void _inround(unsigned long *bo, unsigned long *bi, unsigned long *k)
|
||||
{
|
||||
i_nround(bo, bi, k);
|
||||
}
|
||||
|
||||
static void _ilround(unsigned long *bo, unsigned long *bi, unsigned long *k)
|
||||
{
|
||||
i_lround(bo, bi, k);
|
||||
}
|
||||
|
||||
#undef i_nround
|
||||
#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(ct != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
LOAD32L(b0[0], &ct[0]); LOAD32L(b0[1], &ct[4]);
|
||||
LOAD32L(b0[2], &ct[8]); LOAD32L(b0[3], &ct[12]);
|
||||
b0[0] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 24];
|
||||
b0[1] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 25];
|
||||
b0[2] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 26];
|
||||
b0[3] ^= skey->rijndael.eK[4 * skey->rijndael.k_len + 27];
|
||||
kp = skey->rijndael.dK + 4 * (skey->rijndael.k_len + 5);
|
||||
|
||||
if(skey->rijndael.k_len > 6) {
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
}
|
||||
|
||||
if(skey->rijndael.k_len > 4) {
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
}
|
||||
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
i_nround(b1, b0, kp); i_nround(b0, b1, kp);
|
||||
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]);
|
||||
STORE32L(b0[2], &pt[8]); STORE32L(b0[3], &pt[12]);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(b0, sizeof(b0));
|
||||
zeromem(b1, sizeof(b1));
|
||||
#endif
|
||||
};
|
||||
|
||||
int rijndael_test(void)
|
||||
{
|
||||
int errno;
|
||||
|
||||
static const unsigned char pt128[16] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
|
||||
static const unsigned char key128[16] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f };
|
||||
static const unsigned char ct128[16] = {
|
||||
0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
|
||||
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a };
|
||||
|
||||
static const unsigned char key192[24] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
|
||||
static const unsigned char ct192[16] = {
|
||||
0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
|
||||
0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 };
|
||||
|
||||
static const unsigned char key256[32] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f };
|
||||
static const unsigned char ct256[16] = {
|
||||
0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
|
||||
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 };
|
||||
symmetric_key key;
|
||||
unsigned char tmp[2][16];
|
||||
|
||||
if ((errno = rijndael_setup(key128, 16, 0, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
rijndael_ecb_encrypt(pt128, tmp[0], &key);
|
||||
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
|
||||
if (memcmp(tmp[0], ct128, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
if (memcmp(tmp[1], pt128, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
if ((errno = rijndael_setup(key192, 24, 0, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
rijndael_ecb_encrypt(pt128, tmp[0], &key);
|
||||
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
|
||||
if (memcmp(tmp[0], ct192, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
if (memcmp(tmp[1], pt128, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
if ((errno = rijndael_setup(key256, 32, 0, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
rijndael_ecb_encrypt(pt128, tmp[0], &key);
|
||||
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
|
||||
if (memcmp(tmp[0], ct256, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
if (memcmp(tmp[1], pt128, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rijndael_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
|
||||
if (*desired_keysize < 16)
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
if (*desired_keysize < 24) {
|
||||
*desired_keysize = 16;
|
||||
return CRYPT_OK;
|
||||
} else if (*desired_keysize < 32) {
|
||||
*desired_keysize = 24;
|
||||
return CRYPT_OK;
|
||||
} else {
|
||||
*desired_keysize = 32;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
851
aes_tab.c
Normal file
851
aes_tab.c
Normal file
@ -0,0 +1,851 @@
|
||||
/* The precompute tables for AES */
|
||||
|
||||
static const unsigned long ft_tab[4][256] = {
|
||||
{0xa56363c6UL, 0x847c7cf8UL, 0x997777eeUL, 0x8d7b7bf6UL, 0x0df2f2ffUL,
|
||||
0xbd6b6bd6UL, 0xb16f6fdeUL, 0x54c5c591UL, 0x50303060UL, 0x03010102UL,
|
||||
0xa96767ceUL, 0x7d2b2b56UL, 0x19fefee7UL, 0x62d7d7b5UL, 0xe6abab4dUL,
|
||||
0x9a7676ecUL, 0x45caca8fUL, 0x9d82821fUL, 0x40c9c989UL, 0x877d7dfaUL,
|
||||
0x15fafaefUL, 0xeb5959b2UL, 0xc947478eUL, 0x0bf0f0fbUL, 0xecadad41UL,
|
||||
0x67d4d4b3UL, 0xfda2a25fUL, 0xeaafaf45UL, 0xbf9c9c23UL, 0xf7a4a453UL,
|
||||
0x967272e4UL, 0x5bc0c09bUL, 0xc2b7b775UL, 0x1cfdfde1UL, 0xae93933dUL,
|
||||
0x6a26264cUL, 0x5a36366cUL, 0x413f3f7eUL, 0x02f7f7f5UL, 0x4fcccc83UL,
|
||||
0x5c343468UL, 0xf4a5a551UL, 0x34e5e5d1UL, 0x08f1f1f9UL, 0x937171e2UL,
|
||||
0x73d8d8abUL, 0x53313162UL, 0x3f15152aUL, 0x0c040408UL, 0x52c7c795UL,
|
||||
0x65232346UL, 0x5ec3c39dUL, 0x28181830UL, 0xa1969637UL, 0x0f05050aUL,
|
||||
0xb59a9a2fUL, 0x0907070eUL, 0x36121224UL, 0x9b80801bUL, 0x3de2e2dfUL,
|
||||
0x26ebebcdUL, 0x6927274eUL, 0xcdb2b27fUL, 0x9f7575eaUL, 0x1b090912UL,
|
||||
0x9e83831dUL, 0x742c2c58UL, 0x2e1a1a34UL, 0x2d1b1b36UL, 0xb26e6edcUL,
|
||||
0xee5a5ab4UL, 0xfba0a05bUL, 0xf65252a4UL, 0x4d3b3b76UL, 0x61d6d6b7UL,
|
||||
0xceb3b37dUL, 0x7b292952UL, 0x3ee3e3ddUL, 0x712f2f5eUL, 0x97848413UL,
|
||||
0xf55353a6UL, 0x68d1d1b9UL, 0x00000000UL, 0x2cededc1UL, 0x60202040UL,
|
||||
0x1ffcfce3UL, 0xc8b1b179UL, 0xed5b5bb6UL, 0xbe6a6ad4UL, 0x46cbcb8dUL,
|
||||
0xd9bebe67UL, 0x4b393972UL, 0xde4a4a94UL, 0xd44c4c98UL, 0xe85858b0UL,
|
||||
0x4acfcf85UL, 0x6bd0d0bbUL, 0x2aefefc5UL, 0xe5aaaa4fUL, 0x16fbfbedUL,
|
||||
0xc5434386UL, 0xd74d4d9aUL, 0x55333366UL, 0x94858511UL, 0xcf45458aUL,
|
||||
0x10f9f9e9UL, 0x06020204UL, 0x817f7ffeUL, 0xf05050a0UL, 0x443c3c78UL,
|
||||
0xba9f9f25UL, 0xe3a8a84bUL, 0xf35151a2UL, 0xfea3a35dUL, 0xc0404080UL,
|
||||
0x8a8f8f05UL, 0xad92923fUL, 0xbc9d9d21UL, 0x48383870UL, 0x04f5f5f1UL,
|
||||
0xdfbcbc63UL, 0xc1b6b677UL, 0x75dadaafUL, 0x63212142UL, 0x30101020UL,
|
||||
0x1affffe5UL, 0x0ef3f3fdUL, 0x6dd2d2bfUL, 0x4ccdcd81UL, 0x140c0c18UL,
|
||||
0x35131326UL, 0x2fececc3UL, 0xe15f5fbeUL, 0xa2979735UL, 0xcc444488UL,
|
||||
0x3917172eUL, 0x57c4c493UL, 0xf2a7a755UL, 0x827e7efcUL, 0x473d3d7aUL,
|
||||
0xac6464c8UL, 0xe75d5dbaUL, 0x2b191932UL, 0x957373e6UL, 0xa06060c0UL,
|
||||
0x98818119UL, 0xd14f4f9eUL, 0x7fdcdca3UL, 0x66222244UL, 0x7e2a2a54UL,
|
||||
0xab90903bUL, 0x8388880bUL, 0xca46468cUL, 0x29eeeec7UL, 0xd3b8b86bUL,
|
||||
0x3c141428UL, 0x79dedea7UL, 0xe25e5ebcUL, 0x1d0b0b16UL, 0x76dbdbadUL,
|
||||
0x3be0e0dbUL, 0x56323264UL, 0x4e3a3a74UL, 0x1e0a0a14UL, 0xdb494992UL,
|
||||
0x0a06060cUL, 0x6c242448UL, 0xe45c5cb8UL, 0x5dc2c29fUL, 0x6ed3d3bdUL,
|
||||
0xefacac43UL, 0xa66262c4UL, 0xa8919139UL, 0xa4959531UL, 0x37e4e4d3UL,
|
||||
0x8b7979f2UL, 0x32e7e7d5UL, 0x43c8c88bUL, 0x5937376eUL, 0xb76d6ddaUL,
|
||||
0x8c8d8d01UL, 0x64d5d5b1UL, 0xd24e4e9cUL, 0xe0a9a949UL, 0xb46c6cd8UL,
|
||||
0xfa5656acUL, 0x07f4f4f3UL, 0x25eaeacfUL, 0xaf6565caUL, 0x8e7a7af4UL,
|
||||
0xe9aeae47UL, 0x18080810UL, 0xd5baba6fUL, 0x887878f0UL, 0x6f25254aUL,
|
||||
0x722e2e5cUL, 0x241c1c38UL, 0xf1a6a657UL, 0xc7b4b473UL, 0x51c6c697UL,
|
||||
0x23e8e8cbUL, 0x7cdddda1UL, 0x9c7474e8UL, 0x211f1f3eUL, 0xdd4b4b96UL,
|
||||
0xdcbdbd61UL, 0x868b8b0dUL, 0x858a8a0fUL, 0x907070e0UL, 0x423e3e7cUL,
|
||||
0xc4b5b571UL, 0xaa6666ccUL, 0xd8484890UL, 0x05030306UL, 0x01f6f6f7UL,
|
||||
0x120e0e1cUL, 0xa36161c2UL, 0x5f35356aUL, 0xf95757aeUL, 0xd0b9b969UL,
|
||||
0x91868617UL, 0x58c1c199UL, 0x271d1d3aUL, 0xb99e9e27UL, 0x38e1e1d9UL,
|
||||
0x13f8f8ebUL, 0xb398982bUL, 0x33111122UL, 0xbb6969d2UL, 0x70d9d9a9UL,
|
||||
0x898e8e07UL, 0xa7949433UL, 0xb69b9b2dUL, 0x221e1e3cUL, 0x92878715UL,
|
||||
0x20e9e9c9UL, 0x49cece87UL, 0xff5555aaUL, 0x78282850UL, 0x7adfdfa5UL,
|
||||
0x8f8c8c03UL, 0xf8a1a159UL, 0x80898909UL, 0x170d0d1aUL, 0xdabfbf65UL,
|
||||
0x31e6e6d7UL, 0xc6424284UL, 0xb86868d0UL, 0xc3414182UL, 0xb0999929UL,
|
||||
0x772d2d5aUL, 0x110f0f1eUL, 0xcbb0b07bUL, 0xfc5454a8UL, 0xd6bbbb6dUL,
|
||||
0x3a16162cUL},
|
||||
{0x6363c6a5UL, 0x7c7cf884UL, 0x7777ee99UL, 0x7b7bf68dUL, 0xf2f2ff0dUL,
|
||||
0x6b6bd6bdUL, 0x6f6fdeb1UL, 0xc5c59154UL, 0x30306050UL, 0x01010203UL,
|
||||
0x6767cea9UL, 0x2b2b567dUL, 0xfefee719UL, 0xd7d7b562UL, 0xabab4de6UL,
|
||||
0x7676ec9aUL, 0xcaca8f45UL, 0x82821f9dUL, 0xc9c98940UL, 0x7d7dfa87UL,
|
||||
0xfafaef15UL, 0x5959b2ebUL, 0x47478ec9UL, 0xf0f0fb0bUL, 0xadad41ecUL,
|
||||
0xd4d4b367UL, 0xa2a25ffdUL, 0xafaf45eaUL, 0x9c9c23bfUL, 0xa4a453f7UL,
|
||||
0x7272e496UL, 0xc0c09b5bUL, 0xb7b775c2UL, 0xfdfde11cUL, 0x93933daeUL,
|
||||
0x26264c6aUL, 0x36366c5aUL, 0x3f3f7e41UL, 0xf7f7f502UL, 0xcccc834fUL,
|
||||
0x3434685cUL, 0xa5a551f4UL, 0xe5e5d134UL, 0xf1f1f908UL, 0x7171e293UL,
|
||||
0xd8d8ab73UL, 0x31316253UL, 0x15152a3fUL, 0x0404080cUL, 0xc7c79552UL,
|
||||
0x23234665UL, 0xc3c39d5eUL, 0x18183028UL, 0x969637a1UL, 0x05050a0fUL,
|
||||
0x9a9a2fb5UL, 0x07070e09UL, 0x12122436UL, 0x80801b9bUL, 0xe2e2df3dUL,
|
||||
0xebebcd26UL, 0x27274e69UL, 0xb2b27fcdUL, 0x7575ea9fUL, 0x0909121bUL,
|
||||
0x83831d9eUL, 0x2c2c5874UL, 0x1a1a342eUL, 0x1b1b362dUL, 0x6e6edcb2UL,
|
||||
0x5a5ab4eeUL, 0xa0a05bfbUL, 0x5252a4f6UL, 0x3b3b764dUL, 0xd6d6b761UL,
|
||||
0xb3b37dceUL, 0x2929527bUL, 0xe3e3dd3eUL, 0x2f2f5e71UL, 0x84841397UL,
|
||||
0x5353a6f5UL, 0xd1d1b968UL, 0x00000000UL, 0xededc12cUL, 0x20204060UL,
|
||||
0xfcfce31fUL, 0xb1b179c8UL, 0x5b5bb6edUL, 0x6a6ad4beUL, 0xcbcb8d46UL,
|
||||
0xbebe67d9UL, 0x3939724bUL, 0x4a4a94deUL, 0x4c4c98d4UL, 0x5858b0e8UL,
|
||||
0xcfcf854aUL, 0xd0d0bb6bUL, 0xefefc52aUL, 0xaaaa4fe5UL, 0xfbfbed16UL,
|
||||
0x434386c5UL, 0x4d4d9ad7UL, 0x33336655UL, 0x85851194UL, 0x45458acfUL,
|
||||
0xf9f9e910UL, 0x02020406UL, 0x7f7ffe81UL, 0x5050a0f0UL, 0x3c3c7844UL,
|
||||
0x9f9f25baUL, 0xa8a84be3UL, 0x5151a2f3UL, 0xa3a35dfeUL, 0x404080c0UL,
|
||||
0x8f8f058aUL, 0x92923fadUL, 0x9d9d21bcUL, 0x38387048UL, 0xf5f5f104UL,
|
||||
0xbcbc63dfUL, 0xb6b677c1UL, 0xdadaaf75UL, 0x21214263UL, 0x10102030UL,
|
||||
0xffffe51aUL, 0xf3f3fd0eUL, 0xd2d2bf6dUL, 0xcdcd814cUL, 0x0c0c1814UL,
|
||||
0x13132635UL, 0xececc32fUL, 0x5f5fbee1UL, 0x979735a2UL, 0x444488ccUL,
|
||||
0x17172e39UL, 0xc4c49357UL, 0xa7a755f2UL, 0x7e7efc82UL, 0x3d3d7a47UL,
|
||||
0x6464c8acUL, 0x5d5dbae7UL, 0x1919322bUL, 0x7373e695UL, 0x6060c0a0UL,
|
||||
0x81811998UL, 0x4f4f9ed1UL, 0xdcdca37fUL, 0x22224466UL, 0x2a2a547eUL,
|
||||
0x90903babUL, 0x88880b83UL, 0x46468ccaUL, 0xeeeec729UL, 0xb8b86bd3UL,
|
||||
0x1414283cUL, 0xdedea779UL, 0x5e5ebce2UL, 0x0b0b161dUL, 0xdbdbad76UL,
|
||||
0xe0e0db3bUL, 0x32326456UL, 0x3a3a744eUL, 0x0a0a141eUL, 0x494992dbUL,
|
||||
0x06060c0aUL, 0x2424486cUL, 0x5c5cb8e4UL, 0xc2c29f5dUL, 0xd3d3bd6eUL,
|
||||
0xacac43efUL, 0x6262c4a6UL, 0x919139a8UL, 0x959531a4UL, 0xe4e4d337UL,
|
||||
0x7979f28bUL, 0xe7e7d532UL, 0xc8c88b43UL, 0x37376e59UL, 0x6d6ddab7UL,
|
||||
0x8d8d018cUL, 0xd5d5b164UL, 0x4e4e9cd2UL, 0xa9a949e0UL, 0x6c6cd8b4UL,
|
||||
0x5656acfaUL, 0xf4f4f307UL, 0xeaeacf25UL, 0x6565caafUL, 0x7a7af48eUL,
|
||||
0xaeae47e9UL, 0x08081018UL, 0xbaba6fd5UL, 0x7878f088UL, 0x25254a6fUL,
|
||||
0x2e2e5c72UL, 0x1c1c3824UL, 0xa6a657f1UL, 0xb4b473c7UL, 0xc6c69751UL,
|
||||
0xe8e8cb23UL, 0xdddda17cUL, 0x7474e89cUL, 0x1f1f3e21UL, 0x4b4b96ddUL,
|
||||
0xbdbd61dcUL, 0x8b8b0d86UL, 0x8a8a0f85UL, 0x7070e090UL, 0x3e3e7c42UL,
|
||||
0xb5b571c4UL, 0x6666ccaaUL, 0x484890d8UL, 0x03030605UL, 0xf6f6f701UL,
|
||||
0x0e0e1c12UL, 0x6161c2a3UL, 0x35356a5fUL, 0x5757aef9UL, 0xb9b969d0UL,
|
||||
0x86861791UL, 0xc1c19958UL, 0x1d1d3a27UL, 0x9e9e27b9UL, 0xe1e1d938UL,
|
||||
0xf8f8eb13UL, 0x98982bb3UL, 0x11112233UL, 0x6969d2bbUL, 0xd9d9a970UL,
|
||||
0x8e8e0789UL, 0x949433a7UL, 0x9b9b2db6UL, 0x1e1e3c22UL, 0x87871592UL,
|
||||
0xe9e9c920UL, 0xcece8749UL, 0x5555aaffUL, 0x28285078UL, 0xdfdfa57aUL,
|
||||
0x8c8c038fUL, 0xa1a159f8UL, 0x89890980UL, 0x0d0d1a17UL, 0xbfbf65daUL,
|
||||
0xe6e6d731UL, 0x424284c6UL, 0x6868d0b8UL, 0x414182c3UL, 0x999929b0UL,
|
||||
0x2d2d5a77UL, 0x0f0f1e11UL, 0xb0b07bcbUL, 0x5454a8fcUL, 0xbbbb6dd6UL,
|
||||
0x16162c3aUL},
|
||||
{0x63c6a563UL, 0x7cf8847cUL, 0x77ee9977UL, 0x7bf68d7bUL, 0xf2ff0df2UL,
|
||||
0x6bd6bd6bUL, 0x6fdeb16fUL, 0xc59154c5UL, 0x30605030UL, 0x01020301UL,
|
||||
0x67cea967UL, 0x2b567d2bUL, 0xfee719feUL, 0xd7b562d7UL, 0xab4de6abUL,
|
||||
0x76ec9a76UL, 0xca8f45caUL, 0x821f9d82UL, 0xc98940c9UL, 0x7dfa877dUL,
|
||||
0xfaef15faUL, 0x59b2eb59UL, 0x478ec947UL, 0xf0fb0bf0UL, 0xad41ecadUL,
|
||||
0xd4b367d4UL, 0xa25ffda2UL, 0xaf45eaafUL, 0x9c23bf9cUL, 0xa453f7a4UL,
|
||||
0x72e49672UL, 0xc09b5bc0UL, 0xb775c2b7UL, 0xfde11cfdUL, 0x933dae93UL,
|
||||
0x264c6a26UL, 0x366c5a36UL, 0x3f7e413fUL, 0xf7f502f7UL, 0xcc834fccUL,
|
||||
0x34685c34UL, 0xa551f4a5UL, 0xe5d134e5UL, 0xf1f908f1UL, 0x71e29371UL,
|
||||
0xd8ab73d8UL, 0x31625331UL, 0x152a3f15UL, 0x04080c04UL, 0xc79552c7UL,
|
||||
0x23466523UL, 0xc39d5ec3UL, 0x18302818UL, 0x9637a196UL, 0x050a0f05UL,
|
||||
0x9a2fb59aUL, 0x070e0907UL, 0x12243612UL, 0x801b9b80UL, 0xe2df3de2UL,
|
||||
0xebcd26ebUL, 0x274e6927UL, 0xb27fcdb2UL, 0x75ea9f75UL, 0x09121b09UL,
|
||||
0x831d9e83UL, 0x2c58742cUL, 0x1a342e1aUL, 0x1b362d1bUL, 0x6edcb26eUL,
|
||||
0x5ab4ee5aUL, 0xa05bfba0UL, 0x52a4f652UL, 0x3b764d3bUL, 0xd6b761d6UL,
|
||||
0xb37dceb3UL, 0x29527b29UL, 0xe3dd3ee3UL, 0x2f5e712fUL, 0x84139784UL,
|
||||
0x53a6f553UL, 0xd1b968d1UL, 0x00000000UL, 0xedc12cedUL, 0x20406020UL,
|
||||
0xfce31ffcUL, 0xb179c8b1UL, 0x5bb6ed5bUL, 0x6ad4be6aUL, 0xcb8d46cbUL,
|
||||
0xbe67d9beUL, 0x39724b39UL, 0x4a94de4aUL, 0x4c98d44cUL, 0x58b0e858UL,
|
||||
0xcf854acfUL, 0xd0bb6bd0UL, 0xefc52aefUL, 0xaa4fe5aaUL, 0xfbed16fbUL,
|
||||
0x4386c543UL, 0x4d9ad74dUL, 0x33665533UL, 0x85119485UL, 0x458acf45UL,
|
||||
0xf9e910f9UL, 0x02040602UL, 0x7ffe817fUL, 0x50a0f050UL, 0x3c78443cUL,
|
||||
0x9f25ba9fUL, 0xa84be3a8UL, 0x51a2f351UL, 0xa35dfea3UL, 0x4080c040UL,
|
||||
0x8f058a8fUL, 0x923fad92UL, 0x9d21bc9dUL, 0x38704838UL, 0xf5f104f5UL,
|
||||
0xbc63dfbcUL, 0xb677c1b6UL, 0xdaaf75daUL, 0x21426321UL, 0x10203010UL,
|
||||
0xffe51affUL, 0xf3fd0ef3UL, 0xd2bf6dd2UL, 0xcd814ccdUL, 0x0c18140cUL,
|
||||
0x13263513UL, 0xecc32fecUL, 0x5fbee15fUL, 0x9735a297UL, 0x4488cc44UL,
|
||||
0x172e3917UL, 0xc49357c4UL, 0xa755f2a7UL, 0x7efc827eUL, 0x3d7a473dUL,
|
||||
0x64c8ac64UL, 0x5dbae75dUL, 0x19322b19UL, 0x73e69573UL, 0x60c0a060UL,
|
||||
0x81199881UL, 0x4f9ed14fUL, 0xdca37fdcUL, 0x22446622UL, 0x2a547e2aUL,
|
||||
0x903bab90UL, 0x880b8388UL, 0x468cca46UL, 0xeec729eeUL, 0xb86bd3b8UL,
|
||||
0x14283c14UL, 0xdea779deUL, 0x5ebce25eUL, 0x0b161d0bUL, 0xdbad76dbUL,
|
||||
0xe0db3be0UL, 0x32645632UL, 0x3a744e3aUL, 0x0a141e0aUL, 0x4992db49UL,
|
||||
0x060c0a06UL, 0x24486c24UL, 0x5cb8e45cUL, 0xc29f5dc2UL, 0xd3bd6ed3UL,
|
||||
0xac43efacUL, 0x62c4a662UL, 0x9139a891UL, 0x9531a495UL, 0xe4d337e4UL,
|
||||
0x79f28b79UL, 0xe7d532e7UL, 0xc88b43c8UL, 0x376e5937UL, 0x6ddab76dUL,
|
||||
0x8d018c8dUL, 0xd5b164d5UL, 0x4e9cd24eUL, 0xa949e0a9UL, 0x6cd8b46cUL,
|
||||
0x56acfa56UL, 0xf4f307f4UL, 0xeacf25eaUL, 0x65caaf65UL, 0x7af48e7aUL,
|
||||
0xae47e9aeUL, 0x08101808UL, 0xba6fd5baUL, 0x78f08878UL, 0x254a6f25UL,
|
||||
0x2e5c722eUL, 0x1c38241cUL, 0xa657f1a6UL, 0xb473c7b4UL, 0xc69751c6UL,
|
||||
0xe8cb23e8UL, 0xdda17cddUL, 0x74e89c74UL, 0x1f3e211fUL, 0x4b96dd4bUL,
|
||||
0xbd61dcbdUL, 0x8b0d868bUL, 0x8a0f858aUL, 0x70e09070UL, 0x3e7c423eUL,
|
||||
0xb571c4b5UL, 0x66ccaa66UL, 0x4890d848UL, 0x03060503UL, 0xf6f701f6UL,
|
||||
0x0e1c120eUL, 0x61c2a361UL, 0x356a5f35UL, 0x57aef957UL, 0xb969d0b9UL,
|
||||
0x86179186UL, 0xc19958c1UL, 0x1d3a271dUL, 0x9e27b99eUL, 0xe1d938e1UL,
|
||||
0xf8eb13f8UL, 0x982bb398UL, 0x11223311UL, 0x69d2bb69UL, 0xd9a970d9UL,
|
||||
0x8e07898eUL, 0x9433a794UL, 0x9b2db69bUL, 0x1e3c221eUL, 0x87159287UL,
|
||||
0xe9c920e9UL, 0xce8749ceUL, 0x55aaff55UL, 0x28507828UL, 0xdfa57adfUL,
|
||||
0x8c038f8cUL, 0xa159f8a1UL, 0x89098089UL, 0x0d1a170dUL, 0xbf65dabfUL,
|
||||
0xe6d731e6UL, 0x4284c642UL, 0x68d0b868UL, 0x4182c341UL, 0x9929b099UL,
|
||||
0x2d5a772dUL, 0x0f1e110fUL, 0xb07bcbb0UL, 0x54a8fc54UL, 0xbb6dd6bbUL,
|
||||
0x162c3a16UL},
|
||||
{0xc6a56363UL, 0xf8847c7cUL, 0xee997777UL, 0xf68d7b7bUL, 0xff0df2f2UL,
|
||||
0xd6bd6b6bUL, 0xdeb16f6fUL, 0x9154c5c5UL, 0x60503030UL, 0x02030101UL,
|
||||
0xcea96767UL, 0x567d2b2bUL, 0xe719fefeUL, 0xb562d7d7UL, 0x4de6ababUL,
|
||||
0xec9a7676UL, 0x8f45cacaUL, 0x1f9d8282UL, 0x8940c9c9UL, 0xfa877d7dUL,
|
||||
0xef15fafaUL, 0xb2eb5959UL, 0x8ec94747UL, 0xfb0bf0f0UL, 0x41ecadadUL,
|
||||
0xb367d4d4UL, 0x5ffda2a2UL, 0x45eaafafUL, 0x23bf9c9cUL, 0x53f7a4a4UL,
|
||||
0xe4967272UL, 0x9b5bc0c0UL, 0x75c2b7b7UL, 0xe11cfdfdUL, 0x3dae9393UL,
|
||||
0x4c6a2626UL, 0x6c5a3636UL, 0x7e413f3fUL, 0xf502f7f7UL, 0x834fccccUL,
|
||||
0x685c3434UL, 0x51f4a5a5UL, 0xd134e5e5UL, 0xf908f1f1UL, 0xe2937171UL,
|
||||
0xab73d8d8UL, 0x62533131UL, 0x2a3f1515UL, 0x080c0404UL, 0x9552c7c7UL,
|
||||
0x46652323UL, 0x9d5ec3c3UL, 0x30281818UL, 0x37a19696UL, 0x0a0f0505UL,
|
||||
0x2fb59a9aUL, 0x0e090707UL, 0x24361212UL, 0x1b9b8080UL, 0xdf3de2e2UL,
|
||||
0xcd26ebebUL, 0x4e692727UL, 0x7fcdb2b2UL, 0xea9f7575UL, 0x121b0909UL,
|
||||
0x1d9e8383UL, 0x58742c2cUL, 0x342e1a1aUL, 0x362d1b1bUL, 0xdcb26e6eUL,
|
||||
0xb4ee5a5aUL, 0x5bfba0a0UL, 0xa4f65252UL, 0x764d3b3bUL, 0xb761d6d6UL,
|
||||
0x7dceb3b3UL, 0x527b2929UL, 0xdd3ee3e3UL, 0x5e712f2fUL, 0x13978484UL,
|
||||
0xa6f55353UL, 0xb968d1d1UL, 0x00000000UL, 0xc12cededUL, 0x40602020UL,
|
||||
0xe31ffcfcUL, 0x79c8b1b1UL, 0xb6ed5b5bUL, 0xd4be6a6aUL, 0x8d46cbcbUL,
|
||||
0x67d9bebeUL, 0x724b3939UL, 0x94de4a4aUL, 0x98d44c4cUL, 0xb0e85858UL,
|
||||
0x854acfcfUL, 0xbb6bd0d0UL, 0xc52aefefUL, 0x4fe5aaaaUL, 0xed16fbfbUL,
|
||||
0x86c54343UL, 0x9ad74d4dUL, 0x66553333UL, 0x11948585UL, 0x8acf4545UL,
|
||||
0xe910f9f9UL, 0x04060202UL, 0xfe817f7fUL, 0xa0f05050UL, 0x78443c3cUL,
|
||||
0x25ba9f9fUL, 0x4be3a8a8UL, 0xa2f35151UL, 0x5dfea3a3UL, 0x80c04040UL,
|
||||
0x058a8f8fUL, 0x3fad9292UL, 0x21bc9d9dUL, 0x70483838UL, 0xf104f5f5UL,
|
||||
0x63dfbcbcUL, 0x77c1b6b6UL, 0xaf75dadaUL, 0x42632121UL, 0x20301010UL,
|
||||
0xe51affffUL, 0xfd0ef3f3UL, 0xbf6dd2d2UL, 0x814ccdcdUL, 0x18140c0cUL,
|
||||
0x26351313UL, 0xc32fececUL, 0xbee15f5fUL, 0x35a29797UL, 0x88cc4444UL,
|
||||
0x2e391717UL, 0x9357c4c4UL, 0x55f2a7a7UL, 0xfc827e7eUL, 0x7a473d3dUL,
|
||||
0xc8ac6464UL, 0xbae75d5dUL, 0x322b1919UL, 0xe6957373UL, 0xc0a06060UL,
|
||||
0x19988181UL, 0x9ed14f4fUL, 0xa37fdcdcUL, 0x44662222UL, 0x547e2a2aUL,
|
||||
0x3bab9090UL, 0x0b838888UL, 0x8cca4646UL, 0xc729eeeeUL, 0x6bd3b8b8UL,
|
||||
0x283c1414UL, 0xa779dedeUL, 0xbce25e5eUL, 0x161d0b0bUL, 0xad76dbdbUL,
|
||||
0xdb3be0e0UL, 0x64563232UL, 0x744e3a3aUL, 0x141e0a0aUL, 0x92db4949UL,
|
||||
0x0c0a0606UL, 0x486c2424UL, 0xb8e45c5cUL, 0x9f5dc2c2UL, 0xbd6ed3d3UL,
|
||||
0x43efacacUL, 0xc4a66262UL, 0x39a89191UL, 0x31a49595UL, 0xd337e4e4UL,
|
||||
0xf28b7979UL, 0xd532e7e7UL, 0x8b43c8c8UL, 0x6e593737UL, 0xdab76d6dUL,
|
||||
0x018c8d8dUL, 0xb164d5d5UL, 0x9cd24e4eUL, 0x49e0a9a9UL, 0xd8b46c6cUL,
|
||||
0xacfa5656UL, 0xf307f4f4UL, 0xcf25eaeaUL, 0xcaaf6565UL, 0xf48e7a7aUL,
|
||||
0x47e9aeaeUL, 0x10180808UL, 0x6fd5babaUL, 0xf0887878UL, 0x4a6f2525UL,
|
||||
0x5c722e2eUL, 0x38241c1cUL, 0x57f1a6a6UL, 0x73c7b4b4UL, 0x9751c6c6UL,
|
||||
0xcb23e8e8UL, 0xa17cddddUL, 0xe89c7474UL, 0x3e211f1fUL, 0x96dd4b4bUL,
|
||||
0x61dcbdbdUL, 0x0d868b8bUL, 0x0f858a8aUL, 0xe0907070UL, 0x7c423e3eUL,
|
||||
0x71c4b5b5UL, 0xccaa6666UL, 0x90d84848UL, 0x06050303UL, 0xf701f6f6UL,
|
||||
0x1c120e0eUL, 0xc2a36161UL, 0x6a5f3535UL, 0xaef95757UL, 0x69d0b9b9UL,
|
||||
0x17918686UL, 0x9958c1c1UL, 0x3a271d1dUL, 0x27b99e9eUL, 0xd938e1e1UL,
|
||||
0xeb13f8f8UL, 0x2bb39898UL, 0x22331111UL, 0xd2bb6969UL, 0xa970d9d9UL,
|
||||
0x07898e8eUL, 0x33a79494UL, 0x2db69b9bUL, 0x3c221e1eUL, 0x15928787UL,
|
||||
0xc920e9e9UL, 0x8749ceceUL, 0xaaff5555UL, 0x50782828UL, 0xa57adfdfUL,
|
||||
0x038f8c8cUL, 0x59f8a1a1UL, 0x09808989UL, 0x1a170d0dUL, 0x65dabfbfUL,
|
||||
0xd731e6e6UL, 0x84c64242UL, 0xd0b86868UL, 0x82c34141UL, 0x29b09999UL,
|
||||
0x5a772d2dUL, 0x1e110f0fUL, 0x7bcbb0b0UL, 0xa8fc5454UL, 0x6dd6bbbbUL,
|
||||
0x2c3a1616UL}
|
||||
};
|
||||
|
||||
static const unsigned long it_tab[4][256] = {
|
||||
{0x50a7f451UL, 0x5365417eUL, 0xc3a4171aUL, 0x965e273aUL, 0xcb6bab3bUL,
|
||||
0xf1459d1fUL, 0xab58faacUL, 0x9303e34bUL, 0x55fa3020UL, 0xf66d76adUL,
|
||||
0x9176cc88UL, 0x254c02f5UL, 0xfcd7e54fUL, 0xd7cb2ac5UL, 0x80443526UL,
|
||||
0x8fa362b5UL, 0x495ab1deUL, 0x671bba25UL, 0x980eea45UL, 0xe1c0fe5dUL,
|
||||
0x02752fc3UL, 0x12f04c81UL, 0xa397468dUL, 0xc6f9d36bUL, 0xe75f8f03UL,
|
||||
0x959c9215UL, 0xeb7a6dbfUL, 0xda595295UL, 0x2d83bed4UL, 0xd3217458UL,
|
||||
0x2969e049UL, 0x44c8c98eUL, 0x6a89c275UL, 0x78798ef4UL, 0x6b3e5899UL,
|
||||
0xdd71b927UL, 0xb64fe1beUL, 0x17ad88f0UL, 0x66ac20c9UL, 0xb43ace7dUL,
|
||||
0x184adf63UL, 0x82311ae5UL, 0x60335197UL, 0x457f5362UL, 0xe07764b1UL,
|
||||
0x84ae6bbbUL, 0x1ca081feUL, 0x942b08f9UL, 0x58684870UL, 0x19fd458fUL,
|
||||
0x876cde94UL, 0xb7f87b52UL, 0x23d373abUL, 0xe2024b72UL, 0x578f1fe3UL,
|
||||
0x2aab5566UL, 0x0728ebb2UL, 0x03c2b52fUL, 0x9a7bc586UL, 0xa50837d3UL,
|
||||
0xf2872830UL, 0xb2a5bf23UL, 0xba6a0302UL, 0x5c8216edUL, 0x2b1ccf8aUL,
|
||||
0x92b479a7UL, 0xf0f207f3UL, 0xa1e2694eUL, 0xcdf4da65UL, 0xd5be0506UL,
|
||||
0x1f6234d1UL, 0x8afea6c4UL, 0x9d532e34UL, 0xa055f3a2UL, 0x32e18a05UL,
|
||||
0x75ebf6a4UL, 0x39ec830bUL, 0xaaef6040UL, 0x069f715eUL, 0x51106ebdUL,
|
||||
0xf98a213eUL, 0x3d06dd96UL, 0xae053eddUL, 0x46bde64dUL, 0xb58d5491UL,
|
||||
0x055dc471UL, 0x6fd40604UL, 0xff155060UL, 0x24fb9819UL, 0x97e9bdd6UL,
|
||||
0xcc434089UL, 0x779ed967UL, 0xbd42e8b0UL, 0x888b8907UL, 0x385b19e7UL,
|
||||
0xdbeec879UL, 0x470a7ca1UL, 0xe90f427cUL, 0xc91e84f8UL, 0x00000000UL,
|
||||
0x83868009UL, 0x48ed2b32UL, 0xac70111eUL, 0x4e725a6cUL, 0xfbff0efdUL,
|
||||
0x5638850fUL, 0x1ed5ae3dUL, 0x27392d36UL, 0x64d90f0aUL, 0x21a65c68UL,
|
||||
0xd1545b9bUL, 0x3a2e3624UL, 0xb1670a0cUL, 0x0fe75793UL, 0xd296eeb4UL,
|
||||
0x9e919b1bUL, 0x4fc5c080UL, 0xa220dc61UL, 0x694b775aUL, 0x161a121cUL,
|
||||
0x0aba93e2UL, 0xe52aa0c0UL, 0x43e0223cUL, 0x1d171b12UL, 0x0b0d090eUL,
|
||||
0xadc78bf2UL, 0xb9a8b62dUL, 0xc8a91e14UL, 0x8519f157UL, 0x4c0775afUL,
|
||||
0xbbdd99eeUL, 0xfd607fa3UL, 0x9f2601f7UL, 0xbcf5725cUL, 0xc53b6644UL,
|
||||
0x347efb5bUL, 0x7629438bUL, 0xdcc623cbUL, 0x68fcedb6UL, 0x63f1e4b8UL,
|
||||
0xcadc31d7UL, 0x10856342UL, 0x40229713UL, 0x2011c684UL, 0x7d244a85UL,
|
||||
0xf83dbbd2UL, 0x1132f9aeUL, 0x6da129c7UL, 0x4b2f9e1dUL, 0xf330b2dcUL,
|
||||
0xec52860dUL, 0xd0e3c177UL, 0x6c16b32bUL, 0x99b970a9UL, 0xfa489411UL,
|
||||
0x2264e947UL, 0xc48cfca8UL, 0x1a3ff0a0UL, 0xd82c7d56UL, 0xef903322UL,
|
||||
0xc74e4987UL, 0xc1d138d9UL, 0xfea2ca8cUL, 0x360bd498UL, 0xcf81f5a6UL,
|
||||
0x28de7aa5UL, 0x268eb7daUL, 0xa4bfad3fUL, 0xe49d3a2cUL, 0x0d927850UL,
|
||||
0x9bcc5f6aUL, 0x62467e54UL, 0xc2138df6UL, 0xe8b8d890UL, 0x5ef7392eUL,
|
||||
0xf5afc382UL, 0xbe805d9fUL, 0x7c93d069UL, 0xa92dd56fUL, 0xb31225cfUL,
|
||||
0x3b99acc8UL, 0xa77d1810UL, 0x6e639ce8UL, 0x7bbb3bdbUL, 0x097826cdUL,
|
||||
0xf418596eUL, 0x01b79aecUL, 0xa89a4f83UL, 0x656e95e6UL, 0x7ee6ffaaUL,
|
||||
0x08cfbc21UL, 0xe6e815efUL, 0xd99be7baUL, 0xce366f4aUL, 0xd4099feaUL,
|
||||
0xd67cb029UL, 0xafb2a431UL, 0x31233f2aUL, 0x3094a5c6UL, 0xc066a235UL,
|
||||
0x37bc4e74UL, 0xa6ca82fcUL, 0xb0d090e0UL, 0x15d8a733UL, 0x4a9804f1UL,
|
||||
0xf7daec41UL, 0x0e50cd7fUL, 0x2ff69117UL, 0x8dd64d76UL, 0x4db0ef43UL,
|
||||
0x544daaccUL, 0xdf0496e4UL, 0xe3b5d19eUL, 0x1b886a4cUL, 0xb81f2cc1UL,
|
||||
0x7f516546UL, 0x04ea5e9dUL, 0x5d358c01UL, 0x737487faUL, 0x2e410bfbUL,
|
||||
0x5a1d67b3UL, 0x52d2db92UL, 0x335610e9UL, 0x1347d66dUL, 0x8c61d79aUL,
|
||||
0x7a0ca137UL, 0x8e14f859UL, 0x893c13ebUL, 0xee27a9ceUL, 0x35c961b7UL,
|
||||
0xede51ce1UL, 0x3cb1477aUL, 0x59dfd29cUL, 0x3f73f255UL, 0x79ce1418UL,
|
||||
0xbf37c773UL, 0xeacdf753UL, 0x5baafd5fUL, 0x146f3ddfUL, 0x86db4478UL,
|
||||
0x81f3afcaUL, 0x3ec468b9UL, 0x2c342438UL, 0x5f40a3c2UL, 0x72c31d16UL,
|
||||
0x0c25e2bcUL, 0x8b493c28UL, 0x41950dffUL, 0x7101a839UL, 0xdeb30c08UL,
|
||||
0x9ce4b4d8UL, 0x90c15664UL, 0x6184cb7bUL, 0x70b632d5UL, 0x745c6c48UL,
|
||||
0x4257b8d0UL},
|
||||
{0xa7f45150UL, 0x65417e53UL, 0xa4171ac3UL, 0x5e273a96UL, 0x6bab3bcbUL,
|
||||
0x459d1ff1UL, 0x58faacabUL, 0x03e34b93UL, 0xfa302055UL, 0x6d76adf6UL,
|
||||
0x76cc8891UL, 0x4c02f525UL, 0xd7e54ffcUL, 0xcb2ac5d7UL, 0x44352680UL,
|
||||
0xa362b58fUL, 0x5ab1de49UL, 0x1bba2567UL, 0x0eea4598UL, 0xc0fe5de1UL,
|
||||
0x752fc302UL, 0xf04c8112UL, 0x97468da3UL, 0xf9d36bc6UL, 0x5f8f03e7UL,
|
||||
0x9c921595UL, 0x7a6dbfebUL, 0x595295daUL, 0x83bed42dUL, 0x217458d3UL,
|
||||
0x69e04929UL, 0xc8c98e44UL, 0x89c2756aUL, 0x798ef478UL, 0x3e58996bUL,
|
||||
0x71b927ddUL, 0x4fe1beb6UL, 0xad88f017UL, 0xac20c966UL, 0x3ace7db4UL,
|
||||
0x4adf6318UL, 0x311ae582UL, 0x33519760UL, 0x7f536245UL, 0x7764b1e0UL,
|
||||
0xae6bbb84UL, 0xa081fe1cUL, 0x2b08f994UL, 0x68487058UL, 0xfd458f19UL,
|
||||
0x6cde9487UL, 0xf87b52b7UL, 0xd373ab23UL, 0x024b72e2UL, 0x8f1fe357UL,
|
||||
0xab55662aUL, 0x28ebb207UL, 0xc2b52f03UL, 0x7bc5869aUL, 0x0837d3a5UL,
|
||||
0x872830f2UL, 0xa5bf23b2UL, 0x6a0302baUL, 0x8216ed5cUL, 0x1ccf8a2bUL,
|
||||
0xb479a792UL, 0xf207f3f0UL, 0xe2694ea1UL, 0xf4da65cdUL, 0xbe0506d5UL,
|
||||
0x6234d11fUL, 0xfea6c48aUL, 0x532e349dUL, 0x55f3a2a0UL, 0xe18a0532UL,
|
||||
0xebf6a475UL, 0xec830b39UL, 0xef6040aaUL, 0x9f715e06UL, 0x106ebd51UL,
|
||||
0x8a213ef9UL, 0x06dd963dUL, 0x053eddaeUL, 0xbde64d46UL, 0x8d5491b5UL,
|
||||
0x5dc47105UL, 0xd406046fUL, 0x155060ffUL, 0xfb981924UL, 0xe9bdd697UL,
|
||||
0x434089ccUL, 0x9ed96777UL, 0x42e8b0bdUL, 0x8b890788UL, 0x5b19e738UL,
|
||||
0xeec879dbUL, 0x0a7ca147UL, 0x0f427ce9UL, 0x1e84f8c9UL, 0x00000000UL,
|
||||
0x86800983UL, 0xed2b3248UL, 0x70111eacUL, 0x725a6c4eUL, 0xff0efdfbUL,
|
||||
0x38850f56UL, 0xd5ae3d1eUL, 0x392d3627UL, 0xd90f0a64UL, 0xa65c6821UL,
|
||||
0x545b9bd1UL, 0x2e36243aUL, 0x670a0cb1UL, 0xe757930fUL, 0x96eeb4d2UL,
|
||||
0x919b1b9eUL, 0xc5c0804fUL, 0x20dc61a2UL, 0x4b775a69UL, 0x1a121c16UL,
|
||||
0xba93e20aUL, 0x2aa0c0e5UL, 0xe0223c43UL, 0x171b121dUL, 0x0d090e0bUL,
|
||||
0xc78bf2adUL, 0xa8b62db9UL, 0xa91e14c8UL, 0x19f15785UL, 0x0775af4cUL,
|
||||
0xdd99eebbUL, 0x607fa3fdUL, 0x2601f79fUL, 0xf5725cbcUL, 0x3b6644c5UL,
|
||||
0x7efb5b34UL, 0x29438b76UL, 0xc623cbdcUL, 0xfcedb668UL, 0xf1e4b863UL,
|
||||
0xdc31d7caUL, 0x85634210UL, 0x22971340UL, 0x11c68420UL, 0x244a857dUL,
|
||||
0x3dbbd2f8UL, 0x32f9ae11UL, 0xa129c76dUL, 0x2f9e1d4bUL, 0x30b2dcf3UL,
|
||||
0x52860decUL, 0xe3c177d0UL, 0x16b32b6cUL, 0xb970a999UL, 0x489411faUL,
|
||||
0x64e94722UL, 0x8cfca8c4UL, 0x3ff0a01aUL, 0x2c7d56d8UL, 0x903322efUL,
|
||||
0x4e4987c7UL, 0xd138d9c1UL, 0xa2ca8cfeUL, 0x0bd49836UL, 0x81f5a6cfUL,
|
||||
0xde7aa528UL, 0x8eb7da26UL, 0xbfad3fa4UL, 0x9d3a2ce4UL, 0x9278500dUL,
|
||||
0xcc5f6a9bUL, 0x467e5462UL, 0x138df6c2UL, 0xb8d890e8UL, 0xf7392e5eUL,
|
||||
0xafc382f5UL, 0x805d9fbeUL, 0x93d0697cUL, 0x2dd56fa9UL, 0x1225cfb3UL,
|
||||
0x99acc83bUL, 0x7d1810a7UL, 0x639ce86eUL, 0xbb3bdb7bUL, 0x7826cd09UL,
|
||||
0x18596ef4UL, 0xb79aec01UL, 0x9a4f83a8UL, 0x6e95e665UL, 0xe6ffaa7eUL,
|
||||
0xcfbc2108UL, 0xe815efe6UL, 0x9be7bad9UL, 0x366f4aceUL, 0x099fead4UL,
|
||||
0x7cb029d6UL, 0xb2a431afUL, 0x233f2a31UL, 0x94a5c630UL, 0x66a235c0UL,
|
||||
0xbc4e7437UL, 0xca82fca6UL, 0xd090e0b0UL, 0xd8a73315UL, 0x9804f14aUL,
|
||||
0xdaec41f7UL, 0x50cd7f0eUL, 0xf691172fUL, 0xd64d768dUL, 0xb0ef434dUL,
|
||||
0x4daacc54UL, 0x0496e4dfUL, 0xb5d19ee3UL, 0x886a4c1bUL, 0x1f2cc1b8UL,
|
||||
0x5165467fUL, 0xea5e9d04UL, 0x358c015dUL, 0x7487fa73UL, 0x410bfb2eUL,
|
||||
0x1d67b35aUL, 0xd2db9252UL, 0x5610e933UL, 0x47d66d13UL, 0x61d79a8cUL,
|
||||
0x0ca1377aUL, 0x14f8598eUL, 0x3c13eb89UL, 0x27a9ceeeUL, 0xc961b735UL,
|
||||
0xe51ce1edUL, 0xb1477a3cUL, 0xdfd29c59UL, 0x73f2553fUL, 0xce141879UL,
|
||||
0x37c773bfUL, 0xcdf753eaUL, 0xaafd5f5bUL, 0x6f3ddf14UL, 0xdb447886UL,
|
||||
0xf3afca81UL, 0xc468b93eUL, 0x3424382cUL, 0x40a3c25fUL, 0xc31d1672UL,
|
||||
0x25e2bc0cUL, 0x493c288bUL, 0x950dff41UL, 0x01a83971UL, 0xb30c08deUL,
|
||||
0xe4b4d89cUL, 0xc1566490UL, 0x84cb7b61UL, 0xb632d570UL, 0x5c6c4874UL,
|
||||
0x57b8d042UL},
|
||||
{0xf45150a7UL, 0x417e5365UL, 0x171ac3a4UL, 0x273a965eUL, 0xab3bcb6bUL,
|
||||
0x9d1ff145UL, 0xfaacab58UL, 0xe34b9303UL, 0x302055faUL, 0x76adf66dUL,
|
||||
0xcc889176UL, 0x02f5254cUL, 0xe54ffcd7UL, 0x2ac5d7cbUL, 0x35268044UL,
|
||||
0x62b58fa3UL, 0xb1de495aUL, 0xba25671bUL, 0xea45980eUL, 0xfe5de1c0UL,
|
||||
0x2fc30275UL, 0x4c8112f0UL, 0x468da397UL, 0xd36bc6f9UL, 0x8f03e75fUL,
|
||||
0x9215959cUL, 0x6dbfeb7aUL, 0x5295da59UL, 0xbed42d83UL, 0x7458d321UL,
|
||||
0xe0492969UL, 0xc98e44c8UL, 0xc2756a89UL, 0x8ef47879UL, 0x58996b3eUL,
|
||||
0xb927dd71UL, 0xe1beb64fUL, 0x88f017adUL, 0x20c966acUL, 0xce7db43aUL,
|
||||
0xdf63184aUL, 0x1ae58231UL, 0x51976033UL, 0x5362457fUL, 0x64b1e077UL,
|
||||
0x6bbb84aeUL, 0x81fe1ca0UL, 0x08f9942bUL, 0x48705868UL, 0x458f19fdUL,
|
||||
0xde94876cUL, 0x7b52b7f8UL, 0x73ab23d3UL, 0x4b72e202UL, 0x1fe3578fUL,
|
||||
0x55662aabUL, 0xebb20728UL, 0xb52f03c2UL, 0xc5869a7bUL, 0x37d3a508UL,
|
||||
0x2830f287UL, 0xbf23b2a5UL, 0x0302ba6aUL, 0x16ed5c82UL, 0xcf8a2b1cUL,
|
||||
0x79a792b4UL, 0x07f3f0f2UL, 0x694ea1e2UL, 0xda65cdf4UL, 0x0506d5beUL,
|
||||
0x34d11f62UL, 0xa6c48afeUL, 0x2e349d53UL, 0xf3a2a055UL, 0x8a0532e1UL,
|
||||
0xf6a475ebUL, 0x830b39ecUL, 0x6040aaefUL, 0x715e069fUL, 0x6ebd5110UL,
|
||||
0x213ef98aUL, 0xdd963d06UL, 0x3eddae05UL, 0xe64d46bdUL, 0x5491b58dUL,
|
||||
0xc471055dUL, 0x06046fd4UL, 0x5060ff15UL, 0x981924fbUL, 0xbdd697e9UL,
|
||||
0x4089cc43UL, 0xd967779eUL, 0xe8b0bd42UL, 0x8907888bUL, 0x19e7385bUL,
|
||||
0xc879dbeeUL, 0x7ca1470aUL, 0x427ce90fUL, 0x84f8c91eUL, 0x00000000UL,
|
||||
0x80098386UL, 0x2b3248edUL, 0x111eac70UL, 0x5a6c4e72UL, 0x0efdfbffUL,
|
||||
0x850f5638UL, 0xae3d1ed5UL, 0x2d362739UL, 0x0f0a64d9UL, 0x5c6821a6UL,
|
||||
0x5b9bd154UL, 0x36243a2eUL, 0x0a0cb167UL, 0x57930fe7UL, 0xeeb4d296UL,
|
||||
0x9b1b9e91UL, 0xc0804fc5UL, 0xdc61a220UL, 0x775a694bUL, 0x121c161aUL,
|
||||
0x93e20abaUL, 0xa0c0e52aUL, 0x223c43e0UL, 0x1b121d17UL, 0x090e0b0dUL,
|
||||
0x8bf2adc7UL, 0xb62db9a8UL, 0x1e14c8a9UL, 0xf1578519UL, 0x75af4c07UL,
|
||||
0x99eebbddUL, 0x7fa3fd60UL, 0x01f79f26UL, 0x725cbcf5UL, 0x6644c53bUL,
|
||||
0xfb5b347eUL, 0x438b7629UL, 0x23cbdcc6UL, 0xedb668fcUL, 0xe4b863f1UL,
|
||||
0x31d7cadcUL, 0x63421085UL, 0x97134022UL, 0xc6842011UL, 0x4a857d24UL,
|
||||
0xbbd2f83dUL, 0xf9ae1132UL, 0x29c76da1UL, 0x9e1d4b2fUL, 0xb2dcf330UL,
|
||||
0x860dec52UL, 0xc177d0e3UL, 0xb32b6c16UL, 0x70a999b9UL, 0x9411fa48UL,
|
||||
0xe9472264UL, 0xfca8c48cUL, 0xf0a01a3fUL, 0x7d56d82cUL, 0x3322ef90UL,
|
||||
0x4987c74eUL, 0x38d9c1d1UL, 0xca8cfea2UL, 0xd498360bUL, 0xf5a6cf81UL,
|
||||
0x7aa528deUL, 0xb7da268eUL, 0xad3fa4bfUL, 0x3a2ce49dUL, 0x78500d92UL,
|
||||
0x5f6a9bccUL, 0x7e546246UL, 0x8df6c213UL, 0xd890e8b8UL, 0x392e5ef7UL,
|
||||
0xc382f5afUL, 0x5d9fbe80UL, 0xd0697c93UL, 0xd56fa92dUL, 0x25cfb312UL,
|
||||
0xacc83b99UL, 0x1810a77dUL, 0x9ce86e63UL, 0x3bdb7bbbUL, 0x26cd0978UL,
|
||||
0x596ef418UL, 0x9aec01b7UL, 0x4f83a89aUL, 0x95e6656eUL, 0xffaa7ee6UL,
|
||||
0xbc2108cfUL, 0x15efe6e8UL, 0xe7bad99bUL, 0x6f4ace36UL, 0x9fead409UL,
|
||||
0xb029d67cUL, 0xa431afb2UL, 0x3f2a3123UL, 0xa5c63094UL, 0xa235c066UL,
|
||||
0x4e7437bcUL, 0x82fca6caUL, 0x90e0b0d0UL, 0xa73315d8UL, 0x04f14a98UL,
|
||||
0xec41f7daUL, 0xcd7f0e50UL, 0x91172ff6UL, 0x4d768dd6UL, 0xef434db0UL,
|
||||
0xaacc544dUL, 0x96e4df04UL, 0xd19ee3b5UL, 0x6a4c1b88UL, 0x2cc1b81fUL,
|
||||
0x65467f51UL, 0x5e9d04eaUL, 0x8c015d35UL, 0x87fa7374UL, 0x0bfb2e41UL,
|
||||
0x67b35a1dUL, 0xdb9252d2UL, 0x10e93356UL, 0xd66d1347UL, 0xd79a8c61UL,
|
||||
0xa1377a0cUL, 0xf8598e14UL, 0x13eb893cUL, 0xa9ceee27UL, 0x61b735c9UL,
|
||||
0x1ce1ede5UL, 0x477a3cb1UL, 0xd29c59dfUL, 0xf2553f73UL, 0x141879ceUL,
|
||||
0xc773bf37UL, 0xf753eacdUL, 0xfd5f5baaUL, 0x3ddf146fUL, 0x447886dbUL,
|
||||
0xafca81f3UL, 0x68b93ec4UL, 0x24382c34UL, 0xa3c25f40UL, 0x1d1672c3UL,
|
||||
0xe2bc0c25UL, 0x3c288b49UL, 0x0dff4195UL, 0xa8397101UL, 0x0c08deb3UL,
|
||||
0xb4d89ce4UL, 0x566490c1UL, 0xcb7b6184UL, 0x32d570b6UL, 0x6c48745cUL,
|
||||
0xb8d04257UL},
|
||||
{0x5150a7f4UL, 0x7e536541UL, 0x1ac3a417UL, 0x3a965e27UL, 0x3bcb6babUL,
|
||||
0x1ff1459dUL, 0xacab58faUL, 0x4b9303e3UL, 0x2055fa30UL, 0xadf66d76UL,
|
||||
0x889176ccUL, 0xf5254c02UL, 0x4ffcd7e5UL, 0xc5d7cb2aUL, 0x26804435UL,
|
||||
0xb58fa362UL, 0xde495ab1UL, 0x25671bbaUL, 0x45980eeaUL, 0x5de1c0feUL,
|
||||
0xc302752fUL, 0x8112f04cUL, 0x8da39746UL, 0x6bc6f9d3UL, 0x03e75f8fUL,
|
||||
0x15959c92UL, 0xbfeb7a6dUL, 0x95da5952UL, 0xd42d83beUL, 0x58d32174UL,
|
||||
0x492969e0UL, 0x8e44c8c9UL, 0x756a89c2UL, 0xf478798eUL, 0x996b3e58UL,
|
||||
0x27dd71b9UL, 0xbeb64fe1UL, 0xf017ad88UL, 0xc966ac20UL, 0x7db43aceUL,
|
||||
0x63184adfUL, 0xe582311aUL, 0x97603351UL, 0x62457f53UL, 0xb1e07764UL,
|
||||
0xbb84ae6bUL, 0xfe1ca081UL, 0xf9942b08UL, 0x70586848UL, 0x8f19fd45UL,
|
||||
0x94876cdeUL, 0x52b7f87bUL, 0xab23d373UL, 0x72e2024bUL, 0xe3578f1fUL,
|
||||
0x662aab55UL, 0xb20728ebUL, 0x2f03c2b5UL, 0x869a7bc5UL, 0xd3a50837UL,
|
||||
0x30f28728UL, 0x23b2a5bfUL, 0x02ba6a03UL, 0xed5c8216UL, 0x8a2b1ccfUL,
|
||||
0xa792b479UL, 0xf3f0f207UL, 0x4ea1e269UL, 0x65cdf4daUL, 0x06d5be05UL,
|
||||
0xd11f6234UL, 0xc48afea6UL, 0x349d532eUL, 0xa2a055f3UL, 0x0532e18aUL,
|
||||
0xa475ebf6UL, 0x0b39ec83UL, 0x40aaef60UL, 0x5e069f71UL, 0xbd51106eUL,
|
||||
0x3ef98a21UL, 0x963d06ddUL, 0xddae053eUL, 0x4d46bde6UL, 0x91b58d54UL,
|
||||
0x71055dc4UL, 0x046fd406UL, 0x60ff1550UL, 0x1924fb98UL, 0xd697e9bdUL,
|
||||
0x89cc4340UL, 0x67779ed9UL, 0xb0bd42e8UL, 0x07888b89UL, 0xe7385b19UL,
|
||||
0x79dbeec8UL, 0xa1470a7cUL, 0x7ce90f42UL, 0xf8c91e84UL, 0x00000000UL,
|
||||
0x09838680UL, 0x3248ed2bUL, 0x1eac7011UL, 0x6c4e725aUL, 0xfdfbff0eUL,
|
||||
0x0f563885UL, 0x3d1ed5aeUL, 0x3627392dUL, 0x0a64d90fUL, 0x6821a65cUL,
|
||||
0x9bd1545bUL, 0x243a2e36UL, 0x0cb1670aUL, 0x930fe757UL, 0xb4d296eeUL,
|
||||
0x1b9e919bUL, 0x804fc5c0UL, 0x61a220dcUL, 0x5a694b77UL, 0x1c161a12UL,
|
||||
0xe20aba93UL, 0xc0e52aa0UL, 0x3c43e022UL, 0x121d171bUL, 0x0e0b0d09UL,
|
||||
0xf2adc78bUL, 0x2db9a8b6UL, 0x14c8a91eUL, 0x578519f1UL, 0xaf4c0775UL,
|
||||
0xeebbdd99UL, 0xa3fd607fUL, 0xf79f2601UL, 0x5cbcf572UL, 0x44c53b66UL,
|
||||
0x5b347efbUL, 0x8b762943UL, 0xcbdcc623UL, 0xb668fcedUL, 0xb863f1e4UL,
|
||||
0xd7cadc31UL, 0x42108563UL, 0x13402297UL, 0x842011c6UL, 0x857d244aUL,
|
||||
0xd2f83dbbUL, 0xae1132f9UL, 0xc76da129UL, 0x1d4b2f9eUL, 0xdcf330b2UL,
|
||||
0x0dec5286UL, 0x77d0e3c1UL, 0x2b6c16b3UL, 0xa999b970UL, 0x11fa4894UL,
|
||||
0x472264e9UL, 0xa8c48cfcUL, 0xa01a3ff0UL, 0x56d82c7dUL, 0x22ef9033UL,
|
||||
0x87c74e49UL, 0xd9c1d138UL, 0x8cfea2caUL, 0x98360bd4UL, 0xa6cf81f5UL,
|
||||
0xa528de7aUL, 0xda268eb7UL, 0x3fa4bfadUL, 0x2ce49d3aUL, 0x500d9278UL,
|
||||
0x6a9bcc5fUL, 0x5462467eUL, 0xf6c2138dUL, 0x90e8b8d8UL, 0x2e5ef739UL,
|
||||
0x82f5afc3UL, 0x9fbe805dUL, 0x697c93d0UL, 0x6fa92dd5UL, 0xcfb31225UL,
|
||||
0xc83b99acUL, 0x10a77d18UL, 0xe86e639cUL, 0xdb7bbb3bUL, 0xcd097826UL,
|
||||
0x6ef41859UL, 0xec01b79aUL, 0x83a89a4fUL, 0xe6656e95UL, 0xaa7ee6ffUL,
|
||||
0x2108cfbcUL, 0xefe6e815UL, 0xbad99be7UL, 0x4ace366fUL, 0xead4099fUL,
|
||||
0x29d67cb0UL, 0x31afb2a4UL, 0x2a31233fUL, 0xc63094a5UL, 0x35c066a2UL,
|
||||
0x7437bc4eUL, 0xfca6ca82UL, 0xe0b0d090UL, 0x3315d8a7UL, 0xf14a9804UL,
|
||||
0x41f7daecUL, 0x7f0e50cdUL, 0x172ff691UL, 0x768dd64dUL, 0x434db0efUL,
|
||||
0xcc544daaUL, 0xe4df0496UL, 0x9ee3b5d1UL, 0x4c1b886aUL, 0xc1b81f2cUL,
|
||||
0x467f5165UL, 0x9d04ea5eUL, 0x015d358cUL, 0xfa737487UL, 0xfb2e410bUL,
|
||||
0xb35a1d67UL, 0x9252d2dbUL, 0xe9335610UL, 0x6d1347d6UL, 0x9a8c61d7UL,
|
||||
0x377a0ca1UL, 0x598e14f8UL, 0xeb893c13UL, 0xceee27a9UL, 0xb735c961UL,
|
||||
0xe1ede51cUL, 0x7a3cb147UL, 0x9c59dfd2UL, 0x553f73f2UL, 0x1879ce14UL,
|
||||
0x73bf37c7UL, 0x53eacdf7UL, 0x5f5baafdUL, 0xdf146f3dUL, 0x7886db44UL,
|
||||
0xca81f3afUL, 0xb93ec468UL, 0x382c3424UL, 0xc25f40a3UL, 0x1672c31dUL,
|
||||
0xbc0c25e2UL, 0x288b493cUL, 0xff41950dUL, 0x397101a8UL, 0x08deb30cUL,
|
||||
0xd89ce4b4UL, 0x6490c156UL, 0x7b6184cbUL, 0xd570b632UL, 0x48745c6cUL,
|
||||
0xd04257b8UL}
|
||||
};
|
||||
|
||||
static const unsigned long fl_tab[4][256] = {
|
||||
{0x00000063UL, 0x0000007cUL, 0x00000077UL, 0x0000007bUL, 0x000000f2UL,
|
||||
0x0000006bUL, 0x0000006fUL, 0x000000c5UL, 0x00000030UL, 0x00000001UL,
|
||||
0x00000067UL, 0x0000002bUL, 0x000000feUL, 0x000000d7UL, 0x000000abUL,
|
||||
0x00000076UL, 0x000000caUL, 0x00000082UL, 0x000000c9UL, 0x0000007dUL,
|
||||
0x000000faUL, 0x00000059UL, 0x00000047UL, 0x000000f0UL, 0x000000adUL,
|
||||
0x000000d4UL, 0x000000a2UL, 0x000000afUL, 0x0000009cUL, 0x000000a4UL,
|
||||
0x00000072UL, 0x000000c0UL, 0x000000b7UL, 0x000000fdUL, 0x00000093UL,
|
||||
0x00000026UL, 0x00000036UL, 0x0000003fUL, 0x000000f7UL, 0x000000ccUL,
|
||||
0x00000034UL, 0x000000a5UL, 0x000000e5UL, 0x000000f1UL, 0x00000071UL,
|
||||
0x000000d8UL, 0x00000031UL, 0x00000015UL, 0x00000004UL, 0x000000c7UL,
|
||||
0x00000023UL, 0x000000c3UL, 0x00000018UL, 0x00000096UL, 0x00000005UL,
|
||||
0x0000009aUL, 0x00000007UL, 0x00000012UL, 0x00000080UL, 0x000000e2UL,
|
||||
0x000000ebUL, 0x00000027UL, 0x000000b2UL, 0x00000075UL, 0x00000009UL,
|
||||
0x00000083UL, 0x0000002cUL, 0x0000001aUL, 0x0000001bUL, 0x0000006eUL,
|
||||
0x0000005aUL, 0x000000a0UL, 0x00000052UL, 0x0000003bUL, 0x000000d6UL,
|
||||
0x000000b3UL, 0x00000029UL, 0x000000e3UL, 0x0000002fUL, 0x00000084UL,
|
||||
0x00000053UL, 0x000000d1UL, 0x00000000UL, 0x000000edUL, 0x00000020UL,
|
||||
0x000000fcUL, 0x000000b1UL, 0x0000005bUL, 0x0000006aUL, 0x000000cbUL,
|
||||
0x000000beUL, 0x00000039UL, 0x0000004aUL, 0x0000004cUL, 0x00000058UL,
|
||||
0x000000cfUL, 0x000000d0UL, 0x000000efUL, 0x000000aaUL, 0x000000fbUL,
|
||||
0x00000043UL, 0x0000004dUL, 0x00000033UL, 0x00000085UL, 0x00000045UL,
|
||||
0x000000f9UL, 0x00000002UL, 0x0000007fUL, 0x00000050UL, 0x0000003cUL,
|
||||
0x0000009fUL, 0x000000a8UL, 0x00000051UL, 0x000000a3UL, 0x00000040UL,
|
||||
0x0000008fUL, 0x00000092UL, 0x0000009dUL, 0x00000038UL, 0x000000f5UL,
|
||||
0x000000bcUL, 0x000000b6UL, 0x000000daUL, 0x00000021UL, 0x00000010UL,
|
||||
0x000000ffUL, 0x000000f3UL, 0x000000d2UL, 0x000000cdUL, 0x0000000cUL,
|
||||
0x00000013UL, 0x000000ecUL, 0x0000005fUL, 0x00000097UL, 0x00000044UL,
|
||||
0x00000017UL, 0x000000c4UL, 0x000000a7UL, 0x0000007eUL, 0x0000003dUL,
|
||||
0x00000064UL, 0x0000005dUL, 0x00000019UL, 0x00000073UL, 0x00000060UL,
|
||||
0x00000081UL, 0x0000004fUL, 0x000000dcUL, 0x00000022UL, 0x0000002aUL,
|
||||
0x00000090UL, 0x00000088UL, 0x00000046UL, 0x000000eeUL, 0x000000b8UL,
|
||||
0x00000014UL, 0x000000deUL, 0x0000005eUL, 0x0000000bUL, 0x000000dbUL,
|
||||
0x000000e0UL, 0x00000032UL, 0x0000003aUL, 0x0000000aUL, 0x00000049UL,
|
||||
0x00000006UL, 0x00000024UL, 0x0000005cUL, 0x000000c2UL, 0x000000d3UL,
|
||||
0x000000acUL, 0x00000062UL, 0x00000091UL, 0x00000095UL, 0x000000e4UL,
|
||||
0x00000079UL, 0x000000e7UL, 0x000000c8UL, 0x00000037UL, 0x0000006dUL,
|
||||
0x0000008dUL, 0x000000d5UL, 0x0000004eUL, 0x000000a9UL, 0x0000006cUL,
|
||||
0x00000056UL, 0x000000f4UL, 0x000000eaUL, 0x00000065UL, 0x0000007aUL,
|
||||
0x000000aeUL, 0x00000008UL, 0x000000baUL, 0x00000078UL, 0x00000025UL,
|
||||
0x0000002eUL, 0x0000001cUL, 0x000000a6UL, 0x000000b4UL, 0x000000c6UL,
|
||||
0x000000e8UL, 0x000000ddUL, 0x00000074UL, 0x0000001fUL, 0x0000004bUL,
|
||||
0x000000bdUL, 0x0000008bUL, 0x0000008aUL, 0x00000070UL, 0x0000003eUL,
|
||||
0x000000b5UL, 0x00000066UL, 0x00000048UL, 0x00000003UL, 0x000000f6UL,
|
||||
0x0000000eUL, 0x00000061UL, 0x00000035UL, 0x00000057UL, 0x000000b9UL,
|
||||
0x00000086UL, 0x000000c1UL, 0x0000001dUL, 0x0000009eUL, 0x000000e1UL,
|
||||
0x000000f8UL, 0x00000098UL, 0x00000011UL, 0x00000069UL, 0x000000d9UL,
|
||||
0x0000008eUL, 0x00000094UL, 0x0000009bUL, 0x0000001eUL, 0x00000087UL,
|
||||
0x000000e9UL, 0x000000ceUL, 0x00000055UL, 0x00000028UL, 0x000000dfUL,
|
||||
0x0000008cUL, 0x000000a1UL, 0x00000089UL, 0x0000000dUL, 0x000000bfUL,
|
||||
0x000000e6UL, 0x00000042UL, 0x00000068UL, 0x00000041UL, 0x00000099UL,
|
||||
0x0000002dUL, 0x0000000fUL, 0x000000b0UL, 0x00000054UL, 0x000000bbUL,
|
||||
0x00000016UL},
|
||||
{0x00006300UL, 0x00007c00UL, 0x00007700UL, 0x00007b00UL, 0x0000f200UL,
|
||||
0x00006b00UL, 0x00006f00UL, 0x0000c500UL, 0x00003000UL, 0x00000100UL,
|
||||
0x00006700UL, 0x00002b00UL, 0x0000fe00UL, 0x0000d700UL, 0x0000ab00UL,
|
||||
0x00007600UL, 0x0000ca00UL, 0x00008200UL, 0x0000c900UL, 0x00007d00UL,
|
||||
0x0000fa00UL, 0x00005900UL, 0x00004700UL, 0x0000f000UL, 0x0000ad00UL,
|
||||
0x0000d400UL, 0x0000a200UL, 0x0000af00UL, 0x00009c00UL, 0x0000a400UL,
|
||||
0x00007200UL, 0x0000c000UL, 0x0000b700UL, 0x0000fd00UL, 0x00009300UL,
|
||||
0x00002600UL, 0x00003600UL, 0x00003f00UL, 0x0000f700UL, 0x0000cc00UL,
|
||||
0x00003400UL, 0x0000a500UL, 0x0000e500UL, 0x0000f100UL, 0x00007100UL,
|
||||
0x0000d800UL, 0x00003100UL, 0x00001500UL, 0x00000400UL, 0x0000c700UL,
|
||||
0x00002300UL, 0x0000c300UL, 0x00001800UL, 0x00009600UL, 0x00000500UL,
|
||||
0x00009a00UL, 0x00000700UL, 0x00001200UL, 0x00008000UL, 0x0000e200UL,
|
||||
0x0000eb00UL, 0x00002700UL, 0x0000b200UL, 0x00007500UL, 0x00000900UL,
|
||||
0x00008300UL, 0x00002c00UL, 0x00001a00UL, 0x00001b00UL, 0x00006e00UL,
|
||||
0x00005a00UL, 0x0000a000UL, 0x00005200UL, 0x00003b00UL, 0x0000d600UL,
|
||||
0x0000b300UL, 0x00002900UL, 0x0000e300UL, 0x00002f00UL, 0x00008400UL,
|
||||
0x00005300UL, 0x0000d100UL, 0x00000000UL, 0x0000ed00UL, 0x00002000UL,
|
||||
0x0000fc00UL, 0x0000b100UL, 0x00005b00UL, 0x00006a00UL, 0x0000cb00UL,
|
||||
0x0000be00UL, 0x00003900UL, 0x00004a00UL, 0x00004c00UL, 0x00005800UL,
|
||||
0x0000cf00UL, 0x0000d000UL, 0x0000ef00UL, 0x0000aa00UL, 0x0000fb00UL,
|
||||
0x00004300UL, 0x00004d00UL, 0x00003300UL, 0x00008500UL, 0x00004500UL,
|
||||
0x0000f900UL, 0x00000200UL, 0x00007f00UL, 0x00005000UL, 0x00003c00UL,
|
||||
0x00009f00UL, 0x0000a800UL, 0x00005100UL, 0x0000a300UL, 0x00004000UL,
|
||||
0x00008f00UL, 0x00009200UL, 0x00009d00UL, 0x00003800UL, 0x0000f500UL,
|
||||
0x0000bc00UL, 0x0000b600UL, 0x0000da00UL, 0x00002100UL, 0x00001000UL,
|
||||
0x0000ff00UL, 0x0000f300UL, 0x0000d200UL, 0x0000cd00UL, 0x00000c00UL,
|
||||
0x00001300UL, 0x0000ec00UL, 0x00005f00UL, 0x00009700UL, 0x00004400UL,
|
||||
0x00001700UL, 0x0000c400UL, 0x0000a700UL, 0x00007e00UL, 0x00003d00UL,
|
||||
0x00006400UL, 0x00005d00UL, 0x00001900UL, 0x00007300UL, 0x00006000UL,
|
||||
0x00008100UL, 0x00004f00UL, 0x0000dc00UL, 0x00002200UL, 0x00002a00UL,
|
||||
0x00009000UL, 0x00008800UL, 0x00004600UL, 0x0000ee00UL, 0x0000b800UL,
|
||||
0x00001400UL, 0x0000de00UL, 0x00005e00UL, 0x00000b00UL, 0x0000db00UL,
|
||||
0x0000e000UL, 0x00003200UL, 0x00003a00UL, 0x00000a00UL, 0x00004900UL,
|
||||
0x00000600UL, 0x00002400UL, 0x00005c00UL, 0x0000c200UL, 0x0000d300UL,
|
||||
0x0000ac00UL, 0x00006200UL, 0x00009100UL, 0x00009500UL, 0x0000e400UL,
|
||||
0x00007900UL, 0x0000e700UL, 0x0000c800UL, 0x00003700UL, 0x00006d00UL,
|
||||
0x00008d00UL, 0x0000d500UL, 0x00004e00UL, 0x0000a900UL, 0x00006c00UL,
|
||||
0x00005600UL, 0x0000f400UL, 0x0000ea00UL, 0x00006500UL, 0x00007a00UL,
|
||||
0x0000ae00UL, 0x00000800UL, 0x0000ba00UL, 0x00007800UL, 0x00002500UL,
|
||||
0x00002e00UL, 0x00001c00UL, 0x0000a600UL, 0x0000b400UL, 0x0000c600UL,
|
||||
0x0000e800UL, 0x0000dd00UL, 0x00007400UL, 0x00001f00UL, 0x00004b00UL,
|
||||
0x0000bd00UL, 0x00008b00UL, 0x00008a00UL, 0x00007000UL, 0x00003e00UL,
|
||||
0x0000b500UL, 0x00006600UL, 0x00004800UL, 0x00000300UL, 0x0000f600UL,
|
||||
0x00000e00UL, 0x00006100UL, 0x00003500UL, 0x00005700UL, 0x0000b900UL,
|
||||
0x00008600UL, 0x0000c100UL, 0x00001d00UL, 0x00009e00UL, 0x0000e100UL,
|
||||
0x0000f800UL, 0x00009800UL, 0x00001100UL, 0x00006900UL, 0x0000d900UL,
|
||||
0x00008e00UL, 0x00009400UL, 0x00009b00UL, 0x00001e00UL, 0x00008700UL,
|
||||
0x0000e900UL, 0x0000ce00UL, 0x00005500UL, 0x00002800UL, 0x0000df00UL,
|
||||
0x00008c00UL, 0x0000a100UL, 0x00008900UL, 0x00000d00UL, 0x0000bf00UL,
|
||||
0x0000e600UL, 0x00004200UL, 0x00006800UL, 0x00004100UL, 0x00009900UL,
|
||||
0x00002d00UL, 0x00000f00UL, 0x0000b000UL, 0x00005400UL, 0x0000bb00UL,
|
||||
0x00001600UL},
|
||||
{0x00630000UL, 0x007c0000UL, 0x00770000UL, 0x007b0000UL, 0x00f20000UL,
|
||||
0x006b0000UL, 0x006f0000UL, 0x00c50000UL, 0x00300000UL, 0x00010000UL,
|
||||
0x00670000UL, 0x002b0000UL, 0x00fe0000UL, 0x00d70000UL, 0x00ab0000UL,
|
||||
0x00760000UL, 0x00ca0000UL, 0x00820000UL, 0x00c90000UL, 0x007d0000UL,
|
||||
0x00fa0000UL, 0x00590000UL, 0x00470000UL, 0x00f00000UL, 0x00ad0000UL,
|
||||
0x00d40000UL, 0x00a20000UL, 0x00af0000UL, 0x009c0000UL, 0x00a40000UL,
|
||||
0x00720000UL, 0x00c00000UL, 0x00b70000UL, 0x00fd0000UL, 0x00930000UL,
|
||||
0x00260000UL, 0x00360000UL, 0x003f0000UL, 0x00f70000UL, 0x00cc0000UL,
|
||||
0x00340000UL, 0x00a50000UL, 0x00e50000UL, 0x00f10000UL, 0x00710000UL,
|
||||
0x00d80000UL, 0x00310000UL, 0x00150000UL, 0x00040000UL, 0x00c70000UL,
|
||||
0x00230000UL, 0x00c30000UL, 0x00180000UL, 0x00960000UL, 0x00050000UL,
|
||||
0x009a0000UL, 0x00070000UL, 0x00120000UL, 0x00800000UL, 0x00e20000UL,
|
||||
0x00eb0000UL, 0x00270000UL, 0x00b20000UL, 0x00750000UL, 0x00090000UL,
|
||||
0x00830000UL, 0x002c0000UL, 0x001a0000UL, 0x001b0000UL, 0x006e0000UL,
|
||||
0x005a0000UL, 0x00a00000UL, 0x00520000UL, 0x003b0000UL, 0x00d60000UL,
|
||||
0x00b30000UL, 0x00290000UL, 0x00e30000UL, 0x002f0000UL, 0x00840000UL,
|
||||
0x00530000UL, 0x00d10000UL, 0x00000000UL, 0x00ed0000UL, 0x00200000UL,
|
||||
0x00fc0000UL, 0x00b10000UL, 0x005b0000UL, 0x006a0000UL, 0x00cb0000UL,
|
||||
0x00be0000UL, 0x00390000UL, 0x004a0000UL, 0x004c0000UL, 0x00580000UL,
|
||||
0x00cf0000UL, 0x00d00000UL, 0x00ef0000UL, 0x00aa0000UL, 0x00fb0000UL,
|
||||
0x00430000UL, 0x004d0000UL, 0x00330000UL, 0x00850000UL, 0x00450000UL,
|
||||
0x00f90000UL, 0x00020000UL, 0x007f0000UL, 0x00500000UL, 0x003c0000UL,
|
||||
0x009f0000UL, 0x00a80000UL, 0x00510000UL, 0x00a30000UL, 0x00400000UL,
|
||||
0x008f0000UL, 0x00920000UL, 0x009d0000UL, 0x00380000UL, 0x00f50000UL,
|
||||
0x00bc0000UL, 0x00b60000UL, 0x00da0000UL, 0x00210000UL, 0x00100000UL,
|
||||
0x00ff0000UL, 0x00f30000UL, 0x00d20000UL, 0x00cd0000UL, 0x000c0000UL,
|
||||
0x00130000UL, 0x00ec0000UL, 0x005f0000UL, 0x00970000UL, 0x00440000UL,
|
||||
0x00170000UL, 0x00c40000UL, 0x00a70000UL, 0x007e0000UL, 0x003d0000UL,
|
||||
0x00640000UL, 0x005d0000UL, 0x00190000UL, 0x00730000UL, 0x00600000UL,
|
||||
0x00810000UL, 0x004f0000UL, 0x00dc0000UL, 0x00220000UL, 0x002a0000UL,
|
||||
0x00900000UL, 0x00880000UL, 0x00460000UL, 0x00ee0000UL, 0x00b80000UL,
|
||||
0x00140000UL, 0x00de0000UL, 0x005e0000UL, 0x000b0000UL, 0x00db0000UL,
|
||||
0x00e00000UL, 0x00320000UL, 0x003a0000UL, 0x000a0000UL, 0x00490000UL,
|
||||
0x00060000UL, 0x00240000UL, 0x005c0000UL, 0x00c20000UL, 0x00d30000UL,
|
||||
0x00ac0000UL, 0x00620000UL, 0x00910000UL, 0x00950000UL, 0x00e40000UL,
|
||||
0x00790000UL, 0x00e70000UL, 0x00c80000UL, 0x00370000UL, 0x006d0000UL,
|
||||
0x008d0000UL, 0x00d50000UL, 0x004e0000UL, 0x00a90000UL, 0x006c0000UL,
|
||||
0x00560000UL, 0x00f40000UL, 0x00ea0000UL, 0x00650000UL, 0x007a0000UL,
|
||||
0x00ae0000UL, 0x00080000UL, 0x00ba0000UL, 0x00780000UL, 0x00250000UL,
|
||||
0x002e0000UL, 0x001c0000UL, 0x00a60000UL, 0x00b40000UL, 0x00c60000UL,
|
||||
0x00e80000UL, 0x00dd0000UL, 0x00740000UL, 0x001f0000UL, 0x004b0000UL,
|
||||
0x00bd0000UL, 0x008b0000UL, 0x008a0000UL, 0x00700000UL, 0x003e0000UL,
|
||||
0x00b50000UL, 0x00660000UL, 0x00480000UL, 0x00030000UL, 0x00f60000UL,
|
||||
0x000e0000UL, 0x00610000UL, 0x00350000UL, 0x00570000UL, 0x00b90000UL,
|
||||
0x00860000UL, 0x00c10000UL, 0x001d0000UL, 0x009e0000UL, 0x00e10000UL,
|
||||
0x00f80000UL, 0x00980000UL, 0x00110000UL, 0x00690000UL, 0x00d90000UL,
|
||||
0x008e0000UL, 0x00940000UL, 0x009b0000UL, 0x001e0000UL, 0x00870000UL,
|
||||
0x00e90000UL, 0x00ce0000UL, 0x00550000UL, 0x00280000UL, 0x00df0000UL,
|
||||
0x008c0000UL, 0x00a10000UL, 0x00890000UL, 0x000d0000UL, 0x00bf0000UL,
|
||||
0x00e60000UL, 0x00420000UL, 0x00680000UL, 0x00410000UL, 0x00990000UL,
|
||||
0x002d0000UL, 0x000f0000UL, 0x00b00000UL, 0x00540000UL, 0x00bb0000UL,
|
||||
0x00160000UL},
|
||||
{0x63000000UL, 0x7c000000UL, 0x77000000UL, 0x7b000000UL, 0xf2000000UL,
|
||||
0x6b000000UL, 0x6f000000UL, 0xc5000000UL, 0x30000000UL, 0x01000000UL,
|
||||
0x67000000UL, 0x2b000000UL, 0xfe000000UL, 0xd7000000UL, 0xab000000UL,
|
||||
0x76000000UL, 0xca000000UL, 0x82000000UL, 0xc9000000UL, 0x7d000000UL,
|
||||
0xfa000000UL, 0x59000000UL, 0x47000000UL, 0xf0000000UL, 0xad000000UL,
|
||||
0xd4000000UL, 0xa2000000UL, 0xaf000000UL, 0x9c000000UL, 0xa4000000UL,
|
||||
0x72000000UL, 0xc0000000UL, 0xb7000000UL, 0xfd000000UL, 0x93000000UL,
|
||||
0x26000000UL, 0x36000000UL, 0x3f000000UL, 0xf7000000UL, 0xcc000000UL,
|
||||
0x34000000UL, 0xa5000000UL, 0xe5000000UL, 0xf1000000UL, 0x71000000UL,
|
||||
0xd8000000UL, 0x31000000UL, 0x15000000UL, 0x04000000UL, 0xc7000000UL,
|
||||
0x23000000UL, 0xc3000000UL, 0x18000000UL, 0x96000000UL, 0x05000000UL,
|
||||
0x9a000000UL, 0x07000000UL, 0x12000000UL, 0x80000000UL, 0xe2000000UL,
|
||||
0xeb000000UL, 0x27000000UL, 0xb2000000UL, 0x75000000UL, 0x09000000UL,
|
||||
0x83000000UL, 0x2c000000UL, 0x1a000000UL, 0x1b000000UL, 0x6e000000UL,
|
||||
0x5a000000UL, 0xa0000000UL, 0x52000000UL, 0x3b000000UL, 0xd6000000UL,
|
||||
0xb3000000UL, 0x29000000UL, 0xe3000000UL, 0x2f000000UL, 0x84000000UL,
|
||||
0x53000000UL, 0xd1000000UL, 0x00000000UL, 0xed000000UL, 0x20000000UL,
|
||||
0xfc000000UL, 0xb1000000UL, 0x5b000000UL, 0x6a000000UL, 0xcb000000UL,
|
||||
0xbe000000UL, 0x39000000UL, 0x4a000000UL, 0x4c000000UL, 0x58000000UL,
|
||||
0xcf000000UL, 0xd0000000UL, 0xef000000UL, 0xaa000000UL, 0xfb000000UL,
|
||||
0x43000000UL, 0x4d000000UL, 0x33000000UL, 0x85000000UL, 0x45000000UL,
|
||||
0xf9000000UL, 0x02000000UL, 0x7f000000UL, 0x50000000UL, 0x3c000000UL,
|
||||
0x9f000000UL, 0xa8000000UL, 0x51000000UL, 0xa3000000UL, 0x40000000UL,
|
||||
0x8f000000UL, 0x92000000UL, 0x9d000000UL, 0x38000000UL, 0xf5000000UL,
|
||||
0xbc000000UL, 0xb6000000UL, 0xda000000UL, 0x21000000UL, 0x10000000UL,
|
||||
0xff000000UL, 0xf3000000UL, 0xd2000000UL, 0xcd000000UL, 0x0c000000UL,
|
||||
0x13000000UL, 0xec000000UL, 0x5f000000UL, 0x97000000UL, 0x44000000UL,
|
||||
0x17000000UL, 0xc4000000UL, 0xa7000000UL, 0x7e000000UL, 0x3d000000UL,
|
||||
0x64000000UL, 0x5d000000UL, 0x19000000UL, 0x73000000UL, 0x60000000UL,
|
||||
0x81000000UL, 0x4f000000UL, 0xdc000000UL, 0x22000000UL, 0x2a000000UL,
|
||||
0x90000000UL, 0x88000000UL, 0x46000000UL, 0xee000000UL, 0xb8000000UL,
|
||||
0x14000000UL, 0xde000000UL, 0x5e000000UL, 0x0b000000UL, 0xdb000000UL,
|
||||
0xe0000000UL, 0x32000000UL, 0x3a000000UL, 0x0a000000UL, 0x49000000UL,
|
||||
0x06000000UL, 0x24000000UL, 0x5c000000UL, 0xc2000000UL, 0xd3000000UL,
|
||||
0xac000000UL, 0x62000000UL, 0x91000000UL, 0x95000000UL, 0xe4000000UL,
|
||||
0x79000000UL, 0xe7000000UL, 0xc8000000UL, 0x37000000UL, 0x6d000000UL,
|
||||
0x8d000000UL, 0xd5000000UL, 0x4e000000UL, 0xa9000000UL, 0x6c000000UL,
|
||||
0x56000000UL, 0xf4000000UL, 0xea000000UL, 0x65000000UL, 0x7a000000UL,
|
||||
0xae000000UL, 0x08000000UL, 0xba000000UL, 0x78000000UL, 0x25000000UL,
|
||||
0x2e000000UL, 0x1c000000UL, 0xa6000000UL, 0xb4000000UL, 0xc6000000UL,
|
||||
0xe8000000UL, 0xdd000000UL, 0x74000000UL, 0x1f000000UL, 0x4b000000UL,
|
||||
0xbd000000UL, 0x8b000000UL, 0x8a000000UL, 0x70000000UL, 0x3e000000UL,
|
||||
0xb5000000UL, 0x66000000UL, 0x48000000UL, 0x03000000UL, 0xf6000000UL,
|
||||
0x0e000000UL, 0x61000000UL, 0x35000000UL, 0x57000000UL, 0xb9000000UL,
|
||||
0x86000000UL, 0xc1000000UL, 0x1d000000UL, 0x9e000000UL, 0xe1000000UL,
|
||||
0xf8000000UL, 0x98000000UL, 0x11000000UL, 0x69000000UL, 0xd9000000UL,
|
||||
0x8e000000UL, 0x94000000UL, 0x9b000000UL, 0x1e000000UL, 0x87000000UL,
|
||||
0xe9000000UL, 0xce000000UL, 0x55000000UL, 0x28000000UL, 0xdf000000UL,
|
||||
0x8c000000UL, 0xa1000000UL, 0x89000000UL, 0x0d000000UL, 0xbf000000UL,
|
||||
0xe6000000UL, 0x42000000UL, 0x68000000UL, 0x41000000UL, 0x99000000UL,
|
||||
0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL,
|
||||
0x16000000UL}
|
||||
};
|
||||
|
||||
static const unsigned long il_tab[4][256] = {
|
||||
{0x00000052UL, 0x00000009UL, 0x0000006aUL, 0x000000d5UL, 0x00000030UL,
|
||||
0x00000036UL, 0x000000a5UL, 0x00000038UL, 0x000000bfUL, 0x00000040UL,
|
||||
0x000000a3UL, 0x0000009eUL, 0x00000081UL, 0x000000f3UL, 0x000000d7UL,
|
||||
0x000000fbUL, 0x0000007cUL, 0x000000e3UL, 0x00000039UL, 0x00000082UL,
|
||||
0x0000009bUL, 0x0000002fUL, 0x000000ffUL, 0x00000087UL, 0x00000034UL,
|
||||
0x0000008eUL, 0x00000043UL, 0x00000044UL, 0x000000c4UL, 0x000000deUL,
|
||||
0x000000e9UL, 0x000000cbUL, 0x00000054UL, 0x0000007bUL, 0x00000094UL,
|
||||
0x00000032UL, 0x000000a6UL, 0x000000c2UL, 0x00000023UL, 0x0000003dUL,
|
||||
0x000000eeUL, 0x0000004cUL, 0x00000095UL, 0x0000000bUL, 0x00000042UL,
|
||||
0x000000faUL, 0x000000c3UL, 0x0000004eUL, 0x00000008UL, 0x0000002eUL,
|
||||
0x000000a1UL, 0x00000066UL, 0x00000028UL, 0x000000d9UL, 0x00000024UL,
|
||||
0x000000b2UL, 0x00000076UL, 0x0000005bUL, 0x000000a2UL, 0x00000049UL,
|
||||
0x0000006dUL, 0x0000008bUL, 0x000000d1UL, 0x00000025UL, 0x00000072UL,
|
||||
0x000000f8UL, 0x000000f6UL, 0x00000064UL, 0x00000086UL, 0x00000068UL,
|
||||
0x00000098UL, 0x00000016UL, 0x000000d4UL, 0x000000a4UL, 0x0000005cUL,
|
||||
0x000000ccUL, 0x0000005dUL, 0x00000065UL, 0x000000b6UL, 0x00000092UL,
|
||||
0x0000006cUL, 0x00000070UL, 0x00000048UL, 0x00000050UL, 0x000000fdUL,
|
||||
0x000000edUL, 0x000000b9UL, 0x000000daUL, 0x0000005eUL, 0x00000015UL,
|
||||
0x00000046UL, 0x00000057UL, 0x000000a7UL, 0x0000008dUL, 0x0000009dUL,
|
||||
0x00000084UL, 0x00000090UL, 0x000000d8UL, 0x000000abUL, 0x00000000UL,
|
||||
0x0000008cUL, 0x000000bcUL, 0x000000d3UL, 0x0000000aUL, 0x000000f7UL,
|
||||
0x000000e4UL, 0x00000058UL, 0x00000005UL, 0x000000b8UL, 0x000000b3UL,
|
||||
0x00000045UL, 0x00000006UL, 0x000000d0UL, 0x0000002cUL, 0x0000001eUL,
|
||||
0x0000008fUL, 0x000000caUL, 0x0000003fUL, 0x0000000fUL, 0x00000002UL,
|
||||
0x000000c1UL, 0x000000afUL, 0x000000bdUL, 0x00000003UL, 0x00000001UL,
|
||||
0x00000013UL, 0x0000008aUL, 0x0000006bUL, 0x0000003aUL, 0x00000091UL,
|
||||
0x00000011UL, 0x00000041UL, 0x0000004fUL, 0x00000067UL, 0x000000dcUL,
|
||||
0x000000eaUL, 0x00000097UL, 0x000000f2UL, 0x000000cfUL, 0x000000ceUL,
|
||||
0x000000f0UL, 0x000000b4UL, 0x000000e6UL, 0x00000073UL, 0x00000096UL,
|
||||
0x000000acUL, 0x00000074UL, 0x00000022UL, 0x000000e7UL, 0x000000adUL,
|
||||
0x00000035UL, 0x00000085UL, 0x000000e2UL, 0x000000f9UL, 0x00000037UL,
|
||||
0x000000e8UL, 0x0000001cUL, 0x00000075UL, 0x000000dfUL, 0x0000006eUL,
|
||||
0x00000047UL, 0x000000f1UL, 0x0000001aUL, 0x00000071UL, 0x0000001dUL,
|
||||
0x00000029UL, 0x000000c5UL, 0x00000089UL, 0x0000006fUL, 0x000000b7UL,
|
||||
0x00000062UL, 0x0000000eUL, 0x000000aaUL, 0x00000018UL, 0x000000beUL,
|
||||
0x0000001bUL, 0x000000fcUL, 0x00000056UL, 0x0000003eUL, 0x0000004bUL,
|
||||
0x000000c6UL, 0x000000d2UL, 0x00000079UL, 0x00000020UL, 0x0000009aUL,
|
||||
0x000000dbUL, 0x000000c0UL, 0x000000feUL, 0x00000078UL, 0x000000cdUL,
|
||||
0x0000005aUL, 0x000000f4UL, 0x0000001fUL, 0x000000ddUL, 0x000000a8UL,
|
||||
0x00000033UL, 0x00000088UL, 0x00000007UL, 0x000000c7UL, 0x00000031UL,
|
||||
0x000000b1UL, 0x00000012UL, 0x00000010UL, 0x00000059UL, 0x00000027UL,
|
||||
0x00000080UL, 0x000000ecUL, 0x0000005fUL, 0x00000060UL, 0x00000051UL,
|
||||
0x0000007fUL, 0x000000a9UL, 0x00000019UL, 0x000000b5UL, 0x0000004aUL,
|
||||
0x0000000dUL, 0x0000002dUL, 0x000000e5UL, 0x0000007aUL, 0x0000009fUL,
|
||||
0x00000093UL, 0x000000c9UL, 0x0000009cUL, 0x000000efUL, 0x000000a0UL,
|
||||
0x000000e0UL, 0x0000003bUL, 0x0000004dUL, 0x000000aeUL, 0x0000002aUL,
|
||||
0x000000f5UL, 0x000000b0UL, 0x000000c8UL, 0x000000ebUL, 0x000000bbUL,
|
||||
0x0000003cUL, 0x00000083UL, 0x00000053UL, 0x00000099UL, 0x00000061UL,
|
||||
0x00000017UL, 0x0000002bUL, 0x00000004UL, 0x0000007eUL, 0x000000baUL,
|
||||
0x00000077UL, 0x000000d6UL, 0x00000026UL, 0x000000e1UL, 0x00000069UL,
|
||||
0x00000014UL, 0x00000063UL, 0x00000055UL, 0x00000021UL, 0x0000000cUL,
|
||||
0x0000007dUL},
|
||||
{0x00005200UL, 0x00000900UL, 0x00006a00UL, 0x0000d500UL, 0x00003000UL,
|
||||
0x00003600UL, 0x0000a500UL, 0x00003800UL, 0x0000bf00UL, 0x00004000UL,
|
||||
0x0000a300UL, 0x00009e00UL, 0x00008100UL, 0x0000f300UL, 0x0000d700UL,
|
||||
0x0000fb00UL, 0x00007c00UL, 0x0000e300UL, 0x00003900UL, 0x00008200UL,
|
||||
0x00009b00UL, 0x00002f00UL, 0x0000ff00UL, 0x00008700UL, 0x00003400UL,
|
||||
0x00008e00UL, 0x00004300UL, 0x00004400UL, 0x0000c400UL, 0x0000de00UL,
|
||||
0x0000e900UL, 0x0000cb00UL, 0x00005400UL, 0x00007b00UL, 0x00009400UL,
|
||||
0x00003200UL, 0x0000a600UL, 0x0000c200UL, 0x00002300UL, 0x00003d00UL,
|
||||
0x0000ee00UL, 0x00004c00UL, 0x00009500UL, 0x00000b00UL, 0x00004200UL,
|
||||
0x0000fa00UL, 0x0000c300UL, 0x00004e00UL, 0x00000800UL, 0x00002e00UL,
|
||||
0x0000a100UL, 0x00006600UL, 0x00002800UL, 0x0000d900UL, 0x00002400UL,
|
||||
0x0000b200UL, 0x00007600UL, 0x00005b00UL, 0x0000a200UL, 0x00004900UL,
|
||||
0x00006d00UL, 0x00008b00UL, 0x0000d100UL, 0x00002500UL, 0x00007200UL,
|
||||
0x0000f800UL, 0x0000f600UL, 0x00006400UL, 0x00008600UL, 0x00006800UL,
|
||||
0x00009800UL, 0x00001600UL, 0x0000d400UL, 0x0000a400UL, 0x00005c00UL,
|
||||
0x0000cc00UL, 0x00005d00UL, 0x00006500UL, 0x0000b600UL, 0x00009200UL,
|
||||
0x00006c00UL, 0x00007000UL, 0x00004800UL, 0x00005000UL, 0x0000fd00UL,
|
||||
0x0000ed00UL, 0x0000b900UL, 0x0000da00UL, 0x00005e00UL, 0x00001500UL,
|
||||
0x00004600UL, 0x00005700UL, 0x0000a700UL, 0x00008d00UL, 0x00009d00UL,
|
||||
0x00008400UL, 0x00009000UL, 0x0000d800UL, 0x0000ab00UL, 0x00000000UL,
|
||||
0x00008c00UL, 0x0000bc00UL, 0x0000d300UL, 0x00000a00UL, 0x0000f700UL,
|
||||
0x0000e400UL, 0x00005800UL, 0x00000500UL, 0x0000b800UL, 0x0000b300UL,
|
||||
0x00004500UL, 0x00000600UL, 0x0000d000UL, 0x00002c00UL, 0x00001e00UL,
|
||||
0x00008f00UL, 0x0000ca00UL, 0x00003f00UL, 0x00000f00UL, 0x00000200UL,
|
||||
0x0000c100UL, 0x0000af00UL, 0x0000bd00UL, 0x00000300UL, 0x00000100UL,
|
||||
0x00001300UL, 0x00008a00UL, 0x00006b00UL, 0x00003a00UL, 0x00009100UL,
|
||||
0x00001100UL, 0x00004100UL, 0x00004f00UL, 0x00006700UL, 0x0000dc00UL,
|
||||
0x0000ea00UL, 0x00009700UL, 0x0000f200UL, 0x0000cf00UL, 0x0000ce00UL,
|
||||
0x0000f000UL, 0x0000b400UL, 0x0000e600UL, 0x00007300UL, 0x00009600UL,
|
||||
0x0000ac00UL, 0x00007400UL, 0x00002200UL, 0x0000e700UL, 0x0000ad00UL,
|
||||
0x00003500UL, 0x00008500UL, 0x0000e200UL, 0x0000f900UL, 0x00003700UL,
|
||||
0x0000e800UL, 0x00001c00UL, 0x00007500UL, 0x0000df00UL, 0x00006e00UL,
|
||||
0x00004700UL, 0x0000f100UL, 0x00001a00UL, 0x00007100UL, 0x00001d00UL,
|
||||
0x00002900UL, 0x0000c500UL, 0x00008900UL, 0x00006f00UL, 0x0000b700UL,
|
||||
0x00006200UL, 0x00000e00UL, 0x0000aa00UL, 0x00001800UL, 0x0000be00UL,
|
||||
0x00001b00UL, 0x0000fc00UL, 0x00005600UL, 0x00003e00UL, 0x00004b00UL,
|
||||
0x0000c600UL, 0x0000d200UL, 0x00007900UL, 0x00002000UL, 0x00009a00UL,
|
||||
0x0000db00UL, 0x0000c000UL, 0x0000fe00UL, 0x00007800UL, 0x0000cd00UL,
|
||||
0x00005a00UL, 0x0000f400UL, 0x00001f00UL, 0x0000dd00UL, 0x0000a800UL,
|
||||
0x00003300UL, 0x00008800UL, 0x00000700UL, 0x0000c700UL, 0x00003100UL,
|
||||
0x0000b100UL, 0x00001200UL, 0x00001000UL, 0x00005900UL, 0x00002700UL,
|
||||
0x00008000UL, 0x0000ec00UL, 0x00005f00UL, 0x00006000UL, 0x00005100UL,
|
||||
0x00007f00UL, 0x0000a900UL, 0x00001900UL, 0x0000b500UL, 0x00004a00UL,
|
||||
0x00000d00UL, 0x00002d00UL, 0x0000e500UL, 0x00007a00UL, 0x00009f00UL,
|
||||
0x00009300UL, 0x0000c900UL, 0x00009c00UL, 0x0000ef00UL, 0x0000a000UL,
|
||||
0x0000e000UL, 0x00003b00UL, 0x00004d00UL, 0x0000ae00UL, 0x00002a00UL,
|
||||
0x0000f500UL, 0x0000b000UL, 0x0000c800UL, 0x0000eb00UL, 0x0000bb00UL,
|
||||
0x00003c00UL, 0x00008300UL, 0x00005300UL, 0x00009900UL, 0x00006100UL,
|
||||
0x00001700UL, 0x00002b00UL, 0x00000400UL, 0x00007e00UL, 0x0000ba00UL,
|
||||
0x00007700UL, 0x0000d600UL, 0x00002600UL, 0x0000e100UL, 0x00006900UL,
|
||||
0x00001400UL, 0x00006300UL, 0x00005500UL, 0x00002100UL, 0x00000c00UL,
|
||||
0x00007d00UL},
|
||||
{0x00520000UL, 0x00090000UL, 0x006a0000UL, 0x00d50000UL, 0x00300000UL,
|
||||
0x00360000UL, 0x00a50000UL, 0x00380000UL, 0x00bf0000UL, 0x00400000UL,
|
||||
0x00a30000UL, 0x009e0000UL, 0x00810000UL, 0x00f30000UL, 0x00d70000UL,
|
||||
0x00fb0000UL, 0x007c0000UL, 0x00e30000UL, 0x00390000UL, 0x00820000UL,
|
||||
0x009b0000UL, 0x002f0000UL, 0x00ff0000UL, 0x00870000UL, 0x00340000UL,
|
||||
0x008e0000UL, 0x00430000UL, 0x00440000UL, 0x00c40000UL, 0x00de0000UL,
|
||||
0x00e90000UL, 0x00cb0000UL, 0x00540000UL, 0x007b0000UL, 0x00940000UL,
|
||||
0x00320000UL, 0x00a60000UL, 0x00c20000UL, 0x00230000UL, 0x003d0000UL,
|
||||
0x00ee0000UL, 0x004c0000UL, 0x00950000UL, 0x000b0000UL, 0x00420000UL,
|
||||
0x00fa0000UL, 0x00c30000UL, 0x004e0000UL, 0x00080000UL, 0x002e0000UL,
|
||||
0x00a10000UL, 0x00660000UL, 0x00280000UL, 0x00d90000UL, 0x00240000UL,
|
||||
0x00b20000UL, 0x00760000UL, 0x005b0000UL, 0x00a20000UL, 0x00490000UL,
|
||||
0x006d0000UL, 0x008b0000UL, 0x00d10000UL, 0x00250000UL, 0x00720000UL,
|
||||
0x00f80000UL, 0x00f60000UL, 0x00640000UL, 0x00860000UL, 0x00680000UL,
|
||||
0x00980000UL, 0x00160000UL, 0x00d40000UL, 0x00a40000UL, 0x005c0000UL,
|
||||
0x00cc0000UL, 0x005d0000UL, 0x00650000UL, 0x00b60000UL, 0x00920000UL,
|
||||
0x006c0000UL, 0x00700000UL, 0x00480000UL, 0x00500000UL, 0x00fd0000UL,
|
||||
0x00ed0000UL, 0x00b90000UL, 0x00da0000UL, 0x005e0000UL, 0x00150000UL,
|
||||
0x00460000UL, 0x00570000UL, 0x00a70000UL, 0x008d0000UL, 0x009d0000UL,
|
||||
0x00840000UL, 0x00900000UL, 0x00d80000UL, 0x00ab0000UL, 0x00000000UL,
|
||||
0x008c0000UL, 0x00bc0000UL, 0x00d30000UL, 0x000a0000UL, 0x00f70000UL,
|
||||
0x00e40000UL, 0x00580000UL, 0x00050000UL, 0x00b80000UL, 0x00b30000UL,
|
||||
0x00450000UL, 0x00060000UL, 0x00d00000UL, 0x002c0000UL, 0x001e0000UL,
|
||||
0x008f0000UL, 0x00ca0000UL, 0x003f0000UL, 0x000f0000UL, 0x00020000UL,
|
||||
0x00c10000UL, 0x00af0000UL, 0x00bd0000UL, 0x00030000UL, 0x00010000UL,
|
||||
0x00130000UL, 0x008a0000UL, 0x006b0000UL, 0x003a0000UL, 0x00910000UL,
|
||||
0x00110000UL, 0x00410000UL, 0x004f0000UL, 0x00670000UL, 0x00dc0000UL,
|
||||
0x00ea0000UL, 0x00970000UL, 0x00f20000UL, 0x00cf0000UL, 0x00ce0000UL,
|
||||
0x00f00000UL, 0x00b40000UL, 0x00e60000UL, 0x00730000UL, 0x00960000UL,
|
||||
0x00ac0000UL, 0x00740000UL, 0x00220000UL, 0x00e70000UL, 0x00ad0000UL,
|
||||
0x00350000UL, 0x00850000UL, 0x00e20000UL, 0x00f90000UL, 0x00370000UL,
|
||||
0x00e80000UL, 0x001c0000UL, 0x00750000UL, 0x00df0000UL, 0x006e0000UL,
|
||||
0x00470000UL, 0x00f10000UL, 0x001a0000UL, 0x00710000UL, 0x001d0000UL,
|
||||
0x00290000UL, 0x00c50000UL, 0x00890000UL, 0x006f0000UL, 0x00b70000UL,
|
||||
0x00620000UL, 0x000e0000UL, 0x00aa0000UL, 0x00180000UL, 0x00be0000UL,
|
||||
0x001b0000UL, 0x00fc0000UL, 0x00560000UL, 0x003e0000UL, 0x004b0000UL,
|
||||
0x00c60000UL, 0x00d20000UL, 0x00790000UL, 0x00200000UL, 0x009a0000UL,
|
||||
0x00db0000UL, 0x00c00000UL, 0x00fe0000UL, 0x00780000UL, 0x00cd0000UL,
|
||||
0x005a0000UL, 0x00f40000UL, 0x001f0000UL, 0x00dd0000UL, 0x00a80000UL,
|
||||
0x00330000UL, 0x00880000UL, 0x00070000UL, 0x00c70000UL, 0x00310000UL,
|
||||
0x00b10000UL, 0x00120000UL, 0x00100000UL, 0x00590000UL, 0x00270000UL,
|
||||
0x00800000UL, 0x00ec0000UL, 0x005f0000UL, 0x00600000UL, 0x00510000UL,
|
||||
0x007f0000UL, 0x00a90000UL, 0x00190000UL, 0x00b50000UL, 0x004a0000UL,
|
||||
0x000d0000UL, 0x002d0000UL, 0x00e50000UL, 0x007a0000UL, 0x009f0000UL,
|
||||
0x00930000UL, 0x00c90000UL, 0x009c0000UL, 0x00ef0000UL, 0x00a00000UL,
|
||||
0x00e00000UL, 0x003b0000UL, 0x004d0000UL, 0x00ae0000UL, 0x002a0000UL,
|
||||
0x00f50000UL, 0x00b00000UL, 0x00c80000UL, 0x00eb0000UL, 0x00bb0000UL,
|
||||
0x003c0000UL, 0x00830000UL, 0x00530000UL, 0x00990000UL, 0x00610000UL,
|
||||
0x00170000UL, 0x002b0000UL, 0x00040000UL, 0x007e0000UL, 0x00ba0000UL,
|
||||
0x00770000UL, 0x00d60000UL, 0x00260000UL, 0x00e10000UL, 0x00690000UL,
|
||||
0x00140000UL, 0x00630000UL, 0x00550000UL, 0x00210000UL, 0x000c0000UL,
|
||||
0x007d0000UL},
|
||||
{0x52000000UL, 0x09000000UL, 0x6a000000UL, 0xd5000000UL, 0x30000000UL,
|
||||
0x36000000UL, 0xa5000000UL, 0x38000000UL, 0xbf000000UL, 0x40000000UL,
|
||||
0xa3000000UL, 0x9e000000UL, 0x81000000UL, 0xf3000000UL, 0xd7000000UL,
|
||||
0xfb000000UL, 0x7c000000UL, 0xe3000000UL, 0x39000000UL, 0x82000000UL,
|
||||
0x9b000000UL, 0x2f000000UL, 0xff000000UL, 0x87000000UL, 0x34000000UL,
|
||||
0x8e000000UL, 0x43000000UL, 0x44000000UL, 0xc4000000UL, 0xde000000UL,
|
||||
0xe9000000UL, 0xcb000000UL, 0x54000000UL, 0x7b000000UL, 0x94000000UL,
|
||||
0x32000000UL, 0xa6000000UL, 0xc2000000UL, 0x23000000UL, 0x3d000000UL,
|
||||
0xee000000UL, 0x4c000000UL, 0x95000000UL, 0x0b000000UL, 0x42000000UL,
|
||||
0xfa000000UL, 0xc3000000UL, 0x4e000000UL, 0x08000000UL, 0x2e000000UL,
|
||||
0xa1000000UL, 0x66000000UL, 0x28000000UL, 0xd9000000UL, 0x24000000UL,
|
||||
0xb2000000UL, 0x76000000UL, 0x5b000000UL, 0xa2000000UL, 0x49000000UL,
|
||||
0x6d000000UL, 0x8b000000UL, 0xd1000000UL, 0x25000000UL, 0x72000000UL,
|
||||
0xf8000000UL, 0xf6000000UL, 0x64000000UL, 0x86000000UL, 0x68000000UL,
|
||||
0x98000000UL, 0x16000000UL, 0xd4000000UL, 0xa4000000UL, 0x5c000000UL,
|
||||
0xcc000000UL, 0x5d000000UL, 0x65000000UL, 0xb6000000UL, 0x92000000UL,
|
||||
0x6c000000UL, 0x70000000UL, 0x48000000UL, 0x50000000UL, 0xfd000000UL,
|
||||
0xed000000UL, 0xb9000000UL, 0xda000000UL, 0x5e000000UL, 0x15000000UL,
|
||||
0x46000000UL, 0x57000000UL, 0xa7000000UL, 0x8d000000UL, 0x9d000000UL,
|
||||
0x84000000UL, 0x90000000UL, 0xd8000000UL, 0xab000000UL, 0x00000000UL,
|
||||
0x8c000000UL, 0xbc000000UL, 0xd3000000UL, 0x0a000000UL, 0xf7000000UL,
|
||||
0xe4000000UL, 0x58000000UL, 0x05000000UL, 0xb8000000UL, 0xb3000000UL,
|
||||
0x45000000UL, 0x06000000UL, 0xd0000000UL, 0x2c000000UL, 0x1e000000UL,
|
||||
0x8f000000UL, 0xca000000UL, 0x3f000000UL, 0x0f000000UL, 0x02000000UL,
|
||||
0xc1000000UL, 0xaf000000UL, 0xbd000000UL, 0x03000000UL, 0x01000000UL,
|
||||
0x13000000UL, 0x8a000000UL, 0x6b000000UL, 0x3a000000UL, 0x91000000UL,
|
||||
0x11000000UL, 0x41000000UL, 0x4f000000UL, 0x67000000UL, 0xdc000000UL,
|
||||
0xea000000UL, 0x97000000UL, 0xf2000000UL, 0xcf000000UL, 0xce000000UL,
|
||||
0xf0000000UL, 0xb4000000UL, 0xe6000000UL, 0x73000000UL, 0x96000000UL,
|
||||
0xac000000UL, 0x74000000UL, 0x22000000UL, 0xe7000000UL, 0xad000000UL,
|
||||
0x35000000UL, 0x85000000UL, 0xe2000000UL, 0xf9000000UL, 0x37000000UL,
|
||||
0xe8000000UL, 0x1c000000UL, 0x75000000UL, 0xdf000000UL, 0x6e000000UL,
|
||||
0x47000000UL, 0xf1000000UL, 0x1a000000UL, 0x71000000UL, 0x1d000000UL,
|
||||
0x29000000UL, 0xc5000000UL, 0x89000000UL, 0x6f000000UL, 0xb7000000UL,
|
||||
0x62000000UL, 0x0e000000UL, 0xaa000000UL, 0x18000000UL, 0xbe000000UL,
|
||||
0x1b000000UL, 0xfc000000UL, 0x56000000UL, 0x3e000000UL, 0x4b000000UL,
|
||||
0xc6000000UL, 0xd2000000UL, 0x79000000UL, 0x20000000UL, 0x9a000000UL,
|
||||
0xdb000000UL, 0xc0000000UL, 0xfe000000UL, 0x78000000UL, 0xcd000000UL,
|
||||
0x5a000000UL, 0xf4000000UL, 0x1f000000UL, 0xdd000000UL, 0xa8000000UL,
|
||||
0x33000000UL, 0x88000000UL, 0x07000000UL, 0xc7000000UL, 0x31000000UL,
|
||||
0xb1000000UL, 0x12000000UL, 0x10000000UL, 0x59000000UL, 0x27000000UL,
|
||||
0x80000000UL, 0xec000000UL, 0x5f000000UL, 0x60000000UL, 0x51000000UL,
|
||||
0x7f000000UL, 0xa9000000UL, 0x19000000UL, 0xb5000000UL, 0x4a000000UL,
|
||||
0x0d000000UL, 0x2d000000UL, 0xe5000000UL, 0x7a000000UL, 0x9f000000UL,
|
||||
0x93000000UL, 0xc9000000UL, 0x9c000000UL, 0xef000000UL, 0xa0000000UL,
|
||||
0xe0000000UL, 0x3b000000UL, 0x4d000000UL, 0xae000000UL, 0x2a000000UL,
|
||||
0xf5000000UL, 0xb0000000UL, 0xc8000000UL, 0xeb000000UL, 0xbb000000UL,
|
||||
0x3c000000UL, 0x83000000UL, 0x53000000UL, 0x99000000UL, 0x61000000UL,
|
||||
0x17000000UL, 0x2b000000UL, 0x04000000UL, 0x7e000000UL, 0xba000000UL,
|
||||
0x77000000UL, 0xd6000000UL, 0x26000000UL, 0xe1000000UL, 0x69000000UL,
|
||||
0x14000000UL, 0x63000000UL, 0x55000000UL, 0x21000000UL, 0x0c000000UL,
|
||||
0x7d000000UL}
|
||||
};
|
||||
|
||||
static const unsigned long rco_tab[10] = {
|
||||
0x00000001UL, 0x00000002UL, 0x00000004UL, 0x00000008UL, 0x00000010UL,
|
||||
0x00000020UL, 0x00000040UL, 0x00000080UL, 0x0000001bUL, 0x00000036UL
|
||||
};
|
||||
|
55
ampi.c
Normal file
55
ampi.c
Normal file
@ -0,0 +1,55 @@
|
||||
/* Code submitted by Svante Seleborg, cleaned up by Tom St Denis */
|
||||
|
||||
#include "mycrypt.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef MPI
|
||||
|
||||
mp_err mp_init_multi(mp_int *mp, ...)
|
||||
{
|
||||
mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
|
||||
int n = 0; /* Number of ok inits */
|
||||
mp_int* cur_arg = mp;
|
||||
va_list args;
|
||||
|
||||
va_start(args, mp); /* init args to next argument from caller */
|
||||
while (cur_arg != NULL) {
|
||||
if (mp_init(cur_arg) != MP_OKAY) {
|
||||
/* Oops - error! Back-track and mp_clear what we already
|
||||
succeeded in init-ing, then return error.
|
||||
*/
|
||||
va_list clean_args;
|
||||
cur_arg = mp;
|
||||
va_start(clean_args, mp);
|
||||
while (n--) {
|
||||
mp_clear(cur_arg);
|
||||
cur_arg = va_arg(clean_args, mp_int*);
|
||||
}
|
||||
va_end(clean_args);
|
||||
res = MP_MEM;
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
cur_arg = va_arg(args, mp_int*);
|
||||
}
|
||||
va_end(args);
|
||||
return res; /* Assumed ok, if error flagged above. */
|
||||
}
|
||||
|
||||
/*
|
||||
Clear all arguments given, ended by a NULL marker.
|
||||
*/
|
||||
void mp_clear_multi(mp_int *mp, ...)
|
||||
{
|
||||
mp_int* next_mp = mp;
|
||||
va_list args;
|
||||
va_start(args, mp);
|
||||
while (next_mp != NULL) {
|
||||
mp_clear(next_mp);
|
||||
next_mp = va_arg(args, mp_int*);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
48
authors
Normal file
48
authors
Normal file
@ -0,0 +1,48 @@
|
||||
This is a list of people who have contributed [directly or indirectly] to the project
|
||||
[in no partcular order]. If you have helped and your name is not here email me at
|
||||
tomstdenis@yahoo.com.
|
||||
|
||||
|
||||
1) Richard.van.de.Laarschot@ict.nl
|
||||
|
||||
Gave help porting the lib to MSVC particularly pointed out various warnings and errors.
|
||||
|
||||
2) Richard Heathfield
|
||||
|
||||
Gave a lot of help concerning valid C portable code.
|
||||
|
||||
3) Ajay K. Agrawal
|
||||
|
||||
Helped port the library to MSVC and spotted a few bugs and errors.
|
||||
|
||||
4) Brian Gladman
|
||||
|
||||
Wrote the AES and Serpent code used. Found a bug in the hash code for certain types of inputs.
|
||||
|
||||
5) Svante Seleborg
|
||||
|
||||
Submitted the "ampi.c" code as well as many suggestions on improving the readability of the source code.
|
||||
|
||||
6) Clay Culver
|
||||
|
||||
Submitted a fix for "rsa.c" which cleaned up some code.
|
||||
|
||||
7) Jason Klapste
|
||||
|
||||
Submitted fixes to the yarrow, hash, make process and test code as well as other subtle bug fixes. The
|
||||
yarrow code can now default to any cipher/hash that is left after you remove them from a build.
|
||||
|
||||
8) Dobes Vandermeer <dobes@smartt.com>
|
||||
|
||||
Submitted HMAC code that worked flawlessly out of the box... good job! Also submitted a MD4 routine.
|
||||
Submitted some modified DES code that was merged into the code base [using the libtomcrypt API]
|
||||
|
||||
9) Wayne Scott (wscott@bitmover.com)
|
||||
|
||||
Submitted base64 that complies with the RFC standards.
|
||||
|
||||
10) Sky Schulz (sky@ogn.com)
|
||||
|
||||
Has submitted a set of ideas to improve the library and make it more attractive for professional users.
|
||||
|
||||
|
111
base64.c
Normal file
111
base64.c
Normal file
@ -0,0 +1,111 @@
|
||||
/* compliant base64 code donated by Wayne Scott (wscott@bitmover.com) */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef BASE64
|
||||
|
||||
static const char *codes =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
static const unsigned char map[256] = {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
|
||||
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
|
||||
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255 };
|
||||
|
||||
int base64_encode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long i, len2, leven;
|
||||
unsigned char *p;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* valid output size ? */
|
||||
len2 = 4 * ((len + 2) / 3);
|
||||
if (*outlen < len2 + 1) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
p = out;
|
||||
leven = 3*(len / 3);
|
||||
for (i = 0; i < leven; i += 3) {
|
||||
*p++ = codes[in[0] >> 2];
|
||||
*p++ = codes[((in[0] & 3) << 4) + (in[1] >> 4)];
|
||||
*p++ = codes[((in[1] & 0xf) << 2) + (in[2] >> 6)];
|
||||
*p++ = codes[in[2] & 0x3f];
|
||||
in += 3;
|
||||
}
|
||||
/* Pad it if necessary... */
|
||||
if (i < len) {
|
||||
unsigned a = in[0];
|
||||
unsigned b = (i+1 < len) ? in[1] : 0;
|
||||
unsigned c = 0;
|
||||
|
||||
*p++ = codes[a >> 2];
|
||||
*p++ = codes[((a & 3) << 4) + (b >> 4)];
|
||||
*p++ = (i+1 < len) ? codes[((b & 0xf) << 2) + (c >> 6)] : '=';
|
||||
*p++ = '=';
|
||||
}
|
||||
|
||||
/* append a NULL byte */
|
||||
*p = '\0';
|
||||
|
||||
/* return ok */
|
||||
*outlen = p - out;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int base64_decode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long t, x, y, z;
|
||||
unsigned char c;
|
||||
int g = 3;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
for (x = y = z = t = 0; x < len; x++) {
|
||||
c = map[in[x]];
|
||||
if (c == 255) continue;
|
||||
if (c == 254) { c = 0; g--; }
|
||||
t = (t<<6)|c;
|
||||
if (++y == 4) {
|
||||
if (z + g > *outlen) goto error;
|
||||
out[z++] = (unsigned char)((t>>16)&255);
|
||||
if (g > 1) out[z++] = (unsigned char)((t>>8)&255);
|
||||
if (g > 2) out[z++] = (unsigned char)(t&255);
|
||||
y = t = 0;
|
||||
}
|
||||
}
|
||||
if (y != 0) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
*outlen = z;
|
||||
return CRYPT_OK;
|
||||
error:
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
193
bits.c
Normal file
193
bits.c
Normal file
@ -0,0 +1,193 @@
|
||||
/* portable way to get secure random bits to feed a PRNG */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef DEVRANDOM
|
||||
/* on *NIX read /dev/random */
|
||||
static unsigned long rng_nix(unsigned char *buf, unsigned long len,
|
||||
void (*callback)(void))
|
||||
{
|
||||
#ifdef NO_FILE
|
||||
return 0;
|
||||
#else
|
||||
FILE *f;
|
||||
int x;
|
||||
#ifdef TRY_URANDOM_FIRST
|
||||
f = fopen("/dev/urandom", "rb");
|
||||
if (f == NULL)
|
||||
#endif /* TRY_URANDOM_FIRST */
|
||||
f = fopen("/dev/random", "rb");
|
||||
|
||||
if (f == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
x = fread(buf, 1, len, f);
|
||||
fclose(f);
|
||||
return x;
|
||||
#endif /* NO_FILE */
|
||||
}
|
||||
|
||||
#endif /* DEVRANDOM */
|
||||
|
||||
#ifdef SONY_PS2
|
||||
#include <eetypes.h>
|
||||
#include <eeregs.h>
|
||||
#define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
// Very simple/stupid MD5-based RNG that samples "entropy" from various PS2 control registers
|
||||
static unsigned long rng_ps2(unsigned char *buf, unsigned long len,
|
||||
void (*callback)(void))
|
||||
{
|
||||
static unsigned long lastx[2] = { 0xaab7cb4b2fd3b2b9, 0xcec58aff72afe49f }; // md5sum of bits.c
|
||||
unsigned long j;
|
||||
unsigned int samples[10]; // number of sample data sources
|
||||
int l;
|
||||
hash_state md;
|
||||
|
||||
for (j = 0; j < len; j += sizeof(lastx)) {
|
||||
md5_init(&md);
|
||||
samples[0] = *T2_COUNT;
|
||||
samples[1] = *T3_COUNT;
|
||||
samples[2] = *IPU_TOP;
|
||||
samples[3] = *GIF_TAG0;
|
||||
samples[4] = *GIF_TAG1;
|
||||
samples[5] = *GIF_TAG2;
|
||||
samples[6] = *VIF1_CODE;
|
||||
samples[7] = *VIF0_CODE;
|
||||
samples[8] = *D0_MADR;
|
||||
samples[9] = *D1_MADR;
|
||||
md5_process(&md, (unsigned char *)(&samples[0]), sizeof(samples));
|
||||
// include previous round
|
||||
md5_process(&md, (unsigned char *)(&lastx[0]), sizeof(lastx));
|
||||
md5_done(&md, (unsigned char *)(&lastx[0]));
|
||||
l = min(sizeof(lastx), len-j);
|
||||
memcpy(buf+j, &lastx[0], l); //min(sizeof(lastx), len-j));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
#endif /* SONY_PS2 */
|
||||
|
||||
/* on ANSI C platforms with 100 < CLOCKS_PER_SEC < 10000 */
|
||||
#if !defined(SONY_PS2) && defined(CLOCKS_PER_SEC)
|
||||
|
||||
#define ANSI_RNG
|
||||
|
||||
static unsigned long rng_ansic(unsigned char *buf, unsigned long len,
|
||||
void (*callback)(void))
|
||||
{
|
||||
clock_t t1;
|
||||
int l, acc, bits, a, b;
|
||||
|
||||
if (XCLOCKS_PER_SEC < 100 || XCLOCKS_PER_SEC > 10000) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
l = len;
|
||||
bits = 8;
|
||||
acc = a = b = 0;
|
||||
while (len--) {
|
||||
if (callback != NULL) callback();
|
||||
while (bits--) {
|
||||
do {
|
||||
t1 = XCLOCK(); while (t1 == XCLOCK()) a ^= 1;
|
||||
t1 = XCLOCK(); while (t1 == XCLOCK()) b ^= 1;
|
||||
} while (a == b);
|
||||
acc = (acc << 1) | a;
|
||||
}
|
||||
*buf++ = acc;
|
||||
acc = 0;
|
||||
bits = 8;
|
||||
}
|
||||
acc = bits = a = b = 0;
|
||||
return l;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Try the Microsoft CSP */
|
||||
#ifdef WIN32
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#include <windows.h>
|
||||
#include <wincrypt.h>
|
||||
|
||||
static unsigned long rng_win32(unsigned char *buf, unsigned long len,
|
||||
void (*callback)(void))
|
||||
{
|
||||
HCRYPTPROV hProv = 0;
|
||||
if (!CryptAcquireContext(&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
|
||||
(CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET)) &&
|
||||
!CryptAcquireContext (&hProv, NULL, MS_DEF_PROV, PROV_RSA_FULL,
|
||||
CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET | CRYPT_NEWKEYSET))
|
||||
return 0;
|
||||
|
||||
if (CryptGenRandom(hProv, len, buf) == TRUE) {
|
||||
CryptReleaseContext(hProv, 0);
|
||||
return len;
|
||||
} else {
|
||||
CryptReleaseContext(hProv, 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
unsigned long rng_get_bytes(unsigned char *buf, unsigned long len,
|
||||
void (*callback)(void))
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(buf != NULL);
|
||||
|
||||
#ifdef SONY_PS2
|
||||
x = rng_ps2(buf, len, callback); if (x) { return x; }
|
||||
#elif defined(DEVRANDOM)
|
||||
x = rng_nix(buf, len, callback); if (x) { return x; }
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
x = rng_win32(buf, len, callback); if (x) { return x; }
|
||||
#endif
|
||||
#ifdef ANSI_RNG
|
||||
x = rng_ansic(buf, len, callback); if (x) { return x; }
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rng_make_prng(int bits, int wprng, prng_state *prng,
|
||||
void (*callback)(void))
|
||||
{
|
||||
unsigned char buf[256];
|
||||
int errno;
|
||||
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
/* check parameter */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (bits < 64 || bits > 1024) {
|
||||
return CRYPT_INVALID_PRNGSIZE;
|
||||
}
|
||||
|
||||
if ((errno = prng_descriptor[wprng].start(prng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
bits = ((bits/8)+(bits&7?1:0)) * 2;
|
||||
if (rng_get_bytes(buf, bits, callback) != (unsigned long)bits) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
if ((errno = prng_descriptor[wprng].add_entropy(buf, bits, prng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
691
blowfish.c
Normal file
691
blowfish.c
Normal file
@ -0,0 +1,691 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef BLOWFISH
|
||||
|
||||
const struct _cipher_descriptor blowfish_desc =
|
||||
{
|
||||
"blowfish",
|
||||
0,
|
||||
8, 56, 8, 16,
|
||||
&blowfish_setup,
|
||||
&blowfish_ecb_encrypt,
|
||||
&blowfish_ecb_decrypt,
|
||||
&blowfish_test,
|
||||
&blowfish_keysize
|
||||
};
|
||||
|
||||
static const unsigned long ORIG_P[16 + 2] = {
|
||||
0x243F6A88UL, 0x85A308D3UL, 0x13198A2EUL, 0x03707344UL,
|
||||
0xA4093822UL, 0x299F31D0UL, 0x082EFA98UL, 0xEC4E6C89UL,
|
||||
0x452821E6UL, 0x38D01377UL, 0xBE5466CFUL, 0x34E90C6CUL,
|
||||
0xC0AC29B7UL, 0xC97C50DDUL, 0x3F84D5B5UL, 0xB5470917UL,
|
||||
0x9216D5D9UL, 0x8979FB1BUL
|
||||
};
|
||||
|
||||
static const unsigned long ORIG_S[4][256] = {
|
||||
{ 0xD1310BA6UL, 0x98DFB5ACUL, 0x2FFD72DBUL, 0xD01ADFB7UL,
|
||||
0xB8E1AFEDUL, 0x6A267E96UL, 0xBA7C9045UL, 0xF12C7F99UL,
|
||||
0x24A19947UL, 0xB3916CF7UL, 0x0801F2E2UL, 0x858EFC16UL,
|
||||
0x636920D8UL, 0x71574E69UL, 0xA458FEA3UL, 0xF4933D7EUL,
|
||||
0x0D95748FUL, 0x728EB658UL, 0x718BCD58UL, 0x82154AEEUL,
|
||||
0x7B54A41DUL, 0xC25A59B5UL, 0x9C30D539UL, 0x2AF26013UL,
|
||||
0xC5D1B023UL, 0x286085F0UL, 0xCA417918UL, 0xB8DB38EFUL,
|
||||
0x8E79DCB0UL, 0x603A180EUL, 0x6C9E0E8BUL, 0xB01E8A3EUL,
|
||||
0xD71577C1UL, 0xBD314B27UL, 0x78AF2FDAUL, 0x55605C60UL,
|
||||
0xE65525F3UL, 0xAA55AB94UL, 0x57489862UL, 0x63E81440UL,
|
||||
0x55CA396AUL, 0x2AAB10B6UL, 0xB4CC5C34UL, 0x1141E8CEUL,
|
||||
0xA15486AFUL, 0x7C72E993UL, 0xB3EE1411UL, 0x636FBC2AUL,
|
||||
0x2BA9C55DUL, 0x741831F6UL, 0xCE5C3E16UL, 0x9B87931EUL,
|
||||
0xAFD6BA33UL, 0x6C24CF5CUL, 0x7A325381UL, 0x28958677UL,
|
||||
0x3B8F4898UL, 0x6B4BB9AFUL, 0xC4BFE81BUL, 0x66282193UL,
|
||||
0x61D809CCUL, 0xFB21A991UL, 0x487CAC60UL, 0x5DEC8032UL,
|
||||
0xEF845D5DUL, 0xE98575B1UL, 0xDC262302UL, 0xEB651B88UL,
|
||||
0x23893E81UL, 0xD396ACC5UL, 0x0F6D6FF3UL, 0x83F44239UL,
|
||||
0x2E0B4482UL, 0xA4842004UL, 0x69C8F04AUL, 0x9E1F9B5EUL,
|
||||
0x21C66842UL, 0xF6E96C9AUL, 0x670C9C61UL, 0xABD388F0UL,
|
||||
0x6A51A0D2UL, 0xD8542F68UL, 0x960FA728UL, 0xAB5133A3UL,
|
||||
0x6EEF0B6CUL, 0x137A3BE4UL, 0xBA3BF050UL, 0x7EFB2A98UL,
|
||||
0xA1F1651DUL, 0x39AF0176UL, 0x66CA593EUL, 0x82430E88UL,
|
||||
0x8CEE8619UL, 0x456F9FB4UL, 0x7D84A5C3UL, 0x3B8B5EBEUL,
|
||||
0xE06F75D8UL, 0x85C12073UL, 0x401A449FUL, 0x56C16AA6UL,
|
||||
0x4ED3AA62UL, 0x363F7706UL, 0x1BFEDF72UL, 0x429B023DUL,
|
||||
0x37D0D724UL, 0xD00A1248UL, 0xDB0FEAD3UL, 0x49F1C09BUL,
|
||||
0x075372C9UL, 0x80991B7BUL, 0x25D479D8UL, 0xF6E8DEF7UL,
|
||||
0xE3FE501AUL, 0xB6794C3BUL, 0x976CE0BDUL, 0x04C006BAUL,
|
||||
0xC1A94FB6UL, 0x409F60C4UL, 0x5E5C9EC2UL, 0x196A2463UL,
|
||||
0x68FB6FAFUL, 0x3E6C53B5UL, 0x1339B2EBUL, 0x3B52EC6FUL,
|
||||
0x6DFC511FUL, 0x9B30952CUL, 0xCC814544UL, 0xAF5EBD09UL,
|
||||
0xBEE3D004UL, 0xDE334AFDUL, 0x660F2807UL, 0x192E4BB3UL,
|
||||
0xC0CBA857UL, 0x45C8740FUL, 0xD20B5F39UL, 0xB9D3FBDBUL,
|
||||
0x5579C0BDUL, 0x1A60320AUL, 0xD6A100C6UL, 0x402C7279UL,
|
||||
0x679F25FEUL, 0xFB1FA3CCUL, 0x8EA5E9F8UL, 0xDB3222F8UL,
|
||||
0x3C7516DFUL, 0xFD616B15UL, 0x2F501EC8UL, 0xAD0552ABUL,
|
||||
0x323DB5FAUL, 0xFD238760UL, 0x53317B48UL, 0x3E00DF82UL,
|
||||
0x9E5C57BBUL, 0xCA6F8CA0UL, 0x1A87562EUL, 0xDF1769DBUL,
|
||||
0xD542A8F6UL, 0x287EFFC3UL, 0xAC6732C6UL, 0x8C4F5573UL,
|
||||
0x695B27B0UL, 0xBBCA58C8UL, 0xE1FFA35DUL, 0xB8F011A0UL,
|
||||
0x10FA3D98UL, 0xFD2183B8UL, 0x4AFCB56CUL, 0x2DD1D35BUL,
|
||||
0x9A53E479UL, 0xB6F84565UL, 0xD28E49BCUL, 0x4BFB9790UL,
|
||||
0xE1DDF2DAUL, 0xA4CB7E33UL, 0x62FB1341UL, 0xCEE4C6E8UL,
|
||||
0xEF20CADAUL, 0x36774C01UL, 0xD07E9EFEUL, 0x2BF11FB4UL,
|
||||
0x95DBDA4DUL, 0xAE909198UL, 0xEAAD8E71UL, 0x6B93D5A0UL,
|
||||
0xD08ED1D0UL, 0xAFC725E0UL, 0x8E3C5B2FUL, 0x8E7594B7UL,
|
||||
0x8FF6E2FBUL, 0xF2122B64UL, 0x8888B812UL, 0x900DF01CUL,
|
||||
0x4FAD5EA0UL, 0x688FC31CUL, 0xD1CFF191UL, 0xB3A8C1ADUL,
|
||||
0x2F2F2218UL, 0xBE0E1777UL, 0xEA752DFEUL, 0x8B021FA1UL,
|
||||
0xE5A0CC0FUL, 0xB56F74E8UL, 0x18ACF3D6UL, 0xCE89E299UL,
|
||||
0xB4A84FE0UL, 0xFD13E0B7UL, 0x7CC43B81UL, 0xD2ADA8D9UL,
|
||||
0x165FA266UL, 0x80957705UL, 0x93CC7314UL, 0x211A1477UL,
|
||||
0xE6AD2065UL, 0x77B5FA86UL, 0xC75442F5UL, 0xFB9D35CFUL,
|
||||
0xEBCDAF0CUL, 0x7B3E89A0UL, 0xD6411BD3UL, 0xAE1E7E49UL,
|
||||
0x00250E2DUL, 0x2071B35EUL, 0x226800BBUL, 0x57B8E0AFUL,
|
||||
0x2464369BUL, 0xF009B91EUL, 0x5563911DUL, 0x59DFA6AAUL,
|
||||
0x78C14389UL, 0xD95A537FUL, 0x207D5BA2UL, 0x02E5B9C5UL,
|
||||
0x83260376UL, 0x6295CFA9UL, 0x11C81968UL, 0x4E734A41UL,
|
||||
0xB3472DCAUL, 0x7B14A94AUL, 0x1B510052UL, 0x9A532915UL,
|
||||
0xD60F573FUL, 0xBC9BC6E4UL, 0x2B60A476UL, 0x81E67400UL,
|
||||
0x08BA6FB5UL, 0x571BE91FUL, 0xF296EC6BUL, 0x2A0DD915UL,
|
||||
0xB6636521UL, 0xE7B9F9B6UL, 0xFF34052EUL, 0xC5855664UL,
|
||||
0x53B02D5DUL, 0xA99F8FA1UL, 0x08BA4799UL, 0x6E85076AUL },
|
||||
{ 0x4B7A70E9UL, 0xB5B32944UL, 0xDB75092EUL, 0xC4192623UL,
|
||||
0xAD6EA6B0UL, 0x49A7DF7DUL, 0x9CEE60B8UL, 0x8FEDB266UL,
|
||||
0xECAA8C71UL, 0x699A17FFUL, 0x5664526CUL, 0xC2B19EE1UL,
|
||||
0x193602A5UL, 0x75094C29UL, 0xA0591340UL, 0xE4183A3EUL,
|
||||
0x3F54989AUL, 0x5B429D65UL, 0x6B8FE4D6UL, 0x99F73FD6UL,
|
||||
0xA1D29C07UL, 0xEFE830F5UL, 0x4D2D38E6UL, 0xF0255DC1UL,
|
||||
0x4CDD2086UL, 0x8470EB26UL, 0x6382E9C6UL, 0x021ECC5EUL,
|
||||
0x09686B3FUL, 0x3EBAEFC9UL, 0x3C971814UL, 0x6B6A70A1UL,
|
||||
0x687F3584UL, 0x52A0E286UL, 0xB79C5305UL, 0xAA500737UL,
|
||||
0x3E07841CUL, 0x7FDEAE5CUL, 0x8E7D44ECUL, 0x5716F2B8UL,
|
||||
0xB03ADA37UL, 0xF0500C0DUL, 0xF01C1F04UL, 0x0200B3FFUL,
|
||||
0xAE0CF51AUL, 0x3CB574B2UL, 0x25837A58UL, 0xDC0921BDUL,
|
||||
0xD19113F9UL, 0x7CA92FF6UL, 0x94324773UL, 0x22F54701UL,
|
||||
0x3AE5E581UL, 0x37C2DADCUL, 0xC8B57634UL, 0x9AF3DDA7UL,
|
||||
0xA9446146UL, 0x0FD0030EUL, 0xECC8C73EUL, 0xA4751E41UL,
|
||||
0xE238CD99UL, 0x3BEA0E2FUL, 0x3280BBA1UL, 0x183EB331UL,
|
||||
0x4E548B38UL, 0x4F6DB908UL, 0x6F420D03UL, 0xF60A04BFUL,
|
||||
0x2CB81290UL, 0x24977C79UL, 0x5679B072UL, 0xBCAF89AFUL,
|
||||
0xDE9A771FUL, 0xD9930810UL, 0xB38BAE12UL, 0xDCCF3F2EUL,
|
||||
0x5512721FUL, 0x2E6B7124UL, 0x501ADDE6UL, 0x9F84CD87UL,
|
||||
0x7A584718UL, 0x7408DA17UL, 0xBC9F9ABCUL, 0xE94B7D8CUL,
|
||||
0xEC7AEC3AUL, 0xDB851DFAUL, 0x63094366UL, 0xC464C3D2UL,
|
||||
0xEF1C1847UL, 0x3215D908UL, 0xDD433B37UL, 0x24C2BA16UL,
|
||||
0x12A14D43UL, 0x2A65C451UL, 0x50940002UL, 0x133AE4DDUL,
|
||||
0x71DFF89EUL, 0x10314E55UL, 0x81AC77D6UL, 0x5F11199BUL,
|
||||
0x043556F1UL, 0xD7A3C76BUL, 0x3C11183BUL, 0x5924A509UL,
|
||||
0xF28FE6EDUL, 0x97F1FBFAUL, 0x9EBABF2CUL, 0x1E153C6EUL,
|
||||
0x86E34570UL, 0xEAE96FB1UL, 0x860E5E0AUL, 0x5A3E2AB3UL,
|
||||
0x771FE71CUL, 0x4E3D06FAUL, 0x2965DCB9UL, 0x99E71D0FUL,
|
||||
0x803E89D6UL, 0x5266C825UL, 0x2E4CC978UL, 0x9C10B36AUL,
|
||||
0xC6150EBAUL, 0x94E2EA78UL, 0xA5FC3C53UL, 0x1E0A2DF4UL,
|
||||
0xF2F74EA7UL, 0x361D2B3DUL, 0x1939260FUL, 0x19C27960UL,
|
||||
0x5223A708UL, 0xF71312B6UL, 0xEBADFE6EUL, 0xEAC31F66UL,
|
||||
0xE3BC4595UL, 0xA67BC883UL, 0xB17F37D1UL, 0x018CFF28UL,
|
||||
0xC332DDEFUL, 0xBE6C5AA5UL, 0x65582185UL, 0x68AB9802UL,
|
||||
0xEECEA50FUL, 0xDB2F953BUL, 0x2AEF7DADUL, 0x5B6E2F84UL,
|
||||
0x1521B628UL, 0x29076170UL, 0xECDD4775UL, 0x619F1510UL,
|
||||
0x13CCA830UL, 0xEB61BD96UL, 0x0334FE1EUL, 0xAA0363CFUL,
|
||||
0xB5735C90UL, 0x4C70A239UL, 0xD59E9E0BUL, 0xCBAADE14UL,
|
||||
0xEECC86BCUL, 0x60622CA7UL, 0x9CAB5CABUL, 0xB2F3846EUL,
|
||||
0x648B1EAFUL, 0x19BDF0CAUL, 0xA02369B9UL, 0x655ABB50UL,
|
||||
0x40685A32UL, 0x3C2AB4B3UL, 0x319EE9D5UL, 0xC021B8F7UL,
|
||||
0x9B540B19UL, 0x875FA099UL, 0x95F7997EUL, 0x623D7DA8UL,
|
||||
0xF837889AUL, 0x97E32D77UL, 0x11ED935FUL, 0x16681281UL,
|
||||
0x0E358829UL, 0xC7E61FD6UL, 0x96DEDFA1UL, 0x7858BA99UL,
|
||||
0x57F584A5UL, 0x1B227263UL, 0x9B83C3FFUL, 0x1AC24696UL,
|
||||
0xCDB30AEBUL, 0x532E3054UL, 0x8FD948E4UL, 0x6DBC3128UL,
|
||||
0x58EBF2EFUL, 0x34C6FFEAUL, 0xFE28ED61UL, 0xEE7C3C73UL,
|
||||
0x5D4A14D9UL, 0xE864B7E3UL, 0x42105D14UL, 0x203E13E0UL,
|
||||
0x45EEE2B6UL, 0xA3AAABEAUL, 0xDB6C4F15UL, 0xFACB4FD0UL,
|
||||
0xC742F442UL, 0xEF6ABBB5UL, 0x654F3B1DUL, 0x41CD2105UL,
|
||||
0xD81E799EUL, 0x86854DC7UL, 0xE44B476AUL, 0x3D816250UL,
|
||||
0xCF62A1F2UL, 0x5B8D2646UL, 0xFC8883A0UL, 0xC1C7B6A3UL,
|
||||
0x7F1524C3UL, 0x69CB7492UL, 0x47848A0BUL, 0x5692B285UL,
|
||||
0x095BBF00UL, 0xAD19489DUL, 0x1462B174UL, 0x23820E00UL,
|
||||
0x58428D2AUL, 0x0C55F5EAUL, 0x1DADF43EUL, 0x233F7061UL,
|
||||
0x3372F092UL, 0x8D937E41UL, 0xD65FECF1UL, 0x6C223BDBUL,
|
||||
0x7CDE3759UL, 0xCBEE7460UL, 0x4085F2A7UL, 0xCE77326EUL,
|
||||
0xA6078084UL, 0x19F8509EUL, 0xE8EFD855UL, 0x61D99735UL,
|
||||
0xA969A7AAUL, 0xC50C06C2UL, 0x5A04ABFCUL, 0x800BCADCUL,
|
||||
0x9E447A2EUL, 0xC3453484UL, 0xFDD56705UL, 0x0E1E9EC9UL,
|
||||
0xDB73DBD3UL, 0x105588CDUL, 0x675FDA79UL, 0xE3674340UL,
|
||||
0xC5C43465UL, 0x713E38D8UL, 0x3D28F89EUL, 0xF16DFF20UL,
|
||||
0x153E21E7UL, 0x8FB03D4AUL, 0xE6E39F2BUL, 0xDB83ADF7UL },
|
||||
{ 0xE93D5A68UL, 0x948140F7UL, 0xF64C261CUL, 0x94692934UL,
|
||||
0x411520F7UL, 0x7602D4F7UL, 0xBCF46B2EUL, 0xD4A20068UL,
|
||||
0xD4082471UL, 0x3320F46AUL, 0x43B7D4B7UL, 0x500061AFUL,
|
||||
0x1E39F62EUL, 0x97244546UL, 0x14214F74UL, 0xBF8B8840UL,
|
||||
0x4D95FC1DUL, 0x96B591AFUL, 0x70F4DDD3UL, 0x66A02F45UL,
|
||||
0xBFBC09ECUL, 0x03BD9785UL, 0x7FAC6DD0UL, 0x31CB8504UL,
|
||||
0x96EB27B3UL, 0x55FD3941UL, 0xDA2547E6UL, 0xABCA0A9AUL,
|
||||
0x28507825UL, 0x530429F4UL, 0x0A2C86DAUL, 0xE9B66DFBUL,
|
||||
0x68DC1462UL, 0xD7486900UL, 0x680EC0A4UL, 0x27A18DEEUL,
|
||||
0x4F3FFEA2UL, 0xE887AD8CUL, 0xB58CE006UL, 0x7AF4D6B6UL,
|
||||
0xAACE1E7CUL, 0xD3375FECUL, 0xCE78A399UL, 0x406B2A42UL,
|
||||
0x20FE9E35UL, 0xD9F385B9UL, 0xEE39D7ABUL, 0x3B124E8BUL,
|
||||
0x1DC9FAF7UL, 0x4B6D1856UL, 0x26A36631UL, 0xEAE397B2UL,
|
||||
0x3A6EFA74UL, 0xDD5B4332UL, 0x6841E7F7UL, 0xCA7820FBUL,
|
||||
0xFB0AF54EUL, 0xD8FEB397UL, 0x454056ACUL, 0xBA489527UL,
|
||||
0x55533A3AUL, 0x20838D87UL, 0xFE6BA9B7UL, 0xD096954BUL,
|
||||
0x55A867BCUL, 0xA1159A58UL, 0xCCA92963UL, 0x99E1DB33UL,
|
||||
0xA62A4A56UL, 0x3F3125F9UL, 0x5EF47E1CUL, 0x9029317CUL,
|
||||
0xFDF8E802UL, 0x04272F70UL, 0x80BB155CUL, 0x05282CE3UL,
|
||||
0x95C11548UL, 0xE4C66D22UL, 0x48C1133FUL, 0xC70F86DCUL,
|
||||
0x07F9C9EEUL, 0x41041F0FUL, 0x404779A4UL, 0x5D886E17UL,
|
||||
0x325F51EBUL, 0xD59BC0D1UL, 0xF2BCC18FUL, 0x41113564UL,
|
||||
0x257B7834UL, 0x602A9C60UL, 0xDFF8E8A3UL, 0x1F636C1BUL,
|
||||
0x0E12B4C2UL, 0x02E1329EUL, 0xAF664FD1UL, 0xCAD18115UL,
|
||||
0x6B2395E0UL, 0x333E92E1UL, 0x3B240B62UL, 0xEEBEB922UL,
|
||||
0x85B2A20EUL, 0xE6BA0D99UL, 0xDE720C8CUL, 0x2DA2F728UL,
|
||||
0xD0127845UL, 0x95B794FDUL, 0x647D0862UL, 0xE7CCF5F0UL,
|
||||
0x5449A36FUL, 0x877D48FAUL, 0xC39DFD27UL, 0xF33E8D1EUL,
|
||||
0x0A476341UL, 0x992EFF74UL, 0x3A6F6EABUL, 0xF4F8FD37UL,
|
||||
0xA812DC60UL, 0xA1EBDDF8UL, 0x991BE14CUL, 0xDB6E6B0DUL,
|
||||
0xC67B5510UL, 0x6D672C37UL, 0x2765D43BUL, 0xDCD0E804UL,
|
||||
0xF1290DC7UL, 0xCC00FFA3UL, 0xB5390F92UL, 0x690FED0BUL,
|
||||
0x667B9FFBUL, 0xCEDB7D9CUL, 0xA091CF0BUL, 0xD9155EA3UL,
|
||||
0xBB132F88UL, 0x515BAD24UL, 0x7B9479BFUL, 0x763BD6EBUL,
|
||||
0x37392EB3UL, 0xCC115979UL, 0x8026E297UL, 0xF42E312DUL,
|
||||
0x6842ADA7UL, 0xC66A2B3BUL, 0x12754CCCUL, 0x782EF11CUL,
|
||||
0x6A124237UL, 0xB79251E7UL, 0x06A1BBE6UL, 0x4BFB6350UL,
|
||||
0x1A6B1018UL, 0x11CAEDFAUL, 0x3D25BDD8UL, 0xE2E1C3C9UL,
|
||||
0x44421659UL, 0x0A121386UL, 0xD90CEC6EUL, 0xD5ABEA2AUL,
|
||||
0x64AF674EUL, 0xDA86A85FUL, 0xBEBFE988UL, 0x64E4C3FEUL,
|
||||
0x9DBC8057UL, 0xF0F7C086UL, 0x60787BF8UL, 0x6003604DUL,
|
||||
0xD1FD8346UL, 0xF6381FB0UL, 0x7745AE04UL, 0xD736FCCCUL,
|
||||
0x83426B33UL, 0xF01EAB71UL, 0xB0804187UL, 0x3C005E5FUL,
|
||||
0x77A057BEUL, 0xBDE8AE24UL, 0x55464299UL, 0xBF582E61UL,
|
||||
0x4E58F48FUL, 0xF2DDFDA2UL, 0xF474EF38UL, 0x8789BDC2UL,
|
||||
0x5366F9C3UL, 0xC8B38E74UL, 0xB475F255UL, 0x46FCD9B9UL,
|
||||
0x7AEB2661UL, 0x8B1DDF84UL, 0x846A0E79UL, 0x915F95E2UL,
|
||||
0x466E598EUL, 0x20B45770UL, 0x8CD55591UL, 0xC902DE4CUL,
|
||||
0xB90BACE1UL, 0xBB8205D0UL, 0x11A86248UL, 0x7574A99EUL,
|
||||
0xB77F19B6UL, 0xE0A9DC09UL, 0x662D09A1UL, 0xC4324633UL,
|
||||
0xE85A1F02UL, 0x09F0BE8CUL, 0x4A99A025UL, 0x1D6EFE10UL,
|
||||
0x1AB93D1DUL, 0x0BA5A4DFUL, 0xA186F20FUL, 0x2868F169UL,
|
||||
0xDCB7DA83UL, 0x573906FEUL, 0xA1E2CE9BUL, 0x4FCD7F52UL,
|
||||
0x50115E01UL, 0xA70683FAUL, 0xA002B5C4UL, 0x0DE6D027UL,
|
||||
0x9AF88C27UL, 0x773F8641UL, 0xC3604C06UL, 0x61A806B5UL,
|
||||
0xF0177A28UL, 0xC0F586E0UL, 0x006058AAUL, 0x30DC7D62UL,
|
||||
0x11E69ED7UL, 0x2338EA63UL, 0x53C2DD94UL, 0xC2C21634UL,
|
||||
0xBBCBEE56UL, 0x90BCB6DEUL, 0xEBFC7DA1UL, 0xCE591D76UL,
|
||||
0x6F05E409UL, 0x4B7C0188UL, 0x39720A3DUL, 0x7C927C24UL,
|
||||
0x86E3725FUL, 0x724D9DB9UL, 0x1AC15BB4UL, 0xD39EB8FCUL,
|
||||
0xED545578UL, 0x08FCA5B5UL, 0xD83D7CD3UL, 0x4DAD0FC4UL,
|
||||
0x1E50EF5EUL, 0xB161E6F8UL, 0xA28514D9UL, 0x6C51133CUL,
|
||||
0x6FD5C7E7UL, 0x56E14EC4UL, 0x362ABFCEUL, 0xDDC6C837UL,
|
||||
0xD79A3234UL, 0x92638212UL, 0x670EFA8EUL, 0x406000E0UL },
|
||||
{ 0x3A39CE37UL, 0xD3FAF5CFUL, 0xABC27737UL, 0x5AC52D1BUL,
|
||||
0x5CB0679EUL, 0x4FA33742UL, 0xD3822740UL, 0x99BC9BBEUL,
|
||||
0xD5118E9DUL, 0xBF0F7315UL, 0xD62D1C7EUL, 0xC700C47BUL,
|
||||
0xB78C1B6BUL, 0x21A19045UL, 0xB26EB1BEUL, 0x6A366EB4UL,
|
||||
0x5748AB2FUL, 0xBC946E79UL, 0xC6A376D2UL, 0x6549C2C8UL,
|
||||
0x530FF8EEUL, 0x468DDE7DUL, 0xD5730A1DUL, 0x4CD04DC6UL,
|
||||
0x2939BBDBUL, 0xA9BA4650UL, 0xAC9526E8UL, 0xBE5EE304UL,
|
||||
0xA1FAD5F0UL, 0x6A2D519AUL, 0x63EF8CE2UL, 0x9A86EE22UL,
|
||||
0xC089C2B8UL, 0x43242EF6UL, 0xA51E03AAUL, 0x9CF2D0A4UL,
|
||||
0x83C061BAUL, 0x9BE96A4DUL, 0x8FE51550UL, 0xBA645BD6UL,
|
||||
0x2826A2F9UL, 0xA73A3AE1UL, 0x4BA99586UL, 0xEF5562E9UL,
|
||||
0xC72FEFD3UL, 0xF752F7DAUL, 0x3F046F69UL, 0x77FA0A59UL,
|
||||
0x80E4A915UL, 0x87B08601UL, 0x9B09E6ADUL, 0x3B3EE593UL,
|
||||
0xE990FD5AUL, 0x9E34D797UL, 0x2CF0B7D9UL, 0x022B8B51UL,
|
||||
0x96D5AC3AUL, 0x017DA67DUL, 0xD1CF3ED6UL, 0x7C7D2D28UL,
|
||||
0x1F9F25CFUL, 0xADF2B89BUL, 0x5AD6B472UL, 0x5A88F54CUL,
|
||||
0xE029AC71UL, 0xE019A5E6UL, 0x47B0ACFDUL, 0xED93FA9BUL,
|
||||
0xE8D3C48DUL, 0x283B57CCUL, 0xF8D56629UL, 0x79132E28UL,
|
||||
0x785F0191UL, 0xED756055UL, 0xF7960E44UL, 0xE3D35E8CUL,
|
||||
0x15056DD4UL, 0x88F46DBAUL, 0x03A16125UL, 0x0564F0BDUL,
|
||||
0xC3EB9E15UL, 0x3C9057A2UL, 0x97271AECUL, 0xA93A072AUL,
|
||||
0x1B3F6D9BUL, 0x1E6321F5UL, 0xF59C66FBUL, 0x26DCF319UL,
|
||||
0x7533D928UL, 0xB155FDF5UL, 0x03563482UL, 0x8ABA3CBBUL,
|
||||
0x28517711UL, 0xC20AD9F8UL, 0xABCC5167UL, 0xCCAD925FUL,
|
||||
0x4DE81751UL, 0x3830DC8EUL, 0x379D5862UL, 0x9320F991UL,
|
||||
0xEA7A90C2UL, 0xFB3E7BCEUL, 0x5121CE64UL, 0x774FBE32UL,
|
||||
0xA8B6E37EUL, 0xC3293D46UL, 0x48DE5369UL, 0x6413E680UL,
|
||||
0xA2AE0810UL, 0xDD6DB224UL, 0x69852DFDUL, 0x09072166UL,
|
||||
0xB39A460AUL, 0x6445C0DDUL, 0x586CDECFUL, 0x1C20C8AEUL,
|
||||
0x5BBEF7DDUL, 0x1B588D40UL, 0xCCD2017FUL, 0x6BB4E3BBUL,
|
||||
0xDDA26A7EUL, 0x3A59FF45UL, 0x3E350A44UL, 0xBCB4CDD5UL,
|
||||
0x72EACEA8UL, 0xFA6484BBUL, 0x8D6612AEUL, 0xBF3C6F47UL,
|
||||
0xD29BE463UL, 0x542F5D9EUL, 0xAEC2771BUL, 0xF64E6370UL,
|
||||
0x740E0D8DUL, 0xE75B1357UL, 0xF8721671UL, 0xAF537D5DUL,
|
||||
0x4040CB08UL, 0x4EB4E2CCUL, 0x34D2466AUL, 0x0115AF84UL,
|
||||
0xE1B00428UL, 0x95983A1DUL, 0x06B89FB4UL, 0xCE6EA048UL,
|
||||
0x6F3F3B82UL, 0x3520AB82UL, 0x011A1D4BUL, 0x277227F8UL,
|
||||
0x611560B1UL, 0xE7933FDCUL, 0xBB3A792BUL, 0x344525BDUL,
|
||||
0xA08839E1UL, 0x51CE794BUL, 0x2F32C9B7UL, 0xA01FBAC9UL,
|
||||
0xE01CC87EUL, 0xBCC7D1F6UL, 0xCF0111C3UL, 0xA1E8AAC7UL,
|
||||
0x1A908749UL, 0xD44FBD9AUL, 0xD0DADECBUL, 0xD50ADA38UL,
|
||||
0x0339C32AUL, 0xC6913667UL, 0x8DF9317CUL, 0xE0B12B4FUL,
|
||||
0xF79E59B7UL, 0x43F5BB3AUL, 0xF2D519FFUL, 0x27D9459CUL,
|
||||
0xBF97222CUL, 0x15E6FC2AUL, 0x0F91FC71UL, 0x9B941525UL,
|
||||
0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL,
|
||||
0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL,
|
||||
0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL,
|
||||
0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL,
|
||||
0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL,
|
||||
0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL,
|
||||
0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL,
|
||||
0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL,
|
||||
0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL,
|
||||
0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL,
|
||||
0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL,
|
||||
0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL,
|
||||
0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL,
|
||||
0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL,
|
||||
0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL,
|
||||
0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL,
|
||||
0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL,
|
||||
0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL,
|
||||
0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL,
|
||||
0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL }
|
||||
};
|
||||
|
||||
static unsigned long F(unsigned long x, symmetric_key *key)
|
||||
{
|
||||
return (((key->blowfish.S[0][(x>>24)&255] +
|
||||
key->blowfish.S[1][(x>>16)&255]) ^
|
||||
key->blowfish.S[2][(x>>8)&255]) +
|
||||
key->blowfish.S[3][(x>>0)&255]);
|
||||
}
|
||||
|
||||
int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
|
||||
symmetric_key *skey)
|
||||
{
|
||||
unsigned long x, y, z, A;
|
||||
unsigned char B[8];
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
/* check key length */
|
||||
if (keylen < 8 || keylen > 56) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
/* check rounds */
|
||||
if (num_rounds != 0 && num_rounds != 16) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
/* load in key bytes (Supplied by David Hopwood) */
|
||||
for (x = y = 0; x < 18; x++) {
|
||||
A = 0;
|
||||
for (z = 0; z < 4; z++) {
|
||||
A = (A << 8) | (unsigned long) key[y++ % keylen];
|
||||
}
|
||||
skey->blowfish.K[x] = ORIG_P[x] ^ A;
|
||||
}
|
||||
|
||||
/* copy sboxes */
|
||||
for (x = 0; x < 4; x++) {
|
||||
for (y = 0; y < 256; y++) {
|
||||
skey->blowfish.S[x][y] = ORIG_S[x][y];
|
||||
}
|
||||
}
|
||||
|
||||
/* encrypt K array */
|
||||
zeromem(B, 8);
|
||||
for (x = 0; x < 18; x += 2) {
|
||||
/* encrypt it */
|
||||
blowfish_ecb_encrypt(B, B, skey);
|
||||
/* copy it */
|
||||
LOAD32H(skey->blowfish.K[x], &B[0]);
|
||||
LOAD32H(skey->blowfish.K[x+1], &B[4]);
|
||||
}
|
||||
|
||||
/* encrypt S array */
|
||||
for (x = 0; x < 4; x++) {
|
||||
for (y = 0; y < 256; y += 2) {
|
||||
/* encrypt it */
|
||||
blowfish_ecb_encrypt(B, B, skey);
|
||||
/* copy it */
|
||||
LOAD32H(skey->blowfish.S[x][y], &B[0]);
|
||||
LOAD32H(skey->blowfish.S[x][y+1], &B[4]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(B, sizeof(B));
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#else
|
||||
void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
unsigned long L, R;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* load it */
|
||||
LOAD32H(L, &pt[0]);
|
||||
LOAD32H(R, &pt[4]);
|
||||
|
||||
/* do 16 rounds */
|
||||
L ^= key->blowfish.K[0]; R ^= F(L, key);
|
||||
R ^= key->blowfish.K[1]; L ^= F(R, key);
|
||||
L ^= key->blowfish.K[2]; R ^= F(L, key);
|
||||
R ^= key->blowfish.K[3]; L ^= F(R, key);
|
||||
L ^= key->blowfish.K[4]; R ^= F(L, key);
|
||||
R ^= key->blowfish.K[5]; L ^= F(R, key);
|
||||
L ^= key->blowfish.K[6]; R ^= F(L, key);
|
||||
R ^= key->blowfish.K[7]; L ^= F(R, key);
|
||||
L ^= key->blowfish.K[8]; R ^= F(L, key);
|
||||
R ^= key->blowfish.K[9]; L ^= F(R, key);
|
||||
L ^= key->blowfish.K[10]; R ^= F(L, key);
|
||||
R ^= key->blowfish.K[11]; L ^= F(R, key);
|
||||
L ^= key->blowfish.K[12]; R ^= F(L, key);
|
||||
R ^= key->blowfish.K[13]; L ^= F(R, key);
|
||||
L ^= key->blowfish.K[14]; R ^= F(L, key);
|
||||
R ^= key->blowfish.K[15]; L ^= F(R, key);
|
||||
|
||||
/* last keying */
|
||||
R ^= key->blowfish.K[17];
|
||||
L ^= key->blowfish.K[16];
|
||||
|
||||
/* store */
|
||||
STORE32H(R, &ct[0]);
|
||||
STORE32H(L, &ct[4]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
{
|
||||
_blowfish_ecb_encrypt(pt, ct, key);
|
||||
burn_stack(sizeof(unsigned long) * 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#else
|
||||
void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
unsigned long L, R;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* load it */
|
||||
LOAD32H(R, &ct[0]);
|
||||
LOAD32H(L, &ct[4]);
|
||||
|
||||
/* undo last keying */
|
||||
R ^= key->blowfish.K[17];
|
||||
L ^= key->blowfish.K[16];
|
||||
|
||||
/* do 16 rounds */
|
||||
L ^= F(R, key); R ^= key->blowfish.K[15];
|
||||
R ^= F(L, key); L ^= key->blowfish.K[14];
|
||||
L ^= F(R, key); R ^= key->blowfish.K[13];
|
||||
R ^= F(L, key); L ^= key->blowfish.K[12];
|
||||
L ^= F(R, key); R ^= key->blowfish.K[11];
|
||||
R ^= F(L, key); L ^= key->blowfish.K[10];
|
||||
L ^= F(R, key); R ^= key->blowfish.K[9];
|
||||
R ^= F(L, key); L ^= key->blowfish.K[8];
|
||||
L ^= F(R, key); R ^= key->blowfish.K[7];
|
||||
R ^= F(L, key); L ^= key->blowfish.K[6];
|
||||
L ^= F(R, key); R ^= key->blowfish.K[5];
|
||||
R ^= F(L, key); L ^= key->blowfish.K[4];
|
||||
L ^= F(R, key); R ^= key->blowfish.K[3];
|
||||
R ^= F(L, key); L ^= key->blowfish.K[2];
|
||||
L ^= F(R, key); R ^= key->blowfish.K[1];
|
||||
R ^= F(L, key); L ^= key->blowfish.K[0];
|
||||
|
||||
/* store */
|
||||
STORE32H(L, &pt[0]);
|
||||
STORE32H(R, &pt[4]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
{
|
||||
_blowfish_ecb_decrypt(ct, pt, key);
|
||||
burn_stack(sizeof(unsigned long) * 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int blowfish_test(void)
|
||||
{
|
||||
int errno;
|
||||
symmetric_key key;
|
||||
static const struct {
|
||||
unsigned char key[8], pt[8], ct[8];
|
||||
} tests[] = {
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}
|
||||
},
|
||||
{
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{ 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A}
|
||||
},
|
||||
{
|
||||
{ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
{ 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}
|
||||
},
|
||||
{
|
||||
{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
{ 0x24, 0x66, 0xDD, 0x87, 0x8B, 0x96, 0x3C, 0x9D}
|
||||
},
|
||||
{
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
{ 0x61, 0xF9, 0xC3, 0x80, 0x22, 0x81, 0xB0, 0x96}
|
||||
},
|
||||
{
|
||||
{ 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{ 0x7D, 0x0C, 0xC6, 0x30, 0xAF, 0xDA, 0x1E, 0xC7}
|
||||
},
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}
|
||||
},
|
||||
{
|
||||
{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{ 0x0A, 0xCE, 0xAB, 0x0F, 0xC6, 0xA0, 0xA2, 0x8D}
|
||||
},
|
||||
{
|
||||
{ 0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57},
|
||||
{ 0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42},
|
||||
{ 0x59, 0xC6, 0x82, 0x45, 0xEB, 0x05, 0x28, 0x2B}
|
||||
},
|
||||
{
|
||||
{ 0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E},
|
||||
{ 0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA},
|
||||
{ 0xB1, 0xB8, 0xCC, 0x0B, 0x25, 0x0F, 0x09, 0xA0}
|
||||
},
|
||||
{
|
||||
{ 0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86},
|
||||
{ 0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72},
|
||||
{ 0x17, 0x30, 0xE5, 0x77, 0x8B, 0xEA, 0x1D, 0xA4}
|
||||
},
|
||||
{
|
||||
{ 0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E},
|
||||
{ 0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A},
|
||||
{ 0xA2, 0x5E, 0x78, 0x56, 0xCF, 0x26, 0x51, 0xEB}
|
||||
},
|
||||
{
|
||||
{ 0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6},
|
||||
{ 0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2},
|
||||
{ 0x35, 0x38, 0x82, 0xB1, 0x09, 0xCE, 0x8F, 0x1A}
|
||||
},
|
||||
{
|
||||
{ 0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE},
|
||||
{ 0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A},
|
||||
{ 0x48, 0xF4, 0xD0, 0x88, 0x4C, 0x37, 0x99, 0x18}
|
||||
},
|
||||
{
|
||||
{ 0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6},
|
||||
{ 0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2},
|
||||
{ 0x43, 0x21, 0x93, 0xB7, 0x89, 0x51, 0xFC, 0x98}
|
||||
},
|
||||
{
|
||||
{ 0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE},
|
||||
{ 0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A},
|
||||
{ 0x13, 0xF0, 0x41, 0x54, 0xD6, 0x9D, 0x1A, 0xE5}
|
||||
},
|
||||
{
|
||||
{ 0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16},
|
||||
{ 0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02},
|
||||
{ 0x2E, 0xED, 0xDA, 0x93, 0xFF, 0xD3, 0x9C, 0x79}
|
||||
},
|
||||
{
|
||||
{ 0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F},
|
||||
{ 0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A},
|
||||
{ 0xD8, 0x87, 0xE0, 0x39, 0x3C, 0x2D, 0xA6, 0xE3}
|
||||
},
|
||||
{
|
||||
{ 0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46},
|
||||
{ 0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32},
|
||||
{ 0x5F, 0x99, 0xD0, 0x4F, 0x5B, 0x16, 0x39, 0x69}
|
||||
},
|
||||
{
|
||||
{ 0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E},
|
||||
{ 0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA},
|
||||
{ 0x4A, 0x05, 0x7A, 0x3B, 0x24, 0xD3, 0x97, 0x7B}
|
||||
},
|
||||
{
|
||||
{ 0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76},
|
||||
{ 0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62},
|
||||
{ 0x45, 0x20, 0x31, 0xC1, 0xE4, 0xFA, 0xDA, 0x8E}
|
||||
},
|
||||
{
|
||||
{ 0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07},
|
||||
{ 0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2},
|
||||
{ 0x75, 0x55, 0xAE, 0x39, 0xF5, 0x9B, 0x87, 0xBD}
|
||||
},
|
||||
{
|
||||
{ 0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F},
|
||||
{ 0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA},
|
||||
{ 0x53, 0xC5, 0x5F, 0x9C, 0xB4, 0x9F, 0xC0, 0x19}
|
||||
},
|
||||
{
|
||||
{ 0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7},
|
||||
{ 0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92},
|
||||
{ 0x7A, 0x8E, 0x7B, 0xFA, 0x93, 0x7E, 0x89, 0xA3}
|
||||
},
|
||||
{
|
||||
{ 0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF},
|
||||
{ 0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A},
|
||||
{ 0xCF, 0x9C, 0x5D, 0x7A, 0x49, 0x86, 0xAD, 0xB5}
|
||||
},
|
||||
{
|
||||
{ 0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6},
|
||||
{ 0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2},
|
||||
{ 0xD1, 0xAB, 0xB2, 0x90, 0x65, 0x8B, 0xC7, 0x78}
|
||||
},
|
||||
{
|
||||
{ 0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF},
|
||||
{ 0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A},
|
||||
{ 0x55, 0xCB, 0x37, 0x74, 0xD1, 0x3E, 0xF2, 0x01}
|
||||
},
|
||||
{
|
||||
{ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{ 0xFA, 0x34, 0xEC, 0x48, 0x47, 0xB2, 0x68, 0xB2}
|
||||
},
|
||||
{
|
||||
{ 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E},
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{ 0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE}
|
||||
},
|
||||
{
|
||||
{ 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE},
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{ 0xC3, 0x9E, 0x07, 0x2D, 0x9F, 0xAC, 0x63, 0x1D}
|
||||
},
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{ 0x01, 0x49, 0x33, 0xE0, 0xCD, 0xAF, 0xF6, 0xE4}
|
||||
},
|
||||
{
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0xF2, 0x1E, 0x9A, 0x77, 0xB7, 0x1C, 0x49, 0xBC}
|
||||
},
|
||||
{
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0x24, 0x59, 0x46, 0x88, 0x57, 0x54, 0x36, 0x9A}
|
||||
},
|
||||
{
|
||||
{ 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{ 0x6B, 0x5C, 0x5A, 0x9C, 0x5D, 0x9E, 0x0A, 0x5A}
|
||||
}
|
||||
};
|
||||
unsigned char buf[2][8];
|
||||
int x, failed;
|
||||
|
||||
for (x = failed = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
|
||||
/* setup key */
|
||||
if ((errno = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* encrypt and decrypt */
|
||||
blowfish_ecb_encrypt(tests[x].pt, buf[0], &key);
|
||||
blowfish_ecb_decrypt(buf[0], buf[1], &key);
|
||||
|
||||
/* compare */
|
||||
if (memcmp(buf[0], tests[x].ct, 8)) {
|
||||
#if 0
|
||||
int y;
|
||||
printf("\nEncrypt test %d failed\n", x);
|
||||
for (y = 0; y < 8; y++) printf("%02x ", buf[0][y]);
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
if (memcmp(buf[1], tests[x].pt, 8)) {
|
||||
#if 0
|
||||
int y;
|
||||
printf("\nDecrypt test %d failed\n", x);
|
||||
for (y = 0; y < 8; y++) printf("%02x ", buf[1][y]);
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int blowfish_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
|
||||
if (*desired_keysize < 8) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
} else if (*desired_keysize > 56) {
|
||||
*desired_keysize = 56;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
622
cast5.c
Normal file
622
cast5.c
Normal file
@ -0,0 +1,622 @@
|
||||
/* Implementation of CAST5 (RFC 2144) by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef CAST5
|
||||
|
||||
const struct _cipher_descriptor cast5_desc = {
|
||||
"cast5",
|
||||
15,
|
||||
5, 16, 8, 16,
|
||||
&cast5_setup,
|
||||
&cast5_ecb_encrypt,
|
||||
&cast5_ecb_decrypt,
|
||||
&cast5_test,
|
||||
&cast5_keysize
|
||||
};
|
||||
|
||||
static const unsigned long S1[256] = {
|
||||
0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3,
|
||||
0x6003e540, 0xcf9fc949, 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675,
|
||||
0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, 0x28683b6f, 0xc07fd059,
|
||||
0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
|
||||
0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, 0x2abe32e1, 0xaa54166b,
|
||||
0x22568e3a, 0xa2d341d0, 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de,
|
||||
0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, 0xb82cbaef, 0xd751d159,
|
||||
0x6ff7f0ed, 0x5a097a1f, 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935,
|
||||
0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, 0xb7332290, 0xe93b159f,
|
||||
0xb48ee411, 0x4bff345d, 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165,
|
||||
0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, 0x882240f2, 0x0c6e4f38,
|
||||
0xa4e4bfd7, 0x4f5ba272, 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe,
|
||||
0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, 0x57538ad5, 0x6a390493,
|
||||
0xe63d37e0, 0x2a54f6b3, 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a,
|
||||
0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, 0x38901091, 0xc6b505eb,
|
||||
0x84c7cb8c, 0x2ad75a0f, 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291,
|
||||
0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, 0x6c00b32d, 0x73e2bb14,
|
||||
0xa0bebc3c, 0x54623779, 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6,
|
||||
0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, 0x81383f05, 0x6963c5c8,
|
||||
0x76cb5ad6, 0xd49974c9, 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511,
|
||||
0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, 0x31366241, 0x051ef495,
|
||||
0xaa573b04, 0x4a805d8d, 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e,
|
||||
0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, 0x6b54bfab, 0x2b0b1426,
|
||||
0xab4cc9d7, 0x449ccd82, 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324,
|
||||
0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, 0xeadf55b3, 0xd5bd9e98,
|
||||
0xe31231b2, 0x2ad5ad6c, 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f,
|
||||
0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, 0x7b5a41f0, 0xd37cfbad,
|
||||
0x1b069505, 0x41ece491, 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d,
|
||||
0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, 0xe01063da, 0x4736f464,
|
||||
0x5ad328d8, 0xb347cc96, 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a,
|
||||
0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, 0x3f04442f, 0x6188b153,
|
||||
0xe0397a2e, 0x5727cb79, 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d,
|
||||
0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, 0x4744ead4, 0xb11c3274,
|
||||
0xdd24cb9e, 0x7e1c54bd, 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755,
|
||||
0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, 0x580304f0, 0xca042cf1,
|
||||
0x011a37ea, 0x8dbfaadb, 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9,
|
||||
0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, 0x7c63b2cf, 0x700b45e1,
|
||||
0xd5ea50f1, 0x85a92872, 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79,
|
||||
0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, 0x474d6ad7, 0x7c0c5e5c,
|
||||
0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
|
||||
0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff,
|
||||
0xb141ab08, 0x7cca89b9, 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d,
|
||||
0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf};
|
||||
|
||||
static const unsigned long S2[256] = {
|
||||
0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a,
|
||||
0x55889c94, 0x72fc0651, 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba,
|
||||
0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, 0xa0b52f7b, 0x59e83605,
|
||||
0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
|
||||
0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, 0x01420ddb, 0xe4e7ef5b,
|
||||
0x25a1ff41, 0xe180f806, 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4,
|
||||
0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, 0xe113c85b, 0xacc40083,
|
||||
0xd7503525, 0xf7ea615f, 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359,
|
||||
0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, 0x071f6181, 0x39f7627f,
|
||||
0x361e3084, 0xe4eb573b, 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d,
|
||||
0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, 0x10843094, 0x2537a95e,
|
||||
0xf46f6ffe, 0xa1ff3b1f, 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34,
|
||||
0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, 0x8a45388c, 0x1d804366,
|
||||
0x721d9bfd, 0xa58684bb, 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4,
|
||||
0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, 0xc5d655dd, 0xeb667064,
|
||||
0x77840b4d, 0xa1b6a801, 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860,
|
||||
0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, 0xb5625dbf, 0x68561be6,
|
||||
0x83ca6b94, 0x2d6ed23b, 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709,
|
||||
0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, 0x81ed6f61, 0x20e74364,
|
||||
0xb45e1378, 0xde18639b, 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b,
|
||||
0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, 0x488cb402, 0x1ba4fe5b,
|
||||
0xa4b09f6b, 0x1ca815cf, 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9,
|
||||
0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, 0xee41e729, 0x6e1d2d7c,
|
||||
0x50045286, 0x1e6685f3, 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13,
|
||||
0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, 0xcdff33a6, 0xa02b1741,
|
||||
0x7cbad9a2, 0x2180036f, 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab,
|
||||
0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, 0xcdf0b680, 0x17844d3b,
|
||||
0x31eef84d, 0x7e0824e4, 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6,
|
||||
0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, 0xb3faec54, 0x157fd7fa,
|
||||
0xef8579cc, 0xd152de58, 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8,
|
||||
0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, 0xb8da230c, 0x80823028,
|
||||
0xdcdef3c8, 0xd35fb171, 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d,
|
||||
0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, 0x8b1c34bc, 0x301e16e6,
|
||||
0x273be979, 0xb0ffeaa6, 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b,
|
||||
0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, 0xdc8637a0, 0x16a7d3b1,
|
||||
0x9fc393b7, 0xa7136eeb, 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6,
|
||||
0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, 0xdb92f2fb, 0x5eea29cb,
|
||||
0x145892f5, 0x91584f7f, 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea,
|
||||
0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, 0xb284600c, 0xd835731d,
|
||||
0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
|
||||
0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e,
|
||||
0x5c038323, 0x3e5d3bb9, 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef,
|
||||
0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1};
|
||||
|
||||
static const unsigned long S3[256] = {
|
||||
0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b,
|
||||
0x8c1fc644, 0xaececa90, 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae,
|
||||
0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, 0x11107d9f, 0x07647db9,
|
||||
0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
|
||||
0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, 0x21fffcee, 0x825b1bfd,
|
||||
0x9255c5ed, 0x1257a240, 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e,
|
||||
0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, 0xa8c01db7, 0x579fc264,
|
||||
0x67094f31, 0xf2bd3f5f, 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b,
|
||||
0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, 0xa197c81c, 0x4a012d6e,
|
||||
0xc5884a28, 0xccc36f71, 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f,
|
||||
0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, 0xa747d2d0, 0x1651192e,
|
||||
0xaf70bf3e, 0x58c31380, 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82,
|
||||
0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, 0x8427f4a0, 0x1eac5790,
|
||||
0x796fb449, 0x8252dc15, 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504,
|
||||
0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, 0x23efe941, 0xa903f12e,
|
||||
0x60270df2, 0x0276e4b6, 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176,
|
||||
0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, 0x842f7d83, 0x340ce5c8,
|
||||
0x96bbb682, 0x93b4b148, 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d,
|
||||
0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, 0x8b907cee, 0xb51fd240,
|
||||
0xe7c07ce3, 0xe566b4a1, 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341,
|
||||
0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, 0xf76cedd9, 0xbda8229c,
|
||||
0x127dadaa, 0x438a074e, 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15,
|
||||
0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, 0x68cc7bfb, 0xd90f2788,
|
||||
0x12490181, 0x5de5ffd4, 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f,
|
||||
0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, 0x6d498623, 0x193cbcfa,
|
||||
0x27627545, 0x825cf47a, 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392,
|
||||
0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, 0x285ba1c8, 0x3c62f44f,
|
||||
0x35c0eaa5, 0xe805d231, 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b,
|
||||
0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, 0x694bcc11, 0x236a5cae,
|
||||
0x12deca4d, 0x2c3f8cc5, 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67,
|
||||
0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, 0x3a609437, 0xec00c9a9,
|
||||
0x44715253, 0x0a874b49, 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536,
|
||||
0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, 0x07478cd1, 0x006e1888,
|
||||
0xa2e53f55, 0xb9e6d4bc, 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d,
|
||||
0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, 0x947b0001, 0x570075d2,
|
||||
0xf9bb88f8, 0x8942019e, 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69,
|
||||
0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, 0xcf1febd2, 0x61efc8c2,
|
||||
0xf1ac2571, 0xcc8239c2, 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce,
|
||||
0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, 0x5727c148, 0x2be98a1d,
|
||||
0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
|
||||
0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00,
|
||||
0x52bce688, 0x1b03588a, 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5,
|
||||
0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783};
|
||||
|
||||
static const unsigned long S4[256] = {
|
||||
0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57,
|
||||
0x85510443, 0xfa020ed1, 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120,
|
||||
0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, 0x28147f5f, 0x4fa2b8cd,
|
||||
0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
|
||||
0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, 0x1a05645f, 0x0c13fefe,
|
||||
0x081b08ca, 0x05170121, 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701,
|
||||
0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, 0xce84ffdf, 0xf5718801,
|
||||
0x3dd64b04, 0xa26f263b, 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5,
|
||||
0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, 0xd3772061, 0x11b638e1,
|
||||
0x72500e03, 0xf80eb2bb, 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746,
|
||||
0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, 0x4d351805, 0x7f3d5ce3,
|
||||
0xa6c866c6, 0x5d5bcca9, 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d,
|
||||
0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, 0x022083b8, 0x3fb6180c,
|
||||
0x18f8931e, 0x281658e6, 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c,
|
||||
0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, 0x69dead38, 0x1574ca16,
|
||||
0xdf871b62, 0x211c40b7, 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003,
|
||||
0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, 0x557be8de, 0x00eae4a7,
|
||||
0x0ce5c2ec, 0x4db4bba6, 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327,
|
||||
0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, 0x6e85cb75, 0xbe07c002,
|
||||
0xc2325577, 0x893ff4ec, 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24,
|
||||
0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, 0xaac9548a, 0xeca1d7c7,
|
||||
0x041afa32, 0x1d16625a, 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031,
|
||||
0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, 0x026a4ceb, 0x52437eff,
|
||||
0x2f8f76b4, 0x0df980a5, 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df,
|
||||
0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, 0x1741a254, 0xe5b6a035,
|
||||
0x213d42f6, 0x2c1c7c26, 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69,
|
||||
0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, 0x63315c21, 0x5e0a72ec,
|
||||
0x49bafefd, 0x187908d9, 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7,
|
||||
0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, 0x71eae2a1, 0x1f9af36e,
|
||||
0xcfcbd12f, 0xc1de8417, 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3,
|
||||
0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, 0x6f7de532, 0x58fd7eb6,
|
||||
0xd01ee900, 0x24adffc2, 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2,
|
||||
0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, 0x29908415, 0x7fbb977f,
|
||||
0xaf9eb3db, 0x29c9ed2a, 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091,
|
||||
0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, 0x77079103, 0xdea03af6,
|
||||
0x78a8565e, 0xdee356df, 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef,
|
||||
0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, 0xafe67afb, 0xf470c4b2,
|
||||
0xf3e0eb5b, 0xd6cc9876, 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367,
|
||||
0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, 0xb5676e69, 0x9bd3ddda,
|
||||
0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
|
||||
0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6,
|
||||
0xb657c34d, 0x4edfd282, 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e,
|
||||
0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2};
|
||||
|
||||
static const unsigned long S5[256] = {
|
||||
0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5,
|
||||
0x44dd9d44, 0x1731167f, 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00,
|
||||
0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, 0xe6a2e77f, 0xf0c720cd,
|
||||
0xc4494816, 0xccf5c180, 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff,
|
||||
0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, 0x4e40b48d, 0x248eb6fb,
|
||||
0x8dba1cfe, 0x41a99b02, 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725,
|
||||
0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, 0xf2f3f763, 0x68af8040,
|
||||
0xed0c9e56, 0x11b4958b, 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7,
|
||||
0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, 0x0c05372a, 0x578535f2,
|
||||
0x2261be02, 0xd642a0c9, 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec,
|
||||
0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, 0x5c1ff900, 0xfe38d399,
|
||||
0x0c4eff0b, 0x062407ea, 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774,
|
||||
0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, 0xdf65001f, 0x0ec50966,
|
||||
0xdfdd55bc, 0x29de0655, 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468,
|
||||
0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, 0xbcf3f0aa, 0x87ac36e9,
|
||||
0xe53a7426, 0x01b3d82b, 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910,
|
||||
0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, 0x636737b6, 0x50f5b616,
|
||||
0xf24766e3, 0x8eca36c1, 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4,
|
||||
0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, 0x26e46695, 0xb7566419,
|
||||
0xf654efc5, 0xd08d58b7, 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049,
|
||||
0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, 0xc62bf3cd, 0x9e0885f9,
|
||||
0x68cb3e47, 0x086c010f, 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6,
|
||||
0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, 0x0ab378d5, 0xd951fb0c,
|
||||
0xded7da56, 0x4124bbe4, 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be,
|
||||
0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, 0xc3dc0280, 0x05687715,
|
||||
0x646c6bd7, 0x44904db3, 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6,
|
||||
0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, 0x76f0ae02, 0x083be84d,
|
||||
0x28421c9a, 0x44489406, 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4,
|
||||
0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, 0x3ca5d717, 0x7d161bba,
|
||||
0x9cad9010, 0xaf462ba2, 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487,
|
||||
0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, 0x445f7382, 0x175683f4,
|
||||
0xcdc66a97, 0x70be0288, 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5,
|
||||
0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, 0x1c5c1572, 0xf6721b2c,
|
||||
0x1ad2fff3, 0x8c25404e, 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78,
|
||||
0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, 0x44094f85, 0x3f481d87,
|
||||
0xfcfeae7b, 0x77b5ff76, 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801,
|
||||
0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, 0xdf3b0874, 0x95055110,
|
||||
0x1b5ad7a8, 0xf61ed5ad, 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58,
|
||||
0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, 0x5ce96c28, 0xe176eda3,
|
||||
0x6bac307f, 0x376829d2, 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20,
|
||||
0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, 0xf9e0659a, 0xeeb9491d,
|
||||
0x34010718, 0xbb30cab8, 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55,
|
||||
0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4};
|
||||
|
||||
static const unsigned long S6[256] = {
|
||||
0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, 0x95db08e7, 0x016843b4,
|
||||
0xeced5cbc, 0x325553ac, 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9,
|
||||
0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, 0x33f14961, 0xc01937bd,
|
||||
0xf506c6da, 0xe4625e7e, 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367,
|
||||
0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, 0xa084db2d, 0x09a8486f,
|
||||
0xa888614a, 0x2900af98, 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c,
|
||||
0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, 0xfd41197e, 0x9305a6b0,
|
||||
0xe86be3da, 0x74bed3cd, 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3,
|
||||
0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, 0x5c3d9c01, 0x64bdb941,
|
||||
0x2c0e636a, 0xba7dd9cd, 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d,
|
||||
0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, 0x284caf89, 0xaa928223,
|
||||
0x9334be53, 0x3b3a21bf, 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9,
|
||||
0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, 0x5b7c5ecc, 0x221db3a6,
|
||||
0x9a69a02f, 0x68818a54, 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a,
|
||||
0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, 0x53bddb65, 0xe76ffbe7,
|
||||
0xe967fd78, 0x0ba93563, 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc,
|
||||
0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, 0xe81f994f, 0x9528cd89,
|
||||
0xfd339fed, 0xb87834bf, 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be,
|
||||
0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, 0x4ec75b95, 0x24f2c3c0,
|
||||
0x42d15d99, 0xcd0d7fa0, 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f,
|
||||
0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, 0x372b74af, 0x692573e4,
|
||||
0xe9a9d848, 0xf3160289, 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853,
|
||||
0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, 0x36f73523, 0x4cfb6e87,
|
||||
0x7da4cec0, 0x6c152daa, 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f,
|
||||
0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, 0x2b05d08d, 0x48b9d585,
|
||||
0xdc049441, 0xc8098f9b, 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751,
|
||||
0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, 0xbf32679d, 0xd45b5b75,
|
||||
0xb353fd00, 0xcbb0e358, 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13,
|
||||
0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, 0x47cf8e7a, 0xb6c85283,
|
||||
0x3cc2acfb, 0x3fc06976, 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459,
|
||||
0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, 0x3007cd3e, 0x74719eef,
|
||||
0xdc872681, 0x073340d4, 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891,
|
||||
0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, 0x6fe4ac98, 0xb173ecc0,
|
||||
0xbc60b42a, 0x953498da, 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb,
|
||||
0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, 0xe8816f4a, 0x3814f200,
|
||||
0xa3f94043, 0x9c7a54c2, 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084,
|
||||
0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, 0xba5ac7b5, 0xb6f6deaf,
|
||||
0x3a479c3a, 0x5302da25, 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b,
|
||||
0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, 0xb81a928a, 0x60ed5869,
|
||||
0x97c55b96, 0xeaec991b, 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5,
|
||||
0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, 0xd36b4cf1, 0xf544edeb,
|
||||
0xb0e93524, 0xbebb8fbd, 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454,
|
||||
0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f};
|
||||
|
||||
static const unsigned long S7[256] = {
|
||||
0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, 0x2a8d7f6f, 0xab9bc912,
|
||||
0xde6008a1, 0x2028da1f, 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82,
|
||||
0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, 0xa05fbcf6, 0xcd4181e9,
|
||||
0xe150210c, 0xe24ef1bd, 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43,
|
||||
0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, 0x089766be, 0xbaeeadf4,
|
||||
0x1286becf, 0xb6eacb19, 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9,
|
||||
0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, 0x107789be, 0xb3b2e9ce,
|
||||
0x0502aa8f, 0x0bc0351e, 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516,
|
||||
0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, 0x334266ce, 0x8c9341b7,
|
||||
0xd0d854c0, 0xcb3a6c88, 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e,
|
||||
0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, 0x0a961288, 0xe1a5c06e,
|
||||
0x13749e67, 0x72fc081a, 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756,
|
||||
0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, 0xbc8ec511, 0x38bc46e9,
|
||||
0xc6e6fa14, 0xbae8584a, 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b,
|
||||
0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, 0x92544a8b, 0x009b4fc3,
|
||||
0xaba68ced, 0x9ac96f78, 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688,
|
||||
0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, 0xf7debb85, 0x61fe033c,
|
||||
0x16746233, 0x3c034c28, 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802,
|
||||
0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, 0x0c4fb99a, 0xbb325778,
|
||||
0x3ec6d97b, 0x6e77a6a9, 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7,
|
||||
0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, 0xb96d8c32, 0xebd4e7be,
|
||||
0xbe8b9d2d, 0x7979fb06, 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858,
|
||||
0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, 0xf28ebfb0, 0xf5b9c310,
|
||||
0xa0eac280, 0x08b9767a, 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a,
|
||||
0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, 0x826d2bef, 0x4eeb8476,
|
||||
0x488dcf25, 0x36c9d566, 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df,
|
||||
0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, 0xf22b017d, 0xa4173f70,
|
||||
0xdd1e16c3, 0x15e0d7f9, 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962,
|
||||
0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, 0x93d29a22, 0xe32dbf9a,
|
||||
0x058745b9, 0x3453dc1e, 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07,
|
||||
0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, 0x66626c1c, 0x7154c24c,
|
||||
0xea082b2a, 0x93eb2939, 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c,
|
||||
0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, 0xd3a0c108, 0xa1e7160e,
|
||||
0xe4f2dfa6, 0x693ed285, 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378,
|
||||
0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, 0xc79f022f, 0x3c997e7e,
|
||||
0x5e4f9504, 0x3ffafbbd, 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be,
|
||||
0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, 0x5592a33d, 0xb5229301,
|
||||
0xcfd2a87f, 0x60aeb767, 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2,
|
||||
0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, 0x97fd61a9, 0xea7759f4,
|
||||
0x2d57539d, 0x569a58cf, 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914,
|
||||
0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, 0x3ffa50bc, 0x3d40f021,
|
||||
0xc3c0bdae, 0x4958c24c, 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada,
|
||||
0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3};
|
||||
|
||||
static const unsigned long S8[256] = {
|
||||
0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, 0x7789f8b7, 0xe6c1121b,
|
||||
0x0e241600, 0x052ce8b5, 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174,
|
||||
0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, 0xde9adeb1, 0x0a0cc32c,
|
||||
0xbe197029, 0x84a00940, 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd,
|
||||
0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, 0xc7ece831, 0x3f8f95e7,
|
||||
0x72df191b, 0x7580330d, 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164,
|
||||
0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, 0x12a8ddec, 0xfdaa335d,
|
||||
0x176f43e8, 0x71fb46d4, 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862,
|
||||
0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, 0x4cfde06f, 0xc28ec4b8,
|
||||
0x57e8726e, 0x647a78fc, 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6,
|
||||
0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, 0xbbd35049, 0x2998df04,
|
||||
0x980cf42a, 0x9b6df491, 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e,
|
||||
0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, 0x3cf1d2e2, 0x19b47a38,
|
||||
0x424f7618, 0x35856039, 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8,
|
||||
0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, 0x7170c608, 0x2d5e3354,
|
||||
0xd4de495a, 0x64c6d006, 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42,
|
||||
0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, 0xf8d7e54e, 0x3e378160,
|
||||
0x7895cda5, 0x859c15a5, 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab,
|
||||
0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, 0x835ffcb8, 0x6df4c1f2,
|
||||
0x96f5b195, 0xfd0af0fc, 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225,
|
||||
0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, 0xc4618187, 0xea7a6e98,
|
||||
0x7cd16efc, 0x1436876c, 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441,
|
||||
0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, 0xa842eedf, 0xfdba60b4,
|
||||
0xf1907b75, 0x20e3030f, 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054,
|
||||
0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, 0xf1e47d8d, 0x844a1be5,
|
||||
0xbae7dfdc, 0x42cbda70, 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c,
|
||||
0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, 0x77853b53, 0x37effcb5,
|
||||
0xc5068778, 0xe580b3e6, 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c,
|
||||
0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, 0xdd06caa2, 0x37df932b,
|
||||
0xc4248289, 0xacf3ebc3, 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4,
|
||||
0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, 0xe87b40e4, 0xe98ea084,
|
||||
0x5889e9e1, 0xefd390fc, 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101,
|
||||
0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, 0x646f1282, 0x7523d24a,
|
||||
0xe0779695, 0xf9c17a8f, 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf,
|
||||
0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, 0x11403092, 0x00da6d77,
|
||||
0x4a0cdd61, 0xad1f4603, 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a,
|
||||
0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, 0x2de705ca, 0x8951570f,
|
||||
0xdf09822b, 0xbd691a6c, 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819,
|
||||
0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, 0x5938fa0f, 0x42399ef3,
|
||||
0x36997b07, 0x0e84093d, 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c,
|
||||
0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, 0x589e8d82, 0x0d2059d1,
|
||||
0xa466bb1e, 0xf8da0a82, 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d,
|
||||
0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e};
|
||||
|
||||
/* returns the i'th byte of a variable */
|
||||
#define GB(x, i) (((x[(15-i)>>2])>>(8*((15-i)&3)))&255)
|
||||
|
||||
int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
{
|
||||
unsigned long x[4], z[4];
|
||||
unsigned char buf[16];
|
||||
int y, i;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if (num_rounds != 12 && num_rounds != 16 && num_rounds != 0) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (num_rounds == 12 && keylen > 10) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (keylen < 5 || keylen > 16) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
/* extend the key as required */
|
||||
zeromem(buf, sizeof(buf));
|
||||
memcpy(buf, key, keylen);
|
||||
|
||||
/* load and start the awful looking network */
|
||||
for (y = 0; y < 4; y++) {
|
||||
LOAD32H(x[3-y],buf+4*y);
|
||||
}
|
||||
|
||||
for (i = y = 0; y < 2; y++) {
|
||||
z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)];
|
||||
z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)];
|
||||
z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)];
|
||||
z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0x8)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0x7)] ^ S8[GB(z, 0x6)] ^ S5[GB(z, 0x2)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0xA)] ^ S6[GB(z, 0xB)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S6[GB(z, 0x6)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0xC)] ^ S6[GB(z, 0xd)] ^ S7[GB(z, 0x3)] ^ S8[GB(z, 0x2)] ^ S7[GB(z, 0x9)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0xE)] ^ S6[GB(z, 0xF)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x0)] ^ S8[GB(z, 0xc)];
|
||||
|
||||
x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)];
|
||||
x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)];
|
||||
x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)];
|
||||
x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0x3)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0xc)] ^ S8[GB(x, 0xd)] ^ S5[GB(x, 0x8)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0x1)] ^ S6[GB(x, 0x0)] ^ S7[GB(x, 0xe)] ^ S8[GB(x, 0xf)] ^ S6[GB(x, 0xd)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x8)] ^ S8[GB(x, 0x9)] ^ S7[GB(x, 0x3)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0x5)] ^ S6[GB(x, 0x4)] ^ S7[GB(x, 0xa)] ^ S8[GB(x, 0xb)] ^ S8[GB(x, 0x7)];
|
||||
|
||||
/* second half */
|
||||
|
||||
z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)];
|
||||
z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)];
|
||||
z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)];
|
||||
z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0x3)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0xc)] ^ S8[GB(z, 0xd)] ^ S5[GB(z, 0x9)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0x1)] ^ S6[GB(z, 0x0)] ^ S7[GB(z, 0xe)] ^ S8[GB(z, 0xf)] ^ S6[GB(z, 0xc)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x8)] ^ S8[GB(z, 0x9)] ^ S7[GB(z, 0x2)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0x5)] ^ S6[GB(z, 0x4)] ^ S7[GB(z, 0xa)] ^ S8[GB(z, 0xb)] ^ S8[GB(z, 0x6)];
|
||||
|
||||
x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)];
|
||||
x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)];
|
||||
x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)];
|
||||
x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0x8)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0x7)] ^ S8[GB(x, 0x6)] ^ S5[GB(x, 0x3)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0xa)] ^ S6[GB(x, 0xb)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S6[GB(x, 0x7)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0xc)] ^ S6[GB(x, 0xd)] ^ S7[GB(x, 0x3)] ^ S8[GB(x, 0x2)] ^ S7[GB(x, 0x8)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0xe)] ^ S6[GB(x, 0xf)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x0)] ^ S8[GB(x, 0xd)];
|
||||
}
|
||||
|
||||
skey->cast5.keylen = keylen;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
zeromem(x, sizeof(x));
|
||||
zeromem(z, sizeof(z));
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
static unsigned long FI(unsigned long R, unsigned long Km, unsigned long Kr)
|
||||
{
|
||||
unsigned long I;
|
||||
I = (Km + R);
|
||||
I = ROL(I, Kr);
|
||||
return ((S1[(I>>24)&255] ^ S2[(I>>16)&255]) - S3[(I>>8)&255]) + S4[I&255];
|
||||
}
|
||||
|
||||
static unsigned long FII(unsigned long R, unsigned long Km, unsigned long Kr)
|
||||
{
|
||||
unsigned long I;
|
||||
I = (Km ^ R);
|
||||
I = ROL(I, Kr);
|
||||
return ((S1[(I>>24)&255] - S2[(I>>16)&255]) + S3[(I>>8)&255]) ^ S4[I&255];
|
||||
}
|
||||
|
||||
static unsigned long FIII(unsigned long R, unsigned long Km, unsigned long Kr)
|
||||
{
|
||||
unsigned long I;
|
||||
I = (Km - R);
|
||||
I = ROL(I, Kr);
|
||||
return ((S1[(I>>24)&255] + S2[(I>>16)&255]) ^ S3[(I>>8)&255]) - S4[I&255];
|
||||
}
|
||||
|
||||
void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
{
|
||||
unsigned long R, L;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
LOAD32H(L,&pt[0]);
|
||||
LOAD32H(R,&pt[4]);
|
||||
|
||||
L ^= FI(R, key->cast5.K[0], key->cast5.K[16]);
|
||||
R ^= FII(L, key->cast5.K[1], key->cast5.K[17]);
|
||||
L ^= FIII(R, key->cast5.K[2], key->cast5.K[18]);
|
||||
R ^= FI(L, key->cast5.K[3], key->cast5.K[19]);
|
||||
L ^= FII(R, key->cast5.K[4], key->cast5.K[20]);
|
||||
R ^= FIII(L, key->cast5.K[5], key->cast5.K[21]);
|
||||
L ^= FI(R, key->cast5.K[6], key->cast5.K[22]);
|
||||
R ^= FII(L, key->cast5.K[7], key->cast5.K[23]);
|
||||
L ^= FIII(R, key->cast5.K[8], key->cast5.K[24]);
|
||||
R ^= FI(L, key->cast5.K[9], key->cast5.K[25]);
|
||||
L ^= FII(R, key->cast5.K[10], key->cast5.K[26]);
|
||||
R ^= FIII(L, key->cast5.K[11], key->cast5.K[27]);
|
||||
if (key->cast5.keylen > 10) {
|
||||
L ^= FI(R, key->cast5.K[12], key->cast5.K[28]);
|
||||
R ^= FII(L, key->cast5.K[13], key->cast5.K[29]);
|
||||
L ^= FIII(R, key->cast5.K[14], key->cast5.K[30]);
|
||||
R ^= FI(L, key->cast5.K[15], key->cast5.K[31]);
|
||||
}
|
||||
STORE32H(R,&ct[0]);
|
||||
STORE32H(L,&ct[4]);
|
||||
}
|
||||
|
||||
void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
{
|
||||
unsigned long R, L;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
LOAD32H(R,&ct[0]);
|
||||
LOAD32H(L,&ct[4]);
|
||||
|
||||
if (key->cast5.keylen > 10) {
|
||||
R ^= FI(L, key->cast5.K[15], key->cast5.K[31]);
|
||||
L ^= FIII(R, key->cast5.K[14], key->cast5.K[30]);
|
||||
R ^= FII(L, key->cast5.K[13], key->cast5.K[29]);
|
||||
L ^= FI(R, key->cast5.K[12], key->cast5.K[28]);
|
||||
}
|
||||
|
||||
R ^= FIII(L, key->cast5.K[11], key->cast5.K[27]);
|
||||
L ^= FII(R, key->cast5.K[10], key->cast5.K[26]);
|
||||
R ^= FI(L, key->cast5.K[9], key->cast5.K[25]);
|
||||
L ^= FIII(R, key->cast5.K[8], key->cast5.K[24]);
|
||||
R ^= FII(L, key->cast5.K[7], key->cast5.K[23]);
|
||||
L ^= FI(R, key->cast5.K[6], key->cast5.K[22]);
|
||||
R ^= FIII(L, key->cast5.K[5], key->cast5.K[21]);
|
||||
L ^= FII(R, key->cast5.K[4], key->cast5.K[20]);
|
||||
R ^= FI(L, key->cast5.K[3], key->cast5.K[19]);
|
||||
L ^= FIII(R, key->cast5.K[2], key->cast5.K[18]);
|
||||
R ^= FII(L, key->cast5.K[1], key->cast5.K[17]);
|
||||
L ^= FI(R, key->cast5.K[0], key->cast5.K[16]);
|
||||
|
||||
STORE32H(L,&pt[0]);
|
||||
STORE32H(R,&pt[4]);
|
||||
}
|
||||
|
||||
int cast5_test(void)
|
||||
{
|
||||
static const struct {
|
||||
int keylen;
|
||||
unsigned char key[16];
|
||||
unsigned char pt[8];
|
||||
unsigned char ct[8];
|
||||
} tests[] = {
|
||||
{ 16,
|
||||
{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A},
|
||||
{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2}
|
||||
},
|
||||
{ 10,
|
||||
{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45},
|
||||
{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B},
|
||||
},
|
||||
{ 5,
|
||||
{0x01, 0x23, 0x45, 0x67, 0x12},
|
||||
{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E}
|
||||
}
|
||||
};
|
||||
int i, errno;
|
||||
symmetric_key key;
|
||||
unsigned char buf[8], buf2[8];
|
||||
|
||||
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
|
||||
if ((errno = cast5_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
cast5_ecb_encrypt(tests[i].pt, buf, &key);
|
||||
if (memcmp(buf, tests[i].ct, 8)) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("\n\n\nFailed encrypt test: %d\n", i);
|
||||
for (j = 0; j < 8; j++) printf("%02x ", buf[j]);
|
||||
printf("\n");
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
cast5_ecb_decrypt(buf, buf2, &key);
|
||||
if (memcmp(buf2, tests[i].pt, 8)) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("\n\n\nFailed decrypt test: %d\n", i);
|
||||
for (j = 0; j < 8; j++) printf("%02x ", buf2[j]);
|
||||
printf("\n");
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int cast5_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
if (*desired_keysize < 5) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
} else if (*desired_keysize > 16) {
|
||||
*desired_keysize = 16;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
101
cbc.c
Normal file
101
cbc.c
Normal file
@ -0,0 +1,101 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef CBC
|
||||
|
||||
int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_CBC *cbc)
|
||||
{
|
||||
int x, errno;
|
||||
|
||||
_ARGCHK(IV != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(cbc != NULL);
|
||||
|
||||
/* bad param? */
|
||||
if ((errno = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* setup cipher */
|
||||
if ((errno = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* copy IV */
|
||||
cbc->blocklen = cipher_descriptor[cipher].block_length;
|
||||
cbc->cipher = cipher;
|
||||
for (x = 0; x < cbc->blocklen; x++) {
|
||||
cbc->IV[x] = IV[x];
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc)
|
||||
{
|
||||
int x, errno;
|
||||
unsigned char tmp[MAXBLOCKSIZE];
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(cbc != NULL);
|
||||
|
||||
if ((errno = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* xor IV against plaintext */
|
||||
for (x = 0; x < cbc->blocklen; x++) {
|
||||
tmp[x] = pt[x] ^ cbc->IV[x];
|
||||
}
|
||||
|
||||
/* encrypt */
|
||||
cipher_descriptor[cbc->cipher].ecb_encrypt(tmp, ct, &cbc->key);
|
||||
|
||||
/* store IV [ciphertext] for a future block */
|
||||
for (x = 0; x < cbc->blocklen; x++) {
|
||||
cbc->IV[x] = ct[x];
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(tmp, sizeof(tmp));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc)
|
||||
{
|
||||
int x, errno;
|
||||
unsigned char tmp[MAXBLOCKSIZE], tmp2[MAXBLOCKSIZE];
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(cbc != NULL);
|
||||
|
||||
/* decrypt the block from ct into tmp */
|
||||
if ((errno = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
|
||||
|
||||
/* xor IV against the plaintext of the previous step */
|
||||
for (x = 0; x < cbc->blocklen; x++) {
|
||||
/* copy CT in case ct == pt */
|
||||
tmp2[x] = ct[x];
|
||||
|
||||
/* actually decrypt the byte */
|
||||
pt[x] = tmp[x] ^ cbc->IV[x];
|
||||
}
|
||||
|
||||
/* replace IV with this current ciphertext */
|
||||
for (x = 0; x < cbc->blocklen; x++) {
|
||||
cbc->IV[x] = tmp2[x];
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(tmp, sizeof(tmp));
|
||||
zeromem(tmp2, sizeof(tmp2));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
86
cfb.c
Normal file
86
cfb.c
Normal file
@ -0,0 +1,86 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef CFB
|
||||
|
||||
int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_CFB *cfb)
|
||||
{
|
||||
int x, errno;
|
||||
|
||||
_ARGCHK(IV != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(cfb != NULL);
|
||||
|
||||
if ((errno = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* copy data */
|
||||
cfb->cipher = cipher;
|
||||
cfb->blocklen = cipher_descriptor[cipher].block_length;
|
||||
for (x = 0; x < cfb->blocklen; x++)
|
||||
cfb->IV[x] = IV[x];
|
||||
|
||||
/* init the cipher */
|
||||
if ((errno = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* encrypt the IV */
|
||||
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
|
||||
cfb->padlen = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb)
|
||||
{
|
||||
int errno;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(cfb != NULL);
|
||||
|
||||
if ((errno = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
while (len--) {
|
||||
if (cfb->padlen == cfb->blocklen) {
|
||||
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
|
||||
cfb->padlen = 0;
|
||||
}
|
||||
cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);
|
||||
++pt;
|
||||
++ct;
|
||||
++cfb->padlen;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb)
|
||||
{
|
||||
int errno;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(cfb != NULL);
|
||||
|
||||
if ((errno = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
while (len--) {
|
||||
if (cfb->padlen == cfb->blocklen) {
|
||||
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
|
||||
cfb->padlen = 0;
|
||||
}
|
||||
cfb->pad[cfb->padlen] = *ct;
|
||||
*pt = *ct ^ cfb->IV[cfb->padlen];
|
||||
++pt;
|
||||
++ct;
|
||||
++cfb->padlen;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
622
changes
Normal file
622
changes
Normal file
@ -0,0 +1,622 @@
|
||||
Nov 24th, 2002
|
||||
v0.75 -- Fixed a flaw in hash_filehandle, it should ARGCHK that the filehandle is not NULL
|
||||
-- Fixed a bug where in hash_file if the call to hash_filehandle failed the open file would
|
||||
not be closed.
|
||||
-- Added more strict rules to build process, starting to weed out "oh this works in GCC" style code
|
||||
In the next release "-Wconversion" will be enabled which will deal with all implicit casts.
|
||||
|
||||
Nov 22nd, 2002 [later in the day]
|
||||
v0.74 -- Wrote a small variant of SAFER+ which shaved 50KB off the size of the library on x86 platforms
|
||||
-- Wrote a build option to remove the PK packet functions [keeps the encrypt_key/sign_hash functions]
|
||||
-- Wrote a small variant of Rijndael (trimmed 13KB)
|
||||
-- Trimmed the TIGER/192 hash function a bit
|
||||
-- Overall the entire lib compiled is 295KB [down from 400KB before]
|
||||
-- Fixed a few minor oversights in the MSVC makefile
|
||||
|
||||
Nov 22nd, 2002
|
||||
v0.73 -- Fixed bug in RC4 code where it could only use 255 byte keys.
|
||||
-- Fixed bug in yarrow code where it would allow cast5 or md2 to be used with it...
|
||||
-- Removed the ecc compress/expand points from the global scope. Reduces namespace polution
|
||||
-- Fixed bug where if you used the SPRNG you couldn't pass NULL as your prng_state which you should be
|
||||
able todo since the SPRNG has no state...
|
||||
-- Corrected some oversights in the manual and the examples...
|
||||
-- By default the GF(2^W) math library is excluded from the build. The source is maintained because I wrote it
|
||||
and like it :-). This way the built library is a tad smaller
|
||||
-- the MSVC makefile will now build for a SPACE optimized library rather than TIME optimized.
|
||||
|
||||
Nov 21th, 2002
|
||||
v0.72 -- Fixed bug in the prime testing. In the Miller-Rabin test I was raising the base to "N-1" not "r".
|
||||
The math still worked out fine because in effect it was performing a Fermat test. Tested the new code and it
|
||||
works properly
|
||||
-- Fixed some of the code where it was still using the old error syntax
|
||||
-- Sped up the RSA decrypt/sign routines
|
||||
-- Optimized the ecc_shared_secret routine to not use so much stack
|
||||
-- Fixed up the makefile to make releases where the version # is in the file name and directory it will unzip
|
||||
to
|
||||
|
||||
Nov 19th, 2002
|
||||
v0.71 -- HELP TOM. I need tuition for the January semester. Now I don't want to force donations [nor will I ever]
|
||||
but I really need the help! See my website http://tom.iahu.ca/help_tom.html for more details. Please help
|
||||
if you can!
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- Officially the library is no longer supported in GCC 3.2 in windows [cygwin].
|
||||
In windows you can either use GCC 2.95.3 or try your luck with 3.2 It seems that
|
||||
"-fomit-frame-pointer" is broken in the windows build [but not the linux x86 build???]
|
||||
If you simply must use 3.2 then I suggest you limit the optimizations to simply "-O2"
|
||||
-- Started new error handling API. Similar to the previous except there are more error codes than just
|
||||
CRYPT_ERROR
|
||||
-- Added my implementation of the MD2 hash function [despite the errors in the RFC I managed to get it right!]
|
||||
-- Merged in more changes from Sky Schulz. I have to make mention here that he has been a tremendous help in
|
||||
getting me motivated to make some much needed updates to the library!
|
||||
-- Fixed one of the many mistakes in the manual as pointed out by Daniel Richards
|
||||
-- Fixed a bug in the RC4 code [wasn't setting up the key correctly]
|
||||
-- Added my implementation of the CAST5 [aka CAST-128] block cipher (conforms...)
|
||||
-- Fixed numerous bugs in the PK code. Essentially I was "freeing" keys when the import failed. This is neither
|
||||
required nor a good a idea [double free].
|
||||
-- Tom needs a job.
|
||||
-- Fixed up the test harness as requested by Sky Schulz. Also modifed the timing routines to run for X seconds
|
||||
and count # of ops performed. This is more suitable than say encrypting 10 million blocks on a slow processor
|
||||
where it could take minutes!
|
||||
-- Modified test programs hashsum/encrypt to use the new algorithms and error handling syntax
|
||||
-- Removed the PKCS code since it was incomplete. In the future I plan on writing a "add-on" library that
|
||||
provides PKCS support...
|
||||
-- updated the config system so the #defines are in the makefiles instead of mycrypt_cfg.h
|
||||
-- Willing to work on an hourly basis for 15$ CDN per hour.
|
||||
-- updated the test program to not test ciphers not included
|
||||
-- updated the makefile to make "rsa_sys.c" a dependency of rsa.o [helps develop the code...]
|
||||
-- fixed numerous failures to detect buffer overflows [minor] in the PK code.
|
||||
-- fixed the safer [64-bit block version] test routines which didn't check the returns of the setup
|
||||
function
|
||||
-- check out my CV at http://tom.iahu.ca/cv.html
|
||||
-- removed the GBA makefile and code from demos/test.c [not a particularly useful demo...]
|
||||
-- merged in rudimentary [for testing] PS2 RNG from Sky Schulz
|
||||
-- merged in PS2 timer code [only shell included due to NDA reasons...]
|
||||
-- updated HMAC code to return errors where possible
|
||||
-- Thanks go to Sky Schulz who bought me a RegCode for TextPad [the official editor of libtomcrypt]
|
||||
|
||||
Nov 12th, 2002
|
||||
v0.70 -- Updated so you can swap out the default malloc/calloc/free routines at build time with others. (Sky Schulz)
|
||||
-- Sky Schulz contributed some code towards autodetecting the PS2 in mycrypt_cfg.h
|
||||
-- Added PS2 makefile contributed by Sky Schulz [see a pattern forming?]
|
||||
-- Added ability to have no FILE I/O functions at all (see makefile), Sky Schulz....
|
||||
-- Added support for substituting out the clock() function (Sky Schulz)
|
||||
-- Fixed up makefile to include new headers in the HEADERS variable
|
||||
-- Removed "coin.c" as its not really useful anyways
|
||||
-- Removed many "debug" printfs that would show up on failures. Basically I wanted to ensure the only output
|
||||
would be from the developer themselves.
|
||||
-- Added "rc4.c" a RC4 implementation with a PRNG interface. Since RC4 isn't a block cipher it wouldn't work
|
||||
too well as a block cipher.
|
||||
-- Fixed ARGCHK macro usage when ARGTYPE=1 throughout the code
|
||||
-- updated makefile to make subdirectory properly (Sku Schulz)
|
||||
-- Started towards new API setup. Instead of checking for "== CRYPT_ERROR" you should check "!= CRYPT_OK"
|
||||
In future releases functions will return things other than CRYPT_ERROR on error to give more useful
|
||||
thread safe error reporting. The manual will be updated to reflect this. For this release all
|
||||
errors are returned as CRYPT_ERROR (except as noted) but in future releases this will change.
|
||||
-- Removed the zlib branch since its not really required anyways. Makes the package smaller
|
||||
|
||||
Nov 11th, 2002
|
||||
v0.69 -- Added ARGCHK (see mycrypt_argchk.h) "arguement checking" to all functions that accept pointers
|
||||
-- Note I forgot to change the CRYPT version tag in v0.68... fixed now.
|
||||
|
||||
Nov 8th, 2002
|
||||
v0.68 -- Fixed flaw in kr_import/kr_export that wasted 4 bytes. Source but not binary compatible with v0.67
|
||||
-- Fixed bug in kr_find_name that used memcmp to match strings. Uses strncmp now.
|
||||
-- kr_clear now sets the pointer to NULL to facilate debugging [e.g. using the keyring after clearing]
|
||||
-- static functions in _write/_read in keyring.c now check the return of ctr_encrypt/ctr_decrypt.
|
||||
-- Updated blowfish/rc2/rc5/rc6 keysize() function to not reject keys larger than the biggest key the
|
||||
respective ciphers can use.
|
||||
-- Fixed a bug in hashsum demo that would report the hash for files that don't exist!
|
||||
|
||||
Oct 16th, 2002
|
||||
v0.67 -- Moved the function prototypes into files mycrypt_*.h. To "install" the lib just copy all the
|
||||
header files "*.h" from the base of this project into your global include path.
|
||||
-- Made the OFB/CFB/CTR functions use "unsigned long" for the length instead of "int"
|
||||
-- Added keyring support for the PK functions
|
||||
-- ***API CHANGE*** changed the ecc_make_key and dh_make_key to act more like rsa_make_key. Basically
|
||||
move the first argument to the next to last.
|
||||
-- Fixed bug in dh_test() that wouldn't test the primality of the order of the sub-group
|
||||
-- replaced the primes in the DH code with new ones that are larger than the size they are
|
||||
associated with. That is a 1024-bit DH key will have a 1025-bit prime as the modulus
|
||||
-- cleaned up all the PK code, changed a bit of the API around [not source compatible with v0.66]
|
||||
-- major editing of the manual, started Docer program
|
||||
-- added 160 and 224 bit key settings for ECC. This makes the DH and ECC binary wise incompatible with v0.66
|
||||
-- Added an additional check for memory errors in is_prime() and cleaned up prime.c a bit
|
||||
-- Removed ID_TAG from all files [meh, not a big fan...]
|
||||
-- Removed unused variable from yarrow state and made AES/SHA256 the default cipher/hash combo
|
||||
-- Fixed a bug in the Yarrow code that called prng_is_valid instead of cipher_is_valid from yarrow_start()
|
||||
-- The ECB/CBC/OFB/CFB/CTR wrappers now check that the cipher is valid in the encrypt/decrypt calls
|
||||
Returns int now instead of void.
|
||||
|
||||
Sept 24th, 2002
|
||||
v0.66 -- Updated the /demos/test.c program to time the hashes correctly. Also it uses the yarrow PRNG for all of the
|
||||
tests meaning its possible to run on RNG less platforms
|
||||
-- Updated the /demos/hashsum.c program to hash from the standard input
|
||||
-- Updated the RSA code to make keys a bit quicker [update by Wayne Scott] by not making both primes at the same
|
||||
time.
|
||||
-- Dan Kaminsky suggested some cleanups for the code and the MPI config
|
||||
Code ships in unix LF format by default now too... will still build in MSVC and all... but if you want
|
||||
to read the stuff you'll have to convert it
|
||||
-- Changes to the manual to reflect new API [e.g. hash_memory/file have v0.65 prototypes]and some typos fixed
|
||||
|
||||
Sept 20th, 2002
|
||||
v0.65 -- Wayne Scott (wscott@bitmover.com) made a few of suggestions to improve the library. Most
|
||||
importantly he pointed out the math lib is not really required. He's also tested the lib on 18
|
||||
different platforms. According to him with only a few troubles [lack of /dev/random, etc] the
|
||||
library worked as it was supposed to. You can find the list at
|
||||
http://www.bitkeeper.com/Products.BitKeeper.Platforms.html
|
||||
-- Updated the hash_file and hash_memory functions to keep track of the size of the output
|
||||
-- Wayne Scott updated the demos/test.c file to use the SPRNG less and Yarrow more
|
||||
-- Modified the mycrypt_cfg.h to autodetect x86-32 machines
|
||||
|
||||
Sept 19th, 2002
|
||||
v0.64 -- wrote makefile for the GBA device [and hacked the demos/test.c file to support it conditionally]
|
||||
-- Fixed error in PK (e.g. ECC, RSA, DH) import functions where I was clobbering the packet error messages
|
||||
-- fixed more typos in the manual
|
||||
-- removed all unused variables from the core library (ignore the ID_TAG stuff)
|
||||
-- added "const char *crypt_build_settings" string which is a build time constant that gives a listing
|
||||
of all the build time options. Useful for debugging since you can send that to me and I will know what
|
||||
exactly you had set for the mycrypt_cfg.h file.
|
||||
-- Added control over endianess. Out of the box it defaults to endianess neutral but you can trivially
|
||||
configure the library for your platform. Using this I boosted RC5 from 660Mbit/sec to 785Mbit/sec on my
|
||||
Athlon box. See "mycrypt_cfg.h" for more information.
|
||||
|
||||
Sept 11th, 2002
|
||||
v0.63 -- Made hashsum demo output like the original md5sum program
|
||||
-- Made additions to the examples in the manual (fixed them up a bunch)
|
||||
-- Merged in the base64 code from Wayne Scott (wscott@bitmover.com)
|
||||
|
||||
Aug 29th, 2002
|
||||
v0.62 -- Added the CLEAN_STACK functionality to several of the hashes I forgot to update.
|
||||
|
||||
Aug 9th, 2002
|
||||
v0.61 -- Fixed a bug in the DES code [oops I read something wrong].
|
||||
|
||||
Aug 8th, 2002
|
||||
v0.60 -- Merged in DES code [and wrote 3DES-EDE code based on it] from Dobes V.
|
||||
|
||||
Aug 7th, 2002
|
||||
v0.59 -- Fixed a "unsigned long long" bug that caused v0.58 not to build in MSVC.
|
||||
-- Cleaned up a little in the makefile
|
||||
-- added code that times the hash functions too in the test program
|
||||
|
||||
Aug 3rd, 2002
|
||||
v0.58 -- Added more stack cleaning conditionals throughout the code.
|
||||
-- corrected some CLEAR_STACK conditionals... should have been CLEAN_STACK
|
||||
-- Simplified the RSA, DH and ECC encrypt() routines where they use CTR to encode the message
|
||||
now they only make one call to ctr_encrypt()/ctr_decrypt().
|
||||
|
||||
Aug 2nd, 2002
|
||||
v0.57 -- Fixed a few errors messages in the SAFER code to actually report the correct cipher name.
|
||||
-- rsa_encrypt() uses the "keysize()" method of the cipher being used to more accurately pick a
|
||||
key size. By default rsa_encrypt() will choose to use a 256-bit key but the cipher can turn that
|
||||
down if required.
|
||||
-- The rsa_exptmod() function will now more reliably detect invalid inputs (e.g. greater than the modulus).
|
||||
-- The padding method for RSA is more clearly documented. Namely if you want to encrypt/sign something of length
|
||||
N then your modulus must be of length 1+3N. So to sign a message with say SHA-384 [48 bytes] you need a
|
||||
145 byte (1160 bits) modulus. This is all in the manual now.
|
||||
-- Added build option CLEAN_STACK which will allow you to choose whether you want to clean the stack or not after every
|
||||
cipher/hash call
|
||||
-- Sped up the hash "process()" functions by not copying one byte at a time.
|
||||
++ (added just after I uploaded...)
|
||||
MD4 process() now handles input buffers > 64 bytes
|
||||
|
||||
Aug 1st, 2002
|
||||
v0.56 -- Cleaned up the comments in the Blowfish code.
|
||||
-- Oh yeah, in v0.55 I made all of the descriptor elements constant. I just forgot to mention it.
|
||||
-- fixed a couple of places where descriptor indexes were tested wrong. Not a huge bug but now its harder
|
||||
to mess up.
|
||||
-- Added the SAFER [64-bit block] ciphers K64, SK64, K128 and SK128 to the library.
|
||||
-- Added the RC2 block cipher to the library.
|
||||
-- Changed the SAFER define for the SAFER+ cipher to SAFERP so that the new SAFER [64-bit] ciphers
|
||||
can use them with less confusion.
|
||||
|
||||
July 29th, 2002
|
||||
v0.55 -- My god stupid Blowfish has yet again been fixed. I swear I hate that cipher. Next bug in it and boom its out of the
|
||||
library. Use AES or something else cuz I really hate Blowfish at this stage....
|
||||
-- Partial PKCS support [hint DONT USE IT YET CUZ ITS UNTESTED!]
|
||||
|
||||
July 19th, 2002
|
||||
v0.54 -- Blowfish now conforms to known test vectors. Silly bad coding tom!
|
||||
-- RC5/RC6/Serpent all have more test vectors now [and they seemed to have been working before]
|
||||
|
||||
July 18th, 2002
|
||||
v0.53 -- Added more test vectors to the blowfish code just for kicks [and they are const now too :-)]
|
||||
-- added prng/hash/cipher is_valid functions and used them in all of the PK code so you can't enter the code
|
||||
with an invalid index ever now.
|
||||
-- Simplified the Yarrow code once again :-)
|
||||
|
||||
July 12th, 2002
|
||||
v0.52 -- Fixed a bug in MD4 where the hash descriptor ID was the same as SHA-512. Now MD4 will work with
|
||||
all the routines...
|
||||
-- Fixed the comments in SHA-512 to be a bit more meaningful
|
||||
-- In md4 I made the PADDING array const [again to store it in ROM]
|
||||
-- in hash_file I switched the constant "512" to "sizeof(buf)" to be a bit safer
|
||||
-- in SHA-1's test routine I fixed the string literal to say SHA-1 not sha1
|
||||
-- Fixed a logical error in the CTR code which would make it skip the first IV value. This means
|
||||
the CTR code from v0.52 will be incompatible [binary wise] with previous releases but it makes more
|
||||
sense this way.
|
||||
-- Added {} braces for as many if/for/blocks of code I could find. My rule is that every for/if/while/do block
|
||||
must have {} braces around it.
|
||||
-- made the rounds table in saferp_setup const [again for the ROM think about the ROM!]
|
||||
-- fixed RC5 since it no longer requires rc5 to be registered in the lib. It used to since the descriptors used to
|
||||
be part of the table...
|
||||
-- the packet.c code now makes crypt_error literal string errors when an error occurs
|
||||
-- cleaned up the SAFER+ key schedule to be a bit easier to read.
|
||||
-- fixed a huge bug in Twofish with the TWOFISH_SMALL define. Because I clean the stack now I had
|
||||
changed the "g_func()" to be called indirectly. I forgot to actually return the return of the Twofish
|
||||
g_func() function which caused it not to work... [does now :-)]
|
||||
|
||||
July 11th, 2002
|
||||
v0.51 -- Fixed a bug in SHA512/384 code for multi-block messages.
|
||||
-- Added more test vectors to the SHA384/512 and TIGER hash functions
|
||||
-- cleaned up the hash done routines to make more sense
|
||||
|
||||
July 10th, 2002
|
||||
v0.50 -- Fixed yarrow.c so that the cipher/hash used would be registered. Also fixed
|
||||
a bug where the SAFER+ name was "safer" but should have been "safer+".
|
||||
-- Added an element to the hash descriptors that gives the size of a block [sent into the compressor]
|
||||
-- Cleaned up the support for HMAC's
|
||||
-- Cleaned up the test vector routines to make the test vector data const. This means on some platforms it will be
|
||||
placed in ROM not RAM now.
|
||||
-- Added MD4 code submited by Dobes Vandermeer (dobes@smartt.com)
|
||||
-- Added "burn_stack" function [idea taken from another source of crypto code]. The idea is if a function has
|
||||
alot of variables it will clean up better. Functions like the ecb serpent and twofish code will now have their
|
||||
stacks cleaned and the rest of the code is getting much more straightforward.
|
||||
-- Added a hashing demo by Daniel Richards (kyhwana@world-net.co.nz)
|
||||
-- I (Tom) modified some of the test vector routines to use more vectors ala Dobes style.
|
||||
For example, the MD5/SHA1 code now uses all of the test vectors from the RFC/FIPS spec.
|
||||
-- Fixed the register/unregister functions to properly report errors in crypt_error
|
||||
-- Correctly updated yarrow code to remove a few unused variables.
|
||||
-- Updated manual to fix a few erroneous examples.
|
||||
-- Added section on Hash based Message Authentication Codes (HMAC) to the manual
|
||||
|
||||
June 19th, 2002
|
||||
v0.46 -- Added in HMAC code from Dobes Vandermeer (dobes@smartt.com)
|
||||
|
||||
June 8th, 2002
|
||||
v0.45 -- Fixed bug in rc5.c where if you called rc5_setup() before registering RC5 it would cause
|
||||
undefined behaviour.
|
||||
-- Fixed mycrypt_cfg.h to eliminate the 224 bit ECC key.
|
||||
-- made the "default" makefile target have depends on mycrypt.h and mycrypt_cfg.h
|
||||
|
||||
Apr 4th, 2002
|
||||
v0.44 -- Fixed bug in ecc.c::new_point() where if the initial malloc fails it would not catch it.
|
||||
|
||||
Mar 22nd, 2002
|
||||
v0.43 -- Changed the ZLIB code over to the 1.1.4 code base to avoid the "double free" bug.
|
||||
-- Updated the GCC makefile not to use -O3 or -funroll-loops
|
||||
-- Version tag in mycrypt.h has been updated :-)
|
||||
|
||||
Mar 10th, 2002
|
||||
v0.42 -- The RNG code can now use /dev/urandom before trying /dev/random (J. Klapste)
|
||||
|
||||
Mar 3rd, 2002
|
||||
v0.41 -- Added support to link and use ciphers at compile time. This can greatly reduce the code size!
|
||||
-- Added a demo to show off how small an application can get... 46kb!
|
||||
-- Disastry pointed out that Blowfish is supposed to be high endian.
|
||||
-- Made registry code for the PRNGs as well [now the smallest useable link is 43kb]
|
||||
|
||||
Feb 11th, 2002
|
||||
v0.40 -- RSA signatures use [and check for] fixed padding scheme.
|
||||
-- I'm developing in Linux now :-)
|
||||
-- No more warnings from GCC 2.96
|
||||
|
||||
Feb 5th, 2002
|
||||
v0.39 -- Updated the XTEA code to work in accordance with the XTEA design
|
||||
|
||||
January 24th, 2002
|
||||
v0.38 -- CFB and OFB modes can now handle blocks of variable size like the CTR code
|
||||
-- Wrote a wrapper around the memory compress functions in Zlib that act like the functions
|
||||
in the rest of my crypto lib
|
||||
|
||||
January 23rd, 2002
|
||||
v0.37 -- Added support code so that if a hash size and key size for a cipher don't match up they will
|
||||
use the next lower key supported. (mainly for the PK code). So you can now use SHA-1 with
|
||||
Twofish, etc...
|
||||
-- Added more options for Twofish. You can now tell it to use precomputed sboxes and MDS multiplications
|
||||
This will speed up the TWOFISH_SMALL implementation by increasing the code size by 1024 bytes.
|
||||
-- Fixed a bug in prime.c that would not use the correct table if you undefined SMALL_PRIME_TAB
|
||||
-- Fixed all of the PK packet code to use the same header format [see packet.c]. This makes the PK code
|
||||
binary wise incompatible with previous releases while the API has not changed at all.
|
||||
|
||||
January 22nd, 2002
|
||||
v0.36 -- Corrections to the manual
|
||||
-- Made a modification to Twofish which lets you build a "small ram" variant. It requires
|
||||
about 190 bytes of ram for the key storage compared to the 4,200 bytes the normal
|
||||
variant requires.
|
||||
-- Reduced the stack space used in all of the PK routines.
|
||||
|
||||
January 19th, 2002
|
||||
v0.35 -- If you removed the first hash or cipher from the library it wouldn't return an error if
|
||||
you used an ID=0 [i.e blowfish or sha256] in any routine. Now it checks for that and will
|
||||
return an error like it should
|
||||
-- Merged in new routines from Clay Culver. These routines are for the PK code so you can easily
|
||||
encode a symmetric key for multiple recipients.
|
||||
-- Made the ecc and DH make_key() routines make secret keys of the same size as the keysize listed.
|
||||
Originally I wanted to ensure that the keys were smaller than the order of the field used
|
||||
However, the bias is so insignifcant using full sizes. For example, with a ECC-192 key the order
|
||||
is about 2^191.99, so instead I rounded down and used a 184-bit secret key. Now I simply use a full 192-bit
|
||||
key the code will work just the same except that some 192-bit keys will be duplicates which is not a big
|
||||
deal since 1/2^192 is a very small bias!
|
||||
-- Made the configuration a bit simpler and more exacting. You can for example now select which DH or ECC
|
||||
key settings you wish to support without including the data for all other key settings. I put the #defines
|
||||
in a new file called "mycrypt_cfg.h"
|
||||
-- Configured "mpi-config.h" so its a bit more conservative with the memory required and code space used
|
||||
-- Jason Klapste submitted bug fixes to the yarrow, hash and various other issues. The yarrow code will now
|
||||
use what ever remaining hash/cipher combo is left [after you #undef them] at build time. He also suggested
|
||||
a fix to remove unused structures from the symmetric_key and hash_state unions.
|
||||
-- Made the CTR code handle variable length blocks better. It will buffer the encryption pad so you can
|
||||
encrypt messages any size block at a time.
|
||||
-- Simplified the yarrow code to take advantage of the new CTR code.
|
||||
-- Added a 4096-bit DH key setting. That took me about 36 hours to find!
|
||||
-- Changed the base64 routines to use a real base64 encoding scheme.
|
||||
-- Added in DH and ECC "encrypt_key()" functions. They are still rather "beta"ish.
|
||||
-- Added **Twofish** to the list of ciphers!
|
||||
|
||||
January 18th, 2002
|
||||
v0.34 -- Added "sha512" to the list of hashes. Produces a 512-bit message digest. Note that with the current
|
||||
padding with the rsa_sign() function you cannot use sha512 with a key less than 1536 bits for signatures.
|
||||
-- Cleaned up the other hash functions to use the LOAD and STORE macros...
|
||||
|
||||
January 17th, 2002
|
||||
v0.33 -- Made the lower limit on keysizes for RSA 1024 bits again because I realized that 768 bit keys wouldn't
|
||||
work with the padding scheme and large symmetric keys.
|
||||
-- Added information concerning the Zlib license to the manual
|
||||
-- Added a 3072-bit key setting for the DH code.
|
||||
-- Made the "find_xyz()" routines take "const char *" as per Clay Culver's suggestion.
|
||||
-- Fixed an embarassing typo in the manual concerning the hashes. Thank's Clay for finding it!
|
||||
-- Fixed rand_prime() so that it makes primes bigger than the setting you give. For example,
|
||||
if you want a 1024-bit prime it would make a 1023-bit one. Now it ensures that the prime
|
||||
it makes is always greater than 2^(8n) (n == bytes in prime). This doesn't have a huge
|
||||
impact on security but I corrected it just the same.
|
||||
-- Fixed the CTR routine to work on platforms where char != 8-bits
|
||||
-- Fixed sha1/sha256/md5/blowfish to not assume "unsigned long == 32-bits", Basically any operation with carries
|
||||
I "AND" with 0xFFFFFFFF. That forces only the lower 32-bits to have information in it. On x86 platforms
|
||||
most compilers optimize out the AND operation since its a nop.
|
||||
|
||||
January 16th, 2002
|
||||
v0.32 -- Made Rijndael's setup function fully static so it is thread safe
|
||||
-- Svante Seleborg suggested a cosmetic style fixup for aes.c,
|
||||
basically to remove some of the #defines to clean it up
|
||||
-- Made the PK routines not export the ASCII version of the names of ciphers/hashes which makes
|
||||
the PK message formats *incompatible* with previous releases.
|
||||
-- Merge in Zlib :-)
|
||||
|
||||
|
||||
January 15th, 2002
|
||||
v0.31 -- The RSA routines can now use CRT to speed up decryption/signatures. The routines are backwards
|
||||
compatible with previous releases.
|
||||
-- Fixed another bug that Svante Seleborg found. Basically you could buffer-overrun the
|
||||
rsa_exptmod() function itself if you're not careful. That's fixed now. Fixed another bug in
|
||||
rsa_exptmod() where if it knows the buffer you passed is too small it wouldn't free all used
|
||||
memory.
|
||||
-- improved the readability of the PK import/export functions
|
||||
-- Added a fix to RSA.C by Clay Culver
|
||||
-- Changed the CONST64 macro for MSVC to use the "unsigned __int64" type, e.g. "ui64" instead of "i64".
|
||||
|
||||
January 14th, 2002
|
||||
v0.30 -- Major change to the Yarrow PRNG code, fixed a bug that Eugene Starokoltsev found.
|
||||
Basically if you added entropy to the pool in small increments it could in fact
|
||||
cancel out. Now I hash the pool with the new data which is way smarter.
|
||||
|
||||
January 12th, 2002
|
||||
v0.29 -- Added MPI code written by Svante Seleborg to the library. This will make the PK code much
|
||||
easier to follow and debug. Actually I've already fixed a memory leak in dh_shared_secret().
|
||||
-- Memory leaks found and correct in all three PK routines. The leaks would occur when a bignum
|
||||
operation fails so it wouldn't normally turn up in the course of a program
|
||||
-- Fixed bugs in dh_key_size and ecc_key_size which would return garbage for invalid key idx'es
|
||||
|
||||
January 11th, 2002
|
||||
v0.28 -- Cleaned up some code so that it doesn't assume "char == 8bits". Mainly SAFER+ has been
|
||||
changed.
|
||||
-- ***HUGE*** changes in the PK code. I check all return values in the bignum code so if there
|
||||
are errors [insufficient memory, etc..] it will be reported. This makes the code fairly more
|
||||
robust and likely to catch any errors.
|
||||
-- Updated the is_prime() function to use a new prototype [it can return errors now] and it also
|
||||
does trial divisions against more primes before the Rabin Miller steps
|
||||
-- Added OFB, CFB and ECB generic wrappers for the symmetric ciphers to round out the implementations.
|
||||
-- Added Xtea to the list of ciphers, to the best of my ability I have verified this implementation.
|
||||
I should note that there is not alot of concrete information about the cipher. "Ansi C" versions
|
||||
I found did not address endianess and were not even portable!. This code is portable and to the
|
||||
best of my knowledge implements the Xtea algorithm as per the [short] X-Tea paper.
|
||||
-- Reformated the manual to include the **FULL** source code optimized to be pritable.
|
||||
|
||||
January 9th, 2002
|
||||
v0.27 -- Changed the char constants to numerical values. It is backwards compatible and should work on
|
||||
platforms where 'd' != 100 [for example].
|
||||
-- Made a change to rand_prime() which takes the input length as a signed type so you can pass
|
||||
a negative len to get a "3 mod 4" style prime... oops
|
||||
-- changed the MSVC makefile to build with a warning level of three, no warnings!
|
||||
|
||||
January 8th, 2002
|
||||
v0.26 -- updated SHA-256 to use ROR() for a rotate so 64-bit machines won't corrupt
|
||||
the output
|
||||
-- Changed #include <> to #include "" for local .h files as per Richard Heathfields' suggestions.
|
||||
-- Fixed bug in MPI [well bug in MSVC] that compiled code incorrectly in mp_set_int()
|
||||
I added a work around that catches the error and continues normally.
|
||||
|
||||
January 8th, 2002
|
||||
v0.25 -- Added a stupid define so MSVC 6.00 can build the library.
|
||||
-- Big thanks to sci.crypt and "Ajay K. Agrawal" for helping me port this to MSVC
|
||||
|
||||
January 7th, 2002
|
||||
v0.24 -- Sped up Blowfish by unrolling and removing the swaps.
|
||||
-- Made the code comply with more traditional ANSI C standards
|
||||
Should compile with MSVC with less errors
|
||||
-- moved the demos and documentation into their own directories
|
||||
so you can easily build the library with other tool chains
|
||||
by compiling the files in the root
|
||||
-- converted functions with length of outputs to use
|
||||
"unsigned long" so 16-bit platforms will like this library more.
|
||||
|
||||
January 5th, 2002
|
||||
v0.23 -- Fixed a small error in the MPI config it should build fine anywhere.
|
||||
|
||||
January 4th, 2002
|
||||
v0.22 -- faster gf_mul() code
|
||||
-- gf_shl() and gf_shr() are safe on 64-bit platforms now
|
||||
-- Fixed an error in the hashes that Brian Gladman found.
|
||||
Basically if the message has exactly 56 bytes left to be
|
||||
compressed I handled them incorrectly.
|
||||
|
||||
January 4th, 2002
|
||||
v0.21 -- sped up the ECC code by removing redundant divisions in the
|
||||
point add and double routines. I also extract the bits more
|
||||
efficiently in "ecc_mulmod()" now.
|
||||
-- sped up [and documented] the rand_prime() function. Now it just
|
||||
makes a random integer and increments by two until a prime is found
|
||||
This is faster since it doesn't require alot of calls to the PRNG and
|
||||
it doesn't require loading huge integers over and over. rand_prime()
|
||||
can also make primes congruent to 3 mod 4 [i.e for a blum integer]
|
||||
-- added a gf_sqrt() function that finds square roots in a GF(2^w) field
|
||||
-- fixed a bug in gf_div() that would return the wrong results if the divisor had a greator
|
||||
divisor than the dividend.
|
||||
|
||||
January 4th, 2002
|
||||
v0.20 -- Added the fixed MPI back in so RSA and DH are much faster again
|
||||
|
||||
v0.19 -- Updated the manual to reflect the fact that Brian Gladman wrote the AES and Serpent code.
|
||||
-- DH, ECC and RSA signature/decryption functions check if the key is private
|
||||
-- new DH signature/verification code works just like the RSA/ECC versions
|
||||
|
||||
January 3rd, 2002
|
||||
v0.18 -- Added way more comments to each .C file
|
||||
-- fixed a bug in cbc_decrypt(pt, ct, key) where pt == ct [i.e same buffer]
|
||||
-- fixed RC5 so it reads the default rounds out of the cipher_descriptor table
|
||||
-- cleaned up ecc_export()
|
||||
-- Cleaned up dh_import() and ecc_import() which also perform more
|
||||
error checking now
|
||||
-- Fixed a serious flaw in rsa_import() with private keys.
|
||||
|
||||
January 2nd, 2002
|
||||
v0.17 -- Fixed a bug in the random prime generator that fixes the wrong bits to one
|
||||
-- ECC and DH code verify that the moduli and orders are in fact prime. That
|
||||
slows down the test routines alot but what are you gonna do?
|
||||
-- Fixed a huge bug in the mp_exptmod() function which incorrectly calculates g^x mod p for some
|
||||
values of p. I replaced it with a slow function. Once the author of MPI fixes his faster routine
|
||||
I will switch back.
|
||||
|
||||
January 1st, 2002 [whoa new year!]
|
||||
v0.16 -- Improved GF division code that is faster.
|
||||
-- documented the GF code
|
||||
|
||||
December 31st, 2001
|
||||
v0.15 -- A 1792-bit and 2048-bit DH setting was added. Took me all night to
|
||||
find a 1792 and 2048-bit strong prime but what the heck
|
||||
-- Library now has polynomial-basis GF(2^w) routines I wrote myself. Can be used to perform
|
||||
ECC over GF(2^w) later on....
|
||||
-- Fixed a bug with the defines that allows it to build in windows
|
||||
|
||||
December 30th, 2001
|
||||
v0.14 -- Fixed the xxx_encrypt() packet routines to make an IV of appropriate size
|
||||
for the cipher used. It was defaulting to making a 256-bit IV...
|
||||
-- base64_encode() now appends a NULL byte, um "duh" stupid mistake now fixed...
|
||||
-- spell checked the manual again... :-)
|
||||
|
||||
December 30th, 2001
|
||||
v0.13 -- Switching back to older copy of MPI since it works! arrg..
|
||||
-- Added sign/verify functions for ECC
|
||||
-- all signature verification routines default to invalid signatures.
|
||||
-- Changed all calls to memset to zeromem. Fixed up some buffer problems
|
||||
in other routines. All calls to zeromem let the compiler determine the size
|
||||
of the data to wipe.
|
||||
|
||||
December 29th, 2001
|
||||
v0.12 -- Imported a new version of MPI [the bignum library] that should
|
||||
be a bit more stable [if you want to write your own bignum
|
||||
routines with the library that is...]
|
||||
-- Manual has way more info
|
||||
-- hash_file() clears stack now [like it should]
|
||||
-- The artificial cap on the hash input size of 2^32 bits has been
|
||||
removed. Basically I was too lazy todo 64-bit math before
|
||||
[don't ask why... I can't remember]. Anyways the hashes
|
||||
support the size of 2^64 bits [if you ever use that many bits in a message
|
||||
that's just wierd...]
|
||||
-- The hashes now wipe the "hash_state" after the digest is computed. This helps
|
||||
prevent the internal state of the hash being leaked accidently [i.e stack problems]
|
||||
|
||||
December 29th, 2001
|
||||
v0.11 -- Made #define's so you can trim the library down by removing
|
||||
ciphers, hashs, modes of operation, prngs, and even PK algorithms
|
||||
For example, the library with rijndael+ctr+sha1+ECC is 91KB compared
|
||||
to the 246kb the full library takes.
|
||||
-- Added ECC packet routines for encrypt/decrypt/sign/verify much akin to
|
||||
the RSA packet routines.
|
||||
-- ECC now compresses the public key, a ECC-192 public key takes 33 bytes
|
||||
for example....
|
||||
|
||||
December 28th, 2001
|
||||
v0.10 -- going to restart the manual from scratch to make it more
|
||||
clear and professional
|
||||
-- Added ECC over Z/pZ. Basically provides as much as DH
|
||||
except its faster since the numbers are smaller. For example,
|
||||
A comparable 256-bit ECC key provides as much security as expected
|
||||
from a DH key over 1024-bits.
|
||||
-- Cleaned up the DH code to not export the symbol "sets[]"
|
||||
-- Fixed a bug in the DH code that would not make the correct size
|
||||
random string if you made the key short. For instance if you wanted
|
||||
a 512-bit DH key it would make a 768-bit one but only make up 512-bits
|
||||
for the exponent... now it makes the full 768 bits [or whatever the case
|
||||
is]
|
||||
-- Fixed another ***SERIOUS*** bug in the DH code that would default to 768-bit
|
||||
keys by mistake.
|
||||
|
||||
December 25th, 2001
|
||||
v0.09 -- Includes a demo program called file_crypt which shows off
|
||||
how to use the library to make a command line tool which
|
||||
allows the user to encode/decode a file with any
|
||||
hash (on the passphrase) and cipher in CTR mode.
|
||||
-- Switched everything to use typedef's now to clear up the code.
|
||||
-- Added AES (128/192 and 256 bit key modes)
|
||||
|
||||
December 24th, 2001
|
||||
v0.08 -- fixed a typo in the manual. MPI stores its bignums in
|
||||
BIG endian not little.
|
||||
-- Started adding a RNG to the library. Right now it tries
|
||||
to open /dev/random and if that fails it uses either the
|
||||
MS CSP or the clock drift RNG. It also allows callbacks
|
||||
since the drift RNG is slow (about 3.5 bytes/sec)
|
||||
-- the RNG can also automatically setup a PRNG as well now
|
||||
|
||||
v0.07 -- Added basic DH routines sufficient to
|
||||
negotiate shared secrets
|
||||
[see the manual for a complete example!]
|
||||
-- Fixed rsa_import to detect when the input
|
||||
could be corrupt.
|
||||
-- added more to the manual.
|
||||
|
||||
December 22nd, 2001
|
||||
v0.06 -- Fixed some formatting errors in
|
||||
the hash functions [just source code cleaning]
|
||||
-- Fixed a typo in the error message for sha256 :-)
|
||||
-- Fixed an error in base64_encode() that
|
||||
would fail to catch all buffer overruns
|
||||
-- Test program times the RSA and symmetric cipher
|
||||
routines for kicks...
|
||||
-- Added the "const" modifier to alot of routines to
|
||||
clear up the purpose of each function.
|
||||
-- Changed the name of the library to "TomCrypt"
|
||||
following a suggestion from a sci.crypt reader....
|
||||
|
||||
v0.05 -- Fixed the ROL/ROR macro to be safe on platforms
|
||||
where unsigned long is not 32-bits
|
||||
-- I have added a bit more to the documentation
|
||||
manual "crypt.pdf" provided.
|
||||
-- I have added a makefile for LCC-Win32. It should be
|
||||
easy to port to other LCC platforms by changing a few lines.
|
||||
-- Ran a spell checker over the manual.
|
||||
-- Changed the header and library from "crypt" to "mycrypt" to not
|
||||
clash with the *nix package "crypt".
|
||||
|
||||
v0.04 -- Fixed a bug in the RC5,RC6,Blowfish key schedules
|
||||
where if the key was not a multiple of 4 bytes it would
|
||||
not get loaded correctly.
|
||||
|
||||
December 21st, 2001
|
||||
|
||||
v0.03 -- Added Serpent to the list of ciphers.
|
||||
|
||||
v0.02 -- Changed RC5 to only allow 12 to 24 rounds
|
||||
-- Added more to the manual.
|
||||
|
||||
v0.01 -- We will call this the first version.
|
507
crypt.c
Normal file
507
crypt.c
Normal file
@ -0,0 +1,507 @@
|
||||
#include "mycrypt.h"
|
||||
#include <signal.h>
|
||||
|
||||
struct _cipher_descriptor cipher_descriptor[32] = {
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } };
|
||||
|
||||
struct _hash_descriptor hash_descriptor[32] = {
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL } };
|
||||
|
||||
struct _prng_descriptor prng_descriptor[32] = {
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL } };
|
||||
|
||||
int find_cipher(const char *name)
|
||||
{
|
||||
int x;
|
||||
_ARGCHK(name != NULL);
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (cipher_descriptor[x].name != NULL && !strcmp(cipher_descriptor[x].name, name)) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find_hash(const char *name)
|
||||
{
|
||||
int x;
|
||||
_ARGCHK(name != NULL);
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (hash_descriptor[x].name != NULL && !strcmp(hash_descriptor[x].name, name)) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find_prng(const char *name)
|
||||
{
|
||||
int x;
|
||||
_ARGCHK(name != NULL);
|
||||
for (x = 0; x < 32; x++) {
|
||||
if ((prng_descriptor[x].name != NULL) && !strcmp(prng_descriptor[x].name, name)) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find_cipher_id(unsigned char ID)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (cipher_descriptor[x].ID == ID) {
|
||||
return (cipher_descriptor[x].name == NULL) ? -1 : x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int find_hash_id(unsigned char ID)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (hash_descriptor[x].ID == ID) {
|
||||
return (hash_descriptor[x].name == NULL) ? -1 : x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* idea from Wayne Scott */
|
||||
int find_cipher_any(const char *name, int blocklen, int keylen)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(name != NULL);
|
||||
|
||||
x = find_cipher(name);
|
||||
if (x != -1) return x;
|
||||
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int register_cipher(const struct _cipher_descriptor *cipher)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(cipher != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (!memcmp(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor))) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* find a blank spot */
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (cipher_descriptor[x].name == NULL) {
|
||||
memcpy(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor));
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* no spot */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int unregister_cipher(const struct _cipher_descriptor *cipher)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(cipher != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (!memcmp(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor))) {
|
||||
cipher_descriptor[x].name = NULL;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
int register_hash(const struct _hash_descriptor *hash)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (!memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor))) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* find a blank spot */
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (hash_descriptor[x].name == NULL) {
|
||||
memcpy(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor));
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* no spot */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int unregister_hash(const struct _hash_descriptor *hash)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (!memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor))) {
|
||||
hash_descriptor[x].name = NULL;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
int register_prng(const struct _prng_descriptor *prng)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (!memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor))) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* find a blank spot */
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (prng_descriptor[x].name == NULL) {
|
||||
memcpy(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor));
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* no spot */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int unregister_prng(const struct _prng_descriptor *prng)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < 32; x++) {
|
||||
if (!memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor))) {
|
||||
prng_descriptor[x].name = NULL;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
int cipher_is_valid(int idx)
|
||||
{
|
||||
if (idx < 0 || idx > 32 || cipher_descriptor[idx].name == NULL) {
|
||||
return CRYPT_INVALID_CIPHER;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int hash_is_valid(int idx)
|
||||
{
|
||||
if (idx < 0 || idx > 32 || hash_descriptor[idx].name == NULL) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int prng_is_valid(int idx)
|
||||
{
|
||||
if (idx < 0 || idx > 32 || prng_descriptor[idx].name == NULL) {
|
||||
return CRYPT_INVALID_PRNG;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
const char *crypt_build_settings =
|
||||
"LibTomCrypt " SCRYPT "\n\n"
|
||||
"Endianess: "
|
||||
#if defined(ENDIAN_NEUTRAL)
|
||||
"neutral\n"
|
||||
#elif defined(ENDIAN_LITTLE)
|
||||
"little"
|
||||
#if defined(ENDIAN_32BITWORD)
|
||||
" (32-bit words)\n"
|
||||
#else
|
||||
" (64-bit words)\n"
|
||||
#endif
|
||||
#elif defined(ENDIAN_BIG)
|
||||
"big"
|
||||
#if defined(ENDIAN_32BITWORD)
|
||||
" (32-bit words)\n"
|
||||
#else
|
||||
" (64-bit words)\n"
|
||||
#endif
|
||||
#endif
|
||||
"Clean stack: "
|
||||
#if defined(CLEAN_STACK)
|
||||
"enabled\n"
|
||||
#else
|
||||
"disabled\n"
|
||||
#endif
|
||||
"Ciphers built-in:\n"
|
||||
#if defined(BLOWFISH)
|
||||
" Blowfish\n"
|
||||
#endif
|
||||
#if defined(RC2)
|
||||
" RC2\n"
|
||||
#endif
|
||||
#if defined(RC5)
|
||||
" RC5\n"
|
||||
#endif
|
||||
#if defined(RC6)
|
||||
" RC6\n"
|
||||
#endif
|
||||
#if defined(SERPENT)
|
||||
" Serpent\n"
|
||||
#endif
|
||||
#if defined(SAFERP)
|
||||
" Safer+\n"
|
||||
#endif
|
||||
#if defined(SAFER)
|
||||
" Safer\n"
|
||||
#endif
|
||||
#if defined(RIJNDAEL)
|
||||
" Rijndael\n"
|
||||
#endif
|
||||
#if defined(XTEA)
|
||||
" XTEA\n"
|
||||
#endif
|
||||
#if defined(TWOFISH)
|
||||
" Twofish "
|
||||
#if defined(TWOFISH_SMALL) && defined(TWOFISH_TABLES)
|
||||
"(small, tables)\n"
|
||||
#elif defined(TWOFISH_SMALL)
|
||||
"(small)\n"
|
||||
#elif defined(TWOFISH_TABLES)
|
||||
"(tables)\n"
|
||||
#else
|
||||
"\n"
|
||||
#endif
|
||||
#endif
|
||||
#if defined(DES)
|
||||
" DES\n"
|
||||
#endif
|
||||
#if defined(CAST5)
|
||||
" CAST5\n"
|
||||
#endif
|
||||
|
||||
"\nHashes built-in:\n"
|
||||
#if defined(SHA512)
|
||||
" SHA-512\n"
|
||||
#endif
|
||||
#if defined(SHA384)
|
||||
" SHA-384\n"
|
||||
#endif
|
||||
#if defined(SHA256)
|
||||
" SHA-256\n"
|
||||
#endif
|
||||
#if defined(TIGER)
|
||||
" TIGER\n"
|
||||
#endif
|
||||
#if defined(SHA1)
|
||||
" SHA1\n"
|
||||
#endif
|
||||
#if defined(MD5)
|
||||
" MD5\n"
|
||||
#endif
|
||||
#if defined(MD4)
|
||||
" MD4\n"
|
||||
#endif
|
||||
#if defined(MD2)
|
||||
" MD2\n"
|
||||
#endif
|
||||
|
||||
"\nBlock Chaining Modes:\n"
|
||||
#if defined(CFB)
|
||||
" CFB\n"
|
||||
#endif
|
||||
#if defined(OFB)
|
||||
" OFB\n"
|
||||
#endif
|
||||
#if defined(ECB)
|
||||
" ECB\n"
|
||||
#endif
|
||||
#if defined(CBC)
|
||||
" CBC\n"
|
||||
#endif
|
||||
#if defined(CTR)
|
||||
" CTR\n"
|
||||
#endif
|
||||
|
||||
"\nPRNG:\n"
|
||||
#if defined(YARROW)
|
||||
" Yarrow\n"
|
||||
#endif
|
||||
#if defined(SPRNG)
|
||||
" SPRNG\n"
|
||||
#endif
|
||||
#if defined(RC4)
|
||||
" RC4\n"
|
||||
#endif
|
||||
|
||||
"\nPK Algs:\n"
|
||||
#if defined(MRSA)
|
||||
" RSA\n"
|
||||
#endif
|
||||
#if defined(MDH)
|
||||
" DH\n"
|
||||
#endif
|
||||
#if defined(MECC)
|
||||
" ECC\n"
|
||||
#endif
|
||||
|
||||
"\nCompiler:\n"
|
||||
#if defined(WIN32)
|
||||
" WIN32 platform detected.\n"
|
||||
#endif
|
||||
#if defined(__CYGWIN__)
|
||||
" CYGWIN Detected.\n"
|
||||
#endif
|
||||
#if defined(__DJGPP__)
|
||||
" DJGPP Detected.\n"
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
" MSVC compiler detected.\n"
|
||||
#endif
|
||||
#if defined(__GNUC__)
|
||||
" GCC compiler detected.\n"
|
||||
#endif
|
||||
|
||||
"\nVarious others: "
|
||||
#if defined(GF)
|
||||
" GF "
|
||||
#endif
|
||||
#if defined(BASE64)
|
||||
" BASE64 "
|
||||
#endif
|
||||
#if defined(MPI)
|
||||
" MPI "
|
||||
#endif
|
||||
#if defined(HMAC)
|
||||
" HMAC "
|
||||
#endif
|
||||
#if defined(TRY_UNRANDOM_FIRST)
|
||||
" TRY_UNRANDOM_FIRST "
|
||||
#endif
|
||||
#if defined(SMALL_PRIME_TAB)
|
||||
" SMALL_PRIME_TAB "
|
||||
#endif
|
||||
"\n"
|
||||
|
||||
"\n\n\n"
|
||||
;
|
||||
|
77
ctr.c
Normal file
77
ctr.c
Normal file
@ -0,0 +1,77 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef CTR
|
||||
|
||||
int ctr_start(int cipher, const unsigned char *count, const unsigned char *key, int keylen,
|
||||
int num_rounds, symmetric_CTR *ctr)
|
||||
{
|
||||
int x, errno;
|
||||
|
||||
_ARGCHK(count != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(ctr != NULL);
|
||||
|
||||
/* bad param? */
|
||||
if ((errno = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* setup cipher */
|
||||
if ((errno = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* copy ctr */
|
||||
ctr->blocklen = cipher_descriptor[cipher].block_length;
|
||||
ctr->cipher = cipher;
|
||||
ctr->padlen = 0;
|
||||
for (x = 0; x < ctr->blocklen; x++) {
|
||||
ctr->ctr[x] = count[x];
|
||||
}
|
||||
cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
|
||||
{
|
||||
int x, errno;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(ctr != NULL);
|
||||
|
||||
if ((errno = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
while (len--) {
|
||||
/* is the pad empty? */
|
||||
if (ctr->padlen == ctr->blocklen) {
|
||||
/* increment counter */
|
||||
for (x = 0; x < ctr->blocklen; x++) {
|
||||
ctr->ctr[x] = (ctr->ctr[x] + 1) & 255;
|
||||
if (ctr->ctr[x] != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* encrypt it */
|
||||
cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
|
||||
ctr->padlen = 0;
|
||||
}
|
||||
*ct++ = *pt++ ^ ctr->pad[ctr->padlen++];
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr)
|
||||
{
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(ctr != NULL);
|
||||
|
||||
return ctr_encrypt(ct, pt, len, ctr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
202
demos/encrypt.c
Normal file
202
demos/encrypt.c
Normal file
@ -0,0 +1,202 @@
|
||||
/* encrypt V1.1 Fri Oct 18 04:28:03 NZDT 2002 */
|
||||
/* File de/encryption, using libtomcrypt */
|
||||
/* Written by Daniel Richards <kyhwana@world-net.co.nz> */
|
||||
/* Help from Tom St Denis with various bits */
|
||||
/* This code is public domain, no rights reserved. */
|
||||
/* Encrypts by default, -d flag enables decryption */
|
||||
/* ie: ./encrypt blowfish story.txt story.ct */
|
||||
/* ./encrypt -d blowfish story.ct story.pt */
|
||||
|
||||
#include <mycrypt.h>
|
||||
|
||||
int errno;
|
||||
|
||||
static const struct _cipher_descriptor *ciphers[] = {
|
||||
&blowfish_desc, &xtea_desc, &rc5_desc, &rc6_desc,
|
||||
&saferp_desc, &serpent_desc, &rijndael_desc,
|
||||
&twofish_desc, &safer_k64_desc, &safer_sk64_desc,
|
||||
&safer_k128_desc, &safer_sk128_desc, &rc2_desc,
|
||||
&des_desc, &des3_desc, &cast5_desc, NULL
|
||||
};
|
||||
|
||||
int usage(void)
|
||||
{
|
||||
int x;
|
||||
|
||||
printf("Usage: ./crypt [-d](ecrypt) cipher infile outfile\nCiphers:\n");
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
printf("%s\n",cipher_descriptor[x].name);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void register_algs(void)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; ciphers[x] != NULL; x++) {
|
||||
if (register_cipher(ciphers[x]) == -1) {
|
||||
printf("Error registering cipher\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
if (register_hash(&sha256_desc) == -1) {
|
||||
printf("Error registering SHA256\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (register_prng(&yarrow_desc) == -1) {
|
||||
printf("Error registering yarrow PRNG\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (register_prng(&sprng_desc) == -1) {
|
||||
printf("Error registering sprng PRNG\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned char plaintext[512],ciphertext[512];
|
||||
unsigned char tmpkey[512], key[MAXBLOCKSIZE], IV[MAXBLOCKSIZE];
|
||||
unsigned char inbuf[512]; /* i/o block size */
|
||||
unsigned long outlen, y, ivsize, x, decrypt;
|
||||
symmetric_CTR ctr;
|
||||
int cipher_idx, hash_idx, ks;
|
||||
char *infile, *outfile, *cipher;
|
||||
prng_state prng;
|
||||
FILE *fdin, *fdout;
|
||||
|
||||
/* register algs, so they can be printed */
|
||||
register_algs();
|
||||
|
||||
if (argc < 4) {
|
||||
return usage();
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "-d")) {
|
||||
decrypt = 1;
|
||||
cipher = argv[2];
|
||||
infile = argv[3];
|
||||
outfile = argv[4];
|
||||
} else {
|
||||
decrypt = 0;
|
||||
cipher = argv[1];
|
||||
infile = argv[2];
|
||||
outfile = argv[3];
|
||||
}
|
||||
|
||||
/* file handles setup */
|
||||
fdin = fopen(infile,"rb");
|
||||
if (fdin == NULL) {
|
||||
perror("Can't open input for reading");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fdout = fopen(outfile,"wb");
|
||||
if (fdout == NULL) {
|
||||
perror("Can't open output for writing");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
cipher_idx = find_cipher(cipher);
|
||||
if (cipher_idx == -1) {
|
||||
printf("Invalid cipher entered on command line.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
hash_idx = find_hash("sha256");
|
||||
if (hash_idx == -1) {
|
||||
printf("SHA256 not found...?\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ivsize = cipher_descriptor[cipher_idx].block_length;
|
||||
ks = hash_descriptor[hash_idx].hashsize;
|
||||
if (cipher_descriptor[cipher_idx].keysize(&ks) != CRYPT_OK) {
|
||||
printf("Invalid keysize???\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("\nEnter key: ");
|
||||
fgets(tmpkey,sizeof(tmpkey), stdin);
|
||||
outlen = sizeof(key);
|
||||
if ((errno = hash_memory(hash_idx,tmpkey,strlen(tmpkey),key,&outlen)) != CRYPT_OK) {
|
||||
printf("Error hashing key: %s\n", error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (decrypt) {
|
||||
/* Need to read in IV */
|
||||
if (fread(IV,1,ivsize,fdin) != ivsize) {
|
||||
printf("Error reading IV from input.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) {
|
||||
printf("ctr_start error: %s\n",error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* IV done */
|
||||
do {
|
||||
y = fread(inbuf,1,sizeof(inbuf),fdin);
|
||||
|
||||
if ((errno = ctr_decrypt(inbuf,plaintext,y,&ctr)) != CRYPT_OK) {
|
||||
printf("ctr_decrypt error: %s\n", error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (fwrite(plaintext,1,y,fdout) != y) {
|
||||
printf("Error writing to file.\n");
|
||||
exit(-1);
|
||||
}
|
||||
} while (y == sizeof(inbuf));
|
||||
fclose(fdin);
|
||||
fclose(fdout);
|
||||
|
||||
} else { /* encrypt */
|
||||
/* Setup yarrow for random bytes for IV */
|
||||
|
||||
if ((errno = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) {
|
||||
printf("Error setting up PRNG, %s\n", error_to_string(errno));
|
||||
}
|
||||
|
||||
/* You can use rng_get_bytes on platforms that support it */
|
||||
/* x = rng_get_bytes(IV,ivsize,NULL);*/
|
||||
x = yarrow_read(IV,ivsize,&prng);
|
||||
if (x != ivsize) {
|
||||
printf("Error reading PRNG for IV required.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (fwrite(IV,1,ivsize,fdout) != ivsize) {
|
||||
printf("Error writing IV to output.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) {
|
||||
printf("ctr_start error: %s\n",error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
do {
|
||||
y = fread(inbuf,1,sizeof(inbuf),fdin);
|
||||
|
||||
if ((errno = ctr_encrypt(inbuf,ciphertext,y,&ctr)) != CRYPT_OK) {
|
||||
printf("ctr_encrypt error: %s\n", error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (fwrite(ciphertext,1,y,fdout) != y) {
|
||||
printf("Error writing to output.\n");
|
||||
exit(-1);
|
||||
}
|
||||
} while (y == sizeof(inbuf));
|
||||
fclose(fdout);
|
||||
fclose(fdin);
|
||||
}
|
||||
return 0;
|
||||
}
|
77
demos/hashsum.c
Normal file
77
demos/hashsum.c
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Written by Daniel Richards <kyhwana@world-net.co.nz> 6/7/2002
|
||||
* hash.c: This app uses libtomcrypt to hash either stdin or a file
|
||||
* This file is Public Domain. No rights are reserved.
|
||||
* Compile with 'gcc hashsum.c -o hashsum -ltomcrypt'
|
||||
* This example isn't really big enough to warrent splitting into
|
||||
* more functions ;)
|
||||
*/
|
||||
|
||||
#include <mycrypt.h>
|
||||
|
||||
int errno;
|
||||
|
||||
void register_algs();
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int idx, x, z;
|
||||
unsigned long w;
|
||||
unsigned char hash_buffer[MAXBLOCKSIZE];
|
||||
hash_state md;
|
||||
|
||||
/* You need to register algorithms before using them */
|
||||
register_algs();
|
||||
if (argc < 2) {
|
||||
printf("usage: ./hash algorithm file [file ...]\n");
|
||||
printf("Algorithms:\n");
|
||||
for (x = 0; hash_descriptor[x].name != NULL; x++) {
|
||||
printf(" %s\n", hash_descriptor[x].name);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
idx = find_hash(argv[1]);
|
||||
if (idx == -1) {
|
||||
fprintf(stderr, "\nInvalid hash specified on command line.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
hash_descriptor[idx].init(&md);
|
||||
do {
|
||||
x = fread(hash_buffer, 1, sizeof(hash_buffer), stdin);
|
||||
hash_descriptor[idx].process(&md, hash_buffer, x);
|
||||
} while (x == sizeof(hash_buffer));
|
||||
hash_descriptor[idx].done(&md, hash_buffer);
|
||||
for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) {
|
||||
printf("%02x",hash_buffer[x]);
|
||||
}
|
||||
printf(" (stdin)\n");
|
||||
} else {
|
||||
for (z = 2; z < argc; z++) {
|
||||
w = sizeof(hash_buffer);
|
||||
if ((errno = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) {
|
||||
printf("File hash error: %s\n", error_to_string(errno));
|
||||
} else {
|
||||
for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) {
|
||||
printf("%02x",hash_buffer[x]);
|
||||
}
|
||||
printf(" %s\n", argv[z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void register_algs(void)
|
||||
{
|
||||
register_hash(&sha512_desc);
|
||||
register_hash(&sha384_desc);
|
||||
register_hash(&sha256_desc);
|
||||
register_hash(&sha1_desc);
|
||||
register_hash(&md5_desc);
|
||||
register_hash(&md4_desc);
|
||||
register_hash(&tiger_desc);
|
||||
register_hash(&md2_desc);
|
||||
}
|
11
demos/small.c
Normal file
11
demos/small.c
Normal file
@ -0,0 +1,11 @@
|
||||
// small demo app that just includes a cipher/hash/prng
|
||||
|
||||
#include <mycrypt.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
register_cipher(&rijndael_desc);
|
||||
register_prng(&yarrow_desc);
|
||||
register_hash(&sha1_desc);
|
||||
return 0;
|
||||
}
|
1586
demos/test.c
Normal file
1586
demos/test.c
Normal file
File diff suppressed because it is too large
Load Diff
7
demos/timer.c
Normal file
7
demos/timer.c
Normal file
@ -0,0 +1,7 @@
|
||||
/*
|
||||
* The working version of this file can be found
|
||||
* at the PlayStation(r)2 Developer Network website
|
||||
* under the libtomcrypt project.
|
||||
*/
|
||||
|
||||
#error Please download the implemented version of this file from the PlayStation(r)2 Developer Network website
|
51
demos/timer.h
Normal file
51
demos/timer.h
Normal file
@ -0,0 +1,51 @@
|
||||
#ifndef __TIMER_H__
|
||||
#define __TIMER_H__
|
||||
/****************************************************************************
|
||||
*
|
||||
* Copyright (c) 2000, Sony Computer Entertainment of America Inc.
|
||||
* All rights reserved
|
||||
* SCEA Confidential
|
||||
*
|
||||
* Document: TIMER.H
|
||||
* Author: Ben Wiggins
|
||||
* Date: 7/15/2002
|
||||
* Header: Timer stuff
|
||||
*
|
||||
****************************************************************************/
|
||||
/*============================================================================
|
||||
= INTERFACE REQUIRED HEADERS
|
||||
============================================================================*/
|
||||
/*============================================================================
|
||||
= INTERFACE DEFINITIONS / ENUMERATIONS / SIMPLE TYPEDEFS
|
||||
============================================================================*/
|
||||
/*============================================================================
|
||||
= INTERFACE STRUCTURES / UTILITY CLASSES
|
||||
============================================================================*/
|
||||
/*============================================================================
|
||||
= INTERFACE DATA DECLARATIONS
|
||||
============================================================================*/
|
||||
/*============================================================================
|
||||
= INTERFACE FUNCTION PROTOTYPES
|
||||
============================================================================*/
|
||||
void TIMER_Init(void);
|
||||
void TIMER_Shutdown(void);
|
||||
double TIMER_GetTime(void);
|
||||
|
||||
#include <time.h>
|
||||
#ifdef CLOCKS_PER_SEC
|
||||
#undef CLOCKS_PER_SEC
|
||||
#endif
|
||||
#define CLOCKS_PER_SEC 576000
|
||||
extern clock_t TIMER_clock(void);
|
||||
|
||||
/*============================================================================
|
||||
= INTERFACE TRAILING HEADERS
|
||||
============================================================================*/
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* END HEADER TIMER.H
|
||||
*
|
||||
****************************************************************************/
|
||||
#endif // __TIMER_H__
|
||||
|
728
des.c
Normal file
728
des.c
Normal file
@ -0,0 +1,728 @@
|
||||
/* DES code submitted by Dobes Vandermeer */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef DES
|
||||
|
||||
#define EN0 0
|
||||
#define DE1 1
|
||||
|
||||
const struct _cipher_descriptor des_desc =
|
||||
{
|
||||
"des",
|
||||
13,
|
||||
8, 8, 8, 16,
|
||||
&des_setup,
|
||||
&des_ecb_encrypt,
|
||||
&des_ecb_decrypt,
|
||||
&des_test,
|
||||
&des_keysize
|
||||
};
|
||||
|
||||
const struct _cipher_descriptor des3_desc =
|
||||
{
|
||||
"3des",
|
||||
14,
|
||||
24, 24, 8, 16,
|
||||
&des3_setup,
|
||||
&des3_ecb_encrypt,
|
||||
&des3_ecb_decrypt,
|
||||
&des3_test,
|
||||
&des3_keysize
|
||||
};
|
||||
|
||||
static const unsigned char Df_Key[24] =
|
||||
{
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
|
||||
0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10,
|
||||
0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67
|
||||
};
|
||||
|
||||
static const unsigned short bytebit[8] =
|
||||
{
|
||||
0200, 0100, 040, 020, 010, 04, 02, 01
|
||||
};
|
||||
|
||||
static const unsigned long bigbyte[24] =
|
||||
{
|
||||
0x800000L, 0x400000L, 0x200000L, 0x100000L,
|
||||
0x80000L, 0x40000L, 0x20000L, 0x10000L,
|
||||
0x8000L, 0x4000L, 0x2000L, 0x1000L,
|
||||
0x800L, 0x400L, 0x200L, 0x100L,
|
||||
0x80L, 0x40L, 0x20L, 0x10L,
|
||||
0x8L, 0x4L, 0x2L, 0x1L
|
||||
};
|
||||
|
||||
/* Use the key schedule specific in the standard (ANSI X3.92-1981) */
|
||||
|
||||
static const unsigned char pc1[56] = {
|
||||
56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17,
|
||||
9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
|
||||
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21,
|
||||
13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3
|
||||
};
|
||||
|
||||
static const unsigned char totrot[16] = {
|
||||
1, 2, 4, 6,
|
||||
8, 10, 12, 14,
|
||||
15, 17, 19, 21,
|
||||
23, 25, 27, 28
|
||||
};
|
||||
|
||||
static const unsigned char pc2[48] = {
|
||||
13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
|
||||
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1,
|
||||
40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
|
||||
43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31
|
||||
};
|
||||
|
||||
|
||||
static const unsigned long SP1[64] =
|
||||
{
|
||||
0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
|
||||
0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
|
||||
0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
|
||||
0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
|
||||
0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
|
||||
0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
|
||||
0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
|
||||
0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
|
||||
0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
|
||||
0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
|
||||
0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
|
||||
0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
|
||||
0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
|
||||
0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
|
||||
0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
|
||||
0x00010004L, 0x00010400L, 0x00000000L, 0x01010004
|
||||
};
|
||||
|
||||
static const unsigned long SP2[64] =
|
||||
{
|
||||
0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
|
||||
0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
|
||||
0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
|
||||
0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
|
||||
0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
|
||||
0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
|
||||
0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
|
||||
0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
|
||||
0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
|
||||
0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
|
||||
0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
|
||||
0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
|
||||
0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
|
||||
0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
|
||||
0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
|
||||
0x80000000L, 0x80100020L, 0x80108020L, 0x00108000
|
||||
};
|
||||
|
||||
static const unsigned long SP3[64] =
|
||||
{
|
||||
0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
|
||||
0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
|
||||
0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
|
||||
0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
|
||||
0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
|
||||
0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
|
||||
0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
|
||||
0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
|
||||
0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
|
||||
0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
|
||||
0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
|
||||
0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
|
||||
0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
|
||||
0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
|
||||
0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
|
||||
0x00020208L, 0x00000008L, 0x08020008L, 0x00020200
|
||||
};
|
||||
|
||||
static const unsigned long SP4[64] =
|
||||
{
|
||||
0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
|
||||
0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
|
||||
0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
|
||||
0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
|
||||
0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
|
||||
0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
|
||||
0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
|
||||
0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
|
||||
0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
|
||||
0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
|
||||
0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
|
||||
0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
|
||||
0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
|
||||
0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
|
||||
0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
|
||||
0x00000080L, 0x00800000L, 0x00002000L, 0x00802080
|
||||
};
|
||||
|
||||
static const unsigned long SP5[64] =
|
||||
{
|
||||
0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
|
||||
0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
|
||||
0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
|
||||
0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
|
||||
0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
|
||||
0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
|
||||
0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
|
||||
0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
|
||||
0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
|
||||
0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
|
||||
0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
|
||||
0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
|
||||
0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
|
||||
0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
|
||||
0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
|
||||
0x00000000L, 0x40080000L, 0x02080100L, 0x40000100
|
||||
};
|
||||
|
||||
static const unsigned long SP6[64] =
|
||||
{
|
||||
0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
|
||||
0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
|
||||
0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
|
||||
0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
|
||||
0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
|
||||
0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
|
||||
0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
|
||||
0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
|
||||
0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
|
||||
0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
|
||||
0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
|
||||
0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
|
||||
0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
|
||||
0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
|
||||
0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
|
||||
0x20404000L, 0x20000000L, 0x00400010L, 0x20004010
|
||||
};
|
||||
|
||||
static const unsigned long SP7[64] =
|
||||
{
|
||||
0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
|
||||
0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
|
||||
0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
|
||||
0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
|
||||
0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
|
||||
0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
|
||||
0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
|
||||
0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
|
||||
0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
|
||||
0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
|
||||
0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
|
||||
0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
|
||||
0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
|
||||
0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
|
||||
0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
|
||||
0x04000002L, 0x04000800L, 0x00000800L, 0x00200002
|
||||
};
|
||||
|
||||
static const unsigned long SP8[64] =
|
||||
{
|
||||
0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
|
||||
0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
|
||||
0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
|
||||
0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
|
||||
0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
|
||||
0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
|
||||
0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
|
||||
0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
|
||||
0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
|
||||
0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
|
||||
0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
|
||||
0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
|
||||
0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
|
||||
0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
|
||||
0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
|
||||
0x00001040L, 0x00040040L, 0x10000000L, 0x10041000
|
||||
};
|
||||
|
||||
|
||||
static void cookey(const unsigned long *raw1, unsigned long *keyout);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void _deskey(const unsigned char *key, short edf, unsigned long *keyout)
|
||||
#else
|
||||
void deskey(const unsigned char *key, short edf, unsigned long *keyout)
|
||||
#endif
|
||||
{
|
||||
int i, j, l, m, n;
|
||||
unsigned char pc1m[56], pcr[56];
|
||||
unsigned long kn[32];
|
||||
|
||||
for(j=0; j < 56; j++)
|
||||
{
|
||||
l = pc1[j];
|
||||
m = l & 07;
|
||||
pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
|
||||
}
|
||||
|
||||
for(i=0; i < 16; i++)
|
||||
{
|
||||
if(edf == DE1) m = (15 - i) << 1;
|
||||
else m = i << 1;
|
||||
n = m + 1;
|
||||
kn[m] = kn[n] = 0L;
|
||||
for(j=0; j < 28; j++)
|
||||
{
|
||||
l = j + totrot[i];
|
||||
if(l < 28) pcr[j] = pc1m[l];
|
||||
else pcr[j] = pc1m[l - 28];
|
||||
}
|
||||
for(/*j = 28*/; j < 56; j++)
|
||||
{
|
||||
l = j + totrot[i];
|
||||
if(l < 56) pcr[j] = pc1m[l];
|
||||
else pcr[j] = pc1m[l - 28];
|
||||
}
|
||||
for(j=0; j < 24; j++)
|
||||
{
|
||||
if(pcr[pc2[j]]) kn[m] |= bigbyte[j];
|
||||
if(pcr[pc2[j+24]]) kn[n] |= bigbyte[j];
|
||||
}
|
||||
}
|
||||
|
||||
cookey(kn, keyout);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void deskey(const unsigned char *key, short edf, unsigned long *keyout)
|
||||
{
|
||||
_deskey(key, edf, keyout);
|
||||
burn_stack(sizeof(int)*5 + sizeof(unsigned long)*32 + sizeof(unsigned char)*112);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _cookey(const unsigned long *raw1, unsigned long *keyout)
|
||||
#else
|
||||
static void cookey(const unsigned long *raw1, unsigned long *keyout)
|
||||
#endif
|
||||
{
|
||||
unsigned long *cook;
|
||||
const unsigned long *raw0;
|
||||
unsigned long dough[32];
|
||||
int i;
|
||||
|
||||
cook = dough;
|
||||
for(i=0; i < 16; i++, raw1++)
|
||||
{
|
||||
raw0 = raw1++;
|
||||
*cook = (*raw0 & 0x00fc0000L) << 6;
|
||||
*cook |= (*raw0 & 0x00000fc0L) << 10;
|
||||
*cook |= (*raw1 & 0x00fc0000L) >> 10;
|
||||
*cook++ |= (*raw1 & 0x00000fc0L) >> 6;
|
||||
*cook = (*raw0 & 0x0003f000L) << 12;
|
||||
*cook |= (*raw0 & 0x0000003fL) << 16;
|
||||
*cook |= (*raw1 & 0x0003f000L) >> 4;
|
||||
*cook++ |= (*raw1 & 0x0000003fL);
|
||||
}
|
||||
|
||||
memcpy(keyout, dough, sizeof dough);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void cookey(const unsigned long *raw1, unsigned long *keyout)
|
||||
{
|
||||
_cookey(raw1, keyout);
|
||||
burn_stack(sizeof(unsigned long *) * 2 + sizeof(unsigned long)*32 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CLEAN_STACK
|
||||
static void desfunc(unsigned long *block, const unsigned long *keys)
|
||||
#else
|
||||
static void _desfunc(unsigned long *block, const unsigned long *keys)
|
||||
#endif
|
||||
{
|
||||
unsigned long fval, work, right, leftt;
|
||||
int round;
|
||||
|
||||
leftt = block[0];
|
||||
right = block[1];
|
||||
|
||||
work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
|
||||
right ^= work;
|
||||
leftt ^= (work << 4);
|
||||
|
||||
work = ((leftt >> 16) ^ right) & 0x0000ffffL;
|
||||
right ^= work;
|
||||
leftt ^= (work << 16);
|
||||
|
||||
work = ((right >> 2) ^ leftt) & 0x33333333L;
|
||||
leftt ^= work;
|
||||
right ^= (work << 2);
|
||||
|
||||
work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
|
||||
leftt ^= work;
|
||||
right ^= (work << 8);
|
||||
|
||||
right = ((right << 1) | ((right >> 31) & 1L)) & 0xFFFFFFFFL;
|
||||
work = (leftt ^ right) & 0xaaaaaaaaL;
|
||||
|
||||
leftt ^= work;
|
||||
right ^= work;
|
||||
leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
|
||||
|
||||
for( round = 0; round < 8; round++)
|
||||
{
|
||||
work = ((right << 28) | (right >> 4)) ^ *keys++;
|
||||
fval = SP7[ work & 0x3fL]
|
||||
| SP5[(work >> 8) & 0x3fL]
|
||||
| SP3[(work >> 16) & 0x3fL]
|
||||
| SP1[(work >> 24) & 0x3fL];
|
||||
work = right ^ *keys++;
|
||||
fval |= SP8[ work & 0x3fL]
|
||||
| SP6[(work >> 8) & 0x3fL]
|
||||
| SP4[(work >> 16) & 0x3fL]
|
||||
| SP2[(work >> 24) & 0x3fL];
|
||||
leftt ^= fval;
|
||||
|
||||
work = ((leftt << 28) | (leftt >> 4)) ^ *keys++;
|
||||
fval = SP7[ work & 0x3fL]
|
||||
| SP5[(work >> 8) & 0x3fL]
|
||||
| SP3[(work >> 16) & 0x3fL]
|
||||
| SP1[(work >> 24) & 0x3fL];
|
||||
work = leftt ^ *keys++;
|
||||
fval |= SP8[ work & 0x3fL]
|
||||
| SP6[(work >> 8) & 0x3fL]
|
||||
| SP4[(work >> 16) & 0x3fL]
|
||||
| SP2[(work >> 24) & 0x3fL];
|
||||
right ^= fval;
|
||||
}
|
||||
right = (right << 31) | (right >> 1);
|
||||
work = (leftt ^ right) & 0xaaaaaaaaL;
|
||||
leftt ^= work;
|
||||
right ^= work;
|
||||
leftt = (leftt << 31) | (leftt >> 1);
|
||||
work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
|
||||
right ^= work;
|
||||
leftt ^= (work << 8);
|
||||
// --
|
||||
work = ((leftt >> 2) ^ right) & 0x33333333L;
|
||||
right ^= work;
|
||||
leftt ^= (work << 2);
|
||||
work = ((right >> 16) ^ leftt) & 0x0000ffffL;
|
||||
leftt ^= work;
|
||||
right ^= (work << 16);
|
||||
work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
|
||||
leftt ^= work;
|
||||
right ^= (work << 4);
|
||||
|
||||
block[0] = right;
|
||||
block[1] = leftt;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void desfunc(unsigned long *block, const unsigned long *keys)
|
||||
{
|
||||
_desfunc(block, keys);
|
||||
burn_stack(sizeof(unsigned long) * 4 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if (num_rounds != 0 && num_rounds != 16) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (keylen != 8) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
deskey(key, EN0, skey->des.ek);
|
||||
deskey(key, DE1, skey->des.dk);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if( num_rounds != 0 && num_rounds != 16) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (keylen != 24) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
deskey(key, EN0, skey->des3.ek[0]);
|
||||
deskey(key+8, DE1, skey->des3.ek[1]);
|
||||
deskey(key+16, EN0, skey->des3.ek[2]);
|
||||
|
||||
deskey(key, DE1, skey->des3.dk[2]);
|
||||
deskey(key+8, EN0, skey->des3.dk[1]);
|
||||
deskey(key+16, DE1, skey->des3.dk[0]);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
{
|
||||
unsigned long work[2];
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
LOAD32H(work[0], pt+0);
|
||||
LOAD32H(work[1], pt+4);
|
||||
desfunc(work, key->des.ek);
|
||||
STORE32H(work[0],ct+0);
|
||||
STORE32H(work[1],ct+4);
|
||||
}
|
||||
|
||||
void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
{
|
||||
unsigned long work[2];
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
LOAD32H(work[0], ct+0);
|
||||
LOAD32H(work[1], ct+4);
|
||||
desfunc(work, key->des.dk);
|
||||
STORE32H(work[0],pt+0);
|
||||
STORE32H(work[1],pt+4);
|
||||
}
|
||||
|
||||
void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
{
|
||||
unsigned long work[2];
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
LOAD32H(work[0], pt+0);
|
||||
LOAD32H(work[1], pt+4);
|
||||
desfunc(work, key->des3.ek[0]);
|
||||
desfunc(work, key->des3.ek[1]);
|
||||
desfunc(work, key->des3.ek[2]);
|
||||
STORE32H(work[0],ct+0);
|
||||
STORE32H(work[1],ct+4);
|
||||
}
|
||||
|
||||
void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
{
|
||||
unsigned long work[2];
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
LOAD32H(work[0], ct+0);
|
||||
LOAD32H(work[1], ct+4);
|
||||
desfunc(work, key->des3.dk[0]);
|
||||
desfunc(work, key->des3.dk[1]);
|
||||
desfunc(work, key->des3.dk[2]);
|
||||
STORE32H(work[0],pt+0);
|
||||
STORE32H(work[1],pt+4);
|
||||
}
|
||||
|
||||
int des_test(void)
|
||||
{
|
||||
int errno;
|
||||
static const struct des_test_case {
|
||||
int num, mode; // mode 1 = encrypt
|
||||
unsigned char key[8], txt[8], out[8];
|
||||
} cases[] = {
|
||||
{ 1, 1, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 } },
|
||||
{ 2, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 },
|
||||
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ 3, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 },
|
||||
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ 4, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA },
|
||||
{ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ 5, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F },
|
||||
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ 6, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 },
|
||||
{ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ 7, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF },
|
||||
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ 8, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F },
|
||||
{ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ 9, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 },
|
||||
{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{10, 1, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A },
|
||||
{ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
|
||||
{ 1, 0, { 0x10, 0x31, 0x6E, 0x02, 0x8C, 0x8F, 0x3B, 0x4A },
|
||||
{ 0x82, 0xDC, 0xBA, 0xFB, 0xDE, 0xAB, 0x66, 0x02 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } },
|
||||
{ 2, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x95, 0xF8, 0xA5, 0xE5, 0xDD, 0x31, 0xD9, 0x00 } },
|
||||
{ 3, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0xDD, 0x7F, 0x12, 0x1C, 0xA5, 0x01, 0x56, 0x19 } },
|
||||
{ 4, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x2E, 0x86, 0x53, 0x10, 0x4F, 0x38, 0x34, 0xEA } },
|
||||
{ 5, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x4B, 0xD3, 0x88, 0xFF, 0x6C, 0xD8, 0x1D, 0x4F } },
|
||||
{ 6, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x20, 0xB9, 0xE7, 0x67, 0xB2, 0xFB, 0x14, 0x56 } },
|
||||
{ 7, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x55, 0x57, 0x93, 0x80, 0xD7, 0x71, 0x38, 0xEF } },
|
||||
{ 8, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x6C, 0xC5, 0xDE, 0xFA, 0xAF, 0x04, 0x51, 0x2F } },
|
||||
{ 9, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x0D, 0x9F, 0x27, 0x9B, 0xA5, 0xD8, 0x72, 0x60 } },
|
||||
{10, 0, { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 },
|
||||
{ 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0xD9, 0x03, 0x1B, 0x02, 0x71, 0xBD, 0x5A, 0x0A } }
|
||||
|
||||
/*** more test cases you could add if you are not convinced (the above test cases aren't really too good):
|
||||
|
||||
key plaintext ciphertext
|
||||
0000000000000000 0000000000000000 8CA64DE9C1B123A7
|
||||
FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF 7359B2163E4EDC58
|
||||
3000000000000000 1000000000000001 958E6E627A05557B
|
||||
1111111111111111 1111111111111111 F40379AB9E0EC533
|
||||
0123456789ABCDEF 1111111111111111 17668DFC7292532D
|
||||
1111111111111111 0123456789ABCDEF 8A5AE1F81AB8F2DD
|
||||
0000000000000000 0000000000000000 8CA64DE9C1B123A7
|
||||
FEDCBA9876543210 0123456789ABCDEF ED39D950FA74BCC4
|
||||
7CA110454A1A6E57 01A1D6D039776742 690F5B0D9A26939B
|
||||
0131D9619DC1376E 5CD54CA83DEF57DA 7A389D10354BD271
|
||||
07A1133E4A0B2686 0248D43806F67172 868EBB51CAB4599A
|
||||
3849674C2602319E 51454B582DDF440A 7178876E01F19B2A
|
||||
04B915BA43FEB5B6 42FD443059577FA2 AF37FB421F8C4095
|
||||
0113B970FD34F2CE 059B5E0851CF143A 86A560F10EC6D85B
|
||||
0170F175468FB5E6 0756D8E0774761D2 0CD3DA020021DC09
|
||||
43297FAD38E373FE 762514B829BF486A EA676B2CB7DB2B7A
|
||||
07A7137045DA2A16 3BDD119049372802 DFD64A815CAF1A0F
|
||||
04689104C2FD3B2F 26955F6835AF609A 5C513C9C4886C088
|
||||
37D06BB516CB7546 164D5E404F275232 0A2AEEAE3FF4AB77
|
||||
1F08260D1AC2465E 6B056E18759F5CCA EF1BF03E5DFA575A
|
||||
584023641ABA6176 004BD6EF09176062 88BF0DB6D70DEE56
|
||||
025816164629B007 480D39006EE762F2 A1F9915541020B56
|
||||
49793EBC79B3258F 437540C8698F3CFA 6FBF1CAFCFFD0556
|
||||
4FB05E1515AB73A7 072D43A077075292 2F22E49BAB7CA1AC
|
||||
49E95D6D4CA229BF 02FE55778117F12A 5A6B612CC26CCE4A
|
||||
018310DC409B26D6 1D9D5C5018F728C2 5F4C038ED12B2E41
|
||||
1C587F1C13924FEF 305532286D6F295A 63FAC0D034D9F793
|
||||
0101010101010101 0123456789ABCDEF 617B3A0CE8F07100
|
||||
1F1F1F1F0E0E0E0E 0123456789ABCDEF DB958605F8C8C606
|
||||
E0FEE0FEF1FEF1FE 0123456789ABCDEF EDBFD1C66C29CCC7
|
||||
0000000000000000 FFFFFFFFFFFFFFFF 355550B2150E2451
|
||||
FFFFFFFFFFFFFFFF 0000000000000000 CAAAAF4DEAF1DBAE
|
||||
0123456789ABCDEF 0000000000000000 D5D44FF720683D0D
|
||||
FEDCBA9876543210 FFFFFFFFFFFFFFFF 2A2BB008DF97C2F2
|
||||
|
||||
http://www.ecs.soton.ac.uk/~prw99r/ez438/vectors.txt
|
||||
***/
|
||||
};
|
||||
int i, failed=0;
|
||||
unsigned char out[8];
|
||||
symmetric_key des;
|
||||
|
||||
for(i=0; i < (int)(sizeof(cases)/sizeof(cases[0])); i++)
|
||||
{
|
||||
if ((errno = des_setup(cases[i].key, 8, 0, &des)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
if (cases[i].mode) {
|
||||
des_ecb_encrypt(cases[i].txt, out, &des);
|
||||
} else {
|
||||
des_ecb_decrypt(cases[i].txt, out, &des);
|
||||
}
|
||||
|
||||
if (memcmp(cases[i].out, out, sizeof out) != 0) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("DES test #%d failed!\n", cases[i].num);
|
||||
|
||||
printf( "got: ");
|
||||
for (j=0; j < (int)sizeof out; j++) {
|
||||
printf("%02x ", out[j] & 0xff);
|
||||
}
|
||||
printf("\nwanted: ");
|
||||
for(j=0; j < (int)sizeof out; j++) {
|
||||
printf("%02x ", cases[i].out[j] & 0xff);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
if(failed > 0) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int des3_test(void)
|
||||
{
|
||||
unsigned char key[24], pt[8], ct[8], tmp[8];
|
||||
symmetric_key skey;
|
||||
int x, errno;
|
||||
|
||||
if ((errno = des_test()) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
for (x = 0; x < 8; x++) {
|
||||
pt[x] = x;
|
||||
}
|
||||
|
||||
for (x = 0; x < 24; x++) {
|
||||
key[x] = x;
|
||||
}
|
||||
|
||||
if ((errno = des3_setup(key, 24, 0, &skey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
des3_ecb_encrypt(pt, ct, &skey);
|
||||
des3_ecb_decrypt(ct, tmp, &skey);
|
||||
|
||||
if (memcmp(pt, tmp, 8)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int des_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
if(*desired_keysize < 8) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
*desired_keysize = 8;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int des3_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
if(*desired_keysize < 24) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
*desired_keysize = 24;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
489
dh.c
Normal file
489
dh.c
Normal file
@ -0,0 +1,489 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef MDH
|
||||
|
||||
static const struct {
|
||||
int size;
|
||||
char *name, *base, *prime;
|
||||
} sets[] = {
|
||||
#ifdef DH512
|
||||
{
|
||||
64,
|
||||
"DH-512",
|
||||
"3",
|
||||
"1793360119486011337223707056216512835002732007217684422667328794587337075124"
|
||||
"5439587792371960615073855669274087805055507977323024886880985062002853331424"
|
||||
"203"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH768
|
||||
{
|
||||
96,
|
||||
"DH-768",
|
||||
"2",
|
||||
"2893527720709661239493896562339544088620375736490408468011883030469939904368"
|
||||
"0860923364582982212457078989335831907131881773994018526277492109945959747917"
|
||||
"8279025394653904396221302707492255957231214118178743427870878320796645901947"
|
||||
"9487"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1024
|
||||
{
|
||||
128,
|
||||
"DH-1024",
|
||||
"2",
|
||||
"3477431594398766260792527967974222231775354473882066076071816639030459075912"
|
||||
"0194047822362172211817327089848758298713770865641434468581617942085516098634"
|
||||
"0457973820182883508387588163122354089264395604796675278966117567294812714812"
|
||||
"7968205965648764507160662831267200108590414847865290564578963676831229604111"
|
||||
"36319"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1280
|
||||
{
|
||||
160,
|
||||
"DH-1280",
|
||||
"2",
|
||||
"2618298020488323341377089635550383393554460131909411928885489146533597039863"
|
||||
"5379029297773089246854323581071445272213255646852180580463169755159411503866"
|
||||
"4190218001872082125570169842848154404911652982668791288605239288293106162305"
|
||||
"7236093554796242806887062958692596037823904832542385180840218330924392268465"
|
||||
"0197244314233248991982159235832322194332167923655574170280697353556560854901"
|
||||
"280047"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1536
|
||||
{
|
||||
192,
|
||||
"DH-1536",
|
||||
"3",
|
||||
"2992593690703251306835100868059076484222548092264611010748654597096560864537"
|
||||
"1704684310938824733433085888971827086341295918925237859522548192211945291282"
|
||||
"1170570153374563548621496076860061698150233114892317627457427359445435608693"
|
||||
"5625000902194809114890745455404045166957722404567939575618007347432055137282"
|
||||
"3291711752537781447636541738638119983678441628437171377508654097130147131310"
|
||||
"9209393805685590941710151477648542896503595482724205166251069428524927527085"
|
||||
"2602467"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1792
|
||||
{
|
||||
224,
|
||||
"DH-1792",
|
||||
"2",
|
||||
"3210090394251532205679207425273650879078185529033544241951292722086520015900"
|
||||
"0402371844205168176419829949232601235193754977706171541009393172204470047690"
|
||||
"6659627844880912479392592056697278305733615369406596661203184035142652643118"
|
||||
"1379603333858737848321053048184938839622944591194935387992479717305577175500"
|
||||
"2554620614907177847128950276247571809502831255425929468853285490357704941968"
|
||||
"3407102520889651917659577334897408316217748346860775479727332331727022096550"
|
||||
"7718799868459391361770854814013613619048768630587629568449528005570971478547"
|
||||
"34960319"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH2048
|
||||
{
|
||||
256,
|
||||
"DH-2048",
|
||||
"2",
|
||||
"4726642895635639316469736509812041897640060270607231273592407174543853221823"
|
||||
"7979333351774907308168340693326687317443721193266215155735814510792148768576"
|
||||
"4984911991227443513994894535335532038333186916782632419417062569961974604240"
|
||||
"2901241901263467186228353234265630967717360250949841797609150915436003989316"
|
||||
"5037637034737020327399910409885798185771003505320583967737293415979917317338"
|
||||
"9858373857347474783642420203804168920566508414708692945275435973492502995396"
|
||||
"8243060517332102902655554683247304860032703684578197028928889831788842751736"
|
||||
"4945316709081173840186150794397479045034008257793436817683392375274635794835"
|
||||
"245695887"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH2560
|
||||
{
|
||||
320,
|
||||
"DH-2560",
|
||||
"3",
|
||||
"4364638085059577685748948703943497396233464406019459611612544400721432981520"
|
||||
"4010567649104824811014627875285783993051576616744140702150122992472133564455"
|
||||
"7342265864606569000117714935185566842453630868849121480179691838399545644365"
|
||||
"5711067577313173717585579907818806913366955847993133136872874688941488237617"
|
||||
"8558298254958618375680644901754262226787427510387748147553499120184991222267"
|
||||
"0102069951687572917937634467778042874315463238062009202992087620963771759666"
|
||||
"4482665328580794026699200252242206134194410697184828373996126449788399252071"
|
||||
"0987084027819404215874884544513172913711709852902888677006373648742061314404"
|
||||
"5836803985635654192482395882603511950547826439092832800532152534003936926017"
|
||||
"6124466061356551464456206233957889787267447285030586700468858762515271223502"
|
||||
"75750995227"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH3072
|
||||
{
|
||||
384,
|
||||
"DH-3072",
|
||||
"2",
|
||||
"1142416747335183639807830604262436227795642944052113706188970261176634876069"
|
||||
"2206243140413411077394583180726863277012016602279290144126785129569474909173"
|
||||
"5847898223419867427192303319460727303195559844849117167970588759054009995043"
|
||||
"0587724584911968750902323279027363746682105257685923245298206183100977078603"
|
||||
"1785669030271542286603956118755585683996118896215213488875253101894663403069"
|
||||
"6777459483058938495054342017637452328957807119724320113448575216910178963168"
|
||||
"6140320644942133224365885545343578400651720289418164056243357539082138421096"
|
||||
"0117518650374602256601091379644034244332285065935413233557998331562749140202"
|
||||
"9658442193362989700115138825649355387042894469683222814519074873620465114612"
|
||||
"2132979989735099337056069750580968643878203623537213701573130477907243026098"
|
||||
"6460269894522159103008260495503005267165927542949439526272736586626709581721"
|
||||
"0321895327263896436255906801057848442461527026701693042037830722750891947548"
|
||||
"89511973916207"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH4096
|
||||
{
|
||||
512,
|
||||
"DH-4096",
|
||||
"3",
|
||||
"1214855636816562637502584060163403830270705000634713483015101384881871978446"
|
||||
"8012247985361554068958233050354675916325310675478909486951171720769542207270"
|
||||
"7568804875102242119871203284889005635784597424656074834791863005085393369779"
|
||||
"2254955890439720297560693579400297062396904306270145886830719309296352765295"
|
||||
"7121830407731464190228751653827780070401099576097395898755908857011261979060"
|
||||
"6362013395489321661267883850754077713843779770560245371955901763398648664952"
|
||||
"3611975865005712371194067612263330335590526176087004421363598470302731349138"
|
||||
"7732059014477046821815179040647356365184624522427916765417252923789255682968"
|
||||
"5801015185232631677751193503753101741391050692192245066693320227848902452126"
|
||||
"3798482237150056835746454842662048692127173834433089016107854491097456725016"
|
||||
"3277096631997382384421648431471327891537255132571679155551620949708535844479"
|
||||
"9312548860769600816980737473671129700747381225627224548940589847029717873802"
|
||||
"9484459690836250560495461579533254473316340608217876781986188705928270735695"
|
||||
"7528308255279638383554197625162460286802809880204019145518254873499903069763"
|
||||
"0409310938445143881325121105159739212749146489879740678917545306796007200859"
|
||||
"0614886532333015881171367104445044718144312416815712216611576221546455968770"
|
||||
"801413440778423979"
|
||||
},
|
||||
#endif
|
||||
{
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
static int is_valid_idx(int n)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; sets[x].size; x++);
|
||||
if ((n < 0) || (n >= x)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dh_test(void)
|
||||
{
|
||||
mp_int p, g, tmp;
|
||||
int x, res, primality;
|
||||
|
||||
if (mp_init_multi(&p, &g, &tmp, NULL) != MP_OKAY) { goto error; }
|
||||
|
||||
for (x = 0; sets[x].size; x++) {
|
||||
#if 0
|
||||
printf("dh_test():testing size %d-bits\n", sets[x].size * 8);
|
||||
#endif
|
||||
/* see if g^((p-1)/2) == 1 mod p. */
|
||||
if (mp_read_radix(&g, sets[x].base, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&p, sets[x].prime, 10) != MP_OKAY) { goto error; }
|
||||
|
||||
/* ensure p is prime */
|
||||
if ((res = is_prime(&p, &primality)) != CRYPT_OK) { goto done; }
|
||||
if (primality == 0) {
|
||||
res = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (mp_sub_d(&p, 1, &tmp) != MP_OKAY) { goto error; }
|
||||
if (mp_div_2(&tmp, &tmp) != MP_OKAY) { goto error; }
|
||||
|
||||
/* ensure (p-1)/2 is prime */
|
||||
if ((res = is_prime(&tmp, &primality)) != CRYPT_OK) { goto done; }
|
||||
if (primality == 0) {
|
||||
res = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* now see if g^((p-1)/2) mod p is in fact 1 */
|
||||
if (mp_exptmod(&g, &tmp, &p, &tmp) != MP_OKAY) { goto error; }
|
||||
if (mp_cmp_d(&tmp, 1)) {
|
||||
res = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&tmp, &g, &p, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
void dh_sizes(int *low, int *high)
|
||||
{
|
||||
int x;
|
||||
_ARGCHK(low != NULL);
|
||||
_ARGCHK(high != NULL);
|
||||
*low = INT_MAX;
|
||||
*high = 0;
|
||||
for (x = 0; sets[x].size; x++) {
|
||||
if (*low > sets[x].size) *low = sets[x].size;
|
||||
if (*high < sets[x].size) *high = sets[x].size;
|
||||
}
|
||||
}
|
||||
|
||||
int dh_get_size(dh_key *key)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
if (is_valid_idx(key->idx))
|
||||
return sets[key->idx].size;
|
||||
else
|
||||
return INT_MAX; /* large value that would cause dh_make_key() to fail */
|
||||
}
|
||||
|
||||
int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
|
||||
{
|
||||
unsigned char buf[768];
|
||||
unsigned long x;
|
||||
mp_int p, g;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* good prng? */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* find key size */
|
||||
for (x = 0; (keysize > sets[x].size) && (sets[x].size); x++);
|
||||
#ifdef FAST_PK
|
||||
keysize = MIN(sets[x].size, 32);
|
||||
#else
|
||||
keysize = sets[x].size;
|
||||
#endif
|
||||
|
||||
if (sets[x].size == 0) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
key->idx = x;
|
||||
|
||||
/* make up random string */
|
||||
buf[0] = 0;
|
||||
if (prng_descriptor[wprng].read(buf+1, keysize, prng) != (unsigned long)keysize) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* init parameters */
|
||||
if (mp_init_multi(&g, &p, &key->x, &key->y, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
if (mp_read_radix(&g, sets[x].base, 10) != MP_OKAY) { goto error2; }
|
||||
if (mp_read_radix(&p, sets[x].prime, 10) != MP_OKAY) { goto error2; }
|
||||
|
||||
/* load the x value */
|
||||
mp_read_raw(&key->x, buf, keysize+1);
|
||||
if (mp_exptmod(&g, &key->x, &p, &key->y) != MP_OKAY) { goto error2; }
|
||||
key->type = PK_PRIVATE;
|
||||
|
||||
/* free up ram */
|
||||
res = CRYPT_OK;
|
||||
goto done2;
|
||||
error2:
|
||||
res = CRYPT_MEM;
|
||||
mp_clear_multi(&key->x, &key->y, NULL);
|
||||
done2:
|
||||
mp_clear_multi(&p, &g, NULL);
|
||||
zeromem(buf, sizeof(buf));
|
||||
return res;
|
||||
}
|
||||
|
||||
void dh_free(dh_key *key)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
mp_clear_multi(&key->x, &key->y, NULL);
|
||||
}
|
||||
|
||||
#define OUTPUT_BIGNUM(num, buf2, y, z) \
|
||||
{ \
|
||||
z = mp_raw_size(num); \
|
||||
STORE32L(z, buf2+y); \
|
||||
y += 4; \
|
||||
mp_toraw(num, buf2+y); \
|
||||
y += z; \
|
||||
}
|
||||
|
||||
|
||||
#define INPUT_BIGNUM(num, in, x, y) \
|
||||
{ \
|
||||
/* load value */ \
|
||||
LOAD32L(x, in+y); \
|
||||
y += 4; \
|
||||
\
|
||||
/* sanity check... */ \
|
||||
if (x > 1024) { \
|
||||
errno = CRYPT_ERROR; \
|
||||
goto error; \
|
||||
} \
|
||||
\
|
||||
/* load it */ \
|
||||
if (mp_read_raw(num, (unsigned char *)in+y, x) != MP_OKAY) {\
|
||||
return CRYPT_MEM; \
|
||||
goto error; \
|
||||
} \
|
||||
y += x; \
|
||||
}
|
||||
|
||||
|
||||
int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key)
|
||||
{
|
||||
unsigned char buf2[1536];
|
||||
unsigned long y, z;
|
||||
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* header */
|
||||
buf2[y++] = type;
|
||||
buf2[y++] = key->idx;
|
||||
|
||||
/* export y */
|
||||
OUTPUT_BIGNUM(&key->y, buf2, y, z);
|
||||
|
||||
if (type == PK_PRIVATE) {
|
||||
/* export x */
|
||||
OUTPUT_BIGNUM(&key->x, buf2, y, z);
|
||||
}
|
||||
|
||||
/* check for overflow */
|
||||
if (*outlen < y) {
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf2, sizeof(buf2));
|
||||
#endif
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(buf2, PACKET_SECT_DH, PACKET_SUB_KEY, y);
|
||||
|
||||
/* output it */
|
||||
*outlen = y;
|
||||
memcpy(out, buf2, y);
|
||||
|
||||
/* clear mem */
|
||||
zeromem(buf2, sizeof(buf2));
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int dh_import(const unsigned char *in, dh_key *key)
|
||||
{
|
||||
long x, y;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check type byte */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* init */
|
||||
if (mp_init_multi(&key->x, &key->y, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
y = PACKET_SIZE;
|
||||
key->type = in[y++];
|
||||
key->idx = in[y++];
|
||||
|
||||
/* type check both values */
|
||||
if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) {
|
||||
errno = CRYPT_PK_TYPE_MISMATCH;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* is the key idx valid? */
|
||||
if (!is_valid_idx(key->idx)) {
|
||||
errno = CRYPT_PK_TYPE_MISMATCH;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* load public value g^x mod p*/
|
||||
INPUT_BIGNUM(&key->y, in, x, y);
|
||||
|
||||
if (key->type == PK_PRIVATE) {
|
||||
INPUT_BIGNUM(&key->x, in, x, y);
|
||||
}
|
||||
return CRYPT_OK;
|
||||
error:
|
||||
mp_clear_multi(&key->y, &key->x, NULL);
|
||||
return errno;
|
||||
}
|
||||
|
||||
int dh_shared_secret(dh_key *private_key, dh_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
mp_int tmp, p;
|
||||
unsigned long x;
|
||||
int res;
|
||||
|
||||
_ARGCHK(private_key != NULL);
|
||||
_ARGCHK(public_key != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* types valid? */
|
||||
if (private_key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* same idx? */
|
||||
if (private_key->idx != public_key->idx) {
|
||||
return CRYPT_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
/* compute y^x mod p */
|
||||
if (mp_init_multi(&tmp, &p, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if (mp_read_radix(&p, sets[private_key->idx].prime, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_exptmod(&public_key->y, &private_key->x, &p, &tmp) != MP_OKAY) { goto error; }
|
||||
|
||||
/* enough space for output? */
|
||||
x = mp_raw_size(&tmp);
|
||||
if (*outlen < x) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
mp_toraw(&tmp, out);
|
||||
*outlen = x;
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&p, &tmp, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
#include "dh_sys.c"
|
||||
|
||||
#endif
|
||||
|
774
dh_sys.c
Normal file
774
dh_sys.c
Normal file
@ -0,0 +1,774 @@
|
||||
#ifdef PK_PACKET
|
||||
|
||||
int dh_encrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int cipher, int hash,
|
||||
dh_key *key)
|
||||
{
|
||||
unsigned char pub_expt[1536], dh_shared[1536], IV[MAXBLOCKSIZE], skey[MAXBLOCKSIZE];
|
||||
dh_key pubkey;
|
||||
unsigned long x, y, z, hashsize, blocksize, pubkeysize;
|
||||
int keysize, errno;
|
||||
symmetric_CTR ctr;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check that wprng/cipher/hash are not invalid */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* make a random key and export the public copy */
|
||||
if ((errno = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
pubkeysize = sizeof(pub_expt);
|
||||
if ((errno = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
dh_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* now check if the out buffer is big enough */
|
||||
if (*outlen < (10 + PACKET_SIZE + pubkeysize + cipher_descriptor[cipher].block_length + len)) {
|
||||
dh_free(&pubkey);
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* make random key */
|
||||
blocksize = cipher_descriptor[cipher].block_length;
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
keysize = hashsize;
|
||||
if ((errno = cipher_descriptor[cipher].keysize(&keysize)) != CRYPT_OK) {
|
||||
dh_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
|
||||
x = sizeof(dh_shared);
|
||||
if ((errno = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) {
|
||||
dh_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
dh_free(&pubkey);
|
||||
|
||||
z = sizeof(skey);
|
||||
if ((errno = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* make up IV */
|
||||
if (prng_descriptor[wprng].read(IV, cipher_descriptor[cipher].block_length, prng) !=
|
||||
cipher_descriptor[cipher].block_length) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* setup CTR mode */
|
||||
if ((errno = ctr_start(cipher, IV, skey, keysize, 0, &ctr)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* output header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* size of cipher name and the name itself */
|
||||
out[y++] = cipher_descriptor[cipher].ID;
|
||||
|
||||
/* size of hash name and the name itself */
|
||||
out[y++] = hash_descriptor[hash].ID;
|
||||
|
||||
/* length of DH pubkey and the key itself */
|
||||
STORE32L(pubkeysize, out+y);
|
||||
y += 4;
|
||||
for (x = 0; x < pubkeysize; x++, y++) {
|
||||
out[y] = pub_expt[x];
|
||||
}
|
||||
|
||||
/* cipher IV */
|
||||
for (x = 0; x < blocksize; x++, y++) {
|
||||
out[y] = IV[x];
|
||||
}
|
||||
|
||||
/* length of ciphertext */
|
||||
STORE32L(len, out+y);
|
||||
y += 4;
|
||||
|
||||
/* encrypt the message */
|
||||
if ((errno = ctr_encrypt(in, out+y, len, &ctr)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
y += len;
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENCRYPTED, y);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(pub_expt, sizeof(pub_expt));
|
||||
zeromem(dh_shared, sizeof(dh_shared));
|
||||
zeromem(skey, sizeof(skey));
|
||||
zeromem(IV, sizeof(IV));
|
||||
zeromem(&ctr, sizeof(ctr));
|
||||
#endif
|
||||
*outlen = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int dh_decrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
dh_key *key)
|
||||
{
|
||||
unsigned char shared_secret[1536], skey[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z, res, hashsize, blocksize;
|
||||
int hash, cipher, keysize, errno;
|
||||
dh_key pubkey;
|
||||
symmetric_CTR ctr;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* is header correct? */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENCRYPTED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* now lets get the cipher name */
|
||||
y = PACKET_SIZE;
|
||||
cipher = find_cipher_id(in[y++]);
|
||||
if (cipher == -1) {
|
||||
return CRYPT_INVALID_CIPHER;
|
||||
}
|
||||
|
||||
/* now lets get the hash name */
|
||||
hash = find_hash_id(in[y++]);
|
||||
if (hash == -1) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* common values */
|
||||
blocksize = cipher_descriptor[cipher].block_length;
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
keysize = hashsize;
|
||||
if ((errno = cipher_descriptor[cipher].keysize(&keysize)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* get public key */
|
||||
LOAD32L(x, in+y);
|
||||
y += 4;
|
||||
if ((errno = dh_import(in+y, &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
y += x;
|
||||
|
||||
/* make shared key */
|
||||
x = sizeof(shared_secret);
|
||||
if ((errno = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
|
||||
dh_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
dh_free(&pubkey);
|
||||
|
||||
z = sizeof(skey);
|
||||
if ((errno = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* setup CTR mode */
|
||||
if ((errno = ctr_start(cipher, in+y, skey, keysize, 0, &ctr)) != CRYPT_OK) {
|
||||
res = errno;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* skip over the IV */
|
||||
y += blocksize;
|
||||
|
||||
/* get length */
|
||||
LOAD32L(len,in+y);
|
||||
y += 4;
|
||||
|
||||
/* buffer overflow? */
|
||||
if (len > *outlen) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* decrypt message */
|
||||
if ((errno = ctr_decrypt(in+y, out, len, &ctr)) != CRYPT_OK) {
|
||||
res = errno;
|
||||
goto done;
|
||||
}
|
||||
*outlen = len;
|
||||
|
||||
res = CRYPT_OK;
|
||||
done:
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(shared_secret, sizeof(shared_secret));
|
||||
zeromem(skey, sizeof(skey));
|
||||
zeromem(&ctr, sizeof(ctr));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
int dh_sign(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
int hash, prng_state *prng, int wprng,
|
||||
dh_key *key)
|
||||
{
|
||||
mp_int a, b, k, m, g, p, p1, tmp;
|
||||
unsigned char buf[1536], md[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check parameters */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* hash the message */
|
||||
z = sizeof(md) - 1;
|
||||
md[0] = 0;
|
||||
if ((errno = hash_memory(hash, in, inlen, md+1, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* make up a random value k,
|
||||
* since the order of the group is prime
|
||||
* we need not check if gcd(k, r) is 1
|
||||
*/
|
||||
buf[0] = 0;
|
||||
if (prng_descriptor[wprng].read(buf+1, sets[key->idx].size-1, prng) != (unsigned long)(sets[key->idx].size-1)) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* init bignums */
|
||||
if (mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* load k and m */
|
||||
if (mp_read_raw(&m, md, 1+hash_descriptor[hash].hashsize) != MP_OKAY) { goto error; }
|
||||
if (mp_read_raw(&k, buf, sets[key->idx].size) != MP_OKAY) { goto error; }
|
||||
|
||||
/* load g, p and p1 */
|
||||
if (mp_read_radix(&g, sets[key->idx].base, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&p, sets[key->idx].prime, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_sub_d(&p, 1, &p1) != MP_OKAY) { goto error; } /* p1 = p-1 */
|
||||
if (mp_div_2(&p1, &p1) != MP_OKAY) { goto error; } /* p1 = (p-1)/2 */
|
||||
|
||||
/* now get a = g^k mod p */
|
||||
if (mp_exptmod(&g, &k, &p, &a) != MP_OKAY) { goto error; } /* a = g^k mod p */
|
||||
|
||||
/* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */
|
||||
if (mp_invmod(&k, &p1, &k) != MP_OKAY) { goto error; } /* k = 1/k mod p1 */
|
||||
if (mp_mulmod(&a, &key->x, &p1, &tmp) != MP_OKAY) { goto error; } /* tmp = xa */
|
||||
if (mp_submod(&m, &tmp, &p1, &tmp) != MP_OKAY) { goto error; } /* tmp = M - xa */
|
||||
if (mp_mulmod(&k, &tmp, &p1, &b) != MP_OKAY) { goto error; } /* b = (M - xa)/k */
|
||||
|
||||
/* store header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* store length and name of hash */
|
||||
buf[y++] = hash_descriptor[hash].ID; /* store hash ID */
|
||||
|
||||
/* now store them both (a,b) */
|
||||
x = mp_raw_size(&a); /* get raw size of a */
|
||||
STORE32L(x, buf+y); y += 4; /* store size of a */
|
||||
mp_toraw(&a, buf+y); y += x; /* store a itself */
|
||||
|
||||
x = mp_raw_size(&b); /* get raw size of b */
|
||||
STORE32L(x, buf+y); y += 4; /* store size of b */
|
||||
mp_toraw(&b, buf+y); y += x; /* store b itself */
|
||||
|
||||
/* check if size too big */
|
||||
if (*outlen < y) { goto error; }
|
||||
|
||||
/* store header */
|
||||
packet_store_header(buf, PACKET_SECT_DH, PACKET_SUB_SIGNED, y);
|
||||
|
||||
/* store it */
|
||||
memcpy(out, buf, y);
|
||||
*outlen = y;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(md));
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&tmp, &p1, &g, &p, &m, &k, &b, &a, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
int dh_verify(const unsigned char *sig, const unsigned char *msg,
|
||||
unsigned long inlen, int *stat,
|
||||
dh_key *key)
|
||||
{
|
||||
mp_int a, b, p, g, m, tmp;
|
||||
unsigned char md[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z;
|
||||
int hash, res, errno;
|
||||
|
||||
_ARGCHK(sig != NULL);
|
||||
_ARGCHK(msg != NULL);
|
||||
_ARGCHK(stat != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* default to invalid */
|
||||
*stat = 0;
|
||||
|
||||
/* header ok? */
|
||||
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* get hash out of packet */
|
||||
y = PACKET_SIZE;
|
||||
hash = find_hash_id(sig[y++]);
|
||||
|
||||
if (hash == -1) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* hash the message */
|
||||
md[0] = 0;
|
||||
z = sizeof(md) - 1;
|
||||
if ((errno = hash_memory(hash, msg, inlen, md+1, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* init all bignums */
|
||||
if (mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* load a and b */
|
||||
LOAD32L(x, sig+y);
|
||||
y += 4;
|
||||
if (mp_read_raw(&a, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
LOAD32L(x, sig+y);
|
||||
y += 4;
|
||||
if (mp_read_raw(&b, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
/* load p and g */
|
||||
if (mp_read_radix(&p, sets[key->idx].prime, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&g, sets[key->idx].base, 10) != MP_OKAY) { goto error; }
|
||||
|
||||
/* load m */
|
||||
if (mp_read_raw(&m, md, hash_descriptor[hash].hashsize + 1) != MP_OKAY) { goto error; }
|
||||
|
||||
/* find g^m mod p */
|
||||
if (mp_exptmod(&g, &m, &p, &m) != MP_OKAY) { goto error; } /* m = g^m mod p */
|
||||
|
||||
/* find y^a * a^b */
|
||||
if (mp_exptmod(&key->y, &a, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = y^a mod p */
|
||||
if (mp_exptmod(&a, &b, &p, &a) != MP_OKAY) { goto error; } /* a = a^b mod p */
|
||||
if (mp_mulmod(&a, &tmp, &p, &a) != MP_OKAY) { goto error; } /* a = y^a * a^b mod p */
|
||||
|
||||
/* y^a * a^b == g^m ??? */
|
||||
if (mp_cmp(&a, &m) == 0) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&tmp, &m, &g, &p, &b, &a, NULL);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(md));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *len,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
dh_key *key)
|
||||
{
|
||||
unsigned char pub_expt[1536], dh_shared[1536], skey[MAXBLOCKSIZE];
|
||||
dh_key pubkey;
|
||||
unsigned long x, y, z, hashsize, pubkeysize;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(inkey != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(len != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check that wprng/hash are not invalid */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (keylen > hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* make a random key and export the public copy */
|
||||
if ((errno = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
pubkeysize = sizeof(pub_expt);
|
||||
if ((errno = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
dh_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* now check if the out buffer is big enough */
|
||||
if (*len < (9 + PACKET_SIZE + pubkeysize + keylen)) {
|
||||
dh_free(&pubkey);
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* make random key */
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
|
||||
x = sizeof(dh_shared);
|
||||
if ((errno = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) {
|
||||
dh_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
dh_free(&pubkey);
|
||||
|
||||
z = sizeof(skey);
|
||||
if ((errno = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* output header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* size of hash name and the name itself */
|
||||
out[y++] = hash_descriptor[hash].ID;
|
||||
|
||||
/* length of DH pubkey and the key itself */
|
||||
STORE32L(pubkeysize, out+y);
|
||||
y += 4;
|
||||
for (x = 0; x < pubkeysize; x++, y++) {
|
||||
out[y] = pub_expt[x];
|
||||
}
|
||||
|
||||
/* Store the encrypted key */
|
||||
STORE32L(keylen, out+y);
|
||||
y += 4;
|
||||
|
||||
for (x = 0; x < keylen; x++, y++) {
|
||||
out[y] = skey[x] ^ inkey[x];
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY, y);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(pub_expt, sizeof(pub_expt));
|
||||
zeromem(dh_shared, sizeof(dh_shared));
|
||||
zeromem(skey, sizeof(skey));
|
||||
#endif
|
||||
|
||||
*len = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int dh_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, dh_key *key)
|
||||
{
|
||||
unsigned char shared_secret[1536], skey[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z, res, hashsize, keysize;
|
||||
int hash, errno;
|
||||
dh_key pubkey;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(outkey != NULL);
|
||||
_ARGCHK(keylen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* is header correct? */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* now lets get the hash name */
|
||||
y = PACKET_SIZE;
|
||||
hash = find_hash_id(in[y++]);
|
||||
if (hash == -1) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* common values */
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
|
||||
/* get public key */
|
||||
LOAD32L(x, in+y);
|
||||
y += 4;
|
||||
if ((errno = dh_import(in+y, &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
y += x;
|
||||
|
||||
/* make shared key */
|
||||
x = sizeof(shared_secret);
|
||||
if ((errno = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
|
||||
dh_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
dh_free(&pubkey);
|
||||
|
||||
z = sizeof(skey);
|
||||
if ((errno = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* load in the encrypted key */
|
||||
LOAD32L(keysize, in+y);
|
||||
if (keysize > *keylen) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
y += 4;
|
||||
|
||||
*keylen = keysize;
|
||||
|
||||
for (x = 0; x < keysize; x++, y++) {
|
||||
outkey[x] = skey[x] ^ in[y];
|
||||
}
|
||||
|
||||
res = CRYPT_OK;
|
||||
done:
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(shared_secret, sizeof(shared_secret));
|
||||
zeromem(skey, sizeof(skey));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int dh_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, dh_key *key)
|
||||
{
|
||||
mp_int a, b, k, m, g, p, p1, tmp;
|
||||
unsigned char buf[1536], md[MAXBLOCKSIZE];
|
||||
unsigned long x, y;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check parameters */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* hash the message */
|
||||
md[0] = 0;
|
||||
memcpy(md+1, in, MIN(sizeof(md) - 1, inlen));
|
||||
|
||||
/* make up a random value k,
|
||||
* since the order of the group is prime
|
||||
* we need not check if gcd(k, r) is 1
|
||||
*/
|
||||
buf[0] = 0;
|
||||
if (prng_descriptor[wprng].read(buf+1, sets[key->idx].size-1, prng) !=
|
||||
(unsigned long)(sets[key->idx].size-1)) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* init bignums */
|
||||
if (mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* load k and m */
|
||||
if (mp_read_raw(&m, md, 1+MIN(sizeof(md) - 1, inlen)) != MP_OKAY) { goto error; }
|
||||
if (mp_read_raw(&k, buf, sets[key->idx].size) != MP_OKAY) { goto error; }
|
||||
|
||||
/* load g, p and p1 */
|
||||
if (mp_read_radix(&g, sets[key->idx].base, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&p, sets[key->idx].prime, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_sub_d(&p, 1, &p1) != MP_OKAY) { goto error; }
|
||||
if (mp_div_2(&p1, &p1) != MP_OKAY) { goto error; } /* p1 = (p-1)/2 */
|
||||
|
||||
/* now get a = g^k mod p */
|
||||
if (mp_exptmod(&g, &k, &p, &a) != MP_OKAY) { goto error; }
|
||||
|
||||
/* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */
|
||||
if (mp_invmod(&k, &p1, &k) != MP_OKAY) { goto error; } /* k = 1/k mod p1 */
|
||||
if (mp_mulmod(&a, &key->x, &p1, &tmp) != MP_OKAY) { goto error; } /* tmp = xa */
|
||||
if (mp_submod(&m, &tmp, &p1, &tmp) != MP_OKAY) { goto error; } /* tmp = M - xa */
|
||||
if (mp_mulmod(&k, &tmp, &p1, &b) != MP_OKAY) { goto error; } /* b = (M - xa)/k */
|
||||
|
||||
/* store header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* now store them both (a,b) */
|
||||
x = mp_raw_size(&a);
|
||||
STORE32L(x, buf+y); y += 4;
|
||||
mp_toraw(&a, buf+y); y += x;
|
||||
|
||||
x = mp_raw_size(&b);
|
||||
STORE32L(x, buf+y); y += 4;
|
||||
mp_toraw(&b, buf+y); y += x;
|
||||
|
||||
/* check if size too big */
|
||||
if (*outlen < y) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(buf, PACKET_SECT_DH, PACKET_SUB_SIGNED, y);
|
||||
|
||||
/* store it */
|
||||
memcpy(out, buf, y);
|
||||
*outlen = y;
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(md));
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&tmp, &p1, &g, &p, &m, &k, &b, &a, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
int dh_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
unsigned long inlen, int *stat,
|
||||
dh_key *key)
|
||||
{
|
||||
mp_int a, b, p, g, m, tmp;
|
||||
unsigned char md[MAXBLOCKSIZE];
|
||||
unsigned long x, y;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(sig != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
_ARGCHK(stat != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* default to invalid */
|
||||
*stat = 0;
|
||||
|
||||
/* header ok? */
|
||||
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* get hash out of packet */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* hash the message */
|
||||
md[0] = 0;
|
||||
memcpy(md+1, hash, MIN(sizeof(md) - 1, inlen));
|
||||
|
||||
/* init all bignums */
|
||||
if (mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* load a and b */
|
||||
LOAD32L(x, sig+y);
|
||||
y += 4;
|
||||
if (mp_read_raw(&a, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
LOAD32L(x, sig+y);
|
||||
y += 4;
|
||||
if (mp_read_raw(&b, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
/* load p and g */
|
||||
if (mp_read_radix(&p, sets[key->idx].prime, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&g, sets[key->idx].base, 10) != MP_OKAY) { goto error; }
|
||||
|
||||
/* load m */
|
||||
if (mp_read_raw(&m, md, 1+MIN(sizeof(md)-1, inlen)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* find g^m mod p */
|
||||
if (mp_exptmod(&g, &m, &p, &m) != MP_OKAY) { goto error; } /* m = g^m mod p */
|
||||
|
||||
/* find y^a * a^b */
|
||||
if (mp_exptmod(&key->y, &a, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = y^a mod p */
|
||||
if (mp_exptmod(&a, &b, &p, &a) != MP_OKAY) { goto error; } /* a = a^b mod p */
|
||||
if (mp_mulmod(&a, &tmp, &p, &a) != MP_OKAY) { goto error; } /* a = y^a * a^b mod p */
|
||||
|
||||
/* y^a * a^b == g^m ??? */
|
||||
if (mp_cmp(&a, &m) == 0) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&tmp, &m, &g, &p, &b, &a, NULL);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(md));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
49
ecb.c
Normal file
49
ecb.c
Normal file
@ -0,0 +1,49 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef ECB
|
||||
|
||||
int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb)
|
||||
{
|
||||
int errno;
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(ecb != NULL);
|
||||
|
||||
if ((errno = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
ecb->cipher = cipher;
|
||||
ecb->blocklen = cipher_descriptor[cipher].block_length;
|
||||
return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ecb->key);
|
||||
}
|
||||
|
||||
int ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ECB *ecb)
|
||||
{
|
||||
int errno;
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(ecb != NULL);
|
||||
|
||||
if ((errno = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb)
|
||||
{
|
||||
int errno;
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(ecb != NULL);
|
||||
|
||||
if ((errno = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
827
ecc.c
Normal file
827
ecc.c
Normal file
@ -0,0 +1,827 @@
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
static const struct {
|
||||
int size;
|
||||
char *name, *prime, *B, *order, *Gx, *Gy;
|
||||
} sets[] = {
|
||||
#ifdef ECC160
|
||||
{
|
||||
20,
|
||||
"ECC-160",
|
||||
/* prime */
|
||||
"1461501637330902918203684832716283019655932542983",
|
||||
/* B */
|
||||
"1C9E7C2E5891CBE097BD46",
|
||||
/* order */
|
||||
"1461501637330902918203686297565868358251373258181",
|
||||
/* Gx */
|
||||
"2DCF462904B478D868A7FF3F2BF1FCD9",
|
||||
/* Gy */
|
||||
"DFFAF2EE3848FA75FB967CEC7B9A399E085ACED8",
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC192
|
||||
{
|
||||
24,
|
||||
"ECC-192",
|
||||
/* prime */
|
||||
"6277101735386680763835789423207666416083908700390324961279",
|
||||
|
||||
/* B */
|
||||
"64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
|
||||
|
||||
/* order */
|
||||
"6277101735386680763835789423176059013767194773182842284081",
|
||||
|
||||
/* Gx */
|
||||
"188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
|
||||
|
||||
/* Gy */
|
||||
"07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC224
|
||||
{
|
||||
28,
|
||||
"ECC-224",
|
||||
|
||||
/* prime */
|
||||
"26959946667150639794667015087019630673637144422540572481103610249951",
|
||||
|
||||
/* B */
|
||||
"2051BA041508CED34B3",
|
||||
|
||||
/* order */
|
||||
"26959946667150639794667015087019637467111563745054605861463538557247",
|
||||
|
||||
/* Gx */
|
||||
"2DCF462904B478D868A7FF3F2BF1FCD9",
|
||||
|
||||
/* Gy */
|
||||
"CF337F320BC44A15C3EDB8C4258BB958E57A0CAFA73EB46E9C4BA9AE",
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC256
|
||||
{
|
||||
32,
|
||||
"ECC-256",
|
||||
/* Prime */
|
||||
"115792089210356248762697446949407573530086143415290314195533631308867097853951",
|
||||
|
||||
/* B */
|
||||
"5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
|
||||
|
||||
/* Order */
|
||||
"115792089210356248762697446949407573529996955224135760342422259061068512044369",
|
||||
|
||||
/* Gx */
|
||||
"6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
|
||||
|
||||
/* Gy */
|
||||
"4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC384
|
||||
{
|
||||
48,
|
||||
"ECC-384",
|
||||
/* prime */
|
||||
"394020061963944792122790401001436138050797392704654466679482934042457217714968"
|
||||
"70329047266088258938001861606973112319",
|
||||
|
||||
/* B */
|
||||
"b3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed1"
|
||||
"9d2a85c8edd3ec2aef",
|
||||
|
||||
/* Order */
|
||||
"394020061963944792122790401001436138050797392704654466679469052796276593991132"
|
||||
"63569398956308152294913554433653942643",
|
||||
|
||||
/* Gx and Gy */
|
||||
"aa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf5529"
|
||||
"6c3a545e3872760ab7",
|
||||
"3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e81"
|
||||
"9d7a431d7c90ea0e5f"
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC521
|
||||
{
|
||||
65,
|
||||
"ECC-521",
|
||||
/* prime */
|
||||
"686479766013060971498190079908139321726943530014330540939446345918554318339765"
|
||||
"6052122559640661454554977296311391480858037121987999716643812574028291115057151",
|
||||
|
||||
/* B */
|
||||
"051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7"
|
||||
"e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
|
||||
|
||||
/* Order */
|
||||
"686479766013060971498190079908139321726943530014330540939446345918554318339765"
|
||||
"5394245057746333217197532963996371363321113864768612440380340372808892707005449",
|
||||
|
||||
/* Gx and Gy */
|
||||
"c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe7"
|
||||
"5928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
|
||||
"11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef"
|
||||
"42640c550b9013fad0761353c7086a272c24088be94769fd16650",
|
||||
},
|
||||
#endif
|
||||
{
|
||||
0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
/* you plug in a prime and B value and it finds a pseudo-random base point */
|
||||
void ecc_find_base(void)
|
||||
{
|
||||
static char *prime = "26959946667150639794667015087019630673637144422540572481103610249951";
|
||||
static char *order = "26959946667150639794667015087019637467111563745054605861463538557247";
|
||||
static char *b = "9538957348957353489587";
|
||||
mp_int pp, p, r, B, tmp1, tmp2, tx, ty, x, y;
|
||||
char buf[4096];
|
||||
int i;
|
||||
|
||||
mp_init_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL);
|
||||
mp_read_radix(&p, prime, 10);
|
||||
mp_read_radix(&r, order, 10);
|
||||
mp_read_radix(&B, b, 10);
|
||||
|
||||
/* get (p+1)/4 */
|
||||
mp_add_d(&p, 1, &pp);
|
||||
mp_div_2(&pp, &pp);
|
||||
mp_div_2(&pp, &pp);
|
||||
|
||||
buf[0] = 0;
|
||||
do {
|
||||
printf("."); fflush(stdout);
|
||||
/* make a random value of x */
|
||||
for (i = 0; i < 16; i++) buf[i+1] = rand() & 255;
|
||||
mp_read_raw(&x, buf, 17);
|
||||
mp_copy(&x, &tx);
|
||||
|
||||
/* now compute x^3 - 3x + b */
|
||||
mp_expt_d(&x, 3, &tmp1);
|
||||
mp_mul_d(&x, 3, &tmp2);
|
||||
mp_sub(&tmp1, &tmp2, &tmp1);
|
||||
mp_add(&tmp1, &B, &tmp1);
|
||||
mp_mod(&tmp1, &p, &tmp1);
|
||||
|
||||
/* now compute sqrt via x^((p+1)/4) */
|
||||
mp_exptmod(&tmp1, &pp, &p, &tmp2);
|
||||
mp_copy(&tmp2, &ty);
|
||||
|
||||
/* now square it */
|
||||
mp_sqrmod(&tmp2, &p, &tmp2);
|
||||
|
||||
/* tmp2 should equal tmp1 */
|
||||
} while (mp_cmp(&tmp1, &tmp2));
|
||||
|
||||
/* now output values in way that libtomcrypt wants */
|
||||
mp_todecimal(&p, buf);
|
||||
printf("\n\np==%s\n", buf);
|
||||
mp_tohex(&B, buf);
|
||||
printf("b==%s\n", buf);
|
||||
mp_todecimal(&r, buf);
|
||||
printf("r==%s\n", buf);
|
||||
mp_tohex(&tx, buf);
|
||||
printf("Gx==%s\n", buf);
|
||||
mp_tohex(&ty, buf);
|
||||
printf("Gy==%s\n", buf);
|
||||
|
||||
mp_clear_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int is_valid_idx(int n)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; sets[x].size; x++);
|
||||
if ((n < 0) || (n >= x)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ecc_point *new_point(void)
|
||||
{
|
||||
ecc_point *p;
|
||||
p = XMALLOC(sizeof(ecc_point));
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (mp_init_multi(&p->x, &p->y, NULL) != MP_OKAY) {
|
||||
XFREE(p);
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static void del_point(ecc_point *p)
|
||||
{
|
||||
mp_clear_multi(&p->x, &p->y, NULL);
|
||||
XFREE(p);
|
||||
}
|
||||
|
||||
|
||||
/* double a point R = 2P, R can be P*/
|
||||
static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus)
|
||||
{
|
||||
mp_int s, tmp, tmpx;
|
||||
int res;
|
||||
|
||||
if (mp_init_multi(&s, &tmp, &tmpx, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* s = (3Xp^2 + a) / (2Yp) */
|
||||
if (mp_mul_2(&P->y, &tmp) != MP_OKAY) { goto error; } /* tmp = 2*y */
|
||||
if (mp_invmod(&tmp, modulus, &tmp) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */
|
||||
if (mp_sqr(&P->x, &s) != MP_OKAY) { goto error; } /* s = x^2 */
|
||||
if (mp_mul_d(&s, 3, &s) != MP_OKAY) { goto error; } /* s = 3*(x^2) */
|
||||
if (mp_sub_d(&s, 3, &s) != MP_OKAY) { goto error; } /* s = 3*(x^2) - 3 */
|
||||
if (mp_mulmod(&s, &tmp, modulus, &s) != MP_OKAY) { goto error; } /* s = tmp * s mod modulus */
|
||||
|
||||
/* Xr = s^2 - 2Xp */
|
||||
if (mp_sqr(&s, &tmpx) != MP_OKAY) { goto error; } /* tmpx = s^2 */
|
||||
if (mp_sub(&tmpx, &P->x, &tmpx) != MP_OKAY) { goto error; } /* tmpx = tmpx - x */
|
||||
if (mp_submod(&tmpx, &P->x, modulus, &tmpx) != MP_OKAY) { goto error; } /* tmpx = tmpx - x mod modulus */
|
||||
|
||||
/* Yr = -Yp + s(Xp - Xr) */
|
||||
if (mp_sub(&P->x, &tmpx, &tmp) != MP_OKAY) { goto error; } /* tmp = x - tmpx */
|
||||
if (mp_mul(&tmp, &s, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp * s */
|
||||
if (mp_submod(&tmp, &P->y, modulus, &R->y) != MP_OKAY) { goto error; } /* y = tmp - y mod modulus */
|
||||
if (mp_copy(&tmpx, &R->x) != MP_OKAY) { goto error; } /* x = tmpx */
|
||||
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&tmpx, &tmp, &s, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* add two different points over Z/pZ, R = P + Q, note R can equal either P or Q */
|
||||
static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus)
|
||||
{
|
||||
mp_int s, tmp, tmpx;
|
||||
int res;
|
||||
|
||||
if (mp_init(&tmp) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* is P==Q or P==-Q? */
|
||||
mp_neg(&Q->y, &tmp);
|
||||
mp_mod(&tmp, modulus, &tmp);
|
||||
if (!mp_cmp(&P->x, &Q->x))
|
||||
if (!mp_cmp(&P->y, &Q->y) || !mp_cmp(&P->y, &tmp)) {
|
||||
mp_clear(&tmp);
|
||||
return dbl_point(P, R, modulus);
|
||||
}
|
||||
|
||||
if (mp_init_multi(&tmpx, &s, NULL) != MP_OKAY) {
|
||||
mp_clear(&tmp);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* get s = (Yp - Yq)/(Xp-Xq) mod p */
|
||||
if (mp_submod(&P->x, &Q->x, modulus, &tmp) != MP_OKAY) { goto error; } /* tmp = Px - Qx mod modulus */
|
||||
if (mp_invmod(&tmp, modulus, &tmp) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */
|
||||
if (mp_sub(&P->y, &Q->y, &s) != MP_OKAY) { goto error; } /* s = Py - Qy mod modulus */
|
||||
if (mp_mulmod(&s, &tmp, modulus, &s) != MP_OKAY) { goto error; } /* s = s * tmp mod modulus */
|
||||
|
||||
/* Xr = s^2 - Xp - Xq */
|
||||
if (mp_sqrmod(&s, modulus, &tmp) != MP_OKAY) { goto error; } /* tmp = s^2 mod modulus */
|
||||
if (mp_sub(&tmp, &P->x, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp - Px */
|
||||
if (mp_sub(&tmp, &Q->x, &tmpx) != MP_OKAY) { goto error; } /* tmpx = tmp - Qx */
|
||||
|
||||
/* Yr = -Yp + s(Xp - Xr) */
|
||||
if (mp_sub(&P->x, &tmpx, &tmp) != MP_OKAY) { goto error; } /* tmp = Px - tmpx */
|
||||
if (mp_mul(&tmp, &s, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp * s */
|
||||
if (mp_submod(&tmp, &P->y, modulus, &R->y) != MP_OKAY) { goto error; } /* Ry = tmp - Py mod modulus */
|
||||
if (mp_mod(&tmpx, modulus, &R->x) != MP_OKAY) { goto error; } /* Rx = tmpx mod modulus */
|
||||
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&s, &tmpx, &tmp, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* perform R = kG where k == integer and G == ecc_point */
|
||||
static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus, int idx)
|
||||
{
|
||||
ecc_point *tG;
|
||||
int i, j, z, first, res;
|
||||
mp_digit d;
|
||||
unsigned char bits[768];
|
||||
|
||||
/* get bits of k */
|
||||
for (z = i = 0; z < (int)USED(k); z++) {
|
||||
d = DIGIT(k, z);
|
||||
|
||||
#define DO1 bits[i++] = d&1; d >>= 1;
|
||||
#define DO2 DO1 DO1
|
||||
#define DO4 DO2 DO2
|
||||
|
||||
DO4; DO4; DO4; DO4
|
||||
|
||||
#undef DO4
|
||||
#undef DO2
|
||||
#undef DO1
|
||||
}
|
||||
|
||||
/* make a copy of G incase R==G */
|
||||
tG = new_point();
|
||||
if (tG == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* tG = G */
|
||||
if (mp_copy(&G->x, &tG->x) != MP_OKAY) { goto error; }
|
||||
if (mp_copy(&G->y, &tG->y) != MP_OKAY) { goto error; }
|
||||
|
||||
/* set result to G, R = G */
|
||||
if (mp_copy(&G->x, &R->x) != MP_OKAY) { goto error; }
|
||||
if (mp_copy(&G->y, &R->y) != MP_OKAY) { goto error; }
|
||||
first = 0;
|
||||
|
||||
/* now do dbl+add through all the bits */
|
||||
for (j = i-1; j >= 0; j--) {
|
||||
if (first) {
|
||||
if (dbl_point(R, R, modulus) != CRYPT_OK) { goto error; }
|
||||
}
|
||||
if (bits[j] == 1) {
|
||||
if (first) {
|
||||
if (add_point(R, tG, R, modulus) != CRYPT_OK) { goto error; }
|
||||
}
|
||||
first = 1;
|
||||
}
|
||||
}
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
del_point(tG);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(bits, sizeof(bits));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
int ecc_test(void)
|
||||
{
|
||||
mp_int modulus, order;
|
||||
ecc_point *G, *GG;
|
||||
int i, res, primality;
|
||||
|
||||
if (mp_init_multi(&modulus, &order, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
G = new_point();
|
||||
if (G == NULL) {
|
||||
mp_clear_multi(&modulus, &order, NULL);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
GG = new_point();
|
||||
if (GG == NULL) {
|
||||
mp_clear_multi(&modulus, &order, NULL);
|
||||
del_point(G);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
for (i = 0; sets[i].size; i++) {
|
||||
if (mp_read_radix(&modulus, (unsigned char *)sets[i].prime, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&order, (unsigned char *)sets[i].order, 10) != MP_OKAY) { goto error; }
|
||||
|
||||
/* is prime actually prime? */
|
||||
if (is_prime(&modulus, &primality) != CRYPT_OK) { goto error; }
|
||||
if (primality == 0) {
|
||||
res = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
/* is order prime ? */
|
||||
if (is_prime(&order, &primality) != CRYPT_OK) { goto error; }
|
||||
if (primality == 0) {
|
||||
res = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
if (mp_read_radix(&G->x, (unsigned char *)sets[i].Gx, 16) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&G->y, (unsigned char *)sets[i].Gy, 16) != MP_OKAY) { goto error; }
|
||||
|
||||
/* then we should have G == (order + 1)G */
|
||||
if (mp_add_d(&order, 1, &order) != MP_OKAY) { goto error; }
|
||||
if (ecc_mulmod(&order, G, GG, &modulus, i) != CRYPT_OK) { goto error; }
|
||||
if (mp_cmp(&G->x, &GG->x) || mp_cmp(&G->y, &GG->y)) {
|
||||
res = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done1;
|
||||
}
|
||||
}
|
||||
res = CRYPT_OK;
|
||||
goto done1;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done1:
|
||||
del_point(GG);
|
||||
del_point(G);
|
||||
mp_clear_multi(&order, &modulus, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
void ecc_sizes(int *low, int *high)
|
||||
{
|
||||
int i;
|
||||
_ARGCHK(low != NULL);
|
||||
_ARGCHK(high != NULL);
|
||||
|
||||
*low = INT_MAX;
|
||||
*high = 0;
|
||||
for (i = 0; sets[i].size; i++) {
|
||||
if (sets[i].size < *low) {
|
||||
*low = sets[i].size;
|
||||
}
|
||||
if (sets[i].size > *high) {
|
||||
*high = sets[i].size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
|
||||
{
|
||||
int x, res, errno;
|
||||
ecc_point *base;
|
||||
mp_int prime;
|
||||
unsigned char buf[4096];
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* good prng? */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* find key size */
|
||||
for (x = 0; (keysize > sets[x].size) && (sets[x].size); x++);
|
||||
keysize = sets[x].size;
|
||||
|
||||
if (sets[x].size == 0) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
key->idx = x;
|
||||
|
||||
/* make up random string */
|
||||
buf[0] = 0;
|
||||
if (prng_descriptor[wprng].read(buf+1, keysize, prng) != (unsigned long)keysize) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* setup the key variables */
|
||||
if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
base = new_point();
|
||||
if (base == NULL) {
|
||||
mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* read in the specs for this key */
|
||||
if (mp_read_radix(&prime, (unsigned char *)sets[x].prime, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&base->x, (unsigned char *)sets[x].Gx, 16) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&base->y, (unsigned char *)sets[x].Gy, 16) != MP_OKAY) { goto error; }
|
||||
if (mp_read_raw(&key->k, (unsigned char *)buf, keysize+1) != MP_OKAY) { goto error; }
|
||||
|
||||
/* make the public key */
|
||||
if (ecc_mulmod(&key->k, base, &key->pubkey, &prime, x) != CRYPT_OK) { goto error; }
|
||||
key->type = PK_PRIVATE;
|
||||
|
||||
/* free up ram */
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
del_point(base);
|
||||
mp_clear(&prime);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
void ecc_free(ecc_key *key)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL);
|
||||
}
|
||||
|
||||
static int compress_y_point(ecc_point *pt, int idx, int *result)
|
||||
{
|
||||
mp_int tmp, tmp2, p;
|
||||
int res;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(result != NULL);
|
||||
|
||||
if (mp_init_multi(&tmp, &tmp2, &p, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* get x^3 - 3x + b */
|
||||
if (mp_read_radix(&p, (unsigned char *)sets[idx].B, 16) != MP_OKAY) { goto error; } /* p = B */
|
||||
if (mp_expt_d(&pt->x, 3, &tmp) != MP_OKAY) { goto error; } /* tmp = pX^3 */
|
||||
if (mp_mul_d(&pt->x, 3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */
|
||||
if (mp_sub(&tmp, &tmp2, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */
|
||||
if (mp_add(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp + p */
|
||||
if (mp_read_radix(&p, (unsigned char *)sets[idx].prime, 10) != MP_OKAY) { goto error; } /* p = prime */
|
||||
if (mp_mod(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp mod p */
|
||||
|
||||
/* now find square root */
|
||||
if (mp_add_d(&p, 1, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */
|
||||
if (mp_div_2(&tmp2, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = tmp2/2 */
|
||||
if (mp_div_2(&tmp2, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */
|
||||
if (mp_exptmod(&tmp, &tmp2, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */
|
||||
|
||||
/* if tmp equals the y point give a 0, otherwise 1 */
|
||||
if (mp_cmp(&tmp, &pt->y) == 0)
|
||||
*result = 0;
|
||||
else
|
||||
*result = 1;
|
||||
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&p, &tmp, &tmp2, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
static int expand_y_point(ecc_point *pt, int idx, int result)
|
||||
{
|
||||
mp_int tmp, tmp2, p;
|
||||
int res;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
|
||||
if (mp_init_multi(&tmp, &tmp2, &p, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* get x^3 - 3x + b */
|
||||
if (mp_read_radix(&p, (unsigned char *)sets[idx].B, 16) != MP_OKAY) { goto error; } /* p = B */
|
||||
if (mp_expt_d(&pt->x, 3, &tmp) != MP_OKAY) { goto error; } /* tmp = pX^3 */
|
||||
if (mp_mul_d(&pt->x, 3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */
|
||||
if (mp_sub(&tmp, &tmp2, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */
|
||||
if (mp_add(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp + p */
|
||||
if (mp_read_radix(&p, (unsigned char *)sets[idx].prime, 10) != MP_OKAY) { goto error; } /* p = prime */
|
||||
if (mp_mod(&tmp, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = tmp mod p */
|
||||
|
||||
/* now find square root */
|
||||
if (mp_add_d(&p, 1, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */
|
||||
if (mp_div_2(&tmp2, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = tmp2/2 */
|
||||
if (mp_div_2(&tmp2, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */
|
||||
if (mp_exptmod(&tmp, &tmp2, &p, &tmp) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */
|
||||
|
||||
/* if result==0, then y==tmp, otherwise y==p-tmp */
|
||||
if (result == 0) {
|
||||
if (mp_copy(&tmp, &pt->y) != MP_OKAY) { goto error; }
|
||||
} else {
|
||||
if (mp_sub(&p, &tmp, &pt->y) != MP_OKAY) { goto error; }
|
||||
}
|
||||
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&p, &tmp, &tmp2, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
#define OUTPUT_BIGNUM(num, buf2, y, z) \
|
||||
{ \
|
||||
z = mp_raw_size(num); \
|
||||
STORE32L(z, buf2+y); \
|
||||
y += 4; \
|
||||
mp_toraw(num, buf2+y); \
|
||||
y += z; \
|
||||
}
|
||||
|
||||
|
||||
#define INPUT_BIGNUM(num, in, x, y) \
|
||||
{ \
|
||||
/* load value */ \
|
||||
LOAD32L(x, in+y); \
|
||||
y += 4; \
|
||||
\
|
||||
/* sanity check... */ \
|
||||
if (x > 1024) { \
|
||||
goto error; \
|
||||
} \
|
||||
\
|
||||
/* load it */ \
|
||||
if (mp_read_raw(num, (unsigned char *)in+y, x) != MP_OKAY) {\
|
||||
goto error; \
|
||||
} \
|
||||
y += x; \
|
||||
}
|
||||
|
||||
int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
|
||||
{
|
||||
unsigned long y, z;
|
||||
int res, errno;
|
||||
unsigned char buf2[512];
|
||||
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* type valid? */
|
||||
if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
|
||||
return CRYPT_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
/* output type and magic byte */
|
||||
y = PACKET_SIZE;
|
||||
buf2[y++] = type;
|
||||
buf2[y++] = key->idx;
|
||||
|
||||
/* output x coordinate */
|
||||
OUTPUT_BIGNUM(&(key->pubkey.x), buf2, y, z);
|
||||
|
||||
/* compress y and output it */
|
||||
if ((errno = compress_y_point(&key->pubkey, key->idx, &res)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
buf2[y++] = res;
|
||||
|
||||
if (type == PK_PRIVATE) {
|
||||
OUTPUT_BIGNUM(&key->k, buf2, y, z);
|
||||
}
|
||||
|
||||
/* check size */
|
||||
if (*outlen < y) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(buf2, PACKET_SECT_ECC, PACKET_SUB_KEY, y);
|
||||
|
||||
memcpy(out, buf2, y);
|
||||
*outlen = y;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf2, sizeof(buf2));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int ecc_import(const unsigned char *in, ecc_key *key)
|
||||
{
|
||||
unsigned long x, y;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check type */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* init key */
|
||||
if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
y = PACKET_SIZE;
|
||||
key->type = in[y++];
|
||||
key->idx = in[y++];
|
||||
|
||||
/* type check both values */
|
||||
if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) {
|
||||
res = CRYPT_INVALID_PACKET;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
/* is the key idx valid? */
|
||||
if (!is_valid_idx(key->idx)) {
|
||||
res = CRYPT_INVALID_PACKET;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
/* load x coordinate */
|
||||
INPUT_BIGNUM(&key->pubkey.x, in, x, y);
|
||||
|
||||
/* load y */
|
||||
x = in[y++];
|
||||
if ((errno = expand_y_point(&key->pubkey, key->idx, x)) != CRYPT_OK) { res = errno; goto error2; }
|
||||
|
||||
if (key->type == PK_PRIVATE) {
|
||||
/* load private key */
|
||||
INPUT_BIGNUM(&key->k, in, x, y);
|
||||
}
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
error2:
|
||||
mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL);
|
||||
done:
|
||||
return res;
|
||||
}
|
||||
|
||||
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x, y;
|
||||
ecc_point *result;
|
||||
mp_int prime;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(private_key != NULL);
|
||||
_ARGCHK(public_key != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* type valid? */
|
||||
if (private_key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
if (private_key->idx != public_key->idx) {
|
||||
return CRYPT_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
/* make new point */
|
||||
result = new_point();
|
||||
if (result == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if (mp_init(&prime) != MP_OKAY) {
|
||||
del_point(result);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if (mp_read_radix(&prime, (unsigned char *)sets[private_key->idx].prime, 10) != MP_OKAY) { goto error; }
|
||||
if ((errno = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime, private_key->idx)) != CRYPT_OK) { res = errno; goto done1; }
|
||||
|
||||
x = mp_raw_size(&result->x);
|
||||
y = mp_raw_size(&result->y);
|
||||
|
||||
if (*outlen < (x+y)) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done1;
|
||||
}
|
||||
*outlen = x+y;
|
||||
mp_toraw(&result->x, out);
|
||||
mp_toraw(&result->y, out+x);
|
||||
|
||||
res = CRYPT_OK;
|
||||
goto done1;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done1:
|
||||
mp_clear(&prime);
|
||||
del_point(result);
|
||||
return res;
|
||||
}
|
||||
|
||||
int ecc_get_size(ecc_key *key)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
if (is_valid_idx(key->idx))
|
||||
return sets[key->idx].size;
|
||||
else
|
||||
return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */
|
||||
}
|
||||
|
||||
#include "ecc_sys.c"
|
||||
|
||||
#endif
|
||||
|
||||
|
862
ecc_sys.c
Normal file
862
ecc_sys.c
Normal file
@ -0,0 +1,862 @@
|
||||
#ifdef PK_PACKET
|
||||
|
||||
int ecc_encrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int cipher, int hash,
|
||||
ecc_key *key)
|
||||
{
|
||||
unsigned char pub_expt[512], ecc_shared[256], IV[MAXBLOCKSIZE], skey[MAXBLOCKSIZE];
|
||||
ecc_key pubkey;
|
||||
unsigned long x, y, z, pubkeysize;
|
||||
int keysize, blocksize, hashsize, errno;
|
||||
symmetric_CTR ctr;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check that wprng/cipher/hash are not invalid */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* make a random key and export the public copy */
|
||||
if ((errno = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
pubkeysize = sizeof(pub_expt);
|
||||
if ((errno = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* now check if the out buffer is big enough */
|
||||
if (*outlen < (10 + PACKET_SIZE + pubkeysize +
|
||||
cipher_descriptor[cipher].block_length + len)) {
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* make random key */
|
||||
blocksize = cipher_descriptor[cipher].block_length;
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
keysize = hashsize;
|
||||
if ((errno = cipher_descriptor[cipher].keysize(&keysize)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
x = sizeof(ecc_shared);
|
||||
if ((errno = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
|
||||
z = sizeof(skey);
|
||||
if ((errno = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* make up IV */
|
||||
if (prng_descriptor[wprng].read(IV, cipher_descriptor[cipher].block_length, prng) !=
|
||||
(unsigned long)cipher_descriptor[cipher].block_length) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* setup CTR mode */
|
||||
if ((errno = ctr_start(cipher, IV, skey, keysize, 0, &ctr)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* output header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* size of cipher name and the name itself */
|
||||
out[y++] = cipher_descriptor[cipher].ID;
|
||||
|
||||
/* size of hash name and the name itself */
|
||||
out[y++] = hash_descriptor[hash].ID;
|
||||
|
||||
/* length of ECC pubkey and the key itself */
|
||||
STORE32L(pubkeysize, out+y);
|
||||
y += 4;
|
||||
for (x = 0; x < (unsigned)pubkeysize; x++, y++) {
|
||||
out[y] = pub_expt[x];
|
||||
}
|
||||
|
||||
/* cipher IV */
|
||||
for (x = 0; x < (unsigned)blocksize; x++, y++) {
|
||||
out[y] = IV[x];
|
||||
}
|
||||
|
||||
/* length of ciphertext */
|
||||
STORE32L(len, out+y);
|
||||
y += 4;
|
||||
|
||||
/* encrypt the message */
|
||||
if ((errno = ctr_encrypt(in, out+y, len, &ctr)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
y += len;
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENCRYPTED, y);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(pub_expt, sizeof(pub_expt));
|
||||
zeromem(ecc_shared, sizeof(ecc_shared));
|
||||
zeromem(skey, sizeof(skey));
|
||||
zeromem(IV, sizeof(IV));
|
||||
zeromem(&ctr, sizeof(ctr));
|
||||
#endif
|
||||
|
||||
*outlen = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int ecc_decrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
ecc_key *key)
|
||||
{
|
||||
unsigned char shared_secret[256], skey[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z, res, hashsize, blocksize;
|
||||
int cipher, hash, keysize, errno;
|
||||
ecc_key pubkey;
|
||||
symmetric_CTR ctr;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* is header correct? */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENCRYPTED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* now lets get the cipher name */
|
||||
y = PACKET_SIZE;
|
||||
cipher = find_cipher_id(in[y++]);
|
||||
if (cipher == -1) {
|
||||
return CRYPT_INVALID_CIPHER;
|
||||
}
|
||||
|
||||
/* now lets get the hash name */
|
||||
hash = find_hash_id(in[y++]);
|
||||
if (hash == -1) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* common values */
|
||||
blocksize = cipher_descriptor[cipher].block_length;
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
keysize = hashsize;
|
||||
if ((errno = cipher_descriptor[cipher].keysize(&keysize)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* get public key */
|
||||
LOAD32L(x, in+y);
|
||||
y += 4;
|
||||
if ((errno = ecc_import(in+y, &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
y += x;
|
||||
|
||||
/* make shared key */
|
||||
x = sizeof(shared_secret);
|
||||
if ((errno = ecc_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
|
||||
z = sizeof(skey);
|
||||
if ((errno = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
|
||||
res = errno;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* setup CTR mode */
|
||||
if ((errno = ctr_start(cipher, in+y, skey, keysize, 0, &ctr)) != CRYPT_OK) {
|
||||
res = errno;
|
||||
goto done;
|
||||
}
|
||||
y += blocksize;
|
||||
|
||||
/* get length */
|
||||
LOAD32L(len,in+y);
|
||||
y += 4;
|
||||
|
||||
/* buffer overflow? */
|
||||
if (len > *outlen) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* decrypt message */
|
||||
if ((errno = ctr_decrypt(in+y, out, len, &ctr)) != CRYPT_OK) {
|
||||
res = errno;
|
||||
goto done;
|
||||
}
|
||||
*outlen = len;
|
||||
|
||||
res = CRYPT_OK;
|
||||
done:
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(shared_secret, sizeof(shared_secret));
|
||||
zeromem(skey, sizeof(skey));
|
||||
zeromem(&ctr, sizeof(ctr));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Signatures
|
||||
*
|
||||
* Signatures are performed using a slightly modified ElGamal protocol.
|
||||
* In these notes uppercase letters are points and lowercase letters are
|
||||
* scalars. The users private key is 'x' and public key is Y = xG.
|
||||
* The order of the curve is 'r'.
|
||||
*
|
||||
*
|
||||
* To sign a message 'm' the user does this
|
||||
|
||||
1. Makes up a random 'k' and finds kG [basically makes up a ecc_key], we will let A = kG
|
||||
2. Finds b such that b = (m - x)/k mod r
|
||||
3. Outputs (A, b) as the signature
|
||||
|
||||
To verify a user computes mG and compares that to (bA + Y). Note that (bA + Y) is equal to
|
||||
|
||||
= ((m - x)/k)(kG) + xG
|
||||
= (m - x)G + xG
|
||||
= mG
|
||||
|
||||
In theory, assuming the ECC Discrete Log is a hard problem an attacker
|
||||
cannot find 'x' from (A, b). 'b' is perfectly decorrelated and reveals no
|
||||
information. A reveals what kG is but not 'k' directly. Therefore,
|
||||
assuming finding 'k' given kG is hard, finding 'x' from b is hard too.
|
||||
|
||||
*/
|
||||
|
||||
int ecc_sign(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
int hash, prng_state *prng, int wprng,
|
||||
ecc_key *key)
|
||||
{
|
||||
ecc_key pubkey;
|
||||
mp_int b, p;
|
||||
unsigned char epubkey[256], er[256], md[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z, pubkeysize, rsize;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* is this a private key? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* make up a key and export the public copy */
|
||||
if ((errno = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
pubkeysize = sizeof(epubkey);
|
||||
if ((errno = ecc_export(epubkey, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* get the hash and load it as a bignum into 'b' */
|
||||
md[0] = 0;
|
||||
z = sizeof(md)-1;
|
||||
if ((errno = hash_memory(hash, in, inlen, md+1, &z)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* init the bignums */
|
||||
if (mp_init_multi(&b, &p, NULL) != MP_OKAY) {
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
if (mp_read_radix(&p, sets[key->idx].order, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_raw(&b, md, 1+hash_descriptor[hash].hashsize) != MP_OKAY) { goto error; }
|
||||
|
||||
/* find b = (m - x)/k */
|
||||
if (mp_invmod(&pubkey.k, &p, &pubkey.k) != MP_OKAY) { goto error; } /* k = 1/k */
|
||||
if (mp_submod(&b, &key->k, &p, &b) != MP_OKAY) { goto error; } /* b = m - x */
|
||||
if (mp_mulmod(&b, &pubkey.k, &p, &b) != MP_OKAY) { goto error; } /* b = (m - x)/k */
|
||||
|
||||
/* export it */
|
||||
rsize = mp_raw_size(&b);
|
||||
if (rsize > sizeof(er)) {
|
||||
goto error;
|
||||
}
|
||||
mp_toraw(&b, er);
|
||||
|
||||
/* now lets check the outlen before we write */
|
||||
if (*outlen < (9 + PACKET_SIZE + rsize + pubkeysize)) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
/* lets output */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* length of hash name plus NULL */
|
||||
out[y++] = hash_descriptor[hash].ID;
|
||||
|
||||
/* size of public key */
|
||||
STORE32L(pubkeysize, out+y);
|
||||
y += 4;
|
||||
|
||||
/* copy the public key */
|
||||
for (x = 0; x < pubkeysize; x++, y++) {
|
||||
out[y] = epubkey[x];
|
||||
}
|
||||
|
||||
/* size of 'r' */
|
||||
STORE32L(rsize, out+y);
|
||||
y += 4;
|
||||
|
||||
/* copy r */
|
||||
for (x = 0; x < rsize; x++, y++) {
|
||||
out[y] = er[x];
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED, y);
|
||||
|
||||
/* clear memory */
|
||||
*outlen = y;
|
||||
res = CRYPT_OK;
|
||||
goto done1;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done1:
|
||||
mp_clear_multi(&b, &p, NULL);
|
||||
ecc_free(&pubkey);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(er, sizeof(er));
|
||||
zeromem(epubkey, sizeof(epubkey));
|
||||
zeromem(md, sizeof(md));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
/* verify that mG = (bA + Y) */
|
||||
int ecc_verify(const unsigned char *sig, const unsigned char *msg,
|
||||
unsigned long inlen, int *stat,
|
||||
ecc_key *key)
|
||||
{
|
||||
ecc_point *mG;
|
||||
ecc_key pubkey;
|
||||
mp_int b, p, m;
|
||||
unsigned long x, y, z;
|
||||
int hash, res, errno;
|
||||
unsigned char md[MAXBLOCKSIZE];
|
||||
|
||||
_ARGCHK(sig != NULL);
|
||||
_ARGCHK(msg != NULL);
|
||||
_ARGCHK(stat != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* default to invalid signature */
|
||||
*stat = 0;
|
||||
|
||||
/* is the message format correct? */
|
||||
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* get hash name */
|
||||
y = PACKET_SIZE;
|
||||
hash = find_hash_id(sig[y++]);
|
||||
if (hash == -1) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* get size of public key */
|
||||
LOAD32L(x, sig+y);
|
||||
y += 4;
|
||||
|
||||
/* load the public key */
|
||||
if ((errno = ecc_import((unsigned char*)sig+y, &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
y += x;
|
||||
|
||||
/* load size of 'b' */
|
||||
LOAD32L(x, sig+y);
|
||||
y += 4;
|
||||
|
||||
/* init values */
|
||||
if (mp_init_multi(&b, &m, &p, NULL) != MP_OKAY) {
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
mG = new_point();
|
||||
if (mG == NULL) {
|
||||
mp_clear_multi(&b, &m, &p, NULL);
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* load b */
|
||||
if (mp_read_raw(&b, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
/* get m in binary a bignum */
|
||||
md[0] = 0;
|
||||
z = sizeof(md)-1;
|
||||
if ((errno = hash_memory(hash, msg, inlen, md+1, &z)) != CRYPT_OK) {
|
||||
res = errno;
|
||||
goto done1;
|
||||
}
|
||||
if (mp_read_raw(&m, md, hash_descriptor[hash].hashsize + 1) != MP_OKAY) { goto error; }
|
||||
|
||||
/* load prime */
|
||||
if (mp_read_radix(&p, sets[key->idx].prime, 10) != MP_OKAY) { goto error; }
|
||||
|
||||
/* get bA */
|
||||
if (ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p, key->idx) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* get bA + Y */
|
||||
if (add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* get mG */
|
||||
if (mp_read_radix(&mG->x, sets[key->idx].Gx, 16) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&mG->y, sets[key->idx].Gy, 16) != MP_OKAY) { goto error; }
|
||||
if (ecc_mulmod(&m, mG, mG, &p, key->idx) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* compare mG to bA + Y */
|
||||
if (!mp_cmp(&mG->x, &pubkey.pubkey.x) && !mp_cmp(&mG->y, &pubkey.pubkey.y)) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
/* clear up and return */
|
||||
res = CRYPT_OK;
|
||||
goto done1;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done1:
|
||||
del_point(mG);
|
||||
ecc_free(&pubkey);
|
||||
mp_clear_multi(&p, &m, &b, NULL);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(md));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *len,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
ecc_key *key)
|
||||
{
|
||||
unsigned char pub_expt[256], ecc_shared[256], skey[MAXBLOCKSIZE];
|
||||
ecc_key pubkey;
|
||||
unsigned long x, y, z, hashsize, pubkeysize;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(inkey != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(len != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check that wprng/cipher/hash are not invalid */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (keylen > hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* make a random key and export the public copy */
|
||||
if ((errno = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
pubkeysize = sizeof(pub_expt);
|
||||
if ((errno = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* now check if the out buffer is big enough */
|
||||
if (*len < (9 + PACKET_SIZE + pubkeysize + hash_descriptor[hash].hashsize)) {
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* make random key */
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
x = sizeof(ecc_shared);
|
||||
if ((errno = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
z = sizeof(skey);
|
||||
if ((errno = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* Encrypt the key */
|
||||
for (x = 0; x < keylen; x++) {
|
||||
skey[x] ^= inkey[x];
|
||||
}
|
||||
|
||||
/* output header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* size of hash name and the name itself */
|
||||
out[y++] = hash_descriptor[hash].ID;
|
||||
|
||||
/* length of ECC pubkey and the key itself */
|
||||
STORE32L(pubkeysize, out+y);
|
||||
y += 4;
|
||||
|
||||
for (x = 0; x < pubkeysize; x++, y++) {
|
||||
out[y] = pub_expt[x];
|
||||
}
|
||||
|
||||
STORE32L(keylen, out+y);
|
||||
y += 4;
|
||||
|
||||
/* Store the encrypted key */
|
||||
for (x = 0; x < keylen; x++, y++) {
|
||||
out[y] = skey[x];
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY, y);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(pub_expt, sizeof(pub_expt));
|
||||
zeromem(ecc_shared, sizeof(ecc_shared));
|
||||
zeromem(skey, sizeof(skey));
|
||||
#endif
|
||||
*len = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, ecc_key *key)
|
||||
{
|
||||
unsigned char shared_secret[256], skey[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z, res, hashsize, keysize;
|
||||
int hash, errno;
|
||||
ecc_key pubkey;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(outkey != NULL);
|
||||
_ARGCHK(keylen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* is header correct? */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* now lets get the hash name */
|
||||
y = PACKET_SIZE;
|
||||
hash = find_hash_id(in[y++]);
|
||||
if (hash == -1) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* common values */
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
|
||||
/* get public key */
|
||||
LOAD32L(x, in+y);
|
||||
y += 4;
|
||||
if ((errno = ecc_import(in+y, &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
y += x;
|
||||
|
||||
/* make shared key */
|
||||
x = sizeof(shared_secret);
|
||||
if ((errno = ecc_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
|
||||
z = sizeof(skey);
|
||||
if ((errno = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
LOAD32L(keysize, in+y);
|
||||
y += 4;
|
||||
|
||||
if (*keylen < keysize) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Decrypt the key */
|
||||
for (x = 0; x < keysize; x++, y++) {
|
||||
outkey[x] = skey[x] ^ in[y];
|
||||
}
|
||||
|
||||
*keylen = keysize;
|
||||
|
||||
res = CRYPT_OK;
|
||||
done:
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(shared_secret, sizeof(shared_secret));
|
||||
zeromem(skey, sizeof(skey));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, ecc_key *key)
|
||||
{
|
||||
ecc_key pubkey;
|
||||
mp_int b, p;
|
||||
unsigned char epubkey[256], er[256], md[MAXBLOCKSIZE];
|
||||
unsigned long x, y, pubkeysize, rsize;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* is this a private key? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* make up a key and export the public copy */
|
||||
if ((errno = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
pubkeysize = sizeof(epubkey);
|
||||
if ((errno = ecc_export(epubkey, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* get the hash and load it as a bignum into 'b' */
|
||||
md[0] = 0;
|
||||
memcpy(md+1, in, MIN(sizeof(md)-1,inlen));
|
||||
|
||||
/* init the bignums */
|
||||
if (mp_init_multi(&b, &p, NULL) != MP_OKAY) {
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
if (mp_read_radix(&p, (unsigned char *)sets[key->idx].order, 10) != MP_OKAY) { goto error; }
|
||||
if (mp_read_raw(&b, md, 1+MIN(sizeof(md)-1,inlen)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* find b = (m - x)/k */
|
||||
if (mp_invmod(&pubkey.k, &p, &pubkey.k) != MP_OKAY) { goto error; } /* k = 1/k */
|
||||
if (mp_submod(&b, &key->k, &p, &b) != MP_OKAY) { goto error; } /* b = m - x */
|
||||
if (mp_mulmod(&b, &pubkey.k, &p, &b) != MP_OKAY) { goto error; } /* b = (m - x)/k */
|
||||
|
||||
/* export it */
|
||||
rsize = mp_raw_size(&b);
|
||||
if (rsize > sizeof(er)) {
|
||||
goto error;
|
||||
}
|
||||
mp_toraw(&b, er);
|
||||
|
||||
/* now lets check the outlen before we write */
|
||||
if (*outlen < (12 + rsize + pubkeysize)) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done1;
|
||||
}
|
||||
|
||||
/* lets output */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* size of public key */
|
||||
STORE32L(pubkeysize, out+y);
|
||||
y += 4;
|
||||
|
||||
/* copy the public key */
|
||||
for (x = 0; x < pubkeysize; x++, y++) {
|
||||
out[y] = epubkey[x];
|
||||
}
|
||||
|
||||
/* size of 'r' */
|
||||
STORE32L(rsize, out+y);
|
||||
y += 4;
|
||||
|
||||
/* copy r */
|
||||
for (x = 0; x < rsize; x++, y++) {
|
||||
out[y] = er[x];
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED, y);
|
||||
|
||||
/* clear memory */
|
||||
*outlen = y;
|
||||
res = CRYPT_OK;
|
||||
goto done1;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done1:
|
||||
mp_clear_multi(&b, &p, NULL);
|
||||
ecc_free(&pubkey);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(er, sizeof(er));
|
||||
zeromem(epubkey, sizeof(epubkey));
|
||||
zeromem(md, sizeof(md));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
/* verify that mG = (bA + Y) */
|
||||
int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
unsigned long inlen, int *stat,
|
||||
ecc_key *key)
|
||||
{
|
||||
ecc_point *mG;
|
||||
ecc_key pubkey;
|
||||
mp_int b, p, m;
|
||||
unsigned long x, y;
|
||||
int res, errno;
|
||||
unsigned char md[MAXBLOCKSIZE];
|
||||
|
||||
_ARGCHK(sig != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* default to invalid signature */
|
||||
*stat = 0;
|
||||
|
||||
/* is the message format correct? */
|
||||
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* get hash name */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* get size of public key */
|
||||
LOAD32L(x, sig+y);
|
||||
y += 4;
|
||||
|
||||
/* load the public key */
|
||||
if ((errno = ecc_import((unsigned char*)sig+y, &pubkey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
y += x;
|
||||
|
||||
/* load size of 'b' */
|
||||
LOAD32L(x, sig+y);
|
||||
y += 4;
|
||||
|
||||
/* init values */
|
||||
if (mp_init_multi(&b, &m, &p, NULL) != MP_OKAY) {
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
mG = new_point();
|
||||
if (mG == NULL) {
|
||||
mp_clear_multi(&b, &m, &p, NULL);
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* load b */
|
||||
if (mp_read_raw(&b, (unsigned char *)sig+y, x) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
/* get m in binary a bignum */
|
||||
md[0] = 0;
|
||||
memcpy(md+1,hash,MIN(sizeof(md)-1,inlen));
|
||||
if (mp_read_raw(&m, md, 1+MIN(sizeof(md)-1,inlen)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* load prime */
|
||||
if (mp_read_radix(&p, (unsigned char *)sets[key->idx].prime, 10) != MP_OKAY) { goto error; }
|
||||
|
||||
/* get bA */
|
||||
if (ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p, key->idx) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* get bA + Y */
|
||||
if (add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* get mG */
|
||||
if (mp_read_radix(&mG->x, (unsigned char *)sets[key->idx].Gx, 16) != MP_OKAY) { goto error; }
|
||||
if (mp_read_radix(&mG->y, (unsigned char *)sets[key->idx].Gy, 16) != MP_OKAY) { goto error; }
|
||||
if (ecc_mulmod(&m, mG, mG, &p, key->idx) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* compare mG to bA + Y */
|
||||
if (!mp_cmp(&mG->x, &pubkey.pubkey.x) && !mp_cmp(&mG->y, &pubkey.pubkey.y)) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
/* clear up and return */
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_ERROR;
|
||||
done:
|
||||
del_point(mG);
|
||||
ecc_free(&pubkey);
|
||||
mp_clear_multi(&p, &m, &b, NULL);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(md));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
295
gf.c
Normal file
295
gf.c
Normal file
@ -0,0 +1,295 @@
|
||||
/* polynomial basis GF(2^w) routines */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef GF
|
||||
|
||||
#define FORLOOP for (i = 0; i < LSIZE; i++)
|
||||
|
||||
/* c = a + b */
|
||||
void gf_add(gf_intp a, gf_intp b, gf_intp c)
|
||||
{
|
||||
int i;
|
||||
FORLOOP c[i] = a[i]^b[i];
|
||||
}
|
||||
|
||||
/* b = a */
|
||||
void gf_copy(gf_intp a, gf_intp b)
|
||||
{
|
||||
int i;
|
||||
FORLOOP b[i] = a[i];
|
||||
}
|
||||
|
||||
/* a = 0 */
|
||||
void gf_zero(gf_intp a)
|
||||
{
|
||||
int i;
|
||||
FORLOOP a[i] = 0;
|
||||
}
|
||||
|
||||
/* is a zero? */
|
||||
int gf_iszero(gf_intp a)
|
||||
{
|
||||
int i;
|
||||
FORLOOP if (a[i]) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* is a one? */
|
||||
int gf_isone(gf_intp a)
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < LSIZE; i++) {
|
||||
if (a[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return a[0] == 1;
|
||||
}
|
||||
|
||||
/* b = a << 1*/
|
||||
void gf_shl(gf_intp a, gf_intp b)
|
||||
{
|
||||
int i;
|
||||
gf_int tmp;
|
||||
|
||||
gf_copy(a, tmp);
|
||||
for (i = LSIZE-1; i > 0; i--)
|
||||
b[i] = ((tmp[i]<<1)|((tmp[i-1]&0xFFFFFFFFUL)>>31))&0xFFFFFFFFUL;
|
||||
b[0] = (tmp[0] << 1)&0xFFFFFFFFUL;
|
||||
gf_zero(tmp);
|
||||
}
|
||||
|
||||
/* b = a >> 1 */
|
||||
void gf_shr(gf_intp a, gf_intp b)
|
||||
{
|
||||
int i;
|
||||
gf_int tmp;
|
||||
|
||||
gf_copy(a, tmp);
|
||||
for (i = 0; i < LSIZE-1; i++)
|
||||
b[i] = (((tmp[i]&0xFFFFFFFFUL)>>1)|(tmp[i+1]<<31))&0xFFFFFFFFUL;
|
||||
b[LSIZE-1] = (tmp[LSIZE-1]&0xFFFFFFFFUL)>>1;
|
||||
gf_zero(tmp);
|
||||
}
|
||||
|
||||
/* returns -1 if its zero, otherwise degree of a */
|
||||
int gf_deg(gf_intp a)
|
||||
{
|
||||
int i, ii;
|
||||
unsigned long t;
|
||||
|
||||
ii = -1;
|
||||
for (i = LSIZE-1; i >= 0; i--)
|
||||
if (a[i]) {
|
||||
for (t = a[i], ii = 0; t; t >>= 1, ++ii);
|
||||
break;
|
||||
}
|
||||
if (i == -1) i = 0;
|
||||
return (i<<5)+ii;
|
||||
}
|
||||
|
||||
/* c = ab */
|
||||
void gf_mul(gf_intp a, gf_intp b, gf_intp c)
|
||||
{
|
||||
gf_int ta, tb;
|
||||
int i, n;
|
||||
|
||||
gf_copy(a, ta);
|
||||
gf_copy(b, tb);
|
||||
gf_zero(c);
|
||||
n = gf_deg(ta)+1;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (ta[i>>5]&(1<<(i&31)))
|
||||
gf_add(c, tb, c);
|
||||
gf_shl(tb, tb);
|
||||
}
|
||||
gf_zero(ta);
|
||||
gf_zero(tb);
|
||||
}
|
||||
|
||||
/* q = a/b, r = a%b */
|
||||
void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r)
|
||||
{
|
||||
gf_int ta, tb, shifts[LSIZE*32];
|
||||
int i, magb, mag;
|
||||
|
||||
mag = gf_deg(a);
|
||||
magb = gf_deg(b);
|
||||
|
||||
/* special cases */
|
||||
if (magb > mag) {
|
||||
gf_copy(a, r);
|
||||
gf_zero(q);
|
||||
return;
|
||||
}
|
||||
if (magb == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* copy locally */
|
||||
gf_copy(a, ta);
|
||||
gf_copy(b, tb);
|
||||
gf_zero(q);
|
||||
|
||||
/* make shifted versions of "b" */
|
||||
gf_copy(tb, shifts[0]);
|
||||
for (i = 1; i <= (mag-magb); i++)
|
||||
gf_shl(shifts[i-1], shifts[i]);
|
||||
|
||||
while (mag >= magb) {
|
||||
i = (mag - magb);
|
||||
q[i>>5] |= (1<<(i&31));
|
||||
gf_add(ta, shifts[i], ta);
|
||||
mag = gf_deg(ta);
|
||||
}
|
||||
gf_copy(ta, r);
|
||||
gf_zero(ta);
|
||||
gf_zero(tb);
|
||||
zeromem(shifts, sizeof(shifts));
|
||||
}
|
||||
|
||||
/* b = a mod m */
|
||||
void gf_mod(gf_intp a, gf_intp m, gf_intp b)
|
||||
{
|
||||
gf_int tmp;
|
||||
gf_div(a,m,tmp,b);
|
||||
gf_zero(tmp);
|
||||
}
|
||||
|
||||
/* c = ab (mod m) */
|
||||
void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c)
|
||||
{
|
||||
gf_int tmp;
|
||||
gf_mul(a, b, tmp);
|
||||
gf_mod(tmp, m, c);
|
||||
gf_zero(tmp);
|
||||
}
|
||||
|
||||
/* B = 1/A mod M */
|
||||
void gf_invmod(gf_intp A, gf_intp M, gf_intp B)
|
||||
{
|
||||
gf_int m, n, p0, p1, p2, r, q, tmp;
|
||||
|
||||
/* put all variables in known setup state */
|
||||
gf_zero(p0);
|
||||
gf_zero(p2);
|
||||
gf_copy(M, m);
|
||||
gf_copy(A, n);
|
||||
p0[0] = 1;
|
||||
gf_div(m, n, p1, r);
|
||||
gf_copy(p1, q);
|
||||
|
||||
/* loop until r == 0 */
|
||||
while (!gf_iszero(r)) {
|
||||
gf_copy(n, m);
|
||||
gf_copy(r, n);
|
||||
gf_div(m, n, q, r);
|
||||
gf_mul(q, p1, tmp);
|
||||
gf_add(tmp, p0, p2);
|
||||
gf_copy(p1, p0);
|
||||
gf_copy(p2, p1);
|
||||
}
|
||||
gf_copy(p0, B);
|
||||
gf_zero(p0);
|
||||
}
|
||||
|
||||
/* find a square root modulo a prime. Note the number of
|
||||
* elements is 2^k - 1, so we must square k-2 times to get the
|
||||
* square root..
|
||||
*/
|
||||
void gf_sqrt(gf_intp a, gf_intp M, gf_intp b)
|
||||
{
|
||||
int k;
|
||||
k = gf_deg(M)-2;
|
||||
gf_copy(a, b);
|
||||
while (k--)
|
||||
gf_mulmod(b, b, M, b);
|
||||
}
|
||||
|
||||
/* c = gcd(A,B) */
|
||||
void gf_gcd(gf_intp A, gf_intp B, gf_intp c)
|
||||
{
|
||||
gf_int a, b, r;
|
||||
int n;
|
||||
|
||||
gf_add(A, B, r);
|
||||
n = gf_deg(r);
|
||||
if (gf_deg(A) > n) {
|
||||
gf_copy(A, a);
|
||||
gf_copy(B, b);
|
||||
} else {
|
||||
gf_copy(A, b);
|
||||
gf_copy(B, a);
|
||||
}
|
||||
|
||||
do {
|
||||
gf_mod(a, b, r);
|
||||
gf_copy(b, a);
|
||||
gf_copy(r, b);
|
||||
} while (!gf_iszero(r));
|
||||
gf_copy(a, c);
|
||||
gf_zero(a);
|
||||
gf_zero(b);
|
||||
}
|
||||
|
||||
/* returns non-zero if 'a' is irreducible */
|
||||
int gf_is_prime(gf_intp a)
|
||||
{
|
||||
gf_int u, tmp;
|
||||
int m, n;
|
||||
|
||||
gf_zero(u);
|
||||
u[0] = 2; /* u(x) = x */
|
||||
m = gf_deg(a);
|
||||
for (n = 0; n < (m/2); n++) {
|
||||
gf_mulmod(u, u, a, u); /* u(x) = u(x)^2 mod a(x) */
|
||||
gf_copy(u, tmp);
|
||||
tmp[0] ^= 2; /* tmp(x) = u(x) - x */
|
||||
gf_gcd(tmp, a, tmp); /* tmp(x) = gcd(a(x), u(x) - x) */
|
||||
if (!gf_isone(tmp)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* returns bytes required to store a gf_int */
|
||||
int gf_size(gf_intp a)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = gf_deg(a);
|
||||
if (n == -1) {
|
||||
return 4;
|
||||
}
|
||||
n = n + (32 - (n&31));
|
||||
return n/8;
|
||||
}
|
||||
|
||||
/* store a gf_int */
|
||||
void gf_toraw(gf_intp a, unsigned char *dst)
|
||||
{
|
||||
int x, n;
|
||||
n = gf_size(a)/4;
|
||||
for (x = 0; x < n; x++) {
|
||||
STORE32L(a[x], dst);
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
|
||||
/* read a gf_int (len == in bytes) */
|
||||
void gf_readraw(gf_intp a, unsigned char *str, int len)
|
||||
{
|
||||
int x;
|
||||
gf_zero(a);
|
||||
for (x = 0; x < len/4; x++) {
|
||||
LOAD32L(a[x], str);
|
||||
str += 4;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
93
hash.c
Normal file
93
hash.c
Normal file
@ -0,0 +1,93 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned char *dst, unsigned long *outlen)
|
||||
{
|
||||
hash_state md;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(data != NULL);
|
||||
_ARGCHK(dst != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (*outlen < hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
*outlen = hash_descriptor[hash].hashsize;
|
||||
|
||||
hash_descriptor[hash].init(&md);
|
||||
hash_descriptor[hash].process(&md, data, len);
|
||||
hash_descriptor[hash].done(&md, dst);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outlen)
|
||||
{
|
||||
#ifdef NO_FILE
|
||||
return CRYPT_ERROR;
|
||||
#else
|
||||
hash_state md;
|
||||
unsigned char buf[512];
|
||||
int x, errno;
|
||||
|
||||
_ARGCHK(dst != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(in != NULL);
|
||||
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (*outlen < hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
*outlen = hash_descriptor[hash].hashsize;
|
||||
|
||||
hash_descriptor[hash].init(&md);
|
||||
do {
|
||||
x = fread(buf, 1, sizeof(buf), in);
|
||||
hash_descriptor[hash].process(&md, buf, x);
|
||||
} while (x == sizeof(buf));
|
||||
hash_descriptor[hash].done(&md, dst);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *outlen)
|
||||
{
|
||||
#ifdef NO_FILE
|
||||
return CRYPT_ERROR;
|
||||
#else
|
||||
FILE *in;
|
||||
int errno;
|
||||
_ARGCHK(fname != NULL);
|
||||
_ARGCHK(dst != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
in = fopen(fname, "rb");
|
||||
if (in == NULL) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if ((errno = hash_filehandle(hash, in, dst, outlen)) != CRYPT_OK) {
|
||||
fclose(in);
|
||||
return errno;
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
478
hmac.c
Normal file
478
hmac.c
Normal file
@ -0,0 +1,478 @@
|
||||
/* Submited by Dobes Vandermeer (dobes@smartt.com) */
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
/*
|
||||
(1) append zeros to the end of K to create a B byte string
|
||||
(e.g., if K is of length 20 bytes and B=64, then K will be
|
||||
appended with 44 zero bytes 0x00)
|
||||
(2) XOR (bitwise exclusive-OR) the B byte string computed in step
|
||||
(1) with ipad (ipad = the byte 0x36 repeated B times)
|
||||
(3) append the stream of data 'text' to the B byte string resulting
|
||||
from step (2)
|
||||
(4) apply H to the stream generated in step (3)
|
||||
(5) XOR (bitwise exclusive-OR) the B byte string computed in
|
||||
step (1) with opad (opad = the byte 0x5C repeated B times.)
|
||||
(6) append the H result from step (4) to the B byte string
|
||||
resulting from step (5)
|
||||
(7) apply H to the stream generated in step (6) and output
|
||||
the result
|
||||
*/
|
||||
|
||||
#ifdef HMAC
|
||||
|
||||
#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
|
||||
|
||||
int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen)
|
||||
{
|
||||
unsigned char buf[MAXBLOCKSIZE];
|
||||
unsigned long hashsize;
|
||||
unsigned long i, z;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(hmac != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if(key == NULL || keylen == 0) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
hmac->hash = hash;
|
||||
|
||||
// (1) make sure we have a large enough key
|
||||
hmac->hashsize = hashsize = hash_descriptor[hash].hashsize;
|
||||
if(keylen > HMAC_BLOCKSIZE) {
|
||||
z = sizeof(hmac->key);
|
||||
if ((errno = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
if(hashsize < HMAC_BLOCKSIZE) {
|
||||
zeromem(hmac->key+hashsize, HMAC_BLOCKSIZE - hashsize);
|
||||
}
|
||||
} else {
|
||||
memcpy(hmac->key, key, keylen);
|
||||
if(keylen < HMAC_BLOCKSIZE) {
|
||||
zeromem(hmac->key + keylen, HMAC_BLOCKSIZE - keylen);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the initial vector for step (3)
|
||||
for(i=0; i < keylen; i++) {
|
||||
buf[i] = hmac->key[i] ^ 0x36;
|
||||
}
|
||||
|
||||
for( ; i < HMAC_BLOCKSIZE; i++) {
|
||||
buf[i] = 0x36;
|
||||
}
|
||||
|
||||
// Pre-pend that to the hash data
|
||||
hash_descriptor[hash].init(&hmac->md);
|
||||
hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
int errno;
|
||||
_ARGCHK(hmac != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
if ((errno = hash_is_valid(hmac->hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
hash_descriptor[hmac->hash].process(&hmac->md, buf, len);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int hmac_done(hmac_state *hmac, unsigned char *hashOut)
|
||||
{
|
||||
unsigned char buf[MAXBLOCKSIZE];
|
||||
unsigned char isha[MAXBLOCKSIZE];
|
||||
unsigned long hashsize, i;
|
||||
int hash, errno;
|
||||
|
||||
_ARGCHK(hmac != NULL);
|
||||
_ARGCHK(hashOut != NULL);
|
||||
|
||||
hash = hmac->hash;
|
||||
if((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
// Get the hash of the first HMAC vector plus the data
|
||||
hash_descriptor[hash].done(&hmac->md, isha);
|
||||
|
||||
// Create the second HMAC vector vector for step (3)
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
for(i=0; i < HMAC_BLOCKSIZE; i++) {
|
||||
buf[i] = hmac->key[i] ^ 0x5C;
|
||||
}
|
||||
|
||||
// Now calculate the "outer" hash for step (5), (6), and (7)
|
||||
hash_descriptor[hash].init(&hmac->md);
|
||||
hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE);
|
||||
hash_descriptor[hash].process(&hmac->md, isha, hashsize);
|
||||
hash_descriptor[hash].done(&hmac->md, hashOut);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(hmac->key, sizeof(hmac->key));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *data, unsigned long len, unsigned char *dst)
|
||||
{
|
||||
hmac_state hmac;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(data != NULL);
|
||||
_ARGCHK(dst != NULL);
|
||||
|
||||
if ((errno = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = hmac_process(&hmac, data, len)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = hmac_done(&hmac, dst)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* hmac_file added by Tom St Denis */
|
||||
int hmac_file(int hash, const char *fname, const unsigned char *key,
|
||||
unsigned long keylen, unsigned char *dst)
|
||||
{
|
||||
#ifdef NO_FILE
|
||||
return CRYPT_ERROR;
|
||||
#else
|
||||
hmac_state hmac;
|
||||
FILE *in;
|
||||
unsigned char buf[512];
|
||||
int x, errno;
|
||||
|
||||
_ARGCHK(fname != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(dst != NULL);
|
||||
|
||||
if ((errno = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
in = fopen(fname, "rb");
|
||||
if (in == NULL) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* process the file contents */
|
||||
do {
|
||||
x = fread(buf, 1, sizeof(buf), in);
|
||||
if ((errno = hmac_process(&hmac, buf, x)) != CRYPT_OK) {
|
||||
fclose(in);
|
||||
return errno;
|
||||
}
|
||||
} while (x == sizeof(buf));
|
||||
fclose(in);
|
||||
|
||||
/* get final hmac */
|
||||
if ((errno = hmac_done(&hmac, dst)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clear memory */
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
TEST CASES SOURCE:
|
||||
|
||||
Network Working Group P. Cheng
|
||||
Request for Comments: 2202 IBM
|
||||
Category: Informational R. Glenn
|
||||
NIST
|
||||
September 1997
|
||||
|
||||
Test Cases for HMAC-MD5 and HMAC-SHA-1
|
||||
*/
|
||||
|
||||
|
||||
int hmac_test(void)
|
||||
{
|
||||
unsigned char digest[MAXBLOCKSIZE];
|
||||
int i;
|
||||
|
||||
struct hmac_test_case {
|
||||
int num;
|
||||
char *algo;
|
||||
unsigned char key[128];
|
||||
int keylen;
|
||||
unsigned char data[128];
|
||||
int datalen;
|
||||
unsigned char digest[MAXBLOCKSIZE];
|
||||
} cases[] = {
|
||||
/*
|
||||
3. Test Cases for HMAC-SHA-1
|
||||
|
||||
test_case = 1
|
||||
key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
|
||||
key_len = 20
|
||||
data = "Hi Ther 20
|
||||
digest = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04
|
||||
digest-96 = 0x4c1a03424b55e07fe7f27be1
|
||||
*/
|
||||
{ 5, "sha1",
|
||||
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c}, 20,
|
||||
"Test With Truncation", 20,
|
||||
{0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2,
|
||||
0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04} },
|
||||
|
||||
/*
|
||||
test_case = 6
|
||||
key = 0xaa repeated 80 times
|
||||
key_len = 80
|
||||
data = "Test Using Larger Than Block-Size Key - Hash Key First"
|
||||
data_len = 54
|
||||
digest = 0xaa4ae5e15272d00e95705637ce8a3b55ed402112
|
||||
*/
|
||||
{ 6, "sha1",
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
|
||||
"Test Using Larger Than Block-Size Key - Hash Key First", 54,
|
||||
{0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
|
||||
0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
|
||||
0xed, 0x40, 0x21, 0x12} },
|
||||
|
||||
/*
|
||||
test_case = 7
|
||||
key = 0xaa repeated 80 times
|
||||
key_len = 80
|
||||
data = "Test Using Larger Than Block-Size Key and Larger
|
||||
Than One Block-Size Data"
|
||||
data_len = 73
|
||||
digest = 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91
|
||||
*/
|
||||
{ 7, "sha1",
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
|
||||
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
|
||||
{0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d,
|
||||
0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91} },
|
||||
|
||||
/*
|
||||
2. Test Cases for HMAC-MD5
|
||||
|
||||
test_case = 1
|
||||
key = 0x0b 0b 0b 0b
|
||||
0b 0b 0b 0b
|
||||
0b 0b 0b 0b
|
||||
0b 0b 0b 0b
|
||||
key_len = 16
|
||||
data = "Hi There"
|
||||
data_len = 8
|
||||
digest = 0x92 94 72 7a
|
||||
36 38 bb 1c
|
||||
13 f4 8e f8
|
||||
15 8b fc 9d
|
||||
*/
|
||||
{ 1, "md5",
|
||||
{0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, 16,
|
||||
"Hi There", 8,
|
||||
{0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
|
||||
0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d} },
|
||||
/*
|
||||
test_case = 2
|
||||
key = "Jefe"
|
||||
key_len = 4
|
||||
data = "what do ya want for nothing?"
|
||||
data_len = 28
|
||||
digest = 0x750c783e6ab0b503eaa86e310a5db738
|
||||
*/
|
||||
{ 2, "md5",
|
||||
"Jefe", 4,
|
||||
"what do ya want for nothing?", 28,
|
||||
{0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
|
||||
0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38} },
|
||||
|
||||
/*
|
||||
test_case = 3
|
||||
key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
key_len 16
|
||||
data = 0xdd repeated 50 times
|
||||
data_len = 50
|
||||
digest = 0x56be34521d144c88dbb8c733f0e8b3f6
|
||||
*/
|
||||
{ 3, "md5",
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 16,
|
||||
{0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd}, 50,
|
||||
{0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
|
||||
0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6} },
|
||||
/*
|
||||
|
||||
test_case = 4
|
||||
key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819
|
||||
key_len 25
|
||||
data = 0xcd repeated 50 times
|
||||
data_len = 50
|
||||
digest = 0x697eaf0aca3a3aea3a75164746ffaa79
|
||||
*/
|
||||
{ 4, "md5",
|
||||
{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
|
||||
0x15, 0x16, 0x17, 0x18, 0x19}, 25,
|
||||
{0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd}, 50,
|
||||
{0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
|
||||
0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79} },
|
||||
|
||||
|
||||
/*
|
||||
|
||||
test_case = 5
|
||||
key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
|
||||
key_len = 16
|
||||
data = "Test With Truncation"
|
||||
data_len = 20
|
||||
digest = 0x56461ef2342edc00f9bab995690efd4c
|
||||
digest-96 0x56461ef2342edc00f9bab995
|
||||
*/
|
||||
{ 5, "md5",
|
||||
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}, 16,
|
||||
"Test With Truncation", 20,
|
||||
{0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00,
|
||||
0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c} },
|
||||
|
||||
/*
|
||||
|
||||
test_case = 6
|
||||
key = 0xaa repeated 80 times
|
||||
key_len = 80
|
||||
data = "Test Using Larger Than Block-Size Key - Hash
|
||||
Key First"
|
||||
data_len = 54
|
||||
digest = 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd
|
||||
*/
|
||||
{ 6, "md5",
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
|
||||
"Test Using Larger Than Block-Size Key - Hash Key First", 54,
|
||||
{0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
|
||||
0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd} },
|
||||
|
||||
/*
|
||||
|
||||
test_case = 7
|
||||
key = 0xaa repeated 80 times
|
||||
key_len = 80
|
||||
data = "Test Using Larger Than Block-Size Key and Larger
|
||||
Than One Block-Size Data"
|
||||
data_len = 73
|
||||
digest = 0x6f630fad67cda0ee1fb1f562db3aa53e
|
||||
*/
|
||||
{ 7, "md5",
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
|
||||
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
|
||||
{0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
|
||||
0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e} }
|
||||
};
|
||||
|
||||
int errno;
|
||||
int failed=0;
|
||||
for(i=0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
|
||||
int hash = find_hash(cases[i].algo);
|
||||
if((errno = hmac_memory(hash, cases[i].key, cases[i].keylen, cases[i].data, cases[i].datalen, digest)) != CRYPT_OK) {
|
||||
#if 0
|
||||
printf("HMAC-%s test #%d\n", cases[i].algo, cases[i].num);
|
||||
#endif
|
||||
return errno;
|
||||
}
|
||||
|
||||
if(memcmp(digest, cases[i].digest, hash_descriptor[hash].hashsize) != 0) {
|
||||
#if 0
|
||||
unsigned int j;
|
||||
printf("\nHMAC-%s test #%d:\n", cases[i].algo, cases[i].num);
|
||||
printf( "Result: 0x");
|
||||
for(j=0; j < hash_descriptor[hash].hashsize; j++) {
|
||||
printf("%2x ", digest[j]);
|
||||
}
|
||||
printf("\nCorrect: 0x");
|
||||
for(j=0; j < hash_descriptor[hash].hashsize; j++) {
|
||||
printf("%2x ", cases[i].digest[j]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed++;
|
||||
//return CRYPT_ERROR;
|
||||
} else {
|
||||
/* printf("HMAC-%s test #%d: Passed\n", cases[i].algo, cases[i].num); */
|
||||
}
|
||||
}
|
||||
|
||||
if(failed) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
840
keyring.c
Normal file
840
keyring.c
Normal file
@ -0,0 +1,840 @@
|
||||
/* Provides keyring functionality for libtomcrypt, Tom St Denis */
|
||||
#include <mycrypt.h>
|
||||
|
||||
#ifdef KR
|
||||
|
||||
static const unsigned char key_magic[4] = { 0x12, 0x34, 0x56, 0x78 };
|
||||
static const unsigned char file_magic[4] = { 0x9A, 0xBC, 0xDE, 0xF0 };
|
||||
static const unsigned char sign_magic[4] = { 0x87, 0x56, 0x43, 0x21 };
|
||||
static const unsigned char enc_magic[4] = { 0x0F, 0xED, 0xCB, 0xA9 };
|
||||
|
||||
static const unsigned long crc_table[256] = {
|
||||
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
|
||||
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
|
||||
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
|
||||
0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
|
||||
0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
|
||||
0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
|
||||
0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
|
||||
0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
|
||||
0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
|
||||
0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
|
||||
0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
|
||||
0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
|
||||
0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
|
||||
0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
|
||||
0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
|
||||
0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
|
||||
0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
|
||||
0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
|
||||
0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
|
||||
0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
|
||||
0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
|
||||
0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
|
||||
0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
|
||||
0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
|
||||
0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
|
||||
0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
|
||||
0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
|
||||
0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
|
||||
0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
|
||||
0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
|
||||
0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
|
||||
0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
|
||||
0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
|
||||
0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
|
||||
0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
|
||||
0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
|
||||
0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
|
||||
0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
|
||||
0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
|
||||
0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
|
||||
0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
|
||||
0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
|
||||
0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
|
||||
0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
|
||||
0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
|
||||
0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
|
||||
0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
|
||||
0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
|
||||
0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
|
||||
0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
|
||||
0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
|
||||
0x2d02ef8dL
|
||||
};
|
||||
|
||||
#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
|
||||
#define DO2(buf) DO1(buf); DO1(buf);
|
||||
#define DO4(buf) DO2(buf); DO2(buf);
|
||||
#define DO8(buf) DO4(buf); DO4(buf);
|
||||
|
||||
static unsigned long crc32 (unsigned long crc, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
crc = crc ^ 0xffffffffL;
|
||||
while (len >= 8)
|
||||
{
|
||||
DO8 (buf);
|
||||
len -= 8;
|
||||
}
|
||||
if (len)
|
||||
do
|
||||
{
|
||||
DO1 (buf);
|
||||
}
|
||||
while (--len);
|
||||
return crc ^ 0xffffffffUL;
|
||||
}
|
||||
|
||||
int kr_init(pk_key **pk)
|
||||
{
|
||||
_ARGCHK(pk != NULL);
|
||||
|
||||
*pk = XCALLOC(1, sizeof(pk_key));
|
||||
if (*pk == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
(*pk)->system = NON_KEY;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
unsigned long kr_crc(const unsigned char *name, const unsigned char *email, const unsigned char *description)
|
||||
{
|
||||
unsigned long crc;
|
||||
_ARGCHK(name != NULL);
|
||||
_ARGCHK(email != NULL);
|
||||
_ARGCHK(description != NULL);
|
||||
crc = crc32(0, NULL, 0);
|
||||
crc = crc32(crc, name, MIN(MAXLEN, strlen((char *)name)));
|
||||
crc = crc32(crc, email, MIN(MAXLEN, strlen((char *)email)));
|
||||
return crc32(crc, description, MIN(MAXLEN, strlen((char *)description)));
|
||||
}
|
||||
|
||||
pk_key *kr_find(pk_key *pk, unsigned long ID)
|
||||
{
|
||||
_ARGCHK(pk != NULL);
|
||||
|
||||
while (pk != NULL) {
|
||||
if (pk->system != NON_KEY && pk->ID == ID) {
|
||||
return pk;
|
||||
}
|
||||
pk = pk->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pk_key *kr_find_name(pk_key *pk, const char *name)
|
||||
{
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(name != NULL);
|
||||
|
||||
while (pk != NULL) {
|
||||
if (pk->system != NON_KEY && !strncmp((char *)pk->name, (char *)name, sizeof(pk->name)-1)) {
|
||||
return pk;
|
||||
}
|
||||
pk = pk->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int kr_add(pk_key *pk, int key_type, int system, const unsigned char *name,
|
||||
const unsigned char *email, const unsigned char *description, const _pk_key *key)
|
||||
{
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(name != NULL);
|
||||
_ARGCHK(email != NULL);
|
||||
_ARGCHK(description != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check parameters */
|
||||
if (key_type != PK_PRIVATE && key_type != PK_PRIVATE_OPTIMIZED && key_type != PK_PUBLIC) {
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
if (system != RSA_KEY && system != DH_KEY && system != ECC_KEY) {
|
||||
return CRYPT_PK_INVALID_SYSTEM;
|
||||
}
|
||||
|
||||
/* see if its a dupe */
|
||||
if (kr_find(pk, kr_crc(name, email, description)) != NULL) {
|
||||
return CRYPT_PK_DUP;
|
||||
}
|
||||
|
||||
/* find spot in key ring */
|
||||
while (pk->system != NON_KEY) {
|
||||
if (pk->next == NULL) {
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
pk = pk->next;
|
||||
}
|
||||
|
||||
/* now we have a spot make a next spot */
|
||||
pk->next = XCALLOC(1, sizeof(pk_key));
|
||||
if (pk->next == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
pk->next->system = NON_KEY;
|
||||
|
||||
/* now add this new data to this ring spot */
|
||||
pk->key_type = key_type;
|
||||
pk->system = system;
|
||||
strncpy((char *)pk->name, (char *)name, sizeof(pk->name)-1);
|
||||
strncpy((char *)pk->email, (char *)email, sizeof(pk->email)-1);
|
||||
strncpy((char *)pk->description, (char *)description, sizeof(pk->description)-1);
|
||||
pk->ID = kr_crc(pk->name, pk->email, pk->description);
|
||||
|
||||
/* clear the memory area */
|
||||
zeromem(&(pk->key), sizeof(pk->key));
|
||||
|
||||
/* copy the key */
|
||||
switch (system) {
|
||||
case RSA_KEY:
|
||||
memcpy(&(pk->key.rsa), &(key->rsa), sizeof(key->rsa));
|
||||
break;
|
||||
case DH_KEY:
|
||||
memcpy(&(pk->key.dh), &(key->dh), sizeof(key->dh));
|
||||
break;
|
||||
case ECC_KEY:
|
||||
memcpy(&(pk->key.ecc), &(key->ecc), sizeof(key->ecc));
|
||||
break;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int kr_del(pk_key **_pk, unsigned long ID)
|
||||
{
|
||||
pk_key *ppk, *pk;
|
||||
|
||||
_ARGCHK(_pk != NULL);
|
||||
|
||||
pk = *_pk;
|
||||
ppk = NULL;
|
||||
while (pk->system != NON_KEY && pk->ID != ID) {
|
||||
ppk = pk;
|
||||
pk = pk->next;
|
||||
if (pk == NULL) {
|
||||
return CRYPT_PK_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
switch (pk->system) {
|
||||
case RSA_KEY:
|
||||
rsa_free(&(pk->key.rsa));
|
||||
break;
|
||||
case DH_KEY:
|
||||
dh_free(&(pk->key.dh));
|
||||
break;
|
||||
case ECC_KEY:
|
||||
ecc_free(&(pk->key.ecc));
|
||||
break;
|
||||
}
|
||||
|
||||
if (ppk == NULL) { /* the first element matches the ID */
|
||||
ppk = pk->next; /* get the 2nd element */
|
||||
XFREE(pk); /* free the first */
|
||||
*_pk = ppk; /* make the first element the second */
|
||||
} else { /* (not) first element matches the ID */
|
||||
ppk->next = pk->next; /* make the previous'es next point to the current next */
|
||||
XFREE(pk); /* free the element */
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int kr_clear(pk_key **pk)
|
||||
{
|
||||
int errno;
|
||||
_ARGCHK(pk != NULL);
|
||||
|
||||
while ((*pk)->system != NON_KEY) {
|
||||
if ((errno = kr_del(pk, (*pk)->ID)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
XFREE(*pk);
|
||||
*pk = NULL;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
static unsigned long _write(unsigned char *buf, unsigned long len, FILE *f, symmetric_CTR *ctr)
|
||||
{
|
||||
#ifdef NO_FILE
|
||||
return 0;
|
||||
#else
|
||||
_ARGCHK(buf != NULL);
|
||||
_ARGCHK(f != NULL);
|
||||
if (ctr != NULL) {
|
||||
if (ctr_encrypt(buf, buf, len, ctr) != CRYPT_OK) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return fwrite(buf, 1, len, f);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned long _read(unsigned char *buf, unsigned long len, FILE *f, symmetric_CTR *ctr)
|
||||
{
|
||||
#ifdef NO_FILE
|
||||
return 0;
|
||||
#else
|
||||
unsigned long y;
|
||||
_ARGCHK(buf != NULL);
|
||||
_ARGCHK(f != NULL);
|
||||
y = fread(buf, 1, len, f);
|
||||
if (ctr != NULL) {
|
||||
if (ctr_decrypt(buf, buf, y, ctr) != CRYPT_OK) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return y;
|
||||
#endif
|
||||
}
|
||||
|
||||
int kr_export(pk_key *pk, unsigned long ID, int key_type, unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned char buf[8192], *obuf;
|
||||
pk_key *ppk;
|
||||
unsigned long len;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* find the desired key */
|
||||
ppk = kr_find(pk, ID);
|
||||
if (ppk == NULL) {
|
||||
return CRYPT_PK_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (ppk->key_type == PK_PUBLIC && key_type != PK_PUBLIC) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* this makes PK_PRIVATE an alias for PK_PRIVATE_OPTIMIZED type */
|
||||
if (ppk->key_type == PK_PRIVATE_OPTIMIZED && key_type == PK_PRIVATE) {
|
||||
key_type = PK_PRIVATE_OPTIMIZED;
|
||||
}
|
||||
|
||||
/* now copy the header and various other details */
|
||||
memcpy(buf, key_magic, 4); /* magic info */
|
||||
buf[4] = key_type; /* key type */
|
||||
buf[5] = ppk->system; /* system */
|
||||
STORE32L(ppk->ID, buf+6); /* key ID */
|
||||
memcpy(buf+10, ppk->name, MAXLEN); /* the name */
|
||||
memcpy(buf+10+MAXLEN, ppk->email, MAXLEN); /* the email */
|
||||
memcpy(buf+10+MAXLEN+MAXLEN, ppk->description, MAXLEN); /* the description */
|
||||
|
||||
/* export key */
|
||||
len = sizeof(buf) - (6 + 4 + MAXLEN*3);
|
||||
obuf = buf+6+4+MAXLEN*3;
|
||||
switch (ppk->system) {
|
||||
case RSA_KEY:
|
||||
if ((errno = rsa_export(obuf, &len, key_type, &(ppk->key.rsa))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case DH_KEY:
|
||||
if ((errno = dh_export(obuf, &len, key_type, &(ppk->key.dh))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case ECC_KEY:
|
||||
if ((errno = ecc_export(obuf, &len, key_type, &(ppk->key.ecc))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* get the entire length of the packet */
|
||||
len += 6 + 4 + 3*MAXLEN;
|
||||
|
||||
if (*outlen < len) {
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
} else {
|
||||
*outlen = len;
|
||||
memcpy(out, buf, len);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int kr_import(pk_key *pk, const unsigned char *in)
|
||||
{
|
||||
_pk_key key;
|
||||
int system, key_type, errno;
|
||||
unsigned long ID;
|
||||
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(in != NULL);
|
||||
|
||||
if (memcmp(in, key_magic, 4)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
key_type = in[4]; /* get type */
|
||||
system = in[5]; /* get system */
|
||||
LOAD32L(ID,in+6); /* the ID */
|
||||
|
||||
if (ID != kr_crc(in+10, in+10+MAXLEN, in+10+MAXLEN+MAXLEN)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
zeromem(&key, sizeof(key));
|
||||
switch (system) {
|
||||
case RSA_KEY:
|
||||
if ((errno = rsa_import(in+10+3*MAXLEN, &(key.rsa))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case DH_KEY:
|
||||
if ((errno = dh_import(in+10+3*MAXLEN, &(key.dh))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case ECC_KEY:
|
||||
if ((errno = ecc_import(in+10+3*MAXLEN, &(key.ecc))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return kr_add(pk, key_type, system,
|
||||
in+10, /* the name */
|
||||
in+10+MAXLEN, /* email address */
|
||||
in+10+MAXLEN+MAXLEN, /* description */
|
||||
&key);
|
||||
}
|
||||
|
||||
|
||||
int kr_load(pk_key **pk, FILE *in, symmetric_CTR *ctr)
|
||||
{
|
||||
unsigned char buf[8192], blen[4];
|
||||
unsigned long len;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(in != NULL);
|
||||
|
||||
/* init keyring */
|
||||
if ((errno = kr_init(pk)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* read in magic bytes */
|
||||
if (_read(buf, 6, in, ctr) != 6) { goto done2; }
|
||||
|
||||
if (memcmp(buf, file_magic, 4)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
len = (unsigned long)buf[4] | ((unsigned long)buf[5] << 8);
|
||||
if (len > CRYPT) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* while there are lengths to read... */
|
||||
while (_read(blen, 4, in, ctr) == 4) {
|
||||
/* get length */
|
||||
LOAD32L(len, blen);
|
||||
|
||||
if (len > sizeof(buf)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
if (_read(buf, len, in, ctr) != len) { goto done2; }
|
||||
if ((errno = kr_import(*pk, buf)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
done2:
|
||||
res = CRYPT_ERROR;
|
||||
done:
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
int kr_save(pk_key *pk, FILE *out, symmetric_CTR *ctr)
|
||||
{
|
||||
unsigned char buf[8192], blen[4];
|
||||
unsigned long len;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
|
||||
/* write out magic bytes */
|
||||
memcpy(buf, file_magic, 4);
|
||||
buf[4] = CRYPT&255;
|
||||
buf[5] = (CRYPT>>8)&255;
|
||||
if (_write(buf, 6, out, ctr) != 6) { goto done2; }
|
||||
|
||||
while (pk->system != NON_KEY) {
|
||||
len = sizeof(buf);
|
||||
if ((errno = kr_export(pk, pk->ID, pk->key_type, buf, &len)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
STORE32L(len, blen);
|
||||
if (_write(blen, 4, out, ctr) != 4) { goto done2; }
|
||||
if (_write(buf, len, out, ctr) != len) { goto done2; }
|
||||
|
||||
pk = pk->next;
|
||||
}
|
||||
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
done2:
|
||||
res = CRYPT_ERROR;
|
||||
done:
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
int kr_make_key(pk_key *pk, prng_state *prng, int wprng,
|
||||
int system, int keysize, const unsigned char *name,
|
||||
const unsigned char *email, const unsigned char *description)
|
||||
{
|
||||
_pk_key key;
|
||||
int key_type, errno;
|
||||
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(name != NULL);
|
||||
_ARGCHK(email != NULL);
|
||||
_ARGCHK(description != NULL);
|
||||
|
||||
/* valid PRNG? */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* make the key first */
|
||||
zeromem(&key, sizeof(key));
|
||||
switch (system) {
|
||||
case RSA_KEY:
|
||||
if ((errno = rsa_make_key(prng, wprng, keysize, 65537, &(key.rsa))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
key_type = key.rsa.type;
|
||||
break;
|
||||
case DH_KEY:
|
||||
if ((errno = dh_make_key(prng, wprng, keysize, &(key.dh))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
key_type = key.dh.type;
|
||||
break;
|
||||
case ECC_KEY:
|
||||
if ((errno = ecc_make_key(prng, wprng, keysize, &(key.ecc))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
key_type = key.ecc.type;
|
||||
break;
|
||||
default:
|
||||
return CRYPT_PK_INVALID_SYSTEM;
|
||||
}
|
||||
|
||||
/* now add the key */
|
||||
if ((errno = kr_add(pk, key_type, system, name, email, description, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(&key, sizeof(key));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int kr_encrypt_key(pk_key *pk, unsigned long ID,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash)
|
||||
{
|
||||
unsigned char buf[8192];
|
||||
unsigned long len;
|
||||
pk_key *kr;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* find the key */
|
||||
kr = kr_find(pk, ID);
|
||||
if (kr == NULL) {
|
||||
return CRYPT_PK_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* store the header */
|
||||
memcpy(buf, enc_magic, 4);
|
||||
|
||||
/* now store the ID */
|
||||
STORE32L(kr->ID,buf+4);
|
||||
|
||||
/* now encrypt it */
|
||||
len = sizeof(buf)-8;
|
||||
switch (kr->system) {
|
||||
case RSA_KEY:
|
||||
if ((errno = rsa_encrypt_key(in, inlen, buf+8, &len, prng, wprng, &(kr->key.rsa))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case DH_KEY:
|
||||
if ((errno = dh_encrypt_key(in, inlen, buf+8, &len, prng, wprng, hash, &(kr->key.dh))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case ECC_KEY:
|
||||
if ((errno = ecc_encrypt_key(in, inlen, buf+8, &len, prng, wprng, hash, &(kr->key.ecc))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
len += 8;
|
||||
|
||||
if (len > *outlen) {
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
} else {
|
||||
memcpy(out, buf, len);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
*outlen = len;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int kr_decrypt_key(pk_key *pk, const unsigned char *in,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned char buf[8192];
|
||||
unsigned long len, ID;
|
||||
pk_key *kr;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* check magic header */
|
||||
if (memcmp(in, enc_magic, 4)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* now try to find key */
|
||||
LOAD32L(ID,in+4);
|
||||
kr = kr_find(pk, ID);
|
||||
if (kr == NULL) {
|
||||
return CRYPT_PK_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* is it public? */
|
||||
if (kr->key_type == PK_PUBLIC) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* now try and decrypt it */
|
||||
len = sizeof(buf);
|
||||
switch (kr->system) {
|
||||
case RSA_KEY:
|
||||
if ((errno = rsa_decrypt_key(in+8, buf, &len, &(kr->key.rsa))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case DH_KEY:
|
||||
if ((errno = dh_decrypt_key(in+8, buf, &len, &(kr->key.dh))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case ECC_KEY:
|
||||
if ((errno = ecc_decrypt_key(in+8, buf, &len, &(kr->key.ecc))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (len > *outlen) {
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
} else {
|
||||
memcpy(out, buf, len);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
*outlen = len;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int kr_sign_hash(pk_key *pk, unsigned long ID,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng)
|
||||
{
|
||||
unsigned char buf[8192];
|
||||
unsigned long len;
|
||||
pk_key *kr;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* find the key */
|
||||
kr = kr_find(pk, ID);
|
||||
if (kr == NULL) {
|
||||
return CRYPT_PK_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* is it public? */
|
||||
if (kr->key_type == PK_PUBLIC) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* store the header */
|
||||
memcpy(buf, sign_magic, 4);
|
||||
|
||||
/* now store the ID */
|
||||
STORE32L(kr->ID,buf+4);
|
||||
|
||||
/* now sign it */
|
||||
len = sizeof(buf)-12;
|
||||
switch (kr->system) {
|
||||
case RSA_KEY:
|
||||
if ((errno = rsa_sign_hash(in, inlen, buf+12, &len, &(kr->key.rsa))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case DH_KEY:
|
||||
if ((errno = dh_sign_hash(in, inlen, buf+12, &len, prng, wprng, &(kr->key.dh))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case ECC_KEY:
|
||||
if ((errno = ecc_sign_hash(in, inlen, buf+12, &len, prng, wprng, &(kr->key.ecc))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
STORE32L(inlen,buf+8);
|
||||
len += 12;
|
||||
|
||||
if (len > *outlen) {
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
} else {
|
||||
memcpy(out, buf, len);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
*outlen = len;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int kr_verify_hash(pk_key *pk, const unsigned char *in, const unsigned char *hash,
|
||||
unsigned long hashlen, int *stat)
|
||||
{
|
||||
unsigned long inlen, ID;
|
||||
pk_key *kr;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
_ARGCHK(stat != NULL);
|
||||
|
||||
/* default to not match */
|
||||
*stat = 0;
|
||||
|
||||
/* check magic header */
|
||||
if (memcmp(in, sign_magic, 4)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* now try to find key */
|
||||
LOAD32L(ID,in+4);
|
||||
kr = kr_find(pk, ID);
|
||||
if (kr == NULL) {
|
||||
return CRYPT_PK_NOT_FOUND;
|
||||
}
|
||||
|
||||
/* now try and verify it */
|
||||
LOAD32L(inlen,in+8); /* this is the length of the original inlen */
|
||||
if (inlen != hashlen) { /* size doesn't match means the signature is invalid */
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
switch (kr->system) {
|
||||
case RSA_KEY:
|
||||
if ((errno = rsa_verify_hash(in+12, hash, stat, &(kr->key.rsa))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case DH_KEY:
|
||||
if ((errno = dh_verify_hash(in+12, hash, inlen, stat, &(kr->key.dh))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
case ECC_KEY:
|
||||
if ((errno = ecc_verify_hash(in+12, hash, inlen, stat, &(kr->key.ecc))) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int kr_fingerprint(pk_key *pk, unsigned long ID, int hash,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned char buf[8192];
|
||||
unsigned long len;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(pk != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* valid hash? */
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
len = sizeof(buf);
|
||||
if ((errno = kr_export(pk, ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* now hash it */
|
||||
if ((errno = hash_memory(hash, buf, len, out, outlen)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
262
makefile
Normal file
262
makefile
Normal file
@ -0,0 +1,262 @@
|
||||
# MAKEFILE for linux GCC
|
||||
#
|
||||
# Tom St Denis
|
||||
# Modified by Clay Culver
|
||||
#
|
||||
# NOTE: This should later be replaced by autoconf/automake scripts, but for
|
||||
# the time being this is actually pretty clean. The only ugly part is
|
||||
# handling CFLAGS so that the x86 specific optimizations don't break
|
||||
# a build. This is easy to remedy though, for those that have problems.
|
||||
|
||||
# The version
|
||||
VERSION=0.75
|
||||
|
||||
#Compiler and Linker Names
|
||||
CC=gcc
|
||||
LD=ld
|
||||
|
||||
#Archiver [makes .a files]
|
||||
AR=ar
|
||||
ARFLAGS=rs
|
||||
|
||||
#here you can set the malloc/calloc/free functions you want
|
||||
XMALLOC=malloc
|
||||
XCALLOC=calloc
|
||||
XFREE=free
|
||||
|
||||
#you can redefine the clock
|
||||
XCLOCK=clock
|
||||
XCLOCKS_PER_SEC=CLOCKS_PER_SEC
|
||||
|
||||
#Compilation flags. Note the += does not write over the user's CFLAGS!
|
||||
CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Werror \
|
||||
-DXMALLOC=$(XMALLOC) -DXCALLOC=$(XCALLOC) -DXFREE=$(XFREE) -DXCLOCK=$(XCLOCK) \
|
||||
-DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC)
|
||||
|
||||
#optimize for SPEED (comment out SIZE/DEBUG line as well)
|
||||
#CFLAGS += -O3 -fomit-frame-pointer -funroll-loops
|
||||
|
||||
#optimize for SIZE (comment out SPEED/DEBUG line as well)
|
||||
CFLAGS += -O2
|
||||
|
||||
#compile for DEBUGGING
|
||||
#CFLAGS += -g3
|
||||
|
||||
#These flags control how the library gets built.
|
||||
|
||||
#no file support, when defined the library will not have any functions that can read/write files
|
||||
#(comment out to have file support)
|
||||
#CFLAGS += -DNO_FILE
|
||||
|
||||
#Support the UNIX /dev/random or /dev/urandom
|
||||
CFLAGS += -DDEVRANDOM
|
||||
|
||||
# Use /dev/urandom first on devices where /dev/random is too slow */
|
||||
#CFLAGS += -DTRY_URANDOM_FIRST
|
||||
|
||||
# Clean the stack after sensitive functions. Not always required...
|
||||
# With this defined most of the ciphers and hashes will clean their stack area
|
||||
# after usage with a (sometimes) huge penalty in speed. Normally this is not
|
||||
# required if you simply lock your stack and wipe it when your program is done.
|
||||
#
|
||||
#CFLAGS += -DCLEAN_STACK
|
||||
|
||||
# What algorithms to include? comment out and rebuild to remove em
|
||||
CFLAGS += -DBLOWFISH
|
||||
CFLAGS += -DRC2
|
||||
CFLAGS += -DRC5
|
||||
CFLAGS += -DRC6
|
||||
CFLAGS += -DSERPENT
|
||||
CFLAGS += -DSAFERP
|
||||
CFLAGS += -DSAFER
|
||||
CFLAGS += -DRIJNDAEL
|
||||
CFLAGS += -DXTEA
|
||||
CFLAGS += -DTWOFISH
|
||||
CFLAGS += -DDES
|
||||
CFLAGS += -DCAST5
|
||||
|
||||
#You can also customize the Twofish code. All four combinations
|
||||
#of the flags are possible but only three of them make sense.
|
||||
#
|
||||
#Both undefined: Very fast, requires ~4.2KB of ram per scheduled key
|
||||
#Both defined : Slow, requires only ~100 bytes of ram per scheduled key
|
||||
#
|
||||
#If defined on their own
|
||||
#_SMALL defined: Very Slow, small code only ~100 bytes of ram
|
||||
#_TABLES defined: Very fast, not faster than if both were undefined. Code is ~1KB bigger
|
||||
# faster keysetup though...
|
||||
|
||||
# Small Ram Variant of Twofish. For this you must have TWOFISH defined. This
|
||||
# variant requires about 4kb less memory but is considerably slower. It is ideal
|
||||
# when high throughput is less important than conserving memory. By default it is
|
||||
# not defined which means the larger ram (about 4.2Kb used) variant is built.
|
||||
#CFLAGS += -DTWOFISH_SMALL
|
||||
|
||||
# Tell Twofish to use precomputed tables. If you want to use the small table
|
||||
# variant of Twofish you may want to turn this on. Essentially it tells Twofish to use
|
||||
# precomputed S-boxes (Q0 and Q1) as well as precomputed GF multiplications [in the MDS].
|
||||
# This speeds up the cipher somewhat.
|
||||
#CFLAGS += -DTWOFISH_TABLES
|
||||
|
||||
#Small code variant of the SAFER+ cipher, uses same RAM but less code space
|
||||
#With this defined the cipher is slower. On my x86 with GCC 3.2 it required 50KB less space
|
||||
CFLAGS += -DSAFERP_SMALL
|
||||
|
||||
#Small Rijndael [saves 13KB on an x86]
|
||||
#With this defined the cipher is slower (by 50Mbit/sec on an Athon XP)
|
||||
CFLAGS += -DRIJNDAEL_SMALL
|
||||
|
||||
#Use fast PK routines. Basically this limits the size of the private key in the
|
||||
#DH system to 256 bits. The group order remains unchanged so the best
|
||||
#attacks are still GNFS (for DH upto 2560-bits)
|
||||
#
|
||||
#This will only speed up the key generation and encryption routines. It lowers the
|
||||
#security so its by default not turned on. USE AT YOUR RISK!
|
||||
#CFLAGS += -DFAST_PK
|
||||
|
||||
#Include the PK Packet functions (e.g. dh_encrypt)
|
||||
#Does not affect the key/hash routines (e.g. ecc_sign_hash)
|
||||
#CFLAGS += -DPK_PACKET
|
||||
|
||||
# Chaining modes
|
||||
CFLAGS += -DCFB
|
||||
CFLAGS += -DOFB
|
||||
CFLAGS += -DECB
|
||||
CFLAGS += -DCBC
|
||||
CFLAGS += -DCTR
|
||||
|
||||
#One-way hashes
|
||||
CFLAGS += -DSHA512
|
||||
CFLAGS += -DSHA384
|
||||
CFLAGS += -DSHA256
|
||||
CFLAGS += -DTIGER
|
||||
CFLAGS += -DSHA1
|
||||
CFLAGS += -DMD5
|
||||
CFLAGS += -DMD4
|
||||
CFLAGS += -DMD2
|
||||
|
||||
# base64
|
||||
CFLAGS += -DBASE64
|
||||
|
||||
# prngs
|
||||
CFLAGS += -DYARROW
|
||||
CFLAGS += -DSPRNG
|
||||
CFLAGS += -DRC4
|
||||
|
||||
# PK code
|
||||
CFLAGS += -DMRSA
|
||||
CFLAGS += -DMDH
|
||||
CFLAGS += -DMECC
|
||||
CFLAGS += -DKR
|
||||
|
||||
# include GF math routines? (not currently used by anything internally)
|
||||
#CFLAGS += -DGF
|
||||
|
||||
# include large integer math routines? (required by the PK code)
|
||||
CFLAGS += -DMPI
|
||||
|
||||
# Use a small prime table? It greatly reduces the size of prime.c at a little impact
|
||||
# in speed.
|
||||
#
|
||||
CFLAGS += -DSMALL_PRIME_TAB
|
||||
|
||||
# include HMAC support
|
||||
CFLAGS += -DHMAC
|
||||
|
||||
#Output filenames for various targets.
|
||||
LIBNAME=libtomcrypt.a
|
||||
TEST=test
|
||||
HASH=hashsum
|
||||
CRYPT=encrypt
|
||||
SMALL=small
|
||||
|
||||
#LIBPATH-The directory for libtomcrypt to be installed to.
|
||||
#INCPATH-The directory to install the header files for libtomcrypt.
|
||||
LIBPATH=/usr/lib
|
||||
INCPATH=/usr/include
|
||||
|
||||
#List of objects to compile.
|
||||
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 blowfish.o crypt.o \
|
||||
ampi.o mpi.o prime.o twofish.o packet.o hmac.o strings.o
|
||||
|
||||
TESTOBJECTS=demos/test.o
|
||||
HASHOBJECTS=demos/hashsum.o
|
||||
CRYPTOBJECTS=demos/encrypt.o
|
||||
SMALLOBJECTS=demos/small.o
|
||||
|
||||
#Files left over from making the crypt.pdf.
|
||||
LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind
|
||||
|
||||
#Compressed filenames
|
||||
COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz
|
||||
|
||||
#Header files used by libtomcrypt.
|
||||
HEADERS=mpi-types.h mpi-config.h mpi.h \
|
||||
mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \
|
||||
mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \
|
||||
mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h
|
||||
|
||||
#The default rule for make builds the libtomcrypt library.
|
||||
default:library mycrypt.h mycrypt_cfg.h
|
||||
|
||||
#These are the rules to make certain object files.
|
||||
rsa.o: rsa.c rsa_sys.c
|
||||
ecc.o: ecc.c ecc_sys.c
|
||||
dh.o: dh.c dh_sys.c
|
||||
aes.o: aes.c aes_tab.c
|
||||
sha512.o: sha512.c sha384.c
|
||||
|
||||
#This rule makes the libtomcrypt library.
|
||||
library: $(OBJECTS)
|
||||
$(AR) $(ARFLAGS) $(LIBNAME) $(OBJECTS)
|
||||
|
||||
#This rule makes the test program included with libtomcrypt
|
||||
test: library $(TESTOBJECTS)
|
||||
$(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST) $(WARN)
|
||||
|
||||
#This rule makes the hash program included with libtomcrypt
|
||||
hashsum: library $(HASHOBJECTS)
|
||||
$(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN)
|
||||
|
||||
#makes the crypt program
|
||||
crypt: library $(CRYPTOBJECTS)
|
||||
$(CC) $(CRYPTOBJECTS) $(LIBNAME) -o $(CRYPT) $(WARN)
|
||||
|
||||
#makes the small program
|
||||
small: library $(SMALLOBJECTS)
|
||||
$(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN)
|
||||
|
||||
#This rule installs the library and the header files. This must be run
|
||||
#as root in order to have a high enough permission to write to the correct
|
||||
#directories and to set the owner and group to root.
|
||||
install: library
|
||||
install -g root -o root $(LIBNAME) $(LIBPATH)
|
||||
install -g root -o root $(HEADERS) $(INCPATH)
|
||||
|
||||
#This rule cleans the source tree of all compiled code, not including the pdf
|
||||
#documentation.
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME)
|
||||
rm -f $(TEST) $(HASH) $(COMPRESSED)
|
||||
rm -f *stackdump *.lib *.exe *.obj demos/*.obj zlib/*.obj *.bat
|
||||
|
||||
#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
|
||||
#from the clean command! This is because most people would like to keep the
|
||||
#nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to
|
||||
#delete it if we are rebuilding it.
|
||||
docs: crypt.tex
|
||||
rm -f crypt.pdf
|
||||
rm -f $(LEFTOVERS)
|
||||
latex crypt > /dev/null
|
||||
makeindex crypt > /dev/null
|
||||
pdflatex crypt > /dev/null
|
||||
rm -f $(LEFTOVERS)
|
||||
|
||||
#zipup the project (take that!)
|
||||
zipup: clean docs
|
||||
chdir .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \
|
||||
cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; tar -c libtomcrypt-$(VERSION)/* > crypt-$(VERSION).tar ; \
|
||||
bzip2 -9vv crypt-$(VERSION).tar ; zip -9 -r crypt-$(VERSION).zip libtomcrypt-$(VERSION)/*
|
293
makefile.ps2
Normal file
293
makefile.ps2
Normal file
@ -0,0 +1,293 @@
|
||||
# MAKEFILE for linux GCC
|
||||
#
|
||||
# Tom St Denis
|
||||
# Modified by Clay Culver
|
||||
#
|
||||
# NOTE: This should later be replaced by autoconf/automake scripts, but for
|
||||
# the time being this is actually pretty clean. The only ugly part is
|
||||
# handling CFLAGS so that the x86 specific optimizations don't break
|
||||
# a build. This is easy to remedy though, for those that have problems.
|
||||
|
||||
#Compiler and Linker Names
|
||||
CC=ee-gcc
|
||||
LD=ee-ld
|
||||
|
||||
# PlayStation(tm) 2 specifics
|
||||
TOP = /usr/local/sce/ee
|
||||
LIBDIR = $(TOP)/lib
|
||||
INCDIR = $(TOP)/include/
|
||||
COMMONDIR = $(TOP)/../common/include/
|
||||
LCFILE = $(LIBDIR)/app.cmd
|
||||
LDFLAGS = -DSONY_PS2 -DSONY_PS2_EE -Wl,-Map,$(@).map -mno-crt0 -L$(LIBDIR) -lm
|
||||
AS = ee-gcc
|
||||
ASFLAGS = -DSONY_PS2 -DSONY_PS2_EE -c -xassembler-with-cpp -Wa,-al
|
||||
EXT = .elf
|
||||
CFLAGS += -DSONY_PS2 -DSONY_PS2_EE -Wa,-al -Wno-unused -Werror \
|
||||
-fno-common -fno-strict-aliasing -I$(INCDIR) -I$(COMMONDIR)
|
||||
|
||||
#Archiver [makes .a files]
|
||||
AR=ee-ar
|
||||
ARFLAGS=rs
|
||||
|
||||
#here you can set the malloc/calloc/free functions you want
|
||||
XMALLOC=malloc
|
||||
XCALLOC=calloc
|
||||
XFREE=free
|
||||
|
||||
#you can redefine the clock
|
||||
XCLOCK=TIMER_clock
|
||||
XCLOCKS_PER_SEC=576000
|
||||
|
||||
#Compilation flags. Note the += does not write over the user's CFLAGS!
|
||||
CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wno-unused -Werror \
|
||||
-DXMALLOC=$(XMALLOC) -DXCALLOC=$(XCALLOC) -DXFREE=$(XFREE) -DXCLOCK=$(XCLOCK) \
|
||||
-DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC)
|
||||
|
||||
#no file support, when defined the library will not have any functions that can read/write files
|
||||
#(comment out to have file support)
|
||||
CFLAGS += -DNO_FILE
|
||||
|
||||
#optimize for SPEED (comment out SIZE line as well)
|
||||
#CFLAGS += -O3 -fomit-frame-pointer -funroll-loops
|
||||
|
||||
#optimize for SIZE (comment out SPEED line as well)
|
||||
CFLAGS += -O2
|
||||
|
||||
#These flags control how the library gets built.
|
||||
|
||||
# Clean the stack after sensitive functions. Not always required...
|
||||
# With this defined most of the ciphers and hashes will clean their stack area
|
||||
# after usage with a (sometimes) huge penalty in speed. Normally this is not
|
||||
# required if you simply lock your stack and wipe it when your program is done.
|
||||
#
|
||||
#CFLAGS += -DCLEAN_STACK
|
||||
|
||||
# What algorithms to include? comment out and rebuild to remove em
|
||||
CFLAGS += -DBLOWFISH
|
||||
CFLAGS += -DRC2
|
||||
#CFLAGS += -DRC5
|
||||
#CFLAGS += -DRC6
|
||||
CFLAGS += -DSERPENT
|
||||
CFLAGS += -DSAFERP
|
||||
CFLAGS += -DSAFER
|
||||
CFLAGS += -DRIJNDAEL
|
||||
CFLAGS += -DXTEA
|
||||
CFLAGS += -DTWOFISH
|
||||
CFLAGS += -DDES
|
||||
CFLAGS += -DCAST5
|
||||
|
||||
#You can also customize the Twofish code. All four combinations
|
||||
#of the flags are possible but only three of them make sense.
|
||||
#
|
||||
#Both undefined: Very fast, requires ~4.2KB of ram per scheduled key
|
||||
#Both defined : Slow, requires only ~100 bytes of ram per scheduled key
|
||||
#
|
||||
#If defined on their own
|
||||
#_SMALL defined: Very Slow, small code only ~100 bytes of ram
|
||||
#_TABLES defined: Very fast, not faster than if both were undefined. Code is ~1KB bigger
|
||||
# faster keysetup though...
|
||||
|
||||
# Small Ram Variant of Twofish. For this you must have TWOFISH defined. This
|
||||
# variant requires about 4kb less memory but is considerably slower. It is ideal
|
||||
# when high throughput is less important than conserving memory. By default it is
|
||||
# not defined which means the larger ram (about 4.2Kb used) variant is built.
|
||||
# CFLAGS += -DTWOFISH_SMALL
|
||||
|
||||
# Tell Twofish to use precomputed tables. If you want to use the small table
|
||||
# variant of Twofish you may want to turn this on. Essentially it tells Twofish to use
|
||||
# precomputed S-boxes (Q0 and Q1) as well as precomputed GF multiplications [in the MDS].
|
||||
# This speeds up the cipher somewhat.
|
||||
# CFLAGS += -DTWOFISH_TABLES
|
||||
|
||||
#Small code variant of the SAFER+ cipher, uses same RAM but less code space
|
||||
#With this defined the cipher is slower. On my x86 with GCC 3.2 it required 50KB less space
|
||||
CFLAGS += -DSAFERP_SMALL
|
||||
|
||||
#Small Rijndael [saves 13KB on an x86]
|
||||
#With this defined the cipher is slower (by 50Mbit/sec on an Athon XP)
|
||||
CFLAGS += -DRIJNDAEL_SMALL
|
||||
|
||||
#Use fast PK routines. Basically this limits the size of the private key in the
|
||||
#DH system to 256 bits. The group order remains unchanged so the best
|
||||
#attacks are still GNFS (for DH upto 2560-bits)
|
||||
#
|
||||
#This will only speed up the key generation and encryption routines. It lowers the
|
||||
#security so its by default not turned on. USE AT YOUR RISK!
|
||||
#CFLAGS += -DFAST_PK
|
||||
|
||||
#Include the PK Packet functions (e.g. dh_encrypt)
|
||||
#Does not affect the key/hash routines (e.g. ecc_sign_hash)
|
||||
#CFLAGS += -DPK_PACKET
|
||||
|
||||
# Chaining modes
|
||||
CFLAGS += -DCFB
|
||||
CFLAGS += -DOFB
|
||||
CFLAGS += -DECB
|
||||
CFLAGS += -DCBC
|
||||
CFLAGS += -DCTR
|
||||
|
||||
#One-way hashes
|
||||
CFLAGS += -DSHA512
|
||||
CFLAGS += -DSHA384
|
||||
CFLAGS += -DSHA256
|
||||
CFLAGS += -DTIGER
|
||||
CFLAGS += -DSHA1
|
||||
CFLAGS += -DMD5
|
||||
CFLAGS += -DMD4
|
||||
CFLAGS += -DMD2
|
||||
|
||||
# base64
|
||||
CFLAGS += -DBASE64
|
||||
|
||||
# prngs
|
||||
CFLAGS += -DYARROW
|
||||
CFLAGS += -DSPRNG
|
||||
CFLAGS += -DRC4
|
||||
|
||||
# PK code
|
||||
CFLAGS += -DMRSA
|
||||
CFLAGS += -DMDH
|
||||
CFLAGS += -DMECC
|
||||
CFLAGS += -DKR
|
||||
|
||||
# include GF math routines? (not currently used by anything internally)
|
||||
#CFLAGS += -DGF
|
||||
|
||||
# include large integer math routines? (required by the PK code)
|
||||
CFLAGS += -DMPI
|
||||
|
||||
# Use a small prime table? It greatly reduces the size of prime.c at a little impact
|
||||
# in speed.
|
||||
#
|
||||
CFLAGS += -DSMALL_PRIME_TAB
|
||||
|
||||
# include HMAC support
|
||||
CFLAGS += -DHMAC
|
||||
|
||||
# Have /dev/random or /dev/urandom?
|
||||
#CFLAGS += -DDEVRANDOM
|
||||
|
||||
#Output filenames for various targets.
|
||||
LIBNAME=libtomcrypt.a
|
||||
TEST=test$(EXT)
|
||||
HASH=hashsum$(EXT)
|
||||
CRYPT=encrypt$(EXT)
|
||||
SMALL=small$(EXT)
|
||||
|
||||
#LIBPATH-The directory for libtomcrypt to be installed to.
|
||||
#INCPATH-The directory to install the header files for libtomcrypt.
|
||||
LIBPATH=/usr/lib
|
||||
INCPATH=/usr/include
|
||||
|
||||
#List of objects to compile.
|
||||
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 blowfish.o crypt.o \
|
||||
ampi.o mpi.o prime.o twofish.o packet.o hmac.o strings.o
|
||||
|
||||
# PlayStation(tm) 2 C run-time startup module
|
||||
PS2CRT0=crt0.o
|
||||
|
||||
TESTOBJECTS=$(PS2CRT0) demos/test.o demos/timer.o
|
||||
HASHOBJECTS=$(PS2CRT0) demos/hashsum.o
|
||||
CRYPTOBJECTS=$(PS2CRT0) demos/encrypt.o
|
||||
SMALLOBJECTS=$(PS2CRT0) demos/small.o
|
||||
|
||||
#Files left over from making the crypt.pdf.
|
||||
LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind
|
||||
|
||||
#Compressed filenames
|
||||
COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz
|
||||
|
||||
#Header files used by libtomcrypt.
|
||||
HEADERS=mpi-types.h mpi-config.h mpi.h \
|
||||
mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \
|
||||
mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \
|
||||
mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h
|
||||
|
||||
#The default rule for make builds the libtomcrypt library.
|
||||
default:library mycrypt.h mycrypt_cfg.h
|
||||
|
||||
#These are the rules to make certain object files.
|
||||
rsa.o: rsa.c rsa_sys.c
|
||||
ecc.o: ecc.c ecc_sys.c
|
||||
dh.o: dh.c dh_sys.c
|
||||
aes.o: aes.c aes_tab.c
|
||||
sha512.o: sha512.c sha384.c
|
||||
|
||||
#This rule makes the libtomcrypt library.
|
||||
library: $(OBJECTS)
|
||||
$(AR) $(ARFLAGS) $(LIBNAME) $(OBJECTS)
|
||||
|
||||
#This rule makes the test program included with libtomcrypt
|
||||
test: library $(TESTOBJECTS)
|
||||
$(CC) -o $(TEST) -T $(LCFILE) $(LDFLAGS) $(TESTOBJECTS) $(LIBNAME)
|
||||
|
||||
#This rule makes the hash program included with libtomcrypt
|
||||
hashsum: library $(HASHOBJECTS)
|
||||
$(CC) -o $(HASH) -T $(LCFILE) $(LDFLAGS) $(HASHOBJECTS) $(LIBNAME)
|
||||
|
||||
#makes the crypt program
|
||||
crypt: library $(CRYPTOBJECTS)
|
||||
$(CC) -o $(CRYPT) -T $(LCFILE) $(LDFLAGS) $(CRYPTOBJECTS) $(LIBNAME)
|
||||
|
||||
#makes the small program
|
||||
small: library $(SMALLOBJECTS)
|
||||
$(CC) -o $(SMALL) -T $(LCFILE) $(LDFLAGS) $(SMALLOBJECTS) $(LIBNAME)
|
||||
|
||||
# makes the PlayStation(tm) 2 CRT 0 module
|
||||
$(PS2CRT0): $(LIBDIR)/crt0.s
|
||||
$(AS) $(ASFLAGS) $(TMPFLAGS) -o $@ $< > $*.lst
|
||||
|
||||
#This rule installs the library and the header files. This must be run
|
||||
#as root in order to have a high enough permission to write to the correct
|
||||
#directories and to set the owner and group to root.
|
||||
install: library
|
||||
install -g root -o root $(LIBNAME) $(LIBPATH)
|
||||
install -g root -o root $(HEADERS) $(INCPATH)
|
||||
|
||||
#This rule cleans the source tree of all compiled code, not including the pdf
|
||||
#documentation.
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME)
|
||||
rm -f $(TEST) $(HASH) $(COMPRESSED)
|
||||
rm -f *stackdump *.lib *.exe *.obj demos/*.obj zlib/*.obj
|
||||
rm -f *.o *.lst demos/*.o demos/*.lst
|
||||
|
||||
#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed
|
||||
#from the clean command! This is because most people would like to keep the
|
||||
#nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to
|
||||
#delete it if we are rebuilding it.
|
||||
docs: crypt.tex
|
||||
rm -f crypt.pdf
|
||||
rm -f $(LEFTOVERS)
|
||||
latex crypt > /dev/null
|
||||
makeindex crypt > /dev/null
|
||||
pdflatex crypt > /dev/null
|
||||
rm -f $(LEFTOVERS)
|
||||
|
||||
#This used to be the zipup target. I have split it into two seperate targets:
|
||||
#bz and zip. bz builds a crypt.tar.bz2 package, while zip builds a crypt.zip
|
||||
#package. I have removed the dos2unix commands, as this is a Linux makefile,
|
||||
#and these should not be needed. I also made it output the target to the
|
||||
#current directory instead of the root (/) directory. (Bad Tom!) We are
|
||||
#almost assured write permission in the current directory, but not in the root
|
||||
#directory. This means any user can now build a BZ image or a zip.
|
||||
#NOTE: This removes all pre-built compressed archives during clean.
|
||||
bz: clean docs
|
||||
chdir .. ; rm -f crypt.tar.bz2 ; tar -c libtomcrypt/* > crypt.tar ; bzip2 -9v crypt.tar
|
||||
|
||||
zip: clean docs
|
||||
chdir .. ; rm -f crypt.zip ; zip -9 -r crypt.zip libtomcrypt/*
|
||||
|
||||
#Makes a tar/gz archive of the library.
|
||||
gz: clean docs
|
||||
chdir .. ; rm -f crypt.tar.gz ; tar -c libtomcrypt/* > crypt.tar ; gzip -9v crypt.tar
|
||||
|
||||
#makes a tar/SZIP archive [slightly better than bzip2]
|
||||
szip: clean docs
|
||||
chdir .. ; rm -f crypt.tar.szp ; tar -c libtomcrypt/* > crypt.tar ; szip -b41o64v255 crypt.tar crypt.tar.szp
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CFLAGS) $(TMPFLAGS) -c $< -o $*.o > $*.lst
|
254
makefile.vc
Normal file
254
makefile.vc
Normal file
@ -0,0 +1,254 @@
|
||||
# MAKEFILE for MSVC 6.0 SP5
|
||||
#
|
||||
# Tom St Denis, tomstdenis@yahoo.com
|
||||
#
|
||||
CC=cl
|
||||
AR=lib
|
||||
|
||||
#here you can set the malloc/calloc/free functions you want
|
||||
XMALLOC=malloc
|
||||
XCALLOC=calloc
|
||||
XFREE=free
|
||||
|
||||
#you can redefine the clock
|
||||
XCLOCK=clock
|
||||
XCLOCKS_PER_SEC=CLOCKS_PER_SEC
|
||||
|
||||
CFLAGS = /c /Ogisy1 /Gs /I. /W3 /DWIN32 /DXMALLOC=$(XMALLOC) /DXCALLOC=$(XCALLOC) /DXFREE=$(XFREE) /DXCLOCK=$(XCLOCK) /DXCLOCKS_PER_SEC=$(XCLOCKS_PER_SEC)
|
||||
|
||||
#These flags control how the library gets built.
|
||||
|
||||
#no file support, when defined the library will not have any functions that can read/write files
|
||||
#(comment out to have file support)
|
||||
#CFLAGS += /DNO_FILE
|
||||
|
||||
#Support the UNIX /dev/random or /dev/urandom
|
||||
#CFLAGS += /DDEVRANDOM
|
||||
|
||||
# Use /dev/urandom first on devices where /dev/random is too slow */
|
||||
#CFLAGS += /DTRY_URANDOM_FIRST
|
||||
|
||||
# Clean the stack after sensitive functions. Not always required...
|
||||
# With this defined most of the ciphers and hashes will clean their stack area
|
||||
# after usage with a (sometimes) huge penalty in speed. Normally this is not
|
||||
# required if you simply lock your stack and wipe it when your program is done.
|
||||
#
|
||||
#CFLAGS += /DCLEAN_STACK
|
||||
|
||||
# What algorithms to include? comment out and rebuild to remove em
|
||||
CFLAGS += /DBLOWFISH
|
||||
CFLAGS += /DRC2
|
||||
CFLAGS += /DRC5
|
||||
CFLAGS += /DRC6
|
||||
CFLAGS += /DSERPENT
|
||||
CFLAGS += /DSAFERP
|
||||
CFLAGS += /DSAFER
|
||||
CFLAGS += /DRIJNDAEL
|
||||
CFLAGS += /DXTEA
|
||||
CFLAGS += /DTWOFISH
|
||||
CFLAGS += /DDES
|
||||
CFLAGS += /DCAST5
|
||||
|
||||
#You can also customize the Twofish code. All four combinations
|
||||
#of the flags are possible but only three of them make sense.
|
||||
#
|
||||
#Both undefined: Very fast, requires ~4.2KB of ram per scheduled key
|
||||
#Both defined : Slow, requires only ~100 bytes of ram per scheduled key
|
||||
#
|
||||
#If defined on their own
|
||||
#_SMALL defined: Very Slow, small code only ~100 bytes of ram
|
||||
#_TABLES defined: Very fast, not faster than if both were undefined. Code is ~1KB bigger
|
||||
# faster keysetup though...
|
||||
|
||||
# Small Ram Variant of Twofish. For this you must have TWOFISH defined. This
|
||||
# variant requires about 4kb less memory but is considerably slower. It is ideal
|
||||
# when high throughput is less important than conserving memory. By default it is
|
||||
# not defined which means the larger ram (about 4.2Kb used) variant is built.
|
||||
# CFLAGS += /DTWOFISH_SMALL
|
||||
|
||||
# Tell Twofish to use precomputed tables. If you want to use the small table
|
||||
# variant of Twofish you may want to turn this on. Essentially it tells Twofish to use
|
||||
# precomputed S-boxes (Q0 and Q1) as well as precomputed GF multiplications [in the MDS].
|
||||
# This speeds up the cipher somewhat.
|
||||
# CFLAGS += /DTWOFISH_TABLES
|
||||
|
||||
#Small code variant of the SAFER+ cipher, uses same RAM but less code space
|
||||
#With this defined the cipher is slower. On my x86 with GCC 3.2 it required 50KB less space
|
||||
CFLAGS += /DSAFERP_SMALL
|
||||
|
||||
#Small Rijndael [saves 13KB on an x86]
|
||||
#With this defined the cipher is slower (by 50Mbit/sec on an Athon XP)
|
||||
CFLAGS += /DRIJNDAEL_SMALL
|
||||
|
||||
#Use fast PK routines. Basically this limits the size of the private key in the
|
||||
#DH system to 256 bits. The group order remains unchanged so the best
|
||||
#attacks are still GNFS (for DH upto 2560-bits)
|
||||
#
|
||||
#This will only speed up the key generation and encryption routines. It lowers the
|
||||
#security so its by default not turned on. USE AT YOUR RISK!
|
||||
#CFLAGS += /DFAST_PK
|
||||
|
||||
#Include the PK Packet functions (e.g. dh_encrypt)
|
||||
#Does not affect the key/hash routines (e.g. ecc_sign_hash)
|
||||
#CFLAGS += /DPK_PACKET
|
||||
|
||||
# Chaining modes
|
||||
CFLAGS += /DCFB
|
||||
CFLAGS += /DOFB
|
||||
CFLAGS += /DECB
|
||||
CFLAGS += /DCBC
|
||||
CFLAGS += /DCTR
|
||||
|
||||
#One-way hashes
|
||||
CFLAGS += /DSHA512
|
||||
CFLAGS += /DSHA384
|
||||
CFLAGS += /DSHA256
|
||||
CFLAGS += /DTIGER
|
||||
CFLAGS += /DSHA1
|
||||
CFLAGS += /DMD5
|
||||
CFLAGS += /DMD4
|
||||
CFLAGS += /DMD2
|
||||
|
||||
# base64
|
||||
CFLAGS += /DBASE64
|
||||
|
||||
# prngs
|
||||
CFLAGS += /DYARROW
|
||||
CFLAGS += /DSPRNG
|
||||
CFLAGS += /DRC4
|
||||
|
||||
# PK code
|
||||
CFLAGS += /DMRSA
|
||||
CFLAGS += /DMDH
|
||||
CFLAGS += /DMECC
|
||||
CFLAGS += /DKR
|
||||
|
||||
# include GF math routines? (not currently used by anything internally)
|
||||
#CFLAGS += /DGF
|
||||
|
||||
# include large integer math routines? (required by the PK code)
|
||||
CFLAGS += /DMPI
|
||||
|
||||
# Use a small prime table? It greatly reduces the size of prime.c at a little impact
|
||||
# in speed.
|
||||
#
|
||||
CFLAGS += /DSMALL_PRIME_TAB
|
||||
|
||||
# include HMAC support
|
||||
CFLAGS += /DHMAC
|
||||
|
||||
default: tomcrypt.lib
|
||||
|
||||
keyring.obj: keyring.c
|
||||
$(CC) $(CFLAGS) keyring.c
|
||||
ampi.obj: ampi.c
|
||||
$(CC) $(CFLAGS) ampi.c
|
||||
mpi.obj: mpi.c
|
||||
$(CC) $(CFLAGS) mpi.c
|
||||
blowfish.obj: blowfish.c
|
||||
$(CC) $(CFLAGS) blowfish.c
|
||||
crypt.obj: crypt.c
|
||||
$(CC) $(CFLAGS) crypt.c
|
||||
sha512.obj: sha512.c sha384.c
|
||||
$(CC) $(CFLAGS) sha512.c
|
||||
sha256.obj: sha256.c
|
||||
$(CC) $(CFLAGS) sha256.c
|
||||
hash.obj: hash.c
|
||||
$(CC) $(CFLAGS) hash.c
|
||||
md5.obj: md5.c
|
||||
$(CC) $(CFLAGS) md5.c
|
||||
md4.obj: md4.c
|
||||
$(CC) $(CFLAGS) md4.c
|
||||
sha1.obj: sha1.c
|
||||
$(CC) $(CFLAGS) sha1.c
|
||||
cfb.obj: cfb.c
|
||||
$(CC) $(CFLAGS) cfb.c
|
||||
ofb.obj: ofb.c
|
||||
$(CC) $(CFLAGS) ofb.c
|
||||
ecb.obj: ecb.c
|
||||
$(CC) $(CFLAGS) ecb.c
|
||||
ctr.obj: ctr.c
|
||||
$(CC) $(CFLAGS) ctr.c
|
||||
prime.obj: prime.c
|
||||
$(CC) $(CFLAGS) prime.c
|
||||
base64.obj: base64.c
|
||||
$(CC) $(CFLAGS) base64.c
|
||||
sprng.obj: sprng.c
|
||||
$(CC) $(CFLAGS) sprng.c
|
||||
mem.obj: mem.c
|
||||
$(CC) $(CFLAGS) mem.c
|
||||
gf.obj: gf.c
|
||||
$(CC) $(CFLAGS) gf.c
|
||||
ecc.obj: ecc.c ecc_sys.c
|
||||
$(CC) $(CFLAGS) ecc.c
|
||||
yarrow.obj: yarrow.c
|
||||
$(CC) $(CFLAGS) yarrow.c
|
||||
bits.obj: bits.c
|
||||
$(CC) $(CFLAGS) bits.c
|
||||
rsa.obj: rsa.c
|
||||
$(CC) $(CFLAGS) rsa.c
|
||||
rc6.obj: rc6.c
|
||||
$(CC) $(CFLAGS) rc6.c
|
||||
des.obj: des.c
|
||||
$(CC) $(CFLAGS) des.c
|
||||
tiger.obj: tiger.c
|
||||
$(CC) $(CFLAGS) tiger.c
|
||||
dh.obj: dh.c dh_sys.c
|
||||
$(CC) $(CFLAGS) dh.c
|
||||
serpent.obj: serpent.c
|
||||
$(CC) $(CFLAGS) serpent.c
|
||||
aes.obj: aes.c aes_tab.c
|
||||
$(CC) $(CFLAGS) aes.c
|
||||
rc5.obj: rc5.c
|
||||
$(CC) $(CFLAGS) rc5.c
|
||||
rc2.obj: rc2.c
|
||||
$(CC) $(CFLAGS) rc2.c
|
||||
cbc.obj: cbc.c
|
||||
$(CC) $(CFLAGS) cbc.c
|
||||
safer+.obj: safer+.c
|
||||
$(CC) $(CFLAGS) safer+.c
|
||||
safer.obj: safer.c
|
||||
$(CC) $(CFLAGS) safer.c
|
||||
safer_tab.obj: safer_tab.c
|
||||
$(CC) $(CFLAGS) safer_tab.c
|
||||
xtea.obj: xtea.c
|
||||
$(CC) $(CFLAGS) xtea.c
|
||||
twofish.obj: twofish.c
|
||||
$(CC) $(CFLAGS) twofish.c
|
||||
packet.obj: packet.c
|
||||
$(CC) $(CFLAGS) packet.c
|
||||
pack.obj: pack.c
|
||||
$(CC) $(CFLAGS) pack.c
|
||||
hmac.obj: hmac.c
|
||||
$(CC) $(CFLAGS) hmac.c
|
||||
strings.obj: strings.c
|
||||
$(CC) $(CFLAGS) strings.c
|
||||
md2.obj: md2.c
|
||||
$(CC) $(CFLAGS) md2.c
|
||||
cast5.obj: cast5.c
|
||||
$(CC) $(CFLAGS) cast5.c
|
||||
|
||||
demos/test.obj: demos/test.c
|
||||
$(CC) $(CFLAGS) demos/test.c
|
||||
|
||||
demos/hashsum.obj: demos/hashsum.c
|
||||
$(CC) $(CFLAGS) demos/hashsum.c
|
||||
|
||||
tomcrypt.lib: keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj bits.obj hmac.obj \
|
||||
yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj md2.obj md5.obj md4.obj sha256.obj sha512.obj xtea.obj \
|
||||
aes.obj serpent.obj safer_tab.obj safer.obj safer+.obj cast5.obj rc2.obj rc6.obj rc5.obj des.obj blowfish.obj crypt.obj ampi.obj \
|
||||
strings.obj mpi.obj prime.obj twofish.obj packet.obj
|
||||
$(AR) /out:tomcrypt.lib keyring.obj gf.obj mem.obj sprng.obj ecc.obj base64.obj dh.obj rsa.obj hmac.obj \
|
||||
bits.obj yarrow.obj cfb.obj ofb.obj ecb.obj ctr.obj cbc.obj hash.obj tiger.obj sha1.obj md2.obj md5.obj md4.obj sha256.obj \
|
||||
strings.obj sha512.obj xtea.obj aes.obj serpent.obj safer_tab.obj safer.obj safer+.obj cast5.obj rc2.obj rc6.obj rc5.obj des.obj \
|
||||
blowfish.obj crypt.obj ampi.obj mpi.obj prime.obj twofish.obj packet.obj
|
||||
|
||||
|
||||
test.exe: tomcrypt.lib demos/test.obj
|
||||
link /OUT:test.exe test.obj tomcrypt.lib advapi32.lib
|
||||
|
||||
hashsum.exe: tomcrypt.lib demos/hashsum.obj
|
||||
link /OUT:hashsum.exe hashsum.obj tomcrypt.lib advapi32.lib
|
||||
|
||||
clean:
|
||||
rm -f demos/*.obj *.obj *.exe *.lib
|
203
md2.c
Normal file
203
md2.c
Normal file
@ -0,0 +1,203 @@
|
||||
/* MD2 (RFC 1319) hash function implementation by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef MD2
|
||||
|
||||
const struct _hash_descriptor md2_desc =
|
||||
{
|
||||
"md2",
|
||||
7,
|
||||
16,
|
||||
16,
|
||||
&md2_init,
|
||||
&md2_process,
|
||||
&md2_done,
|
||||
&md2_test
|
||||
};
|
||||
|
||||
static const unsigned char PI_SUBST[256] = {
|
||||
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
|
||||
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
|
||||
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
|
||||
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
|
||||
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
|
||||
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
|
||||
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
|
||||
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
|
||||
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
|
||||
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
|
||||
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
||||
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
|
||||
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
|
||||
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
|
||||
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
|
||||
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
|
||||
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
|
||||
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
|
||||
};
|
||||
|
||||
/* adds 16 bytes to the checksum */
|
||||
static void md2_update_chksum(hash_state *md)
|
||||
{
|
||||
int j;
|
||||
unsigned char L;
|
||||
L = md->md2.chksum[15];
|
||||
for (j = 0; j < 16; j++) {
|
||||
|
||||
/* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say
|
||||
otherwise.
|
||||
*/
|
||||
L = (md->md2.chksum[j] ^= PI_SUBST[md->md2.buf[j] ^ L]);
|
||||
}
|
||||
}
|
||||
|
||||
static void md2_compress(hash_state *md)
|
||||
{
|
||||
int j, k;
|
||||
unsigned char t;
|
||||
|
||||
/* copy block */
|
||||
for (j = 0; j < 16; j++) {
|
||||
md->md2.X[16+j] = md->md2.buf[j];
|
||||
md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j];
|
||||
}
|
||||
|
||||
t = 0;
|
||||
|
||||
/* do 18 rounds */
|
||||
for (j = 0; j < 18; j++) {
|
||||
for (k = 0; k < 48; k++) {
|
||||
t = (md->md2.X[k] ^= PI_SUBST[t]);
|
||||
}
|
||||
t = (t + j) & 255;
|
||||
}
|
||||
}
|
||||
|
||||
void md2_init(hash_state *md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
/* MD2 uses a zero'ed state... */
|
||||
zeromem(md->md2.X, sizeof(md->md2.X));
|
||||
zeromem(md->md2.chksum, sizeof(md->md2.chksum));
|
||||
zeromem(md->md2.buf, sizeof(md->md2.buf));
|
||||
md->md2.curlen = 0;
|
||||
}
|
||||
|
||||
void md2_process(hash_state *md, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long n;
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
while (len) {
|
||||
n = MIN(len, (16 - md->md2.curlen));
|
||||
memcpy(md->md2.buf + md->md2.curlen, buf, n);
|
||||
md->md2.curlen += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
|
||||
/* is 16 bytes full? */
|
||||
if (md->md2.curlen == 16) {
|
||||
md2_compress(md);
|
||||
md2_update_chksum(md);
|
||||
md->md2.curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void md2_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
int i, k;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* pad the message */
|
||||
k = 16 - md->md2.curlen;
|
||||
for (i = md->md2.curlen; i < 16; i++) {
|
||||
md->md2.buf[i] = k;
|
||||
}
|
||||
|
||||
/* hash and update */
|
||||
md2_compress(md);
|
||||
md2_update_chksum(md);
|
||||
|
||||
/* hash checksum */
|
||||
memcpy(md->md2.buf, md->md2.chksum, 16);
|
||||
md2_compress(md);
|
||||
|
||||
/* output is lower 16 bytes of X */
|
||||
memcpy(hash, md->md2.X, 16);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
}
|
||||
|
||||
int md2_test(void)
|
||||
{
|
||||
static const struct {
|
||||
unsigned char *msg;
|
||||
unsigned char md[16];
|
||||
} tests[] = {
|
||||
{ "",
|
||||
{0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d,
|
||||
0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73
|
||||
}
|
||||
},
|
||||
{ "a",
|
||||
{0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72,
|
||||
0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1
|
||||
}
|
||||
},
|
||||
{ "message digest",
|
||||
{0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b,
|
||||
0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0
|
||||
}
|
||||
},
|
||||
{ "abcdefghijklmnopqrstuvwxyz",
|
||||
{0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,
|
||||
0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b
|
||||
}
|
||||
},
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
{0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,
|
||||
0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd
|
||||
}
|
||||
},
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
{0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d,
|
||||
0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8
|
||||
}
|
||||
}
|
||||
};
|
||||
int i;
|
||||
hash_state md;
|
||||
unsigned char buf[16];
|
||||
|
||||
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
|
||||
md2_init(&md);
|
||||
md2_process(&md, tests[i].msg, strlen(tests[i].msg));
|
||||
md2_done(&md, buf);
|
||||
if (memcmp(buf, tests[i].md, 16)) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("\n\nFailed test %d\n\n", i);
|
||||
for (j = 0; j < 16; j++) {
|
||||
printf("%02x ", buf[j]);
|
||||
}
|
||||
printf("\n");
|
||||
printf("Should have been\n");
|
||||
for (j = 0; j < 16; j++) {
|
||||
printf("%02x ", tests[i].md[j]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
290
md4.c
Normal file
290
md4.c
Normal file
@ -0,0 +1,290 @@
|
||||
/* Submitted by Dobes Vandermeer (dobes@smartt.com) */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef MD4
|
||||
|
||||
const struct _hash_descriptor md4_desc =
|
||||
{
|
||||
"md4",
|
||||
6,
|
||||
16,
|
||||
64,
|
||||
&md4_init,
|
||||
&md4_process,
|
||||
&md4_done,
|
||||
&md4_test
|
||||
};
|
||||
|
||||
#define S11 3
|
||||
#define S12 7
|
||||
#define S13 11
|
||||
#define S14 19
|
||||
#define S21 3
|
||||
#define S22 5
|
||||
#define S23 9
|
||||
#define S24 13
|
||||
#define S31 3
|
||||
#define S32 9
|
||||
#define S33 11
|
||||
#define S34 15
|
||||
|
||||
/* F, G and H are basic MD4 functions. */
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits. */
|
||||
#define ROTATE_LEFT(x, n) ROL(x, n)
|
||||
|
||||
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
|
||||
/* Rotation is separate from addition to prevent recomputation */
|
||||
|
||||
#define FF(a, b, c, d, x, s) { \
|
||||
(a) += F ((b), (c), (d)) + (x); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _md4_compress(hash_state *md)
|
||||
#else
|
||||
static void md4_compress(hash_state *md)
|
||||
#endif
|
||||
{
|
||||
unsigned long x[16], a, b, c, d;
|
||||
int i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
/* copy state */
|
||||
a = md->md4.state[0];
|
||||
b = md->md4.state[1];
|
||||
c = md->md4.state[2];
|
||||
d = md->md4.state[3];
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD32L(x[i], md->md4.buf + (4*i));
|
||||
}
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 0], S21); /* 17 */
|
||||
GG (d, a, b, c, x[ 4], S22); /* 18 */
|
||||
GG (c, d, a, b, x[ 8], S23); /* 19 */
|
||||
GG (b, c, d, a, x[12], S24); /* 20 */
|
||||
GG (a, b, c, d, x[ 1], S21); /* 21 */
|
||||
GG (d, a, b, c, x[ 5], S22); /* 22 */
|
||||
GG (c, d, a, b, x[ 9], S23); /* 23 */
|
||||
GG (b, c, d, a, x[13], S24); /* 24 */
|
||||
GG (a, b, c, d, x[ 2], S21); /* 25 */
|
||||
GG (d, a, b, c, x[ 6], S22); /* 26 */
|
||||
GG (c, d, a, b, x[10], S23); /* 27 */
|
||||
GG (b, c, d, a, x[14], S24); /* 28 */
|
||||
GG (a, b, c, d, x[ 3], S21); /* 29 */
|
||||
GG (d, a, b, c, x[ 7], S22); /* 30 */
|
||||
GG (c, d, a, b, x[11], S23); /* 31 */
|
||||
GG (b, c, d, a, x[15], S24); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 0], S31); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32); /* 34 */
|
||||
HH (c, d, a, b, x[ 4], S33); /* 35 */
|
||||
HH (b, c, d, a, x[12], S34); /* 36 */
|
||||
HH (a, b, c, d, x[ 2], S31); /* 37 */
|
||||
HH (d, a, b, c, x[10], S32); /* 38 */
|
||||
HH (c, d, a, b, x[ 6], S33); /* 39 */
|
||||
HH (b, c, d, a, x[14], S34); /* 40 */
|
||||
HH (a, b, c, d, x[ 1], S31); /* 41 */
|
||||
HH (d, a, b, c, x[ 9], S32); /* 42 */
|
||||
HH (c, d, a, b, x[ 5], S33); /* 43 */
|
||||
HH (b, c, d, a, x[13], S34); /* 44 */
|
||||
HH (a, b, c, d, x[ 3], S31); /* 45 */
|
||||
HH (d, a, b, c, x[11], S32); /* 46 */
|
||||
HH (c, d, a, b, x[ 7], S33); /* 47 */
|
||||
HH (b, c, d, a, x[15], S34); /* 48 */
|
||||
|
||||
|
||||
/* Update our state */
|
||||
md->md4.state[0] = md->md4.state[0] + a;
|
||||
md->md4.state[1] = md->md4.state[1] + b;
|
||||
md->md4.state[2] = md->md4.state[2] + c;
|
||||
md->md4.state[3] = md->md4.state[3] + d;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void md4_compress(hash_state *md)
|
||||
{
|
||||
_md4_compress(md);
|
||||
burn_stack(sizeof(unsigned long) * 20 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
void md4_init(hash_state * md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
md->md4.state[0] = 0x67452301UL;
|
||||
md->md4.state[1] = 0xefcdab89UL;
|
||||
md->md4.state[2] = 0x98badcfeUL;
|
||||
md->md4.state[3] = 0x10325476UL;
|
||||
md->md4.length = 0;
|
||||
md->md4.curlen = 0;
|
||||
}
|
||||
|
||||
void md4_process(hash_state * md, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long n;
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
while (len) {
|
||||
n = MIN(len, (64 - md->md4.curlen));
|
||||
memcpy(md->md4.buf + md->md4.curlen, buf, n);
|
||||
md->md4.curlen += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
|
||||
/* is 64 bytes full? */
|
||||
if (md->md4.curlen == 64) {
|
||||
md4_compress(md);
|
||||
md->md4.length += 512;
|
||||
md->md4.curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void md4_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
int i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* increase the length of the message */
|
||||
md->md4.length += md->md4.curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->md4.buf[md->md4.curlen++] = 0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->md4.curlen > 56) {
|
||||
while (md->md4.curlen < 64) {
|
||||
md->md4.buf[md->md4.curlen++] = 0;
|
||||
}
|
||||
md4_compress(md);
|
||||
md->md4.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (md->md4.curlen < 56) {
|
||||
md->md4.buf[md->md4.curlen++] = 0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64L(md->md4.length, md->md4.buf+56);
|
||||
md4_compress(md);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 4; i++) {
|
||||
STORE32L(md->md4.state[i], hash+(4*i));
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
}
|
||||
|
||||
int md4_test(void)
|
||||
{
|
||||
static const struct md4_test_case {
|
||||
int num;
|
||||
unsigned char input[128];
|
||||
int inputlen;
|
||||
unsigned char digest[16];
|
||||
} cases[] = {
|
||||
{ 1, "", 0,
|
||||
{0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
|
||||
0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} },
|
||||
{ 2, "a", 1,
|
||||
{0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
|
||||
0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} },
|
||||
{ 3, "abc", 3,
|
||||
{0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
|
||||
0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} },
|
||||
{ 4, "message digest", 14,
|
||||
{0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
|
||||
0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} },
|
||||
{ 5, "abcdefghijklmnopqrstuvwxyz", 26,
|
||||
{0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
|
||||
0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} },
|
||||
{ 6, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 62,
|
||||
{0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
|
||||
0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} },
|
||||
{ 7, "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 80,
|
||||
{0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
|
||||
0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} },
|
||||
};
|
||||
int i, failed;
|
||||
hash_state md;
|
||||
unsigned char digest[16];
|
||||
|
||||
failed = 0;
|
||||
for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
|
||||
md4_init(&md);
|
||||
md4_process(&md, cases[i].input, cases[i].inputlen);
|
||||
md4_done(&md, digest);
|
||||
if(memcmp(digest, cases[i].digest, 16) != 0) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("\nMD4 test #%d failed\n", cases[i].num);
|
||||
printf( "Result: 0x");
|
||||
for(j=0; j < 16; j++) {
|
||||
printf("%2x", digest[j]);
|
||||
}
|
||||
printf("\nCorrect: 0x");
|
||||
for(j=0; j < 16; j++) {
|
||||
printf("%2x", cases[i].digest[j]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed++;
|
||||
} else {
|
||||
/* printf("MD4 test #%d succeeded.\n", cases[i].num); */
|
||||
}
|
||||
}
|
||||
|
||||
if (failed) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
268
md5.c
Normal file
268
md5.c
Normal file
@ -0,0 +1,268 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef MD5
|
||||
|
||||
const struct _hash_descriptor md5_desc =
|
||||
{
|
||||
"md5",
|
||||
3,
|
||||
16,
|
||||
64,
|
||||
&md5_init,
|
||||
&md5_process,
|
||||
&md5_done,
|
||||
&md5_test
|
||||
};
|
||||
|
||||
#define F(x,y,z) ( (x&y)|((~x)&z) )
|
||||
#define G(x,y,z) ( (x&z)|(y&(~z)) )
|
||||
#define H(x,y,z) (x^y^z)
|
||||
#define I(x,y,z) (y ^ (x | (~z)))
|
||||
|
||||
#define FF(a,b,c,d,M,s,t) \
|
||||
a = (a + F(b,c,d) + M + t); a = ROL(a, s); a = (b + a);
|
||||
|
||||
#define GG(a,b,c,d,M,s,t) \
|
||||
a = (a + G(b,c,d) + M + t); a = ROL(a, s); a = (b + a);
|
||||
|
||||
#define HH(a,b,c,d,M,s,t) \
|
||||
a = (a + H(b,c,d) + M + t); a = ROL(a, s); a = (b + a);
|
||||
|
||||
#define II(a,b,c,d,M,s,t) \
|
||||
a = (a + I(b,c,d) + M + t); a = ROL(a, s); a = (b + a);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _md5_compress(hash_state *md)
|
||||
#else
|
||||
static void md5_compress(hash_state *md)
|
||||
#endif
|
||||
{
|
||||
unsigned long i, W[16], a, b, c, d;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD32L(W[i], md->md5.buf + (4*i));
|
||||
}
|
||||
|
||||
/* copy state */
|
||||
a = md->md5.state[0];
|
||||
b = md->md5.state[1];
|
||||
c = md->md5.state[2];
|
||||
d = md->md5.state[3];
|
||||
|
||||
FF(a,b,c,d,W[0],7,0xd76aa478UL)
|
||||
FF(d,a,b,c,W[1],12,0xe8c7b756UL)
|
||||
FF(c,d,a,b,W[2],17,0x242070dbUL)
|
||||
FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
|
||||
FF(a,b,c,d,W[4],7,0xf57c0fafUL)
|
||||
FF(d,a,b,c,W[5],12,0x4787c62aUL)
|
||||
FF(c,d,a,b,W[6],17,0xa8304613UL)
|
||||
FF(b,c,d,a,W[7],22,0xfd469501UL)
|
||||
FF(a,b,c,d,W[8],7,0x698098d8UL)
|
||||
FF(d,a,b,c,W[9],12,0x8b44f7afUL)
|
||||
FF(c,d,a,b,W[10],17,0xffff5bb1UL)
|
||||
FF(b,c,d,a,W[11],22,0x895cd7beUL)
|
||||
FF(a,b,c,d,W[12],7,0x6b901122UL)
|
||||
FF(d,a,b,c,W[13],12,0xfd987193UL)
|
||||
FF(c,d,a,b,W[14],17,0xa679438eUL)
|
||||
FF(b,c,d,a,W[15],22,0x49b40821UL)
|
||||
GG(a,b,c,d,W[1],5,0xf61e2562UL)
|
||||
GG(d,a,b,c,W[6],9,0xc040b340UL)
|
||||
GG(c,d,a,b,W[11],14,0x265e5a51UL)
|
||||
GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
|
||||
GG(a,b,c,d,W[5],5,0xd62f105dUL)
|
||||
GG(d,a,b,c,W[10],9,0x02441453UL)
|
||||
GG(c,d,a,b,W[15],14,0xd8a1e681UL)
|
||||
GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
|
||||
GG(a,b,c,d,W[9],5,0x21e1cde6UL)
|
||||
GG(d,a,b,c,W[14],9,0xc33707d6UL)
|
||||
GG(c,d,a,b,W[3],14,0xf4d50d87UL)
|
||||
GG(b,c,d,a,W[8],20,0x455a14edUL)
|
||||
GG(a,b,c,d,W[13],5,0xa9e3e905UL)
|
||||
GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
|
||||
GG(c,d,a,b,W[7],14,0x676f02d9UL)
|
||||
GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
|
||||
HH(a,b,c,d,W[5],4,0xfffa3942UL)
|
||||
HH(d,a,b,c,W[8],11,0x8771f681UL)
|
||||
HH(c,d,a,b,W[11],16,0x6d9d6122UL)
|
||||
HH(b,c,d,a,W[14],23,0xfde5380cUL)
|
||||
HH(a,b,c,d,W[1],4,0xa4beea44UL)
|
||||
HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
|
||||
HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
|
||||
HH(b,c,d,a,W[10],23,0xbebfbc70UL)
|
||||
HH(a,b,c,d,W[13],4,0x289b7ec6UL)
|
||||
HH(d,a,b,c,W[0],11,0xeaa127faUL)
|
||||
HH(c,d,a,b,W[3],16,0xd4ef3085UL)
|
||||
HH(b,c,d,a,W[6],23,0x04881d05UL)
|
||||
HH(a,b,c,d,W[9],4,0xd9d4d039UL)
|
||||
HH(d,a,b,c,W[12],11,0xe6db99e5UL)
|
||||
HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
|
||||
HH(b,c,d,a,W[2],23,0xc4ac5665UL)
|
||||
II(a,b,c,d,W[0],6,0xf4292244UL)
|
||||
II(d,a,b,c,W[7],10,0x432aff97UL)
|
||||
II(c,d,a,b,W[14],15,0xab9423a7UL)
|
||||
II(b,c,d,a,W[5],21,0xfc93a039UL)
|
||||
II(a,b,c,d,W[12],6,0x655b59c3UL)
|
||||
II(d,a,b,c,W[3],10,0x8f0ccc92UL)
|
||||
II(c,d,a,b,W[10],15,0xffeff47dUL)
|
||||
II(b,c,d,a,W[1],21,0x85845dd1UL)
|
||||
II(a,b,c,d,W[8],6,0x6fa87e4fUL)
|
||||
II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
|
||||
II(c,d,a,b,W[6],15,0xa3014314UL)
|
||||
II(b,c,d,a,W[13],21,0x4e0811a1UL)
|
||||
II(a,b,c,d,W[4],6,0xf7537e82UL)
|
||||
II(d,a,b,c,W[11],10,0xbd3af235UL)
|
||||
II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
|
||||
II(b,c,d,a,W[9],21,0xeb86d391UL)
|
||||
|
||||
md->md5.state[0] = md->md5.state[0] + a;
|
||||
md->md5.state[1] = md->md5.state[1] + b;
|
||||
md->md5.state[2] = md->md5.state[2] + c;
|
||||
md->md5.state[3] = md->md5.state[3] + d;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void md5_compress(hash_state *md)
|
||||
{
|
||||
_md5_compress(md);
|
||||
burn_stack(sizeof(unsigned long) * 21);
|
||||
}
|
||||
#endif
|
||||
|
||||
void md5_init(hash_state * md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
md->md5.state[0] = 0x67452301UL;
|
||||
md->md5.state[1] = 0xefcdab89UL;
|
||||
md->md5.state[2] = 0x98badcfeUL;
|
||||
md->md5.state[3] = 0x10325476UL;
|
||||
md->md5.curlen = 0;
|
||||
md->md5.length = 0;
|
||||
}
|
||||
|
||||
void md5_process(hash_state * md, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long n;
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
while (len) {
|
||||
n = MIN(len, (64 - md->md5.curlen));
|
||||
memcpy(md->md5.buf + md->md5.curlen, buf, n);
|
||||
md->md5.curlen += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
|
||||
/* is 64 bytes full? */
|
||||
if (md->md5.curlen == 64) {
|
||||
md5_compress(md);
|
||||
md->md5.length += 512;
|
||||
md->md5.curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void md5_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
int i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* increase the length of the message */
|
||||
md->md5.length += md->md5.curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->md5.buf[md->md5.curlen++] = 0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->md5.curlen > 56) {
|
||||
while (md->md5.curlen < 64) {
|
||||
md->md5.buf[md->md5.curlen++] = 0;
|
||||
}
|
||||
md5_compress(md);
|
||||
md->md5.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (md->md5.curlen < 56) {
|
||||
md->md5.buf[md->md5.curlen++] = 0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64L(md->md5.length, md->md5.buf+56);
|
||||
md5_compress(md);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 4; i++) {
|
||||
STORE32L(md->md5.state[i], hash+(4*i));
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
}
|
||||
|
||||
int md5_test(void)
|
||||
{
|
||||
static const struct {
|
||||
unsigned char *msg;
|
||||
unsigned char hash[16];
|
||||
} tests[] = {
|
||||
{ "",
|
||||
{ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
|
||||
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
|
||||
{ "a",
|
||||
{0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
|
||||
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
|
||||
{ "abc",
|
||||
{ 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
|
||||
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
|
||||
{ "message digest",
|
||||
{ 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
|
||||
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
|
||||
{ "abcdefghijklmnopqrstuvwxyz",
|
||||
{ 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
|
||||
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
{ 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
|
||||
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
{ 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
|
||||
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
|
||||
{ NULL, { 0 } }
|
||||
};
|
||||
|
||||
int failed, i;
|
||||
unsigned char tmp[16];
|
||||
hash_state md;
|
||||
|
||||
for (failed = i = 0; tests[i].msg != NULL; i++) {
|
||||
md5_init(&md);
|
||||
md5_process(&md, tests[i].msg, strlen(tests[i].msg));
|
||||
md5_done(&md, tmp);
|
||||
if (memcmp(tmp, tests[i].hash, 16)) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("MD5 Test %d (len == %d) failed\nGot (as a result): ", i, strlen(tests[i].msg));
|
||||
for (j = 0; j < 16; j++) {
|
||||
printf("%02x ", tmp[j]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
19
mem.c
Normal file
19
mem.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
void zeromem(void *dst, unsigned long len)
|
||||
{
|
||||
unsigned char *mem = (unsigned char *)dst;
|
||||
_ARGCHK(dst != NULL);
|
||||
while (len--)
|
||||
*mem++ = 0;
|
||||
}
|
||||
|
||||
void burn_stack(unsigned long len)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
zeromem(buf, sizeof(buf));
|
||||
if (len > sizeof(buf))
|
||||
burn_stack(len - sizeof(buf));
|
||||
}
|
||||
|
||||
|
87
mpi-config.h
Normal file
87
mpi-config.h
Normal file
@ -0,0 +1,87 @@
|
||||
/* Default configuration for MPI library */
|
||||
/* $ID$ */
|
||||
|
||||
#ifndef MPI_CONFIG_H_
|
||||
#define MPI_CONFIG_H_
|
||||
|
||||
/*
|
||||
For boolean options,
|
||||
0 = no
|
||||
1 = yes
|
||||
|
||||
Other options are documented individually.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef MP_IOFUNC
|
||||
#define MP_IOFUNC 1 /* include mp_print() ? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_MODARITH
|
||||
#define MP_MODARITH 1 /* include modular arithmetic ? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_NUMTH
|
||||
#define MP_NUMTH 1 /* include number theoretic functions? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_LOGTAB
|
||||
#define MP_LOGTAB 1 /* use table of logs instead of log()? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_MEMSET
|
||||
#define MP_MEMSET 1 /* use memset() to zero buffers? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_MEMCPY
|
||||
#define MP_MEMCPY 1 /* use memcpy() to copy buffers? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_CRYPTO
|
||||
#define MP_CRYPTO 1 /* erase memory on free? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_ARGCHK
|
||||
/*
|
||||
0 = no parameter checks
|
||||
1 = runtime checks, continue execution and return an error to caller
|
||||
2 = assertions; dump core on parameter errors
|
||||
*/
|
||||
#define MP_ARGCHK 1 /* how to check input arguments */
|
||||
#endif
|
||||
|
||||
#ifndef MP_DEBUG
|
||||
#define MP_DEBUG 0 /* print diagnostic output? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_DEFPREC
|
||||
#define MP_DEFPREC 8 /* default precision, in digits */
|
||||
#endif
|
||||
|
||||
#ifndef MP_MACRO
|
||||
#define MP_MACRO 1 /* use macros for frequent calls? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_SQUARE
|
||||
#define MP_SQUARE 1 /* use separate squaring code? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_PTAB_SIZE
|
||||
/*
|
||||
When building mpprime.c, we build in a table of small prime
|
||||
values to use for primality testing. The more you include,
|
||||
the more space they take up. See primes.c for the possible
|
||||
values (currently 16, 32, 64, 128, 256, and 6542)
|
||||
*/
|
||||
#define MP_PTAB_SIZE 128 /* how many built-in primes? */
|
||||
#endif
|
||||
|
||||
#ifndef MP_COMPAT_MACROS
|
||||
#define MP_COMPAT_MACROS 1 /* define compatibility macros? */
|
||||
#endif
|
||||
|
||||
#endif /* ifndef MPI_CONFIG_H_ */
|
||||
|
||||
|
||||
|
||||
|
16
mpi-types.h
Normal file
16
mpi-types.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* Type definitions generated by 'types.pl' */
|
||||
typedef char mp_sign;
|
||||
typedef unsigned short mp_digit; /* 2 byte type */
|
||||
typedef unsigned int mp_word; /* 4 byte type */
|
||||
typedef unsigned int mp_size;
|
||||
typedef int mp_err;
|
||||
|
||||
#define MP_DIGIT_BIT (CHAR_BIT*sizeof(mp_digit))
|
||||
#define MP_DIGIT_MAX USHRT_MAX
|
||||
#define MP_WORD_BIT (CHAR_BIT*sizeof(mp_word))
|
||||
#define MP_WORD_MAX UINT_MAX
|
||||
|
||||
#define MP_DIGIT_SIZE 2
|
||||
#define DIGIT_FMT "%04X"
|
||||
#define RADIX (MP_DIGIT_MAX+1)
|
||||
|
225
mpi.h
Normal file
225
mpi.h
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
mpi.h
|
||||
|
||||
by Michael J. Fromberger <sting@linguist.dartmouth.edu>
|
||||
Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
|
||||
|
||||
Arbitrary precision integer arithmetic library
|
||||
|
||||
$ID$
|
||||
*/
|
||||
|
||||
#ifndef _H_MPI_
|
||||
#define _H_MPI_
|
||||
|
||||
#include "mpi-config.h"
|
||||
|
||||
#define MP_LT -1
|
||||
#define MP_EQ 0
|
||||
#define MP_GT 1
|
||||
|
||||
#if MP_DEBUG
|
||||
#undef MP_IOFUNC
|
||||
#define MP_IOFUNC 1
|
||||
#endif
|
||||
|
||||
#if MP_IOFUNC
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#define MP_NEG 1
|
||||
#define MP_ZPOS 0
|
||||
|
||||
/* Included for compatibility... */
|
||||
#define NEG MP_NEG
|
||||
#define ZPOS MP_ZPOS
|
||||
|
||||
#define MP_OKAY 0 /* no error, all is well */
|
||||
#define MP_YES 0 /* yes (boolean result) */
|
||||
#define MP_NO -1 /* no (boolean result) */
|
||||
#define MP_MEM -2 /* out of memory */
|
||||
#define MP_RANGE -3 /* argument out of range */
|
||||
#define MP_BADARG -4 /* invalid parameter */
|
||||
#define MP_UNDEF -5 /* answer is undefined */
|
||||
#define MP_LAST_CODE MP_UNDEF
|
||||
|
||||
#include "mpi-types.h"
|
||||
|
||||
/* Included for compatibility... */
|
||||
#define DIGIT_BIT MP_DIGIT_BIT
|
||||
#define DIGIT_MAX MP_DIGIT_MAX
|
||||
|
||||
/* Macros for accessing the mp_int internals */
|
||||
#define SIGN(MP) ((MP)->sign)
|
||||
#define USED(MP) ((MP)->used)
|
||||
#define ALLOC(MP) ((MP)->alloc)
|
||||
#define DIGITS(MP) ((MP)->dp)
|
||||
#define DIGIT(MP,N) (MP)->dp[(N)]
|
||||
|
||||
#if MP_ARGCHK == 1
|
||||
#define ARGCHK(X,Y) {if(!(X)){return (Y);}}
|
||||
#elif MP_ARGCHK == 2
|
||||
#include <assert.h>
|
||||
#define ARGCHK(X,Y) assert(X)
|
||||
#else
|
||||
#define ARGCHK(X,Y) /* */
|
||||
#endif
|
||||
|
||||
/* This defines the maximum I/O base (minimum is 2) */
|
||||
#define MAX_RADIX 64
|
||||
|
||||
typedef struct {
|
||||
mp_sign sign; /* sign of this quantity */
|
||||
mp_size alloc; /* how many digits allocated */
|
||||
mp_size used; /* how many digits used */
|
||||
mp_digit *dp; /* the digits themselves */
|
||||
} mp_int;
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Default precision */
|
||||
|
||||
unsigned int mp_get_prec(void);
|
||||
void mp_set_prec(unsigned int prec);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Memory management */
|
||||
|
||||
mp_err mp_init(mp_int *mp);
|
||||
mp_err mp_init_array(mp_int mp[], int count);
|
||||
mp_err mp_init_size(mp_int *mp, mp_size prec);
|
||||
mp_err mp_init_copy(mp_int *mp, mp_int *from);
|
||||
mp_err mp_copy(mp_int *from, mp_int *to);
|
||||
void mp_exch(mp_int *mp1, mp_int *mp2);
|
||||
void mp_clear(mp_int *mp);
|
||||
void mp_clear_array(mp_int mp[], int count);
|
||||
void mp_zero(mp_int *mp);
|
||||
void mp_set(mp_int *mp, mp_digit d);
|
||||
mp_err mp_set_int(mp_int *mp, long z);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Single digit arithmetic */
|
||||
|
||||
mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b);
|
||||
mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b);
|
||||
mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b);
|
||||
mp_err mp_mul_2(mp_int *a, mp_int *c);
|
||||
mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r);
|
||||
mp_err mp_div_2(mp_int *a, mp_int *c);
|
||||
mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Sign manipulations */
|
||||
|
||||
mp_err mp_abs(mp_int *a, mp_int *b);
|
||||
mp_err mp_neg(mp_int *a, mp_int *b);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Full arithmetic */
|
||||
|
||||
mp_err mp_add(mp_int *a, mp_int *b, mp_int *c);
|
||||
mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c);
|
||||
mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c);
|
||||
mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c);
|
||||
#if MP_SQUARE
|
||||
mp_err mp_sqr(mp_int *a, mp_int *b);
|
||||
#else
|
||||
#define mp_sqr(a, b) mp_mul(a, a, b)
|
||||
#endif
|
||||
mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r);
|
||||
mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r);
|
||||
mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c);
|
||||
mp_err mp_2expt(mp_int *a, mp_digit k);
|
||||
mp_err mp_sqrt(mp_int *a, mp_int *b);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Modular arithmetic */
|
||||
|
||||
#if MP_MODARITH
|
||||
mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c);
|
||||
mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c);
|
||||
mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
|
||||
mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
|
||||
mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
|
||||
#if MP_SQUARE
|
||||
mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c);
|
||||
#else
|
||||
#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c)
|
||||
#endif
|
||||
mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
|
||||
mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c);
|
||||
#endif /* MP_MODARITH */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Comparisons */
|
||||
|
||||
int mp_cmp_z(mp_int *a);
|
||||
int mp_cmp_d(mp_int *a, mp_digit d);
|
||||
int mp_cmp(mp_int *a, mp_int *b);
|
||||
int mp_cmp_mag(mp_int *a, mp_int *b);
|
||||
int mp_cmp_int(mp_int *a, long z);
|
||||
int mp_isodd(mp_int *a);
|
||||
int mp_iseven(mp_int *a);
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Number theoretic */
|
||||
|
||||
#if MP_NUMTH
|
||||
mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
|
||||
mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c);
|
||||
mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y);
|
||||
mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c);
|
||||
#endif /* end MP_NUMTH */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Input and output */
|
||||
|
||||
#if MP_IOFUNC
|
||||
void mp_print(mp_int *mp, FILE *ofp);
|
||||
#endif /* end MP_IOFUNC */
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Base conversion */
|
||||
|
||||
#define BITS 1
|
||||
#define BYTES CHAR_BIT
|
||||
|
||||
mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len);
|
||||
int mp_signed_bin_size(mp_int *mp);
|
||||
mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str);
|
||||
|
||||
mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len);
|
||||
int mp_unsigned_bin_size(mp_int *mp);
|
||||
mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str);
|
||||
|
||||
int mp_count_bits(mp_int *mp);
|
||||
|
||||
#if MP_COMPAT_MACROS
|
||||
#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
|
||||
#define mp_raw_size(mp) mp_signed_bin_size(mp)
|
||||
#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
|
||||
#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
|
||||
#define mp_mag_size(mp) mp_unsigned_bin_size(mp)
|
||||
#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
|
||||
#endif
|
||||
|
||||
mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix);
|
||||
int mp_radix_size(mp_int *mp, int radix);
|
||||
int mp_value_radix_size(int num, int qty, int radix);
|
||||
mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix);
|
||||
|
||||
int mp_char2value(char ch, int r);
|
||||
|
||||
#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
|
||||
#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
|
||||
#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
|
||||
#define mp_tohex(M, S) mp_toradix((M), (S), 16)
|
||||
|
||||
/*------------------------------------------------------------------------*/
|
||||
/* Error strings */
|
||||
|
||||
const char *mp_strerror(mp_err ec);
|
||||
|
||||
#endif /* end _H_MPI_ */
|
75
mycrypt.h
Normal file
75
mycrypt.h
Normal file
@ -0,0 +1,75 @@
|
||||
#ifndef CRYPT_H_
|
||||
#define CRYPT_H_
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* version */
|
||||
#define CRYPT 0x0075
|
||||
#define SCRYPT "0.75"
|
||||
|
||||
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
|
||||
#define MAXBLOCKSIZE 128
|
||||
|
||||
/* error codes [will be expanded in future releases] */
|
||||
enum {
|
||||
CRYPT_OK=0,
|
||||
CRYPT_ERROR,
|
||||
|
||||
CRYPT_INVALID_KEYSIZE,
|
||||
CRYPT_INVALID_ROUNDS,
|
||||
CRYPT_FAIL_TESTVECTOR,
|
||||
|
||||
CRYPT_BUFFER_OVERFLOW,
|
||||
CRYPT_INVALID_PACKET,
|
||||
|
||||
CRYPT_INVALID_PRNGSIZE,
|
||||
CRYPT_ERROR_READPRNG,
|
||||
|
||||
CRYPT_INVALID_CIPHER,
|
||||
CRYPT_INVALID_HASH,
|
||||
CRYPT_INVALID_PRNG,
|
||||
|
||||
CRYPT_MEM,
|
||||
|
||||
CRYPT_PK_TYPE_MISMATCH,
|
||||
CRYPT_PK_NOT_PRIVATE,
|
||||
|
||||
CRYPT_INVALID_ARG,
|
||||
|
||||
CRYPT_PK_INVALID_TYPE,
|
||||
CRYPT_PK_INVALID_SYSTEM,
|
||||
CRYPT_PK_DUP,
|
||||
CRYPT_PK_NOT_FOUND,
|
||||
CRYPT_PK_INVALID_SIZE,
|
||||
|
||||
CRYPT_INVALID_PRIME_SIZE
|
||||
};
|
||||
|
||||
#include <mycrypt_cfg.h>
|
||||
#include <mycrypt_macros.h>
|
||||
#include <mycrypt_cipher.h>
|
||||
#include <mycrypt_hash.h>
|
||||
#include <mycrypt_prng.h>
|
||||
#include <mycrypt_pk.h>
|
||||
#include <mycrypt_gf.h>
|
||||
#include <mycrypt_misc.h>
|
||||
#include <mycrypt_kr.h>
|
||||
|
||||
#include <mycrypt_argchk.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CRYPT_H_ */
|
||||
|
41
mycrypt_argchk.h
Normal file
41
mycrypt_argchk.h
Normal file
@ -0,0 +1,41 @@
|
||||
/* Defines the _ARGCHK macro used within the library */
|
||||
|
||||
/* ARGTYPE is defined in mycrypt_cfg.h */
|
||||
#if ARGTYPE == 0
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
/* this is the default LibTomCrypt macro
|
||||
*
|
||||
* On embedded platforms you can change the fprintf() to be a routine that would display a message
|
||||
* somehow
|
||||
*/
|
||||
#ifndef SONY_PS2
|
||||
|
||||
#define _ARGCHK(x) \
|
||||
if (!(x)) { \
|
||||
fprintf(stderr, "_ARGCHK '%s' failure on line %d of file %s\n", #x, __LINE__, __FILE__); \
|
||||
raise(SIGABRT); \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define _ARGCHK(x) \
|
||||
if (!(x)) { \
|
||||
printf("_ARGCHK '%s' failure on line %d of file %s\n", #x, __LINE__, __FILE__); \
|
||||
raise(SIGABRT); \
|
||||
}
|
||||
|
||||
#endif /* SONY_PS2 */
|
||||
|
||||
#elif ARGTYPE == 1
|
||||
|
||||
/* fatal type of error */
|
||||
#define _ARGCHK(x) assert((x))
|
||||
|
||||
#elif ARGTYPE == 2
|
||||
|
||||
#define _ARGCHK(x)
|
||||
|
||||
#endif
|
||||
|
122
mycrypt_cfg.h
Normal file
122
mycrypt_cfg.h
Normal file
@ -0,0 +1,122 @@
|
||||
/* This is the build config file.
|
||||
*
|
||||
* With this you can setup what to inlcude/exclude automatically during any build. Just comment
|
||||
* out the line that #define's the word for the thing you want to remove. phew!
|
||||
*/
|
||||
|
||||
#ifndef MYCRYPT_CFG_H
|
||||
#define MYCRYPT_CFG_H
|
||||
|
||||
/* you can change how memory allocation works ... */
|
||||
extern void *XMALLOC(size_t n);
|
||||
extern void *XCALLOC(size_t n, size_t s);
|
||||
extern void XFREE(void *p);
|
||||
|
||||
/* change the clock function too */
|
||||
extern clock_t XCLOCK(void);
|
||||
|
||||
/* type of argument checking, 0=default, 1=fatal and 2=none */
|
||||
#define ARGTYPE 0
|
||||
|
||||
/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code */
|
||||
/* detect x86-32 machines somewhat */
|
||||
#if (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__)))
|
||||
#define ENDIAN_LITTLE
|
||||
#define ENDIAN_32BITWORD
|
||||
#endif
|
||||
|
||||
/* detects MIPS R5900 processors (PS2) */
|
||||
#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips))
|
||||
#define ENDIAN_LITTLE
|
||||
#define ENDIAN_64BITWORD
|
||||
#endif
|
||||
|
||||
/* #define ENDIAN_LITTLE */
|
||||
/* #define ENDIAN_BIG */
|
||||
|
||||
/* #define ENDIAN_32BITWORD */
|
||||
/* #define ENDIAN_64BITWORD */
|
||||
|
||||
#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))
|
||||
#error You must specify a word size as well as endianess in mycrypt_cfg.h
|
||||
#endif
|
||||
|
||||
#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))
|
||||
#define ENDIAN_NEUTRAL
|
||||
#endif
|
||||
|
||||
#ifdef SHA384
|
||||
#ifndef SHA512
|
||||
#error The SHA384 hash requires SHA512 to be defined!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef YARROW
|
||||
#ifndef CTR
|
||||
#error YARROW Requires CTR mode
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* packet code */
|
||||
#if defined(MRSA) || defined(MDH) || defined(MECC)
|
||||
#define PACKET
|
||||
|
||||
/* size of a packet header in bytes */
|
||||
#define PACKET_SIZE 8
|
||||
|
||||
/* Section tags */
|
||||
#define PACKET_SECT_RSA 0
|
||||
#define PACKET_SECT_DH 1
|
||||
#define PACKET_SECT_ECC 2
|
||||
|
||||
/* Subsection Tags for the first three sections */
|
||||
#define PACKET_SUB_KEY 0
|
||||
#define PACKET_SUB_ENCRYPTED 1
|
||||
#define PACKET_SUB_SIGNED 2
|
||||
#define PACKET_SUB_ENC_KEY 3
|
||||
#endif
|
||||
|
||||
/* Diffie-Hellman key settings you can omit ones you don't want to save space */
|
||||
#ifdef MDH
|
||||
|
||||
#define DH512
|
||||
#define DH768
|
||||
#define DH1024
|
||||
#define DH1280
|
||||
#define DH1536
|
||||
#define DH1792
|
||||
#define DH2048
|
||||
#define DH2560
|
||||
#define DH3072
|
||||
#define DH4096
|
||||
|
||||
#endif /* MDH */
|
||||
|
||||
/* ECC Key settings */
|
||||
#ifdef MECC
|
||||
|
||||
#define ECC160
|
||||
#define ECC192
|
||||
#define ECC224
|
||||
#define ECC256
|
||||
#define ECC384
|
||||
#define ECC521
|
||||
|
||||
#endif /* MECC */
|
||||
|
||||
#ifdef MPI
|
||||
#include "mpi.h"
|
||||
#else
|
||||
#ifdef MRSA
|
||||
#error RSA requires the big int library
|
||||
#endif
|
||||
#ifdef MECC
|
||||
#error ECC requires the big int library
|
||||
#endif
|
||||
#ifdef MDH
|
||||
#error DH requires the big int library
|
||||
#endif
|
||||
#endif /* MPI */
|
||||
|
||||
#endif /* MYCRYPT_CFG_H */
|
||||
|
349
mycrypt_cipher.h
Normal file
349
mycrypt_cipher.h
Normal file
@ -0,0 +1,349 @@
|
||||
/* ---- SYMMETRIC KEY STUFF -----
|
||||
*
|
||||
* We put each of the ciphers scheduled keys in their own structs then we put all of
|
||||
* the key formats in one union. This makes the function prototypes easier to use.
|
||||
*/
|
||||
#ifdef BLOWFISH
|
||||
struct blowfish_key {
|
||||
unsigned long S[4][256];
|
||||
unsigned long K[18];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef RC5
|
||||
struct rc5_key {
|
||||
int rounds;
|
||||
unsigned long K[50];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef RC6
|
||||
struct rc6_key {
|
||||
unsigned long K[44];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef SAFERP
|
||||
struct saferp_key {
|
||||
unsigned char K[33][16];
|
||||
long rounds;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef SERPENT
|
||||
struct serpent_key {
|
||||
unsigned long K[132];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef RIJNDAEL
|
||||
struct rijndael_key {
|
||||
unsigned long eK[64], dK[64], k_len;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef XTEA
|
||||
struct xtea_key {
|
||||
unsigned long K[4];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef TWOFISH
|
||||
#ifndef TWOFISH_SMALL
|
||||
struct twofish_key {
|
||||
unsigned long S[4][256], K[40];
|
||||
};
|
||||
#else
|
||||
struct twofish_key {
|
||||
unsigned long K[40];
|
||||
unsigned char S[32], start;
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SAFER
|
||||
#define SAFER_K64_DEFAULT_NOF_ROUNDS 6
|
||||
#define SAFER_K128_DEFAULT_NOF_ROUNDS 10
|
||||
#define SAFER_SK64_DEFAULT_NOF_ROUNDS 8
|
||||
#define SAFER_SK128_DEFAULT_NOF_ROUNDS 10
|
||||
#define SAFER_MAX_NOF_ROUNDS 13
|
||||
#define SAFER_BLOCK_LEN 8
|
||||
#define SAFER_KEY_LEN (1 + SAFER_BLOCK_LEN * (1 + 2 * SAFER_MAX_NOF_ROUNDS))
|
||||
typedef unsigned char safer_block_t[SAFER_BLOCK_LEN];
|
||||
typedef unsigned char safer_key_t[SAFER_KEY_LEN];
|
||||
struct safer_key { safer_key_t key; };
|
||||
#endif
|
||||
|
||||
#ifdef RC2
|
||||
struct rc2_key { unsigned xkey[64]; };
|
||||
#endif
|
||||
|
||||
#ifdef DES
|
||||
struct des_key {
|
||||
unsigned long ek[32], dk[32];
|
||||
};
|
||||
|
||||
struct des3_key {
|
||||
unsigned long ek[3][32], dk[3][32];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CAST5
|
||||
struct cast5_key {
|
||||
unsigned long K[32], keylen;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef union Symmetric_key {
|
||||
#ifdef DES
|
||||
struct des_key des;
|
||||
struct des3_key des3;
|
||||
#endif
|
||||
#ifdef RC2
|
||||
struct rc2_key rc2;
|
||||
#endif
|
||||
#ifdef SAFER
|
||||
struct safer_key safer;
|
||||
#endif
|
||||
#ifdef TWOFISH
|
||||
struct twofish_key twofish;
|
||||
#endif
|
||||
#ifdef BLOWFISH
|
||||
struct blowfish_key blowfish;
|
||||
#endif
|
||||
#ifdef RC5
|
||||
struct rc5_key rc5;
|
||||
#endif
|
||||
#ifdef RC6
|
||||
struct rc6_key rc6;
|
||||
#endif
|
||||
#ifdef SAFERP
|
||||
struct saferp_key saferp;
|
||||
#endif
|
||||
#ifdef SERPENT
|
||||
struct serpent_key serpent;
|
||||
#endif
|
||||
#ifdef RIJNDAEL
|
||||
struct rijndael_key rijndael;
|
||||
#endif
|
||||
#ifdef XTEA
|
||||
struct xtea_key xtea;
|
||||
#endif
|
||||
#ifdef CAST5
|
||||
struct cast5_key cast5;
|
||||
#endif
|
||||
} symmetric_key;
|
||||
|
||||
/* A block cipher ECB structure */
|
||||
typedef struct {
|
||||
int cipher, blocklen;
|
||||
symmetric_key key;
|
||||
} symmetric_ECB;
|
||||
|
||||
/* A block cipher CFB structure */
|
||||
typedef struct {
|
||||
int cipher, blocklen, padlen;
|
||||
unsigned char IV[MAXBLOCKSIZE], pad[MAXBLOCKSIZE];
|
||||
symmetric_key key;
|
||||
} symmetric_CFB;
|
||||
|
||||
/* A block cipher OFB structure */
|
||||
typedef struct {
|
||||
int cipher, blocklen, padlen;
|
||||
unsigned char IV[MAXBLOCKSIZE];
|
||||
symmetric_key key;
|
||||
} symmetric_OFB;
|
||||
|
||||
/* A block cipher CBC structure */
|
||||
typedef struct Symmetric_CBC {
|
||||
int cipher, blocklen;
|
||||
unsigned char IV[MAXBLOCKSIZE];
|
||||
symmetric_key key;
|
||||
} symmetric_CBC;
|
||||
|
||||
/* A block cipher CTR structure */
|
||||
typedef struct Symmetric_CTR {
|
||||
int cipher, blocklen, padlen;
|
||||
unsigned char ctr[MAXBLOCKSIZE], pad[MAXBLOCKSIZE];
|
||||
symmetric_key key;
|
||||
} symmetric_CTR;
|
||||
|
||||
/* cipher descriptor table, last entry has "name == NULL" to mark the end of table */
|
||||
extern struct _cipher_descriptor {
|
||||
char *name;
|
||||
unsigned char ID;
|
||||
unsigned long min_key_length, max_key_length, block_length, default_rounds;
|
||||
int (*setup)(const unsigned char *key, int keylength, int num_rounds, symmetric_key *skey);
|
||||
void (*ecb_encrypt)(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
void (*ecb_decrypt)(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
int (*test)(void);
|
||||
int (*keysize)(int *desired_keysize);
|
||||
} cipher_descriptor[];
|
||||
|
||||
#ifdef BLOWFISH
|
||||
extern int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int blowfish_test(void);
|
||||
extern int blowfish_keysize(int *desired_keysize);
|
||||
extern const struct _cipher_descriptor blowfish_desc;
|
||||
#endif
|
||||
|
||||
#ifdef RC5
|
||||
extern int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int rc5_test(void);
|
||||
extern int rc5_keysize(int *desired_keysize);
|
||||
extern const struct _cipher_descriptor rc5_desc;
|
||||
#endif
|
||||
|
||||
#ifdef RC6
|
||||
extern int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int rc6_test(void);
|
||||
extern int rc6_keysize(int *desired_keysize);
|
||||
extern const struct _cipher_descriptor rc6_desc;
|
||||
#endif
|
||||
|
||||
#ifdef RC2
|
||||
extern int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int rc2_test(void);
|
||||
extern int rc2_keysize(int *desired_keysize);
|
||||
extern const struct _cipher_descriptor rc2_desc;
|
||||
#endif
|
||||
|
||||
#ifdef SAFERP
|
||||
extern int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int saferp_test(void);
|
||||
extern int saferp_keysize(int *desired_keysize);
|
||||
extern const struct _cipher_descriptor saferp_desc;
|
||||
#endif
|
||||
|
||||
#ifdef SAFER
|
||||
extern int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
|
||||
extern int safer_k64_test(void);
|
||||
extern int safer_sk64_test(void);
|
||||
extern int safer_sk128_test(void);
|
||||
|
||||
extern int safer_64_keysize(int *desired_keysize);
|
||||
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;
|
||||
#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
|
||||
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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int rijndael_test(void);
|
||||
extern int rijndael_keysize(int *desired_keysize);
|
||||
extern const struct _cipher_descriptor rijndael_desc;
|
||||
#endif
|
||||
|
||||
#ifdef XTEA
|
||||
extern int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int xtea_test(void);
|
||||
extern int xtea_keysize(int *desired_keysize);
|
||||
extern const struct _cipher_descriptor xtea_desc;
|
||||
#endif
|
||||
|
||||
#ifdef TWOFISH
|
||||
extern int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int twofish_test(void);
|
||||
extern int twofish_keysize(int *desired_keysize);
|
||||
extern const struct _cipher_descriptor twofish_desc;
|
||||
#endif
|
||||
|
||||
#ifdef DES
|
||||
extern int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int des_test(void);
|
||||
extern int des_keysize(int *desired_keysize);
|
||||
|
||||
extern int des3_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int des3_test(void);
|
||||
extern int des3_keysize(int *desired_keysize);
|
||||
|
||||
extern const struct _cipher_descriptor des_desc, des3_desc;
|
||||
#endif
|
||||
|
||||
#ifdef CAST5
|
||||
extern int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
|
||||
extern void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
|
||||
extern void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
|
||||
extern int cast5_test(void);
|
||||
extern int cast5_keysize(int *desired_keysize);
|
||||
extern const struct _cipher_descriptor cast5_desc;
|
||||
#endif
|
||||
|
||||
#ifdef ECB
|
||||
extern int ecb_start(int cipher, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_ECB *ecb);
|
||||
extern int ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ECB *ecb);
|
||||
extern int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb);
|
||||
#endif
|
||||
|
||||
#ifdef CFB
|
||||
extern int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_CFB *cfb);
|
||||
extern int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb);
|
||||
extern int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb);
|
||||
#endif
|
||||
|
||||
#ifdef OFB
|
||||
extern int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_OFB *ofb);
|
||||
extern int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb);
|
||||
extern int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb);
|
||||
#endif
|
||||
|
||||
#ifdef CBC
|
||||
extern int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_CBC *cbc);
|
||||
extern int cbc_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc);
|
||||
extern int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc);
|
||||
#endif
|
||||
|
||||
#ifdef CTR
|
||||
extern int ctr_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, 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);
|
||||
#endif
|
||||
|
||||
extern int find_cipher(const char *name);
|
||||
extern int find_cipher_any(const char *name, int blocklen, int keylen);
|
||||
extern int find_cipher_id(unsigned char ID);
|
||||
|
||||
extern int register_cipher(const struct _cipher_descriptor *cipher);
|
||||
extern int unregister_cipher(const struct _cipher_descriptor *cipher);
|
||||
|
||||
extern int cipher_is_valid(int idx);
|
||||
|
32
mycrypt_gf.h
Normal file
32
mycrypt_gf.h
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
/* ---- GF(2^w) polynomial basis ---- */
|
||||
#ifdef GF
|
||||
#define LSIZE 32 /* handle upto 1024-bit GF numbers */
|
||||
|
||||
typedef unsigned long gf_int[LSIZE];
|
||||
typedef unsigned long *gf_intp;
|
||||
|
||||
extern void gf_copy(gf_intp a, gf_intp b);
|
||||
extern void gf_zero(gf_intp a);
|
||||
extern int gf_iszero(gf_intp a);
|
||||
extern int gf_isone(gf_intp a);
|
||||
extern int gf_deg(gf_intp a);
|
||||
|
||||
extern void gf_shl(gf_intp a, gf_intp b);
|
||||
extern void gf_shr(gf_intp a, gf_intp b);
|
||||
extern void gf_add(gf_intp a, gf_intp b, gf_intp c);
|
||||
extern void gf_mul(gf_intp a, gf_intp b, gf_intp c);
|
||||
extern void gf_div(gf_intp a, gf_intp b, gf_intp q, gf_intp r);
|
||||
|
||||
extern void gf_mod(gf_intp a, gf_intp m, gf_intp b);
|
||||
extern void gf_mulmod(gf_intp a, gf_intp b, gf_intp m, gf_intp c);
|
||||
extern void gf_invmod(gf_intp A, gf_intp M, gf_intp B);
|
||||
extern void gf_sqrt(gf_intp a, gf_intp M, gf_intp b);
|
||||
extern void gf_gcd(gf_intp A, gf_intp B, gf_intp c);
|
||||
extern int gf_is_prime(gf_intp a);
|
||||
|
||||
extern int gf_size(gf_intp a);
|
||||
extern void gf_toraw(gf_intp a, unsigned char *dst);
|
||||
extern void gf_readraw(gf_intp a, unsigned char *str, int len);
|
||||
|
||||
#endif
|
184
mycrypt_hash.h
Normal file
184
mycrypt_hash.h
Normal file
@ -0,0 +1,184 @@
|
||||
/* ---- HASH FUNCTIONS ---- */
|
||||
#ifdef SHA512
|
||||
struct sha512_state {
|
||||
ulong64 length, state[8];
|
||||
unsigned long curlen;
|
||||
unsigned char buf[128];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef SHA256
|
||||
struct sha256_state {
|
||||
ulong64 length;
|
||||
unsigned long state[8], curlen;
|
||||
unsigned char buf[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef SHA1
|
||||
struct sha1_state {
|
||||
ulong64 length;
|
||||
unsigned long state[5], curlen;
|
||||
unsigned char buf[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef MD5
|
||||
struct md5_state {
|
||||
ulong64 length;
|
||||
unsigned long state[4], curlen;
|
||||
unsigned char buf[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef MD4
|
||||
struct md4_state {
|
||||
ulong64 length;
|
||||
unsigned long state[4], curlen;
|
||||
unsigned char buf[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef TIGER
|
||||
struct tiger_state {
|
||||
ulong64 state[3], length;
|
||||
unsigned long curlen;
|
||||
unsigned char buf[64];
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef MD2
|
||||
struct md2_state {
|
||||
unsigned char chksum[16], X[48], buf[16];
|
||||
unsigned long curlen;
|
||||
};
|
||||
#endif
|
||||
|
||||
typedef union Hash_state {
|
||||
#ifdef SHA512
|
||||
struct sha512_state sha512;
|
||||
#endif
|
||||
#ifdef SHA256
|
||||
struct sha256_state sha256;
|
||||
#endif
|
||||
#ifdef SHA1
|
||||
struct sha1_state sha1;
|
||||
#endif
|
||||
#ifdef MD5
|
||||
struct md5_state md5;
|
||||
#endif
|
||||
#ifdef MD4
|
||||
struct md4_state md4;
|
||||
#endif
|
||||
#ifdef MD2
|
||||
struct md2_state md2;
|
||||
#endif
|
||||
#ifdef TIGER
|
||||
struct tiger_state tiger;
|
||||
#endif
|
||||
} hash_state;
|
||||
|
||||
extern struct _hash_descriptor {
|
||||
char *name;
|
||||
unsigned char ID;
|
||||
unsigned long hashsize; /* digest output size in bytes */
|
||||
unsigned long blocksize; /* the block size the hash uses */
|
||||
void (*init)(hash_state *);
|
||||
void (*process)(hash_state *, const unsigned char *, unsigned long);
|
||||
void (*done)(hash_state *, unsigned char *);
|
||||
int (*test)(void);
|
||||
} hash_descriptor[];
|
||||
|
||||
#ifdef SHA512
|
||||
extern void sha512_init(hash_state * md);
|
||||
extern void sha512_process(hash_state * md, const unsigned char *buf, unsigned long len);
|
||||
extern void sha512_done(hash_state * md, unsigned char *hash);
|
||||
extern int sha512_test(void);
|
||||
extern const struct _hash_descriptor sha512_desc;
|
||||
#endif
|
||||
|
||||
#ifdef SHA384
|
||||
extern void sha384_init(hash_state * md);
|
||||
extern void sha384_process(hash_state * md, const unsigned char *buf, unsigned long len);
|
||||
extern void sha384_done(hash_state * md, unsigned char *hash);
|
||||
extern int sha384_test(void);
|
||||
extern const struct _hash_descriptor sha384_desc;
|
||||
#endif
|
||||
|
||||
#ifdef SHA256
|
||||
extern void sha256_init(hash_state * md);
|
||||
extern void sha256_process(hash_state * md, const unsigned char *buf, unsigned long len);
|
||||
extern void sha256_done(hash_state * md, unsigned char *hash);
|
||||
extern int sha256_test(void);
|
||||
extern const struct _hash_descriptor sha256_desc;
|
||||
#endif
|
||||
|
||||
#ifdef SHA1
|
||||
extern void sha1_init(hash_state * md);
|
||||
extern void sha1_process(hash_state * md, const unsigned char *buf, unsigned long len);
|
||||
extern void sha1_done(hash_state * md, unsigned char *hash);
|
||||
extern int sha1_test(void);
|
||||
extern const struct _hash_descriptor sha1_desc;
|
||||
#endif
|
||||
|
||||
#ifdef MD5
|
||||
extern void md5_init(hash_state * md);
|
||||
extern void md5_process(hash_state * md, const unsigned char *buf, unsigned long len);
|
||||
extern void md5_done(hash_state * md, unsigned char *hash);
|
||||
extern int md5_test(void);
|
||||
extern const struct _hash_descriptor md5_desc;
|
||||
#endif
|
||||
|
||||
#ifdef MD4
|
||||
extern void md4_init(hash_state * md);
|
||||
extern void md4_process(hash_state * md, const unsigned char *buf, unsigned long len);
|
||||
extern void md4_done(hash_state * md, unsigned char *hash);
|
||||
extern int md4_test(void);
|
||||
extern const struct _hash_descriptor md4_desc;
|
||||
#endif
|
||||
|
||||
#ifdef MD2
|
||||
extern void md2_init(hash_state * md);
|
||||
extern void md2_process(hash_state * md, const unsigned char *buf, unsigned long len);
|
||||
extern void md2_done(hash_state * md, unsigned char *hash);
|
||||
extern int md2_test(void);
|
||||
extern const struct _hash_descriptor md2_desc;
|
||||
#endif
|
||||
|
||||
#ifdef TIGER
|
||||
extern void tiger_init(hash_state * md);
|
||||
extern void tiger_process(hash_state * md, const unsigned char *buf, unsigned long len);
|
||||
extern void tiger_done(hash_state * md, unsigned char *hash);
|
||||
extern int tiger_test(void);
|
||||
extern const struct _hash_descriptor tiger_desc;
|
||||
#endif
|
||||
|
||||
extern int find_hash(const char *name);
|
||||
extern int find_hash_id(unsigned char ID);
|
||||
extern int register_hash(const struct _hash_descriptor *hash);
|
||||
extern int unregister_hash(const struct _hash_descriptor *hash);
|
||||
extern int hash_is_valid(int idx);
|
||||
|
||||
extern int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned char *dst, unsigned long *outlen);
|
||||
extern int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outlen);
|
||||
extern int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *outlen);
|
||||
|
||||
#ifdef HMAC
|
||||
typedef struct Hmac_state {
|
||||
hash_state md;
|
||||
int hash;
|
||||
unsigned long hashsize; /* here for your reference */
|
||||
hash_state hashstate;
|
||||
unsigned char key[MAXBLOCKSIZE];
|
||||
} hmac_state;
|
||||
|
||||
extern int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen);
|
||||
extern int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len);
|
||||
extern int hmac_done(hmac_state *hmac, unsigned char *hash);
|
||||
extern int hmac_test(void);
|
||||
extern int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *data, unsigned long len, unsigned char *dst);
|
||||
extern int hmac_file(int hash, const char *fname, const unsigned char *key,
|
||||
unsigned long keylen, unsigned char *dst);
|
||||
#endif
|
||||
|
77
mycrypt_kr.h
Normal file
77
mycrypt_kr.h
Normal file
@ -0,0 +1,77 @@
|
||||
#ifdef KR
|
||||
|
||||
#define MAXLEN 256
|
||||
|
||||
enum {
|
||||
NON_KEY=0,
|
||||
RSA_KEY,
|
||||
DH_KEY,
|
||||
ECC_KEY
|
||||
};
|
||||
|
||||
typedef union {
|
||||
rsa_key rsa;
|
||||
dh_key dh;
|
||||
ecc_key ecc;
|
||||
} _pk_key;
|
||||
|
||||
typedef struct Pk_key {
|
||||
int key_type, /* PUBLIC, PRIVATE, PRIVATE_OPTIMIZED */
|
||||
system; /* RSA, ECC or DH ? */
|
||||
|
||||
unsigned char
|
||||
name[MAXLEN], /* various info's about this key */
|
||||
email[MAXLEN],
|
||||
description[MAXLEN];
|
||||
|
||||
unsigned long ID; /* CRC32 of the name/email/description together */
|
||||
|
||||
_pk_key key;
|
||||
|
||||
struct Pk_key *next; /* linked list chain */
|
||||
} pk_key;
|
||||
|
||||
extern int kr_init(pk_key **pk);
|
||||
|
||||
extern unsigned long kr_crc(const unsigned char *name, const unsigned char *email, const unsigned char *description);
|
||||
|
||||
extern pk_key *kr_find(pk_key *pk, unsigned long ID);
|
||||
extern pk_key *kr_find_name(pk_key *pk, const char *name);
|
||||
|
||||
extern int kr_add(pk_key *pk, int key_type, int system, const unsigned char *name,
|
||||
const unsigned char *email, const unsigned char *description, const _pk_key *key);
|
||||
|
||||
extern int kr_del(pk_key **_pk, unsigned long ID);
|
||||
extern int kr_clear(pk_key **pk);
|
||||
extern int kr_make_key(pk_key *pk, prng_state *prng, int wprng,
|
||||
int system, int keysize, const unsigned char *name,
|
||||
const unsigned char *email, const unsigned char *description);
|
||||
|
||||
extern int kr_export(pk_key *pk, unsigned long ID, int key_type, unsigned char *out, unsigned long *outlen);
|
||||
extern int kr_import(pk_key *pk, const unsigned char *in);
|
||||
|
||||
extern int kr_load(pk_key **pk, FILE *in, symmetric_CTR *ctr);
|
||||
extern int kr_save(pk_key *pk, FILE *out, symmetric_CTR *ctr);
|
||||
|
||||
extern int kr_encrypt_key(pk_key *pk, unsigned long ID,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash);
|
||||
|
||||
extern int kr_decrypt_key(pk_key *pk, const unsigned char *in,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
extern int kr_sign_hash(pk_key *pk, unsigned long ID,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng);
|
||||
|
||||
extern int kr_verify_hash(pk_key *pk, const unsigned char *in,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat);
|
||||
|
||||
extern int kr_fingerprint(pk_key *pk, unsigned long ID, int hash,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
#endif
|
||||
|
200
mycrypt_macros.h
Normal file
200
mycrypt_macros.h
Normal file
@ -0,0 +1,200 @@
|
||||
/* fix for MSVC ...evil! */
|
||||
#ifdef _MSC_VER
|
||||
#define CONST64(n) n ## ui64
|
||||
typedef unsigned __int64 ulong64;
|
||||
#else
|
||||
#define CONST64(n) n ## ULL
|
||||
typedef unsigned long long ulong64;
|
||||
#endif
|
||||
|
||||
extern char *crypt_error;
|
||||
|
||||
/* ---- HELPER MACROS ---- */
|
||||
#ifdef ENDIAN_NEUTRAL
|
||||
|
||||
#define STORE32L(x, y) \
|
||||
{ (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD32L(x, y) \
|
||||
{ x = ((unsigned long)((y)[3] & 255)<<24) | \
|
||||
((unsigned long)((y)[2] & 255)<<16) | \
|
||||
((unsigned long)((y)[1] & 255)<<8) | \
|
||||
((unsigned long)((y)[0] & 255)); }
|
||||
|
||||
#define STORE64L(x, y) \
|
||||
{ (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64L(x, y) \
|
||||
{ x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
|
||||
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
|
||||
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
|
||||
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
|
||||
|
||||
#define STORE32H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD32H(x, y) \
|
||||
{ x = ((unsigned long)((y)[0] & 255)<<24) | \
|
||||
((unsigned long)((y)[1] & 255)<<16) | \
|
||||
((unsigned long)((y)[2] & 255)<<8) | \
|
||||
((unsigned long)((y)[3] & 255)); }
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64H(x, y) \
|
||||
{ x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
|
||||
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
|
||||
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
|
||||
(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
|
||||
|
||||
#endif /* ENDIAN_NEUTRAL */
|
||||
|
||||
#ifdef ENDIAN_LITTLE
|
||||
|
||||
#define STORE32H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD32H(x, y) \
|
||||
{ x = ((unsigned long)((y)[0] & 255)<<24) | \
|
||||
((unsigned long)((y)[1] & 255)<<16) | \
|
||||
((unsigned long)((y)[2] & 255)<<8) | \
|
||||
((unsigned long)((y)[3] & 255)); }
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64H(x, y) \
|
||||
{ x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
|
||||
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
|
||||
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
|
||||
(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
|
||||
|
||||
#ifdef ENDIAN_32BITWORD
|
||||
|
||||
#define STORE32L(x, y) \
|
||||
{ unsigned long t = (x); memcpy(y, &t, 4); }
|
||||
|
||||
#define LOAD32L(x, y) \
|
||||
memcpy(&(x), y, 4);
|
||||
|
||||
#define STORE64L(x, y) \
|
||||
{ (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64L(x, y) \
|
||||
{ x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
|
||||
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
|
||||
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
|
||||
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
|
||||
|
||||
#else /* 64-bit words then */
|
||||
|
||||
#define STORE32L(x, y) \
|
||||
{ unsigned long t = (x); memcpy(y, &t, 4); }
|
||||
|
||||
#define LOAD32L(x, y) \
|
||||
{ memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
|
||||
|
||||
#define STORE64L(x, y) \
|
||||
{ ulong64 t = (x); memcpy(y, &t, 8); }
|
||||
|
||||
#define LOAD64L(x, y) \
|
||||
{ memcpy(&(x), y, 8); }
|
||||
|
||||
#endif /* ENDIAN_64BITWORD */
|
||||
|
||||
#endif /* ENDIAN_LITTLE */
|
||||
|
||||
#ifdef ENDIAN_BIG
|
||||
#define STORE32L(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD32L(x, y) \
|
||||
{ x = ((unsigned long)((y)[0] & 255)<<24) | \
|
||||
((unsigned long)((y)[1] & 255)<<16) | \
|
||||
((unsigned long)((y)[2] & 255)<<8) | \
|
||||
((unsigned long)((y)[3] & 255)); }
|
||||
|
||||
#define STORE64L(x, y) \
|
||||
{ (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64L(x, y) \
|
||||
{ x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
|
||||
(((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
|
||||
(((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
|
||||
(((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
|
||||
|
||||
#ifdef ENDIAN_32BITWORD
|
||||
|
||||
#define STORE32H(x, y) \
|
||||
{ unsigned long t = (x); memcpy(y, &t, 4); }
|
||||
|
||||
#define LOAD32H(x, y) \
|
||||
memcpy(&(x), y, 4);
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
{ (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255); \
|
||||
(y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255); \
|
||||
(y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255); \
|
||||
(y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
|
||||
|
||||
#define LOAD64H(x, y) \
|
||||
{ x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
|
||||
(((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
|
||||
(((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
|
||||
(((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
|
||||
|
||||
#else /* 64-bit words then */
|
||||
|
||||
#define STORE32H(x, y) \
|
||||
{ unsigned long t = (x); memcpy(y, &t, 4); }
|
||||
|
||||
#define LOAD32H(x, y) \
|
||||
{ memcpy(&(x), y, 4); x &= 0xFFFFFFFF; }
|
||||
|
||||
#define STORE64H(x, y) \
|
||||
{ ulong64 t = (x); memcpy(y, &t, 8); }
|
||||
|
||||
#define LOAD64H(x, y) \
|
||||
{ memcpy(&(x), y, 8); }
|
||||
|
||||
#endif /* ENDIAN_64BITWORD */
|
||||
#endif /* ENDIAN_BIG */
|
||||
|
||||
#define BSWAP(x) ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL) | \
|
||||
((x>>8)&0x0000FF00UL) | ((x<<8)&0x00FF0000UL) )
|
||||
|
||||
#define ROL(x, y) ( (((x)<<((y)&31)) | (((x)&0xFFFFFFFFUL)>>(32-((y)&31)))) & 0xFFFFFFFFUL)
|
||||
#define ROR(x, y) ( ((((x)&0xFFFFFFFFUL)>>((y)&31)) | ((x)<<(32-((y)&31)))) & 0xFFFFFFFFUL)
|
||||
|
||||
#define ROL64(x, y) \
|
||||
( (((x)<<((ulong64)(y)&63)) | \
|
||||
(((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
|
||||
|
||||
#define ROR64(x, y) \
|
||||
( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
|
||||
((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
|
||||
|
||||
#undef MAX
|
||||
#undef MIN
|
||||
#define MAX(x, y) ( ((x)>(y))?(x):(y) )
|
||||
#define MIN(x, y) ( ((x)<(y))?(x):(y) )
|
16
mycrypt_misc.h
Normal file
16
mycrypt_misc.h
Normal file
@ -0,0 +1,16 @@
|
||||
/* ---- BASE64 Routines ---- */
|
||||
#ifdef BASE64
|
||||
extern int base64_encode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
extern int base64_decode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
#endif
|
||||
|
||||
/* ---- MEM routines ---- */
|
||||
extern void zeromem(void *dst, unsigned long len);
|
||||
extern void burn_stack(unsigned long len);
|
||||
|
||||
extern const char *error_to_string(int errno);
|
||||
|
||||
extern const char *crypt_build_settings;
|
219
mycrypt_pk.h
Normal file
219
mycrypt_pk.h
Normal file
@ -0,0 +1,219 @@
|
||||
/* ---- NUMBER THEORY ---- */
|
||||
#ifdef MPI
|
||||
|
||||
extern int is_prime(mp_int *, int *);
|
||||
extern int rand_prime(mp_int *N, long len, prng_state *prng, int wprng);
|
||||
extern mp_err mp_init_multi(mp_int* mp, ...);
|
||||
extern void mp_clear_multi(mp_int* mp, ...);
|
||||
|
||||
#endif
|
||||
|
||||
/* ---- PUBLIC KEY CRYPTO ---- */
|
||||
|
||||
#define PK_PRIVATE 0 /* PK private keys */
|
||||
#define PK_PUBLIC 1 /* PK public keys */
|
||||
#define PK_PRIVATE_OPTIMIZED 2 /* PK private key [rsa optimized] */
|
||||
|
||||
/* ---- PACKET ---- */
|
||||
#ifdef PACKET
|
||||
|
||||
extern void packet_store_header(unsigned char *dst, int section, int subsection, unsigned long length);
|
||||
extern int packet_valid_header(unsigned char *src, int section, int subsection);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ---- RSA ---- */
|
||||
#ifdef MRSA
|
||||
typedef struct Rsa_key {
|
||||
int type;
|
||||
mp_int e, d, N, qP, pQ, dP, dQ, p, q;
|
||||
} rsa_key;
|
||||
|
||||
extern int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key);
|
||||
|
||||
extern int rsa_exptmod(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int which,
|
||||
rsa_key *key);
|
||||
|
||||
extern int rsa_pad(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
int wprng, prng_state *prng);
|
||||
|
||||
extern int rsa_signpad(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
extern int rsa_depad(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
extern int rsa_signdepad(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
|
||||
extern void rsa_free(rsa_key *key);
|
||||
|
||||
#ifdef PK_PACKET
|
||||
|
||||
extern int rsa_encrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int cipher,
|
||||
rsa_key *key);
|
||||
|
||||
extern int rsa_decrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
rsa_key *key);
|
||||
|
||||
extern int rsa_sign(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
int hash, rsa_key *key);
|
||||
|
||||
extern int rsa_verify(const unsigned char *sig, const unsigned char *msg,
|
||||
unsigned long inlen, int *stat,
|
||||
rsa_key *key);
|
||||
|
||||
#endif
|
||||
|
||||
extern int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, rsa_key *key);
|
||||
|
||||
extern int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, rsa_key *key);
|
||||
|
||||
extern int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
rsa_key *key);
|
||||
|
||||
extern int rsa_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
int *stat, rsa_key *key);
|
||||
|
||||
extern int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
|
||||
extern int rsa_import(const unsigned char *in, rsa_key *key);
|
||||
#endif
|
||||
|
||||
/* ---- DH Routines ---- */
|
||||
#ifdef MDH
|
||||
|
||||
typedef struct Dh_key {
|
||||
int idx, type;
|
||||
mp_int x, y;
|
||||
} dh_key;
|
||||
|
||||
extern int dh_test(void);
|
||||
extern void dh_sizes(int *low, int *high);
|
||||
extern int dh_get_size(dh_key *key);
|
||||
|
||||
extern int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key);
|
||||
extern void dh_free(dh_key *key);
|
||||
|
||||
extern int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_key *key);
|
||||
extern int dh_import(const unsigned char *in, dh_key *key);
|
||||
|
||||
extern int dh_shared_secret(dh_key *private_key, dh_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
#ifdef PK_PACKET
|
||||
|
||||
extern int dh_encrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int cipher, int hash,
|
||||
dh_key *key);
|
||||
|
||||
extern int dh_decrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
dh_key *key);
|
||||
|
||||
extern int dh_sign(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int hash,
|
||||
prng_state *prng, int wprng,
|
||||
dh_key *key);
|
||||
|
||||
extern int dh_verify(const unsigned char *sig, const unsigned char *msg,
|
||||
unsigned long inlen, int *stat,
|
||||
dh_key *key);
|
||||
|
||||
#endif
|
||||
|
||||
extern int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *len,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
dh_key *key);
|
||||
|
||||
extern int dh_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, dh_key *key);
|
||||
|
||||
extern int dh_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, dh_key *key);
|
||||
|
||||
extern int dh_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
unsigned long inlen, int *stat,
|
||||
dh_key *key);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* ---- ECC Routines ---- */
|
||||
#ifdef MECC
|
||||
typedef struct {
|
||||
mp_int x, y;
|
||||
} ecc_point;
|
||||
|
||||
typedef struct {
|
||||
int type, idx;
|
||||
ecc_point pubkey;
|
||||
mp_int k;
|
||||
} ecc_key;
|
||||
|
||||
extern int ecc_test(void);
|
||||
extern void ecc_sizes(int *low, int *high);
|
||||
extern int ecc_get_size(ecc_key *key);
|
||||
|
||||
extern int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
|
||||
extern void ecc_free(ecc_key *key);
|
||||
|
||||
extern int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
|
||||
extern int ecc_import(const unsigned char *in, ecc_key *key);
|
||||
|
||||
extern int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
#ifdef PK_PACKET
|
||||
|
||||
extern int ecc_encrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int cipher, int hash,
|
||||
ecc_key *key);
|
||||
|
||||
extern int ecc_decrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
ecc_key *key);
|
||||
|
||||
extern int ecc_sign(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int hash,
|
||||
prng_state *prng, int wprng,
|
||||
ecc_key *key);
|
||||
|
||||
extern int ecc_verify(const unsigned char *sig, const unsigned char *msg,
|
||||
unsigned long inlen, int *stat,
|
||||
ecc_key *key);
|
||||
|
||||
#endif
|
||||
|
||||
extern int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *len,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
ecc_key *key);
|
||||
|
||||
extern int ecc_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, ecc_key *key);
|
||||
|
||||
extern int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, ecc_key *key);
|
||||
|
||||
extern int ecc_verify_hash(const unsigned char *sig, const unsigned char *hash,
|
||||
unsigned long inlen, int *stat,
|
||||
ecc_key *key);
|
||||
#endif
|
||||
|
62
mycrypt_prng.h
Normal file
62
mycrypt_prng.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* ---- PRNG Stuff ---- */
|
||||
struct yarrow_prng {
|
||||
int cipher, hash;
|
||||
unsigned char pool[MAXBLOCKSIZE];
|
||||
symmetric_CTR ctr;
|
||||
};
|
||||
|
||||
struct rc4_prng {
|
||||
int x, y;
|
||||
unsigned char buf[256];
|
||||
};
|
||||
|
||||
typedef union Prng_state {
|
||||
struct yarrow_prng yarrow;
|
||||
struct rc4_prng rc4;
|
||||
} prng_state;
|
||||
|
||||
extern struct _prng_descriptor {
|
||||
char *name;
|
||||
int (*start)(prng_state *);
|
||||
int (*add_entropy)(const unsigned char *, unsigned long, prng_state *);
|
||||
int (*ready)(prng_state *);
|
||||
unsigned long (*read)(unsigned char *, unsigned long len, prng_state *);
|
||||
} prng_descriptor[];
|
||||
|
||||
#ifdef YARROW
|
||||
extern int yarrow_start(prng_state *prng);
|
||||
extern int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng);
|
||||
extern int yarrow_ready(prng_state *prng);
|
||||
extern unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng);
|
||||
extern const struct _prng_descriptor yarrow_desc;
|
||||
#endif
|
||||
|
||||
#ifdef RC4
|
||||
extern int rc4_start(prng_state *prng);
|
||||
extern int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng);
|
||||
extern int rc4_ready(prng_state *prng);
|
||||
extern unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng);
|
||||
extern const struct _prng_descriptor rc4_desc;
|
||||
#endif
|
||||
|
||||
#ifdef SPRNG
|
||||
extern int sprng_start(prng_state *prng);
|
||||
extern int sprng_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng);
|
||||
extern int sprng_ready(prng_state *prng);
|
||||
extern unsigned long sprng_read(unsigned char *buf, unsigned long len, prng_state *prng);
|
||||
extern const struct _prng_descriptor sprng_desc;
|
||||
#endif
|
||||
|
||||
extern int find_prng(const char *name);
|
||||
extern int register_prng(const struct _prng_descriptor *prng);
|
||||
extern int unregister_prng(const struct _prng_descriptor *prng);
|
||||
extern int prng_is_valid(int idx);
|
||||
|
||||
|
||||
/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this
|
||||
* might not work on all platforms as planned
|
||||
*/
|
||||
extern unsigned long rng_get_bytes(unsigned char *buf, unsigned long len, void (*callback)(void));
|
||||
|
||||
extern int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void));
|
||||
|
73
notes/tech0001.txt
Normal file
73
notes/tech0001.txt
Normal file
@ -0,0 +1,73 @@
|
||||
Tech Note 0001
|
||||
How to Gather Entropy on Embedded Systems
|
||||
Tom St Denis
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
This tech note explains a relatively simple way to gather entropy for a PRNG (Yarrow in this case) in embedded systems
|
||||
where there are few sources of entropy or physical sources.
|
||||
|
||||
When trying to setup a secure random number generator a fresh source of random data (entropy) is required to ensure the
|
||||
deterministic state of the PRNG is not known or predetermined with respect to an attacker.
|
||||
|
||||
At the very least the system requires one timer and one source of un-timed interrupts. by "un-timed" I mean interrupts
|
||||
that do not occur at regular intervals [e.g. joypad/keypad input, network packets, etc...].
|
||||
|
||||
First we shall begin by taking an overview of how the Yarrow PRNG works within libtomcrypt. At the heart of all
|
||||
PRNGs is the "prng_state" data type. This is a union of structures that hold the PRNG state for the various prngs. The
|
||||
first thing we require is a state...
|
||||
|
||||
prng_state myPrng;
|
||||
|
||||
Next we must initialize the state once to get the ball rolling
|
||||
|
||||
if (yarrow_start(&myPrng) != CRYPT_OK) {
|
||||
// error should never happen!
|
||||
}
|
||||
|
||||
At this point the PRNG is ready to accept fresh entropy which is added with
|
||||
|
||||
int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
|
||||
|
||||
This function is **NOT** thread safe which will come under consideration later. To add entropy to our PRNG we must
|
||||
call this function with fresh data as its sampled. Lets say we have a timer counter called "uTimer" which is a 32-bit
|
||||
long and say a 32-bit joyPad state called "uPad". An example interrupt handler would look like
|
||||
|
||||
void joypad_interrupt(...) {
|
||||
unsigned char buf[8];
|
||||
|
||||
STORE32L(uTimer, buf);
|
||||
STORE32L(uPad, buf+4)
|
||||
if (yarrow_add_entropy(buf, 8, &myPrng) != CRYPT_OK) {
|
||||
// this should never occur either unless you didn't call yarrow_start
|
||||
}
|
||||
|
||||
// handle interrupt
|
||||
}
|
||||
|
||||
In this snippet the timer count and state of the joypad are added together into the entropy pool. The timer is important
|
||||
because with respect to the joypad it is a good source of entropy (on its own its not). For example, the probability of
|
||||
the user pushing the up arrow is fairly high, but at a specific time is not.
|
||||
|
||||
This method doesn't gather alot of entropy and has to be used to for quite a while. One way to speed it up is to tap
|
||||
multiple sources. If you have a network adapter and other sources of events (keyboard, mouse, etc...) trapping their
|
||||
data is ideal as well. Its important to gather the timer along with the event data.
|
||||
|
||||
As mentioned the "yarrow_add_entropy()" function is not thread safe. If your system allows interrupt handlers to be
|
||||
interrupted themselves then you could have trouble. One simple way is to detect when an interrupt is in progress and
|
||||
simply not add entropy during the call (jump over the yarrow_add_entropy() call)
|
||||
|
||||
Once you feel that there has been enough entropy added to the pool then within a single thread you can call
|
||||
|
||||
int yarrow_ready(prng_state *prng)
|
||||
|
||||
Now the PRNG is ready to read via the
|
||||
|
||||
unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng)
|
||||
|
||||
It is a very good idea that once you call the yarrow_ready() function that you stop harvesting entropy in your interrupt
|
||||
functions. This will free up alot of CPU time. Also one more final note. The yarrow_read() function is not thread
|
||||
safe either. This means if you have multiple threads or processes that read from it you will have to add your own semaphores
|
||||
around calls to it.
|
||||
|
60
ofb.c
Normal file
60
ofb.c
Normal file
@ -0,0 +1,60 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef OFB
|
||||
|
||||
int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_OFB *ofb)
|
||||
{
|
||||
int x, errno;
|
||||
|
||||
_ARGCHK(IV != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(ofb != NULL);
|
||||
|
||||
if ((errno = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* copy details */
|
||||
ofb->cipher = cipher;
|
||||
ofb->blocklen = cipher_descriptor[cipher].block_length;
|
||||
for (x = 0; x < ofb->blocklen; x++) {
|
||||
ofb->IV[x] = IV[x];
|
||||
}
|
||||
|
||||
/* init the cipher */
|
||||
ofb->padlen = ofb->blocklen;
|
||||
return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key);
|
||||
}
|
||||
|
||||
int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb)
|
||||
{
|
||||
int errno;
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(ofb != NULL);
|
||||
if ((errno = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
while (len--) {
|
||||
if (ofb->padlen == ofb->blocklen) {
|
||||
cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key);
|
||||
ofb->padlen = 0;
|
||||
}
|
||||
*ct++ = *pt++ ^ ofb->IV[ofb->padlen++];
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb)
|
||||
{
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(ofb != NULL);
|
||||
return ofb_encrypt(ct, pt, len, ofb);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
43
packet.c
Normal file
43
packet.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef PACKET
|
||||
|
||||
void packet_store_header(unsigned char *dst, int section, int subsection, unsigned long length)
|
||||
{
|
||||
_ARGCHK(dst != NULL);
|
||||
|
||||
/* store version number */
|
||||
dst[0] = CRYPT&255;
|
||||
dst[1] = (CRYPT>>8)&255;
|
||||
|
||||
/* store section and subsection */
|
||||
dst[2] = section & 255;
|
||||
dst[3] = subsection & 255;
|
||||
|
||||
/* store length */
|
||||
STORE32L(length, &dst[4]);
|
||||
}
|
||||
|
||||
int packet_valid_header(unsigned char *src, int section, int subsection)
|
||||
{
|
||||
unsigned long ver;
|
||||
|
||||
_ARGCHK(src != NULL);
|
||||
|
||||
/* check version */
|
||||
ver = ((unsigned long)src[0]) | ((unsigned long)src[1] << 8);
|
||||
if (CRYPT < ver) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* check section and subsection */
|
||||
if (section != src[2] || subsection != src[3]) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
321
rc2.c
Normal file
321
rc2.c
Normal file
@ -0,0 +1,321 @@
|
||||
/**********************************************************************\
|
||||
* To commemorate the 1996 RSA Data Security Conference, the following *
|
||||
* code is released into the public domain by its author. Prost! *
|
||||
* *
|
||||
* This cipher uses 16-bit words and little-endian byte ordering. *
|
||||
* I wonder which processor it was optimized for? *
|
||||
* *
|
||||
* Thanks to CodeView, SoftIce, and D86 for helping bring this code to *
|
||||
* the public. *
|
||||
\**********************************************************************/
|
||||
|
||||
#include <mycrypt.h>
|
||||
|
||||
#ifdef RC2
|
||||
|
||||
const struct _cipher_descriptor rc2_desc = {
|
||||
"rc2",
|
||||
12, 8, 128, 8, 16,
|
||||
&rc2_setup,
|
||||
&rc2_ecb_encrypt,
|
||||
&rc2_ecb_decrypt,
|
||||
&rc2_test,
|
||||
&rc2_keysize
|
||||
};
|
||||
|
||||
|
||||
/**********************************************************************\
|
||||
* Expand a variable-length user key (between 1 and 128 bytes) to a *
|
||||
* 64-short working rc2 key, of at most "bits" effective key bits. *
|
||||
* The effective key bits parameter looks like an export control hack. *
|
||||
* For normal use, it should always be set to 1024. For convenience, *
|
||||
* zero is accepted as an alias for 1024. *
|
||||
\**********************************************************************/
|
||||
|
||||
/* 256-entry permutation table, probably derived somehow from pi */
|
||||
static const unsigned char permute[256] = {
|
||||
217,120,249,196, 25,221,181,237, 40,233,253,121, 74,160,216,157,
|
||||
198,126, 55,131, 43,118, 83,142, 98, 76,100,136, 68,139,251,162,
|
||||
23,154, 89,245,135,179, 79, 19, 97, 69,109,141, 9,129,125, 50,
|
||||
189,143, 64,235,134,183,123, 11,240,149, 33, 34, 92,107, 78,130,
|
||||
84,214,101,147,206, 96,178, 28,115, 86,192, 20,167,140,241,220,
|
||||
18,117,202, 31, 59,190,228,209, 66, 61,212, 48,163, 60,182, 38,
|
||||
111,191, 14,218, 70,105, 7, 87, 39,242, 29,155,188,148, 67, 3,
|
||||
248, 17,199,246,144,239, 62,231, 6,195,213, 47,200,102, 30,215,
|
||||
8,232,234,222,128, 82,238,247,132,170,114,172, 53, 77,106, 42,
|
||||
150, 26,210,113, 90, 21, 73,116, 75,159,208, 94, 4, 24,164,236,
|
||||
194,224, 65,110, 15, 81,203,204, 36,145,175, 80,161,244,112, 57,
|
||||
153,124, 58,133, 35,184,180,122,252, 2, 54, 91, 37, 85,151, 49,
|
||||
45, 93,250,152,227,138,146,174, 5,223, 41, 16,103,108,186,201,
|
||||
211, 0,230,207,225,158,168, 44, 99, 22, 1, 63, 88,226,137,169,
|
||||
13, 56, 52, 27,171, 51,255,176,187, 72, 12, 95,185,177,205, 46,
|
||||
197,243,219, 71,229,165,156,119, 10,166, 32,104,254,127,193,173
|
||||
};
|
||||
|
||||
int rc2_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
|
||||
{
|
||||
unsigned *xkey = skey->rc2.xkey;
|
||||
unsigned char tmp[128];
|
||||
unsigned T8, TM;
|
||||
int i, bits;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if (keylen < 8 || keylen > 128) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
if (rounds && rounds != 16) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
for (i = 0; i < keylen; i++) {
|
||||
tmp[i] = key[i];
|
||||
}
|
||||
|
||||
/* Phase 1: Expand input key to 128 bytes */
|
||||
if (keylen < 128) {
|
||||
for (i = keylen; i < 128; i++) {
|
||||
tmp[i] = permute[(tmp[i - 1] + tmp[i - keylen]) & 255];
|
||||
}
|
||||
}
|
||||
|
||||
/* Phase 2 - reduce effective key size to "bits" */
|
||||
bits = keylen*8;
|
||||
T8 = (bits+7)>>3;
|
||||
TM = (255 >> (7 & -bits));
|
||||
tmp[128 - T8] = permute[tmp[128 - T8] & TM];
|
||||
for (i = 127 - T8; i >= 0; i--) {
|
||||
tmp[i] = permute[tmp[i + 1] ^ tmp[i + T8]];
|
||||
}
|
||||
|
||||
/* Phase 3 - copy to xkey in little-endian order */
|
||||
i = 63;
|
||||
do {
|
||||
xkey[i] = (unsigned)tmp[2*i] + ((unsigned)tmp[2*i+1] << 8);
|
||||
} while (i--);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(tmp, sizeof(tmp));
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**********************************************************************\
|
||||
* Encrypt an 8-byte block of plaintext using the given key. *
|
||||
\**********************************************************************/
|
||||
#ifdef CLEAN_STACK
|
||||
static void _rc2_ecb_encrypt( const unsigned char *plain,
|
||||
unsigned char *cipher,
|
||||
symmetric_key *skey)
|
||||
#else
|
||||
void rc2_ecb_encrypt( const unsigned char *plain,
|
||||
unsigned char *cipher,
|
||||
symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
unsigned *xkey = skey->rc2.xkey;
|
||||
unsigned x76, x54, x32, x10, i;
|
||||
|
||||
_ARGCHK(plain != NULL);
|
||||
_ARGCHK(cipher != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
x76 = ((unsigned)plain[7] << 8) + (unsigned)plain[6];
|
||||
x54 = ((unsigned)plain[5] << 8) + (unsigned)plain[4];
|
||||
x32 = ((unsigned)plain[3] << 8) + (unsigned)plain[2];
|
||||
x10 = ((unsigned)plain[1] << 8) + (unsigned)plain[0];
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
x10 = (x10 + (x32 & ~x76) + (x54 & x76) + xkey[4*i+0]) & 0xFFFF;
|
||||
x10 = ((x10 << 1) | (x10 >> 15)) & 0xFFFF;
|
||||
|
||||
x32 = (x32 + (x54 & ~x10) + (x76 & x10) + xkey[4*i+1]) & 0xFFFF;
|
||||
x32 = ((x32 << 2) | (x32 >> 14)) & 0xFFFF;
|
||||
|
||||
x54 = (x54 + (x76 & ~x32) + (x10 & x32) + xkey[4*i+2]) & 0xFFFF;
|
||||
x54 = ((x54 << 3) | (x54 >> 13)) & 0xFFFF;
|
||||
|
||||
x76 = (x76 + (x10 & ~x54) + (x32 & x54) + xkey[4*i+3]) & 0xFFFF;
|
||||
x76 = ((x76 << 5) | (x76 >> 11)) & 0xFFFF;
|
||||
|
||||
if (i == 4 || i == 10) {
|
||||
x10 = (x10 + xkey[x76 & 63]) & 0xFFFF;
|
||||
x32 = (x32 + xkey[x10 & 63]) & 0xFFFF;
|
||||
x54 = (x54 + xkey[x32 & 63]) & 0xFFFF;
|
||||
x76 = (x76 + xkey[x54 & 63]) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
cipher[0] = (unsigned char)x10;
|
||||
cipher[1] = (unsigned char)(x10 >> 8);
|
||||
cipher[2] = (unsigned char)x32;
|
||||
cipher[3] = (unsigned char)(x32 >> 8);
|
||||
cipher[4] = (unsigned char)x54;
|
||||
cipher[5] = (unsigned char)(x54 >> 8);
|
||||
cipher[6] = (unsigned char)x76;
|
||||
cipher[7] = (unsigned char)(x76 >> 8);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void rc2_ecb_encrypt( const unsigned char *plain,
|
||||
unsigned char *cipher,
|
||||
symmetric_key *skey)
|
||||
{
|
||||
_rc2_ecb_encrypt(plain, cipher, skey);
|
||||
burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 5);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************\
|
||||
* Decrypt an 8-byte block of ciphertext using the given key. *
|
||||
\**********************************************************************/
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _rc2_ecb_decrypt( const unsigned char *cipher,
|
||||
unsigned char *plain,
|
||||
symmetric_key *skey)
|
||||
#else
|
||||
void rc2_ecb_decrypt( const unsigned char *cipher,
|
||||
unsigned char *plain,
|
||||
symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
unsigned x76, x54, x32, x10;
|
||||
unsigned *xkey = skey->rc2.xkey;
|
||||
int i;
|
||||
|
||||
_ARGCHK(plain != NULL);
|
||||
_ARGCHK(cipher != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
x76 = ((unsigned)cipher[7] << 8) + (unsigned)cipher[6];
|
||||
x54 = ((unsigned)cipher[5] << 8) + (unsigned)cipher[4];
|
||||
x32 = ((unsigned)cipher[3] << 8) + (unsigned)cipher[2];
|
||||
x10 = ((unsigned)cipher[1] << 8) + (unsigned)cipher[0];
|
||||
|
||||
for (i = 15; i >= 0; i--) {
|
||||
if (i == 4 || i == 10) {
|
||||
x76 = (x76 - xkey[x54 & 63]) & 0xFFFF;
|
||||
x54 = (x54 - xkey[x32 & 63]) & 0xFFFF;
|
||||
x32 = (x32 - xkey[x10 & 63]) & 0xFFFF;
|
||||
x10 = (x10 - xkey[x76 & 63]) & 0xFFFF;
|
||||
}
|
||||
|
||||
x76 = ((x76 << 11) | (x76 >> 5)) & 0xFFFF;
|
||||
x76 = (x76 - ((x10 & ~x54) + (x32 & x54) + xkey[4*i+3])) & 0xFFFF;
|
||||
|
||||
x54 = ((x54 << 13) | (x54 >> 3)) & 0xFFFF;
|
||||
x54 = (x54 - ((x76 & ~x32) + (x10 & x32) + xkey[4*i+2])) & 0xFFFF;
|
||||
|
||||
x32 = ((x32 << 14) | (x32 >> 2)) & 0xFFFF;
|
||||
x32 = (x32 - ((x54 & ~x10) + (x76 & x10) + xkey[4*i+1])) & 0xFFFF;
|
||||
|
||||
x10 = ((x10 << 15) | (x10 >> 1)) & 0xFFFF;
|
||||
x10 = (x10 - ((x32 & ~x76) + (x54 & x76) + xkey[4*i+0])) & 0xFFFF;
|
||||
}
|
||||
|
||||
plain[0] = (unsigned char)x10;
|
||||
plain[1] = (unsigned char)(x10 >> 8);
|
||||
plain[2] = (unsigned char)x32;
|
||||
plain[3] = (unsigned char)(x32 >> 8);
|
||||
plain[4] = (unsigned char)x54;
|
||||
plain[5] = (unsigned char)(x54 >> 8);
|
||||
plain[6] = (unsigned char)x76;
|
||||
plain[7] = (unsigned char)(x76 >> 8);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void rc2_ecb_decrypt( const unsigned char *cipher,
|
||||
unsigned char *plain,
|
||||
symmetric_key *skey)
|
||||
{
|
||||
_rc2_ecb_decrypt(cipher, plain, skey);
|
||||
burn_stack(sizeof(unsigned *) + sizeof(unsigned) * 4 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
int rc2_test(void)
|
||||
{
|
||||
static const struct {
|
||||
int keylen;
|
||||
unsigned char key[16], pt[8], ct[8];
|
||||
} tests[] = {
|
||||
|
||||
{ 8,
|
||||
{ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 },
|
||||
{ 0x30, 0x64, 0x9e, 0xdf, 0x9b, 0xe7, 0xd2, 0xc2 }
|
||||
|
||||
},
|
||||
{ 16,
|
||||
{ 0x88, 0xbc, 0xa9, 0x0e, 0x90, 0x87, 0x5a, 0x7f,
|
||||
0x0f, 0x79, 0xc3, 0x84, 0x62, 0x7b, 0xaf, 0xb2 },
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x22, 0x69, 0x55, 0x2a, 0xb0, 0xf8, 0x5c, 0xa6 }
|
||||
}
|
||||
};
|
||||
int x, failed, errno;
|
||||
symmetric_key skey;
|
||||
unsigned char buf[2][8];
|
||||
|
||||
failed = 0;
|
||||
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
|
||||
zeromem(buf, sizeof(buf));
|
||||
if ((errno = rc2_setup(tests[x].key, tests[x].keylen, 0, &skey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
rc2_ecb_encrypt(tests[x].pt, buf[0], &skey);
|
||||
rc2_ecb_decrypt(buf[0], buf[1], &skey);
|
||||
|
||||
if (memcmp(buf[0], tests[x].ct, 8)) {
|
||||
#if 0
|
||||
int y;
|
||||
printf("\nTest %d failed to encrypt\n", x);
|
||||
for (y = 0; y < 8; y++) {
|
||||
printf("%02x ", buf[0][y]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
if (memcmp(buf[1], tests[x].pt, 8)) {
|
||||
#if 0
|
||||
int y;
|
||||
printf("\nTest %d failed to decrypt\n", x);
|
||||
for (y = 0; y < 8; y++) {
|
||||
printf("%02x ", buf[1][y]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int rc2_keysize(int *keysize)
|
||||
{
|
||||
_ARGCHK(keysize != NULL);
|
||||
if (*keysize < 8) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
} else if (*keysize > 128) {
|
||||
*keysize = 128;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
97
rc4.c
Normal file
97
rc4.c
Normal file
@ -0,0 +1,97 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef RC4
|
||||
|
||||
const struct _prng_descriptor rc4_desc =
|
||||
{
|
||||
"rc4",
|
||||
&rc4_start,
|
||||
&rc4_add_entropy,
|
||||
&rc4_ready,
|
||||
&rc4_read
|
||||
};
|
||||
|
||||
int rc4_start(prng_state *prng)
|
||||
{
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
/* set keysize to zero */
|
||||
prng->rc4.x = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
|
||||
{
|
||||
_ARGCHK(buf != NULL);
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
if (prng->rc4.x + len > 256) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
while (len--) {
|
||||
prng->rc4.buf[prng->rc4.x++] = *buf++;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
}
|
||||
|
||||
int rc4_ready(prng_state *prng)
|
||||
{
|
||||
unsigned char key[256], tmp;
|
||||
int keylen, x, y;
|
||||
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
/* extract the key */
|
||||
memcpy(key, prng->rc4.buf, 256);
|
||||
keylen = prng->rc4.x;
|
||||
|
||||
/* make RC4 perm and shuffle */
|
||||
for (x = 0; x < 256; x++) {
|
||||
prng->rc4.buf[x] = x;
|
||||
}
|
||||
|
||||
for (x = y = 0; x < 256; x++) {
|
||||
y = (y + prng->rc4.buf[x] + key[x % keylen]) & 255;
|
||||
tmp = prng->rc4.buf[x]; prng->rc4.buf[x] = prng->rc4.buf[y]; prng->rc4.buf[y] = tmp;
|
||||
}
|
||||
prng->rc4.x = x;
|
||||
prng->rc4.y = y;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(key, sizeof(key));
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char *s, tmp;
|
||||
unsigned long n;
|
||||
|
||||
_ARGCHK(buf != NULL);
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
n = len;
|
||||
x = prng->rc4.x;
|
||||
y = prng->rc4.y;
|
||||
s = prng->rc4.buf;
|
||||
while (len--) {
|
||||
x = (x + 1) & 255;
|
||||
y = (y + s[x]) & 255;
|
||||
tmp = s[x]; s[x] = s[y]; s[y] = tmp;
|
||||
tmp = (s[x] + s[y]) & 255;
|
||||
*buf++ ^= s[tmp];
|
||||
}
|
||||
prng->rc4.x = x;
|
||||
prng->rc4.y = y;
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
234
rc5.c
Normal file
234
rc5.c
Normal file
@ -0,0 +1,234 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef RC5
|
||||
|
||||
const struct _cipher_descriptor rc5_desc =
|
||||
{
|
||||
"rc5",
|
||||
2,
|
||||
8, 128, 8, 12,
|
||||
&rc5_setup,
|
||||
&rc5_ecb_encrypt,
|
||||
&rc5_ecb_decrypt,
|
||||
&rc5_test,
|
||||
&rc5_keysize
|
||||
};
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static int _rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
#else
|
||||
int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
unsigned long L[64], S[50], A, B, i, j, v, s, t, l;
|
||||
|
||||
_ARGCHK(skey != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* test parameters */
|
||||
if (num_rounds == 0) {
|
||||
num_rounds = rc5_desc.default_rounds;
|
||||
}
|
||||
|
||||
if (num_rounds < 12 || num_rounds > 24) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
/* key must be between 64 and 1024 bits */
|
||||
if (keylen < 8 || keylen > 128) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
/* copy the key into the L array */
|
||||
for (A = i = j = 0; i < (unsigned long)keylen; ) {
|
||||
A = (A << 8) | ((unsigned long)(key[i++] & 255));
|
||||
if (!(i & 3)) {
|
||||
L[j++] = BSWAP(A);
|
||||
A = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (keylen & 3) {
|
||||
A <<= (8 * (4 - (keylen&3)));
|
||||
L[j++] = BSWAP(A);
|
||||
}
|
||||
|
||||
/* setup the S array */
|
||||
t = 2 * (num_rounds + 1);
|
||||
S[0] = 0xB7E15163UL;
|
||||
for (i = 1; i < t; i++) S[i] = S[i - 1] + 0x9E3779B9UL;
|
||||
|
||||
/* mix buffer */
|
||||
s = 3 * MAX(t, j);
|
||||
l = j;
|
||||
for (A = B = i = j = v = 0; v < s; v++) {
|
||||
A = S[i] = ROL(S[i] + A + B, 3);
|
||||
B = L[j] = ROL(L[j] + A + B, (A+B));
|
||||
i = (i + 1) % t;
|
||||
j = (j + 1) % l;
|
||||
}
|
||||
|
||||
/* copy to key */
|
||||
for (i = 0; i < t; i++) {
|
||||
skey->rc5.K[i] = S[i];
|
||||
}
|
||||
skey->rc5.rounds = num_rounds;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
{
|
||||
int x;
|
||||
x = _rc5_setup(key, keylen, num_rounds, skey);
|
||||
burn_stack(sizeof(unsigned long) * 122 + sizeof(int));
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#else
|
||||
void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
unsigned long A, B;
|
||||
int r;
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
|
||||
LOAD32L(A, &pt[0]);
|
||||
LOAD32L(B, &pt[4]);
|
||||
A += key->rc5.K[0];
|
||||
B += key->rc5.K[1];
|
||||
for (r = 0; r < key->rc5.rounds; r++) {
|
||||
A = ROL(A ^ B, B) + key->rc5.K[r+r+2];
|
||||
B = ROL(B ^ A, A) + key->rc5.K[r+r+3];
|
||||
}
|
||||
STORE32L(A, &ct[0]);
|
||||
STORE32L(B, &ct[4]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
{
|
||||
_rc5_ecb_encrypt(pt, ct, key);
|
||||
burn_stack(sizeof(unsigned long) * 2 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#else
|
||||
void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
unsigned long A, B;
|
||||
int r;
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
|
||||
LOAD32L(A, &ct[0]);
|
||||
LOAD32L(B, &ct[4]);
|
||||
for (r = key->rc5.rounds - 1; r >= 0; r--) {
|
||||
B = ROR(B - key->rc5.K[r+r+3], A) ^ A;
|
||||
A = ROR(A - key->rc5.K[r+r+2], B) ^ B;
|
||||
}
|
||||
A -= key->rc5.K[0];
|
||||
B -= key->rc5.K[1];
|
||||
STORE32L(A, &pt[0]);
|
||||
STORE32L(B, &pt[4]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
{
|
||||
_rc5_ecb_decrypt(ct, pt, key);
|
||||
burn_stack(sizeof(unsigned long) * 2 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
int rc5_test(void)
|
||||
{
|
||||
static const struct {
|
||||
unsigned char key[16], pt[8], ct[8];
|
||||
} tests[] = {
|
||||
{
|
||||
{ 0x91, 0x5f, 0x46, 0x19, 0xbe, 0x41, 0xb2, 0x51,
|
||||
0x63, 0x55, 0xa5, 0x01, 0x10, 0xa9, 0xce, 0x91 },
|
||||
{ 0x21, 0xa5, 0xdb, 0xee, 0x15, 0x4b, 0x8f, 0x6d },
|
||||
{ 0xf7, 0xc0, 0x13, 0xac, 0x5b, 0x2b, 0x89, 0x52 }
|
||||
},
|
||||
{
|
||||
{ 0x78, 0x33, 0x48, 0xe7, 0x5a, 0xeb, 0x0f, 0x2f,
|
||||
0xd7, 0xb1, 0x69, 0xbb, 0x8d, 0xc1, 0x67, 0x87 },
|
||||
{ 0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52 },
|
||||
{ 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 }
|
||||
},
|
||||
{
|
||||
{ 0xDC, 0x49, 0xdb, 0x13, 0x75, 0xa5, 0x58, 0x4f,
|
||||
0x64, 0x85, 0xb4, 0x13, 0xb5, 0xf1, 0x2b, 0xaf },
|
||||
{ 0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92 },
|
||||
{ 0x65, 0xc1, 0x78, 0xb2, 0x84, 0xd1, 0x97, 0xcc }
|
||||
}
|
||||
};
|
||||
unsigned char buf[2][8];
|
||||
int x, failed, errno;
|
||||
symmetric_key key;
|
||||
|
||||
for (x = failed = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
|
||||
/* setup key */
|
||||
if ((errno = rc5_setup(tests[x].key, 16, 12, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* encrypt and decrypt */
|
||||
rc5_ecb_encrypt(tests[x].pt, buf[0], &key);
|
||||
rc5_ecb_decrypt(buf[0], buf[1], &key);
|
||||
|
||||
/* compare */
|
||||
if (memcmp(buf[0], tests[x].ct, 8)) {
|
||||
#if 0
|
||||
int y;
|
||||
printf("\nEncrypt test %d failed\n", x);
|
||||
for (y = 0; y < 8; y++) printf("%02x ", buf[0][y]);
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
if (memcmp(buf[1], tests[x].pt, 8)) {
|
||||
#if 0
|
||||
int y;
|
||||
printf("\nDecrypt test %d failed\n", x);
|
||||
for (y = 0; y < 8; y++) printf("%02x ", buf[1][y]);
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int rc5_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
if (*desired_keysize < 8) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
} else if (*desired_keysize > 128) {
|
||||
*desired_keysize = 128;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
253
rc6.c
Normal file
253
rc6.c
Normal file
@ -0,0 +1,253 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef RC6
|
||||
|
||||
const struct _cipher_descriptor rc6_desc =
|
||||
{
|
||||
"rc6",
|
||||
3,
|
||||
8, 128, 16, 20,
|
||||
&rc6_setup,
|
||||
&rc6_ecb_encrypt,
|
||||
&rc6_ecb_decrypt,
|
||||
&rc6_test,
|
||||
&rc6_keysize
|
||||
};
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static int _rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
#else
|
||||
int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
unsigned long L[64], S[50], A, B, i, j, v, s, t, l;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
/* test parameters */
|
||||
if (num_rounds != 0 && num_rounds != 20) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
/* key must be between 64 and 1024 bits */
|
||||
if (keylen < 8 || keylen > 128) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
/* copy the key into the L array */
|
||||
for (A = i = j = 0; i < (unsigned long)keylen; ) {
|
||||
A = (A << 8) | ((unsigned long)(key[i++] & 255));
|
||||
if (!(i & 3)) {
|
||||
L[j++] = BSWAP(A);
|
||||
A = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle odd sized keys */
|
||||
if (keylen & 3) {
|
||||
A <<= (8 * (4 - (keylen&3)));
|
||||
L[j++] = BSWAP(A);
|
||||
}
|
||||
|
||||
/* setup the S array */
|
||||
t = 44; /* fixed at 20 rounds */
|
||||
S[0] = 0xB7E15163UL;
|
||||
for (i = 1; i < t; i++)
|
||||
S[i] = S[i - 1] + 0x9E3779B9UL;
|
||||
|
||||
/* mix buffer */
|
||||
s = 3 * MAX(t, j);
|
||||
l = j;
|
||||
for (A = B = i = j = v = 0; v < s; v++) {
|
||||
A = S[i] = ROL(S[i] + A + B, 3);
|
||||
B = L[j] = ROL(L[j] + A + B, (A+B));
|
||||
i = (i + 1) % t;
|
||||
j = (j + 1) % l;
|
||||
}
|
||||
|
||||
/* copy to key */
|
||||
for (i = 0; i < t; i++) {
|
||||
skey->rc6.K[i] = S[i];
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
{
|
||||
int x;
|
||||
x = _rc6_setup(key, keylen, num_rounds, skey);
|
||||
burn_stack(sizeof(unsigned long) * 122);
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#else
|
||||
void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
unsigned long a,b,c,d,t,u;
|
||||
int r;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
LOAD32L(a,&pt[0]);LOAD32L(b,&pt[4]);LOAD32L(c,&pt[8]);LOAD32L(d,&pt[12]);
|
||||
b += key->rc6.K[0];
|
||||
d += key->rc6.K[1];
|
||||
for (r = 0; r < 20; r++) {
|
||||
t = (b * (b + b + 1)); t = ROL(t, 5);
|
||||
u = (d * (d + d + 1)); u = ROL(u, 5);
|
||||
a = ROL(a^t,u) + key->rc6.K[r+r+2];
|
||||
c = ROL(c^u,t) + key->rc6.K[r+r+3];
|
||||
t = a; a = b; b = c; c = d; d = t;
|
||||
}
|
||||
a += key->rc6.K[42];
|
||||
c += key->rc6.K[43];
|
||||
STORE32L(a,&ct[0]);STORE32L(b,&ct[4]);STORE32L(c,&ct[8]);STORE32L(d,&ct[12]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
{
|
||||
_rc6_ecb_encrypt(pt, ct, key);
|
||||
burn_stack(sizeof(unsigned long) * 6 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#else
|
||||
void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
unsigned long a,b,c,d,t,u;
|
||||
int r;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
|
||||
LOAD32L(a,&ct[0]);LOAD32L(b,&ct[4]);LOAD32L(c,&ct[8]);LOAD32L(d,&ct[12]);
|
||||
a -= key->rc6.K[42];
|
||||
c -= key->rc6.K[43];
|
||||
for (r = 19; r >= 0; r--) {
|
||||
t = d; d = c; c = b; b = a; a = t;
|
||||
t = (b * (b + b + 1)); t = ROL(t, 5);
|
||||
u = (d * (d + d + 1)); u = ROL(u, 5);
|
||||
c = ROR(c - key->rc6.K[r+r+3], t) ^ u;
|
||||
a = ROR(a - key->rc6.K[r+r+2], u) ^ t;
|
||||
}
|
||||
b -= key->rc6.K[0];
|
||||
d -= key->rc6.K[1];
|
||||
STORE32L(a,&pt[0]);STORE32L(b,&pt[4]);STORE32L(c,&pt[8]);STORE32L(d,&pt[12]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
{
|
||||
_rc6_ecb_decrypt(ct, pt, key);
|
||||
burn_stack(sizeof(unsigned long) * 6 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
int rc6_test(void)
|
||||
{
|
||||
static const struct {
|
||||
int keylen;
|
||||
unsigned char key[32], pt[16], ct[16];
|
||||
} tests[] = {
|
||||
{
|
||||
16,
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
|
||||
0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
|
||||
0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
|
||||
{ 0x52, 0x4e, 0x19, 0x2f, 0x47, 0x15, 0xc6, 0x23,
|
||||
0x1f, 0x51, 0xf6, 0x36, 0x7e, 0xa4, 0x3f, 0x18 }
|
||||
},
|
||||
{
|
||||
24,
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
|
||||
0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
|
||||
0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
|
||||
{ 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
|
||||
0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
|
||||
{ 0x68, 0x83, 0x29, 0xd0, 0x19, 0xe5, 0x05, 0x04,
|
||||
0x1e, 0x52, 0xe9, 0x2a, 0xf9, 0x52, 0x91, 0xd4 }
|
||||
},
|
||||
{
|
||||
32,
|
||||
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
|
||||
0x01, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
|
||||
0x89, 0x9a, 0xab, 0xbc, 0xcd, 0xde, 0xef, 0xf0,
|
||||
0x10, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe },
|
||||
{ 0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
|
||||
0x8a, 0x9b, 0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1 },
|
||||
{ 0xc8, 0x24, 0x18, 0x16, 0xf0, 0xd7, 0xe4, 0x89,
|
||||
0x20, 0xad, 0x16, 0xa1, 0x67, 0x4e, 0x5d, 0x48 }
|
||||
}
|
||||
};
|
||||
unsigned char buf[2][16];
|
||||
int x, failed, errno;
|
||||
symmetric_key key;
|
||||
|
||||
for (x = failed = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
|
||||
/* setup key */
|
||||
if ((errno = rc6_setup(tests[x].key, tests[x].keylen, 0, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* encrypt and decrypt */
|
||||
rc6_ecb_encrypt(tests[x].pt, buf[0], &key);
|
||||
rc6_ecb_decrypt(buf[0], buf[1], &key);
|
||||
|
||||
/* compare */
|
||||
if (memcmp(buf[0], tests[x].ct, 16)) {
|
||||
#if 0
|
||||
int y;
|
||||
printf("\nEncrypt test %d failed\n", x);
|
||||
for (y = 0; y < 16; y++) printf("%02x ", buf[0][y]);
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
if (memcmp(buf[1], tests[x].pt, 16)) {
|
||||
#if 0
|
||||
int y;
|
||||
printf("\nDecrypt test %d failed\n", x);
|
||||
for (y = 0; y < 16; y++) printf("%02x ", buf[1][y]);
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int rc6_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
if (*desired_keysize < 8) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
} else if (*desired_keysize > 128) {
|
||||
*desired_keysize = 128;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif /*RC6*/
|
||||
|
||||
|
436
rsa.c
Normal file
436
rsa.c
Normal file
@ -0,0 +1,436 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef MRSA
|
||||
|
||||
int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
|
||||
{
|
||||
mp_int p, q, tmp1, tmp2, tmp3;
|
||||
int res, errno;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
if ((size < (1024/8)) || (size > (4096/8))) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
if ((e < 3) || (!(e & 1))) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if (mp_init_multi(&p, &q, &tmp1, &tmp2, &tmp3, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* make primes p and q (optimization provided by Wayne Scott) */
|
||||
if (mp_set_int(&tmp3, e) != MP_OKAY) { goto error; } /* tmp3 = e */
|
||||
|
||||
/* make prime "p" */
|
||||
do {
|
||||
if (rand_prime(&p, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
|
||||
if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = p-1 */
|
||||
if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = gcd(p-1, e) */
|
||||
} while (mp_cmp_d(&tmp2, 1) != 0);
|
||||
|
||||
/* make prime "q" */
|
||||
do {
|
||||
if (rand_prime(&q, size/2, prng, wprng) != CRYPT_OK) { res = CRYPT_ERROR; goto done; }
|
||||
if (mp_sub_d(&q, 1, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = q-1 */
|
||||
if (mp_gcd(&tmp1, &tmp3, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = gcd(q-1, e) */
|
||||
} while (mp_cmp_d(&tmp2, 1) != 0);
|
||||
|
||||
/* tmp1 = lcm(p-1, q-1) */
|
||||
if (mp_sub_d(&p, 1, &tmp2) != MP_OKAY) { goto error; } /* tmp2 = p-1 */
|
||||
/* tmp1 = q-1 (previous do/while loop) */
|
||||
if (mp_lcm(&tmp1, &tmp2, &tmp1) != MP_OKAY) { goto error; } /* tmp1 = lcm(p-1, q-1) */
|
||||
|
||||
/* make key */
|
||||
if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
|
||||
&key->qP, &key->pQ, &key->p, &key->q, NULL) != MP_OKAY) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
mp_set_int(&key->e, e); /* key->e = e */
|
||||
if (mp_invmod(&key->e, &tmp1, &key->d) != MP_OKAY) goto error2; /* key->d = 1/e mod lcm(p-1,q-1) */
|
||||
if (mp_mul(&p, &q, &key->N) != MP_OKAY) goto error2; /* key->N = pq */
|
||||
|
||||
/* optimize for CRT now */
|
||||
/* find d mod q-1 and d mod p-1 */
|
||||
if (mp_sub_d(&p, 1, &tmp1) != MP_OKAY) { goto error2; } /* tmp1 = q-1 */
|
||||
if (mp_sub_d(&q, 1, &tmp2) != MP_OKAY) { goto error2; } /* tmp2 = p-1 */
|
||||
|
||||
if (mp_mod(&key->d, &tmp1, &key->dP) != MP_OKAY) { goto error2; } /* dP = d mod p-1 */
|
||||
if (mp_mod(&key->d, &tmp2, &key->dQ) != MP_OKAY) { goto error2; } /* dQ = d mod q-1 */
|
||||
|
||||
if (mp_invmod(&q, &p, &key->qP) != MP_OKAY) { goto error2; } /* qP = 1/q mod p */
|
||||
if (mp_mulmod(&key->qP, &q, &key->N, &key->qP)) { goto error2; } /* qP = q * (1/q mod p) mod N */
|
||||
|
||||
if (mp_invmod(&p, &q, &key->pQ) != MP_OKAY) { goto error2; } /* pQ = 1/p mod q */
|
||||
if (mp_mulmod(&key->pQ, &p, &key->N, &key->pQ)) { goto error2; } /* pQ = p * (1/p mod q) mod N */
|
||||
|
||||
if (mp_copy(&p, &key->p) != MP_OKAY) { goto error2; }
|
||||
if (mp_copy(&q, &key->q) != MP_OKAY) { goto error2; }
|
||||
|
||||
res = CRYPT_OK;
|
||||
key->type = PK_PRIVATE_OPTIMIZED;
|
||||
goto done;
|
||||
error2:
|
||||
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
|
||||
&key->qP, &key->pQ, &key->p, &key->q, NULL);
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&tmp3, &tmp2, &tmp1, &p, &q, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
void rsa_free(rsa_key *key)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
mp_clear_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP,
|
||||
&key->qP, &key->pQ, &key->p, &key->q, NULL);
|
||||
}
|
||||
|
||||
int rsa_exptmod(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int which,
|
||||
rsa_key *key)
|
||||
{
|
||||
mp_int tmp, tmpa, tmpb;
|
||||
unsigned long x;
|
||||
int res;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* init and copy into tmp */
|
||||
if (mp_init_multi(&tmp, &tmpa, &tmpb, NULL) != MP_OKAY) { goto error; }
|
||||
if (mp_read_unsigned_bin(&tmp, (unsigned char *)in, inlen) != MP_OKAY) { goto error; }
|
||||
|
||||
/* sanity check on the input */
|
||||
if (mp_cmp(&key->N, &tmp) == MP_LT) {
|
||||
res = CRYPT_PK_INVALID_SIZE;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* are we using the private exponent and is the key optimized? */
|
||||
if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) {
|
||||
/* tmpa = tmp^dP mod p */
|
||||
if (mp_exptmod(&tmp, &key->dP, &key->p, &tmpa) != MP_OKAY) { goto error; }
|
||||
|
||||
/* tmpb = tmp^dQ mod q */
|
||||
if (mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb) != MP_OKAY) { goto error; }
|
||||
|
||||
/* tmp = tmpa*qP + tmpb*pQ mod N */
|
||||
if (mp_mul(&tmpa, &key->qP, &tmpa) != MP_OKAY) { goto error; }
|
||||
if (mp_mul(&tmpb, &key->pQ, &tmpb) != MP_OKAY) { goto error; }
|
||||
if (mp_addmod(&tmpa, &tmpb, &key->N, &tmp) != MP_OKAY) { goto error; }
|
||||
} else {
|
||||
/* exptmod it */
|
||||
if (mp_exptmod(&tmp, which==PK_PRIVATE?&key->d:&key->e, &key->N, &tmp) != MP_OKAY) { goto error; }
|
||||
}
|
||||
|
||||
/* read it back */
|
||||
x = mp_raw_size(&tmp)-1;
|
||||
if (x > *outlen) {
|
||||
res = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
*outlen = x;
|
||||
|
||||
/* convert it */
|
||||
mp_to_unsigned_bin(&tmp, out);
|
||||
|
||||
/* clean up and return */
|
||||
res = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
res = CRYPT_MEM;
|
||||
done:
|
||||
mp_clear_multi(&tmp, &tmpa, &tmpb, NULL);
|
||||
return res;
|
||||
}
|
||||
|
||||
int rsa_signpad(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x, y;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
if (*outlen < (3 * inlen)) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* check inlen */
|
||||
if ((inlen <= 0) || inlen > 512) {
|
||||
return CRYPT_PK_INVALID_SIZE;
|
||||
}
|
||||
|
||||
for (y = x = 0; x < inlen; x++)
|
||||
out[y++] = 0xFF;
|
||||
for (x = 0; x < inlen; x++)
|
||||
out[y++] = in[x];
|
||||
for (x = 0; x < inlen; x++)
|
||||
out[y++] = 0xFF;
|
||||
*outlen = 3 * inlen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_pad(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
int wprng, prng_state *prng)
|
||||
{
|
||||
unsigned char buf[2048];
|
||||
unsigned long x;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* is output big enough? */
|
||||
if (*outlen < (3 * inlen)) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* get random padding required */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* check inlen */
|
||||
if ((inlen <= 0) || inlen > 512) {
|
||||
return CRYPT_PK_INVALID_SIZE;
|
||||
}
|
||||
|
||||
if (prng_descriptor[wprng].read(buf, inlen*2-2, prng) != (inlen*2 - 2)) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* pad it like a sandwitch (sp?)
|
||||
*
|
||||
* Looks like 0xFF R1 M R2 0xFF
|
||||
*
|
||||
* Where R1/R2 are random and exactly equal to the length of M minus one byte.
|
||||
*/
|
||||
for (x = 0; x < inlen-1; x++) {
|
||||
out[x+1] = buf[x];
|
||||
}
|
||||
|
||||
for (x = 0; x < inlen; x++) {
|
||||
out[x+inlen] = in[x];
|
||||
}
|
||||
|
||||
for (x = 0; x < inlen-1; x++) {
|
||||
out[x+inlen+inlen] = buf[x+inlen-1];
|
||||
}
|
||||
|
||||
/* last and first bytes are 0xFF */
|
||||
out[0] = 0xFF;
|
||||
out[inlen+inlen+inlen-1] = 0xFF;
|
||||
|
||||
/* clear up and return */
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
*outlen = inlen*3;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_signdepad(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
if (*outlen < inlen/3) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* check padding bytes */
|
||||
for (x = 0; x < inlen/3; x++) {
|
||||
if (in[x] != 0xFF || in[x+(inlen/3)+(inlen/3)] != 0xFF) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
}
|
||||
for (x = 0; x < inlen/3; x++)
|
||||
out[x] = in[x+(inlen/3)];
|
||||
*outlen = inlen/3;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_depad(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
if (*outlen < inlen/3) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
for (x = 0; x < inlen/3; x++)
|
||||
out[x] = in[x+(inlen/3)];
|
||||
*outlen = inlen/3;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#define OUTPUT_BIGNUM(num, buf2, y, z) \
|
||||
{ \
|
||||
z = mp_raw_size(num); \
|
||||
STORE32L(z, buf2+y); \
|
||||
y += 4; \
|
||||
mp_toraw(num, buf2+y); \
|
||||
y += z; \
|
||||
}
|
||||
|
||||
|
||||
#define INPUT_BIGNUM(num, in, x, y) \
|
||||
{ \
|
||||
/* load value */ \
|
||||
LOAD32L(x, in+y); \
|
||||
y += 4; \
|
||||
\
|
||||
/* sanity check... */ \
|
||||
if (x > 1024) { \
|
||||
goto error2; \
|
||||
} \
|
||||
\
|
||||
/* load it */ \
|
||||
if (mp_read_raw(num, (unsigned char *)in+y, x) != MP_OKAY) {\
|
||||
goto error2; \
|
||||
} \
|
||||
y += x; \
|
||||
}
|
||||
|
||||
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
|
||||
{
|
||||
unsigned char buf2[5120];
|
||||
unsigned long y, z;
|
||||
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* type valid? */
|
||||
if (!(key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) &&
|
||||
(type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED)) {
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
/* start at offset y=PACKET_SIZE */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* output key type */
|
||||
buf2[y++] = type;
|
||||
|
||||
/* output modulus */
|
||||
OUTPUT_BIGNUM(&key->N, buf2, y, z);
|
||||
|
||||
/* output public key */
|
||||
OUTPUT_BIGNUM(&key->e, buf2, y, z);
|
||||
|
||||
if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) {
|
||||
OUTPUT_BIGNUM(&key->d, buf2, y, z);
|
||||
}
|
||||
|
||||
if (type == PK_PRIVATE_OPTIMIZED) {
|
||||
OUTPUT_BIGNUM(&key->dQ, buf2, y, z);
|
||||
OUTPUT_BIGNUM(&key->dP, buf2, y, z);
|
||||
OUTPUT_BIGNUM(&key->pQ, buf2, y, z);
|
||||
OUTPUT_BIGNUM(&key->qP, buf2, y, z);
|
||||
OUTPUT_BIGNUM(&key->p, buf2, y, z);
|
||||
OUTPUT_BIGNUM(&key->q, buf2, y, z);
|
||||
}
|
||||
|
||||
/* check size */
|
||||
if (*outlen < y) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* store packet header */
|
||||
packet_store_header(buf2, PACKET_SECT_RSA, PACKET_SUB_KEY, y);
|
||||
|
||||
/* copy to the user buffer */
|
||||
memcpy(out, buf2, y);
|
||||
*outlen = y;
|
||||
|
||||
/* clear stack and return */
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf2, sizeof(buf2));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_import(const unsigned char *in, rsa_key *key)
|
||||
{
|
||||
unsigned long x, y;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* test packet header */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* init key */
|
||||
if (mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP,
|
||||
&key->pQ, &key->p, &key->q, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* get key type */
|
||||
y = PACKET_SIZE;
|
||||
key->type = in[y++];
|
||||
|
||||
/* load the modulus */
|
||||
INPUT_BIGNUM(&key->N, in, x, y);
|
||||
|
||||
/* load public exponent */
|
||||
INPUT_BIGNUM(&key->e, in, x, y);
|
||||
|
||||
/* get private exponent */
|
||||
if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) {
|
||||
INPUT_BIGNUM(&key->d, in, x, y);
|
||||
}
|
||||
|
||||
/* get CRT private data if required */
|
||||
if (key->type == PK_PRIVATE_OPTIMIZED) {
|
||||
INPUT_BIGNUM(&key->dQ, in, x, y);
|
||||
INPUT_BIGNUM(&key->dP, in, x, y);
|
||||
INPUT_BIGNUM(&key->pQ, in, x, y);
|
||||
INPUT_BIGNUM(&key->qP, in, x, y);
|
||||
INPUT_BIGNUM(&key->p, in, x, y);
|
||||
INPUT_BIGNUM(&key->q, in, x, y);
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
error2:
|
||||
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
|
||||
&key->pQ, &key->qP, &key->p, &key->q, NULL);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
#include "rsa_sys.c"
|
||||
|
||||
#endif /* RSA */
|
||||
|
||||
|
584
rsa_sys.c
Normal file
584
rsa_sys.c
Normal file
@ -0,0 +1,584 @@
|
||||
#ifdef PK_PACKET
|
||||
|
||||
int rsa_encrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int cipher,
|
||||
rsa_key *key)
|
||||
{
|
||||
unsigned char sym_IV[MAXBLOCKSIZE], sym_key[MAXBLOCKSIZE], rsa_in[4096], rsa_out[4096];
|
||||
symmetric_CTR ctr;
|
||||
unsigned long x, y, blklen, rsa_size;
|
||||
int keylen, errno;;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* are the parameters valid? */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* setup the CTR key */
|
||||
keylen = 32; /* default to 256-bit keys */
|
||||
if ((errno = cipher_descriptor[cipher].keysize(&keylen)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
blklen = cipher_descriptor[cipher].block_length;
|
||||
if (prng_descriptor[wprng].read(sym_key, keylen, prng) != (unsigned long)keylen) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
if (prng_descriptor[wprng].read(sym_IV, blklen, prng) != blklen) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* setup CTR mode */
|
||||
if ((errno = ctr_start(cipher, sym_IV, sym_key, keylen, 0, &ctr)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* rsa_pad the symmetric key */
|
||||
y = sizeof(rsa_in);
|
||||
if ((errno = rsa_pad(sym_key, keylen, rsa_in, &y, wprng, prng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* rsa encrypt it */
|
||||
rsa_size = sizeof(rsa_out);
|
||||
if ((errno = rsa_exptmod(rsa_in, y, rsa_out, &rsa_size, PK_PUBLIC, key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* check size */
|
||||
if (*outlen < (PACKET_SIZE+9+rsa_size+blklen+len)) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* now lets make the header */
|
||||
y = PACKET_SIZE;
|
||||
out[y++] = cipher_descriptor[cipher].ID;
|
||||
|
||||
/* store the size of the RSA value */
|
||||
STORE32L(rsa_size, (out+y));
|
||||
y += 4;
|
||||
|
||||
/* store the rsa value */
|
||||
for (x = 0; x < rsa_size; x++, y++) {
|
||||
out[y] = rsa_out[x];
|
||||
}
|
||||
|
||||
/* store the IV used */
|
||||
for (x = 0; x < blklen; x++, y++) {
|
||||
out[y] = sym_IV[x];
|
||||
}
|
||||
|
||||
/* store the length */
|
||||
STORE32L(len, (out+y));
|
||||
y += 4;
|
||||
|
||||
/* encrypt the message */
|
||||
if ((errno = ctr_encrypt(in, out+y, len, &ctr)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
y += len;
|
||||
|
||||
/* store the header */
|
||||
packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_ENCRYPTED, y);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(sym_key, sizeof(sym_key));
|
||||
zeromem(sym_IV, sizeof(sym_IV));
|
||||
zeromem(&ctr, sizeof(ctr));
|
||||
zeromem(rsa_in, sizeof(rsa_in));
|
||||
zeromem(rsa_out, sizeof(rsa_out));
|
||||
#endif
|
||||
|
||||
*outlen = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_decrypt(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
rsa_key *key)
|
||||
{
|
||||
unsigned char sym_IV[MAXBLOCKSIZE], sym_key[MAXBLOCKSIZE], rsa_in[4096], rsa_out[4096];
|
||||
symmetric_CTR ctr;
|
||||
unsigned long x, y, z, keylen, blklen, rsa_size;
|
||||
int cipher, errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* check the header */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_ENCRYPTED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* grab cipher name */
|
||||
y = PACKET_SIZE;
|
||||
cipher = find_cipher_id(in[y++]);
|
||||
if (cipher == -1) {
|
||||
return CRYPT_INVALID_CIPHER;
|
||||
}
|
||||
keylen = MIN(cipher_descriptor[cipher].max_key_length, 32);
|
||||
blklen = cipher_descriptor[cipher].block_length;
|
||||
|
||||
/* grab length of the rsa key */
|
||||
LOAD32L(rsa_size, (in+y))
|
||||
y += 4;
|
||||
|
||||
/* read it in */
|
||||
for (x = 0; x < rsa_size; x++, y++) {
|
||||
rsa_in[x] = in[y];
|
||||
}
|
||||
|
||||
/* decrypt it */
|
||||
x = sizeof(rsa_out);
|
||||
if ((errno = rsa_exptmod(rsa_in, rsa_size, rsa_out, &x, PK_PRIVATE, key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* depad it */
|
||||
z = sizeof(sym_key);
|
||||
if ((errno = rsa_depad(rsa_out, x, sym_key, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* read the IV in */
|
||||
for (x = 0; x < blklen; x++, y++) {
|
||||
sym_IV[x] = in[y];
|
||||
}
|
||||
|
||||
/* setup CTR mode */
|
||||
if ((errno = ctr_start(cipher, sym_IV, sym_key, keylen, 0, &ctr)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* get len */
|
||||
LOAD32L(len, (in+y));
|
||||
y += 4;
|
||||
|
||||
/* check size */
|
||||
if (*outlen < len) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* decrypt the message */
|
||||
if ((errno = ctr_decrypt(in+y, out, len, &ctr)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(sym_key, sizeof(sym_key));
|
||||
zeromem(sym_IV, sizeof(sym_IV));
|
||||
zeromem(&ctr, sizeof(ctr));
|
||||
zeromem(rsa_in, sizeof(rsa_in));
|
||||
zeromem(rsa_out, sizeof(rsa_out));
|
||||
#endif
|
||||
*outlen = len;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* Signature Message Format
|
||||
offset | length | Contents
|
||||
----------------------------------------------------------------------
|
||||
0 | 1 | hash ID
|
||||
1 | 4 | length of rsa_pad'ed signature
|
||||
5 | p | the rsa_pad'ed signature
|
||||
*/
|
||||
|
||||
int rsa_sign(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
int hash, rsa_key *key)
|
||||
{
|
||||
unsigned long hashlen, rsa_size, x, y, z;
|
||||
unsigned char rsa_in[4096], rsa_out[4096];
|
||||
int errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* type of key? */
|
||||
if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* are the parameters valid? */
|
||||
if ((errno = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* hash it */
|
||||
hashlen = hash_descriptor[hash].hashsize;
|
||||
z = sizeof(rsa_in);
|
||||
if ((errno = hash_memory(hash, in, inlen, rsa_in, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* pad it */
|
||||
x = sizeof(rsa_in);
|
||||
if ((errno = rsa_signpad(rsa_in, hashlen, rsa_out, &x)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* sign it */
|
||||
rsa_size = sizeof(rsa_in);
|
||||
if ((errno = rsa_exptmod(rsa_out, x, rsa_in, &rsa_size, PK_PRIVATE, key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* check size */
|
||||
if (*outlen < (PACKET_SIZE+4+rsa_size)) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* now lets output the message */
|
||||
y = PACKET_SIZE;
|
||||
out[y++] = hash_descriptor[hash].ID;
|
||||
|
||||
/* output the len */
|
||||
STORE32L(rsa_size, (out+y));
|
||||
y += 4;
|
||||
|
||||
/* store the signature */
|
||||
for (x = 0; x < rsa_size; x++, y++) {
|
||||
out[y] = rsa_in[x];
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_SIGNED, y);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(rsa_in, sizeof(rsa_in));
|
||||
zeromem(rsa_out, sizeof(rsa_out));
|
||||
#endif
|
||||
*outlen = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_verify(const unsigned char *sig, const unsigned char *msg,
|
||||
unsigned long inlen, int *stat,
|
||||
rsa_key *key)
|
||||
{
|
||||
unsigned long hashlen, rsa_size, x, y, z, w;
|
||||
int hash, errno;
|
||||
unsigned char rsa_in[4096], rsa_out[4096];
|
||||
|
||||
_ARGCHK(sig != NULL);
|
||||
_ARGCHK(msg != NULL);
|
||||
_ARGCHK(stat != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* always be incorrect by default */
|
||||
*stat = 0;
|
||||
|
||||
/* verify header */
|
||||
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_RSA, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* grab hash name */
|
||||
y = PACKET_SIZE;
|
||||
hash = find_hash_id(sig[y++]);
|
||||
if (hash == -1) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
hashlen = hash_descriptor[hash].hashsize;
|
||||
|
||||
/* get the len */
|
||||
LOAD32L(rsa_size, (sig+y));
|
||||
y += 4;
|
||||
|
||||
/* load the signature */
|
||||
for (x = 0; x < rsa_size; x++, y++) {
|
||||
rsa_in[x] = sig[y];
|
||||
}
|
||||
|
||||
/* exptmod it */
|
||||
x = sizeof(rsa_in);
|
||||
if ((errno = rsa_exptmod(rsa_in, rsa_size, rsa_out, &x, PK_PUBLIC, key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* depad it */
|
||||
z = sizeof(rsa_in);
|
||||
if ((errno = rsa_signdepad(rsa_out, x, rsa_in, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* check? */
|
||||
w = sizeof(rsa_out);
|
||||
if ((errno = hash_memory(hash, msg, inlen, rsa_out, &w)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((z == hashlen) && (!memcmp(rsa_in, rsa_out, hashlen))) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(rsa_in, sizeof(rsa_in));
|
||||
zeromem(rsa_out, sizeof(rsa_out));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* these are smaller routines written by Clay Culver. They do the same function as the rsa_encrypt/decrypt
|
||||
* except that they are used to RSA encrypt/decrypt a single value and not a packet.
|
||||
*/
|
||||
int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, rsa_key *key)
|
||||
{
|
||||
unsigned char rsa_in[4096], rsa_out[4096];
|
||||
unsigned long x, y, rsa_size;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(inkey != NULL);
|
||||
_ARGCHK(outkey != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* are the parameters valid? */
|
||||
if ((errno = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* rsa_pad the symmetric key */
|
||||
y = sizeof(rsa_in);
|
||||
if ((errno = rsa_pad(inkey, inlen, rsa_in, &y, wprng, prng)) != CRYPT_OK) {
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
/* rsa encrypt it */
|
||||
rsa_size = sizeof(rsa_out);
|
||||
if ((errno = rsa_exptmod(rsa_in, y, rsa_out, &rsa_size, PK_PUBLIC, key)) != CRYPT_OK) {
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
/* check size */
|
||||
if (*outlen < (PACKET_SIZE+4+rsa_size)) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* now lets make the header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* store the size of the RSA value */
|
||||
STORE32L(rsa_size, (outkey+y));
|
||||
y += 4;
|
||||
|
||||
/* store the rsa value */
|
||||
for (x = 0; x < rsa_size; x++, y++) {
|
||||
outkey[y] = rsa_out[x];
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY, y);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(rsa_in, sizeof(rsa_in));
|
||||
zeromem(rsa_out, sizeof(rsa_out));
|
||||
#endif
|
||||
*outlen = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_decrypt_key(const unsigned char *in, unsigned char *outkey,
|
||||
unsigned long *keylen, rsa_key *key)
|
||||
{
|
||||
unsigned char sym_key[MAXBLOCKSIZE], rsa_in[4096], rsa_out[4096];
|
||||
unsigned long x, y, z, i, rsa_size;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(outkey != NULL);
|
||||
_ARGCHK(keylen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* check the header */
|
||||
if ((errno = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* grab length of the rsa key */
|
||||
y = PACKET_SIZE;
|
||||
LOAD32L(rsa_size, (in+y))
|
||||
y += 4;
|
||||
|
||||
/* read it in */
|
||||
for (x = 0; x < rsa_size; x++, y++) {
|
||||
rsa_in[x] = in[y];
|
||||
}
|
||||
|
||||
/* decrypt it */
|
||||
x = sizeof(rsa_out);
|
||||
if ((errno = rsa_exptmod(rsa_in, rsa_size, rsa_out, &x, PK_PRIVATE, key)) != CRYPT_OK)
|
||||
return errno;
|
||||
|
||||
/* depad it */
|
||||
z = sizeof(sym_key);
|
||||
if ((errno = rsa_depad(rsa_out, x, sym_key, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* check size */
|
||||
if (*keylen < z) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
for (i = 0; i < z; i++) {
|
||||
outkey[i] = sym_key[i];
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(sym_key, sizeof(sym_key));
|
||||
zeromem(rsa_in, sizeof(rsa_in));
|
||||
zeromem(rsa_out, sizeof(rsa_out));
|
||||
#endif
|
||||
*keylen = z;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
rsa_key *key)
|
||||
{
|
||||
unsigned long rsa_size, x, y;
|
||||
unsigned char rsa_in[4096], rsa_out[4096];
|
||||
int errno;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* type of key? */
|
||||
if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* pad it */
|
||||
x = sizeof(rsa_out);
|
||||
if ((errno = rsa_signpad(in, inlen, rsa_out, &x)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* sign it */
|
||||
rsa_size = sizeof(rsa_in);
|
||||
if ((errno = rsa_exptmod(rsa_out, x, rsa_in, &rsa_size, PK_PRIVATE, key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* check size */
|
||||
if (*outlen < (PACKET_SIZE+4+rsa_size)) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* now lets output the message */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* output the len */
|
||||
STORE32L(rsa_size, (out+y));
|
||||
y += 4;
|
||||
|
||||
/* store the signature */
|
||||
for (x = 0; x < rsa_size; x++, y++) {
|
||||
out[y] = rsa_in[x];
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_SIGNED, y);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(rsa_in, sizeof(rsa_in));
|
||||
zeromem(rsa_out, sizeof(rsa_out));
|
||||
#endif
|
||||
*outlen = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int rsa_verify_hash(const unsigned char *sig, const unsigned char *md,
|
||||
int *stat, rsa_key *key)
|
||||
{
|
||||
unsigned long rsa_size, x, y, z;
|
||||
unsigned char rsa_in[4096], rsa_out[4096];
|
||||
int errno;
|
||||
|
||||
_ARGCHK(sig != NULL);
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(stat != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* always be incorrect by default */
|
||||
*stat = 0;
|
||||
|
||||
/* verify header */
|
||||
if ((errno = packet_valid_header((unsigned char *)sig, PACKET_SECT_RSA, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* get the len */
|
||||
y = PACKET_SIZE;
|
||||
LOAD32L(rsa_size, (sig+y));
|
||||
y += 4;
|
||||
|
||||
/* load the signature */
|
||||
for (x = 0; x < rsa_size; x++, y++) {
|
||||
rsa_in[x] = sig[y];
|
||||
}
|
||||
|
||||
/* exptmod it */
|
||||
x = sizeof(rsa_in);
|
||||
if ((errno = rsa_exptmod(rsa_in, rsa_size, rsa_out, &x, PK_PUBLIC, key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* depad it */
|
||||
z = sizeof(rsa_in);
|
||||
if ((errno = rsa_signdepad(rsa_out, x, rsa_in, &z)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* check? */
|
||||
if (!memcmp(rsa_in, md, z)) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(rsa_in, sizeof(rsa_in));
|
||||
zeromem(rsa_out, sizeof(rsa_out));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
506
safer+.c
Normal file
506
safer+.c
Normal file
@ -0,0 +1,506 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef SAFERP
|
||||
|
||||
const struct _cipher_descriptor saferp_desc =
|
||||
{
|
||||
"safer+",
|
||||
4,
|
||||
16, 32, 16, 8,
|
||||
&saferp_setup,
|
||||
&saferp_ecb_encrypt,
|
||||
&saferp_ecb_decrypt,
|
||||
&saferp_test,
|
||||
&saferp_keysize
|
||||
};
|
||||
|
||||
/* ROUND(b,i)
|
||||
*
|
||||
* This is one forward key application. Note the basic form is
|
||||
* key addition, substitution, key addition. The safer_ebox and safer_lbox
|
||||
* are the exponentiation box and logarithm boxes respectively.
|
||||
* The value of 'i' is the current round number which allows this
|
||||
* function to be unrolled massively. Most of SAFER+'s speed
|
||||
* comes from not having to compute indirect accesses into the
|
||||
* array of 16 bytes b[0..15] which is the block of data
|
||||
*/
|
||||
|
||||
extern const unsigned char safer_ebox[], safer_lbox[];
|
||||
|
||||
#define ROUND(b, i) \
|
||||
b[0] = (safer_ebox[(b[0] ^ skey->saferp.K[i][0]) & 255] + skey->saferp.K[i+1][0]) & 255; \
|
||||
b[1] = safer_lbox[(b[1] + skey->saferp.K[i][1]) & 255] ^ skey->saferp.K[i+1][1]; \
|
||||
b[2] = safer_lbox[(b[2] + skey->saferp.K[i][2]) & 255] ^ skey->saferp.K[i+1][2]; \
|
||||
b[3] = (safer_ebox[(b[3] ^ skey->saferp.K[i][3]) & 255] + skey->saferp.K[i+1][3]) & 255; \
|
||||
b[4] = (safer_ebox[(b[4] ^ skey->saferp.K[i][4]) & 255] + skey->saferp.K[i+1][4]) & 255; \
|
||||
b[5] = safer_lbox[(b[5] + skey->saferp.K[i][5]) & 255] ^ skey->saferp.K[i+1][5]; \
|
||||
b[6] = safer_lbox[(b[6] + skey->saferp.K[i][6]) & 255] ^ skey->saferp.K[i+1][6]; \
|
||||
b[7] = (safer_ebox[(b[7] ^ skey->saferp.K[i][7]) & 255] + skey->saferp.K[i+1][7]) & 255; \
|
||||
b[8] = (safer_ebox[(b[8] ^ skey->saferp.K[i][8]) & 255] + skey->saferp.K[i+1][8]) & 255; \
|
||||
b[9] = safer_lbox[(b[9] + skey->saferp.K[i][9]) & 255] ^ skey->saferp.K[i+1][9]; \
|
||||
b[10] = safer_lbox[(b[10] + skey->saferp.K[i][10]) & 255] ^ skey->saferp.K[i+1][10]; \
|
||||
b[11] = (safer_ebox[(b[11] ^ skey->saferp.K[i][11]) & 255] + skey->saferp.K[i+1][11]) & 255; \
|
||||
b[12] = (safer_ebox[(b[12] ^ skey->saferp.K[i][12]) & 255] + skey->saferp.K[i+1][12]) & 255; \
|
||||
b[13] = safer_lbox[(b[13] + skey->saferp.K[i][13]) & 255] ^ skey->saferp.K[i+1][13]; \
|
||||
b[14] = safer_lbox[(b[14] + skey->saferp.K[i][14]) & 255] ^ skey->saferp.K[i+1][14]; \
|
||||
b[15] = (safer_ebox[(b[15] ^ skey->saferp.K[i][15]) & 255] + skey->saferp.K[i+1][15]) & 255;
|
||||
|
||||
/* This is one inverse key application */
|
||||
#define iROUND(b, i) \
|
||||
b[0] = safer_lbox[(b[0] - skey->saferp.K[i+1][0]) & 255] ^ skey->saferp.K[i][0]; \
|
||||
b[1] = (safer_ebox[(b[1] ^ skey->saferp.K[i+1][1]) & 255] - skey->saferp.K[i][1]) & 255; \
|
||||
b[2] = (safer_ebox[(b[2] ^ skey->saferp.K[i+1][2]) & 255] - skey->saferp.K[i][2]) & 255; \
|
||||
b[3] = safer_lbox[(b[3] - skey->saferp.K[i+1][3]) & 255] ^ skey->saferp.K[i][3]; \
|
||||
b[4] = safer_lbox[(b[4] - skey->saferp.K[i+1][4]) & 255] ^ skey->saferp.K[i][4]; \
|
||||
b[5] = (safer_ebox[(b[5] ^ skey->saferp.K[i+1][5]) & 255] - skey->saferp.K[i][5]) & 255; \
|
||||
b[6] = (safer_ebox[(b[6] ^ skey->saferp.K[i+1][6]) & 255] - skey->saferp.K[i][6]) & 255; \
|
||||
b[7] = safer_lbox[(b[7] - skey->saferp.K[i+1][7]) & 255] ^ skey->saferp.K[i][7]; \
|
||||
b[8] = safer_lbox[(b[8] - skey->saferp.K[i+1][8]) & 255] ^ skey->saferp.K[i][8]; \
|
||||
b[9] = (safer_ebox[(b[9] ^ skey->saferp.K[i+1][9]) & 255] - skey->saferp.K[i][9]) & 255; \
|
||||
b[10] = (safer_ebox[(b[10] ^ skey->saferp.K[i+1][10]) & 255] - skey->saferp.K[i][10]) & 255; \
|
||||
b[11] = safer_lbox[(b[11] - skey->saferp.K[i+1][11]) & 255] ^ skey->saferp.K[i][11]; \
|
||||
b[12] = safer_lbox[(b[12] - skey->saferp.K[i+1][12]) & 255] ^ skey->saferp.K[i][12]; \
|
||||
b[13] = (safer_ebox[(b[13] ^ skey->saferp.K[i+1][13]) & 255] - skey->saferp.K[i][13]) & 255; \
|
||||
b[14] = (safer_ebox[(b[14] ^ skey->saferp.K[i+1][14]) & 255] - skey->saferp.K[i][14]) & 255; \
|
||||
b[15] = safer_lbox[(b[15] - skey->saferp.K[i+1][15]) & 255] ^ skey->saferp.K[i][15];
|
||||
|
||||
/* This is a forward single layer PHT transform. */
|
||||
#define PHT(b) \
|
||||
b[0] = (b[0] + (b[1] = (b[0] + b[1]) & 255)) & 255; \
|
||||
b[2] = (b[2] + (b[3] = (b[3] + b[2]) & 255)) & 255; \
|
||||
b[4] = (b[4] + (b[5] = (b[5] + b[4]) & 255)) & 255; \
|
||||
b[6] = (b[6] + (b[7] = (b[7] + b[6]) & 255)) & 255; \
|
||||
b[8] = (b[8] + (b[9] = (b[9] + b[8]) & 255)) & 255; \
|
||||
b[10] = (b[10] + (b[11] = (b[11] + b[10]) & 255)) & 255; \
|
||||
b[12] = (b[12] + (b[13] = (b[13] + b[12]) & 255)) & 255; \
|
||||
b[14] = (b[14] + (b[15] = (b[15] + b[14]) & 255)) & 255;
|
||||
|
||||
/* This is an inverse single layer PHT transform */
|
||||
#define iPHT(b) \
|
||||
b[15] = (b[15] - (b[14] = (b[14] - b[15]) & 255)) & 255; \
|
||||
b[13] = (b[13] - (b[12] = (b[12] - b[13]) & 255)) & 255; \
|
||||
b[11] = (b[11] - (b[10] = (b[10] - b[11]) & 255)) & 255; \
|
||||
b[9] = (b[9] - (b[8] = (b[8] - b[9]) & 255)) & 255; \
|
||||
b[7] = (b[7] - (b[6] = (b[6] - b[7]) & 255)) & 255; \
|
||||
b[5] = (b[5] - (b[4] = (b[4] - b[5]) & 255)) & 255; \
|
||||
b[3] = (b[3] - (b[2] = (b[2] - b[3]) & 255)) & 255; \
|
||||
b[1] = (b[1] - (b[0] = (b[0] - b[1]) & 255)) & 255; \
|
||||
|
||||
/* This is the "Armenian" Shuffle. It takes the input from b and stores it in b2 */
|
||||
#define SHUF(b, b2) \
|
||||
b2[0] = b[8]; b2[1] = b[11]; b2[2] = b[12]; b2[3] = b[15]; \
|
||||
b2[4] = b[2]; b2[5] = b[1]; b2[6] = b[6]; b2[7] = b[5]; \
|
||||
b2[8] = b[10]; b2[9] = b[9]; b2[10] = b[14]; b2[11] = b[13]; \
|
||||
b2[12] = b[0]; b2[13] = b[7]; b2[14] = b[4]; b2[15] = b[3];
|
||||
|
||||
/* This is the inverse shuffle. It takes from b and gives to b2 */
|
||||
#define iSHUF(b, b2) \
|
||||
b2[0] = b[12]; b2[1] = b[5]; b2[2] = b[4]; b2[3] = b[15]; \
|
||||
b2[4] = b[14]; b2[5] = b[7]; b2[6] = b[6]; b2[7] = b[13]; \
|
||||
b2[8] = b[0]; b2[9] = b[9]; b2[10] = b[8]; b2[11] = b[1]; \
|
||||
b2[12] = b[2]; b2[13] = b[11]; b2[14] = b[10]; b2[15] = b[3];
|
||||
|
||||
/* The complete forward Linear Transform layer.
|
||||
* Note that alternating usage of b and b2.
|
||||
* Each round of LT starts in 'b' and ends in 'b2'.
|
||||
*/
|
||||
#define LT(b, b2) \
|
||||
PHT(b); SHUF(b, b2); \
|
||||
PHT(b2); SHUF(b2, b); \
|
||||
PHT(b); SHUF(b, b2); \
|
||||
PHT(b2);
|
||||
|
||||
/* This is the inverse linear transform layer. */
|
||||
#define iLT(b, b2) \
|
||||
iPHT(b); \
|
||||
iSHUF(b, b2); iPHT(b2); \
|
||||
iSHUF(b2, b); iPHT(b); \
|
||||
iSHUF(b, b2); iPHT(b2);
|
||||
|
||||
#ifdef SAFERP_SMALL
|
||||
|
||||
static void _round(unsigned char *b, int i, symmetric_key *skey)
|
||||
{
|
||||
ROUND(b, i);
|
||||
}
|
||||
|
||||
static void _iround(unsigned char *b, int i, symmetric_key *skey)
|
||||
{
|
||||
iROUND(b, i);
|
||||
}
|
||||
|
||||
static void _lt(unsigned char *b, unsigned char *b2)
|
||||
{
|
||||
LT(b, b2);
|
||||
}
|
||||
|
||||
static void _ilt(unsigned char *b, unsigned char *b2)
|
||||
{
|
||||
iLT(b, b2);
|
||||
}
|
||||
|
||||
#undef ROUND
|
||||
#define ROUND(b, i) _round(b, i, skey)
|
||||
|
||||
#undef iROUND
|
||||
#define iROUND(b, i) _iround(b, i, skey)
|
||||
|
||||
#undef LT
|
||||
#define LT(b, b2) _lt(b, b2)
|
||||
|
||||
#undef iLT
|
||||
#define iLT(b, b2) _ilt(b, b2)
|
||||
|
||||
#endif
|
||||
|
||||
/* These are the 33, 128-bit bias words for the key schedule */
|
||||
const unsigned char safer_bias[33][16] = {
|
||||
{ 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172, 100},
|
||||
{ 236, 171, 170, 198, 103, 149, 88, 13, 248, 154, 246, 110, 102, 220, 5, 61},
|
||||
{ 138, 195, 216, 137, 106, 233, 54, 73, 67, 191, 235, 212, 150, 155, 104, 160},
|
||||
{ 93, 87, 146, 31, 213, 113, 92, 187, 34, 193, 190, 123, 188, 153, 99, 148},
|
||||
{ 42, 97, 184, 52, 50, 25, 253, 251, 23, 64, 230, 81, 29, 65, 68, 143},
|
||||
{ 221, 4, 128, 222, 231, 49, 214, 127, 1, 162, 247, 57, 218, 111, 35, 202},
|
||||
{ 58, 208, 28, 209, 48, 62, 18, 161, 205, 15, 224, 168, 175, 130, 89, 44},
|
||||
{ 125, 173, 178, 239, 194, 135, 206, 117, 6, 19, 2, 144, 79, 46, 114, 51},
|
||||
{ 192, 141, 207, 169, 129, 226, 196, 39, 47, 108, 122, 159, 82, 225, 21, 56},
|
||||
{ 252, 32, 66, 199, 8, 228, 9, 85, 94, 140, 20, 118, 96, 255, 223, 215},
|
||||
{ 250, 11, 33, 0, 26, 249, 166, 185, 232, 158, 98, 76, 217, 145, 80, 210},
|
||||
{ 24, 180, 7, 132, 234, 91, 164, 200, 14, 203, 72, 105, 75, 78, 156, 53},
|
||||
{ 69, 77, 84, 229, 37, 60, 12, 74, 139, 63, 204, 167, 219, 107, 174, 244},
|
||||
{ 45, 243, 124, 109, 157, 181, 38, 116, 242, 147, 83, 176, 240, 17, 237, 131},
|
||||
{ 182, 3, 22, 115, 59, 30, 142, 112, 189, 134, 27, 71, 126, 36, 86, 241},
|
||||
{ 136, 70, 151, 177, 186, 163, 183, 16, 10, 197, 55, 179, 201, 90, 40, 172},
|
||||
{ 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51, 239},
|
||||
{ 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20, 129, 151, 113, 202},
|
||||
{ 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160, 4, 180, 133, 74, 246},
|
||||
{ 84, 182, 223, 12, 26, 142, 222, 224, 57, 252, 32, 155, 36, 78, 169, 152},
|
||||
{ 171, 242, 96, 208, 108, 234, 250, 199, 217, 0, 212, 31, 110, 67, 188, 236},
|
||||
{ 137, 254, 122, 93, 73, 201, 50, 194, 249, 154, 248, 109, 22, 219, 89, 150},
|
||||
{ 233, 205, 230, 70, 66, 143, 10, 193, 204, 185, 101, 176, 210, 198, 172, 30},
|
||||
{ 98, 41, 46, 14, 116, 80, 2, 90, 195, 37, 123, 138, 42, 91, 240, 6},
|
||||
{ 71, 111, 112, 157, 126, 16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104},
|
||||
{ 117, 125, 228, 237, 128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175},
|
||||
{ 229, 25, 97, 253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35},
|
||||
{ 200, 5, 225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7},
|
||||
{ 40, 1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207},
|
||||
{ 8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247},
|
||||
{ 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177, 255},
|
||||
{ 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131, 241, 51}};
|
||||
|
||||
int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
{
|
||||
unsigned x, y;
|
||||
unsigned char t[33];
|
||||
static const int rounds[3] = { 8, 12, 16 };
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
/* check arguments */
|
||||
if (keylen != 16 && keylen != 24 && keylen != 32) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
/* Is the number of rounds valid? Either use zero for default or
|
||||
* 8,12,16 rounds for 16,24,32 byte keys
|
||||
*/
|
||||
if (num_rounds != 0 && num_rounds != rounds[(keylen/8)-2]) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
/* 128 bit key version */
|
||||
if (keylen == 16) {
|
||||
/* copy key into t */
|
||||
for (x = y = 0; x < 16; x++) {
|
||||
t[x] = key[x];
|
||||
y ^= key[x];
|
||||
}
|
||||
t[16] = y;
|
||||
|
||||
/* make round keys */
|
||||
for (x = 0; x < 16; x++) {
|
||||
skey->saferp.K[0][x] = t[x];
|
||||
}
|
||||
|
||||
/* make the 16 other keys as a transformation of the first key */
|
||||
for (x = 1; x < 17; x++) {
|
||||
/* rotate 3 bits each */
|
||||
for (y = 0; y < 17; y++) {
|
||||
t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
|
||||
}
|
||||
|
||||
/* select and add */
|
||||
for (y = 0; y < 16; y++) {
|
||||
skey->saferp.K[x][y] = (t[(x+y)%17] + safer_bias[x-1][y]) & 255;
|
||||
}
|
||||
}
|
||||
skey->saferp.rounds = 8;
|
||||
} else if (keylen == 24) {
|
||||
/* copy key into t */
|
||||
for (x = y = 0; x < 24; x++) {
|
||||
t[x] = key[x];
|
||||
y ^= key[x];
|
||||
}
|
||||
t[24] = y;
|
||||
|
||||
/* make round keys */
|
||||
for (x = 0; x < 16; x++) {
|
||||
skey->saferp.K[0][x] = t[x];
|
||||
}
|
||||
|
||||
for (x = 1; x < 25; x++) {
|
||||
/* rotate 3 bits each */
|
||||
for (y = 0; y < 25; y++) {
|
||||
t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
|
||||
}
|
||||
|
||||
/* select and add */
|
||||
for (y = 0; y < 16; y++) {
|
||||
skey->saferp.K[x][y] = (t[(x+y)%25] + safer_bias[x-1][y]) & 255;
|
||||
}
|
||||
}
|
||||
skey->saferp.rounds = 12;
|
||||
} else {
|
||||
/* copy key into t */
|
||||
for (x = y = 0; x < 32; x++) {
|
||||
t[x] = key[x];
|
||||
y ^= key[x];
|
||||
}
|
||||
t[32] = y;
|
||||
|
||||
/* make round keys */
|
||||
for (x = 0; x < 16; x++) {
|
||||
skey->saferp.K[0][x] = t[x];
|
||||
}
|
||||
|
||||
for (x = 1; x < 33; x++) {
|
||||
/* rotate 3 bits each */
|
||||
for (y = 0; y < 33; y++) {
|
||||
t[y] = ((t[y]<<3)|(t[y]>>5)) & 255;
|
||||
}
|
||||
|
||||
/* select and add */
|
||||
for (y = 0; y < 16; y++) {
|
||||
skey->saferp.K[x][y] = (t[(x+y)%33] + safer_bias[x-1][y]) & 255;
|
||||
}
|
||||
}
|
||||
skey->saferp.rounds = 16;
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(t, sizeof(t));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
void saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
|
||||
{
|
||||
unsigned char b[16];
|
||||
int x;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
/* do eight rounds */
|
||||
for (x = 0; x < 16; x++) {
|
||||
b[x] = pt[x];
|
||||
}
|
||||
ROUND(b, 0); LT(b, ct);
|
||||
ROUND(ct, 2); LT(ct, b);
|
||||
ROUND(b, 4); LT(b, ct);
|
||||
ROUND(ct, 6); LT(ct, b);
|
||||
ROUND(b, 8); LT(b, ct);
|
||||
ROUND(ct, 10); LT(ct, b);
|
||||
ROUND(b, 12); LT(b, ct);
|
||||
ROUND(ct, 14); LT(ct, b);
|
||||
/* 192-bit key? */
|
||||
if (skey->saferp.rounds > 8) {
|
||||
ROUND(b, 16); LT(b, ct);
|
||||
ROUND(ct, 18); LT(ct, b);
|
||||
ROUND(b, 20); LT(b, ct);
|
||||
ROUND(ct, 22); LT(ct, b);
|
||||
}
|
||||
/* 256-bit key? */
|
||||
if (skey->saferp.rounds > 12) {
|
||||
ROUND(b, 24); LT(b, ct);
|
||||
ROUND(ct, 26); LT(ct, b);
|
||||
ROUND(b, 28); LT(b, ct);
|
||||
ROUND(ct, 30); LT(ct, b);
|
||||
}
|
||||
ct[0] = b[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
|
||||
ct[1] = (b[1] + skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
|
||||
ct[2] = (b[2] + skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
|
||||
ct[3] = b[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
|
||||
ct[4] = b[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
|
||||
ct[5] = (b[5] + skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
|
||||
ct[6] = (b[6] + skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
|
||||
ct[7] = b[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
|
||||
ct[8] = b[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
|
||||
ct[9] = (b[9] + skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
|
||||
ct[10] = (b[10] + skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
|
||||
ct[11] = b[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
|
||||
ct[12] = b[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
|
||||
ct[13] = (b[13] + skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
|
||||
ct[14] = (b[14] + skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
|
||||
ct[15] = b[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(b, sizeof(b));
|
||||
#endif
|
||||
}
|
||||
|
||||
void saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
|
||||
{
|
||||
unsigned char b[16];
|
||||
int x;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
/* do eight rounds */
|
||||
b[0] = ct[0] ^ skey->saferp.K[skey->saferp.rounds*2][0];
|
||||
b[1] = (ct[1] - skey->saferp.K[skey->saferp.rounds*2][1]) & 255;
|
||||
b[2] = (ct[2] - skey->saferp.K[skey->saferp.rounds*2][2]) & 255;
|
||||
b[3] = ct[3] ^ skey->saferp.K[skey->saferp.rounds*2][3];
|
||||
b[4] = ct[4] ^ skey->saferp.K[skey->saferp.rounds*2][4];
|
||||
b[5] = (ct[5] - skey->saferp.K[skey->saferp.rounds*2][5]) & 255;
|
||||
b[6] = (ct[6] - skey->saferp.K[skey->saferp.rounds*2][6]) & 255;
|
||||
b[7] = ct[7] ^ skey->saferp.K[skey->saferp.rounds*2][7];
|
||||
b[8] = ct[8] ^ skey->saferp.K[skey->saferp.rounds*2][8];
|
||||
b[9] = (ct[9] - skey->saferp.K[skey->saferp.rounds*2][9]) & 255;
|
||||
b[10] = (ct[10] - skey->saferp.K[skey->saferp.rounds*2][10]) & 255;
|
||||
b[11] = ct[11] ^ skey->saferp.K[skey->saferp.rounds*2][11];
|
||||
b[12] = ct[12] ^ skey->saferp.K[skey->saferp.rounds*2][12];
|
||||
b[13] = (ct[13] - skey->saferp.K[skey->saferp.rounds*2][13]) & 255;
|
||||
b[14] = (ct[14] - skey->saferp.K[skey->saferp.rounds*2][14]) & 255;
|
||||
b[15] = ct[15] ^ skey->saferp.K[skey->saferp.rounds*2][15];
|
||||
/* 256-bit key? */
|
||||
if (skey->saferp.rounds > 12) {
|
||||
iLT(b, pt); iROUND(pt, 30);
|
||||
iLT(pt, b); iROUND(b, 28);
|
||||
iLT(b, pt); iROUND(pt, 26);
|
||||
iLT(pt, b); iROUND(b, 24);
|
||||
}
|
||||
/* 192-bit key? */
|
||||
if (skey->saferp.rounds > 8) {
|
||||
iLT(b, pt); iROUND(pt, 22);
|
||||
iLT(pt, b); iROUND(b, 20);
|
||||
iLT(b, pt); iROUND(pt, 18);
|
||||
iLT(pt, b); iROUND(b, 16);
|
||||
}
|
||||
iLT(b, pt); iROUND(pt, 14);
|
||||
iLT(pt, b); iROUND(b, 12);
|
||||
iLT(b, pt); iROUND(pt,10);
|
||||
iLT(pt, b); iROUND(b, 8);
|
||||
iLT(b, pt); iROUND(pt,6);
|
||||
iLT(pt, b); iROUND(b, 4);
|
||||
iLT(b, pt); iROUND(pt,2);
|
||||
iLT(pt, b); iROUND(b, 0);
|
||||
for (x = 0; x < 16; x++) {
|
||||
pt[x] = b[x];
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(b, sizeof(b));
|
||||
#endif
|
||||
}
|
||||
|
||||
int saferp_test(void)
|
||||
{
|
||||
static const unsigned char key128[16] =
|
||||
{ 41, 35, 190, 132, 225, 108, 214, 174,
|
||||
82, 144, 73, 241, 241, 187, 233, 235 };
|
||||
static const unsigned char pt128[16] =
|
||||
{ 179, 166, 219, 60, 135, 12, 62, 153,
|
||||
36, 94, 13, 28, 6, 183, 71, 222 };
|
||||
static const unsigned char ct128[16] =
|
||||
{ 224, 31, 182, 10, 12, 255, 84, 70,
|
||||
127, 13, 89, 249, 9, 57, 165, 220 };
|
||||
|
||||
static const unsigned char key192[24] =
|
||||
{ 72, 211, 143, 117, 230, 217, 29, 42,
|
||||
229, 192, 247, 43, 120, 129, 135, 68,
|
||||
14, 95, 80, 0, 212, 97, 141, 190 };
|
||||
static const unsigned char pt192[16] =
|
||||
{ 123, 5, 21, 7, 59, 51, 130, 31,
|
||||
24, 112, 146, 218, 100, 84, 206, 177 };
|
||||
static const unsigned char ct192[16] =
|
||||
{ 92, 136, 4, 63, 57, 95, 100, 0,
|
||||
150, 130, 130, 16, 193, 111, 219, 133 };
|
||||
|
||||
static const unsigned char key256[32] =
|
||||
{ 243, 168, 141, 254, 190, 242, 235, 113,
|
||||
255, 160, 208, 59, 117, 6, 140, 126,
|
||||
135, 120, 115, 77, 208, 190, 130, 190,
|
||||
219, 194, 70, 65, 43, 140, 250, 48 };
|
||||
static const unsigned char pt256[16] =
|
||||
{ 127, 112, 240, 167, 84, 134, 50, 149,
|
||||
170, 91, 104, 19, 11, 230, 252, 245 };
|
||||
static const unsigned char ct256[16] =
|
||||
{ 88, 11, 25, 36, 172, 229, 202, 213,
|
||||
170, 65, 105, 153, 220, 104, 153, 138 };
|
||||
|
||||
unsigned char buf[2][16];
|
||||
symmetric_key skey;
|
||||
int errno;
|
||||
|
||||
/* test 128-bit key */
|
||||
if ((errno = saferp_setup(key128, 16, 0, &skey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
saferp_ecb_encrypt(pt128, buf[0], &skey);
|
||||
saferp_ecb_decrypt(buf[0], buf[1], &skey);
|
||||
|
||||
/* compare */
|
||||
if (memcmp(buf[0], &ct128, 16) || memcmp(buf[1], &pt128, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* test 192-bit key */
|
||||
if ((errno = saferp_setup(key192, 24, 0, &skey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
saferp_ecb_encrypt(pt192, buf[0], &skey);
|
||||
saferp_ecb_decrypt(buf[0], buf[1], &skey);
|
||||
|
||||
/* compare */
|
||||
if (memcmp(buf[0], &ct192, 16) || memcmp(buf[1], &pt192, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* test 256-bit key */
|
||||
if ((errno = saferp_setup(key256, 32, 0, &skey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
saferp_ecb_encrypt(pt256, buf[0], &skey);
|
||||
saferp_ecb_decrypt(buf[0], buf[1], &skey);
|
||||
|
||||
/* compare */
|
||||
if (memcmp(buf[0], &ct256, 16) || memcmp(buf[1], &pt256, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int saferp_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
|
||||
if (*desired_keysize < 16)
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
if (*desired_keysize < 24) {
|
||||
*desired_keysize = 16;
|
||||
return CRYPT_OK;
|
||||
} else if (*desired_keysize < 32) {
|
||||
*desired_keysize = 24;
|
||||
return CRYPT_OK;
|
||||
} else {
|
||||
*desired_keysize = 32;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
421
safer.c
Normal file
421
safer.c
Normal file
@ -0,0 +1,421 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* FILE: safer.c
|
||||
*
|
||||
* DESCRIPTION: block-cipher algorithm SAFER (Secure And Fast Encryption
|
||||
* Routine) in its four versions: SAFER K-64, SAFER K-128,
|
||||
* SAFER SK-64 and SAFER SK-128.
|
||||
*
|
||||
* AUTHOR: Richard De Moliner (demoliner@isi.ee.ethz.ch)
|
||||
* Signal and Information Processing Laboratory
|
||||
* Swiss Federal Institute of Technology
|
||||
* CH-8092 Zuerich, Switzerland
|
||||
*
|
||||
* DATE: September 9, 1995
|
||||
*
|
||||
* CHANGE HISTORY:
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#include <mycrypt.h>
|
||||
|
||||
#ifdef SAFER
|
||||
|
||||
const struct _cipher_descriptor
|
||||
safer_k64_desc = {
|
||||
"safer-k64",
|
||||
8, 8, 8, 8, SAFER_K64_DEFAULT_NOF_ROUNDS,
|
||||
&safer_k64_setup,
|
||||
&safer_ecb_encrypt,
|
||||
&safer_ecb_decrypt,
|
||||
&safer_k64_test,
|
||||
&safer_64_keysize
|
||||
},
|
||||
|
||||
safer_sk64_desc = {
|
||||
"safer-sk64",
|
||||
9, 8, 8, 8, SAFER_SK64_DEFAULT_NOF_ROUNDS,
|
||||
&safer_sk64_setup,
|
||||
&safer_ecb_encrypt,
|
||||
&safer_ecb_decrypt,
|
||||
&safer_sk64_test,
|
||||
&safer_64_keysize
|
||||
},
|
||||
|
||||
safer_k128_desc = {
|
||||
"safer-k128",
|
||||
10, 16, 16, 8, SAFER_K128_DEFAULT_NOF_ROUNDS,
|
||||
&safer_k128_setup,
|
||||
&safer_ecb_encrypt,
|
||||
&safer_ecb_decrypt,
|
||||
&safer_sk128_test,
|
||||
&safer_128_keysize
|
||||
},
|
||||
|
||||
safer_sk128_desc = {
|
||||
"safer-sk128",
|
||||
11, 16, 16, 8, SAFER_SK128_DEFAULT_NOF_ROUNDS,
|
||||
&safer_sk128_setup,
|
||||
&safer_ecb_encrypt,
|
||||
&safer_ecb_decrypt,
|
||||
&safer_sk128_test,
|
||||
&safer_128_keysize
|
||||
};
|
||||
|
||||
/******************* Constants ************************************************/
|
||||
// #define TAB_LEN 256
|
||||
|
||||
/******************* Assertions ***********************************************/
|
||||
|
||||
/******************* Macros ***************************************************/
|
||||
#define ROL8(x, n) ((unsigned char)((unsigned int)(x) << (n)\
|
||||
|(unsigned int)((x) & 0xFF) >> (8 - (n))))
|
||||
#define EXP(x) safer_ebox[(x) & 0xFF]
|
||||
#define LOG(x) safer_lbox[(x) & 0xFF]
|
||||
#define PHT(x, y) { y += x; x += y; }
|
||||
#define IPHT(x, y) { x -= y; y -= x; }
|
||||
|
||||
/******************* Types ****************************************************/
|
||||
extern const unsigned char safer_ebox[], safer_lbox[];
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _Safer_Expand_Userkey(const unsigned char *userkey_1,
|
||||
const unsigned char *userkey_2,
|
||||
unsigned int nof_rounds,
|
||||
int strengthened,
|
||||
safer_key_t key)
|
||||
#else
|
||||
static void Safer_Expand_Userkey(const unsigned char *userkey_1,
|
||||
const unsigned char *userkey_2,
|
||||
unsigned int nof_rounds,
|
||||
int strengthened,
|
||||
safer_key_t key)
|
||||
#endif
|
||||
{ unsigned int i, j;
|
||||
unsigned char ka[SAFER_BLOCK_LEN + 1];
|
||||
unsigned char kb[SAFER_BLOCK_LEN + 1];
|
||||
|
||||
if (SAFER_MAX_NOF_ROUNDS < nof_rounds)
|
||||
nof_rounds = SAFER_MAX_NOF_ROUNDS;
|
||||
*key++ = (unsigned char)nof_rounds;
|
||||
ka[SAFER_BLOCK_LEN] = 0;
|
||||
kb[SAFER_BLOCK_LEN] = 0;
|
||||
for (j = 0; j < SAFER_BLOCK_LEN; j++)
|
||||
{
|
||||
ka[SAFER_BLOCK_LEN] ^= ka[j] = ROL8(userkey_1[j], 5);
|
||||
kb[SAFER_BLOCK_LEN] ^= kb[j] = *key++ = userkey_2[j];
|
||||
}
|
||||
for (i = 1; i <= nof_rounds; i++)
|
||||
{
|
||||
for (j = 0; j < SAFER_BLOCK_LEN + 1; j++)
|
||||
{
|
||||
ka[j] = ROL8(ka[j], 6);
|
||||
kb[j] = ROL8(kb[j], 6);
|
||||
}
|
||||
for (j = 0; j < SAFER_BLOCK_LEN; j++)
|
||||
if (strengthened)
|
||||
*key++ = (ka[(j + 2 * i - 1) % (SAFER_BLOCK_LEN + 1)]
|
||||
+ safer_ebox[safer_ebox[18 * i + j + 1]]) & 0xFF;
|
||||
else
|
||||
*key++ = (ka[j] + safer_ebox[safer_ebox[18 * i + j + 1]]) & 0xFF;
|
||||
for (j = 0; j < SAFER_BLOCK_LEN; j++)
|
||||
if (strengthened)
|
||||
*key++ = (kb[(j + 2 * i) % (SAFER_BLOCK_LEN + 1)]
|
||||
+ safer_ebox[safer_ebox[18 * i + j + 10]]) & 0xFF;
|
||||
else
|
||||
*key++ = (kb[j] + safer_ebox[safer_ebox[18 * i + j + 10]]) & 0xFF;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(ka, sizeof(ka));
|
||||
zeromem(kb, sizeof(kb));
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void Safer_Expand_Userkey(const unsigned char *userkey_1,
|
||||
const unsigned char *userkey_2,
|
||||
unsigned int nof_rounds,
|
||||
int strengthened,
|
||||
safer_key_t key)
|
||||
{
|
||||
_Safer_Expand_Userkey(userkey_1, userkey_2, nof_rounds, strengthened, key);
|
||||
burn_stack(sizeof(unsigned char) * (2 * (SAFER_BLOCK_LEN + 1)) + sizeof(unsigned int)*2);
|
||||
}
|
||||
#endif
|
||||
|
||||
int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if (numrounds && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (keylen != 8) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
Safer_Expand_Userkey(key, key, numrounds?numrounds:SAFER_K64_DEFAULT_NOF_ROUNDS, 0, skey->safer.key);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if (numrounds && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (keylen != 8) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
Safer_Expand_Userkey(key, key, numrounds?numrounds:SAFER_SK64_DEFAULT_NOF_ROUNDS, 1, skey->safer.key);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if (numrounds && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (keylen != 16) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
Safer_Expand_Userkey(key, key+8, numrounds?numrounds:SAFER_K128_DEFAULT_NOF_ROUNDS, 0, skey->safer.key);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if (numrounds && (numrounds < 6 || numrounds > SAFER_MAX_NOF_ROUNDS)) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (keylen != 16) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
Safer_Expand_Userkey(key, key+8, numrounds?numrounds:SAFER_SK128_DEFAULT_NOF_ROUNDS, 1, skey->safer.key);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _safer_ecb_encrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
#else
|
||||
void safer_ecb_encrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
#endif
|
||||
{ unsigned char a, b, c, d, e, f, g, h, t;
|
||||
unsigned int round;
|
||||
unsigned char *key;
|
||||
|
||||
_ARGCHK(block_in != NULL);
|
||||
_ARGCHK(block_out != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
key = skey->safer.key;
|
||||
a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
|
||||
e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
|
||||
if (SAFER_MAX_NOF_ROUNDS < (round = *key)) round = SAFER_MAX_NOF_ROUNDS;
|
||||
while(round--)
|
||||
{
|
||||
a ^= *++key; b += *++key; c += *++key; d ^= *++key;
|
||||
e ^= *++key; f += *++key; g += *++key; h ^= *++key;
|
||||
a = EXP(a) + *++key; b = LOG(b) ^ *++key;
|
||||
c = LOG(c) ^ *++key; d = EXP(d) + *++key;
|
||||
e = EXP(e) + *++key; f = LOG(f) ^ *++key;
|
||||
g = LOG(g) ^ *++key; h = EXP(h) + *++key;
|
||||
PHT(a, b); PHT(c, d); PHT(e, f); PHT(g, h);
|
||||
PHT(a, c); PHT(e, g); PHT(b, d); PHT(f, h);
|
||||
PHT(a, e); PHT(b, f); PHT(c, g); PHT(d, h);
|
||||
t = b; b = e; e = c; c = t; t = d; d = f; f = g; g = t;
|
||||
}
|
||||
a ^= *++key; b += *++key; c += *++key; d ^= *++key;
|
||||
e ^= *++key; f += *++key; g += *++key; h ^= *++key;
|
||||
block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
|
||||
block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
|
||||
block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
|
||||
block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void safer_ecb_encrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
{
|
||||
_safer_ecb_encrypt(block_in, block_out, skey);
|
||||
burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _safer_ecb_decrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
#else
|
||||
void safer_ecb_decrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
#endif
|
||||
{ unsigned char a, b, c, d, e, f, g, h, t;
|
||||
unsigned int round;
|
||||
unsigned char *key;
|
||||
|
||||
_ARGCHK(block_in != NULL);
|
||||
_ARGCHK(block_out != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
key = skey->safer.key;
|
||||
a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3];
|
||||
e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7];
|
||||
if (SAFER_MAX_NOF_ROUNDS < (round = *key)) round = SAFER_MAX_NOF_ROUNDS;
|
||||
key += SAFER_BLOCK_LEN * (1 + 2 * round);
|
||||
h ^= *key; g -= *--key; f -= *--key; e ^= *--key;
|
||||
d ^= *--key; c -= *--key; b -= *--key; a ^= *--key;
|
||||
while (round--)
|
||||
{
|
||||
t = e; e = b; b = c; c = t; t = f; f = d; d = g; g = t;
|
||||
IPHT(a, e); IPHT(b, f); IPHT(c, g); IPHT(d, h);
|
||||
IPHT(a, c); IPHT(e, g); IPHT(b, d); IPHT(f, h);
|
||||
IPHT(a, b); IPHT(c, d); IPHT(e, f); IPHT(g, h);
|
||||
h -= *--key; g ^= *--key; f ^= *--key; e -= *--key;
|
||||
d -= *--key; c ^= *--key; b ^= *--key; a -= *--key;
|
||||
h = LOG(h) ^ *--key; g = EXP(g) - *--key;
|
||||
f = EXP(f) - *--key; e = LOG(e) ^ *--key;
|
||||
d = LOG(d) ^ *--key; c = EXP(c) - *--key;
|
||||
b = EXP(b) - *--key; a = LOG(a) ^ *--key;
|
||||
}
|
||||
block_out[0] = a & 0xFF; block_out[1] = b & 0xFF;
|
||||
block_out[2] = c & 0xFF; block_out[3] = d & 0xFF;
|
||||
block_out[4] = e & 0xFF; block_out[5] = f & 0xFF;
|
||||
block_out[6] = g & 0xFF; block_out[7] = h & 0xFF;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void safer_ecb_decrypt(const unsigned char *block_in,
|
||||
unsigned char *block_out,
|
||||
symmetric_key *skey)
|
||||
{
|
||||
_safer_ecb_decrypt(block_in, block_out, skey);
|
||||
burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *));
|
||||
}
|
||||
#endif
|
||||
|
||||
int safer_64_keysize(int *keysize)
|
||||
{
|
||||
_ARGCHK(keysize != NULL);
|
||||
if (*keysize < 8) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
} else {
|
||||
*keysize = 8;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int safer_128_keysize(int *keysize)
|
||||
{
|
||||
_ARGCHK(keysize != NULL);
|
||||
if (*keysize < 16) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
} else {
|
||||
*keysize = 16;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int safer_k64_test(void)
|
||||
{
|
||||
static const unsigned char k64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
|
||||
k64_key[] = { 8, 7, 6, 5, 4, 3, 2, 1 },
|
||||
k64_ct[] = { 200, 242, 156, 221, 135, 120, 62, 217 };
|
||||
|
||||
symmetric_key skey;
|
||||
unsigned char buf[2][8];
|
||||
int errno;
|
||||
|
||||
/* test K64 */
|
||||
if ((errno = safer_k64_setup(k64_key, 8, 6, &skey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
safer_ecb_encrypt(k64_pt, buf[0], &skey);
|
||||
safer_ecb_decrypt(buf[0], buf[1], &skey);
|
||||
|
||||
if (memcmp(buf[0], k64_ct, 8) || memcmp(buf[1], k64_pt, 8)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
int safer_sk64_test(void)
|
||||
{
|
||||
static const unsigned char sk64_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
|
||||
sk64_key[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
|
||||
sk64_ct[] = { 95, 206, 155, 162, 5, 132, 56, 199 };
|
||||
|
||||
symmetric_key skey;
|
||||
unsigned char buf[2][8];
|
||||
int errno;
|
||||
|
||||
/* test SK64 */
|
||||
if ((errno = safer_sk64_setup(sk64_key, 8, 6, &skey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
safer_ecb_encrypt(sk64_pt, buf[0], &skey);
|
||||
safer_ecb_decrypt(buf[0], buf[1], &skey);
|
||||
|
||||
if (memcmp(buf[0], sk64_ct, 8) || memcmp(buf[1], sk64_pt, 8)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int safer_sk128_test(void)
|
||||
{
|
||||
static const unsigned char sk128_pt[] = { 1, 2, 3, 4, 5, 6, 7, 8 },
|
||||
sk128_key[] = { 1, 2, 3, 4, 5, 6, 7, 8,
|
||||
0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
sk128_ct[] = { 255, 120, 17, 228, 179, 167, 46, 113 };
|
||||
|
||||
symmetric_key skey;
|
||||
unsigned char buf[2][8];
|
||||
int errno;
|
||||
|
||||
/* test SK128 */
|
||||
if ((errno = safer_sk128_setup(sk128_key, 16, 0, &skey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
safer_ecb_encrypt(sk128_pt, buf[0], &skey);
|
||||
safer_ecb_decrypt(buf[0], buf[1], &skey);
|
||||
|
||||
if (memcmp(buf[0], sk128_ct, 8) || memcmp(buf[1], sk128_pt, 8)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
48
safer_tab.c
Normal file
48
safer_tab.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#if defined(SAFERP) || defined(SAFER)
|
||||
|
||||
/* This is the box defined by ebox[x] = 45^x mod 257.
|
||||
* Its assumed that the value "256" corresponds to zero. */
|
||||
const unsigned char safer_ebox[256] = {
|
||||
1, 45, 226, 147, 190, 69, 21, 174, 120, 3, 135, 164, 184, 56, 207, 63,
|
||||
8, 103, 9, 148, 235, 38, 168, 107, 189, 24, 52, 27, 187, 191, 114, 247,
|
||||
64, 53, 72, 156, 81, 47, 59, 85, 227, 192, 159, 216, 211, 243, 141, 177,
|
||||
255, 167, 62, 220, 134, 119, 215, 166, 17, 251, 244, 186, 146, 145, 100, 131,
|
||||
241, 51, 239, 218, 44, 181, 178, 43, 136, 209, 153, 203, 140, 132, 29, 20,
|
||||
129, 151, 113, 202, 95, 163, 139, 87, 60, 130, 196, 82, 92, 28, 232, 160,
|
||||
4, 180, 133, 74, 246, 19, 84, 182, 223, 12, 26, 142, 222, 224, 57, 252,
|
||||
32, 155, 36, 78, 169, 152, 158, 171, 242, 96, 208, 108, 234, 250, 199, 217,
|
||||
0, 212, 31, 110, 67, 188, 236, 83, 137, 254, 122, 93, 73, 201, 50, 194,
|
||||
249, 154, 248, 109, 22, 219, 89, 150, 68, 233, 205, 230, 70, 66, 143, 10,
|
||||
193, 204, 185, 101, 176, 210, 198, 172, 30, 65, 98, 41, 46, 14, 116, 80,
|
||||
2, 90, 195, 37, 123, 138, 42, 91, 240, 6, 13, 71, 111, 112, 157, 126,
|
||||
16, 206, 18, 39, 213, 76, 79, 214, 121, 48, 104, 54, 117, 125, 228, 237,
|
||||
128, 106, 144, 55, 162, 94, 118, 170, 197, 127, 61, 175, 165, 229, 25, 97,
|
||||
253, 77, 124, 183, 11, 238, 173, 75, 34, 245, 231, 115, 35, 33, 200, 5,
|
||||
225, 102, 221, 179, 88, 105, 99, 86, 15, 161, 49, 149, 23, 7, 58, 40
|
||||
};
|
||||
|
||||
/* This is the inverse of ebox or the base 45 logarithm */
|
||||
const unsigned char safer_lbox[256] = {
|
||||
128, 0, 176, 9, 96, 239, 185, 253, 16, 18, 159, 228, 105, 186, 173, 248,
|
||||
192, 56, 194, 101, 79, 6, 148, 252, 25, 222, 106, 27, 93, 78, 168, 130,
|
||||
112, 237, 232, 236, 114, 179, 21, 195, 255, 171, 182, 71, 68, 1, 172, 37,
|
||||
201, 250, 142, 65, 26, 33, 203, 211, 13, 110, 254, 38, 88, 218, 50, 15,
|
||||
32, 169, 157, 132, 152, 5, 156, 187, 34, 140, 99, 231, 197, 225, 115, 198,
|
||||
175, 36, 91, 135, 102, 39, 247, 87, 244, 150, 177, 183, 92, 139, 213, 84,
|
||||
121, 223, 170, 246, 62, 163, 241, 17, 202, 245, 209, 23, 123, 147, 131, 188,
|
||||
189, 82, 30, 235, 174, 204, 214, 53, 8, 200, 138, 180, 226, 205, 191, 217,
|
||||
208, 80, 89, 63, 77, 98, 52, 10, 72, 136, 181, 86, 76, 46, 107, 158,
|
||||
210, 61, 60, 3, 19, 251, 151, 81, 117, 74, 145, 113, 35, 190, 118, 42,
|
||||
95, 249, 212, 85, 11, 220, 55, 49, 22, 116, 215, 119, 167, 230, 7, 219,
|
||||
164, 47, 70, 243, 97, 69, 103, 227, 12, 162, 59, 28, 133, 24, 4, 29,
|
||||
41, 160, 143, 178, 90, 216, 166, 126, 238, 141, 83, 75, 161, 154, 193, 14,
|
||||
122, 73, 165, 44, 129, 196, 199, 54, 43, 127, 67, 149, 51, 242, 108, 104,
|
||||
109, 240, 2, 40, 206, 221, 155, 234, 94, 153, 124, 20, 134, 207, 229, 66,
|
||||
184, 64, 120, 45, 58, 233, 100, 31, 146, 144, 125, 57, 111, 224, 137, 48
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
719
serpent.c
Normal file
719
serpent.c
Normal file
@ -0,0 +1,719 @@
|
||||
#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++] = 0x01;
|
||||
while (x < 32) {
|
||||
buf[x++] = 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)
|
||||
{
|
||||
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, failed, errno;
|
||||
symmetric_key key;
|
||||
|
||||
for (x = failed = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
|
||||
/* setup key */
|
||||
if ((errno = serpent_setup(tests[x].key, tests[x].keylen, 0, &key))!= CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* 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)) {
|
||||
#if 0
|
||||
int y;
|
||||
printf("\nEncrypt test %d failed\n", x);
|
||||
for (y = 0; y < 16; y++) printf("%02x ", buf[0][y]);
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
if (memcmp(buf[1], tests[x].pt, 16)) {
|
||||
#if 0
|
||||
int y;
|
||||
printf("\nDecrypt test %d failed\n", x);
|
||||
for (y = 0; y < 16; y++) printf("%02x ", buf[1][y]);
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
|
232
sha1.c
Normal file
232
sha1.c
Normal file
@ -0,0 +1,232 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef SHA1
|
||||
|
||||
const struct _hash_descriptor sha1_desc =
|
||||
{
|
||||
"sha1",
|
||||
2,
|
||||
20,
|
||||
64,
|
||||
&sha1_init,
|
||||
&sha1_process,
|
||||
&sha1_done,
|
||||
&sha1_test
|
||||
};
|
||||
|
||||
#define F0(x,y,z) ( (x&y) | ((~x)&z) )
|
||||
#define F1(x,y,z) (x ^ y ^ z)
|
||||
#define F2(x,y,z) ((x & y) | (z & (x | y)))
|
||||
#define F3(x,y,z) (x ^ y ^ z)
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _sha1_compress(hash_state *md)
|
||||
#else
|
||||
static void sha1_compress(hash_state *md)
|
||||
#endif
|
||||
{
|
||||
unsigned long a,b,c,d,e,W[80],i,j;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD32H(W[i], md->sha1.buf + (4*i));
|
||||
}
|
||||
|
||||
/* copy state */
|
||||
a = md->sha1.state[0];
|
||||
b = md->sha1.state[1];
|
||||
c = md->sha1.state[2];
|
||||
d = md->sha1.state[3];
|
||||
e = md->sha1.state[4];
|
||||
|
||||
/* expand it */
|
||||
for (i = 16; i < 80; i++) {
|
||||
j = W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
|
||||
W[i] = ROL(j, 1);
|
||||
}
|
||||
|
||||
/* compress */
|
||||
/* round one */
|
||||
for (i = 0; i < 20; i++) {
|
||||
j = (ROL(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL);
|
||||
e = d;
|
||||
d = c;
|
||||
c = ROL(b, 30);
|
||||
b = a;
|
||||
a = j;
|
||||
}
|
||||
|
||||
/* round two */
|
||||
for (i = 20; i < 40; i++) {
|
||||
j = (ROL(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL);
|
||||
e = d;
|
||||
d = c;
|
||||
c = ROL(b, 30);
|
||||
b = a;
|
||||
a = j;
|
||||
}
|
||||
|
||||
/* round three */
|
||||
for (i = 40; i < 60; i++) {
|
||||
j = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL);
|
||||
e = d;
|
||||
d = c;
|
||||
c = ROL(b, 30);
|
||||
b = a;
|
||||
a = j;
|
||||
}
|
||||
|
||||
/* round four */
|
||||
for (i = 60; i < 80; i++) {
|
||||
j = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL);
|
||||
e = d;
|
||||
d = c;
|
||||
c = ROL(b, 30);
|
||||
b = a;
|
||||
a = j;
|
||||
}
|
||||
|
||||
/* store */
|
||||
md->sha1.state[0] = md->sha1.state[0] + a;
|
||||
md->sha1.state[1] = md->sha1.state[1] + b;
|
||||
md->sha1.state[2] = md->sha1.state[2] + c;
|
||||
md->sha1.state[3] = md->sha1.state[3] + d;
|
||||
md->sha1.state[4] = md->sha1.state[4] + e;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void sha1_compress(hash_state *md)
|
||||
{
|
||||
_sha1_compress(md);
|
||||
burn_stack(sizeof(unsigned long) * 87);
|
||||
}
|
||||
#endif
|
||||
|
||||
void sha1_init(hash_state * md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
md->sha1.state[0] = 0x67452301UL;
|
||||
md->sha1.state[1] = 0xefcdab89UL;
|
||||
md->sha1.state[2] = 0x98badcfeUL;
|
||||
md->sha1.state[3] = 0x10325476UL;
|
||||
md->sha1.state[4] = 0xc3d2e1f0UL;
|
||||
md->sha1.curlen = 0;
|
||||
md->sha1.length = 0;
|
||||
}
|
||||
|
||||
void sha1_process(hash_state * md, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long n;
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
|
||||
while (len) {
|
||||
n = MIN(len, (64 - md->sha1.curlen));
|
||||
memcpy(md->sha1.buf + md->sha1.curlen, buf, n);
|
||||
md->sha1.curlen += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
|
||||
/* is 64 bytes full? */
|
||||
if (md->sha1.curlen == 64) {
|
||||
sha1_compress(md);
|
||||
md->sha1.length += 512;
|
||||
md->sha1.curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sha1_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
int i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* increase the length of the message */
|
||||
md->sha1.length += md->sha1.curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->sha1.buf[md->sha1.curlen++] = 0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->sha1.curlen > 56) {
|
||||
while (md->sha1.curlen < 64) {
|
||||
md->sha1.buf[md->sha1.curlen++] = 0;
|
||||
}
|
||||
sha1_compress(md);
|
||||
md->sha1.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (md->sha1.curlen < 56) {
|
||||
md->sha1.buf[md->sha1.curlen++] = 0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64H(md->sha1.length, md->sha1.buf+56);
|
||||
sha1_compress(md);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 5; i++) {
|
||||
STORE32H(md->sha1.state[i], hash+(4*i));
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
}
|
||||
|
||||
int sha1_test(void)
|
||||
{
|
||||
static const struct {
|
||||
unsigned char *msg;
|
||||
unsigned char hash[20];
|
||||
} tests[] = {
|
||||
{ "abc",
|
||||
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
|
||||
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
|
||||
0x9c, 0xd0, 0xd8, 0x9d }
|
||||
},
|
||||
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
|
||||
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
|
||||
0xE5, 0x46, 0x70, 0xF1 }
|
||||
},
|
||||
{ NULL, { 0 }}
|
||||
};
|
||||
|
||||
int failed, i;
|
||||
unsigned char tmp[20];
|
||||
hash_state md;
|
||||
|
||||
for (failed = i = 0; tests[i].msg != NULL; i++) {
|
||||
sha1_init(&md);
|
||||
sha1_process(&md, tests[i].msg, strlen(tests[i].msg));
|
||||
sha1_done(&md, tmp);
|
||||
if (memcmp(tmp, tests[i].hash, 20)) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("\nSHA-1 Test %d failed\nGot (as a result): ", i);
|
||||
for (j = 0; j < 20; j++) {
|
||||
printf("%02x ", tmp[j]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
229
sha256.c
Normal file
229
sha256.c
Normal file
@ -0,0 +1,229 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef SHA256
|
||||
|
||||
const struct _hash_descriptor sha256_desc =
|
||||
{
|
||||
"sha256",
|
||||
0,
|
||||
32,
|
||||
64,
|
||||
&sha256_init,
|
||||
&sha256_process,
|
||||
&sha256_done,
|
||||
&sha256_test
|
||||
};
|
||||
|
||||
/* the K array */
|
||||
static const unsigned long K[64] = {
|
||||
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
|
||||
0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
|
||||
0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
|
||||
0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
|
||||
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
|
||||
0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
|
||||
0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
|
||||
0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
|
||||
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
|
||||
0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
|
||||
0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
|
||||
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
|
||||
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
|
||||
};
|
||||
|
||||
/* Various logical functions */
|
||||
#define Ch(x,y,z) ((x & y) ^ (~x & z))
|
||||
#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
|
||||
#define S(x, n) ROR((x),(n))
|
||||
#define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
|
||||
#define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
|
||||
#define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
|
||||
#define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
|
||||
#define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
|
||||
|
||||
/* compress 512-bits */
|
||||
#ifdef CLEAN_STACK
|
||||
static void _sha256_compress(hash_state * md)
|
||||
#else
|
||||
static void sha256_compress(hash_state * md)
|
||||
#endif
|
||||
{
|
||||
unsigned long S[8], W[64], t0, t1;
|
||||
int i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
/* copy state into S */
|
||||
for (i = 0; i < 8; i++)
|
||||
S[i] = md->sha256.state[i];
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD32H(W[i], md->sha256.buf + (4*i));
|
||||
}
|
||||
|
||||
/* fill W[16..63] */
|
||||
for (i = 16; i < 64; i++)
|
||||
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
|
||||
|
||||
/* Compress */
|
||||
for (i = 0; i < 64; i++) {
|
||||
t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
|
||||
t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
|
||||
S[7] = S[6];
|
||||
S[6] = S[5];
|
||||
S[5] = S[4];
|
||||
S[4] = S[3] + t0;
|
||||
S[3] = S[2];
|
||||
S[2] = S[1];
|
||||
S[1] = S[0];
|
||||
S[0] = t0 + t1;
|
||||
}
|
||||
|
||||
/* feedback */
|
||||
for (i = 0; i < 8; i++) {
|
||||
md->sha256.state[i] = md->sha256.state[i] + S[i];
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void sha256_compress(hash_state * md)
|
||||
{
|
||||
_sha256_compress(md);
|
||||
burn_stack(sizeof(unsigned long) * 74);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* init the sha256 state */
|
||||
void sha256_init(hash_state * md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
md->sha256.curlen = 0;
|
||||
md->sha256.length = 0;
|
||||
md->sha256.state[0] = 0x6A09E667UL;
|
||||
md->sha256.state[1] = 0xBB67AE85UL;
|
||||
md->sha256.state[2] = 0x3C6EF372UL;
|
||||
md->sha256.state[3] = 0xA54FF53AUL;
|
||||
md->sha256.state[4] = 0x510E527FUL;
|
||||
md->sha256.state[5] = 0x9B05688CUL;
|
||||
md->sha256.state[6] = 0x1F83D9ABUL;
|
||||
md->sha256.state[7] = 0x5BE0CD19UL;
|
||||
}
|
||||
|
||||
void sha256_process(hash_state * md, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long n;
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
|
||||
while (len) {
|
||||
n = MIN(len, (64 - md->sha256.curlen));
|
||||
memcpy(md->sha256.buf + md->sha256.curlen, buf, n);
|
||||
md->sha256.curlen += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
|
||||
/* is 64 bytes full? */
|
||||
if (md->sha256.curlen == 64) {
|
||||
sha256_compress(md);
|
||||
md->sha256.length += 512;
|
||||
md->sha256.curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sha256_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
int i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* increase the length of the message */
|
||||
md->sha256.length += md->sha256.curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->sha256.buf[md->sha256.curlen++] = 0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->sha256.curlen > 56) {
|
||||
while (md->sha256.curlen < 64) {
|
||||
md->sha256.buf[md->sha256.curlen++] = 0;
|
||||
}
|
||||
sha256_compress(md);
|
||||
md->sha256.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (md->sha256.curlen < 56) {
|
||||
md->sha256.buf[md->sha256.curlen++] = 0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64H(md->sha256.length, md->sha256.buf+56);
|
||||
sha256_compress(md);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 8; i++) {
|
||||
STORE32H(md->sha256.state[i], hash+(4*i));
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
}
|
||||
|
||||
int sha256_test(void)
|
||||
{
|
||||
static const struct {
|
||||
unsigned char *msg;
|
||||
unsigned char hash[32];
|
||||
} tests[] = {
|
||||
{ "abc",
|
||||
{ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
|
||||
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
|
||||
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
|
||||
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }
|
||||
},
|
||||
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
|
||||
{ 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8,
|
||||
0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39,
|
||||
0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67,
|
||||
0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 }
|
||||
},
|
||||
{ NULL, { 0 } }
|
||||
};
|
||||
|
||||
int failed, i;
|
||||
unsigned char tmp[32];
|
||||
hash_state md;
|
||||
|
||||
for (failed = i = 0; tests[i].msg != NULL; i++) {
|
||||
sha256_init(&md);
|
||||
sha256_process(&md, tests[i].msg, strlen(tests[i].msg));
|
||||
sha256_done(&md, tmp);
|
||||
if (memcmp(tmp, tests[i].hash, 32)) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("\nSHA-256 Test %d failed\nGot (as a result): ", i);
|
||||
for (j = 0; j < 32; j++) {
|
||||
printf("%02x ", tmp[j]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
107
sha384.c
Normal file
107
sha384.c
Normal file
@ -0,0 +1,107 @@
|
||||
/* included in sha512.c */
|
||||
|
||||
const struct _hash_descriptor sha384_desc =
|
||||
{
|
||||
"sha384",
|
||||
4,
|
||||
48,
|
||||
128,
|
||||
&sha384_init,
|
||||
&sha384_process,
|
||||
&sha384_done,
|
||||
&sha384_test
|
||||
};
|
||||
|
||||
void sha384_init(hash_state * md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
md->sha512.curlen = 0;
|
||||
md->sha512.length = 0;
|
||||
md->sha512.state[0] = CONST64(0xcbbb9d5dc1059ed8);
|
||||
md->sha512.state[1] = CONST64(0x629a292a367cd507);
|
||||
md->sha512.state[2] = CONST64(0x9159015a3070dd17);
|
||||
md->sha512.state[3] = CONST64(0x152fecd8f70e5939);
|
||||
md->sha512.state[4] = CONST64(0x67332667ffc00b31);
|
||||
md->sha512.state[5] = CONST64(0x8eb44a8768581511);
|
||||
md->sha512.state[6] = CONST64(0xdb0c2e0d64f98fa7);
|
||||
md->sha512.state[7] = CONST64(0x47b5481dbefa4fa4);
|
||||
}
|
||||
|
||||
void sha384_process(hash_state * md, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
sha512_process(md, buf, len);
|
||||
}
|
||||
|
||||
void sha384_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
unsigned char buf[64];
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
sha512_done(md, buf);
|
||||
memcpy(hash, buf, 48);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
}
|
||||
|
||||
int sha384_test(void)
|
||||
{
|
||||
static const struct {
|
||||
unsigned char *msg;
|
||||
unsigned char hash[48];
|
||||
} tests[] = {
|
||||
{ "abc",
|
||||
{ 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b,
|
||||
0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07,
|
||||
0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
|
||||
0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed,
|
||||
0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23,
|
||||
0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 }
|
||||
},
|
||||
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
|
||||
{ 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8,
|
||||
0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47,
|
||||
0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2,
|
||||
0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12,
|
||||
0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9,
|
||||
0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 }
|
||||
},
|
||||
{ NULL, { 0 }}
|
||||
};
|
||||
|
||||
int failed, i;
|
||||
unsigned char tmp[48];
|
||||
hash_state md;
|
||||
|
||||
for (failed = i = 0; tests[i].msg != NULL; i++) {
|
||||
sha384_init(&md);
|
||||
sha384_process(&md, tests[i].msg, strlen(tests[i].msg));
|
||||
sha384_done(&md, tmp);
|
||||
if (memcmp(tmp, tests[i].hash, 48)) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("\nSHA-384 Test %d failed\nGot (as a result): ", i);
|
||||
for (j = 0; j < 48; j++) {
|
||||
printf("%02x ", tmp[j]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
272
sha512.c
Normal file
272
sha512.c
Normal file
@ -0,0 +1,272 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef SHA512
|
||||
|
||||
const struct _hash_descriptor sha512_desc =
|
||||
{
|
||||
"sha512",
|
||||
5,
|
||||
64,
|
||||
128,
|
||||
&sha512_init,
|
||||
&sha512_process,
|
||||
&sha512_done,
|
||||
&sha512_test
|
||||
};
|
||||
|
||||
/* the K array */
|
||||
static const ulong64 K[80] = {
|
||||
CONST64(0x428a2f98d728ae22), CONST64(0x7137449123ef65cd),
|
||||
CONST64(0xb5c0fbcfec4d3b2f), CONST64(0xe9b5dba58189dbbc),
|
||||
CONST64(0x3956c25bf348b538), CONST64(0x59f111f1b605d019),
|
||||
CONST64(0x923f82a4af194f9b), CONST64(0xab1c5ed5da6d8118),
|
||||
CONST64(0xd807aa98a3030242), CONST64(0x12835b0145706fbe),
|
||||
CONST64(0x243185be4ee4b28c), CONST64(0x550c7dc3d5ffb4e2),
|
||||
CONST64(0x72be5d74f27b896f), CONST64(0x80deb1fe3b1696b1),
|
||||
CONST64(0x9bdc06a725c71235), CONST64(0xc19bf174cf692694),
|
||||
CONST64(0xe49b69c19ef14ad2), CONST64(0xefbe4786384f25e3),
|
||||
CONST64(0x0fc19dc68b8cd5b5), CONST64(0x240ca1cc77ac9c65),
|
||||
CONST64(0x2de92c6f592b0275), CONST64(0x4a7484aa6ea6e483),
|
||||
CONST64(0x5cb0a9dcbd41fbd4), CONST64(0x76f988da831153b5),
|
||||
CONST64(0x983e5152ee66dfab), CONST64(0xa831c66d2db43210),
|
||||
CONST64(0xb00327c898fb213f), CONST64(0xbf597fc7beef0ee4),
|
||||
CONST64(0xc6e00bf33da88fc2), CONST64(0xd5a79147930aa725),
|
||||
CONST64(0x06ca6351e003826f), CONST64(0x142929670a0e6e70),
|
||||
CONST64(0x27b70a8546d22ffc), CONST64(0x2e1b21385c26c926),
|
||||
CONST64(0x4d2c6dfc5ac42aed), CONST64(0x53380d139d95b3df),
|
||||
CONST64(0x650a73548baf63de), CONST64(0x766a0abb3c77b2a8),
|
||||
CONST64(0x81c2c92e47edaee6), CONST64(0x92722c851482353b),
|
||||
CONST64(0xa2bfe8a14cf10364), CONST64(0xa81a664bbc423001),
|
||||
CONST64(0xc24b8b70d0f89791), CONST64(0xc76c51a30654be30),
|
||||
CONST64(0xd192e819d6ef5218), CONST64(0xd69906245565a910),
|
||||
CONST64(0xf40e35855771202a), CONST64(0x106aa07032bbd1b8),
|
||||
CONST64(0x19a4c116b8d2d0c8), CONST64(0x1e376c085141ab53),
|
||||
CONST64(0x2748774cdf8eeb99), CONST64(0x34b0bcb5e19b48a8),
|
||||
CONST64(0x391c0cb3c5c95a63), CONST64(0x4ed8aa4ae3418acb),
|
||||
CONST64(0x5b9cca4f7763e373), CONST64(0x682e6ff3d6b2b8a3),
|
||||
CONST64(0x748f82ee5defb2fc), CONST64(0x78a5636f43172f60),
|
||||
CONST64(0x84c87814a1f0ab72), CONST64(0x8cc702081a6439ec),
|
||||
CONST64(0x90befffa23631e28), CONST64(0xa4506cebde82bde9),
|
||||
CONST64(0xbef9a3f7b2c67915), CONST64(0xc67178f2e372532b),
|
||||
CONST64(0xca273eceea26619c), CONST64(0xd186b8c721c0c207),
|
||||
CONST64(0xeada7dd6cde0eb1e), CONST64(0xf57d4f7fee6ed178),
|
||||
CONST64(0x06f067aa72176fba), CONST64(0x0a637dc5a2c898a6),
|
||||
CONST64(0x113f9804bef90dae), CONST64(0x1b710b35131c471b),
|
||||
CONST64(0x28db77f523047d84), CONST64(0x32caab7b40c72493),
|
||||
CONST64(0x3c9ebe0a15c9bebc), CONST64(0x431d67c49c100d4c),
|
||||
CONST64(0x4cc5d4becb3e42b6), CONST64(0x597f299cfc657e2a),
|
||||
CONST64(0x5fcb6fab3ad6faec), CONST64(0x6c44198c4a475817)
|
||||
};
|
||||
|
||||
/* Various logical functions */
|
||||
#define Ch(x,y,z) ((x & y) ^ (~x & z))
|
||||
#define Maj(x,y,z) ((x & y) ^ (x & z) ^ (y & z))
|
||||
#define S(x, n) ROR64((x),(n))
|
||||
#define R(x, n) (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)n))
|
||||
#define Sigma0(x) (S(x, 28) ^ S(x, 34) ^ S(x, 39))
|
||||
#define Sigma1(x) (S(x, 14) ^ S(x, 18) ^ S(x, 41))
|
||||
#define Gamma0(x) (S(x, 1) ^ S(x, 8) ^ R(x, 7))
|
||||
#define Gamma1(x) (S(x, 19) ^ S(x, 61) ^ R(x, 6))
|
||||
|
||||
/* compress 1024-bits */
|
||||
#ifdef CLEAN_STACK
|
||||
static void _sha512_compress(hash_state * md)
|
||||
#else
|
||||
static void sha512_compress(hash_state * md)
|
||||
#endif
|
||||
{
|
||||
ulong64 S[8], W[80], t0, t1;
|
||||
int i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
/* copy state into S */
|
||||
for (i = 0; i < 8; i++)
|
||||
S[i] = md->sha512.state[i];
|
||||
|
||||
/* copy the state into 1024-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD64H(W[i], md->sha512.buf + (8*i));
|
||||
}
|
||||
|
||||
/* fill W[16..79] */
|
||||
for (i = 16; i < 80; i++)
|
||||
W[i] = Gamma1(W[i - 2]) + W[i - 7] + Gamma0(W[i - 15]) + W[i - 16];
|
||||
|
||||
/* Compress */
|
||||
for (i = 0; i < 80; i++) {
|
||||
t0 = S[7] + Sigma1(S[4]) + Ch(S[4], S[5], S[6]) + K[i] + W[i];
|
||||
t1 = Sigma0(S[0]) + Maj(S[0], S[1], S[2]);
|
||||
S[7] = S[6];
|
||||
S[6] = S[5];
|
||||
S[5] = S[4];
|
||||
S[4] = S[3] + t0;
|
||||
S[3] = S[2];
|
||||
S[2] = S[1];
|
||||
S[1] = S[0];
|
||||
S[0] = t0 + t1;
|
||||
}
|
||||
|
||||
/* feedback */
|
||||
for (i = 0; i < 8; i++) {
|
||||
md->sha512.state[i] = md->sha512.state[i] + S[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* compress 1024-bits */
|
||||
#ifdef CLEAN_STACK
|
||||
static void sha512_compress(hash_state * md)
|
||||
{
|
||||
_sha512_compress(md);
|
||||
burn_stack(sizeof(ulong64) * 90 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* init the sha512 state */
|
||||
void sha512_init(hash_state * md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
md->sha512.curlen = 0;
|
||||
md->sha512.length = 0;
|
||||
md->sha512.state[0] = CONST64(0x6a09e667f3bcc908);
|
||||
md->sha512.state[1] = CONST64(0xbb67ae8584caa73b);
|
||||
md->sha512.state[2] = CONST64(0x3c6ef372fe94f82b);
|
||||
md->sha512.state[3] = CONST64(0xa54ff53a5f1d36f1);
|
||||
md->sha512.state[4] = CONST64(0x510e527fade682d1);
|
||||
md->sha512.state[5] = CONST64(0x9b05688c2b3e6c1f);
|
||||
md->sha512.state[6] = CONST64(0x1f83d9abfb41bd6b);
|
||||
md->sha512.state[7] = CONST64(0x5be0cd19137e2179);
|
||||
}
|
||||
|
||||
void sha512_process(hash_state * md, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long n;
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
while (len) {
|
||||
n = MIN(len, (128 - md->sha512.curlen));
|
||||
memcpy(md->sha512.buf + md->sha512.curlen, buf, n);
|
||||
md->sha512.curlen += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
|
||||
/* is 64 bytes full? */
|
||||
if (md->sha512.curlen == 128) {
|
||||
sha512_compress(md);
|
||||
md->sha512.length += 1024;
|
||||
md->sha512.curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sha512_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
int i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* increase the length of the message */
|
||||
md->sha512.length += md->sha512.curlen * CONST64(8);
|
||||
|
||||
/* append the '1' bit */
|
||||
md->sha512.buf[md->sha512.curlen++] = 0x80;
|
||||
|
||||
/* if the length is currently above 112 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->sha512.curlen > 112) {
|
||||
while (md->sha512.curlen < 128) {
|
||||
md->sha512.buf[md->sha512.curlen++] = 0;
|
||||
}
|
||||
sha512_compress(md);
|
||||
md->sha512.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 120 bytes of zeroes
|
||||
* note: that from 112 to 120 is the 64 MSB of the length. We assume that you won't hash
|
||||
* > 2^64 bits of data... :-)
|
||||
*/
|
||||
while (md->sha512.curlen < 120) {
|
||||
md->sha512.buf[md->sha512.curlen++] = 0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64H(md->sha512.length, md->sha512.buf+120);
|
||||
sha512_compress(md);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 8; i++) {
|
||||
STORE64H(md->sha512.state[i], hash+(8*i));
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
}
|
||||
|
||||
int sha512_test(void)
|
||||
{
|
||||
static const struct {
|
||||
unsigned char *msg;
|
||||
unsigned char hash[64];
|
||||
} tests[] = {
|
||||
{ "abc",
|
||||
{ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba,
|
||||
0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31,
|
||||
0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
|
||||
0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a,
|
||||
0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8,
|
||||
0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
|
||||
0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e,
|
||||
0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f }
|
||||
},
|
||||
{ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu",
|
||||
{ 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda,
|
||||
0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f,
|
||||
0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1,
|
||||
0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18,
|
||||
0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4,
|
||||
0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a,
|
||||
0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54,
|
||||
0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 }
|
||||
},
|
||||
{ NULL, { 0 }}
|
||||
};
|
||||
|
||||
int failed, i;
|
||||
unsigned char tmp[64];
|
||||
hash_state md;
|
||||
|
||||
for (failed = i = 0; tests[i].msg != NULL; i++) {
|
||||
sha512_init(&md);
|
||||
sha512_process(&md, tests[i].msg, strlen(tests[i].msg));
|
||||
sha512_done(&md, tmp);
|
||||
if (memcmp(tmp, tests[i].hash, 64)) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("\nSHA-512 Test %d failed\nGot (as a result): ", i);
|
||||
for (j = 0; j < 64; j++) {
|
||||
printf("%02x ", tmp[j]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SHA384
|
||||
#include "sha384.c"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
42
sprng.c
Normal file
42
sprng.c
Normal file
@ -0,0 +1,42 @@
|
||||
/* A secure PRNG using the RNG functions. Basically this is a
|
||||
* wrapper that allows you to use a secure RNG as a PRNG
|
||||
* in the various other functions.
|
||||
*/
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef SPRNG
|
||||
|
||||
const struct _prng_descriptor sprng_desc =
|
||||
{
|
||||
"sprng",
|
||||
&sprng_start,
|
||||
&sprng_add_entropy,
|
||||
&sprng_ready,
|
||||
&sprng_read
|
||||
};
|
||||
|
||||
int sprng_start(prng_state *prng)
|
||||
{
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int sprng_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
|
||||
{
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int sprng_ready(prng_state *prng)
|
||||
{
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
unsigned long sprng_read(unsigned char *buf, unsigned long len, prng_state *prng)
|
||||
{
|
||||
_ARGCHK(buf != NULL);
|
||||
return rng_get_bytes(buf, len, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
47
strings.c
Normal file
47
strings.c
Normal file
@ -0,0 +1,47 @@
|
||||
/* Future releases will make use of this */
|
||||
#include "mycrypt.h"
|
||||
|
||||
static const char *err_2_str[] =
|
||||
{
|
||||
"CRYPT_OK",
|
||||
"CRYPT_ERROR",
|
||||
|
||||
"Invalid keysize for block cipher.",
|
||||
"Invalid number of rounds for block cipher.",
|
||||
"Algorithm failed test vectors.",
|
||||
|
||||
"Buffer overflow.",
|
||||
"Invalid input packet.",
|
||||
|
||||
"Invalid number of bits for a PRNG.",
|
||||
"Error reading the PRNG.",
|
||||
|
||||
"Invalid cipher specified.",
|
||||
"Invalid hash specified.",
|
||||
"Invalid PRNG specified.",
|
||||
|
||||
"Out of memory.",
|
||||
|
||||
"Invalid PK key or key type specified for function.",
|
||||
"A private PK key is required.",
|
||||
|
||||
"Invalid argument provided.",
|
||||
|
||||
"Invalid PK type.",
|
||||
"Invalid PK system.",
|
||||
"Duplicate PK key found on keyring.",
|
||||
"Key not found in keyring.",
|
||||
"Invalid sized parameter.",
|
||||
|
||||
"Invalid size for prime."
|
||||
};
|
||||
|
||||
const char *error_to_string(int errno)
|
||||
{
|
||||
if (errno < 0 || errno > (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) {
|
||||
return "Invalid error code.";
|
||||
} else {
|
||||
return err_2_str[errno];
|
||||
}
|
||||
}
|
||||
|
775
tiger.c
Normal file
775
tiger.c
Normal file
@ -0,0 +1,775 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef TIGER
|
||||
|
||||
const struct _hash_descriptor tiger_desc =
|
||||
{
|
||||
"tiger",
|
||||
1,
|
||||
24,
|
||||
64,
|
||||
&tiger_init,
|
||||
&tiger_process,
|
||||
&tiger_done,
|
||||
&tiger_test
|
||||
};
|
||||
|
||||
#define t1 (table)
|
||||
#define t2 (table+256)
|
||||
#define t3 (table+256*2)
|
||||
#define t4 (table+256*3)
|
||||
|
||||
#define save_abc aa = a; bb = b; cc = c;
|
||||
|
||||
static const ulong64 table[4*256] = {
|
||||
CONST64(0x02AAB17CF7E90C5E) /* 0 */, CONST64(0xAC424B03E243A8EC) /* 1 */,
|
||||
CONST64(0x72CD5BE30DD5FCD3) /* 2 */, CONST64(0x6D019B93F6F97F3A) /* 3 */,
|
||||
CONST64(0xCD9978FFD21F9193) /* 4 */, CONST64(0x7573A1C9708029E2) /* 5 */,
|
||||
CONST64(0xB164326B922A83C3) /* 6 */, CONST64(0x46883EEE04915870) /* 7 */,
|
||||
CONST64(0xEAACE3057103ECE6) /* 8 */, CONST64(0xC54169B808A3535C) /* 9 */,
|
||||
CONST64(0x4CE754918DDEC47C) /* 10 */, CONST64(0x0AA2F4DFDC0DF40C) /* 11 */,
|
||||
CONST64(0x10B76F18A74DBEFA) /* 12 */, CONST64(0xC6CCB6235AD1AB6A) /* 13 */,
|
||||
CONST64(0x13726121572FE2FF) /* 14 */, CONST64(0x1A488C6F199D921E) /* 15 */,
|
||||
CONST64(0x4BC9F9F4DA0007CA) /* 16 */, CONST64(0x26F5E6F6E85241C7) /* 17 */,
|
||||
CONST64(0x859079DBEA5947B6) /* 18 */, CONST64(0x4F1885C5C99E8C92) /* 19 */,
|
||||
CONST64(0xD78E761EA96F864B) /* 20 */, CONST64(0x8E36428C52B5C17D) /* 21 */,
|
||||
CONST64(0x69CF6827373063C1) /* 22 */, CONST64(0xB607C93D9BB4C56E) /* 23 */,
|
||||
CONST64(0x7D820E760E76B5EA) /* 24 */, CONST64(0x645C9CC6F07FDC42) /* 25 */,
|
||||
CONST64(0xBF38A078243342E0) /* 26 */, CONST64(0x5F6B343C9D2E7D04) /* 27 */,
|
||||
CONST64(0xF2C28AEB600B0EC6) /* 28 */, CONST64(0x6C0ED85F7254BCAC) /* 29 */,
|
||||
CONST64(0x71592281A4DB4FE5) /* 30 */, CONST64(0x1967FA69CE0FED9F) /* 31 */,
|
||||
CONST64(0xFD5293F8B96545DB) /* 32 */, CONST64(0xC879E9D7F2A7600B) /* 33 */,
|
||||
CONST64(0x860248920193194E) /* 34 */, CONST64(0xA4F9533B2D9CC0B3) /* 35 */,
|
||||
CONST64(0x9053836C15957613) /* 36 */, CONST64(0xDB6DCF8AFC357BF1) /* 37 */,
|
||||
CONST64(0x18BEEA7A7A370F57) /* 38 */, CONST64(0x037117CA50B99066) /* 39 */,
|
||||
CONST64(0x6AB30A9774424A35) /* 40 */, CONST64(0xF4E92F02E325249B) /* 41 */,
|
||||
CONST64(0x7739DB07061CCAE1) /* 42 */, CONST64(0xD8F3B49CECA42A05) /* 43 */,
|
||||
CONST64(0xBD56BE3F51382F73) /* 44 */, CONST64(0x45FAED5843B0BB28) /* 45 */,
|
||||
CONST64(0x1C813D5C11BF1F83) /* 46 */, CONST64(0x8AF0E4B6D75FA169) /* 47 */,
|
||||
CONST64(0x33EE18A487AD9999) /* 48 */, CONST64(0x3C26E8EAB1C94410) /* 49 */,
|
||||
CONST64(0xB510102BC0A822F9) /* 50 */, CONST64(0x141EEF310CE6123B) /* 51 */,
|
||||
CONST64(0xFC65B90059DDB154) /* 52 */, CONST64(0xE0158640C5E0E607) /* 53 */,
|
||||
CONST64(0x884E079826C3A3CF) /* 54 */, CONST64(0x930D0D9523C535FD) /* 55 */,
|
||||
CONST64(0x35638D754E9A2B00) /* 56 */, CONST64(0x4085FCCF40469DD5) /* 57 */,
|
||||
CONST64(0xC4B17AD28BE23A4C) /* 58 */, CONST64(0xCAB2F0FC6A3E6A2E) /* 59 */,
|
||||
CONST64(0x2860971A6B943FCD) /* 60 */, CONST64(0x3DDE6EE212E30446) /* 61 */,
|
||||
CONST64(0x6222F32AE01765AE) /* 62 */, CONST64(0x5D550BB5478308FE) /* 63 */,
|
||||
CONST64(0xA9EFA98DA0EDA22A) /* 64 */, CONST64(0xC351A71686C40DA7) /* 65 */,
|
||||
CONST64(0x1105586D9C867C84) /* 66 */, CONST64(0xDCFFEE85FDA22853) /* 67 */,
|
||||
CONST64(0xCCFBD0262C5EEF76) /* 68 */, CONST64(0xBAF294CB8990D201) /* 69 */,
|
||||
CONST64(0xE69464F52AFAD975) /* 70 */, CONST64(0x94B013AFDF133E14) /* 71 */,
|
||||
CONST64(0x06A7D1A32823C958) /* 72 */, CONST64(0x6F95FE5130F61119) /* 73 */,
|
||||
CONST64(0xD92AB34E462C06C0) /* 74 */, CONST64(0xED7BDE33887C71D2) /* 75 */,
|
||||
CONST64(0x79746D6E6518393E) /* 76 */, CONST64(0x5BA419385D713329) /* 77 */,
|
||||
CONST64(0x7C1BA6B948A97564) /* 78 */, CONST64(0x31987C197BFDAC67) /* 79 */,
|
||||
CONST64(0xDE6C23C44B053D02) /* 80 */, CONST64(0x581C49FED002D64D) /* 81 */,
|
||||
CONST64(0xDD474D6338261571) /* 82 */, CONST64(0xAA4546C3E473D062) /* 83 */,
|
||||
CONST64(0x928FCE349455F860) /* 84 */, CONST64(0x48161BBACAAB94D9) /* 85 */,
|
||||
CONST64(0x63912430770E6F68) /* 86 */, CONST64(0x6EC8A5E602C6641C) /* 87 */,
|
||||
CONST64(0x87282515337DDD2B) /* 88 */, CONST64(0x2CDA6B42034B701B) /* 89 */,
|
||||
CONST64(0xB03D37C181CB096D) /* 90 */, CONST64(0xE108438266C71C6F) /* 91 */,
|
||||
CONST64(0x2B3180C7EB51B255) /* 92 */, CONST64(0xDF92B82F96C08BBC) /* 93 */,
|
||||
CONST64(0x5C68C8C0A632F3BA) /* 94 */, CONST64(0x5504CC861C3D0556) /* 95 */,
|
||||
CONST64(0xABBFA4E55FB26B8F) /* 96 */, CONST64(0x41848B0AB3BACEB4) /* 97 */,
|
||||
CONST64(0xB334A273AA445D32) /* 98 */, CONST64(0xBCA696F0A85AD881) /* 99 */,
|
||||
CONST64(0x24F6EC65B528D56C) /* 100 */, CONST64(0x0CE1512E90F4524A) /* 101 */,
|
||||
CONST64(0x4E9DD79D5506D35A) /* 102 */, CONST64(0x258905FAC6CE9779) /* 103 */,
|
||||
CONST64(0x2019295B3E109B33) /* 104 */, CONST64(0xF8A9478B73A054CC) /* 105 */,
|
||||
CONST64(0x2924F2F934417EB0) /* 106 */, CONST64(0x3993357D536D1BC4) /* 107 */,
|
||||
CONST64(0x38A81AC21DB6FF8B) /* 108 */, CONST64(0x47C4FBF17D6016BF) /* 109 */,
|
||||
CONST64(0x1E0FAADD7667E3F5) /* 110 */, CONST64(0x7ABCFF62938BEB96) /* 111 */,
|
||||
CONST64(0xA78DAD948FC179C9) /* 112 */, CONST64(0x8F1F98B72911E50D) /* 113 */,
|
||||
CONST64(0x61E48EAE27121A91) /* 114 */, CONST64(0x4D62F7AD31859808) /* 115 */,
|
||||
CONST64(0xECEBA345EF5CEAEB) /* 116 */, CONST64(0xF5CEB25EBC9684CE) /* 117 */,
|
||||
CONST64(0xF633E20CB7F76221) /* 118 */, CONST64(0xA32CDF06AB8293E4) /* 119 */,
|
||||
CONST64(0x985A202CA5EE2CA4) /* 120 */, CONST64(0xCF0B8447CC8A8FB1) /* 121 */,
|
||||
CONST64(0x9F765244979859A3) /* 122 */, CONST64(0xA8D516B1A1240017) /* 123 */,
|
||||
CONST64(0x0BD7BA3EBB5DC726) /* 124 */, CONST64(0xE54BCA55B86ADB39) /* 125 */,
|
||||
CONST64(0x1D7A3AFD6C478063) /* 126 */, CONST64(0x519EC608E7669EDD) /* 127 */,
|
||||
CONST64(0x0E5715A2D149AA23) /* 128 */, CONST64(0x177D4571848FF194) /* 129 */,
|
||||
CONST64(0xEEB55F3241014C22) /* 130 */, CONST64(0x0F5E5CA13A6E2EC2) /* 131 */,
|
||||
CONST64(0x8029927B75F5C361) /* 132 */, CONST64(0xAD139FABC3D6E436) /* 133 */,
|
||||
CONST64(0x0D5DF1A94CCF402F) /* 134 */, CONST64(0x3E8BD948BEA5DFC8) /* 135 */,
|
||||
CONST64(0xA5A0D357BD3FF77E) /* 136 */, CONST64(0xA2D12E251F74F645) /* 137 */,
|
||||
CONST64(0x66FD9E525E81A082) /* 138 */, CONST64(0x2E0C90CE7F687A49) /* 139 */,
|
||||
CONST64(0xC2E8BCBEBA973BC5) /* 140 */, CONST64(0x000001BCE509745F) /* 141 */,
|
||||
CONST64(0x423777BBE6DAB3D6) /* 142 */, CONST64(0xD1661C7EAEF06EB5) /* 143 */,
|
||||
CONST64(0xA1781F354DAACFD8) /* 144 */, CONST64(0x2D11284A2B16AFFC) /* 145 */,
|
||||
CONST64(0xF1FC4F67FA891D1F) /* 146 */, CONST64(0x73ECC25DCB920ADA) /* 147 */,
|
||||
CONST64(0xAE610C22C2A12651) /* 148 */, CONST64(0x96E0A810D356B78A) /* 149 */,
|
||||
CONST64(0x5A9A381F2FE7870F) /* 150 */, CONST64(0xD5AD62EDE94E5530) /* 151 */,
|
||||
CONST64(0xD225E5E8368D1427) /* 152 */, CONST64(0x65977B70C7AF4631) /* 153 */,
|
||||
CONST64(0x99F889B2DE39D74F) /* 154 */, CONST64(0x233F30BF54E1D143) /* 155 */,
|
||||
CONST64(0x9A9675D3D9A63C97) /* 156 */, CONST64(0x5470554FF334F9A8) /* 157 */,
|
||||
CONST64(0x166ACB744A4F5688) /* 158 */, CONST64(0x70C74CAAB2E4AEAD) /* 159 */,
|
||||
CONST64(0xF0D091646F294D12) /* 160 */, CONST64(0x57B82A89684031D1) /* 161 */,
|
||||
CONST64(0xEFD95A5A61BE0B6B) /* 162 */, CONST64(0x2FBD12E969F2F29A) /* 163 */,
|
||||
CONST64(0x9BD37013FEFF9FE8) /* 164 */, CONST64(0x3F9B0404D6085A06) /* 165 */,
|
||||
CONST64(0x4940C1F3166CFE15) /* 166 */, CONST64(0x09542C4DCDF3DEFB) /* 167 */,
|
||||
CONST64(0xB4C5218385CD5CE3) /* 168 */, CONST64(0xC935B7DC4462A641) /* 169 */,
|
||||
CONST64(0x3417F8A68ED3B63F) /* 170 */, CONST64(0xB80959295B215B40) /* 171 */,
|
||||
CONST64(0xF99CDAEF3B8C8572) /* 172 */, CONST64(0x018C0614F8FCB95D) /* 173 */,
|
||||
CONST64(0x1B14ACCD1A3ACDF3) /* 174 */, CONST64(0x84D471F200BB732D) /* 175 */,
|
||||
CONST64(0xC1A3110E95E8DA16) /* 176 */, CONST64(0x430A7220BF1A82B8) /* 177 */,
|
||||
CONST64(0xB77E090D39DF210E) /* 178 */, CONST64(0x5EF4BD9F3CD05E9D) /* 179 */,
|
||||
CONST64(0x9D4FF6DA7E57A444) /* 180 */, CONST64(0xDA1D60E183D4A5F8) /* 181 */,
|
||||
CONST64(0xB287C38417998E47) /* 182 */, CONST64(0xFE3EDC121BB31886) /* 183 */,
|
||||
CONST64(0xC7FE3CCC980CCBEF) /* 184 */, CONST64(0xE46FB590189BFD03) /* 185 */,
|
||||
CONST64(0x3732FD469A4C57DC) /* 186 */, CONST64(0x7EF700A07CF1AD65) /* 187 */,
|
||||
CONST64(0x59C64468A31D8859) /* 188 */, CONST64(0x762FB0B4D45B61F6) /* 189 */,
|
||||
CONST64(0x155BAED099047718) /* 190 */, CONST64(0x68755E4C3D50BAA6) /* 191 */,
|
||||
CONST64(0xE9214E7F22D8B4DF) /* 192 */, CONST64(0x2ADDBF532EAC95F4) /* 193 */,
|
||||
CONST64(0x32AE3909B4BD0109) /* 194 */, CONST64(0x834DF537B08E3450) /* 195 */,
|
||||
CONST64(0xFA209DA84220728D) /* 196 */, CONST64(0x9E691D9B9EFE23F7) /* 197 */,
|
||||
CONST64(0x0446D288C4AE8D7F) /* 198 */, CONST64(0x7B4CC524E169785B) /* 199 */,
|
||||
CONST64(0x21D87F0135CA1385) /* 200 */, CONST64(0xCEBB400F137B8AA5) /* 201 */,
|
||||
CONST64(0x272E2B66580796BE) /* 202 */, CONST64(0x3612264125C2B0DE) /* 203 */,
|
||||
CONST64(0x057702BDAD1EFBB2) /* 204 */, CONST64(0xD4BABB8EACF84BE9) /* 205 */,
|
||||
CONST64(0x91583139641BC67B) /* 206 */, CONST64(0x8BDC2DE08036E024) /* 207 */,
|
||||
CONST64(0x603C8156F49F68ED) /* 208 */, CONST64(0xF7D236F7DBEF5111) /* 209 */,
|
||||
CONST64(0x9727C4598AD21E80) /* 210 */, CONST64(0xA08A0896670A5FD7) /* 211 */,
|
||||
CONST64(0xCB4A8F4309EBA9CB) /* 212 */, CONST64(0x81AF564B0F7036A1) /* 213 */,
|
||||
CONST64(0xC0B99AA778199ABD) /* 214 */, CONST64(0x959F1EC83FC8E952) /* 215 */,
|
||||
CONST64(0x8C505077794A81B9) /* 216 */, CONST64(0x3ACAAF8F056338F0) /* 217 */,
|
||||
CONST64(0x07B43F50627A6778) /* 218 */, CONST64(0x4A44AB49F5ECCC77) /* 219 */,
|
||||
CONST64(0x3BC3D6E4B679EE98) /* 220 */, CONST64(0x9CC0D4D1CF14108C) /* 221 */,
|
||||
CONST64(0x4406C00B206BC8A0) /* 222 */, CONST64(0x82A18854C8D72D89) /* 223 */,
|
||||
CONST64(0x67E366B35C3C432C) /* 224 */, CONST64(0xB923DD61102B37F2) /* 225 */,
|
||||
CONST64(0x56AB2779D884271D) /* 226 */, CONST64(0xBE83E1B0FF1525AF) /* 227 */,
|
||||
CONST64(0xFB7C65D4217E49A9) /* 228 */, CONST64(0x6BDBE0E76D48E7D4) /* 229 */,
|
||||
CONST64(0x08DF828745D9179E) /* 230 */, CONST64(0x22EA6A9ADD53BD34) /* 231 */,
|
||||
CONST64(0xE36E141C5622200A) /* 232 */, CONST64(0x7F805D1B8CB750EE) /* 233 */,
|
||||
CONST64(0xAFE5C7A59F58E837) /* 234 */, CONST64(0xE27F996A4FB1C23C) /* 235 */,
|
||||
CONST64(0xD3867DFB0775F0D0) /* 236 */, CONST64(0xD0E673DE6E88891A) /* 237 */,
|
||||
CONST64(0x123AEB9EAFB86C25) /* 238 */, CONST64(0x30F1D5D5C145B895) /* 239 */,
|
||||
CONST64(0xBB434A2DEE7269E7) /* 240 */, CONST64(0x78CB67ECF931FA38) /* 241 */,
|
||||
CONST64(0xF33B0372323BBF9C) /* 242 */, CONST64(0x52D66336FB279C74) /* 243 */,
|
||||
CONST64(0x505F33AC0AFB4EAA) /* 244 */, CONST64(0xE8A5CD99A2CCE187) /* 245 */,
|
||||
CONST64(0x534974801E2D30BB) /* 246 */, CONST64(0x8D2D5711D5876D90) /* 247 */,
|
||||
CONST64(0x1F1A412891BC038E) /* 248 */, CONST64(0xD6E2E71D82E56648) /* 249 */,
|
||||
CONST64(0x74036C3A497732B7) /* 250 */, CONST64(0x89B67ED96361F5AB) /* 251 */,
|
||||
CONST64(0xFFED95D8F1EA02A2) /* 252 */, CONST64(0xE72B3BD61464D43D) /* 253 */,
|
||||
CONST64(0xA6300F170BDC4820) /* 254 */, CONST64(0xEBC18760ED78A77A) /* 255 */,
|
||||
CONST64(0xE6A6BE5A05A12138) /* 256 */, CONST64(0xB5A122A5B4F87C98) /* 257 */,
|
||||
CONST64(0x563C6089140B6990) /* 258 */, CONST64(0x4C46CB2E391F5DD5) /* 259 */,
|
||||
CONST64(0xD932ADDBC9B79434) /* 260 */, CONST64(0x08EA70E42015AFF5) /* 261 */,
|
||||
CONST64(0xD765A6673E478CF1) /* 262 */, CONST64(0xC4FB757EAB278D99) /* 263 */,
|
||||
CONST64(0xDF11C6862D6E0692) /* 264 */, CONST64(0xDDEB84F10D7F3B16) /* 265 */,
|
||||
CONST64(0x6F2EF604A665EA04) /* 266 */, CONST64(0x4A8E0F0FF0E0DFB3) /* 267 */,
|
||||
CONST64(0xA5EDEEF83DBCBA51) /* 268 */, CONST64(0xFC4F0A2A0EA4371E) /* 269 */,
|
||||
CONST64(0xE83E1DA85CB38429) /* 270 */, CONST64(0xDC8FF882BA1B1CE2) /* 271 */,
|
||||
CONST64(0xCD45505E8353E80D) /* 272 */, CONST64(0x18D19A00D4DB0717) /* 273 */,
|
||||
CONST64(0x34A0CFEDA5F38101) /* 274 */, CONST64(0x0BE77E518887CAF2) /* 275 */,
|
||||
CONST64(0x1E341438B3C45136) /* 276 */, CONST64(0xE05797F49089CCF9) /* 277 */,
|
||||
CONST64(0xFFD23F9DF2591D14) /* 278 */, CONST64(0x543DDA228595C5CD) /* 279 */,
|
||||
CONST64(0x661F81FD99052A33) /* 280 */, CONST64(0x8736E641DB0F7B76) /* 281 */,
|
||||
CONST64(0x15227725418E5307) /* 282 */, CONST64(0xE25F7F46162EB2FA) /* 283 */,
|
||||
CONST64(0x48A8B2126C13D9FE) /* 284 */, CONST64(0xAFDC541792E76EEA) /* 285 */,
|
||||
CONST64(0x03D912BFC6D1898F) /* 286 */, CONST64(0x31B1AAFA1B83F51B) /* 287 */,
|
||||
CONST64(0xF1AC2796E42AB7D9) /* 288 */, CONST64(0x40A3A7D7FCD2EBAC) /* 289 */,
|
||||
CONST64(0x1056136D0AFBBCC5) /* 290 */, CONST64(0x7889E1DD9A6D0C85) /* 291 */,
|
||||
CONST64(0xD33525782A7974AA) /* 292 */, CONST64(0xA7E25D09078AC09B) /* 293 */,
|
||||
CONST64(0xBD4138B3EAC6EDD0) /* 294 */, CONST64(0x920ABFBE71EB9E70) /* 295 */,
|
||||
CONST64(0xA2A5D0F54FC2625C) /* 296 */, CONST64(0xC054E36B0B1290A3) /* 297 */,
|
||||
CONST64(0xF6DD59FF62FE932B) /* 298 */, CONST64(0x3537354511A8AC7D) /* 299 */,
|
||||
CONST64(0xCA845E9172FADCD4) /* 300 */, CONST64(0x84F82B60329D20DC) /* 301 */,
|
||||
CONST64(0x79C62CE1CD672F18) /* 302 */, CONST64(0x8B09A2ADD124642C) /* 303 */,
|
||||
CONST64(0xD0C1E96A19D9E726) /* 304 */, CONST64(0x5A786A9B4BA9500C) /* 305 */,
|
||||
CONST64(0x0E020336634C43F3) /* 306 */, CONST64(0xC17B474AEB66D822) /* 307 */,
|
||||
CONST64(0x6A731AE3EC9BAAC2) /* 308 */, CONST64(0x8226667AE0840258) /* 309 */,
|
||||
CONST64(0x67D4567691CAECA5) /* 310 */, CONST64(0x1D94155C4875ADB5) /* 311 */,
|
||||
CONST64(0x6D00FD985B813FDF) /* 312 */, CONST64(0x51286EFCB774CD06) /* 313 */,
|
||||
CONST64(0x5E8834471FA744AF) /* 314 */, CONST64(0xF72CA0AEE761AE2E) /* 315 */,
|
||||
CONST64(0xBE40E4CDAEE8E09A) /* 316 */, CONST64(0xE9970BBB5118F665) /* 317 */,
|
||||
CONST64(0x726E4BEB33DF1964) /* 318 */, CONST64(0x703B000729199762) /* 319 */,
|
||||
CONST64(0x4631D816F5EF30A7) /* 320 */, CONST64(0xB880B5B51504A6BE) /* 321 */,
|
||||
CONST64(0x641793C37ED84B6C) /* 322 */, CONST64(0x7B21ED77F6E97D96) /* 323 */,
|
||||
CONST64(0x776306312EF96B73) /* 324 */, CONST64(0xAE528948E86FF3F4) /* 325 */,
|
||||
CONST64(0x53DBD7F286A3F8F8) /* 326 */, CONST64(0x16CADCE74CFC1063) /* 327 */,
|
||||
CONST64(0x005C19BDFA52C6DD) /* 328 */, CONST64(0x68868F5D64D46AD3) /* 329 */,
|
||||
CONST64(0x3A9D512CCF1E186A) /* 330 */, CONST64(0x367E62C2385660AE) /* 331 */,
|
||||
CONST64(0xE359E7EA77DCB1D7) /* 332 */, CONST64(0x526C0773749ABE6E) /* 333 */,
|
||||
CONST64(0x735AE5F9D09F734B) /* 334 */, CONST64(0x493FC7CC8A558BA8) /* 335 */,
|
||||
CONST64(0xB0B9C1533041AB45) /* 336 */, CONST64(0x321958BA470A59BD) /* 337 */,
|
||||
CONST64(0x852DB00B5F46C393) /* 338 */, CONST64(0x91209B2BD336B0E5) /* 339 */,
|
||||
CONST64(0x6E604F7D659EF19F) /* 340 */, CONST64(0xB99A8AE2782CCB24) /* 341 */,
|
||||
CONST64(0xCCF52AB6C814C4C7) /* 342 */, CONST64(0x4727D9AFBE11727B) /* 343 */,
|
||||
CONST64(0x7E950D0C0121B34D) /* 344 */, CONST64(0x756F435670AD471F) /* 345 */,
|
||||
CONST64(0xF5ADD442615A6849) /* 346 */, CONST64(0x4E87E09980B9957A) /* 347 */,
|
||||
CONST64(0x2ACFA1DF50AEE355) /* 348 */, CONST64(0xD898263AFD2FD556) /* 349 */,
|
||||
CONST64(0xC8F4924DD80C8FD6) /* 350 */, CONST64(0xCF99CA3D754A173A) /* 351 */,
|
||||
CONST64(0xFE477BACAF91BF3C) /* 352 */, CONST64(0xED5371F6D690C12D) /* 353 */,
|
||||
CONST64(0x831A5C285E687094) /* 354 */, CONST64(0xC5D3C90A3708A0A4) /* 355 */,
|
||||
CONST64(0x0F7F903717D06580) /* 356 */, CONST64(0x19F9BB13B8FDF27F) /* 357 */,
|
||||
CONST64(0xB1BD6F1B4D502843) /* 358 */, CONST64(0x1C761BA38FFF4012) /* 359 */,
|
||||
CONST64(0x0D1530C4E2E21F3B) /* 360 */, CONST64(0x8943CE69A7372C8A) /* 361 */,
|
||||
CONST64(0xE5184E11FEB5CE66) /* 362 */, CONST64(0x618BDB80BD736621) /* 363 */,
|
||||
CONST64(0x7D29BAD68B574D0B) /* 364 */, CONST64(0x81BB613E25E6FE5B) /* 365 */,
|
||||
CONST64(0x071C9C10BC07913F) /* 366 */, CONST64(0xC7BEEB7909AC2D97) /* 367 */,
|
||||
CONST64(0xC3E58D353BC5D757) /* 368 */, CONST64(0xEB017892F38F61E8) /* 369 */,
|
||||
CONST64(0xD4EFFB9C9B1CC21A) /* 370 */, CONST64(0x99727D26F494F7AB) /* 371 */,
|
||||
CONST64(0xA3E063A2956B3E03) /* 372 */, CONST64(0x9D4A8B9A4AA09C30) /* 373 */,
|
||||
CONST64(0x3F6AB7D500090FB4) /* 374 */, CONST64(0x9CC0F2A057268AC0) /* 375 */,
|
||||
CONST64(0x3DEE9D2DEDBF42D1) /* 376 */, CONST64(0x330F49C87960A972) /* 377 */,
|
||||
CONST64(0xC6B2720287421B41) /* 378 */, CONST64(0x0AC59EC07C00369C) /* 379 */,
|
||||
CONST64(0xEF4EAC49CB353425) /* 380 */, CONST64(0xF450244EEF0129D8) /* 381 */,
|
||||
CONST64(0x8ACC46E5CAF4DEB6) /* 382 */, CONST64(0x2FFEAB63989263F7) /* 383 */,
|
||||
CONST64(0x8F7CB9FE5D7A4578) /* 384 */, CONST64(0x5BD8F7644E634635) /* 385 */,
|
||||
CONST64(0x427A7315BF2DC900) /* 386 */, CONST64(0x17D0C4AA2125261C) /* 387 */,
|
||||
CONST64(0x3992486C93518E50) /* 388 */, CONST64(0xB4CBFEE0A2D7D4C3) /* 389 */,
|
||||
CONST64(0x7C75D6202C5DDD8D) /* 390 */, CONST64(0xDBC295D8E35B6C61) /* 391 */,
|
||||
CONST64(0x60B369D302032B19) /* 392 */, CONST64(0xCE42685FDCE44132) /* 393 */,
|
||||
CONST64(0x06F3DDB9DDF65610) /* 394 */, CONST64(0x8EA4D21DB5E148F0) /* 395 */,
|
||||
CONST64(0x20B0FCE62FCD496F) /* 396 */, CONST64(0x2C1B912358B0EE31) /* 397 */,
|
||||
CONST64(0xB28317B818F5A308) /* 398 */, CONST64(0xA89C1E189CA6D2CF) /* 399 */,
|
||||
CONST64(0x0C6B18576AAADBC8) /* 400 */, CONST64(0xB65DEAA91299FAE3) /* 401 */,
|
||||
CONST64(0xFB2B794B7F1027E7) /* 402 */, CONST64(0x04E4317F443B5BEB) /* 403 */,
|
||||
CONST64(0x4B852D325939D0A6) /* 404 */, CONST64(0xD5AE6BEEFB207FFC) /* 405 */,
|
||||
CONST64(0x309682B281C7D374) /* 406 */, CONST64(0xBAE309A194C3B475) /* 407 */,
|
||||
CONST64(0x8CC3F97B13B49F05) /* 408 */, CONST64(0x98A9422FF8293967) /* 409 */,
|
||||
CONST64(0x244B16B01076FF7C) /* 410 */, CONST64(0xF8BF571C663D67EE) /* 411 */,
|
||||
CONST64(0x1F0D6758EEE30DA1) /* 412 */, CONST64(0xC9B611D97ADEB9B7) /* 413 */,
|
||||
CONST64(0xB7AFD5887B6C57A2) /* 414 */, CONST64(0x6290AE846B984FE1) /* 415 */,
|
||||
CONST64(0x94DF4CDEACC1A5FD) /* 416 */, CONST64(0x058A5BD1C5483AFF) /* 417 */,
|
||||
CONST64(0x63166CC142BA3C37) /* 418 */, CONST64(0x8DB8526EB2F76F40) /* 419 */,
|
||||
CONST64(0xE10880036F0D6D4E) /* 420 */, CONST64(0x9E0523C9971D311D) /* 421 */,
|
||||
CONST64(0x45EC2824CC7CD691) /* 422 */, CONST64(0x575B8359E62382C9) /* 423 */,
|
||||
CONST64(0xFA9E400DC4889995) /* 424 */, CONST64(0xD1823ECB45721568) /* 425 */,
|
||||
CONST64(0xDAFD983B8206082F) /* 426 */, CONST64(0xAA7D29082386A8CB) /* 427 */,
|
||||
CONST64(0x269FCD4403B87588) /* 428 */, CONST64(0x1B91F5F728BDD1E0) /* 429 */,
|
||||
CONST64(0xE4669F39040201F6) /* 430 */, CONST64(0x7A1D7C218CF04ADE) /* 431 */,
|
||||
CONST64(0x65623C29D79CE5CE) /* 432 */, CONST64(0x2368449096C00BB1) /* 433 */,
|
||||
CONST64(0xAB9BF1879DA503BA) /* 434 */, CONST64(0xBC23ECB1A458058E) /* 435 */,
|
||||
CONST64(0x9A58DF01BB401ECC) /* 436 */, CONST64(0xA070E868A85F143D) /* 437 */,
|
||||
CONST64(0x4FF188307DF2239E) /* 438 */, CONST64(0x14D565B41A641183) /* 439 */,
|
||||
CONST64(0xEE13337452701602) /* 440 */, CONST64(0x950E3DCF3F285E09) /* 441 */,
|
||||
CONST64(0x59930254B9C80953) /* 442 */, CONST64(0x3BF299408930DA6D) /* 443 */,
|
||||
CONST64(0xA955943F53691387) /* 444 */, CONST64(0xA15EDECAA9CB8784) /* 445 */,
|
||||
CONST64(0x29142127352BE9A0) /* 446 */, CONST64(0x76F0371FFF4E7AFB) /* 447 */,
|
||||
CONST64(0x0239F450274F2228) /* 448 */, CONST64(0xBB073AF01D5E868B) /* 449 */,
|
||||
CONST64(0xBFC80571C10E96C1) /* 450 */, CONST64(0xD267088568222E23) /* 451 */,
|
||||
CONST64(0x9671A3D48E80B5B0) /* 452 */, CONST64(0x55B5D38AE193BB81) /* 453 */,
|
||||
CONST64(0x693AE2D0A18B04B8) /* 454 */, CONST64(0x5C48B4ECADD5335F) /* 455 */,
|
||||
CONST64(0xFD743B194916A1CA) /* 456 */, CONST64(0x2577018134BE98C4) /* 457 */,
|
||||
CONST64(0xE77987E83C54A4AD) /* 458 */, CONST64(0x28E11014DA33E1B9) /* 459 */,
|
||||
CONST64(0x270CC59E226AA213) /* 460 */, CONST64(0x71495F756D1A5F60) /* 461 */,
|
||||
CONST64(0x9BE853FB60AFEF77) /* 462 */, CONST64(0xADC786A7F7443DBF) /* 463 */,
|
||||
CONST64(0x0904456173B29A82) /* 464 */, CONST64(0x58BC7A66C232BD5E) /* 465 */,
|
||||
CONST64(0xF306558C673AC8B2) /* 466 */, CONST64(0x41F639C6B6C9772A) /* 467 */,
|
||||
CONST64(0x216DEFE99FDA35DA) /* 468 */, CONST64(0x11640CC71C7BE615) /* 469 */,
|
||||
CONST64(0x93C43694565C5527) /* 470 */, CONST64(0xEA038E6246777839) /* 471 */,
|
||||
CONST64(0xF9ABF3CE5A3E2469) /* 472 */, CONST64(0x741E768D0FD312D2) /* 473 */,
|
||||
CONST64(0x0144B883CED652C6) /* 474 */, CONST64(0xC20B5A5BA33F8552) /* 475 */,
|
||||
CONST64(0x1AE69633C3435A9D) /* 476 */, CONST64(0x97A28CA4088CFDEC) /* 477 */,
|
||||
CONST64(0x8824A43C1E96F420) /* 478 */, CONST64(0x37612FA66EEEA746) /* 479 */,
|
||||
CONST64(0x6B4CB165F9CF0E5A) /* 480 */, CONST64(0x43AA1C06A0ABFB4A) /* 481 */,
|
||||
CONST64(0x7F4DC26FF162796B) /* 482 */, CONST64(0x6CBACC8E54ED9B0F) /* 483 */,
|
||||
CONST64(0xA6B7FFEFD2BB253E) /* 484 */, CONST64(0x2E25BC95B0A29D4F) /* 485 */,
|
||||
CONST64(0x86D6A58BDEF1388C) /* 486 */, CONST64(0xDED74AC576B6F054) /* 487 */,
|
||||
CONST64(0x8030BDBC2B45805D) /* 488 */, CONST64(0x3C81AF70E94D9289) /* 489 */,
|
||||
CONST64(0x3EFF6DDA9E3100DB) /* 490 */, CONST64(0xB38DC39FDFCC8847) /* 491 */,
|
||||
CONST64(0x123885528D17B87E) /* 492 */, CONST64(0xF2DA0ED240B1B642) /* 493 */,
|
||||
CONST64(0x44CEFADCD54BF9A9) /* 494 */, CONST64(0x1312200E433C7EE6) /* 495 */,
|
||||
CONST64(0x9FFCC84F3A78C748) /* 496 */, CONST64(0xF0CD1F72248576BB) /* 497 */,
|
||||
CONST64(0xEC6974053638CFE4) /* 498 */, CONST64(0x2BA7B67C0CEC4E4C) /* 499 */,
|
||||
CONST64(0xAC2F4DF3E5CE32ED) /* 500 */, CONST64(0xCB33D14326EA4C11) /* 501 */,
|
||||
CONST64(0xA4E9044CC77E58BC) /* 502 */, CONST64(0x5F513293D934FCEF) /* 503 */,
|
||||
CONST64(0x5DC9645506E55444) /* 504 */, CONST64(0x50DE418F317DE40A) /* 505 */,
|
||||
CONST64(0x388CB31A69DDE259) /* 506 */, CONST64(0x2DB4A83455820A86) /* 507 */,
|
||||
CONST64(0x9010A91E84711AE9) /* 508 */, CONST64(0x4DF7F0B7B1498371) /* 509 */,
|
||||
CONST64(0xD62A2EABC0977179) /* 510 */, CONST64(0x22FAC097AA8D5C0E) /* 511 */,
|
||||
CONST64(0xF49FCC2FF1DAF39B) /* 512 */, CONST64(0x487FD5C66FF29281) /* 513 */,
|
||||
CONST64(0xE8A30667FCDCA83F) /* 514 */, CONST64(0x2C9B4BE3D2FCCE63) /* 515 */,
|
||||
CONST64(0xDA3FF74B93FBBBC2) /* 516 */, CONST64(0x2FA165D2FE70BA66) /* 517 */,
|
||||
CONST64(0xA103E279970E93D4) /* 518 */, CONST64(0xBECDEC77B0E45E71) /* 519 */,
|
||||
CONST64(0xCFB41E723985E497) /* 520 */, CONST64(0xB70AAA025EF75017) /* 521 */,
|
||||
CONST64(0xD42309F03840B8E0) /* 522 */, CONST64(0x8EFC1AD035898579) /* 523 */,
|
||||
CONST64(0x96C6920BE2B2ABC5) /* 524 */, CONST64(0x66AF4163375A9172) /* 525 */,
|
||||
CONST64(0x2174ABDCCA7127FB) /* 526 */, CONST64(0xB33CCEA64A72FF41) /* 527 */,
|
||||
CONST64(0xF04A4933083066A5) /* 528 */, CONST64(0x8D970ACDD7289AF5) /* 529 */,
|
||||
CONST64(0x8F96E8E031C8C25E) /* 530 */, CONST64(0xF3FEC02276875D47) /* 531 */,
|
||||
CONST64(0xEC7BF310056190DD) /* 532 */, CONST64(0xF5ADB0AEBB0F1491) /* 533 */,
|
||||
CONST64(0x9B50F8850FD58892) /* 534 */, CONST64(0x4975488358B74DE8) /* 535 */,
|
||||
CONST64(0xA3354FF691531C61) /* 536 */, CONST64(0x0702BBE481D2C6EE) /* 537 */,
|
||||
CONST64(0x89FB24057DEDED98) /* 538 */, CONST64(0xAC3075138596E902) /* 539 */,
|
||||
CONST64(0x1D2D3580172772ED) /* 540 */, CONST64(0xEB738FC28E6BC30D) /* 541 */,
|
||||
CONST64(0x5854EF8F63044326) /* 542 */, CONST64(0x9E5C52325ADD3BBE) /* 543 */,
|
||||
CONST64(0x90AA53CF325C4623) /* 544 */, CONST64(0xC1D24D51349DD067) /* 545 */,
|
||||
CONST64(0x2051CFEEA69EA624) /* 546 */, CONST64(0x13220F0A862E7E4F) /* 547 */,
|
||||
CONST64(0xCE39399404E04864) /* 548 */, CONST64(0xD9C42CA47086FCB7) /* 549 */,
|
||||
CONST64(0x685AD2238A03E7CC) /* 550 */, CONST64(0x066484B2AB2FF1DB) /* 551 */,
|
||||
CONST64(0xFE9D5D70EFBF79EC) /* 552 */, CONST64(0x5B13B9DD9C481854) /* 553 */,
|
||||
CONST64(0x15F0D475ED1509AD) /* 554 */, CONST64(0x0BEBCD060EC79851) /* 555 */,
|
||||
CONST64(0xD58C6791183AB7F8) /* 556 */, CONST64(0xD1187C5052F3EEE4) /* 557 */,
|
||||
CONST64(0xC95D1192E54E82FF) /* 558 */, CONST64(0x86EEA14CB9AC6CA2) /* 559 */,
|
||||
CONST64(0x3485BEB153677D5D) /* 560 */, CONST64(0xDD191D781F8C492A) /* 561 */,
|
||||
CONST64(0xF60866BAA784EBF9) /* 562 */, CONST64(0x518F643BA2D08C74) /* 563 */,
|
||||
CONST64(0x8852E956E1087C22) /* 564 */, CONST64(0xA768CB8DC410AE8D) /* 565 */,
|
||||
CONST64(0x38047726BFEC8E1A) /* 566 */, CONST64(0xA67738B4CD3B45AA) /* 567 */,
|
||||
CONST64(0xAD16691CEC0DDE19) /* 568 */, CONST64(0xC6D4319380462E07) /* 569 */,
|
||||
CONST64(0xC5A5876D0BA61938) /* 570 */, CONST64(0x16B9FA1FA58FD840) /* 571 */,
|
||||
CONST64(0x188AB1173CA74F18) /* 572 */, CONST64(0xABDA2F98C99C021F) /* 573 */,
|
||||
CONST64(0x3E0580AB134AE816) /* 574 */, CONST64(0x5F3B05B773645ABB) /* 575 */,
|
||||
CONST64(0x2501A2BE5575F2F6) /* 576 */, CONST64(0x1B2F74004E7E8BA9) /* 577 */,
|
||||
CONST64(0x1CD7580371E8D953) /* 578 */, CONST64(0x7F6ED89562764E30) /* 579 */,
|
||||
CONST64(0xB15926FF596F003D) /* 580 */, CONST64(0x9F65293DA8C5D6B9) /* 581 */,
|
||||
CONST64(0x6ECEF04DD690F84C) /* 582 */, CONST64(0x4782275FFF33AF88) /* 583 */,
|
||||
CONST64(0xE41433083F820801) /* 584 */, CONST64(0xFD0DFE409A1AF9B5) /* 585 */,
|
||||
CONST64(0x4325A3342CDB396B) /* 586 */, CONST64(0x8AE77E62B301B252) /* 587 */,
|
||||
CONST64(0xC36F9E9F6655615A) /* 588 */, CONST64(0x85455A2D92D32C09) /* 589 */,
|
||||
CONST64(0xF2C7DEA949477485) /* 590 */, CONST64(0x63CFB4C133A39EBA) /* 591 */,
|
||||
CONST64(0x83B040CC6EBC5462) /* 592 */, CONST64(0x3B9454C8FDB326B0) /* 593 */,
|
||||
CONST64(0x56F56A9E87FFD78C) /* 594 */, CONST64(0x2DC2940D99F42BC6) /* 595 */,
|
||||
CONST64(0x98F7DF096B096E2D) /* 596 */, CONST64(0x19A6E01E3AD852BF) /* 597 */,
|
||||
CONST64(0x42A99CCBDBD4B40B) /* 598 */, CONST64(0xA59998AF45E9C559) /* 599 */,
|
||||
CONST64(0x366295E807D93186) /* 600 */, CONST64(0x6B48181BFAA1F773) /* 601 */,
|
||||
CONST64(0x1FEC57E2157A0A1D) /* 602 */, CONST64(0x4667446AF6201AD5) /* 603 */,
|
||||
CONST64(0xE615EBCACFB0F075) /* 604 */, CONST64(0xB8F31F4F68290778) /* 605 */,
|
||||
CONST64(0x22713ED6CE22D11E) /* 606 */, CONST64(0x3057C1A72EC3C93B) /* 607 */,
|
||||
CONST64(0xCB46ACC37C3F1F2F) /* 608 */, CONST64(0xDBB893FD02AAF50E) /* 609 */,
|
||||
CONST64(0x331FD92E600B9FCF) /* 610 */, CONST64(0xA498F96148EA3AD6) /* 611 */,
|
||||
CONST64(0xA8D8426E8B6A83EA) /* 612 */, CONST64(0xA089B274B7735CDC) /* 613 */,
|
||||
CONST64(0x87F6B3731E524A11) /* 614 */, CONST64(0x118808E5CBC96749) /* 615 */,
|
||||
CONST64(0x9906E4C7B19BD394) /* 616 */, CONST64(0xAFED7F7E9B24A20C) /* 617 */,
|
||||
CONST64(0x6509EADEEB3644A7) /* 618 */, CONST64(0x6C1EF1D3E8EF0EDE) /* 619 */,
|
||||
CONST64(0xB9C97D43E9798FB4) /* 620 */, CONST64(0xA2F2D784740C28A3) /* 621 */,
|
||||
CONST64(0x7B8496476197566F) /* 622 */, CONST64(0x7A5BE3E6B65F069D) /* 623 */,
|
||||
CONST64(0xF96330ED78BE6F10) /* 624 */, CONST64(0xEEE60DE77A076A15) /* 625 */,
|
||||
CONST64(0x2B4BEE4AA08B9BD0) /* 626 */, CONST64(0x6A56A63EC7B8894E) /* 627 */,
|
||||
CONST64(0x02121359BA34FEF4) /* 628 */, CONST64(0x4CBF99F8283703FC) /* 629 */,
|
||||
CONST64(0x398071350CAF30C8) /* 630 */, CONST64(0xD0A77A89F017687A) /* 631 */,
|
||||
CONST64(0xF1C1A9EB9E423569) /* 632 */, CONST64(0x8C7976282DEE8199) /* 633 */,
|
||||
CONST64(0x5D1737A5DD1F7ABD) /* 634 */, CONST64(0x4F53433C09A9FA80) /* 635 */,
|
||||
CONST64(0xFA8B0C53DF7CA1D9) /* 636 */, CONST64(0x3FD9DCBC886CCB77) /* 637 */,
|
||||
CONST64(0xC040917CA91B4720) /* 638 */, CONST64(0x7DD00142F9D1DCDF) /* 639 */,
|
||||
CONST64(0x8476FC1D4F387B58) /* 640 */, CONST64(0x23F8E7C5F3316503) /* 641 */,
|
||||
CONST64(0x032A2244E7E37339) /* 642 */, CONST64(0x5C87A5D750F5A74B) /* 643 */,
|
||||
CONST64(0x082B4CC43698992E) /* 644 */, CONST64(0xDF917BECB858F63C) /* 645 */,
|
||||
CONST64(0x3270B8FC5BF86DDA) /* 646 */, CONST64(0x10AE72BB29B5DD76) /* 647 */,
|
||||
CONST64(0x576AC94E7700362B) /* 648 */, CONST64(0x1AD112DAC61EFB8F) /* 649 */,
|
||||
CONST64(0x691BC30EC5FAA427) /* 650 */, CONST64(0xFF246311CC327143) /* 651 */,
|
||||
CONST64(0x3142368E30E53206) /* 652 */, CONST64(0x71380E31E02CA396) /* 653 */,
|
||||
CONST64(0x958D5C960AAD76F1) /* 654 */, CONST64(0xF8D6F430C16DA536) /* 655 */,
|
||||
CONST64(0xC8FFD13F1BE7E1D2) /* 656 */, CONST64(0x7578AE66004DDBE1) /* 657 */,
|
||||
CONST64(0x05833F01067BE646) /* 658 */, CONST64(0xBB34B5AD3BFE586D) /* 659 */,
|
||||
CONST64(0x095F34C9A12B97F0) /* 660 */, CONST64(0x247AB64525D60CA8) /* 661 */,
|
||||
CONST64(0xDCDBC6F3017477D1) /* 662 */, CONST64(0x4A2E14D4DECAD24D) /* 663 */,
|
||||
CONST64(0xBDB5E6D9BE0A1EEB) /* 664 */, CONST64(0x2A7E70F7794301AB) /* 665 */,
|
||||
CONST64(0xDEF42D8A270540FD) /* 666 */, CONST64(0x01078EC0A34C22C1) /* 667 */,
|
||||
CONST64(0xE5DE511AF4C16387) /* 668 */, CONST64(0x7EBB3A52BD9A330A) /* 669 */,
|
||||
CONST64(0x77697857AA7D6435) /* 670 */, CONST64(0x004E831603AE4C32) /* 671 */,
|
||||
CONST64(0xE7A21020AD78E312) /* 672 */, CONST64(0x9D41A70C6AB420F2) /* 673 */,
|
||||
CONST64(0x28E06C18EA1141E6) /* 674 */, CONST64(0xD2B28CBD984F6B28) /* 675 */,
|
||||
CONST64(0x26B75F6C446E9D83) /* 676 */, CONST64(0xBA47568C4D418D7F) /* 677 */,
|
||||
CONST64(0xD80BADBFE6183D8E) /* 678 */, CONST64(0x0E206D7F5F166044) /* 679 */,
|
||||
CONST64(0xE258A43911CBCA3E) /* 680 */, CONST64(0x723A1746B21DC0BC) /* 681 */,
|
||||
CONST64(0xC7CAA854F5D7CDD3) /* 682 */, CONST64(0x7CAC32883D261D9C) /* 683 */,
|
||||
CONST64(0x7690C26423BA942C) /* 684 */, CONST64(0x17E55524478042B8) /* 685 */,
|
||||
CONST64(0xE0BE477656A2389F) /* 686 */, CONST64(0x4D289B5E67AB2DA0) /* 687 */,
|
||||
CONST64(0x44862B9C8FBBFD31) /* 688 */, CONST64(0xB47CC8049D141365) /* 689 */,
|
||||
CONST64(0x822C1B362B91C793) /* 690 */, CONST64(0x4EB14655FB13DFD8) /* 691 */,
|
||||
CONST64(0x1ECBBA0714E2A97B) /* 692 */, CONST64(0x6143459D5CDE5F14) /* 693 */,
|
||||
CONST64(0x53A8FBF1D5F0AC89) /* 694 */, CONST64(0x97EA04D81C5E5B00) /* 695 */,
|
||||
CONST64(0x622181A8D4FDB3F3) /* 696 */, CONST64(0xE9BCD341572A1208) /* 697 */,
|
||||
CONST64(0x1411258643CCE58A) /* 698 */, CONST64(0x9144C5FEA4C6E0A4) /* 699 */,
|
||||
CONST64(0x0D33D06565CF620F) /* 700 */, CONST64(0x54A48D489F219CA1) /* 701 */,
|
||||
CONST64(0xC43E5EAC6D63C821) /* 702 */, CONST64(0xA9728B3A72770DAF) /* 703 */,
|
||||
CONST64(0xD7934E7B20DF87EF) /* 704 */, CONST64(0xE35503B61A3E86E5) /* 705 */,
|
||||
CONST64(0xCAE321FBC819D504) /* 706 */, CONST64(0x129A50B3AC60BFA6) /* 707 */,
|
||||
CONST64(0xCD5E68EA7E9FB6C3) /* 708 */, CONST64(0xB01C90199483B1C7) /* 709 */,
|
||||
CONST64(0x3DE93CD5C295376C) /* 710 */, CONST64(0xAED52EDF2AB9AD13) /* 711 */,
|
||||
CONST64(0x2E60F512C0A07884) /* 712 */, CONST64(0xBC3D86A3E36210C9) /* 713 */,
|
||||
CONST64(0x35269D9B163951CE) /* 714 */, CONST64(0x0C7D6E2AD0CDB5FA) /* 715 */,
|
||||
CONST64(0x59E86297D87F5733) /* 716 */, CONST64(0x298EF221898DB0E7) /* 717 */,
|
||||
CONST64(0x55000029D1A5AA7E) /* 718 */, CONST64(0x8BC08AE1B5061B45) /* 719 */,
|
||||
CONST64(0xC2C31C2B6C92703A) /* 720 */, CONST64(0x94CC596BAF25EF42) /* 721 */,
|
||||
CONST64(0x0A1D73DB22540456) /* 722 */, CONST64(0x04B6A0F9D9C4179A) /* 723 */,
|
||||
CONST64(0xEFFDAFA2AE3D3C60) /* 724 */, CONST64(0xF7C8075BB49496C4) /* 725 */,
|
||||
CONST64(0x9CC5C7141D1CD4E3) /* 726 */, CONST64(0x78BD1638218E5534) /* 727 */,
|
||||
CONST64(0xB2F11568F850246A) /* 728 */, CONST64(0xEDFABCFA9502BC29) /* 729 */,
|
||||
CONST64(0x796CE5F2DA23051B) /* 730 */, CONST64(0xAAE128B0DC93537C) /* 731 */,
|
||||
CONST64(0x3A493DA0EE4B29AE) /* 732 */, CONST64(0xB5DF6B2C416895D7) /* 733 */,
|
||||
CONST64(0xFCABBD25122D7F37) /* 734 */, CONST64(0x70810B58105DC4B1) /* 735 */,
|
||||
CONST64(0xE10FDD37F7882A90) /* 736 */, CONST64(0x524DCAB5518A3F5C) /* 737 */,
|
||||
CONST64(0x3C9E85878451255B) /* 738 */, CONST64(0x4029828119BD34E2) /* 739 */,
|
||||
CONST64(0x74A05B6F5D3CECCB) /* 740 */, CONST64(0xB610021542E13ECA) /* 741 */,
|
||||
CONST64(0x0FF979D12F59E2AC) /* 742 */, CONST64(0x6037DA27E4F9CC50) /* 743 */,
|
||||
CONST64(0x5E92975A0DF1847D) /* 744 */, CONST64(0xD66DE190D3E623FE) /* 745 */,
|
||||
CONST64(0x5032D6B87B568048) /* 746 */, CONST64(0x9A36B7CE8235216E) /* 747 */,
|
||||
CONST64(0x80272A7A24F64B4A) /* 748 */, CONST64(0x93EFED8B8C6916F7) /* 749 */,
|
||||
CONST64(0x37DDBFF44CCE1555) /* 750 */, CONST64(0x4B95DB5D4B99BD25) /* 751 */,
|
||||
CONST64(0x92D3FDA169812FC0) /* 752 */, CONST64(0xFB1A4A9A90660BB6) /* 753 */,
|
||||
CONST64(0x730C196946A4B9B2) /* 754 */, CONST64(0x81E289AA7F49DA68) /* 755 */,
|
||||
CONST64(0x64669A0F83B1A05F) /* 756 */, CONST64(0x27B3FF7D9644F48B) /* 757 */,
|
||||
CONST64(0xCC6B615C8DB675B3) /* 758 */, CONST64(0x674F20B9BCEBBE95) /* 759 */,
|
||||
CONST64(0x6F31238275655982) /* 760 */, CONST64(0x5AE488713E45CF05) /* 761 */,
|
||||
CONST64(0xBF619F9954C21157) /* 762 */, CONST64(0xEABAC46040A8EAE9) /* 763 */,
|
||||
CONST64(0x454C6FE9F2C0C1CD) /* 764 */, CONST64(0x419CF6496412691C) /* 765 */,
|
||||
CONST64(0xD3DC3BEF265B0F70) /* 766 */, CONST64(0x6D0E60F5C3578A9E) /* 767 */,
|
||||
CONST64(0x5B0E608526323C55) /* 768 */, CONST64(0x1A46C1A9FA1B59F5) /* 769 */,
|
||||
CONST64(0xA9E245A17C4C8FFA) /* 770 */, CONST64(0x65CA5159DB2955D7) /* 771 */,
|
||||
CONST64(0x05DB0A76CE35AFC2) /* 772 */, CONST64(0x81EAC77EA9113D45) /* 773 */,
|
||||
CONST64(0x528EF88AB6AC0A0D) /* 774 */, CONST64(0xA09EA253597BE3FF) /* 775 */,
|
||||
CONST64(0x430DDFB3AC48CD56) /* 776 */, CONST64(0xC4B3A67AF45CE46F) /* 777 */,
|
||||
CONST64(0x4ECECFD8FBE2D05E) /* 778 */, CONST64(0x3EF56F10B39935F0) /* 779 */,
|
||||
CONST64(0x0B22D6829CD619C6) /* 780 */, CONST64(0x17FD460A74DF2069) /* 781 */,
|
||||
CONST64(0x6CF8CC8E8510ED40) /* 782 */, CONST64(0xD6C824BF3A6ECAA7) /* 783 */,
|
||||
CONST64(0x61243D581A817049) /* 784 */, CONST64(0x048BACB6BBC163A2) /* 785 */,
|
||||
CONST64(0xD9A38AC27D44CC32) /* 786 */, CONST64(0x7FDDFF5BAAF410AB) /* 787 */,
|
||||
CONST64(0xAD6D495AA804824B) /* 788 */, CONST64(0xE1A6A74F2D8C9F94) /* 789 */,
|
||||
CONST64(0xD4F7851235DEE8E3) /* 790 */, CONST64(0xFD4B7F886540D893) /* 791 */,
|
||||
CONST64(0x247C20042AA4BFDA) /* 792 */, CONST64(0x096EA1C517D1327C) /* 793 */,
|
||||
CONST64(0xD56966B4361A6685) /* 794 */, CONST64(0x277DA5C31221057D) /* 795 */,
|
||||
CONST64(0x94D59893A43ACFF7) /* 796 */, CONST64(0x64F0C51CCDC02281) /* 797 */,
|
||||
CONST64(0x3D33BCC4FF6189DB) /* 798 */, CONST64(0xE005CB184CE66AF1) /* 799 */,
|
||||
CONST64(0xFF5CCD1D1DB99BEA) /* 800 */, CONST64(0xB0B854A7FE42980F) /* 801 */,
|
||||
CONST64(0x7BD46A6A718D4B9F) /* 802 */, CONST64(0xD10FA8CC22A5FD8C) /* 803 */,
|
||||
CONST64(0xD31484952BE4BD31) /* 804 */, CONST64(0xC7FA975FCB243847) /* 805 */,
|
||||
CONST64(0x4886ED1E5846C407) /* 806 */, CONST64(0x28CDDB791EB70B04) /* 807 */,
|
||||
CONST64(0xC2B00BE2F573417F) /* 808 */, CONST64(0x5C9590452180F877) /* 809 */,
|
||||
CONST64(0x7A6BDDFFF370EB00) /* 810 */, CONST64(0xCE509E38D6D9D6A4) /* 811 */,
|
||||
CONST64(0xEBEB0F00647FA702) /* 812 */, CONST64(0x1DCC06CF76606F06) /* 813 */,
|
||||
CONST64(0xE4D9F28BA286FF0A) /* 814 */, CONST64(0xD85A305DC918C262) /* 815 */,
|
||||
CONST64(0x475B1D8732225F54) /* 816 */, CONST64(0x2D4FB51668CCB5FE) /* 817 */,
|
||||
CONST64(0xA679B9D9D72BBA20) /* 818 */, CONST64(0x53841C0D912D43A5) /* 819 */,
|
||||
CONST64(0x3B7EAA48BF12A4E8) /* 820 */, CONST64(0x781E0E47F22F1DDF) /* 821 */,
|
||||
CONST64(0xEFF20CE60AB50973) /* 822 */, CONST64(0x20D261D19DFFB742) /* 823 */,
|
||||
CONST64(0x16A12B03062A2E39) /* 824 */, CONST64(0x1960EB2239650495) /* 825 */,
|
||||
CONST64(0x251C16FED50EB8B8) /* 826 */, CONST64(0x9AC0C330F826016E) /* 827 */,
|
||||
CONST64(0xED152665953E7671) /* 828 */, CONST64(0x02D63194A6369570) /* 829 */,
|
||||
CONST64(0x5074F08394B1C987) /* 830 */, CONST64(0x70BA598C90B25CE1) /* 831 */,
|
||||
CONST64(0x794A15810B9742F6) /* 832 */, CONST64(0x0D5925E9FCAF8C6C) /* 833 */,
|
||||
CONST64(0x3067716CD868744E) /* 834 */, CONST64(0x910AB077E8D7731B) /* 835 */,
|
||||
CONST64(0x6A61BBDB5AC42F61) /* 836 */, CONST64(0x93513EFBF0851567) /* 837 */,
|
||||
CONST64(0xF494724B9E83E9D5) /* 838 */, CONST64(0xE887E1985C09648D) /* 839 */,
|
||||
CONST64(0x34B1D3C675370CFD) /* 840 */, CONST64(0xDC35E433BC0D255D) /* 841 */,
|
||||
CONST64(0xD0AAB84234131BE0) /* 842 */, CONST64(0x08042A50B48B7EAF) /* 843 */,
|
||||
CONST64(0x9997C4EE44A3AB35) /* 844 */, CONST64(0x829A7B49201799D0) /* 845 */,
|
||||
CONST64(0x263B8307B7C54441) /* 846 */, CONST64(0x752F95F4FD6A6CA6) /* 847 */,
|
||||
CONST64(0x927217402C08C6E5) /* 848 */, CONST64(0x2A8AB754A795D9EE) /* 849 */,
|
||||
CONST64(0xA442F7552F72943D) /* 850 */, CONST64(0x2C31334E19781208) /* 851 */,
|
||||
CONST64(0x4FA98D7CEAEE6291) /* 852 */, CONST64(0x55C3862F665DB309) /* 853 */,
|
||||
CONST64(0xBD0610175D53B1F3) /* 854 */, CONST64(0x46FE6CB840413F27) /* 855 */,
|
||||
CONST64(0x3FE03792DF0CFA59) /* 856 */, CONST64(0xCFE700372EB85E8F) /* 857 */,
|
||||
CONST64(0xA7BE29E7ADBCE118) /* 858 */, CONST64(0xE544EE5CDE8431DD) /* 859 */,
|
||||
CONST64(0x8A781B1B41F1873E) /* 860 */, CONST64(0xA5C94C78A0D2F0E7) /* 861 */,
|
||||
CONST64(0x39412E2877B60728) /* 862 */, CONST64(0xA1265EF3AFC9A62C) /* 863 */,
|
||||
CONST64(0xBCC2770C6A2506C5) /* 864 */, CONST64(0x3AB66DD5DCE1CE12) /* 865 */,
|
||||
CONST64(0xE65499D04A675B37) /* 866 */, CONST64(0x7D8F523481BFD216) /* 867 */,
|
||||
CONST64(0x0F6F64FCEC15F389) /* 868 */, CONST64(0x74EFBE618B5B13C8) /* 869 */,
|
||||
CONST64(0xACDC82B714273E1D) /* 870 */, CONST64(0xDD40BFE003199D17) /* 871 */,
|
||||
CONST64(0x37E99257E7E061F8) /* 872 */, CONST64(0xFA52626904775AAA) /* 873 */,
|
||||
CONST64(0x8BBBF63A463D56F9) /* 874 */, CONST64(0xF0013F1543A26E64) /* 875 */,
|
||||
CONST64(0xA8307E9F879EC898) /* 876 */, CONST64(0xCC4C27A4150177CC) /* 877 */,
|
||||
CONST64(0x1B432F2CCA1D3348) /* 878 */, CONST64(0xDE1D1F8F9F6FA013) /* 879 */,
|
||||
CONST64(0x606602A047A7DDD6) /* 880 */, CONST64(0xD237AB64CC1CB2C7) /* 881 */,
|
||||
CONST64(0x9B938E7225FCD1D3) /* 882 */, CONST64(0xEC4E03708E0FF476) /* 883 */,
|
||||
CONST64(0xFEB2FBDA3D03C12D) /* 884 */, CONST64(0xAE0BCED2EE43889A) /* 885 */,
|
||||
CONST64(0x22CB8923EBFB4F43) /* 886 */, CONST64(0x69360D013CF7396D) /* 887 */,
|
||||
CONST64(0x855E3602D2D4E022) /* 888 */, CONST64(0x073805BAD01F784C) /* 889 */,
|
||||
CONST64(0x33E17A133852F546) /* 890 */, CONST64(0xDF4874058AC7B638) /* 891 */,
|
||||
CONST64(0xBA92B29C678AA14A) /* 892 */, CONST64(0x0CE89FC76CFAADCD) /* 893 */,
|
||||
CONST64(0x5F9D4E0908339E34) /* 894 */, CONST64(0xF1AFE9291F5923B9) /* 895 */,
|
||||
CONST64(0x6E3480F60F4A265F) /* 896 */, CONST64(0xEEBF3A2AB29B841C) /* 897 */,
|
||||
CONST64(0xE21938A88F91B4AD) /* 898 */, CONST64(0x57DFEFF845C6D3C3) /* 899 */,
|
||||
CONST64(0x2F006B0BF62CAAF2) /* 900 */, CONST64(0x62F479EF6F75EE78) /* 901 */,
|
||||
CONST64(0x11A55AD41C8916A9) /* 902 */, CONST64(0xF229D29084FED453) /* 903 */,
|
||||
CONST64(0x42F1C27B16B000E6) /* 904 */, CONST64(0x2B1F76749823C074) /* 905 */,
|
||||
CONST64(0x4B76ECA3C2745360) /* 906 */, CONST64(0x8C98F463B91691BD) /* 907 */,
|
||||
CONST64(0x14BCC93CF1ADE66A) /* 908 */, CONST64(0x8885213E6D458397) /* 909 */,
|
||||
CONST64(0x8E177DF0274D4711) /* 910 */, CONST64(0xB49B73B5503F2951) /* 911 */,
|
||||
CONST64(0x10168168C3F96B6B) /* 912 */, CONST64(0x0E3D963B63CAB0AE) /* 913 */,
|
||||
CONST64(0x8DFC4B5655A1DB14) /* 914 */, CONST64(0xF789F1356E14DE5C) /* 915 */,
|
||||
CONST64(0x683E68AF4E51DAC1) /* 916 */, CONST64(0xC9A84F9D8D4B0FD9) /* 917 */,
|
||||
CONST64(0x3691E03F52A0F9D1) /* 918 */, CONST64(0x5ED86E46E1878E80) /* 919 */,
|
||||
CONST64(0x3C711A0E99D07150) /* 920 */, CONST64(0x5A0865B20C4E9310) /* 921 */,
|
||||
CONST64(0x56FBFC1FE4F0682E) /* 922 */, CONST64(0xEA8D5DE3105EDF9B) /* 923 */,
|
||||
CONST64(0x71ABFDB12379187A) /* 924 */, CONST64(0x2EB99DE1BEE77B9C) /* 925 */,
|
||||
CONST64(0x21ECC0EA33CF4523) /* 926 */, CONST64(0x59A4D7521805C7A1) /* 927 */,
|
||||
CONST64(0x3896F5EB56AE7C72) /* 928 */, CONST64(0xAA638F3DB18F75DC) /* 929 */,
|
||||
CONST64(0x9F39358DABE9808E) /* 930 */, CONST64(0xB7DEFA91C00B72AC) /* 931 */,
|
||||
CONST64(0x6B5541FD62492D92) /* 932 */, CONST64(0x6DC6DEE8F92E4D5B) /* 933 */,
|
||||
CONST64(0x353F57ABC4BEEA7E) /* 934 */, CONST64(0x735769D6DA5690CE) /* 935 */,
|
||||
CONST64(0x0A234AA642391484) /* 936 */, CONST64(0xF6F9508028F80D9D) /* 937 */,
|
||||
CONST64(0xB8E319A27AB3F215) /* 938 */, CONST64(0x31AD9C1151341A4D) /* 939 */,
|
||||
CONST64(0x773C22A57BEF5805) /* 940 */, CONST64(0x45C7561A07968633) /* 941 */,
|
||||
CONST64(0xF913DA9E249DBE36) /* 942 */, CONST64(0xDA652D9B78A64C68) /* 943 */,
|
||||
CONST64(0x4C27A97F3BC334EF) /* 944 */, CONST64(0x76621220E66B17F4) /* 945 */,
|
||||
CONST64(0x967743899ACD7D0B) /* 946 */, CONST64(0xF3EE5BCAE0ED6782) /* 947 */,
|
||||
CONST64(0x409F753600C879FC) /* 948 */, CONST64(0x06D09A39B5926DB6) /* 949 */,
|
||||
CONST64(0x6F83AEB0317AC588) /* 950 */, CONST64(0x01E6CA4A86381F21) /* 951 */,
|
||||
CONST64(0x66FF3462D19F3025) /* 952 */, CONST64(0x72207C24DDFD3BFB) /* 953 */,
|
||||
CONST64(0x4AF6B6D3E2ECE2EB) /* 954 */, CONST64(0x9C994DBEC7EA08DE) /* 955 */,
|
||||
CONST64(0x49ACE597B09A8BC4) /* 956 */, CONST64(0xB38C4766CF0797BA) /* 957 */,
|
||||
CONST64(0x131B9373C57C2A75) /* 958 */, CONST64(0xB1822CCE61931E58) /* 959 */,
|
||||
CONST64(0x9D7555B909BA1C0C) /* 960 */, CONST64(0x127FAFDD937D11D2) /* 961 */,
|
||||
CONST64(0x29DA3BADC66D92E4) /* 962 */, CONST64(0xA2C1D57154C2ECBC) /* 963 */,
|
||||
CONST64(0x58C5134D82F6FE24) /* 964 */, CONST64(0x1C3AE3515B62274F) /* 965 */,
|
||||
CONST64(0xE907C82E01CB8126) /* 966 */, CONST64(0xF8ED091913E37FCB) /* 967 */,
|
||||
CONST64(0x3249D8F9C80046C9) /* 968 */, CONST64(0x80CF9BEDE388FB63) /* 969 */,
|
||||
CONST64(0x1881539A116CF19E) /* 970 */, CONST64(0x5103F3F76BD52457) /* 971 */,
|
||||
CONST64(0x15B7E6F5AE47F7A8) /* 972 */, CONST64(0xDBD7C6DED47E9CCF) /* 973 */,
|
||||
CONST64(0x44E55C410228BB1A) /* 974 */, CONST64(0xB647D4255EDB4E99) /* 975 */,
|
||||
CONST64(0x5D11882BB8AAFC30) /* 976 */, CONST64(0xF5098BBB29D3212A) /* 977 */,
|
||||
CONST64(0x8FB5EA14E90296B3) /* 978 */, CONST64(0x677B942157DD025A) /* 979 */,
|
||||
CONST64(0xFB58E7C0A390ACB5) /* 980 */, CONST64(0x89D3674C83BD4A01) /* 981 */,
|
||||
CONST64(0x9E2DA4DF4BF3B93B) /* 982 */, CONST64(0xFCC41E328CAB4829) /* 983 */,
|
||||
CONST64(0x03F38C96BA582C52) /* 984 */, CONST64(0xCAD1BDBD7FD85DB2) /* 985 */,
|
||||
CONST64(0xBBB442C16082AE83) /* 986 */, CONST64(0xB95FE86BA5DA9AB0) /* 987 */,
|
||||
CONST64(0xB22E04673771A93F) /* 988 */, CONST64(0x845358C9493152D8) /* 989 */,
|
||||
CONST64(0xBE2A488697B4541E) /* 990 */, CONST64(0x95A2DC2DD38E6966) /* 991 */,
|
||||
CONST64(0xC02C11AC923C852B) /* 992 */, CONST64(0x2388B1990DF2A87B) /* 993 */,
|
||||
CONST64(0x7C8008FA1B4F37BE) /* 994 */, CONST64(0x1F70D0C84D54E503) /* 995 */,
|
||||
CONST64(0x5490ADEC7ECE57D4) /* 996 */, CONST64(0x002B3C27D9063A3A) /* 997 */,
|
||||
CONST64(0x7EAEA3848030A2BF) /* 998 */, CONST64(0xC602326DED2003C0) /* 999 */,
|
||||
CONST64(0x83A7287D69A94086) /* 1000 */, CONST64(0xC57A5FCB30F57A8A) /* 1001 */,
|
||||
CONST64(0xB56844E479EBE779) /* 1002 */, CONST64(0xA373B40F05DCBCE9) /* 1003 */,
|
||||
CONST64(0xD71A786E88570EE2) /* 1004 */, CONST64(0x879CBACDBDE8F6A0) /* 1005 */,
|
||||
CONST64(0x976AD1BCC164A32F) /* 1006 */, CONST64(0xAB21E25E9666D78B) /* 1007 */,
|
||||
CONST64(0x901063AAE5E5C33C) /* 1008 */, CONST64(0x9818B34448698D90) /* 1009 */,
|
||||
CONST64(0xE36487AE3E1E8ABB) /* 1010 */, CONST64(0xAFBDF931893BDCB4) /* 1011 */,
|
||||
CONST64(0x6345A0DC5FBBD519) /* 1012 */, CONST64(0x8628FE269B9465CA) /* 1013 */,
|
||||
CONST64(0x1E5D01603F9C51EC) /* 1014 */, CONST64(0x4DE44006A15049B7) /* 1015 */,
|
||||
CONST64(0xBF6C70E5F776CBB1) /* 1016 */, CONST64(0x411218F2EF552BED) /* 1017 */,
|
||||
CONST64(0xCB0C0708705A36A3) /* 1018 */, CONST64(0xE74D14754F986044) /* 1019 */,
|
||||
CONST64(0xCD56D9430EA8280E) /* 1020 */, CONST64(0xC12591D7535F5065) /* 1021 */,
|
||||
CONST64(0xC83223F1720AEF96) /* 1022 */, CONST64(0xC3A0396F7363A51F) /* 1023 */};
|
||||
|
||||
/* one round of the hash function */
|
||||
static void round(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 x, ulong64 mul)
|
||||
{
|
||||
*c ^= x;
|
||||
*a -= t1[(*c)&255] ^ t2[((*c)>>16)&255] ^ t3[((*c)>>32)&255] ^ t4[((*c)>>48)&255];
|
||||
*b += t4[((*c)>>8)&255] ^ t3[((*c)>>24)&255] ^ t2[((*c)>>40)&255] ^ t1[((*c)>>56)&255];
|
||||
*b *= mul;
|
||||
}
|
||||
|
||||
/* one complete pass */
|
||||
static void pass(ulong64 *a, ulong64 *b, ulong64 *c, ulong64 *x, ulong64 mul)
|
||||
{
|
||||
round(a,b,c,x[0],mul);
|
||||
round(b,c,a,x[1],mul);
|
||||
round(c,a,b,x[2],mul);
|
||||
round(a,b,c,x[3],mul);
|
||||
round(b,c,a,x[4],mul);
|
||||
round(c,a,b,x[5],mul);
|
||||
round(a,b,c,x[6],mul);
|
||||
round(b,c,a,x[7],mul);
|
||||
}
|
||||
|
||||
/* The key mixing schedule */
|
||||
static void key_schedule(ulong64 *x) {
|
||||
x[0] -= x[7] ^ CONST64(0xA5A5A5A5A5A5A5A5);
|
||||
x[1] ^= x[0];
|
||||
x[2] += x[1];
|
||||
x[3] -= x[2] ^ ((~x[1])<<19);
|
||||
x[4] ^= x[3];
|
||||
x[5] += x[4];
|
||||
x[6] -= x[5] ^ ((~x[4])>>23);
|
||||
x[7] ^= x[6];
|
||||
x[0] += x[7];
|
||||
x[1] -= x[0] ^ ((~x[7])<<19);
|
||||
x[2] ^= x[1];
|
||||
x[3] += x[2];
|
||||
x[4] -= x[3] ^ ((~x[2])>>23);
|
||||
x[5] ^= x[4];
|
||||
x[6] += x[5];
|
||||
x[7] -= x[6] ^ CONST64(0x0123456789ABCDEF);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _tiger_compress(hash_state *md)
|
||||
#else
|
||||
static void tiger_compress(hash_state *md)
|
||||
#endif
|
||||
{
|
||||
ulong64 a, b, c, x[8];
|
||||
unsigned long i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
/* load words */
|
||||
for (i = 0; i < 8; i++) {
|
||||
LOAD64L(x[i],&md->tiger.buf[8*i]);
|
||||
}
|
||||
a = md->tiger.state[0];
|
||||
b = md->tiger.state[1];
|
||||
c = md->tiger.state[2];
|
||||
|
||||
pass(&a,&b,&c,x,5);
|
||||
key_schedule(x);
|
||||
pass(&c,&a,&b,x,7);
|
||||
key_schedule(x);
|
||||
pass(&b,&c,&a,x,9);
|
||||
|
||||
/* store state */
|
||||
md->tiger.state[0] = a ^ md->tiger.state[0];
|
||||
md->tiger.state[1] = b - md->tiger.state[1];
|
||||
md->tiger.state[2] = c + md->tiger.state[2];
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void tiger_compress(hash_state *md)
|
||||
{
|
||||
_tiger_compress(md);
|
||||
burn_stack(sizeof(ulong64) * 11 + sizeof(unsigned long));
|
||||
}
|
||||
#endif
|
||||
|
||||
void tiger_init(hash_state *md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
md->tiger.state[0] = CONST64(0x0123456789ABCDEF);
|
||||
md->tiger.state[1] = CONST64(0xFEDCBA9876543210);
|
||||
md->tiger.state[2] = CONST64(0xF096A5B4C3B2E187);
|
||||
md->tiger.curlen = 0;
|
||||
md->tiger.length = 0;
|
||||
}
|
||||
|
||||
void tiger_process(hash_state * md, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long n;
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
while (len) {
|
||||
n = MIN(len, (64 - md->tiger.curlen));
|
||||
memcpy(md->tiger.buf + md->tiger.curlen, buf, n);
|
||||
md->tiger.curlen += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
|
||||
/* is 64 bytes full? */
|
||||
if (md->tiger.curlen == 64) {
|
||||
tiger_compress(md);
|
||||
md->tiger.length += 512; /* add the number of bits not bytes */
|
||||
md->tiger.curlen = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tiger_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* increase the length of the message */
|
||||
md->tiger.length += md->tiger.curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->tiger.buf[md->tiger.curlen++] = 0x01;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal. */
|
||||
if (md->tiger.curlen > 56) {
|
||||
while (md->tiger.curlen < 64) {
|
||||
md->tiger.buf[md->tiger.curlen++] = 0;
|
||||
}
|
||||
tiger_compress(md);
|
||||
md->tiger.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (md->tiger.curlen < 56) {
|
||||
md->tiger.buf[md->tiger.curlen++] = 0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64L(md->tiger.length, md->tiger.buf+56);
|
||||
tiger_compress(md);
|
||||
|
||||
/* copy output */
|
||||
STORE64L(md->tiger.state[0], &hash[0]);
|
||||
STORE64L(md->tiger.state[1], &hash[8]);
|
||||
STORE64L(md->tiger.state[2], &hash[16]);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
}
|
||||
|
||||
int tiger_test(void)
|
||||
{
|
||||
static const struct {
|
||||
unsigned char *msg;
|
||||
unsigned char hash[24];
|
||||
} tests[] = {
|
||||
{ "",
|
||||
{ 0x32, 0x93, 0xac, 0x63, 0x0c, 0x13, 0xf0, 0x24,
|
||||
0x5f, 0x92, 0xbb, 0xb1, 0x76, 0x6e, 0x16, 0x16,
|
||||
0x7a, 0x4e, 0x58, 0x49, 0x2d, 0xde, 0x73, 0xf3 }
|
||||
},
|
||||
{ "abc",
|
||||
{ 0x2a, 0xab, 0x14, 0x84, 0xe8, 0xc1, 0x58, 0xf2,
|
||||
0xbf, 0xb8, 0xc5, 0xff, 0x41, 0xb5, 0x7a, 0x52,
|
||||
0x51, 0x29, 0x13, 0x1c, 0x95, 0x7b, 0x5f, 0x93 }
|
||||
},
|
||||
{ "Tiger",
|
||||
{ 0xdd, 0x00, 0x23, 0x07, 0x99, 0xf5, 0x00, 0x9f,
|
||||
0xec, 0x6d, 0xeb, 0xc8, 0x38, 0xbb, 0x6a, 0x27,
|
||||
0xdf, 0x2b, 0x9d, 0x6f, 0x11, 0x0c, 0x79, 0x37 }
|
||||
},
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
|
||||
{ 0xf7, 0x1c, 0x85, 0x83, 0x90, 0x2a, 0xfb, 0x87,
|
||||
0x9e, 0xdf, 0xe6, 0x10, 0xf8, 0x2c, 0x0d, 0x47,
|
||||
0x86, 0xa3, 0xa5, 0x34, 0x50, 0x44, 0x86, 0xb5 }
|
||||
},
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
|
||||
{ 0xc5, 0x40, 0x34, 0xe5, 0xb4, 0x3e, 0xb8, 0x00,
|
||||
0x58, 0x48, 0xa7, 0xe0, 0xae, 0x6a, 0xac, 0x76,
|
||||
0xe4, 0xff, 0x59, 0x0a, 0xe7, 0x15, 0xfd, 0x25 }
|
||||
},
|
||||
{ NULL, { 0 }}
|
||||
};
|
||||
|
||||
int failed, i;
|
||||
unsigned char tmp[24];
|
||||
hash_state md;
|
||||
|
||||
for (failed = i = 0; tests[i].msg != NULL; i++) {
|
||||
tiger_init(&md);
|
||||
tiger_process(&md, tests[i].msg, strlen(tests[i].msg));
|
||||
tiger_done(&md, tmp);
|
||||
if (memcmp(tmp, tests[i].hash, 24)) {
|
||||
#if 0
|
||||
int j;
|
||||
printf("\nTIGER-192 Test %d failed\nGot (as a result): ", i);
|
||||
for (j = 0; j < 24; j++) {
|
||||
printf("%02x ", tmp[j]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed = 1;
|
||||
}
|
||||
}
|
||||
if (failed == 1) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
Hash of "":
|
||||
24F0130C63AC9332 16166E76B1BB925F F373DE2D49584E7A
|
||||
Hash of "abc":
|
||||
F258C1E88414AB2A 527AB541FFC5B8BF 935F7B951C132951
|
||||
Hash of "Tiger":
|
||||
9F00F599072300DD 276ABB38C8EB6DEC 37790C116F9D2BDF
|
||||
Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-":
|
||||
87FB2A9083851CF7 470D2CF810E6DF9E B586445034A5A386
|
||||
Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdefghijklmnopqrstuvwxyz+0123456789":
|
||||
467DB80863EBCE48 8DF1CD1261655DE9 57896565975F9197
|
||||
Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham":
|
||||
0C410A042968868A 1671DA5A3FD29A72 5EC1E457D3CDB303
|
||||
Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge.":
|
||||
EBF591D5AFA655CE 7F22894FF87F54AC 89C811B6B0DA3193
|
||||
Hash of "Tiger - A Fast New Hash Function, by Ross Anderson and Eli Biham, proceedings of Fast Software Encryption 3, Cambridge, 1996.":
|
||||
3D9AEB03D1BD1A63 57B2774DFD6D5B24 DD68151D503974FC
|
||||
Hash of "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-":
|
||||
00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4
|
||||
*/
|
||||
|
||||
|
||||
|
727
twofish.c
Normal file
727
twofish.c
Normal file
@ -0,0 +1,727 @@
|
||||
/* Implementation of Twofish by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef TWOFISH
|
||||
|
||||
const struct _cipher_descriptor twofish_desc =
|
||||
{
|
||||
"twofish",
|
||||
7,
|
||||
16, 32, 16, 16,
|
||||
&twofish_setup,
|
||||
&twofish_ecb_encrypt,
|
||||
&twofish_ecb_decrypt,
|
||||
&twofish_test,
|
||||
&twofish_keysize
|
||||
};
|
||||
|
||||
/* the two polynomials */
|
||||
#define MDS_POLY 0x169
|
||||
#define RS_POLY 0x14D
|
||||
|
||||
/* The 4x4 MDS Linear Transform */
|
||||
static const unsigned char MDS[4][4] = {
|
||||
{ 0x01, 0xEF, 0x5B, 0x5B },
|
||||
{ 0x5B, 0xEF, 0xEF, 0x01 },
|
||||
{ 0xEF, 0x5B, 0x01, 0xEF },
|
||||
{ 0xEF, 0x01, 0xEF, 0x5B }
|
||||
};
|
||||
|
||||
/* The 4x8 RS Linear Transform */
|
||||
static const unsigned char RS[4][8] = {
|
||||
{ 0x01, 0xA4, 0x55, 0x87, 0x5A, 0x58, 0xDB, 0x9E },
|
||||
{ 0xA4, 0x56, 0x82, 0xF3, 0X1E, 0XC6, 0X68, 0XE5 },
|
||||
{ 0X02, 0XA1, 0XFC, 0XC1, 0X47, 0XAE, 0X3D, 0X19 },
|
||||
{ 0XA4, 0X55, 0X87, 0X5A, 0X58, 0XDB, 0X9E, 0X03 }
|
||||
};
|
||||
|
||||
/* sbox usage orderings */
|
||||
static const unsigned char qord[4][5] = {
|
||||
{ 1, 1, 0, 0, 1 },
|
||||
{ 0, 1, 1, 0, 0 },
|
||||
{ 0, 0, 0, 1, 1 },
|
||||
{ 1, 0, 1, 1, 0 }
|
||||
};
|
||||
|
||||
#ifdef TWOFISH_TABLES
|
||||
static const unsigned char SBOX[2][256] = {
|
||||
{
|
||||
0xa9, 0x67, 0xb3, 0xe8, 0x04, 0xfd, 0xa3, 0x76, 0x9a, 0x92,
|
||||
0x80, 0x78, 0xe4, 0xdd, 0xd1, 0x38, 0x0d, 0xc6, 0x35, 0x98,
|
||||
0x18, 0xf7, 0xec, 0x6c, 0x43, 0x75, 0x37, 0x26, 0xfa, 0x13,
|
||||
0x94, 0x48, 0xf2, 0xd0, 0x8b, 0x30, 0x84, 0x54, 0xdf, 0x23,
|
||||
0x19, 0x5b, 0x3d, 0x59, 0xf3, 0xae, 0xa2, 0x82, 0x63, 0x01,
|
||||
0x83, 0x2e, 0xd9, 0x51, 0x9b, 0x7c, 0xa6, 0xeb, 0xa5, 0xbe,
|
||||
0x16, 0x0c, 0xe3, 0x61, 0xc0, 0x8c, 0x3a, 0xf5, 0x73, 0x2c,
|
||||
0x25, 0x0b, 0xbb, 0x4e, 0x89, 0x6b, 0x53, 0x6a, 0xb4, 0xf1,
|
||||
0xe1, 0xe6, 0xbd, 0x45, 0xe2, 0xf4, 0xb6, 0x66, 0xcc, 0x95,
|
||||
0x03, 0x56, 0xd4, 0x1c, 0x1e, 0xd7, 0xfb, 0xc3, 0x8e, 0xb5,
|
||||
0xe9, 0xcf, 0xbf, 0xba, 0xea, 0x77, 0x39, 0xaf, 0x33, 0xc9,
|
||||
0x62, 0x71, 0x81, 0x79, 0x09, 0xad, 0x24, 0xcd, 0xf9, 0xd8,
|
||||
0xe5, 0xc5, 0xb9, 0x4d, 0x44, 0x08, 0x86, 0xe7, 0xa1, 0x1d,
|
||||
0xaa, 0xed, 0x06, 0x70, 0xb2, 0xd2, 0x41, 0x7b, 0xa0, 0x11,
|
||||
0x31, 0xc2, 0x27, 0x90, 0x20, 0xf6, 0x60, 0xff, 0x96, 0x5c,
|
||||
0xb1, 0xab, 0x9e, 0x9c, 0x52, 0x1b, 0x5f, 0x93, 0x0a, 0xef,
|
||||
0x91, 0x85, 0x49, 0xee, 0x2d, 0x4f, 0x8f, 0x3b, 0x47, 0x87,
|
||||
0x6d, 0x46, 0xd6, 0x3e, 0x69, 0x64, 0x2a, 0xce, 0xcb, 0x2f,
|
||||
0xfc, 0x97, 0x05, 0x7a, 0xac, 0x7f, 0xd5, 0x1a, 0x4b, 0x0e,
|
||||
0xa7, 0x5a, 0x28, 0x14, 0x3f, 0x29, 0x88, 0x3c, 0x4c, 0x02,
|
||||
0xb8, 0xda, 0xb0, 0x17, 0x55, 0x1f, 0x8a, 0x7d, 0x57, 0xc7,
|
||||
0x8d, 0x74, 0xb7, 0xc4, 0x9f, 0x72, 0x7e, 0x15, 0x22, 0x12,
|
||||
0x58, 0x07, 0x99, 0x34, 0x6e, 0x50, 0xde, 0x68, 0x65, 0xbc,
|
||||
0xdb, 0xf8, 0xc8, 0xa8, 0x2b, 0x40, 0xdc, 0xfe, 0x32, 0xa4,
|
||||
0xca, 0x10, 0x21, 0xf0, 0xd3, 0x5d, 0x0f, 0x00, 0x6f, 0x9d,
|
||||
0x36, 0x42, 0x4a, 0x5e, 0xc1, 0xe0},
|
||||
{
|
||||
0x75, 0xf3, 0xc6, 0xf4, 0xdb, 0x7b, 0xfb, 0xc8, 0x4a, 0xd3,
|
||||
0xe6, 0x6b, 0x45, 0x7d, 0xe8, 0x4b, 0xd6, 0x32, 0xd8, 0xfd,
|
||||
0x37, 0x71, 0xf1, 0xe1, 0x30, 0x0f, 0xf8, 0x1b, 0x87, 0xfa,
|
||||
0x06, 0x3f, 0x5e, 0xba, 0xae, 0x5b, 0x8a, 0x00, 0xbc, 0x9d,
|
||||
0x6d, 0xc1, 0xb1, 0x0e, 0x80, 0x5d, 0xd2, 0xd5, 0xa0, 0x84,
|
||||
0x07, 0x14, 0xb5, 0x90, 0x2c, 0xa3, 0xb2, 0x73, 0x4c, 0x54,
|
||||
0x92, 0x74, 0x36, 0x51, 0x38, 0xb0, 0xbd, 0x5a, 0xfc, 0x60,
|
||||
0x62, 0x96, 0x6c, 0x42, 0xf7, 0x10, 0x7c, 0x28, 0x27, 0x8c,
|
||||
0x13, 0x95, 0x9c, 0xc7, 0x24, 0x46, 0x3b, 0x70, 0xca, 0xe3,
|
||||
0x85, 0xcb, 0x11, 0xd0, 0x93, 0xb8, 0xa6, 0x83, 0x20, 0xff,
|
||||
0x9f, 0x77, 0xc3, 0xcc, 0x03, 0x6f, 0x08, 0xbf, 0x40, 0xe7,
|
||||
0x2b, 0xe2, 0x79, 0x0c, 0xaa, 0x82, 0x41, 0x3a, 0xea, 0xb9,
|
||||
0xe4, 0x9a, 0xa4, 0x97, 0x7e, 0xda, 0x7a, 0x17, 0x66, 0x94,
|
||||
0xa1, 0x1d, 0x3d, 0xf0, 0xde, 0xb3, 0x0b, 0x72, 0xa7, 0x1c,
|
||||
0xef, 0xd1, 0x53, 0x3e, 0x8f, 0x33, 0x26, 0x5f, 0xec, 0x76,
|
||||
0x2a, 0x49, 0x81, 0x88, 0xee, 0x21, 0xc4, 0x1a, 0xeb, 0xd9,
|
||||
0xc5, 0x39, 0x99, 0xcd, 0xad, 0x31, 0x8b, 0x01, 0x18, 0x23,
|
||||
0xdd, 0x1f, 0x4e, 0x2d, 0xf9, 0x48, 0x4f, 0xf2, 0x65, 0x8e,
|
||||
0x78, 0x5c, 0x58, 0x19, 0x8d, 0xe5, 0x98, 0x57, 0x67, 0x7f,
|
||||
0x05, 0x64, 0xaf, 0x63, 0xb6, 0xfe, 0xf5, 0xb7, 0x3c, 0xa5,
|
||||
0xce, 0xe9, 0x68, 0x44, 0xe0, 0x4d, 0x43, 0x69, 0x29, 0x2e,
|
||||
0xac, 0x15, 0x59, 0xa8, 0x0a, 0x9e, 0x6e, 0x47, 0xdf, 0x34,
|
||||
0x35, 0x6a, 0xcf, 0xdc, 0x22, 0xc9, 0xc0, 0x9b, 0x89, 0xd4,
|
||||
0xed, 0xab, 0x12, 0xa2, 0x0d, 0x52, 0xbb, 0x02, 0x2f, 0xa9,
|
||||
0xd7, 0x61, 0x1e, 0xb4, 0x50, 0x04, 0xf6, 0xc2, 0x16, 0x25,
|
||||
0x86, 0x56, 0x55, 0x09, 0xbe, 0x91}
|
||||
};
|
||||
|
||||
static const unsigned char GF_EF[256] = {
|
||||
0x00, 0xef, 0xb7, 0x58, 0x07, 0xe8, 0xb0, 0x5f, 0x0e, 0xe1,
|
||||
0xb9, 0x56, 0x09, 0xe6, 0xbe, 0x51, 0x1c, 0xf3, 0xab, 0x44,
|
||||
0x1b, 0xf4, 0xac, 0x43, 0x12, 0xfd, 0xa5, 0x4a, 0x15, 0xfa,
|
||||
0xa2, 0x4d, 0x38, 0xd7, 0x8f, 0x60, 0x3f, 0xd0, 0x88, 0x67,
|
||||
0x36, 0xd9, 0x81, 0x6e, 0x31, 0xde, 0x86, 0x69, 0x24, 0xcb,
|
||||
0x93, 0x7c, 0x23, 0xcc, 0x94, 0x7b, 0x2a, 0xc5, 0x9d, 0x72,
|
||||
0x2d, 0xc2, 0x9a, 0x75, 0x70, 0x9f, 0xc7, 0x28, 0x77, 0x98,
|
||||
0xc0, 0x2f, 0x7e, 0x91, 0xc9, 0x26, 0x79, 0x96, 0xce, 0x21,
|
||||
0x6c, 0x83, 0xdb, 0x34, 0x6b, 0x84, 0xdc, 0x33, 0x62, 0x8d,
|
||||
0xd5, 0x3a, 0x65, 0x8a, 0xd2, 0x3d, 0x48, 0xa7, 0xff, 0x10,
|
||||
0x4f, 0xa0, 0xf8, 0x17, 0x46, 0xa9, 0xf1, 0x1e, 0x41, 0xae,
|
||||
0xf6, 0x19, 0x54, 0xbb, 0xe3, 0x0c, 0x53, 0xbc, 0xe4, 0x0b,
|
||||
0x5a, 0xb5, 0xed, 0x02, 0x5d, 0xb2, 0xea, 0x05, 0xe0, 0x0f,
|
||||
0x57, 0xb8, 0xe7, 0x08, 0x50, 0xbf, 0xee, 0x01, 0x59, 0xb6,
|
||||
0xe9, 0x06, 0x5e, 0xb1, 0xfc, 0x13, 0x4b, 0xa4, 0xfb, 0x14,
|
||||
0x4c, 0xa3, 0xf2, 0x1d, 0x45, 0xaa, 0xf5, 0x1a, 0x42, 0xad,
|
||||
0xd8, 0x37, 0x6f, 0x80, 0xdf, 0x30, 0x68, 0x87, 0xd6, 0x39,
|
||||
0x61, 0x8e, 0xd1, 0x3e, 0x66, 0x89, 0xc4, 0x2b, 0x73, 0x9c,
|
||||
0xc3, 0x2c, 0x74, 0x9b, 0xca, 0x25, 0x7d, 0x92, 0xcd, 0x22,
|
||||
0x7a, 0x95, 0x90, 0x7f, 0x27, 0xc8, 0x97, 0x78, 0x20, 0xcf,
|
||||
0x9e, 0x71, 0x29, 0xc6, 0x99, 0x76, 0x2e, 0xc1, 0x8c, 0x63,
|
||||
0x3b, 0xd4, 0x8b, 0x64, 0x3c, 0xd3, 0x82, 0x6d, 0x35, 0xda,
|
||||
0x85, 0x6a, 0x32, 0xdd, 0xa8, 0x47, 0x1f, 0xf0, 0xaf, 0x40,
|
||||
0x18, 0xf7, 0xa6, 0x49, 0x11, 0xfe, 0xa1, 0x4e, 0x16, 0xf9,
|
||||
0xb4, 0x5b, 0x03, 0xec, 0xb3, 0x5c, 0x04, 0xeb, 0xba, 0x55,
|
||||
0x0d, 0xe2, 0xbd, 0x52, 0x0a, 0xe5};
|
||||
|
||||
static const unsigned char GF_5B[256] = {
|
||||
0x00, 0x5b, 0xb6, 0xed, 0x05, 0x5e, 0xb3, 0xe8, 0x0a, 0x51,
|
||||
0xbc, 0xe7, 0x0f, 0x54, 0xb9, 0xe2, 0x14, 0x4f, 0xa2, 0xf9,
|
||||
0x11, 0x4a, 0xa7, 0xfc, 0x1e, 0x45, 0xa8, 0xf3, 0x1b, 0x40,
|
||||
0xad, 0xf6, 0x28, 0x73, 0x9e, 0xc5, 0x2d, 0x76, 0x9b, 0xc0,
|
||||
0x22, 0x79, 0x94, 0xcf, 0x27, 0x7c, 0x91, 0xca, 0x3c, 0x67,
|
||||
0x8a, 0xd1, 0x39, 0x62, 0x8f, 0xd4, 0x36, 0x6d, 0x80, 0xdb,
|
||||
0x33, 0x68, 0x85, 0xde, 0x50, 0x0b, 0xe6, 0xbd, 0x55, 0x0e,
|
||||
0xe3, 0xb8, 0x5a, 0x01, 0xec, 0xb7, 0x5f, 0x04, 0xe9, 0xb2,
|
||||
0x44, 0x1f, 0xf2, 0xa9, 0x41, 0x1a, 0xf7, 0xac, 0x4e, 0x15,
|
||||
0xf8, 0xa3, 0x4b, 0x10, 0xfd, 0xa6, 0x78, 0x23, 0xce, 0x95,
|
||||
0x7d, 0x26, 0xcb, 0x90, 0x72, 0x29, 0xc4, 0x9f, 0x77, 0x2c,
|
||||
0xc1, 0x9a, 0x6c, 0x37, 0xda, 0x81, 0x69, 0x32, 0xdf, 0x84,
|
||||
0x66, 0x3d, 0xd0, 0x8b, 0x63, 0x38, 0xd5, 0x8e, 0xa0, 0xfb,
|
||||
0x16, 0x4d, 0xa5, 0xfe, 0x13, 0x48, 0xaa, 0xf1, 0x1c, 0x47,
|
||||
0xaf, 0xf4, 0x19, 0x42, 0xb4, 0xef, 0x02, 0x59, 0xb1, 0xea,
|
||||
0x07, 0x5c, 0xbe, 0xe5, 0x08, 0x53, 0xbb, 0xe0, 0x0d, 0x56,
|
||||
0x88, 0xd3, 0x3e, 0x65, 0x8d, 0xd6, 0x3b, 0x60, 0x82, 0xd9,
|
||||
0x34, 0x6f, 0x87, 0xdc, 0x31, 0x6a, 0x9c, 0xc7, 0x2a, 0x71,
|
||||
0x99, 0xc2, 0x2f, 0x74, 0x96, 0xcd, 0x20, 0x7b, 0x93, 0xc8,
|
||||
0x25, 0x7e, 0xf0, 0xab, 0x46, 0x1d, 0xf5, 0xae, 0x43, 0x18,
|
||||
0xfa, 0xa1, 0x4c, 0x17, 0xff, 0xa4, 0x49, 0x12, 0xe4, 0xbf,
|
||||
0x52, 0x09, 0xe1, 0xba, 0x57, 0x0c, 0xee, 0xb5, 0x58, 0x03,
|
||||
0xeb, 0xb0, 0x5d, 0x06, 0xd8, 0x83, 0x6e, 0x35, 0xdd, 0x86,
|
||||
0x6b, 0x30, 0xd2, 0x89, 0x64, 0x3f, 0xd7, 0x8c, 0x61, 0x3a,
|
||||
0xcc, 0x97, 0x7a, 0x21, 0xc9, 0x92, 0x7f, 0x24, 0xc6, 0x9d,
|
||||
0x70, 0x2b, 0xc3, 0x98, 0x75, 0x2e};
|
||||
|
||||
#define sbox(i, x) ((unsigned long)SBOX[i][(x)&255])
|
||||
|
||||
#else
|
||||
|
||||
/* The Q-box tables */
|
||||
static const unsigned char qbox[2][4][16] = {
|
||||
{
|
||||
{ 0x8, 0x1, 0x7, 0xD, 0x6, 0xF, 0x3, 0x2, 0x0, 0xB, 0x5, 0x9, 0xE, 0xC, 0xA, 0x4 },
|
||||
{ 0xE, 0XC, 0XB, 0X8, 0X1, 0X2, 0X3, 0X5, 0XF, 0X4, 0XA, 0X6, 0X7, 0X0, 0X9, 0XD },
|
||||
{ 0XB, 0XA, 0X5, 0XE, 0X6, 0XD, 0X9, 0X0, 0XC, 0X8, 0XF, 0X3, 0X2, 0X4, 0X7, 0X1 },
|
||||
{ 0XD, 0X7, 0XF, 0X4, 0X1, 0X2, 0X6, 0XE, 0X9, 0XB, 0X3, 0X0, 0X8, 0X5, 0XC, 0XA }
|
||||
},
|
||||
{
|
||||
{ 0X2, 0X8, 0XB, 0XD, 0XF, 0X7, 0X6, 0XE, 0X3, 0X1, 0X9, 0X4, 0X0, 0XA, 0XC, 0X5 },
|
||||
{ 0X1, 0XE, 0X2, 0XB, 0X4, 0XC, 0X3, 0X7, 0X6, 0XD, 0XA, 0X5, 0XF, 0X9, 0X0, 0X8 },
|
||||
{ 0X4, 0XC, 0X7, 0X5, 0X1, 0X6, 0X9, 0XA, 0X0, 0XE, 0XD, 0X8, 0X2, 0XB, 0X3, 0XF },
|
||||
{ 0xB, 0X9, 0X5, 0X1, 0XC, 0X3, 0XD, 0XE, 0X6, 0X4, 0X7, 0XF, 0X2, 0X0, 0X8, 0XA }
|
||||
}
|
||||
};
|
||||
|
||||
/* computes S_i[x] */
|
||||
#ifdef CLEAN_STACK
|
||||
static unsigned long _sbox(int i, unsigned long x)
|
||||
#else
|
||||
unsigned long sbox(int i, unsigned long x)
|
||||
#endif
|
||||
{
|
||||
unsigned char a0,b0,a1,b1,a2,b2,a3,b3,a4,b4,y;
|
||||
|
||||
/* a0,b0 = [x/16], x mod 16 */
|
||||
a0 = (x>>4)&15;
|
||||
b0 = (x)&15;
|
||||
|
||||
/* a1 = a0 ^ b0 */
|
||||
a1 = a0 ^ b0;
|
||||
|
||||
/* b1 = a0 ^ ROR(b0, 1) ^ 8a0 */
|
||||
b1 = (a0 ^ ((b0<<3)|(b0>>1)) ^ (a0<<3)) & 15;
|
||||
|
||||
/* a2,b2 = t0[a1], t1[b1] */
|
||||
a2 = qbox[i][0][a1];
|
||||
b2 = qbox[i][1][b1];
|
||||
|
||||
/* a3 = a2 ^ b2 */
|
||||
a3 = a2 ^ b2;
|
||||
|
||||
/* b3 = a2 ^ ROR(b2, 1) ^ 8a2 */
|
||||
b3 = (a2 ^ ((b2<<3)|(b2>>1)) ^ (a2<<3)) & 15;
|
||||
|
||||
/* a4,b4 = t2[a3], t3[b3] */
|
||||
a4 = qbox[i][2][a3];
|
||||
b4 = qbox[i][3][b3];
|
||||
|
||||
/* y = 16b4 + a4 */
|
||||
y = (b4 << 4) + a4;
|
||||
|
||||
/* return result */
|
||||
return (unsigned long)y;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static unsigned long sbox(int i, unsigned long x)
|
||||
{
|
||||
unsigned long y;
|
||||
y = _sbox(i, x);
|
||||
burn_stack(sizeof(unsigned char) * 11);
|
||||
return y;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* computes ab mod p */
|
||||
static unsigned long gf_mult(unsigned long a, unsigned long b, unsigned long p)
|
||||
{
|
||||
unsigned long result = 0;
|
||||
while (a) {
|
||||
if (a&1)
|
||||
result ^= b;
|
||||
a >>= 1;
|
||||
b <<= 1;
|
||||
if (b & 0x100)
|
||||
b ^= p;
|
||||
}
|
||||
return result & 255;
|
||||
}
|
||||
|
||||
|
||||
/* Computes [y0 y1 y2 y3] = MDS . [x0 x1 x2 x3] */
|
||||
static void mds_mult(const unsigned char *in, unsigned char *out)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char tmp[4];
|
||||
|
||||
for (x = 0; x < 4; x++) {
|
||||
tmp[x] = 0;
|
||||
for (y = 0; y < 4; y++)
|
||||
tmp[x] ^= gf_mult(in[y], MDS[x][y], MDS_POLY);
|
||||
}
|
||||
for (x = 0; x < 4; x++)
|
||||
out[x] = tmp[x];
|
||||
zeromem(tmp, 4);
|
||||
}
|
||||
|
||||
/* computes [y0 y1 y2 y3] = RS . [x0 x1 x2 x3 x4 x5 x6 x7] */
|
||||
static void rs_mult(const unsigned char *in, unsigned char *out)
|
||||
{
|
||||
int x, y;
|
||||
unsigned char tmp[4];
|
||||
|
||||
for (x = 0; x < 4; x++) {
|
||||
tmp[x] = 0;
|
||||
for (y = 0; y < 8; y++)
|
||||
tmp[x] ^= gf_mult(in[y], RS[x][y], RS_POLY);
|
||||
}
|
||||
for (x = 0; x < 4; x++)
|
||||
out[x] = tmp[x];
|
||||
zeromem(tmp, 4);
|
||||
}
|
||||
|
||||
/* computes [y0 y1 y2 y3] = MDS . [x0] */
|
||||
#ifndef TWOFISH_TABLES
|
||||
static unsigned long mds_column_mult(unsigned char in, int col)
|
||||
{
|
||||
return
|
||||
(gf_mult(in, MDS[0][col], MDS_POLY) << 0) |
|
||||
(gf_mult(in, MDS[1][col], MDS_POLY) << 8) |
|
||||
(gf_mult(in, MDS[2][col], MDS_POLY) << 16) |
|
||||
(gf_mult(in, MDS[3][col], MDS_POLY) << 24);
|
||||
}
|
||||
#else
|
||||
static unsigned long mds_column_mult(unsigned char in, int col)
|
||||
{
|
||||
unsigned long x01, x5B, xEF;
|
||||
|
||||
x01 = in;
|
||||
x5B = GF_5B[in];
|
||||
xEF = GF_EF[in];
|
||||
|
||||
switch (col) {
|
||||
case 0:
|
||||
return (x01 << 0 ) |
|
||||
(x5B << 8 ) |
|
||||
(xEF << 16) |
|
||||
(xEF << 24);
|
||||
case 1:
|
||||
return (xEF << 0 ) |
|
||||
(xEF << 8 ) |
|
||||
(x5B << 16) |
|
||||
(x01 << 24);
|
||||
case 2:
|
||||
return (x5B << 0 ) |
|
||||
(xEF << 8 ) |
|
||||
(x01 << 16) |
|
||||
(xEF << 24);
|
||||
case 3:
|
||||
return (x5B << 0 ) |
|
||||
(x01 << 8 ) |
|
||||
(xEF << 16) |
|
||||
(x5B << 24);
|
||||
}
|
||||
/* avoid warnings, we'd never get here normally but just to calm compiler warnings... */
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* computes h(x) */
|
||||
static void h_func(const unsigned char *in, unsigned char *out, unsigned char *M, int k, int offset)
|
||||
{
|
||||
int x;
|
||||
unsigned char y[4];
|
||||
|
||||
for (x = 0; x < 4; x++)
|
||||
y[x] = in[x];
|
||||
|
||||
switch (k) {
|
||||
case 4:
|
||||
y[0] = sbox(1, y[0]) ^ M[4 * (6 + offset) + 0];
|
||||
y[1] = sbox(0, y[1]) ^ M[4 * (6 + offset) + 1];
|
||||
y[2] = sbox(0, y[2]) ^ M[4 * (6 + offset) + 2];
|
||||
y[3] = sbox(1, y[3]) ^ M[4 * (6 + offset) + 3];
|
||||
case 3:
|
||||
y[0] = sbox(1, y[0]) ^ M[4 * (4 + offset) + 0];
|
||||
y[1] = sbox(1, y[1]) ^ M[4 * (4 + offset) + 1];
|
||||
y[2] = sbox(0, y[2]) ^ M[4 * (4 + offset) + 2];
|
||||
y[3] = sbox(0, y[3]) ^ M[4 * (4 + offset) + 3];
|
||||
case 2:
|
||||
y[0] = sbox(1, sbox(0, sbox(0, y[0]) ^ M[4 * (2 + offset) + 0]) ^ M[4 * (0 + offset) + 0]);
|
||||
y[1] = sbox(0, sbox(0, sbox(1, y[1]) ^ M[4 * (2 + offset) + 1]) ^ M[4 * (0 + offset) + 1]);
|
||||
y[2] = sbox(1, sbox(1, sbox(0, y[2]) ^ M[4 * (2 + offset) + 2]) ^ M[4 * (0 + offset) + 2]);
|
||||
y[3] = sbox(0, sbox(1, sbox(1, y[3]) ^ M[4 * (2 + offset) + 3]) ^ M[4 * (0 + offset) + 3]);
|
||||
}
|
||||
mds_mult(y, out);
|
||||
}
|
||||
|
||||
#ifndef TWOFISH_SMALL
|
||||
|
||||
static unsigned long g_func(unsigned long x, symmetric_key *key)
|
||||
{
|
||||
return
|
||||
key->twofish.S[0][(x>>0)&255] ^
|
||||
key->twofish.S[1][(x>>8)&255] ^
|
||||
key->twofish.S[2][(x>>16)&255] ^
|
||||
key->twofish.S[3][(x>>24)&255];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static unsigned long _g_func(unsigned long x, symmetric_key *key)
|
||||
#else
|
||||
unsigned long g_func(unsigned long x, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
unsigned char g, i, y, z;
|
||||
unsigned long res;
|
||||
|
||||
res = 0;
|
||||
for (y = 0; y < 4; y++) {
|
||||
z = key->twofish.start;
|
||||
|
||||
/* do unkeyed substitution */
|
||||
g = sbox(qord[y][z++], (x >> (8*y)) & 255);
|
||||
|
||||
/* first subkey */
|
||||
i = 0;
|
||||
|
||||
/* do key mixing+sbox until z==5 */
|
||||
while (z != 5) {
|
||||
g = g ^ key->twofish.S[4*i++ + y];
|
||||
g = sbox(qord[y][z++], g);
|
||||
}
|
||||
|
||||
/* multiply g by a column of the MDS */
|
||||
res ^= mds_column_mult(g, y);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static unsigned long g_func(unsigned long x, symmetric_key *key)
|
||||
{
|
||||
unsigned long y;
|
||||
y = _g_func(x, key);
|
||||
burn_stack(sizeof(unsigned char) * 4 + sizeof(unsigned long));
|
||||
return y;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static int _twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
#else
|
||||
int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
#ifndef TWOFISH_SMALL
|
||||
int g, z, i;
|
||||
unsigned char S[4*4];
|
||||
#endif
|
||||
int k, x, y, start;
|
||||
unsigned char tmp[4], tmp2[4], M[8*4];
|
||||
unsigned long A, B;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
/* invalid arguments? */
|
||||
if (num_rounds != 16 && num_rounds != 0) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (keylen != 16 && keylen != 24 && keylen != 32) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
/* k = keysize/64 [but since our keysize is in bytes...] */
|
||||
k = keylen / 8;
|
||||
|
||||
/* copy the key into M */
|
||||
for (x = 0; x < keylen; x++)
|
||||
M[x] = key[x];
|
||||
|
||||
/* create the S[..] words */
|
||||
#ifndef TWOFISH_SMALL
|
||||
for (x = 0; x < k; x++)
|
||||
rs_mult(M+(x*8), S+(x*4));
|
||||
#else
|
||||
for (x = 0; x < k; x++)
|
||||
rs_mult(M+(x*8), skey->twofish.S+(x*4));
|
||||
#endif
|
||||
|
||||
/* make subkeys */
|
||||
for (x = 0; x < 20; x++) {
|
||||
/* A = h(p * 2x, Me) */
|
||||
for (y = 0; y < 4; y++)
|
||||
tmp[y] = x+x;
|
||||
h_func(tmp, tmp2, M, k, 0);
|
||||
LOAD32L(A, tmp2);
|
||||
|
||||
/* B = ROL(h(p * (2x + 1), Mo), 8) */
|
||||
for (y = 0; y < 4; y++)
|
||||
tmp[y] = x+x+1;
|
||||
h_func(tmp, tmp2, M, k, 1);
|
||||
LOAD32L(B, tmp2);
|
||||
B = ROL(B, 8);
|
||||
|
||||
/* K[2i] = A + B */
|
||||
skey->twofish.K[x+x] = (A + B) & 0xFFFFFFFFUL;
|
||||
|
||||
/* K[2i+1] = (A + 2B) <<< 9 */
|
||||
skey->twofish.K[x+x+1] = ROL(B + B + A, 9);
|
||||
}
|
||||
|
||||
/* where to start in the sbox layers */
|
||||
switch (k) {
|
||||
case 4 : start = 0; break;
|
||||
case 3 : start = 1; break;
|
||||
default: start = 2; break;
|
||||
}
|
||||
|
||||
#ifndef TWOFISH_SMALL
|
||||
/* make the sboxes (large ram variant) */
|
||||
for (y = 0; y < 4; y++) {
|
||||
for (x = 0; x < 256; x++) {
|
||||
z = start;
|
||||
|
||||
/* do unkeyed substitution */
|
||||
g = sbox(qord[y][z++], x);
|
||||
|
||||
/* first subkey */
|
||||
i = 0;
|
||||
|
||||
/* do key mixing+sbox until z==5 */
|
||||
while (z != 5) {
|
||||
g = g ^ S[4*i++ + y];
|
||||
g = sbox(qord[y][z++], g);
|
||||
}
|
||||
|
||||
/* multiply g by a column of the MDS */
|
||||
skey->twofish.S[y][x] = mds_column_mult(g, y);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* small ram variant */
|
||||
skey->twofish.start = start;
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
{
|
||||
int x;
|
||||
x = _twofish_setup(key, keylen, num_rounds, skey);
|
||||
burn_stack(sizeof(int) * 7 + sizeof(unsigned char) * 56 + sizeof(unsigned long) * 2);
|
||||
return x;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#else
|
||||
void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
unsigned long a,b,c,d,ta,tb,tc,td,t1,t2;
|
||||
int r;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
LOAD32L(a,&pt[0]); LOAD32L(b,&pt[4]);
|
||||
LOAD32L(c,&pt[8]); LOAD32L(d,&pt[12]);
|
||||
a ^= key->twofish.K[0];
|
||||
b ^= key->twofish.K[1];
|
||||
c ^= key->twofish.K[2];
|
||||
d ^= key->twofish.K[3];
|
||||
|
||||
for (r = 0; r < 16; r += 2) {
|
||||
t1 = g_func(a, key);
|
||||
t2 = g_func(ROL(b, 8), key);
|
||||
t2 += (t1 += t2);
|
||||
t1 += key->twofish.K[r+r+8];
|
||||
t2 += key->twofish.K[r+r+9];
|
||||
c ^= t1; c = ROR(c, 1);
|
||||
d = ROL(d, 1) ^ t2;
|
||||
|
||||
t1 = g_func(c, key);
|
||||
t2 = g_func(ROL(d, 8), key);
|
||||
t2 += (t1 += t2);
|
||||
t1 += key->twofish.K[r+r+10];
|
||||
t2 += key->twofish.K[r+r+11];
|
||||
a ^= t1; a = ROR(a, 1);
|
||||
b = ROL(b, 1) ^ t2;
|
||||
}
|
||||
|
||||
/* output with "undo last swap" */
|
||||
ta = c ^ key->twofish.K[4];
|
||||
tb = d ^ key->twofish.K[5];
|
||||
tc = a ^ key->twofish.K[6];
|
||||
td = b ^ key->twofish.K[7];
|
||||
|
||||
/* store output */
|
||||
STORE32L(ta,&ct[0]); STORE32L(tb,&ct[4]);
|
||||
STORE32L(tc,&ct[8]); STORE32L(td,&ct[12]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
{
|
||||
_twofish_ecb_encrypt(pt, ct, key);
|
||||
burn_stack(sizeof(unsigned long) * 10 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#else
|
||||
void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
unsigned long a,b,c,d,ta,tb,tc,td,t1,t2;
|
||||
int r;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* load input */
|
||||
LOAD32L(ta,&ct[0]); LOAD32L(tb,&ct[4]);
|
||||
LOAD32L(tc,&ct[8]); LOAD32L(td,&ct[12]);
|
||||
|
||||
/* undo undo final swap */
|
||||
a = tc ^ key->twofish.K[6];
|
||||
b = td ^ key->twofish.K[7];
|
||||
c = ta ^ key->twofish.K[4];
|
||||
d = tb ^ key->twofish.K[5];
|
||||
|
||||
for (r = 14; r >= 0; r -= 2) {
|
||||
t1 = g_func(c, key);
|
||||
t2 = g_func(ROL(d, 8), key);
|
||||
t2 += (t1 += t2);
|
||||
t1 += key->twofish.K[r+r+10];
|
||||
t2 += key->twofish.K[r+r+11];
|
||||
a = ROL(a, 1) ^ t1;
|
||||
b = b ^ t2; b = ROR(b, 1);
|
||||
|
||||
t1 = g_func(a, key);
|
||||
t2 = g_func(ROL(b, 8), key);
|
||||
t2 += (t1 += t2);
|
||||
t1 += key->twofish.K[r+r+8];
|
||||
t2 += key->twofish.K[r+r+9];
|
||||
c = ROL(c, 1) ^ t1;
|
||||
d = d ^ t2; d = ROR(d, 1);
|
||||
}
|
||||
|
||||
/* pre-white */
|
||||
a ^= key->twofish.K[0];
|
||||
b ^= key->twofish.K[1];
|
||||
c ^= key->twofish.K[2];
|
||||
d ^= key->twofish.K[3];
|
||||
|
||||
/* store */
|
||||
STORE32L(a, &pt[0]); STORE32L(b, &pt[4]);
|
||||
STORE32L(c, &pt[8]); STORE32L(d, &pt[12]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
{
|
||||
_twofish_ecb_decrypt(ct, pt, key);
|
||||
burn_stack(sizeof(unsigned long) * 10 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
int twofish_test(void)
|
||||
{
|
||||
static const unsigned char key128[16] = {
|
||||
0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32,
|
||||
0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A };
|
||||
static const unsigned char pt128[16] = {
|
||||
0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E,
|
||||
0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 };
|
||||
static const unsigned char ct128[16] = {
|
||||
0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85,
|
||||
0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 };
|
||||
|
||||
static const unsigned char key192[24] = {
|
||||
0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36,
|
||||
0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88,
|
||||
0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 };
|
||||
static const unsigned char pt192[16] = {
|
||||
0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5,
|
||||
0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 };
|
||||
static const unsigned char ct192[16] = {
|
||||
0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45,
|
||||
0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 };
|
||||
|
||||
static const unsigned char key256[32] = {
|
||||
0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46,
|
||||
0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D,
|
||||
0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B,
|
||||
0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F };
|
||||
static const unsigned char pt256[16] = {
|
||||
0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F,
|
||||
0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 };
|
||||
static const unsigned char ct256[16] = {
|
||||
0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97,
|
||||
0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA };
|
||||
|
||||
symmetric_key key;
|
||||
unsigned char tmp[2][16];
|
||||
int errno;
|
||||
|
||||
if ((errno = twofish_setup(key128, 16, 0, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
twofish_ecb_encrypt(pt128, tmp[0], &key);
|
||||
twofish_ecb_decrypt(tmp[0], tmp[1], &key);
|
||||
if (memcmp(tmp[0], ct128, 16) || memcmp(tmp[1], pt128, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
if ((errno = twofish_setup(key192, 24, 0, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
twofish_ecb_encrypt(pt192, tmp[0], &key);
|
||||
twofish_ecb_decrypt(tmp[0], tmp[1], &key);
|
||||
if (memcmp(tmp[0], ct192, 16) || memcmp(tmp[1], pt192, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
if ((errno = twofish_setup(key256, 32, 0, &key)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
twofish_ecb_encrypt(pt256, tmp[0], &key);
|
||||
twofish_ecb_decrypt(tmp[0], tmp[1], &key);
|
||||
if (memcmp(tmp[0], ct256, 16) || memcmp(tmp[1], pt256, 16)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int twofish_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize);
|
||||
if (*desired_keysize < 16)
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
if (*desired_keysize < 24) {
|
||||
*desired_keysize = 16;
|
||||
return CRYPT_OK;
|
||||
} else if (*desired_keysize < 32) {
|
||||
*desired_keysize = 24;
|
||||
return CRYPT_OK;
|
||||
} else {
|
||||
*desired_keysize = 32;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
121
xtea.c
Normal file
121
xtea.c
Normal file
@ -0,0 +1,121 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef XTEA
|
||||
|
||||
const struct _cipher_descriptor xtea_desc =
|
||||
{
|
||||
"xtea",
|
||||
1,
|
||||
16, 16, 8, 32,
|
||||
&xtea_setup,
|
||||
&xtea_ecb_encrypt,
|
||||
&xtea_ecb_decrypt,
|
||||
&xtea_test,
|
||||
&xtea_keysize
|
||||
};
|
||||
|
||||
int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
/* check arguments */
|
||||
if (keylen != 16) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
if (num_rounds != 0 && num_rounds != 32) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
/* load key */
|
||||
LOAD32L(skey->xtea.K[0], key+0);
|
||||
LOAD32L(skey->xtea.K[1], key+4);
|
||||
LOAD32L(skey->xtea.K[2], key+8);
|
||||
LOAD32L(skey->xtea.K[3], key+12);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
void xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
{
|
||||
unsigned long y, z, sum;
|
||||
int r;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
LOAD32L(y, &pt[0]);
|
||||
LOAD32L(z, &pt[4]);
|
||||
sum = 0;
|
||||
for (r = 0; r < 32; r++) {
|
||||
y = (y + ((((z<<4)^(z>>5)) + z) ^ (sum + key->xtea.K[sum&3]))) & 0xFFFFFFFFUL;
|
||||
sum = (sum + 0x9E3779B9UL) & 0xFFFFFFFFUL;
|
||||
z = (z + ((((y<<4)^(y>>5)) + y) ^ (sum + key->xtea.K[(sum>>11)&3]))) & 0xFFFFFFFFUL;
|
||||
}
|
||||
STORE32L(y, &ct[0]);
|
||||
STORE32L(z, &ct[4]);
|
||||
}
|
||||
|
||||
void xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
{
|
||||
unsigned long y, z, sum;
|
||||
int r;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
LOAD32L(y, &ct[0]);
|
||||
LOAD32L(z, &ct[4]);
|
||||
sum = (32UL*0x9E3779B9UL)&0xFFFFFFFFUL;
|
||||
for (r = 0; r < 32; r++) {
|
||||
z = (z - ((((y<<4)^(y>>5)) + y) ^ (sum + key->xtea.K[(sum>>11)&3]))) & 0xFFFFFFFFUL;
|
||||
sum = (sum - 0x9E3779B9UL) & 0xFFFFFFFFUL;
|
||||
y = (y - ((((z<<4)^(z>>5)) + z) ^ (sum + key->xtea.K[sum&3]))) & 0xFFFFFFFFUL;
|
||||
}
|
||||
STORE32L(y, &pt[0]);
|
||||
STORE32L(z, &pt[4]);
|
||||
}
|
||||
|
||||
int xtea_test(void)
|
||||
{
|
||||
static const unsigned char key[16] =
|
||||
{ 0x78, 0x56, 0x34, 0x12, 0xf0, 0xcd, 0xcb, 0x9a,
|
||||
0x48, 0x37, 0x26, 0x15, 0xc0, 0xbf, 0xae, 0x9d };
|
||||
static const unsigned char pt[8] =
|
||||
{ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
|
||||
static const unsigned char ct[8] =
|
||||
{ 0x75, 0xd7, 0xc5, 0xbf, 0xcf, 0x58, 0xc9, 0x3f };
|
||||
unsigned char tmp[2][8];
|
||||
symmetric_key skey;
|
||||
int errno;
|
||||
|
||||
if ((errno = xtea_setup(key, 16, 0, &skey)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
xtea_ecb_encrypt(pt, tmp[0], &skey);
|
||||
xtea_ecb_decrypt(tmp[0], tmp[1], &skey);
|
||||
|
||||
if (memcmp(tmp[0], ct, 8) || memcmp(tmp[1], pt, 8)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int xtea_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize);
|
||||
if (*desired_keysize < 16) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
*desired_keysize = 16;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
144
yarrow.c
Normal file
144
yarrow.c
Normal file
@ -0,0 +1,144 @@
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef YARROW
|
||||
|
||||
const struct _prng_descriptor yarrow_desc =
|
||||
{
|
||||
"yarrow",
|
||||
&yarrow_start,
|
||||
&yarrow_add_entropy,
|
||||
&yarrow_ready,
|
||||
&yarrow_read
|
||||
};
|
||||
|
||||
int yarrow_start(prng_state *prng)
|
||||
{
|
||||
int errno;
|
||||
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
/* these are the default hash/cipher combo used */
|
||||
#ifdef RIJNDAEL
|
||||
prng->yarrow.cipher = register_cipher(&rijndael_desc);
|
||||
#elif defined(BLOWFISH)
|
||||
prng->yarrow.cipher = register_cipher(&blowfish_desc);
|
||||
#elif defined(TWOFISH)
|
||||
prng->yarrow.cipher = register_cipher(&twofish_desc);
|
||||
#elif defined(CAST5)
|
||||
prng->yarrow.cipher = register_cipher(&cast5_desc);
|
||||
#elif defined(SERPENT)
|
||||
prng->yarrow.cipher = register_cipher(&serpent_desc);
|
||||
#elif defined(SAFER)
|
||||
prng->yarrow.cipher = register_cipher(&saferp_desc);
|
||||
#elif defined(RC5)
|
||||
prng->yarrow.cipher = register_cipher(&rc5_desc);
|
||||
#elif defined(RC6)
|
||||
prng->yarrow.cipher = register_cipher(&rc6_desc);
|
||||
#elif defined(XTEA)
|
||||
prng->yarrow.cipher = register_cipher(&xtea_desc);
|
||||
#elif defined(RC2)
|
||||
prng->yarrow.cipher = register_cipher(&rc2_desc);
|
||||
#elif defined(DES)
|
||||
prng->yarrow.cipher = register_cipher(&des3_desc);
|
||||
#elif
|
||||
#error YARROW needs at least one CIPHER
|
||||
#endif
|
||||
if ((errno = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
#ifdef SHA256
|
||||
prng->yarrow.hash = register_hash(&sha256_desc);
|
||||
#elif defined(SHA512)
|
||||
prng->yarrow.hash = register_hash(&sha512_desc);
|
||||
#elif defined(SHA384)
|
||||
prng->yarrow.hash = register_hash(&sha384_desc);
|
||||
#elif defined(SHA1)
|
||||
prng->yarrow.hash = register_hash(&sha1_desc);
|
||||
#elif defined(TIGER)
|
||||
prng->yarrow.hash = register_hash(&tiger_desc);
|
||||
#elif defined(MD5)
|
||||
prng->yarrow.hash = register_hash(&md5_desc);
|
||||
#elif defined(MD4)
|
||||
prng->yarrow.hash = register_hash(&md4_desc);
|
||||
#elif defined(MD2)
|
||||
prng->yarrow.hash = register_hash(&md2_desc);
|
||||
#else
|
||||
#error YARROW needs at least one HASH
|
||||
#endif
|
||||
if ((errno = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* zero the memory used */
|
||||
zeromem(prng->yarrow.pool, sizeof(prng->yarrow.pool));
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
|
||||
{
|
||||
hash_state md;
|
||||
int errno;
|
||||
|
||||
_ARGCHK(buf != NULL);
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
if ((errno = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* start the hash */
|
||||
hash_descriptor[prng->yarrow.hash].init(&md);
|
||||
|
||||
/* hash the current pool */
|
||||
hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, hash_descriptor[prng->yarrow.hash].hashsize);
|
||||
|
||||
/* add the new entropy */
|
||||
hash_descriptor[prng->yarrow.hash].process(&md, buf, len);
|
||||
|
||||
/* store result */
|
||||
hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int yarrow_ready(prng_state *prng)
|
||||
{
|
||||
int ks, errno;
|
||||
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
if ((errno = hash_is_valid(prng->yarrow.hash)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = cipher_is_valid(prng->yarrow.cipher)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
/* setup CTR mode using the "pool" as the key */
|
||||
ks = hash_descriptor[prng->yarrow.hash].hashsize;
|
||||
if ((errno = cipher_descriptor[prng->yarrow.cipher].keysize(&ks)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
if ((errno = ctr_start(prng->yarrow.cipher, prng->yarrow.pool, prng->yarrow.pool, ks, 0, &prng->yarrow.ctr)) != CRYPT_OK) {
|
||||
return errno;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
unsigned long yarrow_read(unsigned char *buf, unsigned long len, prng_state *prng)
|
||||
{
|
||||
_ARGCHK(buf != NULL);
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
if (ctr_encrypt(buf, buf, len, &prng->yarrow.ctr) != CRYPT_OK) {
|
||||
return 0;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user