Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for new IntegrityRegisters field #369

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)?;

jhand2 marked this conversation as resolved.
Show resolved Hide resolved
// 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
Loading