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?
*
#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;
{
OPENSSL_free(v->poly);
v->poly = NULL;
+ v->num_poly = 0;
}
/* @brief zeroize a vectors polynomial coefficients */
__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);
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;
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;
(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 \
}
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;
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)
(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 \
}