added libtomcrypt-0.96

This commit is contained in:
Tom St Denis 2004-05-31 02:36:47 +00:00 committed by Steffen Jaeckel
parent 40c5578ac3
commit 3fe312ccef
92 changed files with 3451 additions and 5214 deletions

38
PLAN
View File

@ -1,38 +0,0 @@
The following functions are marked for removal and/or behavioural change by v1.00 of LibTomCrypt
1. RSA Support
rsa_pad, rsa_signpad, rsa_depad, rsa_signdepad, rsa_import, rsa_export
They will be replaced with PKCS #1 compliant OAEP/PSS padding function as early as v0.96
2. DSA Support
dsa_import, dsa_export
Will be replaced with suitable DSS [what is the standard?] compliant formats. Planned for v0.96
3. Key Ring Support
(all)
The entire API will be dropped as early as v0.96. It was just an experiment and nobody uses it anyways.
4. Test Harness
demos/test.c
The test harness is well overdue for a makeover. Planned for as early as v0.97
Put things in order...
v0.96 -- removed keyring.c and gf.c
-- removed LTC RSA padding
-- DSS support [whatever this entails]
-- Bug fixes/updates to the PKCS/DSS support, should be stable in this release
v0.97 -- Re-written test harness
-- More demos in the manual and demos/ directory
... future???

285
aes.c
View File

@ -30,16 +30,20 @@
#ifdef RIJNDAEL #ifdef RIJNDAEL
#ifndef ENCRYPT_ONLY
#define SETUP rijndael_setup
#define ECB_ENC rijndael_ecb_encrypt
#define ECB_DEC rijndael_ecb_decrypt
#define ECB_TEST rijndael_test
#define ECB_KS rijndael_keysize
const struct _cipher_descriptor rijndael_desc = const struct _cipher_descriptor rijndael_desc =
{ {
"rijndael", "rijndael",
6, 6,
16, 32, 16, 10, 16, 32, 16, 10,
&rijndael_setup, SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_KS
&rijndael_ecb_encrypt,
&rijndael_ecb_decrypt,
&rijndael_test,
&rijndael_keysize
}; };
const struct _cipher_descriptor aes_desc = const struct _cipher_descriptor aes_desc =
@ -47,21 +51,63 @@ const struct _cipher_descriptor aes_desc =
"aes", "aes",
6, 6,
16, 32, 16, 10, 16, 32, 16, 10,
&rijndael_setup, SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_KS
&rijndael_ecb_encrypt,
&rijndael_ecb_decrypt,
&rijndael_test,
&rijndael_keysize
}; };
#else
#define SETUP rijndael_enc_setup
#define ECB_ENC rijndael_enc_ecb_encrypt
#define ECB_KS rijndael_enc_keysize
const struct _cipher_descriptor rijndael_enc_desc =
{
"rijndael",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_KS
};
const struct _cipher_descriptor aes_enc_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_KS
};
#endif
#include "aes_tab.c" #include "aes_tab.c"
int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey) static ulong32 setup_mix(ulong32 temp)
{
return (Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]);
}
#ifndef ENCRYPT_ONLY
static ulong32 setup_mix2(ulong32 temp)
{
return Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
}
#endif
int SETUP(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
{ {
int i, j; int i, j;
ulong32 temp, *rk, *rrk; ulong32 temp, *rk;
#ifndef ENCRYPT_ONLY
_ARGCHK(key != NULL); ulong32 *rrk;
#endif
_ARGCHK(key != NULL);
_ARGCHK(skey != NULL); _ARGCHK(skey != NULL);
if (keylen != 16 && keylen != 24 && keylen != 32) { if (keylen != 16 && keylen != 24 && keylen != 32) {
@ -85,12 +131,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
j = 44; j = 44;
for (;;) { for (;;) {
temp = rk[3]; temp = rk[3];
rk[4] = rk[0] ^ rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
(Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]) ^
rcon[i];
rk[5] = rk[1] ^ rk[4]; rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5]; rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6]; rk[7] = rk[3] ^ rk[6];
@ -109,12 +150,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
#else #else
temp = rk[5]; temp = rk[5];
#endif #endif
rk[ 6] = rk[ 0] ^ rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
(Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]) ^
rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7]; rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8]; rk[ 9] = rk[ 3] ^ rk[ 8];
@ -137,12 +173,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
#else #else
temp = rk[7]; temp = rk[7];
#endif #endif
rk[ 8] = rk[ 0] ^ rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
(Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]) ^
rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8]; rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9]; rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10]; rk[11] = rk[ 3] ^ rk[10];
@ -150,11 +181,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
break; break;
} }
temp = rk[11]; temp = rk[11];
rk[12] = rk[ 4] ^ rk[12] = rk[ 4] ^ setup_mix(ROR(temp, 8));
(Te4_3[byte(temp, 3)]) ^
(Te4_2[byte(temp, 2)]) ^
(Te4_1[byte(temp, 1)]) ^
(Te4_0[byte(temp, 0)]);
rk[13] = rk[ 5] ^ rk[12]; rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13]; rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14]; rk[15] = rk[ 7] ^ rk[14];
@ -165,6 +192,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
j = 4; j = 4;
} }
#ifndef ENCRYPT_ONLY
/* setup the inverse key now */ /* setup the inverse key now */
rk = skey->rijndael.dK; rk = skey->rijndael.dK;
rrk = skey->rijndael.eK + j - 4; rrk = skey->rijndael.eK + j - 4;
@ -182,29 +210,13 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
rk += 4; rk += 4;
#ifdef SMALL_CODE #ifdef SMALL_CODE
temp = rrk[0]; temp = rrk[0];
rk[0] = rk[0] = setup_mix2(temp);
Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
temp = rrk[1]; temp = rrk[1];
rk[1] = rk[1] = setup_mix2(temp);
Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
temp = rrk[2]; temp = rrk[2];
rk[2] = rk[2] = setup_mix2(temp);
Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
temp = rrk[3]; temp = rrk[3];
rk[3] = rk[3] = setup_mix2(temp);
Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
#else #else
temp = rrk[0]; temp = rrk[0];
rk[0] = rk[0] =
@ -241,6 +253,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
*rk++ = *rrk++; *rk++ = *rrk++;
*rk++ = *rrk++; *rk++ = *rrk++;
*rk = *rrk; *rk = *rrk;
#endif /* ENCRYPT_ONLY */
return CRYPT_OK; return CRYPT_OK;
} }
@ -248,7 +261,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else #else
void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif #endif
{ {
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@ -270,6 +283,44 @@ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
LOAD32H(s2, pt + 8); s2 ^= rk[2]; LOAD32H(s2, pt + 8); s2 ^= rk[2];
LOAD32H(s3, pt + 12); s3 ^= rk[3]; LOAD32H(s3, pt + 12); s3 ^= rk[3];
#ifdef SMALL_CODE
for (r = 0; ; r++) {
rk += 4;
t0 =
Te0(byte(s0, 3)) ^
Te1(byte(s1, 2)) ^
Te2(byte(s2, 1)) ^
Te3(byte(s3, 0)) ^
rk[0];
t1 =
Te0(byte(s1, 3)) ^
Te1(byte(s2, 2)) ^
Te2(byte(s3, 1)) ^
Te3(byte(s0, 0)) ^
rk[1];
t2 =
Te0(byte(s2, 3)) ^
Te1(byte(s3, 2)) ^
Te2(byte(s0, 1)) ^
Te3(byte(s1, 0)) ^
rk[2];
t3 =
Te0(byte(s3, 3)) ^
Te1(byte(s0, 2)) ^
Te2(byte(s1, 1)) ^
Te3(byte(s2, 0)) ^
rk[3];
if (r == Nr-2) {
break;
}
s0 = t0; s1 = t1; s2 = t2; s3 = t3;
}
rk += 4;
#else
/* /*
* Nr - 1 full rounds: * Nr - 1 full rounds:
*/ */
@ -330,52 +381,57 @@ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
Te3(byte(t2, 0)) ^ Te3(byte(t2, 0)) ^
rk[3]; rk[3];
} }
#endif
/* /*
* apply last round and * apply last round and
* map cipher state to byte array block: * map cipher state to byte array block:
*/ */
s0 = s0 =
(Te4_3[(t0 >> 24) ]) ^ (Te4_3[byte(t0, 3)]) ^
(Te4_2[(t1 >> 16) & 0xff]) ^ (Te4_2[byte(t1, 2)]) ^
(Te4_1[(t2 >> 8) & 0xff]) ^ (Te4_1[byte(t2, 1)]) ^
(Te4_0[(t3 ) & 0xff]) ^ (Te4_0[byte(t3, 0)]) ^
rk[0]; rk[0];
STORE32H(s0, ct); STORE32H(s0, ct);
s1 = s1 =
(Te4_3[(t1 >> 24) ]) ^ (Te4_3[byte(t1, 3)]) ^
(Te4_2[(t2 >> 16) & 0xff]) ^ (Te4_2[byte(t2, 2)]) ^
(Te4_1[(t3 >> 8) & 0xff]) ^ (Te4_1[byte(t3, 1)]) ^
(Te4_0[(t0 ) & 0xff]) ^ (Te4_0[byte(t0, 0)]) ^
rk[1]; rk[1];
STORE32H(s1, ct+4); STORE32H(s1, ct+4);
s2 = s2 =
(Te4_3[(t2 >> 24) ]) ^ (Te4_3[byte(t2, 3)]) ^
(Te4_2[(t3 >> 16) & 0xff]) ^ (Te4_2[byte(t3, 2)]) ^
(Te4_1[(t0 >> 8) & 0xff]) ^ (Te4_1[byte(t0, 1)]) ^
(Te4_0[(t1 ) & 0xff]) ^ (Te4_0[byte(t1, 0)]) ^
rk[2]; rk[2];
STORE32H(s2, ct+8); STORE32H(s2, ct+8);
s3 = s3 =
(Te4_3[(t3 >> 24) ]) ^ (Te4_3[byte(t3, 3)]) ^
(Te4_2[(t0 >> 16) & 0xff]) ^ (Te4_2[byte(t0, 2)]) ^
(Te4_1[(t1 >> 8) & 0xff]) ^ (Te4_1[byte(t1, 1)]) ^
(Te4_0[(t2 ) & 0xff]) ^ (Te4_0[byte(t2, 0)]) ^
rk[3]; rk[3];
STORE32H(s3, ct+12); STORE32H(s3, ct+12);
} }
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey) void ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{ {
_rijndael_ecb_encrypt(pt, ct, skey); _rijndael_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
} }
#endif #endif
#ifndef ENCRYPT_ONLY
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else #else
void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif #endif
{ {
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk; ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
@ -397,6 +453,42 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
LOAD32H(s2, ct + 8); s2 ^= rk[2]; LOAD32H(s2, ct + 8); s2 ^= rk[2];
LOAD32H(s3, ct + 12); s3 ^= rk[3]; LOAD32H(s3, ct + 12); s3 ^= rk[3];
#ifdef SMALL_CODE
for (r = 0; ; r++) {
rk += 4;
t0 =
Td0(byte(s0, 3)) ^
Td1(byte(s3, 2)) ^
Td2(byte(s2, 1)) ^
Td3(byte(s1, 0)) ^
rk[0];
t1 =
Td0(byte(s1, 3)) ^
Td1(byte(s0, 2)) ^
Td2(byte(s3, 1)) ^
Td3(byte(s2, 0)) ^
rk[1];
t2 =
Td0(byte(s2, 3)) ^
Td1(byte(s1, 2)) ^
Td2(byte(s0, 1)) ^
Td3(byte(s3, 0)) ^
rk[2];
t3 =
Td0(byte(s3, 3)) ^
Td1(byte(s2, 2)) ^
Td2(byte(s1, 1)) ^
Td3(byte(s0, 0)) ^
rk[3];
if (r == Nr-2) {
break;
}
s0 = t0; s1 = t1; s2 = t2; s3 = t3;
}
rk += 4;
#else
/* /*
* Nr - 1 full rounds: * Nr - 1 full rounds:
*/ */
@ -459,51 +551,52 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
Td3(byte(t0, 0)) ^ Td3(byte(t0, 0)) ^
rk[3]; rk[3];
} }
#endif
/* /*
* apply last round and * apply last round and
* map cipher state to byte array block: * map cipher state to byte array block:
*/ */
s0 = s0 =
(Td4[(t0 >> 24) ] & 0xff000000) ^ (Td4[byte(t0, 3)] & 0xff000000) ^
(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[byte(t3, 2)] & 0x00ff0000) ^
(Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[byte(t2, 1)] & 0x0000ff00) ^
(Td4[(t1 ) & 0xff] & 0x000000ff) ^ (Td4[byte(t1, 0)] & 0x000000ff) ^
rk[0]; rk[0];
STORE32H(s0, pt); STORE32H(s0, pt);
s1 = s1 =
(Td4[(t1 >> 24) ] & 0xff000000) ^ (Td4[byte(t1, 3)] & 0xff000000) ^
(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[byte(t0, 2)] & 0x00ff0000) ^
(Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[byte(t3, 1)] & 0x0000ff00) ^
(Td4[(t2 ) & 0xff] & 0x000000ff) ^ (Td4[byte(t2, 0)] & 0x000000ff) ^
rk[1]; rk[1];
STORE32H(s1, pt+4); STORE32H(s1, pt+4);
s2 = s2 =
(Td4[(t2 >> 24) ] & 0xff000000) ^ (Td4[byte(t2, 3)] & 0xff000000) ^
(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[byte(t1, 2)] & 0x00ff0000) ^
(Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[byte(t0, 1)] & 0x0000ff00) ^
(Td4[(t3 ) & 0xff] & 0x000000ff) ^ (Td4[byte(t3, 0)] & 0x000000ff) ^
rk[2]; rk[2];
STORE32H(s2, pt+8); STORE32H(s2, pt+8);
s3 = s3 =
(Td4[(t3 >> 24) ] & 0xff000000) ^ (Td4[byte(t3, 3)] & 0xff000000) ^
(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^ (Td4[byte(t2, 2)] & 0x00ff0000) ^
(Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^ (Td4[byte(t1, 1)] & 0x0000ff00) ^
(Td4[(t0 ) & 0xff] & 0x000000ff) ^ (Td4[byte(t0, 0)] & 0x000000ff) ^
rk[3]; rk[3];
STORE32H(s3, pt+12); STORE32H(s3, pt+12);
} }
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey) void ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{ {
_rijndael_ecb_decrypt(ct, pt, skey); _rijndael_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2); burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
} }
#endif #endif
int rijndael_test(void) int ECB_TEST(void)
{ {
#ifndef LTC_TEST #ifndef LTC_TEST
return CRYPT_NOP; return CRYPT_NOP;
@ -584,7 +677,9 @@ int rijndael_test(void)
#endif #endif
} }
int rijndael_keysize(int *desired_keysize) #endif /* ENCRYPT_ONLY */
int ECB_KS(int *desired_keysize)
{ {
_ARGCHK(desired_keysize != NULL); _ARGCHK(desired_keysize != NULL);

View File

@ -157,6 +157,8 @@ static const ulong32 Te4[256] = {
0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL, 0xb0b0b0b0UL, 0x54545454UL, 0xbbbbbbbbUL, 0x16161616UL,
}; };
#ifndef ENCRYPT_ONLY
static const ulong32 TD0[256] = { static const ulong32 TD0[256] = {
0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL, 0x51f4a750UL, 0x7e416553UL, 0x1a17a4c3UL, 0x3a275e96UL,
0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL, 0x3bab6bcbUL, 0x1f9d45f1UL, 0xacfa58abUL, 0x4be30393UL,
@ -291,6 +293,8 @@ static const ulong32 Td4[256] = {
0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL, 0x55555555UL, 0x21212121UL, 0x0c0c0c0cUL, 0x7d7d7d7dUL,
}; };
#endif /* ENCRYPT_ONLY */
#ifdef SMALL_CODE #ifdef SMALL_CODE
#define Te0(x) TE0[x] #define Te0(x) TE0[x]
@ -660,6 +664,8 @@ static const ulong32 Te4_3[] = {
0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL 0x41000000UL, 0x99000000UL, 0x2d000000UL, 0x0f000000UL, 0xb0000000UL, 0x54000000UL, 0xbb000000UL, 0x16000000UL
}; };
#ifndef ENCRYPT_ONLY
static const ulong32 TD1[256] = { static const ulong32 TD1[256] = {
0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL, 0x5051f4a7UL, 0x537e4165UL, 0xc31a17a4UL, 0x963a275eUL,
0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL, 0xcb3bab6bUL, 0xf11f9d45UL, 0xabacfa58UL, 0x934be303UL,
@ -999,6 +1005,8 @@ static const ulong32 Tks3[] = {
0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL 0x79b492a7UL, 0x70b999a9UL, 0x6bae84bbUL, 0x62a38fb5UL, 0x5d80be9fUL, 0x548db591UL, 0x4f9aa883UL, 0x4697a38dUL
}; };
#endif /* ENCRYPT_ONLY */
#endif /* SMALL CODE */ #endif /* SMALL CODE */
static const ulong32 rcon[] = { static const ulong32 rcon[] = {

View File

@ -8,14 +8,12 @@
* *
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/ */
/* compliant base64 code donated by Wayne Scott (wscott@bitmover.com) */ /* compliant base64 code donated by Wayne Scott (wscott@bitmover.com) */
#include "mycrypt.h" #include "mycrypt.h"
#ifdef BASE64 #ifdef BASE64
static const char *codes =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static const unsigned char map[256] = { 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, 255, 255, 255, 255, 255,
@ -40,49 +38,6 @@ 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 };
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) & 0x3F];
*p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F];
*p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F];
*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;
*p++ = codes[(a >> 2) & 0x3F];
*p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F];
*p++ = (i+1 < len) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=';
*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, int base64_decode(const unsigned char *in, unsigned long len,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {

63
base64_encode.c Normal file
View File

@ -0,0 +1,63 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
/* compliant base64 code donated by Wayne Scott (wscott@bitmover.com) */
#include "mycrypt.h"
#ifdef BASE64
static const char *codes =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
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) & 0x3F];
*p++ = codes[(((in[0] & 3) << 4) + (in[1] >> 4)) & 0x3F];
*p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F];
*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;
*p++ = codes[(a >> 2) & 0x3F];
*p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F];
*p++ = (i+1 < len) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=';
*p++ = '=';
}
/* append a NULL byte */
*p = '\0';
/* return ok */
*outlen = p - out;
return CRYPT_OK;
}
#endif

View File

@ -25,14 +25,15 @@ int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc)
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) { if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
return err; return err;
} }
cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key); _ARGCHK(cipher_descriptor[cbc->cipher].ecb_decrypt != NULL);
/* is blocklen valid? */ /* is blocklen valid? */
if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) { if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) {
return CRYPT_INVALID_ARG; return CRYPT_INVALID_ARG;
} }
/* xor IV against the plaintext of the previous step */ /* decrypt and xor IV against the plaintext of the previous step */
cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
for (x = 0; x < cbc->blocklen; x++) { for (x = 0; x < cbc->blocklen; x++) {
/* copy CT in case ct == pt */ /* copy CT in case ct == pt */
tmp2[x] = ct[x]; tmp2[x] = ct[x];

30
cbc_getiv.c Normal file
View File

@ -0,0 +1,30 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef CBC
int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc)
{
_ARGCHK(IV != NULL);
_ARGCHK(len != NULL);
_ARGCHK(cbc != NULL);
if ((unsigned long)cbc->blocklen > *len) {
return CRYPT_BUFFER_OVERFLOW;
}
memcpy(IV, cbc->IV, cbc->blocklen);
*len = cbc->blocklen;
return CRYPT_OK;
}
#endif

28
cbc_setiv.c Normal file
View File

@ -0,0 +1,28 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef CBC
int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc)
{
_ARGCHK(IV != NULL);
_ARGCHK(cbc != NULL);
if (len != (unsigned long)cbc->blocklen) {
return CRYPT_INVALID_ARG;
}
memcpy(cbc->IV, IV, len);
return CRYPT_OK;
}
#endif

30
cfb_getiv.c Normal file
View File

@ -0,0 +1,30 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef CFB
int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb)
{
_ARGCHK(IV != NULL);
_ARGCHK(len != NULL);
_ARGCHK(cfb != NULL);
if ((unsigned long)cfb->blocklen > *len) {
return CRYPT_BUFFER_OVERFLOW;
}
memcpy(IV, cfb->IV, cfb->blocklen);
*len = cfb->blocklen;
return CRYPT_OK;
}
#endif

39
cfb_setiv.c Normal file
View File

@ -0,0 +1,39 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef CFB
int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
{
int err;
_ARGCHK(IV != NULL);
_ARGCHK(cfb != NULL);
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
return err;
}
if (len != (unsigned long)cfb->blocklen) {
return CRYPT_INVALID_ARG;
}
/* force next block */
cfb->padlen = 0;
cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
return CRYPT_OK;
}
#endif

25
changes
View File

