pcpngrsagenerate.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*
  2. * Copyright (C) 2016 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. #include "owndefs.h"
  32. #include "owncp.h"
  33. #include "pcpbn.h"
  34. #include "pcpprimeg.h"
  35. #include "pcpngrsa.h"
  36. #include "pcpngrsamontstuff.h"
  37. /*F*
  38. // Name: ippsRSA_ValidateKeys
  39. //
  40. // Purpose: Validate RSA keys
  41. //
  42. // Returns: Reason:
  43. // ippStsNullPtrErr NULL == pPublicKey
  44. // NULL == pPrivateKeyType2
  45. // NULL == pPrivateKeyType1
  46. // NULL == pBuffer
  47. // NULL == pPrimeGen
  48. // NULL == rndFunc
  49. // NULL == pResult
  50. //
  51. // ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID(pPublicKey)
  52. // !RSA_PRV_KEY2_VALID_ID(pPrivateKeyType2)
  53. // !RSA_PRV_KEY1_VALID_ID(pPrivateKeyType1)
  54. // !PRIME_VALID_ID(pPrimeGen)
  55. //
  56. // ippStsIncompleteContextErr public and.or private key is not set up
  57. //
  58. // ippStsSizeErr PRIME_MAXBITSIZE(pPrimeGen) < factorPbitSize
  59. //
  60. // ippStsBadArgErr nTrials < 1
  61. //
  62. // ippStsNoErr no error
  63. //
  64. // Parameters:
  65. // pResult pointer to the validation result
  66. // pPublicKey pointer to the public key context
  67. // pPrivateKeyType2 pointer to the private key type2 context
  68. // pPrivateKeyType1 (optional) pointer to the private key type1 context
  69. // pBuffer pointer to the temporary buffer
  70. // nTrials parameter of Miller-Rabin Test
  71. // pPrimeGen pointer to the Prime generator context
  72. // rndFunc external PRNG
  73. // pRndParam pointer to the external PRNG parameters
  74. *F*/
  75. /*
  76. // make sure D*E = 1 mod(phi(P,Q))
  77. // where phi(P,Q) = (P-1)*(Q-1)
  78. */
  79. static
  80. int isValidPriv1_classic(const BNU_CHUNK_T* pN, int nsN,
  81. const BNU_CHUNK_T* pE, int nsE,
  82. const BNU_CHUNK_T* pD, int nsD,
  83. const BNU_CHUNK_T* pFactorP, int nsP,
  84. const BNU_CHUNK_T* pFactorQ, int nsQ,
  85. BNU_CHUNK_T* pBuffer)
  86. {
  87. BNU_CHUNK_T* pPhi = pBuffer;
  88. BNU_CHUNK_T* pProduct = pPhi + nsN;
  89. BNU_CHUNK_T c = cpSub_BNU(pPhi, pN, pFactorP, nsP);
  90. int prodLen;
  91. if(nsN>1) cpDec_BNU(pPhi+nsP, pN+nsP, nsQ, c);
  92. c = cpSub_BNU(pPhi,pPhi, pFactorQ, nsQ);
  93. if(nsN>1) cpDec_BNU(pPhi+nsQ, pPhi+nsQ, nsP, c);
  94. cpInc_BNU(pPhi, pPhi, nsP+nsQ, 1);
  95. cpMul_BNU_school(pProduct, pE, nsE, pD, nsD);
  96. prodLen = cpMod_BNU(pProduct, nsE+nsD, pPhi, nsN);
  97. return 1==cpEqu_BNU_CHUNK(pProduct, prodLen, 1)? IPP_IS_VALID : IPP_IS_INVALID;
  98. }
  99. /*
  100. // make sure D*E = 1 mod(lcm(P-1,Q-1))
  101. // where lcm(P-1,Q-1) = (P-1)*(Q-1)/gcd(P-1,Q-1)
  102. */
  103. static
  104. int isValidPriv1_rsa(const BNU_CHUNK_T* pN, int nsN,
  105. const BNU_CHUNK_T* pE, int nsE,
  106. const BNU_CHUNK_T* pD, int nsD,
  107. BNU_CHUNK_T* pFactorP, int nsP,
  108. BNU_CHUNK_T* pFactorQ, int nsQ,
  109. BNU_CHUNK_T* pBuffer)
  110. {
  111. __ALIGN8 IppsBigNumState tmpBN1;
  112. __ALIGN8 IppsBigNumState tmpBN2;
  113. __ALIGN8 IppsBigNumState tmpBN3;
  114. BNU_CHUNK_T* pProduct = pBuffer;
  115. BNU_CHUNK_T* pGcd = pProduct+(nsN+1);
  116. BNU_CHUNK_T* pLcm;
  117. int nsLcm;
  118. int prodLen;
  119. pBuffer = pGcd + (nsP+1)*2;
  120. /* P = P-1 and Q = Q-1 */
  121. pFactorP[0]--;
  122. pFactorQ[0]--;
  123. /* compute product (P-1)*(Q-1) = P*Q -P -Q +1 = N -(P-1) -(Q-1) -1 */
  124. {
  125. BNU_CHUNK_T c = cpSub_BNU(pProduct, pN, pFactorP, nsP);
  126. if(nsN>1) cpDec_BNU(pProduct+nsP, pN+nsP, nsQ, c);
  127. c = cpSub_BNU(pProduct, pProduct, pFactorQ, nsQ);
  128. if(nsN>1) cpDec_BNU(pProduct+nsQ, pProduct+nsQ, nsP, c);
  129. cpDec_BNU(pProduct, pProduct, nsN, 1);
  130. }
  131. /* compute gcd(p-1, q-1) */
  132. BN_Make(pGcd, pGcd+nsP+1, nsP, &tmpBN1); /* BN(gcd) */
  133. BN_SIZE(&tmpBN1) = nsP;
  134. BN_Make(pFactorP, pBuffer, nsP, &tmpBN2); /* BN(P-1) */
  135. BN_SIZE(&tmpBN2) = nsP;
  136. BN_Make(pFactorQ, pBuffer+nsP+1, nsQ, &tmpBN3); /* BN(Q-1) */
  137. BN_SIZE(&tmpBN3) = nsQ;
  138. ippsGcd_BN(&tmpBN2, &tmpBN3, &tmpBN1);
  139. /* compute lcm(p-1, q-1) = (p-1)(q-1)/gcd(p-1, q-1) */
  140. pLcm = pBuffer;
  141. cpDiv_BNU(pLcm, &nsLcm, pProduct, nsN, pGcd, BN_SIZE(&tmpBN1));
  142. /* test E*D = 1 mod lcm */
  143. cpMul_BNU_school(pProduct, pE, nsE, pD, nsD);
  144. prodLen = cpMod_BNU(pProduct, nsE+nsD, pLcm, nsLcm);
  145. /* restore P and Q */
  146. pFactorP[0]++;
  147. pFactorQ[0]++;
  148. return 1==cpEqu_BNU_CHUNK(pProduct, prodLen, 1)? IPP_IS_VALID : IPP_IS_INVALID;
  149. }
  150. IPPFUN(IppStatus, ippsRSA_ValidateKeys,(int* pResult,
  151. const IppsRSAPublicKeyState* pPublicKey,
  152. const IppsRSAPrivateKeyState* pPrivateKeyType2,
  153. const IppsRSAPrivateKeyState* pPrivateKeyType1, /*optional */
  154. Ipp8u* pBuffer,
  155. int nTrials,
  156. IppsPrimeState* pPrimeGen,
  157. IppBitSupplier rndFunc, void* pRndParam))
  158. {
  159. IPP_BAD_PTR1_RET(pPublicKey);
  160. pPublicKey = (IppsRSAPublicKeyState*)( IPP_ALIGNED_PTR(pPublicKey, RSA_PUBLIC_KEY_ALIGNMENT) );
  161. IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pPublicKey), ippStsContextMatchErr);
  162. IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pPublicKey), ippStsIncompleteContextErr);
  163. IPP_BAD_PTR1_RET(pPrivateKeyType2);
  164. pPrivateKeyType2 = (IppsRSAPrivateKeyState*)( IPP_ALIGNED_PTR(pPrivateKeyType2, RSA_PRIVATE_KEY_ALIGNMENT) );
  165. IPP_BADARG_RET(!RSA_PRV_KEY2_VALID_ID(pPrivateKeyType2), ippStsContextMatchErr);
  166. IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pPrivateKeyType2), ippStsIncompleteContextErr);
  167. if(pPrivateKeyType1) { /* pPrivateKeyType1 is optional */
  168. pPrivateKeyType1 = (IppsRSAPrivateKeyState*)( IPP_ALIGNED_PTR(pPrivateKeyType1, RSA_PRIVATE_KEY_ALIGNMENT) );
  169. IPP_BADARG_RET(!RSA_PRV_KEY1_VALID_ID(pPrivateKeyType1), ippStsContextMatchErr);
  170. IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pPrivateKeyType1), ippStsIncompleteContextErr);
  171. }
  172. IPP_BAD_PTR1_RET(pPrimeGen);
  173. pPrimeGen = (IppsPrimeState*)( IPP_ALIGNED_PTR(pPrimeGen, PRIME_ALIGNMENT) );
  174. IPP_BADARG_RET(!PRIME_VALID_ID(pPrimeGen), ippStsContextMatchErr);
  175. IPP_BADARG_RET(PRIME_MAXBITSIZE(pPrimeGen) < RSA_PRV_KEY_BITSIZE_P(pPrivateKeyType2), ippStsSizeErr);
  176. IPP_BAD_PTR3_RET(pResult, pBuffer, rndFunc);
  177. /* test security parameter parameter */
  178. IPP_BADARG_RET((1>nTrials), ippStsBadArgErr);
  179. {
  180. BNU_CHUNK_T* pScratchBuffer = (BNU_CHUNK_T*)(IPP_ALIGNED_PTR(pBuffer, (int)sizeof(BNU_CHUNK_T)));
  181. /* E key component */
  182. BNU_CHUNK_T* pExpE = RSA_PUB_KEY_E(pPublicKey);
  183. cpSize nsE = BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_E(pPublicKey));
  184. /* P, dP, invQ key components */
  185. BNU_CHUNK_T* pFactorP= MNT_MODULUS(RSA_PRV_KEY_PMONT(pPrivateKeyType2));
  186. BNU_CHUNK_T* pExpDp = RSA_PRV_KEY_DP(pPrivateKeyType2);
  187. BNU_CHUNK_T* pInvQ = RSA_PRV_KEY_INVQ(pPrivateKeyType2);
  188. cpSize nsP = MNT_SIZE(RSA_PRV_KEY_PMONT(pPrivateKeyType2));
  189. /* Q, dQ key components */
  190. BNU_CHUNK_T* pFactorQ= MNT_MODULUS(RSA_PRV_KEY_QMONT(pPrivateKeyType2));
  191. BNU_CHUNK_T* pExpDq = RSA_PRV_KEY_DQ(pPrivateKeyType2);
  192. cpSize nsQ = MNT_SIZE(RSA_PRV_KEY_QMONT(pPrivateKeyType2));
  193. /*const*/ BNU_CHUNK_T* pN0 = MNT_MODULUS(RSA_PUB_KEY_NMONT(pPublicKey));
  194. cpSize nsN = MNT_SIZE(RSA_PUB_KEY_NMONT(pPublicKey));
  195. *pResult = IPP_IS_VALID;
  196. /* make sure P is prime */
  197. if(!cpPrimeTest(pFactorP, nsP, nTrials, pPrimeGen, rndFunc, pRndParam)) {
  198. *pResult = IPP_IS_COMPOSITE;
  199. return ippStsNoErr;
  200. }
  201. /* make sure Q is prime */
  202. if(!cpPrimeTest(pFactorQ, nsQ, nTrials, pPrimeGen, rndFunc, pRndParam)) {
  203. *pResult = IPP_IS_COMPOSITE;
  204. return ippStsNoErr;
  205. }
  206. /* make sure PubKey(N)==PrivKeytype2(N) and PubKey(N)==PrivKeytype1(N) */
  207. if(cpCmp_BNU(pN0, nsN,
  208. MNT_MODULUS(RSA_PRV_KEY_NMONT(pPrivateKeyType2)), MNT_SIZE(RSA_PRV_KEY_NMONT(pPrivateKeyType2)))) {
  209. *pResult = IPP_IS_INVALID;
  210. return ippStsNoErr;
  211. }
  212. if(pPrivateKeyType1) {
  213. if(cpCmp_BNU(pN0, nsN,
  214. MNT_MODULUS(RSA_PRV_KEY_NMONT(pPrivateKeyType1)), MNT_SIZE(RSA_PRV_KEY_NMONT(pPrivateKeyType1)))) {
  215. *pResult = IPP_IS_INVALID;
  216. return ippStsNoErr;
  217. }
  218. }
  219. /* make sure 3 <= E < N */
  220. if(1==nsE && pExpE[0]<3) {
  221. *pResult = IPP_IS_INVALID;
  222. return ippStsNoErr;
  223. }
  224. if(0 <= cpCmp_BNU(pExpE, nsE, pN0, nsN)) {
  225. *pResult = IPP_IS_INVALID;
  226. return ippStsNoErr;
  227. }
  228. {
  229. BNU_CHUNK_T* pFactor1 = pScratchBuffer;
  230. BNU_CHUNK_T* pInv = pFactor1 +nsP+1;
  231. BNU_CHUNK_T* pBufInv = pInv +nsP+1;
  232. BNU_CHUNK_T* pBufE = pBufInv +nsP+1;
  233. BNU_CHUNK_T* pBufFact = pBufE +nsP+1;
  234. BNU_CHUNK_T* pProduct = pBufInv;
  235. /* make sure E*dP = 1 mod (P-1) */
  236. cpDec_BNU(pFactor1, pFactorP, nsP, 1);
  237. cpMul_BNU_school(pProduct, pExpDp, nsP, pExpE, nsE);
  238. cpMod_BNU(pProduct, nsP+nsE, pFactor1, nsP);
  239. if(!cpEqu_BNU_CHUNK(pProduct, nsP, 1)) {
  240. *pResult = IPP_IS_INVALID;
  241. return ippStsNoErr;
  242. }
  243. /* make sure 1==GCD(E,P-1) => exist Inv(E,P-1) */
  244. if(!cpModInv_BNU(pInv, pExpE, nsE, pFactor1, nsP, pBufInv, pBufE, pBufFact)) {
  245. *pResult = IPP_IS_INVALID;
  246. return ippStsNoErr;
  247. }
  248. /* make sure E*dQ = 1 mod (Q-1) */
  249. cpDec_BNU(pFactor1, pFactorQ, nsQ, 1);
  250. cpMul_BNU_school(pProduct, pExpDq, nsQ, pExpE, nsE);
  251. cpMod_BNU(pProduct, nsQ+nsE, pFactor1, nsQ);
  252. if(!cpEqu_BNU_CHUNK(pProduct, nsQ, 1)) {
  253. *pResult = IPP_IS_INVALID;
  254. return ippStsNoErr;
  255. }
  256. /* make sure 1==GCD(E,Q-1) => exist Inv(E,Q-1) */
  257. if(!cpModInv_BNU(pInv, pExpE, nsE, pFactor1, nsQ, pBufInv, pBufE, pBufFact)) {
  258. *pResult = IPP_IS_INVALID;
  259. return ippStsNoErr;
  260. }
  261. }
  262. /* make sure Q*Qinv = 1 mod P */
  263. cpMontMul_BNU(pScratchBuffer,
  264. pFactorQ, nsQ,
  265. pInvQ, nsP,
  266. pFactorP, nsP, MNT_HELPER(RSA_PRV_KEY_PMONT(pPrivateKeyType2)),
  267. pScratchBuffer+nsP, NULL);
  268. if(!cpEqu_BNU_CHUNK(pScratchBuffer, nsP, 1)) {
  269. *pResult = IPP_IS_INVALID;
  270. return ippStsNoErr;
  271. }
  272. /* test priva exponent (optiobal) */
  273. if(pPrivateKeyType1) {
  274. const BNU_CHUNK_T* pExpD = RSA_PRV_KEY_D(pPrivateKeyType1);
  275. cpSize nsD = nsN;
  276. int resilt1 = isValidPriv1_classic(pN0,nsN, pExpE,nsE, pExpD,nsD,
  277. pFactorP,nsP, pFactorQ,nsQ,
  278. (BNU_CHUNK_T*)pScratchBuffer);
  279. int resilt2 = isValidPriv1_rsa(pN0,nsN, pExpE,nsE, pExpD,nsD,
  280. pFactorP,nsP, pFactorQ,nsQ,
  281. (BNU_CHUNK_T*)pScratchBuffer);
  282. if(IPP_IS_VALID!=resilt1 && IPP_IS_VALID!=resilt2) {
  283. *pResult = IPP_IS_INVALID;
  284. return ippStsNoErr;
  285. }
  286. }
  287. return ippStsNoErr;
  288. }
  289. }