Skip to content

Commit 8933beb

Browse files
committed
Set validator reportData correctly
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
1 parent 9f82f8d commit 8933beb

File tree

3 files changed

+11
-94
lines changed

3 files changed

+11
-94
lines changed

internal/attestation/gcp/snp/BUILD.bazel

-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ go_library(
2424
"@com_github_google_go_sev_guest//validate",
2525
"@com_github_google_go_sev_guest//verify",
2626
"@com_github_google_go_sev_guest//verify/trust",
27-
"@com_github_google_go_tpm//legacy/tpm2",
2827
"@com_github_google_go_tpm_tools//client",
2928
"@com_github_google_go_tpm_tools//proto/attest",
3029
],
@@ -45,6 +44,5 @@ go_test(
4544
"//internal/config",
4645
"@com_github_google_go_tpm_tools//proto/attest",
4746
"@com_github_stretchr_testify//assert",
48-
"@com_github_stretchr_testify//require",
4947
],
5048
)

internal/attestation/gcp/snp/validator.go

+11-36
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ package snp
99
import (
1010
"context"
1111
"crypto"
12-
"crypto/sha512"
1312
"crypto/x509"
1413
"encoding/json"
1514
"fmt"
@@ -27,7 +26,6 @@ import (
2726
"github.com/google/go-sev-guest/verify"
2827
"github.com/google/go-sev-guest/verify/trust"
2928
"github.com/google/go-tpm-tools/proto/attest"
30-
"github.com/google/go-tpm/legacy/tpm2"
3129
)
3230

3331
// Validator for GCP SEV-SNP / TPM attestation.
@@ -62,53 +60,30 @@ func NewValidator(cfg *config.GCPSEVSNP, log attestation.Logger) (*Validator, er
6260
v.Validator = vtpm.NewValidator(
6361
cfg.Measurements,
6462
v.getTrustedKey,
65-
v.validateCVM,
63+
func(_ vtpm.AttestationDocument, _ *attest.MachineState) error { return nil },
6664
log,
6765
)
6866
return v, nil
6967
}
7068

7169
// getTrustedKey returns TPM endorsement key provided through the GCE metadata API.
72-
func (v *Validator) getTrustedKey(ctx context.Context, attDoc vtpm.AttestationDocument, _ []byte) (crypto.PublicKey, error) {
70+
func (v *Validator) getTrustedKey(ctx context.Context, attDoc vtpm.AttestationDocument, extraData []byte) (crypto.PublicKey, error) {
7371
ekPub, err := v.gceKeyGetter(ctx, attDoc, nil)
7472
if err != nil {
7573
return nil, fmt.Errorf("getting TPM endorsement key: %w", err)
7674
}
7775

78-
return ekPub, nil
79-
}
80-
81-
// validateCVM validates the SEV-SNP attestation document.
82-
func (v *Validator) validateCVM(attDoc vtpm.AttestationDocument, _ *attest.MachineState) error {
83-
pubArea, err := tpm2.DecodePublic(attDoc.Attestation.AkPub)
84-
if err != nil {
85-
return fmt.Errorf("decoding public area: %w", err)
86-
}
87-
88-
pubKey, err := pubArea.Key()
89-
if err != nil {
90-
return fmt.Errorf("getting public key: %w", err)
91-
}
92-
93-
akDigest, err := sha512sum(pubKey)
94-
if err != nil {
95-
return fmt.Errorf("calculating hash of attestation key: %w", err)
96-
}
97-
98-
if err := v.reportValidator.validate(attDoc, (*x509.Certificate)(&v.cfg.AMDSigningKey), (*x509.Certificate)(&v.cfg.AMDRootKey), akDigest, v.cfg, v.log); err != nil {
99-
return fmt.Errorf("validating SNP report: %w", err)
76+
if len(extraData) > 64 {
77+
return nil, fmt.Errorf("extra data too long: %d, should be 64 bytes at most", len(extraData))
10078
}
101-
return nil
102-
}
79+
extraData64 := make([]byte, 64)
80+
copy(extraData64, extraData)
10381

104-
// sha512sum PEM-encodes a public key and calculates the SHA512 hash of the encoded key.
105-
func sha512sum(key crypto.PublicKey) ([64]byte, error) {
106-
pub, err := x509.MarshalPKIXPublicKey(key)
107-
if err != nil {
108-
return [64]byte{}, fmt.Errorf("marshalling public key: %w", err)
82+
if err := v.reportValidator.validate(attDoc, (*x509.Certificate)(&v.cfg.AMDSigningKey), (*x509.Certificate)(&v.cfg.AMDRootKey), [64]byte(extraData64), v.cfg, v.log); err != nil {
83+
return nil, fmt.Errorf("validating SNP report: %w", err)
10984
}
11085

111-
return sha512.Sum512(pub), nil
86+
return ekPub, nil
11287
}
11388

11489
// snpReportValidator validates a given SNP report.
@@ -146,7 +121,7 @@ func (r *reportVerifierImpl) SnpAttestation(att *sevsnp.Attestation, opts *verif
146121
// validate the report by checking if it has a valid VCEK signature.
147122
// The certificate chain ARK -> ASK -> VCEK is also validated.
148123
// Checks that the report's userData matches the connection's userData.
149-
func (a *gcpValidator) validate(attestation vtpm.AttestationDocument, ask *x509.Certificate, ark *x509.Certificate, akDigest [64]byte, config *config.GCPSEVSNP, log attestation.Logger) error {
124+
func (a *gcpValidator) validate(attestation vtpm.AttestationDocument, ask *x509.Certificate, ark *x509.Certificate, reportData [64]byte, config *config.GCPSEVSNP, log attestation.Logger) error {
150125
var info snp.InstanceInfo
151126
if err := json.Unmarshal(attestation.InstanceInfo, &info); err != nil {
152127
return fmt.Errorf("unmarshalling instance info: %w", err)
@@ -170,7 +145,7 @@ func (a *gcpValidator) validate(attestation vtpm.AttestationDocument, ask *x509.
170145

171146
validateOpts := &validate.Options{
172147
// Check that the attestation key's digest is included in the report.
173-
ReportData: akDigest[:],
148+
ReportData: reportData[:],
174149
GuestPolicy: abi.SnpPolicy{
175150
Debug: false, // Debug means the VM can be decrypted by the host for debugging purposes and thus is not allowed.
176151
SMT: true, // Allow Simultaneous Multi-Threading (SMT). Normally, we would want to disable SMT

internal/attestation/gcp/snp/validator_test.go

-56
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,16 @@ SPDX-License-Identifier: AGPL-3.0-only
77
package snp
88

99
import (
10-
"bytes"
1110
"context"
1211
"crypto"
1312
"crypto/x509"
14-
"encoding/hex"
15-
"fmt"
1613
"testing"
1714

1815
"github.com/edgelesssys/constellation/v2/internal/attestation"
1916
"github.com/edgelesssys/constellation/v2/internal/attestation/vtpm"
2017
"github.com/edgelesssys/constellation/v2/internal/config"
2118
"github.com/google/go-tpm-tools/proto/attest"
2219
"github.com/stretchr/testify/assert"
23-
"github.com/stretchr/testify/require"
2420
)
2521

2622
func TestGetTrustedKey(t *testing.T) {
@@ -64,58 +60,6 @@ func TestGetTrustedKey(t *testing.T) {
6460
}
6561
}
6662

67-
func TestSha512sum(t *testing.T) {
68-
testCases := map[string]struct {
69-
key string
70-
hash string
71-
match bool
72-
}{
73-
"success": {
74-
// Generated using: rsa.GenerateKey(rand.Reader, 1024).
75-
key: "30819f300d06092a864886f70d010101050003818d0030818902818100d4b2f072a32fa98456eb7f5938e2ff361fb64d698ea91e003d34bfc5374b814c16ba9ae3ec392ef6d48cf79b63067e338aa941219a7bcdf18aa43cd38bbe5567504838a3b1dca482035458853c5a171709dfae9df551815010bdfbc6df733cde84c4f7a5b0591d9cda9db087fb411ee3e2a4f19ad50c8331712ecdc5dd7ce34b0203010001",
76-
hash: "2d6fe5ec59d7240b8a4c27c2ff27ba1071105fa50d45543768fcbabf9ee3cb8f8fa0afa51e08e053af30f6d11066ebfd47e75bda5ccc085c115d7e1896f3c62f",
77-
match: true,
78-
},
79-
"mismatching hash": {
80-
key: "30819f300d06092a864886f70d010101050003818d0030818902818100d4b2f072a32fa98456eb7f5938e2ff361fb64d698ea91e003d34bfc5374b814c16ba9ae3ec392ef6d48cf79b63067e338aa941219a7bcdf18aa43cd38bbe5567504838a3b1dca482035458853c5a171709dfae9df551815010bdfbc6df733cde84c4f7a5b0591d9cda9db087fb411ee3e2a4f19ad50c8331712ecdc5dd7ce34b0203010001",
81-
hash: "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
82-
match: false,
83-
},
84-
}
85-
86-
for name, tc := range testCases {
87-
t.Run(name, func(t *testing.T) {
88-
assert := assert.New(t)
89-
require := require.New(t)
90-
91-
newKey, err := loadKeyFromHex(tc.key)
92-
require.NoError(err)
93-
94-
// Function under test:
95-
hash, err := sha512sum(newKey)
96-
assert.NoError(err)
97-
98-
expected, err := hex.DecodeString(tc.hash)
99-
require.NoError(err)
100-
101-
if tc.match {
102-
assert.True(bytes.Equal(expected, hash[:]), fmt.Sprintf("expected hash %x, got %x", expected, hash))
103-
} else {
104-
assert.False(bytes.Equal(expected, hash[:]), fmt.Sprintf("expected mismatching hashes, got %x", hash))
105-
}
106-
})
107-
}
108-
}
109-
110-
func loadKeyFromHex(key string) (crypto.PublicKey, error) {
111-
decoded, err := hex.DecodeString(key)
112-
if err != nil {
113-
return nil, err
114-
}
115-
116-
return x509.ParsePKIXPublicKey(decoded)
117-
}
118-
11963
type stubGCPValidator struct{}
12064

12165
func (stubGCPValidator) validate(_ vtpm.AttestationDocument, _ *x509.Certificate, _ *x509.Certificate, _ [64]byte, _ *config.GCPSEVSNP, _ attestation.Logger) error {

0 commit comments

Comments
 (0)