123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437 |
- /*
- * Copyright (C) 2016 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.
- *
- */
- #include "owndefs.h"
- #include "owncp.h"
- #include "pcpbn.h"
- #include "pcpngrsa.h"
- #include "pcpngrsamontstuff.h"
- /*F*
- // Name: ippsRSA_GetBufferSizePublicKey
- //
- // Purpose: Returns size of temporary buffer (in bytes) for public key operation
- //
- // Returns: Reason:
- // ippStsNullPtrErr NULL == pKey
- // NULL == pBufferSize
- //
- // ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID()
- //
- // ippStsIncompleteContextErr no ippsRSA_SetPublicKey() call
- //
- // ippStsNoErr no error
- //
- // Parameters:
- // pBufferSize pointer to size of temporary buffer
- // pKey pointer to the key context
- *F*/
- IPPFUN(IppStatus, ippsRSA_GetBufferSizePublicKey,(int* pBufferSize, const IppsRSAPublicKeyState* pKey))
- {
- IPP_BAD_PTR1_RET(pKey);
- pKey = (IppsRSAPublicKeyState*)( IPP_ALIGNED_PTR(pKey, RSA_PUBLIC_KEY_ALIGNMENT) );
- IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr);
- IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr);
- IPP_BAD_PTR1_RET(pBufferSize);
- {
- cpSize expBitSize = RSA_PUB_KEY_BITSIZE_E(pKey);
- cpSize w = gsMontExp_WinSize(expBitSize);
- cpSize precompLen = (1==w)? 0 : (1<<w);
- cpSize nsM = BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_N(pKey));
- /*
- // scratch structure: length (elements)
- // BN data and BN buffer (RSA-OAEP|PKCS v1.5) (2)
- // pre-computed resource (1<<w or 0, if w=1)
- // copy of base (need if y=x^e is inplace) (1) (w=1)
- // or resource to keep zero-extended power e (1) (w>1)
- // temporary product (2)
- */
- cpSize bufferLen = ((nsM+1)*2)*2
- +precompLen*nsM
- +nsM
- +nsM*2;
- *pBufferSize = bufferLen*sizeof(BNU_CHUNK_T)
- + sizeof(BNU_CHUNK_T)-1
- + (CACHE_LINE_SIZE-1);
- return ippStsNoErr;
- }
- }
- /*F*
- // Name: ippsRSA_GetBufferSizePublicKey
- //
- // Purpose: Returns size of temporary buffer (in bytes) for public key operation
- //
- // Returns: Reason:
- // ippStsNullPtrErr NULL == pKey
- // NULL == pBufferSize
- //
- // ippStsContextMatchErr !RSA_PRV_KEY_VALID_ID()
- //
- // ippStsIncompleteContextErr (type1) private key is not set up
- //
- // ippStsNoErr no error
- //
- // Parameters:
- // pBufferSize pointer to size of temporary buffer
- // pKey pointer to the key context
- *F*/
- IPPFUN(IppStatus, ippsRSA_GetBufferSizePrivateKey,(int* pBufferSize, const IppsRSAPrivateKeyState* pKey))
- {
- IPP_BAD_PTR1_RET(pKey);
- pKey = (IppsRSAPrivateKeyState*)( IPP_ALIGNED_PTR(pKey, RSA_PUBLIC_KEY_ALIGNMENT) );
- IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pKey), ippStsContextMatchErr);
- IPP_BADARG_RET(RSA_PRV_KEY1_VALID_ID(pKey) && !RSA_PRV_KEY_IS_SET(pKey), ippStsIncompleteContextErr);
- IPP_BAD_PTR1_RET(pBufferSize);
- {
- cpSize bufferLen;
- if(RSA_PRV_KEY1_VALID_ID(pKey)) {
- cpSize expBitSize = RSA_PRV_KEY_BITSIZE_D(pKey);
- cpSize w = gsMontExp_WinSize(expBitSize);
- cpSize precompLen = (1==w)? 0 : (1<<w);
- cpSize nsN = BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_N(pKey));
- /*
- // scratch structure: length (elements)
- // BN data and BN buffer (RSA-OAEP|PKCS v1.5) (2)
- // pre-computed resource (1<<w or 0, if w=1)
- // recoure to keep "masked" multipler (x|1) (1), (w=1)
- // copy of base (need if y=x^e is inplace) (1), (w>1)
- // temporary product (2)
- */
- bufferLen = ((nsN+1)*2)*2
- +gsPrecompResourcelen(precompLen,nsN) //+precompLen*nsN
- +nsN
- +nsN
- +nsN*2;
- }
- else {
- cpSize expBitSize = IPP_MAX(RSA_PRV_KEY_BITSIZE_P(pKey), RSA_PRV_KEY_BITSIZE_Q(pKey));
- cpSize w = gsMontExp_WinSize(expBitSize);
- cpSize precompLen = (1==w)? 0 : (1<<w);
- cpSize nsP = BITS_BNU_CHUNK(expBitSize);
- /* for validation/generation purpose */
- cpSize validationBufferLen = 5*(nsP+1);
- cpSize generationBufferLen = 5*(nsP*2+1);
- /*
- // scratch structure: length (elements)
- // BN data and BN buffer (RSA-OAEP|PKCS v1.5) (2)*(~2)
- // pre-computed resource (1<<w or 0, if w=1)
- // copy of base (need if y=x^e is inplace) (1), (w=1)
- // or resource for ScramblePut/Get (1), (w>1)
- // recoure to keep "masked" multipler (x|1) (1), (w=1)
- // or resource to keep zero-extended power e (1), (w>1)
- // temporary product (2)
- */
- bufferLen = ((nsP*2+1)*2)*2
- +gsPrecompResourcelen(precompLen, nsP) //+precompLen*nsP
- +nsP
- +nsP
- +nsP*2;
- bufferLen = IPP_MAX( IPP_MAX(validationBufferLen,generationBufferLen), bufferLen );
- }
- *pBufferSize = bufferLen*sizeof(BNU_CHUNK_T)
- + sizeof(BNU_CHUNK_T)-1
- + (CACHE_LINE_SIZE-1);
- return ippStsNoErr;
- }
- }
- void gsRSApub_cipher(IppsBigNumState* pY,
- const IppsBigNumState* pX,
- const IppsRSAPublicKeyState* pKey,
- BNU_CHUNK_T* pScratchBuffer)
- {
- IppsMontState* pMontN = RSA_PUB_KEY_NMONT(pKey);
- gsMontEnc_BN(pY, pX, pMontN, pScratchBuffer);
- {
- /* optimal size of window */
- BNU_CHUNK_T* pExp = RSA_PUB_KEY_E(pKey);
- cpSize nsExp = BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_E(pKey));
- cpSize w = gsMontExp_WinSize(RSA_PUB_KEY_BITSIZE_E(pKey));
- if(1==w)
- gsMontExpBin_BN(pY, pY, pExp, nsExp, pMontN, pScratchBuffer);
- else
- gsMontExpWin_BN(pY, pY, pExp, nsExp, w, pMontN, pScratchBuffer);
- }
- gsMontDec_BN(pY, pY, pMontN, pScratchBuffer);
- }
- /*F*
- // Name: ippsRSA_Encrypt
- //
- // Purpose: Performs RSA Encryprion
- //
- // Returns: Reason:
- // ippStsNullPtrErr NULL == pKey
- // NULL == pPtxt
- // NULL == pCtxt
- // NULL == pBuffer
- //
- // ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID()
- // !BN_VALID_ID(pPtxt)
- // !BN_VALID_ID(pCtxt)
- //
- // ippStsIncompleteContextErr public key is not setup
- //
- // ippStsOutOfRangeErr pPtxt >= modulus
- // pPtxt <0
- //
- // ippStsSizeErr BN_ROOM(pCtxt) is not enough
- //
- // ippStsNoErr no error
- //
- // Parameters:
- // pPtxt pointer to the plaintext
- // pCtxt pointer to the ciphertext
- // pKey pointer to the key context
- // pScratchBuffer pointer to the temporary buffer
- *F*/
- IPPFUN(IppStatus, ippsRSA_Encrypt,(const IppsBigNumState* pPtxt,
- IppsBigNumState* pCtxt,
- const IppsRSAPublicKeyState* pKey,
- Ipp8u* pScratchBuffer))
- {
- IPP_BAD_PTR2_RET(pKey, pScratchBuffer);
- pKey = (IppsRSAPublicKeyState*)( IPP_ALIGNED_PTR(pKey, RSA_PUBLIC_KEY_ALIGNMENT) );
- IPP_BADARG_RET(!RSA_PUB_KEY_VALID_ID(pKey), ippStsContextMatchErr);
- IPP_BADARG_RET(!RSA_PUB_KEY_IS_SET(pKey), ippStsIncompleteContextErr);
- IPP_BAD_PTR1_RET(pPtxt);
- pPtxt = (IppsBigNumState*)( IPP_ALIGNED_PTR(pPtxt, BN_ALIGNMENT) );
- IPP_BADARG_RET(!BN_VALID_ID(pPtxt), ippStsContextMatchErr);
- IPP_BADARG_RET(BN_NEGATIVE(pPtxt), ippStsOutOfRangeErr);
- IPP_BADARG_RET(0 <= cpCmp_BNU(BN_NUMBER(pPtxt), BN_SIZE(pPtxt),
- MNT_MODULUS(RSA_PUB_KEY_NMONT(pKey)), MNT_SIZE(RSA_PUB_KEY_NMONT(pKey))), ippStsOutOfRangeErr);
- IPP_BAD_PTR1_RET(pCtxt);
- pCtxt = (IppsBigNumState*)( IPP_ALIGNED_PTR(pCtxt, BN_ALIGNMENT) );
- IPP_BADARG_RET(!BN_VALID_ID(pCtxt), ippStsContextMatchErr);
- IPP_BADARG_RET(BN_ROOM(pCtxt) < BITS_BNU_CHUNK(RSA_PUB_KEY_BITSIZE_N(pKey)), ippStsSizeErr);
- gsRSApub_cipher(pCtxt,
- pPtxt,
- pKey,
- (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T))) );
- return ippStsNoErr;
- }
- void gsRSAprv_cipher(IppsBigNumState* pY,
- const IppsBigNumState* pX,
- const IppsRSAPrivateKeyState* pKey,
- BNU_CHUNK_T* pScratchBuffer)
- {
- IppsMontState* pMontN = RSA_PRV_KEY_NMONT(pKey);
- gsMontEnc_BN(pY, pX, pMontN, pScratchBuffer);
- {
- /* optimal size of window */
- BNU_CHUNK_T* pExp = RSA_PRV_KEY_D(pKey);
- cpSize nsExp = BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_D(pKey));
- cpSize w = gsMontExp_WinSize(RSA_PRV_KEY_BITSIZE_D(pKey));
- if(1==w)
- gsMontExpBin_BN_sscm(pY, pY, pExp, nsExp, pMontN, pScratchBuffer);
- else
- gsMontExpWin_BN_sscm(pY, pY, pExp, nsExp, w, pMontN, pScratchBuffer);
- }
- gsMontDec_BN(pY, pY, pMontN, pScratchBuffer);
- }
- void gsRSAprv_cipher_crt(IppsBigNumState* pY,
- const IppsBigNumState* pX,
- const IppsRSAPrivateKeyState* pKey,
- BNU_CHUNK_T* pScratchBuffer)
- {
- /* P- and Q- montgometry engines */
- IppsMontState* pMontP = RSA_PRV_KEY_PMONT(pKey);
- IppsMontState* pMontQ = RSA_PRV_KEY_QMONT(pKey);
- cpSize nsP = MNT_SIZE(pMontP);
- cpSize nsQ = MNT_SIZE(pMontQ);
- const BNU_CHUNK_T* dataX = BN_NUMBER(pX);
- cpSize nsX = BN_SIZE(pX);
- BNU_CHUNK_T* dataXp = BN_NUMBER(pY);
- BNU_CHUNK_T* dataXq = BN_BUFFER(pY);
- cpSize bitSizeDP = BITSIZE_BNU(RSA_PRV_KEY_DP(pKey), nsP);
- cpSize bitSizeDQ = BITSIZE_BNU(RSA_PRV_KEY_DQ(pKey), nsQ);
- cpSize w;
- BNU_CHUNK_T cf;
- /* compute xq = x^dQ mod Q */
- COPY_BNU(dataXq, dataX, nsX);
- cpMod_BNU(dataXq, nsX, MNT_MODULUS(pMontQ), nsQ);
- gsMontEnc_BNU(dataXq, dataXq, nsQ, pMontQ, pScratchBuffer);
- w = gsMontExp_WinSize(bitSizeDQ);
- if(1==w)
- gsMontExpBin_BNU_sscm(dataXq,
- dataXq, nsQ,
- RSA_PRV_KEY_DQ(pKey), BITS_BNU_CHUNK(bitSizeDQ),
- pMontQ, pScratchBuffer);
- else
- gsMontExpWin_BNU_sscm(dataXq,
- dataXq, nsQ,
- RSA_PRV_KEY_DQ(pKey), BITS_BNU_CHUNK(bitSizeDQ), w,
- pMontQ, pScratchBuffer);
- gsMontDec_BNU(dataXq, dataXq, nsQ, pMontQ, pScratchBuffer);
- /* compute xp = x^dP mod P */
- COPY_BNU(dataXp, dataX, nsX);
- cpMod_BNU(dataXp, nsX, MNT_MODULUS(pMontP), nsP);
- gsMontEnc_BNU(dataXp, dataXp, nsP, pMontP, pScratchBuffer);
- w = gsMontExp_WinSize(bitSizeDP);
- if(1==w)
- gsMontExpBin_BNU_sscm(dataXp,
- dataXp, nsP,
- RSA_PRV_KEY_DP(pKey), BITS_BNU_CHUNK(bitSizeDP),
- pMontP, pScratchBuffer);
- else
- gsMontExpWin_BNU_sscm(dataXp,
- dataXp, nsP,
- RSA_PRV_KEY_DP(pKey), BITS_BNU_CHUNK(bitSizeDP), w,
- pMontP, pScratchBuffer);
- gsMontDec_BNU(dataXp, dataXp, nsP, pMontP, pScratchBuffer);
- /* xp -= xq */
- cf = cpSub_BNU(dataXp, dataXp, dataXq, nsQ);
- if(nsP-nsQ)
- cf = cpDec_BNU(dataXp+nsQ, dataXp+nsQ, (nsP-nsQ), cf);
- if(cf)
- cpAdd_BNU(dataXp, dataXp, MNT_MODULUS(pMontP), nsP);
- /* xp = xp*qInv mod P */
- cpMontMul_BNU(dataXp,
- dataXp, nsP,
- RSA_PRV_KEY_INVQ(pKey), nsP,
- MNT_MODULUS(pMontP), nsP, MNT_HELPER(pMontP),
- pScratchBuffer, NULL);
- /* Y = xq + xp*Q */
- cpMul_BNU_school(pScratchBuffer,
- dataXp, nsP,
- MNT_MODULUS(pMontQ), nsQ);
- cf = cpAdd_BNU(BN_NUMBER(pY), pScratchBuffer, dataXq, nsQ);
- cpInc_BNU(BN_NUMBER(pY)+nsQ, pScratchBuffer+nsQ, nsP, cf);
- nsX = nsP+nsQ;
- FIX_BNU(BN_NUMBER(pY), nsX);
- BN_SIZE(pY) = nsX;
- BN_SIGN(pY) = ippBigNumPOS;
- }
- /*F*
- // Name: ippsRSA_Decrypt
- //
- // Purpose: Performs RSA Decryprion
- //
- // Returns: Reason:
- // ippStsNullPtrErr NULL == pKey
- // NULL == pCtxt
- // NULL == pPtxt
- // NULL == pBuffer
- //
- // ippStsContextMatchErr !RSA_PUB_KEY_VALID_ID()
- // !BN_VALID_ID(pCtxt)
- // !BN_VALID_ID(pPtxt)
- //
- // ippStsIncompleteContextErr private key is not set up
- //
- // ippStsOutOfRangeErr pCtxt >= modulus
- // pCtxt <0
- //
- // ippStsSizeErr BN_ROOM(pPtxt) is not enough
- //
- // ippStsNoErr no error
- //
- // Parameters:
- // pCtxt pointer to the ciphertext
- // pPtxt pointer to the plaintext
- // pKey pointer to the key context
- // pScratchBuffer pointer to the temporary buffer
- *F*/
- IPPFUN(IppStatus, ippsRSA_Decrypt,(const IppsBigNumState* pCtxt,
- IppsBigNumState* pPtxt,
- const IppsRSAPrivateKeyState* pKey,
- Ipp8u* pScratchBuffer))
- {
- IPP_BAD_PTR2_RET(pKey, pScratchBuffer);
- pKey = (IppsRSAPrivateKeyState*)( IPP_ALIGNED_PTR(pKey, RSA_PRIVATE_KEY_ALIGNMENT) );
- IPP_BADARG_RET(!RSA_PRV_KEY_VALID_ID(pKey), ippStsContextMatchErr);
- IPP_BADARG_RET(!RSA_PRV_KEY_IS_SET(pKey), ippStsIncompleteContextErr);
- IPP_BAD_PTR1_RET(pCtxt);
- pCtxt = (IppsBigNumState*)( IPP_ALIGNED_PTR(pCtxt, BN_ALIGNMENT) );
- IPP_BADARG_RET(!BN_VALID_ID(pCtxt), ippStsContextMatchErr);
- IPP_BADARG_RET(BN_NEGATIVE(pCtxt), ippStsOutOfRangeErr);
- IPP_BADARG_RET(0 <= cpCmp_BNU(BN_NUMBER(pCtxt), BN_SIZE(pCtxt),
- MNT_MODULUS(RSA_PRV_KEY_NMONT(pKey)), MNT_SIZE(RSA_PRV_KEY_NMONT(pKey))), ippStsOutOfRangeErr);
- IPP_BAD_PTR1_RET(pPtxt);
- pPtxt = (IppsBigNumState*)( IPP_ALIGNED_PTR(pPtxt, BN_ALIGNMENT) );
- IPP_BADARG_RET(!BN_VALID_ID(pPtxt), ippStsContextMatchErr);
- IPP_BADARG_RET(BN_ROOM(pPtxt) < BITS_BNU_CHUNK(RSA_PRV_KEY_BITSIZE_N(pKey)), ippStsSizeErr);
- if(RSA_PRV_KEY1_VALID_ID(pKey))
- gsRSAprv_cipher(pPtxt,
- pCtxt,
- pKey,
- (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T))) );
- else
- gsRSAprv_cipher_crt(pPtxt,
- pCtxt,
- pKey,
- (BNU_CHUNK_T*)(IPP_ALIGNED_PTR((pScratchBuffer), (int)sizeof(BNU_CHUNK_T))) );
- return ippStsNoErr;
- }
|