sgx_server

package module
v0.0.0-...-801386f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2019 License: MIT Imports: 33 Imported by: 0

README

Go SGX Remote Attestation Server

Introduction

SGX is a new hardware instruction set and features Intel introduced to protect the code running in an untrusted environment (e.g., on cloud infrastructure, like AWS or GCP). One of the fundamental operations of SGX is "remote attestation" (RA). The goal of RA is to convince someone that a piece of code that has been vetted before is running on a device. The RA process is carried out between three parties in SGX: the enclave, the server (service provider), and the Intel Attestation Server (IAS). The enclave is the machine that is running the code that is supposed to be verified, and the server is the machine that wants to verify that the enclave is running the correct code. IAS helps the server verify that the enclave is running on a real SGX device, which in turn guarantees that the claims from the enclave are correct. Intel has some example code and more detailed explanations of this process on their website if you are interested.

This repository contains a pure Go implementation of the server side operations in SGX RA.

Requirements and installation

This code has been tested with Go v1.13. You can install this server by doing

go get -u ./...
go install ./...

This code uses protobufs to define some types that will be shared between the server and the enclave. There is an included generated protobuf file (sgx.pb.go), so you shouldn't need the compiler. But if you want to generate it from the proto source, you need protobuf compiler with the Go plugin for compiling the regular protobuf and gRPC services. Please follow the instructions on the Go protobuf repository to install them. You also might want make which automatically builds the protobuf and install the example server, though the Makefile is simple enough that you can just run those commands manually if you'd like.

Running the sample server

There is a sample server in cmd/example_server directory, which gets installed with installation command above. To run the server, you need to do two things:

  1. Create a configuration file for the server. The configuration file is a JSON file containing a few fields. This is documented more carefully in config.go. Save this file somewhere, e.g., config.json.

  2. Acquire TLS certificate and key. For testing, you can use a self signed cert. Call these files tls.crt and tls.key.

Now, you can run the server:

$GOPATH/bin/example_server -config config.json -tlsKey tls.key -tlsPub tls.crt

This runs the server on port 50051 (the default example port for gRPC). You can override this port via -port option.

Compatible SGX client and enclave

There is no public sample enclave that talks to this server yet, but this is in the works. In general, the messages in the proto file has been designed to very closely match the native SGX structures, so it should just be a matter of translating the SGX structs to proto messages, and sending it via gRPC calls defined in the proto file.

Documentation

Overview

Package sgx_server implements the ISV Remote Attestation Server of the SGX remote attestation pipeline, described in the Intel code sample:

https://software.intel.com/en-us/articles/code-sample-intel-software-guard-extensions-remote-attestation-end-to-end-example

The most typical way to interfact with this code base is through the SessionManager interface. The SessionManager manages the Session interfaces based on a session id, and can create or fetch new sessions. Each Session logically represents an SGX session. After proper authentication, the client on the other side of the connection is guaranteed to be an SGX device. Session also supports MACing or encrypting messages for the SGX client, which helps protect the integrity or confidentiality of the data.

You can configure this server (i.e., the SessionManager) using a pretty straightforward JSON-based configuration file.

Index

Constants

View Source
const (
	// dev
	DEBUG_IAS_HOST = "https://api.trustedservices.intel.com/sgx/dev/attestation/v3"
	// prod
	IAS_HOST = "https://api.trustedservices.intel.com/sgx/attestation/v3"
)

URL for the IAS attestation API.

View Source
const (
	ISV_NONCE        = "nonce"
	ISV_QUOTE        = "isvEnclaveQuote"
	ISV_QUOTE_BODY   = "isvEnclaveQuoteBody"
	ISV_QUOTE_STATUS = "isvEnclaveQuoteStatus"

	// 432 bytes for everything in the quote structure, except for
	// the signature fields.
	NO_SIG_QUOTE_LEN = 432

	PSE_MANIFEST        = "pseManifest"
	PSE_MANIFEST_HASH   = "pseManifestHash"
	PSE_MANIFEST_STATUS = "pseManifestStatus"

	PLATFORM_INFO_BLOB = "platformInfoBlob"
)

Fields of the report body.

