From 4d3defca060bfde7cde1b3e9910ac4eca78403cd Mon Sep 17 00:00:00 2001 From: Malte Poll <1780588+malt3@users.noreply.github.com> Date: Mon, 18 Mar 2024 16:11:05 +0100 Subject: [PATCH] verify: embed expected launch digest in manifest for verification --- cli/cmd/verify.go | 11 +++++++---- coordinator/mesh.go | 11 +++++++---- internal/manifest/constants.go | 12 ++++-------- internal/manifest/manifest.go | 5 +++-- packages/by-name/contrast/package.nix | 4 ++++ 5 files changed, 25 insertions(+), 18 deletions(-) diff --git a/cli/cmd/verify.go b/cli/cmd/verify.go index 8b9c9b8ee8..055ca45d1a 100644 --- a/cli/cmd/verify.go +++ b/cli/cmd/verify.go @@ -144,14 +144,19 @@ func parseVerifyFlags(cmd *cobra.Command) (*verifyFlags, error) { func newCoordinatorValidateOptsGen(hostData []byte) *snp.StaticValidateOptsGenerator { defaultManifest := manifest.Default() - trustedIDKeyDigests, err := (&defaultManifest.ReferenceValues.SNP.TrustedIDKeyHashes).ByteSlices() + trustedMeasurement, err := defaultManifest.ReferenceValues.SNP.TrustedMeasurement.Bytes() if err != nil { panic(err) // We are decoding known values, tests should catch any failure. } + if trustedMeasurement == nil { + // This is required to prevent an empty measurement in the manifest from disabling the measurement check. + trustedMeasurement = make([]byte, 48) + } return &snp.StaticValidateOptsGenerator{ Opts: &validate.Options{ - HostData: hostData, + HostData: hostData, + Measurement: trustedMeasurement, GuestPolicy: abi.SnpPolicy{ Debug: false, SMT: true, @@ -170,8 +175,6 @@ func newCoordinatorValidateOptsGen(hostData []byte) *snp.StaticValidateOptsGener UcodeSpl: 115, }, PermitProvisionalFirmware: true, - TrustedIDKeyHashes: trustedIDKeyDigests, - RequireIDBlock: false, // TODO(malt3): re-enable once we control the full boot (including the id block) }, } } diff --git a/coordinator/mesh.go b/coordinator/mesh.go index feb0501dde..dc301937e3 100644 --- a/coordinator/mesh.go +++ b/coordinator/mesh.go @@ -48,12 +48,17 @@ func (m *meshAuthority) SNPValidateOpts(report *sevsnp.Report) (*validate.Option return nil, fmt.Errorf("hostdata %s not found in manifest", hostData) } - trustedIDKeyDigestHashes, err := mnfst.ReferenceValues.SNP.TrustedIDKeyHashes.ByteSlices() + trustedMeasurement, err := mnfst.ReferenceValues.SNP.TrustedMeasurement.Bytes() if err != nil { - return nil, fmt.Errorf("failed to convert TrustedIDKeyHashes from manifest to byte slices: %w", err) + return nil, fmt.Errorf("failed to convert TrustedMeasurement from manifest to byte slices: %w", err) + } + if trustedMeasurement == nil { + // This is required to prevent an empty measurement in the manifest from disabling the measurement check. + trustedMeasurement = make([]byte, 48) } return &validate.Options{ + Measurement: trustedMeasurement, GuestPolicy: abi.SnpPolicy{ Debug: false, SMT: true, @@ -72,8 +77,6 @@ func (m *meshAuthority) SNPValidateOpts(report *sevsnp.Report) (*validate.Option UcodeSpl: mnfst.ReferenceValues.SNP.MinimumTCB.MicrocodeVersion.UInt8(), }, PermitProvisionalFirmware: true, - TrustedIDKeyHashes: trustedIDKeyDigestHashes, - RequireIDBlock: false, // TODO(malt3): re-enable once we control the full boot (including the id block) }, nil } diff --git a/internal/manifest/constants.go b/internal/manifest/constants.go index 0e4e45e9b5..58470ed244 100644 --- a/internal/manifest/constants.go +++ b/internal/manifest/constants.go @@ -1,5 +1,8 @@ package manifest +// This value is injected at build time. +var trustedMeasurement = "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + // Default returns a default manifest. func Default() Manifest { return Manifest{ @@ -11,14 +14,7 @@ func Default() Manifest { SNPVersion: 8, MicrocodeVersion: 115, }, - TrustedIDKeyHashes: []HexString{ - "b2bcf1b11d9fb3f2e4e7979546844d26c30255fff0775f3af56f8295f361a7d1a34a54516d41abfff7320763a5b701d8", - "22087e0b99b911c9cffccfd9550a054531c105d46ed6d31f948eae56bd2defa4887e2fc4207768ec610aa232ac7490c4", - "bb4bb49681f267bd1d504ce1c4388abcf7e3e53b6003a1bfcfe9884056047912ebb9a813da95cf711a0410ddc00fe65b", // Added 2024-01-22 - "92898fbc330c89f8a38b8516087970b1d3361e017c84bd5abe901cab7edeb0a4271509edba1670c14feb82293bcde33f", // Added 2024-02-07 - "089ee8adfc810a72eb2683007f34db9f8160c4d1936b70570b779ef3b7bb66046194298cea8d51ebfd4b7c8a2b8ea2d7", // Added 2024-02-21 - "1383573d02170f77b1fc2a8bfd5eaec89b0158b3f186eee7b65f785187c41b50be5d97e3b23fa9c5a4b70fe0d1e03af7", // Added 2024-03-12 - }, + TrustedMeasurement: HexString(trustedMeasurement), }, }, } diff --git a/internal/manifest/manifest.go b/internal/manifest/manifest.go index e2a1030213..22ca556664 100644 --- a/internal/manifest/manifest.go +++ b/internal/manifest/manifest.go @@ -24,8 +24,9 @@ type ReferenceValues struct { // SNPReferenceValues contains reference values for the SNP report. type SNPReferenceValues struct { - MinimumTCB SNPTCB - TrustedIDKeyHashes HexStrings // 0356215882a825279a85b300b0b742931d113bf7e32dde2e50ffde7ec743ca491ecdd7f336dc28a6e0b2bb57af7a44a3 + MinimumTCB SNPTCB + // TrustedMeasurement is the hash of the trusted launch digest. + TrustedMeasurement HexString } // SNPTCB represents a set of SNP TCB values. diff --git a/packages/by-name/contrast/package.nix b/packages/by-name/contrast/package.nix index 2e4fdc39e5..902125f6be 100644 --- a/packages/by-name/contrast/package.nix +++ b/packages/by-name/contrast/package.nix @@ -4,6 +4,7 @@ , genpolicy-msft , genpolicy ? genpolicy-msft , contrast +, runtime-class-files }: let e2e = buildGoTest rec { @@ -17,6 +18,8 @@ let subPackages = [ "e2e/openssl" ]; }; + launchDigest = builtins.readFile "${runtime-class-files}/launch-digest.hex"; + packageOutputs = [ "coordinator" "initializer" "cli" ]; in @@ -63,6 +66,7 @@ buildGoModule rec { "-s" "-w" "-X main.version=v${version}" + "-X github.com/edgelesssys/contrast/internal/manifest.trustedMeasurement=${launchDigest}" ]; preCheck = ''