#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#ifdef NO_INLINE
#include <wolfssl/wolfcrypt/misc.h>
#else
#define WOLFSSL_MISC_INCLUDED
#include <wolfcrypt/src/misc.c>
#endif
#if defined(WOLFSSL_PSOC6_CRYPTO)
#include <stdint.h>
#include <string.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
#include <wolfssl/wolfcrypt/logging.h>
#include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
#include <wolfssl/wolfcrypt/random.h>
#include "cy_crypto_core_hw_v2.h"
#include "cy_crypto_core_mem.h"
#ifdef HAVE_ECC
#include <wolfssl/wolfcrypt/ecc.h>
#endif
#ifndef NO_AES
#include <wolfssl/wolfcrypt/aes.h>
#include "cy_crypto_common.h"
#include "cy_crypto_core_aes.h"
#include "cy_crypto_core_aes_v2.h"
#endif
#ifndef NO_SHA256
#include "wolfssl/wolfcrypt/sha256.h"
#endif
#ifdef WOLFSSL_SHA3
#include "wolfssl/wolfcrypt/sha3.h"
#endif
#if defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)
#include "wolfssl/wolfcrypt/sha512.h"
#endif
#if defined(PSOC6_HASH_SHA3)
#define BITS_IN_BYTE 8U
#define PSOC6_CRYPTO_SHA3_RB_LOWER 128U
#define PSOC6_CRYPTO_SHA3_RB_UPPER 72U
#endif
static CRYPTO_Type* crypto_base = PSOC6_CRYPTO_BASE;
int psoc6_crypto_port_init(void)
{
Cy_Crypto_Core_Enable(crypto_base);
return 0;
}
int wc_Psoc6_Sha1_Sha2_Init(void* sha, wc_psoc6_hash_sha1_sha2_t hash_mode,
int init_hash)
{
cy_en_crypto_status_t res;
if (sha == NULL) {
return BAD_FUNC_ARG;
}
if (!Cy_Crypto_Core_IsEnabled(crypto_base)) {
Cy_Crypto_Core_Enable(crypto_base);
}
switch (hash_mode) {
#if !defined(NO_SHA) && defined(PSOC6_HASH_SHA1)
case WC_PSOC6_SHA1:
res = Cy_Crypto_Core_Sha_Init(
crypto_base, &((wc_Sha*)sha)->hash_state, CY_CRYPTO_MODE_SHA1,
&((wc_Sha*)sha)->sha_buffers);
if ((res == CY_CRYPTO_SUCCESS) && (init_hash == 1))
res = Cy_Crypto_Core_Sha_Start(crypto_base,
&((wc_Sha*)sha)->hash_state);
break;
#endif
#if defined(PSOC6_HASH_SHA2)
#if !defined(NO_SHA256)
#if defined(WOLFSSL_SHA224)
case WC_PSOC6_SHA224:
res = Cy_Crypto_Core_Sha_Init(
crypto_base, &((wc_Sha224*)sha)->hash_state,
CY_CRYPTO_MODE_SHA224, &((wc_Sha224*)sha)->sha_buffers);
if ((res == CY_CRYPTO_SUCCESS) && (init_hash == 1))
res = Cy_Crypto_Core_Sha_Start(crypto_base,
&((wc_Sha224*)sha)->hash_state);
break;
#endif
case WC_PSOC6_SHA256:
res = Cy_Crypto_Core_Sha_Init(
crypto_base, &((wc_Sha256*)sha)->hash_state,
CY_CRYPTO_MODE_SHA256, &((wc_Sha256*)sha)->sha_buffers);
if ((res == CY_CRYPTO_SUCCESS) && (init_hash == 1))
res = Cy_Crypto_Core_Sha_Start(crypto_base,
&((wc_Sha256*)sha)->hash_state);
break;
#endif
#if defined(WOLFSSL_SHA384)
case WC_PSOC6_SHA384:
res = Cy_Crypto_Core_Sha_Init(
crypto_base, &((wc_Sha384*)sha)->hash_state,
CY_CRYPTO_MODE_SHA384, &((wc_Sha384*)sha)->sha_buffers);
if ((res == CY_CRYPTO_SUCCESS) && (init_hash == 1))
res = Cy_Crypto_Core_Sha_Start(crypto_base,
&((wc_Sha384*)sha)->hash_state);
break;
#endif
#if defined(WOLFSSL_SHA512)
case WC_PSOC6_SHA512:
res = Cy_Crypto_Core_Sha_Init(
crypto_base, &((wc_Sha512*)sha)->hash_state,
CY_CRYPTO_MODE_SHA512, &((wc_Sha512*)sha)->sha_buffers);
if ((res == CY_CRYPTO_SUCCESS) && (init_hash == 1))
res = Cy_Crypto_Core_Sha_Start(crypto_base,
&((wc_Sha512*)sha)->hash_state);
break;
#if !defined(WOLFSSL_NOSHA512_224)
case WC_PSOC6_SHA512_224:
res = Cy_Crypto_Core_Sha_Init(
crypto_base, &((wc_Sha512*)sha)->hash_state,
CY_CRYPTO_MODE_SHA512_224, &((wc_Sha512*)sha)->sha_buffers);
if ((res == CY_CRYPTO_SUCCESS) && (init_hash == 1))
res = Cy_Crypto_Core_Sha_Start(crypto_base,
&((wc_Sha512*)sha)->hash_state);
break;
#endif
#if !defined(WOLFSSL_NOSHA512_256)
case WC_PSOC6_SHA512_256:
res = Cy_Crypto_Core_Sha_Init(
crypto_base, &((wc_Sha512*)sha)->hash_state,
CY_CRYPTO_MODE_SHA512_256, &((wc_Sha512*)sha)->sha_buffers);
if ((res == CY_CRYPTO_SUCCESS) && (init_hash == 1))
res = Cy_Crypto_Core_Sha_Start(crypto_base,
&((wc_Sha512*)sha)->hash_state);
break;
#endif
#endif
#endif
default:
return BAD_FUNC_ARG;
}
return res;
}
int wc_Psoc6_Sha_Free(void)
{
int ret;
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
Cy_Crypto_Core_V2_RBClear(crypto_base);
Cy_Crypto_Core_V2_Sync(crypto_base);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
#if !defined(NO_SHA) && defined(PSOC6_HASH_SHA1)
int wc_InitSha_ex(wc_Sha* sha, void* heap, int devid)
{
int ret;
if (sha == NULL)
return BAD_FUNC_ARG;
(void)heap;
XMEMSET(sha, 0, sizeof(wc_Sha));
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA1, 1);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_ShaUpdate(wc_Sha* sha, const byte* in, word32 sz)
{
int ret;
if (sha == NULL || (in == NULL && sz > 0)) {
return BAD_FUNC_ARG;
}
if (in == NULL && sz == 0) {
return 0;
}
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_ShaFinal(wc_Sha* sha, byte* hash)
{
int ret;
if (sha == NULL || hash == NULL)
return BAD_FUNC_ARG;
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret =
(int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash);
wolfSSL_CryptHwMutexUnLock();
}
if (ret != 0)
return ret;
return wc_InitSha(sha);
}
#endif
#if defined(PSOC6_HASH_SHA2)
#if !defined(NO_SHA256)
int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devid)
{
int ret;
if (sha == NULL)
return BAD_FUNC_ARG;
(void)heap;
(void)devid;
XMEMSET(sha, 0, sizeof(wc_Sha256));
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA256, 1);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz)
{
int ret;
if (sha == NULL || (in == NULL && sz > 0)) {
return BAD_FUNC_ARG;
}
if (in == NULL && sz == 0) {
return 0;
}
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_Sha256Final(wc_Sha256* sha, byte* hash)
{
int ret;
if (sha == NULL || hash == NULL)
return BAD_FUNC_ARG;
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret =
(int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash);
wolfSSL_CryptHwMutexUnLock();
}
if (ret != 0)
return ret;
return wc_InitSha256(sha);
}
#if defined(WOLFSSL_SHA224)
int wc_InitSha224_ex(wc_Sha224* sha, void* heap, int devid)
{
int ret;
if (sha == NULL)
return BAD_FUNC_ARG;
(void)heap;
(void)devid;
XMEMSET(sha, 0, sizeof(wc_Sha224));
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA224, 1);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_Sha224Update(wc_Sha224* sha, const byte* in, word32 sz)
{
int ret;
if (sha == NULL || (in == NULL && sz > 0)) {
return BAD_FUNC_ARG;
}
if (in == NULL && sz == 0) {
return 0;
}
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_Sha224Final(wc_Sha224* sha, byte* hash)
{
int ret;
if (sha == NULL || hash == NULL)
return BAD_FUNC_ARG;
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret =
(int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash);
wolfSSL_CryptHwMutexUnLock();
}
if (ret != 0)
return ret;
return wc_InitSha224(sha);
}
#endif
#endif
#if defined(WOLFSSL_SHA384)
int wc_InitSha384_ex(wc_Sha384* sha, void* heap, int devid)
{
int ret;
if (sha == NULL)
return BAD_FUNC_ARG;
(void)heap;
(void)devid;
XMEMSET(sha, 0, sizeof(wc_Sha384));
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA384, 1);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_Sha384Update(wc_Sha384* sha, const byte* in, word32 sz)
{
int ret;
if (sha == NULL || (in == NULL && sz > 0)) {
return BAD_FUNC_ARG;
}
if (in == NULL && sz == 0) {
return 0;
}
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_Sha384Final(wc_Sha384* sha, byte* hash)
{
int ret;
if (sha == NULL || hash == NULL)
return BAD_FUNC_ARG;
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret =
(int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash);
wolfSSL_CryptHwMutexUnLock();
}
if (ret != 0)
return ret;
return wc_InitSha384(sha);
}
#endif
#if defined(WOLFSSL_SHA512)
int wc_InitSha512_ex(wc_Sha512* sha, void* heap, int devid)
{
int ret;
(void)heap;
(void)devid;
XMEMSET(sha, 0, sizeof(wc_Sha512));
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA512, 1);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_Sha512Update(wc_Sha512* sha, const byte* in, word32 sz)
{
int ret;
if (sha == NULL || (in == NULL && sz > 0)) {
return BAD_FUNC_ARG;
}
if (in == NULL && sz == 0) {
return 0;
}
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_Sha512Final(wc_Sha512* sha, byte* hash)
{
int ret;
if (sha == NULL || hash == NULL)
return BAD_FUNC_ARG;
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret =
(int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash);
wolfSSL_CryptHwMutexUnLock();
}
if (ret != 0)
return ret;
return wc_InitSha512(sha);
}
#ifndef WOLFSSL_NOSHA512_224
int wc_InitSha512_224_ex(wc_Sha512* sha, void* heap, int devid)
{
int ret;
if (sha == NULL)
return BAD_FUNC_ARG;
(void)heap;
(void)devid;
XMEMSET(sha, 0, sizeof(wc_Sha512));
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA512_224, 1);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_Sha512_224Update(wc_Sha512* sha, const byte* in, word32 sz)
{
return wc_Sha512Update(sha, in, sz);
}
int wc_Sha512_224Final(wc_Sha512* sha, byte* hash)
{
int ret;
if (sha == NULL || hash == NULL)
return BAD_FUNC_ARG;
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret =
(int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash);
wolfSSL_CryptHwMutexUnLock();
}
return wc_InitSha512_224(sha);
}
#endif
#ifndef WOLFSSL_NOSHA512_256
int wc_InitSha512_256_ex(wc_Sha512* sha, void* heap, int devid)
{
int ret;
if (sha == NULL)
return BAD_FUNC_ARG;
(void)heap;
(void)devid;
XMEMSET(sha, 0, sizeof(wc_Sha512));
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA512_256, 1);
wolfSSL_CryptHwMutexUnLock();
}
return ret;
}
int wc_Sha512_256Update(wc_Sha512* sha, const byte* in, word32 sz)
{
return wc_Sha512Update(sha, in, sz);
}
int wc_Sha512_256Final(wc_Sha512* sha, byte* hash)
{
int ret;
if (sha == NULL || hash == NULL)
return BAD_FUNC_ARG;
ret = wolfSSL_CryptHwMutexLock();
if (ret == 0) {
ret =
(int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash);
wolfSSL_CryptHwMutexUnLock();
}
if (ret != 0)
return ret;
return wc_InitSha512_256(sha);
}
#endif
#endif
#endif
#if defined(WOLFSSL_SHA3) && defined(PSOC6_HASH_SHA3)
int wc_Psoc6_Sha3_Init(void* sha3)
{
wc_Sha3* sha3_ctx = (wc_Sha3*)sha3;
if (!Cy_Crypto_Core_IsEnabled(crypto_base)) {
Cy_Crypto_Core_Enable(crypto_base);
}
Cy_Crypto_Core_MemSet(crypto_base, sha3, 0, sizeof(wc_Sha3));
sha3_ctx->hash_state.hash =
(uint8_t*)((cy_stc_crypto_v2_sha3_buffers_t*)&sha3_ctx->sha_buffers)
->hash;
sha3_ctx->hash_state.modeHw = (uint32_t)CY_CRYPTO_V2_SHA3_OPC;
sha3_ctx->hash_state.hashSize = 0;
sha3_ctx->init_done = false;
return 0;
}
int wc_Psoc6_Sha3_Update(void* sha3, const byte* data, word32 len, byte p)
{
wc_Sha3* sha3_ctx = (wc_Sha3*)sha3;
if (!sha3_ctx->init_done) {
switch (p) {
case WC_SHA3_128_COUNT:
sha3_ctx->hash_state.mode = CY_CRYPTO_MODE_SHA3_224;
sha3_ctx->hash_state.blockSize =
WC_SHA3_128_COUNT * BITS_IN_BYTE;
break;
case WC_SHA3_224_COUNT:
sha3_ctx->hash_state.mode = CY_CRYPTO_MODE_SHA3_224;
sha3_ctx->hash_state.blockSize = CY_CRYPTO_SHA3_224_BLOCK_SIZE;
sha3_ctx->hash_state.digestSize = CY_CRYPTO_SHA224_DIGEST_SIZE;
break;
case WC_SHA3_256_COUNT:
sha3_ctx->hash_state.mode = CY_CRYPTO_MODE_SHA3_256;
sha3_ctx->hash_state.blockSize = CY_CRYPTO_SHA3_256_BLOCK_SIZE;
sha3_ctx->hash_state.digestSize = CY_CRYPTO_SHA256_DIGEST_SIZE;
break;
case WC_SHA3_384_COUNT:
sha3_ctx->hash_state.mode = CY_CRYPTO_MODE_SHA3_384;
sha3_ctx->hash_state.blockSize = CY_CRYPTO_SHA3_384_BLOCK_SIZE;
sha3_ctx->hash_state.digestSize = CY_CRYPTO_SHA384_DIGEST_SIZE;
break;
case WC_SHA3_512_COUNT:
sha3_ctx->hash_state.mode = CY_CRYPTO_MODE_SHA3_512;
sha3_ctx->hash_state.blockSize = CY_CRYPTO_SHA3_512_BLOCK_SIZE;
sha3_ctx->hash_state.digestSize = CY_CRYPTO_SHA512_DIGEST_SIZE;
break;
default:
return BAD_FUNC_ARG;
}
sha3_ctx->init_done = true;
}
return Cy_Crypto_Core_Sha_Update(crypto_base, &sha3_ctx->hash_state, data,
len);
}
int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l)
{
word32 rate = p * BITS_IN_BYTE;
word32 offset;
wc_Sha3* sha3_ctx = (wc_Sha3*)sha3;
#ifdef WOLFSSL_HASH_FLAGS
if ((p == WC_SHA3_256_COUNT) && (sha3_ctx->flags & WC_HASH_SHA3_KECCAK256))
padChar = 0x01;
#endif
sha3_ctx->hash_state.hash[sha3_ctx->hash_state.blockIdx] ^= padChar;
sha3_ctx->hash_state.hash[rate - 1] ^= 0x80;
Cy_Crypto_Core_V2_RBClear(crypto_base);
Cy_Crypto_Core_V2_Sync(crypto_base);
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_LOAD0,
sha3_ctx->sha_buffers.hash,
CY_CRYPTO_SHA3_STATE_SIZE);
Cy_Crypto_Core_V2_RBXor(crypto_base, 0U, PSOC6_CRYPTO_SHA3_RB_LOWER);
Cy_Crypto_Core_V2_RBSwap(crypto_base);
Cy_Crypto_Core_V2_RBXor(crypto_base, 0U, PSOC6_CRYPTO_SHA3_RB_UPPER);
Cy_Crypto_Core_V2_RBSwap(crypto_base);
Cy_Crypto_Core_V2_Sync(crypto_base);
for (offset = 0; l - offset >= rate; offset += rate) {
Cy_Crypto_Core_V2_Run(crypto_base, sha3_ctx->hash_state.modeHw);
Cy_Crypto_Core_V2_Sync(crypto_base);
if (rate > PSOC6_CRYPTO_SHA3_RB_LOWER) {
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
hash + offset,
PSOC6_CRYPTO_SHA3_RB_LOWER);
Cy_Crypto_Core_V2_RBStore(crypto_base, 0U,
PSOC6_CRYPTO_SHA3_RB_LOWER);
Cy_Crypto_Core_V2_FFStoreSync(crypto_base);
Cy_Crypto_Core_V2_RBSwap(crypto_base);
Cy_Crypto_Core_V2_Sync(crypto_base);
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
hash + offset +
PSOC6_CRYPTO_SHA3_RB_LOWER,
(rate - PSOC6_CRYPTO_SHA3_RB_LOWER));
Cy_Crypto_Core_V2_RBStore(crypto_base, 0U,
(rate - PSOC6_CRYPTO_SHA3_RB_LOWER));
Cy_Crypto_Core_V2_FFStoreSync(crypto_base);
Cy_Crypto_Core_V2_RBSwap(crypto_base);
}
else {
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
hash + offset, rate);
Cy_Crypto_Core_V2_RBStore(crypto_base, 0U, rate);
Cy_Crypto_Core_V2_FFStoreSync(crypto_base);
}
}
if (offset != l) {
Cy_Crypto_Core_V2_Run(crypto_base, sha3_ctx->hash_state.modeHw);
Cy_Crypto_Core_V2_Sync(crypto_base);
if ((l - offset) > PSOC6_CRYPTO_SHA3_RB_LOWER) {
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
hash + offset,
PSOC6_CRYPTO_SHA3_RB_LOWER);
Cy_Crypto_Core_V2_RBStore(crypto_base, 0U,
PSOC6_CRYPTO_SHA3_RB_LOWER);
Cy_Crypto_Core_V2_FFStoreSync(crypto_base);
Cy_Crypto_Core_V2_RBSwap(crypto_base);
Cy_Crypto_Core_V2_Sync(crypto_base);
Cy_Crypto_Core_V2_FFStart(
crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
hash + offset + PSOC6_CRYPTO_SHA3_RB_LOWER,
((l - offset) - PSOC6_CRYPTO_SHA3_RB_LOWER));
Cy_Crypto_Core_V2_RBStore(
crypto_base, 0U, ((l - offset) - PSOC6_CRYPTO_SHA3_RB_LOWER));
Cy_Crypto_Core_V2_FFStoreSync(crypto_base);
}
else {
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
hash + offset, l - offset);
Cy_Crypto_Core_V2_RBStore(crypto_base, 0U, l - offset);
Cy_Crypto_Core_V2_FFStoreSync(crypto_base);
}
}
return 0;
}
#if defined(WOLFSSL_SHAKE128) || defined(WOLFSSL_SHAKE256)
int wc_Psoc6_Shake_SqueezeBlocks(void* shake, byte* out, word32 blockCnt)
{
wc_Shake* shake_ctx = (wc_Shake*)shake;
for (; (blockCnt > 0); blockCnt--) {
Cy_Crypto_Core_V2_Run(crypto_base, shake_ctx->hash_state.modeHw);
Cy_Crypto_Core_V2_Sync(crypto_base);
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE, out,
PSOC6_CRYPTO_SHA3_RB_LOWER);
Cy_Crypto_Core_V2_RBStore(crypto_base, 0U, PSOC6_CRYPTO_SHA3_RB_LOWER);
Cy_Crypto_Core_V2_FFStoreSync(crypto_base);
Cy_Crypto_Core_V2_RBSwap(crypto_base);
Cy_Crypto_Core_V2_Sync(crypto_base);
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
out + PSOC6_CRYPTO_SHA3_RB_LOWER,
shake_ctx->hash_state.blockSize -
PSOC6_CRYPTO_SHA3_RB_LOWER);
Cy_Crypto_Core_V2_RBStore(crypto_base, 0U,
shake_ctx->hash_state.blockSize -
PSOC6_CRYPTO_SHA3_RB_LOWER);
Cy_Crypto_Core_V2_FFStoreSync(crypto_base);
Cy_Crypto_Core_V2_RBSwap(crypto_base);
out += shake_ctx->hash_state.blockSize;
}
return 0;
}
#endif
#endif
#if defined(PSOC6_CRYPTO_AES)
static cy_en_crypto_aes_key_length_t psoc6_get_aes_key_length(word32 keyLen)
{
switch (keyLen) {
case 16:
return CY_CRYPTO_KEY_AES_128;
case 24:
return CY_CRYPTO_KEY_AES_192;
case 32:
return CY_CRYPTO_KEY_AES_256;
default:
return CY_CRYPTO_KEY_AES_128;
}
}
int wc_Psoc6_Aes_SetKey(Aes* aes, const byte* userKey, word32 len,
const byte* iv, int dir)
{
int ret = 0;
if (aes == NULL || userKey == NULL) {
return BAD_FUNC_ARG;
}
if (len != 16 && len != 24 && len != 32) {
return BAD_FUNC_ARG;
}
aes->keylen = len;
aes->rounds = len / 4 + 6;
#if defined(WOLFSSL_AES_CFB)
aes->left = 0;
#endif
XMEMCPY(aes->key, userKey, len);
if (iv != NULL) {
XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE);
}
(void)dir;
return ret;
}
void wc_Psoc6_Aes_Free(Aes* aes)
{
if (aes->aes_state.buffers != NULL) {
Cy_Crypto_Core_V2_MemSet(
crypto_base, (void*)aes->aes_state.buffers, 0u,
((uint16_t)sizeof(cy_stc_crypto_aes_buffers_t)));
}
#ifdef HAVE_AESGCM
if (aes->aes_gcm_state.aes_buffer != NULL) {
Cy_Crypto_Core_Aes_GCM_Free(crypto_base, &aes->aes_gcm_state);
}
#endif
}
int wc_Psoc6_Aes_Encrypt(Aes* aes, const byte* in, byte* out)
{
int ret = 0;
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
if (aes == NULL || in == NULL || out == NULL) {
return BAD_FUNC_ARG;
}
keyLength = psoc6_get_aes_key_length(aes->keylen);
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
status = Cy_Crypto_Core_Aes_Init(crypto_base, (const uint8_t*)aes->key,
keyLength, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aesInited = 1;
status = Cy_Crypto_Core_Aes_Ecb(crypto_base, CY_CRYPTO_ENCRYPT, out, in,
&aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
cleanup:
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#ifdef WOLFSSL_AES_DIRECT
int wc_Psoc6_Aes_EncryptDirect(Aes* aes, byte* out, const byte* in)
{
return wc_Psoc6_Aes_Encrypt(aes, in, out);
}
#endif
#ifdef HAVE_AES_DECRYPT
int wc_Psoc6_Aes_Decrypt(Aes* aes, const byte* in, byte* out)
{
int ret = 0;
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
if (aes == NULL || in == NULL || out == NULL) {
return BAD_FUNC_ARG;
}
keyLength = psoc6_get_aes_key_length(aes->keylen);
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
status = Cy_Crypto_Core_Aes_Init(crypto_base, (const uint8_t*)aes->key,
keyLength, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aesInited = 1;
status = Cy_Crypto_Core_Aes_Ecb(crypto_base, CY_CRYPTO_DECRYPT, out, in,
&aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
cleanup:
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#ifdef WOLFSSL_AES_DIRECT
int wc_Psoc6_Aes_DecryptDirect(Aes* aes, byte* out, const byte* in)
{
return wc_Psoc6_Aes_Decrypt(aes, in, out);
}
#endif
#endif
#if defined(HAVE_AES_ECB)
int wc_Psoc6_Aes_EcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
int ret = 0;
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
if (aes == NULL || in == NULL || out == NULL) {
return BAD_FUNC_ARG;
}
if (sz % AES_BLOCK_SIZE != 0) {
return BAD_FUNC_ARG;
}
keyLength = psoc6_get_aes_key_length(aes->keylen);
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
status = Cy_Crypto_Core_Aes_Init(crypto_base, (const uint8_t*)aes->key,
keyLength, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aesInited = 1;
Cy_Crypto_Core_V2_Aes_LoadEncKey(crypto_base, &aes->aes_state);
Cy_Crypto_Core_V2_FFContinue(crypto_base, CY_CRYPTO_V2_RB_FF_LOAD0, in, sz);
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE, out, sz);
for (; sz > 0; sz -= CY_CRYPTO_AES_BLOCK_SIZE) {
Cy_Crypto_Core_V2_BlockMov(crypto_base, CY_CRYPTO_V2_RB_BLOCK0,
CY_CRYPTO_V2_RB_FF_LOAD0,
CY_CRYPTO_AES_BLOCK_SIZE);
Cy_Crypto_Core_V2_RunAes(crypto_base);
Cy_Crypto_Core_V2_BlockMov(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
CY_CRYPTO_V2_RB_BLOCK1,
CY_CRYPTO_AES_BLOCK_SIZE);
}
Cy_Crypto_Core_WaitForReady(crypto_base);
cleanup:
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#ifdef HAVE_AES_DECRYPT
int wc_Psoc6_Aes_EcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
int ret = 0;
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
if (aes == NULL || in == NULL || out == NULL) {
return BAD_FUNC_ARG;
}
if (sz % AES_BLOCK_SIZE != 0) {
return BAD_FUNC_ARG;
}
keyLength = psoc6_get_aes_key_length(aes->keylen);
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
status = Cy_Crypto_Core_Aes_Init(crypto_base, (const uint8_t*)aes->key,
keyLength, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aesInited = 1;
Cy_Crypto_Core_V2_Aes_LoadDecKey(crypto_base, &aes->aes_state);
Cy_Crypto_Core_V2_FFContinue(crypto_base, CY_CRYPTO_V2_RB_FF_LOAD0, in, sz);
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE, out, sz);
for (; sz > 0; sz -= CY_CRYPTO_AES_BLOCK_SIZE) {
Cy_Crypto_Core_V2_BlockMov(crypto_base, CY_CRYPTO_V2_RB_BLOCK0,
CY_CRYPTO_V2_RB_FF_LOAD0,
CY_CRYPTO_AES_BLOCK_SIZE);
Cy_Crypto_Core_V2_RunAesInv(crypto_base);
Cy_Crypto_Core_V2_BlockMov(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
CY_CRYPTO_V2_RB_BLOCK1,
CY_CRYPTO_AES_BLOCK_SIZE);
}
Cy_Crypto_Core_WaitForReady(crypto_base);
cleanup:
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#endif
#endif
#ifdef HAVE_AES_CBC
int wc_Psoc6_Aes_CbcEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
int ret = 0;
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
if (aes == NULL || in == NULL || out == NULL) {
return BAD_FUNC_ARG;
}
if (sz % AES_BLOCK_SIZE != 0) {
return BAD_FUNC_ARG;
}
keyLength = psoc6_get_aes_key_length(aes->keylen);
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
status = Cy_Crypto_Core_Aes_Init(crypto_base, (const uint8_t*)aes->key,
keyLength, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aesInited = 1;
status =
Cy_Crypto_Core_Aes_Cbc(crypto_base, CY_CRYPTO_ENCRYPT, sz,
(uint8_t*)aes->reg, out, in, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
cleanup:
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#ifdef HAVE_AES_DECRYPT
int wc_Psoc6_Aes_CbcDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
int ret = 0;
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
if (aes == NULL || in == NULL || out == NULL) {
return BAD_FUNC_ARG;
}
if (sz % AES_BLOCK_SIZE != 0) {
return BAD_FUNC_ARG;
}
keyLength = psoc6_get_aes_key_length(aes->keylen);
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
status = Cy_Crypto_Core_Aes_Init(crypto_base, (const uint8_t*)aes->key,
keyLength, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aesInited = 1;
status =
Cy_Crypto_Core_Aes_Cbc(crypto_base, CY_CRYPTO_DECRYPT, sz,
(uint8_t*)aes->reg, out, in, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
cleanup:
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#endif
#endif
#ifdef WOLFSSL_AES_CFB
int wc_Psoc6_Aes_CfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
int ret = 0;
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
if (aes == NULL || in == NULL || out == NULL) {
return BAD_FUNC_ARG;
}
keyLength = psoc6_get_aes_key_length(aes->keylen);
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
status = Cy_Crypto_Core_Aes_Init(crypto_base, (const uint8_t*)aes->key,
keyLength, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aesInited = 1;
status = Cy_Crypto_Core_Aes_Cfb_Setup(crypto_base, CY_CRYPTO_ENCRYPT,
&aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
status = Cy_Crypto_Core_Aes_Cfb_Set_IV(crypto_base, (uint8_t*)aes->reg,
&aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aes->aes_state.unProcessedBytes = aes->left;
XMEMCPY(aes->aes_state.buffers->unProcessedData, aes->tmp, AES_BLOCK_SIZE);
status = Cy_Crypto_Core_Aes_Cfb_Update(crypto_base, sz, out, in,
&aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
status = Cy_Crypto_Core_Aes_Cfb_Finish(crypto_base, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
XMEMCPY(aes->reg, aes->aes_state.buffers->iv, AES_BLOCK_SIZE);
aes->left = aes->aes_state.unProcessedBytes;
XMEMCPY(aes->tmp, aes->aes_state.buffers->unProcessedData, AES_BLOCK_SIZE);
cleanup:
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#ifdef HAVE_AES_DECRYPT
int wc_Psoc6_Aes_CfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
{
int ret = 0;
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
if (aes == NULL || in == NULL || out == NULL) {
return BAD_FUNC_ARG;
}
keyLength = psoc6_get_aes_key_length(aes->keylen);
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
status = Cy_Crypto_Core_Aes_Init(crypto_base, (const uint8_t*)aes->key,
keyLength, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aesInited = 1;
status = Cy_Crypto_Core_Aes_Cfb_Setup(crypto_base, CY_CRYPTO_DECRYPT,
&aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
status = Cy_Crypto_Core_Aes_Cfb_Set_IV(crypto_base, (uint8_t*)aes->reg,
&aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aes->aes_state.unProcessedBytes = aes->left;
XMEMCPY(aes->aes_state.buffers->unProcessedData, aes->tmp, AES_BLOCK_SIZE);
status = Cy_Crypto_Core_Aes_Cfb_Update(crypto_base, sz, out, in,
&aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
status = Cy_Crypto_Core_Aes_Cfb_Finish(crypto_base, &aes->aes_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
XMEMCPY(aes->reg, aes->aes_state.buffers->iv, AES_BLOCK_SIZE);
aes->left = aes->aes_state.unProcessedBytes;
XMEMCPY(aes->tmp, aes->aes_state.buffers->unProcessedData, AES_BLOCK_SIZE);
cleanup:
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#endif
#endif
#ifdef HAVE_AESGCM
int wc_Psoc6_Aes_GcmEncrypt(Aes* aes, byte* out, const byte* in, word32 sz,
const byte* iv, word32 ivSz, byte* authTag,
word32 authTagSz, const byte* authIn,
word32 authInSz)
{
int ret = 0;
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
keyLength = psoc6_get_aes_key_length(aes->keylen);
cy_stc_crypto_aes_gcm_buffers_t* aesBuffers =
(cy_stc_crypto_aes_gcm_buffers_t*)((
void*)Cy_Crypto_Core_GetVuMemoryAddress(crypto_base));
status = Cy_Crypto_Core_Aes_GCM_Init(crypto_base, aesBuffers,
&aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aesInited = 1;
status = Cy_Crypto_Core_Aes_GCM_SetKey(crypto_base, (uint8_t*)aes->key,
keyLength, &aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
status = Cy_Crypto_Core_Aes_GCM_Start(crypto_base, CY_CRYPTO_ENCRYPT, iv,
ivSz, &aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
if (authIn != NULL && authInSz > 0) {
status = Cy_Crypto_Core_Aes_GCM_AAD_Update(
crypto_base, (uint8_t*)authIn, authInSz, &aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
}
if (sz > 0) {
status = Cy_Crypto_Core_Aes_GCM_Update(crypto_base, in, sz, out,
&aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
}
status = Cy_Crypto_Core_Aes_GCM_Finish(crypto_base, authTag, authTagSz,
&aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
cleanup:
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#if defined(HAVE_AES_DECRYPT) || defined(HAVE_AESGCM_DECRYPT)
int wc_Psoc6_Aes_GcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
const byte* iv, word32 ivSz, const byte* authTag,
word32 authTagSz, const byte* authIn,
word32 authInSz)
{
int ret = 0;
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
byte computedTag[AES_BLOCK_SIZE];
int aesInited = 0;
ret = wolfSSL_CryptHwMutexLock();
if (ret != 0) {
return ret;
}
keyLength = psoc6_get_aes_key_length(aes->keylen);
cy_stc_crypto_aes_gcm_buffers_t* aesBuffers =
(cy_stc_crypto_aes_gcm_buffers_t*)((
void*)Cy_Crypto_Core_GetVuMemoryAddress(crypto_base));
status = Cy_Crypto_Core_Aes_GCM_Init(crypto_base, aesBuffers,
&aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
aesInited = 1;
status = Cy_Crypto_Core_Aes_GCM_SetKey(crypto_base, (uint8_t*)aes->key,
keyLength, &aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
status = Cy_Crypto_Core_Aes_GCM_Start(crypto_base, CY_CRYPTO_DECRYPT, iv,
ivSz, &aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
if (authIn != NULL && authInSz > 0) {
status = Cy_Crypto_Core_Aes_GCM_AAD_Update(
crypto_base, (uint8_t*)authIn, authInSz, &aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
}
if (sz > 0) {
status = Cy_Crypto_Core_Aes_GCM_Update(crypto_base, in, sz, out,
&aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
}
status = Cy_Crypto_Core_Aes_GCM_Finish(crypto_base, computedTag, authTagSz,
&aes->aes_gcm_state);
if (status != CY_CRYPTO_SUCCESS) {
ret = WC_HW_E;
goto cleanup;
}
if (ConstantCompare(computedTag, authTag, authTagSz) != 0) {
ret = AES_GCM_AUTH_E;
goto cleanup;
}
cleanup:
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
wolfSSL_CryptHwMutexUnLock();
return ret;
}
#endif
#endif
#endif
#ifdef HAVE_ECC
#define MAX_ECC_KEYSIZE 66
static cy_en_crypto_ecc_curve_id_t psoc6_get_curve_id(int size)
{
switch (size) {
case 24:
return CY_CRYPTO_ECC_ECP_SECP192R1;
case 28:
return CY_CRYPTO_ECC_ECP_SECP224R1;
case 32:
return CY_CRYPTO_ECC_ECP_SECP256R1;
case 48:
return CY_CRYPTO_ECC_ECP_SECP384R1;
case 66:
return CY_CRYPTO_ECC_ECP_SECP521R1;
default:
return CY_CRYPTO_ECC_ECP_NONE;
}
}
int psoc6_ecc_verify_hash_ex(MATH_INT_T* r, MATH_INT_T* s, const byte* hash,
word32 hashlen, int* verif_res,
struct ecc_key* key)
{
uint8_t signature_buf[MAX_ECC_KEYSIZE * 2] = { 0 };
cy_stc_crypto_ecc_key ecc_key;
bool loadPublicKey = false;
uint8_t stat = 0;
int res = -1;
int keySz;
int rSz, sSz, qxSz, qySz;
uint8_t x[MAX_ECC_KEYSIZE] = { 0 };
uint8_t y[MAX_ECC_KEYSIZE] = { 0 };
uint8_t k[MAX_ECC_KEYSIZE] = { 0 };
if (!key || !verif_res || !r || !s || !hash)
return -BAD_FUNC_ARG;
if (!Cy_Crypto_Core_IsEnabled(crypto_base)) {
Cy_Crypto_Core_Enable(crypto_base);
}
keySz = wc_ecc_size(key);
rSz = mp_unsigned_bin_size(r);
sSz = mp_unsigned_bin_size(s);
if (keySz > MAX_ECC_KEYSIZE)
return -BAD_FUNC_ARG;
ecc_key.type = PK_PUBLIC;
ecc_key.curveID = psoc6_get_curve_id(keySz);
ecc_key.k = NULL;
ecc_key.pubkey.x = x;
ecc_key.pubkey.y = y;
if (key->type == ECC_PRIVATEKEY_ONLY) {
res = mp_to_unsigned_bin(ecc_get_k(key), k);
if (res == MP_OKAY) {
Cy_Crypto_Core_InvertEndianness(k, keySz);
res = Cy_Crypto_Core_ECC_MakePublicKey(crypto_base, ecc_key.curveID,
k, &ecc_key);
if (res == CY_RSLT_SUCCESS) {
loadPublicKey = true;
}
}
if (res != CY_RSLT_SUCCESS) {
return WC_FAILURE;
}
}
else {
qxSz = mp_unsigned_bin_size(key->pubkey.x);
qySz = mp_unsigned_bin_size(key->pubkey.y);
res = mp_to_unsigned_bin(key->pubkey.x, x);
if (res == MP_OKAY) {
res = mp_to_unsigned_bin(key->pubkey.y, y);
if (res == MP_OKAY) {
Cy_Crypto_Core_InvertEndianness(x, qxSz);
Cy_Crypto_Core_InvertEndianness(y, qySz);
}
}
}
if (res == MP_OKAY) {
res = mp_to_unsigned_bin(r, signature_buf);
if (res == MP_OKAY) {
res = mp_to_unsigned_bin(s, signature_buf + keySz);
if (res == MP_OKAY) {
Cy_Crypto_Core_InvertEndianness(signature_buf, rSz);
Cy_Crypto_Core_InvertEndianness(signature_buf + keySz, sSz);
}
}
}
if (res == MP_OKAY) {
res = Cy_Crypto_Core_ECC_VerifyHash(crypto_base, signature_buf, hash,
hashlen, &stat, &ecc_key);
if (res == CY_RSLT_SUCCESS) {
*verif_res = stat;
if (loadPublicKey == true) {
Cy_Crypto_Core_InvertEndianness(ecc_key.pubkey.x, keySz);
Cy_Crypto_Core_InvertEndianness(ecc_key.pubkey.y, keySz);
res = mp_read_unsigned_bin(key->pubkey.x, ecc_key.pubkey.x,
keySz);
if (res == MP_OKAY) {
res = mp_read_unsigned_bin(key->pubkey.y, ecc_key.pubkey.y,
keySz);
}
if (res == MP_OKAY) {
key->type = ECC_PRIVATEKEY;
}
}
}
else {
res = WC_FAILURE;
}
return res;
}
return WC_FAILURE;
}
#endif
#endif