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/29 03:05:39 UTC

[incubator-teaclave-sgx-sdk] branch v2.0.0-preview updated: Protected_fs supports the specified key policy

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 4ad7cc95 Protected_fs supports the specified key policy
4ad7cc95 is described below

commit 4ad7cc9583bf026509ae64ccbd1eb789d02e6c4d
Author: volcano <vo...@163.com>
AuthorDate: Thu Sep 29 11:05:26 2022 +0800

    Protected_fs supports the specified key policy
---
 sgx_protected_fs/tfs/src/capi.rs          |  70 +++++++++++++-------
 sgx_protected_fs/tfs/src/fs.rs            |  23 ++++---
 sgx_protected_fs/tfs/src/sys/file/mod.rs  |  63 ++++++++++++++----
 sgx_protected_fs/tfs/src/sys/file/open.rs |  24 +++++--
 sgx_protected_fs/tfs/src/sys/keys.rs      | 106 +++++++++++++++++++++---------
 sgx_protected_fs/tfs/src/sys/metadata.rs  |  45 ++++++++-----
 sgx_protected_fs/tfs/src/sys/mod.rs       |  26 +++++---
 sgx_protected_fs/tfs/src/sys/node.rs      |   8 +--
 8 files changed, 254 insertions(+), 111 deletions(-)

diff --git a/sgx_protected_fs/tfs/src/capi.rs b/sgx_protected_fs/tfs/src/capi.rs
index 39d93c45..77fd69f4 100644
--- a/sgx_protected_fs/tfs/src/capi.rs
+++ b/sgx_protected_fs/tfs/src/capi.rs
@@ -19,6 +19,8 @@ use crate::sys::error::FsResult;
 use crate::sys::{self as fs_imp, EncryptMode, OpenOptions, RawProtectedFile, SgxFile};
 use sgx_types::error::errno::*;
 use sgx_types::types::c_char;
+#[cfg(feature = "tfs")]
+use sgx_types::types::KeyPolicy;
 use sgx_types::types::{Key128bit, Mac128bit};
 use std::ffi::CStr;
 use std::io::SeekFrom;
