Merge "[rkp] Derive HMAC key from DICE sealing CDI" into main
diff --git a/rialto/src/requests/rkp.rs b/rialto/src/requests/rkp.rs
index 8e49248..f96b85d 100644
--- a/rialto/src/requests/rkp.rs
+++ b/rialto/src/requests/rkp.rs
@@ -23,18 +23,28 @@
use ciborium::{cbor, value::Value};
use core::result;
use coset::{iana, AsCborValue, CoseSign1, CoseSign1Builder, HeaderBuilder};
-use diced_open_dice::{keypair_from_seed, sign, DiceArtifacts, PrivateKey};
+use diced_open_dice::{kdf, keypair_from_seed, sign, DiceArtifacts, PrivateKey};
use log::error;
use service_vm_comm::{EcdsaP256KeyPair, GenerateCertificateRequestParams, RequestProcessingError};
+use zeroize::Zeroizing;
type Result<T> = result::Result<T, RequestProcessingError>;
+/// The salt is generated randomly with:
+/// hexdump -vn32 -e'16/1 "0x%02X, " 1 "\n"' /dev/urandom
+const HMAC_KEY_SALT: [u8; 32] = [
+ 0x82, 0x80, 0xFA, 0xD3, 0xA8, 0x0A, 0x9A, 0x4B, 0xF7, 0xA5, 0x7D, 0x7B, 0xE9, 0xC3, 0xAB, 0x13,
+ 0x89, 0xDC, 0x7B, 0x46, 0xEE, 0x71, 0x22, 0xB4, 0x5F, 0x4C, 0x3F, 0xE2, 0x40, 0x04, 0x3B, 0x6C,
+];
+const HMAC_KEY_INFO: &[u8] = b"rialto hmac key";
+const HMAC_KEY_LENGTH: usize = 32;
+
pub(super) fn generate_ecdsa_p256_key_pair(
- _dice_artifacts: &dyn DiceArtifacts,
+ dice_artifacts: &dyn DiceArtifacts,
) -> Result<EcdsaP256KeyPair> {
- let hmac_key = [];
+ let hmac_key = derive_hmac_key(dice_artifacts)?;
let ec_key = EcKey::new_p256()?;
- let maced_public_key = build_maced_public_key(ec_key.cose_public_key()?, &hmac_key)?;
+ let maced_public_key = build_maced_public_key(ec_key.cose_public_key()?, hmac_key.as_ref())?;
// TODO(b/279425980): Encrypt the private key in a key blob.
// Remove the printing of the private key.
@@ -57,11 +67,10 @@
params: GenerateCertificateRequestParams,
dice_artifacts: &dyn DiceArtifacts,
) -> Result<Vec<u8>> {
- // TODO(b/300590857): Derive the HMAC key from the DICE sealing CDI.
- let hmac_key = [];
+ let hmac_key = derive_hmac_key(dice_artifacts)?;
let mut public_keys: Vec<Value> = Vec::new();
for key_to_sign in params.keys_to_sign {
- let public_key = validate_public_key(&key_to_sign, &hmac_key)?;
+ let public_key = validate_public_key(&key_to_sign, hmac_key.as_ref())?;
public_keys.push(public_key.to_cbor_value()?);
}
// Builds `CsrPayload`.
@@ -95,6 +104,15 @@
cbor_to_vec(&auth_req)
}
+fn derive_hmac_key(dice_artifacts: &dyn DiceArtifacts) -> Result<Zeroizing<[u8; HMAC_KEY_LENGTH]>> {
+ let mut key = Zeroizing::new([0u8; HMAC_KEY_LENGTH]);
+ kdf(dice_artifacts.cdi_seal(), &HMAC_KEY_SALT, HMAC_KEY_INFO, key.as_mut()).map_err(|e| {
+ error!("Failed to compute the HMAC key: {e}");
+ RequestProcessingError::InternalError
+ })?;
+ Ok(key)
+}
+
/// Builds the `SignedData` for the given payload.
fn build_signed_data(payload: &Value, dice_artifacts: &dyn DiceArtifacts) -> Result<CoseSign1> {
let cdi_leaf_priv = derive_cdi_leaf_priv(dice_artifacts).map_err(|e| {