From daf3f6e0723c28a34c80cfcc4a4c5595226f3459 Mon Sep 17 00:00:00 2001 From: "zongmin.gu" Date: Tue, 15 Sep 2020 13:26:05 +0800 Subject: [PATCH] Update Rust SDK for Occlum --- samplecode/unit-test/enclave/src/lib.rs | 2 + samplecode/unit-test/enclave/src/test_file.rs | 41 +++++++++ sgx_tprotected_fs/src/fs.rs | 84 +++++++++++++++++++ sgx_tstd/src/sgxfs.rs | 39 ++++++++- sgx_tstd/src/sys/sgxfs.rs | 38 +++++++-- sgx_types/src/function.rs | 6 +- sgx_types/src/types.rs | 14 +++- 7 files changed, 215 insertions(+), 9 deletions(-) diff --git a/samplecode/unit-test/enclave/src/lib.rs b/samplecode/unit-test/enclave/src/lib.rs index b9ea49be..d740753f 100644 --- a/samplecode/unit-test/enclave/src/lib.rs +++ b/samplecode/unit-test/enclave/src/lib.rs @@ -166,6 +166,8 @@ fn test_main_entrance() -> size_t { test_serialize_enum, // std::sgxfs test_sgxfs, + // std::sgxfs in integrity-only mode + test_sgxfs_integrity_only, // std::fs test_fs, // std::fs untrusted mode diff --git a/samplecode/unit-test/enclave/src/test_file.rs b/samplecode/unit-test/enclave/src/test_file.rs index 766ba674..eeefd9eb 100644 --- a/samplecode/unit-test/enclave/src/test_file.rs +++ b/samplecode/unit-test/enclave/src/test_file.rs @@ -128,3 +128,44 @@ pub fn test_fs_untrusted_fs_feature_enabled() { assert!(f.is_ok()); } } + +pub fn test_sgxfs_integrity_only() { + let write_data = { + let read_result = std::fs::read_to_string("../Makefile"); + assert!(read_result.is_ok()); + read_result.unwrap() + }; + let path = "sgx_file_integrity_only.data"; + let mut new_file = { + let create_result = SgxFile::create_integrity_only(path); + assert!(create_result.is_ok()); + create_result.unwrap() + }; + let _ = new_file.write_all(&write_data.as_bytes()); + let write_mac = { + let mac_result = new_file.get_mac(); + assert!(mac_result.is_ok()); + mac_result.unwrap() + }; + drop(new_file); + + let mut read_data = String::new(); + let mut open_file = { + let open_result = SgxFile::open_integrity_only(path); + assert!(open_result.is_ok()); + open_result.unwrap() + }; + let _ = open_file.read_to_string(&mut read_data); + let read_mac = { + let mac_result = open_file.get_mac(); + assert!(mac_result.is_ok()); + mac_result.unwrap() + }; + drop(open_file); + + assert_eq!(&write_data[..], &read_data[..]); + assert_eq!(&write_mac, &read_mac); + + let remove_result = remove_file(path); + assert!(remove_result.is_ok()); +} diff --git a/sgx_tprotected_fs/src/fs.rs b/sgx_tprotected_fs/src/fs.rs index 241a7d7f..69608907 100644 --- a/sgx_tprotected_fs/src/fs.rs +++ b/sgx_tprotected_fs/src/fs.rs @@ -39,6 +39,15 @@ unsafe fn rsgx_fopen(filename: &CStr, mode: &CStr, key: &sgx_key_128bit_t) -> Sy } } +unsafe fn rsgx_fopen_integrity_only(filename: &CStr, mode: &CStr) -> SysResult { + let file = sgx_fopen_integrity_only(filename.as_ptr(), mode.as_ptr()); + if file.is_null() { + Err(errno()) + } else { + Ok(file) + } +} + unsafe fn rsgx_fopen_auto_key(filename: &CStr, mode: &CStr) -> SysResult { let file = sgx_fopen_auto_key(filename.as_ptr(), mode.as_ptr()); if file.is_null() { @@ -196,6 +205,15 @@ unsafe fn rsgx_fimport_auto_key(filename: &CStr, key: &sgx_key_128bit_t) -> SysE } } +unsafe fn rsgx_fget_mac(stream: SGX_FILE, mac: &mut sgx_aes_gcm_128bit_tag_t) -> SysError { + let ret = sgx_fget_mac(stream, mac as * mut sgx_aes_gcm_128bit_tag_t); + if ret == 0 { + Ok(()) + } else { + Err(errno()) + } +} + pub struct SgxFileStream { stream: SGX_FILE, } @@ -275,6 +293,48 @@ impl SgxFileStream { unsafe { rsgx_fopen_auto_key(filename, mode).map(|f| SgxFileStream { stream: f }) } } + /// + /// The open function creates or opens a protected file in the integrity-only mode. + /// + /// # Description + /// + /// open_integrity_only is different from open and open_auto_key. + /// The protected file opened by this function is in integrity-only mode. + /// In this mode, the content of the file is not encrypted, only MACed. + /// + /// A protected file created by open_integrity_only cannot later be openned + /// by open or open_auto_key and vice versa. + /// + /// # Parameters + /// + /// **filename** + /// + /// The name of the file to be created or opened. + /// + /// **mode** + /// + /// The file open mode string. Allowed values are any combination of, or, with possible + /// and possible (since string functions are currently not sup- ported, is meaningless). + /// + /// # Requirements + /// + /// Header: sgx_tprotected_fs.edl + /// + /// Library: libsgx_tprotected_fs.a + /// + /// This API is provided by Occlum's fork of Intel SGX SDK. + /// + /// # Return value + /// + /// If the function succeeds, it returns a valid file pointer, which can be used by all the other functions + /// in the Protected FS API, otherwise, error code is returned. + /// + pub fn open_integrity_only(filename: &CStr, mode: &CStr) -> SysResult { + unsafe { + rsgx_fopen_integrity_only(filename, mode).map(|f| SgxFileStream{ stream: f}) + } + } + /// /// The read function reads the requested amount of data from the file, and extends the file pointer by that amount. /// @@ -515,6 +575,30 @@ impl SgxFileStream { pub fn clear_cache(&self) -> SysError { unsafe { rsgx_fclear_cache(self.stream) } } + + /// + /// The get_mac function returns the MAC of the protected file. + /// + /// # Description + /// + /// # Requirements + /// + /// Header: sgx_tprotected_fs.edl + /// + /// Library: libsgx_tprotected_fs.a + /// + /// This API is provided by Occlum's fork of Intel SGX SDK. + /// + /// # Return value + /// + /// If the function succeeded, the MAC is returned. + /// If the function failed, error code is returned. + /// + pub fn get_mac(&self) -> SysResult { + let mut mac : sgx_aes_gcm_128bit_tag_t = Default::default(); + unsafe { rsgx_fget_mac(self.stream, &mut mac)?; } + Ok(mac) + } } /// diff --git a/sgx_tstd/src/sgxfs.rs b/sgx_tstd/src/sgxfs.rs index 91b42d78..2c1af77a 100644 --- a/sgx_tstd/src/sgxfs.rs +++ b/sgx_tstd/src/sgxfs.rs @@ -17,7 +17,7 @@ //! Filesystem manipulation operations. -use sgx_types::{sgx_key_128bit_t, sgx_align_key_128bit_t}; +use sgx_types::{sgx_key_128bit_t, sgx_align_key_128bit_t, sgx_aes_gcm_128bit_tag_t}; use crate::io::{self, SeekFrom, Seek, Read, Initializer, Write}; use crate::path::Path; use crate::sys::sgxfs as fs_imp; @@ -109,6 +109,19 @@ impl SgxFile { OpenOptions::new().read(true).open(path.as_ref()) } + /// Attempts to open a file in read-only and integrity-only mode. + /// + /// See the [`OpenOptions::open`] method for more details. + /// + /// # Errors + /// + /// This function will return an error if `path` does not already exist. + /// Other errors may also be returned according to [`OpenOptions::open`]. + /// + pub fn open_integrity_only>(path: P) -> io::Result { + OpenOptions::new().read(true).open_integrity_only(path.as_ref()) + } + /// Opens a file in write-only mode. /// /// This function will create a file if it does not exist, @@ -118,6 +131,15 @@ impl SgxFile { OpenOptions::new().write(true).open(path.as_ref()) } + /// Opens a file in write-only and integrity-only mode. + /// + /// This function will create a file if it does not exist, + /// and will truncate it if it does. + /// + pub fn create_integrity_only>(path: P) -> io::Result { + OpenOptions::new().write(true).open_integrity_only(path.as_ref()) + } + pub fn open_ex>(path: P, key: &sgx_key_128bit_t) -> io::Result { OpenOptions::new().read(true).open_ex(path.as_ref(), key) } @@ -137,6 +159,12 @@ impl SgxFile { pub fn clear_cache(&self) -> io::Result<()> { self.inner.clear_cache() } + + /// Gets the MAC of the SGX protected file + /// + pub fn get_mac(&self) -> io::Result { + self.inner.get_mac() + } } impl AsInner for SgxFile { @@ -273,6 +301,10 @@ impl OpenOptions { self._open_ex(path.as_ref(), key) } + pub fn open_integrity_only>(&self, path: P) -> io::Result { + self._open_integrity_only(path.as_ref()) + } + fn _open(&self, path: &Path) -> io::Result { let inner = fs_imp::SgxFile::open(path, &self.0)?; Ok(SgxFile { inner: inner }) @@ -282,6 +314,11 @@ impl OpenOptions { let inner = fs_imp::SgxFile::open_ex(path, &self.0, key)?; Ok(SgxFile { inner: inner }) } + + fn _open_integrity_only(&self, path: &Path) -> io::Result { + let inner = fs_imp::SgxFile::open_integrity_only(path, &self.0)?; + Ok(SgxFile { inner: inner }) + } } impl AsInnerMut for OpenOptions { diff --git a/sgx_tstd/src/sys/sgxfs.rs b/sgx_tstd/src/sys/sgxfs.rs index 7d6f24f3..0a6acef9 100644 --- a/sgx_tstd/src/sys/sgxfs.rs +++ b/sgx_tstd/src/sys/sgxfs.rs @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License.. -use sgx_types::{sgx_status_t, sgx_key_128bit_t, sgx_align_key_128bit_t}; +use sgx_types::{sgx_status_t, sgx_key_128bit_t, sgx_align_key_128bit_t, sgx_aes_gcm_128bit_tag_t}; use sgx_trts::libc; use sgx_tprotected_fs::{self, SgxFileStream}; use crate::os::unix::prelude::*; @@ -75,18 +75,29 @@ impl SgxFile { let path = cstr(path)?; let mode = opts.get_access_mode()?; let opts = CString::new(mode.as_bytes())?; - SgxFile::open_c(&path, &opts, &sgx_key_128bit_t::default(), true) + SgxFile::open_c(&path, &opts, &sgx_key_128bit_t::default(), true, false) } pub fn open_ex(path: &Path, opts: &OpenOptions, key: &sgx_key_128bit_t) -> io::Result { let path = cstr(path)?; let mode = opts.get_access_mode()?; let opts = CString::new(mode.as_bytes())?; - SgxFile::open_c(&path, &opts, key, false) + SgxFile::open_c(&path, &opts, key, false, false) } - pub fn open_c(path: &CStr, opts: &CStr, key: &sgx_key_128bit_t, auto: bool) -> io::Result { - let file = if auto == true { + pub fn open_integrity_only(path: &Path, opts: &OpenOptions) -> io::Result { + + let path = cstr(path)?; + let mode = opts.get_access_mode()?; + let opts = CString::new(mode.as_bytes())?; + SgxFile::open_c(&path, &opts, &sgx_key_128bit_t::default(), false, true) + } + + pub fn open_c(path: &CStr, opts: &CStr, key: &sgx_key_128bit_t, auto: bool, integrity_only: bool) -> io::Result { + + let file = if integrity_only == true { + SgxFileStream::open_integrity_only(path, opts) + } else if auto == true { SgxFileStream::open_auto_key(path, opts) } else { SgxFileStream::open(path, opts, key) @@ -213,6 +224,23 @@ impl SgxFile { } }) } + + pub fn get_mac(&self) -> io::Result { + + self.0.get_mac().map_err(|err| { + match err { + 1 => Error::from_sgx_error(sgx_status_t::SGX_ERROR_UNEXPECTED), + 2 => Error::from_sgx_error(sgx_status_t::SGX_ERROR_INVALID_PARAMETER), + 3 => Error::from_sgx_error(sgx_status_t::SGX_ERROR_OUT_OF_MEMORY), + 4 | 5 => Error::from_raw_os_error(err), + r if r > 4096 => { + let status = sgx_status_t::from_repr(r as u32).unwrap_or(sgx_status_t::SGX_ERROR_UNEXPECTED); + Error::from_sgx_error(status) + }, + _ => Error::from_raw_os_error(err), + } + }) + } } pub fn remove(path: &Path) -> io::Result<()> { diff --git a/sgx_types/src/function.rs b/sgx_types/src/function.rs index b74afd75..527e4bf9 100644 --- a/sgx_types/src/function.rs +++ b/sgx_types/src/function.rs @@ -644,7 +644,10 @@ extern "C" { pub fn sgx_fopen_auto_key(filename: *const c_char, mode: *const c_char) -> SGX_FILE; - pub fn sgx_fwrite(ptr: *const c_void, + + pub fn sgx_fopen_integrity_only(filename: * const c_char, mode: * const c_char) -> SGX_FILE; + + pub fn sgx_fwrite(ptr: * const c_void, size: size_t, count: size_t, stream: SGX_FILE) -> size_t; @@ -665,6 +668,7 @@ extern "C" { pub fn sgx_fexport_auto_key(filename: *const c_char, key: *mut sgx_key_128bit_t) -> int32_t; pub fn sgx_fimport_auto_key(filename: *const c_char, key: *const sgx_key_128bit_t) -> int32_t; pub fn sgx_fclear_cache(stream: SGX_FILE) -> int32_t; + pub fn sgx_fget_mac(stream: SGX_FILE, mac: * mut sgx_aes_gcm_128bit_tag_t) -> int32_t; } /* intel sgx sdk 2.0 */ diff --git a/sgx_types/src/types.rs b/sgx_types/src/types.rs index 05cb12f2..ad639fda 100644 --- a/sgx_types/src/types.rs +++ b/sgx_types/src/types.rs @@ -897,8 +897,8 @@ impl_enum! { SGX_EXCEPTION_VECTOR_BP = 3, /* INT 3 instruction */ SGX_EXCEPTION_VECTOR_BR = 5, /* BOUND instruction */ SGX_EXCEPTION_VECTOR_UD = 6, /* UD2 instruction or reserved opcode */ - SGX_EXCEPTION_VECTOR_GP = 13, /* General protection exception */ - SGX_EXCEPTION_VECTOR_PF = 14, /* Page fault exception */ + SGX_EXCEPTION_VECTOR_GP = 13, /* General protection */ + SGX_EXCEPTION_VECTOR_PF = 14, /* Page fault */ SGX_EXCEPTION_VECTOR_MF = 16, /* x87 FPU floating-point or WAIT/FWAIT instruction */ SGX_EXCEPTION_VECTOR_AC = 17, /* Any data reference in memory */ SGX_EXCEPTION_VECTOR_XM = 19, /* SSE/SSE2/SSE3 floating-point instruction */ @@ -912,6 +912,7 @@ impl_enum! { pub enum sgx_exception_type_t { SGX_EXCEPTION_HARDWARE = 3, SGX_EXCEPTION_SOFTWARE = 6, + SGX_EXCEPTION_SIMULATED = 7, } } @@ -957,11 +958,20 @@ cfg_if! { } } +impl_struct! { + pub struct sgx_exinfo_t { + pub maddr: u64, + pub errcd: u32, + pub _unused: u32, + } +} + impl_struct! { pub struct sgx_exception_info_t { pub cpu_context: sgx_cpu_context_t, pub exception_vector: sgx_exception_vector_t, pub exception_type: sgx_exception_type_t, + pub exinfo: sgx_exinfo_t, } } -- 2.17.1