Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate go-eventlog into go-tdx-guest. #50

Merged
merged 2 commits into from
Sep 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
strategy:
matrix:
go-version:
- 1.19.x
- 1.20.x
os:
- macos-latest
- ubuntu-latest
Expand Down Expand Up @@ -61,7 +61,7 @@ jobs:
strategy:
matrix:
go-version:
- 1.19.x
- 1.20.x
os:
- ubuntu-latest
name: 'Lint ${{ matrix.dir }} (${{ matrix.os }}, Go ${{ matrix.go-version }})'
Expand All @@ -85,7 +85,7 @@ jobs:
strategy:
matrix:
go-version:
- 1.19.x
- 1.20.x
os:
- ubuntu-latest
name: 'Lint CGO (${{ matrix.os}}, Go ${{ matrix.go-version }})'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
go-version:
- 1.19.x
- 1.20.x
os:
- ubuntu-latest
name: 'Release for (${{ matrix.os}}, Go ${{ matrix.go-version }})'
Expand Down
11 changes: 6 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
module github.com/google/go-tdx-guest

go 1.19
go 1.20

require (
github.com/google/go-cmp v0.5.7
github.com/google/go-cmp v0.6.0
github.com/google/go-configfs-tsm v0.3.2
github.com/google/go-eventlog v0.0.1
github.com/google/go-sev-guest v0.8.0
github.com/google/logger v1.1.1
go.uber.org/multierr v1.11.0
golang.org/x/crypto v0.17.0
golang.org/x/sys v0.15.0
google.golang.org/protobuf v1.31.0
golang.org/x/sys v0.19.0
google.golang.org/protobuf v1.34.2
)

require golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
require github.com/google/go-tpm v0.9.0 // indirect
21 changes: 10 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-configfs-tsm v0.3.2 h1:ZYmHkdQavfsvVGDtX7RRda0gamelUNUhu0A9fbiuLmE=
github.com/google/go-configfs-tsm v0.3.2/go.mod h1:EL1GTDFMb5PZQWDviGfZV9n87WeGTR/JUg13RfwkgRo=
github.com/google/go-eventlog v0.0.1 h1:7lV3gf61LNDhfS9gQplqaJc/j9ztLhKKgZk/lR6vv4Q=
github.com/google/go-eventlog v0.0.1/go.mod h1:7huE5P8w2NTObSwSJjboHmB7ioBNblkijdzoVa2skfQ=
github.com/google/go-sev-guest v0.8.0 h1:IIZIqdcMJXgTm1nMvId442OUpYebbWDWa9bi9/lUUwc=
github.com/google/go-sev-guest v0.8.0/go.mod h1:hc1R4R6f8+NcJwITs0L90fYWTsBpd1Ix+Gur15sqHDs=
github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk=
github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU=
github.com/google/logger v1.1.1 h1:+6Z2geNxc9G+4D4oDO9njjjn2d0wN5d7uOo0vOIW1NQ=
github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
Expand All @@ -16,11 +18,8 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
107 changes: 107 additions & 0 deletions rtmr/ccel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

// Package rtmr provides the library functions:
// 1. extend and read TDX rtmr registers and their tcg maps.
// 2. replay the event log with the TDX quote.
package rtmr

import (
"fmt"

"github.com/google/go-eventlog/ccel"
"github.com/google/go-eventlog/common"
"github.com/google/go-eventlog/proto/state"
"github.com/google/go-eventlog/register"
"github.com/google/go-tdx-guest/abi"
tdxpb "github.com/google/go-tdx-guest/proto/tdx"
"github.com/google/go-tdx-guest/validate"
"github.com/google/go-tdx-guest/verify"
)

// ParseTdxCcelOpts allows for customizing the functionality of VerifyAttestation's TDX verification.
type ParseTdxCcelOpts struct {
Validation *validate.Options
Verification *verify.Options
ExtractOpt *ccel.ExtractOpts
}

func getRtmrsFromTdQuoteV4(quote *tdxpb.QuoteV4) (*register.RTMRBank, error) {
bank := register.RTMRBank{}
rtmrs := quote.TdQuoteBody.Rtmrs
for index, rtmr := range rtmrs {
bank.RTMRs = append(bank.RTMRs, register.RTMR{
Index: int(index),
Digest: rtmr,
})
// Tdx Quote V4 has a maximum of 4 RTMRs
if index > 3 {
return nil, fmt.Errorf("too many RTMRs in quote")
}
}
return &bank, nil
}

