mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-08-02 20:16:15 -04:00
attestation: tdx issuer/validator (#1265)
* Add TDX validator * Add TDX issuer --------- Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
d104af6e51
commit
dd2da25ebe
53 changed files with 808 additions and 229 deletions
|
@ -43,6 +43,12 @@ const (
|
|||
// The value used to extend is derived from Constellation's master key.
|
||||
// TODO: move to stable, non-debug PCR before use.
|
||||
PCRIndexOwnerID = tpmutil.Handle(16)
|
||||
|
||||
// TDXIndexClusterID is the measurement used to mark the node as initialized.
|
||||
// The value is the index of the RTMR + 1, since index 0 of the TDX measurements is reserved for MRTD.
|
||||
TDXIndexClusterID = RTMRIndexClusterID + 1
|
||||
// RTMRIndexClusterID is the RTMR we extend to mark the node as initialized.
|
||||
RTMRIndexClusterID = 2
|
||||
)
|
||||
|
||||
// M are Platform Configuration Register (PCR) values that make up the Measurements.
|
||||
|
@ -128,7 +134,7 @@ func (m *M) EqualTo(other M) bool {
|
|||
}
|
||||
for k, v := range *m {
|
||||
otherExpected := other[k].Expected
|
||||
if !bytes.Equal(v.Expected[:], otherExpected[:]) {
|
||||
if !bytes.Equal(v.Expected, otherExpected) {
|
||||
return false
|
||||
}
|
||||
if v.ValidationOpt != other[k].ValidationOpt {
|
||||
|
@ -177,10 +183,45 @@ func (m *M) SetEnforced(enforced []uint32) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalJSON unmarshals measurements from json.
|
||||
// This function enforces all measurements to be of equal length.
|
||||
func (m *M) UnmarshalJSON(b []byte) error {
|
||||
newM := make(map[uint32]Measurement)
|
||||
if err := json.Unmarshal(b, &newM); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// check if all measurements are of equal length
|
||||
if err := checkLength(newM); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*m = newM
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnmarshalYAML unmarshals measurements from yaml.
|
||||
// This function enforces all measurements to be of equal length.
|
||||
func (m *M) UnmarshalYAML(unmarshal func(any) error) error {
|
||||
newM := make(map[uint32]Measurement)
|
||||
if err := unmarshal(&newM); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// check if all measurements are of equal length
|
||||
if err := checkLength(newM); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*m = newM
|
||||
return nil
|
||||
}
|
||||
|
||||
// Measurement wraps expected PCR value and whether it is enforced.
|
||||
type Measurement struct {
|
||||
// Expected measurement value.
|
||||
Expected [32]byte `json:"expected" yaml:"expected"`
|
||||
// 32 bytes for vTPM attestation, 48 for TDX.
|
||||
Expected []byte `json:"expected" yaml:"expected"`
|
||||
// ValidationOpt indicates how measurement mismatches should be handled.
|
||||
ValidationOpt MeasurementValidationOption `json:"warnOnly" yaml:"warnOnly"`
|
||||
}
|
||||
|
@ -269,11 +310,11 @@ func (m *Measurement) unmarshal(eM encodedMeasurement) error {
|
|||
}
|
||||
}
|
||||
|
||||
if len(expected) != 32 {
|
||||
if len(expected) != 32 && len(expected) != 48 {
|
||||
return fmt.Errorf("invalid measurement: invalid length: %d", len(expected))
|
||||
}
|
||||
|
||||
m.Expected = *(*[32]byte)(expected)
|
||||
m.Expected = expected
|
||||
m.ValidationOpt = eM.WarnOnly
|
||||
|
||||
return nil
|
||||
|
@ -282,7 +323,7 @@ func (m *Measurement) unmarshal(eM encodedMeasurement) error {
|
|||
// WithAllBytes returns a measurement value where all 32 bytes are set to b.
|
||||
func WithAllBytes(b byte, validationOpt MeasurementValidationOption) Measurement {
|
||||
return Measurement{
|
||||
Expected: *(*[32]byte)(bytes.Repeat([]byte{b}, 32)),
|
||||
Expected: bytes.Repeat([]byte{b}, 32),
|
||||
ValidationOpt: validationOpt,
|
||||
}
|
||||
}
|
||||
|
@ -290,7 +331,7 @@ func WithAllBytes(b byte, validationOpt MeasurementValidationOption) Measurement
|
|||
// PlaceHolderMeasurement returns a measurement with placeholder values for Expected.
|
||||
func PlaceHolderMeasurement() Measurement {
|
||||
return Measurement{
|
||||
Expected: *(*[32]byte)(bytes.Repeat([]byte{0x12, 0x34}, 16)),
|
||||
Expected: bytes.Repeat([]byte{0x12, 0x34}, 16),
|
||||
ValidationOpt: Enforce,
|
||||
}
|
||||
}
|
||||
|
@ -316,6 +357,18 @@ func getFromURL(ctx context.Context, client *http.Client, sourceURL *url.URL) ([
|
|||
return content, nil
|
||||
}
|
||||
|
||||
func checkLength(m map[uint32]Measurement) error {
|
||||
var length int
|
||||
for idx, measurement := range m {
|
||||
if length == 0 {
|
||||
length = len(measurement.Expected)
|
||||
} else if len(measurement.Expected) != length {
|
||||
return fmt.Errorf("inconsistent measurement length: index %d: expected %d, got %d", idx, length, len(measurement.Expected))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type encodedMeasurement struct {
|
||||
Expected string `json:"expected" yaml:"expected"`
|
||||
WarnOnly MeasurementValidationOption `json:"warnOnly" yaml:"warnOnly"`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue