arch.go 6.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
package intelsgx // import "github.com/opencontainers/runc/libenclave/intelsgx"

var (
	sgx1Supported           bool = false
	sgx2Supported           bool = false
	virtualizationSupported bool = false
	oversubSupported        bool = false
	miscSelectFeatures      uint32
	maxEnclaveSizeBits      uint32
)

// CPUID leafs
const (
	cpuidExtendedFeatureFlags = 0x7
	cpuidSgxFeature           = 0x12
)

// CPUID leaf 0x12 sub-leafs
const (
	sgxCapabilties    = 0
	sgxAttributes     = 1
	sgxEpcBaseSection = 2
	maxSgxEpcSections = 8
)

const (
27 28 29 30 31 32 33 34 35 36 37
	SigStructLength       = 1808
	EinittokenLength      = 304
	TargetinfoLength      = 512
	ReportLength          = ReportBodyLength + 48
	ReportBodyLength      = 384
	QuoteLength           = QuoteBodyLength + ReportBodyLength + 4
	QuoteBodyLength       = 48
	NonceLength           = 16
	SpidLength            = 16
	SubscriptionKeyLength = 16
	SgxMaxQuoteLength     = 2048
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
)

type SigStruct struct {
	Header         [16]byte  `struct:"[16]byte"`
	Vendor         uint32    `struct:"uint32,little"`
	BuildYear      uint16    `struct:"uint16,little"`
	BuildMonth     uint8     `struct:"uint8"`
	BuildDay       uint8     `struct:"uint8"`
	Header2        [16]byte  `struct:"[16]byte"`
	SwDefined      uint32    `struct:"uint32,little"`
	_              [84]byte  `struct:"[84]byte"`
	Modulus        [384]byte `struct:"[384]byte"`
	Exponent       uint32    `struct:"uint32,little"`
	Signature      [384]byte `struct:"[384]byte"`
	MiscSelect     uint32    `struct:"uint32,little"`
	MiscMask       uint32    `struct:"uint32,little"`
	_              [4]byte   `struct:"[4]byte"`
	ISVFamilyId    [16]byte  `struct:"[16]byte"`
	Attributes     [16]byte  `struct:"[16]byte"`
	AttributesMask [16]byte  `struct:"[16]byte"`
	EnclaveHash    [32]byte  `struct:"[32]byte"`
	_              [16]byte  `struct:"[16]byte"`
	ISVExtProdId   [16]byte  `struct:"[16]byte"`
	ISVProdId      uint16    `struct:"uint16,little"`
	ISVSvn         uint16    `struct:"uint16,little"`
	_              [12]byte  `struct:"[12]byte"`
	Q1             [384]byte `struct:"[384]byte"`
	Q2             [384]byte `struct:"[384]byte"`
}

type Einittoken struct {
	Valid              uint32   `struct:"uint32,little"`
	_                  [44]byte `struct:"[44]byte"`
	Attributes         [16]byte `struct:"[16]byte"`
	MrEnclave          [32]byte `struct:"[32]byte"`
	_                  [32]byte `struct:"[32]byte"`
	MrSigner           [32]byte `struct:"[32]byte"`
	_                  [32]byte `struct:"[32]byte"`
	CpuSvnLe           [16]byte `struct:"[16]byte"`
	ISVProdIdLe        uint16   `struct:"uint16"`
	ISVSvnLe           uint16   `struct:"uint16"`
	_                  [24]byte `struct:"[24]byte"`
	MaskedMiscSelectLe uint32   `struct:"uint32"`
	MaskedAttributesLe [16]byte `struct:"[16]byte"`
	KeyId              [32]byte `struct:"[32]byte"`
	Mac                [16]byte `struct:"[16]byte"`
}

86 87 88 89 90 91 92 93 94 95 96 97
type Targetinfo struct {
	Measurement   [32]byte  `struct:"[32]byte"`
	Attributes    [16]byte  `struct:"[16]byte"`
	CetAttributes uint8     `struct:"uint8"`
	_             uint8     `struct:"uint8"`
	ConfigSvn     uint16    `struct:"uint16"`
	MiscSelect    uint32    `struct:"uint32"`
	_             [8]byte   `struct:"[8]byte"`
	ConfigId      [64]byte  `struct:"[64]byte"`
	_             [384]byte `struct:"[384]byte"`
}

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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221
type Report struct {
	ReportBody
	Keyid [32]byte `struct:"[32]byte"`
	Mac   [16]byte `struct:"[16]byte"`
}