View Source
const (
	ISV_OK                     = "OK"
	ISV_SIGNATURE_INVALID      = "SIGNATURE_INVALID"
	ISV_GROUP_REVOKED          = "GROUP_REVOKED"
	ISV_KEY_REVOKED            = "KEY_REVOKED"
	ISV_SIGRL_VERSION_MISMATCH = "SIGRL_VERSION_MISMATCH"
	ISV_CONFIGURATION_NEEDED   = "CONFIGURATION_NEEDED"
	ISV_GROUP_OUT_OF_DATE      = "GROUP_OUT_OF_DATE"
)

Possible errors from quote verification.

View Source
const (
	PSE_OK                  = "OK"
	PSE_UNKNOWN             = "UNKNOWN"
	PSE_INVALID             = "INVALID"
	PSE_OUT_OF_DATE         = "OUT_OF_DATE"
	PSE_REVOKED             = "REVOKED"
	PSE_RL_VERSION_MISMATCH = "RL_VERSION_MISMATCH"
)

Possible errors from platform services.

View Source
const (
	UNLINKABLE_QUOTE_INT = 0
	LINKABLE_QUOTE_INT   = 1
	KDF_ID_INT           = 1
	EC_COORD_SIZE        = 32
	EPID_GID_SIZE        = 4

	// CPU security version number.
	CPUSVN_IN_QUOTE = 48
	CPUSVN_SIZE     = 16

	// SSA frame extended feature set.
	// Currently not used, and is for potential future extensions.
	MISCSELECT_IN_QUOTE = 64
	MISCSELECT_SIZE     = 4

	// MREnclave starts at byte 112 in the quote.
	MRENCLAVE_IN_QUOTE = 112
	// MRSigner starts at byte 176 in the quote.
	MRSIGNER_IN_QUOTE = 176
	// MR values are geneated using SHA-256, so it's 32 bytes.
	MR_SIZE = 32

	// Enclave production ID.
	ISVPRODID_IN_QUOTE = 304
	ISVPRODID_SIZE     = 2

	// Enclave security version number.
	ISVSVN_IN_QUOTE = 306
	ISVSVN_SIZE     = 2

	// Enclave attributes start at 96, and is 16 bytes.
	ATTRIBUTES_IN_QUOTE = 96
	ATTRIBUTES_SIZE     = 16

	// Hash report starts at byte 368 in the quote
	HASH_REPORT_IN_QUOTE = 368
)

Magic constants used to check the SGX attestation quote. Acquired from https://api.trustedservices.intel.com/documents/sgx-attestation-api-spec.pdf

View Source
const (
	// If set, then the enclave is initialized
	SGX_FLAGS_INITTED = 0x0000000000000001
	// If set, then the enclave is debug
	SGX_FLAGS_DEBUG = 0x0000000000000002
	// If set, then the enclave is 64 bit
	SGX_FLAGS_MODE64BIT = 0x0000000000000004
	// If set, then the enclave has access to provision key
	SGX_FLAGS_PROVISION_KEY = 0x0000000000000010
	// If set, then the enclave has access to EINITTOKEN key
	SGX_FLAGS_EINITTOKEN_KEY = 0x0000000000000020
	// If set enclave uses KSS
	SGX_FLAGS_KSS = 0x000000000000008
)

SGX Enclave flag bits. Acquired from sgx_attributes.h.

View Source
const (
	HEADER_SUBSCRIPTION_KEY = "Ocp-Apim-Subscription-Key"
)

Fields of the header we set for the IAS.

View Source
const (
	// Mininum Intel Attestation Server in the report.
	MIN_IAS_VERSION_NUMBER = 3
)

Intel Attestation Server parameteres.

View Source
const MSG4_SECRET = "REPLACE_ME_WITH_REAL_SECRET"

MSG4_SECRET is what is sent in the last message of SGX attestation, encrypted under a key shared between the server and the client during attestation. You can either change this to a different value, or dynamically generate secrets to send to different enclaves for various reasons.

Variables

View Source
var (
	KDF_ID           = []byte{1, 0}
	UNLINKABLE_QUOTE = []byte{0, 0}
	LINKABLE_QUOTE   = []byte{1, 0}
)

Magic constants used to check the SGX attestation quote.

View Source
var (
	SMK_LABEL = []byte{'S', 'M', 'K'}
	VK_LABEL  = []byte{'V', 'K'}
	SK_LABEL  = []byte{'S', 'K'}
	MK_LABEL  = []byte{'M', 'K'}
)

Magic constants for deriving cryptographic keys for SGX sessions.

Functions

func RegisterAttestationServer

func RegisterAttestationServer(s *grpc.Server, srv AttestationServer)

