Skip to content

Commit

Permalink
Add support for new IntegrityRegisters field
Browse files Browse the repository at this point in the history
The latest DICE Attestation Architecture adds support for the
IntegrityRegisters field. Use this for Cumulative measurements instead
of adding a fwid.
  • Loading branch information
jhand2 committed Jan 24, 2025
1 parent 44a2307 commit 12e2838
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 36 deletions.
75 changes: 56 additions & 19 deletions dpe/src/x509.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,16 +363,21 @@ impl CertWriter<'_> {
supports_recursive: bool,
tagged: bool,
) -> Result<usize, DpeErrorCode> {
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::<u32>(), /*tagged=*/ true)?); // vendorInfo and type
+ (2 * Self::get_structure_size(core::mem::size_of::<u32>(), /*tagged=*/ true)?) // vendorInfo and type
+ integrity_registers_size;

Self::get_structure_size(size, tagged)
}
Expand Down Expand Up @@ -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();
Expand All @@ -1249,6 +1244,32 @@ impl CertWriter<'_> {
bytes_written += self.encode_size_field(core::mem::size_of::<u32>())?;
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)
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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<asn1::IA5String<'a>>,
#[implicit(1)]
_register_num: Option<u64>,
#[implicit(2)]
pub register_digests: Option<asn1::SequenceOf<'a, Fwid<'a>>>,
}

#[derive(asn1::Asn1Read)]
pub struct TcbInfo<'a> {
#[implicit(0)]
Expand All @@ -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<asn1::SequenceOf<'a, IntegrityRegister<'a>>>,
}

#[derive(asn1::Asn1Read)]
Expand Down Expand Up @@ -2394,16 +2427,20 @@ 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!(
parsed_tcb_info.vendor_info.unwrap(),
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);
Expand Down
36 changes: 26 additions & 10 deletions verification/testing/certifyKey.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
14 changes: 7 additions & 7 deletions verification/testing/deriveContext.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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),
Expand All @@ -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)
}
}

Expand All @@ -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)
}
Expand Down

0 comments on commit 12e2838

Please sign in to comment.