// 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() {
            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() {
            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() {
            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() {
            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() {
            return Ok(());
        }

        let ret = {
            let handle = *self.handle.borrow();
            if handle.is_null() {
                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 p_aad = if aad_len != 0 { aad.as_ptr() } else { ptr::null() };

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

        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 = if !aad.is_empty() { aad.as_ptr() } else { ptr::null() };

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

        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() {
            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() {
            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() {
            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() {
            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() {
            return Ok(());
        }

        let ret = {
            let handle = *self.handle.borrow();
            if handle.is_null() {
                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(u32::from(verify));
                *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(u32::from(verify));
                *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() {
            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() {
            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() {
            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 {
                    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() {
            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() {
            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() {
            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() {
            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() {
            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() {
            return Ok(());
        }

        let ret = {
            let handle = *self.handle.borrow();
            if handle.is_null() {
                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),
        }
    }
}

#[allow(clippy::many_single_char_names)]
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.is_empty()) || (n.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (d.is_empty()) || (d.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (e.is_empty()) || (e.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (p.is_empty()) || (p.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (q.is_empty()) || (q.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (dmp1.is_empty()) || (dmp1.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (dmq1.is_empty()) || (dmq1.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (iqmp.is_empty()) || (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.is_empty()) || (e.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (p.is_empty()) || (p.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (q.is_empty()) || (q.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (dmp1.is_empty()) || (dmp1.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (dmq1.is_empty()) || (dmq1.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (iqmp.is_empty()) || (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.is_empty()) || (n.len() > i32::max_value() as usize) {
        return sgx_status_t::SGX_ERROR_INVALID_PARAMETER;
    }
    if (e.is_empty()) || (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.is_empty() {
        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 p_out_data: * mut u8 = if *out_len != 0 {
            out_data.as_mut_ptr()
        } else {
            ptr::null_mut()
        };

        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.is_empty() {
        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 p_out_data: * mut u8 = if *out_len != 0 {
            out_data.as_mut_ptr()
        } else {
            ptr::null_mut()
        };

        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() {
            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() {
            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() {
            return Ok(());
        }

        let ret = {
            let key = *self.key.borrow();
            if key.is_null() {
                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() {
            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() {
            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() {
            return Ok(());
        }

        let ret = {
            let key = *self.key.borrow();
            if key.is_null() {
                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();
    }
}

///
/// rsgx_calculate_ecdsa_priv_key generates an ECDSA private key based on an input random seed.
///
/// # Description
///
/// This function generates an ECDSA private key based on an input random seed.
///
/// # Parameters
///
/// **hash_drg**
///
/// Pointer to the input random seed.
///
/// **sgx_nistp256_r_m1**
///
/// Pointer to the buffer for n-1 where n is order of the ECC group used.
///
/// **out_key**
///
/// Pointer to the generated ECDSA private key.
///
/// # Requirements
///
/// Library: libsgx_tcrypto.a
///
/// # Errors
///
/// **SGX_ERROR_INVALID_PARAMETER**
///
/// Some of the pointers are NULL, or the input size is 0.
///
/// **SGX_ERROR_UNEXPECTED**
///
/// Unexpected error occurred during the ECDSA private key generation.
///
pub fn rsgx_calculate_ecdsa_priv_key(hash_drg: &[u8],
                                     sgx_nistp256_r_m1: &[u8],
                                     out_key: &mut [u8]) -> SgxError {

    if (hash_drg.is_empty()) || (hash_drg.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (sgx_nistp256_r_m1.is_empty()) || (sgx_nistp256_r_m1.len() > i32::max_value() as usize) {
        return Err(sgx_status_t::SGX_ERROR_INVALID_PARAMETER);
    }
    if (out_key.is_empty()) || (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),
    }
}

pub fn rsgx_ecc256_calculate_pub_from_priv(priv_key: &sgx_ec256_private_t,
                                           pub_key: &mut sgx_ec256_public_t) -> SgxError {

    let ret = unsafe {
        sgx_ecc256_calculate_pub_from_priv(priv_key as * const sgx_ec256_private_t,
                                           pub_key as * mut sgx_ec256_public_t)
    };

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