@@ -36,8 +36,9 @@ impl Asymmetric for super::Backend {
36
36
// XXX: Would be better to have a runtime test.
37
37
MLDSA65_Ed25519 | MLDSA87_Ed448 =>
38
38
openssl:: version:: number ( ) >= 0x3_05_00_00_0 ,
39
+ // XXX: Would be better to have a runtime test.
39
40
SLHDSA128s | SLHDSA128f | SLHDSA256s =>
40
- false ,
41
+ openssl :: version :: number ( ) >= 0x3_05_00_00_0 ,
41
42
MLKEM768_X25519 | MLKEM1024_X448 =>
42
43
false ,
43
44
ElGamalEncrypt | ElGamalEncryptSign |
@@ -275,6 +276,168 @@ impl Asymmetric for super::Backend {
275
276
Ok ( ctx. verify ( digest, & signature[ ..] ) ?)
276
277
}
277
278
279
+ fn slhdsa128s_generate_key ( ) -> Result < ( Protected , [ u8 ; 32 ] ) > {
280
+ use openssl:: pkey_slh_dsa:: { PKeySlhDsaBuilder , PKeySlhDsaParams , Variant } ;
281
+
282
+ let key = PKeySlhDsaBuilder :: < Private > :: new_generate ( Variant :: SlhDsaShake128s ) ?
283
+ . generate ( ) ?;
284
+ let public_params = PKeySlhDsaParams :: < Public > :: from_pkey ( & key) ?;
285
+ let secret_params = PKeySlhDsaParams :: < Private > :: from_pkey ( & key) ?;
286
+
287
+ let mut secret = Protected :: from ( vec ! [ 0 ; 64 ] ) ;
288
+ let mut public = [ 0 ; 32 ] ;
289
+ debug_assert_eq ! ( secret. len( ) , secret_params. private_key_seed( ) ?. len( ) ) ;
290
+ debug_assert_eq ! ( public. len( ) , public_params. public_key( ) ?. len( ) ) ;
291
+ secret[ ..] . copy_from_slice ( secret_params. private_key_seed ( ) ?) ;
292
+ public[ ..] . copy_from_slice ( public_params. public_key ( ) ?) ;
293
+
294
+ Ok ( ( secret, public) )
295
+ }
296
+
297
+ fn slhdsa128s_sign ( secret : & Protected , digest : & [ u8 ] )
298
+ -> Result < Box < [ u8 ; 7856 ] > >
299
+ {
300
+ use openssl:: pkey_slh_dsa:: { PKeySlhDsaBuilder , Variant } ;
301
+ use openssl:: signature:: Signature ;
302
+
303
+ let key = PKeySlhDsaBuilder :: < Private > :: new_private (
304
+ Variant :: SlhDsaShake128s , secret. as_ref ( ) ) ?
305
+ . build ( ) ?;
306
+ let mut algo = Signature :: for_slh_dsa ( Variant :: SlhDsaShake128s ) ?;
307
+
308
+ let mut ctx = PkeyCtx :: new ( & key) ?;
309
+ ctx. sign_message_init ( & mut algo) ?;
310
+ let mut signature: Box < [ u8 ; 7856 ] > = vec ! [ 0 ; 7856 ] . try_into ( ) . unwrap ( ) ;
311
+ let len = ctx. sign ( digest, Some ( & mut signature[ ..] ) ) ?;
312
+ debug_assert_eq ! ( len, signature. len( ) ) ;
313
+
314
+ Ok ( signature)
315
+ }
316
+
317
+ fn slhdsa128s_verify ( public : & [ u8 ; 32 ] , digest : & [ u8 ] , signature : & [ u8 ; 7856 ] )
318
+ -> Result < bool >
319
+ {
320
+ use openssl:: pkey_slh_dsa:: { PKeySlhDsaBuilder , Variant } ;
321
+ use openssl:: signature:: Signature ;
322
+
323
+ let key = PKeySlhDsaBuilder :: < Public > :: new_public (
324
+ Variant :: SlhDsaShake128s , public) ?
325
+ . build ( ) ?;
326
+ let mut algo = Signature :: for_slh_dsa ( Variant :: SlhDsaShake128s ) ?;
327
+
328
+ let mut ctx = PkeyCtx :: new ( & key) ?;
329
+ ctx. verify_message_init ( & mut algo) ?;
330
+ Ok ( ctx. verify ( digest, & signature[ ..] ) ?)
331
+ }
332
+
333
+ fn slhdsa128f_generate_key ( ) -> Result < ( Protected , [ u8 ; 32 ] ) > {
334
+ use openssl:: pkey_slh_dsa:: { PKeySlhDsaBuilder , PKeySlhDsaParams , Variant } ;
335
+
336
+ let key = PKeySlhDsaBuilder :: < Private > :: new_generate ( Variant :: SlhDsaShake128f ) ?
337
+ . generate ( ) ?;
338
+ let public_params = PKeySlhDsaParams :: < Public > :: from_pkey ( & key) ?;
339
+ let secret_params = PKeySlhDsaParams :: < Private > :: from_pkey ( & key) ?;
340
+
341
+ let mut secret = Protected :: from ( vec ! [ 0 ; 64 ] ) ;
342
+ let mut public = [ 0 ; 32 ] ;
343
+ debug_assert_eq ! ( secret. len( ) , secret_params. private_key_seed( ) ?. len( ) ) ;
344
+ debug_assert_eq ! ( public. len( ) , public_params. public_key( ) ?. len( ) ) ;
345
+ secret[ ..] . copy_from_slice ( secret_params. private_key_seed ( ) ?) ;
346
+ public[ ..] . copy_from_slice ( public_params. public_key ( ) ?) ;
347
+
348
+ Ok ( ( secret, public) )
349
+ }
350
+
351
+ fn slhdsa128f_sign ( secret : & Protected , digest : & [ u8 ] )
352
+ -> Result < Box < [ u8 ; 17088 ] > >
353
+ {
354
+ use openssl:: pkey_slh_dsa:: { PKeySlhDsaBuilder , Variant } ;
355
+ use openssl:: signature:: Signature ;
356
+
357
+ let key = PKeySlhDsaBuilder :: < Private > :: new_private (
358
+ Variant :: SlhDsaShake128f , secret. as_ref ( ) ) ?
359
+ . build ( ) ?;
360
+ let mut algo = Signature :: for_slh_dsa ( Variant :: SlhDsaShake128f ) ?;
361
+
362
+ let mut ctx = PkeyCtx :: new ( & key) ?;
363
+ ctx. sign_message_init ( & mut algo) ?;
364
+ let mut signature: Box < [ u8 ; 17088 ] > = vec ! [ 0 ; 17088 ] . try_into ( ) . unwrap ( ) ;
365
+ let len = ctx. sign ( digest, Some ( & mut signature[ ..] ) ) ?;
366
+ debug_assert_eq ! ( len, signature. len( ) ) ;
367
+
368
+ Ok ( signature)
369
+ }
370
+
371
+ fn slhdsa128f_verify ( public : & [ u8 ; 32 ] , digest : & [ u8 ] , signature : & [ u8 ; 17088 ] )
372
+ -> Result < bool >
373
+ {
374
+ use openssl:: pkey_slh_dsa:: { PKeySlhDsaBuilder , Variant } ;
375
+ use openssl:: signature:: Signature ;
376
+
377
+ let key = PKeySlhDsaBuilder :: < Public > :: new_public (
378
+ Variant :: SlhDsaShake128f , public) ?
379
+ . build ( ) ?;
380
+ let mut algo = Signature :: for_slh_dsa ( Variant :: SlhDsaShake128f ) ?;
381
+
382
+ let mut ctx = PkeyCtx :: new ( & key) ?;
383
+ ctx. verify_message_init ( & mut algo) ?;
384
+ Ok ( ctx. verify ( digest, & signature[ ..] ) ?)
385
+ }
386
+
387
+ fn slhdsa256s_generate_key ( ) -> Result < ( Protected , Box < [ u8 ; 64 ] > ) > {
388
+ use openssl:: pkey_slh_dsa:: { PKeySlhDsaBuilder , PKeySlhDsaParams , Variant } ;
389
+
390
+ let key = PKeySlhDsaBuilder :: < Private > :: new_generate ( Variant :: SlhDsaShake256s ) ?
391
+ . generate ( ) ?;
392
+ let public_params = PKeySlhDsaParams :: < Public > :: from_pkey ( & key) ?;
393
+ let secret_params = PKeySlhDsaParams :: < Private > :: from_pkey ( & key) ?;
394
+
395
+ let mut secret = Protected :: from ( vec ! [ 0 ; 64 ] ) ;
396
+ let mut public = Box :: new ( [ 0 ; 64 ] ) ;
397
+ debug_assert_eq ! ( secret. len( ) , secret_params. private_key_seed( ) ?. len( ) ) ;
398
+ debug_assert_eq ! ( public. len( ) , public_params. public_key( ) ?. len( ) ) ;
399
+ secret[ ..] . copy_from_slice ( secret_params. private_key_seed ( ) ?) ;
400
+ public[ ..] . copy_from_slice ( public_params. public_key ( ) ?) ;
401
+
402
+ Ok ( ( secret, public) )
403
+ }
404
+
405
+ fn slhdsa256s_sign ( secret : & Protected , digest : & [ u8 ] )
406
+ -> Result < Box < [ u8 ; 29792 ] > >
407
+ {
408
+ use openssl:: pkey_slh_dsa:: { PKeySlhDsaBuilder , Variant } ;
409
+ use openssl:: signature:: Signature ;
410
+
411
+ let key = PKeySlhDsaBuilder :: < Private > :: new_private (
412
+ Variant :: SlhDsaShake256s , secret. as_ref ( ) ) ?
413
+ . build ( ) ?;
414
+ let mut algo = Signature :: for_slh_dsa ( Variant :: SlhDsaShake256s ) ?;
415
+
416
+ let mut ctx = PkeyCtx :: new ( & key) ?;
417
+ ctx. sign_message_init ( & mut algo) ?;
418
+ let mut signature: Box < [ u8 ; 29792 ] > = vec ! [ 0 ; 29792 ] . try_into ( ) . unwrap ( ) ;
419
+ let len = ctx. sign ( digest, Some ( & mut signature[ ..] ) ) ?;
420
+ debug_assert_eq ! ( len, signature. len( ) ) ;
421
+
422
+ Ok ( signature)
423
+ }
424
+
425
+ fn slhdsa256s_verify ( public : & [ u8 ; 64 ] , digest : & [ u8 ] , signature : & [ u8 ; 29792 ] )
426
+ -> Result < bool >
427
+ {
428
+ use openssl:: pkey_slh_dsa:: { PKeySlhDsaBuilder , Variant } ;
429
+ use openssl:: signature:: Signature ;
430
+
431
+ let key = PKeySlhDsaBuilder :: < Public > :: new_public (
432
+ Variant :: SlhDsaShake256s , public) ?
433
+ . build ( ) ?;
434
+ let mut algo = Signature :: for_slh_dsa ( Variant :: SlhDsaShake256s ) ?;
435
+
436
+ let mut ctx = PkeyCtx :: new ( & key) ?;
437
+ ctx. verify_message_init ( & mut algo) ?;
438
+ Ok ( ctx. verify ( digest, & signature[ ..] ) ?)
439
+ }
440
+
278
441
fn dsa_generate_key ( p_bits : usize )
279
442
-> Result < ( MPI , MPI , MPI , MPI , ProtectedMPI ) >
280
443
{
0 commit comments