Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .wolfssl_known_macro_extras
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,8 @@ CTAO_CRYPT_AES_H
CTYPE_USER
CURVED448_SMALL
CUSTOM_ENTROPY_TIMEHIRES
CY_CRYPTO_DCACHE_ENABLED
CY_REMAP_ADDRESS_FOR_CRYPTO
CY_USING_HAL
DCC0_BASE
DCC1_BASE
Expand Down Expand Up @@ -550,6 +552,7 @@ NO_PKCS7_COMPRESSED_DATA
NO_PKCS7_ENCRYPTED_DATA
NO_PKCS7_STREAM
NO_POLY1305_ASM
NO_PSOC6_CRYPTO_ECC
NO_PUBLIC_CCM_SET_NONCE
NO_PUBLIC_GCM_SET_IV
NO_QAT_RNG
Expand Down
2 changes: 1 addition & 1 deletion tests/api/test_aes.c
Original file line number Diff line number Diff line change
Expand Up @@ -5526,7 +5526,7 @@ int test_wc_AesGcmDecrypt_WipeOnAuthFail(void)
!defined(WOLFSSL_KCAPI) && !defined(WOLFSSL_DEVCRYPTO_AES) && \
!defined(WOLFSSL_ASYNC_CRYPT) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
!defined(WOLFSSL_MICROCHIP_TA100) && !defined(WOLFSSL_STM32_BARE) && \
!defined(STM32_CRYPTO_AES_GCM) && !defined(WOLFSSL_PSOC6_CRYPTO) && \
!defined(STM32_CRYPTO_AES_GCM) && \
!defined(WOLFSSL_RISCV_ASM) && \
!defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM) && \
!defined(FREESCALE_LTC_AES_GCM) && !defined(ACVP_VECTOR_TESTING) && \
Expand Down
25 changes: 15 additions & 10 deletions wolfcrypt/src/ecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ ECC Curve Sizes:
!defined(WOLFSSL_KCAPI_ECC) && !defined(WOLFSSL_SE050) && \
!defined(WOLFSSL_XILINX_CRYPT_VERSAL) && \
(!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_SIGN_ONLY)) && \
!defined(WOLFSSL_PSOC6_CRYPTO)
!defined(PSOC6_CRYPTO_ECC)
/* STM32 sign-only (e.g. C5): the HW PKA cannot run the integrated ECDSA
* verify (mode 0x26) correctly, so use the SW verify helper rather than the
* HW-accelerator sigRS path. Note the helper's scalar multiplications still
Expand Down Expand Up @@ -9449,7 +9449,7 @@ int wc_ecc_verify_hash(const byte* sig, word32 siglen, const byte* hash,
#ifndef WOLF_CRYPTO_CB_ONLY_ECC

#if (!defined(WOLFSSL_STM32_PKA) || defined(WC_STM32_PKA_SIGN_ONLY)) && \
!defined(WOLFSSL_PSOC6_CRYPTO) && \
!defined(PSOC6_CRYPTO_ECC) && \
!defined(WOLF_CRYPTO_CB_ONLY_ECC)
static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
{
Expand Down Expand Up @@ -9480,7 +9480,7 @@ static int wc_ecc_check_r_s_range(ecc_key* key, mp_int* r, mp_int* s)
FREE_CURVE_SPECS();
return err;
}
#endif /* !WOLFSSL_STM32_PKA && !WOLFSSL_PSOC6_CRYPTO */
#endif /* !WOLFSSL_STM32_PKA && !PSOC6_CRYPTO_ECC */

