From: slontis Date: Wed, 22 Jan 2025 23:26:51 +0000 (+1100) Subject: SLH-DSA: Remove legacy ASN1 method tables for SLH-DSA. Update to use X-Git-Tag: openssl-3.5.0-alpha1~181 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8f86a75fcff7d55d28240509be067200823fa8e4;p=thirdparty%2Fopenssl.git SLH-DSA: Remove legacy ASN1 method tables for SLH-DSA. Update to use custom encoders for SLH_DSA decode_der2key. Reviewed-by: Paul Dale Reviewed-by: Viktor Dukhovni Reviewed-by: Tim Hudson (Merged from https://github.com/openssl/openssl/pull/25882) --- diff --git a/crypto/asn1/standard_methods.h b/crypto/asn1/standard_methods.h index 2c3bd392049..4fe64014cfc 100644 --- a/crypto/asn1/standard_methods.h +++ b/crypto/asn1/standard_methods.h @@ -40,18 +40,4 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { #ifndef OPENSSL_NO_SM2 &ossl_sm2_asn1_meth, #endif -#ifndef OPENSSL_NO_SLH_DSA - &ossl_slh_dsa_sha2_128s_asn1_meth, - &ossl_slh_dsa_sha2_128f_asn1_meth, - &ossl_slh_dsa_sha2_192s_asn1_meth, - &ossl_slh_dsa_sha2_192f_asn1_meth, - &ossl_slh_dsa_sha2_256s_asn1_meth, - &ossl_slh_dsa_sha2_256f_asn1_meth, - &ossl_slh_dsa_shake_128s_asn1_meth, - &ossl_slh_dsa_shake_128f_asn1_meth, - &ossl_slh_dsa_shake_192s_asn1_meth, - &ossl_slh_dsa_shake_192f_asn1_meth, - &ossl_slh_dsa_shake_256s_asn1_meth, - &ossl_slh_dsa_shake_256f_asn1_meth, -#endif }; diff --git a/crypto/evp/p_lib.c b/crypto/evp/p_lib.c index f0bc5845b68..64ef8109831 100644 --- a/crypto/evp/p_lib.c +++ b/crypto/evp/p_lib.c @@ -43,7 +43,6 @@ #include "crypto/ec.h" #include "crypto/ecx.h" #include "crypto/rsa.h" -#include "crypto/slh_dsa.h" #ifndef FIPS_MODULE # include "crypto/asn1.h" # include "crypto/x509.h" @@ -944,17 +943,6 @@ IMPLEMENT_ECX_VARIANT(ED448) # endif /* OPENSSL_NO_ECX */ -# ifndef OPENSSL_NO_SLH_DSA -SLH_DSA_KEY *ossl_evp_pkey_get1_SLH_DSA_KEY(EVP_PKEY *pkey) -{ - SLH_DSA_KEY *ret = (SLH_DSA_KEY *)evp_pkey_get_legacy(pkey); - - if (ret != NULL) - ret = NULL; - return ret; -} -# endif /* OPENSSL_NO_SLH_DSA */ - # if !defined(OPENSSL_NO_DH) && !defined(OPENSSL_NO_DEPRECATED_3_0) int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *dhkey) diff --git a/crypto/slh_dsa/build.info b/crypto/slh_dsa/build.info index a123a051623..fe0e2527d8f 100644 --- a/crypto/slh_dsa/build.info +++ b/crypto/slh_dsa/build.info @@ -3,7 +3,7 @@ LIBS=../../libcrypto $COMMON=slh_adrs.c slh_dsa.c slh_dsa_hash_ctx.c slh_dsa_key.c slh_fors.c slh_hash.c \ slh_hypertree.c slh_params.c slh_wots.c slh_xmss.c -IF[{- !$disabled{'slh_dsa'} -}] - SOURCE[../../libcrypto]=$COMMON slh_dsa_backend.c slh_dsa_meth.c +IF[{- !$disabled{'slh-dsa'} -}] + SOURCE[../../libcrypto]=$COMMON SOURCE[../../providers/libfips.a]=$COMMON ENDIF diff --git a/crypto/slh_dsa/slh_dsa_backend.c b/crypto/slh_dsa/slh_dsa_backend.c deleted file mode 100644 index cd60963e897..00000000000 --- a/crypto/slh_dsa/slh_dsa_backend.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2024 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 - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include -#include -#include -#include -#include "slh_dsa_local.h" -#include "slh_dsa_key.h" - -SLH_DSA_KEY *ossl_slh_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8_info, - OSSL_LIB_CTX *lib_ctx, const char *propq) -{ - SLH_DSA_KEY *key = NULL; - const X509_ALGOR *alg; - const uint8_t *p; - int nid, p_len, alg_param_type = 0; - ASN1_OCTET_STRING *oct = NULL; - const char *alg_name = NULL; - - if (!PKCS8_pkey_get0(NULL, &p, &p_len, &alg, p8_info)) - return 0; - - X509_ALGOR_get0(NULL, &alg_param_type, NULL, alg); - if (alg_param_type != V_ASN1_UNDEF) - return 0; - - oct = d2i_ASN1_OCTET_STRING(NULL, &p, p_len); - if (oct == NULL) { - p = NULL; - p_len = 0; - } else { - p = ASN1_STRING_get0_data(oct); - p_len = ASN1_STRING_length(oct); - } - if (p == NULL) - goto err; - - nid = OBJ_obj2nid(alg->algorithm); - if (nid == NID_undef) - goto err; - alg_name = OBJ_nid2ln(nid); - if (alg_name == NULL) - goto err; - - key = ossl_slh_dsa_key_new(lib_ctx, propq, alg_name); - if (key == NULL - || !ossl_slh_dsa_set_priv(key, p, p_len)) - goto err; - ASN1_OCTET_STRING_free(oct); - return key; -err: - ossl_slh_dsa_key_free(key); - ASN1_OCTET_STRING_free(oct); - return NULL; -} diff --git a/crypto/slh_dsa/slh_dsa_key.c b/crypto/slh_dsa/slh_dsa_key.c index f6b8d9bb1c2..0fc157d566a 100644 --- a/crypto/slh_dsa/slh_dsa_key.c +++ b/crypto/slh_dsa/slh_dsa_key.c @@ -382,11 +382,6 @@ size_t ossl_slh_dsa_key_get_sig_len(const SLH_DSA_KEY *key) { return key->params->sig_len; } -void ossl_slh_dsa_key_set0_libctx(SLH_DSA_KEY *key, OSSL_LIB_CTX *lib_ctx) -{ - key->libctx = lib_ctx; -} - const char *ossl_slh_dsa_key_get_name(const SLH_DSA_KEY *key) { return key->params->alg; @@ -420,16 +415,18 @@ int ossl_slh_dsa_key_to_text(BIO *out, const SLH_DSA_KEY *key, int selection) ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER); return 0; } + name = ossl_slh_dsa_key_get_name(key); if (ossl_slh_dsa_key_get_pub(key) == NULL) { /* Regardless of the |selection|, there must be a public key */ - ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PUBLIC_KEY); + ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_KEY, + "no %s key material available", name); return 0; } - name = ossl_slh_dsa_key_get_name(key); if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) { if (ossl_slh_dsa_key_get_priv(key) == NULL) { - ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); + ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_KEY, + "no %s key material available", name); return 0; } if (BIO_printf(out, "%s Private-Key:\n", name) <= 0) diff --git a/crypto/slh_dsa/slh_dsa_meth.c b/crypto/slh_dsa/slh_dsa_meth.c deleted file mode 100644 index e397b68b09d..00000000000 --- a/crypto/slh_dsa/slh_dsa_meth.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2024 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 - * in the file LICENSE in the source distribution or at - * https://www.openssl.org/source/license.html - */ - -#include "internal/deprecated.h" /* EVP_PKEY_assign() */ - -#include "internal/cryptlib.h" -#include "crypto/asn1.h" -#include "crypto/evp.h" -#include "crypto/x509.h" -#include "crypto/slh_dsa.h" - -/* Minimal ASN1 method table to support PUB_KEY decoding */ -#define IMPLEMENT_PKEY_ASN1_METHOD(alg, name, PKEY_NAME) \ - const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_##name##_asn1_meth = \ - { \ - EVP_PKEY_SLH_DSA_##PKEY_NAME, EVP_PKEY_SLH_DSA_##PKEY_NAME, \ - 0, \ - alg, \ - "OpenSSL " alg " algorithm", \ - slh_dsa_pub_decode, NULL, NULL, NULL, \ - NULL, NULL, NULL, \ - NULL, NULL, NULL, \ - NULL, NULL, NULL, NULL, NULL, NULL, \ - NULL, \ - slh_dsa_free, \ - } - -static SLH_DSA_KEY *ossl_slh_dsa_key_create(const X509_ALGOR *palg, - const unsigned char *p, int p_len, - int id, int public, - OSSL_LIB_CTX *libctx, - const char *propq) -{ - int ret = 0; - SLH_DSA_KEY *key = NULL; - - if (p == NULL) - return 0; - if (palg != NULL) { - int ptype; - - /* Algorithm parameters must be absent */ - X509_ALGOR_get0(NULL, &ptype, NULL, palg); - if (ptype != V_ASN1_UNDEF) - return 0; - if (id == EVP_PKEY_NONE) - id = OBJ_obj2nid(palg->algorithm); - else if (id != OBJ_obj2nid(palg->algorithm)) - return 0; - } - if (id == EVP_PKEY_NONE) - return 0; - - key = ossl_slh_dsa_key_new(libctx, propq, OBJ_nid2ln(id)); - if (key == NULL) - return 0; - if (public) - ret = ossl_slh_dsa_set_pub(key, p, p_len); - else - ret = ossl_slh_dsa_set_priv(key, p, p_len); - - if (ret == 0) { - ossl_slh_dsa_key_free(key); - key = NULL; - } - return key; -} - -static int slh_dsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) -{ - const unsigned char *p; - int pklen; - X509_ALGOR *palg; - SLH_DSA_KEY *key; - OSSL_LIB_CTX *libctx; - const char *propq; - int ret = 0; - - if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) - return 0; - ossl_x509_PUBKEY_get0_libctx(&libctx, &propq, pubkey); - key = ossl_slh_dsa_key_create(palg, p, pklen, pkey->ameth->pkey_id, 1, - libctx, propq); - if (key != NULL) { - ret = 1; - EVP_PKEY_assign(pkey, pkey->ameth->pkey_id, key); - } - return ret; -} - -static void slh_dsa_free(EVP_PKEY *pkey) -{ - ossl_slh_dsa_key_free(pkey->pkey.slh_dsa); -} - -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-128s", sha2_128s, SHA2_128S); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-128f", sha2_128f, SHA2_128F); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-192s", sha2_192s, SHA2_192S); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-192f", sha2_192f, SHA2_192F); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-256s", sha2_256s, SHA2_256S); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-256f", sha2_256f, SHA2_256F); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-128s", shake_128s, SHAKE_128S); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-128f", shake_128f, SHAKE_128F); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-192s", shake_192s, SHAKE_192S); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-192f", shake_192f, SHAKE_192F); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-256s", shake_256s, SHAKE_256S); -IMPLEMENT_PKEY_ASN1_METHOD("SLH-DSA-SHA2-256f", shake_256f, SHAKE_256F); diff --git a/crypto/x509/x_pubkey.c b/crypto/x509/x_pubkey.c index 4f0c785a783..53639b2bfab 100644 --- a/crypto/x509/x_pubkey.c +++ b/crypto/x509/x_pubkey.c @@ -20,7 +20,6 @@ #include #include "crypto/asn1.h" #include "crypto/evp.h" -#include "crypto/slh_dsa.h" #include "crypto/x509.h" #include #include @@ -1008,79 +1007,6 @@ int ossl_i2d_X448_PUBKEY(const ECX_KEY *a, unsigned char **pp) # endif /* OPENSSL_NO_ECX */ #endif -#ifndef OPENSSL_NO_SLH_DSA - -static SLH_DSA_KEY *d2i_SLH_DSA_PUBKEY(SLH_DSA_KEY **a, - const unsigned char **pp, - long length, int key_type) -{ - EVP_PKEY *pkey; - SLH_DSA_KEY *key = NULL; - const unsigned char *q; - - q = *pp; - pkey = ossl_d2i_PUBKEY_legacy(NULL, &q, length); - if (pkey == NULL) - return NULL; - if (EVP_PKEY_get_id(pkey) == key_type) - key = ossl_evp_pkey_get1_SLH_DSA_KEY(pkey); - EVP_PKEY_free(pkey); - if (key == NULL) - return NULL; - *pp = q; - if (a != NULL) { - ossl_slh_dsa_key_free(*a); - *a = key; - } - return key; -} - -static int i2d_SLH_DSA_PUBKEY(const SLH_DSA_KEY *a, unsigned char **pp, - int key_type) -{ - EVP_PKEY *pktmp; - int ret; - - if (a == NULL) - return 0; - if ((pktmp = EVP_PKEY_new()) == NULL) { - ERR_raise(ERR_LIB_ASN1, ERR_R_EVP_LIB); - return -1; - } - (void)EVP_PKEY_assign(pktmp, key_type, (SLH_DSA_KEY *)a); - ret = i2d_PUBKEY(pktmp, pp); - pktmp->pkey.ptr = NULL; - EVP_PKEY_free(pktmp); - return ret; -} - -# define IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(alg) \ - int ossl_i2d_SLH_DSA_##alg##_PUBKEY(const SLH_DSA_KEY *a, unsigned char **pp)\ - { \ - return i2d_SLH_DSA_PUBKEY(a, pp, EVP_PKEY_SLH_DSA_##alg); \ - } \ - SLH_DSA_KEY *ossl_d2i_SLH_DSA_##alg##_PUBKEY(SLH_DSA_KEY **a, \ - const unsigned char **pp, \ - long length) \ - { \ - return d2i_SLH_DSA_PUBKEY(a, pp, length, EVP_PKEY_SLH_DSA_##alg); \ - } - -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHA2_128S) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHA2_128F) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHA2_192S) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHA2_192F) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHA2_256S) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHA2_256F) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHAKE_128S) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHAKE_128F) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHAKE_192S) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHAKE_192F) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHAKE_256S) -IMPLEMENT_SLH_DSA_PUBKEY_D2I_I2D(SHAKE_256F) - -#endif /* OPENSSL_NO_SLH_DSA */ - void X509_PUBKEY_set0_public_key(X509_PUBKEY *pub, unsigned char *penc, int penclen) { diff --git a/include/crypto/asn1.h b/include/crypto/asn1.h index ea833b9283e..8461c1be8d2 100644 --- a/include/crypto/asn1.h +++ b/include/crypto/asn1.h @@ -103,19 +103,6 @@ extern const EVP_PKEY_ASN1_METHOD ossl_sm2_asn1_meth; extern const EVP_PKEY_ASN1_METHOD ossl_rsa_asn1_meths[2]; extern const EVP_PKEY_ASN1_METHOD ossl_rsa_pss_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_sha2_128s_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_sha2_128f_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_sha2_192s_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_sha2_192f_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_sha2_256s_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_sha2_256f_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_shake_128s_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_shake_128f_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_shake_192s_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_shake_192f_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_shake_256s_asn1_meth; -extern const EVP_PKEY_ASN1_METHOD ossl_slh_dsa_shake_256f_asn1_meth; - /* * These are used internally in the ASN1_OBJECT to keep track of whether the * names and data need to be free()ed diff --git a/include/crypto/evp.h b/include/crypto/evp.h index 5e2f8a148ec..861447f557b 100644 --- a/include/crypto/evp.h +++ b/include/crypto/evp.h @@ -15,7 +15,6 @@ # include # include "internal/refcount.h" # include "crypto/ecx.h" -# include "crypto/slh_dsa.h" /* * Default PKCS5 PBE KDF salt lengths @@ -664,9 +663,6 @@ union legacy_pkey_st { ECX_KEY *ecx; /* X25519, X448, Ed25519, Ed448 */ # endif # endif -# ifndef OPENSSL_NO_SLH_DSA - SLH_DSA_KEY *slh_dsa; /* SLH_DSA_* */ -# endif }; struct evp_pkey_st { diff --git a/include/crypto/slh_dsa.h b/include/crypto/slh_dsa.h index 3b6c59d640e..c6f1eb8c82f 100644 --- a/include/crypto/slh_dsa.h +++ b/include/crypto/slh_dsa.h @@ -20,6 +20,7 @@ # define SLH_DSA_MAX_CONTEXT_STRING_LEN 255 typedef struct slh_dsa_hash_ctx_st SLH_DSA_HASH_CTX; +typedef struct slh_dsa_key_st SLH_DSA_KEY; __owur SLH_DSA_KEY *ossl_slh_dsa_key_new(OSSL_LIB_CTX *libctx, const char *propq, const char *alg); @@ -46,12 +47,6 @@ __owur size_t ossl_slh_dsa_key_get_n(const SLH_DSA_KEY *key); __owur size_t ossl_slh_dsa_key_get_sig_len(const SLH_DSA_KEY *key); __owur const char *ossl_slh_dsa_key_get_name(const SLH_DSA_KEY *key); __owur int ossl_slh_dsa_key_type_matches(const SLH_DSA_KEY *key, const char *alg); -__owur int ossl_slh_dsa_key_to_text(BIO *out, const SLH_DSA_KEY *key, int selection); -void ossl_slh_dsa_key_set0_libctx(SLH_DSA_KEY *key, OSSL_LIB_CTX *lib_ctx); -SLH_DSA_KEY *ossl_slh_dsa_key_from_pkcs8(const PKCS8_PRIV_KEY_INFO *p8inf, - OSSL_LIB_CTX *libctx, const char *propq); -SLH_DSA_KEY *ossl_evp_pkey_get1_SLH_DSA_KEY(EVP_PKEY *pkey); - __owur SLH_DSA_HASH_CTX *ossl_slh_dsa_hash_ctx_new(const SLH_DSA_KEY *key); void ossl_slh_dsa_hash_ctx_free(SLH_DSA_HASH_CTX *ctx); diff --git a/include/crypto/types.h b/include/crypto/types.h index 5dbcd900508..43f04fd5eab 100644 --- a/include/crypto/types.h +++ b/include/crypto/types.h @@ -28,9 +28,6 @@ typedef struct dsa_st DSA; # ifndef OPENSSL_NO_EC typedef struct ecx_key_st ECX_KEY; # endif -# ifndef OPENSSL_NO_SLH_DSA -typedef struct slh_dsa_key_st SLH_DSA_KEY; -# endif typedef struct prov_skey_st PROV_SKEY; diff --git a/providers/implementations/encode_decode/decode_der2key.c b/providers/implementations/encode_decode/decode_der2key.c index 85f6bfc5dc4..7fe74585b47 100644 --- a/providers/implementations/encode_decode/decode_der2key.c +++ b/providers/implementations/encode_decode/decode_der2key.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "internal/cryptlib.h" /* ossl_assert() */ #include "crypto/dh.h" #include "crypto/dsa.h" @@ -44,6 +45,26 @@ #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); @@ -621,21 +642,125 @@ ml_kem_d2i_PUBKEY(const uint8_t **der, long der_len, #endif - #ifndef OPENSSL_NO_SLH_DSA - -/* SLH_DSA only implements PKCS#8 and SubjectPublicKeyInfo */ - -static void *slh_dsa_d2i_PKCS8(void **key, const unsigned char **der, long der_len, - struct der2key_ctx_st *ctx) +static void * +slh_dsa_d2i_PKCS8(const uint8_t **der, long der_len, struct der2key_ctx_st *ctx) { - return der2key_decode_p8(der, der_len, ctx, - (key_from_pkcs8_t *)ossl_slh_dsa_key_from_pkcs8); + 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 void slh_dsa_key_adjust(void *key, struct der2key_ctx_st *ctx) +static ossl_inline void *slh_dsa_d2i_PUBKEY(const uint8_t **der, long der_len, + struct der2key_ctx_st *ctx) { - ossl_slh_dsa_key_set0_libctx(key, PROV_LIBCTX_OF(ctx->provctx)); + 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 large 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 @@ -643,120 +768,120 @@ static void slh_dsa_key_adjust(void *key, struct der2key_ctx_st *ctx) # 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_128S_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_128F_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_192S_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_192F_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_256S_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHA2_256F_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_128S_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_128F_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_192S_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_192F_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_256S_PUBKEY +# 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 slh_dsa_key_adjust +# 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 (d2i_of_void *)ossl_d2i_SLH_DSA_SHAKE_256F_PUBKEY +# 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 slh_dsa_key_adjust +# define slh_dsa_shake_256f_adjust NULL #endif /* OPENSSL_NO_SLH_DSA */ /* ---------------------------------------------------------------------- */ diff --git a/providers/implementations/encode_decode/encode_key2any.c b/providers/implementations/encode_decode/encode_key2any.c index 9c0f2176f4e..42fd74dc653 100644 --- a/providers/implementations/encode_decode/encode_key2any.c +++ b/providers/implementations/encode_decode/encode_key2any.c @@ -1048,27 +1048,19 @@ static int slh_dsa_spki_pub_to_der(const void *vkey, unsigned char **pder) static int slh_dsa_pki_priv_to_der(const void *vkey, unsigned char **pder) { const SLH_DSA_KEY *key = vkey; - const uint8_t *priv; - ASN1_OCTET_STRING oct; - size_t key_blob_len; + size_t len; - if (key == NULL - || (priv = ossl_slh_dsa_key_get_priv(key))== NULL) { + 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); - oct.data = (uint8_t *)priv; - oct.length = ossl_slh_dsa_key_get_priv_len(key); - oct.flags = 0; - - key_blob_len = i2d_ASN1_OCTET_STRING(&oct, pder); - if (key_blob_len < 0) { - ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); + if (pder != NULL + && ((*pder = OPENSSL_memdup(ossl_slh_dsa_key_get_priv(key), len)) == NULL)) return 0; - } - return key_blob_len; + return len; } # define slh_dsa_epki_priv_to_der slh_dsa_pki_priv_to_der @@ -1111,7 +1103,7 @@ static int slh_dsa_pki_priv_to_der(const void *vkey, unsigned char **pder) # 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 +#endif /* OPENSSL_NO_SLH_DSA */ /* ---------------------------------------------------------------------- */ diff --git a/providers/implementations/keymgmt/slh_dsa_kmgmt.c b/providers/implementations/keymgmt/slh_dsa_kmgmt.c index 564e5dba5d7..198622a7005 100644 --- a/providers/implementations/keymgmt/slh_dsa_kmgmt.c +++ b/providers/implementations/keymgmt/slh_dsa_kmgmt.c @@ -206,9 +206,6 @@ static int slh_dsa_export(void *keydata, int selection, OSSL_CALLBACK *param_cb, if ((selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0) return 0; - /* The public key is required for private keys */ - if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0) - return 0; tmpl = OSSL_PARAM_BLD_new(); if (tmpl == NULL)