Skip to content

Commit

Permalink
[feat] Change Ecc384.verify API to return error codes instead of a bool.
Browse files Browse the repository at this point in the history
These error codes have good hamming distances. This is being done to prevent glitching attacks.
  • Loading branch information
mhatrevi committed Jul 27, 2023
1 parent aa9b5ed commit 012e20c
Show file tree
Hide file tree
Showing 20 changed files with 116 additions and 78 deletions.
21 changes: 17 additions & 4 deletions drivers/src/ecc384.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ use zerocopy::{AsBytes, FromBytes};
/// ECC-384 Coordinate
pub type Ecc384Scalar = Array4x12;

#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Ecc384Result {
Success = 0xAAAAAAAA,
SigVerifyFailed = 0x55555555,
}

/// ECC-384 Seed
#[derive(Debug, Copy, Clone)]
pub enum Ecc384Seed<'a> {
Expand Down Expand Up @@ -309,19 +316,21 @@ impl Ecc384 {
/// * `pub_key` - Public key
/// * `digest` - digest to verify
/// * `signature` - Signature to verify
///
///
/// # Result
///
/// * `bool` - True if the signature verification passed else false
/// * `Ecc384Result` - Ecc384Result::Success if the signature verification passed else an error code.
pub fn verify(
&mut self,
pub_key: &Ecc384PubKey,
digest: &Ecc384Scalar,
signature: &Ecc384Signature,
) -> CaliptraResult<bool> {
) -> CaliptraResult<Ecc384Result> {
// If R or S are not in the range [1, N-1], signature check must fail
if !Self::scalar_range_check(&signature.r) || !Self::scalar_range_check(&signature.s) {
return Ok(false);
return Ok(Ecc384Result::SigVerifyFailed);
}

let ecc = self.ecc.regs_mut();
Expand Down Expand Up @@ -350,7 +359,11 @@ impl Ecc384 {
let verify_r = Array4x12::read_from_reg(ecc.verify_r());

// compare the hardware generate `r` with one in signature
let result = verify_r == signature.r;
let result = if verify_r == signature.r {
Ecc384Result::Success
} else {
Ecc384Result::SigVerifyFailed
};

self.zeroize_internal();

Expand Down
8 changes: 4 additions & 4 deletions drivers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ pub use data_vault::{
};
pub use doe::DeobfuscationEngine;
pub use ecc384::{
Ecc384, Ecc384PrivKeyIn, Ecc384PrivKeyOut, Ecc384PubKey, Ecc384Scalar, Ecc384Seed,
Ecc384Signature,
Ecc384, Ecc384PrivKeyIn, Ecc384PrivKeyOut, Ecc384PubKey, Ecc384Result, Ecc384Scalar,
Ecc384Seed, Ecc384Signature,
};
pub use error_reporter::{report_fw_error_fatal, report_fw_error_non_fatal};
pub use exit_ctrl::ExitCtrl;
Expand All @@ -65,8 +65,8 @@ pub use hmac384_kdf::hmac384_kdf;
pub use key_vault::{KeyId, KeyUsage, KeyVault};
pub use kv_access::{KeyReadArgs, KeyWriteArgs};
pub use lms::{
get_lmots_parameters, get_lms_parameters, HashValue, Lms, Sha192Digest, Sha256Digest, D_INTR,
D_LEAF, D_MESG, D_PBLC,
get_lmots_parameters, get_lms_parameters, HashValue, Lms, LmsResult, Sha192Digest,
Sha256Digest, D_INTR, D_LEAF, D_MESG, D_PBLC,
};
pub use mailbox::{Mailbox, MailboxRecvTxn, MailboxSendTxn};
pub use okref::okmutref;
Expand Down
13 changes: 10 additions & 3 deletions drivers/src/lms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ pub struct Lms {}
pub type Sha256Digest = HashValue<8>;
pub type Sha192Digest = HashValue<6>;

#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LmsResult {
Success = 0xCCCCCCCC,
SigVerifyFailed = 0x33333333,
}

#[repr(transparent)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct HashValue<const N: usize>(pub [u32; N]);
Expand Down Expand Up @@ -376,7 +383,7 @@ impl Lms {
input_string: &[u8],
lms_public_key: &LmsPublicKey<N>,
lms_sig: &LmsSignature<N, P, H>,
) -> CaliptraResult<bool> {
) -> CaliptraResult<LmsResult> {
if lms_sig.ots.ots_type != lms_public_key.otstype {
return Err(CaliptraError::DRIVER_LMS_SIGNATURE_LMOTS_DOESNT_MATCH_PUBKEY_LMOTS);
}
Expand Down Expand Up @@ -458,10 +465,10 @@ impl Lms {
}
let candidate_key = &temp;
if *candidate_key != HashValue::from(lms_public_key.digest) {
return Ok(false);
return Ok(LmsResult::SigVerifyFailed);
}
digest.0.fill(0);
temp.0.fill(0);
Ok(true)
Ok(LmsResult::Success)
}
}
12 changes: 6 additions & 6 deletions drivers/test-fw/src/bin/ecc384_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ Abstract:
#![no_main]

use caliptra_drivers::{
Array4x12, Ecc384, Ecc384PrivKeyIn, Ecc384PrivKeyOut, Ecc384PubKey, Ecc384Scalar, Ecc384Seed,
KeyId, KeyReadArgs, KeyUsage, KeyWriteArgs, Trng,
Array4x12, Ecc384, Ecc384PrivKeyIn, Ecc384PrivKeyOut, Ecc384PubKey, Ecc384Result, Ecc384Scalar,
Ecc384Seed, KeyId, KeyReadArgs, KeyUsage, KeyWriteArgs, Trng,
};
use caliptra_kat::Ecc384Kat;
use caliptra_registers::csrng::CsrngReg;
Expand Down Expand Up @@ -195,7 +195,7 @@ fn test_verify() {
};
let result = ecc.verify(&pub_key, &Ecc384Scalar::from(digest), &signature);
assert!(result.is_ok());
assert!(result.unwrap());
assert_eq!(result.unwrap(), Ecc384Result::Success);
}