@@ -42,14 +44,6 @@ pub unsafe extern "C" fn sgx_fopen(
         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(_) => {
@@ -67,9 +61,16 @@ pub unsafe extern "C" fn sgx_fopen(
     };
 
     let encrypt_mode = if key.is_null() {
-        EncryptMode::EncryptAutoKey
+        cfg_if! {
+            if #[cfg(feature = "tfs")] {
+                EncryptMode::EncryptAutoKey(KeyPolicy::MRSIGNER)
+            } else {
+                eos!(EINVAL).set_errno();
+                return ptr::null_mut();
+            }
+        }
     } else {
-        EncryptMode::EncryptWithIntegrity(*key)
+        EncryptMode::EncryptUserKey(*key)
     };
     match SgxFile::open(name, &opts, &encrypt_mode, None) {
         Ok(file) => file.into_raw(),
@@ -105,7 +106,7 @@ pub unsafe extern "C" fn sgx_fopen_auto_key(
         }
     };
 
-    let encrypt_mode = EncryptMode::EncryptAutoKey;
+    let encrypt_mode = EncryptMode::EncryptAutoKey(KeyPolicy::MRSIGNER);
     match SgxFile::open(name, &opts, &encrypt_mode, None) {
         Ok(file) => file.into_raw(),
         Err(_) => ptr::null_mut(),
@@ -147,11 +148,13 @@ pub unsafe extern "C" fn sgx_fopen_integrity_only(
 }
 
 /// # Safety
+#[allow(unused_variables)]
 #[no_mangle]
 pub unsafe extern "C" fn sgx_fopen_ex(
     filename: *const c_char,
     mode: *const c_char,
     key: *const Key128bit,
+    key_policy: u16,
     cache_size: u64,
 ) -> RawProtectedFile {
     if filename.is_null() || mode.is_null() || cache_size < fs_imp::DEFAULT_CACHE_SIZE as u64 {
@@ -159,14 +162,6 @@ pub unsafe extern "C" fn sgx_fopen_ex(
         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(_) => {
@@ -184,9 +179,27 @@ pub unsafe extern "C" fn sgx_fopen_ex(
     };
 
     let encrypt_mode = if key.is_null() {
-        EncryptMode::EncryptAutoKey
+        cfg_if! {
+            if #[cfg(feature = "tfs")] {
+                let key_policy = if key_policy != 0 {
+                    match KeyPolicy::from_bits(key_policy) {
+                        Some(key_policy) => key_policy,
+                        None => {
+                            eos!(EINVAL).set_errno();
+                            return ptr::null_mut();
+                        }
+                    }
+                } else {
+                    KeyPolicy::MRSIGNER
+                };
+                EncryptMode::EncryptAutoKey(key_policy)
+            } else {
+                eos!(EINVAL).set_errno();
+                return ptr::null_mut();
+            }
+        }
     } else {
-        EncryptMode::EncryptWithIntegrity(*key)
+        EncryptMode::EncryptUserKey(*key)
     };
     match SgxFile::open(name, &opts, &encrypt_mode, Some(cache_size as usize)) {
         Ok(file) => file.into_raw(),
@@ -493,6 +506,7 @@ pub unsafe extern "C" fn sgx_fexport_auto_key(
 pub unsafe extern "C" fn sgx_fimport_auto_key(
     filename: *const c_char,
     import_key: *const Key128bit,
+    key_policy: u16,
 ) -> i32 {
     if filename.is_null() || import_key.is_null() {
         eos!(EINVAL).set_errno();
@@ -507,7 +521,19 @@ pub unsafe extern "C" fn sgx_fimport_auto_key(
         }
     };
 
-    match fs_imp::import_key(name, *import_key) {
+    let key_policy = if key_policy != 0 {
+        match KeyPolicy::from_bits(key_policy) {
+            Some(key_policy) => key_policy,
+            None => {
+                eos!(EINVAL).set_errno();
+                return -1;
+            }
+        }
+    } else {
+        KeyPolicy::MRSIGNER
+    };
+
+    match fs_imp::import_key(name, *import_key, key_policy) {
         Ok(_) => 0,
         Err(_) => -1,
     }
diff --git a/sgx_protected_fs/tfs/src/fs.rs b/sgx_protected_fs/tfs/src/fs.rs
index c73de67f..732b8831 100644
--- a/sgx_protected_fs/tfs/src/fs.rs
+++ b/sgx_protected_fs/tfs/src/fs.rs
@@ -28,6 +28,7 @@ cfg_if! {
         use sgx_rsrvmm::map::Map;
         use sgx_types::error::errno::ESGX;
         use sgx_types::error::OsResult;
+        use sgx_types::types::KeyPolicy;
     }
 }
 
@@ -332,8 +333,12 @@ 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,
+    key_policy: Option<KeyPolicy>,
+) -> io::Result<()> {
+    fs_imp::import_key(path.as_ref(), key, key_policy)
 }
 
 impl OpenOptions {
@@ -375,11 +380,11 @@ 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> {
-        self.open_with(path, EncryptMode::with_auto_key(), None)
+        self.open_with(path, EncryptMode::auto_key(None), None)
     }
 
     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)
+        self.open_with(path, EncryptMode::user_key(key), None)
     }
 
     pub fn open_integrity_only<P: AsRef<Path>>(&self, path: P) -> io::Result<SgxFile> {
@@ -406,13 +411,15 @@ impl Default for OpenOptions {
 impl EncryptMode {
     #[cfg(feature = "tfs")]
     #[inline]
-    pub fn with_auto_key() -> EncryptMode {
-        EncryptMode(fs_imp::EncryptMode::EncryptAutoKey)
+    pub fn auto_key(key_policy: Option<KeyPolicy>) -> EncryptMode {
+        EncryptMode(fs_imp::EncryptMode::EncryptAutoKey(
+            key_policy.unwrap_or(KeyPolicy::MRSIGNER),
+        ))
     }
 
     #[inline]
-    pub fn with_user_key(key: Key128bit) -> EncryptMode {
-        EncryptMode(fs_imp::EncryptMode::EncryptWithIntegrity(key))
+    pub fn user_key(key: Key128bit) -> EncryptMode {
+        EncryptMode(fs_imp::EncryptMode::EncryptUserKey(key))
     }
 
     #[inline]
diff --git a/sgx_protected_fs/tfs/src/sys/file/mod.rs b/sgx_protected_fs/tfs/src/sys/file/mod.rs
index 162d7d02..9d9ba9cc 100644
--- a/sgx_protected_fs/tfs/src/sys/file/mod.rs
+++ b/sgx_protected_fs/tfs/src/sys/file/mod.rs
@@ -24,7 +24,7 @@ use crate::sys::node::{FileNode, FileNodeRef};
 use crate::sys::EncryptMode;
 use sgx_types::error::errno::*;
 use sgx_types::error::SgxStatus;
-use sgx_types::types::{Key128bit, Mac128bit};
+use sgx_types::types::{Key128bit, KeyPolicy, Mac128bit};
 use std::io::SeekFrom;
 use std::path::Path;
 use std::path::PathBuf;
@@ -275,18 +275,22 @@ impl ProtectedFile {
         let mut file = FileInner::open(
             path.as_ref(),
             &OpenOptions::new().read(true),
-            &OpenMode::AutoKey,
+            &OpenMode::ExportKey,
             None,
         )?;
         file.close(CloseMode::Export).map(|key| key.unwrap())
     }
 
     #[cfg(feature = "tfs")]
-    pub fn import_key<P: AsRef<Path>>(path: P, key: Key128bit) -> FsResult {
+    pub fn import_key<P: AsRef<Path>>(
+        path: P,
+        key: Key128bit,
+        key_policy: Option<KeyPolicy>,
+    ) -> FsResult {
         let mut file = FileInner::open(
             path.as_ref(),
             &OpenOptions::new().read(true).update(true),
-            &OpenMode::ImportKey(key),
+            &OpenMode::ImportKey((key, key_policy.unwrap_or(KeyPolicy::MRSIGNER))),
             None,
         )?;
         file.close(CloseMode::Import).map(|_| ())
@@ -371,7 +375,7 @@ impl OpenOptions {
         self.read && !self.update
     }
 
-    pub fn check_access_mode(&self) -> FsResult {
+    pub fn check(&self) -> FsResult {
         match (self.read, self.write, self.append) {
             (true, false, false) => Ok(()),
             (false, true, false) => Ok(()),
@@ -389,16 +393,17 @@ impl Default for OpenOptions {
 
 #[derive(Clone, Debug, Eq, PartialEq)]
 pub enum OpenMode {
-    AutoKey,
+    AutoKey(KeyPolicy),
     UserKey(Key128bit),
     IntegrityOnly,
-    ImportKey(Key128bit),
+    ImportKey((Key128bit, KeyPolicy)),
+    ExportKey,
 }
 
 impl OpenMode {
     #[inline]
     pub fn is_auto_key(&self) -> bool {
-        matches!(*self, Self::AutoKey)
+        matches!(*self, Self::AutoKey(_))
     }
 
     #[inline]
@@ -406,6 +411,16 @@ impl OpenMode {
         matches!(*self, Self::IntegrityOnly)
     }
 
+    #[inline]
+    pub fn is_import_key(&self) -> bool {
+        matches!(*self, Self::ImportKey(_))
+    }
+
+    #[inline]
+    pub fn is_export_key(&self) -> bool {
+        matches!(*self, Self::ExportKey)
+    }
+
     #[inline]
     pub fn user_key(&self) -> Option<&Key128bit> {
         match self {
@@ -417,18 +432,40 @@ impl OpenMode {
     #[inline]
     pub fn import_key(&self) -> Option<&Key128bit> {
         match self {
-            Self::ImportKey(key) => Some(key),
+            Self::ImportKey((key, _)) => Some(key),
             _ => None,
         }
     }
+
+    #[inline]
+    pub fn key_policy(&self) -> Option<KeyPolicy> {
+        match self {
+            Self::AutoKey(key_policy) | Self::ImportKey((_, key_policy)) => Some(*key_policy),
+            _ => None,
+        }
+    }
+
+    pub fn check(&self) -> FsResult {
+        match self {
+            Self::AutoKey(key_policy) | Self::ImportKey((_, key_policy)) => {
+                ensure!(key_policy.is_valid(), eos!(EINVAL));
+                ensure!(
+                    key_policy.intersects(KeyPolicy::MRENCLAVE | KeyPolicy::MRSIGNER),
+                    eos!(EINVAL)
+                );
+                Ok(())
+            }
+            _ => Ok(()),
+        }
+    }
 }
 
 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::EncryptAutoKey(key_policy) => Self::AutoKey(key_policy),
+            EncryptMode::EncryptUserKey(key) => Self::UserKey(key),
             EncryptMode::IntegrityOnly => Self::IntegrityOnly,
         }
     }
@@ -438,8 +475,8 @@ 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::EncryptAutoKey(key_policy) => Self::AutoKey(*key_policy),
+            EncryptMode::EncryptUserKey(key) => Self::UserKey(*key),
             EncryptMode::IntegrityOnly => Self::IntegrityOnly,
         }
     }
diff --git a/sgx_protected_fs/tfs/src/sys/file/open.rs b/sgx_protected_fs/tfs/src/sys/file/open.rs
index 04232403..4b398719 100644
--- a/sgx_protected_fs/tfs/src/sys/file/open.rs
+++ b/sgx_protected_fs/tfs/src/sys/file/open.rs
@@ -52,7 +52,7 @@ impl FileInner {
         let file_name = path.file_name().ok_or(EINVAL)?.to_str().ok_or(EINVAL)?;
         Self::check_open_param(path, file_name, opts, mode)?;
 
-        let key_gen = FsKeyGen::new(mode.user_key().cloned())?;
+        let key_gen = FsKeyGen::new(mode)?;
 
         Self::check_file_exist(opts, mode, path)?;
 
@@ -135,10 +135,18 @@ impl FileInner {
         let encrypt_flags = mode.into();
         ensure!(encrypt_flags == metadata.encrypt_flags(), eos!(EINVAL));
 
-        let key = mode
-            .import_key()
-            .cloned()
-            .unwrap_or(metadata.restore_key(key_gen)?);
+        let key_policy = mode.key_policy();
+        if mode.is_auto_key() {
+            ensure!(key_policy.unwrap() == metadata.key_policy(), eos!(EINVAL));
+        }
+
+        let key = match mode.import_key() {
+            Some(key) => {
+                metadata.set_key_policy(key_policy.unwrap());
+                *key
+            }
+            None => metadata.restore_key(key_gen)?,
+        };
         metadata.decrypt(&key)?;
 
         let meta_file_name = metadata.file_name()?;
@@ -161,6 +169,9 @@ impl FileInner {
         let mut metadata = MetadataInfo::new();
 
         metadata.set_encrypt_flags(mode.into());
+        if let Some(key_policy) = mode.key_policy() {
+            metadata.set_key_policy(key_policy);
+        }
         metadata.encrypted_plain.file_name[0..file_name.len()]
             .copy_from_slice(file_name.as_bytes());
 
@@ -212,7 +223,8 @@ impl FileInner {
         ensure!(name_len > 0, eos!(EINVAL));
         ensure!(name_len < FILENAME_MAX_LEN - 1, eos!(ENAMETOOLONG));
 
-        opts.check_access_mode()?;
+        opts.check()?;
+        mode.check()?;
 
         if let Some(key) = mode.import_key() {
             ensure!(key.ct_ne(&Key128bit::default()), eos!(EINVAL));
diff --git a/sgx_protected_fs/tfs/src/sys/keys.rs b/sgx_protected_fs/tfs/src/sys/keys.rs
index 0c5765fd..fa17e453 100644
--- a/sgx_protected_fs/tfs/src/sys/keys.rs
+++ b/sgx_protected_fs/tfs/src/sys/keys.rs
@@ -16,6 +16,7 @@
 // under the License..
 
 use crate::sys::error::FsResult;
+use crate::sys::file::OpenMode;
 use sgx_crypto::mac::AesCMac;
 use sgx_rand::{RdRand, Rng};
 #[cfg(feature = "tfs")]
@@ -23,12 +24,10 @@ use sgx_tse::{EnclaveKey, EnclaveReport};
 use sgx_types::error::errno::*;
 use sgx_types::marker::ContiguousMemory;
 #[cfg(feature = "tfs")]
-use sgx_types::types::Report;
-#[cfg(feature = "tfs")]
 use sgx_types::types::{
-    Attributes, AttributesFlags, KeyName, KeyPolicy, KeyRequest, TSEAL_DEFAULT_MISCMASK,
+    Attributes, AttributesFlags, KeyName, KeyRequest, Report, TSEAL_DEFAULT_MISCMASK,
 };
-use sgx_types::types::{CpuSvn, Key128bit, KeyId};
+use sgx_types::types::{CpuSvn, Key128bit, KeyId, KeyPolicy};
 #[cfg(feature = "tfs")]
 use std::boxed::Box;
 
@@ -41,6 +40,7 @@ pub trait RestoreKey {
         &self,
         key_type: KeyType,
         key_id: KeyId,
+        key_policy: Option<KeyPolicy>,
         cpu_svn: Option<CpuSvn>,
         isv_svn: Option<u16>,
     ) -> FsResult<Key128bit>;
@@ -54,7 +54,7 @@ pub enum KeyType {
 }
 
 #[derive(Clone, Debug, Default)]
-struct MasterKey {
+pub struct MasterKey {
     key: Key128bit,
     key_id: KeyId,
     count: u32,
@@ -100,6 +100,7 @@ impl RestoreKey for MasterKey {
         &self,
         _key_type: KeyType,
         _key_id: KeyId,
+        _key_policy: Option<KeyPolicy>,
         _cpu_svn: Option<CpuSvn>,
         _isv_svn: Option<u16>,
     ) -> FsResult<Key128bit> {
@@ -115,20 +116,27 @@ impl Drop for MasterKey {
 }
 
 #[derive(Clone, Debug)]
-enum MetadataKey {
+pub enum MetadataKey {
     UserKey(Key128bit),
     #[cfg(feature = "tfs")]
-    CpuKey(Box<Report>),
+    AutoKey {
+        report: Box<Report>,
+        key_policy: Option<KeyPolicy>,
+    },
 }
 
 impl MetadataKey {
-    fn new(user_key: Option<Key128bit>) -> FsResult<MetadataKey> {
+    #[allow(unused_variables)]
+    fn new(user_key: Option<Key128bit>, key_policy: Option<KeyPolicy>) -> FsResult<MetadataKey> {
         if let Some(user_key) = user_key {
             Ok(Self::UserKey(user_key))
         } else {
             cfg_if! {
                 if #[cfg(feature = "tfs")] {
-                    Ok(Self::CpuKey(Box::new(*Report::get_self())))
+                    Ok(Self::AutoKey {
+                        report: Box::new(*Report::get_self()),
+                        key_policy,
+                    })
                 } else {
                     Err(eos!(ENOTSUP))
                 }
@@ -144,14 +152,17 @@ impl DeriveKey for MetadataKey {
         match self {
             Self::UserKey(ref user_key) => KdfInput::derive_key(user_key, KeyType::Metadata, 0),
             #[cfg(feature = "tfs")]
-            Self::CpuKey(ref report) => {
+            Self::AutoKey {
+                ref report,
+                ref key_policy,
+            } => {
                 let mut rng = RdRand::new().map_err(|_| ENOTSUP)?;
                 let mut key_id = KeyId::default();
                 rng.fill_bytes(key_id.as_mut());
 
                 let key_request = KeyRequest {
                     key_name: KeyName::Seal,
-                    key_policy: KeyPolicy::MRSIGNER,
+                    key_policy: key_policy.unwrap_or(KeyPolicy::MRSIGNER),
                     isv_svn: report.body.isv_svn,
                     cpu_svn: report.body.cpu_svn,
                     attribute_mask: Attributes {
@@ -175,6 +186,7 @@ impl RestoreKey for MetadataKey {
         &self,
         key_type: KeyType,
         key_id: KeyId,
+        key_policy: Option<KeyPolicy>,
         cpu_svn: Option<CpuSvn>,
         isv_svn: Option<u16>,
     ) -> FsResult<Key128bit> {
@@ -185,13 +197,13 @@ impl RestoreKey for MetadataKey {
                 KdfInput::restore_key(user_key, KeyType::Metadata, 0, key_id)
             }
             #[cfg(feature = "tfs")]
-            Self::CpuKey(_) => {
+            Self::AutoKey { .. } => {
                 let cpu_svn = cpu_svn.ok_or(EINVAL)?;
                 let isv_svn = isv_svn.ok_or(EINVAL)?;
 
                 let key_request = KeyRequest {
                     key_name: KeyName::Seal,
-                    key_policy: KeyPolicy::MRSIGNER,
+                    key_policy: key_policy.unwrap_or(KeyPolicy::MRSIGNER),
                     isv_svn,
                     cpu_svn,
                     attribute_mask: Attributes {
@@ -214,7 +226,7 @@ impl Drop for MetadataKey {
         match self {
             Self::UserKey(ref mut key) => key.fill(0),
             #[cfg(feature = "tfs")]
-            Self::CpuKey(_) => {}
+            Self::AutoKey { .. } => {}
         }
     }
 }
@@ -294,26 +306,47 @@ impl KdfInput {
 }
 
 #[derive(Clone, Debug)]
-pub struct FsKeyGen {
-    master_key: MasterKey,
-    metadata_key: MetadataKey,
+pub enum FsKeyGen {
+    EncryptWithIntegrity(MetadataKey, MasterKey),
+    IntegrityOnly,
+    Import(MetadataKey),
+    Export(MetadataKey),
 }
 
 impl FsKeyGen {
-    pub fn new(user_key: Option<Key128bit>) -> FsResult<FsKeyGen> {
-        Ok(Self {
-            master_key: MasterKey::new()?,
-            metadata_key: MetadataKey::new(user_key)?,
-        })
+    pub fn new(mode: &OpenMode) -> FsResult<FsKeyGen> {
+        match mode {
+            OpenMode::AutoKey(key_policy) => Ok(Self::EncryptWithIntegrity(
+                MetadataKey::new(None, Some(*key_policy))?,
+                MasterKey::new()?,
+            )),
+            OpenMode::UserKey(user_key) => Ok(Self::EncryptWithIntegrity(
+                MetadataKey::new(Some(*user_key), None)?,
+                MasterKey::new()?,
+            )),
+            OpenMode::IntegrityOnly => Ok(Self::IntegrityOnly),
+            OpenMode::ImportKey((_, key_policy)) => {
+                Ok(Self::Import(MetadataKey::new(None, Some(*key_policy))?))
+            }
+            OpenMode::ExportKey => Ok(Self::Export(MetadataKey::new(None, None)?)),
+        }
     }
 }
 
 impl DeriveKey for FsKeyGen {
     fn derive_key(&mut self, key_type: KeyType, node_number: u64) -> FsResult<(Key128bit, KeyId)> {
-        match key_type {
-            KeyType::Metadata => self.metadata_key.derive_key(KeyType::Metadata, 0),
-            KeyType::Master => self.master_key.derive_key(KeyType::Master, 0),
-            KeyType::Random => self.master_key.derive_key(KeyType::Random, node_number),
+        match self {
+            Self::EncryptWithIntegrity(metadata_key, master_key) => match key_type {
+                KeyType::Metadata => metadata_key.derive_key(KeyType::Metadata, 0),
+                KeyType::Master => master_key.derive_key(KeyType::Master, 0),
+                KeyType::Random => master_key.derive_key(KeyType::Random, node_number),
+            },
+            Self::IntegrityOnly => Ok((Key128bit::default(), KeyId::default())),
+            Self::Import(metadata_key) => {
+                ensure!(key_type == KeyType::Metadata, eos!(EINVAL));
+                metadata_key.derive_key(KeyType::Metadata, 0)
+            }
+            Self::Export(_) => Err(eos!(EINVAL)),
         }
     }
 }
@@ -323,12 +356,25 @@ impl RestoreKey for FsKeyGen {
         &self,
         key_type: KeyType,
         key_id: KeyId,
+        key_policy: Option<KeyPolicy>,
         cpu_svn: Option<CpuSvn>,
         isv_svn: Option<u16>,
     ) -> FsResult<Key128bit> {
-        ensure!(key_type == KeyType::Metadata, eos!(EINVAL));
-
-        self.metadata_key
-            .restore_key(key_type, key_id, cpu_svn, isv_svn)
+        match self {
+            Self::EncryptWithIntegrity(metadata_key, _) => match key_type {
+                KeyType::Metadata => {
+                    metadata_key.restore_key(key_type, key_id, key_policy, cpu_svn, isv_svn)
+                }
+                KeyType::Master | KeyType::Random => Err(eos!(EINVAL)),
+            },
+            Self::IntegrityOnly => Ok(Key128bit::default()),
+            Self::Import(_) => Err(eos!(EINVAL)),
+            Self::Export(metadata_key) => match key_type {
+                KeyType::Metadata => {
+                    metadata_key.restore_key(key_type, key_id, key_policy, cpu_svn, isv_svn)
+                }
+                KeyType::Master | KeyType::Random => Err(eos!(EINVAL)),
+            },
+        }
     }
 }
diff --git a/sgx_protected_fs/tfs/src/sys/metadata.rs b/sgx_protected_fs/tfs/src/sys/metadata.rs
index 42c14dc0..a8231f7f 100644
--- a/sgx_protected_fs/tfs/src/sys/metadata.rs
+++ b/sgx_protected_fs/tfs/src/sys/metadata.rs
@@ -22,7 +22,7 @@ use crate::sys::keys::{DeriveKey, KeyType, RestoreKey};
 use crate::sys::node::{META_DATA_PHY_NUM, NODE_SIZE};
 use sgx_crypto::aes::gcm::{Aad, AesGcm, Nonce};
 use sgx_types::error::SgxStatus;
-use sgx_types::types::{Attributes, CpuSvn, Key128bit, KeyId, Mac128bit};
+use sgx_types::types::{Attributes, CpuSvn, Key128bit, KeyId, KeyPolicy, Mac128bit};
 use std::ffi::CStr;
 use std::mem;
 
@@ -66,7 +66,7 @@ impl EncryptFlags {
 impl From<&OpenMode> for EncryptFlags {
     fn from(mode: &OpenMode) -> Self {
         match mode {
-            OpenMode::AutoKey | OpenMode::ImportKey(_) => Self::AutoKey,
+            OpenMode::AutoKey(_) | OpenMode::ExportKey | OpenMode::ImportKey(_) => Self::AutoKey,
             OpenMode::UserKey(_) => Self::UserKey,
             OpenMode::IntegrityOnly => Self::IntegrityOnly,
         }
@@ -74,18 +74,19 @@ impl From<&OpenMode> for EncryptFlags {
 }
 
 #[derive(Clone, Copy, Debug, Default)]
-#[repr(C, packed)]
+#[repr(C)]
 pub struct MetadataPlain {
     pub file_id: u64,
     pub major_version: u8,
     pub minor_version: u8,
+    pub encrypt_flags: EncryptFlags,
+    pub update_flag: u8,
+    pub key_policy: KeyPolicy,
+    pub isv_svn: u16,
     pub key_id: KeyId,
     pub cpu_svn: CpuSvn,
-    pub isv_svn: u16,
-    pub encrypt_flags: EncryptFlags,
     pub attribute_mask: Attributes,
     pub gmac: Mac128bit,
-    pub update_flag: u8,
 }
 
 impl MetadataPlain {
@@ -121,7 +122,7 @@ const METADATA_PADDING: usize =
 const METADATA_ENCRYPTED: usize = mem::size_of::<MetadataEncrypted>();
 
 #[derive(Clone, Copy, Debug)]
-#[repr(C, packed)]
+#[repr(C)]
 pub struct Metadata {
     pub plaintext: MetadataPlain,
     pub ciphertext: [u8; METADATA_ENCRYPTED],
@@ -139,7 +140,7 @@ impl Metadata {
 }
 
 #[derive(Copy, Clone, Debug, Default)]
-#[repr(C, packed)]
+#[repr(C)]
 pub struct MetadataNode {
     pub node_number: u64,
     pub metadata: Metadata,
@@ -209,6 +210,16 @@ impl MetadataInfo {
         self.node.metadata.plaintext.encrypt_flags = encrypt_flags;
     }
 
+    #[inline]
+    pub fn key_policy(&self) -> KeyPolicy {
+        self.node.metadata.plaintext.key_policy
+    }
+
+    #[inline]
+    pub fn set_key_policy(&mut self, key_policy: KeyPolicy) {
+        self.node.metadata.plaintext.key_policy = key_policy;
+    }
+
     #[inline]
     pub fn update_flag(&self) -> bool {
         self.node.metadata.plaintext.update_flag != 0
@@ -283,6 +294,7 @@ impl MetadataInfo {
     }
 
     pub fn derive_key(&mut self, derive: &mut dyn DeriveKey) -> FsResult<Key128bit> {
+        let (key, key_id) = derive.derive_key(KeyType::Metadata, 0)?;
         match self.encrypt_flags() {
             EncryptFlags::AutoKey => {
                 cfg_if! {
@@ -290,27 +302,23 @@ impl MetadataInfo {
                         use sgx_tse::EnclaveReport;
                         use sgx_types::types::Report;
 
-                        let (key, key_id) = derive.derive_key(KeyType::Metadata, 0)?;
                         self.node.metadata.plaintext.key_id = key_id;
 
                         let report = Report::get_self();
                         self.node.metadata.plaintext.cpu_svn = report.body.cpu_svn;
                         self.node.metadata.plaintext.isv_svn = report.body.isv_svn;
-
-                        Ok(key)
                     } else {
                         use sgx_types::error::errno::ENOTSUP;
-                        Err(eos!(ENOTSUP))
+                        bail!(eos!(ENOTSUP));
                     }
                 }
             }
             EncryptFlags::UserKey => {
-                let (key, key_id) = derive.derive_key(KeyType::Metadata, 0)?;
                 self.node.metadata.plaintext.key_id = key_id;
-                Ok(key)
             }
-            EncryptFlags::IntegrityOnly => Ok(Key128bit::default()),
+            EncryptFlags::IntegrityOnly => {}
         }
+        Ok(key)
     }
 
     pub fn restore_key(&self, restore: &dyn RestoreKey) -> FsResult<Key128bit> {
@@ -321,22 +329,23 @@ impl MetadataInfo {
                         restore.restore_key(
                             KeyType::Metadata,
                             self.node.metadata.plaintext.key_id,
+                            Some(self.node.metadata.plaintext.key_policy),
                             Some(self.node.metadata.plaintext.cpu_svn),
                             Some(self.node.metadata.plaintext.isv_svn),
                         )
                     } else {
                         use sgx_types::error::errno::ENOTSUP;
-                        Err(eos!(ENOTSUP))
+                        bail!(eos!(ENOTSUP));
                     }
                 }
             }
-            EncryptFlags::UserKey => restore.restore_key(
+            EncryptFlags::UserKey | EncryptFlags::IntegrityOnly => restore.restore_key(
                 KeyType::Metadata,
                 self.node.metadata.plaintext.key_id,
                 None,
                 None,
+                None,
             ),
-            EncryptFlags::IntegrityOnly => Ok(Key128bit::default()),
         }
     }
 
diff --git a/sgx_protected_fs/tfs/src/sys/mod.rs b/sgx_protected_fs/tfs/src/sys/mod.rs
index 8744cd2a..d34ed887 100644
--- a/sgx_protected_fs/tfs/src/sys/mod.rs
+++ b/sgx_protected_fs/tfs/src/sys/mod.rs
@@ -17,6 +17,8 @@
 
 use crate::sys::error::FsError;
 use crate::sys::file::{self as file_imp, ProtectedFile};
+#[cfg(feature = "tfs")]
+use sgx_types::types::KeyPolicy;
 use sgx_types::types::{Key128bit, Mac128bit};
 use std::boxed::Box;
 use std::io::{Result, SeekFrom};
@@ -42,8 +44,8 @@ pub struct OpenOptions(file_imp::OpenOptions);
 #[derive(Clone, Debug)]
 pub enum EncryptMode {
     #[cfg(feature = "tfs")]
-    EncryptAutoKey,
-    EncryptWithIntegrity(Key128bit),
+    EncryptAutoKey(KeyPolicy),
+    EncryptUserKey(Key128bit),
     IntegrityOnly,
 }
 
@@ -51,25 +53,30 @@ impl OpenOptions {
     pub fn new() -> OpenOptions {
         Self(file_imp::OpenOptions::new())
     }
-
+    #[inline]
     pub fn read(&mut self, read: bool) {
         self.0.read = read;
     }
+    #[inline]
     pub fn write(&mut self, write: bool) {
         self.0.write = write;
     }
+    #[inline]
     pub fn append(&mut self, append: bool) {
         self.0.append = append;
     }
+    #[inline]
     pub fn update(&mut self, update: bool) {
         self.0.update = update;
     }
+    #[inline]
     pub fn binary(&mut self, binary: bool) {
         self.0.binary = binary;
     }
 
-    pub fn check_access_mode(&self) -> Result<()> {
-        self.0.check_access_mode().map_err(|e| {
+    #[allow(dead_code)]
+    pub fn check(&self) -> Result<()> {
+        self.0.check().map_err(|e| {
             e.set_errno();
             e.to_io_error()
         })
@@ -94,7 +101,6 @@ impl SgxFile {
         encrypt_mode: &EncryptMode,
         cache_size: Option<usize>,
     ) -> Result<SgxFile> {
-        opts.check_access_mode()?;
         ProtectedFile::open(path, &opts.0, &encrypt_mode.into(), cache_size)
             .map_err(|e| {
                 e.set_errno();
@@ -261,8 +267,12 @@ pub fn export_key<P: AsRef<Path>>(path: P) -> Result<Key128bit> {
 
 #[cfg(feature = "tfs")]
 #[inline]
-pub fn import_key<P: AsRef<Path>>(path: P, key: Key128bit) -> Result<()> {
-    ProtectedFile::import_key(path, key).map_err(|e| {
+pub fn import_key<P: AsRef<Path>>(
+    path: P,
+    key: Key128bit,
+    key_policy: Option<KeyPolicy>,
+) -> Result<()> {
+    ProtectedFile::import_key(path, key, key_policy).map_err(|e| {
         e.set_errno();
         e.to_io_error()
     })
diff --git a/sgx_protected_fs/tfs/src/sys/node.rs b/sgx_protected_fs/tfs/src/sys/node.rs
index 7419c328..5df3ec28 100644
--- a/sgx_protected_fs/tfs/src/sys/node.rs
+++ b/sgx_protected_fs/tfs/src/sys/node.rs
@@ -318,12 +318,8 @@ impl FileNode {
     }
 
     pub fn derive_key(&mut self, derive: &mut dyn DeriveKey) -> FsResult<Key128bit> {
-        if !self.encrypt_flags.is_integrity_only() {
-            let (key, _) = derive.derive_key(KeyType::Random, self.ciphertext.physical_number)?;
-            Ok(key)
-        } else {
-            Ok(Key128bit::default())
-        }
+        let (key, _) = derive.derive_key(KeyType::Random, self.ciphertext.physical_number)?;
+        Ok(key)
     }
 
     #[inline]


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org