Skip to content

Commit

Permalink
feat(transaction-sign): sign algorand transactions in enclave
Browse files Browse the repository at this point in the history
  • Loading branch information
tshepang committed Mar 1, 2023
1 parent f6c239a commit c4a4ad9
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
44 changes: 44 additions & 0 deletions utils/app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,16 @@ extern "C" {
complete_data_len: *mut usize,
complete_data_hash: *mut u8,
) -> sgx_status_t;

fn transaction_sign_ecall(
eid: sgx_enclave_id_t,
retval: *mut sgx_status_t,
transaction: *const u8,
transaction_len: usize,
account_seed: *const u8,
signed_transaction: *mut u8,
signed_transaction_len: *mut usize,
) -> sgx_status_t;
}

fn init_enclave() -> SgxResult<SgxEnclave> {
Expand All @@ -63,6 +73,7 @@ fn utils(_py: Python, module: &PyModule) -> PyResult<()> {
module.add_function(wrap_pyfunction!(row_counter, module)?)?;
module.add_function(wrap_pyfunction!(dataset_hashing, module)?)?;
module.add_function(wrap_pyfunction!(dataset_append, module)?)?;
module.add_function(wrap_pyfunction!(transaction_sign, module)?)?;
Ok(())
}

Expand Down Expand Up @@ -162,3 +173,36 @@ pub fn dataset_append(original_data: &str, new_data: &str) -> PyResult<(String,
let complete_data_hash = String::from_utf8_lossy(complete_data_hash);
Ok((complete_data.into(), complete_data_hash.into()))
}

#[pyfunction]
pub fn transaction_sign(transaction: &str, account_seed: &str) -> PyResult<Vec<u8>> {
let enclave = match init_enclave() {
Ok(enclave) => enclave,
Err(why) => {
let message = format!("initialising enclave failed: {why}!");
return Err(PyValueError::new_err(message));
}
};
let mut retval = sgx_status_t::SGX_SUCCESS;
let mut signed_transaction = Vec::with_capacity(100); // TODO avoid magic number
let mut signed_transaction_len = 0;
let result = unsafe {
transaction_sign_ecall(
enclave.geteid(),
&mut retval,
transaction.as_ptr(),
transaction.len(),
account_seed.as_ptr(),
signed_transaction.as_mut_ptr(),
&mut signed_transaction_len,
)
};
enclave.destroy();
if result != sgx_status_t::SGX_SUCCESS {
let message = format!("enclave ECALL failed: {result}!");
return Err(PyValueError::new_err(message));
}
let signed_transaction =
unsafe { slice::from_raw_parts(signed_transaction.as_ptr(), signed_transaction_len) };
Ok(signed_transaction.into())
}
8 changes: 8 additions & 0 deletions utils/enclave/Enclave.edl
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,13 @@ enclave {
[out] size_t* complete_data_len,
[out, size=64] uint8_t* complete_data_hash
);

public sgx_status_t transaction_sign_ecall(
[in, size=transaction_len] const uint8_t* transaction,
size_t transaction_len,
[in, size=32] const uint8_t* account_seed,
[user_check] uint8_t* signed_transaction,
[out] size_t* signed_transaction_len
);
};
};
25 changes: 25 additions & 0 deletions utils/enclave/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use std::{eprintln, ptr, slice, vec::Vec};
use sgx_tstd as std;
use sgx_types::*;

static ALGORAND_ACCOUNT_SEED_IN_BYTES: usize = 64;
// TODO: place this in a shared crate
static HASH_SIZE_IN_BYTES: usize = 64;

Expand Down Expand Up @@ -88,3 +89,27 @@ pub unsafe extern "C" fn dataset_append_ecall(

sgx_status_t::SGX_SUCCESS
}

#[no_mangle]
pub unsafe extern "C" fn transaction_sign_ecall(
transaction: *const u8,
transaction_len: usize,
account_seed: *const u8,
signed_transaction: &mut u8,
signed_transaction_len: &mut usize,
) -> sgx_status_t {
let transaction = unsafe { slice::from_raw_parts(transaction, transaction_len) };
let account_seed =
unsafe { slice::from_raw_parts(account_seed, ALGORAND_ACCOUNT_SEED_IN_BYTES) };

*signed_transaction_len = transaction.len();
unsafe {
ptr::copy_nonoverlapping(
transaction.as_ptr(),
signed_transaction,
*signed_transaction_len,
)
};

sgx_status_t::SGX_SUCCESS
}

0 comments on commit c4a4ad9

Please sign in to comment.