Skip to content

Added KSS features support including Config ID/SVN #2101

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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
4 changes: 4 additions & 0 deletions CI-Examples/python/python.manifest.template
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }}
sgx.enclave_size = "1G"
sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '32' }}

sgx.kss = true
sgx.isvfamilyid = "0x00112233445566778899aabbccddeeff"
sgx.isvextprodid = "0xcafef00dcafef00df00dcafef00dcafe"

sgx.remote_attestation = "{{ ra_type }}"

sgx.trusted_files = [
Expand Down
5 changes: 5 additions & 0 deletions CI-Examples/python/scripts/sgx-quote.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,16 @@
quote = f.read()

print(f"Extracted SGX quote with size = {len(quote)} and the following fields:")
print(f" ISVEXTPRODID: {quote[80:96].hex()}")
print(f" ATTRIBUTES.FLAGS: {quote[96:104].hex()} [ Debug bit: {quote[96] & 2 > 0} ]")
print(f" ATTRIBUTES.XFRM: {quote[104:112].hex()}")
print(f" MRENCLAVE: {quote[112:144].hex()}")
print(f" MRSIGNER: {quote[176:208].hex()}")
print(f" CONFIGID: {quote[240:272].hex()}")
print(f" {quote[272:304].hex()}")
print(f" ISVPRODID: {quote[304:306].hex()}")
print(f" ISVSVN: {quote[306:308].hex()}")
print(f" CONFIGSVN: {quote[308:310].hex()}")
print(f" ISVFAMILYID: {quote[352:368].hex()}")
print(f" REPORTDATA: {quote[368:400].hex()}")
print(f" {quote[400:432].hex()}")
5 changes: 5 additions & 0 deletions CI-Examples/python/scripts/sgx-report.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,16 @@
report = f.read()

print(f"Generated SGX report with size = {len(report)} and the following fields:")
print(f" ISVEXTPRODID: {report[32:48].hex()}")
print(f" ATTRIBUTES.FLAGS: {report[48:56].hex()} [ Debug bit: {report[48] & 2 > 0} ]")
print(f" ATTRIBUTES.XFRM: {report[56:64].hex()}")
print(f" MRENCLAVE: {report[64:96].hex()}")
print(f" MRSIGNER: {report[128:160].hex()}")
print(f" CONFIGID: {report[192:224].hex()}")
print(f" {report[224:256].hex()}")
print(f" ISVPRODID: {report[256:258].hex()}")
print(f" ISVSVN: {report[258:260].hex()}")
print(f" CONFIGSVN: {report[260:262].hex()}")
print(f" ISVFAMILYID: {report[304:320].hex()}")
print(f" REPORTDATA: {report[320:352].hex()}")
print(f" {report[352:384].hex()}")
7 changes: 7 additions & 0 deletions CI-Examples/ra-tls-mbedtls-with-kss/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*.tar.gz
/OUTPUT
/client
/mbedtls
/server
/ssl/ca.*
/ssl/server.*
111 changes: 111 additions & 0 deletions CI-Examples/ra-tls-mbedtls-with-kss/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# Copyright (C) 2023 Gramine contributors
# SPDX-License-Identifier: BSD-3-Clause

ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine)

ifeq ($(DEBUG),1)
GRAMINE_LOG_LEVEL = debug
CFLAGS += -O0 -ggdb3
else
GRAMINE_LOG_LEVEL = error
CFLAGS += -O2
endif

CFLAGS += -fPIE
LDFLAGS += -pie

.PHONY: all
all: app dcap

.PHONY: app
app: ssl/server.crt server.manifest.sgx server.sig client

.PHONY: dcap
dcap: client_dcap.manifest.sgx client_dcap.sig

############################# SSL DATA DEPENDENCY #############################

