Skip to content

Commit

Permalink
Merge pull request #53 from dreemkiller/nitro_enclaves
Browse files Browse the repository at this point in the history
Add support for Nitro enclaves
  • Loading branch information
dominic-mulligan-arm authored Jan 29, 2021
2 parents 28c4f7c + 836e78d commit 5090a11
Show file tree
Hide file tree
Showing 62 changed files with 3,792 additions and 155 deletions.
45 changes: 45 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ OPTEE_DIR_SDK ?= /work/rust-optee-trustzone-sdk/
AARCH64_OPENSSL_DIR ?= /work/rust-optee-trustzone-sdk/optee-qemuv8-3.7.0/build/openssl-1.0.2s/
AARCH64_GCC ?= $(OPTEE_DIR)/toolchains/aarch64/bin/aarch64-linux-gnu-gcc
SGX_RUST_FLAG ?= "-L/work/sgxsdk/lib64 -L/work/sgxsdk/sdk_libs"
NITRO_RUST_FLAG ?= ""

all:
@echo $(WARNING_COLOR)"Please explicitly choose a target."$(RESET_COLOR)
Expand Down Expand Up @@ -46,6 +47,12 @@ sgx: sdk sgx-env
cd sonora-bind && RUSTFLAGS=$(SGX_RUST_FLAG) cargo build
cd durango && RUSTFLAGS=$(SGX_RUST_FLAG) cargo build --lib --features sgx

nitro: sdk
pwd
RUSTFLAGS=$(NITRO_RUST_FLAG) $(MAKE) -C mexico-city nitro
RUSTFLAGS=$(NITRO_RUST_FLAG) $(MAKE) -C nitro-root-enclave
RUSTFLAGS=$(NITRO_RUST_FLAG) $(MAKE) -C nitro-root-enclave-server

# Compile for trustzone, note: source the rust-optee-trustzone-sdk/environment first, however assume `unset CC`.
trustzone: sdk trustzone-env
$(MAKE) -C mexico-city trustzone CC=$(AARCH64_GCC)
Expand Down Expand Up @@ -98,6 +105,42 @@ trustzone-veracruz-test: trustzone test_cases trustzone-test-env
trustzone-test-env: tz_test.sh run_tz_test.sh
chmod u+x $^

nitro-sinaloa-test: nitro test_cases
cd sinaloa-test \
&& RUSTFLAGS=$(NITRO_RUST_FLAG) cargo test --features nitro \
&& RUSTFLAGS=$(NITRO_RUST_FLAG) cargo test test_debug --features nitro,debug -- --ignored --test-threads=1
cd sinaloa-test \
&& ./nitro_terminate.sh
cd ./sinaloa-test \
&& ./nitro_ec2_terminate_root.sh

nitro-sinaloa-test-dry-run: nitro test_cases
cd sinaloa-test \
&& RUSTFLAGS=$(NITRO_RUST_FLAG) cargo test --features sgx --no-run

nitro-sinaloa-performance: nitro test_cases
cd sinaloa-test \
&& RUSTFLAGS=$(NITRO_RUST_FLAG) cargo test test_performance_ --features nitro -- --ignored
cd sinaloa-test \
&& ./nitro_terminate.sh
cd ./sinaloa-test \
&& ./nitro_ec2_terminate_root.sh

nitro-veracruz-test-dry-run: nitro test_cases
cd veracruz-test \
&& RUSTFLAGS=$(SGX_RUST_FLAG) cargo test --features nitro --no-run

nitro-veracruz-test: nitro test_cases
cd veracruz-test \
&& RUSTFLAGS=$(SGX_RUST_FLAG) cargo test --features nitro
cd sinaloa-test \
&& ./nitro_terminate.sh
cd ./sinaloa-test \
&& ./nitro_ec2_terminate_root.sh

nitro-psa-attestation:
cd psa-attestation && cargo build --features nitro

trustzone-env:
unset CC
rustup target add aarch64-unknown-linux-gnu arm-unknown-linux-gnueabihf
Expand All @@ -116,12 +159,14 @@ clean:
cd veracruz-utils && cargo clean
cd sinaloa-test && cargo clean
cd veracruz-test && cargo clean
cd nitro-root-enclave-server && cargo clean
$(MAKE) clean -C mexico-city
$(MAKE) clean -C jalisco
$(MAKE) clean -C sinaloa
$(MAKE) clean -C test-collateral
$(MAKE) clean -C sonora
$(MAKE) clean -C sdk
$(MAKE) clean -C nitro-root-enclave

