diff --git a/internal/guest/runtime/hcsv2/hostdata.go b/internal/guest/runtime/hcsv2/hostdata.go index 7b18704968..c4a30b9bba 100644 --- a/internal/guest/runtime/hcsv2/hostdata.go +++ b/internal/guest/runtime/hcsv2/hostdata.go @@ -8,13 +8,13 @@ import ( "fmt" "os" - "github.com/Microsoft/hcsshim/internal/guest/amdsev" + "github.com/Microsoft/hcsshim/pkg/amdsev" ) // validateHostData fetches SNP report (if applicable) and validates `hostData` against // HostData set at UVM launch. func validateHostData(hostData []byte) error { - report, err := amdsev.FetchParsedSNPReport("") + report, err := amdsev.FetchParsedSNPReport(nil) if err != nil { // For non-SNP hardware /dev/sev will not exist if os.IsNotExist(err) { diff --git a/internal/tools/snp-report/fake/report.go b/internal/tools/snp-report/fake/report.go index 709db23d85..50c5dd6df7 100644 --- a/internal/tools/snp-report/fake/report.go +++ b/internal/tools/snp-report/fake/report.go @@ -7,7 +7,7 @@ import ( "encoding/hex" "fmt" - "github.com/Microsoft/hcsshim/internal/guest/amdsev" + "github.com/Microsoft/hcsshim/pkg/amdsev" ) const fakeSNPReport = "01000000010000001f00030000000000010000000000000000000000000000000200000000000000000000000000000000000000010000000000000000000028010000000000000000000000000000007ab000a323b3c873f5b81bbe584e7c1a26bcf40dc27e00f8e0d144b1ed2d14f10000000000000000000000000000000000000000000000000000000000000000e29af700e85b39996fa38226d2804b78cad746ffef4477360a61b47874bdecd640f9d32f5ff64a55baad3c545484d9ed28603a3ea835a83bd688b0ec1dcb36b6b8c22412e5b63115b75db8628b989bc598c475ca5f7683e8d351e7e789a1baff19041750567161ad52bf0d152bd76d7c6f313d0a0fd72d0089692c18f521155800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040aea62690b08eb6d680392c9a9b3db56a9b3cc44083b9da31fb88bcfc493407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000000028000000000000000000000000000000000000000000000000e6c86796cd44b0bc6b7c0d4fdab33e2807e14b5fc4538b3750921169d97bcf4447c7d3ab2a7c25f74c1641e2885c1011d025cc536f5c9a2504713136c7877f480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003131c0f3e7be5c6e400f22404596e1874381e99d03de45ef8b97eee0a0fa93a4911550330343f14dddbbd6c0db83744f000000000000000000000000000000000000000000000000db07c83c5e6162c2387f3b76cd547672657f6a5df99df98efee7c15349320d83e086c5003ec43050a9b18d1c39dedc340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" diff --git a/internal/tools/snp-report/main.go b/internal/tools/snp-report/main.go index 90c9795b79..394eae0050 100644 --- a/internal/tools/snp-report/main.go +++ b/internal/tools/snp-report/main.go @@ -4,14 +4,45 @@ package main import ( + "encoding/hex" "flag" "fmt" "os" - "github.com/Microsoft/hcsshim/internal/guest/amdsev" "github.com/Microsoft/hcsshim/internal/tools/snp-report/fake" + "github.com/Microsoft/hcsshim/pkg/amdsev" ) +// verboseReport returns formatted attestation report. +func verboseReport(r amdsev.Report) string { + fieldNameFmt := "%-20s" + pretty := "" + pretty += fmt.Sprintf(fieldNameFmt+"%08x\n", "Version", r.Version) + pretty += fmt.Sprintf(fieldNameFmt+"%08x\n", "GuestSVN", r.GuestSVN) + pretty += fmt.Sprintf(fieldNameFmt+"%016x\n", "Policy", r.Policy) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "FamilyID", r.FamilyID) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "ImageID", r.ImageID) + pretty += fmt.Sprintf(fieldNameFmt+"%08x\n", "VMPL", r.VMPL) + pretty += fmt.Sprintf(fieldNameFmt+"%08x\n", "SignatureAlgo", r.SignatureAlgo) + pretty += fmt.Sprintf(fieldNameFmt+"%016x\n", "PlatformVersion", r.PlatformVersion) + pretty += fmt.Sprintf(fieldNameFmt+"%016x\n", "PlatformInfo", r.PlatformInfo) + pretty += fmt.Sprintf(fieldNameFmt+"%08x\n", "AuthorKeyEn", r.AuthorKeyEn) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "ReportData", r.ReportData) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "Measurement", r.Measurement) + pretty += fmt.Sprintf(fieldNameFmt+"%x\n", "HostData", r.HostData) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "IDKeyDigest", r.IDKeyDigest) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "AuthorKeyDigest", r.AuthorKeyDigest) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "ReportID", r.ReportID) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "ReportIDMA", r.ReportIDMA) + pretty += fmt.Sprintf(fieldNameFmt+"%016x\n", "ReportTCB", r.ReportTCB) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "ChipID", r.ChipID) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "CommittedSVN", r.CommittedSVN) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "CommittedVersion", r.CommittedVersion) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "LaunchSVN", r.LaunchSVN) + pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "Signature", r.Signature) + return pretty +} + func main() { fakeReportFlag := flag.Bool( "fake-report", @@ -41,13 +72,22 @@ func main() { flag.Parse() + var reportBytes []byte + if *reportDataFlag != "" { + var err error + reportBytes, err = hex.DecodeString(*reportDataFlag) + if err != nil { + fmt.Printf("failed to decode report data:%s\n", err) + os.Exit(1) + } + } if *binaryFmtFlag { var binaryReport []byte var err error if !*fakeReportFlag { binaryReport, err = fake.FetchRawSNPReport() } else { - binaryReport, err = amdsev.FetchRawSNPReport(*reportDataFlag) + binaryReport, err = amdsev.FetchRawSNPReport(reportBytes) } if err != nil { fmt.Println(err) @@ -62,7 +102,7 @@ func main() { if *fakeReportFlag { report, err = fake.FetchSNPReport(*hostDataFlag) } else { - report, err = amdsev.FetchParsedSNPReport(*reportDataFlag) + report, err = amdsev.FetchParsedSNPReport(reportBytes) } if err != nil { fmt.Printf("failed to fetch SNP report: %s", err) @@ -72,6 +112,6 @@ func main() { if !*verbosePrintFlag { fmt.Printf("%+v\n", report) } else { - fmt.Println(report.PrettyString()) + fmt.Println(verboseReport(report)) } } diff --git a/internal/guest/amdsev/report.go b/pkg/amdsev/report.go similarity index 74% rename from internal/guest/amdsev/report.go rename to pkg/amdsev/report.go index 18b9a87864..937adcf052 100644 --- a/internal/guest/amdsev/report.go +++ b/pkg/amdsev/report.go @@ -143,7 +143,7 @@ type reportResponse struct { } // FetchRawSNPReport returns attestation report bytes. -func FetchRawSNPReport(reportData string) ([]byte, error) { +func FetchRawSNPReport(reportData []byte) ([]byte, error) { f, err := os.OpenFile("/dev/sev", os.O_RDWR, 0) if err != nil { return nil, err @@ -157,15 +157,11 @@ func FetchRawSNPReport(reportData string) ([]byte, error) { msgReportOut reportResponse ) - if reportData != "" { + if reportData != nil { if len(reportData) > len(msgReportIn.ReportData) { return nil, fmt.Errorf("reportData too large: %s", reportData) } - rd, err := hex.DecodeString(reportData) - if err != nil { - return nil, err - } - copy(msgReportIn.ReportData[:], rd[:]) + copy(msgReportIn.ReportData[:], reportData) } payload := &guestRequest{ @@ -212,36 +208,6 @@ type Report struct { Signature string } -// PrettyString returns formatted attestation report. -func (r Report) PrettyString() string { - fieldNameFmt := "%-20s" - pretty := "" - pretty += fmt.Sprintf(fieldNameFmt+"%08x\n", "Version", r.Version) - pretty += fmt.Sprintf(fieldNameFmt+"%08x\n", "GuestSVN", r.GuestSVN) - pretty += fmt.Sprintf(fieldNameFmt+"%016x\n", "Policy", r.Policy) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "FamilyID", r.FamilyID) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "ImageID", r.ImageID) - pretty += fmt.Sprintf(fieldNameFmt+"%08x\n", "VMPL", r.VMPL) - pretty += fmt.Sprintf(fieldNameFmt+"%08x\n", "SignatureAlgo", r.SignatureAlgo) - pretty += fmt.Sprintf(fieldNameFmt+"%016x\n", "PlatformVersion", r.PlatformVersion) - pretty += fmt.Sprintf(fieldNameFmt+"%016x\n", "PlatformInfo", r.PlatformInfo) - pretty += fmt.Sprintf(fieldNameFmt+"%08x\n", "AuthorKeyEn", r.AuthorKeyEn) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "ReportData", r.ReportData) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "Measurement", r.Measurement) - pretty += fmt.Sprintf(fieldNameFmt+"%x\n", "HostData", r.HostData) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "IDKeyDigest", r.IDKeyDigest) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "AuthorKeyDigest", r.AuthorKeyDigest) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "ReportID", r.ReportID) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "ReportIDMA", r.ReportIDMA) - pretty += fmt.Sprintf(fieldNameFmt+"%016x\n", "ReportTCB", r.ReportTCB) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "ChipID", r.ChipID) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "CommittedSVN", r.CommittedSVN) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "CommittedVersion", r.CommittedVersion) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "LaunchSVN", r.LaunchSVN) - pretty += fmt.Sprintf(fieldNameFmt+"%s\n", "Signature", r.Signature) - return pretty -} - // mirrorBytes mirrors the byte ordering so that hex-encoding little endian // ordered bytes come out in the readable order. func mirrorBytes(b []byte) []byte { @@ -253,7 +219,7 @@ func mirrorBytes(b []byte) []byte { } // FetchParsedSNPReport parses raw attestation response into proper structs. -func FetchParsedSNPReport(reportData string) (Report, error) { +func FetchParsedSNPReport(reportData []byte) (Report, error) { rawBytes, err := FetchRawSNPReport(reportData) if err != nil { return Report{}, err diff --git a/internal/guest/amdsev/report_test.go b/pkg/amdsev/report_test.go similarity index 100% rename from internal/guest/amdsev/report_test.go rename to pkg/amdsev/report_test.go