@ -1,3 +1,28 @@
May 30th, 2004
v0.96 -- Removed GF and Keyring code
-- Extended OAEP decoder to distinguish better [and use a more uniform API]
-- Changed PSS/OAEP API slightly to be more consistent with other PK functions (order of arguments)
-- rsa_exptmod() now pads with leading zeroes as per I2OSP.
-- added error checking to yarrow code
-- Mike Frysinger pointed out that tommath.h from this distro will overwrite tommath.h
from libtommath. I changed this to ltc_tommath.h to avoid any such problems.
-- Fixed bug in PSS encoder/decoder that didn't handle the MSB properly
-- refactored AES, now sports an "encrypt only" descriptor which uses half as much code space.
-- modded Yarrow to try and use refactored AES code and added WHIRLPOOL support (d'oh) ;-)
-- updated ECB, OCB and CBC decrypt functions to detect when "encrypt only" descriptor is used.
-- replaced old RSA code with new code that uses PKCS #1 v2.0 padding
-- replaced old test harness with new over-engineer'ed one in /demos/test/
-- updated cbc/cfb/ofb/ctr code with setiv/getiv functions to change/read the IV without re-keying.
-- Added PKCS #1 v1.5 RSA encryption and signature padding routines
-- Added DER OID's to most hash descriptors (as many as I could find)
-- modded rsa_exptmod() to use timing-resilient tim_exptmod() when doing private key operations
added #define RSA_TIMING which can turn on/off this feature.
-- No more config.pl so please just read mycrypt_custom.h for build-time tweaks
-- Small update to rand_prime()
-- Updated sha1, md5 and sha256 so they are smaller when SMALL_CODE is defined. If you want speed though,
you're going to have to undefine SMALL_CODE ;-)
-- Worked over AES so that it's even smaller now [in both modes].
May 12th, 2004 May 12th, 2004
v0.95 -- Optimized AES and WHIRLPOOL for SMALL_CODE by taking advantage of the fact v0.95 -- Optimized AES and WHIRLPOOL for SMALL_CODE by taking advantage of the fact
the transforms are circulant. AES dropped 5KB and WHIRLPOOL dropped 13KB the transforms are circulant. AES dropped 5KB and WHIRLPOOL dropped 13KB

24
crypt.c
View File

@ -120,6 +120,9 @@ const char *crypt_build_settings =
#if defined(RIPEMD160) #if defined(RIPEMD160)
" RIPEMD160\n" " RIPEMD160\n"
#endif #endif
#if defined(WHIRLPOOL)
" WHIRLPOOL\n"
#endif
"\nBlock Chaining Modes:\n" "\nBlock Chaining Modes:\n"
#if defined(CFB) #if defined(CFB)
@ -151,7 +154,11 @@ const char *crypt_build_settings =
"\nPK Algs:\n" "\nPK Algs:\n"
#if defined(MRSA) #if defined(MRSA)
" RSA\n" " RSA"
#if defined(RSA_TIMING)
" + RSA_TIMING "
#endif
"\n"
#endif #endif
#if defined(MDH) #if defined(MDH)
" DH\n" " DH\n"
@ -162,9 +169,6 @@ const char *crypt_build_settings =
#if defined(MDSA) #if defined(MDSA)
" DSA\n" " DSA\n"
#endif #endif
#if defined(KR)
" KR\n"
#endif
"\nCompiler:\n" "\nCompiler:\n"
#if defined(WIN32) #if defined(WIN32)
@ -187,9 +191,6 @@ const char *crypt_build_settings =
#endif #endif
"\nVarious others: " "\nVarious others: "
#if defined(GF)
" GF "
#endif
#if defined(BASE64) #if defined(BASE64)
" BASE64 " " BASE64 "
#endif #endif
@ -222,6 +223,15 @@ const char *crypt_build_settings =
#endif #endif
#if defined(PKCS_5) #if defined(PKCS_5)
" PKCS#5 " " PKCS#5 "
#endif
#if defined(SMALL_CODE)
" SMALL_CODE "
#endif
#if defined(NO_FILE)
" NO_FILE "
#endif
#if defined(LTC_TEST)
" LTC_TEST "
#endif #endif
"\n" "\n"
"\n\n\n" "\n\n\n"

View File

@ -1,88 +0,0 @@
\BOOKMARK [0][-]{chapter.1}{Introduction}{}
\BOOKMARK [1][-]{section.1.1}{What is the LibTomCrypt?}{chapter.1}
\BOOKMARK [2][-]{subsection.1.1.1}{What the library IS for?}{section.1.1}
\BOOKMARK [2][-]{subsection.1.1.2}{What the library IS NOT for?}{section.1.1}
\BOOKMARK [1][-]{section.1.2}{Why did I write it?}{chapter.1}
\BOOKMARK [2][-]{subsection.1.2.1}{Modular}{section.1.2}
\BOOKMARK [1][-]{section.1.3}{License}{chapter.1}
\BOOKMARK [1][-]{section.1.4}{Patent Disclosure}{chapter.1}
\BOOKMARK [1][-]{section.1.5}{Building the library}{chapter.1}
\BOOKMARK [1][-]{section.1.6}{Building against the library}{chapter.1}
\BOOKMARK [1][-]{section.1.7}{Thanks}{chapter.1}
\BOOKMARK [0][-]{chapter.2}{The Application Programming Interface \(API\)}{}
\BOOKMARK [1][-]{section.2.1}{Introduction}{chapter.2}
\BOOKMARK [1][-]{section.2.2}{Macros}{chapter.2}
\BOOKMARK [1][-]{section.2.3}{Functions with Variable Length Output}{chapter.2}
\BOOKMARK [1][-]{section.2.4}{Functions that need a PRNG}{chapter.2}
\BOOKMARK [1][-]{section.2.5}{Functions that use Arrays of Octets}{chapter.2}
\BOOKMARK [0][-]{chapter.3}{Symmetric Block Ciphers}{}
\BOOKMARK [1][-]{section.3.1}{Core Functions}{chapter.3}
\BOOKMARK [1][-]{section.3.2}{Key Sizes and Number of Rounds}{chapter.3}
\BOOKMARK [1][-]{section.3.3}{The Cipher Descriptors}{chapter.3}
\BOOKMARK [2][-]{subsection.3.3.1}{Notes}{section.3.3}
\BOOKMARK [1][-]{section.3.4}{Symmetric Modes of Operations}{chapter.3}
\BOOKMARK [2][-]{subsection.3.4.1}{Background}{section.3.4}
\BOOKMARK [2][-]{subsection.3.4.2}{Choice of Mode}{section.3.4}
\BOOKMARK [2][-]{subsection.3.4.3}{Implementation}{section.3.4}
\BOOKMARK [1][-]{section.3.5}{Encrypt and Authenticate Modes}{chapter.3}
\BOOKMARK [2][-]{subsection.3.5.1}{EAX Mode}{section.3.5}
\BOOKMARK [2][-]{subsection.3.5.2}{OCB Mode}{section.3.5}
\BOOKMARK [0][-]{chapter.4}{One-Way Cryptographic Hash Functions}{}
\BOOKMARK [1][-]{section.4.1}{Core Functions}{chapter.4}
\BOOKMARK [1][-]{section.4.2}{Hash Descriptors}{chapter.4}
\BOOKMARK [2][-]{subsection.4.2.1}{Notice}{section.4.2}
\BOOKMARK [0][-]{chapter.5}{Message Authentication Codes}{}
\BOOKMARK [1][-]{section.5.1}{HMAC Protocol}{chapter.5}
\BOOKMARK [1][-]{section.5.2}{OMAC Support}{chapter.5}
\BOOKMARK [1][-]{section.5.3}{PMAC Support}{chapter.5}
\BOOKMARK [0][-]{chapter.6}{Pseudo-Random Number Generators}{}
\BOOKMARK [1][-]{section.6.1}{Core Functions}{chapter.6}
\BOOKMARK [2][-]{subsection.6.1.1}{Remarks}{section.6.1}
\BOOKMARK [2][-]{subsection.6.1.2}{Example}{section.6.1}
\BOOKMARK [1][-]{section.6.2}{PRNG Descriptors}{chapter.6}
\BOOKMARK [1][-]{section.6.3}{The Secure RNG}{chapter.6}
\BOOKMARK [2][-]{subsection.6.3.1}{The Secure PRNG Interface}{section.6.3}
\BOOKMARK [0][-]{chapter.7}{RSA Routines}{}
\BOOKMARK [1][-]{section.7.1}{Background}{chapter.7}
\BOOKMARK [1][-]{section.7.2}{Core Functions}{chapter.7}
\BOOKMARK [1][-]{section.7.3}{Packet Routines}{chapter.7}
\BOOKMARK [1][-]{section.7.4}{Remarks}{chapter.7}
\BOOKMARK [0][-]{chapter.8}{Diffie-Hellman Key Exchange}{}
\BOOKMARK [1][-]{section.8.1}{Background}{chapter.8}
\BOOKMARK [1][-]{section.8.2}{Core Functions}{chapter.8}
\BOOKMARK [2][-]{subsection.8.2.1}{Remarks on Usage}{section.8.2}
\BOOKMARK [2][-]{subsection.8.2.2}{Remarks on The Snippet}{section.8.2}
\BOOKMARK [1][-]{section.8.3}{Other Diffie-Hellman Functions}{chapter.8}
\BOOKMARK [1][-]{section.8.4}{DH Packet}{chapter.8}
\BOOKMARK [0][-]{chapter.9}{Elliptic Curve Cryptography}{}
\BOOKMARK [1][-]{section.9.1}{Background}{chapter.9}
\BOOKMARK [1][-]{section.9.2}{Core Functions}{chapter.9}
\BOOKMARK [1][-]{section.9.3}{ECC Packet}{chapter.9}
\BOOKMARK [1][-]{section.9.4}{ECC Keysizes}{chapter.9}
\BOOKMARK [0][-]{chapter.10}{Digital Signature Algorithm}{}
\BOOKMARK [1][-]{section.10.1}{Introduction}{chapter.10}
\BOOKMARK [1][-]{section.10.2}{Key Generation}{chapter.10}
\BOOKMARK [1][-]{section.10.3}{Key Verification}{chapter.10}
\BOOKMARK [1][-]{section.10.4}{Signatures}{chapter.10}
\BOOKMARK [1][-]{section.10.5}{Import and Export}{chapter.10}
\BOOKMARK [0][-]{chapter.11}{Public Keyrings}{}
\BOOKMARK [1][-]{section.11.1}{Introduction}{chapter.11}
\BOOKMARK [1][-]{section.11.2}{The Keyring API}{chapter.11}
\BOOKMARK [0][-]{chapter.12}{GF\(2w\) Math Routines}{}
\BOOKMARK [0][-]{chapter.13}{Miscellaneous}{}
\BOOKMARK [1][-]{section.13.1}{Base64 Encoding and Decoding}{chapter.13}
\BOOKMARK [1][-]{section.13.2}{The Multiple Precision Integer Library \(MPI\)}{chapter.13}
\BOOKMARK [2][-]{subsection.13.2.1}{Binary Forms of ``mp\137int'' Variables}{section.13.2}
\BOOKMARK [2][-]{subsection.13.2.2}{Primality Testing}{section.13.2}
\BOOKMARK [0][-]{chapter.14}{Programming Guidelines}{}
\BOOKMARK [1][-]{section.14.1}{Secure Pseudo Random Number Generators}{chapter.14}
\BOOKMARK [1][-]{section.14.2}{Preventing Trivial Errors}{chapter.14}
\BOOKMARK [1][-]{section.14.3}{Registering Your Algorithms}{chapter.14}
\BOOKMARK [1][-]{section.14.4}{Key Sizes}{chapter.14}
\BOOKMARK [2][-]{subsection.14.4.1}{Symmetric Ciphers}{section.14.4}
\BOOKMARK [2][-]{subsection.14.4.2}{Assymetric Ciphers}{section.14.4}
\BOOKMARK [1][-]{section.14.5}{Thread Safety}{chapter.14}
\BOOKMARK [0][-]{chapter.15}{Configuring the Library}{}
\BOOKMARK [1][-]{section.15.1}{Introduction}{chapter.15}
\BOOKMARK [1][-]{section.15.2}{mycrypt\137cfg.h}{chapter.15}
\BOOKMARK [1][-]{section.15.3}{The Configure Script}{chapter.15}

BIN
crypt.pdf

Binary file not shown.

1005
crypt.tex

File diff suppressed because it is too large Load Diff

View File

@ -11,35 +11,35 @@
#include "mycrypt.h" #include "mycrypt.h"
struct _hash_descriptor hash_descriptor[TAB_SIZE] = { struct _hash_descriptor hash_descriptor[TAB_SIZE] = {
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL }, { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL } }; { NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL } };

30
ctr_getiv.c Normal file
View File

@ -0,0 +1,30 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef CTR
int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr)
{
_ARGCHK(IV != NULL);
_ARGCHK(len != NULL);
_ARGCHK(ctr != NULL);
if ((unsigned long)ctr->blocklen > *len) {
return CRYPT_BUFFER_OVERFLOW;
}
memcpy(IV, ctr->ctr, ctr->blocklen);
*len = ctr->blocklen;
return CRYPT_OK;
}
#endif

43
ctr_setiv.c Normal file
View File

@ -0,0 +1,43 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef CTR
int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
{
int err;
_ARGCHK(IV != NULL);
_ARGCHK(ctr != NULL);
/* bad param? */
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
return err;
}
if (len != (unsigned long)ctr->blocklen) {
return CRYPT_INVALID_ARG;
}
/* set IV */
memcpy(ctr->ctr, IV, len);
/* force next block */
ctr->padlen = 0;
cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
return CRYPT_OK;
}
#endif

View File

