1=pod 2 3=encoding utf-8 4 5=head1 NAME 6 7EVP_PKEY-ML-DSA, EVP_KEYMGMT-ML-DSA, 8EVP_PKEY-ML-DSA-44, EVP_PKEY-ML-DSA-65, EVP_PKEY-ML-DSA-87 9- EVP_PKEY ML-DSA keytype and algorithm support 10 11=head1 DESCRIPTION 12 13ML-DSA implements the algorithms B<ML-DSA-44>, B<ML-DSA-65> and B<ML-DSA-87>. 14The key types B<EVP_PKEY_ML_DSA_44>, B<EVP_PKEY_ML_DSA_65> and 15B<EVP_PKEY_ML_DSA_87> are implemented in OpenSSL's default and FIPS providers. 16These implementations support the associated key, containing the public key I<pub> 17and the private key I<priv>. 18 19Each of the different key types has an associated security category. 20This value is one of 2, 3 or 5 for key types B<ML-DSA-44>, B<ML-DSA-65> 21and B<ML-DSA-87> respectively, which correspond to security strengths of 22128, 192 and 256 repsectively. 23 24=head2 Keygen Parameters 25 26=over 4 27 28=item "seed" (B<OSSL_PKEY_PARAM_ML_DSA_SEED>) <octet string> 29 30The seed can be used to generate the private and public key components in a 31deterministic manner. 32The length of the value supplied must be 32 bytes. 33When this value is not supplied the seed is generated randomly using a DRBG. 34 35Generated keys default to retaining the seed used. 36The seed is also by default retained when keys are loaded from B<PKCS#8> files 37in the seed format. 38When available, the seed parameter is also used during key export and import, 39with keys (by default) regenerated from the seed even when also provided on import. 40See L</Provider configuration parameters> below for related controls. 41 42When the seed is retained, it is also available as a B<gettable> parameter, 43and private key output to B<PKCS#8> files will by default include the seed. 44When the seed was not initially known, or was not retained, B<PKCS#8> private 45key files will contain only the private key in FIPS 204 C<sk> format. 46 47=item "properties" (B<OSSL_PKEY_PARAM_PROPERTIES>) <UTF8 string> 48 49Sets properties to be used when fetching algorithm implementations used for 50ML-DSA hashing operations. 51 52=back 53 54Use L<EVP_PKEY_CTX_set_params(3)> after calling L<EVP_PKEY_keygen_init(3)>. 55 56=head2 Common ML-DSA parameters 57 58In addition to the common parameters that all keytypes should support (see 59L<provider-keymgmt(7)/Common Information Parameters>, the implementation of 60these key types support the parameters listed below. 61These are gettable using 62L<EVP_PKEY_get_octet_string_param(3)> or L<EVP_PKEY_get_params(3)>. 63They can be initialised via L<EVP_PKEY_fromdata(3)>, and are returned by 64L<EVP_PKEY_todata(3)> given a suitable I<selection>. 65Once a public or private key is configured, it can no longer be modified, 66nor can another key component be added. 67 68=over 4 69 70=item "pub" (B<OSSL_PKEY_PARAM_PUB_KEY>) <octet string> 71 72The encoded public key value of size 1312, 1952 or 2592 bytes depending on the 73respective key type of B<ML-DSA-44>, B<ML-DSA-65> or B<ML-DSA-87>. 74 75=item "priv" (B<OSSL_PKEY_PARAM_PRIV_KEY>) <octet string> 76 77The encoded private key value of size 2560, 4032 or 4896 bytes depending on the 78respective key type of B<ML-DSA-44>, B<ML-DSA-65> or B<ML-DSA-87>. 79 80=back 81 82=head2 Provider configuration parameters 83 84See the description of the B<-provparam> option in L<openssl(1)> to learn 85how to set provider configuration parameters in the command line tools. 86See L<OSSL_PROVIDER_add_conf_parameter(3)> to learn how to set provider 87configuration options programmatically. 88 89=over 4 90 91=item C<ml-dsa.retain_seed> (B<OSSL_PKEY_PARAM_ML_DSA_RETAIN_SEED>) <UTF8 string> 92 93When set to a string representing a false boolean value (see 94L<OSSL_PROVIDER_conf_get_bool(3)>), the seed will not be retained after key 95generation or key import from a seed value. 96If the resulting key is then written to a PKCS#8 object, it will contain 97only the FIPS 204 C<sk> key. 98 99=item C<ml-dsa.prefer_seed> (B<OSSL_PKEY_PARAM_ML_DSA_PREFER_SEED>) <UTF8 string> 100 101When decoding PKCS#8 objects that contain both a seed and the FIPS 204 C<sk> 102private key, the seed is by default used to regenerate the key, and the 103companion private key is ignored. 104When this configuration parameter is set to a string representing a false 105boolean value (see L<OSSL_PROVIDER_conf_get_bool(3)>), the seed is ignored 106(neither used to regenerate the key, nor retained), and the companion key is 107used instead. 108 109=item C<ml-dsa.input_formats> (B<OSSL_PKEY_PARAM_ML_DSA_INPUT_FORMATS>) <UTF8 string> 110 111List of enabled private key input formats when parsing PKCS#8 objects. 112List elements are separated by commas, spaces or tabs. 113The list of enabled formats can be specified in the configuration file, as seen 114in the L</EXAMPLES> section below, or the via the B<-provparam> command-line 115option (see also L<OSSL_PROVIDER_add_conf_parameter(3)>). 116 117Values specified on the command-line override any configuration file settings. 118By default all the supported formats are enabled. 119The supported formats are: 120 121=over 4 122 123=item C<seed-priv>: 124 125This format represents B<PKCS#8> objects in which both the FIPS 204 32-byte 126B<ξ> seed and the secret key B<sk> are present in the private key as part of 127the DER encoding of the ASN.1 sequence: 128 129 ML-DSA-PrivateKey ::= CHOICE { 130 seed [0] IMPLICIT OCTET STRING (SIZE (32)), 131 expandedKey OCTET STRING (SIZE (2560 | 4032 | 4896)), 132 both SEQUENCE { 133 seed OCTET STRING (SIZE (32)), 134 expandedKey OCTET STRING (SIZE (2560 | 4032 | 4896)) } } 135 136If the C<seed-priv> format is not included in the list, this format will not be 137recognised on input. 138 139=item C<seed-only>: 140 141This format represents B<PKCS#8> objects in which only the 32-byte FIPS 204 142B<ξ> seed is present in the above sequence. 143If the C<seed-only> format is not included in the list, this format will not be 144recognised on input. 145 146=item C<priv-only>: 147 148This format represents B<PKCS#8> objects in which only the FIPS 204 149private key B<sk> is present in the above sequence. 150If the C<priv-only> format is not included in the list, this format will not be 151recognised on input. 152 153=item C<oqskeypair>: 154 155This format represents B<PKCS#8> objects in which the private key is a DER 156encoding of an octet string containing the concatenaton of the FIPS 204 private 157key B<sk> and the public key B<pk>. 158This encoding is used in some builds of the C<oqsprovider>. 159If the C<oqskeypair> format is not included in the list, this format will not be 160recognised on input. 161 162=item C<bare-seed>: 163 164This format represents B<PKCS#8> objects in which the private key contains 165the 32-byte FIPS 204 seed B<ξ> without any ASN.1 encapsulation. 166If the C<bare-seed> format is not included in the list, this format will not be 167recognised on input. 168 169=item C<bare-priv>: 170 171This format represents B<PKCS#8> objects in which the private key contains 172the FIPS 204 secret key B<sk> without any ASN.1 encapsulation. 173If the C<bare-priv> format is not included in the list, this format will not be 174recognised on input. 175 176=back 177 178=item C<ml-dsa.output_formats> (B<OSSL_PKEY_PARAM_ML_DSA_OUTPUT_FORMATS>) <UTF8 string> 179 180Ordered list of enabled private key output formats when writing B<PKCS#8> files. 181List elements are separated by commas, spaces or tabs. 182The list of enabled formats can be specified in the configuration file, as seen 183in the L</EXAMPLES> section below, or the via the B<-provparam> command-line 184option. 185 186This supports the same set of formats as described under C<ml-dsa.input_formats> 187above. 188The order in which elements are listed is important, the selected format will be 189the first one that is possible to output. 190If the key seed is known, the first listed format will be selected. 191If the key seed is not known, the first format that omits the seed will be selected. 192The default order is equivalent to C<seed-priv> first and C<priv-only> second, with 193both seed and key output when the seed is available, and just the 194key otherwise. 195If C<seed-only> is listed first, then the seed will be output without the key 196when available, otherwise the output will have just the key. 197If C<priv-only> is listed first, then just the key is output regardless of 198whether the seed is present. 199The legacy C<oqskeypair>, C<bare-seed> and C<bare-priv> formats can also be 200output, by listing those first. 201 202=back 203 204=head1 CONFORMING TO 205 206=over 4 207 208=item FIPS 204 209 210=back 211 212=head1 EXAMPLES 213 214An B<EVP_PKEY> context can be obtained by calling: 215 216 EVP_PKEY_CTX *pctx = 217 EVP_PKEY_CTX_new_from_name(NULL, "ML-DSA-44", NULL); 218 219An B<ML-DSA-44> key can be generated like this: 220 221 pkey = EVP_PKEY_Q_keygen(NULL, NULL, "ML-DSA-44"); 222 223The key pair components can be extracted from a key by calling: 224 225 /* Sizes large enough for ML-DSA-87 */ 226 uint8_t pub[2592], priv[4896], seed[32]: 227 size_t priv_len, pub_len, seed_len; 228 229 EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_ML_DSA_SEED, 230 seed, sizeof(seed), &seed_len); 231 EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PRIV_KEY, 232 priv, sizeof(priv), &priv_len); 233 EVP_PKEY_get_octet_string_param(pkey, OSSL_PKEY_PARAM_PUB_KEY, 234 pub, sizeof(pub), &pub_len)); 235 236An B<ML-DSA> private key in seed format can be converted to a key in the FIPS 237204 B<sk> format by running: 238 239 $ openssl pkey -provparam ml-dsa.retain_seed=no \ 240 -in seed-only.pem -out priv-only.pem 241 242To generate an, e.g., B<ML-DSA-65> key, in FIPS 204 B<sk> format, you can run: 243 244 $ openssl genpkey -provparam ml-dsa.retain_seed=no \ 245 -algorithm ml-dsa-65 -out priv-only.pem 246 247If you have a B<PKCS#8> file with both a seed and a key, and prefer to import the 248companion key rather than the seed, you can run: 249 250 $ openssl pkey -provparam ml-dsa.prefer_seed=no \ 251 -in seed-priv.pem -out priv-only.pem 252 253In the B<openssl.cnf> file, this looks like: 254 255 openssl_conf = openssl_init 256 257 [openssl_init] 258 providers = providers_sect 259 260 # Can be referenced in one or more provider sections 261 [ml_dsa_sect] 262 prefer_seed = yes 263 retain_seed = yes 264 # OQS legacy formats disabled 265 input_formats = seed-priv, seed-only, priv-only 266 # Output either the seed alone, or else the key alone 267 output_formats = seed-only, priv-only 268 269 [providers_sect] 270 default = default_sect 271 # Or perhaps just: base = default_sect 272 base = base_sect 273 274 [default_sect] 275 ml-dsa = ml_dsa_sect 276 277 [base_sect] 278 ml-dsa = ml_dsa_sect 279 280=head1 SEE ALSO 281 282L<EVP_KEYMGMT(3)>, 283L<EVP_PKEY(3)>, 284L<provider-keymgmt(7)>, 285L<EVP_PKEY_get_raw_private_key(3)>, 286L<EVP_PKEY_get_raw_public_key(3)>, 287L<EVP_PKEY_get1_encoded_public_key(3)>, 288L<OSSL_PROVIDER_add_conf_parameter(3)>, 289L<provider-keymgmt(7)>, 290L<EVP_SIGNATURE-ML-DSA(7)> 291 292=head1 HISTORY 293 294This functionality was added in OpenSSL 3.5. 295 296=head1 COPYRIGHT 297 298Copyright 2025 The OpenSSL Project Authors. All Rights Reserved. 299 300Licensed under the Apache License 2.0 (the "License"). You may not use 301this file except in compliance with the License. You can obtain a copy 302in the file LICENSE in the source distribution or at 303L<https://www.openssl.org/source/license.html>. 304 305=cut 306