Types

type A

type A struct {
	Gb   *PublicKey `protobuf:"bytes,1,opt,name=gb,proto3" json:"gb,omitempty"`
	Spid []byte     `protobuf:"bytes,2,opt,name=spid,proto3" json:"spid,omitempty"`
	// quote_type and kdf_id are actually uint16_t,
	// but protobufs don't have such types, so keep as bytes
	QuoteType            []byte     `protobuf:"bytes,3,opt,name=quote_type,json=quoteType,proto3" json:"quote_type,omitempty"`
	KdfId                []byte     `protobuf:"bytes,4,opt,name=kdf_id,json=kdfId,proto3" json:"kdf_id,omitempty"`
	Signature            *Signature `protobuf:"bytes,5,opt,name=signature,proto3" json:"signature,omitempty"`
	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
	XXX_unrecognized     []byte     `json:"-"`
	XXX_sizecache        int32      `json:"-"`
}

func (*A) Descriptor

func (*A) Descriptor() ([]byte, []int)

func (*A) GetGb

func (m *A) GetGb() *PublicKey

func (*A) GetKdfId

func (m *A) GetKdfId() []byte

func (*A) GetQuoteType

func (m *A) GetQuoteType() []byte

func (*A) GetSignature

func (m *A) GetSignature() *Signature

func (*A) GetSpid

func (m *A) GetSpid() []byte

func (*A) ProtoMessage

func (*A) ProtoMessage()

func (*A) Reset

func (m *A) Reset()

func (*A) String

func (m *A) String() string

func (*A) XXX_DiscardUnknown

func (m *A) XXX_DiscardUnknown()

func (*A) XXX_Marshal

func (m *A) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*A) XXX_Merge

func (m *A) XXX_Merge(src proto.Message)

func (*A) XXX_Size

func (m *A) XXX_Size() int

func (*A) XXX_Unmarshal

func (m *A) XXX_Unmarshal(b []byte) error

type AttestationClient

type AttestationClient interface {
	StartAttestation(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Challenge, error)
	SendMsg1(ctx context.Context, in *Msg1, opts ...grpc.CallOption) (*Msg2, error)
	SendMsg3(ctx context.Context, in *Msg3, opts ...grpc.CallOption) (*Msg4, error)
}

AttestationClient is the client API for Attestation service.

For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.

func NewAttestationClient

func NewAttestationClient(cc *grpc.ClientConn) AttestationClient

type AttestationResult

type AttestationResult struct {
	EnclaveTrusted bool `protobuf:"varint,1,opt,name=enclave_trusted,json=enclaveTrusted,proto3" json:"enclave_trusted,omitempty"`
	PseTrusted     bool `protobuf:"varint,2,opt,name=pse_trusted,json=pseTrusted,proto3" json:"pse_trusted,omitempty"`
	// only sent on error
	Pib                  []byte   `protobuf:"bytes,3,opt,name=pib,proto3" json:"pib,omitempty"`
	Advisories           []string `protobuf:"bytes,4,rep,name=advisories,proto3" json:"advisories,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (*AttestationResult) Descriptor

func (*AttestationResult) Descriptor() ([]byte, []int)

func (*AttestationResult) GetAdvisories

func (m *AttestationResult) GetAdvisories() []string

func (*AttestationResult) GetEnclaveTrusted

func (m *AttestationResult) GetEnclaveTrusted() bool

func (*AttestationResult) GetPib

func (m *AttestationResult) GetPib() []byte

func (*AttestationResult) GetPseTrusted

func (m *AttestationResult) GetPseTrusted() bool

func (*AttestationResult) ProtoMessage

func (*AttestationResult) ProtoMessage()

func (*AttestationResult) Reset

func (m *AttestationResult) Reset()

func (*AttestationResult) String

func (m *AttestationResult) String() string

func (*AttestationResult) XXX_DiscardUnknown

func (m *AttestationResult) XXX_DiscardUnknown()

func (*AttestationResult) XXX_Marshal

func (m *AttestationResult) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*AttestationResult) XXX_Merge

func (m *AttestationResult) XXX_Merge(src proto.Message)

func (*AttestationResult) XXX_Size

func (m *AttestationResult) XXX_Size() int

func (*AttestationResult) XXX_Unmarshal

func (m *AttestationResult) XXX_Unmarshal(b []byte) error

type AttestationServer

type AttestationServer interface {
	StartAttestation(context.Context, *Request) (*Challenge, error)
	SendMsg1(context.Context, *Msg1) (*Msg2, error)
	SendMsg3(context.Context, *Msg3) (*Msg4, error)
}

AttestationServer is the server API for Attestation service.

type Cache

type Cache interface {
	// Store the session under id key.
	Set(key string, session Session)

	// Get fetches the session correspoding to the session id key,
	// and returns (point to the session, true) if the id exsits.
	// Otherwise, Get returns (nil, false).
	Get(key string) (Session, bool)

	// Delete the entry if the key exists.
	Delete(key string)
}

Cache manages the lists of sessions and their ids. Typically, a cache will have some sort of capacity and an eviction policy which helps the SessionManager manage a number of sessions effectively.

func NewSimpleLRUCache

func NewSimpleLRUCache(capacity int) Cache

NewSimpleLRUCache generates a simple cache with capacity, and implements a simple LRU eviction policy.

type Challenge

type Challenge struct {
	SessionId            string   `protobuf:"bytes,1,opt,name=session_id,json=sessionId,proto3" json:"session_id,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (*Challenge) Descriptor

func (*Challenge) Descriptor() ([]byte, []int)

func (*Challenge) GetSessionId

func (m *Challenge) GetSessionId() string

func (*Challenge) ProtoMessage

func (*Challenge) ProtoMessage()

func (*Challenge) Reset

func (m *Challenge) Reset()

func (*Challenge) String

func (m *Challenge) String() string

func (*Challenge) XXX_DiscardUnknown

func (m *Challenge) XXX_DiscardUnknown()

func (*Challenge) XXX_Marshal

func (m *Challenge) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Challenge) XXX_Merge

