Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/origin/develop' into #200-gener…
Browse files Browse the repository at this point in the history
…ate-signed-contract-id

# Conflicts:
#	cosmwasm/lib/wasmi-runtime/src/contract_operations.rs
#	cosmwasm/lib/wasmi-runtime/src/runtime.rs
  • Loading branch information
Itzik Grossman committed Jun 2, 2020
2 parents 58785cd + 68cb5a9 commit 37ba7d3
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 128 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,7 @@ SHA256SUMS*
*.so
/third_party/vendor
.vscode
*.sealed
*.sealed
*.der
spid.txt
api_key.txt
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ clean-enclave:
sanity-test:
SGX_MODE=SW $(MAKE) build_linux
cp ./cosmwasm/lib/wasmi-runtime/librust_cosmwasm_enclave.signed.so .
./cosmwasm/lib/wasmi-sgx-test.sh
SGX_MODE=SW ./cosmwasm/lib/wasmi-sgx-test.sh

sanity-test-hw:
$(MAKE) build_linux
Expand Down
28 changes: 28 additions & 0 deletions cosmwasm/lib/wasmi-runtime/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cosmwasm/lib/wasmi-runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ sgx_trts = { rev = "v1.1.2", git = "https://github.com/apache/teaclave-sgx-sdk.g
sgx_tseal = { rev = "v1.1.2", git = "https://github.com/apache/teaclave-sgx-sdk.git" }
sgx_tcrypto = { rev = "v1.1.2", git = "https://github.com/apache/teaclave-sgx-sdk.git" }
aes-siv = { version = "0.2.0" }
miscreant = "0.5.2"
enclave-ffi-types = { path = "../enclave-ffi-types" }
pwasm-utils = { version = "0.12.0", default-features = false }
parity-wasm = { version = "0.41.0", default-features = false }
Expand Down
2 changes: 1 addition & 1 deletion cosmwasm/lib/wasmi-runtime/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ librust_cosmwasm_enclave.so: $(CUSTOM_LIBRARY_PATH)/libenclave.a Enclave_t.o
$(CXX) Enclave_t.o -o $@ $(RustEnclave_Link_Flags)

$(CUSTOM_LIBRARY_PATH)/libenclave.a: $(CUSTOM_LIBRARY_PATH) $(Rust_Crate_Source)
RUST_TARGET_PATH=$(Rust_Target_Path) RUSTFLAGS="-Z force-unstable-if-unmarked" xargo build --features "SGX_MODE_$(SGX_MODE)" --target x86_64-unknown-linux-sgx --release
RUST_TARGET_PATH=$(Rust_Target_Path) RUSTFLAGS="-Z force-unstable-if-unmarked -Ctarget-feature=+aes,+ssse3" xargo build --features "SGX_MODE_$(SGX_MODE)" --target x86_64-unknown-linux-sgx --release
cp target/x86_64-unknown-linux-sgx/release/libwasmi_runtime_enclave.a $(CUSTOM_LIBRARY_PATH)/libenclave.a

$(CUSTOM_LIBRARY_PATH):
Expand Down
106 changes: 52 additions & 54 deletions cosmwasm/lib/wasmi-runtime/src/contract_operations.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use crate::crypto::*;
use base64;
use enclave_ffi_types::{Ctx, EnclaveError};
use log::*;
Expand All @@ -12,7 +11,7 @@ use super::results::{HandleSuccess, InitSuccess, QuerySuccess};
use crate::cosmwasm::encoding::Binary;
use crate::cosmwasm::types::{ContractResult, Env, Response};

use crate::crypto::{Hmac, Kdf, KEY_MANAGER};
use crate::crypto::{sha_256, AESKey, Hmac, Kdf, SIVEncryptable, HASH_SIZE, KEY_MANAGER};
use crate::errors::wasmi_error_to_enclave_error;
use crate::gas::{gas_rules, WasmCosts};
use crate::runtime::{Engine, EnigmaImportResolver, Runtime};
Expand Down Expand Up @@ -306,32 +305,26 @@ pub fn query(
}

fn decrypt_msg(msg: &[u8]) -> Result<Vec<u8>, EnclaveError> {
// TODO:
// extract "challenge" & "wallet_pubkey" from AAD
// validate that "env.message.signer" is derived from "wallet_pubkey"
// calculate "shared_key_base" from "ECDH(wallet_pubkey, sk_consensus_io_exchange_keypair)"
// calculate "shared_key" from "HKDF(shared_key_base + challenge)"
// decrypt(shared_key, msg)
// ?? need to authenticate ADD or doest it happen inside decrypt ??
// TODO check msg.len > 65

// pseudo code:
// [challenge, pk_wallet] = get_AAD(encrypted_input)
// base_key = ECDH(sk_io, pk_wallet)
// encryption_key = HKDF(base_key + challenge)
// decrypted_input = decrypt(key=encryption_key, data=encrypted_input)
// ?? need to authenticate ADD or doest it happen inside decrypt ??
let nonce = &msg[0..32]; // to then kdf with aes key
let tx_sender_wallet_pubkey = &msg[32..65]; // 33 bytes compressed secp256k1 pubkey
let encrypted_msg = &msg[65..];

/////////////////////////////////// ASSAF TAKE IT FROM HERE
// derive decryption key

// TODO KEY_MANAGER should be initialized in the boot process and after that it'll never panic, if it panics on boot than the node is in a broken state and should panic
let key = AESKey::new_from_slice(&[7_u8; 32]);

// let (msg, aad) = msg.split_at(msg.len() - 89);

// aad = last 89 bytes of msg
// let aad = msg[(msg.len() - 89)..];
// ad = first 33 bytes of msg
// let ad = msg[(msg.len() - 89)..];
// let msg = mag[0..(msg.len() - 89)];

// pass
let msg = key.decrypt(msg).map_err(|err| {
let msg = key.decrypt_siv(encrypted_msg, &vec![&[]]).map_err(|err| {
error!(
"handle() got an error while trying to decrypt the msg: {}",
err
Expand Down Expand Up @@ -376,32 +369,34 @@ fn encrypt_output(output: &Vec<u8>) -> Result<Vec<u8>, EnclaveError> {

if let Value::String(err) = &v["err"] {
v["err"] = Value::String(base64::encode(
&key.encrypt(&err.to_owned().into_bytes()).map_err(|err| {
error!(
"got an error while trying to encrypt output error {:?}: {}",
err, err
);
EnclaveError::FailedSeal
})?,
&key.encrypt_siv(&err.to_owned().into_bytes(), &vec![&[]])
.map_err(|err| {
error!(
"got an error while trying to encrypt output error {:?}: {}",
err, err
);
EnclaveError::FailedSeal
})?,
));
} else if let Value::String(ok) = &v["ok"] {
// query
v["ok"] = Value::String(base64::encode(
&key.encrypt(&ok.to_owned().into_bytes()).map_err(|err| {
error!(
"got an error while trying to encrypt query output {:?}: {}",
ok, err
);
EnclaveError::FailedSeal
})?,
&key.encrypt_siv(&ok.to_owned().into_bytes(), &vec![&[]])
.map_err(|err| {
error!(
"got an error while trying to encrypt query output {:?}: {}",
ok, err
);
EnclaveError::FailedSeal
})?,
));
} else if let Value::Object(ok) = &mut v["ok"] {
// init of handle
if let Value::Array(msgs) = &mut ok["messages"] {
for msg in msgs {
if let Value::String(msg_to_next_call) = &mut msg["contract"]["msg"] {
msg["contract"]["msg"] = Value::String(base64::encode(
&key.encrypt(&msg_to_next_call.to_owned().into_bytes())
&key.encrypt_siv(&msg_to_next_call.to_owned().into_bytes(), &vec![&[]])
.map_err(|err| {
error!(
"got an error while trying to encrypt the msg to next call {:?}: {}",
Expand All @@ -418,38 +413,41 @@ fn encrypt_output(output: &Vec<u8>) -> Result<Vec<u8>, EnclaveError> {
for e in events {
if let Value::String(k) = &mut e["key"] {
e["key"] = Value::String(base64::encode(
&key.encrypt(&k.to_owned().into_bytes()).map_err(|err| {
error!(
"got an error while trying to encrypt the event key {}: {}",
k, err
);
EnclaveError::FailedSeal
})?,
&key.encrypt_siv(&k.to_owned().into_bytes(), &vec![&[]])
.map_err(|err| {
error!(
"got an error while trying to encrypt the event key {}: {}",
k, err
);
EnclaveError::FailedSeal
})?,
));
}
if let Value::String(v) = &mut e["value"] {
e["value"] = Value::String(base64::encode(
&key.encrypt(&v.to_owned().into_bytes()).map_err(|err| {
error!(
"got an error while trying to encrypt the event value {}: {}",
v, err
);
EnclaveError::FailedSeal
})?,
&key.encrypt_siv(&v.to_owned().into_bytes(), &vec![&[]])
.map_err(|err| {
error!(
"got an error while trying to encrypt the event value {}: {}",
v, err
);
EnclaveError::FailedSeal
})?,
));
}
}
}

if let Value::String(data) = &mut v["ok"]["data"] {
v["ok"]["data"] = Value::String(base64::encode(
&key.encrypt(&data.to_owned().into_bytes()).map_err(|err| {
error!(
"got an error while trying to encrypt the data section {}: {}",
data, err
);
EnclaveError::FailedSeal
})?,
&key.encrypt_siv(&data.to_owned().into_bytes(), &vec![&[]])
.map_err(|err| {
error!(
"got an error while trying to encrypt the data section {}: {}",
data, err
);
EnclaveError::FailedSeal
})?,
));
}
}
Expand Down
11 changes: 7 additions & 4 deletions cosmwasm/lib/wasmi-runtime/src/crypto/aes_siv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::crypto::traits::SIVEncryptable;
use aes_siv::aead::generic_array::GenericArray;
use aes_siv::siv::Aes128Siv;
use enclave_ffi_types::CryptoError;
use log::*;

impl SIVEncryptable for AESKey {
fn encrypt_siv(&self, plaintext: &[u8], ad: &Vec<&[u8]>) -> Result<Vec<u8>, CryptoError> {
Expand All @@ -33,13 +34,14 @@ impl SIVEncryptable for AESKey {

fn aes_siv_encrypt(
plaintext: &[u8],
iv: &Vec<&[u8]>,
ad: &Vec<&[u8]>,
key: &SymmetricKey,
) -> Result<Vec<u8>, CryptoError> {
let mut cipher = Aes128Siv::new(GenericArray::clone_from_slice(key));
let ciphertext = match cipher.encrypt(iv, plaintext) {
let ciphertext = match cipher.encrypt(ad, plaintext) {
Ok(res) => res,
Err(e) => {
error!("aes_siv_encrypt error: {:?}", e);
return Err(CryptoError::EncryptionError);
}
};
Expand All @@ -48,13 +50,14 @@ fn aes_siv_encrypt(

fn aes_siv_decrypt(
ciphertext: &[u8],
iv: &Vec<&[u8]>,
ad: &Vec<&[u8]>,
key: &SymmetricKey,
) -> Result<Vec<u8>, CryptoError> {
let mut cipher = Aes128Siv::new(GenericArray::clone_from_slice(key));
let plaintext = match cipher.decrypt(iv, ciphertext) {
let plaintext = match cipher.decrypt(ad, ciphertext) {
Ok(res) => res,
Err(e) => {
error!("aes_siv_decrypt error: {:?}", e);
return Err(CryptoError::DecryptionError);
}
};
Expand Down
53 changes: 18 additions & 35 deletions cosmwasm/lib/wasmi-runtime/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,35 +187,26 @@ impl Externals for Runtime {
String::from_utf8_lossy(&state_key_name)
);

// Call read_db (this bubbles up to Tendermint via ocalls and FFI to Go code)
// This returns the value from Tendermint
// fn read_db(context: Ctx, key: &[u8]) -> Option<Vec<u8>> {
let value = match read_db(unsafe { &self.context.clone() }, &state_key_name)
.map_err(|err| {
error!(
"read_db() got an error from ocall_read_db, stopping wasm: {:?}",
err
);
WasmEngineError::FailedOcall
})? {
None => return Ok(Some(RuntimeValue::I32(0))),
Some(value) => value,
};

// TODO KEY_MANAGER should be initialized in the boot process and after that it'll never panic, if it panics on boot than the node is in a broken state and should panic
// TODO derive encryption key for these key-value on this contract
let base_state_key = key_manager::KEY_MANAGER.get_consensus_state_ikm().unwrap();
let encrypted_state_key_name = base_state_key.encrypt(&state_key_name).map_err(|err| {
error!(
"read_db() got an error while trying to encrypt the state_key_name {:?}, stopping wasm: {:?}",
String::from_utf8_lossy(&state_key_name),
err
);
WasmEngineError::EncryptionError
})?;

// Call read_db (this bubbles up to Tendermint via ocalls and FFI to Go code)
// This returns the value from Tendermint
// fn read_db(context: Ctx, key: &[u8]) -> Option<Vec<u8>> {
let value =
match read_db(unsafe { &self.context.clone() }, &encrypted_state_key_name)
.map_err(|err| {
error!(
"read_db() got an error from ocall_read_db, stopping wasm: {:?}",
err
);
WasmEngineError::FailedOcall
})? {
None => return Ok(Some(RuntimeValue::I32(0))),
Some(value) => value,
};

let decrypted_value = base_state_key.encrypt(&value).map_err(|err| {
let decrypted_value = base_state_key.decrypt_siv(&value, &vec![]).map_err(|err| {
error!(
"read_db() got an error while trying to decrypt the value for key {:?}, stopping wasm: {:?}",
String::from_utf8_lossy(&state_key_name),
Expand Down Expand Up @@ -326,15 +317,7 @@ impl Externals for Runtime {
// TODO KEY_MANAGER should be initialized in the boot process and after that it'll never panic, if it panics on boot than the node is in a broken state and should panic
// TODO derive encryption key for these key-value on this contract
let base_state_key = key_manager::KEY_MANAGER.get_consensus_state_ikm().unwrap();
let encrypted_state_key_name = base_state_key.encrypt(&state_key_name).map_err(|err| {
error!(
"write_db() got an error while trying to encrypt the state_key_name {:?}, stopping wasm: {:?}",
String::from_utf8_lossy(&state_key_name),
err
);
WasmEngineError::EncryptionError
})?;
let encrypted_value = base_state_key.encrypt(&value).map_err(|err| {
let encrypted_value = base_state_key.encrypt_siv(&value,&vec![]).map_err(|err| {
error!(
"write_db() got an error while trying to encrypt the value {:?}, stopping wasm: {:?}",
String::from_utf8_lossy(&value),
Expand All @@ -347,7 +330,7 @@ impl Externals for Runtime {
// fn write_db(context: Ctx, key: &[u8], value: &[u8]) {
write_db(
unsafe { self.context.clone() },
&encrypted_state_key_name,
&state_key_name,
&encrypted_value,
)
.map_err(|err| {
Expand Down
4 changes: 2 additions & 2 deletions cosmwasm/lib/wasmi-sgx-test.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

set -euv
set -euvx

function wait_for_tx () {
until (./enigmacli q tx "$1")
Expand All @@ -26,7 +26,7 @@ perl -i -pe 's/"stake"/"uscrt"/g' ~/.enigmad/config/genesis.json
./enigmad collect-gentxs
./enigmad validate-genesis

./enigmad init-bootstrap /home/runner/work/SecretNetwork/SecretNetwork/node-master-cert.der /home/runner/work/SecretNetwork/SecretNetwork/io-master-cert.der
./enigmad init-bootstrap ./node-master-cert.der ./io-master-cert.der

./enigmad validate-genesis

Expand Down
Loading

0 comments on commit 37ba7d3

Please sign in to comment.