use crate::internal_alloc::Vec;
use noxtls_core::{Error, Result};
use super::{hmac_sha256, hmac_sha384, sha256, sha384, Digest, Sha256};
#[derive(Debug, Clone, Default)]
pub struct TlsTranscriptSha256 {
hasher: Sha256,
}
impl TlsTranscriptSha256 {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn update(&mut self, message: &[u8]) {
self.hasher.update(message);
}
#[must_use]
pub fn snapshot_hash(&self) -> [u8; 32] {
let digest = self.hasher.clone().finalize();
let mut out = [0_u8; 32];
out.copy_from_slice(&digest);
out
}
}
#[derive(Debug, Clone, Default)]
pub struct TlsTranscriptSha384 {
transcript: Vec<u8>,
}
impl TlsTranscriptSha384 {
#[must_use]
pub fn new() -> Self {
Self::default()
}
pub fn update(&mut self, message: &[u8]) {
self.transcript.extend_from_slice(message);
}
#[must_use]
pub fn snapshot_hash(&self) -> [u8; 48] {
sha384(&self.transcript)
}
}
pub fn tls12_prf_sha256(secret: &[u8], label: &[u8], seed: &[u8], len: usize) -> Result<Vec<u8>> {
if secret.is_empty() {
return Err(Error::InvalidLength("tls12 prf secret must not be empty"));
}
if len == 0 {
return Ok(Vec::new());
}
let mut label_seed = Vec::with_capacity(label.len() + seed.len());
label_seed.extend_from_slice(label);
label_seed.extend_from_slice(seed);
let mut a = hmac_sha256(secret, &label_seed);
let mut out = Vec::with_capacity(len);
while out.len() < len {
let mut block_input = Vec::with_capacity(a.len() + label_seed.len());
block_input.extend_from_slice(&a);
block_input.extend_from_slice(&label_seed);
out.extend_from_slice(&hmac_sha256(secret, &block_input));
a = hmac_sha256(secret, &a);
}
out.truncate(len);
Ok(out)
}
pub fn tls12_prf_sha384(secret: &[u8], label: &[u8], seed: &[u8], len: usize) -> Result<Vec<u8>> {
if secret.is_empty() {
return Err(Error::InvalidLength("tls12 prf secret must not be empty"));
}
if len == 0 {
return Ok(Vec::new());
}
let mut label_seed = Vec::with_capacity(label.len() + seed.len());
label_seed.extend_from_slice(label);
label_seed.extend_from_slice(seed);
let mut a = hmac_sha384(secret, &label_seed);
let mut out = Vec::with_capacity(len);
while out.len() < len {
let mut block_input = Vec::with_capacity(a.len() + label_seed.len());
block_input.extend_from_slice(&a);
block_input.extend_from_slice(&label_seed);
out.extend_from_slice(&hmac_sha384(secret, &block_input));
a = hmac_sha384(secret, &a);
}
out.truncate(len);
Ok(out)
}
pub fn tls12_finished_verify_data_sha256(
master_secret: &[u8],
finished_label: &[u8],
transcript: &[u8],
) -> Result<[u8; 12]> {
let hash = sha256(transcript);
let verify = tls12_prf_sha256(master_secret, finished_label, &hash, 12)?;
let mut out = [0_u8; 12];
out.copy_from_slice(&verify);
Ok(out)
}
pub fn tls12_finished_verify_data_sha384(
master_secret: &[u8],
finished_label: &[u8],
transcript: &[u8],
) -> Result<[u8; 12]> {
let hash = sha384(transcript);
let verify = tls12_prf_sha384(master_secret, finished_label, &hash, 12)?;
let mut out = [0_u8; 12];
out.copy_from_slice(&verify);
Ok(out)
}