mirror of
https://github.com/clearml/dropbear
synced 2025-06-26 18:17:32 +00:00
put back the 0.95 makefile which was inadvertently merged over
--HG-- branch : libtomcrypt extra : convert_revision : a8432150cae4fe7441284bef582b002687ede6e0
This commit is contained in:
9
LICENSE
Normal file
9
LICENSE
Normal file
@@ -0,0 +1,9 @@
|
||||
LibTomCrypt is public domain. As should all quality software be.
|
||||
|
||||
All of the software was either written by or donated to Tom St Denis for the purposes
|
||||
of this project. The only exception is the SAFER.C source which has no known
|
||||
license status (assumed copyrighted) which is why SAFER,C is shipped as disabled.
|
||||
|
||||
Tom St Denis
|
||||
|
||||
|
||||
38
PLAN
Normal file
38
PLAN
Normal file
@@ -0,0 +1,38 @@
|
||||
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???
|
||||
606
aes.c
Normal file
606
aes.c
Normal file
@@ -0,0 +1,606 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* AES implementation by Tom St Denis
|
||||
*
|
||||
* Derived from the Public Domain source code by
|
||||
|
||||
---
|
||||
* rijndael-alg-fst.c
|
||||
*
|
||||
* @version 3.0 (December 2000)
|
||||
*
|
||||
* Optimised ANSI C code for the Rijndael cipher (now AES)
|
||||
*
|
||||
* @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
|
||||
* @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
|
||||
* @author Paulo Barreto <paulo.barreto@terra.com.br>
|
||||
---
|
||||
*/
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef RIJNDAEL
|
||||
|
||||
const struct _cipher_descriptor rijndael_desc =
|
||||
{
|
||||
"rijndael",
|
||||
6,
|
||||
16, 32, 16, 10,
|
||||
&rijndael_setup,
|
||||
&rijndael_ecb_encrypt,
|
||||
&rijndael_ecb_decrypt,
|
||||
&rijndael_test,
|
||||
&rijndael_keysize
|
||||
};
|
||||
|
||||
const struct _cipher_descriptor aes_desc =
|
||||
{
|
||||
"aes",
|
||||
6,
|
||||
16, 32, 16, 10,
|
||||
&rijndael_setup,
|
||||
&rijndael_ecb_encrypt,
|
||||
&rijndael_ecb_decrypt,
|
||||
&rijndael_test,
|
||||
&rijndael_keysize
|
||||
};
|
||||
|
||||
#include "aes_tab.c"
|
||||
|
||||
int rijndael_setup(const unsigned char *key, int keylen, int rounds, symmetric_key *skey)
|
||||
{
|
||||
int i, j;
|
||||
ulong32 temp, *rk, *rrk;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if (keylen != 16 && keylen != 24 && keylen != 32) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
if (rounds != 0 && rounds != (10 + ((keylen/8)-2)*2)) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
|
||||
|
||||
/* setup the forward key */
|
||||
i = 0;
|
||||
rk = skey->rijndael.eK;
|
||||
LOAD32H(rk[0], key );
|
||||
LOAD32H(rk[1], key + 4);
|
||||
LOAD32H(rk[2], key + 8);
|
||||
LOAD32H(rk[3], key + 12);
|
||||
if (keylen == 16) {
|
||||
j = 44;
|
||||
for (;;) {
|
||||
temp = rk[3];
|
||||
rk[4] = rk[0] ^
|
||||
(Te4_3[byte(temp, 2)]) ^
|
||||
(Te4_2[byte(temp, 1)]) ^
|
||||
(Te4_1[byte(temp, 0)]) ^
|
||||
(Te4_0[byte(temp, 3)]) ^
|
||||
rcon[i];
|
||||
rk[5] = rk[1] ^ rk[4];
|
||||
rk[6] = rk[2] ^ rk[5];
|
||||
rk[7] = rk[3] ^ rk[6];
|
||||
if (++i == 10) {
|
||||
break;
|
||||
}
|
||||
rk += 4;
|
||||
}
|
||||
} else if (keylen == 24) {
|
||||
j = 52;
|
||||
LOAD32H(rk[4], key + 16);
|
||||
LOAD32H(rk[5], key + 20);
|
||||
for (;;) {
|
||||
#ifdef _MSC_VER
|
||||
temp = skey->rijndael.eK[rk - skey->rijndael.eK + 5];
|
||||
#else
|
||||
temp = rk[5];
|
||||
#endif
|
||||
rk[ 6] = rk[ 0] ^
|
||||
(Te4_3[byte(temp, 2)]) ^
|
||||
(Te4_2[byte(temp, 1)]) ^
|
||||
(Te4_1[byte(temp, 0)]) ^
|
||||
(Te4_0[byte(temp, 3)]) ^
|
||||
rcon[i];
|
||||
rk[ 7] = rk[ 1] ^ rk[ 6];
|
||||
rk[ 8] = rk[ 2] ^ rk[ 7];
|
||||
rk[ 9] = rk[ 3] ^ rk[ 8];
|
||||
if (++i == 8) {
|
||||
break;
|
||||
}
|
||||
rk[10] = rk[ 4] ^ rk[ 9];
|
||||
rk[11] = rk[ 5] ^ rk[10];
|
||||
rk += 6;
|
||||
}
|
||||
} else if (keylen == 32) {
|
||||
j = 60;
|
||||
LOAD32H(rk[4], key + 16);
|
||||
LOAD32H(rk[5], key + 20);
|
||||
LOAD32H(rk[6], key + 24);
|
||||
LOAD32H(rk[7], key + 28);
|
||||
for (;;) {
|
||||
#ifdef _MSC_VER
|
||||
temp = skey->rijndael.eK[rk - skey->rijndael.eK + 7];
|
||||
#else
|
||||
temp = rk[7];
|
||||
#endif
|
||||
rk[ 8] = rk[ 0] ^
|
||||
(Te4_3[byte(temp, 2)]) ^
|
||||
(Te4_2[byte(temp, 1)]) ^
|
||||
(Te4_1[byte(temp, 0)]) ^
|
||||
(Te4_0[byte(temp, 3)]) ^
|
||||
rcon[i];
|
||||
rk[ 9] = rk[ 1] ^ rk[ 8];
|
||||
rk[10] = rk[ 2] ^ rk[ 9];
|
||||
rk[11] = rk[ 3] ^ rk[10];
|
||||
if (++i == 7) {
|
||||
break;
|
||||
}
|
||||
temp = rk[11];
|
||||
rk[12] = rk[ 4] ^
|
||||
(Te4_3[byte(temp, 3)]) ^
|
||||
(Te4_2[byte(temp, 2)]) ^
|
||||
(Te4_1[byte(temp, 1)]) ^
|
||||
(Te4_0[byte(temp, 0)]);
|
||||
rk[13] = rk[ 5] ^ rk[12];
|
||||
rk[14] = rk[ 6] ^ rk[13];
|
||||
rk[15] = rk[ 7] ^ rk[14];
|
||||
rk += 8;
|
||||
}
|
||||
} else {
|
||||
/* this can't happen */
|
||||
j = 4;
|
||||
}
|
||||
|
||||
/* setup the inverse key now */
|
||||
rk = skey->rijndael.dK;
|
||||
rrk = skey->rijndael.eK + j - 4;
|
||||
|
||||
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
|
||||
/* copy first */
|
||||
*rk++ = *rrk++;
|
||||
*rk++ = *rrk++;
|
||||
*rk++ = *rrk++;
|
||||
*rk = *rrk;
|
||||
rk -= 3; rrk -= 3;
|
||||
|
||||
for (i = 1; i < skey->rijndael.Nr; i++) {
|
||||
rrk -= 4;
|
||||
rk += 4;
|
||||
#ifdef SMALL_CODE
|
||||
temp = rrk[0];
|
||||
rk[0] =
|
||||
Td0(255 & Te4[byte(temp, 3)]) ^
|
||||
Td1(255 & Te4[byte(temp, 2)]) ^
|
||||
Td2(255 & Te4[byte(temp, 1)]) ^
|
||||
Td3(255 & Te4[byte(temp, 0)]);
|
||||
temp = rrk[1];
|
||||
rk[1] =
|
||||
Td0(255 & Te4[byte(temp, 3)]) ^
|
||||
Td1(255 & Te4[byte(temp, 2)]) ^
|
||||
Td2(255 & Te4[byte(temp, 1)]) ^
|
||||
Td3(255 & Te4[byte(temp, 0)]);
|
||||
temp = rrk[2];
|
||||
rk[2] =
|
||||
Td0(255 & Te4[byte(temp, 3)]) ^
|
||||
Td1(255 & Te4[byte(temp, 2)]) ^
|
||||
Td2(255 & Te4[byte(temp, 1)]) ^
|
||||
Td3(255 & Te4[byte(temp, 0)]);
|
||||
temp = rrk[3];
|
||||
rk[3] =
|
||||
Td0(255 & Te4[byte(temp, 3)]) ^
|
||||
Td1(255 & Te4[byte(temp, 2)]) ^
|
||||
Td2(255 & Te4[byte(temp, 1)]) ^
|
||||
Td3(255 & Te4[byte(temp, 0)]);
|
||||
#else
|
||||
temp = rrk[0];
|
||||
rk[0] =
|
||||
Tks0[byte(temp, 3)] ^
|
||||
Tks1[byte(temp, 2)] ^
|
||||
Tks2[byte(temp, 1)] ^
|
||||
Tks3[byte(temp, 0)];
|
||||
temp = rrk[1];
|
||||
rk[1] =
|
||||
Tks0[byte(temp, 3)] ^
|
||||
Tks1[byte(temp, 2)] ^
|
||||
Tks2[byte(temp, 1)] ^
|
||||
Tks3[byte(temp, 0)];
|
||||
temp = rrk[2];
|
||||
rk[2] =
|
||||
Tks0[byte(temp, 3)] ^
|
||||
Tks1[byte(temp, 2)] ^
|
||||
Tks2[byte(temp, 1)] ^
|
||||
Tks3[byte(temp, 0)];
|
||||
temp = rrk[3];
|
||||
rk[3] =
|
||||
Tks0[byte(temp, 3)] ^
|
||||
Tks1[byte(temp, 2)] ^
|
||||
Tks2[byte(temp, 1)] ^
|
||||
Tks3[byte(temp, 0)];
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/* copy last */
|
||||
rrk -= 4;
|
||||
rk += 4;
|
||||
*rk++ = *rrk++;
|
||||
*rk++ = *rrk++;
|
||||
*rk++ = *rrk++;
|
||||
*rk = *rrk;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_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)
|
||||
#endif
|
||||
{
|
||||
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
|
||||
int Nr, r;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
Nr = skey->rijndael.Nr;
|
||||
rk = skey->rijndael.eK;
|
||||
|
||||
/*
|
||||
* map byte array block to cipher state
|
||||
* and add initial round key:
|
||||
*/
|
||||
LOAD32H(s0, pt ); s0 ^= rk[0];
|
||||
LOAD32H(s1, pt + 4); s1 ^= rk[1];
|
||||
LOAD32H(s2, pt + 8); s2 ^= rk[2];
|
||||
LOAD32H(s3, pt + 12); s3 ^= rk[3];
|
||||
|
||||
/*
|
||||
* Nr - 1 full rounds:
|
||||
*/
|
||||
r = Nr >> 1;
|
||||
for (;;) {
|
||||
t0 =
|
||||
Te0(byte(s0, 3)) ^
|
||||
Te1(byte(s1, 2)) ^
|
||||
Te2(byte(s2, 1)) ^
|
||||
Te3(byte(s3, 0)) ^
|
||||
rk[4];
|
||||
t1 =
|
||||
Te0(byte(s1, 3)) ^
|
||||
Te1(byte(s2, 2)) ^
|
||||
Te2(byte(s3, 1)) ^
|
||||
Te3(byte(s0, 0)) ^
|
||||
rk[5];
|
||||
t2 =
|
||||
Te0(byte(s2, 3)) ^
|
||||
Te1(byte(s3, 2)) ^
|
||||
Te2(byte(s0, 1)) ^
|
||||
Te3(byte(s1, 0)) ^
|
||||
rk[6];
|
||||
t3 =
|
||||
Te0(byte(s3, 3)) ^
|
||||
Te1(byte(s0, 2)) ^
|
||||
Te2(byte(s1, 1)) ^
|
||||
Te3(byte(s2, 0)) ^
|
||||
rk[7];
|
||||
|
||||
rk += 8;
|
||||
if (--r == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
s0 =
|
||||
Te0(byte(t0, 3)) ^
|
||||
Te1(byte(t1, 2)) ^
|
||||
Te2(byte(t2, 1)) ^
|
||||
Te3(byte(t3, 0)) ^
|
||||
rk[0];
|
||||
s1 =
|
||||
Te0(byte(t1, 3)) ^
|
||||
Te1(byte(t2, 2)) ^
|
||||
Te2(byte(t3, 1)) ^
|
||||
Te3(byte(t0, 0)) ^
|
||||
rk[1];
|
||||
s2 =
|
||||
Te0(byte(t2, 3)) ^
|
||||
Te1(byte(t3, 2)) ^
|
||||
Te2(byte(t0, 1)) ^
|
||||
Te3(byte(t1, 0)) ^
|
||||
rk[2];
|
||||
s3 =
|
||||
Te0(byte(t3, 3)) ^
|
||||
Te1(byte(t0, 2)) ^
|
||||
Te2(byte(t1, 1)) ^
|
||||
Te3(byte(t2, 0)) ^
|
||||
rk[3];
|
||||
}
|
||||
/*
|
||||
* 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]) ^
|
||||
rk[0];
|
||||
STORE32H(s0, ct);
|
||||
s1 =
|
||||
(Te4_3[(t1 >> 24) ]) ^
|
||||
(Te4_2[(t2 >> 16) & 0xff]) ^
|
||||
(Te4_1[(t3 >> 8) & 0xff]) ^
|
||||
(Te4_0[(t0 ) & 0xff]) ^
|
||||
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]) ^
|
||||
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]) ^
|
||||
rk[3];
|
||||
STORE32H(s3, ct+12);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void rijndael_ecb_encrypt(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
|
||||
|
||||
#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)
|
||||
#endif
|
||||
{
|
||||
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
|
||||
int Nr, r;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
Nr = skey->rijndael.Nr;
|
||||
rk = skey->rijndael.dK;
|
||||
|
||||
/*
|
||||
* map byte array block to cipher state
|
||||
* and add initial round key:
|
||||
*/
|
||||
LOAD32H(s0, ct ); s0 ^= rk[0];
|
||||
LOAD32H(s1, ct + 4); s1 ^= rk[1];
|
||||
LOAD32H(s2, ct + 8); s2 ^= rk[2];
|
||||
LOAD32H(s3, ct + 12); s3 ^= rk[3];
|
||||
|
||||
/*
|
||||
* Nr - 1 full rounds:
|
||||
*/
|
||||
r = Nr >> 1;
|
||||
for (;;) {
|
||||
|
||||
t0 =
|
||||
Td0(byte(s0, 3)) ^
|
||||
Td1(byte(s3, 2)) ^
|
||||
Td2(byte(s2, 1)) ^
|
||||
Td3(byte(s1, 0)) ^
|
||||
rk[4];
|
||||
t1 =
|
||||
Td0(byte(s1, 3)) ^
|
||||
Td1(byte(s0, 2)) ^
|
||||
Td2(byte(s3, 1)) ^
|
||||
Td3(byte(s2, 0)) ^
|
||||
rk[5];
|
||||
t2 =
|
||||
Td0(byte(s2, 3)) ^
|
||||
Td1(byte(s1, 2)) ^
|
||||
Td2(byte(s0, 1)) ^
|
||||
Td3(byte(s3, 0)) ^
|
||||
rk[6];
|
||||
t3 =
|
||||
Td0(byte(s3, 3)) ^
|
||||
Td1(byte(s2, 2)) ^
|
||||
Td2(byte(s1, 1)) ^
|
||||
Td3(byte(s0, 0)) ^
|
||||
rk[7];
|
||||
|
||||
rk += 8;
|
||||
if (--r == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
s0 =
|
||||
Td0(byte(t0, 3)) ^
|
||||
Td1(byte(t3, 2)) ^
|
||||
Td2(byte(t2, 1)) ^
|
||||
Td3(byte(t1, 0)) ^
|
||||
rk[0];
|
||||
s1 =
|
||||
Td0(byte(t1, 3)) ^
|
||||
Td1(byte(t0, 2)) ^
|
||||
Td2(byte(t3, 1)) ^
|
||||
Td3(byte(t2, 0)) ^
|
||||
rk[1];
|
||||
s2 =
|
||||
Td0(byte(t2, 3)) ^
|
||||
Td1(byte(t1, 2)) ^
|
||||
Td2(byte(t0, 1)) ^
|
||||
Td3(byte(t3, 0)) ^
|
||||
rk[2];
|
||||
s3 =
|
||||
Td0(byte(t3, 3)) ^
|
||||
Td1(byte(t2, 2)) ^
|
||||
Td2(byte(t1, 1)) ^
|
||||
Td3(byte(t0, 0)) ^
|
||||
rk[3];
|
||||
}
|
||||
|
||||
/*
|
||||
* apply last round and
|
||||
* map cipher state to byte array block:
|
||||
*/
|
||||
s0 =
|
||||
(Td4[(t0 >> 24) ] & 0xff000000) ^
|
||||
(Td4[(t3 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Td4[(t2 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Td4[(t1 ) & 0xff] & 0x000000ff) ^
|
||||
rk[0];
|
||||
STORE32H(s0, pt);
|
||||
s1 =
|
||||
(Td4[(t1 >> 24) ] & 0xff000000) ^
|
||||
(Td4[(t0 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Td4[(t3 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Td4[(t2 ) & 0xff] & 0x000000ff) ^
|
||||
rk[1];
|
||||
STORE32H(s1, pt+4);
|
||||
s2 =
|
||||
(Td4[(t2 >> 24) ] & 0xff000000) ^
|
||||
(Td4[(t1 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Td4[(t0 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Td4[(t3 ) & 0xff] & 0x000000ff) ^
|
||||
rk[2];
|
||||
STORE32H(s2, pt+8);
|
||||
s3 =
|
||||
(Td4[(t3 >> 24) ] & 0xff000000) ^
|
||||
(Td4[(t2 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Td4[(t1 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Td4[(t0 ) & 0xff] & 0x000000ff) ^
|
||||
rk[3];
|
||||
STORE32H(s3, pt+12);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void rijndael_ecb_decrypt(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)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
int err;
|
||||
static const struct {
|
||||
int keylen;
|
||||
unsigned char key[32], pt[16], ct[16];
|
||||
} tests[] = {
|
||||
{ 16,
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
|
||||
{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
|
||||
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
|
||||
}, {
|
||||
24,
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
|
||||
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
|
||||
{ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
|
||||
0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
|
||||
}, {
|
||||
32,
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
|
||||
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
|
||||
{ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
|
||||
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
|
||||
}
|
||||
};
|
||||
|
||||
symmetric_key key;
|
||||
unsigned char tmp[2][16];
|
||||
int i, y;
|
||||
|
||||
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
|
||||
zeromem(&key, sizeof(key));
|
||||
if ((err = rijndael_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
rijndael_ecb_encrypt(tests[i].pt, tmp[0], &key);
|
||||
rijndael_ecb_decrypt(tmp[0], tmp[1], &key);
|
||||
if (memcmp(tmp[0], tests[i].ct, 16) || memcmp(tmp[1], tests[i].pt, 16)) {
|
||||
#if 0
|
||||
printf("\n\nTest %d failed\n", i);
|
||||
if (memcmp(tmp[0], tests[i].ct, 16)) {
|
||||
printf("CT: ");
|
||||
for (i = 0; i < 16; i++) {
|
||||
printf("%02x ", tmp[0][i]);
|
||||
}
|
||||
printf("\n");
|
||||
} else {
|
||||
printf("PT: ");
|
||||
for (i = 0; i < 16; i++) {
|
||||
printf("%02x ", tmp[1][i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
|
||||
for (y = 0; y < 16; y++) tmp[0][y] = 0;
|
||||
for (y = 0; y < 1000; y++) rijndael_ecb_encrypt(tmp[0], tmp[0], &key);
|
||||
for (y = 0; y < 1000; y++) rijndael_ecb_decrypt(tmp[0], tmp[0], &key);
|
||||
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int rijndael_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
|
||||
if (*desired_keysize < 16)
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
if (*desired_keysize < 24) {
|
||||
*desired_keysize = 16;
|
||||
return CRYPT_OK;
|
||||
} else if (*desired_keysize < 32) {
|
||||
*desired_keysize = 24;
|
||||
return CRYPT_OK;
|
||||
} else {
|
||||
*desired_keysize = 32;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
55
ampi.c
Normal file
55
ampi.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/* Code submitted by Svante Seleborg, cleaned up by Tom St Denis */
|
||||
|
||||
#include "mycrypt.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef MPI
|
||||
|
||||
mp_err mp_init_multi(mp_int *mp, ...)
|
||||
{
|
||||
mp_err res = MP_OKAY; /* Assume ok until proven otherwise */
|
||||
int n = 0; /* Number of ok inits */
|
||||
mp_int* cur_arg = mp;
|
||||
va_list args;
|
||||
|
||||
va_start(args, mp); /* init args to next argument from caller */
|
||||
while (cur_arg != NULL) {
|
||||
if (mp_init(cur_arg) != MP_OKAY) {
|
||||
/* Oops - error! Back-track and mp_clear what we already
|
||||
succeeded in init-ing, then return error.
|
||||
*/
|
||||
va_list clean_args;
|
||||
cur_arg = mp;
|
||||
va_start(clean_args, mp);
|
||||
while (n--) {
|
||||
mp_clear(cur_arg);
|
||||
cur_arg = va_arg(clean_args, mp_int*);
|
||||
}
|
||||
va_end(clean_args);
|
||||
res = MP_MEM;
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
cur_arg = va_arg(args, mp_int*);
|
||||
}
|
||||
va_end(args);
|
||||
return res; /* Assumed ok, if error flagged above. */
|
||||
}
|
||||
|
||||
/*
|
||||
Clear all arguments given, ended by a NULL marker.
|
||||
*/
|
||||
void mp_clear_multi(mp_int *mp, ...)
|
||||
{
|
||||
mp_int* next_mp = mp;
|
||||
va_list args;
|
||||
va_start(args, mp);
|
||||
while (next_mp != NULL) {
|
||||
mp_clear(next_mp);
|
||||
next_mp = va_arg(args, mp_int*);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
55
authors
Normal file
55
authors
Normal file
@@ -0,0 +1,55 @@
|
||||
This is a list of people who have contributed [directly or indirectly] to the project
|
||||
[in no partcular order]. If you have helped and your name is not here email me at
|
||||
tomstdenis@yahoo.com.
|
||||
|
||||
|
||||
1) Richard.van.de.Laarschot@ict.nl
|
||||
|
||||
Gave help porting the lib to MSVC particularly pointed out various warnings and errors.
|
||||
|
||||
2) Richard Heathfield
|
||||
|
||||
Gave a lot of help concerning valid C portable code.
|
||||
|
||||
3) Ajay K. Agrawal
|
||||
|
||||
Helped port the library to MSVC and spotted a few bugs and errors.
|
||||
|
||||
4) Brian Gladman
|
||||
|
||||
Wrote the AES and Serpent code used. Found a bug in the hash code for certain types of inputs.
|
||||
|
||||
5) Svante Seleborg
|
||||
|
||||
Submitted the "ampi.c" code as well as many suggestions on improving the readability of the source code.
|
||||
|
||||
6) Clay Culver
|
||||
|
||||
Submitted a fix for "rsa.c" which cleaned up some code. Submited some other fixes too. :-)
|
||||
Clay has helped find bugs in various pieces of code including the registry functions, base64 routines
|
||||
and the make process. He is also now the primary author of the libtomcrypt reference manual and has plan
|
||||
at making a HTML version.
|
||||
|
||||
7) Jason Klapste
|
||||
|
||||
Submitted fixes to the yarrow, hash, make process and test code as well as other subtle bug fixes. The
|
||||
yarrow code can now default to any cipher/hash that is left after you remove them from a build.
|
||||
|
||||
8) Dobes Vandermeer <dobes@smartt.com>
|
||||
|
||||
Submitted HMAC code that worked flawlessly out of the box... good job! Also submitted a MD4 routine.
|
||||
Submitted some modified DES code that was merged into the code base [using the libtomcrypt API]
|
||||
|
||||
9) Wayne Scott (wscott@bitmover.com)
|
||||
|
||||
Submitted base64 that complies with the RFC standards. Submitted some ideas to improve the RSA key generation
|
||||
as well.
|
||||
|
||||
10) Sky Schulz (sky@ogn.com)
|
||||
|
||||
Has submitted a set of ideas to improve the library and make it more attractive for professional users.
|
||||
|
||||
11) Mike Frysinger
|
||||
|
||||
Together with Clay came up with a more "unix friendly" makefile. Mike Frysinger has been keeping copies of
|
||||
the library for the Gentoo linux distribution.
|
||||
121
base64.c
Normal file
121
base64.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/* 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+/";
|
||||
|
||||
static const unsigned char map[256] = {
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
|
||||
255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
|
||||
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
|
||||
37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255 };
|
||||
|
||||
int base64_encode(const unsigned char *in, unsigned long len,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long i, len2, leven;
|
||||
unsigned char *p;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* valid output size ? */
|
||||
len2 = 4 * ((len + 2) / 3);
|
||||
if (*outlen < len2 + 1) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
p = out;
|
||||
leven = 3*(len / 3);
|
||||
for (i = 0; i < leven; i += 3) {
|
||||
*p++ = codes[(in[0] >> 2) & 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)
|
||||
{
|
||||
unsigned long t, x, y, z;
|
||||
unsigned char c;
|
||||
int g;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
g = 3;
|
||||
for (x = y = z = t = 0; x < len; x++) {
|
||||
c = map[in[x]&0xFF];
|
||||
if (c == 255) continue;
|
||||
if (c == 254) { c = 0; g--; }
|
||||
t = (t<<6)|c;
|
||||
if (++y == 4) {
|
||||
if (z + g > *outlen) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
out[z++] = (unsigned char)((t>>16)&255);
|
||||
if (g > 1) out[z++] = (unsigned char)((t>>8)&255);
|
||||
if (g > 2) out[z++] = (unsigned char)(t&255);
|
||||
y = t = 0;
|
||||
}
|
||||
}
|
||||
if (y != 0) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
*outlen = z;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
541
blowfish.c
Normal file
541
blowfish.c
Normal file
@@ -0,0 +1,541 @@
|
||||
/* 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 BLOWFISH
|
||||
|
||||
const struct _cipher_descriptor blowfish_desc =
|
||||
{
|
||||
"blowfish",
|
||||
0,
|
||||
8, 56, 8, 16,
|
||||
&blowfish_setup,
|
||||
&blowfish_ecb_encrypt,
|
||||
&blowfish_ecb_decrypt,
|
||||
&blowfish_test,
|
||||
&blowfish_keysize
|
||||
};
|
||||
|
||||
static const ulong32 ORIG_P[16 + 2] = {
|
||||
0x243F6A88UL, 0x85A308D3UL, 0x13198A2EUL, 0x03707344UL,
|
||||
0xA4093822UL, 0x299F31D0UL, 0x082EFA98UL, 0xEC4E6C89UL,
|
||||
0x452821E6UL, 0x38D01377UL, 0xBE5466CFUL, 0x34E90C6CUL,
|
||||
0xC0AC29B7UL, 0xC97C50DDUL, 0x3F84D5B5UL, 0xB5470917UL,
|
||||
0x9216D5D9UL, 0x8979FB1BUL
|
||||
};
|
||||
|
||||
static const ulong32 ORIG_S[4][256] = {
|
||||
{ 0xD1310BA6UL, 0x98DFB5ACUL, 0x2FFD72DBUL, 0xD01ADFB7UL,
|
||||
0xB8E1AFEDUL, 0x6A267E96UL, 0xBA7C9045UL, 0xF12C7F99UL,
|
||||
0x24A19947UL, 0xB3916CF7UL, 0x0801F2E2UL, 0x858EFC16UL,
|
||||
0x636920D8UL, 0x71574E69UL, 0xA458FEA3UL, 0xF4933D7EUL,
|
||||
0x0D95748FUL, 0x728EB658UL, 0x718BCD58UL, 0x82154AEEUL,
|
||||
0x7B54A41DUL, 0xC25A59B5UL, 0x9C30D539UL, 0x2AF26013UL,
|
||||
0xC5D1B023UL, 0x286085F0UL, 0xCA417918UL, 0xB8DB38EFUL,
|
||||
0x8E79DCB0UL, 0x603A180EUL, 0x6C9E0E8BUL, 0xB01E8A3EUL,
|
||||
0xD71577C1UL, 0xBD314B27UL, 0x78AF2FDAUL, 0x55605C60UL,
|
||||
0xE65525F3UL, 0xAA55AB94UL, 0x57489862UL, 0x63E81440UL,
|
||||
0x55CA396AUL, 0x2AAB10B6UL, 0xB4CC5C34UL, 0x1141E8CEUL,
|
||||
0xA15486AFUL, 0x7C72E993UL, 0xB3EE1411UL, 0x636FBC2AUL,
|
||||
0x2BA9C55DUL, 0x741831F6UL, 0xCE5C3E16UL, 0x9B87931EUL,
|
||||
0xAFD6BA33UL, 0x6C24CF5CUL, 0x7A325381UL, 0x28958677UL,
|
||||
0x3B8F4898UL, 0x6B4BB9AFUL, 0xC4BFE81BUL, 0x66282193UL,
|
||||
0x61D809CCUL, 0xFB21A991UL, 0x487CAC60UL, 0x5DEC8032UL,
|
||||
0xEF845D5DUL, 0xE98575B1UL, 0xDC262302UL, 0xEB651B88UL,
|
||||
0x23893E81UL, 0xD396ACC5UL, 0x0F6D6FF3UL, 0x83F44239UL,
|
||||
0x2E0B4482UL, 0xA4842004UL, 0x69C8F04AUL, 0x9E1F9B5EUL,
|
||||
0x21C66842UL, 0xF6E96C9AUL, 0x670C9C61UL, 0xABD388F0UL,
|
||||
0x6A51A0D2UL, 0xD8542F68UL, 0x960FA728UL, 0xAB5133A3UL,
|
||||
0x6EEF0B6CUL, 0x137A3BE4UL, 0xBA3BF050UL, 0x7EFB2A98UL,
|
||||
0xA1F1651DUL, 0x39AF0176UL, 0x66CA593EUL, 0x82430E88UL,
|
||||
0x8CEE8619UL, 0x456F9FB4UL, 0x7D84A5C3UL, 0x3B8B5EBEUL,
|
||||
0xE06F75D8UL, 0x85C12073UL, 0x401A449FUL, 0x56C16AA6UL,
|
||||
0x4ED3AA62UL, 0x363F7706UL, 0x1BFEDF72UL, 0x429B023DUL,
|
||||
0x37D0D724UL, 0xD00A1248UL, 0xDB0FEAD3UL, 0x49F1C09BUL,
|
||||
0x075372C9UL, 0x80991B7BUL, 0x25D479D8UL, 0xF6E8DEF7UL,
|
||||
0xE3FE501AUL, 0xB6794C3BUL, 0x976CE0BDUL, 0x04C006BAUL,
|
||||
0xC1A94FB6UL, 0x409F60C4UL, 0x5E5C9EC2UL, 0x196A2463UL,
|
||||
0x68FB6FAFUL, 0x3E6C53B5UL, 0x1339B2EBUL, 0x3B52EC6FUL,
|
||||
0x6DFC511FUL, 0x9B30952CUL, 0xCC814544UL, 0xAF5EBD09UL,
|
||||
0xBEE3D004UL, 0xDE334AFDUL, 0x660F2807UL, 0x192E4BB3UL,
|
||||
0xC0CBA857UL, 0x45C8740FUL, 0xD20B5F39UL, 0xB9D3FBDBUL,
|
||||
0x5579C0BDUL, 0x1A60320AUL, 0xD6A100C6UL, 0x402C7279UL,
|
||||
0x679F25FEUL, 0xFB1FA3CCUL, 0x8EA5E9F8UL, 0xDB3222F8UL,
|
||||
0x3C7516DFUL, 0xFD616B15UL, 0x2F501EC8UL, 0xAD0552ABUL,
|
||||
0x323DB5FAUL, 0xFD238760UL, 0x53317B48UL, 0x3E00DF82UL,
|
||||
0x9E5C57BBUL, 0xCA6F8CA0UL, 0x1A87562EUL, 0xDF1769DBUL,
|
||||
0xD542A8F6UL, 0x287EFFC3UL, 0xAC6732C6UL, 0x8C4F5573UL,
|
||||
0x695B27B0UL, 0xBBCA58C8UL, 0xE1FFA35DUL, 0xB8F011A0UL,
|
||||
0x10FA3D98UL, 0xFD2183B8UL, 0x4AFCB56CUL, 0x2DD1D35BUL,
|
||||
0x9A53E479UL, 0xB6F84565UL, 0xD28E49BCUL, 0x4BFB9790UL,
|
||||
0xE1DDF2DAUL, 0xA4CB7E33UL, 0x62FB1341UL, 0xCEE4C6E8UL,
|
||||
0xEF20CADAUL, 0x36774C01UL, 0xD07E9EFEUL, 0x2BF11FB4UL,
|
||||
0x95DBDA4DUL, 0xAE909198UL, 0xEAAD8E71UL, 0x6B93D5A0UL,
|
||||
0xD08ED1D0UL, 0xAFC725E0UL, 0x8E3C5B2FUL, 0x8E7594B7UL,
|
||||
0x8FF6E2FBUL, 0xF2122B64UL, 0x8888B812UL, 0x900DF01CUL,
|
||||
0x4FAD5EA0UL, 0x688FC31CUL, 0xD1CFF191UL, 0xB3A8C1ADUL,
|
||||
0x2F2F2218UL, 0xBE0E1777UL, 0xEA752DFEUL, 0x8B021FA1UL,
|
||||
0xE5A0CC0FUL, 0xB56F74E8UL, 0x18ACF3D6UL, 0xCE89E299UL,
|
||||
0xB4A84FE0UL, 0xFD13E0B7UL, 0x7CC43B81UL, 0xD2ADA8D9UL,
|
||||
0x165FA266UL, 0x80957705UL, 0x93CC7314UL, 0x211A1477UL,
|
||||
0xE6AD2065UL, 0x77B5FA86UL, 0xC75442F5UL, 0xFB9D35CFUL,
|
||||
0xEBCDAF0CUL, 0x7B3E89A0UL, 0xD6411BD3UL, 0xAE1E7E49UL,
|
||||
0x00250E2DUL, 0x2071B35EUL, 0x226800BBUL, 0x57B8E0AFUL,
|
||||
0x2464369BUL, 0xF009B91EUL, 0x5563911DUL, 0x59DFA6AAUL,
|
||||
0x78C14389UL, 0xD95A537FUL, 0x207D5BA2UL, 0x02E5B9C5UL,
|
||||
0x83260376UL, 0x6295CFA9UL, 0x11C81968UL, 0x4E734A41UL,
|
||||
0xB3472DCAUL, 0x7B14A94AUL, 0x1B510052UL, 0x9A532915UL,
|
||||
0xD60F573FUL, 0xBC9BC6E4UL, 0x2B60A476UL, 0x81E67400UL,
|
||||
0x08BA6FB5UL, 0x571BE91FUL, 0xF296EC6BUL, 0x2A0DD915UL,
|
||||
0xB6636521UL, 0xE7B9F9B6UL, 0xFF34052EUL, 0xC5855664UL,
|
||||
0x53B02D5DUL, 0xA99F8FA1UL, 0x08BA4799UL, 0x6E85076AUL },
|
||||
{ 0x4B7A70E9UL, 0xB5B32944UL, 0xDB75092EUL, 0xC4192623UL,
|
||||
0xAD6EA6B0UL, 0x49A7DF7DUL, 0x9CEE60B8UL, 0x8FEDB266UL,
|
||||
0xECAA8C71UL, 0x699A17FFUL, 0x5664526CUL, 0xC2B19EE1UL,
|
||||
0x193602A5UL, 0x75094C29UL, 0xA0591340UL, 0xE4183A3EUL,
|
||||
0x3F54989AUL, 0x5B429D65UL, 0x6B8FE4D6UL, 0x99F73FD6UL,
|
||||
0xA1D29C07UL, 0xEFE830F5UL, 0x4D2D38E6UL, 0xF0255DC1UL,
|
||||
0x4CDD2086UL, 0x8470EB26UL, 0x6382E9C6UL, 0x021ECC5EUL,
|
||||
0x09686B3FUL, 0x3EBAEFC9UL, 0x3C971814UL, 0x6B6A70A1UL,
|
||||
0x687F3584UL, 0x52A0E286UL, 0xB79C5305UL, 0xAA500737UL,
|
||||
0x3E07841CUL, 0x7FDEAE5CUL, 0x8E7D44ECUL, 0x5716F2B8UL,
|
||||
0xB03ADA37UL, 0xF0500C0DUL, 0xF01C1F04UL, 0x0200B3FFUL,
|
||||
0xAE0CF51AUL, 0x3CB574B2UL, 0x25837A58UL, 0xDC0921BDUL,
|
||||
0xD19113F9UL, 0x7CA92FF6UL, 0x94324773UL, 0x22F54701UL,
|
||||
0x3AE5E581UL, 0x37C2DADCUL, 0xC8B57634UL, 0x9AF3DDA7UL,
|
||||
0xA9446146UL, 0x0FD0030EUL, 0xECC8C73EUL, 0xA4751E41UL,
|
||||
0xE238CD99UL, 0x3BEA0E2FUL, 0x3280BBA1UL, 0x183EB331UL,
|
||||
0x4E548B38UL, 0x4F6DB908UL, 0x6F420D03UL, 0xF60A04BFUL,
|
||||
0x2CB81290UL, 0x24977C79UL, 0x5679B072UL, 0xBCAF89AFUL,
|
||||
0xDE9A771FUL, 0xD9930810UL, 0xB38BAE12UL, 0xDCCF3F2EUL,
|
||||
0x5512721FUL, 0x2E6B7124UL, 0x501ADDE6UL, 0x9F84CD87UL,
|
||||
0x7A584718UL, 0x7408DA17UL, 0xBC9F9ABCUL, 0xE94B7D8CUL,
|
||||
0xEC7AEC3AUL, 0xDB851DFAUL, 0x63094366UL, 0xC464C3D2UL,
|
||||
0xEF1C1847UL, 0x3215D908UL, 0xDD433B37UL, 0x24C2BA16UL,
|
||||
0x12A14D43UL, 0x2A65C451UL, 0x50940002UL, 0x133AE4DDUL,
|
||||
0x71DFF89EUL, 0x10314E55UL, 0x81AC77D6UL, 0x5F11199BUL,
|
||||
0x043556F1UL, 0xD7A3C76BUL, 0x3C11183BUL, 0x5924A509UL,
|
||||
0xF28FE6EDUL, 0x97F1FBFAUL, 0x9EBABF2CUL, 0x1E153C6EUL,
|
||||
0x86E34570UL, 0xEAE96FB1UL, 0x860E5E0AUL, 0x5A3E2AB3UL,
|
||||
0x771FE71CUL, 0x4E3D06FAUL, 0x2965DCB9UL, 0x99E71D0FUL,
|
||||
0x803E89D6UL, 0x5266C825UL, 0x2E4CC978UL, 0x9C10B36AUL,
|
||||
0xC6150EBAUL, 0x94E2EA78UL, 0xA5FC3C53UL, 0x1E0A2DF4UL,
|
||||
0xF2F74EA7UL, 0x361D2B3DUL, 0x1939260FUL, 0x19C27960UL,
|
||||
0x5223A708UL, 0xF71312B6UL, 0xEBADFE6EUL, 0xEAC31F66UL,
|
||||
0xE3BC4595UL, 0xA67BC883UL, 0xB17F37D1UL, 0x018CFF28UL,
|
||||
0xC332DDEFUL, 0xBE6C5AA5UL, 0x65582185UL, 0x68AB9802UL,
|
||||
0xEECEA50FUL, 0xDB2F953BUL, 0x2AEF7DADUL, 0x5B6E2F84UL,
|
||||
0x1521B628UL, 0x29076170UL, 0xECDD4775UL, 0x619F1510UL,
|
||||
0x13CCA830UL, 0xEB61BD96UL, 0x0334FE1EUL, 0xAA0363CFUL,
|
||||
0xB5735C90UL, 0x4C70A239UL, 0xD59E9E0BUL, 0xCBAADE14UL,
|
||||
0xEECC86BCUL, 0x60622CA7UL, 0x9CAB5CABUL, 0xB2F3846EUL,
|
||||
0x648B1EAFUL, 0x19BDF0CAUL, 0xA02369B9UL, 0x655ABB50UL,
|
||||
0x40685A32UL, 0x3C2AB4B3UL, 0x319EE9D5UL, 0xC021B8F7UL,
|
||||
0x9B540B19UL, 0x875FA099UL, 0x95F7997EUL, 0x623D7DA8UL,
|
||||
0xF837889AUL, 0x97E32D77UL, 0x11ED935FUL, 0x16681281UL,
|
||||
0x0E358829UL, 0xC7E61FD6UL, 0x96DEDFA1UL, 0x7858BA99UL,
|
||||
0x57F584A5UL, 0x1B227263UL, 0x9B83C3FFUL, 0x1AC24696UL,
|
||||
0xCDB30AEBUL, 0x532E3054UL, 0x8FD948E4UL, 0x6DBC3128UL,
|
||||
0x58EBF2EFUL, 0x34C6FFEAUL, 0xFE28ED61UL, 0xEE7C3C73UL,
|
||||
0x5D4A14D9UL, 0xE864B7E3UL, 0x42105D14UL, 0x203E13E0UL,
|
||||
0x45EEE2B6UL, 0xA3AAABEAUL, 0xDB6C4F15UL, 0xFACB4FD0UL,
|
||||
0xC742F442UL, 0xEF6ABBB5UL, 0x654F3B1DUL, 0x41CD2105UL,
|
||||
0xD81E799EUL, 0x86854DC7UL, 0xE44B476AUL, 0x3D816250UL,
|
||||
0xCF62A1F2UL, 0x5B8D2646UL, 0xFC8883A0UL, 0xC1C7B6A3UL,
|
||||
0x7F1524C3UL, 0x69CB7492UL, 0x47848A0BUL, 0x5692B285UL,
|
||||
0x095BBF00UL, 0xAD19489DUL, 0x1462B174UL, 0x23820E00UL,
|
||||
0x58428D2AUL, 0x0C55F5EAUL, 0x1DADF43EUL, 0x233F7061UL,
|
||||
0x3372F092UL, 0x8D937E41UL, 0xD65FECF1UL, 0x6C223BDBUL,
|
||||
0x7CDE3759UL, 0xCBEE7460UL, 0x4085F2A7UL, 0xCE77326EUL,
|
||||
0xA6078084UL, 0x19F8509EUL, 0xE8EFD855UL, 0x61D99735UL,
|
||||
0xA969A7AAUL, 0xC50C06C2UL, 0x5A04ABFCUL, 0x800BCADCUL,
|
||||
0x9E447A2EUL, 0xC3453484UL, 0xFDD56705UL, 0x0E1E9EC9UL,
|
||||
0xDB73DBD3UL, 0x105588CDUL, 0x675FDA79UL, 0xE3674340UL,
|
||||
0xC5C43465UL, 0x713E38D8UL, 0x3D28F89EUL, 0xF16DFF20UL,
|
||||
0x153E21E7UL, 0x8FB03D4AUL, 0xE6E39F2BUL, 0xDB83ADF7UL },
|
||||
{ 0xE93D5A68UL, 0x948140F7UL, 0xF64C261CUL, 0x94692934UL,
|
||||
0x411520F7UL, 0x7602D4F7UL, 0xBCF46B2EUL, 0xD4A20068UL,
|
||||
0xD4082471UL, 0x3320F46AUL, 0x43B7D4B7UL, 0x500061AFUL,
|
||||
0x1E39F62EUL, 0x97244546UL, 0x14214F74UL, 0xBF8B8840UL,
|
||||
0x4D95FC1DUL, 0x96B591AFUL, 0x70F4DDD3UL, 0x66A02F45UL,
|
||||
0xBFBC09ECUL, 0x03BD9785UL, 0x7FAC6DD0UL, 0x31CB8504UL,
|
||||
0x96EB27B3UL, 0x55FD3941UL, 0xDA2547E6UL, 0xABCA0A9AUL,
|
||||
0x28507825UL, 0x530429F4UL, 0x0A2C86DAUL, 0xE9B66DFBUL,
|
||||
0x68DC1462UL, 0xD7486900UL, 0x680EC0A4UL, 0x27A18DEEUL,
|
||||
0x4F3FFEA2UL, 0xE887AD8CUL, 0xB58CE006UL, 0x7AF4D6B6UL,
|
||||
0xAACE1E7CUL, 0xD3375FECUL, 0xCE78A399UL, 0x406B2A42UL,
|
||||
0x20FE9E35UL, 0xD9F385B9UL, 0xEE39D7ABUL, 0x3B124E8BUL,
|
||||
0x1DC9FAF7UL, 0x4B6D1856UL, 0x26A36631UL, 0xEAE397B2UL,
|
||||
0x3A6EFA74UL, 0xDD5B4332UL, 0x6841E7F7UL, 0xCA7820FBUL,
|
||||
0xFB0AF54EUL, 0xD8FEB397UL, 0x454056ACUL, 0xBA489527UL,
|
||||
0x55533A3AUL, 0x20838D87UL, 0xFE6BA9B7UL, 0xD096954BUL,
|
||||
0x55A867BCUL, 0xA1159A58UL, 0xCCA92963UL, 0x99E1DB33UL,
|
||||
0xA62A4A56UL, 0x3F3125F9UL, 0x5EF47E1CUL, 0x9029317CUL,
|
||||
0xFDF8E802UL, 0x04272F70UL, 0x80BB155CUL, 0x05282CE3UL,
|
||||
0x95C11548UL, 0xE4C66D22UL, 0x48C1133FUL, 0xC70F86DCUL,
|
||||
0x07F9C9EEUL, 0x41041F0FUL, 0x404779A4UL, 0x5D886E17UL,
|
||||
0x325F51EBUL, 0xD59BC0D1UL, 0xF2BCC18FUL, 0x41113564UL,
|
||||
0x257B7834UL, 0x602A9C60UL, 0xDFF8E8A3UL, 0x1F636C1BUL,
|
||||
0x0E12B4C2UL, 0x02E1329EUL, 0xAF664FD1UL, 0xCAD18115UL,
|
||||
0x6B2395E0UL, 0x333E92E1UL, 0x3B240B62UL, 0xEEBEB922UL,
|
||||
0x85B2A20EUL, 0xE6BA0D99UL, 0xDE720C8CUL, 0x2DA2F728UL,
|
||||
0xD0127845UL, 0x95B794FDUL, 0x647D0862UL, 0xE7CCF5F0UL,
|
||||
0x5449A36FUL, 0x877D48FAUL, 0xC39DFD27UL, 0xF33E8D1EUL,
|
||||
0x0A476341UL, 0x992EFF74UL, 0x3A6F6EABUL, 0xF4F8FD37UL,
|
||||
0xA812DC60UL, 0xA1EBDDF8UL, 0x991BE14CUL, 0xDB6E6B0DUL,
|
||||
0xC67B5510UL, 0x6D672C37UL, 0x2765D43BUL, 0xDCD0E804UL,
|
||||
0xF1290DC7UL, 0xCC00FFA3UL, 0xB5390F92UL, 0x690FED0BUL,
|
||||
0x667B9FFBUL, 0xCEDB7D9CUL, 0xA091CF0BUL, 0xD9155EA3UL,
|
||||
0xBB132F88UL, 0x515BAD24UL, 0x7B9479BFUL, 0x763BD6EBUL,
|
||||
0x37392EB3UL, 0xCC115979UL, 0x8026E297UL, 0xF42E312DUL,
|
||||
0x6842ADA7UL, 0xC66A2B3BUL, 0x12754CCCUL, 0x782EF11CUL,
|
||||
0x6A124237UL, 0xB79251E7UL, 0x06A1BBE6UL, 0x4BFB6350UL,
|
||||
0x1A6B1018UL, 0x11CAEDFAUL, 0x3D25BDD8UL, 0xE2E1C3C9UL,
|
||||
0x44421659UL, 0x0A121386UL, 0xD90CEC6EUL, 0xD5ABEA2AUL,
|
||||
0x64AF674EUL, 0xDA86A85FUL, 0xBEBFE988UL, 0x64E4C3FEUL,
|
||||
0x9DBC8057UL, 0xF0F7C086UL, 0x60787BF8UL, 0x6003604DUL,
|
||||
0xD1FD8346UL, 0xF6381FB0UL, 0x7745AE04UL, 0xD736FCCCUL,
|
||||
0x83426B33UL, 0xF01EAB71UL, 0xB0804187UL, 0x3C005E5FUL,
|
||||
0x77A057BEUL, 0xBDE8AE24UL, 0x55464299UL, 0xBF582E61UL,
|
||||
0x4E58F48FUL, 0xF2DDFDA2UL, 0xF474EF38UL, 0x8789BDC2UL,
|
||||
0x5366F9C3UL, 0xC8B38E74UL, 0xB475F255UL, 0x46FCD9B9UL,
|
||||
0x7AEB2661UL, 0x8B1DDF84UL, 0x846A0E79UL, 0x915F95E2UL,
|
||||
0x466E598EUL, 0x20B45770UL, 0x8CD55591UL, 0xC902DE4CUL,
|
||||
0xB90BACE1UL, 0xBB8205D0UL, 0x11A86248UL, 0x7574A99EUL,
|
||||
0xB77F19B6UL, 0xE0A9DC09UL, 0x662D09A1UL, 0xC4324633UL,
|
||||
0xE85A1F02UL, 0x09F0BE8CUL, 0x4A99A025UL, 0x1D6EFE10UL,
|
||||
0x1AB93D1DUL, 0x0BA5A4DFUL, 0xA186F20FUL, 0x2868F169UL,
|
||||
0xDCB7DA83UL, 0x573906FEUL, 0xA1E2CE9BUL, 0x4FCD7F52UL,
|
||||
0x50115E01UL, 0xA70683FAUL, 0xA002B5C4UL, 0x0DE6D027UL,
|
||||
0x9AF88C27UL, 0x773F8641UL, 0xC3604C06UL, 0x61A806B5UL,
|
||||
0xF0177A28UL, 0xC0F586E0UL, 0x006058AAUL, 0x30DC7D62UL,
|
||||
0x11E69ED7UL, 0x2338EA63UL, 0x53C2DD94UL, 0xC2C21634UL,
|
||||
0xBBCBEE56UL, 0x90BCB6DEUL, 0xEBFC7DA1UL, 0xCE591D76UL,
|
||||
0x6F05E409UL, 0x4B7C0188UL, 0x39720A3DUL, 0x7C927C24UL,
|
||||
0x86E3725FUL, 0x724D9DB9UL, 0x1AC15BB4UL, 0xD39EB8FCUL,
|
||||
0xED545578UL, 0x08FCA5B5UL, 0xD83D7CD3UL, 0x4DAD0FC4UL,
|
||||
0x1E50EF5EUL, 0xB161E6F8UL, 0xA28514D9UL, 0x6C51133CUL,
|
||||
0x6FD5C7E7UL, 0x56E14EC4UL, 0x362ABFCEUL, 0xDDC6C837UL,
|
||||
0xD79A3234UL, 0x92638212UL, 0x670EFA8EUL, 0x406000E0UL },
|
||||
{ 0x3A39CE37UL, 0xD3FAF5CFUL, 0xABC27737UL, 0x5AC52D1BUL,
|
||||
0x5CB0679EUL, 0x4FA33742UL, 0xD3822740UL, 0x99BC9BBEUL,
|
||||
0xD5118E9DUL, 0xBF0F7315UL, 0xD62D1C7EUL, 0xC700C47BUL,
|
||||
0xB78C1B6BUL, 0x21A19045UL, 0xB26EB1BEUL, 0x6A366EB4UL,
|
||||
0x5748AB2FUL, 0xBC946E79UL, 0xC6A376D2UL, 0x6549C2C8UL,
|
||||
0x530FF8EEUL, 0x468DDE7DUL, 0xD5730A1DUL, 0x4CD04DC6UL,
|
||||
0x2939BBDBUL, 0xA9BA4650UL, 0xAC9526E8UL, 0xBE5EE304UL,
|
||||
0xA1FAD5F0UL, 0x6A2D519AUL, 0x63EF8CE2UL, 0x9A86EE22UL,
|
||||
0xC089C2B8UL, 0x43242EF6UL, 0xA51E03AAUL, 0x9CF2D0A4UL,
|
||||
0x83C061BAUL, 0x9BE96A4DUL, 0x8FE51550UL, 0xBA645BD6UL,
|
||||
0x2826A2F9UL, 0xA73A3AE1UL, 0x4BA99586UL, 0xEF5562E9UL,
|
||||
0xC72FEFD3UL, 0xF752F7DAUL, 0x3F046F69UL, 0x77FA0A59UL,
|
||||
0x80E4A915UL, 0x87B08601UL, 0x9B09E6ADUL, 0x3B3EE593UL,
|
||||
0xE990FD5AUL, 0x9E34D797UL, 0x2CF0B7D9UL, 0x022B8B51UL,
|
||||
0x96D5AC3AUL, 0x017DA67DUL, 0xD1CF3ED6UL, 0x7C7D2D28UL,
|
||||
0x1F9F25CFUL, 0xADF2B89BUL, 0x5AD6B472UL, 0x5A88F54CUL,
|
||||
0xE029AC71UL, 0xE019A5E6UL, 0x47B0ACFDUL, 0xED93FA9BUL,
|
||||
0xE8D3C48DUL, 0x283B57CCUL, 0xF8D56629UL, 0x79132E28UL,
|
||||
0x785F0191UL, 0xED756055UL, 0xF7960E44UL, 0xE3D35E8CUL,
|
||||
0x15056DD4UL, 0x88F46DBAUL, 0x03A16125UL, 0x0564F0BDUL,
|
||||
0xC3EB9E15UL, 0x3C9057A2UL, 0x97271AECUL, 0xA93A072AUL,
|
||||
0x1B3F6D9BUL, 0x1E6321F5UL, 0xF59C66FBUL, 0x26DCF319UL,
|
||||
0x7533D928UL, 0xB155FDF5UL, 0x03563482UL, 0x8ABA3CBBUL,
|
||||
0x28517711UL, 0xC20AD9F8UL, 0xABCC5167UL, 0xCCAD925FUL,
|
||||
0x4DE81751UL, 0x3830DC8EUL, 0x379D5862UL, 0x9320F991UL,
|
||||
0xEA7A90C2UL, 0xFB3E7BCEUL, 0x5121CE64UL, 0x774FBE32UL,
|
||||
0xA8B6E37EUL, 0xC3293D46UL, 0x48DE5369UL, 0x6413E680UL,
|
||||
0xA2AE0810UL, 0xDD6DB224UL, 0x69852DFDUL, 0x09072166UL,
|
||||
0xB39A460AUL, 0x6445C0DDUL, 0x586CDECFUL, 0x1C20C8AEUL,
|
||||
0x5BBEF7DDUL, 0x1B588D40UL, 0xCCD2017FUL, 0x6BB4E3BBUL,
|
||||
0xDDA26A7EUL, 0x3A59FF45UL, 0x3E350A44UL, 0xBCB4CDD5UL,
|
||||
0x72EACEA8UL, 0xFA6484BBUL, 0x8D6612AEUL, 0xBF3C6F47UL,
|
||||
0xD29BE463UL, 0x542F5D9EUL, 0xAEC2771BUL, 0xF64E6370UL,
|
||||
0x740E0D8DUL, 0xE75B1357UL, 0xF8721671UL, 0xAF537D5DUL,
|
||||
0x4040CB08UL, 0x4EB4E2CCUL, 0x34D2466AUL, 0x0115AF84UL,
|
||||
0xE1B00428UL, 0x95983A1DUL, 0x06B89FB4UL, 0xCE6EA048UL,
|
||||
0x6F3F3B82UL, 0x3520AB82UL, 0x011A1D4BUL, 0x277227F8UL,
|
||||
0x611560B1UL, 0xE7933FDCUL, 0xBB3A792BUL, 0x344525BDUL,
|
||||
0xA08839E1UL, 0x51CE794BUL, 0x2F32C9B7UL, 0xA01FBAC9UL,
|
||||
0xE01CC87EUL, 0xBCC7D1F6UL, 0xCF0111C3UL, 0xA1E8AAC7UL,
|
||||
0x1A908749UL, 0xD44FBD9AUL, 0xD0DADECBUL, 0xD50ADA38UL,
|
||||
0x0339C32AUL, 0xC6913667UL, 0x8DF9317CUL, 0xE0B12B4FUL,
|
||||
0xF79E59B7UL, 0x43F5BB3AUL, 0xF2D519FFUL, 0x27D9459CUL,
|
||||
0xBF97222CUL, 0x15E6FC2AUL, 0x0F91FC71UL, 0x9B941525UL,
|
||||
0xFAE59361UL, 0xCEB69CEBUL, 0xC2A86459UL, 0x12BAA8D1UL,
|
||||
0xB6C1075EUL, 0xE3056A0CUL, 0x10D25065UL, 0xCB03A442UL,
|
||||
0xE0EC6E0EUL, 0x1698DB3BUL, 0x4C98A0BEUL, 0x3278E964UL,
|
||||
0x9F1F9532UL, 0xE0D392DFUL, 0xD3A0342BUL, 0x8971F21EUL,
|
||||
0x1B0A7441UL, 0x4BA3348CUL, 0xC5BE7120UL, 0xC37632D8UL,
|
||||
0xDF359F8DUL, 0x9B992F2EUL, 0xE60B6F47UL, 0x0FE3F11DUL,
|
||||
0xE54CDA54UL, 0x1EDAD891UL, 0xCE6279CFUL, 0xCD3E7E6FUL,
|
||||
0x1618B166UL, 0xFD2C1D05UL, 0x848FD2C5UL, 0xF6FB2299UL,
|
||||
0xF523F357UL, 0xA6327623UL, 0x93A83531UL, 0x56CCCD02UL,
|
||||
0xACF08162UL, 0x5A75EBB5UL, 0x6E163697UL, 0x88D273CCUL,
|
||||
0xDE966292UL, 0x81B949D0UL, 0x4C50901BUL, 0x71C65614UL,
|
||||
0xE6C6C7BDUL, 0x327A140AUL, 0x45E1D006UL, 0xC3F27B9AUL,
|
||||
0xC9AA53FDUL, 0x62A80F00UL, 0xBB25BFE2UL, 0x35BDD2F6UL,
|
||||
0x71126905UL, 0xB2040222UL, 0xB6CBCF7CUL, 0xCD769C2BUL,
|
||||
0x53113EC0UL, 0x1640E3D3UL, 0x38ABBD60UL, 0x2547ADF0UL,
|
||||
0xBA38209CUL, 0xF746CE76UL, 0x77AFA1C5UL, 0x20756060UL,
|
||||
0x85CBFE4EUL, 0x8AE88DD8UL, 0x7AAAF9B0UL, 0x4CF9AA7EUL,
|
||||
0x1948C25CUL, 0x02FB8A8CUL, 0x01C36AE4UL, 0xD6EBE1F9UL,
|
||||
0x90D4F869UL, 0xA65CDEA0UL, 0x3F09252DUL, 0xC208E69FUL,
|
||||
0xB74E6132UL, 0xCE77E25BUL, 0x578FDFE3UL, 0x3AC372E6UL }
|
||||
};
|
||||
|
||||
int blowfish_setup(const unsigned char *key, int keylen, int num_rounds,
|
||||
symmetric_key *skey)
|
||||
{
|
||||
ulong32 x, y, z, A;
|
||||
unsigned char B[8];
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
/* check key length */
|
||||
if (keylen < 8 || keylen > 56) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
/* check rounds */
|
||||
if (num_rounds != 0 && num_rounds != 16) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
/* load in key bytes (Supplied by David Hopwood) */
|
||||
for (x = y = 0; x < 18; x++) {
|
||||
A = 0;
|
||||
for (z = 0; z < 4; z++) {
|
||||
A = (A << 8) | ((ulong32)key[y++] & 255);
|
||||
if (y == (ulong32)keylen) {
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
skey->blowfish.K[x] = ORIG_P[x] ^ A;
|
||||
}
|
||||
|
||||
/* copy sboxes */
|
||||
for (x = 0; x < 4; x++) {
|
||||
for (y = 0; y < 256; y++) {
|
||||
skey->blowfish.S[x][y] = ORIG_S[x][y];
|
||||
}
|
||||
}
|
||||
|
||||
/* encrypt K array */
|
||||
for (x = 0; x < 8; x++) {
|
||||
B[x] = 0;
|
||||
}
|
||||
|
||||
for (x = 0; x < 18; x += 2) {
|
||||
/* encrypt it */
|
||||
blowfish_ecb_encrypt(B, B, skey);
|
||||
/* copy it */
|
||||
LOAD32H(skey->blowfish.K[x], &B[0]);
|
||||
LOAD32H(skey->blowfish.K[x+1], &B[4]);
|
||||
}
|
||||
|
||||
/* encrypt S array */
|
||||
for (x = 0; x < 4; x++) {
|
||||
for (y = 0; y < 256; y += 2) {
|
||||
/* encrypt it */
|
||||
blowfish_ecb_encrypt(B, B, skey);
|
||||
/* copy it */
|
||||
LOAD32H(skey->blowfish.S[x][y], &B[0]);
|
||||
LOAD32H(skey->blowfish.S[x][y+1], &B[4]);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(B, sizeof(B));
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifndef __GNUC__
|
||||
#define F(x) ((S1[byte(x,3)] + S2[byte(x,2)]) ^ S3[byte(x,1)]) + S4[byte(x,0)]
|
||||
#else
|
||||
#define F(x) ((key->blowfish.S[0][byte(x,3)] + key->blowfish.S[1][byte(x,2)]) ^ key->blowfish.S[2][byte(x,1)]) + key->blowfish.S[3][byte(x,0)]
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#else
|
||||
void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
ulong32 L, R;
|
||||
int r;
|
||||
#ifndef __GNUC__
|
||||
ulong32 *S1, *S2, *S3, *S4;
|
||||
#endif
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
#ifndef __GNUC__
|
||||
S1 = key->blowfish.S[0];
|
||||
S2 = key->blowfish.S[1];
|
||||
S3 = key->blowfish.S[2];
|
||||
S4 = key->blowfish.S[3];
|
||||
#endif
|
||||
|
||||
/* load it */
|
||||
LOAD32H(L, &pt[0]);
|
||||
LOAD32H(R, &pt[4]);
|
||||
|
||||
/* do 16 rounds */
|
||||
for (r = 0; r < 16; ) {
|
||||
L ^= key->blowfish.K[r++]; R ^= F(L);
|
||||
R ^= key->blowfish.K[r++]; L ^= F(R);
|
||||
L ^= key->blowfish.K[r++]; R ^= F(L);
|
||||
R ^= key->blowfish.K[r++]; L ^= F(R);
|
||||
}
|
||||
|
||||
/* last keying */
|
||||
R ^= key->blowfish.K[17];
|
||||
L ^= key->blowfish.K[16];
|
||||
|
||||
/* store */
|
||||
STORE32H(R, &ct[0]);
|
||||
STORE32H(L, &ct[4]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
{
|
||||
_blowfish_ecb_encrypt(pt, ct, key);
|
||||
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#else
|
||||
void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
ulong32 L, R;
|
||||
int r;
|
||||
#ifndef __GNUC__
|
||||
ulong32 *S1, *S2, *S3, *S4;
|
||||
#endif
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
#ifndef __GNUC__
|
||||
S1 = key->blowfish.S[0];
|
||||
S2 = key->blowfish.S[1];
|
||||
S3 = key->blowfish.S[2];
|
||||
S4 = key->blowfish.S[3];
|
||||
#endif
|
||||
|
||||
/* load it */
|
||||
LOAD32H(R, &ct[0]);
|
||||
LOAD32H(L, &ct[4]);
|
||||
|
||||
/* undo last keying */
|
||||
R ^= key->blowfish.K[17];
|
||||
L ^= key->blowfish.K[16];
|
||||
|
||||
/* do 16 rounds */
|
||||
for (r = 15; r > 0; ) {
|
||||
L ^= F(R); R ^= key->blowfish.K[r--];
|
||||
R ^= F(L); L ^= key->blowfish.K[r--];
|
||||
L ^= F(R); R ^= key->blowfish.K[r--];
|
||||
R ^= F(L); L ^= key->blowfish.K[r--];
|
||||
}
|
||||
|
||||
/* store */
|
||||
STORE32H(L, &pt[0]);
|
||||
STORE32H(R, &pt[4]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
{
|
||||
_blowfish_ecb_decrypt(ct, pt, key);
|
||||
burn_stack(sizeof(ulong32) * 2 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int blowfish_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
int err;
|
||||
symmetric_key key;
|
||||
static const struct {
|
||||
unsigned char key[8], pt[8], ct[8];
|
||||
} tests[] = {
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}
|
||||
},
|
||||
{
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
{ 0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A}
|
||||
},
|
||||
{
|
||||
{ 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
{ 0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}
|
||||
}
|
||||
};
|
||||
unsigned char tmp[2][8];
|
||||
int x, y;
|
||||
|
||||
for (x = 0; x < (int)(sizeof(tests) / sizeof(tests[0])); x++) {
|
||||
/* setup key */
|
||||
if ((err = blowfish_setup(tests[x].key, 8, 16, &key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* encrypt and decrypt */
|
||||
blowfish_ecb_encrypt(tests[x].pt, tmp[0], &key);
|
||||
blowfish_ecb_decrypt(tmp[0], tmp[1], &key);
|
||||
|
||||
/* compare */
|
||||
if ((memcmp(tmp[0], tests[x].ct, 8) != 0) || (memcmp(tmp[1], tests[x].pt, 8) != 0)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
|
||||
for (y = 0; y < 8; y++) tmp[0][y] = 0;
|
||||
for (y = 0; y < 1000; y++) blowfish_ecb_encrypt(tmp[0], tmp[0], &key);
|
||||
for (y = 0; y < 1000; y++) blowfish_ecb_decrypt(tmp[0], tmp[0], &key);
|
||||
for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int blowfish_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
|
||||
if (*desired_keysize < 8) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
} else if (*desired_keysize > 56) {
|
||||
*desired_keysize = 56;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
21
burn_stack.c
Normal file
21
burn_stack.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/* 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"
|
||||
|
||||
void burn_stack(unsigned long len)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
zeromem(buf, sizeof(buf));
|
||||
if (len > (unsigned long)sizeof(buf))
|
||||
burn_stack(len - sizeof(buf));
|
||||
}
|
||||
|
||||
|
||||
669
cast5.c
Normal file
669
cast5.c
Normal file
@@ -0,0 +1,669 @@
|
||||
/* 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
|
||||
*/
|
||||
/* Implementation of CAST5 (RFC 2144) by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef CAST5
|
||||
|
||||
const struct _cipher_descriptor cast5_desc = {
|
||||
"cast5",
|
||||
15,
|
||||
5, 16, 8, 16,
|
||||
&cast5_setup,
|
||||
&cast5_ecb_encrypt,
|
||||
&cast5_ecb_decrypt,
|
||||
&cast5_test,
|
||||
&cast5_keysize
|
||||
};
|
||||
|
||||
static const ulong32 S1[256] = {
|
||||
0x30fb40d4UL, 0x9fa0ff0bUL, 0x6beccd2fUL, 0x3f258c7aUL, 0x1e213f2fUL, 0x9c004dd3UL,
|
||||
0x6003e540UL, 0xcf9fc949UL, 0xbfd4af27UL, 0x88bbbdb5UL, 0xe2034090UL, 0x98d09675UL,
|
||||
0x6e63a0e0UL, 0x15c361d2UL, 0xc2e7661dUL, 0x22d4ff8eUL, 0x28683b6fUL, 0xc07fd059UL,
|
||||
0xff2379c8UL, 0x775f50e2UL, 0x43c340d3UL, 0xdf2f8656UL, 0x887ca41aUL, 0xa2d2bd2dUL,
|
||||
0xa1c9e0d6UL, 0x346c4819UL, 0x61b76d87UL, 0x22540f2fUL, 0x2abe32e1UL, 0xaa54166bUL,
|
||||
0x22568e3aUL, 0xa2d341d0UL, 0x66db40c8UL, 0xa784392fUL, 0x004dff2fUL, 0x2db9d2deUL,
|
||||
0x97943facUL, 0x4a97c1d8UL, 0x527644b7UL, 0xb5f437a7UL, 0xb82cbaefUL, 0xd751d159UL,
|
||||
0x6ff7f0edUL, 0x5a097a1fUL, 0x827b68d0UL, 0x90ecf52eUL, 0x22b0c054UL, 0xbc8e5935UL,
|
||||
0x4b6d2f7fUL, 0x50bb64a2UL, 0xd2664910UL, 0xbee5812dUL, 0xb7332290UL, 0xe93b159fUL,
|
||||
0xb48ee411UL, 0x4bff345dUL, 0xfd45c240UL, 0xad31973fUL, 0xc4f6d02eUL, 0x55fc8165UL,
|
||||
0xd5b1caadUL, 0xa1ac2daeUL, 0xa2d4b76dUL, 0xc19b0c50UL, 0x882240f2UL, 0x0c6e4f38UL,
|
||||
0xa4e4bfd7UL, 0x4f5ba272UL, 0x564c1d2fUL, 0xc59c5319UL, 0xb949e354UL, 0xb04669feUL,
|
||||
0xb1b6ab8aUL, 0xc71358ddUL, 0x6385c545UL, 0x110f935dUL, 0x57538ad5UL, 0x6a390493UL,
|
||||
0xe63d37e0UL, 0x2a54f6b3UL, 0x3a787d5fUL, 0x6276a0b5UL, 0x19a6fcdfUL, 0x7a42206aUL,
|
||||
0x29f9d4d5UL, 0xf61b1891UL, 0xbb72275eUL, 0xaa508167UL, 0x38901091UL, 0xc6b505ebUL,
|
||||
0x84c7cb8cUL, 0x2ad75a0fUL, 0x874a1427UL, 0xa2d1936bUL, 0x2ad286afUL, 0xaa56d291UL,
|
||||
0xd7894360UL, 0x425c750dUL, 0x93b39e26UL, 0x187184c9UL, 0x6c00b32dUL, 0x73e2bb14UL,
|
||||
0xa0bebc3cUL, 0x54623779UL, 0x64459eabUL, 0x3f328b82UL, 0x7718cf82UL, 0x59a2cea6UL,
|
||||
0x04ee002eUL, 0x89fe78e6UL, 0x3fab0950UL, 0x325ff6c2UL, 0x81383f05UL, 0x6963c5c8UL,
|
||||
0x76cb5ad6UL, 0xd49974c9UL, 0xca180dcfUL, 0x380782d5UL, 0xc7fa5cf6UL, 0x8ac31511UL,
|
||||
0x35e79e13UL, 0x47da91d0UL, 0xf40f9086UL, 0xa7e2419eUL, 0x31366241UL, 0x051ef495UL,
|
||||
0xaa573b04UL, 0x4a805d8dUL, 0x548300d0UL, 0x00322a3cUL, 0xbf64cddfUL, 0xba57a68eUL,
|
||||
0x75c6372bUL, 0x50afd341UL, 0xa7c13275UL, 0x915a0bf5UL, 0x6b54bfabUL, 0x2b0b1426UL,
|
||||
0xab4cc9d7UL, 0x449ccd82UL, 0xf7fbf265UL, 0xab85c5f3UL, 0x1b55db94UL, 0xaad4e324UL,
|
||||
0xcfa4bd3fUL, 0x2deaa3e2UL, 0x9e204d02UL, 0xc8bd25acUL, 0xeadf55b3UL, 0xd5bd9e98UL,
|
||||
0xe31231b2UL, 0x2ad5ad6cUL, 0x954329deUL, 0xadbe4528UL, 0xd8710f69UL, 0xaa51c90fUL,
|
||||
0xaa786bf6UL, 0x22513f1eUL, 0xaa51a79bUL, 0x2ad344ccUL, 0x7b5a41f0UL, 0xd37cfbadUL,
|
||||
0x1b069505UL, 0x41ece491UL, 0xb4c332e6UL, 0x032268d4UL, 0xc9600accUL, 0xce387e6dUL,
|
||||
0xbf6bb16cUL, 0x6a70fb78UL, 0x0d03d9c9UL, 0xd4df39deUL, 0xe01063daUL, 0x4736f464UL,
|
||||
0x5ad328d8UL, 0xb347cc96UL, 0x75bb0fc3UL, 0x98511bfbUL, 0x4ffbcc35UL, 0xb58bcf6aUL,
|
||||
0xe11f0abcUL, 0xbfc5fe4aUL, 0xa70aec10UL, 0xac39570aUL, 0x3f04442fUL, 0x6188b153UL,
|
||||
0xe0397a2eUL, 0x5727cb79UL, 0x9ceb418fUL, 0x1cacd68dUL, 0x2ad37c96UL, 0x0175cb9dUL,
|
||||
0xc69dff09UL, 0xc75b65f0UL, 0xd9db40d8UL, 0xec0e7779UL, 0x4744ead4UL, 0xb11c3274UL,
|
||||
0xdd24cb9eUL, 0x7e1c54bdUL, 0xf01144f9UL, 0xd2240eb1UL, 0x9675b3fdUL, 0xa3ac3755UL,
|
||||
0xd47c27afUL, 0x51c85f4dUL, 0x56907596UL, 0xa5bb15e6UL, 0x580304f0UL, 0xca042cf1UL,
|
||||
0x011a37eaUL, 0x8dbfaadbUL, 0x35ba3e4aUL, 0x3526ffa0UL, 0xc37b4d09UL, 0xbc306ed9UL,
|
||||
0x98a52666UL, 0x5648f725UL, 0xff5e569dUL, 0x0ced63d0UL, 0x7c63b2cfUL, 0x700b45e1UL,
|
||||
0xd5ea50f1UL, 0x85a92872UL, 0xaf1fbda7UL, 0xd4234870UL, 0xa7870bf3UL, 0x2d3b4d79UL,
|
||||
0x42e04198UL, 0x0cd0ede7UL, 0x26470db8UL, 0xf881814cUL, 0x474d6ad7UL, 0x7c0c5e5cUL,
|
||||
0xd1231959UL, 0x381b7298UL, 0xf5d2f4dbUL, 0xab838653UL, 0x6e2f1e23UL, 0x83719c9eUL,
|
||||
0xbd91e046UL, 0x9a56456eUL, 0xdc39200cUL, 0x20c8c571UL, 0x962bda1cUL, 0xe1e696ffUL,
|
||||
0xb141ab08UL, 0x7cca89b9UL, 0x1a69e783UL, 0x02cc4843UL, 0xa2f7c579UL, 0x429ef47dUL,
|
||||
0x427b169cUL, 0x5ac9f049UL, 0xdd8f0f00UL, 0x5c8165bfUL};
|
||||
|
||||
static const ulong32 S2[256] = {
|
||||
0x1f201094UL, 0xef0ba75bUL, 0x69e3cf7eUL, 0x393f4380UL, 0xfe61cf7aUL, 0xeec5207aUL,
|
||||
0x55889c94UL, 0x72fc0651UL, 0xada7ef79UL, 0x4e1d7235UL, 0xd55a63ceUL, 0xde0436baUL,
|
||||
0x99c430efUL, 0x5f0c0794UL, 0x18dcdb7dUL, 0xa1d6eff3UL, 0xa0b52f7bUL, 0x59e83605UL,
|
||||
0xee15b094UL, 0xe9ffd909UL, 0xdc440086UL, 0xef944459UL, 0xba83ccb3UL, 0xe0c3cdfbUL,
|
||||
0xd1da4181UL, 0x3b092ab1UL, 0xf997f1c1UL, 0xa5e6cf7bUL, 0x01420ddbUL, 0xe4e7ef5bUL,
|
||||
0x25a1ff41UL, 0xe180f806UL, 0x1fc41080UL, 0x179bee7aUL, 0xd37ac6a9UL, 0xfe5830a4UL,
|
||||
0x98de8b7fUL, 0x77e83f4eUL, 0x79929269UL, 0x24fa9f7bUL, 0xe113c85bUL, 0xacc40083UL,
|
||||
0xd7503525UL, 0xf7ea615fUL, 0x62143154UL, 0x0d554b63UL, 0x5d681121UL, 0xc866c359UL,
|
||||
0x3d63cf73UL, 0xcee234c0UL, 0xd4d87e87UL, 0x5c672b21UL, 0x071f6181UL, 0x39f7627fUL,
|
||||
0x361e3084UL, 0xe4eb573bUL, 0x602f64a4UL, 0xd63acd9cUL, 0x1bbc4635UL, 0x9e81032dUL,
|
||||
0x2701f50cUL, 0x99847ab4UL, 0xa0e3df79UL, 0xba6cf38cUL, 0x10843094UL, 0x2537a95eUL,
|
||||
0xf46f6ffeUL, 0xa1ff3b1fUL, 0x208cfb6aUL, 0x8f458c74UL, 0xd9e0a227UL, 0x4ec73a34UL,
|
||||
0xfc884f69UL, 0x3e4de8dfUL, 0xef0e0088UL, 0x3559648dUL, 0x8a45388cUL, 0x1d804366UL,
|
||||
0x721d9bfdUL, 0xa58684bbUL, 0xe8256333UL, 0x844e8212UL, 0x128d8098UL, 0xfed33fb4UL,
|
||||
0xce280ae1UL, 0x27e19ba5UL, 0xd5a6c252UL, 0xe49754bdUL, 0xc5d655ddUL, 0xeb667064UL,
|
||||
0x77840b4dUL, 0xa1b6a801UL, 0x84db26a9UL, 0xe0b56714UL, 0x21f043b7UL, 0xe5d05860UL,
|
||||
0x54f03084UL, 0x066ff472UL, 0xa31aa153UL, 0xdadc4755UL, 0xb5625dbfUL, 0x68561be6UL,
|
||||
0x83ca6b94UL, 0x2d6ed23bUL, 0xeccf01dbUL, 0xa6d3d0baUL, 0xb6803d5cUL, 0xaf77a709UL,
|
||||
0x33b4a34cUL, 0x397bc8d6UL, 0x5ee22b95UL, 0x5f0e5304UL, 0x81ed6f61UL, 0x20e74364UL,
|
||||
0xb45e1378UL, 0xde18639bUL, 0x881ca122UL, 0xb96726d1UL, 0x8049a7e8UL, 0x22b7da7bUL,
|
||||
0x5e552d25UL, 0x5272d237UL, 0x79d2951cUL, 0xc60d894cUL, 0x488cb402UL, 0x1ba4fe5bUL,
|
||||
0xa4b09f6bUL, 0x1ca815cfUL, 0xa20c3005UL, 0x8871df63UL, 0xb9de2fcbUL, 0x0cc6c9e9UL,
|
||||
0x0beeff53UL, 0xe3214517UL, 0xb4542835UL, 0x9f63293cUL, 0xee41e729UL, 0x6e1d2d7cUL,
|
||||
0x50045286UL, 0x1e6685f3UL, 0xf33401c6UL, 0x30a22c95UL, 0x31a70850UL, 0x60930f13UL,
|
||||
0x73f98417UL, 0xa1269859UL, 0xec645c44UL, 0x52c877a9UL, 0xcdff33a6UL, 0xa02b1741UL,
|
||||
0x7cbad9a2UL, 0x2180036fUL, 0x50d99c08UL, 0xcb3f4861UL, 0xc26bd765UL, 0x64a3f6abUL,
|
||||
0x80342676UL, 0x25a75e7bUL, 0xe4e6d1fcUL, 0x20c710e6UL, 0xcdf0b680UL, 0x17844d3bUL,
|
||||
0x31eef84dUL, 0x7e0824e4UL, 0x2ccb49ebUL, 0x846a3baeUL, 0x8ff77888UL, 0xee5d60f6UL,
|
||||
0x7af75673UL, 0x2fdd5cdbUL, 0xa11631c1UL, 0x30f66f43UL, 0xb3faec54UL, 0x157fd7faUL,
|
||||
0xef8579ccUL, 0xd152de58UL, 0xdb2ffd5eUL, 0x8f32ce19UL, 0x306af97aUL, 0x02f03ef8UL,
|
||||
0x99319ad5UL, 0xc242fa0fUL, 0xa7e3ebb0UL, 0xc68e4906UL, 0xb8da230cUL, 0x80823028UL,
|
||||
0xdcdef3c8UL, 0xd35fb171UL, 0x088a1bc8UL, 0xbec0c560UL, 0x61a3c9e8UL, 0xbca8f54dUL,
|
||||
0xc72feffaUL, 0x22822e99UL, 0x82c570b4UL, 0xd8d94e89UL, 0x8b1c34bcUL, 0x301e16e6UL,
|
||||
0x273be979UL, 0xb0ffeaa6UL, 0x61d9b8c6UL, 0x00b24869UL, 0xb7ffce3fUL, 0x08dc283bUL,
|
||||
0x43daf65aUL, 0xf7e19798UL, 0x7619b72fUL, 0x8f1c9ba4UL, 0xdc8637a0UL, 0x16a7d3b1UL,
|
||||
0x9fc393b7UL, 0xa7136eebUL, 0xc6bcc63eUL, 0x1a513742UL, 0xef6828bcUL, 0x520365d6UL,
|
||||
0x2d6a77abUL, 0x3527ed4bUL, 0x821fd216UL, 0x095c6e2eUL, 0xdb92f2fbUL, 0x5eea29cbUL,
|
||||
0x145892f5UL, 0x91584f7fUL, 0x5483697bUL, 0x2667a8ccUL, 0x85196048UL, 0x8c4baceaUL,
|
||||
0x833860d4UL, 0x0d23e0f9UL, 0x6c387e8aUL, 0x0ae6d249UL, 0xb284600cUL, 0xd835731dUL,
|
||||
0xdcb1c647UL, 0xac4c56eaUL, 0x3ebd81b3UL, 0x230eabb0UL, 0x6438bc87UL, 0xf0b5b1faUL,
|
||||
0x8f5ea2b3UL, 0xfc184642UL, 0x0a036b7aUL, 0x4fb089bdUL, 0x649da589UL, 0xa345415eUL,
|
||||
0x5c038323UL, 0x3e5d3bb9UL, 0x43d79572UL, 0x7e6dd07cUL, 0x06dfdf1eUL, 0x6c6cc4efUL,
|
||||
0x7160a539UL, 0x73bfbe70UL, 0x83877605UL, 0x4523ecf1UL};
|
||||
|
||||
static const ulong32 S3[256] = {
|
||||
0x8defc240UL, 0x25fa5d9fUL, 0xeb903dbfUL, 0xe810c907UL, 0x47607fffUL, 0x369fe44bUL,
|
||||
0x8c1fc644UL, 0xaececa90UL, 0xbeb1f9bfUL, 0xeefbcaeaUL, 0xe8cf1950UL, 0x51df07aeUL,
|
||||
0x920e8806UL, 0xf0ad0548UL, 0xe13c8d83UL, 0x927010d5UL, 0x11107d9fUL, 0x07647db9UL,
|
||||
0xb2e3e4d4UL, 0x3d4f285eUL, 0xb9afa820UL, 0xfade82e0UL, 0xa067268bUL, 0x8272792eUL,
|
||||
0x553fb2c0UL, 0x489ae22bUL, 0xd4ef9794UL, 0x125e3fbcUL, 0x21fffceeUL, 0x825b1bfdUL,
|
||||
0x9255c5edUL, 0x1257a240UL, 0x4e1a8302UL, 0xbae07fffUL, 0x528246e7UL, 0x8e57140eUL,
|
||||
0x3373f7bfUL, 0x8c9f8188UL, 0xa6fc4ee8UL, 0xc982b5a5UL, 0xa8c01db7UL, 0x579fc264UL,
|
||||
0x67094f31UL, 0xf2bd3f5fUL, 0x40fff7c1UL, 0x1fb78dfcUL, 0x8e6bd2c1UL, 0x437be59bUL,
|
||||
0x99b03dbfUL, 0xb5dbc64bUL, 0x638dc0e6UL, 0x55819d99UL, 0xa197c81cUL, 0x4a012d6eUL,
|
||||
0xc5884a28UL, 0xccc36f71UL, 0xb843c213UL, 0x6c0743f1UL, 0x8309893cUL, 0x0feddd5fUL,
|
||||
0x2f7fe850UL, 0xd7c07f7eUL, 0x02507fbfUL, 0x5afb9a04UL, 0xa747d2d0UL, 0x1651192eUL,
|
||||
0xaf70bf3eUL, 0x58c31380UL, 0x5f98302eUL, 0x727cc3c4UL, 0x0a0fb402UL, 0x0f7fef82UL,
|
||||
0x8c96fdadUL, 0x5d2c2aaeUL, 0x8ee99a49UL, 0x50da88b8UL, 0x8427f4a0UL, 0x1eac5790UL,
|
||||
0x796fb449UL, 0x8252dc15UL, 0xefbd7d9bUL, 0xa672597dUL, 0xada840d8UL, 0x45f54504UL,
|
||||
0xfa5d7403UL, 0xe83ec305UL, 0x4f91751aUL, 0x925669c2UL, 0x23efe941UL, 0xa903f12eUL,
|
||||
0x60270df2UL, 0x0276e4b6UL, 0x94fd6574UL, 0x927985b2UL, 0x8276dbcbUL, 0x02778176UL,
|
||||
0xf8af918dUL, 0x4e48f79eUL, 0x8f616ddfUL, 0xe29d840eUL, 0x842f7d83UL, 0x340ce5c8UL,
|
||||
0x96bbb682UL, 0x93b4b148UL, 0xef303cabUL, 0x984faf28UL, 0x779faf9bUL, 0x92dc560dUL,
|
||||
0x224d1e20UL, 0x8437aa88UL, 0x7d29dc96UL, 0x2756d3dcUL, 0x8b907ceeUL, 0xb51fd240UL,
|
||||
0xe7c07ce3UL, 0xe566b4a1UL, 0xc3e9615eUL, 0x3cf8209dUL, 0x6094d1e3UL, 0xcd9ca341UL,
|
||||
0x5c76460eUL, 0x00ea983bUL, 0xd4d67881UL, 0xfd47572cUL, 0xf76cedd9UL, 0xbda8229cUL,
|
||||
0x127dadaaUL, 0x438a074eUL, 0x1f97c090UL, 0x081bdb8aUL, 0x93a07ebeUL, 0xb938ca15UL,
|
||||
0x97b03cffUL, 0x3dc2c0f8UL, 0x8d1ab2ecUL, 0x64380e51UL, 0x68cc7bfbUL, 0xd90f2788UL,
|
||||
0x12490181UL, 0x5de5ffd4UL, 0xdd7ef86aUL, 0x76a2e214UL, 0xb9a40368UL, 0x925d958fUL,
|
||||
0x4b39fffaUL, 0xba39aee9UL, 0xa4ffd30bUL, 0xfaf7933bUL, 0x6d498623UL, 0x193cbcfaUL,
|
||||
0x27627545UL, 0x825cf47aUL, 0x61bd8ba0UL, 0xd11e42d1UL, 0xcead04f4UL, 0x127ea392UL,
|
||||
0x10428db7UL, 0x8272a972UL, 0x9270c4a8UL, 0x127de50bUL, 0x285ba1c8UL, 0x3c62f44fUL,
|
||||
0x35c0eaa5UL, 0xe805d231UL, 0x428929fbUL, 0xb4fcdf82UL, 0x4fb66a53UL, 0x0e7dc15bUL,
|
||||
0x1f081fabUL, 0x108618aeUL, 0xfcfd086dUL, 0xf9ff2889UL, 0x694bcc11UL, 0x236a5caeUL,
|
||||
0x12deca4dUL, 0x2c3f8cc5UL, 0xd2d02dfeUL, 0xf8ef5896UL, 0xe4cf52daUL, 0x95155b67UL,
|
||||
0x494a488cUL, 0xb9b6a80cUL, 0x5c8f82bcUL, 0x89d36b45UL, 0x3a609437UL, 0xec00c9a9UL,
|
||||
0x44715253UL, 0x0a874b49UL, 0xd773bc40UL, 0x7c34671cUL, 0x02717ef6UL, 0x4feb5536UL,
|
||||
0xa2d02fffUL, 0xd2bf60c4UL, 0xd43f03c0UL, 0x50b4ef6dUL, 0x07478cd1UL, 0x006e1888UL,
|
||||
0xa2e53f55UL, 0xb9e6d4bcUL, 0xa2048016UL, 0x97573833UL, 0xd7207d67UL, 0xde0f8f3dUL,
|
||||
0x72f87b33UL, 0xabcc4f33UL, 0x7688c55dUL, 0x7b00a6b0UL, 0x947b0001UL, 0x570075d2UL,
|
||||
0xf9bb88f8UL, 0x8942019eUL, 0x4264a5ffUL, 0x856302e0UL, 0x72dbd92bUL, 0xee971b69UL,
|
||||
0x6ea22fdeUL, 0x5f08ae2bUL, 0xaf7a616dUL, 0xe5c98767UL, 0xcf1febd2UL, 0x61efc8c2UL,
|
||||
0xf1ac2571UL, 0xcc8239c2UL, 0x67214cb8UL, 0xb1e583d1UL, 0xb7dc3e62UL, 0x7f10bdceUL,
|
||||
0xf90a5c38UL, 0x0ff0443dUL, 0x606e6dc6UL, 0x60543a49UL, 0x5727c148UL, 0x2be98a1dUL,
|
||||
0x8ab41738UL, 0x20e1be24UL, 0xaf96da0fUL, 0x68458425UL, 0x99833be5UL, 0x600d457dUL,
|
||||
0x282f9350UL, 0x8334b362UL, 0xd91d1120UL, 0x2b6d8da0UL, 0x642b1e31UL, 0x9c305a00UL,
|
||||
0x52bce688UL, 0x1b03588aUL, 0xf7baefd5UL, 0x4142ed9cUL, 0xa4315c11UL, 0x83323ec5UL,
|
||||
0xdfef4636UL, 0xa133c501UL, 0xe9d3531cUL, 0xee353783UL};
|
||||
|
||||
static const ulong32 S4[256] = {
|
||||
0x9db30420UL, 0x1fb6e9deUL, 0xa7be7befUL, 0xd273a298UL, 0x4a4f7bdbUL, 0x64ad8c57UL,
|
||||
0x85510443UL, 0xfa020ed1UL, 0x7e287affUL, 0xe60fb663UL, 0x095f35a1UL, 0x79ebf120UL,
|
||||
0xfd059d43UL, 0x6497b7b1UL, 0xf3641f63UL, 0x241e4adfUL, 0x28147f5fUL, 0x4fa2b8cdUL,
|
||||
0xc9430040UL, 0x0cc32220UL, 0xfdd30b30UL, 0xc0a5374fUL, 0x1d2d00d9UL, 0x24147b15UL,
|
||||
0xee4d111aUL, 0x0fca5167UL, 0x71ff904cUL, 0x2d195ffeUL, 0x1a05645fUL, 0x0c13fefeUL,
|
||||
0x081b08caUL, 0x05170121UL, 0x80530100UL, 0xe83e5efeUL, 0xac9af4f8UL, 0x7fe72701UL,
|
||||
0xd2b8ee5fUL, 0x06df4261UL, 0xbb9e9b8aUL, 0x7293ea25UL, 0xce84ffdfUL, 0xf5718801UL,
|
||||
0x3dd64b04UL, 0xa26f263bUL, 0x7ed48400UL, 0x547eebe6UL, 0x446d4ca0UL, 0x6cf3d6f5UL,
|
||||
0x2649abdfUL, 0xaea0c7f5UL, 0x36338cc1UL, 0x503f7e93UL, 0xd3772061UL, 0x11b638e1UL,
|
||||
0x72500e03UL, 0xf80eb2bbUL, 0xabe0502eUL, 0xec8d77deUL, 0x57971e81UL, 0xe14f6746UL,
|
||||
0xc9335400UL, 0x6920318fUL, 0x081dbb99UL, 0xffc304a5UL, 0x4d351805UL, 0x7f3d5ce3UL,
|
||||
0xa6c866c6UL, 0x5d5bcca9UL, 0xdaec6feaUL, 0x9f926f91UL, 0x9f46222fUL, 0x3991467dUL,
|
||||
0xa5bf6d8eUL, 0x1143c44fUL, 0x43958302UL, 0xd0214eebUL, 0x022083b8UL, 0x3fb6180cUL,
|
||||
0x18f8931eUL, 0x281658e6UL, 0x26486e3eUL, 0x8bd78a70UL, 0x7477e4c1UL, 0xb506e07cUL,
|
||||
0xf32d0a25UL, 0x79098b02UL, 0xe4eabb81UL, 0x28123b23UL, 0x69dead38UL, 0x1574ca16UL,
|
||||
0xdf871b62UL, 0x211c40b7UL, 0xa51a9ef9UL, 0x0014377bUL, 0x041e8ac8UL, 0x09114003UL,
|
||||
0xbd59e4d2UL, 0xe3d156d5UL, 0x4fe876d5UL, 0x2f91a340UL, 0x557be8deUL, 0x00eae4a7UL,
|
||||
0x0ce5c2ecUL, 0x4db4bba6UL, 0xe756bdffUL, 0xdd3369acUL, 0xec17b035UL, 0x06572327UL,
|
||||
0x99afc8b0UL, 0x56c8c391UL, 0x6b65811cUL, 0x5e146119UL, 0x6e85cb75UL, 0xbe07c002UL,
|
||||
0xc2325577UL, 0x893ff4ecUL, 0x5bbfc92dUL, 0xd0ec3b25UL, 0xb7801ab7UL, 0x8d6d3b24UL,
|
||||
0x20c763efUL, 0xc366a5fcUL, 0x9c382880UL, 0x0ace3205UL, 0xaac9548aUL, 0xeca1d7c7UL,
|
||||
0x041afa32UL, 0x1d16625aUL, 0x6701902cUL, 0x9b757a54UL, 0x31d477f7UL, 0x9126b031UL,
|
||||
0x36cc6fdbUL, 0xc70b8b46UL, 0xd9e66a48UL, 0x56e55a79UL, 0x026a4cebUL, 0x52437effUL,
|
||||
0x2f8f76b4UL, 0x0df980a5UL, 0x8674cde3UL, 0xedda04ebUL, 0x17a9be04UL, 0x2c18f4dfUL,
|
||||
0xb7747f9dUL, 0xab2af7b4UL, 0xefc34d20UL, 0x2e096b7cUL, 0x1741a254UL, 0xe5b6a035UL,
|
||||
0x213d42f6UL, 0x2c1c7c26UL, 0x61c2f50fUL, 0x6552daf9UL, 0xd2c231f8UL, 0x25130f69UL,
|
||||
0xd8167fa2UL, 0x0418f2c8UL, 0x001a96a6UL, 0x0d1526abUL, 0x63315c21UL, 0x5e0a72ecUL,
|
||||
0x49bafefdUL, 0x187908d9UL, 0x8d0dbd86UL, 0x311170a7UL, 0x3e9b640cUL, 0xcc3e10d7UL,
|
||||
0xd5cad3b6UL, 0x0caec388UL, 0xf73001e1UL, 0x6c728affUL, 0x71eae2a1UL, 0x1f9af36eUL,
|
||||
0xcfcbd12fUL, 0xc1de8417UL, 0xac07be6bUL, 0xcb44a1d8UL, 0x8b9b0f56UL, 0x013988c3UL,
|
||||
0xb1c52fcaUL, 0xb4be31cdUL, 0xd8782806UL, 0x12a3a4e2UL, 0x6f7de532UL, 0x58fd7eb6UL,
|
||||
0xd01ee900UL, 0x24adffc2UL, 0xf4990fc5UL, 0x9711aac5UL, 0x001d7b95UL, 0x82e5e7d2UL,
|
||||
0x109873f6UL, 0x00613096UL, 0xc32d9521UL, 0xada121ffUL, 0x29908415UL, 0x7fbb977fUL,
|
||||
0xaf9eb3dbUL, 0x29c9ed2aUL, 0x5ce2a465UL, 0xa730f32cUL, 0xd0aa3fe8UL, 0x8a5cc091UL,
|
||||
0xd49e2ce7UL, 0x0ce454a9UL, 0xd60acd86UL, 0x015f1919UL, 0x77079103UL, 0xdea03af6UL,
|
||||
0x78a8565eUL, 0xdee356dfUL, 0x21f05cbeUL, 0x8b75e387UL, 0xb3c50651UL, 0xb8a5c3efUL,
|
||||
0xd8eeb6d2UL, 0xe523be77UL, 0xc2154529UL, 0x2f69efdfUL, 0xafe67afbUL, 0xf470c4b2UL,
|
||||
0xf3e0eb5bUL, 0xd6cc9876UL, 0x39e4460cUL, 0x1fda8538UL, 0x1987832fUL, 0xca007367UL,
|
||||
0xa99144f8UL, 0x296b299eUL, 0x492fc295UL, 0x9266beabUL, 0xb5676e69UL, 0x9bd3dddaUL,
|
||||
0xdf7e052fUL, 0xdb25701cUL, 0x1b5e51eeUL, 0xf65324e6UL, 0x6afce36cUL, 0x0316cc04UL,
|
||||
0x8644213eUL, 0xb7dc59d0UL, 0x7965291fUL, 0xccd6fd43UL, 0x41823979UL, 0x932bcdf6UL,
|
||||
0xb657c34dUL, 0x4edfd282UL, 0x7ae5290cUL, 0x3cb9536bUL, 0x851e20feUL, 0x9833557eUL,
|
||||
0x13ecf0b0UL, 0xd3ffb372UL, 0x3f85c5c1UL, 0x0aef7ed2UL};
|
||||
|
||||
static const ulong32 S5[256] = {
|
||||
0x7ec90c04UL, 0x2c6e74b9UL, 0x9b0e66dfUL, 0xa6337911UL, 0xb86a7fffUL, 0x1dd358f5UL,
|
||||
0x44dd9d44UL, 0x1731167fUL, 0x08fbf1faUL, 0xe7f511ccUL, 0xd2051b00UL, 0x735aba00UL,
|
||||
0x2ab722d8UL, 0x386381cbUL, 0xacf6243aUL, 0x69befd7aUL, 0xe6a2e77fUL, 0xf0c720cdUL,
|
||||
0xc4494816UL, 0xccf5c180UL, 0x38851640UL, 0x15b0a848UL, 0xe68b18cbUL, 0x4caadeffUL,
|
||||
0x5f480a01UL, 0x0412b2aaUL, 0x259814fcUL, 0x41d0efe2UL, 0x4e40b48dUL, 0x248eb6fbUL,
|
||||
0x8dba1cfeUL, 0x41a99b02UL, 0x1a550a04UL, 0xba8f65cbUL, 0x7251f4e7UL, 0x95a51725UL,
|
||||
0xc106ecd7UL, 0x97a5980aUL, 0xc539b9aaUL, 0x4d79fe6aUL, 0xf2f3f763UL, 0x68af8040UL,
|
||||
0xed0c9e56UL, 0x11b4958bUL, 0xe1eb5a88UL, 0x8709e6b0UL, 0xd7e07156UL, 0x4e29fea7UL,
|
||||
0x6366e52dUL, 0x02d1c000UL, 0xc4ac8e05UL, 0x9377f571UL, 0x0c05372aUL, 0x578535f2UL,
|
||||
0x2261be02UL, 0xd642a0c9UL, 0xdf13a280UL, 0x74b55bd2UL, 0x682199c0UL, 0xd421e5ecUL,
|
||||
0x53fb3ce8UL, 0xc8adedb3UL, 0x28a87fc9UL, 0x3d959981UL, 0x5c1ff900UL, 0xfe38d399UL,
|
||||
0x0c4eff0bUL, 0x062407eaUL, 0xaa2f4fb1UL, 0x4fb96976UL, 0x90c79505UL, 0xb0a8a774UL,
|
||||
0xef55a1ffUL, 0xe59ca2c2UL, 0xa6b62d27UL, 0xe66a4263UL, 0xdf65001fUL, 0x0ec50966UL,
|
||||
0xdfdd55bcUL, 0x29de0655UL, 0x911e739aUL, 0x17af8975UL, 0x32c7911cUL, 0x89f89468UL,
|
||||
0x0d01e980UL, 0x524755f4UL, 0x03b63cc9UL, 0x0cc844b2UL, 0xbcf3f0aaUL, 0x87ac36e9UL,
|
||||
0xe53a7426UL, 0x01b3d82bUL, 0x1a9e7449UL, 0x64ee2d7eUL, 0xcddbb1daUL, 0x01c94910UL,
|
||||
0xb868bf80UL, 0x0d26f3fdUL, 0x9342ede7UL, 0x04a5c284UL, 0x636737b6UL, 0x50f5b616UL,
|
||||
0xf24766e3UL, 0x8eca36c1UL, 0x136e05dbUL, 0xfef18391UL, 0xfb887a37UL, 0xd6e7f7d4UL,
|
||||
0xc7fb7dc9UL, 0x3063fcdfUL, 0xb6f589deUL, 0xec2941daUL, 0x26e46695UL, 0xb7566419UL,
|
||||
0xf654efc5UL, 0xd08d58b7UL, 0x48925401UL, 0xc1bacb7fUL, 0xe5ff550fUL, 0xb6083049UL,
|
||||
0x5bb5d0e8UL, 0x87d72e5aUL, 0xab6a6ee1UL, 0x223a66ceUL, 0xc62bf3cdUL, 0x9e0885f9UL,
|
||||
0x68cb3e47UL, 0x086c010fUL, 0xa21de820UL, 0xd18b69deUL, 0xf3f65777UL, 0xfa02c3f6UL,
|
||||
0x407edac3UL, 0xcbb3d550UL, 0x1793084dUL, 0xb0d70ebaUL, 0x0ab378d5UL, 0xd951fb0cUL,
|
||||
0xded7da56UL, 0x4124bbe4UL, 0x94ca0b56UL, 0x0f5755d1UL, 0xe0e1e56eUL, 0x6184b5beUL,
|
||||
0x580a249fUL, 0x94f74bc0UL, 0xe327888eUL, 0x9f7b5561UL, 0xc3dc0280UL, 0x05687715UL,
|
||||
0x646c6bd7UL, 0x44904db3UL, 0x66b4f0a3UL, 0xc0f1648aUL, 0x697ed5afUL, 0x49e92ff6UL,
|
||||
0x309e374fUL, 0x2cb6356aUL, 0x85808573UL, 0x4991f840UL, 0x76f0ae02UL, 0x083be84dUL,
|
||||
0x28421c9aUL, 0x44489406UL, 0x736e4cb8UL, 0xc1092910UL, 0x8bc95fc6UL, 0x7d869cf4UL,
|
||||
0x134f616fUL, 0x2e77118dUL, 0xb31b2be1UL, 0xaa90b472UL, 0x3ca5d717UL, 0x7d161bbaUL,
|
||||
0x9cad9010UL, 0xaf462ba2UL, 0x9fe459d2UL, 0x45d34559UL, 0xd9f2da13UL, 0xdbc65487UL,
|
||||
0xf3e4f94eUL, 0x176d486fUL, 0x097c13eaUL, 0x631da5c7UL, 0x445f7382UL, 0x175683f4UL,
|
||||
0xcdc66a97UL, 0x70be0288UL, 0xb3cdcf72UL, 0x6e5dd2f3UL, 0x20936079UL, 0x459b80a5UL,
|
||||
0xbe60e2dbUL, 0xa9c23101UL, 0xeba5315cUL, 0x224e42f2UL, 0x1c5c1572UL, 0xf6721b2cUL,
|
||||
0x1ad2fff3UL, 0x8c25404eUL, 0x324ed72fUL, 0x4067b7fdUL, 0x0523138eUL, 0x5ca3bc78UL,
|
||||
0xdc0fd66eUL, 0x75922283UL, 0x784d6b17UL, 0x58ebb16eUL, 0x44094f85UL, 0x3f481d87UL,
|
||||
0xfcfeae7bUL, 0x77b5ff76UL, 0x8c2302bfUL, 0xaaf47556UL, 0x5f46b02aUL, 0x2b092801UL,
|
||||
0x3d38f5f7UL, 0x0ca81f36UL, 0x52af4a8aUL, 0x66d5e7c0UL, 0xdf3b0874UL, 0x95055110UL,
|
||||
0x1b5ad7a8UL, 0xf61ed5adUL, 0x6cf6e479UL, 0x20758184UL, 0xd0cefa65UL, 0x88f7be58UL,
|
||||
0x4a046826UL, 0x0ff6f8f3UL, 0xa09c7f70UL, 0x5346aba0UL, 0x5ce96c28UL, 0xe176eda3UL,
|
||||
0x6bac307fUL, 0x376829d2UL, 0x85360fa9UL, 0x17e3fe2aUL, 0x24b79767UL, 0xf5a96b20UL,
|
||||
0xd6cd2595UL, 0x68ff1ebfUL, 0x7555442cUL, 0xf19f06beUL, 0xf9e0659aUL, 0xeeb9491dUL,
|
||||
0x34010718UL, 0xbb30cab8UL, 0xe822fe15UL, 0x88570983UL, 0x750e6249UL, 0xda627e55UL,
|
||||
0x5e76ffa8UL, 0xb1534546UL, 0x6d47de08UL, 0xefe9e7d4UL};
|
||||
|
||||
static const ulong32 S6[256] = {
|
||||
0xf6fa8f9dUL, 0x2cac6ce1UL, 0x4ca34867UL, 0xe2337f7cUL, 0x95db08e7UL, 0x016843b4UL,
|
||||
0xeced5cbcUL, 0x325553acUL, 0xbf9f0960UL, 0xdfa1e2edUL, 0x83f0579dUL, 0x63ed86b9UL,
|
||||
0x1ab6a6b8UL, 0xde5ebe39UL, 0xf38ff732UL, 0x8989b138UL, 0x33f14961UL, 0xc01937bdUL,
|
||||
0xf506c6daUL, 0xe4625e7eUL, 0xa308ea99UL, 0x4e23e33cUL, 0x79cbd7ccUL, 0x48a14367UL,
|
||||
0xa3149619UL, 0xfec94bd5UL, 0xa114174aUL, 0xeaa01866UL, 0xa084db2dUL, 0x09a8486fUL,
|
||||
0xa888614aUL, 0x2900af98UL, 0x01665991UL, 0xe1992863UL, 0xc8f30c60UL, 0x2e78ef3cUL,
|
||||
0xd0d51932UL, 0xcf0fec14UL, 0xf7ca07d2UL, 0xd0a82072UL, 0xfd41197eUL, 0x9305a6b0UL,
|
||||
0xe86be3daUL, 0x74bed3cdUL, 0x372da53cUL, 0x4c7f4448UL, 0xdab5d440UL, 0x6dba0ec3UL,
|
||||
0x083919a7UL, 0x9fbaeed9UL, 0x49dbcfb0UL, 0x4e670c53UL, 0x5c3d9c01UL, 0x64bdb941UL,
|
||||
0x2c0e636aUL, 0xba7dd9cdUL, 0xea6f7388UL, 0xe70bc762UL, 0x35f29adbUL, 0x5c4cdd8dUL,
|
||||
0xf0d48d8cUL, 0xb88153e2UL, 0x08a19866UL, 0x1ae2eac8UL, 0x284caf89UL, 0xaa928223UL,
|
||||
0x9334be53UL, 0x3b3a21bfUL, 0x16434be3UL, 0x9aea3906UL, 0xefe8c36eUL, 0xf890cdd9UL,
|
||||
0x80226daeUL, 0xc340a4a3UL, 0xdf7e9c09UL, 0xa694a807UL, 0x5b7c5eccUL, 0x221db3a6UL,
|
||||
0x9a69a02fUL, 0x68818a54UL, 0xceb2296fUL, 0x53c0843aUL, 0xfe893655UL, 0x25bfe68aUL,
|
||||
0xb4628abcUL, 0xcf222ebfUL, 0x25ac6f48UL, 0xa9a99387UL, 0x53bddb65UL, 0xe76ffbe7UL,
|
||||
0xe967fd78UL, 0x0ba93563UL, 0x8e342bc1UL, 0xe8a11be9UL, 0x4980740dUL, 0xc8087dfcUL,
|
||||
0x8de4bf99UL, 0xa11101a0UL, 0x7fd37975UL, 0xda5a26c0UL, 0xe81f994fUL, 0x9528cd89UL,
|
||||
0xfd339fedUL, 0xb87834bfUL, 0x5f04456dUL, 0x22258698UL, 0xc9c4c83bUL, 0x2dc156beUL,
|
||||
0x4f628daaUL, 0x57f55ec5UL, 0xe2220abeUL, 0xd2916ebfUL, 0x4ec75b95UL, 0x24f2c3c0UL,
|
||||
0x42d15d99UL, 0xcd0d7fa0UL, 0x7b6e27ffUL, 0xa8dc8af0UL, 0x7345c106UL, 0xf41e232fUL,
|
||||
0x35162386UL, 0xe6ea8926UL, 0x3333b094UL, 0x157ec6f2UL, 0x372b74afUL, 0x692573e4UL,
|
||||
0xe9a9d848UL, 0xf3160289UL, 0x3a62ef1dUL, 0xa787e238UL, 0xf3a5f676UL, 0x74364853UL,
|
||||
0x20951063UL, 0x4576698dUL, 0xb6fad407UL, 0x592af950UL, 0x36f73523UL, 0x4cfb6e87UL,
|
||||
0x7da4cec0UL, 0x6c152daaUL, 0xcb0396a8UL, 0xc50dfe5dUL, 0xfcd707abUL, 0x0921c42fUL,
|
||||
0x89dff0bbUL, 0x5fe2be78UL, 0x448f4f33UL, 0x754613c9UL, 0x2b05d08dUL, 0x48b9d585UL,
|
||||
0xdc049441UL, 0xc8098f9bUL, 0x7dede786UL, 0xc39a3373UL, 0x42410005UL, 0x6a091751UL,
|
||||
0x0ef3c8a6UL, 0x890072d6UL, 0x28207682UL, 0xa9a9f7beUL, 0xbf32679dUL, 0xd45b5b75UL,
|
||||
0xb353fd00UL, 0xcbb0e358UL, 0x830f220aUL, 0x1f8fb214UL, 0xd372cf08UL, 0xcc3c4a13UL,
|
||||
0x8cf63166UL, 0x061c87beUL, 0x88c98f88UL, 0x6062e397UL, 0x47cf8e7aUL, 0xb6c85283UL,
|
||||
0x3cc2acfbUL, 0x3fc06976UL, 0x4e8f0252UL, 0x64d8314dUL, 0xda3870e3UL, 0x1e665459UL,
|
||||
0xc10908f0UL, 0x513021a5UL, 0x6c5b68b7UL, 0x822f8aa0UL, 0x3007cd3eUL, 0x74719eefUL,
|
||||
0xdc872681UL, 0x073340d4UL, 0x7e432fd9UL, 0x0c5ec241UL, 0x8809286cUL, 0xf592d891UL,
|
||||
0x08a930f6UL, 0x957ef305UL, 0xb7fbffbdUL, 0xc266e96fUL, 0x6fe4ac98UL, 0xb173ecc0UL,
|
||||
0xbc60b42aUL, 0x953498daUL, 0xfba1ae12UL, 0x2d4bd736UL, 0x0f25faabUL, 0xa4f3fcebUL,
|
||||
0xe2969123UL, 0x257f0c3dUL, 0x9348af49UL, 0x361400bcUL, 0xe8816f4aUL, 0x3814f200UL,
|
||||
0xa3f94043UL, 0x9c7a54c2UL, 0xbc704f57UL, 0xda41e7f9UL, 0xc25ad33aUL, 0x54f4a084UL,
|
||||
0xb17f5505UL, 0x59357cbeUL, 0xedbd15c8UL, 0x7f97c5abUL, 0xba5ac7b5UL, 0xb6f6deafUL,
|
||||
0x3a479c3aUL, 0x5302da25UL, 0x653d7e6aUL, 0x54268d49UL, 0x51a477eaUL, 0x5017d55bUL,
|
||||
0xd7d25d88UL, 0x44136c76UL, 0x0404a8c8UL, 0xb8e5a121UL, 0xb81a928aUL, 0x60ed5869UL,
|
||||
0x97c55b96UL, 0xeaec991bUL, 0x29935913UL, 0x01fdb7f1UL, 0x088e8dfaUL, 0x9ab6f6f5UL,
|
||||
0x3b4cbf9fUL, 0x4a5de3abUL, 0xe6051d35UL, 0xa0e1d855UL, 0xd36b4cf1UL, 0xf544edebUL,
|
||||
0xb0e93524UL, 0xbebb8fbdUL, 0xa2d762cfUL, 0x49c92f54UL, 0x38b5f331UL, 0x7128a454UL,
|
||||
0x48392905UL, 0xa65b1db8UL, 0x851c97bdUL, 0xd675cf2fUL};
|
||||
|
||||
static const ulong32 S7[256] = {
|
||||
0x85e04019UL, 0x332bf567UL, 0x662dbfffUL, 0xcfc65693UL, 0x2a8d7f6fUL, 0xab9bc912UL,
|
||||
0xde6008a1UL, 0x2028da1fUL, 0x0227bce7UL, 0x4d642916UL, 0x18fac300UL, 0x50f18b82UL,
|
||||
0x2cb2cb11UL, 0xb232e75cUL, 0x4b3695f2UL, 0xb28707deUL, 0xa05fbcf6UL, 0xcd4181e9UL,
|
||||
0xe150210cUL, 0xe24ef1bdUL, 0xb168c381UL, 0xfde4e789UL, 0x5c79b0d8UL, 0x1e8bfd43UL,
|
||||
0x4d495001UL, 0x38be4341UL, 0x913cee1dUL, 0x92a79c3fUL, 0x089766beUL, 0xbaeeadf4UL,
|
||||
0x1286becfUL, 0xb6eacb19UL, 0x2660c200UL, 0x7565bde4UL, 0x64241f7aUL, 0x8248dca9UL,
|
||||
0xc3b3ad66UL, 0x28136086UL, 0x0bd8dfa8UL, 0x356d1cf2UL, 0x107789beUL, 0xb3b2e9ceUL,
|
||||
0x0502aa8fUL, 0x0bc0351eUL, 0x166bf52aUL, 0xeb12ff82UL, 0xe3486911UL, 0xd34d7516UL,
|
||||
0x4e7b3affUL, 0x5f43671bUL, 0x9cf6e037UL, 0x4981ac83UL, 0x334266ceUL, 0x8c9341b7UL,
|
||||
0xd0d854c0UL, 0xcb3a6c88UL, 0x47bc2829UL, 0x4725ba37UL, 0xa66ad22bUL, 0x7ad61f1eUL,
|
||||
0x0c5cbafaUL, 0x4437f107UL, 0xb6e79962UL, 0x42d2d816UL, 0x0a961288UL, 0xe1a5c06eUL,
|
||||
0x13749e67UL, 0x72fc081aUL, 0xb1d139f7UL, 0xf9583745UL, 0xcf19df58UL, 0xbec3f756UL,
|
||||
0xc06eba30UL, 0x07211b24UL, 0x45c28829UL, 0xc95e317fUL, 0xbc8ec511UL, 0x38bc46e9UL,
|
||||
0xc6e6fa14UL, 0xbae8584aUL, 0xad4ebc46UL, 0x468f508bUL, 0x7829435fUL, 0xf124183bUL,
|
||||
0x821dba9fUL, 0xaff60ff4UL, 0xea2c4e6dUL, 0x16e39264UL, 0x92544a8bUL, 0x009b4fc3UL,
|
||||
0xaba68cedUL, 0x9ac96f78UL, 0x06a5b79aUL, 0xb2856e6eUL, 0x1aec3ca9UL, 0xbe838688UL,
|
||||
0x0e0804e9UL, 0x55f1be56UL, 0xe7e5363bUL, 0xb3a1f25dUL, 0xf7debb85UL, 0x61fe033cUL,
|
||||
0x16746233UL, 0x3c034c28UL, 0xda6d0c74UL, 0x79aac56cUL, 0x3ce4e1adUL, 0x51f0c802UL,
|
||||
0x98f8f35aUL, 0x1626a49fUL, 0xeed82b29UL, 0x1d382fe3UL, 0x0c4fb99aUL, 0xbb325778UL,
|
||||
0x3ec6d97bUL, 0x6e77a6a9UL, 0xcb658b5cUL, 0xd45230c7UL, 0x2bd1408bUL, 0x60c03eb7UL,
|
||||
0xb9068d78UL, 0xa33754f4UL, 0xf430c87dUL, 0xc8a71302UL, 0xb96d8c32UL, 0xebd4e7beUL,
|
||||
0xbe8b9d2dUL, 0x7979fb06UL, 0xe7225308UL, 0x8b75cf77UL, 0x11ef8da4UL, 0xe083c858UL,
|
||||
0x8d6b786fUL, 0x5a6317a6UL, 0xfa5cf7a0UL, 0x5dda0033UL, 0xf28ebfb0UL, 0xf5b9c310UL,
|
||||
0xa0eac280UL, 0x08b9767aUL, 0xa3d9d2b0UL, 0x79d34217UL, 0x021a718dUL, 0x9ac6336aUL,
|
||||
0x2711fd60UL, 0x438050e3UL, 0x069908a8UL, 0x3d7fedc4UL, 0x826d2befUL, 0x4eeb8476UL,
|
||||
0x488dcf25UL, 0x36c9d566UL, 0x28e74e41UL, 0xc2610acaUL, 0x3d49a9cfUL, 0xbae3b9dfUL,
|
||||
0xb65f8de6UL, 0x92aeaf64UL, 0x3ac7d5e6UL, 0x9ea80509UL, 0xf22b017dUL, 0xa4173f70UL,
|
||||
0xdd1e16c3UL, 0x15e0d7f9UL, 0x50b1b887UL, 0x2b9f4fd5UL, 0x625aba82UL, 0x6a017962UL,
|
||||
0x2ec01b9cUL, 0x15488aa9UL, 0xd716e740UL, 0x40055a2cUL, 0x93d29a22UL, 0xe32dbf9aUL,
|
||||
0x058745b9UL, 0x3453dc1eUL, 0xd699296eUL, 0x496cff6fUL, 0x1c9f4986UL, 0xdfe2ed07UL,
|
||||
0xb87242d1UL, 0x19de7eaeUL, 0x053e561aUL, 0x15ad6f8cUL, 0x66626c1cUL, 0x7154c24cUL,
|
||||
0xea082b2aUL, 0x93eb2939UL, 0x17dcb0f0UL, 0x58d4f2aeUL, 0x9ea294fbUL, 0x52cf564cUL,
|
||||
0x9883fe66UL, 0x2ec40581UL, 0x763953c3UL, 0x01d6692eUL, 0xd3a0c108UL, 0xa1e7160eUL,
|
||||
0xe4f2dfa6UL, 0x693ed285UL, 0x74904698UL, 0x4c2b0eddUL, 0x4f757656UL, 0x5d393378UL,
|
||||
0xa132234fUL, 0x3d321c5dUL, 0xc3f5e194UL, 0x4b269301UL, 0xc79f022fUL, 0x3c997e7eUL,
|
||||
0x5e4f9504UL, 0x3ffafbbdUL, 0x76f7ad0eUL, 0x296693f4UL, 0x3d1fce6fUL, 0xc61e45beUL,
|
||||
0xd3b5ab34UL, 0xf72bf9b7UL, 0x1b0434c0UL, 0x4e72b567UL, 0x5592a33dUL, 0xb5229301UL,
|
||||
0xcfd2a87fUL, 0x60aeb767UL, 0x1814386bUL, 0x30bcc33dUL, 0x38a0c07dUL, 0xfd1606f2UL,
|
||||
0xc363519bUL, 0x589dd390UL, 0x5479f8e6UL, 0x1cb8d647UL, 0x97fd61a9UL, 0xea7759f4UL,
|
||||
0x2d57539dUL, 0x569a58cfUL, 0xe84e63adUL, 0x462e1b78UL, 0x6580f87eUL, 0xf3817914UL,
|
||||
0x91da55f4UL, 0x40a230f3UL, 0xd1988f35UL, 0xb6e318d2UL, 0x3ffa50bcUL, 0x3d40f021UL,
|
||||
0xc3c0bdaeUL, 0x4958c24cUL, 0x518f36b2UL, 0x84b1d370UL, 0x0fedce83UL, 0x878ddadaUL,
|
||||
0xf2a279c7UL, 0x94e01be8UL, 0x90716f4bUL, 0x954b8aa3UL};
|
||||
|
||||
static const ulong32 S8[256] = {
|
||||
0xe216300dUL, 0xbbddfffcUL, 0xa7ebdabdUL, 0x35648095UL, 0x7789f8b7UL, 0xe6c1121bUL,
|
||||
0x0e241600UL, 0x052ce8b5UL, 0x11a9cfb0UL, 0xe5952f11UL, 0xece7990aUL, 0x9386d174UL,
|
||||
0x2a42931cUL, 0x76e38111UL, 0xb12def3aUL, 0x37ddddfcUL, 0xde9adeb1UL, 0x0a0cc32cUL,
|
||||
0xbe197029UL, 0x84a00940UL, 0xbb243a0fUL, 0xb4d137cfUL, 0xb44e79f0UL, 0x049eedfdUL,
|
||||
0x0b15a15dUL, 0x480d3168UL, 0x8bbbde5aUL, 0x669ded42UL, 0xc7ece831UL, 0x3f8f95e7UL,
|
||||
0x72df191bUL, 0x7580330dUL, 0x94074251UL, 0x5c7dcdfaUL, 0xabbe6d63UL, 0xaa402164UL,
|
||||
0xb301d40aUL, 0x02e7d1caUL, 0x53571daeUL, 0x7a3182a2UL, 0x12a8ddecUL, 0xfdaa335dUL,
|
||||
0x176f43e8UL, 0x71fb46d4UL, 0x38129022UL, 0xce949ad4UL, 0xb84769adUL, 0x965bd862UL,
|
||||
0x82f3d055UL, 0x66fb9767UL, 0x15b80b4eUL, 0x1d5b47a0UL, 0x4cfde06fUL, 0xc28ec4b8UL,
|
||||
0x57e8726eUL, 0x647a78fcUL, 0x99865d44UL, 0x608bd593UL, 0x6c200e03UL, 0x39dc5ff6UL,
|
||||
0x5d0b00a3UL, 0xae63aff2UL, 0x7e8bd632UL, 0x70108c0cUL, 0xbbd35049UL, 0x2998df04UL,
|
||||
0x980cf42aUL, 0x9b6df491UL, 0x9e7edd53UL, 0x06918548UL, 0x58cb7e07UL, 0x3b74ef2eUL,
|
||||
0x522fffb1UL, 0xd24708ccUL, 0x1c7e27cdUL, 0xa4eb215bUL, 0x3cf1d2e2UL, 0x19b47a38UL,
|
||||
0x424f7618UL, 0x35856039UL, 0x9d17dee7UL, 0x27eb35e6UL, 0xc9aff67bUL, 0x36baf5b8UL,
|
||||
0x09c467cdUL, 0xc18910b1UL, 0xe11dbf7bUL, 0x06cd1af8UL, 0x7170c608UL, 0x2d5e3354UL,
|
||||
0xd4de495aUL, 0x64c6d006UL, 0xbcc0c62cUL, 0x3dd00db3UL, 0x708f8f34UL, 0x77d51b42UL,
|
||||
0x264f620fUL, 0x24b8d2bfUL, 0x15c1b79eUL, 0x46a52564UL, 0xf8d7e54eUL, 0x3e378160UL,
|
||||
0x7895cda5UL, 0x859c15a5UL, 0xe6459788UL, 0xc37bc75fUL, 0xdb07ba0cUL, 0x0676a3abUL,
|
||||
0x7f229b1eUL, 0x31842e7bUL, 0x24259fd7UL, 0xf8bef472UL, 0x835ffcb8UL, 0x6df4c1f2UL,
|
||||
0x96f5b195UL, 0xfd0af0fcUL, 0xb0fe134cUL, 0xe2506d3dUL, 0x4f9b12eaUL, 0xf215f225UL,
|
||||
0xa223736fUL, 0x9fb4c428UL, 0x25d04979UL, 0x34c713f8UL, 0xc4618187UL, 0xea7a6e98UL,
|
||||
0x7cd16efcUL, 0x1436876cUL, 0xf1544107UL, 0xbedeee14UL, 0x56e9af27UL, 0xa04aa441UL,
|
||||
0x3cf7c899UL, 0x92ecbae6UL, 0xdd67016dUL, 0x151682ebUL, 0xa842eedfUL, 0xfdba60b4UL,
|
||||
0xf1907b75UL, 0x20e3030fUL, 0x24d8c29eUL, 0xe139673bUL, 0xefa63fb8UL, 0x71873054UL,
|
||||
0xb6f2cf3bUL, 0x9f326442UL, 0xcb15a4ccUL, 0xb01a4504UL, 0xf1e47d8dUL, 0x844a1be5UL,
|
||||
0xbae7dfdcUL, 0x42cbda70UL, 0xcd7dae0aUL, 0x57e85b7aUL, 0xd53f5af6UL, 0x20cf4d8cUL,
|
||||
0xcea4d428UL, 0x79d130a4UL, 0x3486ebfbUL, 0x33d3cddcUL, 0x77853b53UL, 0x37effcb5UL,
|
||||
0xc5068778UL, 0xe580b3e6UL, 0x4e68b8f4UL, 0xc5c8b37eUL, 0x0d809ea2UL, 0x398feb7cUL,
|
||||
0x132a4f94UL, 0x43b7950eUL, 0x2fee7d1cUL, 0x223613bdUL, 0xdd06caa2UL, 0x37df932bUL,
|
||||
0xc4248289UL, 0xacf3ebc3UL, 0x5715f6b7UL, 0xef3478ddUL, 0xf267616fUL, 0xc148cbe4UL,
|
||||
0x9052815eUL, 0x5e410fabUL, 0xb48a2465UL, 0x2eda7fa4UL, 0xe87b40e4UL, 0xe98ea084UL,
|
||||
0x5889e9e1UL, 0xefd390fcUL, 0xdd07d35bUL, 0xdb485694UL, 0x38d7e5b2UL, 0x57720101UL,
|
||||
0x730edebcUL, 0x5b643113UL, 0x94917e4fUL, 0x503c2fbaUL, 0x646f1282UL, 0x7523d24aUL,
|
||||
0xe0779695UL, 0xf9c17a8fUL, 0x7a5b2121UL, 0xd187b896UL, 0x29263a4dUL, 0xba510cdfUL,
|
||||
0x81f47c9fUL, 0xad1163edUL, 0xea7b5965UL, 0x1a00726eUL, 0x11403092UL, 0x00da6d77UL,
|
||||
0x4a0cdd61UL, 0xad1f4603UL, 0x605bdfb0UL, 0x9eedc364UL, 0x22ebe6a8UL, 0xcee7d28aUL,
|
||||
0xa0e736a0UL, 0x5564a6b9UL, 0x10853209UL, 0xc7eb8f37UL, 0x2de705caUL, 0x8951570fUL,
|
||||
0xdf09822bUL, 0xbd691a6cUL, 0xaa12e4f2UL, 0x87451c0fUL, 0xe0f6a27aUL, 0x3ada4819UL,
|
||||
0x4cf1764fUL, 0x0d771c2bUL, 0x67cdb156UL, 0x350d8384UL, 0x5938fa0fUL, 0x42399ef3UL,
|
||||
0x36997b07UL, 0x0e84093dUL, 0x4aa93e61UL, 0x8360d87bUL, 0x1fa98b0cUL, 0x1149382cUL,
|
||||
0xe97625a5UL, 0x0614d1b7UL, 0x0e25244bUL, 0x0c768347UL, 0x589e8d82UL, 0x0d2059d1UL,
|
||||
0xa466bb1eUL, 0xf8da0a82UL, 0x04f19130UL, 0xba6e4ec0UL, 0x99265164UL, 0x1ee7230dUL,
|
||||
0x50b2ad80UL, 0xeaee6801UL, 0x8db2a283UL, 0xea8bf59eUL};
|
||||
|
||||
/* returns the i'th byte of a variable */
|
||||
#ifdef _MSC_VER
|
||||
#define GB(x, i) ((unsigned char)((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3))))
|
||||
#else
|
||||
#define GB(x, i) (((x[(15-i)>>2])>>(unsigned)(8*((15-i)&3)))&255)
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static int _cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
#else
|
||||
int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
#endif
|
||||
{
|
||||
ulong32 x[4], z[4];
|
||||
unsigned char buf[16];
|
||||
int y, i;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(skey != NULL);
|
||||
|
||||
if (num_rounds != 12 && num_rounds != 16 && num_rounds != 0) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (num_rounds == 12 && keylen > 10) {
|
||||
return CRYPT_INVALID_ROUNDS;
|
||||
}
|
||||
|
||||
if (keylen < 5 || keylen > 16) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
/* extend the key as required */
|
||||
zeromem(buf, sizeof(buf));
|
||||
memcpy(buf, key, (size_t)keylen);
|
||||
|
||||
/* load and start the awful looking network */
|
||||
for (y = 0; y < 4; y++) {
|
||||
LOAD32H(x[3-y],buf+4*y);
|
||||
}
|
||||
|
||||
for (i = y = 0; y < 2; y++) {
|
||||
z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)];
|
||||
z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)];
|
||||
z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)];
|
||||
z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0x8)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0x7)] ^ S8[GB(z, 0x6)] ^ S5[GB(z, 0x2)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0xA)] ^ S6[GB(z, 0xB)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S6[GB(z, 0x6)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0xC)] ^ S6[GB(z, 0xd)] ^ S7[GB(z, 0x3)] ^ S8[GB(z, 0x2)] ^ S7[GB(z, 0x9)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0xE)] ^ S6[GB(z, 0xF)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x0)] ^ S8[GB(z, 0xc)];
|
||||
|
||||
x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)];
|
||||
x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)];
|
||||
x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)];
|
||||
x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0x3)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0xc)] ^ S8[GB(x, 0xd)] ^ S5[GB(x, 0x8)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0x1)] ^ S6[GB(x, 0x0)] ^ S7[GB(x, 0xe)] ^ S8[GB(x, 0xf)] ^ S6[GB(x, 0xd)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x8)] ^ S8[GB(x, 0x9)] ^ S7[GB(x, 0x3)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0x5)] ^ S6[GB(x, 0x4)] ^ S7[GB(x, 0xa)] ^ S8[GB(x, 0xb)] ^ S8[GB(x, 0x7)];
|
||||
|
||||
/* second half */
|
||||
z[3] = x[3] ^ S5[GB(x, 0xD)] ^ S6[GB(x, 0xF)] ^ S7[GB(x, 0xC)] ^ S8[GB(x, 0xE)] ^ S7[GB(x, 0x8)];
|
||||
z[2] = x[1] ^ S5[GB(z, 0x0)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0x1)] ^ S8[GB(z, 0x3)] ^ S8[GB(x, 0xA)];
|
||||
z[1] = x[0] ^ S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x5)] ^ S8[GB(z, 0x4)] ^ S5[GB(x, 0x9)];
|
||||
z[0] = x[2] ^ S5[GB(z, 0xA)] ^ S6[GB(z, 0x9)] ^ S7[GB(z, 0xb)] ^ S8[GB(z, 0x8)] ^ S6[GB(x, 0xB)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0x3)] ^ S6[GB(z, 0x2)] ^ S7[GB(z, 0xc)] ^ S8[GB(z, 0xd)] ^ S5[GB(z, 0x9)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0x1)] ^ S6[GB(z, 0x0)] ^ S7[GB(z, 0xe)] ^ S8[GB(z, 0xf)] ^ S6[GB(z, 0xc)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0x7)] ^ S6[GB(z, 0x6)] ^ S7[GB(z, 0x8)] ^ S8[GB(z, 0x9)] ^ S7[GB(z, 0x2)];
|
||||
skey->cast5.K[i++] = S5[GB(z, 0x5)] ^ S6[GB(z, 0x4)] ^ S7[GB(z, 0xa)] ^ S8[GB(z, 0xb)] ^ S8[GB(z, 0x6)];
|
||||
|
||||
x[3] = z[1] ^ S5[GB(z, 0x5)] ^ S6[GB(z, 0x7)] ^ S7[GB(z, 0x4)] ^ S8[GB(z, 0x6)] ^ S7[GB(z, 0x0)];
|
||||
x[2] = z[3] ^ S5[GB(x, 0x0)] ^ S6[GB(x, 0x2)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x3)] ^ S8[GB(z, 0x2)];
|
||||
x[1] = z[2] ^ S5[GB(x, 0x7)] ^ S6[GB(x, 0x6)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S5[GB(z, 0x1)];
|
||||
x[0] = z[0] ^ S5[GB(x, 0xA)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0xb)] ^ S8[GB(x, 0x8)] ^ S6[GB(z, 0x3)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0x8)] ^ S6[GB(x, 0x9)] ^ S7[GB(x, 0x7)] ^ S8[GB(x, 0x6)] ^ S5[GB(x, 0x3)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0xa)] ^ S6[GB(x, 0xb)] ^ S7[GB(x, 0x5)] ^ S8[GB(x, 0x4)] ^ S6[GB(x, 0x7)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0xc)] ^ S6[GB(x, 0xd)] ^ S7[GB(x, 0x3)] ^ S8[GB(x, 0x2)] ^ S7[GB(x, 0x8)];
|
||||
skey->cast5.K[i++] = S5[GB(x, 0xe)] ^ S6[GB(x, 0xf)] ^ S7[GB(x, 0x1)] ^ S8[GB(x, 0x0)] ^ S8[GB(x, 0xd)];
|
||||
}
|
||||
|
||||
skey->cast5.keylen = keylen;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
zeromem(x, sizeof(x));
|
||||
zeromem(z, sizeof(z));
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
|
||||
{
|
||||
int z;
|
||||
z = _cast5_setup(key, keylen, num_rounds, skey);
|
||||
burn_stack(sizeof(ulong32)*8 + 16 + sizeof(int)*2);
|
||||
return z;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define INLINE __inline
|
||||
#else
|
||||
#define INLINE
|
||||
#endif
|
||||
|
||||
INLINE static ulong32 FI(ulong32 R, ulong32 Km, ulong32 Kr)
|
||||
{
|
||||
ulong32 I;
|
||||
I = (Km + R);
|
||||
I = ROL(I, Kr);
|
||||
return ((S1[byte(I, 3)] ^ S2[byte(I,2)]) - S3[byte(I,1)]) + S4[byte(I,0)];
|
||||
}
|
||||
|
||||
INLINE static ulong32 FII(ulong32 R, ulong32 Km, ulong32 Kr)
|
||||
{
|
||||
ulong32 I;
|
||||
I = (Km ^ R);
|
||||
I = ROL(I, Kr);
|
||||
return ((S1[byte(I, 3)] - S2[byte(I,2)]) + S3[byte(I,1)]) ^ S4[byte(I,0)];
|
||||
}
|
||||
|
||||
INLINE static ulong32 FIII(ulong32 R, ulong32 Km, ulong32 Kr)
|
||||
{
|
||||
ulong32 I;
|
||||
I = (Km - R);
|
||||
I = ROL(I, Kr);
|
||||
return ((S1[byte(I, 3)] + S2[byte(I,2)]) ^ S3[byte(I,1)]) - S4[byte(I,0)];
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#else
|
||||
void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
ulong32 R, L;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
LOAD32H(L,&pt[0]);
|
||||
LOAD32H(R,&pt[4]);
|
||||
L ^= FI(R, key->cast5.K[0], key->cast5.K[16]);
|
||||
R ^= FII(L, key->cast5.K[1], key->cast5.K[17]);
|
||||
L ^= FIII(R, key->cast5.K[2], key->cast5.K[18]);
|
||||
R ^= FI(L, key->cast5.K[3], key->cast5.K[19]);
|
||||
L ^= FII(R, key->cast5.K[4], key->cast5.K[20]);
|
||||
R ^= FIII(L, key->cast5.K[5], key->cast5.K[21]);
|
||||
L ^= FI(R, key->cast5.K[6], key->cast5.K[22]);
|
||||
R ^= FII(L, key->cast5.K[7], key->cast5.K[23]);
|
||||
L ^= FIII(R, key->cast5.K[8], key->cast5.K[24]);
|
||||
R ^= FI(L, key->cast5.K[9], key->cast5.K[25]);
|
||||
L ^= FII(R, key->cast5.K[10], key->cast5.K[26]);
|
||||
R ^= FIII(L, key->cast5.K[11], key->cast5.K[27]);
|
||||
if (key->cast5.keylen > 10) {
|
||||
L ^= FI(R, key->cast5.K[12], key->cast5.K[28]);
|
||||
R ^= FII(L, key->cast5.K[13], key->cast5.K[29]);
|
||||
L ^= FIII(R, key->cast5.K[14], key->cast5.K[30]);
|
||||
R ^= FI(L, key->cast5.K[15], key->cast5.K[31]);
|
||||
}
|
||||
STORE32H(R,&ct[0]);
|
||||
STORE32H(L,&ct[4]);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *key)
|
||||
{
|
||||
_cast5_ecb_encrypt(pt,ct,key);
|
||||
burn_stack(sizeof(ulong32)*3);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#else
|
||||
void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
#endif
|
||||
{
|
||||
ulong32 R, L;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
LOAD32H(R,&ct[0]);
|
||||
LOAD32H(L,&ct[4]);
|
||||
if (key->cast5.keylen > 10) {
|
||||
R ^= FI(L, key->cast5.K[15], key->cast5.K[31]);
|
||||
L ^= FIII(R, key->cast5.K[14], key->cast5.K[30]);
|
||||
R ^= FII(L, key->cast5.K[13], key->cast5.K[29]);
|
||||
L ^= FI(R, key->cast5.K[12], key->cast5.K[28]);
|
||||
}
|
||||
R ^= FIII(L, key->cast5.K[11], key->cast5.K[27]);
|
||||
L ^= FII(R, key->cast5.K[10], key->cast5.K[26]);
|
||||
R ^= FI(L, key->cast5.K[9], key->cast5.K[25]);
|
||||
L ^= FIII(R, key->cast5.K[8], key->cast5.K[24]);
|
||||
R ^= FII(L, key->cast5.K[7], key->cast5.K[23]);
|
||||
L ^= FI(R, key->cast5.K[6], key->cast5.K[22]);
|
||||
R ^= FIII(L, key->cast5.K[5], key->cast5.K[21]);
|
||||
L ^= FII(R, key->cast5.K[4], key->cast5.K[20]);
|
||||
R ^= FI(L, key->cast5.K[3], key->cast5.K[19]);
|
||||
L ^= FIII(R, key->cast5.K[2], key->cast5.K[18]);
|
||||
R ^= FII(L, key->cast5.K[1], key->cast5.K[17]);
|
||||
L ^= FI(R, key->cast5.K[0], key->cast5.K[16]);
|
||||
STORE32H(L,&pt[0]);
|
||||
STORE32H(R,&pt[4]);
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
void cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *key)
|
||||
{
|
||||
_cast5_ecb_decrypt(ct,pt,key);
|
||||
burn_stack(sizeof(ulong32)*3);
|
||||
}
|
||||
#endif
|
||||
|
||||
int cast5_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
int keylen;
|
||||
unsigned char key[16];
|
||||
unsigned char pt[8];
|
||||
unsigned char ct[8];
|
||||
} tests[] = {
|
||||
{ 16,
|
||||
{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A},
|
||||
{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2}
|
||||
},
|
||||
{ 10,
|
||||
{0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, 0x23, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B},
|
||||
},
|
||||
{ 5,
|
||||
{0x01, 0x23, 0x45, 0x67, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
{0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E}
|
||||
}
|
||||
};
|
||||
int i, y, err;
|
||||
symmetric_key key;
|
||||
unsigned char tmp[2][8];
|
||||
|
||||
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
|
||||
if ((err = cast5_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
cast5_ecb_encrypt(tests[i].pt, tmp[0], &key);
|
||||
cast5_ecb_decrypt(tmp[0], tmp[1], &key);
|
||||
if ((memcmp(tmp[0], tests[i].ct, 8) != 0) || (memcmp(tmp[1], tests[i].pt, 8) != 0)) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
|
||||
for (y = 0; y < 8; y++) tmp[0][y] = 0;
|
||||
for (y = 0; y < 1000; y++) cast5_ecb_encrypt(tmp[0], tmp[0], &key);
|
||||
for (y = 0; y < 1000; y++) cast5_ecb_decrypt(tmp[0], tmp[0], &key);
|
||||
for (y = 0; y < 8; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
|
||||
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
int cast5_keysize(int *desired_keysize)
|
||||
{
|
||||
_ARGCHK(desired_keysize != NULL);
|
||||
if (*desired_keysize < 5) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
} else if (*desired_keysize > 16) {
|
||||
*desired_keysize = 16;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
56
cbc_decrypt.c
Normal file
56
cbc_decrypt.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_CBC *cbc)
|
||||
{
|
||||
int x, err;
|
||||
unsigned char tmp[MAXBLOCKSIZE], tmp2[MAXBLOCKSIZE];
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(cbc != NULL);
|
||||
|
||||
/* decrypt the block from ct into tmp */
|
||||
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key);
|
||||
|
||||
/* 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 */
|
||||
for (x = 0; x < cbc->blocklen; x++) {
|
||||
/* copy CT in case ct == pt */
|
||||
tmp2[x] = ct[x];
|
||||
|
||||
/* actually decrypt the byte */
|
||||
pt[x] = tmp[x] ^ cbc->IV[x];
|
||||
}
|
||||
|
||||
/* replace IV with this current ciphertext */
|
||||
for (x = 0; x < cbc->blocklen; x++) {
|
||||
cbc->IV[x] = tmp2[x];
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(tmp, sizeof(tmp));
|
||||
zeromem(tmp2, sizeof(tmp2));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
52
cbc_encrypt.c
Normal file
52
cbc_encrypt.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_CBC *cbc)
|
||||
{
|
||||
int x, err;
|
||||
unsigned char tmp[MAXBLOCKSIZE];
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(cbc != NULL);
|
||||
|
||||
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* is blocklen valid? */
|
||||
if (cbc->blocklen < 0 || cbc->blocklen > (int)sizeof(cbc->IV)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* xor IV against plaintext */
|
||||
for (x = 0; x < cbc->blocklen; x++) {
|
||||
tmp[x] = pt[x] ^ cbc->IV[x];
|
||||
}
|
||||
|
||||
/* encrypt */
|
||||
cipher_descriptor[cbc->cipher].ecb_encrypt(tmp, ct, &cbc->key);
|
||||
|
||||
/* store IV [ciphertext] for a future block */
|
||||
for (x = 0; x < cbc->blocklen; x++) {
|
||||
cbc->IV[x] = ct[x];
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(tmp, sizeof(tmp));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
43
cbc_start.c
Normal file
43
cbc_start.c
Normal 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 CBC
|
||||
|
||||
int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_CBC *cbc)
|
||||
{
|
||||
int x, err;
|
||||
|
||||
_ARGCHK(IV != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(cbc != NULL);
|
||||
|
||||
/* bad param? */
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* setup cipher */
|
||||
if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cbc->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* copy IV */
|
||||
cbc->blocklen = cipher_descriptor[cipher].block_length;
|
||||
cbc->cipher = cipher;
|
||||
for (x = 0; x < cbc->blocklen; x++) {
|
||||
cbc->IV[x] = IV[x];
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
48
cfb_decrypt.c
Normal file
48
cfb_decrypt.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/* 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_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb)
|
||||
{
|
||||
int err;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(cfb != NULL);
|
||||
|
||||
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* is blocklen/padlen valid? */
|
||||
if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) ||
|
||||
cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
while (len-- > 0) {
|
||||
if (cfb->padlen == cfb->blocklen) {
|
||||
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
|
||||
cfb->padlen = 0;
|
||||
}
|
||||
cfb->pad[cfb->padlen] = *ct;
|
||||
*pt = *ct ^ cfb->IV[cfb->padlen];
|
||||
++pt;
|
||||
++ct;
|
||||
++cfb->padlen;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
46
cfb_encrypt.c
Normal file
46
cfb_encrypt.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb)
|
||||
{
|
||||
int err;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(cfb != NULL);
|
||||
|
||||
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* is blocklen/padlen valid? */
|
||||
if (cfb->blocklen < 0 || cfb->blocklen > (int)sizeof(cfb->IV) ||
|
||||
cfb->padlen < 0 || cfb->padlen > (int)sizeof(cfb->pad)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
while (len-- > 0) {
|
||||
if (cfb->padlen == cfb->blocklen) {
|
||||
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key);
|
||||
cfb->padlen = 0;
|
||||
}
|
||||
cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);
|
||||
++pt;
|
||||
++ct;
|
||||
++cfb->padlen;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
47
cfb_start.c
Normal file
47
cfb_start.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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_start(int cipher, const unsigned char *IV, const unsigned char *key,
|
||||
int keylen, int num_rounds, symmetric_CFB *cfb)
|
||||
{
|
||||
int x, err;
|
||||
|
||||
_ARGCHK(IV != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(cfb != NULL);
|
||||
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* copy data */
|
||||
cfb->cipher = cipher;
|
||||
cfb->blocklen = cipher_descriptor[cipher].block_length;
|
||||
for (x = 0; x < cfb->blocklen; x++)
|
||||
cfb->IV[x] = IV[x];
|
||||
|
||||
/* init the cipher */
|
||||
if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* encrypt the IV */
|
||||
cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
|
||||
cfb->padlen = 0;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
957
changes
Normal file
957
changes
Normal file
@@ -0,0 +1,957 @@
|
||||
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
|
||||
using the default build options on the x86.
|
||||
-- Updated eax so the eax_done() would clear the state [like hmac,pmac,ocb] when
|
||||
CLEAN_STACK has been defined.
|
||||
-- added LTC_TEST support to rmd160
|
||||
-- updates to mycrypt_pk.h
|
||||
-- updated rand_prime() to faciliate making RSA composites
|
||||
-- DSA/RSA now makes composites of the exact size desired.
|
||||
-- Refactored quite a bit of the code, fewer functions per C file
|
||||
-- cleaned up the makefiles to organize the objects logically
|
||||
-- added ICC makefile along with "profiled" targets for both GNU and ICC compilers
|
||||
-- Marked functions for removal before v1.00 see PLAN for more information
|
||||
-- GCC 3.4.0 tested and seems to work
|
||||
-- Added PKCS #5 support
|
||||
-- Fixed typo in comment header of .C files ;-)
|
||||
-- Added PKCS #1 OAEP and PSS support.
|
||||
|
||||
Feb 20th, 2004
|
||||
v0.94 -- removed unused variables from ocb.c and fixed it to match known test vectors.
|
||||
-- Added PMAC support, minor changes to OMAC/EAX code [I think....]
|
||||
-- Teamed up with Brian Gladman. His code verifies against my vectors and my code
|
||||
verifies against his test vectors. Hazaa for co-operation!
|
||||
-- Various small changes (added missing ARGCHKs and cleaned up indentation)
|
||||
-- Optimization to base64, removed unused variable "c"
|
||||
-- Added base64 gen to demos/tv_gen.c
|
||||
-- Fix to demos/x86_prof.c to correctly identify the i386 architecture... weird...
|
||||
-- Fixed up all of the PK code by adding missing error checking, removed "res" variables,
|
||||
shrunk some stack variables, removed non-required stack variables and added proper
|
||||
error conversion from MPI to LTC codes. I also spotted a few "off by one" error
|
||||
checking which could have been used to force the code to read past the end of
|
||||
the buffer (in theory, haven't checked if it would work) by a few bytes.
|
||||
-- Added checks to OUTPUT_BIGNUM so the *_export() functions cannot overflow the output and I
|
||||
also modded it so it stores in the output provided to the function (that is not on
|
||||
the local stack) which saves memory and time.
|
||||
-- Made SAFER default to disabled for now (plans are to cleanhouse write an implementation later)
|
||||
-- Added the 512-bit one-way hash WHIRLPOOL which clocks in at 138 cycles per byte on my
|
||||
Athlon XP [for comparison, SHA-512 clocks in at 77 cycles per byte]. This code uses the
|
||||
teams new sbox design (not the original NESSIE one).
|
||||
|
||||
|
||||
Jan 25th, 2004
|
||||
v0.93 -- [note: deleted v0.93 changes by accident... recreating from memory...]
|
||||
-- Fix to RC2 to not deference pointer before ARGCHK
|
||||
-- Fix to NOEKEON to match published test vectors as well as cleaned up the code a bit
|
||||
-- Optimized Twofish [down to 28 cycles/byte on my box] and Blowfish
|
||||
-- Fix to OMAC to test cipher block size first [prevents wasting any time]
|
||||
-- Added more OMAC test vectors
|
||||
-- Added EAX Encrypt+Authenticate support
|
||||
-- Fix to DSA to check return of a few LTM functions I forgot [mp_to_unsigned_bin]
|
||||
-- Added common headers to all C files
|
||||
-- CTR mode supports big and little [default] endian counters now.
|
||||
-- fix to find_cipher_any() so that it can handle a fragmented cipher_descriptor table.
|
||||
-- added find_hash_any() akin to find_cipher_any().
|
||||
-- Added EAX code to demos/tv_gen.c Hazaa!
|
||||
-- Removed SONY defines and files from codebase.
|
||||
-- Added OCB support [patents be damned] and to demos/tv_gen.c
|
||||
-- Merge all of the INPUT/OUTPUT BIGNUM macros (less toc) into mycrypt_pk.h
|
||||
-- Made appropriate changes to the debug string in crypt.c
|
||||
|
||||
Dec 24th, 2003
|
||||
v0.92 -- Updated the config.pl script so the options have more details.
|
||||
-- Updated demos/tv_gen to include RIPEMD hashes
|
||||
-- Updated Twofish so when TWOFISH_ALL_TABLES is defined a pre-computed RS table
|
||||
is included [speedup: slight, about 4k cycles on my Athlon].
|
||||
-- Re-wrote the twofish large key generation [the four 8x32 key dependent tables]. Now about twice as fast.
|
||||
With both optimizations [e.g. TWOFISH_ALL_TABLES defined] a 128-bit Twofish key can now be scheduled
|
||||
in 26,000 cycles on my Athlon XP [as opposed to 49,000 before] when optimized for size.
|
||||
-- config.pl has been updated so rmd128.o and rmd160.o are objects included in the build [oops]
|
||||
-- Andrew Mann found a bug in rsa_exptmod() which wouldn't indicate if the wrong type of key was specified
|
||||
(e.g. not PK_PRIVATE or PK_PUBLIC)
|
||||
-- Fixed up demos/x86_prof so it sorts the output now :-)
|
||||
-- The project is now powered by radioactive rubber pants.
|
||||
-- Fixed dh_encrypt_key() so if you pass it a hash with a smaller output than the input key it
|
||||
will return CRYPT_INVALID_HASH [to match what ecc_encrypt_key() will do]
|
||||
-- Merge the store/encrypt key part of ecc_encrypt_key() as per dh_encrypt_key() [can you guess what I'm upto?]
|
||||
-- Massive updates to the prime generation code. I use the LTM random prime functions [and provide a nice
|
||||
interface between the LTC PRNG's and the LTM generic prng prototype]. I also use a variable number of tests
|
||||
depending on the input size. This nicely speeds up most prime generation/testing within the library.
|
||||
-- Added SHA-224 to the list of hashes.
|
||||
-- Made HMAC test vectors constant and static [takes ROM space instead of RAM]
|
||||
-- This release was brought to you by the letter P which stands for Patent Infringement.
|
||||
-- Added generic HASH_PROCESS macro to mycrypt_hash.h which simplifies the hash "process" functions
|
||||
I also optimized the compression functions of all but MD2 to not perform input copies when avoidable.
|
||||
-- Removed the division from the Blowfish setup function [dropped 3k cycles on my Athlon]
|
||||
-- Added stack cleaning to rijndael, cast5 so now all ciphers have CLEAN_STACK code.
|
||||
-- Added Skipjack to the list of ciphers [made appropriate changes to demos/test.c, demos/tv_gen.c and
|
||||
demos/x86_prof.c]
|
||||
-- Added mechanical testing to cipher test vector routines. Now it encrypts 1000 times, then decrypts and
|
||||
compares. Any fault (e.g. bug in code, compiler) in the routines is likely to show through. Doesn't
|
||||
stress test the key gen though...
|
||||
-- Matt Johnson found a bug in the blowfish.c apparently I was out of my mind and put twofish defines in there
|
||||
The code now builds with any config. Thanks.
|
||||
-- Added OMAC1 Message Authentication Code support to the library.
|
||||
-- Re-prototyped the hash "process" and "done" to prevent buffer overflows [which don't seem easy to exploit].
|
||||
Updated HMAC code to use them too. Hazaa!
|
||||
-- Fixed bug in ECC code which wouldn't do an _ARGCHK on stat in ecc_verify_hash().
|
||||
-- Fixed [temp fix] bug in all PK where the OUTPUT_BIGNUM macros would not trap errors on the to_unsigned_bin
|
||||
conversion [now returns CRYPT_MEM, will fix it up better later]
|
||||
-- Added DSA to the list of supported PK algorithms.
|
||||
-- Fixed up various ciphers to &255 the input key bytes where required [e.g. where used to index a table] to prevent
|
||||
problems on platforms where CHAR_BIT != 8
|
||||
-- Merged in LibTomMath v0.28
|
||||
-- Updated demos/x86_prof.c to use Yarrow during the key sched testing [was horribly slow on platforms with blockable
|
||||
/dev/random].
|
||||
-- Added OMAC/HMAC tests to demos/tv_gen and I now store the output of this in notes/
|
||||
-- Fixed a bug in config.pl that wouldn't have TWOFISH_TABLES defined by default (too many commas on the line)
|
||||
-- Fixed bug in hmac_done(). Apparently FIPS-198 [HMAC] specifies that the output can be truncated. My code
|
||||
would not support that (does now just like the new OMAC code).
|
||||
-- Removed "hashsize" from hmac_state as it wasn't being used.
|
||||
-- Made demos/test.c stop if OMAC or HMAC tests fail (instead of just printing a failed message and keep going).
|
||||
-- Updated notes/tech0003.txt to take into account the existence of Skipjack [also I fixed a few typos].
|
||||
-- Slight changes to Noekeon, with SMALL_CODE undefined it uses a fully unrolled version. Dropped +10 cycles/byte
|
||||
on my Athlon (35 cycles per byte or 410.4Mbit/sec at 1795Mhz)
|
||||
-- Added _ARGCHK() calls to is_prime() for the two input pointers.
|
||||
|
||||
Sept 25th, 2003
|
||||
v0.91 -- HMAC fix of 0.90 was incorrect for keys larger than the block size of the hash.
|
||||
-- Added error CRYPT_FILE_NOTFOUND for the file [hmac/hash] routines.
|
||||
-- Added RIPEMD hashes to the hashsum demo.
|
||||
-- Added hashsum demo to MSVC makefile.
|
||||
-- Added RMD160 to the x86_prof demo [oops]
|
||||
-- Merged in LibTomMath-0.27 with a patch to mp_shrink() that will be in LibTomMath-0.28
|
||||
Fixes another potential memory leak.
|
||||
|
||||
Sept 7th, 2003
|
||||
v0.90 -- new ROL/ROR for x86 GCC
|
||||
-- Jochen Katz submitted a patch to the makefile to prevent "make" from making the .a library
|
||||
when not required.
|
||||
== By default the KR code is not enabled [it's only a demo anyways!]
|
||||
-- changed the "buf" in ecc_make_key from 4KB to 128 bytes [since the largest key is 65 bytes]
|
||||
-- hmac_done() now requires you pass it the size of the destination buffer to prevent
|
||||
buffer overflows. (API CHANGE)
|
||||
-- hmac/hash filebased routines now return CRYPT_NOP if NO_FILE is defined.
|
||||
-- I've removed the primes from dh.c and replaced them with DR safe primes suitable for the default
|
||||
configuration of LibTomMath. Check out these comparisons on a 1.3Ghz Athlon XP, optimized for size,
|
||||
|
||||
768-bit, 4 vs. 10
|
||||
1024-bit, 8 vs. 18
|
||||
1280-bit, 12 vs. 34
|
||||
1536-bit, 20 vs. 56
|
||||
1792-bit 28 vs. 88
|
||||
2048-bit, 40 vs. 124
|
||||
2560-bit, 71 vs. 234
|
||||
3072-bit, 113 vs. 386
|
||||
4096-bit, 283 vs. 916
|
||||
|
||||
Times are all in milliseconds for key generation. New primes times on the left. This makes the code binary
|
||||
incompatible with previous releases. However, this addition is long overdue as LibTomMath has supported DR
|
||||
reductions for quite some time.
|
||||
-- Added RIPE-MD 128 and 160 to the list of supported hashes [10 in total].
|
||||
-- The project has been released as public domain. TDCAL no longer applies.
|
||||
|
||||
July 15th, 2003
|
||||
v0.89 -- Fix a bug in bits.c which would prevent it from building with msvc
|
||||
-- Merged in LibTomMath v0.24 [and I used the alloc/free macros this time!]
|
||||
-- Removed the LTC version of next_prime() and replaced it with a call to the
|
||||
mp_prime_next_prime() from LibTomMath
|
||||
-- reverted bits.c to the 0.86 copy since the new one doesn't build in MSVC
|
||||
or cygwin.
|
||||
|
||||
Jul 10th, 2003
|
||||
v0.88 -- Sped up CAST5 key schedule for MSVC
|
||||
-- added "ulong32" which allows people on 64-bit platforms to force the 32-bit tables in
|
||||
ciphers like blowfish and AES to be 32-bits. E.g. when unsigned long is 64-bits.
|
||||
-- Optimized the SAFER-SK64, SAFER-SK128, SAFER+, RC5 and RC6 key schedule [big time!]
|
||||
-- Optimized SHA-1 and SHA-256 quite a bit too.
|
||||
-- Fixed up the makefile to use -fomit-frame-pointer more liberally
|
||||
-- Added tv_gen program which makes test vectors for ciphers/hashes
|
||||
-- Merged in LibTomMath v0.22
|
||||
|
||||
Jun 19th, 2003
|
||||
v0.87 -- Many MSVC optimizations to the code base
|
||||
-- Improved the AES and Twofish key schedule [faster, more constant time]
|
||||
-- Tons of optimizations here and there.
|
||||
|
||||
Jun 15th, 2003
|
||||
v0.86 -- Fixed up AES to workaround MSVC optimizer bug
|
||||
-- Merged in fresh LTM base [based on v0.20] so there are no warnings with MSVC
|
||||
-- Wrote x86_prof which will time the hashes and ciphers downto cycles per byte.
|
||||
-- Fixed up demos/encrypt to remove serpent_desc from the list
|
||||
-- Re-enabled MSVC optimizations w00t w00t
|
||||
-- Replaced "errno" with "err" in all functions that had it so it wouldn't clash
|
||||
with the global "errno"
|
||||
-- Removed a set of unused variables from certain functions
|
||||
-- Removed {#line 0 "..."} stuff from mpi.c to comply with ISO C :-)
|
||||
|
||||
Jun 11th, 2003
|
||||
v0.85 -- Swapped in a new AES routine
|
||||
-- Removed Serpent
|
||||
-- Added TDCAL policy document
|
||||
|
||||
Jun 1st, 2003
|
||||
v0.84 -- Removed a 4KB buffer from rsa_decrypt_key that wasn't being used no more
|
||||
-- Fixed another potential buffer problem. Not an overflow but could cause the
|
||||
PK import routines to read past the end of the buffer.
|
||||
-- Optimized the ECC mulmod more by removing a if condition that will always be false
|
||||
-- Optimized prime.c to not include a 2nd prime table, removed code from is_prime calls prime
|
||||
test from LibTomMath now
|
||||
-- Added LTC_TEST define which when defined will enable the test vector routines [see mycrypt_custom.h]
|
||||
-- Removed ampi.o from the depends cuz it ain't no not working in *nix with it [routines are in mpi.c now].
|
||||
|
||||
|
||||
Mar 29th, 2003
|
||||
v0.83 -- Optimized the ecc_mulmod, it's faster and takes less heap/stack space
|
||||
-- Fixed a free memory error in ecc_mulmod and del_point which would try to free NULL
|
||||
-- Fixed two serious bugs in rsa_decrypt_key and rsa_verify_hash that would allow a trivialy
|
||||
buffer overflow.
|
||||
-- Fixed a bug in the hmac testing code if you don't register all the hashes it won't return
|
||||
errors now.
|
||||
|
||||
Mar 15th, 2003
|
||||
v0.82 -- Manual updated
|
||||
-- Added MSVC makefile [back, actually its written from scratch to work with NMAKE]
|
||||
-- Change to HMAC helper functions API to avoid buffer overflow [source changes]
|
||||
-- the rsa_encrypt_key was supposed to reject key sizes out of bounds ...
|
||||
same fix to the rsa_sign_hash
|
||||
-- Added code to ensure that that chaining mode code (cfb/ofb/ctr/cbc) have valid
|
||||
structures when being called. E.g. the indexes to the pad/ivs are not out of bounds
|
||||
-- Cleaned up the DES code and simplified the core desfunc routine.
|
||||
-- Simplified one of the boolean functions in MD4
|
||||
|
||||
Jan 16th, 2003
|
||||
v0.81 -- Merged in new makefile from Clay Culver and Mike Frysinger
|
||||
-- Sped up the ECC mulmod() routine by making the word size adapt to the input. Saves a whopping 9 point
|
||||
operations on 521-bit keys now (translates to about 8ms on my Athlon XP). I also now use barrett reduction
|
||||
as much as possible. This sped the routine up quite a bit.
|
||||
-- Fixed a huge flaw in ecc_verify_hash() where it would return CRYPT_OK on error... Now fixed.
|
||||
-- Fixed up config.pl by fixing an invalid query and the file is saved in non-windows [e.g. not CR/LF] format
|
||||
(fix due to Mika Boström)
|
||||
-- Merged in LibTomMath for kicks
|
||||
-- Changed the build process so that by default "mycrypt_custom.h" is included and provided
|
||||
The makefile doesn't include any build options anymore
|
||||
-- Removed the PS2 and VC makefiles.
|
||||
|
||||
Dec 16th, 2002
|
||||
v0.80 -- Found a change I made to the MPI that is questionable. Not quite a bug but definately not desired. Had todo
|
||||
with the digit shifting. In v0.79 I simply truncated without zeroing. It didn't cause problems during my
|
||||
testing but I fixed it up none the less.
|
||||
-- Optimized s_mp_mul_dig() from MPI to do a minimal number of passes.
|
||||
-- Fixed in rsa_exptmod() where I was getting the size of the result. Basically it accomplishes the same thing
|
||||
but the fixed code is more readable.
|
||||
-- Fixed slight bug in dh_sign_hash() where the random "k" value was 1 byte shorter than it should have been. I've
|
||||
also made the #define FAST_PK speed up signatures as well. Essentially FAST_PK tells the DH sub-system to
|
||||
limit any private exponent to 256-bits. Note that when FAST_PK is defined does not make the library
|
||||
binary or source incompatible with a copy of the library with it undefined.
|
||||
-- Removed the DSA code. If you want fast diffie-hellman just define FAST_PK :-)
|
||||
-- Updated dh_sign_hash()/dh_verify_hash() to export "unsigned" bignums. Saves two bytes but is not binary
|
||||
compatible with the previous release... sorry! I've performed the same fix to the ecc code as well.
|
||||
-- Fixed up the PK code to remove all use of mp_toraw() and mp_read_raw() [get all the changes out of the way now]
|
||||
-- Fixed a bug in the DH code where it missed trapping a few errors if they occurred.
|
||||
-- Fixed a slight "its-not-a-bug-but-could-be-done-better" bug in the next_prime() function. Essentially it was
|
||||
testing to ensure that in the loop that searches for the next candidate that the step never grows beyond
|
||||
65000. Should have been testing for MP_DIGIT_MAX
|
||||
-- Spruced up the config.pl script. It now makes a header file "mycrypt_custom.h" which can be included *before*
|
||||
you include mycrypt.h. This allows you to add libtomcrypt to a project without completely changing your make
|
||||
system around. Note that you should use the makefile it writes to at least build the library initially.
|
||||
-- Used splint to check alot of the code out. Tons of minor fixes and explicit casts added.
|
||||
-- Also made all the internal functions of MPI are now static to avoid poluting the namespace
|
||||
-- **Notice**: There are no planned future releases for at least a month from the this release date.
|
||||
|
||||
Dec 14th, 2002
|
||||
v0.79 -- Change to PK code [binary and source]. I made it so you have to pass the buffer size to the *_decrypt_key and
|
||||
*_verify_hash functions. This prevents malformed packets from performing buffer overflows. I've also trimmed
|
||||
the packet header size [by 4 bytes].
|
||||
-- Made the test program halt on the first error it occurs. Also made it trap more errors than before.
|
||||
-- Wrote the first chapter of my new book [DRAFT!], not in this package but check my website!
|
||||
-- Included a perl script "config.pl" that will make "makefile.out" according to the users needs.
|
||||
-- Added shell script to look for latest release
|
||||
-- Merge DH and ECC key defines from mycrypt_cfg.h into the makefiles
|
||||
-- updated the makefile to use BSD friendly archiving invokations
|
||||
-- Changed the DH and ECC code to use base64 static key settings [e.g. the primes]. Dropped the code size by 3KB
|
||||
and is ever-so-slightly faster than before.
|
||||
-- added "mp_shrink" function to shrink the size of bignums. Specially useful for PK code :-)
|
||||
-- Added new exptmod function that calculates a^b mod c with fewer multiplies then before [~20% for crypto
|
||||
sized numbers]. Also added a "low mem" variant that doesn't use more than 20KB [upto 4096 bit nums] of
|
||||
heap todo the calculation. Both are #define'able controlled
|
||||
-- Added XREALLOC macro to provide realloc() functionality.
|
||||
-- Added fix where in rsa_import() if you imported a public key or a non-optimized key it would free the mp_int's
|
||||
not being used.
|
||||
-- Fixed potential bug in the ECC code. Only would occur on platforms where char is not eight bits [which isn't
|
||||
often!]
|
||||
-- Fixed up the ECC point multiplication, its about 15% faster now
|
||||
-- While I was at it [since the lib isn't binary backwards compatible anyways] I've fixed the PK export routines
|
||||
so they export as "unsigned" types saving 1 byte per bignum outputted. Not a lot but heck why not.
|
||||
|
||||
Nov 28th, 2002
|
||||
v0.78 -- Made the default ARGCHK macro a function call instead which reduced the code size from 264KB to 239KB.
|
||||
-- Fixed a bug in the XTEA keysize function which called ARGCHK incorrectly.
|
||||
-- Added Noekeon block cipher at 2,800 bytes of object code and 345Mbit/sec it is a welcome addition.
|
||||
-- Made the KR code check if the other PK systems are included [provides error when building otherwise].
|
||||
-- Made "aes" an alias for Rijndael via a pre-processor macro. Now you can use "aes_ecb_encrypt", etc... :-)
|
||||
Thanks to Jean-Luc Cooke for the "buzzword conformance" suggestion.
|
||||
-- Removed the old PK code entirely (e.g. rsa_sign, dh_encrypt). The *_sign_hash and *_encrypt_key functions
|
||||
are all that is to remain.
|
||||
-- **NOTE** Changed the PK *_import (including the keyring) routine to accept a "inlen" parameter. This fixes a
|
||||
bug where improperly made key packets could result in reading passed the end of the buffer. This means
|
||||
the code is no longer source compatible but still binary compatible.
|
||||
-- Fixed a few other minor bugs in the PK import code while I was at it.
|
||||
|
||||
Nov 26th, 2002
|
||||
v0.77 -- Updated the XTEA code to use pre-computed keys. With optimizations for speed it achieves 222Mbit/sec
|
||||
compared to the 121Mbit/sec before. It is 288 bytes bigger than before.
|
||||
-- Cleaned up some of the ciphers and hashes (coding style, cosmetic changes)
|
||||
-- Optimized AES slightly for 256-bit keys [only one if statement now, still two for 192-bit keys]
|
||||
-- Removed most test cases from Blowfish, left three of them there. Makes it smaller and faster to test.
|
||||
-- Changed the primality routines around. I now use 8 rounds of Rabin-Miller, I use 256 primes in the sieve
|
||||
step and the "rand_prime" function uses a modified sieve that avoids alot of un-needed bignum work.
|
||||
-- Fixed a bug in the ECC/DH signatures where the keys "setting" value was not checked for validity. This means
|
||||
that a invalid value could have caused segfaults, etc...
|
||||
-- **NOTE** Changed the way the ECC/DH export/import functions work. They are source but not binary compatible
|
||||
with v0.76. Essentially insteading of exporting the setting index like before I export the key size. Now
|
||||
if you ever re-configure which key settings are supported the lib will still be able to make use of your
|
||||
keys.
|
||||
-- Optimized Blowfish by inlining the round function, unrolling it for four rounds then using a for loop for the
|
||||
rest. It achieves a rate of 425Mbit/sec with the new code compared to 314Mbit/sec before. The new blowfish
|
||||
object file is 7,813 bytes compared to 8,663 before and is 850 bytes smaller. So the code is both smaller and
|
||||
faster!
|
||||
-- Optimized Twofish as well by inlining the round function. Gets ~400Mbit/sec compared to 280Mbit/sec before
|
||||
and the code is only 78 bytes larger than the previous copy.
|
||||
-- Removed SMALL_PRIME_TAB build option. I use the smaller table always.
|
||||
-- Fixed some mistakes concerning prime generation in the manual.
|
||||
-- [Note: sizes/speeds are for GCC 3.2 on an x86 Athlon XP @ 1.53Ghz]
|
||||
|
||||
Nov 25th, 2002
|
||||
v0.76 -- Updated makefiles a bit more, use "-Os" instead of "-O2" to optimize for size. Got the lib
|
||||
downto 265KB using GCC 3.2 on my x86 box.
|
||||
-- Updated the SAFER+, Twofish and Rijndael test vector routine to use the table driven design.
|
||||
-- Updated all other test vector routines to return as soon as an error is found
|
||||
-- fixed a bug in the test program where errors in the hash test routines would not be reported
|
||||
correctly. I found this by temporarily changing one of the bytes of the test vectors. All the
|
||||
hashes check out [the demos/test.c would still have reported an error, just the wrong one].
|
||||
|
||||
|
||||
Nov 24th, 2002
|
||||
v0.75 -- Fixed a flaw in hash_filehandle, it should ARGCHK that the filehandle is not NULL
|
||||
-- Fixed a bug where in hash_file if the call to hash_filehandle failed the open file would
|
||||
not be closed.
|
||||
-- Added more strict rules to build process, starting to weed out "oh this works in GCC" style code
|
||||
In the next release "-Wconversion" will be enabled which will deal with all implicit casts.
|
||||
|
||||
Nov 22nd, 2002 [later in the day]
|
||||
v0.74 -- Wrote a small variant of SAFER+ which shaved 50KB off the size of the library on x86 platforms
|
||||
-- Wrote a build option to remove the PK packet functions [keeps the encrypt_key/sign_hash functions]
|
||||
-- Wrote a small variant of Rijndael (trimmed 13KB)
|
||||
-- Trimmed the TIGER/192 hash function a bit
|
||||
-- Overall the entire lib compiled is 295KB [down from 400KB before]
|
||||
-- Fixed a few minor oversights in the MSVC makefile
|
||||
|
||||
Nov 22nd, 2002
|
||||
v0.73 -- Fixed bug in RC4 code where it could only use 255 byte keys.
|
||||
-- Fixed bug in yarrow code where it would allow cast5 or md2 to be used with it...
|
||||
-- Removed the ecc compress/expand points from the global scope. Reduces namespace polution
|
||||
-- Fixed bug where if you used the SPRNG you couldn't pass NULL as your prng_state which you should be
|
||||
able todo since the SPRNG has no state...
|
||||
-- Corrected some oversights in the manual and the examples...
|
||||
-- By default the GF(2^W) math library is excluded from the build. The source is maintained because I wrote it
|
||||
and like it :-). This way the built library is a tad smaller
|
||||
-- the MSVC makefile will now build for a SPACE optimized library rather than TIME optimized.
|
||||
|
||||
Nov 21th, 2002
|
||||
v0.72 -- Fixed bug in the prime testing. In the Miller-Rabin test I was raising the base to "N-1" not "r".
|
||||
The math still worked out fine because in effect it was performing a Fermat test. Tested the new code and it
|
||||
works properly
|
||||
-- Fixed some of the code where it was still using the old error syntax
|
||||
-- Sped up the RSA decrypt/sign routines
|
||||
-- Optimized the ecc_shared_secret routine to not use so much stack
|
||||
-- Fixed up the makefile to make releases where the version # is in the file name and directory it will unzip
|
||||
to
|
||||
|
||||
Nov 19th, 2002
|
||||
v0.71 -- HELP TOM. I need tuition for the January semester. Now I don't want to force donations [nor will I ever]
|
||||
but I really need the help! See my website http://tom.iahu.ca/help_tom.html for more details. Please help
|
||||
if you can!
|
||||
--------------------------------------------------------------------------------------------------------------
|
||||
-- Officially the library is no longer supported in GCC 3.2 in windows [cygwin].
|
||||
In windows you can either use GCC 2.95.3 or try your luck with 3.2 It seems that
|
||||
"-fomit-frame-pointer" is broken in the windows build [but not the linux x86 build???]
|
||||
If you simply must use 3.2 then I suggest you limit the optimizations to simply "-O2"
|
||||
-- Started new error handling API. Similar to the previous except there are more error codes than just
|
||||
CRYPT_ERROR
|
||||
-- Added my implementation of the MD2 hash function [despite the errors in the RFC I managed to get it right!]
|
||||
-- Merged in more changes from Sky Schulz. I have to make mention here that he has been a tremendous help in
|
||||
getting me motivated to make some much needed updates to the library!
|
||||
-- Fixed one of the many mistakes in the manual as pointed out by Daniel Richards
|
||||
-- Fixed a bug in the RC4 code [wasn't setting up the key correctly]
|
||||
-- Added my implementation of the CAST5 [aka CAST-128] block cipher (conforms...)
|
||||
-- Fixed numerous bugs in the PK code. Essentially I was "freeing" keys when the import failed. This is neither
|
||||
required nor a good a idea [double free].
|
||||
-- Tom needs a job.
|
||||
-- Fixed up the test harness as requested by Sky Schulz. Also modifed the timing routines to run for X seconds
|
||||
and count # of ops performed. This is more suitable than say encrypting 10 million blocks on a slow processor
|
||||
where it could take minutes!
|
||||
-- Modified test programs hashsum/encrypt to use the new algorithms and error handling syntax
|
||||
-- Removed the PKCS code since it was incomplete. In the future I plan on writing a "add-on" library that
|
||||
provides PKCS support...
|
||||
-- updated the config system so the #defines are in the makefiles instead of mycrypt_cfg.h
|
||||
-- Willing to work on an hourly basis for 15$ CDN per hour.
|
||||
-- updated the test program to not test ciphers not included
|
||||
-- updated the makefile to make "rsa_sys.c" a dependency of rsa.o [helps develop the code...]
|
||||
-- fixed numerous failures to detect buffer overflows [minor] in the PK code.
|
||||
-- fixed the safer [64-bit block version] test routines which didn't check the returns of the setup
|
||||
function
|
||||
-- check out my CV at http://tom.iahu.ca/cv.html
|
||||
-- removed the GBA makefile and code from demos/test.c [not a particularly useful demo...]
|
||||
-- merged in rudimentary [for testing] PS2 RNG from Sky Schulz
|
||||
-- merged in PS2 timer code [only shell included due to NDA reasons...]
|
||||
-- updated HMAC code to return errors where possible
|
||||
-- Thanks go to Sky Schulz who bought me a RegCode for TextPad [the official editor of libtomcrypt]
|
||||
|
||||
Nov 12th, 2002
|
||||
v0.70 -- Updated so you can swap out the default malloc/calloc/free routines at build time with others. (Sky Schulz)
|
||||
-- Sky Schulz contributed some code towards autodetecting the PS2 in mycrypt_cfg.h
|
||||
-- Added PS2 makefile contributed by Sky Schulz [see a pattern forming?]
|
||||
-- Added ability to have no FILE I/O functions at all (see makefile), Sky Schulz....
|
||||
-- Added support for substituting out the clock() function (Sky Schulz)
|
||||
-- Fixed up makefile to include new headers in the HEADERS variable
|
||||
-- Removed "coin.c" as its not really useful anyways
|
||||
-- Removed many "debug" printfs that would show up on failures. Basically I wanted to ensure the only output
|
||||
would be from the developer themselves.
|
||||
-- Added "rc4.c" a RC4 implementation with a PRNG interface. Since RC4 isn't a block cipher it wouldn't work
|
||||
too well as a block cipher.
|
||||
-- Fixed ARGCHK macro usage when ARGTYPE=1 throughout the code
|
||||
-- updated makefile to make subdirectory properly (Sku Schulz)
|
||||
-- Started towards new API setup. Instead of checking for "== CRYPT_ERROR" you should check "!= CRYPT_OK"
|
||||
In future releases functions will return things other than CRYPT_ERROR on error to give more useful
|
||||
thread safe error reporting. The manual will be updated to reflect this. For this release all
|
||||
errors are returned as CRYPT_ERROR (except as noted) but in future releases this will change.
|
||||
-- Removed the zlib branch since its not really required anyways. Makes the package smaller
|
||||
|
||||
Nov 11th, 2002
|
||||
v0.69 -- Added ARGCHK (see mycrypt_argchk.h) "arguement checking" to all functions that accept pointers
|
||||
-- Note I forgot to change the CRYPT version tag in v0.68... fixed now.
|
||||
|
||||
Nov 8th, 2002
|
||||
v0.68 -- Fixed flaw in kr_import/kr_export that wasted 4 bytes. Source but not binary compatible with v0.67
|
||||
-- Fixed bug in kr_find_name that used memcmp to match strings. Uses strncmp now.
|
||||
-- kr_clear now sets the pointer to NULL to facilate debugging [e.g. using the keyring after clearing]
|
||||
-- static functions in _write/_read in keyring.c now check the return of ctr_encrypt/ctr_decrypt.
|
||||
-- Updated blowfish/rc2/rc5/rc6 keysize() function to not reject keys larger than the biggest key the
|
||||
respective ciphers can use.
|
||||
-- Fixed a bug in hashsum demo that would report the hash for files that don't exist!
|
||||
|
||||
Oct 16th, 2002
|
||||
v0.67 -- Moved the function prototypes into files mycrypt_*.h. To "install" the lib just copy all the
|
||||
header files "*.h" from the base of this project into your global include path.
|
||||
-- Made the OFB/CFB/CTR functions use "unsigned long" for the length instead of "int"
|
||||
-- Added keyring support for the PK functions
|
||||
-- ***API CHANGE*** changed the ecc_make_key and dh_make_key to act more like rsa_make_key. Basically
|
||||
move the first argument to the next to last.
|
||||
-- Fixed bug in dh_test() that wouldn't test the primality of the order of the sub-group
|
||||
-- replaced the primes in the DH code with new ones that are larger than the size they are
|
||||
associated with. That is a 1024-bit DH key will have a 1025-bit prime as the modulus
|
||||
-- cleaned up all the PK code, changed a bit of the API around [not source compatible with v0.66]
|
||||
-- major editing of the manual, started Docer program
|
||||
-- added 160 and 224 bit key settings for ECC. This makes the DH and ECC binary wise incompatible with v0.66
|
||||
-- Added an additional check for memory errors in is_prime() and cleaned up prime.c a bit
|
||||
-- Removed ID_TAG from all files [meh, not a big fan...]
|
||||
-- Removed unused variable from yarrow state and made AES/SHA256 the default cipher/hash combo
|
||||
-- Fixed a bug in the Yarrow code that called prng_is_valid instead of cipher_is_valid from yarrow_start()
|
||||
-- The ECB/CBC/OFB/CFB/CTR wrappers now check that the cipher is valid in the encrypt/decrypt calls
|
||||
Returns int now instead of void.
|
||||
|
||||
Sept 24th, 2002
|
||||
v0.66 -- Updated the /demos/test.c program to time the hashes correctly. Also it uses the yarrow PRNG for all of the
|
||||
tests meaning its possible to run on RNG less platforms
|
||||
-- Updated the /demos/hashsum.c program to hash from the standard input
|
||||
-- Updated the RSA code to make keys a bit quicker [update by Wayne Scott] by not making both primes at the same
|
||||
time.
|
||||
-- Dan Kaminsky suggested some cleanups for the code and the MPI config
|
||||
Code ships in unix LF format by default now too... will still build in MSVC and all... but if you want
|
||||
to read the stuff you'll have to convert it
|
||||
-- Changes to the manual to reflect new API [e.g. hash_memory/file have v0.65 prototypes]and some typos fixed
|
||||
|
||||
Sept 20th, 2002
|
||||
v0.65 -- Wayne Scott (wscott@bitmover.com) made a few of suggestions to improve the library. Most
|
||||
importantly he pointed out the math lib is not really required. He's also tested the lib on 18
|
||||
different platforms. According to him with only a few troubles [lack of /dev/random, etc] the
|
||||
library worked as it was supposed to. You can find the list at
|
||||
http://www.bitkeeper.com/Products.BitKeeper.Platforms.html
|
||||
-- Updated the hash_file and hash_memory functions to keep track of the size of the output
|
||||
-- Wayne Scott updated the demos/test.c file to use the SPRNG less and Yarrow more
|
||||
-- Modified the mycrypt_cfg.h to autodetect x86-32 machines
|
||||
|
||||
Sept 19th, 2002
|
||||
v0.64 -- wrote makefile for the GBA device [and hacked the demos/test.c file to support it conditionally]
|
||||
-- Fixed error in PK (e.g. ECC, RSA, DH) import functions where I was clobbering the packet error messages
|
||||
-- fixed more typos in the manual
|
||||
-- removed all unused variables from the core library (ignore the ID_TAG stuff)
|
||||
-- added "const char *crypt_build_settings" string which is a build time constant that gives a listing
|
||||
of all the build time options. Useful for debugging since you can send that to me and I will know what
|
||||
exactly you had set for the mycrypt_cfg.h file.
|
||||
-- Added control over endianess. Out of the box it defaults to endianess neutral but you can trivially
|
||||
configure the library for your platform. Using this I boosted RC5 from 660Mbit/sec to 785Mbit/sec on my
|
||||
Athlon box. See "mycrypt_cfg.h" for more information.
|
||||
|
||||
Sept 11th, 2002
|
||||
v0.63 -- Made hashsum demo output like the original md5sum program
|
||||
-- Made additions to the examples in the manual (fixed them up a bunch)
|
||||
-- Merged in the base64 code from Wayne Scott (wscott@bitmover.com)
|
||||
|
||||
Aug 29th, 2002
|
||||
v0.62 -- Added the CLEAN_STACK functionality to several of the hashes I forgot to update.
|
||||
|
||||
Aug 9th, 2002
|
||||
v0.61 -- Fixed a bug in the DES code [oops I read something wrong].
|
||||
|
||||
Aug 8th, 2002
|
||||
v0.60 -- Merged in DES code [and wrote 3DES-EDE code based on it] from Dobes V.
|
||||
|
||||
Aug 7th, 2002
|
||||
v0.59 -- Fixed a "unsigned long long" bug that caused v0.58 not to build in MSVC.
|
||||
-- Cleaned up a little in the makefile
|
||||
-- added code that times the hash functions too in the test program
|
||||
|
||||
Aug 3rd, 2002
|
||||
v0.58 -- Added more stack cleaning conditionals throughout the code.
|
||||
-- corrected some CLEAR_STACK conditionals... should have been CLEAN_STACK
|
||||
-- Simplified the RSA, DH and ECC encrypt() routines where they use CTR to encode the message
|
||||
now they only make one call to ctr_encrypt()/ctr_decrypt().
|
||||
|
||||
Aug 2nd, 2002
|
||||
v0.57 -- Fixed a few errors messages in the SAFER code to actually report the correct cipher name.
|
||||
-- rsa_encrypt() uses the "keysize()" method of the cipher being used to more accurately pick a
|
||||
key size. By default rsa_encrypt() will choose to use a 256-bit key but the cipher can turn that
|
||||
down if required.
|
||||
-- The rsa_exptmod() function will now more reliably detect invalid inputs (e.g. greater than the modulus).
|
||||
-- The padding method for RSA is more clearly documented. Namely if you want to encrypt/sign something of length
|
||||
N then your modulus must be of length 1+3N. So to sign a message with say SHA-384 [48 bytes] you need a
|
||||
145 byte (1160 bits) modulus. This is all in the manual now.
|
||||
-- Added build option CLEAN_STACK which will allow you to choose whether you want to clean the stack or not after every
|
||||
cipher/hash call
|
||||
-- Sped up the hash "process()" functions by not copying one byte at a time.
|
||||
++ (added just after I uploaded...)
|
||||
MD4 process() now handles input buffers > 64 bytes
|
||||
|
||||
Aug 1st, 2002
|
||||
v0.56 -- Cleaned up the comments in the Blowfish code.
|
||||
-- Oh yeah, in v0.55 I made all of the descriptor elements constant. I just forgot to mention it.
|
||||
-- fixed a couple of places where descriptor indexes were tested wrong. Not a huge bug but now its harder
|
||||
to mess up.
|
||||
-- Added the SAFER [64-bit block] ciphers K64, SK64, K128 and SK128 to the library.
|
||||
-- Added the RC2 block cipher to the library.
|
||||
-- Changed the SAFER define for the SAFER+ cipher to SAFERP so that the new SAFER [64-bit] ciphers
|
||||
can use them with less confusion.
|
||||
|
||||
July 29th, 2002
|
||||
v0.55 -- My god stupid Blowfish has yet again been fixed. I swear I hate that cipher. Next bug in it and boom its out of the
|
||||
library. Use AES or something else cuz I really hate Blowfish at this stage....
|
||||
-- Partial PKCS support [hint DONT USE IT YET CUZ ITS UNTESTED!]
|
||||
|
||||
July 19th, 2002
|
||||
v0.54 -- Blowfish now conforms to known test vectors. Silly bad coding tom!
|
||||
-- RC5/RC6/Serpent all have more test vectors now [and they seemed to have been working before]
|
||||
|
||||
July 18th, 2002
|
||||
v0.53 -- Added more test vectors to the blowfish code just for kicks [and they are const now too :-)]
|
||||
-- added prng/hash/cipher is_valid functions and used them in all of the PK code so you can't enter the code
|
||||
with an invalid index ever now.
|
||||
-- Simplified the Yarrow code once again :-)
|
||||
|
||||
July 12th, 2002
|
||||
v0.52 -- Fixed a bug in MD4 where the hash descriptor ID was the same as SHA-512. Now MD4 will work with
|
||||
all the routines...
|
||||
-- Fixed the comments in SHA-512 to be a bit more meaningful
|
||||
-- In md4 I made the PADDING array const [again to store it in ROM]
|
||||
-- in hash_file I switched the constant "512" to "sizeof(buf)" to be a bit safer
|
||||
-- in SHA-1's test routine I fixed the string literal to say SHA-1 not sha1
|
||||
-- Fixed a logical error in the CTR code which would make it skip the first IV value. This means
|
||||
the CTR code from v0.52 will be incompatible [binary wise] with previous releases but it makes more
|
||||
sense this way.
|
||||
-- Added {} braces for as many if/for/blocks of code I could find. My rule is that every for/if/while/do block
|
||||
must have {} braces around it.
|
||||
-- made the rounds table in saferp_setup const [again for the ROM think about the ROM!]
|
||||
-- fixed RC5 since it no longer requires rc5 to be registered in the lib. It used to since the descriptors used to
|
||||
be part of the table...
|
||||
-- the packet.c code now makes crypt_error literal string errors when an error occurs
|
||||
-- cleaned up the SAFER+ key schedule to be a bit easier to read.
|
||||
-- fixed a huge bug in Twofish with the TWOFISH_SMALL define. Because I clean the stack now I had
|
||||
changed the "g_func()" to be called indirectly. I forgot to actually return the return of the Twofish
|
||||
g_func() function which caused it not to work... [does now :-)]
|
||||
|
||||
July 11th, 2002
|
||||
v0.51 -- Fixed a bug in SHA512/384 code for multi-block messages.
|
||||
-- Added more test vectors to the SHA384/512 and TIGER hash functions
|
||||
-- cleaned up the hash done routines to make more sense
|
||||
|
||||
July 10th, 2002
|
||||
v0.50 -- Fixed yarrow.c so that the cipher/hash used would be registered. Also fixed
|
||||
a bug where the SAFER+ name was "safer" but should have been "safer+".
|
||||
-- Added an element to the hash descriptors that gives the size of a block [sent into the compressor]
|
||||
-- Cleaned up the support for HMAC's
|
||||
-- Cleaned up the test vector routines to make the test vector data const. This means on some platforms it will be
|
||||
placed in ROM not RAM now.
|
||||
-- Added MD4 code submited by Dobes Vandermeer (dobes@smartt.com)
|
||||
-- Added "burn_stack" function [idea taken from another source of crypto code]. The idea is if a function has
|
||||
alot of variables it will clean up better. Functions like the ecb serpent and twofish code will now have their
|
||||
stacks cleaned and the rest of the code is getting much more straightforward.
|
||||
-- Added a hashing demo by Daniel Richards (kyhwana@world-net.co.nz)
|
||||
-- I (Tom) modified some of the test vector routines to use more vectors ala Dobes style.
|
||||
For example, the MD5/SHA1 code now uses all of the test vectors from the RFC/FIPS spec.
|
||||
-- Fixed the register/unregister functions to properly report errors in crypt_error
|
||||
-- Correctly updated yarrow code to remove a few unused variables.
|
||||
-- Updated manual to fix a few erroneous examples.
|
||||
-- Added section on Hash based Message Authentication Codes (HMAC) to the manual
|
||||
|
||||
June 19th, 2002
|
||||
v0.46 -- Added in HMAC code from Dobes Vandermeer (dobes@smartt.com)
|
||||
|
||||
June 8th, 2002
|
||||
v0.45 -- Fixed bug in rc5.c where if you called rc5_setup() before registering RC5 it would cause
|
||||
undefined behaviour.
|
||||
-- Fixed mycrypt_cfg.h to eliminate the 224 bit ECC key.
|
||||
-- made the "default" makefile target have depends on mycrypt.h and mycrypt_cfg.h
|
||||
|
||||
Apr 4th, 2002
|
||||
v0.44 -- Fixed bug in ecc.c::new_point() where if the initial malloc fails it would not catch it.
|
||||
|
||||
Mar 22nd, 2002
|
||||
v0.43 -- Changed the ZLIB code over to the 1.1.4 code base to avoid the "double free" bug.
|
||||
-- Updated the GCC makefile not to use -O3 or -funroll-loops
|
||||
-- Version tag in mycrypt.h has been updated :-)
|
||||
|
||||
Mar 10th, 2002
|
||||
v0.42 -- The RNG code can now use /dev/urandom before trying /dev/random (J. Klapste)
|
||||
|
||||
Mar 3rd, 2002
|
||||
v0.41 -- Added support to link and use ciphers at compile time. This can greatly reduce the code size!
|
||||
-- Added a demo to show off how small an application can get... 46kb!
|
||||
-- Disastry pointed out that Blowfish is supposed to be high endian.
|
||||
-- Made registry code for the PRNGs as well [now the smallest useable link is 43kb]
|
||||
|
||||
Feb 11th, 2002
|
||||
v0.40 -- RSA signatures use [and check for] fixed padding scheme.
|
||||
-- I'm developing in Linux now :-)
|
||||
-- No more warnings from GCC 2.96
|
||||
|
||||
Feb 5th, 2002
|
||||
v0.39 -- Updated the XTEA code to work in accordance with the XTEA design
|
||||
|
||||
January 24th, 2002
|
||||
v0.38 -- CFB and OFB modes can now handle blocks of variable size like the CTR code
|
||||
-- Wrote a wrapper around the memory compress functions in Zlib that act like the functions
|
||||
in the rest of my crypto lib
|
||||
|
||||
January 23rd, 2002
|
||||
v0.37 -- Added support code so that if a hash size and key size for a cipher don't match up they will
|
||||
use the next lower key supported. (mainly for the PK code). So you can now use SHA-1 with
|
||||
Twofish, etc...
|
||||
-- Added more options for Twofish. You can now tell it to use precomputed sboxes and MDS multiplications
|
||||
This will speed up the TWOFISH_SMALL implementation by increasing the code size by 1024 bytes.
|
||||
-- Fixed a bug in prime.c that would not use the correct table if you undefined SMALL_PRIME_TAB
|
||||
-- Fixed all of the PK packet code to use the same header format [see packet.c]. This makes the PK code
|
||||
binary wise incompatible with previous releases while the API has not changed at all.
|
||||
|
||||
January 22nd, 2002
|
||||
v0.36 -- Corrections to the manual
|
||||
-- Made a modification to Twofish which lets you build a "small ram" variant. It requires
|
||||
about 190 bytes of ram for the key storage compared to the 4,200 bytes the normal
|
||||
variant requires.
|
||||
-- Reduced the stack space used in all of the PK routines.
|
||||
|
||||
January 19th, 2002
|
||||
v0.35 -- If you removed the first hash or cipher from the library it wouldn't return an error if
|
||||
you used an ID=0 [i.e blowfish or sha256] in any routine. Now it checks for that and will
|
||||
return an error like it should
|
||||
-- Merged in new routines from Clay Culver. These routines are for the PK code so you can easily
|
||||
encode a symmetric key for multiple recipients.
|
||||
-- Made the ecc and DH make_key() routines make secret keys of the same size as the keysize listed.
|
||||
Originally I wanted to ensure that the keys were smaller than the order of the field used
|
||||
However, the bias is so insignifcant using full sizes. For example, with a ECC-192 key the order
|
||||
is about 2^191.99, so instead I rounded down and used a 184-bit secret key. Now I simply use a full 192-bit
|
||||
key the code will work just the same except that some 192-bit keys will be duplicates which is not a big
|
||||
deal since 1/2^192 is a very small bias!
|
||||
-- Made the configuration a bit simpler and more exacting. You can for example now select which DH or ECC
|
||||
key settings you wish to support without including the data for all other key settings. I put the #defines
|
||||
in a new file called "mycrypt_cfg.h"
|
||||
-- Configured "mpi-config.h" so its a bit more conservative with the memory required and code space used
|
||||
-- Jason Klapste submitted bug fixes to the yarrow, hash and various other issues. The yarrow code will now
|
||||
use what ever remaining hash/cipher combo is left [after you #undef them] at build time. He also suggested
|
||||
a fix to remove unused structures from the symmetric_key and hash_state unions.
|
||||
-- Made the CTR code handle variable length blocks better. It will buffer the encryption pad so you can
|
||||
encrypt messages any size block at a time.
|
||||
-- Simplified the yarrow code to take advantage of the new CTR code.
|
||||
-- Added a 4096-bit DH key setting. That took me about 36 hours to find!
|
||||
-- Changed the base64 routines to use a real base64 encoding scheme.
|
||||
-- Added in DH and ECC "encrypt_key()" functions. They are still rather "beta"ish.
|
||||
-- Added **Twofish** to the list of ciphers!
|
||||
|
||||
January 18th, 2002
|
||||
v0.34 -- Added "sha512" to the list of hashes. Produces a 512-bit message digest. Note that with the current
|
||||
padding with the rsa_sign() function you cannot use sha512 with a key less than 1536 bits for signatures.
|
||||
-- Cleaned up the other hash functions to use the LOAD and STORE macros...
|
||||
|
||||
January 17th, 2002
|
||||
v0.33 -- Made the lower limit on keysizes for RSA 1024 bits again because I realized that 768 bit keys wouldn't
|
||||
work with the padding scheme and large symmetric keys.
|
||||
-- Added information concerning the Zlib license to the manual
|
||||
-- Added a 3072-bit key setting for the DH code.
|
||||
-- Made the "find_xyz()" routines take "const char *" as per Clay Culver's suggestion.
|
||||
-- Fixed an embarassing typo in the manual concerning the hashes. Thank's Clay for finding it!
|
||||
-- Fixed rand_prime() so that it makes primes bigger than the setting you give. For example,
|
||||
if you want a 1024-bit prime it would make a 1023-bit one. Now it ensures that the prime
|
||||
it makes is always greater than 2^(8n) (n == bytes in prime). This doesn't have a huge
|
||||
impact on security but I corrected it just the same.
|
||||
-- Fixed the CTR routine to work on platforms where char != 8-bits
|
||||
-- Fixed sha1/sha256/md5/blowfish to not assume "unsigned long == 32-bits", Basically any operation with carries
|
||||
I "AND" with 0xFFFFFFFF. That forces only the lower 32-bits to have information in it. On x86 platforms
|
||||
most compilers optimize out the AND operation since its a nop.
|
||||
|
||||
January 16th, 2002
|
||||
v0.32 -- Made Rijndael's setup function fully static so it is thread safe
|
||||
-- Svante Seleborg suggested a cosmetic style fixup for aes.c,
|
||||
basically to remove some of the #defines to clean it up
|
||||
-- Made the PK routines not export the ASCII version of the names of ciphers/hashes which makes
|
||||
the PK message formats *incompatible* with previous releases.
|
||||
-- Merge in Zlib :-)
|
||||
|
||||
|
||||
January 15th, 2002
|
||||
v0.31 -- The RSA routines can now use CRT to speed up decryption/signatures. The routines are backwards
|
||||
compatible with previous releases.
|
||||
-- Fixed another bug that Svante Seleborg found. Basically you could buffer-overrun the
|
||||
rsa_exptmod() function itself if you're not careful. That's fixed now. Fixed another bug in
|
||||
rsa_exptmod() where if it knows the buffer you passed is too small it wouldn't free all used
|
||||
memory.
|
||||
-- improved the readability of the PK import/export functions
|
||||
-- Added a fix to RSA.C by Clay Culver
|
||||
-- Changed the CONST64 macro for MSVC to use the "unsigned __int64" type, e.g. "ui64" instead of "i64".
|
||||
|
||||
January 14th, 2002
|
||||
v0.30 -- Major change to the Yarrow PRNG code, fixed a bug that Eugene Starokoltsev found.
|
||||
Basically if you added entropy to the pool in small increments it could in fact
|
||||
cancel out. Now I hash the pool with the new data which is way smarter.
|
||||
|
||||
January 12th, 2002
|
||||
v0.29 -- Added MPI code written by Svante Seleborg to the library. This will make the PK code much
|
||||
easier to follow and debug. Actually I've already fixed a memory leak in dh_shared_secret().
|
||||
-- Memory leaks found and correct in all three PK routines. The leaks would occur when a bignum
|
||||
operation fails so it wouldn't normally turn up in the course of a program
|
||||
-- Fixed bugs in dh_key_size and ecc_key_size which would return garbage for invalid key idx'es
|
||||
|
||||
January 11th, 2002
|
||||
v0.28 -- Cleaned up some code so that it doesn't assume "char == 8bits". Mainly SAFER+ has been
|
||||
changed.
|
||||
-- ***HUGE*** changes in the PK code. I check all return values in the bignum code so if there
|
||||
are errors [insufficient memory, etc..] it will be reported. This makes the code fairly more
|
||||
robust and likely to catch any errors.
|
||||
-- Updated the is_prime() function to use a new prototype [it can return errors now] and it also
|
||||
does trial divisions against more primes before the Rabin Miller steps
|
||||
-- Added OFB, CFB and ECB generic wrappers for the symmetric ciphers to round out the implementations.
|
||||
-- Added Xtea to the list of ciphers, to the best of my ability I have verified this implementation.
|
||||
I should note that there is not alot of concrete information about the cipher. "Ansi C" versions
|
||||
I found did not address endianess and were not even portable!. This code is portable and to the
|
||||
best of my knowledge implements the Xtea algorithm as per the [short] X-Tea paper.
|
||||
-- Reformated the manual to include the **FULL** source code optimized to be pritable.
|
||||
|
||||
January 9th, 2002
|
||||
v0.27 -- Changed the char constants to numerical values. It is backwards compatible and should work on
|
||||
platforms where 'd' != 100 [for example].
|
||||
-- Made a change to rand_prime() which takes the input length as a signed type so you can pass
|
||||
a negative len to get a "3 mod 4" style prime... oops
|
||||
-- changed the MSVC makefile to build with a warning level of three, no warnings!
|
||||
|
||||
January 8th, 2002
|
||||
v0.26 -- updated SHA-256 to use ROR() for a rotate so 64-bit machines won't corrupt
|
||||
the output
|
||||
-- Changed #include <> to #include "" for local .h files as per Richard Heathfields' suggestions.
|
||||
-- Fixed bug in MPI [well bug in MSVC] that compiled code incorrectly in mp_set_int()
|
||||
I added a work around that catches the error and continues normally.
|
||||
|
||||
January 8th, 2002
|
||||
v0.25 -- Added a stupid define so MSVC 6.00 can build the library.
|
||||
-- Big thanks to sci.crypt and "Ajay K. Agrawal" for helping me port this to MSVC
|
||||
|
||||
January 7th, 2002
|
||||
v0.24 -- Sped up Blowfish by unrolling and removing the swaps.
|
||||
-- Made the code comply with more traditional ANSI C standards
|
||||
Should compile with MSVC with less errors
|
||||
-- moved the demos and documentation into their own directories
|
||||
so you can easily build the library with other tool chains
|
||||
by compiling the files in the root
|
||||
-- converted functions with length of outputs to use
|
||||
"unsigned long" so 16-bit platforms will like this library more.
|
||||
|
||||
January 5th, 2002
|
||||
v0.23 -- Fixed a small error in the MPI config it should build fine anywhere.
|
||||
|
||||
January 4th, 2002
|
||||
v0.22 -- faster gf_mul() code
|
||||
-- gf_shl() and gf_shr() are safe on 64-bit platforms now
|
||||
-- Fixed an error in the hashes that Brian Gladman found.
|
||||
Basically if the message has exactly 56 bytes left to be
|
||||
compressed I handled them incorrectly.
|
||||
|
||||
January 4th, 2002
|
||||
v0.21 -- sped up the ECC code by removing redundant divisions in the
|
||||
point add and double routines. I also extract the bits more
|
||||
efficiently in "ecc_mulmod()" now.
|
||||
-- sped up [and documented] the rand_prime() function. Now it just
|
||||
makes a random integer and increments by two until a prime is found
|
||||
This is faster since it doesn't require alot of calls to the PRNG and
|
||||
it doesn't require loading huge integers over and over. rand_prime()
|
||||
can also make primes congruent to 3 mod 4 [i.e for a blum integer]
|
||||
-- added a gf_sqrt() function that finds square roots in a GF(2^w) field
|
||||
-- fixed a bug in gf_div() that would return the wrong results if the divisor had a greator
|
||||
divisor than the dividend.
|
||||
|
||||
January 4th, 2002
|
||||
v0.20 -- Added the fixed MPI back in so RSA and DH are much faster again
|
||||
|
||||
v0.19 -- Updated the manual to reflect the fact that Brian Gladman wrote the AES and Serpent code.
|
||||
-- DH, ECC and RSA signature/decryption functions check if the key is private
|
||||
-- new DH signature/verification code works just like the RSA/ECC versions
|
||||
|
||||
January 3rd, 2002
|
||||
v0.18 -- Added way more comments to each .C file
|
||||
-- fixed a bug in cbc_decrypt(pt, ct, key) where pt == ct [i.e same buffer]
|
||||
-- fixed RC5 so it reads the default rounds out of the cipher_descriptor table
|
||||
-- cleaned up ecc_export()
|
||||
-- Cleaned up dh_import() and ecc_import() which also perform more
|
||||
error checking now
|
||||
-- Fixed a serious flaw in rsa_import() with private keys.
|
||||
|
||||
January 2nd, 2002
|
||||
v0.17 -- Fixed a bug in the random prime generator that fixes the wrong bits to one
|
||||
-- ECC and DH code verify that the moduli and orders are in fact prime. That
|
||||
slows down the test routines alot but what are you gonna do?
|
||||
-- Fixed a huge bug in the mp_exptmod() function which incorrectly calculates g^x mod p for some
|
||||
values of p. I replaced it with a slow function. Once the author of MPI fixes his faster routine
|
||||
I will switch back.
|
||||
|
||||
January 1st, 2002 [whoa new year!]
|
||||
v0.16 -- Improved GF division code that is faster.
|
||||
-- documented the GF code
|
||||
|
||||
December 31st, 2001
|
||||
v0.15 -- A 1792-bit and 2048-bit DH setting was added. Took me all night to
|
||||
find a 1792 and 2048-bit strong prime but what the heck
|
||||
-- Library now has polynomial-basis GF(2^w) routines I wrote myself. Can be used to perform
|
||||
ECC over GF(2^w) later on....
|
||||
-- Fixed a bug with the defines that allows it to build in windows
|
||||
|
||||
December 30th, 2001
|
||||
v0.14 -- Fixed the xxx_encrypt() packet routines to make an IV of appropriate size
|
||||
for the cipher used. It was defaulting to making a 256-bit IV...
|
||||
-- base64_encode() now appends a NULL byte, um "duh" stupid mistake now fixed...
|
||||
-- spell checked the manual again... :-)
|
||||
|
||||
December 30th, 2001
|
||||
v0.13 -- Switching back to older copy of MPI since it works! arrg..
|
||||
-- Added sign/verify functions for ECC
|
||||
-- all signature verification routines default to invalid signatures.
|
||||
-- Changed all calls to memset to zeromem. Fixed up some buffer problems
|
||||
in other routines. All calls to zeromem let the compiler determine the size
|
||||
of the data to wipe.
|
||||
|
||||
December 29th, 2001
|
||||
v0.12 -- Imported a new version of MPI [the bignum library] that should
|
||||
be a bit more stable [if you want to write your own bignum
|
||||
routines with the library that is...]
|
||||
-- Manual has way more info
|
||||
-- hash_file() clears stack now [like it should]
|
||||
-- The artificial cap on the hash input size of 2^32 bits has been
|
||||
removed. Basically I was too lazy todo 64-bit math before
|
||||
[don't ask why... I can't remember]. Anyways the hashes
|
||||
support the size of 2^64 bits [if you ever use that many bits in a message
|
||||
that's just wierd...]
|
||||
-- The hashes now wipe the "hash_state" after the digest is computed. This helps
|
||||
prevent the internal state of the hash being leaked accidently [i.e stack problems]
|
||||
|
||||
December 29th, 2001
|
||||
v0.11 -- Made #define's so you can trim the library down by removing
|
||||
ciphers, hashs, modes of operation, prngs, and even PK algorithms
|
||||
For example, the library with rijndael+ctr+sha1+ECC is 91KB compared
|
||||
to the 246kb the full library takes.
|
||||
-- Added ECC packet routines for encrypt/decrypt/sign/verify much akin to
|
||||
the RSA packet routines.
|
||||
-- ECC now compresses the public key, a ECC-192 public key takes 33 bytes
|
||||
for example....
|
||||
|
||||
December 28th, 2001
|
||||
v0.10 -- going to restart the manual from scratch to make it more
|
||||
clear and professional
|
||||
-- Added ECC over Z/pZ. Basically provides as much as DH
|
||||
except its faster since the numbers are smaller. For example,
|
||||
A comparable 256-bit ECC key provides as much security as expected
|
||||
from a DH key over 1024-bits.
|
||||
-- Cleaned up the DH code to not export the symbol "sets[]"
|
||||
-- Fixed a bug in the DH code that would not make the correct size
|
||||
random string if you made the key short. For instance if you wanted
|
||||
a 512-bit DH key it would make a 768-bit one but only make up 512-bits
|
||||
for the exponent... now it makes the full 768 bits [or whatever the case
|
||||
is]
|
||||
-- Fixed another ***SERIOUS*** bug in the DH code that would default to 768-bit
|
||||
keys by mistake.
|
||||
|
||||
December 25th, 2001
|
||||
v0.09 -- Includes a demo program called file_crypt which shows off
|
||||
how to use the library to make a command line tool which
|
||||
allows the user to encode/decode a file with any
|
||||
hash (on the passphrase) and cipher in CTR mode.
|
||||
-- Switched everything to use typedef's now to clear up the code.
|
||||
-- Added AES (128/192 and 256 bit key modes)
|
||||
|
||||
December 24th, 2001
|
||||
v0.08 -- fixed a typo in the manual. MPI stores its bignums in
|
||||
BIG endian not little.
|
||||
-- Started adding a RNG to the library. Right now it tries
|
||||
to open /dev/random and if that fails it uses either the
|
||||
MS CSP or the clock drift RNG. It also allows callbacks
|
||||
since the drift RNG is slow (about 3.5 bytes/sec)
|
||||
-- the RNG can also automatically setup a PRNG as well now
|
||||
|
||||
v0.07 -- Added basic DH routines sufficient to
|
||||
negotiate shared secrets
|
||||
[see the manual for a complete example!]
|
||||
-- Fixed rsa_import to detect when the input
|
||||
could be corrupt.
|
||||
-- added more to the manual.
|
||||
|
||||
December 22nd, 2001
|
||||
v0.06 -- Fixed some formatting errors in
|
||||
the hash functions [just source code cleaning]
|
||||
-- Fixed a typo in the error message for sha256 :-)
|
||||
-- Fixed an error in base64_encode() that
|
||||
would fail to catch all buffer overruns
|
||||
-- Test program times the RSA and symmetric cipher
|
||||
routines for kicks...
|
||||
-- Added the "const" modifier to alot of routines to
|
||||
clear up the purpose of each function.
|
||||
-- Changed the name of the library to "TomCrypt"
|
||||
following a suggestion from a sci.crypt reader....
|
||||
|
||||
v0.05 -- Fixed the ROL/ROR macro to be safe on platforms
|
||||
where unsigned long is not 32-bits
|
||||
-- I have added a bit more to the documentation
|
||||
manual "crypt.pdf" provided.
|
||||
-- I have added a makefile for LCC-Win32. It should be
|
||||
easy to port to other LCC platforms by changing a few lines.
|
||||
-- Ran a spell checker over the manual.
|
||||
-- Changed the header and library from "crypt" to "mycrypt" to not
|
||||
clash with the *nix package "crypt".
|
||||
|
||||
v0.04 -- Fixed a bug in the RC5,RC6,Blowfish key schedules
|
||||
where if the key was not a multiple of 4 bytes it would
|
||||
not get loaded correctly.
|
||||
|
||||
December 21st, 2001
|
||||
|
||||
v0.03 -- Added Serpent to the list of ciphers.
|
||||
|
||||
v0.02 -- Changed RC5 to only allow 12 to 24 rounds
|
||||
-- Added more to the manual.
|
||||
|
||||
v0.01 -- We will call this the first version.
|
||||
232
crypt.c
Normal file
232
crypt.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/* 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"
|
||||
|
||||
/* Dropbear doesn't need these
|
||||
|
||||
const char *crypt_build_settings =
|
||||
"LibTomCrypt " SCRYPT "\n\n"
|
||||
"Endianess: "
|
||||
#if defined(ENDIAN_NEUTRAL)
|
||||
"neutral\n"
|
||||
#elif defined(ENDIAN_LITTLE)
|
||||
"little"
|
||||
#if defined(ENDIAN_32BITWORD)
|
||||
" (32-bit words)\n"
|
||||
#else
|
||||
" (64-bit words)\n"
|
||||
#endif
|
||||
#elif defined(ENDIAN_BIG)
|
||||
"big"
|
||||
#if defined(ENDIAN_32BITWORD)
|
||||
" (32-bit words)\n"
|
||||
#else
|
||||
" (64-bit words)\n"
|
||||
#endif
|
||||
#endif
|
||||
"Clean stack: "
|
||||
#if defined(CLEAN_STACK)
|
||||
"enabled\n"
|
||||
#else
|
||||
"disabled\n"
|
||||
#endif
|
||||
"Ciphers built-in:\n"
|
||||
#if defined(BLOWFISH)
|
||||
" Blowfish\n"
|
||||
#endif
|
||||
#if defined(RC2)
|
||||
" RC2\n"
|
||||
#endif
|
||||
#if defined(RC5)
|
||||
" RC5\n"
|
||||
#endif
|
||||
#if defined(RC6)
|
||||
" RC6\n"
|
||||
#endif
|
||||
#if defined(SAFERP)
|
||||
" Safer+\n"
|
||||
#endif
|
||||
#if defined(SAFER)
|
||||
" Safer\n"
|
||||
#endif
|
||||
#if defined(RIJNDAEL)
|
||||
" Rijndael\n"
|
||||
#endif
|
||||
#if defined(XTEA)
|
||||
" XTEA\n"
|
||||
#endif
|
||||
#if defined(TWOFISH)
|
||||
" Twofish "
|
||||
#if defined(TWOFISH_SMALL) && defined(TWOFISH_TABLES)
|
||||
"(small, tables)\n"
|
||||
#elif defined(TWOFISH_SMALL)
|
||||
"(small)\n"
|
||||
#elif defined(TWOFISH_TABLES)
|
||||
"(tables)\n"
|
||||
#else
|
||||
"\n"
|
||||
#endif
|
||||
#endif
|
||||
#if defined(DES)
|
||||
" DES\n"
|
||||
#endif
|
||||
#if defined(CAST5)
|
||||
" CAST5\n"
|
||||
#endif
|
||||
#if defined(NOEKEON)
|
||||
" Noekeon\n"
|
||||
#endif
|
||||
#if defined(SKIPJACK)
|
||||
" Skipjack\n"
|
||||
#endif
|
||||
|
||||
"\nHashes built-in:\n"
|
||||
#if defined(SHA512)
|
||||
" SHA-512\n"
|
||||
#endif
|
||||
#if defined(SHA384)
|
||||
" SHA-384\n"
|
||||
#endif
|
||||
#if defined(SHA256)
|
||||
" SHA-256\n"
|
||||
#endif
|
||||
#if defined(SHA224)
|
||||
" SHA-224\n"
|
||||
#endif
|
||||
#if defined(TIGER)
|
||||
" TIGER\n"
|
||||
#endif
|
||||
#if defined(SHA1)
|
||||
" SHA1\n"
|
||||
#endif
|
||||
#if defined(MD5)
|
||||
" MD5\n"
|
||||
#endif
|
||||
#if defined(MD4)
|
||||
" MD4\n"
|
||||
#endif
|
||||
#if defined(MD2)
|
||||
" MD2\n"
|
||||
#endif
|
||||
#if defined(RIPEMD128)
|
||||
" RIPEMD128\n"
|
||||
#endif
|
||||
#if defined(RIPEMD160)
|
||||
" RIPEMD160\n"
|
||||
#endif
|
||||
|
||||
"\nBlock Chaining Modes:\n"
|
||||
#if defined(CFB)
|
||||
" CFB\n"
|
||||
#endif
|
||||
#if defined(OFB)
|
||||
" OFB\n"
|
||||
#endif
|
||||
#if defined(ECB)
|
||||
" ECB\n"
|
||||
#endif
|
||||
#if defined(CBC)
|
||||
" CBC\n"
|
||||
#endif
|
||||
#if defined(CTR)
|
||||
" CTR\n"
|
||||
#endif
|
||||
|
||||
"\nPRNG:\n"
|
||||
#if defined(YARROW)
|
||||
" Yarrow\n"
|
||||
#endif
|
||||
#if defined(SPRNG)
|
||||
" SPRNG\n"
|
||||
#endif
|
||||
#if defined(RC4)
|
||||
" RC4\n"
|
||||
#endif
|
||||
|
||||
"\nPK Algs:\n"
|
||||
#if defined(MRSA)
|
||||
" RSA\n"
|
||||
#endif
|
||||
#if defined(MDH)
|
||||
" DH\n"
|
||||
#endif
|
||||
#if defined(MECC)
|
||||
" ECC\n"
|
||||
#endif
|
||||
#if defined(MDSA)
|
||||
" DSA\n"
|
||||
#endif
|
||||
#if defined(KR)
|
||||
" KR\n"
|
||||
#endif
|
||||
|
||||
"\nCompiler:\n"
|
||||
#if defined(WIN32)
|
||||
" WIN32 platform detected.\n"
|
||||
#endif
|
||||
#if defined(__CYGWIN__)
|
||||
" CYGWIN Detected.\n"
|
||||
#endif
|
||||
#if defined(__DJGPP__)
|
||||
" DJGPP Detected.\n"
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
" MSVC compiler detected.\n"
|
||||
#endif
|
||||
#if defined(__GNUC__)
|
||||
" GCC compiler detected.\n"
|
||||
#endif
|
||||
#if defined(INTEL_CC)
|
||||
" Intel C Compiler detected.\n"
|
||||
#endif
|
||||
|
||||
"\nVarious others: "
|
||||
#if defined(GF)
|
||||
" GF "
|
||||
#endif
|
||||
#if defined(BASE64)
|
||||
" BASE64 "
|
||||
#endif
|
||||
#if defined(MPI)
|
||||
" MPI "
|
||||
#endif
|
||||
#if defined(HMAC)
|
||||
" HMAC "
|
||||
#endif
|
||||
#if defined(OMAC)
|
||||
" OMAC "
|
||||
#endif
|
||||
#if defined(PMAC)
|
||||
" PMAC "
|
||||
#endif
|
||||
#if defined(EAX_MODE)
|
||||
" EAX_MODE "
|
||||
#endif
|
||||
#if defined(OCB_MODE)
|
||||
" OCB_MODE "
|
||||
#endif
|
||||
#if defined(TRY_UNRANDOM_FIRST)
|
||||
" TRY_UNRANDOM_FIRST "
|
||||
#endif
|
||||
#if defined(LTC_TEST)
|
||||
" LTC_TEST "
|
||||
#endif
|
||||
#if defined(PKCS_1)
|
||||
" PKCS#1 "
|
||||
#endif
|
||||
#if defined(PKCS_5)
|
||||
" PKCS#5 "
|
||||
#endif
|
||||
"\n"
|
||||
"\n\n\n"
|
||||
;
|
||||
*/
|
||||
|
||||
88
crypt.out
Normal file
88
crypt.out
Normal file
@@ -0,0 +1,88 @@
|
||||
\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}
|
||||
21
crypt_argchk.c
Normal file
21
crypt_argchk.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/* 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"
|
||||
#include <signal.h>
|
||||
|
||||
#if (ARGTYPE == 0)
|
||||
void crypt_argchk(char *v, char *s, int d)
|
||||
{
|
||||
fprintf(stderr, "_ARGCHK '%s' failure on line %d of file %s\n",
|
||||
v, d, s);
|
||||
(void)raise(SIGABRT);
|
||||
}
|
||||
#endif
|
||||
18
crypt_cipher_descriptor.c
Normal file
18
crypt_cipher_descriptor.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/* 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"
|
||||
|
||||
struct _cipher_descriptor cipher_descriptor[TAB_SIZE] = {
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } };
|
||||
|
||||
19
crypt_cipher_is_valid.c
Normal file
19
crypt_cipher_is_valid.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/* 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"
|
||||
|
||||
int cipher_is_valid(int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) {
|
||||
return CRYPT_INVALID_CIPHER;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
24
crypt_find_cipher.c
Normal file
24
crypt_find_cipher.c
Normal file
@@ -0,0 +1,24 @@
|
||||
/* 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"
|
||||
|
||||
int find_cipher(const char *name)
|
||||
{
|
||||
int x;
|
||||
_ARGCHK(name != NULL);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (cipher_descriptor[x].name != NULL && !strcmp(cipher_descriptor[x].name, name)) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
32
crypt_find_cipher_any.c
Normal file
32
crypt_find_cipher_any.c
Normal file
@@ -0,0 +1,32 @@
|
||||
/* 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"
|
||||
|
||||
/* idea from Wayne Scott */
|
||||
int find_cipher_any(const char *name, int blocklen, int keylen)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(name != NULL);
|
||||
|
||||
x = find_cipher(name);
|
||||
if (x != -1) return x;
|
||||
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (cipher_descriptor[x].name == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (blocklen <= (int)cipher_descriptor[x].block_length && keylen <= (int)cipher_descriptor[x].max_key_length) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
22
crypt_find_cipher_id.c
Normal file
22
crypt_find_cipher_id.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/* 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"
|
||||
|
||||
int find_cipher_id(unsigned char ID)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (cipher_descriptor[x].ID == ID) {
|
||||
return (cipher_descriptor[x].name == NULL) ? -1 : x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
23
crypt_find_hash.c
Normal file
23
crypt_find_hash.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/* 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"
|
||||
|
||||
int find_hash(const char *name)
|
||||
{
|
||||
int x;
|
||||
_ARGCHK(name != NULL);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (hash_descriptor[x].name != NULL && strcmp(hash_descriptor[x].name, name) == 0) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
34
crypt_find_hash_any.c
Normal file
34
crypt_find_hash_any.c
Normal file
@@ -0,0 +1,34 @@
|
||||
/* 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"
|
||||
|
||||
/* return first hash with at least [amount over] digestlen bytes of output */
|
||||
int find_hash_any(const char *name, int digestlen)
|
||||
{
|
||||
int x, y, z;
|
||||
_ARGCHK(name != NULL);
|
||||
|
||||
x = find_hash(name);
|
||||
if (x != -1) return x;
|
||||
|
||||
y = MAXBLOCKSIZE+1;
|
||||
z = -1;
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (hash_descriptor[x].name == NULL) {
|
||||
continue;
|
||||
}
|
||||
if ((int)hash_descriptor[x].hashsize >= digestlen && (int)hash_descriptor[x].hashsize < y) {
|
||||
z = x;
|
||||
y = hash_descriptor[x].hashsize;
|
||||
}
|
||||
}
|
||||
return z;
|
||||
}
|
||||
22
crypt_find_hash_id.c
Normal file
22
crypt_find_hash_id.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/* 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"
|
||||
|
||||
int find_hash_id(unsigned char ID)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (hash_descriptor[x].ID == ID) {
|
||||
return (hash_descriptor[x].name == NULL) ? -1 : x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
24
crypt_find_prng.c
Normal file
24
crypt_find_prng.c
Normal file
@@ -0,0 +1,24 @@
|
||||
/* 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"
|
||||
|
||||
int find_prng(const char *name)
|
||||
{
|
||||
int x;
|
||||
_ARGCHK(name != NULL);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if ((prng_descriptor[x].name != NULL) && strcmp(prng_descriptor[x].name, name) == 0) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
17
crypt_hash_descriptor.c
Normal file
17
crypt_hash_descriptor.c
Normal file
@@ -0,0 +1,17 @@
|
||||
/* 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"
|
||||
|
||||
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 } };
|
||||
19
crypt_hash_is_valid.c
Normal file
19
crypt_hash_is_valid.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/* 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"
|
||||
|
||||
int hash_is_valid(int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
18
crypt_prng_descriptor.c
Normal file
18
crypt_prng_descriptor.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/* 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"
|
||||
|
||||
struct _prng_descriptor prng_descriptor[TAB_SIZE] = {
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL },
|
||||
{ NULL, NULL, NULL, NULL, NULL } };
|
||||
|
||||
19
crypt_prng_is_valid.c
Normal file
19
crypt_prng_is_valid.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/* 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"
|
||||
|
||||
int prng_is_valid(int idx)
|
||||
{
|
||||
if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
|
||||
return CRYPT_INVALID_PRNG;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
36
crypt_register_cipher.c
Normal file
36
crypt_register_cipher.c
Normal 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"
|
||||
|
||||
int register_cipher(const struct _cipher_descriptor *cipher)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(cipher != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* find a blank spot */
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (cipher_descriptor[x].name == NULL) {
|
||||
memcpy(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor));
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* no spot */
|
||||
return -1;
|
||||
}
|
||||
36
crypt_register_hash.c
Normal file
36
crypt_register_hash.c
Normal 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"
|
||||
|
||||
int register_hash(const struct _hash_descriptor *hash)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor)) == 0) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* find a blank spot */
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (hash_descriptor[x].name == NULL) {
|
||||
memcpy(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor));
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* no spot */
|
||||
return -1;
|
||||
}
|
||||
36
crypt_register_prng.c
Normal file
36
crypt_register_prng.c
Normal 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"
|
||||
|
||||
int register_prng(const struct _prng_descriptor *prng)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor)) == 0) {
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* find a blank spot */
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (prng_descriptor[x].name == NULL) {
|
||||
memcpy(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor));
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* no spot */
|
||||
return -1;
|
||||
}
|
||||
28
crypt_unregister_cipher.c
Normal file
28
crypt_unregister_cipher.c
Normal 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"
|
||||
|
||||
int unregister_cipher(const struct _cipher_descriptor *cipher)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(cipher != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (memcmp(&cipher_descriptor[x], cipher, sizeof(struct _cipher_descriptor)) == 0) {
|
||||
cipher_descriptor[x].name = NULL;
|
||||
cipher_descriptor[x].ID = 255;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
27
crypt_unregister_hash.c
Normal file
27
crypt_unregister_hash.c
Normal file
@@ -0,0 +1,27 @@
|
||||
/* 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"
|
||||
|
||||
int unregister_hash(const struct _hash_descriptor *hash)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (memcmp(&hash_descriptor[x], hash, sizeof(struct _hash_descriptor)) == 0) {
|
||||
hash_descriptor[x].name = NULL;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
27
crypt_unregister_prng.c
Normal file
27
crypt_unregister_prng.c
Normal file
@@ -0,0 +1,27 @@
|
||||
/* 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"
|
||||
|
||||
int unregister_prng(const struct _prng_descriptor *prng)
|
||||
{
|
||||
int x;
|
||||
|
||||
_ARGCHK(prng != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (memcmp(&prng_descriptor[x], prng, sizeof(struct _prng_descriptor)) != 0) {
|
||||
prng_descriptor[x].name = NULL;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
25
ctr_decrypt.c
Normal file
25
ctr_decrypt.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/* 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_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr)
|
||||
{
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(ctr != NULL);
|
||||
|
||||
return ctr_encrypt(ct, pt, len, ctr);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
64
ctr_encrypt.c
Normal file
64
ctr_encrypt.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/* 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_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
|
||||
{
|
||||
int x, err;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(ctr != NULL);
|
||||
|
||||
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* is blocklen/padlen valid? */
|
||||
if (ctr->blocklen < 0 || ctr->blocklen > (int)sizeof(ctr->ctr) ||
|
||||
ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
while (len-- > 0) {
|
||||
/* is the pad empty? */
|
||||
if (ctr->padlen == ctr->blocklen) {
|
||||
/* increment counter */
|
||||
if (ctr->mode == 0) {
|
||||
/* little-endian */
|
||||
for (x = 0; x < ctr->blocklen; x++) {
|
||||
ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
|
||||
if (ctr->ctr[x] != (unsigned char)0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* big-endian */
|
||||
for (x = ctr->blocklen-1; x >= 0; x--) {
|
||||
ctr->ctr[x] = (ctr->ctr[x] + (unsigned char)1) & (unsigned char)255;
|
||||
if (ctr->ctr[x] != (unsigned char)0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* encrypt it */
|
||||
cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
|
||||
ctr->padlen = 0;
|
||||
}
|
||||
*ct++ = *pt++ ^ ctr->pad[ctr->padlen++];
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
46
ctr_start.c
Normal file
46
ctr_start.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/* 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_start(int cipher, const unsigned char *count, const unsigned char *key, int keylen,
|
||||
int num_rounds, symmetric_CTR *ctr)
|
||||
{
|
||||
int x, err;
|
||||
|
||||
_ARGCHK(count != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(ctr != NULL);
|
||||
|
||||
/* bad param? */
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* setup cipher */
|
||||
if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ctr->key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* copy ctr */
|
||||
ctr->blocklen = cipher_descriptor[cipher].block_length;
|
||||
ctr->cipher = cipher;
|
||||
ctr->padlen = 0;
|
||||
ctr->mode = 0;
|
||||
for (x = 0; x < ctr->blocklen; x++) {
|
||||
ctr->ctr[x] = count[x];
|
||||
}
|
||||
cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
231
demos/encrypt.c
Normal file
231
demos/encrypt.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/* encrypt V1.1 Fri Oct 18 04:28:03 NZDT 2002 */
|
||||
/* File de/encryption, using libtomcrypt */
|
||||
/* Written by Daniel Richards <kyhwana@world-net.co.nz> */
|
||||
/* Help from Tom St Denis with various bits */
|
||||
/* This code is public domain, no rights reserved. */
|
||||
/* Encrypts by default, -d flag enables decryption */
|
||||
/* ie: ./encrypt blowfish story.txt story.ct */
|
||||
/* ./encrypt -d blowfish story.ct story.pt */
|
||||
|
||||
#include <mycrypt.h>
|
||||
|
||||
int errno;
|
||||
|
||||
int usage(char *name)
|
||||
{
|
||||
int x;
|
||||
|
||||
printf("Usage: %s [-d](ecrypt) cipher infile outfile\nCiphers:\n", name);
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
printf("%s\n",cipher_descriptor[x].name);
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void register_algs(void)
|
||||
{
|
||||
int x;
|
||||
|
||||
#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
|
||||
|
||||
if (register_hash(&sha256_desc) == -1) {
|
||||
printf("Error registering SHA256\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (register_prng(&yarrow_desc) == -1) {
|
||||
printf("Error registering yarrow PRNG\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (register_prng(&sprng_desc) == -1) {
|
||||
printf("Error registering sprng PRNG\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
unsigned char plaintext[512],ciphertext[512];
|
||||
unsigned char tmpkey[512], key[MAXBLOCKSIZE], IV[MAXBLOCKSIZE];
|
||||
unsigned char inbuf[512]; /* i/o block size */
|
||||
unsigned long outlen, y, ivsize, x, decrypt;
|
||||
symmetric_CTR ctr;
|
||||
int cipher_idx, hash_idx, ks;
|
||||
char *infile, *outfile, *cipher;
|
||||
prng_state prng;
|
||||
FILE *fdin, *fdout;
|
||||
|
||||
/* register algs, so they can be printed */
|
||||
register_algs();
|
||||
|
||||
if (argc < 4) {
|
||||
return usage(argv[0]);
|
||||
}
|
||||
|
||||
if (!strcmp(argv[1], "-d")) {
|
||||
decrypt = 1;
|
||||
cipher = argv[2];
|
||||
infile = argv[3];
|
||||
outfile = argv[4];
|
||||
} else {
|
||||
decrypt = 0;
|
||||
cipher = argv[1];
|
||||
infile = argv[2];
|
||||
outfile = argv[3];
|
||||
}
|
||||
|
||||
/* file handles setup */
|
||||
fdin = fopen(infile,"rb");
|
||||
if (fdin == NULL) {
|
||||
perror("Can't open input for reading");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fdout = fopen(outfile,"wb");
|
||||
if (fdout == NULL) {
|
||||
perror("Can't open output for writing");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
cipher_idx = find_cipher(cipher);
|
||||
if (cipher_idx == -1) {
|
||||
printf("Invalid cipher entered on command line.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
hash_idx = find_hash("sha256");
|
||||
if (hash_idx == -1) {
|
||||
printf("SHA256 not found...?\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ivsize = cipher_descriptor[cipher_idx].block_length;
|
||||
ks = hash_descriptor[hash_idx].hashsize;
|
||||
if (cipher_descriptor[cipher_idx].keysize(&ks) != CRYPT_OK) {
|
||||
printf("Invalid keysize???\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
printf("\nEnter key: ");
|
||||
fgets((char *)tmpkey,sizeof(tmpkey), stdin);
|
||||
outlen = sizeof(key);
|
||||
if ((errno = hash_memory(hash_idx,tmpkey,strlen((char *)tmpkey),key,&outlen)) != CRYPT_OK) {
|
||||
printf("Error hashing key: %s\n", error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (decrypt) {
|
||||
/* Need to read in IV */
|
||||
if (fread(IV,1,ivsize,fdin) != ivsize) {
|
||||
printf("Error reading IV from input.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) {
|
||||
printf("ctr_start error: %s\n",error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
/* IV done */
|
||||
do {
|
||||
y = fread(inbuf,1,sizeof(inbuf),fdin);
|
||||
|
||||
if ((errno = ctr_decrypt(inbuf,plaintext,y,&ctr)) != CRYPT_OK) {
|
||||
printf("ctr_decrypt error: %s\n", error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (fwrite(plaintext,1,y,fdout) != y) {
|
||||
printf("Error writing to file.\n");
|
||||
exit(-1);
|
||||
}
|
||||
} while (y == sizeof(inbuf));
|
||||
fclose(fdin);
|
||||
fclose(fdout);
|
||||
|
||||
} else { /* encrypt */
|
||||
/* Setup yarrow for random bytes for IV */
|
||||
|
||||
if ((errno = rng_make_prng(128, find_prng("yarrow"), &prng, NULL)) != CRYPT_OK) {
|
||||
printf("Error setting up PRNG, %s\n", error_to_string(errno));
|
||||
}
|
||||
|
||||
/* You can use rng_get_bytes on platforms that support it */
|
||||
/* x = rng_get_bytes(IV,ivsize,NULL);*/
|
||||
x = yarrow_read(IV,ivsize,&prng);
|
||||
if (x != ivsize) {
|
||||
printf("Error reading PRNG for IV required.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (fwrite(IV,1,ivsize,fdout) != ivsize) {
|
||||
printf("Error writing IV to output.\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if ((errno = ctr_start(cipher_idx,IV,key,ks,0,&ctr)) != CRYPT_OK) {
|
||||
printf("ctr_start error: %s\n",error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
do {
|
||||
y = fread(inbuf,1,sizeof(inbuf),fdin);
|
||||
|
||||
if ((errno = ctr_encrypt(inbuf,ciphertext,y,&ctr)) != CRYPT_OK) {
|
||||
printf("ctr_encrypt error: %s\n", error_to_string(errno));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (fwrite(ciphertext,1,y,fdout) != y) {
|
||||
printf("Error writing to output.\n");
|
||||
exit(-1);
|
||||
}
|
||||
} while (y == sizeof(inbuf));
|
||||
fclose(fdout);
|
||||
fclose(fdin);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
106
demos/hashsum.c
Normal file
106
demos/hashsum.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Written by Daniel Richards <kyhwana@world-net.co.nz> 6/7/2002
|
||||
* hash.c: This app uses libtomcrypt to hash either stdin or a file
|
||||
* This file is Public Domain. No rights are reserved.
|
||||
* Compile with 'gcc hashsum.c -o hashsum -ltomcrypt'
|
||||
* This example isn't really big enough to warrent splitting into
|
||||
* more functions ;)
|
||||
*/
|
||||
|
||||
#include <mycrypt_custom.h>
|
||||
|
||||
int errno;
|
||||
|
||||
void register_algs();
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int idx, x, z;
|
||||
unsigned long w;
|
||||
unsigned char hash_buffer[MAXBLOCKSIZE];
|
||||
hash_state md;
|
||||
|
||||
/* You need to register algorithms before using them */
|
||||
register_algs();
|
||||
if (argc < 2) {
|
||||
printf("usage: ./hash algorithm file [file ...]\n");
|
||||
printf("Algorithms:\n");
|
||||
for (x = 0; hash_descriptor[x].name != NULL; x++) {
|
||||
printf(" %s\n", hash_descriptor[x].name);
|
||||
}
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
idx = find_hash(argv[1]);
|
||||
if (idx == -1) {
|
||||
fprintf(stderr, "\nInvalid hash specified on command line.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (argc == 2) {
|
||||
hash_descriptor[idx].init(&md);
|
||||
do {
|
||||
x = fread(hash_buffer, 1, sizeof(hash_buffer), stdin);
|
||||
hash_descriptor[idx].process(&md, hash_buffer, x);
|
||||
} while (x == sizeof(hash_buffer));
|
||||
hash_descriptor[idx].done(&md, hash_buffer);
|
||||
for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) {
|
||||
printf("%02x",hash_buffer[x]);
|
||||
}
|
||||
printf(" (stdin)\n");
|
||||
} else {
|
||||
for (z = 2; z < argc; z++) {
|
||||
w = sizeof(hash_buffer);
|
||||
if ((errno = hash_file(idx,argv[z],hash_buffer,&w)) != CRYPT_OK) {
|
||||
printf("File hash error: %s\n", error_to_string(errno));
|
||||
} else {
|
||||
for (x = 0; x < (int)hash_descriptor[idx].hashsize; x++) {
|
||||
printf("%02x",hash_buffer[x]);
|
||||
}
|
||||
printf(" %s\n", argv[z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
void register_algs(void)
|
||||
{
|
||||
#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 SHA224
|
||||
register_hash (&sha224_desc);
|
||||
#endif
|
||||
#ifdef SHA256
|
||||
register_hash (&sha256_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
|
||||
|
||||
}
|
||||
11
demos/small.c
Normal file
11
demos/small.c
Normal file
@@ -0,0 +1,11 @@
|
||||
// small demo app that just includes a cipher/hash/prng
|
||||
|
||||
#include <mycrypt.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
register_cipher(&rijndael_desc);
|
||||
register_prng(&yarrow_desc);
|
||||
register_hash(&sha256_desc);
|
||||
return 0;
|
||||
}
|
||||
1982
demos/test.c
Normal file
1982
demos/test.c
Normal file
File diff suppressed because it is too large
Load Diff
492
demos/tv_gen.c
Normal file
492
demos/tv_gen.c
Normal file
@@ -0,0 +1,492 @@
|
||||
#include <mycrypt.h>
|
||||
|
||||
void reg_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 SHA224
|
||||
register_hash (&sha224_desc);
|
||||
#endif
|
||||
#ifdef SHA256
|
||||
register_hash (&sha256_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
|
||||
}
|
||||
|
||||
void hash_gen(void)
|
||||
{
|
||||
unsigned char md[MAXBLOCKSIZE], buf[MAXBLOCKSIZE*2+2];
|
||||
unsigned long outlen, x, y, z;
|
||||
FILE *out;
|
||||
|
||||
out = fopen("hash_tv.txt", "w");
|
||||
|
||||
fprintf(out, "Hash Test Vectors:\n\nThese are the hashes of nn bytes '00 01 02 03 .. (nn-1)'\n\n");
|
||||
for (x = 0; hash_descriptor[x].name != NULL; x++) {
|
||||
fprintf(out, "Hash: %s\n", hash_descriptor[x].name);
|
||||
|
||||
for (y = 0; y <= (hash_descriptor[x].blocksize * 2); y++) {
|
||||
for (z = 0; z < y; z++) {
|
||||
buf[z] = (unsigned char)(z & 255);
|
||||
}
|
||||
outlen = sizeof(md);
|
||||
hash_memory(x, buf, y, md, &outlen);
|
||||
fprintf(out, "%3lu: ", y);
|
||||
for (z = 0; z < outlen; z++) {
|
||||
fprintf(out, "%02X", md[z]);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
void cipher_gen(void)
|
||||
{
|
||||
unsigned char key[MAXBLOCKSIZE], pt[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z, w;
|
||||
int kl, lastkl;
|
||||
FILE *out;
|
||||
symmetric_key skey;
|
||||
|
||||
out = fopen("cipher_tv.txt", "w");
|
||||
|
||||
fprintf(out,
|
||||
"Cipher Test Vectors\n\nThese are test encryptions with key of nn bytes '00 01 02 03 .. (nn-1)' and original PT of the same style.\n"
|
||||
"The output of step N is used as the key and plaintext for step N+1 (key bytes repeated as required to fill the key)\n\n");
|
||||
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
fprintf(out, "Cipher: %s\n", cipher_descriptor[x].name);
|
||||
|
||||
/* three modes, smallest, medium, large keys */
|
||||
lastkl = 10000;
|
||||
for (y = 0; y < 3; y++) {
|
||||
switch (y) {
|
||||
case 0: kl = cipher_descriptor[x].min_key_length; break;
|
||||
case 1: kl = (cipher_descriptor[x].min_key_length + cipher_descriptor[x].max_key_length)/2; break;
|
||||
case 2: kl = cipher_descriptor[x].max_key_length; break;
|
||||
}
|
||||
cipher_descriptor[x].keysize(&kl);
|
||||
if (kl == lastkl) break;
|
||||
lastkl = kl;
|
||||
fprintf(out, "Key Size: %d bytes\n", kl);
|
||||
|
||||
for (z = 0; (int)z < kl; z++) {
|
||||
key[z] = (unsigned char)z;
|
||||
}
|
||||
cipher_descriptor[x].setup(key, kl, 0, &skey);
|
||||
|
||||
for (z = 0; (int)z < cipher_descriptor[x].block_length; z++) {
|
||||
pt[z] = (unsigned char)z;
|
||||
}
|
||||
for (w = 0; w < 50; w++) {
|
||||
cipher_descriptor[x].ecb_encrypt(pt, pt, &skey);
|
||||
fprintf(out, "%2lu: ", w);
|
||||
for (z = 0; (int)z < cipher_descriptor[x].block_length; z++) {
|
||||
fprintf(out, "%02X", pt[z]);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
|
||||
/* reschedule a new key */
|
||||
for (z = 0; z < (unsigned long)kl; z++) {
|
||||
key[z] = pt[z % cipher_descriptor[x].block_length];
|
||||
}
|
||||
cipher_descriptor[x].setup(key, kl, 0, &skey);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
void hmac_gen(void)
|
||||
{
|
||||
unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2];
|
||||
int x, y, z, kl, err;
|
||||
FILE *out;
|
||||
unsigned long len;
|
||||
|
||||
out = fopen("hmac_tv.txt", "w");
|
||||
|
||||
fprintf(out,
|
||||
"HMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are HMACed. The initial key is\n"
|
||||
"of the same format (the same length as the HASH output size). The HMAC key in step N+1 is the HMAC output of\n"
|
||||
"step N.\n\n");
|
||||
|
||||
for (x = 0; hash_descriptor[x].name != NULL; x++) {
|
||||
fprintf(out, "HMAC-%s\n", hash_descriptor[x].name);
|
||||
|
||||
/* initial key */
|
||||
for (y = 0; y < (int)hash_descriptor[x].hashsize; y++) {
|
||||
key[y] = (y&255);
|
||||
}
|
||||
|
||||
for (y = 0; y <= (int)(hash_descriptor[x].blocksize * 2); y++) {
|
||||
for (z = 0; z < y; z++) {
|
||||
input[z] = (unsigned char)(z & 255);
|
||||
}
|
||||
len = sizeof(output);
|
||||
if ((err = hmac_memory(x, key, hash_descriptor[x].hashsize, input, y, output, &len)) != CRYPT_OK) {
|
||||
printf("Error hmacing: %s\n", error_to_string(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(out, "%3d: ", y);
|
||||
for (z = 0; z <(int) len; z++) {
|
||||
fprintf(out, "%02X", output[z]);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
|
||||
/* forward the key */
|
||||
memcpy(key, output, hash_descriptor[x].hashsize);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
void omac_gen(void)
|
||||
{
|
||||
unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2];
|
||||
int err, x, y, z, kl;
|
||||
FILE *out;
|
||||
unsigned long len;
|
||||
|
||||
out = fopen("omac_tv.txt", "w");
|
||||
|
||||
fprintf(out,
|
||||
"OMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is\n"
|
||||
"of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of\n"
|
||||
"step N (repeated as required to fill the array).\n\n");
|
||||
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
kl = cipher_descriptor[x].block_length;
|
||||
|
||||
/* skip ciphers which do not have 64 or 128 bit block sizes */
|
||||
if (kl != 8 && kl != 16) continue;
|
||||
|
||||
if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) {
|
||||
kl = cipher_descriptor[x].max_key_length;
|
||||
}
|
||||
fprintf(out, "OMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
|
||||
|
||||
/* initial key/block */
|
||||
for (y = 0; y < kl; y++) {
|
||||
key[y] = (y & 255);
|
||||
}
|
||||
|
||||
for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) {
|
||||
for (z = 0; z < y; z++) {
|
||||
input[z] = (unsigned char)(z & 255);
|
||||
}
|
||||
len = sizeof(output);
|
||||
if ((err = omac_memory(x, key, kl, input, y, output, &len)) != CRYPT_OK) {
|
||||
printf("Error omacing: %s\n", error_to_string(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(out, "%3d: ", y);
|
||||
for (z = 0; z <(int)len; z++) {
|
||||
fprintf(out, "%02X", output[z]);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
|
||||
/* forward the key */
|
||||
for (z = 0; z < kl; z++) {
|
||||
key[z] = output[z % len];
|
||||
}
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
void pmac_gen(void)
|
||||
{
|
||||
unsigned char key[MAXBLOCKSIZE], output[MAXBLOCKSIZE], input[MAXBLOCKSIZE*2+2];
|
||||
int err, x, y, z, kl;
|
||||
FILE *out;
|
||||
unsigned long len;
|
||||
|
||||
out = fopen("pmac_tv.txt", "w");
|
||||
|
||||
fprintf(out,
|
||||
"PMAC Tests. In these tests messages of N bytes long (00,01,02,...,NN-1) are OMAC'ed. The initial key is\n"
|
||||
"of the same format (length specified per cipher). The OMAC key in step N+1 is the OMAC output of\n"
|
||||
"step N (repeated as required to fill the array).\n\n");
|
||||
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
kl = cipher_descriptor[x].block_length;
|
||||
|
||||
/* skip ciphers which do not have 64 or 128 bit block sizes */
|
||||
if (kl != 8 && kl != 16) continue;
|
||||
|
||||
if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) {
|
||||
kl = cipher_descriptor[x].max_key_length;
|
||||
}
|
||||
fprintf(out, "PMAC-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
|
||||
|
||||
/* initial key/block */
|
||||
for (y = 0; y < kl; y++) {
|
||||
key[y] = (y & 255);
|
||||
}
|
||||
|
||||
for (y = 0; y <= (int)(cipher_descriptor[x].block_length*2); y++) {
|
||||
for (z = 0; z < y; z++) {
|
||||
input[z] = (unsigned char)(z & 255);
|
||||
}
|
||||
len = sizeof(output);
|
||||
if ((err = pmac_memory(x, key, kl, input, y, output, &len)) != CRYPT_OK) {
|
||||
printf("Error omacing: %s\n", error_to_string(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(out, "%3d: ", y);
|
||||
for (z = 0; z <(int)len; z++) {
|
||||
fprintf(out, "%02X", output[z]);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
|
||||
/* forward the key */
|
||||
for (z = 0; z < kl; z++) {
|
||||
key[z] = output[z % len];
|
||||
}
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
void eax_gen(void)
|
||||
{
|
||||
int err, kl, x, y1, z;
|
||||
FILE *out;
|
||||
unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2], header[MAXBLOCKSIZE*2],
|
||||
plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
|
||||
unsigned long len;
|
||||
|
||||
out = fopen("eax_tv.txt", "w");
|
||||
fprintf(out, "EAX Test Vectors. Uses the 00010203...NN-1 pattern for header/nonce/plaintext/key. The outputs\n"
|
||||
"are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n"
|
||||
"step repeated sufficiently.\n\n");
|
||||
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
kl = cipher_descriptor[x].block_length;
|
||||
|
||||
/* skip ciphers which do not have 64 or 128 bit block sizes */
|
||||
if (kl != 8 && kl != 16) continue;
|
||||
|
||||
if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) {
|
||||
kl = cipher_descriptor[x].max_key_length;
|
||||
}
|
||||
fprintf(out, "EAX-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
|
||||
|
||||
/* the key */
|
||||
for (z = 0; z < kl; z++) {
|
||||
key[z] = (z & 255);
|
||||
}
|
||||
|
||||
for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
|
||||
for (z = 0; z < y1; z++) {
|
||||
plaintext[z] = (unsigned char)(z & 255);
|
||||
nonce[z] = (unsigned char)(z & 255);
|
||||
header[z] = (unsigned char)(z & 255);
|
||||
}
|
||||
len = sizeof(tag);
|
||||
if ((err = eax_encrypt_authenticate_memory(x, key, kl, nonce, y1, header, y1, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) {
|
||||
printf("Error EAX'ing: %s\n", error_to_string(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(out, "%3d: ", y1);
|
||||
for (z = 0; z < y1; z++) {
|
||||
fprintf(out, "%02X", plaintext[z]);
|
||||
}
|
||||
fprintf(out, ", ");
|
||||
for (z = 0; z <(int)len; z++) {
|
||||
fprintf(out, "%02X", tag[z]);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
|
||||
/* forward the key */
|
||||
for (z = 0; z < kl; z++) {
|
||||
key[z] = tag[z % len];
|
||||
}
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
void ocb_gen(void)
|
||||
{
|
||||
int err, kl, x, y1, z;
|
||||
FILE *out;
|
||||
unsigned char key[MAXBLOCKSIZE], nonce[MAXBLOCKSIZE*2],
|
||||
plaintext[MAXBLOCKSIZE*2], tag[MAXBLOCKSIZE];
|
||||
unsigned long len;
|
||||
|
||||
out = fopen("ocb_tv.txt", "w");
|
||||
fprintf(out, "OCB Test Vectors. Uses the 00010203...NN-1 pattern for nonce/plaintext/key. The outputs\n"
|
||||
"are of the form ciphertext,tag for a given NN. The key for step N>1 is the tag of the previous\n"
|
||||
"step repeated sufficiently. The nonce is fixed throughout.\n\n");
|
||||
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
kl = cipher_descriptor[x].block_length;
|
||||
|
||||
/* skip ciphers which do not have 64 or 128 bit block sizes */
|
||||
if (kl != 8 && kl != 16) continue;
|
||||
|
||||
if (cipher_descriptor[x].keysize(&kl) != CRYPT_OK) {
|
||||
kl = cipher_descriptor[x].max_key_length;
|
||||
}
|
||||
fprintf(out, "OCB-%s (%d byte key)\n", cipher_descriptor[x].name, kl);
|
||||
|
||||
/* the key */
|
||||
for (z = 0; z < kl; z++) {
|
||||
key[z] = (z & 255);
|
||||
}
|
||||
|
||||
/* fixed nonce */
|
||||
for (z = 0; z < cipher_descriptor[x].block_length; z++) {
|
||||
nonce[z] = z;
|
||||
}
|
||||
|
||||
for (y1 = 0; y1 <= (int)(cipher_descriptor[x].block_length*2); y1++){
|
||||
for (z = 0; z < y1; z++) {
|
||||
plaintext[z] = (unsigned char)(z & 255);
|
||||
}
|
||||
len = sizeof(tag);
|
||||
if ((err = ocb_encrypt_authenticate_memory(x, key, kl, nonce, plaintext, y1, plaintext, tag, &len)) != CRYPT_OK) {
|
||||
printf("Error OCB'ing: %s\n", error_to_string(err));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
fprintf(out, "%3d: ", y1);
|
||||
for (z = 0; z < y1; z++) {
|
||||
fprintf(out, "%02X", plaintext[z]);
|
||||
}
|
||||
fprintf(out, ", ");
|
||||
for (z = 0; z <(int)len; z++) {
|
||||
fprintf(out, "%02X", tag[z]);
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
|
||||
/* forward the key */
|
||||
for (z = 0; z < kl; z++) {
|
||||
key[z] = tag[z % len];
|
||||
}
|
||||
}
|
||||
fprintf(out, "\n");
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
void base64_gen(void)
|
||||
{
|
||||
FILE *out;
|
||||
unsigned char dst[256], src[32];
|
||||
unsigned long x, y, len;
|
||||
|
||||
out = fopen("base64_tv.txt", "w");
|
||||
fprintf(out, "Base64 vectors. These are the base64 encodings of the strings 00,01,02...NN-1\n\n");
|
||||
for (x = 0; x <= 32; x++) {
|
||||
for (y = 0; y < x; y++) {
|
||||
src[y] = y;
|
||||
}
|
||||
len = sizeof(dst);
|
||||
base64_encode(src, x, dst, &len);
|
||||
fprintf(out, "%2lu: %s\n", x, dst);
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
reg_algs();
|
||||
printf("Generating hash vectors..."); fflush(stdout); hash_gen(); printf("done\n");
|
||||
printf("Generating cipher vectors..."); fflush(stdout); cipher_gen(); printf("done\n");
|
||||
printf("Generating HMAC vectors..."); fflush(stdout); hmac_gen(); printf("done\n");
|
||||
printf("Generating OMAC vectors..."); fflush(stdout); omac_gen(); printf("done\n");
|
||||
printf("Generating PMAC vectors..."); fflush(stdout); pmac_gen(); printf("done\n");
|
||||
printf("Generating EAX vectors..."); fflush(stdout); eax_gen(); printf("done\n");
|
||||
printf("Generating OCB vectors..."); fflush(stdout); ocb_gen(); printf("done\n");
|
||||
printf("Generating BASE64 vectors..."); fflush(stdout); base64_gen(); printf("done\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
358
demos/x86_prof.c
Normal file
358
demos/x86_prof.c
Normal file
@@ -0,0 +1,358 @@
|
||||
#include <mycrypt.h>
|
||||
|
||||
#define KTIMES 25
|
||||
#define TIMES 100000
|
||||
|
||||
struct list {
|
||||
int id;
|
||||
unsigned long spd1, spd2, avg;
|
||||
} results[100];
|
||||
|
||||
int no_results;
|
||||
|
||||
int sorter(const void *a, const void *b)
|
||||
{
|
||||
const struct list *A, *B;
|
||||
A = a;
|
||||
B = b;
|
||||
if (A->avg < B->avg) return -1;
|
||||
if (A->avg > B->avg) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tally_results(int type)
|
||||
{
|
||||
int x;
|
||||
|
||||
// qsort the results
|
||||
qsort(results, no_results, sizeof(struct list), &sorter);
|
||||
|
||||
printf("\n");
|
||||
if (type == 0) {
|
||||
for (x = 0; x < no_results; x++) {
|
||||
printf("%-20s: Schedule at %6lu\n", cipher_descriptor[results[x].id].name, (unsigned long)results[x].spd1);
|
||||
}
|
||||
} else if (type == 1) {
|
||||
for (x = 0; x < no_results; x++) {
|
||||
printf
|
||||
("%-20s: Encrypt at %5lu, Decrypt at %5lu\n", cipher_descriptor[results[x].id].name, results[x].spd1, results[x].spd2);
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < no_results; x++) {
|
||||
printf
|
||||
("%-20s: Process at %5lu\n", hash_descriptor[results[x].id].name, results[x].spd1 / 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* RDTSC from Scott Duplichan */
|
||||
static ulong64 rdtsc (void)
|
||||
{
|
||||
#if defined __GNUC__
|
||||
#ifdef __i386__
|
||||
ulong64 a;
|
||||
__asm__ __volatile__ ("rdtsc ":"=A" (a));
|
||||
return a;
|
||||
#else /* gcc-IA64 version */
|
||||
unsigned long result;
|
||||
__asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
|
||||
while (__builtin_expect ((int) result == -1, 0))
|
||||
__asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
|
||||
return result;
|
||||
#endif
|
||||
|
||||
// Microsoft and Intel Windows compilers
|
||||
#elif defined _M_IX86
|
||||
__asm rdtsc
|
||||
#elif defined _M_AMD64
|
||||
return __rdtsc ();
|
||||
#elif defined _M_IA64
|
||||
#if defined __INTEL_COMPILER
|
||||
#include <ia64intrin.h>
|
||||
#endif
|
||||
return __getReg (3116);
|
||||
#else
|
||||
#error need rdtsc function for this build
|
||||
#endif
|
||||
}
|
||||
|
||||
ulong64 timer, skew = 0;
|
||||
prng_state prng;
|
||||
|
||||
void t_start(void)
|
||||
{
|
||||
timer = rdtsc();
|
||||
}
|
||||
|
||||
ulong64 t_read(void)
|
||||
{
|
||||
return rdtsc() - timer;
|
||||
}
|
||||
|
||||
void init_timer(void)
|
||||
{
|
||||
ulong64 c1, c2, t1, t2, t3;
|
||||
unsigned long y1;
|
||||
|
||||
c1 = c2 = (ulong64)-1;
|
||||
for (y1 = 0; y1 < TIMES*100; y1++) {
|
||||
t_start();
|
||||
t1 = t_read();
|
||||
t3 = t_read();
|
||||
t2 = t_read() - t1;
|
||||
|
||||
c1 = (c1 > t1) ? t1 : c1;
|
||||
c2 = (c2 > t2) ? t2 : c2;
|
||||
}
|
||||
skew = c2 - c1;
|
||||
printf("Clock Skew: %lu\n", (unsigned long)skew);
|
||||
}
|
||||
|
||||
void reg_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 SHA224
|
||||
register_hash (&sha224_desc);
|
||||
#endif
|
||||
#ifdef SHA256
|
||||
register_hash (&sha256_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
|
||||
|
||||
register_prng(&yarrow_desc);
|
||||
rng_make_prng(128, find_prng("yarrow"), &prng, NULL);
|
||||
}
|
||||
|
||||
int time_keysched(void)
|
||||
{
|
||||
unsigned long x, i, y1;
|
||||
ulong64 t1, c1;
|
||||
symmetric_key skey;
|
||||
int kl;
|
||||
int (*func) (const unsigned char *, int , int , symmetric_key *);
|
||||
unsigned char key[MAXBLOCKSIZE];
|
||||
|
||||
printf ("\n\nKey Schedule Time Trials for the Symmetric Ciphers:\n(Times are cycles per key)\n");
|
||||
no_results = 0;
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
#define DO1(k) func(k, kl, 0, &skey);
|
||||
|
||||
func = cipher_descriptor[x].setup;
|
||||
kl = cipher_descriptor[x].min_key_length;
|
||||
c1 = (ulong64)-1;
|
||||
for (y1 = 0; y1 < KTIMES; y1++) {
|
||||
yarrow_read(key, kl, &prng);
|
||||
t_start();
|
||||
DO1(key);
|
||||
t1 = t_read();
|
||||
c1 = (t1 > c1) ? c1 : t1;
|
||||
}
|
||||
t1 = c1 - skew;
|
||||
results[no_results].spd1 = results[no_results].avg = t1;
|
||||
results[no_results++].id = x;
|
||||
printf("."); fflush(stdout);
|
||||
|
||||
#undef DO1
|
||||
}
|
||||
tally_results(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int time_cipher(void)
|
||||
{
|
||||
unsigned long x, y1;
|
||||
ulong64 t1, t2, c1, c2, a1, a2;
|
||||
symmetric_key skey;
|
||||
void (*func) (const unsigned char *, unsigned char *, symmetric_key *);
|
||||
unsigned char key[MAXBLOCKSIZE], pt[MAXBLOCKSIZE];
|
||||
|
||||
|
||||
printf ("\n\nECB Time Trials for the Symmetric Ciphers:\n");
|
||||
no_results = 0;
|
||||
for (x = 0; cipher_descriptor[x].name != NULL; x++) {
|
||||
cipher_descriptor[x].setup (key, cipher_descriptor[x].min_key_length, 0,
|
||||
&skey);
|
||||
|
||||
#define DO1 func(pt,pt,&skey);
|
||||
#define DO2 DO1 DO1
|
||||
|
||||
func = cipher_descriptor[x].ecb_encrypt;
|
||||
c1 = c2 = (ulong64)-1;
|
||||
for (y1 = 0; y1 < TIMES; y1++) {
|
||||
t_start();
|
||||
DO1;
|
||||
t1 = t_read();
|
||||
DO2;
|
||||
t2 = t_read();
|
||||
t2 -= t1;
|
||||
|
||||
c1 = (t1 > c1 ? c1 : t1);
|
||||
c2 = (t2 > c2 ? c2 : t2);
|
||||
}
|
||||
a1 = c2 - c1 - skew;
|
||||
|
||||
|
||||
func = cipher_descriptor[x].ecb_decrypt;
|
||||
c1 = c2 = (ulong64)-1;
|
||||
for (y1 = 0; y1 < TIMES; y1++) {
|
||||
t_start();
|
||||
DO1;
|
||||
t1 = t_read();
|
||||
DO2;
|
||||
t2 = t_read();
|
||||
t2 -= t1;
|
||||
|
||||
c1 = (t1 > c1 ? c1 : t1);
|
||||
c2 = (t2 > c2 ? c2 : t2);
|
||||
}
|
||||
a2 = c2 - c1 - skew;
|
||||
|
||||
results[no_results].id = x;
|
||||
results[no_results].spd1 = a1/cipher_descriptor[x].block_length;
|
||||
results[no_results].spd2 = a2/cipher_descriptor[x].block_length;;
|
||||
results[no_results].avg = (results[no_results].spd1 + results[no_results].spd2+1)/2;
|
||||
++no_results;
|
||||
printf("."); fflush(stdout);
|
||||
|
||||
#undef DO2
|
||||
#undef DO1
|
||||
}
|
||||
tally_results(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int time_hash(void)
|
||||
{
|
||||
unsigned long x, y1, len;
|
||||
ulong64 t1, t2, c1, c2;
|
||||
hash_state md;
|
||||
int (*func)(hash_state *, const unsigned char *, unsigned long);
|
||||
unsigned char pt[MAXBLOCKSIZE];
|
||||
|
||||
|
||||
printf ("\n\nHASH Time Trials for:\n");
|
||||
no_results = 0;
|
||||
for (x = 0; hash_descriptor[x].name != NULL; x++) {
|
||||
hash_descriptor[x].init(&md);
|
||||
|
||||
#define DO1 func(&md,pt,len);
|
||||
#define DO2 DO1 DO1
|
||||
|
||||
func = hash_descriptor[x].process;
|
||||
len = hash_descriptor[x].blocksize;
|
||||
|
||||
c1 = c2 = (ulong64)-1;
|
||||
for (y1 = 0; y1 < TIMES; y1++) {
|
||||
t_start();
|
||||
DO1;
|
||||
t1 = t_read();
|
||||
DO2;
|
||||
t2 = t_read() - t1;
|
||||
c1 = (t1 > c1) ? c1 : t1;
|
||||
c2 = (t2 > c2) ? c2 : t2;
|
||||
}
|
||||
t1 = c2 - c1 - skew;
|
||||
t1 = ((t1 * CONST64(1000))) / ((ulong64)hash_descriptor[x].blocksize);
|
||||
results[no_results].id = x;
|
||||
results[no_results].spd1 = results[no_results].avg = t1;
|
||||
++no_results;
|
||||
printf("."); fflush(stdout);
|
||||
#undef DO2
|
||||
#undef DO1
|
||||
}
|
||||
tally_results(2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
reg_algs();
|
||||
|
||||
printf("Timings for ciphers and hashes. Times are listed as cycles per byte processed.\n\n");
|
||||
|
||||
// init_timer();
|
||||
time_cipher();
|
||||
time_keysched();
|
||||
time_hash();
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
452
dh.c
Normal file
452
dh.c
Normal file
@@ -0,0 +1,452 @@
|
||||
/* 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 MDH
|
||||
|
||||
/* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */
|
||||
static const struct {
|
||||
int size;
|
||||
char *name, *base, *prime;
|
||||
} sets[] = {
|
||||
#ifdef DH768
|
||||
{
|
||||
96,
|
||||
"DH-768",
|
||||
"4",
|
||||
"F///////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"//////m3wvV"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1024
|
||||
{
|
||||
128,
|
||||
"DH-1024",
|
||||
"4",
|
||||
"F///////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////m3C47"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1280
|
||||
{
|
||||
160,
|
||||
"DH-1280",
|
||||
"4",
|
||||
"F///////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"//////////////////////////////m4kSN"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1536
|
||||
{
|
||||
192,
|
||||
"DH-1536",
|
||||
"4",
|
||||
"F///////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////m5uqd"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH1792
|
||||
{
|
||||
224,
|
||||
"DH-1792",
|
||||
"4",
|
||||
"F///////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"//////////////////////////////////////////////////////mT/sd"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH2048
|
||||
{
|
||||
256,
|
||||
"DH-2048",
|
||||
"4",
|
||||
"3///////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"/////////////////////////////////////////m8MPh"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH2560
|
||||
{
|
||||
320,
|
||||
"DH-2560",
|
||||
"4",
|
||||
"3///////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"/////mKFpF"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH3072
|
||||
{
|
||||
384,
|
||||
"DH-3072",
|
||||
"4",
|
||||
"3///////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"/////////////////////////////m32nN"
|
||||
},
|
||||
#endif
|
||||
#ifdef DH4096
|
||||
{
|
||||
512,
|
||||
"DH-4096",
|
||||
"4",
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"////////////////////////////////////////////////////////////"
|
||||
"/////////////////////m8pOF"
|
||||
},
|
||||
#endif
|
||||
{
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
static int is_valid_idx(int n)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; sets[x].size; x++);
|
||||
if ((n < 0) || (n >= x)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int dh_test(void)
|
||||
{
|
||||
mp_int p, g, tmp;
|
||||
int x, err, primality;
|
||||
|
||||
if ((err = mp_init_multi(&p, &g, &tmp, NULL)) != MP_OKAY) { goto error; }
|
||||
|
||||
for (x = 0; sets[x].size != 0; x++) {
|
||||
#if 0
|
||||
printf("dh_test():testing size %d-bits\n", sets[x].size * 8);
|
||||
#endif
|
||||
if ((err = mp_read_radix(&g,(char *)sets[x].base, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_read_radix(&p,(char *)sets[x].prime, 64)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* ensure p is prime */
|
||||
if ((err = is_prime(&p, &primality)) != CRYPT_OK) { goto done; }
|
||||
if (primality == 0) {
|
||||
err = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((err = mp_sub_d(&p, 1, &tmp)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_div_2(&tmp, &tmp)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* ensure (p-1)/2 is prime */
|
||||
if ((err = is_prime(&tmp, &primality)) != CRYPT_OK) { goto done; }
|
||||
if (primality == 0) {
|
||||
err = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* now see if g^((p-1)/2) mod p is in fact 1 */
|
||||
if ((err = mp_exptmod(&g, &tmp, &p, &tmp)) != MP_OKAY) { goto error; }
|
||||
if (mp_cmp_d(&tmp, 1)) {
|
||||
err = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
mp_clear_multi(&tmp, &g, &p, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
void dh_sizes(int *low, int *high)
|
||||
{
|
||||
int x;
|
||||
_ARGCHK(low != NULL);
|
||||
_ARGCHK(high != NULL);
|
||||
*low = INT_MAX;
|
||||
*high = 0;
|
||||
for (x = 0; sets[x].size != 0; x++) {
|
||||
if (*low > sets[x].size) *low = sets[x].size;
|
||||
if (*high < sets[x].size) *high = sets[x].size;
|
||||
}
|
||||
}
|
||||
|
||||
int dh_get_size(dh_key *key)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
if (is_valid_idx(key->idx) == 1) {
|
||||
return sets[key->idx].size;
|
||||
} else {
|
||||
return INT_MAX; /* large value that would cause dh_make_key() to fail */
|
||||
}
|
||||
}
|
||||
|
||||
int dh_make_key(prng_state *prng, int wprng, int keysize, dh_key *key)
|
||||
{
|
||||
unsigned char buf[512];
|
||||
unsigned long x;
|
||||
mp_int p, g;
|
||||
int err;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* good prng? */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find key size */
|
||||
for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++);
|
||||
#ifdef FAST_PK
|
||||
keysize = MIN(sets[x].size, 32);
|
||||
#else
|
||||
keysize = sets[x].size;
|
||||
#endif
|
||||
|
||||
if (sets[x].size == 0) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
key->idx = x;
|
||||
|
||||
/* make up random string */
|
||||
if (prng_descriptor[wprng].read(buf, keysize, prng) != (unsigned long)keysize) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* init parameters */
|
||||
if ((err = mp_init_multi(&g, &p, &key->x, &key->y, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* load the x value */
|
||||
if ((err = mp_read_unsigned_bin(&key->x, buf, keysize)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_exptmod(&g, &key->x, &p, &key->y)) != MP_OKAY) { goto error; }
|
||||
key->type = PK_PRIVATE;
|
||||
|
||||
if ((err = mp_shrink(&key->x)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_shrink(&key->y)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* free up ram */
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
mp_clear_multi(&key->x, &key->y, NULL);
|
||||
done:
|
||||
mp_clear_multi(&p, &g, NULL);
|
||||
zeromem(buf, sizeof(buf));
|
||||
return err;
|
||||
}
|
||||
|
||||
void dh_free(dh_key *key)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
mp_clear_multi(&key->x, &key->y, NULL);
|
||||
}
|
||||
|
||||
int dh_export(unsigned char *out, unsigned long *outlen, int type, dh_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 + 2)) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* header */
|
||||
out[y++] = type;
|
||||
out[y++] = (unsigned char)(sets[key->idx].size / 8);
|
||||
|
||||
/* export y */
|
||||
OUTPUT_BIGNUM(&key->y, out, y, z);
|
||||
|
||||
if (type == PK_PRIVATE) {
|
||||
/* export x */
|
||||
OUTPUT_BIGNUM(&key->x, out, y, z);
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_KEY);
|
||||
|
||||
/* store len */
|
||||
*outlen = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
|
||||
{
|
||||
unsigned long x, y, s;
|
||||
int err;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* make sure valid length */
|
||||
if ((2+PACKET_SIZE) > inlen) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* check type byte */
|
||||
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_KEY)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* init */
|
||||
if ((err = mp_init_multi(&key->x, &key->y, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
/* advance past packet header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* key type, e.g. private, public */
|
||||
key->type = (int)in[y++];
|
||||
|
||||
/* key size in bytes */
|
||||
s = (unsigned long)in[y++] * 8;
|
||||
|
||||
for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++);
|
||||
if (sets[x].size == 0) {
|
||||
err = CRYPT_INVALID_KEYSIZE;
|
||||
goto error;
|
||||
}
|
||||
key->idx = (int)x;
|
||||
|
||||
/* type check both values */
|
||||
if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) {
|
||||
err = CRYPT_PK_TYPE_MISMATCH;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* is the key idx valid? */
|
||||
if (is_valid_idx(key->idx) != 1) {
|
||||
err = CRYPT_PK_TYPE_MISMATCH;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* load public value g^x mod p*/
|
||||
INPUT_BIGNUM(&key->y, in, x, y, inlen);
|
||||
|
||||
if (key->type == PK_PRIVATE) {
|
||||
INPUT_BIGNUM(&key->x, in, x, y, inlen);
|
||||
}
|
||||
|
||||
/* eliminate private key if public */
|
||||
if (key->type == PK_PUBLIC) {
|
||||
mp_clear(&key->x);
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
error:
|
||||
mp_clear_multi(&key->y, &key->x, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
int dh_shared_secret(dh_key *private_key, dh_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
mp_int tmp, p;
|
||||
unsigned long x;
|
||||
int err;
|
||||
|
||||
_ARGCHK(private_key != NULL);
|
||||
_ARGCHK(public_key != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* types valid? */
|
||||
if (private_key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* same idx? */
|
||||
if (private_key->idx != public_key->idx) {
|
||||
return CRYPT_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
/* compute y^x mod p */
|
||||
if ((err = mp_init_multi(&tmp, &p, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
if ((err = mp_read_radix(&p, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_exptmod(&public_key->y, &private_key->x, &p, &tmp)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* enough space for output? */
|
||||
x = (unsigned long)mp_unsigned_bin_size(&tmp);
|
||||
if (*outlen < x) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
if ((err = mp_to_unsigned_bin(&tmp, out)) != MP_OKAY) { goto error; }
|
||||
*outlen = x;
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
mp_clear_multi(&p, &tmp, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
#include "dh_sys.c"
|
||||
|
||||
#endif
|
||||
|
||||
399
dh_sys.c
Normal file
399
dh_sys.c
Normal file
@@ -0,0 +1,399 @@
|
||||
/* 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
|
||||
*/
|
||||
int dh_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *len,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
dh_key *key)
|
||||
{
|
||||
unsigned char pub_expt[768], dh_shared[768], skey[MAXBLOCKSIZE];
|
||||
dh_key pubkey;
|
||||
unsigned long x, y, z, hashsize, pubkeysize;
|
||||
int err;
|
||||
|
||||
_ARGCHK(inkey != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(len != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check that wprng/hash are not invalid */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (keylen > hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* make a random key and export the public copy */
|
||||
if ((err = dh_make_key(prng, wprng, dh_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pubkeysize = sizeof(pub_expt);
|
||||
if ((err = dh_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
dh_free(&pubkey);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* now check if the out buffer is big enough */
|
||||
if (*len < (1 + 4 + 4 + PACKET_SIZE + pubkeysize + keylen)) {
|
||||
dh_free(&pubkey);
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* make random key */
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
|
||||
x = (unsigned long)sizeof(dh_shared);
|
||||
if ((err = dh_shared_secret(&pubkey, key, dh_shared, &x)) != CRYPT_OK) {
|
||||
dh_free(&pubkey);
|
||||
return err;
|
||||
}
|
||||
dh_free(&pubkey);
|
||||
|
||||
z = sizeof(skey);
|
||||
if ((err = hash_memory(hash, dh_shared, x, skey, &z)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_ENC_KEY);
|
||||
|
||||
/* output header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* size of hash name and the name itself */
|
||||
out[y++] = hash_descriptor[hash].ID;
|
||||
|
||||
/* length of DH pubkey and the key itself */
|
||||
STORE32L(pubkeysize, out+y);
|
||||
y += 4;
|
||||
for (x = 0; x < pubkeysize; x++, y++) {
|
||||
out[y] = pub_expt[x];
|
||||
}
|
||||
|
||||
/* Store the encrypted key */
|
||||
STORE32L(keylen, out+y);
|
||||
y += 4;
|
||||
|
||||
for (x = 0; x < keylen; x++, y++) {
|
||||
out[y] = skey[x] ^ inkey[x];
|
||||
}
|
||||
*len = y;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(pub_expt, sizeof(pub_expt));
|
||||
zeromem(dh_shared, sizeof(dh_shared));
|
||||
zeromem(skey, sizeof(skey));
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int dh_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
dh_key *key)
|
||||
{
|
||||
unsigned char shared_secret[768], skey[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z,hashsize, keysize;
|
||||
int hash, err;
|
||||
dh_key pubkey;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(outkey != NULL);
|
||||
_ARGCHK(keylen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* check if initial header should fit */
|
||||
if (inlen < PACKET_SIZE+1+4+4) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
inlen -= PACKET_SIZE+1+4+4;
|
||||
}
|
||||
|
||||
/* is header correct? */
|
||||
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DH, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* now lets get the hash name */
|
||||
y = PACKET_SIZE;
|
||||
hash = find_hash_id(in[y++]);
|
||||
if (hash == -1) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* common values */
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
|
||||
/* get public key */
|
||||
LOAD32L(x, in+y);
|
||||
|
||||
/* now check if the imported key will fit */
|
||||
if (inlen < x) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
inlen -= x;
|
||||
}
|
||||
|
||||
y += 4;
|
||||
if ((err = dh_import(in+y, x, &pubkey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
y += x;
|
||||
|
||||
/* make shared key */
|
||||
x = (unsigned long)sizeof(shared_secret);
|
||||
if ((err = dh_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
|
||||
dh_free(&pubkey);
|
||||
return err;
|
||||
}
|
||||
dh_free(&pubkey);
|
||||
|
||||
z = sizeof(skey);
|
||||
if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* load in the encrypted key */
|
||||
LOAD32L(keysize, in+y);
|
||||
|
||||
/* will the outkey fit as part of the input */
|
||||
if (inlen < keysize) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
inlen -= keysize;
|
||||
}
|
||||
|
||||
if (keysize > *keylen) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
y += 4;
|
||||
|
||||
*keylen = keysize;
|
||||
|
||||
for (x = 0; x < keysize; x++, y++) {
|
||||
outkey[x] = skey[x] ^ in[y];
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
done:
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(shared_secret, sizeof(shared_secret));
|
||||
zeromem(skey, sizeof(skey));
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
/* perform an ElGamal Signature of a hash
|
||||
*
|
||||
* The math works as follows. x is the private key, M is the message to sign
|
||||
|
||||
1. pick a random k
|
||||
2. compute a = g^k mod p
|
||||
3. compute b = (M - xa)/k mod p
|
||||
4. Send (a,b)
|
||||
|
||||
Now to verify with y=g^x mod p, a and b
|
||||
|
||||
1. compute y^a * a^b = g^(xa) * g^(k*(M-xa)/k)
|
||||
= g^(xa + (M - xa))
|
||||
= g^M [all mod p]
|
||||
|
||||
2. Compare against g^M mod p [based on input hash].
|
||||
3. If result of #2 == result of #1 then signature valid
|
||||
*/
|
||||
int dh_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, dh_key *key)
|
||||
{
|
||||
mp_int a, b, k, m, g, p, p1, tmp;
|
||||
unsigned char buf[520];
|
||||
unsigned long x, y;
|
||||
int err;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check parameters */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* is the IDX valid ? */
|
||||
if (is_valid_idx(key->idx) != 1) {
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
/* make up a random value k,
|
||||
* since the order of the group is prime
|
||||
* we need not check if gcd(k, r) is 1
|
||||
*/
|
||||
if (prng_descriptor[wprng].read(buf, sets[key->idx].size, prng) !=
|
||||
(unsigned long)(sets[key->idx].size)) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* init bignums */
|
||||
if ((err = mp_init_multi(&a, &b, &k, &m, &p, &g, &p1, &tmp, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
/* load k and m */
|
||||
if ((err = mp_read_unsigned_bin(&m, (unsigned char *)in, inlen)) != MP_OKAY) { goto error; }
|
||||
#ifdef FAST_PK
|
||||
if ((err = mp_read_unsigned_bin(&k, buf, MIN(32,sets[key->idx].size))) != MP_OKAY) { goto error; }
|
||||
#else
|
||||
if ((err = mp_read_unsigned_bin(&k, buf, sets[key->idx].size)) != MP_OKAY) { goto error; }
|
||||
#endif
|
||||
|
||||
/* load g, p and p1 */
|
||||
if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_sub_d(&p, 1, &p1)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_div_2(&p1, &p1)) != MP_OKAY) { goto error; } /* p1 = (p-1)/2 */
|
||||
|
||||
/* now get a = g^k mod p */
|
||||
if ((err = mp_exptmod(&g, &k, &p, &a)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* now find M = xa + kb mod p1 or just b = (M - xa)/k mod p1 */
|
||||
if ((err = mp_invmod(&k, &p1, &k)) != MP_OKAY) { goto error; } /* k = 1/k mod p1 */
|
||||
if ((err = mp_mulmod(&a, &key->x, &p1, &tmp)) != MP_OKAY) { goto error; } /* tmp = xa */
|
||||
if ((err = mp_submod(&m, &tmp, &p1, &tmp)) != MP_OKAY) { goto error; } /* tmp = M - xa */
|
||||
if ((err = mp_mulmod(&k, &tmp, &p1, &b)) != MP_OKAY) { goto error; } /* b = (M - xa)/k */
|
||||
|
||||
/* check for overflow */
|
||||
if ((unsigned long)(PACKET_SIZE + 4 + 4 + mp_unsigned_bin_size(&a) + mp_unsigned_bin_size(&b)) > *outlen) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* now store them both (a,b) */
|
||||
x = (unsigned long)mp_unsigned_bin_size(&a);
|
||||
STORE32L(x, out+y); y += 4;
|
||||
if ((err = mp_to_unsigned_bin(&a, out+y)) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
x = (unsigned long)mp_unsigned_bin_size(&b);
|
||||
STORE32L(x, out+y); y += 4;
|
||||
if ((err = mp_to_unsigned_bin(&b, out+y)) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
/* check if size too big */
|
||||
if (*outlen < y) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_DH, PACKET_SUB_SIGNED);
|
||||
*outlen = y;
|
||||
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
mp_clear_multi(&tmp, &p1, &g, &p, &m, &k, &b, &a, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
/* verify the signature in sig of the given hash */
|
||||
int dh_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, dh_key *key)
|
||||
{
|
||||
mp_int a, b, p, g, m, tmp;
|
||||
unsigned long x, y;
|
||||
int err;
|
||||
|
||||
_ARGCHK(sig != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
_ARGCHK(stat != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* default to invalid */
|
||||
*stat = 0;
|
||||
|
||||
/* check initial input length */
|
||||
if (siglen < PACKET_SIZE+4+4) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* header ok? */
|
||||
if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DH, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* get hash out of packet */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* init all bignums */
|
||||
if ((err = mp_init_multi(&a, &p, &b, &g, &m, &tmp, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
/* load a and b */
|
||||
INPUT_BIGNUM(&a, sig, x, y, siglen);
|
||||
INPUT_BIGNUM(&b, sig, x, y, siglen);
|
||||
|
||||
/* load p and g */
|
||||
if ((err = mp_read_radix(&p, sets[key->idx].prime, 64)) != MP_OKAY) { goto error1; }
|
||||
if ((err = mp_read_radix(&g, sets[key->idx].base, 64)) != MP_OKAY) { goto error1; }
|
||||
|
||||
/* load m */
|
||||
if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, hashlen)) != MP_OKAY) { goto error1; }
|
||||
|
||||
/* find g^m mod p */
|
||||
if ((err = mp_exptmod(&g, &m, &p, &m)) != MP_OKAY) { goto error1; } /* m = g^m mod p */
|
||||
|
||||
/* find y^a * a^b */
|
||||
if ((err = mp_exptmod(&key->y, &a, &p, &tmp)) != MP_OKAY) { goto error1; } /* tmp = y^a mod p */
|
||||
if ((err = mp_exptmod(&a, &b, &p, &a)) != MP_OKAY) { goto error1; } /* a = a^b mod p */
|
||||
if ((err = mp_mulmod(&a, &tmp, &p, &a)) != MP_OKAY) { goto error1; } /* a = y^a * a^b mod p */
|
||||
|
||||
/* y^a * a^b == g^m ??? */
|
||||
if (mp_cmp(&a, &m) == 0) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error1:
|
||||
err = mpi_to_ltc_error(err);
|
||||
error:
|
||||
done:
|
||||
mp_clear_multi(&tmp, &m, &g, &p, &b, &a, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
62
dsa_export.c
Normal file
62
dsa_export.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/* 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 MDSA
|
||||
|
||||
int dsa_export(unsigned char *out, unsigned long *outlen, int type, dsa_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 + 2)) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
if (type != PK_PUBLIC && type != PK_PRIVATE) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_KEY);
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* store g, p, q, qord */
|
||||
out[y++] = type;
|
||||
out[y++] = (key->qord>>8)&255;
|
||||
out[y++] = key->qord & 255;
|
||||
|
||||
OUTPUT_BIGNUM(&key->g,out,y,z);
|
||||
OUTPUT_BIGNUM(&key->p,out,y,z);
|
||||
OUTPUT_BIGNUM(&key->q,out,y,z);
|
||||
|
||||
/* public exponent */
|
||||
OUTPUT_BIGNUM(&key->y,out,y,z);
|
||||
|
||||
if (type == PK_PRIVATE) {
|
||||
OUTPUT_BIGNUM(&key->x,out,y,z);
|
||||
}
|
||||
|
||||
*outlen = y;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
21
dsa_free.c
Normal file
21
dsa_free.c
Normal file
@@ -0,0 +1,21 @@
|
||||
/* 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 MDSA
|
||||
|
||||
void dsa_free(dsa_key *key)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
59
dsa_import.c
Normal file
59
dsa_import.c
Normal 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 MDSA
|
||||
|
||||
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
|
||||
{
|
||||
unsigned long x, y;
|
||||
int err;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check length */
|
||||
if ((1+2+PACKET_SIZE) > inlen) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* check type */
|
||||
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_DSA, PACKET_SUB_KEY)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* init key */
|
||||
if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* read type/qord */
|
||||
key->type = in[y++];
|
||||
key->qord = ((unsigned)in[y]<<8)|((unsigned)in[y+1]);
|
||||
y += 2;
|
||||
|
||||
/* input publics */
|
||||
INPUT_BIGNUM(&key->g,in,x,y, inlen);
|
||||
INPUT_BIGNUM(&key->p,in,x,y, inlen);
|
||||
INPUT_BIGNUM(&key->q,in,x,y, inlen);
|
||||
INPUT_BIGNUM(&key->y,in,x,y, inlen);
|
||||
if (key->type == PK_PRIVATE) {
|
||||
INPUT_BIGNUM(&key->x,in,x,y, inlen);
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
error:
|
||||
mp_clear_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
117
dsa_make_key.c
Normal file
117
dsa_make_key.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* 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 MDSA
|
||||
|
||||
int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
|
||||
{
|
||||
mp_int tmp, tmp2;
|
||||
int err, res;
|
||||
unsigned char buf[512];
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check prng */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* check size */
|
||||
if (group_size >= 1024 || group_size <= 15 ||
|
||||
group_size >= modulus_size || (modulus_size - group_size) >= (int)sizeof(buf)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* init mp_ints */
|
||||
if ((err = mp_init_multi(&tmp, &tmp2, &key->g, &key->q, &key->p, &key->x, &key->y, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
/* make our prime q */
|
||||
if ((err = rand_prime(&key->q, group_size*8, prng, wprng)) != CRYPT_OK) { goto error2; }
|
||||
|
||||
/* double q */
|
||||
if ((err = mp_mul_2(&key->q, &tmp)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* now make a random string and multply it against q */
|
||||
if (prng_descriptor[wprng].read(buf+1, modulus_size - group_size, prng) != (unsigned long)(modulus_size - group_size)) {
|
||||
err = CRYPT_ERROR_READPRNG;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
/* force magnitude */
|
||||
buf[0] = 1;
|
||||
|
||||
/* force even */
|
||||
buf[modulus_size - group_size] &= ~1;
|
||||
|
||||
if ((err = mp_read_unsigned_bin(&tmp2, buf, modulus_size - group_size+1)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_mul(&key->q, &tmp2, &key->p)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_add_d(&key->p, 1, &key->p)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* now loop until p is prime */
|
||||
for (;;) {
|
||||
if ((err = is_prime(&key->p, &res)) != CRYPT_OK) { goto error2; }
|
||||
if (res == MP_YES) break;
|
||||
|
||||
/* add 2q to p and 2 to tmp2 */
|
||||
if ((err = mp_add(&tmp, &key->p, &key->p)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_add_d(&tmp2, 2, &tmp2)) != MP_OKAY) { goto error; }
|
||||
}
|
||||
|
||||
/* now p = (q * tmp2) + 1 is prime, find a value g for which g^tmp2 != 1 */
|
||||
mp_set(&key->g, 1);
|
||||
|
||||
do {
|
||||
if ((err = mp_add_d(&key->g, 1, &key->g)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_exptmod(&key->g, &tmp2, &key->p, &tmp)) != MP_OKAY) { goto error; }
|
||||
} while (mp_cmp_d(&tmp, 1) == MP_EQ);
|
||||
|
||||
/* at this point tmp generates a group of order q mod p */
|
||||
mp_exch(&tmp, &key->g);
|
||||
|
||||
/* so now we have our DH structure, generator g, order q, modulus p
|
||||
Now we need a random exponent [mod q] and it's power g^x mod p
|
||||
*/
|
||||
do {
|
||||
if (prng_descriptor[wprng].read(buf, group_size, prng) != (unsigned long)group_size) {
|
||||
err = CRYPT_ERROR_READPRNG;
|
||||
goto error2;
|
||||
}
|
||||
if ((err = mp_read_unsigned_bin(&key->x, buf, group_size)) != MP_OKAY) { goto error; }
|
||||
} while (mp_cmp_d(&key->x, 1) != MP_GT);
|
||||
if ((err = mp_exptmod(&key->g, &key->x, &key->p, &key->y)) != MP_OKAY) { goto error; }
|
||||
|
||||
key->type = PK_PRIVATE;
|
||||
key->qord = group_size;
|
||||
|
||||
/* shrink the ram required */
|
||||
if ((err = mp_shrink(&key->g)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_shrink(&key->p)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_shrink(&key->q)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_shrink(&key->x)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_shrink(&key->y)) != MP_OKAY) { goto error; }
|
||||
|
||||
err = CRYPT_OK;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
|
||||
goto done;
|
||||
error : err = mpi_to_ltc_error(err);
|
||||
error2: mp_clear_multi(&key->g, &key->q, &key->p, &key->x, &key->y, NULL);
|
||||
done : mp_clear_multi(&tmp, &tmp2, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
125
dsa_sign_hash.c
Normal file
125
dsa_sign_hash.c
Normal file
@@ -0,0 +1,125 @@
|
||||
/* 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 MDSA
|
||||
|
||||
int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, dsa_key *key)
|
||||
{
|
||||
mp_int k, kinv, tmp, r, s;
|
||||
unsigned char buf[512];
|
||||
int err, y;
|
||||
unsigned long len;
|
||||
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* check group order size */
|
||||
if (key->qord >= (int)sizeof(buf)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* Init our temps */
|
||||
if ((err = mp_init_multi(&k, &kinv, &r, &s, &tmp, NULL)) != MP_OKAY) { goto error; }
|
||||
|
||||
retry:
|
||||
|
||||
do {
|
||||
/* gen random k */
|
||||
if (prng_descriptor[wprng].read(buf, key->qord, prng) != (unsigned long)key->qord) {
|
||||
err = CRYPT_ERROR_READPRNG;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* read k */
|
||||
if ((err = mp_read_unsigned_bin(&k, buf, key->qord)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* k > 1 ? */
|
||||
if (mp_cmp_d(&k, 1) != MP_GT) { goto retry; }
|
||||
|
||||
/* test gcd */
|
||||
if ((err = mp_gcd(&k, &key->q, &tmp)) != MP_OKAY) { goto error; }
|
||||
} while (mp_cmp_d(&tmp, 1) != MP_EQ);
|
||||
|
||||
/* now find 1/k mod q */
|
||||
if ((err = mp_invmod(&k, &key->q, &kinv)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* now find r = g^k mod p mod q */
|
||||
if ((err = mp_exptmod(&key->g, &k, &key->p, &r)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_mod(&r, &key->q, &r)) != MP_OKAY) { goto error; }
|
||||
|
||||
if (mp_iszero(&r) == MP_YES) { goto retry; }
|
||||
|
||||
/* now find s = (in + xr)/k mod q */
|
||||
if ((err = mp_read_unsigned_bin(&tmp, (unsigned char *)in, inlen)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_mul(&key->x, &r, &s)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_add(&s, &tmp, &s)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_mulmod(&s, &kinv, &key->q, &s)) != MP_OKAY) { goto error; }
|
||||
|
||||
if (mp_iszero(&s) == MP_YES) { goto retry; }
|
||||
|
||||
/* now store em both */
|
||||
|
||||
/* first check that we have enough room */
|
||||
if (*outlen < (unsigned long)(PACKET_SIZE + 4 + mp_unsigned_bin_size(&s) + mp_unsigned_bin_size(&r))) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* packet header */
|
||||
packet_store_header(out, PACKET_SECT_DSA, PACKET_SUB_SIGNED);
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* store length of r */
|
||||
len = mp_unsigned_bin_size(&r);
|
||||
out[y++] = (len>>8)&255;
|
||||
out[y++] = len&255;
|
||||
|
||||
/* store r */
|
||||
if ((err = mp_to_unsigned_bin(&r, out+y)) != MP_OKAY) { goto error; }
|
||||
y += len;
|
||||
|
||||
/* store length of s */
|
||||
len = mp_unsigned_bin_size(&s);
|
||||
out[y++] = (len>>8)&255;
|
||||
out[y++] = len&255;
|
||||
|
||||
/* store s */
|
||||
if ((err = mp_to_unsigned_bin(&s, out+y)) != MP_OKAY) { goto error; }
|
||||
y += len;
|
||||
|
||||
/* reset size */
|
||||
*outlen = y;
|
||||
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
|
||||
error : err = mpi_to_ltc_error(err);
|
||||
done : mp_clear_multi(&k, &kinv, &r, &s, &tmp, NULL);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
97
dsa_verify_hash.c
Normal file
97
dsa_verify_hash.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/* 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 MDSA
|
||||
|
||||
int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long inlen,
|
||||
int *stat, dsa_key *key)
|
||||
{
|
||||
mp_int r, s, w, v, u1, u2;
|
||||
unsigned long x, y;
|
||||
int err;
|
||||
|
||||
_ARGCHK(sig != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
_ARGCHK(stat != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* default to invalid signature */
|
||||
*stat = 0;
|
||||
|
||||
if (siglen < PACKET_SIZE+2+2) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* is the message format correct? */
|
||||
if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_DSA, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* skip over header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* init our variables */
|
||||
if ((err = mp_init_multi(&r, &s, &w, &v, &u1, &u2, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
/* read in r followed by s */
|
||||
x = ((unsigned)sig[y]<<8)|((unsigned)sig[y+1]);
|
||||
y += 2;
|
||||
if (y + x > siglen) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto done;
|
||||
}
|
||||
if ((err = mp_read_unsigned_bin(&r, (unsigned char *)sig+y, x)) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
/* load s */
|
||||
x = ((unsigned)sig[y]<<8)|((unsigned)sig[y+1]);
|
||||
y += 2;
|
||||
if (y + x > siglen) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto done;
|
||||
}
|
||||
if ((err = mp_read_unsigned_bin(&s, (unsigned char *)sig+y, x)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* w = 1/s mod q */
|
||||
if ((err = mp_invmod(&s, &key->q, &w)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* u1 = m * w mod q */
|
||||
if ((err = mp_read_unsigned_bin(&u1, (unsigned char *)hash, inlen)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_mulmod(&u1, &w, &key->q, &u1)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* u2 = r*w mod q */
|
||||
if ((err = mp_mulmod(&r, &w, &key->q, &u2)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* v = g^u1 * y^u2 mod p mod q */
|
||||
if ((err = mp_exptmod(&key->g, &u1, &key->p, &u1)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_exptmod(&key->y, &u2, &key->p, &u2)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_mulmod(&u1, &u2, &key->p, &v)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_mod(&v, &key->q, &v)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* if r = v then we're set */
|
||||
if (mp_cmp(&r, &v) == MP_EQ) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
|
||||
error : err = mpi_to_ltc_error(err);
|
||||
done : mp_clear_multi(&r, &s, &w, &v, &u1, &u2, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
86
dsa_verify_key.c
Normal file
86
dsa_verify_key.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/* 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 MDSA
|
||||
|
||||
int dsa_verify_key(dsa_key *key, int *stat)
|
||||
{
|
||||
mp_int tmp, tmp2;
|
||||
int res, err;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(stat != NULL);
|
||||
|
||||
*stat = 0;
|
||||
|
||||
/* first make sure key->q and key->p are prime */
|
||||
if ((err = is_prime(&key->q, &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (res == 0) {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
if ((err = is_prime(&key->p, &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (res == 0) {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* now make sure that g is not -1, 0 or 1 and <p */
|
||||
if (mp_cmp_d(&key->g, 0) == MP_EQ || mp_cmp_d(&key->g, 1) == MP_EQ) {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
if ((err = mp_init_multi(&tmp, &tmp2, NULL)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_sub_d(&key->p, 1, &tmp)) != MP_OKAY) { goto error; }
|
||||
if (mp_cmp(&tmp, &key->g) == MP_EQ || mp_cmp(&key->g, &key->p) != MP_LT) {
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* 1 < y < p-1 */
|
||||
if (!(mp_cmp_d(&key->y, 1) == MP_GT && mp_cmp(&key->y, &tmp) == MP_LT)) {
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* now we have to make sure that g^q = 1, and that p-1/q gives 0 remainder */
|
||||
if ((err = mp_div(&tmp, &key->q, &tmp, &tmp2)) != MP_OKAY) { goto error; }
|
||||
if (mp_iszero(&tmp2) != MP_YES) {
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((err = mp_exptmod(&key->g, &key->q, &key->p, &tmp)) != MP_OKAY) { goto error; }
|
||||
if (mp_cmp_d(&tmp, 1) != MP_EQ) {
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* now we have to make sure that y^q = 1, this makes sure y \in g^x mod p */
|
||||
if ((err = mp_exptmod(&key->y, &key->q, &key->p, &tmp)) != MP_OKAY) { goto error; }
|
||||
if (mp_cmp_d(&tmp, 1) != MP_EQ) {
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* at this point we are out of tests ;-( */
|
||||
err = CRYPT_OK;
|
||||
*stat = 1;
|
||||
goto done;
|
||||
error: err = mpi_to_ltc_error(err);
|
||||
done : mp_clear_multi(&tmp, &tmp2, NULL);
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
25
eax_addheader.c
Normal file
25
eax_addheader.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* EAX Implementation by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef EAX_MODE
|
||||
|
||||
/* add header (metadata) to the stream */
|
||||
int eax_addheader(eax_state *eax, const unsigned char *header, unsigned long length)
|
||||
{
|
||||
_ARGCHK(eax != NULL);
|
||||
_ARGCHK(header != NULL);
|
||||
return omac_process(&eax->headeromac, header, length);
|
||||
}
|
||||
|
||||
#endif
|
||||
34
eax_decrypt.c
Normal file
34
eax_decrypt.c
Normal file
@@ -0,0 +1,34 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* EAX Implementation by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef EAX_MODE
|
||||
|
||||
int eax_decrypt(eax_state *eax, const unsigned char *ct, unsigned char *pt, unsigned long length)
|
||||
{
|
||||
int err;
|
||||
|
||||
_ARGCHK(eax != NULL);
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
|
||||
/* omac ciphertext */
|
||||
if ((err = omac_process(&eax->ctomac, ct, length)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* decrypt */
|
||||
return ctr_decrypt(ct, pt, length, &eax->ctr);
|
||||
}
|
||||
|
||||
#endif
|
||||
60
eax_decrypt_verify_memory.c
Normal file
60
eax_decrypt_verify_memory.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* EAX Implementation by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef EAX_MODE
|
||||
|
||||
int eax_decrypt_verify_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
const unsigned char *ct, unsigned long ctlen,
|
||||
unsigned char *pt,
|
||||
unsigned char *tag, unsigned long taglen,
|
||||
int *res)
|
||||
{
|
||||
int err;
|
||||
eax_state eax;
|
||||
unsigned char buf[MAXBLOCKSIZE];
|
||||
unsigned long buflen;
|
||||
|
||||
_ARGCHK(res != NULL);
|
||||
|
||||
/* default to zero */
|
||||
*res = 0;
|
||||
|
||||
if ((err = eax_init(&eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = eax_decrypt(&eax, ct, pt, ctlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
buflen = MIN(sizeof(buf), taglen);
|
||||
if ((err = eax_done(&eax, buf, &buflen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* compare tags */
|
||||
if (buflen >= taglen && memcmp(buf, tag, taglen) == 0) {
|
||||
*res = 1;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
56
eax_done.c
Normal file
56
eax_done.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* EAX Implementation by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef EAX_MODE
|
||||
|
||||
int eax_done(eax_state *eax, unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
int err;
|
||||
unsigned char headermac[MAXBLOCKSIZE], ctmac[MAXBLOCKSIZE];
|
||||
unsigned long x, len;
|
||||
|
||||
_ARGCHK(eax != NULL);
|
||||
_ARGCHK(tag != NULL);
|
||||
_ARGCHK(taglen != NULL);
|
||||
|
||||
/* finish ctomac */
|
||||
len = sizeof(ctmac);
|
||||
if ((err = omac_done(&eax->ctomac, ctmac, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* finish headeromac */
|
||||
|
||||
/* note we specifically don't reset len so the two lens are minimal */
|
||||
|
||||
if ((err = omac_done(&eax->headeromac, headermac, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* compute N xor H xor C */
|
||||
for (x = 0; x < len && x < *taglen; x++) {
|
||||
tag[x] = eax->N[x] ^ headermac[x] ^ ctmac[x];
|
||||
}
|
||||
*taglen = x;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(ctmac, sizeof(ctmac));
|
||||
zeromem(headermac, sizeof(headermac));
|
||||
zeromem(eax, sizeof(*eax));
|
||||
#endif
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
35
eax_encrypt.c
Normal file
35
eax_encrypt.c
Normal file
@@ -0,0 +1,35 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* EAX Implementation by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef EAX_MODE
|
||||
|
||||
int eax_encrypt(eax_state *eax, const unsigned char *pt, unsigned char *ct, unsigned long length)
|
||||
{
|
||||
int err;
|
||||
|
||||
_ARGCHK(eax != NULL);
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
|
||||
/* encrypt */
|
||||
if ((err = ctr_encrypt(pt, ct, length, &eax->ctr)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* omac ciphertext */
|
||||
return omac_process(&eax->ctomac, ct, length);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
43
eax_encrypt_authenticate_memory.c
Normal file
43
eax_encrypt_authenticate_memory.c
Normal 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
|
||||
*/
|
||||
|
||||
/* EAX Implementation by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef EAX_MODE
|
||||
|
||||
int eax_encrypt_authenticate_memory(int cipher,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen,
|
||||
const unsigned char *pt, unsigned long ptlen,
|
||||
unsigned char *ct,
|
||||
unsigned char *tag, unsigned long *taglen)
|
||||
{
|
||||
int err;
|
||||
eax_state eax;
|
||||
|
||||
if ((err = eax_init(&eax, cipher, key, keylen, nonce, noncelen, header, headerlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = eax_encrypt(&eax, pt, ct, ptlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = eax_done(&eax, tag, taglen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
106
eax_init.c
Normal file
106
eax_init.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* EAX Implementation by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef EAX_MODE
|
||||
|
||||
int eax_init(eax_state *eax, int cipher, const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *nonce, unsigned long noncelen,
|
||||
const unsigned char *header, unsigned long headerlen)
|
||||
{
|
||||
unsigned char buf[MAXBLOCKSIZE];
|
||||
int err, blklen;
|
||||
omac_state omac;
|
||||
unsigned long len;
|
||||
|
||||
|
||||
_ARGCHK(eax != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(nonce != NULL);
|
||||
if (headerlen > 0) {
|
||||
_ARGCHK(header != NULL);
|
||||
}
|
||||
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
blklen = cipher_descriptor[cipher].block_length;
|
||||
|
||||
/* N = OMAC_0K(nonce) */
|
||||
zeromem(buf, sizeof(buf));
|
||||
if ((err = omac_init(&omac, cipher, key, keylen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* omac the [0]_n */
|
||||
if ((err = omac_process(&omac, buf, blklen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
/* omac the nonce */
|
||||
if ((err = omac_process(&omac, nonce, noncelen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
/* store result */
|
||||
len = sizeof(eax->N);
|
||||
if ((err = omac_done(&omac, eax->N, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* H = OMAC_1K(header) */
|
||||
zeromem(buf, sizeof(buf));
|
||||
buf[blklen - 1] = 1;
|
||||
|
||||
if ((err = omac_init(&eax->headeromac, cipher, key, keylen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* omac the [1]_n */
|
||||
if ((err = omac_process(&eax->headeromac, buf, blklen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
/* omac the header */
|
||||
if (headerlen != 0) {
|
||||
if ((err = omac_process(&eax->headeromac, header, headerlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
/* note we don't finish the headeromac, this allows us to add more header later */
|
||||
|
||||
/* setup the CTR mode */
|
||||
if ((err = ctr_start(cipher, eax->N, key, keylen, 0, &eax->ctr)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
/* use big-endian counter */
|
||||
eax->ctr.mode = 1;
|
||||
|
||||
/* setup the OMAC for the ciphertext */
|
||||
if ((err = omac_init(&eax->ctomac, cipher, key, keylen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* omac [2]_n */
|
||||
zeromem(buf, sizeof(buf));
|
||||
buf[blklen-1] = 2;
|
||||
if ((err = omac_process(&eax->ctomac, buf, blklen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
zeromem(&omac, sizeof(omac));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
271
eax_test.c
Normal file
271
eax_test.c
Normal file
@@ -0,0 +1,271 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* EAX Implementation by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef EAX_MODE
|
||||
|
||||
int eax_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
int keylen,
|
||||
noncelen,
|
||||
headerlen,
|
||||
msglen;
|
||||
|
||||
unsigned char key[MAXBLOCKSIZE],
|
||||
nonce[MAXBLOCKSIZE],
|
||||
header[MAXBLOCKSIZE],
|
||||
plaintext[MAXBLOCKSIZE],
|
||||
ciphertext[MAXBLOCKSIZE],
|
||||
tag[MAXBLOCKSIZE];
|
||||
} tests[] = {
|
||||
|
||||
/* NULL message */
|
||||
{
|
||||
16, 0, 0, 0,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0 },
|
||||
/* header */
|
||||
{ 0 },
|
||||
/* plaintext */
|
||||
{ 0 },
|
||||
/* ciphertext */
|
||||
{ 0 },
|
||||
/* tag */
|
||||
{ 0x9a, 0xd0, 0x7e, 0x7d, 0xbf, 0xf3, 0x01, 0xf5,
|
||||
0x05, 0xde, 0x59, 0x6b, 0x96, 0x15, 0xdf, 0xff }
|
||||
},
|
||||
|
||||
/* test with nonce */
|
||||
{
|
||||
16, 16, 0, 0,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* header */
|
||||
{ 0 },
|
||||
/* plaintext */
|
||||
{ 0 },
|
||||
/* ciphertext */
|
||||
{ 0 },
|
||||
/* tag */
|
||||
{ 0x1c, 0xe1, 0x0d, 0x3e, 0xff, 0xd4, 0xca, 0xdb,
|
||||
0xe2, 0xe4, 0x4b, 0x58, 0xd6, 0x0a, 0xb9, 0xec }
|
||||
},
|
||||
|
||||
/* test with header [no nonce] */
|
||||
{
|
||||
16, 0, 16, 0,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0 },
|
||||
/* header */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* plaintext */
|
||||
{ 0 },
|
||||
/* ciphertext */
|
||||
{ 0 },
|
||||
/* tag */
|
||||
{ 0x3a, 0x69, 0x8f, 0x7a, 0x27, 0x0e, 0x51, 0xb0,
|
||||
0xf6, 0x5b, 0x3d, 0x3e, 0x47, 0x19, 0x3c, 0xff }
|
||||
},
|
||||
|
||||
/* test with header + nonce + plaintext */
|
||||
{
|
||||
16, 16, 16, 32,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* header */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* plaintext */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
|
||||
/* ciphertext */
|
||||
{ 0x29, 0xd8, 0x78, 0xd1, 0xa3, 0xbe, 0x85, 0x7b,
|
||||
0x6f, 0xb8, 0xc8, 0xea, 0x59, 0x50, 0xa7, 0x78,
|
||||
0x33, 0x1f, 0xbf, 0x2c, 0xcf, 0x33, 0x98, 0x6f,
|
||||
0x35, 0xe8, 0xcf, 0x12, 0x1d, 0xcb, 0x30, 0xbc },
|
||||
/* tag */
|
||||
{ 0x4f, 0xbe, 0x03, 0x38, 0xbe, 0x1c, 0x8c, 0x7e,
|
||||
0x1d, 0x7a, 0xe7, 0xe4, 0x5b, 0x92, 0xc5, 0x87 }
|
||||
},
|
||||
|
||||
/* test with header + nonce + plaintext [not even sizes!] */
|
||||
{
|
||||
16, 15, 14, 29,
|
||||
/* key */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
|
||||
/* nonce */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e },
|
||||
/* header */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d },
|
||||
/* plaintext */
|
||||
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c },
|
||||
/* ciphertext */
|
||||
{ 0xdd, 0x25, 0xc7, 0x54, 0xc5, 0xb1, 0x7c, 0x59,
|
||||
0x28, 0xb6, 0x9b, 0x73, 0x15, 0x5f, 0x7b, 0xb8,
|
||||
0x88, 0x8f, 0xaf, 0x37, 0x09, 0x1a, 0xd9, 0x2c,
|
||||
0x8a, 0x24, 0xdb, 0x86, 0x8b },
|
||||
/* tag */
|
||||
{ 0x0d, 0x1a, 0x14, 0xe5, 0x22, 0x24, 0xff, 0xd2,
|
||||
0x3a, 0x05, 0xfa, 0x02, 0xcd, 0xef, 0x52, 0xda }
|
||||
},
|
||||
|
||||
/* Vectors from Brian Gladman */
|
||||
|
||||
{
|
||||
16, 16, 8, 0,
|
||||
/* key */
|
||||
{ 0x23, 0x39, 0x52, 0xde, 0xe4, 0xd5, 0xed, 0x5f,
|
||||
0x9b, 0x9c, 0x6d, 0x6f, 0xf8, 0x0f, 0xf4, 0x78 },
|
||||
/* nonce */
|
||||
{ 0x62, 0xec, 0x67, 0xf9, 0xc3, 0xa4, 0xa4, 0x07,
|
||||
0xfc, 0xb2, 0xa8, 0xc4, 0x90, 0x31, 0xa8, 0xb3 },
|
||||
/* header */
|
||||
{ 0x6b, 0xfb, 0x91, 0x4f, 0xd0, 0x7e, 0xae, 0x6b },
|
||||
/* PT */
|
||||
{ 0x00 },
|
||||
/* CT */
|
||||
{ 0x00 },
|
||||
/* tag */
|
||||
{ 0xe0, 0x37, 0x83, 0x0e, 0x83, 0x89, 0xf2, 0x7b,
|
||||
0x02, 0x5a, 0x2d, 0x65, 0x27, 0xe7, 0x9d, 0x01 }
|
||||
},
|
||||
|
||||
{
|
||||
16, 16, 8, 2,
|
||||
/* key */
|
||||
{ 0x91, 0x94, 0x5d, 0x3f, 0x4d, 0xcb, 0xee, 0x0b,
|
||||
0xf4, 0x5e, 0xf5, 0x22, 0x55, 0xf0, 0x95, 0xa4 },
|
||||
/* nonce */
|
||||
{ 0xbe, 0xca, 0xf0, 0x43, 0xb0, 0xa2, 0x3d, 0x84,
|
||||
0x31, 0x94, 0xba, 0x97, 0x2c, 0x66, 0xde, 0xbd },
|
||||
/* header */
|
||||
{ 0xfa, 0x3b, 0xfd, 0x48, 0x06, 0xeb, 0x53, 0xfa },
|
||||
/* PT */
|
||||
{ 0xf7, 0xfb },
|
||||
/* CT */
|
||||
{ 0x19, 0xdd },
|
||||
/* tag */
|
||||
{ 0x5c, 0x4c, 0x93, 0x31, 0x04, 0x9d, 0x0b, 0xda,
|
||||
0xb0, 0x27, 0x74, 0x08, 0xf6, 0x79, 0x67, 0xe5 }
|
||||
},
|
||||
|
||||
{
|
||||
16, 16, 8, 5,
|
||||
/* key */
|
||||
{ 0x01, 0xf7, 0x4a, 0xd6, 0x40, 0x77, 0xf2, 0xe7,
|
||||
0x04, 0xc0, 0xf6, 0x0a, 0xda, 0x3d, 0xd5, 0x23 },
|
||||
/* nonce */
|
||||
{ 0x70, 0xc3, 0xdb, 0x4f, 0x0d, 0x26, 0x36, 0x84,
|
||||
0x00, 0xa1, 0x0e, 0xd0, 0x5d, 0x2b, 0xff, 0x5e },
|
||||
/* header */
|
||||
{ 0x23, 0x4a, 0x34, 0x63, 0xc1, 0x26, 0x4a, 0xc6 },
|
||||
/* PT */
|
||||
{ 0x1a, 0x47, 0xcb, 0x49, 0x33 },
|
||||
/* CT */
|
||||
{ 0xd8, 0x51, 0xd5, 0xba, 0xe0 },
|
||||
/* Tag */
|
||||
{ 0x3a, 0x59, 0xf2, 0x38, 0xa2, 0x3e, 0x39, 0x19,
|
||||
0x9d, 0xc9, 0x26, 0x66, 0x26, 0xc4, 0x0f, 0x80 }
|
||||
}
|
||||
|
||||
};
|
||||
int err, x, idx, res;
|
||||
unsigned long len;
|
||||
unsigned char outct[MAXBLOCKSIZE], outtag[MAXBLOCKSIZE];
|
||||
|
||||
/* AES can be under rijndael or aes... try to find it */
|
||||
if ((idx = find_cipher("aes")) == -1) {
|
||||
if ((idx = find_cipher("rijndael")) == -1) {
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < (int)(sizeof(tests)/sizeof(tests[0])); x++) {
|
||||
len = sizeof(outtag);
|
||||
if ((err = eax_encrypt_authenticate_memory(idx, tests[x].key, tests[x].keylen,
|
||||
tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen,
|
||||
tests[x].plaintext, tests[x].msglen, outct, outtag, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (memcmp(outct, tests[x].ciphertext, tests[x].msglen) || memcmp(outtag, tests[x].tag, len)) {
|
||||
#if 0
|
||||
unsigned long y;
|
||||
printf("\n\nFailure: \nCT:\n");
|
||||
for (y = 0; y < (unsigned long)tests[x].msglen; ) {
|
||||
printf("0x%02x", outct[y]);
|
||||
if (y < (unsigned long)(tests[x].msglen-1)) printf(", ");
|
||||
if (!(++y % 8)) printf("\n");
|
||||
}
|
||||
printf("\nTAG:\n");
|
||||
for (y = 0; y < len; ) {
|
||||
printf("0x%02x", outtag[y]);
|
||||
if (y < len-1) printf(", ");
|
||||
if (!(++y % 8)) printf("\n");
|
||||
}
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
/* test decrypt */
|
||||
if ((err = eax_decrypt_verify_memory(idx, tests[x].key, tests[x].keylen,
|
||||
tests[x].nonce, tests[x].noncelen, tests[x].header, tests[x].headerlen,
|
||||
outct, tests[x].msglen, outct, outtag, len, &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((res != 1) || memcmp(outct, tests[x].plaintext, tests[x].msglen)) {
|
||||
#if 0
|
||||
unsigned long y;
|
||||
printf("\n\nFailure (res == %d): \nPT:\n", res);
|
||||
for (y = 0; y < (unsigned long)tests[x].msglen; ) {
|
||||
printf("0x%02x", outct[y]);
|
||||
if (y < (unsigned long)(tests[x].msglen-1)) printf(", ");
|
||||
if (!(++y % 8)) printf("\n");
|
||||
}
|
||||
printf("\n\n");
|
||||
#endif
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif /* LTC_TEST */
|
||||
}
|
||||
|
||||
#endif /* EAX_MODE */
|
||||
31
ecb_decrypt.c
Normal file
31
ecb_decrypt.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/* 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 ECB
|
||||
|
||||
int ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_ECB *ecb)
|
||||
{
|
||||
int err;
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(ecb != NULL);
|
||||
|
||||
if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
29
ecb_encrypt.c
Normal file
29
ecb_encrypt.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/* 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 ECB
|
||||
|
||||
int ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_ECB *ecb)
|
||||
{
|
||||
int err;
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(ct != NULL);
|
||||
_ARGCHK(ecb != NULL);
|
||||
|
||||
if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
29
ecb_start.c
Normal file
29
ecb_start.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/* 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 ECB
|
||||
|
||||
int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb)
|
||||
{
|
||||
int err;
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(ecb != NULL);
|
||||
|
||||
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
ecb->cipher = cipher;
|
||||
ecb->blocklen = cipher_descriptor[cipher].block_length;
|
||||
return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ecb->key);
|
||||
}
|
||||
|
||||
#endif
|
||||
937
ecc.c
Normal file
937
ecc.c
Normal file
@@ -0,0 +1,937 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
|
||||
*
|
||||
* All curves taken from NIST recommendation paper of July 1999
|
||||
* Available at http://csrc.nist.gov/cryptval/dss.htm
|
||||
*/
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef MECC
|
||||
|
||||
/* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */
|
||||
static const struct {
|
||||
int size;
|
||||
char *name, *prime, *B, *order, *Gx, *Gy;
|
||||
} sets[] = {
|
||||
#ifdef ECC160
|
||||
{
|
||||
20,
|
||||
"ECC-160",
|
||||
/* prime */
|
||||
"G00000000000000000000000007",
|
||||
/* B */
|
||||
"1oUV2vOaSlWbxr6",
|
||||
/* order */
|
||||
"G0000000000004sCQUtDxaqDUN5",
|
||||
/* Gx */
|
||||
"jpqOf1BHus6Yd/pyhyVpP",
|
||||
/* Gy */
|
||||
"D/wykuuIFfr+vPyx7kQEPu8MixO",
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC192
|
||||
{
|
||||
24,
|
||||
"ECC-192",
|
||||
/* prime */
|
||||
"/////////////////////l//////////",
|
||||
|
||||
/* B */
|
||||
"P2456UMSWESFf+chSYGmIVwutkp1Hhcn",
|
||||
|
||||
/* order */
|
||||
"////////////////cTxuDXHhoR6qqYWn",
|
||||
|
||||
/* Gx */
|
||||
"68se3h0maFPylo3hGw680FJ/2ls2/n0I",
|
||||
|
||||
/* Gy */
|
||||
"1nahbV/8sdXZ417jQoJDrNFvTw4UUKWH"
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC224
|
||||
{
|
||||
28,
|
||||
"ECC-224",
|
||||
|
||||
/* prime */
|
||||
"400000000000000000000000000000000000BV",
|
||||
|
||||
/* B */
|
||||
"21HkWGL2CxJIp",
|
||||
|
||||
/* order */
|
||||
"4000000000000000000Kxnixk9t8MLzMiV264/",
|
||||
|
||||
/* Gx */
|
||||
"jpqOf1BHus6Yd/pyhyVpP",
|
||||
|
||||
/* Gy */
|
||||
"3FCtyo2yHA5SFjkCGbYxbOvNeChwS+j6wSIwck",
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC256
|
||||
{
|
||||
32,
|
||||
"ECC-256",
|
||||
/* Prime */
|
||||
"F////y000010000000000000000////////////////",
|
||||
|
||||
/* B */
|
||||
"5h6DTYgEfFdi+kzLNQOXhnb7GQmp5EmzZlEF3udqc1B",
|
||||
|
||||
/* Order */
|
||||
"F////y00000//////////+yvlgjfnUUXFEvoiByOoLH",
|
||||
|
||||
/* Gx */
|
||||
"6iNqVBXB497+BpcvMEaGF9t0ts1BUipeFIXEKNOcCAM",
|
||||
|
||||
/* Gy */
|
||||
"4/ZGkB+6d+RZkVhIdmFdXOhpZDNQp5UpiksG6Wtlr7r"
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC384
|
||||
{
|
||||
48,
|
||||
"ECC-384",
|
||||
/* prime */
|
||||
"//////////////////////////////////////////x/////00000000003/"
|
||||
"////",
|
||||
|
||||
/* B */
|
||||
"ip4lf+8+v+IOZWLhu/Wj6HWTd6x+WK4I0nG8Zr0JXrh6LZcDYYxHdIg5oEtJ"
|
||||
"x2hl",
|
||||
|
||||
/* Order */
|
||||
"////////////////////////////////nsDDWVGtBTzO6WsoIB2dUkpi6MhC"
|
||||
"nIbp",
|
||||
|
||||
/* Gx and Gy */
|
||||
"geVA8hwB1JUEiSSUyo2jT6uTEsABfvkOMVT1u89KAZXL0l9TlrKfR3fKNZXo"
|
||||
"TWgt",
|
||||
|
||||
"DXVUIfOcB6zTdfY/afBSAVZq7RqecXHywTen4xNmkC0AOB7E7Nw1dNf37NoG"
|
||||
"wWvV"
|
||||
},
|
||||
#endif
|
||||
#ifdef ECC521
|
||||
{
|
||||
65,
|
||||
"ECC-521",
|
||||
/* prime */
|
||||
"V///////////////////////////////////////////////////////////"
|
||||
"///////////////////////////",
|
||||
|
||||
/* B */
|
||||
"56LFhbXZXoQ7vAQ8Q2sXK3kejfoMvcp5VEuj8cHZl49uLOPEL7iVfDx5bB0l"
|
||||
"JknlmSrSz+8FImqyUz57zHhK3y0",
|
||||
|
||||
/* Order */
|
||||
"V//////////////////////////////////////////+b66XuE/BvPhVym1I"
|
||||
"FS9fT0xjScuYPn7hhjljnwHE6G9",
|
||||
|
||||
/* Gx and Gy */
|
||||
"CQ5ZWQt10JfpPu+osOZbRH2d6I1EGK/jI7uAAzWQqqzkg5BNdVlvrae/Xt19"
|
||||
"wB/gDupIBF1XMf2c/b+VZ72vRrc",
|
||||
|
||||
"HWvAMfucZl015oANxGiVHlPcFL4ILURH6WNhxqN9pvcB9VkSfbUz2P0nL2v0"
|
||||
"J+j1s4rF726edB2G8Y+b7QVqMPG",
|
||||
},
|
||||
#endif
|
||||
{
|
||||
0,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
|
||||
/* you plug in a prime and B value and it finds a pseudo-random base point */
|
||||
void ecc_find_base(void)
|
||||
{
|
||||
static char *prime = "26959946667150639794667015087019630673637144422540572481103610249951";
|
||||
static char *order = "26959946667150639794667015087019637467111563745054605861463538557247";
|
||||
static char *b = "9538957348957353489587";
|
||||
mp_int pp, p, r, B, tmp1, tmp2, tx, ty, x, y;
|
||||
char buf[4096];
|
||||
int i;
|
||||
|
||||
mp_init_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL);
|
||||
mp_read_radix(&p, prime, 10);
|
||||
mp_read_radix(&r, order, 10);
|
||||
mp_read_radix(&B, b, 10);
|
||||
|
||||
/* get (p+1)/4 */
|
||||
mp_add_d(&p, 1, &pp);
|
||||
mp_div_2(&pp, &pp);
|
||||
mp_div_2(&pp, &pp);
|
||||
|
||||
buf[0] = 0;
|
||||
do {
|
||||
printf("."); fflush(stdout);
|
||||
/* make a random value of x */
|
||||
for (i = 0; i < 16; i++) buf[i+1] = rand() & 255;
|
||||
mp_read_raw(&x, buf, 17);
|
||||
mp_copy(&x, &tx);
|
||||
|
||||
/* now compute x^3 - 3x + b */
|
||||
mp_expt_d(&x, 3, &tmp1);
|
||||
mp_mul_d(&x, 3, &tmp2);
|
||||
mp_sub(&tmp1, &tmp2, &tmp1);
|
||||
mp_add(&tmp1, &B, &tmp1);
|
||||
mp_mod(&tmp1, &p, &tmp1);
|
||||
|
||||
/* now compute sqrt via x^((p+1)/4) */
|
||||
mp_exptmod(&tmp1, &pp, &p, &tmp2);
|
||||
mp_copy(&tmp2, &ty);
|
||||
|
||||
/* now square it */
|
||||
mp_sqrmod(&tmp2, &p, &tmp2);
|
||||
|
||||
/* tmp2 should equal tmp1 */
|
||||
} while (mp_cmp(&tmp1, &tmp2));
|
||||
|
||||
/* now output values in way that libtomcrypt wants */
|
||||
mp_todecimal(&p, buf);
|
||||
printf("\n\np==%s\n", buf);
|
||||
mp_tohex(&B, buf);
|
||||
printf("b==%s\n", buf);
|
||||
mp_todecimal(&r, buf);
|
||||
printf("r==%s\n", buf);
|
||||
mp_tohex(&tx, buf);
|
||||
printf("Gx==%s\n", buf);
|
||||
mp_tohex(&ty, buf);
|
||||
printf("Gy==%s\n", buf);
|
||||
|
||||
mp_clear_multi(&tx, &ty, &x, &y, &p, &pp, &r, &B, &tmp1, &tmp2, NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
static int is_valid_idx(int n)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; sets[x].size != 0; x++);
|
||||
if ((n < 0) || (n >= x)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static ecc_point *new_point(void)
|
||||
{
|
||||
ecc_point *p;
|
||||
p = XMALLOC(sizeof(ecc_point));
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (mp_init_multi(&p->x, &p->y, NULL) != MP_OKAY) {
|
||||
XFREE(p);
|
||||
return NULL;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static void del_point(ecc_point *p)
|
||||
{
|
||||
/* prevents free'ing null arguments */
|
||||
if (p != NULL) {
|
||||
mp_clear_multi(&p->x, &p->y, NULL);
|
||||
XFREE(p);
|
||||
}
|
||||
}
|
||||
|
||||
/* double a point R = 2P, R can be P*/
|
||||
static int dbl_point(ecc_point *P, ecc_point *R, mp_int *modulus, mp_int *mu)
|
||||
{
|
||||
mp_int s, tmp, tmpx;
|
||||
int err;
|
||||
|
||||
if ((err = mp_init_multi(&s, &tmp, &tmpx, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
/* s = (3Xp^2 + a) / (2Yp) */
|
||||
if ((err = mp_mul_2(&P->y, &tmp)) != MP_OKAY) { goto error; } /* tmp = 2*y */
|
||||
if ((err = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */
|
||||
if ((err = mp_sqr(&P->x, &s)) != MP_OKAY) { goto error; } /* s = x^2 */
|
||||
if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_mul_d(&s,(mp_digit)3, &s)) != MP_OKAY) { goto error; } /* s = 3*(x^2) */
|
||||
if ((err = mp_sub_d(&s,(mp_digit)3, &s)) != MP_OKAY) { goto error; } /* s = 3*(x^2) - 3 */
|
||||
if (mp_cmp_d(&s, 0) == MP_LT) { /* if s < 0 add modulus */
|
||||
if ((err = mp_add(&s, modulus, &s)) != MP_OKAY) { goto error; }
|
||||
}
|
||||
if ((err = mp_mul(&s, &tmp, &s)) != MP_OKAY) { goto error; } /* s = tmp * s mod modulus */
|
||||
if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* Xr = s^2 - 2Xp */
|
||||
if ((err = mp_sqr(&s, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = s^2 */
|
||||
if ((err = mp_reduce(&tmpx, modulus, mu)) != MP_OKAY) { goto error; } /* tmpx = tmpx mod modulus */
|
||||
if ((err = mp_sub(&tmpx, &P->x, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x */
|
||||
if ((err = mp_submod(&tmpx, &P->x, modulus, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmpx - x mod modulus */
|
||||
|
||||
/* Yr = -Yp + s(Xp - Xr) */
|
||||
if ((err = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY) { goto error; } /* tmp = x - tmpx */
|
||||
if ((err = mp_mul(&tmp, &s, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp * s */
|
||||
if ((err = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY) { goto error; } /* y = tmp - y mod modulus */
|
||||
if ((err = mp_copy(&tmpx, &R->x)) != MP_OKAY) { goto error; } /* x = tmpx */
|
||||
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
mp_clear_multi(&tmpx, &tmp, &s, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* add two different points over Z/pZ, R = P + Q, note R can equal either P or Q */
|
||||
static int add_point(ecc_point *P, ecc_point *Q, ecc_point *R, mp_int *modulus, mp_int *mu)
|
||||
{
|
||||
mp_int s, tmp, tmpx;
|
||||
int err;
|
||||
|
||||
if ((err = mp_init(&tmp)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
/* is P==Q or P==-Q? */
|
||||
if (((err = mp_neg(&Q->y, &tmp)) != MP_OKAY) || ((err = mp_mod(&tmp, modulus, &tmp)) != MP_OKAY)) {
|
||||
mp_clear(&tmp);
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
if (mp_cmp(&P->x, &Q->x) == MP_EQ)
|
||||
if (mp_cmp(&P->y, &Q->y) == MP_EQ || mp_cmp(&P->y, &tmp) == MP_EQ) {
|
||||
mp_clear(&tmp);
|
||||
return dbl_point(P, R, modulus, mu);
|
||||
}
|
||||
|
||||
if ((err = mp_init_multi(&tmpx, &s, NULL)) != MP_OKAY) {
|
||||
mp_clear(&tmp);
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
/* get s = (Yp - Yq)/(Xp-Xq) mod p */
|
||||
if ((err = mp_sub(&P->x, &Q->x, &tmp)) != MP_OKAY) { goto error; } /* tmp = Px - Qx mod modulus */
|
||||
if (mp_cmp_d(&tmp, 0) == MP_LT) { /* if tmp<0 add modulus */
|
||||
if ((err = mp_add(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; }
|
||||
}
|
||||
if ((err = mp_invmod(&tmp, modulus, &tmp)) != MP_OKAY) { goto error; } /* tmp = 1/tmp mod modulus */
|
||||
if ((err = mp_sub(&P->y, &Q->y, &s)) != MP_OKAY) { goto error; } /* s = Py - Qy mod modulus */
|
||||
if (mp_cmp_d(&s, 0) == MP_LT) { /* if s<0 add modulus */
|
||||
if ((err = mp_add(&s, modulus, &s)) != MP_OKAY) { goto error; }
|
||||
}
|
||||
if ((err = mp_mul(&s, &tmp, &s)) != MP_OKAY) { goto error; } /* s = s * tmp mod modulus */
|
||||
if ((err = mp_reduce(&s, modulus, mu)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* Xr = s^2 - Xp - Xq */
|
||||
if ((err = mp_sqr(&s, &tmp)) != MP_OKAY) { goto error; } /* tmp = s^2 mod modulus */
|
||||
if ((err = mp_reduce(&tmp, modulus, mu)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_sub(&tmp, &P->x, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - Px */
|
||||
if ((err = mp_sub(&tmp, &Q->x, &tmpx)) != MP_OKAY) { goto error; } /* tmpx = tmp - Qx */
|
||||
|
||||
/* Yr = -Yp + s(Xp - Xr) */
|
||||
if ((err = mp_sub(&P->x, &tmpx, &tmp)) != MP_OKAY) { goto error; } /* tmp = Px - tmpx */
|
||||
if ((err = mp_mul(&tmp, &s, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp * s */
|
||||
if ((err = mp_submod(&tmp, &P->y, modulus, &R->y)) != MP_OKAY) { goto error; } /* Ry = tmp - Py mod modulus */
|
||||
if ((err = mp_mod(&tmpx, modulus, &R->x)) != MP_OKAY) { goto error; } /* Rx = tmpx mod modulus */
|
||||
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
mp_clear_multi(&s, &tmpx, &tmp, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* size of sliding window, don't change this! */
|
||||
#define WINSIZE 4
|
||||
|
||||
/* perform R = kG where k == integer and G == ecc_point */
|
||||
static int ecc_mulmod(mp_int *k, ecc_point *G, ecc_point *R, mp_int *modulus)
|
||||
{
|
||||
ecc_point *tG, *M[8];
|
||||
int i, j, err;
|
||||
mp_int mu;
|
||||
mp_digit buf;
|
||||
int first, bitbuf, bitcpy, bitcnt, mode, digidx;
|
||||
|
||||
/* init barrett reduction */
|
||||
if ((err = mp_init(&mu)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
if ((err = mp_reduce_setup(&mu, modulus)) != MP_OKAY) {
|
||||
mp_clear(&mu);
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
/* alloc ram for window temps */
|
||||
for (i = 0; i < 8; i++) {
|
||||
M[i] = new_point();
|
||||
if (M[i] == NULL) {
|
||||
for (j = 0; j < i; j++) {
|
||||
del_point(M[j]);
|
||||
}
|
||||
mp_clear(&mu);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
/* make a copy of G incase R==G */
|
||||
tG = new_point();
|
||||
if (tG == NULL) { err = CRYPT_MEM; goto done; }
|
||||
|
||||
/* tG = G */
|
||||
if ((err = mp_copy(&G->x, &tG->x)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_copy(&G->y, &tG->y)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* calc the M tab, which holds kG for k==8..15 */
|
||||
/* M[0] == 8G */
|
||||
if ((err = dbl_point(G, M[0], modulus, &mu)) != CRYPT_OK) { goto done; }
|
||||
if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK) { goto done; }
|
||||
if ((err = dbl_point(M[0], M[0], modulus, &mu)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* now find (8+k)G for k=1..7 */
|
||||
for (j = 9; j < 16; j++) {
|
||||
if ((err = add_point(M[j-9], G, M[j-8], modulus, &mu)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
|
||||
/* setup sliding window */
|
||||
mode = 0;
|
||||
bitcnt = 1;
|
||||
buf = 0;
|
||||
digidx = k->used - 1;
|
||||
bitcpy = bitbuf = 0;
|
||||
first = 1;
|
||||
|
||||
/* perform ops */
|
||||
for (;;) {
|
||||
/* grab next digit as required */
|
||||
if (--bitcnt == 0) {
|
||||
if (digidx == -1) {
|
||||
break;
|
||||
}
|
||||
buf = k->dp[digidx--];
|
||||
bitcnt = (int) DIGIT_BIT;
|
||||
}
|
||||
|
||||
/* grab the next msb from the multiplicand */
|
||||
i = (buf >> (DIGIT_BIT - 1)) & 1;
|
||||
buf <<= 1;
|
||||
|
||||
/* skip leading zero bits */
|
||||
if (mode == 0 && i == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if the bit is zero and mode == 1 then we double */
|
||||
if (mode == 1 && i == 0) {
|
||||
if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; }
|
||||
continue;
|
||||
}
|
||||
|
||||
/* else we add it to the window */
|
||||
bitbuf |= (i << (WINSIZE - ++bitcpy));
|
||||
mode = 2;
|
||||
|
||||
if (bitcpy == WINSIZE) {
|
||||
/* if this is the first window we do a simple copy */
|
||||
if (first == 1) {
|
||||
/* R = kG [k = first window] */
|
||||
if ((err = mp_copy(&M[bitbuf-8]->x, &R->x)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_copy(&M[bitbuf-8]->y, &R->y)) != MP_OKAY) { goto error; }
|
||||
first = 0;
|
||||
} else {
|
||||
/* normal window */
|
||||
/* ok window is filled so double as required and add */
|
||||
/* double first */
|
||||
for (j = 0; j < WINSIZE; j++) {
|
||||
if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
|
||||
/* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */
|
||||
if ((err = add_point(R, M[bitbuf-8], R, modulus, &mu)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
/* empty window and reset */
|
||||
bitcpy = bitbuf = 0;
|
||||
mode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if bits remain then double/add */
|
||||
if (mode == 2 && bitcpy > 0) {
|
||||
/* double then add */
|
||||
for (j = 0; j < bitcpy; j++) {
|
||||
/* only double if we have had at least one add first */
|
||||
if (first == 0) {
|
||||
if ((err = dbl_point(R, R, modulus, &mu)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
|
||||
bitbuf <<= 1;
|
||||
if ((bitbuf & (1 << WINSIZE)) != 0) {
|
||||
if (first == 1){
|
||||
/* first add, so copy */
|
||||
if ((err = mp_copy(&tG->x, &R->x)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_copy(&tG->y, &R->y)) != MP_OKAY) { goto error; }
|
||||
first = 0;
|
||||
} else {
|
||||
/* then add */
|
||||
if ((err = add_point(R, tG, R, modulus, &mu)) != CRYPT_OK) { goto done; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
del_point(tG);
|
||||
for (i = 0; i < 8; i++) {
|
||||
del_point(M[i]);
|
||||
}
|
||||
mp_clear(&mu);
|
||||
return err;
|
||||
}
|
||||
|
||||
#undef WINSIZE
|
||||
|
||||
int ecc_test(void)
|
||||
{
|
||||
mp_int modulus, order;
|
||||
ecc_point *G, *GG;
|
||||
int i, err, primality;
|
||||
|
||||
if ((err = mp_init_multi(&modulus, &order, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
G = new_point();
|
||||
GG = new_point();
|
||||
if (G == NULL || GG == NULL) {
|
||||
mp_clear_multi(&modulus, &order, NULL);
|
||||
del_point(G);
|
||||
del_point(GG);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
for (i = 0; sets[i].size; i++) {
|
||||
#if 0
|
||||
printf("Testing %d\n", sets[i].size);
|
||||
#endif
|
||||
if ((err = mp_read_radix(&modulus, (char *)sets[i].prime, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_read_radix(&order, (char *)sets[i].order, 64)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* is prime actually prime? */
|
||||
if ((err = is_prime(&modulus, &primality)) != CRYPT_OK) { goto done; }
|
||||
if (primality == 0) {
|
||||
err = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* is order prime ? */
|
||||
if ((err = is_prime(&order, &primality)) != CRYPT_OK) { goto done; }
|
||||
if (primality == 0) {
|
||||
err = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((err = mp_read_radix(&G->x, (char *)sets[i].Gx, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_read_radix(&G->y, (char *)sets[i].Gy, 64)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* then we should have G == (order + 1)G */
|
||||
if ((err = mp_add_d(&order, 1, &order)) != MP_OKAY) { goto error; }
|
||||
if ((err = ecc_mulmod(&order, G, GG, &modulus)) != CRYPT_OK) { goto done; }
|
||||
if (mp_cmp(&G->x, &GG->x) != 0 || mp_cmp(&G->y, &GG->y) != 0) {
|
||||
err = CRYPT_FAIL_TESTVECTOR;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
del_point(GG);
|
||||
del_point(G);
|
||||
mp_clear_multi(&order, &modulus, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
void ecc_sizes(int *low, int *high)
|
||||
{
|
||||
int i;
|
||||
_ARGCHK(low != NULL);
|
||||
_ARGCHK(high != NULL);
|
||||
|
||||
*low = INT_MAX;
|
||||
*high = 0;
|
||||
for (i = 0; sets[i].size != 0; i++) {
|
||||
if (sets[i].size < *low) {
|
||||
*low = sets[i].size;
|
||||
}
|
||||
if (sets[i].size > *high) {
|
||||
*high = sets[i].size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
|
||||
{
|
||||
int x, err;
|
||||
ecc_point *base;
|
||||
mp_int prime;
|
||||
unsigned char buf[128];
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* good prng? */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find key size */
|
||||
for (x = 0; (keysize > sets[x].size) && (sets[x].size != 0); x++);
|
||||
keysize = sets[x].size;
|
||||
|
||||
if (sets[x].size == 0) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
key->idx = x;
|
||||
|
||||
/* make up random string */
|
||||
if (prng_descriptor[wprng].read(buf, (unsigned long)keysize, prng) != (unsigned long)keysize) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
/* setup the key variables */
|
||||
if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
base = new_point();
|
||||
if (base == NULL) {
|
||||
mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, &prime, NULL);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* read in the specs for this key */
|
||||
if ((err = mp_read_radix(&prime, (char *)sets[key->idx].prime, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_read_radix(&base->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_read_radix(&base->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_read_unsigned_bin(&key->k, (unsigned char *)buf, keysize)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* make the public key */
|
||||
if ((err = ecc_mulmod(&key->k, base, &key->pubkey, &prime)) != CRYPT_OK) { goto done; }
|
||||
key->type = PK_PRIVATE;
|
||||
|
||||
/* shrink key */
|
||||
if ((err = mp_shrink(&key->k)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_shrink(&key->pubkey.x)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_shrink(&key->pubkey.y)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* free up ram */
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
del_point(base);
|
||||
mp_clear(&prime);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
void ecc_free(ecc_key *key)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL);
|
||||
}
|
||||
|
||||
static int compress_y_point(ecc_point *pt, int idx, int *result)
|
||||
{
|
||||
mp_int tmp, tmp2, p;
|
||||
int err;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
_ARGCHK(result != NULL);
|
||||
|
||||
if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
/* get x^3 - 3x + b */
|
||||
if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */
|
||||
if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY) { goto error; } /* tmp = pX^3 */
|
||||
if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */
|
||||
if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */
|
||||
if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp + p */
|
||||
if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY) { goto error; } /* p = prime */
|
||||
if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp mod p */
|
||||
|
||||
/* now find square root */
|
||||
if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */
|
||||
if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */
|
||||
if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */
|
||||
|
||||
/* if tmp equals the y point give a 0, otherwise 1 */
|
||||
if (mp_cmp(&tmp, &pt->y) == 0) {
|
||||
*result = 0;
|
||||
} else {
|
||||
*result = 1;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
mp_clear_multi(&p, &tmp, &tmp2, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int expand_y_point(ecc_point *pt, int idx, int result)
|
||||
{
|
||||
mp_int tmp, tmp2, p;
|
||||
int err;
|
||||
|
||||
_ARGCHK(pt != NULL);
|
||||
|
||||
if ((err = mp_init_multi(&tmp, &tmp2, &p, NULL)) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* get x^3 - 3x + b */
|
||||
if ((err = mp_read_radix(&p, (char *)sets[idx].B, 64)) != MP_OKAY) { goto error; } /* p = B */
|
||||
if ((err = mp_expt_d(&pt->x, 3, &tmp)) != MP_OKAY) { goto error; } /* tmp = pX^3 */
|
||||
if ((err = mp_mul_d(&pt->x, 3, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = 3*pX^3 */
|
||||
if ((err = mp_sub(&tmp, &tmp2, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp - tmp2 */
|
||||
if ((err = mp_add(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp + p */
|
||||
if ((err = mp_read_radix(&p, (char *)sets[idx].prime, 64)) != MP_OKAY) { goto error; } /* p = prime */
|
||||
if ((err = mp_mod(&tmp, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = tmp mod p */
|
||||
|
||||
/* now find square root */
|
||||
if ((err = mp_add_d(&p, 1, &tmp2)) != MP_OKAY) { goto error; } /* tmp2 = p + 1 */
|
||||
if ((err = mp_div_2d(&tmp2, 2, &tmp2, NULL)) != MP_OKAY) { goto error; } /* tmp2 = (p+1)/4 */
|
||||
if ((err = mp_exptmod(&tmp, &tmp2, &p, &tmp)) != MP_OKAY) { goto error; } /* tmp = (x^3 - 3x + b)^((p+1)/4) mod p */
|
||||
|
||||
/* if result==0, then y==tmp, otherwise y==p-tmp */
|
||||
if (result == 0) {
|
||||
if ((err = mp_copy(&tmp, &pt->y) != MP_OKAY)) { goto error; }
|
||||
} else {
|
||||
if ((err = mp_sub(&p, &tmp, &pt->y) != MP_OKAY)) { goto error; }
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
mp_clear_multi(&p, &tmp, &tmp2, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
|
||||
{
|
||||
unsigned long y, z;
|
||||
int cp, err;
|
||||
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* can we store the static header? */
|
||||
if (*outlen < (PACKET_SIZE + 3)) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* type valid? */
|
||||
if (key->type != PK_PRIVATE && type == PK_PRIVATE) {
|
||||
return CRYPT_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
/* output type and magic byte */
|
||||
y = PACKET_SIZE;
|
||||
out[y++] = (unsigned char)type;
|
||||
out[y++] = (unsigned char)sets[key->idx].size;
|
||||
|
||||
/* output x coordinate */
|
||||
OUTPUT_BIGNUM(&(key->pubkey.x), out, y, z);
|
||||
|
||||
/* compress y and output it */
|
||||
if ((err = compress_y_point(&key->pubkey, key->idx, &cp)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
out[y++] = (unsigned char)cp;
|
||||
|
||||
if (type == PK_PRIVATE) {
|
||||
OUTPUT_BIGNUM(&key->k, out, y, z);
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_KEY);
|
||||
*outlen = y;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key)
|
||||
{
|
||||
unsigned long x, y, s;
|
||||
int err;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check length */
|
||||
if ((3+PACKET_SIZE) > inlen) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* check type */
|
||||
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_KEY)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* init key */
|
||||
if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL) != MP_OKAY) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
y = PACKET_SIZE;
|
||||
key->type = (int)in[y++];
|
||||
s = (unsigned long)in[y++];
|
||||
|
||||
for (x = 0; (s > (unsigned long)sets[x].size) && (sets[x].size != 0); x++);
|
||||
if (sets[x].size == 0) {
|
||||
err = CRYPT_INVALID_KEYSIZE;
|
||||
goto error;
|
||||
}
|
||||
key->idx = (int)x;
|
||||
|
||||
/* type check both values */
|
||||
if ((key->type != PK_PUBLIC) && (key->type != PK_PRIVATE)) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* is the key idx valid? */
|
||||
if (is_valid_idx(key->idx) != 1) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* load x coordinate */
|
||||
INPUT_BIGNUM(&key->pubkey.x, in, x, y, inlen);
|
||||
|
||||
/* load y */
|
||||
x = (unsigned long)in[y++];
|
||||
if ((err = expand_y_point(&key->pubkey, key->idx, (int)x)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (key->type == PK_PRIVATE) {
|
||||
/* load private key */
|
||||
INPUT_BIGNUM(&key->k, in, x, y, inlen);
|
||||
}
|
||||
|
||||
/* eliminate private key if public */
|
||||
if (key->type == PK_PUBLIC) {
|
||||
mp_clear(&key->k);
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
error:
|
||||
mp_clear_multi(&key->pubkey.x, &key->pubkey.y, &key->k, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x, y;
|
||||
ecc_point *result;
|
||||
mp_int prime;
|
||||
int err;
|
||||
|
||||
_ARGCHK(private_key != NULL);
|
||||
_ARGCHK(public_key != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
/* type valid? */
|
||||
if (private_key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
if (private_key->idx != public_key->idx) {
|
||||
return CRYPT_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
/* make new point */
|
||||
result = new_point();
|
||||
if (result == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = mp_init(&prime)) != MP_OKAY) {
|
||||
del_point(result);
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
if ((err = mp_read_radix(&prime, (char *)sets[private_key->idx].prime, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = ecc_mulmod(&private_key->k, &public_key->pubkey, result, &prime)) != CRYPT_OK) { goto done1; }
|
||||
|
||||
x = (unsigned long)mp_unsigned_bin_size(&result->x);
|
||||
y = (unsigned long)mp_unsigned_bin_size(&result->y);
|
||||
|
||||
if (*outlen < (x+y)) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done1;
|
||||
}
|
||||
*outlen = x+y;
|
||||
if ((err = mp_to_unsigned_bin(&result->x, out)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_to_unsigned_bin(&result->y, out+x)) != MP_OKAY) { goto error; }
|
||||
|
||||
err = CRYPT_OK;
|
||||
goto done1;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done1:
|
||||
mp_clear(&prime);
|
||||
del_point(result);
|
||||
return err;
|
||||
}
|
||||
|
||||
int ecc_get_size(ecc_key *key)
|
||||
{
|
||||
_ARGCHK(key != NULL);
|
||||
if (is_valid_idx(key->idx))
|
||||
return sets[key->idx].size;
|
||||
else
|
||||
return INT_MAX; /* large value known to cause it to fail when passed to ecc_make_key() */
|
||||
}
|
||||
|
||||
#include "ecc_sys.c"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
432
ecc_sys.c
Normal file
432
ecc_sys.c
Normal file
@@ -0,0 +1,432 @@
|
||||
/* 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
|
||||
*/
|
||||
int ecc_encrypt_key(const unsigned char *inkey, unsigned long keylen,
|
||||
unsigned char *out, unsigned long *len,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
ecc_key *key)
|
||||
{
|
||||
unsigned char pub_expt[256], ecc_shared[256], skey[MAXBLOCKSIZE];
|
||||
ecc_key pubkey;
|
||||
unsigned long x, y, z, hashsize, pubkeysize;
|
||||
int err;
|
||||
|
||||
_ARGCHK(inkey != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(len != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* check that wprng/cipher/hash are not invalid */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (keylen > hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* make a random key and export the public copy */
|
||||
if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pubkeysize = (unsigned long)sizeof(pub_expt);
|
||||
if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* now check if the out buffer is big enough */
|
||||
if (*len < (9 + PACKET_SIZE + pubkeysize + hash_descriptor[hash].hashsize)) {
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* make random key */
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
x = (unsigned long)sizeof(ecc_shared);
|
||||
if ((err = ecc_shared_secret(&pubkey, key, ecc_shared, &x)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return err;
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
z = (unsigned long)sizeof(skey);
|
||||
if ((err = hash_memory(hash, ecc_shared, x, skey, &z)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY);
|
||||
|
||||
/* output header */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* size of hash name and the name itself */
|
||||
out[y++] = hash_descriptor[hash].ID;
|
||||
|
||||
/* length of ECC pubkey and the key itself */
|
||||
STORE32L(pubkeysize, out+y);
|
||||
y += 4;
|
||||
|
||||
for (x = 0; x < pubkeysize; x++, y++) {
|
||||
out[y] = pub_expt[x];
|
||||
}
|
||||
|
||||
STORE32L(keylen, out+y);
|
||||
y += 4;
|
||||
|
||||
/* Encrypt/Store the encrypted key */
|
||||
for (x = 0; x < keylen; x++, y++) {
|
||||
out[y] = skey[x] ^ inkey[x];
|
||||
}
|
||||
*len = y;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(pub_expt, sizeof(pub_expt));
|
||||
zeromem(ecc_shared, sizeof(ecc_shared));
|
||||
zeromem(skey, sizeof(skey));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int ecc_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *outkey, unsigned long *keylen,
|
||||
ecc_key *key)
|
||||
{
|
||||
unsigned char shared_secret[256], skey[MAXBLOCKSIZE];
|
||||
unsigned long x, y, z, hashsize, keysize;
|
||||
int hash, err;
|
||||
ecc_key pubkey;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(outkey != NULL);
|
||||
_ARGCHK(keylen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* correct length ? */
|
||||
if (inlen < PACKET_SIZE+1+4+4) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
inlen -= PACKET_SIZE+1+4+4;
|
||||
}
|
||||
|
||||
/* is header correct? */
|
||||
if ((err = packet_valid_header((unsigned char *)in, PACKET_SECT_ECC, PACKET_SUB_ENC_KEY)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* now lets get the hash name */
|
||||
y = PACKET_SIZE;
|
||||
hash = find_hash_id(in[y++]);
|
||||
if (hash == -1) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* common values */
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
|
||||
/* get public key */
|
||||
LOAD32L(x, in+y);
|
||||
if (inlen < x) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
inlen -= x;
|
||||
}
|
||||
y += 4;
|
||||
if ((err = ecc_import(in+y, x, &pubkey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
y += x;
|
||||
|
||||
/* make shared key */
|
||||
x = (unsigned long)sizeof(shared_secret);
|
||||
if ((err = ecc_shared_secret(key, &pubkey, shared_secret, &x)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return err;
|
||||
}
|
||||
ecc_free(&pubkey);
|
||||
|
||||
z = (unsigned long)sizeof(skey);
|
||||
if ((err = hash_memory(hash, shared_secret, x, skey, &z)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
LOAD32L(keysize, in+y);
|
||||
if (inlen < keysize) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
inlen -= keysize;
|
||||
}
|
||||
y += 4;
|
||||
|
||||
if (*keylen < keysize) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Decrypt the key */
|
||||
for (x = 0; x < keysize; x++, y++) {
|
||||
outkey[x] = skey[x] ^ in[y];
|
||||
}
|
||||
|
||||
*keylen = keysize;
|
||||
|
||||
err = CRYPT_OK;
|
||||
done:
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(shared_secret, sizeof(shared_secret));
|
||||
zeromem(skey, sizeof(skey));
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
int ecc_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, ecc_key *key)
|
||||
{
|
||||
ecc_key pubkey;
|
||||
mp_int b, p;
|
||||
unsigned char epubkey[256], er[256];
|
||||
unsigned long x, y, pubkeysize, rsize;
|
||||
int err;
|
||||
|
||||
_ARGCHK(in != NULL);
|
||||
_ARGCHK(out != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* is this a private key? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* is the IDX valid ? */
|
||||
if (is_valid_idx(key->idx) != 1) {
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* make up a key and export the public copy */
|
||||
if ((err = ecc_make_key(prng, wprng, ecc_get_size(key), &pubkey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
pubkeysize = (unsigned long)sizeof(epubkey);
|
||||
if ((err = ecc_export(epubkey, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
|
||||
ecc_free(&pubkey);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* get the hash and load it as a bignum into 'b' */
|
||||
/* init the bignums */
|
||||
if ((err = mp_init_multi(&b, &p, NULL)) != MP_OKAY) {
|
||||
ecc_free(&pubkey);
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
if ((err = mp_read_radix(&p, (char *)sets[key->idx].order, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_read_unsigned_bin(&b, (unsigned char *)in, (int)inlen)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* find b = (m - x)/k */
|
||||
if ((err = mp_invmod(&pubkey.k, &p, &pubkey.k)) != MP_OKAY) { goto error; } /* k = 1/k */
|
||||
if ((err = mp_submod(&b, &key->k, &p, &b)) != MP_OKAY) { goto error; } /* b = m - x */
|
||||
if ((err = mp_mulmod(&b, &pubkey.k, &p, &b)) != MP_OKAY) { goto error; } /* b = (m - x)/k */
|
||||
|
||||
/* export it */
|
||||
rsize = (unsigned long)mp_unsigned_bin_size(&b);
|
||||
if (rsize > (unsigned long)sizeof(er)) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto error;
|
||||
}
|
||||
if ((err = mp_to_unsigned_bin(&b, er)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* now lets check the outlen before we write */
|
||||
if (*outlen < (12 + rsize + pubkeysize)) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* lets output */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* size of public key */
|
||||
STORE32L(pubkeysize, out+y);
|
||||
y += 4;
|
||||
|
||||
/* copy the public key */
|
||||
for (x = 0; x < pubkeysize; x++, y++) {
|
||||
out[y] = epubkey[x];
|
||||
}
|
||||
|
||||
/* size of 'r' */
|
||||
STORE32L(rsize, out+y);
|
||||
y += 4;
|
||||
|
||||
/* copy r */
|
||||
for (x = 0; x < rsize; x++, y++) {
|
||||
out[y] = er[x];
|
||||
}
|
||||
|
||||
/* store header */
|
||||
packet_store_header(out, PACKET_SECT_ECC, PACKET_SUB_SIGNED);
|
||||
|
||||
/* clear memory */
|
||||
*outlen = y;
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
mp_clear_multi(&b, &p, NULL);
|
||||
ecc_free(&pubkey);
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(er, sizeof(er));
|
||||
zeromem(epubkey, sizeof(epubkey));
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
/* verify that mG = (bA + Y)
|
||||
*
|
||||
* The signatures work by making up a fresh key "a" with a public key "A". Now we want to sign so the
|
||||
* public key Y = xG can verify it.
|
||||
*
|
||||
* b = (m - x)/k, A is the public key embedded and Y is the users public key [who signed it]
|
||||
* A = kG therefore bA == ((m-x)/k)kG == (m-x)G
|
||||
*
|
||||
* Adding Y = xG to the bA gives us (m-x)G + xG == mG
|
||||
*
|
||||
* The user given only xG, kG and b cannot determine k or x which means they can't find the private key.
|
||||
*
|
||||
*/
|
||||
int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long inlen,
|
||||
int *stat, ecc_key *key)
|
||||
{
|
||||
ecc_point *mG;
|
||||
ecc_key pubkey;
|
||||
mp_int b, p, m, mu;
|
||||
unsigned long x, y;
|
||||
int err;
|
||||
|
||||
_ARGCHK(sig != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
_ARGCHK(stat != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
/* default to invalid signature */
|
||||
*stat = 0;
|
||||
|
||||
if (siglen < PACKET_SIZE+4+4) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= PACKET_SIZE+4+4;
|
||||
}
|
||||
|
||||
/* is the message format correct? */
|
||||
if ((err = packet_valid_header((unsigned char *)sig, PACKET_SECT_ECC, PACKET_SUB_SIGNED)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* get hash name */
|
||||
y = PACKET_SIZE;
|
||||
|
||||
/* get size of public key */
|
||||
LOAD32L(x, sig+y);
|
||||
if (siglen < x) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= x;
|
||||
}
|
||||
y += 4;
|
||||
|
||||
/* load the public key */
|
||||
if ((err = ecc_import((unsigned char*)sig+y, x, &pubkey)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
y += x;
|
||||
|
||||
/* load size of 'b' */
|
||||
LOAD32L(x, sig+y);
|
||||
if (siglen < x) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
siglen -= x;
|
||||
}
|
||||
y += 4;
|
||||
|
||||
/* init values */
|
||||
if ((err = mp_init_multi(&b, &m, &p, &mu, NULL)) != MP_OKAY) {
|
||||
ecc_free(&pubkey);
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
|
||||
mG = new_point();
|
||||
if (mG == NULL) {
|
||||
mp_clear_multi(&b, &m, &p, &mu, NULL);
|
||||
ecc_free(&pubkey);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* load b */
|
||||
if ((err = mp_read_unsigned_bin(&b, (unsigned char *)sig+y, (int)x)) != MP_OKAY) { goto error; }
|
||||
y += x;
|
||||
|
||||
/* get m in binary a bignum */
|
||||
if ((err = mp_read_unsigned_bin(&m, (unsigned char *)hash, (int)inlen)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* load prime */
|
||||
if ((err = mp_read_radix(&p, (char *)sets[key->idx].prime, 64)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* calculate barrett stuff */
|
||||
mp_set(&mu, 1);
|
||||
mp_lshd(&mu, 2 * USED(&p));
|
||||
if ((err = mp_div(&mu, &p, &mu, NULL)) != MP_OKAY) { goto error; }
|
||||
|
||||
/* get bA */
|
||||
if ((err = ecc_mulmod(&b, &pubkey.pubkey, &pubkey.pubkey, &p)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* get bA + Y */
|
||||
if ((err = add_point(&pubkey.pubkey, &key->pubkey, &pubkey.pubkey, &p, &mu)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* get mG */
|
||||
if ((err = mp_read_radix(&mG->x, (char *)sets[key->idx].Gx, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = mp_read_radix(&mG->y, (char *)sets[key->idx].Gy, 64)) != MP_OKAY) { goto error; }
|
||||
if ((err = ecc_mulmod(&m, mG, mG, &p)) != CRYPT_OK) { goto done; }
|
||||
|
||||
/* compare mG to bA + Y */
|
||||
if (mp_cmp(&mG->x, &pubkey.pubkey.x) == MP_EQ && mp_cmp(&mG->y, &pubkey.pubkey.y) == MP_EQ) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
/* clear up and return */
|
||||
err = CRYPT_OK;
|
||||
goto done;
|
||||
error:
|
||||
err = mpi_to_ltc_error(err);
|
||||
done:
|
||||
del_point(mG);
|
||||
ecc_free(&pubkey);
|
||||
mp_clear_multi(&p, &m, &b, &mu, NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
18
examples/ch1-01.c
Normal file
18
examples/ch1-01.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Name : ch1-01.c
|
||||
* Purpose : Demonstration of a basic libtomcrypt program
|
||||
* Author : Tom St Denis
|
||||
*
|
||||
* History : v0.79 Initial release
|
||||
*/
|
||||
|
||||
/* ch1-01-1 */
|
||||
/* Include the default headers and libtomcrypt headers */
|
||||
#include <mycrypt.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/* ch1-01-1 */
|
||||
|
||||
25
examples/ch1-02.c
Normal file
25
examples/ch1-02.c
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Name : ch1-02.c
|
||||
* Purpose : Demonstration of error handling
|
||||
* Author : Tom St Denis
|
||||
*
|
||||
* History : v0.79 Initial release
|
||||
*/
|
||||
|
||||
/* ch1-01-1 */
|
||||
#include <mycrypt.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int errno;
|
||||
|
||||
if ((errno = some_func(...)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*ch1-01-1 */
|
||||
|
||||
|
||||
29
examples/ch1-03.c
Normal file
29
examples/ch1-03.c
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Name : ch1-03.c
|
||||
* Purpose : Demonstration of variable length outputs
|
||||
* Author : Tom St Denis
|
||||
*
|
||||
* History : v0.79 Initial release
|
||||
*/
|
||||
|
||||
/* ch1-01-1 */
|
||||
#include <mycrypt.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned long length;
|
||||
unsigned char buffer[512];
|
||||
int errno;
|
||||
|
||||
length = sizeof(buffer);
|
||||
if ((errno = some_func(..., buffer, &length)) != CRYPT_OK) {
|
||||
printf("Error: %s\n", error_to_string(errno));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("Size of output is %lu bytes\n", length);
|
||||
return 0;
|
||||
}
|
||||
/* ch1-01-1 */
|
||||
|
||||
|
||||
|
||||
35
examples/ch2-01.c
Normal file
35
examples/ch2-01.c
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Name : ch2-01.c
|
||||
* Purpose : Demonstration of reading the RNG
|
||||
* Author : Tom St Denis
|
||||
*
|
||||
* History : v0.81 Initial release
|
||||
*/
|
||||
|
||||
/* ch2-02-2 */
|
||||
#include <mycrypt.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
unsigned long len;
|
||||
int ix;
|
||||
|
||||
/* read the RNG */
|
||||
len = rng_get_bytes(buf, sizeof(buf), NULL);
|
||||
|
||||
/* verify return */
|
||||
if (len != sizeof(buf)) {
|
||||
printf("Error: Only read %lu bytes.\n", len);
|
||||
} else {
|
||||
printf("Read %lu bytes\n", len);
|
||||
for (ix = 0; ix < sizeof(buf); ix++) {
|
||||
printf("%02x ", buf[ix]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
/* ch2-02-2 */
|
||||
|
||||
305
gf.c
Normal file
305
gf.c
Normal file
@@ -0,0 +1,305 @@
|
||||
/* 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
|
||||
|
||||
|
||||
41
hash_file.c
Normal file
41
hash_file.c
Normal file
@@ -0,0 +1,41 @@
|
||||
/* 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"
|
||||
|
||||
int hash_file(int hash, const char *fname, unsigned char *dst, unsigned long *outlen)
|
||||
{
|
||||
#ifdef NO_FILE
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
FILE *in;
|
||||
int err;
|
||||
_ARGCHK(fname != NULL);
|
||||
_ARGCHK(dst != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
in = fopen(fname, "rb");
|
||||
if (in == NULL) {
|
||||
return CRYPT_FILE_NOTFOUND;
|
||||
}
|
||||
|
||||
err = hash_filehandle(hash, in, dst, outlen);
|
||||
if (fclose(in) != 0) {
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
return err;
|
||||
#endif
|
||||
}
|
||||
|
||||
49
hash_filehandle.c
Normal file
49
hash_filehandle.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* 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"
|
||||
|
||||
int hash_filehandle(int hash, FILE *in, unsigned char *dst, unsigned long *outlen)
|
||||
{
|
||||
#ifdef NO_FILE
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
hash_state md;
|
||||
unsigned char buf[512];
|
||||
size_t x;
|
||||
int err;
|
||||
|
||||
_ARGCHK(dst != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
_ARGCHK(in != NULL);
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (*outlen < hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
*outlen = hash_descriptor[hash].hashsize;
|
||||
|
||||
hash_descriptor[hash].init(&md);
|
||||
do {
|
||||
x = fread(buf, 1, sizeof(buf), in);
|
||||
hash_descriptor[hash].process(&md, buf, x);
|
||||
} while (x == sizeof(buf));
|
||||
hash_descriptor[hash].done(&md, dst);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
35
hash_memory.c
Normal file
35
hash_memory.c
Normal file
@@ -0,0 +1,35 @@
|
||||
/* 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"
|
||||
|
||||
int hash_memory(int hash, const unsigned char *data, unsigned long len, unsigned char *dst, unsigned long *outlen)
|
||||
{
|
||||
hash_state md;
|
||||
int err;
|
||||
|
||||
_ARGCHK(data != NULL);
|
||||
_ARGCHK(dst != NULL);
|
||||
_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (*outlen < hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
*outlen = hash_descriptor[hash].hashsize;
|
||||
|
||||
hash_descriptor[hash].init(&md);
|
||||
hash_descriptor[hash].process(&md, data, len);
|
||||
hash_descriptor[hash].done(&md, dst);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
84
hmac_done.c
Normal file
84
hmac_done.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/* 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
|
||||
*/
|
||||
/* Submited by Dobes Vandermeer (dobes@smartt.com) */
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
/*
|
||||
(1) append zeros to the end of K to create a B byte string
|
||||
(e.g., if K is of length 20 bytes and B=64, then K will be
|
||||
appended with 44 zero bytes 0x00)
|
||||
(2) XOR (bitwise exclusive-OR) the B byte string computed in step
|
||||
(1) with ipad (ipad = the byte 0x36 repeated B times)
|
||||
(3) append the stream of data 'text' to the B byte string resulting
|
||||
from step (2)
|
||||
(4) apply H to the stream generated in step (3)
|
||||
(5) XOR (bitwise exclusive-OR) the B byte string computed in
|
||||
step (1) with opad (opad = the byte 0x5C repeated B times.)
|
||||
(6) append the H result from step (4) to the B byte string
|
||||
resulting from step (5)
|
||||
(7) apply H to the stream generated in step (6) and output
|
||||
the result
|
||||
*/
|
||||
|
||||
#ifdef HMAC
|
||||
|
||||
#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
|
||||
|
||||
int hmac_done(hmac_state *hmac, unsigned char *hashOut, unsigned long *outlen)
|
||||
{
|
||||
unsigned char buf[MAXBLOCKSIZE];
|
||||
unsigned char isha[MAXBLOCKSIZE];
|
||||
unsigned long hashsize, i;
|
||||
int hash, err;
|
||||
|
||||
_ARGCHK(hmac != NULL);
|
||||
_ARGCHK(hashOut != NULL);
|
||||
|
||||
hash = hmac->hash;
|
||||
if((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* get the hash message digest size */
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
|
||||
// Get the hash of the first HMAC vector plus the data
|
||||
if ((err = hash_descriptor[hash].done(&hmac->md, isha)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// Create the second HMAC vector vector for step (3)
|
||||
for(i=0; i < HMAC_BLOCKSIZE; i++) {
|
||||
buf[i] = hmac->key[i] ^ 0x5C;
|
||||
}
|
||||
|
||||
// Now calculate the "outer" hash for step (5), (6), and (7)
|
||||
hash_descriptor[hash].init(&hmac->md);
|
||||
hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE);
|
||||
hash_descriptor[hash].process(&hmac->md, isha, hashsize);
|
||||
hash_descriptor[hash].done(&hmac->md, buf);
|
||||
|
||||
// copy to output
|
||||
for (i = 0; i < hashsize && i < *outlen; i++) {
|
||||
hashOut[i] = buf[i];
|
||||
}
|
||||
*outlen = i;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(isha, sizeof(buf));
|
||||
zeromem(buf, sizeof(isha));
|
||||
zeromem(hmac, sizeof(*hmac));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
96
hmac_file.c
Normal file
96
hmac_file.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/* 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
|
||||
*/
|
||||
/* Submited by Dobes Vandermeer (dobes@smartt.com) */
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
/*
|
||||
(1) append zeros to the end of K to create a B byte string
|
||||
(e.g., if K is of length 20 bytes and B=64, then K will be
|
||||
appended with 44 zero bytes 0x00)
|
||||
(2) XOR (bitwise exclusive-OR) the B byte string computed in step
|
||||
(1) with ipad (ipad = the byte 0x36 repeated B times)
|
||||
(3) append the stream of data 'text' to the B byte string resulting
|
||||
from step (2)
|
||||
(4) apply H to the stream generated in step (3)
|
||||
(5) XOR (bitwise exclusive-OR) the B byte string computed in
|
||||
step (1) with opad (opad = the byte 0x5C repeated B times.)
|
||||
(6) append the H result from step (4) to the B byte string
|
||||
resulting from step (5)
|
||||
(7) apply H to the stream generated in step (6) and output
|
||||
the result
|
||||
*/
|
||||
|
||||
#ifdef HMAC
|
||||
|
||||
#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
|
||||
|
||||
/* hmac_file added by Tom St Denis */
|
||||
int hmac_file(int hash, const char *fname,
|
||||
const unsigned char *key, unsigned long keylen,
|
||||
unsigned char *dst, unsigned long *dstlen)
|
||||
{
|
||||
#ifdef NO_FILE
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
hmac_state hmac;
|
||||
FILE *in;
|
||||
unsigned char buf[512];
|
||||
size_t x;
|
||||
int err;
|
||||
|
||||
_ARGCHK(fname != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(dst != NULL);
|
||||
_ARGCHK(dstlen != NULL);
|
||||
|
||||
if((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
in = fopen(fname, "rb");
|
||||
if (in == NULL) {
|
||||
return CRYPT_FILE_NOTFOUND;
|
||||
}
|
||||
|
||||
/* process the file contents */
|
||||
do {
|
||||
x = fread(buf, 1, sizeof(buf), in);
|
||||
if ((err = hmac_process(&hmac, buf, (unsigned long)x)) != CRYPT_OK) {
|
||||
/* we don't trap this error since we're already returning an error! */
|
||||
fclose(in);
|
||||
return err;
|
||||
}
|
||||
} while (x == sizeof(buf));
|
||||
|
||||
if (fclose(in) != 0) {
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
/* get final hmac */
|
||||
if ((err = hmac_done(&hmac, dst, dstlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
/* clear memory */
|
||||
zeromem(buf, sizeof(buf));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
87
hmac_init.c
Normal file
87
hmac_init.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/* 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
|
||||
*/
|
||||
/* Submited by Dobes Vandermeer (dobes@smartt.com) */
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
/*
|
||||
(1) append zeros to the end of K to create a B byte string
|
||||
(e.g., if K is of length 20 bytes and B=64, then K will be
|
||||
appended with 44 zero bytes 0x00)
|
||||
(2) XOR (bitwise exclusive-OR) the B byte string computed in step
|
||||
(1) with ipad (ipad = the byte 0x36 repeated B times)
|
||||
(3) append the stream of data 'text' to the B byte string resulting
|
||||
from step (2)
|
||||
(4) apply H to the stream generated in step (3)
|
||||
(5) XOR (bitwise exclusive-OR) the B byte string computed in
|
||||
step (1) with opad (opad = the byte 0x5C repeated B times.)
|
||||
(6) append the H result from step (4) to the B byte string
|
||||
resulting from step (5)
|
||||
(7) apply H to the stream generated in step (6) and output
|
||||
the result
|
||||
*/
|
||||
|
||||
#ifdef HMAC
|
||||
|
||||
#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
|
||||
|
||||
int hmac_init(hmac_state *hmac, int hash, const unsigned char *key, unsigned long keylen)
|
||||
{
|
||||
unsigned char buf[MAXBLOCKSIZE];
|
||||
unsigned long hashsize;
|
||||
unsigned long i, z;
|
||||
int err;
|
||||
|
||||
_ARGCHK(hmac != NULL);
|
||||
_ARGCHK(key != NULL);
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* valid key length? */
|
||||
if (keylen == 0) {
|
||||
return CRYPT_INVALID_KEYSIZE;
|
||||
}
|
||||
|
||||
hmac->hash = hash;
|
||||
|
||||
// (1) make sure we have a large enough key
|
||||
hashsize = hash_descriptor[hash].hashsize;
|
||||
if(keylen > HMAC_BLOCKSIZE) {
|
||||
z = (unsigned long)sizeof(hmac->key);
|
||||
if ((err = hash_memory(hash, key, keylen, hmac->key, &z)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if(hashsize < HMAC_BLOCKSIZE) {
|
||||
zeromem((hmac->key) + hashsize, (size_t)(HMAC_BLOCKSIZE - hashsize));
|
||||
}
|
||||
keylen = hashsize;
|
||||
} else {
|
||||
memcpy(hmac->key, key, (size_t)keylen);
|
||||
if(keylen < HMAC_BLOCKSIZE) {
|
||||
zeromem((hmac->key) + keylen, (size_t)(HMAC_BLOCKSIZE - keylen));
|
||||
}
|
||||
}
|
||||
|
||||
// Create the initial vector for step (3)
|
||||
for(i=0; i < HMAC_BLOCKSIZE; i++) {
|
||||
buf[i] = hmac->key[i] ^ 0x36;
|
||||
}
|
||||
|
||||
// Pre-pend that to the hash data
|
||||
hash_descriptor[hash].init(&hmac->md);
|
||||
hash_descriptor[hash].process(&hmac->md, buf, HMAC_BLOCKSIZE);
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
67
hmac_memory.c
Normal file
67
hmac_memory.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/* 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
|
||||
*/
|
||||
/* Submited by Dobes Vandermeer (dobes@smartt.com) */
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
/*
|
||||
(1) append zeros to the end of K to create a B byte string
|
||||
(e.g., if K is of length 20 bytes and B=64, then K will be
|
||||
appended with 44 zero bytes 0x00)
|
||||
(2) XOR (bitwise exclusive-OR) the B byte string computed in step
|
||||
(1) with ipad (ipad = the byte 0x36 repeated B times)
|
||||
(3) append the stream of data 'text' to the B byte string resulting
|
||||
from step (2)
|
||||
(4) apply H to the stream generated in step (3)
|
||||
(5) XOR (bitwise exclusive-OR) the B byte string computed in
|
||||
step (1) with opad (opad = the byte 0x5C repeated B times.)
|
||||
(6) append the H result from step (4) to the B byte string
|
||||
resulting from step (5)
|
||||
(7) apply H to the stream generated in step (6) and output
|
||||
the result
|
||||
*/
|
||||
|
||||
#ifdef HMAC
|
||||
|
||||
#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
|
||||
|
||||
int hmac_memory(int hash, const unsigned char *key, unsigned long keylen,
|
||||
const unsigned char *data, unsigned long len,
|
||||
unsigned char *dst, unsigned long *dstlen)
|
||||
{
|
||||
hmac_state hmac;
|
||||
int err;
|
||||
|
||||
_ARGCHK(key != NULL);
|
||||
_ARGCHK(data != NULL);
|
||||
_ARGCHK(dst != NULL);
|
||||
_ARGCHK(dstlen != NULL);
|
||||
|
||||
if((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = hmac_init(&hmac, hash, key, keylen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = hmac_process(&hmac, data, len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = hmac_done(&hmac, dst, dstlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
48
hmac_process.c
Normal file
48
hmac_process.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/* 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
|
||||
*/
|
||||
/* Submited by Dobes Vandermeer (dobes@smartt.com) */
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
/*
|
||||
(1) append zeros to the end of K to create a B byte string
|
||||
(e.g., if K is of length 20 bytes and B=64, then K will be
|
||||
appended with 44 zero bytes 0x00)
|
||||
(2) XOR (bitwise exclusive-OR) the B byte string computed in step
|
||||
(1) with ipad (ipad = the byte 0x36 repeated B times)
|
||||
(3) append the stream of data 'text' to the B byte string resulting
|
||||
from step (2)
|
||||
(4) apply H to the stream generated in step (3)
|
||||
(5) XOR (bitwise exclusive-OR) the B byte string computed in
|
||||
step (1) with opad (opad = the byte 0x5C repeated B times.)
|
||||
(6) append the H result from step (4) to the B byte string
|
||||
resulting from step (5)
|
||||
(7) apply H to the stream generated in step (6) and output
|
||||
the result
|
||||
*/
|
||||
|
||||
#ifdef HMAC
|
||||
|
||||
#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
|
||||
|
||||
int hmac_process(hmac_state *hmac, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
int err;
|
||||
_ARGCHK(hmac != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
if ((err = hash_is_valid(hmac->hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
return hash_descriptor[hmac->hash].process(&hmac->md, buf, len);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
325
hmac_test.c
Normal file
325
hmac_test.c
Normal file
@@ -0,0 +1,325 @@
|
||||
/* 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
|
||||
*/
|
||||
/* Submited by Dobes Vandermeer (dobes@smartt.com) */
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
/*
|
||||
(1) append zeros to the end of K to create a B byte string
|
||||
(e.g., if K is of length 20 bytes and B=64, then K will be
|
||||
appended with 44 zero bytes 0x00)
|
||||
(2) XOR (bitwise exclusive-OR) the B byte string computed in step
|
||||
(1) with ipad (ipad = the byte 0x36 repeated B times)
|
||||
(3) append the stream of data 'text' to the B byte string resulting
|
||||
from step (2)
|
||||
(4) apply H to the stream generated in step (3)
|
||||
(5) XOR (bitwise exclusive-OR) the B byte string computed in
|
||||
step (1) with opad (opad = the byte 0x5C repeated B times.)
|
||||
(6) append the H result from step (4) to the B byte string
|
||||
resulting from step (5)
|
||||
(7) apply H to the stream generated in step (6) and output
|
||||
the result
|
||||
*/
|
||||
|
||||
#ifdef HMAC
|
||||
|
||||
#define HMAC_BLOCKSIZE hash_descriptor[hash].blocksize
|
||||
|
||||
/*
|
||||
|
||||
TEST CASES SOURCE:
|
||||
|
||||
Network Working Group P. Cheng
|
||||
Request for Comments: 2202 IBM
|
||||
Category: Informational R. Glenn
|
||||
NIST
|
||||
September 1997
|
||||
|
||||
Test Cases for HMAC-MD5 and HMAC-SHA-1
|
||||
*/
|
||||
|
||||
|
||||
int hmac_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
unsigned char digest[MAXBLOCKSIZE];
|
||||
int i;
|
||||
|
||||
static const struct hmac_test_case {
|
||||
int num;
|
||||
char *algo;
|
||||
unsigned char key[128];
|
||||
unsigned long keylen;
|
||||
unsigned char data[128];
|
||||
unsigned long datalen;
|
||||
unsigned char digest[MAXBLOCKSIZE];
|
||||
} cases[] = {
|
||||
/*
|
||||
3. Test Cases for HMAC-SHA-1
|
||||
|
||||
test_case = 1
|
||||
key = 0x0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b
|
||||
key_len = 20
|
||||
data = "Hi Ther 20
|
||||
digest = 0x4c1a03424b55e07fe7f27be1d58bb9324a9a5a04
|
||||
digest-96 = 0x4c1a03424b55e07fe7f27be1
|
||||
*/
|
||||
{ 5, "sha1",
|
||||
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c}, 20,
|
||||
"Test With Truncation", 20,
|
||||
{0x4c, 0x1a, 0x03, 0x42, 0x4b, 0x55, 0xe0, 0x7f, 0xe7, 0xf2,
|
||||
0x7b, 0xe1, 0xd5, 0x8b, 0xb9, 0x32, 0x4a, 0x9a, 0x5a, 0x04} },
|
||||
|
||||
/*
|
||||
test_case = 6
|
||||
key = 0xaa repeated 80 times
|
||||
key_len = 80
|
||||
data = "Test Using Larger Than Block-Size Key - Hash Key First"
|
||||
data_len = 54
|
||||
digest = 0xaa4ae5e15272d00e95705637ce8a3b55ed402112
|
||||
*/
|
||||
{ 6, "sha1",
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
|
||||
"Test Using Larger Than Block-Size Key - Hash Key First", 54,
|
||||
{0xaa, 0x4a, 0xe5, 0xe1, 0x52, 0x72, 0xd0, 0x0e,
|
||||
0x95, 0x70, 0x56, 0x37, 0xce, 0x8a, 0x3b, 0x55,
|
||||
0xed, 0x40, 0x21, 0x12} },
|
||||
|
||||
/*
|
||||
test_case = 7
|
||||
key = 0xaa repeated 80 times
|
||||
key_len = 80
|
||||
data = "Test Using Larger Than Block-Size Key and Larger
|
||||
Than One Block-Size Data"
|
||||
data_len = 73
|
||||
digest = 0xe8e99d0f45237d786d6bbaa7965c7808bbff1a91
|
||||
*/
|
||||
{ 7, "sha1",
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
|
||||
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
|
||||
{0xe8, 0xe9, 0x9d, 0x0f, 0x45, 0x23, 0x7d, 0x78, 0x6d,
|
||||
0x6b, 0xba, 0xa7, 0x96, 0x5c, 0x78, 0x08, 0xbb, 0xff, 0x1a, 0x91} },
|
||||
|
||||
/*
|
||||
2. Test Cases for HMAC-MD5
|
||||
|
||||
test_case = 1
|
||||
key = 0x0b 0b 0b 0b
|
||||
0b 0b 0b 0b
|
||||
0b 0b 0b 0b
|
||||
0b 0b 0b 0b
|
||||
key_len = 16
|
||||
data = "Hi There"
|
||||
data_len = 8
|
||||
digest = 0x92 94 72 7a
|
||||
36 38 bb 1c
|
||||
13 f4 8e f8
|
||||
15 8b fc 9d
|
||||
*/
|
||||
{ 1, "md5",
|
||||
{0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b}, 16,
|
||||
"Hi There", 8,
|
||||
{0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c,
|
||||
0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d} },
|
||||
/*
|
||||
test_case = 2
|
||||
key = "Jefe"
|
||||
key_len = 4
|
||||
data = "what do ya want for nothing?"
|
||||
data_len = 28
|
||||
digest = 0x750c783e6ab0b503eaa86e310a5db738
|
||||
*/
|
||||
{ 2, "md5",
|
||||
"Jefe", 4,
|
||||
"what do ya want for nothing?", 28,
|
||||
{0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03,
|
||||
0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38} },
|
||||
|
||||
/*
|
||||
test_case = 3
|
||||
key = 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
key_len 16
|
||||
data = 0xdd repeated 50 times
|
||||
data_len = 50
|
||||
digest = 0x56be34521d144c88dbb8c733f0e8b3f6
|
||||
*/
|
||||
{ 3, "md5",
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 16,
|
||||
{0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
||||
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd}, 50,
|
||||
{0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88,
|
||||
0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6} },
|
||||
/*
|
||||
|
||||
test_case = 4
|
||||
key = 0x0102030405060708090a0b0c0d0e0f10111213141516171819
|
||||
key_len 25
|
||||
data = 0xcd repeated 50 times
|
||||
data_len = 50
|
||||
digest = 0x697eaf0aca3a3aea3a75164746ffaa79
|
||||
*/
|
||||
{ 4, "md5",
|
||||
{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
|
||||
0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14,
|
||||
0x15, 0x16, 0x17, 0x18, 0x19}, 25,
|
||||
{0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
|
||||
0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd}, 50,
|
||||
{0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea,
|
||||
0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79} },
|
||||
|
||||
|
||||
/*
|
||||
|
||||
test_case = 5
|
||||
key = 0x0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c
|
||||
key_len = 16
|
||||
data = "Test With Truncation"
|
||||
data_len = 20
|
||||
digest = 0x56461ef2342edc00f9bab995690efd4c
|
||||
digest-96 0x56461ef2342edc00f9bab995
|
||||
*/
|
||||
{ 5, "md5",
|
||||
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c}, 16,
|
||||
"Test With Truncation", 20,
|
||||
{0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00,
|
||||
0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c} },
|
||||
|
||||
/*
|
||||
|
||||
test_case = 6
|
||||
key = 0xaa repeated 80 times
|
||||
key_len = 80
|
||||
data = "Test Using Larger Than Block-Size Key - Hash
|
||||
Key First"
|
||||
data_len = 54
|
||||
digest = 0x6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd
|
||||
*/
|
||||
{ 6, "md5",
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
|
||||
"Test Using Larger Than Block-Size Key - Hash Key First", 54,
|
||||
{0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f,
|
||||
0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd} },
|
||||
|
||||
/*
|
||||
|
||||
test_case = 7
|
||||
key = 0xaa repeated 80 times
|
||||
key_len = 80
|
||||
data = "Test Using Larger Than Block-Size Key and Larger
|
||||
Than One Block-Size Data"
|
||||
data_len = 73
|
||||
digest = 0x6f630fad67cda0ee1fb1f562db3aa53e
|
||||
*/
|
||||
{ 7, "md5",
|
||||
{0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
||||
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa}, 80,
|
||||
"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", 73,
|
||||
{0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee,
|
||||
0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e} }
|
||||
};
|
||||
|
||||
unsigned long outlen;
|
||||
int err;
|
||||
int tested=0,failed=0;
|
||||
for(i=0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
|
||||
int hash = find_hash(cases[i].algo);
|
||||
if (hash == -1) continue;
|
||||
++tested;
|
||||
outlen = sizeof(digest);
|
||||
if((err = hmac_memory(hash, cases[i].key, cases[i].keylen, cases[i].data, cases[i].datalen, digest, &outlen)) != CRYPT_OK) {
|
||||
#if 0
|
||||
printf("HMAC-%s test #%d\n", cases[i].algo, cases[i].num);
|
||||
#endif
|
||||
return err;
|
||||
}
|
||||
|
||||
if(memcmp(digest, cases[i].digest, (size_t)hash_descriptor[hash].hashsize) != 0) {
|
||||
#if 0
|
||||
unsigned int j;
|
||||
printf("\nHMAC-%s test #%d:\n", cases[i].algo, cases[i].num);
|
||||
printf( "Result: 0x");
|
||||
for(j=0; j < hash_descriptor[hash].hashsize; j++) {
|
||||
printf("%2x ", digest[j]);
|
||||
}
|
||||
printf("\nCorrect: 0x");
|
||||
for(j=0; j < hash_descriptor[hash].hashsize; j++) {
|
||||
printf("%2x ", cases[i].digest[j]);
|
||||
}
|
||||
printf("\n");
|
||||
#endif
|
||||
failed++;
|
||||
//return CRYPT_ERROR;
|
||||
} else {
|
||||
/* printf("HMAC-%s test #%d: Passed\n", cases[i].algo, cases[i].num); */
|
||||
}
|
||||
}
|
||||
|
||||
if (failed != 0) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
} else if (tested == 0) {
|
||||
return CRYPT_NOP;
|
||||
} else {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
27
is_prime.c
Normal file
27
is_prime.c
Normal file
@@ -0,0 +1,27 @@
|
||||
/* 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
|
||||
|
||||
/* figures out if a number is prime (MR test) */
|
||||
int is_prime(mp_int *N, int *result)
|
||||
{
|
||||
int err;
|
||||
_ARGCHK(N != NULL);
|
||||
_ARGCHK(result != NULL);
|
||||
if ((err = mp_prime_is_prime(N, mp_prime_rabin_miller_trials(mp_count_bits(N)), result)) != MP_OKAY) {
|
||||
return mpi_to_ltc_error(err);
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
862
keyring.c
Normal file
862
keyring.c
Normal file
@@ -0,0 +1,862 @@
|
||||
/* 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
|
||||
|
||||
|
||||
254
makefile
Normal file
254
makefile
Normal file
@@ -0,0 +1,254 @@
|
||||
# MAKEFILE for linux GCC
|
||||
#
|
||||
# Tom St Denis
|
||||
# Modified by Clay Culver
|
||||
#
|
||||
# NOTE: This should later be replaced by autoconf/automake scripts, but for
|
||||
# the time being this is actually pretty clean. The only ugly part is
|
||||
# handling CFLAGS so that the x86 specific optimizations don't break
|
||||
# a build. This is easy to remedy though, for those that have problems.
|
||||
|
||||
# The version
|
||||
VERSION=0.95
|
||||
|
||||
#ch1-01-1
|
||||
# Compiler and Linker Names
|
||||
#CC=gcc
|
||||
#LD=ld
|
||||
|
||||
# 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!
|
||||
# The rest of the flags come from the parent Dropbear makefile
|
||||
CFLAGS += -c -I./
|
||||
# -Werror
|
||||
|
||||
# optimize for SPEED
|
||||
#CFLAGS += -O3 -funroll-loops
|
||||
|
||||
#add -fomit-frame-pointer. v3.2 is buggy for certain platforms!
|
||||
#CFLAGS += -fomit-frame-pointer
|
||||
|
||||
# optimize for SIZE
|
||||
#CFLAGS += -Os
|
||||
|
||||
# compile for DEBUGING
|
||||
#CFLAGS += -g3
|
||||
#ch1-01-3
|
||||
|
||||
#These flags control how the library gets built.
|
||||
|
||||
#Output filenames for various targets.
|
||||
LIBNAME=libtomcrypt.a
|
||||
TEST=test
|
||||
HASH=hashsum
|
||||
CRYPT=encrypt
|
||||
SMALL=small
|
||||
PROF=x86_prof
|
||||
TV=tv_gen
|
||||
|
||||
#LIBPATH-The directory for libtomcrypt to be installed to.
|
||||
#INCPATH-The directory to install the header files for libtomcrypt.
|
||||
#DATAPATH-The directory to install the pdf docs.
|
||||
DESTDIR=
|
||||
LIBPATH=/usr/lib
|
||||
INCPATH=/usr/include
|
||||
DATAPATH=/usr/share/doc/libtomcrypt/pdf
|
||||
|
||||
#List of objects to compile.
|
||||
|
||||
#Leave MPI built-in or force developer to link against libtommath?
|
||||
MPIOBJECT=mpi.o
|
||||
|
||||
OBJECTS=keyring.o gf.o base64.o \
|
||||
\
|
||||
crypt.o crypt_find_cipher.o crypt_find_hash_any.o \
|
||||
crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \
|
||||
crypt_argchk.o crypt_find_cipher_any.o crypt_find_hash_id.o \
|
||||
crypt_prng_descriptor.o crypt_register_prng.o crypt_cipher_descriptor.o \
|
||||
crypt_find_cipher_id.o crypt_find_prng.o crypt_prng_is_valid.o \
|
||||
crypt_unregister_cipher.o crypt_cipher_is_valid.o crypt_find_hash.o \
|
||||
crypt_hash_descriptor.o crypt_register_cipher.o crypt_unregister_hash.o \
|
||||
\
|
||||
sprng.o yarrow.o rc4.o rng_get_bytes.o rng_make_prng.o \
|
||||
\
|
||||
rand_prime.o is_prime.o \
|
||||
\
|
||||
ecc.o dh.o \
|
||||
\
|
||||
rsa.o rsa_exptmod.o rsa_free.o rsa_make_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 \
|
||||
\
|
||||
md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
|
||||
rmd128.o rmd160.o \
|
||||
\
|
||||
packet_store_header.o packet_valid_header.o \
|
||||
\
|
||||
eax_addheader.o eax_decrypt.o eax_decrypt_verify_memory.o eax_done.o eax_encrypt.o \
|
||||
eax_encrypt_authenticate_memory.o eax_init.o eax_test.o \
|
||||
\
|
||||
ocb_decrypt.o ocb_decrypt_verify_memory.o ocb_done_decrypt.o ocb_done_encrypt.o \
|
||||
ocb_encrypt.o ocb_encrypt_authenticate_memory.o ocb_init.o ocb_ntz.o \
|
||||
ocb_shift_xor.o ocb_test.o s_ocb_done.o \
|
||||
\
|
||||
omac_done.o omac_file.o omac_init.o omac_memory.o omac_process.o omac_test.o \
|
||||
\
|
||||
pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \
|
||||
pmac_shift_xor.o pmac_test.o \
|
||||
\
|
||||
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 \
|
||||
ecb_start.o ecb_encrypt.o ecb_decrypt.o \
|
||||
\
|
||||
hash_file.o hash_filehandle.o hash_memory.o \
|
||||
\
|
||||
hmac_done.o hmac_file.o hmac_init.o hmac_memory.o hmac_process.o hmac_test.o \
|
||||
\
|
||||
pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \
|
||||
pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
|
||||
\
|
||||
pkcs_5_1.o pkcs_5_2.o \
|
||||
\
|
||||
burn_stack.o zeromem.o \
|
||||
$(MPIOBJECT)
|
||||
|
||||
TESTOBJECTS=demos/test.o
|
||||
HASHOBJECTS=demos/hashsum.o
|
||||
CRYPTOBJECTS=demos/encrypt.o
|
||||
SMALLOBJECTS=demos/small.o
|
||||
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
|
||||
|
||||
#Compressed filenames
|
||||
COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz
|
||||
|
||||
#Header files used by libtomcrypt.
|
||||
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 mycrypt_pkcs.h
|
||||
|
||||
#The default rule for make builds the libtomcrypt library.
|
||||
default:library mycrypt.h mycrypt_cfg.h
|
||||
|
||||
#These are the rules to make certain object files.
|
||||
rsa.o: rsa.c rsa_sys.c
|
||||
ecc.o: ecc.c ecc_sys.c
|
||||
dh.o: dh.c dh_sys.c
|
||||
aes.o: aes.c aes_tab.c
|
||||
twofish.o: twofish.c twofish_tab.c
|
||||
sha512.o: sha512.c sha384.c
|
||||
sha256.o: sha256.c sha224.c
|
||||
|
||||
#This rule makes the libtomcrypt library.
|
||||
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)
|
||||
|
||||
#makes the crypt program
|
||||
crypt: library $(CRYPTOBJECTS)
|
||||
$(CC) $(CRYPTOBJECTS) $(LIBNAME) -o $(CRYPT) $(WARN)
|
||||
|
||||
#makes the small program
|
||||
small: library $(SMALLOBJECTS)
|
||||
$(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN)
|
||||
|
||||
x86_prof: library $(PROFS)
|
||||
$(CC) $(PROFS) $(LIBNAME) -o $(PROF)
|
||||
|
||||
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.
|
||||
install: library docs
|
||||
install -d -g root -o root $(DESTDIR)$(LIBPATH)
|
||||
install -d -g root -o root $(DESTDIR)$(INCPATH)
|
||||
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)
|
||||
|
||||
#This rule cleans the source tree of all compiled code, not including the pdf
|
||||
#documentation.
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME)
|
||||
rm -f $(TEST) $(HASH) $(COMPRESSED) $(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 *~
|
||||
|
||||
#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)
|
||||
latex crypt > /dev/null
|
||||
makeindex crypt > /dev/null
|
||||
latex crypt > /dev/null
|
||||
latex crypt > /dev/null
|
||||
dvipdf crypt
|
||||
rm -f $(LEFTOVERS)
|
||||
|
||||
#beta
|
||||
beta: clean
|
||||
cd .. ; rm -rf crypt* libtomcrypt-$(VERSION)-beta ; mkdir libtomcrypt-$(VERSION)-beta ; \
|
||||
cp -R ./libtomcrypt/* ./libtomcrypt-$(VERSION)-beta/ ; tar -c libtomcrypt-$(VERSION)-beta/* > crypt-$(VERSION)-beta.tar ; \
|
||||
bzip2 -9vv crypt-$(VERSION)-beta.tar ; zip -9 -r crypt-$(VERSION)-beta.zip libtomcrypt-$(VERSION)-beta/*
|
||||
|
||||
#zipup the project (take that!)
|
||||
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)/*
|
||||
84
makefile.cygwin_dll
Normal file
84
makefile.cygwin_dll
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
|
||||
default: ltc_dll
|
||||
|
||||
|
||||
# Compilation flags. Note the += does not write over the user's CFLAGS!
|
||||
CFLAGS += -I./ -Wall -Wsign-compare -W -Wno-unused -Wshadow -mno-cygwin -DWIN32
|
||||
|
||||
# optimize for SPEED
|
||||
#CFLAGS += -O3 -funroll-loops
|
||||
|
||||
#add -fomit-frame-pointer. v3.2 is buggy for certain platforms!
|
||||
#CFLAGS += -fomit-frame-pointer
|
||||
|
||||
# optimize for SIZE
|
||||
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 \
|
||||
\
|
||||
crypt.o crypt_find_cipher.o crypt_find_hash_any.o \
|
||||
crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \
|
||||
crypt_argchk.o crypt_find_cipher_any.o crypt_find_hash_id.o \
|
||||
crypt_prng_descriptor.o crypt_register_prng.o crypt_cipher_descriptor.o \
|
||||
crypt_find_cipher_id.o crypt_find_prng.o crypt_prng_is_valid.o \
|
||||
crypt_unregister_cipher.o crypt_cipher_is_valid.o crypt_find_hash.o \
|
||||
crypt_hash_descriptor.o crypt_register_cipher.o crypt_unregister_hash.o \
|
||||
\
|
||||
sprng.o yarrow.o rc4.o rng_get_bytes.o rng_make_prng.o \
|
||||
\
|
||||
rand_prime.o is_prime.o \
|
||||
\
|
||||
ecc.o dh.o \
|
||||
\
|
||||
rsa.o rsa_exptmod.o rsa_free.o rsa_make_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 \
|
||||
\
|
||||
md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
|
||||
rmd128.o rmd160.o \
|
||||
\
|
||||
packet_store_header.o packet_valid_header.o \
|
||||
\
|
||||
eax_addheader.o eax_decrypt.o eax_decrypt_verify_memory.o eax_done.o eax_encrypt.o \
|
||||
eax_encrypt_authenticate_memory.o eax_init.o eax_test.o \
|
||||
\
|
||||
ocb_decrypt.o ocb_decrypt_verify_memory.o ocb_done_decrypt.o ocb_done_encrypt.o \
|
||||
ocb_encrypt.o ocb_encrypt_authenticate_memory.o ocb_init.o ocb_ntz.o \
|
||||
ocb_shift_xor.o ocb_test.o s_ocb_done.o \
|
||||
\
|
||||
omac_done.o omac_file.o omac_init.o omac_memory.o omac_process.o omac_test.o \
|
||||
\
|
||||
pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \
|
||||
pmac_shift_xor.o pmac_test.o \
|
||||
\
|
||||
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 \
|
||||
ecb_start.o ecb_encrypt.o ecb_decrypt.o \
|
||||
\
|
||||
hash_file.o hash_filehandle.o hash_memory.o \
|
||||
\
|
||||
hmac_done.o hmac_file.o hmac_init.o hmac_memory.o hmac_process.o hmac_test.o \
|
||||
\
|
||||
pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \
|
||||
pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
|
||||
\
|
||||
pkcs_5_1.o pkcs_5_2.o \
|
||||
\
|
||||
burn_stack.o zeromem.o \
|
||||
$(MPIOBJECT)
|
||||
|
||||
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
|
||||
213
makefile.icc
Normal file
213
makefile.icc
Normal file
@@ -0,0 +1,213 @@
|
||||
# MAKEFILE for linux ICC (Intel C compiler)
|
||||
#
|
||||
# Tested with ICC v8....
|
||||
#
|
||||
# Be aware that ICC isn't quite as stable as GCC and several optimization switches
|
||||
# seem to break the code (that GCC and MSVC compile just fine). In particular
|
||||
# "-ip" and "-x*" seem to break the code (ROL/ROR macro problems). As the makefile
|
||||
# is shipped the code will build and execute properly.
|
||||
#
|
||||
# Also note that ICC often makes code that is slower than GCC. This is probably due to
|
||||
# a mix of not being able to use "-ip" and just having fewer optimization algos than GCC.
|
||||
#
|
||||
# Tom St Denis
|
||||
|
||||
#ch1-01-1
|
||||
# Compiler and Linker Names
|
||||
CC=icc
|
||||
#LD=ld
|
||||
|
||||
# Archiver [makes .a files]
|
||||
#AR=ar
|
||||
#ARFLAGS=r
|
||||
|
||||
# Compilation flags. Note the += does not write over the user's CFLAGS!
|
||||
CFLAGS += -c -I./ -DINTEL_CC
|
||||
|
||||
# optimize for SPEED
|
||||
#
|
||||
# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4
|
||||
# -ax? specifies make code specifically for ? but compatible with IA-32
|
||||
# -x? specifies compile solely for ? [not specifically IA-32 compatible]
|
||||
#
|
||||
# where ? is
|
||||
# K - PIII
|
||||
# W - first P4 [Williamette]
|
||||
# N - P4 Northwood
|
||||
# P - P4 Prescott
|
||||
# B - Blend of P4 and PM [mobile]
|
||||
#
|
||||
# Default to just generic max opts
|
||||
CFLAGS += -O3 -xN -ip
|
||||
|
||||
# want to see stuff?
|
||||
#CFLAGS += -opt_report
|
||||
|
||||
#These flags control how the library gets built.
|
||||
|
||||
#Output filenames for various targets.
|
||||
LIBNAME=libtomcrypt.a
|
||||
TEST=test
|
||||
HASH=hashsum
|
||||
CRYPT=encrypt
|
||||
SMALL=small
|
||||
PROF=x86_prof
|
||||
TV=tv_gen
|
||||
|
||||
#LIBPATH-The directory for libtomcrypt to be installed to.
|
||||
#INCPATH-The directory to install the header files for libtomcrypt.
|
||||
#DATAPATH-The directory to install the pdf docs.
|
||||
DESTDIR=
|
||||
LIBPATH=/usr/lib
|
||||
INCPATH=/usr/include
|
||||
DATAPATH=/usr/share/doc/libtomcrypt/pdf
|
||||
|
||||
#List of objects to compile.
|
||||
|
||||
#Leave MPI built-in or force developer to link against libtommath?
|
||||
MPIOBJECT=mpi.o
|
||||
|
||||
OBJECTS=keyring.o gf.o strings.o base64.o \
|
||||
\
|
||||
crypt.o crypt_find_cipher.o crypt_find_hash_any.o \
|
||||
crypt_hash_is_valid.o crypt_register_hash.o crypt_unregister_prng.o \
|
||||
crypt_argchk.o crypt_find_cipher_any.o crypt_find_hash_id.o \
|
||||
crypt_prng_descriptor.o crypt_register_prng.o crypt_cipher_descriptor.o \
|
||||
crypt_find_cipher_id.o crypt_find_prng.o crypt_prng_is_valid.o \
|
||||
crypt_unregister_cipher.o crypt_cipher_is_valid.o crypt_find_hash.o \
|
||||
crypt_hash_descriptor.o crypt_register_cipher.o crypt_unregister_hash.o \
|
||||
\
|
||||
sprng.o yarrow.o rc4.o rng_get_bytes.o rng_make_prng.o \
|
||||
\
|
||||
rand_prime.o is_prime.o \
|
||||
\
|
||||
ecc.o dh.o \
|
||||
\
|
||||
rsa.o rsa_exptmod.o rsa_free.o rsa_make_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 \
|
||||
\
|
||||
md2.o md4.o md5.o sha1.o sha256.o sha512.o tiger.o whirl.o \
|
||||
rmd128.o rmd160.o \
|
||||
\
|
||||
packet_store_header.o packet_valid_header.o \
|
||||
\
|
||||
eax_addheader.o eax_decrypt.o eax_decrypt_verify_memory.o eax_done.o eax_encrypt.o \
|
||||
eax_encrypt_authenticate_memory.o eax_init.o eax_test.o \
|
||||
\
|
||||
ocb_decrypt.o ocb_decrypt_verify_memory.o ocb_done_decrypt.o ocb_done_encrypt.o \
|
||||
ocb_encrypt.o ocb_encrypt_authenticate_memory.o ocb_init.o ocb_ntz.o \
|
||||
ocb_shift_xor.o ocb_test.o s_ocb_done.o \
|
||||
\
|
||||
omac_done.o omac_file.o omac_init.o omac_memory.o omac_process.o omac_test.o \
|
||||
\
|
||||
pmac_done.o pmac_file.o pmac_init.o pmac_memory.o pmac_ntz.o pmac_process.o \
|
||||
pmac_shift_xor.o pmac_test.o \
|
||||
\
|
||||
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 \
|
||||
ecb_start.o ecb_encrypt.o ecb_decrypt.o \
|
||||
\
|
||||
hash_file.o hash_filehandle.o hash_memory.o \
|
||||
\
|
||||
hmac_done.o hmac_file.o hmac_init.o hmac_memory.o hmac_process.o hmac_test.o \
|
||||
\
|
||||
pkcs_1_mgf1.o pkcs_1_oaep_encode.o pkcs_1_oaep_decode.o \
|
||||
pkcs_1_pss_encode.o pkcs_1_pss_decode.o pkcs_1_i2osp.o pkcs_1_os2ip.o \
|
||||
\
|
||||
pkcs_5_1.o pkcs_5_2.o \
|
||||
\
|
||||
burn_stack.o zeromem.o \
|
||||
$(MPIOBJECT)
|
||||
|
||||
TESTOBJECTS=demos/test.o
|
||||
HASHOBJECTS=demos/hashsum.o
|
||||
CRYPTOBJECTS=demos/encrypt.o
|
||||
SMALLOBJECTS=demos/small.o
|
||||
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
|
||||
|
||||
#Compressed filenames
|
||||
COMPRESSED=crypt.tar.bz2 crypt.zip crypt.tar.gz
|
||||
|
||||
#Header files used by libtomcrypt.
|
||||
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
|
||||
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
|
||||
|
||||
#This rule makes the libtomcrypt library.
|
||||
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)
|
||||
|
||||
#makes the crypt program
|
||||
crypt: library $(CRYPTOBJECTS)
|
||||
$(CC) $(CRYPTOBJECTS) $(LIBNAME) -o $(CRYPT) $(WARN)
|
||||
|
||||
#makes the small program
|
||||
small: library $(SMALLOBJECTS)
|
||||
$(CC) $(SMALLOBJECTS) $(LIBNAME) -o $(SMALL) $(WARN)
|
||||
|
||||
x86_prof: library $(PROFS)
|
||||
$(CC) $(PROFS) $(LIBNAME) -o $(PROF)
|
||||
|
||||
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.
|
||||
install: library
|
||||
install -d -g root -o root $(DESTDIR)$(LIBPATH)
|
||||
install -d -g root -o root $(DESTDIR)$(INCPATH)
|
||||
install -g root -o root $(LIBNAME) $(DESTDIR)$(LIBPATH)
|
||||
install -g root -o root $(HEADERS) $(DESTDIR)$(INCPATH)
|
||||
|
||||
#This rule cleans the source tree of all compiled code, not including the pdf
|
||||
#documentation.
|
||||
clean:
|
||||
rm -f $(OBJECTS) $(TESTOBJECTS) $(HASHOBJECTS) $(CRYPTOBJECTS) $(SMALLOBJECTS) $(LEFTOVERS) $(LIBNAME)
|
||||
rm -f $(TEST) $(HASH) $(COMPRESSED) $(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
|
||||
86
makefile.msvc
Normal file
86
makefile.msvc
Normal file
@@ -0,0 +1,86 @@
|
||||
#MSVC Makefile [tested with MSVC 6.00 with SP5]
|
||||
#
|
||||
#Tom St Denis
|
||||
CFLAGS = /I. /Ox /DWIN32 /W3
|
||||
|
||||
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 \
|
||||
\
|
||||
crypt.obj crypt_find_cipher.obj crypt_find_hash_any.obj \
|
||||
crypt_hash_is_valid.obj crypt_register_hash.obj crypt_unregister_prng.obj \
|
||||
crypt_argchk.obj crypt_find_cipher_any.obj crypt_find_hash_id.obj \
|
||||
crypt_prng_descriptor.obj crypt_register_prng.obj crypt_cipher_descriptor.obj \
|
||||
crypt_find_cipher_id.obj crypt_find_prng.obj crypt_prng_is_valid.obj \
|
||||
crypt_unregister_cipher.obj crypt_cipher_is_valid.obj crypt_find_hash.obj \
|
||||
crypt_hash_descriptor.obj crypt_register_cipher.obj crypt_unregister_hash.obj \
|
||||
\
|
||||
sprng.obj yarrow.obj rc4.obj rng_get_bytes.obj rng_make_prng.obj \
|
||||
\
|
||||
rand_prime.obj is_prime.obj \
|
||||
\
|
||||
ecc.obj dh.obj \
|
||||
\
|
||||
rsa.obj rsa_exptmod.obj rsa_free.obj rsa_make_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 \
|
||||
\
|
||||
md2.obj md4.obj md5.obj sha1.obj sha256.obj sha512.obj tiger.obj whirl.obj \
|
||||
rmd128.obj rmd160.obj \
|
||||
\
|
||||
packet_store_header.obj packet_valid_header.obj \
|
||||
\
|
||||
eax_addheader.obj eax_decrypt.obj eax_decrypt_verify_memory.obj eax_done.obj eax_encrypt.obj \
|
||||
eax_encrypt_authenticate_memory.obj eax_init.obj eax_test.obj \
|
||||
\
|
||||
ocb_decrypt.obj ocb_decrypt_verify_memory.obj ocb_done_decrypt.obj ocb_done_encrypt.obj \
|
||||
ocb_encrypt.obj ocb_encrypt_authenticate_memory.obj ocb_init.obj ocb_ntz.obj \
|
||||
ocb_shift_xor.obj ocb_test.obj s_ocb_done.obj \
|
||||
\
|
||||
omac_done.obj omac_file.obj omac_init.obj omac_memory.obj omac_process.obj omac_test.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 \
|
||||
ecb_start.obj ecb_encrypt.obj ecb_decrypt.obj \
|
||||
\
|
||||
hash_file.obj hash_filehandle.obj hash_memory.obj \
|
||||
\
|
||||
hmac_done.obj hmac_file.obj hmac_init.obj hmac_memory.obj hmac_process.obj hmac_test.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_5_1.obj pkcs_5_2.obj \
|
||||
\
|
||||
burn_stack.obj zeromem.obj \
|
||||
$(MPIOBJECT)
|
||||
|
||||
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
|
||||
|
||||
tv_gen: demos/tv_gen.c library
|
||||
cl $(CFLAGS) demos/tv_gen.c tomcrypt.lib advapi32.lib
|
||||
|
||||
hashsum: demos/hashsum.c library
|
||||
cl $(CFLAGS) demos/hashsum.c tomcrypt.lib advapi32.lib
|
||||
214
md2.c
Normal file
214
md2.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/* 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
|
||||
*/
|
||||
/* MD2 (RFC 1319) hash function implementation by Tom St Denis */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef MD2
|
||||
|
||||
const struct _hash_descriptor md2_desc =
|
||||
{
|
||||
"md2",
|
||||
7,
|
||||
16,
|
||||
16,
|
||||
&md2_init,
|
||||
&md2_process,
|
||||
&md2_done,
|
||||
&md2_test
|
||||
};
|
||||
|
||||
static const unsigned char PI_SUBST[256] = {
|
||||
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
|
||||
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
|
||||
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
|
||||
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
|
||||
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
|
||||
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
|
||||
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
|
||||
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
|
||||
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
|
||||
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
|
||||
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
|
||||
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
|
||||
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
|
||||
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
|
||||
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
|
||||
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
|
||||
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
|
||||
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
|
||||
};
|
||||
|
||||
/* adds 16 bytes to the checksum */
|
||||
static void md2_update_chksum(hash_state *md)
|
||||
{
|
||||
int j;
|
||||
unsigned char L;
|
||||
L = md->md2.chksum[15];
|
||||
for (j = 0; j < 16; j++) {
|
||||
|
||||
/* caution, the RFC says its "C[j] = S[M[i*16+j] xor L]" but the reference source code [and test vectors] say
|
||||
otherwise.
|
||||
*/
|
||||
L = (md->md2.chksum[j] ^= PI_SUBST[(int)(md->md2.buf[j] ^ L)] & 255);
|
||||
}
|
||||
}
|
||||
|
||||
static void md2_compress(hash_state *md)
|
||||
{
|
||||
int j, k;
|
||||
unsigned char t;
|
||||
|
||||
/* copy block */
|
||||
for (j = 0; j < 16; j++) {
|
||||
md->md2.X[16+j] = md->md2.buf[j];
|
||||
md->md2.X[32+j] = md->md2.X[j] ^ md->md2.X[16+j];
|
||||
}
|
||||
|
||||
t = (unsigned char)0;
|
||||
|
||||
/* do 18 rounds */
|
||||
for (j = 0; j < 18; j++) {
|
||||
for (k = 0; k < 48; k++) {
|
||||
t = (md->md2.X[k] ^= PI_SUBST[(int)(t & 255)]);
|
||||
}
|
||||
t = (t + (unsigned char)j) & 255;
|
||||
}
|
||||
}
|
||||
|
||||
void md2_init(hash_state *md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
|
||||
/* MD2 uses a zero'ed state... */
|
||||
zeromem(md->md2.X, sizeof(md->md2.X));
|
||||
zeromem(md->md2.chksum, sizeof(md->md2.chksum));
|
||||
zeromem(md->md2.buf, sizeof(md->md2.buf));
|
||||
md->md2.curlen = 0;
|
||||
}
|
||||
|
||||
int md2_process(hash_state *md, const unsigned char *buf, unsigned long len)
|
||||
{
|
||||
unsigned long n;
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(buf != NULL);
|
||||
if (md-> md2 .curlen > sizeof(md-> md2 .buf)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
while (len > 0) {
|
||||
n = MIN(len, (16 - md->md2.curlen));
|
||||
memcpy(md->md2.buf + md->md2.curlen, buf, (size_t)n);
|
||||
md->md2.curlen += n;
|
||||
buf += n;
|
||||
len -= n;
|
||||
|
||||
/* is 16 bytes full? */
|
||||
if (md->md2.curlen == 16) {
|
||||
md2_compress(md);
|
||||
md2_update_chksum(md);
|
||||
md->md2.curlen = 0;
|
||||
}
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int md2_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
unsigned long i, k;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
if (md->md2.curlen >= sizeof(md->md2.buf)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
||||
/* pad the message */
|
||||
k = 16 - md->md2.curlen;
|
||||
for (i = md->md2.curlen; i < 16; i++) {
|
||||
md->md2.buf[i] = (unsigned char)k;
|
||||
}
|
||||
|
||||
/* hash and update */
|
||||
md2_compress(md);
|
||||
md2_update_chksum(md);
|
||||
|
||||
/* hash checksum */
|
||||
memcpy(md->md2.buf, md->md2.chksum, 16);
|
||||
md2_compress(md);
|
||||
|
||||
/* output is lower 16 bytes of X */
|
||||
memcpy(hash, md->md2.X, 16);
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int md2_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
char *msg;
|
||||
unsigned char md[16];
|
||||
} tests[] = {
|
||||
{ "",
|
||||
{0x83,0x50,0xe5,0xa3,0xe2,0x4c,0x15,0x3d,
|
||||
0xf2,0x27,0x5c,0x9f,0x80,0x69,0x27,0x73
|
||||
}
|
||||
},
|
||||
{ "a",
|
||||
{0x32,0xec,0x01,0xec,0x4a,0x6d,0xac,0x72,
|
||||
0xc0,0xab,0x96,0xfb,0x34,0xc0,0xb5,0xd1
|
||||
}
|
||||
},
|
||||
{ "message digest",
|
||||
{0xab,0x4f,0x49,0x6b,0xfb,0x2a,0x53,0x0b,
|
||||
0x21,0x9f,0xf3,0x30,0x31,0xfe,0x06,0xb0
|
||||
}
|
||||
},
|
||||
{ "abcdefghijklmnopqrstuvwxyz",
|
||||
{0x4e,0x8d,0xdf,0xf3,0x65,0x02,0x92,0xab,
|
||||
0x5a,0x41,0x08,0xc3,0xaa,0x47,0x94,0x0b
|
||||
}
|
||||
},
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
{0xda,0x33,0xde,0xf2,0xa4,0x2d,0xf1,0x39,
|
||||
0x75,0x35,0x28,0x46,0xc3,0x03,0x38,0xcd
|
||||
}
|
||||
},
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
{0xd5,0x97,0x6f,0x79,0xd8,0x3d,0x3a,0x0d,
|
||||
0xc9,0x80,0x6c,0x3c,0x66,0xf3,0xef,0xd8
|
||||
}
|
||||
}
|
||||
};
|
||||
int i;
|
||||
hash_state md;
|
||||
unsigned char buf[16];
|
||||
|
||||
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
|
||||
md2_init(&md);
|
||||
md2_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
|
||||
md2_done(&md, buf);
|
||||
if (memcmp(buf, tests[i].md, 16) != 0) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
266
md4.c
Normal file
266
md4.c
Normal file
@@ -0,0 +1,266 @@
|
||||
/* 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
|
||||
*/
|
||||
/* Submitted by Dobes Vandermeer (dobes@smartt.com) */
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef MD4
|
||||
|
||||
const struct _hash_descriptor md4_desc =
|
||||
{
|
||||
"md4",
|
||||
6,
|
||||
16,
|
||||
64,
|
||||
&md4_init,
|
||||
&md4_process,
|
||||
&md4_done,
|
||||
&md4_test
|
||||
};
|
||||
|
||||
#define S11 3
|
||||
#define S12 7
|
||||
#define S13 11
|
||||
#define S14 19
|
||||
#define S21 3
|
||||
#define S22 5
|
||||
#define S23 9
|
||||
#define S24 13
|
||||
#define S31 3
|
||||
#define S32 9
|
||||
#define S33 11
|
||||
#define S34 15
|
||||
|
||||
/* F, G and H are basic MD4 functions. */
|
||||
#define F(x, y, z) (z ^ (x & (y ^ z)))
|
||||
#define G(x, y, z) ((x & y) | (z & (x | y)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits. */
|
||||
#define ROTATE_LEFT(x, n) ROL(x, n)
|
||||
|
||||
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
|
||||
/* Rotation is separate from addition to prevent recomputation */
|
||||
|
||||
#define FF(a, b, c, d, x, s) { \
|
||||
(a) += F ((b), (c), (d)) + (x); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + 0x5a827999UL; \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + 0x6ed9eba1UL; \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _md4_compress(hash_state *md, unsigned char *buf)
|
||||
#else
|
||||
static void md4_compress(hash_state *md, unsigned char *buf)
|
||||
#endif
|
||||
{
|
||||
ulong32 x[16], a, b, c, d;
|
||||
int i;
|
||||
|
||||
/* copy state */
|
||||
a = md->md4.state[0];
|
||||
b = md->md4.state[1];
|
||||
c = md->md4.state[2];
|
||||
d = md->md4.state[3];
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD32L(x[i], buf + (4*i));
|
||||
}
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 0], S21); /* 17 */
|
||||
GG (d, a, b, c, x[ 4], S22); /* 18 */
|
||||
GG (c, d, a, b, x[ 8], S23); /* 19 */
|
||||
GG (b, c, d, a, x[12], S24); /* 20 */
|
||||
GG (a, b, c, d, x[ 1], S21); /* 21 */
|
||||
GG (d, a, b, c, x[ 5], S22); /* 22 */
|
||||
GG (c, d, a, b, x[ 9], S23); /* 23 */
|
||||
GG (b, c, d, a, x[13], S24); /* 24 */
|
||||
GG (a, b, c, d, x[ 2], S21); /* 25 */
|
||||
GG (d, a, b, c, x[ 6], S22); /* 26 */
|
||||
GG (c, d, a, b, x[10], S23); /* 27 */
|
||||
GG (b, c, d, a, x[14], S24); /* 28 */
|
||||
GG (a, b, c, d, x[ 3], S21); /* 29 */
|
||||
GG (d, a, b, c, x[ 7], S22); /* 30 */
|
||||
GG (c, d, a, b, x[11], S23); /* 31 */
|
||||
GG (b, c, d, a, x[15], S24); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 0], S31); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32); /* 34 */
|
||||
HH (c, d, a, b, x[ 4], S33); /* 35 */
|
||||
HH (b, c, d, a, x[12], S34); /* 36 */
|
||||
HH (a, b, c, d, x[ 2], S31); /* 37 */
|
||||
HH (d, a, b, c, x[10], S32); /* 38 */
|
||||
HH (c, d, a, b, x[ 6], S33); /* 39 */
|
||||
HH (b, c, d, a, x[14], S34); /* 40 */
|
||||
HH (a, b, c, d, x[ 1], S31); /* 41 */
|
||||
HH (d, a, b, c, x[ 9], S32); /* 42 */
|
||||
HH (c, d, a, b, x[ 5], S33); /* 43 */
|
||||
HH (b, c, d, a, x[13], S34); /* 44 */
|
||||
HH (a, b, c, d, x[ 3], S31); /* 45 */
|
||||
HH (d, a, b, c, x[11], S32); /* 46 */
|
||||
HH (c, d, a, b, x[ 7], S33); /* 47 */
|
||||
HH (b, c, d, a, x[15], S34); /* 48 */
|
||||
|
||||
|
||||
/* Update our state */
|
||||
md->md4.state[0] = md->md4.state[0] + a;
|
||||
md->md4.state[1] = md->md4.state[1] + b;
|
||||
md->md4.state[2] = md->md4.state[2] + c;
|
||||
md->md4.state[3] = md->md4.state[3] + d;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void md4_compress(hash_state *md, unsigned char *buf)
|
||||
{
|
||||
_md4_compress(md, buf);
|
||||
burn_stack(sizeof(ulong32) * 20 + sizeof(int));
|
||||
}
|
||||
#endif
|
||||
|
||||
void md4_init(hash_state * md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
md->md4.state[0] = 0x67452301UL;
|
||||
md->md4.state[1] = 0xefcdab89UL;
|
||||
md->md4.state[2] = 0x98badcfeUL;
|
||||
md->md4.state[3] = 0x10325476UL;
|
||||
md->md4.length = 0;
|
||||
md->md4.curlen = 0;
|
||||
}
|
||||
|
||||
HASH_PROCESS(md4_process, md4_compress, md4, 64)
|
||||
|
||||
int md4_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
int i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
if (md->md4.curlen >= sizeof(md->md4.buf)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* increase the length of the message */
|
||||
md->md4.length += md->md4.curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->md4.buf[md->md4.curlen++] = (unsigned char)0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->md4.curlen > 56) {
|
||||
while (md->md4.curlen < 64) {
|
||||
md->md4.buf[md->md4.curlen++] = (unsigned char)0;
|
||||
}
|
||||
md4_compress(md, md->md4.buf);
|
||||
md->md4.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (md->md4.curlen < 56) {
|
||||
md->md4.buf[md->md4.curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64L(md->md4.length, md->md4.buf+56);
|
||||
md4_compress(md, md->md4.buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 4; i++) {
|
||||
STORE32L(md->md4.state[i], hash+(4*i));
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int md4_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct md4_test_case {
|
||||
char *input;
|
||||
unsigned char digest[16];
|
||||
} cases[] = {
|
||||
{ "",
|
||||
{0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
|
||||
0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0} },
|
||||
{ "a",
|
||||
{0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46,
|
||||
0x24, 0x5e, 0x05, 0xfb, 0xdb, 0xd6, 0xfb, 0x24} },
|
||||
{ "abc",
|
||||
{0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52,
|
||||
0x5f, 0xc1, 0x0a, 0xe8, 0x7a, 0xa6, 0x72, 0x9d} },
|
||||
{ "message digest",
|
||||
{0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8,
|
||||
0x18, 0x87, 0x48, 0x06, 0xe1, 0xc7, 0x01, 0x4b} },
|
||||
{ "abcdefghijklmnopqrstuvwxyz",
|
||||
{0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd,
|
||||
0xee, 0xa8, 0xed, 0x63, 0xdf, 0x41, 0x2d, 0xa9} },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
{0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35,
|
||||
0x1c, 0xe6, 0x27, 0xe1, 0x53, 0xe7, 0xf0, 0xe4} },
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
{0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19,
|
||||
0x9c, 0x3e, 0x7b, 0x16, 0x4f, 0xcc, 0x05, 0x36} },
|
||||
};
|
||||
int i;
|
||||
hash_state md;
|
||||
unsigned char digest[16];
|
||||
|
||||
for(i = 0; i < (int)(sizeof(cases) / sizeof(cases[0])); i++) {
|
||||
md4_init(&md);
|
||||
md4_process(&md, (unsigned char *)cases[i].input, (unsigned long)strlen(cases[i].input));
|
||||
md4_done(&md, digest);
|
||||
if (memcmp(digest, cases[i].digest, 16) != 0) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
258
md5.c
Normal file
258
md5.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/* 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
|
||||
*/
|
||||
|
||||
/* MD5 hash function by Tom St Denis */
|
||||
|
||||
#include "mycrypt.h"
|
||||
|
||||
#ifdef MD5
|
||||
|
||||
const struct _hash_descriptor md5_desc =
|
||||
{
|
||||
"md5",
|
||||
3,
|
||||
16,
|
||||
64,
|
||||
&md5_init,
|
||||
&md5_process,
|
||||
&md5_done,
|
||||
&md5_test
|
||||
};
|
||||
|
||||
#define F(x,y,z) (z ^ (x & (y ^ z)))
|
||||
#define G(x,y,z) (y ^ (z & (y ^ x)))
|
||||
#define H(x,y,z) (x^y^z)
|
||||
#define I(x,y,z) (y^(x|(~z)))
|
||||
|
||||
#define FF(a,b,c,d,M,s,t) \
|
||||
a = (a + F(b,c,d) + M + t); a = ROL(a, s) + b;
|
||||
|
||||
#define GG(a,b,c,d,M,s,t) \
|
||||
a = (a + G(b,c,d) + M + t); a = ROL(a, s) + b;
|
||||
|
||||
#define HH(a,b,c,d,M,s,t) \
|
||||
a = (a + H(b,c,d) + M + t); a = ROL(a, s) + b;
|
||||
|
||||
#define II(a,b,c,d,M,s,t) \
|
||||
a = (a + I(b,c,d) + M + t); a = ROL(a, s) + b;
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void _md5_compress(hash_state *md, unsigned char *buf)
|
||||
#else
|
||||
static void md5_compress(hash_state *md, unsigned char *buf)
|
||||
#endif
|
||||
{
|
||||
ulong32 i, W[16], a, b, c, d;
|
||||
|
||||
/* copy the state into 512-bits into W[0..15] */
|
||||
for (i = 0; i < 16; i++) {
|
||||
LOAD32L(W[i], buf + (4*i));
|
||||
}
|
||||
|
||||
/* copy state */
|
||||
a = md->md5.state[0];
|
||||
b = md->md5.state[1];
|
||||
c = md->md5.state[2];
|
||||
d = md->md5.state[3];
|
||||
|
||||
FF(a,b,c,d,W[0],7,0xd76aa478UL)
|
||||
FF(d,a,b,c,W[1],12,0xe8c7b756UL)
|
||||
FF(c,d,a,b,W[2],17,0x242070dbUL)
|
||||
FF(b,c,d,a,W[3],22,0xc1bdceeeUL)
|
||||
FF(a,b,c,d,W[4],7,0xf57c0fafUL)
|
||||
FF(d,a,b,c,W[5],12,0x4787c62aUL)
|
||||
FF(c,d,a,b,W[6],17,0xa8304613UL)
|
||||
FF(b,c,d,a,W[7],22,0xfd469501UL)
|
||||
FF(a,b,c,d,W[8],7,0x698098d8UL)
|
||||
FF(d,a,b,c,W[9],12,0x8b44f7afUL)
|
||||
FF(c,d,a,b,W[10],17,0xffff5bb1UL)
|
||||
FF(b,c,d,a,W[11],22,0x895cd7beUL)
|
||||
FF(a,b,c,d,W[12],7,0x6b901122UL)
|
||||
FF(d,a,b,c,W[13],12,0xfd987193UL)
|
||||
FF(c,d,a,b,W[14],17,0xa679438eUL)
|
||||
FF(b,c,d,a,W[15],22,0x49b40821UL)
|
||||
GG(a,b,c,d,W[1],5,0xf61e2562UL)
|
||||
GG(d,a,b,c,W[6],9,0xc040b340UL)
|
||||
GG(c,d,a,b,W[11],14,0x265e5a51UL)
|
||||
GG(b,c,d,a,W[0],20,0xe9b6c7aaUL)
|
||||
GG(a,b,c,d,W[5],5,0xd62f105dUL)
|
||||
GG(d,a,b,c,W[10],9,0x02441453UL)
|
||||
GG(c,d,a,b,W[15],14,0xd8a1e681UL)
|
||||
GG(b,c,d,a,W[4],20,0xe7d3fbc8UL)
|
||||
GG(a,b,c,d,W[9],5,0x21e1cde6UL)
|
||||
GG(d,a,b,c,W[14],9,0xc33707d6UL)
|
||||
GG(c,d,a,b,W[3],14,0xf4d50d87UL)
|
||||
GG(b,c,d,a,W[8],20,0x455a14edUL)
|
||||
GG(a,b,c,d,W[13],5,0xa9e3e905UL)
|
||||
GG(d,a,b,c,W[2],9,0xfcefa3f8UL)
|
||||
GG(c,d,a,b,W[7],14,0x676f02d9UL)
|
||||
GG(b,c,d,a,W[12],20,0x8d2a4c8aUL)
|
||||
HH(a,b,c,d,W[5],4,0xfffa3942UL)
|
||||
HH(d,a,b,c,W[8],11,0x8771f681UL)
|
||||
HH(c,d,a,b,W[11],16,0x6d9d6122UL)
|
||||
HH(b,c,d,a,W[14],23,0xfde5380cUL)
|
||||
HH(a,b,c,d,W[1],4,0xa4beea44UL)
|
||||
HH(d,a,b,c,W[4],11,0x4bdecfa9UL)
|
||||
HH(c,d,a,b,W[7],16,0xf6bb4b60UL)
|
||||
HH(b,c,d,a,W[10],23,0xbebfbc70UL)
|
||||
HH(a,b,c,d,W[13],4,0x289b7ec6UL)
|
||||
HH(d,a,b,c,W[0],11,0xeaa127faUL)
|
||||
HH(c,d,a,b,W[3],16,0xd4ef3085UL)
|
||||
HH(b,c,d,a,W[6],23,0x04881d05UL)
|
||||
HH(a,b,c,d,W[9],4,0xd9d4d039UL)
|
||||
HH(d,a,b,c,W[12],11,0xe6db99e5UL)
|
||||
HH(c,d,a,b,W[15],16,0x1fa27cf8UL)
|
||||
HH(b,c,d,a,W[2],23,0xc4ac5665UL)
|
||||
II(a,b,c,d,W[0],6,0xf4292244UL)
|
||||
II(d,a,b,c,W[7],10,0x432aff97UL)
|
||||
II(c,d,a,b,W[14],15,0xab9423a7UL)
|
||||
II(b,c,d,a,W[5],21,0xfc93a039UL)
|
||||
II(a,b,c,d,W[12],6,0x655b59c3UL)
|
||||
II(d,a,b,c,W[3],10,0x8f0ccc92UL)
|
||||
II(c,d,a,b,W[10],15,0xffeff47dUL)
|
||||
II(b,c,d,a,W[1],21,0x85845dd1UL)
|
||||
II(a,b,c,d,W[8],6,0x6fa87e4fUL)
|
||||
II(d,a,b,c,W[15],10,0xfe2ce6e0UL)
|
||||
II(c,d,a,b,W[6],15,0xa3014314UL)
|
||||
II(b,c,d,a,W[13],21,0x4e0811a1UL)
|
||||
II(a,b,c,d,W[4],6,0xf7537e82UL)
|
||||
II(d,a,b,c,W[11],10,0xbd3af235UL)
|
||||
II(c,d,a,b,W[2],15,0x2ad7d2bbUL)
|
||||
II(b,c,d,a,W[9],21,0xeb86d391UL)
|
||||
|
||||
md->md5.state[0] = md->md5.state[0] + a;
|
||||
md->md5.state[1] = md->md5.state[1] + b;
|
||||
md->md5.state[2] = md->md5.state[2] + c;
|
||||
md->md5.state[3] = md->md5.state[3] + d;
|
||||
}
|
||||
|
||||
#ifdef CLEAN_STACK
|
||||
static void md5_compress(hash_state *md, unsigned char *buf)
|
||||
{
|
||||
_md5_compress(md, buf);
|
||||
burn_stack(sizeof(ulong32) * 21);
|
||||
}
|
||||
#endif
|
||||
|
||||
void md5_init(hash_state * md)
|
||||
{
|
||||
_ARGCHK(md != NULL);
|
||||
md->md5.state[0] = 0x67452301UL;
|
||||
md->md5.state[1] = 0xefcdab89UL;
|
||||
md->md5.state[2] = 0x98badcfeUL;
|
||||
md->md5.state[3] = 0x10325476UL;
|
||||
md->md5.curlen = 0;
|
||||
md->md5.length = 0;
|
||||
}
|
||||
|
||||
HASH_PROCESS(md5_process, md5_compress, md5, 64)
|
||||
|
||||
int md5_done(hash_state * md, unsigned char *hash)
|
||||
{
|
||||
int i;
|
||||
|
||||
_ARGCHK(md != NULL);
|
||||
_ARGCHK(hash != NULL);
|
||||
|
||||
if (md->md5.curlen >= sizeof(md->md5.buf)) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
|
||||
/* increase the length of the message */
|
||||
md->md5.length += md->md5.curlen * 8;
|
||||
|
||||
/* append the '1' bit */
|
||||
md->md5.buf[md->md5.curlen++] = (unsigned char)0x80;
|
||||
|
||||
/* if the length is currently above 56 bytes we append zeros
|
||||
* then compress. Then we can fall back to padding zeros and length
|
||||
* encoding like normal.
|
||||
*/
|
||||
if (md->md5.curlen > 56) {
|
||||
while (md->md5.curlen < 64) {
|
||||
md->md5.buf[md->md5.curlen++] = (unsigned char)0;
|
||||
}
|
||||
md5_compress(md, md->md5.buf);
|
||||
md->md5.curlen = 0;
|
||||
}
|
||||
|
||||
/* pad upto 56 bytes of zeroes */
|
||||
while (md->md5.curlen < 56) {
|
||||
md->md5.buf[md->md5.curlen++] = (unsigned char)0;
|
||||
}
|
||||
|
||||
/* store length */
|
||||
STORE64L(md->md5.length, md->md5.buf+56);
|
||||
md5_compress(md, md->md5.buf);
|
||||
|
||||
/* copy output */
|
||||
for (i = 0; i < 4; i++) {
|
||||
STORE32L(md->md5.state[i], hash+(4*i));
|
||||
}
|
||||
#ifdef CLEAN_STACK
|
||||
zeromem(md, sizeof(hash_state));
|
||||
#endif
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int md5_test(void)
|
||||
{
|
||||
#ifndef LTC_TEST
|
||||
return CRYPT_NOP;
|
||||
#else
|
||||
static const struct {
|
||||
char *msg;
|
||||
unsigned char hash[16];
|
||||
} tests[] = {
|
||||
{ "",
|
||||
{ 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
|
||||
0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e } },
|
||||
{ "a",
|
||||
{0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8,
|
||||
0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61 } },
|
||||
{ "abc",
|
||||
{ 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0,
|
||||
0xd6, 0x96, 0x3f, 0x7d, 0x28, 0xe1, 0x7f, 0x72 } },
|
||||
{ "message digest",
|
||||
{ 0xf9, 0x6b, 0x69, 0x7d, 0x7c, 0xb7, 0x93, 0x8d,
|
||||
0x52, 0x5a, 0x2f, 0x31, 0xaa, 0xf1, 0x61, 0xd0 } },
|
||||
{ "abcdefghijklmnopqrstuvwxyz",
|
||||
{ 0xc3, 0xfc, 0xd3, 0xd7, 0x61, 0x92, 0xe4, 0x00,
|
||||
0x7d, 0xfb, 0x49, 0x6c, 0xca, 0x67, 0xe1, 0x3b } },
|
||||
{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
|
||||
{ 0xd1, 0x74, 0xab, 0x98, 0xd2, 0x77, 0xd9, 0xf5,
|
||||
0xa5, 0x61, 0x1c, 0x2c, 0x9f, 0x41, 0x9d, 0x9f } },
|
||||
{ "12345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
||||
{ 0x57, 0xed, 0xf4, 0xa2, 0x2b, 0xe3, 0xc9, 0x55,
|
||||
0xac, 0x49, 0xda, 0x2e, 0x21, 0x07, 0xb6, 0x7a } },
|
||||
{ NULL, { 0 } }
|
||||
};
|
||||
|
||||
int i;
|
||||
unsigned char tmp[16];
|
||||
hash_state md;
|
||||
|
||||
for (i = 0; tests[i].msg != NULL; i++) {
|
||||
md5_init(&md);
|
||||
md5_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
|
||||
md5_done(&md, tmp);
|
||||
if (memcmp(tmp, tests[i].hash, 16) != 0) {
|
||||
return CRYPT_FAIL_TESTVECTOR;
|
||||
}
|
||||
}
|
||||
return CRYPT_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
83
mycrypt.h
Normal file
83
mycrypt.h
Normal file
@@ -0,0 +1,83 @@
|
||||
#ifndef CRYPT_H_
|
||||
#define CRYPT_H_
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* if there is a custom definition header file use it */
|
||||
#include <mycrypt_custom.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* version */
|
||||
#define CRYPT 0x0095
|
||||
#define SCRYPT "0.95"
|
||||
|
||||
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
|
||||
#define MAXBLOCKSIZE 128
|
||||
|
||||
/* descriptor table size */
|
||||
/* Dropbear change - this should be smaller, saves some size */
|
||||
#define TAB_SIZE 4
|
||||
|
||||
/* error codes [will be expanded in future releases] */
|
||||
enum {
|
||||
CRYPT_OK=0, /* Result OK */
|
||||
CRYPT_ERROR, /* Generic Error */
|
||||
CRYPT_NOP, /* Not a failure but no operation was performed */
|
||||
|
||||
CRYPT_INVALID_KEYSIZE, /* Invalid key size given */
|
||||
CRYPT_INVALID_ROUNDS, /* Invalid number of rounds */
|
||||
CRYPT_FAIL_TESTVECTOR, /* Algorithm failed test vectors */
|
||||
|
||||
CRYPT_BUFFER_OVERFLOW, /* Not enough space for output */
|
||||
CRYPT_INVALID_PACKET, /* Invalid input packet given */
|
||||
|
||||
CRYPT_INVALID_PRNGSIZE, /* Invalid number of bits for a PRNG */
|
||||
CRYPT_ERROR_READPRNG, /* Could not read enough from PRNG */
|
||||
|
||||
CRYPT_INVALID_CIPHER, /* Invalid cipher specified */
|
||||
CRYPT_INVALID_HASH, /* Invalid hash specified */
|
||||
CRYPT_INVALID_PRNG, /* Invalid PRNG specified */
|
||||
|
||||
CRYPT_MEM, /* Out of memory */
|
||||
|
||||
CRYPT_PK_TYPE_MISMATCH, /* Not equivalent types of PK keys */
|
||||
CRYPT_PK_NOT_PRIVATE, /* Requires a private PK key */
|
||||
|
||||
CRYPT_INVALID_ARG, /* Generic invalid argument */
|
||||
CRYPT_FILE_NOTFOUND, /* File Not Found */
|
||||
|
||||
CRYPT_PK_INVALID_TYPE, /* Invalid type of PK key */
|
||||
CRYPT_PK_INVALID_SYSTEM,/* Invalid PK system specified */
|
||||
CRYPT_PK_DUP, /* Duplicate key already in key ring */
|
||||
CRYPT_PK_NOT_FOUND, /* Key not found in keyring */
|
||||
CRYPT_PK_INVALID_SIZE, /* Invalid size input for PK parameters */
|
||||
|
||||
CRYPT_INVALID_PRIME_SIZE/* Invalid size of prime requested */
|
||||
};
|
||||
|
||||
#include <mycrypt_cfg.h>
|
||||
#include <mycrypt_macros.h>
|
||||
#include <mycrypt_cipher.h>
|
||||
#include <mycrypt_hash.h>
|
||||
#include <mycrypt_prng.h>
|
||||
#include <mycrypt_pk.h>
|
||||
#include <mycrypt_gf.h>
|
||||
#include <mycrypt_misc.h>
|
||||
#include <mycrypt_kr.h>
|
||||
#include <mycrypt_argchk.h>
|
||||
#include <mycrypt_pkcs.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CRYPT_H_ */
|
||||
|
||||
24
mycrypt_argchk.h
Normal file
24
mycrypt_argchk.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/* Defines the _ARGCHK macro used within the library */
|
||||
|
||||
/* ch1-01-1 */
|
||||
/* ARGTYPE is defined in mycrypt_cfg.h */
|
||||
#if ARGTYPE == 2 || defined(NDEBUG)
|
||||
|
||||
#define _ARGCHK(x)
|
||||
|
||||
#elif ARGTYPE == 0
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
/* this is the default LibTomCrypt macro */
|
||||
extern void crypt_argchk(char *v, char *s, int d);
|
||||
#define _ARGCHK(x) if (!(x)) { crypt_argchk(#x, __FILE__, __LINE__); }
|
||||
|
||||
#elif ARGTYPE == 1
|
||||
|
||||
/* fatal type of error */
|
||||
#define _ARGCHK(x) assert((x))
|
||||
|
||||
#endif
|
||||
/* ch1-01-1 */
|
||||
|
||||
78
mycrypt_cfg.h
Normal file
78
mycrypt_cfg.h
Normal file
@@ -0,0 +1,78 @@
|
||||
/* This is the build config file.
|
||||
*
|
||||
* With this you can setup what to inlcude/exclude automatically during any build. Just comment
|
||||
* out the line that #define's the word for the thing you want to remove. phew!
|
||||
*/
|
||||
|
||||
#ifndef MYCRYPT_CFG_H
|
||||
#define MYCRYPT_CFG_H
|
||||
|
||||
/* you can change how memory allocation works ... */
|
||||
extern void *XMALLOC(size_t n);
|
||||
extern void *REALLOC(void *p, size_t n);
|
||||
extern void *XCALLOC(size_t n, size_t s);
|
||||
extern void XFREE(void *p);
|
||||
|
||||
/* change the clock function too */
|
||||
extern clock_t XCLOCK(void);
|
||||
|
||||
/* ch1-01-1 */
|
||||
/* type of argument checking, 0=default, 1=fatal and 2=none */
|
||||
#define ARGTYPE 0
|
||||
/* ch1-01-1 */
|
||||
|
||||
/* Controls endianess and size of registers. Leave uncommented to get platform neutral [slower] code */
|
||||
/* detect x86-32 machines somewhat */
|
||||
#if defined(INTEL_CC) || (defined(_MSC_VER) && defined(WIN32)) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__)))
|
||||
#define ENDIAN_LITTLE
|
||||
#define ENDIAN_32BITWORD
|
||||
#endif
|
||||
|
||||
/* detects MIPS R5900 processors (PS2) */
|
||||
#if (defined(__R5900) || defined(R5900) || defined(__R5900__)) && (defined(_mips) || defined(__mips__) || defined(mips))
|
||||
#define ENDIAN_LITTLE
|
||||
#define ENDIAN_64BITWORD
|
||||
#endif
|
||||
|
||||
/* #define ENDIAN_LITTLE */
|
||||
/* #define ENDIAN_BIG */
|
||||
|
||||
/* #define ENDIAN_32BITWORD */
|
||||
/* #define ENDIAN_64BITWORD */
|
||||
|
||||
#if (defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE)) && !(defined(ENDIAN_32BITWORD) || defined(ENDIAN_64BITWORD))
|
||||
#error You must specify a word size as well as endianess in mycrypt_cfg.h
|
||||
#endif
|
||||
|
||||
#if !(defined(ENDIAN_BIG) || defined(ENDIAN_LITTLE))
|
||||
#define ENDIAN_NEUTRAL
|
||||
#endif
|
||||
|
||||
#ifdef YARROW
|
||||
#ifndef CTR
|
||||
#error YARROW requires CTR chaining mode to be defined!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* packet code */
|
||||
#if defined(MRSA) || defined(MDH) || defined(MECC)
|
||||
#define PACKET
|
||||
|
||||
/* size of a packet header in bytes */
|
||||
#define PACKET_SIZE 4
|
||||
|
||||
/* Section tags */
|
||||
#define PACKET_SECT_RSA 0
|
||||
#define PACKET_SECT_DH 1
|
||||
#define PACKET_SECT_ECC 2
|
||||
#define PACKET_SECT_DSA 3
|
||||
|
||||
/* Subsection Tags for the first three sections */
|
||||
#define PACKET_SUB_KEY 0
|
||||
#define PACKET_SUB_ENCRYPTED 1
|
||||
#define PACKET_SUB_SIGNED 2
|
||||
#define PACKET_SUB_ENC_KEY 3
|
||||
#endif
|
||||
|
||||
#endif /* MYCRYPT_CFG_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user