Browse Source

distinguish between Ed25519 and X25519

Signed-off-by: Steffen Jaeckel <[email protected]>
Steffen Jaeckel 3 years ago
parent
commit
661f5845fe

+ 4 - 2
doc/crypt.tex

@@ -7465,14 +7465,16 @@ enum ltc_pka_id {
    LTC_PKA_RSA,
    LTC_PKA_RSA,
    LTC_PKA_DSA,
    LTC_PKA_DSA,
    LTC_PKA_EC,
    LTC_PKA_EC,
-   LTC_PKA_CURVE25519,
+   LTC_PKA_X25519,
+   LTC_PKA_ED25519,
    LTC_PKA_DH,
    LTC_PKA_DH,
 };
 };
 
 
 typedef struct {
 typedef struct {
    union {
    union {
 #ifdef LTC_CURVE25519
 #ifdef LTC_CURVE25519
-      curve25519_key curve25519;
+      curve25519_key x25519;
+      curve25519_key ed25519;
 #endif
 #endif
 #ifdef LTC_MDH
 #ifdef LTC_MDH
       dh_key dh;
       dh_key dh;

+ 14 - 16
src/headers/tomcrypt_pk.h

@@ -22,6 +22,16 @@ typedef struct {
 
 
 /* ---- NUMBER THEORY ---- */
 /* ---- 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 {
 enum public_key_type {
    /* Refers to the public key */
    /* Refers to the public key */
    PK_PUBLIC      = 0x0000,
    PK_PUBLIC      = 0x0000,
@@ -349,12 +359,8 @@ typedef struct {
    /** The key type, PK_PRIVATE or PK_PUBLIC */
    /** The key type, PK_PRIVATE or PK_PUBLIC */
    enum public_key_type type;
    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 */
    /** The private key */
    unsigned char priv[32];
    unsigned char priv[32];
@@ -513,19 +519,11 @@ int dsa_shared_secret(void          *private_key, void *base,
  * LibTomCrypt Public Key Algorithm descriptor
  * 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 {
 typedef struct {
    union {
    union {
 #ifdef LTC_CURVE25519
 #ifdef LTC_CURVE25519
-      curve25519_key curve25519;
+      curve25519_key x25519;
+      curve25519_key ed25519;
 #endif
 #endif
 #ifdef LTC_MDH
 #ifdef LTC_MDH
       dh_key dh;
       dh_key dh;

+ 3 - 0
src/headers/tomcrypt_private.h

@@ -53,6 +53,7 @@ enum ltc_oid_id {
    LTC_OID_X25519,
    LTC_OID_X25519,
    LTC_OID_ED25519,
    LTC_OID_ED25519,
    LTC_OID_DH,
    LTC_OID_DH,
+   LTC_OID_NUM
 };
 };
 
 
 /*
 /*
@@ -349,6 +350,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 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_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_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_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);
 int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen);

+ 6 - 6
src/misc/pem/pem_pkcs.c

@@ -122,13 +122,13 @@ retry:
             break;
             break;
 #endif
 #endif
 #ifdef LTC_CURVE25519
 #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:
          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;
             break;
 #endif
 #endif
          default:
          default:

+ 2 - 2
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;
       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;
       goto cleanup;
    }
    }
 
 
-   key->id = LTC_PKA_CURVE25519;
+   key->id = LTC_PKA_ED25519;
 
 
 cleanup:
 cleanup:
    zeromem(pubkey, sizeof(pubkey));
    zeromem(pubkey, sizeof(pubkey));

+ 45 - 7
src/pk/asn1/oid/pk_get.c

@@ -11,26 +11,64 @@ typedef struct {
 } oid_table_entry;
 } oid_table_entry;
 
 
 static const oid_table_entry pka_oids[] = {
 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_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_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,        LTC_PKA_EC,         "1.2.840.10045.2.1" },
                                               { LTC_OID_EC_PRIMEF, LTC_PKA_EC,         "1.2.840.10045.1.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" },
                                               { 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.
    Returns the OID requested.
    @return CRYPT_OK if valid
    @return CRYPT_OK if valid
 */
 */
 int pk_get_oid(enum ltc_oid_id id, const char **st)
 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);
    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;
          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;
       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) {
       if (XSTRCMP(pka_oids[i].oid, tmp) == 0) {
          *id = pka_oids[i].id;
          *id = pka_oids[i].id;
          return CRYPT_OK;
          return CRYPT_OK;

+ 6 - 2
src/pk/ec25519/ec25519_export.c

@@ -25,6 +25,7 @@ int ec25519_export(       unsigned char *out, unsigned long *outlen,
    const char* OID;
    const char* OID;
    unsigned long oid[16], oidlen;
    unsigned long oid[16], oidlen;
    ltc_asn1_list alg_id[1];
    ltc_asn1_list alg_id[1];
+   enum ltc_oid_id oid_id;
    unsigned char private_key[34];
    unsigned char private_key[34];
    unsigned long version, private_key_len = sizeof(private_key);
    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;
    std = which & PK_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 (which == PK_PRIVATE) {
       if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
       if(key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
 
 
       if (std == PK_STD) {
       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;
             return err;
          }
          }
          oidlen = sizeof(oid)/sizeof(oid[0]);
          oidlen = sizeof(oid)/sizeof(oid[0]);
@@ -72,7 +76,7 @@ int ec25519_export(       unsigned char *out, unsigned long *outlen,
    } else {
    } else {
       if (std == PK_STD) {
       if (std == PK_STD) {
          /* encode public key as SubjectPublicKeyInfo */
          /* 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 {
       } else {
          if (*outlen < sizeof(key->pub)) {
          if (*outlen < sizeof(key->pub)) {
             err = CRYPT_BUFFER_OVERFLOW;
             err = CRYPT_BUFFER_OVERFLOW;

+ 1 - 1
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) {
    if ((err = der_decode_octet_string(priv_key->data, priv_key->size, key->priv, &key_len)) == CRYPT_OK) {
       fp(key->pub, key->priv);
       fp(key->pub, key->priv);
       key->type = PK_PRIVATE;
       key->type = PK_PRIVATE;
-      key->algo = id;
+      err = pk_get_pka_id(id, &key->pka);
    }
    }
    return err;
    return err;
 }
 }

+ 1 - 1
src/pk/ed25519/ed25519_export.c

@@ -23,7 +23,7 @@ int ed25519_export(       unsigned char *out, unsigned long *outlen,
 {
 {
    LTC_ARGCHK(key != NULL);
    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);
    return ec25519_export(out, outlen, which, key);
 }
 }

+ 1 - 1
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);
    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) {
    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->type = PK_PUBLIC;
-      key->algo = LTC_OID_ED25519;
+      key->pka = LTC_PKA_ED25519;
    }
    }
    return err;
    return err;
 }
 }

+ 1 - 1
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 {
    } else {
       return CRYPT_INVALID_ARG;
       return CRYPT_INVALID_ARG;
    }
    }
-   key->algo = LTC_OID_ED25519;
+   key->pka = LTC_PKA_ED25519;
    key->type = which;
    key->type = which;
 
 
    return CRYPT_OK;
    return CRYPT_OK;

+ 1 - 1
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;
       return err;
    }
    }
    key->type = PK_PUBLIC;
    key->type = PK_PUBLIC;
-   key->algo = LTC_OID_ED25519;
+   key->pka = LTC_PKA_ED25519;
 
 
    return err;
    return err;
 }
 }

+ 1 - 1
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->type = PK_PRIVATE;
-   key->algo = LTC_OID_ED25519;
+   key->pka = LTC_PKA_ED25519;
 
 
    return err;
    return err;
 }
 }

+ 1 - 1
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(siglen      != NULL);
    LTC_ARGCHK(private_key != 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 (private_key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
 
 
    if (*siglen < 64uL) {
    if (*siglen < 64uL) {

+ 1 - 1
src/pk/ed25519/ed25519_verify.c

@@ -27,7 +27,7 @@ static int s_ed25519_verify(const  unsigned char *msg, unsigned long msglen,
    *stat = 0;
    *stat = 0;
 
 
    if (siglen != 64uL) return CRYPT_INVALID_ARG;
    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;
    mlen = msglen + siglen;
    if ((mlen < msglen) || (mlen < siglen)) return CRYPT_OVERFLOW;
    if ((mlen < msglen) || (mlen < siglen)) return CRYPT_OVERFLOW;

+ 1 - 1
src/pk/x25519/x25519_export.c

@@ -23,7 +23,7 @@ int x25519_export(      unsigned char *out, unsigned long *outlen,
 {
 {
    LTC_ARGCHK(key != NULL);
    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);
    return ec25519_export(out, outlen, which, key);
 }
 }

+ 1 - 1
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);
    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) {
    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->type = PK_PUBLIC;
-      key->algo = LTC_OID_X25519;
+      key->pka = LTC_PKA_X25519;
    }
    }
    return err;
    return err;
 }
 }

+ 1 - 1
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 {
    } else {
       return CRYPT_INVALID_ARG;
       return CRYPT_INVALID_ARG;
    }
    }
-   key->algo = LTC_OID_X25519;
+   key->pka = LTC_PKA_X25519;
    key->type = which;
    key->type = which;
 
 
    return CRYPT_OK;
    return CRYPT_OK;

+ 1 - 1
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;
       return err;
    }
    }
    key->type = PK_PUBLIC;
    key->type = PK_PUBLIC;
-   key->algo = LTC_OID_X25519;
+   key->pka = LTC_PKA_X25519;
 
 
    return err;
    return err;
 }
 }

+ 1 - 1
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);
    tweetnacl_crypto_scalarmult_base(key->pub, key->priv);
 
 
    key->type = PK_PRIVATE;
    key->type = PK_PRIVATE;
-   key->algo = LTC_OID_X25519;
+   key->pka = LTC_PKA_X25519;
 
 
    return err;
    return err;
 }
 }

+ 3 - 2
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(out                != NULL);
    LTC_ARGCHK(outlen             != 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;
       *outlen = 32uL;
       return CRYPT_BUFFER_OVERFLOW;
       return CRYPT_BUFFER_OVERFLOW;
    }
    }

+ 2 - 1
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);
          return ecc_key_cmp(PK_PRIVATE, &s_ecc_key_should, &key->u.ecc);
 #endif
 #endif
          break;
          break;
-      case LTC_PKA_CURVE25519:
+      case LTC_PKA_ED25519:
+      case LTC_PKA_X25519:
       case LTC_PKA_DH:
       case LTC_PKA_DH:
          return CRYPT_OK;
          return CRYPT_OK;
       default:
       default: