PSOC E8XXGP Device Support Library

| PSOC E8XXGP Device Support Library

API Reference
Direct Crypto Core Access
PDL API Reference » Crypto (Cryptography)

## General Description

Use the low-level API for direct access to the Crypto hardware.

The functions and other declarations used in this part of the driver are in cy_crypto_core.h. You can also include cy_pdl.h to get access to all functions and declarations in the PDL.

Firmware initializes and starts the Crypto operations. The firmware then provides the configuration data required for the desired cryptographic technique.

# Common Use Cases

## Crypto Hardware Enable

Use Cy_Crypto_Core_Enable to enable the Crypto IP block, After this call, the Crypto driver is ready to execute crypto functions

Code example:

cy_en_crypto_status_t cryptoStatus;
/* Enable Crypto IP */
cryptoStatus = Cy_Crypto_Core_Enable(
CRYPTO_HW); /* Pointer to Crypto instance */
/* ... check for errors... */
cy_en_crypto_status_t
cy_en_crypto_status_t
Errors of the Crypto block.
Definition: cy_crypto_common.h:532
Cy_Crypto_Core_Enable
cy_en_crypto_status_t Cy_Crypto_Core_Enable(CRYPTO_Type *base)
The function to enable the Crypto hardware.
Definition: cy_crypto_core_hw.c:459

## Crypto Hardware Disable

Use Cy_Crypto_Core_Disable to disable the Crypto IP block and call Cy_Crypto_Core_ClearVuRegisters to clear whole register file, After this call, No crypto function should be executed

Code example:

/* Check if Crypto IP is enabled */
if (Cy_Crypto_Core_IsEnabled(CRYPTO_HW)) {
/* Disable Crypto HW */
Cy_Crypto_Core_Disable(CRYPTO_HW);
/* Clear whole register file */
Cy_Crypto_Core_ClearVuRegisters(CRYPTO_HW);
}
Cy_Crypto_Core_ClearVuRegisters
void Cy_Crypto_Core_ClearVuRegisters(CRYPTO_Type *base)
The function to initialize the Crypto VU registers.
Definition: cy_crypto_core_hw.c:178
Cy_Crypto_Core_Disable
cy_en_crypto_status_t Cy_Crypto_Core_Disable(CRYPTO_Type *base)
Disables the operation of the CRYPTO block.
Definition: cy_crypto_core_hw.c:551
Cy_Crypto_Core_IsEnabled
__STATIC_INLINE bool Cy_Crypto_Core_IsEnabled(CRYPTO_Type *base)
The function checks whether the Crypto hardware is enabled.
Definition: cy_crypto_core_hw.h:810

## TDES encryption

To encrypt a message using the TDES algorithm:

- Place three DES keys into an array,
- Call Cy_Crypto_Core_Tdes with required parameters, including the array of keys

Code example:

/* Note: all keys are placed into the one keys array. */
#define STRING_LENGTH 8
uint8_t msgString[STRING_LENGTH] = "Crypto!";
uint8_t encString[STRING_LENGTH];
#define KEY1 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
#define KEY2 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
#define KEY3 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
uint8_t tdesKey[] = { KEY1, KEY2, KEY3 };
cy_en_crypto_status_t cryptoStatus;
cryptoStatus = Cy_Crypto_Core_Tdes(
CRYPTO_HW,
CY_CRYPTO_ENCRYPT,
tdesKey, /* Pointer to keys */
encString, /* Destination string */
msgString); /* Source String */
/* ... check for errors... */
CY_CRYPTO_ENCRYPT
@ CY_CRYPTO_ENCRYPT
The forward mode, plain text will be encrypted into cipher text.
Definition: cy_crypto_common.h:484
Cy_Crypto_Core_Tdes
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Tdes(CRYPTO_Type *base, cy_en_crypto_dir_mode_t dirMode, uint8_t const *key, uint8_t *dst, uint8_t const *src)
Performs the TDES operation on a single block.
Definition: cy_crypto_core_des.h:144

## DES encryption

To encrypt a message using the DES algorithm:

- Place DES key into an array,
- Call Cy_Crypto_Core_Des with required parameters, including the key array

Code example:

/* Note: all keys are placed into the one keys array. */
#define STRING_LENGTH 8
uint8_t msgString[STRING_LENGTH] = "Crypto!";
uint8_t encString[STRING_LENGTH];
#define KEY1 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
uint8_t desKey[] = { KEY1 };
cy_en_crypto_status_t cryptoStatus;
cryptoStatus = Cy_Crypto_Core_Des(
CRYPTO_HW,
CY_CRYPTO_ENCRYPT,
desKey, /* Pointer to key */
encString, /* Destination string */
msgString); /* Source String */
/* ... check for errors... */
Cy_Crypto_Core_Des
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Des(CRYPTO_Type *base, cy_en_crypto_dir_mode_t dirMode, uint8_t const *key, uint8_t *dst, uint8_t const *src)
Performs the DES operation on a single block.
Definition: cy_crypto_core_des.h:89

## AES encryption

The Crypto driver provides a four AES encryption algorithms (ECB, CBC, CFB and CTR) that are used similarly.

