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:

  1. Inspect the source code that performs the computation to confirm that it indeed hashes 100 million times, starting with the string “Hello World!”.

  2. Verify that the MRENCLAVE of the remote attestation verification report matches the MRENCLAVE 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
_images/sgx-hashmachine-match.png

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
_images/sgx-hashmachine-failure.png

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:

  1. Creates an elliptic curve key pair and saves it to disk.

  2. Simulates uploading the public key to a cloud.

  3. Signs some “sensor data.”

  4. Simulates uploading the sensor data and signature to a cloud.

  5. 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:

  1. In an SGX enclave: create an elliptic curve key pair, seal the private key and save sealed blob to disk.

  2. Simulate uploading the public key to a cloud.

  3. In an SGX enclave: unseals the private key, and sign some “sensor data.”

  4. Simulate uploading the sensor data and signature to a cloud.

  5. 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.