# SSL data: key and x.509 self-signed certificate
ssl/server.crt: ssl/ca_config.conf
openssl genrsa -out ssl/ca.key 2048
openssl req -x509 -new -nodes -key ssl/ca.key -sha256 -days 1024 -out ssl/ca.crt -config ssl/ca_config.conf
openssl genrsa -out ssl/server.key 2048
openssl req -new -key ssl/server.key -out ssl/server.csr -config ssl/ca_config.conf
openssl x509 -req -days 360 -in ssl/server.csr -CA ssl/ca.crt -CAkey ssl/ca.key -CAcreateserial -out ssl/server.crt

######################### CLIENT/SERVER EXECUTABLES ###########################

CFLAGS += $(shell pkg-config --cflags mbedtls_gramine) \
$(shell pkg-config --cflags ra_tls_gramine)

# no need for `pkg-config --libs ra_tls_gramine` because programs use dlopen
LDFLAGS += -ldl -Wl,--enable-new-dtags $(shell pkg-config --libs mbedtls_gramine)

server: src/server.c
$(CC) $< $(CFLAGS) $(LDFLAGS) -o $@

client: src/client.c
$(CC) $< $(CFLAGS) $(LDFLAGS) -o $@

############################### SERVER MANIFEST ###############################

server.manifest: server.manifest.template server
gramine-manifest \
-Dlog_level=$(GRAMINE_LOG_LEVEL) \
-Darch_libdir=$(ARCH_LIBDIR) \
$< > $@

server.manifest.sgx server.sig &: server.manifest
gramine-sgx-sign \
--manifest $< \
--output $<.sgx

########################### CLIENT (DCAP) MANIFEST ############################

client_dcap.manifest: client.manifest.template client
gramine-manifest \
-Dlog_level=$(GRAMINE_LOG_LEVEL) \
-Darch_libdir=$(ARCH_LIBDIR) \
$< >$@

client_dcap.manifest.sgx client_dcap.sig: sgx_sign_client_dcap
@:

.INTERMEDIATE: sgx_sign_client_dcap
sgx_sign_client_dcap: client_dcap.manifest
gramine-sgx-sign \
--manifest $< \
--output $<.sgx

############################### SGX CHECKS FOR CI #############################

.PHONY: check_dcap
check_dcap: app dcap
gramine-sgx server >/dev/null & SERVER_ID=$$!; \
../../scripts/wait_for_server 60 127.0.0.1 4433; \
./client dcap | tee OUTPUT; \
./client dcap 0 0 0 0 | tee -a OUTPUT; \
kill -9 $$SERVER_ID
@grep -q "using default SGX-measurement verification callback" OUTPUT && echo "[ Success 1/4 ]"
@grep -q "using our own SGX-measurement verification callback" OUTPUT && echo "[ Success 2/4 ]"
@grep -q "Verifying peer X.509 certificate... ok" OUTPUT && echo "[ Success 3/4 ]"
@(exit `grep -c "failed" "OUTPUT"`) && echo "[ Success 4/4 ]"
@rm OUTPUT

.PHONY: check_dcap_fail
check_dcap_fail: app dcap
gramine-sgx server --test-malicious-quote >/dev/null & SERVER_ID=$$!; \
../../scripts/wait_for_server 60 127.0.0.1 4433; \
./client dcap && exit 1 || echo "[ Success 1/1 ]"; \
kill -9 $$SERVER_ID

################################## CLEANUP ####################################

.PHONY: clean
clean:
$(RM) -r \
*.sig *.manifest.sgx *.manifest server client *.so *.so.* OUTPUT

.PHONY: distclean
distclean: clean
$(RM) -r ssl/ca.* ssl/server.*
197 changes: 197 additions & 0 deletions CI-Examples/ra-tls-mbedtls-with-kss/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# RA-TLS Minimal Example

This directory contains the Makefile, the template server manifest, and the
minimal server and client written against the mbedTLS library.

