diff --git a/drivers/src/fuse_bank.rs b/drivers/src/fuse_bank.rs index 44f7ae8642..1664f9b8c7 100644 --- a/drivers/src/fuse_bank.rs +++ b/drivers/src/fuse_bank.rs @@ -30,7 +30,8 @@ pub enum X509KeyIdAlgo { Sha1 = 0, Sha256 = 1, Sha384 = 2, - Fuse = 3, + Sha512 = 3, + Fuse = 4, } bitflags::bitflags! { @@ -46,16 +47,21 @@ bitflags::bitflags! { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum IdevidCertAttr { Flags = 0, - SubjectKeyId1 = 1, - SubjectKeyId2 = 2, - SubjectKeyId3 = 3, - SubjectKeyId4 = 4, - SubjectKeyId5 = 5, - UeidType = 6, - ManufacturerSerialNumber1 = 7, - ManufacturerSerialNumber2 = 8, - ManufacturerSerialNumber3 = 9, - ManufacturerSerialNumber4 = 10, + EccSubjectKeyId1 = 1, + EccSubjectKeyId2 = 2, + EccSubjectKeyId3 = 3, + EccSubjectKeyId4 = 4, + EccSubjectKeyId5 = 5, + MldsaSubjectKeyId1 = 6, + MldsaSubjectKeyId2 = 7, + MldsaSubjectKeyId3 = 8, + MldsaSubjectKeyId4 = 9, + MldsaSubjectKeyId5 = 10, + UeidType = 11, + ManufacturerSerialNumber1 = 12, + ManufacturerSerialNumber2 = 13, + ManufacturerSerialNumber3 = 14, + ManufacturerSerialNumber4 = 15, } impl From for usize { @@ -85,25 +91,31 @@ impl FuseBank<'_> { /// Get the key id crypto algorithm. /// /// # Arguments - /// * None + /// * `ecc_key_id_algo` - Whether to get ECC or MLDSA key id algorithm /// /// # Returns /// key id crypto algorithm /// - pub fn idev_id_x509_key_id_algo(&self) -> X509KeyIdAlgo { + pub fn idev_id_x509_key_id_algo(&self, ecc_key_id_algo: bool) -> X509KeyIdAlgo { let soc_ifc_regs = self.soc_ifc.regs(); - let flags = soc_ifc_regs + let mut flags = soc_ifc_regs .fuse_idevid_cert_attr() .at(IdevidCertAttr::Flags.into()) .read(); - match flags & 0x3 { + if !ecc_key_id_algo { + // ECC Key Id Algo is in Bits 0-2. + // MLDSA Key Id Algo is in Bits 3-5. + flags >>= 3; + } + + match flags & 0x7 { 0 => X509KeyIdAlgo::Sha1, 1 => X509KeyIdAlgo::Sha256, 2 => X509KeyIdAlgo::Sha384, - 3 => X509KeyIdAlgo::Fuse, - _ => unreachable!(), + 4 => X509KeyIdAlgo::Sha512, + _ => X509KeyIdAlgo::Fuse, } } @@ -152,33 +164,51 @@ impl FuseBank<'_> { /// Get the subject key identifier. /// /// # Arguments - /// * None + /// * `ecc_subject_key_id` - Whether to get ECC or MLDSA subject key identifier /// /// # Returns /// subject key identifier /// - pub fn subject_key_id(&self) -> [u8; 20] { + pub fn subject_key_id(&self, ecc_subject_key_id: bool) -> [u8; 20] { + let key_id = if ecc_subject_key_id { + [ + IdevidCertAttr::EccSubjectKeyId1, + IdevidCertAttr::EccSubjectKeyId2, + IdevidCertAttr::EccSubjectKeyId3, + IdevidCertAttr::EccSubjectKeyId4, + IdevidCertAttr::EccSubjectKeyId5, + ] + } else { + [ + IdevidCertAttr::MldsaSubjectKeyId1, + IdevidCertAttr::MldsaSubjectKeyId2, + IdevidCertAttr::MldsaSubjectKeyId3, + IdevidCertAttr::MldsaSubjectKeyId4, + IdevidCertAttr::MldsaSubjectKeyId5, + ] + }; + let soc_ifc_regs = self.soc_ifc.regs(); let subkeyid1 = soc_ifc_regs .fuse_idevid_cert_attr() - .at(IdevidCertAttr::SubjectKeyId1.into()) + .at(key_id[0].into()) .read(); let subkeyid2 = soc_ifc_regs .fuse_idevid_cert_attr() - .at(IdevidCertAttr::SubjectKeyId2.into()) + .at(key_id[1].into()) .read(); let subkeyid3 = soc_ifc_regs .fuse_idevid_cert_attr() - .at(IdevidCertAttr::SubjectKeyId3.into()) + .at(key_id[2].into()) .read(); let subkeyid4 = soc_ifc_regs .fuse_idevid_cert_attr() - .at(IdevidCertAttr::SubjectKeyId4.into()) + .at(key_id[3].into()) .read(); let subkeyid5 = soc_ifc_regs .fuse_idevid_cert_attr() - .at(IdevidCertAttr::SubjectKeyId5.into()) + .at(key_id[4].into()) .read(); let mut subject_key_id = [0u8; 20]; diff --git a/rom/dev/README.md b/rom/dev/README.md index 868238d630..4032624b5e 100644 --- a/rom/dev/README.md +++ b/rom/dev/README.md @@ -64,7 +64,7 @@ Following are the main FUSE & Architectural Registers used by the Caliptra ROM f | FUSE_OWNER_PK_HASH | 384 | Owner ECC and LMS or MLDSA Public Key Hash | | FUSE_RUNTIME_SVN | 128 | Runtime Security Version Number | | FUSE_ANTI_ROLLBACK_DISABLE | 1 | Disable SVN checking for FMC & Runtime when bit is set | -| FUSE_IDEVID_CERT_ATTR | 768 | FUSE containing information for generating IDEVID CSR
**Word 0:bits[0-2]**: ECDSA X509 Key Id Algorithm (3 bits) 0: SHA1, 1: SHA256, 2: SHA384, 3: SHA512, 4: Fuse
**Word 0:bits[3-5]**: MLDSA X509 Key Id Algorithm (3 bits) 0: SHA1, 1: SHA256, 2: SHA384, 3: SHA512, 4: Fuse
**Word 1,2,3,4,5**: ECDSA Subject Key Id
**Word 6,7,8,9,10**: MLDSA Subject Key Id
**Words 11,12**: Unique Endpoint ID
**Words 13,14,15,16**: Manufacturer Serial Number | +| FUSE_IDEVID_CERT_ATTR | 768 | FUSE containing information for generating IDEVID CSR
**Word 0:bits[0-2]**: ECDSA X509 Key Id Algorithm (3 bits) 0: SHA1, 1: SHA256, 2: SHA384, 3: SHA512, 4: Fuse
**Word 0:bits[3-5]**: MLDSA X509 Key Id Algorithm (3 bits) 0: SHA1, 1: SHA256, 2: SHA384, 3: SHA512, 4: Fuse
**Word 1,2,3,4,5**: ECDSA Subject Key Id
**Word 6,7,8,9,10**: MLDSA Subject Key Id
**Words 11**: UEID type as defined in [IETF RATS specification](https://www.ietf.org/archive/id/draft-ietf-rats-eat-21.html#section-4.2.1.1)
**Words 12,13,14,15**: Manufacturer Serial Number | | MANUF_DEBUG_UNLOCK_TOKEN | 128 | Secret value for manufacturing debug unlock authorization | ### Architectural Registers diff --git a/rom/dev/src/flow/cold_reset/x509.rs b/rom/dev/src/flow/cold_reset/x509.rs index 2018a97aaa..e5769aea50 100644 --- a/rom/dev/src/flow/cold_reset/x509.rs +++ b/rom/dev/src/flow/cold_reset/x509.rs @@ -101,9 +101,13 @@ impl X509 { let pub_key_size = Self::get_pubkey_bytes(pub_key, &mut pub_key_bytes); let data: &[u8] = &pub_key_bytes[..pub_key_size]; - // [CAP2][TODO] Get the hash algorithm if the key is MLDSA. + let ecc_pub_key = matches!(pub_key, PubKey::Ecc(_)); - let digest: [u8; 20] = match env.soc_ifc.fuse_bank().idev_id_x509_key_id_algo() { + let digest: [u8; 20] = match env + .soc_ifc + .fuse_bank() + .idev_id_x509_key_id_algo(ecc_pub_key) + { X509KeyIdAlgo::Sha1 => { cprintln!("[idev] Sha1 KeyId Algorithm"); let digest = Crypto::sha1_digest(env, data); @@ -121,9 +125,15 @@ impl X509 { let digest: [u8; 48] = okref(&digest)?.into(); digest[..20].try_into().unwrap() } + X509KeyIdAlgo::Sha512 => { + cprintln!("[idev] Sha512 KeyId Algorithm"); + let digest = Crypto::sha512_digest(env, data); + let digest: [u8; 64] = okref(&digest)?.into(); + digest[..20].try_into().unwrap() + } X509KeyIdAlgo::Fuse => { cprintln!("[idev] Fuse KeyId"); - env.soc_ifc.fuse_bank().subject_key_id() + env.soc_ifc.fuse_bank().subject_key_id(ecc_pub_key) } };