RA Flexible Software Package Documentation  Release v5.9.0

 
Secure Crypto Engine (r_sce_protected_cavp)

Driver for the CAVP Certified Secure Crypto Engine (SCE) on RA MCUs.

Version

v1.1.0

The version that appears on the Components tab of the FSP Configuration editor is v1.1.0+fsp.<fsp_version>. The <fsp_version> metadata reflects tooling support files only and does not indicate any changes to the CAVP certified code. See Module Versioning for more information about component versioning in FSP.

Functions

The user documentation for the functions in this module.

Overview

This module provides SCE CAVP Certified functions.

HW Overview

SCE9 Protected Mode CAVP certification has been obtained using the RA6M4 as the target processor.

Crypto Peripheral version Devices
SCE9 (Protected mode) RA4M2, RA4M3, RA6M4, RA6M5

Features

The SCE module supports for the following features.

Configuration

Clock Configuration

This module does not require a specific clock configuration.

Pin Configuration

This module does not use I/O pins.

Usage Notes

Getting Started: Creating a SCE Protected Mode Project

Start by creating a new project in e² studio or RASC. On the Stacks tab, add New > Security > SCE Protected Mode(CAVP Certified). For information on how to install and update secure keys, refer to the Application Note R11AN0496.

Reducing intialization time

The SCE intialization sequence can be modified to support a smaller subset of features and allow for a shorter intialization period. This is particularly useful in cases where startup time is important and the cryptographic features that are required are known in advance. The current fast boot configuration option supports the cryptographic primitives requried by MCUBoot including:

Limitations

Usage of R_SCE_ECDSA_secp384r1_SignatureGenerate/Verify

The SCE does not support SHA-384 in hardware, so the APIs listed below require the user to create a SHA-384 function for signature generation and verification. To use the APIs listed below, enable SCE_USER_SHA_384_ENABLED on RA Smart Configurator and prepare a function called SCE_USER_SHA_384_FUNCTION. The interface of SCE_USER_SHA_384_FUNCTION, which is called by the following APIs, is described below.

SCE_USER_SHA_384_FUNCTION()

uint32_t SCE_USER_SHA_384_FUNCTION(uint8_t * message, uint8_t * digest, uint32_t message_length)

SHA-384 hash calculation is performed for an area extending the number of bytes specified by the argument message_length from the address specified by the argument message. The calculation result should be stored at the address specified by the argument digest.

Parameters
message[in] Start address of message
digest[in,out] address for storing hash calculation result (48 bytes)
message_length[in] Effective byte count of message
Return values
0Hash value stored successfully.
othersStoring of hash value failed.

Examples

AES Example

This is an example of AES-256 encryption and decryption.

static uint8_t plain[BLOCK * 2] =
{
0x52, 0x65, 0x6e, 0x65, 0x73, 0x61, 0x73, 0x20, 0x45, 0x6c, 0x65, 0x63, 0x74, 0x72, 0x6f, 0x6e,
0x69, 0x63, 0x73, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x6f, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00
};
void r_sce_example_aes ()
{
sce_aes_wrapped_key_t wrapped_key;
uint8_t cipher_calculated[32] = {0};
uint8_t plain_calculated[32] = {0};
uint32_t dummy;
/* SCE power on */
R_SCE_Open(&sce_ctrl, &sce_cfg);
/* Generate a random key */
/* Encrypt a plain text */
R_SCE_AES256ECB_EncryptInit(&handle, &wrapped_key);
R_SCE_AES256ECB_EncryptUpdate(&handle, plain, cipher_calculated, BLOCK * 2);
R_SCE_AES256ECB_EncryptFinal(&handle, cipher_calculated, &dummy);
/* Decrypt a cipher text using same key as Encryption */
R_SCE_AES256ECB_DecryptInit(&handle, &wrapped_key);
R_SCE_AES256ECB_DecryptUpdate(&handle, cipher_calculated, plain_calculated, BLOCK * 2);
R_SCE_AES256ECB_DecryptFinal(&handle, plain_calculated, &dummy);
/* SCE power off */
R_SCE_Close(&sce_ctrl);
/* Compare plain and plain_calculated */
if (memcmp(plain, plain_calculated, BLOCK * 2))
{
while (1)
{
/* plain and plain_calculated are different (incorrect) */
}
}
else
{
while (1)
{
/* plain and plain_calculated are the same (correct) */
}
}
}

