### Changes between 3.4 and 3.5 [xx XXX xxxx]
+* Add ML-DSA as specified in FIPS 204.
+
+ The base code was derived from BoringSSL C++ code.
+ *Shane Lontis, Viktor Dukhovni and Paul Dale*
+
* Added new API calls to enable 3rd party QUIC stacks to use the OpenSSL TLS
implementation.
GENERATE[html/man7/EVP_PKEY-HMAC.html]=man7/EVP_PKEY-HMAC.pod
DEPEND[man/man7/EVP_PKEY-HMAC.7]=man7/EVP_PKEY-HMAC.pod
GENERATE[man/man7/EVP_PKEY-HMAC.7]=man7/EVP_PKEY-HMAC.pod
+DEPEND[html/man7/EVP_PKEY-ML-DSA.html]=man7/EVP_PKEY-ML-DSA.pod
+GENERATE[html/man7/EVP_PKEY-ML-DSA.html]=man7/EVP_PKEY-ML-DSA.pod
+DEPEND[man/man7/EVP_PKEY-ML-DSA.7]=man7/EVP_PKEY-ML-DSA.pod
+GENERATE[man/man7/EVP_PKEY-ML-DSA.7]=man7/EVP_PKEY-ML-DSA.pod
DEPEND[html/man7/EVP_PKEY-RSA.html]=man7/EVP_PKEY-RSA.pod
GENERATE[html/man7/EVP_PKEY-RSA.html]=man7/EVP_PKEY-RSA.pod
DEPEND[man/man7/EVP_PKEY-RSA.7]=man7/EVP_PKEY-RSA.pod
GENERATE[html/man7/EVP_SIGNATURE-HMAC.html]=man7/EVP_SIGNATURE-HMAC.pod
DEPEND[man/man7/EVP_SIGNATURE-HMAC.7]=man7/EVP_SIGNATURE-HMAC.pod
GENERATE[man/man7/EVP_SIGNATURE-HMAC.7]=man7/EVP_SIGNATURE-HMAC.pod
+DEPEND[html/man7/EVP_SIGNATURE-ML-DSA.html]=man7/EVP_SIGNATURE-ML-DSA.pod
+GENERATE[html/man7/EVP_SIGNATURE-ML-DSA.html]=man7/EVP_SIGNATURE-ML-DSA.pod
+DEPEND[man/man7/EVP_SIGNATURE-ML-DSA.7]=man7/EVP_SIGNATURE-ML-DSA.pod
+GENERATE[man/man7/EVP_SIGNATURE-ML-DSA.7]=man7/EVP_SIGNATURE-ML-DSA.pod
DEPEND[html/man7/EVP_SIGNATURE-RSA.html]=man7/EVP_SIGNATURE-RSA.pod
GENERATE[html/man7/EVP_SIGNATURE-RSA.html]=man7/EVP_SIGNATURE-RSA.pod
DEPEND[man/man7/EVP_SIGNATURE-RSA.7]=man7/EVP_SIGNATURE-RSA.pod
html/man7/EVP_PKEY-EC.html \
html/man7/EVP_PKEY-FFC.html \
html/man7/EVP_PKEY-HMAC.html \
+html/man7/EVP_PKEY-ML-DSA.html \
html/man7/EVP_PKEY-RSA.html \
html/man7/EVP_PKEY-SM2.html \
html/man7/EVP_PKEY-X25519.html \
html/man7/EVP_SIGNATURE-ECDSA.html \
html/man7/EVP_SIGNATURE-ED25519.html \
html/man7/EVP_SIGNATURE-HMAC.html \
+html/man7/EVP_SIGNATURE-ML-DSA.html \
html/man7/EVP_SIGNATURE-RSA.html \
html/man7/OSSL_PROVIDER-FIPS.html \
html/man7/OSSL_PROVIDER-base.html \
man/man7/EVP_PKEY-EC.7 \
man/man7/EVP_PKEY-FFC.7 \
man/man7/EVP_PKEY-HMAC.7 \
+man/man7/EVP_PKEY-ML-DSA.7 \
man/man7/EVP_PKEY-RSA.7 \
man/man7/EVP_PKEY-SM2.7 \
man/man7/EVP_PKEY-X25519.7 \
man/man7/EVP_SIGNATURE-ECDSA.7 \
man/man7/EVP_SIGNATURE-ED25519.7 \
man/man7/EVP_SIGNATURE-HMAC.7 \
+man/man7/EVP_SIGNATURE-ML-DSA.7 \
man/man7/EVP_SIGNATURE-RSA.7 \
man/man7/OSSL_PROVIDER-FIPS.7 \
man/man7/OSSL_PROVIDER-base.7 \
L<OSSL_PARAM(3)>, L<EVP_PKEY_todata(3)>,
L<EVP_PKEY-RSA(7)>, L<EVP_PKEY-DSA(7)>, L<EVP_PKEY-DH(7)>, L<EVP_PKEY-EC(7)>,
L<EVP_PKEY-ED448(7)>, L<EVP_PKEY-X25519(7)>, L<EVP_PKEY-X448(7)>,
-L<EVP_PKEY-ED25519(7)>
+L<EVP_PKEY-ED25519(7)>, L<EVP_PKEY-ML-DSA(7)>
=head1 HISTORY
L<EVP_PKEY_fromdata(3)>,
L<EVP_PKEY-RSA(7)>, L<EVP_PKEY-DSA(7)>, L<EVP_PKEY-DH(7)>, L<EVP_PKEY-EC(7)>,
L<EVP_PKEY-ED448(7)>, L<EVP_PKEY-X25519(7)>, L<EVP_PKEY-X448(7)>,
-L<EVP_PKEY-ED25519(7)>
+L<EVP_PKEY-ED25519(7)>, L<EVP_PKEY-ML-DSA(7)>
=head1 HISTORY
--- /dev/null
+=pod
+
+=head1 NAME
+
+EVP_PKEY-ML-DSA, EVP_KEYMGMT-ML-DSA,
+EVP_PKEY-ML-DSA-44, EVP_PKEY-ML-DSA-65, EVP_PKEY-ML-DSA-87
+- EVP_PKEY ML-DSA keytype and algorithm support
+
+=head1 DESCRIPTION
+
+ML-DSA implements the algorithms B<ML-DSA-44>, B<ML-DSA-65> and B<ML-DSA-87>.
+The key types B<EVP_PKEY_ML_DSA_44>, B<EVP_PKEY_ML_DSA_65> and
+B<EVP_PKEY_ML_DSA_87> are implemented in OpenSSL's default provider.
+These implementations support the associated key, containing the public key I<pub>
+and the private key I<priv>.
+
+Each of the different key types has an associated security category.
+This value is one of 2, 3 or 5 for key types B<ML-DSA-44>, B<ML-DSA-65>
+and B<ML-DSA-87> respectively, which correspond to security strengths of
+128, 192 and 256 repsectively.
+
+=head2 Keygen Parameters
+
+=over 4
+
+=item "seed" (B<OSSL_PKEY_PARAM_ML_DSA_SEED>) <octet string>
+
+The seed used to generate the private and public key components in a
+deterministic manner. This should only be used for testing purposes.
+The length of the value supplied must be 32 bytes.
+When this value is not supplied the seed is generated randomly using a DRBG.
+
+=item "properties" (B<OSSL_PKEY_PARAM_PROPERTIES>) <utf8_string>
+
+Sets properties to be used when fetching algorithm implementations used for
+ML-DSA hashing operations.
+
+=back
+
+Use EVP_PKEY_CTX_set_params() after calling EVP_PKEY_keygen_init().
+
+=head2 Common ML-DSA parameters
+
+In addition to the common parameters that all keytypes should support (see
+L<provider-keymgmt(7)/Common parameters>), the implementation of these key types
+support the following.
+
+The following parameters are gettable using EVP_PKEY_get_octet_string_param(),
+and settable when using EVP_PKEY_fromdata().
+
+=over 4
+
+=item "pub" (B<OSSL_PKEY_PARAM_PUB_KEY>) <octet string>
+
+The encoded public key value of size 1312, 1952 or 2592 bytes depending on the
+respective key type of B<ML-DSA-44>, B<ML-DSA-65> or B<ML-DSA-87>.
+
+=item "priv" (B<OSSL_PKEY_PARAM_PRIV_KEY>) <octet string>
+
+The encoded private key value of size 2560, 4032 or 4896 bytes depending on the
+respective key type of B<ML-DSA-44>, B<ML-DSA-65> or B<ML-DSA-87>.
+
+=back
+
+=head1 CONFORMING TO
+
+=over 4
+
+=item FIPS 204
+
+=back
+
+=head1 EXAMPLES
+
+An B<EVP_PKEY> context can be obtained by calling:
+
+ EVP_PKEY_CTX *pctx =
+ EVP_PKEY_CTX_new_from_name(NULL, "ML-DSA-44", NULL);
+
+An B<ML-DSA> key can be generated like this:
+
+ pkey = EVP_PKEY_Q_keygen(NULL, NULL, "ML-DSA-44");
+
+The key pair components can be extracted from a key by calling:
+
+ uint8_t priv[3 * 1024], pub[5 * 1024];
+ size_t priv_len, pub_len;
+
+ EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
+ priv, sizeof(priv), &priv_len);
+ EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY,
+ pub, sizeof(pub), &pub_len));
+
+Similar code can be used for the other key types such as "ML-DSA-87".
+
+=head1 SEE ALSO
+
+L<EVP_KEYMGMT(3)>, L<EVP_PKEY(3)>, L<provider-keymgmt(7)>,
+L<EVP_SIGNATURE-ML-DSA(7)>
+
+=head1 HISTORY
+
+This functionality was added in OpenSSL 3.5.
+
+=head1 COPYRIGHT
+
+Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
--- /dev/null
+=pod
+
+=head1 NAME
+
+EVP_SIGNATURE-ML-DSA,
+EVP_SIGNATURE-ML-DSA-44, EVP_SIGNATURE-ML-DSA-65, EVP_SIGNATURE-ML-DSA-87,
+- EVP_SIGNATURE ML-DSA support
+
+=head1 DESCRIPTION
+
+The B<ML-DSA-44>, B<ML-DSA-65> and B<ML-DSA-87> EVP_PKEY implementations
+support key generation, and one-shot sign and verify using the ML-DSA
+signature schemes described in FIPS 204.
+
+The different algorithms names correspond to the parameter sets defined in
+FIPS 204 Section 4 Table 1.
+(The signatures range in size from ~2.5K to ~4.5K depending on the type chosen).
+There are 3 different security categories also depending on the type.
+
+L<EVP_SIGNATURE_fetch(3)> can be used to explicitely fetch one of the 3
+algorithms which can then be used with L<EVP_PKEY_sign_message_init(3)>,
+L<EVP_PKEY_sign(3)>, L<EVP_PKEY_verify_message_init(3)>, and
+L<EVP_PKEY_verify(3)> to sign or verify one-shot messages.
+
+The normal signing process (called Pure ML-DSA Signature Generation)
+encodes the message internally as 0x00 || len(ctx) || ctx || message.
+where B<ctx> is some optional value of size 0x00..0xFF.
+OpenSSL also allows the message to not be encoded which is required for
+testing. OpenSSL does not support Pre Hash ML-DSA Signature Generation, but this
+may be done by the user by doing Pre hash encoding externally and then chosing
+the option to not encode the message.
+
+=head2 ML-DSA Signature Parameters
+
+The following parameter can be used for both signing and verification.
+it may be set by passing an OSSL_PARAM array to L<EVP_PKEY_sign_message_init(3)>
+or L<EVP_PKEY_verify_message_init(3)>
+
+=over 4
+
+=item "context-string" (B<OSSL_SIGNATURE_PARAM_CONTEXT_STRING>) <octet string>
+
+A string of octets with length at most 255. By default it is the empty string.
+
+=back
+
+The following parameters can be used when signing:
+They can be set by passing an OSSL_PARAM array to L<EVP_PKEY_sign_init_ex2(3)>.
+
+=over 4
+
+=item "message-encoding" (B<OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING>) <integer>
+
+The default value of 1 uses 'Pure ML-DSA Signature Generation' as described
+above. Setting it to 0 does not encode the message, which is used for testing,
+but can also be used for 'Pre Hash ML-DSA Signature Generation'.
+
+=item "test-entropy" (B<OSSL_SIGNATURE_PARAM_TEST_ENTROPY <octet string>
+
+Used for testing to pass an optional deterministic per message random value.
+If set the size must be 32 bytes.
+
+=item "deterministic" (B<OSSL_SIGNATURE_PARAM_DETERMINISTIC>) <integer>
+
+The default value of 0 causes the per message randomness to be randomly
+generated using a DRBG. Setting this to 1 causes the per message randomness
+to be set to 32 bytes of zeros. This value is ignored if "test-entropy" is set.
+
+=back
+
+See L<EVP_PKEY-ML-DSA(7)> for information related to B<ML-DSA> keys.
+
+
+=head1 EXAMPLES
+
+To sign a message using an ML-DSA EVP_PKEY structure:
+
+ void do_sign(EVP_PKEY *key, unsigned char *msg, size_t msg_len)
+ {
+ size_t sig_len;
+ unsigned char *sig = NULL;
+ const OSSL_PARAM params[] = {
+ OSSL_PARAM_octet_string("context-string", (unsigned char *)"A context string", 33),
+ OSSL_PARAM_END
+ };
+ EVP_PKEY_CTX *sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
+ EVP_SIGNATURE *sig_alg = EVP_SIGNATURE_fetch(NULL, "ML-DSA-65", NULL);
+
+ EVP_PKEY_sign_message_init(sctx, sig_alg, params);
+ /* Calculate the required size for the signature by passing a NULL buffer. */
+ EVP_PKEY_sign(sctx, NULL, &sig_len, msg, msg_len);
+ sig = OPENSSL_zalloc(sig_len);
+ EVP_PKEY_sign(sctx, sig, &sig_len, msg, msg_len);
+ ...
+ OPENSSL_free(sig);
+ EVP_SIGNATURE(sig_alg);
+ EVP_PKEY_CTX_free(sctx);
+ }
+
+=head1 SEE ALSO
+
+L<EVP_PKEY-ML-DSA(7)>
+L<provider-signature(7)>,
+L<EVP_PKEY_sign(3)>,
+L<EVP_PKEY_verify(3)>,
+
+=head1 HISTORY
+
+This functionality was added in OpenSSL 3.5.
+
+=head1 COPYRIGHT
+
+Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
=item SM2
+=item ML-DSA-44
+
+=item ML-DSA-65
+
+=item ML-DSA-87
+
=back
In addition to this provider, all of these encoding algorithms are also
=item DER
+=item ML-DSA-44
+
+=item ML-DSA-65
+
+=item ML-DSA-87
+
=back
In addition to this provider, all of these decoding algorithms are also
=item SM2
+=item ML-DSA, see L<EVP_SIGNATURE-ML-DSA(7)>
+
=item HMAC, see L<EVP_SIGNATURE-HMAC(7)>
=item SIPHASH, see L<EVP_SIGNATURE-Siphash(7)>
=item SM2, see L<EVP_KEYMGMT-SM2(7)>
+=item ML-DSA, see L<EVP_KEYMGMT-ML-DSA(7)>
+
=back
=head2 Random Number Generation
=item SM2
+=item ML-DSA-44
+
+=item ML-DSA-65
+
+=item ML-DSA-87
+
=back
In addition to this provider, all of these encoding algorithms are also
=item SM2
+=item ML-DSA-44
+
+=item ML-DSA-65
+
+=item ML-DSA-87
+
=item DER
=back
L<provider(7)>,
L<EVP_PKEY-X25519(7)>, L<EVP_PKEY-X448(7)>, L<EVP_PKEY-ED25519(7)>,
L<EVP_PKEY-ED448(7)>, L<EVP_PKEY-EC(7)>, L<EVP_PKEY-RSA(7)>,
-L<EVP_PKEY-DSA(7)>, L<EVP_PKEY-DH(7)>
+L<EVP_PKEY-DSA(7)>, L<EVP_PKEY-DH(7)>, L<EVP_PKEY-ML-DSA(7)>
=head1 HISTORY