@@ -2100,69 +2100,99 @@ EVPKeyPointer EVPKeyPointer::NewRawPrivate(
21002100}
21012101
21022102#if OPENSSL_WITH_PQC
2103- EVPKeyPointer EVPKeyPointer::NewRawSeed (
2104- int id, const Buffer< const unsigned char >& data) {
2105- if (id == 0 ) return {} ;
2103+ namespace {
2104+ constexpr size_t kPqcMlDsaSeedSize = 32 ;
2105+ constexpr size_t kPqcMlKemSeedSize = 64 ;
21062106
2107- #ifdef OPENSSL_IS_BORINGSSL
2108- // BoringSSL exposes seed-based construction via EVP_PKEY_from_private_seed,
2109- // which needs an |EVP_PKEY_ALG*| rather than a NID.
2110- const EVP_PKEY_ALG* alg = nullptr ;
2107+ size_t GetPqcSeedSize (int id) {
21112108 switch (id) {
21122109 case EVP_PKEY_ML_DSA_44:
2113- alg = EVP_pkey_ml_dsa_44 ();
2114- break ;
21152110 case EVP_PKEY_ML_DSA_65:
2116- alg = EVP_pkey_ml_dsa_65 ();
2117- break ;
21182111 case EVP_PKEY_ML_DSA_87:
2119- alg = EVP_pkey_ml_dsa_87 ();
2120- break ;
2112+ return kPqcMlDsaSeedSize ;
2113+ #if OPENSSL_WITH_PQC_ML_KEM_512
2114+ case EVP_PKEY_ML_KEM_512:
2115+ #endif
21212116 case EVP_PKEY_ML_KEM_768:
2122- alg = EVP_pkey_ml_kem_768 ();
2123- break ;
21242117 case EVP_PKEY_ML_KEM_1024:
2125- alg = EVP_pkey_ml_kem_1024 ();
2126- break ;
2118+ return kPqcMlKemSeedSize ;
21272119 default :
2128- return {};
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 ();
21292139 }
2130- return EVPKeyPointer ( EVP_PKEY_from_private_seed (alg, data. data , data. len ));
2140+ }
21312141#else
2132- // ML-DSA and ML-KEM seeds use distinct OSSL_PARAM keys.
2133- const char * param_name;
2142+ const char * GetPqcSeedParamName (int id) {
21342143 switch (id) {
21352144 case EVP_PKEY_ML_DSA_44:
21362145 case EVP_PKEY_ML_DSA_65:
21372146 case EVP_PKEY_ML_DSA_87:
2138- param_name = OSSL_PKEY_PARAM_ML_DSA_SEED;
2139- break ;
2147+ return OSSL_PKEY_PARAM_ML_DSA_SEED;
21402148 case EVP_PKEY_ML_KEM_512:
21412149 case EVP_PKEY_ML_KEM_768:
21422150 case EVP_PKEY_ML_KEM_1024:
2143- param_name = OSSL_PKEY_PARAM_ML_KEM_SEED;
2144- break ;
2151+ return OSSL_PKEY_PARAM_ML_KEM_SEED;
21452152 default :
2146- return {} ;
2153+ unreachable () ;
21472154 }
2155+ }
2156+ #endif
21482157
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
21492164 OSSL_PARAM params[] = {
2150- OSSL_PARAM_construct_octet_string (
2151- param_name, const_cast <unsigned char *>(data.data ), data.len ),
2165+ OSSL_PARAM_construct_octet_string (GetPqcSeedParamName (id),
2166+ const_cast <unsigned char *>(data.data ),
2167+ data.len ),
21522168 OSSL_PARAM_END};
21532169
2154- EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id (id, nullptr );
2155- if (ctx == nullptr ) return {};
2170+ auto ctx = EVPKeyCtxPointer::NewFromID (id);
2171+ if (! ctx) return {};
21562172
21572173 EVP_PKEY* pkey = nullptr ;
2158- if (ctx == nullptr || EVP_PKEY_fromdata_init (ctx) <= 0 ||
2159- EVP_PKEY_fromdata (ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0 ) {
2160- 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 ) {
21612176 return {};
21622177 }
2163-
21642178 return EVPKeyPointer (pkey);
2165- #endif // OPENSSL_IS_BORINGSSL
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);
21662196}
21672197#endif
21682198
@@ -2290,62 +2320,14 @@ DataPointer EVPKeyPointer::rawPublicKey() const {
22902320DataPointer EVPKeyPointer::rawSeed () const {
22912321 if (!pkey_) return {};
22922322
2293- #ifdef OPENSSL_IS_BORINGSSL
2294- size_t seed_len;
2295- switch (id ()) {
2296- case EVP_PKEY_ML_DSA_44:
2297- case EVP_PKEY_ML_DSA_65:
2298- case EVP_PKEY_ML_DSA_87:
2299- seed_len = 32 ; // ML-DSA uses 32-byte seeds
2300- break ;
2301- case EVP_PKEY_ML_KEM_768:
2302- case EVP_PKEY_ML_KEM_1024:
2303- seed_len = 64 ; // ML-KEM uses 64-byte seeds
2304- break ;
2305- default :
2306- return {};
2307- }
2308-
2309- if (auto data = DataPointer::Alloc (seed_len)) {
2310- const Buffer<unsigned char > buf = data;
2311- size_t len = data.size ();
2312- if (EVP_PKEY_get_private_seed (get (), buf.data , &len) != 1 ) return {};
2313- return data;
2314- }
2315- return {};
2316- #else
2317- // Determine seed length and parameter name based on key type
2318- size_t seed_len;
2319- const char * param_name;
2320-
2321- switch (id ()) {
2322- case EVP_PKEY_ML_DSA_44:
2323- case EVP_PKEY_ML_DSA_65:
2324- case EVP_PKEY_ML_DSA_87:
2325- seed_len = 32 ; // ML-DSA uses 32-byte seeds
2326- param_name = OSSL_PKEY_PARAM_ML_DSA_SEED;
2327- break ;
2328- case EVP_PKEY_ML_KEM_512:
2329- case EVP_PKEY_ML_KEM_768:
2330- case EVP_PKEY_ML_KEM_1024:
2331- seed_len = 64 ; // ML-KEM uses 64-byte seeds
2332- param_name = OSSL_PKEY_PARAM_ML_KEM_SEED;
2333- break ;
2334- default :
2335- unreachable ();
2336- }
2323+ const size_t seed_len = GetPqcSeedSize (id ());
23372324
23382325 if (auto data = DataPointer::Alloc (seed_len)) {
23392326 const Buffer<unsigned char > buf = data;
2340- size_t len = data.size ();
2341-
2342- if (EVP_PKEY_get_octet_string_param (
2343- get (), param_name, buf.data , len, &seed_len) != 1 )
2344- return {};
2327+ if (!GetPqcSeed (get (), id (), buf)) return {};
23452328 return data;
23462329 }
23472330 return {};
2348- #endif // OPENSSL_IS_BORINGSSL
23492331}
23502332#endif
23512333
0 commit comments