sgx_keyreq/
keyrequest.rs

1use crate::ecalls::{egetkey, ereport, ECallStatus};
2use sgx_isa::{Keyname, Keypolicy, Keyrequest};
3
4/// Options for requesting a key
5#[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
20/// Fills a key in-place based on a seed
21///
22/// This function loops over the seed and builds multiple keyrequests based on the seed.
23/// Because of the 128 bit nature of the returned keys, the higher the entropy of the seed,
24/// the higher entropy of the resulting key
25pub 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}