EVP_PKEY-ML-DSA.pod revision 1.1.1.1 1 =pod
2
3 =encoding utf-8
4
5 =head1 NAME
6
7 EVP_PKEY-ML-DSA, EVP_KEYMGMT-ML-DSA,
8 EVP_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
13 ML-DSA implements the algorithms B<ML-DSA-44>, B<ML-DSA-65> and B<ML-DSA-87>.
14 The key types B<EVP_PKEY_ML_DSA_44>, B<EVP_PKEY_ML_DSA_65> and
15 B<EVP_PKEY_ML_DSA_87> are implemented in OpenSSL's default and FIPS providers.
16 These implementations support the associated key, containing the public key I<pub>
17 and the private key I<priv>.
18
19 Each of the different key types has an associated security category.
20 This value is one of 2, 3 or 5 for key types B<ML-DSA-44>, B<ML-DSA-65>
21 and B<ML-DSA-87> respectively, which correspond to security strengths of
22 128, 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
30 The seed can be used to generate the private and public key components in a
31 deterministic manner.
32 The length of the value supplied must be 32 bytes.
33 When this value is not supplied the seed is generated randomly using a DRBG.
34
35 Generated keys default to retaining the seed used.
36 The seed is also by default retained when keys are loaded from B<PKCS#8> files
37 in the seed format.
38 When available, the seed parameter is also used during key export and import,
39 with keys (by default) regenerated from the seed even when also provided on import.
40 See L</Provider configuration parameters> below for related controls.
41
42 When the seed is retained, it is also available as a B<gettable> parameter,
43 and private key output to B<PKCS#8> files will by default include the seed.
44 When the seed was not initially known, or was not retained, B<PKCS#8> private
45 key 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
49 Sets properties to be used when fetching algorithm implementations used for
50 ML-DSA hashing operations.
51
52 =back
53
54 Use L<EVP_PKEY_CTX_set_params(3)> after calling L<EVP_PKEY_keygen_init(3)>.
55
56 =head2 Common ML-DSA parameters
57
58 In addition to the common parameters that all keytypes should support (see
59 L<provider-keymgmt(7)/Common Information Parameters>, the implementation of
60 these key types support the parameters listed below.
61 These are gettable using
62 L<EVP_PKEY_get_octet_string_param(3)> or L<EVP_PKEY_get_params(3)>.
63 They can be initialised via L<EVP_PKEY_fromdata(3)>, and are returned by
64 L<EVP_PKEY_todata(3)> given a suitable I<selection>.
65 Once a public or private key is configured, it can no longer be modified,
66 nor can another key component be added.
67
68 =over 4
69
70 =item "pub" (B<OSSL_PKEY_PARAM_PUB_KEY>) <octet string>
71
72 The encoded public key value of size 1312, 1952 or 2592 bytes depending on the
73 respective 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
77 The encoded private key value of size 2560, 4032 or 4896 bytes depending on the
78 respective 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
84 See the description of the B<-provparam> option in L<openssl(1)> to learn
85 how to set provider configuration parameters in the command line tools.
86 See L<OSSL_PROVIDER_add_conf_parameter(3)> to learn how to set provider
87 configuration 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
93 When set to a string representing a false boolean value (see
94 L<OSSL_PROVIDER_conf_get_bool(3)>), the seed will not be retained after key
95 generation or key import from a seed value.
96 If the resulting key is then written to a PKCS#8 object, it will contain
97 only 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
101 When decoding PKCS#8 objects that contain both a seed and the FIPS 204 C<sk>
102 private key, the seed is by default used to regenerate the key, and the
103 companion private key is ignored.
104 When this configuration parameter is set to a string representing a false
105 boolean 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
107 used instead.
108
109 =item C<ml-dsa.input_formats> (B<OSSL_PKEY_PARAM_ML_DSA_INPUT_FORMATS>) <UTF8 string>
110
111 List of enabled private key input formats when parsing PKCS#8 objects.
112 List elements are separated by commas, spaces or tabs.
113 The list of enabled formats can be specified in the configuration file, as seen
114 in the L</EXAMPLES> section below, or the via the B<-provparam> command-line
115 option (see also L<OSSL_PROVIDER_add_conf_parameter(3)>).
116
117 Values specified on the command-line override any configuration file settings.
118 By default all the supported formats are enabled.
119 The supported formats are:
120
121 =over 4
122
123 =item C<seed-priv>:
124
125 This format represents B<PKCS#8> objects in which both the FIPS 204 32-byte
126 B<> seed and the secret key B<sk> are present in the private key as part of
127 the 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
136 If the C<seed-priv> format is not included in the list, this format will not be
137 recognised on input.
138
139 =item C<seed-only>:
140
141 This format represents B<PKCS#8> objects in which only the 32-byte FIPS 204
142 B<> seed is present in the above sequence.
143 If the C<seed-only> format is not included in the list, this format will not be
144 recognised on input.
145
146 =item C<priv-only>:
147
148 This format represents B<PKCS#8> objects in which only the FIPS 204
149 private key B<sk> is present in the above sequence.
150 If the C<priv-only> format is not included in the list, this format will not be
151 recognised on input.
152
153 =item C<oqskeypair>:
154
155 This format represents B<PKCS#8> objects in which the private key is a DER
156 encoding of an octet string containing the concatenaton of the FIPS 204 private
157 key B<sk> and the public key B<pk>.
158 This encoding is used in some builds of the C<oqsprovider>.
159 If the C<oqskeypair> format is not included in the list, this format will not be
160 recognised on input.
161
162 =item C<bare-seed>:
163
164 This format represents B<PKCS#8> objects in which the private key contains
165 the 32-byte FIPS 204 seed B<> without any ASN.1 encapsulation.
166 If the C<bare-seed> format is not included in the list, this format will not be
167 recognised on input.
168
169 =item C<bare-priv>:
170
171 This format represents B<PKCS#8> objects in which the private key contains
172 the FIPS 204 secret key B<sk> without any ASN.1 encapsulation.
173 If the C<bare-priv> format is not included in the list, this format will not be
174 recognised on input.
175
176 =back
177
178 =item C<ml-dsa.output_formats> (B<OSSL_PKEY_PARAM_ML_DSA_OUTPUT_FORMATS>) <UTF8 string>
179
180 Ordered list of enabled private key output formats when writing B<PKCS#8> files.
181 List elements are separated by commas, spaces or tabs.
182 The list of enabled formats can be specified in the configuration file, as seen
183 in the L</EXAMPLES> section below, or the via the B<-provparam> command-line
184 option.
185
186 This supports the same set of formats as described under C<ml-dsa.input_formats>
187 above.
188 The order in which elements are listed is important, the selected format will be
189 the first one that is possible to output.
190 If the key seed is known, the first listed format will be selected.
191 If the key seed is not known, the first format that omits the seed will be selected.
192 The default order is equivalent to C<seed-priv> first and C<priv-only> second, with
193 both seed and key output when the seed is available, and just the
194 key otherwise.
195 If C<seed-only> is listed first, then the seed will be output without the key
196 when available, otherwise the output will have just the key.
197 If C<priv-only> is listed first, then just the key is output regardless of
198 whether the seed is present.
199 The legacy C<oqskeypair>, C<bare-seed> and C<bare-priv> formats can also be
200 output, 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
214 An 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
219 An B<ML-DSA-44> key can be generated like this:
220
221 pkey = EVP_PKEY_Q_keygen(NULL, NULL, "ML-DSA-44");
222
223 The 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
236 An B<ML-DSA> private key in seed format can be converted to a key in the FIPS
237 204 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
242 To 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
247 If you have a B<PKCS#8> file with both a seed and a key, and prefer to import the
248 companion 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
253 In 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
282 L<EVP_KEYMGMT(3)>,
283 L<EVP_PKEY(3)>,
284 L<provider-keymgmt(7)>,
285 L<EVP_PKEY_get_raw_private_key(3)>,
286 L<EVP_PKEY_get_raw_public_key(3)>,
287 L<EVP_PKEY_get1_encoded_public_key(3)>,
288 L<OSSL_PROVIDER_add_conf_parameter(3)>,
289 L<provider-keymgmt(7)>,
290 L<EVP_SIGNATURE-ML-DSA(7)>
291
292 =head1 HISTORY
293
294 This functionality was added in OpenSSL 3.5.
295
296 =head1 COPYRIGHT
297
298 Copyright 2025 The OpenSSL Project Authors. All Rights Reserved.
299
300 Licensed under the Apache License 2.0 (the "License"). You may not use
301 this file except in compliance with the License. You can obtain a copy
302 in the file LICENSE in the source distribution or at
303 L<https://www.openssl.org/source/license.html>.
304
305 =cut
306