Merge pull request #1110 from dgarske/pic32mz_largehash

Fixes for PIC32MZ to support large hashing using hardware
This commit is contained in:
toddouska
2017-08-22 09:24:05 -07:00
committed by GitHub
13 changed files with 901 additions and 284 deletions

View File

@ -59,6 +59,19 @@ int CRYPT_MD5_Initialize(CRYPT_MD5_CTX* md5)
return wc_InitMd5((Md5*)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);
#else
(void)sz;
#endif
return 0;
}
/* Add data to MD5 */ /* Add data to MD5 */
int CRYPT_MD5_DataAdd(CRYPT_MD5_CTX* md5, const unsigned char* input, int CRYPT_MD5_DataAdd(CRYPT_MD5_CTX* md5, const unsigned char* input,
@ -95,6 +108,19 @@ int CRYPT_SHA_Initialize(CRYPT_SHA_CTX* sha)
return wc_InitSha((Sha*)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);
#else
(void)sz;
#endif
return 0;
}
/* Add data to SHA */ /* Add data to SHA */
int CRYPT_SHA_DataAdd(CRYPT_SHA_CTX* sha, const unsigned char* input, int CRYPT_SHA_DataAdd(CRYPT_SHA_CTX* sha, const unsigned char* input,
@ -131,6 +157,19 @@ int CRYPT_SHA256_Initialize(CRYPT_SHA256_CTX* sha256)
return wc_InitSha256((Sha256*)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);
#else
(void)sz;
#endif
return 0;
}
/* Add data to SHA-256 */ /* Add data to SHA-256 */
int CRYPT_SHA256_DataAdd(CRYPT_SHA256_CTX* sha256, const unsigned char* input, int CRYPT_SHA256_DataAdd(CRYPT_SHA256_CTX* sha256, const unsigned char* input,

View File

@ -40,6 +40,7 @@ typedef struct CRYPT_MD5_CTX {
int CRYPT_MD5_Initialize(CRYPT_MD5_CTX*); int CRYPT_MD5_Initialize(CRYPT_MD5_CTX*);
int CRYPT_MD5_DataAdd(CRYPT_MD5_CTX*, const unsigned char*, unsigned int); int CRYPT_MD5_DataAdd(CRYPT_MD5_CTX*, const unsigned char*, unsigned int);
int CRYPT_MD5_Finalize(CRYPT_MD5_CTX*, unsigned char*); int CRYPT_MD5_Finalize(CRYPT_MD5_CTX*, unsigned char*);
int CRYPT_MD5_DataSizeSet(CRYPT_MD5_CTX* md5, unsigned int sz);
enum { enum {
CRYPT_MD5_DIGEST_SIZE = 16 CRYPT_MD5_DIGEST_SIZE = 16
@ -54,6 +55,7 @@ typedef struct CRYPT_SHA_CTX {
int CRYPT_SHA_Initialize(CRYPT_SHA_CTX*); int CRYPT_SHA_Initialize(CRYPT_SHA_CTX*);
int CRYPT_SHA_DataAdd(CRYPT_SHA_CTX*, const unsigned char*, unsigned int); int CRYPT_SHA_DataAdd(CRYPT_SHA_CTX*, const unsigned char*, unsigned int);
int CRYPT_SHA_Finalize(CRYPT_SHA_CTX*, unsigned char*); int CRYPT_SHA_Finalize(CRYPT_SHA_CTX*, unsigned char*);
int CRYPT_SHA_DataSizeSet(CRYPT_SHA_CTX* sha, unsigned int sz);
enum { enum {
CRYPT_SHA_DIGEST_SIZE = 20 CRYPT_SHA_DIGEST_SIZE = 20
@ -68,6 +70,7 @@ typedef struct CRYPT_SHA256_CTX {
int CRYPT_SHA256_Initialize(CRYPT_SHA256_CTX*); int CRYPT_SHA256_Initialize(CRYPT_SHA256_CTX*);
int CRYPT_SHA256_DataAdd(CRYPT_SHA256_CTX*, const unsigned char*, unsigned int); int CRYPT_SHA256_DataAdd(CRYPT_SHA256_CTX*, const unsigned char*, unsigned int);
int CRYPT_SHA256_Finalize(CRYPT_SHA256_CTX*, unsigned char*); int CRYPT_SHA256_Finalize(CRYPT_SHA256_CTX*, unsigned char*);
int CRYPT_SHA256_DataSizeSet(CRYPT_SHA256_CTX* sha256, unsigned int sz);
enum { enum {
CRYPT_SHA256_DIGEST_SIZE = 32 CRYPT_SHA256_DIGEST_SIZE = 32

View File

@ -112,13 +112,13 @@ extern "C" {
#ifdef USE_FAST_MATH #ifdef USE_FAST_MATH
/* Maximum math bits (Max RSA key bits * 2) */ /* Maximum math bits (Max RSA key bits * 2) */
#undef FP_MAX_BITS #undef FP_MAX_BITS
#define FP_MAX_BITS 2048 #define FP_MAX_BITS 4096
#endif #endif
/* half as much memory but twice as slow */ /* half as much memory but twice as slow */
#undef RSA_LOW_MEM #undef RSA_LOW_MEM
//#define RSA_LOW_MEM //#define RSA_LOW_MEM
/* timing resistance */ /* timing resistance */
#undef WC_RSA_BLINDING #undef WC_RSA_BLINDING
#define WC_RSA_BLINDING #define WC_RSA_BLINDING
@ -237,10 +237,10 @@ extern "C" {
#define BENCH_EMBEDDED #define BENCH_EMBEDDED
#undef USE_CERT_BUFFERS_2048 #undef USE_CERT_BUFFERS_2048
//#define USE_CERT_BUFFERS_2048 #define USE_CERT_BUFFERS_2048
#undef USE_CERT_BUFFERS_1024 #undef USE_CERT_BUFFERS_1024
#define USE_CERT_BUFFERS_1024 //#define USE_CERT_BUFFERS_1024
#undef USE_CERT_BUFFERS_256 #undef USE_CERT_BUFFERS_256
#define USE_CERT_BUFFERS_256 #define USE_CERT_BUFFERS_256

View File

@ -112,13 +112,13 @@ extern "C" {
#ifdef USE_FAST_MATH #ifdef USE_FAST_MATH
/* Maximum math bits (Max RSA key bits * 2) */ /* Maximum math bits (Max RSA key bits * 2) */
#undef FP_MAX_BITS #undef FP_MAX_BITS
#define FP_MAX_BITS 2048 #define FP_MAX_BITS 4096
#endif #endif
/* half as much memory but twice as slow */ /* half as much memory but twice as slow */
#undef RSA_LOW_MEM #undef RSA_LOW_MEM
//#define RSA_LOW_MEM //#define RSA_LOW_MEM
/* timing resistance */ /* timing resistance */
#undef WC_RSA_BLINDING #undef WC_RSA_BLINDING
#define WC_RSA_BLINDING #define WC_RSA_BLINDING
@ -237,10 +237,10 @@ extern "C" {
#define BENCH_EMBEDDED #define BENCH_EMBEDDED
#undef USE_CERT_BUFFERS_2048 #undef USE_CERT_BUFFERS_2048
//#define USE_CERT_BUFFERS_2048 #define USE_CERT_BUFFERS_2048
#undef USE_CERT_BUFFERS_1024 #undef USE_CERT_BUFFERS_1024
#define USE_CERT_BUFFERS_1024 //#define USE_CERT_BUFFERS_1024
#undef USE_CERT_BUFFERS_256 #undef USE_CERT_BUFFERS_256
#define USE_CERT_BUFFERS_256 #define USE_CERT_BUFFERS_256

View File

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

View File

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

View File

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

View File

@ -107,14 +107,11 @@ static int Pic32Crypto(const byte* in, int inLen, word32* out, int outLen,
sa_p = KVA0_TO_KVA1(&sa); sa_p = KVA0_TO_KVA1(&sa);
bd_p = KVA0_TO_KVA1(&bd); bd_p = KVA0_TO_KVA1(&bd);
out_p= KVA0_TO_KVA1(out); out_p= KVA0_TO_KVA1(out);
in_p = KVA0_TO_KVA1(in);
if (in) { /* Sync cache if in physical memory (not flash) */
in_p = KVA0_TO_KVA1(in); if (PIC32MZ_IF_RAM(in_p)) {
XMEMCPY(in_p, in, inLen);
/* Sync cache if in physical memory (not flash) */
if (PIC32MZ_IF_RAM(in_p)) {
XMEMCPY(in_p, in, inLen);
}
} }
/* Set up the Security Association */ /* Set up the Security Association */
@ -196,6 +193,9 @@ static int Pic32Crypto(const byte* in, int inLen, word32* out, int outLen,
CECON = 1 << 6; CECON = 1 << 6;
while (CECON); while (CECON);
/* Clear the interrupt flags */
CEINTSRC = 0xF;
/* Run the engine */ /* Run the engine */
CEBDPADDR = (unsigned int)KVA_TO_PA(&bd); CEBDPADDR = (unsigned int)KVA_TO_PA(&bd);
CEINTEN = 0x07; /* enable DMA Packet Completion Interrupt */ CEINTEN = 0x07; /* enable DMA Packet Completion Interrupt */
@ -215,7 +215,7 @@ static int Pic32Crypto(const byte* in, int inLen, word32* out, int outLen,
/* check for errors */ /* check for errors */
if (CESTATbits.ERROP || timeout <= 0) { if (CESTATbits.ERROP || timeout <= 0) {
#if 1 #if 0
printf("PIC32 Crypto: ERROP %x, ERRPHASE %x, TIMEOUT %d\n", printf("PIC32 Crypto: ERROP %x, ERRPHASE %x, TIMEOUT %d\n",
CESTATbits.ERROP, CESTATbits.ERRPHASE, timeout); CESTATbits.ERROP, CESTATbits.ERRPHASE, timeout);
#endif #endif
@ -238,41 +238,214 @@ static int Pic32Crypto(const byte* in, int inLen, word32* out, int outLen,
} }
} }
if (outLen > 0) { /* copy result to output */
/* copy result to output */ #if PIC32_NO_OUT_SWAP
#if PIC32_NO_OUT_SWAP /* swap bytes */
/* swap bytes */ ByteReverseWords(out, (word32*)out_p, outLen);
ByteReverseWords(out, (word32*)out_p, outLen); #elif defined(_SYS_DEVCON_LOCAL_H)
#else /* sync cache */
/* sync cache */ SYS_DEVCON_DataCacheInvalidate((word32)out, outLen);
#ifdef _SYS_DEVCON_LOCAL_H #else
SYS_DEVCON_DataCacheInvalidate((word32)out, outLen); XMEMCPY(out, out_p, outLen);
#else #endif
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; return ret;
} }
#endif /* WOLFSSL_PIC32MZ_CRYPT || WOLFSSL_PIC32MZ_HASH */ #endif /* WOLFSSL_PIC32MZ_CRYPT || WOLFSSL_PIC32MZ_HASH */
#ifdef WOLFSSL_PIC32MZ_HASH #ifdef WOLFSSL_PIC32MZ_HASH
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
/* tunable large hash block size */
#ifndef PIC32_BLOCK_SIZE
#define PIC32_BLOCK_SIZE 256
#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);
wolfSSL_CryptHwMutexLock();
/* 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
wolfSSL_CryptHwMutexUnLock();
}
#endif /* WOLFSSL_PIC32MZ_LARGE_HASH */
int wc_Pic32Hash(const byte* in, int inLen, word32* out, int outLen, int algo) int wc_Pic32Hash(const byte* in, int inLen, word32* out, int outLen, int algo)
{ {
return Pic32Crypto(in, inLen, out, outLen, PIC32_ENCRYPTION, algo, 0, return Pic32Crypto(in, inLen, out, outLen, PIC32_ENCRYPTION, algo, 0,
@ -288,14 +461,28 @@ int wc_Pic32HashCopy(hashUpdCache* src, hashUpdCache* dst)
return 0; return 0;
} }
static int wc_Pic32HashUpdate(hashUpdCache* cache, byte* stdBuf, word32 stdBufLen, static int wc_Pic32HashUpdate(hashUpdCache* cache, byte* stdBuf, int stdBufLen,
const byte* data, word32 len, void* heap) word32* digest, int digestSz, const byte* data, int len, int algo, void* heap)
{ {
/* cache updates */ int ret = 0;
word32 newLenUpd, newLenPad, padRemain; word32 newLenUpd, newLenPad, padRemain;
byte* newBuf; byte* newBuf;
int isNewBuf = 0; 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 */ /* calculate new len */
newLenUpd = cache->updLen + len; newLenUpd = cache->updLen + len;
@ -341,27 +528,68 @@ static int wc_Pic32HashUpdate(hashUpdCache* cache, byte* stdBuf, word32 stdBufLe
cache->updLen = newLenUpd; cache->updLen = newLenUpd;
cache->bufLen = newLenPad; cache->bufLen = newLenPad;
return 0; return ret;
} }
static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash, static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf,
int digestSz, int algo, void* heap) word32* digest, byte* hash, int digestSz, int algo, void* heap)
{ {
int ret; int ret = 0;
word32 digest[PIC32_DIGEST_SIZE / sizeof(word32)] = {0};
/* if room add the pad */ /* if room add the pad */
if (cache->updLen < cache->bufLen) { if (cache->buf && cache->updLen < cache->bufLen) {
cache->buf[cache->updLen] = 0x80; cache->buf[cache->updLen] = 0x80;
} }
ret = wc_Pic32Hash(cache->buf, cache->updLen, digest, digestSz, algo); #ifdef WOLFSSL_PIC32MZ_LARGE_HASH
if (ret == 0) { if (cache->finalLen) {
start_engine(&gLHDesc);
wait_engine(&gLHDesc, (char*)digest, digestSz);
XMEMCPY(hash, digest, digestSz); XMEMCPY(hash, digest, digestSz);
cache->finalLen = 0;
} }
if (cache->buf != stdBuf && !cache->isCopy) { else
XFREE(cache->buf, heap, DYNAMIC_TYPE_HASH_TMP); #endif
{
if (cache->updLen == 0) {
/* handle empty input */
switch (algo) {
case PIC32_ALGO_SHA256: {
const char* sha256EmptyHash =
"\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9"
"\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52"
"\xb8\x55";
XMEMCPY(hash, sha256EmptyHash, digestSz);
break;
}
case PIC32_ALGO_SHA1: {
const char* shaEmptyHash =
"\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18"
"\x90\xaf\xd8\x07\x09";
XMEMCPY(hash, shaEmptyHash, digestSz);
break;
}
case PIC32_ALGO_MD5: {
const char* md5EmptyHash =
"\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42"
"\x7e";
XMEMCPY(hash, md5EmptyHash, digestSz);
break;
}
} /* switch */
}
else {
ret = wc_Pic32Hash(cache->buf, cache->updLen, digest, digestSz, algo);
if (ret == 0) {
XMEMCPY(hash, digest, digestSz);
}
}
if (cache->buf && cache->buf != stdBuf && !cache->isCopy) {
XFREE(cache->buf, heap, DYNAMIC_TYPE_HASH_TMP);
}
} }
cache->buf = NULL; cache->buf = NULL;
cache->bufLen = cache->updLen = 0; cache->bufLen = cache->updLen = 0;
@ -386,7 +614,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
if (md5 == NULL || (data == NULL && len > 0)) if (md5 == NULL || (data == NULL && len > 0))
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
return wc_Pic32HashUpdate(&md5->cache, (byte*)md5->buffer, 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) int wc_Md5Final(Md5* md5, byte* hash)
@ -397,7 +626,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
ret = wc_Pic32HashFinal(&md5->cache, (byte*)md5->buffer, 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 */ wc_InitMd5_ex(md5, md5->heap, INVALID_DEVID); /* reset state */
@ -406,8 +636,13 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
void wc_Md5SizeSet(Md5* md5, word32 len) void wc_Md5SizeSet(Md5* md5, word32 len)
{ {
(void)md5; if (md5) {
(void)len; #ifdef WOLFSSL_PIC32MZ_LARGE_HASH
md5->cache.finalLen = len;
#else
(void)len;
#endif
}
} }
#endif /* !NO_MD5 */ #endif /* !NO_MD5 */
#ifndef NO_SHA #ifndef NO_SHA
@ -427,7 +662,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
if (sha == NULL || (data == NULL && len > 0)) if (sha == NULL || (data == NULL && len > 0))
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
return wc_Pic32HashUpdate(&sha->cache, (byte*)sha->buffer, 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) int wc_ShaFinal(Sha* sha, byte* hash)
@ -438,7 +674,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
ret = wc_Pic32HashFinal(&sha->cache, (byte*)sha->buffer, 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 */ wc_InitSha_ex(sha, sha->heap, INVALID_DEVID); /* reset state */
@ -446,8 +683,13 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
} }
void wc_ShaSizeSet(Sha* sha, word32 len) void wc_ShaSizeSet(Sha* sha, word32 len)
{ {
(void)sha; if (sha) {
(void)len; #ifdef WOLFSSL_PIC32MZ_LARGE_HASH
sha->cache.finalLen = len;
#else
(void)len;
#endif
}
} }
#endif /* !NO_SHA */ #endif /* !NO_SHA */
#ifndef NO_SHA256 #ifndef NO_SHA256
@ -467,7 +709,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
if (sha256 == NULL || (data == NULL && len > 0)) if (sha256 == NULL || (data == NULL && len > 0))
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
return wc_Pic32HashUpdate(&sha256->cache, (byte*)sha256->buffer, 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) int wc_Sha256Final(Sha256* sha256, byte* hash)
@ -478,7 +721,8 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
ret = wc_Pic32HashFinal(&sha256->cache, (byte*)sha256->buffer, 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 */ wc_InitSha256_ex(sha256, sha256->heap, INVALID_DEVID); /* reset state */
@ -487,8 +731,13 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf, byte* hash,
void wc_Sha256SizeSet(Sha256* sha256, word32 len) void wc_Sha256SizeSet(Sha256* sha256, word32 len)
{ {
(void)sha256; if (sha256) {
(void)len; #ifdef WOLFSSL_PIC32MZ_LARGE_HASH
sha256->cache.finalLen = len;
#else
(void)len;
#endif
}
} }
#endif /* !NO_SHA256 */ #endif /* !NO_SHA256 */
#endif #endif

View File

@ -291,14 +291,14 @@ int wc_InitRsaHw(RsaKey* key)
} }
if (mp_to_unsigned_bin(&(key->n), m) != MP_OKAY) { if (mp_to_unsigned_bin(&(key->n), m) != MP_OKAY) {
WOLFSSL_MSG("Unable to get RSA key modulous"); WOLFSSL_MSG("Unable to get RSA key modulus");
XFREE(m, key->heap, DYNAMIC_TYPE_KEY); XFREE(m, key->heap, DYNAMIC_TYPE_KEY);
return MP_READ_E; return MP_READ_E;
} }
eSz = mp_unsigned_bin_size(&(key->e)); eSz = mp_unsigned_bin_size(&(key->e));
if (eSz > MAX_E_SIZE) { if (eSz > MAX_E_SIZE) {
WOLFSSL_MSG("Expnonent of size 4 bytes expected"); WOLFSSL_MSG("Exponent of size 4 bytes expected");
XFREE(m, key->heap, DYNAMIC_TYPE_KEY); XFREE(m, key->heap, DYNAMIC_TYPE_KEY);
return BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
@ -582,7 +582,7 @@ static int RsaPad_OAEP(const byte* input, word32 inputLen, byte* pkcsBlock,
/* handles check of location for idx as well as psLen, cast to int to check /* handles check of location for idx as well as psLen, cast to int to check
for pkcsBlockLen(k) - 2 * hLen - 2 being negative for pkcsBlockLen(k) - 2 * hLen - 2 being negative
This check is similar to decryption where k > 2 * hLen + 2 as msg This check is similar to decryption where k > 2 * hLen + 2 as msg
size aproaches 0. In decryption if k is less than or equal -- then there size approaches 0. In decryption if k is less than or equal -- then there
is no possible room for msg. is no possible room for msg.
k = RSA key size k = RSA key size
hLen = hash digest size -- will always be >= 0 at this point hLen = hash digest size -- will always be >= 0 at this point
@ -902,7 +902,7 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
idx = hLen + 1 + hLen; idx = hLen + 1 + hLen;
while (idx < pkcsBlockLen && pkcsBlock[idx] == 0) {idx++;} while (idx < pkcsBlockLen && pkcsBlock[idx] == 0) {idx++;}
/* create hash of label for comparision with hash sent */ /* create hash of label for comparison with hash sent */
if ((ret = wc_Hash(hType, optLabel, labelLen, h, hLen)) != 0) { if ((ret = wc_Hash(hType, optLabel, labelLen, h, hLen)) != 0) {
return ret; return ret;
} }
@ -919,6 +919,7 @@ static int RsaUnPad_OAEP(byte *pkcsBlock, unsigned int pkcsBlockLen,
ret += pkcsBlock[0] ^ 0x00; /* Y, the first value, should be 0 */ ret += pkcsBlock[0] ^ 0x00; /* Y, the first value, should be 0 */
if (ret != 0) { if (ret != 0) {
WOLFSSL_MSG("RsaUnPad_OAEP: Padding Error");
return BAD_PADDING_E; return BAD_PADDING_E;
} }
@ -941,8 +942,10 @@ static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
if (hLen < 0) if (hLen < 0)
return hLen; return hLen;
if (pkcsBlock[pkcsBlockLen - 1] != 0xbc) if (pkcsBlock[pkcsBlockLen - 1] != 0xbc) {
WOLFSSL_MSG("RsaUnPad_PSS: Padding Error 0xBC");
return BAD_PADDING_E; return BAD_PADDING_E;
}
tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_RSA_BUFFER); tmp = (byte*)XMALLOC(pkcsBlockLen, heap, DYNAMIC_TYPE_RSA_BUFFER);
if (tmp == NULL) { if (tmp == NULL) {
@ -959,11 +962,13 @@ static int RsaUnPad_PSS(byte *pkcsBlock, unsigned int pkcsBlockLen,
for (i = 0; i < (int)(pkcsBlockLen - 1 - hLen - hLen - 1); i++) { for (i = 0; i < (int)(pkcsBlockLen - 1 - hLen - hLen - 1); i++) {
if (tmp[i] != pkcsBlock[i]) { if (tmp[i] != pkcsBlock[i]) {
XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);
WOLFSSL_MSG("RsaUnPad_PSS: Padding Error Match");
return BAD_PADDING_E; return BAD_PADDING_E;
} }
} }
if (tmp[i] != (pkcsBlock[i] ^ 0x01)) { if (tmp[i] != (pkcsBlock[i] ^ 0x01)) {
XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER); XFREE(tmp, heap, DYNAMIC_TYPE_RSA_BUFFER);
WOLFSSL_MSG("RsaUnPad_PSS: Padding Error End");
return BAD_PADDING_E; return BAD_PADDING_E;
} }
for (i++; i < (int)(pkcsBlockLen - 1 - hLen); i++) for (i++; i < (int)(pkcsBlockLen - 1 - hLen); i++)
@ -1780,8 +1785,10 @@ int wc_RsaPSS_CheckPadding(const byte* in, word32 inSz, byte* sig,
ret = wc_Hash(hashType, sig, RSA_PSS_PAD_SZ + inSz * 2, sig, inSz); ret = wc_Hash(hashType, sig, RSA_PSS_PAD_SZ + inSz * 2, sig, inSz);
if (ret != 0) if (ret != 0)
return ret; return ret;
if (XMEMCMP(sig, sig + RSA_PSS_PAD_SZ + inSz * 2, inSz) != 0) if (XMEMCMP(sig, sig + RSA_PSS_PAD_SZ + inSz * 2, inSz) != 0) {
WOLFSSL_MSG("RsaPSS_CheckPadding: Padding Error");
ret = BAD_PADDING_E; ret = BAD_PADDING_E;
}
else else
ret = 0; ret = 0;
} }

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -46,6 +46,10 @@
#endif #endif
#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 <xc.h>
#include <sys/endian.h> #include <sys/endian.h>
@ -112,6 +116,9 @@ typedef struct hashUpdCache {
unsigned int bufLen; unsigned int bufLen;
unsigned int updLen; unsigned int updLen;
int isCopy; int isCopy;
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
unsigned int finalLen;
#endif
} hashUpdCache; } hashUpdCache;

View File

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