From 93c77e9d9659732931beca9adabcdc0e4707f361 Mon Sep 17 00:00:00 2001 From: Dionna Glaze Date: Mon, 25 Sep 2023 22:49:31 +0000 Subject: [PATCH] Fix "modelstepping" handling in verification The "Milan-B0" naming in a product name is not directly derivable from the cpuid(1) values. Instead this B0 naming is from a different naming convention that comes from the development lifecycle that the manufacturer decides. Every stepping number that is visible to consumers is subject to a table lookup. That table can only be built from a piecemeal toilsome effort of following the manufacturers' publications about its product lines. This fix has been verified in hardware tests. Signed-off-by: Dionna Glaze --- abi/abi.go | 11 +++--- kds/kds.go | 76 +++++++++++++++++++++++++-------------- kds/kds_test.go | 48 ++++++++++--------------- proto/sevsnp.proto | 2 +- proto/sevsnp/sevsnp.pb.go | 57 +++++++++++++++-------------- testing/mocks.go | 4 +-- verify/verify.go | 34 ++++++++++++------ verify/verify_test.go | 26 ++++++-------- 8 files changed, 141 insertions(+), 117 deletions(-) diff --git a/abi/abi.go b/abi/abi.go index fe46476..84dc793 100644 --- a/abi/abi.go +++ b/abi/abi.go @@ -818,11 +818,12 @@ func SevProduct() *pb.SevProduct { // 15:14 reserved // 11:8 Family ID family := (eax >> 8) & 0xf - // 7:4 Model, 3:0 Stepping - modelStepping := eax & 0xff + // 3:0 Stepping + stepping := eax & 0xf // Ah, Fh, {0h,1h} values from the KDS specification, // section "Determining the Product Name". var productName pb.SevProduct_SevProductName + // Product information specified by processor programming reference publications. if extendedFamily == 0xA && family == 0xF { switch extendedModel { case 0: @@ -834,12 +835,12 @@ func SevProduct() *pb.SevProduct { } } return &pb.SevProduct{ - Name: productName, - ModelStepping: modelStepping, + Name: productName, + Stepping: stepping, } } // DefaultSevProduct returns the initial product version for a commercially available AMD SEV-SNP chip. func DefaultSevProduct() *pb.SevProduct { - return &pb.SevProduct{Name: pb.SevProduct_SEV_PRODUCT_MILAN, ModelStepping: 0xB0} + return &pb.SevProduct{Name: pb.SevProduct_SEV_PRODUCT_MILAN, Stepping: 1} } diff --git a/kds/kds.go b/kds/kds.go index 2a646ff..3fcb685 100644 --- a/kds/kds.go +++ b/kds/kds.go @@ -84,6 +84,20 @@ var ( kdsBaseURL = "https://" + kdsHostname kdsVcekPath = "/vcek/v1/" kdsVlekPath = "/vlek/v1/" + + // Chip manufacturers assign stepping versions strings that are + // to describe a stepping number for a particular model chip. There is no way + // other than documentation to map a stepping number to a stepping version and + // vice versa. + steppingDecoder = map[string]*pb.SevProduct{ + "Milan-B0": {Name: pb.SevProduct_SEV_PRODUCT_MILAN, Stepping: 0}, + "Milan-B1": {Name: pb.SevProduct_SEV_PRODUCT_MILAN, Stepping: 1}, + "Genoa-B0": {Name: pb.SevProduct_SEV_PRODUCT_GENOA, Stepping: 0}, + "Genoa-B1": {Name: pb.SevProduct_SEV_PRODUCT_GENOA, Stepping: 1}, + "Genoa-B2": {Name: pb.SevProduct_SEV_PRODUCT_GENOA, Stepping: 2}, + } + milanSteppingVersions = []string{"B0", "B1"} + genoaSteppingVersions = []string{"B0", "B1", "B2"} ) // TCBVersion is a 64-bit bitfield of different security patch levels of AMD firmware and microcode. @@ -692,45 +706,55 @@ func ProductName(product *pb.SevProduct) string { if product == nil { product = abi.DefaultSevProduct() } - return fmt.Sprintf("%s-%02X", ProductString(product), product.ModelStepping) + if product.Stepping > 15 { + return "badstepping" + } + switch product.Name { + case pb.SevProduct_SEV_PRODUCT_MILAN: + if int(product.Stepping) >= len(milanSteppingVersions) { + return "unmappedMilanStepping" + } + return fmt.Sprintf("Milan-%s", milanSteppingVersions[product.Stepping]) + case pb.SevProduct_SEV_PRODUCT_GENOA: + if int(product.Stepping) >= len(genoaSteppingVersions) { + return "unmappedGenoaStepping" + } + return fmt.Sprintf("Milan-%s", genoaSteppingVersions[product.Stepping]) + default: + return "Unknown" + } +} + +func parseProduct(product string) (pb.SevProduct_SevProductName, error) { + switch product { + case "Milan": + return pb.SevProduct_SEV_PRODUCT_MILAN, nil + case "Genoa": + return pb.SevProduct_SEV_PRODUCT_GENOA, nil + default: + return pb.SevProduct_SEV_PRODUCT_UNKNOWN, fmt.Errorf("unknown AMD SEV product: %q", product) + } } // ParseProductName returns the KDS project input value, and the model, stepping numbers represented // by a given V[CL]EK productName extension value, or an error. func ParseProductName(productName string, key abi.ReportSigner) (*pb.SevProduct, error) { - var product, stepping string - var needStepping bool switch key { case abi.VcekReportSigner: - subs := strings.SplitN(productName, "-", 2) - if len(subs) != 2 { - return nil, fmt.Errorf("productName value %q does not match the VCEK expected Name-ModelStepping format", productName) + product, ok := steppingDecoder[productName] + if !ok { + return nil, fmt.Errorf("unknown product name (new stepping published?): %q", productName) } - product = subs[0] - stepping = subs[1] - needStepping = true + return product, nil case abi.VlekReportSigner: // VLEK certificates don't carry the stepping value in productName. - product = productName - } - var name pb.SevProduct_SevProductName - switch product { - case "Milan": - name = pb.SevProduct_SEV_PRODUCT_MILAN - case "Genoa": - name = pb.SevProduct_SEV_PRODUCT_GENOA - default: - return nil, fmt.Errorf("unknown AMD SEV product: %q", product) - } - var modelStepping uint64 - if needStepping { - var err error - modelStepping, err = strconv.ParseUint(stepping, 16, 8) + name, err := parseProduct(productName) if err != nil { - return nil, fmt.Errorf("model stepping in productName is not a hexadecimal byte: %q", stepping) + return nil, err } + return &pb.SevProduct{Name: name}, nil } - return &pb.SevProduct{Name: name, ModelStepping: uint32(modelStepping)}, nil + return nil, fmt.Errorf("internal: unhandled reportSigner %v", key) } // CrlLinkByKey returns the CRL distribution point for the given key type's diff --git a/kds/kds_test.go b/kds/kds_test.go index dd27e50..53924c3 100644 --- a/kds/kds_test.go +++ b/kds/kds_test.go @@ -185,29 +185,29 @@ func TestProductName(t *testing.T) { }{ { name: "nil", - want: "Milan-B0", + want: "Milan-B1", }, { name: "unknown", input: &pb.SevProduct{ - ModelStepping: 0x1A, + Stepping: 0x1A, }, - want: "Unknown-1A", + want: "badstepping", }, { - name: "Milan-00", + name: "Milan-B0", input: &pb.SevProduct{ Name: pb.SevProduct_SEV_PRODUCT_MILAN, }, - want: "Milan-00", + want: "Milan-B0", }, { name: "Genoa-FF", input: &pb.SevProduct{ - Name: pb.SevProduct_SEV_PRODUCT_GENOA, - ModelStepping: 0xFF, + Name: pb.SevProduct_SEV_PRODUCT_GENOA, + Stepping: 0xFF, }, - want: "Genoa-FF", + want: "badstepping", }, } for _, tc := range tcs { @@ -229,36 +229,26 @@ func TestParseProductName(t *testing.T) { }{ { name: "empty", - wantErr: "does not match", - }, - { - name: "Too much", - input: "Milan-B0-and some extra", - wantErr: "not a hexadecimal byte: \"B0-and some extra\"", - }, - { - name: "start-", - input: "-00", - wantErr: "unknown AMD SEV product: \"\"", - }, - { - name: "end-", - input: "Milan-", - wantErr: "model stepping in productName is not a hexadecimal byte: \"\"", + wantErr: "unknown product name", }, { name: "Too big", input: "Milan-100", - wantErr: "model stepping in productName is not a hexadecimal byte: \"100\"", + wantErr: "unknown product name", }, { - name: "happy path", - input: "Genoa-9C", + name: "happy path Genoa", + input: "Genoa-B1", want: &pb.SevProduct{ - Name: pb.SevProduct_SEV_PRODUCT_GENOA, - ModelStepping: 0x9C, + Name: pb.SevProduct_SEV_PRODUCT_GENOA, + Stepping: 1, }, }, + { + name: "bad revision Milan", + input: "Milan-A1", + wantErr: "unknown product name", + }, { name: "vlek products have no stepping", input: "Genoa", diff --git a/proto/sevsnp.proto b/proto/sevsnp.proto index a9ef743..3c04d95 100644 --- a/proto/sevsnp.proto +++ b/proto/sevsnp.proto @@ -90,7 +90,7 @@ message SevProduct { } SevProductName name = 1; - uint32 model_stepping = 2; // Must be a byte + uint32 stepping = 2; // Must be a 4-bit number } message Attestation { diff --git a/proto/sevsnp/sevsnp.pb.go b/proto/sevsnp/sevsnp.pb.go index 0e5ed9f..eed9fae 100644 --- a/proto/sevsnp/sevsnp.pb.go +++ b/proto/sevsnp/sevsnp.pb.go @@ -462,8 +462,8 @@ type SevProduct struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Name SevProduct_SevProductName `protobuf:"varint,1,opt,name=name,proto3,enum=sevsnp.SevProduct_SevProductName" json:"name,omitempty"` - ModelStepping uint32 `protobuf:"varint,2,opt,name=model_stepping,json=modelStepping,proto3" json:"model_stepping,omitempty"` // Must be a byte + Name SevProduct_SevProductName `protobuf:"varint,1,opt,name=name,proto3,enum=sevsnp.SevProduct_SevProductName" json:"name,omitempty"` + Stepping uint32 `protobuf:"varint,2,opt,name=stepping,proto3" json:"stepping,omitempty"` // Must be a 4-bit number } func (x *SevProduct) Reset() { @@ -505,9 +505,9 @@ func (x *SevProduct) GetName() SevProduct_SevProductName { return SevProduct_SEV_PRODUCT_UNKNOWN } -func (x *SevProduct) GetModelStepping() uint32 { +func (x *SevProduct) GetStepping() uint32 { if x != nil { - return x.ModelStepping + return x.Stepping } return 0 } @@ -656,34 +656,33 @@ var file_sevsnp_proto_rawDesc = []byte{ 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xc3, 0x01, 0x0a, 0x0a, 0x53, 0x65, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb8, 0x01, 0x0a, 0x0a, 0x53, 0x65, 0x76, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x12, 0x35, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e, 0x73, 0x65, 0x76, 0x73, 0x6e, 0x70, 0x2e, 0x53, 0x65, 0x76, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x2e, 0x53, 0x65, 0x76, 0x50, 0x72, 0x6f, - 0x64, 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, - 0x0a, 0x0e, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x70, 0x69, 0x6e, 0x67, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x53, 0x74, 0x65, - 0x70, 0x70, 0x69, 0x6e, 0x67, 0x22, 0x57, 0x0a, 0x0e, 0x53, 0x65, 0x76, 0x50, 0x72, 0x6f, 0x64, - 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x45, 0x56, 0x5f, 0x50, - 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, - 0x12, 0x15, 0x0a, 0x11, 0x53, 0x45, 0x56, 0x5f, 0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x5f, - 0x4d, 0x49, 0x4c, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x45, 0x56, 0x5f, 0x50, - 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x5f, 0x47, 0x45, 0x4e, 0x4f, 0x41, 0x10, 0x02, 0x22, 0xaa, - 0x01, 0x0a, 0x0b, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, - 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0e, - 0x2e, 0x73, 0x65, 0x76, 0x73, 0x6e, 0x70, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x06, - 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x45, 0x0a, 0x11, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, - 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x65, 0x76, 0x73, 0x6e, 0x70, 0x2e, 0x43, 0x65, 0x72, 0x74, 0x69, - 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x52, 0x10, 0x63, 0x65, 0x72, - 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x2c, 0x0a, - 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, - 0x2e, 0x73, 0x65, 0x76, 0x73, 0x6e, 0x70, 0x2e, 0x53, 0x65, 0x76, 0x50, 0x72, 0x6f, 0x64, 0x75, - 0x63, 0x74, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x42, 0x2d, 0x5a, 0x2b, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x67, 0x6f, 0x2d, 0x73, 0x65, 0x76, 0x2d, 0x67, 0x75, 0x65, 0x73, 0x74, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x76, 0x73, 0x6e, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x64, 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x73, 0x74, 0x65, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x08, 0x73, 0x74, 0x65, 0x70, 0x70, 0x69, 0x6e, 0x67, 0x22, 0x57, 0x0a, 0x0e, 0x53, 0x65, + 0x76, 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x17, 0x0a, 0x13, + 0x53, 0x45, 0x56, 0x5f, 0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, + 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x45, 0x56, 0x5f, 0x50, 0x52, 0x4f, + 0x44, 0x55, 0x43, 0x54, 0x5f, 0x4d, 0x49, 0x4c, 0x41, 0x4e, 0x10, 0x01, 0x12, 0x15, 0x0a, 0x11, + 0x53, 0x45, 0x56, 0x5f, 0x50, 0x52, 0x4f, 0x44, 0x55, 0x43, 0x54, 0x5f, 0x47, 0x45, 0x4e, 0x4f, + 0x41, 0x10, 0x02, 0x22, 0xaa, 0x01, 0x0a, 0x0b, 0x41, 0x74, 0x74, 0x65, 0x73, 0x74, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x73, 0x65, 0x76, 0x73, 0x6e, 0x70, 0x2e, 0x52, 0x65, 0x70, + 0x6f, 0x72, 0x74, 0x52, 0x06, 0x72, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x45, 0x0a, 0x11, 0x63, + 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x65, 0x76, 0x73, 0x6e, 0x70, 0x2e, + 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x69, 0x6e, + 0x52, 0x10, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, + 0x69, 0x6e, 0x12, 0x2c, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x65, 0x76, 0x73, 0x6e, 0x70, 0x2e, 0x53, 0x65, 0x76, + 0x50, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, 0x74, + 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x67, 0x6f, 0x2d, 0x73, 0x65, 0x76, 0x2d, 0x67, 0x75, 0x65, + 0x73, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x65, 0x76, 0x73, 0x6e, 0x70, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/testing/mocks.go b/testing/mocks.go index 7afabb7..d6c4fa9 100644 --- a/testing/mocks.go +++ b/testing/mocks.go @@ -144,8 +144,8 @@ func (d *Device) Ioctl(command uintptr, req any) (uintptr, error) { func (d *Device) Product() *spb.SevProduct { if d.SevProduct == nil { return &spb.SevProduct{ - Name: spb.SevProduct_SEV_PRODUCT_MILAN, - ModelStepping: 0xB0, + Name: spb.SevProduct_SEV_PRODUCT_MILAN, + Stepping: 0, // Milan-B0 is the product name we fake. } } return d.SevProduct diff --git a/verify/verify.go b/verify/verify.go index d74bffb..8f8bca8 100644 --- a/verify/verify.go +++ b/verify/verify.go @@ -451,9 +451,9 @@ func checkProductName(got, want *spb.SevProduct, key abi.ReportSigner) error { return fmt.Errorf("%v cert product name %v is not %v", key, got, want) } // The model stepping number is only part of the VLEK product name, not VLEK's. - if key == abi.VcekReportSigner && got.ModelStepping != want.ModelStepping { - return fmt.Errorf("%v cert product model-stepping number %02X is not %02X", - key, got.ModelStepping, want.ModelStepping) + if key == abi.VcekReportSigner && got.Stepping != want.Stepping { + return fmt.Errorf("%v cert product stepping number %02X is not %02X", + key, got.Stepping, want.Stepping) } return nil } @@ -483,6 +483,7 @@ func decodeCerts(chain *spb.CertificateChain, key abi.ReportSigner, options *Opt if err != nil { return nil, nil, err } + fmt.Println("product", exts.ProductName, product) productName := kds.ProductString(product) // Ensure the extension product info matches expectations. if err := checkProductName(product, options.Product, key); err != nil { @@ -650,15 +651,13 @@ func SnpAttestation(attestation *spb.Attestation, options *Options) error { // fillInAttestation uses AMD's KDS to populate any empty certificate field in the attestation's // certificate chain. func fillInAttestation(attestation *spb.Attestation, options *Options) error { + var productOverridden bool if options.Product != nil { attestation.Product = options.Product - } - if attestation.Product == nil { - // The default product is the first launched SEV-SNP product value. - attestation.Product = &spb.SevProduct{ - Name: spb.SevProduct_SEV_PRODUCT_MILAN, - ModelStepping: 0xB0, - } + productOverridden = true + } else if attestation.Product == nil { + attestation.Product = abi.DefaultSevProduct() + productOverridden = true } if options.DisableCertFetching { return nil @@ -702,6 +701,21 @@ func fillInAttestation(attestation *spb.Attestation, options *Options) error { } } chain.VcekCert = vcek + if productOverridden { + cert, err := x509.ParseCertificate(vcek) + if err != nil { + return err + } + exts, err := kds.VcekCertificateExtensions(cert) + if err != nil { + return err + } + attestation.Product, err = kds.ParseProductName(exts.ProductName, abi.VcekReportSigner) + fmt.Printf("filled in product with %v\n", attestation.Product) + if err != nil { + return err + } + } } case abi.VlekReportSigner: // We can't lazily ask KDS for the certificate as a user. The CSP must cache their provisioned diff --git a/verify/verify_test.go b/verify/verify_test.go index 6b7a1cf..745bbfc 100644 --- a/verify/verify_test.go +++ b/verify/verify_test.go @@ -291,7 +291,7 @@ func TestKdsMetadataLogic(t *testing.T) { }, }, }, - wantErr: "unknown AMD SEV product: \"Cookie\"", + wantErr: "unknown product", }, } for _, tc := range tests { @@ -474,24 +474,20 @@ func TestOpenGetExtendedReportVerifyClose(t *testing.T) { options := &Options{TrustedRoots: goodRoots, Getter: kds} badOptions := &Options{TrustedRoots: badRoots, Getter: kds} for _, tc := range tests { - t.Run(tc.Name, func(t *testing.T) { - if testclient.SkipUnmockableTestCase(&tc) { - t.Skip() - return - } - - for _, getReport := range reportGetters { + if testclient.SkipUnmockableTestCase(&tc) { + t.Run(tc.Name, func(t *testing.T) { t.Skip() }) + } + for _, getReport := range reportGetters { + t.Run(tc.Name+"_"+getReport.name, func(t *testing.T) { if getReport.skipVlek && tc.EK == test.KeyChoiceVlek { t.Skip() - continue } if getReport.vlekOnly && tc.EK != test.KeyChoiceVlek { t.Skip() - continue } ereport, err := getReport.getter(d, tc.Input) if !test.Match(err, tc.WantErr) { - t.Fatalf("%s: %s(d, %v) = %v, %v. Want err: %v", tc.Name, getReport.name, tc.Input, ereport, err, tc.WantErr) + t.Fatalf("(d, %v) = %v, %v. Want err: %v", tc.Input, ereport, err, tc.WantErr) } if tc.WantErr == "" { var wantAttestationErr string @@ -507,12 +503,12 @@ func TestOpenGetExtendedReportVerifyClose(t *testing.T) { wantBad = getReport.vlekBadRootErr } if err := SnpAttestation(ereport, badOptions); !test.Match(err, wantBad) { - t.Errorf("%s: SnpAttestation(_) bad root test errored unexpectedly: %v, want %s", - getReport.name, err, wantBad) + t.Errorf("SnpAttestation(_) bad root test errored unexpectedly: %v, want %s", + err, wantBad) } } - } - }) + }) + } } }