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/06/30 23:55:39 UTC

[incubator-teaclave] branch master updated: Refactoring error handling for IPC and services (#375)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new db6ddd8  Refactoring error handling for IPC and services (#375)
db6ddd8 is described below

commit db6ddd8847216a56a3c80a4f732773727974d502
Author: Mingshen Sun <bo...@mssun.me>
AuthorDate: Tue Jun 30 16:55:32 2020 -0700

    Refactoring error handling for IPC and services (#375)
---
 binder/src/binder.rs                               |  25 +--
 binder/src/{lib.rs => error.rs}                    |  36 ++--
 binder/src/ipc/app.rs                              |  16 +-
 binder/src/ipc/enclave.rs                          |   3 +-
 binder/src/ipc/mod.rs                              |  14 +-
 binder/src/lib.rs                                  |   1 +
 binder/src/macros.rs                               |   8 +-
 crypto/src/lib.rs                                  |   4 +-
 .../access_control/enclave/src/error.rs            |  25 ++-
 services/access_control/enclave/src/lib.rs         |   1 +
 services/access_control/enclave/src/service.rs     |  16 +-
 services/authentication/enclave/src/api_service.rs |  22 +--
 .../authentication/enclave/src/error.rs            |  31 +--
 services/authentication/enclave/src/lib.rs         |   1 +
 .../frontend/enclave/src/error.rs                  |  27 +--
 services/frontend/enclave/src/lib.rs               |   1 +
 services/frontend/enclave/src/service.rs           |  19 +-
 .../management/enclave/src/error.rs                |  32 +--
 services/management/enclave/src/lib.rs             |   1 +
 services/management/enclave/src/service.rs         | 137 +++++++------
 .../scheduler/enclave/src/error.rs                 |  29 +--
 services/scheduler/enclave/src/lib.rs              |   7 +-
 services/scheduler/enclave/src/service.rs          |  26 +--
 .../storage/enclave/src/error.rs                   |  29 +--
 services/storage/enclave/src/lib.rs                |   1 +
 services/storage/enclave/src/proxy.rs              |   2 +-
 services/storage/enclave/src/service.rs            |  20 +-
 types/src/{lib.rs => attestation.rs}               | 102 +---------
 types/src/error.rs                                 |  81 ++++++++
 types/src/lib.rs                                   | 216 ++-------------------
 30 files changed, 335 insertions(+), 598 deletions(-)

diff --git a/binder/src/binder.rs b/binder/src/binder.rs
index bbf6b55..82c9fd3 100644
--- a/binder/src/binder.rs
+++ b/binder/src/binder.rs
@@ -15,12 +15,15 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use std::prelude::v1::*;
+
 use sgx_types::*;
 use sgx_urts::SgxEnclave;
 
 use log::{debug, error};
 use serde::{Deserialize, Serialize};
 
+use crate::error::TeeBinderError;
 use crate::ipc::ECallChannel;
 use crate::ipc::IpcSender;
 use crate::proto::{
@@ -30,22 +33,12 @@ use teaclave_types::TeeServiceResult;
 
 const ENCLAVE_FILE_SUFFIX: &str = "_enclave.signed.so";
 
-#[derive(thiserror::Error, Debug)]
-pub enum TeeBinderError {
-    #[error("IpcError")]
-    IpcError,
-    #[error("SgxError")]
-    SgxError(sgx_types::sgx_status_t),
-    #[error("TeeServiceError")]
-    TeeServiceError,
-}
-
 pub struct TeeBinder {
     enclave: SgxEnclave,
 }
 
 impl TeeBinder {
-    pub fn new(name: &str) -> std::result::Result<TeeBinder, TeeBinderError> {
+    pub fn new(name: &str) -> Result<TeeBinder, TeeBinderError> {
         let enclave = if cfg!(production) {
             create_sgx_enclave(&name, false)?
         } else {
@@ -63,11 +56,7 @@ impl TeeBinder {
         Ok(tee)
     }
 
-    pub fn invoke<U, V>(
-        &self,
-        command: ECallCommand,
-        input: U,
-    ) -> std::result::Result<V, TeeBinderError>
+    pub fn invoke<U, V>(&self, command: ECallCommand, input: U) -> Result<V, TeeBinderError>
     where
         U: Serialize,
         V: for<'de> Deserialize<'de>,
@@ -75,7 +64,7 @@ impl TeeBinder {
         let mut channel = ECallChannel::new(self.enclave.geteid());
         channel
             .invoke::<U, V>(command.into(), input)
-            .map_err(|_| TeeBinderError::IpcError)
+            .map_err(TeeBinderError::IpcError)
     }
 
     pub fn finalize(&self) {
@@ -99,7 +88,7 @@ impl Drop for TeeBinder {
 fn create_sgx_enclave(
     enclave_name: &str,
     debug_launch: bool,
-) -> std::result::Result<SgxEnclave, TeeBinderError> {
+) -> Result<SgxEnclave, TeeBinderError> {
     let mut launch_token: sgx_launch_token_t = [0; 1024]; // launch_token is deprecated
     let mut launch_token_updated: i32 = 0; // launch_token is deprecated
 
diff --git a/binder/src/lib.rs b/binder/src/error.rs
similarity index 55%
copy from binder/src/lib.rs
copy to binder/src/error.rs
index ee8ee37..8be8e76 100644
--- a/binder/src/lib.rs
+++ b/binder/src/error.rs
@@ -15,20 +15,30 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![cfg_attr(feature = "mesalock_sgx", no_std)]
-#[cfg(feature = "mesalock_sgx")]
-extern crate sgx_tstd as std;
+use teaclave_types::{ECallStatus, SgxStatus};
+use thiserror::Error;
 
-pub mod ipc;
-pub mod proto;
+#[cfg(feature = "app")]
+#[derive(Error, Debug)]
+pub enum TeeBinderError {
+    #[error("failed to invoke IPC")]
+    IpcError(IpcError),
+    #[error("found SGX error: {0}")]
+    SgxError(SgxStatus),
+}
+
+#[derive(Error, Debug)]
+pub enum IpcError {
+    #[error("found SGX error: {0}")]
+    SgxError(SgxStatus),
+    #[error("ECall returns error code: {0}")]
+    ECallError(ECallStatus),
+    #[error("cannot serialize or deserialize IPC messages")]
+    SerdeError,
+}
 
-cfg_if::cfg_if! {
-    if #[cfg(feature = "app")]  {
-        mod binder;
-        mod ocall;
-        pub use binder::TeeBinder;
-    } else if #[cfg(feature = "mesalock_sgx")] {
-        mod macros;
-        pub use teaclave_binder_attribute::handle_ecall;
+impl From<serde_json::error::Error> for IpcError {
+    fn from(_: serde_json::error::Error) -> Self {
+        IpcError::SerdeError
     }
 }
diff --git a/binder/src/ipc/app.rs b/binder/src/ipc/app.rs
index 922053a..60c86cc 100644
--- a/binder/src/ipc/app.rs
+++ b/binder/src/ipc/app.rs
@@ -24,16 +24,16 @@ use sgx_types::{sgx_enclave_id_t, sgx_status_t};
 use crate::ipc::IpcError;
 use crate::ipc::IpcSender;
 use log::{debug, error};
-use teaclave_types::EnclaveStatus;
+use teaclave_types::ECallStatus;
 
 // Delaration of ecall for App, the implementation is in TEE
 // This function is automatically generated by the procedure macro #[ecall_entry_point].
-// fn enclave_init(eid: sgx_enclave_id_t, retval: *mut EnclaveStatus) -> sgx_status_t;
+// fn enclave_init(eid: sgx_enclave_id_t, retval: *mut ECallStatus) -> sgx_status_t;
 #[no_mangle]
 extern "C" {
     fn ecall_ipc_entry_point(
         eid: sgx_enclave_id_t,
-        retval: *mut EnclaveStatus,
+        retval: *mut ECallStatus,
         cmd: u32,
         in_buf: *const u8,
         in_len: usize,
@@ -75,7 +75,7 @@ impl ECallChannel {
             let mut out_len: usize = out_max;
             let out_ptr: *mut u8 = out_buf.as_mut_ptr();
 
-            let mut ecall_ret = EnclaveStatus::default();
+            let mut ecall_ret = ECallStatus::default();
 
             let sgx_status = unsafe {
                 ecall_ipc_entry_point(
@@ -93,7 +93,7 @@ impl ECallChannel {
             // Check sgx return values
             if sgx_status != sgx_status_t::SGX_SUCCESS {
                 error!("ecall_ipc_entry_point, app sgx_error:{}", sgx_status);
-                return Err(IpcError::SgxError(sgx_status as i32));
+                return Err(IpcError::SgxError(sgx_status));
             }
 
             // Check rust logic return values
@@ -115,7 +115,7 @@ impl ECallChannel {
             // Transparent deliever the errors to outer logic.
             if ecall_ret.is_err() {
                 error!("ecall_ipc_entry_point, app api_error: {:?}", ecall_ret);
-                return Err(IpcError::EnclaveError(ecall_ret));
+                return Err(IpcError::ECallError(ecall_ret));
             }
 
             unsafe {
@@ -136,9 +136,9 @@ impl IpcSender for ECallChannel {
         U: Serialize,
         V: for<'de> Deserialize<'de>,
     {
-        let request_payload = serde_json::to_vec(&input).map_err(|_| IpcError::SerdeError)?;
+        let request_payload = serde_json::to_vec(&input)?;
         let result_buf = self.ecall_ipc_app_to_tee(cmd, request_payload)?;
-        let response: V = serde_json::from_slice(&result_buf).map_err(|_| IpcError::SerdeError)?;
+        let response: V = serde_json::from_slice(&result_buf)?;
         Ok(response)
     }
 }
diff --git a/binder/src/ipc/enclave.rs b/binder/src/ipc/enclave.rs
index 2482c26..7b95aaf 100644
--- a/binder/src/ipc/enclave.rs
+++ b/binder/src/ipc/enclave.rs
@@ -31,8 +31,7 @@ impl IpcReceiver for ECallReceiver {
         X: IpcService<U, V>,
     {
         let input: U = serde_json::from_slice(&input_payload)?;
-        let response: std::result::Result<V, teaclave_types::TeeServiceError> =
-            x.handle_invoke(input);
+        let response: Result<V, teaclave_types::TeeServiceError> = x.handle_invoke(input);
         let response_payload = serde_json::to_vec(&response)?;
 
         Ok(response_payload)
diff --git a/binder/src/ipc/mod.rs b/binder/src/ipc/mod.rs
index 1662216..98d0a36 100644
--- a/binder/src/ipc/mod.rs
+++ b/binder/src/ipc/mod.rs
@@ -18,6 +18,8 @@
 use serde::{Deserialize, Serialize};
 use std::prelude::v1::*;
 
+use crate::error::IpcError;
+
 // Intra-Process-Communication
 // Developer should split a process into two partitions, App and TEE.
 
@@ -55,18 +57,6 @@ pub trait IpcReceiver {
         X: IpcService<U, V>;
 }
 
-#[derive(thiserror::Error, Debug, Serialize, Deserialize)]
-pub enum IpcError {
-    #[error("SgxError")]
-    SgxError(i32),
-    #[error("EnclaveError")]
-    EnclaveError(teaclave_types::EnclaveStatus),
-    #[error("SerdeError")]
-    SerdeError,
-    #[error("TeeServiceError")]
-    TeeServiceError,
-}
-
 cfg_if::cfg_if! {
     if #[cfg(feature = "app")]  {
         mod app;
diff --git a/binder/src/lib.rs b/binder/src/lib.rs
index ee8ee37..05193e2 100644
--- a/binder/src/lib.rs
+++ b/binder/src/lib.rs
@@ -19,6 +19,7 @@
 #[cfg(feature = "mesalock_sgx")]
 extern crate sgx_tstd as std;
 
+mod error;
 pub mod ipc;
 pub mod proto;
 
diff --git a/binder/src/macros.rs b/binder/src/macros.rs
index d81fa1e..0446e47 100644
--- a/binder/src/macros.rs
+++ b/binder/src/macros.rs
@@ -90,7 +90,7 @@ macro_rules! register_ecall_handler {
             out_buf: *mut u8,
             out_max: usize,
             out_len: &mut usize,
-        ) -> teaclave_types::EnclaveStatus {
+        ) -> teaclave_types::ECallStatus {
             // The last argument could be either * mut usize, or &mut usize
             let input_buf: &[u8] = unsafe { std::slice::from_raw_parts(in_buf, in_len) };
 
@@ -101,7 +101,7 @@ macro_rules! register_ecall_handler {
                     Ok(out) => out,
                     Err(e) => {
                         log::error!("tee execute cmd: {:x}, error: {}", cmd, e);
-                        return teaclave_types::EnclaveStatus(1);
+                        return teaclave_types::ECallStatus(1);
                     }
                 }
             };
@@ -113,7 +113,7 @@ macro_rules! register_ecall_handler {
 
             if inner_len > out_max {
                 log::debug!("tee before copy out_buf check: out_max={:x} < inner={:x}", out_max, inner_len);
-                return teaclave_types::EnclaveStatus(0x0000_000c);
+                return teaclave_types::ECallStatus(0x0000_000c);
             }
 
             // The following lines use a trick of "constructing a mutable slice
@@ -126,7 +126,7 @@ macro_rules! register_ecall_handler {
 
             // out_len would be used in `set_len` in the untrusted app
             // so out_len cannot be larger than out_max. Additional checks are **required**.
-            teaclave_types::EnclaveStatus::default()
+            teaclave_types::ECallStatus::default()
         }
     }
 }
diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs
index 1834bdf..dd91d19 100644
--- a/crypto/src/lib.rs
+++ b/crypto/src/lib.rs
@@ -209,7 +209,7 @@ impl TeaclaveFile128Key {
         loop {
             let n = file.read(&mut buffer)?;
             if n > 0 {
-                output.write(&buffer[..n])?;
+                output.write_all(&buffer[..n])?;
             } else {
                 break;
             }
@@ -225,7 +225,7 @@ impl TeaclaveFile128Key {
         loop {
             let n = content.read(&mut buffer[..])?;
             if n > 0 {
-                file.write(&buffer[..n])?;
+                file.write_all(&buffer[..n])?;
             } else {
                 break;
             }
diff --git a/binder/src/lib.rs b/services/access_control/enclave/src/error.rs
similarity index 65%
copy from binder/src/lib.rs
copy to services/access_control/enclave/src/error.rs
index ee8ee37..6d961d7 100644
--- a/binder/src/lib.rs
+++ b/services/access_control/enclave/src/error.rs
@@ -15,20 +15,19 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![cfg_attr(feature = "mesalock_sgx", no_std)]
-#[cfg(feature = "mesalock_sgx")]
-extern crate sgx_tstd as std;
+use std::prelude::v1::*;
 
-pub mod ipc;
-pub mod proto;
+use teaclave_types::TeaclaveServiceResponseError;
+use thiserror::Error;
 
-cfg_if::cfg_if! {
-    if #[cfg(feature = "app")]  {
-        mod binder;
-        mod ocall;
-        pub use binder::TeeBinder;
-    } else if #[cfg(feature = "mesalock_sgx")] {
-        mod macros;
-        pub use teaclave_binder_attribute::handle_ecall;
+#[derive(Error, Debug)]
+pub(crate) enum TeaclavAccessControlError {
+    #[error("access control error")]
+    AccessControlError,
+}
+
+impl From<TeaclavAccessControlError> for TeaclaveServiceResponseError {
+    fn from(error: TeaclavAccessControlError) -> Self {
+        TeaclaveServiceResponseError::RequestError(error.to_string())
     }
 }
diff --git a/services/access_control/enclave/src/lib.rs b/services/access_control/enclave/src/lib.rs
index cb86dad..3c37b39 100644
--- a/services/access_control/enclave/src/lib.rs
+++ b/services/access_control/enclave/src/lib.rs
@@ -44,6 +44,7 @@ use teaclave_service_enclave_utils::ServiceEnclave;
 use teaclave_types::{EnclaveInfo, TeeServiceError, TeeServiceResult};
 
 mod acs;
+mod error;
 mod service;
 
 fn start_service(config: &RuntimeConfig) -> Result<()> {
diff --git a/services/access_control/enclave/src/service.rs b/services/access_control/enclave/src/service.rs
index 804ea55..a0c2cb3 100644
--- a/services/access_control/enclave/src/service.rs
+++ b/services/access_control/enclave/src/service.rs
@@ -16,6 +16,7 @@
 // under the License.
 
 use crate::acs::{AccessControlModule, EnforceRequest};
+use crate::error::TeaclavAccessControlError;
 use std::prelude::v1::*;
 use teaclave_proto::teaclave_access_control_service::{
     AuthorizeDataRequest, AuthorizeDataResponse, AuthorizeFunctionRequest,
@@ -24,20 +25,7 @@ use teaclave_proto::teaclave_access_control_service::{
 };
 use teaclave_rpc::Request;
 use teaclave_service_enclave_utils::{bail, teaclave_service};
-use teaclave_types::{TeaclaveServiceResponseError, TeaclaveServiceResponseResult};
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-enum TeaclavAccessControlError {
-    #[error("access control error")]
-    AccessControlError,
-}
-
-impl From<TeaclavAccessControlError> for TeaclaveServiceResponseError {
-    fn from(error: TeaclavAccessControlError) -> Self {
-        TeaclaveServiceResponseError::RequestError(error.to_string())
-    }
-}
+use teaclave_types::TeaclaveServiceResponseResult;
 
 #[teaclave_service(teaclave_access_control_service, TeaclaveAccessControl)]
 #[derive(Clone)]
diff --git a/services/authentication/enclave/src/api_service.rs b/services/authentication/enclave/src/api_service.rs
index 8695bef..5470ce9 100644
--- a/services/authentication/enclave/src/api_service.rs
+++ b/services/authentication/enclave/src/api_service.rs
@@ -15,6 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use crate::error::TeaclaveAuthenticationApiError;
 use crate::user_db::{DbClient, DbError};
 use crate::user_info::UserInfo;
 use std::prelude::v1::*;
@@ -26,26 +27,7 @@ use teaclave_proto::teaclave_authentication_service::{
 };
 use teaclave_rpc::Request;
 use teaclave_service_enclave_utils::{bail, ensure, teaclave_service};
-use teaclave_types::{TeaclaveServiceResponseError, TeaclaveServiceResponseResult};
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-enum TeaclaveAuthenticationApiError {
-    #[error("permission denied")]
-    PermissionDenied,
-    #[error("invalid userid")]
-    InvalidUserId,
-    #[error("invalid password")]
-    InvalidPassword,
-    #[error("service unavailable")]
-    ServiceUnavailable,
-}
-
-impl From<TeaclaveAuthenticationApiError> for TeaclaveServiceResponseError {
-    fn from(error: TeaclaveAuthenticationApiError) -> Self {
-        TeaclaveServiceResponseError::RequestError(error.to_string())
-    }
-}
+use teaclave_types::TeaclaveServiceResponseResult;
 
 #[teaclave_service(
     teaclave_authentication_service,
diff --git a/binder/src/lib.rs b/services/authentication/enclave/src/error.rs
similarity index 57%
copy from binder/src/lib.rs
copy to services/authentication/enclave/src/error.rs
index ee8ee37..378e2a8 100644
--- a/binder/src/lib.rs
+++ b/services/authentication/enclave/src/error.rs
@@ -15,20 +15,25 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![cfg_attr(feature = "mesalock_sgx", no_std)]
-#[cfg(feature = "mesalock_sgx")]
-extern crate sgx_tstd as std;
+use std::prelude::v1::*;
 
-pub mod ipc;
-pub mod proto;
+use teaclave_types::TeaclaveServiceResponseError;
+use thiserror::Error;
 
-cfg_if::cfg_if! {
-    if #[cfg(feature = "app")]  {
-        mod binder;
-        mod ocall;
-        pub use binder::TeeBinder;
-    } else if #[cfg(feature = "mesalock_sgx")] {
-        mod macros;
-        pub use teaclave_binder_attribute::handle_ecall;
+#[derive(Error, Debug)]
+pub(crate) enum TeaclaveAuthenticationApiError {
+    #[error("permission denied")]
+    PermissionDenied,
+    #[error("invalid userid")]
+    InvalidUserId,
+    #[error("invalid password")]
+    InvalidPassword,
+    #[error("service unavailable")]
+    ServiceUnavailable,
+}
+
+impl From<TeaclaveAuthenticationApiError> for TeaclaveServiceResponseError {
+    fn from(error: TeaclaveAuthenticationApiError) -> Self {
+        TeaclaveServiceResponseError::RequestError(error.to_string())
     }
 }
diff --git a/services/authentication/enclave/src/lib.rs b/services/authentication/enclave/src/lib.rs
index 3bf2285..439f3e9 100644
--- a/services/authentication/enclave/src/lib.rs
+++ b/services/authentication/enclave/src/lib.rs
@@ -49,6 +49,7 @@ use teaclave_service_enclave_utils::ServiceEnclave;
 use teaclave_types::{EnclaveInfo, TeeServiceError, TeeServiceResult};
 
 mod api_service;
+mod error;
 mod internal_service;
 mod user_db;
 mod user_info;
diff --git a/binder/src/lib.rs b/services/frontend/enclave/src/error.rs
similarity index 63%
copy from binder/src/lib.rs
copy to services/frontend/enclave/src/error.rs
index ee8ee37..e2a9855 100644
--- a/binder/src/lib.rs
+++ b/services/frontend/enclave/src/error.rs
@@ -15,20 +15,21 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![cfg_attr(feature = "mesalock_sgx", no_std)]
-#[cfg(feature = "mesalock_sgx")]
-extern crate sgx_tstd as std;
+use std::prelude::v1::*;
 
-pub mod ipc;
-pub mod proto;
+use teaclave_types::TeaclaveServiceResponseError;
+use thiserror::Error;
 
-cfg_if::cfg_if! {
-    if #[cfg(feature = "app")]  {
-        mod binder;
-        mod ocall;
-        pub use binder::TeeBinder;
-    } else if #[cfg(feature = "mesalock_sgx")] {
-        mod macros;
-        pub use teaclave_binder_attribute::handle_ecall;
+#[derive(Error, Debug)]
+pub(crate) enum TeaclaveFrontendError {
+    #[error("authentication error")]
+    AuthenticationError,
+    #[error("lock error")]
+    LockError,
+}
+
+impl From<TeaclaveFrontendError> for TeaclaveServiceResponseError {
+    fn from(error: TeaclaveFrontendError) -> Self {
+        TeaclaveServiceResponseError::RequestError(error.to_string())
     }
 }
diff --git a/services/frontend/enclave/src/lib.rs b/services/frontend/enclave/src/lib.rs
index 53990bb..dc71fd9 100644
--- a/services/frontend/enclave/src/lib.rs
+++ b/services/frontend/enclave/src/lib.rs
@@ -44,6 +44,7 @@ use teaclave_service_enclave_utils::{
 };
 use teaclave_types::{TeeServiceError, TeeServiceResult};
 
+mod error;
 mod service;
 
 fn start_service(config: &RuntimeConfig) -> Result<()> {
diff --git a/services/frontend/enclave/src/service.rs b/services/frontend/enclave/src/service.rs
index c0f60d5..79c070d 100644
--- a/services/frontend/enclave/src/service.rs
+++ b/services/frontend/enclave/src/service.rs
@@ -15,10 +15,11 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use crate::error::TeaclaveFrontendError;
+
 use anyhow::Result;
 use std::prelude::v1::*;
 use std::sync::{Arc, SgxMutex as Mutex};
-use thiserror::Error;
 
 use teaclave_proto::teaclave_authentication_service::{
     TeaclaveAuthenticationInternalClient, UserAuthenticateRequest,
@@ -39,21 +40,7 @@ use teaclave_proto::teaclave_management_service::TeaclaveManagementClient;
 use teaclave_rpc::endpoint::Endpoint;
 use teaclave_rpc::Request;
 use teaclave_service_enclave_utils::{bail, teaclave_service};
-use teaclave_types::{TeaclaveServiceResponseError, TeaclaveServiceResponseResult};
-
-#[derive(Error, Debug)]
-enum TeaclaveFrontendError {
-    #[error("authentication error")]
-    AuthenticationError,
-    #[error("lock error")]
-    LockError,
-}
-
-impl From<TeaclaveFrontendError> for TeaclaveServiceResponseError {
-    fn from(error: TeaclaveFrontendError) -> Self {
-        TeaclaveServiceResponseError::RequestError(error.to_string())
-    }
-}
+use teaclave_types::TeaclaveServiceResponseResult;
 
 #[teaclave_service(teaclave_frontend_service, TeaclaveFrontend, TeaclaveFrontendError)]
 #[derive(Clone)]
diff --git a/binder/src/lib.rs b/services/management/enclave/src/error.rs
similarity index 56%
copy from binder/src/lib.rs
copy to services/management/enclave/src/error.rs
index ee8ee37..917b897 100644
--- a/binder/src/lib.rs
+++ b/services/management/enclave/src/error.rs
@@ -15,20 +15,26 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![cfg_attr(feature = "mesalock_sgx", no_std)]
-#[cfg(feature = "mesalock_sgx")]
-extern crate sgx_tstd as std;
+use std::prelude::v1::*;
+use teaclave_types::TeaclaveServiceResponseError;
+use thiserror::Error;
 
-pub mod ipc;
-pub mod proto;
+#[derive(Error, Debug)]
+pub(crate) enum TeaclaveManagementServiceError {
+    #[error("invalid request")]
+    InvalidRequest,
+    #[error("data error")]
+    DataError,
+    #[error("storage error")]
+    StorageError,
+    #[error("permission denied")]
+    PermissionDenied,
+    #[error("bad task")]
+    BadTask,
+}
 
-cfg_if::cfg_if! {
-    if #[cfg(feature = "app")]  {
-        mod binder;
-        mod ocall;
-        pub use binder::TeeBinder;
-    } else if #[cfg(feature = "mesalock_sgx")] {
-        mod macros;
-        pub use teaclave_binder_attribute::handle_ecall;
+impl From<TeaclaveManagementServiceError> for TeaclaveServiceResponseError {
+    fn from(error: TeaclaveManagementServiceError) -> Self {
+        TeaclaveServiceResponseError::RequestError(error.to_string())
     }
 }
diff --git a/services/management/enclave/src/lib.rs b/services/management/enclave/src/lib.rs
index f4deec4..07f357f 100644
--- a/services/management/enclave/src/lib.rs
+++ b/services/management/enclave/src/lib.rs
@@ -42,6 +42,7 @@ use teaclave_rpc::server::SgxTrustedTlsServer;
 use teaclave_service_enclave_utils::{create_trusted_storage_endpoint, ServiceEnclave};
 use teaclave_types::{EnclaveInfo, TeeServiceError, TeeServiceResult};
 
+mod error;
 mod service;
 
 fn start_service(config: &RuntimeConfig) -> Result<()> {
diff --git a/services/management/enclave/src/service.rs b/services/management/enclave/src/service.rs
index 6ea1343..734db1d 100644
--- a/services/management/enclave/src/service.rs
+++ b/services/management/enclave/src/service.rs
@@ -15,6 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use crate::error::TeaclaveManagementServiceError;
 use anyhow::{anyhow, Result};
 use std::collections::HashMap;
 use std::convert::TryInto;
@@ -39,31 +40,14 @@ use teaclave_rpc::endpoint::Endpoint;
 use teaclave_rpc::Request;
 use teaclave_service_enclave_utils::{ensure, teaclave_service};
 use teaclave_types::*;
-use thiserror::Error;
 use url::Url;
 use uuid::Uuid;
 
-#[derive(Error, Debug)]
-enum ServiceError {
-    #[error("invalid request")]
-    InvalidRequest,
-    #[error("data error")]
-    DataError,
-    #[error("storage error")]
-    StorageError,
-    #[error("permission denied")]
-    PermissionDenied,
-    #[error("bad task")]
-    BadTask,
-}
-
-impl From<ServiceError> for TeaclaveServiceResponseError {
-    fn from(error: ServiceError) -> Self {
-        TeaclaveServiceResponseError::RequestError(error.to_string())
-    }
-}
-
-#[teaclave_service(teaclave_management_service, TeaclaveManagement, ServiceError)]
+#[teaclave_service(
+    teaclave_management_service,
+    TeaclaveManagement,
+    TeaclaveManagementServiceError
+)]
 #[derive(Clone)]
 pub(crate) struct TeaclaveManagementService {
     storage_client: Arc<Mutex<TeaclaveStorageClient>>,
@@ -85,7 +69,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
         );
 
         self.write_to_db(&input_file)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         let response = RegisterInputFileResponse::new(input_file.external_id());
         Ok(response)
@@ -103,11 +87,11 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let old_input_file: TeaclaveInputFile = self
             .read_from_db(&request.data_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         ensure!(
             old_input_file.owner == OwnerList::from(vec![user_id]),
-            ServiceError::PermissionDenied
+            TeaclaveManagementServiceError::PermissionDenied
         );
 
         let input_file = TeaclaveInputFile::new(
@@ -118,7 +102,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
         );
 
         self.write_to_db(&input_file)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         let response = UpdateInputFileResponse::new(input_file.external_id());
         Ok(response)
@@ -134,7 +118,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
         let output_file = TeaclaveOutputFile::new(request.url, request.crypto_info, vec![user_id]);
 
         self.write_to_db(&output_file)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         let response = RegisterOutputFileResponse::new(output_file.external_id());
         Ok(response)
@@ -152,11 +136,11 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let old_output_file: TeaclaveOutputFile = self
             .read_from_db(&request.data_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         ensure!(
             old_output_file.owner == OwnerList::from(vec![user_id]),
-            ServiceError::PermissionDenied
+            TeaclaveManagementServiceError::PermissionDenied
         );
 
         let output_file = TeaclaveOutputFile::new(
@@ -166,7 +150,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
         );
 
         self.write_to_db(&output_file)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         let response = UpdateOutputFileResponse::new(output_file.external_id());
         Ok(response)
@@ -182,15 +166,15 @@ impl TeaclaveManagement for TeaclaveManagementService {
         let owner_list = request.message.owner_list;
         ensure!(
             owner_list.len() > 1 && owner_list.contains(&user_id),
-            ServiceError::PermissionDenied
+            TeaclaveManagementServiceError::PermissionDenied
         );
 
         let output_file = self
             .create_fusion_data(owner_list)
-            .map_err(|_| ServiceError::DataError)?;
+            .map_err(|_| TeaclaveManagementServiceError::DataError)?;
 
         self.write_to_db(&output_file)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         let response = RegisterFusionOutputResponse::new(output_file.external_id());
         Ok(response)
@@ -207,18 +191,18 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let output: TeaclaveOutputFile = self
             .read_from_db(&request.message.data_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         ensure!(
             output.owner.contains(&user_id),
-            ServiceError::PermissionDenied
+            TeaclaveManagementServiceError::PermissionDenied
         );
 
-        let input =
-            TeaclaveInputFile::from_output(output).map_err(|_| ServiceError::PermissionDenied)?;
+        let input = TeaclaveInputFile::from_output(output)
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         self.write_to_db(&input)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         let response = RegisterInputFromOutputResponse::new(input.external_id());
         Ok(response)
@@ -233,11 +217,11 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let output_file: TeaclaveOutputFile = self
             .read_from_db(&request.message.data_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         ensure!(
             output_file.owner.contains(&user_id),
-            ServiceError::PermissionDenied
+            TeaclaveManagementServiceError::PermissionDenied
         );
 
         let response = GetOutputFileResponse::new(output_file.owner, output_file.cmac);
@@ -253,11 +237,11 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let input_file: TeaclaveInputFile = self
             .read_from_db(&request.message.data_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         ensure!(
             input_file.owner.contains(&user_id),
-            ServiceError::PermissionDenied
+            TeaclaveManagementServiceError::PermissionDenied
         );
 
         let response = GetInputFileResponse::new(input_file.owner, input_file.cmac);
@@ -276,7 +260,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
             .owner(user_id);
 
         self.write_to_db(&function)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         let response = RegisterFunctionResponse::new(function.external_id());
         Ok(response)
@@ -291,11 +275,11 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let function: Function = self
             .read_from_db(&request.message.function_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         ensure!(
             (function.public || function.owner == user_id),
-            ServiceError::PermissionDenied
+            TeaclaveManagementServiceError::PermissionDenied
         );
 
         let response = GetFunctionResponse {
@@ -327,7 +311,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let function: Function = self
             .read_from_db(&request.function_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         let task = Task::<Create>::new(
             user_id,
@@ -337,13 +321,13 @@ impl TeaclaveManagement for TeaclaveManagementService {
             request.outputs_ownership,
             function,
         )
-        .map_err(|_| ServiceError::BadTask)?;
+        .map_err(|_| TeaclaveManagementServiceError::BadTask)?;
 
         log::debug!("CreateTask: {:?}", task);
 
         let ts: TaskState = task.into();
         self.write_to_db(&ts)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         let response = CreateTaskResponse::new(ts.external_id());
         Ok(response)
@@ -358,9 +342,12 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let ts: TaskState = self
             .read_from_db(&request.message.task_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
-        ensure!(ts.has_participant(&user_id), ServiceError::PermissionDenied);
+        ensure!(
+            ts.has_participant(&user_id),
+            TeaclaveManagementServiceError::PermissionDenied
+        );
 
         log::debug!("GetTask: {:?}", ts);
 
@@ -402,36 +389,39 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let ts: TaskState = self
             .read_from_db(&request.task_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
-        ensure!(ts.has_participant(&user_id), ServiceError::PermissionDenied);
+        ensure!(
+            ts.has_participant(&user_id),
+            TeaclaveManagementServiceError::PermissionDenied
+        );
 
         let mut task: Task<Assign> = ts.try_into().map_err(|e| {
             log::warn!("Assign state error: {:?}", e);
-            ServiceError::PermissionDenied
+            TeaclaveManagementServiceError::PermissionDenied
         })?;
 
         for (data_name, data_id) in request.inputs.iter() {
             let file: TeaclaveInputFile = self
                 .read_from_db(&data_id)
-                .map_err(|_| ServiceError::PermissionDenied)?;
+                .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
             task.assign_input(&user_id, data_name, file)
-                .map_err(|_| ServiceError::PermissionDenied)?;
+                .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
         }
 
         for (data_name, data_id) in request.outputs.iter() {
             let file: TeaclaveOutputFile = self
                 .read_from_db(&data_id)
-                .map_err(|_| ServiceError::PermissionDenied)?;
+                .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
             task.assign_output(&user_id, data_name, file)
-                .map_err(|_| ServiceError::PermissionDenied)?;
+                .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
         }
 
         log::debug!("AssignData: {:?}", task);
 
         let ts: TaskState = task.into();
         self.write_to_db(&ts)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         Ok(AssignDataResponse)
     }
@@ -448,21 +438,21 @@ impl TeaclaveManagement for TeaclaveManagementService {
         let request = request.message;
         let ts: TaskState = self
             .read_from_db(&request.task_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         let mut task: Task<Approve> = ts.try_into().map_err(|e| {
             log::warn!("Approve state error: {:?}", e);
-            ServiceError::PermissionDenied
+            TeaclaveManagementServiceError::PermissionDenied
         })?;
 
         task.approve(&user_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         log::debug!("ApproveTask: approve:{:?}", task);
 
         let ts: TaskState = task.into();
         self.write_to_db(&ts)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         Ok(ApproveTaskResponse)
     }
@@ -479,20 +469,23 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let ts: TaskState = self
             .read_from_db(&request.task_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         // Early validation
-        ensure!(ts.has_creator(&user_id), ServiceError::PermissionDenied);
+        ensure!(
+            ts.has_creator(&user_id),
+            TeaclaveManagementServiceError::PermissionDenied
+        );
 
         let function: Function = self
             .read_from_db(&ts.function_id)
-            .map_err(|_| ServiceError::PermissionDenied)?;
+            .map_err(|_| TeaclaveManagementServiceError::PermissionDenied)?;
 
         log::debug!("InvokeTask: get function: {:?}", function);
 
         let mut task: Task<Stage> = ts.try_into().map_err(|e| {
             log::warn!("Stage state error: {:?}", e);
-            ServiceError::PermissionDenied
+            TeaclaveManagementServiceError::PermissionDenied
         })?;
 
         log::debug!("InvokeTask: get task: {:?}", task);
@@ -505,7 +498,7 @@ impl TeaclaveManagement for TeaclaveManagementService {
 
         let ts: TaskState = task.into();
         self.write_to_db(&ts)
-            .map_err(|_| ServiceError::StorageError)?;
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?;
 
         Ok(InvokeTaskResponse)
     }
@@ -547,7 +540,9 @@ impl TeaclaveManagementService {
         &self,
         meta: &HashMap<String, String>,
     ) -> TeaclaveServiceResponseResult<UserID> {
-        let user_id = meta.get("id").ok_or_else(|| ServiceError::InvalidRequest)?;
+        let user_id = meta
+            .get("id")
+            .ok_or_else(|| TeaclaveManagementServiceError::InvalidRequest)?;
         Ok(user_id.to_string().into())
     }
 
@@ -578,13 +573,15 @@ impl TeaclaveManagementService {
     }
 
     fn enqueue_to_db(&self, key: &[u8], item: &impl Storable) -> TeaclaveServiceResponseResult<()> {
-        let value = item.to_vec().map_err(|_| ServiceError::DataError)?;
+        let value = item
+            .to_vec()
+            .map_err(|_| TeaclaveManagementServiceError::DataError)?;
         let enqueue_request = EnqueueRequest::new(key, value);
         let _enqueue_response = self
             .storage_client
             .clone()
             .lock()
-            .map_err(|_| ServiceError::StorageError)?
+            .map_err(|_| TeaclaveManagementServiceError::StorageError)?
             .enqueue(enqueue_request)?;
         Ok(())
     }
diff --git a/binder/src/lib.rs b/services/scheduler/enclave/src/error.rs
similarity index 61%
copy from binder/src/lib.rs
copy to services/scheduler/enclave/src/error.rs
index ee8ee37..48a0ab2 100644
--- a/binder/src/lib.rs
+++ b/services/scheduler/enclave/src/error.rs
@@ -15,20 +15,23 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![cfg_attr(feature = "mesalock_sgx", no_std)]
-#[cfg(feature = "mesalock_sgx")]
-extern crate sgx_tstd as std;
+use std::prelude::v1::*;
 
-pub mod ipc;
-pub mod proto;
+use teaclave_types::TeaclaveServiceResponseError;
+use thiserror::Error;
 
-cfg_if::cfg_if! {
-    if #[cfg(feature = "app")]  {
-        mod binder;
-        mod ocall;
-        pub use binder::TeeBinder;
-    } else if #[cfg(feature = "mesalock_sgx")] {
-        mod macros;
-        pub use teaclave_binder_attribute::handle_ecall;
+#[derive(Error, Debug)]
+pub enum TeaclaveSchedulerError {
+    #[error("scheduler service error")]
+    SchedulerServiceErr,
+    #[error("data error")]
+    DataError,
+    #[error("storage error")]
+    StorageError,
+}
+
+impl From<TeaclaveSchedulerError> for TeaclaveServiceResponseError {
+    fn from(error: TeaclaveSchedulerError) -> Self {
+        TeaclaveServiceResponseError::RequestError(error.to_string())
     }
 }
diff --git a/services/scheduler/enclave/src/lib.rs b/services/scheduler/enclave/src/lib.rs
index 9cd60de..a7c287b 100644
--- a/services/scheduler/enclave/src/lib.rs
+++ b/services/scheduler/enclave/src/lib.rs
@@ -27,9 +27,6 @@ use std::prelude::v1::*;
 extern crate log;
 use anyhow::{anyhow, Result};
 
-mod publisher;
-mod service;
-
 use teaclave_attestation::{verifier, AttestationConfig, RemoteAttestation};
 use teaclave_binder::proto::{
     ECallCommand, FinalizeEnclaveInput, FinalizeEnclaveOutput, InitEnclaveInput, InitEnclaveOutput,
@@ -47,6 +44,10 @@ use teaclave_service_enclave_utils::create_trusted_storage_endpoint;
 use teaclave_service_enclave_utils::ServiceEnclave;
 use teaclave_types::{EnclaveInfo, TeeServiceError, TeeServiceResult};
 
+mod error;
+mod publisher;
+mod service;
+
 fn start_service(config: &RuntimeConfig) -> Result<()> {
     let listen_address = config.internal_endpoints.scheduler.listen_address;
     let attestation_config = AttestationConfig::from_teaclave_config(&config)?;
diff --git a/services/scheduler/enclave/src/service.rs b/services/scheduler/enclave/src/service.rs
index 7f86eeb..8c681f5 100644
--- a/services/scheduler/enclave/src/service.rs
+++ b/services/scheduler/enclave/src/service.rs
@@ -15,16 +15,13 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![allow(unused_imports)]
-#![allow(unused_variables)]
+use crate::error::TeaclaveSchedulerError;
 
 use std::collections::VecDeque;
 use std::convert::TryInto;
-#[cfg(feature = "mesalock_sgx")]
 use std::prelude::v1::*;
 use std::sync::{Arc, SgxMutex as Mutex};
 
-use std::collections::HashMap;
 use teaclave_proto::teaclave_scheduler_service::*;
 use teaclave_proto::teaclave_storage_service::*;
 use teaclave_rpc::endpoint::Endpoint;
@@ -35,23 +32,6 @@ use uuid::Uuid;
 
 use anyhow::anyhow;
 use anyhow::Result;
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-pub enum TeaclaveSchedulerError {
-    #[error("scheduler service error")]
-    SchedulerServiceErr,
-    #[error("data error")]
-    DataError,
-    #[error("storage error")]
-    StorageError,
-}
-
-impl From<TeaclaveSchedulerError> for TeaclaveServiceResponseError {
-    fn from(error: TeaclaveSchedulerError) -> Self {
-        TeaclaveServiceResponseError::RequestError(error.to_string())
-    }
-}
 
 #[teaclave_service(teaclave_scheduler_service, TeaclaveScheduler, TeaclaveSchedulerError)]
 #[derive(Clone)]
@@ -146,7 +126,7 @@ impl TeaclaveScheduler for TeaclaveSchedulerService {
     // Subscriber
     fn subscribe(
         &self,
-        request: Request<SubscribeRequest>,
+        _request: Request<SubscribeRequest>,
     ) -> TeaclaveServiceResponseResult<SubscribeResponse> {
         // TODO: subscribe a specific topic
         unimplemented!()
@@ -154,7 +134,7 @@ impl TeaclaveScheduler for TeaclaveSchedulerService {
 
     fn pull_task(
         &self,
-        request: Request<PullTaskRequest>,
+        _request: Request<PullTaskRequest>,
     ) -> TeaclaveServiceResponseResult<PullTaskResponse> {
         let key = StagedTask::get_queue_key().as_bytes();
         let staged_task = self.pull_staged_task(key)?;
diff --git a/binder/src/lib.rs b/services/storage/enclave/src/error.rs
similarity index 61%
copy from binder/src/lib.rs
copy to services/storage/enclave/src/error.rs
index ee8ee37..617c53a 100644
--- a/binder/src/lib.rs
+++ b/services/storage/enclave/src/error.rs
@@ -15,20 +15,23 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![cfg_attr(feature = "mesalock_sgx", no_std)]
-#[cfg(feature = "mesalock_sgx")]
-extern crate sgx_tstd as std;
+use std::prelude::v1::*;
 
-pub mod ipc;
-pub mod proto;
+use teaclave_types::TeaclaveServiceResponseError;
+use thiserror::Error;
 
-cfg_if::cfg_if! {
-    if #[cfg(feature = "app")]  {
-        mod binder;
-        mod ocall;
-        pub use binder::TeeBinder;
-    } else if #[cfg(feature = "mesalock_sgx")] {
-        mod macros;
-        pub use teaclave_binder_attribute::handle_ecall;
+#[derive(Error, Debug)]
+pub(crate) enum TeaclaveStorageError {
+    #[error("connection error")]
+    Connection,
+    #[error("leveldb error")]
+    LevelDb(#[from] rusty_leveldb::Status),
+    #[error("none error")]
+    None,
+}
+
+impl From<TeaclaveStorageError> for TeaclaveServiceResponseError {
+    fn from(error: TeaclaveStorageError) -> Self {
+        TeaclaveServiceResponseError::RequestError(error.to_string())
     }
 }
diff --git a/services/storage/enclave/src/lib.rs b/services/storage/enclave/src/lib.rs
index 15a3382..a456bed 100644
--- a/services/storage/enclave/src/lib.rs
+++ b/services/storage/enclave/src/lib.rs
@@ -45,6 +45,7 @@ use teaclave_rpc::server::SgxTrustedTlsServer;
 use teaclave_service_enclave_utils::ServiceEnclave;
 use teaclave_types::{EnclaveInfo, TeeServiceError, TeeServiceResult};
 
+mod error;
 mod proxy;
 mod service;
 
diff --git a/services/storage/enclave/src/proxy.rs b/services/storage/enclave/src/proxy.rs
index 2466d42..62e73e0 100644
--- a/services/storage/enclave/src/proxy.rs
+++ b/services/storage/enclave/src/proxy.rs
@@ -15,7 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use crate::service::TeaclaveStorageError;
+use crate::error::TeaclaveStorageError;
 use std::prelude::v1::*;
 use std::sync::mpsc::{channel, Sender};
 use teaclave_proto::teaclave_storage_service::{TeaclaveStorageRequest, TeaclaveStorageResponse};
diff --git a/services/storage/enclave/src/service.rs b/services/storage/enclave/src/service.rs
index 87b30f8..899eac9 100644
--- a/services/storage/enclave/src/service.rs
+++ b/services/storage/enclave/src/service.rs
@@ -15,6 +15,7 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use crate::error::TeaclaveStorageError;
 use crate::proxy::ProxyRequest;
 use rusty_leveldb::DB;
 use std::cell::RefCell;
@@ -26,24 +27,7 @@ use teaclave_proto::teaclave_storage_service::{
 };
 use teaclave_rpc::Request;
 use teaclave_service_enclave_utils::{bail, teaclave_service};
-use teaclave_types::{TeaclaveServiceResponseError, TeaclaveServiceResponseResult};
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-pub(crate) enum TeaclaveStorageError {
-    #[error("connection error")]
-    Connection,
-    #[error("leveldb error")]
-    LevelDb(#[from] rusty_leveldb::Status),
-    #[error("none error")]
-    None,
-}
-
-impl From<TeaclaveStorageError> for TeaclaveServiceResponseError {
-    fn from(error: TeaclaveStorageError) -> Self {
-        TeaclaveServiceResponseError::RequestError(error.to_string())
-    }
-}
+use teaclave_types::TeaclaveServiceResponseResult;
 
 #[teaclave_service(teaclave_storage_service, TeaclaveStorage, TeaclaveStorageError)]
 pub(crate) struct TeaclaveStorageService {
diff --git a/types/src/lib.rs b/types/src/attestation.rs
similarity index 64%
copy from types/src/lib.rs
copy to types/src/attestation.rs
index 7045d4a..0b1e2c0 100644
--- a/types/src/lib.rs
+++ b/types/src/attestation.rs
@@ -15,83 +15,13 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#![cfg_attr(feature = "mesalock_sgx", no_std)]
-#[cfg(feature = "mesalock_sgx")]
-#[macro_use]
-extern crate sgx_tstd as std;
-
 #[cfg(feature = "mesalock_sgx")]
 use std::prelude::v1::*;
 
-use anyhow::Result;
-use anyhow::{bail, ensure};
 use std::collections::HashMap;
 
-use serde::{Deserialize, Deserializer, Serialize};
-
-use thiserror::Error;
-
-mod crypto;
-pub use crypto::*;
-mod worker;
-pub use worker::*;
-mod file;
-pub use file::*;
-mod function;
-pub use function::*;
-mod staged_task;
-pub use staged_task::*;
-mod staged_function;
-pub use staged_function::*;
-mod staged_file;
-pub use staged_file::*;
-mod storage;
-pub use storage::Storable;
-mod task;
-pub use task::*;
-mod task_state;
-pub use task_state::*;
-mod file_agent;
-pub use file_agent::*;
-mod macros;
-pub use macros::*;
-
-/// Status for Ecall
-#[repr(C)]
-#[derive(Debug, Serialize, Deserialize)]
-pub struct EnclaveStatus(pub u32);
-
-/// Status for Ocall
-pub type UntrustedStatus = EnclaveStatus;
-
-impl EnclaveStatus {
-    pub fn default() -> EnclaveStatus {
-        EnclaveStatus(0)
-    }
-
-    pub fn is_err(&self) -> bool {
-        match self.0 {
-            0 => false,
-            _ => true,
-        }
-    }
-
-    pub fn is_err_ffi_outbuf(&self) -> bool {
-        self.0 == 0x0000_000c
-    }
-}
-
-#[derive(thiserror::Error, Debug, Serialize, Deserialize)]
-pub enum TeeServiceError {
-    #[error("SgxError")]
-    SgxError,
-    #[error("ServiceError")]
-    ServiceError,
-    #[error("CommandNotRegistered")]
-    CommandNotRegistered,
-}
-
-pub type TeeServiceResult<T> = std::result::Result<T, TeeServiceError>;
+use anyhow::{bail, ensure, Result};
+use serde::{Deserialize, Deserializer};
 
 pub type SgxMeasurement = [u8; sgx_types::SGX_HASH_SIZE];
 
@@ -209,31 +139,3 @@ impl EnclaveInfo {
         }
     }
 }
-
-#[derive(Error, Debug, Serialize, Deserialize, PartialEq)]
-#[serde(rename_all = "snake_case")]
-pub enum TeaclaveServiceResponseError {
-    #[error("Request error: {0}")]
-    RequestError(String),
-    #[error("Connection error: {0}")]
-    ConnectionError(String),
-    #[error("Internal error: {0}")]
-    InternalError(String),
-}
-
-impl From<anyhow::Error> for TeaclaveServiceResponseError {
-    fn from(error: anyhow::Error) -> Self {
-        TeaclaveServiceResponseError::RequestError(error.to_string())
-    }
-}
-
-pub type TeaclaveServiceResponseResult<T> = std::result::Result<T, TeaclaveServiceResponseError>;
-
-#[cfg(feature = "enclave_unit_test")]
-pub mod tests {
-    use super::*;
-
-    pub fn run_tests() -> bool {
-        worker::tests::run_tests()
-    }
-}
diff --git a/types/src/error.rs b/types/src/error.rs
new file mode 100644
index 0000000..9ed5b84
--- /dev/null
+++ b/types/src/error.rs
@@ -0,0 +1,81 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::fmt;
+#[cfg(feature = "mesalock_sgx")]
+use std::prelude::v1::*;
+
+use serde::{Deserialize, Serialize};
+use thiserror::Error;
+
+pub type SgxStatus = sgx_types::sgx_status_t;
+
+/// Status for Ecall
+#[repr(C)]
+#[derive(Debug, Serialize, Deserialize, Default)]
+pub struct ECallStatus(pub u32);
+
+impl ECallStatus {
+    pub fn is_err(&self) -> bool {
+        self.0 != 0
+    }
+
+    pub fn is_ok(&self) -> bool {
+        self.0 == 0
+    }
+
+    pub fn is_err_ffi_outbuf(&self) -> bool {
+        self.0 == 0x0000_000c
+    }
+}
+
+impl fmt::Display for ECallStatus {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
+
+#[derive(Error, Debug, Serialize, Deserialize)]
+pub enum TeeServiceError {
+    #[error("SgxError")]
+    SgxError,
+    #[error("ServiceError")]
+    ServiceError,
+    #[error("CommandNotRegistered")]
+    CommandNotRegistered,
+}
+
+pub type TeeServiceResult<T> = std::result::Result<T, TeeServiceError>;
+
+#[derive(Error, Debug, Serialize, Deserialize, PartialEq)]
+#[serde(rename_all = "snake_case")]
+pub enum TeaclaveServiceResponseError {
+    #[error("Request error: {0}")]
+    RequestError(String),
+    #[error("Connection error: {0}")]
+    ConnectionError(String),
+    #[error("Internal error: {0}")]
+    InternalError(String),
+}
+
+impl From<anyhow::Error> for TeaclaveServiceResponseError {
+    fn from(error: anyhow::Error) -> Self {
+        TeaclaveServiceResponseError::RequestError(error.to_string())
+    }
+}
+
+pub type TeaclaveServiceResponseResult<T> = std::result::Result<T, TeaclaveServiceResponseError>;
diff --git a/types/src/lib.rs b/types/src/lib.rs
index 7045d4a..74d62f3 100644
--- a/types/src/lib.rs
+++ b/types/src/lib.rs
@@ -23,211 +23,35 @@ extern crate sgx_tstd as std;
 #[cfg(feature = "mesalock_sgx")]
 use std::prelude::v1::*;
 
-use anyhow::Result;
-use anyhow::{bail, ensure};
-use std::collections::HashMap;
-
-use serde::{Deserialize, Deserializer, Serialize};
-
-use thiserror::Error;
-
+mod attestation;
 mod crypto;
-pub use crypto::*;
-mod worker;
-pub use worker::*;
+mod error;
 mod file;
-pub use file::*;
+mod file_agent;
 mod function;
-pub use function::*;
-mod staged_task;
-pub use staged_task::*;
-mod staged_function;
-pub use staged_function::*;
+mod macros;
 mod staged_file;
-pub use staged_file::*;
+mod staged_function;
+mod staged_task;
 mod storage;
-pub use storage::Storable;
 mod task;
-pub use task::*;
 mod task_state;
-pub use task_state::*;
-mod file_agent;
+mod worker;
+
+pub use attestation::*;
+pub use crypto::*;
+pub use error::*;
+pub use file::*;
 pub use file_agent::*;
-mod macros;
+pub use function::*;
 pub use macros::*;
-
-/// Status for Ecall
-#[repr(C)]
-#[derive(Debug, Serialize, Deserialize)]
-pub struct EnclaveStatus(pub u32);
-
-/// Status for Ocall
-pub type UntrustedStatus = EnclaveStatus;
-
-impl EnclaveStatus {
-    pub fn default() -> EnclaveStatus {
-        EnclaveStatus(0)
-    }
-
-    pub fn is_err(&self) -> bool {
-        match self.0 {
-            0 => false,
-            _ => true,
-        }
-    }
-
-    pub fn is_err_ffi_outbuf(&self) -> bool {
-        self.0 == 0x0000_000c
-    }
-}
-
-#[derive(thiserror::Error, Debug, Serialize, Deserialize)]
-pub enum TeeServiceError {
-    #[error("SgxError")]
-    SgxError,
-    #[error("ServiceError")]
-    ServiceError,
-    #[error("CommandNotRegistered")]
-    CommandNotRegistered,
-}
-
-pub type TeeServiceResult<T> = std::result::Result<T, TeeServiceError>;
-
-pub type SgxMeasurement = [u8; sgx_types::SGX_HASH_SIZE];
-
-#[derive(Debug, Deserialize, Copy, Clone, Eq, PartialEq)]
-pub struct EnclaveMeasurement {
-    #[serde(deserialize_with = "from_hex")]
-    pub mr_signer: SgxMeasurement,
-    #[serde(deserialize_with = "from_hex")]
-    pub mr_enclave: SgxMeasurement,
-}
-
-impl EnclaveMeasurement {
-    pub fn new(mr_enclave: SgxMeasurement, mr_signer: SgxMeasurement) -> Self {
-        Self {
-            mr_enclave,
-            mr_signer,
-        }
-    }
-}
-
-/// Deserializes a hex string to a `SgxMeasurement` (i.e., [0; 32]).
-pub fn from_hex<'de, D>(deserializer: D) -> Result<SgxMeasurement, D::Error>
-where
-    D: Deserializer<'de>,
-{
-    use serde::de::Error;
-    String::deserialize(deserializer).and_then(|string| {
-        let v = hex::decode(&string).map_err(|_| Error::custom("ParseError"))?;
-        let mut array = [0; sgx_types::SGX_HASH_SIZE];
-        let bytes = &v[..array.len()]; // panics if not enough data
-        array.copy_from_slice(bytes);
-        Ok(array)
-    })
-}
-
-#[derive(Clone)]
-pub struct EnclaveAttr {
-    pub measurement: EnclaveMeasurement,
-}
-
-pub struct EnclaveInfo {
-    pub measurements: HashMap<String, EnclaveMeasurement>,
-}
-
-#[derive(Debug, Deserialize)]
-#[serde(transparent)]
-struct EnclaveInfoToml(HashMap<String, EnclaveMeasurement>);
-
-impl EnclaveInfo {
-    pub fn verify_and_new<T, U>(
-        enclave_info: &[u8],
-        public_keys: &[T],
-        signatures: &[U],
-    ) -> Result<Self>
-    where
-        T: AsRef<[u8]>,
-        U: AsRef<[u8]>,
-    {
-        ensure!(
-            signatures.len() <= public_keys.len(),
-            "Invalid number of public keys"
-        );
-        if !Self::verify(enclave_info, public_keys, signatures) {
-            bail!("Invalid enclave_info");
-        }
-
-        Ok(Self::from_bytes(enclave_info))
-    }
-
-    pub fn from_bytes(enclave_info: &[u8]) -> Self {
-        let config: EnclaveInfoToml = toml::from_slice(enclave_info)
-            .expect("Content not correct, unable to load enclave info.");
-        let mut info_map = std::collections::HashMap::new();
-        for (k, v) in config.0 {
-            info_map.insert(k, EnclaveMeasurement::new(v.mr_enclave, v.mr_signer));
-        }
-
-        Self {
-            measurements: info_map,
-        }
-    }
-
-    pub fn verify<T, U>(enclave_info: &[u8], public_keys: &[T], signatures: &[U]) -> bool
-    where
-        T: AsRef<[u8]>,
-        U: AsRef<[u8]>,
-    {
-        use ring::signature;
-
-        for s in signatures {
-            let mut verified = false;
-            for k in public_keys {
-                if signature::UnparsedPublicKey::new(&signature::RSA_PKCS1_2048_8192_SHA256, k)
-                    .verify(enclave_info, s.as_ref())
-                    .is_ok()
-                {
-                    verified = true;
-                }
-            }
-            if !verified {
-                return false;
-            }
-        }
-
-        true
-    }
-
-    pub fn get_enclave_attr(&self, service_name: &str) -> Option<EnclaveAttr> {
-        if let Some(measurement) = self.measurements.get(service_name) {
-            Some(EnclaveAttr {
-                measurement: *measurement,
-            })
-        } else {
-            None
-        }
-    }
-}
-
-#[derive(Error, Debug, Serialize, Deserialize, PartialEq)]
-#[serde(rename_all = "snake_case")]
-pub enum TeaclaveServiceResponseError {
-    #[error("Request error: {0}")]
-    RequestError(String),
-    #[error("Connection error: {0}")]
-    ConnectionError(String),
-    #[error("Internal error: {0}")]
-    InternalError(String),
-}
-
-impl From<anyhow::Error> for TeaclaveServiceResponseError {
-    fn from(error: anyhow::Error) -> Self {
-        TeaclaveServiceResponseError::RequestError(error.to_string())
-    }
-}
-
-pub type TeaclaveServiceResponseResult<T> = std::result::Result<T, TeaclaveServiceResponseError>;
+pub use staged_file::*;
+pub use staged_function::*;
+pub use staged_task::*;
+pub use storage::*;
+pub use task::*;
+pub use task_state::*;
+pub use worker::*;
 
 #[cfg(feature = "enclave_unit_test")]
 pub mod tests {


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