123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- /*
- * Copyright (C) 2011-2017 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:
- * ipp_rsa_key.cpp
- *Description:
- * Wrapper for rsa key operation functions (public key generation and free excluded)
- *
- */
- #include "ipp_wrapper.h"
- #include "util.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- extern "C" int memset_s(void *s, size_t smax, int c, size_t n);
- static 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;
- }
- static 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 create_rsa_priv2_key(int p_byte_size, const Ipp32u *p, const Ipp32u *q,
- const Ipp32u *dmp1, const Ipp32u *dmq1, const Ipp32u *iqmp,
- IppsRSAPrivateKeyState **new_pri_key2)
- {
- IppsRSAPrivateKeyState *p_rsa2 = NULL;
- IppsBigNumState *p_p = NULL, *p_q = NULL, *p_dmp1 = NULL, *p_dmq1 = NULL, *p_iqmp = NULL;
- int rsa2_size = 0;
- if(p_byte_size <= 0 || p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL || new_pri_key2 == NULL)
- {
- return ippStsBadArgErr;
- }
- IppStatus error_code = ippStsNoErr;
- do{
- error_code = newBN(p, p_byte_size, &p_p);
- ERROR_BREAK(error_code);
- error_code = newBN(q, p_byte_size, &p_q);
- ERROR_BREAK(error_code);
- error_code = newBN(dmp1, p_byte_size, &p_dmp1);
- ERROR_BREAK(error_code);
- error_code = newBN(dmq1, p_byte_size, &p_dmq1);
- ERROR_BREAK(error_code);
- error_code = newBN(iqmp, p_byte_size, &p_iqmp);
- ERROR_BREAK(error_code);
- error_code = ippsRSA_GetSizePrivateKeyType2(p_byte_size * 8, p_byte_size * 8, &rsa2_size);
- ERROR_BREAK(error_code);
- p_rsa2 = (IppsRSAPrivateKeyState *)malloc(rsa2_size);
- NULL_BREAK(p_rsa2);
- error_code = ippsRSA_InitPrivateKeyType2(p_byte_size * 8, p_byte_size * 8, p_rsa2, rsa2_size);
- ERROR_BREAK(error_code);
- error_code = ippsRSA_SetPrivateKeyType2(p_p, p_q, p_dmp1, p_dmq1, p_iqmp, p_rsa2);
- ERROR_BREAK(error_code);
- }while(0);
- secure_free_BN(p_p, p_byte_size);
- secure_free_BN(p_q, p_byte_size);
- secure_free_BN(p_dmp1, p_byte_size);
- secure_free_BN(p_dmq1, p_byte_size);
- secure_free_BN(p_iqmp, p_byte_size);
- if(error_code != ippStsNoErr || p_rsa2 == NULL)
- {
- if(error_code == ippStsNoErr )
- error_code = ippStsMemAllocErr;
- /* Clear sensitive data before free */
- secure_free_rsa_pri2_key(p_byte_size, p_rsa2);
- return error_code;
- }
- *new_pri_key2 = p_rsa2;
- return error_code;
- }
- extern "C" IppStatus create_rsa_priv1_key(int n_byte_size, int d_byte_size, const Ipp32u *n, const Ipp32u *d, IppsRSAPrivateKeyState **new_pri_key1)
- {
- IppsRSAPrivateKeyState *p_rsa1 = NULL;
- IppsBigNumState *p_n = NULL, *p_d = NULL;
- int rsa1_size = 0;
- if(n_byte_size <= 0 || d_byte_size <= 0 || n == NULL || d == NULL || new_pri_key1 == NULL)
- {
- return ippStsBadArgErr;
- }
- IppStatus error_code = ippStsNoErr;
- do{
- error_code = newBN(n, n_byte_size, &p_n);
- ERROR_BREAK(error_code);
- error_code = newBN(d, d_byte_size, &p_d);
- ERROR_BREAK(error_code);
- 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);
- error_code = ippsRSA_SetPrivateKeyType1(p_n, p_d, p_rsa1);
- ERROR_BREAK(error_code);
- }while(0);
- secure_free_BN(p_n, n_byte_size);
- secure_free_BN(p_d, d_byte_size);
- if(error_code != ippStsNoErr || p_rsa1 == NULL)
- {
- if(error_code == ippStsNoErr )
- error_code = ippStsMemAllocErr;
- /* Clear sensitive data before free */
- secure_free_rsa_pri1_key(n_byte_size, d_byte_size, p_rsa1);
- return error_code;
- }
- *new_pri_key1 = p_rsa1;
- return error_code;
- }
- extern "C" IppStatus create_validate_rsa_key_pair(int n_byte_size, int e_byte_size, const Ipp32u *n, const Ipp32u *d, const Ipp32u *e, const Ipp32u *p, const Ipp32u *q,
- const Ipp32u *dmp1, const Ipp32u *dmq1, const Ipp32u *iqmp,
- IppsRSAPrivateKeyState **new_pri_key, IppsRSAPublicKeyState **new_pub_key, int *validate_result)
- {
- if(n_byte_size <= 0 || e_byte_size <= 0 || n == NULL || d == NULL || e == NULL ||
- p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL || new_pri_key == NULL ||
- new_pub_key == NULL || validate_result == NULL)
- {
- return ippStsBadArgErr;
- }
- IppsRSAPrivateKeyState *p_pri_key1 = NULL, *p_pri_key2 = NULL;
- IppsRSAPublicKeyState *p_pub_key = NULL;
- IppStatus error_code = ippStsNoErr;
- IppsPRNGState *p_rand = NULL;
- IppsPrimeState *p_prime = NULL;
- Ipp8u * scratch_buffer = NULL;
- int result = IPP_IS_VALID;
- int max_size = 0, pri1_size = 0, pri2_size = 0, pub_size = 0;
- do
- {
- /* Generate the pri_key1, pri_key2 and pub_key */
- error_code = create_rsa_priv1_key(n_byte_size, n_byte_size, n, d, &p_pri_key1);
- ERROR_BREAK(error_code);
- error_code = create_rsa_priv2_key(n_byte_size/2, p, q, dmp1, dmq1, iqmp, &p_pri_key2);
- ERROR_BREAK(error_code);
- error_code = create_rsa_pub_key(n_byte_size, e_byte_size, n, e, &p_pub_key);
- ERROR_BREAK(error_code);
- /* Generate random state and prime state */
- error_code = newPRNG(&p_rand);
- ERROR_BREAK(error_code);
- error_code = newPrimeGen(n_byte_size * 8 / 2, &p_prime);
- ERROR_BREAK(error_code);
- /* Allocate scratch buffer */
- error_code = ippsRSA_GetBufferSizePrivateKey(&pri1_size, p_pri_key1);
- ERROR_BREAK(error_code);
- error_code = ippsRSA_GetBufferSizePrivateKey(&pri2_size, p_pri_key2);
- ERROR_BREAK(error_code);
- max_size = MAX(pri1_size, pri2_size);
- error_code = ippsRSA_GetBufferSizePublicKey(&pub_size, p_pub_key);
- ERROR_BREAK(error_code);
- max_size = MAX(max_size, pub_size);
- scratch_buffer = (Ipp8u *)malloc(max_size);
- NULL_BREAK(scratch_buffer);
- memset(scratch_buffer, 0, max_size);
- /* Validate keys */
- error_code = ippsRSA_ValidateKeys(&result, p_pub_key, p_pri_key2, p_pri_key1, scratch_buffer, 10, p_prime, ippsPRNGen, p_rand);
- ERROR_BREAK(error_code);
- }while(0);
- SAFE_FREE_MM(p_rand);
- SAFE_FREE_MM(p_prime);
- secure_free_rsa_pri2_key(n_byte_size/2, p_pri_key2);
- if(error_code != ippStsNoErr || scratch_buffer == NULL)
- {
- if(error_code == ippStsNoErr)
- error_code = ippStsMemAllocErr;
- SAFE_FREE_MM(scratch_buffer);
- secure_free_rsa_pri1_key(n_byte_size, n_byte_size, p_pri_key1);
- secure_free_rsa_pub_key(n_byte_size, e_byte_size, p_pub_key);
- return error_code;
- }
- SAFE_FREE_MM(scratch_buffer);
- *new_pri_key = p_pri_key1;
- *new_pub_key = p_pub_key;
- *validate_result = result;
- return error_code;
- }
- extern "C" IppStatus get_pub_key(const IppsRSAPublicKeyState *pub_key, int *e_byte_size, Ipp32u *e, int *n_byte_size, Ipp32u *n)
- {
- IppStatus error_code = ippStsNoErr;
- IppsBigNumState *p_n=NULL, *p_e=NULL;
- if(!pub_key || !e_byte_size || !e || !n_byte_size || !n)
- {
- return ippStsBadArgErr;
- }
- do
- {
- error_code = newBN(NULL, SE_KEY_SIZE, &p_n);
- ERROR_BREAK(error_code);
- error_code = newBN(NULL, sizeof(Ipp32u), &p_e);
- ERROR_BREAK(error_code);
- error_code = ippsRSA_GetPublicKey(p_n, p_e, pub_key);
- ERROR_BREAK(error_code);
- IppsBigNumSGN sgn = IppsBigNumPOS;
- Ipp32u *pdata = NULL;
- int length_in_bit = 0;
- error_code = ippsRef_BN(&sgn, &length_in_bit, &pdata, p_n);
- ERROR_BREAK(error_code);
- *n_byte_size = ROUND_TO(length_in_bit, 8)/8;
- memset(n, 0, *n_byte_size);
- memcpy(n, pdata, ROUND_TO(length_in_bit, 8)/8);
- error_code = ippsRef_BN(&sgn, &length_in_bit, &pdata, p_e);
- ERROR_BREAK(error_code);
- *e_byte_size = ROUND_TO(length_in_bit, 8)/8;
- memset(e, 0, *e_byte_size);
- memcpy(e, pdata, ROUND_TO(length_in_bit, 8)/8);
- } while(0);
- secure_free_BN(p_n, SE_KEY_SIZE);
- secure_free_BN(p_e, sizeof(Ipp32u));
- 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 * 8, p_byte_size * 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;
- }
|