@ -4,7 +4,7 @@
int main(void) int main(void)
{ {
register_cipher(&rijndael_desc); register_cipher(&rijndael_enc_desc);
register_prng(&yarrow_desc); register_prng(&yarrow_desc);
register_hash(&sha256_desc); register_hash(&sha256_desc);
return 0; return 0;

View File

@ -1202,69 +1202,6 @@ ecc_tests (void)
} }
#endif #endif
#ifdef GF
void
gf_tests (void)
{
gf_int a, b, c, d;
int n;
unsigned char buf[1024];
printf ("GF tests\n");
gf_zero (a);
gf_zero (b);
gf_zero (c);
gf_zero (d);
/* a == 0x18000000b */
a[1] = 1;
a[0] = 0x8000000bUL;
/* b == 0x012345678 */
b[0] = 0x012345678UL;
/* find 1/b mod a */
gf_invmod (b, a, c);
/* find 1/1/b mod a */
gf_invmod (c, a, d);
/* display them */
printf (" %08lx %08lx\n", c[0], d[0]);
/* store as binary string */
n = gf_size (a);
printf (" a takes %d bytes\n", n);
gf_toraw (a, buf);
gf_readraw (a, buf, n);
printf (" a == %08lx%08lx\n", a[1], a[0]);
/* primality testing */
gf_zero (a);
a[0] = 0x169;
printf (" GF prime: %s, ", gf_is_prime (a) ? "passed" : "failed");
a[0] = 0x168;
printf (" %s\n", gf_is_prime (a) ? "failed" : "passed");
/* test sqrt code */
gf_zero (a);
a[1] = 0x00000001;
a[0] = 0x8000000bUL;
gf_zero (b);
b[0] = 0x12345678UL;
gf_sqrt (b, a, c);
gf_mulmod (c, c, a, b);
printf (" (%08lx)^2 = %08lx (mod %08lx%08lx) \n", c[0], b[0], a[1], a[0]);
}
#else
void
gf_tests (void)
{
printf ("GF not compiled in\n");
}
#endif
#ifdef MPI #ifdef MPI
void void
test_prime (void) test_prime (void)
@ -1390,299 +1327,6 @@ register_all_algs (void)
#endif #endif
} }
#ifdef KR
void
kr_display (pk_key * kr)
{
static const char *sys[] = { "NON-KEY", "RSA", "DH", "ECC" };
static const char *type[] = { "PRIVATE", "PUBLIC", "PRIVATE_OPTIMIZED" };
while (kr->system != NON_KEY) {
printf ("CRC [%08lx], System [%10s], Type [%20s], %s, %s, %s\n", kr->ID,
sys[kr->system], type[kr->key_type], kr->name, kr->email,
kr->description);
kr = kr->next;
}
printf ("\n");
}
void
kr_test_makekeys (pk_key ** kr)
{
if ((errnum = kr_init (kr)) != CRYPT_OK) {
printf ("KR init error %s\n", error_to_string (errnum));
exit (-1);
}
/* make a DH key */
printf ("KR: Making DH key...\n");
if ((errnum =
kr_make_key (*kr, &prng, find_prng ("yarrow"), DH_KEY, 128, "dhkey",
"dh@dh.dh", "dhkey one")) != CRYPT_OK) {
printf ("Make key error: %s\n", error_to_string (errnum));
exit (-1);
}
/* make a ECC key */
printf ("KR: Making ECC key...\n");
if ((errnum =
kr_make_key (*kr, &prng, find_prng ("yarrow"), ECC_KEY, 20, "ecckey",
"ecc@ecc.ecc", "ecckey one")) != CRYPT_OK) {
printf ("Make key error: %s\n", error_to_string (errnum));
exit (-1);
}
/* make a RSA key */
printf ("KR: Making RSA key...\n");
if ((errnum =
kr_make_key (*kr, &prng, find_prng ("yarrow"), RSA_KEY, 128, "rsakey",
"rsa@rsa.rsa", "rsakey one")) != CRYPT_OK) {
printf ("Make key error: %s\n", error_to_string (errnum));
exit (-1);
}
}
void
kr_test (void)
{
pk_key *kr, *_kr;
unsigned char buf[8192], buf2[8192], buf3[8192];
unsigned long len;
int i, j, stat;
#ifndef NO_FILE
FILE *f;
#endif
kr_test_makekeys (&kr);
printf ("The original list:\n");
kr_display (kr);
for (i = 0; i < 3; i++) {
len = sizeof (buf);
if ((errnum = kr_export (kr, kr->ID, kr->key_type, buf, &len)) != CRYPT_OK) {
printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
printf ("Exported key was: %lu bytes\n", len);
if ((errnum = kr_del (&kr, kr->ID)) != CRYPT_OK) {
printf ("Error deleting key %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
kr_display (kr);
if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
printf ("Error importing key %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
kr_display (kr);
}
for (i = 0; i < 3; i++) {
len = sizeof (buf);
if ((errnum = kr_export (kr, kr->ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
printf ("Exported key was: %lu bytes\n", len);
if ((errnum = kr_del (&kr, kr->ID)) != CRYPT_OK) {
printf ("Error deleting key %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
kr_display (kr);
if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
printf ("Error importing key %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
kr_display (kr);
}
if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
printf ("Error clearing ring: %s\n", error_to_string (errnum));
exit (-1);
}
/* TEST output to file */
#ifndef NO_FILE
if ((errnum = kr_init (&kr)) != CRYPT_OK) {
printf ("KR init error %s\n", error_to_string (errnum));
exit (-1);
}
kr_test_makekeys (&kr);
/* save to file */
f = fopen ("ring.dat", "wb");
if ((errnum = kr_save (kr, f, NULL)) != CRYPT_OK) {
printf ("kr_save error %s\n", error_to_string (errnum));
exit (-1);
}
fclose (f);
/* delete and load */
if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
printf ("clear error: %s\n", error_to_string (errnum));
exit (-1);
}
f = fopen ("ring.dat", "rb");
if ((errnum = kr_load (&kr, f, NULL)) != CRYPT_OK) {
printf ("kr_load error %s\n", error_to_string (errnum));
exit (-1);
}
fclose (f);
remove ("ring.dat");
printf ("After load and save...\n");
kr_display (kr);
if ((errnum = kr_clear (&kr)) != CRYPT_OK) {
printf ("clear error: %s\n", error_to_string (errnum));
exit (-1);
}
#endif
/* test the packet encryption/sign stuff */
for (i = 0; i < 32; i++)
buf[i] = i;
kr_test_makekeys (&kr);
_kr = kr;
for (i = 0; i < 3; i++) {
printf ("Testing a key with system %d, type %d:\t", _kr->system,
_kr->key_type);
len = sizeof (buf2);
if ((errnum =
kr_encrypt_key (kr, _kr->ID, buf, 16, buf2, &len, &prng,
find_prng ("yarrow"),
find_hash ("md5"))) != CRYPT_OK) {
printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
len = sizeof (buf3);
if ((errnum = kr_decrypt_key (kr, buf2, buf3, &len)) != CRYPT_OK) {
printf ("decrypt error, %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
if (len != 16 || memcmp (buf3, buf, 16)) {
printf ("kr_decrypt_key failed, %i, %lu\n", i, len);
exit (-1);
}
printf ("kr_encrypt_key passed, ");
len = sizeof (buf2);
if ((errnum =
kr_sign_hash (kr, _kr->ID, buf, 32, buf2, &len, &prng,
find_prng ("yarrow"))) != CRYPT_OK) {
printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
exit (-1);
}
printf ("kr_sign_hash: ");
if ((errnum = kr_verify_hash (kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
exit (-1);
}
printf ("%s, ", stat ? "passed" : "failed");
buf[15] ^= 1;
if ((errnum = kr_verify_hash (kr, buf2, buf, 32, &stat)) != CRYPT_OK) {
printf ("kr_sign_hash failed, %i, %s\n", i, error_to_string (errnum));
exit (-1);
}
printf ("%s\n", (!stat) ? "passed" : "failed");
buf[15] ^= 1;
len = sizeof (buf);
if ((errnum =
kr_fingerprint (kr, _kr->ID, find_hash ("sha1"), buf,
&len)) != CRYPT_OK) {
printf ("kr_fingerprint failed, %i, %lu\n", i, len);
exit (-1);
}
printf ("Fingerprint: ");
for (j = 0; j < 20; j++) {
printf ("%02x", buf[j]);
if (j < 19)
printf (":");
}
printf ("\n\n");
_kr = _kr->next;
}
/* Test encrypting/decrypting to a public key */
/* first dump the other two keys */
kr_del (&kr, kr->ID);
kr_del (&kr, kr->ID);
kr_display (kr);
/* now export it as public and private */
len = sizeof (buf);
if ((errnum = kr_export (kr, kr->ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
printf ("Error exporting key %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
/* check boundaries */
memset (buf + len, 0, sizeof (buf) - len);
len = sizeof (buf2);
if ((errnum = kr_export (kr, kr->ID, PK_PRIVATE, buf2, &len)) != CRYPT_OK) {
printf ("Error exporting key %s\n", error_to_string (errnum));
exit (-1);
}
/* check boundaries */
memset (buf2 + len, 0, sizeof (buf2) - len);
/* delete the key and import the public */
kr_clear (&kr);
kr_init (&kr);
kr_display (kr);
if ((errnum = kr_import (kr, buf, len)) != CRYPT_OK) {
printf ("Error importing key %s\n", error_to_string (errnum));
exit (-1);
}
kr_display (kr);
/* now encrypt a buffer */
for (i = 0; i < 16; i++)
buf[i] = i;
len = sizeof (buf3);
if ((errnum =
kr_encrypt_key (kr, kr->ID, buf, 16, buf3, &len, &prng,
find_prng ("yarrow"),
find_hash ("md5"))) != CRYPT_OK) {
printf ("Encrypt error, %d, %s\n", i, error_to_string (errnum));
exit (-1);
}
/* now delete the key and import the private one */
kr_clear (&kr);
kr_init (&kr);
kr_display (kr);
if ((errnum = kr_import (kr, buf2, len)) != CRYPT_OK) {
printf ("Error importing key %s\n", error_to_string (errnum));
exit (-1);
}
kr_display (kr);
/* now decrypt */
len = sizeof (buf2);
if ((errnum = kr_decrypt_key (kr, buf3, buf2, &len)) != CRYPT_OK) {
printf ("decrypt error, %s\n", error_to_string (errnum));
exit (-1);
}
printf ("KR encrypt to public, decrypt with private: ");
if (len == 16 && !memcmp (buf2, buf, 16)) {
printf ("passed\n");
} else {
printf ("failed\n");
}
kr_clear (&kr);
}
#endif
void void
test_errs (void) test_errs (void)
{ {
@ -1840,13 +1484,13 @@ void pkcs1_test(void)
/* decode it */ /* decode it */
l2 = sizeof(buf[2]); l2 = sizeof(buf[2]);
if ((err = pkcs_1_oaep_decode(buf[1], l1, NULL, 0, 1024, hash_idx, buf[2], &l2)) != CRYPT_OK) { if ((err = pkcs_1_oaep_decode(buf[1], l1, NULL, 0, 1024, hash_idx, buf[2], &l2, &res1)) != CRYPT_OK) {
printf("OAEP decode: %s\n", error_to_string(err)); printf("OAEP decode: %s\n", error_to_string(err));
exit(-1); exit(-1);
} }
if (l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) { if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
printf("Outsize == %lu, should have been %lu, msg contents follow.\n", l2, l3); printf("res == %d, Outsize == %lu, should have been %lu, msg contents follow.\n", res1, l2, l3);
printf("ORIGINAL:\n"); printf("ORIGINAL:\n");
for (x = 0; x < l3; x++) { for (x = 0; x < l3; x++) {
printf("%02x ", buf[0][x]); printf("%02x ", buf[0][x]);
@ -1959,16 +1603,12 @@ main (void)
rng_tests (); rng_tests ();
test_prime(); test_prime();
#ifdef KR
kr_test ();
#endif
dsa_tests(); dsa_tests();
rsa_test (); rsa_test ();
pad_test (); pad_test ();
ecc_tests (); ecc_tests ();
dh_tests (); dh_tests ();
gf_tests ();
base64_test (); base64_test ();
time_ecb (); time_ecb ();

File diff suppressed because it is too large Load Diff

20
demos/test/base64_test.c Normal file
View File

@ -0,0 +1,20 @@
#include "test.h"
int base64_test(void)
{
unsigned char in[64], out[256], tmp[64];
unsigned long x, l1, l2;
for (x = 0; x < 64; x++) {
yarrow_read(in, x, &test_yarrow);
l1 = sizeof(out);
DO(base64_encode(in, x, out, &l1));
l2 = sizeof(tmp);
DO(base64_decode(out, l1, tmp, &l2));
if (l2 != x || memcmp(tmp, in, x)) {
printf("base64 failed %lu %lu %lu", x, l1, l2);
return 1;
}
}
return 0;
}

View File

@ -0,0 +1,20 @@
/* test the ciphers and hashes using their built-in self-tests */
#include "test.h"
int cipher_hash_test(void)
{
int x;
/* test ciphers */
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
DO(cipher_descriptor[x].test());
}
/* test hashes */
for (x = 0; hash_descriptor[x].name != NULL; x++) {
DO(hash_descriptor[x].test());
}
return 0;
}

87
demos/test/dh_tests.c Normal file
View File

@ -0,0 +1,87 @@
#include "test.h"
int dh_tests (void)
{
unsigned char buf[3][4096];
unsigned long x, y, z;
int stat, stat2;
dh_key usera, userb;
DO(dh_test());
/* make up two keys */
DO(dh_make_key (&test_yarrow, find_prng ("yarrow"), 96, &usera));
DO(dh_make_key (&test_yarrow, find_prng ("yarrow"), 96, &userb));
/* make the shared secret */
x = 4096;
DO(dh_shared_secret (&usera, &userb, buf[0], &x));
y = 4096;
DO(dh_shared_secret (&userb, &usera, buf[1], &y));
if (y != x) {
printf ("DH Shared keys are not same size.\n");
return 1;
}
if (memcmp (buf[0], buf[1], x)) {
printf ("DH Shared keys not same contents.\n");
return 1;
}
/* now export userb */
y = 4096;
DO(dh_export (buf[1], &y, PK_PUBLIC, &userb));
dh_free (&userb);
/* import and make the shared secret again */
DO(dh_import (buf[1], y, &userb));
z = 4096;
DO(dh_shared_secret (&usera, &userb, buf[2], &z));
if (z != x) {
printf ("failed. Size don't match?\n");
return 1;
}
if (memcmp (buf[0], buf[2], x)) {
printf ("Failed. Content didn't match.\n");
return 1;
}
dh_free (&usera);
dh_free (&userb);
/* test encrypt_key */
dh_make_key (&test_yarrow, find_prng ("yarrow"), 128, &usera);
for (x = 0; x < 16; x++) {
buf[0][x] = x;
}
y = sizeof (buf[1]);
DO(dh_encrypt_key (buf[0], 16, buf[1], &y, &test_yarrow, find_prng ("yarrow"), find_hash ("md5"), &usera));
zeromem (buf[0], sizeof (buf[0]));
x = sizeof (buf[0]);
DO(dh_decrypt_key (buf[1], y, buf[0], &x, &usera));
if (x != 16) {
printf ("Failed (length)\n");
return 1;
}
for (x = 0; x < 16; x++)
if (buf[0][x] != x) {
printf ("Failed (contents)\n");
return 1;
}
/* test sign_hash */
for (x = 0; x < 16; x++) {
buf[0][x] = x;
}
x = sizeof (buf[1]);
DO(dh_sign_hash (buf[0], 16, buf[1], &x, &test_yarrow , find_prng ("yarrow"), &usera));
DO(dh_verify_hash (buf[1], x, buf[0], 16, &stat, &usera));
buf[0][0] ^= 1;
DO(dh_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera));
if (!(stat == 1 && stat2 == 0)) {
printf("dh_sign/verify_hash %d %d", stat, stat2);
return 1;
}
dh_free (&usera);
return 0;
}

51
demos/test/dsa_test.c Normal file
View File

@ -0,0 +1,51 @@
#include "test.h"
int dsa_test(void)
{
unsigned char msg[16], out[1024], out2[1024];
unsigned long x, y;
int err, stat1, stat2;
dsa_key key, key2;
/* make a random key */
DO(dsa_make_key(&test_yarrow, find_prng("yarrow"), 20, 128, &key));
/* verify it */
DO(dsa_verify_key(&key, &stat1));
if (stat1 == 0) { printf("dsa_verify_key "); return 1; }
/* sign the message */
x = sizeof(out);
DO(dsa_sign_hash(msg, sizeof(msg), out, &x, &test_yarrow, find_prng("yarrow"), &key));
/* verify it once */
DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key));
/* Modify and verify again */
msg[0] ^= 1;
DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat2, &key));
msg[0] ^= 1;
if (!(stat1 == 1 && stat2 == 0)) { printf("dsa_verify %d %d", stat1, stat2); return 1; }
/* test exporting it */
x = sizeof(out2);
DO(dsa_export(out2, &x, PK_PRIVATE, &key));
DO(dsa_import(out2, x, &key2));
/* verify a signature with it */
DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
if (stat1 == 0) { printf("dsa_verify (import private) %d ", stat1); return 1; }
dsa_free(&key2);
/* export as public now */
x = sizeof(out2);
DO(dsa_export(out2, &x, PK_PUBLIC, &key));
DO(dsa_import(out2, x, &key2));
/* verify a signature with it */
DO(dsa_verify_hash(out, x, msg, sizeof(msg), &stat1, &key2));
if (stat1 == 0) { printf("dsa_verify (import public) %d ", stat1); return 1; }
dsa_free(&key2);
dsa_free(&key);
return 0;
}

89
demos/test/ecc_test.c Normal file
View File

@ -0,0 +1,89 @@
#include "test.h"
int ecc_tests (void)
{
unsigned char buf[4][4096];
unsigned long x, y, z;
int stat, stat2;
ecc_key usera, userb;
DO(ecc_test ());
/* make up two keys */
DO(ecc_make_key (&test_yarrow, find_prng ("yarrow"), 24, &usera));
DO(ecc_make_key (&test_yarrow, find_prng ("yarrow"), 24, &userb));
/* make the shared secret */
x = 4096;
DO(ecc_shared_secret (&usera, &userb, buf[0], &x));
y = 4096;
DO(ecc_shared_secret (&userb, &usera, buf[1], &y));
if (y != x) {
printf ("ecc Shared keys are not same size.");
return 1;
}
if (memcmp (buf[0], buf[1], x)) {
printf ("ecc Shared keys not same contents.");
return 1;
}
/* now export userb */
y = 4096;
DO(ecc_export (buf[1], &y, PK_PUBLIC, &userb));
ecc_free (&userb);
/* import and make the shared secret again */
DO(ecc_import (buf[1], y, &userb));
z = 4096;
DO(ecc_shared_secret (&usera, &userb, buf[2], &z));
if (z != x) {
printf ("failed. Size don't match?");
return 1;
}
if (memcmp (buf[0], buf[2], x)) {
printf ("Failed. Content didn't match.");
return 1;
}
ecc_free (&usera);
ecc_free (&userb);
/* test encrypt_key */
ecc_make_key (&test_yarrow, find_prng ("yarrow"), 20, &usera);
for (x = 0; x < 32; x++) {
buf[0][x] = x;
}
y = sizeof (buf[1]);
DO(ecc_encrypt_key (buf[0], 32, buf[1], &y, &test_yarrow, find_prng ("yarrow"), find_hash ("sha256"), &usera));
zeromem (buf[0], sizeof (buf[0]));
x = sizeof (buf[0]);
DO(ecc_decrypt_key (buf[1], y, buf[0], &x, &usera));
if (x != 32) {
printf ("Failed (length)");
return 1;
}
for (x = 0; x < 32; x++)
if (buf[0][x] != x) {
printf ("Failed (contents)");
return 1;
}
/* test sign_hash */
for (x = 0; x < 16; x++) {
buf[0][x] = x;
}
x = sizeof (buf[1]);
DO(ecc_sign_hash (buf[0], 16, buf[1], &x, &test_yarrow, find_prng ("yarrow"), &usera));
DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat, &usera));
buf[0][0] ^= 1;
DO(ecc_verify_hash (buf[1], x, buf[0], 16, &stat2, &usera));
if (!(stat == 1 && stat2 == 0)) {
printf("ecc_verify_hash failed");
return 1;
}
ecc_free (&usera);
return 0;
}

12
demos/test/mac_test.c Normal file
View File

@ -0,0 +1,12 @@
/* test pmac/omac/hmac */
#include "test.h"
int mac_test(void)
{
DO(hmac_test());
DO(pmac_test());
DO(omac_test());
DO(eax_test());
DO(ocb_test());
return 0;
}

13
demos/test/makefile Normal file
View File

@ -0,0 +1,13 @@
# make test harness, it is good.
CFLAGS += -Wall -W -Os -I../../ -I./
default: test
OBJECTS=test.o cipher_hash_test.o mac_test.o modes_test.o \
pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.c dh_tests.o
test: $(OBJECTS)
$(CC) $(OBJECTS) -ltomcrypt -o test
clean:
rm -f test *.o *.obj *.exe *~

14
demos/test/makefile.icc Normal file
View File

@ -0,0 +1,14 @@
# make test harness, it is good.
CFLAGS += -O3 -xN -ip -I../../ -I./
CC=icc
default: test
OBJECTS=test.o cipher_hash_test.o mac_test.o modes_test.o \
pkcs_1_test.o store_test.o rsa_test.o ecc_test.o dsa_test.c dh_tests.o
test: $(OBJECTS)
$(CC) $(OBJECTS) -ltomcrypt -o test
clean:
rm -f test *.o *~

14
demos/test/makefile.msvc Normal file
View File

@ -0,0 +1,14 @@
# make test harness, it is good.
CFLAGS = $(CFLAGS) /W3 /Ox -I../../ -I./
default: test.exe
OBJECTS = test.obj cipher_hash_test.obj mac_test.obj modes_test.obj \
pkcs_1_test.obj store_test.obj rsa_test.obj ecc_test.obj dsa_test.c dh_tests.obj
test.exe: $(OBJECTS)
cl $(OBJECTS) tomcrypt.lib advapi32.lib
clean:
rm -f test.exe *.obj *~

112
demos/test/modes_test.c Normal file
View File

@ -0,0 +1,112 @@
/* test CFB/OFB/CBC modes */
#include "test.h"
int modes_test(void)
{
unsigned char pt[64], ct[64], tmp[64], key[16], iv[16], iv2[16];
int x, cipher_idx;
symmetric_CBC cbc;
symmetric_CFB cfb;
symmetric_OFB ofb;
symmetric_CTR ctr;
unsigned long l;
/* make a random pt, key and iv */
yarrow_read(pt, 64, &test_yarrow);
yarrow_read(key, 16, &test_yarrow);
yarrow_read(iv, 16, &test_yarrow);
/* get idx of AES handy */
cipher_idx = find_cipher("aes");
if (cipher_idx == -1) {
printf("test requires AES");
return 1;
}
/* test CBC mode */
/* encode the block */
DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
l = sizeof(iv2);
DO(cbc_getiv(iv2, &l, &cbc));
if (l != 16 || memcmp(iv2, iv, 16)) {
printf("cbc_getiv failed");
return 1;
}
for (x = 0; x < 4; x++) {
DO(cbc_encrypt(pt+x*16, ct+x*16, &cbc));
}
/* decode the block */
DO(cbc_setiv(iv2, l, &cbc));
zeromem(tmp, sizeof(tmp));
for (x = 0; x < 4; x++) {
DO(cbc_decrypt(ct+x*16, tmp+x*16, &cbc));
}
if (memcmp(tmp, pt, 64) != 0) {
printf("CBC failed");
return 1;
}
/* test CFB mode */
/* encode the block */
DO(cfb_start(cipher_idx, iv, key, 16, 0, &cfb));
l = sizeof(iv2);
DO(cfb_getiv(iv2, &l, &cfb));
/* note we don't memcmp iv2/iv since cfb_start processes the IV for the first block */
if (l != 16) {
printf("cfb_getiv failed");
return 1;
}
DO(cfb_encrypt(pt, ct, 64, &cfb));
/* decode the block */
DO(cfb_setiv(iv, l, &cfb));
zeromem(tmp, sizeof(tmp));
DO(cfb_decrypt(ct, tmp, 64, &cfb));
if (memcmp(tmp, pt, 64) != 0) {
printf("CFB failed");
return 1;
}
/* test OFB mode */
/* encode the block */
DO(ofb_start(cipher_idx, iv, key, 16, 0, &ofb));
l = sizeof(iv2);
DO(ofb_getiv(iv2, &l, &ofb));
if (l != 16 || memcmp(iv2, iv, 16)) {
printf("ofb_getiv failed");
return 1;
}
DO(ofb_encrypt(pt, ct, 64, &ofb));
/* decode the block */
DO(ofb_setiv(iv2, l, &ofb));
zeromem(tmp, sizeof(tmp));
DO(ofb_decrypt(ct, tmp, 64, &ofb));
if (memcmp(tmp, pt, 64) != 0) {
printf("OFB failed");
return 1;
}
/* test CTR mode */
/* encode the block */
DO(ctr_start(cipher_idx, iv, key, 16, 0, &ctr));
l = sizeof(iv2);
DO(ctr_getiv(iv2, &l, &ctr));
if (l != 16 || memcmp(iv2, iv, 16)) {
printf("ctr_getiv failed");
return 1;
}
DO(ctr_encrypt(pt, ct, 64, &ctr));
/* decode the block */
DO(ctr_setiv(iv2, l, &ctr));
zeromem(tmp, sizeof(tmp));
DO(ctr_decrypt(ct, tmp, 64, &ctr));
if (memcmp(tmp, pt, 64) != 0) {
printf("CTR failed");
return 1;
}
return 0;
}

103
demos/test/pkcs_1_test.c Normal file
View File

@ -0,0 +1,103 @@
#include "test.h"
int pkcs_1_test(void)
{
unsigned char buf[3][128];
int res1, res2, res3, prng_idx, hash_idx;
unsigned long x, y, l1, l2, l3, i1, i2, lparamlen, saltlen, modlen;
static const unsigned char lparam[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 };
/* get hash/prng */
hash_idx = find_hash("sha1");
prng_idx = find_prng("yarrow");
if (hash_idx == -1 || prng_idx == -1) {
printf("pkcs_1 tests require sha1/yarrow");
return 1;
}
/* do many tests */
for (x = 0; x < 10000; x++) {
zeromem(buf, sizeof(buf));
/* make a dummy message (of random length) */
l3 = (rand() & 31) + 8;
for (y = 0; y < l3; y++) buf[0][y] = rand() & 255;
/* random modulus len (v1.5 must be multiple of 8 though arbitrary sizes seem to work) */
modlen = 800 + 8 * (abs(rand()) % 28);
/* PKCS v1.5 testing (encryption) */
l1 = sizeof(buf[1]);
DO(pkcs_1_v15_es_encode(buf[0], l3, modlen, &test_yarrow, prng_idx, buf[1], &l1));
DO(pkcs_1_v15_es_decode(buf[1], l1, modlen, buf[2], l3, &res1));
if (res1 != 1 || memcmp(buf[0], buf[2], l3)) {
printf("pkcs v1.5 encrypt failed %d, %lu, %lu ", res1, l1, l3);
return 1;
}
/* PKCS v1.5 testing (signatures) */
l1 = sizeof(buf[1]);
DO(pkcs_1_v15_sa_encode(buf[0], l3, hash_idx, modlen, buf[1], &l1));
DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res1));
buf[0][i1 = abs(rand()) % l3] ^= 1;
DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res2));
buf[0][i1] ^= 1;
buf[1][i2 = abs(rand()) % l1] ^= 1;
DO(pkcs_1_v15_sa_decode(buf[0], l3, buf[1], l1, hash_idx, modlen, &res3));
if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
printf("pkcs v1.5 sign failed %d %d %d ", res1, res2, res3);
return 1;
}
/* pick a random lparam len [0..16] */
lparamlen = abs(rand()) % 17;
/* pick a random saltlen 0..16 */
saltlen = abs(rand()) % 17;
/* PKCS #1 v2.0 supports modlens not multiple of 8 */
modlen = 800 + (abs(rand()) % 224);
/* encode it */
l1 = sizeof(buf[1]);
DO(pkcs_1_oaep_encode(buf[0], l3, lparam, lparamlen, modlen, &test_yarrow, prng_idx, hash_idx, buf[1], &l1));
/* decode it */
l2 = sizeof(buf[2]);
DO(pkcs_1_oaep_decode(buf[1], l1, lparam, lparamlen, modlen, hash_idx, buf[2], &l2, &res1));
if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
printf("Outsize == %lu, should have been %lu, res1 = %d, lparamlen = %lu, msg contents follow.\n", l2, l3, res1, lparamlen);
printf("ORIGINAL:\n");
for (x = 0; x < l3; x++) {
printf("%02x ", buf[0][x]);
}
printf("\nRESULT:\n");
for (x = 0; x < l2; x++) {
printf("%02x ", buf[2][x]);
}
printf("\n\n");
return 1;
}
/* test PSS */
l1 = sizeof(buf[1]);
DO(pkcs_1_pss_encode(buf[0], l3, saltlen, &test_yarrow, prng_idx, hash_idx, modlen, buf[1], &l1));
DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res1));
buf[0][i1 = abs(rand()) % l3] ^= 1;
DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res2));
buf[0][i1] ^= 1;
buf[1][i2 = abs(rand()) % l1] ^= 1;
DO(pkcs_1_pss_decode(buf[0], l3, buf[1], l1, saltlen, hash_idx, modlen, &res3));
if (!(res1 == 1 && res2 == 0 && res3 == 0)) {
printf("PSS failed: %d, %d, %d, %lu, %lu\n", res1, res2, res3, l3, saltlen);
return 1;
}
}
return 0;
}

91
demos/test/rsa_test.c Normal file
View File

@ -0,0 +1,91 @@
#include "test.h"
int rsa_test(void)
{
unsigned char in[1024], out[1024], tmp[1024];
rsa_key key;
int hash_idx, prng_idx, stat, stat2;
unsigned long len, len2;
static unsigned char lparam[] = { 0x01, 0x02, 0x03, 0x04 };
hash_idx = find_hash("sha1");
prng_idx = find_prng("yarrow");
if (hash_idx == -1 || prng_idx == -1) {
printf("rsa_test requires SHA1 and yarrow");
return 1;
}
/* make a random key/msg */
yarrow_read(in, 20, &test_yarrow);
/* make a random key */
DO(rsa_make_key(&test_yarrow, prng_idx, 1024/8, 65537, &key));
/* encrypt the key (without lparam) */
len = sizeof(out);
len2 = sizeof(tmp);
DO(rsa_encrypt_key(in, 20, out, &len, NULL, 0, &test_yarrow, prng_idx, hash_idx, &key));
/* change a byte */
out[0] ^= 1;
DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, &test_yarrow, prng_idx, hash_idx, &stat2, &key));
/* change a byte back */
out[0] ^= 1;
DO(rsa_decrypt_key(out, len, tmp, &len2, NULL, 0, &test_yarrow, prng_idx, hash_idx, &stat, &key));
if (!(stat == 1 && stat2 == 0)) {
printf("rsa_decrypt_key failed");
return 1;
}
if (len2 != 20 || memcmp(tmp, in, 20)) {
printf("rsa_decrypt_key mismatch len %lu", len2);
return 1;
}
/* encrypt the key (with lparam) */
len = sizeof(out);
len2 = sizeof(tmp);
DO(rsa_encrypt_key(in, 20, out, &len, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &key));
/* change a byte */
out[0] ^= 1;
DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &stat2, &key));
/* change a byte back */
out[0] ^= 1;
DO(rsa_decrypt_key(out, len, tmp, &len2, lparam, sizeof(lparam), &test_yarrow, prng_idx, hash_idx, &stat, &key));
if (!(stat == 1 && stat2 == 0)) {
printf("rsa_decrypt_key failed");
return 1;
}
if (len2 != 20 || memcmp(tmp, in, 20)) {
printf("rsa_decrypt_key mismatch len %lu", len2);
return 1;
}
/* sign a message (unsalted, lower cholestorol and Atkins approved) now */
len = sizeof(out);
DO(rsa_sign_hash(in, 20, out, &len, &test_yarrow, prng_idx, hash_idx, 0, &key));
DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat, &key));
/* change a byte */
in[0] ^= 1;
DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 0, &stat2, &key));
if (!(stat == 1 && stat2 == 0)) {
printf("rsa_verify_hash (unsalted) failed, %d, %d", stat, stat2);
return 1;
}
/* sign a message (salted) now */
len = sizeof(out);
DO(rsa_sign_hash(in, 20, out, &len, &test_yarrow, prng_idx, hash_idx, 8, &key));
DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 8, &stat, &key));
/* change a byte */
in[0] ^= 1;
DO(rsa_verify_hash(out, len, in, 20, &test_yarrow, prng_idx, hash_idx, 8, &stat2, &key));
if (!(stat == 1 && stat2 == 0)) {
printf("rsa_verify_hash (salted) failed, %d, %d", stat, stat2);
return 1;
}
/* free the key and return */
rsa_free(&key);
return 0;
}

43
demos/test/store_test.c Normal file
View File

@ -0,0 +1,43 @@
#include "test.h"
int store_test(void)
{
unsigned char buf[8];
unsigned long L;
ulong64 LL;
L = 0x12345678UL;
STORE32L (L, &buf[0]);
L = 0;
LOAD32L (L, &buf[0]);
if (L != 0x12345678UL) {
printf ("LOAD/STORE32 Little don't work");
return 1;
}
LL = CONST64 (0x01020304050607);
STORE64L (LL, &buf[0]);
LL = 0;
LOAD64L (LL, &buf[0])
if (LL != CONST64 (0x01020304050607)) {
printf ("LOAD/STORE64 Little don't work");
return 1;
}
L = 0x12345678UL;
STORE32H (L, &buf[0]);
L = 0;
LOAD32H (L, &buf[0]);
if (L != 0x12345678UL) {
printf ("LOAD/STORE32 High don't work, %08lx", L);
return 1;
}
LL = CONST64 (0x01020304050607);
STORE64H (LL, &buf[0]);
LL = 0;
LOAD64H (LL, &buf[0])
if (LL != CONST64 (0x01020304050607)) {
printf ("LOAD/STORE64 High don't work");
return 1;
}
return 0;
}

177
demos/test/test.c Normal file
View File

@ -0,0 +1,177 @@
#include "test.h"
test_entry tests[26];
test_entry test_list[26] = {
/* test name provides requires entry */
{"store_test", "a", "", store_test },
{"cipher_hash_test", "b", "a", cipher_hash_test },
{"modes_test", "c", "b", modes_test },
{"mac_test", "d", "c", mac_test },
{"pkcs_1_test", "e", "b", pkcs_1_test },
{"rsa_test", "f", "e", rsa_test },
{"ecc_test", "g", "a", ecc_tests },
{"dsa_test", "h", "a", dsa_test },
{"dh_test", "i", "a", dh_tests },
{NULL, NULL, NULL, NULL}
};
prng_state test_yarrow;
static int current_test;
void run_cmd(int res, int line, char *file, char *cmd)
{
if (res != CRYPT_OK) {
fprintf(stderr, "[%s]: %s (%d)\n%s:%d:%s\n", tests[current_test].name, error_to_string(res), res, file, line, cmd);
exit(EXIT_FAILURE);
}
}
void register_algs(void)
{
#ifdef RIJNDAEL
register_cipher (&aes_desc);
#endif
#ifdef BLOWFISH
register_cipher (&blowfish_desc);
#endif
#ifdef XTEA
register_cipher (&xtea_desc);
#endif
#ifdef RC5
register_cipher (&rc5_desc);
#endif
#ifdef RC6
register_cipher (&rc6_desc);
#endif
#ifdef SAFERP
register_cipher (&saferp_desc);
#endif
#ifdef TWOFISH
register_cipher (&twofish_desc);
#endif
#ifdef SAFER
register_cipher (&safer_k64_desc);
register_cipher (&safer_sk64_desc);
register_cipher (&safer_k128_desc);
register_cipher (&safer_sk128_desc);
#endif
#ifdef RC2
register_cipher (&rc2_desc);
#endif
#ifdef DES
register_cipher (&des_desc);
register_cipher (&des3_desc);
#endif
#ifdef CAST5
register_cipher (&cast5_desc);
#endif
#ifdef NOEKEON
register_cipher (&noekeon_desc);
#endif
#ifdef SKIPJACK
register_cipher (&skipjack_desc);
#endif
#ifdef TIGER
register_hash (&tiger_desc);
#endif
#ifdef MD2
register_hash (&md2_desc);
#endif
#ifdef MD4
register_hash (&md4_desc);
#endif
#ifdef MD5
register_hash (&md5_desc);
#endif
#ifdef SHA1
register_hash (&sha1_desc);
#endif
#ifdef SHA256
register_hash (&sha256_desc);
#endif
#ifdef SHA224
register_hash (&sha224_desc);
#endif
#ifdef SHA384
register_hash (&sha384_desc);
#endif
#ifdef SHA512
register_hash (&sha512_desc);
#endif
#ifdef RIPEMD128
register_hash (&rmd128_desc);
#endif
#ifdef RIPEMD160
register_hash (&rmd160_desc);
#endif
#ifdef WHIRLPOOL
register_hash (&whirlpool_desc);
#endif
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);
}
}
/* sort tests based on their requirement/services. Helps make sure dependencies are tested first */
void sort(void)
{
unsigned x, y, z, a, pidx[26];
/* find out where things are provided */
zeromem(pidx, sizeof(pidx));
z = 0;
do {
y = 0;
for (x = 0; test_list[x].name != NULL; x++) {
if (test_list[x].entry == NULL) continue;
if (strlen(test_list[x].prov) == 0) {
y = 1;
tests[z++] = test_list[x]; test_list[x].entry = NULL;
pidx[test_list[x].prov[0]-'a'] = 1;
break;
} else {
for (a = 0; a < strlen(test_list[x].req); a++) {
if (pidx[test_list[x].req[a]-'a'] == 0) break;
}
if (a == strlen(test_list[x].req)) {
y = 1;
tests[z++] = test_list[x]; test_list[x].entry = NULL;
pidx[test_list[x].prov[0]-'a'] = 1;
break;
}
}
}
} while (y == 1);
}
int main(void)
{
printf("Built with\n%s\n", crypt_build_settings);
srand(time(NULL));
sort();
register_algs();
// start dummy yarrow for internal use
DO(yarrow_start(&test_yarrow));
DO(yarrow_add_entropy("test", 4, &test_yarrow));
DO(yarrow_ready(&test_yarrow));
// do tests
for (current_test = 0; tests[current_test].name != NULL; current_test++) {
printf("[%-20s]: ", tests[current_test].name); fflush(stdout);
printf("\t%s\n", tests[current_test].entry()==0?"passed":"failed");
}
return 0;
}

29
demos/test/test.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef __TEST_H_
#define __TEST_H_
#include "mycrypt.h"
typedef struct {
char *name, *prov, *req;
int (*entry)(void);
} test_entry;
extern prng_state test_yarrow;
void run_cmd(int res, int line, char *file, char *cmd);
#define DO(x) run_cmd((x), __LINE__, __FILE__, #x)
/* TESTS */
int cipher_hash_test(void);
int modes_test(void);
int mac_test(void);
int pkcs_1_test(void);
int store_test(void);
int rsa_test(void);
int ecc_tests(void);
int dsa_test(void);
int dh_tests(void);
#endif

BIN
doc/crypt.pdf Normal file

Binary file not shown.

View File

@ -19,9 +19,12 @@ int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb)
_ARGCHK(ct != NULL); _ARGCHK(ct != NULL);
_ARGCHK(ecb != NULL); _ARGCHK(ecb != NULL);
/* valid cipher? */
if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) { if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
return err; return err;
} }
_ARGCHK(cipher_descriptor[ecb->cipher].ecb_decrypt != NULL);
cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key); cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key);
return CRYPT_OK; return CRYPT_OK;
} }

View File

@ -9,7 +9,6 @@
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/ */
/* Future releases will make use of this */
#include "mycrypt.h" #include "mycrypt.h"
static const char *err_2_str[] = static const char *err_2_str[] =
@ -50,16 +49,6 @@ static const char *err_2_str[] =
}; };
#ifdef MPI
static const struct {
int mpi_code, ltc_code;
} mpi_to_ltc_codes[] = {
{ MP_OKAY , CRYPT_OK},
{ MP_MEM , CRYPT_MEM},
{ MP_VAL , CRYPT_INVALID_ARG},
};
#endif
const char *error_to_string(int err) const char *error_to_string(int err)
{ {
if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) { if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) {
@ -69,18 +58,3 @@ const char *error_to_string(int err)
} }
} }
#ifdef MPI
/* convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) */
int mpi_to_ltc_error(int err)
{
int x;
for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
if (err == mpi_to_ltc_codes[x].mpi_code) {
return mpi_to_ltc_codes[x].ltc_code;
}
}
return CRYPT_ERROR;
}
#endif

