mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2026-07-08 02:50:47 +02:00
Merge pull request #10431 from mattia-moffa/20260330-max32666-sha-bare-metal
MAX32666 bare-metal SHA accelerator
This commit is contained in:
@@ -84,9 +84,11 @@ hardware.
|
||||
- SHA-384
|
||||
- SHA-512
|
||||
|
||||
Please note that when using `MAX3266X_SHA` there will be a limitation when
|
||||
attempting to do a larger sized hash as the SDK for the hardware currently
|
||||
expects a the whole msg buffer to be given.
|
||||
By default `MAX3266X_SHA` drives the TPU directly, feeding the message to the
|
||||
hardware incrementally so hashes of any size are supported. Adding
|
||||
`#define WOLFSSL_MAX3266X_SHA_ONESHOT` to `user_settings.h` instead buffers
|
||||
the whole message in memory and hashes it in one shot using the SDK, which
|
||||
has slightly better performance.
|
||||
|
||||
`#define MAX3266X_MATH` (Replaces math operation calls for algos
|
||||
like RSA and ECC key generation):
|
||||
|
||||
@@ -136,6 +136,8 @@ int wc_MxcAesCryptoCb(wc_CryptoInfo* info)
|
||||
|
||||
#ifdef MAX3266X_SHA_CB
|
||||
|
||||
#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT
|
||||
|
||||
/* Shared callback handler: Update grows buffer, Final computes hash. */
|
||||
static int wc_MxcShaCbDispatch(byte** msg, word32* used, word32* len,
|
||||
void* heap, const byte* in, word32 inSz,
|
||||
@@ -202,9 +204,150 @@ int wc_MxcShaCryptoCb(wc_CryptoInfo* info)
|
||||
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
#else /* WOLFSSL_MAX3266X_SHA_ONESHOT */
|
||||
|
||||
int wc_MXC_TPU_SHA_Update(unsigned int* digest, unsigned int* buffer,
|
||||
unsigned int* buffLen, unsigned int* loLen,
|
||||
unsigned int* hiLen, int stateWords,
|
||||
unsigned int blockSz, MXC_TPU_HASH_TYPE algo,
|
||||
const unsigned char* data, unsigned int len);
|
||||
int wc_MXC_TPU_SHA_Final(unsigned int* digest, unsigned int* buffer,
|
||||
unsigned int* buffLen, unsigned int loLen,
|
||||
unsigned int hiLen, int stateWords,
|
||||
unsigned int digestSz, MXC_TPU_HASH_TYPE algo,
|
||||
unsigned char* hash);
|
||||
static int wc_MXC_TPU_SHA_Init(unsigned int* digest, int stateWords,
|
||||
MXC_TPU_HASH_TYPE algo);
|
||||
|
||||
static int wc_MxcShaCbDispatch(
|
||||
unsigned int* digest, unsigned int* buffer,
|
||||
unsigned int* buffLen, unsigned int* loLen,
|
||||
unsigned int* hiLen, void** devCtx, int stateWords,
|
||||
unsigned int blockSz, unsigned int digestSz,
|
||||
MXC_TPU_HASH_TYPE algo,
|
||||
const unsigned char* in, unsigned int inSz,
|
||||
unsigned char* outDigest)
|
||||
{
|
||||
if (*devCtx == NULL) {
|
||||
int initRet = wc_MXC_TPU_SHA_Init(digest, stateWords, algo);
|
||||
if (initRet != 0)
|
||||
return initRet;
|
||||
*devCtx = (void*)1;
|
||||
}
|
||||
|
||||
if (in != NULL && outDigest == NULL) {
|
||||
MAX3266X_MSG("Update CB");
|
||||
return wc_MXC_TPU_SHA_Update(digest, buffer, buffLen, loLen, hiLen,
|
||||
stateWords, blockSz, algo, in, inSz);
|
||||
}
|
||||
if (in == NULL && outDigest != NULL) {
|
||||
int ret;
|
||||
MAX3266X_MSG("Final CB");
|
||||
ret = wc_MXC_TPU_SHA_Final(digest, buffer, buffLen,
|
||||
*loLen, *hiLen, stateWords,
|
||||
digestSz, algo, outDigest);
|
||||
/* Reset context state for reuse */
|
||||
if (ret == 0) {
|
||||
*buffLen = 0;
|
||||
*loLen = 0;
|
||||
*hiLen = 0;
|
||||
XMEMSET(buffer, 0, blockSz);
|
||||
ret = wc_MXC_TPU_SHA_Init(digest, stateWords, algo);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
if (inSz == 0) {
|
||||
return 0; /* Don't need to Update when size is zero */
|
||||
}
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* SHA-384/512 callback helper: bridges word64 loLen to unsigned int pair
|
||||
* and delegates to wc_MxcShaCbDispatch. */
|
||||
static int wc_MxcShaCbDispatch512(wc_Sha512* ctx, int stateWords,
|
||||
unsigned int blockSz, unsigned int digestSz,
|
||||
MXC_TPU_HASH_TYPE algo,
|
||||
const unsigned char* in, unsigned int inSz,
|
||||
unsigned char* digest)
|
||||
{
|
||||
unsigned int loLen = (unsigned int)ctx->loLen;
|
||||
unsigned int hiLen = (unsigned int)(ctx->loLen >> 32);
|
||||
int ret;
|
||||
|
||||
ret = wc_MxcShaCbDispatch((unsigned int*)ctx->digest,
|
||||
(unsigned int*)ctx->buffer,
|
||||
&ctx->buffLen, &loLen, &hiLen,
|
||||
&ctx->devCtx, stateWords, blockSz, digestSz,
|
||||
algo, in, inSz, digest);
|
||||
|
||||
ctx->loLen = (word64)loLen | ((word64)hiLen << 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wc_MxcShaCryptoCb(wc_CryptoInfo* info)
|
||||
{
|
||||
switch (info->hash.type) {
|
||||
#ifndef NO_SHA
|
||||
case WC_HASH_TYPE_SHA:
|
||||
return wc_MxcShaCbDispatch(
|
||||
info->hash.sha1->digest,
|
||||
info->hash.sha1->buffer,
|
||||
&info->hash.sha1->buffLen,
|
||||
&info->hash.sha1->loLen, &info->hash.sha1->hiLen,
|
||||
&info->hash.sha1->devCtx,
|
||||
MXC_SHA1_STATE_WORDS, WC_SHA_BLOCK_SIZE,
|
||||
WC_SHA_DIGEST_SIZE, MXC_TPU_HASH_SHA1,
|
||||
info->hash.in, info->hash.inSz, info->hash.digest);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case WC_HASH_TYPE_SHA224:
|
||||
return wc_MxcShaCbDispatch(
|
||||
info->hash.sha224->digest,
|
||||
info->hash.sha224->buffer,
|
||||
&info->hash.sha224->buffLen,
|
||||
&info->hash.sha224->loLen, &info->hash.sha224->hiLen,
|
||||
&info->hash.sha224->devCtx,
|
||||
MXC_SHA224_STATE_WORDS, WC_SHA224_BLOCK_SIZE,
|
||||
WC_SHA224_DIGEST_SIZE, MXC_TPU_HASH_SHA224,
|
||||
info->hash.in, info->hash.inSz, info->hash.digest);
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case WC_HASH_TYPE_SHA256:
|
||||
return wc_MxcShaCbDispatch(
|
||||
info->hash.sha256->digest,
|
||||
info->hash.sha256->buffer,
|
||||
&info->hash.sha256->buffLen,
|
||||
&info->hash.sha256->loLen, &info->hash.sha256->hiLen,
|
||||
&info->hash.sha256->devCtx,
|
||||
MXC_SHA256_STATE_WORDS, WC_SHA256_BLOCK_SIZE,
|
||||
WC_SHA256_DIGEST_SIZE, MXC_TPU_HASH_SHA256,
|
||||
info->hash.in, info->hash.inSz, info->hash.digest);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_HASH_TYPE_SHA384:
|
||||
return wc_MxcShaCbDispatch512(info->hash.sha384,
|
||||
MXC_SHA384_STATE_WORDS, WC_SHA384_BLOCK_SIZE,
|
||||
WC_SHA384_DIGEST_SIZE, MXC_TPU_HASH_SHA384,
|
||||
info->hash.in, info->hash.inSz, info->hash.digest);
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case WC_HASH_TYPE_SHA512:
|
||||
return wc_MxcShaCbDispatch512(info->hash.sha512,
|
||||
MXC_SHA512_STATE_WORDS, WC_SHA512_BLOCK_SIZE,
|
||||
WC_SHA512_DIGEST_SIZE, MXC_TPU_HASH_SHA512,
|
||||
info->hash.in, info->hash.inSz, info->hash.digest);
|
||||
#endif
|
||||
default:
|
||||
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_MAX3266X_SHA_ONESHOT */
|
||||
#endif /* MAX3266X_SHA_CB */
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_COPY
|
||||
#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT
|
||||
static int wc_MxcCopyCb(wc_CryptoInfo* info)
|
||||
{
|
||||
if (info == NULL || info->copy.src == NULL || info->copy.dst == NULL) {
|
||||
@@ -268,6 +411,55 @@ static int wc_MxcCopyCb(wc_CryptoInfo* info)
|
||||
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
}
|
||||
}
|
||||
#else /* WOLFSSL_MAX3266X_SHA_ONESHOT */
|
||||
static int wc_MxcCopyCb(wc_CryptoInfo* info)
|
||||
{
|
||||
word32 sz;
|
||||
|
||||
if (info == NULL || info->copy.src == NULL || info->copy.dst == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
switch (info->copy.type) {
|
||||
#ifdef MAX3266X_SHA_CB
|
||||
#ifndef NO_SHA
|
||||
case WC_HASH_TYPE_SHA:
|
||||
wc_ShaFree((wc_Sha*)info->copy.dst);
|
||||
sz = sizeof(wc_Sha);
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA224
|
||||
case WC_HASH_TYPE_SHA224:
|
||||
wc_Sha224Free((wc_Sha224*)info->copy.dst);
|
||||
sz = sizeof(wc_Sha224);
|
||||
break;
|
||||
#endif
|
||||
#ifndef NO_SHA256
|
||||
case WC_HASH_TYPE_SHA256:
|
||||
wc_Sha256Free((wc_Sha256*)info->copy.dst);
|
||||
sz = sizeof(wc_Sha256);
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA384
|
||||
case WC_HASH_TYPE_SHA384:
|
||||
wc_Sha384Free((wc_Sha384*)info->copy.dst);
|
||||
sz = sizeof(wc_Sha384);
|
||||
break;
|
||||
#endif
|
||||
#ifdef WOLFSSL_SHA512
|
||||
case WC_HASH_TYPE_SHA512:
|
||||
wc_Sha512Free((wc_Sha512*)info->copy.dst);
|
||||
sz = sizeof(wc_Sha512);
|
||||
break;
|
||||
#endif
|
||||
#endif /* MAX3266X_SHA_CB */
|
||||
default:
|
||||
return WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
}
|
||||
XMEMCPY(info->copy.dst, info->copy.src, sz);
|
||||
return 0;
|
||||
}
|
||||
#endif /* WOLFSSL_MAX3266X_SHA_ONESHOT */
|
||||
#endif /* WOLF_CRYPTO_CB_COPY */
|
||||
|
||||
#ifdef WOLF_CRYPTO_CB_FREE
|
||||
@@ -370,7 +562,7 @@ int wc_MxcCryptoCb(int devIdArg, wc_CryptoInfo* info, void* ctx)
|
||||
break;
|
||||
#endif /* WOLF_CRYPTO_CB_FREE */
|
||||
default:
|
||||
MAX3266X_MSG("Callback not support with MXC, using SW");
|
||||
MAX3266X_MSG("Callback not supported with MXC, using SW");
|
||||
/* return this to bypass HW and use SW */
|
||||
ret = WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE);
|
||||
}
|
||||
@@ -691,6 +883,8 @@ int wc_MxcCb_AesCbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
|
||||
#if defined(MAX3266X_SHA) || defined(MAX3266X_SHA_CB)
|
||||
|
||||
#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT
|
||||
|
||||
/* Check for empty message and provide pre-computed digest if so */
|
||||
/* Returns 1 if empty (digest filled), 0 if needs hardware processing */
|
||||
int wc_MXC_TPU_SHA_GetDigest(const unsigned char* msg, unsigned int msgSz,
|
||||
@@ -853,7 +1047,285 @@ int wc_MXC_TPU_SHA_Final(unsigned char** msg, unsigned int* used,
|
||||
return status;
|
||||
}
|
||||
|
||||
#else /* WOLFSSL_MAX3266X_SHA_ONESHOT */
|
||||
|
||||
/* TPU hash helpers (bare-metal SHA accelerator) */
|
||||
|
||||
/* Reset TPU, select hash function, and restore intermediate state into
|
||||
* the HASH_DIGEST registers. */
|
||||
void wc_MXC_TPU_Hash_Setup(MXC_TPU_HASH_TYPE algo,
|
||||
const unsigned int* state, int stateWords)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Init TPU clock */
|
||||
MXC_TPU_Init(MXC_SYS_PERIPH_CLOCK_TPU);
|
||||
|
||||
/* Reset TPU */
|
||||
MXC_TPU->ctrl = MXC_F_TPU_CTRL_RST;
|
||||
while (!(MXC_TPU->ctrl & MXC_F_TPU_CTRL_RDY)) {}
|
||||
MXC_TPU->ctrl |= MXC_F_TPU_CTRL_FLAG_MODE;
|
||||
|
||||
/* Select hash function and INIT to prime the hardware's internal state */
|
||||
MXC_TPU->hash_ctrl = ((unsigned int)algo << MXC_F_TPU_HASH_CTRL_HASH_POS)
|
||||
| MXC_F_TPU_HASH_CTRL_INIT;
|
||||
while (MXC_TPU->hash_ctrl & MXC_F_TPU_HASH_CTRL_INIT) {}
|
||||
|
||||
/* Overwrite the standard IV with our saved intermediate state */
|
||||
for (i = 0; i < stateWords; i++) {
|
||||
MXC_TPU->hash_digest[i] = state[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Feed one complete block to the TPU and wait for completion. */
|
||||
void wc_MXC_TPU_Hash_Feed_Block(const unsigned char* data,
|
||||
unsigned int blockSz)
|
||||
{
|
||||
unsigned int word;
|
||||
|
||||
MXC_TPU->ctrl |= MXC_F_TPU_CTRL_DMA_DONE | MXC_F_TPU_CTRL_GLS_DONE |
|
||||
MXC_F_TPU_CTRL_HSH_DONE | MXC_F_TPU_CTRL_CPH_DONE |
|
||||
MXC_F_TPU_CTRL_MAA_DONE;
|
||||
|
||||
for (word = 0; word < blockSz; word += 4) {
|
||||
while (!(MXC_TPU->ctrl & MXC_F_TPU_CTRL_RDY)) {}
|
||||
MXC_TPU->data_in[0] = (unsigned int)data[word]
|
||||
| ((unsigned int)data[word + 1] << 8)
|
||||
| ((unsigned int)data[word + 2] << 16)
|
||||
| ((unsigned int)data[word + 3] << 24);
|
||||
}
|
||||
|
||||
while (!(MXC_TPU->ctrl & MXC_F_TPU_CTRL_HSH_DONE)) {}
|
||||
}
|
||||
|
||||
/* Feed the last (possibly partial) block with LAST flag and msg size. */
|
||||
void wc_MXC_TPU_Hash_Feed_Last(const unsigned char* data,
|
||||
unsigned int dataLen,
|
||||
unsigned int totalLenLo,
|
||||
unsigned int totalLenHi)
|
||||
{
|
||||
unsigned int word;
|
||||
|
||||
/* Set total message size for padding calculation */
|
||||
MXC_TPU->hash_msg_sz[0] = totalLenLo;
|
||||
MXC_TPU->hash_msg_sz[1] = totalLenHi;
|
||||
|
||||
/* Signal this is the last block */
|
||||
MXC_TPU->hash_ctrl |= MXC_F_TPU_HASH_CTRL_LAST;
|
||||
|
||||
/* Empty message: the hardware needs a dummy write to data_in to
|
||||
* trigger processing of the padding-only block. */
|
||||
if (totalLenLo == 0 && totalLenHi == 0) {
|
||||
while (!(MXC_TPU->ctrl & MXC_F_TPU_CTRL_RDY)) {}
|
||||
MXC_TPU->data_in[0] = 0;
|
||||
}
|
||||
|
||||
for (word = 0; word < dataLen; word += 4) {
|
||||
while (!(MXC_TPU->ctrl & MXC_F_TPU_CTRL_RDY)) {}
|
||||
if (dataLen >= (word + 4)) {
|
||||
MXC_TPU->data_in[0] = (unsigned int)data[word]
|
||||
| ((unsigned int)data[word + 1] << 8)
|
||||
| ((unsigned int)data[word + 2] << 16)
|
||||
| ((unsigned int)data[word + 3] << 24);
|
||||
}
|
||||
else if ((dataLen & 3) == 1) {
|
||||
MXC_TPU->data_in[0] = (unsigned int)data[word];
|
||||
}
|
||||
else if ((dataLen & 3) == 2) {
|
||||
MXC_TPU->data_in[0] = (unsigned int)data[word]
|
||||
| ((unsigned int)data[word + 1] << 8);
|
||||
}
|
||||
else if ((dataLen & 3) == 3) {
|
||||
MXC_TPU->data_in[0] = (unsigned int)data[word]
|
||||
| ((unsigned int)data[word + 1] << 8)
|
||||
| ((unsigned int)data[word + 2] << 16);
|
||||
}
|
||||
}
|
||||
|
||||
while (!(MXC_TPU->ctrl & MXC_F_TPU_CTRL_HSH_DONE)) {}
|
||||
}
|
||||
|
||||
/* Save intermediate hash state from hardware registers into context. */
|
||||
void wc_MXC_TPU_Hash_Save_State(unsigned int* state, int stateWords)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < stateWords; i++) {
|
||||
state[i] = MXC_TPU->hash_digest[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Read final digest from hardware registers. */
|
||||
void wc_MXC_TPU_Hash_Read_Digest(unsigned char* digest, unsigned int digestSz)
|
||||
{
|
||||
XMEMCPY(digest, (const void*)MXC_TPU->hash_digest, digestSz);
|
||||
}
|
||||
|
||||
/* Generic Update */
|
||||
int wc_MXC_TPU_SHA_Update(unsigned int* digest, unsigned int* buffer,
|
||||
unsigned int* buffLen, unsigned int* loLen,
|
||||
unsigned int* hiLen, int stateWords,
|
||||
unsigned int blockSz, MXC_TPU_HASH_TYPE algo,
|
||||
const unsigned char* data, unsigned int len)
|
||||
{
|
||||
int status;
|
||||
unsigned int fill;
|
||||
|
||||
if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Update total length */
|
||||
{
|
||||
unsigned int oldLo = *loLen;
|
||||
*loLen += len;
|
||||
if (*loLen < oldLo) {
|
||||
(*hiLen)++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If there's existing buffered data, try to complete a block */
|
||||
if (*buffLen > 0) {
|
||||
fill = blockSz - *buffLen;
|
||||
if (len < fill) {
|
||||
XMEMCPY((unsigned char*)buffer + *buffLen, data, len);
|
||||
*buffLen += len;
|
||||
return 0;
|
||||
}
|
||||
XMEMCPY((unsigned char*)buffer + *buffLen, data, fill);
|
||||
data += fill;
|
||||
len -= fill;
|
||||
|
||||
/* Only process the completed buffer block if there's more data
|
||||
* coming. The TPU requires LAST to be set with real data (unless the
|
||||
* entire message is empty), so we always keep at least one block
|
||||
* buffered for Final. */
|
||||
if (len > 0) {
|
||||
*buffLen = 0;
|
||||
status = wolfSSL_HwHashMutexLock();
|
||||
if (status != 0) return status;
|
||||
wc_MXC_TPU_Hash_Setup(algo, digest, stateWords);
|
||||
wc_MXC_TPU_Hash_Feed_Block((const unsigned char*)buffer, blockSz);
|
||||
wc_MXC_TPU_Hash_Save_State(digest, stateWords);
|
||||
MAX3266X_MSG("SHA HW Acceleration Used");
|
||||
wolfSSL_HwHashMutexUnLock();
|
||||
}
|
||||
else {
|
||||
*buffLen = blockSz;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process full blocks directly from input, always leaving the last
|
||||
* complete block buffered so Final has data to feed with LAST. */
|
||||
if (len > blockSz) {
|
||||
status = wolfSSL_HwHashMutexLock();
|
||||
if (status != 0) return status;
|
||||
wc_MXC_TPU_Hash_Setup(algo, digest, stateWords);
|
||||
|
||||
while (len > blockSz) {
|
||||
wc_MXC_TPU_Hash_Feed_Block(data, blockSz);
|
||||
data += blockSz;
|
||||
len -= blockSz;
|
||||
}
|
||||
|
||||
wc_MXC_TPU_Hash_Save_State(digest, stateWords);
|
||||
MAX3266X_MSG("SHA HW Acceleration Used");
|
||||
wolfSSL_HwHashMutexUnLock();
|
||||
}
|
||||
|
||||
/* Buffer remaining data (1..blockSz bytes) */
|
||||
if (len > 0) {
|
||||
XMEMCPY((unsigned char*)buffer, data, len);
|
||||
*buffLen = len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generic Final */
|
||||
int wc_MXC_TPU_SHA_Final(unsigned int* digest, unsigned int* buffer,
|
||||
unsigned int* buffLen, unsigned int loLen,
|
||||
unsigned int hiLen, int stateWords,
|
||||
unsigned int digestSz, MXC_TPU_HASH_TYPE algo,
|
||||
unsigned char* hash)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = wolfSSL_HwHashMutexLock();
|
||||
if (status != 0) return status;
|
||||
|
||||
wc_MXC_TPU_Hash_Setup(algo, digest, stateWords);
|
||||
wc_MXC_TPU_Hash_Feed_Last((const unsigned char*)buffer, *buffLen,
|
||||
loLen, hiLen);
|
||||
wc_MXC_TPU_Hash_Read_Digest(hash, digestSz);
|
||||
MAX3266X_MSG("SHA HW Acceleration Used");
|
||||
|
||||
wolfSSL_HwHashMutexUnLock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generic GetHash */
|
||||
int wc_MXC_TPU_SHA_GetHash(unsigned int* digest, unsigned int* buffer,
|
||||
unsigned int buffLen, unsigned int loLen,
|
||||
unsigned int hiLen, int stateWords,
|
||||
unsigned int digestSz, MXC_TPU_HASH_TYPE algo,
|
||||
unsigned char* hash)
|
||||
{
|
||||
int status;
|
||||
/* Use copies so we don't modify the real context */
|
||||
unsigned int tmpDigest[MXC_SHA512_STATE_WORDS];
|
||||
unsigned int tmpBuf[128 / sizeof(unsigned int)]; /* max block: 1024 bits */
|
||||
|
||||
XMEMCPY(tmpDigest, digest, stateWords * sizeof(unsigned int));
|
||||
if (buffLen > 0) {
|
||||
XMEMCPY(tmpBuf, buffer, buffLen);
|
||||
}
|
||||
|
||||
status = wolfSSL_HwHashMutexLock();
|
||||
if (status != 0) return status;
|
||||
|
||||
wc_MXC_TPU_Hash_Setup(algo, tmpDigest, stateWords);
|
||||
wc_MXC_TPU_Hash_Feed_Last((const unsigned char*)tmpBuf, buffLen,
|
||||
loLen, hiLen);
|
||||
wc_MXC_TPU_Hash_Read_Digest(hash, digestSz);
|
||||
MAX3266X_MSG("SHA HW Acceleration Used");
|
||||
|
||||
wolfSSL_HwHashMutexUnLock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Init helper: use TPU INIT to get the standard IV for any algorithm */
|
||||
static int wc_MXC_TPU_SHA_Init(unsigned int* digest, int stateWords,
|
||||
MXC_TPU_HASH_TYPE algo)
|
||||
{
|
||||
int status = wolfSSL_HwHashMutexLock();
|
||||
if (status != 0) return status;
|
||||
|
||||
MXC_TPU_Init(MXC_SYS_PERIPH_CLOCK_TPU);
|
||||
MXC_TPU->ctrl = MXC_F_TPU_CTRL_RST;
|
||||
while (!(MXC_TPU->ctrl & MXC_F_TPU_CTRL_RDY)) {}
|
||||
MXC_TPU->ctrl |= MXC_F_TPU_CTRL_FLAG_MODE;
|
||||
|
||||
/* Select hash function and trigger INIT to load standard IV */
|
||||
MXC_TPU->hash_ctrl = (unsigned int)algo << MXC_F_TPU_HASH_CTRL_HASH_POS;
|
||||
MXC_TPU->hash_ctrl |= MXC_F_TPU_HASH_CTRL_INIT;
|
||||
while (MXC_TPU->hash_ctrl & MXC_F_TPU_HASH_CTRL_INIT) {}
|
||||
|
||||
/* Save the standard IV into the context */
|
||||
wc_MXC_TPU_Hash_Save_State(digest, stateWords);
|
||||
|
||||
wolfSSL_HwHashMutexUnLock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_MAX3266X_SHA_ONESHOT */
|
||||
|
||||
/* Per-algorithm Init / Update / Final / GetHash / Copy / Free */
|
||||
|
||||
#ifndef MAX3266X_SHA_CB
|
||||
|
||||
#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT
|
||||
|
||||
#if !defined(NO_SHA)
|
||||
|
||||
WOLFSSL_API int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
|
||||
@@ -1198,7 +1670,428 @@ WOLFSSL_API void wc_Sha512Free(wc_Sha512* sha512)
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
#endif /* !MAX3266X_SHA_CB*/
|
||||
|
||||
#else /* WOLFSSL_MAX3266X_SHA_ONESHOT */
|
||||
/* Non-callback path: provide the wc_Sha* API functions directly */
|
||||
|
||||
#if !defined(NO_SHA)
|
||||
|
||||
WOLFSSL_API int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
|
||||
{
|
||||
if (sha == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
(void)devId;
|
||||
XMEMSET(sha, 0, sizeof(*sha));
|
||||
sha->heap = heap;
|
||||
return wc_MXC_TPU_SHA_Init(sha->digest, MXC_SHA1_STATE_WORDS,
|
||||
MXC_TPU_HASH_SHA1);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_ShaUpdate(wc_Sha* sha, const unsigned char* data,
|
||||
unsigned int len)
|
||||
{
|
||||
if (sha == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return wc_MXC_TPU_SHA_Update(sha->digest,
|
||||
sha->buffer, &sha->buffLen, &sha->loLen, &sha->hiLen,
|
||||
MXC_SHA1_STATE_WORDS, WC_SHA_BLOCK_SIZE,
|
||||
MXC_TPU_HASH_SHA1, data, len);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_ShaFinal(wc_Sha* sha, unsigned char* hash)
|
||||
{
|
||||
int ret;
|
||||
if (sha == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
ret = wc_MXC_TPU_SHA_Final(sha->digest,
|
||||
sha->buffer, &sha->buffLen, sha->loLen, sha->hiLen,
|
||||
MXC_SHA1_STATE_WORDS,
|
||||
WC_SHA_DIGEST_SIZE, MXC_TPU_HASH_SHA1, hash);
|
||||
if (ret == 0) {
|
||||
return wc_InitSha_ex(sha, sha->heap, INVALID_DEVID);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_ShaGetHash(wc_Sha* sha, unsigned char* hash)
|
||||
{
|
||||
if (sha == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return wc_MXC_TPU_SHA_GetHash(sha->digest,
|
||||
sha->buffer, sha->buffLen, sha->loLen, sha->hiLen,
|
||||
MXC_SHA1_STATE_WORDS,
|
||||
WC_SHA_DIGEST_SIZE, MXC_TPU_HASH_SHA1, hash);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_ShaCopy(wc_Sha* src, wc_Sha* dst)
|
||||
{
|
||||
if (src == NULL || dst == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
XMEMCPY(dst, src, sizeof(wc_Sha));
|
||||
return 0;
|
||||
}
|
||||
|
||||
WOLFSSL_API void wc_ShaFree(wc_Sha* sha)
|
||||
{
|
||||
if (sha == NULL) {
|
||||
return;
|
||||
}
|
||||
ForceZero(sha, sizeof(wc_Sha));
|
||||
}
|
||||
|
||||
#endif /* !NO_SHA */
|
||||
|
||||
#if defined(WOLFSSL_SHA224)
|
||||
|
||||
WOLFSSL_API int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
|
||||
{
|
||||
if (sha224 == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
(void)devId;
|
||||
XMEMSET(sha224, 0, sizeof(*sha224));
|
||||
sha224->heap = heap;
|
||||
return wc_MXC_TPU_SHA_Init(sha224->digest, MXC_SHA224_STATE_WORDS,
|
||||
MXC_TPU_HASH_SHA224);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_InitSha224(wc_Sha224* sha224)
|
||||
{
|
||||
return wc_InitSha224_ex(sha224, NULL, INVALID_DEVID);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha224Update(wc_Sha224* sha224, const unsigned char* data,
|
||||
unsigned int len)
|
||||
{
|
||||
if (sha224 == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return wc_MXC_TPU_SHA_Update(sha224->digest,
|
||||
sha224->buffer, &sha224->buffLen,
|
||||
&sha224->loLen, &sha224->hiLen,
|
||||
MXC_SHA224_STATE_WORDS, WC_SHA224_BLOCK_SIZE,
|
||||
MXC_TPU_HASH_SHA224, data, len);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha224Final(wc_Sha224* sha224, unsigned char* hash)
|
||||
{
|
||||
int ret;
|
||||
if (sha224 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
ret = wc_MXC_TPU_SHA_Final(sha224->digest,
|
||||
sha224->buffer, &sha224->buffLen,
|
||||
sha224->loLen, sha224->hiLen,
|
||||
MXC_SHA224_STATE_WORDS,
|
||||
WC_SHA224_DIGEST_SIZE, MXC_TPU_HASH_SHA224, hash);
|
||||
if (ret == 0) {
|
||||
return wc_InitSha224_ex(sha224, sha224->heap, INVALID_DEVID);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha224GetHash(wc_Sha224* sha224, unsigned char* hash)
|
||||
{
|
||||
if (sha224 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return wc_MXC_TPU_SHA_GetHash(sha224->digest,
|
||||
sha224->buffer, sha224->buffLen,
|
||||
sha224->loLen, sha224->hiLen,
|
||||
MXC_SHA224_STATE_WORDS,
|
||||
WC_SHA224_DIGEST_SIZE, MXC_TPU_HASH_SHA224, hash);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst)
|
||||
{
|
||||
if (src == NULL || dst == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
XMEMCPY(dst, src, sizeof(wc_Sha224));
|
||||
return 0;
|
||||
}
|
||||
|
||||
WOLFSSL_API void wc_Sha224Free(wc_Sha224* sha224)
|
||||
{
|
||||
if (sha224 == NULL) {
|
||||
return;
|
||||
}
|
||||
ForceZero(sha224, sizeof(wc_Sha224));
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SHA224 */
|
||||
|
||||
#if !defined(NO_SHA256)
|
||||
|
||||
WOLFSSL_API int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
|
||||
{
|
||||
if (sha256 == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
(void)devId;
|
||||
XMEMSET(sha256, 0, sizeof(*sha256));
|
||||
sha256->heap = heap;
|
||||
return wc_MXC_TPU_SHA_Init(sha256->digest, MXC_SHA256_STATE_WORDS,
|
||||
MXC_TPU_HASH_SHA256);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_InitSha256(wc_Sha256* sha256)
|
||||
{
|
||||
return wc_InitSha256_ex(sha256, NULL, INVALID_DEVID);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha256Update(wc_Sha256* sha256, const unsigned char* data,
|
||||
unsigned int len)
|
||||
{
|
||||
if (sha256 == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return wc_MXC_TPU_SHA_Update(sha256->digest,
|
||||
sha256->buffer, &sha256->buffLen,
|
||||
&sha256->loLen, &sha256->hiLen,
|
||||
MXC_SHA256_STATE_WORDS, WC_SHA256_BLOCK_SIZE,
|
||||
MXC_TPU_HASH_SHA256, data, len);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha256Final(wc_Sha256* sha256, unsigned char* hash)
|
||||
{
|
||||
int ret;
|
||||
if (sha256 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
ret = wc_MXC_TPU_SHA_Final(sha256->digest,
|
||||
sha256->buffer, &sha256->buffLen,
|
||||
sha256->loLen, sha256->hiLen,
|
||||
MXC_SHA256_STATE_WORDS,
|
||||
WC_SHA256_DIGEST_SIZE, MXC_TPU_HASH_SHA256, hash);
|
||||
if (ret == 0) {
|
||||
return wc_InitSha256_ex(sha256, sha256->heap, INVALID_DEVID);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha256GetHash(wc_Sha256* sha256, unsigned char* hash)
|
||||
{
|
||||
if (sha256 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return wc_MXC_TPU_SHA_GetHash(sha256->digest,
|
||||
sha256->buffer, sha256->buffLen,
|
||||
sha256->loLen, sha256->hiLen,
|
||||
MXC_SHA256_STATE_WORDS,
|
||||
WC_SHA256_DIGEST_SIZE, MXC_TPU_HASH_SHA256, hash);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
|
||||
{
|
||||
if (src == NULL || dst == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
XMEMCPY(dst, src, sizeof(wc_Sha256));
|
||||
return 0;
|
||||
}
|
||||
|
||||
WOLFSSL_API void wc_Sha256Free(wc_Sha256* sha256)
|
||||
{
|
||||
if (sha256 == NULL) {
|
||||
return;
|
||||
}
|
||||
ForceZero(sha256, sizeof(wc_Sha256));
|
||||
}
|
||||
|
||||
#endif /* !NO_SHA256 */
|
||||
|
||||
#if defined(WOLFSSL_SHA384)
|
||||
|
||||
WOLFSSL_API int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
|
||||
{
|
||||
if (sha384 == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
(void)devId;
|
||||
XMEMSET(sha384, 0, sizeof(*sha384));
|
||||
sha384->heap = heap;
|
||||
return wc_MXC_TPU_SHA_Init((word32*)sha384->digest,
|
||||
MXC_SHA384_STATE_WORDS, MXC_TPU_HASH_SHA384);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_InitSha384(wc_Sha384* sha384)
|
||||
{
|
||||
return wc_InitSha384_ex(sha384, NULL, INVALID_DEVID);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha384Update(wc_Sha384* sha384, const unsigned char* data,
|
||||
unsigned int len)
|
||||
{
|
||||
word32 loLen, hiLen;
|
||||
int ret;
|
||||
if (sha384 == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
/* SHA-384/512 context uses word64 loLen/hiLen; the generic Update helper
|
||||
* uses word32. We bridge by converting here. */
|
||||
loLen = (word32)sha384->loLen;
|
||||
hiLen = (word32)(sha384->loLen >> 32);
|
||||
|
||||
ret = wc_MXC_TPU_SHA_Update((word32*)sha384->digest,
|
||||
(word32*)sha384->buffer, &sha384->buffLen,
|
||||
&loLen, &hiLen,
|
||||
MXC_SHA384_STATE_WORDS, WC_SHA384_BLOCK_SIZE,
|
||||
MXC_TPU_HASH_SHA384, data, len);
|
||||
|
||||
/* Write back the updated length */
|
||||
sha384->loLen = (word64)loLen | ((word64)hiLen << 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha384Final(wc_Sha384* sha384, unsigned char* hash)
|
||||
{
|
||||
int ret;
|
||||
if (sha384 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
ret = wc_MXC_TPU_SHA_Final((word32*)sha384->digest,
|
||||
(word32*)sha384->buffer, &sha384->buffLen,
|
||||
(word32)sha384->loLen, (word32)(sha384->loLen >> 32),
|
||||
MXC_SHA384_STATE_WORDS,
|
||||
WC_SHA384_DIGEST_SIZE, MXC_TPU_HASH_SHA384, hash);
|
||||
if (ret == 0) {
|
||||
return wc_InitSha384_ex(sha384, sha384->heap, INVALID_DEVID);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha384GetHash(wc_Sha384* sha384, unsigned char* hash)
|
||||
{
|
||||
if (sha384 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return wc_MXC_TPU_SHA_GetHash((word32*)sha384->digest,
|
||||
(word32*)sha384->buffer, sha384->buffLen,
|
||||
(word32)sha384->loLen, (word32)(sha384->loLen >> 32),
|
||||
MXC_SHA384_STATE_WORDS,
|
||||
WC_SHA384_DIGEST_SIZE, MXC_TPU_HASH_SHA384, hash);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
|
||||
{
|
||||
if (src == NULL || dst == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
XMEMCPY(dst, src, sizeof(wc_Sha384));
|
||||
return 0;
|
||||
}
|
||||
|
||||
WOLFSSL_API void wc_Sha384Free(wc_Sha384* sha384)
|
||||
{
|
||||
if (sha384 == NULL) {
|
||||
return;
|
||||
}
|
||||
ForceZero(sha384, sizeof(wc_Sha384));
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
|
||||
#if defined(WOLFSSL_SHA512)
|
||||
|
||||
WOLFSSL_API int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
|
||||
{
|
||||
if (sha512 == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
(void)devId;
|
||||
XMEMSET(sha512, 0, sizeof(*sha512));
|
||||
sha512->heap = heap;
|
||||
#if defined(WOLFSSL_SHA512_HASHTYPE)
|
||||
sha512->hashType = WC_HASH_TYPE_SHA512;
|
||||
#endif
|
||||
return wc_MXC_TPU_SHA_Init((word32*)sha512->digest,
|
||||
MXC_SHA512_STATE_WORDS, MXC_TPU_HASH_SHA512);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_InitSha512(wc_Sha512* sha512)
|
||||
{
|
||||
return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha512Update(wc_Sha512* sha512, const unsigned char* data,
|
||||
unsigned int len)
|
||||
{
|
||||
word32 loLen, hiLen;
|
||||
int ret;
|
||||
if (sha512 == NULL || (data == NULL && len > 0)) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
loLen = (word32)sha512->loLen;
|
||||
hiLen = (word32)(sha512->loLen >> 32);
|
||||
|
||||
ret = wc_MXC_TPU_SHA_Update((word32*)sha512->digest,
|
||||
(word32*)sha512->buffer, &sha512->buffLen,
|
||||
&loLen, &hiLen,
|
||||
MXC_SHA512_STATE_WORDS, WC_SHA512_BLOCK_SIZE,
|
||||
MXC_TPU_HASH_SHA512, data, len);
|
||||
|
||||
sha512->loLen = (word64)loLen | ((word64)hiLen << 32);
|
||||
return ret;
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha512Final(wc_Sha512* sha512, unsigned char* hash)
|
||||
{
|
||||
int ret;
|
||||
if (sha512 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
ret = wc_MXC_TPU_SHA_Final((word32*)sha512->digest,
|
||||
(word32*)sha512->buffer, &sha512->buffLen,
|
||||
(word32)sha512->loLen, (word32)(sha512->loLen >> 32),
|
||||
MXC_SHA512_STATE_WORDS,
|
||||
WC_SHA512_DIGEST_SIZE, MXC_TPU_HASH_SHA512, hash);
|
||||
if (ret == 0) {
|
||||
return wc_InitSha512_ex(sha512, sha512->heap, INVALID_DEVID);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha512GetHash(wc_Sha512* sha512, unsigned char* hash)
|
||||
{
|
||||
if (sha512 == NULL || hash == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
return wc_MXC_TPU_SHA_GetHash((word32*)sha512->digest,
|
||||
(word32*)sha512->buffer, sha512->buffLen,
|
||||
(word32)sha512->loLen, (word32)(sha512->loLen >> 32),
|
||||
MXC_SHA512_STATE_WORDS,
|
||||
WC_SHA512_DIGEST_SIZE, MXC_TPU_HASH_SHA512, hash);
|
||||
}
|
||||
|
||||
WOLFSSL_API int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
|
||||
{
|
||||
if (src == NULL || dst == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
XMEMCPY(dst, src, sizeof(wc_Sha512));
|
||||
return 0;
|
||||
}
|
||||
|
||||
WOLFSSL_API void wc_Sha512Free(wc_Sha512* sha512)
|
||||
{
|
||||
if (sha512 == NULL) {
|
||||
return;
|
||||
}
|
||||
ForceZero(sha512, sizeof(wc_Sha512));
|
||||
}
|
||||
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
|
||||
#endif /* WOLFSSL_MAX3266X_SHA_ONESHOT */
|
||||
#endif /* !MAX3266X_SHA_CB */
|
||||
#endif /* MAX3266X_SHA || MAX3266X_SHA_CB */
|
||||
|
||||
#if defined(MAX3266X_MATH)
|
||||
@@ -1285,6 +2178,7 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand,
|
||||
MXC_TPU_MAA_TYPE clc, unsigned int length)
|
||||
{
|
||||
mp_digit* zero_tmp;
|
||||
unsigned int zero_size;
|
||||
MAX3266X_MSG("Zero Padding Buffers for Hardware");
|
||||
if (length > MXC_MAA_MAX_SIZE) {
|
||||
MAX3266X_MSG("Hardware cannot exceed 2048 bit input");
|
||||
@@ -1296,19 +2190,23 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand,
|
||||
}
|
||||
|
||||
/* Create an array to compare values to to check edge for error edge case */
|
||||
zero_tmp = (mp_digit*)XMALLOC(multiplier->size*sizeof(mp_digit), NULL,
|
||||
zero_size = mod->size;
|
||||
if ((exp != NULL) && (exp->size > zero_size)) {
|
||||
zero_size = exp->size;
|
||||
}
|
||||
zero_tmp = (mp_digit*)XMALLOC(zero_size*sizeof(mp_digit), NULL,
|
||||
DYNAMIC_TYPE_TMP_BUFFER);
|
||||
if (zero_tmp == NULL) {
|
||||
MAX3266X_MSG("NULL pointer found after XMALLOC call");
|
||||
return MEMORY_E;
|
||||
}
|
||||
XMEMSET(zero_tmp, 0x00, multiplier->size*sizeof(mp_digit));
|
||||
XMEMSET(zero_tmp, 0x00, zero_size*sizeof(mp_digit));
|
||||
|
||||
/* Check for invalid arguments before padding */
|
||||
switch ((char)clc) {
|
||||
case MXC_TPU_MAA_EXP:
|
||||
/* Cannot be 0 for a^e mod m operation */
|
||||
if (XMEMCMP(zero_tmp, exp, (exp->used*sizeof(mp_digit))) == 0) {
|
||||
if (XMEMCMP(zero_tmp, exp->dp, (exp->used*sizeof(mp_digit))) == 0) {
|
||||
XFREE(zero_tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
MAX3266X_MSG("Cannot use Value 0 for Exp");
|
||||
return BAD_FUNC_ARG;
|
||||
@@ -1331,7 +2229,7 @@ int wc_MXC_MAA_zeroPad(mp_int* multiplier, mp_int* multiplicand,
|
||||
case MXC_TPU_MAA_ADD:
|
||||
case MXC_TPU_MAA_SUB:
|
||||
/* Cannot be 0 for mod m value */
|
||||
if (XMEMCMP(zero_tmp, mod, (exp->used*sizeof(mp_digit))) == 0) {
|
||||
if (XMEMCMP(zero_tmp, mod->dp, (mod->used*sizeof(mp_digit))) == 0) {
|
||||
XFREE(zero_tmp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||
MAX3266X_MSG("Cannot use Value 0 for Exp");
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
@@ -57,13 +57,16 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Enable copy/free callbacks when using callback mode */
|
||||
/* Enable copy callback when using callback mode (SHA Copy needs it) */
|
||||
#if defined(MAX3266X_SHA_CB)
|
||||
#ifndef WOLF_CRYPTO_CB_COPY
|
||||
#define WOLF_CRYPTO_CB_COPY
|
||||
#endif
|
||||
#ifndef WOLF_CRYPTO_CB_FREE
|
||||
#define WOLF_CRYPTO_CB_FREE
|
||||
/* One-shot mode buffers the whole message, so Free is needed too */
|
||||
#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT
|
||||
#ifndef WOLF_CRYPTO_CB_FREE
|
||||
#define WOLF_CRYPTO_CB_FREE
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -246,6 +249,20 @@
|
||||
|
||||
#if defined(MAX3266X_SHA) || defined(MAX3266X_SHA_CB)
|
||||
|
||||
#if defined(WOLFSSL_SHA512)
|
||||
/* Does not support these SHA512 Macros */
|
||||
#ifndef WOLFSSL_NOSHA512_224
|
||||
#warning "MAX3266X Port does not support SHA-512/224"
|
||||
#define WOLFSSL_NOSHA512_224
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA512_256
|
||||
#warning "MAX3266X Port does not support SHA-512/256"
|
||||
#define WOLFSSL_NOSHA512_256
|
||||
#endif
|
||||
#endif /* WOLFSSL_SHA512 */
|
||||
|
||||
#ifdef WOLFSSL_MAX3266X_SHA_ONESHOT
|
||||
|
||||
/* Use HASH_KEEP to accumulate message data for one-shot TPU hardware */
|
||||
#ifndef WOLFSSL_HASH_KEEP
|
||||
#define WOLFSSL_HASH_KEEP
|
||||
@@ -293,16 +310,6 @@
|
||||
#endif /* WOLFSSL_SHA384 */
|
||||
|
||||
#if defined(WOLFSSL_SHA512)
|
||||
/* Does not support these SHA512 Macros */
|
||||
#ifndef WOLFSSL_NOSHA512_224
|
||||
#warning "MAX3266X Port does not support SHA-512/224"
|
||||
#define WOLFSSL_NOSHA512_224
|
||||
#endif
|
||||
#ifndef WOLFSSL_NOSHA512_256
|
||||
#warning "MAX3266X Port does not support SHA-512/256"
|
||||
#define WOLFSSL_NOSHA512_256
|
||||
#endif
|
||||
|
||||
/* Define the SHA-512 digest for an empty string */
|
||||
/* as a constant byte array */
|
||||
static const unsigned char MXC_EMPTY_DIGEST_SHA512[64] = {
|
||||
@@ -354,6 +361,54 @@
|
||||
unsigned char* digest,
|
||||
MXC_TPU_HASH_TYPE algo);
|
||||
|
||||
#else /* WOLFSSL_MAX3266X_SHA_ONESHOT */
|
||||
|
||||
/* Number of HASH_DIGEST register words for each algorithm's state */
|
||||
#define MXC_SHA1_STATE_WORDS 5 /* 160-bit state */
|
||||
#define MXC_SHA224_STATE_WORDS 8 /* 256-bit internal state */
|
||||
#define MXC_SHA256_STATE_WORDS 8 /* 256-bit state */
|
||||
#define MXC_SHA384_STATE_WORDS 16 /* 512-bit internal state (word32) */
|
||||
#define MXC_SHA512_STATE_WORDS 16 /* 512-bit state (word32) */
|
||||
|
||||
/* TPU hash helpers - bare-metal SHA acceleration */
|
||||
WOLFSSL_LOCAL void wc_MXC_TPU_Hash_Setup(MXC_TPU_HASH_TYPE algo,
|
||||
const unsigned int* state, int stateWords);
|
||||
WOLFSSL_LOCAL void wc_MXC_TPU_Hash_Feed_Block(const unsigned char* data,
|
||||
unsigned int blockSz);
|
||||
WOLFSSL_LOCAL void wc_MXC_TPU_Hash_Feed_Last(const unsigned char* data,
|
||||
unsigned int dataLen,
|
||||
unsigned int totalLenLo,
|
||||
unsigned int totalLenHi);
|
||||
WOLFSSL_LOCAL void wc_MXC_TPU_Hash_Save_State(unsigned int* state,
|
||||
int stateWords);
|
||||
WOLFSSL_LOCAL void wc_MXC_TPU_Hash_Read_Digest(unsigned char* digest,
|
||||
unsigned int digestSz);
|
||||
|
||||
/* Generic SHA Update/Final/GetHash */
|
||||
WOLFSSL_LOCAL int wc_MXC_TPU_SHA_Update(unsigned int* digest,
|
||||
unsigned int* buffer,
|
||||
unsigned int* buffLen,
|
||||
unsigned int* loLen, unsigned int* hiLen,
|
||||
int stateWords, unsigned int blockSz,
|
||||
MXC_TPU_HASH_TYPE algo,
|
||||
const unsigned char* data,
|
||||
unsigned int len);
|
||||
WOLFSSL_LOCAL int wc_MXC_TPU_SHA_Final(unsigned int* digest,
|
||||
unsigned int* buffer,
|
||||
unsigned int* buffLen,
|
||||
unsigned int loLen, unsigned int hiLen,
|
||||
int stateWords, unsigned int digestSz,
|
||||
MXC_TPU_HASH_TYPE algo,
|
||||
unsigned char* hash);
|
||||
WOLFSSL_LOCAL int wc_MXC_TPU_SHA_GetHash(unsigned int* digest,
|
||||
unsigned int* buffer,
|
||||
unsigned int buffLen,
|
||||
unsigned int loLen, unsigned int hiLen,
|
||||
int stateWords, unsigned int digestSz,
|
||||
MXC_TPU_HASH_TYPE algo,
|
||||
unsigned char* hash);
|
||||
|
||||
#endif /* WOLFSSL_MAX3266X_SHA_ONESHOT */
|
||||
|
||||
#endif /* defined(MAX3266X_SHA) || defined(MAX3266X_SHA_CB) */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user