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???

287
aes.c
View File

@ -30,16 +30,20 @@
#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 =
{
"rijndael",
6,
16, 32, 16, 10,
&rijndael_setup,
&rijndael_ecb_encrypt,
&rijndael_ecb_decrypt,
&rijndael_test,
&rijndael_keysize
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_KS
};
const struct _cipher_descriptor aes_desc =
@ -47,21 +51,63 @@ const struct _cipher_descriptor aes_desc =
"aes",
6,
16, 32, 16, 10,
&rijndael_setup,
&rijndael_ecb_encrypt,
&rijndael_ecb_decrypt,
&rijndael_test,
&rijndael_keysize
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_KS
};
#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"
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;
ulong32 temp, *rk, *rrk;
_ARGCHK(key != NULL);
ulong32 temp, *rk;
#ifndef ENCRYPT_ONLY
ulong32 *rrk;
#endif
_ARGCHK(key != NULL);
_ARGCHK(skey != NULL);
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;
for (;;) {
temp = rk[3];
rk[4] = rk[0] ^
(Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]) ^
rcon[i];
rk[4] = rk[0] ^ setup_mix(temp) ^ rcon[i];
rk[5] = rk[1] ^ rk[4];
rk[6] = rk[2] ^ rk[5];
rk[7] = rk[3] ^ rk[6];
@ -109,12 +150,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
#else
temp = rk[5];
#endif
rk[ 6] = rk[ 0] ^
(Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]) ^
rcon[i];
rk[ 6] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
rk[ 7] = rk[ 1] ^ rk[ 6];
rk[ 8] = rk[ 2] ^ rk[ 7];
rk[ 9] = rk[ 3] ^ rk[ 8];
@ -137,12 +173,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
#else
temp = rk[7];
#endif
rk[ 8] = rk[ 0] ^
(Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]) ^
rcon[i];
rk[ 8] = rk[ 0] ^ setup_mix(temp) ^ rcon[i];
rk[ 9] = rk[ 1] ^ rk[ 8];
rk[10] = rk[ 2] ^ rk[ 9];
rk[11] = rk[ 3] ^ rk[10];
@ -150,11 +181,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
break;
}
temp = rk[11];
rk[12] = rk[ 4] ^
(Te4_3[byte(temp, 3)]) ^
(Te4_2[byte(temp, 2)]) ^
(Te4_1[byte(temp, 1)]) ^
(Te4_0[byte(temp, 0)]);
rk[12] = rk[ 4] ^ setup_mix(ROR(temp, 8));
rk[13] = rk[ 5] ^ rk[12];
rk[14] = rk[ 6] ^ rk[13];
rk[15] = rk[ 7] ^ rk[14];
@ -164,7 +191,8 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
/* this can't happen */
j = 4;
}
#ifndef ENCRYPT_ONLY
/* setup the inverse key now */
rk = skey->rijndael.dK;
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;
#ifdef SMALL_CODE
temp = rrk[0];
rk[0] =
Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
rk[0] = setup_mix2(temp);
temp = rrk[1];
rk[1] =
Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
rk[1] = setup_mix2(temp);
temp = rrk[2];
rk[2] =
Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
rk[2] = setup_mix2(temp);
temp = rrk[3];
rk[3] =
Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
rk[3] = setup_mix2(temp);
#else
temp = rrk[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;
#endif /* ENCRYPT_ONLY */
return CRYPT_OK;
}
@ -248,7 +261,7 @@ int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_k
#ifdef CLEAN_STACK
static void _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#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
{
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(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:
*/
@ -330,52 +381,57 @@ void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_
Te3(byte(t2, 0)) ^
rk[3];
}
#endif
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Te4_3[(t0 >> 24) ]) ^
(Te4_2[(t1 >> 16) & 0xff]) ^
(Te4_1[(t2 >> 8) & 0xff]) ^
(Te4_0[(t3 ) & 0xff]) ^
(Te4_3[byte(t0, 3)]) ^
(Te4_2[byte(t1, 2)]) ^
(Te4_1[byte(t2, 1)]) ^
(Te4_0[byte(t3, 0)]) ^
rk[0];
STORE32H(s0, ct);
s1 =
(Te4_3[(t1 >> 24) ]) ^
(Te4_2[(t2 >> 16) & 0xff]) ^
(Te4_1[(t3 >> 8) & 0xff]) ^
(Te4_0[(t0 ) & 0xff]) ^
(Te4_3[byte(t1, 3)]) ^
(Te4_2[byte(t2, 2)]) ^
(Te4_1[byte(t3, 1)]) ^
(Te4_0[byte(t0, 0)]) ^
rk[1];
STORE32H(s1, ct+4);
s2 =
(Te4_3[(t2 >> 24) ]) ^
(Te4_2[(t3 >> 16) & 0xff]) ^
(Te4_1[(t0 >> 8) & 0xff]) ^
(Te4_0[(t1 ) & 0xff]) ^
(Te4_3[byte(t2, 3)]) ^
(Te4_2[byte(t3, 2)]) ^
(Te4_1[byte(t0, 1)]) ^
(Te4_0[byte(t1, 0)]) ^
rk[2];
STORE32H(s2, ct+8);
s3 =
(Te4_3[(t3 >> 24) ]) ^
(Te4_2[(t0 >> 16) & 0xff]) ^
(Te4_1[(t1 >> 8) & 0xff]) ^
(Te4_0[(t2 ) & 0xff]) ^
(Te4_3[byte(t3, 3)]) ^
(Te4_2[byte(t0, 2)]) ^
(Te4_1[byte(t1, 1)]) ^
(Te4_0[byte(t2, 0)]) ^
rk[3];
STORE32H(s3, ct+12);
}
#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);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
}
#endif
#ifndef ENCRYPT_ONLY
#ifdef CLEAN_STACK
static void _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#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
{
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(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:
*/
@ -459,51 +551,52 @@ void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_
Td3(byte(t0, 0)) ^
rk[3];
}
#endif
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Td4[(t0 >> 24) ] & 0xff000000) ^
(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t1 ) & 0xff] & 0x000000ff) ^
(Td4[byte(t0, 3)] & 0xff000000) ^
(Td4[byte(t3, 2)] & 0x00ff0000) ^
(Td4[byte(t2, 1)] & 0x0000ff00) ^
(Td4[byte(t1, 0)] & 0x000000ff) ^
rk[0];
STORE32H(s0, pt);
s1 =
(Td4[(t1 >> 24) ] & 0xff000000) ^
(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t2 ) & 0xff] & 0x000000ff) ^
(Td4[byte(t1, 3)] & 0xff000000) ^
(Td4[byte(t0, 2)] & 0x00ff0000) ^
(Td4[byte(t3, 1)] & 0x0000ff00) ^
(Td4[byte(t2, 0)] & 0x000000ff) ^
rk[1];
STORE32H(s1, pt+4);
s2 =
(Td4[(t2 >> 24) ] & 0xff000000) ^
(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t3 ) & 0xff] & 0x000000ff) ^
(Td4[byte(t2, 3)] & 0xff000000) ^
(Td4[byte(t1, 2)] & 0x00ff0000) ^
(Td4[byte(t0, 1)] & 0x0000ff00) ^
(Td4[byte(t3, 0)] & 0x000000ff) ^
rk[2];
STORE32H(s2, pt+8);
s3 =
(Td4[(t3 >> 24) ] & 0xff000000) ^
(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
(Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
(Td4[(t0 ) & 0xff] & 0x000000ff) ^
(Td4[byte(t3, 3)] & 0xff000000) ^
(Td4[byte(t2, 2)] & 0x00ff0000) ^
(Td4[byte(t1, 1)] & 0x0000ff00) ^
(Td4[byte(t0, 0)] & 0x000000ff) ^
rk[3];
STORE32H(s3, pt+12);
}
#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);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
}
#endif
int rijndael_test(void)
int ECB_TEST(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
@ -584,7 +677,9 @@ int rijndael_test(void)
#endif
}
int rijndael_keysize(int *desired_keysize)
#endif /* ENCRYPT_ONLY */
int ECB_KS(int *desired_keysize)
{
_ARGCHK(desired_keysize != NULL);

View File

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

View File

@ -8,14 +8,12 @@
*
* 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+/";
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,
@ -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 };
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,
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) {
return err;
}
cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
_ARGCHK(cipher_descriptor[cbc->cipher].ecb_decrypt != NULL);
/* is blocklen valid? */
if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) {
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++) {
/* copy CT in case ct == pt */
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
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

24
crypt.c
View File

@ -120,6 +120,9 @@ const char *crypt_build_settings =
#if defined(RIPEMD160)
" RIPEMD160\n"
#endif
#if defined(WHIRLPOOL)
" WHIRLPOOL\n"
#endif
"\nBlock Chaining Modes:\n"
#if defined(CFB)
@ -151,7 +154,11 @@ const char *crypt_build_settings =
"\nPK Algs:\n"
#if defined(MRSA)
" RSA\n"
" RSA"
#if defined(RSA_TIMING)
" + RSA_TIMING "
#endif
"\n"
#endif
#if defined(MDH)
" DH\n"
@ -162,9 +169,6 @@ const char *crypt_build_settings =
#if defined(MDSA)
" DSA\n"
#endif
#if defined(KR)
" KR\n"
#endif
"\nCompiler:\n"
#if defined(WIN32)
@ -187,9 +191,6 @@ const char *crypt_build_settings =
#endif
"\nVarious others: "
#if defined(GF)
" GF "
#endif
#if defined(BASE64)
" BASE64 "
#endif
@ -222,6 +223,15 @@ const char *crypt_build_settings =
#endif
#if defined(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
"\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"
struct _hash_descriptor hash_descriptor[TAB_SIZE] = {
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL, NULL, NULL } };
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 0, NULL, NULL, NULL, NULL },
{ NULL, 0, 0, 0, { 0x00 }, 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)
{
register_cipher(&rijndael_desc);
register_cipher(&rijndael_enc_desc);
register_prng(&yarrow_desc);
register_hash(&sha256_desc);
return 0;

View File

@ -1202,69 +1202,6 @@ ecc_tests (void)
}
#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
void
test_prime (void)
@ -1390,299 +1327,6 @@ register_all_algs (void)
#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
test_errs (void)
{
@ -1840,13 +1484,13 @@ void pkcs1_test(void)
/* decode it */
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));
exit(-1);
}
if (l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
printf("Outsize == %lu, should have been %lu, msg contents follow.\n", l2, l3);
if (res1 != 1 || l2 != l3 || memcmp(buf[2], buf[0], l3) != 0) {
printf("res == %d, Outsize == %lu, should have been %lu, msg contents follow.\n", res1, l2, l3);
printf("ORIGINAL:\n");
for (x = 0; x < l3; x++) {
printf("%02x ", buf[0][x]);
@ -1959,16 +1603,12 @@ main (void)
rng_tests ();
test_prime();
#ifdef KR
kr_test ();
#endif
dsa_tests();
rsa_test ();
pad_test ();
ecc_tests ();
dh_tests ();
gf_tests ();
base64_test ();
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(ecb != NULL);
/* valid cipher? */
if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
return err;
}
_ARGCHK(cipher_descriptor[ecb->cipher].ecb_decrypt != NULL);
cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key);
return CRYPT_OK;
}

