From 01b2e0a4e54101f194dac0aa55a5709c0d4a9de2 Mon Sep 17 00:00:00 2001 From: Dionna Glaze Date: Thu, 29 Sep 2022 00:15:13 +0000 Subject: [PATCH 1/2] Use "product" consistently with AMD's use The code conflates platform with product, which is not particularly helpful. Change wording to match AMD's use from the KDS documentation to keep the code clear. Signed-off-by: Dionna Glaze --- README.md | 4 +-- kds/kds.go | 24 +++++++-------- verify/verify.go | 68 +++++++++++++++++++++---------------------- verify/verify_test.go | 38 ++++++++++++------------ 4 files changed, 67 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 58c0a64..706fb57 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ This type contains three fields: certificate revocation list (CRL) and check for revocations. * `Getter HTTPSGetter`: must be non-`nil` if `CheckRevocations` is true. * `TrustedRoots map[string][]*AMDRootCerts`: if `nil`, uses the library's embedded certificates. - Maps a platform name to all allowed root certifications for that platform (e.g., Milan). + Maps a product name to all allowed root certifications for that product (e.g., Milan). The `HTTPSGetter` interface consists of a single method `Get(url string) ([]byte, error)` that should return the body of the HTTPS response. @@ -101,7 +101,7 @@ The `HTTPSGetter` interface consists of a single method `Get(url string) This type has 6 fields, the first 3 of which are mandatory: -* `Platform string`: the name of the platform this bundle is for (e.g., `"Milan"`). +* `Product string`: the name of the product this bundle is for (e.g., `"Milan"`). * `AskX509 *x509.Certificate`: an X.509 representation of the AMD SEV Signer intermediate key (ASK)'s certificate. * `ArkX509 *x509.Certificate`: an X.509 representation of the AMD SEV Root key (ARK)'s certificate. * `AskSev *abi.AskCert`: if non-`nil`, will cross-check with diff --git a/kds/kds.go b/kds/kds.go index c80964e..dec1a6e 100644 --- a/kds/kds.go +++ b/kds/kds.go @@ -339,9 +339,9 @@ func VcekCertificateExtensions(cert *x509.Certificate) (*VcekExtensions, error) return extensions, nil } -// ParsePlatformCertChain returns the DER-formatted certificates represented by the body -// of the PlatformCertChain (cert_chain) endpoint, ASK and ARK in that order. -func ParsePlatformCertChain(pems []byte) ([]byte, []byte, error) { +// ParseProductCertChain returns the DER-formatted certificates represented by the body +// of the ProductCertChain (cert_chain) endpoint, ASK and ARK in that order. +func ParseProductCertChain(pems []byte) ([]byte, []byte, error) { checkForm := func(name string, b *pem.Block) error { if b == nil { return fmt.Errorf("could not find %s PEM block", name) @@ -365,23 +365,23 @@ func ParsePlatformCertChain(pems []byte) ([]byte, []byte, error) { return askBlock.Bytes, arkBlock.Bytes, nil } -// platformBaseURL returns the base URL for all certificate queries within a particular platform. -func platformBaseURL(name string) string { +// productBaseURL returns the base URL for all certificate queries within a particular product. +func productBaseURL(name string) string { return fmt.Sprintf("%s/vcek/v1/%s", kdsBaseURL, name) } -// PlatformCertChainURL returns the AMD KDS URL for retrieving the ARK and ASK -// certificates on the given platform in PEM format. -func PlatformCertChainURL(platform string) string { - return fmt.Sprintf("%s/cert_chain", platformBaseURL(platform)) +// ProductCertChainURL returns the AMD KDS URL for retrieving the ARK and ASK +// certificates on the given product in PEM format. +func ProductCertChainURL(product string) string { + return fmt.Sprintf("%s/cert_chain", productBaseURL(product)) } -// VCEKCertURL returns the AMD KDS URL for retrieving the VCEK on a given platform +// VCEKCertURL returns the AMD KDS URL for retrieving the VCEK on a given product // at a given TCB version. The hwid is the CHIP_ID field in an attestation report. -func VCEKCertURL(platform string, hwid []byte, tcb TCBVersion) string { +func VCEKCertURL(product string, hwid []byte, tcb TCBVersion) string { parts := DecomposeTCBVersion(tcb) return fmt.Sprintf("%s/%s?blSPL=%d&teeSPL=%d&snpSPL=%d&ucodeSPL=%d", - platformBaseURL(platform), + productBaseURL(product), hex.EncodeToString(hwid), parts.BlSpl, parts.TeeSpl, diff --git a/verify/verify.go b/verify/verify.go index 839fdaf..0561871 100644 --- a/verify/verify.go +++ b/verify/verify.go @@ -57,15 +57,15 @@ const ( // The VCEK productName in includes the specific silicon stepping // corresponding to the supplied hwID. For example, “Milan-B0”. -// The product should inform what platform keys we expect the key to be certified by. +// The product should inform what product keys we expect the key to be certified by. var vcekProductMap = map[string]string{ "Milan-B0": "Milan", } // AMDRootCerts encapsulates the certificates that represent root of trust in AMD. type AMDRootCerts struct { - // Platform is the expected CPU platform name, e.g., Milan, Turin, Genoa. - Platform string + // Product is the expected CPU product name, e.g., Milan, Turin, Genoa. + Product string // AskX509 is an X.509 certificate for the AMD SEV signing key (ASK) AskX509 *x509.Certificate // ArkX509 is an X.509 certificate for the AMD root key (ARK). @@ -78,7 +78,7 @@ type AMDRootCerts struct { ArkSev *abi.AskCert // Protects concurrent updates to CRL. mu sync.Mutex - // CRL is the certificate revocation list for this AMD platform. Populated once, only when a + // CRL is the certificate revocation list for this AMD product. Populated once, only when a // revocation is checked. CRL *x509.RevocationList } @@ -122,7 +122,7 @@ func (r *AMDRootCerts) FromDER(ask []byte, ark []byte) error { // certificates in data. This is the format the Key Distribution Service (KDS) uses, e.g., // https://kdsintf.amd.com/vcek/v1/Milan/cert_chain func (r *AMDRootCerts) FromKDSCertBytes(data []byte) error { - ask, ark, err := kds.ParsePlatformCertChain(data) + ask, ark, err := kds.ParseProductCertChain(data) if err != nil { return err } @@ -198,7 +198,7 @@ func crossCheckSevX509(sev *abi.AskCert, x *x509.Certificate) error { return fmt.Errorf("cross-check failed: SEV cert public key (%v) not equal to X.509 public key (%v)", pub, certPub) } default: - return fmt.Errorf("platform public key not RSA: %v", x.PublicKey) + return fmt.Errorf("product public key not RSA: %v", x.PublicKey) } return nil } @@ -233,8 +233,8 @@ func validateAmdLocation(name pkix.Name, role string) error { return nil } -func validateCRLlink(x *x509.Certificate, platform, role string) error { - url := fmt.Sprintf("https://kdsintf.amd.com/vcek/v1/%s/crl", platform) +func validateCRLlink(x *x509.Certificate, product, role string) error { + url := fmt.Sprintf("https://kdsintf.amd.com/vcek/v1/%s/crl", product) if len(x.CRLDistributionPoints) != 1 { return fmt.Errorf("%s has %d CRL distribution points, want 1", role, len(x.CRLDistributionPoints)) } @@ -258,11 +258,11 @@ func (r *AMDRootCerts) validateRootX509(x *x509.Certificate, version int, role, if err := validateAmdLocation(x.Subject, fmt.Sprintf("%s subject", role)); err != nil { return err } - // Only check platform name if it's specified. + // Only check product name if it's specified. if cn != "" && x.Subject.CommonName != cn { return fmt.Errorf("%s common-name is %s. Expected %s", role, x.Subject.CommonName, cn) } - return validateCRLlink(x, r.Platform, role) + return validateCRLlink(x, r.Product, role) } // ValidateAskX509 checks expected metadata about the ASK X.509 certificate. It does not verify the @@ -272,8 +272,8 @@ func (r *AMDRootCerts) ValidateAskX509() error { r = DefaultRootCerts["Milan"] } var cn string - if r.Platform != "" { - cn = fmt.Sprintf("SEV-%s", r.Platform) + if r.Product != "" { + cn = fmt.Sprintf("SEV-%s", r.Product) } if err := r.validateRootX509(r.AskX509, askX509Version, "ASK", cn); err != nil { return err @@ -291,8 +291,8 @@ func (r *AMDRootCerts) ValidateArkX509() error { r = DefaultRootCerts["Milan"] } var cn string - if r.Platform != "" { - cn = fmt.Sprintf("ARK-%s", r.Platform) + if r.Product != "" { + cn = fmt.Sprintf("ARK-%s", r.Product) } if err := r.validateRootX509(r.ArkX509, arkX509Version, "ARK", cn); err != nil { return err @@ -361,7 +361,7 @@ func (r *AMDRootCerts) ValidateVcekCertIssuer(issuer pkix.Name) error { if err := validateAmdLocation(issuer, "VCEK issuer"); err != nil { return err } - cn := fmt.Sprintf("SEV-%s", r.Platform) + cn := fmt.Sprintf("SEV-%s", r.Product) if issuer.CommonName != cn { return fmt.Errorf("VCEK certificate issuer common name %s not expected. Expected %s", issuer.CommonName, cn) } @@ -377,13 +377,13 @@ func ValidateVcekExtensions(exts *kds.VcekExtensions) error { return nil } -// validateVcekCertificatePlatformNonspecific returns an error if the given certificate doesn't have +// validateVcekCertificateProductNonspecific returns an error if the given certificate doesn't have // the documented qualities of a VCEK certificate according to Key Distribution Service // documentation: // https://www.amd.com/system/files/TechDocs/57230.pdf // This does not check the certificate revocation list since that requires internet access. // If valid, then returns the VCEK-specific certificate extensions in the VcekExtensions type. -func validateVcekCertificatePlatformNonspecific(cert *x509.Certificate) (*kds.VcekExtensions, error) { +func validateVcekCertificateProductNonspecific(cert *x509.Certificate) (*kds.VcekExtensions, error) { if cert.Version != 3 { return nil, fmt.Errorf("VCEK certificate version is %v, expected 3", cert.Version) } @@ -419,7 +419,7 @@ func validateVcekCertificatePlatformNonspecific(cert *x509.Certificate) (*kds.Vc return exts, nil } -func (r *AMDRootCerts) validateVcekCertificatePlatformSpecifics(cert *x509.Certificate) error { +func (r *AMDRootCerts) validateVcekCertificateProductSpecifics(cert *x509.Certificate) error { if err := r.ValidateVcekCertIssuer(cert.Issuer); err != nil { return err } @@ -438,18 +438,18 @@ func VcekDER(vcek []byte, ask []byte, ark []byte, options *Options) (*x509.Certi if err != nil { return nil, nil, fmt.Errorf("could not interpret VCEK DER bytes: %v", err) } - exts, err := validateVcekCertificatePlatformNonspecific(vcekCert) + exts, err := validateVcekCertificateProductNonspecific(vcekCert) if err != nil { return nil, nil, err } roots := options.TrustedRoots - platform := vcekProductMap[exts.ProductName] + product := vcekProductMap[exts.ProductName] if roots == nil { root := &AMDRootCerts{ - Platform: platform, + Product: product, // Require that the root matches embedded root certs. - AskSev: DefaultRootCerts[platform].AskSev, - ArkSev: DefaultRootCerts[platform].ArkSev, + AskSev: DefaultRootCerts[product].AskSev, + ArkSev: DefaultRootCerts[product].ArkSev, } if err := root.FromDER(ask, ark); err != nil { return nil, nil, err @@ -458,16 +458,16 @@ func VcekDER(vcek []byte, ask []byte, ark []byte, options *Options) (*x509.Certi return nil, nil, err } roots = map[string][]*AMDRootCerts{ - platform: {root}, + product: {root}, } } var lastErr error - for _, platformRoot := range roots[platform] { - if err := platformRoot.validateVcekCertificatePlatformSpecifics(vcekCert); err != nil { + for _, productRoot := range roots[product] { + if err := productRoot.validateVcekCertificateProductSpecifics(vcekCert); err != nil { lastErr = err continue } - return vcekCert, platformRoot, nil + return vcekCert, productRoot, nil } return nil, nil, fmt.Errorf("VCEK could not be verified by any trusted roots. Last error: %v", lastErr) } @@ -515,7 +515,7 @@ type Options struct { Getter HTTPSGetter // TrustedRoots specifies the ARK and ASK certificates to trust when checking the VCEK. If nil, // then verification will fall back on embedded AMD-published root certificates. - // Maps the platform name to an array of allowed roots. + // Maps the product name to an array of allowed roots. TrustedRoots map[string][]*AMDRootCerts } @@ -579,19 +579,19 @@ type AttestationRecreationErr struct { // fillInAttestation uses AMD's KDS to populate any empty certificate field in the attestation's // certificate chain. func fillInAttestation(attestation *spb.Attestation, getter HTTPSGetter) error { - // TODO(Issue #11): Determine the platform a report was fetched from, or make this an option. - platform := "Milan" + // TODO(Issue #11): Determine the product a report was fetched from, or make this an option. + product := "Milan" if getter == nil { getter = &SimpleHTTPSGetter{} } report := attestation.GetReport() chain := attestation.GetCertificateChain() if len(chain.GetAskCert()) == 0 || len(chain.GetArkCert()) == 0 { - askark, err := getter.Get(kds.PlatformCertChainURL(platform)) + askark, err := getter.Get(kds.ProductCertChainURL(product)) if err != nil { return AttestationRecreationErr{fmt.Errorf("could not download ASK and ARK certificates: %v", err)} } - ask, ark, err := kds.ParsePlatformCertChain(askark) + ask, ark, err := kds.ParseProductCertChain(askark) if err != nil { // Treat a bad parse as a network error since it's likely due to an incomplete transfer. return AttestationRecreationErr{fmt.Errorf("could not parse root cert_chain: %v", err)} @@ -604,7 +604,7 @@ func fillInAttestation(attestation *spb.Attestation, getter HTTPSGetter) error { } } if len(chain.GetVcekCert()) == 0 { - vcekURL := kds.VCEKCertURL(platform, report.GetChipId(), kds.TCBVersion(report.GetCurrentTcb())) + vcekURL := kds.VCEKCertURL(product, report.GetChipId(), kds.TCBVersion(report.GetCurrentTcb())) vcek, err := getter.Get(vcekURL) if err != nil { return AttestationRecreationErr{fmt.Errorf("could not download VCEK certificate: %v", err)} @@ -687,7 +687,7 @@ func (r *AMDRootCerts) GetCrlAndCheckRoot(getter HTTPSGetter) (*x509.RevocationL } return r.CRL, nil } - return nil, CRLUnavailableErr{multierr.Append(errs, errors.New("could not fetch platform CRL"))} + return nil, CRLUnavailableErr{multierr.Append(errs, errors.New("could not fetch product CRL"))} } // verifyCRL checks that the VCEK CRL is signed by the ARK. Must be called after r.CRL is set. diff --git a/verify/verify_test.go b/verify/verify_test.go index 0dbc08f..18596c7 100644 --- a/verify/verify_test.go +++ b/verify/verify_test.go @@ -45,13 +45,13 @@ var milanBytes []byte //go:embed testdata/attestation.bin var attestationBytes []byte -const platform = "Milan" +const product = "Milan" var signMu sync.Once var signer *test.AmdSigner func initSigner() { - newSigner, err := test.DefaultCertChain(platform, time.Now()) + newSigner, err := test.DefaultCertChain(product, time.Now()) if err != nil { // Unexpected panic(err) } @@ -74,9 +74,9 @@ func TestEmbeddedCertsAppendixB3Expectations(t *testing.T) { func TestFakeCertsKDSExpectations(t *testing.T) { signMu.Do(initSigner) root := AMDRootCerts{ - Platform: platform, - ArkX509: signer.Ark, - AskX509: signer.Ask, + Product: product, + ArkX509: signer.Ark, + AskX509: signer.Ask, // No ArkSev or AskSev intentionally for test certs. } if err := root.ValidateArkX509(); err != nil { @@ -92,7 +92,7 @@ func TestParseVcekCert(t *testing.T) { if err != nil { t.Errorf("could not parse valid VCEK certificate: %v", err) } - if _, err := validateVcekCertificatePlatformNonspecific(cert); err != nil { + if _, err := validateVcekCertificateProductNonspecific(cert); err != nil { t.Errorf("could not validate valid VCEK certificate: %v", err) } } @@ -112,7 +112,7 @@ func TestVerifyVcekCert(t *testing.T) { if opts == nil { t.Fatalf("root x509 certificates missing: %v", root) } - // This time is within the 25 year lifespan of the Milan platform. + // This time is within the 25 year lifespan of the Milan product. opts.CurrentTime = time.Date(2022, time.September, 24, 1, 0, 0, 0, time.UTC) chains, err := vcek.Verify(*opts) if err != nil { @@ -292,9 +292,9 @@ func TestKdsMetadataLogic(t *testing.T) { // won't get tested. options := &Options{TrustedRoots: map[string][]*AMDRootCerts{ "Milan": {&AMDRootCerts{ - Platform: "Milan", - ArkX509: newSigner.Ark, - AskX509: newSigner.Ask, + Product: "Milan", + ArkX509: newSigner.Ark, + AskX509: newSigner.Ask, }}, }} if tc.wantErr != "" { @@ -356,9 +356,9 @@ func TestCRLRootValidity(t *testing.T) { Number: big.NewInt(1), } root := &AMDRootCerts{ - Platform: "Milan", - ArkX509: signer.Ark, - AskX509: signer.Ask, + Product: "Milan", + ArkX509: signer.Ark, + AskX509: signer.Ask, } // Now try signing a CRL with a different root that certifies Vcek with a different serial number. @@ -378,9 +378,9 @@ func TestCRLRootValidity(t *testing.T) { // Finally try checking a VCEK that's signed by a revoked ASK. root2 := &AMDRootCerts{ - Platform: "Milan", - ArkX509: signer2.Ark, - AskX509: signer2.Ask, + Product: "Milan", + ArkX509: signer2.Ark, + AskX509: signer2.Ask, } wantErr2 := "ASK was revoked at 2022-06-14 12:01:00 +0000 UTC" if err := root2.VcekNotRevoked(g2, signer2.Vcek); err == nil || !strings.Contains(err.Error(), wantErr2) { @@ -401,9 +401,9 @@ func TestOpenGetExtendedReportVerifyClose(t *testing.T) { // Trust the test device's root certs. options := &Options{TrustedRoots: map[string][]*AMDRootCerts{ "Milan": {&AMDRootCerts{ - Platform: "Milan", - ArkX509: d.Signer.Ark, - AskX509: d.Signer.Ask, + Product: "Milan", + ArkX509: d.Signer.Ark, + AskX509: d.Signer.Ask, }}}} for _, tc := range tests { ereport, err := sg.GetExtendedReport(d, tc.Input) From 75f16542c2f3b5a1f406df86631efb12f7dfae28 Mon Sep 17 00:00:00 2001 From: Dionna Glaze Date: Thu, 29 Sep 2022 00:21:34 +0000 Subject: [PATCH 2/2] Change UserData to ReportData for consistency The REPORT_DATA field is for users to supply their own data to include with the report, but the naming inconsistency with AMD's documentation is too confusing to make the name difference worth keeping. Signed-off-by: Dionna Glaze --- README.md | 4 ++-- client/client.go | 44 ++++++++++++++++++------------------ client/linuxabi/linux_abi.go | 4 ++-- testing/mocks.go | 14 ++++++------ testing/test_cases.go | 18 +++++++-------- validate/validate.go | 6 ++--- validate/validate_test.go | 32 +++++++++++++------------- 7 files changed, 61 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 706fb57..c366286 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ This function creates a file descriptor to the `/dev/sev-guest` device and returns an object that has methods encapsulating commands to the device. When done, remember to `Close()` the device. -### `func GetExtendedReport(d Device, userData [64]byte) (*pb.Attestation, error)` +### `func GetExtendedReport(d Device, reportData [64]byte) (*pb.Attestation, error)` This function takes an object implementing the `Device` interface (e.g., a `LinuxDevice`) and returns the protocol buffer representation of the attestation @@ -134,7 +134,7 @@ fields of an attestation report. The fields that either can be skipped or must match the given value exactly are: -* `UserData` for the `REPORT_DATA` field +* `ReportData` for the `REPORT_DATA` field * `HostData` for the `HOST_DATA` field * `ImageID` for the `IMAGE_ID` field * `FamilyID` for the `FAMILY_ID` field diff --git a/client/client.go b/client/client.go index 83f5428..40302ec 100644 --- a/client/client.go +++ b/client/client.go @@ -46,12 +46,12 @@ func message(d Device, command uintptr, req *labi.SnpUserGuestRequest) error { // GetRawReportAtVmpl requests for an attestation report at the given VMPL that incorporates the // given user data. -func GetRawReportAtVmpl(d Device, userData [64]byte, vmpl int) ([]byte, error) { +func GetRawReportAtVmpl(d Device, reportData [64]byte, vmpl int) ([]byte, error) { var snpReportRsp labi.SnpReportRespABI userGuestReq := labi.SnpUserGuestRequest{ ReqData: &labi.SnpReportReqABI{ - UserData: userData, - Vmpl: uint32(vmpl), + ReportData: reportData, + Vmpl: uint32(vmpl), }, RespData: &snpReportRsp, } @@ -62,13 +62,13 @@ func GetRawReportAtVmpl(d Device, userData [64]byte, vmpl int) ([]byte, error) { } // GetRawReport requests for an attestation report at VMPL0 that incorporates the given user data. -func GetRawReport(d Device, userData [64]byte) ([]byte, error) { - return GetRawReportAtVmpl(d, userData, 0) +func GetRawReport(d Device, reportData [64]byte) ([]byte, error) { + return GetRawReportAtVmpl(d, reportData, 0) } // GetReportAtVmpl gets an attestation report at the given VMPL into its protobuf representation. -func GetReportAtVmpl(d Device, userData [64]byte, vmpl int) (*pb.Report, error) { - data, err := GetRawReportAtVmpl(d, userData, vmpl) +func GetReportAtVmpl(d Device, reportData [64]byte, vmpl int) (*pb.Report, error) { + data, err := GetRawReportAtVmpl(d, reportData, vmpl) if err != nil { return nil, err } @@ -76,21 +76,21 @@ func GetReportAtVmpl(d Device, userData [64]byte, vmpl int) (*pb.Report, error) } // GetReport gets an attestation report at VMPL0 into its protobuf representation. -func GetReport(d Device, userData [64]byte) (*pb.Report, error) { - return GetReportAtVmpl(d, userData, 0) +func GetReport(d Device, reportData [64]byte) (*pb.Report, error) { + return GetReportAtVmpl(d, reportData, 0) } -// getExtendedReportIn issues a GetExtendedReport command to the sev-guest driver with userData +// getExtendedReportIn issues a GetExtendedReport command to the sev-guest driver with reportData // input and certs as a destination for certificate data. If certs is empty, this function returns // the expected size of certs as its second result value. If certs is non-empty, this function -// returns the signed attestation report containing userData and the certificate chain for the +// returns the signed attestation report containing reportData and the certificate chain for the // report's endorsement key. -func getExtendedReportIn(d Device, userData [64]byte, vmpl int, certs []byte) ([]byte, uint32, error) { +func getExtendedReportIn(d Device, reportData [64]byte, vmpl int, certs []byte) ([]byte, uint32, error) { var snpReportRsp labi.SnpReportRespABI snpExtReportReq := labi.SnpExtendedReportReq{ Data: labi.SnpReportReqABI{ - UserData: userData, - Vmpl: uint32(vmpl), + ReportData: reportData, + Vmpl: uint32(vmpl), }, Certs: certs, CertsLength: uint32(len(certs)), @@ -122,13 +122,13 @@ func queryCertificateLength(d Device, vmpl int) (uint32, error) { // GetRawExtendedReportAtVmpl requests for an attestation report that incorporates the given user // data at the given VMPL, and additional key certificate information. -func GetRawExtendedReportAtVmpl(d Device, userData [64]byte, vmpl int) ([]byte, []byte, error) { +func GetRawExtendedReportAtVmpl(d Device, reportData [64]byte, vmpl int) ([]byte, []byte, error) { length, err := queryCertificateLength(d, vmpl) if err != nil { return nil, nil, fmt.Errorf("error querying certificate length: %v", err) } certs := make([]byte, length) - report, _, err := getExtendedReportIn(d, userData, vmpl, certs) + report, _, err := getExtendedReportIn(d, reportData, vmpl, certs) if err != nil { return nil, nil, err } @@ -137,13 +137,13 @@ func GetRawExtendedReportAtVmpl(d Device, userData [64]byte, vmpl int) ([]byte, // GetRawExtendedReport requests for an attestation report that incorporates the given user data, // and additional key certificate information. -func GetRawExtendedReport(d Device, userData [64]byte) ([]byte, []byte, error) { - return GetRawExtendedReportAtVmpl(d, userData, 0) +func GetRawExtendedReport(d Device, reportData [64]byte) ([]byte, []byte, error) { + return GetRawExtendedReportAtVmpl(d, reportData, 0) } // GetExtendedReportAtVmpl gets an extended attestation report at the given VMPL into a structured type. -func GetExtendedReportAtVmpl(d Device, userData [64]byte, vmpl int) (*pb.Attestation, error) { - reportBytes, certBytes, err := GetRawExtendedReportAtVmpl(d, userData, vmpl) +func GetExtendedReportAtVmpl(d Device, reportData [64]byte, vmpl int) (*pb.Attestation, error) { + reportBytes, certBytes, err := GetRawExtendedReportAtVmpl(d, reportData, vmpl) if err != nil { return nil, err } @@ -161,8 +161,8 @@ func GetExtendedReportAtVmpl(d Device, userData [64]byte, vmpl int) (*pb.Attesta } // GetExtendedReport gets an extended attestation report at VMPL0 into a structured type. -func GetExtendedReport(d Device, userData [64]byte) (*pb.Attestation, error) { - return GetExtendedReportAtVmpl(d, userData, 0) +func GetExtendedReport(d Device, reportData [64]byte) (*pb.Attestation, error) { + return GetExtendedReportAtVmpl(d, reportData, 0) } // GuestFieldSelect represents which guest-provided information will be mixed into a derived key. diff --git a/client/linuxabi/linux_abi.go b/client/linuxabi/linux_abi.go index 911f531..d81f380 100644 --- a/client/linuxabi/linux_abi.go +++ b/client/linuxabi/linux_abi.go @@ -108,8 +108,8 @@ func (err SevEsErr) Error() string { // SnpReportReqABI is Linux's sev-guest ioctl abi for sending a GET_REPORT request. See // include/uapi/linux/sev-guest.h type SnpReportReqABI struct { - // UserData to be included in the report - UserData [64]uint8 + // ReportData to be included in the report + ReportData [64]uint8 // Vmpl is the SEV-SNP VMPL level to be included in the report. // The kernel must have access to the corresponding VMPCK. diff --git a/testing/mocks.go b/testing/mocks.go index e67214c..2af920c 100644 --- a/testing/mocks.go +++ b/testing/mocks.go @@ -32,11 +32,11 @@ type GetReportResponse struct { // Device represents a sev-guest driver implementation with pre-programmed responses to commands. type Device struct { - isOpen bool - UserDataRsp map[string]interface{} - Keys map[string][]byte - Certs []byte - Signer *AmdSigner + isOpen bool + ReportDataRsp map[string]interface{} + Keys map[string][]byte + Certs []byte + Signer *AmdSigner } // Open changes the mock device's state to open. @@ -58,9 +58,9 @@ func (d *Device) Close() error { } func (d *Device) getReport(req *labi.SnpReportReqABI, rsp *labi.SnpReportRespABI, fwErr *uint64) (uintptr, error) { - mockRspI, ok := d.UserDataRsp[hex.EncodeToString(req.UserData[:])] + mockRspI, ok := d.ReportDataRsp[hex.EncodeToString(req.ReportData[:])] if !ok { - return 0, fmt.Errorf("test error: no response for %v", req.UserData) + return 0, fmt.Errorf("test error: no response for %v", req.ReportData) } mockRsp, ok := mockRspI.(*GetReportResponse) if !ok { diff --git a/testing/test_cases.go b/testing/test_cases.go index a93a817..f3cb69a 100644 --- a/testing/test_cases.go +++ b/testing/test_cases.go @@ -24,10 +24,10 @@ import ( labi "github.com/google/go-sev-guest/client/linuxabi" ) -// userZeros defines a UserData example that is all zeros +// userZeros defines a ReportData example that is all zeros var userZeros [64]byte -// userZeros1 defines a UserData example that is all zeros except the last byte is 1. +// userZeros1 defines a ReportData example that is all zeros except the last byte is 1. var userZeros1 = [64]byte{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -38,7 +38,7 @@ var userZeros1 = [64]byte{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} -// userZeros11 defines a UserData example that is all zeros except the last 2 bytes are both 1. +// userZeros11 defines a ReportData example that is all zeros except the last 2 bytes are both 1. var userZeros11 = [64]byte{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -91,7 +91,7 @@ var oneReport = ` // We can't sign the report with AMD keys, and verification isn't the client's responsibility, so // we keep the signature zeros. // Similarly, we leave the randomly-generated fields zero. -func TestRawReport(userData [64]byte) [labi.SnpReportRespReportSize]byte { +func TestRawReport(reportData [64]byte) [labi.SnpReportRespReportSize]byte { var r [labi.SnpReportRespReportSize]byte // Set Version to 2 binary.LittleEndian.PutUint32(r[0x00:0x04], 2) @@ -99,7 +99,7 @@ func TestRawReport(userData [64]byte) [labi.SnpReportRespReportSize]byte { // Signature algorithm ECC P-384 with SHA-384 is encoded as 1. binary.LittleEndian.PutUint32(r[0x34:0x38], 1) // Place user data in its report location. - copy(r[0x50:0x90], userData[:]) + copy(r[0x50:0x90], reportData[:]) return r } @@ -178,9 +178,9 @@ func TcDevice(tcs []TestCase, opts *DeviceOptions) (*Device, error) { } } return &Device{ - UserDataRsp: responses, - Certs: certs, - Signer: signer, - Keys: opts.Keys, + ReportDataRsp: responses, + Certs: certs, + Signer: signer, + Keys: opts.Keys, }, nil } diff --git a/validate/validate.go b/validate/validate.go index 5c034bc..39b0264 100644 --- a/validate/validate.go +++ b/validate/validate.go @@ -34,8 +34,8 @@ import ( type Options struct { // GuestPolicy is the maximum of acceptable guest policies. GuestPolicy abi.SnpPolicy - // UserData is the expected REPORT_DATA field. Must be nil or 64 bytes long. Not checked if nil. - UserData []byte + // ReportData is the expected REPORT_DATA field. Must be nil or 64 bytes long. Not checked if nil. + ReportData []byte // HostData is the expected HOST_DATA field. Must be nil or 32 bytes long. Not checked if nil. HostData []byte // ImageID is the expected IMAGE_ID field. Must be nil or 16 bytes long. Not checked if nil. @@ -139,7 +139,7 @@ func validateByteField(option, field string, size int, given, required []byte) e func validateVerbatimFields(report *spb.Report, options *Options) error { return multierr.Combine( - validateByteField("UserData", "REPORT_DATA", abi.ReportDataSize, report.GetReportData(), options.UserData), + validateByteField("ReportData", "REPORT_DATA", abi.ReportDataSize, report.GetReportData(), options.ReportData), validateByteField("HostData", "HOST_DATA", abi.HostDataSize, report.GetHostData(), options.HostData), validateByteField("FamilyID", "FAMILY_ID", abi.FamilyIDSize, report.GetFamilyId(), options.FamilyID), validateByteField("ImageID", "IMAGE_ID", abi.ImageIDSize, report.GetImageId(), options.ImageID), diff --git a/validate/validate_test.go b/validate/validate_test.go index 0082c79..6c1ef4f 100644 --- a/validate/validate_test.go +++ b/validate/validate_test.go @@ -265,7 +265,7 @@ func TestValidateSnpAttestation(t *testing.T) { } tests := []testCase{ { - name: "just userData", + name: "just reportData", attestation: func() *spb.Attestation { report, err := sg.GetReport(device0, nonce0s1) if err != nil { @@ -278,13 +278,13 @@ func TestValidateSnpAttestation(t *testing.T) { VcekCert: sign0.Vcek.Raw, }} }(), - opts: &Options{UserData: nonce0s1[:], GuestPolicy: abi.SnpPolicy{Debug: true}}, + opts: &Options{ReportData: nonce0s1[:], GuestPolicy: abi.SnpPolicy{Debug: true}}, }, { name: "deep check", attestation: attestation12345, opts: &Options{ - UserData: nonce12345[:], + ReportData: nonce12345[:], GuestPolicy: abi.SnpPolicy{Debug: true, SMT: true}, PlatformInfo: &abi.SnpPlatformInfo{SMTEnabled: true}, Measurement: measurement, @@ -306,7 +306,7 @@ func TestValidateSnpAttestation(t *testing.T) { name: "Minimum TCB checked", attestation: attestation12345, opts: &Options{ - UserData: nonce12345[:], + ReportData: nonce12345[:], GuestPolicy: abi.SnpPolicy{Debug: true, SMT: true}, PlatformInfo: &abi.SnpPlatformInfo{SMTEnabled: true}, MinimumTCB: kds.TCBParts{UcodeSpl: 0xff, SnpSpl: 0x05, BlSpl: 0x02}, @@ -317,7 +317,7 @@ func TestValidateSnpAttestation(t *testing.T) { name: "Minimum build checked", attestation: attestation12345, opts: &Options{ - UserData: nonce12345[:], + ReportData: nonce12345[:], GuestPolicy: abi.SnpPolicy{Debug: true, SMT: true}, PlatformInfo: &abi.SnpPlatformInfo{SMTEnabled: true}, MinimumBuild: 3, @@ -328,7 +328,7 @@ func TestValidateSnpAttestation(t *testing.T) { name: "Minimum version checked", attestation: attestation12345, opts: &Options{ - UserData: nonce12345[:], + ReportData: nonce12345[:], GuestPolicy: abi.SnpPolicy{Debug: true, SMT: true}, PlatformInfo: &abi.SnpPlatformInfo{SMTEnabled: true}, MinimumVersion: 0xff00, @@ -339,7 +339,7 @@ func TestValidateSnpAttestation(t *testing.T) { name: "Author key checked", attestation: attestation54321, opts: &Options{ - UserData: nonce54321[:], + ReportData: nonce54321[:], GuestPolicy: abi.SnpPolicy{Debug: true, SMT: true}, PlatformInfo: &abi.SnpPlatformInfo{SMTEnabled: true}, RequireAuthorKey: true, @@ -352,7 +352,7 @@ func TestValidateSnpAttestation(t *testing.T) { name: "PlatformInfo checked", attestation: attestation54321, opts: &Options{ - UserData: nonce54321[:], + ReportData: nonce54321[:], GuestPolicy: abi.SnpPolicy{Debug: true, SMT: true}, PlatformInfo: &abi.SnpPlatformInfo{}, }, @@ -362,7 +362,7 @@ func TestValidateSnpAttestation(t *testing.T) { name: "Requiring IDBlock requires trust", attestation: attestation12345, opts: &Options{ - UserData: nonce12345[:], + ReportData: nonce12345[:], GuestPolicy: abi.SnpPolicy{Debug: true, SMT: true}, PlatformInfo: &abi.SnpPlatformInfo{SMTEnabled: true}, RequireIDBlock: true, @@ -375,7 +375,7 @@ func TestValidateSnpAttestation(t *testing.T) { name: "accepted provisional by build", attestation: attestationb1455, opts: &Options{ - UserData: nonceb1455[:], + ReportData: nonceb1455[:], GuestPolicy: abi.SnpPolicy{Debug: true}, PermitProvisionalFirmware: true, }, @@ -383,14 +383,14 @@ func TestValidateSnpAttestation(t *testing.T) { { name: "rejected provisional by build", attestation: attestationb1455, - opts: &Options{UserData: nonceb1455[:], GuestPolicy: abi.SnpPolicy{Debug: true}}, + opts: &Options{ReportData: nonceb1455[:], GuestPolicy: abi.SnpPolicy{Debug: true}}, wantErr: "committed build number 1 does not match the current build number 2", }, { name: "accepted provisional by tcb", attestation: attestationcb1455, opts: &Options{ - UserData: noncecb1455[:], + ReportData: noncecb1455[:], GuestPolicy: abi.SnpPolicy{Debug: true}, PermitProvisionalFirmware: true, }, @@ -398,14 +398,14 @@ func TestValidateSnpAttestation(t *testing.T) { { name: "rejected provisional by tcb", attestation: attestationcb1455, - opts: &Options{UserData: noncecb1455[:], GuestPolicy: abi.SnpPolicy{Debug: true}}, + opts: &Options{ReportData: noncecb1455[:], GuestPolicy: abi.SnpPolicy{Debug: true}}, wantErr: "firmware's committed TCB 9270000000007f00 does not match the current TCB 9270000000007f1f", }, { name: "accepted provisional by version", attestation: attestation11355, opts: &Options{ - UserData: nonce11355[:], + ReportData: nonce11355[:], GuestPolicy: abi.SnpPolicy{Debug: true}, PermitProvisionalFirmware: true, }, @@ -413,7 +413,7 @@ func TestValidateSnpAttestation(t *testing.T) { { name: "rejected provisional by version", attestation: attestation11355, - opts: &Options{UserData: nonce11355[:], GuestPolicy: abi.SnpPolicy{Debug: true}}, + opts: &Options{ReportData: nonce11355[:], GuestPolicy: abi.SnpPolicy{Debug: true}}, wantErr: "committed API version (1.49) does not match the current API version (1.51)", }, } @@ -427,7 +427,7 @@ func TestValidateSnpAttestation(t *testing.T) { switch i { case 0: name = "REPORT_DATA" - opts.UserData = make([]byte, abi.ReportDataSize) + opts.ReportData = make([]byte, abi.ReportDataSize) case 1: name = "HOST_DATA" opts.HostData = make([]byte, abi.HostDataSize)