diff --git a/doc/crypt.tex b/doc/crypt.tex index b24332f55..96c08c1f1 100644 --- a/doc/crypt.tex +++ b/doc/crypt.tex @@ -7385,14 +7385,16 @@ \subsection{The PKA Union} LTC_PKA_RSA, LTC_PKA_DSA, LTC_PKA_EC, - LTC_PKA_CURVE25519, + LTC_PKA_X25519, + LTC_PKA_ED25519, LTC_PKA_DH, }; typedef struct { union { #ifdef LTC_CURVE25519 - curve25519_key curve25519; + curve25519_key x25519; + curve25519_key ed25519; #endif #ifdef LTC_MDH dh_key dh; diff --git a/src/headers/tomcrypt_pk.h b/src/headers/tomcrypt_pk.h index 68907a368..440c3e120 100644 --- a/src/headers/tomcrypt_pk.h +++ b/src/headers/tomcrypt_pk.h @@ -22,6 +22,16 @@ typedef struct { /* ---- NUMBER THEORY ---- */ +enum ltc_pka_id { + LTC_PKA_UNDEF = 0, + LTC_PKA_RSA, + LTC_PKA_DSA, + LTC_PKA_EC, + LTC_PKA_X25519, + LTC_PKA_ED25519, + LTC_PKA_DH, +}; + enum public_key_type { /* Refers to the public key */ PK_PUBLIC = 0x0000, @@ -347,12 +357,8 @@ typedef struct { /** The key type, PK_PRIVATE or PK_PUBLIC */ enum public_key_type type; - /** The PK-algorithm, PKA_ED25519 or PKA_X25519 */ - /** This was supposed to be: - * enum public_key_algorithms algo; - * but that enum is now in tomcrypt_private.h - */ - int algo; + /** The PK-algorithm, LTC_PKA_ED25519 or LTC_PKA_X25519 */ + enum ltc_pka_id pka; /** The private key */ unsigned char priv[32]; @@ -511,19 +517,11 @@ int dsa_shared_secret(void *private_key, void *base, * LibTomCrypt Public Key Algorithm descriptor */ -enum ltc_pka_id { - LTC_PKA_UNDEF = 0, - LTC_PKA_RSA, - LTC_PKA_DSA, - LTC_PKA_EC, - LTC_PKA_CURVE25519, - LTC_PKA_DH, -}; - typedef struct { union { #ifdef LTC_CURVE25519 - curve25519_key curve25519; + curve25519_key x25519; + curve25519_key ed25519; #endif #ifdef LTC_MDH dh_key dh; diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index afff95be9..1c14c87c5 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -32,6 +32,7 @@ enum ltc_oid_id { LTC_OID_X25519, LTC_OID_ED25519, LTC_OID_DH, + LTC_OID_NUM }; /* @@ -324,6 +325,8 @@ int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng); int rand_bn_upto(void *N, void *limit, prng_state *prng, int wprng); int pk_get_oid(enum ltc_oid_id id, const char **st); +int pk_get_pka_id(enum ltc_oid_id id, enum ltc_pka_id *pka); +int pk_get_oid_id(enum ltc_pka_id pka, enum ltc_oid_id *oid); int pk_get_oid_from_asn1(const ltc_asn1_list *oid, enum ltc_oid_id *id); int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen); int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen); diff --git a/src/misc/pem/pem_pkcs.c b/src/misc/pem/pem_pkcs.c index 1dfaa7c92..9b634bc78 100644 --- a/src/misc/pem/pem_pkcs.c +++ b/src/misc/pem/pem_pkcs.c @@ -122,13 +122,13 @@ static int s_decode(struct get_char *g, ltc_pka_key *k, const password_ctx *pw_c break; #endif #ifdef LTC_CURVE25519 - case LTC_OID_ED25519: - err = ed25519_import_pkcs8_asn1(alg_id, priv_key, &k->u.curve25519); - k->id = LTC_PKA_CURVE25519; - break; case LTC_OID_X25519: - err = x25519_import_pkcs8_asn1(alg_id, priv_key, &k->u.curve25519); - k->id = LTC_PKA_CURVE25519; + err = x25519_import_pkcs8_asn1(alg_id, priv_key, &k->u.x25519); + k->id = LTC_PKA_X25519; + break; + case LTC_OID_ED25519: + err = ed25519_import_pkcs8_asn1(alg_id, priv_key, &k->u.ed25519); + k->id = LTC_PKA_ED25519; break; #endif default: diff --git a/src/misc/pem/pem_ssh.c b/src/misc/pem/pem_ssh.c index cf6a4bc41..64ad5b4df 100644 --- a/src/misc/pem/pem_ssh.c +++ b/src/misc/pem/pem_ssh.c @@ -96,11 +96,11 @@ int ssh_decode_ed25519(const unsigned char *in, unsigned long *inlen, ltc_pka_ke goto cleanup; } - if ((err = ed25519_import_raw(&privkey[32], 32, PK_PRIVATE, &key->u.curve25519)) != CRYPT_OK) { + if ((err = ed25519_import_raw(&privkey[32], 32, PK_PRIVATE, &key->u.ed25519)) != CRYPT_OK) { goto cleanup; } - key->id = LTC_PKA_CURVE25519; + key->id = LTC_PKA_ED25519; cleanup: zeromem(pubkey, sizeof(pubkey)); diff --git a/src/pk/asn1/oid/pk_get.c b/src/pk/asn1/oid/pk_get.c index 4d00d3d69..48a8a9840 100644 --- a/src/pk/asn1/oid/pk_get.c +++ b/src/pk/asn1/oid/pk_get.c @@ -11,26 +11,64 @@ typedef struct { } 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_CURVE25519, "1.3.101.110" }, - { LTC_OID_ED25519, LTC_PKA_CURVE25519, "1.3.101.112" }, + { 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) { - unsigned int i; + const oid_table_entry* e = s_get_entry(id); LTC_ARGCHK(st != NULL); - for (i = 0; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) { - if (pka_oids[i].id == id) { - *st = pka_oids[i].oid; + 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; } } @@ -57,7 +95,7 @@ int pk_get_oid_from_asn1(const ltc_asn1_list *oid, enum ltc_oid_id *id) return err; } - for (i = 0; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) { + 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; diff --git a/src/pk/ec25519/ec25519_export.c b/src/pk/ec25519/ec25519_export.c index 42f4c4b5d..a6dba677b 100644 --- a/src/pk/ec25519/ec25519_export.c +++ b/src/pk/ec25519/ec25519_export.c @@ -25,6 +25,7 @@ int ec25519_export( unsigned char *out, unsigned long *outlen, 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); @@ -34,12 +35,15 @@ int ec25519_export( unsigned char *out, unsigned long *outlen, 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(key->algo, &OID)) != CRYPT_OK) { + if ((err = pk_get_oid(oid_id, &OID)) != CRYPT_OK) { return err; } oidlen = sizeof(oid)/sizeof(oid[0]); @@ -72,7 +76,7 @@ int ec25519_export( unsigned char *out, unsigned long *outlen, } else { if (std == PK_STD) { /* encode public key as SubjectPublicKeyInfo */ - err = x509_encode_subject_public_key_info(out, outlen, key->algo, key->pub, 32uL, LTC_ASN1_EOL, NULL, 0); + 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; diff --git a/src/pk/ec25519/ec25519_import_pkcs8.c b/src/pk/ec25519/ec25519_import_pkcs8.c index fa417bc90..4a7f9fb9f 100644 --- a/src/pk/ec25519/ec25519_import_pkcs8.c +++ b/src/pk/ec25519/ec25519_import_pkcs8.c @@ -39,7 +39,7 @@ int ec25519_import_pkcs8_asn1(ltc_asn1_list *alg_id, ltc_asn1_list *priv_key, 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; - key->algo = id; + err = pk_get_pka_id(id, &key->pka); } return err; } diff --git a/src/pk/ed25519/ed25519_export.c b/src/pk/ed25519/ed25519_export.c index 2b710e58d..5ec68eb2e 100644 --- a/src/pk/ed25519/ed25519_export.c +++ b/src/pk/ed25519/ed25519_export.c @@ -23,7 +23,7 @@ int ed25519_export( unsigned char *out, unsigned long *outlen, { LTC_ARGCHK(key != NULL); - if (key->algo != LTC_OID_ED25519) return CRYPT_PK_INVALID_TYPE; + if (key->pka != LTC_PKA_ED25519) return CRYPT_PK_INVALID_TYPE; return ec25519_export(out, outlen, which, key); } diff --git a/src/pk/ed25519/ed25519_import.c b/src/pk/ed25519/ed25519_import.c index f197d59dc..634780c4f 100644 --- a/src/pk/ed25519/ed25519_import.c +++ b/src/pk/ed25519/ed25519_import.c @@ -27,7 +27,7 @@ int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key key_len = sizeof(key->pub); if ((err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_ED25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) { key->type = PK_PUBLIC; - key->algo = LTC_OID_ED25519; + key->pka = LTC_PKA_ED25519; } return err; } diff --git a/src/pk/ed25519/ed25519_import_raw.c b/src/pk/ed25519/ed25519_import_raw.c index 19955d134..d62812282 100644 --- a/src/pk/ed25519/ed25519_import_raw.c +++ b/src/pk/ed25519/ed25519_import_raw.c @@ -32,7 +32,7 @@ int ed25519_import_raw(const unsigned char *in, unsigned long inlen, int which, } else { return CRYPT_INVALID_ARG; } - key->algo = LTC_OID_ED25519; + key->pka = LTC_PKA_ED25519; key->type = which; return CRYPT_OK; diff --git a/src/pk/ed25519/ed25519_import_x509.c b/src/pk/ed25519/ed25519_import_x509.c index 44978ac2e..306a0e1e0 100644 --- a/src/pk/ed25519/ed25519_import_x509.c +++ b/src/pk/ed25519/ed25519_import_x509.c @@ -37,7 +37,7 @@ int ed25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519 return err; } key->type = PK_PUBLIC; - key->algo = LTC_OID_ED25519; + key->pka = LTC_PKA_ED25519; return err; } diff --git a/src/pk/ed25519/ed25519_make_key.c b/src/pk/ed25519/ed25519_make_key.c index 7cec1959d..289313b5c 100644 --- a/src/pk/ed25519/ed25519_make_key.c +++ b/src/pk/ed25519/ed25519_make_key.c @@ -28,7 +28,7 @@ int ed25519_make_key(prng_state *prng, int wprng, curve25519_key *key) } key->type = PK_PRIVATE; - key->algo = LTC_OID_ED25519; + key->pka = LTC_PKA_ED25519; return err; } diff --git a/src/pk/ed25519/ed25519_sign.c b/src/pk/ed25519/ed25519_sign.c index d5bf364ee..33c240566 100644 --- a/src/pk/ed25519/ed25519_sign.c +++ b/src/pk/ed25519/ed25519_sign.c @@ -23,7 +23,7 @@ static int s_ed25519_sign(const unsigned char *msg, unsigned long msglen, LTC_ARGCHK(siglen != NULL); LTC_ARGCHK(private_key != NULL); - if (private_key->algo != LTC_OID_ED25519) return CRYPT_PK_INVALID_TYPE; + if (private_key->pka != LTC_PKA_ED25519) return CRYPT_PK_INVALID_TYPE; if (private_key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE; if (*siglen < 64uL) { diff --git a/src/pk/ed25519/ed25519_verify.c b/src/pk/ed25519/ed25519_verify.c index e7dcc3077..7afab7cab 100644 --- a/src/pk/ed25519/ed25519_verify.c +++ b/src/pk/ed25519/ed25519_verify.c @@ -27,7 +27,7 @@ static int s_ed25519_verify(const unsigned char *msg, unsigned long msglen, *stat = 0; if (siglen != 64uL) return CRYPT_INVALID_ARG; - if (public_key->algo != LTC_OID_ED25519) return CRYPT_PK_INVALID_TYPE; + if (public_key->pka != LTC_PKA_ED25519) return CRYPT_PK_INVALID_TYPE; mlen = msglen + siglen; if ((mlen < msglen) || (mlen < siglen)) return CRYPT_OVERFLOW; diff --git a/src/pk/x25519/x25519_export.c b/src/pk/x25519/x25519_export.c index 0687c135f..fd9972238 100644 --- a/src/pk/x25519/x25519_export.c +++ b/src/pk/x25519/x25519_export.c @@ -23,7 +23,7 @@ int x25519_export( unsigned char *out, unsigned long *outlen, { LTC_ARGCHK(key != NULL); - if (key->algo != LTC_OID_X25519) return CRYPT_PK_INVALID_TYPE; + if (key->pka != LTC_PKA_X25519) return CRYPT_PK_INVALID_TYPE; return ec25519_export(out, outlen, which, key); } diff --git a/src/pk/x25519/x25519_import.c b/src/pk/x25519/x25519_import.c index 247885f93..a16c624d2 100644 --- a/src/pk/x25519/x25519_import.c +++ b/src/pk/x25519/x25519_import.c @@ -27,7 +27,7 @@ int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key * key_len = sizeof(key->pub); if ((err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_X25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) { key->type = PK_PUBLIC; - key->algo = LTC_OID_X25519; + key->pka = LTC_PKA_X25519; } return err; } diff --git a/src/pk/x25519/x25519_import_raw.c b/src/pk/x25519/x25519_import_raw.c index e86e8c6a2..da659201d 100644 --- a/src/pk/x25519/x25519_import_raw.c +++ b/src/pk/x25519/x25519_import_raw.c @@ -32,7 +32,7 @@ int x25519_import_raw(const unsigned char *in, unsigned long inlen, int which, c } else { return CRYPT_INVALID_ARG; } - key->algo = LTC_OID_X25519; + key->pka = LTC_PKA_X25519; key->type = which; return CRYPT_OK; diff --git a/src/pk/x25519/x25519_import_x509.c b/src/pk/x25519/x25519_import_x509.c index 043b6ad98..a3d90cdc5 100644 --- a/src/pk/x25519/x25519_import_x509.c +++ b/src/pk/x25519/x25519_import_x509.c @@ -37,7 +37,7 @@ int x25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_ return err; } key->type = PK_PUBLIC; - key->algo = LTC_OID_X25519; + key->pka = LTC_PKA_X25519; return err; } diff --git a/src/pk/x25519/x25519_make_key.c b/src/pk/x25519/x25519_make_key.c index 40276fe9e..a30003cc4 100644 --- a/src/pk/x25519/x25519_make_key.c +++ b/src/pk/x25519/x25519_make_key.c @@ -34,7 +34,7 @@ int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key) tweetnacl_crypto_scalarmult_base(key->pub, key->priv); key->type = PK_PRIVATE; - key->algo = LTC_OID_X25519; + key->pka = LTC_PKA_X25519; return err; } diff --git a/src/pk/x25519/x25519_shared_secret.c b/src/pk/x25519/x25519_shared_secret.c index eaea1c0d8..d7e9ea8c1 100644 --- a/src/pk/x25519/x25519_shared_secret.c +++ b/src/pk/x25519/x25519_shared_secret.c @@ -26,9 +26,10 @@ int x25519_shared_secret(const curve25519_key *private_key, LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - if(private_key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE; + if (public_key->pka != LTC_PKA_X25519) return CRYPT_PK_INVALID_TYPE; + if (private_key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE; - if(*outlen < 32uL) { + if (*outlen < 32uL) { *outlen = 32uL; return CRYPT_BUFFER_OVERFLOW; } diff --git a/tests/pem_test.c b/tests/pem_test.c index 255f0fce3..327ad7670 100644 --- a/tests/pem_test.c +++ b/tests/pem_test.c @@ -64,7 +64,8 @@ static int s_key_cmp(ltc_pka_key *key) return ecc_key_cmp(PK_PRIVATE, &s_ecc_key_should, &key->u.ecc); #endif break; - case LTC_PKA_CURVE25519: + case LTC_PKA_ED25519: + case LTC_PKA_X25519: case LTC_PKA_DH: return CRYPT_OK; default: