refactor input/output with AES and fix sizes passed in

This commit is contained in:
Jacob Barthelmeh 2017-12-22 12:18:04 -07:00
parent b3eef2b10e
commit fe7dec0edb
2 changed files with 249 additions and 200 deletions

View File

@ -139,7 +139,7 @@ int wc_AesCbcEncrypt(Aes* aes, byte* out,
arg[0] = CAAM_ENC; arg[0] = CAAM_ENC;
arg[1] = keySz; arg[1] = keySz;
arg[2] = sz; arg[2] = blocks * AES_BLOCK_SIZE;
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCBC)) != 0) { if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCBC)) != 0) {
WOLFSSL_MSG("Error with CAAM AES CBC encrypt"); WOLFSSL_MSG("Error with CAAM AES CBC encrypt");
@ -192,7 +192,7 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out,
arg[0] = CAAM_DEC; arg[0] = CAAM_DEC;
arg[1] = keySz; arg[1] = keySz;
arg[2] = sz; arg[2] = blocks * AES_BLOCK_SIZE;
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCBC)) != 0) { if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCBC)) != 0) {
WOLFSSL_MSG("Error with CAAM AES CBC decrypt"); WOLFSSL_MSG("Error with CAAM AES CBC decrypt");
@ -203,24 +203,47 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out,
return 0; return 0;
} }
#ifdef HAVE_AES_ECB #if defined(HAVE_AES_ECB)
/* is assumed that input size is a multiple of AES_BLOCK_SIZE */ /* is assumed that input size is a multiple of AES_BLOCK_SIZE */
int wc_AesEcbEncrypt(Aes* aes, byte* out, int wc_AesEcbEncrypt(Aes* aes, byte* out,
const byte* in, word32 sz) const byte* in, word32 sz)
{ {
word32 blocks; word32 blocks;
Buffer buf[3];
word32 arg[4];
word32 keySz;
int ret;
if (aes == NULL || out == NULL || in == NULL) { if (aes == NULL || out == NULL || in == NULL) {
BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
blocks = sz / AES_BLOCK_SIZE; blocks = sz / AES_BLOCK_SIZE;
while (blocks > 0) { if (wc_AesGetKeySize(aes, &keySz) != 0) {
wc_AesEncryptDirect(aes, out, in); return BAD_FUNC_ARG;
blocks--; }
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE; /* Set buffers for key, cipher text, and plain text */
buf[0].BufferType = DataBuffer;
buf[0].TheAddress = (Address)aes->key;
buf[0].Length = keySz;
buf[1].BufferType = DataBuffer;
buf[1].TheAddress = (Address)in;
buf[1].Length = blocks * AES_BLOCK_SIZE;
buf[2].BufferType = DataBuffer | LastBuffer;
buf[2].TheAddress = (Address)out;
buf[2].Length = blocks * AES_BLOCK_SIZE;
arg[0] = CAAM_ENC;
arg[1] = keySz;
arg[2] = blocks * AES_BLOCK_SIZE;
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESECB)) != 0) {
WOLFSSL_MSG("Error with CAAM AES ECB encrypt");
return ret;
} }
return 0; return 0;
@ -231,19 +254,41 @@ int wc_AesEcbDecrypt(Aes* aes, byte* out,
const byte* in, word32 sz) const byte* in, word32 sz)
{ {
word32 blocks; word32 blocks;
Buffer buf[3];
word32 arg[4];
word32 keySz;
int ret;
if (aes == NULL || out == NULL || in == NULL) { if (aes == NULL || out == NULL || in == NULL) {
BAD_FUNC_ARG; return BAD_FUNC_ARG;
} }
blocks = sz / AES_BLOCK_SIZE; blocks = sz / AES_BLOCK_SIZE;
/* @TODO search for more efficient solution */ if (wc_AesGetKeySize(aes, &keySz) != 0) {
while (blocks > 0) { return BAD_FUNC_ARG;
wc_AesDecryptDirect(aes, out, in); }
blocks--;
out += AES_BLOCK_SIZE; /* Set buffers for key, cipher text, and plain text */
in += AES_BLOCK_SIZE; buf[0].BufferType = DataBuffer;
buf[0].TheAddress = (Address)aes->key;
buf[0].Length = keySz;
buf[1].BufferType = DataBuffer;
buf[1].TheAddress = (Address)in;
buf[1].Length = blocks * AES_BLOCK_SIZE;
buf[2].BufferType = DataBuffer | LastBuffer;
buf[2].TheAddress = (Address)out;
buf[2].Length = blocks * AES_BLOCK_SIZE;
arg[0] = CAAM_DEC;
arg[1] = keySz;
arg[2] = blocks * AES_BLOCK_SIZE;
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESECB)) != 0) {
WOLFSSL_MSG("Error with CAAM AES ECB decrypt");
return ret;
} }
return 0; return 0;
@ -311,13 +356,15 @@ int wc_AesCtrEncrypt(Aes* aes, byte* out,
arg[0] = CAAM_ENC; arg[0] = CAAM_ENC;
arg[1] = keySz; arg[1] = keySz;
arg[2] = sz; arg[2] = blocks * AES_BLOCK_SIZE;
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCTR)) != 0) { if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCTR)) != 0) {
WOLFSSL_MSG("Error with CAAM AES CTR encrypt"); WOLFSSL_MSG("Error with CAAM AES CTR encrypt");
return ret; return ret;
} }
out += blocks * AES_BLOCK_SIZE; out += blocks * AES_BLOCK_SIZE;
in += blocks * AES_BLOCK_SIZE;
sz -= blocks * AES_BLOCK_SIZE; sz -= blocks * AES_BLOCK_SIZE;
} }

