@@ -696,6 +696,67 @@ impl<T> PkeyCtxRef<T> {
696696 Ok ( ( ) )
697697 }
698698
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+
699760 /// Derives a shared secret between two keys.
700761 ///
701762 /// 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==
11071168 assert_eq ! ( output, expected_output) ;
11081169 assert ! ( ErrorStack :: get( ) . errors( ) . is_empty( ) ) ;
11091170 }
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+ }
11101217}
0 commit comments