diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 04d3cea5e94..a75327a591f 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -232,7 +232,8 @@ ECC Curve Sizes: #if !defined(WOLFSSL_ATECC508A) && !defined(WOLFSSL_ATECC608A) && \ !defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ !defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_SE050) && \ - !defined(WOLFSSL_XILINX_CRYPT_VERSAL) && !defined(WOLFSSL_STM32_PKA) + !defined(WOLFSSL_XILINX_CRYPT_VERSAL) && !defined(WOLFSSL_STM32_PKA) && \ + !defined(WOLFSSL_PSOC6_CRYPTO) #undef HAVE_ECC_VERIFY_HELPER #define HAVE_ECC_VERIFY_HELPER #endif diff --git a/wolfcrypt/src/include.am b/wolfcrypt/src/include.am index 7d44a36634d..0441153a97f 100644 --- a/wolfcrypt/src/include.am +++ b/wolfcrypt/src/include.am @@ -149,6 +149,7 @@ EXTRA_DIST += wolfcrypt/src/port/ti/ti-aes.c \ wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c \ wolfcrypt/src/port/Renesas/renesas_rx64_hw_util.c \ wolfcrypt/src/port/Renesas/README.md \ + wolfcrypt/src/port/cypress/README.md \ wolfcrypt/src/port/cypress/psoc6_crypto.c \ wolfcrypt/src/port/liboqs/liboqs.c \ wolfcrypt/src/port/maxim/max3266x.c \ diff --git a/wolfcrypt/src/port/cypress/README.md b/wolfcrypt/src/port/cypress/README.md new file mode 100644 index 00000000000..66f8ac42cab --- /dev/null +++ b/wolfcrypt/src/port/cypress/README.md @@ -0,0 +1,89 @@ +# PSoC6 Hardware Crypto Port for wolfSSL + +This directory provides a hardware-accelerated cryptography port for Cypress PSoC6 devices, integrating the PSoC6 hardware crypto block with the wolfSSL cryptography library. The implementation leverages the PSoC6 hardware to accelerate various cryptographic hash and ECC operations, improving performance and reducing CPU load. + +## Implemented Features + +### 1. Hardware-Accelerated Hash Functions + +The following hash algorithms are implemented using the PSoC6 hardware crypto block: + +- **SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256** + - All handled by the function `wc_Psoc6_Sha1_Sha2_Init`, which initializes the hardware for the selected hash mode. + - The macros `PSOC6_HASH_SHA1` and `PSOC6_HASH_SHA2` (defined in `psoc6_crypto.h`) control which SHA-1 and SHA-2 family algorithms are available for hardware acceleration. + - The corresponding wolfSSL macros (e.g., `WOLFSSL_SHA224`, `WOLFSSL_SHA384`, `WOLFSSL_SHA512`) must also be defined to enable the algorithm in the library. + +- **SHA-3 Family** + - Supported if `PSOC6_HASH_SHA3` (defined in `psoc6_crypto.h`) and `WOLFSSL_SHA3` are both defined. + - Functions: `wc_Psoc6_Sha3_Init`, `wc_Psoc6_Sha3_Update`, `wc_Psoc6_Sha3_Final` + - SHAKE support: `wc_Psoc6_Shake_SqueezeBlocks` + - To enable SHAKE support (and use wc_Psoc6_Shake_SqueezeBlocks), you must define either `WOLFSSL_SHAKE128` or `WOLFSSL_SHAKE256` in addition to `WOLFSSL_SHA3` and hardware acceleration macros. + +All hash operations are offloaded to the PSoC6 hardware, with mutex protection for thread safety. + +### 2. Hardware-Accelerated ECDSA Verification + +- **ECDSA Signature Verification** + - Function: `psoc6_ecc_verify_hash_ex` + - Uses PSoC6 hardware to verify ECDSA signatures for supported curves (up to secp521r1). + - Enabled when `HAVE_ECC` is defined. + +### 3. Crypto Block Initialization and Resource Management + +- **Initialization** + - Function: `psoc6_crypto_port_init` + - Enables the PSoC6 crypto hardware block. +- **Resource Cleanup** + - Function: `wc_Psoc6_Sha_Free` + - Clears and synchronizes the hardware register buffer. + +## Enable Hardware Acceleration + +To enable PSoC6 hardware crypto acceleration for hash and ECC algorithms, ensure the following macros are defined: + +- `WOLFSSL_PSOC6_CRYPTO` — Enables the PSoC6 hardware crypto port. +- The following are defined in `psoc6_crypto.h` and control which hardware hash accelerations are available: + - `PSOC6_HASH_SHA1` — Enables SHA-1 hardware acceleration. + - `PSOC6_HASH_SHA2` — Enables SHA-2 family (SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256) hardware acceleration. + - `PSOC6_HASH_SHA3` — Enables SHA-3 family hardware acceleration. +- To enable the corresponding algorithms in wolfSSL, define the following macros as needed (typically in your `wolfssl/wolfcrypt/settings.h` or build system): + - `WOLFSSL_SHA224` — Enable SHA-224 support. + - `WOLFSSL_SHA384` — Enable SHA-384 support. + - `WOLFSSL_SHA512` — Enable SHA-512, SHA-512/224, SHA-512/256 support. + - `WOLFSSL_SHA3` — Enable SHA-3 support. + - `WOLFSSL_SHAKE128`, `WOLFSSL_SHAKE256` — Enable SHAKE support. + - `HAVE_ECC` — Enable ECC and ECDSA support. + +**Example: Enabling SHA-1, SHA-2, and SHA-3 Hardware Acceleration** + +In your build configuration or `wolfssl/wolfcrypt/settings.h`: +```c +#define WOLFSSL_PSOC6_CRYPTO +#define WOLFSSL_SHA224 +#define WOLFSSL_SHA384 +#define WOLFSSL_SHA512 +#define WOLFSSL_SHA3 +#define WOLFSSL_SHAKE128 +#define WOLFSSL_SHAKE256 +#define HAVE_ECC +``` +- No need to define `PSOC6_HASH_SHA1`, `PSOC6_HASH_SHA2`, or `PSOC6_HASH_SHA3` yourself; they are defined in `psoc6_crypto.h`. + +## File Overview + +- `psoc6_crypto.h` + Header file declaring the hardware crypto interface and configuration macros. +- `psoc6_crypto.c` + Implementation of the hardware-accelerated hash and ECC functions for PSoC6. + +## Integration Notes + +- The port expects the PSoC6 PDL (Peripheral Driver Library) to be available and included in your project. +- The hardware crypto block is initialized on first use; no manual initialization is required unless you wish to call `psoc6_crypto_port_init` directly. +- Hash operations are mutex-protected for thread safety. +- ECC hardware operations are not mutex-protected; if you use ECC functions from multiple threads, you must provide your own synchronization. +- The implementation is designed to be compatible with the wolfSSL API, so existing code using wolfSSL hash/ECC functions will automatically benefit from hardware acceleration when enabled. + +--- + +For further details, refer to the comments in [`psoc6_crypto.h`](wolfssl/wolfssl-master/wolfcrypt/port/cypress/psoc6_crypto.h) and [`psoc6_crypto.c`](wolfssl/wolfssl-master/wolfcrypt/src/port/cypress/psoc6_crypto.c) diff --git a/wolfcrypt/src/port/cypress/psoc6_crypto.c b/wolfcrypt/src/port/cypress/psoc6_crypto.c index 527a6f959b2..aca67d1b47d 100644 --- a/wolfcrypt/src/port/cypress/psoc6_crypto.c +++ b/wolfcrypt/src/port/cypress/psoc6_crypto.c @@ -20,30 +20,50 @@ */ #ifdef HAVE_CONFIG_H - #include +#include #endif #include #ifdef NO_INLINE - #include +#include #else - #define WOLFSSL_MISC_INCLUDED - #include +#define WOLFSSL_MISC_INCLUDED +#include #endif #if defined(WOLFSSL_PSOC6_CRYPTO) +#include +#include + #include #include #include #include -#include + +#include "cy_crypto_core_hw_v2.h" +#include "cy_crypto_core_mem.h" #ifdef HAVE_ECC #include #endif -static CRYPTO_Type *crypto_base = PSOC6_CRYPTO_BASE; +#if defined(PSOC6_HASH_SHA3) + +/* Number of bits in a byte */ +#define BITS_IN_BYTE 8U + +/* Number of bytes of SHA3 to store in 1st partition of register buffer + * (reg_buff[1023:0]) */ +#define PSOC6_CRYPTO_SHA3_RB_LOWER 128U + +/* Number of bytes of SHA3 to store in 2nd partition of register buffer + * (reg_buff[2047:1024]) */ +#define PSOC6_CRYPTO_SHA3_RB_UPPER 72U + +#endif /* PSOC6_HASH_SHA3 */ + +static CRYPTO_Type* crypto_base = PSOC6_CRYPTO_BASE; /* Hook for device specific initialization */ int psoc6_crypto_port_init(void) @@ -52,123 +72,948 @@ int psoc6_crypto_port_init(void) return 0; } -/* Sha-512 */ - -#ifdef WOLFSSL_SHA512 -int wc_InitSha512(wc_Sha512* sha) +/* Initialize the PSoC6 hardware crypto engine for SHA-1, SHA-2, or SHA-512 + * operation. + * + * sha Pointer to hash context structure (wc_Sha, wc_Sha224, wc_Sha256, + * wc_Sha384, wc_Sha512). hash_mode Hash mode selector (WC_PSOC6_SHA1, + * WC_PSOC6_SHA224, WC_PSOC6_SHA256, etc.). init_hash If 1, initializes the hash + * state; if 0, does not initialize. returns 0 on success, BAD_FUNC_ARG or + * hardware error code on failure. + */ +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) + if (sha == NULL) { return BAD_FUNC_ARG; - Cy_Crypto_Core_MemSet(crypto_base, sha, 0, sizeof(sha)); - res = Cy_Crypto_Core_Sha_Init(crypto_base, &sha->hash_state, CY_CRYPTO_MODE_SHA512, &sha->sha_buffers); - if (res != CY_CRYPTO_SUCCESS) - return (int)res; - return (int) Cy_Crypto_Core_Sha_Start(crypto_base, &sha->hash_state); + } + + /* Enable CRYPTO block if not enabled */ + 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: + /* Initialize the PSoC6 hash state and configure the SHA mode */ + res = Cy_Crypto_Core_Sha_Init( + crypto_base, &((wc_Sha*)sha)->hash_state, CY_CRYPTO_MODE_SHA1, + &((wc_Sha*)sha)->sha_buffers); + /* Initialize the hash state to the SHA1 initial values if requested + * (init_hash set to 1) */ + 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 /* WOLFSSL_SHA224 */ + 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 /* !NO_SHA256 */ + +#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 /* WOLFSSL_SHA384 */ + +#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 /* WOLFSSL_SHA512_224 */ + +#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 /* WOLFSSL_SHA512_256 */ + +#endif /* WOLFSSL_SHA512 */ + +#endif /* PSOC6_HASH_SHA2 */ + default: + return BAD_FUNC_ARG; + } + + return res; } -int wc_InitSha512_ex(wc_Sha512* sha, void *heap, int devid) +/* Free resources and clear the register buffer for the PSoC6 hardware crypto + * engine. + * + * No parameters. + * No return value. + */ +void wc_Psoc6_Sha_Free(void) { + /* Clear the register buffer */ + Cy_Crypto_Core_V2_RBClear(crypto_base); + + /* Wait until the instruction is complete */ + Cy_Crypto_Core_V2_Sync(crypto_base); +} + +/* SHA */ +#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)); + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Initialize the PSoC6 hash buffers for SHA1 */ + ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA1, 1); + /* Release the lock */ + 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) { + /* valid, but do nothing */ + return 0; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Perform the SHA calculation input data */ + ret = Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + return ret; +} + +int wc_ShaFinal(wc_Sha* sha, byte* hash) +{ + int ret; + + if (sha == NULL || hash == NULL) + return BAD_FUNC_ARG; + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Complete the SHA calculation */ + ret = + (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + if (ret != 0) + return ret; + + /* Reset state */ + return wc_InitSha(sha); +} + +#endif /* !NO_SHA && PSOC6_HASH_SHA1 */ + +/* SHA2 */ +#if defined(PSOC6_HASH_SHA2) + +/* Sha-256 */ +#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; - return wc_InitSha512(sha); + XMEMSET(sha, 0, sizeof(wc_Sha256)); + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Initialize the PSoC6 hash buffers for SHA256 */ + ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA256, 1); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + return ret; } -int wc_Sha512Update(wc_Sha512* sha, const byte* in, word32 sz) +int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz) { - if ((!sha) || (!in)) + int ret; + if (sha == NULL || (in == NULL && sz > 0)) { return BAD_FUNC_ARG; - if (sz == 0) + } + + if (in == NULL && sz == 0) { + /* valid, but do nothing */ return 0; + } - return (int)Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz); + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Perform the SHA calculation input data */ + ret = Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; } -int wc_Sha512Final(wc_Sha512* sha, byte* hash) +int wc_Sha256Final(wc_Sha256* sha, byte* hash) { - if ((!sha) || (!hash)) + int ret; + if (sha == NULL || hash == NULL) return BAD_FUNC_ARG; - return (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash); + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Complete the SHA calculation */ + ret = + (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + if (ret != 0) + return ret; + + /* Reset state */ + return wc_InitSha256(sha); } -int wc_Sha512GetHash(wc_Sha512* sha, byte* hash) +/* Sha-224 */ +#if defined(WOLFSSL_SHA224) + +int wc_InitSha224_ex(wc_Sha224* sha, void* heap, int devid) { - if ((!sha) || (!hash)) + int ret; + if (sha == NULL) return BAD_FUNC_ARG; - Cy_Crypto_Core_MemCpy(crypto_base, hash, sha->hash_state.hash, WC_SHA512_DIGEST_SIZE); - return 0; + + (void)heap; + (void)devid; + XMEMSET(sha, 0, sizeof(wc_Sha224)); + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Initialize the PSoC6 hash buffers for SHA224 */ + ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA224, 1); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + return ret; } -int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) +int wc_Sha224Update(wc_Sha224* sha, const byte* in, word32 sz) { - if ((!dst) || (!src)) + int ret; + if (sha == NULL || (in == NULL && sz > 0)) { return BAD_FUNC_ARG; - Cy_Crypto_Core_MemCpy(crypto_base, dst, src, sizeof(wc_Sha512)); - return (int)Cy_Crypto_Core_Sha_Init(crypto_base, &dst->hash_state, CY_CRYPTO_MODE_SHA512, &dst->sha_buffers); + } + + if (in == NULL && sz == 0) { + /* valid, but do nothing */ + return 0; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Perform the SHA calculation input data */ + ret = Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; } -void wc_Sha512Free(wc_Sha512* sha) +int wc_Sha224Final(wc_Sha224* sha, byte* hash) { - if (sha) - Cy_Crypto_Core_Sha_Free(crypto_base, &sha->hash_state); + int ret; + if (sha == NULL || hash == NULL) + return BAD_FUNC_ARG; + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Complete the SHA calculation */ + ret = + (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + if (ret != 0) + return ret; + + /* Reset state */ + return wc_InitSha224(sha); } -#endif +#endif /* #if !NO_SHA224 */ +#endif /* #if !NO_SHA256 */ -/* Sha-256 */ +/* SHA-384 */ +#if defined(WOLFSSL_SHA384) -#ifndef NO_SHA256 -int wc_InitSha256(wc_Sha256* sha) +int wc_InitSha384_ex(wc_Sha384* sha, void* heap, int devid) { - cy_en_crypto_status_t res; - if (!sha) + int ret; + if (sha == NULL) return BAD_FUNC_ARG; - Cy_Crypto_Core_MemSet(crypto_base, sha, 0, sizeof(sha)); - res = Cy_Crypto_Core_Sha_Init(crypto_base, &sha->hash_state, CY_CRYPTO_MODE_SHA256, &sha->sha_buffers); - if (res != CY_CRYPTO_SUCCESS) - return (int)res; - return (int) Cy_Crypto_Core_Sha_Start(crypto_base, &sha->hash_state); + + (void)heap; + (void)devid; + XMEMSET(sha, 0, sizeof(wc_Sha384)); + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Initialize the PSoC6 hash buffers for SHA384 */ + ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA384, 1); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + return ret; } -int wc_Sha256Update(wc_Sha256* sha, const byte* in, word32 sz) +int wc_Sha384Update(wc_Sha384* sha, const byte* in, word32 sz) { - if ((!sha) || (!in)) + int ret; + if (sha == NULL || (in == NULL && sz > 0)) { return BAD_FUNC_ARG; - if (sz == 0) + } + + if (in == NULL && sz == 0) { + /* valid, but do nothing */ return 0; + } - return (int)Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz); + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Perform the SHA calculation input data */ + ret = Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + return ret; } -int wc_Sha256Final(wc_Sha256* sha, byte* hash) +int wc_Sha384Final(wc_Sha384* sha, byte* hash) +{ + int ret; + + if (sha == NULL || hash == NULL) + return BAD_FUNC_ARG; + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Complete the SHA calculation */ + ret = + (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + if (ret != 0) + return ret; + + /* Reset state */ + return wc_InitSha384(sha); +} + +#endif /* WOLFSSL_SHA384 */ + +/* Sha-512 */ +#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)); + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Initialize the PSoC6 hash buffers for SHA512 */ + ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA512, 1); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + return ret; +} + +int wc_Sha512Update(wc_Sha512* sha, const byte* in, word32 sz) { - if ((!sha) || (!hash)) + int ret; + if (sha == NULL || (in == NULL && sz > 0)) { return BAD_FUNC_ARG; - return (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash); + } + + if (in == NULL && sz == 0) { + /* valid, but do nothing */ + return 0; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Perform the SHA calculation input data */ + ret = Cy_Crypto_Core_Sha_Update(crypto_base, &sha->hash_state, in, sz); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + return ret; } -int wc_Sha256GetHash(wc_Sha256* sha, byte* hash) +int wc_Sha512Final(wc_Sha512* sha, byte* hash) { - if ((!sha) || (!hash)) + int ret; + if (sha == NULL || hash == NULL) return BAD_FUNC_ARG; - Cy_Crypto_Core_MemCpy(crypto_base, hash, sha->hash_state.hash, WC_SHA256_DIGEST_SIZE); - return 0; + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Complete the SHA calculation */ + ret = + (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + if (ret != 0) + return ret; + + /* Reset state */ + return wc_InitSha512(sha); } -int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst) +/* SHA-512_224 */ + +#ifndef WOLFSSL_NOSHA512_224 + +int wc_InitSha512_224_ex(wc_Sha512* sha, void* heap, int devid) { - if ((!dst) || (!src)) + int ret; + if (sha == NULL) return BAD_FUNC_ARG; - Cy_Crypto_Core_MemCpy(crypto_base, dst, src, sizeof(wc_Sha256)); - return (int)Cy_Crypto_Core_Sha_Init(crypto_base, &dst->hash_state, CY_CRYPTO_MODE_SHA256, &dst->sha_buffers); + + (void)heap; + (void)devid; + XMEMSET(sha, 0, sizeof(wc_Sha512)); + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Initialize the PSoC6 hash buffers for SHA512_224 */ + ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA512_224, 1); + /* Release the lock */ + 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; + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Complete the SHA calculation */ + ret = + (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + /* Reset state */ + return wc_InitSha512_224(sha); +} + +#endif /* !WOLFSSL_NOSHA512_224 */ + +/* SHA-512_256 */ + +#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)); + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Initialize the PSoC6 hash buffers for SHA512_256 */ + ret = wc_Psoc6_Sha1_Sha2_Init(sha, WC_PSOC6_SHA512_256, 1); + /* Release the lock */ + 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; + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Complete the SHA calculation */ + ret = + (int)Cy_Crypto_Core_Sha_Finish(crypto_base, &sha->hash_state, hash); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + if (ret != 0) + return ret; + + /* Reset state */ + return wc_InitSha512_256(sha); +} + +#endif /* !WOLFSSL_NOSHA512_256 */ +#endif /* WOLFSSL_SHA512 */ +#endif /* PSOC6_HASH_SHA2 */ + +/* SHA3 */ +#if defined(WOLFSSL_SHA3) && defined(PSOC6_HASH_SHA3) + +/* Initialize the state for a SHA-3 hash operation using the PSoC6 hardware + * crypto engine. + * + * sha3 wc_Sha3 object holding state. + * returns 0 on success. + */ +int wc_Psoc6_Sha3_Init(void* sha3) +{ + wc_Sha3* sha3_ctx = (wc_Sha3*)sha3; + + /* Enable CRYPTO block if not enabled */ + if (!Cy_Crypto_Core_IsEnabled(crypto_base)) { + Cy_Crypto_Core_Enable(crypto_base); + } + + /* Clear the data in sha3 structure */ + Cy_Crypto_Core_MemSet(crypto_base, sha3, 0, sizeof(wc_Sha3)); + + /* Initialise the hash pointer in hash_state structure */ + sha3_ctx->hash_state.hash = + (uint8_t*)((cy_stc_crypto_v2_sha3_buffers_t*)&sha3_ctx->sha_buffers) + ->hash; + + /* Set the SHA mode to SHA3 */ + sha3_ctx->hash_state.modeHw = (uint32_t)CY_CRYPTO_V2_SHA3_OPC; + + /* Initialize the hashsize to 0 */ + sha3_ctx->hash_state.hashSize = 0; + + /* Set the init_done flag to false. It will be updated in */ + /* Sha3Update once the mode and blockSize are updated */ + sha3_ctx->init_done = false; + + return 0; +} + +/* Update the SHA-3 hash state with input data using the PSoC6 hardware crypto + * engine. + * + * sha3 wc_Sha3 object holding state. + * data Input data buffer. + * len Length of input data. + * p SHA-3 parameter (block size/count). + * returns 0 on success, BAD_FUNC_ARG or hardware error code on failure. + */ +int wc_Psoc6_Sha3_Update(void* sha3, const byte* data, word32 len, byte p) +{ + wc_Sha3* sha3_ctx = (wc_Sha3*)sha3; + + /* If the initialization is not done, set it up */ + if (!sha3_ctx->init_done) { + /* Set the SHA mode, blockSize and digestSize (for applicable ones) */ + switch (p) { + case WC_SHA3_128_COUNT: + /* For SHAKE-128 Cy_Crypto_Core_Sha_Update requires mode to be + * valid (SHA3_224 fits) */ + 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; + } + + /* Update the init_done flag */ + sha3_ctx->init_done = true; + } + + /* Perform the SHA calculation input data */ + return Cy_Crypto_Core_Sha_Update(crypto_base, &sha3_ctx->hash_state, data, + len); +} + +/* Finalize the SHA-3 hash operation and produce the digest using the PSoC6 + * hardware crypto engine. + * + * sha3 wc_Sha3 object holding state. + * padChar Padding character for SHA-3. + * hash Output buffer for hash result. + * p SHA-3 parameter (block size/count). + * l Output length. + * returns 0 on success, BAD_FUNC_ARG or hardware error code on failure. + */ +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; + + /* For KECCCAK256 specific padding */ +#ifdef WOLFSSL_HASH_FLAGS + if ((p == WC_SHA3_256_COUNT) && (sha3_ctx->flags & WC_HASH_SHA3_KECCAK256)) + padChar = 0x01; +#endif + + /* Apply padding */ + sha3_ctx->hash_state.hash[sha3_ctx->hash_state.blockIdx] ^= padChar; + sha3_ctx->hash_state.hash[rate - 1] ^= 0x80; + + /* Clear the register buffer */ + Cy_Crypto_Core_V2_RBClear(crypto_base); + + /* Wait until the instruction is complete */ + Cy_Crypto_Core_V2_Sync(crypto_base); + + /* Start streaming data in sha3_ctx->sha_buffers.hash into LOAD_FIFO0 */ + Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_LOAD0, + sha3_ctx->sha_buffers.hash, + CY_CRYPTO_SHA3_STATE_SIZE); + + /* XOR data present in lower register buffer partition with data streamed + * from LOAD0_FIF0 */ + Cy_Crypto_Core_V2_RBXor(crypto_base, 0U, PSOC6_CRYPTO_SHA3_RB_LOWER); + + /* Swap the data present in the two register buffer partitions + * (swap(reg_buff[1023:0], reg_buff[2047:1024])) */ + Cy_Crypto_Core_V2_RBSwap(crypto_base); + + /* XOR data present in upper register buffer partition with data streamed + * from LOAD0_FIF0 */ + Cy_Crypto_Core_V2_RBXor(crypto_base, 0U, PSOC6_CRYPTO_SHA3_RB_UPPER); + + /* Swap the data present in the two register buffer partitions. The recently + * XOR'ed data will be now present in 2nd partition */ + Cy_Crypto_Core_V2_RBSwap(crypto_base); + + /* Wait until the instruction is complete */ + Cy_Crypto_Core_V2_Sync(crypto_base); + + /* Process full blocks and write output to hash buffer */ + for (offset = 0; l - offset >= rate; offset += rate) { + /* Perform SHA3 on current state. */ + Cy_Crypto_Core_V2_Run(crypto_base, sha3_ctx->hash_state.modeHw); + + /* Wait until the instruction is complete */ + Cy_Crypto_Core_V2_Sync(crypto_base); + + /* If the rate is more than 128, then we have to copy the data in 2nd + * partition of register buffer as well */ + if (rate > PSOC6_CRYPTO_SHA3_RB_LOWER) { + /* Start streaming data in 1st partition of register buffer into + * hash buffer */ + Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE, + hash + offset, + PSOC6_CRYPTO_SHA3_RB_LOWER); + + /* Copy the data in register buffer lower partition into hash buffer + */ + Cy_Crypto_Core_V2_RBStore(crypto_base, 0U, + PSOC6_CRYPTO_SHA3_RB_LOWER); + + /* Wait until FF_STORE operation is completed */ + Cy_Crypto_Core_V2_FFStoreSync(crypto_base); + + /* Swap the data present in the two register buffer partitions + * (swap(reg_buff[1023:0], reg_buff[2047:1024])) */ + Cy_Crypto_Core_V2_RBSwap(crypto_base); + + /* Wait until the instruction is complete */ + Cy_Crypto_Core_V2_Sync(crypto_base); + + /* Now the 1st partition have 2nd partition data, start streaming + * remaining extra data in register buffer into hash buffer */ + 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)); + + /* Copy the remaining data in register buffer lower partition into + * hash buffer */ + Cy_Crypto_Core_V2_RBStore(crypto_base, 0U, + (rate - PSOC6_CRYPTO_SHA3_RB_LOWER)); + + /* Wait until FF_STORE operation is completed */ + Cy_Crypto_Core_V2_FFStoreSync(crypto_base); + + /* Swap back the register buffer partitions */ + Cy_Crypto_Core_V2_RBSwap(crypto_base); + } + else { + /* Start streaming data in 1st partition of register buffer into + * hash buffer */ + Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE, + hash + offset, rate); + + /* Copy the remaining data in register buffer lower partition into + * hash buffer */ + Cy_Crypto_Core_V2_RBStore(crypto_base, 0U, rate); + + /* Wait until FF_STORE operation is completed */ + Cy_Crypto_Core_V2_FFStoreSync(crypto_base); + } + } + + /* If more data need to be processed */ + if (offset != l) { + /* Perform SHA3 on current state. */ + Cy_Crypto_Core_V2_Run(crypto_base, sha3_ctx->hash_state.modeHw); + + /* Wait until the instruction is complete */ + Cy_Crypto_Core_V2_Sync(crypto_base); + + /* If amount of data to be copied is more than length of register buffer + * partition (128), */ + /* then we have to copy the data in 2nd partition of register buffer as + * well */ + if ((l - offset) > PSOC6_CRYPTO_SHA3_RB_LOWER) { + /* Start streaming data in 1st partition of register buffer into + * hash buffer */ + Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE, + hash + offset, + PSOC6_CRYPTO_SHA3_RB_LOWER); + + /* Copy the data in register buffer lower partition into hash buffer + */ + Cy_Crypto_Core_V2_RBStore(crypto_base, 0U, + PSOC6_CRYPTO_SHA3_RB_LOWER); + + /* Wait until FF_STORE operation is completed */ + Cy_Crypto_Core_V2_FFStoreSync(crypto_base); + + /* Swap the data present in the two register buffer partitions + * (swap(reg_buff[1023:0], reg_buff[2047:1024])) */ + Cy_Crypto_Core_V2_RBSwap(crypto_base); + + /* Wait until the instruction is complete */ + Cy_Crypto_Core_V2_Sync(crypto_base); + + /* Now the 1st partition have 2nd partition data, start streaming + * remaining extra data in register buffer into hash buffer */ + 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)); + + /* Copy the remaining data in register buffer lower partition into + * hash buffer */ + Cy_Crypto_Core_V2_RBStore( + crypto_base, 0U, ((l - offset) - PSOC6_CRYPTO_SHA3_RB_LOWER)); + + /* Wait until FF_STORE operation is completed */ + Cy_Crypto_Core_V2_FFStoreSync(crypto_base); + } + else { + /* Start streaming data in 1st partition of register buffer into + * hash buffer */ + Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE, + hash + offset, l - offset); + + /* Copy the data in register buffer lower partition into hash buffer + */ + Cy_Crypto_Core_V2_RBStore(crypto_base, 0U, l - offset); + + /* Wait until FF_STORE operation is completed */ + Cy_Crypto_Core_V2_FFStoreSync(crypto_base); + } + } + + return 0; } -void wc_Sha256Free(wc_Sha256* sha) +#if defined(WOLFSSL_SHAKE128) || defined(WOLFSSL_SHAKE256) + +/* Squeeze output blocks from a SHAKE state using the PSoC6 hardware crypto + * engine. + * + * shake wc_Shake object holding state. + * out Output buffer for squeezed blocks. + * blockCnt Number of blocks to squeeze. + * returns 0 on success, BAD_FUNC_ARG or hardware error code on failure. + */ +int wc_Psoc6_Shake_SqueezeBlocks(void* shake, byte* out, word32 blockCnt) { - if (sha) - Cy_Crypto_Core_Sha_Free(crypto_base, &sha->hash_state); + wc_Shake* shake_ctx = (wc_Shake*)shake; + + for (; (blockCnt > 0); blockCnt--) { + /* Perform SHA3 on the current state */ + Cy_Crypto_Core_V2_Run(crypto_base, shake_ctx->hash_state.modeHw); + + /* Wait until the instruction is complete */ + Cy_Crypto_Core_V2_Sync(crypto_base); + + /* Start streaming data in 1st partition of register buffer into hash + * buffer */ + Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE, out, + PSOC6_CRYPTO_SHA3_RB_LOWER); + + /* Copy the data in register buffer lower partition into hash buffer */ + Cy_Crypto_Core_V2_RBStore(crypto_base, 0U, PSOC6_CRYPTO_SHA3_RB_LOWER); + + /* Wait until FF_STORE operation is completed */ + Cy_Crypto_Core_V2_FFStoreSync(crypto_base); + + /* Swap the data present in the two register buffer partitions + * (swap(reg_buff[1023:0], reg_buff[2047:1024])) */ + Cy_Crypto_Core_V2_RBSwap(crypto_base); + + /* Wait until the instruction is complete */ + Cy_Crypto_Core_V2_Sync(crypto_base); + + /* Now the 1st partition have 2nd partition data, start streaming + * remaining extra data in register buffer into hash buffer */ + 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); + + /* Copy the remaining data in register buffer lower partition into hash + * buffer */ + Cy_Crypto_Core_V2_RBStore(crypto_base, 0U, + shake_ctx->hash_state.blockSize - + PSOC6_CRYPTO_SHA3_RB_LOWER); + + /* Wait until FF_STORE operation is completed */ + Cy_Crypto_Core_V2_FFStoreSync(crypto_base); + + /* Swap back the register buffer partitions */ + Cy_Crypto_Core_V2_RBSwap(crypto_base); + + /* Move to the next block */ + out += shake_ctx->hash_state.blockSize; + } + + return 0; } -#endif /* NO_SHA256 */ + +#endif /* WOLFSSL_SHAKE128 || WOLFSSL_SHAKE256 */ + +#endif /* WOLFSSL_SHA3 && PSOC6_HASH_SHA3 */ /* ECDSA */ #ifdef HAVE_ECC @@ -176,7 +1021,7 @@ void wc_Sha256Free(wc_Sha256* sha) #define MAX_ECC_KEYSIZE 66 /* Supports up to secp521r1 */ static cy_en_crypto_ecc_curve_id_t psoc6_get_curve_id(int size) { - switch(size) { + switch (size) { case 24: return CY_CRYPTO_ECC_ECP_SECP192R1; case 28: @@ -192,58 +1037,129 @@ static cy_en_crypto_ecc_curve_id_t psoc6_get_curve_id(int size) } } -int psoc6_ecc_verify_hash_ex(MATH_INT_T *r, MATH_INT_T *s, const byte* hash, - word32 hashlen, int* verif_res, ecc_key* key) +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]; + uint8_t signature_buf[MAX_ECC_KEYSIZE * 2] = { 0 }; cy_stc_crypto_ecc_key ecc_key; - uint8_t stat = 0; - int res = -1; - int szModulus; - int szkbin; - uint8_t x[MAX_ECC_KEYSIZE], y[MAX_ECC_KEYSIZE]; + 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; - /* retrieve and check sizes */ - szModulus = mp_unsigned_bin_size(key->pubkey.x); - szkbin = mp_unsigned_bin_size(r); - if (szModulus > MAX_ECC_KEYSIZE) + /* Enable CRYPTO block if not enabled */ + 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; /* Prepare ECC key */ - ecc_key.type = PK_PUBLIC; - ecc_key.curveID = psoc6_get_curve_id(szModulus); - ecc_key.k = NULL; + 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; - res = mp_to_unsigned_bin(key->pubkey.x, x); - if (res == MP_OKAY) - res = mp_to_unsigned_bin(key->pubkey.y, y); - Cy_Crypto_Core_InvertEndianness(x, szModulus); - Cy_Crypto_Core_InvertEndianness(y, szModulus); + /* If the key is private only, generate the public key before */ + if (key->type == ECC_PRIVATEKEY_ONLY) { + /* Get the private key as bytes */ + res = mp_to_unsigned_bin(ecc_get_k(key), k); + if (res == MP_OKAY) { + /* Convert the private key into little endian */ + Cy_Crypto_Core_InvertEndianness(k, keySz); + + /* Make the public key from the private key */ + res = Cy_Crypto_Core_ECC_MakePublicKey(crypto_base, ecc_key.curveID, + k, &ecc_key); + + /* Load the public key into the key structure. */ + 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); + } + } + } - /* Prepare signature buffer */ - if (res == MP_OKAY) + /* Note: keySz is used for the offset of the s component in signature_buf + * because the hardware expects r and s to be packed as [r (keySz bytes)][s + * (keySz bytes)]. However, rSz and sSz are used for endianness conversion + * since they represent the actual sizes of the r and s values as produced + * by mp_to_unsigned_bin. + */ + if (res == MP_OKAY) { + /* Copy r component */ res = mp_to_unsigned_bin(r, signature_buf); - if (res == MP_OKAY) - res = mp_to_unsigned_bin(s, signature_buf + szkbin); - Cy_Crypto_Core_InvertEndianness(signature_buf, szkbin); - Cy_Crypto_Core_InvertEndianness(signature_buf + szkbin, szkbin); + if (res == MP_OKAY) { + /* Copy s component. */ + res = mp_to_unsigned_bin(s, signature_buf + keySz); + if (res == MP_OKAY) { + /* Convert to little endian */ + Cy_Crypto_Core_InvertEndianness(signature_buf, rSz); + Cy_Crypto_Core_InvertEndianness(signature_buf + keySz, sSz); + } + } + } /* perform HW ECDSA */ - if (res == MP_OKAY) - res = Cy_Crypto_Core_ECC_VerifyHash(crypto_base, signature_buf, hash, hashlen, &stat, &ecc_key); - if (res == 0) { - *verif_res = stat; + 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 res; + + return WC_FAILURE; } #endif /* HAVE_ECC */ - - #endif /* defined(WOLFSSL_PSOC6_CRYPTO) */ - diff --git a/wolfcrypt/src/sha.c b/wolfcrypt/src/sha.c index 618a6deb2a8..e8362b5829e 100644 --- a/wolfcrypt/src/sha.c +++ b/wolfcrypt/src/sha.c @@ -50,6 +50,10 @@ #include #endif +#if defined(WOLFSSL_PSOC6_CRYPTO) + #include +#endif + /* Assume no hash HW available until supporting HW found. */ #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW @@ -388,6 +392,8 @@ #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) /* implemented in wolfcrypt/src/port/psa/psa_hash.c */ +#elif defined(PSOC6_HASH_SHA1) + /* Implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */ #else /* Software implementation */ #define USE_SHA_SOFTWARE_IMPL @@ -1074,6 +1080,10 @@ void wc_ShaFree(wc_Sha* sha) #ifdef WOLFSSL_IMXRT_DCP DCPShaFree(sha); #endif + +#if defined(PSOC6_HASH_SHA1) + wc_Psoc6_Sha_Free(); +#endif } #endif /* !MAX3266X_SHA */ @@ -1164,6 +1174,10 @@ int wc_ShaCopy(wc_Sha* src, wc_Sha* dst) } #endif +#if defined(PSOC6_HASH_SHA1) + wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA1, 0); +#endif + #ifdef WOLFSSL_HASH_FLAGS dst->flags |= WC_HASH_FLAG_ISCOPY; #endif diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 07a5e29c2c6..b315a8b589d 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -114,7 +114,6 @@ on the specific device platform. #elif defined(WOLFSSL_CRYPTOCELL) /* wc_port.c includes wolfcrypt/src/port/arm/cryptoCellHash.c */ -#elif defined(WOLFSSL_PSOC6_CRYPTO) #elif defined(MAX3266X_SHA) /* Already brought in by sha256.h */ @@ -221,7 +220,7 @@ on the specific device platform. ((!defined(WOLFSSL_RENESAS_TSIP_TLS) && \ !defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) || \ defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) && \ - !defined(WOLFSSL_PSOC6_CRYPTO) && !defined(WOLFSSL_IMXRT_DCP) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ + !defined(PSOC6_HASH_SHA2) && !defined(WOLFSSL_IMXRT_DCP) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \ !defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_SE050_HASH) && \ ((!defined(WOLFSSL_RENESAS_SCEPROTECT) && \ !defined(WOLFSSL_RENESAS_RSIP)) \ @@ -1048,8 +1047,7 @@ static int InitSha256(wc_Sha256* sha256) /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */ -#elif defined(WOLFSSL_PSOC6_CRYPTO) - +#elif defined(PSOC6_HASH_SHA2) /* implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */ #elif defined(WOLFSSL_IMXRT_DCP) @@ -2004,6 +2002,8 @@ static int Transform_Sha256(wc_Sha256* sha256, const byte* data) !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH) /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */ +#elif defined(PSOC6_HASH_SHA2) + /* Implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */ #else @@ -2258,6 +2258,9 @@ static int Transform_Sha256(wc_Sha256* sha256, const byte* data) XFREE(sha224->msg, sha224->heap, DYNAMIC_TYPE_TMP_BUFFER); sha224->msg = NULL; } + #endif + #if defined(PSOC6_HASH_SHA2) + wc_Psoc6_Sha_Free(); #endif ForceZero(sha224, sizeof(*sha224)); } @@ -2376,6 +2379,11 @@ void wc_Sha256Free(wc_Sha256* sha256) ESP_LOGV(TAG, "Hardware unlock not needed in wc_Sha256Free."); } #endif + +#if defined(PSOC6_HASH_SHA2) + wc_Psoc6_Sha_Free(); +#endif + ForceZero(sha256, sizeof(*sha256)); } /* wc_Sha256Free */ @@ -2498,6 +2506,9 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz) } #endif + #if defined(PSOC6_HASH_SHA2) + wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA224, 0); + #endif return ret; } @@ -2539,9 +2550,6 @@ int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz) && !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH) /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */ - -#elif defined(WOLFSSL_PSOC6_CRYPTO) - /* implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */ #elif defined(WOLFSSL_IMXRT_DCP) /* implemented in wolfcrypt/src/port/nxp/dcp_port.c */ #elif defined(WOLFSSL_KCAPI_HASH) diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index 03a3a2c087e..e6a80e3b039 100644 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -27,6 +27,10 @@ #undef WOLFSSL_RISCV_ASM #endif +#if defined(WOLFSSL_PSOC6_CRYPTO) + #include +#endif + #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_XILINX_CRYPT) && \ !defined(WOLFSSL_AFALG_XILINX_SHA3) @@ -297,7 +301,7 @@ void BlockSha3(word64* s) */ #define ROTL64(a, n) (((a)<<(n))|((a)>>(64-(n)))) -#if !defined(STM32_HASH_SHA3) +#if !defined(STM32_HASH_SHA3) && !defined(PSOC6_HASH_SHA3) /* An array of values to XOR for block operation. */ static const word64 hash_keccak_r[24] = { @@ -532,7 +536,7 @@ do { \ while (0) #endif /* SHA3_BY_SPEC */ -#if !defined(STM32_HASH_SHA3) +#if !defined(STM32_HASH_SHA3) && !defined(PSOC6_HASH_SHA3) /* The block operation performed on the state. * * s The state. @@ -562,7 +566,7 @@ void BlockSha3(word64* s) #endif /* STM32_HASH_SHA3 */ #endif /* !WOLFSSL_ARMASM && !WOLFSSL_RISCV_ASM */ -#if !defined(STM32_HASH_SHA3) +#if !defined(STM32_HASH_SHA3) && !defined(PSOC6_HASH_SHA3) #if defined(BIG_ENDIAN_ORDER) static WC_INLINE word64 Load64Unaligned(const unsigned char *a) { @@ -913,6 +917,78 @@ static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, byte p, word32 l) return ret; } +#elif defined(PSOC6_HASH_SHA3) + +static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId) +{ + int ret; + if (sha3 == NULL) { + return BAD_FUNC_ARG; + } + (void)devId; + (void)heap; + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Initialize hash state for SHA-3 operation */ + ret = wc_Psoc6_Sha3_Init(sha3); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} + +static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p) +{ + int ret; + + if (sha3 == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + + if (data == NULL && len == 0) { + /* valid, but do nothing */ + return 0; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Perform SHA3 on the input data and update the hash state */ + ret = wc_Psoc6_Sha3_Update(sha3, data, len, p); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} + +static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len) +{ + int ret; + + if (sha3 == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Finalize SHA3 operations and produce digest */ + ret = wc_Psoc6_Sha3_Final(sha3, 0x06, hash, p, len); + if (ret == 0) { + /* Initialize hash state for SHA-3 operation */ + ret = wc_Psoc6_Sha3_Init(sha3); + } + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} + #else /* Initialize the state for a SHA-3 hash operation. @@ -1062,6 +1138,7 @@ static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len) return InitSha3(sha3); /* reset state */ } #endif + /* Dispose of any dynamically allocated data from the SHA3-384 operation. * (Required for async ops.) * @@ -1078,8 +1155,11 @@ static void wc_Sha3Free(wc_Sha3* sha3) wolfAsync_DevCtxFree(&sha3->asyncDev, WOLFSSL_ASYNC_MARKER_SHA3); #endif /* WOLFSSL_ASYNC_CRYPT */ -} +#if defined(PSOC6_HASH_SHA3) + wc_Psoc6_Sha_Free(); +#endif +} /* Copy the state of the SHA3 operation. * @@ -1099,6 +1179,12 @@ static int wc_Sha3Copy(wc_Sha3* src, wc_Sha3* dst) #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3) ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); #endif + +#if defined(PSOC6_HASH_SHA3) + /* Re-initialize internal pointers in hash_state that point inside sha_buffers */ + dst->hash_state.hash = (uint8_t*)((cy_stc_crypto_v2_sha3_buffers_t *)&dst->sha_buffers)->hash; +#endif + #ifdef WOLFSSL_HASH_FLAGS dst->flags |= WC_HASH_FLAG_ISCOPY; #endif @@ -1131,7 +1217,6 @@ static int wc_Sha3GetHash(wc_Sha3* sha3, byte* hash, byte p, byte len) return ret; } - /* Initialize the state for a SHA3-224 hash operation. * * sha3 wc_Sha3 object holding state. @@ -1449,6 +1534,101 @@ int wc_InitShake128(wc_Shake* shake, void* heap, int devId) return wc_InitSha3(shake, heap, devId); } +#if defined(PSOC6_HASH_SHA3) + +int wc_Shake128_Update(wc_Shake* shake, const byte* data, word32 len) +{ + int ret; + if (shake == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + + if (data == NULL && len == 0) { + /* valid, but do nothing */ + return 0; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Perform SHA3 on the input data and update the hash state */ + ret = wc_Psoc6_Sha3_Update(shake, data, len, WC_SHA3_128_COUNT); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} + +int wc_Shake128_Final(wc_Shake* shake, byte* hash, word32 hashLen) +{ + int ret; + + if (shake == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Finalize SHA3 operations and produce digest */ + ret = wc_Psoc6_Sha3_Final(shake, 0x1f, hash, WC_SHA3_128_COUNT, hashLen); + if (ret == 0) { + /* Initialize hash state for SHA-3 operation */ + ret = wc_Psoc6_Sha3_Init(shake); + } + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; + +} + +int wc_Shake128_Absorb(wc_Shake* shake, const byte* data, word32 len) +{ + int ret; + + if ((shake == NULL) || (data == NULL && len != 0)) { + return BAD_FUNC_ARG; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Perform SHA3 on the input data and update the hash state */ + ret = wc_Psoc6_Sha3_Update(shake, data, len, WC_SHA3_128_COUNT); + if (ret == 0) { + /* Finalize SHA3 operations and produce digest */ + ret = wc_Psoc6_Sha3_Final(shake, 0x1f, NULL, WC_SHA3_128_COUNT, 0); + } + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} + + +int wc_Shake128_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt) +{ + int ret; + if ((shake == NULL) || (out == NULL && blockCnt != 0)) { + return BAD_FUNC_ARG; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Squeeze output blocks from current hash state */ + ret = wc_Psoc6_Shake_SqueezeBlocks(shake, out, blockCnt); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} +#else /* Update the SHAKE128 hash state with message data. * * shake wc_Shake object holding state. @@ -1563,6 +1743,8 @@ int wc_Shake128_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt) return 0; } +#endif + /* Dispose of any dynamically allocated data from the SHAKE128 operation. * (Required for async ops.) @@ -1600,6 +1782,100 @@ int wc_InitShake256(wc_Shake* shake, void* heap, int devId) return wc_InitSha3(shake, heap, devId); } + +#ifdef PSOC6_HASH_SHA3 + +int wc_Shake256_Update(wc_Shake* shake, const byte* data, word32 len) +{ + int ret; + if (shake == NULL || (data == NULL && len > 0)) { + return BAD_FUNC_ARG; + } + + if (data == NULL && len == 0) { + /* valid, but do nothing */ + return 0; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Perform SHA3 on the input data and update the hash state */ + ret = wc_Psoc6_Sha3_Update(shake, data, len, WC_SHA3_256_COUNT); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} + +int wc_Shake256_Final(wc_Shake* shake, byte* hash, word32 hashLen) +{ + int ret; + if (shake == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Finalize SHA3 operations and produce digest */ + ret = wc_Psoc6_Sha3_Final(shake, 0x1f, hash, WC_SHA3_256_COUNT, hashLen); + if (ret == 0) { + /* Initialize hash state for SHA-3 operation */ + ret = wc_Psoc6_Sha3_Init(shake); + } + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} + +int wc_Shake256_Absorb(wc_Shake* shake, const byte* data, word32 len) +{ + int ret; + + if ((shake == NULL) || (data == NULL && len != 0)) { + return BAD_FUNC_ARG; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Perform SHA3 on the input data and update the hash state */ + ret = wc_Psoc6_Sha3_Update(shake, data, len, WC_SHA3_256_COUNT); + if (ret == 0) { + /* Finalize SHA3 operations and produce digest */ + ret = wc_Psoc6_Sha3_Final(shake, 0x1f, NULL, WC_SHA3_256_COUNT, 0); + } + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} + +int wc_Shake256_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt) +{ + int ret; + if ((shake == NULL) || (out == NULL && blockCnt != 0)) { + return BAD_FUNC_ARG; + } + + /* Lock the mutex to perform crypto operations */ + ret = wolfSSL_CryptHwMutexLock(); + if (ret == 0) { + /* Squeeze output blocks from current hash state */ + ret = wc_Psoc6_Shake_SqueezeBlocks(shake, out, blockCnt); + /* Release the lock */ + wolfSSL_CryptHwMutexUnLock(); + } + + return ret; +} + +#else /* Update the SHAKE256 hash state with message data. * * shake wc_Shake object holding state. @@ -1708,6 +1984,7 @@ int wc_Shake256_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt) return 0; } +#endif /* Dispose of any dynamically allocated data from the SHAKE256 operation. * (Required for async ops.) diff --git a/wolfcrypt/src/sha512.c b/wolfcrypt/src/sha512.c index 84d8625fc96..31c62e21e66 100644 --- a/wolfcrypt/src/sha512.c +++ b/wolfcrypt/src/sha512.c @@ -23,7 +23,7 @@ #if (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)) && \ (!defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_ARMASM_NO_NEON)) && \ - !defined(WOLFSSL_PSOC6_CRYPTO) && !defined(WOLFSSL_RISCV_ASM) + !defined(WOLFSSL_RISCV_ASM) /* determine if we are using Espressif SHA hardware acceleration */ #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW @@ -93,6 +93,10 @@ /* #include */ #endif +#if defined(WOLFSSL_PSOC6_CRYPTO) + #include +#endif + #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) #if defined(__GNUC__) && ((__GNUC__ < 4) || \ (__GNUC__ == 4 && __GNUC_MINOR__ <= 8)) @@ -260,6 +264,8 @@ return ret; } +#elif defined(PSOC6_HASH_SHA2) + /* Functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */ #else @@ -1224,6 +1230,7 @@ int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len) #elif defined(MAX3266X_SHA) /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ #elif defined(STM32_HASH_SHA512) +#elif defined(PSOC6_HASH_SHA2) #else static WC_INLINE int Sha512Final(wc_Sha512* sha512) @@ -1387,6 +1394,7 @@ static WC_INLINE int Sha512Final(wc_Sha512* sha512) #elif defined(MAX3266X_SHA) /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */ #elif defined(STM32_HASH_SHA512) +#elif defined(PSOC6_HASH_SHA2) #elif defined(WOLFSSL_SILABS_SHA512) #else @@ -1519,6 +1527,10 @@ void wc_Sha512Free(wc_Sha512* sha512) wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512); #endif /* WOLFSSL_ASYNC_CRYPT */ +#if defined(PSOC6_HASH_SHA2) + wc_Psoc6_Sha_Free(); +#endif + ForceZero(sha512, sizeof(*sha512)); } #endif @@ -1702,6 +1714,9 @@ int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data) return ret; } +#elif defined(PSOC6_HASH_SHA2) + /* implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */ + #else static int InitSha384(wc_Sha384* sha384) @@ -2090,6 +2105,10 @@ int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst) } #endif +#if defined(PSOC6_HASH_SHA2) + wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA512, 0); +#endif + return ret; } @@ -2173,12 +2192,14 @@ int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash) return ret; } +#elif defined(PSOC6_HASH_SHA2) + /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */ #endif int wc_InitSha512_224(wc_Sha512* sha) { return wc_InitSha512_224_ex(sha, NULL, INVALID_DEVID); } -#if !defined(STM32_HASH_SHA512_224) +#if !defined(STM32_HASH_SHA512_224) && !defined(PSOC6_HASH_SHA2) int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len) { return wc_Sha512Update(sha, data, len); @@ -2192,6 +2213,8 @@ int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len) #elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #elif defined(STM32_HASH_SHA512_224) +#elif defined(PSOC6_HASH_SHA2) + /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */ #else int wc_Sha512_224FinalRaw(wc_Sha512* sha, byte* hash) @@ -2312,12 +2335,14 @@ int wc_Sha512_224Transform(wc_Sha512* sha, const unsigned char* data) return ret; } +#elif defined(PSOC6_HASH_SHA2) + /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */ #endif int wc_InitSha512_256(wc_Sha512* sha) { return wc_InitSha512_256_ex(sha, NULL, INVALID_DEVID); } -#if !defined(STM32_HASH_SHA512_256) +#if !defined(STM32_HASH_SHA512_256) && !defined(PSOC6_HASH_SHA2) int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len) { return wc_Sha512Update(sha, data, len); @@ -2331,6 +2356,8 @@ int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len) #elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH) #elif defined(STM32_HASH_SHA512_256) +#elif defined(PSOC6_HASH_SHA2) + /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */ #else int wc_Sha512_256FinalRaw(wc_Sha512* sha, byte* hash) { @@ -2505,6 +2532,10 @@ int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst) } #endif +#if defined(PSOC6_HASH_SHA2) + wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA384, 0); +#endif + return ret; } diff --git a/wolfcrypt/src/wc_mlkem_poly.c b/wolfcrypt/src/wc_mlkem_poly.c index 9f8184de31d..496c7318956 100644 --- a/wolfcrypt/src/wc_mlkem_poly.c +++ b/wolfcrypt/src/wc_mlkem_poly.c @@ -3000,7 +3000,7 @@ int mlkem_hash512(wc_Sha3* hash, const byte* data1, word32 data1Len, */ void mlkem_prf_init(wc_Shake* prf) { - XMEMSET(prf->s, 0, sizeof(prf->s)); + wc_InitShake256(prf, NULL, 0); } /* New/Initialize SHAKE-256 object. diff --git a/wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h b/wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h index 40f30f2429e..c9ef31d8047 100644 --- a/wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h +++ b/wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h @@ -24,32 +24,64 @@ #include #include /* for MATH_INT_T */ -#include "cy_crypto_core_sha.h" -#include "cy_device_headers.h" -#include "psoc6_02_config.h" -#include "cy_crypto_common.h" -#include "cy_crypto_core.h" +#include +#if defined(WOLFSSL_PSOC6_CRYPTO) -#ifdef WOLFSSL_SHA512 -#include +#include "cy_pdl.h" + +/* SHA1, SHA2 and SHA3 are supported for PSOC6 */ +#define PSOC6_HASH_SHA1 +#define PSOC6_HASH_SHA2 +#define PSOC6_HASH_SHA3 + +typedef enum { + WC_PSOC6_SHA1 = 0, + WC_PSOC6_SHA224 = 1, + WC_PSOC6_SHA256 = 2, + WC_PSOC6_SHA384 = 3, + WC_PSOC6_SHA512 = 4, + WC_PSOC6_SHA512_224 = 5, + WC_PSOC6_SHA512_256 = 6 +} wc_psoc6_hash_sha1_sha2_t; + +#if defined(PSOC6_HASH_SHA1) || defined(PSOC6_HASH_SHA2) +int wc_Psoc6_Sha1_Sha2_Init(void* sha, wc_psoc6_hash_sha1_sha2_t hash_mode, + int init_hash); +#endif + +#if defined(PSOC6_HASH_SHA1) || defined(PSOC6_HASH_SHA2) || \ + defined(PSOC6_HASH_SHA3) +void wc_Psoc6_Sha_Free(void); #endif -#ifndef NO_SHA256 -#include -#include -#endif /* !def NO_SHA256 */ +#if defined(WOLFSSL_SHA3) && defined(PSOC6_HASH_SHA3) +int wc_Psoc6_Sha3_Init(void* sha3); +int wc_Psoc6_Sha3_Update(void* sha3, const byte* data, word32 len, byte p); +int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l); +int wc_Psoc6_Shake_SqueezeBlocks(void* shake, byte* out, word32 blockCnt); +#endif /* WOLFSSL_SHA3 && PSOC6_HASH_SHA3 */ #ifdef HAVE_ECC -#include -int psoc6_ecc_verify_hash_ex(MATH_INT_T *r, MATH_INT_T *s, const byte* hash, - word32 hashlen, int* verif_res, ecc_key* key); + +/* Forward declaration of ecc_key structure. + * Only pointers to struct ecc_key are used in this header, + * so the forward declaration is sufficient. + * The full definition is in wolfssl/wolfcrypt/ecc.h. + */ +struct ecc_key; + +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); #endif /* HAVE_ECC */ -#define PSOC6_CRYPTO_BASE ((CRYPTO_Type*) CRYPTO_BASE) +#define PSOC6_CRYPTO_BASE ((CRYPTO_Type*)CRYPTO_BASE) /* Crypto HW engine initialization */ int psoc6_crypto_port_init(void); +#endif /* WOLFSSL_PSOC6_CRYPTO */ + #endif /* _PSOC6_CRYPTO_PORT_H_ */ diff --git a/wolfssl/wolfcrypt/sha.h b/wolfssl/wolfcrypt/sha.h index ca5780edcde..e80a0d4a39e 100644 --- a/wolfssl/wolfcrypt/sha.h +++ b/wolfssl/wolfcrypt/sha.h @@ -48,6 +48,15 @@ #include "fsl_dcp.h" #endif +#if defined(WOLFSSL_PSOC6_CRYPTO) + #include + + #include "cy_crypto_core_sha.h" + #include "cy_device_headers.h" + #include "cy_crypto_common.h" + #include "cy_crypto_core.h" +#endif + #ifdef __cplusplus extern "C" { #endif @@ -141,6 +150,9 @@ struct wc_Sha { dcp_hash_ctx_t ctx; #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) psa_hash_operation_t psa_ctx; +#elif defined(PSOC6_HASH_SHA1) + cy_stc_crypto_sha_state_t hash_state; + cy_stc_crypto_v2_sha1_buffers_t sha_buffers; #else word32 buffLen; /* in bytes */ word32 loLen; /* length in bytes */ diff --git a/wolfssl/wolfcrypt/sha256.h b/wolfssl/wolfcrypt/sha256.h index 468e4d1dbbc..bf0d5213a47 100644 --- a/wolfssl/wolfcrypt/sha256.h +++ b/wolfssl/wolfcrypt/sha256.h @@ -50,10 +50,12 @@ #endif #if defined(WOLFSSL_PSOC6_CRYPTO) -#include "cy_crypto_core_sha.h" -#include "cy_device_headers.h" -#include "cy_crypto_common.h" -#include "cy_crypto_core.h" + #include + + #include "cy_crypto_core_sha.h" + #include "cy_device_headers.h" + #include "cy_crypto_common.h" + #include "cy_crypto_core.h" #endif #ifdef __cplusplus @@ -163,6 +165,7 @@ enum { #include "mcapi_error.h" #endif + /* wc_Sha256 digest */ struct wc_Sha256 { #ifdef FREESCALE_LTC_SHA @@ -176,9 +179,8 @@ struct wc_Sha256 { #elif defined(WOLFSSL_IMXRT_DCP) dcp_handle_t handle; dcp_hash_ctx_t ctx; -#elif defined(WOLFSSL_PSOC6_CRYPTO) +#elif defined(PSOC6_HASH_SHA2) cy_stc_crypto_sha_state_t hash_state; - cy_en_crypto_sha_mode_t sha_mode; cy_stc_crypto_v2_sha256_buffers_t sha_buffers; #elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH) psa_hash_operation_t psa_ctx; diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index 88382e4be9c..9fc32c06a59 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -117,8 +117,22 @@ enum { #include #else +#if defined(WOLFSSL_PSOC6_CRYPTO) + #include + + #include "cy_crypto_core_sha.h" + #include "cy_device_headers.h" + #include "cy_crypto_common.h" + #include "cy_crypto_core.h" +#endif + /* Sha3 digest */ struct wc_Sha3 { +#if defined(PSOC6_HASH_SHA3) + cy_stc_crypto_sha_state_t hash_state; + cy_stc_crypto_v2_sha3_buffers_t sha_buffers; + bool init_done; +#else /* State data that is processed for each block. */ word64 s[25]; /* Unprocessed message data. */ @@ -147,6 +161,7 @@ struct wc_Sha3 { #if defined(STM32_HASH_SHA3) STM32_HASH_Context stmCtx; #endif +#endif }; #ifndef WC_SHA3_TYPE_DEFINED diff --git a/wolfssl/wolfcrypt/sha512.h b/wolfssl/wolfcrypt/sha512.h index 36c056408dd..5d154b739fc 100644 --- a/wolfssl/wolfcrypt/sha512.h +++ b/wolfssl/wolfcrypt/sha512.h @@ -59,11 +59,14 @@ #include #endif #if defined(WOLFSSL_PSOC6_CRYPTO) + #include + #include "cy_crypto_core_sha.h" #include "cy_device_headers.h" #include "cy_crypto_common.h" #include "cy_crypto_core.h" #endif + #if defined(WOLFSSL_KCAPI_HASH) #include #endif @@ -144,9 +147,8 @@ enum { #endif /* wc_Sha512 digest */ struct wc_Sha512 { -#ifdef WOLFSSL_PSOC6_CRYPTO +#if defined(PSOC6_HASH_SHA2) cy_stc_crypto_sha_state_t hash_state; - cy_en_crypto_sha_mode_t sha_mode; cy_stc_crypto_v2_sha512_buffers_t sha_buffers; void* heap; #else