@@ -34,9 +34,13 @@ constexpr static PQCMapping pqc_mappings[] = {
3434 {" ML-DSA-44" , EVP_PKEY_ML_DSA_44},
3535 {" ML-DSA-65" , EVP_PKEY_ML_DSA_65},
3636 {" ML-DSA-87" , EVP_PKEY_ML_DSA_87},
37- {" ML-KEM-512" , EVP_PKEY_ML_KEM_512},
3837 {" ML-KEM-768" , EVP_PKEY_ML_KEM_768},
3938 {" ML-KEM-1024" , EVP_PKEY_ML_KEM_1024},
39+
40+ #if OPENSSL_WITH_PQC_ML_KEM_512
41+ {" ML-KEM-512" , EVP_PKEY_ML_KEM_512},
42+ #endif
43+ #if OPENSSL_WITH_PQC_SLH_DSA
4044 {" SLH-DSA-SHA2-128f" , EVP_PKEY_SLH_DSA_SHA2_128F},
4145 {" SLH-DSA-SHA2-128s" , EVP_PKEY_SLH_DSA_SHA2_128S},
4246 {" SLH-DSA-SHA2-192f" , EVP_PKEY_SLH_DSA_SHA2_192F},
@@ -49,6 +53,7 @@ constexpr static PQCMapping pqc_mappings[] = {
4953 {" SLH-DSA-SHAKE-192s" , EVP_PKEY_SLH_DSA_SHAKE_192S},
5054 {" SLH-DSA-SHAKE-256f" , EVP_PKEY_SLH_DSA_SHAKE_256F},
5155 {" SLH-DSA-SHAKE-256s" , EVP_PKEY_SLH_DSA_SHAKE_256S},
56+ #endif
5257};
5358
5459#endif
@@ -2095,27 +2100,99 @@ EVPKeyPointer EVPKeyPointer::NewRawPrivate(
20952100}
20962101
20972102#if OPENSSL_WITH_PQC
2098- EVPKeyPointer EVPKeyPointer::NewRawSeed (
2099- int id, const Buffer<const unsigned char >& data) {
2100- if (id == 0 ) return {};
2103+ namespace {
2104+ constexpr size_t kPqcMlDsaSeedSize = 32 ;
2105+ constexpr size_t kPqcMlKemSeedSize = 64 ;
2106+
2107+ size_t GetPqcSeedSize (int id) {
2108+ switch (id) {
2109+ case EVP_PKEY_ML_DSA_44:
2110+ case EVP_PKEY_ML_DSA_65:
2111+ case EVP_PKEY_ML_DSA_87:
2112+ return kPqcMlDsaSeedSize ;
2113+ #if OPENSSL_WITH_PQC_ML_KEM_512
2114+ case EVP_PKEY_ML_KEM_512:
2115+ #endif
2116+ case EVP_PKEY_ML_KEM_768:
2117+ case EVP_PKEY_ML_KEM_1024:
2118+ return kPqcMlKemSeedSize ;
2119+ default :
2120+ unreachable ();
2121+ }
2122+ }
2123+
2124+ #if OPENSSL_WITH_BORINGSSL_PQC
2125+ const EVP_PKEY_ALG* GetPqcSeedAlg (int id) {
2126+ switch (id) {
2127+ case EVP_PKEY_ML_DSA_44:
2128+ return EVP_pkey_ml_dsa_44 ();
2129+ case EVP_PKEY_ML_DSA_65:
2130+ return EVP_pkey_ml_dsa_65 ();
2131+ case EVP_PKEY_ML_DSA_87:
2132+ return EVP_pkey_ml_dsa_87 ();
2133+ case EVP_PKEY_ML_KEM_768:
2134+ return EVP_pkey_ml_kem_768 ();
2135+ case EVP_PKEY_ML_KEM_1024:
2136+ return EVP_pkey_ml_kem_1024 ();
2137+ default :
2138+ unreachable ();
2139+ }
2140+ }
2141+ #else
2142+ const char * GetPqcSeedParamName (int id) {
2143+ switch (id) {
2144+ case EVP_PKEY_ML_DSA_44:
2145+ case EVP_PKEY_ML_DSA_65:
2146+ case EVP_PKEY_ML_DSA_87:
2147+ return OSSL_PKEY_PARAM_ML_DSA_SEED;
2148+ case EVP_PKEY_ML_KEM_512:
2149+ case EVP_PKEY_ML_KEM_768:
2150+ case EVP_PKEY_ML_KEM_1024:
2151+ return OSSL_PKEY_PARAM_ML_KEM_SEED;
2152+ default :
2153+ unreachable ();
2154+ }
2155+ }
2156+ #endif
21012157
2158+ EVPKeyPointer NewPqcKeyFromSeed (int id,
2159+ const Buffer<const unsigned char >& data) {
2160+ #if OPENSSL_WITH_BORINGSSL_PQC
2161+ return EVPKeyPointer (
2162+ EVP_PKEY_from_private_seed (GetPqcSeedAlg (id), data.data , data.len ));
2163+ #else
21022164 OSSL_PARAM params[] = {
2103- OSSL_PARAM_construct_octet_string (OSSL_PKEY_PARAM_ML_DSA_SEED ,
2165+ OSSL_PARAM_construct_octet_string (GetPqcSeedParamName (id) ,
21042166 const_cast <unsigned char *>(data.data ),
21052167 data.len ),
21062168 OSSL_PARAM_END};
21072169
2108- EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id (id, nullptr );
2109- if (ctx == nullptr ) return {};
2170+ auto ctx = EVPKeyCtxPointer::NewFromID (id);
2171+ if (! ctx) return {};
21102172
21112173 EVP_PKEY* pkey = nullptr ;
2112- if (ctx == nullptr || EVP_PKEY_fromdata_init (ctx) <= 0 ||
2113- EVP_PKEY_fromdata (ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0 ) {
2114- EVP_PKEY_CTX_free (ctx);
2174+ if (EVP_PKEY_fromdata_init (ctx.get ()) <= 0 ||
2175+ EVP_PKEY_fromdata (ctx.get (), &pkey, EVP_PKEY_KEYPAIR, params) <= 0 ) {
21152176 return {};
21162177 }
2117-
21182178 return EVPKeyPointer (pkey);
2179+ #endif
2180+ }
2181+
2182+ bool GetPqcSeed (EVP_PKEY* pkey, int id, const Buffer<unsigned char >& out) {
2183+ size_t len = out.len ;
2184+ #if OPENSSL_WITH_BORINGSSL_PQC
2185+ return EVP_PKEY_get_private_seed (pkey, out.data , &len) == 1 ;
2186+ #else
2187+ return EVP_PKEY_get_octet_string_param (
2188+ pkey, GetPqcSeedParamName (id), out.data , out.len , &len) == 1 ;
2189+ #endif
2190+ }
2191+ } // namespace
2192+
2193+ EVPKeyPointer EVPKeyPointer::NewRawSeed (
2194+ int id, const Buffer<const unsigned char >& data) {
2195+ return NewPqcKeyFromSeed (id, data);
21192196}
21202197#endif
21212198
@@ -2165,7 +2242,7 @@ EVP_PKEY* EVPKeyPointer::release() {
21652242int EVPKeyPointer::id (const EVP_PKEY* key) {
21662243 if (key == nullptr ) return 0 ;
21672244 int type = EVP_PKEY_id (key);
2168- #if OPENSSL_WITH_PQC
2245+ #if OPENSSL_WITH_OPENSSL_PQC
21692246 // EVP_PKEY_id returns -1 when EVP_PKEY_* is only implemented in a provider
21702247 // which is the case for all post-quantum NIST algorithms
21712248 // one suggested way would be to use a chain of `EVP_PKEY_is_a`
@@ -2243,34 +2320,11 @@ DataPointer EVPKeyPointer::rawPublicKey() const {
22432320DataPointer EVPKeyPointer::rawSeed () const {
22442321 if (!pkey_) return {};
22452322
2246- // Determine seed length and parameter name based on key type
2247- size_t seed_len;
2248- const char * param_name;
2249-
2250- switch (id ()) {
2251- case EVP_PKEY_ML_DSA_44:
2252- case EVP_PKEY_ML_DSA_65:
2253- case EVP_PKEY_ML_DSA_87:
2254- seed_len = 32 ; // ML-DSA uses 32-byte seeds
2255- param_name = OSSL_PKEY_PARAM_ML_DSA_SEED;
2256- break ;
2257- case EVP_PKEY_ML_KEM_512:
2258- case EVP_PKEY_ML_KEM_768:
2259- case EVP_PKEY_ML_KEM_1024:
2260- seed_len = 64 ; // ML-KEM uses 64-byte seeds
2261- param_name = OSSL_PKEY_PARAM_ML_KEM_SEED;
2262- break ;
2263- default :
2264- unreachable ();
2265- }
2323+ const size_t seed_len = GetPqcSeedSize (id ());
22662324
22672325 if (auto data = DataPointer::Alloc (seed_len)) {
22682326 const Buffer<unsigned char > buf = data;
2269- size_t len = data.size ();
2270-
2271- if (EVP_PKEY_get_octet_string_param (
2272- get (), param_name, buf.data , len, &seed_len) != 1 )
2273- return {};
2327+ if (!GetPqcSeed (get (), id (), buf)) return {};
22742328 return data;
22752329 }
22762330 return {};
@@ -2312,6 +2366,7 @@ EVPKeyPointer::operator const EC_KEY*() const {
23122366}
23132367
23142368namespace {
2369+
23152370EVPKeyPointer::ParseKeyResult TryParsePublicKeyInner (const BIOPointer& bp,
23162371 const char * name,
23172372 auto && parse) {
@@ -2739,6 +2794,7 @@ bool EVPKeyPointer::isOneShotVariant() const {
27392794 case EVP_PKEY_ML_DSA_44:
27402795 case EVP_PKEY_ML_DSA_65:
27412796 case EVP_PKEY_ML_DSA_87:
2797+ #if OPENSSL_WITH_PQC_SLH_DSA
27422798 case EVP_PKEY_SLH_DSA_SHA2_128F:
27432799 case EVP_PKEY_SLH_DSA_SHA2_128S:
27442800 case EVP_PKEY_SLH_DSA_SHA2_192F:
@@ -2751,6 +2807,7 @@ bool EVPKeyPointer::isOneShotVariant() const {
27512807 case EVP_PKEY_SLH_DSA_SHAKE_192S:
27522808 case EVP_PKEY_SLH_DSA_SHAKE_256F:
27532809 case EVP_PKEY_SLH_DSA_SHAKE_256S:
2810+ #endif
27542811#endif
27552812 return true ;
27562813 default :
@@ -4401,7 +4458,17 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::signInitWithContext(
44014458 const EVPKeyPointer& key,
44024459 const Digest& digest,
44034460 const Buffer<const unsigned char >& context_string) {
4404- #ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
4461+ #ifdef OPENSSL_IS_BORINGSSL
4462+ EVP_PKEY_CTX* ctx = nullptr ;
4463+ if (!EVP_DigestSignInit (ctx_.get (), &ctx, digest, nullptr , key.get ())) {
4464+ return std::nullopt ;
4465+ }
4466+ if (EVP_PKEY_CTX_set1_signature_context_string (
4467+ ctx, context_string.data , context_string.len ) <= 0 ) {
4468+ return std::nullopt ;
4469+ }
4470+ return ctx;
4471+ #elif defined(OSSL_SIGNATURE_PARAM_CONTEXT_STRING)
44054472 EVP_PKEY_CTX* ctx = nullptr ;
44064473
44074474#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
@@ -4446,7 +4513,17 @@ std::optional<EVP_PKEY_CTX*> EVPMDCtxPointer::verifyInitWithContext(
44464513 const EVPKeyPointer& key,
44474514 const Digest& digest,
44484515 const Buffer<const unsigned char >& context_string) {
4449- #ifdef OSSL_SIGNATURE_PARAM_CONTEXT_STRING
4516+ #ifdef OPENSSL_IS_BORINGSSL
4517+ EVP_PKEY_CTX* ctx = nullptr ;
4518+ if (!EVP_DigestVerifyInit (ctx_.get (), &ctx, digest, nullptr , key.get ())) {
4519+ return std::nullopt ;
4520+ }
4521+ if (EVP_PKEY_CTX_set1_signature_context_string (
4522+ ctx, context_string.data , context_string.len ) <= 0 ) {
4523+ return std::nullopt ;
4524+ }
4525+ return ctx;
4526+ #elif defined(OSSL_SIGNATURE_PARAM_CONTEXT_STRING)
44504527 EVP_PKEY_CTX* ctx = nullptr ;
44514528
44524529#ifdef OSSL_SIGNATURE_PARAM_INSTANCE
0 commit comments