]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
ML-DSA: Add support for dup.
authorslontis <shane.lontis@oracle.com>
Fri, 17 Jan 2025 04:05:21 +0000 (15:05 +1100)
committerTomas Mraz <tomas@openssl.org>
Fri, 14 Feb 2025 09:46:03 +0000 (10:46 +0100)
Reviewed-by: Viktor Dukhovni <viktor@openssl.org>
Reviewed-by: Paul Dale <ppzgs1@gmail.com>
(Merged from https://github.com/openssl/openssl/pull/26451)

crypto/ml_dsa/ml_dsa_key.c
crypto/ml_dsa/ml_dsa_key.h
crypto/ml_dsa/ml_dsa_vector.h
include/crypto/ml_dsa.h
providers/implementations/keymgmt/ml_dsa_kmgmt.c
providers/implementations/signature/ml_dsa_sig.c

index 00f1dc4a3678f10d13698dc7be49ee864a6345b7..6694a94e22d01aad3bc777ef45108adae94ca77a 100644 (file)
@@ -96,6 +96,73 @@ void ossl_ml_dsa_key_free(ML_DSA_KEY *key)
     OPENSSL_free(key);
 }
 
+/**
+ * @brief Duplicate a key
+ *
+ * @param src A ML_DSA_KEY object to copy
+ * @param selection to select public and/or private components. Selecting the
+ *                  private key will also select the public key
+ * @returns The duplicated key, or NULL on failure.
+ */
+ML_DSA_KEY *ossl_ml_dsa_key_dup(const ML_DSA_KEY *src, int selection)
+{
+    ML_DSA_KEY *ret = NULL;
+
+    if (src == NULL)
+        return NULL;
+
+    ret = OPENSSL_zalloc(sizeof(*ret));
+    if (ret != NULL) {
+        ret->libctx = src->libctx;
+        ret->params = src->params;
+        if (src->propq != NULL) {
+            if ((ret->propq = OPENSSL_strdup(src->propq)) == NULL)
+                goto err;
+        }
+        if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) != 0) {
+            if (src->pub_encoding != NULL) {
+                /* The public components are present if the private key is present */
+                memcpy(ret->rho, src->rho, sizeof(src->rho));
+                memcpy(ret->tr, src->tr, sizeof(src->tr));
+                if (src->t1.poly != NULL) {
+                    if (!ossl_ml_dsa_key_pub_alloc(ret))
+                        goto err;
+                    vector_copy(&ret->t1, &src->t1);
+                }
+                if ((ret->pub_encoding = OPENSSL_memdup(src->pub_encoding,
+                                                        src->params->pk_len)) == NULL)
+                    goto err;
+            }
+            if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+                if (src->priv_encoding != NULL) {
+                    memcpy(ret->K, src->K, sizeof(src->K));
+                    if (src->s1.poly != NULL) {
+                        if (!ossl_ml_dsa_key_priv_alloc(ret))
+                            goto err;
+                        vector_copy(&ret->s1, &src->s1);
+                        vector_copy(&ret->s2, &src->s2);
+                        vector_copy(&ret->t0, &src->t0);
+                    }
+                    if (src->priv_encoding != NULL) {
+                        if ((ret->priv_encoding =
+                                OPENSSL_memdup(src->priv_encoding,
+                                               src->params->sk_len)) == NULL)
+                            goto err;
+                    }
+                }
+            }
+        }
+        EVP_MD_up_ref(src->shake128_md);
+        EVP_MD_up_ref(src->shake256_md);
+        ret->shake128_md = src->shake128_md;
+        ret->shake256_md = src->shake256_md;
+    }
+    return ret;
+ err:
+    ossl_ml_dsa_key_free(ret);
+    return NULL;
+}
+
 /**
  * @brief Are 2 keys equal?
  *
index aeef961cb802f8a305ce9c11e48701431eb10183..26ffe2ebbc4eaaf5161aa31d8dc8de42d8a58539 100644 (file)
@@ -12,6 +12,7 @@
 #include "internal/refcount.h"
 #include "ml_dsa_vector.h"
 
+/* NOTE - any changes to this struct may require updates to ossl_ml_dsa_dup() */
 struct ml_dsa_key_st {
     OSSL_LIB_CTX *libctx;
     const ML_DSA_PARAMS *params;
index e5b05069980a2c3fefba7333d4b47ab9d6f307cb..dd45a46627f779ae8de1dadbdef8e36b75aa8154 100644 (file)
@@ -45,6 +45,7 @@ void vector_free(VECTOR *v)
 {
     OPENSSL_free(v->poly);
     v->poly = NULL;
+    v->num_poly = 0;
 }
 
 /* @brief zeroize a vectors polynomial coefficients */
index 2008da796833ab38ffeb41be5336b7bdefc779b1..7e15cffb0b252c80a971df7f5d7f4d58412cfd13 100644 (file)
@@ -24,6 +24,7 @@ __owur ML_DSA_KEY *ossl_ml_dsa_key_new(OSSL_LIB_CTX *libctx, const char *propq,
 __owur int ossl_ml_dsa_key_pub_alloc(ML_DSA_KEY *key);
 __owur int ossl_ml_dsa_key_priv_alloc(ML_DSA_KEY *key);
 void ossl_ml_dsa_key_free(ML_DSA_KEY *key);
+__owur ML_DSA_KEY *ossl_ml_dsa_key_dup(const ML_DSA_KEY *src, int selection);
 __owur int ossl_ml_dsa_key_equal(const ML_DSA_KEY *key1, const ML_DSA_KEY *key2,
                                  int selection);
 __owur int ossl_ml_dsa_key_has(const ML_DSA_KEY *key, int selection);
index e959022adf0bd2c4000c05cca71d82dedfc85276..fbe5cc87d5697dda89731fc2031f9eda1114dac1 100644 (file)
@@ -26,6 +26,7 @@ static OSSL_FUNC_keymgmt_export_fn ml_dsa_export;
 static OSSL_FUNC_keymgmt_import_types_fn ml_dsa_imexport_types;
 static OSSL_FUNC_keymgmt_export_types_fn ml_dsa_imexport_types;
 static OSSL_FUNC_keymgmt_load_fn ml_dsa_load;
+static OSSL_FUNC_keymgmt_dup_fn ml_dsa_dup_key;
 static OSSL_FUNC_keymgmt_get_params_fn ml_dsa_get_params;
 static OSSL_FUNC_keymgmt_gettable_params_fn ml_dsa_gettable_params;
 static OSSL_FUNC_keymgmt_validate_fn ml_dsa_validate;
@@ -54,6 +55,13 @@ static void ml_dsa_free_key(void *keydata)
     ossl_ml_dsa_key_free((ML_DSA_KEY *)keydata);
 }
 
+static void *ml_dsa_dup_key(const void *keydata_from, int selection)
+{
+    if (ossl_prov_is_running())
+        return ossl_ml_dsa_key_dup(keydata_from, selection);
+    return NULL;
+}
+
 static int ml_dsa_has(const void *keydata, int selection)
 {
     const ML_DSA_KEY *key = keydata;
@@ -361,6 +369,7 @@ static void ml_dsa_gen_cleanup(void *genctx)
           (void (*)(void))ml_dsa_gen_set_params },                             \
         { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS,                               \
           (void (*)(void))ml_dsa_gen_settable_params },                        \
+        { OSSL_FUNC_KEYMGMT_DUP, (void (*)(void))ml_dsa_dup_key },             \
         OSSL_DISPATCH_END                                                      \
     }
 
