945 lines
27 KiB
C
945 lines
27 KiB
C
/*******************************************************************************
|
|
* Copyright 2002-2020 Intel Corporation
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*******************************************************************************/
|
|
|
|
/*
|
|
//
|
|
// Purpose:
|
|
// Cryptography Primitive.
|
|
// Digesting message according to SHA256
|
|
//
|
|
// Contents:
|
|
// ippsSHA256GetSize()
|
|
// ippsSHA256Init()
|
|
// ippsSHA256Pack()
|
|
// ippsSHA256Unpack()
|
|
// ippsSHA256Duplicate()
|
|
// ippsSHA256Update()
|
|
// ippsSHA256GetTag()
|
|
// ippsSHA256Final()
|
|
// ippsSHA256MessageDigest()
|
|
//
|
|
//
|
|
*/
|
|
|
|
#include "owndefs.h"
|
|
#include "owncp.h"
|
|
#include "pcphash.h"
|
|
#include "pcphash_rmf.h"
|
|
#include "pcptool.h"
|
|
|
|
/* SHA-256, SHA-224 constants */
|
|
static const Ipp32u sha256_iv[] = {
|
|
0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
|
|
0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19};
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
static const Ipp32u sha224_iv[] = {
|
|
0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939,
|
|
0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4};
|
|
#endif
|
|
|
|
static __ALIGN16 const Ipp32u sha256_cnt[] = {
|
|
0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
|
|
0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
|
|
0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
|
|
0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
|
|
0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
|
|
0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
|
|
0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
|
|
0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
|
|
0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
|
|
0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
|
|
0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
|
|
0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
|
|
0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
|
|
0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
|
|
0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
|
|
0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2
|
|
};
|
|
|
|
|
|
/* setup init hash value */
|
|
__INLINE void hashInit(Ipp32u* pHash, const Ipp32u* iv)
|
|
{
|
|
pHash[0] = iv[0];
|
|
pHash[1] = iv[1];
|
|
pHash[2] = iv[2];
|
|
pHash[3] = iv[3];
|
|
pHash[4] = iv[4];
|
|
pHash[5] = iv[5];
|
|
pHash[6] = iv[6];
|
|
pHash[7] = iv[7];
|
|
}
|
|
|
|
void sha256_hashInit(void* pHash)
|
|
{
|
|
hashInit((Ipp32u*)pHash, sha256_iv);
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
void sha224_hashInit(void* pHash)
|
|
{
|
|
hashInit((Ipp32u*)pHash, sha224_iv);
|
|
}
|
|
#endif
|
|
|
|
#if defined(_ALG_SHA256_COMPACT_)
|
|
void UpdateSHA256Compact(void* uniHash, const Ipp8u* mblk, int mlen, const void* uniParam)
|
|
{
|
|
#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
|
|
#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
|
|
|
#define SUM0(x) (ROR32((x), 2) ^ ROR32((x),13) ^ ROR32((x),22))
|
|
#define SUM1(x) (ROR32((x), 6) ^ ROR32((x),11) ^ ROR32((x),25))
|
|
|
|
#define SIG0(x) (ROR32((x), 7) ^ ROR32((x),18) ^ LSR32((x), 3))
|
|
#define SIG1(x) (ROR32((x),17) ^ ROR32((x),19) ^ LSR32((x),10))
|
|
|
|
#define COMPACT_SHA256_STEP(A,B,C,D,E,F,G,H, W,K, r) { \
|
|
Ipp32u _T1 = (H) + SUM1((E)) + CH((E),(F),(G)) + (W)[(r)] + (K)[(r)]; \
|
|
Ipp32u _T2 = SUM0((A)) + MAJ((A),(B),(C)); \
|
|
(H) = (G); \
|
|
(G) = (F); \
|
|
(F) = (E); \
|
|
(E) = (D)+_T1; \
|
|
(D) = (C); \
|
|
(C) = (B); \
|
|
(B) = (A); \
|
|
(A) = _T1+_T2; \
|
|
}
|
|
|
|
Ipp32u* data = (Ipp32u*)mblk;
|
|
Ipp32u* digest = (Ipp32u*)uniHash;
|
|
Ipp32u* SHA256_cnt_loc = (Ipp32u*)uniParam;
|
|
|
|
for(; mlen>=MBS_SHA256; data += MBS_SHA256/sizeof(Ipp32u), mlen -= MBS_SHA256) {
|
|
int t;
|
|
|
|
/*
|
|
// expand message block
|
|
*/
|
|
Ipp32u W[64];
|
|
/* initialize the first 16 words in the array W (remember about endian) */
|
|
for(t=0; t<16; t++) {
|
|
#if (IPP_ENDIAN == IPP_BIG_ENDIAN)
|
|
W[t] = data[t];
|
|
#else
|
|
W[t] = ENDIANNESS( data[t] );
|
|
#endif
|
|
}
|
|
for(; t<64; t++)
|
|
W[t] = SIG1(W[t-2]) + W[t-7] + SIG0(W[t-15]) + W[t-16];
|
|
|
|
/*
|
|
// update hash
|
|
*/
|
|
{
|
|
/* init A, B, C, D, E, F, G, H by the input hash */
|
|
Ipp32u A = digest[0];
|
|
Ipp32u B = digest[1];
|
|
Ipp32u C = digest[2];
|
|
Ipp32u D = digest[3];
|
|
Ipp32u E = digest[4];
|
|
Ipp32u F = digest[5];
|
|
Ipp32u G = digest[6];
|
|
Ipp32u H = digest[7];
|
|
|
|
for(t=0; t<64; t++)
|
|
COMPACT_SHA256_STEP(A,B,C,D,E,F,G,H, W,SHA256_cnt_loc, t);
|
|
|
|
/* update hash*/
|
|
digest[0] += A;
|
|
digest[1] += B;
|
|
digest[2] += C;
|
|
digest[3] += D;
|
|
digest[4] += E;
|
|
digest[5] += F;
|
|
digest[6] += G;
|
|
digest[7] += H;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void UpdateSHA256(void* pHash, const Ipp8u* pMsg, int msgLen, const void* pParam)
|
|
{
|
|
#if defined(_SLIMBOOT_OPT)
|
|
#if (FixedPcdGet32 (PcdCryptoShaOptMask) & IPP_CRYPTO_SHA256_NI)
|
|
UpdateSHA256Ni(pHash, pMsg, msgLen, pParam);
|
|
#elif (FixedPcdGet32 (PcdCryptoShaOptMask) & IPP_CRYPTO_SHA256_V8)
|
|
UpdateSHA256V8(pHash, pMsg, msgLen, pParam);
|
|
#else
|
|
UpdateSHA256Compact(pHash, pMsg, msgLen, pParam);
|
|
#endif
|
|
#else
|
|
#if defined(_ALG_SHA256_COMPACT_)
|
|
UpdateSHA256Compact(pHash, pMsg, msgLen, pParam);
|
|
#else
|
|
UpdateSHA256V8(pHash, pMsg, msgLen, pParam);
|
|
#endif
|
|
#endif
|
|
}
|
|
|
|
void sha256_hashUpdate(void* pHash, const Ipp8u* pMsg, int msgLen)
|
|
{
|
|
UpdateSHA256(pHash, pMsg, msgLen, sha256_cnt);
|
|
}
|
|
|
|
#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_)
|
|
void sha256_ni_hashUpdate(void* pHash, const Ipp8u* pMsg, int msgLen)
|
|
{
|
|
UpdateSHA256ni(pHash, pMsg, msgLen, sha256_cnt);
|
|
}
|
|
#endif
|
|
|
|
/* convert hash into big endian */
|
|
void sha256_hashOctString(Ipp8u* pMD, void* pHashVal)
|
|
{
|
|
/* convert hash into big endian */
|
|
((Ipp32u*)pMD)[0] = ENDIANNESS32(((Ipp32u*)pHashVal)[0]);
|
|
((Ipp32u*)pMD)[1] = ENDIANNESS32(((Ipp32u*)pHashVal)[1]);
|
|
((Ipp32u*)pMD)[2] = ENDIANNESS32(((Ipp32u*)pHashVal)[2]);
|
|
((Ipp32u*)pMD)[3] = ENDIANNESS32(((Ipp32u*)pHashVal)[3]);
|
|
((Ipp32u*)pMD)[4] = ENDIANNESS32(((Ipp32u*)pHashVal)[4]);
|
|
((Ipp32u*)pMD)[5] = ENDIANNESS32(((Ipp32u*)pHashVal)[5]);
|
|
((Ipp32u*)pMD)[6] = ENDIANNESS32(((Ipp32u*)pHashVal)[6]);
|
|
((Ipp32u*)pMD)[7] = ENDIANNESS32(((Ipp32u*)pHashVal)[7]);
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
void sha224_hashOctString(Ipp8u* pMD, void* pHashVal)
|
|
{
|
|
/* convert hash into big endian */
|
|
((Ipp32u*)pMD)[0] = ENDIANNESS32(((Ipp32u*)pHashVal)[0]);
|
|
((Ipp32u*)pMD)[1] = ENDIANNESS32(((Ipp32u*)pHashVal)[1]);
|
|
((Ipp32u*)pMD)[2] = ENDIANNESS32(((Ipp32u*)pHashVal)[2]);
|
|
((Ipp32u*)pMD)[3] = ENDIANNESS32(((Ipp32u*)pHashVal)[3]);
|
|
((Ipp32u*)pMD)[4] = ENDIANNESS32(((Ipp32u*)pHashVal)[4]);
|
|
((Ipp32u*)pMD)[5] = ENDIANNESS32(((Ipp32u*)pHashVal)[5]);
|
|
((Ipp32u*)pMD)[6] = ENDIANNESS32(((Ipp32u*)pHashVal)[6]);
|
|
}
|
|
#endif
|
|
|
|
void sha256_msgRep(Ipp8u* pDst, Ipp64u lenLo, Ipp64u lenHi)
|
|
{
|
|
IPP_UNREFERENCED_PARAMETER(lenHi);
|
|
#ifdef _SLIMBOOT_OPT
|
|
lenLo = ENDIANNESS64(LShiftU64 (lenLo, 3));
|
|
#else
|
|
lenLo = ENDIANNESS64(lenLo<<3);
|
|
#endif
|
|
|
|
((Ipp64u*)(pDst))[0] = lenLo;
|
|
}
|
|
|
|
|
|
/*
|
|
// SHA256 init context
|
|
*/
|
|
static IppStatus GetSizeSHA256(int* pSize)
|
|
{
|
|
IPP_BAD_PTR1_RET(pSize);
|
|
*pSize = sizeof(IppsSHA256State) +(SHA256_ALIGNMENT-1);
|
|
return ippStsNoErr;
|
|
}
|
|
|
|
static IppStatus InitSHA256(IppsSHA256State* pState, const DigestSHA256 IV)
|
|
{
|
|
/* test state pointer */
|
|
IPP_BAD_PTR1_RET(pState);
|
|
pState = (IppsSHA256State*)( IPP_ALIGNED_PTR(pState, SHA256_ALIGNMENT) );
|
|
|
|
HASH_CTX_ID(pState) = idCtxSHA256;
|
|
HASH_LENLO(pState) = 0;
|
|
HAHS_BUFFIDX(pState) = 0;
|
|
|
|
/* setup initial digest */
|
|
HASH_VALUE(pState)[0] = IV[0];
|
|
HASH_VALUE(pState)[1] = IV[1];
|
|
HASH_VALUE(pState)[2] = IV[2];
|
|
HASH_VALUE(pState)[3] = IV[3];
|
|
HASH_VALUE(pState)[4] = IV[4];
|
|
HASH_VALUE(pState)[5] = IV[5];
|
|
HASH_VALUE(pState)[6] = IV[6];
|
|
HASH_VALUE(pState)[7] = IV[7];
|
|
|
|
return ippStsNoErr;
|
|
}
|
|
|
|
/*F*
|
|
// Name: ippsSHA256GetSize
|
|
// ippsSHA224GetSize
|
|
//
|
|
// Purpose: Returns size (bytes) of IppsSHA256State state.
|
|
//
|
|
// Returns: Reason:
|
|
// ippStsNullPtrErr pSize == NULL
|
|
// ippStsNoErr no errors
|
|
//
|
|
// Parameters:
|
|
// pSize pointer to state size
|
|
//
|
|
*F*/
|
|
IPPFUN(IppStatus, ippsSHA256GetSize,(int* pSize))
|
|
{
|
|
return GetSizeSHA256(pSize);
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
IPPFUN(IppStatus, ippsSHA224GetSize,(int* pSize))
|
|
{
|
|
return GetSizeSHA256(pSize);
|
|
}
|
|
#endif
|
|
|
|
/*F*
|
|
// Name: ippsSHA256Init
|
|
// ippsSHA224Init
|
|
//
|
|
// Purpose: Init SHA256
|
|
//
|
|
// Returns: Reason:
|
|
// ippStsNullPtrErr pState == NULL
|
|
// ippStsNoErr no errors
|
|
//
|
|
// Parameters:
|
|
// pState pointer to the SHA512 state
|
|
//
|
|
*F*/
|
|
IPPFUN(IppStatus, ippsSHA256Init,(IppsSHA256State* pState))
|
|
{
|
|
return InitSHA256(pState, sha256_iv);
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
IPPFUN(IppStatus, ippsSHA224Init,(IppsSHA224State* pState))
|
|
{
|
|
return InitSHA256(pState, sha224_iv);
|
|
}
|
|
#endif
|
|
|
|
/*F*
|
|
// Name: ippsSHA256Pack
|
|
// ippsSHA224Pack
|
|
//
|
|
// Purpose: Copy initialized context to the buffer.
|
|
//
|
|
// Returns: Reason:
|
|
// ippStsNullPtrErr pSize == NULL
|
|
// pBuffer == NULL
|
|
// ippStsNoErr no errors
|
|
//
|
|
// Parameters:
|
|
// pCtx pointer to the hash state
|
|
// pBuffer pointer to the destination buffer
|
|
//
|
|
*F*/
|
|
IPPFUN(IppStatus, ippsSHA256Pack,(const IppsSHA256State* pCtx, Ipp8u* pBuffer))
|
|
{
|
|
/* test pointers */
|
|
IPP_BAD_PTR2_RET(pCtx, pBuffer);
|
|
pCtx = (IppsSHA256State*)( IPP_ALIGNED_PTR(pCtx, SHA256_ALIGNMENT) );
|
|
IPP_BADARG_RET(idCtxSHA256 !=HASH_CTX_ID(pCtx), ippStsContextMatchErr);
|
|
|
|
CopyBlock(pCtx, pBuffer, sizeof(IppsSHA256State));
|
|
return ippStsNoErr;
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
IPPFUN(IppStatus, ippsSHA224Pack,(const IppsSHA224State* pCtx, Ipp8u* pBuffer))
|
|
{
|
|
return ippsSHA256Pack(pCtx, pBuffer);
|
|
}
|
|
#endif
|
|
|
|
/*F*
|
|
// Name: ippsSHA256Unpack
|
|
// ippsSHA224Unpack
|
|
//
|
|
// Purpose: Unpack buffer content into the initialized context.
|
|
//
|
|
// Returns: Reason:
|
|
// ippStsNullPtrErr pSize == NULL
|
|
// pBuffer == NULL
|
|
// ippStsNoErr no errors
|
|
//
|
|
// Parameters:
|
|
// pBuffer pointer to the input buffer
|
|
// pCtx pointer hash state
|
|
//
|
|
*F*/
|
|
IPPFUN(IppStatus, ippsSHA256Unpack,(const Ipp8u* pBuffer, IppsSHA256State* pCtx))
|
|
{
|
|
/* test pointers */
|
|
IPP_BAD_PTR2_RET(pCtx, pBuffer);
|
|
pCtx = (IppsSHA256State*)( IPP_ALIGNED_PTR(pCtx, SHA256_ALIGNMENT) );
|
|
|
|
CopyBlock(pBuffer, pCtx, sizeof(IppsSHA256State));
|
|
return ippStsNoErr;
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
IPPFUN(IppStatus, ippsSHA224Unpack,(const Ipp8u* pBuffer, IppsSHA224State* pCtx))
|
|
{
|
|
return ippsSHA256Unpack(pBuffer, pCtx);
|
|
}
|
|
#endif
|
|
|
|
/*F*
|
|
// Name: ippsSHA256Duplicate
|
|
// ippsSHA224Duplicate
|
|
//
|
|
// Purpose: Clone SHA256 state.
|
|
//
|
|
// Returns: Reason:
|
|
// ippStsNullPtrErr pSrcState == NULL
|
|
// pDstState == NULL
|
|
// ippStsContextMatchErr pSrcState->idCtx != idCtxSHA256
|
|
// pDstState->idCtx != idCtxSHA256
|
|
// ippStsNoErr no errors
|
|
//
|
|
// Parameters:
|
|
// pSrcState pointer to the source SHA256 state
|
|
// pDstState pointer to the target SHA256 state
|
|
//
|
|
// Note:
|
|
// pDstState may to be uninitialized by ippsSHA256Init()
|
|
//
|
|
*F*/
|
|
IPPFUN(IppStatus, ippsSHA256Duplicate,(const IppsSHA256State* pSrcState, IppsSHA256State* pDstState))
|
|
{
|
|
/* test state pointers */
|
|
IPP_BAD_PTR2_RET(pSrcState, pDstState);
|
|
pSrcState = (IppsSHA256State*)( IPP_ALIGNED_PTR(pSrcState, SHA256_ALIGNMENT) );
|
|
pDstState = (IppsSHA256State*)( IPP_ALIGNED_PTR(pDstState, SHA256_ALIGNMENT) );
|
|
/* test states ID */
|
|
IPP_BADARG_RET(idCtxSHA256 !=HASH_CTX_ID(pSrcState), ippStsContextMatchErr);
|
|
|
|
/* copy state */
|
|
CopyBlock(pSrcState, pDstState, sizeof(IppsSHA256State));
|
|
|
|
return ippStsNoErr;
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
IPPFUN(IppStatus, ippsSHA224Duplicate,(const IppsSHA224State* pSrcState, IppsSHA224State* pDstState))
|
|
{
|
|
return ippsSHA256Duplicate(pSrcState, pDstState);
|
|
}
|
|
#endif
|
|
|
|
/*F*
|
|
// Name: ippsSHA256Update
|
|
// ippsSHA224Update
|
|
//
|
|
// Purpose: Updates intermadiate digest based on input stream.
|
|
//
|
|
// Returns: Reason:
|
|
// ippStsNullPtrErr pSrc == NULL
|
|
// pState == NULL
|
|
// ippStsContextMatchErr pState->idCtx != idCtxSHA256
|
|
// ippStsLengthErr len <0
|
|
// ippStsNoErr no errors
|
|
//
|
|
// Parameters:
|
|
// pSrc pointer to the input stream
|
|
// len input stream length
|
|
// pState pointer to the SHA256 state
|
|
//
|
|
*F*/
|
|
IPPFUN(IppStatus, ippsSHA256Update,(const Ipp8u* pSrc, int len, IppsSHA256State* pState))
|
|
{
|
|
/* test state pointer and ID */
|
|
IPP_BAD_PTR1_RET(pState);
|
|
pState = (IppsSHA256State*)( IPP_ALIGNED_PTR(pState, SHA256_ALIGNMENT) );
|
|
IPP_BADARG_RET(idCtxSHA256 !=HASH_CTX_ID(pState), ippStsContextMatchErr);
|
|
|
|
/* test input length */
|
|
IPP_BADARG_RET((len<0), ippStsLengthErr);
|
|
/* test source pointer */
|
|
IPP_BADARG_RET((len && !pSrc), ippStsNullPtrErr);
|
|
|
|
/*
|
|
// handle non empty message
|
|
*/
|
|
if(len) {
|
|
/* select processing function */
|
|
#if (_SHA_NI_ENABLING_==_FEATURE_ON_)
|
|
cpHashProc updateFunc = UpdateSHA256ni;
|
|
#elif (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_)
|
|
cpHashProc updateFunc = IsFeatureEnabled(SHA_NI_ENABLED)? UpdateSHA256ni : UpdateSHA256;
|
|
#else
|
|
cpHashProc updateFunc = UpdateSHA256;
|
|
#endif
|
|
|
|
int procLen;
|
|
|
|
int idx = HAHS_BUFFIDX(pState);
|
|
Ipp8u* pBuffer = HASH_BUFF(pState);
|
|
Ipp64u lenLo = HASH_LENLO(pState) +len;
|
|
|
|
/* if non empty internal buffer filling */
|
|
if(idx) {
|
|
/* copy from input stream to the internal buffer as match as possible */
|
|
procLen = IPP_MIN(len, (MBS_SHA256-idx));
|
|
CopyBlock(pSrc, pBuffer+idx, procLen);
|
|
|
|
/* update message pointer and length */
|
|
pSrc += procLen;
|
|
len -= procLen;
|
|
idx += procLen;
|
|
|
|
/* update digest if buffer full */
|
|
if( MBS_SHA256 == idx) {
|
|
updateFunc(HASH_VALUE(pState), pBuffer, MBS_SHA256, SHA256_cnt);
|
|
idx = 0;
|
|
}
|
|
}
|
|
|
|
/* main message part processing */
|
|
procLen = len & ~(MBS_SHA256-1);
|
|
if(procLen) {
|
|
updateFunc(HASH_VALUE(pState), pSrc, procLen, sha256_cnt);
|
|
pSrc += procLen;
|
|
len -= procLen;
|
|
}
|
|
|
|
/* store rest of message into the internal buffer */
|
|
if(len) {
|
|
CopyBlock(pSrc, pBuffer, len);
|
|
idx += len;
|
|
}
|
|
|
|
/* update length of processed message */
|
|
HASH_LENLO(pState) = lenLo;
|
|
HAHS_BUFFIDX(pState) = idx;
|
|
}
|
|
|
|
return ippStsNoErr;
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
IPPFUN(IppStatus, ippsSHA224Update,(const Ipp8u* pSrc, int len, IppsSHA224State* pState))
|
|
{
|
|
return ippsSHA256Update(pSrc, len, pState);
|
|
}
|
|
#endif
|
|
|
|
static void cpFinalizeSHA256(DigestSHA256 pHash, const Ipp8u* inpBuffer, int inpLen, Ipp64u processedMsgLen)
|
|
{
|
|
/* select processing function */
|
|
#if (_SHA_NI_ENABLING_==_FEATURE_ON_)
|
|
cpHashProc updateFunc = UpdateSHA256ni;
|
|
#elif (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_)
|
|
cpHashProc updateFunc = IsFeatureEnabled(SHA_NI_ENABLED)? UpdateSHA256ni : UpdateSHA256;
|
|
#else
|
|
cpHashProc updateFunc = UpdateSHA256;
|
|
#endif
|
|
|
|
/* local buffer and it length */
|
|
Ipp8u buffer[MBS_SHA256*2];
|
|
int bufferLen = inpLen < (MBS_SHA256-(int)MLR_SHA256)? MBS_SHA256 : MBS_SHA256*2;
|
|
|
|
/* copy rest of message into internal buffer */
|
|
CopyBlock(inpBuffer, buffer, inpLen);
|
|
|
|
/* padd message */
|
|
buffer[inpLen++] = 0x80;
|
|
PadBlock(0, buffer+inpLen, (cpSize)(bufferLen-inpLen-(int)MLR_SHA256));
|
|
|
|
/* put processed message length in bits */
|
|
#ifdef _SLIMBOOT_OPT
|
|
processedMsgLen = ENDIANNESS64(LShiftU64 (processedMsgLen, 3));
|
|
#else
|
|
processedMsgLen = ENDIANNESS64(processedMsgLen<<3);
|
|
#endif
|
|
((Ipp64u*)(buffer+bufferLen))[-1] = processedMsgLen;
|
|
|
|
/* copmplete hash computation */
|
|
updateFunc(pHash, buffer, bufferLen, sha256_cnt);
|
|
}
|
|
|
|
/*F*
|
|
// Name: ippsSHA256Final
|
|
// ippsSHA224Final
|
|
//
|
|
// Purpose: Stop message digesting and return digest.
|
|
//
|
|
// Returns: Reason:
|
|
// ippStsNullPtrErr pDigest == NULL
|
|
// pState == NULL
|
|
// ippStsContextMatchErr pState->idCtx != idCtxSHA256
|
|
// ippStsNoErr no errors
|
|
//
|
|
// Parameters:
|
|
// pMD address of the output digest
|
|
// pState pointer to the SHA256 state
|
|
//
|
|
*F*/
|
|
IPPFUN(IppStatus, ippsSHA256Final,(Ipp8u* pMD, IppsSHA256State* pState))
|
|
{
|
|
/* test state pointer and ID */
|
|
IPP_BAD_PTR1_RET(pState);
|
|
pState = (IppsSHA256State*)( IPP_ALIGNED_PTR(pState, SHA256_ALIGNMENT) );
|
|
IPP_BADARG_RET(idCtxSHA256 !=HASH_CTX_ID(pState), ippStsContextMatchErr);
|
|
|
|
/* test digest pointer */
|
|
IPP_BAD_PTR1_RET(pMD);
|
|
|
|
cpFinalizeSHA256(HASH_VALUE(pState), HASH_BUFF(pState), HAHS_BUFFIDX(pState), HASH_LENLO(pState));
|
|
/* convert hash into big endian */
|
|
((Ipp32u*)pMD)[0] = ENDIANNESS32(HASH_VALUE(pState)[0]);
|
|
((Ipp32u*)pMD)[1] = ENDIANNESS32(HASH_VALUE(pState)[1]);
|
|
((Ipp32u*)pMD)[2] = ENDIANNESS32(HASH_VALUE(pState)[2]);
|
|
((Ipp32u*)pMD)[3] = ENDIANNESS32(HASH_VALUE(pState)[3]);
|
|
((Ipp32u*)pMD)[4] = ENDIANNESS32(HASH_VALUE(pState)[4]);
|
|
((Ipp32u*)pMD)[5] = ENDIANNESS32(HASH_VALUE(pState)[5]);
|
|
((Ipp32u*)pMD)[6] = ENDIANNESS32(HASH_VALUE(pState)[6]);
|
|
((Ipp32u*)pMD)[7] = ENDIANNESS32(HASH_VALUE(pState)[7]);
|
|
|
|
/* re-init hash value */
|
|
HAHS_BUFFIDX(pState) = 0;
|
|
HASH_LENLO(pState) = 0;
|
|
sha256_hashInit(HASH_VALUE(pState));
|
|
|
|
return ippStsNoErr;
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
IPPFUN(IppStatus, ippsSHA224Final,(Ipp8u* pMD, IppsSHA224State* pState))
|
|
{
|
|
/* test state pointer and ID */
|
|
IPP_BAD_PTR1_RET(pState);
|
|
pState = (IppsSHA256State*)( IPP_ALIGNED_PTR(pState, SHA256_ALIGNMENT) );
|
|
IPP_BADARG_RET(idCtxSHA256 !=HASH_CTX_ID(pState), ippStsContextMatchErr);
|
|
|
|
/* test digest pointer */
|
|
IPP_BAD_PTR1_RET(pMD);
|
|
|
|
cpFinalizeSHA256(HASH_VALUE(pState), HASH_BUFF(pState), HAHS_BUFFIDX(pState), HASH_LENLO(pState));
|
|
/* convert hash into big endian */
|
|
((Ipp32u*)pMD)[0] = ENDIANNESS32(HASH_VALUE(pState)[0]);
|
|
((Ipp32u*)pMD)[1] = ENDIANNESS32(HASH_VALUE(pState)[1]);
|
|
((Ipp32u*)pMD)[2] = ENDIANNESS32(HASH_VALUE(pState)[2]);
|
|
((Ipp32u*)pMD)[3] = ENDIANNESS32(HASH_VALUE(pState)[3]);
|
|
((Ipp32u*)pMD)[4] = ENDIANNESS32(HASH_VALUE(pState)[4]);
|
|
((Ipp32u*)pMD)[5] = ENDIANNESS32(HASH_VALUE(pState)[5]);
|
|
((Ipp32u*)pMD)[6] = ENDIANNESS32(HASH_VALUE(pState)[6]);
|
|
|
|
/* re-init hash value */
|
|
HAHS_BUFFIDX(pState) = 0;
|
|
HASH_LENLO(pState) = 0;
|
|
sha224_hashInit(HASH_VALUE(pState));
|
|
|
|
return ippStsNoErr;
|
|
}
|
|
#endif
|
|
|
|
/*F*
|
|
// Name: ippsSHA256GetTag
|
|
// ippsSHA224GetTag
|
|
//
|
|
// Purpose: Compute digest based on current state.
|
|
// Note, that futher digest update is possible
|
|
//
|
|
// Returns: Reason:
|
|
// ippStsNullPtrErr pTag == NULL
|
|
// pState == NULL
|
|
// ippStsContextMatchErr pState->idCtx != idCtxSHA256
|
|
// ippStsLengthErr max_SHA_digestLen < tagLen <1
|
|
// ippStsNoErr no errors
|
|
//
|
|
// Parameters:
|
|
// pTag address of the output digest
|
|
// tagLen length of digest
|
|
// pState pointer to the SHS state
|
|
//
|
|
*F*/
|
|
IPPFUN(IppStatus, ippsSHA256GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA256State* pState))
|
|
{
|
|
/* test state pointer and ID */
|
|
IPP_BAD_PTR1_RET(pState);
|
|
pState = (IppsSHA256State*)( IPP_ALIGNED_PTR(pState, SHA256_ALIGNMENT) );
|
|
IPP_BADARG_RET(idCtxSHA256 !=HASH_CTX_ID(pState), ippStsContextMatchErr);
|
|
|
|
/* test digest pointer */
|
|
IPP_BAD_PTR1_RET(pTag);
|
|
IPP_BADARG_RET((tagLen<1)||(sizeof(DigestSHA256)<tagLen), ippStsLengthErr);
|
|
|
|
{
|
|
DigestSHA256 digest;
|
|
CopyBlock(HASH_VALUE(pState), digest, sizeof(DigestSHA256));
|
|
cpFinalizeSHA256(digest, HASH_BUFF(pState), HAHS_BUFFIDX(pState), HASH_LENLO(pState));
|
|
digest[0] = ENDIANNESS32(digest[0]);
|
|
digest[1] = ENDIANNESS32(digest[1]);
|
|
digest[2] = ENDIANNESS32(digest[2]);
|
|
digest[3] = ENDIANNESS32(digest[3]);
|
|
digest[4] = ENDIANNESS32(digest[4]);
|
|
digest[5] = ENDIANNESS32(digest[5]);
|
|
digest[6] = ENDIANNESS32(digest[6]);
|
|
digest[7] = ENDIANNESS32(digest[7]);
|
|
CopyBlock(digest, pTag, tagLen);
|
|
|
|
return ippStsNoErr;
|
|
}
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
IPPFUN(IppStatus, ippsSHA224GetTag,(Ipp8u* pTag, Ipp32u tagLen, const IppsSHA224State* pState))
|
|
{
|
|
/* test state pointer and ID */
|
|
IPP_BAD_PTR1_RET(pState);
|
|
pState = (IppsSHA256State*)( IPP_ALIGNED_PTR(pState, SHA256_ALIGNMENT) );
|
|
IPP_BADARG_RET(idCtxSHA256 !=HASH_CTX_ID(pState), ippStsContextMatchErr);
|
|
|
|
/* test digest pointer */
|
|
IPP_BAD_PTR1_RET(pTag);
|
|
IPP_BADARG_RET((tagLen<1)||(sizeof(DigestSHA224)<tagLen), ippStsLengthErr);
|
|
|
|
{
|
|
DigestSHA256 digest;
|
|
CopyBlock(HASH_VALUE(pState), digest, sizeof(DigestSHA256));
|
|
cpFinalizeSHA256(digest, HASH_BUFF(pState), HAHS_BUFFIDX(pState), HASH_LENLO(pState));
|
|
digest[0] = ENDIANNESS32(digest[0]);
|
|
digest[1] = ENDIANNESS32(digest[1]);
|
|
digest[2] = ENDIANNESS32(digest[2]);
|
|
digest[3] = ENDIANNESS32(digest[3]);
|
|
digest[4] = ENDIANNESS32(digest[4]);
|
|
digest[5] = ENDIANNESS32(digest[5]);
|
|
digest[6] = ENDIANNESS32(digest[6]);
|
|
digest[7] = ENDIANNESS32(digest[7]);
|
|
CopyBlock(digest, pTag, tagLen);
|
|
|
|
return ippStsNoErr;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static IppStatus cpSHA256MessageDigest(DigestSHA256 hash, const Ipp8u* pMsg, int msgLen, const DigestSHA256 IV)
|
|
{
|
|
/* test digest pointer */
|
|
IPP_BAD_PTR1_RET(hash);
|
|
/* test message length */
|
|
IPP_BADARG_RET((msgLen<0), ippStsLengthErr);
|
|
/* test message pointer */
|
|
IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr);
|
|
|
|
{
|
|
/* select processing function */
|
|
#if (_SHA_NI_ENABLING_==_FEATURE_ON_)
|
|
cpHashProc updateFunc = UpdateSHA256ni;
|
|
#elif (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_)
|
|
cpHashProc updateFunc = IsFeatureEnabled(SHA_NI_ENABLED)? UpdateSHA256ni : UpdateSHA256;
|
|
#else
|
|
cpHashProc updateFunc = UpdateSHA256;
|
|
#endif
|
|
|
|
/* message length in the multiple MBS and the rest */
|
|
int msgLenBlks = msgLen & (-MBS_SHA256);
|
|
int msgLenRest = msgLen - msgLenBlks;
|
|
|
|
/* init hash */
|
|
hash[0] = IV[0];
|
|
hash[1] = IV[1];
|
|
hash[2] = IV[2];
|
|
hash[3] = IV[3];
|
|
hash[4] = IV[4];
|
|
hash[5] = IV[5];
|
|
hash[6] = IV[6];
|
|
hash[7] = IV[7];
|
|
|
|
/* process main part of the message */
|
|
if(msgLenBlks) {
|
|
updateFunc(hash, pMsg, msgLenBlks, sha256_cnt);
|
|
pMsg += msgLenBlks;
|
|
}
|
|
|
|
cpFinalizeSHA256(hash, pMsg, msgLenRest, msgLen);
|
|
hash[0] = ENDIANNESS32(hash[0]);
|
|
hash[1] = ENDIANNESS32(hash[1]);
|
|
hash[2] = ENDIANNESS32(hash[2]);
|
|
hash[3] = ENDIANNESS32(hash[3]);
|
|
hash[4] = ENDIANNESS32(hash[4]);
|
|
hash[5] = ENDIANNESS32(hash[5]);
|
|
hash[6] = ENDIANNESS32(hash[6]);
|
|
hash[7] = ENDIANNESS32(hash[7]);
|
|
|
|
return ippStsNoErr;
|
|
}
|
|
}
|
|
|
|
/*F*
|
|
// Name: ippsSHA256MessageDigest,
|
|
// ippsSHA224MessageDigest
|
|
//
|
|
// Purpose: Digest of the whole message.
|
|
//
|
|
// Returns: Reason:
|
|
// ippStsNullPtrErr pMsg == NULL
|
|
// pDigest == NULL
|
|
// ippStsLengthErr len <0
|
|
// ippStsNoErr no errors
|
|
//
|
|
// Parameters:
|
|
// pMsg pointer to the input message
|
|
// len input message length
|
|
// pMD address of the output digest
|
|
//
|
|
*F*/
|
|
IPPFUN(IppStatus, ippsSHA256MessageDigest,(const Ipp8u* pMsg, int msgLen, Ipp8u* pMD))
|
|
{
|
|
/* test digest pointer */
|
|
IPP_BAD_PTR1_RET(pMD);
|
|
|
|
{
|
|
DigestSHA256 hash;
|
|
IppStatus sts = cpSHA256MessageDigest(hash, pMsg, msgLen, sha256_iv);
|
|
if(ippStsNoErr==sts)
|
|
CopyBlock(hash, pMD, IPP_SHA256_DIGEST_BITSIZE/BYTESIZE);
|
|
return sts;
|
|
}
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
IPPFUN(IppStatus, ippsSHA224MessageDigest,(const Ipp8u* pMsg, int msgLen, Ipp8u* pMD))
|
|
{
|
|
/* test digest pointer */
|
|
IPP_BAD_PTR1_RET(pMD);
|
|
|
|
{
|
|
DigestSHA256 hash;
|
|
IppStatus sts = cpSHA256MessageDigest(hash, pMsg, msgLen, sha224_iv);
|
|
if(ippStsNoErr==sts)
|
|
CopyBlock(hash, pMD, IPP_SHA224_DIGEST_BITSIZE/BYTESIZE);
|
|
return sts;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
/*
|
|
// available SHA256 methods
|
|
*/
|
|
IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA256, (void) )
|
|
{
|
|
static IppsHashMethod method = {
|
|
ippHashAlg_SHA256,
|
|
IPP_SHA256_DIGEST_BITSIZE/8,
|
|
MBS_SHA256,
|
|
MLR_SHA256,
|
|
sha256_hashInit,
|
|
sha256_hashUpdate,
|
|
sha256_hashOctString,
|
|
sha256_msgRep
|
|
};
|
|
return &method;
|
|
}
|
|
|
|
IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA256_NI, (void) )
|
|
{
|
|
#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_)
|
|
static IppsHashMethod method = {
|
|
ippHashAlg_SHA256,
|
|
IPP_SHA256_DIGEST_BITSIZE/8,
|
|
MBS_SHA256,
|
|
MLR_SHA256,
|
|
sha256_hashInit,
|
|
sha256_ni_hashUpdate,
|
|
sha256_hashOctString,
|
|
sha256_msgRep
|
|
};
|
|
return &method;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA256_TT, (void) )
|
|
{
|
|
static IppsHashMethod method = {
|
|
ippHashAlg_SHA256,
|
|
IPP_SHA256_DIGEST_BITSIZE/8,
|
|
MBS_SHA256,
|
|
MLR_SHA256,
|
|
sha256_hashInit,
|
|
sha256_hashUpdate,
|
|
sha256_hashOctString,
|
|
sha256_msgRep
|
|
};
|
|
#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_)
|
|
if(IsFeatureEnabled(SHA_NI_ENABLED))
|
|
method.hashUpdate = sha256_ni_hashUpdate;
|
|
#endif
|
|
return &method;
|
|
}
|
|
|
|
#if defined(_ENABLE_ALG_SHA224_)
|
|
/*
|
|
// available SHA224 methods
|
|
*/
|
|
IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA224, (void) )
|
|
{
|
|
static IppsHashMethod method = {
|
|
ippHashAlg_SHA224,
|
|
IPP_SHA224_DIGEST_BITSIZE/8,
|
|
MBS_SHA256,
|
|
MLR_SHA256,
|
|
sha224_hashInit,
|
|
sha256_hashUpdate,
|
|
sha224_hashOctString,
|
|
sha256_msgRep
|
|
};
|
|
return &method;
|
|
}
|
|
|
|
IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA224_NI, (void) )
|
|
{
|
|
#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_)
|
|
static IppsHashMethod method = {
|
|
ippHashAlg_SHA224,
|
|
IPP_SHA224_DIGEST_BITSIZE/8,
|
|
MBS_SHA256,
|
|
MLR_SHA256,
|
|
sha224_hashInit,
|
|
sha256_ni_hashUpdate,
|
|
sha224_hashOctString,
|
|
sha256_msgRep
|
|
};
|
|
return &method;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
IPPFUN( const IppsHashMethod*, ippsHashMethod_SHA224_TT, (void) )
|
|
{
|
|
static IppsHashMethod method = {
|
|
ippHashAlg_SHA224,
|
|
IPP_SHA256_DIGEST_BITSIZE/8,
|
|
MBS_SHA256,
|
|
MLR_SHA256,
|
|
sha256_hashInit,
|
|
sha256_hashUpdate,
|
|
sha256_hashOctString,
|
|
sha256_msgRep
|
|
};
|
|
#if (_SHA_NI_ENABLING_==_FEATURE_TICKTOCK_ || _SHA_NI_ENABLING_==_FEATURE_ON_)
|
|
if(IsFeatureEnabled(SHA_NI_ENABLED))
|
|
method.hashUpdate = sha256_ni_hashUpdate;
|
|
#endif
|
|
return &method;
|
|
}
|
|
#endif
|