305
gf.c
View File

@ -1,305 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
/* 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

862
keyring.c
View File

@ -1,862 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
/* 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] = {
0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
0x2d02ef8dUL
};
#define DO1(buf) crc = crc_table[(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)
{
//_ARGCHK(buf != NULL && len == 0);
crc = crc ^ 0xffffffffL;
while (len >= 8) {
DO8 (buf);
len -= 8;
}
if (len > 0) {
do {
DO1 (buf);
} while (--len > 0);
}
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(0UL, NULL, 0UL);
crc = crc32(crc, name, (unsigned long)MIN(MAXLEN, strlen((char *)name)));
crc = crc32(crc, email, (unsigned long)MIN(MAXLEN, strlen((char *)email)));
return crc32(crc, description, (unsigned long)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) == 0) {
return pk;
}
pk = pk->next;
}
return NULL;
}
int kr_add(pk_key *pk, int key_type, int sys, 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 (sys != RSA_KEY && sys != DH_KEY && sys != 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 = sys;
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 (sys) {
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 err;
_ARGCHK(pk != NULL);
while ((*pk)->system != NON_KEY) {
if ((err = kr_del(pk, (*pk)->ID)) != CRYPT_OK) {
return err;
}
}
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 (unsigned long)fwrite(buf, 1, (size_t)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 = (unsigned long)fread(buf, 1, (size_t)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 err;
_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 ((err = rsa_export(obuf, &len, key_type, &(ppk->key.rsa))) != CRYPT_OK) {
return err;
}
break;
case DH_KEY:
if ((err = dh_export(obuf, &len, key_type, &(ppk->key.dh))) != CRYPT_OK) {
return err;
}
break;
case ECC_KEY:
if ((err = ecc_export(obuf, &len, key_type, &(ppk->key.ecc))) != CRYPT_OK) {
return err;
}
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, unsigned long inlen)
{
_pk_key key;
int sys, key_type, err;
unsigned long ID;
_ARGCHK(pk != NULL);
_ARGCHK(in != NULL);
if (inlen < 10) {
return CRYPT_INVALID_PACKET;
}
if (memcmp(in, key_magic, 4) != 0) {
return CRYPT_INVALID_PACKET;
}
key_type = in[4]; /* get type */
sys = 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));
/* size of remaining packet */
inlen -= 10 + 3*MAXLEN;
switch (sys) {
case RSA_KEY:
if ((err = rsa_import(in+10+3*MAXLEN, inlen, &(key.rsa))) != CRYPT_OK) {
return err;
}
break;
case DH_KEY:
if ((err = dh_import(in+10+3*MAXLEN, inlen, &(key.dh))) != CRYPT_OK) {
return err;
}
break;
case ECC_KEY:
if ((err = ecc_import(in+10+3*MAXLEN, inlen, &(key.ecc))) != CRYPT_OK) {
return err;
}
break;
}
return kr_add(pk, key_type, sys,
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, err;
_ARGCHK(pk != NULL);
_ARGCHK(in != NULL);
/* init keyring */
if ((err = kr_init(pk)) != CRYPT_OK) {
return err;
}
/* read in magic bytes */
if (_read(buf, 6, in, ctr) != 6) { goto done2; }
if (memcmp(buf, file_magic, 4) != 0) {
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 > (unsigned long)sizeof(buf)) {
return CRYPT_INVALID_PACKET;
}
if (_read(buf, len, in, ctr) != len) { goto done2; }
if ((err = kr_import(*pk, buf, len)) != CRYPT_OK) {
return err;
}
}
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, err;
_ARGCHK(pk != NULL);
_ARGCHK(out != NULL);
/* write out magic bytes */
memcpy(buf, file_magic, 4);
buf[4] = (unsigned char)(CRYPT&255);
buf[5] = (unsigned char)((CRYPT>>8)&255);
if (_write(buf, 6, out, ctr) != 6) { goto done2; }
while (pk->system != NON_KEY) {
len = sizeof(buf);
if ((err = kr_export(pk, pk->ID, pk->key_type, buf, &len)) != CRYPT_OK) {
return err;
}
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 sys, int keysize, const unsigned char *name,
const unsigned char *email, const unsigned char *description)
{
_pk_key key;
int key_type, err;
_ARGCHK(pk != NULL);
_ARGCHK(name != NULL);
_ARGCHK(email != NULL);
_ARGCHK(description != NULL);
/* valid PRNG? */
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err;
}
/* make the key first */
zeromem(&key, sizeof(key));
switch (sys) {
case RSA_KEY:
if ((err = rsa_make_key(prng, wprng, keysize, 65537, &(key.rsa))) != CRYPT_OK) {
return err;
}
key_type = key.rsa.type;
break;
case DH_KEY:
if ((err = dh_make_key(prng, wprng, keysize, &(key.dh))) != CRYPT_OK) {
return err;
}
key_type = key.dh.type;
break;
case ECC_KEY:
if ((err = ecc_make_key(prng, wprng, keysize, &(key.ecc))) != CRYPT_OK) {
return err;
}
key_type = key.ecc.type;
break;
default:
return CRYPT_PK_INVALID_SYSTEM;
}
/* now add the key */
if ((err = kr_add(pk, key_type, sys, name, email, description, &key)) != CRYPT_OK) {
return err;
}
#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 err;
_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)-12;
switch (kr->system) {
case RSA_KEY:
if ((err = rsa_encrypt_key(in, inlen, buf+12, &len, prng, wprng, &(kr->key.rsa))) != CRYPT_OK) {
return err;
}
break;
case DH_KEY:
if ((err = dh_encrypt_key(in, inlen, buf+12, &len, prng, wprng, hash, &(kr->key.dh))) != CRYPT_OK) {
return err;
}
break;
case ECC_KEY:
if ((err = ecc_encrypt_key(in, inlen, buf+12, &len, prng, wprng, hash, &(kr->key.ecc))) != CRYPT_OK) {
return err;
}
break;
}
STORE32L(len,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_decrypt_key(pk_key *pk, const unsigned char *in,
unsigned char *out, unsigned long *outlen)
{
unsigned char buf[8192];
unsigned long pklen, len, ID;
pk_key *kr;
int err;
_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 */
LOAD32L(pklen,in+8);
len = sizeof(buf);
switch (kr->system) {
case RSA_KEY:
if ((err = rsa_decrypt_key(in+12, pklen, buf, &len, &(kr->key.rsa))) != CRYPT_OK) {
return err;
}
break;
case DH_KEY:
if ((err = dh_decrypt_key(in+12, pklen, buf, &len, &(kr->key.dh))) != CRYPT_OK) {
return err;
}
break;
case ECC_KEY:
if ((err = ecc_decrypt_key(in+12, pklen, buf, &len, &(kr->key.ecc))) != CRYPT_OK) {
return err;
}
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 err;
_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)-16;
switch (kr->system) {
case RSA_KEY:
if ((err = rsa_sign_hash(in, inlen, buf+16, &len, &(kr->key.rsa))) != CRYPT_OK) {
return err;
}
break;
case DH_KEY:
if ((err = dh_sign_hash(in, inlen, buf+16, &len, prng, wprng, &(kr->key.dh))) != CRYPT_OK) {
return err;
}
break;
case ECC_KEY:
if ((err = ecc_sign_hash(in, inlen, buf+16, &len, prng, wprng, &(kr->key.ecc))) != CRYPT_OK) {
return err;
}
break;
}
STORE32L(inlen,buf+8);
STORE32L(len,buf+12);
len += 16;
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, pklen, ID;
pk_key *kr;
int err;
_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 */
LOAD32L(pklen,in+12); /* size of the PK packet */
if (inlen != hashlen) { /* size doesn't match means the signature is invalid */
return CRYPT_OK;
}
switch (kr->system) {
case RSA_KEY:
if ((err = rsa_verify_hash(in+16, pklen, hash, stat, &(kr->key.rsa))) != CRYPT_OK) {
return err;
}
break;
case DH_KEY:
if ((err = dh_verify_hash(in+16, pklen, hash, inlen, stat, &(kr->key.dh))) != CRYPT_OK) {
return err;
}
break;
case ECC_KEY:
if ((err = ecc_verify_hash(in+16, pklen, hash, inlen, stat, &(kr->key.ecc))) != CRYPT_OK) {
return err;
}
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 err;
_ARGCHK(pk != NULL);
_ARGCHK(out != NULL);
_ARGCHK(outlen != NULL);
/* valid hash? */
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
return err;
}
len = (unsigned long)sizeof(buf);
if ((err = kr_export(pk, ID, PK_PUBLIC, buf, &len)) != CRYPT_OK) {
return err;
}
/* now hash it */
if ((err = hash_memory(hash, buf, len, out, outlen)) != CRYPT_OK) {
return err;
}
#ifdef CLEAN_STACK
zeromem(buf, sizeof(buf));
#endif
return CRYPT_OK;
}
#endif

100
makefile
View File

@ -9,9 +9,8 @@
# a build. This is easy to remedy though, for those that have problems. # a build. This is easy to remedy though, for those that have problems.
# The version # The version
VERSION=0.95 VERSION=0.96
#ch1-01-1
# Compiler and Linker Names # Compiler and Linker Names
#CC=gcc #CC=gcc
#LD=ld #LD=ld
@ -19,9 +18,7 @@ VERSION=0.95
# Archiver [makes .a files] # Archiver [makes .a files]
#AR=ar #AR=ar
#ARFLAGS=r #ARFLAGS=r
#ch1-01-1
#ch1-01-3
# Compilation flags. Note the += does not write over the user's CFLAGS! # Compilation flags. Note the += does not write over the user's CFLAGS!
CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wshadow CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wshadow
# -Werror # -Werror
@ -29,8 +26,8 @@ CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wshadow
# optimize for SPEED # optimize for SPEED
#CFLAGS += -O3 -funroll-loops #CFLAGS += -O3 -funroll-loops
#add -fomit-frame-pointer. v3.2 is buggy for certain platforms! #add -fomit-frame-pointer. GCC v3.2 is buggy for certain platforms!
#CFLAGS += -fomit-frame-pointer CFLAGS += -fomit-frame-pointer
# optimize for SIZE # optimize for SIZE
CFLAGS += -Os CFLAGS += -Os
@ -43,7 +40,6 @@ CFLAGS += -Os
#Output filenames for various targets. #Output filenames for various targets.
LIBNAME=libtomcrypt.a LIBNAME=libtomcrypt.a
TEST=test
HASH=hashsum HASH=hashsum
CRYPT=encrypt CRYPT=encrypt
SMALL=small SMALL=small
@ -63,7 +59,7 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf
#Leave MPI built-in or force developer to link against libtommath? #Leave MPI built-in or force developer to link against libtommath?
MPIOBJECT=mpi.o MPIOBJECT=mpi.o
OBJECTS=keyring.o gf.o strings.o base64.o \ OBJECTS=error_to_string.o mpi_to_ltc_error.o base64_encode.o base64_decode.o \
\ \
crypt.o crypt_find_cipher.o crypt_find_hash_any.o \ crypt.o crypt_find_cipher.o crypt_find_hash_any.o \
crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \ crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \
@ -79,12 +75,16 @@ rand_prime.o is_prime.o \
\ \
ecc.o dh.o \ ecc.o dh.o \
\ \
rsa.o rsa_exptmod.o rsa_free.o rsa_make_key.o \ rsa_decrypt_key.o rsa_encrypt_key.o rsa_exptmod.o rsa_free.o rsa_make_key.o \
rsa_sign_hash.o rsa_verify_hash.o rsa_export.o rsa_import.o tim_exptmod.o \
\ \
dsa_export.o dsa_free.o dsa_import.o dsa_make_key.o dsa_sign_hash.o dsa_verify_hash.o dsa_verify_key.o \ dsa_export.o dsa_free.o dsa_import.o dsa_make_key.o dsa_sign_hash.o \
dsa_verify_hash.o dsa_verify_key.o \
\ \
xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \ aes.o aes_enc.o \
rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \ \
blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \
rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \
\ \
md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \ md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
rmd128.o rmd160.o \ rmd128.o rmd160.o \
@ -103,10 +103,10 @@ omac_done.o omac_file.o omac_init.o omac_memory.o omac_process.o omac_test.
pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \ pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \
pmac_shift_xor.o pmac_test.o \ pmac_shift_xor.o pmac_test.o \
\ \
cbc_start.o cbc_encrypt.o cbc_decrypt.o \ cbc_start.o cbc_encrypt.o cbc_decrypt.o cbc_getiv.o cbc_setiv.o \
cfb_start.o cfb_encrypt.o cfb_decrypt.o \ cfb_start.o cfb_encrypt.o cfb_decrypt.o cfb_getiv.o cfb_setiv.o \
ofb_start.o ofb_encrypt.o ofb_decrypt.o \ ofb_start.o ofb_encrypt.o ofb_decrypt.o ofb_getiv.o ofb_setiv.o \
ctr_start.o ctr_encrypt.o ctr_decrypt.o \ ctr_start.o ctr_encrypt.o ctr_decrypt.o ctr_getiv.o ctr_setiv.o \
ecb_start.o ecb_encrypt.o ecb_decrypt.o \ ecb_start.o ecb_encrypt.o ecb_decrypt.o \
\ \
hash_file.o hash_filehandle.o hash_memory.o \ hash_file.o hash_filehandle.o hash_memory.o \
@ -115,6 +115,7 @@ hmac_done.o hmac_file.o hmac_init.o hmac_memory.o hmac_process.o hmac_test.
\ \
pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \ pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \
pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \ pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_sa_decode.o \
\ \
pkcs_5_1.o pkcs_5_2.o \ pkcs_5_1.o pkcs_5_2.o \
\ \
@ -129,26 +130,27 @@ PROFS=demos/x86_prof.o
TVS=demos/tv_gen.o TVS=demos/tv_gen.o
#Files left over from making the crypt.pdf. #Files left over from making the crypt.pdf.
LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind LEFTOVERS=*.dvi *.log *.aux *.toc *.idx *.ilg *.ind *.out
#Compressed filenames #Compressed filenames
COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip
#Header files used by libtomcrypt. #Header files used by libtomcrypt.
HEADERS=tommath.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \ HEADERS=ltc_tommath.h mycrypt_cfg.h \
mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \ mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \
mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h \ mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h \
mycrypt_custom.h mycrypt_pkcs.h mycrypt_custom.h mycrypt_pkcs.h
#The default rule for make builds the libtomcrypt library. #The default rule for make builds the libtomcrypt library.
default:library mycrypt.h mycrypt_cfg.h default:library
#ciphers come in two flavours... enc+dec and enc
aes_enc.o: aes.c aes_tab.c
$(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o
#These are the rules to make certain object files. #These are the rules to make certain object files.
rsa.o: rsa.c rsa_sys.c
ecc.o: ecc.c ecc_sys.c ecc.o: ecc.c ecc_sys.c
dh.o: dh.c dh_sys.c dh.o: dh.c dh_sys.c
aes.o: aes.c aes_tab.c
twofish.o: twofish.c twofish_tab.c
sha512.o: sha512.c sha384.c sha512.o: sha512.c sha384.c
sha256.o: sha256.c sha224.c sha256.o: sha256.c sha224.c
@ -158,10 +160,6 @@ library: $(LIBNAME)
$(LIBNAME): $(OBJECTS) $(LIBNAME): $(OBJECTS)
$(AR) $(ARFLAGS) $@ $(OBJECTS) $(AR) $(ARFLAGS) $@ $(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 #This rule makes the hash program included with libtomcrypt
hashsum: library $(HASHOBJECTS) hashsum: library $(HASHOBJECTS)
$(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN) $(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN)
@ -180,34 +178,6 @@ x86_prof: library $(PROFS)
tv_gen: library $(TVS) tv_gen: library $(TVS)
$(CC) $(TVS) $(LIBNAME) -o $(TV) $(CC) $(TVS) $(LIBNAME) -o $(TV)
#make a profiled library (takes a while!!!)
#
# This will build the library with profile generation
# then run the test demo and rebuild the library.
#
# So far I've seen improvements in the MP math
#
# This works with GCC v3.3.x [tested with 3.3.3]
profiled: $(TESTOBJECTS)
make CFLAGS="$(CFLAGS) -fprofile-arcs"
$(CC) $(TESTOBJECTS) $(LIBNAME) -o $(TEST)
./test
rm -f *.a *.o test demos/test.o
make CFLAGS="$(CFLAGS) -fbranch-probabilities"
#Profiling in GCC 3.4.x is a little diff.
#
#Tested with GCC v3.4.0
profiled34: $(TESTOBJECTS)
make CFLAGS="$(CFLAGS) -fprofile-generate"
$(CC) $(TESTOBJECTS) $(LIBNAME) -lgcov -o $(TEST)
./test
rm -f *.a *.o test demos/test.o
make CFLAGS="$(CFLAGS) -fprofile-use"
#This rule installs the library and the header files. This must be run #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 #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. #directories and to set the owner and group to root.
@ -217,7 +187,7 @@ install: library docs
install -d -g root -o root $(DESTDIR)$(DATAPATH) install -d -g root -o root $(DESTDIR)$(DATAPATH)
install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH) install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH)
install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH) install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH)
install -g root -o root crypt.pdf $(DESTDIR)$(DATAPATH) install -g root -o root doc/crypt.pdf $(DESTDIR)$(DATAPATH)
#This rule cleans the source tree of all compiled code, not including the pdf #This rule cleans the source tree of all compiled code, not including the pdf
#documentation. #documentation.
@ -225,21 +195,31 @@ clean:
rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME) rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME)
rm -f $(TEST) $(HASH) $(COMPRESSED) $(PROFS) $(PROF) $(TVS) $(TV) rm -f $(TEST) $(HASH) $(COMPRESSED) $(PROFS) $(PROF) $(TVS) $(TV)
rm -f *.a *.dll *stackdump *.lib *.exe *.obj demos/*.obj demos/*.o *.bat *.txt *.il *.da demos/*.il demos/*.da *.dyn *.dpi \ rm -f *.a *.dll *stackdump *.lib *.exe *.obj demos/*.obj demos/*.o *.bat *.txt *.il *.da demos/*.il demos/*.da *.dyn *.dpi \
*.gcda *.gcno demos/*.gcno demos/*.gcda *~ *.gcda *.gcno demos/*.gcno demos/*.gcda *~ doc/*
cd demos/test ; make clean
#This builds the crypt.pdf file. Note that the rm -f *.pdf has been removed #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 #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 #nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to
#delete it if we are rebuilding it. #delete it if we are rebuilding it.
docs: crypt.tex docs: crypt.tex
rm -f crypt.pdf $(LEFTOVERS) rm -f doc/crypt.pdf $(LEFTOVERS)
echo "hello" > crypt.ind
latex crypt > /dev/null latex crypt > /dev/null
makeindex crypt > /dev/null makeindex crypt > /dev/null
latex crypt > /dev/null latex crypt > /dev/null
latex crypt > /dev/null latex crypt > /dev/null
dvipdf crypt dvipdf crypt
mv -ivf crypt.pdf doc/crypt.pdf
rm -f $(LEFTOVERS) rm -f $(LEFTOVERS)
docdvi: crypt.tex
echo hello > crypt.ind
latex crypt > /dev/null
latex crypt > /dev/null
makeindex crypt
latex crypt > /dev/null
#beta #beta
beta: clean beta: clean
cd .. ; rm -rf crypt* libtomcrypt-$(VERSION)-beta ; mkdir libtomcrypt-$(VERSION)-beta ; \ cd .. ; rm -rf crypt* libtomcrypt-$(VERSION)-beta ; mkdir libtomcrypt-$(VERSION)-beta ; \
@ -250,4 +230,6 @@ beta: clean
zipup: clean docs zipup: clean docs
cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \ cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \
cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; tar -c libtomcrypt-$(VERSION)/* > crypt-$(VERSION).tar ; \ 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)/* bzip2 -9vv crypt-$(VERSION).tar ; zip -9 -r crypt-$(VERSION).zip libtomcrypt-$(VERSION)/* ; \
gpg -b -a crypt-$(VERSION).tar.bz2 ; \
gpg -b -a crypt-$(VERSION).zip

View File

@ -1,4 +1,4 @@
#makefile for Cygwin [makes a .dll]
default: ltc_dll default: ltc_dll
@ -18,7 +18,7 @@ CFLAGS += -Os
#Leave MPI built-in or force developer to link against libtommath? #Leave MPI built-in or force developer to link against libtommath?
MPIOBJECT=mpi.o MPIOBJECT=mpi.o
OBJECTS=keyring.o gf.o strings.o base64.o \ OBJECTS=error_to_string.o mpi_to_ltc_error.o base64_encode.o base64_decode.o \
\ \
crypt.o crypt_find_cipher.o crypt_find_hash_any.o \ crypt.o crypt_find_cipher.o crypt_find_hash_any.o \
crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \ crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \
@ -34,12 +34,16 @@ rand_prime.o is_prime.o \
\ \
ecc.o dh.o \ ecc.o dh.o \
\ \
rsa.o rsa_exptmod.o rsa_free.o rsa_make_key.o \ rsa_decrypt_key.o rsa_encrypt_key.o rsa_exptmod.o rsa_free.o rsa_make_key.o \
rsa_sign_hash.o rsa_verify_hash.o rsa_export.o rsa_import.o tim_exptmod.o \
\ \
dsa_export.o dsa_free.o dsa_import.o dsa_make_key.o dsa_sign_hash.o dsa_verify_hash.o dsa_verify_key.o \ dsa_export.o dsa_free.o dsa_import.o dsa_make_key.o dsa_sign_hash.o \
dsa_verify_hash.o dsa_verify_key.o \
\ \
xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \ aes.o aes_enc.o \
rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \ \
blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \
rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \
\ \
md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \ md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
rmd128.o rmd160.o \ rmd128.o rmd160.o \
@ -58,10 +62,10 @@ omac_done.o omac_file.o omac_init.o omac_memory.o omac_process.o omac_test.
pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \ pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \
pmac_shift_xor.o pmac_test.o \ pmac_shift_xor.o pmac_test.o \
\ \
cbc_start.o cbc_encrypt.o cbc_decrypt.o \ cbc_start.o cbc_encrypt.o cbc_decrypt.o cbc_getiv.o cbc_setiv.o \
cfb_start.o cfb_encrypt.o cfb_decrypt.o \ cfb_start.o cfb_encrypt.o cfb_decrypt.o cfb_getiv.o cfb_setiv.o \
ofb_start.o ofb_encrypt.o ofb_decrypt.o \ ofb_start.o ofb_encrypt.o ofb_decrypt.o ofb_getiv.o ofb_setiv.o \
ctr_start.o ctr_encrypt.o ctr_decrypt.o \ ctr_start.o ctr_encrypt.o ctr_decrypt.o ctr_getiv.o ctr_setiv.o \
ecb_start.o ecb_encrypt.o ecb_decrypt.o \ ecb_start.o ecb_encrypt.o ecb_decrypt.o \
\ \
hash_file.o hash_filehandle.o hash_memory.o \ hash_file.o hash_filehandle.o hash_memory.o \
@ -70,15 +74,17 @@ hmac_done.o hmac_file.o hmac_init.o hmac_memory.o hmac_process.o hmac_test.
\ \
pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \ pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \
pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \ pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_sa_decode.o \
\ \
pkcs_5_1.o pkcs_5_2.o \ pkcs_5_1.o pkcs_5_2.o \
\ \
burn_stack.o zeromem.o \ burn_stack.o zeromem.o \
$(MPIOBJECT) $(MPIOBJECT)
#ciphers come in two flavours... enc+dec and enc
aes_enc.o: aes.c aes_tab.c
$(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o
ltc_dll: $(OBJECTS) $(MPIOBJECT) ltc_dll: $(OBJECTS) $(MPIOBJECT)
gcc -mno-cygwin -mdll -o libtomcrypt.dll -Wl,--out-implib=libtomcrypt.dll.a -Wl,--export-all-symbols *.o -ladvapi32 gcc -mno-cygwin -mdll -o libtomcrypt.dll -Wl,--out-implib=libtomcrypt.dll.a -Wl,--export-all-symbols *.o -ladvapi32
ranlib libtomcrypt.dll.a ranlib libtomcrypt.dll.a
test: ltc_dll
gcc $(CFLAGS) demos/test.c libtomcrypt.dll.a -Wl,--enable-auto-import -o test -s

View File

@ -24,6 +24,9 @@ CC=icc
# Compilation flags. Note the += does not write over the user's CFLAGS! # Compilation flags. Note the += does not write over the user's CFLAGS!
CFLAGS += -c -I./ -DINTEL_CC CFLAGS += -c -I./ -DINTEL_CC
#The default rule for make builds the libtomcrypt library.
default:library
# optimize for SPEED # optimize for SPEED
# #
# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4 # -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4
@ -47,7 +50,6 @@ CFLAGS += -O3 -xN -ip
#Output filenames for various targets. #Output filenames for various targets.
LIBNAME=libtomcrypt.a LIBNAME=libtomcrypt.a
TEST=test
HASH=hashsum HASH=hashsum
CRYPT=encrypt CRYPT=encrypt
SMALL=small SMALL=small
@ -67,7 +69,7 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf
#Leave MPI built-in or force developer to link against libtommath? #Leave MPI built-in or force developer to link against libtommath?
MPIOBJECT=mpi.o MPIOBJECT=mpi.o
OBJECTS=keyring.o gf.o strings.o base64.o \ OBJECTS=error_to_string.o mpi_to_ltc_error.o base64_encode.o base64_decode.o \
\ \
crypt.o crypt_find_cipher.o crypt_find_hash_any.o \ crypt.o crypt_find_cipher.o crypt_find_hash_any.o \
crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \ crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \
@ -83,12 +85,16 @@ rand_prime.o is_prime.o \
\ \
ecc.o dh.o \ ecc.o dh.o \
\ \
rsa.o rsa_exptmod.o rsa_free.o rsa_make_key.o \ rsa_decrypt_key.o rsa_encrypt_key.o rsa_exptmod.o rsa_free.o rsa_make_key.o \
rsa_sign_hash.o rsa_verify_hash.o rsa_export.o rsa_import.o tim_exptmod.o \
\ \
dsa_export.o dsa_free.o dsa_import.o dsa_make_key.o dsa_sign_hash.o dsa_verify_hash.o dsa_verify_key.o \ dsa_export.o dsa_free.o dsa_import.o dsa_make_key.o dsa_sign_hash.o \
dsa_verify_hash.o dsa_verify_key.o \
\ \
xtea.o aes.o des.o safer_tab.o safer.o saferp.o rc2.o \ aes.o aes_enc.o \
rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \ \
blowfish.o des.o safer_tab.o safer.o saferp.o rc2.o xtea.o \
rc6.o rc5.o cast5.o noekeon.o twofish.o skipjack.o \
\ \
md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \ md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
rmd128.o rmd160.o \ rmd128.o rmd160.o \
@ -107,10 +113,10 @@ omac_done.o omac_file.o omac_init.o omac_memory.o omac_process.o omac_test.
pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \ pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \
pmac_shift_xor.o pmac_test.o \ pmac_shift_xor.o pmac_test.o \
\ \
cbc_start.o cbc_encrypt.o cbc_decrypt.o \ cbc_start.o cbc_encrypt.o cbc_decrypt.o cbc_getiv.o cbc_setiv.o \
cfb_start.o cfb_encrypt.o cfb_decrypt.o \ cfb_start.o cfb_encrypt.o cfb_decrypt.o cfb_getiv.o cfb_setiv.o \
ofb_start.o ofb_encrypt.o ofb_decrypt.o \ ofb_start.o ofb_encrypt.o ofb_decrypt.o ofb_getiv.o ofb_setiv.o \
ctr_start.o ctr_encrypt.o ctr_decrypt.o \ ctr_start.o ctr_encrypt.o ctr_decrypt.o ctr_getiv.o ctr_setiv.o \
ecb_start.o ecb_encrypt.o ecb_decrypt.o \ ecb_start.o ecb_encrypt.o ecb_decrypt.o \
\ \
hash_file.o hash_filehandle.o hash_memory.o \ hash_file.o hash_filehandle.o hash_memory.o \
@ -119,13 +125,18 @@ hmac_done.o hmac_file.o hmac_init.o hmac_memory.o hmac_process.o hmac_test.
\ \
pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \ pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \
pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \ pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
pkcs_1_v15_es_encode.o pkcs_1_v15_es_decode.o pkcs_1_v15_sa_encode.o pkcs_1_v15_sa_decode.o \
\ \
pkcs_5_1.o pkcs_5_2.o \ pkcs_5_1.o pkcs_5_2.o \
\ \
burn_stack.o zeromem.o \ burn_stack.o zeromem.o \
$(MPIOBJECT) $(MPIOBJECT)
TESTOBJECTS=demos/test.o
#ciphers come in two flavours... enc+dec and enc
aes_enc.o: aes.c aes_tab.c
$(CC) $(CFLAGS) -DENCRYPT_ONLY -c aes.c -o aes_enc.o
HASHOBJECTS=demos/hashsum.o HASHOBJECTS=demos/hashsum.o
CRYPTOBJECTS=demos/encrypt.o CRYPTOBJECTS=demos/encrypt.o
SMALLOBJECTS=demos/small.o SMALLOBJECTS=demos/small.o
@ -143,9 +154,6 @@ HEADERS=tommath.h mycrypt_cfg.h mycrypt_gf.h mycrypt_kr.h \
mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \ mycrypt_misc.h mycrypt_prng.h mycrypt_cipher.h mycrypt_hash.h \
mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h mycrypt_custom.h mycrypt_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h mycrypt_custom.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. #These are the rules to make certain object files.
rsa.o: rsa.c rsa_sys.c rsa.o: rsa.c rsa_sys.c
ecc.o: ecc.c ecc_sys.c ecc.o: ecc.c ecc_sys.c
@ -161,10 +169,6 @@ library: $(LIBNAME)
$(LIBNAME): $(OBJECTS) $(LIBNAME): $(OBJECTS)
$(AR) $(ARFLAGS) $@ $(OBJECTS) $(AR) $(ARFLAGS) $@ $(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 #This rule makes the hash program included with libtomcrypt
hashsum: library $(HASHOBJECTS) hashsum: library $(HASHOBJECTS)
$(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN) $(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN)
@ -184,18 +188,6 @@ tv_gen: library $(TVS)
$(CC) $(TVS) $(LIBNAME) -o $(TV) $(CC) $(TVS) $(LIBNAME) -o $(TV)
#make a profiled library (takes a while!!!)
#
# This will build the library with profile generation
# then run the test demo and rebuild the library.
#
# So far I've seen improvements in the MP math
profiled:
make -f makefile.icc CFLAGS="$(CFLAGS) -prof_gen" test
./test
rm -f *.a *.o test demos/test.o
make -f makefile.icc CFLAGS="$(CFLAGS) -prof_use"
#This rule installs the library and the header files. This must be run #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 #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. #directories and to set the owner and group to root.

View File

@ -8,8 +8,7 @@ default: library
# leave this blank and link against libtommath if you want better link resolution # leave this blank and link against libtommath if you want better link resolution
MPIOBJECT=mpi.obj MPIOBJECT=mpi.obj
#List of objects to compile. OBJECTS=error_to_string.obj mpi_to_ltc_error.obj base64_encode.obj base64_decode.obj \
OBJECTS=keyring.obj gf.obj strings.obj base64.obj \
\ \
crypt.obj crypt_find_cipher.obj crypt_find_hash_any.obj \ crypt.obj crypt_find_cipher.obj crypt_find_hash_any.obj \
crypt_hash_is_valid.obj crypt_register_hash.obj crypt_unregister_prng.obj \ crypt_hash_is_valid.obj crypt_register_hash.obj crypt_unregister_prng.obj \
@ -25,12 +24,16 @@ rand_prime.obj is_prime.obj \
\ \
ecc.obj dh.obj \ ecc.obj dh.obj \
\ \
rsa.obj rsa_exptmod.obj rsa_free.obj rsa_make_key.obj \ rsa_decrypt_key.obj rsa_encrypt_key.obj rsa_exptmod.obj rsa_free.obj rsa_make_key.obj \
rsa_sign_hash.obj rsa_verify_hash.obj rsa_export.obj rsa_import.obj tim_exptmod.obj \
\ \
dsa_export.obj dsa_free.obj dsa_import.obj dsa_make_key.obj dsa_sign_hash.obj dsa_verify_hash.obj dsa_verify_key.obj \ dsa_export.obj dsa_free.obj dsa_import.obj dsa_make_key.obj dsa_sign_hash.obj \
dsa_verify_hash.obj dsa_verify_key.obj \
\ \
xtea.obj aes.obj des.obj safer_tab.obj safer.obj saferp.obj rc2.obj \ aes.obj aes_enc.obj \
rc6.obj rc5.obj cast5.obj noekeon.obj blowfish.obj twofish.obj skipjack.obj \ \
blowfish.obj des.obj safer_tab.obj safer.obj saferp.obj rc2.obj xtea.obj \
rc6.obj rc5.obj cast5.obj noekeon.obj twofish.obj skipjack.obj \
\ \
md2.obj md4.obj md5.obj sha1.obj sha256.obj sha512.obj tiger.obj whirl.obj \ md2.obj md4.obj md5.obj sha1.obj sha256.obj sha512.obj tiger.obj whirl.obj \
rmd128.obj rmd160.obj \ rmd128.obj rmd160.obj \
@ -49,10 +52,10 @@ omac_done.obj omac_file.obj omac_init.obj omac_memory.obj omac_process.obj
pmac_done.obj pmac_file.obj pmac_init.obj pmac_memory.obj pmac_ntz.obj pmac_process.obj \ pmac_done.obj pmac_file.obj pmac_init.obj pmac_memory.obj pmac_ntz.obj pmac_process.obj \
pmac_shift_xor.obj pmac_test.obj \ pmac_shift_xor.obj pmac_test.obj \
\ \
cbc_start.obj cbc_encrypt.obj cbc_decrypt.obj \ cbc_start.obj cbc_encrypt.obj cbc_decrypt.obj cbc_getiv.obj cbc_setiv.obj \
cfb_start.obj cfb_encrypt.obj cfb_decrypt.obj \ cfb_start.obj cfb_encrypt.obj cfb_decrypt.obj cfb_getiv.obj cfb_setiv.obj \
ofb_start.obj ofb_encrypt.obj ofb_decrypt.obj \ ofb_start.obj ofb_encrypt.obj ofb_decrypt.obj ofb_getiv.obj ofb_setiv.obj \
ctr_start.obj ctr_encrypt.obj ctr_decrypt.obj \ ctr_start.obj ctr_encrypt.obj ctr_decrypt.obj ctr_getiv.obj ctr_setiv.obj \
ecb_start.obj ecb_encrypt.obj ecb_decrypt.obj \ ecb_start.obj ecb_encrypt.obj ecb_decrypt.obj \
\ \
hash_file.obj hash_filehandle.obj hash_memory.obj \ hash_file.obj hash_filehandle.obj hash_memory.obj \
@ -61,21 +64,20 @@ hmac_done.obj hmac_file.obj hmac_init.obj hmac_memory.obj hmac_process.obj
\ \
pkcs_1_mgf1.obj pkcs_1_oaep_encode.obj pkcs_1_oaep_decode.obj \ pkcs_1_mgf1.obj pkcs_1_oaep_encode.obj pkcs_1_oaep_decode.obj \
pkcs_1_pss_encode.obj pkcs_1_pss_decode.obj pkcs_1_i2osp.obj pkcs_1_os2ip.obj \ pkcs_1_pss_encode.obj pkcs_1_pss_decode.obj pkcs_1_i2osp.obj pkcs_1_os2ip.obj \
pkcs_1_v15_es_encode.obj pkcs_1_v15_es_decode.obj pkcs_1_v15_sa_encode.obj pkcs_1_v15_sa_decode.obj \
\ \
pkcs_5_1.obj pkcs_5_2.obj \ pkcs_5_1.obj pkcs_5_2.obj \
\ \
burn_stack.obj zeromem.obj \ burn_stack.obj zeromem.obj \
$(MPIOBJECT) $(MPIOBJECT)
#ciphers come in two flavours... enc+dec and enc
aes_enc.obj: aes.c aes_tab.c
$(CC) $(CFLAGS) /DENCRYPT_ONLY /c aes.c /Foaes_enc.obj
library: $(OBJECTS) library: $(OBJECTS)
lib /out:tomcrypt.lib $(OBJECTS) lib /out:tomcrypt.lib $(OBJECTS)
test.obj: demos/test.c
cl $(CFLAGS) /c demos/test.c
test: library test.obj
cl test.obj tomcrypt.lib advapi32.lib
x86_prof: demos/x86_prof.c library x86_prof: demos/x86_prof.c library
cl $(CFLAGS) demos/x86_prof.c tomcrypt.lib advapi32.lib cl $(CFLAGS) demos/x86_prof.c tomcrypt.lib advapi32.lib

7
md2.c
View File

@ -19,6 +19,13 @@ const struct _hash_descriptor md2_desc =
7, 7,
16, 16,
16, 16,
/* DER encoding */
{ 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86,
0x48, 0x86, 0xF7, 0x0D, 0x02, 0x02, 0x05, 0x00,
0x04, 0x10 },
18,
&md2_init, &md2_init,
&md2_process, &md2_process,
&md2_done, &md2_done,

