@@ -696,6 +696,67 @@ impl<T> PkeyCtxRef<T> {
696
696
Ok ( ( ) )
697
697
}
698
698
699
+ /// Sets the digest used for TLS1 PRF derivation.
700
+ ///
701
+ /// Requires OpenSSL 1.1.0 or newer.
702
+ #[ corresponds( EVP_PKEY_CTX_set_tls1_prf_md ) ]
703
+ #[ cfg( ossl110) ]
704
+ #[ inline]
705
+ pub fn set_tls1_prf_md ( & mut self , digest : & MdRef ) -> Result < ( ) , ErrorStack > {
706
+ unsafe {
707
+ cvt ( ffi:: EVP_PKEY_CTX_set_tls1_prf_md (
708
+ self . as_ptr ( ) ,
709
+ digest. as_ptr ( ) ,
710
+ ) ) ?;
711
+ }
712
+
713
+ Ok ( ( ) )
714
+ }
715
+
716
+ /// Sets the secret value for TLS PRF derivation.
717
+ ///
718
+ /// Any existing secret value is replaced and any seed is reset.
719
+ ///
720
+ /// Requires OpenSSL 1.1.0 or newer.
721
+ #[ corresponds( EVP_PKEY_CTX_set1_tls1_prf_secret ) ]
722
+ #[ cfg( ossl110) ]
723
+ #[ inline]
724
+ pub fn set_tls1_prf_secret ( & mut self , secret : & [ u8 ] ) -> Result < ( ) , ErrorStack > {
725
+ let len = c_int:: try_from ( secret. len ( ) ) . unwrap ( ) ;
726
+
727
+ unsafe {
728
+ cvt ( ffi:: EVP_PKEY_CTX_set1_tls1_prf_secret (
729
+ self . as_ptr ( ) ,
730
+ secret. as_ptr ( ) ,
731
+ len,
732
+ ) ) ?;
733
+ }
734
+
735
+ Ok ( ( ) )
736
+ }
737
+
738
+ /// Adds a seed for TLS PRF derivation.
739
+ ///
740
+ /// If a seed is already set, the new seed is appended to the existing seed.
741
+ ///
742
+ /// Requires OpenSSL 1.1.0 or newer.
743
+ #[ corresponds( EVP_PKEY_CTX_add1_tls1_prf_seed ) ]
744
+ #[ cfg( ossl110) ]
745
+ #[ inline]
746
+ pub fn add_tls1_prf_seed ( & mut self , seed : & [ u8 ] ) -> Result < ( ) , ErrorStack > {
747
+ let len = c_int:: try_from ( seed. len ( ) ) . unwrap ( ) ;
748
+
749
+ unsafe {
750
+ cvt ( ffi:: EVP_PKEY_CTX_add1_tls1_prf_seed (
751
+ self . as_ptr ( ) ,
752
+ seed. as_ptr ( ) ,
753
+ len,
754
+ ) ) ?;
755
+ }
756
+
757
+ Ok ( ( ) )
758
+ }
759
+
699
760
/// Derives a shared secret between two keys.
700
761
///
701
762
/// If `buf` is set to `None`, an upper bound on the number of bytes required for the buffer will be returned.
@@ -1107,4 +1168,50 @@ mxJ7imIrEg9nIQ==
1107
1168
assert_eq ! ( output, expected_output) ;
1108
1169
assert ! ( ErrorStack :: get( ) . errors( ) . is_empty( ) ) ;
1109
1170
}
1171
+
1172
+ #[ test]
1173
+ #[ cfg( ossl111) ]
1174
+ fn tls1_prf_sha256 ( ) {
1175
+ // SHA256 PRF test vectors from https://mailarchive.ietf.org/arch/msg/tls/fzVCzk-z3FShgGJ6DOXqM1ydxms/
1176
+ let mut ctx = PkeyCtx :: new_id ( Id :: TLS1_PRF ) . unwrap ( ) ;
1177
+ ctx. derive_init ( ) . unwrap ( ) ;
1178
+ ctx. set_tls1_prf_md ( Md :: sha256 ( ) ) . unwrap ( ) ;
1179
+ ctx. set_tls1_prf_secret ( & hex:: decode ( "9bbe436ba940f017b17652849a71db35" ) . unwrap ( ) )
1180
+ . unwrap ( ) ;
1181
+ ctx. add_tls1_prf_seed ( & hex:: decode ( "74657374206c6162656c" ) . unwrap ( ) )
1182
+ . unwrap ( ) ;
1183
+ ctx. add_tls1_prf_seed ( & hex:: decode ( "a0ba9f936cda311827a6f796ffd5198c" ) . unwrap ( ) )
1184
+ . unwrap ( ) ;
1185
+ let mut out = [ 0u8 ; 100 ] ;
1186
+ ctx. derive ( Some ( & mut out) ) . unwrap ( ) ;
1187
+
1188
+ assert_eq ! (
1189
+ & out[ ..] ,
1190
+ hex:: decode( "e3f229ba727be17b8d122620557cd453c2aab21d07c3d495329b52d4e61edb5a6b301791e90d35c9c9a46b4e14baf9af0fa022f7077def17abfd3797c0564bab4fbc91666e9def9b97fce34f796789baa48082d122ee42c5a72e5a5110fff70187347b66" )
1191
+ . unwrap( )
1192
+ ) ;
1193
+ }
1194
+
1195
+ #[ test]
1196
+ #[ cfg( ossl111) ]
1197
+ fn tls1_prf_sha384 ( ) {
1198
+ // SHA384 PRF test vectors from https://mailarchive.ietf.org/arch/msg/tls/fzVCzk-z3FShgGJ6DOXqM1ydxms/
1199
+ let mut ctx = PkeyCtx :: new_id ( Id :: TLS1_PRF ) . unwrap ( ) ;
1200
+ ctx. derive_init ( ) . unwrap ( ) ;
1201
+ ctx. set_tls1_prf_md ( Md :: sha384 ( ) ) . unwrap ( ) ;
1202
+ ctx. set_tls1_prf_secret ( & hex:: decode ( "b80b733d6ceefcdc71566ea48e5567df" ) . unwrap ( ) )
1203
+ . unwrap ( ) ;
1204
+ ctx. add_tls1_prf_seed ( & hex:: decode ( "74657374206c6162656c" ) . unwrap ( ) )
1205
+ . unwrap ( ) ;
1206
+ ctx. add_tls1_prf_seed ( & hex:: decode ( "cd665cf6a8447dd6ff8b27555edb7465" ) . unwrap ( ) )
1207
+ . unwrap ( ) ;
1208
+ let mut out = [ 0u8 ; 148 ] ;
1209
+ ctx. derive ( Some ( & mut out) ) . unwrap ( ) ;
1210
+
1211
+ assert_eq ! (
1212
+ & out[ ..] ,
1213
+ hex:: decode( "7b0c18e9ced410ed1804f2cfa34a336a1c14dffb4900bb5fd7942107e81c83cde9ca0faa60be9fe34f82b1233c9146a0e534cb400fed2700884f9dc236f80edd8bfa961144c9e8d792eca722a7b32fc3d416d473ebc2c5fd4abfdad05d9184259b5bf8cd4d90fa0d31e2dec479e4f1a26066f2eea9a69236a3e52655c9e9aee691c8f3a26854308d5eaa3be85e0990703d73e56f" )
1214
+ . unwrap( )
1215
+ ) ;
1216
+ }
1110
1217
}
0 commit comments