func (m *Challenge) XXX_Merge(src proto.Message)

func (*Challenge) XXX_Size

func (m *Challenge) XXX_Size() int

func (*Challenge) XXX_Unmarshal

func (m *Challenge) XXX_Unmarshal(b []byte) error

type Configuration

type Configuration struct {
	// If true, the session manager will start in release mode,
	// meaning it will connect to the production version of IAS.
	Release bool

	// The subscription key for IAS API. This can be found at
	// https://api.portal.trustedservices.intel.com
	Subscription string

	// The directory that contains all the MREnclave files
	// that are acceptable for this session manager.
	Mrenclaves string

	// The directory that contains all the MRSigner files
	// that are acceptable for this session manager.
	Mrsigners string

	// Hex encoded SPID for IAS API. This can be found at
	// https://api.portal.trustedservices.intel.com
	Spid string

	// The file that contains a PEM encoded long-term ECDSA P-256
	// (SECP256R1) private key for establishing the session. The
	// public key component of this key should be built-in to the
	// client enclave.
	LongTermKey string

	// If True, then it will either prompt the user to type in the
	// password, or use LongTermKeyPassword field to decrypt the
	// long term key.
	LongTermKeyEncrypted bool

	// If LongTermKeyEncrypted is true, and this password is set
	// to an empty string, the program will prompt user for
	// input. Otherwise, LongTermKeyPassword is used as the
	// password.
	LongTermKeyPassword string

	// AllowedAdvisories maps an error during quote verification
	// to which advisories we are allowed to ignore. Current valid
	// keys are: ["CONFIGURATION_NEEDED", "GROUP_OUT_OF_DATE"].
	// Be careful to not set this too liberally.
	AllowedAdvisories map[string][]string

	// ProdID is the enclave production ID set by the entity
	// generating the enclave. It must be a 16-bit int.
	ProdID int

	// ProdSVN is the enclave security version number set by the
	// entity generating the enclave. This is used as the minimum
	// acceptable security version number, meaning any enclave
	// with higher SVN is accepted. It must be a 16-bit int.
	ProdSVN int

	// The maximum number of concurrent sessions the session
	// manager will keep alive. If MaxSessions is -1, then we
	// allow unlimited number of sessions.
	MaxSessions int

	// A session times out after Timeout minutes.
	// If there is no activity for this session within the past
	// Timeout minutes, the manager will remove the session,
	// and the client will have to reauthenticate itself.
	// If Timeout is -1, then a session will never expire.
	// except if there are more than MaxSessions sessions,
	// then the oldest ones will be removed.
	Timeout int
}

func ReadConfiguration

func ReadConfiguration(fileName string) *Configuration

