Skip to content

Commit b670bb1

Browse files
committed
C-WCOW: Hardware checks and reports to separate pkg
Signed-off-by: Mahati Chamarthy <mahati.chamarthy@gmail.com>
1 parent 1bf838e commit b670bb1

File tree

9 files changed

+261
-360
lines changed

9 files changed

+261
-360
lines changed

cmd/gcs-sidecar/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"github.com/Microsoft/hcsshim/internal/gcs/prot"
1616
shimlog "github.com/Microsoft/hcsshim/internal/log"
1717
"github.com/Microsoft/hcsshim/internal/oc"
18+
"github.com/Microsoft/hcsshim/pkg/amdsevsnp"
1819
"github.com/Microsoft/hcsshim/pkg/securitypolicy"
1920
"github.com/sirupsen/logrus"
2021
"go.opencensus.io/trace"
@@ -216,7 +217,7 @@ func main() {
216217
return
217218
}
218219

219-
if err := securitypolicy.StartPSPDriver(ctx); err != nil {
220+
if err := amdsevsnp.StartPSPDriver(ctx); err != nil {
220221
// When error happens, pspdriver.GetPspDriverError() returns true.
221222
// In that case, gcs-sidecar should keep the initial "deny" policy
222223
// and reject all requests from the host.

pkg/amdsevsnp/report.go

Lines changed: 0 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -1,76 +1,11 @@
1-
//go:build linux
2-
// +build linux
3-
41
package amdsevsnp
52

63
import (
74
"bytes"
85
"encoding/binary"
96
"encoding/hex"
10-
"errors"
11-
"fmt"
12-
"os"
13-
"unsafe"
14-
15-
"github.com/Microsoft/hcsshim/internal/guest/linux"
16-
)
17-
18-
const (
19-
msgTypeInvalid = iota
20-
msgCPUIDRequest
21-
msgCPUIDResponse
22-
msgKeyRequest
23-
msgKeyResponse
24-
msgReportRequest
25-
msgReportResponse
26-
msgExportRequest
27-
msgExportResponse
28-
msgImportRequest
29-
msgImportResponse
30-
msgAbsorbRequest
31-
msgAbsorbResponse
32-
msgVMRKRequest
33-
msgVMRKResponse
34-
msgTypeMax
35-
)
36-
37-
type guestRequest5 struct {
38-
RequestMsgType byte
39-
ResponseMsgType byte
40-
MsgVersion byte
41-
RequestLength uint16
42-
RequestUAddr unsafe.Pointer
43-
ResponseLength uint16
44-
ResponseUAddr unsafe.Pointer
45-
Error uint32
46-
}
47-
48-
type guestRequest6 struct {
49-
MsgVersion byte
50-
RequestData unsafe.Pointer
51-
ResponseData unsafe.Pointer
52-
Error uint64
53-
}
54-
55-
// AMD SEV ioctl definitions for kernel 5.x.
56-
const (
57-
snpGetReportIoctlCode5 = 3223868161
587
)
598

60-
// AMD SEV ioctl definitions for kernel 6.x.
61-
const (
62-
snpGetReportIoctlCode6 = 3223343872
63-
)
64-
65-
// reportRequest used to issue SEV-SNP request
66-
// https://www.amd.com/system/files/TechDocs/56860.pdf
67-
// MSG_REPORT_REQ Table 20.
68-
type reportRequest struct {
69-
ReportData [64]byte
70-
VMPL uint32
71-
_ [28]byte
72-
}
73-
749
// report is an internal representation of SEV-SNP report
7510
// https://www.amd.com/system/files/TechDocs/56860.pdf
7611
// ATTESTATION_REPORT Table 21.
@@ -131,133 +66,6 @@ func (sr *report) report() Report {
13166
}
13267
}
13368

134-
// reportResponse is the attestation response struct
135-
// https://www.amd.com/system/files/TechDocs/56860.pdf
136-
// MSG_REPORT_RSP Table 23.
137-
// NOTE: reportResponse.Report is a byte slice, to have the original
138-
// response in bytes. The conversion to internal struct happens inside
139-
// convertRawReport.
140-
//
141-
// NOTE: the additional 64 bytes are reserved, without them, the ioctl fails.
142-
type reportResponse struct {
143-
Status uint32
144-
ReportSize uint32
145-
reserved1 [24]byte
146-
Report [1184]byte
147-
reserved2 [64]byte // padding to the size of SEV_SNP_REPORT_RSP_BUF_SZ (i.e., 1280 bytes)
148-
}
149-
150-
// Size of `snp_report_resp` in include/uapi/linux/sev-guest.h.
151-
// It's used only for Linux 6.x.
152-
// It will have the conteints of reportResponse in the first unsafe.Sizeof(reportResponse{}) bytes.
153-
const reportResponseContainerLength6 = 4000
154-
155-
const snpDevicePath5 = "/dev/sev"
156-
const snpDevicePath6 = "/dev/sev-guest"
157-
158-
func IsSNP() bool {
159-
return isSNPVM5() || isSNPVM6()
160-
}
161-
162-
// Check if the code is being run in SNP VM for Linux kernel version 5.x.
163-
func isSNPVM5() bool {
164-
_, err := os.Stat(snpDevicePath5)
165-
return !errors.Is(err, os.ErrNotExist)
166-
}
167-
168-
// Check if the code is being run in SNP VM for Linux kernel version 6.x.
169-
func isSNPVM6() bool {
170-
_, err := os.Stat(snpDevicePath6)
171-
return !errors.Is(err, os.ErrNotExist)
172-
}
173-
174-
// FetchRawSNPReport returns attestation report bytes.
175-
func FetchRawSNPReport(reportData []byte) ([]byte, error) {
176-
if isSNPVM5() {
177-
return fetchRawSNPReport5(reportData)
178-
} else if isSNPVM6() {
179-
return fetchRawSNPReport6(reportData)
180-
} else {
181-
return nil, fmt.Errorf("SEV device is not found")
182-
}
183-
}
184-
185-
func fetchRawSNPReport5(reportData []byte) ([]byte, error) {
186-
f, err := os.OpenFile(snpDevicePath5, os.O_RDWR, 0)
187-
if err != nil {
188-
return nil, err
189-
}
190-
defer func() {
191-
_ = f.Close()
192-
}()
193-
194-
var (
195-
msgReportIn reportRequest
196-
msgReportOut reportResponse
197-
)
198-
199-
if reportData != nil {
200-
if len(reportData) > len(msgReportIn.ReportData) {
201-
return nil, fmt.Errorf("reportData too large: %s", reportData)
202-
}
203-
copy(msgReportIn.ReportData[:], reportData)
204-
}
205-
206-
payload := &guestRequest5{
207-
RequestMsgType: msgReportRequest,
208-
ResponseMsgType: msgReportResponse,
209-
MsgVersion: 1,
210-
RequestLength: uint16(unsafe.Sizeof(msgReportIn)),
211-
RequestUAddr: unsafe.Pointer(&msgReportIn),
212-
ResponseLength: uint16(unsafe.Sizeof(msgReportOut)),
213-
ResponseUAddr: unsafe.Pointer(&msgReportOut),
214-
Error: 0,
215-
}
216-
217-
if err := linux.Ioctl(f, snpGetReportIoctlCode5, unsafe.Pointer(payload)); err != nil {
218-
return nil, err
219-
}
220-
return msgReportOut.Report[:], nil
221-
}
222-
223-
func fetchRawSNPReport6(reportData []byte) ([]byte, error) {
224-
f, err := os.OpenFile(snpDevicePath6, os.O_RDWR, 0)
225-
if err != nil {
226-
return nil, err
227-
}
228-
defer func() {
229-
_ = f.Close()
230-
}()
231-
232-
var (
233-
msgReportIn reportRequest
234-
msgReportOut reportResponse
235-
)
236-
reportOutContainer := [reportResponseContainerLength6]byte{}
237-
238-
if reportData != nil {
239-
if len(reportData) > len(msgReportIn.ReportData) {
240-
return nil, fmt.Errorf("reportData too large: %s", reportData)
241-
}
242-
copy(msgReportIn.ReportData[:], reportData)
243-
}
244-
245-
payload := &guestRequest6{
246-
MsgVersion: 1,
247-
RequestData: unsafe.Pointer(&msgReportIn),
248-
ResponseData: unsafe.Pointer(&reportOutContainer),
249-
Error: 0,
250-
}
251-
252-
if err := linux.Ioctl(f, snpGetReportIoctlCode6, unsafe.Pointer(payload)); err != nil {
253-
return nil, err
254-
}
255-
256-
msgReportOut = *(*reportResponse)(unsafe.Pointer(&reportOutContainer[0]))
257-
258-
return msgReportOut.Report[:], nil
259-
}
260-
26169
// Report represents parsed attestation report.
26270
type Report struct {
26371
Version uint32

0 commit comments

Comments
 (0)