added libtomcrypt-1.05
This commit is contained in:
committed by
Steffen Jaeckel
parent
9da48eb84b
commit
9264e34ffb
@@ -16,8 +16,8 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/* version */
|
||||
#define CRYPT 0x0104
|
||||
#define SCRYPT "1.04"
|
||||
#define CRYPT 0x0105
|
||||
#define SCRYPT "1.05"
|
||||
|
||||
/* max size of either a cipher/hash block or symmetric key [largest of the two] */
|
||||
#define MAXBLOCKSIZE 128
|
||||
|
||||
@@ -618,12 +618,11 @@ int ctr_done(symmetric_CTR *ctr);
|
||||
int find_cipher(const char *name);
|
||||
int find_cipher_any(const char *name, int blocklen, int keylen);
|
||||
int find_cipher_id(unsigned char ID);
|
||||
|
||||
int register_cipher(const struct ltc_cipher_descriptor *cipher);
|
||||
int unregister_cipher(const struct ltc_cipher_descriptor *cipher);
|
||||
|
||||
int cipher_is_valid(int idx);
|
||||
|
||||
LTC_MUTEX_PROTO(ltc_cipher_mutex);
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
|
||||
@@ -229,6 +229,28 @@
|
||||
#endif
|
||||
|
||||
|
||||
/* THREAD management */
|
||||
|
||||
#ifdef LTC_PTHREAD
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#define LTC_MUTEX_GLOBAL(x) pthread_mutex_t x = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define LTC_MUTEX_PROTO(x) extern pthread_mutex_t x;
|
||||
#define LTC_MUTEX_LOCK(x) pthread_mutex_lock(x);
|
||||
#define LTC_MUTEX_UNLOCK(x) pthread_mutex_unlock(x);
|
||||
|
||||
#else
|
||||
|
||||
/* default no functions */
|
||||
#define LTC_MUTEX_GLOBAL(x)
|
||||
#define LTC_MUTEX_PROTO(x)
|
||||
#define LTC_MUTEX_LOCK(x)
|
||||
#define LTC_MUTEX_UNLOCK(x)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
||||
@@ -279,6 +279,8 @@ int register_hash(const struct ltc_hash_descriptor *hash);
|
||||
int unregister_hash(const struct ltc_hash_descriptor *hash);
|
||||
int hash_is_valid(int idx);
|
||||
|
||||
LTC_MUTEX_PROTO(ltc_hash_mutex);
|
||||
|
||||
int hash_memory(int hash,
|
||||
const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
@@ -259,7 +259,9 @@ enum {
|
||||
LTC_ASN1_OBJECT_IDENTIFIER,
|
||||
LTC_ASN1_IA5_STRING,
|
||||
LTC_ASN1_PRINTABLE_STRING,
|
||||
LTC_ASN1_UTCTIME,
|
||||
|
||||
LTC_ASN1_CHOICE,
|
||||
LTC_ASN1_SEQUENCE
|
||||
};
|
||||
|
||||
@@ -267,6 +269,7 @@ typedef struct {
|
||||
int type;
|
||||
void *data;
|
||||
unsigned long size;
|
||||
int used;
|
||||
} ltc_asn1_list;
|
||||
|
||||
#define LTC_SET_ASN1(list, index, Type, Data, Size) \
|
||||
@@ -276,6 +279,7 @@ typedef struct {
|
||||
LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \
|
||||
LTC_MACRO_list[LTC_MACRO_temp].data = (Data); \
|
||||
LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
|
||||
LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
|
||||
} while (0);
|
||||
|
||||
/* SEQUENCE */
|
||||
@@ -344,6 +348,32 @@ int der_length_printable_string(const unsigned char *octets, unsigned long nocte
|
||||
int der_printable_char_encode(int c);
|
||||
int der_printable_value_decode(int v);
|
||||
|
||||
/* CHOICE */
|
||||
int der_decode_choice(const unsigned char *in, unsigned long *inlen,
|
||||
ltc_asn1_list *list, unsigned long outlen);
|
||||
|
||||
/* UTCTime */
|
||||
typedef struct {
|
||||
unsigned YY, /* year */
|
||||
MM, /* month */
|
||||
DD, /* day */
|
||||
hh, /* hour */
|
||||
mm, /* minute */
|
||||
ss, /* second */
|
||||
off_dir, /* timezone offset direction 0 == +, 1 == - */
|
||||
off_hh, /* timezone offset hours */
|
||||
off_mm; /* timezone offset minutes */
|
||||
} ltc_utctime;
|
||||
|
||||
int der_encode_utctime(ltc_utctime *utctime,
|
||||
unsigned char *out, unsigned long *outlen);
|
||||
|
||||
int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
|
||||
ltc_utctime *out);
|
||||
|
||||
int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source$ */
|
||||
|
||||
@@ -178,6 +178,7 @@ int find_prng(const char *name);
|
||||
int register_prng(const struct ltc_prng_descriptor *prng);
|
||||
int unregister_prng(const struct ltc_prng_descriptor *prng);
|
||||
int prng_is_valid(int idx);
|
||||
LTC_MUTEX_PROTO(ltc_prng_mutex);
|
||||
|
||||
/* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this
|
||||
* might not work on all platforms as planned
|
||||
|
||||
@@ -301,6 +301,9 @@ const char *crypt_build_settings =
|
||||
#endif
|
||||
#if defined(LTC_NO_TABLES)
|
||||
" LTC_NO_TABLES "
|
||||
#endif
|
||||
#if defined(LTC_PTHREAD)
|
||||
" LTC_PTHREAD "
|
||||
#endif
|
||||
"\n"
|
||||
"\n\n\n"
|
||||
|
||||
@@ -19,6 +19,8 @@ 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 }
|
||||
};
|
||||
|
||||
LTC_MUTEX_GLOBAL(ltc_cipher_mutex);
|
||||
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
|
||||
@@ -22,9 +22,12 @@
|
||||
*/
|
||||
int cipher_is_valid(int idx)
|
||||
{
|
||||
LTC_MUTEX_LOCK(<c_cipher_mutex);
|
||||
if (idx < 0 || idx >= TAB_SIZE || cipher_descriptor[idx].name == NULL) {
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return CRYPT_INVALID_CIPHER;
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,14 @@ int find_cipher(const char *name)
|
||||
{
|
||||
int x;
|
||||
LTC_ARGCHK(name != NULL);
|
||||
LTC_MUTEX_LOCK(<c_cipher_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (cipher_descriptor[x].name != NULL && !strcmp(cipher_descriptor[x].name, name)) {
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,14 +31,17 @@ int find_cipher_any(const char *name, int blocklen, int keylen)
|
||||
x = find_cipher(name);
|
||||
if (x != -1) return x;
|
||||
|
||||
LTC_MUTEX_LOCK(<c_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(<c_cipher_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,11 +23,15 @@
|
||||
int find_cipher_id(unsigned char ID)
|
||||
{
|
||||
int x;
|
||||
LTC_MUTEX_LOCK(<c_cipher_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (cipher_descriptor[x].ID == ID) {
|
||||
return (cipher_descriptor[x].name == NULL) ? -1 : x;
|
||||
x = (cipher_descriptor[x].name == NULL) ? -1 : x;
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,14 @@ int find_hash(const char *name)
|
||||
{
|
||||
int x;
|
||||
LTC_ARGCHK(name != NULL);
|
||||
LTC_MUTEX_LOCK(<c_hash_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (hash_descriptor[x].name != NULL && strcmp(hash_descriptor[x].name, name) == 0) {
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
x = find_hash(name);
|
||||
if (x != -1) return x;
|
||||
|
||||
LTC_MUTEX_LOCK(<c_hash_mutex);
|
||||
y = MAXBLOCKSIZE+1;
|
||||
z = -1;
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
@@ -39,6 +40,7 @@
|
||||
y = hash_descriptor[x].hashsize;
|
||||
}
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return z;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,11 +23,15 @@
|
||||
int find_hash_id(unsigned char ID)
|
||||
{
|
||||
int x;
|
||||
LTC_MUTEX_LOCK(<c_hash_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (hash_descriptor[x].ID == ID) {
|
||||
return (hash_descriptor[x].name == NULL) ? -1 : x;
|
||||
}
|
||||
if (hash_descriptor[x].ID == ID) {
|
||||
x = (hash_descriptor[x].name == NULL) ? -1 : x;
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,14 @@ int find_prng(const char *name)
|
||||
{
|
||||
int x;
|
||||
LTC_ARGCHK(name != NULL);
|
||||
LTC_MUTEX_LOCK(<c_prng_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if ((prng_descriptor[x].name != NULL) && strcmp(prng_descriptor[x].name, name) == 0) {
|
||||
LTC_MUTEX_UNLOCK(<c_prng_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_prng_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@ struct ltc_hash_descriptor hash_descriptor[TAB_SIZE] = {
|
||||
{ NULL, 0, 0, 0, { 0 }, 0, NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
LTC_MUTEX_GLOBAL(ltc_hash_mutex);
|
||||
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
|
||||
@@ -22,9 +22,12 @@
|
||||
*/
|
||||
int hash_is_valid(int idx)
|
||||
{
|
||||
LTC_MUTEX_LOCK(<c_hash_mutex);
|
||||
if (idx < 0 || idx >= TAB_SIZE || hash_descriptor[idx].name == NULL) {
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,9 @@ 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$ */
|
||||
|
||||
@@ -22,9 +22,12 @@
|
||||
*/
|
||||
int prng_is_valid(int idx)
|
||||
{
|
||||
LTC_MUTEX_LOCK(<c_prng_mutex);
|
||||
if (idx < 0 || idx >= TAB_SIZE || prng_descriptor[idx].name == NULL) {
|
||||
LTC_MUTEX_UNLOCK(<c_prng_mutex);
|
||||
return CRYPT_INVALID_PRNG;
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_prng_mutex);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,10 @@ int register_cipher(const struct ltc_cipher_descriptor *cipher)
|
||||
LTC_ARGCHK(cipher != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
LTC_MUTEX_LOCK(<c_cipher_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (cipher_descriptor[x].name != NULL && cipher_descriptor[x].ID == cipher->ID) {
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
@@ -37,11 +39,13 @@ int register_cipher(const struct ltc_cipher_descriptor *cipher)
|
||||
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(<c_cipher_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* no spot */
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,10 @@ int register_hash(const struct ltc_hash_descriptor *hash)
|
||||
LTC_ARGCHK(hash != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
LTC_MUTEX_LOCK(<c_hash_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (memcmp(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
@@ -37,11 +39,13 @@ int register_hash(const struct ltc_hash_descriptor *hash)
|
||||
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(<c_hash_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* no spot */
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,8 +27,10 @@ int register_prng(const struct ltc_prng_descriptor *prng)
|
||||
LTC_ARGCHK(prng != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
LTC_MUTEX_LOCK(<c_prng_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (memcmp(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) == 0) {
|
||||
LTC_MUTEX_UNLOCK(<c_prng_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
@@ -37,11 +39,13 @@ int register_prng(const struct ltc_prng_descriptor *prng)
|
||||
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(<c_prng_mutex);
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* no spot */
|
||||
LTC_MUTEX_UNLOCK(<c_prng_mutex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,13 +27,16 @@ int unregister_cipher(const struct ltc_cipher_descriptor *cipher)
|
||||
LTC_ARGCHK(cipher != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
LTC_MUTEX_LOCK(<c_cipher_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (memcmp(&cipher_descriptor[x], cipher, sizeof(struct ltc_cipher_descriptor)) == 0) {
|
||||
cipher_descriptor[x].name = NULL;
|
||||
cipher_descriptor[x].ID = 255;
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_cipher_mutex);
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,12 +27,15 @@ int unregister_hash(const struct ltc_hash_descriptor *hash)
|
||||
LTC_ARGCHK(hash != NULL);
|
||||
|
||||
/* is it already registered? */
|
||||
LTC_MUTEX_LOCK(<c_hash_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (memcmp(&hash_descriptor[x], hash, sizeof(struct ltc_hash_descriptor)) == 0) {
|
||||
hash_descriptor[x].name = NULL;
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_hash_mutex);
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,14 +25,17 @@ int unregister_prng(const struct ltc_prng_descriptor *prng)
|
||||
int x;
|
||||
|
||||
LTC_ARGCHK(prng != NULL);
|
||||
|
||||
|
||||
/* is it already registered? */
|
||||
LTC_MUTEX_LOCK(<c_prng_mutex);
|
||||
for (x = 0; x < TAB_SIZE; x++) {
|
||||
if (memcmp(&prng_descriptor[x], prng, sizeof(struct ltc_prng_descriptor)) != 0) {
|
||||
prng_descriptor[x].name = NULL;
|
||||
LTC_MUTEX_UNLOCK(<c_prng_mutex);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
LTC_MUTEX_UNLOCK(<c_prng_mutex);
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
/* 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_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;
|
||||
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_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_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$ */
|
||||
@@ -185,6 +185,15 @@ int der_decode_sequence(const unsigned char *in, unsigned long inlen,
|
||||
inlen -= z;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_UTCTIME:
|
||||
z = inlen;
|
||||
if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
x += z;
|
||||
inlen -= z;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
z = inlen;
|
||||
if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
|
||||
@@ -197,6 +206,16 @@ int der_decode_sequence(const unsigned char *in, unsigned long inlen,
|
||||
inlen -= z;
|
||||
break;
|
||||
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
z = inlen;
|
||||
if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
x += z;
|
||||
inlen -= z;
|
||||
break;
|
||||
|
||||
default:
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto LBL_ERR;
|
||||
|
||||
@@ -50,7 +50,9 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
||||
case LTC_ASN1_OBJECT_IDENTIFIER:
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
case LTC_ASN1_UTCTIME:
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
case LTC_ASN1_CHOICE:
|
||||
++x;
|
||||
break;
|
||||
|
||||
@@ -92,7 +94,9 @@ int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...)
|
||||
case LTC_ASN1_OBJECT_IDENTIFIER:
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
case LTC_ASN1_UTCTIME:
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
case LTC_ASN1_CHOICE:
|
||||
list[x].type = type;
|
||||
list[x].size = size;
|
||||
list[x++].data = data;
|
||||
|
||||
@@ -103,6 +103,13 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
|
||||
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_SEQUENCE:
|
||||
if ((err = der_length_sequence(data, size, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
@@ -241,6 +248,15 @@ int der_encode_sequence(ltc_asn1_list *list, unsigned long inlen,
|
||||
*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_SEQUENCE:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_sequence(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
|
||||
@@ -51,6 +51,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
||||
case LTC_ASN1_OBJECT_IDENTIFIER:
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
case LTC_ASN1_UTCTIME:
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
++x;
|
||||
break;
|
||||
@@ -93,6 +94,7 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
|
||||
case LTC_ASN1_OBJECT_IDENTIFIER:
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
case LTC_ASN1_UTCTIME:
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
list[x].type = type;
|
||||
list[x].size = size;
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/* 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_decode_utctime.c
|
||||
ASN.1 DER, decode a UTCTIME, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
static int char_to_int(unsigned char x)
|
||||
{
|
||||
switch (x) {
|
||||
case '0': return 0;
|
||||
case '1': return 1;
|
||||
case '2': return 2;
|
||||
case '3': return 3;
|
||||
case '4': return 4;
|
||||
case '5': return 5;
|
||||
case '6': return 6;
|
||||
case '7': return 7;
|
||||
case '8': return 8;
|
||||
case '9': return 9;
|
||||
}
|
||||
return 100;
|
||||
}
|
||||
|
||||
#define DECODE_V(y, max) \
|
||||
y = char_to_int(buf[x])*10 + char_to_int(buf[x+1]); \
|
||||
if (y >= max) return CRYPT_INVALID_PACKET; \
|
||||
x += 2;
|
||||
|
||||
int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
|
||||
ltc_utctime *out)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
unsigned long x;
|
||||
int y;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(inlen != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
|
||||
/* check header */
|
||||
if (*inlen < 2UL || (in[1] >= sizeof(buf)) || ((in[1] + 2UL) > *inlen)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* decode the string */
|
||||
for (x = 0; x < in[1]; x++) {
|
||||
y = der_ia5_value_decode(in[x+2]);
|
||||
if (y == -1) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
buf[x] = y;
|
||||
}
|
||||
*inlen = 2 + x;
|
||||
|
||||
|
||||
/* possible encodings are
|
||||
YYMMDDhhmmZ
|
||||
YYMMDDhhmm+hh'mm'
|
||||
YYMMDDhhmm-hh'mm'
|
||||
YYMMDDhhmmssZ
|
||||
YYMMDDhhmmss+hh'mm'
|
||||
YYMMDDhhmmss-hh'mm'
|
||||
|
||||
So let's do a trivial decode upto [including] mm
|
||||
*/
|
||||
|
||||
x = 0;
|
||||
DECODE_V(out->YY, 100);
|
||||
DECODE_V(out->MM, 13);
|
||||
DECODE_V(out->DD, 32);
|
||||
DECODE_V(out->hh, 24);
|
||||
DECODE_V(out->mm, 60);
|
||||
|
||||
/* clear timezone and seconds info */
|
||||
out->off_dir = out->off_hh = out->off_mm = out->ss = 0;
|
||||
|
||||
/* now is it Z, +, - or 0-9 */
|
||||
if (buf[x] == 'Z') {
|
||||
return CRYPT_OK;
|
||||
} else if (buf[x] == '+' || buf[x] == '-') {
|
||||
out->off_dir = (buf[x++] == '+') ? 0 : 1;
|
||||
DECODE_V(out->off_hh, 24);
|
||||
DECODE_V(out->off_mm, 60);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* decode seconds */
|
||||
DECODE_V(out->ss, 60);
|
||||
|
||||
/* now is it Z, +, - */
|
||||
if (buf[x] == 'Z') {
|
||||
return CRYPT_OK;
|
||||
} else if (buf[x] == '+' || buf[x] == '-') {
|
||||
out->off_dir = (buf[x++] == '+') ? 0 : 1;
|
||||
DECODE_V(out->off_hh, 24);
|
||||
DECODE_V(out->off_mm, 60);
|
||||
return CRYPT_OK;
|
||||
} else {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
@@ -0,0 +1,80 @@
|
||||
/* 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_utctime.c
|
||||
ASN.1 DER, encode a UTCTIME, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
static const char *baseten = "0123456789";
|
||||
|
||||
#define STORE_V(y) \
|
||||
out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
|
||||
out[x++] = der_ia5_char_encode(baseten[y % 10]);
|
||||
|
||||
/**
|
||||
Gets length of DER encoding of UTCTIME
|
||||
@param outlen [out] The length of the DER encoding
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_encode_utctime(ltc_utctime *utctime,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x, tmplen;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(utctime != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((err = der_length_utctime(utctime, &tmplen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (tmplen > *outlen) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
out[0] = 0x17;
|
||||
|
||||
/* store values */
|
||||
x = 2;
|
||||
STORE_V(utctime->YY);
|
||||
STORE_V(utctime->MM);
|
||||
STORE_V(utctime->DD);
|
||||
STORE_V(utctime->hh);
|
||||
STORE_V(utctime->mm);
|
||||
STORE_V(utctime->ss);
|
||||
|
||||
if (utctime->off_mm || utctime->off_hh) {
|
||||
out[x++] = der_ia5_char_encode(utctime->off_dir ? '-' : '+');
|
||||
STORE_V(utctime->off_hh);
|
||||
STORE_V(utctime->off_mm);
|
||||
} else {
|
||||
out[x++] = der_ia5_char_encode('Z');
|
||||
}
|
||||
|
||||
/* store length */
|
||||
out[1] = x - 2;
|
||||
|
||||
/* all good let's return */
|
||||
*outlen = x;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $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, tomstdenis@gmail.com, http://libtomcrypt.org
|
||||
*/
|
||||
#include "tomcrypt.h"
|
||||
|
||||
/**
|
||||
@file der_length_utctime.c
|
||||
ASN.1 DER, get length of UTCTIME, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Gets length of DER encoding of UTCTIME
|
||||
@param outlen [out] The length of the DER encoding
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen)
|
||||
{
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(utctime != NULL);
|
||||
|
||||
if (utctime->off_hh == 0 && utctime->off_mm == 0) {
|
||||
/* we encode as YYMMDDhhmmssZ */
|
||||
*outlen = 2 + 13;
|
||||
} else {
|
||||
/* we encode as YYMMDDhhmmss{+|-}hh'mm' */
|
||||
*outlen = 2 + 17;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* $Source$ */
|
||||
/* $Revision$ */
|
||||
/* $Date$ */
|
||||
@@ -160,7 +160,7 @@ int pkcs_1_oaep_decode(const unsigned char *msg, unsigned long msglen,
|
||||
|
||||
/* copy message */
|
||||
*outlen = (modulus_len - hLen - 1) - x;
|
||||
XMEMCPY(out, DB + x, modulus_len - hLen - 1);
|
||||
XMEMCPY(out, DB + x, modulus_len - hLen - 1 - x);
|
||||
x += modulus_len - hLen - 1;
|
||||
|
||||
/* valid packet */
|
||||
|
||||
@@ -86,6 +86,12 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen,
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* this should never happen ... */
|
||||
if (mp_unsigned_bin_size(&tmp) > mp_unsigned_bin_size(&key->N)) {
|
||||
err = CRYPT_ERROR;
|
||||
goto done;
|
||||
}
|
||||
*outlen = x;
|
||||
|
||||
/* convert it */
|
||||
|
||||
Reference in New Issue
Block a user