#if defined(HAVE_ECC_VERIFY_HELPER) && !defined(WOLFSSL_MICROCHIP)
static int ecc_verify_hash_sp(mp_int *r, mp_int *s, const byte* hash,
Expand Down Expand Up @@ -10011,10 +10011,12 @@ static int ecc_verify_hash(mp_int *r, mp_int *s, const byte* hash,
int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
word32 hashlen, int* res, ecc_key* key)
{
#if defined(WOLFSSL_STM32_PKA) && !defined(WC_STM32_PKA_SIGN_ONLY)
/* HW ECDSA verify via STM32 PKA. Works under both the CubeMX-HAL
* and the bare-metal direct-register paths. (Under WC_STM32_PKA_SIGN_ONLY
* -- e.g. STM32C5 -- verify falls through to the software body below.)
#if (defined(WOLFSSL_STM32_PKA) && !defined(WC_STM32_PKA_SIGN_ONLY)) || \
defined(PSOC6_CRYPTO_ECC)
/* HW ECDSA verify via STM32 PKA or the PSoC6/PSOC Edge crypto engine.
* STM32 PKA works under both the CubeMX-HAL and the bare-metal
* direct-register paths. (Under WC_STM32_PKA_SIGN_ONLY -- e.g. STM32C5 --
* verify falls through to the software body below.)
* Mirror the non-FIPS
* input-validation from the SW body below (length range, all-zero
* digest rejection) so HW + SW share the same input contract. */
Expand All @@ -10026,7 +10028,8 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
if (r == NULL || s == NULL || hash == NULL || res == NULL || key == NULL) {
return ECC_BAD_ARG_E;
}
if ((hashlen > WC_MAX_DIGEST_SIZE) || (hashlen < WC_MIN_DIGEST_SIZE)) {
if ((hashlen > WC_MAX_DIGEST_SIZE) ||
(hashlen < WC_MIN_DIGEST_SIZE_FOR_VERIFY)) {
return BAD_LENGTH_E;
}
#ifndef WC_ALLOW_ECC_ZERO_HASH
Expand All @@ -10037,9 +10040,11 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash,
return ECC_BAD_ARG_E;
Comment thread
aidangarske marked this conversation as resolved.
#endif

return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
#elif defined(WOLFSSL_PSOC6_CRYPTO)
#if defined(PSOC6_CRYPTO_ECC)
return psoc6_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
#else
return stm32_ecc_verify_hash_ex(r, s, hash, hashlen, res, key);
#endif
#else
int err;
word32 keySz = 0;
Expand Down
6 changes: 6 additions & 0 deletions wolfcrypt/src/port/cypress/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,12 @@ In your build configuration or `wolfssl/wolfcrypt/settings.h`:
- 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/AES/ECC functions will automatically benefit from hardware acceleration when enabled.

## PSOC Edge E8

The same port runs on the PSOC Edge E8 family (PSE8x, CAT1D), whose crypto block is the same MXCRYPTO v2 IP, using the PDL crypto core drivers from Infineon's `mtb-dsl-pse8xxgp`. Only those drivers are needed; build them for the CM33 Secure core with `COMPONENT_CM33`, `CORE_NAME_CM33_0`, `COMPONENT_SECURE_DEVICE` and the part macro (for example `PSE846GPS2DBZC4A`).

The crypto engine reads memory over the system bus, so the port translates code-bus addresses, such as data in XIP flash, the way the PDL does. A bare-metal test and benchmark for KIT_PSE84_AI is in wolfssl-examples under `embedded/infineon_psoc_e8`.

---

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)
90 changes: 73 additions & 17 deletions wolfcrypt/src/port/cypress/psoc6_crypto.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,35 @@
#include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
#include <wolfssl/wolfcrypt/random.h>

#include "cy_crypto_common.h"
#include "cy_crypto_core_hw_v2.h"
#include "cy_crypto_core_mem.h"

/* The engine's FIFOs reach memory over the system bus, so a code-bus alias
* (such as XIP flash on PSOC Edge) is translated the way the PDL translates
* its own buffers. This is the identity on PSoC6. */
#if defined(CY_REMAP_ADDRESS_FOR_CRYPTO)
#define PSOC6_CRYPTO_REMAP(p) \
((const uint8_t*)CY_REMAP_ADDRESS_FOR_CRYPTO(p))
#else
#define PSOC6_CRYPTO_REMAP(p) ((const uint8_t*)(p))
#endif

/* With a data cache (CY_CRYPTO_DCACHE_ENABLED in the PDL), the FIFOs neither
* see CPU writes still in the cache nor update it: clean a buffer before the
* engine reads it and invalidate it before the CPU reads what the engine
* wrote. Done on the CPU address, the way the PDL wrappers do it. */
#if defined(CY_CRYPTO_DCACHE_ENABLED) && (CY_CRYPTO_DCACHE_ENABLED == 1)
#define PSOC6_CRYPTO_CLEAN(p, sz) CY_CRYPTO_CLEAN_DCACHE((p), (sz))
#define PSOC6_CRYPTO_INVALIDATE(p, sz) \
CY_CRYPTO_INVALIDATE_DCACHE((p), (sz))
#else
#define PSOC6_CRYPTO_CLEAN(p, sz) \
do { (void)(p); (void)(sz); } while (0)
#define PSOC6_CRYPTO_INVALIDATE(p, sz) \
do { (void)(p); (void)(sz); } while (0)
#endif

#ifdef HAVE_ECC
#include <wolfssl/wolfcrypt/ecc.h>
#endif /* HAVE_ECC */
Expand Down Expand Up @@ -832,9 +858,13 @@ int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l)
padChar = 0x01;
#endif

/* Apply padding */
/* The engine wrote the state; pad it on the CPU, then hand it back. */
PSOC6_CRYPTO_INVALIDATE(sha3_ctx->hash_state.hash,
CY_CRYPTO_SHA3_STATE_SIZE);
sha3_ctx->hash_state.hash[sha3_ctx->hash_state.blockIdx] ^= padChar;
sha3_ctx->hash_state.hash[rate - 1] ^= 0x80;
PSOC6_CRYPTO_CLEAN(sha3_ctx->hash_state.hash, CY_CRYPTO_SHA3_STATE_SIZE);
PSOC6_CRYPTO_CLEAN(hash, l);

/* Clear the register buffer */
Cy_Crypto_Core_V2_RBClear(crypto_base);
Expand All @@ -844,7 +874,7 @@ int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l)