fn test_verify_failure() {
Expand Down Expand Up @@ -224,7 +224,7 @@ fn test_verify_failure() {
let hash = [0xFFu8; 48];
let result = ecc.verify(&pub_key, &Ecc384Scalar::from(hash), &signature);
assert!(result.is_ok());
assert!(!result.unwrap());
assert_eq!(result.unwrap(), Ecc384Result::SigVerifyFailed);
}

fn test_kv_seed_from_input_msg_from_input() {
Expand Down Expand Up @@ -278,7 +278,7 @@ fn test_kv_seed_from_input_msg_from_input() {
};
let result = ecc.verify(&pub_key, &Ecc384Scalar::from(digest), &signature);
assert!(result.is_ok());
assert!(result.unwrap());
assert_eq!(result.unwrap(), Ecc384Result::Success);
}

fn test_kv_seed_from_kv_msg_from_input() {
Expand Down Expand Up @@ -397,7 +397,7 @@ fn test_kv_seed_from_kv_msg_from_input() {
y: pub_key_y.into(),
};
let result = ecc.verify(&pub_key, &Ecc384Scalar::from(msg), &signature);
assert!(result.is_ok());
assert_eq!(result.unwrap(), Ecc384Result::Success);
}

fn test_kat() {
Expand Down
6 changes: 3 additions & 3 deletions drivers/test-fw/src/bin/lms_24_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Abstract:
#![no_std]
#![no_main]

use caliptra_drivers::{get_lms_parameters, HashValue, Lms, Sha256};
use caliptra_drivers::{get_lms_parameters, HashValue, Lms, LmsResult, Sha256};
use caliptra_lms_types::{
bytes_to_words_6, LmotsAlgorithmType, LmotsSignature, LmsAlgorithmType, LmsIdentifier,
LmsPublicKey, LmsSignature,
Expand Down Expand Up @@ -405,10 +405,10 @@ fn test_lms_24_height_15() {
otstype: LMOTS_TYPE,
};

let success = Lms::default()
let result = Lms::default()
.verify_lms_signature(&mut sha256, &MESSAGE, &LMS_PUBLIC_KEY, &LMS_SIG)
.unwrap();
assert_eq!(success, true);
assert_eq!(result, LmsResult::Success);
}

test_suite! {
Expand Down
8 changes: 4 additions & 4 deletions drivers/test-fw/src/bin/lms_32_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Abstract:
#![no_std]
#![no_main]

use caliptra_drivers::{HashValue, Lms, Sha256};
use caliptra_drivers::{HashValue, Lms, LmsResult, Sha256};
use caliptra_lms_types::{
bytes_to_words_8, LmotsAlgorithmType, LmotsSignature, LmsAlgorithmType, LmsPublicKey,
LmsSignature,
Expand Down Expand Up @@ -553,7 +553,7 @@ fn test_lms_lower_32() {
let final_result = Lms::default()
.verify_lms_signature(&mut sha256, &MESSAGE, &LMS_PUBLIC_KEY, &FINAL_LMS_SIG)
.unwrap();
assert_eq!(final_result, true);
assert_eq!(final_result, LmsResult::Success);
}

// from https://www.rfc-editor.org/rfc/rfc8554#page-49
Expand Down Expand Up @@ -809,15 +809,15 @@ fn test_hss_upper_32() {
otstype: LmotsAlgorithmType::LmotsSha256N32W8,
};

let success = Lms::default()
let result = Lms::default()
.verify_lms_signature(
&mut sha256,
&PUBLIC_BUFFER,
&HSS_PUBLIC_KEY,
&UPPER_SIGNATURE,
)
.unwrap();
assert_eq!(success, true);
assert_eq!(result, LmsResult::Success);
}

test_suite! {
Expand Down
26 changes: 13 additions & 13 deletions drivers/test-fw/src/bin/negative_tests_lms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ File contains test cases for LMS signature verification using SHA256/192.
#![no_std]
#![no_main]

use caliptra_drivers::{CaliptraError, Lms, Sha256};
use caliptra_drivers::{CaliptraError, Lms, LmsResult, Sha256};
use caliptra_lms_types::{
bytes_to_words_6, LmotsAlgorithmType, LmotsSignature, LmsAlgorithmType, LmsIdentifier,
LmsPublicKey, LmsSignature,
Expand Down Expand Up @@ -333,55 +333,55 @@ fn test_failures_lms_24() {
otstype: LMOTS_TYPE,
};

let success = Lms::default()
let result = Lms::default()
.verify_lms_signature(&mut sha256, &MESSAGE, &LMS_PUBLIC_KEY, &lms_sig)
.unwrap();
assert_eq!(success, true);
assert_eq!(result, LmsResult::Success);

let new_message = "this is a different message".as_bytes();
let should_fail = Lms::default()
let result = Lms::default()
.verify_lms_signature(&mut sha256, &new_message, &LMS_PUBLIC_KEY, &lms_sig)
.unwrap();
assert_eq!(should_fail, false);
assert_ne!(result, LmsResult::Success);

let new_lms: LmsIdentifier = [0u8; 16];
let new_lms_public_key = LmsPublicKey {
id: new_lms,
..LMS_PUBLIC_KEY
};
let should_fail = Lms::default()
let result = Lms::default()
.verify_lms_signature(&mut sha256, &MESSAGE, &new_lms_public_key, &lms_sig)
.unwrap();
assert_eq!(should_fail, false);
assert_ne!(result, LmsResult::Success);

let new_q = Q + 1;
let new_lms_sig = LmsSignature {
q: new_q.into(),
..lms_sig
};
let should_fail = Lms::default()
let result = Lms::default()
.verify_lms_signature(&mut sha256, &MESSAGE, &LMS_PUBLIC_KEY, &new_lms_sig)
.unwrap();
assert_eq!(should_fail, false);
assert_ne!(result, LmsResult::Success);

let new_public_key = LmsPublicKey {
digest: [U32::ZERO; 6],
..LMS_PUBLIC_KEY
};
let should_fail = Lms::default()
let result = Lms::default()
.verify_lms_signature(&mut sha256, &MESSAGE, &new_public_key, &lms_sig)
.unwrap();
assert_eq!(should_fail, false);
assert_ne!(result, LmsResult::Success);

let new_lms_sig = LmsSignature {
tree_path: [[U32::ZERO; 6]; 15],
..lms_sig
};

let should_fail = Lms::default()
let result = Lms::default()
.verify_lms_signature(&mut sha256, &MESSAGE, &LMS_PUBLIC_KEY, &new_lms_sig)
.unwrap();
assert_eq!(should_fail, false);
assert_ne!(result, LmsResult::Success);

assert_eq!(
Lms::default().verify_lms_signature(
Expand Down
5 changes: 3 additions & 2 deletions fmc/src/flow/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use crate::fmc_env::FmcEnv;
use caliptra_common::{crypto::Ecc384KeyPair, keyids::KEY_ID_TMP};
use caliptra_drivers::{
hmac384_kdf, okref, Array4x12, Array4x5, Array4x8, CaliptraResult, Ecc384PrivKeyIn,
Ecc384PrivKeyOut, Ecc384PubKey, Ecc384Signature, KeyId, KeyReadArgs, KeyUsage, KeyWriteArgs,
Ecc384PrivKeyOut, Ecc384PubKey, Ecc384Result, Ecc384Signature, KeyId, KeyReadArgs, KeyUsage,
KeyWriteArgs,
};

pub enum Crypto {}
Expand Down Expand Up @@ -173,7 +174,7 @@ impl Crypto {
pub_key: &Ecc384PubKey,
data: &[u8],
sig: &Ecc384Signature,
) -> CaliptraResult<bool> {
) -> CaliptraResult<Ecc384Result> {
let digest = Self::sha384_digest(env, data);
let digest = okref(&digest)?;
env.ecc384.verify(pub_key, digest, sig)
Expand Down
4 changes: 2 additions & 2 deletions fmc/src/flow/rt_alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use caliptra_common::crypto::Ecc384KeyPair;
use caliptra_common::keyids::{KEY_ID_RT_CDI, KEY_ID_RT_PRIV_KEY, KEY_ID_TMP};
use caliptra_common::HexBytes;
use caliptra_drivers::{
okref, report_boot_status, CaliptraError, CaliptraResult, KeyId, ResetReason,
okref, report_boot_status, CaliptraError, CaliptraResult, Ecc384Result, KeyId, ResetReason,
};
use caliptra_x509::{NotAfter, NotBefore, RtAliasCertTbs, RtAliasCertTbsParams};

Expand Down Expand Up @@ -292,7 +292,7 @@ impl RtAliasLayer {
cprintln!("[alias rt] SIG.S = {}", HexBytes(&_sig_s));

// Verify the signature of the `To Be Signed` portion
if !Crypto::ecdsa384_verify(env, auth_pub_key, tbs.tbs(), sig)? {
if Crypto::ecdsa384_verify(env, auth_pub_key, tbs.tbs(), sig)? != Ecc384Result::Success {
return Err(CaliptraError::FMC_RT_ALIAS_CERT_VERIFY);
}

Expand Down
4 changes: 2 additions & 2 deletions image/verify/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,15 @@ pub trait ImageVerificationEnv {
digest: &ImageDigest,
pub_key: &ImageEccPubKey,
sig: &ImageEccSignature,
) -> CaliptraResult<bool>;
) -> CaliptraResult<Ecc384Result>;

/// Perform LMS Verification
fn lms_verify(
&mut self,
digest: &ImageDigest,
pub_key: &ImageLmsPublicKey,
sig: &ImageLmsSignature,
) -> CaliptraResult<bool>;
) -> CaliptraResult<LmsResult>;

/// Get Vendor Public Key Digest
fn vendor_pub_key_digest(&self) -> ImageDigest;
Expand Down
Loading

0 comments on commit 012e20c

Please sign in to comment.