Skip to content

Commit

Permalink
Merge pull request #92 from deeglaze/hwproduct
Browse files Browse the repository at this point in the history
Fix check tool product behavior on hardware
  • Loading branch information
deeglaze authored Oct 19, 2023
2 parents 1265664 + 7e30aca commit 1298952
Show file tree
Hide file tree
Showing 16 changed files with 364 additions and 190 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ jobs:
run: go build -v ./...
- name: Test all packages
run: go test -v ./...
- name: Run Go Vet
run: go vet ./...

lint:
strategy:
Expand All @@ -70,7 +72,7 @@ jobs:
with:
go-version: ${{ matrix.go-version }}
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v3.3.0
uses: golangci/golangci-lint-action@v3.6.0
with:
version: latest
working-directory: ./
Expand All @@ -82,6 +84,7 @@ jobs:
-E revive
-E gofmt
-E goimports
--out-format=colored-line-number
--exclude-use-default=false
--max-same-issues=0
--max-issues-per-linter=0
Expand Down
10 changes: 7 additions & 3 deletions abi/abi.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/pborman/uuid"
"golang.org/x/crypto/cryptobyte"
"golang.org/x/crypto/cryptobyte/asn1"
"google.golang.org/protobuf/types/known/wrapperspb"
)

const (
Expand Down Expand Up @@ -835,12 +836,15 @@ func SevProduct() *pb.SevProduct {
}
}
return &pb.SevProduct{
Name: productName,
Stepping: stepping,
Name: productName,
MachineStepping: &wrapperspb.UInt32Value{Value: 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, Stepping: 1}
return &pb.SevProduct{
Name: pb.SevProduct_SEV_PRODUCT_MILAN,
MachineStepping: &wrapperspb.UInt32Value{Value: 1},
}
}
39 changes: 27 additions & 12 deletions kds/kds.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/google/go-sev-guest/abi"
pb "github.com/google/go-sev-guest/proto/sevsnp"
"go.uber.org/multierr"
"google.golang.org/protobuf/types/known/wrapperspb"
)

// Encapsulates the rest of the fields after AMD's V{C,L}EK OID classifier prefix 1.3.6.1.4.1.3704.1.
Expand Down Expand Up @@ -85,16 +86,19 @@ var (
kdsVcekPath = "/vcek/v1/"
kdsVlekPath = "/vlek/v1/"

uint0 = &wrapperspb.UInt32Value{Value: 0}
uint1 = &wrapperspb.UInt32Value{Value: 1}
uint2 = &wrapperspb.UInt32Value{Value: 2}
// Chip manufacturers assign stepping versions strings that are <letter><number>
// 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},
"Milan-B0": {Name: pb.SevProduct_SEV_PRODUCT_MILAN, MachineStepping: uint0},
"Milan-B1": {Name: pb.SevProduct_SEV_PRODUCT_MILAN, MachineStepping: uint1},
"Genoa-B0": {Name: pb.SevProduct_SEV_PRODUCT_GENOA, MachineStepping: uint0},
"Genoa-B1": {Name: pb.SevProduct_SEV_PRODUCT_GENOA, MachineStepping: uint1},
"Genoa-B2": {Name: pb.SevProduct_SEV_PRODUCT_GENOA, MachineStepping: uint2},
}
milanSteppingVersions = []string{"B0", "B1"}
genoaSteppingVersions = []string{"B0", "B1", "B2"}
Expand Down Expand Up @@ -700,32 +704,43 @@ func ProductString(product *pb.SevProduct) string {
}
}

// DefaultProductString returns the product string of the default SEV product.
func DefaultProductString() string {
return ProductString(abi.DefaultSevProduct())
}

