Fixes to support large hashing against HW without caching (in exclusive hardware access) Large hashing uses previous hash code with two descriptors and polling. Added wolfCrypt large hash tests for MD5, SHA and SHA256. Add missing MCAPI set size API's. Cleanup AES GCM large test. Changed MPLABX projects to default to PIC32MZ2048EFM144.

pull/1110/head
David Garske 2017-08-18 11:25:30 -07:00
parent 53e05786da
commit 74ed94ddb1
9 changed files with 436 additions and 99 deletions

View File

@ -59,6 +59,17 @@ int CRYPT_MD5_Initialize(CRYPT_MD5_CTX* md5)
return wc_InitMd5((Md5*)md5);
}
int CRYPT_MD5_DataSizeSet(CRYPT_MD5_CTX* md5, unsigned int sz)
{
if (md5 == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_PIC32MZ_HASH
wc_Md5SizeSet((Md5*)md5, sz);
#endif
return 0;
}
/* Add data to MD5 */
int CRYPT_MD5_DataAdd(CRYPT_MD5_CTX* md5, const unsigned char* input,
@ -95,6 +106,17 @@ int CRYPT_SHA_Initialize(CRYPT_SHA_CTX* sha)
return wc_InitSha((Sha*)sha);
}
int CRYPT_SHA_DataSizeSet(CRYPT_SHA_CTX* sha, unsigned int sz)
{
if (sha == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_PIC32MZ_HASH
wc_ShaSizeSet((Sha*)sha, sz);
#endif
return 0;
}
/* Add data to SHA */
int CRYPT_SHA_DataAdd(CRYPT_SHA_CTX* sha, const unsigned char* input,
@ -131,6 +153,17 @@ int CRYPT_SHA256_Initialize(CRYPT_SHA256_CTX* sha256)
return wc_InitSha256((Sha256*)sha256);
}
int CRYPT_SHA256_DataSizeSet(CRYPT_SHA256_CTX* sha256, unsigned int sz)
{
if (sha256 == NULL)
return BAD_FUNC_ARG;
#ifdef WOLFSSL_PIC32MZ_HASH
wc_Sha256SizeSet((Sha256*)sha256, sz);
#endif
return 0;
}
/* Add data to SHA-256 */
int CRYPT_SHA256_DataAdd(CRYPT_SHA256_CTX* sha256, const unsigned char* input,

View File

@ -31,7 +31,7 @@
<conf name="default" type="2">
<toolsSet>
<developmentServer>localhost</developmentServer>
<targetDevice>PIC32MX795F512L</targetDevice>
<targetDevice>PIC32MZ2048EFM144</targetDevice>
<targetHeader></targetHeader>
<targetPluginBoard></targetPluginBoard>
<platformTool>PKOBSKDEPlatformTool</platformTool>

View File

@ -31,7 +31,7 @@
<conf name="default" type="2">
<toolsSet>
<developmentServer>localhost</developmentServer>
<targetDevice>PIC32MX795F512L</targetDevice>
<targetDevice>PIC32MZ2048EFM144</targetDevice>
<targetHeader></targetHeader>
<targetPluginBoard></targetPluginBoard>
<platformTool>PKOBSKDEPlatformTool</platformTool>

View File

@ -95,7 +95,7 @@
<conf name="default" type="3">
<toolsSet>
<developmentServer>localhost</developmentServer>
<targetDevice>PIC32MX795F512L</targetDevice>
<targetDevice>PIC32MZ2048EFM144</targetDevice>
<targetHeader></targetHeader>
<targetPluginBoard></targetPluginBoard>
<platformTool>PKOBSKDEPlatformTool</platformTool>

View File

@ -107,15 +107,12 @@ static int Pic32Crypto(const byte* in, int inLen, word32* out, int outLen,
sa_p = KVA0_TO_KVA1(&sa);
bd_p = KVA0_TO_KVA1(&bd);
out_p= KVA0_TO_KVA1(out);
if (in) {
in_p = KVA0_TO_KVA1(in);
/* Sync cache if in physical memory (not flash) */
if (PIC32MZ_IF_RAM(in_p)) {
XMEMCPY(in_p, in, inLen);
}
}
/* Set up the Security Association */
XMEMSET(sa_p, 0, sizeof(sa));
@ -215,7 +212,7 @@ static int Pic32Crypto(const byte* in, int inLen, word32* out, int outLen,
/* check for errors */
if (CESTATbits.ERROP || timeout <= 0) {
#if 1
#if 0
printf("PIC32 Crypto: ERROP %x, ERRPHASE %x, TIMEOUT %d\n",
CESTATbits.ERROP, CESTATbits.ERRPHASE, timeout);
#endif
@ -238,41 +235,209 @@ static int Pic32Crypto(const byte* in, int inLen, word32* out, int outLen,
}
}
if (outLen > 0) {
/* copy result to output */
#if PIC32_NO_OUT_SWAP
/* swap bytes */
ByteReverseWords(out, (word32*)out_p, outLen);
#else
#elif defined(_SYS_DEVCON_LOCAL_H)
/* sync cache */
#ifdef _SYS_DEVCON_LOCAL_H
SYS_DEVCON_DataCacheInvalidate((word32)out, outLen);
#else
XMEMCPY(out, out_p, outLen);
#endif
#endif
}
else {
/* sync cache */
#if PIC32_NO_OUT_SWAP
/* swap bytes */
ByteReverseWords(out, (word32*)out_p, PIC32_DIGEST_SIZE);
#else
/* sync cache */
#ifdef _SYS_DEVCON_LOCAL_H
SYS_DEVCON_DataCacheInvalidate((word32)out, PIC32_DIGEST_SIZE);
#else
XMEMCPY(out, out_p, PIC32_DIGEST_SIZE);
#endif
#endif
}
}
return ret;
}
#endif /* WOLFSSL_PIC32MZ_CRYPT || WOLFSSL_PIC32MZ_HASH */
#ifdef WOLFSSL_PIC32MZ_HASH
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
#ifndef PIC32_BLOCK_SIZE
#define PIC32_BLOCK_SIZE 2048
#endif
#define PIC32MZ_MIN_BLOCK 64
#define PIC32MZ_MAX_BLOCK (32*1024)
#ifndef PIC32MZ_MAX_BD
#define PIC32MZ_MAX_BD 2
#endif
#if PIC32_BLOCK_SIZE < PIC32MZ_MIN_BLOCK
#error Encryption block size must be at least 64 bytes.
#endif
/* Crypt Engine descriptor */
typedef struct {
int currBd;
int err;
unsigned int msgSize;
uint32_t processed;
uint32_t dbPtr;
int engine_ready;
volatile bufferDescriptor bd[PIC32MZ_MAX_BD] __attribute__((aligned (8)));
securityAssociation sa __attribute__((aligned (8)));
} pic32mz_desc;
static pic32mz_desc gLHDesc;
static uint8_t gLHDataBuf[PIC32MZ_MAX_BD][PIC32_BLOCK_SIZE] __attribute__((aligned (4), coherent));
static void reset_engine(pic32mz_desc *desc, int algo)
{
int i;
pic32mz_desc* uc_desc = KVA0_TO_KVA1(desc);
/* Software reset */
CECON = 1 << 6;
while (CECON);
/* Clear the interrupt flags */
CEINTSRC = 0xF;
/* Make sure everything is clear first before we setup */
XMEMSET(desc, 0, sizeof(pic32mz_desc));
XMEMSET((void *)&uc_desc->sa, 0, sizeof(uc_desc->sa));
/* Set up the Security Association */
uc_desc->sa.SA_CTRL.ALGO = algo;
uc_desc->sa.SA_CTRL.LNC = 1;
uc_desc->sa.SA_CTRL.FB = 1;
uc_desc->sa.SA_CTRL.ENCTYPE = 1;
uc_desc->sa.SA_CTRL.LOADIV = 1;
/* Set up the Buffer Descriptor */
uc_desc->err = 0;
for (i = 0; i < PIC32MZ_MAX_BD; i++) {
XMEMSET((void *)&uc_desc->bd[i], 0, sizeof(uc_desc->bd[i]));
uc_desc->bd[i].BD_CTRL.LAST_BD = 1;
uc_desc->bd[i].BD_CTRL.LIFM = 1;
uc_desc->bd[i].BD_CTRL.PKT_INT_EN = 1;
uc_desc->bd[i].SA_ADDR = KVA_TO_PA(&uc_desc->sa);
uc_desc->bd[i].SRCADDR = KVA_TO_PA(&gLHDataBuf[i]);
if (PIC32MZ_MAX_BD > i+1)
uc_desc->bd[i].NXTPTR = KVA_TO_PA(&uc_desc->bd[i+1]);
else
uc_desc->bd[i].NXTPTR = KVA_TO_PA(&uc_desc->bd[0]);
XMEMSET((void *)&gLHDataBuf[i], 0, PIC32_BLOCK_SIZE);
}
uc_desc->bd[0].BD_CTRL.SA_FETCH_EN = 1; /* Fetch the security association on the first BD */
desc->dbPtr = 0;
desc->currBd = 0;
desc->msgSize = 0;
desc->processed = 0;
CEBDPADDR = KVA_TO_PA(&(desc->bd[0]));
CEPOLLCON = 10;
#if PIC32_NO_OUT_SWAP
CECON = 0x27;
#else
CECON = 0xa7;
#endif
}
static void update_engine(pic32mz_desc *desc, const byte *input, word32 len,
word32 *hash)
{
int total;
pic32mz_desc *uc_desc = KVA0_TO_KVA1(desc);
uc_desc->bd[desc->currBd].UPDPTR = KVA_TO_PA(hash);
/* Add the data to the current buffer. If the buffer fills, start processing it
and fill the next one. */
while (len) {
/* If we've been given the message size, we can process along the
way.
Enable the current buffer descriptor if it is full. */
if (desc->dbPtr >= PIC32_BLOCK_SIZE) {
/* Wrap up the buffer descriptor and enable it so the engine can process */
uc_desc->bd[desc->currBd].MSGLEN = desc->msgSize;
uc_desc->bd[desc->currBd].BD_CTRL.BUFLEN = desc->dbPtr;
uc_desc->bd[desc->currBd].BD_CTRL.LAST_BD = 0;
uc_desc->bd[desc->currBd].BD_CTRL.LIFM = 0;
uc_desc->bd[desc->currBd].BD_CTRL.DESC_EN = 1;
/* Move to the next buffer descriptor, or wrap around. */
desc->currBd++;
if (desc->currBd >= PIC32MZ_MAX_BD)
desc->currBd = 0;
/* Wait until the engine has processed the new BD. */
while (uc_desc->bd[desc->currBd].BD_CTRL.DESC_EN);
uc_desc->bd[desc->currBd].UPDPTR = KVA_TO_PA(hash);
desc->dbPtr = 0;
}
if (!PIC32MZ_IF_RAM(input)) {
/* If we're inputting from flash, let the BD have
the address and max the buffer size */
uc_desc->bd[desc->currBd].SRCADDR = KVA_TO_PA(input);
total = (len > PIC32MZ_MAX_BLOCK ? PIC32MZ_MAX_BLOCK : len);
desc->dbPtr = total;
len -= total;
input += total;
}
else {
if (len > PIC32_BLOCK_SIZE - desc->dbPtr) {
/* We have more data than can be put in the buffer. Fill what we can.*/
total = PIC32_BLOCK_SIZE - desc->dbPtr;
XMEMCPY(&gLHDataBuf[desc->currBd][desc->dbPtr], input, total);
len -= total;
desc->dbPtr = PIC32_BLOCK_SIZE;
input += total;
}
else {
/* Fill up what we have, but don't turn on the engine.*/
XMEMCPY(&gLHDataBuf[desc->currBd][desc->dbPtr], input, len);
desc->dbPtr += len;
len = 0;
}
}
}
}
static void start_engine(pic32mz_desc *desc)
{
/* Wrap up the last buffer descriptor and enable it */
int i;
int bufferLen;
pic32mz_desc *uc_desc = KVA0_TO_KVA1(desc);
bufferLen = desc->dbPtr;
if (bufferLen % 4)
bufferLen = (bufferLen + 4) - (bufferLen % 4);
uc_desc->bd[desc->currBd].BD_CTRL.BUFLEN = bufferLen;
uc_desc->bd[desc->currBd].BD_CTRL.LAST_BD = 1;
uc_desc->bd[desc->currBd].BD_CTRL.LIFM = 1;
uc_desc->bd[desc->currBd].BD_CTRL.DESC_EN = 1;
}
void wait_engine(pic32mz_desc *desc, char *hash, int hash_sz)
{
int i;
pic32mz_desc *uc_desc = KVA0_TO_KVA1(desc);
unsigned int engineRunning;
do {
engineRunning = 0;
for (i = 0; i < PIC32MZ_MAX_BD; i++) {
engineRunning = engineRunning || uc_desc->bd[i].BD_CTRL.DESC_EN;
}
} while (engineRunning);
#if PIC32_NO_OUT_SWAP
/* swap bytes */
ByteReverseWords(hash, KVA0_TO_KVA1(hash), hash_sz);
#else
/* copy output - hardware already swapped */
XMEMCPY(hash, KVA0_TO_KVA1(hash), hash_sz);
#endif
}
#endif /* WOLFSSL_PIC32MZ_LARGE_HASH */
int wc_Pic32Hash(const byte* in, int inLen, word32* out, int outLen, int algo)
{
return Pic32Crypto(in, inLen, out, outLen, PIC32_ENCRYPTION, algo, 0,
@ -288,14 +453,28 @@ int wc_Pic32HashCopy(hashUpdCache* src, hashUpdCache* dst)
return 0;
}
static int wc_Pic32HashUpdate(hashUpdCache* cache, byte* stdBuf, word32 stdBufLen,
const byte* data, word32 len, void* heap)
static int wc_Pic32HashUpdate(hashUpdCache* cache, byte* stdBuf, int stdBufLen,
word32* digest, int digestSz, const byte* data, int len, int algo, void* heap)
{
/* cache updates */
int ret = 0;
word32 newLenUpd, newLenPad, padRemain;
byte* newBuf;
int isNewBuf = 0;
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
/* if final length is set then pass straight to hardware */
if (cache->finalLen) {
if (cache->bufLen == 0) {
reset_engine(&gLHDesc, algo);
gLHDesc.msgSize = cache->finalLen;
}
update_engine(&gLHDesc, data, len, digest);
cache->bufLen += len; /* track progress for blockType */
return 0;
}
#endif
/* cache updates */
/* calculate new len */
newLenUpd = cache->updLen + len;
@ -341,27 +520,38 @@ static int wc_Pic32HashUpdate(hashUpdCache* cache, byte* stdBuf, word32 stdBufLe
cache->updLen = newLenUpd;
cache->bufLen = newLenPad;
return 0;
return ret;
}
static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
int digestSz, int algo, void* heap)
static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf,
word32* digest, byte* hash, int digestSz, int algo, void* heap)
{
int ret;
word32 digest[PIC32_DIGEST_SIZE / sizeof(word32)] = {0};
int ret = 0;
/* if room add the pad */
if (cache->updLen < cache->bufLen) {
if (cache->buf && cache->updLen < cache->bufLen) {
cache->buf[cache->updLen] = 0x80;
}
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
if (cache->finalLen) {
start_engine(&gLHDesc);
wait_engine(&gLHDesc, (char*)digest, digestSz);
XMEMCPY(hash, digest, digestSz);
cache->finalLen = 0;
}
else
#endif
{
ret = wc_Pic32Hash(cache->buf, cache->updLen, digest, digestSz, algo);
if (ret == 0) {
XMEMCPY(hash, digest, digestSz);
}
if (cache->buf != stdBuf && !cache->isCopy) {
if (cache->buf && cache->buf != stdBuf && !cache->isCopy) {
XFREE(cache->buf, heap, DYNAMIC_TYPE_HASH_TMP);
}
}
cache->buf = NULL;
cache->bufLen = cache->updLen = 0;
@ -386,7 +576,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
if (md5 == NULL || (data == NULL && len > 0))
return BAD_FUNC_ARG;
return wc_Pic32HashUpdate(&md5->cache, (byte*)md5->buffer,
sizeof(md5->buffer), data, len, md5->heap);
sizeof(md5->buffer), md5->digest, MD5_DIGEST_SIZE,
data, len, PIC32_ALGO_MD5, md5->heap);
}
int wc_Md5Final(Md5* md5, byte* hash)
@ -397,7 +588,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
return BAD_FUNC_ARG;
ret = wc_Pic32HashFinal(&md5->cache, (byte*)md5->buffer,
hash, MD5_DIGEST_SIZE, PIC32_ALGO_MD5, md5->heap);
md5->digest, hash, MD5_DIGEST_SIZE,
PIC32_ALGO_MD5, md5->heap);
wc_InitMd5_ex(md5, md5->heap, INVALID_DEVID); /* reset state */
@ -406,8 +598,13 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
void wc_Md5SizeSet(Md5* md5, word32 len)
{
(void)md5;
if (md5) {
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
md5->cache.finalLen = len;
#else
(void)len;
#endif
}
}
#endif /* !NO_MD5 */
#ifndef NO_SHA
@ -427,7 +624,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
if (sha == NULL || (data == NULL && len > 0))
return BAD_FUNC_ARG;
return wc_Pic32HashUpdate(&sha->cache, (byte*)sha->buffer,
sizeof(sha->buffer), data, len, sha->heap);
sizeof(sha->buffer), sha->digest, SHA_DIGEST_SIZE,
data, len, PIC32_ALGO_SHA1, sha->heap);
}
int wc_ShaFinal(Sha* sha, byte* hash)
@ -438,7 +636,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
return BAD_FUNC_ARG;
ret = wc_Pic32HashFinal(&sha->cache, (byte*)sha->buffer,
hash, SHA_DIGEST_SIZE, PIC32_ALGO_SHA1, sha->heap);
sha->digest, hash, SHA_DIGEST_SIZE,
PIC32_ALGO_SHA1, sha->heap);
wc_InitSha_ex(sha, sha->heap, INVALID_DEVID); /* reset state */
@ -446,8 +645,13 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
}
void wc_ShaSizeSet(Sha* sha, word32 len)
{
(void)sha;
if (sha) {
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
sha->cache.finalLen = len;
#else
(void)len;
#endif
}
}
#endif /* !NO_SHA */
#ifndef NO_SHA256
@ -467,7 +671,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
if (sha256 == NULL || (data == NULL && len > 0))
return BAD_FUNC_ARG;
return wc_Pic32HashUpdate(&sha256->cache, (byte*)sha256->buffer,
sizeof(sha256->buffer), data, len, sha256->heap);
sizeof(sha256->buffer), sha256->digest, SHA256_DIGEST_SIZE,
data, len, PIC32_ALGO_SHA256, sha256->heap);
}
int wc_Sha256Final(Sha256* sha256, byte* hash)
@ -478,7 +683,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
return BAD_FUNC_ARG;
ret = wc_Pic32HashFinal(&sha256->cache, (byte*)sha256->buffer,
hash, SHA256_DIGEST_SIZE, PIC32_ALGO_SHA256, sha256->heap);
sha256->digest, hash, SHA256_DIGEST_SIZE,
PIC32_ALGO_SHA256, sha256->heap);
wc_InitSha256_ex(sha256, sha256->heap, INVALID_DEVID); /* reset state */
@ -487,8 +693,13 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
void wc_Sha256SizeSet(Sha256* sha256, word32 len)
{
(void)sha256;
if (sha256) {
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
sha256->cache.finalLen = len;
#else
(void)len;
#endif
}
}
#endif /* !NO_SHA256 */
#endif

View File

@ -1184,11 +1184,10 @@ int md2_test(void)
#ifndef NO_MD5
int md5_test(void)
{
int ret;
int ret = 0;
Md5 md5;
byte hash[MD5_DIGEST_SIZE];
byte hashcopy[MD5_DIGEST_SIZE];
testVector a, b, c, d, e;
testVector test_md5[5];
int times = sizeof(test_md5) / sizeof(testVector), i;
@ -1238,26 +1237,52 @@ int md5_test(void)
for (i = 0; i < times; ++i) {
ret = wc_Md5Update(&md5, (byte*)test_md5[i].input, (word32)test_md5[i].inLen);
if (ret != 0)
return -1510 - i;
ERROR_OUT(-1510 - i, exit);
ret = wc_Md5GetHash(&md5, hashcopy);
if (ret != 0)
return -1520 - i;
ERROR_OUT(-1520 - i, exit);
ret = wc_Md5Final(&md5, hash);
if (ret != 0)
return -1530 - i;
ERROR_OUT(-1530 - i, exit);
if (XMEMCMP(hash, test_md5[i].output, MD5_DIGEST_SIZE) != 0)
return -1540 - i;
ERROR_OUT(-1540 - i, exit);
if (XMEMCMP(hash, hashcopy, MD5_DIGEST_SIZE) != 0)
return -1550 - i;
ERROR_OUT(-1550 - i, exit);
}
/* BEGIN LARGE HASH TEST */ {
byte large_input[1024];
const char* large_digest =
"\x44\xd0\x88\xce\xf1\x36\xd1\x78\xe9\xc8\xba\x84\xc3\xfd\xf6\xca";
for (i = 0; i < (int)sizeof(large_input); i++) {
large_input[i] = (byte)(i & 0xFF);
}
times = 100;
#ifdef WOLFSSL_PIC32MZ_HASH
wc_Md5SizeSet(&md5, times * sizeof(large_input));
#endif
for (i = 0; i < times; ++i) {
ret = wc_Md5Update(&md5, (byte*)large_input, (word32)sizeof(large_input));
if (ret != 0)
ERROR_OUT(-1560, exit);
}
ret = wc_Md5Final(&md5, hash);
if (ret != 0)
ERROR_OUT(-1561, exit);
if (XMEMCMP(hash, large_digest, MD5_DIGEST_SIZE) != 0)
ERROR_OUT(-1562, exit);
} /* END LARGE HASH TEST */
exit:
wc_Md5Free(&md5);
return 0;
return ret;
}
#endif /* NO_MD5 */
@ -1344,13 +1369,12 @@ int md4_test(void)
int sha_test(void)
{
int ret = 0;
Sha sha;
byte hash[SHA_DIGEST_SIZE];
byte hashcopy[SHA_DIGEST_SIZE];
testVector a, b, c, d;
testVector test_sha[4];
int ret;
int times = sizeof(test_sha) / sizeof(struct testVector), i;
a.input = "abc";
@ -1392,26 +1416,53 @@ int sha_test(void)
for (i = 0; i < times; ++i) {
ret = wc_ShaUpdate(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen);
if (ret != 0)
return -1710 - i;
ERROR_OUT(-1710 - i, exit);
ret = wc_ShaGetHash(&sha, hashcopy);
if (ret != 0)
return -1720 - i;
ERROR_OUT(-1720 - i, exit);
ret = wc_ShaFinal(&sha, hash);
if (ret != 0)
return -1730 - i;
ERROR_OUT(-1730 - i, exit);
if (XMEMCMP(hash, test_sha[i].output, SHA_DIGEST_SIZE) != 0)
return -1740 - i;
ERROR_OUT(-1740 - i, exit);
if (XMEMCMP(hash, hashcopy, SHA_DIGEST_SIZE) != 0)
return -1750 - i;
ERROR_OUT(-1750 - i, exit);
}
/* BEGIN LARGE HASH TEST */ {
byte large_input[1024];
const char* large_digest =
"\x8b\x77\x02\x48\x39\xe8\xdb\xd3\x9a\xf4\x05\x24\x66\x12\x2d\x9e"
"\xc5\xd9\x0a\xac";
for (i = 0; i < (int)sizeof(large_input); i++) {
large_input[i] = (byte)(i & 0xFF);
}
times = 100;
#ifdef WOLFSSL_PIC32MZ_HASH
wc_ShaSizeSet(&sha, times * sizeof(large_input));
#endif
for (i = 0; i < times; ++i) {
ret = wc_ShaUpdate(&sha, (byte*)large_input, (word32)sizeof(large_input));
if (ret != 0)
ERROR_OUT(-1760, exit);
}
ret = wc_ShaFinal(&sha, hash);
if (ret != 0)
ERROR_OUT(-1761, exit);
if (XMEMCMP(hash, large_digest, SHA_DIGEST_SIZE) != 0)
ERROR_OUT(-1762, exit);
} /* END LARGE HASH TEST */
exit:
wc_ShaFree(&sha);
return 0;
return ret;
}
#endif /* NO_SHA */
@ -1615,13 +1666,12 @@ int sha224_test(void)
#ifndef NO_SHA256
int sha256_test(void)
{
int ret = 0;
Sha256 sha;
byte hash[SHA256_DIGEST_SIZE];
byte hashcopy[SHA256_DIGEST_SIZE];
testVector a, b;
testVector test_sha[2];
int ret;
int times = sizeof(test_sha) / sizeof(struct testVector), i;
a.input = "abc";
@ -1648,23 +1698,50 @@ int sha256_test(void)
for (i = 0; i < times; ++i) {
ret = wc_Sha256Update(&sha, (byte*)test_sha[i].input,(word32)test_sha[i].inLen);
if (ret != 0)
return -2110 - i;
ERROR_OUT(-2110 - i, exit);
ret = wc_Sha256GetHash(&sha, hashcopy);
if (ret != 0)
return -2120 - i;
ERROR_OUT(-2120 - i, exit);
ret = wc_Sha256Final(&sha, hash);
if (ret != 0)
return -2130 - i;
ERROR_OUT(-2130 - i, exit);
if (XMEMCMP(hash, test_sha[i].output, SHA256_DIGEST_SIZE) != 0)
return -2140 - i;
ERROR_OUT(-2140 - i, exit);
if (XMEMCMP(hash, hashcopy, SHA256_DIGEST_SIZE) != 0)
return -2150 - i;
ERROR_OUT(-2150 - i, exit);
}
/* BEGIN LARGE HASH TEST */ {
byte large_input[1024];
const char* large_digest =
"\x27\x78\x3e\x87\x96\x3a\x4e\xfb\x68\x29\xb5\x31\xc9\xba\x57\xb4"
"\x4f\x45\x79\x7f\x67\x70\xbd\x63\x7f\xbf\x0d\x80\x7c\xbd\xba\xe0";
for (i = 0; i < (int)sizeof(large_input); i++) {
large_input[i] = (byte)(i & 0xFF);
}
times = 100;
#ifdef WOLFSSL_PIC32MZ_HASH
wc_Sha256SizeSet(&sha, times * sizeof(large_input));
#endif
for (i = 0; i < times; ++i) {
ret = wc_Sha256Update(&sha, (byte*)large_input, (word32)sizeof(large_input));
if (ret != 0)
ERROR_OUT(-2160, exit);
}
ret = wc_Sha256Final(&sha, hash);
if (ret != 0)
ERROR_OUT(-2161, exit);
if (XMEMCMP(hash, large_digest, SHA256_DIGEST_SIZE) != 0)
ERROR_OUT(-2162, exit);
} /* END LARGE HASH TEST */
exit:
wc_Sha256Free(&sha);
return 0;
return ret;
}
#endif
@ -4641,11 +4718,12 @@ int aesgcm_test(void)
int alen, plen;
#if !defined(BENCH_EMBEDDED)
#define ENABLE_AESGCM_LARGE_TEST
#define LARGE_BUFFER_SIZE 1024
byte large_input[LARGE_BUFFER_SIZE];
byte large_output[LARGE_BUFFER_SIZE];
byte large_outdec[LARGE_BUFFER_SIZE];
#ifndef BENCH_AESGCM_LARGE
#define BENCH_AESGCM_LARGE 1024
#endif
byte large_input[BENCH_AESGCM_LARGE];
byte large_output[BENCH_AESGCM_LARGE];
byte large_outdec[BENCH_AESGCM_LARGE];
XMEMSET(large_input, 0, sizeof(large_input));
XMEMSET(large_output, 0, sizeof(large_output));
@ -4688,14 +4766,14 @@ int aesgcm_test(void)
return -4306;
/* Large buffer test */
#ifdef ENABLE_AESGCM_LARGE_TEST
#ifdef BENCH_AESGCM_LARGE
/* setup test buffer */
for (alen=0; alen<LARGE_BUFFER_SIZE; alen++)
for (alen=0; alen<BENCH_AESGCM_LARGE; alen++)
large_input[alen] = alen;
/* AES-GCM encrypt and decrypt both use AES encrypt internally */
result = wc_AesGcmEncrypt(&enc, large_output, large_input,
LARGE_BUFFER_SIZE, iv1, sizeof(iv1),
BENCH_AESGCM_LARGE, iv1, sizeof(iv1),
resultT, sizeof(resultT), a, sizeof(a));
#if defined(WOLFSSL_ASYNC_CRYPT)
result = wc_AsyncWait(result, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
@ -4704,16 +4782,16 @@ int aesgcm_test(void)
return -4307;
result = wc_AesGcmDecrypt(&enc, large_outdec, large_output,
LARGE_BUFFER_SIZE, iv1, sizeof(iv1), resultT,
BENCH_AESGCM_LARGE, iv1, sizeof(iv1), resultT,
sizeof(resultT), a, sizeof(a));
#if defined(WOLFSSL_ASYNC_CRYPT)
result = wc_AsyncWait(result, &enc.asyncDev, WC_ASYNC_FLAG_NONE);
#endif
if (result != 0)
return -4308;
if (XMEMCMP(large_input, large_outdec, LARGE_BUFFER_SIZE))
if (XMEMCMP(large_input, large_outdec, BENCH_AESGCM_LARGE))
return -4309;
#endif /* ENABLE_AESGCM_LARGE_TEST */
#endif /* BENCH_AESGCM_LARGE */
#if !defined(HAVE_FIPS) && !defined(STM32F2_CRYPTO) && !defined(STM32F4_CRYPTO)
/* Variable IV length test */

View File

@ -66,7 +66,11 @@ typedef struct Md5 {
word32 loLen; /* length in bytes */
word32 hiLen; /* length in bytes */
word32 buffer[MD5_BLOCK_SIZE / sizeof(word32)];
#ifdef WOLFSSL_PIC32MZ_HASH
word32 digest[PIC32_DIGEST_SIZE / sizeof(word32)];
#else
word32 digest[MD5_DIGEST_SIZE / sizeof(word32)];
#endif
void* heap;
#ifdef WOLFSSL_PIC32MZ_HASH
hashUpdCache cache; /* cache for updates */

View File

@ -46,6 +46,10 @@
#endif
#endif
/* Enables support for large hashing */
/* requires exclusive access to crypto hardware done at application layer */
#define WOLFSSL_PIC32MZ_LARGE_HASH
#include <xc.h>
#include <sys/endian.h>
@ -112,6 +116,9 @@ typedef struct hashUpdCache {
unsigned int bufLen;
unsigned int updLen;
int isCopy;
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
unsigned int finalLen;
#endif
} hashUpdCache;

View File

@ -71,7 +71,11 @@ typedef struct Sha {
word32 loLen; /* length in bytes */
word32 hiLen; /* length in bytes */
word32 buffer[SHA_BLOCK_SIZE / sizeof(word32)];
#ifdef WOLFSSL_PIC32MZ_HASH
word32 digest[PIC32_DIGEST_SIZE / sizeof(word32)];
#else
word32 digest[SHA_DIGEST_SIZE / sizeof(word32)];
#endif
void* heap;
#ifdef WOLFSSL_PIC32MZ_HASH
hashUpdCache cache; /* cache for updates */