Skip to content

Commit

Permalink
Refactor some of the ECC import internals
Browse files Browse the repository at this point in the history
Signed-off-by: Steffen Jaeckel <[email protected]>
  • Loading branch information
sjaeckel committed Oct 10, 2023
1 parent 236ef08 commit 4afb4dd
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 103 deletions.
2 changes: 2 additions & 0 deletions src/headers/tomcrypt_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,8 @@ int ecc_copy_curve(const ecc_key *srckey, ecc_key *key);
int ecc_set_curve_by_size(int size, ecc_key *key);
int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long inlen, ecc_key *key);
int ecc_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, ecc_key *key);
int ecc_import_with_curve(const unsigned char *in, unsigned long inlen, int type, ecc_key *key);
int ecc_import_with_oid(const unsigned char *in, unsigned long inlen, unsigned long *oid, unsigned long oid_len, int type, ecc_key *key);

#ifdef LTC_SSH
int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key);
Expand Down
96 changes: 59 additions & 37 deletions src/pk/ecc/ecc_import_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ static int s_ecc_import_private_with_oid(const unsigned char *in, unsigned long
{
ltc_asn1_list seq_priv[4], custom[2];
unsigned char bin_xy[2*ECC_MAXSIZE+2], bin_k[ECC_MAXSIZE];
unsigned long len, pkver = 0, curveoid[16];
char OID[256];
const ltc_ecc_curve *curve;
unsigned long pkver = 0, curveoid[16];
int err;

/* ### try to load private key - no curve parameters just curve OID */
Expand All @@ -26,50 +24,44 @@ static int s_ecc_import_private_with_oid(const unsigned char *in, unsigned long

/* try to load private key */
err = der_decode_sequence(in, inlen, seq_priv, 4);
if (err == CRYPT_OK) {
/* load curve parameters for given curve OID */
len = sizeof(OID);
if ((err = pk_oid_num_to_str(curveoid, custom[0].size, OID, &len)) != CRYPT_OK) { goto error; }
if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto error; }
if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto error; }
/* load private+public key */
err = ecc_set_key(bin_k, seq_priv[1].size, PK_PRIVATE, key);
}
if (err != CRYPT_OK) { goto error; }
err = ecc_import_with_oid(bin_k, seq_priv[1].size, curveoid, custom[0].size, PK_PRIVATE, key);
error:
return err;
}

static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned long inlen, ecc_key *key)
int ecc_import_with_oid(const unsigned char *in, unsigned long inlen, unsigned long *oid, unsigned long oid_len, int type, ecc_key *key)
{
char OID[256];
unsigned long len;
const ltc_ecc_curve *curve;
int err;

/* load curve parameters for given curve OID */
len = sizeof(OID);
if ((err = pk_oid_num_to_str(oid, oid_len, OID, &len)) != CRYPT_OK) { goto error; }
if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto error; }
if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto error; }
/* load public key */
err = ecc_set_key(in, inlen, type, key);
error:
return err;
}

int ecc_import_with_curve(const unsigned char *in, unsigned long inlen, int type, ecc_key *key)
{
void *prime, *order, *a, *b, *gx, *gy;
ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4], custom[2];
unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE];
unsigned char bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128];
unsigned long len_a, len_b, len_k, len_g;
unsigned long len_a, len_b, len_k, len_g, len_xy, len;
unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16];
int err;

if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, LTC_NULL)) != CRYPT_OK) {
return err;
}

/* ### try to load private key - curve parameters included */