5
md4.c
View File

@ -19,6 +19,11 @@ const struct _hash_descriptor md4_desc =
6, 6,
16, 16,
64, 64,
/* DER encoding (not yet supported) */
{ 0x00 },
0,
&md4_init, &md4_init,
&md4_process, &md4_process,
&md4_done, &md4_done,

62
md5.c
View File

@ -21,6 +21,13 @@ const struct _hash_descriptor md5_desc =
3, 3,
16, 16,
64, 64,
/* DER identifier */
{ 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86,
0x48, 0x86, 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00,
0x04, 0x10 },
18,
&md5_init, &md5_init,
&md5_process, &md5_process,
&md5_done, &md5_done,
@ -44,6 +51,35 @@ const struct _hash_descriptor md5_desc =
#define II(a,b,c,d,M,s,t) \ #define II(a,b,c,d,M,s,t) \
a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b; a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
#ifdef SMALL_CODE
static const unsigned char Worder[64] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
};
static const unsigned char Rorder[64] = {
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
};
static const ulong32 Korder[64] = {
0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
};
#endif
#ifdef CLEAN_STACK #ifdef CLEAN_STACK
static void _md5_compress(hash_state *md, unsigned char *buf) static void _md5_compress(hash_state *md, unsigned char *buf)
#else #else
@ -51,6 +87,9 @@ static void md5_compress(hash_state *md, unsigned char *buf)
#endif #endif
{ {
ulong32 i, W[16], a, b, c, d; ulong32 i, W[16], a, b, c, d;
#ifdef SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */ /* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
@ -63,6 +102,28 @@ static void md5_compress(hash_state *md, unsigned char *buf)
c = md->md5.state[2]; c = md->md5.state[2];
d = md->md5.state[3]; d = md->md5.state[3];
#ifdef SMALL_CODE
for (i = 0; i < 16; ++i) {
FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 32; ++i) {
GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 48; ++i) {
HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 64; ++i) {
II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
#else
FF(a,b,c,d,W[0],7,0xd76aa478UL) FF(a,b,c,d,W[0],7,0xd76aa478UL)
FF(d,a,b,c,W[1],12,0xe8c7b756UL) FF(d,a,b,c,W[1],12,0xe8c7b756UL)
FF(c,d,a,b,W[2],17,0x242070dbUL) FF(c,d,a,b,W[2],17,0x242070dbUL)
@ -127,6 +188,7 @@ static void md5_compress(hash_state *md, unsigned char *buf)
II(d,a,b,c,W[11],10,0xbd3af235UL) II(d,a,b,c,W[11],10,0xbd3af235UL)
II(c,d,a,b,W[2],15,0x2ad7d2bbUL) II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
II(b,c,d,a,W[9],21,0xeb86d391UL) II(b,c,d,a,W[9],21,0xeb86d391UL)
#endif
md->md5.state[0] = md->md5.state[0] + a; md->md5.state[0] = md->md5.state[0] + a;
md->md5.state[1] = md->md5.state[1] + b; md->md5.state[1] = md->md5.state[1] + b;

46
modes_test.c Normal file
View File

@ -0,0 +1,46 @@
/* test CFB/OFB/CBC modes */
#include "test.h"
int modes_test(void)
{
unsigned char pt[64], ct[64], tmp[64], key[16], iv[16];
int x, cipher_idx;
symmetric_CBC cbc;
/* make a random pt, key and iv */
yarrow_read(pt, 64, &test_yarrow);
yarrow_read(key, 16, &test_yarrow);
yarrow_read(iv, 16, &test_yarrow);
/* test CBC mode */
cipher_idx = find_cipher("aes");
if (cipher_idx == -1) {
printf("test requires AES");
return 1;
}
/* encode the block */
DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
for (x = 0; x < 4; x++) {
DO(cbc_encrypt(pt+x*16, ct+x*16, &cbc));
}
/* decode the block */
DO(cbc_start(cipher_idx, iv, key, 16, 0, &cbc));
for (x = 0; x < 4; x++) {
DO(cbc_decrypt(ct+x*16, tmp+x*16, &cbc));
}
if (memcmp(tmp, pt, 64) != 0) {
printf("CBC failed");
return 1;
}
/*
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);
*/
}

240
mpi.c
View File

@ -13,7 +13,7 @@
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
static const struct { static const struct {
int code; int code;
@ -58,7 +58,7 @@ char *mp_error_to_string(int code)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* computes the modular inverse via binary extended euclidean algorithm, /* computes the modular inverse via binary extended euclidean algorithm,
* that is c = 1/a mod b * that is c = 1/a mod b
@ -205,7 +205,7 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* computes xR**-1 == x (mod N) via Montgomery Reduction /* computes xR**-1 == x (mod N) via Montgomery Reduction
* *
@ -376,7 +376,7 @@ fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* Fast (comba) multiplier /* Fast (comba) multiplier
* *
@ -452,7 +452,7 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
} }
/* setup dest */ /* setup dest */
olduse = c->used; olduse = c->used;
c->used = digs; c->used = digs;
{ {
@ -510,7 +510,7 @@ fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* this is a modified version of fast_s_mp_mul_digs that only produces /* this is a modified version of fast_s_mp_mul_digs that only produces
* output digits *above* digs. See the comments for fast_s_mp_mul_digs * output digits *above* digs. See the comments for fast_s_mp_mul_digs
@ -612,7 +612,7 @@ fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* fast squaring /* fast squaring
* *
@ -755,7 +755,7 @@ int fast_s_mp_sqr (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* computes a = 2**b /* computes a = 2**b
* *
@ -801,7 +801,7 @@ mp_2expt (mp_int * a, int b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* b = |a| /* b = |a|
* *
@ -842,7 +842,7 @@ mp_abs (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* high level addition (handles signs) */ /* high level addition (handles signs) */
int mp_add (mp_int * a, mp_int * b, mp_int * c) int mp_add (mp_int * a, mp_int * b, mp_int * c)
@ -893,7 +893,7 @@ int mp_add (mp_int * a, mp_int * b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* single digit addition */ /* single digit addition */
int int
@ -1000,7 +1000,7 @@ mp_add_d (mp_int * a, mp_digit b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* d = a + b (mod c) */ /* d = a + b (mod c) */
int int
@ -1039,7 +1039,7 @@ mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* AND two ints together */ /* AND two ints together */
int int
@ -1094,7 +1094,7 @@ mp_and (mp_int * a, mp_int * b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* trim unused digits /* trim unused digits
* *
@ -1136,7 +1136,7 @@ mp_clamp (mp_int * a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* clear one (frees) */ /* clear one (frees) */
void void
@ -1174,7 +1174,7 @@ mp_clear (mp_int * a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
#include <stdarg.h> #include <stdarg.h>
void mp_clear_multi(mp_int *mp, ...) void mp_clear_multi(mp_int *mp, ...)
@ -1206,7 +1206,7 @@ void mp_clear_multi(mp_int *mp, ...)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* compare two ints (signed)*/ /* compare two ints (signed)*/
int int
@ -1247,7 +1247,7 @@ mp_cmp (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* compare a digit */ /* compare a digit */
int mp_cmp_d(mp_int * a, mp_digit b) int mp_cmp_d(mp_int * a, mp_digit b)
@ -1289,7 +1289,7 @@ int mp_cmp_d(mp_int * a, mp_digit b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* compare maginitude of two ints (unsigned) */ /* compare maginitude of two ints (unsigned) */
int mp_cmp_mag (mp_int * a, mp_int * b) int mp_cmp_mag (mp_int * a, mp_int * b)
@ -1342,7 +1342,7 @@ int mp_cmp_mag (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
static const int lnz[16] = { static const int lnz[16] = {
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
@ -1393,7 +1393,7 @@ int mp_cnt_lsb(mp_int *a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* copy, b = a */ /* copy, b = a */
int int
@ -1459,7 +1459,7 @@ mp_copy (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* returns the number of bits in an int */ /* returns the number of bits in an int */
int int
@ -1502,7 +1502,7 @@ mp_count_bits (mp_int * a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* integer signed division. /* integer signed division.
* c*b + d == a [e.g. a/b, c=quotient, d=remainder] * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
@ -1717,7 +1717,7 @@ __Q:mp_clear (&q);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* b = a/2 */ /* b = a/2 */
int mp_div_2(mp_int * a, mp_int * b) int mp_div_2(mp_int * a, mp_int * b)
@ -1783,7 +1783,7 @@ int mp_div_2(mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* shift right by a certain bit count (store quotient in c, optional remainder in d) */ /* shift right by a certain bit count (store quotient in c, optional remainder in d) */
int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d) int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
@ -1878,7 +1878,7 @@ int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* divide by three (based on routine from MPI and the GMP manual) */ /* divide by three (based on routine from MPI and the GMP manual) */
int int
@ -1955,7 +1955,7 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
static int s_is_power_of_two(mp_digit b, int *p) static int s_is_power_of_two(mp_digit b, int *p)
{ {
@ -2061,7 +2061,7 @@ int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* determines if a number is a valid DR modulus */ /* determines if a number is a valid DR modulus */
int mp_dr_is_modulus(mp_int *a) int mp_dr_is_modulus(mp_int *a)
@ -2102,7 +2102,7 @@ int mp_dr_is_modulus(mp_int *a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* reduce "x" in place modulo "n" using the Diminished Radix algorithm. /* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
* *
@ -2194,7 +2194,7 @@ top:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* determines the setup value */ /* determines the setup value */
void mp_dr_setup(mp_int *a, mp_digit *d) void mp_dr_setup(mp_int *a, mp_digit *d)
@ -2224,7 +2224,7 @@ void mp_dr_setup(mp_int *a, mp_digit *d)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* swap the elements of two integers, for cases where you can't simply swap the /* swap the elements of two integers, for cases where you can't simply swap the
* mp_int pointers around * mp_int pointers around
@ -2256,7 +2256,7 @@ mp_exch (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* calculate c = a**b using a square-multiply algorithm */ /* calculate c = a**b using a square-multiply algorithm */
int mp_expt_d (mp_int * a, mp_digit b, mp_int * c) int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
@ -2311,7 +2311,7 @@ int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* this is a shell function that calls either the normal or Montgomery /* this is a shell function that calls either the normal or Montgomery
@ -2393,7 +2393,7 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85 /* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
* *
@ -2684,7 +2684,7 @@ __M:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* Extended euclidean algorithm of (a, b) produces /* Extended euclidean algorithm of (a, b) produces
a*u1 + b*u2 = u3 a*u1 + b*u2 = u3
@ -2757,7 +2757,7 @@ _ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* read a bigint from a file stream in ASCII */ /* read a bigint from a file stream in ASCII */
int mp_fread(mp_int *a, int radix, FILE *stream) int mp_fread(mp_int *a, int radix, FILE *stream)
@ -2822,7 +2822,7 @@ int mp_fread(mp_int *a, int radix, FILE *stream)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
int mp_fwrite(mp_int *a, int radix, FILE *stream) int mp_fwrite(mp_int *a, int radix, FILE *stream)
{ {
@ -2872,7 +2872,7 @@ int mp_fwrite(mp_int *a, int radix, FILE *stream)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* Greatest Common Divisor using the binary method */ /* Greatest Common Divisor using the binary method */
int mp_gcd (mp_int * a, mp_int * b, mp_int * c) int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
@ -2983,7 +2983,7 @@ __U:mp_clear (&v);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* get the lower 32-bits of an mp_int */ /* get the lower 32-bits of an mp_int */
unsigned long mp_get_int(mp_int * a) unsigned long mp_get_int(mp_int * a)
@ -3026,7 +3026,7 @@ unsigned long mp_get_int(mp_int * a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* grow as required */ /* grow as required */
int mp_grow (mp_int * a, int size) int mp_grow (mp_int * a, int size)
@ -3081,7 +3081,7 @@ int mp_grow (mp_int * a, int size)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* init a new bigint */ /* init a new bigint */
int mp_init (mp_int * a) int mp_init (mp_int * a)
@ -3118,7 +3118,7 @@ int mp_init (mp_int * a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* creates "a" then copies b into it */ /* creates "a" then copies b into it */
int mp_init_copy (mp_int * a, mp_int * b) int mp_init_copy (mp_int * a, mp_int * b)
@ -3148,7 +3148,7 @@ int mp_init_copy (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
#include <stdarg.h> #include <stdarg.h>
int mp_init_multi(mp_int *mp, ...) int mp_init_multi(mp_int *mp, ...)
@ -3205,7 +3205,7 @@ int mp_init_multi(mp_int *mp, ...)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* initialize and set a digit */ /* initialize and set a digit */
int mp_init_set (mp_int * a, mp_digit b) int mp_init_set (mp_int * a, mp_digit b)
@ -3235,7 +3235,7 @@ int mp_init_set (mp_int * a, mp_digit b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* initialize and set a digit */ /* initialize and set a digit */
int mp_init_set_int (mp_int * a, unsigned long b) int mp_init_set_int (mp_int * a, unsigned long b)
@ -3264,7 +3264,7 @@ int mp_init_set_int (mp_int * a, unsigned long b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* init an mp_init for a given size */ /* init an mp_init for a given size */
int mp_init_size (mp_int * a, int size) int mp_init_size (mp_int * a, int size)
@ -3301,7 +3301,7 @@ int mp_init_size (mp_int * a, int size)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* hac 14.61, pp608 */ /* hac 14.61, pp608 */
int mp_invmod (mp_int * a, mp_int * b, mp_int * c) int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
@ -3479,7 +3479,7 @@ __ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* Check if remainders are possible squares - fast exclude non-squares */ /* Check if remainders are possible squares - fast exclude non-squares */
static const char rem_128[128] = { static const char rem_128[128] = {
@ -3586,7 +3586,7 @@ ERR:mp_clear(&t);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* computes the jacobi c = (a | n) (or Legendre if n is prime) /* computes the jacobi c = (a | n) (or Legendre if n is prime)
* HAC pp. 73 Algorithm 2.149 * HAC pp. 73 Algorithm 2.149
@ -3689,7 +3689,7 @@ __A1:mp_clear (&a1);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* c = |a| * |b| using Karatsuba Multiplication using /* c = |a| * |b| using Karatsuba Multiplication using
* three half size multiplications * three half size multiplications
@ -3857,7 +3857,7 @@ ERR:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* Karatsuba squaring, computes b = a*a using three /* Karatsuba squaring, computes b = a*a using three
* half size squarings * half size squarings
@ -3976,7 +3976,7 @@ ERR:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* computes least common multiple as |a*b|/(a, b) */ /* computes least common multiple as |a*b|/(a, b) */
int mp_lcm (mp_int * a, mp_int * b, mp_int * c) int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
@ -4034,7 +4034,7 @@ __T:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* shift left a certain amount of digits */ /* shift left a certain amount of digits */
int mp_lshd (mp_int * a, int b) int mp_lshd (mp_int * a, int b)
@ -4099,7 +4099,7 @@ int mp_lshd (mp_int * a, int b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* c = a mod b, 0 <= c < b */ /* c = a mod b, 0 <= c < b */
int int
@ -4145,7 +4145,7 @@ mp_mod (mp_int * a, mp_int * b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* calc a value mod 2**b */ /* calc a value mod 2**b */
int int
@ -4198,7 +4198,7 @@ mp_mod_2d (mp_int * a, int b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
int int
mp_mod_d (mp_int * a, mp_digit b, mp_digit * c) mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
@ -4223,7 +4223,7 @@ mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* calculates a = B^n mod b for Montgomery reduction /* calculates a = B^n mod b for Montgomery reduction
* Where B is the base [e.g. 2^DIGIT_BIT]. * Where B is the base [e.g. 2^DIGIT_BIT].
@ -4280,7 +4280,7 @@ mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* computes xR**-1 == x (mod N) via Montgomery Reduction */ /* computes xR**-1 == x (mod N) via Montgomery Reduction */
int int
@ -4396,7 +4396,7 @@ mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* setups the montgomery reduction stuff */ /* setups the montgomery reduction stuff */
int int
@ -4453,7 +4453,7 @@ mp_montgomery_setup (mp_int * n, mp_digit * rho)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* high level multiplication (handles sign) */ /* high level multiplication (handles sign) */
int mp_mul (mp_int * a, mp_int * b, mp_int * c) int mp_mul (mp_int * a, mp_int * b, mp_int * c)
@ -4505,7 +4505,7 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* b = a*2 */ /* b = a*2 */
int mp_mul_2(mp_int * a, mp_int * b) int mp_mul_2(mp_int * a, mp_int * b)
@ -4585,7 +4585,7 @@ int mp_mul_2(mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* shift left by a certain bit count */ /* shift left by a certain bit count */
int mp_mul_2d (mp_int * a, int b, mp_int * c) int mp_mul_2d (mp_int * a, int b, mp_int * c)
@ -4668,7 +4668,7 @@ int mp_mul_2d (mp_int * a, int b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* multiply by a digit */ /* multiply by a digit */
int int
@ -4744,7 +4744,7 @@ mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* d = a * b (mod c) */ /* d = a * b (mod c) */
int int
@ -4783,7 +4783,7 @@ mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* find the n'th root of an integer /* find the n'th root of an integer
* *
@ -4913,7 +4913,7 @@ __T1:mp_clear (&t1);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* b = -a */ /* b = -a */
int mp_neg (mp_int * a, mp_int * b) int mp_neg (mp_int * a, mp_int * b)
@ -4945,7 +4945,7 @@ int mp_neg (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* OR two ints together */ /* OR two ints together */
int mp_or (mp_int * a, mp_int * b, mp_int * c) int mp_or (mp_int * a, mp_int * b, mp_int * c)
@ -4993,7 +4993,7 @@ int mp_or (mp_int * a, mp_int * b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* performs one Fermat test. /* performs one Fermat test.
* *
@ -5053,7 +5053,7 @@ __T:mp_clear (&t);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* determines if an integers is divisible by one /* determines if an integers is divisible by one
* of the first PRIME_SIZE primes or not * of the first PRIME_SIZE primes or not
@ -5101,7 +5101,7 @@ int mp_prime_is_divisible (mp_int * a, int *result)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* performs a variable number of rounds of Miller-Rabin /* performs a variable number of rounds of Miller-Rabin
* *
@ -5182,7 +5182,7 @@ __B:mp_clear (&b);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* Miller-Rabin test of "a" to the base of "b" as described in /* Miller-Rabin test of "a" to the base of "b" as described in
* HAC pp. 139 Algorithm 4.24 * HAC pp. 139 Algorithm 4.24
@ -5283,7 +5283,7 @@ __N1:mp_clear (&n1);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* finds the next prime after the number "a" using "t" trials /* finds the next prime after the number "a" using "t" trials
* of Miller-Rabin. * of Miller-Rabin.
@ -5451,7 +5451,7 @@ __ERR:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* makes a truly random prime of a given size (bits), /* makes a truly random prime of a given size (bits),
* *
@ -5573,7 +5573,7 @@ error:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* returns size of ASCII reprensentation */ /* returns size of ASCII reprensentation */
int mp_radix_size (mp_int * a, int radix, int *size) int mp_radix_size (mp_int * a, int radix, int *size)
@ -5642,7 +5642,7 @@ int mp_radix_size (mp_int * a, int radix, int *size)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* chars used in radix conversions */ /* chars used in radix conversions */
const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
@ -5664,7 +5664,7 @@ const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrs
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* makes a pseudo-random int of a given size */ /* makes a pseudo-random int of a given size */
int int
@ -5717,7 +5717,7 @@ mp_rand (mp_int * a, int digits)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* read a string [ASCII] in a given radix */ /* read a string [ASCII] in a given radix */
int mp_read_radix (mp_int * a, char *str, int radix) int mp_read_radix (mp_int * a, char *str, int radix)
@ -5797,7 +5797,7 @@ int mp_read_radix (mp_int * a, char *str, int radix)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* read signed bin, big endian, first byte is 0==positive or 1==negative */ /* read signed bin, big endian, first byte is 0==positive or 1==negative */
int int
@ -5837,7 +5837,7 @@ mp_read_signed_bin (mp_int * a, unsigned char *b, int c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* reads a unsigned char array, assumes the msb is stored first [big endian] */ /* reads a unsigned char array, assumes the msb is stored first [big endian] */
int int
@ -5891,7 +5891,7 @@ mp_read_unsigned_bin (mp_int * a, unsigned char *b, int c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* reduces x mod m, assumes 0 < x < m**2, mu is /* reduces x mod m, assumes 0 < x < m**2, mu is
* precomputed via mp_reduce_setup. * precomputed via mp_reduce_setup.
@ -5979,7 +5979,7 @@ CLEANUP:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* reduces a modulo n where n is of the form 2**p - d */ /* reduces a modulo n where n is of the form 2**p - d */
int int
@ -6039,7 +6039,7 @@ ERR:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* determines the setup value */ /* determines the setup value */
int int
@ -6085,7 +6085,7 @@ mp_reduce_2k_setup(mp_int *a, mp_digit *d)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* determines if mp_reduce_2k can be used */ /* determines if mp_reduce_2k can be used */
int mp_reduce_is_2k(mp_int *a) int mp_reduce_is_2k(mp_int *a)
@ -6134,7 +6134,7 @@ int mp_reduce_is_2k(mp_int *a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* pre-calculate the value required for Barrett reduction /* pre-calculate the value required for Barrett reduction
* For a given modulus "b" it calulates the value required in "a" * For a given modulus "b" it calulates the value required in "a"
@ -6167,7 +6167,7 @@ mp_reduce_setup (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* shift right a certain amount of digits */ /* shift right a certain amount of digits */
void mp_rshd (mp_int * a, int b) void mp_rshd (mp_int * a, int b)
@ -6237,7 +6237,7 @@ void mp_rshd (mp_int * a, int b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* set to a digit */ /* set to a digit */
void mp_set (mp_int * a, mp_digit b) void mp_set (mp_int * a, mp_digit b)
@ -6264,7 +6264,7 @@ void mp_set (mp_int * a, mp_digit b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* set a 32-bit const */ /* set a 32-bit const */
int mp_set_int (mp_int * a, unsigned long b) int mp_set_int (mp_int * a, unsigned long b)
@ -6310,7 +6310,7 @@ int mp_set_int (mp_int * a, unsigned long b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* shrink a bignum */ /* shrink a bignum */
int mp_shrink (mp_int * a) int mp_shrink (mp_int * a)
@ -6343,7 +6343,7 @@ int mp_shrink (mp_int * a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* get the size for an signed equivalent */ /* get the size for an signed equivalent */
int mp_signed_bin_size (mp_int * a) int mp_signed_bin_size (mp_int * a)
@ -6368,7 +6368,7 @@ int mp_signed_bin_size (mp_int * a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* computes b = a*a */ /* computes b = a*a */
int int
@ -6413,7 +6413,7 @@ mp_sqr (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* c = a * a (mod b) */ /* c = a * a (mod b) */
int int
@ -6452,7 +6452,7 @@ mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* this function is less generic than mp_n_root, simpler and faster */ /* this function is less generic than mp_n_root, simpler and faster */
int mp_sqrt(mp_int *arg, mp_int *ret) int mp_sqrt(mp_int *arg, mp_int *ret)
@ -6531,7 +6531,7 @@ E2: mp_clear(&t1);
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* high level subtraction (handles signs) */ /* high level subtraction (handles signs) */
int int
@ -6588,7 +6588,7 @@ mp_sub (mp_int * a, mp_int * b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* single digit subtraction */ /* single digit subtraction */
int int
@ -6675,7 +6675,7 @@ mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* d = a - b (mod c) */ /* d = a - b (mod c) */
int int
@ -6715,7 +6715,7 @@ mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* store in signed [big endian] format */ /* store in signed [big endian] format */
int int
@ -6747,7 +6747,7 @@ mp_to_signed_bin (mp_int * a, unsigned char *b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* store in unsigned [big endian] format */ /* store in unsigned [big endian] format */
int int
@ -6794,7 +6794,7 @@ mp_to_unsigned_bin (mp_int * a, unsigned char *b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* multiplication using the Toom-Cook 3-way algorithm */ /* multiplication using the Toom-Cook 3-way algorithm */
int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c) int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
@ -7070,7 +7070,7 @@ ERR:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* squaring using Toom-Cook 3-way algorithm */ /* squaring using Toom-Cook 3-way algorithm */
int int
@ -7294,7 +7294,7 @@ ERR:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* stores a bignum as a ASCII string in a given radix (2..64) */ /* stores a bignum as a ASCII string in a given radix (2..64) */
int mp_toradix (mp_int * a, char *str, int radix) int mp_toradix (mp_int * a, char *str, int radix)
@ -7367,7 +7367,7 @@ int mp_toradix (mp_int * a, char *str, int radix)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* stores a bignum as a ASCII string in a given radix (2..64) /* stores a bignum as a ASCII string in a given radix (2..64)
* *
@ -7454,7 +7454,7 @@ int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* get the size for an unsigned equivalent */ /* get the size for an unsigned equivalent */
int int
@ -7481,7 +7481,7 @@ mp_unsigned_bin_size (mp_int * a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* XOR two ints together */ /* XOR two ints together */
int int
@ -7530,7 +7530,7 @@ mp_xor (mp_int * a, mp_int * b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* set to zero */ /* set to zero */
void void
@ -7558,7 +7558,7 @@ mp_zero (mp_int * a)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* this table gives the # of rabin miller trials for a prob of failure lower than 2^-96 */ /* this table gives the # of rabin miller trials for a prob of failure lower than 2^-96 */
static const struct { static const struct {
@ -7613,7 +7613,7 @@ int mp_prime_rabin_miller_trials(int size)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
const mp_digit __prime_tab[] = { const mp_digit __prime_tab[] = {
0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013, 0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035, 0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
@ -7672,7 +7672,7 @@ const mp_digit __prime_tab[] = {
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* reverse an array, used for radix code */ /* reverse an array, used for radix code */
void void
@ -7709,7 +7709,7 @@ bn_reverse (unsigned char *s, int len)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* low level addition, based on HAC pp.594, Algorithm 14.7 */ /* low level addition, based on HAC pp.594, Algorithm 14.7 */
int int
@ -7816,7 +7816,7 @@ s_mp_add (mp_int * a, mp_int * b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
#ifdef MP_LOW_MEM #ifdef MP_LOW_MEM
#define TAB_SIZE 32 #define TAB_SIZE 32
@ -8054,7 +8054,7 @@ __M:
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* multiplies |a| * |b| and only computes upto digs digits of result /* multiplies |a| * |b| and only computes upto digs digits of result
* HAC pp. 595, Algorithm 14.12 Modified so you can control how * HAC pp. 595, Algorithm 14.12 Modified so you can control how
@ -8143,7 +8143,7 @@ s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* multiplies |a| * |b| and does not compute the lower digs digits /* multiplies |a| * |b| and does not compute the lower digs digits
* [meant to get the higher part of the product] * [meant to get the higher part of the product]
@ -8220,7 +8220,7 @@ s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */ /* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
int int
@ -8303,7 +8303,7 @@ s_mp_sqr (mp_int * a, mp_int * b)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */ /* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
int int
@ -8390,20 +8390,22 @@ s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
* *
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org * Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/ */
#include <tommath.h> #include <ltc_tommath.h>
/* Known optimal configurations /* Known optimal configurations
CPU /Compiler /MUL CUTOFF/SQR CUTOFF CPU /Compiler /MUL CUTOFF/SQR CUTOFF
------------------------------------------------------------- -------------------------------------------------------------
Intel P4 /GCC v3.2 / 70/ 108 Intel P4 Northwood /GCC v3.3.3 / 59/ 81/profiled build
AMD Athlon XP /GCC v3.2 / 109/ 127 Intel P4 Northwood /GCC v3.3.3 / 59/ 80/profiled_single build
Intel P4 Northwood /ICC v8.0 / 57/ 70/profiled build
Intel P4 Northwood /ICC v8.0 / 54/ 76/profiled_single build
AMD Athlon XP /GCC v3.2 / 109/ 127/
*/ */
/* configured for a AMD XP Thoroughbred core with etc/tune.c */ int KARATSUBA_MUL_CUTOFF = 57, /* Min. number of digits before Karatsuba multiplication is used. */
int KARATSUBA_MUL_CUTOFF = 70, /* Min. number of digits before Karatsuba multiplication is used. */ KARATSUBA_SQR_CUTOFF = 70, /* Min. number of digits before Karatsuba squaring is used. */
KARATSUBA_SQR_CUTOFF = 108, /* Min. number of digits before Karatsuba squaring is used. */
TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */ TOOM_MUL_CUTOFF = 350, /* no optimal values of these are known yet so set em high */
TOOM_SQR_CUTOFF = 400; TOOM_SQR_CUTOFF = 400;

36
mpi_to_ltc_error.c Normal file
View File

@ -0,0 +1,36 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef MPI
static const struct {
int mpi_code, ltc_code;
} mpi_to_ltc_codes[] = {
{ MP_OKAY , CRYPT_OK},
{ MP_MEM , CRYPT_MEM},
{ MP_VAL , CRYPT_INVALID_ARG},
};
/* convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no) */
int mpi_to_ltc_error(int err)
{
int x;
for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
if (err == mpi_to_ltc_codes[x].mpi_code) {
return mpi_to_ltc_codes[x].ltc_code;
}
}
return CRYPT_ERROR;
}
#endif

View File

@ -16,8 +16,8 @@ extern "C" {
#endif #endif
/* version */ /* version */
#define CRYPT 0x0095 #define CRYPT 0x0096
#define SCRYPT "0.95" #define SCRYPT "0.96"
/* max size of either a cipher/hash block or symmetric key [largest of the two] */ /* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 128 #define MAXBLOCKSIZE 128
@ -68,9 +68,7 @@ enum {
#include <mycrypt_hash.h> #include <mycrypt_hash.h>
#include <mycrypt_prng.h> #include <mycrypt_prng.h>
#include <mycrypt_pk.h> #include <mycrypt_pk.h>
#include <mycrypt_gf.h>
#include <mycrypt_misc.h> #include <mycrypt_misc.h>
#include <mycrypt_kr.h>
#include <mycrypt_argchk.h> #include <mycrypt_argchk.h>
#include <mycrypt_pkcs.h> #include <mycrypt_pkcs.h>

View File

@ -261,12 +261,22 @@ extern const struct _cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk
#define aes_test rijndael_test #define aes_test rijndael_test
#define aes_keysize rijndael_keysize #define aes_keysize rijndael_keysize
#define aes_enc_setup rijndael_enc_setup
#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt
#define aes_enc_keysize rijndael_enc_keysize
extern int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); extern int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
extern void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key); extern void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
extern void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, 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_test(void);
extern int rijndael_keysize(int *desired_keysize); extern int rijndael_keysize(int *desired_keysize);
extern int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
extern void rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
extern int rijndael_enc_keysize(int *desired_keysize);
extern const struct _cipher_descriptor rijndael_desc, aes_desc; extern const struct _cipher_descriptor rijndael_desc, aes_desc;
extern const struct _cipher_descriptor rijndael_enc_desc, aes_enc_desc;
#endif #endif
#ifdef XTEA #ifdef XTEA
@ -342,6 +352,8 @@ extern int cfb_start(int cipher, const unsigned char *IV, const unsigned char *k
int keylen, int num_rounds, symmetric_CFB *cfb); 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_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); extern int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb);
extern int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb);
extern int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb);
#endif #endif
#ifdef OFB #ifdef OFB
@ -349,6 +361,8 @@ extern int ofb_start(int cipher, const unsigned char *IV, const unsigned char *k
int keylen, int num_rounds, symmetric_OFB *ofb); 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_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); extern int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb);
extern int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb);
extern int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb);
#endif #endif
#ifdef CBC #ifdef CBC
@ -356,6 +370,8 @@ extern int cbc_start(int cipher, const unsigned char *IV, const unsigned char *k
int keylen, int num_rounds, symmetric_CBC *cbc); 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_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); extern int cbc_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc);
extern int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc);
extern int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc);
#endif #endif
#ifdef CTR #ifdef CTR
@ -363,6 +379,8 @@ extern int ctr_start(int cipher, const unsigned char *IV, const unsigned char *k
int keylen, int num_rounds, symmetric_CTR *ctr); 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_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr);
extern int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr); extern int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr);
extern int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr);
extern int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr);
#endif #endif

View File

@ -9,14 +9,27 @@
#error mycrypt_custom.h should be included before mycrypt.h #error mycrypt_custom.h should be included before mycrypt.h
#endif #endif
/* macros for various libc functions */
#define XMALLOC malloc #define XMALLOC malloc
#define XREALLOC realloc #define XREALLOC realloc
#define XCALLOC calloc #define XCALLOC calloc
#define XFREE free #define XFREE free
#define XCLOCK clock #define XCLOCK clock
#define XCLOCKS_PER_SEC CLOCKS_PER_SEC #define XCLOCKS_PER_SEC CLOCKS_PER_SEC
/* Use small code where possible */
#define SMALL_CODE #define SMALL_CODE
/* Enable self-test test vector checking */
#define LTC_TEST #define LTC_TEST
/* clean the stack of functions which put private information on stack */
//#define CLEAN_STACK
/* disable all file related functions */
//#define NO_FILE
/* various ciphers */
#define BLOWFISH #define BLOWFISH
#define RC2 #define RC2
#define RC5 #define RC5
@ -26,15 +39,21 @@
#define XTEA #define XTEA
#define TWOFISH #define TWOFISH
#define TWOFISH_TABLES #define TWOFISH_TABLES
//#define TWOFISH_ALL_TABLES
//#define TWOFISH_SMALL
#define DES #define DES
#define CAST5 #define CAST5
#define NOEKEON #define NOEKEON
#define SKIPJACK #define SKIPJACK
/* modes of operation */
#define CFB #define CFB
#define OFB #define OFB
#define ECB #define ECB
#define CBC #define CBC
#define CTR #define CTR
/* hash functions */
#define WHIRLPOOL #define WHIRLPOOL
#define SHA512 #define SHA512
#define SHA384 #define SHA384
@ -47,18 +66,30 @@
#define MD2 #define MD2
#define RIPEMD128 #define RIPEMD128
#define RIPEMD160 #define RIPEMD160
/* MAC functions */
#define HMAC #define HMAC
#define OMAC #define OMAC
#define PMAC #define PMAC
/* Encrypt + Authenticate Modes */
#define EAX_MODE #define EAX_MODE
#define OCB_MODE #define OCB_MODE
/* Various tidbits of modern neatoness */
#define BASE64 #define BASE64
#define YARROW #define YARROW
// which descriptor of AES to use?
// 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full]
#define YARROW_AES 0
#define SPRNG #define SPRNG
#define RC4 #define RC4
#define DEVRANDOM #define DEVRANDOM
#define TRY_URANDOM_FIRST #define TRY_URANDOM_FIRST
/* Public Key Neatoness */
#define MRSA #define MRSA
#define RSA_TIMING // enable RSA side channel timing prevention
#define MDSA #define MDSA
#define MDH #define MDH
#define MECC #define MECC
@ -79,10 +110,10 @@
#define ECC521 #define ECC521
#define MPI #define MPI
/* PKCS #1 and 5 stuff */
#define PKCS_1 #define PKCS_1
#define PKCS_5 #define PKCS_5
#include <mycrypt.h> #include <mycrypt.h>
#endif #endif

View File

@ -1,32 +0,0 @@
/* ---- 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

View File

@ -116,6 +116,8 @@ extern struct _hash_descriptor {
unsigned char ID; unsigned char ID;
unsigned long hashsize; /* digest output size in bytes */ unsigned long hashsize; /* digest output size in bytes */
unsigned long blocksize; /* the block size the hash uses */ unsigned long blocksize; /* the block size the hash uses */
unsigned char DER[64]; /* DER encoded identifier */
unsigned long DERlen; /* length of DER encoding */
void (*init)(hash_state *); void (*init)(hash_state *);
int (*process)(hash_state *, const unsigned char *, unsigned long); int (*process)(hash_state *, const unsigned char *, unsigned long);
int (*done)(hash_state *, unsigned char *); int (*done)(hash_state *, unsigned char *);

View File

@ -1,7 +1,7 @@
/* ---- NUMBER THEORY ---- */ /* ---- NUMBER THEORY ---- */
#ifdef MPI #ifdef MPI
#include "tommath.h" #include "ltc_tommath.h"
/* in/out macros */ /* in/out macros */
#define OUTPUT_BIGNUM(num, out, y, z) \ #define OUTPUT_BIGNUM(num, out, y, z) \
@ -86,7 +86,7 @@ extern int packet_valid_header(unsigned char *src, int section, int subsection);
#define MAX_RSA_SIZE 4096 #define MAX_RSA_SIZE 4096
/* Stack required for temps (plus padding) */ /* Stack required for temps (plus padding) */
#define RSA_STACK (8 + (MAX_RSA_SIZE/8)) // #define RSA_STACK (8 + (MAX_RSA_SIZE/8))
typedef struct Rsa_key { typedef struct Rsa_key {
int type; int type;
@ -95,43 +95,51 @@ typedef struct Rsa_key {
extern int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *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, extern int rsa_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which, unsigned char *out, unsigned long *outlen, int which,
rsa_key *key); prng_state *prng, int prng_idx,
rsa_key *key);
extern int rsa_pad(const unsigned char *in, unsigned long inlen, #ifdef RSA_TIMING
unsigned char *out, unsigned long *outlen,
int wprng, prng_state *prng);
extern int rsa_signpad(const unsigned char *in, unsigned long inlen, extern int tim_exptmod(prng_state *prng, int prng_idx,
unsigned char *out, unsigned long *outlen); mp_int *c, mp_int *e, mp_int *d, mp_int *n, mp_int *m);
extern int rsa_depad(const unsigned char *in, unsigned long inlen, #else
unsigned char *out, unsigned long *outlen);
extern int rsa_signdepad(const unsigned char *in, unsigned long inlen, #define tim_exptmod(prng, prng_idx, c, e, d, n, m) mpi_to_ltc_error(mp_exptmod(c, d, n, m))
unsigned char *out, unsigned long *outlen);
#endif
extern void rsa_free(rsa_key *key); extern void rsa_free(rsa_key *key);
extern int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen, int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
unsigned char *outkey, unsigned long *outlen, unsigned char *outkey, unsigned long *outlen,
prng_state *prng, int wprng, rsa_key *key); const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx, int hash_idx, rsa_key *key);
extern int rsa_decrypt_key(const unsigned char *in, unsigned long inlen, int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *outkey, unsigned long *keylen, unsigned char *outkey, unsigned long *keylen,
rsa_key *key); const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx,
int hash_idx, int *res,
rsa_key *key);
extern int rsa_sign_hash(const unsigned char *in, unsigned long inlen, int rsa_sign_hash(const unsigned char *msghash, unsigned long msghashlen,
unsigned char *out, unsigned long *outlen, unsigned char *sig, unsigned long *siglen,
rsa_key *key); prng_state *prng, int prng_idx,
int hash_idx, unsigned long saltlen,
rsa_key *key);
extern int rsa_verify_hash(const unsigned char *sig, unsigned long siglen, int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, int *stat, rsa_key *key); const unsigned char *msghash, unsigned long msghashlen,
prng_state *prng, int prng_idx,
int hash_idx, unsigned long saltlen,
int *stat, rsa_key *key);
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
int rsa_import(const unsigned char *in, unsigned long inlen, 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, unsigned long inlen, rsa_key *key);
#endif #endif
/* ---- DH Routines ---- */ /* ---- DH Routines ---- */

View File

@ -7,20 +7,25 @@ int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen,
int hash_idx, int hash_idx,
unsigned char *mask, unsigned long masklen); unsigned char *mask, unsigned long masklen);
int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out);
int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen);
/* *** v2.0 padding */
int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx, unsigned long modulus_bitlen, prng_state *prng,
int prng_idx, prng_state *prng, int prng_idx, int hash_idx,
unsigned char *out, unsigned long *outlen); unsigned char *out, unsigned long *outlen);
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx, unsigned long modulus_bitlen, int hash_idx,
unsigned char *out, unsigned long *outlen); unsigned char *out, unsigned long *outlen,
int *res);
int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
unsigned long saltlen, int hash_idx, unsigned long saltlen, prng_state *prng,
int prng_idx, prng_state *prng, int prng_idx, int hash_idx,
unsigned long modulus_bitlen, unsigned long modulus_bitlen,
unsigned char *out, unsigned long *outlen); unsigned char *out, unsigned long *outlen);
@ -29,8 +34,30 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
unsigned long saltlen, int hash_idx, unsigned long saltlen, int hash_idx,
unsigned long modulus_bitlen, int *res); unsigned long modulus_bitlen, int *res);
int pkcs_1_i2osp(mp_int *n, unsigned long modulus_len, unsigned char *out); /* *** v1.5 padding */
int pkcs_1_os2ip(mp_int *n, unsigned char *in, unsigned long inlen); /* encryption padding */
int pkcs_1_v15_es_encode(const unsigned char *msg, unsigned long msglen,
unsigned long modulus_bitlen,
prng_state *prng, int prng_idx,
unsigned char *out, unsigned long *outlen);
/* note "outlen" is fixed, you have to tell this decoder how big
* the original message was. Unlike the OAEP decoder it cannot auto-detect it.
*/
int pkcs_1_v15_es_decode(const unsigned char *msg, unsigned long msglen,
unsigned long modulus_bitlen,
unsigned char *out, unsigned long outlen,
int *res);
/* signature padding */
int pkcs_1_v15_sa_encode(const unsigned char *msghash, unsigned long msghashlen,
int hash_idx, unsigned long modulus_bitlen,
unsigned char *out, unsigned long *outlen);
int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
const unsigned char *sig, unsigned long siglen,
int hash_idx, unsigned long modulus_bitlen,
int *res);
#endif /* PKCS_1 */ #endif /* PKCS_1 */

View File

@ -22,9 +22,14 @@ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt)
_ARGCHK(ocb != NULL); _ARGCHK(ocb != NULL);
_ARGCHK(pt != NULL); _ARGCHK(pt != NULL);
_ARGCHK(ct != NULL); _ARGCHK(ct != NULL);
/* check if valid cipher */
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) { if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
return err; return err;
} }
_ARGCHK(cipher_descriptor[ocb->cipher].ecb_decrypt != NULL);
/* check length */
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) { if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
return CRYPT_INVALID_ARG; return CRYPT_INVALID_ARG;
} }

30
ofb_getiv.c Normal file
View File

@ -0,0 +1,30 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef OFB
int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb)
{
_ARGCHK(IV != NULL);
_ARGCHK(len != NULL);
_ARGCHK(ofb != NULL);
if ((unsigned long)ofb->blocklen > *len) {
return CRYPT_BUFFER_OVERFLOW;
}
memcpy(IV, ofb->IV, ofb->blocklen);
*len = ofb->blocklen;
return CRYPT_OK;
}
#endif

38
ofb_setiv.c Normal file
View File

@ -0,0 +1,38 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef OFB
int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb)
{
int err;
_ARGCHK(IV != NULL);
_ARGCHK(ofb != NULL);
if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
return err;
}
if (len != (unsigned long)ofb->blocklen) {
return CRYPT_INVALID_ARG;
}
/* force next block */
ofb->padlen = 0;
cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
return CRYPT_OK;
}
#endif

View File

@ -15,9 +15,10 @@
#ifdef PKCS_1 #ifdef PKCS_1
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen, int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx, unsigned long modulus_bitlen, int hash_idx,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen,
int *res)
{ {
unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)]; unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)];
unsigned long hLen, x, y, modulus_len; unsigned long hLen, x, y, modulus_len;
@ -26,6 +27,10 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
_ARGCHK(msg != NULL); _ARGCHK(msg != NULL);
_ARGCHK(out != NULL); _ARGCHK(out != NULL);
_ARGCHK(outlen != NULL); _ARGCHK(outlen != NULL);
_ARGCHK(res != NULL);
/* default to invalid packet */
*res = 0;
/* test valid hash */ /* test valid hash */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) { if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
@ -49,7 +54,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
/* must have leading 0x00 byte */ /* must have leading 0x00 byte */
if (msg[0] != 0x00) { if (msg[0] != 0x00) {
return CRYPT_INVALID_PACKET; return CRYPT_OK;
} }
/* now read the masked seed */ /* now read the masked seed */
@ -99,7 +104,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
/* compare the lhash'es */ /* compare the lhash'es */
if (memcmp(seed, DB, hLen) != 0) { if (memcmp(seed, DB, hLen) != 0) {
return CRYPT_INVALID_PACKET; return CRYPT_OK;
} }
/* now zeroes before a 0x01 */ /* now zeroes before a 0x01 */
@ -109,7 +114,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
/* error out if wasn't 0x01 */ /* error out if wasn't 0x01 */
if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) { if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) {
return CRYPT_INVALID_PACKET; return CRYPT_OK;
} }
/* rest is the message (and skip 0x01) */ /* rest is the message (and skip 0x01) */
@ -129,6 +134,9 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
zeromem(mask, sizeof(mask)); zeromem(mask, sizeof(mask));
#endif #endif
/* valid packet */
*res = 1;
return CRYPT_OK; return CRYPT_OK;
} }

View File

@ -15,10 +15,10 @@
#ifdef PKCS_1 #ifdef PKCS_1
int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen, int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen, const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx, unsigned long modulus_bitlen, prng_state *prng,
int prng_idx, prng_state *prng, int prng_idx, int hash_idx,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)]; unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)];
unsigned long hLen, x, y, modulus_len; unsigned long hLen, x, y, modulus_len;

View File

@ -60,7 +60,7 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
} }
/* check the MSB */ /* check the MSB */
if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - modulus_bitlen))) != 0) { if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) {
return CRYPT_OK; return CRYPT_OK;
} }
@ -74,6 +74,9 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
DB[y] ^= mask[y]; DB[y] ^= mask[y];
} }
/* now clear the first byte [make sure smaller than modulus] */
DB[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
/* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */ /* DB = PS || 0x01 || salt, PS == modulus_len - saltlen - hLen - 2 zero bytes */
/* check for zeroes and 0x01 */ /* check for zeroes and 0x01 */

View File

@ -15,8 +15,8 @@
#ifdef PKCS_1 #ifdef PKCS_1
int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen, int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
unsigned long saltlen, int hash_idx, unsigned long saltlen, prng_state *prng,
int prng_idx, prng_state *prng, int prng_idx, int hash_idx,
unsigned long modulus_bitlen, unsigned long modulus_bitlen,
unsigned char *out, unsigned long *outlen) unsigned char *out, unsigned long *outlen)
{ {
@ -104,7 +104,7 @@ int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
out[y] = 0xBC; out[y] = 0xBC;
/* now clear the 8*modulus_len - modulus_bitlen most significant bits */ /* now clear the 8*modulus_len - modulus_bitlen most significant bits */
out[0] &= 0xFF >> ((modulus_len<<3) - modulus_bitlen); out[0] &= 0xFF >> ((modulus_len<<3) - (modulus_bitlen-1));
/* store output size */ /* store output size */
*outlen = modulus_len; *outlen = modulus_len;

61
pkcs_1_v15_es_decode.c Normal file
View File

@ -0,0 +1,61 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
/* PKCS #1 v1.5 Encryption Padding -- Tom St Denis */
#ifdef PKCS_1
int pkcs_1_v15_es_decode(const unsigned char *msg, unsigned long msglen,
unsigned long modulus_bitlen,
unsigned char *out, unsigned long outlen,
int *res)
{
unsigned long x, modulus_bytelen;
_ARGCHK(msg != NULL);
_ARGCHK(out != NULL);
_ARGCHK(res != NULL);
/* default to failed */
*res = 0;
/* must be at least 12 bytes long */
if (msglen < 12) {
return CRYPT_INVALID_ARG;
}
modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
/* should start with 0x00 0x02 */
if (msg[0] != 0x00 || msg[1] != 0x02) {
return CRYPT_OK;
}
/* skip over PS */
x = 2 + (modulus_bytelen - outlen - 3);
/* should be 0x00 */
if (msg[x++] != 0x00) {
return CRYPT_OK;
}
/* the message is left */
if (x + outlen > modulus_bytelen) {
return CRYPT_PK_INVALID_SIZE;
}
memcpy(out, msg + x, outlen);
*res = 1;
return CRYPT_OK;
}
#endif

55
pkcs_1_v15_es_encode.c Normal file
View File

@ -0,0 +1,55 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
/* v1.5 Encryption Padding for PKCS #1 -- Tom St Denis */
#ifdef PKCS_1
int pkcs_1_v15_es_encode(const unsigned char *msg, unsigned long msglen,
unsigned long modulus_bitlen,
prng_state *prng, int prng_idx,
unsigned char *out, unsigned long *outlen)
{
unsigned long modulus_bytelen, x, y;
_ARGCHK(msg != NULL);
_ARGCHK(out != NULL);
_ARGCHK(outlen != NULL);
/* get modulus len */
modulus_bytelen = (modulus_bitlen >> 3) + (modulus_bitlen & 7 ? 1 : 0);
if (modulus_bytelen < 12) {
return CRYPT_INVALID_ARG;
}
/* verify length */
if (msglen > (modulus_bytelen - 11) || *outlen < modulus_bytelen) {
return CRYPT_PK_INVALID_SIZE;
}
/* 0x00 0x02 PS 0x00 M */
x = 0;
out[x++] = 0x00;
out[x++] = 0x02;
y = modulus_bytelen - msglen - 3;
if (prng_descriptor[prng_idx].read(out+x, y, prng) != y) {
return CRYPT_ERROR_READPRNG;
}
x += y;
out[x++] = 0x00;
memcpy(out+x, msg, msglen);
*outlen = modulus_bytelen;
return CRYPT_OK;
}
#endif /* PKCS_1 */

77
pkcs_1_v15_sa_decode.c Normal file
View File

@ -0,0 +1,77 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
/* PKCS #1 v1.5 Signature Padding -- Tom St Denis */
#ifdef PKCS_1
int pkcs_1_v15_sa_decode(const unsigned char *msghash, unsigned long msghashlen,
const unsigned char *sig, unsigned long siglen,
int hash_idx, unsigned long modulus_bitlen,
int *res)
{
unsigned long x, y, modulus_bytelen, derlen;
int err;
_ARGCHK(msghash != NULL);
_ARGCHK(sig != NULL);
_ARGCHK(res != NULL);
/* default to invalid */
*res = 0;
/* valid hash ? */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
/* get derlen */
derlen = hash_descriptor[hash_idx].DERlen;
/* get modulus len */
modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
/* valid sizes? */
if ((msghashlen + 3 + derlen > modulus_bytelen) || (siglen != modulus_bytelen)) {
return CRYPT_PK_INVALID_SIZE;
}
/* packet is 0x00 0x01 PS 0x00 T, where PS == 0xFF repeated modulus_bytelen - 3 - derlen - msghashlen times, T == DER || hash */
x = 0;
if (sig[x++] != 0x00 || sig[x++] != 0x01) {
return CRYPT_OK;
}
/* now follows (modulus_bytelen - 3 - derlen - msghashlen) 0xFF bytes */
for (y = 0; y < (modulus_bytelen - 3 - derlen - msghashlen); y++) {
if (sig[x++] != 0xFF) {
return CRYPT_OK;
}
}
if (sig[x++] != 0x00) {
return CRYPT_OK;
}
for (y = 0; y < derlen; y++) {
if (sig[x++] != hash_descriptor[hash_idx].DER[y]) {
return CRYPT_OK;
}
}
if (memcmp(msghash, sig+x, msghashlen) == 0) {
*res = 1;
}
return CRYPT_OK;
}
#endif

71
pkcs_1_v15_sa_encode.c Normal file
View File

@ -0,0 +1,71 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
/* PKCS #1 v1.5 Signature Padding -- Tom St Denis */
#ifdef PKCS_1
int pkcs_1_v15_sa_encode(const unsigned char *msghash, unsigned long msghashlen,
int hash_idx, unsigned long modulus_bitlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long derlen, modulus_bytelen, x, y;
int err;
_ARGCHK(msghash != NULL)
_ARGCHK(out != NULL);
_ARGCHK(outlen != NULL);
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
/* hack, to detect any hash without a DER OID */
if (hash_descriptor[hash_idx].DERlen == 0) {
return CRYPT_INVALID_ARG;
}
/* get modulus len */
modulus_bytelen = (modulus_bitlen>>3) + (modulus_bitlen & 7 ? 1 : 0);
/* get der len ok? Forgive my lame German accent.... */
derlen = hash_descriptor[hash_idx].DERlen;
/* valid sizes? */
if (msghashlen + 3 + derlen > modulus_bytelen) {
return CRYPT_PK_INVALID_SIZE;
}
if (*outlen < modulus_bytelen) {
return CRYPT_BUFFER_OVERFLOW;
}
/* packet is 0x00 0x01 PS 0x00 T, where PS == 0xFF repeated modulus_bytelen - 3 - derlen - msghashlen times, T == DER || hash */
x = 0;
out[x++] = 0x00;
out[x++] = 0x01;
for (y = 0; y < (modulus_bytelen - 3 - derlen - msghashlen); y++) {
out[x++] = 0xFF;
}
out[x++] = 0x00;
for (y = 0; y < derlen; y++) {
out[x++] = hash_descriptor[hash_idx].DER[y];
}
for (y = 0; y < msghashlen; y++) {
out[x++] = msghash[y];
}
*outlen = modulus_bytelen;
return CRYPT_OK;
}
#endif /* PKCS_1 */

View File

@ -54,11 +54,7 @@ int rand_prime(mp_int *N, long len, prng_state *prng, int wprng)
/* New prime generation makes the code even more cryptoish-insane. Do you know what this means!!! /* New prime generation makes the code even more cryptoish-insane. Do you know what this means!!!
-- Gir: Yeah, oh wait, er, no. -- Gir: Yeah, oh wait, er, no.
*/ */
if ((err = mp_prime_random_ex(N, mp_prime_rabin_miller_trials(len), len, type, rand_prime_helper, &rng)) != MP_OKAY) { return mpi_to_ltc_error(mp_prime_random_ex(N, mp_prime_rabin_miller_trials(len), len, type, rand_prime_helper, &rng));
return mpi_to_ltc_error(err);
}
return CRYPT_OK;
} }
#endif #endif

View File

@ -24,6 +24,11 @@ const struct _hash_descriptor rmd128_desc =
8, 8,
16, 16,
64, 64,
/* DER identifier (not supported) */
{ 0x00 },
0,
&rmd128_init, &rmd128_init,
&rmd128_process, &rmd128_process,
&rmd128_done, &rmd128_done,

View File

@ -24,6 +24,12 @@ const struct _hash_descriptor rmd160_desc =
9, 9,
20, 20,
64, 64,
/* DER identifier */
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24,
0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 },
15,
&rmd160_init, &rmd160_init,
&rmd160_process, &rmd160_process,
&rmd160_done, &rmd160_done,

273
rsa.c
View File

@ -1,273 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
/* RSA Code by Tom St Denis */
#include "mycrypt.h"
#ifdef MRSA
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 > MAX_RSA_SIZE/8) {
return CRYPT_PK_INVALID_SIZE;
}
for (y = x = 0; x < inlen; x++)
out[y++] = (unsigned char)0xFF;
for (x = 0; x < inlen; x++)
out[y++] = in[x];
for (x = 0; x < inlen; x++)
out[y++] = (unsigned char)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[3*(MAX_RSA_SIZE/8)];
unsigned long x;
int err;
_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 ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err;
}
/* check inlen */
if (inlen > (MAX_RSA_SIZE/8)) {
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 sandwhich
*
* 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] = out[inlen+inlen+inlen-1] = (unsigned char)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] != (unsigned char)0xFF || in[x+(inlen/3)+(inlen/3)] != (unsigned char)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;
}
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
{
unsigned long y, z;
int err;
_ARGCHK(out != NULL);
_ARGCHK(outlen != NULL);
_ARGCHK(key != NULL);
/* can we store the static header? */
if (*outlen < (PACKET_SIZE + 1)) {
return CRYPT_BUFFER_OVERFLOW;
}
/* 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 */
out[y++] = type;
/* output modulus */
OUTPUT_BIGNUM(&key->N, out, y, z);
/* output public key */
OUTPUT_BIGNUM(&key->e, out, y, z);
if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) {
OUTPUT_BIGNUM(&key->d, out, y, z);
}
if (type == PK_PRIVATE_OPTIMIZED) {
OUTPUT_BIGNUM(&key->dQ, out, y, z);
OUTPUT_BIGNUM(&key->dP, out, y, z);
OUTPUT_BIGNUM(&key->pQ, out, y, z);
OUTPUT_BIGNUM(&key->qP, out, y, z);
OUTPUT_BIGNUM(&key->p, out, y, z);
OUTPUT_BIGNUM(&key->q, out, y, z);
}
/* store packet header */
packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_KEY);
/* copy to the user buffer */
*outlen = y;
/* clear stack and return */
return CRYPT_OK;
}
int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
{
unsigned long x, y;
int err;
_ARGCHK(in != NULL);
_ARGCHK(key != NULL);
/* check length */
if (inlen < (1+PACKET_SIZE)) {
return CRYPT_INVALID_PACKET;
}
/* test packet header */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* init key */
if ((err = 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 mpi_to_ltc_error(err);
}
/* get key type */
y = PACKET_SIZE;
key->type = (int)in[y++];
/* load the modulus */
INPUT_BIGNUM(&key->N, in, x, y, inlen);
/* load public exponent */
INPUT_BIGNUM(&key->e, in, x, y, inlen);
/* get private exponent */
if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) {
INPUT_BIGNUM(&key->d, in, x, y, inlen);
}
/* get CRT private data if required */
if (key->type == PK_PRIVATE_OPTIMIZED) {
INPUT_BIGNUM(&key->dQ, in, x, y, inlen);
INPUT_BIGNUM(&key->dP, in, x, y, inlen);
INPUT_BIGNUM(&key->pQ, in, x, y, inlen);
INPUT_BIGNUM(&key->qP, in, x, y, inlen);
INPUT_BIGNUM(&key->p, in, x, y, inlen);
INPUT_BIGNUM(&key->q, in, x, y, inlen);
}
/* free up ram not required */
if (key->type != PK_PRIVATE_OPTIMIZED) {
mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL);
}
if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
mp_clear(&key->d);
}
return CRYPT_OK;
error:
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
&key->pQ, &key->qP, &key->p, &key->q, NULL);
return err;
}
#include "rsa_sys.c"
#endif /* RSA */

61
rsa_decrypt_key.c Normal file
View File

@ -0,0 +1,61 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef MRSA
/* decrypt then OAEP depad */
int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *outkey, unsigned long *keylen,
const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx,
int hash_idx, int *res,
rsa_key *key)
{
unsigned long modulus_bitlen, modulus_bytelen, x;
int err;
_ARGCHK(outkey != NULL);
_ARGCHK(keylen != NULL);
_ARGCHK(key != NULL);
_ARGCHK(res != NULL);
/* valid hash ? */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
/* get modulus len in bits */
modulus_bitlen = mp_count_bits(&(key->N));
/* outlen must be at least the size of the modulus */
modulus_bytelen = mp_unsigned_bin_size(&(key->N));
if (modulus_bytelen != inlen) {
return CRYPT_INVALID_PACKET;
}
/* rsa decode the packet */
x = *keylen;
if ((err = rsa_exptmod(in, inlen, outkey, &x, PK_PRIVATE, prng, prng_idx, key)) != CRYPT_OK) {
return err;
}
/* now OAEP decode the packet */
return pkcs_1_oaep_decode(outkey, x, lparam, lparamlen, modulus_bitlen, hash_idx,
outkey, keylen, res);
}
#endif /* MRSA */

59
rsa_encrypt_key.c Normal file
View File

@ -0,0 +1,59 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef MRSA
/* OAEP pad then encrypt */
int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
unsigned char *outkey, unsigned long *outlen,
const unsigned char *lparam, unsigned long lparamlen,
prng_state *prng, int prng_idx, int hash_idx, rsa_key *key)
{
unsigned long modulus_bitlen, modulus_bytelen, x;
int err;
_ARGCHK(inkey != NULL);
_ARGCHK(outkey != NULL);
_ARGCHK(outlen != NULL);
_ARGCHK(key != NULL);
/* valid prng and hash ? */
if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
return err;
}
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
/* get modulus len in bits */
modulus_bitlen = mp_count_bits(&(key->N));
/* outlen must be at least the size of the modulus */
modulus_bytelen = mp_unsigned_bin_size(&(key->N));
if (modulus_bytelen > *outlen) {
return CRYPT_BUFFER_OVERFLOW;
}
/* OAEP pad the key */
x = *outlen;
if ((err = pkcs_1_oaep_encode(inkey, inlen, lparam,
lparamlen, modulus_bitlen, prng, prng_idx, hash_idx,
outkey, &x)) != CRYPT_OK) {
return err;
}
/* rsa exptmod the OAEP pad */
return rsa_exptmod(outkey, x, outkey, outlen, PK_PUBLIC, prng, prng_idx, key);
}
#endif /* MRSA */