# NOTE: this target deletes ALL cargo.lock.
clean-cargo-lock:
Expand Down
119 changes: 119 additions & 0 deletions NITRO_INSTRUCTIONS.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Setting up an environment for Veracruz on AWS Nitro Enclaves

Start a standard EC2 instance, with M5.large, x86_64, with a security group that allows port 22 from all IPs, ports 3010 and 9090 from the VPC IPs, with an EBS volume attached (I use 64 GB for that).

Log in to the instance.

Mount the EBS volume (following these instructions: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-using-volumes.html):
```bash
lsblk
sudo file -s /dev/nvme1n1
sudo mkfs -t xfs /dev/nvme1n1
sudo mkdir /ebs_volume
sudo mount /dev/nvme1n1 /ebs_volume/
```

Install some needed packages:
```bash
sudo yum install docker git
sudo yum install openssl11-devel
sudo yum install openssl11
```

Install the AWS CLI tools (source: https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2-linux.html):
```bash
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
```

Following the directions here(https://www.crybit.com/change-default-data-image-directory-docker/), change the location where docker stores images (we do this because the default partition
is too small for the docker images, so we want them stored on the EBS volume):
```bash
sudo systemctl stop docker
sudo mv /var/lib/docker /ebs_volume
sudo ln -s /ebs_volume/docker /var/lib/docker
sudo systemctl start docker
```


Now, get your docker image from wherever (these instructions show it being pulled from AWS ECR - https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html):
```bash
sudo usermod -a -G docker ec2-user
```
logout
log back in


configure your AWS credentials:
```bash
aws configure
```

authenticate to your registry:
```bash
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 768728991925.dkr.ecr.us-east-1.amazonaws.com
```
pull the image:
```bash
docker pull <IMAGE URI>
```


Clone veracruz source:
```bash
git clone https://github.com/veracruz-project/veracruz.git --recursive
```
Now, run the docker container:
```bash
export VERACRUZ_ROOT=<PATH TO VERACRUZ>
docker run -d -v $VERACRUZ_ROOT:/work/veracruz -v $HOME/.cargo/registry:/home/<USERNAME>/.cargo/registry --name veracruz <IMAGE NAME>
```

Now, start a shell in the container:
```bash
docker exec -u dermil01 -it veracruz bash
```

