@@ -2035,6 +2035,31 @@ EVPKeyPointer EVPKeyPointer::NewRawPrivate(
20352035 EVP_PKEY_new_raw_private_key (id, nullptr , data.data , data.len ));
20362036}
20372037
2038+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2039+ EVPKeyPointer EVPKeyPointer::NewRawSeed (
2040+ int id, const Buffer<const unsigned char >& data) {
2041+ if (id == 0 ) return {};
2042+
2043+ OSSL_PARAM params[] = {
2044+ OSSL_PARAM_construct_octet_string (OSSL_PKEY_PARAM_ML_DSA_SEED,
2045+ const_cast <unsigned char *>(data.data ),
2046+ data.len ),
2047+ OSSL_PARAM_END};
2048+
2049+ EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id (id, nullptr );
2050+ if (ctx == nullptr ) return {};
2051+
2052+ EVP_PKEY* pkey = nullptr ;
2053+ if (ctx == nullptr || EVP_PKEY_fromdata_init (ctx) <= 0 ||
2054+ EVP_PKEY_fromdata (ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0 ) {
2055+ EVP_PKEY_CTX_free (ctx);
2056+ return {};
2057+ }
2058+
2059+ return EVPKeyPointer (pkey);
2060+ }
2061+ #endif
2062+
20382063EVPKeyPointer EVPKeyPointer::NewDH (DHPointer&& dh) {
20392064#ifndef NCRYPTO_NO_EVP_DH
20402065 if (!dh) return {};
@@ -2092,7 +2117,16 @@ EVP_PKEY* EVPKeyPointer::release() {
20922117
20932118int EVPKeyPointer::id (const EVP_PKEY* key) {
20942119 if (key == nullptr ) return 0 ;
2095- return EVP_PKEY_id (key);
2120+ int type = EVP_PKEY_id (key);
2121+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2122+ // https://github.com/openssl/openssl/issues/27738#issuecomment-3013215870
2123+ if (type == -1 ) {
2124+ if (EVP_PKEY_is_a (key, " ML-DSA-44" )) return EVP_PKEY_ML_DSA_44;
2125+ if (EVP_PKEY_is_a (key, " ML-DSA-65" )) return EVP_PKEY_ML_DSA_65;
2126+ if (EVP_PKEY_is_a (key, " ML-DSA-87" )) return EVP_PKEY_ML_DSA_87;
2127+ }
2128+ #endif
2129+ return type;
20962130}
20972131
20982132int EVPKeyPointer::base_id (const EVP_PKEY* key) {
@@ -2148,6 +2182,31 @@ DataPointer EVPKeyPointer::rawPublicKey() const {
21482182 return {};
21492183}
21502184
2185+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2186+ DataPointer EVPKeyPointer::rawSeed () const {
2187+ if (!pkey_) return {};
2188+ switch (id ()) {
2189+ case EVP_PKEY_ML_DSA_44:
2190+ case EVP_PKEY_ML_DSA_65:
2191+ case EVP_PKEY_ML_DSA_87:
2192+ break ;
2193+ default :
2194+ unreachable ();
2195+ }
2196+
2197+ size_t seed_len = 32 ;
2198+ if (auto data = DataPointer::Alloc (seed_len)) {
2199+ const Buffer<unsigned char > buf = data;
2200+ size_t len = data.size ();
2201+ if (EVP_PKEY_get_octet_string_param (
2202+ get (), OSSL_PKEY_PARAM_ML_DSA_SEED, buf.data , len, &seed_len) != 1 )
2203+ return {};
2204+ return data;
2205+ }
2206+ return {};
2207+ }
2208+ #endif
2209+
21512210DataPointer EVPKeyPointer::rawPrivateKey () const {
21522211 if (!pkey_) return {};
21532212 if (auto data = DataPointer::Alloc (rawPrivateKeySize ())) {
@@ -2598,7 +2657,18 @@ bool EVPKeyPointer::isRsaVariant() const {
25982657bool EVPKeyPointer::isOneShotVariant () const {
25992658 if (!pkey_) return false ;
26002659 int type = id ();
2601- return type == EVP_PKEY_ED25519 || type == EVP_PKEY_ED448;
2660+ switch (type) {
2661+ case EVP_PKEY_ED25519:
2662+ case EVP_PKEY_ED448:
2663+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2664+ case EVP_PKEY_ML_DSA_44:
2665+ case EVP_PKEY_ML_DSA_65:
2666+ case EVP_PKEY_ML_DSA_87:
2667+ #endif
2668+ return true ;
2669+ default :
2670+ return false ;
2671+ }
26022672}
26032673
26042674bool EVPKeyPointer::isSigVariant () const {
0 commit comments