/* ECPrivateKey SEQUENCE */
LTC_SET_ASN1(custom, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8UL*sizeof(bin_xy));
LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL);
LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, sizeof(bin_k));
LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */
LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */
/* ECParameters SEQUENCE */
LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, sizeof(bin_g));
LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
seq_ecparams[5].optional = 1;
/* FieldID SEQUENCE */
LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
Expand All @@ -78,10 +70,33 @@ static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned lon
LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, sizeof(bin_b));
LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, 8UL*sizeof(bin_seed));
seq_curve[2].optional = 1;
/* try to load private key */
err = der_decode_sequence(in, inlen, seq_priv, 4);
/* ECParameters SEQUENCE */
LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, sizeof(bin_g));
LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
seq_ecparams[5].optional = 1;
if (type == PK_PRIVATE) {
/* ECPrivateKey SEQUENCE */
LTC_SET_ASN1(custom, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
LTC_SET_ASN1(custom, 1, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8UL*sizeof(bin_xy));
LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL);
LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, sizeof(bin_k));
LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 2, LTC_ASN1_CL_CONTEXT_SPECIFIC, 0, custom); /* context specific 0 */
LTC_SET_ASN1_CUSTOM_CONSTRUCTED(seq_priv, 3, LTC_ASN1_CL_CONTEXT_SPECIFIC, 1, custom + 1); /* context specific 1 */
/* try to load private key */
err = der_decode_sequence(in, inlen, seq_priv, 4);
} else if (type == PK_PUBLIC) {
/* try to load public key */
len_xy = sizeof(bin_xy);
len = 6;
err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, &len);
} else {
err = CRYPT_PK_INVALID_TYPE;
}
if (err == CRYPT_OK) {
len_k = seq_priv[1].size;
len_a = seq_curve[0].size;
len_b = seq_curve[1].size;
len_g = seq_ecparams[3].size;
Expand All @@ -91,8 +106,15 @@ static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned lon
if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
/* load curve parameters */
if ((err = ecc_set_curve_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; }
/* load private+public key */
err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key);

if (type == PK_PRIVATE) {
len_k = seq_priv[1].size;
/* load private+public key */
err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key);
} else {
/* load public key */
err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key);
}
}
error:
mp_clear_multi(prime, order, a, b, gx, gy, LTC_NULL);
Expand All @@ -111,7 +133,7 @@ int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *ke
goto success;
}

err = s_ecc_import_private_with_curve(in, inlen, key);
err = ecc_import_with_curve(in, inlen, PK_PRIVATE, key);

success:
return err;
Expand Down
70 changes: 4 additions & 66 deletions src/pk/ecc/ecc_import_x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,78 +8,16 @@ static int s_ecc_import_x509_with_oid(const unsigned char *in, unsigned long inl
{
unsigned char bin_xy[2*ECC_MAXSIZE+2];
unsigned long curveoid[16];
unsigned long len_xy, len_oid, len;
char OID[256];
const ltc_ecc_curve *curve;
unsigned long len_xy, len_oid;
int err;

len_xy = sizeof(bin_xy);
len_oid = 16;
err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_EC, bin_xy, &len_xy,
LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid);
if (err == CRYPT_OK) {
/* load curve parameters for given curve OID */
len = sizeof(OID);
if ((err = pk_oid_num_to_str(curveoid, len_oid, OID, &len)) != CRYPT_OK) { goto error; }
if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto error; }
if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto error; }
/* load public key */
err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key);
}
error:
return err;
}

static int s_ecc_import_x509_with_curve(const unsigned char *in, unsigned long inlen, ecc_key *key)
{
void *prime, *order, *a, *b, *gx, *gy;
ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6];
unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE];
unsigned char bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128];
unsigned long len_a, len_b, len_g, len_xy, len;
unsigned long cofactor = 0, ecver = 0, tmpoid[16];
int err;

if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, LTC_NULL)) != CRYPT_OK) {
return err;
}

/* ECParameters SEQUENCE */
LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, sizeof(bin_g));
LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
seq_ecparams[5].optional = 1;
/* FieldID SEQUENCE */
LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
/* Curve SEQUENCE */
LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, sizeof(bin_a));
LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, sizeof(bin_b));
LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, 8u*sizeof(bin_seed));
seq_curve[2].optional = 1;
/* try to load public key */
len_xy = sizeof(bin_xy);
len = 6;
err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, &len);

if (err == CRYPT_OK) {
len_a = seq_curve[0].size;
len_b = seq_curve[1].size;
len_g = seq_ecparams[3].size;
/* create bignums */
if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; }
if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; }
if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
/* load curve parameters */
if ((err = ecc_set_curve_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; }
/* load public key */
err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key);
}
if (err != CRYPT_OK) { goto error; }
err = ecc_import_with_oid(bin_xy, len_xy, curveoid, len_oid, PK_PUBLIC, key);
error:
mp_clear_multi(prime, order, a, b, gx, gy, LTC_NULL);
return err;
}

Expand All @@ -91,7 +29,7 @@ int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long in
goto success;
}

err = s_ecc_import_x509_with_curve(in, inlen, key);
err = ecc_import_with_curve(in, inlen, PK_PUBLIC, key);

success:
return err;
Expand Down

0 comments on commit 4afb4dd

Please sign in to comment.