Install the AWS Nitro Enclaves CLI (source: https://docs.aws.amazon.com/enclaves/latest/user/nitro-enclave-cli-install.html) (TODO: This should be done by the docker build process):
```bash
sudo amazon-linux-extras install aws-nitro-enclaves-cli
sudo yum install aws-nitro-enclaves-cli-devel -y
sudo usermod -aG ne ec2-user
```

Configure nitro enclaves (source: From <https://docs.aws.amazon.com/enclaves/latest/user/enclaves-user.pdf> ) (TODO: Find out if this will work from inside a docker container).
Edit `/etc/nitro_enclaves/allocator.yaml` and set cpus = 2, memory to 256MB

preparing the build environment inside the container (TODO: This should be done in the container build process):
install the target x86_64-unknown-linux-musl
```bash
rustup target add x86_64-unknown-linux-musl
```

Veracruz needs the ability to start another EC2 instance from your initial EC2 instance. The following instructions set up this ability.

You need to get the subnet that your initial EC2 instance is on.

The id of this subnet should be set in the environment varialbe AWS_SUBNET.

You need to create a security group that allows ports 3010, 9090 for private IP addresses within the subnet.

You probably also want to allow port 22 form all IPs to enable you to SSH into the instance (if you think you'll want to)

The name of this security group should be set in the environment variable AWS_SECURITY_GROUP_ID

You also need to set up an AWSK public/private key pair. You need the private key in a file on your initial EC2 instance. The path to this private key should be set in the environment variable AWS_PRIVATE_KEY_FILENAME.

The name of this key pair (as known by AWS) should be set in the environment variable AWS_KEY_NAME.

The AWS region that you are running on should be set in the environment variable AWS_REGION.

To do this, it is recommended to set the variables in a file called nitro.env as follows:
```bash
export AWS_KEY_NAME="<VALUE>"
export AWS_PRIVATE_KEY_FILENAME="<VALUE>"
export AWS_SUBNET="<VALUE>"
export AWS_REGION="<VALUE>"
export AWS_SECURITY_GROUP_ID="<VALUE>"
```
1 change: 1 addition & 0 deletions baja/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ description = "TLS endpoint and session management for the trusted Veracruz runt
sgx = ["veracruz-utils/sgx", "sgx_tstd", "sgx_types", "rustls/mesalock_sgx", "webpki/mesalock_sgx", "ring/mesalock_sgx", "webpki-roots/mesalock_sgx"]
# NOTE: turn on the `std` on ring for Error trait
tz = ["veracruz-utils/tz", "webpki/default", "webpki-roots/default", "ring/std", "ring/non_sgx", "optee-utee", "rustls/default"]
nitro = ["ring/std", "ring/non_sgx"]

[dependencies]
rustls = { git = "https://github.com/veracruz-project/rustls.git", branch = "veracruz" }
Expand Down
37 changes: 19 additions & 18 deletions baja/src/baja.rs
Original file line number Diff line number Diff line change
Expand Up @@ -345,26 +345,27 @@ impl Baja {
)
};

// NOTE: this should be randomly generated as below. But this is causing
// temporary problems on TrustZone, so instead of randomly generating
// it, we're using a fixed value for now. This **does not** compromise
// the security of the system in any way.
//
// let mut temp = vec![0; 3];
// let rng = SystemRandom::new();
// rng.fill(&mut temp).map_err(|_| "Error generating random bytes")?;
// It must be a valid DNS name, which must not be all numeric
// so we add an a at the beginning to be sure
// let full_string =
// format!("a{:02x}{:02x}{:02x}", temp[0], temp[1], temp[2]);
// full_string[..7].to_string()

let name = FIXED_SERVER_NAME.to_string();

let name = {
// This should be randomly generated as below. But this is causing
// temporary problems on Trustzone, so instead of randomly generating
// it, we're using a static value for now.
// This does not compromise the security of the system
// TODO
//let mut temp = vec![0; 3];

//let rng = ring::rand::SystemRandom::new();
//rng.fill(&mut temp)
//.map_err(|_| "Error generating random bytes")?;
// It must be a valid DNS name, which must not be all numeric
// so we add an a at the beginning to be sure
//let full_string = format!("a{:02x}{:02x}{:02x}", temp[0], temp[1], temp[2]);
//full_string[..7].to_string()
FIXED_SERVER_NAME.to_string()
};
let server_certificate_buffer = generate_certificate(
name.clone().into_bytes(),
name.as_bytes().to_vec(),
server_private_key.clone(),
server_public_key.clone(),
server_public_key,
&policy,
)?;

Expand Down
1 change: 1 addition & 0 deletions chihuahua/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ default = []
std = ["wasmi/non_sgx", "platform-services/std", "wasmtime", "ring/non_sgx"]
sgx = ["sgx_tstd", "wasmi/mesalock_sgx", "platform-services/sgx", "serde/mesalock_sgx", "typetag/mesalock_sgx", "ring/mesalock_sgx"]
tz = ["platform-services/tz", "wasmi/non_sgx", "ring/non_sgx"]
nitro = ["platform-services/nitro"]

[dependencies]
byteorder = { git = "https://github.com/veracruz-project/byteorder.git", branch = "veracruz" }
Expand Down
6 changes: 3 additions & 3 deletions chihuahua/src/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
//! See the file `LICENSE.markdown` in the Veracruz root directory for licensing
//! and copyright information.
#[cfg(any(feature = "std", feature = "tz"))]
#[cfg(any(feature = "std", feature = "tz", feature = "nitro"))]
use std::sync::Mutex;
#[cfg(feature = "sgx")]
use std::sync::SgxMutex as Mutex;
Expand Down Expand Up @@ -93,7 +93,7 @@ pub fn single_threaded_chihuahua(
}
}
}
#[cfg(any(feature = "tz", feature = "sgx"))]
#[cfg(any(feature = "tz", feature = "sgx", feature = "nitro"))]
{
match strategy {
ExecutionStrategy::Interpretation => {
Expand Down Expand Up @@ -149,7 +149,7 @@ pub fn multi_threaded_chihuahua(
}
}
}
#[cfg(any(feature = "tz", feature = "sgx"))]
#[cfg(any(feature = "tz", feature = "sgx", feature = "nitro"))]
{
match strategy {
ExecutionStrategy::Interpretation => {
Expand Down
10 changes: 6 additions & 4 deletions durango/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ description = "Client code for provisioning secrets into, and otherwise interact
[features]
sgx = ["sgx_types", "sgx_ucrypto", "colima/sgx_attestation"]
tz = []
nitro = []
mock = ["mockall", "mockito"]

[dependencies]
# The cargo patch mechanism does NOT work when we add function into a macro_rules!
rustls = { git = "https://github.com/veracruz-project/rustls.git", branch = "self_signed" }
webpki = "0.21"
webpki-roots = "0.19"
ring = { version = "0.16", features = ["std"] }
rustls = { git = "https://github.com/veracruz-project/rustls.git", branch = "veracruz" }
webpki = { git = "https://github.com/veracruz-project/webpki.git", branch = "veracruz" }

webpki-roots = { git = "https://github.com/veracruz-project/webpki-roots.git", branch = "veracruz"}
ring = { git = "https://github.com/veracruz-project/ring.git", branch = "veracruz"}
reqwest = { version = "0.9", default-features=false }
colima = { path = "../colima" }
base64 = "0.10.1"
Expand Down
11 changes: 10 additions & 1 deletion durango/src/attestation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@
//! See the `LICENSE.markdown` file in the Veracruz root directory for
//! information on licensing and copyright.
use veracruz_utils::EnclavePlatform;

#[cfg(feature = "mock")]
use mockall::{automock, predicate::*};

#[cfg_attr(feature = "mock", automock)]
pub trait Attestation {
fn attestation(
policy: &veracruz_utils::VeracruzPolicy,
target_platform: &EnclavePlatform,
) -> Result<(Vec<u8>, String), DurangoError>;
}

Expand All @@ -33,8 +36,14 @@ impl Attestation for AttestationPSA {
/// Attestation against the global policy
fn attestation(
policy: &veracruz_utils::VeracruzPolicy,
target_platform: &EnclavePlatform,
) -> Result<(Vec<u8>, String), DurangoError> {
let expected_enclave_hash = hex::decode(policy.mexico_city_hash().as_str())?;
let mexico_city_hash = policy.mexico_city_hash(target_platform)
.map_err(|err| {
println!("Did not find mexico city hash for platform in policy:{:?}", err);
err
})?;
let expected_enclave_hash = hex::decode(mexico_city_hash.as_str())?;
Self::attestation_flow(
&policy.tabasco_url().as_str(),
&policy.sinaloa_url().as_str(),
Expand Down
10 changes: 7 additions & 3 deletions durango/src/durango.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use std::{
io::{Read, Write},
str::from_utf8,
};
use veracruz_utils::{VeracruzPolicy, VeracruzRole};
use veracruz_utils::{EnclavePlatform, VeracruzPolicy, VeracruzRole};
use webpki;
use webpki_roots;

Expand Down Expand Up @@ -176,6 +176,7 @@ impl Durango {
client_cert_filename: &str,
client_key_filename: &str,
policy_json: &str,
target_platform: &EnclavePlatform
) -> Result<Durango, DurangoError> {
let policy_hash = hex::encode(ring::digest::digest(
&ring::digest::SHA256,
Expand All @@ -186,10 +187,13 @@ impl Durango {
let client_priv_key = Self::read_private_key(client_key_filename)?;

// check if the certificate is valid
let key_pair = ring::signature::RsaKeyPair::from_der(client_priv_key.0.as_slice())?;
let key_pair = ring::signature::RsaKeyPair::from_der(client_priv_key.0.as_slice())
.map_err(|err| {
DurangoError::RingError(format!("from_der failed:{:?}", err))
})?;
Self::check_certificate_validity(client_cert_filename, key_pair.public_key().as_ref())?;

let (enclave_cert_hash, enclave_name) = AttestationHandler::attestation(&policy)?;
let (enclave_cert_hash, enclave_name) = AttestationHandler::attestation(&policy, target_platform)?;

let policy_ciphersuite_string = policy.ciphersuite().as_str();

Expand Down
6 changes: 2 additions & 4 deletions durango/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@ pub enum DurangoError {
TLSUnspecifiedError,
#[error(display = "Durango: TLSError: invalid cyphersuite {:?}.", _0)]
TLSInvalidCyphersuiteError(std::string::String),
#[error(display = "Durango: RingUnspecifiedError: {:?}.", _0)]
RingUnspecifiedError(#[error(source)] ring::error::Unspecified),
#[error(display = "Durango: RingKeyRejectedError: {:?}.", _0)]
RingKeyRejectedError(#[error(source)] ring::error::KeyRejected),
#[error(display = "Durango: RingError: {:?}", _0)]
RingError(std::string::String),
#[error(display = "Durango: SerdeJsonError: {:?}.", _0)]
SerdeJsonError(#[error(source)] serde_json::error::Error),
#[error(display = "Durango: X509Error: {:?}.", _0)]
Expand Down
Loading

0 comments on commit 5090a11

Please sign in to comment.