/* 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,
PSOC6_CRYPTO_REMAP(sha3_ctx->sha_buffers.hash),
Comment thread
aidangarske marked this conversation as resolved.
CY_CRYPTO_SHA3_STATE_SIZE);

/* XOR data present in lower register buffer partition with data streamed
Expand Down Expand Up @@ -880,7 +910,7 @@ int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l)
/* 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_REMAP(hash + offset),
PSOC6_CRYPTO_SHA3_RB_LOWER);

/* Copy the data in register buffer lower partition into hash buffer
Expand All @@ -901,8 +931,8 @@ int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l)
/* 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,
PSOC6_CRYPTO_REMAP(hash + offset +
PSOC6_CRYPTO_SHA3_RB_LOWER),
(rate - PSOC6_CRYPTO_SHA3_RB_LOWER));

/* Copy the remaining data in register buffer lower partition into
Expand All @@ -920,7 +950,7 @@ int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l)
/* 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);
PSOC6_CRYPTO_REMAP(hash + offset), rate);

/* Copy the remaining data in register buffer lower partition into
* hash buffer */
Expand All @@ -947,7 +977,7 @@ int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l)
/* 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_REMAP(hash + offset),
PSOC6_CRYPTO_SHA3_RB_LOWER);

/* Copy the data in register buffer lower partition into hash buffer
Expand All @@ -969,7 +999,7 @@ int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l)
* 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,
PSOC6_CRYPTO_REMAP(hash + offset + PSOC6_CRYPTO_SHA3_RB_LOWER),
((l - offset) - PSOC6_CRYPTO_SHA3_RB_LOWER));

/* Copy the remaining data in register buffer lower partition into
Expand All @@ -984,7 +1014,8 @@ int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l)
/* 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);
PSOC6_CRYPTO_REMAP(hash + offset),
l - offset);

/* Copy the data in register buffer lower partition into hash buffer
*/
Expand All @@ -994,6 +1025,7 @@ int wc_Psoc6_Sha3_Final(void* sha3, byte padChar, byte* hash, byte p, word32 l)
Cy_Crypto_Core_V2_FFStoreSync(crypto_base);
}
}
PSOC6_CRYPTO_INVALIDATE(hash, l);

return 0;
}
Expand All @@ -1011,7 +1043,10 @@ 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)
{
wc_Shake* shake_ctx = (wc_Shake*)shake;
byte* start = out;
word32 outSz = blockCnt * shake_ctx->hash_state.blockSize;

PSOC6_CRYPTO_CLEAN(start, outSz);
for (; (blockCnt > 0); blockCnt--) {
/* Perform SHA3 on the current state */
Cy_Crypto_Core_V2_Run(crypto_base, shake_ctx->hash_state.modeHw);
Expand All @@ -1021,7 +1056,8 @@ int wc_Psoc6_Shake_SqueezeBlocks(void* shake, byte* out, word32 blockCnt)

/* 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,
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
PSOC6_CRYPTO_REMAP(out),
PSOC6_CRYPTO_SHA3_RB_LOWER);

/* Copy the data in register buffer lower partition into hash buffer */
Expand All @@ -1040,7 +1076,8 @@ int wc_Psoc6_Shake_SqueezeBlocks(void* shake, byte* out, word32 blockCnt)
/* 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,
PSOC6_CRYPTO_REMAP(out +
PSOC6_CRYPTO_SHA3_RB_LOWER),
shake_ctx->hash_state.blockSize -
PSOC6_CRYPTO_SHA3_RB_LOWER);

Expand All @@ -1059,6 +1096,7 @@ int wc_Psoc6_Shake_SqueezeBlocks(void* shake, byte* out, word32 blockCnt)
/* Move to the next block */
out += shake_ctx->hash_state.blockSize;
}
PSOC6_CRYPTO_INVALIDATE(start, outSz);

return 0;
}
Expand Down Expand Up @@ -1365,6 +1403,7 @@ int wc_Psoc6_Aes_EcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
word32 outSz = 0;

