mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-30 18:57:27 +02:00
Merge pull request #2923 from dgarske/pic32mz
Fixes for PIC32MZ crypto hardware cache and large hash
This commit is contained in:
@ -301,13 +301,12 @@ typedef struct {
|
|||||||
securityAssociation sa __attribute__((aligned (8)));
|
securityAssociation sa __attribute__((aligned (8)));
|
||||||
} pic32mz_desc;
|
} pic32mz_desc;
|
||||||
|
|
||||||
static pic32mz_desc gLHDesc;
|
static pic32mz_desc gLHDesc __attribute__((coherent));
|
||||||
static uint8_t gLHDataBuf[PIC32MZ_MAX_BD][PIC32_BLOCK_SIZE] __attribute__((aligned (4), coherent));
|
static uint8_t gLHDataBuf[PIC32MZ_MAX_BD][PIC32_BLOCK_SIZE] __attribute__((aligned (4), coherent));
|
||||||
|
|
||||||
static void reset_engine(pic32mz_desc *desc, int algo)
|
static void reset_engine(int algo)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
pic32mz_desc* uc_desc = KVA0_TO_KVA1(desc);
|
|
||||||
|
|
||||||
wolfSSL_CryptHwMutexLock();
|
wolfSSL_CryptHwMutexLock();
|
||||||
|
|
||||||
@ -319,37 +318,36 @@ static void reset_engine(pic32mz_desc *desc, int algo)
|
|||||||
CEINTSRC = 0xF;
|
CEINTSRC = 0xF;
|
||||||
|
|
||||||
/* Make sure everything is clear first before we setup */
|
/* Make sure everything is clear first before we setup */
|
||||||
XMEMSET(desc, 0, sizeof(pic32mz_desc));
|
XMEMSET(&gLHDesc, 0, sizeof(pic32mz_desc));
|
||||||
XMEMSET((void *)&uc_desc->sa, 0, sizeof(uc_desc->sa));
|
|
||||||
|
|
||||||
/* Set up the Security Association */
|
/* Set up the Security Association */
|
||||||
uc_desc->sa.SA_CTRL.ALGO = algo;
|
gLHDesc.sa.SA_CTRL.ALGO = algo;
|
||||||
uc_desc->sa.SA_CTRL.LNC = 1;
|
gLHDesc.sa.SA_CTRL.LNC = 1;
|
||||||
uc_desc->sa.SA_CTRL.FB = 1;
|
gLHDesc.sa.SA_CTRL.FB = 1;
|
||||||
uc_desc->sa.SA_CTRL.ENCTYPE = 1;
|
gLHDesc.sa.SA_CTRL.ENCTYPE = 1;
|
||||||
uc_desc->sa.SA_CTRL.LOADIV = 1;
|
gLHDesc.sa.SA_CTRL.LOADIV = 1;
|
||||||
|
|
||||||
/* Set up the Buffer Descriptor */
|
/* Set up the Buffer Descriptor */
|
||||||
uc_desc->err = 0;
|
gLHDesc.err = 0;
|
||||||
for (i = 0; i < PIC32MZ_MAX_BD; i++) {
|
for (i = 0; i < PIC32MZ_MAX_BD; i++) {
|
||||||
XMEMSET((void *)&uc_desc->bd[i], 0, sizeof(uc_desc->bd[i]));
|
XMEMSET((void *)&gLHDesc.bd[i], 0, sizeof(gLHDesc.bd[i]));
|
||||||
uc_desc->bd[i].BD_CTRL.LAST_BD = 1;
|
gLHDesc.bd[i].BD_CTRL.LAST_BD = 1;
|
||||||
uc_desc->bd[i].BD_CTRL.LIFM = 1;
|
gLHDesc.bd[i].BD_CTRL.LIFM = 1;
|
||||||
uc_desc->bd[i].BD_CTRL.PKT_INT_EN = 1;
|
gLHDesc.bd[i].BD_CTRL.PKT_INT_EN = 1;
|
||||||
uc_desc->bd[i].SA_ADDR = KVA_TO_PA(&uc_desc->sa);
|
gLHDesc.bd[i].SA_ADDR = KVA_TO_PA(&gLHDesc.sa);
|
||||||
uc_desc->bd[i].SRCADDR = KVA_TO_PA(&gLHDataBuf[i]);
|
gLHDesc.bd[i].SRCADDR = KVA_TO_PA(&gLHDataBuf[i]);
|
||||||
if (PIC32MZ_MAX_BD > i+1)
|
if (PIC32MZ_MAX_BD > i+1)
|
||||||
uc_desc->bd[i].NXTPTR = KVA_TO_PA(&uc_desc->bd[i+1]);
|
gLHDesc.bd[i].NXTPTR = KVA_TO_PA(&gLHDesc.bd[i+1]);
|
||||||
else
|
else
|
||||||
uc_desc->bd[i].NXTPTR = KVA_TO_PA(&uc_desc->bd[0]);
|
gLHDesc.bd[i].NXTPTR = KVA_TO_PA(&gLHDesc.bd[0]);
|
||||||
XMEMSET((void *)&gLHDataBuf[i], 0, PIC32_BLOCK_SIZE);
|
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 */
|
gLHDesc.bd[0].BD_CTRL.SA_FETCH_EN = 1; /* Fetch the security association on the first BD */
|
||||||
desc->dbPtr = 0;
|
gLHDesc.dbPtr = 0;
|
||||||
desc->currBd = 0;
|
gLHDesc.currBd = 0;
|
||||||
desc->msgSize = 0;
|
gLHDesc.msgSize = 0;
|
||||||
desc->processed = 0;
|
gLHDesc.processed = 0;
|
||||||
CEBDPADDR = KVA_TO_PA(&(desc->bd[0]));
|
CEBDPADDR = KVA_TO_PA(&(gLHDesc.bd[0]));
|
||||||
|
|
||||||
CEPOLLCON = 10;
|
CEPOLLCON = 10;
|
||||||
|
|
||||||
@ -360,13 +358,11 @@ static void reset_engine(pic32mz_desc *desc, int algo)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_engine(pic32mz_desc *desc, const byte *input, word32 len,
|
static void update_engine(const byte *input, word32 len, word32 *hash)
|
||||||
word32 *hash)
|
|
||||||
{
|
{
|
||||||
int total;
|
int total;
|
||||||
pic32mz_desc *uc_desc = KVA0_TO_KVA1(desc);
|
|
||||||
|
gLHDesc.bd[gLHDesc.currBd].UPDPTR = KVA_TO_PA(hash);
|
||||||
uc_desc->bd[desc->currBd].UPDPTR = KVA_TO_PA(hash);
|
|
||||||
|
|
||||||
/* Add the data to the current buffer. If the buffer fills, start processing it
|
/* Add the data to the current buffer. If the buffer fills, start processing it
|
||||||
and fill the next one. */
|
and fill the next one. */
|
||||||
@ -374,78 +370,76 @@ static void update_engine(pic32mz_desc *desc, const byte *input, word32 len,
|
|||||||
/* If we've been given the message size, we can process along the
|
/* If we've been given the message size, we can process along the
|
||||||
way.
|
way.
|
||||||
Enable the current buffer descriptor if it is full. */
|
Enable the current buffer descriptor if it is full. */
|
||||||
if (desc->dbPtr >= PIC32_BLOCK_SIZE) {
|
if (gLHDesc.dbPtr >= PIC32_BLOCK_SIZE) {
|
||||||
/* Wrap up the buffer descriptor and enable it so the engine can process */
|
/* Wrap up the buffer descriptor and enable it so the engine can process */
|
||||||
uc_desc->bd[desc->currBd].MSGLEN = desc->msgSize;
|
gLHDesc.bd[gLHDesc.currBd].MSGLEN = gLHDesc.msgSize;
|
||||||
uc_desc->bd[desc->currBd].BD_CTRL.BUFLEN = desc->dbPtr;
|
gLHDesc.bd[gLHDesc.currBd].BD_CTRL.BUFLEN = gLHDesc.dbPtr;
|
||||||
uc_desc->bd[desc->currBd].BD_CTRL.LAST_BD = 0;
|
gLHDesc.bd[gLHDesc.currBd].BD_CTRL.LAST_BD = 0;
|
||||||
uc_desc->bd[desc->currBd].BD_CTRL.LIFM = 0;
|
gLHDesc.bd[gLHDesc.currBd].BD_CTRL.LIFM = 0;
|
||||||
uc_desc->bd[desc->currBd].BD_CTRL.DESC_EN = 1;
|
gLHDesc.bd[gLHDesc.currBd].BD_CTRL.DESC_EN = 1;
|
||||||
/* Move to the next buffer descriptor, or wrap around. */
|
/* Move to the next buffer descriptor, or wrap around. */
|
||||||
desc->currBd++;
|
gLHDesc.currBd++;
|
||||||
if (desc->currBd >= PIC32MZ_MAX_BD)
|
if (gLHDesc.currBd >= PIC32MZ_MAX_BD)
|
||||||
desc->currBd = 0;
|
gLHDesc.currBd = 0;
|
||||||
/* Wait until the engine has processed the new BD. */
|
/* Wait until the engine has processed the new BD. */
|
||||||
while (uc_desc->bd[desc->currBd].BD_CTRL.DESC_EN);
|
while (gLHDesc.bd[gLHDesc.currBd].BD_CTRL.DESC_EN);
|
||||||
uc_desc->bd[desc->currBd].UPDPTR = KVA_TO_PA(hash);
|
gLHDesc.bd[gLHDesc.currBd].UPDPTR = KVA_TO_PA(hash);
|
||||||
desc->dbPtr = 0;
|
gLHDesc.dbPtr = 0;
|
||||||
}
|
}
|
||||||
if (!PIC32MZ_IF_RAM(input)) {
|
if (!PIC32MZ_IF_RAM(input)) {
|
||||||
/* If we're inputting from flash, let the BD have
|
/* If we're inputting from flash, let the BD have
|
||||||
the address and max the buffer size */
|
the address and max the buffer size */
|
||||||
uc_desc->bd[desc->currBd].SRCADDR = KVA_TO_PA(input);
|
gLHDesc.bd[gLHDesc.currBd].SRCADDR = KVA_TO_PA(input);
|
||||||
total = (len > PIC32MZ_MAX_BLOCK ? PIC32MZ_MAX_BLOCK : len);
|
total = (len > PIC32MZ_MAX_BLOCK ? PIC32MZ_MAX_BLOCK : len);
|
||||||
desc->dbPtr = total;
|
gLHDesc.dbPtr = total;
|
||||||
len -= total;
|
len -= total;
|
||||||
input += total;
|
input += total;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (len > PIC32_BLOCK_SIZE - desc->dbPtr) {
|
if (len > PIC32_BLOCK_SIZE - gLHDesc.dbPtr) {
|
||||||
/* We have more data than can be put in the buffer. Fill what we can.*/
|
/* We have more data than can be put in the buffer. Fill what we can.*/
|
||||||
total = PIC32_BLOCK_SIZE - desc->dbPtr;
|
total = PIC32_BLOCK_SIZE - gLHDesc.dbPtr;
|
||||||
XMEMCPY(&gLHDataBuf[desc->currBd][desc->dbPtr], input, total);
|
XMEMCPY(&gLHDataBuf[gLHDesc.currBd][gLHDesc.dbPtr], input, total);
|
||||||
len -= total;
|
len -= total;
|
||||||
desc->dbPtr = PIC32_BLOCK_SIZE;
|
gLHDesc.dbPtr = PIC32_BLOCK_SIZE;
|
||||||
input += total;
|
input += total;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Fill up what we have, but don't turn on the engine.*/
|
/* Fill up what we have, but don't turn on the engine.*/
|
||||||
XMEMCPY(&gLHDataBuf[desc->currBd][desc->dbPtr], input, len);
|
XMEMCPY(&gLHDataBuf[gLHDesc.currBd][gLHDesc.dbPtr], input, len);
|
||||||
desc->dbPtr += len;
|
gLHDesc.dbPtr += len;
|
||||||
len = 0;
|
len = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void start_engine(pic32mz_desc *desc)
|
static void start_engine(void)
|
||||||
{
|
{
|
||||||
/* Wrap up the last buffer descriptor and enable it */
|
/* Wrap up the last buffer descriptor and enable it */
|
||||||
int bufferLen;
|
int bufferLen;
|
||||||
pic32mz_desc *uc_desc = KVA0_TO_KVA1(desc);
|
|
||||||
|
|
||||||
bufferLen = desc->dbPtr;
|
bufferLen = gLHDesc.dbPtr;
|
||||||
if (bufferLen % 4)
|
if (bufferLen % 4)
|
||||||
bufferLen = (bufferLen + 4) - (bufferLen % 4);
|
bufferLen = (bufferLen + 4) - (bufferLen % 4);
|
||||||
/* initialize the MSGLEN on engine startup to avoid infinite loop when
|
/* initialize the MSGLEN on engine startup to avoid infinite loop when
|
||||||
* length is less than 257 (size of PIC32_BLOCK_SIZE) */
|
* length is less than 257 (size of PIC32_BLOCK_SIZE) */
|
||||||
uc_desc->bd[desc->currBd].MSGLEN = desc->msgSize;
|
gLHDesc.bd[gLHDesc.currBd].MSGLEN = gLHDesc.msgSize;
|
||||||
uc_desc->bd[desc->currBd].BD_CTRL.BUFLEN = bufferLen;
|
gLHDesc.bd[gLHDesc.currBd].BD_CTRL.BUFLEN = bufferLen;
|
||||||
uc_desc->bd[desc->currBd].BD_CTRL.LAST_BD = 1;
|
gLHDesc.bd[gLHDesc.currBd].BD_CTRL.LAST_BD = 1;
|
||||||
uc_desc->bd[desc->currBd].BD_CTRL.LIFM = 1;
|
gLHDesc.bd[gLHDesc.currBd].BD_CTRL.LIFM = 1;
|
||||||
uc_desc->bd[desc->currBd].BD_CTRL.DESC_EN = 1;
|
gLHDesc.bd[gLHDesc.currBd].BD_CTRL.DESC_EN = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wait_engine(pic32mz_desc *desc, char *hash, int hash_sz)
|
void wait_engine(char *hash, int hash_sz)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
pic32mz_desc *uc_desc = KVA0_TO_KVA1(desc);
|
|
||||||
unsigned int engineRunning;
|
unsigned int engineRunning;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
engineRunning = 0;
|
engineRunning = 0;
|
||||||
for (i = 0; i < PIC32MZ_MAX_BD; i++) {
|
for (i = 0; i < PIC32MZ_MAX_BD; i++) {
|
||||||
engineRunning = engineRunning || uc_desc->bd[i].BD_CTRL.DESC_EN;
|
engineRunning = engineRunning || gLHDesc.bd[i].BD_CTRL.DESC_EN;
|
||||||
}
|
}
|
||||||
} while (engineRunning);
|
} while (engineRunning);
|
||||||
|
|
||||||
@ -489,10 +483,10 @@ static int wc_Pic32HashUpdate(hashUpdCache* cache, byte* stdBuf, int stdBufLen,
|
|||||||
/* if final length is set then pass straight to hardware */
|
/* if final length is set then pass straight to hardware */
|
||||||
if (cache->finalLen) {
|
if (cache->finalLen) {
|
||||||
if (cache->bufLen == 0) {
|
if (cache->bufLen == 0) {
|
||||||
reset_engine(&gLHDesc, algo);
|
reset_engine(algo);
|
||||||
gLHDesc.msgSize = cache->finalLen;
|
gLHDesc.msgSize = cache->finalLen;
|
||||||
}
|
}
|
||||||
update_engine(&gLHDesc, data, len, digest);
|
update_engine(data, len, digest);
|
||||||
cache->bufLen += len; /* track progress for blockType */
|
cache->bufLen += len; /* track progress for blockType */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -560,9 +554,16 @@ static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf,
|
|||||||
|
|
||||||
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
|
#ifdef WOLFSSL_PIC32MZ_LARGE_HASH
|
||||||
if (cache->finalLen) {
|
if (cache->finalLen) {
|
||||||
start_engine(&gLHDesc);
|
/* Only submit to hardware if update data provided matches expected */
|
||||||
wait_engine(&gLHDesc, (char*)digest, digestSz);
|
if (cache->bufLen == cache->finalLen) {
|
||||||
XMEMCPY(hash, digest, digestSz);
|
start_engine();
|
||||||
|
wait_engine((char*)digest, digestSz);
|
||||||
|
XMEMCPY(hash, digest, digestSz);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wolfSSL_CryptHwMutexUnLock();
|
||||||
|
ret = BUFFER_E;
|
||||||
|
}
|
||||||
cache->finalLen = 0;
|
cache->finalLen = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user