Examples¶
This section presents examples which can be followed through to see how the
auditee
tool can be used. Each example contains the source code of an
enclave application, which for the sake of demonstration could be seen as
being under audit. One could imagine that an auditing party would inspect the
source code of the enclave to verify that it meets a set of requirements with
respect to security, functionalities, etc. In addition to the source code,
each example contains a pre-built and signed enclave binary, usually named
Enclave.signed.so
, and a remote attestation verification report from
Intel’s attestation service (IAS). In these examples, the IAS report is in a
json file, usually named ias_report.json
, which also contains Intel’s
signature and certificate necessary to verify the authenticity of the report.
To sum up, an example contains the following pieces of information:
enclave source code
pre-built signed enclave binary (
Enclave.signed.so
)remote attestation report verified by Intel (
ias_report.json
)
A remote attestation report can contain application and/or user specific data
in a field named REPORT_DATA
. This report data is added by the enclave
code at the time a quote is generated. Each example presented in this
documentation will attempt to show a different usage of this REPORT_DATA
field.
Prerequisites¶
To follow through the examples as they are presented it’s best that you have recent versions of docker and docker-compose.
Clone the repository:
$ git clone --recurse-submodules https://github.com/initc3/auditee.git
SGX Hash Machine¶
Let’s imagine Alice claims that the hexadecimal string
fceb63059b60138e03a7d6edf6ccb1d942d9165c2812ba926b0fbb0c729eae97
is the result of having computed the SHA 256 hash 100 million times, starting
with the string "Hello World!"
, and repeatedly hashing the new result of
each iteration. For instance, in Python:
from hashlib import sha256
from time import time
s = b'Hello World!'
begin = time()
for _ in range(1000000000):
s = sha256(s).digest()
end = time()
print(f'time to compute: {end - begin}')
print(f'computed value: {s}')
You could perform the computation yourself, using the above code snippet, to verify the claim. This may take a minute or so. But if the number of iterations was larger, say one trillion, it could take a couple of days … What if the computation took a month, a year? So let’s say that for whatever reason you do not want or cannot perform the computation yourself.
Could you be convinced in another way that the claim is true?
The goal of this example is to show that, if you trust Intel, then you could indeed be convinced that the claim is true. That is, presented with a remote attestation verification report, which contains the result of the computation, we’ll verify whether this report “matches” source code that does perform the 100 million-times hashing computation over “Hello World!”.
To convince yourself that the claim is true, we’ll go through the following steps:
Inspect the source code that performs the computation to confirm that it indeed hashes 100 million times, starting with the string “Hello World!”.
Verify that the
MRENCLAVE
of the remote attestation verification report matches theMRENCLAVE
from an enclave binary built from the above source code.
Todo
The authenticity of the remote attestation verification report MUST be verified to make sure the report does indeed come from Intel.
STEP 1: Inspect the source code¶
Go into the directory examples/hashmachine/sgx-hashmachine/Enclave
and
open the file Enclave.cpp
… check that the number of iterations is
indeed 100 million (100000000) and that the initial string is “Hello World!”.
sgx_status_t get_report(sgx_report_t *report, sgx_target_info_t *target_info) {
sgx_report_data_t report_data = {{0}};
// Hardcoded "Hello World!" string in hexadecimal format
const uint8_t x[] = {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20,
0x57, 0x6f, 0x72, 0x6c, 0x64, 0x21};
int iterations = 100000000;
sgx_status_t sha_ret;
sgx_sha256_hash_t tmp_hash;
sha_ret = sgx_sha256_msg(x, sizeof(x), (sgx_sha256_hash_t *)tmp_hash);
for (int i = 1; i < iterations - 1; i++) {
sha_ret = sgx_sha256_msg((const uint8_t *)&tmp_hash, sizeof(tmp_hash),
(sgx_sha256_hash_t *)tmp_hash);
}
sha_ret = sgx_sha256_msg((const uint8_t *)&tmp_hash, sizeof(tmp_hash),
(sgx_sha256_hash_t *)&report_data);
return sgx_create_report(target_info, &report_data, report);
}
In this example, the enclave code computes the hash (SHA 256) 100 million
times, starting with the string "Hello World!"
and puts the result in the
REPORT_DATA
of a quote (attestation report) that can be sent to Intel for
verification. The function get_report()
is an ECALL that can be
invoked by untrusted code. The important thing to note is that if the enclave
works as it should, the untrusted part of the system cannot modify the code
of get_report()
when it’s executed. Remote attestation can
provide a proof that the above get_report()
code was indeed
executed on a genuine SGX-enabled CPU.
STEP 2: MRENCLAVEs Comparison¶
Under the directory examples/hashmachine
there’s a file named
ias_report.json
. This file contains a remote attestation verification
report that was received from Intel’s Attestation Service (IAS). The
report contains the MRENCLAVE
of the enclave that was attested and a
REPORT_DATA
value. The REPORT_DATA
contains the hash that we care
about, meanwhile the MRENCLAVE
should match that of an enclave binary
built from the source code we inspected in :ref:`step1`_. To compare the two
MRENCLAVEs
we can use the auditee
tool which automates the multiple
steps required, such as building the enclave binary, extracting its
MRENCLAVE
, and parsing the report for its MRENCLAVE
.
From the root of the project, spin up a container:
$ docker-compose run --rm auditee bash
Go into the directory of the sgx-hash
example:
root@f07e2606a418:/usr/src# cd examples/hashmachine/
Start an ipython session:
root@f07e2606a418:/usr/src/examples/hashmachine# ipython
Use the auditee.verify_mrenclave()
function to verify that the
MRENCLAVE
from the enclave binary that was built from source matches the
MRENCLAVE
in the remote attestation report. Recall that the report
confirms, as per Intel, that the code with the specified MRENCLAVE
, was
loaded into a protected area of memory of a genuine Intel SGX processor, which
in turn, more or less confirms that the code that it executes has not been
tampered with.
import auditee
auditee.verify_mrenclave(
'sgx-hashmachine/',
'Enclave.signed.so',
ias_report='ias_report.json',
)
Reproducibility Report
----------------------
- Signed enclave MRENCLAVE: 15e1be2fb364d081cf764c25ffd462e07827c75f45877bbcc441a9b3fb240d9c
- Built-from-source enclave MRENCLAVE: 15e1be2fb364d081cf764c25ffd462e07827c75f45877bbcc441a9b3fb240d9c
- IAS report MRENCLAVE: 15e1be2fb364d081cf764c25ffd462e07827c75f45877bbcc441a9b3fb240d9c
MRENCLAVES match!
Report data
-----------
The following REPORT DATA contained in the remote attestation verification report CAN be trusted.
fceb63059b60138e03a7d6edf6ccb1d942d9165c2812ba926b0fbb0c729eae970000000000000000000000000000000000000000000000000000000000000000
>>> True
Example of MRENCLAVE mismatch:
Reproducibility Report
----------------------
- Signed enclave MRENCLAVE: 46eba17f7432c6939e58f7fd47130a8ec5ef87eb270bac0a641a5c66b36e6231
- Built-from-source enclave MRENCLAVE: 43aba22d286f8daab8ef3c7c0791c85e67a2fdb3c0fd152905deac7b8dfa88f8
- IAS report MRENCLAVE: 46eba17f7432c6939e58f7fd47130a8ec5ef87eb270bac0a641a5c66b36e6231
MRENCLAVES do not match!
Report data
-----------
The following REPORT DATA contained in the remote attestation verification report CANNOT be trusted.
fceb63059b60138e03a7d6edf6ccb1d942d9165c2812ba926b0fbb0c729eae970000000000000000000000000000000000000000000000000000000000000000
>>> False
Remote Attestation Report¶
If you wonder how to get the remote attestation report, consult https://github.com/sbellem/sgx-hashmachine#quickstart.
SGX IoT Gateway¶
This example is based on an Intel Code Sample Gateway Key Provisioning and Secure Signing using Intel® Software Guard Extensions
One issue that may arise in IoT scenarios involving sensor data is the trustworthiness of the data. For example, are the sensor readings authentic and integrity-protected? One way to provide integrity protection and prove authenticity is to use an IoT gateway at the edge to digitally sign the captured data, but then the validity of the digital signatures become dependent upon the uniqueness and confidentiality of the private key. This code sample demonstrates the use of Intel® Software Guard Extensions (Intel® SGX) to protect the private key of an asymmetric elliptic curve keypair used to sign sensor data collected at the edge.
The baseline implementation of gateway key provisioning and secure signing is built with OpenSSL. The run_demo_openssl.sh script performs the following actions:
Creates an elliptic curve key pair and saves it to disk.
Simulates uploading the public key to a cloud.
Signs some “sensor data.”
Simulates uploading the sensor data and signature to a cloud.
Simulated cloud verifies the sensor data and detached signature.
The SGX-based original implementation improves the security of the above by generating the key pair in an enclave and sealing the private key, and storing it on disk. That is:
In an SGX enclave: create an elliptic curve key pair, seal the private key and save sealed blob to disk.
Simulate uploading the public key to a cloud.
In an SGX enclave: unseals the private key, and sign some “sensor data.”
Simulate uploading the sensor data and signature to a cloud.
Simulated cloud verifies the sensor data and detached signature.
In step 2 above, how can one be certain that the correct public key is uploaded to the cloud?
Note
In this modified example, remote attestation is used to prove that the enclave is genuine and moreover to prove that the public key comes from the an enclave that was built from a trusted source code.
Quickstart¶
To try, spin up a container from the root of the repository:
docker-compose run --rm auditee bash
Go under the examples/iot
directory:
cd examples/iot-gateway
Start an ipython
session:
ipython
Verify that the verified remote attestation report contains the “trusted” MRENCLAVE,
which corresponds to the trusted source code. The signed enclave binary (.so
file)
may be considered optional, but could also be useful in some cases. For instance, a
developer or service could build the enclave and sign it, meanwhile another service,
before deploying the enclave, would want to verify that it matches the source code,
(and possibly a previous attestation (?)).
import auditee
auditee.verify_mrenclave(
"sgx-iot/",
"enclave.signed.so",
ias_report="ias_report.json",
)
# ...
Reproducibility Report
----------------------
- Signed enclave MRENCLAVE: 4985c91b6a9cf7a4d56384d25ed9008d9be7f61fa108e4e2669247b11acc013f
- Built-from-source enclave MRENCLAVE: 4985c91b6a9cf7a4d56384d25ed9008d9be7f61fa108e4e2669247b11acc013f
- IAS report MRENCLAVE: 4985c91b6a9cf7a4d56384d25ed9008d9be7f61fa108e4e2669247b11acc013f
MRENCLAVES match!
Report data
-----------
The following REPORT DATA contained in the remote attestation verification report CAN be trusted.
bb7e7fc78e1fce2053a7d87bc7ee4bb5cd6997534529c0ce1fcbb9bc0db8dee9b0aed3032e9304dd9400b1cf177ecca680947201850ae0cd11b0f23f3495cbf7
Out[1]: True
Todo
Show how to verify the signature of the sensor data, using the public key in the report data.
A complete demo which involves:
building the enclave
generating a quote
sending it to Intel for verification
extracting the public key from the report
verifying the signature
can be found under https://github.com/sbellem/sgx-iot#quickstart. Note that this demo requires an SGX-enabled processor. Unsure if you do? See https://github.com/ayeks/SGX-hardware#test-sgx.