Skip to content

Commit

Permalink
Merge pull request cc-api#38 from Ruoyu-y/configtsm-go
Browse files Browse the repository at this point in the history
  • Loading branch information
wenhuizhang authored Apr 16, 2024
2 parents b788f28 + b55fb3a commit 366d479
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 9 deletions.
90 changes: 89 additions & 1 deletion src/golang/cctrusted_vm/cvm.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,107 @@
package vmsdk

import (
"crypto/sha512"
"errors"
"os"
"path/filepath"
"strconv"

"github.com/cc-api/cc-trusted-api/common/golang/cctrusted_base"
)

const (
TSM_PREFIX = "/sys/kernel/config/tsm/report"
)

type Device interface {
ProbeDevice() error
Report(nonce, userDate string) ([]byte, error)
Report(nonce, userData string, extraArgs map[string]any) (cctrusted_base.CcReport, error)
Name() string
CCType() cctrusted_base.CC_Type
Version() cctrusted_base.DeviceVersion
}

type GenericDevice struct {
Device
}

func (d *GenericDevice) Report(nonce, userData string, extraArgs map[string]any) (cctrusted_base.CcReport, error) {
var err error
if _, err = os.Stat(TSM_PREFIX); os.IsNotExist(err) {
return cctrusted_base.CcReport{}, errors.New("Configfs TSM is not supported in the current environment.")
}

hasher := sha512.New()
if nonce != "" {
hasher.Write([]byte(nonce))
}
if userData != "" {
hasher.Write([]byte(userData))
}
reportData := []byte(hasher.Sum(nil))

tempdir, err := os.MkdirTemp(TSM_PREFIX, "report_")
if err != nil {
return cctrusted_base.CcReport{}, errors.New("Failed to init entry in Configfs TSM.")
}
defer os.RemoveAll(tempdir)

if _, err = os.Stat(filepath.Join(tempdir, "inblob")); !os.IsNotExist(err) {
err = os.WriteFile(filepath.Join(tempdir, "inblob"), reportData, 0400)
if err != nil {
return cctrusted_base.CcReport{}, errors.New("Failed to push report data into inblob.")
}
}

if v, ok := extraArgs["privilege"]; ok {
if val, ok := v.(int); ok {
err = os.WriteFile(filepath.Join(tempdir, "privlevel"), []byte(strconv.Itoa(val)), 0400)
if err != nil {
return cctrusted_base.CcReport{}, errors.New("Failed to push privilege data to privlevel file.")
}
}
}

var outblob, provider, auxblob []byte
var generation int
if _, err = os.Stat(filepath.Join(tempdir, "outblob")); !os.IsNotExist(err) {
outblob, err = os.ReadFile(filepath.Join(tempdir, "outblob"))
if err != nil {
return cctrusted_base.CcReport{}, errors.New("Failed to get outblob.")
}
}

if _, err = os.Stat(filepath.Join(tempdir, "generation")); !os.IsNotExist(err) {
rawGeneration, err := os.ReadFile(filepath.Join(tempdir, "generation"))
if err != nil {
return cctrusted_base.CcReport{}, errors.New("Failed to get generation info.")
}
generation, _ = strconv.Atoi(string(rawGeneration))
}

if _, err = os.Stat(filepath.Join(tempdir, "provider")); !os.IsNotExist(err) {
provider, err = os.ReadFile(filepath.Join(tempdir, "provider"))
if err != nil {
return cctrusted_base.CcReport{}, errors.New("Failed to get provider info.")
}
}

if _, err = os.Stat(filepath.Join(tempdir, "auxblob")); !os.IsNotExist(err) {
auxblob, err = os.ReadFile(filepath.Join(tempdir, "auxblob"))
if err != nil {
return cctrusted_base.CcReport{}, errors.New("Failed to get auxblob info.")
}
}

return cctrusted_base.CcReport{
Outblob: outblob,
Provider: string(provider),
Generation: generation,
Auxblob: auxblob,
}, nil
}

type EventRecorder interface {
ProbeRecorder() error
FullEventLog() ([]byte, error)
Expand Down
6 changes: 3 additions & 3 deletions src/golang/cctrusted_vm/sdk/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,20 +121,20 @@ func (s *SDK) internelEventlog() (*cctrusted_base.EventLogger, error) {
}

// Report implements CCTrustedAPI.
func (s *SDK) GetCCReport(nonce, userData string, _ any) (cctrusted_base.Report, error) {
func (s *SDK) GetCCReport(nonce, userData string, extraArgs map[string]any) (cctrusted_base.Report, error) {
if s.cvm == nil {
return nil, errors.New("no available cvm in sdk")
}

reportBytes, err := s.cvm.Report(nonce, userData)
reportStruct, err := s.cvm.Report(nonce, userData, extraArgs)
if err != nil {
return nil, err
}

vmCtx := s.cvm.CVMContext()
switch vmCtx.VMType {
case cctrusted_base.TYPE_CC_TDX:
report, err := tdx.NewTdxReportFromBytes(reportBytes)
report, err := tdx.NewTdxReportFromBytes(reportStruct.Outblob)
if err != nil {
return nil, err
}
Expand Down
24 changes: 19 additions & 5 deletions src/golang/cctrusted_vm/tdx/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var _ cctrusted_vm.Device = (*TDXDevice)(nil)

type TDXDevice struct {
spec tdx.TDXDeviceSpec
cctrusted_vm.GenericDevice
QuoteHandler
}

Expand Down Expand Up @@ -61,17 +62,30 @@ func (t *TDXDevice) initDevice() error {
}

// Report implements cctrusted_vm.Device, get CC report
func (t *TDXDevice) Report(nonce, userDate string) ([]byte, error) {
func (t *TDXDevice) Report(nonce, userData string, extraArgs map[string]any) (cctrusted_base.CcReport, error) {
var resp cctrusted_base.CcReport
var err error

// call parent Report() func to retrieve cc report using Configfs-tsm
resp, err = t.GenericDevice.Report(nonce, userData, extraArgs)
if err == nil {
return resp, nil
}

// get tdx report
tdreport, err := t.TdReport(nonce, userDate)
tdreport, err := t.TdReport(nonce, userData)
if err != nil {
return nil, err
return cctrusted_base.CcReport{}, err
}
// get tdx quote, aka. CC report
quote, err := t.Quote(tdreport)
if err != nil {
return nil, err
return cctrusted_base.CcReport{}, err
}

resp = cctrusted_base.CcReport{
Outblob: quote,
}

return quote, nil
return resp, nil
}

0 comments on commit 366d479

Please sign in to comment.