occlum/deps/rust-sgx-sdk.patch
LI Qing 488ec48fe7 Upgrade Rust SGX SDK and its deps to the latest
1. Upgrade Rust SGX SDK to v1.1.0
2. Upgrade Intel SGX SDK to v2.7.1
3. Upgrade Rust to nightly-2019-11-25
2020-01-23 04:40:54 +00:00

384 lines
14 KiB
Diff

From 45e0641710606f98ed295063d171ca62990d32f3 Mon Sep 17 00:00:00 2001
From: LI Qing <geding.lq@alibaba-inc.com>
Date: Tue, 7 Jan 2020 12:20:05 +0000
Subject: [PATCH] Add support for integrity-only SGX protected files
1. Add SgxFile::open_integrity_only API
2. Add SgxFile::create_integrity_only API
3. Add the unit test for integrity-only SgxFile
---
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 | 39 +++++++++++--
sgx_types/src/function.rs | 3 +
6 files changed, 201 insertions(+), 7 deletions(-)
diff --git a/samplecode/unit-test/enclave/src/lib.rs b/samplecode/unit-test/enclave/src/lib.rs
index c04cb4d..14a6d63 100644
--- a/samplecode/unit-test/enclave/src/lib.rs
+++ b/samplecode/unit-test/enclave/src/lib.rs
@@ -157,6 +157,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 5e7466e..8b8d6d0 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 64d85d0..9ded4e8 100644
--- a/sgx_tprotected_fs/src/fs.rs
+++ b/sgx_tprotected_fs/src/fs.rs
@@ -35,6 +35,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() {
@@ -193,6 +202,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
}
@@ -278,6 +296,48 @@ impl SgxFileStream {
}
///
+ /// 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.
///
/// # Description
@@ -517,6 +577,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 b07aaf2..ccb7f93 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 7b47471..9735193 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::*;
@@ -76,7 +76,7 @@ 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> {
@@ -84,12 +84,22 @@ impl 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> {
+ pub fn open_integrity_only(path: &Path, opts: &OpenOptions) -> io::Result<SgxFile> {
- let file = if auto == true {
+ 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)
@@ -222,6 +232,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<()> {
@@ -331,4 +358,4 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
let ret = io::copy(&mut reader, &mut writer)?;
fs::set_permissions(to, perm)?;
Ok(ret)
-}
\ No newline at end of file
+}
diff --git a/sgx_types/src/function.rs b/sgx_types/src/function.rs
index 5bb06e0..4e8c7bc 100644
--- a/sgx_types/src/function.rs
+++ b/sgx_types/src/function.rs
@@ -609,6 +609,8 @@ extern {
pub fn sgx_fopen_auto_key(filename: * const c_char, mode: * const c_char) -> SGX_FILE;
+ 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,
@@ -630,6 +632,7 @@ extern {
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 */
--
2.7.4