forked from wolfSSL/wolfssl
Add AES-CCM hardware acceleration support and other fixes
This commit is contained in:
@@ -243,9 +243,11 @@
|
|||||||
#include <wolfcrypt/src/misc.c>
|
#include <wolfcrypt/src/misc.c>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_IMX6_CAAM)
|
#if !defined(WOLFSSL_ARMASM)
|
||||||
|
|
||||||
#ifdef WOLFSSL_IMX6_CAAM_BLOB
|
#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>
|
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -785,6 +787,17 @@
|
|||||||
}
|
}
|
||||||
#endif /* HAVE_AES_DECRYPT */
|
#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
|
#else
|
||||||
|
|
||||||
/* using wolfCrypt software AES implementation */
|
/* 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);
|
return wc_AesSetKey(aes, userKey, keylen, iv, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(WOLFSSL_IMX6_CAAM)
|
||||||
|
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
|
static int wc_AesSetKeyLocal(Aes* aes, const byte* userKey, word32 keylen,
|
||||||
const byte* iv, int dir)
|
const byte* iv, int dir)
|
||||||
@@ -2289,6 +2305,9 @@ int wc_AesSetIV(Aes* aes, const byte* iv)
|
|||||||
key, keySize, kLTC_EncryptKey);
|
key, keySize, kLTC_EncryptKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(WOLFSSL_IMX6_CAAM)
|
||||||
|
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/* Allow direct access to one block encrypt */
|
/* Allow direct access to one block encrypt */
|
||||||
void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
|
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 */
|
#endif /* HAVE_AES_DECRYPT */
|
||||||
|
|
||||||
|
#elif defined(WOLFSSL_IMX6_CAAM)
|
||||||
|
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
int wc_AesCbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#elif defined(WOLFSSL_IMX6_CAAM)
|
||||||
|
/* implemented in wolfcrypt/src/port/caam/caam_aes.c */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
/* Use software based AES counter */
|
/* Use software based AES counter */
|
||||||
@@ -3432,10 +3457,10 @@ int wc_AesGcmSetKey(Aes* aes, const byte* key, word32 len)
|
|||||||
byte local[32];
|
byte local[32];
|
||||||
word32 localSz = 32;
|
word32 localSz = 32;
|
||||||
|
|
||||||
if (keylen == (16 + WC_CAAM_BLOB_SZ) ||
|
if (len == (16 + WC_CAAM_BLOB_SZ) ||
|
||||||
keylen == (24 + WC_CAAM_BLOB_SZ) ||
|
len == (24 + WC_CAAM_BLOB_SZ) ||
|
||||||
keylen == (32 + WC_CAAM_BLOB_SZ)) {
|
len == (32 + WC_CAAM_BLOB_SZ)) {
|
||||||
if (wc_caamOpenBlob((byte*)userKey, keylen, local, &localSz) != 0) {
|
if (wc_caamOpenBlob((byte*)key, len, local, &localSz) != 0) {
|
||||||
return BAD_FUNC_ARG;
|
return BAD_FUNC_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -437,6 +437,9 @@ const char* wc_GetErrorString(int error)
|
|||||||
case WC_CAAM_E:
|
case WC_CAAM_E:
|
||||||
return "Error with CAAM use";
|
return "Error with CAAM use";
|
||||||
|
|
||||||
|
case WC_CAAM_WAIT:
|
||||||
|
return "CAAM Driver waiting on resource";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "unknown error number";
|
return "unknown error number";
|
||||||
|
|
||||||
|
@@ -62,7 +62,7 @@ int wc_AesSetKey(Aes* aes, const byte* key, word32 len,
|
|||||||
|
|
||||||
outSz = sizeof(out);
|
outSz = sizeof(out);
|
||||||
/* if length greater then 32 then try to unencapsulate */
|
/* 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,7 +78,6 @@ int wc_AesSetKey(Aes* aes, const byte* key, word32 len,
|
|||||||
aes->keylen = len;
|
aes->keylen = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (aes->keylen) {
|
switch (aes->keylen) {
|
||||||
case 16: aes->rounds = 10; break;
|
case 16: aes->rounds = 10; break;
|
||||||
case 24: aes->rounds = 12; 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,
|
int wc_AesCbcEncrypt(Aes* aes, byte* out,
|
||||||
const byte* in, word32 sz)
|
const byte* in, word32 sz)
|
||||||
{
|
{
|
||||||
@@ -366,12 +348,12 @@ void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
|
|||||||
word32 keySz;
|
word32 keySz;
|
||||||
|
|
||||||
if (aes == NULL || out == NULL || in == NULL) {
|
if (aes == NULL || out == NULL || in == NULL) {
|
||||||
//return BAD_FUNC_ARG;
|
/* return BAD_FUNC_ARG; */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wc_AesGetKeySize(aes, &keySz) != 0) {
|
if (wc_AesGetKeySize(aes, &keySz) != 0) {
|
||||||
//return BAD_FUNC_ARG;
|
/* return BAD_FUNC_ARG; */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,12 +387,12 @@ void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
|
|||||||
word32 keySz;
|
word32 keySz;
|
||||||
|
|
||||||
if (aes == NULL || out == NULL || in == NULL) {
|
if (aes == NULL || out == NULL || in == NULL) {
|
||||||
//return BAD_FUNC_ARG;
|
/* return BAD_FUNC_ARG; */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wc_AesGetKeySize(aes, &keySz) != 0) {
|
if (wc_AesGetKeySize(aes, &keySz) != 0) {
|
||||||
//return BAD_FUNC_ARG;
|
/* return BAD_FUNC_ARG; */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,70 +427,17 @@ int wc_AesSetKeyDirect(Aes* aes, const byte* key, word32 len,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_AESCCM
|
#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,
|
int wc_AesCcmEncrypt(Aes* aes, byte* out,
|
||||||
const byte* in, word32 inSz,
|
const byte* in, word32 inSz,
|
||||||
const byte* nonce, word32 nonceSz,
|
const byte* nonce, word32 nonceSz,
|
||||||
byte* authTag, word32 authTagSz,
|
byte* authTag, word32 authTagSz,
|
||||||
const byte* authIn, word32 authInSz)
|
const byte* authIn, word32 authInSz)
|
||||||
{
|
{
|
||||||
Buffer buf[4];
|
Buffer buf[5];
|
||||||
word32 arg[4];
|
word32 arg[4];
|
||||||
word32 keySz;
|
word32 keySz;
|
||||||
word32 i;
|
word32 i;
|
||||||
byte B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
|
byte B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
|
||||||
byte A[AES_BLOCK_SIZE];
|
|
||||||
byte ASz = 0;
|
|
||||||
int lenSz;
|
int lenSz;
|
||||||
byte mask = 0xFF;
|
byte mask = 0xFF;
|
||||||
const word32 wordSz = (word32)sizeof(word32);
|
const word32 wordSz = (word32)sizeof(word32);
|
||||||
@@ -516,7 +445,8 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out,
|
|||||||
|
|
||||||
/* sanity check on arguments */
|
/* sanity check on arguments */
|
||||||
if (aes == NULL || out == NULL || in == NULL || nonce == NULL
|
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;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
if (wc_AesGetKeySize(aes, &keySz) != 0) {
|
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 */
|
/* set up B0 and CTR0 similar to how wolfcrypt/src/aes.c does */
|
||||||
XMEMCPY(B0Ctr0+1, nonce, nonceSz);
|
XMEMCPY(B0Ctr0+1, nonce, nonceSz);
|
||||||
|
XMEMCPY(B0Ctr0+AES_BLOCK_SIZE+1, nonce, nonceSz);
|
||||||
lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
|
lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
|
||||||
B0Ctr0[0] = (authInSz > 0 ? 64 : 0)
|
B0Ctr0[0] = (authInSz > 0 ? 64 : 0)
|
||||||
+ (8 * (((byte)authTagSz - 2) / 2))
|
+ (8 * (((byte)authTagSz - 2) / 2))
|
||||||
@@ -533,17 +464,9 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out,
|
|||||||
if (mask && i >= wordSz)
|
if (mask && i >= wordSz)
|
||||||
mask = 0x00;
|
mask = 0x00;
|
||||||
B0Ctr0[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
|
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;
|
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 */
|
/* Set buffers for key, cipher text, and plain text */
|
||||||
buf[0].BufferType = DataBuffer;
|
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[1].Length = AES_BLOCK_SIZE + AES_BLOCK_SIZE;
|
||||||
|
|
||||||
buf[2].BufferType = DataBuffer;
|
buf[2].BufferType = DataBuffer;
|
||||||
buf[2].TheAddress = (Address)in;
|
buf[2].TheAddress = (Address)authIn;
|
||||||
buf[2].Length = inSz;
|
buf[2].Length = authInSz;
|
||||||
|
|
||||||
buf[3].BufferType = DataBuffer;
|
buf[3].BufferType = DataBuffer;
|
||||||
buf[3].TheAddress = (Address)out;
|
buf[3].TheAddress = (Address)in;
|
||||||
buf[3].Length = inSz;
|
buf[3].Length = inSz;
|
||||||
|
|
||||||
buf[3].BufferType = DataBuffer | LastBuffer;
|
buf[4].BufferType = DataBuffer | LastBuffer;
|
||||||
buf[3].TheAddress = (Address)A;
|
buf[4].TheAddress = (Address)out;
|
||||||
buf[3].Length = ASz;
|
buf[4].Length = inSz;
|
||||||
|
|
||||||
arg[0] = CAAM_ENC;
|
arg[0] = CAAM_ENC;
|
||||||
arg[1] = keySz;
|
arg[1] = keySz;
|
||||||
arg[2] = inSz;
|
arg[2] = inSz;
|
||||||
arg[3] = ASz;
|
arg[3] = authInSz;
|
||||||
|
|
||||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCCM)) != 0) {
|
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCCM)) != 0) {
|
||||||
WOLFSSL_MSG("Error with CAAM AES-CCM encrypt");
|
WOLFSSL_MSG("Error with CAAM AES-CCM encrypt");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XMEMCPY(authTag, B0Ctr0, authTagSz);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -587,13 +511,12 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out,
|
|||||||
const byte* authTag, word32 authTagSz,
|
const byte* authTag, word32 authTagSz,
|
||||||
const byte* authIn, word32 authInSz)
|
const byte* authIn, word32 authInSz)
|
||||||
{
|
{
|
||||||
Buffer buf[4];
|
Buffer buf[5];
|
||||||
word32 arg[4];
|
word32 arg[4];
|
||||||
word32 keySz;
|
word32 keySz;
|
||||||
word32 i;
|
word32 i;
|
||||||
byte B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
|
byte B0Ctr0[AES_BLOCK_SIZE + AES_BLOCK_SIZE];
|
||||||
byte A[AES_BLOCK_SIZE];
|
byte tag[AES_BLOCK_SIZE];
|
||||||
byte ASz = 0;
|
|
||||||
int lenSz;
|
int lenSz;
|
||||||
byte mask = 0xFF;
|
byte mask = 0xFF;
|
||||||
const word32 wordSz = (word32)sizeof(word32);
|
const word32 wordSz = (word32)sizeof(word32);
|
||||||
@@ -601,7 +524,8 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out,
|
|||||||
|
|
||||||
/* sanity check on arguments */
|
/* sanity check on arguments */
|
||||||
if (aes == NULL || out == NULL || in == NULL || nonce == NULL
|
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;
|
return BAD_FUNC_ARG;
|
||||||
|
|
||||||
if (wc_AesGetKeySize(aes, &keySz) != 0) {
|
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 */
|
/* set up B0 and CTR0 similar to how wolfcrypt/src/aes.c does */
|
||||||
XMEMCPY(B0Ctr0+1, nonce, nonceSz);
|
XMEMCPY(B0Ctr0+1, nonce, nonceSz);
|
||||||
|
XMEMCPY(B0Ctr0+AES_BLOCK_SIZE+1, nonce, nonceSz);
|
||||||
lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
|
lenSz = AES_BLOCK_SIZE - 1 - (byte)nonceSz;
|
||||||
B0Ctr0[0] = (authInSz > 0 ? 64 : 0)
|
B0Ctr0[0] = (authInSz > 0 ? 64 : 0)
|
||||||
+ (8 * (((byte)authTagSz - 2) / 2))
|
+ (8 * (((byte)authTagSz - 2) / 2))
|
||||||
@@ -618,17 +543,10 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out,
|
|||||||
if (mask && i >= wordSz)
|
if (mask && i >= wordSz)
|
||||||
mask = 0x00;
|
mask = 0x00;
|
||||||
B0Ctr0[AES_BLOCK_SIZE - 1 - i] = (inSz >> ((8 * i) & mask)) & mask;
|
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;
|
B0Ctr0[AES_BLOCK_SIZE] = lenSz - 1;
|
||||||
for (i = 0; i < lenSz; i++)
|
wc_AesEncryptDirect(aes, tag, B0Ctr0 + AES_BLOCK_SIZE);
|
||||||
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 */
|
/* Set buffers for key, cipher text, and plain text */
|
||||||
buf[0].BufferType = DataBuffer;
|
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[1].Length = AES_BLOCK_SIZE + AES_BLOCK_SIZE;
|
||||||
|
|
||||||
buf[2].BufferType = DataBuffer;
|
buf[2].BufferType = DataBuffer;
|
||||||
buf[2].TheAddress = (Address)in;
|
buf[2].TheAddress = (Address)authIn;
|
||||||
buf[2].Length = inSz;
|
buf[2].Length = authInSz;
|
||||||
|
|
||||||
buf[3].BufferType = DataBuffer;
|
buf[3].BufferType = DataBuffer;
|
||||||
buf[3].TheAddress = (Address)out;
|
buf[3].TheAddress = (Address)in;
|
||||||
buf[3].Length = inSz;
|
buf[3].Length = inSz;
|
||||||
|
|
||||||
buf[3].BufferType = DataBuffer | LastBuffer;
|
buf[4].BufferType = DataBuffer | LastBuffer;
|
||||||
buf[3].TheAddress = (Address)A;
|
buf[4].TheAddress = (Address)out;
|
||||||
buf[3].Length = ASz;
|
buf[4].Length = inSz;
|
||||||
|
|
||||||
arg[0] = CAAM_DEC;
|
arg[0] = CAAM_DEC;
|
||||||
arg[1] = keySz;
|
arg[1] = keySz;
|
||||||
arg[2] = inSz;
|
arg[2] = inSz;
|
||||||
arg[3] = ASz;
|
arg[3] = authInSz;
|
||||||
|
|
||||||
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCCM)) != 0) {
|
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCCM)) != 0) {
|
||||||
WOLFSSL_MSG("Error with CAAM AES-CCM derypt");
|
WOLFSSL_MSG("Error with CAAM AES-CCM derypt");
|
||||||
return ret;
|
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_AES_DECRYPT */
|
||||||
#endif /* HAVE_AESCCM */
|
#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 */
|
#endif /* WOLFSSL_IMX6_CAAM && !NO_AES */
|
||||||
|
|
||||||
|
@@ -36,9 +36,8 @@
|
|||||||
/* 64 byte buffer for when data crosses a page boundary */
|
/* 64 byte buffer for when data crosses a page boundary */
|
||||||
#define ALIGN_BUF 16
|
#define ALIGN_BUF 16
|
||||||
|
|
||||||
/* MAX_CTX is 64 bytes (sha512 digest) + 8 bytes (CAAM length value)
|
/* MAX_CTX is 64 bytes (sha512 digest) + 8 bytes (CAAM length value) */
|
||||||
X2 for split keys */
|
#define MAX_CTX 18
|
||||||
#define MAX_CTX 36
|
|
||||||
|
|
||||||
#define MIN_READ_REG 0xF2100000
|
#define MIN_READ_REG 0xF2100000
|
||||||
#define MAX_READ_REG 0XF2110000
|
#define MAX_READ_REG 0XF2110000
|
||||||
@@ -60,12 +59,13 @@ struct DescStruct {
|
|||||||
struct IORequestStruct TheIORequest;
|
struct IORequestStruct TheIORequest;
|
||||||
struct CAAM_DEVICE* caam;
|
struct CAAM_DEVICE* caam;
|
||||||
struct buffer buf[MAX_BUF]; /* buffers holding data input address */
|
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 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 shaBuf[ALIGN_BUF]; /* 64 byte buffer for non page align */
|
||||||
UINT4 iv[MAX_CTX]; /* AES IV and also hash state */
|
UINT4 iv[MAX_CTX]; /* AES IV and also hash state */
|
||||||
UINT4 ctxBuf[MAX_CTX]; /* key */
|
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 shaIdx; /* index for descriptor buffer */
|
||||||
Value idx; /* index for descriptor buffer */
|
Value idx; /* index for descriptor buffer */
|
||||||
Value headIdx; /* for first portion of descriptor buffer */
|
Value headIdx; /* for first portion of descriptor buffer */
|
||||||
@@ -312,7 +312,8 @@ static Error caamDoJob(struct DescStruct* desc)
|
|||||||
Error ret;
|
Error ret;
|
||||||
UINT4 status;
|
UINT4 status;
|
||||||
|
|
||||||
/* set desc size */
|
/* clear and set desc size */
|
||||||
|
desc->desc[0] &= 0xFFFFFF80;
|
||||||
desc->desc[0] += desc->idx;
|
desc->desc[0] += desc->idx;
|
||||||
|
|
||||||
/* check input slot is avialable and then add */
|
/* 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) {
|
if (dataSz % align > 0) {
|
||||||
/* store potental overlap */
|
/* store potental overlap */
|
||||||
int tmpSz = dataSz % align;
|
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;
|
unsigned char* local = (unsigned char*)desc->shaBuf;
|
||||||
|
|
||||||
/* if already something in the buffer then add from front */
|
/* if already something in the buffer then add from front */
|
||||||
@@ -556,21 +558,21 @@ static Error caamBlob(struct DescStruct* desc)
|
|||||||
CAAM AES Operations
|
CAAM AES Operations
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* AES operations follow the buffer sequence of KEY -> (IV or B0 | CTR0) ->
|
/* AES operations follow the buffer sequence of KEY -> (IV or B0 | CTR0) -> (AD)
|
||||||
* Input -> Output -> (AD)
|
* -> Input -> Output
|
||||||
*/
|
*/
|
||||||
static Error caamAes(struct DescStruct* desc)
|
static Error caamAes(struct DescStruct* desc)
|
||||||
{
|
{
|
||||||
Value ofst = 0;
|
|
||||||
Error err;
|
|
||||||
struct buffer* ctx[3];
|
struct buffer* ctx[3];
|
||||||
struct buffer* iv[3];
|
struct buffer* iv[3];
|
||||||
|
Value ofst = 0;
|
||||||
|
Error err;
|
||||||
|
UINT4 i;
|
||||||
int ctxIdx = 0;
|
int ctxIdx = 0;
|
||||||
int ivIdx = 0;
|
int ivIdx = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int align = 1;
|
int align = 1;
|
||||||
int sz = 0;
|
int sz = 0;
|
||||||
UINT4 i;
|
|
||||||
|
|
||||||
int ctxSz = desc->ctxSz;
|
int ctxSz = desc->ctxSz;
|
||||||
|
|
||||||
@@ -588,12 +590,13 @@ static Error caamAes(struct DescStruct* desc)
|
|||||||
unsigned char* local = (unsigned char*)desc->ctxBuf;
|
unsigned char* local = (unsigned char*)desc->ctxBuf;
|
||||||
|
|
||||||
if (sz < ctxSz && sz < (MAX_CTX * sizeof(UINT4))) {
|
if (sz < ctxSz && sz < (MAX_CTX * sizeof(UINT4))) {
|
||||||
ctx[ctxIdx++] = buf;
|
ctx[ctxIdx] = buf;
|
||||||
sz += buf->dataSz;
|
sz += buf->dataSz;
|
||||||
|
|
||||||
memcpy((unsigned char*)&local[offset], (unsigned char*)ctx[i]->data,
|
memcpy((unsigned char*)&local[offset],
|
||||||
ctx[i]->dataSz);
|
(unsigned char*)ctx[ctxIdx]->data, ctx[ctxIdx]->dataSz);
|
||||||
offset += ctx[i]->dataSz;
|
offset += ctx[ctxIdx]->dataSz;
|
||||||
|
ctxIdx++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
break;
|
break;
|
||||||
@@ -628,14 +631,9 @@ static Error caamAes(struct DescStruct* desc)
|
|||||||
/* fall through because states are the same only the offest changes */
|
/* fall through because states are the same only the offest changes */
|
||||||
|
|
||||||
case CAAM_AESCBC:
|
case CAAM_AESCBC:
|
||||||
case CAAM_AESCCM:
|
|
||||||
{
|
{
|
||||||
int maxSz = 16; /* default to CBC/CTR max size */
|
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;
|
sz = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
for (; i < desc->DescriptorCount; i++) {
|
for (; i < desc->DescriptorCount; i++) {
|
||||||
@@ -683,53 +681,81 @@ static Error caamAes(struct DescStruct* desc)
|
|||||||
return TransferFailed;
|
return TransferFailed;
|
||||||
}
|
}
|
||||||
desc->desc[desc->idx++] = CAAM_OP | CAAM_CLASS1 | desc->type |
|
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 */
|
/* find output buffers */
|
||||||
caamAddIO(desc, (CAAM_FIFO_L | CAAM_CLASS1 | FIFOL_TYPE_MSG),
|
sz = 0;
|
||||||
desc->inputSz, align, &i);
|
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 */
|
/* handle output buffers */
|
||||||
desc->outputIdx = i;
|
if (desc->output != 0 && offset > 0 && sz > 0) {
|
||||||
sz = 0;
|
/* handle potential leftovers */
|
||||||
for (; i < desc->DescriptorCount; i++) {
|
sz -= offset;
|
||||||
struct buffer* buf = &desc->buf[i];
|
desc->desc[desc->idx++] = CAAM_FIFO_S | FIFOS_TYPE_MSG + offset;
|
||||||
if (sz < desc->inputSz) {
|
if (sz > 0) { /* check if expecting more output */
|
||||||
if (desc->idx + 2 > MAX_DESC_SZ) {
|
desc->desc[desc->idx - 1] |= CAAM_FIFOS_CONT;
|
||||||
return TransferFailed;
|
|
||||||
}
|
}
|
||||||
desc->desc[desc->idx++] = CAAM_FIFO_S | FIFOS_TYPE_MSG +
|
desc->desc[desc->idx++] = BSP_VirtualToPhysical(desc->output);
|
||||||
buf->dataSz;
|
|
||||||
desc->desc[desc->idx++] = BSP_VirtualToPhysical(buf->data);
|
|
||||||
sz += buf->dataSz;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
desc->lastIdx = i;
|
|
||||||
|
|
||||||
/* if is CCM mode handle AAD */
|
/* reset */
|
||||||
if (desc->type == CAAM_AESCCM && desc->aadSz > 0) {
|
desc->output = 0;
|
||||||
sz = 0;
|
offset = 0;
|
||||||
for (; i < desc->DescriptorCount; i++) {
|
}
|
||||||
struct buffer* buf = &desc->buf[i];
|
|
||||||
if (sz < desc->aadSz) {
|
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) {
|
if (desc->idx + 2 > MAX_DESC_SZ) {
|
||||||
return TransferFailed;
|
return TransferFailed;
|
||||||
}
|
}
|
||||||
desc->lastFifo = desc->idx;
|
desc->desc[desc->idx++] = CAAM_FIFO_S | FIFOS_TYPE_MSG + tmp;
|
||||||
desc->desc[desc->idx++] = CAAM_FIFO_L | FIFOL_TYPE_AAD +
|
if (sz > 0) { /* check if expecting more output */
|
||||||
buf->dataSz;
|
desc->desc[desc->idx - 1] |= CAAM_FIFOS_CONT;
|
||||||
|
}
|
||||||
desc->desc[desc->idx++] = BSP_VirtualToPhysical(buf->data);
|
desc->desc[desc->idx++] = BSP_VirtualToPhysical(buf->data);
|
||||||
sz += buf->dataSz;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
desc->desc[desc->lastFifo] |= FIFOL_TYPE_LC1;
|
|
||||||
|
|
||||||
/* store updated IV */
|
/* store updated IV */
|
||||||
if (ivIdx > 0) {
|
if (ivIdx > 0) {
|
||||||
@@ -743,9 +769,368 @@ static Error caamAes(struct DescStruct* desc)
|
|||||||
if ((err = caamDoJob(desc)) != Success) {
|
if ((err = caamDoJob(desc)) != Success) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
ASP_FlushCaches((Address)desc->iv, 16);
|
||||||
|
} while (desc->lastIdx < desc->DescriptorCount);
|
||||||
|
|
||||||
/* flush output buffers */
|
/* 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;
|
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++) {
|
for (i = desc->outputIdx; i < desc->lastIdx; i++) {
|
||||||
ASP_FlushCaches(desc->buf[i].data, desc->buf[i].dataSz);
|
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) */
|
/* handle case with IV (This is also the output of MAC with AES-CCM) */
|
||||||
if (ivIdx > 0) {
|
if (ivIdx > 0) {
|
||||||
unsigned char* pt = (unsigned char*)desc->iv;
|
unsigned char* pt = (unsigned char*)desc->iv;
|
||||||
ASP_FlushCaches((Address)pt, 16);
|
ASP_FlushCaches((Address)pt, ivSz);
|
||||||
for (i = 0; i < ivIdx; i++) {
|
for (i = 0; i < ivIdx; i++) {
|
||||||
memcpy((unsigned char*)iv[i]->data, pt, iv[i]->dataSz);
|
memcpy((unsigned char*)iv[i]->data, pt, iv[i]->dataSz);
|
||||||
pt += iv[i]->dataSz;
|
pt += iv[i]->dataSz;
|
||||||
@@ -812,10 +1197,10 @@ static Error caamSha(struct DescStruct* desc, int start)
|
|||||||
{
|
{
|
||||||
struct buffer* ctx[3];
|
struct buffer* ctx[3];
|
||||||
Error err;
|
Error err;
|
||||||
|
UINT4 i;
|
||||||
int sz = 0;
|
int sz = 0;
|
||||||
int ctxIdx = 0;
|
int ctxIdx = 0;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
UINT4 i;
|
|
||||||
|
|
||||||
int ctxSz = shaSize(desc);
|
int ctxSz = shaSize(desc);
|
||||||
|
|
||||||
@@ -909,12 +1294,11 @@ static Error caamSha(struct DescStruct* desc, int start)
|
|||||||
|
|
||||||
/* store context to buffers */
|
/* store context to buffers */
|
||||||
{
|
{
|
||||||
int j;
|
|
||||||
unsigned char* pt = (unsigned char*)desc->iv;
|
unsigned char* pt = (unsigned char*)desc->iv;
|
||||||
for (j = 0; j < ctxIdx; j++) {
|
for (i = 0; i < ctxIdx; i++) {
|
||||||
memcpy((unsigned char*)ctx[j]->data, pt, ctx[j]->dataSz);
|
memcpy((unsigned char*)ctx[i]->data, pt, ctx[i]->dataSz);
|
||||||
pt += ctx[j]->dataSz;
|
pt += ctx[i]->dataSz;
|
||||||
ASP_FlushCaches(ctx[j]->data, ctx[j]->dataSz);
|
ASP_FlushCaches(ctx[i]->data, ctx[i]->dataSz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1058,8 +1442,8 @@ static Error caamRng(struct DescStruct* desc)
|
|||||||
static Error caamTransferStart(IODeviceVector ioCaam,
|
static Error caamTransferStart(IODeviceVector ioCaam,
|
||||||
Value type, const volatile Value args[4])
|
Value type, const volatile Value args[4])
|
||||||
{
|
{
|
||||||
struct DescStruct* desc;
|
|
||||||
struct CAAM_DEVICE* local = (struct CAAM_DEVICE*)ioCaam;
|
struct CAAM_DEVICE* local = (struct CAAM_DEVICE*)ioCaam;
|
||||||
|
struct DescStruct* desc;
|
||||||
|
|
||||||
/* currently only one desc is available for use */
|
/* currently only one desc is available for use */
|
||||||
desc = &local->DescArray[0];
|
desc = &local->DescArray[0];
|
||||||
@@ -1078,14 +1462,35 @@ static Error caamTransferStart(IODeviceVector ioCaam,
|
|||||||
desc->state = args[0];
|
desc->state = args[0];
|
||||||
desc->ctxSz = args[1];
|
desc->ctxSz = args[1];
|
||||||
desc->inputSz = args[2];
|
desc->inputSz = args[2];
|
||||||
desc->aadSz = args[3];
|
desc->aadSz = 0;
|
||||||
desc->desc[desc->idx++] = CAAM_HEAD; /* later will put size to header*/
|
desc->desc[desc->idx++] = CAAM_HEAD; /* later will put size to header*/
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CAAM_AESECB:
|
case CAAM_AESECB:
|
||||||
case CAAM_AESCBC:
|
case CAAM_AESCBC:
|
||||||
case CAAM_AESCTR:
|
case CAAM_AESCTR:
|
||||||
|
break;
|
||||||
|
|
||||||
case CAAM_AESCCM:
|
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;
|
break;
|
||||||
|
|
||||||
case CAAM_MD5:
|
case CAAM_MD5:
|
||||||
@@ -1131,8 +1536,8 @@ static Error caamTransferBuffer(IODeviceVector TheIODeviceVector,
|
|||||||
IORequest req, IODescriptor NewIODescriptor,
|
IORequest req, IODescriptor NewIODescriptor,
|
||||||
Address data, Address dataSz)
|
Address data, Address dataSz)
|
||||||
{
|
{
|
||||||
Error err;
|
|
||||||
struct DescStruct* desc = (struct DescStruct*)req;
|
struct DescStruct* desc = (struct DescStruct*)req;
|
||||||
|
Error err;
|
||||||
|
|
||||||
switch (desc->type) {
|
switch (desc->type) {
|
||||||
case CAAM_AESECB:
|
case CAAM_AESECB:
|
||||||
@@ -1158,7 +1563,11 @@ static Error caamTransferBuffer(IODeviceVector TheIODeviceVector,
|
|||||||
case CAAM_BLOB_DECAP:
|
case CAAM_BLOB_DECAP:
|
||||||
case CAAM_ENTROPY:
|
case CAAM_ENTROPY:
|
||||||
{ /* set buffer for transfer finish */
|
{ /* 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->data = data;
|
||||||
buf->dataSz = dataSz;
|
buf->dataSz = dataSz;
|
||||||
}
|
}
|
||||||
@@ -1190,10 +1599,13 @@ static Error caamTransferFinish(IODeviceVector ioCaam, IORequest req)
|
|||||||
case CAAM_AESECB:
|
case CAAM_AESECB:
|
||||||
case CAAM_AESCTR:
|
case CAAM_AESCTR:
|
||||||
case CAAM_AESCBC:
|
case CAAM_AESCBC:
|
||||||
case CAAM_AESCCM:
|
|
||||||
ret = caamAes(desc);
|
ret = caamAes(desc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CAAM_AESCCM:
|
||||||
|
ret = caamAead(desc);
|
||||||
|
break;
|
||||||
|
|
||||||
case CAAM_MD5:
|
case CAAM_MD5:
|
||||||
case CAAM_SHA:
|
case CAAM_SHA:
|
||||||
case CAAM_SHA224:
|
case CAAM_SHA224:
|
||||||
|
@@ -86,14 +86,17 @@ int wc_caamSetResource(IODevice ioDev)
|
|||||||
*/
|
*/
|
||||||
int wc_caamInit()
|
int wc_caamInit()
|
||||||
{
|
{
|
||||||
|
int ret;
|
||||||
word32 reg;
|
word32 reg;
|
||||||
|
|
||||||
/* get the driver up */
|
/* get the driver up */
|
||||||
if (caam == NULLIODevice) {
|
if (caam == NULLIODevice) {
|
||||||
WOLFSSL_MSG("Starting CAAM driver");
|
WOLFSSL_MSG("Starting CAAM driver");
|
||||||
if (RequestResource((Object *)&caam, "wolfSSL_CAAM_Driver",
|
if ((ret = (int)RequestResource((Object *)&caam, "wolfSSL_CAAM_Driver",
|
||||||
WC_CAAM_PASSWORD) != Success) {
|
WC_CAAM_PASSWORD)) != (int)Success) {
|
||||||
WOLFSSL_MSG("Unable to get the CAAM IODevice, check password?");
|
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
|
#endif
|
||||||
|
|
||||||
|
(void)ret;
|
||||||
return 0;
|
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 wc_caamAddAndWait(Buffer* buf, word32 arg[4], word32 type)
|
||||||
{
|
{
|
||||||
int ret;
|
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)
|
#if defined(WOLFSSL_CAAM_PRINT) || defined(WOLFSSL_CAAM_DEBUG)
|
||||||
printf("ret of SynchronousSendIORequest = %d type = %d\n", ret, type);
|
printf("ret of SynchronousSendIORequest = %d type = %d\n", ret, type);
|
||||||
#endif
|
#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;
|
return WC_CAAM_E;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -63,7 +63,7 @@
|
|||||||
Common Code Between SHA Functions
|
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)
|
word32 type)
|
||||||
{
|
{
|
||||||
Buffer buf[1];
|
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)
|
word32 type)
|
||||||
{
|
{
|
||||||
Buffer buf[2];
|
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)
|
word32 type)
|
||||||
{
|
{
|
||||||
Buffer buf[2];
|
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;
|
int ret;
|
||||||
if ((ret = _ShaFinal(sha, out, SHA256_DIGEST_SIZE, CAAM_SHA256)) != 0) {
|
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) {
|
if (ret == Success) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (ret != Waiting) {
|
|
||||||
|
/* driver could be waiting for entropy */
|
||||||
|
if (ret != WC_CAAM_WAIT) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
@@ -192,8 +192,9 @@ enum {
|
|||||||
ECC_PRIVATEONLY_E = -246, /* Invalid use of private only ECC key*/
|
ECC_PRIVATEONLY_E = -246, /* Invalid use of private only ECC key*/
|
||||||
EXTKEYUSAGE_E = -247, /* Bad Extended Key Usage value */
|
EXTKEYUSAGE_E = -247, /* Bad Extended Key Usage value */
|
||||||
WC_CAAM_E = -248, /* Error with CAAM use */
|
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 */
|
MIN_CODE_E = -300 /* errors -101 - -299 */
|
||||||
|
|
||||||
/* add new companion error id strings for any new error codes
|
/* add new companion error id strings for any new error codes
|
||||||
|
@@ -58,7 +58,7 @@
|
|||||||
#define CAAM_CLASS1 0x02000000/* i.e. AES */
|
#define CAAM_CLASS1 0x02000000/* i.e. AES */
|
||||||
#define CAAM_CLASS2 0x04000000/* i.e. hash algos */
|
#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_DEC 0x00000000
|
||||||
#define CAAM_ALG_INIT 0x00000004
|
#define CAAM_ALG_INIT 0x00000004
|
||||||
#define CAAM_ALG_INITF 0x0000000C
|
#define CAAM_ALG_INITF 0x0000000C
|
||||||
@@ -105,11 +105,15 @@
|
|||||||
|
|
||||||
#define FIFOL_TYPE_MSG 0x00100000
|
#define FIFOL_TYPE_MSG 0x00100000
|
||||||
#define FIFOL_TYPE_AAD 0x00300000
|
#define FIFOL_TYPE_AAD 0x00300000
|
||||||
|
#define FIFOL_TYPE_FC1 0x00010000
|
||||||
#define FIFOL_TYPE_LC1 0x00020000
|
#define FIFOL_TYPE_LC1 0x00020000
|
||||||
#define FIFOL_TYPE_LC2 0x00040000
|
#define FIFOL_TYPE_LC2 0x00040000
|
||||||
|
|
||||||
#define FIFOS_TYPE_MSG 0x00300000
|
#define FIFOS_TYPE_MSG 0x00300000
|
||||||
|
|
||||||
|
/* continue bit set if more output is expected */
|
||||||
|
#define CAAM_FIFOS_CONT 0x00800000
|
||||||
|
|
||||||
#define CAAM_PAGE_SZ 4096
|
#define CAAM_PAGE_SZ 4096
|
||||||
|
|
||||||
/* RNG Registers */
|
/* RNG Registers */
|
||||||
@@ -170,7 +174,6 @@
|
|||||||
#define CAAM_CBCIV CAAM_CTX1 /* AES-CBC iv is in 1 and 2 */
|
#define CAAM_CBCIV CAAM_CTX1 /* AES-CBC iv is in 1 and 2 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* instantiate RNG and create JDKEK, TDKEK, and TDSK key */
|
/* instantiate RNG and create JDKEK, TDKEK, and TDSK key */
|
||||||
static unsigned int wc_rng_start[] = {
|
static unsigned int wc_rng_start[] = {
|
||||||
CAAM_HEAD | 0x00000006,
|
CAAM_HEAD | 0x00000006,
|
||||||
|
@@ -63,22 +63,22 @@
|
|||||||
#endif /* WC_CAAM_MAX_DIGEST */
|
#endif /* WC_CAAM_MAX_DIGEST */
|
||||||
|
|
||||||
|
|
||||||
typedef struct Sha {
|
typedef struct wc_Sha {
|
||||||
word32 ctx[(WC_CAAM_MAX_DIGEST + WC_CAAM_CTXLEN) / sizeof(word32)];
|
word32 ctx[(WC_CAAM_MAX_DIGEST + WC_CAAM_CTXLEN) / sizeof(word32)];
|
||||||
word32 buffLen; /* in bytes */
|
word32 buffLen; /* in bytes */
|
||||||
word32 buffer[WC_CAAM_HASH_BLOCK / sizeof(word32)];
|
word32 buffer[WC_CAAM_HASH_BLOCK / sizeof(word32)];
|
||||||
} Sha;
|
} wc_Sha;
|
||||||
|
|
||||||
#ifndef NO_MD5
|
#ifndef NO_MD5
|
||||||
typedef struct Sha wc_Md5;
|
typedef struct wc_Sha wc_Md5;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NO_SHA256
|
#ifndef NO_SHA256
|
||||||
typedef struct Sha wc_Sha256;
|
typedef struct wc_Sha wc_Sha256;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WOLFSSL_SHA512
|
#ifdef WOLFSSL_SHA512
|
||||||
typedef struct Sha wc_Sha512;
|
typedef struct wc_Sha wc_Sha512;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* WOLFSSL_IMX6_CAAM */
|
#endif /* WOLFSSL_IMX6_CAAM */
|
||||||
|
Reference in New Issue
Block a user