/* wolfcaam_fsl_nxp.c * * Copyright (C) 2006-2026 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 3 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 */ #ifdef HAVE_CONFIG_H #include #endif #include #if defined(WOLFSSL_IMXRT1170_CAAM) #include #include #include #ifndef WOLFSSL_HAVE_ECC_KEY_GET_PRIV /* FIPS build has replaced ecc.h. */ #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) /* Setup for if memory is cached */ 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 /* If not cached */ 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; /* Initialize CAAM resources. * return 0 on success */ int wc_CAAMInitInterface() { CAAM_Type *base = CAAM; caam_config_t caamConfig; if (wc_InitMutex(&caamMutex) != 0) { WOLFSSL_MSG("Could not init mutex"); return -1; } /* Get default configuration. */ CAAM_GetDefaultConfig(&caamConfig); /* set the job rings */ caamConfig.jobRingInterface[0] = &jr0; caamConfig.jobRingInterface[1] = &jr1; caamConfig.jobRingInterface[2] = &jr2; caamConfig.jobRingInterface[3] = &jr3; /* Init CAAM driver, including CAAM's internal RNG */ if (CAAM_Init(base, &caamConfig) != kStatus_Success) { return -1; } return 0; } /* free up CAAM resources */ 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) /* convert the wolfCrypt hash type to NXP enum */ 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; } } /* Common init code for hash algorithms. * returns 0 on success */ int wc_CAAM_HashInit(caam_handle_t* hndl, caam_hash_ctx_t* ctx, int type) { if (hndl == NULL || ctx == NULL) { return BAD_FUNC_ARG; } /* only using job ring0 for now */ hndl->jobRing = kCAAM_JobRing0; if (CAAM_HASH_Init(CAAM, hndl, ctx, WC2NXP(type), NULL, 0u) != kStatus_Success) { return WC_HW_E; } return 0; } /* All hashing algorithms have common code except the 'type' to perform. * This helper function implements the common code. * returns 0 on success */ 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) { /* input not aligned */ 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) { /* input not aligned */ 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) /* SHA returns 0 on success */ 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 /* SHA224 returns 0 on success */ 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) /* SHA256 returns 0 on success */ 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 /* SHA384 returns 0 on success */ 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 /* SHA512 returns 0 on success */ 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 /* AES-CBC returns 0 on success */ static int DoAesCBC(unsigned int args[4], CAAM_BUFFER *buf, int sz) { status_t status; caam_handle_t hndl; /* @TODO running on alternate job rings - performance enhancement */ 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); /* store updated CBC state */ 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); /* store updated CBC state */ 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 /* AES-CTR returns 0 on success */ 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) { /* input not aligned */ 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) { /* output not aligned */ 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; } /* @TODO running on alternate job rings - performance enhancement */ 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 /* helper function get the ECDSEL value, this is a value that signals the * hardware to use preloaded curve parameters */ 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; } /* ECC sign operation on hardware, can handle black keys * returns 0 on success */ 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; /* input needs to be aligned */ 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; /* @TODO running on alternate job rings - performance enhancement */ 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; } /* check for known predetermined parameters */ ecdsel = GetECDSEL(dp->id); if (ecdsel == 0) { WOLFSSL_MSG("Unsupported curve type"); return BAD_FUNC_ARG; } keySz = kSz = wc_ecc_size(key); /* private key */ if (key->blackKey == CAAM_BLACK_KEY_SM) { ret = -1; /* only handling black keys not SM (secure memory) ones */ } 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) { /* input not aligned */ 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; } /* convert signature from raw bytes to signature format */ 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; } /* helper function to handle r/s with verify * returns 0 on success */ 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; /* input needs to be aligned */ 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; /* @TODO running on alternate job rings - performance enhancement */ hndl.jobRing = kCAAM_JobRing0; if (key->dp != NULL) { dp = key->dp; } else { dp = wc_ecc_get_curve_params(key->idx); } /* right now only support P256/P384 @TODO */ if (dp->id != ECC_SECP256R1 && dp->id != ECC_SECP384R1) { WOLFSSL_MSG("Only support P256 and P384 verify with CAAM for now"); return CRYPTOCB_UNAVAILABLE; } /* check for known predetermined parameters */ ecdsel = GetECDSEL(dp->id); if (ecdsel == 0) { WOLFSSL_MSG("Curve parameters not supported"); return CRYPTOCB_UNAVAILABLE; } /* Wx,y public key */ 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) { /* input not aligned */ 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; } /* ECC verify operation using hardware * returns 0 on success, and sets "res" with verify result (1 for verify ok) */ 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; } /* ECDH operation using hardware, can handle black keys * returns 0 on success */ 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; /* ecc parameters in hardware */ 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; /* @TODO running on alternate job rings - performance enhancement */ 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; } /* check for known predetermined parameters */ ecdsel = GetECDSEL(dp->id); if (ecdsel == 0) { /* predefined value not known, loading all parameters */ 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; } /* public key */ 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); /* private key */ 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 /* creates a [ private black key ] [ x , y ] * returns 0 on success */ 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); /* @TODO running on alternate job rings - performance enhancement */ hndl.jobRing = kCAAM_JobRing0; key->type = ECC_PRIVATEKEY; /* if set to default curve then assume SECP256R1 */ 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) { /* currently only implemented P256/P384 support */ 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 /* WOLFSSL_KEY_GEN */ #endif /* HAVE_ECC */ /* Do a synchronous operations and block till done * returns 0 on success */ 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 /* WOLFSSL_IMXRT1170_CAAM */