Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented Intel SGX driver and example setup #183

Merged
merged 3 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ example-setup/metadata-signed/*
tpmdriver/test_encrypted_ak.json
est/server/server
attestationreport/cache/*
testtool/private.pem
testtool/public.pem
10 changes: 8 additions & 2 deletions attestationreport/attestationreport.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,8 +344,14 @@ type CompanyDescription struct {
// DeviceConfig contains the local device configuration parameters
type DeviceConfig struct {
MetaInfo
AkCsr CsrParams `json:"akCsr" cbor:"3,keyasint"`
IkCsr CsrParams `json:"ikCsr" cbor:"4,keyasint"`
AkCsr CsrParams `json:"akCsr" cbor:"3,keyasint"`
IkCsr CsrParams `json:"ikCsr" cbor:"4,keyasint"`
SgxValues struct {
EncryptedPPID HexByte `json:"encryptedPPID" cbor:"5,keyasint"`
Pceid HexByte `json:"pceid" cbor:"6,keyasint"`
Cpusvn HexByte `json:"cpusvn" cbor:"7,keyasint"`
Pcesvn HexByte `json:"pcesvn" cbor:"8,keyasint"`
}
}

// CsrParams contains certificate signing request parameters
Expand Down
28 changes: 18 additions & 10 deletions attestationreport/intel_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/asn1"
"encoding/binary"
Expand Down Expand Up @@ -282,7 +283,7 @@ type Configuration struct {

// ------------------------- end SGX Extensions -------------------------

func parseSGXExtensions(extensions []byte) (SGXExtensionsValue, error) {
func ParseSGXExtensions(extensions []byte) (SGXExtensionsValue, error) {
var sgx_extensions SGXExtensionsValue

rest, err := asn1.Unmarshal(extensions, &sgx_extensions.Ppid)
Expand Down Expand Up @@ -464,7 +465,7 @@ func parseECDSASignature(buf *bytes.Buffer, sig *ECDSA256QuoteSignatureDataStruc
return fmt.Errorf("failed to parse QECertDataSize")
}
tmp = make([]byte, sig.QECertDataSize)
binary.Read(buf, binary.LittleEndian, &tmp)
err = binary.Read(buf, binary.LittleEndian, &tmp)
if err != nil {
return fmt.Errorf("failed to parse QECertData")
}
Expand Down Expand Up @@ -613,7 +614,7 @@ func VerifyIntelQuoteSignature(reportRaw []byte, quoteSignature any,
case TDX_QUOTE_TYPE:
x509Chains, code = VerifyIntelCertChainFull(certs, CA_PLATFORM, intelCache)
}
if err != nil {
if code != NotSet {
log.Tracef("Failed to verify certificate chain: %v", err)
result.CertChainCheck.SetErr(code)
return result, false
Expand Down Expand Up @@ -658,12 +659,11 @@ func verifyTcbInfo(tcbInfo *TcbInfo, tcbInfoBodyRaw string, tcbKeyCert *x509.Cer
return result
}

regex := regexp.MustCompile(`\s+`)
// remove whitespaces
regex.ReplaceAllString(tcbInfoBodyRaw, "")
regex := regexp.MustCompile(`("(?:\\.|[^"])*")|\s+`)
// remove whitespaces from json while preserving strings
tcbInfoBodyRaw = regex.ReplaceAllString(tcbInfoBodyRaw, "$1")
// remove "{"tcbInfo":" from beginning and signature + rest from the end
tcbInfoBodyRaw = tcbInfoBodyRaw[len(`{"tcbInfo":`) : len(tcbInfoBodyRaw)-128-16]

// get checksum of tcb info body
digest := sha256.Sum256([]byte(tcbInfoBodyRaw))

Expand Down Expand Up @@ -783,7 +783,7 @@ func VerifyQEIdentity(qeReportBody *EnclaveReportBody, qeIdentity *QEIdentity, q
}

regex := regexp.MustCompile(`\s+`)
regex.ReplaceAllString(qeIdentityBodyRaw, "") // remove whitespace
qeIdentityBodyRaw = regex.ReplaceAllString(qeIdentityBodyRaw, "") // remove whitespace
qeIdentityBodyRaw = qeIdentityBodyRaw[len(`{"enclaveIdentity":`) : len(qeIdentityBodyRaw)-128-16] // remove "{"enclaveIdentity":" from beginning and signature + rest from the end

// get checksum of qe identity body
Expand Down Expand Up @@ -1013,13 +1013,21 @@ func fetchCRL(uri string, name string, ca string, cache string) (*x509.Revocatio
if err != nil {
return nil, err
}
return crl, nil
}
return nil, err
}

// Download CRL from the Intel PCS
func downloadCRL(uri string) (*x509.RevocationList, error) {
resp, err := http.Get(uri)
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)

}
tlsConfig := &tls.Config{InsecureSkipVerify: true}
client := http.Client{Transport: &http.Transport{TLSClientConfig: tlsConfig}}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -1057,7 +1065,7 @@ func VerifyIntelCertChainFull(quoteCerts SgxCertificates, ca string, intelCache
// download CRLs from PCS
root_ca_crl, err := fetchCRL(PCS_ROOT_CA_CRL_URI, ROOT_CA_CRL_NAME, "", intelCache)
if err != nil {
log.Tracef("downloading ROOT CA CRL from PCS failed: %v", err)
log.Tracef("downloading Root CA CRL from PCS failed: %v", err)
return nil, DownloadRootCRL
}

Expand Down
6 changes: 3 additions & 3 deletions attestationreport/sgx.go
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ func verifySgxMeasurements(sgxM Measurement, nonce []byte, intelCache string, re
}

// Parse and verify PCK certificate extensions
sgxExtensions, err := parseSGXExtensions(quoteCerts.PCKCert.Extensions[SGX_EXTENSION_INDEX].Value[4:]) // skip the first value (not relevant)
sgxExtensions, err := ParseSGXExtensions(quoteCerts.PCKCert.Extensions[SGX_EXTENSION_INDEX].Value[4:]) // skip the first value (not relevant)
if err != nil {
log.Tracef("failed to parse SGX Extensions from PCK Certificate: %v", err)
result.Summary.SetErr(ParseExtensions)
Expand Down Expand Up @@ -305,7 +305,7 @@ func VerifySgxQuoteBody(body *EnclaveReportBody, tcbInfo *TcbInfo,
result.Artifacts = append(result.Artifacts,
DigestResult{
Name: "MrSigner",
Digest: hex.EncodeToString(body.MRENCLAVE[:]),
Digest: hex.EncodeToString(body.MRSIGNER[:]),
Success: strings.EqualFold(sgxReferenceValue.Sgx.MrSigner, hex.EncodeToString(body.MRSIGNER[:])),
Type: "Measurement",
},
Expand All @@ -331,7 +331,7 @@ func VerifySgxQuoteBody(body *EnclaveReportBody, tcbInfo *TcbInfo,

for _, v := range result.Artifacts {
if !v.Success {
return fmt.Errorf("TDX Quote Body Verification failed. %v: (Got: %v)", v.Name, v.Digest)
return fmt.Errorf("SGX Quote Body Verification failed. %v: (Got: %v)", v.Name, v.Digest)
}
}

Expand Down
9 changes: 4 additions & 5 deletions attestationreport/sgx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ func TestParseSGXExtensions(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parseSGXExtensions(tt.args.extensions)
got, err := ParseSGXExtensions(tt.args.extensions)
if (err != nil) != tt.wantErr {
t.Errorf("ParseSGXExtensions() error = %v, wantErr %v", err, tt.wantErr)
fmt.Println(got)
Expand Down Expand Up @@ -1229,10 +1229,9 @@ var (
sgx_extensions_short = []byte{0x30, 0x1E, 0x06, 0x0A, 0x2A, 0x86, 0x48, 0x86, 0xF8, 0x4D, 0x01, 0x0D, 0x01, 0x01, 0x04, 0x10, 0x68, 0x7F, 0x27, 0x16, 0xC8, 0xB5, 0x33, 0xAE, 0x4F, 0x4A, 0x44, 0x2C, 0x07, 0x9D, 0xB2, 0x04}
sgx_extensions, _ = hex.DecodeString("301E060A2A864886F84D010D01010410687F2716C8B533AE4F4A442C079DB20430820163060A2A864886F84D010D0102308201533010060B2A864886F84D010D0102010201073010060B2A864886F84D010D0102020201073010060B2A864886F84D010D0102030201003010060B2A864886F84D010D0102040201003010060B2A864886F84D010D0102050201003010060B2A864886F84D010D0102060201003010060B2A864886F84D010D0102070201003010060B2A864886F84D010D0102080201003010060B2A864886F84D010D0102090201003010060B2A864886F84D010D01020A0201003010060B2A864886F84D010D01020B0201003010060B2A864886F84D010D01020C0201003010060B2A864886F84D010D01020D0201003010060B2A864886F84D010D01020E0201003010060B2A864886F84D010D01020F0201003010060B2A864886F84D010D0102100201003010060B2A864886F84D010D01021102010D301F060B2A864886F84D010D0102120410070700000000000000000000000000003010060A2A864886F84D010D0103040200003014060A2A864886F84D010D0104040600706A100000300F060A2A864886F84D010D01050A0100")
validSGXVersion uint16 = 0x03
//validSGXAttributes [16]byte = [16]byte{0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
validIsvProdId uint16 = 0x00
validIsvSvn uint16 = 0
validMRSIGNER = "37E0543F5597B0F0E028FA18955E1307CB7A8CF54B37F513FF64961EADEF94C4"
validIsvProdId uint16 = 0x00
validIsvSvn uint16 = 0
validMRSIGNER = "37E0543F5597B0F0E028FA18955E1307CB7A8CF54B37F513FF64961EADEF94C4"

// old/invalid values
tcb_info_old = []byte(`{"tcbInfo":{"id":"SGX","version":3,"issueDate":"2023-05-20T23:45:45Z","nextUpdate":"2023-06-19T23:45:45Z","fmspc":"00706A100000","pceId":"0000","tcbType":0,"tcbEvaluationDataNumber":15,"tcbLevels":[{"tcb":{"sgxtcbcomponents":[{"svn":8},{"svn":8},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":13},"tcbDate":"2023-02-15T00:00:00Z","tcbStatus":"UpToDate"},{"tcb":{"sgxtcbcomponents":[{"svn":7},{"svn":7},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":13},"tcbDate":"2022-11-09T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00657","INTEL-SA-00767"]},{"tcb":{"sgxtcbcomponents":[{"svn":5},{"svn":5},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":11},"tcbDate":"2021-11-10T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00617","INTEL-SA-00657","INTEL-SA-00767"]},{"tcb":{"sgxtcbcomponents":[{"svn":4},{"svn":4},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":11},"tcbDate":"2021-06-09T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00528","INTEL-SA-00617","INTEL-SA-00657","INTEL-SA-00767"]},{"tcb":{"sgxtcbcomponents":[{"svn":3},{"svn":3},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":10},"tcbDate":"2020-11-11T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00465","INTEL-SA-00477","INTEL-SA-00528","INTEL-SA-00617","INTEL-SA-00657","INTEL-SA-00767"]},{"tcb":{"sgxtcbcomponents":[{"svn":2},{"svn":2},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":9},"tcbDate":"2020-06-10T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00381","INTEL-SA-00389","INTEL-SA-00465","INTEL-SA-00477","INTEL-SA-00528","INTEL-SA-00617","INTEL-SA-00657","INTEL-SA-00767"]},{"tcb":{"sgxtcbcomponents":[{"svn":2},{"svn":2},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":7},"tcbDate":"2019-05-15T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00220","INTEL-SA-00270","INTEL-SA-00293","INTEL-SA-00381","INTEL-SA-00389","INTEL-SA-00465","INTEL-SA-00477","INTEL-SA-00528","INTEL-SA-00617","INTEL-SA-00657","INTEL-SA-00767"]},{"tcb":{"sgxtcbcomponents":[{"svn":2},{"svn":2},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":6},"tcbDate":"2018-08-15T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00203","INTEL-SA-00220","INTEL-SA-00270","INTEL-SA-00293","INTEL-SA-00381","INTEL-SA-00389","INTEL-SA-00465","INTEL-SA-00477","INTEL-SA-00528","INTEL-SA-00617","INTEL-SA-00657","INTEL-SA-00767"]},{"tcb":{"sgxtcbcomponents":[{"svn":1},{"svn":1},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":5},"tcbDate":"2018-01-04T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00106","INTEL-SA-00115","INTEL-SA-00135","INTEL-SA-00203","INTEL-SA-00220","INTEL-SA-00270","INTEL-SA-00293","INTEL-SA-00381","INTEL-SA-00389","INTEL-SA-00465","INTEL-SA-00477","INTEL-SA-00528","INTEL-SA-00617","INTEL-SA-00657","INTEL-SA-00767"]},{"tcb":{"sgxtcbcomponents":[{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0},{"svn":0}],"pcesvn":4},"tcbDate":"2017-07-26T00:00:00Z","tcbStatus":"OutOfDate","advisoryIDs":["INTEL-SA-00088","INTEL-SA-00106","INTEL-SA-00115","INTEL-SA-00135","INTEL-SA-00203","INTEL-SA-00220","INTEL-SA-00270","INTEL-SA-00293","INTEL-SA-00381","INTEL-SA-00389","INTEL-SA-00465","INTEL-SA-00477","INTEL-SA-00528","INTEL-SA-00617","INTEL-SA-00657","INTEL-SA-00767"]}]},"signature":"0f0dcda69af0014b69e2af1a826d5cf5caee7fdcac2ec10740d7b6caedf04871005976e4cc0803bc50e824fb23c82b21078da45d867c30925a56e6d23fe53119"}`)
Expand Down
2 changes: 1 addition & 1 deletion attestationreport/tdx.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ func verifyTdxMeasurements(tdxM Measurement, nonce []byte, intelCache string, re
}

// Parse and verify PCK certificate extensions
sgxExtensions, err := parseSGXExtensions(quoteCerts.PCKCert.Extensions[SGX_EXTENSION_INDEX].Value[4:]) // skip the first value (not relevant)
sgxExtensions, err := ParseSGXExtensions(quoteCerts.PCKCert.Extensions[SGX_EXTENSION_INDEX].Value[4:]) // skip the first value (not relevant)
if err != nil {
log.Tracef("failed to parse SGX Extensions from PCK Certificate: %v", err)
result.Summary.SetErr(ParseCert)
Expand Down
25 changes: 25 additions & 0 deletions cmc/sgx.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Copyright (c) 2021 Fraunhofer AISEC
// Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build !nodefaults || sgx

package cmc

import "github.com/Fraunhofer-AISEC/cmc/sgxdriver"

func init() {
log.Info("Adding SGX driver to supported drivers")
drivers["sgx"] = &sgxdriver.Sgx{}
}
6 changes: 6 additions & 0 deletions doc/Architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ The *snpdriver* interfaces with the AMD SEV-SNP SP. It retrieves SNP measurement
an SNP attestation report as well as the certificate chain for this attestation report from the
respective AMD servers. Currently, it can only act as *Measurement* interface.

__sgxdriver:__
The *sgxdriver* interfaces with the Intel SGX CPU. It retrieves SGX measurements in the form of an SGX attestation report signed by the SGX quoting enclave. It implements a small caching mechanism to fetch and store the certificate chain used for report verification from the Intel SGX API. Currently, the driver only acts as a *Measurement* interface.

__tdxdriver:__
*Will be implemented as soon as Intel TDX hardware is available.*

__swdriver:__
The *swdriver* simply creates keys in software for testing purposes and can be used as *Signer*
interface. **Note**: This should mainly be used for testing purposes.
Expand Down
Loading
Loading