@@ -539,6 +539,42 @@ impl Pk {
539
539
Ok ( ret)
540
540
}
541
541
542
+ /// Decrypt using a custom label.
543
+ ///
544
+ /// This function may only be called on an RSA key with its padding set to RSA_PKCS_V21.
545
+ pub fn decrypt_with_label < F : Random > (
546
+ & mut self ,
547
+ cipher : & [ u8 ] ,
548
+ plain : & mut [ u8 ] ,
549
+ rng : & mut F ,
550
+ label : & [ u8 ] ,
551
+ ) -> Result < usize > {
552
+ if self . pk_type ( ) != Type :: Rsa {
553
+ return Err ( Error :: PkTypeMismatch ) ;
554
+ }
555
+ let ctx = self . inner . pk_ctx as * mut rsa_context ;
556
+ if unsafe { ( * ctx) . padding != RSA_PKCS_V21 } {
557
+ return Err ( Error :: RsaInvalidPadding ) ;
558
+ }
559
+
560
+ let mut ret = 0usize ;
561
+ unsafe {
562
+ rsa_rsaes_oaep_decrypt (
563
+ ctx,
564
+ Some ( F :: call) ,
565
+ rng. data_ptr ( ) ,
566
+ RSA_PRIVATE ,
567
+ label. as_ptr ( ) ,
568
+ label. len ( ) ,
569
+ & mut ret,
570
+ cipher. as_ptr ( ) ,
571
+ plain. as_mut_ptr ( ) ,
572
+ plain. len ( ) ,
573
+ ) . into_result ( ) ?;
574
+ }
575
+ Ok ( ret)
576
+ }
577
+
542
578
pub fn encrypt < F : Random > (
543
579
& mut self ,
544
580
plain : & [ u8 ] ,
@@ -562,6 +598,44 @@ impl Pk {
562
598
Ok ( ret)
563
599
}
564
600
601
+ /// Encrypt using a custom label.
602
+ ///
603
+ /// This function may only be called on an RSA key with its padding set to RSA_PKCS_V21.
604
+ pub fn encrypt_with_label < F : Random > (
605
+ & mut self ,
606
+ plain : & [ u8 ] ,
607
+ cipher : & mut [ u8 ] ,
608
+ rng : & mut F ,
609
+ label : & [ u8 ] ,
610
+ ) -> Result < usize > {
611
+ if self . pk_type ( ) != Type :: Rsa {
612
+ return Err ( Error :: PkTypeMismatch ) ;
613
+ }
614
+ let ctx = self . inner . pk_ctx as * mut rsa_context ;
615
+ if unsafe { ( * ctx) . padding != RSA_PKCS_V21 } {
616
+ return Err ( Error :: RsaInvalidPadding ) ;
617
+ }
618
+ let olen = self . len ( ) / 8 ;
619
+ if cipher. len ( ) < olen {
620
+ return Err ( Error :: RsaOutputTooLarge ) ;
621
+ }
622
+
623
+ unsafe {
624
+ rsa_rsaes_oaep_encrypt (
625
+ ctx,
626
+ Some ( F :: call) ,
627
+ rng. data_ptr ( ) ,
628
+ RSA_PUBLIC ,
629
+ label. as_ptr ( ) ,
630
+ label. len ( ) ,
631
+ plain. len ( ) ,
632
+ plain. as_ptr ( ) ,
633
+ cipher. as_mut_ptr ( )
634
+ ) . into_result ( ) ?;
635
+ }
636
+ Ok ( olen)
637
+ }
638
+
565
639
/// Sign the hash `hash` of type `md`, placing the signature in `sig`. `rng` must be a
566
640
/// cryptographically secure RNG.
567
641
///
@@ -1129,6 +1203,34 @@ iy6KC991zzvaWY/Ys+q/84Afqa+0qJKQnPuy/7F5GkVdQA/lfbhi
1129
1203
) ;
1130
1204
}
1131
1205
1206
+ #[ test]
1207
+ fn rsa_encrypt_decrypt_with_label ( ) {
1208
+ let mut pk = Pk :: from_private_key ( TEST_DER , None ) . unwrap ( ) ;
1209
+ let mut cipher = [ 0u8 ; 2048 / 8 ] ;
1210
+ // set raw decryption padding mode
1211
+ pk. set_options ( Options :: Rsa {
1212
+ padding : RsaPadding :: Pkcs1V21 { mgf : MdType :: Sha256 }
1213
+ } ) ;
1214
+
1215
+ let plain = b"testing123" ;
1216
+ let cipher_len = pk. encrypt_with_label ( plain, & mut cipher,
1217
+ & mut crate :: test_support:: rand:: test_rng ( ) ,
1218
+ b"MY_LABEL" ) . unwrap ( ) ;
1219
+ assert_eq ! ( cipher_len, cipher. len( ) ) ;
1220
+
1221
+ let mut plain_decrypted = [ 0u8 ; 10 ] ;
1222
+ let plain_len = pk. decrypt_with_label ( & cipher, & mut plain_decrypted,
1223
+ & mut crate :: test_support:: rand:: test_rng ( ) ,
1224
+ b"MY_LABEL" ) . unwrap ( ) ;
1225
+ assert_eq ! ( plain_len, plain. len( ) ) ;
1226
+ assert_eq ! ( & plain_decrypted, plain) ;
1227
+
1228
+ assert_eq ! ( pk. decrypt_with_label( & cipher, & mut plain_decrypted,
1229
+ & mut crate :: test_support:: rand:: test_rng( ) ,
1230
+ b"WRONG_LABEL" ) . unwrap_err( ) ,
1231
+ Error :: RsaInvalidPadding ) ;
1232
+ }
1233
+
1132
1234
#[ test]
1133
1235
fn rsa_sign_with_none_padding ( ) {
1134
1236
let mut pk =
0 commit comments