oasis_core_runtime/common/sgx/
seal.rs1use anyhow::{format_err, Error};
3use rand::{rngs::SysRng, TryRng};
4use sgx_isa::Keypolicy;
5use zeroize::Zeroize;
6
7use crate::common::{
8 crypto::mrae::deoxysii::{DeoxysII, NONCE_SIZE, TAG_SIZE},
9 sgx::egetkey::egetkey,
10};
11
12pub fn seal(key_policy: Keypolicy, context: &[u8], data: &[u8]) -> Vec<u8> {
16 let mut nonce = [0u8; NONCE_SIZE];
18 SysRng.try_fill_bytes(&mut nonce).unwrap();
19 let d2 = new_deoxysii(key_policy, context);
20 let mut ciphertext = d2.seal(&nonce, data, vec![]);
21 ciphertext.extend_from_slice(&nonce);
22
23 ciphertext
24}
25
26pub fn unseal(
30 key_policy: Keypolicy,
31 context: &[u8],
32 ciphertext: &[u8],
33) -> Result<Option<Vec<u8>>, Error> {
34 let ct_len = ciphertext.len();
35 if ct_len == 0 {
36 return Ok(None);
37 }
38 if ct_len < TAG_SIZE + NONCE_SIZE {
39 return Err(format_err!("ciphertext is corrupted: invalid size"));
40 }
41 let ct_len = ct_len - NONCE_SIZE;
42
43 let mut nonce = [0u8; NONCE_SIZE];
45 nonce.copy_from_slice(&ciphertext[ct_len..]);
46 let ciphertext = &ciphertext[..ct_len];
47
48 let d2 = new_deoxysii(key_policy, context);
49
50 match d2.open(&nonce, ciphertext.to_vec(), vec![]) {
51 Ok(plaintext) => Ok(Some(plaintext)),
52 Err(_) => Err(format_err!("ciphertext is corrupted")),
53 }
54}
55
56pub fn new_deoxysii(key_policy: Keypolicy, context: &[u8]) -> DeoxysII {
61 let mut seal_key = egetkey(key_policy, context);
62 let d2 = DeoxysII::new(&seal_key);
63 seal_key.zeroize();
64
65 d2
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71
72 #[test]
73 fn test_seal_unseal() {
74 let sealed_a = seal(Keypolicy::MRSIGNER, b"MRSIGNER", b"Mr. Signer");
76 let unsealed_a = unseal(Keypolicy::MRSIGNER, b"MRSIGNER", &sealed_a);
77 assert_eq!(unsealed_a.unwrap(), Some(b"Mr. Signer".to_vec()));
78
79 let sealed_b = seal(Keypolicy::MRENCLAVE, b"MRENCLAVE", b"Mr. Enclave");
80 let unsealed_b = unseal(Keypolicy::MRENCLAVE, b"MRENCLAVE", &sealed_b);
81 assert_eq!(unsealed_b.unwrap(), Some(b"Mr. Enclave".to_vec()));
82
83 let unsealed_c = unseal(Keypolicy::MRENCLAVE, b"MRENCLAVE", b"");
85 assert_eq!(unsealed_c.unwrap(), None);
86 }
87
88 #[test]
89 fn test_incorrect_context() {
90 let sealed_b = seal(Keypolicy::MRENCLAVE, b"MRENCLAVE1", b"Mr. Enclave");
92 let unsealed_b = unseal(Keypolicy::MRENCLAVE, b"MRENCLAVE2", &sealed_b);
93 assert_eq!(unsealed_b.is_err(), true);
94 }
95
96 #[test]
97 fn test_incorrect_ciphertext_a() {
98 let sealed_b = seal(Keypolicy::MRENCLAVE, b"MRENCLAVE", b"Mr. Enclave");
99 let unsealed_b = unseal(Keypolicy::MRENCLAVE, b"MRENCLAVE", &sealed_b[..2]);
100 assert_eq!(unsealed_b.is_err(), true);
101 }
102
103 #[test]
104 fn test_incorrect_ciphertext_b() {
105 let mut sealed_b = seal(Keypolicy::MRENCLAVE, b"MRENCLAVE", b"Mr. Enclave");
106 sealed_b[0] = sealed_b[0].wrapping_add(1);
107 let unsealed_b = unseal(Keypolicy::MRENCLAVE, b"MRENCLAVE", &sealed_b);
108 assert_eq!(unsealed_b.is_err(), true);
109 }
110}