mirror of https://github.com/wolfSSL/wolfssl.git
Add AES-CCM hardware acceleration support and other fixes
parent
3a6d5b8f90
commit
351a673ec0
|
@ -243,9 +243,11 @@
|
|||
#include <wolfcrypt/src/misc.c>
|
||||
#endif
|
||||
|
||||
#if !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_IMX6_CAAM)
|
||||
#if !defined(WOLFSSL_ARMASM)
|
||||
|
||||
#ifdef WOLFSSL_IMX6_CAAM_BLOB
|
||||
/* case of possibly not using hardware acceleration for AES but using key
|
||||
blobs */
|
||||
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||
#endif
|
||||
|
||||
|
@ -785,6 +787,17 @@
|
|||
}
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
|
||||
#elif defined(WOLFSSL_IMX6_CAAM)
|
||||
static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
||||
{
|
||||
wc_AesEncryptDirect(aes, outBlock, inBlock);
|
||||
return 0;
|
||||
}
|
||||
static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
||||
{
|
||||
wc_AesDecryptDirect(aes, outBlock, inBlock);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
|
||||
/* using wolfCrypt software AES implementation */
|
||||
|
@ -1978,6 +1991,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock)
|
|||
return wc_AesSetKey(aes, userKey, keylen, iv, dir);
|
||||
}
|
||||
|
||||
#elif defined(WOLFSSL_IMX6_CAAM)
|
||||
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||
|
||||
#else
|
||||
static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
|
||||
const byte* iv, int dir)
|
||||
|
@ -2289,6 +2305,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
|||
key, keySize, kLTC_EncryptKey);
|
||||
}
|
||||
|
||||
#elif defined(WOLFSSL_IMX6_CAAM)
|
||||
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||
|
||||
#else
|
||||
/* Allow direct access to one block encrypt */
|
||||
void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
|
||||
|
@ -2856,6 +2875,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
|||
}
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
|
||||
#elif defined(WOLFSSL_IMX6_CAAM)
|
||||
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||
|
||||
#else
|
||||
|
||||
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
||||
|
@ -3246,6 +3268,9 @@ int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#elif defined(WOLFSSL_IMX6_CAAM)
|
||||
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||
|
||||
#else
|
||||
|
||||
/* Use software based AES counter */
|
||||
|
@ -3432,10 +3457,10 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
|
|||
byte local[32];
|
||||
word32 localSz = 32;
|
||||
|
||||
if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
|
||||
keylen == (24 + WC_CAAM_BLOB_SZ) ||
|
||||
keylen == (32 + WC_CAAM_BLOB_SZ)) {
|
||||
if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
|
||||
if (len == (16 + WC_CAAM_BLOB_SZ) ||
|
||||
len == (24 + WC_CAAM_BLOB_SZ) ||
|
||||
len == (32 + WC_CAAM_BLOB_SZ)) {
|
||||
if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
|
|
|
@ -437,6 +437,9 @@ const char* wc_GetErrorString(int error)
|
|||
case WC_CAAM_E:
|
||||
return "Error with CAAM use";
|
||||
|
||||
case WC_CAAM_WAIT:
|
||||
return "CAAM Driver waiting on resource";
|
||||
|
||||
default:
|
||||
return "unknown error number";
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ int wc_AesSetKey(Aes* aes, const byte* key, word32 len,
|
|||
|
||||
outSz = sizeof(out);
|
||||
/* if length greater then 32 then try to unencapsulate */
|
||||
if ((ret = wc_caamOpenBlob((byte*)key, len, out, &outSz, NULL, 0)) != 0) {
|
||||
if ((ret = wc_caamOpenBlob((byte*)key, len, out, &outSz)) != 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,6 @@ int wc_AesSetKey(Aes* aes, const byte* key, word32 len,
|
|||
aes->keylen = len;
|
||||
}
|
||||
|
||||
|
||||
switch (aes->keylen) {
|
||||
case 16: aes->rounds = 10; break;
|
||||
case 24: aes->rounds = 12; break;
|
||||
|
@ -99,23 +98,6 @@ int wc_AesSetKey(Aes* aes, const byte* key, word32 len,
|
|||
}
|
||||
|
||||
|
||||
int wc_AesSetIV(Aes* aes, const byte* iv)
|
||||
{
|
||||
if (aes == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
if (iv == NULL) {
|
||||
XMEMSET((byte*)aes->reg, 0, AES_BLOCK_SIZE);
|
||||
}
|
||||
else {
|
||||
XMEMCPY((byte*)aes->reg, iv, AES_BLOCK_SIZE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wc_AesCbcEncrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 sz)
|
||||
{
|
||||
|
@ -366,12 +348,12 @@ void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
|
|||
word32 keySz;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
//return BAD_FUNC_ARG;
|
||||
/* return BAD_FUNC_ARG; */
|
||||
return;
|
||||
}
|
||||
|
||||
if (wc_AesGetKeySize(aes, &keySz) != 0) {
|
||||
//return BAD_FUNC_ARG;
|
||||
/* return BAD_FUNC_ARG; */
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -405,12 +387,12 @@ void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
|
|||
word32 keySz;
|
||||
|
||||
if (aes == NULL || out == NULL || in == NULL) {
|
||||
//return BAD_FUNC_ARG;
|
||||
/* return BAD_FUNC_ARG; */
|
||||
return;
|
||||
}
|
||||
|
||||
if (wc_AesGetKeySize(aes, &keySz) != 0) {
|
||||
//return BAD_FUNC_ARG;
|
||||
/* return BAD_FUNC_ARG; */
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -445,70 +427,17 @@ int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_AESCCM
|
||||
|
||||
#warning AES-CCM mode not complete
|
||||
|
||||
/* from wolfcrypt/src/aes.c */
|
||||
static void roll_auth(const byte* in, word32 inSz, byte* out)
|
||||
{
|
||||
word32 authLenSz;
|
||||
word32 remainder;
|
||||
|
||||
/* encode the length in */
|
||||
if (inSz <= 0xFEFF) {
|
||||
authLenSz = 2;
|
||||
out[0] ^= ((inSz & 0xFF00) >> 8);
|
||||
out[1] ^= (inSz & 0x00FF);
|
||||
}
|
||||
else if (inSz <= 0xFFFFFFFF) {
|
||||
authLenSz = 6;
|
||||
out[0] ^= 0xFF; out[1] ^= 0xFE;
|
||||
out[2] ^= ((inSz & 0xFF000000) >> 24);
|
||||
out[3] ^= ((inSz & 0x00FF0000) >> 16);
|
||||
out[4] ^= ((inSz & 0x0000FF00) >> 8);
|
||||
out[5] ^= (inSz & 0x000000FF);
|
||||
}
|
||||
/* Note, the protocol handles auth data up to 2^64, but we are
|
||||
* using 32-bit sizes right now, so the bigger data isn't handled
|
||||
* else if (inSz <= 0xFFFFFFFFFFFFFFFF) {} */
|
||||
else
|
||||
return;
|
||||
|
||||
/* start fill out the rest of the first block */
|
||||
remainder = AES_BLOCK_SIZE - authLenSz;
|
||||
if (inSz >= remainder) {
|
||||
/* plenty of bulk data to fill the remainder of this block */
|
||||
xorbuf(out + authLenSz, in, remainder);
|
||||
inSz -= remainder;
|
||||
in += remainder;
|
||||
}
|
||||
else {
|
||||
/* not enough bulk data, copy what is available, and pad zero */
|
||||
xorbuf(out + authLenSz, in, inSz);
|
||||
inSz = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int wc_AesCcmSetKey(Aes* aes, const byte* key, word32 keySz)
|
||||
{
|
||||
return wc_AesSetKey(aes, key, keySz, NULL, AES_ENCRYPTION);
|
||||
}
|
||||
|
||||
|
||||
int wc_AesCcmEncrypt(Aes* aes, byte* out,
|
||||
const byte* in, word32 inSz,
|
||||
const byte* nonce, word32 nonceSz,
|
||||
byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz)
|
||||
{
|
||||
Buffer buf[4];
|
||||
Buffer buf[5];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
word32 i;
|
||||
byte B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
|
||||
byte A[AES_BLOCK_SIZE];
|
||||
byte ASz = 0;
|
||||
int lenSz;
|
||||
byte mask = 0xFF;
|
||||
const word32 wordSz = (word32)sizeof(word32);
|
||||
|
@ -516,7 +445,8 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out,
|
|||
|
||||
/* sanity check on arguments */
|
||||
if (aes == NULL || out == NULL || in == NULL || nonce == NULL
|
||||
|| authTag == NULL || nonceSz < 7 || nonceSz > 13)
|
||||
|| authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
|
||||
authTagSz > AES_BLOCK_SIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (wc_AesGetKeySize(aes, &keySz) != 0) {
|
||||
|
@ -525,6 +455,7 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out,
|
|||
|
||||
/* set up B0 and CTR0 similar to how wolfcrypt/src/aes.c does */
|
||||
XMEMCPY(B0Ctr0+1, nonce, nonceSz);
|
||||
XMEMCPY(B0Ctr0+AES_BLOCK_SIZE+1, nonce, nonceSz);
|
||||
lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
|
||||
B0Ctr0[0] = (authInSz > 0 ? 64 : 0)
|
||||
+ (8 * (((byte)authTagSz - 2) / 2))
|
||||
|
@ -533,17 +464,9 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out,
|
|||
if (mask && i >= wordSz)
|
||||
mask = 0x00;
|
||||
B0Ctr0[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
|
||||
B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE - 1 - i] = 0;
|
||||
}
|
||||
|
||||
if (authInSz > 0) {
|
||||
ASz = AES_BLOCK_SIZE;
|
||||
roll_auth(authIn, authInSz, A);
|
||||
}
|
||||
|
||||
B0Ctr0[AES_BLOCK_SIZE] = lenSz - 1;
|
||||
for (i = 0; i < lenSz; i++)
|
||||
B0Ctr0[(AES_BLOCK_SIZE + AES_BLOCK_SIZE) - 1 - i] = 0;
|
||||
B0Ctr0[(AES_BLOCK_SIZE + AES_BLOCK_SIZE) - 1] = 1;
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
|
@ -555,27 +478,28 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out,
|
|||
buf[1].Length = AES_BLOCK_SIZE + AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer;
|
||||
buf[2].TheAddress = (Address)in;
|
||||
buf[2].Length = inSz;
|
||||
buf[2].TheAddress = (Address)authIn;
|
||||
buf[2].Length = authInSz;
|
||||
|
||||
buf[3].BufferType = DataBuffer;
|
||||
buf[3].TheAddress = (Address)out;
|
||||
buf[3].TheAddress = (Address)in;
|
||||
buf[3].Length = inSz;
|
||||
|
||||
buf[3].BufferType = DataBuffer | LastBuffer;
|
||||
buf[3].TheAddress = (Address)A;
|
||||
buf[3].Length = ASz;
|
||||
buf[4].BufferType = DataBuffer | LastBuffer;
|
||||
buf[4].TheAddress = (Address)out;
|
||||
buf[4].Length = inSz;
|
||||
|
||||
arg[0] = CAAM_ENC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = inSz;
|
||||
arg[3] = ASz;
|
||||
arg[3] = authInSz;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCCM)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES-CCM encrypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
XMEMCPY(authTag, B0Ctr0, authTagSz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -587,13 +511,12 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out,
|
|||
const byte* authTag, word32 authTagSz,
|
||||
const byte* authIn, word32 authInSz)
|
||||
{
|
||||
Buffer buf[4];
|
||||
Buffer buf[5];
|
||||
word32 arg[4];
|
||||
word32 keySz;
|
||||
word32 i;
|
||||
byte B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
|
||||
byte A[AES_BLOCK_SIZE];
|
||||
byte ASz = 0;
|
||||
byte tag[AES_BLOCK_SIZE];
|
||||
int lenSz;
|
||||
byte mask = 0xFF;
|
||||
const word32 wordSz = (word32)sizeof(word32);
|
||||
|
@ -601,7 +524,8 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out,
|
|||
|
||||
/* sanity check on arguments */
|
||||
if (aes == NULL || out == NULL || in == NULL || nonce == NULL
|
||||
|| authTag == NULL || nonceSz < 7 || nonceSz > 13)
|
||||
|| authTag == NULL || nonceSz < 7 || nonceSz > 13 ||
|
||||
authTagSz > AES_BLOCK_SIZE)
|
||||
return BAD_FUNC_ARG;
|
||||
|
||||
if (wc_AesGetKeySize(aes, &keySz) != 0) {
|
||||
|
@ -610,6 +534,7 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out,
|
|||
|
||||
/* set up B0 and CTR0 similar to how wolfcrypt/src/aes.c does */
|
||||
XMEMCPY(B0Ctr0+1, nonce, nonceSz);
|
||||
XMEMCPY(B0Ctr0+AES_BLOCK_SIZE+1, nonce, nonceSz);
|
||||
lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
|
||||
B0Ctr0[0] = (authInSz > 0 ? 64 : 0)
|
||||
+ (8 * (((byte)authTagSz - 2) / 2))
|
||||
|
@ -618,17 +543,10 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out,
|
|||
if (mask && i >= wordSz)
|
||||
mask = 0x00;
|
||||
B0Ctr0[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
|
||||
B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE - 1 - i] = 0;
|
||||
}
|
||||
|
||||
if (authInSz > 0) {
|
||||
ASz = AES_BLOCK_SIZE;
|
||||
roll_auth(authIn, authInSz, A);
|
||||
}
|
||||
|
||||
B0Ctr0[AES_BLOCK_SIZE] = lenSz - 1;
|
||||
for (i = 0; i < lenSz; i++)
|
||||
B0Ctr0[(AES_BLOCK_SIZE + AES_BLOCK_SIZE) - 1 - i] = 0;
|
||||
B0Ctr0[(AES_BLOCK_SIZE + AES_BLOCK_SIZE) - 1] = 1;
|
||||
wc_AesEncryptDirect(aes, tag, B0Ctr0 + AES_BLOCK_SIZE);
|
||||
|
||||
/* Set buffers for key, cipher text, and plain text */
|
||||
buf[0].BufferType = DataBuffer;
|
||||
|
@ -640,70 +558,44 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out,
|
|||
buf[1].Length = AES_BLOCK_SIZE + AES_BLOCK_SIZE;
|
||||
|
||||
buf[2].BufferType = DataBuffer;
|
||||
buf[2].TheAddress = (Address)in;
|
||||
buf[2].Length = inSz;
|
||||
buf[2].TheAddress = (Address)authIn;
|
||||
buf[2].Length = authInSz;
|
||||
|
||||
buf[3].BufferType = DataBuffer;
|
||||
buf[3].TheAddress = (Address)out;
|
||||
buf[3].TheAddress = (Address)in;
|
||||
buf[3].Length = inSz;
|
||||
|
||||
buf[3].BufferType = DataBuffer | LastBuffer;
|
||||
buf[3].TheAddress = (Address)A;
|
||||
buf[3].Length = ASz;
|
||||
buf[4].BufferType = DataBuffer | LastBuffer;
|
||||
buf[4].TheAddress = (Address)out;
|
||||
buf[4].Length = inSz;
|
||||
|
||||
arg[0] = CAAM_DEC;
|
||||
arg[1] = keySz;
|
||||
arg[2] = inSz;
|
||||
arg[3] = ASz;
|
||||
arg[3] = authInSz;
|
||||
|
||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCCM)) != 0) {
|
||||
WOLFSSL_MSG("Error with CAAM AES-CCM derypt");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
xorbuf(tag, B0Ctr0, authTagSz);
|
||||
if (ConstantCompare(tag, authTag, authTagSz) != 0) {
|
||||
/* If the authTag check fails, don't keep the decrypted data.
|
||||
* Unfortunately, you need the decrypted data to calculate the
|
||||
* check value. */
|
||||
XMEMSET(out, 0, inSz);
|
||||
ret = AES_CCM_AUTH_E;
|
||||
}
|
||||
|
||||
ForceZero(tag, AES_BLOCK_SIZE);
|
||||
ForceZero(B0Ctr0, AES_BLOCK_SIZE * 2);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
#endif /* HAVE_AES_DECRYPT */
|
||||
#endif /* HAVE_AESCCM */
|
||||
|
||||
|
||||
int wc_AesGetKeySize(Aes* aes, word32* keySize)
|
||||
{
|
||||
if (aes != NULL && keySize != NULL) {
|
||||
*keySize = aes->keylen;
|
||||
|
||||
/* preform sanity check on rounds to conform with test case */
|
||||
if (aes->rounds != 10 && aes->rounds != 12 && aes->rounds != 14) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
|
||||
int wc_AesInit(Aes* aes, void* heap, int devId)
|
||||
{
|
||||
if (aes == NULL) {
|
||||
return BAD_FUNC_ARG;
|
||||
}
|
||||
|
||||
aes->heap = heap;
|
||||
(void)devId;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void wc_AesFree(Aes* aes)
|
||||
{
|
||||
if (aes != NULL) {
|
||||
ForceZero((byte*)aes->key, 32);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* WOLFSSL_IMX6_CAAM && !NO_AES */
|
||||
|
||||
|
|
|
@ -36,9 +36,8 @@
|
|||
/* 64 byte buffer for when data crosses a page boundary */
|
||||
#define ALIGN_BUF 16
|
||||
|
||||
/* MAX_CTX is 64 bytes (sha512 digest) + 8 bytes (CAAM length value)
|
||||
X2 for split keys */
|
||||
#define MAX_CTX 36
|
||||
/* MAX_CTX is 64 bytes (sha512 digest) + 8 bytes (CAAM length value) */
|
||||
#define MAX_CTX 18
|
||||
|
||||
#define MIN_READ_REG 0xF2100000
|
||||
#define MAX_READ_REG 0XF2110000
|
||||
|
@ -60,12 +59,13 @@ struct DescStruct {
|
|||
struct IORequestStruct TheIORequest;
|
||||
struct CAAM_DEVICE* caam;
|
||||
struct buffer buf[MAX_BUF]; /* buffers holding data input address */
|
||||
Address output; /* address to output buffer */
|
||||
Address ctxOut; /* address to update buffer holding state */
|
||||
UINT4 desc[MAX_DESC_SZ]; /* max size of 64 word32 */
|
||||
UINT4 aadSzBuf[4]; /* Formated AAD size for CCM */
|
||||
UINT4 shaBuf[ALIGN_BUF]; /* 64 byte buffer for non page align */
|
||||
UINT4 iv[MAX_CTX]; /* AES IV and also hash state */
|
||||
UINT4 ctxBuf[MAX_CTX]; /* key */
|
||||
Address output; /* address to output buffer */
|
||||
Address ctxOut; /* address to update buffer holding state */
|
||||
Value shaIdx; /* index for descriptor buffer */
|
||||
Value idx; /* index for descriptor buffer */
|
||||
Value headIdx; /* for first portion of descriptor buffer */
|
||||
|
@ -312,7 +312,8 @@ static Error caamDoJob(struct DescStruct* desc)
|
|||
Error ret;
|
||||
UINT4 status;
|
||||
|
||||
/* set desc size */
|
||||
/* clear and set desc size */
|
||||
desc->desc[0] &= 0xFFFFFF80;
|
||||
desc->desc[0] += desc->idx;
|
||||
|
||||
/* check input slot is avialable and then add */
|
||||
|
@ -398,7 +399,8 @@ static int caamAddIO(struct DescStruct* desc, UINT4 options, UINT4 sz,
|
|||
if (dataSz % align > 0) {
|
||||
/* store potental overlap */
|
||||
int tmpSz = dataSz % align;
|
||||
int add = (tmpSz < (align - desc->shaIdx)) ? tmpSz : align - desc->shaIdx;
|
||||
int add = (tmpSz < (align - desc->shaIdx)) ? tmpSz :
|
||||
align - desc->shaIdx;
|
||||
unsigned char* local = (unsigned char*)desc->shaBuf;
|
||||
|
||||
/* if already something in the buffer then add from front */
|
||||
|
@ -556,21 +558,21 @@ static Error caamBlob(struct DescStruct* desc)
|
|||
CAAM AES Operations
|
||||
****************************************************************************/
|
||||
|
||||
/* AES operations follow the buffer sequence of KEY -> (IV or B0 | CTR0) ->
|
||||
* Input -> Output -> (AD)
|
||||
/* AES operations follow the buffer sequence of KEY -> (IV or B0 | CTR0) -> (AD)
|
||||
* -> Input -> Output
|
||||
*/
|
||||
static Error caamAes(struct DescStruct* desc)
|
||||
{
|
||||
Value ofst = 0;
|
||||
Error err;
|
||||
struct buffer* ctx[3];
|
||||
struct buffer* iv[3];
|
||||
Value ofst = 0;
|
||||
Error err;
|
||||
UINT4 i;
|
||||
int ctxIdx = 0;
|
||||
int ivIdx = 0;
|
||||
int offset = 0;
|
||||
int align = 1;
|
||||
int sz = 0;
|
||||
UINT4 i;
|
||||
|
||||
int ctxSz = desc->ctxSz;
|
||||
|
||||
|
@ -588,12 +590,13 @@ static Error caamAes(struct DescStruct* desc)
|
|||
unsigned char* local = (unsigned char*)desc->ctxBuf;
|
||||
|
||||
if (sz < ctxSz && sz < (MAX_CTX * sizeof(UINT4))) {
|
||||
ctx[ctxIdx++] = buf;
|
||||
ctx[ctxIdx] = buf;
|
||||
sz += buf->dataSz;
|
||||
|
||||
memcpy((unsigned char*)&local[offset], (unsigned char*)ctx[i]->data,
|
||||
ctx[i]->dataSz);
|
||||
offset += ctx[i]->dataSz;
|
||||
memcpy((unsigned char*)&local[offset],
|
||||
(unsigned char*)ctx[ctxIdx]->data, ctx[ctxIdx]->dataSz);
|
||||
offset += ctx[ctxIdx]->dataSz;
|
||||
ctxIdx++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
|
@ -628,14 +631,9 @@ static Error caamAes(struct DescStruct* desc)
|
|||
/* fall through because states are the same only the offest changes */
|
||||
|
||||
case CAAM_AESCBC:
|
||||
case CAAM_AESCCM:
|
||||
{
|
||||
int maxSz = 16; /* default to CBC/CTR max size */
|
||||
|
||||
if (desc->type == CAAM_AESCCM) {
|
||||
maxSz = 32; /* size of B0 | CTR0 for CCM mode */
|
||||
}
|
||||
|
||||
sz = 0;
|
||||
offset = 0;
|
||||
for (; i < desc->DescriptorCount; i++) {
|
||||
|
@ -683,53 +681,81 @@ static Error caamAes(struct DescStruct* desc)
|
|||
return TransferFailed;
|
||||
}
|
||||
desc->desc[desc->idx++] = CAAM_OP | CAAM_CLASS1 | desc->type |
|
||||
CAAM_ALG_INITF | desc->state;
|
||||
CAAM_ALG_UPDATE | desc->state;
|
||||
|
||||
/* load input and set flush of FIFO input */
|
||||
caamAddIO(desc, (CAAM_FIFO_L | CAAM_CLASS1 | FIFOL_TYPE_MSG),
|
||||
desc->inputSz, align, &i);
|
||||
/* find output buffers */
|
||||
sz = 0;
|
||||
for (desc->outputIdx = i; desc->outputIdx < desc->DescriptorCount &&
|
||||
sz < desc->inputSz; desc->outputIdx++) {
|
||||
sz += desc->buf[desc->outputIdx].dataSz;
|
||||
}
|
||||
|
||||
|
||||
/* indefinit loop for AES operations */
|
||||
desc->lastIdx = desc->outputIdx;
|
||||
desc->headIdx = desc->idx;
|
||||
desc->output = 0;
|
||||
offset = 0; /* store left over amount for output buffer */
|
||||
do {
|
||||
desc->idx = desc->headIdx; /* reset for each loop */
|
||||
|
||||
/* add a single input buffer (multiple ones was giving deco watch dog
|
||||
* time out errors on the FIFO load of 1c.
|
||||
* @TODO this could be a place for optimization if more data could be
|
||||
* loaded in at one time */
|
||||
if (desc->idx + 2 > MAX_DESC_SZ) {
|
||||
return TransferFailed;
|
||||
}
|
||||
sz = desc->buf[i].dataSz;
|
||||
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 */
|
||||
desc->outputIdx = i;
|
||||
sz = 0;
|
||||
for (; i < desc->DescriptorCount; i++) {
|
||||
struct buffer* buf = &desc->buf[i];
|
||||
if (sz < desc->inputSz) {
|
||||
if (desc->idx + 2 > MAX_DESC_SZ) {
|
||||
return TransferFailed;
|
||||
if (desc->output != 0 && offset > 0 && sz > 0) {
|
||||
/* 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++] = CAAM_FIFO_S | FIFOS_TYPE_MSG +
|
||||
buf->dataSz;
|
||||
desc->desc[desc->idx++] = BSP_VirtualToPhysical(buf->data);
|
||||
sz += buf->dataSz;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
desc->lastIdx = i;
|
||||
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->output);
|
||||
|
||||
/* if is CCM mode handle AAD */
|
||||
if (desc->type == CAAM_AESCCM && desc->aadSz > 0) {
|
||||
sz = 0;
|
||||
for (; i < desc->DescriptorCount; i++) {
|
||||
struct buffer* buf = &desc->buf[i];
|
||||
if (sz < desc->aadSz) {
|
||||
/* 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->lastFifo = desc->idx;
|
||||
desc->desc[desc->idx++] = CAAM_FIFO_L | FIFOL_TYPE_AAD +
|
||||
buf->dataSz;
|
||||
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);
|
||||
sz += buf->dataSz;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
desc->desc[desc->lastFifo] |= FIFOL_TYPE_LC1;
|
||||
|
||||
/* store updated IV */
|
||||
if (ivIdx > 0) {
|
||||
|
@ -743,9 +769,368 @@ static Error caamAes(struct DescStruct* desc)
|
|||
if ((err = caamDoJob(desc)) != Success) {
|
||||
return err;
|
||||
}
|
||||
ASP_FlushCaches((Address)desc->iv, 16);
|
||||
} while (desc->lastIdx < desc->DescriptorCount);
|
||||
|
||||
/* flush output buffers */
|
||||
for (i = desc->outputIdx; i < desc->lastIdx; i++) {
|
||||
ASP_FlushCaches(desc->buf[i].data, desc->buf[i].dataSz);
|
||||
}
|
||||
|
||||
/* handle case with IV */
|
||||
if (ivIdx > 0) {
|
||||
unsigned char* pt = (unsigned char*)desc->iv;
|
||||
ASP_FlushCaches((Address)pt, 16);
|
||||
for (i = 0; i < ivIdx; i++) {
|
||||
memcpy((unsigned char*)iv[i]->data, pt, iv[i]->dataSz);
|
||||
pt += iv[i]->dataSz;
|
||||
ASP_FlushCaches(iv[i]->data, iv[i]->dataSz);
|
||||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
CAAM AEAD Operations
|
||||
****************************************************************************/
|
||||
|
||||
/* AEAD operations follow the buffer sequence of KEY -> (IV or B0 | CTR0) -> (AD)
|
||||
* -> Input -> Output
|
||||
*
|
||||
*/
|
||||
static Error caamAead(struct DescStruct* desc)
|
||||
{
|
||||
struct buffer* ctx[3];
|
||||
struct buffer* iv[3];
|
||||
Value ofst = 0;
|
||||
UINT4 state = CAAM_ALG_INIT;
|
||||
UINT4 totalSz = 0;
|
||||
Error err;
|
||||
UINT4 i;
|
||||
int ctxIdx = 0;
|
||||
int ivIdx = 0;
|
||||
int offset = 0;
|
||||
int sz = 0;
|
||||
int ivSz = 32; /* size of B0 | CTR0 for CCM mode */
|
||||
int ctxSz = desc->ctxSz;
|
||||
int align = 16; /* input should be multiples of 16 bytes unless is final */
|
||||
int opIdx;
|
||||
|
||||
if (desc->state != CAAM_ENC && desc->state != CAAM_DEC) {
|
||||
return IllegalStatusNumber;
|
||||
}
|
||||
|
||||
/* sanity check is valid AES key size */
|
||||
if (ctxSz != 16 && ctxSz != 24 && ctxSz != 32) {
|
||||
return ArgumentError;
|
||||
}
|
||||
|
||||
/* get key */
|
||||
for (i = 0; i < desc->DescriptorCount; i++) {
|
||||
struct buffer* buf = &desc->buf[i];
|
||||
unsigned char* local = (unsigned char*)desc->ctxBuf;
|
||||
|
||||
if (sz < ctxSz && sz < (MAX_CTX * sizeof(UINT4))) {
|
||||
ctx[ctxIdx] = buf;
|
||||
sz += buf->dataSz;
|
||||
|
||||
memcpy((unsigned char*)&local[offset],
|
||||
(unsigned char*)ctx[ctxIdx]->data, ctx[ctxIdx]->dataSz);
|
||||
offset += ctx[ctxIdx]->dataSz;
|
||||
ctxIdx++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* sanity checks on size of key */
|
||||
if (sz > ctxSz) {
|
||||
return SizeIsTooLarge;
|
||||
}
|
||||
|
||||
/* Flush cache of ctx buffer then :
|
||||
Add KEY Load command 0x0220000X
|
||||
Add address to read key from 0xXXXXXXXX */
|
||||
ASP_FlushCaches((Address)desc->ctxBuf, ctxSz);
|
||||
if (desc->idx + 2 > MAX_DESC_SZ) {
|
||||
return TransferFailed;
|
||||
}
|
||||
desc->desc[desc->idx++] = (CAAM_KEY | CAAM_CLASS1 | CAAM_NWB) + ctxSz;
|
||||
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->ctxBuf);
|
||||
|
||||
desc->headIdx = desc->idx;
|
||||
desc->output = 0;
|
||||
offset = 0; /* store left over amount for output buffer */
|
||||
do {
|
||||
desc->idx = desc->headIdx; /* reset for each loop */
|
||||
|
||||
/* write operation */
|
||||
if (desc->idx + 1 > MAX_DESC_SZ) {
|
||||
return TransferFailed;
|
||||
}
|
||||
opIdx = desc->idx;
|
||||
desc->desc[desc->idx++] = CAAM_OP | CAAM_CLASS1 | state | desc->type |
|
||||
desc->state;
|
||||
|
||||
/* get IV if needed by algorithm */
|
||||
switch (desc->type) {
|
||||
case CAAM_AESCCM:
|
||||
if ((state & CAAM_ALG_INIT) == CAAM_ALG_INIT) {
|
||||
sz = 0;
|
||||
offset = 0;
|
||||
for (; i < desc->DescriptorCount; i++) {
|
||||
struct buffer* buf = &desc->buf[i];
|
||||
unsigned char* local = (unsigned char*)desc->iv;
|
||||
|
||||
if (sz < ivSz) {
|
||||
iv[ivIdx] = buf;
|
||||
|
||||
if (buf->dataSz + sz > ivSz) {
|
||||
return SizeIsTooLarge;
|
||||
}
|
||||
|
||||
sz += buf->dataSz;
|
||||
memcpy((unsigned char*)&local[offset],
|
||||
(unsigned char*)iv[ivIdx]->data, iv[ivIdx]->dataSz);
|
||||
offset += iv[ivIdx]->dataSz;
|
||||
ivIdx++;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sz != ivSz) {
|
||||
/* invalid IV size */
|
||||
return SizeIsTooLarge;
|
||||
}
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
ASP_FlushCaches((Address)desc->iv, ivSz);
|
||||
if (desc->idx + 2 > MAX_DESC_SZ) {
|
||||
return TransferFailed;
|
||||
}
|
||||
desc->desc[desc->idx++] = (CAAM_LOAD_CTX | CAAM_CLASS1 | ofst)
|
||||
+ ivSz;
|
||||
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->iv);
|
||||
break;
|
||||
|
||||
default:
|
||||
return OperationNotImplemented;
|
||||
}
|
||||
|
||||
|
||||
/********* handle AAD -- is only done with Init **********************/
|
||||
if ((state & CAAM_ALG_INIT) == CAAM_ALG_INIT) {
|
||||
if ((desc->type == CAAM_AESCCM) && (desc->aadSz > 0)) {
|
||||
/* set formated AAD buffer size for CCM */
|
||||
ASP_FlushCaches((Address)desc->aadSzBuf, sizeof(desc->aadSzBuf));
|
||||
desc->desc[desc->idx++] = CAAM_FIFO_L | CAAM_CLASS1 |
|
||||
FIFOL_TYPE_AAD + desc->aadSz;
|
||||
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->aadSzBuf);
|
||||
|
||||
/* now set aadSz to unformated version for getting buffers */
|
||||
if (desc->aadSz == 2) {
|
||||
unsigned char* pt = (unsigned char*)desc->aadSzBuf;
|
||||
desc->aadSz = (((UINT4)pt[0] & 0xFF) << 8) |
|
||||
((UINT4)pt[1] & 0xFF);
|
||||
}
|
||||
else {
|
||||
unsigned char* pt = (unsigned char*)desc->aadSzBuf;
|
||||
desc->aadSz = (((UINT4)pt[2] & 0xFF) << 24) |
|
||||
(((UINT4)pt[3] & 0xFF) << 16) |
|
||||
(((UINT4)pt[4] & 0xFF) << 8) |
|
||||
((UINT4)pt[5] & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
/* get additional data buffers */
|
||||
if (desc->aadSz > 0) {
|
||||
sz = 0;
|
||||
for (; i < desc->DescriptorCount; i++) {
|
||||
struct buffer* buf = &desc->buf[i];
|
||||
if (sz < desc->aadSz) {
|
||||
if (desc->idx + 2 > MAX_DESC_SZ) {
|
||||
return TransferFailed;
|
||||
}
|
||||
desc->lastFifo = desc->idx;
|
||||
desc->desc[desc->idx++] = CAAM_FIFO_L | CAAM_CLASS1 |
|
||||
FIFOL_TYPE_AAD + buf->dataSz;
|
||||
desc->desc[desc->idx++] = BSP_VirtualToPhysical(buf->data);
|
||||
sz += buf->dataSz;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* flush AAD from FIFO and pad it to 16 byte block */
|
||||
desc->desc[desc->lastFifo] |= FIFOL_TYPE_FC1;
|
||||
}
|
||||
|
||||
/* find output buffers */
|
||||
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;
|
||||
}
|
||||
|
||||
/* handle alignment constraints on input */
|
||||
if (desc->shaIdx > 0) {
|
||||
sz = desc->shaIdx;
|
||||
|
||||
/* if there is more input buffers then add part of it */
|
||||
if (i < desc->outputIdx && i < desc->DescriptorCount) {
|
||||
sz = align - desc->shaIdx;
|
||||
sz = (sz <= desc->buf[i].dataSz) ? sz : desc->buf[i].dataSz;
|
||||
memcpy((unsigned char*)(desc->shaBuf) + desc->shaIdx,
|
||||
(unsigned char*)(desc->buf[i].data), sz);
|
||||
|
||||
desc->buf[i].dataSz -= sz;
|
||||
desc->buf[i].data += sz;
|
||||
sz += desc->shaIdx;
|
||||
}
|
||||
|
||||
if (desc->idx + 2 > MAX_DESC_SZ) {
|
||||
return TransferFailed;
|
||||
}
|
||||
ASP_FlushCaches((Address)desc->shaBuf, sz);
|
||||
desc->desc[desc->idx++] = (CAAM_FIFO_L | FIFOL_TYPE_LC1 |
|
||||
CAAM_CLASS1 | FIFOL_TYPE_MSG) + sz;
|
||||
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->shaBuf);
|
||||
desc->shaIdx = 0;
|
||||
}
|
||||
else {
|
||||
sz = desc->buf[i].dataSz;
|
||||
totalSz += sz;
|
||||
if (totalSz == desc->inputSz) { /* not an issue on final */
|
||||
align = 1;
|
||||
}
|
||||
|
||||
desc->shaIdx = sz % align;
|
||||
if (desc->shaIdx != 0) {
|
||||
sz -= desc->shaIdx;
|
||||
memcpy((unsigned char*)desc->shaBuf,
|
||||
(unsigned char*)(desc->buf[i].data) + sz,
|
||||
desc->shaIdx);
|
||||
}
|
||||
|
||||
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 */
|
||||
if ((desc->lastIdx == desc->DescriptorCount) && (offset == 0)) {
|
||||
ivSz = 16;
|
||||
if (desc->state == CAAM_ENC) {
|
||||
ofst = 32 << 8; /* offset is in 15-8 bits */
|
||||
}
|
||||
else {
|
||||
ofst = 0;
|
||||
}
|
||||
desc->desc[opIdx] |= CAAM_ALG_FINAL;
|
||||
}
|
||||
else {
|
||||
/* if not final then store and use ctr and encrypted ctr from
|
||||
context dword 2,3 and 4,5. Also store MAC and AAD info from
|
||||
context dword 6. */
|
||||
ivSz = 56;
|
||||
ofst = 0;
|
||||
}
|
||||
|
||||
if (desc->idx + 2 > MAX_DESC_SZ) {
|
||||
return TransferFailed;
|
||||
}
|
||||
desc->desc[desc->idx++] = CAAM_STORE_CTX | CAAM_CLASS1 | ofst | ivSz;
|
||||
desc->desc[desc->idx++] = BSP_VirtualToPhysical((Address)desc->iv);
|
||||
|
||||
if ((err = caamDoJob(desc)) != Success) {
|
||||
return err;
|
||||
}
|
||||
state = CAAM_ALG_UPDATE;
|
||||
} while (desc->lastIdx < desc->DescriptorCount || offset > 0);
|
||||
|
||||
/* flush output buffers */
|
||||
for (i = desc->outputIdx; i < desc->lastIdx; i++) {
|
||||
ASP_FlushCaches(desc->buf[i].data, desc->buf[i].dataSz);
|
||||
}
|
||||
|
@ -753,7 +1138,7 @@ static Error caamAes(struct DescStruct* desc)
|
|||
/* handle case with IV (This is also the output of MAC with AES-CCM) */
|
||||
if (ivIdx > 0) {
|
||||
unsigned char* pt = (unsigned char*)desc->iv;
|
||||
ASP_FlushCaches((Address)pt, 16);
|
||||
ASP_FlushCaches((Address)pt, ivSz);
|
||||
for (i = 0; i < ivIdx; i++) {
|
||||
memcpy((unsigned char*)iv[i]->data, pt, iv[i]->dataSz);
|
||||
pt += iv[i]->dataSz;
|
||||
|
@ -812,10 +1197,10 @@ static Error caamSha(struct DescStruct* desc, int start)
|
|||
{
|
||||
struct buffer* ctx[3];
|
||||
Error err;
|
||||
UINT4 i;
|
||||
int sz = 0;
|
||||
int ctxIdx = 0;
|
||||
int offset = 0;
|
||||
UINT4 i;
|
||||
|
||||
int ctxSz = shaSize(desc);
|
||||
|
||||
|
@ -909,12 +1294,11 @@ static Error caamSha(struct DescStruct* desc, int start)
|
|||
|
||||
/* store context to buffers */
|
||||
{
|
||||
int j;
|
||||
unsigned char* pt = (unsigned char*)desc->iv;
|
||||
for (j = 0; j < ctxIdx; j++) {
|
||||
memcpy((unsigned char*)ctx[j]->data, pt, ctx[j]->dataSz);
|
||||
pt += ctx[j]->dataSz;
|
||||
ASP_FlushCaches(ctx[j]->data, ctx[j]->dataSz);
|
||||
for (i = 0; i < ctxIdx; i++) {
|
||||
memcpy((unsigned char*)ctx[i]->data, pt, ctx[i]->dataSz);
|
||||
pt += ctx[i]->dataSz;
|
||||
ASP_FlushCaches(ctx[i]->data, ctx[i]->dataSz);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1058,8 +1442,8 @@ static Error caamRng(struct DescStruct* desc)
|
|||
static Error caamTransferStart(IODeviceVector ioCaam,
|
||||
Value type, const volatile Value args[4])
|
||||
{
|
||||
struct DescStruct* desc;
|
||||
struct CAAM_DEVICE* local = (struct CAAM_DEVICE*)ioCaam;
|
||||
struct DescStruct* desc;
|
||||
|
||||
/* currently only one desc is available for use */
|
||||
desc = &local->DescArray[0];
|
||||
|
@ -1078,14 +1462,35 @@ static Error caamTransferStart(IODeviceVector ioCaam,
|
|||
desc->state = args[0];
|
||||
desc->ctxSz = args[1];
|
||||
desc->inputSz = args[2];
|
||||
desc->aadSz = args[3];
|
||||
desc->aadSz = 0;
|
||||
desc->desc[desc->idx++] = CAAM_HEAD; /* later will put size to header*/
|
||||
|
||||
switch (type) {
|
||||
case CAAM_AESECB:
|
||||
case CAAM_AESCBC:
|
||||
case CAAM_AESCTR:
|
||||
break;
|
||||
|
||||
case CAAM_AESCCM:
|
||||
memset((unsigned char*)desc->aadSzBuf, 0, sizeof(desc->aadSzBuf));
|
||||
if (args[3] > 0) {
|
||||
/* encode the length in */
|
||||
if (args[3] <= 0xFEFF) {
|
||||
unsigned char* pt = (unsigned char*)desc->aadSzBuf;
|
||||
desc->aadSz = 2;
|
||||
pt[0] = ((args[3] & 0xFF00) >> 8);
|
||||
pt[1] = (args[3] & 0x00FF);
|
||||
}
|
||||
else if (args[3] <= 0xFFFFFFFF) {
|
||||
unsigned char* pt = (unsigned char*)desc->aadSzBuf;
|
||||
desc->aadSz = 6;
|
||||
pt[0] = 0xFF; pt[1] = 0xFE;
|
||||
pt[2] = ((args[3] & 0xFF000000) >> 24);
|
||||
pt[3] = ((args[3] & 0x00FF0000) >> 16);
|
||||
pt[4] = ((args[3] & 0x0000FF00) >> 8);
|
||||
pt[5] = (args[3] & 0x000000FF);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case CAAM_MD5:
|
||||
|
@ -1131,8 +1536,8 @@ static Error caamTransferBuffer(IODeviceVector TheIODeviceVector,
|
|||
IORequest req, IODescriptor NewIODescriptor,
|
||||
Address data, Address dataSz)
|
||||
{
|
||||
Error err;
|
||||
struct DescStruct* desc = (struct DescStruct*)req;
|
||||
Error err;
|
||||
|
||||
switch (desc->type) {
|
||||
case CAAM_AESECB:
|
||||
|
@ -1158,7 +1563,11 @@ static Error caamTransferBuffer(IODeviceVector TheIODeviceVector,
|
|||
case CAAM_BLOB_DECAP:
|
||||
case CAAM_ENTROPY:
|
||||
{ /* set buffer for transfer finish */
|
||||
struct buffer* buf = &desc->buf[desc->DescriptorCount];
|
||||
struct buffer* buf;
|
||||
if (desc->DescriptorCount >= MAX_BUF) {
|
||||
return TooManyBuffers;
|
||||
}
|
||||
buf = &desc->buf[desc->DescriptorCount];
|
||||
buf->data = data;
|
||||
buf->dataSz = dataSz;
|
||||
}
|
||||
|
@ -1190,10 +1599,13 @@ static Error caamTransferFinish(IODeviceVector ioCaam, IORequest req)
|
|||
case CAAM_AESECB:
|
||||
case CAAM_AESCTR:
|
||||
case CAAM_AESCBC:
|
||||
case CAAM_AESCCM:
|
||||
ret = caamAes(desc);
|
||||
break;
|
||||
|
||||
case CAAM_AESCCM:
|
||||
ret = caamAead(desc);
|
||||
break;
|
||||
|
||||
case CAAM_MD5:
|
||||
case CAAM_SHA:
|
||||
case CAAM_SHA224:
|
||||
|
|
|
@ -86,14 +86,17 @@ int wc_caamSetResource(IODevice ioDev)
|
|||
*/
|
||||
int wc_caamInit()
|
||||
{
|
||||
int ret;
|
||||
word32 reg;
|
||||
|
||||
/* get the driver up */
|
||||
if (caam == NULLIODevice) {
|
||||
WOLFSSL_MSG("Starting CAAM driver");
|
||||
if (RequestResource((Object *)&caam, "wolfSSL_CAAM_Driver",
|
||||
WC_CAAM_PASSWORD) != Success) {
|
||||
if ((ret = (int)RequestResource((Object *)&caam, "wolfSSL_CAAM_Driver",
|
||||
WC_CAAM_PASSWORD)) != (int)Success) {
|
||||
WOLFSSL_MSG("Unable to get the CAAM IODevice, check password?");
|
||||
WOLFSSL_LEAVE("wc_caamInit: error from driver = ", ret);
|
||||
ret = 0; /* not a hard failure because user can set resource */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -135,6 +138,7 @@ int wc_caamInit()
|
|||
}
|
||||
#endif
|
||||
|
||||
(void)ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -174,6 +178,8 @@ void wc_caamWriteRegister(word32 reg, word32 value)
|
|||
}
|
||||
|
||||
|
||||
/* return 0 on success and WC_CAAM_E on failure. Can also return WC_CAAM_WAIT
|
||||
* in the case that the driver is waiting for a resource. */
|
||||
int wc_caamAddAndWait(Buffer* buf, word32 arg[4], word32 type)
|
||||
{
|
||||
int ret;
|
||||
|
@ -187,6 +193,13 @@ int wc_caamAddAndWait(Buffer* buf, word32 arg[4], word32 type)
|
|||
#if defined(WOLFSSL_CAAM_PRINT) || defined(WOLFSSL_CAAM_DEBUG)
|
||||
printf("ret of SynchronousSendIORequest = %d type = %d\n", ret, type);
|
||||
#endif
|
||||
|
||||
/* if waiting for resource or RNG return waiting */
|
||||
if (ret == Waiting) {
|
||||
WOLFSSL_MSG("Waiting on CAAM driver");
|
||||
return WC_CAAM_WAIT;
|
||||
}
|
||||
|
||||
return WC_CAAM_E;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
Common Code Between SHA Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int _InitSha(Sha* sha, void* heap, int devId, word32 digestSz,
|
||||
static int _InitSha(wc_Sha* sha, void* heap, int devId, word32 digestSz,
|
||||
word32 type)
|
||||
{
|
||||
Buffer buf[1];
|
||||
|
@ -97,7 +97,7 @@ static int _InitSha(Sha* sha, void* heap, int devId, word32 digestSz,
|
|||
}
|
||||
|
||||
|
||||
static int _ShaUpdate(Sha* sha, const byte* data, word32 len, word32 digestSz,
|
||||
static int _ShaUpdate(wc_Sha* sha, const byte* data, word32 len, word32 digestSz,
|
||||
word32 type)
|
||||
{
|
||||
Buffer buf[2];
|
||||
|
@ -185,7 +185,7 @@ static int _ShaUpdate(Sha* sha, const byte* data, word32 len, word32 digestSz,
|
|||
}
|
||||
|
||||
|
||||
static int _ShaFinal(Sha* sha, byte* out, word32 digestSz,
|
||||
static int _ShaFinal(wc_Sha* sha, byte* out, word32 digestSz,
|
||||
word32 type)
|
||||
{
|
||||
Buffer buf[2];
|
||||
|
@ -322,7 +322,7 @@ int wc_Sha256Update(wc_Sha256* sha, const byte* data, word32 len)
|
|||
}
|
||||
|
||||
|
||||
int wc_Sha256Final(wc-Sha256* sha, byte* out)
|
||||
int wc_Sha256Final(wc_Sha256* sha, byte* out)
|
||||
{
|
||||
int ret;
|
||||
if ((ret = _ShaFinal(sha, out, SHA256_DIGEST_SIZE, CAAM_SHA256)) != 0) {
|
||||
|
|
|
@ -1655,7 +1655,9 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz)
|
|||
if (ret == Success) {
|
||||
break;
|
||||
}
|
||||
if (ret != Waiting) {
|
||||
|
||||
/* driver could be waiting for entropy */
|
||||
if (ret != WC_CAAM_WAIT) {
|
||||
return ret;
|
||||
}
|
||||
sleep(1);
|
||||
|
|
|
@ -192,8 +192,9 @@ enum {
|
|||
ECC_PRIVATEONLY_E = -246, /* Invalid use of private only ECC key*/
|
||||
EXTKEYUSAGE_E = -247, /* Bad Extended Key Usage value */
|
||||
WC_CAAM_E = -248, /* Error with CAAM use */
|
||||
WC_CAAM_WAIT = -249, /* CAAM Driver waiting on resource */
|
||||
|
||||
WC_LAST_E = -248, /* Update this to indicate last error */
|
||||
WC_LAST_E = -249, /* Update this to indicate last error */
|
||||
MIN_CODE_E = -300 /* errors -101 - -299 */
|
||||
|
||||
/* add new companion error id strings for any new error codes
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
#define CAAM_CLASS1 0x02000000/* i.e. AES */
|
||||
#define CAAM_CLASS2 0x04000000/* i.e. hash algos */
|
||||
|
||||
#define CAAM_ENC 0x0000000D/* init and finalize with enc */
|
||||
#define CAAM_ENC 0x00000001
|
||||
#define CAAM_DEC 0x00000000
|
||||
#define CAAM_ALG_INIT 0x00000004
|
||||
#define CAAM_ALG_INITF 0x0000000C
|
||||
|
@ -105,11 +105,15 @@
|
|||
|
||||
#define FIFOL_TYPE_MSG 0x00100000
|
||||
#define FIFOL_TYPE_AAD 0x00300000
|
||||
#define FIFOL_TYPE_FC1 0x00010000
|
||||
#define FIFOL_TYPE_LC1 0x00020000
|
||||
#define FIFOL_TYPE_LC2 0x00040000
|
||||
|
||||
#define FIFOS_TYPE_MSG 0x00300000
|
||||
|
||||
/* continue bit set if more output is expected */
|
||||
#define CAAM_FIFOS_CONT 0x00800000
|
||||
|
||||
#define CAAM_PAGE_SZ 4096
|
||||
|
||||
/* RNG Registers */
|
||||
|
@ -170,7 +174,6 @@
|
|||
#define CAAM_CBCIV CAAM_CTX1 /* AES-CBC iv is in 1 and 2 */
|
||||
|
||||
|
||||
|
||||
/* instantiate RNG and create JDKEK, TDKEK, and TDSK key */
|
||||
static unsigned int wc_rng_start[] = {
|
||||
CAAM_HEAD | 0x00000006,
|
||||
|
|
|
@ -63,22 +63,22 @@
|
|||
#endif /* WC_CAAM_MAX_DIGEST */
|
||||
|
||||
|
||||
typedef struct Sha {
|
||||
typedef struct wc_Sha {
|
||||
word32 ctx[(WC_CAAM_MAX_DIGEST + WC_CAAM_CTXLEN) / sizeof(word32)];
|
||||
word32 buffLen; /* in bytes */
|
||||
word32 buffer[WC_CAAM_HASH_BLOCK / sizeof(word32)];
|
||||
} Sha;
|
||||
} wc_Sha;
|
||||
|
||||
#ifndef NO_MD5
|
||||
typedef struct Sha wc_Md5;
|
||||
typedef struct wc_Sha wc_Md5;
|
||||
#endif
|
||||
|
||||
#ifndef NO_SHA256
|
||||
typedef struct Sha wc_Sha256;
|
||||
typedef struct wc_Sha wc_Sha256;
|
||||
#endif
|
||||
|
||||
#ifdef WOLFSSL_SHA512
|
||||
typedef struct Sha wc_Sha512;
|
||||
typedef struct wc_Sha wc_Sha512;
|
||||
#endif
|
||||
|
||||
#endif /* WOLFSSL_IMX6_CAAM */
|
||||
|
|
Loading…
Reference in New Issue