oasis_core_runtime/common/sgx/
seal.rs1use anyhow::{format_err, Error};
3use rand::{rngs::OsRng, Rng};
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 rng = OsRng {};
17
18 let mut nonce = [0u8; NONCE_SIZE];
20 rng.fill(&mut nonce);
21 let d2 = new_deoxysii(key_policy, context);
22 let mut ciphertext = d2.seal(&nonce, data, vec![]);
23 ciphertext.extend_from_slice(&nonce);
24
25 ciphertext
26}
27
28pub fn unseal(
32 key_policy: Keypolicy,
33 context: &[u8],
34 ciphertext: &[u8],
35) -> Result<Option<Vec<u8>>, Error> {
36 let ct_len = ciphertext.len();
37 if ct_len == 0 {
38 return Ok(None);
39 }
40 if ct_len < TAG_SIZE + NONCE_SIZE {
41 return Err(format_err!("ciphertext is corrupted: invalid size"));
42 }
43 let ct_len = ct_len - NONCE_SIZE;
44
45 let mut nonce = [0u8; NONCE_SIZE];
47 nonce.copy_from_slice(&ciphertext[ct_len..]);
48 let ciphertext = &ciphertext[..ct_len];
49
50 let d2 = new_deoxysii(key_policy, context);
51
52 match d2.open(&nonce, ciphertext.to_vec(), vec![]) {
53 Ok(plaintext) => Ok(Some(plaintext)),
54 Err(_) => Err(format_err!("ciphertext is corrupted")),
55 }
56}
57
58pub fn new_deoxysii(key_policy: Keypolicy, context: &[u8]) -> DeoxysII {
63 let mut seal_key = egetkey(key_policy, context);
64 let d2 = DeoxysII::new(&seal_key);
65 seal_key.zeroize();
66
67 d2
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_seal_unseal() {
76 let sealed_a = seal(Keypolicy::MRSIGNER, b"MRSIGNER", b"Mr. Signer");
78 let unsealed_a = unseal(Keypolicy::MRSIGNER, b"MRSIGNER", &sealed_a);
79 assert_eq!(unsealed_a.unwrap(), Some(b"Mr. Signer".to_vec()));
80
81 let sealed_b = seal(Keypolicy::MRENCLAVE, b"MRENCLAVE", b"Mr. Enclave");
82 let unsealed_b = unseal(Keypolicy::MRENCLAVE, b"MRENCLAVE", &sealed_b);
83 assert_eq!(unsealed_b.unwrap(), Some(b"Mr. Enclave".to_vec()));
84
85 let unsealed_c = unseal(Keypolicy::MRENCLAVE, b"MRENCLAVE", b"");
87 assert_eq!(unsealed_c.unwrap(), None);
88 }
89
90 #[test]
91 fn test_incorrect_context() {
92 let sealed_b = seal(Keypolicy::MRENCLAVE, b"MRENCLAVE1", b"Mr. Enclave");
94 let unsealed_b = unseal(Keypolicy::MRENCLAVE, b"MRENCLAVE2", &sealed_b);
95 assert_eq!(unsealed_b.is_err(), true);
96 }
97
98 #[test]
99 fn test_incorrect_ciphertext_a() {
100 let sealed_b = seal(Keypolicy::MRENCLAVE, b"MRENCLAVE", b"Mr. Enclave");
101 let unsealed_b = unseal(Keypolicy::MRENCLAVE, b"MRENCLAVE", &sealed_b[..2]);
102 assert_eq!(unsealed_b.is_err(), true);
103 }
104
105 #[test]
106 fn test_incorrect_ciphertext_b() {
107 let mut sealed_b = seal(Keypolicy::MRENCLAVE, b"MRENCLAVE", b"Mr. Enclave");
108 sealed_b[0] = sealed_b[0].wrapping_add(1);
109 let unsealed_b = unseal(Keypolicy::MRENCLAVE, b"MRENCLAVE", &sealed_b);
110 assert_eq!(unsealed_b.is_err(), true);
111 }
112}