Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding ECC error checking during waits #1610

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions FROZEN_IMAGES.sha384sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# WARNING: Do not update this file without the approval of the Caliptra TAC
e3c62ff9b5ca7873001e516a22b62a3090bc470ddb4664ac6feef2ebabb0b65d880a5a38ff31b5250817a39c79d3a68e caliptra-rom-no-log.bin
cefa26982b60ad32595053ef8e516137642a7760434481b1fe4371b4fbaeeb1528b15e8523f8d8c2c9cc9d5920fe9e9b caliptra-rom-with-log.bin
5a97c3e30c2ceaad209745367a5dfd583e6a0ad4f43a6f4254c03d6e929db671c26ac6ffe738a843b98684761f2241b4 caliptra-rom-no-log.bin
8b08a1ce76fd8411bee31c9453c16ab841e3c6ae5716c10a08bb6891f233523e2bd3b263b73e83aa54e6545ab35322fb caliptra-rom-with-log.bin
44 changes: 35 additions & 9 deletions drivers/src/ecc384.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use crate::{
};
#[cfg(not(feature = "no-cfi"))]
use caliptra_cfi_derive::cfi_impl_fn;
use caliptra_registers::ecc::EccReg;
use caliptra_registers::ecc::{EccReg, RegisterBlock};
use core::cmp::Ordering;
use zerocopy::{AsBytes, FromBytes};
use zeroize::Zeroize;
Expand Down Expand Up @@ -182,6 +182,32 @@ impl Ecc384 {
false
}

// Wait on the provided condition OR the error condition defined in this function
// In the event of the error condition being set, clear the error bits and return an error
fn wait<F>(regs: RegisterBlock<ureg::RealMmioMut>, condition: F) -> CaliptraResult<()>
where
F: Fn() -> bool,
{
let err_condition = || {
(u32::from(regs.intr_block_rf().error_global_intr_r().read()) != 0)
|| (u32::from(regs.intr_block_rf().error_internal_intr_r().read()) != 0)
};

// Wait for either the given condition or the error condition
wait::until(|| (condition() || err_condition()));

if err_condition() {
// Clear the errors
// error_global_intr_r is RO
regs.intr_block_rf()
.error_internal_intr_r()
.write(|_| u32::from(regs.intr_block_rf().error_internal_intr_r().read()).into());
return Err(CaliptraError::DRIVER_ECC384_HW_ERROR);
}

Ok(())
}