The server and client are based on `ssl_server.c` and `ssl_client1.c` example
programs shipped with mbedTLS. We modified them to allow using RA-TLS flows. In
particular, the server uses a self-signed RA-TLS cert with the SGX quote
embedded in it via `ra_tls_create_key_and_crt_der()`. The client uses an RA-TLS
verification callback to verify the server RA-TLS certificate via
`ra_tls_verify_callback_der()`.

This example uses the RA-TLS libraries `ra_tls_attest.so` for server and
`ra_tls_verify_dcap.so` for client. These libraries are installed together with
Gramine (you need `meson setup ... -Ddcap=enabled`, which is the default). The
DCAP software infrastructure must be installed and work correctly on the host.

For more documentation about ECDSA (DCAP) remote attestation scheme, refer to
https://gramine.readthedocs.io/en/stable/attestation.html.

## RA-TLS server

The server is supposed to run in the SGX enclave with Gramine and RA-TLS
dlopen-loaded. If the server is started not in the SGX enclave, then it falls
back to using normal X.509 PKI flows.

If server is run with a command-line argument ``--test-malicious-quote``, then
the server will maliciously modify the SGX quote before sending to the client.
This is useful for testing purposes.

## RA-TLS client

The client is supposed to run on a trusted machine (*not* in an SGX enclave).
If RA-TLS library `ra_tls_verify_dcap.so` is not requested by user via `dcap`
command-line argument respectively, the client falls back to using normal X.509
PKI flows (specified as `native` command-line argument).

It is also possible to run the client in an SGX enclave. This will create a
secure channel between two Gramine SGX processes, possibly running on different
machines. It can be used as an example of in-enclave remote attestation and
verification.

If client is run without additional command-line arguments, it uses default
RA-TLS verification callback that compares `MRENCLAVE`, `MRSIGNER`,
`ISV_PROD_ID` and `ISV_SVN` against the corresonding `RA_TLS_*` environment
variables. `MRENCLAVE`, `MRSIGNER` and `ISV_PROD_ID` are expected to match
`RA_TLS_*` ones. `ISV_SVN` is expected to be equal or greater than `RA_TLS_ISV_SVN`.
To run the client with its own verification callback, execute it with four
additional command-line arguments (see the source code for details).

Also, because this example builds and uses debug SGX enclaves (`sgx.debug` is
set to `true`), we use environment variable `RA_TLS_ALLOW_DEBUG_ENCLAVE_INSECURE=1`.
Note that in production environments, you must *not* use this option!

Moreover, we set `RA_TLS_ALLOW_OUTDATED_TCB_INSECURE=1`,
`RA_TLS_ALLOW_HW_CONFIG_NEEDED=1` and `RA_TLS_ALLOW_SW_HARDENING_NEEDED=1` to
allow performing the tests when some of Intel's security advisories haven't been
addressed (for example, when the microcode or architectural enclaves aren't
fully up-to-date). Note that in production environments, you must carefully
analyze whether to use these options!

## KSS features
In addition to the existing ra-tls example, this example shows the use of the following four values
provided by the Key Separation and Sharing (KSS) feature of SGX:
* ISV Extended Production ID (ISV_EXT_PROD_ID)
* ISV Family ID (ISV_FAMILY_ID)
* Config ID (CONFIG_ID)
* Config SVN (CONFIG_SVN)

The KSS enable, ISV_EXT_PROD_ID and ISV_FAMILY_ID of the server enclave are specified
in the manifest (`sgx.kss`, `sgx.isvextprodid` and `sgx.isvfamilyid`),
while the CONFIG_ID and CONFIG_SVN are specified via command line arguments or
environment variables when executing the `gramine-sgx` command.

These values cannot be used when running under non-SGX conditions.

# Quick Start

In most of the examples below, you need to tell the client what values it should
expect for `MRENCLAVE`, `MRSIGNER`, `ISV_PROD_ID` and `ISV_SVN`. One way to
obtain them is to run `gramine-sgx-sigstruct-view server.sig`.

