ipp_rsa_key.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351
  1. /*
  2. * Copyright (C) 2011-2018 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. /**
  32. * File:
  33. * ipp_rsa_key.cpp
  34. *Description:
  35. * Wrapper for rsa key operation functions (public key generation and free excluded)
  36. *
  37. */
  38. #include "ipp_wrapper.h"
  39. #include "util.h"
  40. #include <stdio.h>
  41. #include <stdlib.h>
  42. #include <string.h>
  43. #include <assert.h>
  44. extern "C" int memset_s(void *s, size_t smax, int c, size_t n);
  45. static IppStatus newPRNG(IppsPRNGState **pRandGen)
  46. {
  47. if(pRandGen == NULL)
  48. return ippStsBadArgErr;
  49. int ctxSize = 0;
  50. IppStatus error_code = ippsPRNGGetSize(&ctxSize);
  51. if(error_code != ippStsNoErr)
  52. return error_code;
  53. IppsPRNGState* pCtx = (IppsPRNGState *) malloc(ctxSize);
  54. if(pCtx == NULL)
  55. return ippStsMemAllocErr;
  56. error_code = ippsPRNGInit(160, pCtx);
  57. if(error_code != ippStsNoErr)
  58. {
  59. free(pCtx);
  60. return error_code;
  61. }
  62. *pRandGen = pCtx;
  63. return error_code;
  64. }
  65. static IppStatus newPrimeGen(int nMaxBits, IppsPrimeState ** pPrimeG)
  66. {
  67. if(pPrimeG == NULL || nMaxBits <= 0 )
  68. return ippStsBadArgErr;
  69. int ctxSize = 0;
  70. IppStatus error_code = ippsPrimeGetSize(nMaxBits, &ctxSize);
  71. if(error_code != ippStsNoErr)
  72. return error_code;
  73. IppsPrimeState* pCtx = (IppsPrimeState *) malloc(ctxSize);
  74. if(pCtx == NULL)
  75. return ippStsMemAllocErr;
  76. error_code = ippsPrimeInit(nMaxBits, pCtx);
  77. if(error_code != ippStsNoErr)
  78. {
  79. free(pCtx);
  80. return error_code;
  81. }
  82. *pPrimeG = pCtx;
  83. return error_code;
  84. }
  85. extern "C" IppStatus create_rsa_priv2_key(int p_byte_size, const Ipp32u *p, const Ipp32u *q,
  86. const Ipp32u *dmp1, const Ipp32u *dmq1, const Ipp32u *iqmp,
  87. IppsRSAPrivateKeyState **new_pri_key2)
  88. {
  89. IppsRSAPrivateKeyState *p_rsa2 = NULL;
  90. IppsBigNumState *p_p = NULL, *p_q = NULL, *p_dmp1 = NULL, *p_dmq1 = NULL, *p_iqmp = NULL;
  91. int rsa2_size = 0;
  92. if(p_byte_size <= 0 || p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL || new_pri_key2 == NULL)
  93. {
  94. return ippStsBadArgErr;
  95. }
  96. IppStatus error_code = ippStsNoErr;
  97. do{
  98. error_code = newBN(p, p_byte_size, &p_p);
  99. ERROR_BREAK(error_code);
  100. error_code = newBN(q, p_byte_size, &p_q);
  101. ERROR_BREAK(error_code);
  102. error_code = newBN(dmp1, p_byte_size, &p_dmp1);
  103. ERROR_BREAK(error_code);
  104. error_code = newBN(dmq1, p_byte_size, &p_dmq1);
  105. ERROR_BREAK(error_code);
  106. error_code = newBN(iqmp, p_byte_size, &p_iqmp);
  107. ERROR_BREAK(error_code);
  108. error_code = ippsRSA_GetSizePrivateKeyType2(p_byte_size * 8, p_byte_size * 8, &rsa2_size);
  109. ERROR_BREAK(error_code);
  110. p_rsa2 = (IppsRSAPrivateKeyState *)malloc(rsa2_size);
  111. NULL_BREAK(p_rsa2);
  112. error_code = ippsRSA_InitPrivateKeyType2(p_byte_size * 8, p_byte_size * 8, p_rsa2, rsa2_size);
  113. ERROR_BREAK(error_code);
  114. error_code = ippsRSA_SetPrivateKeyType2(p_p, p_q, p_dmp1, p_dmq1, p_iqmp, p_rsa2);
  115. ERROR_BREAK(error_code);
  116. }while(0);
  117. secure_free_BN(p_p, p_byte_size);
  118. secure_free_BN(p_q, p_byte_size);
  119. secure_free_BN(p_dmp1, p_byte_size);
  120. secure_free_BN(p_dmq1, p_byte_size);
  121. secure_free_BN(p_iqmp, p_byte_size);
  122. if(error_code != ippStsNoErr || p_rsa2 == NULL)
  123. {
  124. if(error_code == ippStsNoErr )
  125. error_code = ippStsMemAllocErr;
  126. /* Clear sensitive data before free */
  127. secure_free_rsa_pri2_key(p_byte_size, p_rsa2);
  128. return error_code;
  129. }
  130. *new_pri_key2 = p_rsa2;
  131. return error_code;
  132. }
  133. 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)
  134. {
  135. IppsRSAPrivateKeyState *p_rsa1 = NULL;
  136. IppsBigNumState *p_n = NULL, *p_d = NULL;
  137. int rsa1_size = 0;
  138. if(n_byte_size <= 0 || d_byte_size <= 0 || n == NULL || d == NULL || new_pri_key1 == NULL)
  139. {
  140. return ippStsBadArgErr;
  141. }
  142. IppStatus error_code = ippStsNoErr;
  143. do{
  144. error_code = newBN(n, n_byte_size, &p_n);
  145. ERROR_BREAK(error_code);
  146. error_code = newBN(d, d_byte_size, &p_d);
  147. ERROR_BREAK(error_code);
  148. error_code = ippsRSA_GetSizePrivateKeyType1(n_byte_size * 8, d_byte_size * 8, &rsa1_size);
  149. ERROR_BREAK(error_code);
  150. p_rsa1 = (IppsRSAPrivateKeyState *)malloc(rsa1_size);
  151. NULL_BREAK(p_rsa1);
  152. error_code = ippsRSA_InitPrivateKeyType1(n_byte_size * 8, d_byte_size * 8, p_rsa1, rsa1_size);
  153. ERROR_BREAK(error_code);
  154. error_code = ippsRSA_SetPrivateKeyType1(p_n, p_d, p_rsa1);
  155. ERROR_BREAK(error_code);
  156. }while(0);
  157. secure_free_BN(p_n, n_byte_size);
  158. secure_free_BN(p_d, d_byte_size);
  159. if(error_code != ippStsNoErr || p_rsa1 == NULL)
  160. {
  161. if(error_code == ippStsNoErr )
  162. error_code = ippStsMemAllocErr;
  163. /* Clear sensitive data before free */
  164. secure_free_rsa_pri1_key(n_byte_size, d_byte_size, p_rsa1);
  165. return error_code;
  166. }
  167. *new_pri_key1 = p_rsa1;
  168. return error_code;
  169. }
  170. 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,
  171. const Ipp32u *dmp1, const Ipp32u *dmq1, const Ipp32u *iqmp,
  172. IppsRSAPrivateKeyState **new_pri_key, IppsRSAPublicKeyState **new_pub_key, int *validate_result)
  173. {
  174. if(n_byte_size <= 0 || e_byte_size <= 0 || n == NULL || d == NULL || e == NULL ||
  175. p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL || new_pri_key == NULL ||
  176. new_pub_key == NULL || validate_result == NULL)
  177. {
  178. return ippStsBadArgErr;
  179. }
  180. IppsRSAPrivateKeyState *p_pri_key1 = NULL, *p_pri_key2 = NULL;
  181. IppsRSAPublicKeyState *p_pub_key = NULL;
  182. IppStatus error_code = ippStsNoErr;
  183. IppsPRNGState *p_rand = NULL;
  184. IppsPrimeState *p_prime = NULL;
  185. Ipp8u * scratch_buffer = NULL;
  186. int result = IPP_IS_VALID;
  187. int max_size = 0, pri1_size = 0, pri2_size = 0, pub_size = 0;
  188. do
  189. {
  190. /* Generate the pri_key1, pri_key2 and pub_key */
  191. error_code = create_rsa_priv1_key(n_byte_size, n_byte_size, n, d, &p_pri_key1);
  192. ERROR_BREAK(error_code);
  193. error_code = create_rsa_priv2_key(n_byte_size/2, p, q, dmp1, dmq1, iqmp, &p_pri_key2);
  194. ERROR_BREAK(error_code);
  195. error_code = create_rsa_pub_key(n_byte_size, e_byte_size, n, e, &p_pub_key);
  196. ERROR_BREAK(error_code);
  197. /* Generate random state and prime state */
  198. error_code = newPRNG(&p_rand);
  199. ERROR_BREAK(error_code);
  200. error_code = newPrimeGen(n_byte_size * 8 / 2, &p_prime);
  201. ERROR_BREAK(error_code);
  202. /* Allocate scratch buffer */
  203. error_code = ippsRSA_GetBufferSizePrivateKey(&pri1_size, p_pri_key1);
  204. ERROR_BREAK(error_code);
  205. error_code = ippsRSA_GetBufferSizePrivateKey(&pri2_size, p_pri_key2);
  206. ERROR_BREAK(error_code);
  207. max_size = MAX(pri1_size, pri2_size);
  208. error_code = ippsRSA_GetBufferSizePublicKey(&pub_size, p_pub_key);
  209. ERROR_BREAK(error_code);
  210. max_size = MAX(max_size, pub_size);
  211. scratch_buffer = (Ipp8u *)malloc(max_size);
  212. NULL_BREAK(scratch_buffer);
  213. memset(scratch_buffer, 0, max_size);
  214. /* Validate keys */
  215. error_code = ippsRSA_ValidateKeys(&result, p_pub_key, p_pri_key2, p_pri_key1, scratch_buffer, 10, p_prime, ippsPRNGen, p_rand);
  216. ERROR_BREAK(error_code);
  217. }while(0);
  218. SAFE_FREE_MM(p_rand);
  219. SAFE_FREE_MM(p_prime);
  220. secure_free_rsa_pri2_key(n_byte_size/2, p_pri_key2);
  221. if(error_code != ippStsNoErr || scratch_buffer == NULL)
  222. {
  223. if(error_code == ippStsNoErr)
  224. error_code = ippStsMemAllocErr;
  225. SAFE_FREE_MM(scratch_buffer);
  226. secure_free_rsa_pri1_key(n_byte_size, n_byte_size, p_pri_key1);
  227. secure_free_rsa_pub_key(n_byte_size, e_byte_size, p_pub_key);
  228. return error_code;
  229. }
  230. SAFE_FREE_MM(scratch_buffer);
  231. *new_pri_key = p_pri_key1;
  232. *new_pub_key = p_pub_key;
  233. *validate_result = result;
  234. return error_code;
  235. }
  236. extern "C" IppStatus get_pub_key(const IppsRSAPublicKeyState *pub_key, int *e_byte_size, Ipp32u *e, int *n_byte_size, Ipp32u *n)
  237. {
  238. IppStatus error_code = ippStsNoErr;
  239. IppsBigNumState *p_n=NULL, *p_e=NULL;
  240. if(!pub_key || !e_byte_size || !e || !n_byte_size || !n)
  241. {
  242. return ippStsBadArgErr;
  243. }
  244. do
  245. {
  246. error_code = newBN(NULL, SE_KEY_SIZE, &p_n);
  247. ERROR_BREAK(error_code);
  248. error_code = newBN(NULL, sizeof(Ipp32u), &p_e);
  249. ERROR_BREAK(error_code);
  250. error_code = ippsRSA_GetPublicKey(p_n, p_e, pub_key);
  251. ERROR_BREAK(error_code);
  252. IppsBigNumSGN sgn = IppsBigNumPOS;
  253. Ipp32u *pdata = NULL;
  254. int length_in_bit = 0;
  255. error_code = ippsRef_BN(&sgn, &length_in_bit, &pdata, p_n);
  256. ERROR_BREAK(error_code);
  257. *n_byte_size = ROUND_TO(length_in_bit, 8)/8;
  258. memset(n, 0, *n_byte_size);
  259. memcpy(n, pdata, ROUND_TO(length_in_bit, 8)/8);
  260. error_code = ippsRef_BN(&sgn, &length_in_bit, &pdata, p_e);
  261. ERROR_BREAK(error_code);
  262. *e_byte_size = ROUND_TO(length_in_bit, 8)/8;
  263. memset(e, 0, *e_byte_size);
  264. memcpy(e, pdata, ROUND_TO(length_in_bit, 8)/8);
  265. } while(0);
  266. secure_free_BN(p_n, SE_KEY_SIZE);
  267. secure_free_BN(p_e, sizeof(Ipp32u));
  268. return error_code;
  269. }
  270. extern "C" void secure_free_rsa_pri1_key(int n_byte_size, int d_byte_size, IppsRSAPrivateKeyState *pri_key1)
  271. {
  272. if(n_byte_size <= 0 || d_byte_size <= 0 || pri_key1 == NULL)
  273. {
  274. if(pri_key1)
  275. free(pri_key1);
  276. return;
  277. }
  278. int rsa1_size = 0;
  279. if(ippsRSA_GetSizePrivateKeyType1(n_byte_size * 8, d_byte_size * 8, &rsa1_size) != ippStsNoErr)
  280. {
  281. free(pri_key1);
  282. return;
  283. }
  284. /* Clear the buffer before free. */
  285. memset_s(pri_key1, rsa1_size, 0, rsa1_size);
  286. free(pri_key1);
  287. return;
  288. }
  289. extern "C" void secure_free_rsa_pri2_key(int p_byte_size, IppsRSAPrivateKeyState *pri_key2)
  290. {
  291. if(p_byte_size <= 0 || pri_key2 == NULL)
  292. {
  293. if(pri_key2)
  294. free(pri_key2);
  295. return;
  296. }
  297. int rsa2_size = 0;
  298. if(ippsRSA_GetSizePrivateKeyType2(p_byte_size * 8, p_byte_size * 8, &rsa2_size) != ippStsNoErr)
  299. {
  300. free(pri_key2);
  301. return;
  302. }
  303. /* Clear the buffer before free. */
  304. memset_s(pri_key2, rsa2_size, 0, rsa2_size);
  305. free(pri_key2);
  306. return;
  307. }