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

[feat] Updating HMAC KDF from 384 to 512 for ROM #1819

Merged
merged 2 commits into from
Dec 2, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
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
14 changes: 8 additions & 6 deletions drivers/src/hmac384_kdf.rs
mhatrevi marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 1 addition & 1 deletion drivers/src/lib.rs
Original file line number Diff line number Diff line change
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 hmac384_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,
mhatrevi marked this conversation as resolved.
Show resolved Hide resolved
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
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
18 changes: 16 additions & 2 deletions rom/dev/src/flow/cold_reset/fmc_alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ use caliptra_common::keyids::{
};
use caliptra_common::pcr::PCR_ID_FMC_CURRENT;
use caliptra_common::RomBootStatus::*;
use caliptra_drivers::{okmutref, report_boot_status, Array4x12, CaliptraResult, KeyId, Lifecycle};
use caliptra_drivers::{
okmutref, report_boot_status, Array4x12, CaliptraResult, HmacMode, KeyId, Lifecycle,
};
use caliptra_x509::{FmcAliasCertTbs, FmcAliasCertTbsParams};
use zeroize::Zeroize;

Expand All @@ -53,6 +55,11 @@ impl FmcAliasLayer {
KEY_ID_FMC_ECDSA_PRIV_KEY as u8,
KEY_ID_FMC_MLDSA_KEYPAIR_SEED as u8
);
cprintln!(
"[afmc] ECC SUBJECT.KEYID = {}, MLDSA SUBJECT.KEYID = {}",
KEY_ID_FMC_ECDSA_PRIV_KEY as u8,
KEY_ID_FMC_MLDSA_KEYPAIR_SEED as u8
);
cprintln!(
"[afmc] ECC AUTHORITY.KEYID = {}, MLDSA AUTHORITY.KEYID = {}",
input.ecc_auth_key_pair.priv_key as u8,
Expand Down Expand Up @@ -119,7 +126,14 @@ impl FmcAliasLayer {
fn derive_cdi(env: &mut RomEnv, measurements: &Array4x12, cdi: KeyId) -> CaliptraResult<()> {
let mut measurements: [u8; 48] = measurements.into();

let result = Crypto::hmac384_kdf(env, cdi, b"alias_fmc_cdi", Some(&measurements), cdi);
let result = Crypto::hmac_kdf(
env,
cdi,
b"alias_fmc_cdi",
Some(&measurements),
KEY_ID_ROM_FMC_CDI,
HmacMode::Hmac512,
);
measurements.zeroize();
result?;
report_boot_status(FmcAliasDeriveCdiComplete.into());
Expand Down
4 changes: 2 additions & 2 deletions rom/dev/src/flow/cold_reset/fw_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ impl FirmwareProcessor {
// SHA2-512/384 Accelerator
sha2_512_384_acc: &mut env.sha2_512_384_acc,

// Hmac384 Engine
hmac384: &mut env.hmac384,
// Hmac Engine
hmac384: &mut env.hmac,
mhatrevi marked this conversation as resolved.
Show resolved Hide resolved

/// Cryptographically Secure Random Number Generator
trng: &mut env.trng,
Expand Down
Loading
Loading