Skip to content

Commit

Permalink
Fix 1600 byte ROM size regression in #684
Browse files Browse the repository at this point in the history
When callers from separate crates call a large generic function like
verify_lms_signature_cfi(), rustc 1.70 may build multiple versions
(depending on optimizer heuristics), even when all the generic
parameters are identical. This is bad, as it can bloat the binary and
the second copy violates the FIPS requirements that the same machine
code be used for the KAT as the actual implementation. To defend against
it, we provide a non-generic function that production firmware should
call instead.
  • Loading branch information
korran committed Aug 30, 2023
1 parent 6734392 commit 8c49288
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 8 deletions.
51 changes: 47 additions & 4 deletions drivers/src/lms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,12 +379,12 @@ impl Lms {

/// Note: Use this function only if glitch protection is not needed.
/// If glitch protection is needed, use `verify_lms_signature_cfi` instead.
pub fn verify_lms_signature<const N: usize, const P: usize, const H: usize>(
pub fn verify_lms_signature(
&self,
sha256_driver: &mut Sha256,
input_string: &[u8],
lms_public_key: &LmsPublicKey<N>,
lms_sig: &LmsSignature<N, P, H>,
lms_public_key: &LmsPublicKey<6>,
lms_sig: &LmsSignature<6, 51, 15>,
) -> CaliptraResult<LmsResult> {
let mut candidate_key =
self.verify_lms_signature_cfi(sha256_driver, input_string, lms_public_key, lms_sig)?;
Expand All @@ -397,7 +397,50 @@ impl Lms {
result
}

pub fn verify_lms_signature_cfi<const N: usize, const P: usize, const H: usize>(
/// Note: Use this function only if glitch protection is not needed.
/// If glitch protection is needed, use `verify_lms_signature_cfi_generic` instead.
pub fn verify_lms_signature_generic<const N: usize, const P: usize, const H: usize>(
&self,
sha256_driver: &mut Sha256,
input_string: &[u8],
lms_public_key: &LmsPublicKey<N>,
lms_sig: &LmsSignature<N, P, H>,
) -> CaliptraResult<LmsResult> {
let mut candidate_key = self.verify_lms_signature_cfi_generic(
sha256_driver,
input_string,
lms_public_key,
lms_sig,
)?;
let result = if candidate_key != HashValue::from(lms_public_key.digest) {
Ok(LmsResult::SigVerifyFailed)
} else {
Ok(LmsResult::Success)
};
candidate_key.0.fill(0);
result
}

// When callers from separate crates call a function like
// verify_lms_signature_cfi_generic(), Rustc 1.70
// may build multiple versions (depending on optimizer heuristics), even when all the
// generic parameters are identical. This is bad, as it can bloat the binary and the
// second copy violates the FIPS requirements that the same machine code be used for the
// KAT as the actual implementation. To defend against it, we provide this non-generic
// function that production firmware should call instead.
#[inline(never)]
pub fn verify_lms_signature_cfi(
&self,
sha256_driver: &mut Sha256,
input_string: &[u8],
lms_public_key: &LmsPublicKey<6>,
lms_sig: &LmsSignature<6, 51, 15>,
) -> CaliptraResult<HashValue<6>> {
self.verify_lms_signature_cfi_generic(sha256_driver, input_string, lms_public_key, lms_sig)
}

#[inline(always)]
pub fn verify_lms_signature_cfi_generic<const N: usize, const P: usize, const H: usize>(
&self,
sha256_driver: &mut Sha256,
input_string: &[u8],
Expand Down
6 changes: 3 additions & 3 deletions drivers/test-fw/src/bin/lms_32_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,12 +551,12 @@ fn test_lms_lower_32() {
};

let final_result = Lms::default()
.verify_lms_signature(&mut sha256, &MESSAGE, &LMS_PUBLIC_KEY, &FINAL_LMS_SIG)
.verify_lms_signature_generic(&mut sha256, &MESSAGE, &LMS_PUBLIC_KEY, &FINAL_LMS_SIG)
.unwrap();
assert_eq!(final_result, LmsResult::Success);

let candidate_key = Lms::default()
.verify_lms_signature_cfi(&mut sha256, &MESSAGE, &LMS_PUBLIC_KEY, &FINAL_LMS_SIG)
.verify_lms_signature_cfi_generic(&mut sha256, &MESSAGE, &LMS_PUBLIC_KEY, &FINAL_LMS_SIG)
.unwrap();
assert_eq!(candidate_key, HashValue::from(LMS_PUBLIC_KEY.digest));
}
Expand Down Expand Up @@ -815,7 +815,7 @@ fn test_hss_upper_32() {
};

let result = Lms::default()
.verify_lms_signature(
.verify_lms_signature_generic(
&mut sha256,
&PUBLIC_BUFFER,
&HSS_PUBLIC_KEY,
Expand Down
2 changes: 1 addition & 1 deletion drivers/test-fw/src/bin/negative_tests_lms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ fn test_failures_lms_24() {
);

assert_eq!(
Lms::default().verify_lms_signature(
Lms::default().verify_lms_signature_generic(
&mut sha256,
&MESSAGE,
&LmsPublicKey {
Expand Down

0 comments on commit 8c49288

Please sign in to comment.