Skip to content

Commit

Permalink
Merge pull request #5578 from oasisprotocol/kostko/feature/pcs-update…
Browse files Browse the repository at this point in the history
…-early

sgx: Support early updates for ECDSA TCB infos
  • Loading branch information
kostko authored Feb 28, 2024
2 parents 8a75487 + ea412e2 commit 0a0529d
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 11 deletions.
1 change: 1 addition & 0 deletions .changelog/5578.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sgx: Support early updates for ECDSA TCB infos
8 changes: 5 additions & 3 deletions go/common/sgx/pcs/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,14 @@ func (hc *httpClient) getUrl(p string) *url.URL { // nolint: revive
return &u
}

func (hc *httpClient) GetTCBBundle(ctx context.Context, fmspc []byte) (*TCBBundle, error) {
// TODO: Cache based on FMSPC, with TTL that is less than expiration time.

func (hc *httpClient) GetTCBBundle(ctx context.Context, fmspc []byte, update UpdateType) (*TCBBundle, error) {
var tcbBundle TCBBundle

// First fetch TCB info.
u := hc.getUrl(pcsAPIGetTCBInfoPath)
q := u.Query()
q.Set("fmspc", hex.EncodeToString(fmspc))
q.Set("update", string(update))
u.RawQuery = q.Encode()
rsp, err := hc.doPCSRequest(ctx, u, http.MethodGet, "", nil, false)
if err != nil {
Expand All @@ -120,6 +119,9 @@ func (hc *httpClient) GetTCBBundle(ctx context.Context, fmspc []byte) (*TCBBundl

// Then fetch QE identity.
u = hc.getUrl(pcsAPIGetQEIdentityPath)
q = u.Query()
q.Set("update", string(update))
u.RawQuery = q.Encode()
rsp, err = hc.doPCSRequest(ctx, u, http.MethodGet, "", nil, false)
if err != nil {
return nil, fmt.Errorf("pcs: QE identity request failed: %w", err)
Expand Down
3 changes: 0 additions & 3 deletions go/common/sgx/pcs/mock.go

This file was deleted.

14 changes: 13 additions & 1 deletion go/common/sgx/pcs/pcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,22 @@ var (
mrSignerBlacklist = make(map[sgx.MrSigner]bool)
)

// UpdateType is the type of update to TCB info.
type UpdateType string

const (
// UpdateStandard indicates standard access to updated TCB Info provided as part of a TCB
// recovery event.
UpdateStandard UpdateType = "standard"
// UpdateEarly indicates an early access to updated TCB Info provided as part of a TCB recovery
// event.
UpdateEarly UpdateType = "early"
)

// Client is an Intel SGX PCS client interface.
type Client interface {
// GetTCBBundle retrieves the signed TCB artifacts needed to verify a quote.
GetTCBBundle(ctx context.Context, fmspc []byte) (*TCBBundle, error)
GetTCBBundle(ctx context.Context, fmspc []byte, update UpdateType) (*TCBBundle, error)

// GetPCKCertificateChain retrieves the PCK certificate chain for the given platform data or PPID.
//
Expand Down
21 changes: 17 additions & 4 deletions go/runtime/host/sgx/ecdsa.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,15 @@ func (ec *teeStateECDSA) Update(ctx context.Context, sp *sgxProvisioner, conn pr
// also do their own verification).
// Check bundles in order: fresh first, then cached, then try downloading again if there was
// no scheduled refresh this time.
tcbBundle, err := func() (*pcs.TCBBundle, error) {
getTcbBundle := func(update pcs.UpdateType) (*pcs.TCBBundle, error) {
var fresh *pcs.TCBBundle

cached, refresh := ec.tcbCache.check(pckInfo.FMSPC)
if refresh {
if fresh, err = sp.pcs.GetTCBBundle(ctx, pckInfo.FMSPC); err != nil {
if fresh, err = sp.pcs.GetTCBBundle(ctx, pckInfo.FMSPC, update); err != nil {
sp.logger.Warn("error downloading TCB refresh",
"err", err,
"update", update,
)
}
if err = ec.verifyBundle(quote, quotePolicy, fresh, sp, "fresh"); err == nil {
Expand All @@ -160,6 +161,7 @@ func (ec *teeStateECDSA) Update(ctx context.Context, sp *sgxProvisioner, conn pr
}
sp.logger.Warn("error verifying downloaded TCB refresh",
"err", err,
"update", update,
)
}

Expand All @@ -169,13 +171,18 @@ func (ec *teeStateECDSA) Update(ctx context.Context, sp *sgxProvisioner, conn pr

// If downloaded already, don't try again but just return the last error.
if refresh {
sp.logger.Warn("error verifying cached TCB",
"err", err,
"update", update,
)
return nil, fmt.Errorf("both fresh and cached TCB bundles failed verification, cached error: %w", err)
}

// If not downloaded yet this time round, try forcing. Any errors are fatal.
if fresh, err = sp.pcs.GetTCBBundle(ctx, pckInfo.FMSPC); err != nil {
if fresh, err = sp.pcs.GetTCBBundle(ctx, pckInfo.FMSPC, update); err != nil {
sp.logger.Warn("error downloading TCB",
"err", err,
"update", update,
)
return nil, err
}
Expand All @@ -184,7 +191,13 @@ func (ec *teeStateECDSA) Update(ctx context.Context, sp *sgxProvisioner, conn pr
}
ec.tcbCache.cache(fresh, pckInfo.FMSPC)
return fresh, nil
}()
}
var tcbBundle *pcs.TCBBundle
for _, update := range []pcs.UpdateType{pcs.UpdateStandard, pcs.UpdateEarly} {
if tcbBundle, err = getTcbBundle(update); err == nil {
break
}
}
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 0a0529d

Please sign in to comment.