// GetRtmrsFromTdQuote extracts the RTMRs from a TDX attestation quote.
// It is the caller's responsibility to verify the quote before calling this function.
func GetRtmrsFromTdQuote(quote interface{}) (*register.RTMRBank, error) {
switch q := quote.(type) {
case *tdxpb.QuoteV4:
rtmrs, err := getRtmrsFromTdQuoteV4(q)
if err != nil {
return nil, err
}
return rtmrs, nil
default:
return nil, fmt.Errorf("unsupported quote type: %T", quote)
}
}

// TdxDefaultOpts returns a default validation policy and verification options for TDX
// attestation quote on GCE.
func TdxDefaultOpts(tdxNonce []byte) ParseTdxCcelOpts {
policy := &validate.Options{HeaderOptions: validate.HeaderOptions{},
TdQuoteBodyOptions: validate.TdQuoteBodyOptions{}}
policy.TdQuoteBodyOptions.ReportData = make([]byte, abi.ReportDataSize)
copy(policy.TdQuoteBodyOptions.ReportData, tdxNonce)
return ParseTdxCcelOpts{
Validation: policy,
Verification: verify.DefaultOptions(),
ExtractOpt: &ccel.ExtractOpts{Loader: common.GRUB},
}
}

// ParseCcelWithTdQuote verify the TD quote, parses the CCEL, and replays the
// events against the RTMR values from the TD quote..
// It returns the corresponding FirmwareLogState containing the events verified
// by particular RTMR indexes/digests.
// It returns an error on failing to replay the events against the RTMR bank or
// on failing to parse malformed events.
func ParseCcelWithTdQuote(ccelBytes []byte, tableBytes []byte, tdxAttestationQuote any, opts *ParseTdxCcelOpts) (*state.FirmwareLogState, error) {
// Check that the quote contains valid signature and certificates.
if err := verify.TdxQuote(tdxAttestationQuote, opts.Verification); err != nil {
return nil, err
}
// Check that the fields of the quote are acceptable.
if err := validate.TdxQuote(tdxAttestationQuote, opts.Validation); err != nil {
return nil, err
}
// Read the RTMRs from the quote.
rtmrBank, err := GetRtmrsFromTdQuote(tdxAttestationQuote)
if err != nil {
return nil, err
}
// Parse the event log and replay the event log with the RTMR values.
return ccel.ExtractFirmwareLogState(tableBytes, ccelBytes, *rtmrBank, *opts.ExtractOpt)
}
51 changes: 51 additions & 0 deletions rtmr/ccel_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.

package rtmr

import (
"os"
"testing"

"github.com/google/go-tdx-guest/abi"
)

func TestReplayCcelWithTdQuote(t *testing.T) {
ccelBytes, err := os.ReadFile("../testing/testdata/ccel/ccel_data.dat")
if err != nil {
t.Fatal(err)
}
tableBytes, err := os.ReadFile("../testing/testdata/ccel/ccel_table.dat")
if err != nil {
t.Fatal(err)
}
quoteBytes, err := os.ReadFile("../testing/testdata/ccel/cos-113-tdx-quote.dat")
if err != nil {
t.Fatal(err)
}
nonceBytes, err := os.ReadFile("../testing/testdata/ccel/nonce.dat")
if err != nil {
t.Fatal(err)
}
option := TdxDefaultOpts(nonceBytes)
quote, err := abi.QuoteToProto(quoteBytes)
if err != nil {
t.Fatal(err)
}
ccel, err := ParseCcelWithTdQuote(ccelBytes, tableBytes, quote, &option)
if err != nil {
t.Fatal(err)
}
t.Log(ccel)
}
5 changes: 3 additions & 2 deletions rtmr/extend.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

// Package rtmr provides the library functions to extend and read TDX rtmr
// registers and their tcg maps.
// Package rtmr provides the library functions:
// 1. extend and read TDX rtmr registers and their tcg maps.
// 2. replay the event log with the TDX quote.
package rtmr

import (
Expand Down
Binary file added testing/testdata/ccel/ccel_data.dat
Binary file not shown.
Binary file added testing/testdata/ccel/ccel_table.dat
Binary file not shown.
Binary file added testing/testdata/ccel/cos-113-tdx-quote.dat
Binary file not shown.
Binary file added testing/testdata/ccel/nonce.dat
Binary file not shown.
Loading