@@ -39,8 +39,9 @@ impl Asymmetric for super::Backend {
39
39
// XXX: Would be better to have a runtime test.
40
40
SLHDSA128s | SLHDSA128f | SLHDSA256s =>
41
41
openssl:: version:: number ( ) >= 0x3_05_00_00_0 ,
42
+ // XXX: Would be better to have a runtime test.
42
43
MLKEM768_X25519 | MLKEM1024_X448 =>
43
- false ,
44
+ openssl :: version :: number ( ) >= 0x3_05_00_00_0 ,
44
45
ElGamalEncrypt | ElGamalEncryptSign |
45
46
Private ( _) | Unknown ( _)
46
47
=> false ,
@@ -438,6 +439,129 @@ impl Asymmetric for super::Backend {
438
439
Ok ( ctx. verify ( digest, & signature[ ..] ) ?)
439
440
}
440
441
442
+ fn mlkem768_generate_key ( ) -> Result < ( Protected , Box < [ u8 ; 1184 ] > ) > {
443
+ use openssl:: pkey_ml_kem:: { PKeyMlKemBuilder , PKeyMlKemParams , Variant } ;
444
+
445
+ let key = PKeyMlKemBuilder :: < Private > :: new_generate ( Variant :: MlKem768 ) ?
446
+ . generate ( ) ?;
447
+ let key_params = PKeyMlKemParams :: < Private > :: from_pkey ( & key) ?;
448
+
449
+ let mut secret = Protected :: from ( vec ! [ 0 ; 64 ] ) ;
450
+ let mut public = Box :: new ( [ 0 ; 1184 ] ) ;
451
+ debug_assert_eq ! ( secret. len( ) , key_params. private_key_seed( ) ?. len( ) ) ;
452
+ debug_assert_eq ! ( public. len( ) , key_params. public_key( ) ?. len( ) ) ;
453
+ secret[ ..] . copy_from_slice ( key_params. private_key_seed ( ) ?) ;
454
+ public[ ..] . copy_from_slice ( key_params. public_key ( ) ?) ;
455
+
456
+ Ok ( ( secret, public) )
457
+ }
458
+
459
+ fn mlkem768_encapsulate ( public : & [ u8 ; 1184 ] )
460
+ -> Result < ( Box < [ u8 ; 1088 ] > , Protected ) >
461
+ {
462
+ use openssl:: pkey_ml_kem:: { PKeyMlKemBuilder , Variant } ;
463
+
464
+ let key = PKeyMlKemBuilder :: < Public > :: new (
465
+ Variant :: MlKem768 , public, None ) ?
466
+ . build ( ) ?;
467
+
468
+ let mut ciphertext = Box :: new ( [ 0 ; 1088 ] ) ;
469
+ let mut keyshare = Protected :: from ( vec ! [ 0 ; 32 ] ) ;
470
+
471
+ let mut ctx = PkeyCtx :: new ( & key) ?;
472
+ ctx. encapsulate_init ( ) ?;
473
+ let ( l0, l1) = ctx. encapsulate ( Some ( & mut ciphertext[ ..] ) ,
474
+ Some ( & mut keyshare) ) ?;
475
+
476
+ debug_assert_eq ! ( l0, ciphertext. len( ) ) ;
477
+ debug_assert_eq ! ( l1, keyshare. len( ) ) ;
478
+ Ok ( ( ciphertext, keyshare) )
479
+ }
480
+
481
+ fn mlkem768_decapsulate ( secret : & Protected ,
482
+ ciphertext : & [ u8 ; 1088 ] )
483
+ -> Result < Protected >
484
+ {
485
+ use openssl:: pkey_ml_kem:: { PKeyMlKemBuilder , Variant } ;
486
+
487
+ let key = PKeyMlKemBuilder :: < Private > :: from_seed (
488
+ Variant :: MlKem768 , secret. as_ref ( ) ) ?
489
+ . build ( ) ?;
490
+
491
+ let mut ctx = PkeyCtx :: new ( & key) ?;
492
+ ctx. decapsulate_init ( ) ?;
493
+ let len = ctx. decapsulate ( & ciphertext[ ..] , None ) ?;
494
+ let mut keyshare = Protected :: from ( vec ! [ 0 ; len] ) ;
495
+ let len = ctx. decapsulate ( & ciphertext[ ..] , Some ( & mut keyshare[ ..] ) ) ?;
496
+
497
+ // Shouldn't happen, but better safe than sorry.
498
+ if len != keyshare. len ( ) {
499
+ let mut k = Protected :: from ( vec ! [ 0 ; len] ) ;
500
+ k[ ..] . copy_from_slice ( & keyshare[ ..len] ) ;
501
+ keyshare = k;
502
+ }
503
+
504
+ Ok ( keyshare)
505
+ }
506
+
507
+ fn mlkem1024_generate_key ( ) -> Result < ( Protected , Box < [ u8 ; 1568 ] > ) > {
508
+ use openssl:: pkey_ml_kem:: { PKeyMlKemBuilder , PKeyMlKemParams , Variant } ;
509
+
510
+ let key = PKeyMlKemBuilder :: < Private > :: new_generate ( Variant :: MlKem1024 ) ?
511
+ . generate ( ) ?;
512
+ let key_params = PKeyMlKemParams :: < Private > :: from_pkey ( & key) ?;
513
+
514
+ let mut secret = Protected :: from ( vec ! [ 0 ; 64 ] ) ;
515
+ let mut public = Box :: new ( [ 0 ; 1568 ] ) ;
516
+ debug_assert_eq ! ( secret. len( ) , key_params. private_key_seed( ) ?. len( ) ) ;
517
+ debug_assert_eq ! ( public. len( ) , key_params. public_key( ) ?. len( ) ) ;
518
+ secret[ ..] . copy_from_slice ( key_params. private_key_seed ( ) ?) ;
519
+ public[ ..] . copy_from_slice ( key_params. public_key ( ) ?) ;
520
+
521
+ Ok ( ( secret, public) )
522
+ }
523
+
524
+ fn mlkem1024_encapsulate ( public : & [ u8 ; 1568 ] )
525
+ -> Result < ( Box < [ u8 ; 1568 ] > , Protected ) >
526
+ {
527
+ use openssl:: pkey_ml_kem:: { PKeyMlKemBuilder , Variant } ;
528
+
529
+ let key = PKeyMlKemBuilder :: < Public > :: new (
530
+ Variant :: MlKem1024 , public, None ) ?
531
+ . build ( ) ?;
532
+
533
+ let mut ciphertext = Box :: new ( [ 0 ; 1568 ] ) ;
534
+ let mut keyshare = Protected :: from ( vec ! [ 0 ; 32 ] ) ;
535
+
536
+ let mut ctx = PkeyCtx :: new ( & key) ?;
537
+ ctx. encapsulate_init ( ) ?;
538
+ let ( l0, l1) = ctx. encapsulate ( Some ( & mut ciphertext[ ..] ) ,
539
+ Some ( & mut keyshare) ) ?;
540
+
541
+ debug_assert_eq ! ( l0, ciphertext. len( ) ) ;
542
+ debug_assert_eq ! ( l1, keyshare. len( ) ) ;
543
+ Ok ( ( ciphertext, keyshare) )
544
+ }
545
+
546
+ fn mlkem1024_decapsulate ( secret : & Protected ,
547
+ ciphertext : & [ u8 ; 1568 ] )
548
+ -> Result < Protected >
549
+ {
550
+ use openssl:: pkey_ml_kem:: { PKeyMlKemBuilder , Variant } ;
551
+
552
+ let key = PKeyMlKemBuilder :: < Private > :: from_seed (
553
+ Variant :: MlKem1024 , secret. as_ref ( ) ) ?
554
+ . build ( ) ?;
555
+
556
+ let mut ctx = PkeyCtx :: new ( & key) ?;
557
+ ctx. decapsulate_init ( ) ?;
558
+ let mut keyshare = Protected :: from ( vec ! [ 0 ; 32 ] ) ;
559
+ let len = ctx. decapsulate ( & ciphertext[ ..] , Some ( & mut keyshare[ ..] ) ) ?;
560
+ debug_assert_eq ! ( len, keyshare. len( ) ) ;
561
+
562
+ Ok ( keyshare)
563
+ }
564
+
441
565
fn dsa_generate_key ( p_bits : usize )
442
566
-> Result < ( MPI , MPI , MPI , MPI , ProtectedMPI ) >
443
567
{
0 commit comments