#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#if defined(WOLFSSL_IMXRT1170_CAAM)
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/port/caam/wolfcaam.h>
#ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV
#define wc_ecc_key_get_priv(key) (&((key)->k))
#define WOLFSSL_HAVE_ECC_KEY_GET_PRIV
#endif
#if defined(FSL_FEATURE_HAS_L1CACHE) || defined(__DCACHE_PRESENT)
AT_NONCACHEABLE_SECTION(static caam_job_ring_interface_t jr0);
AT_NONCACHEABLE_SECTION(static caam_job_ring_interface_t jr1);
AT_NONCACHEABLE_SECTION(static caam_job_ring_interface_t jr2);
AT_NONCACHEABLE_SECTION(static caam_job_ring_interface_t jr3);
#else
static caam_job_ring_interface_t jr0;
static caam_job_ring_interface_t jr1;
static caam_job_ring_interface_t jr2;
static caam_job_ring_interface_t jr3;
#endif
static wolfSSL_Mutex caamMutex;
int wc_CAAMInitInterface()
{
CAAM_Type *base = CAAM;
caam_config_t caamConfig;
if (wc_InitMutex(&caamMutex) != 0) {
WOLFSSL_MSG("Could not init mutex");
return -1;
}
CAAM_GetDefaultConfig(&caamConfig);
caamConfig.jobRingInterface[0] = &jr0;
caamConfig.jobRingInterface[1] = &jr1;
caamConfig.jobRingInterface[2] = &jr2;
caamConfig.jobRingInterface[3] = &jr3;
if (CAAM_Init(base, &caamConfig) != kStatus_Success) {
return -1;
}
return 0;
}
void wc_CAAMFreeInterface()
{
wc_FreeMutex(&caamMutex);
if (CAAM_Deinit(CAAM) != kStatus_Success) {
WOLFSSL_MSG("Failed to deinit CAAM!");
}
}
#if !defined(NO_SHA) || defined(WOLFSSL_SHA224) || !defined(NO_SHA256) \
|| defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512)
static caam_hash_algo_t WC2NXP(int type)
{
switch (type) {
case WC_HASH_TYPE_SHA:
return kCAAM_Sha1;
case WC_HASH_TYPE_SHA224:
return kCAAM_Sha224;
case WC_HASH_TYPE_SHA256:
return kCAAM_Sha256;
case WC_HASH_TYPE_SHA384:
return kCAAM_Sha384;
case WC_HASH_TYPE_SHA512:
return kCAAM_Sha512;
default:
return -1;
}
}
int wc_CAAM_HashInit(caam_handle_t* hndl, caam_hash_ctx_t* ctx, int type)
{
if (hndl == NULL || ctx == NULL) {
return BAD_FUNC_ARG;
}
hndl->jobRing = kCAAM_JobRing0;
if (CAAM_HASH_Init(CAAM, hndl, ctx, WC2NXP(type), NULL, 0u)
!= kStatus_Success) {
return WC_HW_E;
}
return 0;
}
static int wc_CAAM_CommonHash(caam_handle_t* hndl, caam_hash_ctx_t *ctx,
const byte* in, int inSz, byte* digest, size_t digestSz, int hashType)
{
int ret = 0;
status_t status;
if (in != NULL && inSz > 0) {
byte *alignedIn = NULL;
byte *tmpIn = NULL;
if ((wc_ptr_t)in % CAAM_BUFFER_ALIGN) {
tmpIn = (byte*)XMALLOC(inSz + CAAM_BUFFER_ALIGN, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
alignedIn = tmpIn + (CAAM_BUFFER_ALIGN -
((wc_ptr_t)tmpIn % CAAM_BUFFER_ALIGN));
XMEMCPY(alignedIn, in, inSz);
}
else {
alignedIn = (byte*)in;
}
status = CAAM_HASH_Update(ctx, alignedIn, inSz);
XFREE(tmpIn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (status != kStatus_Success) {
return WC_HW_E;
}
}
if (digest != NULL) {
byte *tmpOut = NULL;
byte *alignedOut = NULL;
size_t sz = digestSz;
if ((wc_ptr_t)digest % CAAM_BUFFER_ALIGN) {
tmpOut = (byte*)XMALLOC(sz + CAAM_BUFFER_ALIGN, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
alignedOut = tmpOut + (CAAM_BUFFER_ALIGN -
((wc_ptr_t)tmpOut % CAAM_BUFFER_ALIGN));
}
else {
alignedOut = digest;
}
status = CAAM_HASH_Finish(ctx, alignedOut, &sz);
if (tmpOut != NULL) {
XMEMCPY(digest, alignedOut, sz);
XFREE(tmpOut, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
if (status != kStatus_Success) {
WOLFSSL_MSG("Failed on CAAM_HASH_Finish");
return WC_HW_E;
}
else {
ret = wc_CAAM_HashInit(hndl, ctx, hashType);
}
}
return ret;
}
#endif
#if !defined(NO_SHA)
int wc_CAAM_ShaHash(wc_Sha* sha, const byte* in, word32 inSz, byte* digest)
{
return wc_CAAM_CommonHash(&sha->hndl, &sha->ctx, in, inSz, digest,
WC_SHA_DIGEST_SIZE, WC_HASH_TYPE_SHA);
}
#endif
#ifdef WOLFSSL_SHA224
int wc_CAAM_Sha224Hash(wc_Sha224* sha, const byte* in, word32 inSz,
byte* digest)
{
return wc_CAAM_CommonHash(&sha->hndl, &sha->ctx, in, inSz, digest,
WC_SHA224_DIGEST_SIZE, WC_HASH_TYPE_SHA224);
}
#endif
#if !defined(NO_SHA256)
int wc_CAAM_Sha256Hash(wc_Sha256* sha, const byte* in, word32 inSz,
byte* digest)
{
return wc_CAAM_CommonHash(&sha->hndl, &sha->ctx, in, inSz, digest,
WC_SHA256_DIGEST_SIZE, WC_HASH_TYPE_SHA256);
}
#endif
#ifdef WOLFSSL_SHA384
int wc_CAAM_Sha384Hash(wc_Sha384* sha, const byte* in, word32 inSz,
byte* digest)
{
return wc_CAAM_CommonHash(&sha->hndl, &sha->ctx, in, inSz, digest,
WC_SHA384_DIGEST_SIZE, WC_HASH_TYPE_SHA384);
}
#endif
#ifdef WOLFSSL_SHA512
int wc_CAAM_Sha512Hash(wc_Sha512* sha, const byte* in, word32 inSz,
byte* digest)
{
return wc_CAAM_CommonHash(&sha->hndl, &sha->ctx, in, inSz, digest,
WC_SHA512_DIGEST_SIZE, WC_HASH_TYPE_SHA512);
}
#endif
#ifndef NO_AES_CBC
static int DoAesCBC(unsigned int args[4], CAAM_BUFFER *buf, int sz)
{
status_t status;
caam_handle_t hndl;
hndl.jobRing = kCAAM_JobRing0;
if (args[0] == CAAM_DEC) {
status = CAAM_AES_DecryptCbc(CAAM, &hndl,
(const uint8_t*)buf[2].TheAddress, (uint8_t*)buf[3].TheAddress,
buf[3].Length, (const uint8_t*)buf[4].TheAddress,
(const uint8_t*)buf[0].TheAddress, buf[0].Length);
XMEMCPY((byte*)buf[4].TheAddress,
(byte*)buf[2].TheAddress + buf[2].Length - WC_AES_BLOCK_SIZE,
WC_AES_BLOCK_SIZE);
}
else {
status = CAAM_AES_EncryptCbc(CAAM, &hndl,
(const uint8_t*)buf[2].TheAddress, (uint8_t*)buf[3].TheAddress,
buf[3].Length, (const uint8_t*)buf[4].TheAddress,
(const uint8_t*)buf[0].TheAddress, buf[0].Length);
XMEMCPY((byte*)buf[4].TheAddress,
(byte*)buf[3].TheAddress + buf[3].Length - WC_AES_BLOCK_SIZE,
WC_AES_BLOCK_SIZE);
}
if (status != kStatus_Success) {
return -1;
}
return 0;
}
#endif
#ifdef WOLFSSL_AES_COUNTER
static int DoAesCTR(unsigned int args[4], CAAM_BUFFER *buf, int sz)
{
status_t status;
caam_handle_t hndl;
byte *tmpIn = NULL;
byte *tmpOut = NULL;
byte *alignedIn = NULL;
byte *alignedOut = NULL;
if (buf[2].TheAddress % CAAM_BUFFER_ALIGN) {
tmpIn = (byte*)XMALLOC(buf[2].Length + CAAM_BUFFER_ALIGN, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
alignedIn = tmpIn + (CAAM_BUFFER_ALIGN -
((wc_ptr_t)tmpIn % CAAM_BUFFER_ALIGN));
XMEMCPY(alignedIn, (byte*)buf[2].TheAddress, buf[2].Length);
}
else {
alignedIn = (byte*)buf[2].TheAddress;
}
if (buf[3].TheAddress % CAAM_BUFFER_ALIGN) {
tmpOut = (byte*)XMALLOC(buf[3].Length + CAAM_BUFFER_ALIGN, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
alignedOut = tmpOut + (CAAM_BUFFER_ALIGN -
((wc_ptr_t)tmpOut % CAAM_BUFFER_ALIGN));
}
else {
alignedOut = (byte*)buf[3].TheAddress;
}
hndl.jobRing = kCAAM_JobRing0;
status = CAAM_AES_CryptCtr(CAAM, &hndl, alignedIn, alignedOut,
buf[3].Length, (byte*)buf[4].TheAddress, (byte*)buf[0].TheAddress,
buf[0].Length, (byte*)buf[2].TheAddress, NULL);
if (tmpOut != NULL) {
XMEMCPY((byte*)buf[3].TheAddress, alignedOut, buf[3].Length);
XFREE(tmpOut, NULL, DYNAMIC_TYPE_TMP_BUFFER);
}
XFREE(tmpIn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (status != kStatus_Success) {
return -1;
}
return 0;
}
#endif
#if defined(HAVE_ECC) && defined(WOLFSSL_CAAM_ECC)
#include <wolfssl/wolfcrypt/asn.h>
static word32 GetECDSEL(int curveId)
{
word32 ecdsel = 0;
switch (curveId) {
case ECC_SECP192R1:
ecdsel = CAAM_ECDSA_P192;
break;
case ECC_SECP224R1:
ecdsel = CAAM_ECDSA_P224;
break;
case ECC_CURVE_DEF:
case ECC_SECP256R1:
ecdsel = CAAM_ECDSA_P256;
break;
case ECC_SECP384R1:
ecdsel = CAAM_ECDSA_P384;
break;
case ECC_SECP521R1:
ecdsel = CAAM_ECDSA_P521;
break;
default:
WOLFSSL_MSG("not using preset curve parameters");
}
return ecdsel;
}
int wc_CAAM_EccSign(const byte* in, int inlen, byte* out, word32* outlen,
WC_RNG *rng, ecc_key *key, int devId)
{
const ecc_set_type* dp;
int ret = 0;
ALIGN16 byte k[MAX_ECC_BYTES + WC_CAAM_MAC_SZ];
word32 kSz = MAX_ECC_BYTES + WC_CAAM_MAC_SZ;
byte *alignedIn = NULL;
byte *tmpIn = NULL;
ALIGN16 byte r[MAX_ECC_BYTES] = {0};
ALIGN16 byte s[MAX_ECC_BYTES] = {0};
word32 rSz = MAX_ECC_BYTES;
word32 sSz = MAX_ECC_BYTES;
int keySz;
word32 ecdsel;
word32 enc = 0;
status_t status;
caam_handle_t hndl;
hndl.jobRing = kCAAM_JobRing0;
(void)rng;
if (key->dp != NULL) {
dp = key->dp;
}
else {
dp = wc_ecc_get_curve_params(key->idx);
}
if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) {
WOLFSSL_MSG("Limiting CAAM to P256/P384 for now");
return CRYPTOCB_UNAVAILABLE;
}
ecdsel = GetECDSEL(dp->id);
if (ecdsel == 0) {
WOLFSSL_MSG("Unsupported curve type");
return BAD_FUNC_ARG;
}
keySz = kSz = wc_ecc_size(key);
if (key->blackKey == CAAM_BLACK_KEY_SM) {
ret = -1;
}
else {
if (key->blackKey == CAAM_BLACK_KEY_CCM) {
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(key), k,
kSz + WC_CAAM_MAC_SZ) != MP_OKAY) {
ForceZero(k, sizeof(k));
return MP_TO_E;
}
}
else {
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(key), k, kSz) !=
MP_OKAY) {
ForceZero(k, sizeof(k));
return MP_TO_E;
}
}
}
ecdsel = GetECDSEL(dp->id);
if (ecdsel == 0) {
WOLFSSL_MSG("unknown key type or size");
ForceZero(k, sizeof(k));
return CRYPTOCB_UNAVAILABLE;
}
switch (key->blackKey) {
case 0:
enc = 0;
break;
case CAAM_BLACK_KEY_ECB:
enc = CAAM_PKHA_ENC_PRI_AESECB;
break;
default:
WOLFSSL_MSG("unknown/unsupported key type");
ForceZero(k, sizeof(k));
return BAD_FUNC_ARG;
}
if ((wc_ptr_t)in % CAAM_BUFFER_ALIGN) {
tmpIn = (byte*)XMALLOC(inlen + CAAM_BUFFER_ALIGN, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
alignedIn = tmpIn + (CAAM_BUFFER_ALIGN -
((wc_ptr_t)tmpIn % CAAM_BUFFER_ALIGN));
XMEMCPY(alignedIn, in, inlen);
}
else {
alignedIn = (byte*)in;
}
status = CAAM_ECC_Sign(CAAM, &hndl, k, kSz, alignedIn, inlen, r, rSz, s,
sSz, ecdsel, enc);
XFREE(tmpIn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (status != kStatus_Success) {
ret = -1;
}
if (ret == 0) {
mp_int mpr, mps;
mp_init(&mpr);
mp_init(&mps);
mp_read_unsigned_bin(&mpr, r, keySz);
mp_read_unsigned_bin(&mps, s, keySz);
ret = StoreECC_DSA_Sig(out, outlen, &mpr, &mps);
mp_free(&mpr);
mp_free(&mps);
if (ret != 0) {
WOLFSSL_MSG("Issue converting to signature");
ForceZero(k, sizeof(k));
return -1;
}
}
ForceZero(k, sizeof(k));
return ret;
}
static int wc_CAAM_EccVerify_ex(mp_int* r, mp_int *s, const byte* hash,
word32 hashlen, int* res, ecc_key* key)
{
const ecc_set_type* dp;
int keySz;
word32 ecdsel = 0;
byte *alignedIn = NULL;
byte *tmpIn = NULL;
ALIGN16 byte rbuf[MAX_ECC_BYTES] = {0};
ALIGN16 byte sbuf[MAX_ECC_BYTES] = {0};
ALIGN16 byte qx[MAX_ECC_BYTES] = {0};
ALIGN16 byte qy[MAX_ECC_BYTES] = {0};
ALIGN16 byte qxy[MAX_ECC_BYTES * 2] = {0};
word32 qxLen, qyLen;
status_t status;
caam_handle_t hndl;
hndl.jobRing = kCAAM_JobRing0;
if (key->dp != NULL) {
dp = key->dp;
}
else {
dp = wc_ecc_get_curve_params(key->idx);
}
if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) {
WOLFSSL_MSG("Only support P256 and P384 verify with CAAM for now");
return CRYPTOCB_UNAVAILABLE;
}
ecdsel = GetECDSEL(dp->id);
if (ecdsel == 0) {
WOLFSSL_MSG("Curve parameters not supported");
return CRYPTOCB_UNAVAILABLE;
}
keySz = wc_ecc_size(key);
qxLen = qyLen = MAX_ECC_BYTES;
if (wc_ecc_export_public_raw(key, qx, &qxLen, qy, &qyLen) != 0) {
WOLFSSL_MSG("Issue exporting public key part");
return -1;
}
XMEMCPY(qxy, qx, qxLen);
XMEMCPY(qxy+qxLen, qy, qyLen);
if (mp_to_unsigned_bin_len(r, rbuf, keySz) != MP_OKAY) {
return MP_TO_E;
}
if (mp_to_unsigned_bin_len(s, sbuf, keySz) != MP_OKAY) {
return MP_TO_E;
}
if ((wc_ptr_t)hash % CAAM_BUFFER_ALIGN) {
tmpIn = (byte*)XMALLOC(hashlen + CAAM_BUFFER_ALIGN, NULL,
DYNAMIC_TYPE_TMP_BUFFER);
alignedIn = tmpIn + (CAAM_BUFFER_ALIGN -
((wc_ptr_t)tmpIn % CAAM_BUFFER_ALIGN));
XMEMCPY(alignedIn, hash, hashlen);
}
else {
alignedIn = (byte*)hash;
}
status = CAAM_ECC_Verify(CAAM, &hndl, qxy, qxLen+qyLen, rbuf,
keySz, sbuf, keySz, alignedIn, hashlen, ecdsel);
XFREE(tmpIn, NULL, DYNAMIC_TYPE_TMP_BUFFER);
*res = 0;
if (status == kStatus_Success) {
*res = 1;
}
return MP_OKAY;
}
int wc_CAAM_EccVerify(const byte* sig, word32 siglen, const byte* hash,
word32 hashlen, int* res, ecc_key* key, int devId)
{
int ret;
mp_int r, s;
ret = DecodeECC_DSA_Sig(sig, siglen, &r, &s);
if (ret == 0) {
ret = wc_CAAM_EccVerify_ex(&r, &s, hash, hashlen, res, key);
mp_free(&r);
mp_free(&s);
}
(void)devId;
return ret;
}
int wc_CAAM_Ecdh(ecc_key* private_key, ecc_key* public_key, byte* out,
word32* outlen, int devId)
{
const ecc_set_type* dp;
int keySz;
word32 ecdsel = 0;
int enc;
status_t status;
ALIGN16 byte k[MAX_ECC_BYTES + WC_CAAM_MAC_SZ] = {0};
ALIGN16 byte qx[MAX_ECC_BYTES] = {0};
ALIGN16 byte qy[MAX_ECC_BYTES] = {0};
ALIGN16 byte qxy[MAX_ECC_BYTES * 2] = {0};
word32 qxSz, qySz;
caam_handle_t hndl;
hndl.jobRing = kCAAM_JobRing0;
if (private_key->dp != NULL) {
dp = private_key->dp;
}
else {
dp = wc_ecc_get_curve_params(private_key->idx);
}
if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) {
return CRYPTOCB_UNAVAILABLE;
}
ecdsel = GetECDSEL(dp->id);
if (ecdsel == 0) {
WOLFSSL_MSG("Unsupported curve parameters");
return CRYPTOCB_UNAVAILABLE;
}
keySz = wc_ecc_size(private_key);
if (*outlen < (word32)keySz) {
WOLFSSL_MSG("out buffer is to small");
return BUFFER_E;
}
qxSz = qySz = MAX_ECC_BYTES;
if (wc_ecc_export_public_raw(public_key, qx, &qxSz, qy, &qySz) != 0) {
WOLFSSL_MSG("Issue exporting public key part");
return -1;
}
XMEMCPY(qxy, qx, qxSz);
XMEMCPY(qxy+qxSz, qy, qySz);
if (keySz > MAX_ECC_BYTES) {
return BUFFER_E;
}
enc = 0;
if (private_key->blackKey == CAAM_BLACK_KEY_ECB) {
enc = CAAM_PKHA_ENC_PRI_AESECB;
}
if (private_key->blackKey == CAAM_BLACK_KEY_CCM) {
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(private_key), k,
keySz + WC_CAAM_MAC_SZ) != MP_OKAY) {
ForceZero(k, sizeof(k));
return MP_TO_E;
}
}
else {
if (mp_to_unsigned_bin_len(wc_ecc_key_get_priv(private_key), k, keySz)
!= MP_OKAY) {
ForceZero(k, sizeof(k));
return MP_TO_E;
}
}
if (*outlen < (word32)keySz) {
ForceZero(k, sizeof(k));
return -1;
}
status = CAAM_ECC_ECDH(CAAM, &hndl, k, keySz, qxy, keySz*2, out, keySz,
ecdsel, enc);
ForceZero(k, sizeof(k));
if (status == kStatus_Success) {
*outlen = keySz;
return MP_OKAY;
}
else {
return -1;
}
}
#ifdef WOLFSSL_KEY_GEN
int wc_CAAM_MakeEccKey(WC_RNG* rng, int keySize, ecc_key* key, int curveId,
int devId)
{
int ret = 0;
ALIGN16 byte xy[MAX_ECC_BYTES * 2];
ALIGN16 byte k[MAX_ECC_BYTES];
word32 kSz = MAX_ECC_BYTES;
word32 xySz = MAX_ECC_BYTES * 2;
word32 ecdsel;
word32 enc;
status_t status;
caam_handle_t hndl;
XMEMSET(xy, 0, MAX_ECC_BYTES * 2);
XMEMSET(k, 0, MAX_ECC_BYTES);
hndl.jobRing = kCAAM_JobRing0;
key->type = ECC_PRIVATEKEY;
if (keySize == 32 && curveId == ECC_CURVE_DEF) curveId = ECC_SECP256R1;
if (keySize == 48 && curveId == ECC_CURVE_DEF) curveId = ECC_SECP384R1;
if (curveId != ECC_SECP256R1 && curveId != ECC_SECP384R1) {
return CRYPTOCB_UNAVAILABLE;
}
ecdsel = GetECDSEL(curveId);
if (ecdsel == 0) {
WOLFSSL_MSG("unknown key type or size");
return CRYPTOCB_UNAVAILABLE;
}
switch (key->blackKey) {
case CAAM_BLACK_KEY_ECB:
enc = CAAM_PKHA_ENC_PRI_AESECB;
break;
case 0:
#ifdef WOLFSSL_CAAM_NO_BLACK_KEY
enc = 0;
#else
key->blackKey = CAAM_BLACK_KEY_ECB;
enc = CAAM_PKHA_ENC_PRI_AESECB;
#endif
break;
default:
WOLFSSL_MSG("unknown/unsupported key type");
ForceZero(k, sizeof(k));
return BAD_FUNC_ARG;
}
status = CAAM_ECC_Keygen(CAAM, &hndl, k, &kSz, xy, &xySz, ecdsel,
enc);
if (status != kStatus_Success) {
ret = -1;
}
if (ret == 0 &&
wc_ecc_import_unsigned(key, xy, xy + keySize, k, curveId) != 0) {
WOLFSSL_MSG("issue importing key");
ret = -1;
}
ForceZero(k, sizeof(k));
return ret;
}
#endif
#endif
int SynchronousSendRequest(int type, unsigned int args[4], CAAM_BUFFER *buf,
int sz)
{
int ret = 0;
caam_handle_t hndl;
hndl.jobRing = kCAAM_JobRing0;
switch (type) {
case CAAM_ENTROPY:
if (CAAM_RNG_GetRandomData(CAAM, &hndl, kCAAM_RngStateHandle0,
(uint8_t *)buf[0].TheAddress, buf[0].Length,
kCAAM_RngDataAny, NULL) != kStatus_Success) {
ret = WC_HW_E;
}
break;
#ifndef NO_AES_CBC
case CAAM_AESCBC:
ret = DoAesCBC(args, buf, sz);
break;
#endif
#ifdef WOLFSSL_AES_COUNTER
case CAAM_AESCTR:
ret = DoAesCTR(args, buf, sz);
break;
#endif
#ifdef CAAM_BLOB_EXPANSION
case CAAM_BLOB_ENCAP:
if (CAAM_Blob(CAAM, &hndl, (byte*)buf[1].TheAddress,
buf[1].Length, (byte*)buf[2].TheAddress,
buf[2].Length, (byte*)buf[0].TheAddress,
buf[0].Length, CAAM_ENCAP_BLOB,
(args[0] == 0)? CAAM_RED_BLOB : CAAM_BLACK_BLOB)
!= kStatus_Success) {
ret = WC_HW_E;
}
break;
case CAAM_BLOB_DECAP:
if (CAAM_Blob(CAAM, &hndl, (byte*)buf[1].TheAddress, buf[1].Length,
(byte*)buf[2].TheAddress, buf[2].Length,
(byte*)buf[0].TheAddress, buf[0].Length,
CAAM_DECAP_BLOB,
(args[0] == 0)? CAAM_RED_BLOB : CAAM_BLACK_BLOB)
!= kStatus_Success) {
ret = WC_HW_E;
}
break;
#endif
default:
WOLFSSL_MSG("Unknown/unsupported type. Returning unavailable");
return CRYPTOCB_UNAVAILABLE;
}
if (ret != 0) {
return -1;
}
return Success;
}
#endif