1use crate::ecalls::{egetkey, ereport, ECallStatus};
2use sgx_isa::{Keyname, Keypolicy, Keyrequest};
3
4#[derive(Clone, Copy, Eq, PartialEq)]
6pub struct KeyOpts {
7 pub name: Keyname,
8 pub policy: Keypolicy,
9}
10
11impl Default for KeyOpts {
12 fn default() -> Self {
13 Self {
14 name: Keyname::Seal,
15 policy: Keypolicy::MRSIGNER,
16 }
17 }
18}
19
20pub fn get_key(opts: KeyOpts, seed: &mut [u8]) -> Result<(), ECallStatus> {
26 let report = ereport(Default::default(), [0; 64])?;
27 let base_keyrequest = Keyrequest {
28 keyname: opts.name as u16,
29 keypolicy: opts.policy,
30 isvsvn: report.isvsvn,
31 cpusvn: report.cpusvn,
32 miscmask: report.miscselect.bits(),
33 attributemask: [report.attributes.flags.bits(), report.attributes.xfrm],
34 ..Default::default()
35 };
36
37 let mut chunks = seed.chunks_mut(16);
38 while let Some(chunk) = chunks.next() {
39 let mut keyid = [0; 32];
40 keyid[..chunk.len()].copy_from_slice(chunk);
41 let keyrequest = Keyrequest {
42 keyid,
43 ..base_keyrequest
44 };
45 let key = egetkey(keyrequest)?;
46 chunk.copy_from_slice(&key[..chunk.len()]);
47 }
48
49 Ok(())
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55
56 #[test]
57 fn get_menclave() {
58 let mut key = [0; 32];
59 get_key(
60 KeyOpts {
61 policy: Keypolicy::MRENCLAVE,
62 ..Default::default()
63 },
64 &mut key,
65 )
66 .unwrap();
67 assert_ne!(key, [0; 32]);
68 }
69
70 #[test]
71 fn get_mrsigner() {
72 let mut key = [0; 32];
73 get_key(
74 KeyOpts {
75 policy: Keypolicy::MRSIGNER,
76 ..Default::default()
77 },
78 &mut key,
79 )
80 .unwrap();
81 assert_ne!(key, [0; 32]);
82 }
83
84 #[test]
85 fn get_seal() {
86 let mut key = [0; 32];
87 get_key(
88 KeyOpts {
89 name: Keyname::Seal,
90 ..Default::default()
91 },
92 &mut key,
93 )
94 .unwrap();
95 assert_ne!(key, [0; 32]);
96 }
97
98 #[test]
99 fn get_provision() {
100 let mut key = [0; 32];
101 let res = get_key(
102 KeyOpts {
103 name: Keyname::Provision,
104 ..Default::default()
105 },
106 &mut key,
107 );
108 assert_eq!(res, Err(ECallStatus::InvalidAttribute));
109 }
110
111 #[test]
112 fn get_provision_seal() {
113 let mut key = [0; 32];
114 let res = get_key(
115 KeyOpts {
116 name: Keyname::ProvisionSeal,
117 ..Default::default()
118 },
119 &mut key,
120 );
121 assert_eq!(res, Err(ECallStatus::InvalidAttribute));
122 }
123
124 #[test]
125 fn get_einittoken() {
126 let mut key = [0; 32];
127 let res = get_key(
128 KeyOpts {
129 name: Keyname::Einittoken,
130 ..Default::default()
131 },
132 &mut key,
133 );
134 assert_eq!(res, Err(ECallStatus::InvalidAttribute));
135 }
136
137 #[test]
138 fn get_report() {
139 let mut key = [0; 32];
140 get_key(
141 KeyOpts {
142 name: Keyname::Report,
143 ..Default::default()
144 },
145 &mut key,
146 )
147 .unwrap();
148 assert_ne!(key, [0; 32]);
149 }
150
151 fn check_size(size: usize) {
152 let mut key = vec![0; size];
153 get_key(Default::default(), &mut key).unwrap();
154 assert_ne!(key, vec![0; size]);
155 }
156
157 #[test]
158 fn empty_seal_key_request() {
159 check_size(16);
160 check_size(32);
161 check_size(48);
162 check_size(52);
163 check_size(64);
164 check_size(128);
165 check_size(255);
166 }
167}