@@ -17,7 +17,7 @@ use openssl::derive::Deriver;
17
17
use openssl:: ec:: { EcGroup , EcKey , EcPoint , PointConversionForm } ;
18
18
use openssl:: ecdsa:: EcdsaSig ;
19
19
use openssl:: nid:: Nid ;
20
- use openssl:: pkey:: PKey ;
20
+ use openssl:: pkey:: { PKey , Private , Public } ;
21
21
use openssl:: pkey_ctx:: PkeyCtx ;
22
22
use openssl:: rsa:: { Padding , Rsa , RsaPrivateKeyBuilder } ;
23
23
use openssl:: sign:: Signer as OpenSslSigner ;
@@ -33,7 +33,9 @@ impl Asymmetric for super::Backend {
33
33
RSAEncryptSign | RSAEncrypt | RSASign => true ,
34
34
DSA => true ,
35
35
ECDH | ECDSA | EdDSA => true ,
36
- MLDSA65_Ed25519 | MLDSA87_Ed448 => false ,
36
+ // XXX: Would be better to have a runtime test.
37
+ MLDSA65_Ed25519 | MLDSA87_Ed448 =>
38
+ openssl:: version:: number ( ) >= 0x3_05_00_00_0 ,
37
39
SLHDSA128s | SLHDSA128f | SLHDSA256s =>
38
40
false ,
39
41
MLKEM768_X25519 | MLKEM1024_X448 =>
@@ -165,6 +167,114 @@ impl Asymmetric for super::Backend {
165
167
Ok ( verifier. verify_oneshot ( signature, digest) ?)
166
168
}
167
169
170
+ fn mldsa65_generate_key ( ) -> Result < ( Protected , Box < [ u8 ; 1952 ] > ) > {
171
+ use openssl:: pkey_ml_dsa:: { PKeyMlDsaBuilder , PKeyMlDsaParams , Variant } ;
172
+
173
+ let key = PKeyMlDsaBuilder :: < Private > :: new_generate ( Variant :: MlDsa65 ) ?
174
+ . generate ( ) ?;
175
+ let public_params = PKeyMlDsaParams :: < Public > :: from_pkey ( & key) ?;
176
+ let secret_params = PKeyMlDsaParams :: < Private > :: from_pkey ( & key) ?;
177
+
178
+ let mut secret = Protected :: from ( vec ! [ 0 ; 32 ] ) ;
179
+ let mut public = Box :: new ( [ 0 ; 1952 ] ) ;
180
+ debug_assert_eq ! ( secret. len( ) , secret_params. private_key_seed( ) ?. len( ) ) ;
181
+ debug_assert_eq ! ( public. len( ) , public_params. public_key( ) ?. len( ) ) ;
182
+ secret[ ..] . copy_from_slice ( secret_params. private_key_seed ( ) ?) ;
183
+ public[ ..] . copy_from_slice ( public_params. public_key ( ) ?) ;
184
+
185
+ Ok ( ( secret, public) )
186
+ }
187
+
188
+ fn mldsa65_sign ( secret : & Protected , digest : & [ u8 ] )
189
+ -> Result < Box < [ u8 ; 3309 ] > >
190
+ {
191
+ use openssl:: pkey_ml_dsa:: { PKeyMlDsaBuilder , Variant } ;
192
+ use openssl:: signature:: Signature ;
193
+
194
+ let key = PKeyMlDsaBuilder :: < Private > :: from_seed (
195
+ Variant :: MlDsa65 , secret. as_ref ( ) ) ?
196
+ . build ( ) ?;
197
+ let mut algo = Signature :: for_ml_dsa ( Variant :: MlDsa65 ) ?;
198
+
199
+ let mut ctx = PkeyCtx :: new ( & key) ?;
200
+ ctx. sign_message_init ( & mut algo) ?;
201
+ let mut signature = Box :: new ( [ 0 ; 3309 ] ) ;
202
+ let len = ctx. sign ( digest, Some ( & mut signature[ ..] ) ) ?;
203
+ debug_assert_eq ! ( len, signature. len( ) ) ;
204
+
205
+ Ok ( signature)
206
+ }
207
+
208
+ fn mldsa65_verify ( public : & [ u8 ; 1952 ] , digest : & [ u8 ] , signature : & [ u8 ; 3309 ] )
209
+ -> Result < bool >
210
+ {
211
+ use openssl:: pkey_ml_dsa:: { PKeyMlDsaBuilder , Variant } ;
212
+ use openssl:: signature:: Signature ;
213
+
214
+ let key = PKeyMlDsaBuilder :: < Public > :: new (
215
+ Variant :: MlDsa65 , public, None ) ?
216
+ . build ( ) ?;
217
+ let mut algo = Signature :: for_ml_dsa ( Variant :: MlDsa65 ) ?;
218
+
219
+ let mut ctx = PkeyCtx :: new ( & key) ?;
220
+ ctx. verify_message_init ( & mut algo) ?;
221
+ Ok ( ctx. verify ( digest, & signature[ ..] ) ?)
222
+ }
223
+
224
+ fn mldsa87_generate_key ( ) -> Result < ( Protected , Box < [ u8 ; 2592 ] > ) > {
225
+ use openssl:: pkey_ml_dsa:: { PKeyMlDsaBuilder , PKeyMlDsaParams , Variant } ;
226
+
227
+ let key = PKeyMlDsaBuilder :: < Private > :: new_generate ( Variant :: MlDsa87 ) ?
228
+ . generate ( ) ?;
229
+ let public_params = PKeyMlDsaParams :: < Public > :: from_pkey ( & key) ?;
230
+ let secret_params = PKeyMlDsaParams :: < Private > :: from_pkey ( & key) ?;
231
+
232
+ let mut secret = Protected :: from ( vec ! [ 0 ; 32 ] ) ;
233
+ let mut public = Box :: new ( [ 0 ; 2592 ] ) ;
234
+ debug_assert_eq ! ( secret. len( ) , secret_params. private_key_seed( ) ?. len( ) ) ;
235
+ debug_assert_eq ! ( public. len( ) , public_params. public_key( ) ?. len( ) ) ;
236
+ secret[ ..] . copy_from_slice ( secret_params. private_key_seed ( ) ?) ;
237
+ public[ ..] . copy_from_slice ( public_params. public_key ( ) ?) ;
238
+
239
+ Ok ( ( secret, public) )
240
+ }
241
+
242
+ fn mldsa87_sign ( secret : & Protected , digest : & [ u8 ] )
243
+ -> Result < Box < [ u8 ; 4627 ] > >
244
+ {
245
+ use openssl:: pkey_ml_dsa:: { PKeyMlDsaBuilder , Variant } ;
246
+ use openssl:: signature:: Signature ;
247
+
248
+ let key = PKeyMlDsaBuilder :: < Private > :: from_seed (
249
+ Variant :: MlDsa87 , secret. as_ref ( ) ) ?
250
+ . build ( ) ?;
251
+ let mut algo = Signature :: for_ml_dsa ( Variant :: MlDsa87 ) ?;
252
+
253
+ let mut ctx = PkeyCtx :: new ( & key) ?;
254
+ ctx. sign_message_init ( & mut algo) ?;
255
+ let mut signature = Box :: new ( [ 0 ; 4627 ] ) ;
256
+ let len = ctx. sign ( digest, Some ( & mut signature[ ..] ) ) ?;
257
+ debug_assert_eq ! ( len, signature. len( ) ) ;
258
+
259
+ Ok ( signature)
260
+ }
261
+
262
+ fn mldsa87_verify ( public : & [ u8 ; 2592 ] , digest : & [ u8 ] , signature : & [ u8 ; 4627 ] )
263
+ -> Result < bool >
264
+ {
265
+ use openssl:: pkey_ml_dsa:: { PKeyMlDsaBuilder , Variant } ;
266
+ use openssl:: signature:: Signature ;
267
+
268
+ let key = PKeyMlDsaBuilder :: < Public > :: new (
269
+ Variant :: MlDsa87 , public, None ) ?
270
+ . build ( ) ?;
271
+ let mut algo = Signature :: for_ml_dsa ( Variant :: MlDsa87 ) ?;
272
+
273
+ let mut ctx = PkeyCtx :: new ( & key) ?;
274
+ ctx. verify_message_init ( & mut algo) ?;
275
+ Ok ( ctx. verify ( digest, & signature[ ..] ) ?)
276
+ }
277
+
168
278
fn dsa_generate_key ( p_bits : usize )
169
279
-> Result < ( MPI , MPI , MPI , MPI , ProtectedMPI ) >
170
280
{
0 commit comments