// ProductName returns the expected productName extension value for the product associated
// with an attestation report proto.
func ProductName(product *pb.SevProduct) string {
if product == nil {
product = abi.DefaultSevProduct()
}
if product.Stepping > 15 {
// Can't produce a product name without a stepping value.
if product.MachineStepping == nil {
return "UnknownStepping"
}
stepping := product.MachineStepping.Value
if stepping > 15 {
return "badstepping"
}
switch product.Name {
case pb.SevProduct_SEV_PRODUCT_MILAN:
if int(product.Stepping) >= len(milanSteppingVersions) {
if int(stepping) >= len(milanSteppingVersions) {
return "unmappedMilanStepping"
}
return fmt.Sprintf("Milan-%s", milanSteppingVersions[product.Stepping])
return fmt.Sprintf("Milan-%s", milanSteppingVersions[stepping])
case pb.SevProduct_SEV_PRODUCT_GENOA:
if int(product.Stepping) >= len(genoaSteppingVersions) {
if int(stepping) >= len(genoaSteppingVersions) {
return "unmappedGenoaStepping"
}
return fmt.Sprintf("Milan-%s", genoaSteppingVersions[product.Stepping])
return fmt.Sprintf("Milan-%s", genoaSteppingVersions[stepping])
default:
return "Unknown"
}
}

func parseProduct(product string) (pb.SevProduct_SevProductName, error) {
// ParseProduct returns the SevProductName for a product name without the stepping suffix.
func ParseProduct(product string) (pb.SevProduct_SevProductName, error) {
switch product {
case "Milan":
return pb.SevProduct_SEV_PRODUCT_MILAN, nil
Expand All @@ -748,7 +763,7 @@ func ParseProductName(productName string, key abi.ReportSigner) (*pb.SevProduct,
return product, nil
case abi.VlekReportSigner:
// VLEK certificates don't carry the stepping value in productName.
name, err := parseProduct(productName)
name, err := ParseProduct(productName)
if err != nil {
return nil, err
}
Expand Down
19 changes: 14 additions & 5 deletions kds/kds_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"github.com/google/go-sev-guest/abi"
pb "github.com/google/go-sev-guest/proto/sevsnp"
"google.golang.org/protobuf/testing/protocmp"
"google.golang.org/protobuf/types/known/wrapperspb"
)

func TestProductCertChainURL(t *testing.T) {
Expand Down Expand Up @@ -190,7 +191,7 @@ func TestProductName(t *testing.T) {
{
name: "unknown",
input: &pb.SevProduct{
Stepping: 0x1A,
MachineStepping: &wrapperspb.UInt32Value{Value: 0x1A},
},
want: "badstepping",
},
Expand All @@ -199,13 +200,21 @@ func TestProductName(t *testing.T) {
input: &pb.SevProduct{
Name: pb.SevProduct_SEV_PRODUCT_MILAN,
},
want: "UnknownStepping",
},
{
name: "Milan-B0",
input: &pb.SevProduct{
Name: pb.SevProduct_SEV_PRODUCT_MILAN,
MachineStepping: &wrapperspb.UInt32Value{Value: 0},
},
want: "Milan-B0",
},
{
name: "Genoa-FF",
input: &pb.SevProduct{
Name: pb.SevProduct_SEV_PRODUCT_GENOA,
Stepping: 0xFF,
Name: pb.SevProduct_SEV_PRODUCT_GENOA,
MachineStepping: &wrapperspb.UInt32Value{Value: 0xff},
},
want: "badstepping",
},
Expand Down Expand Up @@ -240,8 +249,8 @@ func TestParseProductName(t *testing.T) {
name: "happy path Genoa",
input: "Genoa-B1",
want: &pb.SevProduct{
Name: pb.SevProduct_SEV_PRODUCT_GENOA,
Stepping: 1,
Name: pb.SevProduct_SEV_PRODUCT_GENOA,
MachineStepping: &wrapperspb.UInt32Value{Value: 1},
},
},
{
Expand Down
3 changes: 3 additions & 0 deletions proto/check.proto
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ syntax = "proto3";
package check;

import "google/protobuf/wrappers.proto";
import "sevsnp.proto";

option go_package = "github.com/google/go-sev-guest/proto/check";

Expand Down Expand Up @@ -50,6 +51,8 @@ message Policy {
repeated bytes trusted_author_key_hashes = 21;
repeated bytes trusted_id_keys = 22;
repeated bytes trusted_id_key_hashes = 23;
// The expected product that generated the attestation report. Stepping optional.
sevsnp.SevProduct product = 24;
}

// RootOfTrust represents configuration for which hardware root of trust
Expand Down
Loading

0 comments on commit 1298952

Please sign in to comment.