diff --git a/dpe/src/x509.rs b/dpe/src/x509.rs index 60aed790..25ab2b74 100644 --- a/dpe/src/x509.rs +++ b/dpe/src/x509.rs @@ -363,16 +363,21 @@ impl CertWriter<'_> { supports_recursive: bool, tagged: bool, ) -> Result { - let fwid0_size = Self::get_fwid_size(&node.tci_current.0, /*tagged=*/ true)?; - let fwid1_size = if supports_recursive { - Self::get_fwid_size(&node.tci_cumulative.0, /*tagged=*/ true)? + let fwid_size = Self::get_fwid_size(&node.tci_current.0, /*tagged=*/ true)?; + let integrity_registers_size = if supports_recursive { + let fwid_size = Self::get_fwid_size(&node.tci_cumulative.0, /*tagged=*/ true)?; + let fwid_list_size = Self::get_structure_size(fwid_size, /*tagged=*/ true)?; + let integrity_register_size = + Self::get_structure_size(fwid_list_size, /*tagged=*/ true)?; + Self::get_structure_size(integrity_register_size, /*tagged=*/ true)? } else { 0 }; - let fwids_size = Self::get_structure_size(fwid0_size + fwid1_size, /*tagged=*/ true)?; + let fwids_size = Self::get_structure_size(fwid_size, /*tagged=*/ true)?; let size = fwids_size - + (2 * Self::get_structure_size(core::mem::size_of::(), /*tagged=*/ true)?); // vendorInfo and type + + (2 * Self::get_structure_size(core::mem::size_of::(), /*tagged=*/ true)?) // vendorInfo and type + + integrity_registers_size; Self::get_structure_size(size, tagged) } @@ -1221,21 +1226,11 @@ impl CertWriter<'_> { // IMPLICIT [6] Constructed let fwid_size = Self::get_fwid_size(&node.tci_current.0, /*tagged=*/ true)?; bytes_written += self.encode_byte(Self::CONTEXT_SPECIFIC | Self::CONSTRUCTED | 0x06)?; - if supports_recursive { - bytes_written += self.encode_size_field(fwid_size * 2)?; - } else { - bytes_written += self.encode_size_field(fwid_size)?; - } + bytes_written += self.encode_size_field(fwid_size)?; // fwid[0] current measurement bytes_written += self.encode_fwid(&node.tci_current)?; - // fwid[1] journey measurement - // Omit fwid[1] from tcb_info if DPE_PROFILE does not support recursive - if supports_recursive { - bytes_written += self.encode_fwid(&node.tci_cumulative)?; - } - // vendorInfo OCTET STRING // IMPLICIT[8] Primitive let vinfo = &node.locality.to_be_bytes(); @@ -1249,6 +1244,32 @@ impl CertWriter<'_> { bytes_written += self.encode_size_field(core::mem::size_of::())?; bytes_written += self.encode_bytes(node.tci_type.as_bytes())?; + // Omit integrityRegisters from tcb_info if DPE_PROFILE does not support recursive + if supports_recursive { + // integrityRegisters SEQUENCE OF + // IMPLICIT [10] Constructed + let fwid_size = Self::get_fwid_size(&node.tci_cumulative.0, /*tagged=*/ true)?; + let fwid_list_size = Self::get_structure_size(fwid_size, /*tagged=*/ true)?; + let integrity_register_size = + Self::get_structure_size(fwid_list_size, /*tagged=*/ true)?; + + bytes_written += self.encode_byte(Self::CONTEXT_SPECIFIC | Self::CONSTRUCTED | 0xa)?; + bytes_written += self.encode_size_field(integrity_register_size)?; + + // integrityRegusters[0] SEQUENCE + bytes_written += self.encode_byte(Self::SEQUENCE_TAG)?; + bytes_written += self.encode_size_field(fwid_list_size)?; + + // IMPLICIT [2] Constructed + // registerDigests SEQUENCE OF FWID + // cumulative measurement + // Note: registerName and registerNum are omitted because DPE only + // supports a single register. + bytes_written += self.encode_byte(Self::CONTEXT_SPECIFIC | Self::CONSTRUCTED | 0x02)?; + bytes_written += self.encode_size_field(fwid_size)?; + bytes_written += self.encode_fwid(&node.tci_cumulative)?; + } + Ok(bytes_written) } @@ -1582,7 +1603,7 @@ impl CertWriter<'_> { /// AuthorityKeyIdentifier ::= SEQUENCE { /// keyIdentifier [0] KeyIdentifier OPTIONAL, /// authorityCertIssuer [1] GeneralNames OPTIONAL, - /// authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL + /// authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL /// } fn encode_authority_key_identifier_extension( &mut self, @@ -2248,6 +2269,16 @@ pub(crate) mod tests { pub(crate) digest: &'a [u8], } + #[derive(asn1::Asn1Read)] + pub struct IntegrityRegister<'a> { + #[implicit(0)] + _register_name: Option>, + #[implicit(1)] + _register_num: Option, + #[implicit(2)] + pub register_digests: Option>>, + } + #[derive(asn1::Asn1Read)] pub struct TcbInfo<'a> { #[implicit(0)] @@ -2270,6 +2301,8 @@ pub(crate) mod tests { pub vendor_info: Option<&'a [u8]>, #[implicit(9)] pub tci_type: Option<&'a [u8]>, + #[implicit(10)] + pub integrity_registers: Option>>, } #[derive(asn1::Asn1Read)] @@ -2394,9 +2427,7 @@ pub(crate) mod tests { // FWIDs let mut fwid_itr = parsed_tcb_info.fwids.unwrap(); let expected_current = fwid_itr.next().unwrap().digest; - let expected_cumulative = fwid_itr.next().unwrap().digest; assert_eq!(expected_current, node.tci_current.0); - assert_eq!(expected_cumulative, node.tci_cumulative.0); assert_eq!(parsed_tcb_info.tci_type.unwrap(), node.tci_type.as_bytes()); assert_eq!( @@ -2404,6 +2435,12 @@ pub(crate) mod tests { node.locality.to_be_bytes() ); + // Integrity registers + let mut ir_itr = parsed_tcb_info.integrity_registers.unwrap(); + let mut fwid_itr = ir_itr.next().unwrap().register_digests.unwrap(); + let expected_cumulative = fwid_itr.next().unwrap().digest; + assert_eq!(expected_cumulative, node.tci_cumulative.0); + // test tbs_info with supports_recursive = false supports_recursive = false; w = CertWriter::new(&mut cert, true); diff --git a/verification/testing/certifyKey.go b/verification/testing/certifyKey.go index 7d0a3208..5c9fa9e0 100644 --- a/verification/testing/certifyKey.go +++ b/verification/testing/certifyKey.go @@ -76,6 +76,7 @@ type Fwid struct { // flags [7] IMPLICIT OperationalFlags OPTIONAL, // vendorInfo [8] IMPLICIT OCTET STRING OPTIONAL, // type [9] IMPLICIT OCTET STRING OPTIONAL, +// integrityRegisters [10] IMPLICIT IrList OPTIONAL, // } // // FWIDLIST ::== SEQUENCE SIZE (1..MAX) OF FWID @@ -91,17 +92,32 @@ type Fwid struct { // recovery (2), // debug (3) // } +// +// IrList ::= SEQUENCE SIZE (1..MAX) OF IntegrityRegister +// IntegrityRegister ::= SEQUENCE { +// registerName [0] IMPLICIT IA5String OPTIONAL, +// registerNum [1] IMPLICIT INTEGER OPTIONAL, +// registerDigests [2] IMPLICIT FWIDLIST +// } + type DiceTcbInfo struct { - Vendor string `asn1:"optional,tag:0,utf8"` - Model string `asn1:"optional,tag:1,utf8"` - Version string `asn1:"optional,tag:2,utf8"` - SVN int `asn1:"optional,tag:3"` - Layer int `asn1:"optional,tag:4"` - Index int `asn1:"optional,tag:5"` - Fwids []Fwid `asn1:"optional,tag:6"` - Flags OperationalFlag `asn1:"optional,tag:7"` - VendorInfo []byte `asn1:"optional,tag:8"` - Type []byte `asn1:"optional,tag:9"` + Vendor string `asn1:"optional,tag:0,utf8"` + Model string `asn1:"optional,tag:1,utf8"` + Version string `asn1:"optional,tag:2,utf8"` + SVN int `asn1:"optional,tag:3"` + Layer int `asn1:"optional,tag:4"` + Index int `asn1:"optional,tag:5"` + Fwids []Fwid `asn1:"optional,tag:6"` + Flags OperationalFlag `asn1:"optional,tag:7"` + VendorInfo []byte `asn1:"optional,tag:8"` + Type []byte `asn1:"optional,tag:9"` + IntegrityRegisters []IntegrityRegister `asn1:"optional,tag:10"` +} + +type IntegrityRegister struct { + RegisterName string `asn1:"optional,tag:0,ia5"` + RegisterNum int `asn1:"optional,tag:1"` + RegisterDigests []Fwid `asn1:"optional,tag:2"` } // OperationalFlag represents the TCBInfo Operational Flags field diff --git a/verification/testing/deriveContext.go b/verification/testing/deriveContext.go index 0623d4e8..42e9ff82 100644 --- a/verification/testing/deriveContext.go +++ b/verification/testing/deriveContext.go @@ -356,7 +356,7 @@ func TestDeriveContextRecursive(d client.TestDPEInstance, c client.DPEClient, t if err != nil { t.Fatal(err) } - lastCumulative := tcbInfo.Fwids[1].Digest + lastCumulative := tcbInfo.IntegrityRegisters[0].RegisterDigests[0].Digest // Set current TCI value _, err = c.DeriveContext(handle, @@ -440,12 +440,12 @@ func TestDeriveContextRecursiveOnDerivedContexts(d client.TestDPEInstance, c cli // Check TCI_CUMULATIVE after creating child context wantCumulativeTCI := computeExpectedCumulative(make([]byte, digestLen), childTcbInfo.Fwids[0].Digest) - if !bytes.Equal(childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) { - t.Errorf("[ERROR]: Child node's cumulative TCI %x, expected %x", childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) + if !bytes.Equal(childTcbInfo.IntegrityRegisters[0].RegisterDigests[0].Digest, wantCumulativeTCI) { + t.Errorf("[ERROR]: Child node's cumulative TCI %x, expected %x", childTcbInfo.IntegrityRegisters[0].RegisterDigests[0].Digest, wantCumulativeTCI) } // Set current TCI value - lastCumulative := childTcbInfo.Fwids[1].Digest + lastCumulative := childTcbInfo.IntegrityRegisters[0].RegisterDigests[0].Digest resp, err := c.DeriveContext(childHandle, extendTciValue, client.DeriveContextFlags(client.Recursive), @@ -465,8 +465,8 @@ func TestDeriveContextRecursiveOnDerivedContexts(d client.TestDPEInstance, c cli } wantCumulativeTCI = computeExpectedCumulative(lastCumulative, extendTciValue) - if !bytes.Equal(childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) { - t.Errorf("[ERROR]: Child node's cumulative TCI %x, expected %x", childTcbInfo.Fwids[1].Digest, wantCumulativeTCI) + if !bytes.Equal(childTcbInfo.IntegrityRegisters[0].RegisterDigests[0].Digest, wantCumulativeTCI) { + t.Errorf("[ERROR]: Child node's cumulative TCI %x, expected %x", childTcbInfo.IntegrityRegisters[0].RegisterDigests[0].Digest, wantCumulativeTCI) } } @@ -491,7 +491,7 @@ func verifyMeasurements(c client.DPEClient, t *testing.T, handle *client.Context // Check that the last TcbInfo current/cumulative are as expected current := tcbInfo.Fwids[0].Digest - cumulative := tcbInfo.Fwids[1].Digest + cumulative := tcbInfo.IntegrityRegisters[0].RegisterDigests[0].Digest if !bytes.Equal(current, expectedCurrent) { t.Errorf("[ERROR]: Unexpected TCI_CURRENT digest, want %v but got %v", expectedCurrent, current) }