ReadConfiguration parses the configuration file, and generates the internal configuration to initialize the session manager. It will fail with log.Fatal if it could not parse the config.

type IAS

type IAS interface {
	// GetRevocationList takes in the gid from Msg1 of the SGX
	// attestation, and talks to the IAS to fetch and return the
	// corresponding revocation list.
	GetRevocationList(gid []byte) ([]byte, error)

	// VerifyQuote takes in the SGX platform security property
	// descruotor and the attestation quote from Msg3 of the SGX
	// attestation, and talks to the IAS to request the quote
	// verification. The IAS can return many advisories
	// depending on the quote, which is included in the error
	// returned. Returns if the PSE can be trusted, the platform
	// information blob, a list of security advisories from Intel,
	// and any error during quote verification.
	VerifyQuoteAndPSE(quote, pse []byte) (bool, []byte, []string, error)
}

IAS communicates with the Intel Attestation Service to provide the caller with the revocation list, or the result of verifying the enclave quote.

func NewIAS

func NewIAS(release bool, subscription string, allowedAdvisories map[string][]string) IAS

NewIAS creates a service that talks to the Intel Attestation Service to download revocation lists and verify quotes. Depending on the value of release parameter, the code will talk to the development or the production version of IAS. You must also provide the subscription string for the correct mode (which can be found at https://api.portal.trustedservices.intel.com). allowedAdvisories paramter specifies which error-advisory combinations are allowed when verifying quotes. This can be useful, for example, when trying to allow hyperthreading in SGX, which automatically yields misconfigured error.

type M

type M struct {
	Ga                   *PublicKey `protobuf:"bytes,1,opt,name=ga,proto3" json:"ga,omitempty"`
	PsSecurityProp       []byte     `protobuf:"bytes,2,opt,name=ps_security_prop,json=psSecurityProp,proto3" json:"ps_security_prop,omitempty"`
	Quote                []byte     `protobuf:"bytes,3,opt,name=quote,proto3" json:"quote,omitempty"`
	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
	XXX_unrecognized     []byte     `json:"-"`
	XXX_sizecache        int32      `json:"-"`
}

func (*M) Descriptor

func (*M) Descriptor() ([]byte, []int)

func (*M) GetGa

func (m *M) GetGa() *PublicKey

func (*M) GetPsSecurityProp

func (m *M) GetPsSecurityProp() []byte

func (*M) GetQuote

func (m *M) GetQuote() []byte

func (*M) ProtoMessage

func (*M) ProtoMessage()

func (*M) Reset

func (m *M) Reset()

func (*M) String

func (m *M) String() string

func (*M) XXX_DiscardUnknown

func (m *M) XXX_DiscardUnknown()

func (*M) XXX_Marshal

func (m *M) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*M) XXX_Merge

func (m *M) XXX_Merge(src proto.Message)

func (*M) XXX_Size

func (m *M) XXX_Size() int

func (*M) XXX_Unmarshal

func (m *M) XXX_Unmarshal(b []byte) error

type Msg0

