Skip to content

Commit

Permalink
refactor: use tls prf from tls-core in rc backend (#413)
Browse files Browse the repository at this point in the history
* refactor: use tls prf from tls-core in rc backend

* clippy
  • Loading branch information
sinui0 authored Jan 17, 2024
1 parent 6bf4e87 commit 5c4da33
Showing 1 changed file with 43 additions and 102 deletions.
145 changes: 43 additions & 102 deletions components/tls/tls-client/src/backend/standard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ use p256::{ecdh::EphemeralSecret, EncodedPoint, PublicKey as ECDHPublicKey};
use rand::{rngs::OsRng, thread_rng, Rng};

use digest::Digest;
use hmac::{Hmac, Mac};
use sha2::Sha256;
use std::{any::Any, convert::TryInto};
use tls_core::{
cert::ServerCertDetails,
Expand All @@ -22,54 +20,10 @@ use tls_core::{
handshake::Random,
message::{OpaqueMessage, PlainMessage},
},
prf::prf,
suites::{self, SupportedCipherSuite},
};

type HmacSha256 = Hmac<Sha256>;

pub(crate) fn hmac_sha256(key: &[u8], input: &[u8]) -> [u8; 32] {
let mut mac = HmacSha256::new_from_slice(key).unwrap();
mac.update(input);
let out = mac.finalize().into_bytes();
out[..32]
.try_into()
.expect("expected output to be 32 bytes")
}

pub(crate) fn seed_ms(client_random: &[u8; 32], server_random: &[u8; 32]) -> [u8; 77] {
let mut seed = [0u8; 77];
seed[..13].copy_from_slice(b"master secret");
seed[13..45].copy_from_slice(client_random);
seed[45..].copy_from_slice(server_random);
seed
}

pub(crate) fn seed_ke(client_random: &[u8; 32], server_random: &[u8; 32]) -> [u8; 77] {
let mut seed = [0u8; 77];
seed[..13].copy_from_slice(b"key expansion");
seed[13..45].copy_from_slice(server_random);
seed[45..].copy_from_slice(client_random);
seed
}

pub(crate) fn seed_cf(handshake_blob: &[u8]) -> [u8; 47] {
let mut hasher = Sha256::new();
hasher.update(handshake_blob);
let mut seed = [0u8; 47];
seed[..15].copy_from_slice(b"client finished");
seed[15..].copy_from_slice(hasher.finalize().as_slice());
seed
}

pub(crate) fn seed_sf(handshake_blob: &[u8]) -> [u8; 47] {
let mut hasher = Sha256::new();
hasher.update(handshake_blob);
let mut seed = [0u8; 47];
seed[..15].copy_from_slice(b"server finished");
seed[15..].copy_from_slice(hasher.finalize().as_slice());
seed
}

/// Implementation of TLS backend using RustCrypto primitives
pub struct RustCryptoBackend {
client_random: Option<Random>,
Expand Down Expand Up @@ -115,17 +69,18 @@ impl RustCryptoBackend {

/// Expands the handshake hash and master secret into verify_data for
/// the Server_Finished
pub fn verify_data_sf_tls12(&mut self, hs_hash: &[u8], ms: &[u8; 48]) -> [u8; 12] {
let mut seed = [0u8; 47];
seed[..15].copy_from_slice(b"server finished");
seed[15..].copy_from_slice(hs_hash);
let a1 = hmac_sha256(ms, &seed);
let mut a1_seed = [0u8; 79];
a1_seed[..32].copy_from_slice(&a1);
a1_seed[32..].copy_from_slice(&seed);
let mut verify_data = [0u8; 12];
verify_data.copy_from_slice(&hmac_sha256(ms, &a1_seed)[..12]);
verify_data
pub fn verify_data_sf_tls12(&self, hs_hash: &[u8], ms: &[u8; 48]) -> [u8; 12] {
let mut vd = [0u8; 12];
prf(&mut vd, ms, b"server finished", hs_hash).expect("key length is valid");
vd
}

/// Expands the handshake hash and master secret into verify_data for
/// the Client_Finished
pub fn verify_data_cf_tls12(&self, hs_hash: &[u8], ms: &[u8; 48]) -> [u8; 12] {
let mut vd = [0u8; 12];
prf(&mut vd, ms, b"client finished", hs_hash).expect("key length is valid");
vd
}

/// Expands pre-master secret into session key using TLS 1.2 PRF
Expand All @@ -137,53 +92,26 @@ impl RustCryptoBackend {
pms: &[u8],
) -> ([u8; 48], [u8; 40]) {
// first expand pms into ms
let seed = seed_ms(client_random, server_random);
let a1 = hmac_sha256(pms, &seed);
let a2 = hmac_sha256(pms, &a1);
let mut a1_seed = [0u8; 109];
a1_seed[..32].copy_from_slice(&a1);
a1_seed[32..].copy_from_slice(&seed);
let mut a2_seed = [0u8; 109];
a2_seed[..32].copy_from_slice(&a2);
a2_seed[32..].copy_from_slice(&seed);
let p1 = hmac_sha256(pms, &a1_seed);
let p2 = hmac_sha256(pms, &a2_seed);
let mut ms = [0u8; 48];
ms[..32].copy_from_slice(&p1);
ms[32..].copy_from_slice(&p2[..16]);
let ms_out = ms;
prf(
&mut ms,
pms,
b"master secret",
&concat::<64>(client_random, server_random),
)
.expect("key length is valid");

// expand ms into session keys
let seed = seed_ke(client_random, server_random);
let a1 = hmac_sha256(&ms, &seed);
let a2 = hmac_sha256(&ms, &a1);
let mut a1_seed = [0u8; 109];
a1_seed[..32].copy_from_slice(&a1);
a1_seed[32..].copy_from_slice(&seed);
let mut a2_seed = [0u8; 109];
a2_seed[..32].copy_from_slice(&a2);
a2_seed[32..].copy_from_slice(&seed);
let p1 = hmac_sha256(&ms, &a1_seed);
let p2 = hmac_sha256(&ms, &a2_seed);
let mut ek = [0u8; 40];
ek[..32].copy_from_slice(&p1);
ek[32..].copy_from_slice(&p2[..8]);
(ms_out, ek)
}

/// Expands the handshake hash and master secret into verify_data for
/// the Client_Finished
pub fn verify_data_cf_tls12(&mut self, hs_hash: &[u8], ms: &[u8; 48]) -> [u8; 12] {
let mut seed = [0u8; 47];
seed[..15].copy_from_slice(b"client finished");
seed[15..].copy_from_slice(hs_hash);
let a1 = hmac_sha256(ms, &seed);
let mut a1_seed = [0u8; 79];
a1_seed[..32].copy_from_slice(&a1);
a1_seed[32..].copy_from_slice(&seed);
let mut verify_data = [0u8; 12];
verify_data.copy_from_slice(&hmac_sha256(ms, &a1_seed)[..12]);
verify_data
let mut session_keys = [0u8; 40];
prf(
&mut session_keys,
&ms,
b"key expansion",
&concat::<64>(server_random, client_random),
)
.expect("key length is valid");

(ms, session_keys)
}

fn set_encrypter(&mut self) -> Result<(), BackendError> {
Expand Down Expand Up @@ -477,6 +405,19 @@ impl Backend for RustCryptoBackend {
}
}

/// Concatenates two slices into a new array.
///
/// # Panics
///
/// Panics if the size of the output array is not equal to the sum of the sizes of the input slices.
fn concat<const O: usize>(left: &[u8], right: &[u8]) -> [u8; O] {
assert_eq!(left.len() + right.len(), O);
let mut out = [0u8; O];
out[..left.len()].copy_from_slice(left);
out[left.len()..].copy_from_slice(right);
out
}

pub struct Encrypter {
write_key: [u8; 16],
write_iv: [u8; 4],
Expand Down

0 comments on commit 5c4da33

Please sign in to comment.