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

hmac384 driver: Reload kv keys for each block #1528

Merged
merged 4 commits into from
Jul 1, 2024
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
bda2b88e54b44766775c30114b8084970c42080d2a68fa305dfcdd5fd8bcd92785ab426e5365ae466989093187572f5a caliptra-rom-no-log.bin
2f8afc38b5c861c0e6014348be0977a150d6a1fb685a31c219b589ec4b7368691f20aca2054b0b4cbfb7e3841d038ef7 caliptra-rom-with-log.bin
e3c62ff9b5ca7873001e516a22b62a3090bc470ddb4664ac6feef2ebabb0b65d880a5a38ff31b5250817a39c79d3a68e caliptra-rom-no-log.bin
cefa26982b60ad32595053ef8e516137642a7760434481b1fe4371b4fbaeeb1528b15e8523f8d8c2c9cc9d5920fe9e9b caliptra-rom-with-log.bin
129 changes: 87 additions & 42 deletions drivers/src/hmac384.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,29 +137,25 @@ impl Hmac384 {

// Configure the hardware so that the output tag is stored at a location specified by the
// caller.
match &mut tag {
Hmac384Tag::Array4x12(_arr) => {
KvAccess::begin_copy_to_arr(hmac.kv_wr_status(), hmac.kv_wr_ctrl())?
}
Hmac384Tag::Key(key) => {
KvAccess::begin_copy_to_kv(hmac.kv_wr_status(), hmac.kv_wr_ctrl(), *key)?
}
if matches!(&mut tag, Hmac384Tag::Array4x12(_)) {
KvAccess::begin_copy_to_arr(hmac.kv_wr_status(), hmac.kv_wr_ctrl())?;
}

// Configure the hardware to use key to use for the HMAC operation
match key {
Hmac384Key::Array4x12(arr) => KvAccess::copy_from_arr(arr, hmac.key())?,
Hmac384Key::Key(key) => {
KvAccess::copy_from_kv(*key, hmac.kv_rd_key_status(), hmac.kv_rd_key_ctrl())
.map_err(|err| err.into_read_key_err())?
let key = match key {
Hmac384Key::Array4x12(arr) => {
KvAccess::copy_from_arr(arr, hmac.key())?;
None
}
}
Hmac384Key::Key(key) => Some(*key),
};

// Generate an LFSR seed and copy to key vault.
self.gen_lfsr_seed(trng)?;

let op = Hmac384Op {
hmac_engine: self,
key,
state: Hmac384OpState::Init,
buf: [0u8; HMAC384_BLOCK_SIZE_BYTES],
buf_idx: 0,
Expand Down Expand Up @@ -214,38 +210,36 @@ impl Hmac384 {

// Configure the hardware so that the output tag is stored at a location specified by the
// caller.
match &mut tag {
let dest_key = match &mut tag {
Hmac384Tag::Array4x12(_arr) => {
KvAccess::begin_copy_to_arr(hmac.kv_wr_status(), hmac.kv_wr_ctrl())?
}
Hmac384Tag::Key(key) => {
KvAccess::begin_copy_to_kv(hmac.kv_wr_status(), hmac.kv_wr_ctrl(), *key)?
KvAccess::begin_copy_to_arr(hmac.kv_wr_status(), hmac.kv_wr_ctrl())?;
None
}
}
Hmac384Tag::Key(dest_key) => Some(*dest_key),
};

// Configure the hardware to use key to use for the HMAC operation
match key {
Hmac384Key::Array4x12(arr) => KvAccess::copy_from_arr(arr, hmac.key())?,
Hmac384Key::Key(key) => {
KvAccess::copy_from_kv(*key, hmac.kv_rd_key_status(), hmac.kv_rd_key_ctrl())
.map_err(|err| err.into_read_key_err())?
let key = match *key {
Hmac384Key::Array4x12(arr) => {
KvAccess::copy_from_arr(arr, hmac.key())?;
None
}
}
Hmac384Key::Key(key) => Some(key),
};
// Generate an LFSR seed and copy to key vault.
self.gen_lfsr_seed(trng)?;

// Calculate the hmac
match data {
Hmac384Data::Slice(buf) => self.hmac_buf(buf)?,
Hmac384Data::Key(key) => self.hmac_key(*key)?,
Hmac384Data::Slice(buf) => self.hmac_buf(buf, key, dest_key)?,
Hmac384Data::Key(data_key) => self.hmac_key(*data_key, key, dest_key)?,
}
let hmac = self.hmac.regs();

// Copy the tag to the specified location
let result = match &mut tag {
Hmac384Tag::Array4x12(arr) => KvAccess::end_copy_to_arr(hmac.tag(), arr),
Hmac384Tag::Key(key) => KvAccess::end_copy_to_kv(hmac.kv_wr_status(), *key)
.map_err(|err| err.into_write_tag_err()),
_ => Ok(()),
};

self.zeroize_internal();
Expand Down Expand Up @@ -280,7 +274,12 @@ impl Hmac384 {
///
/// * `buf` - Buffer to calculate the hmac over
///
fn hmac_buf(&mut self, buf: &[u8]) -> CaliptraResult<()> {
fn hmac_buf(
&mut self,
buf: &[u8],
key: Option<KeyReadArgs>,
dest_key: Option<KeyWriteArgs>,
) -> CaliptraResult<()> {
// Check if the buffer is within the size that we support
if buf.len() > HMAC384_MAX_DATA_SIZE {
return Err(CaliptraError::DRIVER_HMAC384_MAX_DATA);
Expand All @@ -298,7 +297,7 @@ impl Hmac384 {
// the panic.

if let Some(slice) = buf.get(offset..) {
self.hmac_partial_block(slice, first, buf.len())?;
self.hmac_partial_block(slice, first, buf.len(), key, dest_key)?;
break;
} else {
return Err(CaliptraError::DRIVER_HMAC384_INVALID_SLICE);
Expand All @@ -311,7 +310,7 @@ impl Hmac384 {
// the panic.
if let Some(slice) = buf.get(offset..offset + HMAC384_BLOCK_SIZE_BYTES) {
let block = <&[u8; HMAC384_BLOCK_SIZE_BYTES]>::try_from(slice).unwrap();
self.hmac_block(block, first)?;
self.hmac_block(block, first, key, dest_key)?;
bytes_remaining -= HMAC384_BLOCK_SIZE_BYTES;
first = false;
} else {
Expand All @@ -331,20 +330,27 @@ impl Hmac384 {
///
/// * `key` - Key to calculate hmac for
///
fn hmac_key(&mut self, key: KeyReadArgs) -> CaliptraResult<()> {
fn hmac_key(
&mut self,
data_key: KeyReadArgs,
key: Option<KeyReadArgs>,
dest_key: Option<KeyWriteArgs>,
) -> CaliptraResult<()> {
let hmac = self.hmac.regs_mut();

KvAccess::copy_from_kv(key, hmac.kv_rd_block_status(), hmac.kv_rd_block_ctrl())
KvAccess::copy_from_kv(data_key, hmac.kv_rd_block_status(), hmac.kv_rd_block_ctrl())
.map_err(|err| err.into_read_data_err())?;

self.hmac_op(true)
self.hmac_op(true, key, dest_key)
}

fn hmac_partial_block(
&mut self,
slice: &[u8],
first: bool,
buf_size: usize,
key: Option<KeyReadArgs>,
dest_key: Option<KeyWriteArgs>,
) -> CaliptraResult<()> {
/// Set block length
fn set_block_len(buf_size: usize, block: &mut [u8; HMAC384_BLOCK_SIZE_BYTES]) {
Expand All @@ -367,13 +373,13 @@ impl Hmac384 {
}

// Calculate the digest of the op
self.hmac_block(&block, first)?;
self.hmac_block(&block, first, key, dest_key)?;

// Add a padding block if one is needed
if slice.len() >= HMAC384_BLOCK_LEN_OFFSET {
block.fill(0);
set_block_len(buf_size, &mut block);
self.hmac_block(&block, false)?;
self.hmac_block(&block, false, key, dest_key)?;
}

Ok(())
Expand All @@ -391,10 +397,12 @@ impl Hmac384 {
&mut self,
block: &[u8; HMAC384_BLOCK_SIZE_BYTES],
first: bool,
key: Option<KeyReadArgs>,
dest_key: Option<KeyWriteArgs>,
) -> CaliptraResult<()> {
let hmac384 = self.hmac.regs_mut();
Array4x32::from(block).write_to_reg(hmac384.block());
self.hmac_op(first)
self.hmac_op(first, key, dest_key)
}

///
Expand All @@ -404,9 +412,22 @@ impl Hmac384 {
///
/// * `first` - Flag indicating if this is the first block
///
fn hmac_op(&mut self, first: bool) -> CaliptraResult<()> {
fn hmac_op(
&mut self,
first: bool,
key: Option<KeyReadArgs>,
dest_key: Option<KeyWriteArgs>,
) -> CaliptraResult<()> {
let hmac = self.hmac.regs_mut();

if let Some(key) = key {
KvAccess::copy_from_kv(key, hmac.kv_rd_key_status(), hmac.kv_rd_key_ctrl())
.map_err(|err| err.into_read_key_err())?
};
if let Some(dest_key) = dest_key {
KvAccess::begin_copy_to_kv(hmac.kv_wr_status(), hmac.kv_wr_ctrl(), dest_key)?;
}

// Wait for the hardware to be ready
wait::until(|| hmac.status().read().ready());

Expand All @@ -421,6 +442,11 @@ impl Hmac384 {
// Wait for the hmac operation to finish
wait::until(|| hmac.status().read().valid());

if let Some(dest_key) = dest_key {
KvAccess::end_copy_to_kv(hmac.kv_wr_status(), dest_key)
.map_err(|err| err.into_write_tag_err())?;
}

Ok(())
}
}
Expand All @@ -445,6 +471,9 @@ pub struct Hmac384Op<'a> {
/// State
state: Hmac384OpState,

// The keyvault key used to compute the hmac
key: Option<KeyReadArgs>,

/// Staging buffer
buf: [u8; HMAC384_BLOCK_SIZE_BYTES],

Expand Down Expand Up @@ -490,7 +519,12 @@ impl<'a> Hmac384Op<'a> {

// If the buffer is full calculate the digest of accumulated data
if self.buf_idx == self.buf.len() {
self.hmac_engine.hmac_block(&self.buf, self.is_first())?;
self.hmac_engine.hmac_block(
&self.buf,
self.is_first(),
self.key,
self.dest_key(),
)?;
self.reset_buf_state();
}
}
Expand All @@ -510,8 +544,13 @@ impl<'a> Hmac384Op<'a> {

// Calculate the hmac of the final block
let buf = &self.buf[..self.buf_idx];
self.hmac_engine
.hmac_partial_block(buf, self.is_first(), self.data_size)?;
self.hmac_engine.hmac_partial_block(
buf,
self.is_first(),
self.data_size,
self.key,
self.dest_key(),
)?;

// Set the state of the operation to final
self.state = Hmac384OpState::Final;
Expand All @@ -525,6 +564,12 @@ impl<'a> Hmac384Op<'a> {
.map_err(|err| err.into_write_tag_err()),
}
}
fn dest_key(&self) -> Option<KeyWriteArgs> {
match self.tag {
Hmac384Tag::Key(key) => Some(key),
_ => None,
}
}

/// Check if this the first digest operation
fn is_first(&self) -> bool {
Expand Down
46 changes: 46 additions & 0 deletions drivers/test-fw/src/bin/hmac384_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,51 @@ fn test_hmac4() {
test_kv_hmac(&seed, &data, &out_pub_x, &out_pub_y);
}

fn test_hmac_kv_multiblock() {
let seed = [
0x32, 0x36, 0xcf, 0xba, 0x5d, 0xf3, 0x86, 0x39, 0x3e, 0x41, 0x13, 0x2b, 0x2d, 0x70, 0x6c,
0x00, 0x66, 0xe9, 0x2a, 0xa7, 0xb6, 0xe7, 0x09, 0x35, 0x16, 0xb6, 0xeb, 0x5f, 0x0b, 0x1e,
0x09, 0x3d, 0x7c, 0x9f, 0xa8, 0x1a, 0x0e, 0x61, 0x23, 0xac, 0x09, 0x0a, 0x40, 0xa4, 0x42,
0xf9, 0x3f, 0xaa,
];

let data: [u8; 256] = [
0x35, 0xc8, 0x57, 0xb5, 0x0f, 0x0f, 0xb2, 0x1a, 0x39, 0xab, 0xc8, 0xa3, 0xe7, 0xed, 0xf7,
0xe0, 0x4f, 0x16, 0xa4, 0xd5, 0xe6, 0x86, 0xe3, 0xf2, 0x1f, 0x38, 0xf5, 0x6e, 0xbd, 0x88,
0x74, 0x3f, 0x0f, 0xfb, 0x27, 0x29, 0x60, 0x3f, 0x84, 0x07, 0x5e, 0x5e, 0xc4, 0x57, 0x79,
0xce, 0xfa, 0x30, 0x5b, 0xb2, 0xed, 0xdd, 0xd7, 0xe2, 0xd2, 0xb3, 0xa6, 0x7a, 0xd9, 0x1e,
0x5d, 0x86, 0xa1, 0x96, 0x67, 0x2a, 0x47, 0x48, 0x4e, 0x72, 0xd6, 0xec, 0xde, 0x96, 0xbe,
0x5f, 0x9f, 0x09, 0x71, 0xbf, 0xe3, 0xc9, 0x06, 0x59, 0x1a, 0x3b, 0x2e, 0x3b, 0xe8, 0x97,
0x56, 0x27, 0x13, 0x5e, 0xf7, 0xf3, 0x7c, 0xde, 0xe0, 0x94, 0xdd, 0xf3, 0x3d, 0xa0, 0x7f,
0xf5, 0x77, 0x47, 0xca, 0x32, 0xbc, 0xb3, 0x0d, 0x6a, 0x40, 0xeb, 0xeb, 0x07, 0x86, 0x01,
0x27, 0x82, 0x55, 0x6b, 0x8e, 0x0a, 0x48, 0x34, 0x9b, 0x72, 0x91, 0x10, 0x55, 0xeb, 0x2b,
0x0d, 0x53, 0x2d, 0xe2, 0x6b, 0x62, 0xa4, 0x06, 0xfd, 0x03, 0x9b, 0xfd, 0x74, 0x9d, 0xd3,
0x59, 0x3d, 0x66, 0xd6, 0xfb, 0x09, 0x83, 0x63, 0x7d, 0xbf, 0x34, 0x40, 0x40, 0x5b, 0xf7,
0xf8, 0xb0, 0xd3, 0xe8, 0x72, 0x7c, 0x4c, 0xc8, 0xd2, 0x01, 0x8a, 0xf4, 0xc3, 0xf0, 0xff,
0x12, 0x21, 0x17, 0xfb, 0x6a, 0x44, 0x00, 0x52, 0xc2, 0x0c, 0x6a, 0x9b, 0x93, 0x21, 0xd1,
0x65, 0x22, 0x8d, 0xae, 0x70, 0xbf, 0x90, 0xdb, 0xe4, 0x8a, 0x1a, 0xb9, 0x79, 0x48, 0x7a,
0x35, 0x6d, 0x96, 0x29, 0x22, 0x82, 0xd1, 0xfb, 0x06, 0x42, 0x09, 0xbc, 0xe5, 0xd0, 0x1c,
0xec, 0xf5, 0xc1, 0x74, 0x13, 0x4d, 0x89, 0x4a, 0xae, 0xdb, 0xfb, 0xe6, 0xe0, 0x21, 0x89,
0x32, 0xad, 0xa2, 0x0e, 0xcb, 0xc0, 0x96, 0xc7, 0x01, 0xc5, 0xf8, 0x3b, 0xee, 0xf8, 0x4c,
0x6a,
];

let out_pub_x = [
0x75, 0x08, 0xb8, 0xfe, 0x7f, 0x1e, 0x44, 0x19, 0x1b, 0x12, 0x4e, 0xd6, 0x11, 0x7b, 0x1d,
0x0b, 0xce, 0x6d, 0xdc, 0x87, 0xf7, 0x1c, 0x0b, 0xb5, 0x5d, 0x88, 0xb7, 0x1a, 0x48, 0x8d,
0x1b, 0x19, 0x08, 0x3b, 0x30, 0xbf, 0x42, 0x29, 0x2b, 0x8d, 0xf5, 0xdc, 0xd8, 0x0b, 0x89,
0xc8, 0x23, 0x6d,
];
let out_pub_y = [
0xab, 0x30, 0x6a, 0x98, 0xa3, 0x75, 0x2d, 0xaa, 0xd2, 0xfd, 0x72, 0xa9, 0x96, 0x85, 0xf4,
0xcf, 0xe9, 0x8c, 0xbf, 0x0d, 0x94, 0xab, 0x8d, 0x66, 0x86, 0x5e, 0xba, 0x54, 0x56, 0xba,
0x19, 0x07, 0x4f, 0xd7, 0xfe, 0x3d, 0xc0, 0xa5, 0x56, 0x77, 0xdf, 0x78, 0xab, 0x89, 0x6a,
0x02, 0x43, 0xb9,
];

test_kv_hmac(&seed, &data, &out_pub_x, &out_pub_y);
}

///
/// Step 1:
/// Key From Key Vault
Expand Down Expand Up @@ -713,6 +758,7 @@ test_suite! {
test_hmac2,
test_hmac3,
test_hmac4,
test_hmac_kv_multiblock,
test_hmac5,
test_kdf0,
test_kdf1,
Expand Down
Loading
Loading