type Msg0 struct {
	Exgid                uint32   `protobuf:"varint,1,opt,name=exgid,proto3" json:"exgid,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (*Msg0) Descriptor

func (*Msg0) Descriptor() ([]byte, []int)

func (*Msg0) GetExgid

func (m *Msg0) GetExgid() uint32

func (*Msg0) ProtoMessage

func (*Msg0) ProtoMessage()

func (*Msg0) Reset

func (m *Msg0) Reset()

func (*Msg0) String

func (m *Msg0) String() string

func (*Msg0) XXX_DiscardUnknown

func (m *Msg0) XXX_DiscardUnknown()

func (*Msg0) XXX_Marshal

func (m *Msg0) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Msg0) XXX_Merge

func (m *Msg0) XXX_Merge(src proto.Message)

func (*Msg0) XXX_Size

func (m *Msg0) XXX_Size() int

func (*Msg0) XXX_Unmarshal

func (m *Msg0) XXX_Unmarshal(b []byte) error

type Msg1

type Msg1 struct {
	Msg0                 *Msg0      `protobuf:"bytes,1,opt,name=msg0,proto3" json:"msg0,omitempty"`
	Ga                   *PublicKey `protobuf:"bytes,2,opt,name=ga,proto3" json:"ga,omitempty"`
	Gid                  []byte     `protobuf:"bytes,3,opt,name=gid,proto3" json:"gid,omitempty"`
	XXX_NoUnkeyedLiteral struct{}   `json:"-"`
	XXX_unrecognized     []byte     `json:"-"`
	XXX_sizecache        int32      `json:"-"`
}

send msg0 and msg1 together, as per intel's suggestion

func (*Msg1) Descriptor

func (*Msg1) Descriptor() ([]byte, []int)

func (*Msg1) GetGa

func (m *Msg1) GetGa() *PublicKey

func (*Msg1) GetGid

func (m *Msg1) GetGid() []byte

func (*Msg1) GetMsg0

func (m *Msg1) GetMsg0() *Msg0

func (*Msg1) ProtoMessage

func (*Msg1) ProtoMessage()

func (*Msg1) Reset

func (m *Msg1) Reset()

func (*Msg1) String

func (m *Msg1) String() string

func (*Msg1) XXX_DiscardUnknown

func (m *Msg1) XXX_DiscardUnknown()

func (*Msg1) XXX_Marshal

func (m *Msg1) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Msg1) XXX_Merge

func (m *Msg1) XXX_Merge(src proto.Message)

func (*Msg1) XXX_Size

func (m *Msg1) XXX_Size() int

func (*Msg1) XXX_Unmarshal

func (m *Msg1) XXX_Unmarshal(b []byte) error

type Msg2

type Msg2 struct {
	A                    *A       `protobuf:"bytes,1,opt,name=a,proto3" json:"a,omitempty"`
	CmacA                []byte   `protobuf:"bytes,2,opt,name=cmac_a,json=cmacA,proto3" json:"cmac_a,omitempty"`
	SigRlSize            uint32   `protobuf:"varint,3,opt,name=sig_rl_size,json=sigRlSize,proto3" json:"sig_rl_size,omitempty"`
	SigRl                []byte   `protobuf:"bytes,4,opt,name=sig_rl,json=sigRl,proto3" json:"sig_rl,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (*Msg2) Descriptor

func (*Msg2) Descriptor() ([]byte, []int)

func (*Msg2) GetA

func (m *Msg2) GetA() *A

func (*Msg2) GetCmacA

func (m *Msg2) GetCmacA() []byte

func (*Msg2) GetSigRl

func (m *Msg2) GetSigRl() []byte

func (*Msg2) GetSigRlSize

func (m *Msg2) GetSigRlSize() uint32

func (*Msg2) ProtoMessage

func (*Msg2) ProtoMessage()

func (*Msg2) Reset

func (m *Msg2) Reset()

func (*Msg2) String

func (m *Msg2) String() string

func (*Msg2) XXX_DiscardUnknown

func (m *Msg2) XXX_DiscardUnknown()

func (*Msg2) XXX_Marshal

func (m *Msg2) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Msg2) XXX_Merge

func (m *Msg2) XXX_Merge(src proto.Message)

func (*Msg2) XXX_Size

func (m *Msg2) XXX_Size() int

func (*Msg2) XXX_Unmarshal

func (m *Msg2) XXX_Unmarshal(b []byte) error

type Msg3

