Skip to content

Commit

Permalink
[update] Implement IDEVID Subject Key ID for MLDSA (#1870)
Browse files Browse the repository at this point in the history
This change queries the correct algorithm type for generating the IDEVID subject key id for MLDSA from the fuse_idevid_cert_attr fuse.
  • Loading branch information
mhatrevi authored and ArthurHeymans committed Jan 9, 2025
1 parent 36bf568 commit 99e03a4
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 28 deletions.
78 changes: 54 additions & 24 deletions drivers/src/fuse_bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ pub enum X509KeyIdAlgo {
Sha1 = 0,
Sha256 = 1,
Sha384 = 2,
Fuse = 3,
Sha512 = 3,
Fuse = 4,
}

bitflags::bitflags! {
Expand All @@ -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<IdevidCertAttr> for usize {
Expand Down Expand Up @@ -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,
}
}

Expand Down Expand Up @@ -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];
Expand Down
2 changes: 1 addition & 1 deletion rom/dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <br> **Word 0:bits[0-2]**: ECDSA X509 Key Id Algorithm (3 bits) 0: SHA1, 1: SHA256, 2: SHA384, 3: SHA512, 4: Fuse <br> **Word 0:bits[3-5]**: MLDSA X509 Key Id Algorithm (3 bits) 0: SHA1, 1: SHA256, 2: SHA384, 3: SHA512, 4: Fuse <br> **Word 1,2,3,4,5**: ECDSA Subject Key Id <br> **Word 6,7,8,9,10**: MLDSA Subject Key Id <br> **Words 11,12**: Unique Endpoint ID <br> **Words 13,14,15,16**: Manufacturer Serial Number |
| FUSE_IDEVID_CERT_ATTR | 768 | FUSE containing information for generating IDEVID CSR <br> **Word 0:bits[0-2]**: ECDSA X509 Key Id Algorithm (3 bits) 0: SHA1, 1: SHA256, 2: SHA384, 3: SHA512, 4: Fuse <br> **Word 0:bits[3-5]**: MLDSA X509 Key Id Algorithm (3 bits) 0: SHA1, 1: SHA256, 2: SHA384, 3: SHA512, 4: Fuse <br> **Word 1,2,3,4,5**: ECDSA Subject Key Id <br> **Word 6,7,8,9,10**: MLDSA Subject Key Id <br> **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) <br> **Words 12,13,14,15**: Manufacturer Serial Number |
| MANUF_DEBUG_UNLOCK_TOKEN | 128 | Secret value for manufacturing debug unlock authorization |

### Architectural Registers
Expand Down
16 changes: 13 additions & 3 deletions rom/dev/src/flow/cold_reset/x509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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)
}
};

Expand Down

0 comments on commit 99e03a4

Please sign in to comment.