ECC Example

This is an example of ECC secp-256 signature generate and verify.

uint8_t ecc256_data_msg[] =
{
's', 'a', 'm', 'p', 'l', 'e'
};
void r_sce_example_ecc ()
{
sce_ecc_wrapped_pair_key_t wrapped_pair_key;
sce_ecdsa_byte_data_t message_hash =
{
0
};
uint8_t out_data[HW_SCE_ECDSA_DATA_BYTE_SIZE];
fsp_err_t return_code;
message_hash.data_length = sizeof(ecc256_data_msg);
message_hash.pdata = (uint8_t *) ecc256_data_msg;
signature.pdata = out_data;
/* SCE power on */
R_SCE_Open(&sce_ctrl, &sce_cfg);
/* Generate a random pair key */
/* Generate a Signature */
R_SCE_ECDSA_secp256r1_SignatureGenerate(&message_hash, &signature, &wrapped_pair_key.priv_key);
/* Verify Signature and Public wrapped key */
return_code = R_SCE_ECDSA_secp256r1_SignatureVerify(&signature, &message_hash, &wrapped_pair_key.pub_key);
/* SCE power off */
R_SCE_Close(&sce_ctrl);
if (FSP_SUCCESS != return_code)
{
while (1)
{
/* Verify Fail */
}
}
else
{
while (1)
{
/* Verify Success */
}
}
}

RSA Example

This is an example of RSA-2048 encryption and decryption.

uint8_t rsa_msg[256] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
};
void r_sce_example_rsa () {
uint8_t enc_cipher[HW_SCE_RSA_2048_DATA_BYTE_SIZE];
uint8_t dec_plain[HW_SCE_RSA_2048_DATA_BYTE_SIZE];
plain.data_length = sizeof(rsa_msg) - PADDING_MINIMUM_BYTE_SIZE;
plain.pdata = (uint8_t *) rsa_msg;
plain_dec.data_length = sizeof(dec_plain);
plain_dec.pdata = dec_plain;
cipher.data_length = sizeof(enc_cipher);
cipher.pdata = enc_cipher;
/* SCE power on */
R_SCE_Open(&sce_ctrl, &sce_cfg);
/* Generate a random key */
/* Encrypt a plain data */
R_SCE_RSAES_PKCS2048_Encrypt(&plain, &cipher, &wrapped_pair_key.pub_key);
/* Decrypt a plain data */
R_SCE_RSAES_PKCS2048_Decrypt(&cipher, &plain_dec, &wrapped_pair_key.priv_key);
/* SCE power off */
R_SCE_Close(&sce_ctrl);
/* Compare plain_dec and plain */
if (0 != memcmp(plain_dec.pdata, plain.pdata, plain_dec.data_length))
{
while (1)
{
/* plain_dec and plain are different (incorrect) */
}
}
else
{
while (1)
{
/* plain_dec and plain are the same (correct) */
}
}
}

HASH Example

This is an example of calculating the SHA256 hash.

uint8_t message[] =
{
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
};
uint8_t hash[] =
{
0x63, 0x0d, 0xcd, 0x29, 0x66, 0xc4, 0x33, 0x66, 0x91, 0x12, 0x54, 0x48, 0xbb, 0xb2, 0x5b, 0x4f,
0xf4, 0x12, 0xa4, 0x9c, 0x73, 0x2d, 0xb2, 0xc8, 0xab, 0xc1, 0xb8, 0x58, 0x1b, 0xd7, 0x10, 0xdd
};
void r_sce_example_hash ()
{
uint8_t digest[HW_SCE_SHA256_HASH_LENGTH_BYTE_SIZE] = {0};
uint32_t digest_length = 0;
/* SCE power on */
R_SCE_Open(&sce_ctrl, &sce_cfg);
/* Encrypt a message text */
R_SCE_SHA256_Update(&handle, &message, HW_SCE_SHA256_HASH_LENGTH_BYTE_SIZE);
R_SCE_SHA256_Final(&handle, &digest, &digest_length);
/* SCE power off */
R_SCE_Close(&sce_ctrl);
/* Compare digest and hash */
if (0 != memcmp(digest, hash, digest_length))
{
while (1)
{
/* digest and hash are different (incorrect) */
}
}
else
{
while (1)
{
/* digest and hash are the same (correct) */
}
}
}