Skip to content

Commit

Permalink
[feat] Updating HMAC KDF from 384 to 512 for ROM (#1819)
Browse files Browse the repository at this point in the history
  • Loading branch information
mhatrevi authored Dec 2, 2024
1 parent f22cbca commit 742b657
Show file tree
Hide file tree
Showing 34 changed files with 268 additions and 187 deletions.
2 changes: 1 addition & 1 deletion drivers/src/hmac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ impl Hmac {

// Configure the hardware so that the output tag is stored at a location specified by the
// caller.
if matches!(&mut tag, HmacTag::Array4x12(_)) {
if matches!(&mut tag, HmacTag::Array4x12(_) | HmacTag::Array4x16(_)) {
KvAccess::begin_copy_to_arr(hmac.hmac512_kv_wr_status(), hmac.hmac512_kv_wr_ctrl())?;
}

Expand Down
16 changes: 9 additions & 7 deletions drivers/src/hmac384_kdf.rs → drivers/src/hmac_kdf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Licensed under the Apache-2.0 license.
File Name:
hmac384_kdf.rs
hmac_kdf.rs
Abstract:
Expand All @@ -17,36 +17,38 @@ use crate::{Hmac, HmacKey, HmacMode, HmacTag, Trng};
use caliptra_cfi_derive::cfi_mod_fn;
use caliptra_error::CaliptraResult;

/// Calculate HMAC-384-KDF
/// Calculate HMAC-KDF
///
/// If the output is a KV slot, the slot is marked as a valid HMAC key /
/// ECC keygen seed.
/// ECC or MLDSA keygen seed.
///
/// # Arguments
///
/// * `hmac` - HMAC384 context
/// * `key` - HMAC384 key
/// * `hmac` - HMAC context
/// * `key` - HMAC key
/// * `label` - Label for the KDF. If `context` is omitted, this is considered
/// the fixed input data.
/// * `context` - Context for KDF. If present, a NULL byte is included between
/// the label and context.
/// * `trng` - TRNG driver instance
/// * `output` - Location to store the output
/// * `mode` - HMAC Mode
#[cfg_attr(not(feature = "no-cfi"), cfi_mod_fn)]
pub fn hmac384_kdf(
pub fn hmac_kdf(
hmac: &mut Hmac,
key: HmacKey,
label: &[u8],
context: Option<&[u8]>,
trng: &mut Trng,
output: HmacTag,
mode: HmacMode,
) -> CaliptraResult<()> {
#[cfg(feature = "fips-test-hooks")]
unsafe {
crate::FipsTestHook::error_if_hook_set(crate::FipsTestHook::HMAC384_FAILURE)?
}

let mut hmac_op = hmac.hmac_init(&key, trng, output, HmacMode::Hmac384)?;
let mut hmac_op = hmac.hmac_init(&key, trng, output, mode)?;

hmac_op.update(&1_u32.to_be_bytes())?;
hmac_op.update(label)?;
Expand Down
4 changes: 2 additions & 2 deletions drivers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ mod fuse_bank;
pub mod fuse_log;
pub mod hand_off;
mod hmac;
mod hmac384_kdf;
mod hmac_kdf;
mod key_vault;
mod kv_access;
mod lms;
Expand Down Expand Up @@ -77,7 +77,7 @@ pub use fuse_bank::{
};
pub use hand_off::FirmwareHandoffTable;
pub use hmac::{Hmac, HmacData, HmacKey, HmacMode, HmacOp, HmacTag};
pub use hmac384_kdf::hmac384_kdf;
pub use hmac_kdf::hmac_kdf;
pub use key_vault::{KeyId, KeyUsage, KeyVault};
pub use kv_access::{KeyReadArgs, KeyWriteArgs};
pub use lms::{
Expand Down
26 changes: 14 additions & 12 deletions drivers/test-fw/src/bin/hmac_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Abstract:

use caliptra_cfi_lib::CfiCounter;
use caliptra_drivers::{
hmac384_kdf, Array4x12, Array4x16, Ecc384, Ecc384PrivKeyOut, Ecc384Scalar, Ecc384Seed, Hmac,
hmac_kdf, Array4x12, Array4x16, Ecc384, Ecc384PrivKeyOut, Ecc384Scalar, Ecc384Seed, Hmac,
HmacMode, KeyId, KeyReadArgs, KeyUsage, KeyWriteArgs, Trng,
};
use caliptra_kat::Hmac384KdfKat;
Expand Down Expand Up @@ -406,7 +406,7 @@ fn test_hmac5() {
assert_eq!(hmac_step_1, hmac_step_2);
}

fn test_kdf(
fn test_kdf_hmac384(
key_0: &[u8; 48],
msg_0: &[u8],
label: &[u8],
Expand Down Expand Up @@ -445,13 +445,14 @@ fn test_kdf(

let kdf_out = KeyWriteArgs::new(KeyId::KeyId1, KeyUsage::default().set_ecc_key_gen_seed_en());

hmac384_kdf(
hmac_kdf(
&mut hmac384,
kdf_key_in.into(),
label,
context,
&mut trng,
kdf_out.into(),
HmacMode::Hmac384,
)
.unwrap();

Expand All @@ -471,7 +472,7 @@ fn test_kdf(
}

// context_len = 48
fn test_kdf0() {
fn test_kdf0_hmac384() {
let key_0 = [
0x9e, 0x2c, 0xce, 0xc7, 0x00, 0x16, 0x1e, 0x42, 0xff, 0x0e, 0x13, 0x8c, 0x48, 0x89, 0xe4,
0xd6, 0xa0, 0x88, 0x8d, 0x13, 0x1d, 0x58, 0xcb, 0x44, 0xf5, 0xe2, 0x92, 0x47, 0x59, 0x64,
Expand Down Expand Up @@ -504,7 +505,7 @@ fn test_kdf0() {
0xcb, 0x13, 0x18,
];

test_kdf(
test_kdf_hmac384(
&key_0,
&msg_0,
&label,
Expand All @@ -515,7 +516,7 @@ fn test_kdf0() {
}

// context_len = 0
fn test_kdf1() {
fn test_kdf1_hmac384() {
let key_0 = [
0xd3, 0x45, 0xe5, 0x14, 0x19, 0xda, 0xc6, 0x9c, 0x70, 0xc8, 0x22, 0x71, 0xe9, 0x12, 0x28,
0x58, 0x65, 0x64, 0x16, 0xc9, 0x92, 0xf3, 0xda, 0x58, 0x5a, 0xca, 0x96, 0xe5, 0x99, 0x29,
Expand All @@ -542,11 +543,11 @@ fn test_kdf1() {
0x9a, 0xa4, 0x19,
];

test_kdf(&key_0, &msg_0, &label, None, &out_pub_x, &out_pub_y);
test_kdf_hmac384(&key_0, &msg_0, &label, None, &out_pub_x, &out_pub_y);
}

// Test using a NIST vector.
fn test_kdf2() {
fn test_kdf2_hmac384() {
let mut hmac384 = unsafe { Hmac::new(HmacReg::new()) };
let mut trng = unsafe {
Trng::new(
Expand Down Expand Up @@ -578,13 +579,14 @@ fn test_kdf2() {

let mut out_buf = Array4x12::default();

hmac384_kdf(
hmac_kdf(
&mut hmac384,
(&Array4x12::from(&key)).into(),
&label,
None,
&mut trng,
(&mut out_buf).into(),
HmacMode::Hmac384,
)
.unwrap();

Expand Down Expand Up @@ -1015,9 +1017,9 @@ test_suite! {
test_hmac4,
test_hmac_kv_multiblock,
test_hmac5,
test_kdf0,
test_kdf1,
test_kdf2,
test_kdf0_hmac384,
test_kdf1_hmac384,
test_kdf2_hmac384,
test_hmac_multi_block,
test_hmac_exact_single_block,
test_hmac_multi_block_two_step,
Expand Down
9 changes: 5 additions & 4 deletions fmc/src/flow/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use crate::fmc_env::FmcEnv;
use caliptra_cfi_derive::cfi_impl_fn;
use caliptra_common::{crypto::Ecc384KeyPair, keyids::KEY_ID_TMP};
use caliptra_drivers::{
hmac384_kdf, okref, Array4x12, Array4x5, Array4x8, CaliptraResult, Ecc384PrivKeyIn,
Ecc384PrivKeyOut, Ecc384PubKey, Ecc384Result, Ecc384Signature, KeyId, KeyReadArgs, KeyUsage,
KeyWriteArgs, Sha256Alg,
hmac_kdf, okref, Array4x12, Array4x5, Array4x8, CaliptraResult, Ecc384PrivKeyIn,
Ecc384PrivKeyOut, Ecc384PubKey, Ecc384Result, Ecc384Signature, HmacMode, KeyId, KeyReadArgs,
KeyUsage, KeyWriteArgs, Sha256Alg,
};

pub enum Crypto {}
Expand Down Expand Up @@ -79,7 +79,7 @@ impl Crypto {
context: Option<&[u8]>,
output: KeyId,
) -> CaliptraResult<()> {
hmac384_kdf(
hmac_kdf(
&mut env.hmac384,
KeyReadArgs::new(key).into(),
label,
Expand All @@ -92,6 +92,7 @@ impl Crypto {
.set_ecc_key_gen_seed_en(),
)
.into(),
HmacMode::Hmac384,
)
}

Expand Down
14 changes: 11 additions & 3 deletions kat/src/hmac384kdf_kat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Abstract:
--*/

use caliptra_drivers::{hmac384_kdf, Array4x12, CaliptraError, CaliptraResult, Hmac, Trng};
use caliptra_drivers::{hmac_kdf, Array4x12, CaliptraError, CaliptraResult, Hmac, HmacMode, Trng};

const KEY: Array4x12 = Array4x12::new([
0xb57dc523, 0x54afee11, 0xedb4c905, 0x2a528344, 0x348b2c6b, 0x6c39f321, 0x33ed3bb7, 0x2035a4ab,
Expand Down Expand Up @@ -67,8 +67,16 @@ impl Hmac384KdfKat {
fn kat_nist_vector(&self, hmac: &mut Hmac, trng: &mut Trng) -> CaliptraResult<()> {
let mut out = Array4x12::default();

hmac384_kdf(hmac, (&KEY).into(), &LABEL, None, trng, (&mut out).into())
.map_err(|_| CaliptraError::KAT_HMAC384_FAILURE)?;
hmac_kdf(
hmac,
(&KEY).into(),
&LABEL,
None,
trng,
(&mut out).into(),
HmacMode::Hmac384,
)
.map_err(|_| CaliptraError::KAT_HMAC384_FAILURE)?;

if EXPECTED_OUT != <[u8; 48]>::from(out)[..EXPECTED_OUT.len()] {
Err(CaliptraError::KAT_HMAC384_TAG_MISMATCH)?;
Expand Down
4 changes: 2 additions & 2 deletions kat/src/kats_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ pub struct KatsEnv<'a> {
// SHA2-512/384 Accelerator
pub sha2_512_384_acc: &'a mut Sha2_512_384Acc,

/// Hmac384 Engine
pub hmac384: &'a mut Hmac,
/// Hmac-512/384 Engine
pub hmac: &'a mut Hmac,

/// Cryptographically Secure Random Number Generator
pub trng: &'a mut Trng,
Expand Down
2 changes: 1 addition & 1 deletion kat/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub fn execute_kat(env: &mut KatsEnv) -> CaliptraResult<()> {
Ecc384Kat::default().execute(env.ecc384, env.trng)?;

cprintln!("[kat] HMAC-384Kdf");
Hmac384KdfKat::default().execute(env.hmac384, env.trng)?;
Hmac384KdfKat::default().execute(env.hmac, env.trng)?;

cprintln!("[kat] LMS");
LmsKat::default().execute(env.sha256, env.lms)?;
Expand Down
8 changes: 4 additions & 4 deletions rom/dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ The following sections define the various cryptographic primitives used by Calip
| Deobfuscation Engine | `doe_decrypt_uds(kv_slot, iv)` | Decrypt UDS to the specified key vault slot with specified initialization vector<br>**Input**:<br> ***kv_slot*** - key vault slot to decrypt the uds to<br>***iv*** - initialization vector |
| | `doe_decrypt_fe(kv_slot, iv)` | Decrypt Field Entropy to the specified key vault slot with specified initialization vector <br>**Input**:<br>***kv_slot*** - key vault slot to decrypt the field entropy to<br>***iv*** - initialization vector |
| | `doe_clear_secrets()` | Clear UDS Fuse Register, Field Entropy Fuse Register and Obfuscation key |
| Hashed Message Authentication Code | `hmac384_mac(key,data,mac_kv_slot)` | Calculate the MAC using a caller provided key and data. The resultant MAC is stored in key vault slot<br>**Input**:<br>***key*** - caller specified key<br>data - data<br>***mac_kv_slot*** - key vault slot to store the MAC to |
| | `hmac384_mac(kv_slot,data,mac_kv_slot)` | Calculate the MAC using a caller provided key and data. The resultant MAC is stored in key vault slot <br>**Input**: <br>***kv_slot*** - key vault slot to use the key from<br>***data*** - data<br>***mac_kv_slot*** - key vault slot to store the MAC to |
| Hashed Message Authentication Code | `hmac_mac(key,data,mac_kv_slot,mode)` | Calculate the MAC using a caller provided key and data. The resultant MAC is stored in key vault slot<br>**Input**:<br>***key*** - caller specified key<br>data - data<br>***mac_kv_slot*** - key vault slot to store the MAC to<br>***mode*** - HMAC384 or HMAC512 |
| | `hmac_mac(kv_slot,data,mac_kv_slot)` | Calculate the MAC using a caller provided key and data. The resultant MAC is stored in key vault slot <br>**Input**: <br>***kv_slot*** - key vault slot to use the key from<br>***data*** - data<br>***mac_kv_slot*** - key vault slot to store the MAC to<br>***mode*** - HMAC384 or HMAC512 |
| | `hmac512_mac(key,data,mac_kv_slot)` | Calculate the MAC using a caller provided key and data. The resultant MAC is stored in key vault slot<br>**Input**:<br>***key*** - caller specified key<br>data - data<br>***mac_kv_slot*** - key vault slot to store the MAC to |
| | `hmac512_mac(kv_slot,data,mac_kv_slot)` | Calculate the MAC using a caller provided key and data. The resultant MAC is stored in key vault slot <br>**Input**: <br>***kv_slot*** - key vault slot to use the key from<br>***data*** - data<br>***mac_kv_slot*** - key vault slot to store the MAC to |
| Elliptic Curve Cryptography | `ecc384_keygen(seed_kv_slot, priv_kv_slot) -> pub_key` | Generate ECC384 Key Pair.<br>**Input**:<br>***seed_key_slot*** - key vault slot to use as seed for key generation<br>***priv_kv_slot*** - key vault slot to store the private key to<br>**Output**:<br>***pub-key*** - public key associated with the private key |
Expand Down Expand Up @@ -471,9 +471,9 @@ Initial Device ID Layer is used to generate Manufacturer CDI & Private Keys. Thi

11. Generate the MACs over the tbs digests as follows:

`IDevIdTbsEcdsaMac = hmac384_mac(VendorSecretKvSlot, b"idevid_ecc_csr", IDevIdTbsDigestEcdsa)`
`IDevIdTbsEcdsaMac = hmac_mac(VendorSecretKvSlot, b"idevid_ecc_csr", IDevIdTbsDigestEcdsa, HmacMode::Hmac384)`

`IDevIdTbsMldsaMac = hmac512_mac(VendorSecretKvSlot, b"idevid_mldsa_csr",IDevIdTbsDigestMldsa)`
`IDevIdTbsMldsaMac = hmac512_mac(VendorSecretKvSlot, b"idevid_mldsa_csr",IDevIdTbsDigestMldsa, HmacMode::Hmac512)`

12. Upload the CSR(s) to mailbox and wait for JTAG to read the CSR out of the mailbox. Format of the CSR payload is documented below:

Expand Down
30 changes: 17 additions & 13 deletions rom/dev/src/flow/cold_reset/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,22 +113,24 @@ impl Crypto {
env.sha384.digest(data)
}

/// Calculate HMAC-348
/// Calculate HMAC
///
/// # Arguments
///
/// * `env` - ROM Environment
/// * `key` - HMAC384 key slot
/// * `key` - HMAC key slot
/// * `data` - Input data to hash
/// * `tag` - Key slot to store the tag
/// * `mode` - HMAC Mode
#[inline(always)]
pub fn hmac384_mac(
pub fn hmac_mac(
env: &mut RomEnv,
key: KeyId,
data: &HmacData,
tag: KeyId,
mode: HmacMode,
) -> CaliptraResult<()> {
env.hmac384.hmac(
env.hmac.hmac(
&KeyReadArgs::new(key).into(),
data,
&mut env.trng,
Expand All @@ -139,29 +141,31 @@ impl Crypto {
.set_ecc_key_gen_seed_en(),
)
.into(),
HmacMode::Hmac384,
mode,
)
}

/// Calculate HMAC-348 KDF
/// Calculate HMAC KDF
///
/// # Arguments
///
/// * `env` - ROM Environment
/// * `key` - HMAC384 key slot
/// * `key` - HMAC key slot
/// * `label` - Input label
/// * `context` - Input context
/// * `output` - Key slot to store the output
/// * `mode` - HMAC Mode
#[inline(always)]
pub fn hmac384_kdf(
pub fn hmac_kdf(
env: &mut RomEnv,
key: KeyId,
label: &[u8],
context: Option<&[u8]>,
output: KeyId,
mode: HmacMode,
) -> CaliptraResult<()> {
hmac384_kdf(
&mut env.hmac384,
hmac_kdf(
&mut env.hmac,
KeyReadArgs::new(key).into(),
label,
context,
Expand All @@ -173,6 +177,7 @@ impl Crypto {
.set_ecc_key_gen_seed_en(),
)
.into(),
mode,
)
}

Expand All @@ -194,7 +199,7 @@ impl Crypto {
label: &[u8],
priv_key: KeyId,
) -> CaliptraResult<Ecc384KeyPair> {
Crypto::hmac384_kdf(env, cdi, label, None, KEY_ID_TMP)?;
Crypto::hmac_kdf(env, cdi, label, None, KEY_ID_TMP, HmacMode::Hmac512)?;

let key_out = Ecc384PrivKeyOut::Key(KeyWriteArgs::new(
priv_key,
Expand Down Expand Up @@ -266,8 +271,7 @@ impl Crypto {
key_pair_seed: KeyId,
) -> CaliptraResult<MlDsaKeyPair> {
// Generate the seed for key pair generation.
// [CAP2][TODO] Change this to hmac512_kdfwhen available.
Crypto::hmac384_kdf(env, cdi, label, None, key_pair_seed)?;
Crypto::hmac_kdf(env, cdi, label, None, key_pair_seed, HmacMode::Hmac512)?;

// Generate the public key.
let pub_key = env
Expand Down
Loading

0 comments on commit 742b657

Please sign in to comment.