pal_linux.go 3.5 KB
Newer Older
1 2
package enclave_runtime_pal // import "github.com/opencontainers/runc/libenclave/internal/runtime/pal"

3 4
import "C"

5
import (
6
	"encoding/binary"
7
	"fmt"
8 9 10 11 12 13
	"github.com/go-restruct/restruct"
	"github.com/opencontainers/runc/libenclave/attestation"
	"github.com/opencontainers/runc/libenclave/attestation/sgx"
	_ "github.com/opencontainers/runc/libenclave/attestation/sgx/ias"
	"github.com/opencontainers/runc/libenclave/intelsgx"
	"log"
14 15 16
	"os"
)

17 18 19 20
const (
	palApiVersion = 2
)

21 22 23 24
func (pal *enclaveRuntimePal) Load(palPath string) (err error) {
	if err = pal.getPalApiVersion(); err != nil {
		return err
	}
25
	return nil
26 27 28
}

func (pal *enclaveRuntimePal) getPalApiVersion() error {
29 30 31 32
	api := &enclaveRuntimePalApiV1{}
	ver := api.get_version()
	if ver > palApiVersion {
		return fmt.Errorf("unsupported pal api version %d", ver)
33
	}
34 35
	pal.version = ver
	return nil
36 37 38 39
}

func (pal *enclaveRuntimePal) Init(args string, logLevel string) error {
	api := &enclaveRuntimePalApiV1{}
40
	return api.init(args, logLevel)
41 42 43
}

func (pal *enclaveRuntimePal) Exec(cmd []string, envp []string, stdio [3]*os.File) (int32, error) {
44 45 46 47 48 49
	if pal.version == 1 {
		api := &enclaveRuntimePalApiV1{}
		return api.exec(cmd, envp, stdio)
	}

	api := &enclaveRuntimePalApiV2{}
50
	return api.exec(cmd, envp, stdio)
51 52
}

53 54 55
func (pal *enclaveRuntimePal) Kill(pid int, sig int) error {
	if pal.version == 1 {
		return nil
56
	}
57 58 59

	api := &enclaveRuntimePalApiV2{}
	return api.kill(pid, sig)
60 61 62 63
}

func (pal *enclaveRuntimePal) Destroy() error {
	api := &enclaveRuntimePalApiV1{}
64
	return api.destroy()
65
}
Y
YiLin.Li 已提交
66 67 68 69 70 71 72 73 74

func (pal *enclaveRuntimePal) GetLocalReport(targetInfo []byte) ([]byte, error) {
	if pal.version >= 3 {
		api := &enclaveRuntimePalApiV3{}
		return api.getLocalReport(targetInfo)
	}

	return nil, fmt.Errorf("unsupported pal api version %d", pal.version)
}
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150

func parseAttestParameters(spid string, subscriptionKey string, product uint32) map[string]string {
	p := make(map[string]string)

	p["spid"] = spid
	p["subscription-key"] = subscriptionKey
	if product == sgx.ProductEnclave {
		p["service-class"] = "product"
	} else if product == sgx.DebugEnclave {
		p["service-class"] = "dev"
	}

	return p
}

func (pal *enclaveRuntimePal) Attest(spid string, subscriptionKey string, product uint32, quoteType uint32) (err error) {
	if pal.GetLocalReport == nil {
		return nil
	}

	targetInfo, err := intelsgx.GetQeTargetInfo()
	if err != nil {
		return err
	}

	if len(targetInfo) != intelsgx.TargetinfoLength {
		return fmt.Errorf("len(targetInfo) is not %d, but %d", intelsgx.TargetinfoLength, len(targetInfo))
	}

	// get local report of SGX
	report, err := pal.GetLocalReport(targetInfo)
	if err != nil {
		return err
	}
	if len(report) != intelsgx.ReportLength {
		return fmt.Errorf("len(report) is not %d, but %d", intelsgx.ReportLength, len(report))
	}

	// get quote from QE(aesmd)
	linkable := false
	if quoteType == intelsgx.QuoteSignatureTypeLinkable {
		linkable = true
	}
	quote, err := intelsgx.GetQuote(report, spid, linkable)
	if err != nil {
		return err
	}

	q := &intelsgx.Quote{}
	if err := restruct.Unpack(quote, binary.LittleEndian, &q); err != nil {
		return err
	}

	// get IAS remote attestation report
	var verbose bool = true
	p := parseAttestParameters(spid, subscriptionKey, product)
	svc, err := attestation.NewService(p, verbose)
	if err != nil {
		log.Fatal(err)
		return err
	}

	if err = svc.Check(quote); err != nil {
		log.Fatal(err)
		return err
	}

	status := svc.Verify(quote)
	if status.ErrorMessage != "" {
		return fmt.Errorf("%s", status.ErrorMessage)
	}

	svc.ShowStatus(status)

	return nil
}