421 lines
15 KiB
Diff
421 lines
15 KiB
Diff
From daf3f6e0723c28a34c80cfcc4a4c5595226f3459 Mon Sep 17 00:00:00 2001
|
|
From: "zongmin.gu" <zongmin.gzm@antgroup.com>
|
|
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<SGX_FILE> {
|
|
+ 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<SGX_FILE> {
|
|
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<SgxFileStream> {
|
|
+ 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<sgx_aes_gcm_128bit_tag_t> {
|
|
+ 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<P: AsRef<Path>>(path: P) -> io::Result<SgxFile> {
|
|
+ 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<P: AsRef<Path>>(path: P) -> io::Result<SgxFile> {
|
|
+ OpenOptions::new().write(true).open_integrity_only(path.as_ref())
|
|
+ }
|
|
+
|
|
pub fn open_ex<P: AsRef<Path>>(path: P, key: &sgx_key_128bit_t) -> io::Result<SgxFile> {
|
|
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<sgx_aes_gcm_128bit_tag_t> {
|
|
+ self.inner.get_mac()
|
|
+ }
|
|
}
|
|
|
|
impl AsInner<fs_imp::SgxFile> for SgxFile {
|
|
@@ -273,6 +301,10 @@ impl OpenOptions {
|
|
self._open_ex(path.as_ref(), key)
|
|
}
|
|
|
|
+ pub fn open_integrity_only<P: AsRef<Path>>(&self, path: P) -> io::Result<SgxFile> {
|
|
+ self._open_integrity_only(path.as_ref())
|
|
+ }
|
|
+
|
|
fn _open(&self, path: &Path) -> io::Result<SgxFile> {
|
|
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<SgxFile> {
|
|
+ let inner = fs_imp::SgxFile::open_integrity_only(path, &self.0)?;
|
|
+ Ok(SgxFile { inner: inner })
|
|
+ }
|
|
}
|
|
|
|
impl AsInnerMut<fs_imp::OpenOptions> 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<SgxFile> {
|
|
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<SgxFile> {
|
|
- let file = if auto == true {
|
|
+ pub fn open_integrity_only(path: &Path, opts: &OpenOptions) -> io::Result<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(), false, true)
|
|
+ }
|
|
+
|
|
+ pub fn open_c(path: &CStr, opts: &CStr, key: &sgx_key_128bit_t, auto: bool, integrity_only: bool) -> io::Result<SgxFile> {
|
|
+
|
|
+ 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<sgx_aes_gcm_128bit_tag_t> {
|
|
+
|
|
+ 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
|
|
|