@@ -1983,6 +1983,31 @@ EVPKeyPointer EVPKeyPointer::NewRawPrivate(
19831983 EVP_PKEY_new_raw_private_key (id, nullptr , data.data , data.len ));
19841984}
19851985
1986+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
1987+ EVPKeyPointer EVPKeyPointer::NewRawSeed (
1988+ int id, const Buffer<const unsigned char >& data) {
1989+ if (id == 0 ) return {};
1990+
1991+ OSSL_PARAM params[] = {
1992+ OSSL_PARAM_construct_octet_string (OSSL_PKEY_PARAM_ML_DSA_SEED,
1993+ const_cast <unsigned char *>(data.data ),
1994+ data.len ),
1995+ OSSL_PARAM_END};
1996+
1997+ EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new_id (id, nullptr );
1998+ if (ctx == nullptr ) return {};
1999+
2000+ EVP_PKEY* pkey = nullptr ;
2001+ if (ctx == nullptr || EVP_PKEY_fromdata_init (ctx) <= 0 ||
2002+ EVP_PKEY_fromdata (ctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0 ) {
2003+ EVP_PKEY_CTX_free (ctx);
2004+ return {};
2005+ }
2006+
2007+ return EVPKeyPointer (pkey);
2008+ }
2009+ #endif
2010+
19862011EVPKeyPointer EVPKeyPointer::NewDH (DHPointer&& dh) {
19872012#ifndef NCRYPTO_NO_EVP_DH
19882013 if (!dh) return {};
@@ -2040,7 +2065,16 @@ EVP_PKEY* EVPKeyPointer::release() {
20402065
20412066int EVPKeyPointer::id (const EVP_PKEY* key) {
20422067 if (key == nullptr ) return 0 ;
2043- return EVP_PKEY_id (key);
2068+ int type = EVP_PKEY_id (key);
2069+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2070+ // https://github.com/openssl/openssl/issues/27738#issuecomment-3013215870
2071+ if (type == -1 ) {
2072+ if (EVP_PKEY_is_a (key, " ML-DSA-44" )) return EVP_PKEY_ML_DSA_44;
2073+ if (EVP_PKEY_is_a (key, " ML-DSA-65" )) return EVP_PKEY_ML_DSA_65;
2074+ if (EVP_PKEY_is_a (key, " ML-DSA-87" )) return EVP_PKEY_ML_DSA_87;
2075+ }
2076+ #endif
2077+ return type;
20442078}
20452079
20462080int EVPKeyPointer::base_id (const EVP_PKEY* key) {
@@ -2096,6 +2130,31 @@ DataPointer EVPKeyPointer::rawPublicKey() const {
20962130 return {};
20972131}
20982132
2133+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2134+ DataPointer EVPKeyPointer::rawSeed () const {
2135+ if (!pkey_) return {};
2136+ switch (id ()) {
2137+ case EVP_PKEY_ML_DSA_44:
2138+ case EVP_PKEY_ML_DSA_65:
2139+ case EVP_PKEY_ML_DSA_87:
2140+ break ;
2141+ default :
2142+ unreachable ();
2143+ }
2144+
2145+ size_t seed_len = 32 ;
2146+ if (auto data = DataPointer::Alloc (seed_len)) {
2147+ const Buffer<unsigned char > buf = data;
2148+ size_t len = data.size ();
2149+ if (EVP_PKEY_get_octet_string_param (
2150+ get (), OSSL_PKEY_PARAM_ML_DSA_SEED, buf.data , len, &seed_len) != 1 )
2151+ return {};
2152+ return data;
2153+ }
2154+ return {};
2155+ }
2156+ #endif
2157+
20992158DataPointer EVPKeyPointer::rawPrivateKey () const {
21002159 if (!pkey_) return {};
21012160 if (auto data = DataPointer::Alloc (rawPrivateKeySize ())) {
@@ -2546,7 +2605,18 @@ bool EVPKeyPointer::isRsaVariant() const {
25462605bool EVPKeyPointer::isOneShotVariant () const {
25472606 if (!pkey_) return false ;
25482607 int type = id ();
2549- return type == EVP_PKEY_ED25519 || type == EVP_PKEY_ED448;
2608+ switch (type) {
2609+ case EVP_PKEY_ED25519:
2610+ case EVP_PKEY_ED448:
2611+ #if OPENSSL_VERSION_MAJOR >= 3 && OPENSSL_VERSION_MINOR >= 5
2612+ case EVP_PKEY_ML_DSA_44:
2613+ case EVP_PKEY_ML_DSA_65:
2614+ case EVP_PKEY_ML_DSA_87:
2615+ #endif
2616+ return true ;
2617+ default :
2618+ return false ;
2619+ }
25502620}
25512621
25522622bool EVPKeyPointer::isSigVariant () const {
0 commit comments