// Copyright (C) 2017-2018 Baidu, Inc. All Rights Reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materials provided with the
//    distribution.
//  * Neither the name of Baidu, Inc., nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

//!
//! Cryptographic Functions
//!
use sgx_types::*;
use sgx_types::marker::ContiguousMemory;
use core::ops::{Drop, DerefMut};
use core::ptr;
use core::mem;
use core::cell::{Cell, RefCell};

///
/// The rsgx_sha256_msg function performs a standard SHA256 hash over the input data buffer.
///
/// # Description
///
/// The rsgx_sha256_msg function performs a standard SHA256 hash over the input data buffer.
/// Only a 256-bit version of the SHA hash is supported. (Other sizes, for example 512, are
/// not supported in this minimal cryptography library).
///
/// The function should be used if the complete input data stream is available.
/// Otherwise, the Init, Update… Update, Final procedure should be used to compute
/// a SHA256 bit hash over multiple input data sets.
///
/// # Parameters
///
/// **src**
///
/// A pointer to the input data stream to be hashed.
///
/// # Requirements
///
/// Library: libsgx_tcrypto.a
///
/// # Return value
///
/// The 256-bit hash that has been SHA256 calculated
///
/// # Errors
///
/// **SGX_ERROR_INVALID_PARAMETER**
///
/// Input pointers are invalid.
///
/// **SGX_ERROR_OUT_OF_MEMORY**
///
/// Not enough memory is available to complete this operation.
///
/// **SGX_ERROR_UNEXPECTED**
///
/// The SHA256 hash calculation failed.
///
pub fn rsgx_sha256_msg<T>(src: &T) -> SgxResult<sgx_sha256_hash_t>
    where T: Copy + ContiguousMemory {

    let size = mem::size_of::<T>();
    if size == 0 {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if size > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let mut hash = sgx_sha256_hash_t::default();
    let ret = unsafe { sgx_sha256_msg(src as * const _ as * const u8, size as u32, &mut hash as * mut sgx_sha256_hash_t) };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(hash),
        _ => Err(ret),
    }
}

///
/// The rsgx_sha256_slice function performs a standard SHA256 hash over the input data buffer.
///
pub fn rsgx_sha256_slice<T>(src: &[T]) -> SgxResult<sgx_sha256_hash_t>
    where T: Copy + ContiguousMemory {

    let size = mem::size_of_val(src);
    if size == 0 {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if size > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let mut hash = sgx_sha256_hash_t::default();
    let ret = unsafe { sgx_sha256_msg(src.as_ptr() as * const u8, size as u32, &mut hash as * mut sgx_sha256_hash_t) };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(hash),
        _ => Err(ret),
    }
}

fn rsgx_sha256_init(sha_handle: &mut sgx_sha_state_handle_t) -> sgx_status_t {

    unsafe {
        sgx_sha256_init(sha_handle as * mut _ as * mut sgx_sha_state_handle_t)
    }
}

