Avoid exposing secret key material in TLS 1.3 unless actually logging.

This adds a (small) performance penalty for key logging in favor of
clearer encapsulation of key material and improved performance due to
at least one fewer heap allocation.
This commit is contained in:
Brian Smith 2019-07-26 10:36:33 -10:00 committed by ctz
parent 1d99471355
commit 0d66123f9c
2 changed files with 15 additions and 4 deletions

View File

@ -94,10 +94,12 @@ impl KeySchedule {
key_log: &dyn KeyLog, log_label: &str, client_random: &[u8; 32])
-> hkdf::Prk
{
let secret = self.derive::<PayloadU8, _>(PayloadU8Len(self.algorithm.len()), kind, hs_hash)
.into_inner();
key_log.log(log_label, client_random, &secret);
hkdf::Prk::new_less_safe(self.algorithm, &secret)
if key_log.will_log(log_label) {
let secret = self.derive::<PayloadU8, _>(PayloadU8Len(self.algorithm.len()), kind, hs_hash)
.into_inner();
key_log.log(log_label, client_random, &secret);
}
self.derive(self.algorithm, kind, hs_hash)
}
/// Derive a secret of given `kind` using the hash of the empty string

View File

@ -40,6 +40,13 @@ pub trait KeyLog : Send + Sync {
/// These strings are selected to match the NSS key log format:
/// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format
fn log(&self, label: &str, client_random: &[u8], secret: &[u8]);
/// Indicates whether the secret with label `label` will be logged.
///
/// If `will_log` returns true then `log` will be called with the secret.
/// Otherwise, `log` will not be called for the secret. This is a
/// performance optimization.
fn will_log(&self, _label: &str) -> bool { true }
}
/// KeyLog that does exactly nothing.
@ -47,6 +54,8 @@ pub struct NoKeyLog;
impl KeyLog for NoKeyLog {
fn log(&self, _: &str, _: &[u8], _: &[u8]) {}
#[inline]
fn will_log(&self, _label: &str) -> bool { false }
}
// Internal mutable state for KeyLogFile