View File

@ -9,7 +9,6 @@
* Tom St Denis, tomstdenis@iahu.ca, http://libtomcrypt.org
*/
/* Future releases will make use of this */
#include "mycrypt.h"
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)
{
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

102
makefile
View File

@ -9,9 +9,8 @@
# a build. This is easy to remedy though, for those that have problems.
# The version
VERSION=0.95
VERSION=0.96
#ch1-01-1
# Compiler and Linker Names
#CC=gcc
#LD=ld
@ -19,9 +18,7 @@ VERSION=0.95
# Archiver [makes .a files]
#AR=ar
#ARFLAGS=r
#ch1-01-1
#ch1-01-3
# Compilation flags. Note the += does not write over the user's CFLAGS!
CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wshadow
# -Werror
@ -29,8 +26,8 @@ CFLAGS += -c -I./ -Wall -Wsign-compare -W -Wshadow
# optimize for SPEED
#CFLAGS += -O3 -funroll-loops
#add -fomit-frame-pointer. v3.2 is buggy for certain platforms!
#CFLAGS += -fomit-frame-pointer
#add -fomit-frame-pointer. GCC v3.2 is buggy for certain platforms!
CFLAGS += -fomit-frame-pointer
# optimize for SIZE
CFLAGS += -Os
@ -43,7 +40,6 @@ CFLAGS += -Os
#Output filenames for various targets.
LIBNAME=libtomcrypt.a
TEST=test
HASH=hashsum
CRYPT=encrypt
SMALL=small
@ -63,7 +59,7 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf
#Leave MPI built-in or force developer to link against libtommath?
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_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 \
\
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 \
rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \
aes.o aes_enc.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 \
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_shift_xor.o pmac_test.o \
\
cbc_start.o cbc_encrypt.o cbc_decrypt.o \
cfb_start.o cfb_encrypt.o cfb_decrypt.o \
ofb_start.o ofb_encrypt.o ofb_decrypt.o \
ctr_start.o ctr_encrypt.o ctr_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_getiv.o cfb_setiv.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_getiv.o ctr_setiv.o \
ecb_start.o ecb_encrypt.o ecb_decrypt.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_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 \
\
@ -129,26 +130,27 @@ PROFS=demos/x86_prof.o
TVS=demos/tv_gen.o
#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=crypt.tar.bz2 crypt.zip crypt.tar.gz
COMPRESSED=crypt-$(VERSION).tar.bz2 crypt-$(VERSION).zip
#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_macros.h mycrypt_pk.h mycrypt.h mycrypt_argchk.h \
mycrypt_custom.h mycrypt_pkcs.h
#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.
rsa.o: rsa.c rsa_sys.c
ecc.o: ecc.c ecc_sys.c
dh.o: dh.c dh_sys.c
aes.o: aes.c aes_tab.c
twofish.o: twofish.c twofish_tab.c
sha512.o: sha512.c sha384.c
sha256.o: sha256.c sha224.c
@ -158,10 +160,6 @@ library: $(LIBNAME)
$(LIBNAME): $(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
hashsum: library $(HASHOBJECTS)
$(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN)
@ -180,34 +178,6 @@ x86_prof: library $(PROFS)
tv_gen: library $(TVS)
$(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
#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.
@ -217,7 +187,7 @@ install: library docs
install -d -g root -o root $(DESTDIR)$(DATAPATH)
install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH)
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
#documentation.
@ -225,21 +195,31 @@ clean:
rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME)
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 \
*.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
#from the clean command! This is because most people would like to keep the
#nice pre-compiled crypt.pdf that comes with libtomcrypt! We only need to
#delete it if we are rebuilding it.
docs: crypt.tex
rm -f crypt.pdf $(LEFTOVERS)
rm -f doc/crypt.pdf $(LEFTOVERS)
echo "hello" > crypt.ind
latex crypt > /dev/null
makeindex crypt > /dev/null
latex crypt > /dev/null
latex crypt > /dev/null
dvipdf crypt
mv -ivf crypt.pdf doc/crypt.pdf
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: clean
cd .. ; rm -rf crypt* libtomcrypt-$(VERSION)-beta ; mkdir libtomcrypt-$(VERSION)-beta ; \
@ -250,4 +230,6 @@ beta: clean
zipup: clean docs
cd .. ; rm -rf crypt* libtomcrypt-$(VERSION) ; mkdir libtomcrypt-$(VERSION) ; \
cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)/ ; tar -c libtomcrypt-$(VERSION)/* > crypt-$(VERSION).tar ; \
bzip2 -9vv crypt-$(VERSION).tar ; zip -9 -r crypt-$(VERSION).zip libtomcrypt-$(VERSION)/*
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
@ -18,7 +18,7 @@ CFLAGS += -Os
#Leave MPI built-in or force developer to link against libtommath?
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_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 \
\
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 \
rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \
aes.o aes_enc.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 \
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_shift_xor.o pmac_test.o \
\
cbc_start.o cbc_encrypt.o cbc_decrypt.o \
cfb_start.o cfb_encrypt.o cfb_decrypt.o \
ofb_start.o ofb_encrypt.o ofb_decrypt.o \
ctr_start.o ctr_encrypt.o ctr_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_getiv.o cfb_setiv.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_getiv.o ctr_setiv.o \
ecb_start.o ecb_encrypt.o ecb_decrypt.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_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 \
\
burn_stack.o zeromem.o \
$(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)
gcc -mno-cygwin -mdll -o libtomcrypt.dll -Wl,--out-implib=libtomcrypt.dll.a -Wl,--export-all-symbols *.o -ladvapi32
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!
CFLAGS += -c -I./ -DINTEL_CC
#The default rule for make builds the libtomcrypt library.
default:library
# optimize for SPEED
#
# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4
@ -47,7 +50,6 @@ CFLAGS += -O3 -xN -ip
#Output filenames for various targets.
LIBNAME=libtomcrypt.a
TEST=test
HASH=hashsum
CRYPT=encrypt
SMALL=small
@ -67,7 +69,7 @@ DATAPATH=/usr/share/doc/libtomcrypt/pdf
#Leave MPI built-in or force developer to link against libtommath?
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_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 \
\
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 \
rc6.o rc5.o cast5.o noekeon.o blowfish.o twofish.o skipjack.o \
aes.o aes_enc.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 \
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_shift_xor.o pmac_test.o \
\
cbc_start.o cbc_encrypt.o cbc_decrypt.o \
cfb_start.o cfb_encrypt.o cfb_decrypt.o \
ofb_start.o ofb_encrypt.o ofb_decrypt.o \
ctr_start.o ctr_encrypt.o ctr_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_getiv.o cfb_setiv.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_getiv.o ctr_setiv.o \
ecb_start.o ecb_encrypt.o ecb_decrypt.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_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 \
\
burn_stack.o zeromem.o \
$(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
CRYPTOBJECTS=demos/encrypt.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_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.
rsa.o: rsa.c rsa_sys.c
ecc.o: ecc.c ecc_sys.c
@ -161,10 +169,6 @@ library: $(LIBNAME)
$(LIBNAME): $(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
hashsum: library $(HASHOBJECTS)
$(CC) $(HASHOBJECTS) $(LIBNAME) -o $(HASH) $(WARN)
@ -183,19 +187,7 @@ x86_prof: library $(PROFS)
tv_gen: library $(TVS)
$(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
#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.

View File

@ -8,8 +8,7 @@ default: library
# leave this blank and link against libtommath if you want better link resolution
MPIOBJECT=mpi.obj
#List of objects to compile.
OBJECTS=keyring.obj gf.obj strings.obj base64.obj \
OBJECTS=error_to_string.obj mpi_to_ltc_error.obj base64_encode.obj base64_decode.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 \
@ -25,12 +24,16 @@ rand_prime.obj is_prime.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 \
rc6.obj rc5.obj cast5.obj noekeon.obj blowfish.obj twofish.obj skipjack.obj \
aes.obj aes_enc.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 \
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_shift_xor.obj pmac_test.obj \
\
cbc_start.obj cbc_encrypt.obj cbc_decrypt.obj \
cfb_start.obj cfb_encrypt.obj cfb_decrypt.obj \
ofb_start.obj ofb_encrypt.obj ofb_decrypt.obj \
ctr_start.obj ctr_encrypt.obj ctr_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_getiv.obj cfb_setiv.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_getiv.obj ctr_setiv.obj \
ecb_start.obj ecb_encrypt.obj ecb_decrypt.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_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 \
\
burn_stack.obj zeromem.obj \
burn_stack.obj zeromem.obj \
$(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)
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
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,
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_process,
&md2_done,

5
md4.c
View File

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

62
md5.c
View File

@ -21,6 +21,13 @@ const struct _hash_descriptor md5_desc =
3,
16,
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_process,
&md5_done,
@ -44,6 +51,35 @@ const struct _hash_descriptor md5_desc =
#define II(a,b,c,d,M,s,t) \
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
static void _md5_compress(hash_state *md, unsigned char *buf)
#else
@ -51,6 +87,9 @@ static void md5_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 i, W[16], a, b, c, d;
#ifdef SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */
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];
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(d,a,b,c,W[1],12,0xe8c7b756UL)
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(c,d,a,b,W[2],15,0x2ad7d2bbUL)
II(b,c,d,a,W[9],21,0xeb86d391UL)
#endif
md->md5.state[0] = md->md5.state[0] + a;
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);
*/
}

