libtomcrypt, dep libtommath; replacing crypto++

This commit is contained in:
Glenn Maynard
2007-01-24 05:16:57 +00:00
parent 18cda05b5e
commit 86c2d3ff61
292 changed files with 31364 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
LibTomCrypt is public domain. As should all quality software be.
Tom St Denis
@@ -0,0 +1,760 @@
/* 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, [email protected], http://libtomcrypt.com
*/
/* 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 <[email protected]>
* @author Antoon Bosselaers <[email protected]>
* @author Paulo Barreto <[email protected]>
---
*/
/**
@file aes.c
Implementation of AES
*/
#include "tomcrypt.h"
#ifdef RIJNDAEL
#ifndef ENCRYPT_ONLY
#define SETUP rijndael_setup
#define ECB_ENC rijndael_ecb_encrypt
#define ECB_DEC rijndael_ecb_decrypt
#define ECB_DONE rijndael_done
#define ECB_TEST rijndael_test
#define ECB_KS rijndael_keysize
const struct ltc_cipher_descriptor rijndael_desc =
{
"rijndael",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
const struct ltc_cipher_descriptor aes_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#else
#define SETUP rijndael_enc_setup
#define ECB_ENC rijndael_enc_ecb_encrypt
#define ECB_KS rijndael_enc_keysize
#define ECB_DONE rijndael_enc_done
const struct ltc_cipher_descriptor rijndael_enc_desc =
{
"rijndael",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
const struct ltc_cipher_descriptor aes_enc_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif
#include "aes_tab.c"
static ulong32 setup_mix(ulong32 temp)
{
return (Te4_3[byte(temp, 2)]) ^
(Te4_2[byte(temp, 1)]) ^
(Te4_1[byte(temp, 0)]) ^
(Te4_0[byte(temp, 3)]);
}
#ifndef ENCRYPT_ONLY
#ifdef LTC_SMALL_CODE
static ulong32 setup_mix2(ulong32 temp)
{
return Td0(255 & Te4[byte(temp, 3)]) ^
Td1(255 & Te4[byte(temp, 2)]) ^
Td2(255 & Te4[byte(temp, 1)]) ^
Td3(255 & Te4[byte(temp, 0)]);
}
#endif
#endif
/**
Initialize the AES (Rijndael) block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int i, j;
ulong32 temp, *rk;
#ifndef ENCRYPT_ONLY
ulong32 *rrk;
#endif
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE;
}
if (num_rounds != 0 && num_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] ^ setup_mix(temp) ^ 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] ^ setup_mix(temp) ^ 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] ^ setup_mix(temp) ^ 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] ^ setup_mix(RORc(temp, 8));
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 */
return CRYPT_ERROR;
}
#ifndef ENCRYPT_ONLY
/* 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 LTC_SMALL_CODE
temp = rrk[0];
rk[0] = setup_mix2(temp);
temp = rrk[1];
rk[1] = setup_mix2(temp);
temp = rrk[2];
rk[2] = setup_mix2(temp);
temp = rrk[3];
rk[3] = setup_mix2(temp);
#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;
#endif /* ENCRYPT_ONLY */
return CRYPT_OK;
}
/**
Encrypts a block of text with AES
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#else
int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
#endif
{
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
int Nr, r;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_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];
#ifdef LTC_SMALL_CODE
for (r = 0; ; r++) {
rk += 4;
t0 =
Te0(byte(s0, 3)) ^
Te1(byte(s1, 2)) ^
Te2(byte(s2, 1)) ^
Te3(byte(s3, 0)) ^
rk[0];
t1 =
Te0(byte(s1, 3)) ^
Te1(byte(s2, 2)) ^
Te2(byte(s3, 1)) ^
Te3(byte(s0, 0)) ^
rk[1];
t2 =
Te0(byte(s2, 3)) ^
Te1(byte(s3, 2)) ^
Te2(byte(s0, 1)) ^
Te3(byte(s1, 0)) ^
rk[2];
t3 =
Te0(byte(s3, 3)) ^
Te1(byte(s0, 2)) ^
Te2(byte(s1, 1)) ^
Te3(byte(s2, 0)) ^
rk[3];
if (r == Nr-2) {
break;
}
s0 = t0; s1 = t1; s2 = t2; s3 = t3;
}
rk += 4;
#else
/*
* Nr - 1 full rounds:
*/
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];
}
#endif
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Te4_3[byte(t0, 3)]) ^
(Te4_2[byte(t1, 2)]) ^
(Te4_1[byte(t2, 1)]) ^
(Te4_0[byte(t3, 0)]) ^
rk[0];
STORE32H(s0, ct);
s1 =
(Te4_3[byte(t1, 3)]) ^
(Te4_2[byte(t2, 2)]) ^
(Te4_1[byte(t3, 1)]) ^
(Te4_0[byte(t0, 0)]) ^
rk[1];
STORE32H(s1, ct+4);
s2 =
(Te4_3[byte(t2, 3)]) ^
(Te4_2[byte(t3, 2)]) ^
(Te4_1[byte(t0, 1)]) ^
(Te4_0[byte(t1, 0)]) ^
rk[2];
STORE32H(s2, ct+8);
s3 =
(Te4_3[byte(t3, 3)]) ^
(Te4_2[byte(t0, 2)]) ^
(Te4_1[byte(t1, 1)]) ^
(Te4_0[byte(t2, 0)]) ^
rk[3];
STORE32H(s3, ct+12);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int ECB_ENC(const unsigned char *pt, unsigned char *ct, symmetric_key *skey)
{
int err = _rijndael_ecb_encrypt(pt, ct, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
return err;
}
#endif
#ifndef ENCRYPT_ONLY
/**
Decrypts a block of text with AES
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
#ifdef LTC_CLEAN_STACK
static int _rijndael_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#else
int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
#endif
{
ulong32 s0, s1, s2, s3, t0, t1, t2, t3, *rk;
int Nr, r;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_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];
#ifdef LTC_SMALL_CODE
for (r = 0; ; r++) {
rk += 4;
t0 =
Td0(byte(s0, 3)) ^
Td1(byte(s3, 2)) ^
Td2(byte(s2, 1)) ^
Td3(byte(s1, 0)) ^
rk[0];
t1 =
Td0(byte(s1, 3)) ^
Td1(byte(s0, 2)) ^
Td2(byte(s3, 1)) ^
Td3(byte(s2, 0)) ^
rk[1];
t2 =
Td0(byte(s2, 3)) ^
Td1(byte(s1, 2)) ^
Td2(byte(s0, 1)) ^
Td3(byte(s3, 0)) ^
rk[2];
t3 =
Td0(byte(s3, 3)) ^
Td1(byte(s2, 2)) ^
Td2(byte(s1, 1)) ^
Td3(byte(s0, 0)) ^
rk[3];
if (r == Nr-2) {
break;
}
s0 = t0; s1 = t1; s2 = t2; s3 = t3;
}
rk += 4;
#else
/*
* Nr - 1 full rounds:
*/
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];
}
#endif
/*
* apply last round and
* map cipher state to byte array block:
*/
s0 =
(Td4[byte(t0, 3)] & 0xff000000) ^
(Td4[byte(t3, 2)] & 0x00ff0000) ^
(Td4[byte(t2, 1)] & 0x0000ff00) ^
(Td4[byte(t1, 0)] & 0x000000ff) ^
rk[0];
STORE32H(s0, pt);
s1 =
(Td4[byte(t1, 3)] & 0xff000000) ^
(Td4[byte(t0, 2)] & 0x00ff0000) ^
(Td4[byte(t3, 1)] & 0x0000ff00) ^
(Td4[byte(t2, 0)] & 0x000000ff) ^
rk[1];
STORE32H(s1, pt+4);
s2 =
(Td4[byte(t2, 3)] & 0xff000000) ^
(Td4[byte(t1, 2)] & 0x00ff0000) ^
(Td4[byte(t0, 1)] & 0x0000ff00) ^
(Td4[byte(t3, 0)] & 0x000000ff) ^
rk[2];
STORE32H(s2, pt+8);
s3 =
(Td4[byte(t3, 3)] & 0xff000000) ^
(Td4[byte(t2, 2)] & 0x00ff0000) ^
(Td4[byte(t1, 1)] & 0x0000ff00) ^
(Td4[byte(t0, 0)] & 0x000000ff) ^
rk[3];
STORE32H(s3, pt+12);
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
int ECB_DEC(const unsigned char *ct, unsigned char *pt, symmetric_key *skey)
{
int err = _rijndael_ecb_decrypt(ct, pt, skey);
burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
return err;
}
#endif
/**
Performs a self-test of the AES block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int ECB_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 (XMEMCMP(tmp[0], tests[i].ct, 16) || XMEMCMP(tmp[1], tests[i].pt, 16)) {
#if 0
printf("\n\nTest %d failed\n", i);
if (XMEMCMP(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
}
#endif /* ENCRYPT_ONLY */
/** Terminate the context
@param skey The scheduled key
*/
void ECB_DONE(symmetric_key *skey)
{
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int ECB_KS(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16)
return CRYPT_INVALID_KEYSIZE;
if (*keysize < 24) {
*keysize = 16;
return CRYPT_OK;
} else if (*keysize < 32) {
*keysize = 24;
return CRYPT_OK;
} else {
*keysize = 32;
return CRYPT_OK;
}
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,69 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file hash_memory.c
Hash memory helper, Tom St Denis
*/
/**
Hash a block of memory and store the digest.
@param hash The index of the hash you wish to use
@param in The data you wish to hash
@param inlen The length of the data to hash (octets)
@param out [out] Where to store the digest
@param outlen [in/out] Max size and resulting size of the digest
@return CRYPT_OK if successful
*/
int hash_memory(int hash, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen)
{
hash_state *md;
int err;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
return err;
}
if (*outlen < hash_descriptor[hash].hashsize) {
*outlen = hash_descriptor[hash].hashsize;
return CRYPT_BUFFER_OVERFLOW;
}
md = XMALLOC(sizeof(hash_state));
if (md == NULL) {
return CRYPT_MEM;
}
if ((err = hash_descriptor[hash].init(md)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hash_descriptor[hash].process(md, in, inlen)) != CRYPT_OK) {
goto LBL_ERR;
}
err = hash_descriptor[hash].done(md, out);
*outlen = hash_descriptor[hash].hashsize;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
XFREE(md);
return err;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
+368
View File
@@ -0,0 +1,368 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file md5.c
MD5 hash function by Tom St Denis
*/
#ifdef MD5
const struct ltc_hash_descriptor md5_desc =
{
"md5",
3,
16,
64,
/* OID */
{ 1, 2, 840, 113549, 2, 5, },
6,
&md5_init,
&md5_process,
&md5_done,
&md5_test,
NULL
};
#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)))
#ifdef LTC_SMALL_CODE
#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;
static const unsigned char Worder[64] = {
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
1,6,11,0,5,10,15,4,9,14,3,8,13,2,7,12,
5,8,11,14,1,4,7,10,13,0,3,6,9,12,15,2,
0,7,14,5,12,3,10,1,8,15,6,13,4,11,2,9
};
static const unsigned char Rorder[64] = {
7,12,17,22,7,12,17,22,7,12,17,22,7,12,17,22,
5,9,14,20,5,9,14,20,5,9,14,20,5,9,14,20,
4,11,16,23,4,11,16,23,4,11,16,23,4,11,16,23,
6,10,15,21,6,10,15,21,6,10,15,21,6,10,15,21
};
static const ulong32 Korder[64] = {
0xd76aa478UL, 0xe8c7b756UL, 0x242070dbUL, 0xc1bdceeeUL, 0xf57c0fafUL, 0x4787c62aUL, 0xa8304613UL, 0xfd469501UL,
0x698098d8UL, 0x8b44f7afUL, 0xffff5bb1UL, 0x895cd7beUL, 0x6b901122UL, 0xfd987193UL, 0xa679438eUL, 0x49b40821UL,
0xf61e2562UL, 0xc040b340UL, 0x265e5a51UL, 0xe9b6c7aaUL, 0xd62f105dUL, 0x02441453UL, 0xd8a1e681UL, 0xe7d3fbc8UL,
0x21e1cde6UL, 0xc33707d6UL, 0xf4d50d87UL, 0x455a14edUL, 0xa9e3e905UL, 0xfcefa3f8UL, 0x676f02d9UL, 0x8d2a4c8aUL,
0xfffa3942UL, 0x8771f681UL, 0x6d9d6122UL, 0xfde5380cUL, 0xa4beea44UL, 0x4bdecfa9UL, 0xf6bb4b60UL, 0xbebfbc70UL,
0x289b7ec6UL, 0xeaa127faUL, 0xd4ef3085UL, 0x04881d05UL, 0xd9d4d039UL, 0xe6db99e5UL, 0x1fa27cf8UL, 0xc4ac5665UL,
0xf4292244UL, 0x432aff97UL, 0xab9423a7UL, 0xfc93a039UL, 0x655b59c3UL, 0x8f0ccc92UL, 0xffeff47dUL, 0x85845dd1UL,
0x6fa87e4fUL, 0xfe2ce6e0UL, 0xa3014314UL, 0x4e0811a1UL, 0xf7537e82UL, 0xbd3af235UL, 0x2ad7d2bbUL, 0xeb86d391UL
};
#else
#define FF(a,b,c,d,M,s,t) \
a = (a + F(b,c,d) + M + t); a = ROLc(a, s) + b;
#define GG(a,b,c,d,M,s,t) \
a = (a + G(b,c,d) + M + t); a = ROLc(a, s) + b;
#define HH(a,b,c,d,M,s,t) \
a = (a + H(b,c,d) + M + t); a = ROLc(a, s) + b;
#define II(a,b,c,d,M,s,t) \
a = (a + I(b,c,d) + M + t); a = ROLc(a, s) + b;
#endif
#ifdef LTC_CLEAN_STACK
static int _md5_compress(hash_state *md, unsigned char *buf)
#else
static int md5_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 i, W[16], a, b, c, d;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
/* 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];
#ifdef LTC_SMALL_CODE
for (i = 0; i < 16; ++i) {
FF(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 32; ++i) {
GG(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 48; ++i) {
HH(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
for (; i < 64; ++i) {
II(a,b,c,d,W[Worder[i]],Rorder[i],Korder[i]);
t = d; d = c; c = b; b = a; a = t;
}
#else
FF(a,b,c,d,W[0],7,0xd76aa478UL)
FF(d,a,b,c,W[1],12,0xe8c7b756UL)
FF(c,d,a,b,W[2],17,0x242070dbUL)
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)
#endif
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;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int md5_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _md5_compress(md, buf);
burn_stack(sizeof(ulong32) * 21);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int md5_init(hash_state * md)
{
LTC_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;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(md5_process, md5_compress, md5, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (16 bytes)
@return CRYPT_OK if successful
*/
int md5_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != 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], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
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 (XMEMCMP(tmp, tests[i].hash, 16) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
+288
View File
@@ -0,0 +1,288 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file sha1.c
SHA1 code by Tom St Denis
*/
#ifdef SHA1
const struct ltc_hash_descriptor sha1_desc =
{
"sha1",
2,
20,
64,
/* OID */
{ 1, 3, 14, 3, 2, 26, },
6,
&sha1_init,
&sha1_process,
&sha1_done,
&sha1_test,
NULL
};
#define F0(x,y,z) (z ^ (x & (y ^ z)))
#define F1(x,y,z) (x ^ y ^ z)
#define F2(x,y,z) ((x & y) | (z & (x | y)))
#define F3(x,y,z) (x ^ y ^ z)
#ifdef LTC_CLEAN_STACK
static int _sha1_compress(hash_state *md, unsigned char *buf)
#else
static int sha1_compress(hash_state *md, unsigned char *buf)
#endif
{
ulong32 a,b,c,d,e,W[80],i;
#ifdef LTC_SMALL_CODE
ulong32 t;
#endif
/* copy the state into 512-bits into W[0..15] */
for (i = 0; i < 16; i++) {
LOAD32H(W[i], buf + (4*i));
}
/* copy state */
a = md->sha1.state[0];
b = md->sha1.state[1];
c = md->sha1.state[2];
d = md->sha1.state[3];
e = md->sha1.state[4];
/* expand it */
for (i = 16; i < 80; i++) {
W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
}
/* compress */
/* round one */
#define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
#define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
#define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
#define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
#ifdef LTC_SMALL_CODE
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 40; ) {
FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 60; ) {
FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
for (; i < 80; ) {
FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
}
#else
for (i = 0; i < 20; ) {
FF0(a,b,c,d,e,i++);
FF0(e,a,b,c,d,i++);
FF0(d,e,a,b,c,i++);
FF0(c,d,e,a,b,i++);
FF0(b,c,d,e,a,i++);
}
/* round two */
for (; i < 40; ) {
FF1(a,b,c,d,e,i++);
FF1(e,a,b,c,d,i++);
FF1(d,e,a,b,c,i++);
FF1(c,d,e,a,b,i++);
FF1(b,c,d,e,a,i++);
}
/* round three */
for (; i < 60; ) {
FF2(a,b,c,d,e,i++);
FF2(e,a,b,c,d,i++);
FF2(d,e,a,b,c,i++);
FF2(c,d,e,a,b,i++);
FF2(b,c,d,e,a,i++);
}
/* round four */
for (; i < 80; ) {
FF3(a,b,c,d,e,i++);
FF3(e,a,b,c,d,i++);
FF3(d,e,a,b,c,i++);
FF3(c,d,e,a,b,i++);
FF3(b,c,d,e,a,i++);
}
#endif
#undef FF0
#undef FF1
#undef FF2
#undef FF3
/* store */
md->sha1.state[0] = md->sha1.state[0] + a;
md->sha1.state[1] = md->sha1.state[1] + b;
md->sha1.state[2] = md->sha1.state[2] + c;
md->sha1.state[3] = md->sha1.state[3] + d;
md->sha1.state[4] = md->sha1.state[4] + e;
return CRYPT_OK;
}
#ifdef LTC_CLEAN_STACK
static int sha1_compress(hash_state *md, unsigned char *buf)
{
int err;
err = _sha1_compress(md, buf);
burn_stack(sizeof(ulong32) * 87);
return err;
}
#endif
/**
Initialize the hash state
@param md The hash state you wish to initialize
@return CRYPT_OK if successful
*/
int sha1_init(hash_state * md)
{
LTC_ARGCHK(md != NULL);
md->sha1.state[0] = 0x67452301UL;
md->sha1.state[1] = 0xefcdab89UL;
md->sha1.state[2] = 0x98badcfeUL;
md->sha1.state[3] = 0x10325476UL;
md->sha1.state[4] = 0xc3d2e1f0UL;
md->sha1.curlen = 0;
md->sha1.length = 0;
return CRYPT_OK;
}
/**
Process a block of memory though the hash
@param md The hash state
@param in The data to hash
@param inlen The length of the data (octets)
@return CRYPT_OK if successful
*/
HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
/**
Terminate the hash to get the digest
@param md The hash state
@param out [out] The destination of the hash (20 bytes)
@return CRYPT_OK if successful
*/
int sha1_done(hash_state * md, unsigned char *out)
{
int i;
LTC_ARGCHK(md != NULL);
LTC_ARGCHK(out != NULL);
if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
return CRYPT_INVALID_ARG;
}
/* increase the length of the message */
md->sha1.length += md->sha1.curlen * 8;
/* append the '1' bit */
md->sha1.buf[md->sha1.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->sha1.curlen > 56) {
while (md->sha1.curlen < 64) {
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
}
sha1_compress(md, md->sha1.buf);
md->sha1.curlen = 0;
}
/* pad upto 56 bytes of zeroes */
while (md->sha1.curlen < 56) {
md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
}
/* store length */
STORE64H(md->sha1.length, md->sha1.buf+56);
sha1_compress(md, md->sha1.buf);
/* copy output */
for (i = 0; i < 5; i++) {
STORE32H(md->sha1.state[i], out+(4*i));
}
#ifdef LTC_CLEAN_STACK
zeromem(md, sizeof(hash_state));
#endif
return CRYPT_OK;
}
/**
Self-test the hash
@return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
*/
int sha1_test(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
static const struct {
char *msg;
unsigned char hash[20];
} tests[] = {
{ "abc",
{ 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
0x9c, 0xd0, 0xd8, 0x9d }
},
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
{ 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
0xE5, 0x46, 0x70, 0xF1 }
}
};
int i;
unsigned char tmp[20];
hash_state md;
for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) {
sha1_init(&md);
sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
sha1_done(&md, tmp);
if (XMEMCMP(tmp, tests[i].hash, 20) != 0) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,483 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#define DESC_DEF_ONLY
#include "tomcrypt.h"
#ifdef LTM_DESC
#include "libtommath/tommath.h"
static const struct {
int mpi_code, ltc_code;
} mpi_to_ltc_codes[] = {
{ MP_OKAY , CRYPT_OK},
{ MP_MEM , CRYPT_MEM},
{ MP_VAL , CRYPT_INVALID_ARG},
};
/**
Convert a MPI error to a LTC error (Possibly the most powerful function ever! Oh wait... no)
@param err The error to convert
@return The equivalent LTC error code or CRYPT_ERROR if none found
*/
static int mpi_to_ltc_error(int err)
{
int x;
for (x = 0; x < (int)(sizeof(mpi_to_ltc_codes)/sizeof(mpi_to_ltc_codes[0])); x++) {
if (err == mpi_to_ltc_codes[x].mpi_code) {
return mpi_to_ltc_codes[x].ltc_code;
}
}
return CRYPT_ERROR;
}
static int init(void **a)
{
int err;
LTC_ARGCHK(a != NULL);
*a = XCALLOC(1, sizeof(mp_int));
if (*a == NULL) {
return CRYPT_MEM;
}
if ((err = mpi_to_ltc_error(mp_init(*a))) != CRYPT_OK) {
XFREE(*a);
}
return err;
}
static void deinit(void *a)
{
LTC_ARGCHKVD(a != NULL);
mp_clear(a);
XFREE(a);
}
static int neg(void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_neg(a, b));
}
static int copy(void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_copy(a, b));
}
static int init_copy(void **a, void *b)
{
if (init(a) != CRYPT_OK) {
return CRYPT_MEM;
}
return copy(b, *a);
}
/* ---- trivial ---- */
static int set_int(void *a, unsigned long b)
{
LTC_ARGCHK(a != NULL);
return mpi_to_ltc_error(mp_set_int(a, b));
}
static unsigned long get_int(void *a)
{
LTC_ARGCHK(a != NULL);
return mp_get_int(a);
}
static unsigned long get_digit(void *a, int n)
{
mp_int *A;
LTC_ARGCHK(a != NULL);
A = a;
return (n >= A->used || n < 0) ? 0 : A->dp[n];
}
static int get_digit_count(void *a)
{
mp_int *A;
LTC_ARGCHK(a != NULL);
A = a;
return A->used;
}
static int compare(void *a, void *b)
{
int ret;
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
ret = mp_cmp(a, b);
switch (ret) {
case MP_LT: return LTC_MP_LT;
case MP_EQ: return LTC_MP_EQ;
case MP_GT: return LTC_MP_GT;
}
return 0;
}
static int compare_d(void *a, unsigned long b)
{
int ret;
LTC_ARGCHK(a != NULL);
ret = mp_cmp_d(a, b);
switch (ret) {
case MP_LT: return LTC_MP_LT;
case MP_EQ: return LTC_MP_EQ;
case MP_GT: return LTC_MP_GT;
}
return 0;
}
static int count_bits(void *a)
{
LTC_ARGCHK(a != NULL);
return mp_count_bits(a);
}
static int count_lsb_bits(void *a)
{
LTC_ARGCHK(a != NULL);
return mp_cnt_lsb(a);
}
static int twoexpt(void *a, int n)
{
LTC_ARGCHK(a != NULL);
return mpi_to_ltc_error(mp_2expt(a, n));
}
/* ---- conversions ---- */
/* read ascii string */
static int read_radix(void *a, const char *b, int radix)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_read_radix(a, b, radix));
}
/* write one */
static int write_radix(void *a, char *b, int radix)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_toradix(a, b, radix));
}
/* get size as unsigned char string */
static unsigned long unsigned_size(void *a)
{
LTC_ARGCHK(a != NULL);
return mp_unsigned_bin_size(a);
}
/* store */
static int unsigned_write(void *a, unsigned char *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_to_unsigned_bin(a, b));
}
/* read */
static int unsigned_read(void *a, unsigned char *b, unsigned long len)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_read_unsigned_bin(a, b, len));
}
/* add */
static int add(void *a, void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_add(a, b, c));
}
static int addi(void *a, unsigned long b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_add_d(a, b, c));
}
/* sub */
static int sub(void *a, void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_sub(a, b, c));
}
static int subi(void *a, unsigned long b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_sub_d(a, b, c));
}
/* mul */
static int mul(void *a, void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_mul(a, b, c));
}
static int muli(void *a, unsigned long b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_mul_d(a, b, c));
}
/* sqr */
static int sqr(void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_sqr(a, b));
}
/* div */
static int divide(void *a, void *b, void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_div(a, b, c, d));
}
static int div_2(void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_div_2(a, b));
}
/* modi */
static int modi(void *a, unsigned long b, unsigned long *c)
{
mp_digit tmp;
int err;
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(c != NULL);
if ((err = mpi_to_ltc_error(mp_mod_d(a, b, &tmp))) != CRYPT_OK) {
return err;
}
*c = tmp;
return CRYPT_OK;
}
/* gcd */
static int gcd(void *a, void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_gcd(a, b, c));
}
/* lcm */
static int lcm(void *a, void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_lcm(a, b, c));
}
static int mulmod(void *a, void *b, void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
LTC_ARGCHK(d != NULL);
return mpi_to_ltc_error(mp_mulmod(a,b,c,d));
}
static int sqrmod(void *a, void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_sqrmod(a,b,c));
}
/* invmod */
static int invmod(void *a, void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_invmod(a, b, c));
}
/* setup */
static int montgomery_setup(void *a, void **b)
{
int err;
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
*b = XCALLOC(1, sizeof(mp_digit));
if (*b == NULL) {
return CRYPT_MEM;
}
if ((err = mpi_to_ltc_error(mp_montgomery_setup(a, (mp_digit *)*b))) != CRYPT_OK) {
XFREE(*b);
}
return err;
}
/* get normalization value */
static int montgomery_normalization(void *a, void *b)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
return mpi_to_ltc_error(mp_montgomery_calc_normalization(a, b));
}
/* reduce */
static int montgomery_reduce(void *a, void *b, void *c)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
return mpi_to_ltc_error(mp_montgomery_reduce(a, b, *((mp_digit *)c)));
}
/* clean up */
static void montgomery_deinit(void *a)
{
XFREE(a);
}
static int exptmod(void *a, void *b, void *c, void *d)
{
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
LTC_ARGCHK(c != NULL);
LTC_ARGCHK(d != NULL);
return mpi_to_ltc_error(mp_exptmod(a,b,c,d));
}
static int isprime(void *a, int *b)
{
int err;
LTC_ARGCHK(a != NULL);
LTC_ARGCHK(b != NULL);
err = mpi_to_ltc_error(mp_prime_is_prime(a, 8, b));
*b = (*b == MP_YES) ? LTC_MP_YES : LTC_MP_NO;
return err;
}
const ltc_math_descriptor ltm_desc = {
"LibTomMath",
(int)DIGIT_BIT,
&init,
&init_copy,
&deinit,
&neg,
&copy,
&set_int,
&get_int,
&get_digit,
&get_digit_count,
&compare,
&compare_d,
&count_bits,
&count_lsb_bits,
&twoexpt,
&read_radix,
&write_radix,
&unsigned_size,
&unsigned_write,
&unsigned_read,
&add,
&addi,
&sub,
&subi,
&mul,
&muli,
&sqr,
&divide,
&div_2,
&modi,
&gcd,
&lcm,
&mulmod,
&sqrmod,
&invmod,
&montgomery_setup,
&montgomery_normalization,
&montgomery_reduce,
&montgomery_deinit,
&exptmod,
&isprime,
#ifdef MECC
#ifdef MECC_FP
&ltc_ecc_fp_mulmod,
#else
&ltc_ecc_mulmod,
#endif
&ltc_ecc_projective_add_point,
&ltc_ecc_projective_dbl_point,
&ltc_ecc_map,
#ifdef LTC_ECC_SHAMIR
#ifdef MECC_FP
&ltc_ecc_fp_mul2add,
#else
&ltc_ecc_mul2add,
#endif /* MECC_FP */
#else
NULL,
#endif /* LTC_ECC_SHAMIR */
#else
NULL, NULL, NULL, NULL, NULL,
#endif /* MECC */
#ifdef MRSA
&rsa_make_key,
&rsa_exptmod,
#else
NULL, NULL
#endif
};
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,61 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
#ifdef MPI
#include <stdarg.h>
int ltc_init_multi(void **a, ...)
{
void **cur = a;
int np = 0;
va_list args;
va_start(args, a);
while (cur != NULL) {
if (mp_init(cur) != CRYPT_OK) {
/* failed */
va_list clean_list;
va_start(clean_list, a);
cur = a;
while (np--) {
mp_clear(*cur);
cur = va_arg(clean_list, void**);
}
va_end(clean_list);
return CRYPT_MEM;
}
++np;
cur = va_arg(args, void**);
}
va_end(args);
return CRYPT_OK;
}
void ltc_deinit_multi(void *a, ...)
{
void *cur = a;
va_list args;
va_start(args, a);
while (cur != NULL) {
mp_clear(cur);
cur = va_arg(args, void *);
}
va_end(args);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file rand_prime.c
Generate a random prime, Tom St Denis
*/
#define USE_BBS 1
int rand_prime(void *N, long len, prng_state *prng, int wprng)
{
int err, res, type;
unsigned char *buf;
LTC_ARGCHK(N != NULL);
/* get type */
if (len < 0) {
type = USE_BBS;
len = -len;
} else {
type = 0;
}
/* allow sizes between 2 and 512 bytes for a prime size */
if (len < 2 || len > 512) {
return CRYPT_INVALID_PRIME_SIZE;
}
/* valid PRNG? Better be! */
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
return err;
}
/* allocate buffer to work with */
buf = XCALLOC(1, len);
if (buf == NULL) {
return CRYPT_MEM;
}
do {
/* generate value */
if (prng_descriptor[wprng].read(buf, len, prng) != (unsigned long)len) {
XFREE(buf);
return CRYPT_ERROR_READPRNG;
}
/* munge bits */
buf[0] |= 0x80 | 0x40;
buf[len-1] |= 0x01 | ((type & USE_BBS) ? 0x02 : 0x00);
/* load value */
if ((err = mp_read_unsigned_bin(N, buf, len)) != CRYPT_OK) {
XFREE(buf);
return err;
}
/* test */
if ((err = mp_prime_is_prime(N, 8, &res)) != CRYPT_OK) {
XFREE(buf);
return err;
}
} while (res == LTC_MP_NO);
#ifdef LTC_CLEAN_STACK
zeromem(buf, len);
#endif
XFREE(buf);
return CRYPT_OK;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,104 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file base64_decode.c
Compliant base64 code donated by Wayne Scott ([email protected])
*/
#ifdef BASE64
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 };
/**
base64 decode a block of memory
@param in The base64 data to decode
@param inlen The length of the base64 data
@param out [out] The destination of the binary decoded data
@param outlen [in/out] The max size and resulting size of the decoded data
@return CRYPT_OK if successful
*/
int base64_decode(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long t, x, y, z;
unsigned char c;
int g;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
g = 3;
for (x = y = z = t = 0; x < inlen; x++) {
c = map[in[x]&0xFF];
if (c == 255) continue;
/* the final = symbols are read and used to trim the remaining bytes */
if (c == 254) {
c = 0;
/* prevent g < 0 which would potentially allow an overflow later */
if (--g < 0) {
return CRYPT_INVALID_PACKET;
}
} else if (g != 3) {
/* we only allow = to be at the end */
return CRYPT_INVALID_PACKET;
}
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
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,81 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file base64_encode.c
Compliant base64 encoder donated by Wayne Scott ([email protected])
*/
#ifdef BASE64
static const char *codes =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/**
base64 Encode a buffer (NUL terminated)
@param in The input buffer to encode
@param inlen The length of the input buffer
@param out [out] The destination of the base64 encoded data
@param outlen [in/out] The max size and resulting size
@return CRYPT_OK if successful
*/
int base64_encode(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long i, len2, leven;
unsigned char *p;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* valid output size ? */
len2 = 4 * ((inlen + 2) / 3);
if (*outlen < len2 + 1) {
*outlen = len2 + 1;
return CRYPT_BUFFER_OVERFLOW;
}
p = out;
leven = 3*(inlen / 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 < inlen) {
unsigned a = in[0];
unsigned b = (i+1 < inlen) ? in[1] : 0;
*p++ = codes[(a >> 2) & 0x3F];
*p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F];
*p++ = (i+1 < inlen) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=';
*p++ = '=';
}
/* append a NULL byte */
*p = '\0';
/* return ok */
*outlen = p - out;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file burn_stack.c
Burn stack, Tom St Denis
*/
/**
Burn some stack memory
@param len amount of stack to burn in bytes
*/
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));
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,364 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt.c
Build strings, Tom St Denis
*/
const char *crypt_build_settings =
"LibTomCrypt " SCRYPT " (Tom St Denis, [email protected])\n"
"LibTomCrypt is public domain software.\n"
"Built on " __DATE__ " at " __TIME__ "\n\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(LTC_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) && defined(TWOFISH_ALL_TABLES)
"(small, tables, all_tables)\n"
#elif defined(TWOFISH_SMALL) && defined(TWOFISH_TABLES)
"(small, tables)\n"
#elif defined(TWOFISH_SMALL) && defined(TWOFISH_ALL_TABLES)
"(small, all_tables)\n"
#elif defined(TWOFISH_TABLES) && defined(TWOFISH_ALL_TABLES)
"(tables, all_tables)\n"
#elif defined(TWOFISH_SMALL)
"(small)\n"
#elif defined(TWOFISH_TABLES)
"(tables)\n"
#elif defined(TWOFISH_ALL_TABLES)
"(all_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
#if defined(KHAZAD)
" Khazad\n"
#endif
#if defined(ANUBIS)
" Anubis "
#endif
#if defined(ANUBIS_TWEAK)
" (tweaked)"
#endif
"\n"
#if defined(KSEED)
" KSEED\n"
#endif
#if defined(LTC_KASUMI)
" KASUMI\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
#if defined(WHIRLPOOL)
" WHIRLPOOL\n"
#endif
#if defined(CHC_HASH)
" CHC_HASH \n"
#endif
"\nBlock Chaining Modes:\n"
#if defined(LTC_CFB_MODE)
" CFB\n"
#endif
#if defined(LTC_OFB_MODE)
" OFB\n"
#endif
#if defined(LTC_ECB_MODE)
" ECB\n"
#endif
#if defined(LTC_CBC_MODE)
" CBC\n"
#endif
#if defined(LTC_CTR_MODE)
" CTR "
#endif
#if defined(LTC_CTR_OLD)
" (CTR_OLD) "
#endif
"\n"
#if defined(LRW_MODE)
" LRW_MODE"
#if defined(LRW_TABLES)
" (LRW_TABLES) "
#endif
"\n"
#endif
#if defined(LTC_F8_MODE)
" F8 MODE\n"
#endif
"\nMACs:\n"
#if defined(LTC_HMAC)
" HMAC\n"
#endif
#if defined(LTC_OMAC)
" OMAC\n"
#endif
#if defined(LTC_PMAC)
" PMAC\n"
#endif
#if defined(PELICAN)
" PELICAN\n"
#endif
#if defined(LTC_XCBC)
" XCBC-MAC\n"
#endif
#if defined(LTC_F9_MODE)
" F9-MAC\n"
#endif
"\nENC + AUTH modes:\n"
#if defined(EAX_MODE)
" EAX_MODE\n"
#endif
#if defined(OCB_MODE)
" OCB_MODE\n"
#endif
#if defined(CCM_MODE)
" CCM_MODE\n"
#endif
#if defined(GCM_MODE)
" GCM_MODE "
#endif
#if defined(GCM_TABLES)
" (GCM_TABLES) "
#endif
"\n"
"\nPRNG:\n"
#if defined(YARROW)
" Yarrow\n"
#endif
#if defined(SPRNG)
" SPRNG\n"
#endif
#if defined(RC4)
" RC4\n"
#endif
#if defined(FORTUNA)
" Fortuna\n"
#endif
#if defined(SOBER128)
" SOBER128\n"
#endif
"\nPK Algs:\n"
#if defined(MRSA)
" RSA \n"
#endif
#if defined(MECC)
" ECC\n"
#endif
#if defined(MDSA)
" DSA\n"
#endif
#if defined(MKAT)
" Katja\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
#if defined(__x86_64__)
" x86-64 detected.\n"
#endif
#if defined(LTC_PPC32)
" LTC_PPC32 defined \n"
#endif
"\nVarious others: "
#if defined(BASE64)
" BASE64 "
#endif
#if defined(MPI)
" MPI "
#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
#if defined(LTC_SMALL_CODE)
" LTC_SMALL_CODE "
#endif
#if defined(LTC_NO_FILE)
" LTC_NO_FILE "
#endif
#if defined(LTC_DER)
" LTC_DER "
#endif
#if defined(LTC_FAST)
" LTC_FAST "
#endif
#if defined(LTC_NO_FAST)
" LTC_NO_FAST "
#endif
#if defined(LTC_NO_BSWAP)
" LTC_NO_BSWAP "
#endif
#if defined(LTC_NO_ASM)
" LTC_NO_ASM "
#endif
#if defined(LTC_NO_TEST)
" LTC_NO_TEST "
#endif
#if defined(LTC_NO_TABLES)
" LTC_NO_TABLES "
#endif
#if defined(LTC_PTHREAD)
" LTC_PTHREAD "
#endif
#if defined(LTM_DESC)
" LTM_DESC "
#endif
#if defined(TFM_DESC)
" TFM_DESC "
#endif
#if defined(MECC_ACCEL)
" MECC_ACCEL "
#endif
#if defined(GMP_DESC)
" GMP_DESC "
#endif
#if defined(LTC_EASY)
" (easy) "
#endif
#if defined(MECC_FP)
" MECC_FP "
#endif
#if defined(LTC_ECC_SHAMIR)
" LTC_ECC_SHAMIR "
#endif
"\n"
"\n\n\n"
;
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,30 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
#include <signal.h>
/**
@file crypt_argchk.c
Perform argument checking, Tom St Denis
*/
#if (ARGTYPE == 0)
void crypt_argchk(char *v, char *s, int d)
{
fprintf(stderr, "LTC_ARGCHK '%s' failure on line %d of file %s\n",
v, d, s);
(void)raise(SIGABRT);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_cipher_descriptor.c
Stores the cipher descriptor table, Tom St Denis
*/
struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE] = {
{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
LTC_MUTEX_GLOBAL(ltc_cipher_mutex)
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_cipher_is_valid.c
Determine if cipher is valid, Tom St Denis
*/
/*
Test if a cipher index is valid
@param idx The index of the cipher to search for
@return CRYPT_OK if valid
*/
int cipher_is_valid(int idx)
{
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_INVALID_CIPHER;
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_OK;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_find_cipher.c
Find a cipher in the descriptor tables, Tom St Denis
*/
/**
Find a registered cipher by name
@param name The name of the cipher to look for
@return >= 0 if found, -1 if not present
*/
int find_cipher(const char *name)
{
int x;
LTC_ARGCHK(name != NULL);
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name != NULL && !XSTRCMP(cipher_descriptor[x].name, name)) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,50 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_find_cipher_any.c
Find a cipher in the descriptor tables, Tom St Denis
*/
/**
Find a cipher flexibly. First by name then if not present by block and key size
@param name The name of the cipher desired
@param blocklen The minimum length of the block cipher desired (octets)
@param keylen The minimum length of the key size desired (octets)
@return >= 0 if found, -1 if not present
*/
int find_cipher_any(const char *name, int blocklen, int keylen)
{
int x;
LTC_ARGCHK(name != NULL);
x = find_cipher(name);
if (x != -1) return x;
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
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) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,40 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_find_cipher_id.c
Find cipher by ID, Tom St Denis
*/
/**
Find a cipher by ID number
@param ID The ID (not same as index) of the cipher to find
@return >= 0 if found, -1 if not present
*/
int find_cipher_id(unsigned char ID)
{
int x;
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].ID == ID) {
x = (cipher_descriptor[x].name == NULL) ? -1 : x;
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,40 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_find_hash.c
Find a hash, Tom St Denis
*/
/**
Find a registered hash by name
@param name The name of the hash to look for
@return >= 0 if found, -1 if not present
*/
int find_hash(const char *name)
{
int x;
LTC_ARGCHK(name != NULL);
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].name != NULL && XSTRCMP(hash_descriptor[x].name, name) == 0) {
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return -1;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_find_hash_any.c
Find a hash, Tom St Denis
*/
/**
Find a hash flexibly. First by name then if not present by digest size
@param name The name of the hash desired
@param digestlen The minimum length of the digest size (octets)
@return >= 0 if found, -1 if not present
*/int find_hash_any(const char *name, int digestlen)
{
int x, y, z;
LTC_ARGCHK(name != NULL);
x = find_hash(name);
if (x != -1) return x;
LTC_MUTEX_LOCK(&ltc_hash_mutex);
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;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return z;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,40 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_find_hash_id.c
Find hash by ID, Tom St Denis
*/
/**
Find a hash by ID number
@param ID The ID (not same as index) of the hash to find
@return >= 0 if found, -1 if not present
*/
int find_hash_id(unsigned char ID)
{
int x;
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].ID == ID) {
x = (hash_descriptor[x].name == NULL) ? -1 : x;
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return -1;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_find_hash_oid.c
Find a hash, Tom St Denis
*/
int find_hash_oid(const unsigned long *ID, unsigned long IDlen)
{
int x;
LTC_ARGCHK(ID != NULL);
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].name != NULL && hash_descriptor[x].OIDlen == IDlen && !XMEMCMP(hash_descriptor[x].OID, ID, sizeof(unsigned long) * IDlen)) {
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return -1;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_find_prng.c
Find a PRNG, Tom St Denis
*/
/**
Find a registered PRNG by name
@param name The name of the PRNG to look for
@return >= 0 if found, -1 if not present
*/
int find_prng(const char *name)
{
int x;
LTC_ARGCHK(name != NULL);
LTC_MUTEX_LOCK(&ltc_prng_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if ((prng_descriptor[x].name != NULL) && XSTRCMP(prng_descriptor[x].name, name) == 0) {
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return x;
}
}
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return -1;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
#include <stdarg.h>
/**
@file crypt_fsa.c
LibTomCrypt FULL SPEED AHEAD!, Tom St Denis
*/
/* format is ltc_mp, cipher_desc, [cipher_desc], NULL, hash_desc, [hash_desc], NULL, prng_desc, [prng_desc], NULL */
int crypt_fsa(void *mp, ...)
{
int err;
va_list args;
void *p;
va_start(args, mp);
if (mp != NULL) {
XMEMCPY(&ltc_mp, mp, sizeof(ltc_mp));
}
while ((p = va_arg(args, void*)) != NULL) {
if ((err = register_cipher(p)) != CRYPT_OK) {
va_end(args);
return err;
}
}
while ((p = va_arg(args, void*)) != NULL) {
if ((err = register_hash(p)) != CRYPT_OK) {
va_end(args);
return err;
}
}
while ((p = va_arg(args, void*)) != NULL) {
if ((err = register_prng(p)) != CRYPT_OK) {
va_end(args);
return err;
}
}
va_end(args);
return CRYPT_OK;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_hash_descriptor.c
Stores the hash descriptor table, Tom St Denis
*/
struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = {
{ NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL, NULL }
};
LTC_MUTEX_GLOBAL(ltc_hash_mutex)
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_hash_is_valid.c
Determine if hash is valid, Tom St Denis
*/
/*
Test if a hash index is valid
@param idx The index of the hash to search for
@return CRYPT_OK if valid
*/
int hash_is_valid(int idx)
{
LTC_MUTEX_LOCK(&ltc_hash_mutex);
if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_INVALID_HASH;
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_OK;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,13 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
ltc_math_descriptor ltc_mp;
@@ -0,0 +1,26 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_prng_descriptor.c
Stores the PRNG descriptors, Tom St Denis
*/
struct ltc_prng_descriptor prng_descriptor[TAB_SIZE] = {
{ NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
};
LTC_MUTEX_GLOBAL(ltc_prng_mutex)
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_prng_is_valid.c
Determine if PRNG is valid, Tom St Denis
*/
/*
Test if a PRNG index is valid
@param idx The index of the PRNG to search for
@return CRYPT_OK if valid
*/
int prng_is_valid(int idx)
{
LTC_MUTEX_LOCK(&ltc_prng_mutex);
if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_INVALID_PRNG;
}
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_OK;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,54 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_register_cipher.c
Register a cipher, Tom St Denis
*/
/**
Register a cipher with the descriptor table
@param cipher The cipher you wish to register
@return value >= 0 if successfully added (or already present), -1 if unsuccessful
*/
int register_cipher(const struct ltc_cipher_descriptor *cipher)
{
int x;
LTC_ARGCHK(cipher != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) {
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
/* find a blank spot */
for (x = 0; x < TAB_SIZE; x++) {
if (cipher_descriptor[x].name == NULL) {
XMEMCPY(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor));
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return x;
}
}
/* no spot */
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return -1;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,54 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_register_hash.c
Register a HASH, Tom St Denis
*/
/**
Register a hash with the descriptor table
@param hash The hash you wish to register
@return value >= 0 if successfully added (or already present), -1 if unsuccessful
*/
int register_hash(const struct ltc_hash_descriptor *hash)
{
int x;
LTC_ARGCHK(hash != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
/* find a blank spot */
for (x = 0; x < TAB_SIZE; x++) {
if (hash_descriptor[x].name == NULL) {
XMEMCPY(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor));
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return x;
}
}
/* no spot */
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return -1;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,54 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_register_prng.c
Register a PRNG, Tom St Denis
*/
/**
Register a PRNG with the descriptor table
@param prng The PRNG you wish to register
@return value >= 0 if successfully added (or already present), -1 if unsuccessful
*/
int register_prng(const struct ltc_prng_descriptor *prng)
{
int x;
LTC_ARGCHK(prng != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_prng_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return x;
}
}
/* find a blank spot */
for (x = 0; x < TAB_SIZE; x++) {
if (prng_descriptor[x].name == NULL) {
XMEMCPY(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor));
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return x;
}
}
/* no spot */
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return -1;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,45 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_unregister_cipher.c
Unregister a cipher, Tom St Denis
*/
/**
Unregister a cipher from the descriptor table
@param cipher The cipher descriptor to remove
@return CRYPT_OK on success
*/
int unregister_cipher(const struct ltc_cipher_descriptor *cipher)
{
int x;
LTC_ARGCHK(cipher != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_cipher_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (XMEMCMP(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)) == 0) {
cipher_descriptor[x].name = NULL;
cipher_descriptor[x].ID = 255;
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_OK;
}
}
LTC_MUTEX_UNLOCK(&ltc_cipher_mutex);
return CRYPT_ERROR;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,44 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_unregister_hash.c
Unregister a hash, Tom St Denis
*/
/**
Unregister a hash from the descriptor table
@param hash The hash descriptor to remove
@return CRYPT_OK on success
*/
int unregister_hash(const struct ltc_hash_descriptor *hash)
{
int x;
LTC_ARGCHK(hash != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_hash_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (XMEMCMP(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
hash_descriptor[x].name = NULL;
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_OK;
}
}
LTC_MUTEX_UNLOCK(&ltc_hash_mutex);
return CRYPT_ERROR;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,44 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file crypt_unregister_prng.c
Unregister a PRNG, Tom St Denis
*/
/**
Unregister a PRNG from the descriptor table
@param prng The PRNG descriptor to remove
@return CRYPT_OK on success
*/
int unregister_prng(const struct ltc_prng_descriptor *prng)
{
int x;
LTC_ARGCHK(prng != NULL);
/* is it already registered? */
LTC_MUTEX_LOCK(&ltc_prng_mutex);
for (x = 0; x < TAB_SIZE; x++) {
if (XMEMCMP(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) != 0) {
prng_descriptor[x].name = NULL;
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_OK;
}
}
LTC_MUTEX_UNLOCK(&ltc_prng_mutex);
return CRYPT_ERROR;
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,74 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file error_to_string.c
Convert error codes to ASCII strings, Tom St Denis
*/
static const char *err_2_str[] =
{
"CRYPT_OK",
"CRYPT_ERROR",
"Non-fatal 'no-operation' requested.",
"Invalid keysize for block cipher.",
"Invalid number of rounds for block cipher.",
"Algorithm failed test vectors.",
"Buffer overflow.",
"Invalid input packet.",
"Invalid number of bits for a PRNG.",
"Error reading the PRNG.",
"Invalid cipher specified.",
"Invalid hash specified.",
"Invalid PRNG specified.",
"Out of memory.",
"Invalid PK key or key type specified for function.",
"A private PK key is required.",
"Invalid argument provided.",
"File Not Found",
"Invalid PK type.",
"Invalid PK system.",
"Duplicate PK key found on keyring.",
"Key not found in keyring.",
"Invalid sized parameter.",
"Invalid size for prime.",
};
/**
Convert an LTC error code to ASCII
@param err The error code
@return A pointer to the ASCII NUL terminated string for the error or "Invalid error code." if the err code was not valid.
*/
const char *error_to_string(int err)
{
if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) {
return "Invalid error code.";
} else {
return err_2_str[err];
}
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include <tomcrypt.h>
/**
@file pkcs_5_1.c
PKCS #5, Algorithm #1, Tom St Denis
*/
#ifdef PKCS_5
/**
Execute PKCS #5 v1
@param password The password (or key)
@param password_len The length of the password (octet)
@param salt The salt (or nonce) which is 8 octets long
@param iteration_count The PKCS #5 v1 iteration count
@param hash_idx The index of the hash desired
@param out [out] The destination for this algorithm
@param outlen [in/out] The max size and resulting size of the algorithm output
@return CRYPT_OK if successful
*/
int pkcs_5_alg1(const unsigned char *password, unsigned long password_len,
const unsigned char *salt,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen)
{
int err;
unsigned long x;
hash_state *md;
unsigned char *buf;
LTC_ARGCHK(password != NULL);
LTC_ARGCHK(salt != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* test hash IDX */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
/* allocate memory */
md = XMALLOC(sizeof(hash_state));
buf = XMALLOC(MAXBLOCKSIZE);
if (md == NULL || buf == NULL) {
if (md != NULL) {
XFREE(md);
}
if (buf != NULL) {
XFREE(buf);
}
return CRYPT_MEM;
}
/* hash initial password + salt */
if ((err = hash_descriptor[hash_idx].init(md)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hash_descriptor[hash_idx].process(md, password, password_len)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hash_descriptor[hash_idx].process(md, salt, 8)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hash_descriptor[hash_idx].done(md, buf)) != CRYPT_OK) {
goto LBL_ERR;
}
while (--iteration_count) {
/* code goes here. */
x = MAXBLOCKSIZE;
if ((err = hash_memory(hash_idx, buf, hash_descriptor[hash_idx].hashsize, buf, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
}
/* copy upto outlen bytes */
for (x = 0; x < hash_descriptor[hash_idx].hashsize && x < *outlen; x++) {
out[x] = buf[x];
}
*outlen = x;
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(buf, MAXBLOCKSIZE);
zeromem(md, sizeof(hash_state));
#endif
XFREE(buf);
XFREE(md);
return err;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,129 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include <tomcrypt.h>
/**
@file pkcs_5_2.c
PKCS #5, Algorithm #2, Tom St Denis
*/
#ifdef PKCS_5
/**
Execute PKCS #5 v2
@param password The input password (or key)
@param password_len The length of the password (octets)
@param salt The salt (or nonce)
@param salt_len The length of the salt (octets)
@param iteration_count # of iterations desired for PKCS #5 v2 [read specs for more]
@param hash_idx The index of the hash desired
@param out [out] The destination for this algorithm
@param outlen [in/out] The max size and resulting size of the algorithm output
@return CRYPT_OK if successful
*/
int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
const unsigned char *salt, unsigned long salt_len,
int iteration_count, int hash_idx,
unsigned char *out, unsigned long *outlen)
{
int err, itts;
ulong32 blkno;
unsigned long stored, left, x, y;
unsigned char *buf[2];
hmac_state *hmac;
LTC_ARGCHK(password != NULL);
LTC_ARGCHK(salt != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* test hash IDX */
if ((err = hash_is_valid(hash_idx)) != CRYPT_OK) {
return err;
}
buf[0] = XMALLOC(MAXBLOCKSIZE * 2);
hmac = XMALLOC(sizeof(hmac_state));
if (hmac == NULL || buf[0] == NULL) {
if (hmac != NULL) {
XFREE(hmac);
}
if (buf[0] != NULL) {
XFREE(buf[0]);
}
return CRYPT_MEM;
}
/* buf[1] points to the second block of MAXBLOCKSIZE bytes */
buf[1] = buf[0] + MAXBLOCKSIZE;
left = *outlen;
blkno = 1;
stored = 0;
while (left != 0) {
/* process block number blkno */
zeromem(buf[0], MAXBLOCKSIZE*2);
/* store current block number and increment for next pass */
STORE32H(blkno, buf[1]);
++blkno;
/* get PRF(P, S||int(blkno)) */
if ((err = hmac_init(hmac, hash_idx, password, password_len)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hmac_process(hmac, salt, salt_len)) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = hmac_process(hmac, buf[1], 4)) != CRYPT_OK) {
goto LBL_ERR;
}
x = MAXBLOCKSIZE;
if ((err = hmac_done(hmac, buf[0], &x)) != CRYPT_OK) {
goto LBL_ERR;
}
/* now compute repeated and XOR it in buf[1] */
XMEMCPY(buf[1], buf[0], x);
for (itts = 1; itts < iteration_count; ++itts) {
if ((err = hmac_memory(hash_idx, password, password_len, buf[0], x, buf[0], &x)) != CRYPT_OK) {
goto LBL_ERR;
}
for (y = 0; y < x; y++) {
buf[1][y] ^= buf[0][y];
}
}
/* now emit upto x bytes of buf[1] to output */
for (y = 0; y < x && left != 0; ++y) {
out[stored++] = buf[1][y];
--left;
}
}
*outlen = stored;
err = CRYPT_OK;
LBL_ERR:
#ifdef LTC_CLEAN_STACK
zeromem(buf[0], MAXBLOCKSIZE*2);
zeromem(hmac, sizeof(hmac_state));
#endif
XFREE(hmac);
XFREE(buf[0]);
return err;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file zeromem.c
Zero a block of memory, Tom St Denis
*/
/**
Zero a block of memory
@param out The destination of the area to zero
@param outlen The length of the area to zero (octets)
*/
void zeromem(void *out, size_t outlen)
{
unsigned char *mem = out;
LTC_ARGCHKVD(out != NULL);
while (outlen-- > 0) {
*mem++ = 0;
}
}
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cbc_decrypt.c
CBC implementation, encrypt block, Tom St Denis
*/
#ifdef LTC_CBC_MODE
/**
CBC decrypt
@param ct Ciphertext
@param pt [out] Plaintext
@param len The number of bytes to process (must be multiple of block length)
@param cbc CBC state
@return CRYPT_OK if successful
*/
int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc)
{
int x, err;
unsigned char tmp[16];
#ifdef LTC_FAST
LTC_FAST_TYPE tmpy;
#else
unsigned char tmpy;
#endif
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(cbc != NULL);
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen valid? */
if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) {
return CRYPT_INVALID_ARG;
}
if (len % cbc->blocklen) {
return CRYPT_INVALID_ARG;
}
#ifdef LTC_FAST
if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
} else {
while (len) {
/* decrypt */
if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {
return err;
}
/* xor IV against plaintext */
#if defined(LTC_FAST)
for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
tmpy = *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^ *((LTC_FAST_TYPE*)((unsigned char *)tmp + x));
*((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
*((LTC_FAST_TYPE*)((unsigned char *)pt + x)) = tmpy;
}
#else
for (x = 0; x < cbc->blocklen; x++) {
tmpy = tmp[x] ^ cbc->IV[x];
cbc->IV[x] = ct[x];
pt[x] = tmpy;
}
#endif
ct += cbc->blocklen;
pt += cbc->blocklen;
len -= cbc->blocklen;
}
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,42 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cbc_done.c
CBC implementation, finish chain, Tom St Denis
*/
#ifdef LTC_CBC_MODE
/** Terminate the chain
@param cbc The CBC chain to terminate
@return CRYPT_OK on success
*/
int cbc_done(symmetric_CBC *cbc)
{
int err;
LTC_ARGCHK(cbc != NULL);
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[cbc->cipher].done(&cbc->key);
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,98 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cbc_encrypt.c
CBC implementation, encrypt block, Tom St Denis
*/
#ifdef LTC_CBC_MODE
/**
CBC encrypt
@param pt Plaintext
@param ct [out] Ciphertext
@param len The number of bytes to process (must be multiple of block length)
@param cbc CBC state
@return CRYPT_OK if successful
*/
int cbc_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CBC *cbc)
{
int x, err;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(cbc != NULL);
if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen valid? */
if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) {
return CRYPT_INVALID_ARG;
}
if (len % cbc->blocklen) {
return CRYPT_INVALID_ARG;
}
#ifdef LTC_FAST
if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) {
return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key);
} else {
while (len) {
/* xor IV against plaintext */
#if defined(LTC_FAST)
for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
*((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^= *((LTC_FAST_TYPE*)((unsigned char *)pt + x));
}
#else
for (x = 0; x < cbc->blocklen; x++) {
cbc->IV[x] ^= pt[x];
}
#endif
/* encrypt */
if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) {
return err;
}
/* store IV [ciphertext] for a future block */
#if defined(LTC_FAST)
for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
*((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
}
#else
for (x = 0; x < cbc->blocklen; x++) {
cbc->IV[x] = ct[x];
}
#endif
ct += cbc->blocklen;
pt += cbc->blocklen;
len -= cbc->blocklen;
}
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cbc_getiv.c
CBC implementation, get IV, Tom St Denis
*/
#ifdef LTC_CBC_MODE
/**
Get the current initial vector
@param IV [out] The destination of the initial vector
@param len [in/out] The max size and resulting size of the initial vector
@param cbc The CBC state
@return CRYPT_OK if successful
*/
int cbc_getiv(unsigned char *IV, unsigned long *len, symmetric_CBC *cbc)
{
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(len != NULL);
LTC_ARGCHK(cbc != NULL);
if ((unsigned long)cbc->blocklen > *len) {
*len = cbc->blocklen;
return CRYPT_BUFFER_OVERFLOW;
}
XMEMCPY(IV, cbc->IV, cbc->blocklen);
*len = cbc->blocklen;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,44 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cbc_setiv.c
CBC implementation, set IV, Tom St Denis
*/
#ifdef LTC_CBC_MODE
/**
Set an initial vector
@param IV The initial vector
@param len The length of the vector (in octets)
@param cbc The CBC state
@return CRYPT_OK if successful
*/
int cbc_setiv(const unsigned char *IV, unsigned long len, symmetric_CBC *cbc)
{
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(cbc != NULL);
if (len != (unsigned long)cbc->blocklen) {
return CRYPT_INVALID_ARG;
}
XMEMCPY(cbc->IV, IV, len);
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cbc_start.c
CBC implementation, start chain, Tom St Denis
*/
#ifdef LTC_CBC_MODE
/**
Initialize a CBC context
@param cipher The index of the cipher desired
@param IV The initial vector
@param key The secret key
@param keylen The length of the secret key (octets)
@param num_rounds Number of rounds in the cipher desired (0 for default)
@param cbc The CBC state to initialize
@return CRYPT_OK if successful
*/
int cbc_start(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, symmetric_CBC *cbc)
{
int x, err;
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(key != NULL);
LTC_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
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cfb_decrypt.c
CFB implementation, decrypt data, Tom St Denis
*/
#ifdef LTC_CFB_MODE
/**
CFB decrypt
@param ct Ciphertext
@param pt [out] Plaintext
@param len Length of ciphertext (octets)
@param cfb CFB state
@return CRYPT_OK if successful
*/
int cfb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CFB *cfb)
{
int err;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_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) {
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
return err;
}
cfb->padlen = 0;
}
cfb->pad[cfb->padlen] = *ct;
*pt = *ct ^ cfb->IV[cfb->padlen];
++pt;
++ct;
++(cfb->padlen);
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,42 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cfb_done.c
CFB implementation, finish chain, Tom St Denis
*/
#ifdef LTC_CFB_MODE
/** Terminate the chain
@param cfb The CFB chain to terminate
@return CRYPT_OK on success
*/
int cfb_done(symmetric_CFB *cfb)
{
int err;
LTC_ARGCHK(cfb != NULL);
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[cfb->cipher].done(&cfb->key);
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,65 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cfb_encrypt.c
CFB implementation, encrypt data, Tom St Denis
*/
#ifdef LTC_CFB_MODE
/**
CFB encrypt
@param pt Plaintext
@param ct [out] Ciphertext
@param len Length of plaintext (octets)
@param cfb CFB state
@return CRYPT_OK if successful
*/
int cfb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CFB *cfb)
{
int err;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_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) {
if ((err = cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->pad, cfb->IV, &cfb->key)) != CRYPT_OK) {
return err;
}
cfb->padlen = 0;
}
cfb->pad[cfb->padlen] = (*ct = *pt ^ cfb->IV[cfb->padlen]);
++pt;
++ct;
++(cfb->padlen);
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cfb_getiv.c
CFB implementation, get IV, Tom St Denis
*/
#ifdef LTC_CFB_MODE
/**
Get the current initial vector
@param IV [out] The destination of the initial vector
@param len [in/out] The max size and resulting size of the initial vector
@param cfb The CFB state
@return CRYPT_OK if successful
*/
int cfb_getiv(unsigned char *IV, unsigned long *len, symmetric_CFB *cfb)
{
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(len != NULL);
LTC_ARGCHK(cfb != NULL);
if ((unsigned long)cfb->blocklen > *len) {
*len = cfb->blocklen;
return CRYPT_BUFFER_OVERFLOW;
}
XMEMCPY(IV, cfb->IV, cfb->blocklen);
*len = cfb->blocklen;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cfb_setiv.c
CFB implementation, set IV, Tom St Denis
*/
#ifdef LTC_CFB_MODE
/**
Set an initial vector
@param IV The initial vector
@param len The length of the vector (in octets)
@param cfb The CFB state
@return CRYPT_OK if successful
*/
int cfb_setiv(const unsigned char *IV, unsigned long len, symmetric_CFB *cfb)
{
int err;
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(cfb != NULL);
if ((err = cipher_is_valid(cfb->cipher)) != CRYPT_OK) {
return err;
}
if (len != (unsigned long)cfb->blocklen) {
return CRYPT_INVALID_ARG;
}
/* force next block */
cfb->padlen = 0;
return cipher_descriptor[cfb->cipher].ecb_encrypt(IV, cfb->IV, &cfb->key);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,65 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file cfb_start.c
CFB implementation, start chain, Tom St Denis
*/
#ifdef LTC_CFB_MODE
/**
Initialize a CFB context
@param cipher The index of the cipher desired
@param IV The initial vector
@param key The secret key
@param keylen The length of the secret key (octets)
@param num_rounds Number of rounds in the cipher desired (0 for default)
@param cfb The CFB state to initialize
@return CRYPT_OK if successful
*/
int cfb_start(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, symmetric_CFB *cfb)
{
int x, err;
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(key != NULL);
LTC_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 */
cfb->padlen = 0;
return cipher_descriptor[cfb->cipher].ecb_encrypt(cfb->IV, cfb->IV, &cfb->key);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,42 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ctr_decrypt.c
CTR implementation, decrypt data, Tom St Denis
*/
#ifdef LTC_CTR_MODE
/**
CTR decrypt
@param ct Ciphertext
@param pt [out] Plaintext
@param len Length of ciphertext (octets)
@param ctr CTR state
@return CRYPT_OK if successful
*/
int ctr_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CTR *ctr)
{
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ctr != NULL);
return ctr_encrypt(ct, pt, len, ctr);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,42 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ctr_done.c
CTR implementation, finish chain, Tom St Denis
*/
#ifdef LTC_CTR_MODE
/** Terminate the chain
@param ctr The CTR chain to terminate
@return CRYPT_OK on success
*/
int ctr_done(symmetric_CTR *ctr)
{
int err;
LTC_ARGCHK(ctr != NULL);
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[ctr->cipher].done(&ctr->key);
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,112 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ctr_encrypt.c
CTR implementation, encrypt data, Tom St Denis
*/
#ifdef LTC_CTR_MODE
/**
CTR encrypt
@param pt Plaintext
@param ct [out] Ciphertext
@param len Length of plaintext (octets)
@param ctr CTR state
@return CRYPT_OK if successful
*/
int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr)
{
int x, err;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ctr != NULL);
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen/padlen valid? */
if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) ||
ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) {
return CRYPT_INVALID_ARG;
}
#ifdef LTC_FAST
if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) {
return CRYPT_INVALID_ARG;
}
#endif
/* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */
if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) {
if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) {
return err;
}
len %= ctr->blocklen;
}
while (len) {
/* is the pad empty? */
if (ctr->padlen == ctr->blocklen) {
/* increment counter */
if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
/* 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 */
if ((err = cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key)) != CRYPT_OK) {
return err;
}
ctr->padlen = 0;
}
#ifdef LTC_FAST
if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) {
for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) {
*((LTC_FAST_TYPE*)((unsigned char *)ct + x)) = *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) ^
*((LTC_FAST_TYPE*)((unsigned char *)ctr->pad + x));
}
pt += ctr->blocklen;
ct += ctr->blocklen;
len -= ctr->blocklen;
ctr->padlen = ctr->blocklen;
continue;
}
#endif
*ct++ = *pt++ ^ ctr->pad[ctr->padlen++];
--len;
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ctr_getiv.c
CTR implementation, get IV, Tom St Denis
*/
#ifdef LTC_CTR_MODE
/**
Get the current initial vector
@param IV [out] The destination of the initial vector
@param len [in/out] The max size and resulting size of the initial vector
@param ctr The CTR state
@return CRYPT_OK if successful
*/
int ctr_getiv(unsigned char *IV, unsigned long *len, symmetric_CTR *ctr)
{
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(len != NULL);
LTC_ARGCHK(ctr != NULL);
if ((unsigned long)ctr->blocklen > *len) {
*len = ctr->blocklen;
return CRYPT_BUFFER_OVERFLOW;
}
XMEMCPY(IV, ctr->ctr, ctr->blocklen);
*len = ctr->blocklen;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ctr_setiv.c
CTR implementation, set IV, Tom St Denis
*/
#ifdef LTC_CTR_MODE
/**
Set an initial vector
@param IV The initial vector
@param len The length of the vector (in octets)
@param ctr The CTR state
@return CRYPT_OK if successful
*/
int ctr_setiv(const unsigned char *IV, unsigned long len, symmetric_CTR *ctr)
{
int err;
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(ctr != NULL);
/* bad param? */
if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) {
return err;
}
if (len != (unsigned long)ctr->blocklen) {
return CRYPT_INVALID_ARG;
}
/* set IV */
XMEMCPY(ctr->ctr, IV, len);
/* force next block */
ctr->padlen = 0;
return cipher_descriptor[ctr->cipher].ecb_encrypt(IV, ctr->pad, &ctr->key);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,91 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ctr_start.c
CTR implementation, start chain, Tom St Denis
*/
#ifdef LTC_CTR_MODE
/**
Initialize a CTR context
@param cipher The index of the cipher desired
@param IV The initial vector
@param key The secret key
@param keylen The length of the secret key (octets)
@param num_rounds Number of rounds in the cipher desired (0 for default)
@param ctr_mode The counter mode (CTR_COUNTER_LITTLE_ENDIAN or CTR_COUNTER_BIG_ENDIAN)
@param ctr The CTR state to initialize
@return CRYPT_OK if successful
*/
int ctr_start( int cipher,
const unsigned char *IV,
const unsigned char *key, int keylen,
int num_rounds, int ctr_mode,
symmetric_CTR *ctr)
{
int x, err;
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(key != NULL);
LTC_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 = ctr_mode & 1;
for (x = 0; x < ctr->blocklen; x++) {
ctr->ctr[x] = IV[x];
}
if (ctr_mode & LTC_CTR_RFC3686) {
/* increment the IV as per RFC 3686 */
if (ctr->mode == CTR_COUNTER_LITTLE_ENDIAN) {
/* 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;
}
}
}
}
return cipher_descriptor[ctr->cipher].ecb_encrypt(ctr->ctr, ctr->pad, &ctr->key);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,85 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ctr_test.c
CTR implementation, Tests again RFC 3686, Tom St Denis
*/
#ifdef LTC_CTR_MODE
int ctr_test(void)
{
#ifdef LTC_NO_TEST
return CRYPT_NOP;
#else
static const struct {
int keylen, msglen;
unsigned char key[32], IV[16], pt[64], ct[64];
} tests[] = {
/* 128-bit key, 16-byte pt */
{
16, 16,
{0xAE,0x68,0x52,0xF8,0x12,0x10,0x67,0xCC,0x4B,0xF7,0xA5,0x76,0x55,0x77,0xF3,0x9E },
{0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 },
{0x53,0x69,0x6E,0x67,0x6C,0x65,0x20,0x62,0x6C,0x6F,0x63,0x6B,0x20,0x6D,0x73,0x67 },
{0xE4,0x09,0x5D,0x4F,0xB7,0xA7,0xB3,0x79,0x2D,0x61,0x75,0xA3,0x26,0x13,0x11,0xB8 },
},
/* 128-bit key, 36-byte pt */
{
16, 36,
{0x76,0x91,0xBE,0x03,0x5E,0x50,0x20,0xA8,0xAC,0x6E,0x61,0x85,0x29,0xF9,0xA0,0xDC },
{0x00,0xE0,0x01,0x7B,0x27,0x77,0x7F,0x3F,0x4A,0x17,0x86,0xF0,0x00,0x00,0x00,0x00 },
{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,
0x20,0x21,0x22,0x23},
{0xC1,0xCF,0x48,0xA8,0x9F,0x2F,0xFD,0xD9,0xCF,0x46,0x52,0xE9,0xEF,0xDB,0x72,0xD7,
0x45,0x40,0xA4,0x2B,0xDE,0x6D,0x78,0x36,0xD5,0x9A,0x5C,0xEA,0xAE,0xF3,0x10,0x53,
0x25,0xB2,0x07,0x2F },
},
};
int idx, err, x;
unsigned char buf[64];
symmetric_CTR ctr;
/* 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++) {
if ((err = ctr_start(idx, tests[x].IV, tests[x].key, tests[x].keylen, 0, CTR_COUNTER_BIG_ENDIAN|LTC_CTR_RFC3686, &ctr)) != CRYPT_OK) {
return err;
}
if ((err = ctr_encrypt(tests[x].pt, buf, tests[x].msglen, &ctr)) != CRYPT_OK) {
return err;
}
ctr_done(&ctr);
if (XMEMCMP(buf, tests[x].ct, tests[x].msglen)) {
return CRYPT_FAIL_TESTVECTOR;
}
}
return CRYPT_OK;
#endif
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,61 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ecb_decrypt.c
ECB implementation, decrypt a block, Tom St Denis
*/
#ifdef LTC_ECB_MODE
/**
ECB decrypt
@param ct Ciphertext
@param pt [out] Plaintext
@param len The number of octets to process (must be multiple of the cipher block size)
@param ecb ECB state
@return CRYPT_OK if successful
*/
int ecb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_ECB *ecb)
{
int err;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ecb != NULL);
if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
return err;
}
if (len % cipher_descriptor[ecb->cipher].block_length) {
return CRYPT_INVALID_ARG;
}
/* check for accel */
if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) {
return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
} else {
while (len) {
if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) {
return err;
}
pt += cipher_descriptor[ecb->cipher].block_length;
ct += cipher_descriptor[ecb->cipher].block_length;
len -= cipher_descriptor[ecb->cipher].block_length;
}
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,42 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ecb_done.c
ECB implementation, finish chain, Tom St Denis
*/
#ifdef LTC_ECB_MODE
/** Terminate the chain
@param ecb The ECB chain to terminate
@return CRYPT_OK on success
*/
int ecb_done(symmetric_ECB *ecb)
{
int err;
LTC_ARGCHK(ecb != NULL);
if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[ecb->cipher].done(&ecb->key);
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,61 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ecb_encrypt.c
ECB implementation, encrypt a block, Tom St Denis
*/
#ifdef LTC_ECB_MODE
/**
ECB encrypt
@param pt Plaintext
@param ct [out] Ciphertext
@param len The number of octets to process (must be multiple of the cipher block size)
@param ecb ECB state
@return CRYPT_OK if successful
*/
int ecb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_ECB *ecb)
{
int err;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ecb != NULL);
if ((err = cipher_is_valid(ecb->cipher)) != CRYPT_OK) {
return err;
}
if (len % cipher_descriptor[ecb->cipher].block_length) {
return CRYPT_INVALID_ARG;
}
/* check for accel */
if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) {
return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key);
} else {
while (len) {
if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) {
return err;
}
pt += cipher_descriptor[ecb->cipher].block_length;
ct += cipher_descriptor[ecb->cipher].block_length;
len -= cipher_descriptor[ecb->cipher].block_length;
}
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ecb_start.c
ECB implementation, start chain, Tom St Denis
*/
#ifdef LTC_ECB_MODE
/**
Initialize a ECB context
@param cipher The index of the cipher desired
@param key The secret key
@param keylen The length of the secret key (octets)
@param num_rounds Number of rounds in the cipher desired (0 for default)
@param ecb The ECB state to initialize
@return CRYPT_OK if successful
*/
int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb)
{
int err;
LTC_ARGCHK(key != NULL);
LTC_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
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ofb_decrypt.c
OFB implementation, decrypt data, Tom St Denis
*/
#ifdef LTC_OFB_MODE
/**
OFB decrypt
@param ct Ciphertext
@param pt [out] Plaintext
@param len Length of ciphertext (octets)
@param ofb OFB state
@return CRYPT_OK if successful
*/
int ofb_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_OFB *ofb)
{
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ofb != NULL);
return ofb_encrypt(ct, pt, len, ofb);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,42 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ofb_done.c
OFB implementation, finish chain, Tom St Denis
*/
#ifdef LTC_OFB_MODE
/** Terminate the chain
@param ofb The OFB chain to terminate
@return CRYPT_OK on success
*/
int ofb_done(symmetric_OFB *ofb)
{
int err;
LTC_ARGCHK(ofb != NULL);
if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
return err;
}
cipher_descriptor[ofb->cipher].done(&ofb->key);
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ofb_encrypt.c
OFB implementation, encrypt data, Tom St Denis
*/
#ifdef LTC_OFB_MODE
/**
OFB encrypt
@param pt Plaintext
@param ct [out] Ciphertext
@param len Length of plaintext (octets)
@param ofb OFB state
@return CRYPT_OK if successful
*/
int ofb_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_OFB *ofb)
{
int err;
LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(ofb != NULL);
if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
return err;
}
/* is blocklen/padlen valid? */
if (ofb->blocklen < 0 || ofb->blocklen > (int)sizeof(ofb->IV) ||
ofb->padlen < 0 || ofb->padlen > (int)sizeof(ofb->IV)) {
return CRYPT_INVALID_ARG;
}
while (len-- > 0) {
if (ofb->padlen == ofb->blocklen) {
if ((err = cipher_descriptor[ofb->cipher].ecb_encrypt(ofb->IV, ofb->IV, &ofb->key)) != CRYPT_OK) {
return err;
}
ofb->padlen = 0;
}
*ct++ = *pt++ ^ ofb->IV[(ofb->padlen)++];
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ofb_getiv.c
OFB implementation, get IV, Tom St Denis
*/
#ifdef LTC_OFB_MODE
/**
Get the current initial vector
@param IV [out] The destination of the initial vector
@param len [in/out] The max size and resulting size of the initial vector
@param ofb The OFB state
@return CRYPT_OK if successful
*/
int ofb_getiv(unsigned char *IV, unsigned long *len, symmetric_OFB *ofb)
{
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(len != NULL);
LTC_ARGCHK(ofb != NULL);
if ((unsigned long)ofb->blocklen > *len) {
*len = ofb->blocklen;
return CRYPT_BUFFER_OVERFLOW;
}
XMEMCPY(IV, ofb->IV, ofb->blocklen);
*len = ofb->blocklen;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ofb_setiv.c
OFB implementation, set IV, Tom St Denis
*/
#ifdef LTC_OFB_MODE
/**
Set an initial vector
@param IV The initial vector
@param len The length of the vector (in octets)
@param ofb The OFB state
@return CRYPT_OK if successful
*/
int ofb_setiv(const unsigned char *IV, unsigned long len, symmetric_OFB *ofb)
{
int err;
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(ofb != NULL);
if ((err = cipher_is_valid(ofb->cipher)) != CRYPT_OK) {
return err;
}
if (len != (unsigned long)ofb->blocklen) {
return CRYPT_INVALID_ARG;
}
/* force next block */
ofb->padlen = 0;
return cipher_descriptor[ofb->cipher].ecb_encrypt(IV, ofb->IV, &ofb->key);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file ofb_start.c
OFB implementation, start chain, Tom St Denis
*/
#ifdef LTC_OFB_MODE
/**
Initialize a OFB context
@param cipher The index of the cipher desired
@param IV The initial vector
@param key The secret key
@param keylen The length of the secret key (octets)
@param num_rounds Number of rounds in the cipher desired (0 for default)
@param ofb The OFB state to initialize
@return CRYPT_OK if successful
*/
int ofb_start(int cipher, const unsigned char *IV, const unsigned char *key,
int keylen, int num_rounds, symmetric_OFB *ofb)
{
int x, err;
LTC_ARGCHK(IV != NULL);
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(ofb != NULL);
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
return err;
}
/* copy details */
ofb->cipher = cipher;
ofb->blocklen = cipher_descriptor[cipher].block_length;
for (x = 0; x < ofb->blocklen; x++) {
ofb->IV[x] = IV[x];
}
/* init the cipher */
ofb->padlen = ofb->blocklen;
return cipher_descriptor[cipher].setup(key, keylen, num_rounds, &ofb->key);
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,102 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_decode_bit_string.c
ASN.1 DER, encode a BIT STRING, Tom St Denis
*/
#ifdef LTC_DER
/**
Store a BIT STRING
@param in The DER encoded BIT STRING
@param inlen The size of the DER BIT STRING
@param out [out] The array of bits stored (one per char)
@param outlen [in/out] The number of bits stored
@return CRYPT_OK if successful
*/
int der_decode_bit_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long dlen, blen, x, y;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* packet must be at least 4 bytes */
if (inlen < 4) {
return CRYPT_INVALID_ARG;
}
/* check for 0x03 */
if ((in[0]&0x1F) != 0x03) {
return CRYPT_INVALID_PACKET;
}
/* offset in the data */
x = 1;
/* get the length of the data */
if (in[x] & 0x80) {
/* long format get number of length bytes */
y = in[x++] & 0x7F;
/* invalid if 0 or > 2 */
if (y == 0 || y > 2) {
return CRYPT_INVALID_PACKET;
}
/* read the data len */
dlen = 0;
while (y--) {
dlen = (dlen << 8) | (unsigned long)in[x++];
}
} else {
/* short format */
dlen = in[x++] & 0x7F;
}
/* is the data len too long or too short? */
if ((dlen == 0) || (dlen + x > inlen)) {
return CRYPT_INVALID_PACKET;
}
/* get padding count */
blen = ((dlen - 1) << 3) - (in[x++] & 7);
/* too many bits? */
if (blen > *outlen) {
*outlen = blen;
return CRYPT_BUFFER_OVERFLOW;
}
/* decode/store the bits */
for (y = 0; y < blen; y++) {
out[y] = (in[x] & (1 << (7 - (y & 7)))) ? 1 : 0;
if ((y & 7) == 7) {
++x;
}
}
/* we done */
*outlen = blen;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,89 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_encode_bit_string.c
ASN.1 DER, encode a BIT STRING, Tom St Denis
*/
#ifdef LTC_DER
/**
Store a BIT STRING
@param in The array of bits to store (one per char)
@param inlen The number of bits tostore
@param out [out] The destination for the DER encoded BIT STRING
@param outlen [in/out] The max size and resulting size of the DER BIT STRING
@return CRYPT_OK if successful
*/
int der_encode_bit_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long len, x, y;
unsigned char buf;
int err;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* avoid overflows */
if ((err = der_length_bit_string(inlen, &len)) != CRYPT_OK) {
return err;
}
if (len > *outlen) {
*outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
/* store header (include bit padding count in length) */
x = 0;
y = (inlen >> 3) + ((inlen&7) ? 1 : 0) + 1;
out[x++] = 0x03;
if (y < 128) {
out[x++] = (unsigned char)y;
} else if (y < 256) {
out[x++] = 0x81;
out[x++] = (unsigned char)y;
} else if (y < 65536) {
out[x++] = 0x82;
out[x++] = (unsigned char)((y>>8)&255);
out[x++] = (unsigned char)(y&255);
}
/* store number of zero padding bits */
out[x++] = (unsigned char)((8 - inlen) & 7);
/* store the bits in big endian format */
for (y = buf = 0; y < inlen; y++) {
buf |= (in[y] ? 1 : 0) << (7 - (y & 7));
if ((y & 7) == 7) {
out[x++] = buf;
buf = 0;
}
}
/* store last byte */
if (inlen & 7) {
out[x++] = buf;
}
*outlen = x;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,54 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_length_bit_string.c
ASN.1 DER, get length of BIT STRING, Tom St Denis
*/
#ifdef LTC_DER
/**
Gets length of DER encoding of BIT STRING
@param nbits The number of bits in the string to encode
@param outlen [out] The length of the DER encoding for the given string
@return CRYPT_OK if successful
*/
int der_length_bit_string(unsigned long nbits, unsigned long *outlen)
{
unsigned long nbytes;
LTC_ARGCHK(outlen != NULL);
/* get the number of the bytes */
nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1;
if (nbytes < 128) {
/* 03 LL PP DD DD DD ... */
*outlen = 2 + nbytes;
} else if (nbytes < 256) {
/* 03 81 LL PP DD DD DD ... */
*outlen = 3 + nbytes;
} else if (nbytes < 65536) {
/* 03 82 LL LL PP DD DD DD ... */
*outlen = 4 + nbytes;
} else {
return CRYPT_INVALID_ARG;
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_decode_boolean.c
ASN.1 DER, decode a BOOLEAN, Tom St Denis
*/
#ifdef LTC_DER
/**
Read a BOOLEAN
@param in The destination for the DER encoded BOOLEAN
@param inlen The size of the DER BOOLEAN
@param out [out] The boolean to decode
@return CRYPT_OK if successful
*/
int der_decode_boolean(const unsigned char *in, unsigned long inlen,
int *out)
{
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
if (inlen != 3 || in[0] != 0x01 || in[1] != 0x01 || (in[2] != 0x00 && in[2] != 0xFF)) {
return CRYPT_INVALID_ARG;
}
*out = (in[2]==0xFF) ? 1 : 0;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,51 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_encode_boolean.c
ASN.1 DER, encode a BOOLEAN, Tom St Denis
*/
#ifdef LTC_DER
/**
Store a BOOLEAN
@param in The boolean to encode
@param out [out] The destination for the DER encoded BOOLEAN
@param outlen [in/out] The max size and resulting size of the DER BOOLEAN
@return CRYPT_OK if successful
*/
int der_encode_boolean(int in,
unsigned char *out, unsigned long *outlen)
{
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(out != NULL);
if (*outlen < 3) {
*outlen = 3;
return CRYPT_BUFFER_OVERFLOW;
}
*outlen = 3;
out[0] = 0x01;
out[1] = 0x01;
out[2] = in ? 0xFF : 0x00;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_length_boolean.c
ASN.1 DER, get length of a BOOLEAN, Tom St Denis
*/
#ifdef LTC_DER
/**
Gets length of DER encoding of a BOOLEAN
@param outlen [out] The length of the DER encoding
@return CRYPT_OK if successful
*/
int der_length_boolean(unsigned long *outlen)
{
LTC_ARGCHK(outlen != NULL);
*outlen = 3;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,182 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_decode_choice.c
ASN.1 DER, decode a CHOICE, Tom St Denis
*/
#ifdef LTC_DER
/**
Decode a CHOICE
@param in The DER encoded input
@param inlen [in/out] The size of the input and resulting size of read type
@param list The list of items to decode
@param outlen The number of items in the list
@return CRYPT_OK on success
*/
int der_decode_choice(const unsigned char *in, unsigned long *inlen,
ltc_asn1_list *list, unsigned long outlen)
{
unsigned long size, x, z;
void *data;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen != NULL);
LTC_ARGCHK(list != NULL);
/* get blk size */
if (*inlen < 2) {
return CRYPT_INVALID_PACKET;
}
/* set all of the "used" flags to zero */
for (x = 0; x < outlen; x++) {
list[x].used = 0;
}
/* now scan until we have a winner */
for (x = 0; x < outlen; x++) {
size = list[x].size;
data = list[x].data;
switch (list[x].type) {
case LTC_ASN1_INTEGER:
if (der_decode_integer(in, *inlen, data) == CRYPT_OK) {
if (der_length_integer(data, &z) == CRYPT_OK) {
list[x].used = 1;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_SHORT_INTEGER:
if (der_decode_short_integer(in, *inlen, data) == CRYPT_OK) {
if (der_length_short_integer(size, &z) == CRYPT_OK) {
list[x].used = 1;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_BIT_STRING:
if (der_decode_bit_string(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_bit_string(size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_OCTET_STRING:
if (der_decode_octet_string(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_octet_string(size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_NULL:
if (*inlen == 2 && in[x] == 0x05 && in[x+1] == 0x00) {
*inlen = 2;
list[x].used = 1;
return CRYPT_OK;
}
break;
case LTC_ASN1_OBJECT_IDENTIFIER:
if (der_decode_object_identifier(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_object_identifier(data, size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_IA5_STRING:
if (der_decode_ia5_string(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_ia5_string(data, size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_PRINTABLE_STRING:
if (der_decode_printable_string(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_printable_string(data, size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_UTF8_STRING:
if (der_decode_utf8_string(in, *inlen, data, &size) == CRYPT_OK) {
if (der_length_utf8_string(data, size, &z) == CRYPT_OK) {
list[x].used = 1;
list[x].size = size;
*inlen = z;
return CRYPT_OK;
}
}
break;
case LTC_ASN1_UTCTIME:
z = *inlen;
if (der_decode_utctime(in, &z, data) == CRYPT_OK) {
list[x].used = 1;
*inlen = z;
return CRYPT_OK;
}
break;
case LTC_ASN1_SET:
case LTC_ASN1_SETOF:
case LTC_ASN1_SEQUENCE:
if (der_decode_sequence(in, *inlen, data, size) == CRYPT_OK) {
if (der_length_sequence(data, size, &z) == CRYPT_OK) {
list[x].used = 1;
*inlen = z;
return CRYPT_OK;
}
}
break;
default:
return CRYPT_INVALID_ARG;
}
}
return CRYPT_INVALID_PACKET;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_decode_ia5_string.c
ASN.1 DER, encode a IA5 STRING, Tom St Denis
*/
#ifdef LTC_DER
/**
Store a IA5 STRING
@param in The DER encoded IA5 STRING
@param inlen The size of the DER IA5 STRING
@param out [out] The array of octets stored (one per char)
@param outlen [in/out] The number of octets stored
@return CRYPT_OK if successful
*/
int der_decode_ia5_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long x, y, len;
int t;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* must have header at least */
if (inlen < 2) {
return CRYPT_INVALID_PACKET;
}
/* check for 0x16 */
if ((in[0] & 0x1F) != 0x16) {
return CRYPT_INVALID_PACKET;
}
x = 1;
/* decode the length */
if (in[x] & 0x80) {
/* valid # of bytes in length are 1,2,3 */
y = in[x] & 0x7F;
if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
return CRYPT_INVALID_PACKET;
}
/* read the length in */
len = 0;
++x;
while (y--) {
len = (len << 8) | in[x++];
}
} else {
len = in[x++] & 0x7F;
}
/* is it too long? */
if (len > *outlen) {
*outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
if (len + x > inlen) {
return CRYPT_INVALID_PACKET;
}
/* read the data */
for (y = 0; y < len; y++) {
t = der_ia5_value_decode(in[x++]);
if (t == -1) {
return CRYPT_INVALID_ARG;
}
out[y] = t;
}
*outlen = y;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,85 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_encode_ia5_string.c
ASN.1 DER, encode a IA5 STRING, Tom St Denis
*/
#ifdef LTC_DER
/**
Store an IA5 STRING
@param in The array of IA5 to store (one per char)
@param inlen The number of IA5 to store
@param out [out] The destination for the DER encoded IA5 STRING
@param outlen [in/out] The max size and resulting size of the DER IA5 STRING
@return CRYPT_OK if successful
*/
int der_encode_ia5_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long x, y, len;
int err;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* get the size */
if ((err = der_length_ia5_string(in, inlen, &len)) != CRYPT_OK) {
return err;
}
/* too big? */
if (len > *outlen) {
*outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
/* encode the header+len */
x = 0;
out[x++] = 0x16;
if (inlen < 128) {
out[x++] = (unsigned char)inlen;
} else if (inlen < 256) {
out[x++] = 0x81;
out[x++] = (unsigned char)inlen;
} else if (inlen < 65536UL) {
out[x++] = 0x82;
out[x++] = (unsigned char)((inlen>>8)&255);
out[x++] = (unsigned char)(inlen&255);
} else if (inlen < 16777216UL) {
out[x++] = 0x83;
out[x++] = (unsigned char)((inlen>>16)&255);
out[x++] = (unsigned char)((inlen>>8)&255);
out[x++] = (unsigned char)(inlen&255);
} else {
return CRYPT_INVALID_ARG;
}
/* store octets */
for (y = 0; y < inlen; y++) {
out[x++] = der_ia5_char_encode(in[y]);
}
/* retun length */
*outlen = x;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,194 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_length_ia5_string.c
ASN.1 DER, get length of IA5 STRING, Tom St Denis
*/
#ifdef LTC_DER
static const struct {
int code, value;
} ia5_table[] = {
{ '\0', 0 },
{ '\a', 7 },
{ '\b', 8 },
{ '\t', 9 },
{ '\n', 10 },
{ '\f', 12 },
{ '\r', 13 },
{ ' ', 32 },
{ '!', 33 },
{ '"', 34 },
{ '#', 35 },
{ '$', 36 },
{ '%', 37 },
{ '&', 38 },
{ '\'', 39 },
{ '(', 40 },
{ ')', 41 },
{ '*', 42 },
{ '+', 43 },
{ ',', 44 },
{ '-', 45 },
{ '.', 46 },
{ '/', 47 },
{ '0', 48 },
{ '1', 49 },
{ '2', 50 },
{ '3', 51 },
{ '4', 52 },
{ '5', 53 },
{ '6', 54 },
{ '7', 55 },
{ '8', 56 },
{ '9', 57 },
{ ':', 58 },
{ ';', 59 },
{ '<', 60 },
{ '=', 61 },
{ '>', 62 },
{ '?', 63 },
{ '@', 64 },
{ 'A', 65 },
{ 'B', 66 },
{ 'C', 67 },
{ 'D', 68 },
{ 'E', 69 },
{ 'F', 70 },
{ 'G', 71 },
{ 'H', 72 },
{ 'I', 73 },
{ 'J', 74 },
{ 'K', 75 },
{ 'L', 76 },
{ 'M', 77 },
{ 'N', 78 },
{ 'O', 79 },
{ 'P', 80 },
{ 'Q', 81 },
{ 'R', 82 },
{ 'S', 83 },
{ 'T', 84 },
{ 'U', 85 },
{ 'V', 86 },
{ 'W', 87 },
{ 'X', 88 },
{ 'Y', 89 },
{ 'Z', 90 },
{ '[', 91 },
{ '\\', 92 },
{ ']', 93 },
{ '^', 94 },
{ '_', 95 },
{ '`', 96 },
{ 'a', 97 },
{ 'b', 98 },
{ 'c', 99 },
{ 'd', 100 },
{ 'e', 101 },
{ 'f', 102 },
{ 'g', 103 },
{ 'h', 104 },
{ 'i', 105 },
{ 'j', 106 },
{ 'k', 107 },
{ 'l', 108 },
{ 'm', 109 },
{ 'n', 110 },
{ 'o', 111 },
{ 'p', 112 },
{ 'q', 113 },
{ 'r', 114 },
{ 's', 115 },
{ 't', 116 },
{ 'u', 117 },
{ 'v', 118 },
{ 'w', 119 },
{ 'x', 120 },
{ 'y', 121 },
{ 'z', 122 },
{ '{', 123 },
{ '|', 124 },
{ '}', 125 },
{ '~', 126 }
};
int der_ia5_char_encode(int c)
{
int x;
for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) {
if (ia5_table[x].code == c) {
return ia5_table[x].value;
}
}
return -1;
}
int der_ia5_value_decode(int v)
{
int x;
for (x = 0; x < (int)(sizeof(ia5_table)/sizeof(ia5_table[0])); x++) {
if (ia5_table[x].value == v) {
return ia5_table[x].code;
}
}
return -1;
}
/**
Gets length of DER encoding of IA5 STRING
@param octets The values you want to encode
@param noctets The number of octets in the string to encode
@param outlen [out] The length of the DER encoding for the given string
@return CRYPT_OK if successful
*/
int der_length_ia5_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
{
unsigned long x;
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(octets != NULL);
/* scan string for validity */
for (x = 0; x < noctets; x++) {
if (der_ia5_char_encode(octets[x]) == -1) {
return CRYPT_INVALID_ARG;
}
}
if (noctets < 128) {
/* 16 LL DD DD DD ... */
*outlen = 2 + noctets;
} else if (noctets < 256) {
/* 16 81 LL DD DD DD ... */
*outlen = 3 + noctets;
} else if (noctets < 65536UL) {
/* 16 82 LL LL DD DD DD ... */
*outlen = 4 + noctets;
} else if (noctets < 16777216UL) {
/* 16 83 LL LL LL DD DD DD ... */
*outlen = 5 + noctets;
} else {
return CRYPT_INVALID_ARG;
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,110 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_decode_integer.c
ASN.1 DER, decode an integer, Tom St Denis
*/
#ifdef LTC_DER
/**
Read a mp_int integer
@param in The DER encoded data
@param inlen Size of DER encoded data
@param num The first mp_int to decode
@return CRYPT_OK if successful
*/
int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num)
{
unsigned long x, y, z;
int err;
LTC_ARGCHK(num != NULL);
LTC_ARGCHK(in != NULL);
/* min DER INTEGER is 0x02 01 00 == 0 */
if (inlen < (1 + 1 + 1)) {
return CRYPT_INVALID_PACKET;
}
/* ok expect 0x02 when we AND with 0001 1111 [1F] */
x = 0;
if ((in[x++] & 0x1F) != 0x02) {
return CRYPT_INVALID_PACKET;
}
/* now decode the len stuff */
z = in[x++];
if ((z & 0x80) == 0x00) {
/* short form */
/* will it overflow? */
if (x + z > inlen) {
return CRYPT_INVALID_PACKET;
}
/* no so read it */
if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, z)) != CRYPT_OK) {
return err;
}
} else {
/* long form */
z &= 0x7F;
/* will number of length bytes overflow? (or > 4) */
if (((x + z) > inlen) || (z > 4) || (z == 0)) {
return CRYPT_INVALID_PACKET;
}
/* now read it in */
y = 0;
while (z--) {
y = ((unsigned long)(in[x++])) | (y << 8);
}
/* now will reading y bytes overrun? */
if ((x + y) > inlen) {
return CRYPT_INVALID_PACKET;
}
/* no so read it */
if ((err = mp_read_unsigned_bin(num, (unsigned char *)in + x, y)) != CRYPT_OK) {
return err;
}
}
/* see if it's negative */
if (in[x] & 0x80) {
void *tmp;
if (mp_init(&tmp) != CRYPT_OK) {
return CRYPT_MEM;
}
if (mp_2expt(tmp, mp_count_bits(num)) != CRYPT_OK || mp_sub(num, tmp, num) != CRYPT_OK) {
mp_clear(tmp);
return CRYPT_MEM;
}
mp_clear(tmp);
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,130 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_encode_integer.c
ASN.1 DER, encode an integer, Tom St Denis
*/
#ifdef LTC_DER
/* Exports a positive bignum as DER format (upto 2^32 bytes in size) */
/**
Store a mp_int integer
@param num The first mp_int to encode
@param out [out] The destination for the DER encoded integers
@param outlen [in/out] The max size and resulting size of the DER encoded integers
@return CRYPT_OK if successful
*/
int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen)
{
unsigned long tmplen, y;
int err, leading_zero;
LTC_ARGCHK(num != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* find out how big this will be */
if ((err = der_length_integer(num, &tmplen)) != CRYPT_OK) {
return err;
}
if (*outlen < tmplen) {
*outlen = tmplen;
return CRYPT_BUFFER_OVERFLOW;
}
if (mp_cmp_d(num, 0) != LTC_MP_LT) {
/* we only need a leading zero if the msb of the first byte is one */
if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) {
leading_zero = 1;
} else {
leading_zero = 0;
}
/* get length of num in bytes (plus 1 since we force the msbyte to zero) */
y = mp_unsigned_bin_size(num) + leading_zero;
} else {
leading_zero = 0;
y = mp_count_bits(num);
y = y + (8 - (y & 7));
y = y >> 3;
if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --y;
}
/* now store initial data */
*out++ = 0x02;
if (y < 128) {
/* short form */
*out++ = (unsigned char)y;
} else if (y < 256) {
*out++ = 0x81;
*out++ = (unsigned char)y;
} else if (y < 65536UL) {
*out++ = 0x82;
*out++ = (unsigned char)((y>>8)&255);
*out++ = (unsigned char)y;
} else if (y < 16777216UL) {
*out++ = 0x83;
*out++ = (unsigned char)((y>>16)&255);
*out++ = (unsigned char)((y>>8)&255);
*out++ = (unsigned char)y;
} else {
return CRYPT_INVALID_ARG;
}
/* now store msbyte of zero if num is non-zero */
if (leading_zero) {
*out++ = 0x00;
}
/* if it's not zero store it as big endian */
if (mp_cmp_d(num, 0) == LTC_MP_GT) {
/* now store the mpint */
if ((err = mp_to_unsigned_bin(num, out)) != CRYPT_OK) {
return err;
}
} else if (mp_iszero(num) != LTC_MP_YES) {
void *tmp;
/* negative */
if (mp_init(&tmp) != CRYPT_OK) {
return CRYPT_MEM;
}
/* 2^roundup and subtract */
y = mp_count_bits(num);
y = y + (8 - (y & 7));
if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) y -= 8;
if (mp_2expt(tmp, y) != CRYPT_OK || mp_add(tmp, num, tmp) != CRYPT_OK) {
mp_clear(tmp);
return CRYPT_MEM;
}
if ((err = mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) {
mp_clear(tmp);
return err;
}
mp_clear(tmp);
}
/* we good */
*outlen = tmplen;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,82 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_length_integer.c
ASN.1 DER, get length of encoding, Tom St Denis
*/
#ifdef LTC_DER
/**
Gets length of DER encoding of num
@param num The int to get the size of
@param outlen [out] The length of the DER encoding for the given integer
@return CRYPT_OK if successful
*/
int der_length_integer(void *num, unsigned long *outlen)
{
unsigned long z, len;
int leading_zero;
LTC_ARGCHK(num != NULL);
LTC_ARGCHK(outlen != NULL);
if (mp_cmp_d(num, 0) != LTC_MP_LT) {
/* positive */
/* we only need a leading zero if the msb of the first byte is one */
if ((mp_count_bits(num) & 7) == 0 || mp_iszero(num) == LTC_MP_YES) {
leading_zero = 1;
} else {
leading_zero = 0;
}
/* size for bignum */
z = len = leading_zero + mp_unsigned_bin_size(num);
} else {
/* it's negative */
/* find power of 2 that is a multiple of eight and greater than count bits */
leading_zero = 0;
z = mp_count_bits(num);
z = z + (8 - (z & 7));
if (((mp_cnt_lsb(num)+1)==mp_count_bits(num)) && ((mp_count_bits(num)&7)==0)) --z;
len = z = z >> 3;
}
/* now we need a length */
if (z < 128) {
/* short form */
++len;
} else {
/* long form (relies on z != 0), assumes length bytes < 128 */
++len;
while (z) {
++len;
z >>= 8;
}
}
/* we need a 0x02 to indicate it's INTEGER */
++len;
/* return length */
*outlen = len;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,99 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_decode_object_identifier.c
ASN.1 DER, Decode Object Identifier, Tom St Denis
*/
#ifdef LTC_DER
/**
Decode OID data and store the array of integers in words
@param in The OID DER encoded data
@param inlen The length of the OID data
@param words [out] The destination of the OID words
@param outlen [in/out] The number of OID words
@return CRYPT_OK if successful
*/
int der_decode_object_identifier(const unsigned char *in, unsigned long inlen,
unsigned long *words, unsigned long *outlen)
{
unsigned long x, y, t, len;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(words != NULL);
LTC_ARGCHK(outlen != NULL);
/* header is at least 3 bytes */
if (inlen < 3) {
return CRYPT_INVALID_PACKET;
}
/* must be room for at least two words */
if (*outlen < 2) {
return CRYPT_BUFFER_OVERFLOW;
}
/* decode the packet header */
x = 0;
if ((in[x++] & 0x1F) != 0x06) {
return CRYPT_INVALID_PACKET;
}
/* get the length */
if (in[x] < 128) {
len = in[x++];
} else {
if (in[x] < 0x81 || in[x] > 0x82) {
return CRYPT_INVALID_PACKET;
}
y = in[x++] & 0x7F;
len = 0;
while (y--) {
len = (len << 8) | (unsigned long)in[x++];
}
}
if (len < 1 || (len + x) > inlen) {
return CRYPT_INVALID_PACKET;
}
/* decode words */
y = 0;
t = 0;
while (len--) {
t = (t << 7) | (in[x] & 0x7F);
if (!(in[x++] & 0x80)) {
/* store t */
if (y >= *outlen) {
return CRYPT_BUFFER_OVERFLOW;
}
if (y == 0) {
words[0] = t / 40;
words[1] = t % 40;
y = 2;
} else {
words[y++] = t;
}
t = 0;
}
}
*outlen = y;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,111 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_encode_object_identifier.c
ASN.1 DER, Encode Object Identifier, Tom St Denis
*/
#ifdef LTC_DER
/**
Encode an OID
@param words The words to encode (upto 32-bits each)
@param nwords The number of words in the OID
@param out [out] Destination of OID data
@param outlen [in/out] The max and resulting size of the OID
@return CRYPT_OK if successful
*/
int der_encode_object_identifier(unsigned long *words, unsigned long nwords,
unsigned char *out, unsigned long *outlen)
{
unsigned long i, x, y, z, t, mask, wordbuf;
int err;
LTC_ARGCHK(words != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* check length */
if ((err = der_length_object_identifier(words, nwords, &x)) != CRYPT_OK) {
return err;
}
if (x > *outlen) {
*outlen = x;
return CRYPT_BUFFER_OVERFLOW;
}
/* compute length to store OID data */
z = 0;
wordbuf = words[0] * 40 + words[1];
for (y = 1; y < nwords; y++) {
t = der_object_identifier_bits(wordbuf);
z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
if (y < nwords - 1) {
wordbuf = words[y + 1];
}
}
/* store header + length */
x = 0;
out[x++] = 0x06;
if (z < 128) {
out[x++] = (unsigned char)z;
} else if (z < 256) {
out[x++] = 0x81;
out[x++] = (unsigned char)z;
} else if (z < 65536UL) {
out[x++] = 0x82;
out[x++] = (unsigned char)((z>>8)&255);
out[x++] = (unsigned char)(z&255);
} else {
return CRYPT_INVALID_ARG;
}
/* store first byte */
wordbuf = words[0] * 40 + words[1];
for (i = 1; i < nwords; i++) {
/* store 7 bit words in little endian */
t = wordbuf & 0xFFFFFFFF;
if (t) {
y = x;
mask = 0;
while (t) {
out[x++] = (unsigned char)((t & 0x7F) | mask);
t >>= 7;
mask |= 0x80; /* upper bit is set on all but the last byte */
}
/* now swap bytes y...x-1 */
z = x - 1;
while (y < z) {
t = out[y]; out[y] = out[z]; out[z] = (unsigned char)t;
++y;
--z;
}
} else {
/* zero word */
out[x++] = 0x00;
}
if (i < nwords - 1) {
wordbuf = words[i + 1];
}
}
*outlen = x;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,89 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_length_object_identifier.c
ASN.1 DER, get length of Object Identifier, Tom St Denis
*/
#ifdef LTC_DER
unsigned long der_object_identifier_bits(unsigned long x)
{
unsigned long c;
x &= 0xFFFFFFFF;
c = 0;
while (x) {
++c;
x >>= 1;
}
return c;
}
/**
Gets length of DER encoding of Object Identifier
@param nwords The number of OID words
@param words The actual OID words to get the size of
@param outlen [out] The length of the DER encoding for the given string
@return CRYPT_OK if successful
*/
int der_length_object_identifier(unsigned long *words, unsigned long nwords, unsigned long *outlen)
{
unsigned long y, z, t, wordbuf;
LTC_ARGCHK(words != NULL);
LTC_ARGCHK(outlen != NULL);
/* must be >= 2 words */
if (nwords < 2) {
return CRYPT_INVALID_ARG;
}
/* word1 = 0,1,2,3 and word2 0..39 */
if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) {
return CRYPT_INVALID_ARG;
}
/* leading word is the first two */
z = 0;
wordbuf = words[0] * 40 + words[1];
for (y = 1; y < nwords; y++) {
t = der_object_identifier_bits(wordbuf);
z += t/7 + ((t%7) ? 1 : 0) + (wordbuf == 0 ? 1 : 0);
if (y < nwords - 1) {
/* grab next word */
wordbuf = words[y+1];
}
}
/* now depending on the length our length encoding changes */
if (z < 128) {
z += 2;
} else if (z < 256) {
z += 3;
} else if (z < 65536UL) {
z += 4;
} else {
return CRYPT_INVALID_ARG;
}
*outlen = z;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,91 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_decode_octet_string.c
ASN.1 DER, encode a OCTET STRING, Tom St Denis
*/
#ifdef LTC_DER
/**
Store a OCTET STRING
@param in The DER encoded OCTET STRING
@param inlen The size of the DER OCTET STRING
@param out [out] The array of octets stored (one per char)
@param outlen [in/out] The number of octets stored
@return CRYPT_OK if successful
*/
int der_decode_octet_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long x, y, len;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* must have header at least */
if (inlen < 2) {
return CRYPT_INVALID_PACKET;
}
/* check for 0x04 */
if ((in[0] & 0x1F) != 0x04) {
return CRYPT_INVALID_PACKET;
}
x = 1;
/* decode the length */
if (in[x] & 0x80) {
/* valid # of bytes in length are 1,2,3 */
y = in[x] & 0x7F;
if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
return CRYPT_INVALID_PACKET;
}
/* read the length in */
len = 0;
++x;
while (y--) {
len = (len << 8) | in[x++];
}
} else {
len = in[x++] & 0x7F;
}
/* is it too long? */
if (len > *outlen) {
*outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
if (len + x > inlen) {
return CRYPT_INVALID_PACKET;
}
/* read the data */
for (y = 0; y < len; y++) {
out[y] = in[x++];
}
*outlen = y;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_encode_octet_string.c
ASN.1 DER, encode a OCTET STRING, Tom St Denis
*/
#ifdef LTC_DER
/**
Store an OCTET STRING
@param in The array of OCTETS to store (one per char)
@param inlen The number of OCTETS to store
@param out [out] The destination for the DER encoded OCTET STRING
@param outlen [in/out] The max size and resulting size of the DER OCTET STRING
@return CRYPT_OK if successful
*/
int der_encode_octet_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long x, y, len;
int err;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* get the size */
if ((err = der_length_octet_string(inlen, &len)) != CRYPT_OK) {
return err;
}
/* too big? */
if (len > *outlen) {
*outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
/* encode the header+len */
x = 0;
out[x++] = 0x04;
if (inlen < 128) {
out[x++] = (unsigned char)inlen;
} else if (inlen < 256) {
out[x++] = 0x81;
out[x++] = (unsigned char)inlen;
} else if (inlen < 65536UL) {
out[x++] = 0x82;
out[x++] = (unsigned char)((inlen>>8)&255);
out[x++] = (unsigned char)(inlen&255);
} else if (inlen < 16777216UL) {
out[x++] = 0x83;
out[x++] = (unsigned char)((inlen>>16)&255);
out[x++] = (unsigned char)((inlen>>8)&255);
out[x++] = (unsigned char)(inlen&255);
} else {
return CRYPT_INVALID_ARG;
}
/* store octets */
for (y = 0; y < inlen; y++) {
out[x++] = in[y];
}
/* retun length */
*outlen = x;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,53 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_length_octet_string.c
ASN.1 DER, get length of OCTET STRING, Tom St Denis
*/
#ifdef LTC_DER
/**
Gets length of DER encoding of OCTET STRING
@param noctets The number of octets in the string to encode
@param outlen [out] The length of the DER encoding for the given string
@return CRYPT_OK if successful
*/
int der_length_octet_string(unsigned long noctets, unsigned long *outlen)
{
LTC_ARGCHK(outlen != NULL);
if (noctets < 128) {
/* 04 LL DD DD DD ... */
*outlen = 2 + noctets;
} else if (noctets < 256) {
/* 04 81 LL DD DD DD ... */
*outlen = 3 + noctets;
} else if (noctets < 65536UL) {
/* 04 82 LL LL DD DD DD ... */
*outlen = 4 + noctets;
} else if (noctets < 16777216UL) {
/* 04 83 LL LL LL DD DD DD ... */
*outlen = 5 + noctets;
} else {
return CRYPT_INVALID_ARG;
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_decode_printable_string.c
ASN.1 DER, encode a printable STRING, Tom St Denis
*/
#ifdef LTC_DER
/**
Store a printable STRING
@param in The DER encoded printable STRING
@param inlen The size of the DER printable STRING
@param out [out] The array of octets stored (one per char)
@param outlen [in/out] The number of octets stored
@return CRYPT_OK if successful
*/
int der_decode_printable_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long x, y, len;
int t;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* must have header at least */
if (inlen < 2) {
return CRYPT_INVALID_PACKET;
}
/* check for 0x13 */
if ((in[0] & 0x1F) != 0x13) {
return CRYPT_INVALID_PACKET;
}
x = 1;
/* decode the length */
if (in[x] & 0x80) {
/* valid # of bytes in length are 1,2,3 */
y = in[x] & 0x7F;
if ((y == 0) || (y > 3) || ((x + y) > inlen)) {
return CRYPT_INVALID_PACKET;
}
/* read the length in */
len = 0;
++x;
while (y--) {
len = (len << 8) | in[x++];
}
} else {
len = in[x++] & 0x7F;
}
/* is it too long? */
if (len > *outlen) {
*outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
if (len + x > inlen) {
return CRYPT_INVALID_PACKET;
}
/* read the data */
for (y = 0; y < len; y++) {
t = der_printable_value_decode(in[x++]);
if (t == -1) {
return CRYPT_INVALID_ARG;
}
out[y] = t;
}
*outlen = y;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,85 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_encode_printable_string.c
ASN.1 DER, encode a printable STRING, Tom St Denis
*/
#ifdef LTC_DER
/**
Store an printable STRING
@param in The array of printable to store (one per char)
@param inlen The number of printable to store
@param out [out] The destination for the DER encoded printable STRING
@param outlen [in/out] The max size and resulting size of the DER printable STRING
@return CRYPT_OK if successful
*/
int der_encode_printable_string(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long x, y, len;
int err;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* get the size */
if ((err = der_length_printable_string(in, inlen, &len)) != CRYPT_OK) {
return err;
}
/* too big? */
if (len > *outlen) {
*outlen = len;
return CRYPT_BUFFER_OVERFLOW;
}
/* encode the header+len */
x = 0;
out[x++] = 0x13;
if (inlen < 128) {
out[x++] = (unsigned char)inlen;
} else if (inlen < 256) {
out[x++] = 0x81;
out[x++] = (unsigned char)inlen;
} else if (inlen < 65536UL) {
out[x++] = 0x82;
out[x++] = (unsigned char)((inlen>>8)&255);
out[x++] = (unsigned char)(inlen&255);
} else if (inlen < 16777216UL) {
out[x++] = 0x83;
out[x++] = (unsigned char)((inlen>>16)&255);
out[x++] = (unsigned char)((inlen>>8)&255);
out[x++] = (unsigned char)(inlen&255);
} else {
return CRYPT_INVALID_ARG;
}
/* store octets */
for (y = 0; y < inlen; y++) {
out[x++] = der_printable_char_encode(in[y]);
}
/* retun length */
*outlen = x;
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,166 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_length_printable_string.c
ASN.1 DER, get length of Printable STRING, Tom St Denis
*/
#ifdef LTC_DER
static const struct {
int code, value;
} printable_table[] = {
{ ' ', 32 },
{ '\'', 39 },
{ '(', 40 },
{ ')', 41 },
{ '+', 43 },
{ ',', 44 },
{ '-', 45 },
{ '.', 46 },
{ '/', 47 },
{ '0', 48 },
{ '1', 49 },
{ '2', 50 },
{ '3', 51 },
{ '4', 52 },
{ '5', 53 },
{ '6', 54 },
{ '7', 55 },
{ '8', 56 },
{ '9', 57 },
{ ':', 58 },
{ '=', 61 },
{ '?', 63 },
{ 'A', 65 },
{ 'B', 66 },
{ 'C', 67 },
{ 'D', 68 },
{ 'E', 69 },
{ 'F', 70 },
{ 'G', 71 },
{ 'H', 72 },
{ 'I', 73 },
{ 'J', 74 },
{ 'K', 75 },
{ 'L', 76 },
{ 'M', 77 },
{ 'N', 78 },
{ 'O', 79 },
{ 'P', 80 },
{ 'Q', 81 },
{ 'R', 82 },
{ 'S', 83 },
{ 'T', 84 },
{ 'U', 85 },
{ 'V', 86 },
{ 'W', 87 },
{ 'X', 88 },
{ 'Y', 89 },
{ 'Z', 90 },
{ 'a', 97 },
{ 'b', 98 },
{ 'c', 99 },
{ 'd', 100 },
{ 'e', 101 },
{ 'f', 102 },
{ 'g', 103 },
{ 'h', 104 },
{ 'i', 105 },
{ 'j', 106 },
{ 'k', 107 },
{ 'l', 108 },
{ 'm', 109 },
{ 'n', 110 },
{ 'o', 111 },
{ 'p', 112 },
{ 'q', 113 },
{ 'r', 114 },
{ 's', 115 },
{ 't', 116 },
{ 'u', 117 },
{ 'v', 118 },
{ 'w', 119 },
{ 'x', 120 },
{ 'y', 121 },
{ 'z', 122 },
};
int der_printable_char_encode(int c)
{
int x;
for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) {
if (printable_table[x].code == c) {
return printable_table[x].value;
}
}
return -1;
}
int der_printable_value_decode(int v)
{
int x;
for (x = 0; x < (int)(sizeof(printable_table)/sizeof(printable_table[0])); x++) {
if (printable_table[x].value == v) {
return printable_table[x].code;
}
}
return -1;
}
/**
Gets length of DER encoding of Printable STRING
@param octets The values you want to encode
@param noctets The number of octets in the string to encode
@param outlen [out] The length of the DER encoding for the given string
@return CRYPT_OK if successful
*/
int der_length_printable_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
{
unsigned long x;
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(octets != NULL);
/* scan string for validity */
for (x = 0; x < noctets; x++) {
if (der_printable_char_encode(octets[x]) == -1) {
return CRYPT_INVALID_ARG;
}
}
if (noctets < 128) {
/* 16 LL DD DD DD ... */
*outlen = 2 + noctets;
} else if (noctets < 256) {
/* 16 81 LL DD DD DD ... */
*outlen = 3 + noctets;
} else if (noctets < 65536UL) {
/* 16 82 LL LL DD DD DD ... */
*outlen = 4 + noctets;
} else if (noctets < 16777216UL) {
/* 16 83 LL LL LL DD DD DD ... */
*outlen = 5 + noctets;
} else {
return CRYPT_INVALID_ARG;
}
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,287 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
#include <stdarg.h>
/**
@file der_decode_sequence_ex.c
ASN.1 DER, decode a SEQUENCE, Tom St Denis
*/
#ifdef LTC_DER
/**
Decode a SEQUENCE
@param in The DER encoded input
@param inlen The size of the input
@param list The list of items to decode
@param outlen The number of items in the list
@param ordered Search an unordeded or ordered list
@return CRYPT_OK on success
*/
int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
ltc_asn1_list *list, unsigned long outlen, int ordered)
{
int err, type;
unsigned long size, x, y, z, i, blksize;
void *data;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(list != NULL);
/* get blk size */
if (inlen < 2) {
return CRYPT_INVALID_PACKET;
}
/* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
x = 0;
if (in[x] != 0x30 && in[x] != 0x31) {
return CRYPT_INVALID_PACKET;
}
++x;
if (in[x] < 128) {
blksize = in[x++];
} else if (in[x] & 0x80) {
if (in[x] < 0x81 || in[x] > 0x83) {
return CRYPT_INVALID_PACKET;
}
y = in[x++] & 0x7F;
/* would reading the len bytes overrun? */
if (x + y > inlen) {
return CRYPT_INVALID_PACKET;
}
/* read len */
blksize = 0;
while (y--) {
blksize = (blksize << 8) | (unsigned long)in[x++];
}
}
/* would this blksize overflow? */
if (x + blksize > inlen) {
return CRYPT_INVALID_PACKET;
}
/* mark all as unused */
for (i = 0; i < outlen; i++) {
list[i].used = 0;
}
/* ok read data */
inlen = blksize;
for (i = 0; i < outlen; i++) {
z = 0;
type = list[i].type;
size = list[i].size;
data = list[i].data;
if (!ordered && list[i].used == 1) { continue; }
if (type == LTC_ASN1_EOL) {
break;
}
switch (type) {
case LTC_ASN1_BOOLEAN:
z = inlen;
if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
goto LBL_ERR;
}
if ((err = der_length_boolean(&z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_INTEGER:
z = inlen;
if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_SHORT_INTEGER:
z = inlen;
if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_BIT_STRING:
z = inlen;
if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
list[i].size = size;
if ((err = der_length_bit_string(size, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_OCTET_STRING:
z = inlen;
if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
list[i].size = size;
if ((err = der_length_octet_string(size, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_NULL:
if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
if (!ordered) { continue; }
err = CRYPT_INVALID_PACKET;
goto LBL_ERR;
}
z = 2;
break;
case LTC_ASN1_OBJECT_IDENTIFIER:
z = inlen;
if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
list[i].size = size;
if ((err = der_length_object_identifier(data, size, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_IA5_STRING:
z = inlen;
if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
list[i].size = size;
if ((err = der_length_ia5_string(data, size, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_PRINTABLE_STRING:
z = inlen;
if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
list[i].size = size;
if ((err = der_length_printable_string(data, size, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_UTF8_STRING:
z = inlen;
if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
list[i].size = size;
if ((err = der_length_utf8_string(data, size, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_UTCTIME:
z = inlen;
if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
break;
case LTC_ASN1_SET:
z = inlen;
if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_SETOF:
case LTC_ASN1_SEQUENCE:
/* detect if we have the right type */
if ((type == LTC_ASN1_SETOF && (in[x] & 0x3F) != 0x31) || (type == LTC_ASN1_SEQUENCE && (in[x] & 0x3F) != 0x30)) {
err = CRYPT_INVALID_PACKET;
goto LBL_ERR;
}
z = inlen;
if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
break;
case LTC_ASN1_CHOICE:
z = inlen;
if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
break;
default:
err = CRYPT_INVALID_ARG;
goto LBL_ERR;
}
x += z;
inlen -= z;
list[i].used = 1;
if (!ordered) {
/* restart the decoder */
i = -1;
}
}
for (i = 0; i < outlen; i++) {
if (list[i].used == 0) {
err = CRYPT_INVALID_PACKET;
goto LBL_ERR;
}
}
err = CRYPT_OK;
LBL_ERR:
return err;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,386 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_decode_sequence_flexi.c
ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis
*/
#ifdef LTC_DER
static unsigned long fetch_length(const unsigned char *in, unsigned long inlen)
{
unsigned long x, y, z;
y = 0;
/* skip type and read len */
if (inlen < 2) {
return 0xFFFFFFFF;
}
++in; ++y;
/* read len */
x = *in++; ++y;
/* <128 means literal */
if (x < 128) {
return x+y;
}
x &= 0x7F; /* the lower 7 bits are the length of the length */
inlen -= 2;
/* len means len of len! */
if (x == 0 || x > 4 || x > inlen) {
return 0xFFFFFFFF;
}
y += x;
z = 0;
while (x--) {
z = (z<<8) | ((unsigned long)*in);
++in;
}
return z+y;
}
/**
ASN.1 DER Flexi(ble) decoder will decode arbitrary DER packets and create a linked list of the decoded elements.
@param in The input buffer
@param inlen [in/out] The length of the input buffer and on output the amount of decoded data
@param out [out] A pointer to the linked list
@return CRYPT_OK on success.
*/
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out)
{
ltc_asn1_list *l;
unsigned long err, type, len, totlen, x, y;
void *realloc_tmp;
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(inlen != NULL);
LTC_ARGCHK(out != NULL);
l = NULL;
totlen = 0;
/* scan the input and and get lengths and what not */
while (*inlen) {
/* read the type byte */
type = *in;
/* fetch length */
len = fetch_length(in, *inlen);
if (len > *inlen) {
err = CRYPT_INVALID_PACKET;
goto error;
}
/* alloc new link */
if (l == NULL) {
l = XCALLOC(1, sizeof(*l));
if (l == NULL) {
err = CRYPT_MEM;
goto error;
}
} else {
l->next = XCALLOC(1, sizeof(*l));
if (l->next == NULL) {
err = CRYPT_MEM;
goto error;
}
l->next->prev = l;
l = l->next;
}
/* now switch on type */
switch (type) {
case 0x01: /* BOOLEAN */
l->type = LTC_ASN1_BOOLEAN;
l->size = 1;
l->data = XCALLOC(1, sizeof(int));
if ((err = der_decode_boolean(in, *inlen, l->data)) != CRYPT_OK) {
goto error;
}
if ((err = der_length_boolean(&len)) != CRYPT_OK) {
goto error;
}
break;
case 0x02: /* INTEGER */
/* init field */
l->type = LTC_ASN1_INTEGER;
l->size = 1;
if ((err = mp_init(&l->data)) != CRYPT_OK) {
goto error;
}
/* decode field */
if ((err = der_decode_integer(in, *inlen, l->data)) != CRYPT_OK) {
goto error;
}
/* calc length of object */
if ((err = der_length_integer(l->data, &len)) != CRYPT_OK) {
goto error;
}
break;
case 0x03: /* BIT */
/* init field */
l->type = LTC_ASN1_BIT_STRING;
l->size = len * 8; /* *8 because we store decoded bits one per char and they are encoded 8 per char. */
if ((l->data = XCALLOC(1, l->size)) == NULL) {
err = CRYPT_MEM;
goto error;
}
if ((err = der_decode_bit_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
goto error;
}
if ((err = der_length_bit_string(l->size, &len)) != CRYPT_OK) {
goto error;
}
break;
case 0x04: /* OCTET */
/* init field */
l->type = LTC_ASN1_OCTET_STRING;
l->size = len;
if ((l->data = XCALLOC(1, l->size)) == NULL) {
err = CRYPT_MEM;
goto error;
}
if ((err = der_decode_octet_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
goto error;
}
if ((err = der_length_octet_string(l->size, &len)) != CRYPT_OK) {
goto error;
}
break;
case 0x05: /* NULL */
/* valid NULL is 0x05 0x00 */
if (in[0] != 0x05 || in[1] != 0x00) {
err = CRYPT_INVALID_PACKET;
goto error;
}
/* simple to store ;-) */
l->type = LTC_ASN1_NULL;
l->data = NULL;
l->size = 0;
len = 2;
break;
case 0x06: /* OID */
/* init field */
l->type = LTC_ASN1_OBJECT_IDENTIFIER;
l->size = len;
if ((l->data = XCALLOC(len, sizeof(unsigned long))) == NULL) {
err = CRYPT_MEM;
goto error;
}
if ((err = der_decode_object_identifier(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
goto error;
}
if ((err = der_length_object_identifier(l->data, l->size, &len)) != CRYPT_OK) {
goto error;
}
/* resize it to save a bunch of mem */
if ((realloc_tmp = XREALLOC(l->data, l->size * sizeof(unsigned long))) == NULL) {
/* out of heap but this is not an error */
break;
}
l->data = realloc_tmp;
break;
case 0x0C: /* UTF8 */
/* init field */
l->type = LTC_ASN1_UTF8_STRING;
l->size = len;
if ((l->data = XCALLOC(sizeof(wchar_t), l->size)) == NULL) {
err = CRYPT_MEM;
goto error;
}
if ((err = der_decode_utf8_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
goto error;
}
if ((err = der_length_utf8_string(l->data, l->size, &len)) != CRYPT_OK) {
goto error;
}
break;
case 0x13: /* PRINTABLE */
/* init field */
l->type = LTC_ASN1_PRINTABLE_STRING;
l->size = len;
if ((l->data = XCALLOC(1, l->size)) == NULL) {
err = CRYPT_MEM;
goto error;
}
if ((err = der_decode_printable_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
goto error;
}
if ((err = der_length_printable_string(l->data, l->size, &len)) != CRYPT_OK) {
goto error;
}
break;
case 0x16: /* IA5 */
/* init field */
l->type = LTC_ASN1_IA5_STRING;
l->size = len;
if ((l->data = XCALLOC(1, l->size)) == NULL) {
err = CRYPT_MEM;
goto error;
}
if ((err = der_decode_ia5_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
goto error;
}
if ((err = der_length_ia5_string(l->data, l->size, &len)) != CRYPT_OK) {
goto error;
}
break;
case 0x17: /* UTC TIME */
/* init field */
l->type = LTC_ASN1_UTCTIME;
l->size = 1;
if ((l->data = XCALLOC(1, sizeof(ltc_utctime))) == NULL) {
err = CRYPT_MEM;
goto error;
}
len = *inlen;
if ((err = der_decode_utctime(in, &len, l->data)) != CRYPT_OK) {
goto error;
}
if ((err = der_length_utctime(l->data, &len)) != CRYPT_OK) {
goto error;
}
break;
case 0x30: /* SEQUENCE */
case 0x31: /* SET */
/* init field */
l->type = (type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET;
/* we have to decode the SEQUENCE header and get it's length */
/* move past type */
++in; --(*inlen);
/* read length byte */
x = *in++; --(*inlen);
/* smallest SEQUENCE/SET header */
y = 2;
/* now if it's > 127 the next bytes are the length of the length */
if (x > 128) {
x &= 0x7F;
in += x;
*inlen -= x;
/* update sequence header len */
y += x;
}
/* Sequence elements go as child */
len = len - y;
if ((err = der_decode_sequence_flexi(in, &len, &(l->child))) != CRYPT_OK) {
goto error;
}
/* len update */
totlen += y;
/* link them up y0 */
l->child->parent = l;
break;
default:
/* invalid byte ... this is a soft error */
/* remove link */
l = l->prev;
XFREE(l->next);
l->next = NULL;
goto outside;
}
/* advance pointers */
totlen += len;
in += len;
*inlen -= len;
}
outside:
/* rewind l please */
while (l->prev != NULL || l->parent != NULL) {
if (l->parent != NULL) {
l = l->parent;
} else {
l = l->prev;
}
}
/* return */
*out = l;
*inlen = totlen;
return CRYPT_OK;
error:
/* free list */
der_sequence_free(l);
return err;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,139 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
#include <stdarg.h>
/**
@file der_decode_sequence_multi.c
ASN.1 DER, decode a SEQUENCE, Tom St Denis
*/
#ifdef LTC_DER
/**
Decode a SEQUENCE type using a VA list
@param in Input buffer
@param inlen Length of input in octets
@remark <...> is of the form <type, size, data> (int, unsigned long, void*)
@return CRYPT_OK on success
*/
int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
{
int err, type;
unsigned long size, x;
void *data;
va_list args;
ltc_asn1_list *list;
LTC_ARGCHK(in != NULL);
/* get size of output that will be required */
va_start(args, inlen);
x = 0;
for (;;) {
type = va_arg(args, int);
size = va_arg(args, unsigned long);
data = va_arg(args, void*);
if (type == LTC_ASN1_EOL) {
break;
}
switch (type) {
case LTC_ASN1_BOOLEAN:
case LTC_ASN1_INTEGER:
case LTC_ASN1_SHORT_INTEGER:
case LTC_ASN1_BIT_STRING:
case LTC_ASN1_OCTET_STRING:
case LTC_ASN1_NULL:
case LTC_ASN1_OBJECT_IDENTIFIER:
case LTC_ASN1_IA5_STRING:
case LTC_ASN1_PRINTABLE_STRING:
case LTC_ASN1_UTF8_STRING:
case LTC_ASN1_UTCTIME:
case LTC_ASN1_SET:
case LTC_ASN1_SETOF:
case LTC_ASN1_SEQUENCE:
case LTC_ASN1_CHOICE:
++x;
break;
default:
va_end(args);
return CRYPT_INVALID_ARG;
}
}
va_end(args);
/* allocate structure for x elements */
if (x == 0) {
return CRYPT_NOP;
}
list = XCALLOC(sizeof(*list), x);
if (list == NULL) {
return CRYPT_MEM;
}
/* fill in the structure */
va_start(args, inlen);
x = 0;
for (;;) {
type = va_arg(args, int);
size = va_arg(args, unsigned long);
data = va_arg(args, void*);
if (type == LTC_ASN1_EOL) {
break;
}
switch (type) {
case LTC_ASN1_BOOLEAN:
case LTC_ASN1_INTEGER:
case LTC_ASN1_SHORT_INTEGER:
case LTC_ASN1_BIT_STRING:
case LTC_ASN1_OCTET_STRING:
case LTC_ASN1_NULL:
case LTC_ASN1_OBJECT_IDENTIFIER:
case LTC_ASN1_IA5_STRING:
case LTC_ASN1_PRINTABLE_STRING:
case LTC_ASN1_UTF8_STRING:
case LTC_ASN1_UTCTIME:
case LTC_ASN1_SEQUENCE:
case LTC_ASN1_SET:
case LTC_ASN1_SETOF:
case LTC_ASN1_CHOICE:
list[x].type = type;
list[x].size = size;
list[x++].data = data;
break;
default:
va_end(args);
err = CRYPT_INVALID_ARG;
goto LBL_ERR;
}
}
va_end(args);
err = der_decode_sequence(in, inlen, list, x);
LBL_ERR:
XFREE(list);
return err;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,335 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
#include <stdarg.h>
/**
@file der_encode_sequence_ex.c
ASN.1 DER, encode a SEQUENCE, Tom St Denis
*/
#ifdef LTC_DER
/**
Encode a SEQUENCE
@param list The list of items to encode
@param inlen The number of items in the list
@param out [out] The destination
@param outlen [in/out] The size of the output
@param type_of LTC_ASN1_SEQUENCE or LTC_ASN1_SET/LTC_ASN1_SETOF
@return CRYPT_OK on success
*/
int der_encode_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int type_of)
{
int err, type;
unsigned long size, x, y, z, i;
void *data;
LTC_ARGCHK(list != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* get size of output that will be required */
y = 0;
for (i = 0; i < inlen; i++) {
type = list[i].type;
size = list[i].size;
data = list[i].data;
if (type == LTC_ASN1_EOL) {
break;
}
switch (type) {
case LTC_ASN1_BOOLEAN:
if ((err = der_length_boolean(&x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_INTEGER:
if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_SHORT_INTEGER:
if ((err = der_length_short_integer(*((unsigned long*)data), &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_BIT_STRING:
if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_OCTET_STRING:
if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_NULL:
y += 2;
break;
case LTC_ASN1_OBJECT_IDENTIFIER:
if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_IA5_STRING:
if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_PRINTABLE_STRING:
if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_UTF8_STRING:
if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_UTCTIME:
if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_SET:
case LTC_ASN1_SETOF:
case LTC_ASN1_SEQUENCE:
if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
default:
err = CRYPT_INVALID_ARG;
goto LBL_ERR;
}
}
/* calc header size */
z = y;
if (y < 128) {
y += 2;
} else if (y < 256) {
/* 0x30 0x81 LL */
y += 3;
} else if (y < 65536UL) {
/* 0x30 0x82 LL LL */
y += 4;
} else if (y < 16777216UL) {
/* 0x30 0x83 LL LL LL */
y += 5;
} else {
err = CRYPT_INVALID_ARG;
goto LBL_ERR;
}
/* too big ? */
if (*outlen < y) {
*outlen = y;
err = CRYPT_BUFFER_OVERFLOW;
goto LBL_ERR;
}
/* store header */
x = 0;
out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31;
if (z < 128) {
out[x++] = (unsigned char)z;
} else if (z < 256) {
out[x++] = 0x81;
out[x++] = (unsigned char)z;
} else if (z < 65536UL) {
out[x++] = 0x82;
out[x++] = (unsigned char)((z>>8UL)&255);
out[x++] = (unsigned char)(z&255);
} else if (z < 16777216UL) {
out[x++] = 0x83;
out[x++] = (unsigned char)((z>>16UL)&255);
out[x++] = (unsigned char)((z>>8UL)&255);
out[x++] = (unsigned char)(z&255);
}
/* store data */
*outlen -= x;
for (i = 0; i < inlen; i++) {
type = list[i].type;
size = list[i].size;
data = list[i].data;
if (type == LTC_ASN1_EOL) {
break;
}
switch (type) {
case LTC_ASN1_BOOLEAN:
z = *outlen;
if ((err = der_encode_boolean(*((int *)data), out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_INTEGER:
z = *outlen;
if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_SHORT_INTEGER:
z = *outlen;
if ((err = der_encode_short_integer(*((unsigned long*)data), out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_BIT_STRING:
z = *outlen;
if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_OCTET_STRING:
z = *outlen;
if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_NULL:
out[x++] = 0x05;
out[x++] = 0x00;
*outlen -= 2;
break;
case LTC_ASN1_OBJECT_IDENTIFIER:
z = *outlen;
if ((err = der_encode_object_identifier(data, size, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_IA5_STRING:
z = *outlen;
if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_PRINTABLE_STRING:
z = *outlen;
if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_UTF8_STRING:
z = *outlen;
if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_UTCTIME:
z = *outlen;
if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_SET:
z = *outlen;
if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_SETOF:
z = *outlen;
if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
case LTC_ASN1_SEQUENCE:
z = *outlen;
if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
*outlen -= z;
break;
default:
err = CRYPT_INVALID_ARG;
goto LBL_ERR;
}
}
*outlen = x;
err = CRYPT_OK;
LBL_ERR:
return err;
}
#endif
@@ -0,0 +1,138 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
#include <stdarg.h>
/**
@file der_encode_sequence_multi.c
ASN.1 DER, encode a SEQUENCE, Tom St Denis
*/
#ifdef LTC_DER
/**
Encode a SEQUENCE type using a VA list
@param out [out] Destination for data
@param outlen [in/out] Length of buffer and resulting length of output
@remark <...> is of the form <type, size, data> (int, unsigned long, void*)
@return CRYPT_OK on success
*/
int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
{
int err, type;
unsigned long size, x;
void *data;
va_list args;
ltc_asn1_list *list;
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
/* get size of output that will be required */
va_start(args, outlen);
x = 0;
for (;;) {
type = va_arg(args, int);
size = va_arg(args, unsigned long);
data = va_arg(args, void*);
if (type == LTC_ASN1_EOL) {
break;
}
switch (type) {
case LTC_ASN1_BOOLEAN:
case LTC_ASN1_INTEGER:
case LTC_ASN1_SHORT_INTEGER:
case LTC_ASN1_BIT_STRING:
case LTC_ASN1_OCTET_STRING:
case LTC_ASN1_NULL:
case LTC_ASN1_OBJECT_IDENTIFIER:
case LTC_ASN1_IA5_STRING:
case LTC_ASN1_PRINTABLE_STRING:
case LTC_ASN1_UTF8_STRING:
case LTC_ASN1_UTCTIME:
case LTC_ASN1_SEQUENCE:
case LTC_ASN1_SET:
case LTC_ASN1_SETOF:
++x;
break;
default:
va_end(args);
return CRYPT_INVALID_ARG;
}
}
va_end(args);
/* allocate structure for x elements */
if (x == 0) {
return CRYPT_NOP;
}
list = XCALLOC(sizeof(*list), x);
if (list == NULL) {
return CRYPT_MEM;
}
/* fill in the structure */
va_start(args, outlen);
x = 0;
for (;;) {
type = va_arg(args, int);
size = va_arg(args, unsigned long);
data = va_arg(args, void*);
if (type == LTC_ASN1_EOL) {
break;
}
switch (type) {
case LTC_ASN1_BOOLEAN:
case LTC_ASN1_INTEGER:
case LTC_ASN1_SHORT_INTEGER:
case LTC_ASN1_BIT_STRING:
case LTC_ASN1_OCTET_STRING:
case LTC_ASN1_NULL:
case LTC_ASN1_OBJECT_IDENTIFIER:
case LTC_ASN1_IA5_STRING:
case LTC_ASN1_PRINTABLE_STRING:
case LTC_ASN1_UTF8_STRING:
case LTC_ASN1_UTCTIME:
case LTC_ASN1_SEQUENCE:
case LTC_ASN1_SET:
case LTC_ASN1_SETOF:
list[x].type = type;
list[x].size = size;
list[x++].data = data;
break;
default:
va_end(args);
err = CRYPT_INVALID_ARG;
goto LBL_ERR;
}
}
va_end(args);
err = der_encode_sequence(list, x, out, outlen);
LBL_ERR:
XFREE(list);
return err;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,169 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_length_sequence.c
ASN.1 DER, length a SEQUENCE, Tom St Denis
*/
#ifdef LTC_DER
/**
Get the length of a DER sequence
@param list The sequences of items in the SEQUENCE
@param inlen The number of items
@param outlen [out] The length required in octets to store it
@return CRYPT_OK on success
*/
int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
unsigned long *outlen)
{
int err, type;
unsigned long size, x, y, z, i;
void *data;
LTC_ARGCHK(list != NULL);
LTC_ARGCHK(outlen != NULL);
/* get size of output that will be required */
y = 0;
for (i = 0; i < inlen; i++) {
type = list[i].type;
size = list[i].size;
data = list[i].data;
if (type == LTC_ASN1_EOL) {
break;
}
switch (type) {
case LTC_ASN1_BOOLEAN:
if ((err = der_length_boolean(&x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_INTEGER:
if ((err = der_length_integer(data, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_SHORT_INTEGER:
if ((err = der_length_short_integer(*((unsigned long *)data), &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_BIT_STRING:
if ((err = der_length_bit_string(size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_OCTET_STRING:
if ((err = der_length_octet_string(size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_NULL:
y += 2;
break;
case LTC_ASN1_OBJECT_IDENTIFIER:
if ((err = der_length_object_identifier(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_IA5_STRING:
if ((err = der_length_ia5_string(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_PRINTABLE_STRING:
if ((err = der_length_printable_string(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_UTCTIME:
if ((err = der_length_utctime(data, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_UTF8_STRING:
if ((err = der_length_utf8_string(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
case LTC_ASN1_SET:
case LTC_ASN1_SETOF:
case LTC_ASN1_SEQUENCE:
if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
goto LBL_ERR;
}
y += x;
break;
default:
err = CRYPT_INVALID_ARG;
goto LBL_ERR;
}
}
/* calc header size */
z = y;
if (y < 128) {
y += 2;
} else if (y < 256) {
/* 0x30 0x81 LL */
y += 3;
} else if (y < 65536UL) {
/* 0x30 0x82 LL LL */
y += 4;
} else if (y < 16777216UL) {
/* 0x30 0x83 LL LL LL */
y += 5;
} else {
err = CRYPT_INVALID_ARG;
goto LBL_ERR;
}
/* store size */
*outlen = y;
err = CRYPT_OK;
LBL_ERR:
return err;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,65 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_sequence_free.c
ASN.1 DER, free's a structure allocated by der_decode_sequence_flexi(), Tom St Denis
*/
#ifdef LTC_DER
/**
Free memory allocated by der_decode_sequence_flexi()
@param in The list to free
*/
void der_sequence_free(ltc_asn1_list *in)
{
ltc_asn1_list *l;
/* walk to the start of the chain */
while (in->prev != NULL || in->parent != NULL) {
if (in->parent != NULL) {
in = in->parent;
} else {
in = in->prev;
}
}
/* now walk the list and free stuff */
while (in != NULL) {
/* is there a child? */
if (in->child) {
/* disconnect */
in->child->parent = NULL;
der_sequence_free(in->child);
}
switch (in->type) {
case LTC_ASN1_SET:
case LTC_ASN1_SETOF:
case LTC_ASN1_SEQUENCE: break;
case LTC_ASN1_INTEGER : if (in->data != NULL) { mp_clear(in->data); } break;
default : if (in->data != NULL) { XFREE(in->data); }
}
/* move to next and free current */
l = in->next;
free(in);
in = l;
}
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -0,0 +1,103 @@
/* 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, [email protected], http://libtomcrypt.com
*/
#include "tomcrypt.h"
/**
@file der_encode_set.c
ASN.1 DER, Encode a SET, Tom St Denis
*/
#ifdef LTC_DER
/* LTC define to ASN.1 TAG */
static int ltc_to_asn1(int v)
{
switch (v) {
case LTC_ASN1_BOOLEAN: return 0x01;
case LTC_ASN1_INTEGER:
case LTC_ASN1_SHORT_INTEGER: return 0x02;
case LTC_ASN1_BIT_STRING: return 0x03;
case LTC_ASN1_OCTET_STRING: return 0x04;
case LTC_ASN1_NULL: return 0x05;
case LTC_ASN1_OBJECT_IDENTIFIER: return 0x06;
case LTC_ASN1_UTF8_STRING: return 0x0C;
case LTC_ASN1_PRINTABLE_STRING: return 0x13;
case LTC_ASN1_IA5_STRING: return 0x16;
case LTC_ASN1_UTCTIME: return 0x17;
case LTC_ASN1_SEQUENCE: return 0x30;
case LTC_ASN1_SET:
case LTC_ASN1_SETOF: return 0x31;
default: return -1;
}
}
static int qsort_helper(const void *a, const void *b)
{
ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
int r;
r = ltc_to_asn1(A->type) - ltc_to_asn1(B->type);
/* for QSORT the order is UNDEFINED if they are "equal" which means it is NOT DETERMINISTIC. So we force it to be :-) */
if (r == 0) {
/* their order in the original list now determines the position */
return A->used - B->used;
} else {
return r;
}
}
/*
Encode a SET type
@param list The list of items to encode
@param inlen The number of items in the list
@param out [out] The destination
@param outlen [in/out] The size of the output
@return CRYPT_OK on success
*/
int der_encode_set(ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
ltc_asn1_list *copy;
unsigned long x;
int err;
/* make copy of list */
copy = XCALLOC(inlen, sizeof(*copy));
if (copy == NULL) {
return CRYPT_MEM;
}
/* fill in used member with index so we can fully sort it */
for (x = 0; x < inlen; x++) {
copy[x] = list[x];
copy[x].used = x;
}
/* sort it by the "type" field */
XQSORT(copy, inlen, sizeof(*copy), &qsort_helper);
/* call der_encode_sequence_ex() */
err = der_encode_sequence_ex(copy, inlen, out, outlen, LTC_ASN1_SET);
/* free list */
XFREE(copy);
return err;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */

Some files were not shown because too many files have changed in this diff Show More