type ReportBody struct {
	CpuSvn       [16]byte `struct:"[16]byte"`
	MiscSelect   uint32   `struct:"uint32"`
	_            [12]byte `struct:"[12]byte"`
	IsvExtProdId [16]byte `struct:"[16]byte"`
	Attributes   [16]byte `struct:"[16]byte"`
	MrEnclave    [32]byte `struct:"[32]byte"`
	_            [32]byte `struct:"[32]byte"`
	MrSigner     [32]byte `struct:"[32]byte"`
	_            [32]byte `struct:"[32]byte"`
	ConfigId     [64]byte `struct:"[64]byte"`
	IsvProdId    uint16   `struct:"uint16"`
	IsvSvn       uint16   `struct:"uint16"`
	ConfigSvn    uint16   `struct:"uint16"`
	_            [42]byte `struct:"[42]byte"`
	IsvFamilyId  [16]byte `struct:"[16]byte"`
	ReportData   [64]byte `struct:"[64]byte"`
}

type Quote struct {
	QuoteBody
	ReportBody
	SigLen uint32 `struct:"uint32"`
}

const (
	QuoteSignatureTypeUnlinkable = iota
	QuoteSignatureTypeLinkable
)

const (
	QuoteVersion = 2
)

type QuoteBody struct {
	Version       uint16   `struct:"uint16"`
	SignatureType uint16   `struct:"uint16"`
	Gid           uint32   `struct:"uint32"`
	ISVSvnQe      uint16   `struct:"uint16"`
	ISVSvnPce     uint16   `struct:"uint16"`
	_             [4]byte  `struct:"[4]byte"`
	Basename      [32]byte `struct:"[32]byte"`
}

func cpuid_low(leaf, subLeaf uint32) (eax, ebx, ecx, edx uint32)

// Check whether CPUs support SGX or not
func IsSgxSupported() bool {
	_, ebx, _, _ := cpuid_low(cpuidExtendedFeatureFlags, 0)
	if (ebx & 0x4) == 0x0 {
		return false
	}

	return true
}

func GetSgxFeatures() {
	// cpuidSgxFeature leaf is supported only if cpuidExtendedFeatureFlags leaf supported
	if !IsSgxSupported() {
		return
	}

	eax, ebx, _, edx := cpuid_low(cpuidSgxFeature, sgxCapabilties)
	if (eax & 0x1) != 0 {
		sgx1Supported = true
	}

	if (eax & 0x2) != 0 {
		sgx2Supported = true
	}

	if (eax & 0x20) != 0 {
		virtualizationSupported = true
	}

	if (eax & 0x40) != 0 {
		oversubSupported = true
	}

	miscSelectFeatures = ebx

	bit := 32 << (^uint(0) >> 63)
	if bit == 64 {
		maxEnclaveSizeBits = (edx & 0xff00) >> 8
	} else {
		maxEnclaveSizeBits = edx & 0xff
	}
}

// Check whether Intel SGX supports the collection of SGX1 leaf functions
func IsSGX1FunctionsSupported() bool {
	return sgx1Supported
}

// Check whether Intel SGX supports the collection of SGX2 leaf functions
func IsSGX2FunctionsSupported() bool {
	return sgx2Supported
}

// Check whether Intel SGX supports ENCLV instructions EINCVIRTCHILD, EDECVIRTCHILD, and ESETCONTEXT
func IsVirtualizationSupported() bool {
	return virtualizationSupported
}

// Check whether Intel SGX supports ENCLS instructions ETRACKC, ERDINFO, ELDBC, and ELDUC
func IsOversubSupported() bool {
	return oversubSupported
}

// Get the bit vector of supported extended SGX features
func GetExtendedSGXFeatures() uint32 {
	return miscSelectFeatures
}

// Get the max enclave size value
func GetMaxEnclaveSizeBits() uint32 {
	return maxEnclaveSizeBits
}