pcpngrsaencodec.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437
  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 "pcpngrsa.h"
  35. #include "pcpngrsamontstuff.h"
  36. /*F*
  37. // Name: ippsRSA_GetBufferSizePublicKey
  38. //
  39. // Purpose: Returns size of temporary buffer (in bytes) for public key operation
  40. //
  41. // Returns: Reason:
  42. // ippStsNullPtrErr NULL == pKey
  43. // NULL == pBufferSize
  44. //
  45. // ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID()
  46. //
  47. // ippStsIncompleteContextErr no ippsRSA_SetPublicKey() call
  48. //
  49. // ippStsNoErr no error
  50. //
  51. // Parameters:
  52. // pBufferSize pointer to size of temporary buffer
  53. // pKey pointer to the key context
  54. *F*/
  55. IPPFUN(IppStatus, ippsRSA_GetBufferSizePublicKey,(int* pBufferSize, const IppsRSAPublicKeyState* pKey))
  56. {
  57. IPP_BAD_PTR1_RET(pKey);
  58. pKey = (IppsRSAPublicKeyState*)( IPP_ALIGNED_PTR(pKey, RSA_PUBLIC_KEY_ALIGNMENT) );
  59. IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr);
  60. IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr);
  61. IPP_BAD_PTR1_RET(pBufferSize);
  62. {
  63. cpSize expBitSize = RSA_PUB_KEY_BITSIZE_E(pKey);
  64. cpSize w = gsMontExp_WinSize(expBitSize);
  65. cpSize precompLen = (1==w)? 0 : (1<<w);
  66. cpSize nsM = BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_N(pKey));
  67. /*
  68. // scratch structure: length (elements)
  69. // BN data and BN buffer (RSA-OAEP|PKCS v1.5) (2)
  70. // pre-computed resource (1<<w or 0, if w=1)
  71. // copy of base (need if y=x^e is inplace) (1) (w=1)
  72. // or resource to keep zero-extended power e (1) (w>1)
  73. // temporary product (2)
  74. */
  75. cpSize bufferLen = ((nsM+1)*2)*2
  76. +precompLen*nsM
  77. +nsM
  78. +nsM*2;
  79. *pBufferSize = bufferLen*sizeof(BNU_CHUNK_T)
  80. + sizeof(BNU_CHUNK_T)-1
  81. + (CACHE_LINE_SIZE-1);
  82. return ippStsNoErr;
  83. }
  84. }
  85. /*F*
  86. // Name: ippsRSA_GetBufferSizePublicKey
  87. //
  88. // Purpose: Returns size of temporary buffer (in bytes) for public key operation
  89. //
  90. // Returns: Reason:
  91. // ippStsNullPtrErr NULL == pKey
  92. // NULL == pBufferSize
  93. //
  94. // ippStsContextMatchErr !RSA_PRV_KEY_VALID_ID()
  95. //
  96. // ippStsIncompleteContextErr (type1) private key is not set up
  97. //
  98. // ippStsNoErr no error
  99. //
  100. // Parameters:
  101. // pBufferSize pointer to size of temporary buffer
  102. // pKey pointer to the key context
  103. *F*/
  104. IPPFUN(IppStatus, ippsRSA_GetBufferSizePrivateKey,(int* pBufferSize, const IppsRSAPrivateKeyState* pKey))
  105. {
  106. IPP_BAD_PTR1_RET(pKey);
  107. pKey = (IppsRSAPrivateKeyState*)( IPP_ALIGNED_PTR(pKey, RSA_PUBLIC_KEY_ALIGNMENT) );
  108. IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pKey), ippStsContextMatchErr);
  109. IPP_BADARG_RET(RSA_PRV_KEY1_VALID_ID(pKey) && !RSA_PRV_KEY_IS_SET(pKey), ippStsIncompleteContextErr);
  110. IPP_BAD_PTR1_RET(pBufferSize);
  111. {
  112. cpSize bufferLen;
  113. if(RSA_PRV_KEY1_VALID_ID(pKey)) {
  114. cpSize expBitSize = RSA_PRV_KEY_BITSIZE_D(pKey);
  115. cpSize w = gsMontExp_WinSize(expBitSize);
  116. cpSize precompLen = (1==w)? 0 : (1<<w);
  117. cpSize nsN = BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_N(pKey));
  118. /*
  119. // scratch structure: length (elements)
  120. // BN data and BN buffer (RSA-OAEP|PKCS v1.5) (2)
  121. // pre-computed resource (1<<w or 0, if w=1)
  122. // recoure to keep "masked" multipler (x|1) (1), (w=1)
  123. // copy of base (need if y=x^e is inplace) (1), (w>1)
  124. // temporary product (2)
  125. */
  126. bufferLen = ((nsN+1)*2)*2
  127. +gsPrecompResourcelen(precompLen,nsN) //+precompLen*nsN
  128. +nsN
  129. +nsN
  130. +nsN*2;
  131. }
  132. else {
  133. cpSize expBitSize = IPP_MAX(RSA_PRV_KEY_BITSIZE_P(pKey), RSA_PRV_KEY_BITSIZE_Q(pKey));
  134. cpSize w = gsMontExp_WinSize(expBitSize);
  135. cpSize precompLen = (1==w)? 0 : (1<<w);
  136. cpSize nsP = BITS_BNU_CHUNK(expBitSize);
  137. /* for validation/generation purpose */
  138. cpSize validationBufferLen = 5*(nsP+1);
  139. cpSize generationBufferLen = 5*(nsP*2+1);
  140. /*
  141. // scratch structure: length (elements)
  142. // BN data and BN buffer (RSA-OAEP|PKCS v1.5) (2)*(~2)
  143. // pre-computed resource (1<<w or 0, if w=1)
  144. // copy of base (need if y=x^e is inplace) (1), (w=1)
  145. // or resource for ScramblePut/Get (1), (w>1)
  146. // recoure to keep "masked" multipler (x|1) (1), (w=1)
  147. // or resource to keep zero-extended power e (1), (w>1)
  148. // temporary product (2)
  149. */
  150. bufferLen = ((nsP*2+1)*2)*2
  151. +gsPrecompResourcelen(precompLen, nsP) //+precompLen*nsP
  152. +nsP
  153. +nsP
  154. +nsP*2;
  155. bufferLen = IPP_MAX( IPP_MAX(validationBufferLen,generationBufferLen), bufferLen );
  156. }
  157. *pBufferSize = bufferLen*sizeof(BNU_CHUNK_T)
  158. + sizeof(BNU_CHUNK_T)-1
  159. + (CACHE_LINE_SIZE-1);
  160. return ippStsNoErr;
  161. }
  162. }
  163. void gsRSApub_cipher(IppsBigNumState* pY,
  164. const IppsBigNumState* pX,
  165. const IppsRSAPublicKeyState* pKey,
  166. BNU_CHUNK_T* pScratchBuffer)
  167. {
  168. IppsMontState* pMontN = RSA_PUB_KEY_NMONT(pKey);
  169. gsMontEnc_BN(pY, pX, pMontN, pScratchBuffer);
  170. {
  171. /* optimal size of window */
  172. BNU_CHUNK_T* pExp = RSA_PUB_KEY_E(pKey);
  173. cpSize nsExp = BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_E(pKey));
  174. cpSize w = gsMontExp_WinSize(RSA_PUB_KEY_BITSIZE_E(pKey));
  175. if(1==w)
  176. gsMontExpBin_BN(pY, pY, pExp, nsExp, pMontN, pScratchBuffer);
  177. else
  178. gsMontExpWin_BN(pY, pY, pExp, nsExp, w, pMontN, pScratchBuffer);
  179. }
  180. gsMontDec_BN(pY, pY, pMontN, pScratchBuffer);
  181. }
  182. /*F*
  183. // Name: ippsRSA_Encrypt
  184. //
  185. // Purpose: Performs RSA Encryprion
  186. //
  187. // Returns: Reason:
  188. // ippStsNullPtrErr NULL == pKey
  189. // NULL == pPtxt
  190. // NULL == pCtxt
  191. // NULL == pBuffer
  192. //
  193. // ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID()
  194. // !BN_VALID_ID(pPtxt)
  195. // !BN_VALID_ID(pCtxt)
  196. //
  197. // ippStsIncompleteContextErr public key is not setup
  198. //
  199. // ippStsOutOfRangeErr pPtxt >= modulus
  200. // pPtxt <0
  201. //
  202. // ippStsSizeErr BN_ROOM(pCtxt) is not enough
  203. //
  204. // ippStsNoErr no error
  205. //
  206. // Parameters:
  207. // pPtxt pointer to the plaintext
  208. // pCtxt pointer to the ciphertext
  209. // pKey pointer to the key context
  210. // pScratchBuffer pointer to the temporary buffer
  211. *F*/
  212. IPPFUN(IppStatus, ippsRSA_Encrypt,(const IppsBigNumState* pPtxt,
  213. IppsBigNumState* pCtxt,
  214. const IppsRSAPublicKeyState* pKey,
  215. Ipp8u* pScratchBuffer))
  216. {
  217. IPP_BAD_PTR2_RET(pKey, pScratchBuffer);
  218. pKey = (IppsRSAPublicKeyState*)( IPP_ALIGNED_PTR(pKey, RSA_PUBLIC_KEY_ALIGNMENT) );
  219. IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr);
  220. IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr);
  221. IPP_BAD_PTR1_RET(pPtxt);
  222. pPtxt = (IppsBigNumState*)( IPP_ALIGNED_PTR(pPtxt, BN_ALIGNMENT) );
  223. IPP_BADARG_RET(!BN_VALID_ID(pPtxt), ippStsContextMatchErr);
  224. IPP_BADARG_RET(BN_NEGATIVE(pPtxt), ippStsOutOfRangeErr);
  225. IPP_BADARG_RET(0 <= cpCmp_BNU(BN_NUMBER(pPtxt), BN_SIZE(pPtxt),
  226. MNT_MODULUS(RSA_PUB_KEY_NMONT(pKey)), MNT_SIZE(RSA_PUB_KEY_NMONT(pKey))), ippStsOutOfRangeErr);
  227. IPP_BAD_PTR1_RET(pCtxt);
  228. pCtxt = (IppsBigNumState*)( IPP_ALIGNED_PTR(pCtxt, BN_ALIGNMENT) );
  229. IPP_BADARG_RET(!BN_VALID_ID(pCtxt), ippStsContextMatchErr);
  230. IPP_BADARG_RET(BN_ROOM(pCtxt) < BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_N(pKey)), ippStsSizeErr);
  231. gsRSApub_cipher(pCtxt,
  232. pPtxt,
  233. pKey,
  234. (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T))) );
  235. return ippStsNoErr;
  236. }
  237. void gsRSAprv_cipher(IppsBigNumState* pY,
  238. const IppsBigNumState* pX,
  239. const IppsRSAPrivateKeyState* pKey,
  240. BNU_CHUNK_T* pScratchBuffer)
  241. {
  242. IppsMontState* pMontN = RSA_PRV_KEY_NMONT(pKey);
  243. gsMontEnc_BN(pY, pX, pMontN, pScratchBuffer);
  244. {
  245. /* optimal size of window */
  246. BNU_CHUNK_T* pExp = RSA_PRV_KEY_D(pKey);
  247. cpSize nsExp = BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_D(pKey));
  248. cpSize w = gsMontExp_WinSize(RSA_PRV_KEY_BITSIZE_D(pKey));
  249. if(1==w)
  250. gsMontExpBin_BN_sscm(pY, pY, pExp, nsExp, pMontN, pScratchBuffer);
  251. else
  252. gsMontExpWin_BN_sscm(pY, pY, pExp, nsExp, w, pMontN, pScratchBuffer);
  253. }
  254. gsMontDec_BN(pY, pY, pMontN, pScratchBuffer);
  255. }
  256. void gsRSAprv_cipher_crt(IppsBigNumState* pY,
  257. const IppsBigNumState* pX,
  258. const IppsRSAPrivateKeyState* pKey,
  259. BNU_CHUNK_T* pScratchBuffer)
  260. {
  261. /* P- and Q- montgometry engines */
  262. IppsMontState* pMontP = RSA_PRV_KEY_PMONT(pKey);
  263. IppsMontState* pMontQ = RSA_PRV_KEY_QMONT(pKey);
  264. cpSize nsP = MNT_SIZE(pMontP);
  265. cpSize nsQ = MNT_SIZE(pMontQ);
  266. const BNU_CHUNK_T* dataX = BN_NUMBER(pX);
  267. cpSize nsX = BN_SIZE(pX);
  268. BNU_CHUNK_T* dataXp = BN_NUMBER(pY);
  269. BNU_CHUNK_T* dataXq = BN_BUFFER(pY);
  270. cpSize bitSizeDP = BITSIZE_BNU(RSA_PRV_KEY_DP(pKey), nsP);
  271. cpSize bitSizeDQ = BITSIZE_BNU(RSA_PRV_KEY_DQ(pKey), nsQ);
  272. cpSize w;
  273. BNU_CHUNK_T cf;
  274. /* compute xq = x^dQ mod Q */
  275. COPY_BNU(dataXq, dataX, nsX);
  276. cpMod_BNU(dataXq, nsX, MNT_MODULUS(pMontQ), nsQ);
  277. gsMontEnc_BNU(dataXq, dataXq, nsQ, pMontQ, pScratchBuffer);
  278. w = gsMontExp_WinSize(bitSizeDQ);
  279. if(1==w)
  280. gsMontExpBin_BNU_sscm(dataXq,
  281. dataXq, nsQ,
  282. RSA_PRV_KEY_DQ(pKey), BITS_BNU_CHUNK(bitSizeDQ),
  283. pMontQ, pScratchBuffer);
  284. else
  285. gsMontExpWin_BNU_sscm(dataXq,
  286. dataXq, nsQ,
  287. RSA_PRV_KEY_DQ(pKey), BITS_BNU_CHUNK(bitSizeDQ), w,
  288. pMontQ, pScratchBuffer);
  289. gsMontDec_BNU(dataXq, dataXq, nsQ, pMontQ, pScratchBuffer);
  290. /* compute xp = x^dP mod P */
  291. COPY_BNU(dataXp, dataX, nsX);
  292. cpMod_BNU(dataXp, nsX, MNT_MODULUS(pMontP), nsP);
  293. gsMontEnc_BNU(dataXp, dataXp, nsP, pMontP, pScratchBuffer);
  294. w = gsMontExp_WinSize(bitSizeDP);
  295. if(1==w)
  296. gsMontExpBin_BNU_sscm(dataXp,
  297. dataXp, nsP,
  298. RSA_PRV_KEY_DP(pKey), BITS_BNU_CHUNK(bitSizeDP),
  299. pMontP, pScratchBuffer);
  300. else
  301. gsMontExpWin_BNU_sscm(dataXp,
  302. dataXp, nsP,
  303. RSA_PRV_KEY_DP(pKey), BITS_BNU_CHUNK(bitSizeDP), w,
  304. pMontP, pScratchBuffer);
  305. gsMontDec_BNU(dataXp, dataXp, nsP, pMontP, pScratchBuffer);
  306. /* xp -= xq */
  307. cf = cpSub_BNU(dataXp, dataXp, dataXq, nsQ);
  308. if(nsP-nsQ)
  309. cf = cpDec_BNU(dataXp+nsQ, dataXp+nsQ, (nsP-nsQ), cf);
  310. if(cf)
  311. cpAdd_BNU(dataXp, dataXp, MNT_MODULUS(pMontP), nsP);
  312. /* xp = xp*qInv mod P */
  313. cpMontMul_BNU(dataXp,
  314. dataXp, nsP,
  315. RSA_PRV_KEY_INVQ(pKey), nsP,
  316. MNT_MODULUS(pMontP), nsP, MNT_HELPER(pMontP),
  317. pScratchBuffer, NULL);
  318. /* Y = xq + xp*Q */
  319. cpMul_BNU_school(pScratchBuffer,
  320. dataXp, nsP,
  321. MNT_MODULUS(pMontQ), nsQ);
  322. cf = cpAdd_BNU(BN_NUMBER(pY), pScratchBuffer, dataXq, nsQ);
  323. cpInc_BNU(BN_NUMBER(pY)+nsQ, pScratchBuffer+nsQ, nsP, cf);
  324. nsX = nsP+nsQ;
  325. FIX_BNU(BN_NUMBER(pY), nsX);
  326. BN_SIZE(pY) = nsX;
  327. BN_SIGN(pY) = ippBigNumPOS;
  328. }
  329. /*F*
  330. // Name: ippsRSA_Decrypt
  331. //
  332. // Purpose: Performs RSA Decryprion
  333. //
  334. // Returns: Reason:
  335. // ippStsNullPtrErr NULL == pKey
  336. // NULL == pCtxt
  337. // NULL == pPtxt
  338. // NULL == pBuffer
  339. //
  340. // ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID()
  341. // !BN_VALID_ID(pCtxt)
  342. // !BN_VALID_ID(pPtxt)
  343. //
  344. // ippStsIncompleteContextErr private key is not set up
  345. //
  346. // ippStsOutOfRangeErr pCtxt >= modulus
  347. // pCtxt <0
  348. //
  349. // ippStsSizeErr BN_ROOM(pPtxt) is not enough
  350. //
  351. // ippStsNoErr no error
  352. //
  353. // Parameters:
  354. // pCtxt pointer to the ciphertext
  355. // pPtxt pointer to the plaintext
  356. // pKey pointer to the key context
  357. // pScratchBuffer pointer to the temporary buffer
  358. *F*/
  359. IPPFUN(IppStatus, ippsRSA_Decrypt,(const IppsBigNumState* pCtxt,
  360. IppsBigNumState* pPtxt,
  361. const IppsRSAPrivateKeyState* pKey,
  362. Ipp8u* pScratchBuffer))
  363. {
  364. IPP_BAD_PTR2_RET(pKey, pScratchBuffer);
  365. pKey = (IppsRSAPrivateKeyState*)( IPP_ALIGNED_PTR(pKey, RSA_PRIVATE_KEY_ALIGNMENT) );
  366. IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pKey), ippStsContextMatchErr);
  367. IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pKey), ippStsIncompleteContextErr);
  368. IPP_BAD_PTR1_RET(pCtxt);
  369. pCtxt = (IppsBigNumState*)( IPP_ALIGNED_PTR(pCtxt, BN_ALIGNMENT) );
  370. IPP_BADARG_RET(!BN_VALID_ID(pCtxt), ippStsContextMatchErr);
  371. IPP_BADARG_RET(BN_NEGATIVE(pCtxt), ippStsOutOfRangeErr);
  372. IPP_BADARG_RET(0 <= cpCmp_BNU(BN_NUMBER(pCtxt), BN_SIZE(pCtxt),
  373. MNT_MODULUS(RSA_PRV_KEY_NMONT(pKey)), MNT_SIZE(RSA_PRV_KEY_NMONT(pKey))), ippStsOutOfRangeErr);
  374. IPP_BAD_PTR1_RET(pPtxt);
  375. pPtxt = (IppsBigNumState*)( IPP_ALIGNED_PTR(pPtxt, BN_ALIGNMENT) );
  376. IPP_BADARG_RET(!BN_VALID_ID(pPtxt), ippStsContextMatchErr);
  377. IPP_BADARG_RET(BN_ROOM(pPtxt) < BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_N(pKey)), ippStsSizeErr);
  378. if(RSA_PRV_KEY1_VALID_ID(pKey))
  379. gsRSAprv_cipher(pPtxt,
  380. pCtxt,
  381. pKey,
  382. (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T))) );
  383. else
  384. gsRSAprv_cipher_crt(pPtxt,
  385. pCtxt,
  386. pKey,
  387. (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T))) );
  388. return ippStsNoErr;
  389. }