@@ -1863,6 +1863,31 @@ EVPKeyPointer EVPKeyPointer::NewRawPrivate(
18631863 EVP_PKEY_new_raw_private_key (id, nullptr , data.data , data.len ));
18641864}
18651865
1866+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
1867+ EVPKeyPointer EVPKeyPointer::NewRawSeed (
1868+ int id, const Buffer<const unsigned char >& data) {
1869+ if (id == 0 ) return {};
1870+
1871+ OSSL_PARAM params[] = {
1872+ OSSL_PARAM_construct_octet_string (OSSL_PKEY_PARAM_ML_DSA_SEED,
1873+ const_cast <unsigned char *>(data.data ),
1874+ data.len ),
1875+ OSSL_PARAM_END};
1876+
1877+ EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id (id, nullptr );
1878+ if (ctx == nullptr ) return {};
1879+
1880+ EVP_PKEY* pkey = nullptr ;
1881+ if (ctx == nullptr || EVP_PKEY_fromdata_init (ctx) <= 0 ||
1882+ EVP_PKEY_fromdata (ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0 ) {
1883+ EVP_PKEY_CTX_free (ctx);
1884+ return {};
1885+ }
1886+
1887+ return EVPKeyPointer (pkey);
1888+ }
1889+ #endif
1890+
18661891EVPKeyPointer EVPKeyPointer::NewDH (DHPointer&& dh) {
18671892#ifndef NCRYPTO_NO_EVP_DH
18681893 if (!dh) return {};
@@ -1914,7 +1939,16 @@ EVP_PKEY* EVPKeyPointer::release() { return pkey_.release(); }
19141939
19151940int EVPKeyPointer::id (const EVP_PKEY* key) {
19161941 if (key == nullptr ) return 0 ;
1917- return EVP_PKEY_id (key);
1942+ int type = EVP_PKEY_id (key);
1943+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
1944+ // https://github.com/openssl/openssl/issues/27738#issuecomment-3013215870
1945+ if (type == -1 ) {
1946+ if (EVP_PKEY_is_a (key, " ML-DSA-44" )) return EVP_PKEY_ML_DSA_44;
1947+ if (EVP_PKEY_is_a (key, " ML-DSA-65" )) return EVP_PKEY_ML_DSA_65;
1948+ if (EVP_PKEY_is_a (key, " ML-DSA-87" )) return EVP_PKEY_ML_DSA_87;
1949+ }
1950+ #endif
1951+ return type;
19181952}
19191953
19201954int EVPKeyPointer::base_id (const EVP_PKEY* key) {
@@ -1966,6 +2000,31 @@ DataPointer EVPKeyPointer::rawPublicKey() const {
19662000 return {};
19672001}
19682002
2003+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2004+ DataPointer EVPKeyPointer::rawSeed () const {
2005+ if (!pkey_) return {};
2006+ switch (id ()) {
2007+ case EVP_PKEY_ML_DSA_44:
2008+ case EVP_PKEY_ML_DSA_65:
2009+ case EVP_PKEY_ML_DSA_87:
2010+ break ;
2011+ default :
2012+ unreachable ();
2013+ }
2014+
2015+ size_t seed_len = 32 ;
2016+ if (auto data = DataPointer::Alloc (seed_len)) {
2017+ const Buffer<unsigned char > buf = data;
2018+ size_t len = data.size ();
2019+ if (EVP_PKEY_get_octet_string_param (
2020+ get (), OSSL_PKEY_PARAM_ML_DSA_SEED, buf.data , len, &seed_len) != 1 )
2021+ return {};
2022+ return data;
2023+ }
2024+ return {};
2025+ }
2026+ #endif
2027+
19692028DataPointer EVPKeyPointer::rawPrivateKey () const {
19702029 if (!pkey_) return {};
19712030 if (auto data = DataPointer::Alloc (rawPrivateKeySize ())) {
@@ -2390,7 +2449,18 @@ bool EVPKeyPointer::isRsaVariant() const {
23902449bool EVPKeyPointer::isOneShotVariant () const {
23912450 if (!pkey_) return false ;
23922451 int type = id ();
2393- return type == EVP_PKEY_ED25519 || type == EVP_PKEY_ED448;
2452+ switch (type) {
2453+ case EVP_PKEY_ED25519:
2454+ case EVP_PKEY_ED448:
2455+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2456+ case EVP_PKEY_ML_DSA_44:
2457+ case EVP_PKEY_ML_DSA_65:
2458+ case EVP_PKEY_ML_DSA_87:
2459+ #endif
2460+ return true ;
2461+ default :
2462+ return false ;
2463+ }
23942464}
23952465
23962466bool EVPKeyPointer::isSigVariant () const {
0 commit comments