242
mpi.c
View File

@ -13,7 +13,7 @@
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
static const struct {
int code;
@ -58,7 +58,7 @@ char *mp_error_to_string(int code)
*
* 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,
* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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 */
olduse = c->used;
olduse = c->used;
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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
@ -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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* b = |a|
*
@ -842,7 +842,7 @@ mp_abs (mp_int * a, mp_int * b)
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* high level addition (handles signs) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* single digit addition */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* d = a + b (mod c) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* AND two ints together */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* trim unused digits
*
@ -1136,7 +1136,7 @@ mp_clamp (mp_int * a)
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* clear one (frees) */
void
@ -1174,7 +1174,7 @@ mp_clear (mp_int * a)
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
#include <stdarg.h>
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* compare two ints (signed)*/
int
@ -1247,7 +1247,7 @@ mp_cmp (mp_int * a, mp_int * b)
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* compare a digit */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* compare maginitude of two ints (unsigned) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
static const int lnz[16] = {
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* copy, b = a */
int
@ -1459,7 +1459,7 @@ mp_copy (mp_int * a, mp_int * b)
*
* 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 */
int
@ -1502,7 +1502,7 @@ mp_count_bits (mp_int * a)
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* integer signed division.
* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* b = a/2 */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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)
@ -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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* divide by three (based on routine from MPI and the GMP manual) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* determines if a number is a valid DR modulus */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* determines the setup value */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* swap the elements of two integers, for cases where you can't simply swap the
* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* calculate c = a**b using a square-multiply algorithm */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* Extended euclidean algorithm of (a, b) produces
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* read a bigint from a file stream in ASCII */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* Greatest Common Divisor using the binary method */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* get the lower 32-bits of an mp_int */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* grow as required */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* init a new bigint */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* creates "a" then copies b into it */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
#include <stdarg.h>
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* initialize and set a digit */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* initialize and set a digit */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* init an mp_init for a given 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* hac 14.61, pp608 */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* Check if remainders are possible squares - fast exclude non-squares */
static const char rem_128[128] = {
@ -3586,7 +3586,7 @@ ERR:mp_clear(&t);
*
* 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)
* HAC pp. 73 Algorithm 2.149
@ -3689,7 +3689,7 @@ __A1:mp_clear (&a1);
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* c = |a| * |b| using Karatsuba Multiplication using
* three half size multiplications
@ -3857,7 +3857,7 @@ ERR:
*
* 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
* half size squarings
@ -3976,7 +3976,7 @@ ERR:
*
* 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) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* shift left a certain amount of digits */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* c = a mod b, 0 <= c < b */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* calc a value mod 2**b */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
int
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* calculates a = B^n mod b for Montgomery reduction
* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* computes xR**-1 == x (mod N) via Montgomery Reduction */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* setups the montgomery reduction stuff */
int
@ -4453,7 +4453,7 @@ mp_montgomery_setup (mp_int * n, mp_digit * rho)
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* high level multiplication (handles sign) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* b = a*2 */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* shift left by a certain bit count */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* multiply by a digit */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* d = a * b (mod c) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* b = -a */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* OR two ints together */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* performs one Fermat test.
*
@ -5053,7 +5053,7 @@ __T:mp_clear (&t);
*
* 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
* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* Miller-Rabin test of "a" to the base of "b" as described in
* HAC pp. 139 Algorithm 4.24
@ -5283,7 +5283,7 @@ __N1:mp_clear (&n1);
*
* 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
* of Miller-Rabin.
@ -5451,7 +5451,7 @@ __ERR:
*
* 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),
*
@ -5573,7 +5573,7 @@ error:
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* returns size of ASCII reprensentation */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* chars used in radix conversions */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* makes a pseudo-random int of a given size */
int
@ -5717,7 +5717,7 @@ mp_rand (mp_int * a, int digits)
*
* 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 */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* read signed bin, big endian, first byte is 0==positive or 1==negative */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* reads a unsigned char array, assumes the msb is stored first [big endian] */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* reduces x mod m, assumes 0 < x < m**2, mu is
* precomputed via mp_reduce_setup.
@ -5979,7 +5979,7 @@ CLEANUP:
*
* 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 */
int
@ -6039,7 +6039,7 @@ ERR:
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* determines the setup value */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* determines if mp_reduce_2k can be used */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* pre-calculate the value required for Barrett reduction
* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* shift right a certain amount of digits */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* set to a digit */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* set a 32-bit const */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* shrink a bignum */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* get the size for an signed equivalent */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* computes b = a*a */
int
@ -6413,7 +6413,7 @@ mp_sqr (mp_int * a, mp_int * b)
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* c = a * a (mod b) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* this function is less generic than mp_n_root, simpler and faster */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* high level subtraction (handles signs) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* single digit subtraction */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* d = a - b (mod c) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* store in signed [big endian] format */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* store in unsigned [big endian] format */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* multiplication using the Toom-Cook 3-way algorithm */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* squaring using Toom-Cook 3-way algorithm */
int
@ -7294,7 +7294,7 @@ ERR:
*
* 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) */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* get the size for an unsigned equivalent */
int
@ -7481,7 +7481,7 @@ mp_unsigned_bin_size (mp_int * a)
*
* Tom St Denis, tomstdenis@iahu.ca, http://math.libtomcrypt.org
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* XOR two ints together */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* set to zero */
void
@ -7558,7 +7558,7 @@ mp_zero (mp_int * a)
*
* 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 */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
const mp_digit __prime_tab[] = {
0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* reverse an array, used for radix code */
void
@ -7709,7 +7709,7 @@ bn_reverse (unsigned char *s, int len)
*
* 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 */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
#ifdef MP_LOW_MEM
#define TAB_SIZE 32
@ -8054,7 +8054,7 @@ __M:
*
* 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
* 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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* multiplies |a| * |b| and does not compute the lower digs digits
* [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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
int
@ -8303,7 +8303,7 @@ s_mp_sqr (mp_int * a, mp_int * b)
*
* 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 */
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
*/
#include <tommath.h>
#include <ltc_tommath.h>
/* Known optimal configurations
CPU /Compiler /MUL CUTOFF/SQR CUTOFF
-------------------------------------------------------------
Intel P4 /GCC v3.2 / 70/ 108
AMD Athlon XP /GCC v3.2 / 109/ 127
Intel P4 Northwood /GCC v3.3.3 / 59/ 81/profiled build
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 = 70, /* Min. number of digits before Karatsuba multiplication is used. */
KARATSUBA_SQR_CUTOFF = 108, /* Min. number of digits before Karatsuba squaring is used. */
int KARATSUBA_MUL_CUTOFF = 57, /* Min. number of digits before Karatsuba multiplication is used. */
KARATSUBA_SQR_CUTOFF = 70, /* 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_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
/* version */
#define CRYPT 0x0095
#define SCRYPT "0.95"
#define CRYPT 0x0096
#define SCRYPT "0.96"
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
#define MAXBLOCKSIZE 128
@ -68,9 +68,7 @@ enum {
#include <mycrypt_hash.h>
#include <mycrypt_prng.h>
#include <mycrypt_pk.h>
#include <mycrypt_gf.h>
#include <mycrypt_misc.h>
#include <mycrypt_kr.h>
#include <mycrypt_argchk.h>
#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_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 void rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key);
extern void rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key);
extern int rijndael_test(void);
extern int rijndael_keysize(int *desired_keysize);
extern 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_enc_desc, aes_enc_desc;
#endif
#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);
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_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
#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);
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_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
#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);
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_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
#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);
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_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

View File

@ -9,14 +9,27 @@
#error mycrypt_custom.h should be included before mycrypt.h
#endif
/* macros for various libc functions */
#define XMALLOC malloc
#define XREALLOC realloc
#define XCALLOC calloc
#define XFREE free
#define XCLOCK clock
#define XCLOCKS_PER_SEC CLOCKS_PER_SEC
/* Use small code where possible */
#define SMALL_CODE
/* Enable self-test test vector checking */
#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 RC2
#define RC5
@ -26,15 +39,21 @@
#define XTEA
#define TWOFISH
#define TWOFISH_TABLES
//#define TWOFISH_ALL_TABLES
//#define TWOFISH_SMALL
#define DES
#define CAST5
#define NOEKEON
#define SKIPJACK
/* modes of operation */
#define CFB
#define OFB
#define ECB
#define CBC
#define CTR
/* hash functions */
#define WHIRLPOOL
#define SHA512
#define SHA384
@ -47,18 +66,30 @@
#define MD2
#define RIPEMD128
#define RIPEMD160
/* MAC functions */
#define HMAC
#define OMAC
#define PMAC
/* Encrypt + Authenticate Modes */
#define EAX_MODE
#define OCB_MODE
/* Various tidbits of modern neatoness */
#define BASE64
#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 RC4
#define DEVRANDOM
#define TRY_URANDOM_FIRST
/* Public Key Neatoness */
#define MRSA
#define RSA_TIMING // enable RSA side channel timing prevention
#define MDSA
#define MDH
#define MECC
@ -79,10 +110,10 @@
#define ECC521
#define MPI
/* PKCS #1 and 5 stuff */
#define PKCS_1
#define PKCS_5
#include <mycrypt.h>
#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 long hashsize; /* digest output size in bytes */
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 *);
int (*process)(hash_state *, const unsigned char *, unsigned long);
int (*done)(hash_state *, unsigned char *);

View File

@ -1,7 +1,7 @@
/* ---- NUMBER THEORY ---- */
#ifdef MPI
#include "tommath.h"
#include "ltc_tommath.h"
/* in/out macros */
#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
/* 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 {
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_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
rsa_key *key);
extern int rsa_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
prng_state *prng, int prng_idx,
rsa_key *key);
extern int rsa_pad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
int wprng, prng_state *prng);
#ifdef RSA_TIMING
extern int rsa_signpad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
extern int tim_exptmod(prng_state *prng, int prng_idx,
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,
unsigned char *out, unsigned long *outlen);
#else
extern int rsa_signdepad(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
#define tim_exptmod(prng, prng_idx, c, e, d, n, m) mpi_to_ltc_error(mp_exptmod(c, d, n, m))
#endif
extern void rsa_free(rsa_key *key);
extern int rsa_encrypt_key(const unsigned char *inkey, unsigned long inlen,
unsigned char *outkey, unsigned long *outlen,
prng_state *prng, int wprng, rsa_key *key);
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);
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);
extern int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
unsigned char *outkey, unsigned long *keylen,
rsa_key *key);
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);
extern int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen,
rsa_key *key);
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);
extern int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
const unsigned char *hash, int *stat, rsa_key *key);
extern int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key);
extern int rsa_import(const unsigned char *in, unsigned long inlen, 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);
#endif
/* ---- DH Routines ---- */

View File

@ -7,20 +7,25 @@ int pkcs_1_mgf1(const unsigned char *seed, unsigned long seedlen,
int hash_idx,
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,
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx,
int prng_idx, prng_state *prng,
unsigned long modulus_bitlen, prng_state *prng,
int prng_idx, int hash_idx,
unsigned char *out, unsigned long *outlen);
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen,
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,
unsigned long saltlen, int hash_idx,
int prng_idx, prng_state *prng,
unsigned long saltlen, prng_state *prng,
int prng_idx, int hash_idx,
unsigned long modulus_bitlen,
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 modulus_bitlen, int *res);
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);
/* *** v1.5 padding */
/* 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 */