index a429bae66f5d77a9ddfa2494ebd7c0c4d3359d8a..a4803859c87b8a3d636e38dd0209d7af1a2a4f7b 100644 (file)
@@ -32,6 +32,7 @@ static OSSL_FUNC_signature_verify_fn ml_dsa_verify;
 static OSSL_FUNC_signature_freectx_fn ml_dsa_freectx;
 static OSSL_FUNC_signature_set_ctx_params_fn ml_dsa_set_ctx_params;
 static OSSL_FUNC_signature_settable_ctx_params_fn ml_dsa_settable_ctx_params;
+static OSSL_FUNC_signature_dupctx_fn ml_dsa_dupctx;
 
 typedef struct {
     ML_DSA_KEY *key;
@@ -71,6 +72,20 @@ static void *ml_dsa_newctx(void *provctx, const char *alg, const char *propq)
     return ctx;
 }
 
+static void *ml_dsa_dupctx(void *vctx)
+{
+    PROV_ML_DSA_CTX *srcctx = (PROV_ML_DSA_CTX *)vctx;
+
+    if (!ossl_prov_is_running())
+        return NULL;
+
+    /*
+     * Note that the ML_DSA_KEY is ref counted via EVP_PKEY so we can just copy
+     * the key here.
+     */
+    return OPENSSL_memdup(srcctx, sizeof(*srcctx));
+}
+
 static int ml_dsa_signverify_msg_init(void *vctx, void *vkey,
                                       const OSSL_PARAM params[], int operation,
                                       const char *desc)
@@ -227,6 +242,7 @@ static const OSSL_PARAM *ml_dsa_settable_ctx_params(void *vctx,
           (void (*)(void))ml_dsa_set_ctx_params },                             \
         { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS,                             \
           (void (*)(void))ml_dsa_settable_ctx_params },                        \
+        { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))ml_dsa_dupctx },         \
         OSSL_DISPATCH_END                                                      \
     }