@@ -16,42 +16,42 @@ use windows::{
1616
1717pub ( crate ) struct Prf < const HASH_SIZE : usize > ( pub ( crate ) Algorithm < HASH_SIZE > ) ;
1818
19- impl < const HASH_SIZE : usize > rustls:: crypto:: tls12:: Prf for Prf < HASH_SIZE > {
20- fn for_key_exchange (
19+ fn u32_len ( len : usize , name : & str ) -> Result < u32 , rustls:: Error > {
20+ u32:: try_from ( len) . map_err ( |_| rustls:: Error :: General ( format ! ( "{name} is too large for CNG" ) ) )
21+ }
22+
23+ impl < const HASH_SIZE : usize > Prf < HASH_SIZE > {
24+ fn try_for_secret (
2125 & self ,
22- output : & mut [ u8 ; 48 ] ,
23- kx : Box < dyn ActiveKeyExchange > ,
24- peer_pub_key : & [ u8 ] ,
26+ output : & mut [ u8 ] ,
27+ secret : & [ u8 ] ,
2528 label : & [ u8 ] ,
2629 seed : & [ u8 ] ,
2730 ) -> Result < ( ) , rustls:: Error > {
28- let secret = kx. complete ( peer_pub_key) ?;
29- self . for_secret ( output, secret. secret_bytes ( ) , label, seed) ;
30- Ok ( ( ) )
31- }
32-
33- fn for_secret ( & self , output : & mut [ u8 ] , secret : & [ u8 ] , label : & [ u8 ] , seed : & [ u8 ] ) {
3431 let mut key = Owned :: default ( ) ;
32+ let tls12_kdf = tls12_kdf ( ) ?;
3533
3634 unsafe {
37- BCryptGenerateSymmetricKey ( tls12_kdf ( ) , & mut * key, None , secret, 0 )
35+ BCryptGenerateSymmetricKey ( tls12_kdf, & mut * key, None , secret, 0 )
3836 . ok ( )
39- . unwrap ( ) ;
37+ . map_err ( |e| {
38+ rustls:: Error :: General ( format ! ( "TLS 1.2 PRF key import failed: {e}" ) )
39+ } ) ?;
4040 }
4141
4242 let buffers = [
4343 BCryptBuffer {
44- cbBuffer : label. len ( ) as u32 ,
44+ cbBuffer : u32_len ( label. len ( ) , "TLS 1.2 PRF label" ) ? ,
4545 BufferType : KDF_TLS_PRF_LABEL ,
4646 pvBuffer : label. as_ptr ( ) as * mut _ ,
4747 } ,
4848 BCryptBuffer {
49- cbBuffer : seed. len ( ) as u32 ,
49+ cbBuffer : u32_len ( seed. len ( ) , "TLS 1.2 PRF seed" ) ? ,
5050 BufferType : KDF_TLS_PRF_SEED ,
5151 pvBuffer : seed. as_ptr ( ) as * mut _ ,
5252 } ,
5353 BCryptBuffer {
54- cbBuffer : self . 0 . id_bytes . len ( ) as u32 ,
54+ cbBuffer : u32_len ( self . 0 . id_bytes . len ( ) , "TLS 1.2 PRF hash algorithm id" ) ? ,
5555 BufferType : KDF_HASH_ALGORITHM ,
5656 pvBuffer : self . 0 . id_bytes . as_ptr ( ) as * mut _ ,
5757 } ,
@@ -67,8 +67,31 @@ impl<const HASH_SIZE: usize> rustls::crypto::tls12::Prf for Prf<HASH_SIZE> {
6767 unsafe {
6868 BCryptKeyDerivation ( * key, Some ( & params) , output, & mut size, 0 )
6969 . ok ( )
70- . unwrap ( ) ;
70+ . map_err ( |e| {
71+ rustls:: Error :: General ( format ! ( "TLS 1.2 PRF derivation failed: {e}" ) )
72+ } ) ?;
7173 } ;
74+
75+ Ok ( ( ) )
76+ }
77+ }
78+
79+ impl < const HASH_SIZE : usize > rustls:: crypto:: tls12:: Prf for Prf < HASH_SIZE > {
80+ fn for_key_exchange (
81+ & self ,
82+ output : & mut [ u8 ; 48 ] ,
83+ kx : Box < dyn ActiveKeyExchange > ,
84+ peer_pub_key : & [ u8 ] ,
85+ label : & [ u8 ] ,
86+ seed : & [ u8 ] ,
87+ ) -> Result < ( ) , rustls:: Error > {
88+ let secret = kx. complete ( peer_pub_key) ?;
89+ self . try_for_secret ( output, secret. secret_bytes ( ) , label, seed)
90+ }
91+
92+ fn for_secret ( & self , output : & mut [ u8 ] , secret : & [ u8 ] , label : & [ u8 ] , seed : & [ u8 ] ) {
93+ self . try_for_secret ( output, secret, label, seed)
94+ . expect ( "rustls only calls TLS 1.2 PRF for advertised CNG-backed cipher suites" )
7295 }
7396
7497 fn fips ( & self ) -> bool {
@@ -83,7 +106,13 @@ mod test {
83106
84107 use super :: super :: hash:: { SHA256 , SHA384 } ;
85108
86- use super :: Prf ;
109+ use super :: { u32_len, Prf } ;
110+
111+ #[ test]
112+ fn cng_buffer_lengths_fit_in_u32 ( ) {
113+ assert_eq ! ( u32_len( 42 , "test" ) . unwrap( ) , 42 ) ;
114+ assert ! ( u32_len( usize :: MAX , "test" ) . is_err( ) ) ;
115+ }
87116
88117 #[ test]
89118 fn test_sha256 ( ) {
0 commit comments