To encrypt a message using AES ECB algorithm (as example):

- Place AES key into array of appropriate size
- Use Cy_Crypto_Core_Aes_Init to configure the operation
- Call Cy_Crypto_Core_Aes_Ecb (Cy_Crypto_Core_Aes_Cbc, Cy_Crypto_Core_Aes_Cfb or Cy_Crypto_Core_Aes_Ctr) with appropriate parameters to make an operation

Code example:

uint8_t aesKey[CY_CRYPTO_AES_128_KEY_SIZE] = {
0x2Bu, 0x7Eu, 0x15u, 0x16u, 0x28u, 0xAEu, 0xD2u, 0xA6u,
0xABu, 0xF7u, 0x15u, 0x88u, 0x09u, 0xCFu, 0x4Fu, 0x3Cu
};
uint8_t aesEcbPlainText[CY_CRYPTO_AES_BLOCK_SIZE] = {
0x6Bu, 0xC0u, 0xBCu, 0xE1u, 0x2Au, 0x45u, 0x99u, 0x91u,
0xE1u, 0x34u, 0x74u, 0x1Au, 0x7Fu, 0x9Eu, 0x19u, 0x25u
};
uint8_t aesEcbCipherText[CY_CRYPTO_AES_BLOCK_SIZE] = {0};
cy_stc_crypto_aes_state_t aesState;
cy_en_crypto_status_t cryptoStatus;
/* Initialize Crypto AES functionality */
cryptoStatus = Cy_Crypto_Core_Aes_Init(
CRYPTO_HW,
aesKey, /* Pointer to key */
CY_CRYPTO_KEY_AES_128, /* Key size */
&aesState); /* pointer to AES state structure */
/* ... check for errors... */
/* Encrypt one block (16 Bytes) by AES128 */
cryptoStatus = Cy_Crypto_Core_Aes_Ecb(
CRYPTO_HW,
CY_CRYPTO_ENCRYPT,
aesEcbCipherText, /* destination block */
aesEcbPlainText, /* source block */
&aesState);
/* ... check for errors... */
/* Clear AES operation context */
cryptoStatus = Cy_Crypto_Core_Aes_Free(
CRYPTO_HW,
&aesState);
/* ... check for errors... */
cy_stc_crypto_aes_state_t
Definition: cy_crypto_common.h:768
CY_CRYPTO_KEY_AES_128
@ CY_CRYPTO_KEY_AES_128
The AES key size is 128 bits.
Definition: cy_crypto_common.h:474
Cy_Crypto_Core_Aes_Ecb
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Aes_Ecb(CRYPTO_Type *base, cy_en_crypto_dir_mode_t dirMode, uint8_t *dst, uint8_t const *src, cy_stc_crypto_aes_state_t *aesState)
Performs the AES operation on a single block.
Definition: cy_crypto_core_aes.h:275
Cy_Crypto_Core_Aes_Free
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Aes_Free(CRYPTO_Type *base, cy_stc_crypto_aes_state_t *aesState)
Clears AES operation context.
Definition: cy_crypto_core_aes.h:223
Cy_Crypto_Core_Aes_Init
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Aes_Init(CRYPTO_Type *base, uint8_t const *key, cy_en_crypto_aes_key_length_t keyLength, cy_stc_crypto_aes_state_t *aesState)
Initializes AES mode of operation and prepares an inverse key.
Definition: cy_crypto_core_aes.h:124
CY_CRYPTO_AES_128_KEY_SIZE
#define CY_CRYPTO_AES_128_KEY_SIZE
Defines the Crypto AES_128 key maximum size (in bytes)
Definition: cy_crypto_common.h:139
CY_CRYPTO_AES_BLOCK_SIZE
#define CY_CRYPTO_AES_BLOCK_SIZE
Defines the Crypto AES block size (in bytes)
Definition: cy_crypto_common.h:136

## CRC Calculation

To calculate CRC of a data image:

- Use Cy_Crypto_Core_Crc_CalcInit to set parameters for selected CRC mode,
- Call Cy_Crypto_Core_Crc_Calc to calculate CRC for a data image.

Code example:

/* CRC parameters for some CRC algorithms:
+---------------------+-----+------------+------------+------+------+-----+------------+------------+
| CRC algorithm Name | CRC | Polynom | Initial | Data | Data | Rem | Remainder | Expected |
| | len | | seed | REV | XOR | REV | XOR | CRC |
| ------------------- | --- | ---------- |----------- | ---- | ---- | --- | ---------- | ---------- |
| CRC-6 / CDMA2000-A | 6 | 0x27 | 0x3F | 0 | 0 | 0 | 0x00 | 0x0D |
| CRC-6 / CDMA2000-B | 6 | 0x07 | 0x3F | 0 | 0 | 0 | 0x00 | 0x3B |
| CRC-6 / DARC | 6 | 0x19 | 0x00 | 1 | 0 | 1 | 0x00 | 0x26 |
| CRC-6 / ITU | 6 | 0x03 | 0x00 | 1 | 0 | 1 | 0x00 | 0x06 |
| CRC-8 / ITU | 8 | 0x07 | 0x00 | 0 | 0 | 0 | 0x55 | 0xA1 |
| CRC-8 / MAXIM | 8 | 0x31 | 0x00 | 1 | 0 | 1 | 0x00 | 0xA1 |
| CRC-8 / ROHC | 8 | 0x07 | 0xFF | 1 | 0 | 1 | 0x00 | 0xD0 |
| CRC-8 / WCDMA | 8 | 0x9B | 0x00 | 1 | 0 | 1 | 0x00 | 0x25 |
| CRC-16 / CCITT-0 | 16 | 0x1021 | 0xFFFF | 0 | 0 | 0 | 0x0000 | 0x29B1 |
| CRC-16 / CDMA2000 | 16 | 0xC867 | 0xFFFF | 0 | 0 | 0 | 0x0000 | 0x4C06 |
| CRC-32 | 32 | 0x04C11DB7 | 0xFFFFFFFF | 1 | 0 | 1 | 0xFFFFFFFF | 0xCBF43926 |
| CRC-32 / BZIP2 | 32 | 0x04C11DB7 | 0xFFFFFFFF | 0 | 0 | 0 | 0xFFFFFFFF | 0xFC891918 |
+---------------------+-----+------------+------------+------+------+-----+------------+------------+
*/
/* Use "CRC-16/CCITT-0" calculation */
#define CRC16CCITT_WIDTH (16u)
#define CRC16CCITT_POLYNOMIAL (0x1021)
#define CRC16CCITT_LFSR_SEED (0xffff)
#define CRC16CCITT_DATA_REVERSE (0u)
#define CRC16CCITT_DATA_XOR (0u)
#define CRC16CCITT_REM_REVERSE (0u)
#define CRC16CCITT_REM_XOR (0x0000)
uint8_t message[9] = "123456789";
uint32_t calculatedCrc = 0;
cy_en_crypto_status_t cryptoStatus;
/* Initialization Crypto operation */
cryptoStatus = Cy_Crypto_Core_Crc_CalcInit(
CRYPTO_HW,
CRC16CCITT_WIDTH,
CRC16CCITT_POLYNOMIAL,
CRC16CCITT_DATA_REVERSE,
CRC16CCITT_DATA_XOR,
CRC16CCITT_REM_REVERSE,
CRC16CCITT_REM_XOR,
CRC16CCITT_LFSR_SEED);
/* ... check for errors... */
/* Calculate CRC */
cryptoStatus = Cy_Crypto_Core_Crc_Calc(
CRYPTO_HW, /* Pointer to Crypto instance */
CRC16CCITT_WIDTH, /* CRC width in bits*/
&calculatedCrc, /* Pointer to CRC result */
(void*)message, /* Pointer to message */
sizeof(message)); /* Size of message */
/* ... check for errors... */
Cy_Crypto_Core_Crc_Calc
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Crc_Calc(CRYPTO_Type *base, uint32_t width, uint32_t *crc, void const *data, uint32_t dataSize)
Performs the CRC calculation on a message.
Definition: cy_crypto_core_crc.h:456
Cy_Crypto_Core_Crc_CalcInit
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Crc_CalcInit(CRYPTO_Type *base, uint32_t width, uint32_t polynomial, uint32_t dataReverse, uint32_t dataXor, uint32_t remReverse, uint32_t remXor, uint32_t lfsrInitState)
Initializes the CRC calculation.
Definition: cy_crypto_core_crc.h:280

## SHA digest calculation

To calculate a SHA digest of a message:

- Call Cy_Crypto_Core_Sha with appropriate parameters to make an operation

Code example:

uint8_t sha256PlainText[3] = "abc";
uint8_t sha256Digest[CY_CRYPTO_SHA256_DIGEST_SIZE] = {0};
cy_en_crypto_status_t cryptoStatus;
/* Hash the message by SHA256 */
cryptoStatus = Cy_Crypto_Core_Sha(
CRYPTO_HW, /* Pointer to Crypto instance */
sha256PlainText, /* Pointer to message */
sizeof(sha256PlainText), /* Message size */
sha256Digest, /* Pointer to digest buffer */
CY_CRYPTO_MODE_SHA256); /* Hash mode */
/* ... check for errors... */
CY_CRYPTO_MODE_SHA256
@ CY_CRYPTO_MODE_SHA256
Sets the SHA256 mode.
Definition: cy_crypto_common.h:499
Cy_Crypto_Core_Sha
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Sha(CRYPTO_Type *base, uint8_t const *message, uint32_t messageSize, uint8_t *digest, cy_en_crypto_sha_mode_t mode)
Performs the SHA Hash function.
Definition: cy_crypto_core_sha.h:85
CY_CRYPTO_SHA256_DIGEST_SIZE
#define CY_CRYPTO_SHA256_DIGEST_SIZE
Hash size for the SHA256 mode (in bytes)
Definition: cy_crypto_common.h:220

## RSA signature verification

To verify the RSA signature of the data image:

- Fill RSA public key structure by RSA public key data
- Use Cy_Crypto_Core_Sha to calculate SHA digest of the data image
- Use Cy_Crypto_Core_Rsa_Proc to decrypt present encrypted signature
- Use Cy_Crypto_Core_Rsa_Verify to verify the decrypted signature with calculated SHA digest

Code example:

#define RSA_MODULO_LENGTH 2048u
#define RSA_MODULO_DATA_SIZE (RSA_MODULO_LENGTH / 8)
typedef struct
{
cy_stc_crypto_rsa_pub_key_t publicKeyStruct;
uint8_t moduloData[RSA_MODULO_DATA_SIZE];
uint8_t expData [32];
uint8_t k1Data [RSA_MODULO_DATA_SIZE+4];
uint8_t k2Data [RSA_MODULO_DATA_SIZE];
uint8_t k3Data [RSA_MODULO_DATA_SIZE];
} cy_stc_public_key_t;
/* All data arrays should be 4-byte aligned */
cy_stc_public_key_t cy_publicKey =
{
.publicKeyStruct =
{
.moduloPtr = 0,
.moduloLength = RSA_MODULO_LENGTH,
.pubExpPtr = 0,
.pubExpLength = 24,
.barretCoefPtr = NULL,
.inverseModuloPtr = NULL,
.rBarPtr = NULL
},
.moduloData =
{ /* modulus in Little Endian for a public key - rsa_public.txt */
0xD9u, 0x94u, 0x94u, 0x38u, 0xA4u, 0xE0u, 0x50u, 0xA1u,
0xADu, 0xC5u, 0xE2u, 0x66u, 0xA9u, 0x7Fu, 0xE7u, 0xD7u,
0xA8u, 0x10u, 0x87u, 0x3Au, 0xBEu, 0xB3u, 0x0Eu, 0x6Au,
0xB2u, 0x8Bu, 0x2Eu, 0x8Du, 0xC2u, 0x45u, 0x41u, 0xA6u,
0xDBu, 0xEBu, 0x90u, 0x20u, 0x56u, 0xECu, 0xFDu, 0x8Cu,
0x23u, 0x09u, 0x13u, 0x5Du, 0x65u, 0xA2u, 0xADu, 0x9Du,
0x3Bu, 0xF2u, 0x5Bu, 0xF6u, 0xABu, 0x2Eu, 0xFEu, 0xF2u,
0x69u, 0x98u, 0x29u, 0x6Du, 0xD1u, 0x2Eu, 0x91u, 0x5Au,
0x65u, 0x83u, 0xF5u, 0x7Fu, 0x8Eu, 0x73u, 0xFFu, 0xA1u,
0x8Cu, 0x70u, 0x07u, 0xDFu, 0x4Du, 0xF4u, 0x79u, 0xB7u,
0x18u, 0xC1u, 0xA3u, 0x2Bu, 0x82u, 0x5Bu, 0x9Eu, 0xE2u,
0xF0u, 0xA0u, 0xB8u, 0xDAu, 0x19u, 0xADu, 0xBBu, 0x2Bu,
0xD5u, 0x07u, 0x5Au, 0x85u, 0x12u, 0x03u, 0xD8u, 0x60u,
0x53u, 0x3Du, 0xC6u, 0x34u, 0xE2u, 0x7Fu, 0x96u, 0x4Cu,
0x26u, 0x1Eu, 0x82u, 0xB1u, 0x85u, 0xC3u, 0x0Du, 0x54u,
0x68u, 0x37u, 0x97u, 0x58u, 0x19u, 0x36u, 0x43u, 0x9Cu,
0xD9u, 0xC3u, 0x42u, 0xEBu, 0xBEu, 0xE2u, 0x8Fu, 0x72u,
0xF1u, 0x5Eu, 0x2Au, 0x15u, 0x56u, 0x52u, 0xD4u, 0x6Du,
0x61u, 0x97u, 0x16u, 0xFEu, 0xC3u, 0xF9u, 0x17u, 0x3Cu,
0x37u, 0xD5u, 0xE1u, 0xA1u, 0x0Au, 0xB7u, 0xD9u, 0x65u,
0xA1u, 0x15u, 0xECu, 0xC7u, 0x39u, 0xECu, 0xEDu, 0x39u,
0x98u, 0x96u, 0x66u, 0x50u, 0x8Cu, 0x25u, 0xC3u, 0x29u,
0xB9u, 0xF8u, 0x25u, 0x55u, 0x92u, 0x7Au, 0xBFu, 0xFBu,
0x45u, 0x2Au, 0x28u, 0x8Au, 0xF9u, 0xE5u, 0xE2u, 0x30u,
0x72u, 0x0Eu, 0x0Au, 0x1Cu, 0x25u, 0x09u, 0x86u, 0x6Fu,
0xF6u, 0x6Fu, 0x15u, 0xEDu, 0x14u, 0xE6u, 0x1Eu, 0x53u,
0x5Au, 0x15u, 0x25u, 0xB9u, 0x5Eu, 0xC9u, 0xBAu, 0x48u,
0xA3u, 0xE3u, 0x93u, 0x62u, 0x3Cu, 0x6Cu, 0x3Cu, 0x83u,
0x17u, 0x29u, 0xFBu, 0xAEu, 0x91u, 0x47u, 0xC9u, 0x41u,
0x2Fu, 0xF9u, 0x82u, 0x29u, 0x7Bu, 0xB4u, 0x5Au, 0x93u,
0x01u, 0x95u, 0xDBu, 0x08u, 0x7Eu, 0x7Bu, 0x99u, 0x1Eu,
0xD4u, 0x25u, 0xD3u, 0x2Au, 0xF4u, 0xC7u, 0x9Fu, 0xB3u,
},
/* Little endian exponent for a public key - rsa_public.txt */
.expData = { 0x01, 0x00, 0x01 },
.k1Data = { 0, },
.k2Data = { 0, },
.k3Data = { 0, },
};
/* Present encrypted signature of the image */
uint8_t rsaEncryptedSign[RSA_MODULO_DATA_SIZE] =
{
0x12u, 0xCEu, 0x13u, 0x83u, 0x4Fu, 0xFFu, 0x39u, 0x9Bu,
0x33u, 0xDEu, 0xDCu, 0xDBu, 0x7Cu, 0x62u, 0xA5u, 0x10u,
0x24u, 0x07u, 0xEAu, 0x4Cu, 0x04u, 0x4Au, 0xCEu, 0x7Bu,
0x8Cu, 0xD8u, 0xD4u, 0x64u, 0xD1u, 0x98u, 0xA2u, 0x33u,
0x2Eu, 0xFFu, 0x06u, 0x13u, 0xD6u, 0x5Au, 0x50u, 0x3Cu,
0xA2u, 0x5Eu, 0xE3u, 0x11u, 0x54u, 0x7Cu, 0x6Au, 0x49u,
0x39u, 0xA3u, 0x62u, 0x02u, 0x66u, 0xB0u, 0x19u, 0x82u,
0xFBu, 0x5Du, 0x15u, 0xB2u, 0x0Bu, 0xF7u, 0xECu, 0x6Cu,
0xBEu, 0xEBu, 0x04u, 0x1Fu, 0x0Bu, 0x5Bu, 0x18u, 0x0Eu,
0x96u, 0x03u, 0xC4u, 0x1Eu, 0x56u, 0xB6u, 0x1Fu, 0xF2u,
0x08u, 0x7Au, 0x81u, 0x96u, 0x86u, 0xA4u, 0x93u, 0x5Du,
0x66u, 0x63u, 0x10u, 0xD5u, 0x9Bu, 0xA9u, 0xD7u, 0x52u,
0xCDu, 0xEFu, 0x23u, 0xDCu, 0x58u, 0xC7u, 0x3Du, 0x72u,
0x3Fu, 0x09u, 0x5Eu, 0x3Bu, 0x03u, 0xF9u, 0x91u, 0x10u,
0x63u, 0x2Au, 0x56u, 0xFAu, 0xCEu, 0x8Cu, 0x8Au, 0xBFu,
0xB5u, 0xA1u, 0xA7u, 0x0Fu, 0xBBu, 0xD8u, 0xACu, 0x7Fu,
0x43u, 0x3Cu, 0xBFu, 0x11u, 0xD8u, 0xAEu, 0x55u, 0xE7u,
0x23u, 0xF8u, 0xA4u, 0xE0u, 0x56u, 0xCFu, 0x3Fu, 0x21u,
0xA9u, 0xB6u, 0x01u, 0x34u, 0xDFu, 0xB6u, 0xDCu, 0xAAu,
0x29u, 0xB0u, 0x97u, 0x9Du, 0xD9u, 0xAAu, 0x47u, 0xD4u,
0xD9u, 0x4Au, 0x97u, 0x52u, 0x3Cu, 0xB9u, 0x36u, 0xDAu,
0xF6u, 0xA6u, 0x14u, 0x97u, 0xDEu, 0xE6u, 0x76u, 0xBFu,
0x1Bu, 0x23u, 0xDBu, 0x68u, 0x66u, 0xEAu, 0x0Eu, 0xC6u,
0xD3u, 0x52u, 0x05u, 0x86u, 0x26u, 0x04u, 0x31u, 0xCEu,
0xCFu, 0x8Du, 0x13u, 0x84u, 0x81u, 0xF2u, 0x7Bu, 0xB7u,
0xDCu, 0x93u, 0x23u, 0x93u, 0xD1u, 0x0Cu, 0xF4u, 0xDFu,
0x37u, 0x44u, 0x3Du, 0xD7u, 0xAFu, 0xBFu, 0xAFu, 0x32u,
0xE7u, 0x31u, 0x50u, 0x70u, 0x62u, 0xC3u, 0xABu, 0x31u,
0x51u, 0x28u, 0x2Bu, 0x0Bu, 0x31u, 0xC6u, 0xD3u, 0x0Fu,
0x74u, 0xE6u, 0x31u, 0x21u, 0xF0u, 0xA3u, 0x40u, 0x5Du,
0xEDu, 0xFFu, 0xC9u, 0xEBu, 0x5Au, 0x65u, 0xF3u, 0xCBu,
0x67u, 0x50u, 0x62u, 0x2Du, 0x8Au, 0xEAu, 0xC3u, 0xBDu,
};
/* Previously calculated SHA-256 digest of the image */
uint8_t sha256Digest[CY_CRYPTO_SHA256_DIGEST_SIZE] =
{
0xf4u, 0xcbu, 0x29u, 0x53u, 0xadu, 0xc2u, 0xbdu, 0x49u,
0x6bu, 0x43u, 0x28u, 0x2bu, 0x63u, 0xb7u, 0x0du, 0x16u,
0xa9u, 0xd4u, 0x90u, 0x65u, 0x6eu, 0x7bu, 0x6du, 0xb7u,
0x0bu, 0x17u, 0xefu, 0x60u, 0x02u, 0x12u, 0x0fu, 0x90u
};
/* Temporary decryption buffer */
uint8_t rsaOutput[RSA_MODULO_DATA_SIZE];
cy_en_crypto_rsa_ver_result_t verResult;
cy_en_crypto_status_t cryptoStatus;
cy_publicKey.publicKeyStruct.moduloPtr = cy_publicKey.moduloData;
cy_publicKey.publicKeyStruct.pubExpPtr = cy_publicKey.expData;
/* Reverse the signature generated by openssl, CRYPTO IP is Little-Endian */
Cy_Crypto_Core_InvertEndianness(rsaEncryptedSign, RSA_MODULO_DATA_SIZE);
cryptoStatus = Cy_Crypto_Core_Rsa_Proc(
CRYPTO_HW, /* Pointer to Crypto instance */
&cy_publicKey.publicKeyStruct, /* Pointer to key */
rsaEncryptedSign, /* Pointer to signature */
sizeof(rsaEncryptedSign), /* size of signature */
rsaOutput); /* Pointer to decrypted signature */
/* ... check for errors... */
/* Reverse the decrypted signature */
Cy_Crypto_Core_InvertEndianness(rsaOutput, RSA_MODULO_DATA_SIZE);
/* Verify decrypted signature by calculated SHA digest from data image */
cryptoStatus = Cy_Crypto_Core_Rsa_Verify(
CRYPTO_HW,
&verResult, /* Pointer to verification result */
CY_CRYPTO_MODE_SHA256, /* Hash mode */
sha256Digest, /* Pointer to hash digest of image */
rsaOutput, /* Pointer to decrypted signature */
sizeof(rsaOutput)); /* Size of signature */
/* ... check for errors... */
if (CY_CRYPTO_RSA_VERIFY_SUCCESS == verResult)
{
/* Verification OK */
}
else
{
/* Verification FAILED */
}
cy_stc_crypto_rsa_pub_key_t
All fields for the context structure are internal.
Definition: cy_crypto_common.h:323
cy_en_crypto_rsa_ver_result_t
cy_en_crypto_rsa_ver_result_t
Signature verification status.
Definition: cy_crypto_common.h:524
CY_CRYPTO_RSA_VERIFY_SUCCESS
@ CY_CRYPTO_RSA_VERIFY_SUCCESS
PKCS1-v1.5 verify SUCCESS.
Definition: cy_crypto_common.h:525
Cy_Crypto_Core_Rsa_Proc
cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Proc(CRYPTO_Type *base, cy_stc_crypto_rsa_pub_key_t const *key, uint8_t const *message, uint32_t messageSize, uint8_t *processedMessage)
RSA process algorithm based on the Montgomery algorithm using Barrett reduction.
Definition: cy_crypto_core_rsa.c:1219
Cy_Crypto_Core_Rsa_Verify
cy_en_crypto_status_t Cy_Crypto_Core_Rsa_Verify(CRYPTO_Type *base, cy_en_crypto_rsa_ver_result_t *verResult, cy_en_crypto_sha_mode_t digestType, uint8_t const *digest, uint8_t const *decryptedSignature, uint32_t decryptedSignatureLength)
RSA verification with checks for content, paddings and signature format.
Definition: cy_crypto_core_rsa.c:171
Cy_Crypto_Core_InvertEndianness
void Cy_Crypto_Core_InvertEndianness(void *inArrPtr, uint32_t byteSize)
This function reverts byte-array memory block, like: inArr[0] <—> inArr[n] inArr[1] <—> inArr[n-1] ...
Definition: cy_crypto_core_hw.c:728

# RSA Usage Considerations

General RSA encryption and decryption is supported. Cy_Crypto_Core_Rsa_Proc encrypts or decrypts data based on the parameters passed to the function. If you pass in plain text and a public key, the output is encrypted (cipher text). If you pass in cipher text and a private key, the output is decrypted (plain text).

One parameter for this function call is a structure that defines the key: cy_stc_crypto_rsa_pub_key_t. The four modulus and exponent fields are mandatory. They represent the data for either the public or private key as appropriate.

Note
  The modulus and exponent values in the cy_stc_crypto_rsa_pub_key_t must be in little-endian order.
  Use the Cy_Crypto_Core_InvertEndianness function to convert to or from little-endian order.

The remaining fields represent three pre-calculated coefficients that can reduce execution time by up to 5x. The fields are: coefficient for Barrett reduction, binary inverse of the modulus, and the result of (2^moduloLength mod modulo). These fields are optional, and can be set to NULL.

Calculate these coefficients with Cy_Crypto_Core_Rsa_Coef. Pass them in the address of the key structure with the modulus and exponent values for the key. The function returns the coefficients for the key in the key structure, replacing any previous values.

The RSA functionality also implements functions to decrypt a signature using a public key. This signature must follow the RSASSA-PKCS-v1_5 standard. The signature must contain a SHA digest (hash). MD2, MD4, and MD5 message digests are not supported.

An encrypted signature is stored as big-endian data. It must be inverted for RSA processing. To use the provided signature decryption, firmware must

1. Calculate the SHA digest of the data to be verified with Cy_Crypto_Core_Sha.
2. Ensure that the RSA signature is in little-endian format. Use Cy_Crypto_Core_InvertEndianness.
3. Decrypt the RSA signature with a public key, by calling Cy_Crypto_Core_Rsa_Proc.
4. Invert the byte order of the output, to return to big-endian format. Use Cy_Crypto_Core_InvertEndianness.
5. Call Cy_Crypto_Core_Rsa_Verify (which requires data in big-endian format).

## CMAC calculation

To calculate CMAC of a message:

- Place AES key into array of appropriate size
- Call Cy_Crypto_Core_Cmac with appropriate parameters to make an operation

Code example:

uint8_t cmacKey[CY_CRYPTO_AES_256_KEY_SIZE] =
{
0x60u, 0x3Du, 0xEBu, 0x10u, 0x15u, 0xCAu, 0x71u, 0xBEu,
0x2Bu, 0x73u, 0xAEu, 0xF0u, 0x85u, 0x7Du, 0x77u, 0x81u,
0x1Fu, 0x35u, 0x2Cu, 0x07u, 0x3Bu, 0x61u, 0x08u, 0xD7u,
0x2Du, 0x98u, 0x10u, 0xA3u, 0x09u, 0x14u, 0xDFu, 0xF4u
};
uint8_t cmac256PlainText[16] =
{
0x6Bu, 0xC1u, 0xBEu, 0xE2u, 0x2Eu, 0x40u, 0x9Fu, 0x96u,
0xE9u, 0x3Du, 0x7Eu, 0x11u, 0x73u, 0x93u, 0x17u, 0x2Au
};
/* Calculated CMAC */
uint8_t cmac[CY_CRYPTO_AES_BLOCK_SIZE] = {0};
cy_en_crypto_status_t cryptoStatus;
cy_stc_crypto_aes_state_t aesState;
/* CMAC from the text message using AES-256 */
cryptoStatus = Cy_Crypto_Core_Cmac(
CRYPTO_HW, /* Pointer to Crypto instance */
cmac256PlainText, /* Pointer to plain text */
sizeof(cmac256PlainText), /* Size of plain text */
cmacKey, /* Pointer to encryption key */
CY_CRYPTO_KEY_AES_256, /* Size of encryption key */
cmac, /* Pointer to calculated CMAC */
&aesState); /* Pointer to AES state structure */
/* ... check for errors... */
CY_CRYPTO_KEY_AES_256
@ CY_CRYPTO_KEY_AES_256
The AES key size is 256 bits.
Definition: cy_crypto_common.h:476
Cy_Crypto_Core_Cmac
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Cmac(CRYPTO_Type *base, uint8_t const *message, uint32_t messageSize, uint8_t const *key, cy_en_crypto_aes_key_length_t keyLength, uint8_t *cmac, cy_stc_crypto_aes_state_t *aesState)
Calculates the AES Cipher-based Message Authentication Code (CMAC) on the input message with the prov...
Definition: cy_crypto_core_cmac.h:99
CY_CRYPTO_AES_256_KEY_SIZE
#define CY_CRYPTO_AES_256_KEY_SIZE
Defines the Crypto AES_256 key maximum size (in bytes)
Definition: cy_crypto_common.h:145

## HMAC calculation

To calculate HMAC of a message:

- Place HMAC key into array of appropriate size
- Call Cy_Crypto_Core_Hmac with appropriate parameters to make an operation

Code example:

uint8_t hmac256Key[CY_CRYPTO_AES_256_KEY_SIZE] =
{
0x00u, 0x01u, 0x02u, 0x03u, 0x04u, 0x05u, 0x06u, 0x07u,
0x08u, 0x09u, 0x0Au, 0x0Bu, 0x0Cu, 0x0Du, 0x0Eu, 0x0Fu,
0x10u, 0x11u, 0x12u, 0x13u, 0x14u, 0x15u, 0x16u, 0x17u,
0x18u, 0x19u, 0x1Au, 0x1Bu, 0x1Cu, 0x1Du, 0x1Eu, 0x1Fu
};
uint8_t hmac256PlainText[34] =
{
0x53u, 0x61u,
0x6Du, 0x70u, 0x6Cu, 0x65u, 0x20u, 0x6Du, 0x65u, 0x73u,
0x73u, 0x61u, 0x67u, 0x65u, 0x20u, 0x66u, 0x6Fu, 0x72u,
0x20u, 0x6Bu, 0x65u, 0x79u, 0x6Cu, 0x65u, 0x6Eu, 0x3Cu,
0x62u, 0x6Cu, 0x6Fu, 0x63u, 0x6Bu, 0x6Cu, 0x65u, 0x6Eu
};
/* Calculated HMAC */
uint8_t hmac256[CY_CRYPTO_SHA256_DIGEST_SIZE] = {0};
cy_en_crypto_status_t cryptoStatus;
/* HMAC from the text message using SHA256 */
cryptoStatus = Cy_Crypto_Core_Hmac(
CRYPTO_HW, /* Pointer to Crypto instance */
hmac256, /* Pointer to calculated HMAC */
hmac256PlainText, /* Pointer to plain text */
sizeof(hmac256PlainText), /* Size of plain text */
hmac256Key, /* Pointer to encryption key */
sizeof(hmac256Key), /* Size of encryption key */
CY_CRYPTO_MODE_SHA256); /* SHA method */
/* ... check for errors... */
Cy_Crypto_Core_Hmac
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Hmac(CRYPTO_Type *base, uint8_t *hmac, uint8_t const *message, uint32_t messageSize, uint8_t const *key, uint32_t keyLength, cy_en_crypto_sha_mode_t mode)
Performs the HMAC calculation.
Definition: cy_crypto_core_hmac.h:94

## Pseudo Random Number Generation

To generate a pseudo random number:

- Use Cy_Crypto_Core_Prng_Init to set required parameters,
- Call Cy_Crypto_Core_Prng.

Code example:

/* Initialization seed values for Pseudo Random Generator */
#define LFSR32_INITSTATE (0xd8959bc9)
#define LFSR31_INITSTATE (0x2bb911f8)
#define LFSR29_INITSTATE (0x060c31b7)
#define MAX_PRNG_VALUE (255UL)
/* Generated Random Number */
uint32_t rndNum = 0;
cy_en_crypto_status_t cryptoStatus;
/* Initialize Pseudo Random Generator */
cryptoStatus = Cy_Crypto_Core_Prng_Init(
CRYPTO_HW, /* Pointer to Crypto instance */
LFSR32_INITSTATE, /* Seed value for first LFSR */
LFSR31_INITSTATE, /* Seed value for second LFSR */
LFSR29_INITSTATE); /* Seed value for third LFSR */
/* ... check for errors... */
/* Generate a Pseudo Random number in specified range */
cryptoStatus = Cy_Crypto_Core_Prng(
CRYPTO_HW,
MAX_PRNG_VALUE, /* Range of random number */
&rndNum); /* Pointer to generated random number */
/* ... check for errors... */
Cy_Crypto_Core_Prng_Init
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Prng_Init(CRYPTO_Type *base, uint32_t lfsr32InitState, uint32_t lfsr31InitState, uint32_t lfsr29InitState)
Initializes the PRND parameters.
Definition: cy_crypto_core_prng.h:87
Cy_Crypto_Core_Prng
__STATIC_INLINE cy_en_crypto_status_t Cy_Crypto_Core_Prng(CRYPTO_Type *base, uint32_t max, uint32_t *randomNum)
Generates a Pseudo Random Number.
Definition: cy_crypto_core_prng.h:132

## True Random Number Generation

To generate a true random number:

- Call Cy_Crypto_Core_Trng with needed parameters.

Code example:

/* Initialization polynomial values for True Random Generator.
Polynomial for programmable Galois ring oscillator.
The polynomial is represented WITHOUT the high order bit (this bit is always assumed '1').
GARO 31 bit polynomial (0x04c1:1db7) = x31 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
Polynomial for programmable Fibonacci ring oscillator.
The polynomial is represented WITHOUT the high order bit (this bit is always assumed '1').
FIRO 31 bit polynomial (0x04c1:1db7) = x31 + x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x + 1
*/
#define GARO31_INITSTATE (0x04c11db7)
#define FIRO31_INITSTATE (0x04c11db7)
#define MAX_TRNG_BIT_SIZE (32UL)
/* Generated Random Number */
uint32_t rndNum = 0;
cy_en_crypto_status_t cryptoStatus;
/* Generate True Random number in a specified range */
cryptoStatus = Cy_Crypto_Core_Trng(
CRYPTO_HW, /* Pointer to Crypto instance */
GARO31_INITSTATE, /* Polynomial for programmable GARO */
FIRO31_INITSTATE, /* Polynomial for programmable FIRO */
MAX_TRNG_BIT_SIZE, /* Range of random number */
&rndNum); /* Pointer to generated random number */
/* ... check for errors... */
Cy_Crypto_Core_Trng
cy_en_crypto_status_t Cy_Crypto_Core_Trng(CRYPTO_Type *base, uint32_t GAROPol, uint32_t FIROPol, uint32_t max, uint32_t *randomNum)
Generates a True Random Number.
Definition: cy_crypto_core_trng.c:283

## API Reference
| Control and Status
| Symmetric Key Algorithms (AES, GCM, DES, TDES)
| Asymmetric Key Algorithms (RSA, ECP, ECDSA, EDDSA)
| Hash Operations (SHA)
| Message Authentication Code (CMAC, HMAC)
| Key Derivative Function (HKDF)
| Cyclic Redundancy Code (CRC)
| Random Number Generation (TRNG, PRNG)
| Vector Unit (VU)
| Memory Streaming Functions