@@ -1897,6 +1897,31 @@ EVPKeyPointer EVPKeyPointer::NewRawPrivate(
18971897 EVP_PKEY_new_raw_private_key (id, nullptr , data.data , data.len ));
18981898}
18991899
1900+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
1901+ EVPKeyPointer EVPKeyPointer::NewRawSeed (
1902+ int id, const Buffer<const unsigned char >& data) {
1903+ if (id == 0 ) return {};
1904+
1905+ OSSL_PARAM params[] = {
1906+ OSSL_PARAM_construct_octet_string (OSSL_PKEY_PARAM_ML_DSA_SEED,
1907+ const_cast <unsigned char *>(data.data ),
1908+ data.len ),
1909+ OSSL_PARAM_END};
1910+
1911+ EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id (id, nullptr );
1912+ if (ctx == nullptr ) return {};
1913+
1914+ EVP_PKEY* pkey = nullptr ;
1915+ if (ctx == nullptr || EVP_PKEY_fromdata_init (ctx) <= 0 ||
1916+ EVP_PKEY_fromdata (ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0 ) {
1917+ EVP_PKEY_CTX_free (ctx);
1918+ return {};
1919+ }
1920+
1921+ return EVPKeyPointer (pkey);
1922+ }
1923+ #endif
1924+
19001925EVPKeyPointer EVPKeyPointer::NewDH (DHPointer&& dh) {
19011926 if (!dh) return {};
19021927 auto key = New ();
@@ -1942,7 +1967,16 @@ EVP_PKEY* EVPKeyPointer::release() {
19421967
19431968int EVPKeyPointer::id (const EVP_PKEY* key) {
19441969 if (key == nullptr ) return 0 ;
1945- return EVP_PKEY_id (key);
1970+ int type = EVP_PKEY_id (key);
1971+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
1972+ // https://github.com/openssl/openssl/issues/27738#issuecomment-3013215870
1973+ if (type == -1 ) {
1974+ if (EVP_PKEY_is_a (key, " ML-DSA-44" )) return EVP_PKEY_ML_DSA_44;
1975+ if (EVP_PKEY_is_a (key, " ML-DSA-65" )) return EVP_PKEY_ML_DSA_65;
1976+ if (EVP_PKEY_is_a (key, " ML-DSA-87" )) return EVP_PKEY_ML_DSA_87;
1977+ }
1978+ #endif
1979+ return type;
19461980}
19471981
19481982int EVPKeyPointer::base_id (const EVP_PKEY* key) {
@@ -1998,6 +2032,31 @@ DataPointer EVPKeyPointer::rawPublicKey() const {
19982032 return {};
19992033}
20002034
2035+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2036+ DataPointer EVPKeyPointer::rawSeed () const {
2037+ if (!pkey_) return {};
2038+ switch (id ()) {
2039+ case EVP_PKEY_ML_DSA_44:
2040+ case EVP_PKEY_ML_DSA_65:
2041+ case EVP_PKEY_ML_DSA_87:
2042+ break ;
2043+ default :
2044+ unreachable ();
2045+ }
2046+
2047+ size_t seed_len = 32 ;
2048+ if (auto data = DataPointer::Alloc (seed_len)) {
2049+ const Buffer<unsigned char > buf = data;
2050+ size_t len = data.size ();
2051+ if (EVP_PKEY_get_octet_string_param (
2052+ get (), OSSL_PKEY_PARAM_ML_DSA_SEED, buf.data , len, &seed_len) != 1 )
2053+ return {};
2054+ return data;
2055+ }
2056+ return {};
2057+ }
2058+ #endif
2059+
20012060DataPointer EVPKeyPointer::rawPrivateKey () const {
20022061 if (!pkey_) return {};
20032062 if (auto data = DataPointer::Alloc (rawPrivateKeySize ())) {
@@ -2453,7 +2512,18 @@ bool EVPKeyPointer::isRsaVariant() const {
24532512bool EVPKeyPointer::isOneShotVariant () const {
24542513 if (!pkey_) return false ;
24552514 int type = id ();
2456- return type == EVP_PKEY_ED25519 || type == EVP_PKEY_ED448;
2515+ switch (type) {
2516+ case EVP_PKEY_ED25519:
2517+ case EVP_PKEY_ED448:
2518+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2519+ case EVP_PKEY_ML_DSA_44:
2520+ case EVP_PKEY_ML_DSA_65:
2521+ case EVP_PKEY_ML_DSA_87:
2522+ #endif
2523+ return true ;
2524+ default :
2525+ return false ;
2526+ }
24572527}
24582528
24592529bool EVPKeyPointer::isSigVariant () const {
0 commit comments