type Msg3 struct {
	CmacM                []byte   `protobuf:"bytes,1,opt,name=cmac_m,json=cmacM,proto3" json:"cmac_m,omitempty"`
	M                    *M       `protobuf:"bytes,2,opt,name=m,proto3" json:"m,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (*Msg3) Descriptor

func (*Msg3) Descriptor() ([]byte, []int)

func (*Msg3) GetCmacM

func (m *Msg3) GetCmacM() []byte

func (*Msg3) GetM

func (m *Msg3) GetM() *M

func (*Msg3) ProtoMessage

func (*Msg3) ProtoMessage()

func (*Msg3) Reset

func (m *Msg3) Reset()

func (*Msg3) String

func (m *Msg3) String() string

func (*Msg3) XXX_DiscardUnknown

func (m *Msg3) XXX_DiscardUnknown()

func (*Msg3) XXX_Marshal

func (m *Msg3) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Msg3) XXX_Merge

func (m *Msg3) XXX_Merge(src proto.Message)

func (*Msg3) XXX_Size

func (m *Msg3) XXX_Size() int

func (*Msg3) XXX_Unmarshal

func (m *Msg3) XXX_Unmarshal(b []byte) error

type Msg4

type Msg4 struct {
	Result               *AttestationResult `protobuf:"bytes,1,opt,name=result,proto3" json:"result,omitempty"`
	Secret               []byte             `protobuf:"bytes,2,opt,name=secret,proto3" json:"secret,omitempty"`
	Cmac                 []byte             `protobuf:"bytes,3,opt,name=cmac,proto3" json:"cmac,omitempty"`
	XXX_NoUnkeyedLiteral struct{}           `json:"-"`
	XXX_unrecognized     []byte             `json:"-"`
	XXX_sizecache        int32              `json:"-"`
}

TODO: figure out exactly what msg4 looks like

func (*Msg4) Descriptor

func (*Msg4) Descriptor() ([]byte, []int)

func (*Msg4) GetCmac

func (m *Msg4) GetCmac() []byte

func (*Msg4) GetResult

func (m *Msg4) GetResult() *AttestationResult

func (*Msg4) GetSecret

func (m *Msg4) GetSecret() []byte

func (*Msg4) ProtoMessage

func (*Msg4) ProtoMessage()

func (*Msg4) Reset

func (m *Msg4) Reset()

func (*Msg4) String

func (m *Msg4) String() string

func (*Msg4) XXX_DiscardUnknown

func (m *Msg4) XXX_DiscardUnknown()

func (*Msg4) XXX_Marshal

func (m *Msg4) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Msg4) XXX_Merge

func (m *Msg4) XXX_Merge(src proto.Message)

func (*Msg4) XXX_Size

func (m *Msg4) XXX_Size() int

func (*Msg4) XXX_Unmarshal

func (m *Msg4) XXX_Unmarshal(b []byte) error

type PublicKey

type PublicKey struct {
	X                    []byte   `protobuf:"bytes,1,opt,name=x,proto3" json:"x,omitempty"`
	Y                    []byte   `protobuf:"bytes,2,opt,name=y,proto3" json:"y,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (*PublicKey) Descriptor

func (*PublicKey) Descriptor() ([]byte, []int)

func (*PublicKey) GetX

func (m *PublicKey) GetX() []byte

func (*PublicKey) GetY

func (m *PublicKey) GetY() []byte

func (*PublicKey) ProtoMessage

func (*PublicKey) ProtoMessage()

func (*PublicKey) Reset

func (m *PublicKey) Reset()

func (*PublicKey) String

func (m *PublicKey) String() string

func (*PublicKey) XXX_DiscardUnknown

func (m *PublicKey) XXX_DiscardUnknown()

func (*PublicKey) XXX_Marshal

func (m *PublicKey) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*PublicKey) XXX_Merge

func (m *PublicKey) XXX_Merge(src proto.Message)

func (*PublicKey) XXX_Size

func (m *PublicKey) XXX_Size() int

func (*PublicKey) XXX_Unmarshal

func (m *PublicKey) XXX_Unmarshal(b []byte) error

type Request

type Request struct {
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

TODO: actually put in some relevant values into request

func (*Request) Descriptor

func (*Request) Descriptor() ([]byte, []int)

func (*Request) ProtoMessage

func (*Request) ProtoMessage()

func (*Request) Reset

func (m *Request) Reset()

func (*Request) String

func (m *Request) String() string

func (*Request) XXX_DiscardUnknown

func (m *Request) XXX_DiscardUnknown()

func (*Request) XXX_Marshal

func (m *Request) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Request) XXX_Merge

func (m *Request) XXX_Merge(src proto.Message)

func (*Request) XXX_Size

func (m *Request) XXX_Size() int

func (*Request) XXX_Unmarshal

func (m *Request) XXX_Unmarshal(b []byte) error

type Session

type Session interface {
	// Id returns the id associated with this session.
	// Usually hex encoded 16 byte random value, if created using
	// the default SessionManager provided in this module.
	Id() string

	// ProcessMsg1 processes the SGX message 1 (which actually
	// contains SGX message 0 as well), and updates the internal
	// states of the session.
	ProcessMsg1(msg1 *Msg1) error

	// CreateMsg2 returns the message 2 after processing
	// message 1.
	CreateMsg2() (*Msg2, error)

	// ProcessMsg3 receives the SGX message 3 (which contains
	// things like the enclave quote), and verifies the validity
	// of the message with the Intel Attestation Service.
	ProcessMsg3(msg3 *Msg3) error

	// CreateMsg4 returns the last message in SGX attestation.
	CreateMsg4() (*Msg4, error)

	// Authenticated returns if the session has been
	// authenticated.
	Authenticated() bool

	// Seal uses authenticated encryption to encrypt msg for the
	// SGX client. It uses AES GCM to encrypt the message with
	// a random nonce, and it prepends the nonce the resulting
	// ciphertext. The key used is SK derived during the
	// attestation process. This function MUST be called AFTER
	// ProcessMsg3 returns no error.
	Seal(msg []byte) ([]byte, error)

	// Open decrypts and verifies the integrity of a ciphertext
	// generated using Seal. In practice, the ciphertext will
	// be generated by the client which implements the same
	// Seal and Open protocol.
	Open(ciphertext []byte) ([]byte, error)

	// MAC generates a message authentication code using MK
	// derived during the attestation process. It uses CMAC
	// based on AES to genearate the MAC, which is the standard
	// for SGX.
	MAC(msg []byte) []byte

	// Expires returns an error if the sesion is expired already.
	Expired() error
}

