You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by ms...@apache.org on 2020/04/15 01:14:02 UTC

[incubator-teaclave] branch develop updated: [types] Add FileAuthTag type (#263)

This is an automated email from the ASF dual-hosted git repository.

mssun pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git


The following commit(s) were added to refs/heads/develop by this push:
     new b9903b4  [types] Add FileAuthTag type (#263)
b9903b4 is described below

commit b9903b4ae487b991010c1aa3ae593ba72c13fce9
Author: Zhaofeng Chen <zf...@apache.org>
AuthorDate: Tue Apr 14 18:13:56 2020 -0700

    [types] Add FileAuthTag type (#263)
---
 cmake/scripts/test.sh                              |  2 -
 common/protected_fs_rs/src/protected_fs.rs         |  9 ++-
 common/protected_fs_rs/tests/large_file.rs         | 30 ++++++----
 common/protected_fs_rs/tests/rename.rs             | 11 ++--
 services/execution/enclave/src/service.rs          |  3 +-
 services/management/enclave/src/service.rs         | 55 ++++++-----------
 .../src/proto/teaclave_frontend_service.proto      |  6 +-
 services/proto/src/teaclave_frontend_service.rs    | 68 ++++++++++++----------
 .../enclave/src/end_to_end/native_gbdt_training.rs |  4 +-
 tests/functional/enclave/src/frontend_service.rs   | 16 +++--
 tests/functional/enclave/src/management_service.rs | 29 +++++----
 types/src/crypto.rs                                | 32 +++++++++-
 types/src/file.rs                                  | 19 +++---
 types/src/staged_task.rs                           | 12 ++--
 14 files changed, 154 insertions(+), 142 deletions(-)

diff --git a/cmake/scripts/test.sh b/cmake/scripts/test.sh
index fa7b41a..7fb06a2 100755
--- a/cmake/scripts/test.sh
+++ b/cmake/scripts/test.sh
@@ -52,7 +52,6 @@ run_integration_tests() {
     ./teaclave_integration_tests
   popd
 
-  pushd ${MT_SGXAPP_TOML_DIR}
   echo_title "protected_fs_rs tests (untrusted)"
   cargo test --manifest-path ${TEACLAVE_PROJECT_ROOT}/common/protected_fs_rs/Cargo.toml \
             --target-dir ${TEACLAVE_TARGET_DIR}/untrusted
@@ -65,7 +64,6 @@ run_integration_tests() {
 
   cargo test --manifest-path ${TEACLAVE_PROJECT_ROOT}/file_agent/Cargo.toml \
             --target-dir ${TEACLAVE_TARGET_DIR}/untrusted
-  popd
 
   cleanup
 }
diff --git a/common/protected_fs_rs/src/protected_fs.rs b/common/protected_fs_rs/src/protected_fs.rs
index 5ad08a4..b4bda87 100644
--- a/common/protected_fs_rs/src/protected_fs.rs
+++ b/common/protected_fs_rs/src/protected_fs.rs
@@ -88,11 +88,10 @@ impl ProtectedFile {
         self.inner.clear_cache()
     }
 
-    pub fn get_current_meta_gmac(
-        &self,
-        meta_gmac: &mut sgx_aes_gcm_128bit_tag_t,
-    ) -> io::Result<()> {
-        self.inner.get_current_meta_gmac(meta_gmac)
+    pub fn current_meta_gmac(&self) -> io::Result<sgx_aes_gcm_128bit_tag_t> {
+        let mut meta_gmac = sgx_aes_gcm_128bit_tag_t::default();
+        self.inner.get_current_meta_gmac(&mut meta_gmac)?;
+        Ok(meta_gmac)
     }
 
     pub fn rename_meta<P: AsRef<Path>, Q: AsRef<Path>>(
diff --git a/common/protected_fs_rs/tests/large_file.rs b/common/protected_fs_rs/tests/large_file.rs
index 1c8cbae..4360b25 100644
--- a/common/protected_fs_rs/tests/large_file.rs
+++ b/common/protected_fs_rs/tests/large_file.rs
@@ -17,7 +17,12 @@
 extern crate protected_fs;
 use protected_fs::{remove_protected_file, ProtectedFile};
 use rand_core::RngCore;
-use std::io::{Read, Write};
+use std::io::{Read, Result, Write};
+
+fn get_protected_file_cmac(fname: &str, key: &[u8; 16]) -> Result<[u8; 16]> {
+    let file = ProtectedFile::open_ex(fname, key)?;
+    file.current_meta_gmac()
+}
 
 #[test]
 fn test_large_file() {
@@ -25,7 +30,6 @@ fn test_large_file() {
     const NBLOCKS: usize = 0x001_0000;
 
     let key = [90u8; 16];
-    let mut auth_tag = [0u8; 16];
 
     let mut write_data = [0u8; BLOCK_SIZE];
     let mut read_data = [0u8; BLOCK_SIZE];
@@ -37,7 +41,7 @@ fn test_large_file() {
     rng.fill_bytes(&mut write_data);
     let fname = "large_file";
 
-    {
+    let auth_tag = {
         let opt = ProtectedFile::create_ex(fname, &key);
         assert_eq!(opt.is_ok(), true);
         let mut file = opt.unwrap();
@@ -52,21 +56,17 @@ fn test_large_file() {
         let result = file.flush();
         assert_eq!(result.is_ok(), true);
 
-        let result = file.get_current_meta_gmac(&mut auth_tag);
-        assert_eq!(result.is_ok(), true);
-    }
+        file.current_meta_gmac().unwrap()
+    };
 
     {
-        let mut auth_tag_in_file = [0xffu8; 16];
+        let auth_tag_in_file = get_protected_file_cmac(fname, &key).unwrap();
+        assert_eq!(auth_tag_in_file, auth_tag);
+
         let opt = ProtectedFile::open_ex(fname, &key);
         assert_eq!(opt.is_ok(), true);
         let mut file = opt.unwrap();
 
-        let result = file.get_current_meta_gmac(&mut auth_tag_in_file);
-        assert_eq!(result.is_ok(), true);
-
-        assert_eq!(auth_tag_in_file, auth_tag);
-
         for _i in 0..NBLOCKS {
             let result = file.read(&mut read_data);
             assert_eq!(result.is_ok(), true);
@@ -74,5 +74,11 @@ fn test_large_file() {
             assert_eq!(read_size, read_data.len());
         }
     }
+
+    {
+        let auth_tag_in_file = get_protected_file_cmac(fname, &key).unwrap();
+        assert_eq!(auth_tag_in_file, auth_tag);
+    }
+
     assert_eq!(remove_protected_file(fname).is_ok(), true);
 }
diff --git a/common/protected_fs_rs/tests/rename.rs b/common/protected_fs_rs/tests/rename.rs
index f16770d..301a5a9 100644
--- a/common/protected_fs_rs/tests/rename.rs
+++ b/common/protected_fs_rs/tests/rename.rs
@@ -25,7 +25,6 @@ fn test_rename() {
     const BLOCK_SIZE: usize = 2048;
 
     let key = [90u8; 16];
-    let mut auth_tag = [0u8; 16];
 
     let mut write_data = [0u8; BLOCK_SIZE];
     let mut read_data = [0u8; BLOCK_SIZE];
@@ -43,7 +42,7 @@ fn test_rename() {
         assert_eq!(write_size, write_data.len());
     }
 
-    {
+    let auth_tag = {
         // rename_meta requires append mode
         let mut file = ProtectedFile::append_ex(&old_name, &key).unwrap();
         // rename_meta in protected file
@@ -53,17 +52,15 @@ fn test_rename() {
         file.flush().unwrap();
 
         // get the latest gmac
-        file.get_current_meta_gmac(&mut auth_tag).unwrap();
-    }
+        file.current_meta_gmac().unwrap()
+    };
 
     // rename file after close
     fs::rename(old_name, new_name).unwrap();
 
     {
-        let mut auth_tag_in_file = [0xffu8; 16];
         let mut file = ProtectedFile::open_ex(&new_name, &key).unwrap();
-
-        file.get_current_meta_gmac(&mut auth_tag_in_file).unwrap();
+        let auth_tag_in_file = file.current_meta_gmac().unwrap();
         assert_eq!(auth_tag_in_file, auth_tag);
 
         let read_size = file.read(&mut read_data).unwrap();
diff --git a/services/execution/enclave/src/service.rs b/services/execution/enclave/src/service.rs
index 4f692d6..4950986 100644
--- a/services/execution/enclave/src/service.rs
+++ b/services/execution/enclave/src/service.rs
@@ -220,7 +220,8 @@ pub mod tests {
         let crypto = TeaclaveFile128Key::new(&[0; 16]).unwrap();
         let crypto_info = FileCrypto::TeaclaveFile128(crypto);
 
-        let training_input_data = FunctionInputFile::new(input_url, "", crypto_info);
+        let training_input_data =
+            FunctionInputFile::new(input_url, FileAuthTag::mock(), crypto_info);
         let model_output_data = FunctionOutputFile::new(output_url, crypto_info);
 
         let input_data = hashmap!("training_data" => training_input_data);
diff --git a/services/management/enclave/src/service.rs b/services/management/enclave/src/service.rs
index 9b23e6f..57d9873 100644
--- a/services/management/enclave/src/service.rs
+++ b/services/management/enclave/src/service.rs
@@ -78,7 +78,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
         let request = request.message;
         let input_file = TeaclaveInputFile::new(
             request.url,
-            request.hash,
+            request.cmac,
             request.crypto_info,
             vec![user_id],
         );
@@ -86,10 +86,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
         self.write_to_db(&input_file)
             .map_err(|_| ServiceError::StorageError)?;
 
-        let response = RegisterInputFileResponse {
-            data_id: input_file.external_id(),
-        };
-
+        let response = RegisterInputFileResponse::new(input_file.external_id());
         Ok(response)
     }
 
@@ -105,9 +102,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
         self.write_to_db(&output_file)
             .map_err(|_| ServiceError::StorageError)?;
 
-        let response = RegisterOutputFileResponse {
-            data_id: output_file.external_id(),
-        };
+        let response = RegisterOutputFileResponse::new(output_file.external_id());
         Ok(response)
     }
 
@@ -130,15 +125,13 @@ impl TeaclaveManagement for TeaclaveManagementService {
         self.write_to_db(&output_file)
             .map_err(|_| ServiceError::StorageError)?;
 
-        let response = RegisterFusionOutputResponse {
-            data_id: output_file.external_id(),
-        };
+        let response = RegisterFusionOutputResponse::new(output_file.external_id());
         Ok(response)
     }
 
     // access control:
     // 1) user_id in output.owner
-    // 2) hash != none
+    // 2) cmac != none
     fn register_input_from_output(
         &self,
         request: Request<RegisterInputFromOutputRequest>,
@@ -160,9 +153,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
         self.write_to_db(&input)
             .map_err(|_| ServiceError::StorageError)?;
 
-        let response = RegisterInputFromOutputResponse {
-            data_id: input.external_id(),
-        };
+        let response = RegisterInputFromOutputResponse::new(input.external_id());
         Ok(response)
     }
 
@@ -182,10 +173,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
             ServiceError::PermissionDenied
         );
 
-        let response = GetOutputFileResponse {
-            owner: output_file.owner,
-            hash: output_file.hash.unwrap_or_else(|| "".to_string()),
-        };
+        let response = GetOutputFileResponse::new(output_file.owner, output_file.cmac);
         Ok(response)
     }
 
@@ -205,10 +193,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
             ServiceError::PermissionDenied
         );
 
-        let response = GetInputFileResponse {
-            owner: input_file.owner,
-            hash: input_file.hash,
-        };
+        let response = GetInputFileResponse::new(input_file.owner, input_file.cmac);
         Ok(response)
     }
 
@@ -226,9 +211,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
         self.write_to_db(&function)
             .map_err(|_| ServiceError::StorageError)?;
 
-        let response = RegisterFunctionResponse {
-            function_id: function.external_id(),
-        };
+        let response = RegisterFunctionResponse::new(function.external_id());
         Ok(response)
     }
 
@@ -298,9 +281,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
         self.write_to_db(&task)
             .map_err(|_| ServiceError::StorageError)?;
 
-        Ok(CreateTaskResponse {
-            task_id: task.external_id(),
-        })
+        Ok(CreateTaskResponse::new(task.external_id()))
     }
 
     // access control: task.participants.contains(&user_id)
@@ -344,7 +325,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
     // 2) task.status == Created
     // 3) user can use the data:
     //    * input file: user_id == input_file.owner contains user_id
-    //    * output file: output_file.owner contains user_id && output_file.hash.is_none()
+    //    * output file: output_file.owner contains user_id && output_file.cmac.is_none()
     // 4) the data can be assgined to the task:
     //    * input_owners_map or output_owners_map contains the data name
     //    * input file: OwnerList match input_file.owner
@@ -478,7 +459,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
             let output_file: TeaclaveOutputFile = self
                 .read_from_db(&data_id)
                 .map_err(|_| ServiceError::PermissionDenied)?;
-            ensure!(output_file.hash.is_none(), ServiceError::PermissionDenied);
+            ensure!(output_file.cmac.is_none(), ServiceError::PermissionDenied);
             let output_data = FunctionOutputFile::from_teaclave_output_file(&output_file);
             output_map.insert(data_name.to_string(), output_data);
         }
@@ -580,13 +561,13 @@ impl TeaclaveManagementService {
         let mut output_file =
             TeaclaveOutputFile::new_fusion_data(vec!["mock_user1", "frontend_user"])?;
         output_file.uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000001")?;
-        output_file.hash = Some("deadbeef".to_string());
+        output_file.cmac = Some(FileAuthTag::mock());
         self.write_to_db(&output_file)?;
 
         let mut output_file =
             TeaclaveOutputFile::new_fusion_data(vec!["mock_user2", "mock_user3"])?;
         output_file.uuid = Uuid::parse_str("00000000-0000-0000-0000-000000000002")?;
-        output_file.hash = Some("deadbeef".to_string());
+        output_file.cmac = Some(FileAuthTag::mock());
         self.write_to_db(&output_file)?;
 
         let mut input_file = TeaclaveInputFile::from_output(output_file)?;
@@ -636,9 +617,9 @@ pub mod tests {
 
     pub fn handle_input_file() {
         let url = Url::parse("s3://bucket_id/path?token=mock_token").unwrap();
-        let hash = "a6d604b5987b693a19d94704532b5d928c2729f24dfd40745f8d03ac9ac75a8b".to_string();
+        let cmac = FileAuthTag::mock();
         let input_file =
-            TeaclaveInputFile::new(url, hash, FileCrypto::default(), vec!["mock_user"]);
+            TeaclaveInputFile::new(url, cmac, FileCrypto::default(), vec!["mock_user"]);
         assert!(TeaclaveInputFile::match_prefix(&input_file.key_string()));
         let value = input_file.to_vec().unwrap();
         let deserialized_file = TeaclaveInputFile::from_slice(&value).unwrap();
@@ -709,8 +690,8 @@ pub mod tests {
             .owner("mock_user");
 
         let url = Url::parse("s3://bucket_id/path?token=mock_token").unwrap();
-        let hash = "a6d604b5987b693a19d94704532b5d928c2729f24dfd40745f8d03ac9ac75a8b".to_string();
-        let input_data = FunctionInputFile::new(url.clone(), hash, FileCrypto::default());
+        let cmac = FileAuthTag::mock();
+        let input_data = FunctionInputFile::new(url.clone(), cmac, FileCrypto::default());
         let output_data = FunctionOutputFile::new(url, FileCrypto::default());
 
         let staged_task = StagedTask::new()
diff --git a/services/proto/src/proto/teaclave_frontend_service.proto b/services/proto/src/proto/teaclave_frontend_service.proto
index 29c1346..3957b1e 100644
--- a/services/proto/src/proto/teaclave_frontend_service.proto
+++ b/services/proto/src/proto/teaclave_frontend_service.proto
@@ -6,7 +6,7 @@ import "teaclave_common.proto";
 
 message RegisterInputFileRequest {
   string url = 1;
-  string hash = 2;
+  string cmac = 2;
   teaclave_common_proto.FileCryptoInfo crypto_info = 3;
 }
 
@@ -45,7 +45,7 @@ message GetOutputFileRequest {
 
 message GetOutputFileResponse {
   repeated string owner = 1;
-  string hash = 2;
+  string cmac = 2;
 }
 
 message GetInputFileRequest {
@@ -54,7 +54,7 @@ message GetInputFileRequest {
 
 message GetInputFileResponse {
   repeated string owner = 1;
-  string hash = 2;
+  string cmac = 2;
 }
 
 message FunctionInput {
diff --git a/services/proto/src/teaclave_frontend_service.rs b/services/proto/src/teaclave_frontend_service.rs
index e06893c..f1bf80c 100644
--- a/services/proto/src/teaclave_frontend_service.rs
+++ b/services/proto/src/teaclave_frontend_service.rs
@@ -26,8 +26,8 @@ use std::collections::HashMap;
 use std::prelude::v1::*;
 use teaclave_rpc::into_request;
 use teaclave_types::{
-    Executor, ExecutorType, ExternalID, FileCrypto, Function, FunctionArguments, FunctionInput,
-    FunctionOutput, OwnerList, TaskResult, TaskStatus, UserID, UserList,
+    Executor, ExecutorType, ExternalID, FileAuthTag, FileCrypto, Function, FunctionArguments,
+    FunctionInput, FunctionOutput, OwnerList, TaskResult, TaskStatus, UserID, UserList,
 };
 use url::Url;
 use uuid::Uuid;
@@ -42,15 +42,15 @@ pub use proto::TeaclaveFrontendResponse;
 #[derive(Debug, PartialEq)]
 pub struct RegisterInputFileRequest {
     pub url: Url,
-    pub hash: String,
+    pub cmac: FileAuthTag,
     pub crypto_info: FileCrypto,
 }
 
 impl RegisterInputFileRequest {
-    pub fn new(url: Url, hash: impl Into<String>, crypto: impl Into<FileCrypto>) -> Self {
+    pub fn new(url: Url, cmac: FileAuthTag, crypto: impl Into<FileCrypto>) -> Self {
         Self {
             url,
-            hash: hash.into(),
+            cmac,
             crypto_info: crypto.into(),
         }
     }
@@ -171,15 +171,12 @@ impl GetInputFileRequest {
 #[derive(Debug)]
 pub struct GetInputFileResponse {
     pub owner: OwnerList,
-    pub hash: String,
+    pub cmac: FileAuthTag,
 }
 
 impl GetInputFileResponse {
-    pub fn new(owner: OwnerList, hash: impl Into<String>) -> Self {
-        Self {
-            owner,
-            hash: hash.into(),
-        }
+    pub fn new(owner: OwnerList, cmac: FileAuthTag) -> Self {
+        Self { owner, cmac }
     }
 }
 
@@ -201,15 +198,12 @@ impl GetOutputFileRequest {
 #[derive(Debug)]
 pub struct GetOutputFileResponse {
     pub owner: OwnerList,
-    pub hash: String,
+    pub cmac: Option<FileAuthTag>,
 }
 
 impl GetOutputFileResponse {
-    pub fn new(owner: OwnerList, hash: impl Into<String>) -> Self {
-        Self {
-            owner,
-            hash: hash.into(),
-        }
+    pub fn new(owner: OwnerList, cmac: Option<FileAuthTag>) -> Self {
+        Self { owner, cmac }
     }
 }
 
@@ -494,16 +488,18 @@ impl std::convert::TryFrom<proto::RegisterInputFileRequest> for RegisterInputFil
     type Error = Error;
 
     fn try_from(proto: proto::RegisterInputFileRequest) -> Result<Self> {
-        let ret = Self {
-            url: Url::parse(&proto.url)?,
-            hash: proto.hash,
-            crypto_info: proto
-                .crypto_info
-                .ok_or_else(|| anyhow!("missing crypto_info"))?
-                .try_into()?,
-        };
-
-        Ok(ret)
+        let url = Url::parse(&proto.url)?;
+        let cmac = FileAuthTag::from_hex(proto.cmac)?;
+        let crypto_info = proto
+            .crypto_info
+            .ok_or_else(|| anyhow!("missing crypto_info"))?
+            .try_into()?;
+
+        Ok(RegisterInputFileRequest {
+            url,
+            cmac,
+            crypto_info,
+        })
     }
 }
 
@@ -511,7 +507,7 @@ impl From<RegisterInputFileRequest> for proto::RegisterInputFileRequest {
     fn from(request: RegisterInputFileRequest) -> Self {
         Self {
             url: request.url.into_string(),
-            hash: request.hash,
+            cmac: request.cmac.to_hex(),
             crypto_info: Some(request.crypto_info.into()),
         }
     }
@@ -678,7 +674,7 @@ impl std::convert::TryFrom<proto::GetInputFileResponse> for GetInputFileResponse
     fn try_from(proto: proto::GetInputFileResponse) -> Result<Self> {
         Ok(Self {
             owner: OwnerList::new(proto.owner),
-            hash: proto.hash,
+            cmac: FileAuthTag::from_hex(proto.cmac)?,
         })
     }
 }
@@ -687,7 +683,7 @@ impl From<GetInputFileResponse> for proto::GetInputFileResponse {
     fn from(request: GetInputFileResponse) -> Self {
         Self {
             owner: request.owner.into(),
-            hash: request.hash,
+            cmac: request.cmac.to_hex(),
         }
     }
 }
@@ -715,9 +711,17 @@ impl std::convert::TryFrom<proto::GetOutputFileResponse> for GetOutputFileRespon
     type Error = Error;
 
     fn try_from(proto: proto::GetOutputFileResponse) -> Result<Self> {
+        let cmac = {
+            if proto.cmac.is_empty() {
+                None
+            } else {
+                Some(FileAuthTag::from_hex(&proto.cmac)?)
+            }
+        };
+
         Ok(Self {
             owner: OwnerList::new(proto.owner),
-            hash: proto.hash,
+            cmac,
         })
     }
 }
@@ -726,7 +730,7 @@ impl From<GetOutputFileResponse> for proto::GetOutputFileResponse {
     fn from(request: GetOutputFileResponse) -> Self {
         Self {
             owner: request.owner.into(),
-            hash: request.hash,
+            cmac: request.cmac.map_or_else(String::new, |cmac| cmac.to_hex()),
         }
     }
 }
diff --git a/tests/functional/enclave/src/end_to_end/native_gbdt_training.rs b/tests/functional/enclave/src/end_to_end/native_gbdt_training.rs
index 3b1f5c0..234af6b 100644
--- a/tests/functional/enclave/src/end_to_end/native_gbdt_training.rs
+++ b/tests/functional/enclave/src/end_to_end/native_gbdt_training.rs
@@ -78,9 +78,9 @@ fn register_input_file(client: &mut TeaclaveFrontendClient) -> ExternalID {
         Url::parse("http://localhost:6789/fixtures/functions/gbdt_training/train.enc").unwrap();
     let crypto = TeaclaveFile128Key::new(&[0; 16]).unwrap();
     let crypto_info = FileCrypto::TeaclaveFile128(crypto);
-    let hash = "";
+    let cmac = FileAuthTag::mock();
 
-    let request = RegisterInputFileRequest::new(url, hash, crypto_info);
+    let request = RegisterInputFileRequest::new(url, cmac, crypto_info);
     let response = client.register_input_file(request).unwrap();
     log::info!("Register input: {:?}", response);
     response.data_id
diff --git a/tests/functional/enclave/src/frontend_service.rs b/tests/functional/enclave/src/frontend_service.rs
index 3ebb349..08e1484 100644
--- a/tests/functional/enclave/src/frontend_service.rs
+++ b/tests/functional/enclave/src/frontend_service.rs
@@ -70,14 +70,14 @@ fn unauthorized_client() -> TeaclaveFrontendClient {
 
 fn test_register_input_file() {
     let url = Url::parse("https://external-storage.com/filepath?presigned_token").unwrap();
-    let hash = "deadbeefdeadbeef";
+    let cmac = FileAuthTag::mock();
     let crypto_info = FileCrypto::default();
 
-    let request = RegisterInputFileRequest::new(url.clone(), hash, crypto_info);
+    let request = RegisterInputFileRequest::new(url.clone(), cmac, crypto_info);
     let response = authorized_client().register_input_file(request);
     assert!(response.is_ok());
 
-    let request = RegisterInputFileRequest::new(url, hash, crypto_info);
+    let request = RegisterInputFileRequest::new(url, cmac, crypto_info);
     let response = unauthorized_client().register_input_file(request);
     assert!(response.is_err());
 }
@@ -128,8 +128,7 @@ fn test_get_output_file() {
     let data_id = response.data_id;
 
     let request = GetOutputFileRequest::new(data_id.clone());
-    let response = client.get_output_file(request).unwrap();
-    assert!(response.hash.is_empty());
+    client.get_output_file(request).unwrap();
 
     let request = GetOutputFileRequest::new(data_id);
     let response = unauthorized_client().get_output_file(request);
@@ -140,16 +139,15 @@ fn test_get_input_file() {
     let mut client = authorized_client();
 
     let url = Url::parse("https://external-storage.com/filepath?presigned_token").unwrap();
-    let hash = "deadbeefdeadbeef";
+    let cmac = FileAuthTag::mock();
     let crypto_info = FileCrypto::default();
 
-    let request = RegisterInputFileRequest::new(url, hash, crypto_info);
+    let request = RegisterInputFileRequest::new(url, cmac, crypto_info);
     let response = client.register_input_file(request).unwrap();
     let data_id = response.data_id;
 
     let request = GetInputFileRequest::new(data_id.clone());
-    let response = client.get_input_file(request).unwrap();
-    assert!(!response.hash.is_empty());
+    client.get_input_file(request).unwrap();
 
     let request = GetInputFileRequest::new(data_id);
     let response = unauthorized_client().get_input_file(request);
diff --git a/tests/functional/enclave/src/management_service.rs b/tests/functional/enclave/src/management_service.rs
index d2a28c5..37ea704 100644
--- a/tests/functional/enclave/src/management_service.rs
+++ b/tests/functional/enclave/src/management_service.rs
@@ -49,9 +49,9 @@ fn authorized_client(user_id: &str) -> TeaclaveManagementClient {
 
 fn test_register_input_file() {
     let url = Url::parse("https://external-storage.com/filepath?presigned_token").unwrap();
-    let hash = "deadbeefdeadbeef";
+    let cmac = FileAuthTag::mock();
 
-    let request = RegisterInputFileRequest::new(url, hash, FileCrypto::default());
+    let request = RegisterInputFileRequest::new(url, cmac, FileCrypto::default());
     let response = authorized_client("mock_user").register_input_file(request);
     assert!(response.is_ok());
 }
@@ -119,11 +119,11 @@ fn test_get_output_file() {
 
 fn test_get_input_file() {
     let url = Url::parse("https://external-storage.com/filepath?presigned_token").unwrap();
-    let hash = "deadbeefdeadbeef";
+    let cmac = FileAuthTag::mock();
     let crypto_info = FileCrypto::default();
 
     let mut client = authorized_client("mock_user");
-    let request = RegisterInputFileRequest::new(url, hash, crypto_info);
+    let request = RegisterInputFileRequest::new(url, cmac, crypto_info);
     let response = client.register_input_file(request).unwrap();
     let data_id = response.data_id;
     let request = GetInputFileRequest::new(data_id.clone());
@@ -268,8 +268,8 @@ fn test_assign_data() {
 
     // !input_file.owner.contains(user_id)
     let url = Url::parse("https://path").unwrap();
-    let hash = "deadbeefdeadbeef";
-    let request = RegisterInputFileRequest::new(url, hash, FileCrypto::default());
+    let cmac = FileAuthTag::mock();
+    let request = RegisterInputFileRequest::new(url, cmac, FileCrypto::default());
     let response = client2.register_input_file(request).unwrap();
     let input_file_id_user2 = response.data_id;
 
@@ -298,10 +298,9 @@ fn test_assign_data() {
     let existing_outfile_id_user1 =
         ExternalID::try_from("output-00000000-0000-0000-0000-000000000001").unwrap();
 
-    // output_file.hash.is_some()
+    // output_file.cmac.is_some()
     let request = GetOutputFileRequest::new(existing_outfile_id_user1.clone());
-    let response = client1.get_output_file(request).unwrap();
-    assert!(!response.hash.is_empty());
+    client1.get_output_file(request).unwrap();
 
     let request = AssignDataRequest::new(
         task_id.clone(),
@@ -377,8 +376,8 @@ fn test_assign_data() {
 
     // assign all the data
     let url = Url::parse("input://path").unwrap();
-    let hash = "deadbeefdeadbeef";
-    let request = RegisterInputFileRequest::new(url, hash, FileCrypto::default());
+    let cmac = FileAuthTag::mock();
+    let request = RegisterInputFileRequest::new(url, cmac, FileCrypto::default());
     let response = client1.register_input_file(request);
     let input_file_id_user1 = response.unwrap().data_id;
 
@@ -441,8 +440,8 @@ fn test_approve_task() {
 
     // assign all the data
     let url = Url::parse("input://path").unwrap();
-    let hash = "deadbeefdeadbeef";
-    let request = RegisterInputFileRequest::new(url, hash, FileCrypto::default());
+    let cmac = FileAuthTag::mock();
+    let request = RegisterInputFileRequest::new(url, cmac, FileCrypto::default());
     let response = client1.register_input_file(request).unwrap();
 
     let input_file_id_user1 = response.data_id;
@@ -520,8 +519,8 @@ fn test_invoke_task() {
 
     // assign all the data
     let url = Url::parse("input://path").unwrap();
-    let hash = "deadbeefdeadbeef";
-    let request = RegisterInputFileRequest::new(url, hash, FileCrypto::default());
+    let cmac = FileAuthTag::mock();
+    let request = RegisterInputFileRequest::new(url, cmac, FileCrypto::default());
     let response = client1.register_input_file(request).unwrap();
 
     let input_file_id_user1 = response.data_id;
diff --git a/types/src/crypto.rs b/types/src/crypto.rs
index 7316f94..5158dd2 100644
--- a/types/src/crypto.rs
+++ b/types/src/crypto.rs
@@ -18,12 +18,42 @@
 #[cfg(feature = "mesalock_sgx")]
 use std::prelude::v1::*;
 
-use anyhow::{bail, ensure, Result};
+use anyhow::{bail, ensure, Context, Result};
 use serde::{Deserialize, Serialize};
+use std::convert::TryInto;
 use std::format;
 
 use teaclave_crypto::*;
 
+const TEACLAVE_FILE_AUTH_TAG_LENGTH: usize = 16;
+
+#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
+pub struct FileAuthTag {
+    tag: [u8; TEACLAVE_FILE_AUTH_TAG_LENGTH],
+}
+
+impl FileAuthTag {
+    pub fn from_hex(input: impl AsRef<str>) -> Result<Self> {
+        let hex = hex::decode(input.as_ref()).context("Illegal AuthTag provided")?;
+        let tag = hex
+            .as_slice()
+            .try_into()
+            .context("Illegal AuthTag provided")?;
+        Ok(FileAuthTag { tag })
+    }
+
+    pub fn to_hex(&self) -> String {
+        hex::encode(&self.tag)
+    }
+
+    #[cfg(test_mode)]
+    pub fn mock() -> Self {
+        Self {
+            tag: [0; TEACLAVE_FILE_AUTH_TAG_LENGTH],
+        }
+    }
+}
+
 #[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq)]
 pub enum FileCrypto {
     AesGcm128(AesGcm128Key),
diff --git a/types/src/file.rs b/types/src/file.rs
index 074e835..ec3e597 100644
--- a/types/src/file.rs
+++ b/types/src/file.rs
@@ -16,8 +16,7 @@
 // under the License.
 
 use crate::storage::Storable;
-use crate::FileCrypto;
-use crate::OwnerList;
+use crate::{FileAuthTag, FileCrypto, OwnerList};
 use anyhow::{anyhow, Result};
 use serde::{Deserialize, Serialize};
 use std::prelude::v1::*;
@@ -34,7 +33,7 @@ fn create_uuid() -> Uuid {
 #[derive(Debug, Deserialize, Serialize)]
 pub struct TeaclaveInputFile {
     pub url: Url,
-    pub hash: String,
+    pub cmac: FileAuthTag,
     pub crypto_info: FileCrypto,
     pub owner: OwnerList,
     pub uuid: Uuid,
@@ -43,7 +42,7 @@ pub struct TeaclaveInputFile {
 #[derive(Debug, Deserialize, Serialize)]
 pub struct TeaclaveOutputFile {
     pub url: Url,
-    pub hash: Option<String>,
+    pub cmac: Option<FileAuthTag>,
     pub crypto_info: FileCrypto,
     pub owner: OwnerList,
     pub uuid: Uuid,
@@ -52,13 +51,13 @@ pub struct TeaclaveOutputFile {
 impl TeaclaveInputFile {
     pub fn new(
         url: Url,
-        hash: String,
+        cmac: FileAuthTag,
         crypto_info: FileCrypto,
         owner: impl Into<OwnerList>,
     ) -> TeaclaveInputFile {
         TeaclaveInputFile {
             url,
-            hash,
+            cmac,
             crypto_info,
             owner: owner.into(),
             uuid: create_uuid(),
@@ -68,8 +67,8 @@ impl TeaclaveInputFile {
     pub fn from_output(output: TeaclaveOutputFile) -> Result<TeaclaveInputFile> {
         let input = TeaclaveInputFile {
             url: output.url,
-            hash: output
-                .hash
+            cmac: output
+                .cmac
                 .ok_or_else(|| anyhow!("output is not finished"))?,
             crypto_info: output.crypto_info,
             owner: output.owner,
@@ -97,7 +96,7 @@ impl TeaclaveOutputFile {
     ) -> TeaclaveOutputFile {
         TeaclaveOutputFile {
             url,
-            hash: None,
+            cmac: None,
             crypto_info,
             owner: owner.into(),
             uuid: create_uuid(),
@@ -112,7 +111,7 @@ impl TeaclaveOutputFile {
 
         Ok(TeaclaveOutputFile {
             url,
-            hash: None,
+            cmac: None,
             crypto_info,
             owner: owner.into(),
             uuid,
diff --git a/types/src/staged_task.rs b/types/src/staged_task.rs
index a97dca1..5c66b0c 100644
--- a/types/src/staged_task.rs
+++ b/types/src/staged_task.rs
@@ -24,8 +24,8 @@ use url::Url;
 use uuid::Uuid;
 
 use crate::{
-    Executor, ExecutorType, FileCrypto, FunctionArguments, Storable, TeaclaveInputFile,
-    TeaclaveOutputFile,
+    Executor, ExecutorType, FileAuthTag, FileCrypto, FunctionArguments, Storable,
+    TeaclaveInputFile, TeaclaveOutputFile,
 };
 
 const STAGED_TASK_PREFIX: &str = "staged-"; // staged-task-uuid
@@ -75,15 +75,15 @@ impl std::convert::From<HashMap<String, FunctionOutputFile>> for FunctionOutputF
 #[derive(Debug, Clone, Deserialize, Serialize)]
 pub struct FunctionInputFile {
     pub url: Url,
-    pub hash: String,
+    pub cmac: FileAuthTag,
     pub crypto_info: FileCrypto,
 }
 
 impl FunctionInputFile {
-    pub fn new(url: Url, hash: impl ToString, crypto_info: FileCrypto) -> Self {
+    pub fn new(url: Url, cmac: FileAuthTag, crypto_info: FileCrypto) -> Self {
         Self {
             url,
-            hash: hash.to_string(),
+            cmac,
             crypto_info,
         }
     }
@@ -91,7 +91,7 @@ impl FunctionInputFile {
     pub fn from_teaclave_input_file(file: &TeaclaveInputFile) -> Self {
         Self {
             url: file.url.to_owned(),
-            hash: file.hash.to_owned(),
+            cmac: file.cmac.to_owned(),
             crypto_info: file.crypto_info,
         }
     }


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