You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by rd...@apache.org on 2022/09/02 12:41:18 UTC
[incubator-teaclave-sgx-sdk] branch v2.0.0-preview updated: Improve SGX Protected FS
This is an automated email from the ASF dual-hosted git repository.
rduan pushed a commit to branch v2.0.0-preview
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-sgx-sdk.git
The following commit(s) were added to refs/heads/v2.0.0-preview by this push:
new d893bc45 Improve SGX Protected FS
d893bc45 is described below
commit d893bc456cdd46c0ab56cabb8cd41a4c54d38e9f
Author: volcano <vo...@163.com>
AuthorDate: Fri Sep 2 20:40:47 2022 +0800
Improve SGX Protected FS
---
sgx_protected_fs/tfs/src/capi.rs | 70 +++++++++++++++++++++--
sgx_protected_fs/tfs/src/fs.rs | 92 ++++++++++++++++++++++++-------
sgx_protected_fs/tfs/src/sys/file/mod.rs | 18 ++++--
sgx_protected_fs/tfs/src/sys/file/node.rs | 2 +-
sgx_protected_fs/tfs/src/sys/file/open.rs | 22 +++++++-
sgx_protected_fs/tfs/src/sys/metadata.rs | 11 ----
sgx_protected_fs/tfs/src/sys/mod.rs | 6 +-
sgx_protected_fs/ufs/src/lib.rs | 8 ++-
8 files changed, 185 insertions(+), 44 deletions(-)
diff --git a/sgx_protected_fs/tfs/src/capi.rs b/sgx_protected_fs/tfs/src/capi.rs
index 595f9224..39d93c45 100644
--- a/sgx_protected_fs/tfs/src/capi.rs
+++ b/sgx_protected_fs/tfs/src/capi.rs
@@ -37,11 +37,19 @@ pub unsafe extern "C" fn sgx_fopen(
mode: *const c_char,
key: *const Key128bit,
) -> RawProtectedFile {
- if filename.is_null() || mode.is_null() || key.is_null() {
+ if filename.is_null() || mode.is_null() {
eos!(EINVAL).set_errno();
return ptr::null_mut();
}
+ #[cfg(not(feature = "tfs"))]
+ {
+ if key.is_null() {
+ eos!(EINVAL).set_errno();
+ return ptr::null_mut();
+ }
+ }
+
let name = match CStr::from_ptr(filename).to_str() {
Ok(name) => name,
Err(_) => {
@@ -58,8 +66,12 @@ pub unsafe extern "C" fn sgx_fopen(
}
};
- let encrypt_mode = EncryptMode::EncryptWithIntegrity(*key);
- match SgxFile::open(name, &opts, &encrypt_mode) {
+ let encrypt_mode = if key.is_null() {
+ EncryptMode::EncryptAutoKey
+ } else {
+ EncryptMode::EncryptWithIntegrity(*key)
+ };
+ match SgxFile::open(name, &opts, &encrypt_mode, None) {
Ok(file) => file.into_raw(),
Err(_) => ptr::null_mut(),
}
@@ -94,7 +106,7 @@ pub unsafe extern "C" fn sgx_fopen_auto_key(
};
let encrypt_mode = EncryptMode::EncryptAutoKey;
- match SgxFile::open(name, &opts, &encrypt_mode) {
+ match SgxFile::open(name, &opts, &encrypt_mode, None) {
Ok(file) => file.into_raw(),
Err(_) => ptr::null_mut(),
}
@@ -128,7 +140,55 @@ pub unsafe extern "C" fn sgx_fopen_integrity_only(
};
let encrypt_mode = EncryptMode::IntegrityOnly;
- match SgxFile::open(name, &opts, &encrypt_mode) {
+ match SgxFile::open(name, &opts, &encrypt_mode, None) {
+ Ok(file) => file.into_raw(),
+ Err(_) => ptr::null_mut(),
+ }
+}
+
+/// # Safety
+#[no_mangle]
+pub unsafe extern "C" fn sgx_fopen_ex(
+ filename: *const c_char,
+ mode: *const c_char,
+ key: *const Key128bit,
+ cache_size: u64,
+) -> RawProtectedFile {
+ if filename.is_null() || mode.is_null() || cache_size < fs_imp::DEFAULT_CACHE_SIZE as u64 {
+ eos!(EINVAL).set_errno();
+ return ptr::null_mut();
+ }
+
+ #[cfg(not(feature = "tfs"))]
+ {
+ if key.is_null() {
+ eos!(EINVAL).set_errno();
+ return ptr::null_mut();
+ }
+ }
+
+ let name = match CStr::from_ptr(filename).to_str() {
+ Ok(name) => name,
+ Err(_) => {
+ eos!(EINVAL).set_errno();
+ return ptr::null_mut();
+ }
+ };
+
+ let opts = match parse_mode(CStr::from_ptr(mode)) {
+ Ok(mode) => mode,
+ Err(error) => {
+ error.set_errno();
+ return ptr::null_mut();
+ }
+ };
+
+ let encrypt_mode = if key.is_null() {
+ EncryptMode::EncryptAutoKey
+ } else {
+ EncryptMode::EncryptWithIntegrity(*key)
+ };
+ match SgxFile::open(name, &opts, &encrypt_mode, Some(cache_size as usize)) {
Ok(file) => file.into_raw(),
Err(_) => ptr::null_mut(),
}
diff --git a/sgx_protected_fs/tfs/src/fs.rs b/sgx_protected_fs/tfs/src/fs.rs
index 60e6f21b..c73de67f 100644
--- a/sgx_protected_fs/tfs/src/fs.rs
+++ b/sgx_protected_fs/tfs/src/fs.rs
@@ -41,6 +41,9 @@ cfg_if! {
#[derive(Clone, Debug)]
pub struct OpenOptions(fs_imp::OpenOptions);
+#[derive(Clone, Debug)]
+pub struct EncryptMode(fs_imp::EncryptMode);
+
/// A reference to an open Sgxfile on the filesystem.
///
/// An instance of a `SgxFile` can be read and/or written depending on what options
@@ -76,14 +79,14 @@ pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result
SgxFile::create(path)?.write_all(contents.as_ref())
}
-pub fn read_with_key<P: AsRef<Path>>(path: P, key: &Key128bit) -> io::Result<Vec<u8>> {
+pub fn read_with_key<P: AsRef<Path>>(path: P, key: Key128bit) -> io::Result<Vec<u8>> {
let mut file = SgxFile::open_with_key(path, key)?;
let mut bytes = Vec::with_capacity(buffer_capacity_required(&file));
file.read_to_end(&mut bytes)?;
Ok(bytes)
}
-pub fn read_to_string_with_key<P: AsRef<Path>>(path: P, key: &Key128bit) -> io::Result<String> {
+pub fn read_to_string_with_key<P: AsRef<Path>>(path: P, key: Key128bit) -> io::Result<String> {
let mut file = SgxFile::open_with_key(path, key)?;
let mut string = String::with_capacity(buffer_capacity_required(&file));
file.read_to_string(&mut string)?;
@@ -92,7 +95,7 @@ pub fn read_to_string_with_key<P: AsRef<Path>>(path: P, key: &Key128bit) -> io::
pub fn write_with_key<P: AsRef<Path>, C: AsRef<[u8]>>(
path: P,
- key: &Key128bit,
+ key: Key128bit,
contents: C,
) -> io::Result<()> {
SgxFile::create_with_key(path, key)?.write_all(contents.as_ref())
@@ -135,19 +138,19 @@ impl SgxFile {
OpenOptions::new().append(true).open(path.as_ref())
}
- pub fn open_with_key<P: AsRef<Path>>(path: P, key: &Key128bit) -> io::Result<SgxFile> {
+ pub fn open_with_key<P: AsRef<Path>>(path: P, key: Key128bit) -> io::Result<SgxFile> {
OpenOptions::new()
.read(true)
.open_with_key(path.as_ref(), key)
}
- pub fn create_with_key<P: AsRef<Path>>(path: P, key: &Key128bit) -> io::Result<SgxFile> {
+ pub fn create_with_key<P: AsRef<Path>>(path: P, key: Key128bit) -> io::Result<SgxFile> {
OpenOptions::new()
.write(true)
.open_with_key(path.as_ref(), key)
}
- pub fn append_with_key<P: AsRef<Path>>(path: P, key: &Key128bit) -> io::Result<SgxFile> {
+ pub fn append_with_key<P: AsRef<Path>>(path: P, key: Key128bit) -> io::Result<SgxFile> {
OpenOptions::new()
.append(true)
.open_with_key(path.as_ref(), key)
@@ -171,7 +174,37 @@ impl SgxFile {
.open_integrity_only(path.as_ref())
}
- pub fn with_options() -> OpenOptions {
+ pub fn open_with<P: AsRef<Path>>(
+ path: P,
+ encrypt_mode: EncryptMode,
+ cache_size: Option<usize>,
+ ) -> io::Result<SgxFile> {
+ OpenOptions::new()
+ .read(true)
+ .open_with(path.as_ref(), encrypt_mode, cache_size)
+ }
+
+ pub fn create_with<P: AsRef<Path>>(
+ path: P,
+ encrypt_mode: EncryptMode,
+ cache_size: Option<usize>,
+ ) -> io::Result<SgxFile> {
+ OpenOptions::new()
+ .write(true)
+ .open_with(path.as_ref(), encrypt_mode, cache_size)
+ }
+
+ pub fn append_with<P: AsRef<Path>>(
+ path: P,
+ encrypt_mode: EncryptMode,
+ cache_size: Option<usize>,
+ ) -> io::Result<SgxFile> {
+ OpenOptions::new()
+ .append(true)
+ .open_with(path.as_ref(), encrypt_mode, cache_size)
+ }
+
+ pub fn options() -> OpenOptions {
OpenOptions::new()
}
@@ -299,8 +332,8 @@ pub fn export_key<P: AsRef<Path>>(path: P) -> io::Result<Key128bit> {
}
#[cfg(feature = "tfs")]
-pub fn import_key<P: AsRef<Path>>(path: P, key: &Key128bit) -> io::Result<()> {
- fs_imp::import_key(path.as_ref(), *key)
+pub fn import_key<P: AsRef<Path>>(path: P, key: Key128bit) -> io::Result<()> {
+ fs_imp::import_key(path.as_ref(), key)
}
impl OpenOptions {
@@ -342,21 +375,24 @@ impl OpenOptions {
/// Opens a file at `path` with the options specified by `self`.
#[cfg(feature = "tfs")]
pub fn open<P: AsRef<Path>>(&self, path: P) -> io::Result<SgxFile> {
- let inner = fs_imp::SgxFile::open(path, &self.0, &fs_imp::EncryptMode::EncryptAutoKey)?;
- Ok(SgxFile { inner })
+ self.open_with(path, EncryptMode::with_auto_key(), None)
}
- pub fn open_with_key<P: AsRef<Path>>(&self, path: P, key: &Key128bit) -> io::Result<SgxFile> {
- let inner = fs_imp::SgxFile::open(
- path,
- &self.0,
- &fs_imp::EncryptMode::EncryptWithIntegrity(*key),
- )?;
- Ok(SgxFile { inner })
+ pub fn open_with_key<P: AsRef<Path>>(&self, path: P, key: Key128bit) -> io::Result<SgxFile> {
+ self.open_with(path, EncryptMode::with_user_key(key), None)
}
pub fn open_integrity_only<P: AsRef<Path>>(&self, path: P) -> io::Result<SgxFile> {
- let inner = fs_imp::SgxFile::open(path, &self.0, &fs_imp::EncryptMode::IntegrityOnly)?;
+ self.open_with(path, EncryptMode::integrity_only(), None)
+ }
+
+ pub fn open_with<P: AsRef<Path>>(
+ &self,
+ path: P,
+ encrypt_mode: EncryptMode,
+ cache_size: Option<usize>,
+ ) -> io::Result<SgxFile> {
+ let inner = fs_imp::SgxFile::open(path, &self.0, &encrypt_mode.0, cache_size)?;
Ok(SgxFile { inner })
}
}
@@ -366,3 +402,21 @@ impl Default for OpenOptions {
Self::new()
}
}
+
+impl EncryptMode {
+ #[cfg(feature = "tfs")]
+ #[inline]
+ pub fn with_auto_key() -> EncryptMode {
+ EncryptMode(fs_imp::EncryptMode::EncryptAutoKey)
+ }
+
+ #[inline]
+ pub fn with_user_key(key: Key128bit) -> EncryptMode {
+ EncryptMode(fs_imp::EncryptMode::EncryptWithIntegrity(key))
+ }
+
+ #[inline]
+ pub fn integrity_only() -> EncryptMode {
+ EncryptMode(fs_imp::EncryptMode::IntegrityOnly)
+ }
+}
diff --git a/sgx_protected_fs/tfs/src/sys/file/mod.rs b/sgx_protected_fs/tfs/src/sys/file/mod.rs
index 986f8138..162d7d02 100644
--- a/sgx_protected_fs/tfs/src/sys/file/mod.rs
+++ b/sgx_protected_fs/tfs/src/sys/file/mod.rs
@@ -30,6 +30,8 @@ use std::path::Path;
use std::path::PathBuf;
use std::sync::Mutex;
+pub use open::DEFAULT_CACHE_SIZE;
+
mod close;
mod flush;
mod node;
@@ -43,8 +45,6 @@ pub struct ProtectedFile {
file: Mutex<FileInner>,
}
-const MAX_PAGES_IN_CACHE: usize = 48;
-
#[derive(Debug)]
struct FileInner {
host_file: HostFile,
@@ -54,6 +54,7 @@ struct FileInner {
opts: OpenOptions,
need_writing: bool,
end_of_file: bool,
+ max_cache_page: usize,
offset: usize,
last_error: FsError,
status: FileStatus,
@@ -62,8 +63,13 @@ struct FileInner {
}
impl ProtectedFile {
- pub fn open<P: AsRef<Path>>(path: P, opts: &OpenOptions, mode: &OpenMode) -> FsResult<Self> {
- let file = FileInner::open(path.as_ref(), opts, mode)?;
+ pub fn open<P: AsRef<Path>>(
+ path: P,
+ opts: &OpenOptions,
+ mode: &OpenMode,
+ cache_size: Option<usize>,
+ ) -> FsResult<Self> {
+ let file = FileInner::open(path.as_ref(), opts, mode, cache_size)?;
Ok(Self {
file: Mutex::new(file),
})
@@ -270,6 +276,7 @@ impl ProtectedFile {
path.as_ref(),
&OpenOptions::new().read(true),
&OpenMode::AutoKey,
+ None,
)?;
file.close(CloseMode::Export).map(|key| key.unwrap())
}
@@ -280,6 +287,7 @@ impl ProtectedFile {
path.as_ref(),
&OpenOptions::new().read(true).update(true),
&OpenMode::ImportKey(key),
+ None,
)?;
file.close(CloseMode::Import).map(|_| ())
}
@@ -418,6 +426,7 @@ impl OpenMode {
impl From<EncryptMode> for OpenMode {
fn from(encrypt_mode: EncryptMode) -> OpenMode {
match encrypt_mode {
+ #[cfg(feature = "tfs")]
EncryptMode::EncryptAutoKey => Self::AutoKey,
EncryptMode::EncryptWithIntegrity(key) => Self::UserKey(key),
EncryptMode::IntegrityOnly => Self::IntegrityOnly,
@@ -428,6 +437,7 @@ impl From<EncryptMode> for OpenMode {
impl From<&EncryptMode> for OpenMode {
fn from(encrypt_mode: &EncryptMode) -> OpenMode {
match encrypt_mode {
+ #[cfg(feature = "tfs")]
EncryptMode::EncryptAutoKey => Self::AutoKey,
EncryptMode::EncryptWithIntegrity(key) => Self::UserKey(*key),
EncryptMode::IntegrityOnly => Self::IntegrityOnly,
diff --git a/sgx_protected_fs/tfs/src/sys/file/node.rs b/sgx_protected_fs/tfs/src/sys/file/node.rs
index b3f53914..24ad03c4 100644
--- a/sgx_protected_fs/tfs/src/sys/file/node.rs
+++ b/sgx_protected_fs/tfs/src/sys/file/node.rs
@@ -187,7 +187,7 @@ impl FileInner {
}
fn shrink_cache(&mut self) -> FsResult {
- while self.cache.len() > super::MAX_PAGES_IN_CACHE {
+ while self.cache.len() > self.max_cache_page {
let node = self.cache.back().ok_or(SgxStatus::Unexpected)?;
if !node.borrow().need_writing {
let _node = self.cache.pop_back();
diff --git a/sgx_protected_fs/tfs/src/sys/file/open.rs b/sgx_protected_fs/tfs/src/sys/file/open.rs
index 193d8c9d..ddd1f8b8 100644
--- a/sgx_protected_fs/tfs/src/sys/file/open.rs
+++ b/sgx_protected_fs/tfs/src/sys/file/open.rs
@@ -28,12 +28,29 @@ use crate::sys::node::{FileNode, FileNodeRef};
use sgx_types::error::errno::*;
use sgx_types::error::SgxStatus;
use sgx_types::memeq::ConstTimeEq;
+use sgx_types::metadata::SE_PAGE_SIZE;
use sgx_types::types::Key128bit;
use std::borrow::ToOwned;
use std::path::Path;
+macro_rules! is_page_aligned {
+ ($num:expr) => {
+ $num & (SE_PAGE_SIZE - 1) == 0
+ };
+}
+
+pub const DEFAULT_CACHE_SIZE: usize = 48 * SE_PAGE_SIZE;
+
impl FileInner {
- pub fn open(path: &Path, opts: &OpenOptions, mode: &OpenMode) -> FsResult<Self> {
+ pub fn open(
+ path: &Path,
+ opts: &OpenOptions,
+ mode: &OpenMode,
+ cache_size: Option<usize>,
+ ) -> FsResult<Self> {
+ let cache_size = cache_size.unwrap_or(DEFAULT_CACHE_SIZE);
+ ensure!(is_page_aligned!(cache_size), eos!(EINVAL));
+
let file_name = path.file_name().ok_or(EINVAL)?.to_str().ok_or(EINVAL)?;
Self::check_open_param(path, file_name, opts, mode)?;
@@ -86,11 +103,12 @@ impl FileInner {
opts: *opts,
need_writing,
end_of_file: false,
+ max_cache_page: cache_size,
offset,
last_error: esgx!(SgxStatus::Success),
status: FileStatus::NotInitialized,
recovery_path,
- cache: LruCache::new(super::MAX_PAGES_IN_CACHE),
+ cache: LruCache::new(cache_size),
};
protected_file.status = FileStatus::Ok;
diff --git a/sgx_protected_fs/tfs/src/sys/metadata.rs b/sgx_protected_fs/tfs/src/sys/metadata.rs
index 439012cb..42c14dc0 100644
--- a/sgx_protected_fs/tfs/src/sys/metadata.rs
+++ b/sgx_protected_fs/tfs/src/sys/metadata.rs
@@ -20,7 +20,6 @@ use crate::sys::file::OpenMode;
use crate::sys::host::HostFs;
use crate::sys::keys::{DeriveKey, KeyType, RestoreKey};
use crate::sys::node::{META_DATA_PHY_NUM, NODE_SIZE};
-use crate::sys::EncryptMode;
use sgx_crypto::aes::gcm::{Aad, AesGcm, Nonce};
use sgx_types::error::SgxStatus;
use sgx_types::types::{Attributes, CpuSvn, Key128bit, KeyId, Mac128bit};
@@ -74,16 +73,6 @@ impl From<&OpenMode> for EncryptFlags {
}
}
-impl From<&EncryptMode> for EncryptFlags {
- fn from(mode: &EncryptMode) -> Self {
- match mode {
- EncryptMode::EncryptAutoKey => Self::AutoKey,
- EncryptMode::EncryptWithIntegrity(_) => Self::UserKey,
- EncryptMode::IntegrityOnly => Self::IntegrityOnly,
- }
- }
-}
-
#[derive(Clone, Copy, Debug, Default)]
#[repr(C, packed)]
pub struct MetadataPlain {
diff --git a/sgx_protected_fs/tfs/src/sys/mod.rs b/sgx_protected_fs/tfs/src/sys/mod.rs
index 770bccf6..8744cd2a 100644
--- a/sgx_protected_fs/tfs/src/sys/mod.rs
+++ b/sgx_protected_fs/tfs/src/sys/mod.rs
@@ -23,6 +23,8 @@ use std::io::{Result, SeekFrom};
use std::mem::ManuallyDrop;
use std::path::Path;
+pub use file::DEFAULT_CACHE_SIZE;
+
#[macro_use]
pub(crate) mod error;
#[macro_use]
@@ -39,6 +41,7 @@ pub struct OpenOptions(file_imp::OpenOptions);
#[derive(Clone, Debug)]
pub enum EncryptMode {
+ #[cfg(feature = "tfs")]
EncryptAutoKey,
EncryptWithIntegrity(Key128bit),
IntegrityOnly,
@@ -89,9 +92,10 @@ impl SgxFile {
path: P,
opts: &OpenOptions,
encrypt_mode: &EncryptMode,
+ cache_size: Option<usize>,
) -> Result<SgxFile> {
opts.check_access_mode()?;
- ProtectedFile::open(path, &opts.0, &From::from(encrypt_mode))
+ ProtectedFile::open(path, &opts.0, &encrypt_mode.into(), cache_size)
.map_err(|e| {
e.set_errno();
e.to_io_error()
diff --git a/sgx_protected_fs/ufs/src/lib.rs b/sgx_protected_fs/ufs/src/lib.rs
index 6ff08118..5054ee78 100644
--- a/sgx_protected_fs/ufs/src/lib.rs
+++ b/sgx_protected_fs/ufs/src/lib.rs
@@ -110,7 +110,12 @@ impl HostFile {
}
pub fn flush(&mut self) -> OsResult {
- self.stream.flush()
+ self.stream.flush()?;
+ if unsafe { libc::fsync(self.fd) } == 0 {
+ Ok(())
+ } else {
+ Err(errno())
+ }
}
pub fn size(&self) -> OsResult<usize> {
@@ -144,6 +149,7 @@ impl Drop for HostFile {
fn drop(&mut self) {
unsafe {
libc::flock(self.fd, libc::LOCK_UN);
+ libc::fsync(self.fd);
}
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org