View File

@ -22,9 +22,14 @@ int ocb_decrypt(ocb_state *ocb, const unsigned char *ct, unsigned char *pt)
_ARGCHK(ocb != NULL);
_ARGCHK(pt != NULL);
_ARGCHK(ct != NULL);
/* check if valid cipher */
if ((err = cipher_is_valid(ocb->cipher)) != CRYPT_OK) {
return err;
}
_ARGCHK(cipher_descriptor[ocb->cipher].ecb_decrypt != NULL);
/* check length */
if (ocb->block_len != cipher_descriptor[ocb->cipher].block_length) {
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
int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx,
unsigned char *out, unsigned long *outlen)
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx,
unsigned char *out, unsigned long *outlen,
int *res)
{
unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)];
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(out != NULL);
_ARGCHK(outlen != NULL);
_ARGCHK(res != NULL);
/* default to invalid packet */
*res = 0;
/* test valid hash */
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 */
if (msg[0] != 0x00) {
return CRYPT_INVALID_PACKET;
return CRYPT_OK;
}
/* 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 */
if (memcmp(seed, DB, hLen) != 0) {
return CRYPT_INVALID_PACKET;
return CRYPT_OK;
}
/* 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 */
if (x == (modulus_len - hLen - 1) || DB[x] != 0x01) {
return CRYPT_INVALID_PACKET;
return CRYPT_OK;
}
/* 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));
#endif
/* valid packet */
*res = 1;
return CRYPT_OK;
}