72
rsa_export.c Normal file
View File

@ -0,0 +1,72 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef MRSA
int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key)
{
unsigned long y, z;
int err;
_ARGCHK(out != NULL);
_ARGCHK(outlen != NULL);
_ARGCHK(key != NULL);
/* can we store the static header? */
if (*outlen < (PACKET_SIZE + 1)) {
return CRYPT_BUFFER_OVERFLOW;
}
/* 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 */
out[y++] = type;
/* output modulus */
OUTPUT_BIGNUM(&key->N, out, y, z);
/* output public key */
OUTPUT_BIGNUM(&key->e, out, y, z);
if (type == PK_PRIVATE || type == PK_PRIVATE_OPTIMIZED) {
OUTPUT_BIGNUM(&key->d, out, y, z);
}
if (type == PK_PRIVATE_OPTIMIZED) {
OUTPUT_BIGNUM(&key->dQ, out, y, z);
OUTPUT_BIGNUM(&key->dP, out, y, z);
OUTPUT_BIGNUM(&key->pQ, out, y, z);
OUTPUT_BIGNUM(&key->qP, out, y, z);
OUTPUT_BIGNUM(&key->p, out, y, z);
OUTPUT_BIGNUM(&key->q, out, y, z);
}
/* store packet header */
packet_store_header(out, PACKET_SECT_RSA, PACKET_SUB_KEY);
/* copy to the user buffer */
*outlen = y;
/* clear stack and return */
return CRYPT_OK;
}
#endif /* MRSA */

