diff --git a/rune/libenclave/internal/runtime/core/core.go b/rune/libenclave/internal/runtime/core/core.go index 661adcdf6734c19f5f9da87aa908f54008fb796a..2fc2256503d1983c77efab0be717625b496c9e04 100644 --- a/rune/libenclave/internal/runtime/core/core.go +++ b/rune/libenclave/internal/runtime/core/core.go @@ -25,7 +25,7 @@ func (pal *enclaveRuntimeCore) Init(args string, logLevel string) (err error) { return fmt.Errorf("enclave runtime core Init() unimplemented") } -func (pal *enclaveRuntimeCore) Attest() (err error) { +func (pal *enclaveRuntimeCore) Attest(string, string, uint32, uint32) (err error) { return fmt.Errorf("enclave runtime core Attest() unimplemented") } diff --git a/rune/libenclave/internal/runtime/enclave_runtime.go b/rune/libenclave/internal/runtime/enclave_runtime.go index 0b23ad2d5f5f695e97e21e6808b91778383951cb..f1c757ba53db3def2c5e1bee50fa312d8325f76c 100644 --- a/rune/libenclave/internal/runtime/enclave_runtime.go +++ b/rune/libenclave/internal/runtime/enclave_runtime.go @@ -13,7 +13,7 @@ import ( type EnclaveRuntime interface { Load(path string) error Init(args string, logLevel string) error - Attest() error + Attest(string, string, uint32, uint32) error Exec(cmd []string, envp []string, stdio [3]*os.File) (int32, error) Kill(sig int, pid int) error Destroy() error @@ -56,10 +56,10 @@ func StartInitialization(config *configs.InitEnclaveConfig, logLevel string) (*E return rt, nil } -func (rt *EnclaveRuntimeWrapper) LaunchAttestation() error { +func (rt *EnclaveRuntimeWrapper) LaunchAttestation(spid string, subscriptionKey string, product uint32, quoteType uint32) error { logrus.Debugf("attesting enclave runtime") - return rt.runtime.Attest() + return rt.runtime.Attest(spid, subscriptionKey, product, quoteType) } func (rt *EnclaveRuntimeWrapper) ExecutePayload(cmd []string, envp []string, stdio [3]*os.File) (int32, error) { diff --git a/rune/libenclave/internal/runtime/pal/pal_linux.go b/rune/libenclave/internal/runtime/pal/pal_linux.go index f9403ef41cd01d8caa096b22c1a8c20ddc452dca..11a68893ed49570e6689d38663af549ad5324c25 100644 --- a/rune/libenclave/internal/runtime/pal/pal_linux.go +++ b/rune/libenclave/internal/runtime/pal/pal_linux.go @@ -1,7 +1,16 @@ package enclave_runtime_pal // import "github.com/opencontainers/runc/libenclave/internal/runtime/pal" +import "C" + import ( + "encoding/binary" "fmt" + "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" "os" ) @@ -31,10 +40,6 @@ func (pal *enclaveRuntimePal) Init(args string, logLevel string) error { return api.init(args, logLevel) } -func (pal *enclaveRuntimePal) Attest() (err error) { - return nil -} - func (pal *enclaveRuntimePal) Exec(cmd []string, envp []string, stdio [3]*os.File) (int32, error) { if pal.version == 1 { api := &enclaveRuntimePalApiV1{} @@ -67,3 +72,79 @@ func (pal *enclaveRuntimePal) GetLocalReport(targetInfo []byte) ([]byte, error) return nil, fmt.Errorf("unsupported pal api version %d", pal.version) } + +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 +} diff --git a/rune/libenclave/runelet.go b/rune/libenclave/runelet.go index e327b6b20b6972bf70d76db30bc5af3e4bf473e3..2287ec89d599bde0de90f5d03c02690c688caf5d 100644 --- a/rune/libenclave/runelet.go +++ b/rune/libenclave/runelet.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "github.com/opencontainers/runc/libcontainer/utils" + "github.com/opencontainers/runc/libenclave/attestation/sgx" "github.com/opencontainers/runc/libenclave/configs" "github.com/opencontainers/runc/libenclave/internal/runtime" pb "github.com/opencontainers/runc/libenclave/proto" @@ -68,8 +69,10 @@ func StartInitialization(cmd []string, cfg *RuneletConfig) (exitCode int32, err } // Launch a remote attestation to the enclave runtime. - if err = rt.LaunchAttestation(); err != nil { - return 1, err + if config.RaType == sgx.EPID { + if err = rt.LaunchAttestation(config.RaEpidSpid, config.RaEpidSubscriptionKey, config.IsProductEnclave, config.RaEpidIsLinkable); err != nil { + return 1, err + } } if err = readSync(initPipe, procEnclaveReady); err != nil { return 1, err