Session represents a logical connection between an SGX client and this server.

func NewSession

func NewSession(id string, release bool, timeout int, ias IAS, mrenclaves, mrsigners [][MR_SIZE]byte, spid []byte, longTermKey *ecdsa.PrivateKey, prodID, prodSVN uint16) Session

NewSession creates a new session with id. If a session is not used for timeout minutes, then the session is considered invalid. NewSession also receives the interface to IAS, a list of MREnclaves, the SPID for this server, and the private key whose public key is baked into the enclave.

type SessionManager

type SessionManager interface {
	// GetSession returns (Session, true) if there exists a
	// session that matches id. Otherwise, it returns
	// (nil, false).
	GetSession(id string) (Session, bool)

	// NewSession creates a new session. This generates a new
	// unique session id for the session, and returns the id
	// and a random challenge.
	NewSession(in *Request) (*Challenge, error)

	// Msg1ToMsg3 processes SGX message 1 and generates SGX
	// message 2 for the session matching id.
	Msg1ToMsg2(id string, msg1 *Msg1) (*Msg2, error)

	// Msg3ToMsg4 processes SGX message 3 and generates SGX
	// message 4 for the session matching id.
	Msg3ToMsg4(id string, msg3 *Msg3) (*Msg4, error)
}

SessionManager keeps records of different SGX sessions with different clients using session ids. Note that even though NewSession returns the user the session ID, it is *NOT* included in the client's subsequent messages to the server. This is because the clients are expected to include the ID in the metadata of the gRPC call. The AttestationServer interface, which this interface almost implements, is reponsible for parsing the metadata. See the server in cmd/example_server on how to do this.

func NewSessionManager

func NewSessionManager(config *Configuration) SessionManager

NewSessionManager creates a simple SessionManager with LRU cache policy using the configuration.

type Signature

type Signature struct {
	R                    []byte   `protobuf:"bytes,1,opt,name=r,proto3" json:"r,omitempty"`
	S                    []byte   `protobuf:"bytes,2,opt,name=s,proto3" json:"s,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (*Signature) Descriptor

func (*Signature) Descriptor() ([]byte, []int)

func (*Signature) GetR

func (m *Signature) GetR() []byte

func (*Signature) GetS

func (m *Signature) GetS() []byte

func (*Signature) ProtoMessage

func (*Signature) ProtoMessage()

func (*Signature) Reset

func (m *Signature) Reset()

func (*Signature) String

func (m *Signature) String() string

func (*Signature) XXX_DiscardUnknown

func (m *Signature) XXX_DiscardUnknown()

func (*Signature) XXX_Marshal

func (m *Signature) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Signature) XXX_Merge

func (m *Signature) XXX_Merge(src proto.Message)

func (*Signature) XXX_Size

func (m *Signature) XXX_Size() int

func (*Signature) XXX_Unmarshal

func (m *Signature) XXX_Unmarshal(b []byte) error

type UnimplementedAttestationServer

type UnimplementedAttestationServer struct {
}

UnimplementedAttestationServer can be embedded to have forward compatible implementations.

func (*UnimplementedAttestationServer) SendMsg1

func (*UnimplementedAttestationServer) SendMsg1(ctx context.Context, req *Msg1) (*Msg2, error)

func (*UnimplementedAttestationServer) SendMsg3

func (*UnimplementedAttestationServer) SendMsg3(ctx context.Context, req *Msg3) (*Msg4, error)

func (*UnimplementedAttestationServer) StartAttestation

func (*UnimplementedAttestationServer) StartAttestation(ctx context.Context, req *Request) (*Challenge, error)

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL