1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
// Copyright lowRISC contributors (OpenTitan project).
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
use anyhow::Result;
use crate::asn1::builder::Builder;
use crate::asn1::x509::X509;
use crate::asn1::{Oid, Tag};
use crate::template::DiceTcbInfoExtension;
impl DiceTcbInfoExtension {
// From the DICE specification:
// https://trustedcomputinggroup.org/wp-content/uploads/DICE-Attestation-Architecture-r23-final.pdf
//
// tcg OBJECT IDENTIFIER ::= {2 23 133}
// tcg-dice OBJECT IDENTIFIER ::= { tcg platformClass(5) 4 }
// tcg-dice-TcbInfo OBJECT IDENTIFIER ::= {tcg-dice 1}
// DiceTcbInfo ::== SEQUENCE {
// vendor [0] IMPLICIT UTF8String OPTIONAL,
// model [1] IMPLICIT UTF8String OPTIONAL,
// version [2] IMPLICIT UTF8String OPTIONAL,
// svn [3] IMPLICIT INTEGER OPTIONAL,
// layer [4] IMPLICIT INTEGER OPTIONAL,
// index [5] IMPLICIT INTEGER OPTIONAL,
// fwids [6] IMPLICIT FWIDLIST OPTIONAL,
// flags [7] IMPLICIT OperationalFlags OPTIONAL,
// vendorInfo [8] IMPLICIT OCTET STRING OPTIONAL,
// type [9] IMPLICIT OCTET STRING OPTIONAL
// }
// FWIDLIST ::== SEQUENCE SIZE (1..MAX) OF FWID
// FWID ::== SEQUENCE {
// hashAlg OBJECT IDENTIFIER,
// digest OCTET STRING
// }
// OperationalFlags ::= BIT STRING {
// notConfigured (0),
// notSecure (1),
// recovery (2),
// debug (3)
// }
// Push a raw DICE TCB Info extension data, without the X509 extension header.
pub fn push_extension_raw<B: Builder>(&self, builder: &mut B) -> Result<()> {
builder.push_seq(Some("dice_tcb_info".into()), |builder| {
if let Some(vendor) = &self.vendor {
builder.push_string(
Some("dice_vendor".into()),
&Tag::Context {
constructed: false,
value: 0,
},
vendor,
)?;
}
if let Some(model) = &self.model {
builder.push_string(
Some("dice_model".into()),
&Tag::Context {
constructed: false,
value: 1,
},
model,
)?;
}
if let Some(version) = &self.version {
builder.push_string(
Some("dice_version".into()),
&Tag::Context {
constructed: false,
value: 2,
},
version,
)?;
}
if let Some(svn) = &self.svn {
builder.push_integer(
Some("dice_svn".into()),
&Tag::Context {
constructed: false,
value: 3,
},
svn,
)?;
}
if let Some(layer) = &self.layer {
builder.push_integer(
Some("dice_layer".into()),
&Tag::Context {
constructed: false,
value: 4,
},
layer,
)?;
}
if let Some(fwids) = &self.fw_ids {
builder.push_tag(
Some("dice_fwids".into()),
&Tag::Context {
constructed: true,
value: 6,
},
|builder| {
for (idx, fwid) in fwids.iter().enumerate() {
builder.push_seq(Some("fwid".into()), |builder| {
builder.push_oid(&fwid.hash_algorithm.oid())?;
builder.push_octet_string(
Some(format!("dice_fwids_{}", idx)),
|builder| {
builder.push_byte_array(
Some(format!("dice_fwids_{}", idx)),
&fwid.digest,
)
},
)
})?;
}
Ok(())
},
)?;
}
if let Some(flags) = &self.flags {
builder.push_bitstring(
Some("dice_flags".into()),
&Tag::Context {
constructed: false,
value: 7,
},
&[
flags.not_configured.clone(),
flags.not_secure.clone(),
flags.recovery.clone(),
flags.debug.clone(),
],
)?;
}
Ok(())
})
}
// Push a DICE TCB Info X509 extension.
pub fn push_extension<B: Builder>(&self, builder: &mut B) -> Result<()> {
// Per the DICE specification, the DiceTcbInfo extension SHOULD be marked critical.
X509::push_extension(builder, &Oid::DiceTcbInfo, true, |builder| {
self.push_extension_raw(builder)
})
}
}