View File

@ -14,19 +14,24 @@
#ifdef MRSA #ifdef MRSA
int rsa_exptmod(const unsigned char *in, unsigned long inlen, int rsa_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which, unsigned char *out, unsigned long *outlen, int which,
prng_state *prng, int prng_idx,
rsa_key *key) rsa_key *key)
{ {
mp_int tmp, tmpa, tmpb; mp_int tmp, tmpa, tmpb;
unsigned long x; unsigned long x;
int err; int err;
_ARGCHK(in != NULL); _ARGCHK(in != NULL);
_ARGCHK(out != NULL); _ARGCHK(out != NULL);
_ARGCHK(outlen != NULL); _ARGCHK(outlen != NULL);
_ARGCHK(key != NULL); _ARGCHK(key != NULL);
if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
return err;
}
if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) { if (which == PK_PRIVATE && (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED)) {
return CRYPT_PK_NOT_PRIVATE; return CRYPT_PK_NOT_PRIVATE;
} }
@ -49,10 +54,10 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
/* are we using the private exponent and is the key optimized? */ /* are we using the private exponent and is the key optimized? */
if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) { if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) {
/* tmpa = tmp^dP mod p */ /* tmpa = tmp^dP mod p */
if ((err = mp_exptmod(&tmp, &key->dP, &key->p, &tmpa)) != MP_OKAY) { goto error; } if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e, &key->dP, &key->p, &tmpa)) != MP_OKAY) { goto error; }
/* tmpb = tmp^dQ mod q */ /* tmpb = tmp^dQ mod q */
if ((err = mp_exptmod(&tmp, &key->dQ, &key->q, &tmpb)) != MP_OKAY) { goto error; } if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e, &key->dQ, &key->q, &tmpb)) != MP_OKAY) { goto error; }
/* tmp = tmpa*qP + tmpb*pQ mod N */ /* tmp = tmpa*qP + tmpb*pQ mod N */
if ((err = mp_mul(&tmpa, &key->qP, &tmpa)) != MP_OKAY) { goto error; } if ((err = mp_mul(&tmpa, &key->qP, &tmpa)) != MP_OKAY) { goto error; }
@ -60,11 +65,15 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
if ((err = mp_addmod(&tmpa, &tmpb, &key->N, &tmp)) != MP_OKAY) { goto error; } if ((err = mp_addmod(&tmpa, &tmpb, &key->N, &tmp)) != MP_OKAY) { goto error; }
} else { } else {
/* exptmod it */ /* exptmod it */
if ((err = mp_exptmod(&tmp, which==PK_PRIVATE?&key->d:&key->e, &key->N, &tmp)) != MP_OKAY) { goto error; } if (which == PK_PRIVATE) {
if ((err = tim_exptmod(prng, prng_idx, &tmp, &key->e, &key->d, &key->N, &tmp)) != MP_OKAY) { goto error; }
} else {
if ((err = mp_exptmod(&tmp, &key->e, &key->N, &tmp)) != MP_OKAY) { goto error; }
}
} }
/* read it back */ /* read it back */
x = (unsigned long)mp_unsigned_bin_size(&tmp); x = (unsigned long)mp_unsigned_bin_size(&key->N);
if (x > *outlen) { if (x > *outlen) {
err = CRYPT_BUFFER_OVERFLOW; err = CRYPT_BUFFER_OVERFLOW;
goto done; goto done;
@ -72,7 +81,8 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
*outlen = x; *outlen = x;
/* convert it */ /* convert it */
if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY) { goto error; } zeromem(out, x);
if ((err = mp_to_unsigned_bin(&tmp, out+(x-mp_unsigned_bin_size(&tmp)))) != MP_OKAY) { goto error; }
/* clean up and return */ /* clean up and return */
err = CRYPT_OK; err = CRYPT_OK;

81
rsa_import.c Normal file
View File

@ -0,0 +1,81 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef MRSA
int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
{
unsigned long x, y;
int err;
_ARGCHK(in != NULL);
_ARGCHK(key != NULL);
/* check length */
if (inlen < (1+PACKET_SIZE)) {
return CRYPT_INVALID_PACKET;
}
/* test packet header */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_KEY)) != CRYPT_OK) {
return err;
}
/* init key */
if ((err = 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 mpi_to_ltc_error(err);
}
/* get key type */
y = PACKET_SIZE;
key->type = (int)in[y++];
/* load the modulus */
INPUT_BIGNUM(&key->N, in, x, y, inlen);
/* load public exponent */
INPUT_BIGNUM(&key->e, in, x, y, inlen);
/* get private exponent */
if (key->type == PK_PRIVATE || key->type == PK_PRIVATE_OPTIMIZED) {
INPUT_BIGNUM(&key->d, in, x, y, inlen);
}
/* get CRT private data if required */
if (key->type == PK_PRIVATE_OPTIMIZED) {
INPUT_BIGNUM(&key->dQ, in, x, y, inlen);
INPUT_BIGNUM(&key->dP, in, x, y, inlen);
INPUT_BIGNUM(&key->pQ, in, x, y, inlen);
INPUT_BIGNUM(&key->qP, in, x, y, inlen);
INPUT_BIGNUM(&key->p, in, x, y, inlen);
INPUT_BIGNUM(&key->q, in, x, y, inlen);
}
/* free up ram not required */
if (key->type != PK_PRIVATE_OPTIMIZED) {
mp_clear_multi(&key->dQ, &key->dP, &key->pQ, &key->qP, &key->p, &key->q, NULL);
}
if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
mp_clear(&key->d);
}
return CRYPT_OK;
error:
mp_clear_multi(&key->d, &key->e, &key->N, &key->dQ, &key->dP,
&key->pQ, &key->qP, &key->p, &key->q, NULL);
return err;
}
#endif /* MRSA */

