use sgx_isa::Keypolicy;
use sp800_185::KMac;
#[cfg(target_env = "sgx")]
use sgx_isa::{Keyname, Keyrequest};
#[cfg(target_env = "sgx")]
use tiny_keccak::{Hasher, Sha3};
const SEAL_KDF_CUSTOM: &[u8] = b"Ekiden Expand SGX Seal Key";
cfg_if::cfg_if! {
if #[cfg(target_env = "sgx")] {
fn egetkey_impl(key_policy: Keypolicy, context: &[u8]) -> [u8; 16] {
let mut req = Keyrequest::default();
req.keyname = Keyname::Seal as u16;
req.keypolicy = key_policy;
let mut sha3 = Sha3::v256();
sha3.update(context);
let mut k = [0; 32];
sha3.finalize(&mut k);
req.keyid = k;
req.attributemask[0] = 1 | 2 | 4; req.attributemask[1] = 3; match req.egetkey() {
Err(e) => panic!("EGETKEY failed: {:?}", e),
Ok(k) => k,
}
}
} else if #[cfg(feature = "tdx")] {
fn egetkey_impl(_key_policy: Keypolicy, _context: &[u8]) -> [u8; 16] {
unimplemented!("EGETKEY not implemented for TDX");
}
} else {
const MOCK_MRENCLAVE_KEY: &[u8] = b"Ekiden Test MRENCLAVE KEY";
const MOCK_MRSIGNER_KEY: &[u8] = b"Ekiden Test MRSIGNER KEY";
const MOCK_KDF_CUSTOM: &[u8] = b"Ekiden Extract Test SGX Seal Key";
fn egetkey_impl(key_policy: Keypolicy, context: &[u8]) -> [u8; 16] {
let mut k = [0u8; 16];
let mut kdf = match key_policy {
Keypolicy::MRENCLAVE => KMac::new_kmac256(MOCK_MRENCLAVE_KEY, MOCK_KDF_CUSTOM),
Keypolicy::MRSIGNER => KMac::new_kmac256(MOCK_MRSIGNER_KEY, MOCK_KDF_CUSTOM),
_ => panic!("Invalid key_policy"),
};
kdf.update(context);
kdf.finalize(&mut k);
k
}
}
}
pub fn egetkey(key_policy: Keypolicy, context: &[u8]) -> [u8; 32] {
let mut k = [0u8; 32];
let master_secret = egetkey_impl(key_policy, context);
let mut kdf = KMac::new_kmac256(&master_secret, SEAL_KDF_CUSTOM);
kdf.update(context);
kdf.finalize(&mut k);
k
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_egetkey() {
let mr_signer_key = egetkey(Keypolicy::MRSIGNER, b"MRSIGNER");
assert!(mr_signer_key != [0u8; 32]);
let mr_enclave_key = egetkey(Keypolicy::MRENCLAVE, b"MRENCLAVE");
assert!(mr_enclave_key != [0u8; 32]);
assert!(mr_signer_key != mr_enclave_key);
let a_key = egetkey(Keypolicy::MRENCLAVE, b"Context A");
let b_key = egetkey(Keypolicy::MRENCLAVE, b"Context B");
assert!(a_key != b_key);
let aa_key = egetkey(Keypolicy::MRENCLAVE, b"Context A");
assert!(a_key == aa_key);
}
}