Implement serializers for ED25519 and ED448
authorMatt Caswell <matt@openssl.org>
Tue, 17 Mar 2020 22:40:33 +0000 (08:40 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Tue, 17 Mar 2020 22:40:33 +0000 (08:40 +1000)
This is largely based on the existing X25519 and X448 serializers - but
a few adjustments were necessary so that we can identify what type of key
we are using. Previously we used the keylen for this but X25519 and
ED25519 have the same keylen.

Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/11272)

24 files changed:
crypto/ec/ecx_key.c
crypto/ec/ecx_meth.c
include/crypto/ecx.h
providers/defltprov.c
providers/implementations/include/prov/implementations.h
providers/implementations/keymgmt/ecx_kmgmt.c
providers/implementations/serializers/serializer_common.c
providers/implementations/serializers/serializer_ecx.c
providers/implementations/serializers/serializer_ecx_priv.c
providers/implementations/serializers/serializer_ecx_pub.c
providers/implementations/serializers/serializer_local.h
test/evp_pkey_provided_test.c
test/recipes/30-test_evp_pkey_provided/ED25519.priv.der [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED25519.priv.pem [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED25519.priv.txt [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED25519.pub.der [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED25519.pub.pem [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED25519.pub.txt [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED448.priv.der [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED448.priv.pem [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED448.priv.txt [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED448.pub.der [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED448.pub.pem [new file with mode: 0644]
test/recipes/30-test_evp_pkey_provided/ED448.pub.txt [new file with mode: 0644]

index 59643cc6adc0c5087ccdea594d5249c6919c3709..0b43d26ae4d2d0c5216cd80437f4b4fdde132ddb 100644 (file)
@@ -10,7 +10,7 @@
 #include <openssl/err.h>
 #include "crypto/ecx.h"
 
-ECX_KEY *ecx_key_new(size_t keylen, int haspubkey)
+ECX_KEY *ecx_key_new(ECX_KEY_TYPE type, int haspubkey)
 {
     ECX_KEY *ret = OPENSSL_zalloc(sizeof(*ret));
 
@@ -18,7 +18,21 @@ ECX_KEY *ecx_key_new(size_t keylen, int haspubkey)
         return NULL;
 
     ret->haspubkey = haspubkey;
-    ret->keylen = keylen;
+    switch (type) {
+    case ECX_KEY_TYPE_X25519:
+        ret->keylen = X25519_KEYLEN;
+        break;
+    case ECX_KEY_TYPE_X448:
+        ret->keylen = X448_KEYLEN;
+        break;
+    case ECX_KEY_TYPE_ED25519:
+        ret->keylen = ED25519_KEYLEN;
+        break;
+    case ECX_KEY_TYPE_ED448:
+        ret->keylen = ED448_KEYLEN;
+        break;
+    }
+    ret->type = type;
     ret->references = 1;
 
     ret->lock = CRYPTO_THREAD_lock_new();
index f107df3aa4c272b23e560a7ae14106878774c0ae..5f85927bd0276679413b5fa15fc217a67df1df6e 100644 (file)
 #define KEYLENID(id)    (IS25519(id) ? X25519_KEYLEN \
                                      : ((id) == EVP_PKEY_X448 ? X448_KEYLEN \
                                                               : ED448_KEYLEN))
+#define KEYNID2TYPE(id) \
+    (IS25519(id) ?  ECX_KEY_TYPE_X25519 \
+                 : ((id) == EVP_PKEY_X448 ? ECX_KEY_TYPE_X448 \
+                                          : ((id) == EVP_PKEY_ED25519 ? ECX_KEY_TYPE_ED25519 \
+                                                                      : ECX_KEY_TYPE_ED448)))
 #define KEYLEN(p)       KEYLENID((p)->ameth->pkey_id)
 
 
@@ -65,7 +70,7 @@ static int ecx_key_op(EVP_PKEY *pkey, int id, const X509_ALGOR *palg,
         }
     }
 
-    key = ecx_key_new(KEYLENID(id), 1);
+    key = ecx_key_new(KEYNID2TYPE(id), 1);
     if (key == NULL) {
         ECerr(EC_F_ECX_KEY_OP, ERR_R_MALLOC_FAILURE);
         return 0;
@@ -1104,7 +1109,7 @@ static int s390x_pkey_ecx_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     };
-    ECX_KEY *key = ecx_key_new(X25519_KEYLEN, 1);
+    ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X25519, 1);
     unsigned char *privkey = NULL, *pubkey;
 
     if (key == NULL) {
@@ -1146,7 +1151,7 @@ static int s390x_pkey_ecx_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
     };
-    ECX_KEY *key = ecx_key_new(X448_KEYLEN, 1);
+    ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_X448, 1);
     unsigned char *privkey = NULL, *pubkey;
 
     if (key == NULL) {
@@ -1191,7 +1196,7 @@ static int s390x_pkey_ecd_keygen25519(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
         0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
     };
     unsigned char x_dst[32], buff[SHA512_DIGEST_LENGTH];
-    ECX_KEY *key = ecx_key_new(ED25519_KEYLEN, 1);
+    ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED25519, 1);
     unsigned char *privkey = NULL, *pubkey;
     unsigned int sz;
 
@@ -1248,7 +1253,7 @@ static int s390x_pkey_ecd_keygen448(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
         0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69, 0x00
     };
     unsigned char x_dst[57], buff[114];
-    ECX_KEY *key = ecx_key_new(ED448_KEYLEN, 1);
+    ECX_KEY *key = ecx_key_new(ECX_KEY_TYPE_ED448, 1);
     unsigned char *privkey = NULL, *pubkey;
     EVP_MD_CTX *hashctx = NULL;
 
index 3e494bf0921cf1bfacd06d0317409d2faa9e7b12..8afb104438e9bb836f745f610aae199e4da1710b 100644 (file)
 #  define ED448_SECURITY_BITS   224
 #  define ED448_SIGSIZE         114
 
+
+typedef enum {
+    ECX_KEY_TYPE_X25519,
+    ECX_KEY_TYPE_X448,
+    ECX_KEY_TYPE_ED25519,
+    ECX_KEY_TYPE_ED448
+} ECX_KEY_TYPE;
+
+#define KEYTYPE2NID(type) \
+    ((type) == ECX_KEY_TYPE_X25519 \
+     ?  EVP_PKEY_X25519 \
+     : ((type) == ECX_KEY_TYPE_X448 \
+        ? EVP_PKEY_X448 \
+        : ((type) == ECX_KEY_TYPE_ED25519 \
+           ? EVP_PKEY_ED25519 \
+           : EVP_PKEY_ED448)))
+
 struct ecx_key_st {
     unsigned int haspubkey:1;
     unsigned char pubkey[MAX_KEYLEN];
     unsigned char *privkey;
     size_t keylen;
+    ECX_KEY_TYPE type;
     CRYPTO_REF_COUNT references;
     CRYPTO_RWLOCK *lock;
 };
 
 typedef struct ecx_key_st ECX_KEY;
 
-ECX_KEY *ecx_key_new(size_t keylen, int haspubkey);
+ECX_KEY *ecx_key_new(ECX_KEY_TYPE type, int haspubkey);
 unsigned char *ecx_key_allocate_privkey(ECX_KEY *key);
 void ecx_key_free(ECX_KEY *key);
 int ecx_key_up_ref(ECX_KEY *key);
index f89363341ad300e5bb0404d75baa5050c2689240..2ec229e16b76c4fcd7e9e77eadbb3147d9e883c2 100644 (file)
@@ -504,6 +504,32 @@ static const OSSL_ALGORITHM deflt_serializer[] = {
     { "X448", "provider=default,format=pem,type=public",
       x448_pub_pem_serializer_functions },
 
+    { "ED25519", "provider=default,fips=yes,format=text,type=private",
+      ed25519_priv_print_serializer_functions },
+    { "ED25519", "provider=default,fips=yes,format=text,type=public",
+      ed25519_pub_print_serializer_functions },
+    { "ED25519", "provider=default,fips=yes,format=der,type=private",
+      ed25519_priv_der_serializer_functions },
+    { "ED25519", "provider=default,fips=yes,format=der,type=public",
+      ed25519_pub_der_serializer_functions },
+    { "ED25519", "provider=default,fips=yes,format=pem,type=private",
+      ed25519_priv_pem_serializer_functions },
+    { "ED25519", "provider=default,fips=yes,format=pem,type=public",
+      ed25519_pub_pem_serializer_functions },
+
+    { "ED448", "provider=default,format=text,type=private",
+      ed448_priv_print_serializer_functions },
+    { "ED448", "provider=default,format=text,type=public",
+      ed448_pub_print_serializer_functions },
+    { "ED448", "provider=default,format=der,type=private",
+      ed448_priv_der_serializer_functions },
+    { "ED448", "provider=default,format=der,type=public",
+      ed448_pub_der_serializer_functions },
+    { "ED448", "provider=default,format=pem,type=private",
+      ed448_priv_pem_serializer_functions },
+    { "ED448", "provider=default,format=pem,type=public",
+      ed448_pub_pem_serializer_functions },
+
     { "EC", "provider=default,fips=yes,format=text,type=private",
       ec_priv_text_serializer_functions },
     { "EC", "provider=default,fips=yes,format=text,type=public",
index 57a3122b130c7a837ab54151bc9520a45a33c76a..9b5017a14465fd757b2eab88d18e37cf4eea6605 100644 (file)
@@ -322,6 +322,20 @@ extern const OSSL_DISPATCH x448_pub_der_serializer_functions[];
 extern const OSSL_DISPATCH x448_priv_pem_serializer_functions[];
 extern const OSSL_DISPATCH x448_pub_pem_serializer_functions[];
 
+extern const OSSL_DISPATCH ed25519_priv_print_serializer_functions[];
+extern const OSSL_DISPATCH ed25519_pub_print_serializer_functions[];
+extern const OSSL_DISPATCH ed25519_priv_der_serializer_functions[];
+extern const OSSL_DISPATCH ed25519_pub_der_serializer_functions[];
+extern const OSSL_DISPATCH ed25519_priv_pem_serializer_functions[];
+extern const OSSL_DISPATCH ed25519_pub_pem_serializer_functions[];
+
+extern const OSSL_DISPATCH ed448_priv_print_serializer_functions[];
+extern const OSSL_DISPATCH ed448_pub_print_serializer_functions[];
+extern const OSSL_DISPATCH ed448_priv_der_serializer_functions[];
+extern const OSSL_DISPATCH ed448_pub_der_serializer_functions[];
+extern const OSSL_DISPATCH ed448_priv_pem_serializer_functions[];
+extern const OSSL_DISPATCH ed448_pub_pem_serializer_functions[];
+
 extern const OSSL_DISPATCH ec_priv_text_serializer_functions[];
 extern const OSSL_DISPATCH ec_pub_text_serializer_functions[];
 extern const OSSL_DISPATCH ec_param_text_serializer_functions[];
index b078c6de58d5eea854cd0a58aae1c0ae03342baa..6450fbb22e7fe665a219b74b103abb922de96a3a 100644 (file)
@@ -35,22 +35,22 @@ static OSSL_OP_keymgmt_export_types_fn ecx_imexport_types;
 
 static void *x25519_new_key(void *provctx)
 {
-    return ecx_key_new(X25519_KEYLEN, 0);
+    return ecx_key_new(ECX_KEY_TYPE_X25519, 0);
 }
 
 static void *x448_new_key(void *provctx)
 {
-    return ecx_key_new(X448_KEYLEN, 0);
+    return ecx_key_new(ECX_KEY_TYPE_X448, 0);
 }
 
 static void *ed25519_new_key(void *provctx)
 {
-    return ecx_key_new(ED25519_KEYLEN, 0);
+    return ecx_key_new(ECX_KEY_TYPE_ED25519, 0);
 }
 
 static void *ed448_new_key(void *provctx)
 {
-    return ecx_key_new(ED448_KEYLEN, 0);
+    return ecx_key_new(ECX_KEY_TYPE_ED448, 0);
 }
 
 static int ecx_has(void *keydata, int selection)
index 0b99f4939b3d9062d570ee6404d5a9dfa46ad5ef..7c6b5afe18a2657b92399a8b8503007476befb2f 100644 (file)
@@ -14,6 +14,7 @@
 #include <openssl/types.h>
 #include <openssl/x509.h>        /* i2d_X509_PUBKEY_bio() */
 #include "crypto/bn.h"           /* bn_get_words() */
+#include "crypto/ecx.h"
 #include "prov/bio.h"            /* ossl_prov_bio_printf() */
 #include "prov/implementations.h"
 #include "prov/providercommonerr.h" /* PROV_R_READ_KEY */
index 589c6c25f5a6f1f79727424a2fcd8a5f412afad8..78b6ec9691e56a2e70018efa5706bb12a3d23281 100644 (file)
@@ -26,6 +26,14 @@ void ecx_get_new_free_import(ECX_KEY_TYPE type,
         *ecx_new = ossl_prov_get_keymgmt_new(x448_keymgmt_functions);
         *ecx_free = ossl_prov_get_keymgmt_free(x448_keymgmt_functions);
         *ecx_import = ossl_prov_get_keymgmt_import(x448_keymgmt_functions);
+    } else if (type == ECX_KEY_TYPE_ED25519) {
+        *ecx_new = ossl_prov_get_keymgmt_new(ed25519_keymgmt_functions);
+        *ecx_free = ossl_prov_get_keymgmt_free(ed25519_keymgmt_functions);
+        *ecx_import = ossl_prov_get_keymgmt_import(ed25519_keymgmt_functions);
+    } else if (type == ECX_KEY_TYPE_ED448) {
+        *ecx_new = ossl_prov_get_keymgmt_new(ed448_keymgmt_functions);
+        *ecx_free = ossl_prov_get_keymgmt_free(ed448_keymgmt_functions);
+        *ecx_import = ossl_prov_get_keymgmt_import(ed448_keymgmt_functions);
     } else {
         *ecx_new = NULL;
         *ecx_free = NULL;
@@ -40,23 +48,35 @@ int ossl_prov_print_ecx(BIO *out, ECX_KEY *ecxkey, enum ecx_print_type type)
 
     switch (type) {
     case ecx_print_priv:
-        switch (ecxkey->keylen) {
-        case X25519_KEYLEN:
+        switch (ecxkey->type) {
+        case ECX_KEY_TYPE_X25519:
             type_label = "X25519 Private-Key";
             break;
-        case X448_KEYLEN:
+        case ECX_KEY_TYPE_X448:
             type_label = "X448 Private-Key";
             break;
+        case ECX_KEY_TYPE_ED25519:
+            type_label = "ED25519 Private-Key";
+            break;
+        case ECX_KEY_TYPE_ED448:
+            type_label = "ED448 Private-Key";
+            break;
         }
         break;
     case ecx_print_pub:
-        switch (ecxkey->keylen) {
-        case X25519_KEYLEN:
+        switch (ecxkey->type) {
+        case ECX_KEY_TYPE_X25519:
             type_label = "X25519 Public-Key";
             break;
-        case X448_KEYLEN:
+        case ECX_KEY_TYPE_X448:
             type_label = "X448 Public-Key";
             break;
+        case ECX_KEY_TYPE_ED25519:
+            type_label = "ED25519 Public-Key";
+            break;
+        case ECX_KEY_TYPE_ED448:
+            type_label = "ED448 Public-Key";
+            break;
         }
         break;
     }
index 64dc594624da77fbf686fb55b9ad2d7b833dc1bd..c746109424115bc57f7355fedcd67ebc375985fc 100644 (file)
 #include <openssl/pem.h>
 #include <openssl/types.h>
 #include <openssl/params.h>
+#include "crypto/ecx.h"
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "serializer_local.h"
 
 static OSSL_OP_serializer_newctx_fn x25519_priv_newctx;
 static OSSL_OP_serializer_newctx_fn x448_priv_newctx;
+static OSSL_OP_serializer_newctx_fn ed25519_priv_newctx;
+static OSSL_OP_serializer_newctx_fn ed448_priv_newctx;
 static OSSL_OP_serializer_freectx_fn ecx_priv_freectx;
 static OSSL_OP_serializer_set_ctx_params_fn ecx_priv_set_ctx_params;
 static OSSL_OP_serializer_settable_ctx_params_fn ecx_priv_settable_ctx_params;
@@ -65,6 +68,16 @@ static void *x448_priv_newctx(void *provctx)
     return ecx_priv_newctx(provctx, ECX_KEY_TYPE_X448);
 }
 
+static void *ed25519_priv_newctx(void *provctx)
+{
+    return ecx_priv_newctx(provctx, ECX_KEY_TYPE_ED25519);
+}
+
+static void *ed448_priv_newctx(void *provctx)
+{
+    return ecx_priv_newctx(provctx, ECX_KEY_TYPE_ED448);
+}
+
 static void ecx_priv_freectx(void *vctx)
 {
     struct ecx_priv_ctx_st *ctx = vctx;
@@ -150,14 +163,13 @@ static int ecx_priv_der(void *vctx, void *vecxkey, BIO *out,
     struct ecx_priv_ctx_st *ctx = vctx;
     ECX_KEY *ecxkey = vecxkey;
     int ret;
-    int type = (ctx->type == ECX_KEY_TYPE_X25519) ? EVP_PKEY_X25519
-                                                  : EVP_PKEY_X448;
+    int nid = KEYTYPE2NID(ctx->type);
 
     ctx->sc.cb = cb;
     ctx->sc.cbarg = cbarg;
 
     ret = ossl_prov_write_priv_der_from_obj(out, ecxkey,
-                                            type,
+                                            nid,
                                             NULL,
                                             ossl_prov_ecx_priv_to_der,
                                             &ctx->sc);
@@ -194,14 +206,13 @@ static int ecx_priv_pem(void *vctx, void *ecxkey, BIO *out,
 {
     struct ecx_priv_ctx_st *ctx = vctx;
     int ret;
-    int type = (ctx->type == ECX_KEY_TYPE_X25519) ? EVP_PKEY_X25519
-                                                  : EVP_PKEY_X448;
+    int nid = KEYTYPE2NID(ctx->type);
 
     ctx->sc.cb = cb;
     ctx->sc.cbarg = cbarg;
 
     ret = ossl_prov_write_priv_pem_from_obj(out, ecxkey,
-                                            type,
+                                            nid,
                                             NULL,
                                             ossl_prov_ecx_priv_to_der,
                                             &ctx->sc);
@@ -268,3 +279,5 @@ static int ecx_priv_print(void *ctx, void *ecxkey, BIO *out,
 
 MAKE_SERIALIZER_FUNCTIONS_GROUP(x25519)
 MAKE_SERIALIZER_FUNCTIONS_GROUP(x448)
+MAKE_SERIALIZER_FUNCTIONS_GROUP(ed25519)
+MAKE_SERIALIZER_FUNCTIONS_GROUP(ed448)
index 384d75e6b33818c9054e8351d1acf2d8d1857465..cd09cd6abbac5e4566d178165291cf68db8394ff 100644 (file)
 #include <openssl/pem.h>
 #include <openssl/types.h>
 #include <openssl/params.h>
+#include "crypto/ecx.h"
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "serializer_local.h"
 
 static OSSL_OP_serializer_newctx_fn x25519_pub_newctx;
 static OSSL_OP_serializer_newctx_fn x448_pub_newctx;
+static OSSL_OP_serializer_newctx_fn ed25519_pub_newctx;
+static OSSL_OP_serializer_newctx_fn ed448_pub_newctx;
 static OSSL_OP_serializer_freectx_fn ecx_pub_freectx;
 static OSSL_OP_serializer_serialize_data_fn ecx_pub_der_data;
 static OSSL_OP_serializer_serialize_object_fn ecx_pub_der;
@@ -57,6 +60,16 @@ static void *x448_pub_newctx(void *provctx)
     return ecx_pub_newctx(provctx, ECX_KEY_TYPE_X448);
 }
 
+static void *ed25519_pub_newctx(void *provctx)
+{
+    return ecx_pub_newctx(provctx, ECX_KEY_TYPE_ED25519);
+}
+
+static void *ed448_pub_newctx(void *provctx)
+{
+    return ecx_pub_newctx(provctx, ECX_KEY_TYPE_ED448);
+}
+
 static void ecx_pub_freectx(void *ctx)
 {
     OPENSSL_free(ctx);
@@ -92,8 +105,7 @@ static int ecx_pub_der(void *vctx, void *ecxkey, BIO *out,
     struct ecx_pub_ctx_st *ctx = vctx;
 
     return ossl_prov_write_pub_der_from_obj(out, ecxkey,
-                                            ctx->type == ECX_KEY_TYPE_X25519
-                                            ? EVP_PKEY_X25519 : EVP_PKEY_X448,
+                                            KEYTYPE2NID(ctx->type),
                                             NULL,
                                             ossl_prov_ecx_pub_to_der);
 }
@@ -128,8 +140,7 @@ static int ecx_pub_pem(void *vctx, void *ecxkey, BIO *out,
     struct ecx_pub_ctx_st *ctx = vctx;
 
     return ossl_prov_write_pub_pem_from_obj(out, ecxkey,
-                                            ctx->type == ECX_KEY_TYPE_X25519
-                                            ? EVP_PKEY_X25519 : EVP_PKEY_X448,
+                                            KEYTYPE2NID(ctx->type),
                                             NULL,
                                             ossl_prov_ecx_pub_to_der);
 
@@ -182,3 +193,5 @@ static int ecx_pub_print(void *ctx, void *ecxkey, BIO *out,
 
 MAKE_SERIALIZER_FUNCTIONS_GROUP(x25519)
 MAKE_SERIALIZER_FUNCTIONS_GROUP(x448)
+MAKE_SERIALIZER_FUNCTIONS_GROUP(ed25519)
+MAKE_SERIALIZER_FUNCTIONS_GROUP(ed448)
index 3125dc8f74f2dcb794f99895383597f7412f4ad0..b1c36a22212db60734efb1e5a254c81589f41ac6 100644 (file)
@@ -31,11 +31,6 @@ struct pkcs8_encrypt_ctx_st {
     void *cbarg;
 };
 
-typedef enum {
-    ECX_KEY_TYPE_X25519,
-    ECX_KEY_TYPE_X448
-} ECX_KEY_TYPE;
-
 OSSL_OP_keymgmt_new_fn *ossl_prov_get_keymgmt_new(const OSSL_DISPATCH *fns);
 OSSL_OP_keymgmt_free_fn *ossl_prov_get_keymgmt_free(const OSSL_DISPATCH *fns);
 OSSL_OP_keymgmt_import_fn *ossl_prov_get_keymgmt_import(const OSSL_DISPATCH *fns);
@@ -64,12 +59,14 @@ int ossl_prov_prepare_dh_params(const void *dh, int nid,
 int ossl_prov_dh_pub_to_der(const void *dh, unsigned char **pder);
 int ossl_prov_dh_priv_to_der(const void *dh, unsigned char **pder);
 
+#ifndef OPENSSL_NO_EC
 void ecx_get_new_free_import(ECX_KEY_TYPE type,
                              OSSL_OP_keymgmt_new_fn **ecx_new,
                              OSSL_OP_keymgmt_free_fn **ecx_free,
                              OSSL_OP_keymgmt_import_fn **ecx_import);
 int ossl_prov_ecx_pub_to_der(const void *ecxkey, unsigned char **pder);
 int ossl_prov_ecx_priv_to_der(const void *ecxkey, unsigned char **pder);
+#endif
 
 int ossl_prov_prepare_dsa_params(const void *dsa, int nid,
                                 void **pstr, int *pstrtype);
index c395f185dd082e3d6423558faa594542811f694d..d0a87b08d3f43e4d74b2cb6129f73c992901724f 100644 (file)
@@ -392,16 +392,18 @@ static int test_fromdata_dh(void)
 
 # define X25519_IDX      0
 # define X448_IDX        1
+# define ED25519_IDX     2
+# define ED448_IDX       3
 
 static int test_fromdata_ecx(int tst)
 {
     int ret = 0;
     EVP_PKEY_CTX *ctx = NULL;
     EVP_PKEY *pk = NULL;
-    const char *alg = (tst == X25519_IDX) ? "X25519" : "X448";
+    const char *alg = NULL;
 
-    /* X448_KEYLEN > X25519_KEYLEN */
-    static unsigned char key_numbers[2][2][X448_KEYLEN] = {
+    /* ED448_KEYLEN > X448_KEYLEN > X25519_KEYLEN == ED25519_KEYLEN */
+    static unsigned char key_numbers[4][2][ED448_KEYLEN] = {
         /* X25519: Keys from RFC 7748 6.1 */
         {
             /* Private Key */
@@ -439,6 +441,44 @@ static int test_fromdata_ecx(int tst)
                 0x0c, 0x5b, 0x12, 0xda, 0x88, 0x12, 0x0d, 0x53, 0x17, 0x7f,
                 0x80, 0xe5, 0x32, 0xc4, 0x1f, 0xa0
             }
+        },
+        /* ED25519: Keys from RFC 8032 */
+        {
+            /* Private Key */
+            {
+                0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 0xba, 0x84,
+                0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4, 0x44, 0x49, 0xc5, 0x69,
+                0x7b, 0x32, 0x69, 0x19, 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae,
+                0x7f, 0x60
+            },
+            /* Public Key */
+            {
+                0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 0xd5, 0x4b,
+                0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, 0x0e, 0xe1, 0x72, 0xf3,
+                0xda, 0xa6, 0x23, 0x25, 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07,
+                0x51, 0x1a
+            }
+        },
+        /* ED448: Keys from RFC 8032 */
+        {
+            /* Private Key */
+            {
+                0x6c, 0x82, 0xa5, 0x62, 0xcb, 0x80, 0x8d, 0x10, 0xd6, 0x32,
+                0xbe, 0x89, 0xc8, 0x51, 0x3e, 0xbf, 0x6c, 0x92, 0x9f, 0x34,
+                0xdd, 0xfa, 0x8c, 0x9f, 0x63, 0xc9, 0x96, 0x0e, 0xf6, 0xe3,
+                0x48, 0xa3, 0x52, 0x8c, 0x8a, 0x3f, 0xcc, 0x2f, 0x04, 0x4e,
+                0x39, 0xa3, 0xfc, 0x5b, 0x94, 0x49, 0x2f, 0x8f, 0x03, 0x2e,
+                0x75, 0x49, 0xa2, 0x00, 0x98, 0xf9, 0x5b
+            },
+            /* Public Key */
+            {
+                0x5f, 0xd7, 0x44, 0x9b, 0x59, 0xb4, 0x61, 0xfd, 0x2c, 0xe7,
+                0x87, 0xec, 0x61, 0x6a, 0xd4, 0x6a, 0x1d, 0xa1, 0x34, 0x24,
+                0x85, 0xa7, 0x0e, 0x1f, 0x8a, 0x0e, 0xa7, 0x5d, 0x80, 0xe9,
+                0x67, 0x78, 0xed, 0xf1, 0x24, 0x76, 0x9b, 0x46, 0xc7, 0x06,
+                0x1b, 0xd6, 0x78, 0x3d, 0xf1, 0xe5, 0x0f, 0x6c, 0xd1, 0xfa,
+                0x1a, 0xbe, 0xaf, 0xe8, 0x25, 0x61, 0x80
+            }
         }
     };
     OSSL_PARAM x25519_fromdata_params[] = {
@@ -459,19 +499,59 @@ static int test_fromdata_ecx(int tst)
                                 X448_KEYLEN),
         OSSL_PARAM_END
     };
-    OSSL_PARAM *fromdata_params;
-    int bits, security_bits, size;
+    OSSL_PARAM ed25519_fromdata_params[] = {
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
+                                key_numbers[ED25519_IDX][PRIV_KEY],
+                                ED25519_KEYLEN),
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
+                                key_numbers[ED25519_IDX][PUB_KEY],
+                                ED25519_KEYLEN),
+        OSSL_PARAM_END
+    };
+    OSSL_PARAM ed448_fromdata_params[] = {
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
+                                key_numbers[ED448_IDX][PRIV_KEY],
+                                ED448_KEYLEN),
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY,
+                                key_numbers[ED448_IDX][PUB_KEY],
+                                ED448_KEYLEN),
+        OSSL_PARAM_END
+    };
+    OSSL_PARAM *fromdata_params = NULL;
+    int bits = 0, security_bits = 0, size = 0;
 
-    if (tst == X25519_IDX) {
+    switch (tst) {
+    case X25519_IDX:
         fromdata_params = x25519_fromdata_params;
         bits = X25519_BITS;
         security_bits = X25519_SECURITY_BITS;
         size = X25519_KEYLEN;
-    } else {
+        alg = "X25519";
+        break;
+
+    case X448_IDX:
         fromdata_params = x448_fromdata_params;
         bits = X448_BITS;
         security_bits = X448_SECURITY_BITS;
         size = X448_KEYLEN;
+        alg = "X448";
+        break;
+
+    case ED25519_IDX:
+        fromdata_params = ed25519_fromdata_params;
+        bits = ED25519_BITS;
+        security_bits = ED25519_SECURITY_BITS;
+        size = ED25519_KEYLEN;
+        alg = "ED25519";
+        break;
+
+    case ED448_IDX:
+        fromdata_params = ed448_fromdata_params;
+        bits = ED448_BITS;
+        security_bits = ED448_SECURITY_BITS;
+        size = ED448_KEYLEN;
+        alg = "ED448";
+        break;
     }
 
     ctx = EVP_PKEY_CTX_new_from_name(NULL, alg, NULL);
@@ -577,7 +657,7 @@ int setup_tests(void)
     ADD_TEST(test_fromdata_dh);
 #endif
 #ifndef OPENSSL_NO_EC
-    ADD_ALL_TESTS(test_fromdata_ecx, 2);
+    ADD_ALL_TESTS(test_fromdata_ecx, 4);
     ADD_TEST(test_fromdata_ec);
 #endif
     return 1;
diff --git a/test/recipes/30-test_evp_pkey_provided/ED25519.priv.der b/test/recipes/30-test_evp_pkey_provided/ED25519.priv.der
new file mode 100644 (file)
index 0000000..71783b7
Binary files /dev/null and b/test/recipes/30-test_evp_pkey_provided/ED25519.priv.der differ
diff --git a/test/recipes/30-test_evp_pkey_provided/ED25519.priv.pem b/test/recipes/30-test_evp_pkey_provided/ED25519.priv.pem
new file mode 100644 (file)
index 0000000..7cf2b72
--- /dev/null
@@ -0,0 +1,3 @@
+-----BEGIN PRIVATE KEY-----
+MC4CAQAwBQYDK2VwBCIEIJ1hsZ3v/VpguoRK9JLsLMREScVpezJpGXA7rAMcrn9g
+-----END PRIVATE KEY-----
diff --git a/test/recipes/30-test_evp_pkey_provided/ED25519.priv.txt b/test/recipes/30-test_evp_pkey_provided/ED25519.priv.txt
new file mode 100644 (file)
index 0000000..43ed486
--- /dev/null
@@ -0,0 +1,9 @@
+ED25519 Private-Key:
+priv:
+    9d:61:b1:9d:ef:fd:5a:60:ba:84:4a:f4:92:ec:2c:
+    c4:44:49:c5:69:7b:32:69:19:70:3b:ac:03:1c:ae:
+    7f:60
+pub:
+    d7:5a:98:01:82:b1:0a:b7:d5:4b:fe:d3:c9:64:07:
+    3a:0e:e1:72:f3:da:a6:23:25:af:02:1a:68:f7:07:
+    51:1a
diff --git a/test/recipes/30-test_evp_pkey_provided/ED25519.pub.der b/test/recipes/30-test_evp_pkey_provided/ED25519.pub.der
new file mode 100644 (file)
index 0000000..5b33e75
Binary files /dev/null and b/test/recipes/30-test_evp_pkey_provided/ED25519.pub.der differ
diff --git a/test/recipes/30-test_evp_pkey_provided/ED25519.pub.pem b/test/recipes/30-test_evp_pkey_provided/ED25519.pub.pem
new file mode 100644 (file)
index 0000000..9749b69
--- /dev/null
@@ -0,0 +1,3 @@
+-----BEGIN PUBLIC KEY-----
+MCowBQYDK2VwAyEA11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=
+-----END PUBLIC KEY-----
diff --git a/test/recipes/30-test_evp_pkey_provided/ED25519.pub.txt b/test/recipes/30-test_evp_pkey_provided/ED25519.pub.txt
new file mode 100644 (file)
index 0000000..7456dfc
--- /dev/null
@@ -0,0 +1,5 @@
+ED25519 Public-Key:
+pub:
+    d7:5a:98:01:82:b1:0a:b7:d5:4b:fe:d3:c9:64:07:
+    3a:0e:e1:72:f3:da:a6:23:25:af:02:1a:68:f7:07:
+    51:1a
diff --git a/test/recipes/30-test_evp_pkey_provided/ED448.priv.der b/test/recipes/30-test_evp_pkey_provided/ED448.priv.der
new file mode 100644 (file)
index 0000000..5718a54
Binary files /dev/null and b/test/recipes/30-test_evp_pkey_provided/ED448.priv.der differ
diff --git a/test/recipes/30-test_evp_pkey_provided/ED448.priv.pem b/test/recipes/30-test_evp_pkey_provided/ED448.priv.pem
new file mode 100644 (file)
index 0000000..98af164
--- /dev/null
@@ -0,0 +1,4 @@
+-----BEGIN PRIVATE KEY-----
+MEcCAQAwBQYDK2VxBDsEOWyCpWLLgI0Q1jK+ichRPr9skp803fqMn2PJlg7240ij
+UoyKP8wvBE45o/xblEkvjwMudUmiAJj5Ww==
+-----END PRIVATE KEY-----
diff --git a/test/recipes/30-test_evp_pkey_provided/ED448.priv.txt b/test/recipes/30-test_evp_pkey_provided/ED448.priv.txt
new file mode 100644 (file)
index 0000000..071ee6c
--- /dev/null
@@ -0,0 +1,11 @@
+ED448 Private-Key:
+priv:
+    6c:82:a5:62:cb:80:8d:10:d6:32:be:89:c8:51:3e:
+    bf:6c:92:9f:34:dd:fa:8c:9f:63:c9:96:0e:f6:e3:
+    48:a3:52:8c:8a:3f:cc:2f:04:4e:39:a3:fc:5b:94:
+    49:2f:8f:03:2e:75:49:a2:00:98:f9:5b
+pub:
+    5f:d7:44:9b:59:b4:61:fd:2c:e7:87:ec:61:6a:d4:
+    6a:1d:a1:34:24:85:a7:0e:1f:8a:0e:a7:5d:80:e9:
+    67:78:ed:f1:24:76:9b:46:c7:06:1b:d6:78:3d:f1:
+    e5:0f:6c:d1:fa:1a:be:af:e8:25:61:80
diff --git a/test/recipes/30-test_evp_pkey_provided/ED448.pub.der b/test/recipes/30-test_evp_pkey_provided/ED448.pub.der
new file mode 100644 (file)
index 0000000..bd2a955
Binary files /dev/null and b/test/recipes/30-test_evp_pkey_provided/ED448.pub.der differ
diff --git a/test/recipes/30-test_evp_pkey_provided/ED448.pub.pem b/test/recipes/30-test_evp_pkey_provided/ED448.pub.pem
new file mode 100644 (file)
index 0000000..640da6f
--- /dev/null
@@ -0,0 +1,4 @@
+-----BEGIN PUBLIC KEY-----
+MEMwBQYDK2VxAzoAX9dEm1m0Yf0s54fsYWrUah2hNCSFpw4fig6nXYDpZ3jt8SR2
+m0bHBhvWeD3x5Q9s0foavq/oJWGA
+-----END PUBLIC KEY-----
diff --git a/test/recipes/30-test_evp_pkey_provided/ED448.pub.txt b/test/recipes/30-test_evp_pkey_provided/ED448.pub.txt
new file mode 100644 (file)
index 0000000..06a2967
--- /dev/null
@@ -0,0 +1,6 @@
+ED448 Public-Key:
+pub:
+    5f:d7:44:9b:59:b4:61:fd:2c:e7:87:ec:61:6a:d4:
+    6a:1d:a1:34:24:85:a7:0e:1f:8a:0e:a7:5d:80:e9:
+    67:78:ed:f1:24:76:9b:46:c7:06:1b:d6:78:3d:f1:
+    e5:0f:6c:d1:fa:1a:be:af:e8:25:61:80