if (aes == NULL || in == NULL || out == NULL) {
return BAD_FUNC_ARG;
Expand Down Expand Up @@ -1392,8 +1431,13 @@ int wc_Psoc6_Aes_EcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)

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);
PSOC6_CRYPTO_CLEAN(in, sz);
PSOC6_CRYPTO_CLEAN(out, sz);
outSz = sz;
Cy_Crypto_Core_V2_FFContinue(crypto_base, CY_CRYPTO_V2_RB_FF_LOAD0,
PSOC6_CRYPTO_REMAP(in), sz);
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
PSOC6_CRYPTO_REMAP(out), sz);

for (; sz > 0; sz -= CY_CRYPTO_AES_BLOCK_SIZE) {
Cy_Crypto_Core_V2_BlockMov(crypto_base, CY_CRYPTO_V2_RB_BLOCK0,
Expand All @@ -1407,6 +1451,7 @@ int wc_Psoc6_Aes_EcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz)
}

Cy_Crypto_Core_WaitForReady(crypto_base);
PSOC6_CRYPTO_INVALIDATE(out, outSz);

cleanup:
if (aesInited) {
Expand Down Expand Up @@ -1440,6 +1485,7 @@ int wc_Psoc6_Aes_EcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
cy_en_crypto_status_t status;
cy_en_crypto_aes_key_length_t keyLength;
int aesInited = 0;
word32 outSz = 0;

if (aes == NULL || in == NULL || out == NULL) {
return BAD_FUNC_ARG;
Expand Down Expand Up @@ -1468,8 +1514,13 @@ int wc_Psoc6_Aes_EcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
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);
PSOC6_CRYPTO_CLEAN(in, sz);
PSOC6_CRYPTO_CLEAN(out, sz);
outSz = sz;
Cy_Crypto_Core_V2_FFContinue(crypto_base, CY_CRYPTO_V2_RB_FF_LOAD0,
PSOC6_CRYPTO_REMAP(in), sz);
Cy_Crypto_Core_V2_FFStart(crypto_base, CY_CRYPTO_V2_RB_FF_STORE,
PSOC6_CRYPTO_REMAP(out), sz);

for (; sz > 0; sz -= CY_CRYPTO_AES_BLOCK_SIZE) {
Cy_Crypto_Core_V2_BlockMov(crypto_base, CY_CRYPTO_V2_RB_BLOCK0,
Expand All @@ -1483,6 +1534,7 @@ int wc_Psoc6_Aes_EcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz)
}

Cy_Crypto_Core_WaitForReady(crypto_base);
PSOC6_CRYPTO_INVALIDATE(out, outSz);

cleanup:
if (aesInited) {
Expand Down Expand Up @@ -2043,6 +2095,10 @@ int wc_Psoc6_Aes_GcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
}

cleanup:
/* Never release plaintext that failed authentication. */
Comment thread
aidangarske marked this conversation as resolved.
if ((ret != 0) && (out != NULL) && (sz > 0)) {
ForceZero(out, sz);
}
if (aesInited) {
wc_Psoc6_Aes_Free(aes);
}
Expand All @@ -2056,7 +2112,7 @@ int wc_Psoc6_Aes_GcmDecrypt(Aes* aes, byte* out, const byte* in, word32 sz,
#endif /* PSOC6_CRYPTO_AES */

/* ECDSA */
#ifdef HAVE_ECC
#ifdef PSOC6_CRYPTO_ECC

#define MAX_ECC_KEYSIZE 66 /* Supports up to secp521r1 */
static cy_en_crypto_ecc_curve_id_t psoc6_get_curve_id(int size)
Expand Down Expand Up @@ -2209,6 +2265,6 @@ int psoc6_ecc_verify_hash_ex(MATH_INT_T* r, MATH_INT_T* s, const byte* hash,

return WC_FAILURE;
}
#endif /* HAVE_ECC */
#endif /* PSOC6_CRYPTO_ECC */

#endif /* WOLFSSL_PSOC6_CRYPTO */
5 changes: 5 additions & 0 deletions wolfcrypt/src/sha256.c
Original file line number Diff line number Diff line change
Expand Up @@ -3669,6 +3669,11 @@ int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
}
#endif

#if defined(PSOC6_HASH_SHA2)
if ((ret == 0) && (wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA256, 0) != 0))
ret = WC_HW_E;
#endif

return ret;
}
#endif
Expand Down
Loading
Loading