View File

@ -15,10 +15,10 @@
#ifdef PKCS_1
int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, int hash_idx,
int prng_idx, prng_state *prng,
unsigned char *out, unsigned long *outlen)
const unsigned char *lparam, unsigned long lparamlen,
unsigned long modulus_bitlen, prng_state *prng,
int prng_idx, int hash_idx,
unsigned char *out, unsigned long *outlen)
{
unsigned char DB[1024], seed[MAXBLOCKSIZE], mask[sizeof(DB)];
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 */
if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - modulus_bitlen))) != 0) {
if ((sig[0] & ~(0xFF >> ((modulus_len<<3) - (modulus_bitlen-1)))) != 0) {
return CRYPT_OK;
}
@ -73,6 +73,9 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen,
for (y = 0; y < (modulus_len - hLen - 1); 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 */

View File

@ -15,8 +15,8 @@
#ifdef PKCS_1
int pkcs_1_pss_encode(const unsigned char *msghash, unsigned long msghashlen,
unsigned long saltlen, int hash_idx,
int prng_idx, prng_state *prng,
unsigned long saltlen, prng_state *prng,
int prng_idx, int hash_idx,
unsigned long modulus_bitlen,
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;
/* 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 */
*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!!!
-- 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(err);
}
return CRYPT_OK;
return mpi_to_ltc_error(mp_prime_random_ex(N, mp_prime_rabin_miller_trials(len), len, type, rand_prime_helper, &rng));
}
#endif

View File

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

View File

@ -24,6 +24,12 @@ const struct _hash_descriptor rmd160_desc =
9,
20,
64,
/* DER identifier */
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x24,
0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 },
15,
&rmd160_init,
&rmd160_process,
&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,18 +14,23 @@
#ifdef MRSA
int rsa_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
int rsa_exptmod(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
prng_state *prng, int prng_idx,
rsa_key *key)
{
mp_int tmp, tmpa, tmpb;
mp_int tmp, tmpa, tmpb;
unsigned long x;
int err;
int err;
_ARGCHK(in != NULL);
_ARGCHK(out != NULL);
_ARGCHK(outlen != 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)) {
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? */
if (which == PK_PRIVATE && key->type == PK_PRIVATE_OPTIMIZED) {
/* 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 */
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 */
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; }
} else {
/* 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 */
x = (unsigned long)mp_unsigned_bin_size(&tmp);
x = (unsigned long)mp_unsigned_bin_size(&key->N);
if (x > *outlen) {
err = CRYPT_BUFFER_OVERFLOW;
goto done;
@ -72,7 +81,8 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
*outlen = x;
/* 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 */
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)
{
mp_int p, q, tmp1, tmp2, tmp3;
int err;
int err;
_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,
20,
64,
/* DER identifier */
{ 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B, 0x0E,
0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14 },
15,
&sha1_init,
&sha1_process,
&sha1_done,
@ -38,6 +44,9 @@ static void sha1_compress(hash_state *md, unsigned char *buf)
#endif
{
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] */
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 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; ) {
FF0(a,b,c,d,e,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(b,c,d,e,a,i++);
}
#endif
#undef FF0
#undef FF1

View File

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

View File

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

View File

@ -17,6 +17,13 @@ const struct _hash_descriptor sha384_desc =
4,
48,
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,
&sha512_process,
&sha384_done,

View File

@ -21,6 +21,13 @@ const struct _hash_descriptor sha512_desc =
5,
64,
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_process,
&sha512_done,

View File

@ -19,6 +19,13 @@ const struct _hash_descriptor tiger_desc =
1,
24,
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_process,
&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,
64,
64,
/* DER encoding (not yet supported) */
{ 0x00 },
0,
&whirlpool_init,
&whirlpool_process,
&whirlpool_done,
@ -34,7 +39,7 @@ const struct _hash_descriptor whirlpool_desc =
#define GB(a,i,j) ((a[(i) & 7] >> (8 * (j))) & 255)
/* 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)) ^ \
SB1(GB(a, i-1, 6)) ^ \
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 */
#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);
#elif YARROW_AES==3
prng->yarrow.cipher = register_cipher(&aes_desc);
#endif
#elif defined(BLOWFISH)
prng->yarrow.cipher = register_cipher(&blowfish_desc);
#elif defined(TWOFISH)
@ -78,6 +86,8 @@ int yarrow_start(prng_state *prng)
prng->yarrow.hash = register_hash(&md4_desc);
#elif defined(MD2)
prng->yarrow.hash = register_hash(&md2_desc);
#elif defined(WHIRLPOOL)
prng->yarrow.hash = register_hash(&whirlpool_desc);
#else
#error YARROW needs at least one HASH
#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 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 */
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 */
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;
}