View File

@ -352,11 +352,8 @@ static Error caamDoJob(struct DescStruct* desc)
pt += 21; pt += 21;
} }
snprintf(pt, sizeof(msg) - (z * 21), "status = 0x%8.8x\n", status); snprintf(pt, sizeof(msg) - (z * 21), "status = 0x%8.8x\n", status);
//if (desc->output != 0) { /* for testing */ if (desc->buf[0].data != 0) { /* for testing */
// memcpy((char*)desc->output, msg, sizeof(msg)); memcpy((char*)desc->buf[0].data, msg, sizeof(msg));
//}
if (desc->ctxOut != 0) { /* for testing */
memcpy((char*)desc->ctxOut, msg, sizeof(msg));
} }
} }
#endif #endif
@ -560,8 +557,167 @@ static Error caamBlob(struct DescStruct* desc)
CAAM AES Operations CAAM AES Operations
****************************************************************************/ ****************************************************************************/
/* AES operations follow the buffer sequence of KEY -> (IV or B0 | CTR0) -> (AD) /* returns amount writin on success and negative value in error case.
* -> Input -> Output * Is different from caamAddIO in that it only adds a single input buffer
* rather than multiple ones.
*/
static int caamAesInput(struct DescStruct* desc, UINT4* idx, int align,
UINT4 totalSz)
{
int sz;
UINT4 i = *idx;
/* handle alignment constraints on input */
if (desc->alignIdx > 0) {
sz = desc->alignIdx;
/* if there is more input buffers then add part of it */
if (i < desc->outputIdx && i < desc->DescriptorCount) {
sz = align - desc->alignIdx;
sz = (sz <= desc->buf[i].dataSz) ? sz : desc->buf[i].dataSz;
memcpy((unsigned char*)(desc->alignBuf) + desc->alignIdx,
(unsigned char*)(desc->buf[i].data), sz);
desc->buf[i].dataSz -= sz;
desc->buf[i].data += sz;
sz += desc->alignIdx;
}
if (desc->idx + 2 > MAX_DESC_SZ) {
return -1;
}
ASP_FlushCaches((Address)desc->alignBuf, sz);
desc->desc[desc->idx++] = (CAAM_FIFO_L | FIFOL_TYPE_LC1 |
CAAM_CLASS1 | FIFOL_TYPE_MSG) + sz;
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->alignBuf);
desc->alignIdx = 0;
}
else {
sz = desc->buf[i].dataSz;
if ((totalSz + sz) == desc->inputSz) { /* not an issue on final */
align = 1;
}
desc->alignIdx = sz % align;
if (desc->alignIdx != 0) {
sz -= desc->alignIdx;
memcpy((unsigned char*)desc->alignBuf,
(unsigned char*)(desc->buf[i].data) + sz,
desc->alignIdx);
}
if (desc->idx + 2 > MAX_DESC_SZ) {
return -1;
}
desc->desc[desc->idx++] = (CAAM_FIFO_L | FIFOL_TYPE_LC1 |
CAAM_CLASS1 | FIFOL_TYPE_MSG) + sz;
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->buf[i].data);
i++;
}
*idx = i;
return sz;
}
/* returns enum Success on success, all other return values should be
* considered an error.
*
* ofst is the amount of leftover buffer from previous calls
* inputSz is the amount of input in bytes that is being matched to output
*/
static Error caamAesOutput(struct DescStruct* desc, int* ofst, UINT4 inputSz)
{
int offset = *ofst;
if (desc->output != 0 && offset > 0 && inputSz > 0) {
UINT4 addSz;
/* handle potential leftovers */
addSz = (inputSz >= offset) ? offset : inputSz;
inputSz -= addSz;
desc->desc[desc->idx++] = CAAM_FIFO_S | FIFOS_TYPE_MSG + addSz;
if (inputSz > 0) { /* check if expecting more output */
desc->desc[desc->idx - 1] |= CAAM_FIFOS_CONT;
}
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->output);
if (addSz == offset) {
/* reset */
desc->output = 0;
offset = 0;
}
else {
offset -= addSz;
desc->output += addSz;
if (offset < 0) {
return TransferFailed;
}
}
}
for (; desc->lastIdx < desc->DescriptorCount; desc->lastIdx++) {
struct buffer* buf = &desc->buf[desc->lastIdx];
if (inputSz > 0) {
int tmp;
if (buf->dataSz <= inputSz) {
tmp = buf->dataSz;
}
else {
offset = buf->dataSz - inputSz;
tmp = inputSz;
desc->output = buf->data + tmp;
}
inputSz -= tmp;
if (desc->idx + 2 > MAX_DESC_SZ) {
return TransferFailed;
}
desc->desc[desc->idx++] = CAAM_FIFO_S | FIFOS_TYPE_MSG + tmp;
if (inputSz > 0) { /* check if expecting more output */
desc->desc[desc->idx - 1] |= CAAM_FIFOS_CONT;
}
desc->desc[desc->idx++] = BSP_VirtualToPhysical(buf->data);
}
else {
break;
}
}
*ofst = offset;
return Success;
}
/* check size of output and get starting buffer for it */
static Error caamAesOutSz(struct DescStruct* desc, UINT4 i)
{
int sz = 0;
for (desc->outputIdx = i; desc->outputIdx < desc->DescriptorCount &&
sz < desc->inputSz; desc->outputIdx++) {
sz += desc->buf[desc->outputIdx].dataSz;
}
desc->lastIdx = desc->outputIdx;
/* make certain that output size is same as input */
sz = 0;
for (; desc->lastIdx < desc->DescriptorCount; desc->lastIdx++) {
sz += desc->buf[desc->lastIdx].dataSz;
}
if (sz != desc->inputSz) {
return SizeIsTooLarge;
}
desc->lastIdx = desc->outputIdx;
return Success;
}
/* AES operations follow the buffer sequence of KEY -> (IV) -> Input -> Output
*/ */
static Error caamAes(struct DescStruct* desc) static Error caamAes(struct DescStruct* desc)
{ {
@ -569,7 +725,7 @@ static Error caamAes(struct DescStruct* desc)
struct buffer* iv[3]; struct buffer* iv[3];
Value ofst = 0; Value ofst = 0;
Error err; Error err;
UINT4 i; UINT4 i, totalSz = 0;
int ctxIdx = 0; int ctxIdx = 0;
int ivIdx = 0; int ivIdx = 0;
int offset = 0; int offset = 0;
@ -686,15 +842,16 @@ static Error caamAes(struct DescStruct* desc)
CAAM_ALG_UPDATE | desc->state; CAAM_ALG_UPDATE | desc->state;
/* find output buffers */ /* find output buffers */
sz = 0; if (caamAesOutSz(desc, i) != Success) {
for (desc->outputIdx = i; desc->outputIdx < desc->DescriptorCount && return SizeIsTooLarge;
sz < desc->inputSz; desc->outputIdx++) {
sz += desc->buf[desc->outputIdx].dataSz;
} }
/* set alignment constraints */
if (desc->type == CAAM_AESCBC) {
align = 16;
}
/* indefinit loop for AES operations */ /* indefinit loop for input/output buffers */
desc->lastIdx = desc->outputIdx;
desc->headIdx = desc->idx; desc->headIdx = desc->idx;
desc->output = 0; desc->output = 0;
offset = 0; /* store left over amount for output buffer */ offset = 0; /* store left over amount for output buffer */
@ -705,58 +862,13 @@ static Error caamAes(struct DescStruct* desc)
* time out errors on the FIFO load of 1c. * time out errors on the FIFO load of 1c.
* @TODO this could be a place for optimization if more data could be * @TODO this could be a place for optimization if more data could be
* loaded in at one time */ * loaded in at one time */
if (desc->idx + 2 > MAX_DESC_SZ) { if ((sz = caamAesInput(desc, &i, align, totalSz)) < 0) {
return TransferFailed; return TransferFailed;
} }
sz = desc->buf[i].dataSz; totalSz += sz;
desc->desc[desc->idx++] = (CAAM_FIFO_L | FIFOL_TYPE_LC1 | CAAM_CLASS1 |
FIFOL_TYPE_MSG) + sz;
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->buf[i].data);
i++;
/* handle output buffers */ if (caamAesOutput(desc, &offset, sz) != Success) {
if (desc->output != 0 && offset > 0 && sz > 0) { return TransferFailed;
/* handle potential leftovers */
sz -= offset;
desc->desc[desc->idx++] = CAAM_FIFO_S | FIFOS_TYPE_MSG + offset;
if (sz > 0) { /* check if expecting more output */
desc->desc[desc->idx - 1] |= CAAM_FIFOS_CONT;
}
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->output);
/* reset */
desc->output = 0;
offset = 0;
}
for (; desc->lastIdx < desc->DescriptorCount; desc->lastIdx++) {
struct buffer* buf = &desc->buf[desc->lastIdx];
if (sz > 0) {
int tmp;
if (buf->dataSz <= sz) {
tmp = buf->dataSz;
}
else {
offset = buf->dataSz - sz;
tmp = sz;
desc->output = buf->data + tmp;
}
sz -= tmp;
if (desc->idx + 2 > MAX_DESC_SZ) {
return TransferFailed;
}
desc->desc[desc->idx++] = CAAM_FIFO_S | FIFOS_TYPE_MSG + tmp;
if (sz > 0) { /* check if expecting more output */
desc->desc[desc->idx - 1] |= CAAM_FIFOS_CONT;
}
desc->desc[desc->idx++] = BSP_VirtualToPhysical(buf->data);
}
else {
break;
}
} }
/* store updated IV */ /* store updated IV */
@ -772,7 +884,7 @@ static Error caamAes(struct DescStruct* desc)
return err; return err;
} }
ASP_FlushCaches((Address)desc->iv, 16); ASP_FlushCaches((Address)desc->iv, 16);
} while (desc->lastIdx < desc->DescriptorCount); } while (desc->lastIdx < desc->DescriptorCount || offset > 0);
/* flush output buffers */ /* flush output buffers */
for (i = desc->outputIdx; i < desc->lastIdx; i++) { for (i = desc->outputIdx; i < desc->lastIdx; i++) {
@ -975,130 +1087,20 @@ static Error caamAead(struct DescStruct* desc)
} }
/* find output buffers */ /* find output buffers */
sz = 0; if (caamAesOutSz(desc, i) != Success) {
for (desc->outputIdx = i; desc->outputIdx < desc->DescriptorCount &&
sz < desc->inputSz; desc->outputIdx++) {
sz += desc->buf[desc->outputIdx].dataSz;
}
desc->lastIdx = desc->outputIdx;
/* make certain that output size is same as input */
sz = 0;
for (; desc->lastIdx < desc->DescriptorCount; desc->lastIdx++) {
sz += desc->buf[desc->lastIdx].dataSz;
}
if (sz > desc->inputSz) {
return SizeIsTooLarge; return SizeIsTooLarge;
} }
desc->lastIdx = desc->outputIdx;
} }
/* handle alignment constraints on input */ /* handle alignment constraints on input */
if (desc->alignIdx > 0) { if ((sz = caamAesInput(desc, &i, align, totalSz)) < 0) {
sz = desc->alignIdx; return TransferFailed;
/* if there is more input buffers then add part of it */
if (i < desc->outputIdx && i < desc->DescriptorCount) {
sz = align - desc->alignIdx;
sz = (sz <= desc->buf[i].dataSz) ? sz : desc->buf[i].dataSz;
memcpy((unsigned char*)(desc->alignBuf) + desc->alignIdx,
(unsigned char*)(desc->buf[i].data), sz);
desc->buf[i].dataSz -= sz;
desc->buf[i].data += sz;
sz += desc->alignIdx;
}
if (desc->idx + 2 > MAX_DESC_SZ) {
return TransferFailed;
}
ASP_FlushCaches((Address)desc->alignBuf, sz);
desc->desc[desc->idx++] = (CAAM_FIFO_L | FIFOL_TYPE_LC1 |
CAAM_CLASS1 | FIFOL_TYPE_MSG) + sz;
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->alignBuf);
desc->alignIdx = 0;
} }
else { totalSz += sz;
sz = desc->buf[i].dataSz;
totalSz += sz;
if (totalSz == desc->inputSz) { /* not an issue on final */
align = 1;
}
desc->alignIdx = sz % align; /* handle output buffers */
if (desc->alignIdx != 0) { if (caamAesOutput(desc, &offset, sz) != Success) {
sz -= desc->alignIdx; return TransferFailed;
memcpy((unsigned char*)desc->alignBuf,
(unsigned char*)(desc->buf[i].data) + sz,
desc->alignIdx);
}
if (desc->idx + 2 > MAX_DESC_SZ) {
return TransferFailed;
}
desc->desc[desc->idx++] = (CAAM_FIFO_L | FIFOL_TYPE_LC1 |
CAAM_CLASS1 | FIFOL_TYPE_MSG) + sz;
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->buf[i].data);
i++;
}
/************** handle output buffers *******************************/
if (desc->output != 0 && offset > 0 && sz > 0) {
UINT4 addSz;
/* handle potential leftovers */
addSz = (sz >= offset) ? offset : sz;
sz -= addSz;
desc->desc[desc->idx++] = CAAM_FIFO_S | FIFOS_TYPE_MSG + addSz;
if (sz > 0) { /* check if expecting more output */
desc->desc[desc->idx - 1] |= CAAM_FIFOS_CONT;
}
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->output);
if (addSz == offset) {
/* reset */
desc->output = 0;
offset = 0;
}
else {
offset -= addSz;
desc->output += addSz;
if (offset < 0) {
return Failure;
}
}
}
for (; desc->lastIdx < desc->DescriptorCount; desc->lastIdx++) {
struct buffer* buf = &desc->buf[desc->lastIdx];
if (sz > 0) {
int tmp;
if (buf->dataSz <= sz) {
tmp = buf->dataSz;
}
else {
offset = buf->dataSz - sz;
tmp = sz;
desc->output = buf->data + tmp;
}
sz -= tmp;
if (desc->idx + 2 > MAX_DESC_SZ) {
return TransferFailed;
}
desc->desc[desc->idx++] = CAAM_FIFO_S | FIFOS_TYPE_MSG + tmp;
if (sz > 0) { /* check if expecting more output */
desc->desc[desc->idx - 1] |= CAAM_FIFOS_CONT;
}
desc->desc[desc->idx++] = BSP_VirtualToPhysical(buf->data);
}
else {
break;
}
} }
/* store updated IV, if is last then set offset and final for MAC */ /* store updated IV, if is last then set offset and final for MAC */
@ -1186,7 +1188,7 @@ static int shaSize(struct DescStruct* desc)
* start: the index to start traversing through buffers. It's needed to allow * start: the index to start traversing through buffers. It's needed to allow
* for HMAC to reuse this code. * for HMAC to reuse this code.
* *
* return Success on success. All other return values are considered a fail * return Success on success. All other return values are considered a fail
* case. * case.
*/ */
static Error caamSha(struct DescStruct* desc, int start) static Error caamSha(struct DescStruct* desc, int start)