/// Generate ECC-384 Key Pair
///
/// # Arguments
Expand All @@ -206,7 +232,7 @@ impl Ecc384 {
let mut priv_key = priv_key;

// Wait for hardware ready
wait::until(|| ecc.status().read().ready());
Ecc384::wait(ecc, || ecc.status().read().ready())?;

// Configure hardware to route keys to user specified hardware blocks
match &mut priv_key {
Expand Down Expand Up @@ -245,7 +271,7 @@ impl Ecc384 {
ecc.ctrl().write(|w| w.ctrl(|w| w.keygen()));

// Wait for command to complete
wait::until(|| ecc.status().read().valid());
Ecc384::wait(ecc, || ecc.status().read().valid())?;

// Copy the private key
match &mut priv_key {
Expand Down Expand Up @@ -290,7 +316,7 @@ impl Ecc384 {
let ecc = self.ecc.regs_mut();

// Wait for hardware ready
wait::until(|| ecc.status().read().ready());
Ecc384::wait(ecc, || ecc.status().read().ready())?;

// Generate an IV.
let iv = trng.generate()?;
Expand All @@ -299,7 +325,7 @@ impl Ecc384 {
ecc.ctrl().write(|w| w.pcr_sign(true).ctrl(|w| w.signing()));

// Wait for command to complete
wait::until(|| ecc.status().read().valid());
Ecc384::wait(ecc, || ecc.status().read().valid())?;

// Copy signature
let signature = Ecc384Signature {
Expand All @@ -322,7 +348,7 @@ impl Ecc384 {
let ecc = self.ecc.regs_mut();

// Wait for hardware ready
wait::until(|| ecc.status().read().ready());
Ecc384::wait(ecc, || ecc.status().read().ready())?;

// Copy private key
match priv_key {
Expand All @@ -344,7 +370,7 @@ impl Ecc384 {
ecc.ctrl().write(|w| w.ctrl(|w| w.signing()));

// Wait for command to complete
wait::until(|| ecc.status().read().valid());
Ecc384::wait(ecc, || ecc.status().read().valid())?;

// Copy signature
let signature = Ecc384Signature {
Expand Down Expand Up @@ -455,7 +481,7 @@ impl Ecc384 {
let ecc = self.ecc.regs_mut();

// Wait for hardware ready
wait::until(|| ecc.status().read().ready());
Ecc384::wait(ecc, || ecc.status().read().ready())?;

// Copy public key to registers
pub_key.x.write_to_reg(ecc.pubkey_x());
Expand All @@ -472,7 +498,7 @@ impl Ecc384 {
ecc.ctrl().write(|w| w.ctrl(|w| w.verifying()));

// Wait for command to complete
wait::until(|| ecc.status().read().valid());
Ecc384::wait(ecc, || ecc.status().read().valid())?;

// Copy the random value
let verify_r = Array4x12::read_from_reg(ecc.verify_r());
Expand Down
1 change: 1 addition & 0 deletions error/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ impl CaliptraError {
pub const DRIVER_ECC384_SCALAR_RANGE_CHECK_FAILED: CaliptraError =
CaliptraError::new_const(0x0005000f);
pub const DRIVER_ECC384_KEYGEN_BAD_USAGE: CaliptraError = CaliptraError::new_const(0x00050010);
pub const DRIVER_ECC384_HW_ERROR: CaliptraError = CaliptraError::new_const(0x00050011);

pub const DRIVER_KV_ERASE_USE_LOCK_SET_FAILURE: CaliptraError =
CaliptraError::new_const(0x00060001);
Expand Down
29 changes: 29 additions & 0 deletions runtime/tests/runtime_integration_tests/test_ecdsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,3 +248,32 @@ fn test_ecdsa_verify_bad_chksum() {
resp,
);
}

// HW errors are not supported on the SW emulator yet
#[cfg(any(feature = "verilator", feature = "fpga_realtime"))]
#[test]
fn test_ecdsa_hw_failure() {
let mut model = run_rt_test(None, None, None);

let mut cmd = MailboxReq::EcdsaVerify(EcdsaVerifyReq {
hdr: MailboxReqHeader { chksum: 0 },
pub_key_x: [0u8; 48],
pub_key_y: [0u8; 48],
signature_r: [0xa5u8; 48],
signature_s: [0xa5u8; 48],
});
cmd.populate_chksum().unwrap();

let resp = model
.mailbox_execute(
u32::from(CommandId::ECDSA384_VERIFY),
cmd.as_bytes().unwrap(),
)
.unwrap_err();

assert_error(
&mut model,
caliptra_drivers::CaliptraError::DRIVER_ECC384_HW_ERROR,
resp,
);
}
10 changes: 10 additions & 0 deletions sw-emulator/lib/periph/src/asym_ecc384.rs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,14 @@ pub struct AsymEcc384 {
#[register(offset = 0x0000_0614)]
key_write_status: ReadOnlyRegister<u32, KeyWriteStatus::Register>,

/// Error Global Intr register
#[register(offset = 0x0000_080c)]
error_global_intr: ReadOnlyRegister<u32>,

/// Error Internal Intr register
#[register(offset = 0x0000_0814)]
error_internal_intr: ReadOnlyRegister<u32>,

/// Key Vault
key_vault: KeyVault,

Expand Down Expand Up @@ -272,6 +280,8 @@ impl AsymEcc384 {
op_key_read_complete_action: None,
op_seed_read_complete_action: None,
op_key_write_complete_action: None,
error_global_intr: ReadOnlyRegister::new(0),
error_internal_intr: ReadOnlyRegister::new(0),
}
}

Expand Down
Loading