diff options
| author | Enji Cooper <ngie@FreeBSD.org> | 2025-05-07 21:18:24 +0000 |
|---|---|---|
| committer | Enji Cooper <ngie@FreeBSD.org> | 2025-05-07 22:37:22 +0000 |
| commit | 29536654cc41bf41b92dc836c47496dc6fe0b00c (patch) | |
| tree | 368a3c5b14e610bb5f6b71657f61a41e373eaf97 /providers/implementations/encode_decode | |
| parent | 1c34280346af8284acdc0eae39496811d37df25d (diff) | |
Diffstat (limited to 'providers/implementations/encode_decode')
11 files changed, 1383 insertions, 552 deletions
diff --git a/providers/implementations/encode_decode/build.info b/providers/implementations/encode_decode/build.info index d3f6ca4abdef..a1529fdf1258 100644 --- a/providers/implementations/encode_decode/build.info +++ b/providers/implementations/encode_decode/build.info @@ -18,3 +18,15 @@ IF[{- !$disabled{ec} -}] SOURCE[$ENCODER_GOAL]=encode_key2blob.c ENDIF DEPEND[encode_key2any.o]=../../common/include/prov/der_rsa.h + +IF[{- !$disabled{'ml-dsa'} -}] + SOURCE[$DECODER_GOAL]=ml_dsa_codecs.c +ENDIF + +IF[{- !$disabled{'ml-kem'} -}] + SOURCE[$DECODER_GOAL]=ml_kem_codecs.c +ENDIF + +IF[{- !$disabled{'ml-dsa'} || !$disabled{'ml-kem'} -}] + SOURCE[$DECODER_GOAL]=ml_common_codecs.c +ENDIF diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c index f2d9d8255648..a3f0d0897dae 100644 --- a/providers/implementations/encode_decode/decode_der2key.c +++ b/providers/implementations/encode_decode/decode_der2key.c @@ -1,5 +1,5 @@ /* - * 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 @@ -13,6 +13,7 @@ */ #include "internal/deprecated.h" +#include <openssl/byteorder.h> #include <openssl/core_dispatch.h> #include <openssl/core_names.h> #include <openssl/core_object.h> @@ -21,28 +22,57 @@ #include <openssl/params.h> #include <openssl/pem.h> /* PEM_BUFSIZE and public PEM functions */ #include <openssl/pkcs12.h> +#include <openssl/provider.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/dsa.h" #include "crypto/ec.h" #include "crypto/evp.h" #include "crypto/ecx.h" #include "crypto/rsa.h" +#include "crypto/ml_dsa.h" +#include "crypto/slh_dsa.h" #include "crypto/x509.h" +#include "crypto/ml_kem.h" #include "openssl/obj_mac.h" #include "prov/bio.h" #include "prov/implementations.h" #include "endecoder_local.h" +#include "internal/nelem.h" +#include "ml_dsa_codecs.h" +#include "ml_kem_codecs.h" + +#ifndef OPENSSL_NO_SLH_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_SLH_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); typedef void free_key_fn(void *); -typedef void *d2i_PKCS8_fn(void **, const unsigned char **, long, +typedef void *d2i_PKCS8_fn(const unsigned char **, long, struct der2key_ctx_st *); +typedef void *d2i_PUBKEY_fn(const unsigned char **, long, + struct der2key_ctx_st *); struct keytype_desc_st { const char *keytype_name; const OSSL_DISPATCH *fns; /* Keymgmt (to pilfer functions from) */ @@ -66,7 +96,7 @@ struct keytype_desc_st { d2i_of_void *d2i_public_key; /* From type-specific DER */ d2i_of_void *d2i_key_params; /* From type-specific DER */ d2i_PKCS8_fn *d2i_PKCS8; /* Wrapped in a PrivateKeyInfo */ - d2i_of_void *d2i_PUBKEY; /* Wrapped in a SubjectPublicKeyInfo */ + d2i_PUBKEY_fn *d2i_PUBKEY; /* Wrapped in a SubjectPublicKeyInfo */ /* * For any key, we may need to check that the key meets expectations. @@ -89,6 +119,7 @@ struct keytype_desc_st { */ struct der2key_ctx_st { PROV_CTX *provctx; + char propq[OSSL_MAX_PROPQUERY_SIZE]; const struct keytype_desc_st *desc; /* The selection that is passed to der2key_decode() */ int selection; @@ -112,7 +143,7 @@ static void *der2key_decode_p8(const unsigned char **input_der, /* Allow decoding sm2 private key with id_ecPublicKey */ || (OBJ_obj2nid(alg->algorithm) == NID_X9_62_id_ecPublicKey && ctx->desc->evp_type == NID_sm2))) - key = key_from_pkcs8(p8inf, PROV_LIBCTX_OF(ctx->provctx), NULL); + key = key_from_pkcs8(p8inf, PROV_LIBCTX_OF(ctx->provctx), ctx->propq); PKCS8_PRIV_KEY_INFO_free(p8inf); return key; @@ -123,6 +154,8 @@ static void *der2key_decode_p8(const unsigned char **input_der, static OSSL_FUNC_decoder_freectx_fn der2key_freectx; static OSSL_FUNC_decoder_decode_fn der2key_decode; static OSSL_FUNC_decoder_export_object_fn der2key_export_object; +static OSSL_FUNC_decoder_settable_ctx_params_fn der2key_settable_ctx_params; +static OSSL_FUNC_decoder_set_ctx_params_fn der2key_set_ctx_params; static struct der2key_ctx_st * der2key_newctx(void *provctx, const struct keytype_desc_st *desc) @@ -136,6 +169,28 @@ der2key_newctx(void *provctx, const struct keytype_desc_st *desc) return ctx; } +static const OSSL_PARAM *der2key_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END + }; + return settables; +} + +static int der2key_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct der2key_ctx_st *ctx = vctx; + const OSSL_PARAM *p; + char *str = ctx->propq; + + p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); + if (p != NULL && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) + return 0; + + return 1; +} + static void der2key_freectx(void *vctx) { struct der2key_ctx_st *ctx = vctx; @@ -190,7 +245,7 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, ctx->selection = selection; /* - * The caller is allowed to specify 0 as a selection mark, to have the + * The caller is allowed to specify 0 as a selection mask, to have the * structure and key type guessed. For type-specific structures, this * is not recommended, as some structures are very similar. * Note that 0 isn't the same as OSSL_KEYMGMT_SELECT_ALL, as the latter @@ -214,7 +269,7 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { derp = der; if (ctx->desc->d2i_PKCS8 != NULL) { - key = ctx->desc->d2i_PKCS8(NULL, &derp, der_len, ctx); + key = ctx->desc->d2i_PKCS8(&derp, der_len, ctx); if (ctx->flag_fatal) { ERR_clear_last_mark(); goto end; @@ -230,7 +285,7 @@ static int der2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, if (key == NULL && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { derp = der; if (ctx->desc->d2i_PUBKEY != NULL) - key = ctx->desc->d2i_PUBKEY(NULL, &derp, der_len); + key = ctx->desc->d2i_PUBKEY(&derp, der_len, ctx); else if (ctx->desc->d2i_public_key != NULL) key = ctx->desc->d2i_public_key(NULL, &derp, der_len); if (key == NULL && ctx->selection != 0) { @@ -341,6 +396,14 @@ static int der2key_export_object(void *vctx, return 0; } +#define D2I_PUBKEY_NOCTX(n, f) \ + static void * \ + n##_d2i_PUBKEY(const unsigned char **der, long der_len, \ + ossl_unused struct der2key_ctx_st *ctx) \ + { \ + return f(NULL, der, der_len); \ + } + /* ---------------------------------------------------------------------- */ #ifndef OPENSSL_NO_DH @@ -348,17 +411,18 @@ static int der2key_export_object(void *vctx, # define dh_d2i_private_key NULL # define dh_d2i_public_key NULL # define dh_d2i_key_params (d2i_of_void *)d2i_DHparams +# define dh_free (free_key_fn *)DH_free +# define dh_check NULL -static void *dh_d2i_PKCS8(void **key, const unsigned char **der, long der_len, +static void *dh_d2i_PKCS8(const unsigned char **der, long der_len, struct der2key_ctx_st *ctx) { return der2key_decode_p8(der, der_len, ctx, (key_from_pkcs8_t *)ossl_dh_key_from_pkcs8); } -# define dh_d2i_PUBKEY (d2i_of_void *)ossl_d2i_DH_PUBKEY -# define dh_free (free_key_fn *)DH_free -# define dh_check NULL +D2I_PUBKEY_NOCTX(dh, ossl_d2i_DH_PUBKEY) +D2I_PUBKEY_NOCTX(dhx, ossl_d2i_DHx_PUBKEY) static void dh_adjust(void *key, struct der2key_ctx_st *ctx) { @@ -370,7 +434,6 @@ static void dh_adjust(void *key, struct der2key_ctx_st *ctx) # define dhx_d2i_public_key NULL # define dhx_d2i_key_params (d2i_of_void *)d2i_DHxparams # define dhx_d2i_PKCS8 dh_d2i_PKCS8 -# define dhx_d2i_PUBKEY (d2i_of_void *)ossl_d2i_DHx_PUBKEY # define dhx_free (free_key_fn *)DH_free # define dhx_check NULL # define dhx_adjust dh_adjust @@ -383,17 +446,17 @@ static void dh_adjust(void *key, struct der2key_ctx_st *ctx) # define dsa_d2i_private_key (d2i_of_void *)d2i_DSAPrivateKey # define dsa_d2i_public_key (d2i_of_void *)d2i_DSAPublicKey # define dsa_d2i_key_params (d2i_of_void *)d2i_DSAparams +# define dsa_free (free_key_fn *)DSA_free +# define dsa_check NULL -static void *dsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len, +static void *dsa_d2i_PKCS8(const unsigned char **der, long der_len, struct der2key_ctx_st *ctx) { return der2key_decode_p8(der, der_len, ctx, (key_from_pkcs8_t *)ossl_dsa_key_from_pkcs8); } -# define dsa_d2i_PUBKEY (d2i_of_void *)ossl_d2i_DSA_PUBKEY -# define dsa_free (free_key_fn *)DSA_free -# define dsa_check NULL +D2I_PUBKEY_NOCTX(dsa, ossl_d2i_DSA_PUBKEY) static void dsa_adjust(void *key, struct der2key_ctx_st *ctx) { @@ -408,16 +471,16 @@ static void dsa_adjust(void *key, struct der2key_ctx_st *ctx) # define ec_d2i_private_key (d2i_of_void *)d2i_ECPrivateKey # define ec_d2i_public_key NULL # define ec_d2i_key_params (d2i_of_void *)d2i_ECParameters +# define ec_free (free_key_fn *)EC_KEY_free -static void *ec_d2i_PKCS8(void **key, const unsigned char **der, long der_len, +static void *ec_d2i_PKCS8(const unsigned char **der, long der_len, struct der2key_ctx_st *ctx) { return der2key_decode_p8(der, der_len, ctx, (key_from_pkcs8_t *)ossl_ec_key_from_pkcs8); } -# define ec_d2i_PUBKEY (d2i_of_void *)d2i_EC_PUBKEY -# define ec_free (free_key_fn *)EC_KEY_free +D2I_PUBKEY_NOCTX(ec, d2i_EC_PUBKEY) static int ec_check(void *key, struct der2key_ctx_st *ctx) { @@ -439,111 +502,429 @@ static void ec_adjust(void *key, struct der2key_ctx_st *ctx) ossl_ec_key_set0_libctx(key, PROV_LIBCTX_OF(ctx->provctx)); } +# ifndef OPENSSL_NO_ECX /* * ED25519, ED448, X25519, X448 only implement PKCS#8 and SubjectPublicKeyInfo, * so no d2i functions to be had. */ -static void *ecx_d2i_PKCS8(void **key, const unsigned char **der, long der_len, +static void *ecx_d2i_PKCS8(const unsigned char **der, long der_len, struct der2key_ctx_st *ctx) { return der2key_decode_p8(der, der_len, ctx, (key_from_pkcs8_t *)ossl_ecx_key_from_pkcs8); } +D2I_PUBKEY_NOCTX(ed25519, ossl_d2i_ED25519_PUBKEY) +D2I_PUBKEY_NOCTX(ed448, ossl_d2i_ED448_PUBKEY) +D2I_PUBKEY_NOCTX(x25519, ossl_d2i_X25519_PUBKEY) +D2I_PUBKEY_NOCTX(x448, ossl_d2i_X448_PUBKEY) + static void ecx_key_adjust(void *key, struct der2key_ctx_st *ctx) { ossl_ecx_key_set0_libctx(key, PROV_LIBCTX_OF(ctx->provctx)); } -# define ed25519_evp_type EVP_PKEY_ED25519 -# define ed25519_d2i_private_key NULL -# define ed25519_d2i_public_key NULL -# define ed25519_d2i_key_params NULL -# define ed25519_d2i_PKCS8 ecx_d2i_PKCS8 -# define ed25519_d2i_PUBKEY (d2i_of_void *)ossl_d2i_ED25519_PUBKEY -# define ed25519_free (free_key_fn *)ossl_ecx_key_free -# define ed25519_check NULL -# define ed25519_adjust ecx_key_adjust +# define ed25519_evp_type EVP_PKEY_ED25519 +# define ed25519_d2i_private_key NULL +# define ed25519_d2i_public_key NULL +# define ed25519_d2i_key_params NULL +# define ed25519_d2i_PKCS8 ecx_d2i_PKCS8 +# define ed25519_free (free_key_fn *)ossl_ecx_key_free +# define ed25519_check NULL +# define ed25519_adjust ecx_key_adjust -# define ed448_evp_type EVP_PKEY_ED448 -# define ed448_d2i_private_key NULL -# define ed448_d2i_public_key NULL -# define ed448_d2i_key_params NULL -# define ed448_d2i_PKCS8 ecx_d2i_PKCS8 -# define ed448_d2i_PUBKEY (d2i_of_void *)ossl_d2i_ED448_PUBKEY -# define ed448_free (free_key_fn *)ossl_ecx_key_free -# define ed448_check NULL -# define ed448_adjust ecx_key_adjust +# define ed448_evp_type EVP_PKEY_ED448 +# define ed448_d2i_private_key NULL +# define ed448_d2i_public_key NULL +# define ed448_d2i_key_params NULL +# define ed448_d2i_PKCS8 ecx_d2i_PKCS8 +# define ed448_free (free_key_fn *)ossl_ecx_key_free +# define ed448_check NULL +# define ed448_adjust ecx_key_adjust -# define x25519_evp_type EVP_PKEY_X25519 -# define x25519_d2i_private_key NULL -# define x25519_d2i_public_key NULL -# define x25519_d2i_key_params NULL -# define x25519_d2i_PKCS8 ecx_d2i_PKCS8 -# define x25519_d2i_PUBKEY (d2i_of_void *)ossl_d2i_X25519_PUBKEY -# define x25519_free (free_key_fn *)ossl_ecx_key_free -# define x25519_check NULL -# define x25519_adjust ecx_key_adjust +# define x25519_evp_type EVP_PKEY_X25519 +# define x25519_d2i_private_key NULL +# define x25519_d2i_public_key NULL +# define x25519_d2i_key_params NULL +# define x25519_d2i_PKCS8 ecx_d2i_PKCS8 +# define x25519_free (free_key_fn *)ossl_ecx_key_free +# define x25519_check NULL +# define x25519_adjust ecx_key_adjust -# define x448_evp_type EVP_PKEY_X448 -# define x448_d2i_private_key NULL -# define x448_d2i_public_key NULL -# define x448_d2i_key_params NULL -# define x448_d2i_PKCS8 ecx_d2i_PKCS8 -# define x448_d2i_PUBKEY (d2i_of_void *)ossl_d2i_X448_PUBKEY -# define x448_free (free_key_fn *)ossl_ecx_key_free -# define x448_check NULL -# define x448_adjust ecx_key_adjust +# define x448_evp_type EVP_PKEY_X448 +# define x448_d2i_private_key NULL +# define x448_d2i_public_key NULL +# define x448_d2i_key_params NULL +# define x448_d2i_PKCS8 ecx_d2i_PKCS8 +# define x448_free (free_key_fn *)ossl_ecx_key_free +# define x448_check NULL +# define x448_adjust ecx_key_adjust +# endif /* OPENSSL_NO_ECX */ # ifndef OPENSSL_NO_SM2 # define sm2_evp_type EVP_PKEY_SM2 # define sm2_d2i_private_key (d2i_of_void *)d2i_ECPrivateKey # define sm2_d2i_public_key NULL # define sm2_d2i_key_params (d2i_of_void *)d2i_ECParameters +# define sm2_d2i_PUBKEY ec_d2i_PUBKEY +# define sm2_free (free_key_fn *)EC_KEY_free +# define sm2_check ec_check +# define sm2_adjust ec_adjust -static void *sm2_d2i_PKCS8(void **key, const unsigned char **der, long der_len, +static void *sm2_d2i_PKCS8(const unsigned char **der, long der_len, struct der2key_ctx_st *ctx) { return der2key_decode_p8(der, der_len, ctx, (key_from_pkcs8_t *)ossl_ec_key_from_pkcs8); } - -# define sm2_d2i_PUBKEY (d2i_of_void *)d2i_EC_PUBKEY -# define sm2_free (free_key_fn *)EC_KEY_free -# define sm2_check ec_check -# define sm2_adjust ec_adjust # endif + #endif /* ---------------------------------------------------------------------- */ +#ifndef OPENSSL_NO_ML_KEM +static void * +ml_kem_d2i_PKCS8(const uint8_t **der, long der_len, struct der2key_ctx_st *ctx) +{ + ML_KEM_KEY *key; + + key = ossl_ml_kem_d2i_PKCS8(*der, der_len, ctx->desc->evp_type, + ctx->provctx, ctx->propq); + if (key != NULL) + *der += der_len; + return key; +} + +static ossl_inline void * +ml_kem_d2i_PUBKEY(const uint8_t **der, long der_len, + struct der2key_ctx_st *ctx) +{ + ML_KEM_KEY *key; + + key = ossl_ml_kem_d2i_PUBKEY(*der, der_len, ctx->desc->evp_type, + ctx->provctx, ctx->propq); + if (key != NULL) + *der += der_len; + return key; +} + +# define ml_kem_512_evp_type EVP_PKEY_ML_KEM_512 +# define ml_kem_512_d2i_private_key NULL +# define ml_kem_512_d2i_public_key NULL +# define ml_kem_512_d2i_key_params NULL +# define ml_kem_512_d2i_PUBKEY ml_kem_d2i_PUBKEY +# define ml_kem_512_d2i_PKCS8 ml_kem_d2i_PKCS8 +# define ml_kem_512_free (free_key_fn *)ossl_ml_kem_key_free +# define ml_kem_512_check NULL +# define ml_kem_512_adjust NULL + +# define ml_kem_768_evp_type EVP_PKEY_ML_KEM_768 +# define ml_kem_768_d2i_private_key NULL +# define ml_kem_768_d2i_public_key NULL +# define ml_kem_768_d2i_key_params NULL +# define ml_kem_768_d2i_PUBKEY ml_kem_d2i_PUBKEY +# define ml_kem_768_d2i_PKCS8 ml_kem_d2i_PKCS8 +# define ml_kem_768_free (free_key_fn *)ossl_ml_kem_key_free +# define ml_kem_768_check NULL +# define ml_kem_768_adjust NULL + +# define ml_kem_1024_evp_type EVP_PKEY_ML_KEM_1024 +# define ml_kem_1024_d2i_private_key NULL +# define ml_kem_1024_d2i_public_key NULL +# define ml_kem_1024_d2i_PUBKEY ml_kem_d2i_PUBKEY +# define ml_kem_1024_d2i_PKCS8 ml_kem_d2i_PKCS8 +# define ml_kem_1024_d2i_key_params NULL +# define ml_kem_1024_free (free_key_fn *)ossl_ml_kem_key_free +# define ml_kem_1024_check NULL +# define ml_kem_1024_adjust NULL + +#endif + +#ifndef OPENSSL_NO_SLH_DSA +static void * +slh_dsa_d2i_PKCS8(const uint8_t **der, long der_len, struct der2key_ctx_st *ctx) +{ + SLH_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; + + if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, der, der_len)) == NULL + || !PKCS8_pkey_get0(NULL, &p, &plen, &alg, p8inf)) + goto end; + + /* Algorithm parameters must be absent. */ + 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) + goto end; + if ((key = ossl_slh_dsa_key_new(libctx, ctx->propq, + ctx->desc->keytype_name)) == NULL) + goto end; + + if (!ossl_slh_dsa_set_priv(key, p, plen)) + goto end; + ret = key; + end: + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (ret == NULL) + ossl_slh_dsa_key_free(key); + return ret; +} + +static ossl_inline void *slh_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); + SLH_DSA_KEY *ret = NULL; + BARE_PUBKEY *spki = NULL; + const uint8_t *end = *der; + size_t len; + + ret = ossl_slh_dsa_key_new(libctx, ctx->propq, ctx->desc->keytype_name); + if (ret == NULL) + return NULL; + len = ossl_slh_dsa_key_get_pub_len(ret); + + /*- + * The DER ASN.1 encoding of SLH-DSA public keys prepends 18 bytes to the + * encoded public key (since the largest public key size is 64 bytes): + * + * - 2 byte outer sequence tag and length + * - 2 byte algorithm sequence tag and length + * - 2 byte algorithm OID tag and length + * - 9 byte algorithm OID + * - 2 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 != 18 + (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, + 18 + (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_slh_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_slh_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_slh_dsa_key_get_name(ret)); + goto err; + } + + if (!ossl_slh_dsa_set_pub(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_slh_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_slh_dsa_key_free(ret); + ret = NULL; + } + return ret; +} + +# define slh_dsa_sha2_128s_evp_type EVP_PKEY_SLH_DSA_SHA2_128S +# define slh_dsa_sha2_128s_d2i_private_key NULL +# define slh_dsa_sha2_128s_d2i_public_key NULL +# define slh_dsa_sha2_128s_d2i_key_params NULL +# define slh_dsa_sha2_128s_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_sha2_128s_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_sha2_128s_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_sha2_128s_check NULL +# define slh_dsa_sha2_128s_adjust NULL + +# define slh_dsa_sha2_128f_evp_type EVP_PKEY_SLH_DSA_SHA2_128F +# define slh_dsa_sha2_128f_d2i_private_key NULL +# define slh_dsa_sha2_128f_d2i_public_key NULL +# define slh_dsa_sha2_128f_d2i_key_params NULL +# define slh_dsa_sha2_128f_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_sha2_128f_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_sha2_128f_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_sha2_128f_check NULL +# define slh_dsa_sha2_128f_adjust NULL + +# define slh_dsa_sha2_192s_evp_type EVP_PKEY_SLH_DSA_SHA2_192S +# define slh_dsa_sha2_192s_d2i_private_key NULL +# define slh_dsa_sha2_192s_d2i_public_key NULL +# define slh_dsa_sha2_192s_d2i_key_params NULL +# define slh_dsa_sha2_192s_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_sha2_192s_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_sha2_192s_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_sha2_192s_check NULL +# define slh_dsa_sha2_192s_adjust NULL + +# define slh_dsa_sha2_192f_evp_type EVP_PKEY_SLH_DSA_SHA2_192F +# define slh_dsa_sha2_192f_d2i_private_key NULL +# define slh_dsa_sha2_192f_d2i_public_key NULL +# define slh_dsa_sha2_192f_d2i_key_params NULL +# define slh_dsa_sha2_192f_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_sha2_192f_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_sha2_192f_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_sha2_192f_check NULL +# define slh_dsa_sha2_192f_adjust NULL + +# define slh_dsa_sha2_256s_evp_type EVP_PKEY_SLH_DSA_SHA2_256S +# define slh_dsa_sha2_256s_d2i_private_key NULL +# define slh_dsa_sha2_256s_d2i_public_key NULL +# define slh_dsa_sha2_256s_d2i_key_params NULL +# define slh_dsa_sha2_256s_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_sha2_256s_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_sha2_256s_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_sha2_256s_check NULL +# define slh_dsa_sha2_256s_adjust NULL + +# define slh_dsa_sha2_256f_evp_type EVP_PKEY_SLH_DSA_SHA2_256F +# define slh_dsa_sha2_256f_d2i_private_key NULL +# define slh_dsa_sha2_256f_d2i_public_key NULL +# define slh_dsa_sha2_256f_d2i_key_params NULL +# define slh_dsa_sha2_256f_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_sha2_256f_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_sha2_256f_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_sha2_256f_check NULL +# define slh_dsa_sha2_256f_adjust NULL + +# define slh_dsa_shake_128s_evp_type EVP_PKEY_SLH_DSA_SHAKE_128S +# define slh_dsa_shake_128s_d2i_private_key NULL +# define slh_dsa_shake_128s_d2i_public_key NULL +# define slh_dsa_shake_128s_d2i_key_params NULL +# define slh_dsa_shake_128s_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_shake_128s_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_shake_128s_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_shake_128s_check NULL +# define slh_dsa_shake_128s_adjust NULL + +# define slh_dsa_shake_128f_evp_type EVP_PKEY_SLH_DSA_SHAKE_128F +# define slh_dsa_shake_128f_d2i_private_key NULL +# define slh_dsa_shake_128f_d2i_public_key NULL +# define slh_dsa_shake_128f_d2i_key_params NULL +# define slh_dsa_shake_128f_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_shake_128f_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_shake_128f_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_shake_128f_check NULL +# define slh_dsa_shake_128f_adjust NULL + +# define slh_dsa_shake_192s_evp_type EVP_PKEY_SLH_DSA_SHAKE_192S +# define slh_dsa_shake_192s_d2i_private_key NULL +# define slh_dsa_shake_192s_d2i_public_key NULL +# define slh_dsa_shake_192s_d2i_key_params NULL +# define slh_dsa_shake_192s_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_shake_192s_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_shake_192s_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_shake_192s_check NULL +# define slh_dsa_shake_192s_adjust NULL + +# define slh_dsa_shake_192f_evp_type EVP_PKEY_SLH_DSA_SHAKE_192F +# define slh_dsa_shake_192f_d2i_private_key NULL +# define slh_dsa_shake_192f_d2i_public_key NULL +# define slh_dsa_shake_192f_d2i_key_params NULL +# define slh_dsa_shake_192f_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_shake_192f_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_shake_192f_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_shake_192f_check NULL +# define slh_dsa_shake_192f_adjust NULL + +# define slh_dsa_shake_256s_evp_type EVP_PKEY_SLH_DSA_SHAKE_256S +# define slh_dsa_shake_256s_d2i_private_key NULL +# define slh_dsa_shake_256s_d2i_public_key NULL +# define slh_dsa_shake_256s_d2i_key_params NULL +# define slh_dsa_shake_256s_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_shake_256s_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_shake_256s_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_shake_256s_check NULL +# define slh_dsa_shake_256s_adjust NULL + +# define slh_dsa_shake_256f_evp_type EVP_PKEY_SLH_DSA_SHAKE_256F +# define slh_dsa_shake_256f_d2i_private_key NULL +# define slh_dsa_shake_256f_d2i_public_key NULL +# define slh_dsa_shake_256f_d2i_key_params NULL +# define slh_dsa_shake_256f_d2i_PKCS8 slh_dsa_d2i_PKCS8 +# define slh_dsa_shake_256f_d2i_PUBKEY slh_dsa_d2i_PUBKEY +# define slh_dsa_shake_256f_free (free_key_fn *)ossl_slh_dsa_key_free +# define slh_dsa_shake_256f_check NULL +# define slh_dsa_shake_256f_adjust NULL +#endif /* OPENSSL_NO_SLH_DSA */ + +/* ---------------------------------------------------------------------- */ + #define rsa_evp_type EVP_PKEY_RSA #define rsa_d2i_private_key (d2i_of_void *)d2i_RSAPrivateKey #define rsa_d2i_public_key (d2i_of_void *)d2i_RSAPublicKey #define rsa_d2i_key_params NULL +#define rsa_free (free_key_fn *)RSA_free -static void *rsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len, +static void *rsa_d2i_PKCS8(const unsigned char **der, long der_len, struct der2key_ctx_st *ctx) { return der2key_decode_p8(der, der_len, ctx, (key_from_pkcs8_t *)ossl_rsa_key_from_pkcs8); } -#define rsa_d2i_PUBKEY (d2i_of_void *)d2i_RSA_PUBKEY -#define rsa_free (free_key_fn *)RSA_free +static void * +rsa_d2i_PUBKEY(const unsigned char **der, long der_len, + ossl_unused struct der2key_ctx_st *ctx) +{ + return d2i_RSA_PUBKEY(NULL, der, der_len); +} static int rsa_check(void *key, struct der2key_ctx_st *ctx) { + int valid; + switch (RSA_test_flags(key, RSA_FLAG_TYPE_MASK)) { case RSA_FLAG_TYPE_RSA: - return ctx->desc->evp_type == EVP_PKEY_RSA; + valid = (ctx->desc->evp_type == EVP_PKEY_RSA); + break; case RSA_FLAG_TYPE_RSASSAPSS: - return ctx->desc->evp_type == EVP_PKEY_RSA_PSS; + valid = (ctx->desc->evp_type == EVP_PKEY_RSA_PSS); + break; + default: + /* Currently unsupported RSA key type */ + valid = 0; } - /* Currently unsupported RSA key type */ - return 0; + valid = (valid && ossl_rsa_check_factors(key)); + + return valid; } static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) @@ -556,13 +937,72 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) #define rsapss_d2i_public_key (d2i_of_void *)d2i_RSAPublicKey #define rsapss_d2i_key_params NULL #define rsapss_d2i_PKCS8 rsa_d2i_PKCS8 -#define rsapss_d2i_PUBKEY (d2i_of_void *)d2i_RSA_PUBKEY +#define rsapss_d2i_PUBKEY rsa_d2i_PUBKEY #define rsapss_free (free_key_fn *)RSA_free #define rsapss_check rsa_check #define rsapss_adjust rsa_adjust /* ---------------------------------------------------------------------- */ +#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; + + key = ossl_ml_dsa_d2i_PKCS8(*der, der_len, ctx->desc->evp_type, + ctx->provctx, ctx->propq); + if (key != NULL) + *der += der_len; + return key; +} + +static ossl_inline void * ml_dsa_d2i_PUBKEY(const uint8_t **der, long der_len, + struct der2key_ctx_st *ctx) +{ + ML_DSA_KEY *key; + + key = ossl_ml_dsa_d2i_PUBKEY(*der, der_len, ctx->desc->evp_type, + ctx->provctx, ctx->propq); + if (key != NULL) + *der += der_len; + return key; +} + +# 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. @@ -771,7 +1211,11 @@ static void rsa_adjust(void *key, struct der2key_ctx_st *ctx) (void (*)(void))der2key_decode }, \ { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ (void (*)(void))der2key_export_object }, \ - { 0, NULL } \ + { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))der2key_settable_ctx_params }, \ + { OSSL_FUNC_DECODER_SET_CTX_PARAMS, \ + (void (*)(void))der2key_set_ctx_params }, \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_DH @@ -795,6 +1239,7 @@ MAKE_DECODER("EC", ec, ec, PrivateKeyInfo); MAKE_DECODER("EC", ec, ec, SubjectPublicKeyInfo); MAKE_DECODER("EC", ec, ec, type_specific_no_pub); MAKE_DECODER("EC", ec, ec, EC); +# ifndef OPENSSL_NO_ECX MAKE_DECODER("X25519", x25519, ecx, PrivateKeyInfo); MAKE_DECODER("X25519", x25519, ecx, SubjectPublicKeyInfo); MAKE_DECODER("X448", x448, ecx, PrivateKeyInfo); @@ -803,14 +1248,60 @@ MAKE_DECODER("ED25519", ed25519, ecx, PrivateKeyInfo); MAKE_DECODER("ED25519", ed25519, ecx, SubjectPublicKeyInfo); MAKE_DECODER("ED448", ed448, ecx, PrivateKeyInfo); MAKE_DECODER("ED448", ed448, ecx, SubjectPublicKeyInfo); +# endif # ifndef OPENSSL_NO_SM2 MAKE_DECODER("SM2", sm2, ec, PrivateKeyInfo); MAKE_DECODER("SM2", sm2, ec, SubjectPublicKeyInfo); +MAKE_DECODER("SM2", sm2, sm2, type_specific_no_pub); # endif #endif +#ifndef OPENSSL_NO_ML_KEM +MAKE_DECODER("ML-KEM-512", ml_kem_512, ml_kem_512, PrivateKeyInfo); +MAKE_DECODER("ML-KEM-512", ml_kem_512, ml_kem_512, SubjectPublicKeyInfo); +MAKE_DECODER("ML-KEM-768", ml_kem_768, ml_kem_768, PrivateKeyInfo); +MAKE_DECODER("ML-KEM-768", ml_kem_768, ml_kem_768, SubjectPublicKeyInfo); +MAKE_DECODER("ML-KEM-1024", ml_kem_1024, ml_kem_1024, PrivateKeyInfo); +MAKE_DECODER("ML-KEM-1024", ml_kem_1024, ml_kem_1024, SubjectPublicKeyInfo); +#endif +#ifndef OPENSSL_NO_SLH_DSA +MAKE_DECODER("SLH-DSA-SHA2-128s", slh_dsa_sha2_128s, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHA2-128f", slh_dsa_sha2_128f, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHA2-192s", slh_dsa_sha2_192s, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHA2-192f", slh_dsa_sha2_192f, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHA2-256s", slh_dsa_sha2_256s, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHA2-256f", slh_dsa_sha2_256f, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-128s", slh_dsa_shake_128s, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-128f", slh_dsa_shake_128f, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-192s", slh_dsa_shake_192s, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-192f", slh_dsa_shake_192f, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-256s", slh_dsa_shake_256s, slh_dsa, PrivateKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-256f", slh_dsa_shake_256f, slh_dsa, PrivateKeyInfo); + +MAKE_DECODER("SLH-DSA-SHA2-128s", slh_dsa_sha2_128s, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHA2-128f", slh_dsa_sha2_128f, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHA2-192s", slh_dsa_sha2_192s, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHA2-192f", slh_dsa_sha2_192f, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHA2-256s", slh_dsa_sha2_256s, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHA2-256f", slh_dsa_sha2_256f, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-128s", slh_dsa_shake_128s, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-128f", slh_dsa_shake_128f, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-192s", slh_dsa_shake_192s, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-192f", slh_dsa_shake_192f, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-256s", slh_dsa_shake_256s, slh_dsa, SubjectPublicKeyInfo); +MAKE_DECODER("SLH-DSA-SHAKE-256f", slh_dsa_shake_256f, slh_dsa, SubjectPublicKeyInfo); +#endif /* OPENSSL_NO_SLH_DSA */ MAKE_DECODER("RSA", rsa, rsa, PrivateKeyInfo); MAKE_DECODER("RSA", rsa, rsa, SubjectPublicKeyInfo); MAKE_DECODER("RSA", rsa, rsa, type_specific_keypair); 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 diff --git a/providers/implementations/encode_decode/decode_epki2pki.c b/providers/implementations/encode_decode/decode_epki2pki.c index 9cea80b616d6..aecf2eb4f2b4 100644 --- a/providers/implementations/encode_decode/decode_epki2pki.c +++ b/providers/implementations/encode_decode/decode_epki2pki.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 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 @@ -20,18 +20,22 @@ #include "internal/asn1.h" #include "internal/sizes.h" #include "prov/bio.h" +#include "prov/decoders.h" #include "prov/implementations.h" #include "endecoder_local.h" static OSSL_FUNC_decoder_newctx_fn epki2pki_newctx; static OSSL_FUNC_decoder_freectx_fn epki2pki_freectx; static OSSL_FUNC_decoder_decode_fn epki2pki_decode; +static OSSL_FUNC_decoder_settable_ctx_params_fn epki2pki_settable_ctx_params; +static OSSL_FUNC_decoder_set_ctx_params_fn epki2pki_set_ctx_params; /* * Context used for EncryptedPrivateKeyInfo to PrivateKeyInfo decoding. */ struct epki2pki_ctx_st { PROV_CTX *provctx; + char propq[OSSL_MAX_PROPQUERY_SIZE]; }; static void *epki2pki_newctx(void *provctx) @@ -50,6 +54,28 @@ static void epki2pki_freectx(void *vctx) OPENSSL_free(ctx); } +static const OSSL_PARAM *epki2pki_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END + }; + return settables; +} + +static int epki2pki_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct epki2pki_ctx_st *ctx = vctx; + const OSSL_PARAM *p; + char *str = ctx->propq; + + p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); + if (p != NULL && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) + return 0; + + return 1; +} + /* * The selection parameter in epki2pki_decode() is not used by this function * because it's not relevant just to decode EncryptedPrivateKeyInfo to @@ -62,11 +88,7 @@ static int epki2pki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, struct epki2pki_ctx_st *ctx = vctx; BUF_MEM *mem = NULL; unsigned char *der = NULL; - const unsigned char *pder = NULL; long der_len = 0; - X509_SIG *p8 = NULL; - PKCS8_PRIV_KEY_INFO *p8inf = NULL; - const X509_ALGOR *alg = NULL; BIO *in = ossl_bio_new_from_core_bio(ctx->provctx, cin); int ok = 0; @@ -80,11 +102,29 @@ static int epki2pki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, if (!ok) return 1; - pder = der = (unsigned char *)mem->data; + der = (unsigned char *)mem->data; der_len = (long)mem->length; OPENSSL_free(mem); - ok = 1; /* Assume good */ + ok = ossl_epki2pki_der_decode(der, der_len, selection, data_cb, data_cbarg, + pw_cb, pw_cbarg, PROV_LIBCTX_OF(ctx->provctx), + ctx->propq); + OPENSSL_free(der); + return ok; +} + +int ossl_epki2pki_der_decode(unsigned char *der, long der_len, int selection, + OSSL_CALLBACK *data_cb, void *data_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *pder = der; + unsigned char *new_der = NULL; + X509_SIG *p8 = NULL; + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + const X509_ALGOR *alg = NULL; + int ok = 1; /* Assume good */ + ERR_set_mark(); if ((p8 = d2i_X509_SIG(NULL, &pder, der_len)) != NULL) { char pbuf[1024]; @@ -97,17 +137,15 @@ static int epki2pki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, ok = 0; } else { const ASN1_OCTET_STRING *oct; - unsigned char *new_der = NULL; int new_der_len = 0; X509_SIG_get0(p8, &alg, &oct); if (!PKCS12_pbe_crypt_ex(alg, pbuf, plen, oct->data, oct->length, &new_der, &new_der_len, 0, - PROV_LIBCTX_OF(ctx->provctx), NULL)) { + libctx, propq)) { ok = 0; } else { - OPENSSL_free(der); der = new_der; der_len = new_der_len; } @@ -129,13 +167,15 @@ static int epki2pki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, * pass all the applicable data to the callback. */ char keytype[OSSL_MAX_NAME_SIZE]; - OSSL_PARAM params[5], *p = params; + OSSL_PARAM params[6], *p = params; int objtype = OSSL_OBJECT_PKEY; OBJ_obj2txt(keytype, sizeof(keytype), alg->algorithm, 0); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, keytype, 0); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_INPUT_TYPE, + "DER", 0); *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, "PrivateKeyInfo", 0); *p++ = OSSL_PARAM_construct_octet_string(OSSL_OBJECT_PARAM_DATA, @@ -146,7 +186,7 @@ static int epki2pki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, ok = data_cb(params, data_cbarg); } PKCS8_PRIV_KEY_INFO_free(p8inf); - OPENSSL_free(der); + OPENSSL_free(new_der); return ok; } @@ -154,5 +194,9 @@ const OSSL_DISPATCH ossl_EncryptedPrivateKeyInfo_der_to_der_decoder_functions[] { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))epki2pki_newctx }, { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))epki2pki_freectx }, { OSSL_FUNC_DECODER_DECODE, (void (*)(void))epki2pki_decode }, - { 0, NULL } + { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, + (void (*)(void))epki2pki_settable_ctx_params }, + { OSSL_FUNC_DECODER_SET_CTX_PARAMS, + (void (*)(void))epki2pki_set_ctx_params }, + OSSL_DISPATCH_END }; diff --git a/providers/implementations/encode_decode/decode_msblob2key.c b/providers/implementations/encode_decode/decode_msblob2key.c index b9d0cabadae2..df327210f114 100644 --- a/providers/implementations/encode_decode/decode_msblob2key.c +++ b/providers/implementations/encode_decode/decode_msblob2key.c @@ -132,10 +132,8 @@ static int msblob2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, goto next; } buf = OPENSSL_malloc(length); - if (buf == NULL) { - ERR_raise(ERR_LIB_PEM, ERR_R_MALLOC_FAILURE); + if (buf == NULL) goto end; - } p = buf; if (BIO_read(in, buf, length) != (int)length) { ERR_raise(ERR_LIB_PEM, PEM_R_KEYBLOB_TOO_SHORT); @@ -282,7 +280,7 @@ static void rsa_adjust(void *key, struct msblob2key_ctx_st *ctx) (void (*)(void))msblob2key_decode }, \ { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ (void (*)(void))msblob2key_export_object }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_DSA diff --git a/providers/implementations/encode_decode/decode_pem2der.c b/providers/implementations/encode_decode/decode_pem2der.c index bc937ffb9d27..abea679fe19a 100644 --- a/providers/implementations/encode_decode/decode_pem2der.c +++ b/providers/implementations/encode_decode/decode_pem2der.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 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 @@ -24,7 +24,9 @@ #include <openssl/pem.h> #include <openssl/proverr.h> #include "internal/nelem.h" +#include "internal/sizes.h" #include "prov/bio.h" +#include "prov/decoders.h" #include "prov/implementations.h" #include "endecoder_local.h" @@ -52,6 +54,8 @@ static OSSL_FUNC_decoder_decode_fn pem2der_decode; */ struct pem2der_ctx_st { PROV_CTX *provctx; + char data_structure[OSSL_MAX_CODEC_STRUCT_SIZE]; + char propq[OSSL_MAX_PROPQUERY_SIZE]; }; static void *pem2der_newctx(void *provctx) @@ -70,6 +74,37 @@ static void pem2der_freectx(void *vctx) OPENSSL_free(ctx); } +static const OSSL_PARAM *pem2der_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, NULL, 0), + OSSL_PARAM_END + }; + return settables; +} + +static int pem2der_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct pem2der_ctx_st *ctx = vctx; + const OSSL_PARAM *p; + char *str; + + p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); + str = ctx->propq; + if (p != NULL + && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) + return 0; + + p = OSSL_PARAM_locate_const(params, OSSL_OBJECT_PARAM_DATA_STRUCTURE); + str = ctx->data_structure; + if (p != NULL + && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->data_structure))) + return 0; + + return 1; +} + /* pem_password_cb compatible function */ struct pem2der_pass_data_st { OSSL_PASSPHRASE_CALLBACK *cb; @@ -88,10 +123,6 @@ static int pem2der_pass_helper(char *buf, int num, int w, void *data) return (int)plen; } -/* - * The selection parameter in pem2der_decode() is not used by this function - * because it's not relevant just to decode PEM to DER. - */ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, OSSL_CALLBACK *data_cb, void *data_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) @@ -109,8 +140,9 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, /* PKCS#8 and SubjectPublicKeyInfo */ { PEM_STRING_PKCS8, OSSL_OBJECT_PKEY, NULL, "EncryptedPrivateKeyInfo" }, { PEM_STRING_PKCS8INF, OSSL_OBJECT_PKEY, NULL, "PrivateKeyInfo" }, +#define PKCS8_LAST_IDX 1 { PEM_STRING_PUBLIC, OSSL_OBJECT_PKEY, NULL, "SubjectPublicKeyInfo" }, - +#define SPKI_LAST_IDX 2 /* Our set of type specific PEM types */ { PEM_STRING_DHPARAMS, OSSL_OBJECT_PKEY, "DH", "type-specific" }, { PEM_STRING_DHXPARAMS, OSSL_OBJECT_PKEY, "X9.42 DH", "type-specific" }, @@ -119,6 +151,7 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, { PEM_STRING_DSAPARAMS, OSSL_OBJECT_PKEY, "DSA", "type-specific" }, { PEM_STRING_ECPRIVATEKEY, OSSL_OBJECT_PKEY, "EC", "type-specific" }, { PEM_STRING_ECPARAMETERS, OSSL_OBJECT_PKEY, "EC", "type-specific" }, + { PEM_STRING_SM2PARAMETERS, OSSL_OBJECT_PKEY, "SM2", "type-specific" }, { PEM_STRING_RSA, OSSL_OBJECT_PKEY, "RSA", "type-specific" }, { PEM_STRING_RSA_PUBLIC, OSSL_OBJECT_PKEY, "RSA", "type-specific" }, @@ -182,6 +215,31 @@ static int pem2der_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, char *data_type = (char *)pem_name_map[i].data_type; char *data_structure = (char *)pem_name_map[i].data_structure; + /* + * Since this may perform decryption, we need to check the selection to + * avoid password prompts for objects of no interest. + */ + if (i <= PKCS8_LAST_IDX + && ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) + || OPENSSL_strcasecmp(ctx->data_structure, "EncryptedPrivateKeyInfo") == 0 + || OPENSSL_strcasecmp(ctx->data_structure, "PrivateKeyInfo") == 0)) { + ok = ossl_epki2pki_der_decode(der, der_len, selection, data_cb, + data_cbarg, pw_cb, pw_cbarg, + PROV_LIBCTX_OF(ctx->provctx), + ctx->propq); + goto end; + } + + if (i <= SPKI_LAST_IDX + && ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) + || OPENSSL_strcasecmp(ctx->data_structure, "SubjectPublicKeyInfo") == 0)) { + ok = ossl_spki2typespki_der_decode(der, der_len, selection, data_cb, + data_cbarg, pw_cb, pw_cbarg, + PROV_LIBCTX_OF(ctx->provctx), + ctx->propq); + goto end; + } + objtype = pem_name_map[i].object_type; if (data_type != NULL) *p++ = @@ -215,5 +273,9 @@ const OSSL_DISPATCH ossl_pem_to_der_decoder_functions[] = { { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))pem2der_newctx }, { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))pem2der_freectx }, { OSSL_FUNC_DECODER_DECODE, (void (*)(void))pem2der_decode }, - { 0, NULL } + { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, + (void (*)(void))pem2der_settable_ctx_params }, + { OSSL_FUNC_DECODER_SET_CTX_PARAMS, + (void (*)(void))pem2der_set_ctx_params }, + OSSL_DISPATCH_END }; diff --git a/providers/implementations/encode_decode/decode_pvk2key.c b/providers/implementations/encode_decode/decode_pvk2key.c index 2d7cb15e53e0..ea4585d93c5c 100644 --- a/providers/implementations/encode_decode/decode_pvk2key.c +++ b/providers/implementations/encode_decode/decode_pvk2key.c @@ -24,6 +24,7 @@ #include <openssl/pem.h> /* For public PVK functions */ #include <openssl/x509.h> #include "internal/passphrase.h" +#include "internal/sizes.h" #include "crypto/pem.h" /* For internal PVK and "blob" headers */ #include "crypto/rsa.h" #include "prov/bio.h" @@ -49,12 +50,15 @@ struct keytype_desc_st { static OSSL_FUNC_decoder_freectx_fn pvk2key_freectx; static OSSL_FUNC_decoder_decode_fn pvk2key_decode; static OSSL_FUNC_decoder_export_object_fn pvk2key_export_object; +static OSSL_FUNC_decoder_settable_ctx_params_fn pvk2key_settable_ctx_params; +static OSSL_FUNC_decoder_set_ctx_params_fn pvk2key_set_ctx_params; /* * Context used for DER to key decoding. */ struct pvk2key_ctx_st { PROV_CTX *provctx; + char propq[OSSL_MAX_PROPQUERY_SIZE]; const struct keytype_desc_st *desc; /* The selection that is passed to der2key_decode() */ int selection; @@ -79,6 +83,28 @@ static void pvk2key_freectx(void *vctx) OPENSSL_free(ctx); } +static const OSSL_PARAM *pvk2key_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END, + }; + return settables; +} + +static int pvk2key_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct pvk2key_ctx_st *ctx = vctx; + const OSSL_PARAM *p; + char *str = ctx->propq; + + p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); + if (p != NULL && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) + return 0; + + return 1; +} + static int pvk2key_does_selection(void *provctx, int selection) { if (selection == 0) @@ -115,7 +141,8 @@ static int pvk2key_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, goto end; key = ctx->desc->read_private_key(in, ossl_pw_pvk_password, &pwdata, - PROV_LIBCTX_OF(ctx->provctx), NULL); + PROV_LIBCTX_OF(ctx->provctx), + ctx->propq); /* * Because the PVK API doesn't have a separate decrypt call, we need @@ -247,7 +274,11 @@ static void rsa_adjust(void *key, struct pvk2key_ctx_st *ctx) (void (*)(void))pvk2key_decode }, \ { OSSL_FUNC_DECODER_EXPORT_OBJECT, \ (void (*)(void))pvk2key_export_object }, \ - { 0, NULL } \ + { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, \ + (void (*)(void))pvk2key_settable_ctx_params }, \ + { OSSL_FUNC_DECODER_SET_CTX_PARAMS, \ + (void (*)(void))pvk2key_set_ctx_params }, \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_DSA diff --git a/providers/implementations/encode_decode/decode_spki2typespki.c b/providers/implementations/encode_decode/decode_spki2typespki.c index a5dbbb31adf8..8cf6d7d41ce3 100644 --- a/providers/implementations/encode_decode/decode_spki2typespki.c +++ b/providers/implementations/encode_decode/decode_spki2typespki.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 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 @@ -17,12 +17,15 @@ #include "crypto/x509.h" #include "crypto/ec.h" #include "prov/bio.h" +#include "prov/decoders.h" #include "prov/implementations.h" #include "endecoder_local.h" static OSSL_FUNC_decoder_newctx_fn spki2typespki_newctx; static OSSL_FUNC_decoder_freectx_fn spki2typespki_freectx; static OSSL_FUNC_decoder_decode_fn spki2typespki_decode; +static OSSL_FUNC_decoder_settable_ctx_params_fn spki2typespki_settable_ctx_params; +static OSSL_FUNC_decoder_set_ctx_params_fn spki2typespki_set_ctx_params; /* * Context used for SubjectPublicKeyInfo to Type specific SubjectPublicKeyInfo @@ -30,6 +33,7 @@ static OSSL_FUNC_decoder_decode_fn spki2typespki_decode; */ struct spki2typespki_ctx_st { PROV_CTX *provctx; + char propq[OSSL_MAX_PROPQUERY_SIZE]; }; static void *spki2typespki_newctx(void *provctx) @@ -48,27 +52,62 @@ static void spki2typespki_freectx(void *vctx) OPENSSL_free(ctx); } +static const OSSL_PARAM *spki2typespki_settable_ctx_params(ossl_unused void *provctx) +{ + static const OSSL_PARAM settables[] = { + OSSL_PARAM_utf8_string(OSSL_DECODER_PARAM_PROPERTIES, NULL, 0), + OSSL_PARAM_END + }; + return settables; +} + +static int spki2typespki_set_ctx_params(void *vctx, const OSSL_PARAM params[]) +{ + struct spki2typespki_ctx_st *ctx = vctx; + const OSSL_PARAM *p; + char *str = ctx->propq; + + p = OSSL_PARAM_locate_const(params, OSSL_DECODER_PARAM_PROPERTIES); + if (p != NULL && !OSSL_PARAM_get_utf8_string(p, &str, sizeof(ctx->propq))) + return 0; + + return 1; +} + static int spki2typespki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, OSSL_CALLBACK *data_cb, void *data_cbarg, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg) { struct spki2typespki_ctx_st *ctx = vctx; - unsigned char *der, *derp; + unsigned char *der; long len; int ok = 0; - int objtype = OSSL_OBJECT_PKEY; + + if (!ossl_read_der(ctx->provctx, cin, &der, &len)) + return 1; + + ok = ossl_spki2typespki_der_decode(der, len, selection, data_cb, data_cbarg, + pw_cb, pw_cbarg, + PROV_LIBCTX_OF(ctx->provctx), ctx->propq); + OPENSSL_free(der); + return ok; +} + +int ossl_spki2typespki_der_decode(unsigned char *der, long len, int selection, + OSSL_CALLBACK *data_cb, void *data_cbarg, + OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg, + OSSL_LIB_CTX *libctx, const char *propq) +{ + const unsigned char *derp = der; X509_PUBKEY *xpub = NULL; X509_ALGOR *algor = NULL; const ASN1_OBJECT *oid = NULL; char dataname[OSSL_MAX_NAME_SIZE]; - OSSL_PARAM params[5], *p = params; - - if (!ossl_read_der(ctx->provctx, cin, &der, &len)) - return 1; - derp = der; - xpub = ossl_d2i_X509_PUBKEY_INTERNAL((const unsigned char **)&derp, len, - PROV_LIBCTX_OF(ctx->provctx)); + OSSL_PARAM params[6], *p = params; + int objtype = OSSL_OBJECT_PKEY; + int ok = 0; + xpub = ossl_d2i_X509_PUBKEY_INTERNAL(&derp, len, libctx, propq); if (xpub == NULL) { /* We return "empty handed". This is not an error. */ @@ -97,6 +136,9 @@ static int spki2typespki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_TYPE, dataname, 0); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_INPUT_TYPE, + "DER", 0); + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_OBJECT_PARAM_DATA_STRUCTURE, "SubjectPublicKeyInfo", @@ -112,7 +154,6 @@ static int spki2typespki_decode(void *vctx, OSSL_CORE_BIO *cin, int selection, end: ossl_X509_PUBKEY_INTERNAL_free(xpub); - OPENSSL_free(der); return ok; } @@ -120,5 +161,9 @@ const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_der_decoder_functions[] = { { OSSL_FUNC_DECODER_NEWCTX, (void (*)(void))spki2typespki_newctx }, { OSSL_FUNC_DECODER_FREECTX, (void (*)(void))spki2typespki_freectx }, { OSSL_FUNC_DECODER_DECODE, (void (*)(void))spki2typespki_decode }, - { 0, NULL } + { OSSL_FUNC_DECODER_SETTABLE_CTX_PARAMS, + (void (*)(void))spki2typespki_settable_ctx_params }, + { OSSL_FUNC_DECODER_SET_CTX_PARAMS, + (void (*)(void))spki2typespki_set_ctx_params }, + OSSL_DISPATCH_END }; diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c index 1430c330cf0b..67a11590034a 100644 --- a/providers/implementations/encode_decode/encode_key2any.c +++ b/providers/implementations/encode_decode/encode_key2any.c @@ -1,5 +1,5 @@ /* - * 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 @@ -12,6 +12,7 @@ */ #include "internal/deprecated.h" +#include <openssl/byteorder.h> #include <openssl/core.h> #include <openssl/core_dispatch.h> #include <openssl/core_names.h> @@ -29,18 +30,23 @@ #include "internal/passphrase.h" #include "internal/cryptlib.h" #include "crypto/ecx.h" +#include "crypto/ml_kem.h" #include "crypto/rsa.h" +#include "crypto/ml_dsa.h" +#include "crypto/slh_dsa.h" #include "prov/implementations.h" #include "prov/bio.h" #include "prov/provider_ctx.h" #include "prov/der_rsa.h" #include "endecoder_local.h" +#include "ml_dsa_codecs.h" +#include "ml_kem_codecs.h" #if defined(OPENSSL_NO_DH) && defined(OPENSSL_NO_DSA) && defined(OPENSSL_NO_EC) # define OPENSSL_NO_KEYPARAMS #endif -struct key2any_ctx_st { +typedef struct key2any_ctx_st { PROV_CTX *provctx; /* Set to 0 if parameters should not be saved (dsa only) */ @@ -52,22 +58,22 @@ struct key2any_ctx_st { EVP_CIPHER *cipher; struct ossl_passphrase_data_st pwdata; -}; +} KEY2ANY_CTX; typedef int check_key_type_fn(const void *key, int nid); typedef int key_to_paramstring_fn(const void *key, int nid, int save, void **str, int *strtype); typedef int key_to_der_fn(BIO *out, const void *key, int key_nid, const char *pemname, - key_to_paramstring_fn *p2s, i2d_of_void *k2d, - struct key2any_ctx_st *ctx); + key_to_paramstring_fn *p2s, + OSSL_i2d_of_void_ctx *k2d, KEY2ANY_CTX *ctx); typedef int write_bio_of_void_fn(BIO *bp, const void *x); /* Free the blob allocated during key_to_paramstring_fn */ static void free_asn1_data(int type, void *data) { - switch(type) { + switch (type) { case V_ASN1_OBJECT: ASN1_OBJECT_free(data); break; @@ -79,7 +85,8 @@ static void free_asn1_data(int type, void *data) static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, void *params, int params_type, - i2d_of_void *k2d) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { /* der, derlen store the key DER output and its length */ unsigned char *der = NULL; @@ -88,10 +95,10 @@ static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, PKCS8_PRIV_KEY_INFO *p8info = NULL; if ((p8info = PKCS8_PRIV_KEY_INFO_new()) == NULL - || (derlen = k2d(key, &der)) <= 0 + || (derlen = k2d(key, &der, (void *)ctx)) <= 0 || !PKCS8_pkey_set0(p8info, OBJ_nid2obj(key_nid), 0, params_type, params, der, derlen)) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); PKCS8_PRIV_KEY_INFO_free(p8info); OPENSSL_free(der); p8info = NULL; @@ -101,7 +108,7 @@ static PKCS8_PRIV_KEY_INFO *key_to_p8info(const void *key, int key_nid, } static X509_SIG *p8info_to_encp8(PKCS8_PRIV_KEY_INFO *p8info, - struct key2any_ctx_st *ctx) + KEY2ANY_CTX *ctx) { X509_SIG *p8 = NULL; char kstr[PEM_BUFSIZE]; @@ -124,10 +131,11 @@ static X509_SIG *p8info_to_encp8(PKCS8_PRIV_KEY_INFO *p8info, static X509_SIG *key_to_encp8(const void *key, int key_nid, void *params, int params_type, - i2d_of_void *k2d, struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { PKCS8_PRIV_KEY_INFO *p8info = - key_to_p8info(key, key_nid, params, params_type, k2d); + key_to_p8info(key, key_nid, params, params_type, k2d, ctx); X509_SIG *p8 = NULL; if (p8info == NULL) { @@ -141,7 +149,8 @@ static X509_SIG *key_to_encp8(const void *key, int key_nid, static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid, void *params, int params_type, - i2d_of_void k2d) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { /* der, derlen store the key DER output and its length */ unsigned char *der = NULL; @@ -151,10 +160,10 @@ static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid, if ((xpk = X509_PUBKEY_new()) == NULL - || (derlen = k2d(key, &der)) <= 0 + || (derlen = k2d(key, &der, (void *)ctx)) <= 0 || !X509_PUBKEY_set0_param(xpk, OBJ_nid2obj(key_nid), params_type, params, der, derlen)) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_X509_LIB); X509_PUBKEY_free(xpk); OPENSSL_free(der); xpk = NULL; @@ -168,7 +177,7 @@ static X509_PUBKEY *key_to_pubkey(const void *key, int key_nid, * EncryptedPrivateKeyInfo structure (defined by PKCS#8). They require * that there's an intent to encrypt, anything else is an error. * - * key_to_pki_* primarly produce encoded output with the private key data + * key_to_pki_* primarily produce encoded output with the private key data * in a PrivateKeyInfo structure (also defined by PKCS#8). However, if * there is an intent to encrypt the data, the corresponding key_to_epki_* * function is used instead. @@ -186,8 +195,8 @@ static int key_to_epki_der_priv_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -214,8 +223,8 @@ static int key_to_epki_pem_priv_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -242,8 +251,8 @@ static int key_to_pki_der_priv_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -258,7 +267,7 @@ static int key_to_pki_der_priv_bio(BIO *out, const void *key, &str, &strtype)) return 0; - p8info = key_to_p8info(key, key_nid, str, strtype, k2d); + p8info = key_to_p8info(key, key_nid, str, strtype, k2d, ctx); if (p8info != NULL) ret = i2d_PKCS8_PRIV_KEY_INFO_bio(out, p8info); @@ -274,8 +283,8 @@ static int key_to_pki_pem_priv_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -290,7 +299,7 @@ static int key_to_pki_pem_priv_bio(BIO *out, const void *key, &str, &strtype)) return 0; - p8info = key_to_p8info(key, key_nid, str, strtype, k2d); + p8info = key_to_p8info(key, key_nid, str, strtype, k2d, ctx); if (p8info != NULL) ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(out, p8info); @@ -306,8 +315,8 @@ static int key_to_spki_der_pub_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -318,7 +327,7 @@ static int key_to_spki_der_pub_bio(BIO *out, const void *key, &str, &strtype)) return 0; - xpk = key_to_pubkey(key, key_nid, str, strtype, k2d); + xpk = key_to_pubkey(key, key_nid, str, strtype, k2d, ctx); if (xpk != NULL) ret = i2d_X509_PUBKEY_bio(out, xpk); @@ -332,8 +341,8 @@ static int key_to_spki_pem_pub_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { int ret = 0; void *str = NULL; @@ -344,7 +353,7 @@ static int key_to_spki_pem_pub_bio(BIO *out, const void *key, &str, &strtype)) return 0; - xpk = key_to_pubkey(key, key_nid, str, strtype, k2d); + xpk = key_to_pubkey(key, key_nid, str, strtype, k2d, ctx); if (xpk != NULL) ret = PEM_write_bio_X509_PUBKEY(out, xpk); @@ -372,15 +381,15 @@ static int key_to_type_specific_der_bio(BIO *out, const void *key, int key_nid, ossl_unused const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { unsigned char *der = NULL; int derlen; int ret; - if ((derlen = k2d(key, &der)) <= 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if ((derlen = k2d(key, &der, (void *)ctx)) <= 0) { + ERR_raise(ERR_LIB_PROV, ERR_R_PROV_LIB); return 0; } @@ -395,20 +404,19 @@ static int key_to_type_specific_der_bio(BIO *out, const void *key, static int key_to_type_specific_pem_bio_cb(BIO *out, const void *key, int key_nid, const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx, + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx, pem_password_cb *cb, void *cbarg) { - return - PEM_ASN1_write_bio(k2d, pemname, out, key, ctx->cipher, - NULL, 0, cb, cbarg) > 0; + return PEM_ASN1_write_bio_ctx(k2d, (void *)ctx, pemname, out, key, + ctx->cipher, NULL, 0, cb, cbarg) > 0; } static int key_to_type_specific_pem_priv_bio(BIO *out, const void *key, int key_nid, const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname, p2s, k2d, ctx, @@ -418,8 +426,8 @@ static int key_to_type_specific_pem_priv_bio(BIO *out, const void *key, static int key_to_type_specific_pem_pub_bio(BIO *out, const void *key, int key_nid, const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname, p2s, k2d, ctx, NULL, NULL); @@ -429,8 +437,8 @@ static int key_to_type_specific_pem_pub_bio(BIO *out, const void *key, static int key_to_type_specific_pem_param_bio(BIO *out, const void *key, int key_nid, const char *pemname, key_to_paramstring_fn *p2s, - i2d_of_void *k2d, - struct key2any_ctx_st *ctx) + OSSL_i2d_of_void_ctx *k2d, + KEY2ANY_CTX *ctx) { return key_to_type_specific_pem_bio_cb(out, key, key_nid, pemname, p2s, k2d, ctx, NULL, NULL); @@ -439,6 +447,16 @@ static int key_to_type_specific_pem_param_bio(BIO *out, const void *key, /* ---------------------------------------------------------------------- */ +#define k2d_NOCTX(n, f) \ + static int \ + n##_k2d(const void *key, unsigned char **pder, \ + ossl_unused void *ctx) \ + { \ + return f(key, pder); \ + } + +/* ---------------------------------------------------------------------- */ + #ifndef OPENSSL_NO_DH static int prepare_dh_params(const void *dh, int nid, int save, void **pstr, int *pstrtype) @@ -446,7 +464,7 @@ static int prepare_dh_params(const void *dh, int nid, int save, ASN1_STRING *params = ASN1_STRING_new(); if (params == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); return 0; } @@ -456,7 +474,7 @@ static int prepare_dh_params(const void *dh, int nid, int save, params->length = i2d_DHparams(dh, ¶ms->data); if (params->length <= 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); ASN1_STRING_free(params); return 0; } @@ -467,7 +485,8 @@ static int prepare_dh_params(const void *dh, int nid, int save, return 1; } -static int dh_spki_pub_to_der(const void *dh, unsigned char **pder) +static int dh_spki_pub_to_der(const void *dh, unsigned char **pder, + ossl_unused void *ctx) { const BIGNUM *bn = NULL; ASN1_INTEGER *pub_key = NULL; @@ -488,7 +507,8 @@ static int dh_spki_pub_to_der(const void *dh, unsigned char **pder) return ret; } -static int dh_pki_priv_to_der(const void *dh, unsigned char **pder) +static int dh_pki_priv_to_der(const void *dh, unsigned char **pder, + ossl_unused void *ctx) { const BIGNUM *bn = NULL; ASN1_INTEGER *priv_key = NULL; @@ -511,7 +531,9 @@ static int dh_pki_priv_to_der(const void *dh, unsigned char **pder) # define dh_epki_priv_to_der dh_pki_priv_to_der -static int dh_type_specific_params_to_der(const void *dh, unsigned char **pder) +static int +dh_type_specific_params_to_der(const void *dh, unsigned char **pder, + ossl_unused void *ctx) { if (DH_test_flags(dh, DH_FLAG_TYPE_DHX)) return i2d_DHxparams(dh, pder); @@ -535,8 +557,6 @@ static int dh_check_key_type(const void *dh, int expected_type) # define dh_evp_type EVP_PKEY_DH # define dhx_evp_type EVP_PKEY_DHX -# define dh_input_type "DH" -# define dhx_input_type "DHX" # define dh_pem_type "DH" # define dhx_pem_type "X9.42 DH" #endif @@ -550,14 +570,14 @@ static int encode_dsa_params(const void *dsa, int nid, ASN1_STRING *params = ASN1_STRING_new(); if (params == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); return 0; } params->length = i2d_DSAparams(dsa, ¶ms->data); if (params->length <= 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); ASN1_STRING_free(params); return 0; } @@ -582,7 +602,8 @@ static int prepare_dsa_params(const void *dsa, int nid, int save, return 1; } -static int dsa_spki_pub_to_der(const void *dsa, unsigned char **pder) +static int dsa_spki_pub_to_der(const void *dsa, unsigned char **pder, + ossl_unused void *ctx) { const BIGNUM *bn = NULL; ASN1_INTEGER *pub_key = NULL; @@ -603,7 +624,8 @@ static int dsa_spki_pub_to_der(const void *dsa, unsigned char **pder) return ret; } -static int dsa_pki_priv_to_der(const void *dsa, unsigned char **pder) +static int dsa_pki_priv_to_der(const void *dsa, unsigned char **pder, + ossl_unused void *ctx) { const BIGNUM *bn = NULL; ASN1_INTEGER *priv_key = NULL; @@ -624,15 +646,18 @@ static int dsa_pki_priv_to_der(const void *dsa, unsigned char **pder) return ret; } +k2d_NOCTX(dsa_prv, i2d_DSAPrivateKey) +k2d_NOCTX(dsa_pub, i2d_DSAPublicKey) +k2d_NOCTX(dsa_param, i2d_DSAparams) + # define dsa_epki_priv_to_der dsa_pki_priv_to_der -# define dsa_type_specific_priv_to_der (i2d_of_void *)i2d_DSAPrivateKey -# define dsa_type_specific_pub_to_der (i2d_of_void *)i2d_DSAPublicKey -# define dsa_type_specific_params_to_der (i2d_of_void *)i2d_DSAparams +# define dsa_type_specific_priv_to_der dsa_prv_k2d +# define dsa_type_specific_pub_to_der dsa_pub_k2d +# define dsa_type_specific_params_to_der dsa_param_k2d # define dsa_check_key_type NULL # define dsa_evp_type EVP_PKEY_DSA -# define dsa_input_type "DSA" # define dsa_pem_type "DSA" #endif @@ -645,13 +670,13 @@ static int prepare_ec_explicit_params(const void *eckey, ASN1_STRING *params = ASN1_STRING_new(); if (params == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); return 0; } params->length = i2d_ECParameters(eckey, ¶ms->data); if (params->length <= 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); ASN1_STRING_free(params); return 0; } @@ -699,7 +724,8 @@ static int prepare_ec_params(const void *eckey, int nid, int save, } } -static int ec_spki_pub_to_der(const void *eckey, unsigned char **pder) +static int ec_spki_pub_to_der(const void *eckey, unsigned char **pder, + ossl_unused void *ctx) { if (EC_KEY_get0_public_key(eckey) == NULL) { ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); @@ -708,7 +734,8 @@ static int ec_spki_pub_to_der(const void *eckey, unsigned char **pder) return i2o_ECPublicKey(eckey, pder); } -static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder) +static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder, + ossl_unused void *ctx) { EC_KEY *eckey = (EC_KEY *)veckey; unsigned int old_flags; @@ -728,15 +755,17 @@ static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder) return ret; /* return the length of the der encoded data */ } +k2d_NOCTX(ec_param, i2d_ECParameters) +k2d_NOCTX(ec_prv, i2d_ECPrivateKey) + # define ec_epki_priv_to_der ec_pki_priv_to_der -# define ec_type_specific_params_to_der (i2d_of_void *)i2d_ECParameters +# define ec_type_specific_params_to_der ec_param_k2d /* No ec_type_specific_pub_to_der, there simply is no such thing */ -# define ec_type_specific_priv_to_der (i2d_of_void *)i2d_ECPrivateKey +# define ec_type_specific_priv_to_der ec_prv_k2d # define ec_check_key_type NULL # define ec_evp_type EVP_PKEY_EC -# define ec_input_type "EC" # define ec_pem_type "EC" # ifndef OPENSSL_NO_SM2 @@ -749,17 +778,17 @@ static int ec_pki_priv_to_der(const void *veckey, unsigned char **pder) * in AlgorithmIdentified.params). */ # define sm2_evp_type ec_evp_type -# define sm2_input_type "SM2" # define sm2_pem_type "SM2" # endif #endif /* ---------------------------------------------------------------------- */ -#ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_ECX # define prepare_ecx_params NULL -static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder) +static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder, + ossl_unused void *ctx) { const ECX_KEY *ecxkey = vecxkey; unsigned char *keyblob; @@ -770,16 +799,15 @@ static int ecx_spki_pub_to_der(const void *vecxkey, unsigned char **pder) } keyblob = OPENSSL_memdup(ecxkey->pubkey, ecxkey->keylen); - if (keyblob == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + if (keyblob == NULL) return 0; - } *pder = keyblob; return ecxkey->keylen; } -static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder) +static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder, + ossl_unused void *ctx) { const ECX_KEY *ecxkey = vecxkey; ASN1_OCTET_STRING oct; @@ -796,7 +824,7 @@ static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder) keybloblen = i2d_ASN1_OCTET_STRING(&oct, pder); if (keybloblen < 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); return 0; } @@ -816,10 +844,6 @@ static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder) # define ed448_evp_type EVP_PKEY_ED448 # define x25519_evp_type EVP_PKEY_X25519 # define x448_evp_type EVP_PKEY_X448 -# define ed25519_input_type "ED25519" -# define ed448_input_type "ED448" -# define x25519_input_type "X25519" -# define x448_input_type "X448" # define ed25519_pem_type "ED25519" # define ed448_pem_type "ED448" # define x25519_pem_type "X25519" @@ -828,6 +852,65 @@ static int ecx_pki_priv_to_der(const void *vecxkey, unsigned char **pder) /* ---------------------------------------------------------------------- */ +#ifndef OPENSSL_NO_ML_DSA +static int ml_dsa_spki_pub_to_der(const void *vkey, unsigned char **pder, + ossl_unused void *ctx) +{ + return ossl_ml_dsa_i2d_pubkey(vkey, pder); +} + +static int ml_dsa_pki_priv_to_der(const void *vkey, unsigned char **pder, + void *vctx) +{ + KEY2ANY_CTX *ctx = vctx; + + return ossl_ml_dsa_i2d_prvkey(vkey, pder, ctx->provctx); +} + +# 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 */ + +/* ---------------------------------------------------------------------- */ + +#ifndef OPENSSL_NO_ML_KEM + +static int ml_kem_spki_pub_to_der(const void *vkey, unsigned char **pder, + ossl_unused void *ctx) +{ + return ossl_ml_kem_i2d_pubkey(vkey, pder); +} + +static int ml_kem_pki_priv_to_der(const void *vkey, unsigned char **pder, + void *vctx) +{ + KEY2ANY_CTX *ctx = vctx; + + return ossl_ml_kem_i2d_prvkey(vkey, pder, ctx->provctx); +} + +# define ml_kem_epki_priv_to_der ml_kem_pki_priv_to_der +# define prepare_ml_kem_params NULL +# define ml_kem_check_key_type NULL + +# define ml_kem_512_evp_type EVP_PKEY_ML_KEM_512 +# define ml_kem_512_pem_type "ML-KEM-512" +# define ml_kem_768_evp_type EVP_PKEY_ML_KEM_768 +# define ml_kem_768_pem_type "ML-KEM-768" +# define ml_kem_1024_evp_type EVP_PKEY_ML_KEM_1024 +# define ml_kem_1024_pem_type "ML-KEM-1024" +#endif + +/* ---------------------------------------------------------------------- */ + /* * Helper functions to prepare RSA-PSS params for encoding. We would * have simply written the whole AlgorithmIdentifier, but existing libcrypto @@ -906,6 +989,9 @@ static int prepare_rsa_params(const void *rsa, int nid, int save, return 0; } +k2d_NOCTX(rsa_prv, i2d_RSAPrivateKey) +k2d_NOCTX(rsa_pub, i2d_RSAPublicKey) + /* * RSA is extremely simple, as PKCS#1 is used for the PKCS#8 |privateKey| * field as well as the SubjectPublicKeyInfo |subjectPublicKey| field. @@ -913,8 +999,8 @@ static int prepare_rsa_params(const void *rsa, int nid, int save, #define rsa_pki_priv_to_der rsa_type_specific_priv_to_der #define rsa_epki_priv_to_der rsa_type_specific_priv_to_der #define rsa_spki_pub_to_der rsa_type_specific_pub_to_der -#define rsa_type_specific_priv_to_der (i2d_of_void *)i2d_RSAPrivateKey -#define rsa_type_specific_pub_to_der (i2d_of_void *)i2d_RSAPublicKey +#define rsa_type_specific_priv_to_der rsa_prv_k2d +#define rsa_type_specific_pub_to_der rsa_pub_k2d #define rsa_type_specific_params_to_der NULL static int rsa_check_key_type(const void *rsa, int expected_type) @@ -932,19 +1018,103 @@ static int rsa_check_key_type(const void *rsa, int expected_type) #define rsa_evp_type EVP_PKEY_RSA #define rsapss_evp_type EVP_PKEY_RSA_PSS -#define rsa_input_type "RSA" -#define rsapss_input_type "RSA-PSS" #define rsa_pem_type "RSA" #define rsapss_pem_type "RSA-PSS" /* ---------------------------------------------------------------------- */ +#ifndef OPENSSL_NO_SLH_DSA +# define prepare_slh_dsa_params NULL + +static int slh_dsa_spki_pub_to_der(const void *vkey, unsigned char **pder, + ossl_unused void *ctx) +{ + const SLH_DSA_KEY *key = vkey; + uint8_t *key_blob; + size_t key_len; + + if (key == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + key_len = ossl_slh_dsa_key_get_pub_len(key); + key_blob = OPENSSL_memdup(ossl_slh_dsa_key_get_pub(key), key_len); + if (key_blob == NULL) + return 0; + + *pder = key_blob; + return key_len; +} + +static int slh_dsa_pki_priv_to_der(const void *vkey, unsigned char **pder, + ossl_unused void *ctx) +{ + const SLH_DSA_KEY *key = vkey; + size_t len; + + if (ossl_slh_dsa_key_get_priv(key) == NULL) { + ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + len = ossl_slh_dsa_key_get_priv_len(key); + + if (pder != NULL + && ((*pder = OPENSSL_memdup(ossl_slh_dsa_key_get_priv(key), len)) == NULL)) + return 0; + + return len; +} +# define slh_dsa_epki_priv_to_der slh_dsa_pki_priv_to_der + +/* SLH_DSA only has PKCS#8 / SubjectPublicKeyInfo representations. */ + +# define slh_dsa_check_key_type NULL +# define slh_dsa_sha2_128s_evp_type EVP_PKEY_SLH_DSA_SHA2_128S +# define slh_dsa_sha2_128f_evp_type EVP_PKEY_SLH_DSA_SHA2_128F +# define slh_dsa_sha2_192s_evp_type EVP_PKEY_SLH_DSA_SHA2_192S +# define slh_dsa_sha2_192f_evp_type EVP_PKEY_SLH_DSA_SHA2_192F +# define slh_dsa_sha2_256s_evp_type EVP_PKEY_SLH_DSA_SHA2_256S +# define slh_dsa_sha2_256f_evp_type EVP_PKEY_SLH_DSA_SHA2_256F +# define slh_dsa_shake_128s_evp_type EVP_PKEY_SLH_DSA_SHAKE_128S +# define slh_dsa_shake_128f_evp_type EVP_PKEY_SLH_DSA_SHAKE_128F +# define slh_dsa_shake_192s_evp_type EVP_PKEY_SLH_DSA_SHAKE_192S +# define slh_dsa_shake_192f_evp_type EVP_PKEY_SLH_DSA_SHAKE_192F +# define slh_dsa_shake_256s_evp_type EVP_PKEY_SLH_DSA_SHAKE_256S +# define slh_dsa_shake_256f_evp_type EVP_PKEY_SLH_DSA_SHAKE_256F +# define slh_dsa_sha2_128s_input_type "SLH-DSA-SHA2-128s" +# define slh_dsa_sha2_128f_input_type "SLH-DSA-SHA2-128f" +# define slh_dsa_sha2_192s_input_type "SLH-DSA-SHA2-192s" +# define slh_dsa_sha2_192f_input_type "SLH-DSA-SHA2-192f" +# define slh_dsa_sha2_256s_input_type "SLH-DSA-SHA2-256s" +# define slh_dsa_sha2_256f_input_type "SLH-DSA-SHA2-256f" +# define slh_dsa_shake_128s_input_type "SLH-DSA-SHAKE-128s" +# define slh_dsa_shake_128f_input_type "SLH-DSA-SHAKE-128f" +# define slh_dsa_shake_192s_input_type "SLH-DSA-SHAKE-192s" +# define slh_dsa_shake_192f_input_type "SLH-DSA-SHAKE-192f" +# define slh_dsa_shake_256s_input_type "SLH-DSA-SHAKE-256s" +# define slh_dsa_shake_256f_input_type "SLH-DSA-SHAKE-256f" +# define slh_dsa_sha2_128s_pem_type "SLH-DSA-SHA2-128s" +# define slh_dsa_sha2_128f_pem_type "SLH-DSA-SHA2-128f" +# define slh_dsa_sha2_192s_pem_type "SLH-DSA-SHA2-192s" +# define slh_dsa_sha2_192f_pem_type "SLH-DSA-SHA2-192f" +# define slh_dsa_sha2_256s_pem_type "SLH-DSA-SHA2-256s" +# define slh_dsa_sha2_256f_pem_type "SLH-DSA-SHA2-256f" +# define slh_dsa_shake_128s_pem_type "SLH-DSA-SHAKE-128s" +# define slh_dsa_shake_128f_pem_type "SLH-DSA-SHAKE-128f" +# define slh_dsa_shake_192s_pem_type "SLH-DSA-SHAKE-192s" +# define slh_dsa_shake_192f_pem_type "SLH-DSA-SHAKE-192f" +# define slh_dsa_shake_256s_pem_type "SLH-DSA-SHAKE-256s" +# define slh_dsa_shake_256f_pem_type "SLH-DSA-SHAKE-256f" +#endif /* OPENSSL_NO_SLH_DSA */ + +/* ---------------------------------------------------------------------- */ + static OSSL_FUNC_decoder_newctx_fn key2any_newctx; static OSSL_FUNC_decoder_freectx_fn key2any_freectx; static void *key2any_newctx(void *provctx) { - struct key2any_ctx_st *ctx = OPENSSL_zalloc(sizeof(*ctx)); + KEY2ANY_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx)); if (ctx != NULL) { ctx->provctx = provctx; @@ -956,7 +1126,7 @@ static void *key2any_newctx(void *provctx) static void key2any_freectx(void *vctx) { - struct key2any_ctx_st *ctx = vctx; + KEY2ANY_CTX *ctx = vctx; ossl_pw_clear_passphrase_data(&ctx->pwdata); EVP_CIPHER_free(ctx->cipher); @@ -976,7 +1146,7 @@ static const OSSL_PARAM *key2any_settable_ctx_params(ossl_unused void *provctx) static int key2any_set_ctx_params(void *vctx, const OSSL_PARAM params[]) { - struct key2any_ctx_st *ctx = vctx; + KEY2ANY_CTX *ctx = vctx; OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx); const OSSL_PARAM *cipherp = OSSL_PARAM_locate_const(params, OSSL_ENCODER_PARAM_CIPHER); @@ -1043,13 +1213,13 @@ static int key2any_check_selection(int selection, int selection_mask) return 0; } -static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, +static int key2any_encode(KEY2ANY_CTX *ctx, OSSL_CORE_BIO *cout, const void *key, int type, const char *pemname, check_key_type_fn *checker, key_to_der_fn *writer, OSSL_PASSPHRASE_CALLBACK *pwcb, void *pwcbarg, key_to_paramstring_fn *key2paramstring, - i2d_of_void *key2der) + OSSL_i2d_of_void_ctx *key2der) { int ret = 0; @@ -1230,10 +1400,6 @@ static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, * type This is the type name for the set of functions that implement * the key type. For example, ed25519, ed448, x25519 and x448 * are all implemented with the exact same set of functions. - * evp_type The corresponding EVP_PKEY_xxx type macro for each key. - * Necessary because we currently use EVP_PKEY with legacy - * native keys internally. This will need to be refactored - * when that legacy support goes away. * kind What kind of support to implement. These translate into * the DO_##kind macros above. * output The output type to implement. may be der or pem. @@ -1243,7 +1409,7 @@ static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, * * ossl_##impl##_to_##kind##_##output##_encoder_functions */ -#define MAKE_ENCODER(impl, type, evp_type, kind, output) \ +#define MAKE_ENCODER(impl, type, kind, output) \ static OSSL_FUNC_encoder_import_object_fn \ impl##_to_##kind##_##output##_import_object; \ static OSSL_FUNC_encoder_free_object_fn \ @@ -1255,7 +1421,7 @@ static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, impl##_to_##kind##_##output##_import_object(void *vctx, int selection, \ const OSSL_PARAM params[]) \ { \ - struct key2any_ctx_st *ctx = vctx; \ + KEY2ANY_CTX *ctx = vctx; \ \ return ossl_prov_import_key(ossl_##impl##_keymgmt_functions, \ ctx->provctx, selection, params); \ @@ -1306,25 +1472,25 @@ static int key2any_encode(struct key2any_ctx_st *ctx, OSSL_CORE_BIO *cout, (void (*)(void))impl##_to_##kind##_##output##_free_object }, \ { OSSL_FUNC_ENCODER_ENCODE, \ (void (*)(void))impl##_to_##kind##_##output##_encode }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } /* * Replacements for i2d_{TYPE}PrivateKey, i2d_{TYPE}PublicKey, * i2d_{TYPE}params, as they exist. */ -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, type_specific_keypair, der); +MAKE_ENCODER(rsa, rsa, type_specific_keypair, der); #ifndef OPENSSL_NO_DH -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, type_specific_params, der); -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, type_specific_params, der); +MAKE_ENCODER(dh, dh, type_specific_params, der); +MAKE_ENCODER(dhx, dh, type_specific_params, der); #endif #ifndef OPENSSL_NO_DSA -MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, type_specific, der); +MAKE_ENCODER(dsa, dsa, type_specific, der); #endif #ifndef OPENSSL_NO_EC -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, type_specific_no_pub, der); +MAKE_ENCODER(ec, ec, type_specific_no_pub, der); # ifndef OPENSSL_NO_SM2 -MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, type_specific_no_pub, der); +MAKE_ENCODER(sm2, ec, type_specific_no_pub, der); # endif #endif @@ -1332,18 +1498,18 @@ MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, type_specific_no_pub, der); * Replacements for PEM_write_bio_{TYPE}PrivateKey, * PEM_write_bio_{TYPE}PublicKey, PEM_write_bio_{TYPE}params, as they exist. */ -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, type_specific_keypair, pem); +MAKE_ENCODER(rsa, rsa, type_specific_keypair, pem); #ifndef OPENSSL_NO_DH -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, type_specific_params, pem); -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, type_specific_params, pem); +MAKE_ENCODER(dh, dh, type_specific_params, pem); +MAKE_ENCODER(dhx, dh, type_specific_params, pem); #endif #ifndef OPENSSL_NO_DSA -MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, type_specific, pem); +MAKE_ENCODER(dsa, dsa, type_specific, pem); #endif #ifndef OPENSSL_NO_EC -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, type_specific_no_pub, pem); +MAKE_ENCODER(ec, ec, type_specific_no_pub, pem); # ifndef OPENSSL_NO_SM2 -MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, type_specific_no_pub, pem); +MAKE_ENCODER(sm2, ec, type_specific_no_pub, pem); # endif #endif @@ -1355,79 +1521,178 @@ MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, type_specific_no_pub, pem); * For PEM, these are expected to be used by PEM_write_bio_PrivateKey(), * PEM_write_bio_PUBKEY() and PEM_write_bio_Parameters(). */ -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PrivateKeyInfo, der); -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PrivateKeyInfo, pem); -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, SubjectPublicKeyInfo, der); -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, SubjectPublicKeyInfo, pem); -MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PrivateKeyInfo, der); -MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PrivateKeyInfo, pem); -MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, SubjectPublicKeyInfo, der); -MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(rsa, rsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(rsa, rsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(rsa, rsa, PrivateKeyInfo, der); +MAKE_ENCODER(rsa, rsa, PrivateKeyInfo, pem); +MAKE_ENCODER(rsa, rsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(rsa, rsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(rsapss, rsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(rsapss, rsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(rsapss, rsa, PrivateKeyInfo, der); +MAKE_ENCODER(rsapss, rsa, PrivateKeyInfo, pem); +MAKE_ENCODER(rsapss, rsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(rsapss, rsa, SubjectPublicKeyInfo, pem); #ifndef OPENSSL_NO_DH -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PrivateKeyInfo, der); -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PrivateKeyInfo, pem); -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, SubjectPublicKeyInfo, der); -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, SubjectPublicKeyInfo, pem); -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, PrivateKeyInfo, der); -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, PrivateKeyInfo, pem); -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, SubjectPublicKeyInfo, der); -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(dh, dh, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(dh, dh, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(dh, dh, PrivateKeyInfo, der); +MAKE_ENCODER(dh, dh, PrivateKeyInfo, pem); +MAKE_ENCODER(dh, dh, SubjectPublicKeyInfo, der); +MAKE_ENCODER(dh, dh, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(dhx, dh, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(dhx, dh, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(dhx, dh, PrivateKeyInfo, der); +MAKE_ENCODER(dhx, dh, PrivateKeyInfo, pem); +MAKE_ENCODER(dhx, dh, SubjectPublicKeyInfo, der); +MAKE_ENCODER(dhx, dh, SubjectPublicKeyInfo, pem); #endif #ifndef OPENSSL_NO_DSA -MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, PrivateKeyInfo, der); -MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, PrivateKeyInfo, pem); -MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, SubjectPublicKeyInfo, der); -MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(dsa, dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(dsa, dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(dsa, dsa, PrivateKeyInfo, der); +MAKE_ENCODER(dsa, dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(dsa, dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(dsa, dsa, SubjectPublicKeyInfo, pem); #endif #ifndef OPENSSL_NO_EC -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PrivateKeyInfo, der); -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, PrivateKeyInfo, pem); -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der); -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(ec, ec, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(ec, ec, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(ec, ec, PrivateKeyInfo, der); +MAKE_ENCODER(ec, ec, PrivateKeyInfo, pem); +MAKE_ENCODER(ec, ec, SubjectPublicKeyInfo, der); +MAKE_ENCODER(ec, ec, SubjectPublicKeyInfo, pem); # ifndef OPENSSL_NO_SM2 -MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PrivateKeyInfo, der); -MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, PrivateKeyInfo, pem); -MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, der); -MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(sm2, ec, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(sm2, ec, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(sm2, ec, PrivateKeyInfo, der); +MAKE_ENCODER(sm2, ec, PrivateKeyInfo, pem); +MAKE_ENCODER(sm2, ec, SubjectPublicKeyInfo, der); +MAKE_ENCODER(sm2, ec, SubjectPublicKeyInfo, pem); # endif -MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PrivateKeyInfo, der); -MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, PrivateKeyInfo, pem); -MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, SubjectPublicKeyInfo, der); -MAKE_ENCODER(ed25519, ecx, EVP_PKEY_ED25519, SubjectPublicKeyInfo, pem); -MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, der); -MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, pem); -MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, der); -MAKE_ENCODER(ed448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, pem); -MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, PrivateKeyInfo, der); -MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, PrivateKeyInfo, pem); -MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, SubjectPublicKeyInfo, der); -MAKE_ENCODER(x25519, ecx, EVP_PKEY_X25519, SubjectPublicKeyInfo, pem); -MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, der); -MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, EncryptedPrivateKeyInfo, pem); -MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, der); -MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, PrivateKeyInfo, pem); -MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, der); -MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, pem); +# ifndef OPENSSL_NO_ECX +MAKE_ENCODER(ed25519, ecx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(ed25519, ecx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(ed25519, ecx, PrivateKeyInfo, der); +MAKE_ENCODER(ed25519, ecx, PrivateKeyInfo, pem); +MAKE_ENCODER(ed25519, ecx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(ed25519, ecx, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(ed448, ecx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(ed448, ecx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(ed448, ecx, PrivateKeyInfo, der); +MAKE_ENCODER(ed448, ecx, PrivateKeyInfo, pem); +MAKE_ENCODER(ed448, ecx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(ed448, ecx, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(x25519, ecx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(x25519, ecx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(x25519, ecx, PrivateKeyInfo, der); +MAKE_ENCODER(x25519, ecx, PrivateKeyInfo, pem); +MAKE_ENCODER(x25519, ecx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(x25519, ecx, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(x448, ecx, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(x448, ecx, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(x448, ecx, PrivateKeyInfo, der); +MAKE_ENCODER(x448, ecx, PrivateKeyInfo, pem); +MAKE_ENCODER(x448, ecx, SubjectPublicKeyInfo, der); +MAKE_ENCODER(x448, ecx, SubjectPublicKeyInfo, pem); +# endif +#endif +#ifndef OPENSSL_NO_SLH_DSA +MAKE_ENCODER(slh_dsa_sha2_128s, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_128f, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_192s, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_192f, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_256s, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_256f, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_128s, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_128f, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_192s, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_192f, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_256s, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_256f, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_128s, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_128f, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_192s, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_192f, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_256s, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_256f, slh_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_128s, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_128f, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_192s, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_192f, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_256s, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_256f, slh_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_128s, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_128f, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_192s, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_192f, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_256s, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_256f, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_128s, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_128f, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_192s, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_192f, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_256s, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_256f, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_128s, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_128f, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_192s, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_192f, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_256s, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_256f, slh_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_128s, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_128f, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_192s, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_192f, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_256s, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_256f, slh_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_128s, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_128f, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_192s, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_192f, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_256s, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_256f, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_sha2_128s, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_128f, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_192s, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_192f, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_256s, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_sha2_256f, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_128s, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_128f, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_192s, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_192f, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_256s, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_256f, slh_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(slh_dsa_shake_128s, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_128f, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_192s, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_192f, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_256s, slh_dsa, SubjectPublicKeyInfo, pem); +MAKE_ENCODER(slh_dsa_shake_256f, slh_dsa, SubjectPublicKeyInfo, pem); +#endif /* OPENSSL_NO_SLH_DSA */ + +#ifndef OPENSSL_NO_ML_KEM +MAKE_ENCODER(ml_kem_512, ml_kem, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(ml_kem_512, ml_kem, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(ml_kem_512, ml_kem, PrivateKeyInfo, der); +MAKE_ENCODER(ml_kem_512, ml_kem, PrivateKeyInfo, pem); +MAKE_ENCODER(ml_kem_512, ml_kem, SubjectPublicKeyInfo, der); +MAKE_ENCODER(ml_kem_512, ml_kem, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(ml_kem_768, ml_kem, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(ml_kem_768, ml_kem, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(ml_kem_768, ml_kem, PrivateKeyInfo, der); +MAKE_ENCODER(ml_kem_768, ml_kem, PrivateKeyInfo, pem); +MAKE_ENCODER(ml_kem_768, ml_kem, SubjectPublicKeyInfo, der); +MAKE_ENCODER(ml_kem_768, ml_kem, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(ml_kem_1024, ml_kem, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(ml_kem_1024, ml_kem, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(ml_kem_1024, ml_kem, PrivateKeyInfo, der); +MAKE_ENCODER(ml_kem_1024, ml_kem, PrivateKeyInfo, pem); +MAKE_ENCODER(ml_kem_1024, ml_kem, SubjectPublicKeyInfo, der); +MAKE_ENCODER(ml_kem_1024, ml_kem, SubjectPublicKeyInfo, pem); #endif /* @@ -1438,39 +1703,62 @@ MAKE_ENCODER(x448, ecx, EVP_PKEY_ED448, SubjectPublicKeyInfo, pem); * ED25519, ED448, X25519 or X448, and they therefore only have PKCS#8 * and SubjectPublicKeyInfo implementations as implemented above. */ -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, RSA, der); -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, RSA, pem); +MAKE_ENCODER(rsa, rsa, RSA, der); +MAKE_ENCODER(rsa, rsa, RSA, pem); #ifndef OPENSSL_NO_DH -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, DH, der); -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, DH, pem); -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, DHX, der); -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, DHX, pem); +MAKE_ENCODER(dh, dh, DH, der); +MAKE_ENCODER(dh, dh, DH, pem); +MAKE_ENCODER(dhx, dh, DHX, der); +MAKE_ENCODER(dhx, dh, DHX, pem); #endif #ifndef OPENSSL_NO_DSA -MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, DSA, der); -MAKE_ENCODER(dsa, dsa, EVP_PKEY_DSA, DSA, pem); +MAKE_ENCODER(dsa, dsa, DSA, der); +MAKE_ENCODER(dsa, dsa, DSA, pem); #endif #ifndef OPENSSL_NO_EC -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EC, der); -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, EC, pem); +MAKE_ENCODER(ec, ec, EC, der); +MAKE_ENCODER(ec, ec, EC, pem); # ifndef OPENSSL_NO_SM2 -MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SM2, der); -MAKE_ENCODER(sm2, ec, EVP_PKEY_EC, SM2, pem); +MAKE_ENCODER(sm2, ec, SM2, der); +MAKE_ENCODER(sm2, ec, SM2, pem); # endif #endif /* Convenience structure names */ -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PKCS1, der); -MAKE_ENCODER(rsa, rsa, EVP_PKEY_RSA, PKCS1, pem); -MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PKCS1, der); -MAKE_ENCODER(rsapss, rsa, EVP_PKEY_RSA_PSS, PKCS1, pem); +MAKE_ENCODER(rsa, rsa, PKCS1, der); +MAKE_ENCODER(rsa, rsa, PKCS1, pem); +MAKE_ENCODER(rsapss, rsa, PKCS1, der); +MAKE_ENCODER(rsapss, rsa, PKCS1, pem); #ifndef OPENSSL_NO_DH -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PKCS3, der); /* parameters only */ -MAKE_ENCODER(dh, dh, EVP_PKEY_DH, PKCS3, pem); /* parameters only */ -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, X9_42, der); /* parameters only */ -MAKE_ENCODER(dhx, dh, EVP_PKEY_DHX, X9_42, pem); /* parameters only */ +MAKE_ENCODER(dh, dh, PKCS3, der); /* parameters only */ +MAKE_ENCODER(dh, dh, PKCS3, pem); /* parameters only */ +MAKE_ENCODER(dhx, dh, X9_42, der); /* parameters only */ +MAKE_ENCODER(dhx, dh, X9_42, pem); /* parameters only */ #endif #ifndef OPENSSL_NO_EC -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, X9_62, der); -MAKE_ENCODER(ec, ec, EVP_PKEY_EC, X9_62, pem); +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, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(ml_dsa_44, ml_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(ml_dsa_44, ml_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(ml_dsa_44, ml_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(ml_dsa_44, ml_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(ml_dsa_44, ml_dsa, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(ml_dsa_65, ml_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(ml_dsa_65, ml_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(ml_dsa_65, ml_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(ml_dsa_65, ml_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(ml_dsa_65, ml_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(ml_dsa_65, ml_dsa, SubjectPublicKeyInfo, pem); + +MAKE_ENCODER(ml_dsa_87, ml_dsa, EncryptedPrivateKeyInfo, der); +MAKE_ENCODER(ml_dsa_87, ml_dsa, EncryptedPrivateKeyInfo, pem); +MAKE_ENCODER(ml_dsa_87, ml_dsa, PrivateKeyInfo, der); +MAKE_ENCODER(ml_dsa_87, ml_dsa, PrivateKeyInfo, pem); +MAKE_ENCODER(ml_dsa_87, ml_dsa, SubjectPublicKeyInfo, der); +MAKE_ENCODER(ml_dsa_87, ml_dsa, SubjectPublicKeyInfo, pem); +#endif /* OPENSSL_NO_ML_DSA */ diff --git a/providers/implementations/encode_decode/encode_key2blob.c b/providers/implementations/encode_decode/encode_key2blob.c index 550bceb09f58..29e72faa63de 100644 --- a/providers/implementations/encode_decode/encode_key2blob.c +++ b/providers/implementations/encode_decode/encode_key2blob.c @@ -1,5 +1,5 @@ /* - * Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2021-2023 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 @@ -168,7 +168,7 @@ static int key2blob_encode(void *vctx, const void *key, int selection, (void (*)(void))impl##2blob_free_object }, \ { OSSL_FUNC_ENCODER_ENCODE, \ (void (*)(void))impl##2blob_encode }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_EC diff --git a/providers/implementations/encode_decode/encode_key2ms.c b/providers/implementations/encode_decode/encode_key2ms.c index fe8c2dce4316..1f21a5129615 100644 --- a/providers/implementations/encode_decode/encode_key2ms.c +++ b/providers/implementations/encode_decode/encode_key2ms.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2020-2023 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 @@ -222,7 +222,7 @@ static int key2pvk_encode(void *vctx, const void *key, int selection, (void (*)(void))impl##2##output##_free_object }, \ { OSSL_FUNC_ENCODER_ENCODE, \ (void (*)(void))impl##2##output##_encode }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_DSA diff --git a/providers/implementations/encode_decode/encode_key2text.c b/providers/implementations/encode_decode/encode_key2text.c index 637fcf6a1214..7a564807326f 100644 --- a/providers/implementations/encode_decode/encode_key2text.c +++ b/providers/implementations/encode_decode/encode_key2text.c @@ -1,5 +1,5 @@ /* - * Copyright 2020-2023 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 @@ -12,8 +12,6 @@ */ #include "internal/deprecated.h" -#include <ctype.h> - #include <openssl/core.h> #include <openssl/core_dispatch.h> #include <openssl/core_names.h> @@ -21,196 +19,23 @@ #include <openssl/err.h> #include <openssl/safestack.h> #include <openssl/proverr.h> -#include "internal/ffc.h" -#include "crypto/bn.h" /* bn_get_words() */ #include "crypto/dh.h" /* ossl_dh_get0_params() */ #include "crypto/dsa.h" /* ossl_dsa_get0_params() */ #include "crypto/ec.h" /* ossl_ec_key_get_libctx */ #include "crypto/ecx.h" /* ECX_KEY, etc... */ +#include "crypto/ml_kem.h" /* ML_KEM_KEY, etc... */ #include "crypto/rsa.h" /* RSA_PSS_PARAMS_30, etc... */ +#include "crypto/ml_dsa.h" +#include "crypto/slh_dsa.h" #include "prov/bio.h" #include "prov/implementations.h" +#include "internal/encoder.h" #include "endecoder_local.h" +#include "ml_dsa_codecs.h" +#include "ml_kem_codecs.h" DEFINE_SPECIAL_STACK_OF_CONST(BIGNUM_const, BIGNUM) -# ifdef SIXTY_FOUR_BIT_LONG -# define BN_FMTu "%lu" -# define BN_FMTx "%lx" -# endif - -# ifdef SIXTY_FOUR_BIT -# define BN_FMTu "%llu" -# define BN_FMTx "%llx" -# endif - -# ifdef THIRTY_TWO_BIT -# define BN_FMTu "%u" -# define BN_FMTx "%x" -# endif - -static int print_labeled_bignum(BIO *out, const char *label, const BIGNUM *bn) -{ - int ret = 0, use_sep = 0; - char *hex_str = NULL, *p; - const char spaces[] = " "; - const char *post_label_spc = " "; - - const char *neg = ""; - int bytes; - - if (bn == NULL) - return 0; - if (label == NULL) { - label = ""; - post_label_spc = ""; - } - - if (BN_is_zero(bn)) - return BIO_printf(out, "%s%s0\n", label, post_label_spc); - - if (BN_num_bytes(bn) <= BN_BYTES) { - BN_ULONG *words = bn_get_words(bn); - - if (BN_is_negative(bn)) - neg = "-"; - - return BIO_printf(out, "%s%s%s" BN_FMTu " (%s0x" BN_FMTx ")\n", - label, post_label_spc, neg, words[0], neg, words[0]); - } - - hex_str = BN_bn2hex(bn); - if (hex_str == NULL) - return 0; - - p = hex_str; - if (*p == '-') { - ++p; - neg = " (Negative)"; - } - if (BIO_printf(out, "%s%s\n", label, neg) <= 0) - goto err; - - /* Keep track of how many bytes we have printed out so far */ - bytes = 0; - - if (BIO_printf(out, "%s", spaces) <= 0) - goto err; - - /* Add a leading 00 if the top bit is set */ - if (*p >= '8') { - if (BIO_printf(out, "%02x", 0) <= 0) - goto err; - ++bytes; - use_sep = 1; - } - while (*p != '\0') { - /* Do a newline after every 15 hex bytes + add the space indent */ - if ((bytes % 15) == 0 && bytes > 0) { - if (BIO_printf(out, ":\n%s", spaces) <= 0) - goto err; - use_sep = 0; /* The first byte on the next line doesnt have a : */ - } - if (BIO_printf(out, "%s%c%c", use_sep ? ":" : "", - tolower((unsigned char)p[0]), - tolower((unsigned char)p[1])) <= 0) - goto err; - ++bytes; - p += 2; - use_sep = 1; - } - if (BIO_printf(out, "\n") <= 0) - goto err; - ret = 1; -err: - OPENSSL_free(hex_str); - return ret; -} - -/* Number of octets per line */ -#define LABELED_BUF_PRINT_WIDTH 15 - -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_EC) -static int print_labeled_buf(BIO *out, const char *label, - const unsigned char *buf, size_t buflen) -{ - size_t i; - - if (BIO_printf(out, "%s\n", label) <= 0) - return 0; - - for (i = 0; i < buflen; i++) { - if ((i % LABELED_BUF_PRINT_WIDTH) == 0) { - if (i > 0 && BIO_printf(out, "\n") <= 0) - return 0; - if (BIO_printf(out, " ") <= 0) - return 0; - } - - if (BIO_printf(out, "%02x%s", buf[i], - (i == buflen - 1) ? "" : ":") <= 0) - return 0; - } - if (BIO_printf(out, "\n") <= 0) - return 0; - - return 1; -} -#endif - -#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) -static int ffc_params_to_text(BIO *out, const FFC_PARAMS *ffc) -{ - if (ffc->nid != NID_undef) { -#ifndef OPENSSL_NO_DH - const DH_NAMED_GROUP *group = ossl_ffc_uid_to_dh_named_group(ffc->nid); - const char *name = ossl_ffc_named_group_get_name(group); - - if (name == NULL) - goto err; - if (BIO_printf(out, "GROUP: %s\n", name) <= 0) - goto err; - return 1; -#else - /* How could this be? We should not have a nid in a no-dh build. */ - goto err; -#endif - } - - if (!print_labeled_bignum(out, "P: ", ffc->p)) - goto err; - if (ffc->q != NULL) { - if (!print_labeled_bignum(out, "Q: ", ffc->q)) - goto err; - } - if (!print_labeled_bignum(out, "G: ", ffc->g)) - goto err; - if (ffc->j != NULL) { - if (!print_labeled_bignum(out, "J: ", ffc->j)) - goto err; - } - if (ffc->seed != NULL) { - if (!print_labeled_buf(out, "SEED:", ffc->seed, ffc->seedlen)) - goto err; - } - if (ffc->gindex != -1) { - if (BIO_printf(out, "gindex: %d\n", ffc->gindex) <= 0) - goto err; - } - if (ffc->pcounter != -1) { - if (BIO_printf(out, "pcounter: %d\n", ffc->pcounter) <= 0) - goto err; - } - if (ffc->h != 0) { - if (BIO_printf(out, "h: %d\n", ffc->h) <= 0) - goto err; - } - return 1; -err: - return 0; -} -#endif - /* ---------------------------------------------------------------------- */ #ifndef OPENSSL_NO_DH @@ -266,13 +91,13 @@ static int dh_to_text(BIO *out, const void *key, int selection) if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) return 0; if (priv_key != NULL - && !print_labeled_bignum(out, "private-key:", priv_key)) + && !ossl_bio_print_labeled_bignum(out, "private-key:", priv_key)) return 0; if (pub_key != NULL - && !print_labeled_bignum(out, "public-key:", pub_key)) + && !ossl_bio_print_labeled_bignum(out, "public-key:", pub_key)) return 0; if (params != NULL - && !ffc_params_to_text(out, params)) + && !ossl_bio_print_ffc_params(out, params)) return 0; length = DH_get_length(dh); if (length > 0 @@ -282,9 +107,6 @@ static int dh_to_text(BIO *out, const void *key, int selection) return 1; } - -# define dh_input_type "DH" -# define dhx_input_type "DHX" #endif /* ---------------------------------------------------------------------- */ @@ -341,19 +163,17 @@ static int dsa_to_text(BIO *out, const void *key, int selection) if (BIO_printf(out, "%s: (%d bit)\n", type_label, BN_num_bits(p)) <= 0) return 0; if (priv_key != NULL - && !print_labeled_bignum(out, "priv:", priv_key)) + && !ossl_bio_print_labeled_bignum(out, "priv:", priv_key)) return 0; if (pub_key != NULL - && !print_labeled_bignum(out, "pub: ", pub_key)) + && !ossl_bio_print_labeled_bignum(out, "pub: ", pub_key)) return 0; if (params != NULL - && !ffc_params_to_text(out, params)) + && !ossl_bio_print_ffc_params(out, params)) return 0; return 1; } - -# define dsa_input_type "DSA" #endif /* ---------------------------------------------------------------------- */ @@ -381,9 +201,9 @@ static int ec_param_explicit_curve_to_text(BIO *out, const EC_GROUP *group, return 0; plabel = "Polynomial:"; } - return print_labeled_bignum(out, plabel, p) - && print_labeled_bignum(out, "A: ", a) - && print_labeled_bignum(out, "B: ", b); + return ossl_bio_print_labeled_bignum(out, plabel, p) + && ossl_bio_print_labeled_bignum(out, "A: ", a) + && ossl_bio_print_labeled_bignum(out, "B: ", b); } static int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group, @@ -420,7 +240,7 @@ static int ec_param_explicit_gen_to_text(BIO *out, const EC_GROUP *group, if (buflen == 0) return 0; - ret = print_labeled_buf(out, glabel, buf, buflen); + ret = ossl_bio_print_labeled_buf(out, glabel, buf, buflen); OPENSSL_clear_free(buf, buflen); return ret; } @@ -454,11 +274,11 @@ static int ec_param_explicit_to_text(BIO *out, const EC_GROUP *group, if (BIO_printf(out, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) <= 0 || !ec_param_explicit_curve_to_text(out, group, ctx) || !ec_param_explicit_gen_to_text(out, group, ctx) - || !print_labeled_bignum(out, "Order: ", order) + || !ossl_bio_print_labeled_bignum(out, "Order: ", order) || (cofactor != NULL - && !print_labeled_bignum(out, "Cofactor: ", cofactor)) + && !ossl_bio_print_labeled_bignum(out, "Cofactor: ", cofactor)) || (seed != NULL - && !print_labeled_buf(out, "Seed:", seed, seed_len))) + && !ossl_bio_print_labeled_buf(out, "Seed:", seed, seed_len))) goto err; ret = 1; err: @@ -513,7 +333,8 @@ static int ec_to_text(BIO *out, const void *key, int selection) else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) type_label = "Public-Key"; else if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) - type_label = "EC-Parameters"; + if (EC_GROUP_get_curve_name(group) != NID_sm2) + type_label = "EC-Parameters"; if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { const BIGNUM *priv_key = EC_KEY_get0_private_key(ec); @@ -539,14 +360,15 @@ static int ec_to_text(BIO *out, const void *key, int selection) goto err; } - if (BIO_printf(out, "%s: (%d bit)\n", type_label, - EC_GROUP_order_bits(group)) <= 0) + if (type_label != NULL + && BIO_printf(out, "%s: (%d bit)\n", type_label, + EC_GROUP_order_bits(group)) <= 0) goto err; if (priv != NULL - && !print_labeled_buf(out, "priv:", priv, priv_len)) + && !ossl_bio_print_labeled_buf(out, "priv:", priv, priv_len)) goto err; if (pub != NULL - && !print_labeled_buf(out, "pub:", pub, pub_len)) + && !ossl_bio_print_labeled_buf(out, "pub:", pub, pub_len)) goto err; if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) ret = ec_param_to_text(out, group, ossl_ec_key_get_libctx(ec)); @@ -555,17 +377,11 @@ err: OPENSSL_free(pub); return ret; } - -# define ec_input_type "EC" - -# ifndef OPENSSL_NO_SM2 -# define sm2_input_type "SM2" -# endif #endif /* ---------------------------------------------------------------------- */ -#ifndef OPENSSL_NO_EC +#ifndef OPENSSL_NO_ECX static int ecx_to_text(BIO *out, const void *key, int selection) { const ECX_KEY *ecx = key; @@ -599,7 +415,7 @@ static int ecx_to_text(BIO *out, const void *key, int selection) if (BIO_printf(out, "%s Private-Key:\n", type_label) <= 0) return 0; - if (!print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen)) + if (!ossl_bio_print_labeled_buf(out, "priv:", ecx->privkey, ecx->keylen)) return 0; } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) { /* ecx->pubkey is an array, not a pointer... */ @@ -612,20 +428,31 @@ static int ecx_to_text(BIO *out, const void *key, int selection) return 0; } - if (!print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen)) + if (!ossl_bio_print_labeled_buf(out, "pub:", ecx->pubkey, ecx->keylen)) return 0; return 1; } +#endif -# define ed25519_input_type "ED25519" -# define ed448_input_type "ED448" -# define x25519_input_type "X25519" -# define x448_input_type "X448" +/* ---------------------------------------------------------------------- */ + +#ifndef OPENSSL_NO_ML_KEM +static int ml_kem_to_text(BIO *out, const void *vkey, int selection) +{ + return ossl_ml_kem_key_to_text(out, (ML_KEM_KEY *)vkey, selection); +} #endif /* ---------------------------------------------------------------------- */ +#ifndef OPENSSL_NO_SLH_DSA +static int slh_dsa_to_text(BIO *out, const void *key, int selection) +{ + return ossl_slh_dsa_key_to_text(out, (SLH_DSA_KEY *)key, selection); +} +#endif /* OPENSSL_NO_SLH_DSA */ + static int rsa_to_text(BIO *out, const void *key, int selection) { const RSA *rsa = key; @@ -650,7 +477,7 @@ static int rsa_to_text(BIO *out, const void *key, int selection) coeffs = sk_BIGNUM_const_new_null(); if (factors == NULL || exps == NULL || coeffs == NULL) { - ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_PROV, ERR_R_CRYPTO_LIB); goto err; } @@ -678,45 +505,45 @@ static int rsa_to_text(BIO *out, const void *key, int selection) goto err; } - if (!print_labeled_bignum(out, modulus_label, rsa_n)) + if (!ossl_bio_print_labeled_bignum(out, modulus_label, rsa_n)) goto err; - if (!print_labeled_bignum(out, exponent_label, rsa_e)) + if (!ossl_bio_print_labeled_bignum(out, exponent_label, rsa_e)) goto err; if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { int i; - if (!print_labeled_bignum(out, "privateExponent:", rsa_d)) + if (!ossl_bio_print_labeled_bignum(out, "privateExponent:", rsa_d)) goto err; - if (!print_labeled_bignum(out, "prime1:", - sk_BIGNUM_const_value(factors, 0))) + if (!ossl_bio_print_labeled_bignum(out, "prime1:", + sk_BIGNUM_const_value(factors, 0))) goto err; - if (!print_labeled_bignum(out, "prime2:", - sk_BIGNUM_const_value(factors, 1))) + if (!ossl_bio_print_labeled_bignum(out, "prime2:", + sk_BIGNUM_const_value(factors, 1))) goto err; - if (!print_labeled_bignum(out, "exponent1:", - sk_BIGNUM_const_value(exps, 0))) + if (!ossl_bio_print_labeled_bignum(out, "exponent1:", + sk_BIGNUM_const_value(exps, 0))) goto err; - if (!print_labeled_bignum(out, "exponent2:", - sk_BIGNUM_const_value(exps, 1))) + if (!ossl_bio_print_labeled_bignum(out, "exponent2:", + sk_BIGNUM_const_value(exps, 1))) goto err; - if (!print_labeled_bignum(out, "coefficient:", - sk_BIGNUM_const_value(coeffs, 0))) + if (!ossl_bio_print_labeled_bignum(out, "coefficient:", + sk_BIGNUM_const_value(coeffs, 0))) goto err; for (i = 2; i < sk_BIGNUM_const_num(factors); i++) { if (BIO_printf(out, "prime%d:", i + 1) <= 0) goto err; - if (!print_labeled_bignum(out, NULL, - sk_BIGNUM_const_value(factors, i))) + if (!ossl_bio_print_labeled_bignum(out, NULL, + sk_BIGNUM_const_value(factors, i))) goto err; if (BIO_printf(out, "exponent%d:", i + 1) <= 0) goto err; - if (!print_labeled_bignum(out, NULL, - sk_BIGNUM_const_value(exps, i))) + if (!ossl_bio_print_labeled_bignum(out, NULL, + sk_BIGNUM_const_value(exps, i))) goto err; if (BIO_printf(out, "coefficient%d:", i + 1) <= 0) goto err; - if (!print_labeled_bignum(out, NULL, - sk_BIGNUM_const_value(coeffs, i - 1))) + if (!ossl_bio_print_labeled_bignum(out, NULL, + sk_BIGNUM_const_value(coeffs, i - 1))) goto err; } } @@ -778,9 +605,14 @@ static int rsa_to_text(BIO *out, const void *key, int selection) return ret; } -#define rsa_input_type "RSA" -#define rsapss_input_type "RSA-PSS" +/* ---------------------------------------------------------------------- */ +#ifndef OPENSSL_NO_ML_DSA +static int ml_dsa_to_text(BIO *out, const void *key, int selection) +{ + return ossl_ml_dsa_key_to_text(out, (ML_DSA_KEY *)key, selection); +} +#endif /* OPENSSL_NO_ML_DSA */ /* ---------------------------------------------------------------------- */ static void *key2text_newctx(void *provctx) @@ -853,7 +685,7 @@ static int key2text_encode(void *vctx, const void *key, int selection, (void (*)(void))impl##2text_free_object }, \ { OSSL_FUNC_ENCODER_ENCODE, \ (void (*)(void))impl##2text_encode }, \ - { 0, NULL } \ + OSSL_DISPATCH_END \ } #ifndef OPENSSL_NO_DH @@ -868,10 +700,38 @@ MAKE_TEXT_ENCODER(ec, ec); # ifndef OPENSSL_NO_SM2 MAKE_TEXT_ENCODER(sm2, ec); # endif +# ifndef OPENSSL_NO_ECX MAKE_TEXT_ENCODER(ed25519, ecx); MAKE_TEXT_ENCODER(ed448, ecx); MAKE_TEXT_ENCODER(x25519, ecx); MAKE_TEXT_ENCODER(x448, ecx); +# endif +#endif +#ifndef OPENSSL_NO_ML_KEM +MAKE_TEXT_ENCODER(ml_kem_512, ml_kem); +MAKE_TEXT_ENCODER(ml_kem_768, ml_kem); +MAKE_TEXT_ENCODER(ml_kem_1024, ml_kem); #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 + +#ifndef OPENSSL_NO_SLH_DSA +MAKE_TEXT_ENCODER(slh_dsa_sha2_128s, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_sha2_128f, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_sha2_192s, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_sha2_192f, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_sha2_256s, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_sha2_256f, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_shake_128s, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_shake_128f, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_shake_192s, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_shake_192f, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_shake_256s, slh_dsa); +MAKE_TEXT_ENCODER(slh_dsa_shake_256f, slh_dsa); +#endif |
