Skip to content

Commit

Permalink
pr feedback: Ioctl function, host data compare bytes, comments
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim An <maksiman@microsoft.com>
  • Loading branch information
anmaxvl committed Apr 8, 2022
1 parent 1688e24 commit 57be3c5
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 31 deletions.
15 changes: 4 additions & 11 deletions internal/guest/amdsev/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import (
"os"
"unsafe"

"golang.org/x/sys/unix"

"github.com/Microsoft/hcsshim/internal/guest/linux"
)

Expand Down Expand Up @@ -115,7 +113,7 @@ func (sr *report) report() Report {
AuthorKeyEn: sr.AuthorKeyEn,
ReportData: hex.EncodeToString(sr.ReportData[:]),
Measurement: hex.EncodeToString(sr.Measurement[:]),
HostData: hex.EncodeToString(sr.HostData[:]),
HostData: sr.HostData[:],
IDKeyDigest: hex.EncodeToString(sr.IDKeyDigest[:]),
AuthorKeyDigest: hex.EncodeToString(sr.AuthorKeyDigest[:]),
ReportID: hex.EncodeToString(sr.ReportID[:]),
Expand Down Expand Up @@ -181,12 +179,7 @@ func FetchRawSNPReport(reportData string) ([]byte, error) {
Error: 0,
}

if _, _, err := unix.Syscall(
unix.SYS_IOCTL,
f.Fd(),
uintptr(reportCode|ioctlBase),
uintptr(unsafe.Pointer(payload)),
); err != 0 {
if err := linux.Ioctl(f, reportCode|ioctlBase, unsafe.Pointer(payload)); err != nil {
return nil, err
}
return msgReportOut.Report[:], nil
Expand All @@ -206,7 +199,7 @@ type Report struct {
AuthorKeyEn uint32
ReportData string
Measurement string
HostData string
HostData []byte
IDKeyDigest string
AuthorKeyDigest string
ReportID string
Expand Down Expand Up @@ -235,7 +228,7 @@ func (r Report) PrettyString() string {
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+"%s\n", "HostData", r.HostData)
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)
Expand Down
21 changes: 21 additions & 0 deletions internal/guest/linux/ioctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
// Package linux contains definitions required for making a linux ioctl.
package linux

import (
"os"
"unsafe"

"golang.org/x/sys/unix"
)

// 32 bits to describe an ioctl:
// 0-7: NR (command for a given ioctl type)
// 8-15: TYPE (ioctl type)
Expand All @@ -26,3 +33,17 @@ const (
IocDirShift = IocSizeShift + IocSizeBits
IocWRBase = (IocRead | IocWrite) << IocDirShift
)

// Ioctl makes a syscall described by `command` with data `dataPtr` to device
// driver file `f`.
func Ioctl(f *os.File, command int, dataPtr unsafe.Pointer) error {
if _, _, err := unix.Syscall(
unix.SYS_IOCTL,
f.Fd(),
uintptr(command),
uintptr(dataPtr),
); err != 0 {
return err
}
return nil
}
5 changes: 3 additions & 2 deletions internal/guest/runtime/hcsv2/hostdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package hcsv2

import (
"bytes"
"fmt"
"os"

Expand All @@ -12,7 +13,7 @@ import (

// validateHostData fetches SNP report (if applicable) and validates `hostData` against
// HostData set at UVM launch.
func validateHostData(hostData string) error {
func validateHostData(hostData []byte) error {
report, err := amdsev.FetchParsedSNPReport("")
if err != nil {
// For non-SNP hardware /dev/sev will not exist
Expand All @@ -22,7 +23,7 @@ func validateHostData(hostData string) error {
return err
}

if report.HostData != hostData {
if bytes.Compare(hostData, report.HostData) != 0 {
return fmt.Errorf(
"security policy digest %q doesn't match HostData provided at launch %q",
hostData,
Expand Down
2 changes: 1 addition & 1 deletion internal/guest/runtime/hcsv2/uvm.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ func (h *Host) SetSecurityPolicy(base64Policy string) error {
return err
}

if err := validateHostData(fmt.Sprintf("%x", hostData[:])); err != nil {
if err := validateHostData(hostData[:]); err != nil {
return err
}

Expand Down
19 changes: 9 additions & 10 deletions internal/guest/storage/devicemapper/devicemapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,10 @@ func (err *dmError) Error() string {
return "device-mapper " + op + ": " + err.Err.Error()
}

// ioctl issues the specified device-mapper ioctl
func ioctl(f *os.File, code int, data *dmIoctl) error {
_, _, errno := unix.Syscall(unix.SYS_IOCTL, f.Fd(), uintptr(code|_DM_IOCTL_BASE), uintptr(unsafe.Pointer(data)))
if errno != 0 {
return &dmError{Op: code, Err: errno}
// devMapperIoctl issues the specified device-mapper ioctl
func devMapperIoctl(f *os.File, code int, data *dmIoctl) error {
if err := linux.Ioctl(f, code|_DM_IOCTL_BASE, unsafe.Pointer(data)); err != nil {
return &dmError{Op: code, Err: err}
}
return nil
}
Expand All @@ -142,7 +141,7 @@ func openMapper() (f *os.File, err error) {
}()
var d dmIoctl
initIoctl(&d, int(unsafe.Sizeof(d)), "")
err = ioctl(f, _DM_VERSION, &d)
err = devMapperIoctl(f, _DM_VERSION, &d)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -227,7 +226,7 @@ func CreateDevice(name string, flags CreateFlags, targets []Target) (_ string, e
var d dmIoctl
size := int(unsafe.Sizeof(d))
initIoctl(&d, size, name)
err = ioctl(f, _DM_DEV_CREATE, &d)
err = devMapperIoctl(f, _DM_DEV_CREATE, &d)
if err != nil {
return "", err
}
Expand All @@ -243,12 +242,12 @@ func CreateDevice(name string, flags CreateFlags, targets []Target) (_ string, e
if flags&CreateReadOnly != 0 {
di.Flags |= _DM_READONLY_FLAG
}
err = ioctl(f, _DM_TABLE_LOAD, di)
err = devMapperIoctl(f, _DM_TABLE_LOAD, di)
if err != nil {
return "", err
}
initIoctl(&d, size, name)
err = ioctl(f, _DM_DEV_SUSPEND, &d)
err = devMapperIoctl(f, _DM_DEV_SUSPEND, &d)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -293,7 +292,7 @@ func RemoveDevice(name string) (err error) {
func removeDevice(f *os.File, name string) error {
var d dmIoctl
initIoctl(&d, int(unsafe.Sizeof(d)), name)
err := ioctl(f, _DM_DEV_REMOVE, &d)
err := devMapperIoctl(f, _DM_DEV_REMOVE, &d)
if err != nil {
return err
}
Expand Down
15 changes: 8 additions & 7 deletions internal/tools/snp-report/fake/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ func FetchRawSNPReport() ([]byte, error) {
// version of fakeSNPReport. Overrides the resulting report's HostData field
// with provided `hostData`.
func FetchSNPReport(hostData string) (amdsev.Report, error) {
if hostData == "" {
hostData = "28603a3ea835a83bd688b0ec1dcb36b6b8c22412e5b63115b75db8628b989bc5"
}
hdBytes, err := hex.DecodeString(hostData)
if err != nil {
return amdsev.Report{}, fmt.Errorf("failed to decode host data: %w", err)
}
r := amdsev.Report{
Version: 1,
GuestSVN: 1,
Expand All @@ -34,7 +41,7 @@ func FetchSNPReport(hostData string) (amdsev.Report, error) {
AuthorKeyEn: 0,
ReportData: "7ab000a323b3c873f5b81bbe584e7c1a26bcf40dc27e00f8e0d144b1ed2d14f10000000000000000000000000000000000000000000000000000000000000000",
Measurement: "e29af700e85b39996fa38226d2804b78cad746ffef4477360a61b47874bdecd640f9d32f5ff64a55baad3c545484d9ed",
HostData: "28603a3ea835a83bd688b0ec1dcb36b6b8c22412e5b63115b75db8628b989bc5",
HostData: hdBytes[:],
IDKeyDigest: "98c475ca5f7683e8d351e7e789a1baff19041750567161ad52bf0d152bd76d7c6f313d0a0fd72d0089692c18f5211558",
AuthorKeyDigest: "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
ReportID: "40aea62690b08eb6d680392c9a9b3db56a9b3cc44083b9da31fb88bcfc493407",
Expand All @@ -46,11 +53,5 @@ func FetchSNPReport(hostData string) (amdsev.Report, error) {
LaunchSVN: "0000000000000000",
Signature: "3131c0f3e7be5c6e400f22404596e1874381e99d03de45ef8b97eee0a0fa93a4911550330343f14dddbbd6c0db83744f000000000000000000000000000000000000000000000000db07c83c5e6162c2387f3b76cd547672657f6a5df99df98efee7c15349320d83e086c5003ec43050a9b18d1c39dedc340000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
}

if hostData != "" {
dataBytes := make([]byte, len(r.HostData))
copy(dataBytes[:], hostData)
r.HostData = fmt.Sprintf("%x", dataBytes[:])
}
return r, nil
}
3 changes: 3 additions & 0 deletions internal/uvm/create_lcow.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,9 @@ func makeLCOWSecurityDoc(ctx context.Context, opts *OptionsLCOW, uvm *UtilityVM)
if err != nil {
return nil, err
}
// HCS API expect a base64 encoded string as LaunchData. Internally it
// decodes it to bytes. SEV later returns the decoded byte blob as HostData
// field of the report.
hostData := base64.StdEncoding.EncodeToString(policyDigest)

// Put the measurement into the LaunchData field of the HCS creation command.
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 57be3c5

Please sign in to comment.