PROV_R_UNABLE_TO_LOAD_SHA256:147:unable to load sha256
PROV_R_UNABLE_TO_LOCK_PARENT:201:unable to lock parent
PROV_R_UNABLE_TO_RESEED:204:unable to reseed
+PROV_R_UNEXPECTED_KEY_OID:245:unexpected key oid
+PROV_R_UNEXPECTED_KEY_PARAMETERS:246:unexpected key parameters
PROV_R_UNSUPPORTED_CEK_ALG:145:unsupported cek alg
PROV_R_UNSUPPORTED_KEY_SIZE:153:unsupported key size
PROV_R_UNSUPPORTED_MAC_TYPE:137:unsupported mac type
return 1;
}
-static int ml_dsa_key_public_from_private(ML_DSA_KEY *key)
+int ossl_ml_dsa_key_public_from_private(ML_DSA_KEY *key)
{
int ret = 0;
VECTOR t0;
|| !ossl_ml_dsa_sk_decode(key, priv_data, priv_data_len))
return 0;
/* Always generate the public key from the private key */
- if (!ml_dsa_key_public_from_private(key))
+ if (!ossl_ml_dsa_key_public_from_private(key))
return 0;
/* Error if the supplied public key does not match the generated key */
if (pub != NULL
uint32_t gamma2);
int ossl_ml_dsa_pk_encode(ML_DSA_KEY *key);
-int ossl_ml_dsa_pk_decode(ML_DSA_KEY *key, const uint8_t *in, size_t in_len);
int ossl_ml_dsa_sk_encode(ML_DSA_KEY *key);
-int ossl_ml_dsa_sk_decode(ML_DSA_KEY *key, const uint8_t *in, size_t in_len);
int ossl_ml_dsa_sig_encode(const ML_DSA_SIG *sig, const ML_DSA_PARAMS *params,
uint8_t *out);
__owur size_t ossl_ml_dsa_key_get_sig_len(const ML_DSA_KEY *key);
__owur const char *ossl_ml_dsa_key_get_name(const ML_DSA_KEY *key);
__owur int ossl_ml_dsa_key_matches(const ML_DSA_KEY *key, const char *alg);
-__owur int ossl_ml_dsa_key_to_text(BIO *out, const ML_DSA_KEY *key, int selection);
void ossl_ml_dsa_key_set0_libctx(ML_DSA_KEY *key, OSSL_LIB_CTX *lib_ctx);
+__owur int ossl_ml_dsa_key_public_from_private(ML_DSA_KEY *key);
+__owur int ossl_ml_dsa_pk_decode(ML_DSA_KEY *key, const uint8_t *in, size_t in_len);
+__owur int ossl_ml_dsa_sk_decode(ML_DSA_KEY *key, const uint8_t *in, size_t in_len);
+
__owur int ossl_ml_dsa_sign(const ML_DSA_KEY *priv,
const uint8_t *msg, size_t msg_len,
const uint8_t *context, size_t context_len,
# define EVP_PKEY_ED25519 NID_ED25519
# define EVP_PKEY_X448 NID_X448
# define EVP_PKEY_ED448 NID_ED448
+# define EVP_PKEY_ML_DSA_44 NID_ML_DSA_44
+# define EVP_PKEY_ML_DSA_65 NID_ML_DSA_65
+# define EVP_PKEY_ML_DSA_87 NID_ML_DSA_87
+
/* Special indicator that the object is uniquely provider side */
# define EVP_PKEY_KEYMGMT -1
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
# define PROV_R_UNABLE_TO_LOAD_SHA256 147
# define PROV_R_UNABLE_TO_LOCK_PARENT 201
# define PROV_R_UNABLE_TO_RESEED 204
+# define PROV_R_UNEXPECTED_KEY_OID 245
+# define PROV_R_UNEXPECTED_KEY_PARAMETERS 246
# define PROV_R_UNSUPPORTED_CEK_ALG 145
# define PROV_R_UNSUPPORTED_KEY_SIZE 153
# define PROV_R_UNSUPPORTED_MAC_TYPE 137
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2020-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
/*
* Generated by util/mkerr.pl DO NOT EDIT
- * Copyright 1995-2024 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2025 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOCK_PARENT),
"unable to lock parent"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_RESEED), "unable to reseed"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNEXPECTED_KEY_OID),
+ "unexpected key oid"},
+ {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNEXPECTED_KEY_PARAMETERS),
+ "unexpected key parameters"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_CEK_ALG),
"unsupported cek alg"},
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_KEY_SIZE),
DECODER_w_structure("RSA-PSS", der, SubjectPublicKeyInfo, rsapss, yes),
DECODER("RSA", msblob, rsa, yes),
DECODER("RSA", pvk, rsa, yes),
+#ifndef OPENSSL_NO_ML_DSA
+DECODER_w_structure("ML-DSA-44", der, PrivateKeyInfo, ml_dsa_44, no),
+DECODER_w_structure("ML-DSA-65", der, PrivateKeyInfo, ml_dsa_65, no),
+DECODER_w_structure("ML-DSA-87", der, PrivateKeyInfo, ml_dsa_87, no),
+DECODER_w_structure("ML-DSA-44", der, SubjectPublicKeyInfo, ml_dsa_44, no),
+DECODER_w_structure("ML-DSA-65", der, SubjectPublicKeyInfo, ml_dsa_65, no),
+DECODER_w_structure("ML-DSA-87", der, SubjectPublicKeyInfo, ml_dsa_87, no),
+#endif /* OPENSSL_NO_ML_DSA */
/*
* A decoder that takes a SubjectPublicKeyInfo and figures out the types of key
# endif
#endif
+# ifndef OPENSSL_NO_ML_DSA
+ENCODER_TEXT("ML-DSA-44", ml_dsa_44, no),
+ENCODER_TEXT("ML-DSA-65", ml_dsa_65, no),
+ENCODER_TEXT("ML-DSA-87", ml_dsa_87, no),
+# endif
+
/*
* Entries for key type specific output formats. The structure name on these
* is the same as the key type name. This allows us to say something like:
# endif
#endif
+# ifndef OPENSSL_NO_ML_DSA
+ENCODER_w_structure("ML-DSA-44", ml_dsa_44, no, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-44", ml_dsa_44, no, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-44", ml_dsa_44, no, der, PrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-44", ml_dsa_44, no, pem, PrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-44", ml_dsa_44, no, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("ML-DSA-44", ml_dsa_44, no, pem, SubjectPublicKeyInfo),
+
+ENCODER_w_structure("ML-DSA-65", ml_dsa_65, no, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-65", ml_dsa_65, no, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-65", ml_dsa_65, no, der, PrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-65", ml_dsa_65, no, pem, PrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-65", ml_dsa_65, no, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("ML-DSA-65", ml_dsa_65, no, pem, SubjectPublicKeyInfo),
+
+ENCODER_w_structure("ML-DSA-87", ml_dsa_87, no, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-87", ml_dsa_87, no, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-87", ml_dsa_87, no, der, PrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-87", ml_dsa_87, no, pem, PrivateKeyInfo),
+ENCODER_w_structure("ML-DSA-87", ml_dsa_87, no, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("ML-DSA-87", ml_dsa_87, no, pem, SubjectPublicKeyInfo),
+# endif /* OPENSSL_NO_ML_DSA */
+
/*
* Entries for key type specific output formats. These are exactly the
* same as the type specific above, except that they use the key type
#include <openssl/pkcs12.h>
#include <openssl/x509.h>
#include <openssl/proverr.h>
+#include <openssl/asn1t.h>
#include "internal/cryptlib.h" /* ossl_assert() */
#include "internal/asn1.h"
#include "crypto/dh.h"
#include "crypto/evp.h"
#include "crypto/ecx.h"
#include "crypto/rsa.h"
+#include "crypto/ml_dsa.h"
#include "crypto/x509.h"
#include "openssl/obj_mac.h"
#include "prov/bio.h"
#include "endecoder_local.h"
#include "internal/nelem.h"
+#ifndef OPENSSL_NO_ML_DSA
+typedef struct {
+ ASN1_OBJECT *oid;
+} BARE_ALGOR;
+
+typedef struct {
+ BARE_ALGOR algor;
+ ASN1_BIT_STRING *pubkey;
+} BARE_PUBKEY;
+
+ASN1_SEQUENCE(BARE_ALGOR) = {
+ ASN1_SIMPLE(BARE_ALGOR, oid, ASN1_OBJECT),
+} static_ASN1_SEQUENCE_END(BARE_ALGOR)
+
+ASN1_SEQUENCE(BARE_PUBKEY) = {
+ ASN1_EMBED(BARE_PUBKEY, algor, BARE_ALGOR),
+ ASN1_SIMPLE(BARE_PUBKEY, pubkey, ASN1_BIT_STRING)
+} static_ASN1_SEQUENCE_END(BARE_PUBKEY)
+#endif /* OPENSSL_NO_ML_DSA */
+
struct der2key_ctx_st; /* Forward declaration */
typedef int check_key_fn(void *, struct der2key_ctx_st *ctx);
typedef void adjust_key_fn(void *, struct der2key_ctx_st *ctx);
/* ---------------------------------------------------------------------- */
+#ifndef OPENSSL_NO_ML_DSA
+static void *
+ml_dsa_d2i_PKCS8(const uint8_t **der, long der_len, struct der2key_ctx_st *ctx)
+{
+ ML_DSA_KEY *key = NULL, *ret = NULL;
+ OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+ PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+ const unsigned char *p;
+ const X509_ALGOR *alg = NULL;
+ int plen, ptype;
+
+ /*
+ * The private key format in PKCS8 is the 64-bytes (d, z) seed pair.
+ * Algorithm parameters must be absent.
+ */
+ if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, der, der_len)) == NULL
+ || !PKCS8_pkey_get0(NULL, &p, &plen, &alg, p8inf))
+ goto end;
+
+ if ((X509_ALGOR_get0(NULL, &ptype, NULL, alg), ptype != V_ASN1_UNDEF)) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_UNEXPECTED_KEY_PARAMETERS,
+ "unexpected parameters with a PKCS#8 %s private key",
+ ctx->desc->keytype_name);
+ goto end;
+ }
+ if (OBJ_obj2nid(alg->algorithm) != ctx->desc->evp_type) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_UNEXPECTED_KEY_OID,
+ "unexpected algorithm OID for a PKCS#8 %s private key",
+ ctx->desc->keytype_name);
+ goto end;
+ }
+ if ((key = ossl_ml_dsa_key_new(libctx, ctx->propq,
+ ctx->desc->keytype_name)) == NULL)
+ goto end;
+
+ if (!ossl_ml_dsa_sk_decode(key, p, plen)
+ || !ossl_ml_dsa_key_public_from_private(key))
+ goto end;
+ ret = key;
+ end:
+ PKCS8_PRIV_KEY_INFO_free(p8inf);
+ if (ret == NULL)
+ ossl_ml_dsa_key_free(key);
+ return ret;
+}
+
+static ossl_inline void * ml_dsa_d2i_PUBKEY(const uint8_t **der, long der_len,
+ struct der2key_ctx_st *ctx)
+{
+ int ok = 0;
+ OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+ ML_DSA_KEY *ret = NULL;
+ BARE_PUBKEY *spki = NULL;
+ const uint8_t *end = *der;
+ size_t len;
+
+ ret = ossl_ml_dsa_key_new(libctx, ctx->propq, ctx->desc->keytype_name);
+ if (ret == NULL)
+ return NULL;
+ len = ossl_ml_dsa_key_get_pub_len(ret);
+
+ /*-
+ * The DER ASN.1 encoding of ML-DSA public keys prepends 22 bytes to the
+ * encoded public key:
+ *
+ * - 4 byte outer sequence tag and length
+ * - 2 byte algorithm sequence tag and length
+ * - 2 byte algorithm OID tag and length
+ * - 9 byte algorithm OID
+ * - 4 byte bit string tag and length
+ * - 1 bitstring lead byte
+ *
+ * Check that we have the right OID, the bit string has no "bits left" and
+ * that we consume all the input exactly.
+ */
+ if (der_len != 22 + (long)len) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_ENCODING,
+ "unexpected %s public key length: %ld != %ld",
+ ctx->desc->keytype_name, der_len,
+ 22 + (long)len);
+ goto err;
+ }
+
+ if ((spki = OPENSSL_zalloc(sizeof(*spki))) == NULL)
+ goto err;
+
+ /* The spki storage is freed on error */
+ if (ASN1_item_d2i_ex((ASN1_VALUE **)&spki, &end, der_len,
+ ASN1_ITEM_rptr(BARE_PUBKEY), NULL, NULL) == NULL) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_ENCODING,
+ "malformed %s public key ASN.1 encoding",
+ ossl_ml_dsa_key_get_name(ret));
+ goto err;
+ }
+
+ /* The spki structure now owns some memory */
+ if ((spki->pubkey->flags & 0x7) != 0 || end != *der + der_len) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_ENCODING,
+ "malformed %s public key ASN.1 encoding",
+ ossl_ml_dsa_key_get_name(ret));
+ goto err;
+ }
+ if (OBJ_cmp(OBJ_nid2obj(ctx->desc->evp_type), spki->algor.oid) != 0) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_ENCODING,
+ "unexpected algorithm OID for an %s public key",
+ ossl_ml_dsa_key_get_name(ret));
+ goto err;
+ }
+
+ if (!ossl_ml_dsa_pk_decode(ret, spki->pubkey->data, spki->pubkey->length)) {
+ ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_ENCODING,
+ "failed to parse %s public key from the input data",
+ ossl_ml_dsa_key_get_name(ret));
+ goto err;
+ }
+ ok = 1;
+ err:
+ if (spki != NULL) {
+ ASN1_OBJECT_free(spki->algor.oid);
+ ASN1_BIT_STRING_free(spki->pubkey);
+ OPENSSL_free(spki);
+ }
+ if (!ok) {
+ ossl_ml_dsa_key_free(ret);
+ ret = NULL;
+ }
+ return ret;
+}
+
+# define ml_dsa_44_evp_type EVP_PKEY_ML_DSA_44
+# define ml_dsa_44_d2i_private_key NULL
+# define ml_dsa_44_d2i_public_key NULL
+# define ml_dsa_44_d2i_key_params NULL
+# define ml_dsa_44_d2i_PUBKEY ml_dsa_d2i_PUBKEY
+# define ml_dsa_44_d2i_PKCS8 ml_dsa_d2i_PKCS8
+# define ml_dsa_44_free (free_key_fn *)ossl_ml_dsa_key_free
+# define ml_dsa_44_check NULL
+# define ml_dsa_44_adjust NULL
+
+# define ml_dsa_65_evp_type EVP_PKEY_ML_DSA_65
+# define ml_dsa_65_d2i_private_key NULL
+# define ml_dsa_65_d2i_public_key NULL
+# define ml_dsa_65_d2i_key_params NULL
+# define ml_dsa_65_d2i_PUBKEY ml_dsa_d2i_PUBKEY
+# define ml_dsa_65_d2i_PKCS8 ml_dsa_d2i_PKCS8
+# define ml_dsa_65_free (free_key_fn *)ossl_ml_dsa_key_free
+# define ml_dsa_65_check NULL
+# define ml_dsa_65_adjust NULL
+
+# define ml_dsa_87_evp_type EVP_PKEY_ML_DSA_87
+# define ml_dsa_87_d2i_private_key NULL
+# define ml_dsa_87_d2i_public_key NULL
+# define ml_dsa_87_d2i_PUBKEY ml_dsa_d2i_PUBKEY
+# define ml_dsa_87_d2i_PKCS8 ml_dsa_d2i_PKCS8
+# define ml_dsa_87_d2i_key_params NULL
+# define ml_dsa_87_free (free_key_fn *)ossl_ml_dsa_key_free
+# define ml_dsa_87_check NULL
+# define ml_dsa_87_adjust NULL
+
+#endif
+
+/* ---------------------------------------------------------------------- */
+
/*
* The DO_ macros help define the selection mask and the method functions
* for each kind of object we want to decode.
MAKE_DECODER("RSA", rsa, rsa, RSA);
MAKE_DECODER("RSA-PSS", rsapss, rsapss, PrivateKeyInfo);
MAKE_DECODER("RSA-PSS", rsapss, rsapss, SubjectPublicKeyInfo);
+
+#ifndef OPENSSL_NO_ML_DSA
+MAKE_DECODER("ML-DSA-44", ml_dsa_44, ml_dsa_44, PrivateKeyInfo);
+MAKE_DECODER("ML-DSA-44", ml_dsa_44, ml_dsa_44, SubjectPublicKeyInfo);
+MAKE_DECODER("ML-DSA-65", ml_dsa_65, ml_dsa_65, PrivateKeyInfo);
+MAKE_DECODER("ML-DSA-65", ml_dsa_65, ml_dsa_65, SubjectPublicKeyInfo);
+MAKE_DECODER("ML-DSA-87", ml_dsa_87, ml_dsa_87, PrivateKeyInfo);
+MAKE_DECODER("ML-DSA-87", ml_dsa_87, ml_dsa_87, SubjectPublicKeyInfo);
+#endif
#include "internal/cryptlib.h"
#include "crypto/ecx.h"
#include "crypto/rsa.h"
+#include "crypto/ml_dsa.h"
#include "prov/implementations.h"
#include "prov/bio.h"
#include "prov/provider_ctx.h"
/* ---------------------------------------------------------------------- */
+#ifndef OPENSSL_NO_ML_DSA
+static int ml_dsa_spki_pub_to_der(const void *vkey, unsigned char **pder)
+{
+ const ML_DSA_KEY *key = vkey;
+ size_t publen;
+
+ if (ossl_ml_dsa_key_get_pub(key) == NULL) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ publen = ossl_ml_dsa_key_get_pub_len(key);
+
+ if (pder != NULL
+ && ((*pder = OPENSSL_memdup(ossl_ml_dsa_key_get_pub(key),
+ publen)) == NULL))
+ return 0;
+
+ return publen;
+}
+
+static int ml_dsa_pki_priv_to_der(const void *vkey, unsigned char **pder)
+{
+ const ML_DSA_KEY *key = vkey;
+ size_t len;
+
+ if (ossl_ml_dsa_key_get_priv(key) == NULL) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ len = ossl_ml_dsa_key_get_priv_len(key);
+
+ if (pder != NULL
+ && ((*pder = OPENSSL_memdup(ossl_ml_dsa_key_get_priv(key), len)) == NULL))
+ return 0;
+
+ return len;
+}
+
+# define ml_dsa_epki_priv_to_der ml_dsa_pki_priv_to_der
+# define prepare_ml_dsa_params NULL
+# define ml_dsa_check_key_type NULL
+
+# define ml_dsa_44_evp_type EVP_PKEY_ML_DSA_44
+# define ml_dsa_44_pem_type "ML-DSA-44"
+# define ml_dsa_65_evp_type EVP_PKEY_ML_DSA_65
+# define ml_dsa_65_pem_type "ML-DSA-65"
+# define ml_dsa_87_evp_type EVP_PKEY_ML_DSA_87
+# define ml_dsa_87_pem_type "ML-DSA-87"
+#endif /* OPENSSL_NO_ML_DSA */
+
+/* ---------------------------------------------------------------------- */
+
/*
* Helper functions to prepare RSA-PSS params for encoding. We would
* have simply written the whole AlgorithmIdentifier, but existing libcrypto
MAKE_ENCODER(ec, ec, X9_62, der);
MAKE_ENCODER(ec, ec, X9_62, pem);
#endif
+
+#ifndef OPENSSL_NO_ML_DSA
+MAKE_ENCODER(ml_dsa_44, ml_dsa, EVP_PKEY_ML_DSA_44, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(ml_dsa_44, ml_dsa, EVP_PKEY_ML_DSA_44, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(ml_dsa_44, ml_dsa, EVP_PKEY_ML_DSA_44, PrivateKeyInfo, der);
+MAKE_ENCODER(ml_dsa_44, ml_dsa, EVP_PKEY_ML_DSA_44, PrivateKeyInfo, pem);
+MAKE_ENCODER(ml_dsa_44, ml_dsa, EVP_PKEY_ML_DSA_44, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(ml_dsa_44, ml_dsa, EVP_PKEY_ML_DSA_44, SubjectPublicKeyInfo, pem);
+
+MAKE_ENCODER(ml_dsa_65, ml_dsa, EVP_PKEY_ML_DSA_65, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(ml_dsa_65, ml_dsa, EVP_PKEY_ML_DSA_65, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(ml_dsa_65, ml_dsa, EVP_PKEY_ML_DSA_65, PrivateKeyInfo, der);
+MAKE_ENCODER(ml_dsa_65, ml_dsa, EVP_PKEY_ML_DSA_65, PrivateKeyInfo, pem);
+MAKE_ENCODER(ml_dsa_65, ml_dsa, EVP_PKEY_ML_DSA_65, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(ml_dsa_65, ml_dsa, EVP_PKEY_ML_DSA_65, SubjectPublicKeyInfo, pem);
+
+MAKE_ENCODER(ml_dsa_87, ml_dsa, EVP_PKEY_ML_DSA_87, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(ml_dsa_87, ml_dsa, EVP_PKEY_ML_DSA_87, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(ml_dsa_87, ml_dsa, EVP_PKEY_ML_DSA_87, PrivateKeyInfo, der);
+MAKE_ENCODER(ml_dsa_87, ml_dsa, EVP_PKEY_ML_DSA_87, PrivateKeyInfo, pem);
+MAKE_ENCODER(ml_dsa_87, ml_dsa, EVP_PKEY_ML_DSA_87, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(ml_dsa_87, ml_dsa, EVP_PKEY_ML_DSA_87, SubjectPublicKeyInfo, pem);
+#endif /* OPENSSL_NO_ML_DSA */
#include "crypto/ec.h" /* ossl_ec_key_get_libctx */
#include "crypto/ecx.h" /* ECX_KEY, etc... */
#include "crypto/rsa.h" /* RSA_PSS_PARAMS_30, etc... */
+#include "crypto/ml_dsa.h"
#include "prov/bio.h"
#include "prov/implementations.h"
#include "internal/encoder.h"
/* ---------------------------------------------------------------------- */
+#ifndef OPENSSL_NO_ML_DSA
+static int ml_dsa_to_text(BIO *out, const void *key, int selection)
+{
+ const char *name;
+
+ if (out == NULL || key == NULL) {
+ ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+ return 0;
+ }
+ if (ossl_ml_dsa_key_get_pub(key) == NULL) {
+ /* Regardless of the |selection|, there must be a public key */
+ ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY);
+ return 0;
+ }
+
+ name = ossl_ml_dsa_key_get_name(key);
+ if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+ if (ossl_ml_dsa_key_get_priv(key) == NULL) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY);
+ return 0;
+ }
+ if (BIO_printf(out, "%s Private-Key:\n", name) <= 0)
+ return 0;
+ if (!ossl_bio_print_labeled_buf(out, "priv:",
+ ossl_ml_dsa_key_get_priv(key),
+ ossl_ml_dsa_key_get_priv_len(key)))
+ return 0;
+ } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+ if (BIO_printf(out, "%s Public-Key:\n", name) <= 0)
+ return 0;
+ }
+
+ if (!ossl_bio_print_labeled_buf(out, "pub:",
+ ossl_ml_dsa_key_get_pub(key),
+ ossl_ml_dsa_key_get_pub_len(key)))
+ return 0;
+
+ return 1;
+}
+#endif /* OPENSSL_NO_ML_DSA */
+
+/* ---------------------------------------------------------------------- */
+
static void *key2text_newctx(void *provctx)
{
return provctx;
#endif
MAKE_TEXT_ENCODER(rsa, rsa);
MAKE_TEXT_ENCODER(rsapss, rsa);
+
+#ifndef OPENSSL_NO_ML_DSA
+MAKE_TEXT_ENCODER(ml_dsa_44, ml_dsa);
+MAKE_TEXT_ENCODER(ml_dsa_65, ml_dsa);
+MAKE_TEXT_ENCODER(ml_dsa_87, ml_dsa);
+#endif
extern const OSSL_DISPATCH ossl_x448_to_OSSL_current_der_encoder_functions[];
extern const OSSL_DISPATCH ossl_x448_to_text_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_44_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_44_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_44_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_44_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_44_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_44_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_44_to_OSSL_current_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_44_to_text_encoder_functions[];
+
+extern const OSSL_DISPATCH ossl_ml_dsa_65_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_65_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_65_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_65_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_65_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_65_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_65_to_OSSL_current_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_65_to_text_encoder_functions[];
+
+extern const OSSL_DISPATCH ossl_ml_dsa_87_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_87_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_87_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_87_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_87_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_87_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_87_to_OSSL_current_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_dsa_87_to_text_encoder_functions[];
+
/* Decoders */
extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_dh_decoder_functions[];
extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_dh_decoder_functions[];
extern const OSSL_DISPATCH ossl_file_store_functions[];
extern const OSSL_DISPATCH ossl_winstore_store_functions[];
+
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ml_dsa_44_decoder_functions[];
+extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ml_dsa_44_decoder_functions[];
+
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ml_dsa_65_decoder_functions[];
+extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ml_dsa_65_decoder_functions[];
+
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ml_dsa_87_decoder_functions[];
+extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ml_dsa_87_decoder_functions[];
}
#endif
-#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC)
+#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) \
+ || !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_ML_DSA)
static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
OSSL_PARAM *genparams)
{
IMPLEMENT_TEST_SUITE_PROTECTED_PVK(RSA, "RSA")
#endif
+#ifndef OPENSSL_ML_DSA
+KEYS(ML_DSA_44);
+KEYS(ML_DSA_65);
+KEYS(ML_DSA_87);
+IMPLEMENT_TEST_SUITE(ML_DSA_44, "ML-DSA-44", 0)
+IMPLEMENT_TEST_SUITE(ML_DSA_65, "ML-DSA-65", 0)
+IMPLEMENT_TEST_SUITE(ML_DSA_87, "ML-DSA-87", 0)
+#endif /* OPENSSL_ML_DSA */
+
#ifndef OPENSSL_NO_EC
/* Explicit parameters that match a named curve */
static int do_create_ec_explicit_prime_params(OSSL_PARAM_BLD *bld,
MAKE_KEYS(X25519, "X25519", NULL);
MAKE_KEYS(X448, "X448", NULL);
#endif
+#ifndef OPENSSL_ML_DSA
+ MAKE_KEYS(ML_DSA_44, "ML-DSA-44", NULL);
+ MAKE_KEYS(ML_DSA_65, "ML-DSA-65", NULL);
+ MAKE_KEYS(ML_DSA_87, "ML-DSA-87", NULL);
+#endif /* OPENSSL_ML_DSA */
+
TEST_info("Loading RSA key...");
ok = ok && TEST_ptr(key_RSA = load_pkey_pem(rsa_file, keyctx));
TEST_info("Loading RSA_PSS key...");
# ifndef OPENSSL_NO_RC4
ADD_TEST_SUITE_PROTECTED_PVK(RSA);
# endif
+
+#ifndef OPENSSL_ML_DSA
+ ADD_TEST_SUITE(ML_DSA_44);
+ ADD_TEST_SUITE(ML_DSA_65);
+ ADD_TEST_SUITE(ML_DSA_87);
+#endif /* OPENSSL_ML_DSA */
}
return 1;
FREE_KEYS(RSA);
FREE_KEYS(RSA_PSS);
+#ifndef OPENSSL_ML_DSA
+ FREE_KEYS(ML_DSA_44);
+ FREE_KEYS(ML_DSA_65);
+ FREE_KEYS(ML_DSA_87);
+#endif /* OPENSSL_ML_DSA */
+
OSSL_PROVIDER_unload(nullprov);
OSSL_PROVIDER_unload(deflprov);
OSSL_PROVIDER_unload(keyprov);