For all examples, we set the following environment variables:
```sh
export RA_TLS_ALLOW_DEBUG_ENCLAVE_INSECURE=1
export RA_TLS_ALLOW_OUTDATED_TCB_INSECURE=1
export RA_TLS_ALLOW_HW_CONFIG_NEEDED=1
export RA_TLS_ALLOW_SW_HARDENING_NEEDED=1
```

- Normal non-RA-TLS flows; without SGX and without Gramine:

```sh
make app
./server &
./client native
# client will successfully connect to the server via normal x.509 PKI flows
kill %%
```

- RA-TLS flows with SGX and with Gramine, ECDSA-based (DCAP) attestation:

```sh
make clean
make app dcap

gramine-sgx --config-id=<CONFIG_ID to set to the server enclave> \
--config-svn=<CONFIG_SVN to set to the server enclave> \
./server &

RA_TLS_MRENCLAVE=<MRENCLAVE of the server enclave> \
RA_TLS_MRSIGNER=<MRSIGNER of the server enclave> \
RA_TLS_ISV_PROD_ID=<ISV_PROD_ID of the server enclave> \
RA_TLS_ISV_SVN=<ISV_SVN of the server enclave> \
RA_TLS_ISV_EXT_PROD_ID=<ISV_EXT_PROD_ID of the server enclave> \
RA_TLS_ISV_FAMILY_ID=<ISV_FAMILY_ID of the server enclave> \
RA_TLS_CONFIG_ID=<CONFIG_ID of the server enclave> \
RA_TLS_CONFIG_SVN=<CONFIG_SVN of the server enclave> \
./client dcap

# client will successfully connect to the server via RA-TLS/DCAP flows
kill %%
```

The environment variables SGX_CONFIG_ID and SGX_CONFIG_SVN can also be used to specify
the Config ID and Config SVN.
If both command line arguments and environment variables are specified,
an error is returned if those values do not match.

``` sh
SGX_CONFIG_ID=<CONFIG_ID to set to the server enclave> \
SGX_CONFIG_SVN=<CONFIG_SVN to set to the server enclave> \
gramine-sgx ./server
```

- RA-TLS flows with SGX and with Gramine, client with its own verification callback:

```sh
make clean
make app dcap

gramine-sgx --config-id=<CONFIG_ID to set to the server enclave> \
--config-svn=<CONFIG_SVN to set to the server enclave> \
./server &

./client dcap \
<MRENCLAVE of the server enclave> \
<MRSIGNER of the server enclave> \
<ISV_PROD_ID of the server enclave> \
<ISV_SVN of the server enclave> \
<ISV_EXT_PROD_ID of the server enclave> \
<ISV_FAMILY_ID of the server enclave> \
<CONFIG_ID of the server enclave> \
<CONFIG_SVN of the server enclave>

# client will successfully connect to the server via RA-TLS/DCAP flows
kill %%
```

Note that the Config ID must be specified as a hexadecimal string and the Config SVN as a decimal number.

- RA-TLS flows with SGX and with Gramine, server sends malicious SGX quote:

```sh
make clean
make app dcap

gramine-sgx ./server --test-malicious-quote &
./client dcap

# client will fail to verify the malicious SGX quote and will *not* connect to the server
kill %%
```

- RA-TLS flows with SGX and with Gramine, running DCAP client in SGX:

```sh
make clean
make app dcap

gramine-sgx --config-id=<CONFIG_ID to set to the server enclave> \
--config-svn=<CONFIG_SVN to set to the server enclave> \
./server &

gramine-sgx ./client_dcap dcap \
<MRENCLAVE of the server enclave> \
<MRSIGNER of the server enclave> \
<ISV_PROD_ID of the server enclave> \
<ISV_SVN of the server enclave> \
<ISV_EXT_PROD_ID of the server enclave> \
<ISV_FAMILY_ID of the server enclave> \
<CONFIG_ID of the server enclave> \
<CONFIG_SVN of the server enclave>

# client will successfully connect to the server via RA-TLS/DCAP flows
kill %%
```
Loading