Browse Source

Merge pull request #250 from llly/tlibcrypto_update

Update tlibcrypto to add new crypto wrapper function
Andy Zhao 6 years ago
parent
commit
e9a7c096a8

+ 13 - 1
common/inc/internal/ipp_wrapper.h

@@ -34,6 +34,17 @@
 
 #include "ippcp.h"
 
+#ifndef CLEAR_FREE_MEM
+#define CLEAR_FREE_MEM(address, size) {            \
+	if (address != NULL) {                          \
+		if (size > 0) {                             \
+			(void)memset_s(address, size, 0, size); \
+		}                                           \
+		free(address);                              \
+	}				                                \
+}
+#endif
+
 #ifndef SAFE_FREE_MM
 #define SAFE_FREE_MM(ptr) {\
     if(ptr != NULL)     \
@@ -55,7 +66,8 @@ extern "C" {
 #endif
 
 IppStatus newBN(const Ipp32u *data, int size_in_bytes, IppsBigNumState **p_new_BN);
-
+IppStatus newPrimeGen(int nMaxBits, IppsPrimeState ** pPrimeG);
+IppStatus newPRNG(IppsPRNGState **pRandGen);
 IppStatus create_rsa_priv1_key(int n_byte_size, int d_byte_size, const Ipp32u *n, const Ipp32u *d, IppsRSAPrivateKeyState **new_pri_key1);
 
 IppStatus create_rsa_priv2_key(int p_byte_size, const Ipp32u *p, const Ipp32u *q,

+ 46 - 0
common/inc/internal/ssl_wrapper.h

@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2011-2018 Intel Corporation. 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 Intel Corporation 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.
+ *
+ */
+#ifndef _SSL_WRAPPER_H
+#define _SSL_WRAPPER_H
+
+
+#ifndef BN_CHECK_BREAK
+#define BN_CHECK_BREAK(x)  if((x == NULL) || (BN_is_zero(x))){break;}
+#endif
+
+#ifndef NULL_BREAK
+#define NULL_BREAK(x)   if(!x){break;}
+#endif
+
+
+#endif
+
+

+ 155 - 0
common/inc/sgx_tcrypto.h

@@ -42,6 +42,7 @@
 
 #include "sgx.h"
 #include "sgx_defs.h"
+#include "stdlib.h"
 
 #define SGX_SHA256_HASH_SIZE            32
 #define SGX_ECP256_KEY_SIZE             32
@@ -138,6 +139,41 @@ typedef enum {
 	SGX_RSA_INVALID_SIGNATURE    /* invalid signature */
 } sgx_rsa_result_t;
 
+typedef enum {
+    SGX_RSA_PRIVATE_KEY,               /* RSA private key state     */
+
+    SGX_RSA_PUBLIC_KEY    /* RSA public key state */
+} sgx_rsa_key_type_t;
+
+#define N_SIZE_IN_BYTES    384
+#define E_SIZE_IN_BYTES    4
+#define D_SIZE_IN_BYTES    384
+#define P_SIZE_IN_BYTES    192
+#define Q_SIZE_IN_BYTES    192
+#define DMP1_SIZE_IN_BYTES 192
+#define DMQ1_SIZE_IN_BYTES 192
+#define IQMP_SIZE_IN_BYTES 192
+
+#define N_SIZE_IN_UINT     N_SIZE_IN_BYTES/sizeof(unsigned int)
+#define E_SIZE_IN_UINT     E_SIZE_IN_BYTES/sizeof(unsigned int)
+#define D_SIZE_IN_UINT     D_SIZE_IN_BYTES/sizeof(unsigned int)
+#define P_SIZE_IN_UINT     P_SIZE_IN_BYTES/sizeof(unsigned int)
+#define Q_SIZE_IN_UINT     Q_SIZE_IN_BYTES/sizeof(unsigned int)
+#define DMP1_SIZE_IN_UINT  DMP1_SIZE_IN_BYTES/sizeof(unsigned int)
+#define DMQ1_SIZE_IN_UINT  DMQ1_SIZE_IN_BYTES/sizeof(unsigned int)
+#define IQMP_SIZE_IN_UINT  IQMP_SIZE_IN_BYTES/sizeof(unsigned int)
+
+typedef struct _rsa_params_t {
+	unsigned int n[N_SIZE_IN_UINT];
+	unsigned int e[E_SIZE_IN_UINT];
+	unsigned int d[D_SIZE_IN_UINT];
+	unsigned int p[P_SIZE_IN_UINT];
+	unsigned int q[Q_SIZE_IN_UINT];
+	unsigned int dmp1[DMP1_SIZE_IN_UINT];
+	unsigned int dmq1[DMQ1_SIZE_IN_UINT];
+	unsigned int iqmp[IQMP_SIZE_IN_UINT];
+}rsa_params_t;
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -656,8 +692,127 @@ extern "C" {
         const sgx_rsa3072_signature_t *p_signature,
 		sgx_rsa_result_t *p_result);
 
+    /** Create RSA key pair with <n_byte_size> key size and <e_byte_size> public exponent.
+    *
+    * Parameters:
+    *   Return: sgx_status_t  - SGX_SUCCESS or failure as defined in sgx_error.h
+    *   Inputs: p_e [In/Out] Pointer to the public exponent e.
+    *           n_byte_size [In] Size in bytes of the key modulus.
+    *           e_byte_size	[In] Size in bytes of the key public exponent.
+    *   Output: p_*			[Out] Pointer to the matching key parameter/factor buffer.
+    */
+    sgx_status_t sgx_create_rsa_key_pair(int n_byte_size, int e_byte_size, unsigned char *p_n, unsigned char *p_d, unsigned char *p_e,
+        unsigned char *p_p, unsigned char *p_q, unsigned char *p_dmp1,
+        unsigned char *p_dmq1, unsigned char *p_iqmp);
+
+    /** Decrypt ciphertext [pin_data] using RSA private key, with OAEP SHA-256
+    *
+    * Parameters:
+    *   Return: sgx_status_t  - SGX_SUCCESS or failure as defined in sgx_error.h
+    *   Inputs: rsa_key	- Pointer to the EVP_PKEY struct containting RSA private key.
+    *           pin_data - Pointer to the input ciphertext buffer.
+    *           pin_len - Ciphertext buffer size.
+    *   Output: pout_data - Pointer to the output buffer.
+    *           pout_len - Pointer to amount of data written.
+    *
+    */
+    sgx_status_t sgx_rsa_priv_decrypt_sha256(void* rsa_key, unsigned char* pout_data, size_t* pout_len, const unsigned char* pin_data, const size_t pin_len);
+
+    /** Encrypt input data [pin_data] using RSA public key, with OAEP SHA-256
+    *
+    * Parameters:
+    *   Return: sgx_status_t  - SGX_SUCCESS or failure as defined in sgx_error.h
+    *   Inputs: rsa_key - Pointer to the EVP_PKEY struct containting RSA public key.
+    *           pin_data - Pointer to the input data buffer.
+    *           pin_len - Input buffer size.
+    *   Output: pout_data - Pointer to the output buffer.
+    *           pout_len - Pointer to amount of data (ciphertext) written.
+    *
+    */
+    sgx_status_t sgx_rsa_pub_encrypt_sha256(void* rsa_key, unsigned char* pout_data, size_t* pout_len, const unsigned char* pin_data, const size_t pin_len);
+
+    /** Create RSA private key using input buffer factors in little endian.
+    *
+    * Parameters:
+    *   Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h
+    *   Inputs: prime_size - Pointer to the modulus size.
+    *           exp_size - Pointer to the public exponent e size.
+    *           g_rsa_key_e	- Pointer to the public exponent e buffer.
+    *           g_rsa_key_p	- Pointer to the prime number p.
+    *           g_rsa_key_q	- Pointer to the prime number q.
+    *           g_rsa_key_dmp1 - Pointer to dmp1 [d mod (p-1)].
+    *           g_rsa_key_dmq1 - Pointer to dmq1 [d mod (q-1)].
+    *           g_rsa_key_iqmp - Pointer to iqmp [q^-1 mod p].
+    *   Output: new_pri_key2 - Pointer to the generated private key.
+    *
+    */
+    sgx_status_t sgx_create_rsa_priv2_key(int prime_size, int exp_size, const unsigned char *g_rsa_key_e, const unsigned char *g_rsa_key_p, const unsigned char *g_rsa_key_q,
+        const unsigned char *g_rsa_key_dmp1, const unsigned char *g_rsa_key_dmq1, const unsigned char *g_rsa_key_iqmp,
+        void **new_pri_key2);
+
+    /** Create RSA private key using input buffer factors in little endian.
+    *
+    * Parameters:
+    *   Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h
+    *   Inputs: n_byte_size	- Pointer to the modulus size.
+    *           e_byte_size	- Pointer to the public exponent e size.
+    *           d_byte_size	- Pointer to the private exponent d size.
+    *           le_e - Pointer to the public exponent e buffer.
+    *           le_n - Pointer to the modulus n.
+    *           le_d - Pointer to the private exponent d.
+    *   Output: new_pri_key1 - Pointer to the generated private key.
+    *
+    */
+    sgx_status_t sgx_create_rsa_priv1_key(int n_byte_size, int e_byte_size, int d_byte_size, const unsigned char *le_n, const unsigned char *le_e,
+        const unsigned char *le_d, void **new_pri_key1);
+
+    /** Create RSA public key using input buffer factors in little endian.
+    *
+    * Parameters:
+    *   Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h
+    *   Inputs: prime_size		- Pointer to the modulus size.
+    *           exp_size		- Pointer to the public exponent e size.
+    *           le_n			- Pointer to the modulus n buffer.
+    *           le_e - Pointer to the public exponent e buffer.
+    *   Output: new_pub_key1 - Pointer to the generated public key.
+    *
+    */
+    sgx_status_t sgx_create_rsa_pub1_key(int prime_size, int exp_size, const unsigned char *le_n, const unsigned char *le_e, void **new_pub_key1);
+
+    /** Clear and free RSA key which was generated by one of the Tcrypto "sgx_create_rsa_*" APIs.
+    *
+    * Parameters:
+    *   Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h
+    *   Inputs: p_rsa_key		- Pointer to the RSA key.
+    *           (Note: All input parameters below are relevant only when using IPP based tcrypto library)
+    *           key_type		- key state type, relevant only when using IPP based tcrypto library.
+    *                             Possible options {SGX_RSA_PRIVATE_KEY, SGX_RSA_PUBLIC_KEY}
+    *           mod_size		- RSA key modulus size.
+    *           exp_size		- RSA key public exponent size.
+    *   Output:
+    *
+    */
+    sgx_status_t sgx_free_rsa_key(void *p_rsa_key, sgx_rsa_key_type_t key_type, int mod_size, int exp_size);
+
+    /** Create an ECDSA private key based on input random seed.
+    *
+    * Parameters:
+    *   Return: sgx_status_t - SGX_SUCCESS or failure as defined in sgx_error.h
+    *   Inputs: hash_drg - Input seed
+    *           hash_drg_len - Seed len
+    *           sgx_nistp256_r_m1 -
+    *           sgx_nistp256_r_m1_len - nistp256 len
+    *   Output: out_key - ECDSA private key
+    *           out_key_len - ECDSA private key length
+    *
+    */
+    sgx_status_t sgx_calculate_ecdsa_priv_key(const unsigned char* hash_drg, int hash_drg_len,
+        const unsigned char* sgx_nistp256_r_m1, int sgx_nistp256_r_m1_len,
+        unsigned char* out_key, int out_key_len);
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif
+

+ 4 - 4
sdk/tlibcrypto/Makefile

@@ -37,7 +37,7 @@ CPPFLAGS := -I$(COMMON_DIR)/inc/internal \
 
 CXXFLAGS += $(ENCLAVE_CXXFLAGS) -Werror -fno-exceptions -fno-rtti
 
-OBJ = init_tcrypto_lib.o sgx_aes_ctr.o sgx_aes_gcm.o sgx_cmac128.o sgx_ecc256.o sgx_ecc256_ecdsa.o sgx_sha256.o sgx_sha256_msg.o sgx_ecc256_internal.o sgx_rsa3072.o
+OBJ = init_tcrypto_lib.o sgx_aes_ctr.o sgx_rsa_encryption.o sgx_aes_gcm.o sgx_cmac128.o sgx_ecc256.o sgx_ecc256_ecdsa.o sgx_sha256.o sgx_sha256_msg.o sgx_ecc256_internal.o sgx_rsa3072.o
 SHARED_OBJ = tcrypto_version.o
 
 ifneq ($(USE_OPT_LIBS), 1)
@@ -50,14 +50,14 @@ else
 endif #($(ARCH), x86_64)
 
 ifdef DEBUG
+    SGX_COMMON_CFLAGS += -O0
     OPENSSL_LIBRARY_PATH := $(OPENSSL_PACKAGE)/lib64/debug
 else
     OPENSSL_LIBRARY_PATH := $(OPENSSL_PACKAGE)/lib64/release
 endif
 
-SGXSSL_Library_Name := sgx_tsgxssl
 OpenSSL_Crypto_Library_Name := sgx_tsgxssl_crypto
-
+SGXSSL_Library_Name := sgx_tsgxssl
 PREPARE_SGXSSL := $(LINUX_EXTERNAL_DIR)/sgxssl/prepare_sgxssl.sh
 PREPRARE_SGX_SSL:
 	chmod 755 $(PREPARE_SGXSSL)
@@ -72,7 +72,7 @@ LIB_NAME := libsgx_tcrypto_sgxssl.a
 else
 
 CPPFLAGS += -I$(SGX_IPP_INC)
-OBJ += sgx_ecc256_common.o
+OBJ += sgx_ecc256_common.o sgx_rsa_internal.o
 SRCDIR := ipp
 
 LIB_NAME := libsgx_tcrypto_ipp.a

+ 552 - 0
sdk/tlibcrypto/ipp/sgx_rsa_encryption.cpp

@@ -0,0 +1,552 @@
+/*
+ * Copyright (C) 2011-2018 Intel Corporation. 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 Intel Corporation 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.
+ *
+ */
+
+/**
+* File:
+*     sgx_rsa_encryption.cpp
+* Description:
+*     Wrapper for rsa operation functions
+*
+*/
+#include "util.h"
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "sgx_error.h"
+#include "ipp_wrapper.h"
+#include "sgx_trts.h"
+
+#define RSA_SEED_SIZE_SHA256 32
+
+sgx_status_t sgx_create_rsa_key_pair(int n_byte_size, int e_byte_size, unsigned char *p_n, unsigned char *p_d, unsigned char *p_e,
+    unsigned char *p_p, unsigned char *p_q, unsigned char *p_dmp1,
+    unsigned char *p_dmq1, unsigned char *p_iqmp)
+{
+    if (n_byte_size <= 0 || e_byte_size <= 0 || p_n == NULL || p_d == NULL || p_e == NULL ||
+        p_p == NULL || p_q == NULL || p_dmp1 == NULL || p_dmq1 == NULL || p_iqmp == NULL) {
+        return SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    IppsRSAPrivateKeyState *p_pri_key = NULL;
+	IppsRSAPublicKeyState *p_pub_key = NULL;
+    IppStatus error_code = ippStsNoErr;
+    sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+    IppsPRNGState *p_rand = NULL;
+    IppsPrimeState *p_prime = NULL;
+    Ipp8u * scratch_buffer = NULL;
+    int pri_size = 0;
+    IppsBigNumState *bn_n = NULL, *bn_e = NULL, *bn_d = NULL, *bn_e_s = NULL, *bn_p = NULL, *bn_q = NULL, *bn_dmp1 = NULL, *bn_dmq1 = NULL, *bn_iqmp = NULL;
+    int validate_keys = IPP_IS_INVALID;
+    int size;
+    IppsBigNumSGN sgn;
+
+    do {
+
+        //create a new PRNG
+        //
+        error_code = newPRNG(&p_rand);
+        ERROR_BREAK(error_code);
+        
+        //create a new prime number generator
+        //
+        error_code = newPrimeGen(n_byte_size * 8 / 2, &p_prime);
+        ERROR_BREAK(error_code);
+        
+        //allocate and init private key of type 2
+        //
+        error_code = ippsRSA_GetSizePrivateKeyType2(n_byte_size / 2 * 8, n_byte_size / 2 * 8, &pri_size);
+        ERROR_BREAK(error_code);
+        p_pri_key = (IppsRSAPrivateKeyState *)malloc(pri_size);
+        NULL_BREAK(p_pri_key);
+        error_code = ippsRSA_InitPrivateKeyType2(n_byte_size / 2 * 8, n_byte_size / 2 * 8, p_pri_key, pri_size);
+        ERROR_BREAK(error_code);
+        
+        //allocate scratch buffer, to be used as temp buffer
+        //
+        scratch_buffer = (Ipp8u *)malloc(pri_size);
+        NULL_BREAK(scratch_buffer);
+        memset(scratch_buffer, 0, pri_size);
+
+        //allocate and initialize RSA BNs
+        //
+        error_code = newBN((const Ipp32u*)p_e, e_byte_size, &bn_e_s);
+        ERROR_BREAK(error_code);
+        error_code = newBN(NULL, n_byte_size, &bn_n);
+        ERROR_BREAK(error_code);
+        error_code = newBN(NULL, e_byte_size, &bn_e);
+        ERROR_BREAK(error_code);
+        error_code = newBN(NULL, n_byte_size, &bn_d);
+        ERROR_BREAK(error_code);
+        error_code = newBN(NULL, n_byte_size / 2, &bn_p);
+        ERROR_BREAK(error_code);
+        error_code = newBN(NULL, n_byte_size / 2, &bn_q);
+        ERROR_BREAK(error_code);
+        error_code = newBN(NULL, n_byte_size / 2, &bn_dmp1);
+        ERROR_BREAK(error_code);
+        error_code = newBN(NULL, n_byte_size / 2, &bn_dmq1);
+        ERROR_BREAK(error_code);
+        error_code = newBN(NULL, n_byte_size / 2, &bn_iqmp);
+        ERROR_BREAK(error_code);
+
+        //generate RSA key components with n_byte_size modulus and p_e public exponent
+        //
+        error_code = ippsRSA_GenerateKeys(bn_e_s,
+            bn_n,
+            bn_e,
+            bn_d,
+            p_pri_key,
+            scratch_buffer,
+            1,
+            p_prime,
+            ippsPRNGen,
+            p_rand);
+        ERROR_BREAK(error_code);
+
+        //extract private key components into BNs
+        //
+        error_code = ippsRSA_GetPrivateKeyType2(bn_p,
+            bn_q,
+            bn_dmp1,
+            bn_dmq1,
+            bn_iqmp,
+            p_pri_key);
+        ERROR_BREAK(error_code);
+
+        //allocate and initialize public key
+        //
+        error_code = ippsRSA_GetSizePublicKey(n_byte_size * 8, e_byte_size * 8, &pri_size);
+        ERROR_BREAK(error_code);
+        p_pub_key = (IppsRSAPublicKeyState *)malloc(pri_size);
+        NULL_BREAK(p_pub_key);
+        error_code = ippsRSA_InitPublicKey(n_byte_size * 8, e_byte_size * 8, p_pub_key, pri_size);
+        ERROR_BREAK(error_code);
+        error_code = ippsRSA_SetPublicKey(bn_n, bn_e, p_pub_key);
+        ERROR_BREAK(error_code);
+        
+        //validate generated keys
+        //
+        ippsRSA_ValidateKeys(&validate_keys, p_pub_key, p_pri_key, NULL, scratch_buffer, 10, p_prime, ippsPRNGen, p_rand);
+        if (validate_keys != IPP_IS_VALID) {
+            break;
+        }
+
+        //extract RSA components from BNs into output buffers
+        //
+        error_code = ippsGetSize_BN(bn_n, &size);
+        ERROR_BREAK(error_code);
+        error_code = ippsGet_BN(&sgn, &size, (Ipp32u*)p_n, bn_n);
+        ERROR_BREAK(error_code);
+        error_code = ippsGetSize_BN(bn_e, &size);
+        ERROR_BREAK(error_code);
+        error_code = ippsGet_BN(&sgn, &size, (Ipp32u*)p_e, bn_e);
+        ERROR_BREAK(error_code);
+        error_code = ippsGetSize_BN(bn_d, &size);
+        ERROR_BREAK(error_code);
+        error_code = ippsGet_BN(&sgn, &size, (Ipp32u*)p_d, bn_d);
+        ERROR_BREAK(error_code);
+        error_code = ippsGetSize_BN(bn_p, &size);
+        ERROR_BREAK(error_code);
+        error_code = ippsGet_BN(&sgn, &size, (Ipp32u*)p_p, bn_p);
+        ERROR_BREAK(error_code);
+        error_code = ippsGetSize_BN(bn_q, &size);
+        ERROR_BREAK(error_code);
+        error_code = ippsGet_BN(&sgn, &size, (Ipp32u*)p_q, bn_q);
+        ERROR_BREAK(error_code);
+        error_code = ippsGetSize_BN(bn_dmp1, &size);
+        ERROR_BREAK(error_code);
+        error_code = ippsGet_BN(&sgn, &size, (Ipp32u*)p_dmp1, bn_dmp1);
+        ERROR_BREAK(error_code);
+        error_code = ippsGetSize_BN(bn_dmq1, &size);
+        ERROR_BREAK(error_code);
+        error_code = ippsGet_BN(&sgn, &size, (Ipp32u*)p_dmq1, bn_dmq1);
+        ERROR_BREAK(error_code);
+        error_code = ippsGetSize_BN(bn_iqmp, &size);
+        ERROR_BREAK(error_code);
+        error_code = ippsGet_BN(&sgn, &size, (Ipp32u*)p_iqmp, bn_iqmp);
+        ERROR_BREAK(error_code);
+
+        ret_code = SGX_SUCCESS;
+
+    } while (0);
+
+    secure_free_BN(bn_e_s, e_byte_size);
+    secure_free_BN(bn_e, e_byte_size);
+    secure_free_BN(bn_d, n_byte_size);
+    secure_free_BN(bn_n, n_byte_size);
+    secure_free_BN(bn_p, n_byte_size / 2);
+    secure_free_BN(bn_q, n_byte_size / 2);
+    secure_free_BN(bn_dmp1, n_byte_size / 2);
+    secure_free_BN(bn_dmq1, n_byte_size / 2);
+    secure_free_BN(bn_iqmp, n_byte_size / 2);
+
+    SAFE_FREE_MM(p_rand);
+    SAFE_FREE_MM(p_prime);
+    secure_free_rsa_pri2_key(n_byte_size / 2, p_pri_key);
+    secure_free_rsa_pub_key(n_byte_size, e_byte_size, p_pub_key);
+    SAFE_FREE_MM(scratch_buffer);
+
+    return ret_code;
+}
+
+sgx_status_t sgx_create_rsa_priv2_key(int prime_size, int exp_size, const unsigned char *g_rsa_key_e, const unsigned char *g_rsa_key_p, const unsigned char *g_rsa_key_q,
+    const unsigned char *g_rsa_key_dmp1, const unsigned char *g_rsa_key_dmq1, const unsigned char *g_rsa_key_iqmp,
+    void **new_pri_key2)
+{
+    (void)(exp_size);
+    (void)(g_rsa_key_e);
+    IppsRSAPrivateKeyState *p_rsa2 = NULL;
+    IppsBigNumState *p_p = NULL, *p_q = NULL, *p_dmp1 = NULL, *p_dmq1 = NULL, *p_iqmp = NULL;
+    int rsa2_size = 0;
+    sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+    if (prime_size <= 0 || g_rsa_key_p == NULL || g_rsa_key_q == NULL || g_rsa_key_dmp1 == NULL || g_rsa_key_dmq1 == NULL || g_rsa_key_iqmp == NULL || new_pri_key2 == NULL) {
+        return SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    IppStatus error_code = ippStsNoErr;
+    do {
+
+        //generate and assign RSA components BNs
+        //
+        error_code = newBN((const Ipp32u*)g_rsa_key_p, prime_size / 2, &p_p);
+        ERROR_BREAK(error_code);
+        error_code = newBN((const Ipp32u*)g_rsa_key_q, prime_size / 2, &p_q);
+        ERROR_BREAK(error_code);
+        error_code = newBN((const Ipp32u*)g_rsa_key_dmp1, prime_size / 2, &p_dmp1);
+        ERROR_BREAK(error_code);
+        error_code = newBN((const Ipp32u*)g_rsa_key_dmq1, prime_size / 2, &p_dmq1);
+        ERROR_BREAK(error_code);
+        error_code = newBN((const Ipp32u*)g_rsa_key_iqmp, prime_size / 2, &p_iqmp);
+        ERROR_BREAK(error_code);
+        
+        //allocate and initialize private key of type 2
+        //
+        error_code = ippsRSA_GetSizePrivateKeyType2(prime_size / 2 * 8, prime_size / 2 * 8, &rsa2_size);
+        ERROR_BREAK(error_code);
+        p_rsa2 = (IppsRSAPrivateKeyState *)malloc(rsa2_size);
+        NULL_BREAK(p_rsa2);
+        error_code = ippsRSA_InitPrivateKeyType2(prime_size / 2 * 8, prime_size / 2 * 8, p_rsa2, rsa2_size);
+        ERROR_BREAK(error_code);
+        
+        //setup private key with values of input components
+        //
+        error_code = ippsRSA_SetPrivateKeyType2(p_p, p_q, p_dmp1, p_dmq1, p_iqmp, p_rsa2);
+        ERROR_BREAK(error_code);
+        *new_pri_key2 = (void*)p_rsa2;
+
+        ret_code = SGX_SUCCESS;
+    } while (0);
+
+    secure_free_BN(p_p, prime_size / 2);
+    secure_free_BN(p_q, prime_size / 2);
+    secure_free_BN(p_dmp1, prime_size / 2);
+    secure_free_BN(p_dmq1, prime_size / 2);
+    secure_free_BN(p_iqmp, prime_size / 2);
+
+    if (ret_code != SGX_SUCCESS) {
+        secure_free_rsa_pri2_key(prime_size, p_rsa2);
+    }
+    return ret_code;
+}
+
+sgx_status_t sgx_create_rsa_pub1_key(int prime_size, int exp_size, const unsigned char *le_n, const unsigned char *le_e, void **new_pub_key1)
+{
+    if (new_pub_key1 == NULL || prime_size <= 0 || exp_size <= 0 || le_n == NULL || le_e == NULL) {
+        return SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    IppsRSAPublicKeyState *p_pub_key = NULL;
+    IppsBigNumState *p_n = NULL, *p_e = NULL;
+    int rsa_size = 0;
+    sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+    IppStatus error_code = ippStsNoErr;
+    do {
+
+        //generate and assign RSA components BNs
+        //
+        error_code = newBN((const Ipp32u*)le_n, prime_size, &p_n);
+        ERROR_BREAK(error_code);
+        error_code = newBN((const Ipp32u*)le_e, exp_size, &p_e);
+        ERROR_BREAK(error_code);
+
+        //allocate and initialize public key
+        //
+        error_code = ippsRSA_GetSizePublicKey(prime_size * 8, exp_size * 8, &rsa_size);
+        ERROR_BREAK(error_code);
+        p_pub_key = (IppsRSAPublicKeyState *)malloc(rsa_size);
+        NULL_BREAK(p_pub_key);
+        error_code = ippsRSA_InitPublicKey(prime_size * 8, exp_size * 8, p_pub_key, rsa_size);
+        ERROR_BREAK(error_code);
+
+        //setup public key with values of input components
+        //
+        error_code = ippsRSA_SetPublicKey(p_n, p_e, p_pub_key);
+        ERROR_BREAK(error_code);
+
+        *new_pub_key1 = (void*)p_pub_key;
+        ret_code = SGX_SUCCESS;
+    } while (0);
+
+    secure_free_BN(p_n, prime_size);
+    secure_free_BN(p_e, exp_size);
+
+    if (ret_code != SGX_SUCCESS) {
+        secure_free_rsa_pub_key(prime_size, exp_size, p_pub_key);
+    }
+
+    return ret_code;
+}
+
+sgx_status_t sgx_rsa_pub_encrypt_sha256(void* rsa_key, unsigned char* pout_data, size_t* pout_len, const unsigned char* pin_data,
+    const size_t pin_len) {
+    (void)(pout_len);
+    if (rsa_key == NULL || pin_data == NULL || pin_len < 1 || pin_len >= INT_MAX) {
+        return SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    uint8_t *p_scratch_buffer = NULL;
+    Ipp8u seeds[RSA_SEED_SIZE_SHA256] = { 0 };
+    int scratch_buff_size = 0;
+    sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+    if (pout_data == NULL) {
+        return SGX_SUCCESS;
+    }
+
+    do {
+        
+        //get scratch buffer size, to be used as temp buffer, and allocate it
+        //
+        if (ippsRSA_GetBufferSizePublicKey(&scratch_buff_size, (IppsRSAPublicKeyState*)rsa_key) != ippStsNoErr) {
+            break;
+        }
+        p_scratch_buffer = (uint8_t *)malloc(8 * scratch_buff_size);
+        NULL_BREAK(p_scratch_buffer);
+
+        //get random seed
+        //
+        if (sgx_read_rand(seeds, RSA_SEED_SIZE_SHA256) != SGX_SUCCESS) {
+            break;
+        }
+
+        //encrypt input data with public rsa_key and SHA256 padding
+        //
+        if (ippsRSAEncrypt_OAEP(pin_data, (int)pin_len, NULL, 0, seeds,
+            pout_data, (IppsRSAPublicKeyState*)rsa_key, IPP_ALG_HASH_SHA256, p_scratch_buffer) != ippStsNoErr) {
+            break;
+        }
+
+        ret_code = SGX_SUCCESS;
+    } while (0);
+
+    memset_s(seeds, RSA_SEED_SIZE_SHA256, 0, RSA_SEED_SIZE_SHA256);
+    SAFE_FREE_MM(p_scratch_buffer);
+
+    return ret_code;
+}
+
+sgx_status_t sgx_rsa_priv_decrypt_sha256(void* rsa_key, unsigned char* pout_data, size_t* pout_len, const unsigned char* pin_data,
+    const size_t pin_len) {
+    (void)(pin_len);
+    if (rsa_key == NULL || pout_len == NULL || pin_data == NULL) {
+        return SGX_ERROR_INVALID_PARAMETER;
+    }
+    sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+    uint8_t *p_scratch_buffer = NULL;
+    int scratch_buff_size = 0;
+    if (pout_data == NULL) {
+        return SGX_SUCCESS;
+    }
+    do {
+
+        //get scratch buffer size, to be used as temp buffer, and allocate it
+        //
+        if (ippsRSA_GetBufferSizePrivateKey(&scratch_buff_size, (IppsRSAPrivateKeyState*)rsa_key) != ippStsNoErr) {
+            break;
+        }
+        p_scratch_buffer = (uint8_t *)malloc(scratch_buff_size);
+        NULL_BREAK(p_scratch_buffer);
+
+        //decrypt input ciphertext using private key rsa_key
+        if (ippsRSADecrypt_OAEP(pin_data, NULL, 0, pout_data, (int*)pout_len, (IppsRSAPrivateKeyState*)rsa_key,
+            IPP_ALG_HASH_SHA256, p_scratch_buffer) != ippStsNoErr) {
+            break;
+        }
+        ret_code = SGX_SUCCESS;
+
+    } while (0);
+    SAFE_FREE_MM(p_scratch_buffer);
+
+    return ret_code;
+}
+
+sgx_status_t sgx_create_rsa_priv1_key(int n_byte_size, int e_byte_size, int d_byte_size, const unsigned char *le_n, const unsigned char *le_e,
+    const unsigned char *le_d, void **new_pri_key1)
+{
+    if (n_byte_size <= 0 || e_byte_size <= 0 || d_byte_size <= 0 || new_pri_key1 == NULL ||
+        le_n == NULL || le_e == NULL || le_d == NULL) {
+        return SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    IppsRSAPrivateKeyState *p_rsa1 = NULL;
+    IppsBigNumState *p_n = NULL, *p_d = NULL;
+    int rsa1_size = 0;
+    sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+
+    IppStatus error_code = ippStsNoErr;
+    do {
+
+        //generate and assign RSA components BNs
+        //
+        error_code = newBN((const Ipp32u*)le_n, n_byte_size, &p_n);
+        ERROR_BREAK(error_code);
+        error_code = newBN((const Ipp32u*)le_d, d_byte_size, &p_d);
+        ERROR_BREAK(error_code);
+
+        //allocate and init private key of type 1
+        //
+        error_code = ippsRSA_GetSizePrivateKeyType1(n_byte_size * 8, d_byte_size * 8, &rsa1_size);
+        ERROR_BREAK(error_code);
+        p_rsa1 = (IppsRSAPrivateKeyState *)malloc(rsa1_size);
+        NULL_BREAK(p_rsa1);
+        error_code = ippsRSA_InitPrivateKeyType1(n_byte_size * 8, d_byte_size * 8, p_rsa1, rsa1_size);
+        ERROR_BREAK(error_code);
+        
+        //setup private key with values of input components
+        //
+        error_code = ippsRSA_SetPrivateKeyType1(p_n, p_d, p_rsa1);
+        ERROR_BREAK(error_code);
+
+        *new_pri_key1 = p_rsa1;
+        ret_code = SGX_SUCCESS;
+
+    } while (0);
+
+    secure_free_BN(p_n, n_byte_size);
+    secure_free_BN(p_d, d_byte_size);
+    if (ret_code != SGX_SUCCESS) {
+        secure_free_rsa_pri1_key(n_byte_size, d_byte_size, p_rsa1);
+    }
+
+    return ret_code;
+}
+
+
+sgx_status_t sgx_free_rsa_key(void *p_rsa_key, sgx_rsa_key_type_t key_type, int mod_size, int exp_size) {
+	if (key_type == SGX_RSA_PRIVATE_KEY) {
+		(void)(exp_size);
+		secure_free_rsa_pri2_key(mod_size, (IppsRSAPrivateKeyState*)p_rsa_key);
+	} else if (key_type == SGX_RSA_PUBLIC_KEY) {
+		secure_free_rsa_pub_key(mod_size, exp_size, (IppsRSAPublicKeyState*)p_rsa_key);
+	}
+
+	return SGX_SUCCESS;
+}
+
+
+sgx_status_t sgx_calculate_ecdsa_priv_key(const unsigned char* hash_drg, int hash_drg_len,
+    const unsigned char* sgx_nistp256_r_m1, int sgx_nistp256_r_m1_len,
+    unsigned char* out_key, int out_key_len) {
+
+    if (out_key == NULL || hash_drg_len <= 0 || sgx_nistp256_r_m1_len <= 0 ||
+        out_key_len <= 0 || hash_drg == NULL || sgx_nistp256_r_m1 == NULL) {
+        return SGX_ERROR_INVALID_PARAMETER;
+    }
+
+    sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+    IppStatus ipp_status = ippStsNoErr;
+    IppsBigNumState *bn_d = NULL;
+    IppsBigNumState *bn_m = NULL;
+    IppsBigNumState *bn_o = NULL;
+    IppsBigNumState *bn_one = NULL;
+    Ipp32u i = 1;
+
+    do {
+
+        //allocate and initialize BNs
+        //
+        ipp_status = newBN(reinterpret_cast<const Ipp32u *>(hash_drg), hash_drg_len, &bn_d);
+        ERROR_BREAK(ipp_status);
+        
+        //generate mod to be n-1 where n is order of ECC Group
+        //
+        ipp_status = newBN(reinterpret_cast<const Ipp32u *>(sgx_nistp256_r_m1), sgx_nistp256_r_m1_len, &bn_m);
+        ERROR_BREAK(ipp_status);
+        
+        //allocate memory for output BN
+        //
+        ipp_status = newBN(NULL, sgx_nistp256_r_m1_len, &bn_o);
+        ERROR_BREAK(ipp_status);
+        
+        //create big number with value of 1
+        //
+        ipp_status = newBN(&i, sizeof(Ipp32u), &bn_one);
+        ERROR_BREAK(ipp_status);
+
+        //calculate output's BN value
+        ipp_status = ippsMod_BN(bn_d, bn_m, bn_o);
+        ERROR_BREAK(ipp_status)
+
+        //increase by 1
+        //
+        ipp_status = ippsAdd_BN(bn_o, bn_one, bn_o);
+        ERROR_BREAK(ipp_status);
+
+        /*Unmatched size*/
+        if (sgx_nistp256_r_m1_len != sizeof(sgx_ec256_private_t)) {
+            break;
+        }
+
+        //convert BN_o into octet string
+        ipp_status = ippsGetOctString_BN(reinterpret_cast<Ipp8u *>(out_key), sgx_nistp256_r_m1_len, bn_o);//output data in bigendian order
+        ERROR_BREAK(ipp_status);
+
+        ret_code = SGX_SUCCESS;
+    } while (0);
+
+    if (NULL != bn_d) {
+        secure_free_BN(bn_d, hash_drg_len);
+    }
+    if (NULL != bn_m) {
+        secure_free_BN(bn_m, sgx_nistp256_r_m1_len);
+    }
+    if (NULL != bn_o) {
+        secure_free_BN(bn_o, sgx_nistp256_r_m1_len);
+    }
+    if (NULL != bn_one) {
+        secure_free_BN(bn_one, sizeof(uint32_t));
+    }
+    if (ret_code != SGX_SUCCESS) {
+        (void)memset_s(out_key, out_key_len, 0, out_key_len);
+    }
+
+    return ret_code;
+}

+ 224 - 0
sdk/tlibcrypto/ipp/sgx_rsa_internal.cpp

@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2011-2018 Intel Corporation. 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 Intel Corporation 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.
+ *
+ */
+
+/**
+* File:
+*     sgx_rsa_encryption.cpp
+* Description:
+*     Wrapper for rsa operation functions
+*
+*/
+#include "util.h"
+#include <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "sgx_error.h"
+#include "sgx_tcrypto.h"
+#include "ipp_wrapper.h"
+#include "sgx_trts.h"
+
+#define RSA_SEED_SIZE_SHA256 32
+
+extern "C" IppStatus newPrimeGen(int nMaxBits, IppsPrimeState ** pPrimeG)
+{
+    if (pPrimeG == NULL || nMaxBits <= 0) {
+        return ippStsBadArgErr;
+    }
+    int ctxSize = 0;
+    IppStatus error_code = ippsPrimeGetSize(nMaxBits, &ctxSize);
+    if (error_code != ippStsNoErr) {
+        return error_code;
+    }
+    IppsPrimeState* pCtx = (IppsPrimeState *)malloc(ctxSize);
+    if (pCtx == NULL) {
+        return ippStsMemAllocErr;
+    }
+
+    error_code = ippsPrimeInit(nMaxBits, pCtx);
+    if (error_code != ippStsNoErr) {
+        free(pCtx);
+        return error_code;
+    }
+
+    *pPrimeG = pCtx;
+    return error_code;
+}
+
+extern "C" IppStatus newPRNG(IppsPRNGState **pRandGen)
+{
+    if (pRandGen == NULL) {
+        return ippStsBadArgErr;
+    }
+    int ctxSize = 0;
+    IppStatus error_code = ippsPRNGGetSize(&ctxSize);
+    if (error_code != ippStsNoErr) {
+        return error_code;
+    }
+
+    IppsPRNGState* pCtx = (IppsPRNGState *)malloc(ctxSize);
+    if (pCtx == NULL) {
+        return ippStsMemAllocErr;
+    }
+
+    error_code = ippsPRNGInit(160, pCtx);
+    if (error_code != ippStsNoErr) {
+        free(pCtx);
+        return error_code;
+    }
+
+    *pRandGen = pCtx;
+    return error_code;
+}
+
+
+extern "C" IppStatus newBN(const Ipp32u *data, int size_in_bytes, IppsBigNumState **p_new_BN)
+{
+    IppsBigNumState *pBN = 0;
+    int bn_size = 0;
+
+    if (p_new_BN == NULL || size_in_bytes <= 0 || size_in_bytes % sizeof(Ipp32u))
+        return ippStsBadArgErr;
+
+    /* Get the size of the IppsBigNumState context in bytes */
+    IppStatus error_code = ippsBigNumGetSize(size_in_bytes / (int)sizeof(Ipp32u), &bn_size);
+    if (error_code != ippStsNoErr) {
+        *p_new_BN = 0;
+        return error_code;
+    }
+    pBN = (IppsBigNumState *)malloc(bn_size);
+    if (!pBN) {
+        error_code = ippStsMemAllocErr;
+        *p_new_BN = 0;
+        return error_code;
+    }
+    /* Initializes context and partitions allocated buffer */
+    error_code = ippsBigNumInit(size_in_bytes / (int)sizeof(Ipp32u), pBN);
+    if (error_code != ippStsNoErr) {
+        SAFE_FREE_MM(pBN);
+        *p_new_BN = 0;
+        return error_code;
+    }
+    if (data) {
+        error_code = ippsSet_BN(IppsBigNumPOS, size_in_bytes / (int)sizeof(Ipp32u), data, pBN);
+        if (error_code != ippStsNoErr) {
+            SAFE_FREE_MM(pBN);
+            *p_new_BN = 0;
+            return error_code;
+        }
+    }
+    *p_new_BN = pBN;
+    return error_code;
+
+}
+
+extern "C" void secure_free_rsa_pri1_key(int n_byte_size, int d_byte_size, IppsRSAPrivateKeyState *pri_key1)
+{
+    if (n_byte_size <= 0 || d_byte_size <= 0 || pri_key1 == NULL) {
+        if (pri_key1)
+            free(pri_key1);
+        return;
+    }
+
+    int rsa1_size = 0;
+    if (ippsRSA_GetSizePrivateKeyType1(n_byte_size * 8, d_byte_size * 8, &rsa1_size) != ippStsNoErr) {
+        free(pri_key1);
+        return;
+    }
+    /* Clear the buffer before free. */
+    memset_s(pri_key1, rsa1_size, 0, rsa1_size);
+    free(pri_key1);
+    return;
+}
+
+extern "C" void secure_free_rsa_pri2_key(int p_byte_size, IppsRSAPrivateKeyState *pri_key2)
+{
+    if (p_byte_size <= 0 || pri_key2 == NULL) {
+        if (pri_key2)
+            free(pri_key2);
+        return;
+    }
+
+    int rsa2_size = 0;
+    if (ippsRSA_GetSizePrivateKeyType2(p_byte_size / 2 * 8, p_byte_size / 2 * 8, &rsa2_size) != ippStsNoErr) {
+        free(pri_key2);
+        return;
+    }
+    /* Clear the buffer before free. */
+    memset_s(pri_key2, rsa2_size, 0, rsa2_size);
+    free(pri_key2);
+    return;
+}
+
+extern "C" void secure_free_BN(IppsBigNumState *pBN, int size_in_bytes)
+{
+    if (pBN == NULL || size_in_bytes <= 0 || size_in_bytes % sizeof(Ipp32u)) {
+        if (pBN) {
+            free(pBN);
+        }
+        return;
+    }
+
+    int bn_size = 0;
+
+    /* Get the size of the IppsBigNumState context in bytes
+    * Since we have checked the size_in_bytes before and the &bn_size is not NULL,
+    * ippsBigNumGetSize never returns failure
+    */
+    if (ippsBigNumGetSize(size_in_bytes / (int)sizeof(Ipp32u), &bn_size) != ippStsNoErr) {
+        free(pBN);
+        return;
+    }
+    /* Clear the buffer before free. */
+    memset_s(pBN, bn_size, 0, bn_size);
+    free(pBN);
+    return;
+}
+
+
+extern "C" void secure_free_rsa_pub_key(int n_byte_size, int e_byte_size, IppsRSAPublicKeyState *pub_key)
+{
+    if (n_byte_size <= 0 || e_byte_size <= 0 || pub_key == NULL) {
+        if (pub_key)
+            free(pub_key);
+        return;
+    }
+    int rsa_size = 0;
+    if (ippsRSA_GetSizePublicKey(n_byte_size * 8, e_byte_size * 8, &rsa_size) != ippStsNoErr) {
+        free(pub_key);
+        return;
+    }
+    /* Clear the buffer before free. */
+    memset_s(pub_key, rsa_size, 0, rsa_size);
+    free(pub_key);
+    return;
+}

+ 2 - 2
sdk/tlibcrypto/sgxssl/sgx_ecc256.cpp

@@ -136,12 +136,12 @@ sgx_status_t sgx_ecc256_create_key_pair(sgx_ec256_private_t *p_private,
 		// get public and private keys
 		//
 		public_k = EC_KEY_get0_public_key(ec_key);
-		if (NULL == ec_key) {
+		if (NULL == public_k) {
 			break;
 		}
 
 		private_k = EC_KEY_get0_private_key(ec_key);
-		if (NULL == ec_key) {
+		if (NULL == private_k) {
 			break;
 		}
 

+ 66 - 0
sdk/tlibcrypto/sgxssl/sgx_ecc256_ecdsa.cpp

@@ -34,6 +34,8 @@
 #include <openssl/ec.h>
 #include <openssl/bn.h>
 #include <openssl/err.h>
+#include "ssl_wrapper.h"
+#include "se_memcpy.h"
 #include "sgx_tcrypto.h"
 
 /* Computes signature for data based on private key
@@ -337,3 +339,67 @@ sgx_status_t sgx_ecdsa_verify(const uint8_t *p_data,
 
 	return retval;
 }
+
+
+sgx_status_t sgx_calculate_ecdsa_priv_key(const unsigned char* hash_drg, int hash_drg_len,
+	const unsigned char* sgx_nistp256_r_m1, int sgx_nistp256_r_m1_len,
+	unsigned char* out_key, int out_key_len) {
+
+	if (out_key == NULL || hash_drg_len <= 0 || sgx_nistp256_r_m1_len <= 0 ||
+		out_key_len <= 0 || hash_drg == NULL || sgx_nistp256_r_m1 == NULL) {
+		return SGX_ERROR_INVALID_PARAMETER;
+	}
+
+	sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+	int result_len = 0;
+	BIGNUM* bn_d = NULL;
+	BIGNUM* bn_m = NULL;
+	BIGNUM* bn_o = NULL;
+	BN_CTX* tmp_ctx = NULL;
+
+	do {
+
+		bn_o = BN_new();
+		NULL_BREAK(bn_o);
+
+		bn_d = BN_lebin2bn(hash_drg, hash_drg_len, bn_d);
+		BN_CHECK_BREAK(bn_d);
+
+		bn_m = BN_lebin2bn(sgx_nistp256_r_m1, sgx_nistp256_r_m1_len, bn_m);
+		BN_CHECK_BREAK(bn_m);
+
+		tmp_ctx = BN_CTX_new();
+		NULL_BREAK(tmp_ctx);
+
+		if (!BN_mod(bn_o, bn_d, bn_m, tmp_ctx)) {
+			break;
+		}
+
+		if (!BN_add_word(bn_o, 1)) {
+			break;
+		}
+
+		result_len = BN_num_bytes(bn_o);
+		if ((result_len < 0) || (out_key_len < result_len)) {
+			break;
+		}
+		if (BN_bn2bin(bn_o, out_key) != result_len) {
+			break;
+		}
+
+		ret_code = SGX_SUCCESS;
+	} while (0);
+
+	//clear and free used structs
+	//
+	BN_CTX_free(tmp_ctx);
+	BN_clear_free(bn_d);
+	BN_clear_free(bn_m);
+	BN_clear_free(bn_o);
+
+	if (ret_code != SGX_SUCCESS) {
+		(void)memset_s(out_key, out_key_len, 0, out_key_len);
+	}
+
+	return ret_code;
+}

+ 438 - 0
sdk/tlibcrypto/sgxssl/sgx_rsa_encryption.cpp

@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2011-2018 Intel Corporation. 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 Intel Corporation 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.
+ *
+ */
+
+/**
+* File:
+*     sgx_rsa_encryption.cpp
+* Description:
+*     Wrapper for rsa operation functions
+*
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "sgx_error.h"
+#include "sgx_tcrypto.h"
+#include "se_tcrypto_common.h"
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/evp.h>
+#include <openssl/err.h>
+#include "ssl_wrapper.h"
+
+sgx_status_t sgx_create_rsa_key_pair(int n_byte_size, int e_byte_size, unsigned char *p_n, unsigned char *p_d, unsigned char *p_e,
+	unsigned char *p_p, unsigned char *p_q, unsigned char *p_dmp1,
+	unsigned char *p_dmq1, unsigned char *p_iqmp)
+{
+	if (n_byte_size <= 0 || e_byte_size <= 0 || p_n == NULL || p_d == NULL || p_e == NULL ||
+		p_p == NULL || p_q == NULL || p_dmp1 == NULL || p_dmq1 == NULL || p_iqmp == NULL) {
+		return SGX_ERROR_INVALID_PARAMETER;
+	}
+
+	sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+	RSA* rsa_ctx = NULL;
+	BIGNUM* bn_n = NULL;
+	BIGNUM* bn_e = NULL;
+	BIGNUM* tmp_bn_e = NULL;
+	BIGNUM* bn_d = NULL;
+	BIGNUM* bn_dmp1 = NULL;
+	BIGNUM* bn_dmq1 = NULL;
+	BIGNUM* bn_iqmp = NULL;
+	BIGNUM* bn_q = NULL;
+	BIGNUM* bn_p = NULL;
+
+	do {
+		//create new rsa ctx
+		//
+		rsa_ctx = RSA_new();
+		if (rsa_ctx == NULL) {
+			ret_code = SGX_ERROR_OUT_OF_MEMORY;
+			break;
+		}
+
+		//generate rsa key pair, with n_byte_size*8 mod size and p_e exponent
+		//
+		tmp_bn_e = BN_lebin2bn(p_e, e_byte_size, tmp_bn_e);
+		BN_CHECK_BREAK(tmp_bn_e);
+		if (RSA_generate_key_ex(rsa_ctx, n_byte_size * 8, tmp_bn_e, NULL) != 1) {
+			break;
+		}
+
+		//validate RSA key size match input parameter n size
+		//
+		int gen_rsa_size = RSA_size(rsa_ctx);
+		if (gen_rsa_size != n_byte_size) {
+			break;
+		}
+
+		//get RSA key internal values
+		//
+		RSA_get0_key(rsa_ctx, (const BIGNUM**)(&bn_n), (const BIGNUM**)(&bn_e), (const BIGNUM**)(&bn_d));
+		RSA_get0_factors(rsa_ctx, (const BIGNUM**)(&bn_p), (const BIGNUM**)(&bn_q));
+		RSA_get0_crt_params(rsa_ctx, (const BIGNUM**)(&bn_dmp1), (const BIGNUM**)(&bn_dmq1), (const BIGNUM**)(&bn_iqmp));
+
+		//copy the generated key to input pointers
+		//
+		if (!BN_bn2lebinpad(bn_n, p_n, BN_num_bytes(bn_n)) ||
+			!BN_bn2lebinpad(bn_d, p_d, BN_num_bytes(bn_d)) ||
+			!BN_bn2lebinpad(bn_e, p_e, BN_num_bytes(bn_e)) ||
+			!BN_bn2lebinpad(bn_p, p_p, BN_num_bytes(bn_p)) ||
+			!BN_bn2lebinpad(bn_q, p_q, BN_num_bytes(bn_q)) ||
+			!BN_bn2lebinpad(bn_dmp1, p_dmp1, BN_num_bytes(bn_dmp1)) ||
+			!BN_bn2lebinpad(bn_dmq1, p_dmq1, BN_num_bytes(bn_dmq1)) ||
+			!BN_bn2lebinpad(bn_iqmp, p_iqmp, BN_num_bytes(bn_iqmp))) {
+			break;
+		}
+
+		ret_code = SGX_SUCCESS;
+	} while (0);
+
+	//free rsa ctx (RSA_free also free related BNs obtained in RSA_get functions)
+	//
+	RSA_free(rsa_ctx);
+	BN_clear_free(tmp_bn_e);
+
+	return ret_code;
+}
+
+sgx_status_t sgx_create_rsa_priv2_key(int prime_size, int exp_size, const unsigned char *g_rsa_key_e, const unsigned char *g_rsa_key_p, const unsigned char *g_rsa_key_q,
+	const unsigned char *g_rsa_key_dmp1, const unsigned char *g_rsa_key_dmq1, const unsigned char *g_rsa_key_iqmp,
+	void **new_pri_key2)
+{
+	if (prime_size <= 0 || exp_size <= 0 || new_pri_key2 == NULL ||
+		g_rsa_key_e == NULL || g_rsa_key_p == NULL || g_rsa_key_q == NULL || g_rsa_key_dmp1 == NULL ||
+		g_rsa_key_dmq1 == NULL || g_rsa_key_iqmp == NULL) {
+		return SGX_ERROR_INVALID_PARAMETER;
+	}
+
+	bool rsa_memory_manager = 0;
+	EVP_PKEY *rsa_key = NULL;
+	RSA *rsa_ctx = NULL;
+	sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+	BIGNUM* n = NULL;
+	BIGNUM* e = NULL;
+	BIGNUM* d = NULL;
+	BIGNUM* dmp1 = NULL;
+	BIGNUM* dmq1 = NULL;
+	BIGNUM* iqmp = NULL;
+	BIGNUM* q = NULL;
+	BIGNUM* p = NULL;
+	BN_CTX* tmp_ctx = NULL;
+
+	do {
+		tmp_ctx = BN_CTX_new();
+		NULL_BREAK(tmp_ctx);
+		n = BN_new();
+		NULL_BREAK(n);
+
+		// convert RSA params, factors to BNs
+		//
+		p = BN_lebin2bn(g_rsa_key_p, (prime_size / 2), p);
+		BN_CHECK_BREAK(p);
+		q = BN_lebin2bn(g_rsa_key_q, (prime_size / 2), q);
+		BN_CHECK_BREAK(q);
+		dmp1 = BN_lebin2bn(g_rsa_key_dmp1, (prime_size / 2), dmp1);
+		BN_CHECK_BREAK(dmp1);
+		dmq1 = BN_lebin2bn(g_rsa_key_dmq1, (prime_size / 2), dmq1);
+		BN_CHECK_BREAK(dmq1);
+		iqmp = BN_lebin2bn(g_rsa_key_iqmp, (prime_size / 2), iqmp);
+		BN_CHECK_BREAK(iqmp);
+		e = BN_lebin2bn(g_rsa_key_e, (exp_size), e);
+		BN_CHECK_BREAK(e);
+
+		// calculate n value
+		//
+		if (!BN_mul(n, p, q, tmp_ctx)) {
+			break;
+		}
+
+		//calculate d value
+		//ϕ(n)=(p−1)(q−1)
+		//d=(e^−1) mod ϕ(n)
+		//
+		d = BN_dup(n);
+		NULL_BREAK(d);
+		if (!BN_sub(d, d, p) || !BN_sub(d, d, q) || !BN_add_word(d, 1) || !BN_mod_inverse(d, e, d, tmp_ctx)) {
+			break;
+		}
+
+		// allocates and initializes an RSA key structure
+		//
+		rsa_ctx = RSA_new();
+		rsa_key = EVP_PKEY_new();
+
+		if (rsa_ctx == NULL || rsa_key == NULL || !EVP_PKEY_assign_RSA(rsa_key, rsa_ctx)) {
+			RSA_free(rsa_ctx);
+			rsa_key = NULL;
+			break;
+		}
+
+		//setup RSA key with input values
+		//Calling set functions transfers the memory management of the values to the RSA object,
+		//and therefore the values that have been passed in should not be freed by the caller after these functions has been called.
+		//
+		if (!RSA_set0_factors(rsa_ctx, p, q)) {
+			break;
+		}
+		rsa_memory_manager = 1;
+		if (!RSA_set0_crt_params(rsa_ctx, dmp1, dmq1, iqmp)) {
+			BN_clear_free(n);
+			BN_clear_free(e);
+			BN_clear_free(d);
+			BN_clear_free(dmp1);
+			BN_clear_free(dmq1);
+			BN_clear_free(iqmp);
+			break;
+		}
+
+		if (!RSA_set0_key(rsa_ctx, n, e, d)) {
+			BN_clear_free(n);
+			BN_clear_free(e);
+			BN_clear_free(d);
+			break;
+		}
+
+		*new_pri_key2 = rsa_key;
+		ret_code = SGX_SUCCESS;
+	} while (0);
+
+	BN_CTX_free(tmp_ctx);
+
+	//in case of failure, free allocated BNs and RSA struct
+	//
+	if (ret_code != SGX_SUCCESS) {
+		//BNs were not assigned to rsa ctx yet, user code must free allocated BNs
+		//
+		if (!rsa_memory_manager) {
+			BN_clear_free(n);
+			BN_clear_free(e);
+			BN_clear_free(d);
+			BN_clear_free(dmp1);
+			BN_clear_free(dmq1);
+			BN_clear_free(iqmp);
+			BN_clear_free(q);
+			BN_clear_free(p);
+		}
+		EVP_PKEY_free(rsa_key);
+	}
+
+	return ret_code;
+}
+
+sgx_status_t sgx_create_rsa_pub1_key(int prime_size, int exp_size, const unsigned char *le_n, const unsigned char *le_e, void **new_pub_key1)
+{
+	if (new_pub_key1 == NULL || prime_size <= 0 || exp_size <= 0 || le_n == NULL || le_e == NULL) {
+		return SGX_ERROR_INVALID_PARAMETER;
+	}
+
+	EVP_PKEY *rsa_key = NULL;
+	RSA *rsa_ctx = NULL;
+	sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+	BIGNUM* n = NULL;
+	BIGNUM* e = NULL;
+
+	do {
+		//convert input buffers to BNs
+		//
+		n = BN_lebin2bn(le_n, prime_size, n);
+		BN_CHECK_BREAK(n);
+		e = BN_lebin2bn(le_e, exp_size, e);
+		BN_CHECK_BREAK(e);
+
+		// allocates and initializes an RSA key structure
+		//
+		rsa_ctx = RSA_new();
+		rsa_key = EVP_PKEY_new();
+
+		if (rsa_ctx == NULL || rsa_key == NULL || !EVP_PKEY_assign_RSA(rsa_key, rsa_ctx)) {
+			RSA_free(rsa_ctx);
+			rsa_ctx = NULL;
+			break;
+		}
+
+		//set n, e values of RSA key
+		//Calling set functions transfers the memory management of input BNs to the RSA object,
+		//and therefore the values that have been passed in should not be freed by the caller after these functions has been called.
+		//
+		if (!RSA_set0_key(rsa_ctx, n, e, NULL)) {
+			break;
+		}
+		*new_pub_key1 = rsa_key;
+		ret_code = SGX_SUCCESS;
+	} while (0);
+
+	if (ret_code != SGX_SUCCESS) {
+		EVP_PKEY_free(rsa_key);
+		BN_clear_free(n);
+		BN_clear_free(e);
+	}
+
+	return ret_code;
+}
+
+sgx_status_t sgx_rsa_pub_encrypt_sha256(void* rsa_key, unsigned char* pout_data, size_t* pout_len, const unsigned char* pin_data,
+	const size_t pin_len) {
+
+	if (rsa_key == NULL || pout_len == NULL || pin_data == NULL || pin_len < 1 || pin_len >= INT_MAX) {
+		return SGX_ERROR_INVALID_PARAMETER;
+	}
+
+	EVP_PKEY_CTX *ctx = NULL;
+	sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+
+	do {
+		//allocate and init PKEY_CTX
+		//
+		ctx = EVP_PKEY_CTX_new((EVP_PKEY*)rsa_key, NULL);
+		if ((ctx == NULL) || (EVP_PKEY_encrypt_init(ctx) < 1)) {
+			break;
+		}
+
+		//set the RSA padding mode, init it to use SHA256
+		//
+		EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING);
+		EVP_PKEY_CTX_set_rsa_oaep_md(ctx, EVP_sha256());
+
+		if (EVP_PKEY_encrypt(ctx, pout_data, pout_len, pin_data, pin_len) <= 0) {
+			break;
+		}
+
+		ret_code = SGX_SUCCESS;
+	} while (0);
+
+	EVP_PKEY_CTX_free(ctx);
+
+	return ret_code;
+}
+
+sgx_status_t sgx_rsa_priv_decrypt_sha256(void* rsa_key, unsigned char* pout_data, size_t* pout_len, const unsigned char* pin_data,
+	const size_t pin_len) {
+
+	if (rsa_key == NULL || pout_len == NULL || pin_data == NULL || pin_len < 1 || pin_len >= INT_MAX) {
+		return SGX_ERROR_INVALID_PARAMETER;
+	}
+
+	EVP_PKEY_CTX *ctx = NULL;
+	sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+
+	do {
+		//allocate and init PKEY_CTX
+		//
+		ctx = EVP_PKEY_CTX_new((EVP_PKEY*)rsa_key, NULL);
+		if ((ctx == NULL) || (EVP_PKEY_decrypt_init(ctx) < 1)) {
+			break;
+		}
+
+		//set the RSA padding mode, init it to use SHA256
+		//
+		EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING);
+		EVP_PKEY_CTX_set_rsa_oaep_md(ctx, EVP_sha256());
+
+		if (EVP_PKEY_decrypt(ctx, pout_data, pout_len, pin_data, pin_len) <= 0) {
+			break;
+		}
+
+		ret_code = SGX_SUCCESS;
+	} while (0);
+
+	EVP_PKEY_CTX_free(ctx);
+
+	return ret_code;
+}
+
+sgx_status_t sgx_create_rsa_priv1_key(int n_byte_size, int e_byte_size, int d_byte_size, const unsigned char *le_n, const unsigned char *le_e,
+	const unsigned char *le_d, void **new_pri_key1)
+{
+	if (n_byte_size <= 0 || e_byte_size <= 0 || d_byte_size <= 0 || new_pri_key1 == NULL ||
+		le_n == NULL || le_e == NULL || le_d == NULL) {
+		return SGX_ERROR_INVALID_PARAMETER;
+	}
+
+	EVP_PKEY *rsa_key = NULL;
+	RSA *rsa_ctx = NULL;
+	sgx_status_t ret_code = SGX_ERROR_UNEXPECTED;
+	BIGNUM* n = NULL;
+	BIGNUM* e = NULL;
+	BIGNUM* d = NULL;
+
+	do {
+		//convert input buffers to BNs
+		//
+		n = BN_lebin2bn(le_n, n_byte_size, n);
+		BN_CHECK_BREAK(n);
+		e = BN_lebin2bn(le_e, e_byte_size, e);
+		BN_CHECK_BREAK(e);
+		d = BN_lebin2bn(le_d, d_byte_size, d);
+		BN_CHECK_BREAK(d);
+
+		// allocates and initializes an RSA key structure
+		//
+		rsa_ctx = RSA_new();
+		rsa_key = EVP_PKEY_new();
+
+		if (rsa_ctx == NULL || rsa_key == NULL || !EVP_PKEY_assign_RSA(rsa_key, rsa_ctx)) {
+			RSA_free(rsa_ctx);
+			rsa_ctx = NULL;
+			break;
+		}
+
+		//set n, e values of RSA key
+		//Calling set functions transfers the memory management of input BNs to the RSA object,
+		//and therefore the values that have been passed in should not be freed by the caller after these functions has been called.
+		//
+		if (!RSA_set0_key(rsa_ctx, n, e, d)) {
+			break;
+		}
+
+		*new_pri_key1 = rsa_key;
+		ret_code = SGX_SUCCESS;
+	} while (0);
+
+	if (ret_code != SGX_SUCCESS) {
+		EVP_PKEY_free(rsa_key);
+		BN_clear_free(n);
+		BN_clear_free(e);
+		BN_clear_free(d);
+	}
+
+	return ret_code;
+}
+
+sgx_status_t sgx_free_rsa_key(void *p_rsa_key, sgx_rsa_key_type_t key_type, int mod_size, int exp_size) {
+	(void)(key_type);
+	(void)(mod_size);
+	(void)(exp_size);
+	if (p_rsa_key != NULL) {
+		EVP_PKEY_free((EVP_PKEY*)p_rsa_key);
+	}
+	return SGX_SUCCESS;
+}