1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
use crate::Error;
use getrandom::getrandom;
use sha2::{Digest, Sha256};
use std::fs;
/// `Gramine`: Gramine is a virtualized runtime used to manage vanilla binaries
/// to execute in an SGX execution environment. This struct allows access to
/// specific overrides that come out-of-the-box with Gramine.
pub struct Gramine;
impl Gramine {
/// `Gramine::generate_quote`: This call allows the user to progmatically
/// create a signature, or "quote" that can prove some piece of data was
/// generated by a specific enclave. This quote contains a field, "MR_ENCLAVE"
/// Which holds a measurement of the code that generated the signature.
///
/// # Parameters:
/// - `user_data`: This is an arbitrary piece of data that can be attached
/// to the signature for other parties to verify that this data was
/// produced in an enclave with a MR_ENCLAVE measurement
///
/// # Returns
/// `Vec<u8>` of a buffer containing the quote/signature
pub fn generate_quote(user_data: &[u8]) -> std::result::Result<Vec<u8>, Error> {
match fs::metadata("/dev/attestation/quote") {
Ok(_) => (),
Err(_) => return Err(Error::SgxError),
}
let mut hasher = Sha256::new();
hasher.update(user_data);
let hash_result = &hasher.finalize()[..32];
let mut data = [0u8; 64];
data[..32].copy_from_slice(hash_result);
let user_report_data_path = "/dev/attestation/user_report_data";
if fs::write(user_report_data_path, &data[..]).is_err() {
return Err(Error::SgxWriteError);
}
fs::read("/dev/attestation/quote").map_err(|_| Error::SgxError)
}
/// `read_rand`: Gramine provides convinient accessors to read randomness
/// that could not be predicted outside the enclave. Gramine will intercept
/// calls to the getrandom syscall, /dev/random, and /dev/urandom to use
/// SGX sourced randomness instead.
///
/// # Relavent documentation:
/// - <https://gramine.readthedocs.io/en/latest/devel/features.html#randomness>
///
/// # Parameters:
/// - `buf`: the buffer to write the output randomness to.
///
/// # Returns
/// Error on failure.
pub fn read_rand(buf: &mut [u8]) -> std::result::Result<(), Error> {
// https://gramine.readthedocs.io/en/latest/devel/features.html#randomness
getrandom(buf).map_err(|_| Error::SgxError)
}
}