fn rsgx_sha256_update_msg<T>(src: &T, sha_handle: sgx_sha_state_handle_t) -> sgx_status_t
    where T: Copy + ContiguousMemory {

    let size = mem::size_of::<T>();
    if size == 0 {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if size > u32::max_value() as usize {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }

    unsafe {
        sgx_sha256_update(src as * const _ as * const u8, size as u32, sha_handle)
    }
}

fn rsgx_sha256_update_slice<T>(src: &[T], sha_handle: sgx_sha_state_handle_t) -> sgx_status_t
    where T: Copy + ContiguousMemory {

    let size = mem::size_of_val(src);
    if size == 0 {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if size > u32::max_value() as usize {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    unsafe {
        sgx_sha256_update(src.as_ptr() as * const u8, size as u32, sha_handle)
    }
}

fn rsgx_sha256_get_hash(sha_handle: sgx_sha_state_handle_t, hash: &mut sgx_sha256_hash_t) -> sgx_status_t {

    unsafe { sgx_sha256_get_hash(sha_handle, hash as * mut sgx_sha256_hash_t) }
}

fn rsgx_sha256_close(sha_handle: sgx_sha_state_handle_t) -> sgx_status_t {

     unsafe { sgx_sha256_close(sha_handle) }
}

///
/// SHA algorithm context state.
///
/// This is a handle to the context state used by the cryptography library to perform an iterative SHA256 hash.
/// The algorithm stores the intermediate results of performing the hash calculation over data sets.
///
pub struct SgxShaHandle {
    handle: RefCell<sgx_sha_state_handle_t>,
    initflag: Cell<bool>,
}

impl SgxShaHandle {

    ///
    /// Constructs a new, empty SgxShaHandle.
    ///
    pub fn new() -> Self {
        SgxShaHandle{
            handle: RefCell::new(ptr::null_mut() as sgx_sha_state_handle_t),
            initflag: Cell::new(false),
        }
    }

    ///
    /// init returns an allocated and initialized SHA algorithm context state.
    ///
    /// This should be part of the Init, Update … Update, Final process when the SHA hash is to be performed
    /// over multiple datasets. If a complete dataset is available, the recommend call is rsgx_sha256_msg to
    /// perform the hash in a single call.
    ///
    /// # Description
    ///
    /// Calling init is the first set in performing a SHA256 hash over multiple datasets. The caller does not
    /// allocate memory for the SHA256 state that this function returns. The state is specific to the implementation
    /// of the cryptography library; thus the allocation is performed by the library itself. If the hash over the
    /// desired datasets is completed or any error occurs during the hash calculation process, sgx_sha256_close should
    /// be called to free the state allocated by this algorithm.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_OUT_OF_MEMORY**
    ///
    /// Not enough memory is available to complete this operation.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// The SHA256 state is not initialized properly due to an internal cryptography library failure.
    ///
    pub fn init(&self) -> SgxError {

        if self.initflag.get() == true {
            return Ok(());
        }

        let ret = rsgx_sha256_init(self.handle.borrow_mut().deref_mut());
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                self.initflag.set(true);
                Ok(())
            },
            _ => Err(ret),
        }
    }

    ///
    /// update_msg performs a SHA256 hash over the input dataset provided.
    ///
    /// This function supports an iterative calculation of the hash over multiple datasets where the
    /// sha_handle contains the intermediate results of the hash calculation over previous datasets.
    ///
    /// # Description
    ///
    /// This function should be used as part of a SHA256 calculation over multiple datasets.
    /// If a SHA256 hash is needed over a single data set, function rsgx_sha256_msg should be used instead.
    /// Prior to calling this function on the first dataset, the init function must be called first to allocate
    /// and initialize the SHA256 state structure which will hold intermediate hash results over earlier datasets.
    /// The function get_hash should be used to obtain the hash after the final dataset has been processed
    /// by this function.
    ///
    /// # Parameters
    ///
    /// **src**
    ///
    /// A pointer to the input data stream to be hashed.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_INVALID_STATE**
    ///
    /// The SHA256 state is not initialized.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// An internal cryptography library failure occurred while performing the SHA256 hash calculation.
    ///
    pub fn update_msg<T>(&self, src: &T) -> SgxError
        where T: Copy + ContiguousMemory {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let ret = rsgx_sha256_update_msg(src, *self.handle.borrow());
        match ret {
            sgx_status_t::SGX_SUCCESS => Ok(()),
            _ => Err(ret),
        }
    }

    ///
    /// update_slice performs a SHA256 hash over the input dataset provided.
    ///
    pub fn update_slice<T>(&self, src: &[T]) -> SgxError
        where T: Copy + ContiguousMemory {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let ret = rsgx_sha256_update_slice(src, *self.handle.borrow());
        match ret {
            sgx_status_t::SGX_SUCCESS => Ok(()),
            _ => Err(ret),
        }
    }

    ///
    /// get_hash obtains the SHA256 hash after the final dataset has been processed.
    ///
    /// # Description
    ///
    /// This function returns the hash after performing the SHA256 calculation over one or more datasets
    /// using the update function.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Return value
    ///
    /// The 256-bit hash that has been SHA256 calculated
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_INVALID_STATE**
    ///
    /// The SHA256 state is not initialized.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// The SHA256 state passed in is likely problematic causing an internal cryptography library failure.
    ///
    pub fn get_hash(&self) -> SgxResult<sgx_sha256_hash_t> {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let mut hash = sgx_sha256_hash_t::default();
        let ret = rsgx_sha256_get_hash(*self.handle.borrow(), &mut hash);
        match ret {
            sgx_status_t::SGX_SUCCESS => Ok(hash),
            _ => Err(ret),
        }
    }

    ///
    /// close cleans up and deallocates the SHA256 state that was allocated in function init.
    ///
    /// # Description
    ///
    /// Calling close is the last step after performing a SHA256 hash over multiple datasets.
    /// The caller uses this function to deallocate memory used to store the SHA256 calculation state.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The input handle is invalid.
    ///
    pub fn close(&self) -> SgxError {

        if self.initflag.get() == false {
            return Ok(());
        }

        let ret = {
            let handle = *self.handle.borrow();
            if handle.is_null() == true {
                sgx_status_t::SGX_SUCCESS
            } else {
                rsgx_sha256_close(handle)
            }
        };

        match ret {
            sgx_status_t::SGX_SUCCESS => {
                self.initflag.set(false);
                *self.handle.borrow_mut() = ptr::null_mut();
                Ok(())
            },
            _ => Err(ret),
        }
    }
}

impl Default for SgxShaHandle {
    fn default() -> Self {
        Self::new()
    }
}

impl Drop for SgxShaHandle {

    ///
    /// drop cleans up and deallocates the SHA256 state that was allocated in function init.
    ///
    fn drop(&mut self) {
        let _ = self.close();
    }
}

///
/// rsgx_rijndael128GCM_encrypt performs a Rijndael AES-GCM encryption operation.
///
/// Only a 128bit key size is supported by this Intel(R) SGX SDK cryptography library.
///
/// # Description
///
/// The Galois/Counter Mode (GCM) is a mode of operation of the AES algorithm.
/// GCM [NIST SP 800-38D] uses a variation of the counter mode of operation for
/// encryption. GCM assures authenticity of the confidential data (of up to about
/// 64 GB per invocation) using a universal hash function defined over a binary
/// finite field (the Galois field).
///
/// GCM can also provide authentication assurance for additional data (of practically
/// unlimited length per invocation) that is not encrypted. GCM provides
/// stronger authentication assurance than a (non-cryptographic) checksum or
/// error detecting code. In particular, GCM can detect both accidental modifications
/// of the data and intentional, unauthorized modifications.
///
/// It is recommended that the source and destination data buffers are allocated
/// within the enclave. The AAD buffer could be allocated within or outside
/// enclave memory. The use of AAD data buffer could be information identifying
/// the encrypted data since it will remain in clear text.
///
/// # Parameters
///
/// **key**
///
/// A pointer to key to be used in the AES-GCM encryption operation. The size must be 128 bits.
///
/// **src**
///
/// A pointer to the input data stream to be encrypted. Buffer content could be empty if there is AAD text.
///
/// **iv**
///
/// A pointer to the initialization vector to be used in the AES-GCM calculation. NIST AES-GCM recommended
/// IV size is 96 bits (12 bytes).
///
/// **aad**
///
/// A pointer to an optional additional authentication data buffer which is used in the GCM MAC calculation.
/// The data in this buffer will not be encrypted. The field is optional and content could be empty.
///
/// **dst**
///
/// A pointer to the output encrypted data buffer. This buffer should be allocated by the calling code.
///
/// **mac**
///
/// This is the output GCM MAC performed over the input data buffer (data to be encrypted) as well as
/// the additional authentication data (this is optional data). The calling code should allocate this buffer.
///
/// # Requirements
///
/// Library: libsgx_tcrypto.a
///
/// # Errors
///
/// **SGX_ERROR_INVALID_PARAMETER**
///
/// If both source buffer and AAD buffer content are empty.
///
/// If IV Length is not equal to 12 (bytes).
///
/// **SGX_ERROR_OUT_OF_MEMORY**
///
/// Not enough memory is available to complete this operation.
///
/// **SGX_ERROR_UNEXPECTED**
///
/// An internal cryptography library failure occurred.
///
pub fn rsgx_rijndael128GCM_encrypt(key: &sgx_aes_gcm_128bit_key_t,
                                   src: &[u8],
                                   iv: &[u8],
                                   aad: &[u8],
                                   dst: &mut [u8],
                                   mac: &mut sgx_aes_gcm_128bit_tag_t) -> SgxError {

    let src_len = src.len();
    if src_len > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    let iv_len = iv.len();
    if iv_len != SGX_AESGCM_IV_SIZE {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    let aad_len = aad.len();
    if aad_len > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    let dst_len = dst.len();
    if dst_len > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if dst_len < src_len {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let ret = unsafe {
        let mut p_aad: * const u8 = ptr::null();
        if aad_len != 0 {
            p_aad = aad.as_ptr();
        }

        let mut p_src: * const u8 = ptr::null();
        let mut p_dst: * mut u8 = ptr::null_mut();
        if src_len != 0 {
            p_src = src.as_ptr();
            p_dst = dst.as_mut_ptr();
        }

        sgx_rijndael128GCM_encrypt(key as * const sgx_aes_gcm_128bit_key_t,
                                   p_src,
                                   src_len as u32,
                                   p_dst,
                                   iv.as_ptr(),
                                   iv_len as u32,
                                   p_aad,
                                   aad_len as u32,
                                   mac as * mut sgx_aes_gcm_128bit_tag_t)
    };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(()),
        _ => Err(ret),
    }
}

///
/// rsgx_rijndael128GCM_decrypt performs a Rijndael AES-GCM decryption operation.
///
/// Only a 128bit key size is supported by this Intel(R) SGX SDK cryptography library.
///
/// # Description
///
/// The Galois/Counter Mode (GCM) is a mode of operation of the AES algorithm.
/// GCM [NIST SP 800-38D] uses a variation of the counter mode of operation for
/// encryption. GCM assures authenticity of the confidential data (of up to about
/// 64 GB per invocation) using a universal hash function defined over a binary
/// finite field (the Galois field).
///
/// GCM can also provide authentication assurance for additional data (of practically
/// unlimited length per invocation) that is not encrypted. GCM provides
/// stronger authentication assurance than a (non-cryptographic) checksum or
/// error detecting code. In particular, GCM can detect both accidental modifications
/// of the data and intentional, unauthorized modifications.
///
/// It is recommended that the destination data buffer is allocated within the
/// enclave. The AAD buffer could be allocated within or outside enclave memory.
///
/// # Parameters
///
/// **key**
///
/// A pointer to key to be used in the AES-GCM decryption operation. The size must be 128 bits.
///
/// **src**
///
/// A pointer to the input data stream to be decrypted. Buffer content could be empty if there is AAD text.
///
/// **iv**
///
/// A pointer to the initialization vector to be used in the AES-GCM calculation. NIST AES-GCM recommended
/// IV size is 96 bits (12 bytes).
///
/// **aad**
///
/// A pointer to an optional additional authentication data buffer which is provided for the GCM MAC calculation
/// when encrypting. The data in this buffer was not encrypted. The field is optional and content could be empty.
///
/// **mac**
///
/// This is the GCM MAC that was performed over the input data buffer (data to be encrypted) as well as
/// the additional authentication data (this is optional data) during the encryption process (call to
/// rsgx_rijndael128GCM_encrypt).
///
/// **dst**
///
/// A pointer to the output decrypted data buffer. This buffer should be allocated by the calling code.
///
/// # Requirements
///
/// Library: libsgx_tcrypto.a
///
/// # Errors
///
/// **SGX_ERROR_INVALID_PARAMETER**
///
/// If both source buffer and AAD buffer content are empty.
///
/// If IV Length is not equal to 12 (bytes).
///
/// **SGX_ERROR_MAC_MISMATCH**
///
/// The input MAC does not match the MAC calculated.
///
/// **SGX_ERROR_OUT_OF_MEMORY**
///
/// Not enough memory is available to complete this operation.
///
/// **SGX_ERROR_UNEXPECTED**
///
/// An internal cryptography library failure occurred.
///
pub fn rsgx_rijndael128GCM_decrypt(key: &sgx_aes_gcm_128bit_key_t,
                                   src: &[u8],
                                   iv: &[u8],
                                   aad: &[u8],
                                   mac: &sgx_aes_gcm_128bit_tag_t,
                                   dst: &mut [u8]) -> SgxError {

    let src_len = src.len();
    if src_len > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    let iv_len = iv.len();
    if iv_len != SGX_AESGCM_IV_SIZE {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    let aad_len = aad.len();
    if aad_len > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    let dst_len = dst.len();
    if dst_len > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if dst_len < src_len {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let ret = unsafe {
        let mut p_aad: * const u8 =  ptr::null();
        if aad.len() != 0 {
            p_aad = aad.as_ptr();
        }

        let mut p_src: * const u8 = ptr::null();
        let mut p_dst: * mut u8 = ptr::null_mut();
        if src.len() != 0 {
            p_src = src.as_ptr();
            p_dst = dst.as_mut_ptr();
        }

        sgx_rijndael128GCM_decrypt(key as * const sgx_aes_gcm_128bit_key_t,
                                   p_src,
                                   src_len as u32,
                                   p_dst,
                                   iv.as_ptr(),
                                   iv_len as u32,
                                   p_aad,
                                   aad_len as u32,
                                   mac as * const sgx_aes_gcm_128bit_tag_t)
    };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(()),
        _ => Err(ret),
    }
}

///
/// The rsgx_rijndael128_cmac_msg function performs a standard 128bit CMAC hash over the input data buffer.
///
/// # Description
///
/// The rsgx_rijndael128_cmac_msg function performs a standard CMAC hash over the input data buffer.
/// Only a 128-bit version of the CMAC hash is supported.
///
/// The function should be used if the complete input data stream is available.
/// Otherwise, the Init, Update… Update, Final procedure should be used to compute
/// a CMAC hash over multiple input data sets.
///
/// # Parameters
///
/// **key**
///
/// A pointer to key to be used in the CMAC hash operation. The size must be 128 bits.
///
/// **src**
///
/// A pointer to the input data stream to be hashed.
///
/// # Requirements
///
/// Library: libsgx_tcrypto.a
///
/// # Return value
///
/// The 128-bit hash that has been CMAC calculated
///
/// # Errors
///
/// **SGX_ERROR_INVALID_PARAMETER**
///
/// The pointer is invalid.
///
/// **SGX_ERROR_OUT_OF_MEMORY**
///
/// Not enough memory is available to complete this operation.
///
/// **SGX_ERROR_UNEXPECTED**
///
/// An internal cryptography library failure occurred.
///
pub fn rsgx_rijndael128_cmac_msg<T>(key: &sgx_cmac_128bit_key_t, src: &T) -> SgxResult<sgx_cmac_128bit_tag_t>
    where T: Copy + ContiguousMemory {

    let size = mem::size_of::<T>();
    if size == 0 {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if size > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let mut mac = sgx_cmac_128bit_tag_t::default();
    let ret = unsafe {
        sgx_rijndael128_cmac_msg(key as * const sgx_cmac_128bit_key_t,
                                 src as * const _ as * const u8,
                                 size as u32,
                                 &mut mac as * mut sgx_cmac_128bit_tag_t)
    };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(mac),
        _ => Err(ret),
    }
}

///
/// The rsgx_rijndael128_cmac_slice function performs a standard 128bit CMAC hash over the input data buffer.
///
pub fn rsgx_rijndael128_cmac_slice<T>(key: &sgx_cmac_128bit_key_t, src: &[T]) -> SgxResult<sgx_cmac_128bit_tag_t>
    where T: Copy + ContiguousMemory {

    let size = mem::size_of_val(src);
    if size == 0 {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if size > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let mut mac = sgx_cmac_128bit_tag_t::default();
    let ret = unsafe {
        sgx_rijndael128_cmac_msg(key as * const sgx_cmac_128bit_key_t,
                                 src.as_ptr() as * const u8,
                                 size as u32,
                                 &mut mac as * mut sgx_cmac_128bit_tag_t)
    };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(mac),
        _ => Err(ret),
    }
}

fn rsgx_cmac128_init(key: &sgx_cmac_128bit_key_t, cmac_handle: &mut sgx_cmac_state_handle_t) -> sgx_status_t {

    unsafe {
        sgx_cmac128_init(key as * const sgx_cmac_128bit_key_t,
                         cmac_handle as * mut _ as * mut sgx_cmac_state_handle_t)
    }
}

fn rsgx_cmac128_update_msg<T>(src: &T, cmac_handle: sgx_cmac_state_handle_t) -> sgx_status_t
    where T: Copy + ContiguousMemory {

    let size = mem::size_of::<T>();
    if size == 0 {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if size > u32::max_value() as usize {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    unsafe {
        sgx_cmac128_update(src as * const _ as * const u8, size as u32, cmac_handle)
    }
}

fn rsgx_cmac128_update_slice<T>(src: &[T], cmac_handle: sgx_cmac_state_handle_t) -> sgx_status_t
    where T: Copy + ContiguousMemory {

    let size = mem::size_of_val(src);
    if size == 0 {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if size > u32::max_value() as usize {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    unsafe {
        sgx_cmac128_update(src.as_ptr() as * const _ as * const u8, size as u32, cmac_handle)
    }
}

fn rsgx_cmac128_final(cmac_handle: sgx_cmac_state_handle_t, hash: &mut sgx_cmac_128bit_tag_t) -> sgx_status_t {

    unsafe { sgx_cmac128_final(cmac_handle, hash as * mut sgx_cmac_128bit_tag_t) }
}

fn rsgx_cmac128_close(cmac_handle: sgx_cmac_state_handle_t) -> sgx_status_t {

    unsafe { sgx_cmac128_close(cmac_handle) }
}

///
/// CMAC algorithm context state.
///
/// This is a handle to the context state used by the cryptography library to perform an
/// iterative CMAC 128-bit hash. The algorithm stores the intermediate results of performing
/// the hash calculation over data sets.
///
pub struct SgxCmacHandle {
    handle: RefCell<sgx_cmac_state_handle_t>,
    initflag: Cell<bool>,
}

impl SgxCmacHandle {

    ///
    /// Constructs a new, empty SgxCmacHandle.
    ///
    pub fn new() -> Self {
        SgxCmacHandle{
            handle: RefCell::new(ptr::null_mut() as sgx_cmac_state_handle_t),
            initflag: Cell::new(false),
            }
    }

    ///
    /// init returns an allocated and initialized CMAC algorithm context state.
    ///
    /// This should be part of the Init, Update … Update, Final process when the CMAC hash is to be
    /// performed over multiple datasets. If a complete dataset is available, the recommended call
    /// is rsgx_rijndael128_cmac_msg to perform the hash in a single call.
    ///
    /// # Description
    ///
    /// Calling init is the first set in performing a CMAC 128-bit hash over multiple datasets.
    /// The caller does not allocate memory for the CMAC state that this function returns.
    /// The state is specific to the implementation of the cryptography library and thus the
    /// allocation is performed by the library itself. If the hash over the desired datasets is
    /// completed or any error occurs during the hash calculation process, sgx_cmac128_close should
    /// be called to free the state allocated by this algorithm.
    ///
    /// # Parameters
    ///
    /// **key**
    ///
    /// A pointer to key to be used in the CMAC hash operation. The size must be 128 bits.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_OUT_OF_MEMORY**
    ///
    /// Not enough memory is available to complete this operation.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// An internal cryptography library failure occurred.
    ///
    pub fn init(&self, key: &sgx_cmac_128bit_key_t) -> SgxError {

        if self.initflag.get() == true {
            return Ok(());
        }

        let ret = rsgx_cmac128_init(key, self.handle.borrow_mut().deref_mut());
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                self.initflag.set(true);
                Ok(())
            },
            _ => Err(ret),
        }
    }

    ///
    /// update_msg performs a CMAC 128-bit hash over the input dataset provided.
    ///
    /// This function supports an iterative calculation of the hash over multiple datasets where the
    /// cmac_handle contains the intermediate results of the hash calculation over previous datasets.
    ///
    /// # Description
    ///
    /// This function should be used as part of a CMAC 128-bit hash calculation over
    /// multiple datasets. If a CMAC hash is needed over a single data set, function
    /// rsgx_rijndael128_cmac128_msg should be used instead. Prior to calling
    /// this function on the first dataset, the init function must be called first to
    /// allocate and initialize the CMAC state structure which will hold intermediate
    /// hash results over earlier datasets. The function get_hash should be used
    /// to obtain the hash after the final dataset has been processed by this function.
    ///
    /// # Parameters
    ///
    /// **src**
    ///
    /// A pointer to the input data stream to be hashed.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_INVALID_STATE**
    ///
    /// The CMAC state is not initialized.
    ///
    /// **SGX_ERROR_OUT_OF_MEMORY**
    ///
    /// Not enough memory is available to complete this operation.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// An internal cryptography library failure occurred while performing the CMAC hash calculation.
    ///
    pub fn update_msg<T>(&self, src: &T) -> SgxError
        where T: Copy + ContiguousMemory {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let ret = rsgx_cmac128_update_msg(src, *self.handle.borrow());
        match ret {
            sgx_status_t::SGX_SUCCESS => Ok(()),
            _ => Err(ret),
        }
    }

    ///
    /// update_slice performs a CMAC 128-bit hash over the input dataset provided.
    ///
    pub fn update_slice<T>(&self, src: &[T]) -> SgxError
        where T: Copy + ContiguousMemory {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let ret = rsgx_cmac128_update_slice(src, *self.handle.borrow());
        match ret {
            sgx_status_t::SGX_SUCCESS => Ok(()),
            _ => Err(ret),
        }
    }

    ///
    /// get_hash obtains the CMAC 128-bit hash after the final dataset has been processed.
    ///
    /// # Description
    ///
    /// This function returns the hash after performing the CMAC 128-bit hash calculation
    /// over one or more datasets using the update function.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Return value
    ///
    /// The 128-bit hash that has been CMAC calculated
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_INVALID_STATE**
    ///
    /// The CMAC state is not initialized.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// The CMAC state passed in is likely problematic causing an internal cryptography library failure.
    ///
    pub fn get_hash(&self) -> SgxResult<sgx_cmac_128bit_tag_t> {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let mut hash = sgx_cmac_128bit_tag_t::default();
        let ret = rsgx_cmac128_final(*self.handle.borrow(), &mut hash);
        match ret {
            sgx_status_t::SGX_SUCCESS => Ok(hash),
            _ => Err(ret),
        }
    }

    ///
    /// close cleans up and deallocates the CMAC algorithm context state that was allocated in function init.
    ///
    /// # Description
    ///
    /// Calling close is the last step after performing a CMAC hash over multiple datasets.
    /// The caller uses this function to deallocate memory used for storing the CMAC algorithm context state.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The input handle is invalid.
    ///
    pub fn close(&self) -> SgxError {

        if self.initflag.get() == false {
            return Ok(());
        }

        let ret = {
            let handle = *self.handle.borrow();
            if handle.is_null() == true {
                sgx_status_t::SGX_SUCCESS
            } else {
                rsgx_cmac128_close(handle)
            }
        };

        match ret {
            sgx_status_t::SGX_SUCCESS => {
                self.initflag.set(false);
                *self.handle.borrow_mut() = ptr::null_mut();
                Ok(())
            },
            _ => Err(ret),
        }
    }
}

impl Default for SgxCmacHandle {
    fn default() -> Self {
        Self::new()
    }
}

impl Drop for SgxCmacHandle {
    ///
    /// drop cleans up and deallocates the CMAC algorithm context state that was allocated in function init.
    ///
    fn drop(&mut self) {
       let _ = self.close();
    }
}

pub const SGX_AESCTR_CTR_SIZE: size_t = 16;
pub type sgx_aes_ctr_128bit_ctr_t = [uint8_t; SGX_AESCTR_CTR_SIZE];

///
/// rsgx_aes_ctr_encrypt performs a Rijndael AES-CTR encryption operation.
///
/// Only a 128bit key size is supported by this Intel(R) SGX SDK cryptography library.
///
/// # Description
///
/// This function encrypts the input data stream of a variable length according to
/// the CTR mode as specified in [NIST SP 800-38A]. The counter can be thought
/// of as an IV which increments on successive encryption or decryption calls. For
/// a given dataset or data stream, the incremented counter block should be used
/// on successive calls of the encryption process for that given stream. However,
/// for new or different datasets/streams, the same counter should not be reused,
/// instead initialize the counter for the new data set.
///
/// It is recommended that the source, destination and counter data buffers are
/// allocated within the enclave.
///
/// # Parameters
///
/// **key**
///
/// A pointer to key to be used in the AES-CTR encryption operation. The size must be 128 bits.
///
/// **src**
///
/// A pointer to the input data stream to be encrypted.
///
/// **ctr**
///
/// A pointer to the initialization vector to be used in the AES-CTR calculation.
///
/// **ctr_inc_bits**
///
/// Specifies the number of bits in the counter to be incremented.
///
/// **dst**
///
/// A pointer to the output encrypted data buffer. This buffer should be allocated by the calling code.
///
/// # Requirements
///
/// Library: libsgx_tcrypto.a
///
/// # Errors
///
/// **SGX_ERROR_INVALID_PARAMETER**
///
/// The pointer is invalid.
///
/// **SGX_ERROR_OUT_OF_MEMORY**
///
/// Not enough memory is available to complete this operation.
///
/// **SGX_ERROR_UNEXPECTED**
///
/// An internal cryptography library failure occurred.
///
pub fn rsgx_aes_ctr_encrypt(key: &sgx_aes_ctr_128bit_key_t,
                            src: &[u8],
                            ctr: &sgx_aes_ctr_128bit_ctr_t,
                            ctr_inc_bits: u32,
                            dst: &mut [u8]) -> SgxError {

    let src_len = src.len();
    if src_len > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if src_len < 1 {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    let dst_len = dst.len();
    if dst_len > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if dst_len < src_len {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let ret = unsafe {
        sgx_aes_ctr_encrypt(key as * const sgx_aes_ctr_128bit_key_t,
                            src.as_ptr(),
                            src_len as u32,
                            ctr as * const sgx_aes_ctr_128bit_ctr_t as * const u8,
                            ctr_inc_bits,
                            dst.as_mut_ptr())
    };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(()),
        _ => Err(ret),
    }
}

///
/// rsgx_aes_ctr_decrypt performs a Rijndael AES-CTR decryption operation.
///
/// Only a 128bit key size is supported by this Intel(R) SGX SDK cryptography library.
///
/// # Description
///
/// This function decrypts the input data stream of a variable length according to
/// the CTR mode as specified in [NIST SP 800-38A]. The counter can be thought
/// of as an IV which increments on successive encryption or decryption calls. For
/// a given dataset or data stream, the incremented counter block should be used
/// on successive calls of the decryption process for that given stream. However,
/// for new or different datasets/streams, the same counter should not be reused,
/// instead initialize the counter for the new data set.
///
/// It is recommended that the source, destination and counter data buffers are
/// allocated within the enclave.
///
/// # Parameters
///
/// **key**
///
/// A pointer to key to be used in the AES-CTR encryption operation. The size must be 128 bits.
///
/// **src**
///
/// A pointer to the input data stream to be decrypted.
///
/// **ctr**
///
/// A pointer to the initialization vector to be used in the AES-CTR calculation.
///
/// **ctr_inc_bits**
///
/// Specifies the number of bits in the counter to be incremented.
///
/// **dst**
///
/// A pointer to the output decrypted data buffer. This buffer should be allocated by the calling code.
///
/// # Requirements
///
/// Library: libsgx_tcrypto.a
///
/// # Errors
///
/// **SGX_ERROR_INVALID_PARAMETER**
///
/// The pointer is invalid.
///
/// **SGX_ERROR_OUT_OF_MEMORY**
///
/// Not enough memory is available to complete this operation.
///
/// **SGX_ERROR_UNEXPECTED**
///
/// An internal cryptography library failure occurred.
///
pub fn rsgx_aes_ctr_decrypt(key: &sgx_aes_ctr_128bit_key_t,
                            src: &[u8],
                            ctr: &sgx_aes_ctr_128bit_ctr_t,
                            ctr_inc_bits: u32,
                            dst: &mut [u8]) -> SgxError {

    let src_len = src.len();
    if src_len > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if src_len < 1 {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    let dst_len = dst.len();
    if dst_len > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if dst_len < src_len {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let ret = unsafe {
        sgx_aes_ctr_decrypt(key as * const sgx_aes_ctr_128bit_key_t,
                            src.as_ptr(),
                            src.len() as u32,
                            ctr as * const sgx_aes_ctr_128bit_ctr_t as * const u8,
                            ctr_inc_bits,
                            dst.as_mut_ptr())
    };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(()),
        _ => Err(ret),
    }
}

fn rsgx_ecc256_open_context(ecc_handle: &mut sgx_ecc_state_handle_t) -> sgx_status_t {

    unsafe { sgx_ecc256_open_context(ecc_handle as * mut _ as * mut sgx_ecc_state_handle_t) }
}

fn rsgx_ecc256_close_context(ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {

    unsafe { sgx_ecc256_close_context(ecc_handle) }
}

fn rsgx_ecc256_create_key_pair(private: &mut sgx_ec256_private_t,
                               public: &mut sgx_ec256_public_t,
                               ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {
    unsafe {
        sgx_ecc256_create_key_pair(private as * mut sgx_ec256_private_t,
                                   public as * mut sgx_ec256_public_t,
                                   ecc_handle)
    }
}

fn rsgx_ecc256_check_point(point: &sgx_ec256_public_t, ecc_handle: sgx_ecc_state_handle_t, valid: &mut i32) -> sgx_status_t {

    unsafe { sgx_ecc256_check_point(point as * const sgx_ec256_public_t, ecc_handle, valid as * mut i32) }
}

fn rsgx_ecc256_compute_shared_dhkey(private_b: &sgx_ec256_private_t,
                                    public_ga: &sgx_ec256_public_t,
                                    shared_key: &mut sgx_ec256_dh_shared_t,
                                    ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {
    unsafe {
        sgx_ecc256_compute_shared_dhkey(private_b as * const _ as * mut sgx_ec256_private_t,
                                        public_ga as * const _ as * mut sgx_ec256_public_t,
                                        shared_key as * mut sgx_ec256_dh_shared_t,
                                        ecc_handle)
    }
}

/* delete (intel sgx sdk 2.0)
fn rsgx_ecc256_compute_shared_dhkey512(private_b: &sgx_ec256_private_t,
                                       public_ga: &sgx_ec256_public_t,
                                       shared_key: &mut sgx_ec256_dh_shared512_t,
                                       ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t {

    unsafe {
        sgx_ecc256_compute_shared_dhkey512(private_b as * const _ as * mut sgx_ec256_private_t,
                                           public_ga as * const _ as * mut sgx_ec256_public_t,
                                           shared_key as * mut sgx_ec256_dh_shared512_t,
                                           ecc_handle)
    }
}
*/

fn rsgx_ecdsa_sign_msg<T>(data: &T,
                          private: &sgx_ec256_private_t,
                          signature: &mut sgx_ec256_signature_t,
                          ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t
    where T: Copy + ContiguousMemory {

    let size = mem::size_of::<T>();
    if size == 0 {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if size > u32::max_value() as usize {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }

    unsafe {
        sgx_ecdsa_sign(data as * const _  as * const u8,
                       size as u32,
                       private as * const _ as * mut sgx_ec256_private_t,
                       signature as * mut sgx_ec256_signature_t,
                       ecc_handle)
    }
}

fn rsgx_ecdsa_sign_slice<T>(data: &[T],
                            private: &sgx_ec256_private_t,
                            signature: &mut sgx_ec256_signature_t,
                            ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t
    where T: Copy + ContiguousMemory {

    let size = mem::size_of_val(data);
    if size == 0 {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if size > u32::max_value() as usize {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }

    unsafe {
        sgx_ecdsa_sign(data.as_ptr() as * const _  as * const u8,
                       size as u32,
                       private as * const _ as * mut sgx_ec256_private_t,
                       signature as * mut sgx_ec256_signature_t,
                       ecc_handle)
    }
}

fn rsgx_ecdsa_verify_msg<T>(data: &T,
                            public: &sgx_ec256_public_t,
                            signature: &sgx_ec256_signature_t,
                            result: &mut sgx_generic_ecresult_t,
                            ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t
    where T: Copy + ContiguousMemory {

    let size = mem::size_of::<T>();
    if size == 0 {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if size > u32::max_value() as usize {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }

    unsafe {

        let mut verify: u8 = 0;
        let ret = sgx_ecdsa_verify(data as * const _ as * const u8,
                                   size as u32,
                                   public as * const sgx_ec256_public_t,
                                   signature as * const _ as * mut sgx_ec256_signature_t,
                                   &mut verify as * mut u8,
                                   ecc_handle);
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                let ecresult = sgx_generic_ecresult_t::from_repr(verify as u32);
                *result = ecresult.unwrap_or(sgx_generic_ecresult_t::SGX_EC_INVALID_SIGNATURE);
            },
            _ => { *result = sgx_generic_ecresult_t::SGX_EC_INVALID_SIGNATURE; },
        };
        ret
    }
}

fn rsgx_ecdsa_verify_slice<T>(data: &[T],
                              public: &sgx_ec256_public_t,
                              signature: &sgx_ec256_signature_t,
                              result: &mut sgx_generic_ecresult_t,
                              ecc_handle: sgx_ecc_state_handle_t) -> sgx_status_t
    where T: Copy + ContiguousMemory {

    let size = mem::size_of_val(data);
    if size == 0 {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if size > u32::max_value() as usize {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }

    unsafe {

        let mut verify: u8 = 0;
        let ret = sgx_ecdsa_verify(data.as_ptr() as * const _ as * const u8,
                                   size as u32,
                                   public as * const sgx_ec256_public_t,
                                   signature as * const _ as * mut sgx_ec256_signature_t,
                                   &mut verify as * mut u8,
                                   ecc_handle);
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                let ecresult = sgx_generic_ecresult_t::from_repr(verify as u32);
                *result = ecresult.unwrap_or(sgx_generic_ecresult_t::SGX_EC_INVALID_SIGNATURE);
            },
            _ => { *result = sgx_generic_ecresult_t::SGX_EC_INVALID_SIGNATURE; },
        };
        ret
    }
}

///
/// ECC GF(p) context state.
///
/// This is a handle to the ECC GF(p) context state allocated and initialized used to perform
/// elliptic curve cryptosystem standard functions. The algorithm stores the intermediate results
/// of calculations performed using this context.
///
pub struct SgxEccHandle{
    handle: RefCell<sgx_ecc_state_handle_t>,
    initflag: Cell<bool>,
}

impl SgxEccHandle {

    ///
    /// Constructs a new, empty SgxEccHandle.
    ///
    pub fn new() -> Self {
        SgxEccHandle{
            handle: RefCell::new(ptr::null_mut() as sgx_ecc_state_handle_t),
            initflag: Cell::new(false),
            }
    }

    ///
    /// open returns an allocated and initialized context for the elliptic curve cryptosystem
    /// over a prime finite field, GF(p).
    ///
    /// This context must be created prior to calling create_key_pair or compute_shared_dhkey.
    /// When the calling code has completed its set of ECC operations, close should be called to
    /// cleanup and deallocate the ECC context.
    ///
    /// # Description
    ///
    /// open is utilized to allocate and initialize a 256-bit
    /// GF(p) cryptographic system. The caller does not allocate memory for the ECC
    /// state that this function returns. The state is specific to the implementation of
    /// the cryptography library and thus the allocation is performed by the library
    /// itself. If the ECC cryptographic function using this cryptographic system is completed
    /// or any error occurs, close should be called to free the state allocated by this algorithm.
    ///
    /// Public key cryptography successfully allows to solving problems of information
    /// safety by enabling trusted communication over insecure channels. Although
    /// elliptic curves are well studied as a branch of mathematics, an interest to the
    /// cryptographic schemes based on elliptic curves is constantly rising due to the
    /// advantages that the elliptic curve algorithms provide in the wireless communications:
    /// shorter processing time and key length.
    ///
    /// Elliptic curve cryptosystems (ECCs) implement a different way of creating public
    /// keys. As elliptic curve calculation is based on the addition of the rational
    /// points in the (x,y) plane and it is difficult to solve a discrete logarithm from
    /// these points, a higher level of safety is achieved through the cryptographic
    /// schemes that use the elliptic curves. The cryptographic systems that encrypt
    /// messages by using the properties of elliptic curves are hard to attack due to
    /// the extreme complexity of deciphering the private key.
    ///
    /// Using of elliptic curves allows shorter public key length and encourages cryptographers
    /// to create cryptosystems with the same or higher encryption
    /// strength as the RSA or DSA cryptosystems. Because of the relatively short key
    /// length, ECCs do encryption and decryption faster on the hardware that
    /// requires less computation processing volumes.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_OUT_OF_MEMORY**
    ///
    /// Not enough memory is available to complete this operation.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// The ECC context state was not initialized properly due to an internal cryptography library failure.
    ///
    pub fn open(&self) -> SgxError {

        if self.initflag.get() == true {
            return Ok(());
        }

        let ret = rsgx_ecc256_open_context(self.handle.borrow_mut().deref_mut());
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                self.initflag.set(true);
                Ok(())
            },
            _ => Err(ret),
        }
    }

    ///
    /// create_key_pair generates a private/public key pair on the ECC curve for the given
    /// cryptographic system.
    ///
    /// open must be called to allocate and initialize the ECC context prior to making this call.
    ///
    /// # Description
    ///
    /// This function populates private/public key pair. The calling code allocates
    /// memory for the private and public key pointers to be populated. The function
    /// generates a private key p_private and computes a public key p_public of
    /// the elliptic cryptosystem over a finite field GF(p).
    ///
    /// The private key p_private is a number that lies in the range of [1, n-1]
    /// where n is the order of the elliptic curve base point.
    /// The public key p_public is an elliptic curve point such that p_public =
    /// p_private *G, where G is the base point of the elliptic curve.
    /// The context of the point p_public as an elliptic curve point must be created
    /// by using the function open.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Return value
    ///
    /// **sgx_ec256_private_t**
    ///
    /// The private key which is a number that lies in the range of [1, n-1] where n is the order
    /// of the elliptic curve base point.
    ///
    /// **sgx_ec256_public_t**
    ///
    /// The public key which is an elliptic curve point such that:
    ///
    /// public key = private key * G, where G is the base point of the elliptic curve.
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_INVALID_STATE**
    ///
    /// The ECC state is not initialized.
    ///
    /// **SGX_ERROR_OUT_OF_MEMORY**
    ///
    /// Not enough memory is available to complete this operation.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// The key creation process failed due to an internal cryptography library failure.
    ///
    pub fn create_key_pair(&self) -> SgxResult<(sgx_ec256_private_t, sgx_ec256_public_t)> {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let mut private = sgx_ec256_private_t::default();
        let mut public = sgx_ec256_public_t::default();
        let ret = rsgx_ecc256_create_key_pair(&mut private, &mut public, *self.handle.borrow());

        match ret {
            sgx_status_t::SGX_SUCCESS => Ok((private, public)),
            _ => Err(ret),
        }
    }

    ///
    /// check_point checks whether the input point is a valid point on the ECC curve for the given cryptographic system.
    ///
    /// open context must be called to allocate and initialize the ECC context prior to making this call.
    ///
    /// # Description
    ///
    /// check_point validates whether the input point is a valid point on the ECC curve for the given cryptographic system.
    ///
    /// # Parameters
    ///
    /// **point**
    ///
    /// A pointer to the point to perform validity check on.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Return value
    ///
    /// **true**
    ///
    /// The input point is valid
    ///
    /// **false**
    ///
    /// The input point is not valid
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_INVALID_STATE**
    ///
    /// The ECC state is not initialized.
    ///
    /// **SGX_ERROR_OUT_OF_MEMORY**
    ///
    /// Not enough memory is available to complete this operation.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// An internal cryptography library failure occurred.
    ///
    pub fn check_point(&self, point: &sgx_ec256_public_t) -> SgxResult<bool> {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let mut valid: i32 = 0;
        let ret = rsgx_ecc256_check_point(point, *self.handle.borrow(), &mut valid);
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                if valid > 0 {
                    Ok(true)
                } else if valid == 0 {
                    Ok(false)
                } else {
                    Ok(false)
                }
            },
            _ => Err(ret),
        }
    }

    ///
    /// compute_shared_dhkey generates a secret key shared between two participants of the cryptosystem.
    ///
    /// # Description
    ///
    /// This function computes the Diffie-Hellman shared key based on the enclave’s
    /// own (local) private key and remote enclave’s public Ga Key.
    ///
    /// The function computes a secret number sharedKey, which is a secret key
    /// shared between two participants of the cryptosystem.
    ///
    /// In cryptography, metasyntactic names such as Alice as Bob are normally used
    /// as examples and in discussions and stand for participant A and participant B.
    ///
    /// Both participants (Alice and Bob) use the cryptosystem for receiving a common
    /// secret point on the elliptic curve called a secret key (sharedKey). To
    /// receive a secret key, participants apply the Diffie-Hellman key-agreement
    /// scheme involving public key exchange. The value of the secret key entirely
    /// depends on participants.
    ///
    /// According to the scheme, Alice and Bob perform the following operations:
    ///
    /// 1. Alice calculates her own public key pubKeyA by using her private key
    /// privKeyA: pubKeyA = privKeyA * G, where G is the base point of the
    /// elliptic curve.
    ///
    /// 2. Alice passes the public key to Bob.
    ///
    /// 3. Bob calculates his own public key pubKeyB by using his private key
    /// privKeyB: pubKeyB = privKeyB * G, where G is a base point of the elliptic curve.
    ///
    /// 4. Bob passes the public key to Alice.
    ///
    /// 5. Alice gets Bob's public key and calculates the secret point shareKeyA. When
    /// calculating, she uses her own private key and Bob's public key and applies the
    /// following formula:
    ///
    /// shareKeyA = privKeyA * pubKeyB = privKeyA * privKeyB * G.
    ///
    /// 6. Bob gets Alice's public key and calculates the secret point shareKeyB. When
    /// calculating, he uses his own private key and Alice's public key and applies the
    /// following formula:
    ///
    /// shareKeyB = privKeyB * pubKeyA = privKeyB * privKeyA * G.
    ///
    /// As the following equation is true privKeyA * privKeyB * G =
    /// privKeyB * privKeyA * G, the result of both calculations is the same,
    /// that is, the equation shareKeyA = shareKeyB is true. The secret point serves as
    /// a secret key.
    ///
    /// Shared secret shareKey is an x-coordinate of the secret point on the elliptic
    /// curve. The elliptic curve domain parameters must be hitherto defined by the
    /// function: open.
    ///
    /// # Parameters
    ///
    /// **private_b**
    ///
    /// A pointer to the local private key.
    ///
    /// **public_ga**
    ///
    /// A pointer to the remote public key.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Return value
    ///
    /// The secret key generated by this function which is a common point on the elliptic curve.
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_INVALID_STATE**
    ///
    /// The ECC state is not initialized.
    ///
    /// **SGX_ERROR_OUT_OF_MEMORY**
    ///
    /// Not enough memory is available to complete this operation.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// The key creation process failed due to an internal cryptography library failure.
    ///
    pub fn compute_shared_dhkey(&self, private_b: &sgx_ec256_private_t, public_ga: &sgx_ec256_public_t) -> SgxResult<sgx_ec256_dh_shared_t> {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let mut shared_key = sgx_ec256_dh_shared_t::default();
        let ret = rsgx_ecc256_compute_shared_dhkey(private_b, public_ga, &mut shared_key, *self.handle.borrow());
        match ret {
            sgx_status_t::SGX_SUCCESS => Ok(shared_key),
            _ => Err(ret),
        }
    }

    /* delete (intel sgx sdk 2.0)
    pub fn compute_shared_dhkey512(&self, private_b: &sgx_ec256_private_t, public_ga: &sgx_ec256_public_t) -> SgxResult<sgx_ec256_dh_shared512_t> {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let mut shared_key = sgx_ec256_dh_shared512_t::default();
        let ret = rsgx_ecc256_compute_shared_dhkey512(private_b, public_ga, &mut shared_key, *self.handle.borrow());
        match ret {
            sgx_status_t::SGX_SUCCESS => Ok(shared_key),
            _ => Err(ret),
        }
    }
    */

    ///
    /// ecdsa_sign_msg computes a digital signature with a given private key over an input dataset.
    ///
    /// # Description
    ///
    /// This function computes a digital signature over the input dataset based on the
    /// put private key.
    ///
    /// A message digest is a fixed size number derived from the original message
    // with an applied hash function over the binary code of the message. (SHA256
    /// in this case)
    ///
    /// The signer's private key and the message digest are used to create a signature.
    ///
    /// A digital signature over a message consists of a pair of large numbers, 256-bits
    /// each, which the given function computes.
    ///
    /// The scheme used for computing a digital signature is of the ECDSA scheme, an
    /// elliptic curve of the DSA scheme.
    ///
    /// The keys can be generated and set up by the function: create_key_pair.
    ///
    /// The elliptic curve domain parameters must be created by function: open.
    ///
    /// # Parameters
    ///
    /// **data**
    ///
    /// A pointer to the data to calculate the signature over.
    ///
    /// **private**
    ///
    /// A pointer to the private key to be used in the calculation of the signature.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Return value
    ///
    /// The signature generated by this function.
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_INVALID_STATE**
    ///
    /// The ECC state is not initialized.
    ///
    /// **SGX_ERROR_OUT_OF_MEMORY**
    ///
    /// Not enough memory is available to complete this operation.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// The signature generation process failed due to an internal cryptography library failure.
    ///
    pub fn ecdsa_sign_msg<T>(&self, data: &T, private: &sgx_ec256_private_t) -> SgxResult<sgx_ec256_signature_t>
        where T: Copy + ContiguousMemory {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let mut signature = sgx_ec256_signature_t::default();
        let ret = rsgx_ecdsa_sign_msg(data, private, &mut signature, *self.handle.borrow());
        match ret {
            sgx_status_t::SGX_SUCCESS => Ok(signature),
            _ => Err(ret),
        }
    }

    ///
    /// ecdsa_sign_slice computes a digital signature with a given private key over an input dataset.
    ///
    pub fn ecdsa_sign_slice<T>(&self, data: &[T], private: &sgx_ec256_private_t) -> SgxResult<sgx_ec256_signature_t>
        where T: Copy + ContiguousMemory {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let mut signature = sgx_ec256_signature_t::default();
        let ret = rsgx_ecdsa_sign_slice(data, private, &mut signature, *self.handle.borrow());
        match ret {
            sgx_status_t::SGX_SUCCESS => Ok(signature),
            _ => Err(ret),
        }
    }

    ///
    /// ecdsa_verify_msg verifies the input digital signature with a given public key over an input dataset.
    ///
    /// # Description
    ///
    /// This function verifies the signature for the given data set based on the input public key.
    ///
    /// A digital signature over a message consists of a pair of large numbers, 256-bits
    /// each, which could be created by function: sgx_ecdsa_sign. The scheme
    /// used for computing a digital signature is of the ECDSA scheme, an elliptic
    /// curve of the DSA scheme.
    ///
    /// The elliptic curve domain parameters must be created by function: open.
    ///
    /// # Parameters
    ///
    /// **data**
    ///
    /// A pointer to the signed dataset to verify.
    ///
    /// **public**
    ///
    /// A pointer to the public key to be used in the calculation of the signature.
    ///
    /// **signature**
    ///
    /// A pointer to the signature to be verified.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Return value
    ///
    /// **true**
    ///
    /// Digital signature is valid.
    ///
    /// **false**
    ///
    /// Digital signature is not valid.
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The pointer is invalid.
    ///
    /// **SGX_ERROR_INVALID_STATE**
    ///
    /// The ECC state is not initialized.
    ///
    /// **SGX_ERROR_OUT_OF_MEMORY**
    ///
    /// Not enough memory is available to complete this operation.
    ///
    /// **SGX_ERROR_UNEXPECTED**
    ///
    /// The verification process failed due to an internal cryptography library failure.
    ///
    pub fn ecdsa_verify_msg<T>(&self,
                               data: &T,
                               public: &sgx_ec256_public_t,
                               signature: &sgx_ec256_signature_t) -> SgxResult<bool>
        where T: Copy + ContiguousMemory {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let mut result = sgx_generic_ecresult_t::default();
        let ret = rsgx_ecdsa_verify_msg(data, public, signature, &mut result, *self.handle.borrow());
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                match result {
                    sgx_generic_ecresult_t::SGX_EC_VALID => Ok(true),
                    _ => Ok(false),
                }
            },
            _ => Err(ret),
        }
    }

    ///
    /// ecdsa_verify_slice verifies the input digital signature with a given public key over an input dataset.
    ///
    pub fn ecdsa_verify_slice<T>(&self,
                                 data: &[T],
                                 public: &sgx_ec256_public_t,
                                 signature: &sgx_ec256_signature_t) -> SgxResult<bool>
        where T: Copy + ContiguousMemory {

        if self.initflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let mut result = sgx_generic_ecresult_t::default();
        let ret = rsgx_ecdsa_verify_slice(data, public, signature, &mut result, *self.handle.borrow());
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                match result {
                    sgx_generic_ecresult_t::SGX_EC_VALID => Ok(true),
                    _ => Ok(false),
                }
            },
            _ => Err(ret),
        }
    }

    ///
    /// close cleans up and deallocates the ECC 256 GF(p) state that was allocated in function open.
    ///
    /// # Description
    ///
    /// close is used by calling code to deallocate memory used for storing the ECC 256 GF(p) state used
    /// in ECC cryptographic calculations.
    ///
    /// # Requirements
    ///
    /// Library: libsgx_tcrypto.a
    ///
    /// # Errors
    ///
    /// **SGX_ERROR_INVALID_PARAMETER**
    ///
    /// The input handle is invalid.
    ///
    pub fn close(&self) -> SgxError {

        if self.initflag.get() == false {
            return Ok(());
        }

        let ret = {
            let handle = *self.handle.borrow();
            if handle.is_null() == true {
                sgx_status_t::SGX_SUCCESS
            } else {
                rsgx_ecc256_close_context(handle)
            }
        };

        match ret {
            sgx_status_t::SGX_SUCCESS => {
                self.initflag.set(false);
                *self.handle.borrow_mut() = ptr::null_mut();
                Ok(())
            },
            _ => Err(ret),
        }
    }
}

impl Default for SgxEccHandle {
    fn default() -> Self {
        Self::new()
    }
}

impl Drop for SgxEccHandle {
    ///
    /// close cleans up and deallocates the ECC 256 GF(p) state that was allocated in function open.
    ///
    fn drop(&mut self) {
        let _ = self.close();
    }
}

///
/// The rsgx_rsa3072_sign_msg computes a digital signature for a given dataset based on RSA 3072 private key.
///
/// # Description
///
/// This function computes a digital signature over the input dataset based on the RSA 3072 private key.
///
/// A message digest is a fixed size number derived from the original message with an applied hash function
/// over the binary code of the message. (SHA256 in this case)
///
/// The signer's private key and the message digest are used to create a signature.
///
/// The scheme used for computing a digital signature is of the RSASSA-PKCS1-v1_5 scheme.
///
/// # Parameters
///
/// **data**
///
/// A pointer to the data to calculate the signature over.
///
/// **key**
///
/// A pointer to the RSA key.
///
/// # Requirements
///
/// Library: libsgx_tcrypto.a
///
/// # Return value
///
/// The signature generated by this function.
///
/// # Errors
///
/// **SGX_ERROR_INVALID_PARAMETER**
///
/// The RSA key, data is NULL. Or the data size is 0.
///
/// **SGX_ERROR_OUT_OF_MEMORY**
///
/// Not enough memory is available to complete this operation.
///
/// **SGX_ERROR_UNEXPECTED**
///
/// The signature generation process failed due to an internal cryptography library failure.
///
pub fn rsgx_rsa3072_sign_msg<T>(data: &T, key: &sgx_rsa3072_key_t) -> SgxResult<sgx_rsa3072_signature_t>
    where T: Copy + ContiguousMemory {

    let size = mem::size_of::<T>();
    if size == 0 {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if size > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let mut sign = sgx_rsa3072_signature_t::default();
    let ret = unsafe {
        sgx_rsa3072_sign(data as * const _ as * const u8,
                         size as u32,
                         key as * const sgx_rsa3072_key_t,
                         &mut sign as * mut sgx_rsa3072_signature_t)
    };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(sign),
        _ => Err(ret),
    }
}

///
/// The rsgx_rsa3072_sign_slice computes a digital signature for a given dataset based on RSA 3072 private key.
///
pub fn rsgx_rsa3072_sign_slice<T>(data: &[T], key: &sgx_rsa3072_key_t) -> SgxResult<sgx_rsa3072_signature_t>
    where T: Copy + ContiguousMemory {

    let size = mem::size_of_val(data);
    if size == 0 {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if size > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let mut sign = sgx_rsa3072_signature_t::default();
    let ret = unsafe {
        sgx_rsa3072_sign(data.as_ptr() as * const _ as * const u8,
                         size as u32,
                         key as * const sgx_rsa3072_key_t,
                         &mut sign as * mut sgx_rsa3072_signature_t)
    };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(sign),
        _ => Err(ret),
    }
}

///
/// rsgx_rsa3072_verify_msg verifies the input digital signature for the given data- set based on the RSA 3072 public key.
///
/// # Description
///
/// This function verifies the signature for the given data set based on the input RSA 3072 public key.
///
/// A digital signature over a message is a buffer of 384-bytes, which could be created by function: rsgx_rsa3072_sign.
/// The scheme used for computing a digital signature is of the RSASSA-PKCS1-v1_5 scheme.
///
/// # Parameters
///
/// **data**
///
/// A pointer to the signed dataset to be verified.
///
/// **public**
///
/// A pointer to the public key to be used in the calculation of the signature.
///
/// **signature**
///
/// A pointer to the signature to be verified.
///
/// # Requirements
///
/// Library: libsgx_tcrypto.a
///
/// # Return value
///
/// **true**
///
/// Digital signature is valid.
///
/// **false**
///
/// Digital signature is not valid.
///
/// # Errors
///
/// **SGX_ERROR_INVALID_PARAMETER**
///
/// The private key, data is NULL. Or the data size is 0.
///
/// **SGX_ERROR_OUT_OF_MEMORY**
///
/// Not enough memory is available to complete this operation.
///
/// **SGX_ERROR_UNEXPECTED**
///
/// The verification process failed due to an internal cryptography library failure.
///
pub fn rsgx_rsa3072_verify_msg<T>(data: &T,
                                  public: &sgx_rsa3072_public_key_t,
                                  signature: &sgx_rsa3072_signature_t) -> SgxResult<bool>
    where T: Copy + ContiguousMemory {

    let size = mem::size_of::<T>();
    if size == 0 {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if size > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    unsafe {

        let mut verify = sgx_rsa_result_t::SGX_RSA_INVALID_SIGNATURE;
        let ret = sgx_rsa3072_verify(data as * const _ as * const u8,
                                     size as u32,
                                     public as * const sgx_rsa3072_public_key_t,
                                     signature as * const sgx_rsa3072_signature_t,
                                     &mut verify as * mut sgx_rsa_result_t);
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                match verify {
                    sgx_rsa_result_t::SGX_RSA_VALID => Ok(true),
                    _ => Ok(false),
                }
            },
            _ => Err(ret),
        }
    }
}

///
/// rsgx_rsa3072_verify_slice verifies the input digital signature for the given data- set based on the RSA 3072 public key.
///
pub fn rsgx_rsa3072_verify_slice<T>(data: &[T],
                                    public: &sgx_rsa3072_public_key_t,
                                    signature: &sgx_rsa3072_signature_t) -> SgxResult<bool>
    where T: Copy + ContiguousMemory {

    let size = mem::size_of_val(data);
    if size == 0 {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if size > u32::max_value() as usize {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    unsafe {

        let mut verify = sgx_rsa_result_t::SGX_RSA_INVALID_SIGNATURE;
        let ret = sgx_rsa3072_verify(data.as_ptr() as * const _ as * const u8,
                                     size as u32,
                                     public as * const sgx_rsa3072_public_key_t,
                                     signature as * const sgx_rsa3072_signature_t,
                                     &mut verify as * mut sgx_rsa_result_t);
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                match verify {
                    sgx_rsa_result_t::SGX_RSA_VALID => Ok(true),
                    _ => Ok(false),
                }
            },
            _ => Err(ret),
        }
    }
}

pub fn rsgx_create_rsa_key_pair(n_byte_size: i32,
                                e_byte_size: i32,
                                n: &mut [u8],
                                d: &mut [u8],
                                e: &mut [u8],
                                p: &mut [u8],
                                q: &mut [u8],
                                dmp1: &mut [u8],
                                dmq1: &mut [u8],
                                iqmp: &mut [u8]) -> SgxError {

    if (n_byte_size <= 0) || (e_byte_size <= 0) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (n.len() == 0) || (n.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (d.len() == 0) || (d.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (e.len() == 0) || (e.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (p.len() == 0) || (p.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (q.len() == 0) || (q.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (dmp1.len() == 0) || (dmp1.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (dmq1.len() == 0) || (dmq1.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (iqmp.len() == 0) || (iqmp.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let ret = unsafe {
        sgx_create_rsa_key_pair(n_byte_size,
                                e_byte_size,
                                n.as_mut_ptr(),
                                d.as_mut_ptr(),
                                e.as_mut_ptr(),
                                p.as_mut_ptr(),
                                q.as_mut_ptr(),
                                dmp1.as_mut_ptr(),
                                dmq1.as_mut_ptr(),
                                iqmp.as_mut_ptr())
    };
    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(()),
        _ => Err(ret),
    }
}

fn rsgx_create_rsa_priv_key(mod_size: i32,
                            exp_size: i32,
                            e: &[u8],
                            p: &[u8],
                            q: &[u8],
                            dmp1: &[u8],
                            dmq1: &[u8],
                            iqmp: &[u8],
                            new_pri_key: &mut sgx_rsa_key_t) -> sgx_status_t {

    if (mod_size <= 0) || (exp_size <= 0) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (e.len() == 0) || (e.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (p.len() == 0) || (p.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (q.len() == 0) || (q.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (dmp1.len() == 0) || (dmp1.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (dmq1.len() == 0) || (dmq1.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (iqmp.len() == 0) || (iqmp.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }

    unsafe {
        sgx_create_rsa_priv2_key(mod_size,
                                 exp_size,
                                 e.as_ptr(),
                                 p.as_ptr(),
                                 q.as_ptr(),
                                 dmp1.as_ptr(),
                                 dmq1.as_ptr(),
                                 iqmp.as_ptr(),
                                 new_pri_key as * mut sgx_rsa_key_t)
    }
}

fn rsgx_create_rsa_pub_key(mod_size: i32,
                           exp_size: i32,
                           n: &[u8],
                           e: &[u8],
                           new_pub_key: &mut sgx_rsa_key_t) -> sgx_status_t {

    if (mod_size <= 0) || (exp_size <= 0) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (n.len() == 0) || (n.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (e.len() == 0) || (e.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }

    unsafe {
        sgx_create_rsa_pub1_key(mod_size,
                                exp_size,
                                n.as_ptr(),
                                e.as_ptr(),
                                new_pub_key as * mut sgx_rsa_key_t)
    }
}

fn rsgx_free_rsa_key(rsa_key: sgx_rsa_key_t,
                     key_type: sgx_rsa_key_type_t,
                     mod_size: i32,
                     exp_size: i32) -> sgx_status_t {

    if (mod_size <= 0) || (exp_size <= 0) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }

    unsafe {
        sgx_free_rsa_key(rsa_key, key_type, mod_size, exp_size)
    }
}

fn rsgx_rsa_priv_decrypt_sha256(rsa_key: sgx_rsa_key_t,
                                out_data: &mut [u8],
                                out_len: &mut usize,
                                in_data: &[u8]) -> sgx_status_t {

    if in_data.len() == 0 {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if * out_len != 0 && out_data.len() != * out_len {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }

    unsafe {
         let mut p_out_data: * mut u8 = ptr::null_mut();
        if * out_len != 0 {
            p_out_data = out_data.as_mut_ptr();
        }
        sgx_rsa_priv_decrypt_sha256(rsa_key,
                                    p_out_data,
                                    out_len as * mut usize,
                                    in_data.as_ptr(),
                                    in_data.len())
    }
}

fn rsgx_rsa_pub_encrypt_sha256(rsa_key: sgx_rsa_key_t,
                               out_data: &mut [u8],
                               out_len: &mut usize,
                               in_data: &[u8]) -> sgx_status_t {

    if in_data.len() == 0 {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if * out_len != 0 && out_data.len() != * out_len {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    
    unsafe {
        let mut p_out_data: * mut u8 = ptr::null_mut();
        if * out_len != 0 {
            p_out_data = out_data.as_mut_ptr();
        }
        sgx_rsa_pub_encrypt_sha256(rsa_key,
                                   p_out_data,
                                   out_len as * mut usize,
                                   in_data.as_ptr(),
                                   in_data.len())
    }
}

pub struct SgxRsaPrivKey {
    key: RefCell<sgx_rsa_key_t>,
    mod_size: Cell<i32>,
    exp_size: Cell<i32>,
    createflag: Cell<bool>,
}

impl SgxRsaPrivKey {

    pub fn new() -> Self {
        SgxRsaPrivKey {
            key: RefCell::new(ptr::null_mut() as sgx_rsa_key_t),
            mod_size: Cell::new(0),
            exp_size: Cell::new(0),
            createflag: Cell::new(false),
        }
    }

    pub fn create(&self, 
                  mod_size: i32,
                  exp_size: i32,
                  e: &[u8],
                  p: &[u8],
                  q: &[u8],
                  dmp1: &[u8],
                  dmq1: &[u8],
                  iqmp: &[u8]) -> SgxError {

        
        if self.createflag.get() == true {
            return Ok(());
        }

        let ret = rsgx_create_rsa_priv_key(mod_size,
                                           exp_size,
                                           e,
                                           p,
                                           q,
                                           dmp1,
                                           dmq1,
                                           iqmp,
                                           self.key.borrow_mut().deref_mut());
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                self.mod_size.set(mod_size);
                self.exp_size.set(exp_size);
                self.createflag.set(true);
                Ok(())
            },
            _ => Err(ret),
        }
    }

    pub fn decrypt_sha256(&self,
                          out_data: &mut [u8],
                          out_len: &mut usize,
                          in_data: &[u8]) -> SgxError {

        if self.createflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let ret = rsgx_rsa_priv_decrypt_sha256(*self.key.borrow(),
                                               out_data,
                                               out_len,
                                               in_data);
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                Ok(())
            },
            _ => Err(ret),
        }
    }

    pub fn free(&self) -> SgxError {

        if self.createflag.get() == false {
            return Ok(());
        }

        let ret = {
            let key = *self.key.borrow();
            if key.is_null() == true {
                sgx_status_t::SGX_SUCCESS
            } else {
                rsgx_free_rsa_key(key, 
                                  sgx_rsa_key_type_t::SGX_RSA_PRIVATE_KEY, 
                                  self.mod_size.get(),
                                  self.exp_size.get())
            }
        };

        match ret {
            sgx_status_t::SGX_SUCCESS => {
                self.createflag.set(false);
                *self.key.borrow_mut() = ptr::null_mut();
                Ok(())
            },
            _ => Err(ret),
        }
    }
}

impl Default for SgxRsaPrivKey {
    fn default() -> Self {
        Self::new()
    }
}

impl Drop for SgxRsaPrivKey {
    fn drop(&mut self) {
        let _ = self.free();
    }
}

pub struct SgxRsaPubKey {
    key: RefCell<sgx_rsa_key_t>,
    mod_size: Cell<i32>,
    exp_size: Cell<i32>,
    createflag: Cell<bool>,
}

impl SgxRsaPubKey {

    pub fn new() -> Self {
        SgxRsaPubKey {
            key: RefCell::new(ptr::null_mut() as sgx_rsa_key_t),
            mod_size: Cell::new(0),
            exp_size: Cell::new(0),
            createflag: Cell::new(false),
        }
    }

    pub fn create(&self, 
                  mod_size: i32,
                  exp_size: i32,
                  n: &[u8],
                  e: &[u8]) -> SgxError {
        
        if self.createflag.get() == true {
            return Ok(());
        }

        let ret = rsgx_create_rsa_pub_key(mod_size,
                                          exp_size,
                                          n,
                                          e,
                                          self.key.borrow_mut().deref_mut());
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                self.mod_size.set(mod_size);
                self.exp_size.set(exp_size);
                self.createflag.set(true);
                Ok(())
            },
            _ => Err(ret),
        }
    }

    pub fn encrypt_sha256(&self,
                          out_data: &mut [u8],
                          out_len: &mut usize, 
                          in_data: &[u8]) -> SgxError {

        if self.createflag.get() == false {
            return Err(sgx_status_t::SGX_ERROR_INVALID_STATE);
        }

        let ret = rsgx_rsa_pub_encrypt_sha256(*self.key.borrow(),
                                              out_data,
                                              out_len,
                                              in_data);
        match ret {
            sgx_status_t::SGX_SUCCESS => {
                Ok(())
            },
            _ => Err(ret),
        }
    }

    pub fn free(&self) -> SgxError {

        if self.createflag.get() == false {
            return Ok(());
        }

        let ret = {
            let key = *self.key.borrow();
            if key.is_null() == true {
                sgx_status_t::SGX_SUCCESS
            } else {
                rsgx_free_rsa_key(key, 
                                  sgx_rsa_key_type_t::SGX_RSA_PUBLIC_KEY, 
                                  self.mod_size.get(),
                                  self.exp_size.get())
            }
        };

        match ret {
            sgx_status_t::SGX_SUCCESS => {
                self.createflag.set(false);
                *self.key.borrow_mut() = ptr::null_mut();
                Ok(())
            },
            _ => Err(ret),
        }
    }
}

impl Default for SgxRsaPubKey {
    fn default() -> Self {
        Self::new()
    }
}

impl Drop for SgxRsaPubKey {
    fn drop(&mut self) {
        let _ = self.free();
    }
}

pub fn rsgx_calculate_ecdsa_priv_key(hash_drg: &[u8],
                                    sgx_nistp256_r_m1: &[u8],
                                    out_key: &mut [u8]) -> SgxError {

    if (hash_drg.len() == 0) || (hash_drg.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (sgx_nistp256_r_m1.len() == 0) || (sgx_nistp256_r_m1.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (out_key.len() == 0) || (out_key.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }

    let ret = unsafe {
        sgx_calculate_ecdsa_priv_key(hash_drg.as_ptr(),
                                     hash_drg.len() as i32,
                                     sgx_nistp256_r_m1.as_ptr(),
                                     sgx_nistp256_r_m1.len() as i32,
                                     out_key.as_mut_ptr(),
                                     out_key.len() as i32)
    };

    match ret {
        sgx_status_t::SGX_SUCCESS => Ok(()),
        _ => Err(ret),
    }
}
