123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513 |
- /*
- * 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 "pcphash.h"
- #include "pcptool.h"
- /*F*
- // Name: ippsHashGetSize
- //
- // Purpose: Returns size (bytes) of IppsHashState state.
- //
- // Returns: Reason:
- // ippStsNullPtrErr pSize == NULL
- // ippStsNoErr no errors
- //
- // Parameters:
- // pSize pointer to state size
- //
- *F*/
- IPPFUN(IppStatus, ippsHashGetSize,(int* pSize))
- {
- /* test pointers */
- IPP_BAD_PTR1_RET(pSize);
- *pSize = sizeof(IppsHashState);
- return ippStsNoErr;
- }
- /*F*
- // Name: ippsHashInit
- //
- // Purpose: Init Hash state.
- //
- // Returns: Reason:
- // ippStsNullPtrErr pState == NULL
- // ippStsNotSupportedModeErr if algID is not match to supported hash alg
- // ippStsNoErr no errors
- //
- // Parameters:
- // pCtx pointer to the Hash state
- // algID hash alg ID
- //
- *F*/
- int cpReInitHash(IppsHashState* pCtx, IppHashAlgId algID)
- {
- int hashIvSize = cpHashIvSize(algID);
- const Ipp8u* iv = cpHashIV[algID];
- HASH_LENLO(pCtx) = CONST_64(0);
- HASH_LENHI(pCtx) = CONST_64(0);
- HAHS_BUFFIDX(pCtx) = 0;
- CopyBlock(iv, HASH_VALUE(pCtx), hashIvSize);
- return hashIvSize;
- }
- /*
- // hash alg default processing functions and opt argument
- */
- static cpHashProc cpHashProcFunc[] = {
- (cpHashProc)NULL,
- UpdateSHA1,
- UpdateSHA256,
- UpdateSHA256,
- UpdateSHA512,
- UpdateSHA512,
- UpdateMD5,
- UpdateSHA512,
- UpdateSHA512,
- };
- int cpInitHash(IppsHashState* pCtx, IppHashAlgId algID)
- {
- /* setup default processing function */
- HASH_FUNC(pCtx) = cpHashProcFunc[algID];
- /* setup optional agr of processing function */
- HASH_FUNC_PAR(pCtx) = cpHashProcFuncOpt[algID];
- return cpReInitHash(pCtx, algID);
- }
- IPPFUN(IppStatus, ippsHashInit,(IppsHashState* pCtx, IppHashAlgId algID))
- {
- /* get algorithm id */
- algID = cpValidHashAlg(algID);
- /* test hash alg */
- IPP_BADARG_RET(ippHashAlg_Unknown==algID, ippStsNotSupportedModeErr);
- /* test ctx pointer */
- IPP_BAD_PTR1_RET(pCtx);
- /* test hash alg */
- /* set ctx ID */
- HASH_CTX_ID(pCtx) = idCtxHash;
- HASH_ALG_ID(pCtx) = algID;
- /* init context */
- cpInitHash(pCtx, algID);
- return ippStsNoErr;
- }
- /*F*
- // Name: ippsHashUpdate
- //
- // Purpose: Updates intermediate hash value based on input stream.
- //
- // Returns: Reason:
- // ippStsNullPtrErr pCtx == NULL
- // ippStsNullPtrErr pSrc==0 but len!=0
- // ippStsContextMatchErr pCtx->idCtx != idCtxHash
- // ippStsLengthErr len <0
- // ippStsNoErr no errors
- //
- // Parameters:
- // pSrc pointer to the input stream
- // len input stream length
- // pCtx pointer to the Hash context
- //
- *F*/
- __INLINE int IsExceedMsgLen(Ipp64u maxLo, Ipp64u maxHi, Ipp64u lenLo, Ipp64u lenHi)
- {
- int isExceed = lenLo > maxLo;
- isExceed = (lenHi+isExceed) > maxHi;
- return isExceed;
- }
- IPPFUN(IppStatus, ippsHashUpdate,(const Ipp8u* pSrc, int len, IppsHashState* pCtx))
- {
- /* test state pointer and ID */
- IPP_BAD_PTR1_RET(pCtx);
- /* test the context */
- IPP_BADARG_RET(!HASH_VALID_ID(pCtx), ippStsContextMatchErr);
- /* test input length */
- IPP_BADARG_RET((len<0 && pSrc), ippStsLengthErr);
- /* test source pointer */
- IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr);
- /* handle non empty input */
- if(len) {
- const cpHashAttr* pAttr = &cpHashAlgAttr[HASH_ALG_ID(pCtx)];
- /* test if size of message is being processed not exceeded yet */
- Ipp64u lenLo = HASH_LENLO(pCtx);
- Ipp64u lenHi = HASH_LENHI(pCtx);
- lenLo += len;
- if(lenLo < HASH_LENLO(pCtx)) lenHi++;
- if(IsExceedMsgLen(pAttr->msgLenMax[0],pAttr->msgLenMax[1], lenLo,lenHi))
- IPP_ERROR_RET(ippStsLengthErr);
- else {
- cpHashProc hashFunc = HASH_FUNC(pCtx); /* processing function */
- const void* pParam = HASH_FUNC_PAR(pCtx); /* and it's addition params */
- int mbs = pAttr->msgBlkSize; /* data block size */
- /*
- // processing
- */
- {
- int procLen;
- /* test if internal buffer is not empty */
- int n = HAHS_BUFFIDX(pCtx);
- if(n) {
- procLen = IPP_MIN(len, (mbs-n));
- CopyBlock(pSrc, HASH_BUFF(pCtx)+n, procLen);
- HAHS_BUFFIDX(pCtx) = n += procLen;
- /* block processing */
- if(mbs==n) {
- hashFunc(HASH_VALUE(pCtx), HASH_BUFF(pCtx), mbs, pParam);
- HAHS_BUFFIDX(pCtx) = 0;
- }
- /* update message pointer and length */
- pSrc += procLen;
- len -= procLen;
- }
- /* main processing part */
- procLen = len & ~(mbs-1);
- if(procLen) {
- hashFunc(HASH_VALUE(pCtx), pSrc, procLen, pParam);
- pSrc += procLen;
- len -= procLen;
- }
- /* rest of input message */
- if(len) {
- CopyBlock(pSrc, HASH_BUFF(pCtx), len);
- HAHS_BUFFIDX(pCtx) += len;
- }
- }
- /* update length of processed message */
- HASH_LENLO(pCtx) = lenLo;
- HASH_LENHI(pCtx) = lenHi;
- return ippStsNoErr;
- }
- }
- return ippStsNoErr;
- }
- static void cpComputeDigest(Ipp8u* pHashTag, int hashTagLen, const IppsHashState* pCtx)
- {
- /* hash alg and parameters */
- cpHashProc hashFunc = HASH_FUNC(pCtx); /* processing function */
- const void* pParam = HASH_FUNC_PAR(pCtx); /* and it's addition params */
- /* attributes */
- const cpHashAttr* pAttr = &cpHashAlgAttr[HASH_ALG_ID(pCtx)];
- int mbs = pAttr->msgBlkSize; /* data block size */
- int ivSize = pAttr->ivSize; /* size of hash's IV */
- int msgLenRepSize = pAttr->msgLenRepSize; /* length of the message representation */
- /* number of bytes in context buffer */
- int n = HAHS_BUFFIDX(pCtx);
- /* buffer and it actual length */
- Ipp8u buffer[MBS_HASH_MAX*2];
- int bufferLen = n < (mbs-msgLenRepSize)? mbs : mbs*2;
- /* copy current hash value */
- cpHash hash;
- CopyBlock(HASH_VALUE(pCtx), hash, ivSize);
- /* copy of state's buffer */
- CopyBlock(HASH_BUFF(pCtx), buffer, bufferLen);
- /* end of message bit */
- buffer[n++] = 0x80;
- /* padd buffer */
- PaddBlock(0, buffer+n, bufferLen-n-msgLenRepSize);
- /* message length representation in bits (remember about big endian) */
- {
- /* convert processed message length bytes ->bits */
- Ipp64u lo = HASH_LENLO(pCtx);
- Ipp64u hi = HASH_LENHI(pCtx);
- hi = LSL64(hi,3) | LSR64(lo,63-3);
- lo = LSL64(lo,3);
- if(msgLenRepSize>(int)(sizeof(Ipp64u))) {
- #if (IPP_ENDIAN == IPP_BIG_ENDIAN)
- ((Ipp64u*)(buffer+bufferLen))[-2] = hi;
- #else
- ((Ipp64u*)(buffer+bufferLen))[-2] = ENDIANNESS64(hi);
- #endif
- }
- /* recall about MD5 specific */
- if(ippHashAlg_MD5!=HASH_ALG_ID(pCtx)) {
- #if (IPP_ENDIAN == IPP_BIG_ENDIAN)
- ((Ipp64u*)(buffer+bufferLen))[-1] = lo;
- #else
- ((Ipp64u*)(buffer+bufferLen))[-1] = ENDIANNESS64(lo);
- #endif
- }
- else {
- #if (IPP_ENDIAN == IPP_BIG_ENDIAN)
- ((Ipp64u*)(buffer+bufferLen))[-1] = ENDIANNESS64(lo);
- #else
- ((Ipp64u*)(buffer+bufferLen))[-1] = lo;
- #endif
- }
- }
- /* copmplete hash computation */
- hashFunc(hash, buffer, bufferLen, pParam);
- /* store digest into the user buffer (remember digest in big endian) */
- if(msgLenRepSize>(int)(sizeof(Ipp64u))) {
- /* ippHashAlg_SHA384, ippHashAlg_SHA512, ippHashAlg_SHA512_224 and ippHashAlg_SHA512_256 */
- hash[0] = ENDIANNESS64(hash[0]);
- hash[1] = ENDIANNESS64(hash[1]);
- hash[2] = ENDIANNESS64(hash[2]);
- hash[3] = ENDIANNESS64(hash[3]);
- hash[4] = ENDIANNESS64(hash[4]);
- hash[5] = ENDIANNESS64(hash[5]);
- hash[6] = ENDIANNESS64(hash[6]);
- hash[7] = ENDIANNESS64(hash[7]);
- }
- else if(ippHashAlg_MD5!=HASH_ALG_ID(pCtx)) {
- ((Ipp32u*)hash)[0] = ENDIANNESS32(((Ipp32u*)hash)[0]);
- ((Ipp32u*)hash)[1] = ENDIANNESS32(((Ipp32u*)hash)[1]);
- ((Ipp32u*)hash)[2] = ENDIANNESS32(((Ipp32u*)hash)[2]);
- ((Ipp32u*)hash)[3] = ENDIANNESS32(((Ipp32u*)hash)[3]);
- ((Ipp32u*)hash)[4] = ENDIANNESS32(((Ipp32u*)hash)[4]);
- if(ippHashAlg_SHA1!=HASH_ALG_ID(pCtx)) {
- ((Ipp32u*)hash)[5] = ENDIANNESS32(((Ipp32u*)hash)[5]);
- ((Ipp32u*)hash)[6] = ENDIANNESS32(((Ipp32u*)hash)[6]);
- ((Ipp32u*)hash)[7] = ENDIANNESS32(((Ipp32u*)hash)[7]);
- }
- }
- CopyBlock(hash, pHashTag, hashTagLen);
- }
- /*F*
- // Name: ippsHashGetTag
- //
- // Purpose: Compute digest based on current state.
- // Note, that futher digest update is possible
- //
- // Returns: Reason:
- // ippStsNullPtrErr pTag == NULL
- // pCtx == NULL
- // ippStsContextMatchErr pCtx->idCtx != idCtxHash
- // ippStsLengthErr hashSize < tagLen <1
- // ippStsNoErr no errors
- //
- // Parameters:
- // pTag address of the output digest
- // tagLen length of digest
- // pCtx pointer to the SHS state
- //
- *F*/
- IPPFUN(IppStatus, ippsHashGetTag,(Ipp8u* pTag, int tagLen, const IppsHashState* pCtx))
- {
- /* test state pointer and ID */
- IPP_BAD_PTR2_RET(pTag, pCtx);
- /* test the context */
- IPP_BADARG_RET(!HASH_VALID_ID(pCtx), ippStsContextMatchErr);
- {
- /* size of hash */
- int hashSize = cpHashAlgAttr[HASH_ALG_ID(pCtx)].hashSize;
- if(tagLen<1||hashSize<tagLen) IPP_ERROR_RET(ippStsLengthErr);
- cpComputeDigest(pTag, tagLen, pCtx);
- return ippStsNoErr;
- }
- }
- /*F*
- // Name: ippsHashFinal
- //
- // Purpose: Complete message digesting and return digest.
- //
- // Returns: Reason:
- // ippStsNullPtrErr pMD == NULL
- // pCtx == NULL
- // ippStsContextMatchErr pCtx->idCtx != idCtxHash
- // ippStsNoErr no errors
- //
- // Parameters:
- // pMD address of the output digest
- // pCtx pointer to the SHS state
- //
- *F*/
- IPPFUN(IppStatus, ippsHashFinal,(Ipp8u* pMD, IppsHashState* pCtx))
- {
- /* test state pointer and ID */
- IPP_BAD_PTR2_RET(pMD, pCtx);
- /* test the context */
- IPP_BADARG_RET(!HASH_VALID_ID(pCtx), ippStsContextMatchErr);
- {
- IppHashAlgId algID = HASH_ALG_ID(pCtx);
- int hashSize = cpHashAlgAttr[algID].hashSize;
- cpComputeDigest(pMD, hashSize, pCtx);
- cpReInitHash(pCtx, algID);
- return ippStsNoErr;
- }
- }
- /*F*
- // Name: ippsHashMessage
- //
- // Purpose: Hash of the whole message.
- //
- // Returns: Reason:
- // ippStsNullPtrErr pMD == NULL
- // pMsg == NULL but msgLen!=0
- // ippStsLengthErr msgLen <0
- // ippStsNotSupportedModeErr if algID is not match to supported hash alg
- // ippStsNoErr no errors
- //
- // Parameters:
- // pMsg pointer to the input message
- // msgLen input message length
- // pMD address of the output digest
- // algID hash alg ID
- //
- *F*/
- IPPFUN(IppStatus, ippsHashMessage,(const Ipp8u* pMsg, int msgLen, Ipp8u* pMD, IppHashAlgId algID))
- {
- /* get algorithm id */
- algID = cpValidHashAlg(algID);
- /* test hash alg */
- IPP_BADARG_RET(ippHashAlg_Unknown==algID, ippStsNotSupportedModeErr);
- /* test digest pointer */
- IPP_BAD_PTR1_RET(pMD);
- /* test message length */
- IPP_BADARG_RET((msgLen<0), ippStsLengthErr);
- /* test message pointer */
- IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr);
- {
- /* processing function and parameter */
- cpHashProc hashFunc = cpHashProcFunc[algID];
- const void* pParam = cpHashProcFuncOpt[algID];
- /* attributes */
- const cpHashAttr* pAttr = &cpHashAlgAttr[algID];
- int mbs = pAttr->msgBlkSize; /* data block size */
- int ivSize = pAttr->ivSize; /* size of hash's IV */
- int hashSize = pAttr->hashSize; /* hash size */
- int msgLenRepSize = pAttr->msgLenRepSize; /* length of the message representation */
- /* message bitlength representation */
- Ipp64u msgLenBits = (Ipp64u)msgLen*8;
- /* length of main message part */
- int msgLenBlks = msgLen & (-mbs);
- /* rest of message length */
- int msgLenRest = msgLen - msgLenBlks;
- /* end of message buffer */
- Ipp8u buffer[MBS_HASH_MAX*2];
- int bufferLen = (msgLenRest < (mbs-msgLenRepSize))? mbs : mbs*2;
- /* init hash */
- cpHash hash;
- const Ipp8u* iv = cpHashIV[algID];
- CopyBlock(iv, hash, ivSize);
- /*construct last messge block(s) */
- #define MSG_LEN_REP (sizeof(Ipp64u))
- /* copy end of message */
- CopyBlock(pMsg+msgLen-msgLenRest, buffer, msgLenRest);
- /* end of message bit */
- buffer[msgLenRest++] = 0x80;
- /* padd buffer */
- PaddBlock(0, buffer+msgLenRest, bufferLen-msgLenRest-MSG_LEN_REP);
- /* copy message bitlength representation */
- if(ippHashAlg_MD5!=algID)
- msgLenBits = ENDIANNESS64(msgLenBits);
- ((Ipp64u*)(buffer+bufferLen))[-1] = msgLenBits;
- #undef MSG_LEN_REP
- /* message processing */
- if(msgLenBlks)
- hashFunc(hash, pMsg, msgLenBlks, pParam);
- hashFunc(hash, buffer, bufferLen, pParam);
- /* store digest into the user buffer (remember digest in big endian) */
- if(msgLenRepSize > (int)(sizeof(Ipp64u))) {
- /* ippHashAlg_SHA384, ippHashAlg_SHA512, ippHashAlg_SHA512_224 and ippHashAlg_SHA512_256 */
- hash[0] = ENDIANNESS64(hash[0]);
- hash[1] = ENDIANNESS64(hash[1]);
- hash[2] = ENDIANNESS64(hash[2]);
- hash[3] = ENDIANNESS64(hash[3]);
- hash[4] = ENDIANNESS64(hash[4]);
- hash[5] = ENDIANNESS64(hash[5]);
- hash[6] = ENDIANNESS64(hash[6]);
- hash[7] = ENDIANNESS64(hash[7]);
- }
- else if(ippHashAlg_MD5!=algID) {
- /* ippHashAlg_SHA1, ippHashAlg_SHA224, ippHashAlg_SHA256 and ippHashAlg_SM3 */
- ((Ipp32u*)hash)[0] = ENDIANNESS32(((Ipp32u*)hash)[0]);
- ((Ipp32u*)hash)[1] = ENDIANNESS32(((Ipp32u*)hash)[1]);
- ((Ipp32u*)hash)[2] = ENDIANNESS32(((Ipp32u*)hash)[2]);
- ((Ipp32u*)hash)[3] = ENDIANNESS32(((Ipp32u*)hash)[3]);
- ((Ipp32u*)hash)[4] = ENDIANNESS32(((Ipp32u*)hash)[4]);
- ((Ipp32u*)hash)[5] = ENDIANNESS32(((Ipp32u*)hash)[5]);
- ((Ipp32u*)hash)[6] = ENDIANNESS32(((Ipp32u*)hash)[6]);
- ((Ipp32u*)hash)[7] = ENDIANNESS32(((Ipp32u*)hash)[7]);
- }
- CopyBlock(hash, pMD, hashSize);
- return ippStsNoErr;
- }
- }
|