Add AES-CCM hardware acceleration support and other fixes

pull/1270/head
Jacob Barthelmeh 2017-12-20 11:12:36 -07:00
parent 3a6d5b8f90
commit 351a673ec0
10 changed files with 2206 additions and 1855 deletions

View File

@ -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;
}

View File

@ -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";

View File

@ -46,51 +46,50 @@ int wc_AesSetKey(Aes* aes, const byte* key, word32 len,
const byte* iv, int dir)
{
int ret;
if (aes == NULL || key == NULL) {
return BAD_FUNC_ARG;
return BAD_FUNC_ARG;
}
if (len > 32) {
byte out[32]; /* max AES key size */
word32 outSz;
byte out[32]; /* max AES key size */
word32 outSz;
int ret;
if (len != 64 && len != 72 && len != 80) {
return BAD_FUNC_ARG;
}
outSz = sizeof(out);
/* if length greater then 32 then try to unencapsulate */
if ((ret = wc_caamOpenBlob((byte*)key, len, out, &outSz, NULL, 0)) != 0) {
return ret;
}
if (len != 64 && len != 72 && len != 80) {
return BAD_FUNC_ARG;
}
XMEMCPY((byte*)aes->key, out, outSz);
outSz = sizeof(out);
/* if length greater then 32 then try to unencapsulate */
if ((ret = wc_caamOpenBlob((byte*)key, len, out, &outSz)) != 0) {
return ret;
}
XMEMCPY((byte*)aes->key, out, outSz);
aes->keylen = outSz;
}
else {
if (len != 16 && len != 24 && len != 32) {
return BAD_FUNC_ARG;
}
return BAD_FUNC_ARG;
}
XMEMCPY((byte*)aes->key, key, len);
aes->keylen = len;
}
switch (aes->keylen) {
case 16: aes->rounds = 10; break;
case 24: aes->rounds = 12; break;
case 32: aes->rounds = 14; break;
default:
return BAD_FUNC_ARG;
case 16: aes->rounds = 10; break;
case 24: aes->rounds = 12; break;
case 32: aes->rounds = 14; break;
default:
return BAD_FUNC_ARG;
}
if ((ret = wc_AesSetIV(aes, iv)) != 0) {
return ret;
}
#ifdef WOLFSSL_AES_COUNTER
aes->left = 0;
#endif
@ -99,35 +98,18 @@ 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)
{
word32 blocks;
WOLFSSL_ENTER("wc_AesCbcEncrypt");
if (aes == NULL || out == NULL || in == NULL) {
return BAD_FUNC_ARG;
}
blocks = sz / AES_BLOCK_SIZE;
if (blocks > 0) {
Buffer buf[4];
word32 arg[4];
@ -146,7 +128,7 @@ int wc_AesCbcEncrypt(Aes* aes, byte* out,
buf[1].BufferType = DataBuffer;
buf[1].TheAddress = (Address)aes->reg;
buf[1].Length = AES_BLOCK_SIZE;
buf[2].BufferType = DataBuffer;
buf[2].TheAddress = (Address)in;
buf[2].Length = blocks * AES_BLOCK_SIZE;
@ -154,17 +136,17 @@ int wc_AesCbcEncrypt(Aes* aes, byte* out,
buf[3].BufferType = DataBuffer | LastBuffer;
buf[3].TheAddress = (Address)out;
buf[3].Length = blocks * AES_BLOCK_SIZE;
arg[0] = CAAM_ENC;
arg[1] = keySz;
arg[2] = sz;
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCBC)) != 0) {
WOLFSSL_MSG("Error with CAAM AES CBC encrypt");
return ret;
WOLFSSL_MSG("Error with CAAM AES CBC encrypt");
return ret;
}
}
return 0;
}
@ -173,14 +155,14 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out,
const byte* in, word32 sz)
{
word32 blocks;
WOLFSSL_ENTER("wc_AesCbcDecrypt");
if (aes == NULL || out == NULL || in == NULL) {
return BAD_FUNC_ARG;
}
blocks = sz / AES_BLOCK_SIZE;
if (blocks > 0) {
Buffer buf[4];
word32 arg[4];
@ -188,7 +170,7 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out,
int ret;
if (wc_AesGetKeySize(aes, &keySz) != 0) {
return BAD_FUNC_ARG;
return BAD_FUNC_ARG;
}
/* Set buffers for key, cipher text, and plain text */
@ -199,7 +181,7 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out,
buf[1].BufferType = DataBuffer;
buf[1].TheAddress = (Address)aes->reg;
buf[1].Length = AES_BLOCK_SIZE;
buf[2].BufferType = DataBuffer;
buf[2].TheAddress = (Address)in;
buf[2].Length = blocks * AES_BLOCK_SIZE;
@ -207,17 +189,17 @@ int wc_AesCbcDecrypt(Aes* aes, byte* out,
buf[3].BufferType = DataBuffer | LastBuffer;
buf[3].TheAddress = (Address)out;
buf[3].Length = blocks * AES_BLOCK_SIZE;
arg[0] = CAAM_DEC;
arg[1] = keySz;
arg[2] = sz;
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCBC)) != 0) {
WOLFSSL_MSG("Error with CAAM AES CBC decrypt");
return ret;
WOLFSSL_MSG("Error with CAAM AES CBC decrypt");
return ret;
}
}
return 0;
}
@ -227,20 +209,20 @@ int wc_AesEcbEncrypt(Aes* aes, byte* out,
const byte* in, word32 sz)
{
word32 blocks;
if (aes == NULL || out == NULL || in == NULL) {
BAD_FUNC_ARG;
}
blocks = sz / AES_BLOCK_SIZE;
while (blocks > 0) {
wc_AesEncryptDirect(aes, out, in);
blocks--;
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
blocks--;
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
}
return 0;
}
@ -249,7 +231,7 @@ int wc_AesEcbDecrypt(Aes* aes, byte* out,
const byte* in, word32 sz)
{
word32 blocks;
if (aes == NULL || out == NULL || in == NULL) {
BAD_FUNC_ARG;
}
@ -259,11 +241,11 @@ int wc_AesEcbDecrypt(Aes* aes, byte* out,
/* @TODO search for more efficient solution */
while (blocks > 0) {
wc_AesDecryptDirect(aes, out, in);
blocks--;
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
blocks--;
out += AES_BLOCK_SIZE;
in += AES_BLOCK_SIZE;
}
return 0;
}
#endif
@ -281,62 +263,62 @@ static INLINE void IncrementAesCounter(byte* inOutCtr)
}
}
int wc_AesCtrEncrypt(Aes* aes, byte* out,
const byte* in, word32 sz)
{
byte* tmp;
Buffer buf[4];
word32 arg[4];
word32 keySz;
int ret, blocks;
byte* tmp;
Buffer buf[4];
word32 arg[4];
word32 keySz;
int ret, blocks;
if (aes == NULL || out == NULL || in == NULL) {
return BAD_FUNC_ARG;
}
if (aes == NULL || out == NULL || in == NULL) {
return BAD_FUNC_ARG;
}
if (wc_AesGetKeySize(aes, &keySz) != 0) {
return BAD_FUNC_ARG;
}
if (wc_AesGetKeySize(aes, &keySz) != 0) {
return BAD_FUNC_ARG;
}
/* consume any unused bytes left in aes->tmp */
tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
while (aes->left && sz) {
*(out++) = *(in++) ^ *(tmp++);
aes->left--;
sz--;
}
/* consume any unused bytes left in aes->tmp */
tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left;
while (aes->left && sz) {
*(out++) = *(in++) ^ *(tmp++);
aes->left--;
sz--;
}
/* do full blocks to then get potential left over amount */
blocks = sz / AES_BLOCK_SIZE;
if (blocks > 0) {
/* Set buffers for key, cipher text, and plain text */
buf[0].BufferType = DataBuffer;
buf[0].TheAddress = (Address)aes->key;
buf[0].Length = keySz;
/* do full blocks to then get potential left over amount */
blocks = sz / AES_BLOCK_SIZE;
if (blocks > 0) {
/* Set buffers for key, cipher text, and plain text */
buf[0].BufferType = DataBuffer;
buf[0].TheAddress = (Address)aes->key;
buf[0].Length = keySz;
buf[1].BufferType = DataBuffer;
buf[1].TheAddress = (Address)aes->reg;
buf[1].Length = AES_BLOCK_SIZE;
buf[2].BufferType = DataBuffer;
buf[2].TheAddress = (Address)in;
buf[2].Length = blocks * AES_BLOCK_SIZE;
buf[1].BufferType = DataBuffer;
buf[1].TheAddress = (Address)aes->reg;
buf[1].Length = AES_BLOCK_SIZE;
buf[3].BufferType = DataBuffer | LastBuffer;
buf[3].TheAddress = (Address)out;
buf[3].Length = blocks * AES_BLOCK_SIZE;
arg[0] = CAAM_ENC;
arg[1] = keySz;
arg[2] = sz;
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCTR)) != 0) {
WOLFSSL_MSG("Error with CAAM AES CTR encrypt");
return ret;
}
out += blocks * AES_BLOCK_SIZE;
sz -= blocks * AES_BLOCK_SIZE;
buf[2].BufferType = DataBuffer;
buf[2].TheAddress = (Address)in;
buf[2].Length = blocks * AES_BLOCK_SIZE;
buf[3].BufferType = DataBuffer | LastBuffer;
buf[3].TheAddress = (Address)out;
buf[3].Length = blocks * AES_BLOCK_SIZE;
arg[0] = CAAM_ENC;
arg[1] = keySz;
arg[2] = sz;
if ((ret = wc_caamAddAndWait(buf, arg, CAAM_AESCTR)) != 0) {
WOLFSSL_MSG("Error with CAAM AES CTR encrypt");
return ret;
}
out += blocks * AES_BLOCK_SIZE;
sz -= blocks * AES_BLOCK_SIZE;
}
if (sz) {
@ -351,7 +333,7 @@ int wc_AesCtrEncrypt(Aes* aes, byte* out,
aes->left--;
}
}
return 0;
}
#endif
@ -366,13 +348,13 @@ 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;
/* return BAD_FUNC_ARG; */
return;
}
/* Set buffers for key, cipher text, and plain text */
@ -387,11 +369,11 @@ void wc_AesEncryptDirect(Aes* aes, byte* out, const byte* in)
buf[2].BufferType = DataBuffer | LastBuffer;
buf[2].TheAddress = (Address)out;
buf[2].Length = AES_BLOCK_SIZE;
arg[0] = CAAM_ENC;
arg[1] = keySz;
arg[2] = AES_BLOCK_SIZE;
if (wc_caamAddAndWait(buf, arg, CAAM_AESECB) != 0) {
WOLFSSL_MSG("Error with CAAM AES direct encrypt");
}
@ -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;
}
@ -426,11 +408,11 @@ void wc_AesDecryptDirect(Aes* aes, byte* out, const byte* in)
buf[2].BufferType = DataBuffer | LastBuffer;
buf[2].TheAddress = (Address)out;
buf[2].Length = AES_BLOCK_SIZE;
arg[0] = CAAM_DEC;
arg[1] = keySz;
arg[2] = AES_BLOCK_SIZE;
if (wc_caamAddAndWait(buf, arg, CAAM_AESECB) != 0) {
WOLFSSL_MSG("Error with CAAM AES direct decrypt");
}
@ -445,78 +427,26 @@ 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);
int ret;
/* 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,18 +464,10 @@ 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;
buf[0].TheAddress = (Address)aes->key;
@ -553,32 +476,33 @@ int wc_AesCcmEncrypt(Aes* aes, byte* out,
buf[1].BufferType = DataBuffer;
buf[1].TheAddress = (Address)B0Ctr0;
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;
return ret;
}
XMEMCPY(authTag, B0Ctr0, authTagSz);
return 0;
}
#ifdef HAVE_AES_DECRYPT
int wc_AesCcmDecrypt(Aes* aes, byte* out,
@ -587,21 +511,21 @@ 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);
int ret;
/* 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,18 +543,11 @@ 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;
buf[0].TheAddress = (Address)aes->key;
@ -638,72 +556,46 @@ int wc_AesCcmDecrypt(Aes* aes, byte* out,
buf[1].BufferType = DataBuffer;
buf[1].TheAddress = (Address)B0Ctr0;
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 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 */

