MTB CAT1 Peripheral driver library
Direct Crypto Core Access

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... */

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 */
/* Clear whole register file */
}

TDES encryption

To encrypt a message using the TDES algorithm:

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,
tdesKey, /* Pointer to keys */
encString, /* Destination string */
msgString); /* Source String */
/* ... check for errors... */

DES encryption

To encrypt a message using the DES algorithm:

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,
desKey, /* Pointer to key */
encString, /* Destination string */
msgString); /* Source String */
/* ... check for errors... */

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):

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_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,
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... */

CRC Calculation

To calculate CRC of 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 */
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... */

SHA digest calculation

To calculate a SHA digest of a message:

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... */

RSA signature verification

To verify the RSA signature of the data image:

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_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 */
}

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:

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;
/* 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... */

HMAC calculation

To calculate HMAC of a message:

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... */

Pseudo Random Number Generation

To generate a pseudo random number:

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... */

True Random Number Generation

To generate a true random number:

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... */

API Reference

 Control and Status
 
 Symmetric Key Algorithms (AES, GCM, DES, TDES)
 
 Asymmetric Key Algorithms (RSA, ECP, ECDSA)
 
 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