From 181b8f64d2b7c96b13489cec25ed2dff9c8d720e Mon Sep 17 00:00:00 2001 From: Malte Poll <1780588+malt3@users.noreply.github.com> Date: Thu, 4 Jan 2024 16:39:45 +0100 Subject: [PATCH] image: add static (per-CSP) measurements during "measurement envelope" This logic was previously performed in a GitHub Actions workflow using yq. Since every step should now be performed in Bazel, this now needs to happen here. --- .../internal/cmd/measurementsenvelope.go | 5 + internal/attestation/measurements/BUILD.bazel | 1 + .../attestation/measurements/overrides.go | 132 ++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 internal/attestation/measurements/overrides.go diff --git a/image/upload/internal/cmd/measurementsenvelope.go b/image/upload/internal/cmd/measurementsenvelope.go index 1f6c49b02..e7480d1ca 100644 --- a/image/upload/internal/cmd/measurementsenvelope.go +++ b/image/upload/internal/cmd/measurementsenvelope.go @@ -66,6 +66,11 @@ func runEnvelopeMeasurements(cmd *cobra.Command, _ []string) error { return fmt.Errorf("enveloping measurements: reading input file: %w", err) } + measuremnt.Measurements, err = measurements.ApplyOverrides(measuremnt.Measurements, flags.csp, flags.attestationVariant) + if err != nil { + return fmt.Errorf("enveloping measurements: overriding static measurements: %w", err) + } + enveloped := measurements.ImageMeasurementsV2{ Ref: flags.version.Ref(), Stream: flags.version.Stream(), diff --git a/internal/attestation/measurements/BUILD.bazel b/internal/attestation/measurements/BUILD.bazel index b3b615e19..ea3fe108b 100644 --- a/internal/attestation/measurements/BUILD.bazel +++ b/internal/attestation/measurements/BUILD.bazel @@ -10,6 +10,7 @@ go_library( "measurements_enterprise.go", # keep "measurements_oss.go", + "overrides.go", ], importpath = "github.com/edgelesssys/constellation/v2/internal/attestation/measurements", visibility = ["//:__subpackages__"], diff --git a/internal/attestation/measurements/overrides.go b/internal/attestation/measurements/overrides.go new file mode 100644 index 000000000..1118756ce --- /dev/null +++ b/internal/attestation/measurements/overrides.go @@ -0,0 +1,132 @@ +/* +Copyright (c) Edgeless Systems GmbH + +SPDX-License-Identifier: AGPL-3.0-only +*/ + +package measurements + +import ( + "fmt" + + "github.com/edgelesssys/constellation/v2/internal/attestation/variant" + "github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider" +) + +var measurementOverridesForCSP = map[string]measurementOverride{ + cloudprovider.AWS.String(): { + MustEnforce: []uint32{ + 4, 8, 9, 11, 12, 13, uint32(PCRIndexClusterID), + }, + MustWarn: []uint32{ + 0, 2, 3, 6, 14, + }, + ValueOverrides: []valueOverride{ + {Index: 2, Value: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}}, + {Index: 3, Value: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}}, + {Index: 6, Value: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}}, + {Index: 14, Value: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }, + }, + cloudprovider.Azure.String(): { + MustEnforce: []uint32{ + 4, 8, 9, 11, 12, 13, uint32(PCRIndexClusterID), + }, + MustWarn: []uint32{ + 1, 2, 3, 14, + }, + ValueOverrides: []valueOverride{ + {Index: 1, Value: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}}, + {Index: 2, Value: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}}, + {Index: 3, Value: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}}, + {Index: 14, Value: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }, + }, + cloudprovider.GCP.String(): { + MustEnforce: []uint32{ + 4, 8, 9, 11, 12, 13, uint32(PCRIndexClusterID), + }, + MustWarn: []uint32{ + 1, 2, 3, 6, 14, + }, + ValueOverrides: []valueOverride{ + {Index: 1, Value: []byte{0x74, 0x5f, 0x2f, 0xb4, 0x23, 0x5e, 0x46, 0x47, 0xaa, 0x0a, 0xd5, 0xac, 0xe7, 0x81, 0xcd, 0x92, 0x9e, 0xb6, 0x8c, 0x28, 0x87, 0x0e, 0x7d, 0xd5, 0xd1, 0xa1, 0x53, 0x58, 0x54, 0x32, 0x5e, 0x56}}, + {Index: 2, Value: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}}, + {Index: 3, Value: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}}, + {Index: 6, Value: []byte{0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}}, + {Index: 14, Value: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }, + }, + cloudprovider.OpenStack.String(): { + MustEnforce: []uint32{ + 4, 8, 9, 11, 12, 13, uint32(PCRIndexClusterID), + }, + MustWarn: []uint32{ + 14, + }, + ValueOverrides: []valueOverride{ + {Index: 14, Value: []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, + }, + }, +} + +var measurementOverridesForAttestationVariant = map[string]measurementOverride{ + variant.AWSNitroTPM{}.String(): { + ValueOverrides: []valueOverride{ + {Index: 0, Value: []byte{0x73, 0x7f, 0x76, 0x7a, 0x12, 0xf5, 0x4e, 0x70, 0xee, 0xcb, 0xc8, 0x68, 0x40, 0x11, 0x32, 0x3a, 0xe2, 0xfe, 0x2d, 0xd9, 0xf9, 0x07, 0x85, 0x57, 0x79, 0x69, 0xd7, 0xa2, 0x01, 0x3e, 0x8c, 0x12}}, + }, + }, + variant.AWSSEVSNP{}.String(): { + ValueOverrides: []valueOverride{ + {Index: 0, Value: []byte{0x7b, 0x06, 0x8c, 0x0c, 0x3a, 0xc2, 0x9a, 0xfe, 0x26, 0x41, 0x34, 0x53, 0x6b, 0x9b, 0xe2, 0x6f, 0x1d, 0x4c, 0xcd, 0x57, 0x5b, 0x88, 0xd3, 0xc3, 0xce, 0xab, 0xf3, 0x6a, 0xc9, 0x9c, 0x02, 0x78}}, + }, + }, +} + +type measurementOverride struct { + MustEnforce []uint32 + MustWarn []uint32 + ValueOverrides []valueOverride +} + +type valueOverride struct { + Index uint32 + Value []byte +} + +// ApplyOverrides applies overrides to the given measurements. +func ApplyOverrides(in M, csp cloudprovider.Provider, attestationVariant string) (M, error) { + out := in.Copy() + var matchingOverrides []measurementOverride + if cspOverride, ok := measurementOverridesForCSP[csp.String()]; ok { + matchingOverrides = append(matchingOverrides, cspOverride) + } + if attestationVariantOverride, ok := measurementOverridesForAttestationVariant[attestationVariant]; ok { + matchingOverrides = append(matchingOverrides, attestationVariantOverride) + } + for _, override := range matchingOverrides { + for _, i := range override.ValueOverrides { + m, ok := out[i.Index] + if !ok { + m = Measurement{} + } + m.Expected = i.Value + out[i.Index] = m + } + for _, i := range override.MustEnforce { + m, ok := out[i] + if !ok { + return nil, fmt.Errorf("missing measurement for PCR %d", i) + } + m.ValidationOpt = Enforce + } + for _, i := range override.MustWarn { + m, ok := out[i] + if !ok { + return nil, fmt.Errorf("missing measurement for PCR %d", i) + } + m.ValidationOpt = WarnOnly + } + } + return out, nil +}