View File

@ -17,7 +17,7 @@
int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key) int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
{ {
mp_int p, q, tmp1, tmp2, tmp3; mp_int p, q, tmp1, tmp2, tmp3;
int err; int err;
_ARGCHK(key != NULL); _ARGCHK(key != NULL);

59
rsa_sign_hash.c Normal file
View File

@ -0,0 +1,59 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef MRSA
/* PSS pad then sign */
int rsa_sign_hash(const unsigned char *msghash, unsigned long msghashlen,
unsigned char *sig, unsigned long *siglen,
prng_state *prng, int prng_idx,
int hash_idx, unsigned long saltlen,
rsa_key *key)
{
unsigned long modulus_bitlen, modulus_bytelen, x;
int err;
_ARGCHK(msghash != NULL);
_ARGCHK(sig != NULL);
_ARGCHK(siglen != NULL);
_ARGCHK(key != NULL);
/* valid prng and hash ? */
if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
return err;
}
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
/* get modulus len in bits */
modulus_bitlen = mp_count_bits(&(key->N));
/* outlen must be at least the size of the modulus */
modulus_bytelen = mp_unsigned_bin_size(&(key->N));
if (modulus_bytelen > *siglen) {
return CRYPT_BUFFER_OVERFLOW;
}
/* PSS pad the key */
x = *siglen;
if ((err = pkcs_1_pss_encode(msghash, msghashlen, saltlen, prng, prng_idx,
hash_idx, modulus_bitlen, sig, &x)) != CRYPT_OK) {
return err;
}
/* RSA encode it */
return rsa_exptmod(sig, x, sig, siglen, PK_PRIVATE, prng, prng_idx, key);
}
#endif /* MRSA */

274
rsa_sys.c
View File

@ -1,274 +0,0 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
/* 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[RSA_STACK], rsa_out[RSA_STACK];
unsigned long x, y, rsa_size;
int err;
_ARGCHK(inkey != NULL);
_ARGCHK(outkey != NULL);
_ARGCHK(outlen != NULL);
_ARGCHK(key != NULL);
/* only allow keys from 64 to 256 bits */
if (inlen < 8 || inlen > 32) {
return CRYPT_INVALID_ARG;
}
/* are the parameters valid? */
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err;
}
/* rsa_pad the symmetric key */
y = (unsigned long)sizeof(rsa_in);
if ((err = rsa_pad(inkey, inlen, rsa_in, &y, wprng, prng)) != CRYPT_OK) {
return CRYPT_ERROR;
}
/* rsa encrypt it */
rsa_size = (unsigned long)sizeof(rsa_out);
if ((err = 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;
}
/* store header */
packet_store_header(outkey, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY);
/* 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];
}
*outlen = y;
#ifdef CLEAN_STACK
/* clean up */
zeromem(rsa_in, sizeof(rsa_in));
zeromem(rsa_out, sizeof(rsa_out));
#endif
return CRYPT_OK;
}
int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *outkey, unsigned long *keylen,
rsa_key *key)
{
unsigned char sym_key[MAXBLOCKSIZE], rsa_out[RSA_STACK];
unsigned long x, y, z, i, rsa_size;
int err;
_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;
}
if (inlen < PACKET_SIZE+4) {
return CRYPT_INVALID_PACKET;
} else {
inlen -= PACKET_SIZE+4;
}
/* check the header */
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_RSA, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
return err;
}
/* grab length of the rsa key */
y = PACKET_SIZE;
LOAD32L(rsa_size, (in+y));
if (inlen < rsa_size) {
return CRYPT_INVALID_PACKET;
} else {
inlen -= rsa_size;
}
y += 4;
/* decrypt it */
x = (unsigned long)sizeof(rsa_out);
if ((err = rsa_exptmod(in+y, rsa_size, rsa_out, &x, PK_PRIVATE, key)) != CRYPT_OK) {
return err;
}
y += rsa_size;
/* depad it */
z = (unsigned long)sizeof(sym_key);
if ((err = rsa_depad(rsa_out, x, sym_key, &z)) != CRYPT_OK) {
return err;
}
/* 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_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[RSA_STACK], rsa_out[RSA_STACK];
int err;
_ARGCHK(in != NULL);
_ARGCHK(out != NULL);
_ARGCHK(outlen != NULL);
_ARGCHK(key != NULL);
/* reject nonsense sizes */
if (inlen > (512/3) || inlen < 16) {
return CRYPT_INVALID_ARG;
}
/* type of key? */
if (key->type != PK_PRIVATE && key->type != PK_PRIVATE_OPTIMIZED) {
return CRYPT_PK_NOT_PRIVATE;
}
/* pad it */
x = (unsigned long)sizeof(rsa_out);
if ((err = rsa_signpad(in, inlen, rsa_out, &x)) != CRYPT_OK) {
return err;
}
/* sign it */
rsa_size = (unsigned long)sizeof(rsa_in);
if ((err = rsa_exptmod(rsa_out, x, rsa_in, &rsa_size, PK_PRIVATE, key)) != CRYPT_OK) {
return err;
}
/* 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);
#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, unsigned long siglen,
const unsigned char *md, int *stat, rsa_key *key)
{
unsigned long rsa_size, x, y, z;
unsigned char rsa_in[RSA_STACK], rsa_out[RSA_STACK];
int err;
_ARGCHK(sig != NULL);
_ARGCHK(md != NULL);
_ARGCHK(stat != NULL);
_ARGCHK(key != NULL);
/* always be incorrect by default */
*stat = 0;
if (siglen < PACKET_SIZE+4) {
return CRYPT_INVALID_PACKET;
} else {
siglen -= PACKET_SIZE+4;
}
/* verify header */
if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_RSA, PACKET_SUB_SIGNED)) != CRYPT_OK) {
return err;
}
/* get the len */
y = PACKET_SIZE;
LOAD32L(rsa_size, (sig+y));
if (siglen < rsa_size) {
return CRYPT_INVALID_PACKET;
} else {
siglen -= rsa_size;
}
y += 4;
/* exptmod it */
x = (unsigned long)sizeof(rsa_out);
if ((err = rsa_exptmod(sig+y, rsa_size, rsa_out, &x, PK_PUBLIC, key)) != CRYPT_OK) {
return err;
}
y += rsa_size;
/* depad it */
z = (unsigned long)sizeof(rsa_in);
if ((err = rsa_signdepad(rsa_out, x, rsa_in, &z)) != CRYPT_OK) {
return err;
}
/* check? */
if (memcmp(rsa_in, md, (size_t)z) == 0) {
*stat = 1;
}
#ifdef CLEAN_STACK
zeromem(rsa_in, sizeof(rsa_in));
zeromem(rsa_out, sizeof(rsa_out));
#endif
return CRYPT_OK;
}

69
rsa_verify_hash.c Normal file
View File

@ -0,0 +1,69 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
#include "mycrypt.h"
#ifdef MRSA
/* design then PSS depad */
int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *msghash, unsigned long msghashlen,
prng_state *prng, int prng_idx,
int hash_idx, unsigned long saltlen,
int *stat, rsa_key *key)
{
unsigned long modulus_bitlen, modulus_bytelen, x;
int err;
unsigned char *tmpbuf;
_ARGCHK(msghash != NULL);
_ARGCHK(sig != NULL);
_ARGCHK(stat != NULL);
_ARGCHK(key != NULL);
/* valid hash ? */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
return err;
}
/* get modulus len in bits */
modulus_bitlen = mp_count_bits(&(key->N));
/* outlen must be at least the size of the modulus */
modulus_bytelen = mp_unsigned_bin_size(&(key->N));
if (modulus_bytelen != siglen) {
return CRYPT_INVALID_PACKET;
}
/* allocate temp buffer for decoded sig */
tmpbuf = XCALLOC(1, modulus_bytelen + 1);
if (tmpbuf == NULL) {
return CRYPT_MEM;
}
/* RSA decode it */
x = siglen;
if ((err = rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, prng, prng_idx, key)) != CRYPT_OK) {
XFREE(tmpbuf);
return err;
}
/* PSS decode it */
err = pkcs_1_pss_decode(msghash, msghashlen, tmpbuf, x, saltlen, hash_idx, modulus_bitlen, stat);
XFREE(tmpbuf);
return err;
}
#endif /* MRSA */

30
sha1.c
View File

@ -20,6 +20,12 @@ const struct _hash_descriptor sha1_desc =
2, 2,
20, 20,
64, 64,
/* DER identifier */
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E,
0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 },
15,
&sha1_init, &sha1_init,
&sha1_process, &sha1_process,
&sha1_done, &sha1_done,
@ -38,6 +44,9 @@ static void sha1_compress(hash_state *md, unsigned char *buf)
#endif #endif
{ {
ulong32 a,b,c,d,e,W[80],i; ulong32 a,b,c,d,e,W[80],i;
#ifdef SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */ /* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++) {
@ -63,6 +72,26 @@ static void sha1_compress(hash_state *md, unsigned char *buf)
#define FF2(a,b,c,d,e,i) e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30); #define FF2(a,b,c,d,e,i) e = (ROL(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROL(b, 30);
#define FF3(a,b,c,d,e,i) e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30); #define FF3(a,b,c,d,e,i) e = (ROL(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROL(b, 30);
#ifdef SMALL_CODE
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 40; ) {
FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 60; ) {
FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 80; ) {
FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
#else
for (i = 0; i < 20; ) { for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++); FF0(a,b,c,d,e,i++);
FF0(e,a,b,c,d,i++); FF0(e,a,b,c,d,i++);
@ -97,6 +126,7 @@ static void sha1_compress(hash_state *md, unsigned char *buf)
FF3(c,d,e,a,b,i++); FF3(c,d,e,a,b,i++);
FF3(b,c,d,e,a,i++); FF3(b,c,d,e,a,i++);
} }
#endif
#undef FF0 #undef FF0
#undef FF1 #undef FF1

View File

@ -16,6 +16,11 @@ const struct _hash_descriptor sha224_desc =
10, 10,
28, 28,
64, 64,
/* DER identifier (not supported) */
{ 0x00 },
0,
&sha224_init, &sha224_init,
&sha256_process, &sha256_process,
&sha224_done, &sha224_done,

View File

@ -22,12 +22,20 @@ const struct _hash_descriptor sha256_desc =
0, 0,
32, 32,
64, 64,
/* DER identifier */
{ 0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05,
0x00, 0x04, 0x20 },
19,
&sha256_init, &sha256_init,
&sha256_process, &sha256_process,
&sha256_done, &sha256_done,
&sha256_test &sha256_test
}; };
#ifdef SMALL_CODE
/* the K array */ /* the K array */
static const unsigned long K[64] = { static const unsigned long K[64] = {
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
@ -44,6 +52,7 @@ static const unsigned long K[64] = {
0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
}; };
#endif
/* Various logical functions */ /* Various logical functions */
#define Ch(x,y,z) (z ^ (x & (y ^ z))) #define Ch(x,y,z) (z ^ (x & (y ^ z)))
@ -63,6 +72,9 @@ static void sha256_compress(hash_state * md, unsigned char *buf)
#endif #endif
{ {
ulong32 S[8], W[64], t0, t1; ulong32 S[8], W[64], t0, t1;
#ifdef SMALL_CODE
ulong32 t;
#endif
int i; int i;
/* copy state into S */ /* copy state into S */
@ -82,22 +94,17 @@ static void sha256_compress(hash_state * md, unsigned char *buf)
/* Compress */ /* Compress */
#ifdef SMALL_CODE #ifdef SMALL_CODE
#define RND(a,b,c,d,e,f,g,h,i) \ #define RND(a,b,c,d,e,f,g,h,i) \
t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \ t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
t1 = Sigma0(a) + Maj(a, b, c); \ t1 = Sigma0(a) + Maj(a, b, c); \
d += t0; \ d += t0; \
h = t0 + t1; h = t0 + t1;
for (i = 0; i < 64; i += 8) { for (i = 0; i < 64; ++i) {
RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i+0); RND(S[0],S[1],S[2],S[3],S[4],S[5],S[6],S[7],i);
RND(S[7],S[0],S[1],S[2],S[3],S[4],S[5],S[6],i+1); t = S[7]; S[7] = S[6]; S[6] = S[5]; S[5] = S[4];
RND(S[6],S[7],S[0],S[1],S[2],S[3],S[4],S[5],i+2); S[4] = S[3]; S[3] = S[2]; S[2] = S[1]; S[1] = S[0]; S[0] = t;
RND(S[5],S[6],S[7],S[0],S[1],S[2],S[3],S[4],i+3); }
RND(S[4],S[5],S[6],S[7],S[0],S[1],S[2],S[3],i+4);
RND(S[3],S[4],S[5],S[6],S[7],S[0],S[1],S[2],i+5);
RND(S[2],S[3],S[4],S[5],S[6],S[7],S[0],S[1],i+6);
RND(S[1],S[2],S[3],S[4],S[5],S[6],S[7],S[0],i+7);
}
#else #else
#define RND(a,b,c,d,e,f,g,h,i,ki) \ #define RND(a,b,c,d,e,f,g,h,i,ki) \
t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \ t0 = h + Sigma1(e) + Ch(e, f, g) + ki + W[i]; \

View File

@ -17,6 +17,13 @@ const struct _hash_descriptor sha384_desc =
4, 4,
48, 48,
128, 128,
/* DER identifier */
{ 0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05,
0x00, 0x04, 0x30 },
19,
&sha384_init, &sha384_init,
&sha512_process, &sha512_process,
&sha384_done, &sha384_done,

View File

@ -21,6 +21,13 @@ const struct _hash_descriptor sha512_desc =
5, 5,
64, 64,
128, 128,
/* DER identifier */
{ 0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86,
0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05,
0x00, 0x04, 0x40 },
19,
&sha512_init, &sha512_init,
&sha512_process, &sha512_process,
&sha512_done, &sha512_done,

View File

@ -19,6 +19,13 @@ const struct _hash_descriptor tiger_desc =
1, 1,
24, 24,
64, 64,
/* DER identifier */
{ 0x30, 0x29, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06,
0x01, 0x04, 0x01, 0xDA, 0x47, 0x0C, 0x02, 0x05,
0x00, 0x04, 0x18 },
19,
&tiger_init, &tiger_init,
&tiger_process, &tiger_process,
&tiger_done, &tiger_done,

77
tim_exptmod.c Normal file
View File

@ -0,0 +1,77 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
/* RSA Code by Tom St Denis */
#include "mycrypt.h"
#ifdef RSA_TIMING
/* decrypts c into m */
int tim_exptmod(prng_state *prng, int prng_idx,
mp_int *c, mp_int *e, mp_int *d, mp_int *n, mp_int *m)
{
int err;
mp_int r, tmp, tmp2;
unsigned char *rtmp;
unsigned long rlen;
_ARGCHK(c != NULL);
_ARGCHK(e != NULL);
_ARGCHK(d != NULL);
_ARGCHK(n != NULL);
_ARGCHK(m != NULL);
if ((err = prng_is_valid(prng_idx)) != CRYPT_OK) {
return err;
}
/* pick random r */
rtmp = XMALLOC(MAX_RSA_SIZE/8);
if (rtmp == NULL) {
return CRYPT_MEM;
}
rlen = mp_unsigned_bin_size(n);
if (prng_descriptor[prng_idx].read(rtmp, rlen, prng) != rlen) {
XFREE(rtmp);
return CRYPT_ERROR_READPRNG;
}
if ((err = mp_init_multi(&r, &tmp, &tmp2, NULL)) != MP_OKAY) {
XFREE(rtmp);
return mpi_to_ltc_error(err);
}
/* read in r */
if ((err = mp_read_unsigned_bin(&r, rtmp, rlen)) != MP_OKAY) { goto __ERR; }
/* compute tmp = r^e */
if ((err = mp_exptmod(&r, e, n, &tmp)) != MP_OKAY) { goto __ERR; }
/* multiply C into the mix */
if ((err = mp_mulmod(c, &tmp, n, &tmp)) != MP_OKAY) { goto __ERR; }
/* raise to d */
if ((err = mp_exptmod(&tmp, d, n, &tmp)) != MP_OKAY) { goto __ERR; }
/* invert r and multiply */
if ((err = mp_invmod(&r, n, &tmp2)) != MP_OKAY) { goto __ERR; }
/* multiply and we are totally set */
if ((err = mp_mulmod(&tmp, &tmp2, n, m)) != MP_OKAY) { goto __ERR; }
__ERR: mp_clear_multi(&r, &tmp, &tmp2, NULL);
XFREE(rtmp);
return mpi_to_ltc_error(err);
}
#endif

View File

@ -21,6 +21,11 @@ const struct _hash_descriptor whirlpool_desc =
11, 11,
64, 64,
64, 64,
/* DER encoding (not yet supported) */
{ 0x00 },
0,
&whirlpool_init, &whirlpool_init,
&whirlpool_process, &whirlpool_process,
&whirlpool_done, &whirlpool_done,
@ -34,7 +39,7 @@ const struct _hash_descriptor whirlpool_desc =
#define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255) #define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255)
/* shortcut macro to perform three functions at once */ /* shortcut macro to perform three functions at once */
#define theta_pi_gamma(a, i) \ #define theta_pi_gamma(a, i) \
SB0(GB(a, i-0, 7)) ^ \ SB0(GB(a, i-0, 7)) ^ \
SB1(GB(a, i-1, 6)) ^ \ SB1(GB(a, i-1, 6)) ^ \
SB2(GB(a, i-2, 5)) ^ \ SB2(GB(a, i-2, 5)) ^ \

View File

@ -30,7 +30,15 @@ int yarrow_start(prng_state *prng)
/* these are the default hash/cipher combo used */ /* these are the default hash/cipher combo used */
#ifdef RIJNDAEL #ifdef RIJNDAEL
#if YARROW_AES==0
prng->yarrow.cipher = register_cipher(&rijndael_enc_desc);
#elif YARROW_AES==1
prng->yarrow.cipher = register_cipher(&aes_enc_desc);
#elif YARROW_AES==2
prng->yarrow.cipher = register_cipher(&rijndael_desc); prng->yarrow.cipher = register_cipher(&rijndael_desc);
#elif YARROW_AES==3
prng->yarrow.cipher = register_cipher(&aes_desc);
#endif
#elif defined(BLOWFISH) #elif defined(BLOWFISH)
prng->yarrow.cipher = register_cipher(&blowfish_desc); prng->yarrow.cipher = register_cipher(&blowfish_desc);
#elif defined(TWOFISH) #elif defined(TWOFISH)
@ -78,6 +86,8 @@ int yarrow_start(prng_state *prng)
prng->yarrow.hash = register_hash(&md4_desc); prng->yarrow.hash = register_hash(&md4_desc);
#elif defined(MD2) #elif defined(MD2)
prng->yarrow.hash = register_hash(&md2_desc); prng->yarrow.hash = register_hash(&md2_desc);
#elif defined(WHIRLPOOL)
prng->yarrow.hash = register_hash(&whirlpool_desc);
#else #else
#error YARROW needs at least one HASH #error YARROW needs at least one HASH
#endif #endif
@ -107,13 +117,20 @@ int yarrow_add_entropy(const unsigned char *buf, unsigned long len, prng_state *
hash_descriptor[prng->yarrow.hash].init(&md); hash_descriptor[prng->yarrow.hash].init(&md);
/* hash the current pool */ /* hash the current pool */
hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool, hash_descriptor[prng->yarrow.hash].hashsize); if ((err = hash_descriptor[prng->yarrow.hash].process(&md, prng->yarrow.pool,
hash_descriptor[prng->yarrow.hash].hashsize)) != CRYPT_OK) {
return err;
}
/* add the new entropy */ /* add the new entropy */
hash_descriptor[prng->yarrow.hash].process(&md, buf, len); if ((err = hash_descriptor[prng->yarrow.hash].process(&md, buf, len)) != CRYPT_OK) {
return err;
}
/* store result */ /* store result */
hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool); if ((err = hash_descriptor[prng->yarrow.hash].done(&md, prng->yarrow.pool)) != CRYPT_OK) {
return err;
}
return CRYPT_OK; return CRYPT_OK;
} }