File diff suppressed because it is too large Load Diff

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);

View File

@ -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

View File

@ -1,184 +1,187 @@
/* caam_driver.h
*
* Copyright (C) 2006-2016 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef CAAM_DRIVER_H
#define CAAM_DRIVER_H
#define CAAM_BASE 0xf2100000
#define CAAM_PAGE 0xf0100000
#define CAAM_PAGE_MAX 6
/******************************************************************************
Basic Descriptors
****************************************************************************/
/* descriptor commands */
#define CAAM_KEY 0x00000000
#define CAAM_LOAD 0x10000000
#define CAAM_LOAD_CTX 0x10200000
#define CAAM_IMM 0x00800000
#define CAAM_FIFO_L 0x20000000
#define CAAM_FIFO_S 0x60000000
#define CAAM_FIFO_S_SKEY 0x60260000
#define CAAM_STORE 0x50000000
#define CAAM_STORE_CTX 0x50200000
#define CAAM_MOVE 0x78000000
#define CAAM_OP 0x80000000
#define CAAM_SIG 0x90000000
#define CAAM_JUMP 0xA0000000
#define CAAM_SEQI 0xF0000000/* SEQ in */
#define CAAM_SEQO 0xF8000000/* SEQ out */
#define CAAM_HEAD 0xB0800000
#define CAAM_NWB 0x00200000
#define CAAM_BLOB_ENCAP 0x07000000
#define CAAM_BLOB_DECAP 0x06000000
#define CAAM_OPID_BLOB 0x000D0000
/* algorithms modes and types */
#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_DEC 0x00000000
#define CAAM_ALG_INIT 0x00000004
#define CAAM_ALG_INITF 0x0000000C
#define CAAM_ALG_UPDATE 0x00000000
#define CAAM_ALG_FINAL 0x00000008
/* AES 10h */
#define CAAM_AESCTR 0x00100000
#define CAAM_AESCBC 0x00100100
#define CAAM_AESECB 0x00100200
#define CAAM_AESCFB 0x00100300
#define CAAM_AESOFB 0x00100400
#define CAAM_CMAC 0x00100600
#define CAAM_AESCCM 0x00100800
/* HASH 40h */
#define CAAM_MD5 0x00400000
#define CAAM_SHA 0x00410000
#define CAAM_SHA224 0x00420000
#define CAAM_SHA256 0x00430000
#define CAAM_SHA384 0x00440000
#define CAAM_SHA512 0x00450000
/* HMAC 40h + 10 AAI */
#define CAAM_HMAC_MD5 0x00400010
#define CAAM_HMAC_SHA 0x00410010
#define CAAM_HMAC_SHA224 0x00420010
#define CAAM_HMAC_SHA256 0x00430010
#define CAAM_HMAC_SHA384 0x00440010
#define CAAM_HMAC_SHA512 0x00450010
#define CAAM_MD5_CTXSZ (16 + 8)
#define CAAM_SHA_CTXSZ (20 + 8)
#define CAAM_SHA224_CTXSZ (32 + 8)
#define CAAM_SHA256_CTXSZ (32 + 8)
#define CAAM_SHA384_CTXSZ (64 + 8)
#define CAAM_SHA512_CTXSZ (64 + 8)
/* RNG 50h */
#define CAAM_RNG 0x00500000
/* Used to get raw entropy from TRNG */
#define CAAM_ENTROPY 0x00500001
#define FIFOL_TYPE_MSG 0x00100000
#define FIFOL_TYPE_AAD 0x00300000
#define FIFOL_TYPE_LC1 0x00020000
#define FIFOL_TYPE_LC2 0x00040000
#define FIFOS_TYPE_MSG 0x00300000
#define CAAM_PAGE_SZ 4096
/* RNG Registers */
#define CAAM_RTMCTL CAAM_BASE + 0X0600
#define CAAM_RTSDCTL CAAM_BASE + 0X0610
#define CAAM_RTFRQMIN CAAM_BASE + 0X0618
#define CAAM_RTFRQMAX CAAM_BASE + 0X061C
#define CAAM_RDSTA CAAM_BASE + 0X06C0
#define CAAM_RTSTATUS CAAM_BASE + 0x063C
/* each of the following 11 RTENT registers are an offset of 4 from RTENT0 */
#define CAAM_RTENT0 CAAM_BASE + 0x0640
#define CAAM_RTENT11 CAAM_BASE + 0x066C /* Max RTENT register */
/* RNG Masks/Values */
#ifndef CAAM_ENT_DLY
#define CAAM_ENT_DLY 1200 /* @TODO lower value may gain performance */
#endif
#define CAAM_PRGM 0x00010000 /* Set RTMCTL to program state */
#define CAAM_TRNG 0x00000020 /* Set TRNG access */
#define CAAM_CTLERR 0x00001000
#define CAAM_ENTVAL 0x00000400 /* checking RTMCTL for entropy ready */
/* Input Job Ring Registers */
#define CAAM_IRBAR0 CAAM_BASE + 0x1004
#define CAAM_IRSR0 CAAM_BASE + 0x100C
#define CAAM_IRJAR0 CAAM_BASE + 0x101C
/* Ouput Job Ring Registers */
#define CAAM_ORBAR0 CAAM_BASE + 0x1024
#define CAAM_ORSR0 CAAM_BASE + 0x102C
#define CAAM_ORJAR0 CAAM_BASE + 0x103C
/* Status Registers */
#define CAAM_STATUS CAAM_BASE + 0x0FD4
#define CAAM_VERSION_MS CAAM_BASE + 0x0FE8
#define CAAM_VERSION_LS CAAM_BASE + 0x0FEC
#define CAMM_SUPPORT_MS CAAM_BASE + 0x0FF0
#define CAMM_SUPPORT_LS CAAM_BASE + 0x0FF4
#define CAAM_C1DSR_LS CAAM_BASE + 0x8014
#define CAAM_C1MR CAAM_BASE + 0x8004
/* output FIFO is 16 entries deep and each entry has a two 4 byte registers */
#define CAAM_FIFOO_MS CAAM_BASE + 0x87F0
#define CAAM_FIFOO_LS CAAM_BASE + 0x87F4
/* input FIFO is 16 entries deep with each entry having two 4 byte registers
All data writin to it from IP bus should be in big endian format */
#define CAAM_FIFOI_LS CAAM_BASE + 0x87E0
/* offset of 4 with range 0 .. 13 */
#define CAAM_CTX1 CAAM_BASE + 0x8100
#define CAAM_CTRIV CAAM_CTX1 + 8 /* AES-CTR iv is in 2 and 3 */
#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,
CAAM_OP | CAAM_CLASS1 | CAAM_RNG | 0x00000004, /* Instantiate RNG handle 0 with TRNG */
CAAM_JUMP | 0x02000001, /* wait for Class1 RNG and jump to next cmd */
CAAM_LOAD | 0x00880004, /* Load to clear written register */
0x00000001, /* reset done interupt */
CAAM_OP | CAAM_CLASS1 | CAAM_RNG | 0x00001000 /* Generate secure keys */
};
#endif /* CAAM_DRIVER_H */
/* caam_driver.h
*
* Copyright (C) 2006-2016 wolfSSL Inc.
*
* This file is part of wolfSSL.
*
* wolfSSL is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* wolfSSL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
*/
#ifndef CAAM_DRIVER_H
#define CAAM_DRIVER_H
#define CAAM_BASE 0xf2100000
#define CAAM_PAGE 0xf0100000
#define CAAM_PAGE_MAX 6
/******************************************************************************
Basic Descriptors
****************************************************************************/
/* descriptor commands */
#define CAAM_KEY 0x00000000
#define CAAM_LOAD 0x10000000
#define CAAM_LOAD_CTX 0x10200000
#define CAAM_IMM 0x00800000
#define CAAM_FIFO_L 0x20000000
#define CAAM_FIFO_S 0x60000000
#define CAAM_FIFO_S_SKEY 0x60260000
#define CAAM_STORE 0x50000000
#define CAAM_STORE_CTX 0x50200000
#define CAAM_MOVE 0x78000000
#define CAAM_OP 0x80000000
#define CAAM_SIG 0x90000000
#define CAAM_JUMP 0xA0000000
#define CAAM_SEQI 0xF0000000/* SEQ in */
#define CAAM_SEQO 0xF8000000/* SEQ out */
#define CAAM_HEAD 0xB0800000
#define CAAM_NWB 0x00200000
#define CAAM_BLOB_ENCAP 0x07000000
#define CAAM_BLOB_DECAP 0x06000000
#define CAAM_OPID_BLOB 0x000D0000
/* algorithms modes and types */
#define CAAM_CLASS1 0x02000000/* i.e. AES */
#define CAAM_CLASS2 0x04000000/* i.e. hash algos */
#define CAAM_ENC 0x00000001
#define CAAM_DEC 0x00000000
#define CAAM_ALG_INIT 0x00000004
#define CAAM_ALG_INITF 0x0000000C
#define CAAM_ALG_UPDATE 0x00000000
#define CAAM_ALG_FINAL 0x00000008
/* AES 10h */
#define CAAM_AESCTR 0x00100000
#define CAAM_AESCBC 0x00100100
#define CAAM_AESECB 0x00100200
#define CAAM_AESCFB 0x00100300
#define CAAM_AESOFB 0x00100400
#define CAAM_CMAC 0x00100600
#define CAAM_AESCCM 0x00100800
/* HASH 40h */
#define CAAM_MD5 0x00400000
#define CAAM_SHA 0x00410000
#define CAAM_SHA224 0x00420000
#define CAAM_SHA256 0x00430000
#define CAAM_SHA384 0x00440000
#define CAAM_SHA512 0x00450000
/* HMAC 40h + 10 AAI */
#define CAAM_HMAC_MD5 0x00400010
#define CAAM_HMAC_SHA 0x00410010
#define CAAM_HMAC_SHA224 0x00420010
#define CAAM_HMAC_SHA256 0x00430010
#define CAAM_HMAC_SHA384 0x00440010
#define CAAM_HMAC_SHA512 0x00450010
#define CAAM_MD5_CTXSZ (16 + 8)
#define CAAM_SHA_CTXSZ (20 + 8)
#define CAAM_SHA224_CTXSZ (32 + 8)
#define CAAM_SHA256_CTXSZ (32 + 8)
#define CAAM_SHA384_CTXSZ (64 + 8)
#define CAAM_SHA512_CTXSZ (64 + 8)
/* RNG 50h */
#define CAAM_RNG 0x00500000
/* Used to get raw entropy from TRNG */
#define CAAM_ENTROPY 0x00500001
#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 */
#define CAAM_RTMCTL CAAM_BASE + 0X0600
#define CAAM_RTSDCTL CAAM_BASE + 0X0610
#define CAAM_RTFRQMIN CAAM_BASE + 0X0618
#define CAAM_RTFRQMAX CAAM_BASE + 0X061C
#define CAAM_RDSTA CAAM_BASE + 0X06C0
#define CAAM_RTSTATUS CAAM_BASE + 0x063C
/* each of the following 11 RTENT registers are an offset of 4 from RTENT0 */
#define CAAM_RTENT0 CAAM_BASE + 0x0640
#define CAAM_RTENT11 CAAM_BASE + 0x066C /* Max RTENT register */
/* RNG Masks/Values */
#ifndef CAAM_ENT_DLY
#define CAAM_ENT_DLY 1200 /* @TODO lower value may gain performance */
#endif
#define CAAM_PRGM 0x00010000 /* Set RTMCTL to program state */
#define CAAM_TRNG 0x00000020 /* Set TRNG access */
#define CAAM_CTLERR 0x00001000
#define CAAM_ENTVAL 0x00000400 /* checking RTMCTL for entropy ready */
/* Input Job Ring Registers */
#define CAAM_IRBAR0 CAAM_BASE + 0x1004
#define CAAM_IRSR0 CAAM_BASE + 0x100C
#define CAAM_IRJAR0 CAAM_BASE + 0x101C
/* Ouput Job Ring Registers */
#define CAAM_ORBAR0 CAAM_BASE + 0x1024
#define CAAM_ORSR0 CAAM_BASE + 0x102C
#define CAAM_ORJAR0 CAAM_BASE + 0x103C
/* Status Registers */
#define CAAM_STATUS CAAM_BASE + 0x0FD4
#define CAAM_VERSION_MS CAAM_BASE + 0x0FE8
#define CAAM_VERSION_LS CAAM_BASE + 0x0FEC
#define CAMM_SUPPORT_MS CAAM_BASE + 0x0FF0
#define CAMM_SUPPORT_LS CAAM_BASE + 0x0FF4
#define CAAM_C1DSR_LS CAAM_BASE + 0x8014
#define CAAM_C1MR CAAM_BASE + 0x8004
/* output FIFO is 16 entries deep and each entry has a two 4 byte registers */
#define CAAM_FIFOO_MS CAAM_BASE + 0x87F0
#define CAAM_FIFOO_LS CAAM_BASE + 0x87F4
/* input FIFO is 16 entries deep with each entry having two 4 byte registers
All data writin to it from IP bus should be in big endian format */
#define CAAM_FIFOI_LS CAAM_BASE + 0x87E0
/* offset of 4 with range 0 .. 13 */
#define CAAM_CTX1 CAAM_BASE + 0x8100
#define CAAM_CTRIV CAAM_CTX1 + 8 /* AES-CTR iv is in 2 and 3 */
#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,
CAAM_OP | CAAM_CLASS1 | CAAM_RNG | 0x00000004, /* Instantiate RNG handle 0 with TRNG */
CAAM_JUMP | 0x02000001, /* wait for Class1 RNG and jump to next cmd */
CAAM_LOAD | 0x00880004, /* Load to clear written register */
0x00000001, /* reset done interupt */
CAAM_OP | CAAM_CLASS1 | CAAM_RNG | 0x00001000 /* Generate secure keys */
};
#endif /* CAAM_DRIVER_H */

View File

@ -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 */