added libtomcrypt-1.08

This commit is contained in:
Tom St Denis
2005-11-24 11:57:58 +00:00
committed by Steffen Jaeckel
parent 4a1a5796de
commit 1eeff0bfb4
34 changed files with 754 additions and 187 deletions
@@ -144,6 +144,8 @@ int der_decode_choice(const unsigned char *in, unsigned long *inlen,
}
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) {
@@ -13,7 +13,7 @@
/**
@file der_decode_sequence.c
@file der_decode_sequence_ex.c
ASN.1 DER, decode a SEQUENCE, Tom St Denis
*/
@@ -25,10 +25,11 @@
@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(const unsigned char *in, unsigned long inlen,
ltc_asn1_list *list, unsigned long outlen)
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;
@@ -36,17 +37,18 @@ int der_decode_sequence(const unsigned char *in, unsigned long inlen,
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(list != NULL);
/* get blk size */
if (inlen < 2) {
return CRYPT_INVALID_PACKET;
}
/* sequence type? */
/* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
x = 0;
if (in[x++] != 0x30) {
if (in[x] != 0x30 && in[x] != 0x31) {
return CRYPT_INVALID_PACKET;
}
++x;
if (in[x] < 128) {
blksize = in[x++];
@@ -73,12 +75,19 @@ int der_decode_sequence(const unsigned char *in, unsigned long 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;
@@ -88,139 +97,155 @@ int der_decode_sequence(const unsigned char *in, unsigned long inlen,
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;
}
x += z;
inlen -= z;
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(size, &z)) != CRYPT_OK) {
if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
goto LBL_ERR;
}
x += z;
inlen -= z;
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;
}
x += z;
inlen -= z;
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;
}
x += z;
inlen -= z;
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;
}
x += 2;
inlen -= 2;
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;
}
x += z;
inlen -= z;
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;
}
x += z;
inlen -= z;
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;
}
x += z;
inlen -= z;
break;
case LTC_ASN1_UTCTIME:
z = inlen;
if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
if (!ordered) { continue; }
goto LBL_ERR;
}
x += z;
inlen -= z;
break;
case LTC_ASN1_SEQUENCE:
case LTC_ASN1_SET:
z = inlen;
if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
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:
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;
}
x += z;
inlen -= z;
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;
}
x += z;
inlen -= z;
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:
@@ -12,7 +12,7 @@
/**
@file der_decode_sequence_flexi.c
ASN.1 DER, decode a SEQUENCE with a flexi parser, Tom St Denis
ASN.1 DER, decode an array of ASN.1 types with a flexi parser, Tom St Denis
*/
#ifdef LTC_DER
@@ -268,9 +268,10 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
break;
case 0x30: /* SEQUENCE */
case 0x31: /* SET */
/* init field */
l->type = LTC_ASN1_SEQUENCE;
l->type = (type == 0x30) ? LTC_ASN1_SEQUENCE : LTC_ASN1_SET;
/* we have to decode the SEQUENCE header and get it's length */
@@ -280,7 +281,7 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc
/* read length byte */
x = *in++; --(*inlen);
/* smallest SEQUENCE header */
/* smallest SEQUENCE/SET header */
y = 2;
/* now if it's > 127 the next bytes are the length of the length */
@@ -51,6 +51,8 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
case LTC_ASN1_IA5_STRING:
case LTC_ASN1_PRINTABLE_STRING:
case LTC_ASN1_UTCTIME:
case LTC_ASN1_SET:
case LTC_ASN1_SETOF:
case LTC_ASN1_SEQUENCE:
case LTC_ASN1_CHOICE:
++x;
@@ -96,6 +98,8 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
case LTC_ASN1_PRINTABLE_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;
@@ -13,7 +13,7 @@
/**
@file der_encode_sequence.c
@file der_encode_sequence_ex.c
ASN.1 DER, encode a SEQUENCE, Tom St Denis
*/
@@ -25,10 +25,11 @@
@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(ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
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;
@@ -110,13 +111,14 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
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;
@@ -150,7 +152,8 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
/* store header */
x = 0;
out[x++] = 0x30;
out[x++] = (type_of == LTC_ASN1_SEQUENCE) ? 0x30 : 0x31;
if (z < 128) {
out[x++] = z;
} else if (z < 256) {
@@ -257,15 +260,33 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
*outlen -= z;
break;
case LTC_ASN1_SEQUENCE:
case LTC_ASN1_SET:
z = *outlen;
if ((err = der_encode_sequence(data, size, out + x, &z)) != CRYPT_OK) {
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;
@@ -53,6 +53,8 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
case LTC_ASN1_PRINTABLE_STRING:
case LTC_ASN1_UTCTIME:
case LTC_ASN1_SEQUENCE:
case LTC_ASN1_SET:
case LTC_ASN1_SETOF:
++x;
break;
@@ -96,6 +98,8 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
case LTC_ASN1_PRINTABLE_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;
@@ -9,8 +9,6 @@
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
*/
#include "tomcrypt.h"
#include <stdarg.h>
/**
@file der_length_sequence.c
@@ -108,6 +106,8 @@ int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
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;
@@ -149,3 +149,7 @@ LBL_ERR:
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -44,6 +44,8 @@ void der_sequence_free(ltc_asn1_list *in)
}
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); }
+93
View File
@@ -0,0 +1,93 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
*/
#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_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_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;
}
}
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$ */
+154
View File
@@ -0,0 +1,154 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis
*
* LibTomCrypt is a library that provides various cryptographic
* algorithms in a highly modular and flexible manner.
*
* The library is free for all purposes without any express
* guarantee it works.
*
* Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.org
*/
#include "tomcrypt.h"
/**
@file der_encode_setof.c
ASN.1 DER, Encode SET OF, Tom St Denis
*/
#ifdef LTC_DER
struct edge {
unsigned char *start;
unsigned long size;
};
static int qsort_helper(const void *a, const void *b)
{
struct edge *A = (struct edge *)a, *B = (struct edge *)b;
int r;
unsigned long x;
/* compare min length */
r = XMEMCMP(A->start, B->start, MIN(A->size, B->size));
if (r == 0 && A->size != B->size) {
if (A->size > B->size) {
for (x = B->size; x < A->size; x++) {
if (A->start[x]) {
return 1;
}
}
} else {
for (x = A->size; x < B->size; x++) {
if (B->start[x]) {
return -1;
}
}
}
}
return r;
}
int der_encode_setof(ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen)
{
unsigned long x, y, z, hdrlen;
int err;
struct edge *edges;
unsigned char *ptr, *buf;
/* check that they're all the same type */
for (x = 1; x < inlen; x++) {
if (list[x].type != list[x-1].type) {
return CRYPT_INVALID_ARG;
}
}
/* alloc buffer to store copy of output */
buf = XCALLOC(1, *outlen);
if (buf == NULL) {
return CRYPT_MEM;
}
/* encode list */
if ((err = der_encode_sequence_ex(list, inlen, buf, outlen, LTC_ASN1_SETOF)) != CRYPT_OK) {
XFREE(buf);
return err;
}
/* allocate edges */
edges = XCALLOC(inlen, sizeof(*edges));
if (edges == NULL) {
XFREE(buf);
return CRYPT_MEM;
}
/* skip header */
ptr = buf + 1;
/* now skip length data */
x = *ptr++;
if (x >= 0x80) {
ptr += (x & 0x7F);
}
/* get the size of the static header */
hdrlen = ((unsigned long)ptr) - ((unsigned long)buf);
/* scan for edges */
x = 0;
while (ptr < (buf + *outlen)) {
/* store start */
edges[x].start = ptr;
/* skip type */
z = 1;
/* parse length */
y = ptr[z++];
if (y < 128) {
edges[x].size = y;
} else {
y &= 0x7F;
edges[x].size = 0;
while (y--) {
edges[x].size = (edges[x].size << 8) | ((unsigned long)ptr[z++]);
}
}
/* skip content */
edges[x].size += z;
ptr += edges[x].size;
++x;
}
/* sort based on contents (using edges) */
XQSORT(edges, inlen, sizeof(*edges), &qsort_helper);
/* copy static header */
XMEMCPY(out, buf, hdrlen);
/* copy+sort using edges+indecies to output from buffer */
for (y = hdrlen, x = 0; x < inlen; x++) {
XMEMCPY(out+y, edges[x].start, edges[x].size);
y += edges[x].size;
}
#ifdef LTC_CLEAN_STACK
zeromem(buf, *outlen);
#endif
/* free buffers */
XFREE(edges);
XFREE(buf);
return CRYPT_OK;
}
#endif
/* $Source$ */
/* $Revision$ */
/* $Date$ */
@@ -39,7 +39,7 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen)
++z;
y >>= 8;
}
/* handle zero */
if (z == 0) {
z = 1;
@@ -59,6 +59,7 @@ int der_length_short_integer(unsigned long num, unsigned long *outlen)
/* return length */
*outlen = len;
return CRYPT_OK;
}
+1 -1
View File
@@ -15,7 +15,7 @@
DSA Crypto, Tom St Denis
*/
#ifdef MECC
#ifdef MDSA
/**
Decrypt an DSA encrypted key
+1 -1
View File
@@ -70,7 +70,7 @@ int rsa_decrypt_key(const unsigned char *in, unsigned long inlen,
/* rsa decode the packet */
x = inlen;
if ((err = rsa_exptmod(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) {
if ((err = ltc_mp.rsa_me(in, inlen, tmp, &x, PK_PRIVATE, key)) != CRYPT_OK) {
XFREE(tmp);
return err;
}
+1 -1
View File
@@ -70,7 +70,7 @@ int rsa_encrypt_key(const unsigned char *in, unsigned long inlen,
}
/* rsa exptmod the OAEP pad */
return rsa_exptmod(out, x, out, outlen, PK_PUBLIC, key);
return ltc_mp.rsa_me(out, x, out, outlen, PK_PUBLIC, key);
}
#endif /* MRSA */
-5
View File
@@ -35,11 +35,6 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
unsigned long x;
int err;
/* Try the accelerator if present */
if (ltc_mp.rsa_me != NULL) {
return ltc_mp.rsa_me(in, inlen, out, outlen, which, key);
}
LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
-7
View File
@@ -32,14 +32,7 @@ int rsa_make_key(prng_state *prng, int wprng, int size, long e, rsa_key *key)
int err;
LTC_ARGCHK(ltc_mp.name != NULL);
/* check for descriptor */
if (ltc_mp.rsa_keygen != NULL) {
return ltc_mp.rsa_keygen(prng, wprng, size, e, key);
}
LTC_ARGCHK(key != NULL);
if ((size < (MIN_RSA_SIZE/8)) || (size > (MAX_RSA_SIZE/8))) {
return CRYPT_INVALID_KEYSIZE;
+1 -1
View File
@@ -69,7 +69,7 @@ int rsa_sign_hash(const unsigned char *in, unsigned long inlen,
}
/* RSA encode it */
return rsa_exptmod(out, x, out, outlen, PK_PRIVATE, key);
return ltc_mp.rsa_me(out, x, out, outlen, PK_PRIVATE, key);
}
#endif /* MRSA */
+1 -1
View File
@@ -68,7 +68,7 @@ int rsa_verify_hash(const unsigned char *sig, unsigned long siglen,
/* RSA decode it */
x = siglen;
if ((err = rsa_exptmod(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) {
if ((err = ltc_mp.rsa_me(sig, siglen, tmpbuf, &x, PK_PUBLIC, key)) != CRYPT_OK) {
XFREE(tmpbuf);
return err;
}