Skip to content
This repository has been archived by the owner on Jul 27, 2022. It is now read-only.

Problem: deprecated enclave launch token functionality (CRO-499) #494

Merged
merged 1 commit into from
Oct 21, 2019
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
58 changes: 8 additions & 50 deletions chain-tx-enclave/enclave-u-common/src/enclave_u/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,65 +31,23 @@
use sgx_types::*;
use sgx_urts::SgxEnclave;

use log::{info, warn};

static ENCLAVE_FILE: &'static str = "enclave.signed.so";

pub const VALIDATION_TOKEN_KEY: &[u8] = b"tx-validation-enclave.token";
pub const QUERY_TOKEN_KEY: &[u8] = b"tx-query-enclave.token";

pub const TOKEN_LEN: usize = 1024;

/// returns the initialized enclave and the launch token (if it was created or updated)
pub fn init_enclave(debug: bool, previous_token: Option<Vec<u8>>) -> (SgxResult<SgxEnclave>, Option<sgx_launch_token_t>) {
let mut launch_token: sgx_launch_token_t = [0; TOKEN_LEN];
let mut launch_token_updated: i32 = 0;
// Step 1: try to retrieve the launch token saved by last transaction
// if there is no token, then create a new one.
//
// try to get the token saved in the key-value db */
let stored_token = match previous_token {
Some(token) => {
info!("[+] Open token file success! ");
if token.len() != TOKEN_LEN {
warn!(
"[+] Token file invalid, will create new token file -- size: {} (expected {})",
token.len(),
TOKEN_LEN
);
false
} else {
launch_token.copy_from_slice(&token);
true
}
}
_ => {
warn!("[-] Open token file error or not found! Will create one.");
false
}
};

// Step 2: call sgx_create_enclave to initialize an enclave instance
/// returns the initialized enclave
pub fn init_enclave(debug: bool) -> SgxResult<SgxEnclave> {
// call sgx_create_enclave to initialize an enclave instance
// Debug Support: set 2nd parameter to 1
let debug = if debug { 1 } else { 0 };
let mut misc_attr = sgx_misc_attribute_t {
secs_attr: sgx_attributes_t { flags: 0, xfrm: 0 },
misc_select: 0,
};
let enclave = SgxEnclave::create(
// TODO: remove the launch token-related args when they are removed from SDK
SgxEnclave::create(
ENCLAVE_FILE,
debug,
&mut launch_token,
&mut launch_token_updated,
&mut [0; 1024],
&mut 0,
&mut misc_attr,
);

// Step 3: save the launch token if it is updated
if (stored_token && launch_token_updated != 0) || !stored_token {
(enclave, Some(launch_token))
} else {
(enclave, None)
}


)
}
52 changes: 10 additions & 42 deletions chain-tx-enclave/tx-query/app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ mod enclave_u;
#[cfg(feature = "sgx-test")]
mod test;

use crate::enclave_u::{init_connection, ZMQ_SOCKET};
use enclave_protocol::{EnclaveRequest, EnclaveResponse, FLAGS};
use crate::enclave_u::init_connection;
use enclave_u::run_server;
use enclave_u_common::enclave_u::{init_enclave, QUERY_TOKEN_KEY};
use enclave_u_common::enclave_u::init_enclave;
use log::{error, info, warn};
use parity_scale_codec::{Decode, Encode};
use sgx_types::sgx_status_t;
use sgx_urts::SgxEnclave;
use std::env;
Expand All @@ -21,45 +19,15 @@ use std::time::Duration;
const TIMEOUT_SEC: u64 = 5;

pub fn start_enclave() -> SgxEnclave {
ZMQ_SOCKET.with(|socket| {
let q_token = QUERY_TOKEN_KEY.to_vec();
let request = EnclaveRequest::GetCachedLaunchToken {
enclave_metaname: q_token.clone(),
};
let req = request.encode();
socket.send(req, FLAGS).expect("request sending failed");
let msg = socket
.recv_bytes(FLAGS)
.expect("failed to receive a response");
match EnclaveResponse::decode(&mut msg.as_slice()) {
Ok(EnclaveResponse::GetCachedLaunchToken(Ok(token))) => {
let launch_token = token.map(|x| x.to_vec());
match init_enclave(true, launch_token) {
(Ok(r), new_token) => {
info!("[+] Init Enclave Successful {}!", r.geteid());
if let Some(launch_token) = new_token {
let request = EnclaveRequest::UpdateCachedLaunchToken {
enclave_metaname: q_token,
token: Box::new(launch_token),
};
let req = request.encode();
socket.send(req, FLAGS).expect("request sending failed");
socket
.recv_bytes(FLAGS)
.expect("failed to receive a response");
}
return r;
}
(Err(x), _) => {
panic!("[-] Init Enclave Failed {}!", x.as_str());
}
};
}
_ => {
panic!("error in launch zmq response");
}
match init_enclave(true) {
Ok(r) => {
info!("[+] Init Query Enclave Successful {}!", r.geteid());
r
}
Err(e) => {
panic!("[-] Init Query Enclave Failed {}!", e.as_str());
}
})
}
}

#[cfg(feature = "sgx-test")]
Expand Down
2 changes: 1 addition & 1 deletion chain-tx-enclave/tx-query/app/src/test/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use client_core::cipher::DefaultTransactionObfuscation;
use client_core::cipher::TransactionObfuscation;
use enclave_protocol::FLAGS;
use enclave_protocol::{EnclaveRequest, EnclaveResponse};
use enclave_u_common::enclave_u::{init_enclave, VALIDATION_TOKEN_KEY};
use enclave_u_common::enclave_u::init_enclave;
use env_logger::{Builder, WriteStyle};
use log::LevelFilter;
use log::{debug, error, info, warn};
Expand Down
33 changes: 0 additions & 33 deletions chain-tx-enclave/tx-validation/app/src/enclave_u/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use chain_core::tx::TxAux;
use chain_core::tx::TxObfuscated;
use chain_tx_validation::Error;
use enclave_protocol::{IntraEnclaveRequest, IntraEnclaveResponse, IntraEnclaveResponseOk};
use enclave_u_common::enclave_u::TOKEN_LEN;
use log::{info, warn};
use parity_scale_codec::{Decode, Encode};
use sled::Tree;
use std::mem::size_of;
Expand All @@ -32,37 +30,6 @@ extern "C" {

}

pub fn get_token(metadb: &Tree, token_key: &[u8]) -> Option<Vec<u8>> {
match metadb.get(token_key) {
Ok(x) => x.map(|tok| tok.to_vec()),
_ => None,
}
}

pub fn get_token_arr(metadb: &Tree, token_key: &[u8]) -> Result<Option<Box<[u8; TOKEN_LEN]>>, ()> {
match metadb.get(token_key) {
Ok(x) => Ok(x.map(|tok| {
let mut token = [0; TOKEN_LEN];
token.copy_from_slice(&tok);
Box::new(token)
})),
_ => Err(()),
}
}

pub fn store_token(metadb: &mut Tree, token_key: &[u8], launch_token: Vec<u8>) -> Result<(), ()> {
match metadb.insert(token_key, launch_token) {
Ok(_) => {
info!("[+] Saved updated launch token!");
Ok(())
}
Err(_) => {
warn!("[-] Failed to save updated launch token!");
Err(())
}
}
}

pub fn check_initchain(
eid: sgx_enclave_id_t,
chain_hex_id: u8,
Expand Down
15 changes: 5 additions & 10 deletions chain-tx-enclave/tx-validation/app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ mod server;
#[cfg(feature = "sgx-test")]
mod test;

use crate::enclave_u::{get_token, store_token};
use crate::server::TxValidationServer;
use enclave_u_common::enclave_u::{init_enclave, VALIDATION_TOKEN_KEY};
use enclave_u_common::enclave_u::init_enclave;
use enclave_u_common::{storage_path, META_KEYSPACE, TX_KEYSPACE};
use log::{error, info};
use sled::Db;
Expand All @@ -26,22 +25,18 @@ fn main() {
return;
}
let db = Db::open(storage_path()).expect("failed to open a storage path");
let mut metadb = db
let metadb = db
.open_tree(META_KEYSPACE)
.expect("failed to open a meta keyspace");
let txdb = db
.open_tree(TX_KEYSPACE)
.expect("failed to open a tx keyspace");
let token = get_token(&metadb, VALIDATION_TOKEN_KEY);
let enclave = match init_enclave(true, token) {
(Ok(r), new_token) => {
let enclave = match init_enclave(true) {
Ok(r) => {
info!("[+] Init Enclave Successful {}!", r.geteid());
if let Some(launch_token) = new_token {
let _ = store_token(&mut metadb, VALIDATION_TOKEN_KEY, launch_token.to_vec());
}
r
}
(Err(x), _) => {
Err(x) => {
error!("[-] Init Enclave Failed {}!", x.as_str());
return;
}
Expand Down
33 changes: 11 additions & 22 deletions chain-tx-enclave/tx-validation/app/src/server/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use crate::enclave_u::{
check_initchain, check_tx, encrypt_tx, end_block, get_token_arr, store_token,
};
use crate::enclave_u::{check_initchain, check_tx, encrypt_tx, end_block};
use chain_core::state::account::DepositBondTx;
use chain_core::tx::data::TxId;
use chain_core::tx::TxAux;
Expand Down Expand Up @@ -33,7 +31,7 @@ impl TxValidationServer {
txdb: Tree,
metadb: Tree,
) -> Result<TxValidationServer, Error> {
match txdb.get(LAST_CHAIN_INFO_KEY) {
match metadb.get(LAST_CHAIN_INFO_KEY) {
Err(_) => Err(Error::EFAULT),
Ok(s) => {
let info = s.map(|stored| {
Expand Down Expand Up @@ -80,6 +78,11 @@ impl TxValidationServer {
}
}

pub fn flush_all(&mut self) -> Result<usize, sled::Error> {
let _ = self.txdb.flush()?;
self.metadb.flush()
}

pub fn execute(&mut self) {
info!("running zmq server");
loop {
Expand All @@ -92,7 +95,7 @@ impl TxValidationServer {
last_app_hash,
}) => {
debug!("check chain");
match self.txdb.get(LAST_APP_HASH_KEY) {
match self.metadb.get(LAST_APP_HASH_KEY) {
Err(_) => EnclaveResponse::CheckChain(Err(None)),
Ok(s) => {
let ss = s.map(|stored| {
Expand All @@ -117,14 +120,14 @@ impl TxValidationServer {
IntraEnclaveRequest::EndBlock,
)),
Ok(EnclaveRequest::CommitBlock { app_hash }) => {
let _ = self.txdb.insert(LAST_APP_HASH_KEY, &app_hash);
let _ = self.metadb.insert(LAST_APP_HASH_KEY, &app_hash);
match self.info {
Some(info) => {
let _ = self.txdb.insert(LAST_CHAIN_INFO_KEY, &info.encode()[..]);
let _ = self.metadb.insert(LAST_CHAIN_INFO_KEY, &info.encode()[..]);
}
_ => {}
};
if let Ok(_) = self.txdb.flush() {
if let Ok(_) = self.flush_all() {
EnclaveResponse::CommitBlock(Ok(()))
} else {
EnclaveResponse::CommitBlock(Err(()))
Expand All @@ -147,20 +150,6 @@ impl TxValidationServer {
))
}
}
Ok(EnclaveRequest::GetCachedLaunchToken { enclave_metaname }) => {
EnclaveResponse::GetCachedLaunchToken(get_token_arr(
&self.metadb,
&enclave_metaname,
))
}
Ok(EnclaveRequest::UpdateCachedLaunchToken {
enclave_metaname,
token,
}) => EnclaveResponse::UpdateCachedLaunchToken(store_token(
&mut self.metadb,
&enclave_metaname,
token.to_vec(),
)),
Ok(EnclaveRequest::GetSealedTxData { txids }) => {
EnclaveResponse::GetSealedTxData(
self.lookup_txids(txids.iter().map(|x| *x)),
Expand Down
13 changes: 4 additions & 9 deletions chain-tx-enclave/tx-validation/app/src/test/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::enclave_u::{check_initchain, check_tx, end_block};
use crate::enclave_u::{get_token, store_token};
use chain_core::common::MerkleTree;
use chain_core::init::address::RedeemAddress;
use chain_core::init::coin::Coin;
Expand Down Expand Up @@ -27,7 +26,7 @@ use chain_core::tx::{
use chain_core::ChainInfo;
use chain_tx_validation::Error;
use enclave_protocol::{EncryptionRequest, IntraEnclaveRequest, VerifyTxRequest};
use enclave_u_common::enclave_u::{init_enclave, VALIDATION_TOKEN_KEY};
use enclave_u_common::enclave_u::init_enclave;
use env_logger::{Builder, WriteStyle};
use log::LevelFilter;
use log::{debug, error, info};
Expand Down Expand Up @@ -115,16 +114,12 @@ pub fn test_sealing() {
.open_tree(crate::TX_KEYSPACE)
.expect("failed to open a tx keyspace");

let token = get_token(&metadb, VALIDATION_TOKEN_KEY);
let enclave = match init_enclave(true, token) {
(Ok(r), new_token) => {
let enclave = match init_enclave(true) {
Ok(r) => {
info!("[+] Init Enclave Successful {}!", r.geteid());
if let Some(launch_token) = new_token {
store_token(&mut metadb, VALIDATION_TOKEN_KEY, launch_token.to_vec());
}
r
}
(Err(x), _) => {
Err(x) => {
error!("[-] Init Enclave Failed {}!", x.as_str());
return;
}
Expand Down
14 changes: 0 additions & 14 deletions enclave-protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ use secp256k1::{
};

pub const ENCRYPTION_REQUEST_SIZE: usize = 1024 * 60; // 60 KB
const TOKEN_LEN: usize = 1024;

/// raw sgx_sealed_data_t
type SealedLog = Vec<u8>;
Expand Down Expand Up @@ -130,7 +129,6 @@ pub struct QueryEncryptRequest {
}

/// requests sent from chain-abci app to enclave wrapper server
/// FIXME: remove launch token stuff (deprecated in SGX SDK 2.6)
#[derive(Encode, Decode)]
pub enum EnclaveRequest {
/// a sanity check (sends the chain network ID -- last byte / two hex digits convention)
Expand All @@ -149,13 +147,6 @@ pub enum EnclaveRequest {
/// request to flush/persist storage + store the computed app hash
/// FIXME: enclave should be able to compute a part of app hash, so send the other parts and check the same app hash was computed
CommitBlock { app_hash: H256 },
/// request to get a stored launch token (requested by TQE -- they should be on the same machine)
GetCachedLaunchToken { enclave_metaname: Vec<u8> },
/// request to update the stored launch token (requested by TQE -- they should be on the same machine)
UpdateCachedLaunchToken {
enclave_metaname: Vec<u8>,
token: Box<[u8; TOKEN_LEN]>,
},
/// request to get tx data sealed to "mrsigner" (requested by TQE -- they should be on the same machine)
GetSealedTxData { txids: Vec<TxId> },
/// request to encrypt tx by the current key (requested by TQE -- they should be on the same machine)
Expand All @@ -170,7 +161,6 @@ impl EnclaveRequest {

/// reponses sent from enclave wrapper server to chain-abci app
/// TODO: better error responses?
/// FIXME: remove launch token stuff (deprecated in SGX SDK 2.6)
#[derive(Encode, Decode)]
pub enum EnclaveResponse {
/// returns OK if chain_hex_id matches the one embedded in enclave and last_app_hash matches (returns the last app hash if any)
Expand All @@ -181,10 +171,6 @@ pub enum EnclaveResponse {
EndBlock(Result<Box<TxFilter>, ()>),
/// returns if the data was sucessfully persisted in the enclave's local storage
CommitBlock(Result<(), ()>),
/// returns a stored launch token if any
GetCachedLaunchToken(Result<Option<Box<[u8; TOKEN_LEN]>>, ()>),
/// indicates whether the update was successful
UpdateCachedLaunchToken(Result<(), ()>),
/// returns Some(sealed data payloads) or None (if any TXID was not found / invalid)
GetSealedTxData(Option<Vec<SealedLog>>),
/// returns Ok(encrypted tx payload) if Tx was valid
Expand Down