Replaced system SQLite with SQLCipher to support encrypted database
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
int err;
|
||||
|
||||
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 */
|
||||
y = inlen - 1;
|
||||
if ((err = der_decode_asn1_length(in + x, &y, &dlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += y;
|
||||
/* is the data len too long or too short? */
|
||||
if ((dlen == 0) || (dlen > (inlen - x))) {
|
||||
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
|
||||
@@ -0,0 +1,84 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_decode_bit_string.c
|
||||
ASN.1 DER, encode a BIT STRING, Tom St Denis
|
||||
*/
|
||||
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
#define SETBIT(v, n) (v=((unsigned char)(v) | (1U << (unsigned char)(n))))
|
||||
#define CLRBIT(v, n) (v=((unsigned char)(v) & ~(1U << (unsigned char)(n))))
|
||||
|
||||
/**
|
||||
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 (8 per char)
|
||||
@param outlen [in/out] The number of bits stored
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_decode_raw_bit_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long dlen, blen, x, y;
|
||||
int err;
|
||||
|
||||
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 */
|
||||
y = inlen - 1;
|
||||
if ((err = der_decode_asn1_length(in + x, &y, &dlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += y;
|
||||
/* is the data len too long or too short? */
|
||||
if ((dlen == 0) || (dlen > (inlen - x))) {
|
||||
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++) {
|
||||
if (in[x] & (1 << (7 - (y & 7)))) {
|
||||
SETBIT(out[y/8], 7-(y%8));
|
||||
} else {
|
||||
CLRBIT(out[y/8], 7-(y%8));
|
||||
}
|
||||
if ((y & 7) == 7) {
|
||||
++x;
|
||||
}
|
||||
}
|
||||
|
||||
/* we done */
|
||||
*outlen = blen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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 + 7) >> 3) + 1;
|
||||
|
||||
out[x++] = 0x03;
|
||||
len = *outlen - x;
|
||||
if ((err = der_encode_asn1_length(y, out + x, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += len;
|
||||
|
||||
/* 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
|
||||
@@ -0,0 +1,75 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_encode_bit_string.c
|
||||
ASN.1 DER, encode a BIT STRING, Tom St Denis
|
||||
*/
|
||||
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
#define getbit(n, k) (((n) & ( 1 << (k) )) >> (k))
|
||||
|
||||
/**
|
||||
Store a BIT STRING
|
||||
@param in The array of bits to store (8 per char)
|
||||
@param inlen The number of bits to store
|
||||
@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_raw_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 + 7) >> 3) + 1;
|
||||
|
||||
out[x++] = 0x03;
|
||||
len = *outlen - x;
|
||||
if ((err = der_encode_asn1_length(y, out + x, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += len;
|
||||
|
||||
/* 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 |= (getbit(in[y/8],7-y%8)?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
|
||||
@@ -0,0 +1,36 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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, x;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* get the number of the bytes */
|
||||
nbytes = (nbits >> 3) + ((nbits & 7) ? 1 : 0) + 1;
|
||||
|
||||
if ((err = der_length_asn1_length(nbytes, &x)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
*outlen = 1 + x + nbytes;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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
|
||||
@@ -0,0 +1,39 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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
|
||||
@@ -0,0 +1,23 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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
|
||||
@@ -0,0 +1,221 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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_BOOLEAN:
|
||||
if (der_decode_boolean(in, *inlen, data) == CRYPT_OK) {
|
||||
if (der_length_boolean(&z) == CRYPT_OK) {
|
||||
list[x].used = 1;
|
||||
*inlen = z;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
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(*(unsigned long*)data, &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_RAW_BIT_STRING:
|
||||
if (der_decode_raw_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_TELETEX_STRING:
|
||||
if (der_decode_teletex_string(in, *inlen, data, &size) == CRYPT_OK) {
|
||||
if (der_length_teletex_string(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_GENERALIZEDTIME:
|
||||
z = *inlen;
|
||||
if (der_decode_generalizedtime(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;
|
||||
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
if (der_decode_custom_type(in, *inlen, &list[x]) == CRYPT_OK) {
|
||||
if (der_length_custom_type(&list[x], &z, NULL) == CRYPT_OK) {
|
||||
list[x].used = 1;
|
||||
*inlen = z;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_EOL:
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,426 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
|
||||
/**
|
||||
@file der_decode_custom_type.c
|
||||
ASN.1 DER, decode a Custom type, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Decode a Custom type
|
||||
@param in The DER encoded input
|
||||
@param inlen The size of the input
|
||||
@param root The item that defines the custom type to decode
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_decode_custom_type(const unsigned char *in, unsigned long inlen,
|
||||
ltc_asn1_list *root)
|
||||
{
|
||||
LTC_ARGCHK(root != NULL);
|
||||
return der_decode_custom_type_ex(in, inlen, root, NULL, 0, LTC_DER_SEQ_ORDERED | LTC_DER_SEQ_RELAXED);
|
||||
}
|
||||
|
||||
/**
|
||||
Extended-decode a Custom type
|
||||
|
||||
This function is used to decode custom types and sequences/sets
|
||||
For custom types root is used
|
||||
For sequences/sets list and outlen are used
|
||||
|
||||
@param in The DER encoded input
|
||||
@param inlen The size of the input
|
||||
@param root The item that defines the custom type to decode
|
||||
@param list The list of items to decode
|
||||
@param outlen The number of items in the list
|
||||
@param flags c.f. enum ltc_der_seq
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen,
|
||||
ltc_asn1_list *root,
|
||||
ltc_asn1_list *list, unsigned long outlen,
|
||||
unsigned int flags)
|
||||
{
|
||||
int err, seq_err, i, ordered;
|
||||
ltc_asn1_type type;
|
||||
ltc_asn1_list ident;
|
||||
unsigned long size, x, y, z, blksize;
|
||||
unsigned char* in_new = NULL;
|
||||
void *data;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
/* get blk size */
|
||||
if (inlen < 2) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
x = 0;
|
||||
|
||||
if (root == NULL) {
|
||||
LTC_ARGCHK(list != NULL);
|
||||
|
||||
/* sequence type? We allow 0x30 SEQUENCE and 0x31 SET since fundamentally they're the same structure */
|
||||
if (in[x] != 0x30 && in[x] != 0x31) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
++x;
|
||||
} else {
|
||||
if (root->type != LTC_ASN1_CUSTOM_TYPE) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* Alloc a copy of the data for primitive handling. */
|
||||
if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
|
||||
in_new = XMALLOC(inlen);
|
||||
if (in_new == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
XMEMCPY(in_new, in, inlen);
|
||||
in = in_new;
|
||||
}
|
||||
|
||||
y = inlen;
|
||||
if ((err = der_decode_asn1_identifier(in, &y, &ident)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if ((ident.type != root->type) ||
|
||||
(ident.klass != root->klass) ||
|
||||
(ident.pc != root->pc) ||
|
||||
(ident.tag != root->tag)) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
x += y;
|
||||
|
||||
list = root->data;
|
||||
outlen = root->size;
|
||||
}
|
||||
|
||||
if (root != NULL && root->pc == LTC_ASN1_PC_PRIMITIVE) {
|
||||
if (((unsigned long)root->used >= der_asn1_type_to_identifier_map_sz) ||
|
||||
(der_asn1_type_to_identifier_map[root->used] == -1)) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
root->type = (ltc_asn1_type)root->used;
|
||||
list = root;
|
||||
outlen = 1;
|
||||
|
||||
x -= 1;
|
||||
in_new[x] = (unsigned char)der_asn1_type_to_identifier_map[list[0].type];
|
||||
blksize = inlen - x;
|
||||
} else {
|
||||
|
||||
y = inlen - x;
|
||||
if ((err = der_decode_asn1_length(&in[x], &y, &blksize)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
x += y;
|
||||
}
|
||||
|
||||
/* would this blksize overflow? */
|
||||
if (blksize > (inlen - x)) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* mark all as unused */
|
||||
for (i = 0; i < (int)outlen; i++) {
|
||||
list[i].used = 0;
|
||||
}
|
||||
ordered = flags & LTC_DER_SEQ_ORDERED;
|
||||
|
||||
/* ok read data */
|
||||
seq_err = CRYPT_OK;
|
||||
blksize += x;
|
||||
inlen -= x;
|
||||
for (i = 0; i < (int)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;
|
||||
}
|
||||
|
||||
if (root != NULL && root->pc == LTC_ASN1_PC_PRIMITIVE && i != 0) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
case LTC_ASN1_SET:
|
||||
case LTC_ASN1_SETOF:
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
break;
|
||||
default:
|
||||
/* Verify that all basic types are indeed UNIVERSAL&PRIMITIVE */
|
||||
if (((flags & LTC_DER_SEQ_STRICT) == LTC_DER_SEQ_STRICT) && (inlen > 0)) {
|
||||
if (in[x] & 0xE0u) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case LTC_ASN1_BOOLEAN:
|
||||
z = inlen;
|
||||
if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
|
||||
if (!ordered || list[i].optional) { continue; }
|
||||
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 || list[i].optional) { 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 || list[i].optional) { 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 || list[i].optional) { 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_RAW_BIT_STRING:
|
||||
z = inlen;
|
||||
if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
|
||||
if (!ordered || list[i].optional) { 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 || list[i].optional) { 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 || list[i].optional) { 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 || list[i].optional) { 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_TELETEX_STRING:
|
||||
z = inlen;
|
||||
if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) {
|
||||
if (!ordered || list[i].optional) { continue; }
|
||||
goto LBL_ERR;
|
||||
}
|
||||
list[i].size = size;
|
||||
if ((err = der_length_teletex_string(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 || list[i].optional) { 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 || list[i].optional) { 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 || list[i].optional) { 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 || list[i].optional) { continue; }
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_GENERALIZEDTIME:
|
||||
z = inlen;
|
||||
if ((err = der_decode_generalizedtime(in + x, &z, data)) != CRYPT_OK) {
|
||||
if (!ordered || list[i].optional) { 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 || list[i].optional) { 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;
|
||||
err = der_decode_sequence_ex(in + x, z, data, size, flags);
|
||||
if (err == CRYPT_INPUT_TOO_LONG) {
|
||||
seq_err = CRYPT_INPUT_TOO_LONG;
|
||||
err = CRYPT_OK;
|
||||
}
|
||||
if (err != CRYPT_OK) {
|
||||
if (!ordered || list[i].optional) { continue; }
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
z = inlen;
|
||||
err = der_decode_custom_type(in + x, z, &list[i]);
|
||||
if (err == CRYPT_INPUT_TOO_LONG) {
|
||||
seq_err = CRYPT_INPUT_TOO_LONG;
|
||||
err = CRYPT_OK;
|
||||
}
|
||||
if (err != CRYPT_OK) {
|
||||
if (!ordered || list[i].optional) { continue; }
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if ((err = der_length_custom_type(&list[i], &z, NULL)) != 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 || list[i].optional) { continue; }
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_EOL:
|
||||
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 < (int)outlen; i++) {
|
||||
if (list[i].used == 0 && list[i].optional == 0) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (blksize == x && seq_err == CRYPT_OK && inlen == 0) {
|
||||
/* everything decoded and no errors in nested sequences */
|
||||
err = CRYPT_OK;
|
||||
} else if (blksize == x && seq_err == CRYPT_INPUT_TOO_LONG && inlen == 0) {
|
||||
/* a sequence reported too-long input, but now we've decoded everything */
|
||||
err = CRYPT_OK;
|
||||
} else if (blksize != x && ((flags & LTC_DER_SEQ_STRICT) == LTC_DER_SEQ_STRICT)) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
} else {
|
||||
err = CRYPT_INPUT_TOO_LONG;
|
||||
}
|
||||
|
||||
LBL_ERR:
|
||||
if (in_new != NULL) {
|
||||
XFREE(in_new);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,228 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
|
||||
/**
|
||||
@file der_encode_custom_type.c
|
||||
ASN.1 DER, encode a Custom Type, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Encode a Custom Type
|
||||
|
||||
This function is a bit special compared to the others, as it requires the
|
||||
root-ltc_asn1_list where the type is defined.
|
||||
|
||||
@param root The root of the list of items to encode
|
||||
@param out [out] The destination
|
||||
@param outlen [in/out] The size of the output
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_encode_custom_type(const ltc_asn1_list *root,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_type type;
|
||||
const ltc_asn1_list *list;
|
||||
unsigned long size, x, y, z, i, inlen, id_len;
|
||||
void *data;
|
||||
|
||||
LTC_ARGCHK(root != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* get size of output that will be required */
|
||||
y = 0; z = 0;
|
||||
if (der_length_custom_type(root, &y, &z) != CRYPT_OK) return CRYPT_INVALID_ARG;
|
||||
|
||||
/* too big ? */
|
||||
if (*outlen < y) {
|
||||
*outlen = y;
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* get length of the identifier, so we know the offset where to start writing */
|
||||
if (der_length_asn1_identifier(root, &id_len) != CRYPT_OK) return CRYPT_INVALID_ARG;
|
||||
x = id_len;
|
||||
|
||||
|
||||
if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
|
||||
list = root;
|
||||
inlen = 1;
|
||||
/* In case it's a PRIMITIVE type we encode directly to the output
|
||||
* but leave space for a potentially longer identifier as it will
|
||||
* simply be replaced afterwards.
|
||||
*/
|
||||
x -= 1;
|
||||
} else {
|
||||
list = root->data;
|
||||
inlen = root->size;
|
||||
/* store length, identifier will be added later */
|
||||
y = *outlen - x;
|
||||
if ((err = der_encode_asn1_length(z, &out[x], &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
x += y;
|
||||
}
|
||||
|
||||
/* store data */
|
||||
*outlen -= x;
|
||||
for (i = 0; i < inlen; i++) {
|
||||
if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
|
||||
type = (ltc_asn1_type)list[i].used;
|
||||
} else {
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_INTEGER:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_BIT_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_OCTET_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_NULL:
|
||||
out[x] = 0x05;
|
||||
out[x+1] = 0x00;
|
||||
z = 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;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_UTF8_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_UTCTIME:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_GENERALIZEDTIME:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_generalizedtime(data, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SET:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SETOF:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_custom_type(&list[i], out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
|
||||
x += z;
|
||||
*outlen -= z;
|
||||
}
|
||||
|
||||
if ((err = der_encode_asn1_identifier(root, out, &id_len)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
*outlen = x;
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,203 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_length_custom_type.c
|
||||
ASN.1 DER, length of a custom type, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Get the length of a DER custom type
|
||||
|
||||
This function is a bit special compared to the others, as it requires the
|
||||
root-ltc_asn1_list where the type is defined.
|
||||
|
||||
@param root The root of the struct to encode
|
||||
@param outlen [out] The length required in octets to store it
|
||||
@param payloadlen [out] The length of the payload in octets
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_length_custom_type(const ltc_asn1_list *root, unsigned long *outlen, unsigned long *payloadlen)
|
||||
{
|
||||
int err;
|
||||
const ltc_asn1_list *list;
|
||||
ltc_asn1_type type;
|
||||
unsigned long size, x, y, i, inlen, id_len;
|
||||
void *data;
|
||||
|
||||
LTC_ARGCHK(root != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* get size of output that will be required */
|
||||
if ((err = der_length_asn1_identifier(root, &id_len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
y = id_len;
|
||||
|
||||
if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
|
||||
list = root;
|
||||
inlen = 1;
|
||||
} else {
|
||||
list = root->data;
|
||||
inlen = root->size;
|
||||
}
|
||||
for (i = 0; i < inlen; i++) {
|
||||
if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
|
||||
type = (ltc_asn1_type)list[i].used;
|
||||
} else {
|
||||
type = list[i].type;
|
||||
}
|
||||
size = list[i].size;
|
||||
data = list[i].data;
|
||||
|
||||
if (type == LTC_ASN1_EOL) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* some items may be optional during import */
|
||||
if (!list[i].used && list[i].optional) continue;
|
||||
|
||||
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:
|
||||
case LTC_ASN1_RAW_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_TELETEX_STRING:
|
||||
if ((err = der_length_teletex_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_GENERALIZEDTIME:
|
||||
if ((err = der_length_generalizedtime(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_CUSTOM_TYPE:
|
||||
if ((err = der_length_custom_type(&list[i], &x, NULL)) != 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;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_EOL:
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (root->pc == LTC_ASN1_PC_PRIMITIVE) {
|
||||
/* In case it's a PRIMITIVE element we're going
|
||||
* to only replace the identifier of the one element
|
||||
* by the custom identifier.
|
||||
*/
|
||||
y -= 1;
|
||||
if (payloadlen != NULL) {
|
||||
*payloadlen = y - id_len;
|
||||
}
|
||||
} else {
|
||||
/* calc length of length */
|
||||
if ((err = der_length_asn1_length(y - id_len, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if (payloadlen != NULL) {
|
||||
*payloadlen = y - id_len;
|
||||
}
|
||||
y += x;
|
||||
}
|
||||
|
||||
/* store size */
|
||||
*outlen = y;
|
||||
|
||||
LBL_ERR:
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,157 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_asn1_maps.c
|
||||
ASN.1 DER, a collection of maps to convert between different representations, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
A Map from ltc_asn1_type to the regularly used ASN.1 identifier
|
||||
*/
|
||||
const int der_asn1_type_to_identifier_map[] =
|
||||
{
|
||||
/* 0 */
|
||||
-1, /* LTC_ASN1_EOL, */
|
||||
1, /* LTC_ASN1_BOOLEAN, */
|
||||
2, /* LTC_ASN1_INTEGER, */
|
||||
2, /* LTC_ASN1_SHORT_INTEGER, */
|
||||
3, /* LTC_ASN1_BIT_STRING, */
|
||||
/* 5 */
|
||||
4, /* LTC_ASN1_OCTET_STRING, */
|
||||
5, /* LTC_ASN1_NULL, */
|
||||
6, /* LTC_ASN1_OBJECT_IDENTIFIER, */
|
||||
22, /* LTC_ASN1_IA5_STRING, */
|
||||
19, /* LTC_ASN1_PRINTABLE_STRING, */
|
||||
/* 10 */
|
||||
12, /* LTC_ASN1_UTF8_STRING, */
|
||||
23, /* LTC_ASN1_UTCTIME, */
|
||||
-1, /* LTC_ASN1_CHOICE, */
|
||||
48, /* LTC_ASN1_SEQUENCE, */
|
||||
49, /* LTC_ASN1_SET, */
|
||||
/* 15 */
|
||||
49, /* LTC_ASN1_SETOF, */
|
||||
3, /* LTC_ASN1_RAW_BIT_STRING, */
|
||||
20, /* LTC_ASN1_TELETEX_STRING, */
|
||||
24, /* LTC_ASN1_GENERALIZEDTIME, */
|
||||
-1, /* LTC_ASN1_CUSTOM_TYPE, */
|
||||
};
|
||||
const unsigned long der_asn1_type_to_identifier_map_sz = sizeof(der_asn1_type_to_identifier_map)/sizeof(der_asn1_type_to_identifier_map[0]);
|
||||
|
||||
/**
|
||||
A Map from the ASN.1 Class to its string
|
||||
*/
|
||||
const char* der_asn1_class_to_string_map[] =
|
||||
{
|
||||
"UNIVERSAL",
|
||||
"APPLICATION",
|
||||
"CONTEXT-SPECIFIC",
|
||||
"PRIVATE",
|
||||
};
|
||||
const unsigned long der_asn1_class_to_string_map_sz = sizeof(der_asn1_class_to_string_map)/sizeof(der_asn1_class_to_string_map[0]);
|
||||
|
||||
/**
|
||||
A Map from the ASN.1 P/C-bit to its string
|
||||
*/
|
||||
const char* der_asn1_pc_to_string_map[] =
|
||||
{
|
||||
"PRIMITIVE",
|
||||
"CONSTRUCTED",
|
||||
};
|
||||
const unsigned long der_asn1_pc_to_string_map_sz = sizeof(der_asn1_pc_to_string_map)/sizeof(der_asn1_pc_to_string_map[0]);
|
||||
|
||||
/**
|
||||
A Map from the ASN.1 tag to its string
|
||||
*/
|
||||
const char* der_asn1_tag_to_string_map[] =
|
||||
{
|
||||
"Reserved for use by the encoding rules",
|
||||
"Boolean type",
|
||||
"Integer type",
|
||||
"Bitstring type",
|
||||
"Octetstring type",
|
||||
"Null type",
|
||||
"Object identifier type",
|
||||
"Object descriptor type",
|
||||
"External type and Instance-of type",
|
||||
"Real type",
|
||||
"Enumerated type",
|
||||
"Embedded-pdv type",
|
||||
"UTF8String type",
|
||||
"Relative object identifier type",
|
||||
"The time type",
|
||||
"Reserved for future editions of this Recommendation | International Standard",
|
||||
"Sequence and Sequence-of types",
|
||||
"Set and Set-of types",
|
||||
"NumericString type",
|
||||
"PrintableString type",
|
||||
"TeletexString (T61String) type",
|
||||
"VideotexString type",
|
||||
"IA5String type",
|
||||
"UTCTime type",
|
||||
"GeneralizedTime type",
|
||||
"GraphicString type",
|
||||
"VisibleString (ISO646String) type",
|
||||
"GeneralString type",
|
||||
"UniversalString type",
|
||||
"UnrestrictedCharacterString type",
|
||||
"BMPString type",
|
||||
"Date type",
|
||||
"TimeOfDay type",
|
||||
"DateTime type",
|
||||
"Duration type",
|
||||
"OID internationalized resource identifier type",
|
||||
"Relative OID internationalized resource identifier type",
|
||||
};
|
||||
const unsigned long der_asn1_tag_to_string_map_sz = sizeof(der_asn1_tag_to_string_map)/sizeof(der_asn1_tag_to_string_map[0]);
|
||||
|
||||
/**
|
||||
A Map from ASN.1 Tags to ltc_asn1_type
|
||||
*/
|
||||
const ltc_asn1_type der_asn1_tag_to_type_map[] =
|
||||
{
|
||||
/* 0 */
|
||||
LTC_ASN1_EOL, /* Reserved for use by the encoding rules */
|
||||
LTC_ASN1_BOOLEAN, /* Boolean type */
|
||||
LTC_ASN1_INTEGER, /* Integer type */
|
||||
LTC_ASN1_BIT_STRING, /* Bitstring type */
|
||||
LTC_ASN1_OCTET_STRING, /* Octetstring type */
|
||||
/* 5 */
|
||||
LTC_ASN1_NULL, /* Null type */
|
||||
LTC_ASN1_OBJECT_IDENTIFIER, /* Object identifier type */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* Object descriptor type */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* External type and Instance-of type */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* Real type */
|
||||
/* 10 */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* Enumerated type */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* Embedded-pdv type */
|
||||
LTC_ASN1_UTF8_STRING, /* UTF8String type */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* Relative object identifier type */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* The time type */
|
||||
/* 15 */
|
||||
LTC_ASN1_EOL, /* Reserved for future editions of this Recommendation | International Standard */
|
||||
LTC_ASN1_SEQUENCE, /* Sequence and Sequence-of types */
|
||||
LTC_ASN1_SET, /* Set and Set-of types */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* NumericString types */
|
||||
LTC_ASN1_PRINTABLE_STRING, /* PrintableString types */
|
||||
/* 20 */
|
||||
LTC_ASN1_TELETEX_STRING, /* TeletexString (T61String) types */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* VideotexString types */
|
||||
LTC_ASN1_IA5_STRING, /* IA5String types */
|
||||
LTC_ASN1_UTCTIME, /* UTCTime types */
|
||||
LTC_ASN1_GENERALIZEDTIME, /* GeneralizedTime types */
|
||||
/* 25 */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* GraphicString types */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* VisibleString (ISO646String) types */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* GeneralString types */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* UniversalString types */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* UnrestrictedCharacterString types */
|
||||
/* 30 */
|
||||
LTC_ASN1_CUSTOM_TYPE, /* BMPString types */
|
||||
};
|
||||
const unsigned long der_asn1_tag_to_type_map_sz = sizeof(der_asn1_tag_to_type_map)/sizeof(der_asn1_tag_to_type_map[0]);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,123 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_decode_asn1_identifier.c
|
||||
ASN.1 DER, decode the ASN.1 Identifier, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
/* c.f. X.680 & X.690, some decisions backed by X.690 ch. 10.2 */
|
||||
static const unsigned char tag_constructed_map[] =
|
||||
{
|
||||
/* 0 */
|
||||
255,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
/* 5 */
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
/* 10 */
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
/* 15 */
|
||||
255,
|
||||
LTC_ASN1_PC_CONSTRUCTED,
|
||||
LTC_ASN1_PC_CONSTRUCTED,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
/* 20 */
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
/* 25 */
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
LTC_ASN1_PC_PRIMITIVE,
|
||||
};
|
||||
static const unsigned long tag_constructed_map_sz = sizeof(tag_constructed_map)/sizeof(tag_constructed_map[0]);
|
||||
|
||||
/**
|
||||
Decode the ASN.1 Identifier
|
||||
@param id Where to store the decoded Identifier
|
||||
@param in Where to read the Identifier from
|
||||
@param inlen [in/out] The size of in available/read
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_decode_asn1_identifier(const unsigned char *in, unsigned long *inlen, ltc_asn1_list *id)
|
||||
{
|
||||
ulong64 tmp;
|
||||
unsigned long tag_len;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(id != NULL);
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(inlen != NULL);
|
||||
|
||||
if (*inlen == 0) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
tag_len = 1;
|
||||
id->klass = (in[0] >> 6) & 0x3;
|
||||
id->pc = (in[0] >> 5) & 0x1;
|
||||
id->tag = in[0] & 0x1f;
|
||||
|
||||
err = CRYPT_OK;
|
||||
if (id->tag == 0x1f) {
|
||||
id->tag = 0;
|
||||
do {
|
||||
if (*inlen < tag_len) {
|
||||
/* break the loop and trigger the BOF error-code */
|
||||
tmp = 0xff;
|
||||
break;
|
||||
}
|
||||
id->tag <<= 7;
|
||||
id->tag |= in[tag_len] & 0x7f;
|
||||
tmp = in[tag_len] & 0x80;
|
||||
tag_len++;
|
||||
} while ((tmp != 0) && (tag_len < 10));
|
||||
|
||||
if (tmp != 0) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
} else if (id->tag < 0x1f) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
if (err != CRYPT_OK) {
|
||||
id->pc = 0;
|
||||
id->klass = 0;
|
||||
id->tag = 0;
|
||||
} else {
|
||||
*inlen = tag_len;
|
||||
if ((id->klass == LTC_ASN1_CL_UNIVERSAL) &&
|
||||
(id->tag < der_asn1_tag_to_type_map_sz) &&
|
||||
(id->tag < tag_constructed_map_sz) &&
|
||||
(id->pc == tag_constructed_map[id->tag])) {
|
||||
id->type = der_asn1_tag_to_type_map[id->tag];
|
||||
} else {
|
||||
if ((id->klass == LTC_ASN1_CL_UNIVERSAL) && (id->tag == 0)) {
|
||||
id->type = LTC_ASN1_EOL;
|
||||
} else {
|
||||
id->type = LTC_ASN1_CUSTOM_TYPE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_decode_asn1_length.c
|
||||
ASN.1 DER, decode the ASN.1 Length field, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
/**
|
||||
Decode the ASN.1 Length field
|
||||
@param in Where to read the length field from
|
||||
@param inlen [in/out] The size of in available/read
|
||||
@param outlen [out] The decoded ASN.1 length
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen)
|
||||
{
|
||||
unsigned long real_len, decoded_len, offset, i;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(inlen != NULL);
|
||||
|
||||
if (*inlen < 1) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
real_len = in[0];
|
||||
|
||||
if (real_len < 128) {
|
||||
decoded_len = real_len;
|
||||
offset = 1;
|
||||
} else {
|
||||
real_len &= 0x7F;
|
||||
if (real_len == 0) {
|
||||
return CRYPT_PK_ASN1_ERROR;
|
||||
}
|
||||
if (real_len > sizeof(decoded_len)) {
|
||||
return CRYPT_OVERFLOW;
|
||||
}
|
||||
if (real_len > (*inlen - 1)) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
decoded_len = 0;
|
||||
offset = 1 + real_len;
|
||||
for (i = 0; i < real_len; i++) {
|
||||
decoded_len = (decoded_len << 8) | in[1 + i];
|
||||
}
|
||||
}
|
||||
|
||||
if (outlen != NULL) *outlen = decoded_len;
|
||||
if (decoded_len > (*inlen - offset)) return CRYPT_OVERFLOW;
|
||||
*inlen = offset;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_encode_asn1_identifier.c
|
||||
ASN.1 DER, encode the ASN.1 Identifier, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
/**
|
||||
Encode the ASN.1 Identifier
|
||||
@param id The ASN.1 Identifer to encode
|
||||
@param out Where to write the identifier to
|
||||
@param outlen [in/out] The size of out available/written
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_encode_asn1_identifier(const ltc_asn1_list *id, unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
ulong64 tmp;
|
||||
unsigned long tag_len;
|
||||
|
||||
LTC_ARGCHK(id != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
if (id->type != LTC_ASN1_CUSTOM_TYPE) {
|
||||
if ((unsigned)id->type >= der_asn1_type_to_identifier_map_sz) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
if (der_asn1_type_to_identifier_map[id->type] == -1) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
if (out != NULL) {
|
||||
*out = der_asn1_type_to_identifier_map[id->type];
|
||||
}
|
||||
*outlen = 1;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
if (id->klass < LTC_ASN1_CL_UNIVERSAL || id->klass > LTC_ASN1_CL_PRIVATE) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
if (id->pc < LTC_ASN1_PC_PRIMITIVE || id->pc > LTC_ASN1_PC_CONSTRUCTED) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
if (id->tag > (ULONG_MAX >> (8 + 7))) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (out != NULL) {
|
||||
if (*outlen < 1) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
out[0] = id->klass << 6 | id->pc << 5;
|
||||
}
|
||||
|
||||
if (id->tag < 0x1f) {
|
||||
if (out != NULL) {
|
||||
out[0] |= id->tag & 0x1f;
|
||||
}
|
||||
*outlen = 1;
|
||||
} else {
|
||||
tag_len = 0;
|
||||
tmp = id->tag;
|
||||
do {
|
||||
tag_len++;
|
||||
tmp >>= 7;
|
||||
} while (tmp);
|
||||
|
||||
if (out != NULL) {
|
||||
if (*outlen < tag_len + 1) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
out[0] |= 0x1f;
|
||||
for (tmp = 1; tmp <= tag_len; ++tmp) {
|
||||
out[tmp] = ((id->tag >> (7 * (tag_len - tmp))) & 0x7f) | 0x80;
|
||||
}
|
||||
out[tag_len] &= ~0x80;
|
||||
}
|
||||
*outlen = tag_len + 1;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,117 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_encode_asn1_length.c
|
||||
ASN.1 DER, encode the ASN.1 length field, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
/**
|
||||
Encode the ASN.1 length field
|
||||
@param len The length to encode
|
||||
@param out Where to write the length field to
|
||||
@param outlen [in/out] The size of out available/written
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_encode_asn1_length(unsigned long len, unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x, y;
|
||||
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
x = len;
|
||||
y = 0;
|
||||
|
||||
while(x != 0) {
|
||||
y++;
|
||||
x >>= 8;
|
||||
}
|
||||
if (y == 0) {
|
||||
return CRYPT_PK_ASN1_ERROR;
|
||||
}
|
||||
|
||||
if (out == NULL) {
|
||||
if (len < 128) {
|
||||
x = y;
|
||||
} else {
|
||||
x = y + 1;
|
||||
}
|
||||
} else {
|
||||
if (*outlen < y) {
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
x = 0;
|
||||
if (len < 128) {
|
||||
out[x++] = (unsigned char)len;
|
||||
} else if (len <= 0xffUL) {
|
||||
out[x++] = 0x81;
|
||||
out[x++] = (unsigned char)len;
|
||||
} else if (len <= 0xffffUL) {
|
||||
out[x++] = 0x82;
|
||||
out[x++] = (unsigned char)((len>>8UL)&255);
|
||||
out[x++] = (unsigned char)(len&255);
|
||||
} else if (len <= 0xffffffUL) {
|
||||
out[x++] = 0x83;
|
||||
out[x++] = (unsigned char)((len>>16UL)&255);
|
||||
out[x++] = (unsigned char)((len>>8UL)&255);
|
||||
out[x++] = (unsigned char)(len&255);
|
||||
#if ULONG_MAX != ULLONG_MAX
|
||||
} else {
|
||||
out[x++] = 0x84;
|
||||
out[x++] = (unsigned char)((len>>24UL)&255);
|
||||
out[x++] = (unsigned char)((len>>16UL)&255);
|
||||
out[x++] = (unsigned char)((len>>8UL)&255);
|
||||
out[x++] = (unsigned char)(len&255);
|
||||
}
|
||||
#else
|
||||
} else if (len <= 0xffffffffUL) {
|
||||
out[x++] = 0x84;
|
||||
out[x++] = (unsigned char)((len>>24UL)&255);
|
||||
out[x++] = (unsigned char)((len>>16UL)&255);
|
||||
out[x++] = (unsigned char)((len>>8UL)&255);
|
||||
out[x++] = (unsigned char)(len&255);
|
||||
} else if (len <= 0xffffffffffULL) {
|
||||
out[x++] = 0x85;
|
||||
out[x++] = (unsigned char)((len>>32ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>24ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>16ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>8ULL)&255);
|
||||
out[x++] = (unsigned char)(len&255);
|
||||
} else if (len <= 0xffffffffffffULL) {
|
||||
out[x++] = 0x86;
|
||||
out[x++] = (unsigned char)((len>>40ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>32ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>24ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>16ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>8ULL)&255);
|
||||
out[x++] = (unsigned char)(len&255);
|
||||
} else if (len <= 0xffffffffffffffULL) {
|
||||
out[x++] = 0x87;
|
||||
out[x++] = (unsigned char)((len>>48ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>40ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>32ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>24ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>16ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>8ULL)&255);
|
||||
out[x++] = (unsigned char)(len&255);
|
||||
} else {
|
||||
out[x++] = 0x88;
|
||||
out[x++] = (unsigned char)((len>>56ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>48ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>40ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>32ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>24ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>16ULL)&255);
|
||||
out[x++] = (unsigned char)((len>>8ULL)&255);
|
||||
out[x++] = (unsigned char)(len&255);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
*outlen = x;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_length_asn1_identifier.c
|
||||
ASN.1 DER, determine the length when encoding the ASN.1 Identifier, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
/**
|
||||
Determine the length required when encoding the ASN.1 Identifier
|
||||
@param id The ASN.1 identifier to encode
|
||||
@param idlen [out] The required length to encode list
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
|
||||
int der_length_asn1_identifier(const ltc_asn1_list *id, unsigned long *idlen)
|
||||
{
|
||||
return der_encode_asn1_identifier(id, NULL, idlen);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_length_asn1_length.c
|
||||
ASN.1 DER, determine the length of the ASN.1 length field, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
/**
|
||||
Determine the length required to encode len in the ASN.1 length field
|
||||
@param len The length to encode
|
||||
@param outlen [out] The length that's required to store len
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_length_asn1_length(unsigned long len, unsigned long *outlen)
|
||||
{
|
||||
return der_encode_asn1_length(len, NULL, outlen);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,141 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_decode_generalizedtime.c
|
||||
ASN.1 DER, decode a GeneralizedTime, Steffen Jaeckel
|
||||
Based on der_decode_utctime.c
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
#ifndef LTC_DER_CHAR_TO_INT
|
||||
#define LTC_DER_CHAR_TO_INT
|
||||
static LTC_INLINE int s_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;
|
||||
default: return 100;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define DECODE_V(y, max) do {\
|
||||
y = s_char_to_int(buf[x])*10 + s_char_to_int(buf[x+1]); \
|
||||
if (y >= max) return CRYPT_INVALID_PACKET; \
|
||||
x += 2; \
|
||||
} while(0)
|
||||
|
||||
#define DECODE_V4(y, max) do {\
|
||||
y = s_char_to_int(buf[x])*1000 + s_char_to_int(buf[x+1])*100 + s_char_to_int(buf[x+2])*10 + s_char_to_int(buf[x+3]); \
|
||||
if (y >= max) return CRYPT_INVALID_PACKET; \
|
||||
x += 4; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
Decodes a Generalized time structure in DER format (reads all 6 valid encoding formats)
|
||||
@param in Input buffer
|
||||
@param inlen Length of input buffer in octets
|
||||
@param out [out] Destination of Generalized time structure
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_decode_generalizedtime(const unsigned char *in, unsigned long *inlen,
|
||||
ltc_generalizedtime *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;
|
||||
}
|
||||
if (!((y >= '0' && y <= '9')
|
||||
|| y == 'Z' || y == '.'
|
||||
|| y == '+' || y == '-')) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
buf[x] = y;
|
||||
}
|
||||
*inlen = 2 + x;
|
||||
|
||||
if (x < 15) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* possible encodings are
|
||||
YYYYMMDDhhmmssZ
|
||||
YYYYMMDDhhmmss+hh'mm'
|
||||
YYYYMMDDhhmmss-hh'mm'
|
||||
YYYYMMDDhhmmss.fsZ
|
||||
YYYYMMDDhhmmss.fs+hh'mm'
|
||||
YYYYMMDDhhmmss.fs-hh'mm'
|
||||
|
||||
So let's do a trivial decode upto [including] ss
|
||||
*/
|
||||
|
||||
x = 0;
|
||||
DECODE_V4(out->YYYY, 10000);
|
||||
DECODE_V(out->MM, 13);
|
||||
DECODE_V(out->DD, 32);
|
||||
DECODE_V(out->hh, 24);
|
||||
DECODE_V(out->mm, 60);
|
||||
DECODE_V(out->ss, 60);
|
||||
|
||||
/* clear fractional seconds info */
|
||||
out->fs = 0;
|
||||
|
||||
/* now is it Z or . */
|
||||
if (buf[x] == 'Z') {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
if (buf[x] == '.') {
|
||||
x++;
|
||||
while (buf[x] >= '0' && buf[x] <= '9') {
|
||||
unsigned fs = out->fs;
|
||||
if (x >= sizeof(buf)) return CRYPT_INVALID_PACKET;
|
||||
out->fs *= 10;
|
||||
out->fs += s_char_to_int(buf[x]);
|
||||
if (fs > out->fs) return CRYPT_OVERFLOW;
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
/* now is it Z, +, - */
|
||||
if (buf[x] == 'Z') {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
#undef DECODE_V
|
||||
#undef DECODE_V4
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_encode_utctime.c
|
||||
ASN.1 DER, encode a GeneralizedTime, Steffen Jaeckel
|
||||
Based on der_encode_utctime.c
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
#define STORE_V(y) do {\
|
||||
out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
|
||||
out[x++] = der_ia5_char_encode(baseten[y % 10]); \
|
||||
} while(0)
|
||||
|
||||
#define STORE_V4(y) do {\
|
||||
out[x++] = der_ia5_char_encode(baseten[(y/1000) % 10]); \
|
||||
out[x++] = der_ia5_char_encode(baseten[(y/100) % 10]); \
|
||||
out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
|
||||
out[x++] = der_ia5_char_encode(baseten[y % 10]); \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
Encodes a Generalized time structure in DER format
|
||||
@param gtime The GeneralizedTime structure to encode
|
||||
@param out The destination of the DER encoding of the GeneralizedTime structure
|
||||
@param outlen [in/out] The length of the DER encoding
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_encode_generalizedtime(const ltc_generalizedtime *gtime,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
const char * const baseten = "0123456789";
|
||||
unsigned long x, tmplen;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(gtime != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((err = der_length_generalizedtime(gtime, &tmplen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (tmplen > *outlen) {
|
||||
*outlen = tmplen;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
out[0] = 0x18;
|
||||
|
||||
/* store values */
|
||||
x = 2;
|
||||
STORE_V4(gtime->YYYY);
|
||||
STORE_V(gtime->MM);
|
||||
STORE_V(gtime->DD);
|
||||
STORE_V(gtime->hh);
|
||||
STORE_V(gtime->mm);
|
||||
STORE_V(gtime->ss);
|
||||
|
||||
if (gtime->fs) {
|
||||
unsigned long divisor;
|
||||
unsigned fs = gtime->fs;
|
||||
unsigned len = 0;
|
||||
out[x++] = der_ia5_char_encode('.');
|
||||
divisor = 1;
|
||||
do {
|
||||
fs /= 10;
|
||||
divisor *= 10;
|
||||
len++;
|
||||
} while(fs != 0);
|
||||
while (len-- > 1) {
|
||||
divisor /= 10;
|
||||
out[x++] = der_ia5_char_encode(baseten[(gtime->fs/divisor) % 10]);
|
||||
}
|
||||
out[x++] = der_ia5_char_encode(baseten[gtime->fs % 10]);
|
||||
}
|
||||
|
||||
if (gtime->off_mm || gtime->off_hh) {
|
||||
out[x++] = der_ia5_char_encode(gtime->off_dir ? '-' : '+');
|
||||
STORE_V(gtime->off_hh);
|
||||
STORE_V(gtime->off_mm);
|
||||
} else {
|
||||
out[x++] = der_ia5_char_encode('Z');
|
||||
}
|
||||
|
||||
/* store length */
|
||||
out[1] = (unsigned char)(x - 2);
|
||||
|
||||
/* all good let's return */
|
||||
*outlen = x;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#undef STORE_V
|
||||
#undef STORE_V4
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,48 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_length_utctime.c
|
||||
ASN.1 DER, get length of GeneralizedTime, Steffen Jaeckel
|
||||
Based on der_length_utctime.c
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Gets length of DER encoding of GeneralizedTime
|
||||
@param gtime The GeneralizedTime structure to get the size of
|
||||
@param outlen [out] The length of the DER encoding
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_length_generalizedtime(const ltc_generalizedtime *gtime, unsigned long *outlen)
|
||||
{
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(gtime != NULL);
|
||||
|
||||
if (gtime->fs == 0) {
|
||||
/* we encode as YYYYMMDDhhmmssZ */
|
||||
*outlen = 2 + 14 + 1;
|
||||
} else {
|
||||
unsigned long len = 2 + 14 + 1;
|
||||
unsigned fs = gtime->fs;
|
||||
do {
|
||||
fs /= 10;
|
||||
len++;
|
||||
} while(fs != 0);
|
||||
if (gtime->off_hh == 0 && gtime->off_mm == 0) {
|
||||
/* we encode as YYYYMMDDhhmmss.fsZ */
|
||||
len += 1;
|
||||
}
|
||||
else {
|
||||
/* we encode as YYYYMMDDhhmmss.fs{+|-}hh'mm' */
|
||||
len += 5;
|
||||
}
|
||||
*outlen = len;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,73 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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, err;
|
||||
|
||||
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;
|
||||
|
||||
/* get the length of the data */
|
||||
y = inlen - x;
|
||||
if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += y;
|
||||
|
||||
/* is it too long? */
|
||||
if (len > *outlen) {
|
||||
*outlen = len;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (len > (inlen - x)) {
|
||||
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
|
||||
@@ -0,0 +1,61 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
len = *outlen - x;
|
||||
if ((err = der_encode_asn1_length(inlen, out + x, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += len;
|
||||
|
||||
/* store octets */
|
||||
for (y = 0; y < inlen; y++) {
|
||||
out[x++] = der_ia5_char_encode(in[y]);
|
||||
}
|
||||
|
||||
/* retun length */
|
||||
*outlen = x;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,172 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
int err;
|
||||
|
||||
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 ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
*outlen = 1 + x + noctets;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
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;
|
||||
}
|
||||
|
||||
/* get the length of the data */
|
||||
inlen -= x;
|
||||
if ((err = der_decode_asn1_length(in + x, &inlen, &y)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += inlen;
|
||||
|
||||
if ((err = ltc_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 (ltc_mp_init(&tmp) != CRYPT_OK) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if (ltc_mp_2expt(tmp, ltc_mp_count_bits(num)) != CRYPT_OK || ltc_mp_sub(num, tmp, num) != CRYPT_OK) {
|
||||
ltc_mp_clear(tmp);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
ltc_mp_clear(tmp);
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,111 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@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, len;
|
||||
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 (ltc_mp_cmp_d(num, 0) != LTC_MP_LT) {
|
||||
/* we only need a leading zero if the msb of the first byte is one */
|
||||
if ((ltc_mp_count_bits(num) & 7) == 0 || ltc_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 = ltc_mp_unsigned_bin_size(num) + leading_zero;
|
||||
} else {
|
||||
leading_zero = 0;
|
||||
y = ltc_mp_count_bits(num);
|
||||
y = y + (8 - (y & 7));
|
||||
y = y >> 3;
|
||||
if (((ltc_mp_cnt_lsb(num)+1)==ltc_mp_count_bits(num)) && ((ltc_mp_count_bits(num)&7)==0)) --y;
|
||||
}
|
||||
|
||||
/* now store initial data */
|
||||
*out++ = 0x02;
|
||||
len = *outlen - 1;
|
||||
if ((err = der_encode_asn1_length(y, out, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
out += len;
|
||||
|
||||
/* 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 (ltc_mp_cmp_d(num, 0) == LTC_MP_GT) {
|
||||
/* now store the mpint */
|
||||
if ((err = ltc_mp_to_unsigned_bin(num, out)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
} else if (ltc_mp_iszero(num) != LTC_MP_YES) {
|
||||
void *tmp;
|
||||
|
||||
/* negative */
|
||||
if (ltc_mp_init(&tmp) != CRYPT_OK) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* 2^roundup and subtract */
|
||||
y = ltc_mp_count_bits(num);
|
||||
y = y + (8 - (y & 7));
|
||||
if (((ltc_mp_cnt_lsb(num)+1)==ltc_mp_count_bits(num)) && ((ltc_mp_count_bits(num)&7)==0)) y -= 8;
|
||||
if (ltc_mp_2expt(tmp, y) != CRYPT_OK || ltc_mp_add(tmp, num, tmp) != CRYPT_OK) {
|
||||
ltc_mp_clear(tmp);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
if ((err = ltc_mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) {
|
||||
ltc_mp_clear(tmp);
|
||||
return err;
|
||||
}
|
||||
ltc_mp_clear(tmp);
|
||||
}
|
||||
|
||||
/* we good */
|
||||
*outlen = tmplen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
@@ -0,0 +1,55 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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, err;
|
||||
|
||||
LTC_ARGCHK(num != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
if (ltc_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 ((ltc_mp_count_bits(num) & 7) == 0 || ltc_mp_iszero(num) == LTC_MP_YES) {
|
||||
leading_zero = 1;
|
||||
} else {
|
||||
leading_zero = 0;
|
||||
}
|
||||
|
||||
/* size for bignum */
|
||||
len = leading_zero + ltc_mp_unsigned_bin_size(num);
|
||||
} else {
|
||||
/* it's negative */
|
||||
/* find power of 2 that is a multiple of eight and greater than count bits */
|
||||
z = ltc_mp_count_bits(num);
|
||||
z = z + (8 - (z & 7));
|
||||
if (((ltc_mp_cnt_lsb(num)+1)==ltc_mp_count_bits(num)) && ((ltc_mp_count_bits(num)&7)==0)) --z;
|
||||
len = z >> 3;
|
||||
}
|
||||
|
||||
if ((err = der_length_asn1_length(len, &z)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
*outlen = 1 + z + len;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,94 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
int err;
|
||||
|
||||
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) {
|
||||
*outlen = 2;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* decode the packet header */
|
||||
x = 0;
|
||||
if ((in[x++] & 0x1F) != 0x06) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* get the length of the data */
|
||||
y = inlen - x;
|
||||
if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += y;
|
||||
|
||||
if ((len == 0) || (len > (inlen - x))) {
|
||||
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) {
|
||||
y++;
|
||||
} else {
|
||||
if (y == 0) {
|
||||
if (t <= 79) {
|
||||
words[0] = t / 40;
|
||||
words[1] = t % 40;
|
||||
} else {
|
||||
words[0] = 2;
|
||||
words[1] = t - 80;
|
||||
}
|
||||
y = 2;
|
||||
} else {
|
||||
words[y++] = t;
|
||||
}
|
||||
}
|
||||
t = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (y > *outlen) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
} else {
|
||||
err = CRYPT_OK;
|
||||
}
|
||||
|
||||
*outlen = y;
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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(const 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;
|
||||
y = *outlen - x;
|
||||
if ((err = der_encode_asn1_length(z, out + x, &y)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += y;
|
||||
|
||||
/* 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
|
||||
@@ -0,0 +1,77 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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(const 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 and word2 0..39 */
|
||||
if (words[0] > 2 || (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
|
||||
@@ -0,0 +1,69 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
int err;
|
||||
|
||||
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;
|
||||
|
||||
/* get the length of the data */
|
||||
y = inlen - x;
|
||||
if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += y;
|
||||
|
||||
/* is it too long? */
|
||||
if (len > *outlen) {
|
||||
*outlen = len;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (len > (inlen - x)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* read the data */
|
||||
for (y = 0; y < len; y++) {
|
||||
out[y] = in[x++];
|
||||
}
|
||||
|
||||
*outlen = y;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,62 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
len = *outlen - x;
|
||||
if ((err = der_encode_asn1_length(inlen, out + x, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += len;
|
||||
|
||||
/* store octets */
|
||||
for (y = 0; y < inlen; y++) {
|
||||
out[x++] = in[y];
|
||||
}
|
||||
|
||||
/* retun length */
|
||||
*outlen = x;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,33 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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)
|
||||
{
|
||||
unsigned long x;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
*outlen = 1 + x + noctets;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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, err;
|
||||
|
||||
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;
|
||||
|
||||
/* get the length of the data */
|
||||
y = inlen - x;
|
||||
if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += y;
|
||||
|
||||
/* is it too long? */
|
||||
if (len > *outlen) {
|
||||
*outlen = len;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (len > (inlen - x)) {
|
||||
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
|
||||
@@ -0,0 +1,61 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
len = *outlen - x;
|
||||
if ((err = der_encode_asn1_length(inlen, out + x, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += len;
|
||||
|
||||
/* store octets */
|
||||
for (y = 0; y < inlen; y++) {
|
||||
out[x++] = der_printable_char_encode(in[y]);
|
||||
}
|
||||
|
||||
/* retun length */
|
||||
*outlen = x;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,144 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
int err;
|
||||
|
||||
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 ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
*outlen = 1 + x + noctets;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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 flags c.f. enum ltc_der_seq
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_decode_sequence_ex(const unsigned char *in, unsigned long inlen,
|
||||
ltc_asn1_list *list, unsigned long outlen, unsigned int flags)
|
||||
{
|
||||
return der_decode_custom_type_ex(in, inlen, NULL, list, outlen, flags);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,546 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@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 int s_new_element(ltc_asn1_list **l)
|
||||
{
|
||||
/* alloc new link */
|
||||
if (*l == NULL) {
|
||||
*l = XCALLOC(1, sizeof(ltc_asn1_list));
|
||||
if (*l == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
} else {
|
||||
(*l)->next = XCALLOC(1, sizeof(ltc_asn1_list));
|
||||
if ((*l)->next == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
(*l)->next->prev = *l;
|
||||
*l = (*l)->next;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
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
|
||||
@param depth The depth/level of decoding recursion we've already reached
|
||||
@return CRYPT_OK on success.
|
||||
*/
|
||||
static int s_der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out, unsigned long depth)
|
||||
{
|
||||
ltc_asn1_list *l;
|
||||
unsigned long err, identifier, len, totlen, data_offset, id_len, len_len;
|
||||
void *realloc_tmp;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(inlen != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
|
||||
l = NULL;
|
||||
totlen = 0;
|
||||
|
||||
if (*inlen == 0) {
|
||||
/* alloc new link */
|
||||
if ((err = s_new_element(&l)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* scan the input and and get lengths and what not */
|
||||
while (*inlen) {
|
||||
/* alloc new link */
|
||||
if ((err = s_new_element(&l)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
id_len = *inlen;
|
||||
if ((err = der_decode_asn1_identifier(in, &id_len, l)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
/* read the type byte */
|
||||
identifier = *in;
|
||||
|
||||
if (l->type != LTC_ASN1_EOL) {
|
||||
/* fetch length */
|
||||
len_len = *inlen - id_len;
|
||||
#if defined(LTC_TEST_DBG)
|
||||
data_offset = 666;
|
||||
len = 0;
|
||||
#endif
|
||||
if ((err = der_decode_asn1_length(&in[id_len], &len_len, &len)) != CRYPT_OK) {
|
||||
#if defined(LTC_TEST_DBG)
|
||||
fprintf(stderr, "E1 %02lx: hl=%4lu l=%4lu - %s (%s)\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag], error_to_string(err));
|
||||
#endif
|
||||
goto error;
|
||||
} else if (len > (*inlen - id_len - len_len)) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
#if defined(LTC_TEST_DBG)
|
||||
fprintf(stderr, "E2 %02lx: hl=%4lu l=%4lu - %s (%s)\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag], error_to_string(err));
|
||||
#endif
|
||||
goto error;
|
||||
}
|
||||
data_offset = id_len + len_len;
|
||||
#if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1
|
||||
if (l->type == LTC_ASN1_CUSTOM_TYPE && l->klass == LTC_ASN1_CL_CONTEXT_SPECIFIC) {
|
||||
fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - Context Specific[%s %llu]\n", identifier, data_offset, len, der_asn1_pc_to_string_map[l->pc], l->tag);
|
||||
} else {
|
||||
fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - %s\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag]);
|
||||
}
|
||||
#endif
|
||||
len += data_offset;
|
||||
|
||||
if (l->type == LTC_ASN1_CUSTOM_TYPE) {
|
||||
/* Custom type, use the 'used' field to store the original identifier */
|
||||
l->used = identifier;
|
||||
if (l->pc == LTC_ASN1_PC_CONSTRUCTED) {
|
||||
/* treat constructed elements like SEQUENCEs */
|
||||
identifier = 0x20;
|
||||
} else {
|
||||
/* primitive elements are treated as opaque data */
|
||||
identifier = 0x80;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Init this so gcc won't complain,
|
||||
* as this case will only be hit when we
|
||||
* can't decode the identifier so the
|
||||
* switch-case should go to default anyway...
|
||||
*/
|
||||
data_offset = 0;
|
||||
len = 0;
|
||||
}
|
||||
|
||||
/* now switch on type */
|
||||
switch (identifier) {
|
||||
case 0x01: /* BOOLEAN */
|
||||
if (l->type != LTC_ASN1_BOOLEAN) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
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 */
|
||||
if (l->type != LTC_ASN1_INTEGER) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = 1;
|
||||
if ((err = ltc_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 */
|
||||
if (l->type != LTC_ASN1_BIT_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
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 */
|
||||
if (l->type != LTC_ASN1_OCTET_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
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 */
|
||||
if (l->type != LTC_ASN1_NULL) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* valid NULL is 0x05 0x00 */
|
||||
if (in[0] != 0x05 || in[1] != 0x00) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* simple to store ;-) */
|
||||
l->data = NULL;
|
||||
l->size = 0;
|
||||
len = 2;
|
||||
|
||||
break;
|
||||
|
||||
case 0x06: /* OID */
|
||||
if (l->type != LTC_ASN1_OBJECT_IDENTIFIER) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
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 */
|
||||
if (l->type != LTC_ASN1_UTF8_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(l->size, sizeof(wchar_t))) == 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 */
|
||||
if (l->type != LTC_ASN1_PRINTABLE_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
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 0x14: /* TELETEXT */
|
||||
if (l->type != LTC_ASN1_TELETEX_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(1, l->size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_teletex_string(in, *inlen, l->data, &l->size)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_teletex_string(l->data, l->size, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x16: /* IA5 */
|
||||
if (l->type != LTC_ASN1_IA5_STRING) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
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 */
|
||||
if (l->type != LTC_ASN1_UTCTIME) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
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 0x18:
|
||||
if (l->type != LTC_ASN1_GENERALIZEDTIME) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* init field */
|
||||
l->size = len;
|
||||
|
||||
if ((l->data = XCALLOC(1, sizeof(ltc_generalizedtime))) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_generalizedtime(in, &len, l->data)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_length_generalizedtime(l->data, &len)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x20: /* Any CONSTRUCTED element that is neither SEQUENCE nor SET */
|
||||
case 0x30: /* SEQUENCE */
|
||||
case 0x31: /* SET */
|
||||
|
||||
/* init field */
|
||||
if (identifier == 0x20) {
|
||||
if (l->type != LTC_ASN1_CUSTOM_TYPE) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (identifier == 0x30) {
|
||||
if (l->type != LTC_ASN1_SEQUENCE) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (l->type != LTC_ASN1_SET) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
/* check that we don't go over the recursion limit */
|
||||
if (depth > LTC_DER_MAX_RECURSION) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((l->data = XMALLOC(len)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
XMEMCPY(l->data, in, len);
|
||||
l->size = len;
|
||||
|
||||
|
||||
/* jump to the start of the data */
|
||||
in += data_offset;
|
||||
*inlen -= data_offset;
|
||||
len -= data_offset;
|
||||
|
||||
/* save the decoded ASN.1 len */
|
||||
len_len = len;
|
||||
|
||||
/* Sequence elements go as child */
|
||||
if ((err = s_der_decode_sequence_flexi(in, &len, &(l->child), depth+1)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
if (len_len != len) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* len update */
|
||||
totlen += data_offset;
|
||||
|
||||
/* the flexi decoder can also do nothing, so make sure a child has been allocated */
|
||||
if (l->child) {
|
||||
/* link them up y0 */
|
||||
l->child->parent = l;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 0x80: /* Context-specific */
|
||||
if (l->type != LTC_ASN1_CUSTOM_TYPE) {
|
||||
err = CRYPT_PK_ASN1_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((l->data = XCALLOC(1, len - data_offset)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
XMEMCPY(l->data, in + data_offset, len - data_offset);
|
||||
l->size = len - data_offset;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
/* invalid byte ... this is a soft error */
|
||||
/* remove link */
|
||||
if (l->prev) {
|
||||
l = l->prev;
|
||||
XFREE(l->next);
|
||||
l->next = NULL;
|
||||
}
|
||||
goto outside;
|
||||
}
|
||||
|
||||
/* advance pointers */
|
||||
totlen += len;
|
||||
in += len;
|
||||
*inlen -= len;
|
||||
}
|
||||
|
||||
outside:
|
||||
|
||||
/* in case we processed anything */
|
||||
if (totlen) {
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
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)
|
||||
{
|
||||
return s_der_decode_sequence_flexi(in, inlen, out, 0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
@@ -0,0 +1,184 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@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
|
||||
@param a1 Initialized argument list #1
|
||||
@param a2 Initialized argument list #2 (copy of #1)
|
||||
@param flags c.f. enum ltc_der_seq
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
static int s_der_decode_sequence_va(const unsigned char *in, unsigned long inlen, va_list a1, va_list a2, unsigned int flags)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_type type;
|
||||
unsigned long size, x;
|
||||
void *data;
|
||||
ltc_asn1_list *list;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
/* get size of output that will be required */
|
||||
x = 0;
|
||||
for (;;) {
|
||||
type = (ltc_asn1_type)va_arg(a1, int);
|
||||
|
||||
if (type == LTC_ASN1_EOL) {
|
||||
break;
|
||||
}
|
||||
|
||||
size = va_arg(a1, unsigned long);
|
||||
data = va_arg(a1, void*);
|
||||
LTC_UNUSED_PARAM(size);
|
||||
LTC_UNUSED_PARAM(data);
|
||||
|
||||
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:
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
case LTC_ASN1_GENERALIZEDTIME:
|
||||
++x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
/* allocate structure for x elements */
|
||||
if (x == 0) {
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
|
||||
list = XCALLOC(x, sizeof(*list));
|
||||
if (list == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* fill in the structure */
|
||||
x = 0;
|
||||
for (;;) {
|
||||
type = (ltc_asn1_type)va_arg(a2, int);
|
||||
size = va_arg(a2, unsigned long);
|
||||
data = va_arg(a2, 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:
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
case LTC_ASN1_GENERALIZEDTIME:
|
||||
LTC_SET_ASN1(list, x++, type, data, size);
|
||||
break;
|
||||
/* coverity[dead_error_line] */
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
err = der_decode_sequence_ex(in, inlen, list, x, flags);
|
||||
XFREE(list);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
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, ...)
|
||||
{
|
||||
va_list a1, a2;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
va_start(a1, inlen);
|
||||
va_start(a2, inlen);
|
||||
|
||||
err = s_der_decode_sequence_va(in, inlen, a1, a2, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_RELAXED);
|
||||
|
||||
va_end(a2);
|
||||
va_end(a1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Decode a SEQUENCE type using a VA list
|
||||
@param in Input buffer
|
||||
@param inlen Length of input in octets
|
||||
@param flags c.f. enum ltc_der_seq
|
||||
@remark <...> is of the form <type, size, data> (int, unsigned long, void*)
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...)
|
||||
{
|
||||
va_list a1, a2;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
va_start(a1, flags);
|
||||
va_start(a2, flags);
|
||||
|
||||
err = s_der_decode_sequence_va(in, inlen, a1, a2, flags);
|
||||
|
||||
va_end(a2);
|
||||
va_end(a1);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
@@ -0,0 +1,202 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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(const ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen, int type_of)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_type 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; z = 0;
|
||||
if (der_length_sequence_ex(list, inlen, &y, &z) != CRYPT_OK) return CRYPT_INVALID_ARG;
|
||||
|
||||
/* 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;
|
||||
|
||||
y = *outlen - x;
|
||||
if ((err = der_encode_asn1_length(z, &out[x], &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
x += y;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_INTEGER:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_integer(data, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
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;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_BIT_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_RAW_BIT_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_raw_bit_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_OCTET_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_octet_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_NULL:
|
||||
out[x] = 0x05;
|
||||
out[x+1] = 0x00;
|
||||
z = 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;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_IA5_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_ia5_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_PRINTABLE_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_printable_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_UTF8_STRING:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_utf8_string(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_UTCTIME:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_utctime(data, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_GENERALIZEDTIME:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_generalizedtime(data, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SET:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_set(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SETOF:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_setof(data, size, out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_SEQUENCE:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_sequence_ex(data, size, out + x, &z, type)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
z = *outlen;
|
||||
if ((err = der_encode_custom_type(&list[i], out + x, &z)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
x += z;
|
||||
*outlen -= z;
|
||||
}
|
||||
*outlen = x;
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,142 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@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;
|
||||
ltc_asn1_type 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 = (ltc_asn1_type)va_arg(args, int);
|
||||
|
||||
if (type == LTC_ASN1_EOL) {
|
||||
break;
|
||||
}
|
||||
|
||||
size = va_arg(args, unsigned long);
|
||||
data = va_arg(args, void*);
|
||||
LTC_UNUSED_PARAM(size);
|
||||
LTC_UNUSED_PARAM(data);
|
||||
|
||||
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_RAW_BIT_STRING:
|
||||
case LTC_ASN1_GENERALIZEDTIME:
|
||||
++x;
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
va_end(args);
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
/* allocate structure for x elements */
|
||||
if (x == 0) {
|
||||
return CRYPT_NOP;
|
||||
}
|
||||
|
||||
list = XCALLOC(x, sizeof(*list));
|
||||
if (list == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* fill in the structure */
|
||||
va_start(args, outlen);
|
||||
x = 0;
|
||||
for (;;) {
|
||||
type = (ltc_asn1_type)va_arg(args, int);
|
||||
|
||||
if (type == LTC_ASN1_EOL) {
|
||||
break;
|
||||
}
|
||||
|
||||
size = va_arg(args, unsigned long);
|
||||
data = va_arg(args, void*);
|
||||
|
||||
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_RAW_BIT_STRING:
|
||||
case LTC_ASN1_GENERALIZEDTIME:
|
||||
LTC_SET_ASN1(list, x++, type, data, size);
|
||||
break;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
case LTC_ASN1_EOL:
|
||||
case LTC_ASN1_TELETEX_STRING:
|
||||
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
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
@@ -0,0 +1,38 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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_flexi_sequence_cmp(const ltc_asn1_list *flexi, der_flexi_check *check)
|
||||
{
|
||||
ltc_asn1_list *cur;
|
||||
if (flexi->type != LTC_ASN1_SEQUENCE) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
cur = flexi->child;
|
||||
while(check->t != LTC_ASN1_EOL) {
|
||||
if (!LTC_ASN1_IS_TYPE(cur, check->t)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
if (check->pp != NULL) *check->pp = cur;
|
||||
cur = cur->next;
|
||||
check++;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,179 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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(const ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned long *outlen)
|
||||
{
|
||||
return der_length_sequence_ex(list, inlen, outlen, NULL);
|
||||
}
|
||||
|
||||
int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned long *outlen, unsigned long *payloadlen)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_type type;
|
||||
unsigned long size, x, y, 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;
|
||||
}
|
||||
|
||||
/* some items may be optional during import */
|
||||
if (!list[i].used && list[i].optional) continue;
|
||||
|
||||
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:
|
||||
case LTC_ASN1_RAW_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_TELETEX_STRING:
|
||||
if ((err = der_length_teletex_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_GENERALIZEDTIME:
|
||||
if ((err = der_length_generalizedtime(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_CUSTOM_TYPE:
|
||||
if ((err = der_length_custom_type(&list[i], &x, NULL)) != 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;
|
||||
|
||||
case LTC_ASN1_CHOICE:
|
||||
case LTC_ASN1_EOL:
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = der_length_asn1_length(y, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
if (payloadlen != NULL) {
|
||||
*payloadlen = y;
|
||||
}
|
||||
|
||||
/* store size */
|
||||
*outlen = y + x + 1;
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,53 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
|
||||
if (!in) return;
|
||||
|
||||
/* 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_SETOF: break;
|
||||
case LTC_ASN1_INTEGER : if (in->data != NULL) { ltc_mp_clear(in->data); } break;
|
||||
default : if (in->data != NULL) { XFREE(in->data); }
|
||||
}
|
||||
|
||||
/* move to next and free current */
|
||||
l = in->next;
|
||||
XFREE(in);
|
||||
in = l;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_sequence_shrink.c
|
||||
Free memory allocated for CONSTRUCTED, SET or SEQUENCE elements by der_decode_sequence_flexi(), Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Free memory allocated for CONSTRUCTED,
|
||||
SET or SEQUENCE elements by der_decode_sequence_flexi()
|
||||
@param in The list to shrink
|
||||
*/
|
||||
void der_sequence_shrink(ltc_asn1_list *in)
|
||||
{
|
||||
if (!in) return;
|
||||
|
||||
/* now walk the list and free stuff */
|
||||
while (in != NULL) {
|
||||
/* is there a child? */
|
||||
if (in->child) {
|
||||
der_sequence_shrink(in->child);
|
||||
}
|
||||
|
||||
switch (in->type) {
|
||||
case LTC_ASN1_CUSTOM_TYPE:
|
||||
case LTC_ASN1_SET:
|
||||
case LTC_ASN1_SEQUENCE : if (in->data != NULL) { XFREE(in->data); in->data = NULL; } break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
/* move to next and free current */
|
||||
in = in->next;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@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 s_ltc_to_asn1(ltc_asn1_type v)
|
||||
{
|
||||
return der_asn1_type_to_identifier_map[v];
|
||||
}
|
||||
|
||||
#define s_qsort_helper s_set_qsort_helper
|
||||
static int s_qsort_helper(const void *a, const void *b)
|
||||
{
|
||||
ltc_asn1_list *A = (ltc_asn1_list *)a, *B = (ltc_asn1_list *)b;
|
||||
int r;
|
||||
|
||||
r = s_ltc_to_asn1(A->type) - s_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;
|
||||
}
|
||||
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(const 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), &s_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;
|
||||
}
|
||||
|
||||
#undef s_qsort_helper
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
154
Sources/DataLiteC/libtomcrypt/pk/asn1/der/set/der_encode_setof.c
Normal file
154
Sources/DataLiteC/libtomcrypt/pk/asn1/der/set/der_encode_setof.c
Normal file
@@ -0,0 +1,154 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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;
|
||||
};
|
||||
|
||||
#define s_qsort_helper s_setof_qsort_helper
|
||||
static int s_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;
|
||||
}
|
||||
|
||||
/**
|
||||
Encode a SETOF stucture
|
||||
@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_setof(const ltc_asn1_list *list, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x, y, z;
|
||||
ptrdiff_t 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 = ptr - 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), &s_qsort_helper);
|
||||
|
||||
/* copy static header */
|
||||
XMEMCPY(out, buf, hdrlen);
|
||||
|
||||
/* copy+sort using edges+indecies to output from buffer */
|
||||
for (y = (unsigned long)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;
|
||||
}
|
||||
|
||||
#undef s_qsort_helper
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_decode_short_integer.c
|
||||
ASN.1 DER, decode an integer, Tom St Denis
|
||||
*/
|
||||
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Read a short integer
|
||||
@param in The DER encoded data
|
||||
@param inlen Size of data
|
||||
@param num [out] The integer to decode
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num)
|
||||
{
|
||||
unsigned long len, x, y;
|
||||
|
||||
LTC_ARGCHK(num != NULL);
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
/* check length */
|
||||
if (inlen < 2) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* check header */
|
||||
x = 0;
|
||||
if ((in[x++] & 0x1F) != 0x02) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* get the packet len */
|
||||
len = in[x++];
|
||||
|
||||
if (x + len > inlen) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
if (len > sizeof(unsigned long)) {
|
||||
return CRYPT_OVERFLOW;
|
||||
}
|
||||
|
||||
/* read number */
|
||||
y = 0;
|
||||
while (len--) {
|
||||
y = (y<<8) | (unsigned long)in[x++];
|
||||
}
|
||||
*num = y;
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,85 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_encode_short_integer.c
|
||||
ASN.1 DER, encode an integer, Tom St Denis
|
||||
*/
|
||||
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Store a short integer in the range (0,2^32-1)
|
||||
@param num The integer 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_short_integer(unsigned long num, unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long len, x, y, z;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* force to 32 bits */
|
||||
num &= 0xFFFFFFFFUL;
|
||||
|
||||
/* find out how big this will be */
|
||||
if ((err = der_length_short_integer(num, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (*outlen < len) {
|
||||
*outlen = len;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* get len of output */
|
||||
z = 0;
|
||||
y = num;
|
||||
while (y) {
|
||||
++z;
|
||||
y >>= 8;
|
||||
}
|
||||
|
||||
/* handle zero */
|
||||
if (z == 0) {
|
||||
z = 1;
|
||||
}
|
||||
|
||||
/* see if msb is set */
|
||||
z += (num&(1UL<<((z<<3) - 1))) ? 1 : 0;
|
||||
|
||||
/* adjust the number so the msB is non-zero */
|
||||
for (x = 0; (z <= 4) && (x < (4 - z)); x++) {
|
||||
num <<= 8;
|
||||
}
|
||||
|
||||
/* store header */
|
||||
x = 0;
|
||||
out[x++] = 0x02;
|
||||
out[x++] = (unsigned char)z;
|
||||
|
||||
/* if 31st bit is set output a leading zero and decrement count */
|
||||
if (z == 5) {
|
||||
out[x++] = 0;
|
||||
--z;
|
||||
}
|
||||
|
||||
/* store values */
|
||||
for (y = 0; y < z; y++) {
|
||||
out[x++] = (unsigned char)((num >> 24) & 0xFF);
|
||||
num <<= 8;
|
||||
}
|
||||
|
||||
/* we good */
|
||||
*outlen = x;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,52 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_length_short_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 integer 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_short_integer(unsigned long num, unsigned long *outlen)
|
||||
{
|
||||
unsigned long z, y;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* force to 32 bits */
|
||||
num &= 0xFFFFFFFFUL;
|
||||
|
||||
/* get the number of bytes */
|
||||
z = 0;
|
||||
y = num;
|
||||
while (y) {
|
||||
++z;
|
||||
y >>= 8;
|
||||
}
|
||||
|
||||
/* handle zero */
|
||||
if (z == 0) {
|
||||
z = 1;
|
||||
} else if ((num&(1UL<<((z<<3) - 1))) != 0) {
|
||||
/* in case msb is set */
|
||||
++z;
|
||||
}
|
||||
|
||||
if ((err = der_length_asn1_length(z, &y)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
*outlen = 1 + y + z;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_decode_teletex_string.c
|
||||
ASN.1 DER, encode a teletex STRING
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Store a teletex STRING
|
||||
@param in The DER encoded teletex STRING
|
||||
@param inlen The size of the DER teletex 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_teletex_string(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x, y, len;
|
||||
int t, err;
|
||||
|
||||
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 0x14 */
|
||||
if ((in[0] & 0x1F) != 0x14) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
x = 1;
|
||||
|
||||
/* get the length of the data */
|
||||
y = inlen - x;
|
||||
if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += y;
|
||||
|
||||
/* is it too long? */
|
||||
if (len > *outlen) {
|
||||
*outlen = len;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
if (len > (inlen - x)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* read the data */
|
||||
for (y = 0; y < len; y++) {
|
||||
t = der_teletex_value_decode(in[x++]);
|
||||
if (t == -1) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
out[y] = t;
|
||||
}
|
||||
|
||||
*outlen = y;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,188 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_length_teletex_string.c
|
||||
ASN.1 DER, get length of teletex STRING
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
static const struct {
|
||||
int code, value;
|
||||
} teletex_table[] = {
|
||||
{ '\0', 0 },
|
||||
{ '\a', 7 },
|
||||
{ '\b', 8 },
|
||||
{ '\t', 9 },
|
||||
{ '\n', 10 },
|
||||
{ '\v', 11 },
|
||||
{ '\f', 12 },
|
||||
{ '\r', 13 },
|
||||
{ ' ', 32 },
|
||||
{ '!', 33 },
|
||||
{ '"', 34 },
|
||||
{ '%', 37 },
|
||||
{ '&', 38 },
|
||||
{ '\'', 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 },
|
||||
{ ';', 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 },
|
||||
{ ']', 93 },
|
||||
{ '_', 95 },
|
||||
{ '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 },
|
||||
{ '|', 124 },
|
||||
{ ' ', 160 },
|
||||
{ 0xa1, 161 },
|
||||
{ 0xa2, 162 },
|
||||
{ 0xa3, 163 },
|
||||
{ '$', 164 },
|
||||
{ 0xa5, 165 },
|
||||
{ '#', 166 },
|
||||
{ 0xa7, 167 },
|
||||
{ 0xa4, 168 },
|
||||
{ 0xab, 171 },
|
||||
{ 0xb0, 176 },
|
||||
{ 0xb1, 177 },
|
||||
{ 0xb2, 178 },
|
||||
{ 0xb3, 179 },
|
||||
{ 0xd7, 180 },
|
||||
{ 0xb5, 181 },
|
||||
{ 0xb6, 182 },
|
||||
{ 0xb7, 183 },
|
||||
{ 0xf7, 184 },
|
||||
{ 0xbb, 187 },
|
||||
{ 0xbc, 188 },
|
||||
{ 0xbd, 189 },
|
||||
{ 0xbe, 190 },
|
||||
{ 0xbf, 191 },
|
||||
};
|
||||
|
||||
int der_teletex_char_encode(int c)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) {
|
||||
if (teletex_table[x].code == c) {
|
||||
return teletex_table[x].value;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int der_teletex_value_decode(int v)
|
||||
{
|
||||
int x;
|
||||
for (x = 0; x < (int)(sizeof(teletex_table)/sizeof(teletex_table[0])); x++) {
|
||||
if (teletex_table[x].value == v) {
|
||||
return teletex_table[x].code;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
Gets length of DER encoding of teletex 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_teletex_string(const unsigned char *octets, unsigned long noctets, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(octets != NULL);
|
||||
|
||||
/* scan string for validity */
|
||||
for (x = 0; x < noctets; x++) {
|
||||
if (der_teletex_char_encode(octets[x]) == -1) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
|
||||
if ((err = der_length_asn1_length(noctets, &x)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
*outlen = 1 + x + noctets;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_decode_utctime.c
|
||||
ASN.1 DER, decode a UTCTIME, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
#ifndef LTC_DER_CHAR_TO_INT
|
||||
#define LTC_DER_CHAR_TO_INT
|
||||
static LTC_INLINE int s_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;
|
||||
default: return 100;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define DECODE_V(y, max) \
|
||||
y = s_char_to_int(buf[x])*10 + s_char_to_int(buf[x+1]); \
|
||||
if (y >= max) return CRYPT_INVALID_PACKET; \
|
||||
x += 2;
|
||||
|
||||
/**
|
||||
Decodes a UTC time structure in DER format (reads all 6 valid encoding formats)
|
||||
@param in Input buffer
|
||||
@param inlen Length of input buffer in octets
|
||||
@param out [out] Destination of UTC time structure
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_decode_utctime(const unsigned char *in, unsigned long *inlen,
|
||||
ltc_utctime *out)
|
||||
{
|
||||
unsigned char buf[32] = { 0 }; /* initialize as all zeroes */
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
#undef DECODE_V
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,72 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_encode_utctime.c
|
||||
ASN.1 DER, encode a UTCTIME, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
#define STORE_V(y) \
|
||||
out[x++] = der_ia5_char_encode(baseten[(y/10) % 10]); \
|
||||
out[x++] = der_ia5_char_encode(baseten[y % 10]);
|
||||
|
||||
/**
|
||||
Encodes a UTC time structure in DER format
|
||||
@param utctime The UTC time structure to encode
|
||||
@param out The destination of the DER encoding of the UTC time structure
|
||||
@param outlen [in/out] The length of the DER encoding
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_encode_utctime(const ltc_utctime *utctime,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
const char * const baseten = "0123456789";
|
||||
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) {
|
||||
*outlen = tmplen;
|
||||
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] = (unsigned char)(x - 2);
|
||||
|
||||
/* all good let's return */
|
||||
*outlen = x;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#undef STORE_V
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.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 utctime The UTC time structure to get the size of
|
||||
@param outlen [out] The length of the DER encoding
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_length_utctime(const 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
|
||||
@@ -0,0 +1,118 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_decode_utf8_string.c
|
||||
ASN.1 DER, encode a UTF8 STRING, Tom St Denis
|
||||
*/
|
||||
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Decode a UTF8 STRING and recover an array of unicode characters.
|
||||
@param in The DER encoded UTF8 STRING
|
||||
@param inlen The size of the DER UTF8 STRING
|
||||
@param out [out] The array of unicode characters (wchar_t*)
|
||||
@param outlen [in/out] The number of unicode characters in the array
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_decode_utf8_string(const unsigned char *in, unsigned long inlen,
|
||||
wchar_t *out, unsigned long *outlen)
|
||||
{
|
||||
wchar_t tmp;
|
||||
unsigned long x, y, z, len;
|
||||
int err;
|
||||
|
||||
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 0x0C */
|
||||
if ((in[0] & 0x1F) != 0x0C) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
x = 1;
|
||||
|
||||
/* get the length of the data */
|
||||
y = inlen - x;
|
||||
if ((err = der_decode_asn1_length(in + x, &y, &len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += y;
|
||||
|
||||
if (len > (inlen - x)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* proceed to recover unicode characters from utf8 data.
|
||||
for reference see Section 3 of RFC 3629:
|
||||
|
||||
https://tools.ietf.org/html/rfc3629#section-3
|
||||
*/
|
||||
len += x;
|
||||
for (y = 0; x < len; ) {
|
||||
/* read first byte */
|
||||
tmp = in[x++];
|
||||
|
||||
/* a unicode character is recovered from a sequence of 1 to 4 utf8 bytes.
|
||||
the form of those bytes must match a row in the following table:
|
||||
|
||||
0xxxxxxx
|
||||
110xxxxx 10xxxxxx
|
||||
1110xxxx 10xxxxxx 10xxxxxx
|
||||
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
|
||||
|
||||
the number of leading ones in the first byte (0,2,3,4) determines the
|
||||
number of remaining bytes to read (0,1,2,3)
|
||||
*/
|
||||
|
||||
/* determine z, the number of leading ones.
|
||||
this is done by left-shifting tmp, which clears the ms-bits */
|
||||
for (z = 0; (tmp & 0x80) && (z <= 4); z++, tmp = (tmp << 1) & 0xFF);
|
||||
|
||||
/* z should be in {0,2,3,4} */
|
||||
if (z == 1 || z > 4) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* right-shift tmp to restore least-sig bits */
|
||||
tmp >>= z;
|
||||
|
||||
/* now update z so it equals the number of additional bytes to read */
|
||||
if (z > 0) { --z; }
|
||||
|
||||
if (x + z > len) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* read remaining bytes */
|
||||
while (z-- != 0) {
|
||||
if ((in[x] & 0xC0) != 0x80) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
tmp = (tmp << 6) | ((wchar_t)in[x++] & 0x3F);
|
||||
}
|
||||
|
||||
if (y < *outlen) {
|
||||
out[y] = tmp;
|
||||
}
|
||||
y++;
|
||||
}
|
||||
if (y > *outlen) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
} else {
|
||||
err = CRYPT_OK;
|
||||
}
|
||||
*outlen = y;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,75 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_encode_utf8_string.c
|
||||
ASN.1 DER, encode a UTF8 STRING, Tom St Denis
|
||||
*/
|
||||
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Store an UTF8 STRING
|
||||
@param in The array of UTF8 to store (one per wchar_t)
|
||||
@param inlen The number of UTF8 to store
|
||||
@param out [out] The destination for the DER encoded UTF8 STRING
|
||||
@param outlen [in/out] The max size and resulting size of the DER UTF8 STRING
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int der_encode_utf8_string(const wchar_t *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 */
|
||||
for (x = len = 0; x < inlen; x++) {
|
||||
if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG;
|
||||
len += der_utf8_charsize(in[x]);
|
||||
}
|
||||
if ((err = der_length_asn1_length(len, &x)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += len + 1;
|
||||
|
||||
/* too big? */
|
||||
if (x > *outlen) {
|
||||
*outlen = x;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
|
||||
/* encode the header+len */
|
||||
x = 0;
|
||||
out[x++] = 0x0C;
|
||||
|
||||
y = *outlen - x;
|
||||
if ((err = der_encode_asn1_length(len, out + x, &y)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
x += y;
|
||||
|
||||
/* store UTF8 */
|
||||
for (y = 0; y < inlen; y++) {
|
||||
switch (der_utf8_charsize(in[y])) {
|
||||
case 1: out[x++] = (unsigned char)in[y]; break;
|
||||
case 2: out[x++] = 0xC0 | ((in[y] >> 6) & 0x1F); out[x++] = 0x80 | (in[y] & 0x3F); break;
|
||||
case 3: out[x++] = 0xE0 | ((in[y] >> 12) & 0x0F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break;
|
||||
#if !defined(LTC_WCHAR_MAX) || LTC_WCHAR_MAX > 0xFFFF
|
||||
case 4: out[x++] = 0xF0 | ((in[y] >> 18) & 0x07); out[x++] = 0x80 | ((in[y] >> 12) & 0x3F); out[x++] = 0x80 | ((in[y] >> 6) & 0x3F); out[x++] = 0x80 | (in[y] & 0x3F); break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* return length */
|
||||
*outlen = x;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,81 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file der_length_utf8_string.c
|
||||
ASN.1 DER, get length of UTF8 STRING, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/** Return the size in bytes of a UTF-8 character
|
||||
@param c The UTF-8 character to measure
|
||||
@return The size in bytes
|
||||
*/
|
||||
unsigned long der_utf8_charsize(const wchar_t c)
|
||||
{
|
||||
if (c <= 0x7F) {
|
||||
return 1;
|
||||
}
|
||||
if (c <= 0x7FF) {
|
||||
return 2;
|
||||
}
|
||||
#if LTC_WCHAR_MAX == 0xFFFF
|
||||
return 3;
|
||||
#else
|
||||
if (c <= 0xFFFF) {
|
||||
return 3;
|
||||
}
|
||||
return 4;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
Test whether the given code point is valid character
|
||||
@param c The UTF-8 character to test
|
||||
@return 1 - valid, 0 - invalid
|
||||
*/
|
||||
int der_utf8_valid_char(const wchar_t c)
|
||||
{
|
||||
LTC_UNUSED_PARAM(c);
|
||||
#if !defined(LTC_WCHAR_MAX) || LTC_WCHAR_MAX > 0xFFFF
|
||||
if (c > 0x10FFFF) return 0;
|
||||
#endif
|
||||
#if LTC_WCHAR_MAX != 0xFFFF && LTC_WCHAR_MAX != 0xFFFFFFFF
|
||||
if (c < 0) return 0;
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
Gets length of DER encoding of UTF8 STRING
|
||||
@param in The characters to measure the length of
|
||||
@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_utf8_string(const wchar_t *in, unsigned long noctets, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x, len;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
len = 0;
|
||||
for (x = 0; x < noctets; x++) {
|
||||
if (!der_utf8_valid_char(in[x])) return CRYPT_INVALID_ARG;
|
||||
len += der_utf8_charsize(in[x]);
|
||||
}
|
||||
|
||||
if ((err = der_length_asn1_length(len, &x)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
*outlen = 1 + x + len;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
106
Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_get.c
Normal file
106
Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_get.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
typedef struct {
|
||||
enum ltc_oid_id id;
|
||||
enum ltc_pka_id pka;
|
||||
const char* oid;
|
||||
} oid_table_entry;
|
||||
|
||||
static const oid_table_entry pka_oids[] = {
|
||||
{ LTC_OID_UNDEF, LTC_PKA_UNDEF, NULL },
|
||||
{ LTC_OID_RSA, LTC_PKA_RSA, "1.2.840.113549.1.1.1" },
|
||||
{ LTC_OID_DSA, LTC_PKA_DSA, "1.2.840.10040.4.1" },
|
||||
{ LTC_OID_EC, LTC_PKA_EC, "1.2.840.10045.2.1" },
|
||||
{ LTC_OID_EC_PRIMEF, LTC_PKA_EC, "1.2.840.10045.1.1" },
|
||||
{ LTC_OID_X25519, LTC_PKA_X25519, "1.3.101.110" },
|
||||
{ LTC_OID_ED25519, LTC_PKA_ED25519, "1.3.101.112" },
|
||||
{ LTC_OID_DH, LTC_PKA_DH, "1.2.840.113549.1.3.1" },
|
||||
};
|
||||
|
||||
static LTC_INLINE const oid_table_entry* s_get_entry(enum ltc_oid_id id)
|
||||
{
|
||||
if (id < LTC_OID_NUM)
|
||||
return &pka_oids[id];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the OID requested.
|
||||
@return CRYPT_OK if valid
|
||||
*/
|
||||
int pk_get_oid(enum ltc_oid_id id, const char **st)
|
||||
{
|
||||
const oid_table_entry* e = s_get_entry(id);
|
||||
LTC_ARGCHK(st != NULL);
|
||||
if (e != NULL) {
|
||||
*st = e->oid;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the PKA ID requested.
|
||||
@return CRYPT_OK if valid
|
||||
*/
|
||||
int pk_get_pka_id(enum ltc_oid_id id, enum ltc_pka_id *pka)
|
||||
{
|
||||
const oid_table_entry* e = s_get_entry(id);
|
||||
LTC_ARGCHK(pka != NULL);
|
||||
if (e != NULL) {
|
||||
*pka = e->pka;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the OID ID requested.
|
||||
@return CRYPT_OK if valid
|
||||
*/
|
||||
int pk_get_oid_id(enum ltc_pka_id pka, enum ltc_oid_id *oid)
|
||||
{
|
||||
unsigned int i;
|
||||
LTC_ARGCHK(oid != NULL);
|
||||
for (i = 1; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) {
|
||||
if (pka_oids[i].pka == pka) {
|
||||
*oid = pka_oids[i].id;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/*
|
||||
Returns the PKA ID of an OID.
|
||||
@return CRYPT_OK if valid
|
||||
*/
|
||||
int pk_get_oid_from_asn1(const ltc_asn1_list *oid, enum ltc_oid_id *id)
|
||||
{
|
||||
unsigned long i;
|
||||
char tmp[LTC_OID_MAX_STRLEN] = { 0 };
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(oid != NULL);
|
||||
LTC_ARGCHK(id != NULL);
|
||||
|
||||
if (oid->type != LTC_ASN1_OBJECT_IDENTIFIER) return CRYPT_INVALID_ARG;
|
||||
|
||||
i = sizeof(tmp);
|
||||
if ((err = pk_oid_num_to_str(oid->data, oid->size, tmp, &i)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
for (i = 1; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) {
|
||||
if (XSTRCMP(pka_oids[i].oid, tmp) == 0) {
|
||||
*id = pka_oids[i].id;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
}
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
#endif
|
||||
44
Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_oid_cmp.c
Normal file
44
Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_oid_cmp.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/*
|
||||
Compare an OID string to an array of `unsigned long`.
|
||||
@return CRYPT_OK if equal
|
||||
*/
|
||||
int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long o2size)
|
||||
{
|
||||
unsigned long i;
|
||||
char tmp[LTC_OID_MAX_STRLEN] = { 0 };
|
||||
int err;
|
||||
|
||||
if (o1 == NULL || o2 == NULL) return CRYPT_ERROR;
|
||||
|
||||
i = sizeof(tmp);
|
||||
if ((err = pk_oid_num_to_str(o2, o2size, tmp, &i)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (XSTRCMP(o1, tmp) != 0) {
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/*
|
||||
Compare an OID string to an OID element decoded from ASN.1.
|
||||
@return CRYPT_OK if equal
|
||||
*/
|
||||
int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2)
|
||||
{
|
||||
if (o1 == NULL || o2 == NULL) return CRYPT_ERROR;
|
||||
|
||||
if (o2->type != LTC_ASN1_OBJECT_IDENTIFIER) return CRYPT_INVALID_ARG;
|
||||
|
||||
return pk_oid_cmp_with_ulong(o1, o2->data, o2->size);
|
||||
}
|
||||
|
||||
#endif
|
||||
88
Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_oid_str.c
Normal file
88
Sources/DataLiteC/libtomcrypt/pk/asn1/oid/pk_oid_str.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen)
|
||||
{
|
||||
unsigned long i, j, limit, oid_j;
|
||||
size_t OID_len;
|
||||
|
||||
LTC_ARGCHK(oidlen != NULL);
|
||||
|
||||
limit = *oidlen;
|
||||
*oidlen = 0; /* make sure that we return zero oidlen on error */
|
||||
for (i = 0; i < limit; i++) oid[i] = 0;
|
||||
|
||||
if (OID == NULL) return CRYPT_OK;
|
||||
|
||||
OID_len = XSTRLEN(OID);
|
||||
if (OID_len == 0) return CRYPT_OK;
|
||||
|
||||
for (i = 0, j = 0; i < OID_len; i++) {
|
||||
if (OID[i] == '.') {
|
||||
if (++j >= limit) continue;
|
||||
}
|
||||
else if ((OID[i] >= '0') && (OID[i] <= '9')) {
|
||||
if ((j >= limit) || (oid == NULL)) continue;
|
||||
oid_j = oid[j];
|
||||
oid[j] = oid[j] * 10 + (OID[i] - '0');
|
||||
if (oid[j] < oid_j) return CRYPT_OVERFLOW;
|
||||
}
|
||||
else {
|
||||
return CRYPT_ERROR;
|
||||
}
|
||||
}
|
||||
if (j == 0) return CRYPT_ERROR;
|
||||
if (j >= limit) {
|
||||
*oidlen = j;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
*oidlen = j + 1;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen)
|
||||
{
|
||||
int i;
|
||||
unsigned long j, k;
|
||||
char tmp[LTC_OID_MAX_STRLEN] = { 0 };
|
||||
|
||||
LTC_ARGCHK(oid != NULL);
|
||||
LTC_ARGCHK(oidlen < INT_MAX);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
for (i = oidlen - 1, k = 0; i >= 0; i--) {
|
||||
j = oid[i];
|
||||
if (j == 0) {
|
||||
tmp[k] = '0';
|
||||
if (++k >= sizeof(tmp)) return CRYPT_ERROR;
|
||||
}
|
||||
else {
|
||||
while (j > 0) {
|
||||
tmp[k] = '0' + (j % 10);
|
||||
if (++k >= sizeof(tmp)) return CRYPT_ERROR;
|
||||
j /= 10;
|
||||
}
|
||||
}
|
||||
if (i > 0) {
|
||||
tmp[k] = '.';
|
||||
if (++k >= sizeof(tmp)) return CRYPT_ERROR;
|
||||
}
|
||||
}
|
||||
if (*outlen < k + 1) {
|
||||
*outlen = k + 1;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
LTC_ARGCHK(OID != NULL);
|
||||
for (j = 0; j < k; j++) OID[j] = tmp[k - j - 1];
|
||||
OID[k] = '\0';
|
||||
*outlen = k; /* the length without terminating NUL byte */
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
106
Sources/DataLiteC/libtomcrypt/pk/asn1/pkcs8/pkcs8_decode_flexi.c
Normal file
106
Sources/DataLiteC/libtomcrypt/pk/asn1/pkcs8/pkcs8_decode_flexi.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_PKCS_8
|
||||
|
||||
/**
|
||||
PKCS#8 decrypt if necessary & flexi-decode
|
||||
|
||||
@param in Pointer to the ASN.1 encoded input data
|
||||
@param inlen Length of the input data
|
||||
@param pwd Pointer to the password that was used when encrypting
|
||||
@param pwdlen Length of the password
|
||||
@param decoded_list Pointer to a pointer for the flexi-decoded list
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen,
|
||||
const password_ctx *pw_ctx,
|
||||
ltc_asn1_list **decoded_list)
|
||||
{
|
||||
unsigned long len = inlen;
|
||||
unsigned long dec_size;
|
||||
unsigned char *dec_data = NULL;
|
||||
ltc_asn1_list *l = NULL;
|
||||
int err;
|
||||
pbes_arg pbes;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(decoded_list != NULL);
|
||||
|
||||
XMEMSET(&pbes, 0, sizeof(pbes));
|
||||
|
||||
*decoded_list = NULL;
|
||||
if ((err = der_decode_sequence_flexi(in, &len, &l)) == CRYPT_OK) {
|
||||
/* the following "if" detects whether it is encrypted or not */
|
||||
/* PKCS8 Setup
|
||||
* 0:d=0 hl=4 l= 380 cons: SEQUENCE
|
||||
* 4:d=1 hl=2 l= 78 cons: SEQUENCE
|
||||
* 6:d=2 hl=2 l= 9 prim: OBJECT :OID indicating PBES1 or PBES2 (== *lalgoid)
|
||||
* 17:d=2 hl=2 l= 65 cons: SEQUENCE
|
||||
* Stuff in between is dependent on whether it's PBES1 or PBES2
|
||||
* 84:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data)
|
||||
*/
|
||||
if (l->type == LTC_ASN1_SEQUENCE &&
|
||||
LTC_ASN1_IS_TYPE(l->child, LTC_ASN1_SEQUENCE) &&
|
||||
LTC_ASN1_IS_TYPE(l->child->child, LTC_ASN1_OBJECT_IDENTIFIER) &&
|
||||
LTC_ASN1_IS_TYPE(l->child->child->next, LTC_ASN1_SEQUENCE) &&
|
||||
LTC_ASN1_IS_TYPE(l->child->next, LTC_ASN1_OCTET_STRING)) {
|
||||
ltc_asn1_list *lalgoid = l->child->child;
|
||||
|
||||
if ((pw_ctx == NULL) || (pw_ctx->callback == NULL)) {
|
||||
err = CRYPT_PW_CTX_MISSING;
|
||||
goto LBL_DONE;
|
||||
}
|
||||
|
||||
if (pbes1_extract(lalgoid, &pbes) == CRYPT_OK) {
|
||||
/* Successfully extracted PBES1 parameters */
|
||||
} else if (pbes2_extract(lalgoid, &pbes) == CRYPT_OK) {
|
||||
/* Successfully extracted PBES2 parameters */
|
||||
} else {
|
||||
/* unsupported encryption */
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_DONE;
|
||||
}
|
||||
|
||||
if (pw_ctx->callback(&pbes.pw.pw, &pbes.pw.l, pw_ctx->userdata)) {
|
||||
err = CRYPT_ERROR;
|
||||
goto LBL_DONE;
|
||||
}
|
||||
|
||||
pbes.enc_data = l->child->next;
|
||||
|
||||
dec_size = pbes.enc_data->size;
|
||||
if ((dec_data = XMALLOC(dec_size)) == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto LBL_DONE;
|
||||
}
|
||||
|
||||
if ((err = pbes_decrypt(&pbes, dec_data, &dec_size)) != CRYPT_OK) goto LBL_DONE;
|
||||
|
||||
der_free_sequence_flexi(l);
|
||||
l = NULL;
|
||||
err = der_decode_sequence_flexi(dec_data, &dec_size, &l);
|
||||
if (err != CRYPT_OK) goto LBL_DONE;
|
||||
*decoded_list = l;
|
||||
}
|
||||
else {
|
||||
/* not encrypted */
|
||||
err = CRYPT_OK;
|
||||
*decoded_list = l;
|
||||
}
|
||||
/* Set l to NULL so it won't be free'd */
|
||||
l = NULL;
|
||||
}
|
||||
|
||||
LBL_DONE:
|
||||
if (dec_data) {
|
||||
zeromem(dec_data, dec_size);
|
||||
XFREE(dec_data);
|
||||
}
|
||||
password_free(&pbes.pw, pw_ctx);
|
||||
if (l) der_free_sequence_flexi(l);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
54
Sources/DataLiteC/libtomcrypt/pk/asn1/pkcs8/pkcs8_get.c
Normal file
54
Sources/DataLiteC/libtomcrypt/pk/asn1/pkcs8/pkcs8_get.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@file pkcs8_get.c
|
||||
PKCS#8 utility functions
|
||||
*/
|
||||
|
||||
#ifdef LTC_PKCS_8
|
||||
|
||||
int pkcs8_get_children(const ltc_asn1_list *decoded_list, enum ltc_oid_id *pka, ltc_asn1_list **alg_id, ltc_asn1_list **priv_key)
|
||||
{
|
||||
int err;
|
||||
unsigned long n;
|
||||
der_flexi_check flexi_should[4];
|
||||
ltc_asn1_list *seq_l, *version;
|
||||
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
if (alg_id == NULL) alg_id = &seq_l;
|
||||
|
||||
/* Setup for basic structure */
|
||||
n=0;
|
||||
LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_INTEGER, &version);
|
||||
LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, alg_id);
|
||||
LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OCTET_STRING, priv_key);
|
||||
LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL);
|
||||
|
||||
err = der_flexi_sequence_cmp(decoded_list, flexi_should);
|
||||
switch (err) {
|
||||
case CRYPT_OK:
|
||||
case CRYPT_INPUT_TOO_LONG:
|
||||
/* If there are attributes added after the private_key it is tagged with version 1 and
|
||||
* we get an 'input too long' error but the rest is already decoded and can be
|
||||
* handled the same as for version 0
|
||||
*/
|
||||
if (ltc_mp_cmp_d(version->data, 0) != LTC_MP_EQ && ltc_mp_cmp_d(version->data, 1) != LTC_MP_EQ) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return err;
|
||||
}
|
||||
return pk_get_oid_from_asn1((*alg_id)->child, pka);
|
||||
}
|
||||
|
||||
#endif /* LTC_PKCS_8 */
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
@@ -0,0 +1,71 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file x509_decode_public_key_from_certificate.c
|
||||
ASN.1 DER/X.509, decode a certificate
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/**
|
||||
Try to decode the public key from a X.509 certificate
|
||||
@param in The input buffer
|
||||
@param inlen The length of the input buffer
|
||||
@param algorithm One out of the enum #public_key_algorithms
|
||||
@param param_type The parameters' type out of the enum ltc_asn1_type
|
||||
@param parameters The parameters to include
|
||||
@param parameters_len [in/out] The number of parameters to include
|
||||
@param callback The callback
|
||||
@param ctx The context passed to the callback
|
||||
@return CRYPT_OK on success,
|
||||
CRYPT_NOP if no SubjectPublicKeyInfo was found,
|
||||
another error if decoding or memory allocation failed
|
||||
*/
|
||||
int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned long inlen,
|
||||
enum ltc_oid_id algorithm, ltc_asn1_type param_type,
|
||||
ltc_asn1_list* parameters, unsigned long *parameters_len,
|
||||
public_key_decode_cb callback, void *ctx)
|
||||
{
|
||||
int err;
|
||||
unsigned char *tmpbuf = NULL;
|
||||
unsigned long tmpbuf_len;
|
||||
ltc_asn1_list *decoded_list = NULL, *spki;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(inlen != 0);
|
||||
LTC_ARGCHK(callback != NULL);
|
||||
|
||||
if ((err = x509_decode_spki(in, inlen, &decoded_list, &spki)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (algorithm == LTC_OID_EC) {
|
||||
err = callback(spki->data, spki->size, ctx);
|
||||
} else {
|
||||
|
||||
tmpbuf_len = inlen;
|
||||
tmpbuf = XCALLOC(1, tmpbuf_len);
|
||||
if (tmpbuf == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto LBL_OUT;
|
||||
}
|
||||
|
||||
err = x509_decode_subject_public_key_info(spki->data, spki->size,
|
||||
algorithm, tmpbuf, &tmpbuf_len,
|
||||
param_type, parameters, parameters_len);
|
||||
if (err == CRYPT_OK) {
|
||||
err = callback(tmpbuf, tmpbuf_len, ctx);
|
||||
goto LBL_OUT;
|
||||
}
|
||||
}
|
||||
|
||||
LBL_OUT:
|
||||
if (decoded_list) der_free_sequence_flexi(decoded_list);
|
||||
if (tmpbuf != NULL) XFREE(tmpbuf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,82 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file x509_decode_public_key_from_certificate.c
|
||||
ASN.1 DER/X.509, decode a SubjectPublicKeyInfo
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/* Check if it looks like a SubjectPublicKeyInfo */
|
||||
#define LOOKS_LIKE_SPKI(l) ((l) != NULL) \
|
||||
&& ((l)->type == LTC_ASN1_SEQUENCE) \
|
||||
&& ((l)->child != NULL) \
|
||||
&& ((l)->child->type == LTC_ASN1_OBJECT_IDENTIFIER) \
|
||||
&& ((l)->next != NULL) \
|
||||
&& ((l)->next->type == LTC_ASN1_BIT_STRING)
|
||||
|
||||
/**
|
||||
DER decode a X.509 certificate and return the SubjectPublicKeyInfo
|
||||
@param in The input buffer
|
||||
@param inlen The length of the input buffer
|
||||
@param out [out] A pointer to the decoded linked list (you take ownership of this one and
|
||||
`der_free_sequence_flexi()` it when you're done)
|
||||
@param spki [out] A pointer to the SubjectPublicKeyInfo
|
||||
@return CRYPT_OK on success, CRYPT_NOP if no SubjectPublicKeyInfo was found, another error if decoding failed
|
||||
*/
|
||||
int x509_decode_spki(const unsigned char *in, unsigned long inlen, ltc_asn1_list **out, ltc_asn1_list **spki)
|
||||
{
|
||||
int err;
|
||||
unsigned long tmp_inlen;
|
||||
ltc_asn1_list *decoded_list = NULL, *l;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(inlen != 0);
|
||||
|
||||
tmp_inlen = inlen;
|
||||
if ((err = der_decode_sequence_flexi(in, &tmp_inlen, &decoded_list)) == CRYPT_OK) {
|
||||
l = decoded_list;
|
||||
|
||||
err = CRYPT_NOP;
|
||||
|
||||
/* Move 2 levels up in the tree
|
||||
SEQUENCE
|
||||
SEQUENCE
|
||||
...
|
||||
*/
|
||||
if ((l->type == LTC_ASN1_SEQUENCE) && (l->child != NULL)) {
|
||||
l = l->child;
|
||||
if ((l->type == LTC_ASN1_SEQUENCE) && (l->child != NULL)) {
|
||||
l = l->child;
|
||||
|
||||
/* Move forward in the tree until we find this combination
|
||||
...
|
||||
SEQUENCE
|
||||
SEQUENCE
|
||||
OBJECT IDENTIFIER <some PKA OID, e.g. 1.2.840.113549.1.1.1>
|
||||
NULL
|
||||
BIT STRING
|
||||
*/
|
||||
do {
|
||||
/* The additional check for l->data is there to make sure
|
||||
* we won't try to decode a list that has been 'shrunk'
|
||||
*/
|
||||
if ((l->type == LTC_ASN1_SEQUENCE)
|
||||
&& (l->data != NULL)
|
||||
&& LOOKS_LIKE_SPKI(l->child)) {
|
||||
*out = decoded_list;
|
||||
*spki = l;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
l = l->next;
|
||||
} while(l);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (decoded_list) der_free_sequence_flexi(decoded_list);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,119 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file x509_decode_subject_public_key_info.c
|
||||
ASN.1 DER/X.509, encode a SubjectPublicKeyInfo structure --nmav
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/* AlgorithmIdentifier := SEQUENCE {
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters ANY DEFINED BY algorithm
|
||||
* }
|
||||
*
|
||||
* SubjectPublicKeyInfo := SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING
|
||||
* }
|
||||
*/
|
||||
/**
|
||||
Decode a SubjectPublicKeyInfo
|
||||
@param in The input buffer
|
||||
@param inlen The length of the input buffer
|
||||
@param algorithm One out of the enum #public_key_algorithms
|
||||
@param public_key The buffer for the public key
|
||||
@param public_key_len [in/out] The length of the public key buffer and the written length
|
||||
@param parameters_type The parameters' type out of the enum ltc_asn1_type
|
||||
@param parameters The parameters to include
|
||||
@param parameters_len [in/out] The number of parameters to include
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
|
||||
enum ltc_oid_id algorithm, void *public_key, unsigned long *public_key_len,
|
||||
ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len)
|
||||
{
|
||||
int err;
|
||||
unsigned long len, alg_id_num, tmplen;
|
||||
const char* oid;
|
||||
unsigned char *tmpbuf;
|
||||
unsigned long tmpoid[16];
|
||||
unsigned long *_parameters_len;
|
||||
ltc_asn1_list alg_id[2];
|
||||
ltc_asn1_list subject_pubkey[2];
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(inlen != 0);
|
||||
LTC_ARGCHK(public_key_len != NULL);
|
||||
|
||||
if (parameters_type != LTC_ASN1_EOL) {
|
||||
if ((parameters == NULL) || (parameters_len == NULL)) {
|
||||
tmplen = 0;
|
||||
_parameters_len = &tmplen;
|
||||
} else {
|
||||
_parameters_len = parameters_len;
|
||||
}
|
||||
}
|
||||
|
||||
err = pk_get_oid(algorithm, &oid);
|
||||
if (err != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* see if the OpenSSL DER format RSA public key will work */
|
||||
tmpbuf = XCALLOC(1, inlen);
|
||||
if (tmpbuf == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* this includes the internal hash ID and optional params (NULL in this case) */
|
||||
LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0]));
|
||||
if (parameters_type == LTC_ASN1_EOL) {
|
||||
alg_id_num = 1;
|
||||
} else {
|
||||
LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, *_parameters_len);
|
||||
alg_id_num = 2;
|
||||
}
|
||||
|
||||
/* the actual format of the SSL DER key is odd, it stores a RSAPublicKey
|
||||
* in a **BIT** string ... so we have to extract it then proceed to convert bit to octet
|
||||
*/
|
||||
LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, alg_id_num);
|
||||
LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, inlen*8U);
|
||||
|
||||
err=der_decode_sequence(in, inlen, subject_pubkey, 2UL);
|
||||
if (err != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if (parameters_type != LTC_ASN1_EOL) {
|
||||
*_parameters_len = alg_id[1].size;
|
||||
}
|
||||
|
||||
if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) {
|
||||
/* OID mismatch */
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
len = subject_pubkey[1].size/8;
|
||||
if (*public_key_len >= len) {
|
||||
XMEMCPY(public_key, subject_pubkey[1].data, len);
|
||||
*public_key_len = len;
|
||||
} else {
|
||||
*public_key_len = len;
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
|
||||
XFREE(tmpbuf);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,66 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file x509_encode_subject_public_key_info.c
|
||||
ASN.1 DER/X.509, encode a SubjectPublicKeyInfo structure --nmav
|
||||
*/
|
||||
|
||||
#ifdef LTC_DER
|
||||
|
||||
/* AlgorithmIdentifier := SEQUENCE {
|
||||
* algorithm OBJECT IDENTIFIER,
|
||||
* parameters ANY DEFINED BY algorithm
|
||||
* }
|
||||
*
|
||||
* SubjectPublicKeyInfo := SEQUENCE {
|
||||
* algorithm AlgorithmIdentifier,
|
||||
* subjectPublicKey BIT STRING
|
||||
* }
|
||||
*/
|
||||
/**
|
||||
Encode a SubjectPublicKeyInfo
|
||||
@param out The output buffer
|
||||
@param outlen [in/out] Length of buffer and resulting length of output
|
||||
@param algorithm One out of the enum #public_key_algorithms
|
||||
@param public_key The buffer for the public key
|
||||
@param public_key_len The length of the public key buffer
|
||||
@param parameters_type The parameters' type out of the enum ltc_asn1_type
|
||||
@param parameters The parameters to include
|
||||
@param parameters_len The number of parameters to include
|
||||
@return CRYPT_OK on success
|
||||
*/
|
||||
int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen,
|
||||
enum ltc_oid_id algorithm, const void* public_key, unsigned long public_key_len,
|
||||
ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_list alg_id[2];
|
||||
const char *OID;
|
||||
unsigned long oid[16], oidlen;
|
||||
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
if ((err = pk_get_oid(algorithm, &OID)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
oidlen = sizeof(oid)/sizeof(oid[0]);
|
||||
if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
|
||||
LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len);
|
||||
|
||||
return der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id,
|
||||
LTC_ASN1_RAW_BIT_STRING, public_key_len*8U, public_key,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
248
Sources/DataLiteC/libtomcrypt/pk/dh/dh.c
Normal file
248
Sources/DataLiteC/libtomcrypt/pk/dh/dh.c
Normal file
@@ -0,0 +1,248 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
/* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */
|
||||
const ltc_dh_set_type ltc_dh_sets[] = {
|
||||
#ifdef LTC_DH768
|
||||
{ /* 768-bit MODP Group 1 - https://tools.ietf.org/html/rfc7296#appendix-B.1 */
|
||||
96,
|
||||
"DH-768",
|
||||
"2",
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
|
||||
"E485B576625E7EC6F44C42E9A63A3620FFFFFFFFFFFFFFFF"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_DH1024
|
||||
{ /* 1024-bit MODP Group 2 - https://tools.ietf.org/html/rfc7296#appendix-B.2 */
|
||||
128,
|
||||
"DH-1024",
|
||||
"2",
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381"
|
||||
"FFFFFFFFFFFFFFFF"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_DH1536
|
||||
{ /* 1536-bit MODP Group 5 - https://tools.ietf.org/html/rfc3526#section-2 */
|
||||
192,
|
||||
"DH-1536",
|
||||
"2",
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D"
|
||||
"670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_DH2048
|
||||
{ /* 2048-bit MODP Group 14 - https://tools.ietf.org/html/rfc3526#section-3 */
|
||||
256,
|
||||
"DH-2048",
|
||||
"2",
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D"
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
|
||||
"15728E5A8AACAA68FFFFFFFFFFFFFFFF"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_DH3072
|
||||
{ /* 3072-bit MODP Group 15 - https://tools.ietf.org/html/rfc3526#section-4 */
|
||||
384,
|
||||
"DH-3072",
|
||||
"2",
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D"
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
|
||||
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
|
||||
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
|
||||
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
|
||||
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
|
||||
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
|
||||
"43DB5BFCE0FD108E4B82D120A93AD2CAFFFFFFFFFFFFFFFF"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_DH4096
|
||||
{ /* 4096-bit MODP Group 16 - https://tools.ietf.org/html/rfc3526#section-5 */
|
||||
512,
|
||||
"DH-4096",
|
||||
"2",
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D"
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
|
||||
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
|
||||
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
|
||||
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
|
||||
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
|
||||
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
|
||||
"43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
|
||||
"88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
|
||||
"2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
|
||||
"287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
|
||||
"1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
|
||||
"93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934063199"
|
||||
"FFFFFFFFFFFFFFFF"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_DH6144
|
||||
{ /* 6144-bit MODP Group 17 - https://tools.ietf.org/html/rfc3526#section-6 */
|
||||
768,
|
||||
"DH-6144",
|
||||
"2",
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D"
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
|
||||
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
|
||||
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
|
||||
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
|
||||
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
|
||||
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
|
||||
"43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
|
||||
"88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
|
||||
"2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
|
||||
"287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
|
||||
"1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
|
||||
"93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
|
||||
"36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
|
||||
"F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
|
||||
"179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
|
||||
"DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
|
||||
"5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
|
||||
"D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
|
||||
"23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
|
||||
"CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
|
||||
"06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
|
||||
"DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
|
||||
"12BF2D5B0B7474D6E694F91E6DCC4024FFFFFFFFFFFFFFFF"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_DH8192
|
||||
{ /* 8192-bit MODP Group 18 - https://tools.ietf.org/html/rfc3526#section-7 */
|
||||
1024,
|
||||
"DH-8192",
|
||||
"2",
|
||||
"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1"
|
||||
"29024E088A67CC74020BBEA63B139B22514A08798E3404DD"
|
||||
"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245"
|
||||
"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED"
|
||||
"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D"
|
||||
"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F"
|
||||
"83655D23DCA3AD961C62F356208552BB9ED529077096966D"
|
||||
"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B"
|
||||
"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9"
|
||||
"DE2BCBF6955817183995497CEA956AE515D2261898FA0510"
|
||||
"15728E5A8AAAC42DAD33170D04507A33A85521ABDF1CBA64"
|
||||
"ECFB850458DBEF0A8AEA71575D060C7DB3970F85A6E1E4C7"
|
||||
"ABF5AE8CDB0933D71E8C94E04A25619DCEE3D2261AD2EE6B"
|
||||
"F12FFA06D98A0864D87602733EC86A64521F2B18177B200C"
|
||||
"BBE117577A615D6C770988C0BAD946E208E24FA074E5AB31"
|
||||
"43DB5BFCE0FD108E4B82D120A92108011A723C12A787E6D7"
|
||||
"88719A10BDBA5B2699C327186AF4E23C1A946834B6150BDA"
|
||||
"2583E9CA2AD44CE8DBBBC2DB04DE8EF92E8EFC141FBECAA6"
|
||||
"287C59474E6BC05D99B2964FA090C3A2233BA186515BE7ED"
|
||||
"1F612970CEE2D7AFB81BDD762170481CD0069127D5B05AA9"
|
||||
"93B4EA988D8FDDC186FFB7DC90A6C08F4DF435C934028492"
|
||||
"36C3FAB4D27C7026C1D4DCB2602646DEC9751E763DBA37BD"
|
||||
"F8FF9406AD9E530EE5DB382F413001AEB06A53ED9027D831"
|
||||
"179727B0865A8918DA3EDBEBCF9B14ED44CE6CBACED4BB1B"
|
||||
"DB7F1447E6CC254B332051512BD7AF426FB8F401378CD2BF"
|
||||
"5983CA01C64B92ECF032EA15D1721D03F482D7CE6E74FEF6"
|
||||
"D55E702F46980C82B5A84031900B1C9E59E7C97FBEC7E8F3"
|
||||
"23A97A7E36CC88BE0F1D45B7FF585AC54BD407B22B4154AA"
|
||||
"CC8F6D7EBF48E1D814CC5ED20F8037E0A79715EEF29BE328"
|
||||
"06A1D58BB7C5DA76F550AA3D8A1FBFF0EB19CCB1A313D55C"
|
||||
"DA56C9EC2EF29632387FE8D76E3C0468043E8F663F4860EE"
|
||||
"12BF2D5B0B7474D6E694F91E6DBE115974A3926F12FEE5E4"
|
||||
"38777CB6A932DF8CD8BEC4D073B931BA3BC832B68D9DD300"
|
||||
"741FA7BF8AFC47ED2576F6936BA424663AAB639C5AE4F568"
|
||||
"3423B4742BF1C978238F16CBE39D652DE3FDB8BEFC848AD9"
|
||||
"22222E04A4037C0713EB57A81A23F0C73473FC646CEA306B"
|
||||
"4BCBC8862F8385DDFA9D4B7FA2C087E879683303ED5BDD3A"
|
||||
"062B3CF5B3A278A66D2A13F83F44F82DDF310EE074AB6A36"
|
||||
"4597E899A0255DC164F31CC50846851DF9AB48195DED7EA1"
|
||||
"B1D510BD7EE74D73FAF36BC31ECFA268359046F4EB879F92"
|
||||
"4009438B481C6CD7889A002ED5EE382BC9190DA6FC026E47"
|
||||
"9558E4475677E9AA9E3050E2765694DFC81F56E880B96E71"
|
||||
"60C980DD98EDD3DFFFFFFFFFFFFFFFFF"
|
||||
},
|
||||
#endif
|
||||
{
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
Returns the DH group size (octets) for given key
|
||||
@param key The DH key to get the size of
|
||||
@return The group size in octets (0 on error)
|
||||
*/
|
||||
int dh_get_groupsize(const dh_key *key)
|
||||
{
|
||||
if (key == NULL) return 0;
|
||||
return ltc_mp_unsigned_bin_size(key->prime);
|
||||
}
|
||||
|
||||
/**
|
||||
Init a DH key
|
||||
@param key The DH key to initialize
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dh_init(dh_key *key)
|
||||
{
|
||||
int err;
|
||||
LTC_ARGCHK(key != NULL);
|
||||
if ((err = ltc_mp_init_multi(&key->x, &key->y, &key->base, &key->prime, LTC_NULL)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
55
Sources/DataLiteC/libtomcrypt/pk/dh/dh_check_pubkey.c
Normal file
55
Sources/DataLiteC/libtomcrypt/pk/dh/dh_check_pubkey.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
/**
|
||||
Check DH public key (INTERNAL ONLY, not part of public API)
|
||||
@param key The key you wish to test
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dh_check_pubkey(const dh_key *key)
|
||||
{
|
||||
void *p_minus1;
|
||||
ltc_mp_digit digit;
|
||||
int i, digit_count, bits_set = 0, err;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
if ((err = ltc_mp_init(&p_minus1)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* avoid: y <= 1 OR y >= p-1 */
|
||||
if ((err = ltc_mp_sub_d(key->prime, 1, p_minus1)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
if (ltc_mp_cmp(key->y, p_minus1) != LTC_MP_LT || ltc_mp_cmp_d(key->y, 1) != LTC_MP_GT) {
|
||||
err = CRYPT_INVALID_ARG;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* public key must have more than one bit set */
|
||||
digit_count = ltc_mp_get_digit_count(key->y);
|
||||
for (i = 0; i < digit_count && bits_set < 2; i++) {
|
||||
digit = ltc_mp_get_digit(key->y, i);
|
||||
while (digit > 0) {
|
||||
if (digit & 1) bits_set++;
|
||||
digit >>= 1;
|
||||
}
|
||||
}
|
||||
if (bits_set > 1) {
|
||||
err = CRYPT_OK;
|
||||
}
|
||||
else {
|
||||
err = CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
error:
|
||||
ltc_mp_clear(p_minus1);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
52
Sources/DataLiteC/libtomcrypt/pk/dh/dh_export.c
Normal file
52
Sources/DataLiteC/libtomcrypt/pk/dh/dh_export.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
/**
|
||||
Export a DH key to a binary packet
|
||||
@param out [out] The destination for the key
|
||||
@param outlen [in/out] The max size and resulting size of the DH key
|
||||
@param type Which type of key (PK_PRIVATE or PK_PUBLIC)
|
||||
@param key The key you wish to export
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dh_export(unsigned char *out, unsigned long *outlen, int type, const dh_key *key)
|
||||
{
|
||||
unsigned char flags[1];
|
||||
int err;
|
||||
unsigned long version = 0;
|
||||
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
if (type == PK_PRIVATE) {
|
||||
/* export x - private key */
|
||||
flags[0] = 1;
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &version,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_INTEGER, 1UL, key->prime,
|
||||
LTC_ASN1_INTEGER, 1UL, key->base,
|
||||
LTC_ASN1_INTEGER, 1UL, key->x,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
}
|
||||
else {
|
||||
/* export y - public key */
|
||||
flags[0] = 0;
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &version,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_INTEGER, 1UL, key->prime,
|
||||
LTC_ASN1_INTEGER, 1UL, key->base,
|
||||
LTC_ASN1_INTEGER, 1UL, key->y,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
37
Sources/DataLiteC/libtomcrypt/pk/dh/dh_export_key.c
Normal file
37
Sources/DataLiteC/libtomcrypt/pk/dh/dh_export_key.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
/**
|
||||
Binary export a DH key to a buffer
|
||||
@param out [out] The destination for the key
|
||||
@param outlen [in/out] The max size and resulting size of the DH key
|
||||
@param type Which type of key (PK_PRIVATE or PK_PUBLIC)
|
||||
@param key The key you wish to export
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dh_export_key(void *out, unsigned long *outlen, int type, const dh_key *key)
|
||||
{
|
||||
unsigned long len;
|
||||
void *k;
|
||||
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
k = (type == PK_PRIVATE) ? key->x : key->y;
|
||||
len = ltc_mp_unsigned_bin_size(k);
|
||||
|
||||
if (*outlen < len) {
|
||||
*outlen = len;
|
||||
return CRYPT_BUFFER_OVERFLOW;
|
||||
}
|
||||
*outlen = len;
|
||||
|
||||
return ltc_mp_to_unsigned_bin(k, out);
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
18
Sources/DataLiteC/libtomcrypt/pk/dh/dh_free.c
Normal file
18
Sources/DataLiteC/libtomcrypt/pk/dh/dh_free.c
Normal file
@@ -0,0 +1,18 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
/**
|
||||
Free the allocated ram for a DH key
|
||||
@param key The key which you wish to free
|
||||
*/
|
||||
void dh_free(dh_key *key)
|
||||
{
|
||||
LTC_ARGCHKVD(key != NULL);
|
||||
ltc_mp_cleanup_multi(&key->prime, &key->base, &key->y, &key->x, LTC_NULL);
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
96
Sources/DataLiteC/libtomcrypt/pk/dh/dh_generate_key.c
Normal file
96
Sources/DataLiteC/libtomcrypt/pk/dh/dh_generate_key.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
static int s_dh_groupsize_to_keysize(int groupsize)
|
||||
{
|
||||
/* The strength estimates from https://tools.ietf.org/html/rfc3526#section-8
|
||||
* We use "Estimate 2" to get an appropriate private key (exponent) size.
|
||||
*/
|
||||
if (groupsize <= 0) {
|
||||
return 0;
|
||||
}
|
||||
if (groupsize <= 192) {
|
||||
return 30; /* 1536-bit => key size 240-bit */
|
||||
}
|
||||
if (groupsize <= 256) {
|
||||
return 40; /* 2048-bit => key size 320-bit */
|
||||
}
|
||||
if (groupsize <= 384) {
|
||||
return 52; /* 3072-bit => key size 416-bit */
|
||||
}
|
||||
if (groupsize <= 512) {
|
||||
return 60; /* 4096-bit => key size 480-bit */
|
||||
}
|
||||
if (groupsize <= 768) {
|
||||
return 67; /* 6144-bit => key size 536-bit */
|
||||
}
|
||||
if (groupsize <= 1024) {
|
||||
return 77; /* 8192-bit => key size 616-bit */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dh_generate_key(prng_state *prng, int wprng, dh_key *key)
|
||||
{
|
||||
unsigned char *buf;
|
||||
unsigned long keysize;
|
||||
int err, max_iterations = LTC_PK_MAX_RETRIES;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
/* good prng? */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
keysize = s_dh_groupsize_to_keysize(ltc_mp_unsigned_bin_size(key->prime));
|
||||
if (keysize == 0) {
|
||||
err = CRYPT_INVALID_KEYSIZE;
|
||||
goto freemp;
|
||||
}
|
||||
|
||||
/* allocate buffer */
|
||||
buf = XMALLOC(keysize);
|
||||
if (buf == NULL) {
|
||||
err = CRYPT_MEM;
|
||||
goto freemp;
|
||||
}
|
||||
|
||||
key->type = PK_PRIVATE;
|
||||
do {
|
||||
/* make up random buf */
|
||||
if (prng_descriptor[wprng].read(buf, keysize, prng) != keysize) {
|
||||
err = CRYPT_ERROR_READPRNG;
|
||||
goto freebuf;
|
||||
}
|
||||
/* load the x value - private key */
|
||||
if ((err = ltc_mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) {
|
||||
goto freebuf;
|
||||
}
|
||||
/* compute the y value - public key */
|
||||
if ((err = ltc_mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) {
|
||||
goto freebuf;
|
||||
}
|
||||
err = dh_check_pubkey(key);
|
||||
} while (err != CRYPT_OK && max_iterations-- > 0);
|
||||
|
||||
freebuf:
|
||||
zeromem(buf, keysize);
|
||||
XFREE(buf);
|
||||
freemp:
|
||||
if (err != CRYPT_OK) dh_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
89
Sources/DataLiteC/libtomcrypt/pk/dh/dh_import.c
Normal file
89
Sources/DataLiteC/libtomcrypt/pk/dh/dh_import.c
Normal file
@@ -0,0 +1,89 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
/**
|
||||
Import a DH key from a binary packet
|
||||
@param in The packet to read
|
||||
@param inlen The length of the input packet
|
||||
@param key [out] Where to import the key to
|
||||
@return CRYPT_OK if successful, on error all allocated memory is freed automatically
|
||||
*/
|
||||
int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
|
||||
{
|
||||
unsigned char flags[1];
|
||||
int err;
|
||||
unsigned long version;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* init */
|
||||
if ((err = dh_init(key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* find out what type of key it is */
|
||||
err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &version,
|
||||
LTC_ASN1_BIT_STRING, 1UL, &flags,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (version == 0) {
|
||||
if (flags[0] == 1) {
|
||||
key->type = PK_PRIVATE;
|
||||
if ((err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &version,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_INTEGER, 1UL, key->prime,
|
||||
LTC_ASN1_INTEGER, 1UL, key->base,
|
||||
LTC_ASN1_INTEGER, 1UL, key->x,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
/* compute public key: y = (base ^ x) mod prime */
|
||||
if ((err = ltc_mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else if (flags[0] == 0) {
|
||||
key->type = PK_PUBLIC;
|
||||
if ((err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &version,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_INTEGER, 1UL, key->prime,
|
||||
LTC_ASN1_INTEGER, 1UL, key->base,
|
||||
LTC_ASN1_INTEGER, 1UL, key->y,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* check public key */
|
||||
if ((err = dh_check_pubkey(key)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
error:
|
||||
dh_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
87
Sources/DataLiteC/libtomcrypt/pk/dh/dh_import_pkcs8.c
Normal file
87
Sources/DataLiteC/libtomcrypt/pk/dh/dh_import_pkcs8.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
int dh_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dh_key *key)
|
||||
{
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
if (!alg_id->child ||
|
||||
!LTC_ASN1_IS_TYPE(alg_id->child->next, LTC_ASN1_SEQUENCE) ||
|
||||
!LTC_ASN1_IS_TYPE(alg_id->child->next->child, LTC_ASN1_INTEGER) ||
|
||||
!LTC_ASN1_IS_TYPE(alg_id->child->next->child->next, LTC_ASN1_INTEGER)) {
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
if ((err = dh_init(key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = ltc_mp_copy(alg_id->child->next->child->data, key->prime)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
if ((err = ltc_mp_copy(alg_id->child->next->child->next->data, key->base)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((err = der_decode_integer(priv_key->data, priv_key->size, key->x)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
/* compute public key: y = (base ^ x) mod prime */
|
||||
if ((err = ltc_mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
/* check public key */
|
||||
if ((err = dh_check_pubkey(key)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
key->type = PK_PRIVATE;
|
||||
|
||||
return CRYPT_OK;
|
||||
error:
|
||||
dh_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Import a DH key in PKCS#8 format
|
||||
@param in The packet to import from
|
||||
@param inlen It's length (octets)
|
||||
@param pw_ctx The password context when decrypting the private key
|
||||
@param key [out] Destination for newly imported key
|
||||
@return CRYPT_OK if successful, on error all allocated memory is freed automatically
|
||||
*/
|
||||
int dh_import_pkcs8(const unsigned char *in, unsigned long inlen,
|
||||
const password_ctx *pw_ctx, dh_key *key)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_list *l = NULL;
|
||||
ltc_asn1_list *alg_id, *priv_key;
|
||||
enum ltc_oid_id pka;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
if ((err = pkcs8_decode_flexi(in, inlen, pw_ctx, &l)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = pkcs8_get_children(l, &pka, &alg_id, &priv_key)) != CRYPT_OK) {
|
||||
goto LBL_DER_FREE;
|
||||
}
|
||||
if (pka != LTC_OID_DH) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_DER_FREE;
|
||||
}
|
||||
|
||||
err = dh_import_pkcs8_asn1(alg_id, priv_key, key);
|
||||
|
||||
LBL_DER_FREE:
|
||||
der_free_sequence_flexi(l);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
115
Sources/DataLiteC/libtomcrypt/pk/dh/dh_set.c
Normal file
115
Sources/DataLiteC/libtomcrypt/pk/dh/dh_set.c
Normal file
@@ -0,0 +1,115 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
/**
|
||||
Import DH key parts p and g from raw numbers
|
||||
|
||||
@param p DH's p (prime)
|
||||
@param plen DH's p's length
|
||||
@param g DH's g (group)
|
||||
@param glen DH's g's length
|
||||
@param key [out] the destination for the imported key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dh_set_pg(const unsigned char *p, unsigned long plen,
|
||||
const unsigned char *g, unsigned long glen,
|
||||
dh_key *key)
|
||||
{
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(p != NULL);
|
||||
LTC_ARGCHK(g != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
if ((err = dh_init(key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = ltc_mp_read_unsigned_bin(key->base, (unsigned char*)g, glen)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
if ((err = ltc_mp_read_unsigned_bin(key->prime, (unsigned char*)p, plen)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
dh_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Import DH key parts p and g from built-in DH groups
|
||||
|
||||
@param groupsize The size of the DH group to use
|
||||
@param key [out] Where the newly created DH key will be stored
|
||||
@return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically.
|
||||
*/
|
||||
int dh_set_pg_groupsize(int groupsize, dh_key *key)
|
||||
{
|
||||
int err, i;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
LTC_ARGCHK(groupsize > 0);
|
||||
|
||||
for (i = 0; (groupsize > ltc_dh_sets[i].size) && (ltc_dh_sets[i].size != 0); i++);
|
||||
if (ltc_dh_sets[i].size == 0) return CRYPT_INVALID_KEYSIZE;
|
||||
|
||||
if ((err = dh_init(key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = ltc_mp_read_radix(key->base, ltc_dh_sets[i].base, 16)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
if ((err = ltc_mp_read_radix(key->prime, ltc_dh_sets[i].prime, 16)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
dh_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Import DH public or private key part from raw numbers
|
||||
|
||||
NB: The p & g parts must be set beforehand
|
||||
|
||||
@param in The key-part to import, either public or private.
|
||||
@param inlen The key-part's length
|
||||
@param type Which type of key (PK_PRIVATE or PK_PUBLIC)
|
||||
@param key [out] the destination for the imported key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dh_set_key(const unsigned char *in, unsigned long inlen, int type, dh_key *key)
|
||||
{
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
if (type == PK_PRIVATE) {
|
||||
key->type = PK_PRIVATE;
|
||||
if ((err = ltc_mp_read_unsigned_bin(key->x, (unsigned char*)in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
if ((err = ltc_mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
}
|
||||
else {
|
||||
key->type = PK_PUBLIC;
|
||||
if ((err = ltc_mp_read_unsigned_bin(key->y, (unsigned char*)in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
}
|
||||
|
||||
/* check public key */
|
||||
if ((err = dh_check_pubkey(key)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
dh_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
44
Sources/DataLiteC/libtomcrypt/pk/dh/dh_set_pg_dhparam.c
Normal file
44
Sources/DataLiteC/libtomcrypt/pk/dh/dh_set_pg_dhparam.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
/**
|
||||
Import DH key parts p and g from dhparam
|
||||
|
||||
dhparam data: openssl dhparam -outform DER -out dhparam.der 2048
|
||||
|
||||
@param dhparam The DH param DER encoded data
|
||||
@param dhparamlen The length of dhparam data
|
||||
@param key [out] Where the newly created DH key will be stored
|
||||
@return CRYPT_OK if successful, note: on error all allocated memory will be freed automatically.
|
||||
*/
|
||||
int dh_set_pg_dhparam(const unsigned char *dhparam, unsigned long dhparamlen, dh_key *key)
|
||||
{
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
LTC_ARGCHK(dhparam != NULL);
|
||||
LTC_ARGCHK(dhparamlen > 0);
|
||||
|
||||
if ((err = dh_init(key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = der_decode_sequence_multi(dhparam, dhparamlen,
|
||||
LTC_ASN1_INTEGER, 1UL, key->prime,
|
||||
LTC_ASN1_INTEGER, 1UL, key->base,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
dh_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
70
Sources/DataLiteC/libtomcrypt/pk/dh/dh_shared_secret.c
Normal file
70
Sources/DataLiteC/libtomcrypt/pk/dh/dh_shared_secret.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#ifdef LTC_MDH
|
||||
|
||||
/**
|
||||
Create a DH shared secret.
|
||||
@param private_key The private DH key in the pair
|
||||
@param public_key The public DH key in the pair
|
||||
@param out [out] The destination of the shared data
|
||||
@param outlen [in/out] The max size and resulting size of the shared data.
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dh_shared_secret(const dh_key *private_key, const dh_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
void *tmp;
|
||||
unsigned long x;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(private_key != NULL);
|
||||
LTC_ARGCHK(public_key != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* types valid? */
|
||||
if (private_key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* same DH group? */
|
||||
if (ltc_mp_cmp(private_key->prime, public_key->prime) != LTC_MP_EQ) { return CRYPT_PK_TYPE_MISMATCH; }
|
||||
if (ltc_mp_cmp(private_key->base, public_key->base) != LTC_MP_EQ) { return CRYPT_PK_TYPE_MISMATCH; }
|
||||
|
||||
/* init big numbers */
|
||||
if ((err = ltc_mp_init(&tmp)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* check public key */
|
||||
if ((err = dh_check_pubkey(public_key)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* compute tmp = y^x mod p */
|
||||
if ((err = ltc_mp_exptmod(public_key->y, private_key->x, private_key->prime, tmp)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* enough space for output? */
|
||||
x = (unsigned long)ltc_mp_unsigned_bin_size(tmp);
|
||||
if (*outlen < x) {
|
||||
*outlen = x;
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto error;
|
||||
}
|
||||
if ((err = ltc_mp_to_unsigned_bin(tmp, out)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
*outlen = x;
|
||||
err = CRYPT_OK;
|
||||
|
||||
error:
|
||||
ltc_mp_clear(tmp);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_MDH */
|
||||
129
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_decrypt_key.c
Normal file
129
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_decrypt_key.c
Normal file
@@ -0,0 +1,129 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file dsa_decrypt_key.c
|
||||
DSA Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Decrypt an DSA encrypted key
|
||||
@param in The ciphertext
|
||||
@param inlen The length of the ciphertext (octets)
|
||||
@param out [out] The plaintext
|
||||
@param outlen [in/out] The max size and resulting size of the plaintext
|
||||
@param key The corresponding private DSA key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_decrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
const dsa_key *key)
|
||||
{
|
||||
unsigned char *skey, *expt;
|
||||
void *g_pub;
|
||||
unsigned long x, y;
|
||||
unsigned long hashOID[32] = { 0 };
|
||||
int hash, err;
|
||||
ltc_asn1_list decode[3];
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* right key type? */
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* decode to find out hash */
|
||||
LTC_SET_ASN1(decode, 0, LTC_ASN1_OBJECT_IDENTIFIER, hashOID, sizeof(hashOID)/sizeof(hashOID[0]));
|
||||
err = der_decode_sequence(in, inlen, decode, 1);
|
||||
if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
|
||||
return err;
|
||||
}
|
||||
|
||||
hash = find_hash_oid(hashOID, decode[0].size);
|
||||
if (hash_is_valid(hash) != CRYPT_OK) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
|
||||
/* we now have the hash! */
|
||||
|
||||
if ((err = ltc_mp_init(&g_pub)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* allocate memory */
|
||||
expt = XMALLOC(ltc_mp_unsigned_bin_size(key->p) + 1);
|
||||
skey = XMALLOC(MAXBLOCKSIZE);
|
||||
if (expt == NULL || skey == NULL) {
|
||||
if (expt != NULL) {
|
||||
XFREE(expt);
|
||||
}
|
||||
if (skey != NULL) {
|
||||
XFREE(skey);
|
||||
}
|
||||
ltc_mp_clear(g_pub);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
LTC_SET_ASN1(decode, 1, LTC_ASN1_INTEGER, g_pub, 1UL);
|
||||
LTC_SET_ASN1(decode, 2, LTC_ASN1_OCTET_STRING, skey, MAXBLOCKSIZE);
|
||||
|
||||
/* read the structure in now */
|
||||
if ((err = der_decode_sequence(in, inlen, decode, 3)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* make shared key */
|
||||
x = ltc_mp_unsigned_bin_size(key->p) + 1;
|
||||
if ((err = dsa_shared_secret(key->x, g_pub, key, expt, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
y = ltc_mp_unsigned_bin_size(key->p) + 1;
|
||||
y = MIN(y, MAXBLOCKSIZE);
|
||||
if ((err = hash_memory(hash, expt, x, expt, &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* ensure the hash of the shared secret is at least as big as the encrypt itself */
|
||||
if (decode[2].size > y) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* avoid buffer overflow */
|
||||
if (*outlen < decode[2].size) {
|
||||
*outlen = decode[2].size;
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* Decrypt the key */
|
||||
for (x = 0; x < decode[2].size; x++) {
|
||||
out[x] = expt[x] ^ skey[x];
|
||||
}
|
||||
*outlen = x;
|
||||
|
||||
err = CRYPT_OK;
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(expt, ltc_mp_unsigned_bin_size(key->p) + 1);
|
||||
zeromem(skey, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(expt);
|
||||
XFREE(skey);
|
||||
|
||||
ltc_mp_clear(g_pub);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
118
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_encrypt_key.c
Normal file
118
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_encrypt_key.c
Normal file
@@ -0,0 +1,118 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file dsa_encrypt_key.c
|
||||
DSA Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Encrypt a symmetric key with DSA
|
||||
@param in The symmetric key you want to encrypt
|
||||
@param inlen The length of the key to encrypt (octets)
|
||||
@param out [out] The destination for the ciphertext
|
||||
@param outlen [in/out] The max size and resulting size of the ciphertext
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG you wish to use
|
||||
@param hash The index of the hash you want to use
|
||||
@param key The DSA key you want to encrypt to
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, int hash,
|
||||
const dsa_key *key)
|
||||
{
|
||||
unsigned char *expt, *skey;
|
||||
void *g_pub, *g_priv;
|
||||
unsigned long x, y;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* check that wprng/cipher/hash are not invalid */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (inlen > hash_descriptor[hash].hashsize) {
|
||||
return CRYPT_INVALID_HASH;
|
||||
}
|
||||
|
||||
/* make a random key and export the public copy */
|
||||
if ((err = ltc_mp_init_multi(&g_pub, &g_priv, LTC_NULL)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
expt = XMALLOC(ltc_mp_unsigned_bin_size(key->p) + 1);
|
||||
skey = XMALLOC(MAXBLOCKSIZE);
|
||||
if (expt == NULL || skey == NULL) {
|
||||
if (expt != NULL) {
|
||||
XFREE(expt);
|
||||
}
|
||||
if (skey != NULL) {
|
||||
XFREE(skey);
|
||||
}
|
||||
ltc_mp_deinit_multi(g_pub, g_priv, LTC_NULL);
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* make a random g_priv, g_pub = g^x pair
|
||||
private key x should be in range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2)
|
||||
*/
|
||||
if ((err = rand_bn_upto(g_priv, key->q, prng, wprng)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* compute y */
|
||||
if ((err = ltc_mp_exptmod(key->g, g_priv, key->p, g_pub)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* make random key */
|
||||
x = ltc_mp_unsigned_bin_size(key->p) + 1;
|
||||
if ((err = dsa_shared_secret(g_priv, key->y, key, expt, &x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
y = MAXBLOCKSIZE;
|
||||
if ((err = hash_memory(hash, expt, x, skey, &y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* Encrypt key */
|
||||
for (x = 0; x < inlen; x++) {
|
||||
skey[x] ^= in[x];
|
||||
}
|
||||
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_OBJECT_IDENTIFIER, hash_descriptor[hash].OIDlen, hash_descriptor[hash].OID,
|
||||
LTC_ASN1_INTEGER, 1UL, g_pub,
|
||||
LTC_ASN1_OCTET_STRING, inlen, skey,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
|
||||
LBL_ERR:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
/* clean up */
|
||||
zeromem(expt, ltc_mp_unsigned_bin_size(key->p) + 1);
|
||||
zeromem(skey, MAXBLOCKSIZE);
|
||||
#endif
|
||||
|
||||
XFREE(skey);
|
||||
XFREE(expt);
|
||||
|
||||
ltc_mp_deinit_multi(g_pub, g_priv, LTC_NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
100
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_export.c
Normal file
100
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_export.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file dsa_export.c
|
||||
DSA implementation, export key, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Export a DSA key to a binary packet
|
||||
@param out [out] Where to store the packet
|
||||
@param outlen [in/out] The max size and resulting size of the packet
|
||||
@param type The type of key to export (PK_PRIVATE or PK_PUBLIC)
|
||||
@param key The key to export
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_export(unsigned char *out, unsigned long *outlen, int type, const dsa_key *key)
|
||||
{
|
||||
unsigned long zero=0;
|
||||
unsigned char flags[1];
|
||||
int err, std;
|
||||
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
std = type & PK_STD;
|
||||
type &= ~PK_STD;
|
||||
|
||||
if (type == PK_PRIVATE && key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_TYPE_MISMATCH;
|
||||
}
|
||||
|
||||
if (type == PK_PRIVATE) {
|
||||
if (std) {
|
||||
return der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
|
||||
LTC_ASN1_INTEGER, 1UL, key->p,
|
||||
LTC_ASN1_INTEGER, 1UL, key->q,
|
||||
LTC_ASN1_INTEGER, 1UL, key->g,
|
||||
LTC_ASN1_INTEGER, 1UL, key->y,
|
||||
LTC_ASN1_INTEGER, 1UL, key->x,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
}
|
||||
flags[0] = 1;
|
||||
return der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_INTEGER, 1UL, key->g,
|
||||
LTC_ASN1_INTEGER, 1UL, key->p,
|
||||
LTC_ASN1_INTEGER, 1UL, key->q,
|
||||
LTC_ASN1_INTEGER, 1UL, key->y,
|
||||
LTC_ASN1_INTEGER, 1UL, key->x,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
}
|
||||
|
||||
if (type == PK_PUBLIC) {
|
||||
if (std) {
|
||||
unsigned long tmplen = (unsigned long)(ltc_mp_count_bits(key->y) / 8) + 8;
|
||||
unsigned char* tmp = XMALLOC(tmplen);
|
||||
ltc_asn1_list int_list[3];
|
||||
|
||||
if (tmp == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
err = der_encode_integer(key->y, tmp, &tmplen);
|
||||
if (err != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
LTC_SET_ASN1(int_list, 0, LTC_ASN1_INTEGER, key->p, 1UL);
|
||||
LTC_SET_ASN1(int_list, 1, LTC_ASN1_INTEGER, key->q, 1UL);
|
||||
LTC_SET_ASN1(int_list, 2, LTC_ASN1_INTEGER, key->g, 1UL);
|
||||
|
||||
err = x509_encode_subject_public_key_info(out, outlen, LTC_OID_DSA, tmp,
|
||||
tmplen, LTC_ASN1_SEQUENCE, int_list,
|
||||
sizeof(int_list) / sizeof(int_list[0]));
|
||||
|
||||
error:
|
||||
XFREE(tmp);
|
||||
return err;
|
||||
}
|
||||
flags[0] = 0;
|
||||
return der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_INTEGER, 1UL, key->g,
|
||||
LTC_ASN1_INTEGER, 1UL, key->p,
|
||||
LTC_ASN1_INTEGER, 1UL, key->q,
|
||||
LTC_ASN1_INTEGER, 1UL, key->y,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
}
|
||||
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
23
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_free.c
Normal file
23
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_free.c
Normal file
@@ -0,0 +1,23 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file dsa_free.c
|
||||
DSA implementation, free a DSA key, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Free a DSA key
|
||||
@param key The key to free from memory
|
||||
*/
|
||||
void dsa_free(dsa_key *key)
|
||||
{
|
||||
LTC_ARGCHKVD(key != NULL);
|
||||
ltc_mp_cleanup_multi(&key->y, &key->x, &key->q, &key->g, &key->p, LTC_NULL);
|
||||
key->type = key->qord = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
37
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_generate_key.c
Normal file
37
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_generate_key.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file dsa_make_key.c
|
||||
DSA implementation, generate a DSA key
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Create a DSA key
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG desired
|
||||
@param key [in/out] Where to store the created key
|
||||
@return CRYPT_OK if successful.
|
||||
*/
|
||||
int dsa_generate_key(prng_state *prng, int wprng, dsa_key *key)
|
||||
{
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
/* so now we have our DH structure, generator g, order q, modulus p
|
||||
Now we need a random exponent [mod q] and it's power g^x mod p
|
||||
*/
|
||||
/* private key x should be from range: 1 <= x <= q-1 (see FIPS 186-4 B.1.2) */
|
||||
if ((err = rand_bn_upto(key->x, key->q, prng, wprng)) != CRYPT_OK) { return err; }
|
||||
if ((err = ltc_mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { return err; }
|
||||
key->type = PK_PRIVATE;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
235
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_generate_pqg.c
Normal file
235
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_generate_pqg.c
Normal file
@@ -0,0 +1,235 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@file dsa_generate_pqg.c
|
||||
DSA implementation - generate DSA parameters p, q & g
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Create DSA parameters (INTERNAL ONLY, not part of public API)
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG desired
|
||||
@param group_size Size of the multiplicative group (octets)
|
||||
@param modulus_size Size of the modulus (octets)
|
||||
@param p [out] bignum where generated 'p' is stored (must be initialized by caller)
|
||||
@param q [out] bignum where generated 'q' is stored (must be initialized by caller)
|
||||
@param g [out] bignum where generated 'g' is stored (must be initialized by caller)
|
||||
@return CRYPT_OK if successful, upon error this function will free all allocated memory
|
||||
*/
|
||||
static int s_dsa_make_params(prng_state *prng, int wprng, int group_size, int modulus_size, void *p, void *q, void *g)
|
||||
{
|
||||
unsigned long L, N, n, outbytes, seedbytes, counter, j, i;
|
||||
int err, res, mr_tests_q, mr_tests_p, found_p, found_q, hash;
|
||||
unsigned char *wbuf, *sbuf, digest[MAXBLOCKSIZE];
|
||||
void *t2L1, *t2N1, *t2q, *t2seedlen, *U, *W, *X, *c, *h, *e, *seedinc;
|
||||
const char *accepted_hashes[] = { "sha3-512", "sha512", "sha3-384", "sha384", "sha3-256", "sha256" };
|
||||
|
||||
/* check size */
|
||||
if (group_size > LTC_MDSA_MAX_GROUP || group_size < 1 || group_size >= modulus_size || modulus_size > LTC_MDSA_MAX_MODULUS) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
/* FIPS-186-4 A.1.1.2 Generation of the Probable Primes p and q Using an Approved Hash Function
|
||||
*
|
||||
* L = The desired length of the prime p (in bits e.g. L = 1024)
|
||||
* N = The desired length of the prime q (in bits e.g. N = 160)
|
||||
* seedlen = The desired bit length of the domain parameter seed; seedlen shallbe equal to or greater than N
|
||||
* outlen = The bit length of Hash function
|
||||
*
|
||||
* 1. Check that the (L, N)
|
||||
* 2. If (seedlen <N), then return INVALID.
|
||||
* 3. n = ceil(L / outlen) - 1
|
||||
* 4. b = L- 1 - (n * outlen)
|
||||
* 5. domain_parameter_seed = an arbitrary sequence of seedlen bits
|
||||
* 6. U = Hash (domain_parameter_seed) mod 2^(N-1)
|
||||
* 7. q = 2^(N-1) + U + 1 - (U mod 2)
|
||||
* 8. Test whether or not q is prime as specified in Appendix C.3
|
||||
* 9. If qis not a prime, then go to step 5.
|
||||
* 10. offset = 1
|
||||
* 11. For counter = 0 to (4L- 1) do {
|
||||
* For j=0 to n do {
|
||||
* Vj = Hash ((domain_parameter_seed+ offset + j) mod 2^seedlen
|
||||
* }
|
||||
* W = V0 + (V1 *2^outlen) + ... + (Vn-1 * 2^((n-1) * outlen)) + ((Vn mod 2^b) * 2^(n * outlen))
|
||||
* X = W + 2^(L-1) Comment: 0 <= W < 2^(L-1); hence 2^(L-1) <= X < 2^L
|
||||
* c = X mod 2*q
|
||||
* p = X - (c - 1) Comment: p ~ 1 (mod 2*q)
|
||||
* If (p >= 2^(L-1)) {
|
||||
* Test whether or not p is prime as specified in Appendix C.3.
|
||||
* If p is determined to be prime, then return VALID and the values of p, qand (optionally) the values of domain_parameter_seed and counter
|
||||
* }
|
||||
* offset = offset + n + 1 Comment: Increment offset
|
||||
* }
|
||||
*/
|
||||
|
||||
seedbytes = group_size;
|
||||
L = (unsigned long)modulus_size * 8;
|
||||
N = (unsigned long)group_size * 8;
|
||||
|
||||
/* XXX-TODO no Lucas test */
|
||||
#ifdef LTC_MPI_HAS_LUCAS_TEST
|
||||
/* M-R tests (when followed by one Lucas test) according FIPS-186-4 - Appendix C.3 - table C.1 */
|
||||
mr_tests_p = (L <= 2048) ? 3 : 2;
|
||||
if (N <= 160) { mr_tests_q = 19; }
|
||||
else if (N <= 224) { mr_tests_q = 24; }
|
||||
else { mr_tests_q = 27; }
|
||||
#else
|
||||
/* M-R tests (without Lucas test) according FIPS-186-4 - Appendix C.3 - table C.1 */
|
||||
if (L <= 1024) { mr_tests_p = 40; }
|
||||
else if (L <= 2048) { mr_tests_p = 56; }
|
||||
else { mr_tests_p = 64; }
|
||||
|
||||
if (N <= 160) { mr_tests_q = 40; }
|
||||
else if (N <= 224) { mr_tests_q = 56; }
|
||||
else { mr_tests_q = 64; }
|
||||
#endif
|
||||
|
||||
hash = -1;
|
||||
for (i = 0; i < sizeof(accepted_hashes)/sizeof(accepted_hashes[0]); ++i) {
|
||||
hash = find_hash(accepted_hashes[i]);
|
||||
if (hash != -1) break;
|
||||
}
|
||||
if (hash == -1) {
|
||||
return CRYPT_INVALID_ARG; /* no appropriate hash function found */
|
||||
}
|
||||
if (N > hash_descriptor[hash].hashsize * 8) {
|
||||
return CRYPT_INVALID_ARG; /* group_size too big */
|
||||
}
|
||||
|
||||
if ((err = hash_is_valid(hash)) != CRYPT_OK) { return err; }
|
||||
outbytes = hash_descriptor[hash].hashsize;
|
||||
|
||||
n = ((L + outbytes*8 - 1) / (outbytes*8)) - 1;
|
||||
|
||||
if ((wbuf = XMALLOC((n+1)*outbytes)) == NULL) { err = CRYPT_MEM; goto cleanup3; }
|
||||
if ((sbuf = XMALLOC(seedbytes)) == NULL) { err = CRYPT_MEM; goto cleanup2; }
|
||||
|
||||
err = ltc_mp_init_multi(&t2L1, &t2N1, &t2q, &t2seedlen, &U, &W, &X, &c, &h, &e, &seedinc, LTC_NULL);
|
||||
if (err != CRYPT_OK) { goto cleanup1; }
|
||||
|
||||
if ((err = ltc_mp_2expt(t2L1, L-1)) != CRYPT_OK) { goto cleanup; }
|
||||
/* t2L1 = 2^(L-1) */
|
||||
if ((err = ltc_mp_2expt(t2N1, N-1)) != CRYPT_OK) { goto cleanup; }
|
||||
/* t2N1 = 2^(N-1) */
|
||||
if ((err = ltc_mp_2expt(t2seedlen, seedbytes*8)) != CRYPT_OK) { goto cleanup; }
|
||||
/* t2seedlen = 2^seedlen */
|
||||
|
||||
for(found_p=0; !found_p;) {
|
||||
/* q */
|
||||
for(found_q=0; !found_q;) {
|
||||
if (prng_descriptor[wprng].read(sbuf, seedbytes, prng) != seedbytes) { err = CRYPT_ERROR_READPRNG; goto cleanup; }
|
||||
i = outbytes;
|
||||
if ((err = hash_memory(hash, sbuf, seedbytes, digest, &i)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_read_unsigned_bin(U, digest, outbytes)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_mod(U, t2N1, U)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_add(t2N1, U, q)) != CRYPT_OK) { goto cleanup; }
|
||||
if (!ltc_mp_isodd(q)) ltc_mp_add_d(q, 1, q);
|
||||
if ((err = ltc_mp_prime_is_prime(q, mr_tests_q, &res)) != CRYPT_OK) { goto cleanup; }
|
||||
if (res == LTC_MP_YES) found_q = 1;
|
||||
}
|
||||
|
||||
/* p */
|
||||
if ((err = ltc_mp_read_unsigned_bin(seedinc, sbuf, seedbytes)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_add(q, q, t2q)) != CRYPT_OK) { goto cleanup; }
|
||||
for(counter=0; counter < 4*L && !found_p; counter++) {
|
||||
for(j=0; j<=n; j++) {
|
||||
if ((err = ltc_mp_add_d(seedinc, 1, seedinc)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_mod(seedinc, t2seedlen, seedinc)) != CRYPT_OK) { goto cleanup; }
|
||||
/* seedinc = (seedinc+1) % 2^seed_bitlen */
|
||||
if ((i = ltc_mp_unsigned_bin_size(seedinc)) > seedbytes) { err = CRYPT_INVALID_ARG; goto cleanup; }
|
||||
zeromem(sbuf, seedbytes);
|
||||
if ((err = ltc_mp_to_unsigned_bin(seedinc, sbuf + seedbytes-i)) != CRYPT_OK) { goto cleanup; }
|
||||
i = outbytes;
|
||||
err = hash_memory(hash, sbuf, seedbytes, wbuf+(n-j)*outbytes, &i);
|
||||
if (err != CRYPT_OK) { goto cleanup; }
|
||||
}
|
||||
if ((err = ltc_mp_read_unsigned_bin(W, wbuf, (n+1)*outbytes)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_mod(W, t2L1, W)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_add(W, t2L1, X)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_mod(X, t2q, c)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_sub_d(c, 1, p)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_sub(X, p, p)) != CRYPT_OK) { goto cleanup; }
|
||||
if (ltc_mp_cmp(p, t2L1) != LTC_MP_LT) {
|
||||
/* p >= 2^(L-1) */
|
||||
if ((err = ltc_mp_prime_is_prime(p, mr_tests_p, &res)) != CRYPT_OK) { goto cleanup; }
|
||||
if (res == LTC_MP_YES) {
|
||||
found_p = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FIPS-186-4 A.2.1 Unverifiable Generation of the Generator g
|
||||
* 1. e = (p - 1)/q
|
||||
* 2. h = any integer satisfying: 1 < h < (p - 1)
|
||||
* h could be obtained from a random number generator or from a counter that changes after each use
|
||||
* 3. g = h^e mod p
|
||||
* 4. if (g == 1), then go to step 2.
|
||||
*
|
||||
*/
|
||||
|
||||
if ((err = ltc_mp_sub_d(p, 1, e)) != CRYPT_OK) { goto cleanup; }
|
||||
if ((err = ltc_mp_div(e, q, e, c)) != CRYPT_OK) { goto cleanup; }
|
||||
/* e = (p - 1)/q */
|
||||
i = ltc_mp_count_bits(p);
|
||||
do {
|
||||
do {
|
||||
if ((err = rand_bn_bits(h, i, prng, wprng)) != CRYPT_OK) { goto cleanup; }
|
||||
} while (ltc_mp_cmp(h, p) != LTC_MP_LT || ltc_mp_cmp_d(h, 2) != LTC_MP_GT);
|
||||
if ((err = ltc_mp_sub_d(h, 1, h)) != CRYPT_OK) { goto cleanup; }
|
||||
/* h is randon and 1 < h < (p-1) */
|
||||
if ((err = ltc_mp_exptmod(h, e, p, g)) != CRYPT_OK) { goto cleanup; }
|
||||
} while (ltc_mp_cmp_d(g, 1) == LTC_MP_EQ);
|
||||
|
||||
err = CRYPT_OK;
|
||||
cleanup:
|
||||
ltc_mp_deinit_multi(t2L1, t2N1, t2q, t2seedlen, U, W, X, c, h, e, seedinc, LTC_NULL);
|
||||
cleanup1:
|
||||
XFREE(sbuf);
|
||||
cleanup2:
|
||||
XFREE(wbuf);
|
||||
cleanup3:
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Generate DSA parameters p, q & g
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG desired
|
||||
@param group_size Size of the multiplicative group (octets)
|
||||
@param modulus_size Size of the modulus (octets)
|
||||
@param key [out] Where to store the created key
|
||||
@return CRYPT_OK if successful.
|
||||
*/
|
||||
int dsa_generate_pqg(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* init key */
|
||||
if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
|
||||
/* generate params */
|
||||
err = s_dsa_make_params(prng, wprng, group_size, modulus_size, key->p, key->q, key->g);
|
||||
if (err != CRYPT_OK) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
key->qord = group_size;
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
cleanup:
|
||||
dsa_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
145
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_import.c
Normal file
145
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_import.c
Normal file
@@ -0,0 +1,145 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@file dsa_import.c
|
||||
DSA implementation, import a DSA key, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
int dsa_import_pkcs1(const unsigned char *in, unsigned long inlen, dsa_key *key)
|
||||
{
|
||||
int err;
|
||||
unsigned long zero = 0;
|
||||
/* get key type */
|
||||
if ((err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
|
||||
LTC_ASN1_INTEGER, 1UL, key->p,
|
||||
LTC_ASN1_INTEGER, 1UL, key->q,
|
||||
LTC_ASN1_INTEGER, 1UL, key->g,
|
||||
LTC_ASN1_INTEGER, 1UL, key->y,
|
||||
LTC_ASN1_INTEGER, 1UL, key->x,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) {
|
||||
|
||||
key->type = PK_PRIVATE;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Import a DSA key
|
||||
@param in The binary packet to import from
|
||||
@param inlen The length of the binary packet
|
||||
@param key [out] Where to store the imported key
|
||||
@return CRYPT_OK if successful, upon error this function will free all allocated memory
|
||||
*/
|
||||
int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
|
||||
{
|
||||
int err, stat;
|
||||
unsigned char* tmpbuf = NULL;
|
||||
unsigned char flags[1];
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
/* init key */
|
||||
if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
|
||||
|
||||
/* try to match the old libtomcrypt format */
|
||||
err = der_decode_sequence_multi(in, inlen, LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
|
||||
if (err == CRYPT_OK || err == CRYPT_INPUT_TOO_LONG) {
|
||||
/* private key */
|
||||
if (flags[0] == 1) {
|
||||
if ((err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_INTEGER, 1UL, key->g,
|
||||
LTC_ASN1_INTEGER, 1UL, key->p,
|
||||
LTC_ASN1_INTEGER, 1UL, key->q,
|
||||
LTC_ASN1_INTEGER, 1UL, key->y,
|
||||
LTC_ASN1_INTEGER, 1UL, key->x,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
key->type = PK_PRIVATE;
|
||||
goto LBL_OK;
|
||||
}
|
||||
/* public key */
|
||||
else if (flags[0] == 0) {
|
||||
if ((err = der_decode_sequence_multi(in, inlen,
|
||||
LTC_ASN1_BIT_STRING, 1UL, flags,
|
||||
LTC_ASN1_INTEGER, 1UL, key->g,
|
||||
LTC_ASN1_INTEGER, 1UL, key->p,
|
||||
LTC_ASN1_INTEGER, 1UL, key->q,
|
||||
LTC_ASN1_INTEGER, 1UL, key->y,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
key->type = PK_PUBLIC;
|
||||
goto LBL_OK;
|
||||
}
|
||||
else {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (dsa_import_pkcs1(in, inlen, key) != CRYPT_OK) {
|
||||
ltc_asn1_list params[3];
|
||||
unsigned long tmpbuf_len = inlen, len;
|
||||
|
||||
LTC_SET_ASN1(params, 0, LTC_ASN1_INTEGER, key->p, 1UL);
|
||||
LTC_SET_ASN1(params, 1, LTC_ASN1_INTEGER, key->q, 1UL);
|
||||
LTC_SET_ASN1(params, 2, LTC_ASN1_INTEGER, key->g, 1UL);
|
||||
len = 3;
|
||||
|
||||
tmpbuf = XCALLOC(1, tmpbuf_len);
|
||||
if (tmpbuf == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
err = x509_decode_subject_public_key_info(in, inlen,
|
||||
LTC_OID_DSA, tmpbuf, &tmpbuf_len,
|
||||
LTC_ASN1_SEQUENCE, params, &len);
|
||||
if (err != CRYPT_OK) {
|
||||
XFREE(tmpbuf);
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
if ((err = der_decode_integer(tmpbuf, tmpbuf_len, key->y)) != CRYPT_OK) {
|
||||
XFREE(tmpbuf);
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
key->type = PK_PUBLIC;
|
||||
XFREE(tmpbuf);
|
||||
}
|
||||
|
||||
LBL_OK:
|
||||
key->qord = ltc_mp_unsigned_bin_size(key->q);
|
||||
|
||||
/* quick p, q, g validation, without primality testing
|
||||
* + x, y validation */
|
||||
if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if (stat == 0) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
LBL_ERR:
|
||||
dsa_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
94
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_import_pkcs8.c
Normal file
94
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_import_pkcs8.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/**
|
||||
@file dsa_import_pkcs8.c
|
||||
Import a PKCS DSA key
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
int dsa_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, dsa_key *key)
|
||||
{
|
||||
int err, stat;
|
||||
|
||||
LTC_UNUSED_PARAM(alg_id);
|
||||
|
||||
if (!alg_id->child
|
||||
|| !LTC_ASN1_IS_TYPE(alg_id->child->next, LTC_ASN1_SEQUENCE)
|
||||
|| !LTC_ASN1_IS_TYPE(priv_key, LTC_ASN1_OCTET_STRING)) {
|
||||
return CRYPT_INVALID_PACKET;
|
||||
}
|
||||
if ((err = dsa_set_pqg_dsaparam(alg_id->child->next->data, alg_id->child->next->size, key)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = der_decode_integer(priv_key->data, priv_key->size, key->x)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if ((err = ltc_mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* quick p, q, g validation, without primality testing
|
||||
* + x, y validation */
|
||||
if ((err = dsa_int_validate(key, &stat)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if (stat == 0) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
key->qord = ltc_mp_unsigned_bin_size(key->q);
|
||||
key->type = PK_PRIVATE;
|
||||
|
||||
return err;
|
||||
LBL_ERR:
|
||||
dsa_free(key);
|
||||
return err;
|
||||
}
|
||||
/**
|
||||
Import an RSAPrivateKey in PKCS#8 format
|
||||
@param in The packet to import from
|
||||
@param inlen It's length (octets)
|
||||
@param pw_ctx The password context when decrypting the private key
|
||||
@param key [out] Destination for newly imported key
|
||||
@return CRYPT_OK if successful, upon error allocated memory is freed
|
||||
*/
|
||||
int dsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
|
||||
const password_ctx *pw_ctx,
|
||||
dsa_key *key)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_list *l = NULL;
|
||||
ltc_asn1_list *alg_id, *priv_key;
|
||||
enum ltc_oid_id pka;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
if ((err = pkcs8_decode_flexi(in, inlen, pw_ctx, &l)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = pkcs8_get_children(l, &pka, &alg_id, &priv_key)) != CRYPT_OK) {
|
||||
goto LBL_DER_FREE;
|
||||
}
|
||||
if (pka != LTC_OID_DSA) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_DER_FREE;
|
||||
}
|
||||
|
||||
err = dsa_import_pkcs8_asn1(alg_id, priv_key, key);
|
||||
|
||||
LBL_DER_FREE:
|
||||
der_free_sequence_flexi(l);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif /* LTC_MRSA */
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
22
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_init.c
Normal file
22
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_init.c
Normal file
@@ -0,0 +1,22 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Init DSA key
|
||||
@param key [out] the key to init
|
||||
@return CRYPT_OK if successful.
|
||||
*/
|
||||
int dsa_int_init(dsa_key *key)
|
||||
{
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
/* init key */
|
||||
return ltc_mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
31
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_make_key.c
Normal file
31
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_make_key.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file dsa_make_key.c
|
||||
DSA implementation, generate a DSA key
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Old-style creation of a DSA key
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG desired
|
||||
@param group_size Size of the multiplicative group (octets)
|
||||
@param modulus_size Size of the modulus (octets)
|
||||
@param key [out] Where to store the created key
|
||||
@return CRYPT_OK if successful.
|
||||
*/
|
||||
int dsa_make_key(prng_state *prng, int wprng, int group_size, int modulus_size, dsa_key *key)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = dsa_generate_pqg(prng, wprng, group_size, modulus_size, key)) != CRYPT_OK) { return err; }
|
||||
if ((err = dsa_generate_key(prng, wprng, key)) != CRYPT_OK) { return err; }
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
104
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_set.c
Normal file
104
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_set.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Import DSA's p, q & g from raw numbers
|
||||
@param p DSA's p in binary representation
|
||||
@param plen The length of p
|
||||
@param q DSA's q in binary representation
|
||||
@param qlen The length of q
|
||||
@param g DSA's g in binary representation
|
||||
@param glen The length of g
|
||||
@param key [out] the destination for the imported key
|
||||
@return CRYPT_OK if successful.
|
||||
*/
|
||||
int dsa_set_pqg(const unsigned char *p, unsigned long plen,
|
||||
const unsigned char *q, unsigned long qlen,
|
||||
const unsigned char *g, unsigned long glen,
|
||||
dsa_key *key)
|
||||
{
|
||||
int err, stat;
|
||||
|
||||
LTC_ARGCHK(p != NULL);
|
||||
LTC_ARGCHK(q != NULL);
|
||||
LTC_ARGCHK(g != NULL);
|
||||
|
||||
/* init key */
|
||||
if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
|
||||
|
||||
if ((err = ltc_mp_read_unsigned_bin(key->p, p , plen)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
if ((err = ltc_mp_read_unsigned_bin(key->g, g , glen)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
if ((err = ltc_mp_read_unsigned_bin(key->q, q , qlen)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
|
||||
key->qord = ltc_mp_unsigned_bin_size(key->q);
|
||||
|
||||
/* do only a quick validation, without primality testing */
|
||||
if ((err = dsa_int_validate_pqg(key, &stat)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
if (stat == 0) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
dsa_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Import DSA public or private key-part from raw numbers
|
||||
|
||||
NB: The p, q & g parts must be set beforehand
|
||||
|
||||
@param in The key-part to import, either public or private.
|
||||
@param inlen The key-part's length
|
||||
@param type Which type of key (PK_PRIVATE or PK_PUBLIC)
|
||||
@param key [out] the destination for the imported key
|
||||
@return CRYPT_OK if successful.
|
||||
*/
|
||||
int dsa_set_key(const unsigned char *in, unsigned long inlen, int type, dsa_key *key)
|
||||
{
|
||||
int err, stat = 0;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(key->x != NULL);
|
||||
LTC_ARGCHK(key->y != NULL);
|
||||
LTC_ARGCHK(key->p != NULL);
|
||||
LTC_ARGCHK(key->g != NULL);
|
||||
LTC_ARGCHK(key->q != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
if (type == PK_PRIVATE) {
|
||||
key->type = PK_PRIVATE;
|
||||
if ((err = ltc_mp_read_unsigned_bin(key->x, in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
if ((err = ltc_mp_exptmod(key->g, key->x, key->p, key->y)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
}
|
||||
else {
|
||||
key->type = PK_PUBLIC;
|
||||
if ((err = ltc_mp_read_unsigned_bin(key->y, in, inlen)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
}
|
||||
|
||||
if ((err = dsa_int_validate_xy(key, &stat)) != CRYPT_OK) { goto LBL_ERR; }
|
||||
if (stat == 0) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
dsa_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
61
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_set_pqg_dsaparam.c
Normal file
61
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_set_pqg_dsaparam.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Import DSA's p, q & g from dsaparam
|
||||
|
||||
dsaparam data: openssl dsaparam -outform DER -out dsaparam.der 2048
|
||||
|
||||
@param dsaparam The DSA param DER encoded data
|
||||
@param dsaparamlen The length of dhparam data
|
||||
@param key [out] the destination for the imported key
|
||||
@return CRYPT_OK if successful.
|
||||
*/
|
||||
int dsa_set_pqg_dsaparam(const unsigned char *dsaparam, unsigned long dsaparamlen,
|
||||
dsa_key *key)
|
||||
{
|
||||
int err, stat;
|
||||
|
||||
LTC_ARGCHK(dsaparam != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
/* init key */
|
||||
if ((err = dsa_int_init(key)) != CRYPT_OK) return err;
|
||||
|
||||
if ((err = der_decode_sequence_multi(dsaparam, dsaparamlen,
|
||||
LTC_ASN1_INTEGER, 1UL, key->p,
|
||||
LTC_ASN1_INTEGER, 1UL, key->q,
|
||||
LTC_ASN1_INTEGER, 1UL, key->g,
|
||||
LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
key->qord = ltc_mp_unsigned_bin_size(key->q);
|
||||
|
||||
/* quick p, q, g validation, without primality testing */
|
||||
if ((err = dsa_int_validate_pqg(key, &stat)) != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
if (stat == 0) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
return CRYPT_OK;
|
||||
|
||||
LBL_ERR:
|
||||
dsa_free(key);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
60
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_shared_secret.c
Normal file
60
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_shared_secret.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file dsa_shared_secret.c
|
||||
DSA Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Create a DSA shared secret between two keys
|
||||
@param private_key The private DSA key (the exponent)
|
||||
@param base The base of the exponentiation (allows this to be used for both encrypt and decrypt)
|
||||
@param public_key The public key
|
||||
@param out [out] Destination of the shared secret
|
||||
@param outlen [in/out] The max size and resulting size of the shared secret
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_shared_secret(void *private_key, void *base,
|
||||
const dsa_key *public_key,
|
||||
unsigned char *out, unsigned long *outlen)
|
||||
{
|
||||
unsigned long x;
|
||||
void *res;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(private_key != NULL);
|
||||
LTC_ARGCHK(public_key != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
|
||||
/* make new point */
|
||||
if ((err = ltc_mp_init(&res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if ((err = ltc_mp_exptmod(base, private_key, public_key->p, res)) != CRYPT_OK) {
|
||||
ltc_mp_clear(res);
|
||||
return err;
|
||||
}
|
||||
|
||||
x = (unsigned long)ltc_mp_unsigned_bin_size(res);
|
||||
if (*outlen < x) {
|
||||
*outlen = x;
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
goto done;
|
||||
}
|
||||
zeromem(out, x);
|
||||
if ((err = ltc_mp_to_unsigned_bin(res, out + (x - ltc_mp_unsigned_bin_size(res)))) != CRYPT_OK) { goto done; }
|
||||
|
||||
err = CRYPT_OK;
|
||||
*outlen = x;
|
||||
done:
|
||||
ltc_mp_clear(res);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
142
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_sign_hash.c
Normal file
142
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_sign_hash.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file dsa_sign_hash.c
|
||||
DSA implementation, sign a hash, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Sign a hash with DSA
|
||||
@param in The hash to sign
|
||||
@param inlen The length of the hash to sign
|
||||
@param r The "r" integer of the signature (caller must initialize with ltc_mp_init() first)
|
||||
@param s The "s" integer of the signature (caller must initialize with ltc_mp_init() first)
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG desired
|
||||
@param key A private DSA key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
|
||||
void *r, void *s,
|
||||
prng_state *prng, int wprng, const dsa_key *key)
|
||||
{
|
||||
void *k, *kinv, *tmp;
|
||||
unsigned char *buf;
|
||||
int err, qbits;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(r != NULL);
|
||||
LTC_ARGCHK(s != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (key->type != PK_PRIVATE) {
|
||||
return CRYPT_PK_NOT_PRIVATE;
|
||||
}
|
||||
|
||||
/* check group order size */
|
||||
if (key->qord >= LTC_MDSA_MAX_GROUP) {
|
||||
return CRYPT_INVALID_ARG;
|
||||
}
|
||||
|
||||
buf = XMALLOC(LTC_MDSA_MAX_GROUP);
|
||||
if (buf == NULL) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
/* Init our temps */
|
||||
if ((err = ltc_mp_init_multi(&k, &kinv, &tmp, LTC_NULL)) != CRYPT_OK) { goto ERRBUF; }
|
||||
|
||||
qbits = ltc_mp_count_bits(key->q);
|
||||
retry:
|
||||
|
||||
do {
|
||||
/* gen random k */
|
||||
if ((err = rand_bn_bits(k, qbits, prng, wprng)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* k should be from range: 1 <= k <= q-1 (see FIPS 186-4 B.2.2) */
|
||||
if (ltc_mp_cmp_d(k, 0) != LTC_MP_GT || ltc_mp_cmp(k, key->q) != LTC_MP_LT) { goto retry; }
|
||||
|
||||
/* test gcd */
|
||||
if ((err = ltc_mp_gcd(k, key->q, tmp)) != CRYPT_OK) { goto error; }
|
||||
} while (ltc_mp_cmp_d(tmp, 1) != LTC_MP_EQ);
|
||||
|
||||
/* now find 1/k mod q */
|
||||
if ((err = ltc_mp_invmod(k, key->q, kinv)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* now find r = g^k mod p mod q */
|
||||
if ((err = ltc_mp_exptmod(key->g, k, key->p, r)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_mp_mod(r, key->q, r)) != CRYPT_OK) { goto error; }
|
||||
|
||||
if (ltc_mp_iszero(r) == LTC_MP_YES) { goto retry; }
|
||||
|
||||
/* FIPS 186-4 4.6: use leftmost min(bitlen(q), bitlen(hash)) bits of 'hash'*/
|
||||
inlen = MIN(inlen, (unsigned long)(key->qord));
|
||||
|
||||
/* now find s = (in + xr)/k mod q */
|
||||
if ((err = ltc_mp_read_unsigned_bin(tmp, in, inlen)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_mp_mul(key->x, r, s)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_mp_add(s, tmp, s)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_mp_mulmod(s, kinv, key->q, s)) != CRYPT_OK) { goto error; }
|
||||
|
||||
if (ltc_mp_iszero(s) == LTC_MP_YES) { goto retry; }
|
||||
|
||||
err = CRYPT_OK;
|
||||
error:
|
||||
ltc_mp_deinit_multi(k, kinv, tmp, LTC_NULL);
|
||||
ERRBUF:
|
||||
#ifdef LTC_CLEAN_STACK
|
||||
zeromem(buf, LTC_MDSA_MAX_GROUP);
|
||||
#endif
|
||||
XFREE(buf);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Sign a hash with DSA
|
||||
@param in The hash to sign
|
||||
@param inlen The length of the hash to sign
|
||||
@param out [out] Where to store the signature
|
||||
@param outlen [in/out] The max size and resulting size of the signature
|
||||
@param prng An active PRNG state
|
||||
@param wprng The index of the PRNG desired
|
||||
@param key A private DSA key
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
|
||||
unsigned char *out, unsigned long *outlen,
|
||||
prng_state *prng, int wprng, const dsa_key *key)
|
||||
{
|
||||
void *r, *s;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
if (ltc_mp_init_multi(&r, &s, LTC_NULL) != CRYPT_OK) {
|
||||
return CRYPT_MEM;
|
||||
}
|
||||
|
||||
if ((err = dsa_sign_hash_raw(in, inlen, r, s, prng, wprng, key)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_INTEGER, 1UL, r,
|
||||
LTC_ASN1_INTEGER, 1UL, s,
|
||||
LTC_ASN1_EOL, 0UL, NULL);
|
||||
|
||||
error:
|
||||
ltc_mp_deinit_multi(r, s, LTC_NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
127
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_verify_hash.c
Normal file
127
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_verify_hash.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file dsa_verify_hash.c
|
||||
DSA implementation, verify a signature, Tom St Denis
|
||||
*/
|
||||
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Verify a DSA signature
|
||||
@param r DSA "r" parameter
|
||||
@param s DSA "s" parameter
|
||||
@param hash The hash that was signed
|
||||
@param hashlen The length of the hash that was signed
|
||||
@param stat [out] The result of the signature verification, 1==valid, 0==invalid
|
||||
@param key The corresponding public DSA key
|
||||
@return CRYPT_OK if successful (even if the signature is invalid)
|
||||
*/
|
||||
int dsa_verify_hash_raw( void *r, void *s,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, const dsa_key *key)
|
||||
{
|
||||
void *w, *v, *u1, *u2;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(r != NULL);
|
||||
LTC_ARGCHK(s != NULL);
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
/* default to invalid signature */
|
||||
*stat = 0;
|
||||
|
||||
/* init our variables */
|
||||
if ((err = ltc_mp_init_multi(&w, &v, &u1, &u2, LTC_NULL)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* neither r or s can be null or >q*/
|
||||
if (ltc_mp_cmp_d(r, 0) != LTC_MP_GT || ltc_mp_cmp_d(s, 0) != LTC_MP_GT || ltc_mp_cmp(r, key->q) != LTC_MP_LT || ltc_mp_cmp(s, key->q) != LTC_MP_LT) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* FIPS 186-4 4.7: use leftmost min(bitlen(q), bitlen(hash)) bits of 'hash' */
|
||||
hashlen = MIN(hashlen, (unsigned long)(key->qord));
|
||||
|
||||
/* w = 1/s mod q */
|
||||
if ((err = ltc_mp_invmod(s, key->q, w)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* u1 = m * w mod q */
|
||||
if ((err = ltc_mp_read_unsigned_bin(u1, hash, hashlen)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_mp_mulmod(u1, w, key->q, u1)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* u2 = r*w mod q */
|
||||
if ((err = ltc_mp_mulmod(r, w, key->q, u2)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* v = g^u1 * y^u2 mod p mod q */
|
||||
if ((err = ltc_mp_exptmod(key->g, u1, key->p, u1)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_mp_exptmod(key->y, u2, key->p, u2)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_mp_mulmod(u1, u2, key->p, v)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_mp_mod(v, key->q, v)) != CRYPT_OK) { goto error; }
|
||||
|
||||
/* if r = v then we're set */
|
||||
if (ltc_mp_cmp(r, v) == LTC_MP_EQ) {
|
||||
*stat = 1;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
error:
|
||||
ltc_mp_deinit_multi(w, v, u1, u2, LTC_NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Verify a DSA signature
|
||||
@param sig The signature
|
||||
@param siglen The length of the signature (octets)
|
||||
@param hash The hash that was signed
|
||||
@param hashlen The length of the hash that was signed
|
||||
@param stat [out] The result of the signature verification, 1==valid, 0==invalid
|
||||
@param key The corresponding public DSA key
|
||||
@return CRYPT_OK if successful (even if the signature is invalid)
|
||||
*/
|
||||
int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
|
||||
const unsigned char *hash, unsigned long hashlen,
|
||||
int *stat, const dsa_key *key)
|
||||
{
|
||||
int err;
|
||||
void *r, *s;
|
||||
ltc_asn1_list sig_seq[2];
|
||||
unsigned long reallen = 0;
|
||||
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
*stat = 0; /* must be set before the first return */
|
||||
|
||||
if ((err = ltc_mp_init_multi(&r, &s, LTC_NULL)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
LTC_SET_ASN1(sig_seq, 0, LTC_ASN1_INTEGER, r, 1UL);
|
||||
LTC_SET_ASN1(sig_seq, 1, LTC_ASN1_INTEGER, s, 1UL);
|
||||
|
||||
err = der_decode_sequence_strict(sig, siglen, sig_seq, 2);
|
||||
if (err != CRYPT_OK) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
err = der_length_sequence(sig_seq, 2, &reallen);
|
||||
if (err != CRYPT_OK || reallen != siglen) {
|
||||
goto LBL_ERR;
|
||||
}
|
||||
|
||||
/* do the op */
|
||||
err = dsa_verify_hash_raw(r, s, hash, hashlen, stat, key);
|
||||
|
||||
LBL_ERR:
|
||||
ltc_mp_deinit_multi(r, s, LTC_NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
204
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_verify_key.c
Normal file
204
Sources/DataLiteC/libtomcrypt/pk/dsa/dsa_verify_key.c
Normal file
@@ -0,0 +1,204 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file dsa_verify_key.c
|
||||
DSA implementation, verify a key, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_MDSA
|
||||
|
||||
/**
|
||||
Validate a DSA key
|
||||
|
||||
Yeah, this function should've been called dsa_validate_key()
|
||||
in the first place and for compat-reasons we keep it
|
||||
as it was (for now).
|
||||
|
||||
@param key The key to validate
|
||||
@param stat [out] Result of test, 1==valid, 0==invalid
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_verify_key(const dsa_key *key, int *stat)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = dsa_int_validate_primes(key, stat);
|
||||
if (err != CRYPT_OK || *stat == 0) return err;
|
||||
|
||||
return dsa_int_validate(key, stat);
|
||||
}
|
||||
|
||||
/**
|
||||
Non-complex part (no primality testing) of the validation
|
||||
of DSA params (p, q, g)
|
||||
|
||||
@param key The key to validate
|
||||
@param stat [out] Result of test, 1==valid, 0==invalid
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_int_validate_pqg(const dsa_key *key, int *stat)
|
||||
{
|
||||
void *tmp1, *tmp2;
|
||||
int err;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
*stat = 0;
|
||||
|
||||
/* check q-order */
|
||||
if ( key->qord >= LTC_MDSA_MAX_GROUP || key->qord <= 15 ||
|
||||
(unsigned long)key->qord >= ltc_mp_unsigned_bin_size(key->p) ||
|
||||
(ltc_mp_unsigned_bin_size(key->p) - key->qord) >= LTC_MDSA_DELTA ) {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* FIPS 186-4 chapter 4.1: 1 < g < p */
|
||||
if (ltc_mp_cmp_d(key->g, 1) != LTC_MP_GT || ltc_mp_cmp(key->g, key->p) != LTC_MP_LT) {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
if ((err = ltc_mp_init_multi(&tmp1, &tmp2, LTC_NULL)) != CRYPT_OK) { return err; }
|
||||
|
||||
/* FIPS 186-4 chapter 4.1: q is a divisor of (p - 1) */
|
||||
if ((err = ltc_mp_sub_d(key->p, 1, tmp1)) != CRYPT_OK) { goto error; }
|
||||
if ((err = ltc_mp_div(tmp1, key->q, tmp1, tmp2)) != CRYPT_OK) { goto error; }
|
||||
if (ltc_mp_iszero(tmp2) != LTC_MP_YES) {
|
||||
err = CRYPT_OK;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* FIPS 186-4 chapter 4.1: g is a generator of a subgroup of order q in
|
||||
* the multiplicative group of GF(p) - so we make sure that g^q mod p = 1
|
||||
*/
|
||||
if ((err = ltc_mp_exptmod(key->g, key->q, key->p, tmp1)) != CRYPT_OK) { goto error; }
|
||||
if (ltc_mp_cmp_d(tmp1, 1) != LTC_MP_EQ) {
|
||||
err = CRYPT_OK;
|
||||
goto error;
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
*stat = 1;
|
||||
error:
|
||||
ltc_mp_deinit_multi(tmp2, tmp1, LTC_NULL);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Primality testing of DSA params p and q
|
||||
|
||||
@param key The key to validate
|
||||
@param stat [out] Result of test, 1==valid, 0==invalid
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_int_validate_primes(const dsa_key *key, int *stat)
|
||||
{
|
||||
int err, res;
|
||||
|
||||
*stat = 0;
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
|
||||
/* key->q prime? */
|
||||
if ((err = ltc_mp_prime_is_prime(key->q, LTC_MILLER_RABIN_REPS, &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (res == LTC_MP_NO) {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/* key->p prime? */
|
||||
if ((err = ltc_mp_prime_is_prime(key->p, LTC_MILLER_RABIN_REPS, &res)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if (res == LTC_MP_NO) {
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
*stat = 1;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
Validation of a DSA key (x and y values)
|
||||
|
||||
@param key The key to validate
|
||||
@param stat [out] Result of test, 1==valid, 0==invalid
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_int_validate_xy(const dsa_key *key, int *stat)
|
||||
{
|
||||
void *tmp;
|
||||
int err;
|
||||
|
||||
*stat = 0;
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(stat != NULL);
|
||||
|
||||
/* 1 < y < p-1 */
|
||||
if ((err = ltc_mp_init(&tmp)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
if ((err = ltc_mp_sub_d(key->p, 1, tmp)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
if (ltc_mp_cmp_d(key->y, 1) != LTC_MP_GT || ltc_mp_cmp(key->y, tmp) != LTC_MP_LT) {
|
||||
err = CRYPT_OK;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (key->type == PK_PRIVATE) {
|
||||
/* FIPS 186-4 chapter 4.1: 0 < x < q */
|
||||
if (ltc_mp_cmp_d(key->x, 0) != LTC_MP_GT || ltc_mp_cmp(key->x, key->q) != LTC_MP_LT) {
|
||||
err = CRYPT_OK;
|
||||
goto error;
|
||||
}
|
||||
/* FIPS 186-4 chapter 4.1: y = g^x mod p */
|
||||
if ((err = ltc_mp_exptmod(key->g, key->x, key->p, tmp)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
if (ltc_mp_cmp(tmp, key->y) != LTC_MP_EQ) {
|
||||
err = CRYPT_OK;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* with just a public key we cannot test y = g^x mod p therefore we
|
||||
* only test that y^q mod p = 1, which makes sure y is in g^x mod p
|
||||
*/
|
||||
if ((err = ltc_mp_exptmod(key->y, key->q, key->p, tmp)) != CRYPT_OK) {
|
||||
goto error;
|
||||
}
|
||||
if (ltc_mp_cmp_d(tmp, 1) != LTC_MP_EQ) {
|
||||
err = CRYPT_OK;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
err = CRYPT_OK;
|
||||
*stat = 1;
|
||||
error:
|
||||
ltc_mp_clear(tmp);
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Validation of DSA params (p, q, g) and DSA key (x and y)
|
||||
|
||||
@param key The key to validate
|
||||
@param stat [out] Result of test, 1==valid, 0==invalid
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int dsa_int_validate(const dsa_key *key, int *stat)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = dsa_int_validate_pqg(key, stat);
|
||||
if (err != CRYPT_OK || *stat == 0) return err;
|
||||
|
||||
return dsa_int_validate_xy(key, stat);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file ec25519_crypto_ctx.c
|
||||
curve25519 crypto context helper
|
||||
*/
|
||||
|
||||
#ifdef LTC_CURVE25519
|
||||
|
||||
int ec25519_crypto_ctx(unsigned char *out, unsigned long *outlen, unsigned char flag, const unsigned char *ctx, unsigned long ctxlen)
|
||||
{
|
||||
unsigned char *buf = out;
|
||||
|
||||
const char *prefix = "SigEd25519 no Ed25519 collisions";
|
||||
const unsigned long prefix_len = XSTRLEN(prefix);
|
||||
const unsigned char ctxlen8 = (unsigned char)ctxlen;
|
||||
|
||||
if (ctxlen > 255u) return CRYPT_INPUT_TOO_LONG;
|
||||
if (*outlen < prefix_len + 2u + ctxlen) return CRYPT_BUFFER_OVERFLOW;
|
||||
|
||||
XMEMCPY(buf, prefix, prefix_len);
|
||||
buf += prefix_len;
|
||||
XMEMCPY(buf, &flag, 1);
|
||||
buf++;
|
||||
XMEMCPY(buf, &ctxlen8, 1);
|
||||
buf++;
|
||||
|
||||
if (ctxlen > 0u) {
|
||||
LTC_ARGCHK(ctx != NULL);
|
||||
XMEMCPY(buf, ctx, ctxlen);
|
||||
buf += ctxlen;
|
||||
}
|
||||
|
||||
*outlen = buf-out;
|
||||
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
94
Sources/DataLiteC/libtomcrypt/pk/ec25519/ec25519_export.c
Normal file
94
Sources/DataLiteC/libtomcrypt/pk/ec25519/ec25519_export.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file ec25519_export.c
|
||||
Generic export of a Curve/Ed25519 key to a binary packet, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_CURVE25519
|
||||
|
||||
/**
|
||||
Generic export of a Curve/Ed25519 key to a binary packet
|
||||
@param out [out] The destination for the key
|
||||
@param outlen [in/out] The max size and resulting size of the Ed25519 key
|
||||
@param type Which type of key (PK_PRIVATE, PK_PUBLIC|PK_STD or PK_PUBLIC)
|
||||
@param key The key you wish to export
|
||||
@return CRYPT_OK if successful
|
||||
*/
|
||||
int ec25519_export( unsigned char *out, unsigned long *outlen,
|
||||
int which,
|
||||
const curve25519_key *key)
|
||||
{
|
||||
int err, std;
|
||||
const char* OID;
|
||||
unsigned long oid[16], oidlen;
|
||||
ltc_asn1_list alg_id[1];
|
||||
enum ltc_oid_id oid_id;
|
||||
unsigned char private_key[34];
|
||||
unsigned long version, private_key_len = sizeof(private_key);
|
||||
|
||||
LTC_ARGCHK(out != NULL);
|
||||
LTC_ARGCHK(outlen != NULL);
|
||||
LTC_ARGCHK(key != NULL);
|
||||
|
||||
std = which & PK_STD;
|
||||
which &= ~PK_STD;
|
||||
if ((err = pk_get_oid_id(key->pka, &oid_id)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (which == PK_PRIVATE) {
|
||||
if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
|
||||
|
||||
if (std == PK_STD) {
|
||||
if ((err = pk_get_oid(oid_id, &OID)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
oidlen = sizeof(oid)/sizeof(oid[0]);
|
||||
if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen);
|
||||
|
||||
/* encode private key as PKCS#8 */
|
||||
if ((err = der_encode_octet_string(key->priv, 32uL, private_key, &private_key_len)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
version = 0;
|
||||
err = der_encode_sequence_multi(out, outlen,
|
||||
LTC_ASN1_SHORT_INTEGER, 1uL, &version,
|
||||
LTC_ASN1_SEQUENCE, 1uL, alg_id,
|
||||
LTC_ASN1_OCTET_STRING, private_key_len, private_key,
|
||||
LTC_ASN1_EOL, 0uL, NULL);
|
||||
} else {
|
||||
if (*outlen < sizeof(key->priv)) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
} else {
|
||||
XMEMCPY(out, key->priv, sizeof(key->priv));
|
||||
err = CRYPT_OK;
|
||||
}
|
||||
*outlen = sizeof(key->priv);
|
||||
}
|
||||
} else {
|
||||
if (std == PK_STD) {
|
||||
/* encode public key as SubjectPublicKeyInfo */
|
||||
err = x509_encode_subject_public_key_info(out, outlen, oid_id, key->pub, 32uL, LTC_ASN1_EOL, NULL, 0);
|
||||
} else {
|
||||
if (*outlen < sizeof(key->pub)) {
|
||||
err = CRYPT_BUFFER_OVERFLOW;
|
||||
} else {
|
||||
XMEMCPY(out, key->pub, sizeof(key->pub));
|
||||
err = CRYPT_OK;
|
||||
}
|
||||
*outlen = sizeof(key->pub);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,86 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file ec25519_import_pkcs8.c
|
||||
Generic import of a Curve/Ed25519 private key in PKCS#8 format, Steffen Jaeckel
|
||||
*/
|
||||
|
||||
#ifdef LTC_CURVE25519
|
||||
|
||||
typedef int (*sk_to_pk)(unsigned char *pk , const unsigned char *sk);
|
||||
|
||||
int ec25519_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key,
|
||||
enum ltc_oid_id id,
|
||||
curve25519_key *key)
|
||||
{
|
||||
int err;
|
||||
unsigned long key_len;
|
||||
sk_to_pk fp;
|
||||
|
||||
LTC_ARGCHK(key != NULL);
|
||||
LTC_ARGCHK(ltc_mp.name != NULL);
|
||||
|
||||
LTC_UNUSED_PARAM(alg_id);
|
||||
|
||||
switch (id) {
|
||||
case LTC_OID_ED25519:
|
||||
fp = tweetnacl_crypto_sk_to_pk;
|
||||
break;
|
||||
case LTC_OID_X25519:
|
||||
fp = tweetnacl_crypto_scalarmult_base;
|
||||
break;
|
||||
default:
|
||||
return CRYPT_PK_INVALID_TYPE;
|
||||
}
|
||||
|
||||
key_len = sizeof(key->priv);
|
||||
if ((err = der_decode_octet_string(priv_key->data, priv_key->size, key->priv, &key_len)) == CRYPT_OK) {
|
||||
fp(key->pub, key->priv);
|
||||
key->type = PK_PRIVATE;
|
||||
err = pk_get_pka_id(id, &key->pka);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
Generic import of a Curve/Ed25519 private key in PKCS#8 format
|
||||
@param in The packet to import from
|
||||
@param inlen It's length (octets)
|
||||
@param pw_ctx The password context when decrypting the private key
|
||||
@param id The type of the private key
|
||||
@param key [out] Destination for newly imported key
|
||||
@return CRYPT_OK if successful, on error all allocated memory is freed automatically
|
||||
*/
|
||||
int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
|
||||
const password_ctx *pw_ctx,
|
||||
enum ltc_oid_id id,
|
||||
curve25519_key *key)
|
||||
{
|
||||
int err;
|
||||
ltc_asn1_list *l = NULL;
|
||||
ltc_asn1_list *alg_id, *priv_key;
|
||||
enum ltc_oid_id pka;
|
||||
|
||||
LTC_ARGCHK(in != NULL);
|
||||
|
||||
err = pkcs8_decode_flexi(in, inlen, pw_ctx, &l);
|
||||
if (err != CRYPT_OK) return err;
|
||||
|
||||
if ((err = pkcs8_get_children(l, &pka, &alg_id, &priv_key)) != CRYPT_OK) {
|
||||
goto LBL_DER_FREE;
|
||||
}
|
||||
if (pka != id) {
|
||||
err = CRYPT_INVALID_PACKET;
|
||||
goto LBL_DER_FREE;
|
||||
}
|
||||
|
||||
err = ec25519_import_pkcs8_asn1(alg_id, priv_key, id, key);
|
||||
|
||||
LBL_DER_FREE:
|
||||
der_free_sequence_flexi(l);
|
||||
return err;
|
||||
}
|
||||
|
||||
#endif
|
||||
502
Sources/DataLiteC/libtomcrypt/pk/ec25519/tweetnacl.c
Normal file
502
Sources/DataLiteC/libtomcrypt/pk/ec25519/tweetnacl.c
Normal file
@@ -0,0 +1,502 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wconversion"
|
||||
#pragma clang diagnostic ignored "-Wshorten-64-to-32"
|
||||
|
||||
/* automatically generated file, do not edit */
|
||||
|
||||
#define add tnacl_add
|
||||
#define FOR(i,n) for (i = 0;i < n;++i)
|
||||
#define sv static void
|
||||
|
||||
typedef unsigned char u8;
|
||||
typedef ulong32 u32;
|
||||
typedef ulong64 u64;
|
||||
typedef long64 i64;
|
||||
typedef i64 gf[16];
|
||||
|
||||
static const u8
|
||||
nine[32] = {9};
|
||||
static const gf
|
||||
gf0,
|
||||
gf1 = {1},
|
||||
gf121665 = {0xDB41,1},
|
||||
D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
|
||||
D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
|
||||
X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
|
||||
Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
|
||||
I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
|
||||
|
||||
static int vn(const u8 *x,const u8 *y,int n)
|
||||
{
|
||||
int i;
|
||||
u32 d = 0;
|
||||
FOR(i,n) d |= x[i]^y[i];
|
||||
return (1 & ((d - 1) >> 8)) - 1;
|
||||
}
|
||||
|
||||
static int tweetnacl_crypto_verify_32(const u8 *x,const u8 *y)
|
||||
{
|
||||
return vn(x,y,32);
|
||||
}
|
||||
|
||||
sv set25519(gf r, const gf a)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) r[i]=a[i];
|
||||
}
|
||||
|
||||
sv car25519(gf o)
|
||||
{
|
||||
int i;
|
||||
i64 c;
|
||||
FOR(i,16) {
|
||||
o[i]+=(1LL<<16);
|
||||
c=o[i]>>16;
|
||||
o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
|
||||
o[i]-=c<<16;
|
||||
}
|
||||
}
|
||||
|
||||
sv sel25519(gf p,gf q,int b)
|
||||
{
|
||||
i64 t,i,c=~(b-1);
|
||||
FOR(i,16) {
|
||||
t= c&(p[i]^q[i]);
|
||||
p[i]^=t;
|
||||
q[i]^=t;
|
||||
}
|
||||
}
|
||||
|
||||
sv pack25519(u8 *o,const gf n)
|
||||
{
|
||||
int i,j,b;
|
||||
gf m,t;
|
||||
FOR(i,16) t[i]=n[i];
|
||||
car25519(t);
|
||||
car25519(t);
|
||||
car25519(t);
|
||||
FOR(j,2) {
|
||||
m[0]=t[0]-0xffed;
|
||||
for(i=1;i<15;i++) {
|
||||
m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
|
||||
m[i-1]&=0xffff;
|
||||
}
|
||||
m[15]=t[15]-0x7fff-((m[14]>>16)&1);
|
||||
b=(m[15]>>16)&1;
|
||||
m[14]&=0xffff;
|
||||
sel25519(t,m,1-b);
|
||||
}
|
||||
FOR(i,16) {
|
||||
o[2*i]=t[i]&0xff;
|
||||
o[2*i+1]=t[i]>>8;
|
||||
}
|
||||
}
|
||||
|
||||
static int neq25519(const gf a, const gf b)
|
||||
{
|
||||
u8 c[32],d[32];
|
||||
pack25519(c,a);
|
||||
pack25519(d,b);
|
||||
return tweetnacl_crypto_verify_32(c,d);
|
||||
}
|
||||
|
||||
static u8 par25519(const gf a)
|
||||
{
|
||||
u8 d[32];
|
||||
pack25519(d,a);
|
||||
return d[0]&1;
|
||||
}
|
||||
|
||||
sv unpack25519(gf o, const u8 *n)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8);
|
||||
o[15]&=0x7fff;
|
||||
}
|
||||
|
||||
sv A(gf o,const gf a,const gf b)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) o[i]=a[i]+b[i];
|
||||
}
|
||||
|
||||
sv Z(gf o,const gf a,const gf b)
|
||||
{
|
||||
int i;
|
||||
FOR(i,16) o[i]=a[i]-b[i];
|
||||
}
|
||||
|
||||
sv M(gf o,const gf a,const gf b)
|
||||
{
|
||||
i64 i,j,t[31];
|
||||
FOR(i,31) t[i]=0;
|
||||
FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j];
|
||||
FOR(i,15) t[i]+=38*t[i+16];
|
||||
FOR(i,16) o[i]=t[i];
|
||||
car25519(o);
|
||||
car25519(o);
|
||||
}
|
||||
|
||||
sv S(gf o,const gf a)
|
||||
{
|
||||
M(o,a,a);
|
||||
}
|
||||
|
||||
sv inv25519(gf o,const gf i)
|
||||
{
|
||||
gf c;
|
||||
int a;
|
||||
FOR(a,16) c[a]=i[a];
|
||||
for(a=253;a>=0;a--) {
|
||||
S(c,c);
|
||||
if(a!=2&&a!=4) M(c,c,i);
|
||||
}
|
||||
FOR(a,16) o[a]=c[a];
|
||||
}
|
||||
|
||||
sv pow2523(gf o,const gf i)
|
||||
{
|
||||
gf c;
|
||||
int a;
|
||||
FOR(a,16) c[a]=i[a];
|
||||
for(a=250;a>=0;a--) {
|
||||
S(c,c);
|
||||
if(a!=1) M(c,c,i);
|
||||
}
|
||||
FOR(a,16) o[a]=c[a];
|
||||
}
|
||||
|
||||
int tweetnacl_crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
|
||||
{
|
||||
u8 z[32];
|
||||
i64 x[80],r,i;
|
||||
gf a,b,c,d,e,f;
|
||||
FOR(i,31) z[i]=n[i];
|
||||
z[31]=(n[31]&127)|64;
|
||||
z[0]&=248;
|
||||
unpack25519(x,p);
|
||||
FOR(i,16) {
|
||||
b[i]=x[i];
|
||||
d[i]=a[i]=c[i]=0;
|
||||
}
|
||||
a[0]=d[0]=1;
|
||||
for(i=254;i>=0;--i) {
|
||||
r=(z[i>>3]>>(i&7))&1;
|
||||
sel25519(a,b,r);
|
||||
sel25519(c,d,r);
|
||||
A(e,a,c);
|
||||
Z(a,a,c);
|
||||
A(c,b,d);
|
||||
Z(b,b,d);
|
||||
S(d,e);
|
||||
S(f,a);
|
||||
M(a,c,a);
|
||||
M(c,b,e);
|
||||
A(e,a,c);
|
||||
Z(a,a,c);
|
||||
S(b,a);
|
||||
Z(c,d,f);
|
||||
M(a,c,gf121665);
|
||||
A(a,a,d);
|
||||
M(c,c,a);
|
||||
M(a,d,f);
|
||||
M(d,b,x);
|
||||
S(b,e);
|
||||
sel25519(a,b,r);
|
||||
sel25519(c,d,r);
|
||||
}
|
||||
FOR(i,16) {
|
||||
x[i+16]=a[i];
|
||||
x[i+32]=c[i];
|
||||
x[i+48]=b[i];
|
||||
x[i+64]=d[i];
|
||||
}
|
||||
inv25519(x+32,x+32);
|
||||
M(x+16,x+16,x+32);
|
||||
pack25519(q,x+16);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tweetnacl_crypto_scalarmult_base(u8 *q,const u8 *n)
|
||||
{
|
||||
return tweetnacl_crypto_scalarmult(q,n,nine);
|
||||
}
|
||||
|
||||
static LTC_INLINE int tweetnacl_crypto_hash_ctx(u8 *out,const u8 *m,u64 n,const u8 *ctx,u32 cs)
|
||||
{
|
||||
unsigned long len = 64;
|
||||
int hash_idx = find_hash("sha512");
|
||||
|
||||
if (n > ULONG_MAX) return CRYPT_OVERFLOW;
|
||||
|
||||
if(cs == 0)
|
||||
return hash_memory(hash_idx, m, n, out, &len);
|
||||
|
||||
return hash_memory_multi(hash_idx, out, &len, ctx, cs, m, n, LTC_NULL);
|
||||
}
|
||||
|
||||
static LTC_INLINE int tweetnacl_crypto_hash(u8 *out,const u8 *m,u64 n)
|
||||
{
|
||||
return tweetnacl_crypto_hash_ctx(out, m, n, NULL, 0);
|
||||
}
|
||||
|
||||
sv add(gf p[4],gf q[4])
|
||||
{
|
||||
gf a,b,c,d,t,e,f,g,h;
|
||||
|
||||
Z(a, p[1], p[0]);
|
||||
Z(t, q[1], q[0]);
|
||||
M(a, a, t);
|
||||
A(b, p[0], p[1]);
|
||||
A(t, q[0], q[1]);
|
||||
M(b, b, t);
|
||||
M(c, p[3], q[3]);
|
||||
M(c, c, D2);
|
||||
M(d, p[2], q[2]);
|
||||
A(d, d, d);
|
||||
Z(e, b, a);
|
||||
Z(f, d, c);
|
||||
A(g, d, c);
|
||||
A(h, b, a);
|
||||
|
||||
M(p[0], e, f);
|
||||
M(p[1], h, g);
|
||||
M(p[2], g, f);
|
||||
M(p[3], e, h);
|
||||
}
|
||||
|
||||
sv cswap(gf p[4],gf q[4],u8 b)
|
||||
{
|
||||
int i;
|
||||
FOR(i,4)
|
||||
sel25519(p[i],q[i],b);
|
||||
}
|
||||
|
||||
sv pack(u8 *r,gf p[4])
|
||||
{
|
||||
gf tx, ty, zi;
|
||||
inv25519(zi, p[2]);
|
||||
M(tx, p[0], zi);
|
||||
M(ty, p[1], zi);
|
||||
pack25519(r, ty);
|
||||
r[31] ^= par25519(tx) << 7;
|
||||
}
|
||||
|
||||
sv scalarmult(gf p[4],gf q[4],const u8 *s)
|
||||
{
|
||||
int i;
|
||||
set25519(p[0],gf0);
|
||||
set25519(p[1],gf1);
|
||||
set25519(p[2],gf1);
|
||||
set25519(p[3],gf0);
|
||||
for (i = 255;i >= 0;--i) {
|
||||
u8 b = (s[i/8]>>(i&7))&1;
|
||||
cswap(p,q,b);
|
||||
add(q,p);
|
||||
add(p,p);
|
||||
cswap(p,q,b);
|
||||
}
|
||||
}
|
||||
|
||||
sv scalarbase(gf p[4],const u8 *s)
|
||||
{
|
||||
gf q[4];
|
||||
set25519(q[0],X);
|
||||
set25519(q[1],Y);
|
||||
set25519(q[2],gf1);
|
||||
M(q[3],X,Y);
|
||||
scalarmult(p,q,s);
|
||||
}
|
||||
|
||||
int tweetnacl_crypto_sk_to_pk(u8 *pk, const u8 *sk)
|
||||
{
|
||||
u8 d[64];
|
||||
gf p[4];
|
||||
tweetnacl_crypto_hash(d, sk, 32);
|
||||
d[0] &= 248;
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
|
||||
scalarbase(p,d);
|
||||
pack(pk,p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, u8 *pk, u8 *sk)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* randombytes(sk,32); */
|
||||
if ((err = prng_is_valid(wprng)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
if (prng_descriptor[wprng].read(sk,32, prng) != 32) {
|
||||
return CRYPT_ERROR_READPRNG;
|
||||
}
|
||||
|
||||
if ((err = tweetnacl_crypto_sk_to_pk(pk, sk)) != CRYPT_OK) {
|
||||
return err;
|
||||
}
|
||||
|
||||
/* FOR(i,32) sk[32 + i] = pk[i];
|
||||
* we don't copy the pk in the sk */
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
|
||||
|
||||
sv modL(u8 *r,i64 x[64])
|
||||
{
|
||||
i64 carry,i,j;
|
||||
for (i = 63;i >= 32;--i) {
|
||||
carry = 0;
|
||||
for (j = i - 32;j < i - 12;++j) {
|
||||
x[j] += carry - 16 * x[i] * L[j - (i - 32)];
|
||||
carry = (x[j] + 128) >> 8;
|
||||
x[j] -= carry << 8;
|
||||
}
|
||||
x[j] += carry;
|
||||
x[i] = 0;
|
||||
}
|
||||
carry = 0;
|
||||
FOR(j,32) {
|
||||
x[j] += carry - (x[31] >> 4) * L[j];
|
||||
carry = x[j] >> 8;
|
||||
x[j] &= 255;
|
||||
}
|
||||
FOR(j,32) x[j] -= carry * L[j];
|
||||
FOR(i,32) {
|
||||
x[i+1] += x[i] >> 8;
|
||||
r[i] = x[i] & 255;
|
||||
}
|
||||
}
|
||||
|
||||
sv reduce(u8 *r)
|
||||
{
|
||||
i64 x[64],i;
|
||||
FOR(i,64) x[i] = (u64) r[i];
|
||||
FOR(i,64) r[i] = 0;
|
||||
modL(r,x);
|
||||
}
|
||||
|
||||
int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,const u8 *pk, const u8 *ctx, u64 cs)
|
||||
{
|
||||
u8 d[64],h[64],r[64];
|
||||
i64 i,j,x[64];
|
||||
gf p[4];
|
||||
|
||||
tweetnacl_crypto_hash(d, sk, 32);
|
||||
d[0] &= 248;
|
||||
d[31] &= 127;
|
||||
d[31] |= 64;
|
||||
|
||||
*smlen = mlen+64;
|
||||
FOR(i,(i64)mlen) sm[64 + i] = m[i];
|
||||
FOR(i,32) sm[32 + i] = d[32 + i];
|
||||
|
||||
tweetnacl_crypto_hash_ctx(r, sm+32, mlen+32,ctx,cs);
|
||||
reduce(r);
|
||||
scalarbase(p,r);
|
||||
pack(sm,p);
|
||||
|
||||
FOR(i,32) sm[i+32] = pk[i];
|
||||
tweetnacl_crypto_hash_ctx(h,sm,mlen + 64,ctx,cs);
|
||||
reduce(h);
|
||||
|
||||
FOR(i,64) x[i] = 0;
|
||||
FOR(i,32) x[i] = (u64) r[i];
|
||||
FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j];
|
||||
modL(sm + 32,x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int unpackneg(gf r[4],const u8 p[32])
|
||||
{
|
||||
gf t, chk, num, den, den2, den4, den6;
|
||||
set25519(r[2],gf1);
|
||||
unpack25519(r[1],p);
|
||||
S(num,r[1]);
|
||||
M(den,num,D);
|
||||
Z(num,num,r[2]);
|
||||
A(den,r[2],den);
|
||||
|
||||
S(den2,den);
|
||||
S(den4,den2);
|
||||
M(den6,den4,den2);
|
||||
M(t,den6,num);
|
||||
M(t,t,den);
|
||||
|
||||
pow2523(t,t);
|
||||
M(t,t,num);
|
||||
M(t,t,den);
|
||||
M(t,t,den);
|
||||
M(r[0],t,den);
|
||||
|
||||
S(chk,r[0]);
|
||||
M(chk,chk,den);
|
||||
if (neq25519(chk, num)) M(r[0],r[0],I);
|
||||
|
||||
S(chk,r[0]);
|
||||
M(chk,chk,den);
|
||||
if (neq25519(chk, num)) return -1;
|
||||
|
||||
if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
|
||||
|
||||
M(r[3],r[0],r[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen,const u8 *ctx,u64 cs,const u8 *pk)
|
||||
{
|
||||
u64 i;
|
||||
u8 s[32],t[32],h[64];
|
||||
gf p[4],q[4];
|
||||
|
||||
*stat = 0;
|
||||
if (*mlen < smlen) return CRYPT_BUFFER_OVERFLOW;
|
||||
*mlen = -1;
|
||||
if (smlen < 64) return CRYPT_INVALID_ARG;
|
||||
|
||||
if (unpackneg(q,pk)) return CRYPT_ERROR;
|
||||
|
||||
XMEMMOVE(m,sm,smlen);
|
||||
XMEMMOVE(s,m + 32,32);
|
||||
XMEMMOVE(m + 32,pk,32);
|
||||
tweetnacl_crypto_hash_ctx(h,m,smlen,ctx,cs);
|
||||
reduce(h);
|
||||
scalarmult(p,q,h);
|
||||
|
||||
scalarbase(q,s);
|
||||
add(p,q);
|
||||
pack(t,p);
|
||||
|
||||
smlen -= 64;
|
||||
if (tweetnacl_crypto_verify_32(sm, t)) {
|
||||
FOR(i,smlen) m[i] = 0;
|
||||
zeromem(m, smlen);
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
*stat = 1;
|
||||
XMEMMOVE(m,m + 64,smlen);
|
||||
*mlen = smlen;
|
||||
return CRYPT_OK;
|
||||
}
|
||||
|
||||
int tweetnacl_crypto_ph(u8 *out,const u8 *msg,u64 msglen)
|
||||
{
|
||||
return tweetnacl_crypto_hash(out, msg, msglen);
|
||||
}
|
||||
|
||||
#undef add
|
||||
#undef FOR
|
||||
#undef sv
|
||||
|
||||
#pragma clang diagnostic pop
|
||||
435
Sources/DataLiteC/libtomcrypt/pk/ecc/ecc.c
Normal file
435
Sources/DataLiteC/libtomcrypt/pk/ecc/ecc.c
Normal file
@@ -0,0 +1,435 @@
|
||||
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
|
||||
/* SPDX-License-Identifier: Unlicense */
|
||||
|
||||
#include "tomcrypt_private.h"
|
||||
|
||||
/**
|
||||
@file ecc.c
|
||||
ECC Crypto, Tom St Denis
|
||||
*/
|
||||
|
||||
#ifdef LTC_MECC
|
||||
|
||||
/* This array holds the curve parameters.
|
||||
* Curves (prime field only) are taken from:
|
||||
* - http://www.secg.org/collateral/sec2_final.pdf (named: SECP*)
|
||||
* - http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf (named: NISTP*)
|
||||
* - ANS X9.62 (named: PRIMEP*)
|
||||
* - http://www.ecc-brainpool.org/download/Domain-parameters.pdf (named: BRAINPOOLP*)
|
||||
*/
|
||||
const ltc_ecc_curve ltc_ecc_curves[] = {
|
||||
#ifdef LTC_ECC_SECP112R1
|
||||
{
|
||||
/* prime */ "DB7C2ABF62E35E668076BEAD208B",
|
||||
/* A */ "DB7C2ABF62E35E668076BEAD2088",
|
||||
/* B */ "659EF8BA043916EEDE8911702B22",
|
||||
/* order */ "DB7C2ABF62E35E7628DFAC6561C5",
|
||||
/* Gx */ "09487239995A5EE76B55F9C2F098",
|
||||
/* Gy */ "A89CE5AF8724C0A23E0E0FF77500",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.6"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP112R2
|
||||
{
|
||||
/* prime */ "DB7C2ABF62E35E668076BEAD208B",
|
||||
/* A */ "6127C24C05F38A0AAAF65C0EF02C",
|
||||
/* B */ "51DEF1815DB5ED74FCC34C85D709",
|
||||
/* order */ "36DF0AAFD8B8D7597CA10520D04B",
|
||||
/* Gx */ "4BA30AB5E892B4E1649DD0928643",
|
||||
/* Gy */ "ADCD46F5882E3747DEF36E956E97",
|
||||
/* cofactor */ 4,
|
||||
/* OID */ "1.3.132.0.7"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP128R1
|
||||
{
|
||||
/* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
/* A */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
|
||||
/* B */ "E87579C11079F43DD824993C2CEE5ED3",
|
||||
/* order */ "FFFFFFFE0000000075A30D1B9038A115",
|
||||
/* Gx */ "161FF7528B899B2D0C28607CA52C5B86",
|
||||
/* Gy */ "CF5AC8395BAFEB13C02DA292DDED7A83",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.28"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP128R2
|
||||
{
|
||||
/* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
/* A */ "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
|
||||
/* B */ "5EEEFCA380D02919DC2C6558BB6D8A5D",
|
||||
/* order */ "3FFFFFFF7FFFFFFFBE0024720613B5A3",
|
||||
/* Gx */ "7B6AA5D85E572983E6FB32A7CDEBC140",
|
||||
/* Gy */ "27B6916A894D3AEE7106FE805FC34B44",
|
||||
/* cofactor */ 4,
|
||||
/* OID */ "1.3.132.0.29"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP160R1
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
|
||||
/* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
|
||||
/* B */ "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
|
||||
/* order */ "0100000000000000000001F4C8F927AED3CA752257",
|
||||
/* Gx */ "4A96B5688EF573284664698968C38BB913CBFC82",
|
||||
/* Gy */ "23A628553168947D59DCC912042351377AC5FB32",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.8"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP160R2
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
|
||||
/* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
|
||||
/* B */ "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
|
||||
/* order */ "0100000000000000000000351EE786A818F3A1A16B",
|
||||
/* Gx */ "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
|
||||
/* Gy */ "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.30"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP160K1
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
|
||||
/* A */ "0000000000000000000000000000000000000000",
|
||||
/* B */ "0000000000000000000000000000000000000007",
|
||||
/* order */ "0100000000000000000001B8FA16DFAB9ACA16B6B3",
|
||||
/* Gx */ "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
|
||||
/* Gy */ "938CF935318FDCED6BC28286531733C3F03C4FEE",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.9"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP192R1
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
|
||||
/* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
|
||||
/* B */ "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
|
||||
/* order */ "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
|
||||
/* Gx */ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
|
||||
/* Gy */ "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.2.840.10045.3.1.1"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_PRIME192V2
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
|
||||
/* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
|
||||
/* B */ "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
|
||||
/* order */ "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",
|
||||
/* Gx */ "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
|
||||
/* Gy */ "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.2.840.10045.3.1.2"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_PRIME192V3
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
|
||||
/* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
|
||||
/* B */ "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
|
||||
/* order */ "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",
|
||||
/* Gx */ "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
|
||||
/* Gy */ "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.2.840.10045.3.1.3"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP192K1
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
|
||||
/* A */ "000000000000000000000000000000000000000000000000",
|
||||
/* B */ "000000000000000000000000000000000000000000000003",
|
||||
/* order */ "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",
|
||||
/* Gx */ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
|
||||
/* Gy */ "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.31"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP224R1
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
|
||||
/* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
|
||||
/* B */ "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
|
||||
/* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
|
||||
/* Gx */ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
|
||||
/* Gy */ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.33"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP224K1
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
|
||||
/* A */ "00000000000000000000000000000000000000000000000000000000",
|
||||
/* B */ "00000000000000000000000000000000000000000000000000000005",
|
||||
/* order */ "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",
|
||||
/* Gx */ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
|
||||
/* Gy */ "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.32"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP256R1
|
||||
{
|
||||
/* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
/* A */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
|
||||
/* B */ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
|
||||
/* order */ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
|
||||
/* Gx */ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
|
||||
/* Gy */ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.2.840.10045.3.1.7"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP256K1
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
|
||||
/* A */ "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
/* B */ "0000000000000000000000000000000000000000000000000000000000000007",
|
||||
/* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
|
||||
/* Gx */ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
|
||||
/* Gy */ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.10"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP384R1
|
||||
{
|
||||
/* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
|
||||
/* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
|
||||
/* B */ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
|
||||
/* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
|
||||
/* Gx */ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
|
||||
/* Gy */ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.34"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_SECP521R1
|
||||
{
|
||||
/* prime */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
||||
/* A */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
|
||||
/* B */ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
|
||||
/* order */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
|
||||
/* Gx */ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
|
||||
/* Gy */ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.132.0.35"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_PRIME239V1
|
||||
{
|
||||
/* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
|
||||
/* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
|
||||
/* B */ "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
|
||||
/* order */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",
|
||||
/* Gx */ "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
|
||||
/* Gy */ "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.2.840.10045.3.1.4"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_PRIME239V2
|
||||
{
|
||||
/* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
|
||||
/* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
|
||||
/* B */ "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
|
||||
/* order */ "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",
|
||||
/* Gx */ "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
|
||||
/* Gy */ "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.2.840.10045.3.1.5"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_PRIME239V3
|
||||
{
|
||||
/* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
|
||||
/* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
|
||||
/* B */ "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
|
||||
/* order */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",
|
||||
/* Gx */ "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
|
||||
/* Gy */ "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.2.840.10045.3.1.6"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP160R1
|
||||
{
|
||||
/* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
|
||||
/* A */ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
|
||||
/* B */ "1E589A8595423412134FAA2DBDEC95C8D8675E58",
|
||||
/* order */ "E95E4A5F737059DC60DF5991D45029409E60FC09",
|
||||
/* Gx */ "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
|
||||
/* Gy */ "1667CB477A1A8EC338F94741669C976316DA6321",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.1"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP192R1
|
||||
{
|
||||
/* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
|
||||
/* A */ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
|
||||
/* B */ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
|
||||
/* order */ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
|
||||
/* Gx */ "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
|
||||
/* Gy */ "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.3"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP224R1
|
||||
{
|
||||
/* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
|
||||
/* A */ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
|
||||
/* B */ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
|
||||
/* order */ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
|
||||
/* Gx */ "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
|
||||
/* Gy */ "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.5"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP256R1
|
||||
{
|
||||
/* prime */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
|
||||
/* A */ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
|
||||
/* B */ "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
|
||||
/* order */ "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
|
||||
/* Gx */ "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
|
||||
/* Gy */ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.7"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP320R1
|
||||
{
|
||||
/* prime */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
|
||||
/* A */ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
|
||||
/* B */ "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
|
||||
/* order */ "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
|
||||
/* Gx */ "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
|
||||
/* Gy */ "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.9"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP384R1
|
||||
{
|
||||
/* prime */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
|
||||
/* A */ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
|
||||
/* B */ "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
|
||||
/* order */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
|
||||
/* Gx */ "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
|
||||
/* Gy */ "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.11"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP512R1
|
||||
{
|
||||
/* prime */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
|
||||
/* A */ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
|
||||
/* B */ "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
|
||||
/* order */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
|
||||
/* Gx */ "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
|
||||
/* Gy */ "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.13"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP160T1
|
||||
{
|
||||
/* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
|
||||
/* A */ "E95E4A5F737059DC60DFC7AD95B3D8139515620C",
|
||||
/* B */ "7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380",
|
||||
/* order */ "E95E4A5F737059DC60DF5991D45029409E60FC09",
|
||||
/* Gx */ "B199B13B9B34EFC1397E64BAEB05ACC265FF2378",
|
||||
/* Gy */ "ADD6718B7C7C1961F0991B842443772152C9E0AD",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.2"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP192T1
|
||||
{
|
||||
/* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
|
||||
/* A */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294",
|
||||
/* B */ "13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79",
|
||||
/* order */ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
|
||||
/* Gx */ "3AE9E58C82F63C30282E1FE7BBF43FA72C446AF6F4618129",
|
||||
/* Gy */ "097E2C5667C2223A902AB5CA449D0084B7E5B3DE7CCC01C9",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.4"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP224T1
|
||||
{
|
||||
/* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
|
||||
/* A */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC",
|
||||
/* B */ "4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D",
|
||||
/* order */ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
|
||||
/* Gx */ "6AB1E344CE25FF3896424E7FFE14762ECB49F8928AC0C76029B4D580",
|
||||
/* Gy */ "0374E9F5143E568CD23F3F4D7C0D4B1E41C8CC0D1C6ABD5F1A46DB4C",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.6"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP256T1
|
||||
{
|
||||
/* prime */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
|
||||
/* A */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374",
|
||||
/* B */ "662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04",
|
||||
/* order */ "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
|
||||
/* Gx */ "A3E8EB3CC1CFE7B7732213B23A656149AFA142C47AAFBC2B79A191562E1305F4",
|
||||
/* Gy */ "2D996C823439C56D7F7B22E14644417E69BCB6DE39D027001DABE8F35B25C9BE",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.8"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP320T1
|
||||
{
|
||||
/* prime */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
|
||||
/* A */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24",
|
||||
/* B */ "A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353",
|
||||
/* order */ "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
|
||||
/* Gx */ "925BE9FB01AFC6FB4D3E7D4990010F813408AB106C4F09CB7EE07868CC136FFF3357F624A21BED52",
|
||||
/* Gy */ "63BA3A7A27483EBF6671DBEF7ABB30EBEE084E58A0B077AD42A5A0989D1EE71B1B9BC0455FB0D2C3",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.10"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP384T1
|
||||
{
|
||||
/* prime */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
|
||||
/* A */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50",
|
||||
/* B */ "7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE",
|
||||
/* order */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
|
||||
/* Gx */ "18DE98B02DB9A306F2AFCD7235F72A819B80AB12EBD653172476FECD462AABFFC4FF191B946A5F54D8D0AA2F418808CC",
|
||||
/* Gy */ "25AB056962D30651A114AFD2755AD336747F93475B7A1FCA3B88F2B6A208CCFE469408584DC2B2912675BF5B9E582928",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.12"
|
||||
},
|
||||
#endif
|
||||
#ifdef LTC_ECC_BRAINPOOLP512T1
|
||||
{
|
||||
/* prime */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
|
||||
/* A */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0",
|
||||
/* B */ "7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E",
|
||||
/* order */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
|
||||
/* Gx */ "640ECE5C12788717B9C1BA06CBC2A6FEBA85842458C56DDE9DB1758D39C0313D82BA51735CDB3EA499AA77A7D6943A64F7A3F25FE26F06B51BAA2696FA9035DA",
|
||||
/* Gy */ "5B534BD595F5AF0FA2C892376C84ACE1BB4E3019B71634C01131159CAE03CEE9D9932184BEEF216BD71DF2DADF86A627306ECFF96DBB8BACE198B61E00F8B332",
|
||||
/* cofactor */ 1,
|
||||
/* OID */ "1.3.36.3.3.2.8.1.1.14"
|
||||
},
|
||||
#endif
|
||||
{
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user