From 491e67a478a5c1019026305ff53f4cbbdf4e6702 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 10 Sep 2024 23:26:41 +0500 Subject: [PATCH 01/58] PUFcc Support in Zephyr --- .../rapidsilicon/virgo_proto/virgo_proto.dts | 5 + drivers/crypto/CMakeLists.txt | 1 + drivers/crypto/Kconfig | 1 + drivers/crypto/Kconfig.pufs | 11 + drivers/crypto/crypto_pufs.c | 1314 +++++++++++++++++ drivers/crypto/crypto_pufs.h | 779 ++++++++++ dts/riscv/rapidsilicon/rapidsi_virgo.dtsi | 2 +- 7 files changed, 2112 insertions(+), 1 deletion(-) create mode 100644 drivers/crypto/Kconfig.pufs create mode 100644 drivers/crypto/crypto_pufs.c create mode 100644 drivers/crypto/crypto_pufs.h diff --git a/boards/rapidsilicon/virgo_proto/virgo_proto.dts b/boards/rapidsilicon/virgo_proto/virgo_proto.dts index a116964a01762..0943a164c1c69 100644 --- a/boards/rapidsilicon/virgo_proto/virgo_proto.dts +++ b/boards/rapidsilicon/virgo_proto/virgo_proto.dts @@ -7,6 +7,7 @@ /dts-v1/; #include + / { model = "Rapid Silicon Virgo Proto"; @@ -50,6 +51,10 @@ status = "okay"; }; + &pufs { + status = "okay"; + }; + &spi0 { status = "okay"; clock-frequency = <26666667>; diff --git a/drivers/crypto/CMakeLists.txt b/drivers/crypto/CMakeLists.txt index 68b63aef6ee9a..222bf000875ab 100644 --- a/drivers/crypto/CMakeLists.txt +++ b/drivers/crypto/CMakeLists.txt @@ -12,4 +12,5 @@ zephyr_library_sources_ifdef(CONFIG_CRYPTO_NPCX_SHA crypto_npcx_sha.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCHP_XEC_SYMCR crypto_mchp_xec_symcr.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_IT8XXX2_SHA crypto_it8xxx2_sha.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCUX_DCP crypto_mcux_dcp.c) +zephyr_library_sources_ifdef(CONFIG_CRYPTO_PUF_SECURITY crypto_pufs.c) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 5342441038e66..24dd8a23c4f37 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -77,6 +77,7 @@ source "drivers/crypto/Kconfig.stm32" source "drivers/crypto/Kconfig.nrf_ecb" source "drivers/crypto/Kconfig.intel" source "drivers/crypto/Kconfig.npcx" +source "drivers/crypto/Kconfig.pufs" source "drivers/crypto/Kconfig.xec" source "drivers/crypto/Kconfig.it8xxx2" source "drivers/crypto/Kconfig.mcux_dcp" diff --git a/drivers/crypto/Kconfig.pufs b/drivers/crypto/Kconfig.pufs new file mode 100644 index 0000000000000..834a25989e782 --- /dev/null +++ b/drivers/crypto/Kconfig.pufs @@ -0,0 +1,11 @@ +# PUF Security Cryptographic Accelerator configuration options + +# Copyright (c) 2024 Muhammad Junaid Aslam +# SPDX-License-Identifier: Apache-2.0 + +menuconfig CRYPTO_PUF_SECURITY + bool "PUF security Cryptographic Accelerator driver" + default y + depends on DT_HAS_PUFSECURITY_PUFCC_ENABLED + help + Enable PUF Security based Cryptographic Accelerator driver. diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c new file mode 100644 index 0000000000000..ffb300407388d --- /dev/null +++ b/drivers/crypto/crypto_pufs.c @@ -0,0 +1,1314 @@ +#include "crypto_pufs.h" + +#include + +#include +#include +#include + +#define LOG_LEVEL CONFIG_CRYPTO_LOG_LEVEL +#include +LOG_MODULE_REGISTER(crypto_puf_security); + +#if DT_HAS_COMPAT_STATUS_OKAY(pufsecurity_pufcc) + #define DT_DRV_COMPAT pufsecurity_pufcc +#else + #error No PUF Security HW Crypto Accelerator in device tree +#endif + +/***************************************************************************** + * Macros + ****************************************************************************/ +#define SG_DMA_MAX_DSCS_SIZE (512 - 8) // Enough for 15 descriptors +#define BUFFER_SIZE 512 +#define PUFCC_MAX_BUSY_COUNT 8000000 // Max busy count for processing 10MB data +#define CTR_MODE_BLOCK_SIZE 16 + +/***************************************************************************** + * Local variable declarations + ****************************************************************************/ +uint8_t __pufcc_descriptors[BUFFER_SIZE]; +static struct pufcc_sg_dma_desc *sg_dma_descs = + (struct pufcc_sg_dma_desc *)&__pufcc_descriptors; +static uint8_t pufcc_buffer[BUFFER_SIZE]; + +// PUFcc microprogram for RSA2048 +static uint32_t rsa_2048_mprog[] = { + 0x33cdac81, 0x6817434e, 0x4283ad5d, 0x27499978, 0x8a000040, 0x0a1080c0, + 0xc3800b00, 0x081810c6, 0xfc000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}; + +// PUFcc microprogram for ECDSA256 +static uint32_t p256_ecdsa_mprog[] = { + 0xb1703302, 0x0f91d3f8, 0x004ae67d, 0x8f7093c5, 0x8a000068, 0x0a014088, + 0xc3000000, 0xa0624000, 0x43000100, 0x20824000, 0x0a014090, 0xc3000000, + 0x20624800, 0x43000100, 0xa0824800, 0x0a014090, 0xc3000600, 0x8900101e, + 0x8e000028, 0x8a000068, 0x8a014800, 0x8a028070, 0x43000400, 0x0901101e, + 0x8e000028, 0x8a000068, 0x8a014800, 0x0a028088, 0x43000400, 0x0902101e, + 0x8e000048, 0x8a028058, 0x0a03c060, 0x92050020, 0x8a064808, 0x41801600, + 0x8900101e, 0x09011028, 0x8e000048, 0x0a028078, 0x8a03c080, 0x92050020, + 0x8a064810, 0x41801600, 0x0902101e, 0x89031028, 0x8e000048, 0x8a028800, + 0x0a03c808, 0x0a050810, 0x0a064818, 0xc1000700, 0x20a25000, 0x8900101e, + 0x8e000028, 0x8a000068, 0x8a014800, 0x43000200, 0x8900101e, 0x1c110800, + 0x18025800, 0xfc000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}; + +// EC NIST-P256 parameters +struct pufcc_ecc_param ecc_param_nistp256 = { + "\xff\xff\xff\xff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff", // prime + "\xff\xff\xff\xff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xfc", // a + "\x5a\xc6\x35\xd8\xaa\x3a\x93\xe7\xb3\xeb\xbd\x55\x76\x98\x86" + "\xbc\x65\x1d\x06\xb0\xcc\x53\xb0\xf6\x3b\xce\x3c\x3e\x27\xd2" + "\x60\x4b", // b + "\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" + "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98" + "\xc2\x96", // px + "\x4f\xe3\x42\xe2\xfe\x1a\x7f\x9b\x8e\xe7\xeb\x4a\x7c\x0f\x9e" + "\x16\x2b\xce\x33\x57\x6b\x31\x5e\xce\xcb\xb6\x40\x68\x37\xbf" + "\x51\xf5", // py + "\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff" + "\xff\xbc\xe6\xfa\xad\xa7\x17\x9e\x84\xf3\xb9\xca\xc2\xfc\x63" + "\x25\x51" // order +}; + +// Base register addresses of different PUFcc modules +static struct pufcc_dma_regs *dma_regs; +static struct pufcc_rt_regs *rt_regs; +static struct pufcc_otp_mem *otp_mem; +static struct pufcc_hmac_regs *hmac_regs; +static struct pufcc_crypto_regs *crypto_regs; +static struct pufcc_sp38a_regs *sp38a_regs; +static struct pufcc_pkc_regs *pkc_regs; + +/***************************************************************************** + * Local function declarations + ****************************************************************************/ +static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, + struct rs_crypto_addr *msg_addr); +static enum pufcc_status otp_range_check(uint32_t addr, uint32_t len); +static int rwlck_index_get(uint32_t idx); +static void reverse(uint8_t *dst, const uint8_t *src, size_t len); +static uint32_t be2le(uint32_t var); +static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, + uint32_t error_mask); +enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, + enum pufcc_otp_lock *lock_val); + +/***************************************************************************** + * API functions + ****************************************************************************/ +/** + * @fn pufcc_calc_sha256_hash + * @brief Calculates SHA256 hash + * + * @param[in] data_addr Data address info + * @param[in] hash Pointer to hash strcut to return hash value in + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_calc_sha256_hash(struct rs_crypto_addr *data_addr, + struct rs_crypto_hash *hash) { + enum pufcc_status status; + struct pufcc_intrpt_reg intrpt_reg = {0}; + struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; + struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; + struct pufcc_dma_key_cfg0_reg dma_key_cfg0_reg = {0}; + struct pufcc_start_reg start_reg = {0}; + + // Set 'intrpt' register values + intrpt_reg.intrpt_st = 1; // Write 1 to clear interrupt + intrpt_reg.intrpt_en = 0; // Disable interrupt + + // Set dma_dsc_cfg_4 reg values + dma_dsc_cfg_4_reg.head = 1; + dma_dsc_cfg_4_reg.tail = 1; + + // set values for key_cfg_0 register + dma_key_cfg0_reg.key_dst = PUFCC_DMA_KEY_DST_HASH; + + // Set values for start register + start_reg.start_p = 1; // Start operation bit + + // Set values for HMAC config register + struct pufcc_hmac_config_reg hmac_config_reg = { + .variant = PUFCC_HMAC_VARIANT_SHA256, // Shah 256 + .function = PUFCC_HMAC_FUNCTION_HASH, // Hash + }; + + /*** Configure DMA registers ***/ + // Set dma_cfg_0 register + REG_WRITE_32(&dma_regs->cfg_0, &dma_cfg_0_reg); + + // Set data source address in dsc_cfg_0 register + dma_regs->dsc_cfg_0 = data_addr->read_addr; + + // Set data length in dsc_cfg_2 register + dma_regs->dsc_cfg_2 = data_addr->len; + + // Set the dsc_cfg_4 register to values defined above + REG_WRITE_32(&dma_regs->dsc_cfg_4, &dma_dsc_cfg_4_reg); + + // Set the key_cfg_0 register to values defined above + REG_WRITE_32(&dma_regs->key_cfg_0, &dma_key_cfg0_reg); + + // Write intrpt register to values defined above + REG_WRITE_32(&dma_regs->interrupt, &intrpt_reg); + + /** Configure HMAC registers **/ + // Set the config register to values defined above + REG_WRITE_32(&hmac_regs->cfg, &hmac_config_reg); + + // Write previous length in HMAC plen register + hmac_regs->plen = hmac_regs->alen; + + // Write intrpt register to values defined above + REG_WRITE_32(&hmac_regs->interrupt, &intrpt_reg); + + // Start the DMA operation by writing to its start register + REG_WRITE_32(&dma_regs->start, &start_reg); + + // Poll on busy status + status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); + + if (status != PUFCC_SUCCESS) { + return status; + } + + if (hmac_regs->status) { + return PUFCC_E_ERROR; + } + + // Read the calculated hash + for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { + ((uint32_t *)hash->val)[i] = be2le(crypto_regs->dgst_out[i]); + } + + hash->len = PUFCC_SHA_256_LEN; + + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_calc_sha256_hash_sg + * @brief Calculates SHA256 hash of non-contiguous data. + * All non contiguous data addresses can be passed in as a single linked + * list in the form of 'rs_crypto_addr' struct as 'data_addr' parameter + * or this function can be invoked multiple times with partial data + * address info in the linked list by setting the 'first' and 'last' + * params accordingly as detailed below against each param. In case of + * partial data address info and hence multiple invocations, we also need + * to pass in previously calculated hash values to every invocation + * after the first one and the accumulated length of all previous + * messages/data. + * + * Note: In case of multiple data chunks either in a single linked list + * or as partial linked lists using multiple invocations the sizes of all + * chunks must be multiples of 64 bytes except the last chunk. + * + * @param[in] data_addr A linked list of data address info + * @param[in] first Boolean to indicate if 'data_addr' contains the first + * data block + * @param[in] last Boolean to indicate if 'data_addr' contains the last + * data block + * Note: 'first' and 'last' can both be true if + * 'data_addr' linked list contains both first and last + * data blocks or if it contains a single data block that + * is both first as well last. + * @param[in] prev_len Pointer to accumulated length of previously processed + * data; 0 for first invocation. Currently processed data + * length will be added to this value. + * @param[in] hash_in Hash of the data bocks processed already; can be NULL + * for first invocation. + * @param[out] hash_out Pointer to hash strcut to return hash value in + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, + bool first, bool last, + uint32_t *prev_len, + struct rs_crypto_hash *hash_in, + struct rs_crypto_hash *hash_out) { + enum pufcc_status status; + uint32_t plen = 0; + uint8_t desc_count = 0; + struct rs_crypto_addr *curr_addr = data_addr; + struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; + struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; + struct pufcc_dma_key_cfg0_reg dma_key_cfg0_reg = {0}; + struct pufcc_intrpt_reg intrpt_reg = {0}; + struct pufcc_start_reg start_reg = {0}; + struct pufcc_hmac_config_reg hmac_config_reg = {0}; + + if (!first) plen = *prev_len; + + // Set DMA 'intrpt' register values + intrpt_reg.intrpt_st = 1; // Write 1 to clear interrupt + intrpt_reg.intrpt_en = 0; // Disable interrupt + + // Set values for start register + start_reg.start_p = 1; // Start operation + + // Set values for HMAC config register + hmac_config_reg.variant = PUFCC_HMAC_VARIANT_SHA256; + hmac_config_reg.function = PUFCC_HMAC_FUNCTION_HASH; + + // Set key_cfg_0 for hash calculation + dma_key_cfg0_reg.key_dst = PUFCC_DMA_KEY_DST_HASH; + + // Set previous hash value if it's not the first data block + if (!first) { + for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { + crypto_regs->dgst_in[i] = be2le(((uint32_t *)hash_in->val)[i]); + } + } + + // Set SGDMA descriptors + do { + sg_dma_descs[desc_count].read_addr = be2le(curr_addr->read_addr); + sg_dma_descs[desc_count].length = be2le(curr_addr->len); + sg_dma_descs[desc_count].next = + be2le((uint32_t)&sg_dma_descs[desc_count + 1]); + + sg_dma_descs[desc_count].key_cfg = be2le(*(uint32_t *)&dma_key_cfg0_reg); + sg_dma_descs[desc_count].cypt_cfg[0] = be2le(*(uint32_t *)&hmac_config_reg); + sg_dma_descs[desc_count].cypt_cfg[1] = be2le(plen); + + *(uint32_t *)&dma_dsc_cfg_4_reg = 0; + dma_dsc_cfg_4_reg.offset = plen % 16; + + plen += curr_addr->len; + curr_addr = curr_addr->next; + + if (!desc_count && first) { + dma_dsc_cfg_4_reg.head = 1; + } + + // Mark this descriptor as last if there is no more data + if (!curr_addr) { + dma_dsc_cfg_4_reg.dn_pause = 1; + if (last) { + dma_dsc_cfg_4_reg.tail = 1; + } + } + + sg_dma_descs[desc_count].dsc_cfg_4 = be2le(*(uint32_t *)&dma_dsc_cfg_4_reg); + desc_count++; + } while (curr_addr && ((desc_count * sizeof(struct pufcc_sg_dma_desc)) < + SG_DMA_MAX_DSCS_SIZE)); + + if (curr_addr) { + // No enough descriptors available + return PUFCC_E_OVERFLOW; + } + + // Update accumulated data length + *prev_len = plen; + + /*** Configure DMA registers ***/ + // Enable SGDMA in dma_cfg_0 register + dma_cfg_0_reg.sg_en = 1; + REG_WRITE_32(&dma_regs->cfg_0, &dma_cfg_0_reg); + + // Set dsc_cfg_2 register to indicate it's an SGDMA operation + dma_regs->dsc_cfg_2 = PUFCC_DMA_DSC_CFG2_SGDMA_VAL; + + // Set starting address of SGDMA descriptors in dma_dsc_cfg3 register + dma_regs->dsc_cfg_3 = (uint32_t)sg_dma_descs; + + // Clear and disable DMA and HMAC interrupts + REG_WRITE_32(&dma_regs->interrupt, &intrpt_reg); + REG_WRITE_32(&hmac_regs->interrupt, &intrpt_reg); + + // Start the DMA operation by writing to its start register + REG_WRITE_32(&dma_regs->start, &start_reg); + + // Poll on busy status + status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); + + if (status != PUFCC_SUCCESS) { + return status; + } + + if (hmac_regs->status) { + return PUFCC_E_ERROR; + } + + // Read the calculated hash value + for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { + ((uint32_t *)hash_out->val)[i] = be2le(crypto_regs->dgst_out[i]); + } + + hash_out->len = PUFCC_SHA_256_LEN; + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_decrypt_aes + * @brief Decrypt passed in data using AES decryption algorithm + * + * @param[in] out_addr Address to write decrypted data to + * @param[in] in_addr Address of the encrypted data + * @param[in] in_len Length of the input data in bytes + * @param[in] prev_len Length of the previously decrypted data in case + * decrypting data in chunks; 0 for first or single + * chunk + * @param[in] key_type Key type i.e. SW or OTP + * @param[in] key_addr Address or OTP slot of the decryption key + * @param[in] key_len Length of the decryption key + * @param[in] iv_addr IV address + * @param[in] iv_len IV length + * @param[in] write_type Write type i.e. write decrypted data to fixed address + * or auto-increment the destination address + * @param[in] readback_iv If true, read back updated IV value corresponding to + * number of processed data blocks into passed in + * iv_addr buffer. In this case iv_addr buffer must be + * writable. + * + * @return PUFCC_SUCCESS on success, otherwise an error code + */ +enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, + uint32_t in_len, uint32_t prev_len, + enum pufcc_key_type key_type, + uint32_t key_addr, uint32_t key_len, + uint32_t iv_addr, uint32_t iv_len, + enum pufcc_dma_rw_type write_type, + bool readback_iv) { + enum pufcc_status status; + uint32_t temp32; + + // Configure DMA intrpt register + temp32 = 0; + struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; + intrpt_reg->intrpt_st = 1; // Write 1 to clear interrupt + REG_WRITE_32(&dma_regs->interrupt, intrpt_reg); + + // Set dma_cfg_0 register + temp32 = 0; + REG_WRITE_32(&dma_regs->cfg_0, &temp32); + + struct pufcc_dma_cfg_1_reg *cfg_1_reg = (struct pufcc_dma_cfg_1_reg *)&temp32; + cfg_1_reg->rbst_max = 0xF; + cfg_1_reg->rbst_min = 0xF; + cfg_1_reg->wbst_max = 0xF; + cfg_1_reg->wbst_min = 0xF; + + REG_WRITE_32(&dma_regs->cfg_1, cfg_1_reg); + + // Set data source address in dsc_cfg_0 register + REG_WRITE_32(&dma_regs->dsc_cfg_0, &in_addr); + + // Set decrypted data destination address in dsc_cfg_1 register + REG_WRITE_32(&dma_regs->dsc_cfg_1, &out_addr); + + // Set data length in dsc_cfg_2 register + REG_WRITE_32(&dma_regs->dsc_cfg_2, &in_len); + + // Configure dma_dsc_cfg_4 register + temp32 = 0; + struct pufcc_dma_dsc_cfg_4_reg *dsc_cfg_4_reg = + (struct pufcc_dma_dsc_cfg_4_reg *)&temp32; + dsc_cfg_4_reg->fw = write_type; + dsc_cfg_4_reg->fr = AUTO_INCREMENT; // Autoincrement source address + dsc_cfg_4_reg->offset = prev_len % CTR_MODE_BLOCK_SIZE; + REG_WRITE_32(&dma_regs->dsc_cfg_4, dsc_cfg_4_reg); + + // Configure key_cfg_0 register + struct pufcc_dma_key_cfg0_reg *key_cfg_0_reg = + (struct pufcc_dma_key_cfg0_reg *)&temp32; + key_cfg_0_reg->key_src = key_type; + key_cfg_0_reg->key_dst = PUFCC_DMA_KEY_DST_SP38A; // SP38a + key_cfg_0_reg->key_size = key_len * 8; // Key length in bits + + // Configure the decryption key + if (key_type == PUFCC_SW_KEY) { + for (uint32_t i = 0; i < (key_len / PUFCC_WORD_SIZE); i++) { + crypto_regs->sw_key[i] = be2le(((uint32_t *)key_addr)[i]); + } + } else { + key_cfg_0_reg->key_idx = (enum pufcc_key_type)key_addr; + } + + REG_WRITE_32(&dma_regs->key_cfg_0, key_cfg_0_reg); + + // Configure IV + for (uint32_t i = 0; i < (iv_len / PUFCC_WORD_SIZE); i++) { + crypto_regs->iv[i] = be2le(((uint32_t *)iv_addr)[i]); + } + + // Configure SP38a intrpt register + temp32 = 0; + intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; + intrpt_reg->intrpt_st = 1; // Clear interrupt by writing 1 + REG_WRITE_32(&sp38a_regs->interrupt, intrpt_reg); + + // Configure SP38a config register + struct pufcc_sp38a_config_reg *sp38a_config_reg = + (struct pufcc_sp38a_config_reg *)&temp32; + sp38a_config_reg->variant = + (key_len == PUFCC_CRYPTO_AES128_KEY_LEN ? PUFCC_AES128 : PUFCC_AES256); + sp38a_config_reg->mode = PUFCC_CTR128; + sp38a_config_reg->enc_dec = 0; // Decryption + REG_WRITE_32(&sp38a_regs->cfg, sp38a_config_reg); + + // Start DMA operation + struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; + start_reg->start_p = 1; + REG_WRITE_32(&dma_regs->start, start_reg); + + // Poll on busy status + status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); + + if (status != PUFCC_SUCCESS) { + return status; + } + + if (sp38a_regs->status & PUFCC_SP38A_STATUS_ERROR_MASK) { + return PUFCC_E_ERROR; + } + + // Read back updated IV + if (readback_iv) { + for (uint8_t i = 0; i < iv_len / PUFCC_WORD_SIZE; i++) { + ((uint32_t *)iv_addr)[i] = be2le(crypto_regs->iv[i]); + } + } + + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_rsa2048_sign_verify + * @brief Verify RSA2048 signature of the input message data + * + * @param[in] sig Address of the message signature + * @param[in] msg_addr Address of the message data + * @param[in] pub_key RSA2048 public key + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_rsa2048_sign_verify( + uint8_t *sig, struct rs_crypto_addr *msg_addr, + struct rs_crypto_rsa2048_puk *pub_key) { + enum pufcc_status status = PUFCC_SUCCESS; + uint32_t temp32; + uint8_t dec_msg[PUFCC_RSA_2048_LEN]; + + // Configure signature scheme + temp32 = 0; + struct pufcc_pkc_ecp_ec_reg *ecp_ec_reg = + (struct pufcc_pkc_ecp_ec_reg *)&temp32; + ecp_ec_reg->field = PUFCC_RSA_2048; + REG_WRITE_32(&pkc_regs->ecp_ec, ecp_ec_reg); + + // Reverse public key modulus + reverse(pufcc_buffer, pub_key->n, PUFCC_RSA_2048_LEN); + + // Write reversed public key modulus to ECP data field at proper offset + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET, + pufcc_buffer, PUFCC_RSA_2048_LEN); + + // Write public key exponent to ecp_e_short register + REG_WRITE_32(&pkc_regs->ecp_e_short, &pub_key->e); + + // Reverse signature + reverse(pufcc_buffer, sig, PUFCC_RSA_2048_LEN); + + // Write reversed signature to ECP data field at proper offset + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, + pufcc_buffer, PUFCC_RSA_2048_LEN); + + // Write microprogram for RSA2048 + memcpy((void *)&pkc_regs->ecp_mac, rsa_2048_mprog, sizeof(rsa_2048_mprog)); + + // Clear and disable PKC interrupt + temp32 = 0; + struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; + intrpt_reg->intrpt_st = 1; + REG_WRITE_32(&pkc_regs->interrupt, intrpt_reg); + + // Start PKC operation + struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; + start_reg->start_p = 1; + REG_WRITE_32(&pkc_regs->start, start_reg); + + // Poll on busy status + status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); + + if (status != PUFCC_SUCCESS) { + return status; + } + + // Read decrypted message from proper offset in ECP data field and reverse it + memcpy(pufcc_buffer, + (uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, + PUFCC_RSA_2048_LEN); + reverse(dec_msg, pufcc_buffer, PUFCC_RSA_2048_LEN); + + status = rsa_p1v15_verify(dec_msg, msg_addr); + + return status; +} + +/** + * @fn pufcc_ecdsa256_sign_verify + * @brief Verify ECDSA256 signature of the input message data + * + * @param[in] sig Address of the message signature + * @param[in] msg_addr Address of the message data + * @param[in] pub_key ECDSA256 public key + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_ecdsa256_sign_verify( + struct rs_crypto_ec256_sig *sig, struct rs_crypto_addr *msg_addr, + struct rs_crypto_ec256_puk *pub_key) { + uint32_t temp32, prev_len = 0; + enum pufcc_status status; + struct rs_crypto_hash hash; + + // Calculate hash of the message + if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != + PUFCC_SUCCESS) { + return PUFCC_E_ERROR; + } + + // Set the EC NIST P256 parameters after reversing them + reverse(pufcc_buffer, ecc_param_nistp256.prime, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PRIME_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, ecc_param_nistp256.a, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_A_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, ecc_param_nistp256.b, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_B_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, ecc_param_nistp256.px, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PX_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, ecc_param_nistp256.py, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PY_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, ecc_param_nistp256.order, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_ORDER_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + // Configure signature scheme + temp32 = 0; + struct pufcc_pkc_ecp_ec_reg *ecp_ec_reg = + (struct pufcc_pkc_ecp_ec_reg *)&temp32; + ecp_ec_reg->field = PUFCC_ECDSA256; + ecp_ec_reg->h = 1; // EC cofactor h + REG_WRITE_32(&pkc_regs->ecp_ec, ecp_ec_reg); + + // Write microprogram for ECDSA 256 + memcpy((void *)&pkc_regs->ecp_mac, p256_ecdsa_mprog, + sizeof(p256_ecdsa_mprog)); + + // Set the hash, public key & signature in PKC module after reversing each + reverse(pufcc_buffer, hash.val, PUFCC_SHA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_HASH_OFFSET, + pufcc_buffer, PUFCC_SHA_256_LEN); + + reverse(pufcc_buffer, pub_key->x, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBX_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, pub_key->y, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBY_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, sig->r, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_R_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, sig->s, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_S_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + // Clear and disable PKC interrupt + temp32 = 0; + struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; + intrpt_reg->intrpt_st = 1; + REG_WRITE_32(&pkc_regs->interrupt, intrpt_reg); + + // Start PKC operation + struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; + start_reg->start_p = 1; + REG_WRITE_32(&pkc_regs->start, start_reg); + + // Poll on busy status + status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); + + return status; +} + +/** + * @fn pufcc_dma_transfer + * @brief Transfer data using PUFcc DMA + * + * @param[in] src_addr Source data address + * @param[in] dest_addr Destination data address + * @param[in] len Length of the data to be transferred + * @param[in] fixed_read Read data from a fixed address + * @param[in] fixed_write Write data to a fixed address + * @return PUFCC_SUCCESS on success, otherwise an error code + */ +enum pufcc_status pufcc_dma_transfer(uint32_t src_addr, uint32_t dest_addr, + uint32_t len, bool fixed_read, + bool fixed_write) { + enum pufcc_status status; + uint32_t temp32 = 0; + + // Configure DMA intrpt register + struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; + intrpt_reg->intrpt_st = 1; // Write 1 to clear interrupt + REG_WRITE_32(&dma_regs->interrupt, intrpt_reg); + + // Set dma_cfg_0 register + temp32 = 0; // rng_en = 0, sg_en = 0 + REG_WRITE_32(&dma_regs->cfg_0, &temp32); + + struct pufcc_dma_cfg_1_reg *cfg_1_reg = (struct pufcc_dma_cfg_1_reg *)&temp32; + cfg_1_reg->rbst_max = 0xF; + cfg_1_reg->rbst_min = 0xF; + cfg_1_reg->wbst_max = 0xF; + cfg_1_reg->wbst_min = 0xF; + REG_WRITE_32(&dma_regs->cfg_1, cfg_1_reg); + + // Set data source address in dsc_cfg_0 register + REG_WRITE_32(&dma_regs->dsc_cfg_0, &src_addr); + + // Set decrypted data destination address in dsc_cfg_1 register + REG_WRITE_32(&dma_regs->dsc_cfg_1, &dest_addr); + + // Set data length in dsc_cfg_2 register + REG_WRITE_32(&dma_regs->dsc_cfg_2, &len); + + // Configure dma_dsc_cfg_4 register + temp32 = 0; + struct pufcc_dma_dsc_cfg_4_reg *dsc_cfg_4_reg = + (struct pufcc_dma_dsc_cfg_4_reg *)&temp32; + dsc_cfg_4_reg->fw = fixed_write; + dsc_cfg_4_reg->fr = fixed_read; + dsc_cfg_4_reg->no_cypt = true; // Bypass crypto modules + REG_WRITE_32(&dma_regs->dsc_cfg_4, dsc_cfg_4_reg); + + // Start DMA operation + struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; + start_reg->start_p = 1; + REG_WRITE_32(&dma_regs->start, start_reg); + + // Poll on busy status + status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); + + return status; +} + +/** + * @fn pufcc_otp_setup_wait + * @brief Wait for the PUFrt module setup during power on + * + * @return PUFCC_SUCCESS if OTP is setup successfully, otherwise an error code + */ +enum pufcc_status pufcc_otp_setup_wait(void) { + enum pufcc_status status = busy_wait(&rt_regs->status, PUFCC_RT_ERROR_MASK); + + return status; +} + +/** + * @fn pufcc_program_otp + * @brief Write data to an OTP slot. + * PUFcc OTP memory contains 1024 bytes and is divided into 32 + * individual slots of 32 bytes each. + * + * @param[in] in_buf Buffer containing data to be written to OTP + * @param[in] len Length of the input buffer + * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_program_otp(const uint8_t *in_buf, uint32_t len, + enum pufcc_otp_slot otp_slot) { + enum pufcc_status check; + uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; + uint32_t start_index = addr / PUFCC_WORD_SIZE; + enum pufcc_otp_lock lock; + + if ((check = otp_range_check(addr, len)) != PUFCC_SUCCESS) return check; + + // Return error if write access is locked + pufcc_get_otp_rwlck(otp_slot, &lock); + if (lock != PUFCC_OTP_RW) return PUFCC_E_DENY; + + // Program the OTP slot + for (uint32_t i = 0; i < len; i += 4) { + union { + uint32_t word; + uint8_t byte[4]; + } otp_word; + for (int8_t j = 3; j >= 0; j--) // reserve, default 0xff + otp_word.byte[j] = ((i + 3 - j) < len) ? in_buf[i + 3 - j] : 0xff; + + otp_mem->otp[start_index + (i / 4)] = otp_word.word; + } + + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_read_otp + * @brief Read data from an OTP slot. + * PUFcc OTP memory contains 1024 bytes and is divided into 32 + * individual slots of 32 bytes each. + * + * @param[in] out_buf Buffer to read data into + * @param[in] len Length of the data to read + * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_read_otp(uint8_t *out_buf, uint32_t len, + enum pufcc_otp_slot otp_slot) { + enum pufcc_status check; + uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; + uint32_t word, start_index, wlen; + enum pufcc_otp_lock lock = PUFCC_OTP_RW; // default value + + if ((check = otp_range_check(addr, len)) != PUFCC_SUCCESS) return check; + + // Return error if read access is locked + pufcc_get_otp_rwlck(otp_slot, &lock); + if (lock == PUFCC_OTP_NA) return PUFCC_E_DENY; + + wlen = len / PUFCC_WORD_SIZE; + start_index = addr / PUFCC_WORD_SIZE; + + if (wlen > 0) { + memcpy(out_buf, (void *)(otp_mem->otp + start_index), + wlen * PUFCC_WORD_SIZE); + + uint32_t *out32 = (uint32_t *)out_buf; + for (size_t i = 0; i < wlen; ++i) *(out32 + i) = be2le(*(out32 + i)); + } + + if (len % PUFCC_WORD_SIZE != 0) { + out_buf += wlen * PUFCC_WORD_SIZE; + word = be2le(*(otp_mem->otp + start_index + wlen)); + memcpy(out_buf, &word, len % PUFCC_WORD_SIZE); + } + + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_lock_otp + * @brief Lock an OTP key slot according to passed-in lock value. + * + * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 + * @param[in] len Length of the OTP slot to be locked + * @param[in] lock Value of the lock to be placed + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_lock_otp(enum pufcc_otp_slot otp_slot, uint32_t len, + enum pufcc_otp_lock lock) { + enum pufcc_status check; + uint32_t lock_val = lock, shift = 0, start = 0, end = 0, mask = 0, val32 = 0; + int rwlock_index; + uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; + + if ((check = otp_range_check(addr, len)) != PUFCC_SUCCESS) return check; + + // Set end and start indices of OTP words + end = (len + 3) / 4; + start = addr / PUFCC_WORD_SIZE; + + for (uint32_t i = 0; i < end; i++) { + int idx = start + i; + + // Get the index of RWLCK register corresponding to current OTP word index + if ((rwlock_index = rwlck_index_get(idx)) == -1) { + return PUFCC_E_ERROR; + } + + // Get shift size for lock value to be written to RWLCK register according + // to OTP word index + shift = (idx % PUFCC_OTP_WORDS_PER_RWLCK_REG) * + PUFCC_OTP_RWLCK_REG_BITS_PER_OTP_WORD; + // Update lock value for current 'rwlock_index' + val32 |= lock_val << shift; + // Update mask value for current 'rwlock_index' + mask |= 0xF << shift; + + // If we have fully utilized RWLCK register at 'rwlock_index' or this is + // the end of OTP range that we are locking then write the lock value in + // RWLCK register at 'rwlock_index' + if (shift == 28 || i == end - 1) { + // Read modify write + val32 |= (rt_regs->pif[rwlock_index] & (~mask)); + rt_regs->pif[rwlock_index] = val32; + + // Clear values for next iteration + val32 = 0; + mask = 0; + } + } + + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_zeroize_otp + * @brief Zeroize an OTP key slot (32 bytes) permanently. + * + * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_zeroize_otp(enum pufcc_otp_slot otp_slot) { + enum pufcc_status status; + + if (otp_slot < PUFCC_OTPKEY_0 || otp_slot > PUFCC_OTPKEY_31) { + status = PUFCC_E_INVALID; + } else { + uint32_t zeroize_cmd = + (otp_slot - PUFCC_OTPKEY_0) + PUFCC_OTP_ZEROIZE_BASE_CMD; + + rt_regs->otp_zeroize = zeroize_cmd; + + // Wait on busy status + status = busy_wait(&rt_regs->status, PUFCC_RT_ERROR_MASK); + } + + return status; +} + +/** + * @fn pufcc_get_otp_rwlck + * @brief Get the read write lock value of passed-in OTP slot. This function + * assumes that the lock value of all the words of an OTP is same as that + * of the first word of that slot + * + * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 + * @param[out] lock_val Lock address to return the lock value in + * @return PUFCC_SUCCESS on success, otherwise and error code + */ +enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, + enum pufcc_otp_lock *lock_val) { + enum pufcc_status check; + uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; + + if ((check = otp_range_check(addr, 4)) != PUFCC_SUCCESS) return check; + + // Get OTP word index + int index = addr / PUFCC_WORD_SIZE; + + // Get offset of the lock value within RWLCK register corresponding to this + // OTP word + int rwlck_offset = (index % PUFCC_OTP_WORDS_PER_RWLCK_REG) * + PUFCC_OTP_RWLCK_REG_BITS_PER_OTP_WORD; + + // Get the index of RWLCK register corresponding to current OTP word index + // read lock value at that index + index = rwlck_index_get(index); + uint32_t lck = (rt_regs->pif[index] >> rwlck_offset) & PUFCC_PIF_RWLCK_MASK; + + switch (lck) { + // Read write access + case PUFCC_OTP_RWLCK_RW_0: + case PUFCC_OTP_RWLCK_RW_1: + case PUFCC_OTP_RWLCK_RW_2: + case PUFCC_OTP_RWLCK_RW_3: + case PUFCC_OTP_RWLCK_RW_4: + *lock_val = PUFCC_OTP_RW; + break; + + // Read only access + case PUFCC_OTP_RWLCK_RO_0: + case PUFCC_OTP_RWLCK_RO_1: + case PUFCC_OTP_RWLCK_RO_2: + *lock_val = PUFCC_OTP_RO; + break; + + // All other values indicate no access + default: + *lock_val = PUFCC_OTP_NA; + break; + } + + return PUFCC_SUCCESS; +} + +int pufcc_dma_request_channel(struct pufcc_dma_dev *dev) { + if (dev->is_dev_free) { + dev->is_dev_free = false; + return 0; + } + + return -1; +} + +void pufcc_dma_release_channel(struct pufcc_dma_dev *dev, int channel) { + (void)channel; + dev->is_dev_free = true; +} + +enum rs_status pufcc_dma_config_descriptor_memory(struct pufcc_dma_dev *dev, + int channel, uintptr_t addr, + size_t max_descriptors) { + // Check that channel is valid and is in use + if ((channel != 0) || (dev->is_dev_free)) { + return ERROR; + } + + dev->dma_descs = (struct pufcc_sg_dma_desc *)addr; + dev->num_descriptors = max_descriptors; + return OK; +} + +enum rs_status pufcc_dma_config_xfer(struct pufcc_dma_dev *dev, int channel, + struct rs_dma_config *config) { + uint8_t desc_count = 0; + struct rs_dma_block_config *current_block = config->head_block; + struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; + struct pufcc_dma_cfg_1_reg cfg_1_reg = {0}; + struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; + struct pufcc_intrpt_reg intrpt_reg = {0}; + + // Check that channel is valid and is in use and required descriptors for this + // transactions are available + if ((channel != 0) || (dev->is_dev_free) || + (config->block_count > dev->num_descriptors)) { + return ERROR; + } + + // Write 1 to clear interrupt + intrpt_reg.intrpt_st = 1; + + // Setup interrupt + if (config->complete_callback_en) { + intrpt_reg.intrpt_en = 1; + } else { + intrpt_reg.intrpt_en = 0; + } + + // Set SGDMA descriptors + do { + dev->dma_descs[desc_count].read_addr = + be2le((uint32_t)current_block->src_addr); + dev->dma_descs[desc_count].write_addr = + be2le((uint32_t)current_block->dst_addr); + dev->dma_descs[desc_count].length = be2le(current_block->block_size); + dev->dma_descs[desc_count].next = + be2le((uint32_t)&dev->dma_descs[desc_count + 1]); + + dev->dma_descs[desc_count].key_cfg = 0; + dev->dma_descs[desc_count].cypt_cfg[0] = 0; + dev->dma_descs[desc_count].cypt_cfg[1] = 0; + + *(uint32_t *)&dma_dsc_cfg_4_reg = 0; + if (current_block->src_addr_adjust == RS_DMA_ADDR_ADJUST_FIXED) { + dma_dsc_cfg_4_reg.fr = 1; + } else if (current_block->src_addr_adjust != RS_DMA_ADDR_ADJUST_INCREMENT) { + return ERROR; + } + + if (current_block->dst_addr_adjust == RS_DMA_ADDR_ADJUST_FIXED) { + dma_dsc_cfg_4_reg.fw = 1; + } else if (current_block->dst_addr_adjust != RS_DMA_ADDR_ADJUST_INCREMENT) { + return ERROR; + } + + // Bypass crypto modules + dma_dsc_cfg_4_reg.no_cypt = true; + + if (!desc_count) { + dma_dsc_cfg_4_reg.head = true; + } + + current_block = current_block->next_block; + + // Mark this descriptor as last if there is no more data + if (!current_block) { + dma_dsc_cfg_4_reg.dn_pause = true; + dma_dsc_cfg_4_reg.tail = true; + + if (config->complete_callback_en) { + dma_dsc_cfg_4_reg.dn_intrpt = true; + } + } + + dev->dma_descs[desc_count].dsc_cfg_4 = + be2le(*(uint32_t *)&dma_dsc_cfg_4_reg); + + desc_count++; + } while (current_block && (desc_count < dev->num_descriptors)); + + if (current_block) { + // No enough descriptors available + return ERROR; + } + + /*** Configure DMA registers ***/ + // Enable SGDMA in dma_cfg_0 register + dma_cfg_0_reg.sg_en = 1; + REG_WRITE_32(&dev->regs->cfg_0, &dma_cfg_0_reg); + + cfg_1_reg.rbst_max = 0xF; + cfg_1_reg.rbst_min = 0xF; + cfg_1_reg.wbst_max = 0xF; + cfg_1_reg.wbst_min = 0xF; + REG_WRITE_32(&dev->regs->cfg_1, &cfg_1_reg); + + // Set dsc_cfg_2 register to indicate it's an SGDMA operation + dev->regs->dsc_cfg_2 = PUFCC_DMA_DSC_CFG2_SGDMA_VAL; + + // Set starting address of SGDMA descriptors in dma_dsc_cfg3 register + dev->regs->dsc_cfg_3 = (uint32_t)dev->dma_descs; + + // Write interrupt register with values populated above + REG_WRITE_32(&dev->regs->interrupt, &intrpt_reg); + + // Set up call backs + dev->callback = config->callback; + dev->callback_args = config->callback_args; + + return OK; +} + +enum rs_status pufcc_dma_start_xfer(struct pufcc_dma_dev *dev, int channel) { + struct pufcc_start_reg start_reg = {0}; + + // Check that channel number is valid and the channel has been requested + if ((channel != 0) || (dev->is_dev_free)) { + return ERROR; + } + + // Start the DMA operation by writing to its start register + start_reg.start_p = 1; + REG_WRITE_32(&dev->regs->start, &start_reg); + + return OK; +} + +enum rs_status pufcc_dma_stop_xfer(struct pufcc_dma_dev *dev, int channel) { + struct pufcc_sg_dma_desc *next_desc_ptr; + struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; + + // check the channel number is valid and the channel has been requested + if ((channel != 0) || dev->is_dev_free) { + return ERROR; + } + + // Get pointer to next descriptor in queue + next_desc_ptr = (struct pufcc_sg_dma_desc *)dev->regs->dsc_cur_3; + + // Make sure that this descriptor lies within descriptor memory; it will lie + // outside the memory if last descriptor is already being processed + if (((uint32_t)next_desc_ptr > (uint32_t)dev->dma_descs) && + ((uint32_t)next_desc_ptr < + ((uint32_t)dev->dma_descs + + (dev->num_descriptors * sizeof(struct pufcc_sg_dma_desc))))) { + // Set up descriptor to stop DMA operation + *(uint32_t *)&dma_dsc_cfg_4_reg = next_desc_ptr->dsc_cfg_4; + dma_dsc_cfg_4_reg.dn_pause = true; + dma_dsc_cfg_4_reg.tail = true; + } + + return OK; +} + +void pufcc_dma_irq_handler(struct pufcc_dma_dev *dev) { + int status = (dev->regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); + struct pufcc_intrpt_reg *intrpt_reg_ptr = + (struct pufcc_intrpt_reg *)&dev->regs->interrupt; + + // Clear and disable interrupt + intrpt_reg_ptr->intrpt_st = 1; // Set to clear + intrpt_reg_ptr->intrpt_en = 0; + + dev->callback(dev->callback_args, 0, status); +} + +/** + * @fn rsa_p1v15_verify + * @brief Verify input RSA2048 decrypted message according to PKCS#1 v1.5 RSA + * verification standard. + * @param[in] dec_msg Input RSA decrypted message + * @param[in] msg_addr Address of the original data that was RSA signed + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, + struct rs_crypto_addr *msg_addr) { + uint32_t i, prev_len = 0; + struct rs_crypto_hash hash; + uint8_t pret[19] = {0x30, 0, 0x30, 0x0d, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0, 0x05, 0x00, 0x04, 0}; + + if ((dec_msg[0] != 0x00) || (dec_msg[1] != 0x01)) { + return PUFCC_E_VERFAIL; + } + + for (i = 2; i < PUFCC_RSA_2048_LEN; i++) { + if (dec_msg[i] != 0xff) { + break; + } + } + + if (dec_msg[i++] != 0x00) { + return PUFCC_E_VERFAIL; + } + + // Verify that decrypted message has SHA256 hash + if (dec_msg[i + 14] == 1) { + pret[1] = 0x31; + pret[14] = 0x01; + pret[18] = 0x20; + } else { + return PUFCC_E_INVALID; + } + + if ((memcmp(dec_msg + i, pret, 19) != 0) || + ((i + 19 + pret[18]) != PUFCC_RSA_2048_LEN)) { + return PUFCC_E_VERFAIL; + } + + // Calculate hash of the message + if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != + PUFCC_SUCCESS) { + return PUFCC_E_ERROR; + } + + if (memcmp(dec_msg + i + 19, hash.val, hash.len) != 0) { + return PUFCC_E_VERFAIL; + } + + return PUFCC_SUCCESS; +} + +/** + * @fn rwlck_index_get + * @brief Get the index of RWLCK register corresponding to passed-in OTP word + * index. + * + * @param[in] idx OTP word index for which to get the RWLCK register index for + * @return Index of the RWLCK register + */ +static int rwlck_index_get(uint32_t idx) { + uint32_t rwlck_idx = idx / PUFCC_OTP_WORDS_PER_RWLCK_REG; + + if (rwlck_idx >= PUFCC_PIF_MAX_RWLOCK_REGS) return -1; + + // Return the actual index of RWCLK register in PIF registers group + return PUFCC_PIF_RWLCK_START_INDEX + rwlck_idx; +} + +/** + * @fn reverse + * @brief Reverse input byte array. + * + * @param[in] dst Destination address of the reversed byte array + * @param[in] src Address of the input byte array + * @param[in] len Length of the input byte array to be reversed + */ +static void reverse(uint8_t *dst, const uint8_t *src, size_t len) { + for (size_t i = 0, j = len - 1; i < len; i++, j--) { + dst[i] = src[j]; + } +} + +/** + * @fn be2le + * @brief Reverse endianness of the input 4 byte word + * + * @param[in] var Input 4 byte variable + * @return 4 byte word with reversed endianness + */ +static uint32_t be2le(uint32_t var) { + return (((0xff000000 & var) >> 24) | ((0x00ff0000 & var) >> 8) | + ((0x0000ff00 & var) << 8) | ((0x000000ff & var) << 24)); +} + +/** + * @fn otp_range_check + * @brief Check range validity of the input OTP address + * + * @param[in] addr OTP address + * @param[in] len Length of OTP after OTP address + * @return 4 byte word with reversed endianness + * @return PUFCC_SUCCESS if OTP address and range is valid, otherwise + * an error code. + */ +static enum pufcc_status otp_range_check(uint32_t addr, uint32_t len) { + // word-aligned OTP address check + if ((addr % PUFCC_WORD_SIZE) != 0) return PUFCC_E_ALIGN; + // OTP boundary check + if ((len > PUFCC_OTP_LEN) || (addr > (PUFCC_OTP_LEN - len))) + return PUFCC_E_OVERFLOW; + return PUFCC_SUCCESS; +} + +/** + * @fn busy_wait + * @brief Waits on busy bit of the passed-in status register till it gets + * cleared or it times out. + * + * @param[in] status_reg_addr Status register's address + * @param[in] error_mask Bitmask of error bits in passed-in status register + * @return PUFCC_SUCCESS if busy bit gets cleared without an + * error, otherwise an error code. + */ +static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, + uint32_t error_mask) { + uint32_t status; + int32_t busy_count = PUFCC_MAX_BUSY_COUNT; + + do { + status = sys_read32((mem_addr_t)status_reg_addr); + busy_count--; + } while ((status & PUFCC_BUSY_BIT_MASK) && (busy_count > 0)); + + if (status & PUFCC_BUSY_BIT_MASK) { + return PUFCC_E_TIMEOUT; + } else if (status & error_mask) { + return PUFCC_E_ERROR; + } + + return PUFCC_SUCCESS; +} + +enum pufcc_status crypto_pufs_init(uint32_t base_addr) { + enum pufcc_status status; + + // Initialize base addresses of different PUFcc modules + dma_regs = (struct pufcc_dma_regs *)base_addr; + rt_regs = (struct pufcc_rt_regs *)(base_addr + PUFCC_RT_OFFSET); + otp_mem = (struct pufcc_otp_mem *)(base_addr + PUFCC_RT_OFFSET + + PUFCC_RT_OTP_OFFSET); + hmac_regs = (struct pufcc_hmac_regs *)(base_addr + PUFCC_HMAC_OFFSET); + crypto_regs = (struct pufcc_crypto_regs *)(base_addr + PUFCC_CRYPTO_OFFSET); + sp38a_regs = (struct pufcc_sp38a_regs *)(base_addr + PUFCC_SP38A_OFFSET); + pkc_regs = (struct pufcc_pkc_regs *)(base_addr + PUFCC_PKC_OFFSET); + + // Wait for OTP setup + status = pufcc_otp_setup_wait(); + + return status; +} + +DEVICE_DT_INST_DEFINE(0, crypto_pufs_init, NULL, + &crypto_stm32_dev_data, + &crypto_stm32_dev_config, POST_KERNEL, + CONFIG_CRYPTO_INIT_PRIORITY, (void *)&crypto_enc_funcs); \ No newline at end of file diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h new file mode 100644 index 0000000000000..f9eb23526b2e8 --- /dev/null +++ b/drivers/crypto/crypto_pufs.h @@ -0,0 +1,779 @@ +/* + * Copyright (c) 2024 Muhammad Junaid Aslam + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#ifndef ZEPHYR_DRIVERS_CRYPTO_PUFS_H_ +#define ZEPHYR_DRIVERS_CRYPTO_PUFS_H_ + +#include +#include +#include +#include + +/*** Generic PUFcc defines ***/ +#define PUFCC_WORD_SIZE 4 +#define PUFCC_BUSY_BIT_MASK 0x00000001 + +/*** RT and OTP defines ***/ +#define PUFCC_RT_OFFSET 0x3000 +#define PUFCC_RT_OTP_OFFSET 0x400 +#define PUFCC_RT_ERROR_MASK 0x0000001e +#define PUFCC_OTP_LEN 1024 +#define PUFCC_OTP_KEY_LEN 32 +#define PUFCC_OTP_ZEROIZE_BASE_CMD 0x80 + +// One read/write lock register controls 8 OTP words +#define PUFCC_OTP_WORDS_PER_RWLCK_REG 8 + +// 4 bits are reserved for lock value of one OTP word in read/write lock +// register +#define PUFCC_OTP_RWLCK_REG_BITS_PER_OTP_WORD 4 +#define PUFCC_PIF_RWLCK_MASK 0xF +#define PUFCC_PIF_MAX_RWLOCK_REGS \ + (PUFCC_OTP_LEN / PUFCC_WORD_SIZE / PUFCC_OTP_WORDS_PER_RWLCK_REG) + +// Start index of the RWLCK register in PIF registers group +#define PUFCC_PIF_RWLCK_START_INDEX 32 + +// Define all possible OTP lock values +#define PUFCC_OTP_RWLCK_RW_0 0x0 // Read Write access +#define PUFCC_OTP_RWLCK_RW_1 0x1 // Read Write access +#define PUFCC_OTP_RWLCK_RW_2 0x2 // Read Write access +#define PUFCC_OTP_RWLCK_RW_3 0x4 // Read Write access +#define PUFCC_OTP_RWLCK_RW_4 0x8 // Read Write access +#define PUFCC_OTP_RWLCK_RO_0 0x3 // Read Only access +#define PUFCC_OTP_RWLCK_RO_1 0x7 // Read Only access +#define PUFCC_OTP_RWLCK_RO_2 0xb // Read Only access + +/*** DMA defines ***/ +#define PUFCC_DMA_KEY_DST_HASH 0x1 +#define PUFCC_DMA_KEY_DST_SP38A 0x8 +#define PUFCC_DMA_DSC_CFG2_SGDMA_VAL 0x20 +#define PUFCC_DMA_ERROR_MASK 0xFFFFFFFE + +/*** HMAC defines ***/ +#define PUFCC_HMAC_OFFSET 0x0800 +#define PUFCC_HMAC_SW_KEY_MAXLEN 64 +#define PUFCC_SHA_256_LEN 32 +#define PUFCC_HMAC_FUNCTION_HASH 0x0 +#define PUFCC_HMAC_VARIANT_SHA256 0x03 + +/*** Crypto defines ***/ +#define PUFCC_CRYPTO_OFFSET 0x0100 +#define PUFCC_CRYPTO_SW_KEY_MAXLEN 64 // The byte length of CRYPTO_SW_KEY_ADDR +#define PUFCC_CRYPTO_DGST_LEN 64 // The byte length of CRYPTO_DGST field +#define PUFCC_CRYPTO_IV_MAXLEN 16 +#define PUFCC_CRYPTO_AES128_KEY_LEN 16 +#define PUFCC_CRYPTO_AES256_KEY_LEN 32 + +/*** SP38a defines ***/ +#define PUFCC_SP38A_OFFSET 0x0200 +#define PUFCC_SP38A_STATUS_ERROR_MASK 0xfffff0c0 + +/*** PKC defines ***/ +#define PUFCC_PKC_OFFSET 0x1000 +#define PUFCC_RSA_2048_LEN 256 +#define PUFCC_ECDSA_256_LEN 32 +#define PUFCC_DATA_RSA2048_MODULUS_OFFSET 256 +#define PUFCC_DATA_RSA2048_SIGN_OFFSET 768 +#define PUFCC_DATA_ECDSA_PRIME_OFFSET 256 +#define PUFCC_PKC_ERROR_MASK 0xFFFFFFFE +#define PUFCC_DATA_ECDSA_EC_A_OFFSET \ + (PUFCC_DATA_ECDSA_PRIME_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_EC_B_OFFSET \ + (PUFCC_DATA_ECDSA_EC_A_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_PX_OFFSET \ + (PUFCC_DATA_ECDSA_EC_B_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_PY_OFFSET \ + (PUFCC_DATA_ECDSA_PX_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_ORDER_OFFSET \ + (PUFCC_DATA_ECDSA_PY_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_HASH_OFFSET \ + (PUFCC_DATA_ECDSA_ORDER_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_PUBX_OFFSET \ + (PUFCC_DATA_ECDSA_HASH_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_PUBY_OFFSET \ + (PUFCC_DATA_ECDSA_PUBX_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_SIG_R_OFFSET \ + (PUFCC_DATA_ECDSA_PUBY_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_SIG_S_OFFSET \ + (PUFCC_DATA_ECDSA_SIG_R_OFFSET + PUFCC_ECDSA_256_LEN) + +/** + * @brief SHA lengths + */ +#define RS_SHA_MAX_LEN 64 +#define RS_SHA256_LEN 32 + +/** + * @brief ECDSA256 quadrant and key lengths + */ +#define RS_EC256_QLEN 32 +#define RS_EC256_KEY_LEN (32 * 2) + +/** + * @brief RSA 2048 public key modulus length + * + */ +#define RS_RSA_2048_LEN 256 + +/** + * @brief RSA 2048 public key exponent length + */ +#define RS_RSA_E_LEN 4 + +/** + * @brief RSA 2048 public key length + */ +#define RS_RSA_2048_KEY_LEN (RS_RSA_2048_LEN + RS_RSA_E_LEN) + +/** + * @brief IV length for AES-CTR128 + */ +#define RS_AES_CTR128_IV_EN 16 + +/** + * @brief Key length for AES128 + */ +#define RS_AES16_KEY_LEN 16 + +/** + * @brief Key length for AES256 + */ +#define RS_AES32_KEY_LEN 32 + +/***************************************************************************** + * Enumerations + ****************************************************************************/ +// PUFcc status codes +enum pufcc_status { + PUFCC_SUCCESS, // Success. + PUFCC_E_ALIGN, // Address alignment mismatch. + PUFCC_E_OVERFLOW, // Space overflow. + PUFCC_E_UNDERFLOW, // Size too small. + PUFCC_E_INVALID, // Invalid argument. + PUFCC_E_BUSY, // Resource is occupied. + PUFCC_E_UNAVAIL, // Resource is unavailable. + PUFCC_E_FIRMWARE, // Firmware error. + PUFCC_E_VERFAIL, // Invalid public key or digital signature. + PUFCC_E_ECMPROG, // Invalid ECC microprogram. + PUFCC_E_DENY, // Access denied. + PUFCC_E_UNSUPPORT, // Not support. + PUFCC_E_INFINITY, // Point at infinity. + PUFCC_E_ERROR, // Unspecific error. + PUFCC_E_TIMEOUT, // Operation timed out. +}; + +// PUFcc key slots; 32 slots of 256 bits each +enum pufcc_otp_slot { + PUFCC_OTPKEY_0, // OTP key slot 0, 256 bits + PUFCC_OTPKEY_1, // OTP key slot 1, 256 bits + PUFCC_OTPKEY_2, // OTP key slot 2, 256 bits + PUFCC_OTPKEY_3, // OTP key slot 3, 256 bits + PUFCC_OTPKEY_4, // OTP key slot 4, 256 bits + PUFCC_OTPKEY_5, // OTP key slot 5, 256 bits + PUFCC_OTPKEY_6, // OTP key slot 6, 256 bits + PUFCC_OTPKEY_7, // OTP key slot 7, 256 bits + PUFCC_OTPKEY_8, // OTP key slot 8, 256 bits + PUFCC_OTPKEY_9, // OTP key slot 9, 256 bits + PUFCC_OTPKEY_10, // OTP key slot 10, 256 bits + PUFCC_OTPKEY_11, // OTP key slot 11, 256 bits + PUFCC_OTPKEY_12, // OTP key slot 12, 256 bits + PUFCC_OTPKEY_13, // OTP key slot 13, 256 bits + PUFCC_OTPKEY_14, // OTP key slot 14, 256 bits + PUFCC_OTPKEY_15, // OTP key slot 15, 256 bits + PUFCC_OTPKEY_16, // OTP key slot 16, 256 bits + PUFCC_OTPKEY_17, // OTP key slot 17, 256 bits + PUFCC_OTPKEY_18, // OTP key slot 18, 256 bits + PUFCC_OTPKEY_19, // OTP key slot 19, 256 bits + PUFCC_OTPKEY_20, // OTP key slot 20, 256 bits + PUFCC_OTPKEY_21, // OTP key slot 21, 256 bits + PUFCC_OTPKEY_22, // OTP key slot 22, 256 bits + PUFCC_OTPKEY_23, // OTP key slot 23, 256 bits + PUFCC_OTPKEY_24, // OTP key slot 24, 256 bits + PUFCC_OTPKEY_25, // OTP key slot 25, 256 bits + PUFCC_OTPKEY_26, // OTP key slot 26, 256 bits + PUFCC_OTPKEY_27, // OTP key slot 27, 256 bits + PUFCC_OTPKEY_28, // OTP key slot 28, 256 bits + PUFCC_OTPKEY_29, // OTP key slot 29, 256 bits + PUFCC_OTPKEY_30, // OTP key slot 30, 256 bits + PUFCC_OTPKEY_31, // OTP key slot 31, 256 bits +}; + +// OTP lock types +enum pufcc_otp_lock { + PUFCC_OTP_NA = 0xF, // No-Access + PUFCC_OTP_RO = 0x3, // Read-Only + PUFCC_OTP_RW = 0x0, // Read-Write +}; + +// PUFcc read/write types +enum pufcc_dma_rw_type { AUTO_INCREMENT, FIXED_RW }; + +// PUFcc key types +enum pufcc_key_type { PUFCC_SW_KEY, PUFCC_OTP_KEY }; + +// PUFcc SP38a variants +enum pufcc_sp38a_variant { + PUFCC_AES128, + PUFCC_AES192, + PUFCC_AES256, + PUFCC_SM4 +}; + +// PUFcc PKC schemes +enum pufcc_pkc_scheme { PUFCC_RSA_2048 = 0x86, PUFCC_ECDSA256 = 0x82 }; + +// PUFcc SP38a modes +enum pufcc_sp38a_mode { + PUFCC_ECB_CLR, + PUFCC_CFB, + PUFCC_OFB, + PUFCC_CBC_CLR, + PUFCC_CBC_CTS1, + PUFCC_CBC_CTS2, + PUFCC_CBC_CTS3, + PUFCC_CTR32, + PUFCC_CTR64, + PUFCC_CTR128 +}; + +// Scatter gather DMA descriptor struct +struct pufcc_sg_dma_desc { + uint32_t read_addr; + uint32_t write_addr; + uint32_t length; + uint32_t next; + uint32_t dsc_cfg_4; + uint32_t key_cfg; + uint32_t cypt_cfg[2]; +}; + +/** + * @enum rs_crypto_status + * @brief Enum for crypto specific status values + * + */ +enum rs_crypto_status { + CRYPTO_SUCCESS = 0, + NULL_POINTER = 1, + MEM_UNAVAILABLE = 2, + CRYPTO_INIT_ERROR = 3, + RSA_VERIFY_ERROR = 4, + ECDSA_VERIFY_ERROR = 5, + DECRYPTION_ERROR = 6, + HASH_CALC_ERROR = 7, + ECP_CONFIG_ERROR = 8, + INVALID_RSA_TYPE = 9, + INVALID_HASH_ALGO = 10, + INVALID_ENCRYPTION_ALGO = 11, + INVALID_SIGNING_ALGO = 12, + INVALID_CIPHER_TYPE = 13, + BOP_IMAGE_NOT_FOUND = 14, + INVALID_IMAGE_TYPE = 15, + KEY_WRITE_ERROR = 16, + KEY_READ_ERROR = 17, + KEY_LOCK_ERROR = 18, + INVALID_PUBLIC_KEY = 19, + INVALID_ENC_KEY = 20, + NON_SECURE_IMAGE = 21, + CRC_CHECK_FAILED = 22, + INVALID_KEY_SLOT = 23, + INVALID_KEY_SRC = 24, + NO_ENC_KEY = 25, + NO_ACCESS = 26, + DATA_TRANSFER_ERROR = 27, + KEY_NOT_IN_MANIFEST = 28, + CRYPTO_xCB_ERROR = 29, + INVALID_KEYS = 30, + NO_ACTIONS = 31, + INTEGRITY_CHECK_FAILED = 32, + CBUFFER_READ_ERROR = 33, + INVALID_TARGET_DEVICE = 34, + DECOMPRESSION_ERROR = 35, + INVALID_ACTION_CMD = 36, + INVALID_CMPR_ALGO = 37, + CBUFFER_DATA_CONSUMPTION_MISMATCH = 38, + ALL_ACTIONS_NOT_CONSUMED = 39, + MALFORMED_ACTION = 40, + LIFECYCLE_PROGRAMMING_ERROR = 41, + FLASH_PROGRAM_ERROR = 42, + FLASH_ERASE_ERROR = 43 +}; + +/** + * @enum rs_sign_algo + * @brief Enum for signing algorithms + * + */ +enum rs_crypto_sign_algo { + SIGN_ALGO_NULL = 0, + SIGN_ALGO_ECDSA256 = 0x10, + SIGN_ALGO_ECDSA384 = 0x11, + SIGN_ALGO_RSA2048 = 0x20, + SIGN_ALGO_BRAINPOOL256 = 0x30, + SIGN_ALGO_BRAINPOOL384 = 0x31, + SIGN_ALGO_SM2 = 0x40 +}; + +/** + * @enum rs_enc_algo + * @brief Enum for encryption algorithms + */ +enum rs_crypto_enc_algo { + ENC_ALGO_NULL = 0, + ENC_ALGO_AES128_CTR = 0x10, + ENC_ALGO_AES192_CTR = 0x11, + ENC_ALGO_AES256_CTR = 0x12, + ENC_ALGO_AES128_GCM = 0x20, + ENC_ALGO_AES192_GCM = 0x21, + ENC_ALGO_AES256_GCM = 0x22 +}; + +/** + * @enum rs_crypto_cipher + * @brief Symmetric cipher types + */ +enum rs_crypto_cipher { AES_CIPHER, SM4_CIPHER, CHACHA_CIPHER }; + +/** + * @enum rs_crypto_rsa_type + * @brief RSA types + */ +enum rs_crypto_rsa_type { RSA_1024, RSA_2048, RSA_3072, RSA_4096 }; + +/** + * @enum rs_crypto_key_src + * @brief Key source i.e. software or hardware + */ +enum rs_crypto_key_src { + RS_SW_KEY, // Software key in a buffer + RS_HW_KEY // Hardware/OTP based key +}; + +/** + * @enum rs_crypto_key_slots + * @brief RS defined key slots + */ +enum rs_crypto_key_slot { + RS_FSBL_RSA2048_PUBK_HASH_SLOT, + RS_FSBL_ECDSA256_PUBK_HASH_SLOT, + RS_FSBL_AES16_ENC_KEY_SLOT, + RS_FSBL_AES32_ENC_KEY_SLOT, + RS_ACPU_RSA2048_PUBK_HASH_SLOT, + RS_ACPU_ECDSA256_PUBK_HASH_SLOT, + RS_ACPU_AES16_ENC_KEY_SLOT, + RS_ACPU_AES32_ENC_KEY_SLOT, + RS_XCB_RSA2048_PUBK_HASH_SLOT, + RS_XCB_ECDSA256_PUBK_HASH_SLOT, + RS_XCB_AES16_ENC_KEY_SLOT, + RS_XCB_AES32_ENC_KEY_SLOT, + RS_LIFECYCLE_BITS_SLOT, + RS_CHIP_ID_SLOT, + RS_INVALID_KEY_SLOT, + RS_ALL_KEY_SLOTS // Used to indicate an operation on all valid key slots + // above +}; + +/** + * @enum rs_crypto_hash_type + * @brief Types of cryptographic hash algorithms + */ +enum rs_crypto_hash_type { SHA256 = 0x10, SHA384 = 0x11, SHA512 = 0x12 }; + +/** + * @enum rs_crypto_tfr_type + * @brief Types of secure transfer type in case of peripherals + */ +enum rs_crypto_tfr_type { + RS_SECURE_TX, // Write to peripheral + RS_SECURE_RX // Read from peripheral +}; + +enum rs_status { OK = 0, WOULD_BLOCK = 1, ERROR = 2 } __attribute__((packed)); + +typedef void (*rs_dma_callback_t)(void* app_data, int ch, int status); + +/***************************************************************************** + * Register structures + ****************************************************************************/ +// General register structs +struct pufcc_intrpt_reg { + uint32_t intrpt_st : 1; + uint32_t reserved1 : 15; + uint32_t intrpt_en : 1; + uint32_t reserved2 : 15; +}; + +struct pufcc_start_reg { + uint32_t start_p : 1; + uint32_t reserved : 31; +}; + +// DMA register structs +struct pufcc_dma_cfg_0_reg { + uint32_t rng_en : 1; + uint32_t sg_en : 1; + uint32_t reserved : 30; +}; + +struct pufcc_dma_cfg_1_reg { + uint8_t rbst_max; + uint8_t wbst_max; + uint8_t rbst_min; + uint8_t wbst_min; +}; + +struct pufcc_dma_dsc_cfg_4_reg { + uint32_t wprot : 8; + uint32_t rprot : 8; + uint32_t fw : 1; + uint32_t fr : 1; + uint32_t reserved : 5; + uint32_t no_cypt : 1; + uint32_t offset : 4; + uint32_t dn_pause : 1; + uint32_t dn_intrpt : 1; + uint32_t tail : 1; + uint32_t head : 1; +}; + +struct pufcc_dma_key_cfg0_reg { + uint32_t key_src : 4; + uint32_t key_dst : 4; + uint32_t key_size : 11; + uint32_t reserved1 : 5; + uint32_t key_idx : 5; + uint32_t reserved2 : 3; +}; + +// HMAC register structs +struct pufcc_hmac_config_reg { + uint32_t variant : 4; + uint32_t reserved : 4; + uint32_t function : 1; + uint32_t reserved2 : 23; +}; + +// PUFcc SP38a register structs +struct pufcc_sp38a_config_reg { + uint32_t variant : 2; + uint32_t reserved1 : 2; + uint32_t mode : 4; + uint32_t enc_dec : 1; + uint32_t reserved2 : 23; +}; + +// PKC register register structs +struct pufcc_pkc_ecp_ec_reg { + uint32_t reserved1 : 8; + uint32_t field : 8; // PKC scheme + uint32_t h : 4; // EC cofactor h + uint32_t reserved2 : 12; +}; + +// ECC parameters structure +struct pufcc_ecc_param { + const void *prime; // Field modulus + const void *a; // EC parameter a + const void *b; // EC parameter b + const void *px; // x-coordinate of base point P + const void *py; // y-coordinate of base point P + const void *order; // Subgroup order +}; + +/***************************************************************************** + * PUFcc register maps + ****************************************************************************/ +// OTP memory map +struct pufcc_otp_mem { + uint32_t otp[256]; +}; + +struct pufcc_rt_regs { + volatile uint32_t pif[64]; + uint32_t _pad1[64]; + volatile uint32_t ptr[16]; + volatile uint32_t ptc[16]; + volatile uint32_t ptm[2]; + uint32_t _pad2[6]; + volatile uint32_t rn; + volatile uint32_t rn_status; + volatile uint32_t healthcfg; + volatile uint32_t feature; + volatile uint32_t interrupt; + volatile uint32_t otp_psmsk[2]; + volatile uint32_t puf_psmsk; + volatile uint32_t version; + volatile uint32_t status; + volatile uint32_t cfg; + volatile uint32_t set_pin; + volatile uint32_t auto_repair; + volatile uint32_t ini_off_chk; + volatile uint32_t repair_pgn; + volatile uint32_t repair_reg; + volatile uint32_t puf_qty_chk; + volatile uint32_t puf_enroll; + volatile uint32_t puf_zeroize; + volatile uint32_t set_flag; + volatile uint32_t otp_zeroize; + uint32_t _pad3[3]; + volatile uint32_t puf[64]; + volatile uint32_t otp[256]; +}; + +// DMA module register map +struct pufcc_dma_regs { + volatile uint32_t version; + volatile uint32_t interrupt; + volatile uint32_t feature; + uint32_t _pad1; + volatile uint32_t status_0; + volatile uint32_t status_1; + uint32_t _pad2[2]; + volatile uint32_t start; + volatile uint32_t cfg_0; + volatile uint32_t cfg_1; + uint32_t _pad3[2]; + volatile uint32_t dsc_cfg_0; + volatile uint32_t dsc_cfg_1; + volatile uint32_t dsc_cfg_2; + volatile uint32_t dsc_cfg_3; + volatile uint32_t dsc_cfg_4; + uint32_t _pad4[2]; + volatile uint32_t dsc_cur_0; + volatile uint32_t dsc_cur_1; + volatile uint32_t dsc_cur_2; + volatile uint32_t dsc_cur_3; + volatile uint32_t dsc_cur_4; + uint32_t _pad5[2]; + volatile uint32_t key_cfg_0; + volatile uint32_t cl_cfg_0; +}; + +// HMAC module register map +struct pufcc_hmac_regs { + volatile uint32_t version; + volatile uint32_t interrupt; + volatile uint32_t feature; + uint32_t _pad1; + volatile uint32_t status; + uint32_t _pad2; + volatile uint32_t cfg; + uint32_t _pad3; + volatile uint32_t plen; + uint32_t _pad4[3]; + volatile uint32_t alen; + uint32_t _pad5[3]; + volatile uint8_t sw_key[PUFCC_HMAC_SW_KEY_MAXLEN]; +}; + +// Crypto module register map +struct pufcc_crypto_regs { + volatile uint32_t version; + volatile uint32_t interrupt; + volatile uint32_t feature; + uint32_t _pad1[5]; + volatile uint32_t iv_out[PUFCC_CRYPTO_IV_MAXLEN / PUFCC_WORD_SIZE]; + volatile uint32_t iv[PUFCC_CRYPTO_IV_MAXLEN / PUFCC_WORD_SIZE]; + volatile uint32_t sw_key[PUFCC_CRYPTO_SW_KEY_MAXLEN / PUFCC_WORD_SIZE]; + volatile uint32_t dgst_in[PUFCC_CRYPTO_DGST_LEN / PUFCC_WORD_SIZE]; + volatile uint32_t dgst_out[PUFCC_CRYPTO_DGST_LEN / PUFCC_WORD_SIZE]; +}; + +// SP38a module register map +struct pufcc_sp38a_regs { + volatile uint32_t version; + volatile uint32_t interrupt; + volatile uint32_t feature; + uint32_t _pad1; + volatile uint32_t status; + uint32_t _pad2; + volatile uint32_t cfg; +}; + +// PKC module register map +struct pufcc_pkc_regs { + volatile uint32_t version; + volatile uint32_t interrupt; + volatile uint32_t start; + volatile uint32_t status; + volatile uint32_t ecp_err_code; + volatile uint32_t ecp_err_pc; + volatile uint32_t ecp_err_cmd; + volatile uint32_t mp_version; + uint32_t _pad1[56]; + volatile uint32_t ecp_ec; + volatile uint32_t ecp_keysel; + volatile uint32_t ecp_otpkba; + volatile uint32_t ecp_key_usage; + volatile uint32_t ecp_e_short; + uint32_t _pad2[55]; + volatile uint32_t ecp_mac[4]; + volatile uint32_t ecp_data[512]; +}; + +struct pufcc_dma_dev { + struct pufcc_dma_regs *regs; + bool is_dev_free; + struct pufcc_sg_dma_desc *dma_descs; + uint32_t num_descriptors; + void *callback_args; + rs_dma_callback_t callback; +}; + +/** + * @struct rs_crypto_addr + * @brief Address info for cryptographic operations + */ +struct rs_crypto_addr { + uint32_t read_addr; + uint32_t write_addr; + uint32_t len; + enum rs_crypto_tfr_type tfr_type; // Transfer type (read or write) in case of + // peripherals, otherwise don't care + bool periph_rw; // Indicates if data transfer involves a peripheral + struct rs_crypto_addr *next; // In case data lies at multiple locations +}; + +/** + * @struct rs_crypto_key + * @brief Generic cryptographic key structure + */ +struct rs_crypto_key { + enum rs_crypto_key_src key_src; + uint8_t *key_addr; // For software key in a buffer + enum rs_crypto_key_slot key_slot; // For HW/OTP/eFuse based key + uint32_t key_len; + uint8_t *iv; + uint32_t iv_len; + bool readback_iv; // If true, read back updated IV value corresponding to + // number of processed data blocks during decryption into + // the iv buffer above. In this case iv buffer must be + // writable. +}; + +/** + * @struct rs_crypto_rsa2048_puk + * @brief RSA 2048 public key structure + */ +struct rs_crypto_rsa2048_puk { + uint8_t n[RS_RSA_2048_LEN]; // Modulus + uint32_t e; // Exponent +}; + +/** + * @struct rs_crypto_ec256_puk + * @brief ECDSA256 public key + */ +struct rs_crypto_ec256_puk { + uint8_t x[RS_EC256_QLEN]; + uint8_t y[RS_EC256_QLEN]; +}; + +/** + * @struct rs_crypto_ec256_sig + * @brief ECDSA256 signature + */ +struct rs_crypto_ec256_sig { + uint8_t r[RS_EC256_QLEN]; + uint8_t s[RS_EC256_QLEN]; +}; + +/** + * @struct rs_crypto_hash + * @brief Hash structure + */ +struct rs_crypto_hash { + uint8_t val[RS_SHA_MAX_LEN]; + uint32_t len; +}; + +/** + * @enum rs_crypto_key_manifest + * @brief Key manifest structure + */ +struct rs_crypto_key_manifest { + uint32_t key_mask; // Key availability bitmask according to + // 'rs_crypto_key_slot' enum above + uint8_t fsbl_rsa2048_pubk_hash[32]; + uint8_t fsbl_ecdsa256_pubk_hash[32]; + uint8_t fsbl_aes128_enc_key[16]; + uint8_t fsbl_aes256_enc_key[32]; + uint8_t acpu_rsa2048_pubk_hash[32]; + uint8_t acpu_ecdsa256_pubk_hash[32]; + uint8_t acpu_aes128_enc_key[16]; + uint8_t acpu_aes256_enc_key[32]; + uint8_t xcb_rsa2048_pubk_hash[32]; + uint8_t xcb_ecdsa256_pubk_hash[32]; + uint8_t xcb_aes128_enc_key[16]; + uint8_t xcb_aes256_enc_key[32]; +}; + +enum rs_dma_addr_adjust { + RS_DMA_ADDR_ADJUST_INCREMENT = 0x0, + RS_DMA_ADDR_ADJUST_DECREMENT = 0x1, + RS_DMA_ADDR_ADJUST_FIXED = 0x2, +}; + +struct rs_dma_block_config { + uintptr_t src_addr; + uintptr_t dst_addr; + uint32_t block_size; + struct rs_dma_block_config* next_block; + enum rs_dma_addr_adjust src_addr_adjust; + enum rs_dma_addr_adjust dst_addr_adjust; +}; + +struct rs_dma_config { + // peripheral combination. Platform dependent + uint8_t dma_slot __attribute__((aligned(4))); + // What type of DMA transfer this is + uint8_t xfer_dir __attribute__((aligned(4))); + // enable callback on transfer complete + uint8_t complete_callback_en __attribute__((aligned(4))); + // enable callback on transfer error + uint8_t err_callback_en __attribute__((aligned(4))); + // select software or hardware handshaking on the source + uint8_t src_handshake_mode __attribute__((aligned(4))); + // select software or hardware handshaking on the dest + uint8_t dst_handshake_mode __attribute__((aligned(4))); + // priority of the transfer + uint8_t xfer_priority __attribute__((aligned(4))); + // width of src data in bytes + uint16_t src_data_size __attribute__((aligned(4))); + // width of dst data in bytes + uint16_t dst_data_size __attribute__((aligned(4))); + // length of data to be retrieved in each src transfer step + uint16_t src_burst_len __attribute__((aligned(4))); + // length of data to be written in each dest transfer step + uint16_t dst_burst_len __attribute__((aligned(4))); + // total amount of transfer blocks to be used + uint32_t block_count __attribute__((aligned(4))); + // first transfer descriptor + struct rs_dma_block_config* head_block __attribute__((aligned(4))); + // arguments to be passed as app_data to the dma callback + void* callback_args __attribute__((aligned(4))); + rs_dma_callback_t callback __attribute__((aligned(4))); +} __attribute__((aligned(4))); + +/* +The following macro can be used to write register values. +REG_WRITE_32(Destination_Addr, Source_Addr) +*/ +#define REG_WRITE_32(Destination_Addr, Source_Addr) \ + *(uint32_t *)Destination_Addr = *(uint32_t *)Source_Addr; + +#endif /* ZEPHYR_DRIVERS_CRYPTO_CRYPTO_STM32_PRIV_H_ */ diff --git a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi index 1dd6b4ea998b9..bc3387638762f 100644 --- a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi +++ b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi @@ -181,7 +181,7 @@ status = "disabled"; }; - pufcc: pufcc@A0130000 { + pufs: pufcc@A0130000 { compatible = "pufsecurity,pufcc"; reg = <0xA0130000 DT_SIZE_K(64)>; interrupts = <33 3>; From 95036e6335eb960f3649879cf6d427e8ffa55fb1 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 11 Sep 2024 21:45:58 +0500 Subject: [PATCH 02/58] PUFcc Support in Progress --- drivers/crypto/crypto_pufs.c | 335 +++++------------------------------ drivers/crypto/crypto_pufs.h | 318 ++++----------------------------- 2 files changed, 82 insertions(+), 571 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index ffb300407388d..7e1da6fd61322 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -97,7 +97,7 @@ static struct pufcc_pkc_regs *pkc_regs; * Local function declarations ****************************************************************************/ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, - struct rs_crypto_addr *msg_addr); + struct pufs_crypto_addr *msg_addr); static enum pufcc_status otp_range_check(uint32_t addr, uint32_t len); static int rwlck_index_get(uint32_t idx); static void reverse(uint8_t *dst, const uint8_t *src, size_t len); @@ -118,8 +118,8 @@ enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, * @param[in] hash Pointer to hash strcut to return hash value in * @return PUFCC_SUCCESS on success, otherwise an error code. */ -enum pufcc_status pufcc_calc_sha256_hash(struct rs_crypto_addr *data_addr, - struct rs_crypto_hash *hash) { +enum pufcc_status pufcc_calc_sha256_hash(struct pufs_crypto_addr *data_addr, + struct pufs_crypto_hash *hash) { enum pufcc_status status; struct pufcc_intrpt_reg intrpt_reg = {0}; struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; @@ -204,7 +204,7 @@ enum pufcc_status pufcc_calc_sha256_hash(struct rs_crypto_addr *data_addr, * @fn pufcc_calc_sha256_hash_sg * @brief Calculates SHA256 hash of non-contiguous data. * All non contiguous data addresses can be passed in as a single linked - * list in the form of 'rs_crypto_addr' struct as 'data_addr' parameter + * list in the form of 'pufs_crypto_addr' struct as 'data_addr' parameter * or this function can be invoked multiple times with partial data * address info in the linked list by setting the 'first' and 'last' * params accordingly as detailed below against each param. In case of @@ -234,15 +234,15 @@ enum pufcc_status pufcc_calc_sha256_hash(struct rs_crypto_addr *data_addr, * @param[out] hash_out Pointer to hash strcut to return hash value in * @return PUFCC_SUCCESS on success, otherwise an error code. */ -enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, +enum pufcc_status pufcc_calc_sha256_hash_sg(struct pufs_crypto_addr *data_addr, bool first, bool last, uint32_t *prev_len, - struct rs_crypto_hash *hash_in, - struct rs_crypto_hash *hash_out) { + struct pufs_crypto_hash *hash_in, + struct pufs_crypto_hash *hash_out) { enum pufcc_status status; uint32_t plen = 0; uint8_t desc_count = 0; - struct rs_crypto_addr *curr_addr = data_addr; + struct pufs_crypto_addr *curr_addr = data_addr; struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; struct pufcc_dma_key_cfg0_reg dma_key_cfg0_reg = {0}; @@ -497,8 +497,8 @@ enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, * @return PUFCC_SUCCESS on success, otherwise an error code. */ enum pufcc_status pufcc_rsa2048_sign_verify( - uint8_t *sig, struct rs_crypto_addr *msg_addr, - struct rs_crypto_rsa2048_puk *pub_key) { + uint8_t *sig, struct pufs_crypto_addr *msg_addr, + struct pufs_crypto_rsa2048_puk *pub_key) { enum pufcc_status status = PUFCC_SUCCESS; uint32_t temp32; uint8_t dec_msg[PUFCC_RSA_2048_LEN]; @@ -569,11 +569,11 @@ enum pufcc_status pufcc_rsa2048_sign_verify( * @return PUFCC_SUCCESS on success, otherwise an error code. */ enum pufcc_status pufcc_ecdsa256_sign_verify( - struct rs_crypto_ec256_sig *sig, struct rs_crypto_addr *msg_addr, + struct pufs_crypto_ec256_sig *sig, struct pufs_crypto_addr *msg_addr, struct rs_crypto_ec256_puk *pub_key) { uint32_t temp32, prev_len = 0; enum pufcc_status status; - struct rs_crypto_hash hash; + struct pufs_crypto_hash hash; // Calculate hash of the message if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != @@ -656,68 +656,6 @@ enum pufcc_status pufcc_ecdsa256_sign_verify( return status; } -/** - * @fn pufcc_dma_transfer - * @brief Transfer data using PUFcc DMA - * - * @param[in] src_addr Source data address - * @param[in] dest_addr Destination data address - * @param[in] len Length of the data to be transferred - * @param[in] fixed_read Read data from a fixed address - * @param[in] fixed_write Write data to a fixed address - * @return PUFCC_SUCCESS on success, otherwise an error code - */ -enum pufcc_status pufcc_dma_transfer(uint32_t src_addr, uint32_t dest_addr, - uint32_t len, bool fixed_read, - bool fixed_write) { - enum pufcc_status status; - uint32_t temp32 = 0; - - // Configure DMA intrpt register - struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; - intrpt_reg->intrpt_st = 1; // Write 1 to clear interrupt - REG_WRITE_32(&dma_regs->interrupt, intrpt_reg); - - // Set dma_cfg_0 register - temp32 = 0; // rng_en = 0, sg_en = 0 - REG_WRITE_32(&dma_regs->cfg_0, &temp32); - - struct pufcc_dma_cfg_1_reg *cfg_1_reg = (struct pufcc_dma_cfg_1_reg *)&temp32; - cfg_1_reg->rbst_max = 0xF; - cfg_1_reg->rbst_min = 0xF; - cfg_1_reg->wbst_max = 0xF; - cfg_1_reg->wbst_min = 0xF; - REG_WRITE_32(&dma_regs->cfg_1, cfg_1_reg); - - // Set data source address in dsc_cfg_0 register - REG_WRITE_32(&dma_regs->dsc_cfg_0, &src_addr); - - // Set decrypted data destination address in dsc_cfg_1 register - REG_WRITE_32(&dma_regs->dsc_cfg_1, &dest_addr); - - // Set data length in dsc_cfg_2 register - REG_WRITE_32(&dma_regs->dsc_cfg_2, &len); - - // Configure dma_dsc_cfg_4 register - temp32 = 0; - struct pufcc_dma_dsc_cfg_4_reg *dsc_cfg_4_reg = - (struct pufcc_dma_dsc_cfg_4_reg *)&temp32; - dsc_cfg_4_reg->fw = fixed_write; - dsc_cfg_4_reg->fr = fixed_read; - dsc_cfg_4_reg->no_cypt = true; // Bypass crypto modules - REG_WRITE_32(&dma_regs->dsc_cfg_4, dsc_cfg_4_reg); - - // Start DMA operation - struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; - start_reg->start_p = 1; - REG_WRITE_32(&dma_regs->start, start_reg); - - // Poll on busy status - status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); - - return status; -} - /** * @fn pufcc_otp_setup_wait * @brief Wait for the PUFrt module setup during power on @@ -746,7 +684,7 @@ enum pufcc_status pufcc_program_otp(const uint8_t *in_buf, uint32_t len, enum pufcc_status check; uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; uint32_t start_index = addr / PUFCC_WORD_SIZE; - enum pufcc_otp_lock lock; + enum pufcc_otp_lock lock = PUFCC_OTP_NA; if ((check = otp_range_check(addr, len)) != PUFCC_SUCCESS) return check; @@ -950,196 +888,17 @@ enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, return PUFCC_SUCCESS; } -int pufcc_dma_request_channel(struct pufcc_dma_dev *dev) { - if (dev->is_dev_free) { - dev->is_dev_free = false; - return 0; - } +// static void pufs_irq_handler(const struct device *dev) { +// int status = (dev->regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); +// struct pufcc_intrpt_reg *intrpt_reg_ptr = +// (struct pufcc_intrpt_reg *)&dev->regs->interrupt; - return -1; -} +// // Clear and disable interrupt +// intrpt_reg_ptr->intrpt_st = 1; // Set to clear +// intrpt_reg_ptr->intrpt_en = 0; -void pufcc_dma_release_channel(struct pufcc_dma_dev *dev, int channel) { - (void)channel; - dev->is_dev_free = true; -} - -enum rs_status pufcc_dma_config_descriptor_memory(struct pufcc_dma_dev *dev, - int channel, uintptr_t addr, - size_t max_descriptors) { - // Check that channel is valid and is in use - if ((channel != 0) || (dev->is_dev_free)) { - return ERROR; - } - - dev->dma_descs = (struct pufcc_sg_dma_desc *)addr; - dev->num_descriptors = max_descriptors; - return OK; -} - -enum rs_status pufcc_dma_config_xfer(struct pufcc_dma_dev *dev, int channel, - struct rs_dma_config *config) { - uint8_t desc_count = 0; - struct rs_dma_block_config *current_block = config->head_block; - struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; - struct pufcc_dma_cfg_1_reg cfg_1_reg = {0}; - struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; - struct pufcc_intrpt_reg intrpt_reg = {0}; - - // Check that channel is valid and is in use and required descriptors for this - // transactions are available - if ((channel != 0) || (dev->is_dev_free) || - (config->block_count > dev->num_descriptors)) { - return ERROR; - } - - // Write 1 to clear interrupt - intrpt_reg.intrpt_st = 1; - - // Setup interrupt - if (config->complete_callback_en) { - intrpt_reg.intrpt_en = 1; - } else { - intrpt_reg.intrpt_en = 0; - } - - // Set SGDMA descriptors - do { - dev->dma_descs[desc_count].read_addr = - be2le((uint32_t)current_block->src_addr); - dev->dma_descs[desc_count].write_addr = - be2le((uint32_t)current_block->dst_addr); - dev->dma_descs[desc_count].length = be2le(current_block->block_size); - dev->dma_descs[desc_count].next = - be2le((uint32_t)&dev->dma_descs[desc_count + 1]); - - dev->dma_descs[desc_count].key_cfg = 0; - dev->dma_descs[desc_count].cypt_cfg[0] = 0; - dev->dma_descs[desc_count].cypt_cfg[1] = 0; - - *(uint32_t *)&dma_dsc_cfg_4_reg = 0; - if (current_block->src_addr_adjust == RS_DMA_ADDR_ADJUST_FIXED) { - dma_dsc_cfg_4_reg.fr = 1; - } else if (current_block->src_addr_adjust != RS_DMA_ADDR_ADJUST_INCREMENT) { - return ERROR; - } - - if (current_block->dst_addr_adjust == RS_DMA_ADDR_ADJUST_FIXED) { - dma_dsc_cfg_4_reg.fw = 1; - } else if (current_block->dst_addr_adjust != RS_DMA_ADDR_ADJUST_INCREMENT) { - return ERROR; - } - - // Bypass crypto modules - dma_dsc_cfg_4_reg.no_cypt = true; - - if (!desc_count) { - dma_dsc_cfg_4_reg.head = true; - } - - current_block = current_block->next_block; - - // Mark this descriptor as last if there is no more data - if (!current_block) { - dma_dsc_cfg_4_reg.dn_pause = true; - dma_dsc_cfg_4_reg.tail = true; - - if (config->complete_callback_en) { - dma_dsc_cfg_4_reg.dn_intrpt = true; - } - } - - dev->dma_descs[desc_count].dsc_cfg_4 = - be2le(*(uint32_t *)&dma_dsc_cfg_4_reg); - - desc_count++; - } while (current_block && (desc_count < dev->num_descriptors)); - - if (current_block) { - // No enough descriptors available - return ERROR; - } - - /*** Configure DMA registers ***/ - // Enable SGDMA in dma_cfg_0 register - dma_cfg_0_reg.sg_en = 1; - REG_WRITE_32(&dev->regs->cfg_0, &dma_cfg_0_reg); - - cfg_1_reg.rbst_max = 0xF; - cfg_1_reg.rbst_min = 0xF; - cfg_1_reg.wbst_max = 0xF; - cfg_1_reg.wbst_min = 0xF; - REG_WRITE_32(&dev->regs->cfg_1, &cfg_1_reg); - - // Set dsc_cfg_2 register to indicate it's an SGDMA operation - dev->regs->dsc_cfg_2 = PUFCC_DMA_DSC_CFG2_SGDMA_VAL; - - // Set starting address of SGDMA descriptors in dma_dsc_cfg3 register - dev->regs->dsc_cfg_3 = (uint32_t)dev->dma_descs; - - // Write interrupt register with values populated above - REG_WRITE_32(&dev->regs->interrupt, &intrpt_reg); - - // Set up call backs - dev->callback = config->callback; - dev->callback_args = config->callback_args; - - return OK; -} - -enum rs_status pufcc_dma_start_xfer(struct pufcc_dma_dev *dev, int channel) { - struct pufcc_start_reg start_reg = {0}; - - // Check that channel number is valid and the channel has been requested - if ((channel != 0) || (dev->is_dev_free)) { - return ERROR; - } - - // Start the DMA operation by writing to its start register - start_reg.start_p = 1; - REG_WRITE_32(&dev->regs->start, &start_reg); - - return OK; -} - -enum rs_status pufcc_dma_stop_xfer(struct pufcc_dma_dev *dev, int channel) { - struct pufcc_sg_dma_desc *next_desc_ptr; - struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; - - // check the channel number is valid and the channel has been requested - if ((channel != 0) || dev->is_dev_free) { - return ERROR; - } - - // Get pointer to next descriptor in queue - next_desc_ptr = (struct pufcc_sg_dma_desc *)dev->regs->dsc_cur_3; - - // Make sure that this descriptor lies within descriptor memory; it will lie - // outside the memory if last descriptor is already being processed - if (((uint32_t)next_desc_ptr > (uint32_t)dev->dma_descs) && - ((uint32_t)next_desc_ptr < - ((uint32_t)dev->dma_descs + - (dev->num_descriptors * sizeof(struct pufcc_sg_dma_desc))))) { - // Set up descriptor to stop DMA operation - *(uint32_t *)&dma_dsc_cfg_4_reg = next_desc_ptr->dsc_cfg_4; - dma_dsc_cfg_4_reg.dn_pause = true; - dma_dsc_cfg_4_reg.tail = true; - } - - return OK; -} - -void pufcc_dma_irq_handler(struct pufcc_dma_dev *dev) { - int status = (dev->regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); - struct pufcc_intrpt_reg *intrpt_reg_ptr = - (struct pufcc_intrpt_reg *)&dev->regs->interrupt; - - // Clear and disable interrupt - intrpt_reg_ptr->intrpt_st = 1; // Set to clear - intrpt_reg_ptr->intrpt_en = 0; - - dev->callback(dev->callback_args, 0, status); -} +// dev->callback(dev->callback_args, 0, status); +// } /** * @fn rsa_p1v15_verify @@ -1150,9 +909,9 @@ void pufcc_dma_irq_handler(struct pufcc_dma_dev *dev) { * @return PUFCC_SUCCESS on success, otherwise an error code. */ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, - struct rs_crypto_addr *msg_addr) { + struct pufs_crypto_addr *msg_addr) { uint32_t i, prev_len = 0; - struct rs_crypto_hash hash; + struct pufs_crypto_hash hash; uint8_t pret[19] = {0x30, 0, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0, 0x05, 0x00, 0x04, 0}; @@ -1289,26 +1048,26 @@ static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, return PUFCC_SUCCESS; } -enum pufcc_status crypto_pufs_init(uint32_t base_addr) { - enum pufcc_status status; - - // Initialize base addresses of different PUFcc modules - dma_regs = (struct pufcc_dma_regs *)base_addr; - rt_regs = (struct pufcc_rt_regs *)(base_addr + PUFCC_RT_OFFSET); - otp_mem = (struct pufcc_otp_mem *)(base_addr + PUFCC_RT_OFFSET + - PUFCC_RT_OTP_OFFSET); - hmac_regs = (struct pufcc_hmac_regs *)(base_addr + PUFCC_HMAC_OFFSET); - crypto_regs = (struct pufcc_crypto_regs *)(base_addr + PUFCC_CRYPTO_OFFSET); - sp38a_regs = (struct pufcc_sp38a_regs *)(base_addr + PUFCC_SP38A_OFFSET); - pkc_regs = (struct pufcc_pkc_regs *)(base_addr + PUFCC_PKC_OFFSET); - - // Wait for OTP setup - status = pufcc_otp_setup_wait(); - - return status; -} - -DEVICE_DT_INST_DEFINE(0, crypto_pufs_init, NULL, - &crypto_stm32_dev_data, - &crypto_stm32_dev_config, POST_KERNEL, - CONFIG_CRYPTO_INIT_PRIORITY, (void *)&crypto_enc_funcs); \ No newline at end of file +// static int crypto_pufs_init(const struct device *dev) { +// enum pufcc_status status; + +// // Initialize base addresses of different PUFcc modules +// dma_regs = (struct pufcc_dma_regs *)dev->config; +// rt_regs = (struct pufcc_rt_regs *)(base_addr + PUFCC_RT_OFFSET); +// otp_mem = (struct pufcc_otp_mem *)(base_addr + PUFCC_RT_OFFSET + +// PUFCC_RT_OTP_OFFSET); +// hmac_regs = (struct pufcc_hmac_regs *)(base_addr + PUFCC_HMAC_OFFSET); +// crypto_regs = (struct pufcc_crypto_regs *)(base_addr + PUFCC_CRYPTO_OFFSET); +// sp38a_regs = (struct pufcc_sp38a_regs *)(base_addr + PUFCC_SP38A_OFFSET); +// pkc_regs = (struct pufcc_pkc_regs *)(base_addr + PUFCC_PKC_OFFSET); + +// // Wait for OTP setup +// status = pufcc_otp_setup_wait(); + +// return status; +// } + +// DEVICE_DT_INST_DEFINE(0, crypto_pufs_init, NULL, +// &crypto_stm32_dev_data, +// &crypto_stm32_dev_config, POST_KERNEL, +// CONFIG_CRYPTO_INIT_PRIORITY, (void *)&crypto_enc_funcs); \ No newline at end of file diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index f9eb23526b2e8..6d186d84f9a4b 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -114,45 +114,20 @@ /** * @brief SHA lengths */ -#define RS_SHA_MAX_LEN 64 -#define RS_SHA256_LEN 32 +#define PUFS_SHA_MAX_LEN 64 +#define PUFS_SHA256_LEN 32 /** * @brief ECDSA256 quadrant and key lengths */ -#define RS_EC256_QLEN 32 -#define RS_EC256_KEY_LEN (32 * 2) +#define PUFS_EC256_QLEN 32 +#define PUFS_EC256_KEY_LEN (32 * 2) /** * @brief RSA 2048 public key modulus length * */ -#define RS_RSA_2048_LEN 256 - -/** - * @brief RSA 2048 public key exponent length - */ -#define RS_RSA_E_LEN 4 - -/** - * @brief RSA 2048 public key length - */ -#define RS_RSA_2048_KEY_LEN (RS_RSA_2048_LEN + RS_RSA_E_LEN) - -/** - * @brief IV length for AES-CTR128 - */ -#define RS_AES_CTR128_IV_EN 16 - -/** - * @brief Key length for AES128 - */ -#define RS_AES16_KEY_LEN 16 - -/** - * @brief Key length for AES256 - */ -#define RS_AES32_KEY_LEN 32 +#define PUFS_RSA_2048_LEN 256 /***************************************************************************** * Enumerations @@ -250,6 +225,15 @@ enum pufcc_sp38a_mode { PUFCC_CTR128 }; +/** + * @enum pufs_crypto_tfr_type + * @brief Types of secure transfer type in case of peripherals + */ +enum pufs_crypto_tfr_type { + PUFS_SECURE_TX, // Write to peripheral + PUFS_SECURE_RX // Read from peripheral +}; + // Scatter gather DMA descriptor struct struct pufcc_sg_dma_desc { uint32_t read_addr; @@ -261,151 +245,6 @@ struct pufcc_sg_dma_desc { uint32_t cypt_cfg[2]; }; -/** - * @enum rs_crypto_status - * @brief Enum for crypto specific status values - * - */ -enum rs_crypto_status { - CRYPTO_SUCCESS = 0, - NULL_POINTER = 1, - MEM_UNAVAILABLE = 2, - CRYPTO_INIT_ERROR = 3, - RSA_VERIFY_ERROR = 4, - ECDSA_VERIFY_ERROR = 5, - DECRYPTION_ERROR = 6, - HASH_CALC_ERROR = 7, - ECP_CONFIG_ERROR = 8, - INVALID_RSA_TYPE = 9, - INVALID_HASH_ALGO = 10, - INVALID_ENCRYPTION_ALGO = 11, - INVALID_SIGNING_ALGO = 12, - INVALID_CIPHER_TYPE = 13, - BOP_IMAGE_NOT_FOUND = 14, - INVALID_IMAGE_TYPE = 15, - KEY_WRITE_ERROR = 16, - KEY_READ_ERROR = 17, - KEY_LOCK_ERROR = 18, - INVALID_PUBLIC_KEY = 19, - INVALID_ENC_KEY = 20, - NON_SECURE_IMAGE = 21, - CRC_CHECK_FAILED = 22, - INVALID_KEY_SLOT = 23, - INVALID_KEY_SRC = 24, - NO_ENC_KEY = 25, - NO_ACCESS = 26, - DATA_TRANSFER_ERROR = 27, - KEY_NOT_IN_MANIFEST = 28, - CRYPTO_xCB_ERROR = 29, - INVALID_KEYS = 30, - NO_ACTIONS = 31, - INTEGRITY_CHECK_FAILED = 32, - CBUFFER_READ_ERROR = 33, - INVALID_TARGET_DEVICE = 34, - DECOMPRESSION_ERROR = 35, - INVALID_ACTION_CMD = 36, - INVALID_CMPR_ALGO = 37, - CBUFFER_DATA_CONSUMPTION_MISMATCH = 38, - ALL_ACTIONS_NOT_CONSUMED = 39, - MALFORMED_ACTION = 40, - LIFECYCLE_PROGRAMMING_ERROR = 41, - FLASH_PROGRAM_ERROR = 42, - FLASH_ERASE_ERROR = 43 -}; - -/** - * @enum rs_sign_algo - * @brief Enum for signing algorithms - * - */ -enum rs_crypto_sign_algo { - SIGN_ALGO_NULL = 0, - SIGN_ALGO_ECDSA256 = 0x10, - SIGN_ALGO_ECDSA384 = 0x11, - SIGN_ALGO_RSA2048 = 0x20, - SIGN_ALGO_BRAINPOOL256 = 0x30, - SIGN_ALGO_BRAINPOOL384 = 0x31, - SIGN_ALGO_SM2 = 0x40 -}; - -/** - * @enum rs_enc_algo - * @brief Enum for encryption algorithms - */ -enum rs_crypto_enc_algo { - ENC_ALGO_NULL = 0, - ENC_ALGO_AES128_CTR = 0x10, - ENC_ALGO_AES192_CTR = 0x11, - ENC_ALGO_AES256_CTR = 0x12, - ENC_ALGO_AES128_GCM = 0x20, - ENC_ALGO_AES192_GCM = 0x21, - ENC_ALGO_AES256_GCM = 0x22 -}; - -/** - * @enum rs_crypto_cipher - * @brief Symmetric cipher types - */ -enum rs_crypto_cipher { AES_CIPHER, SM4_CIPHER, CHACHA_CIPHER }; - -/** - * @enum rs_crypto_rsa_type - * @brief RSA types - */ -enum rs_crypto_rsa_type { RSA_1024, RSA_2048, RSA_3072, RSA_4096 }; - -/** - * @enum rs_crypto_key_src - * @brief Key source i.e. software or hardware - */ -enum rs_crypto_key_src { - RS_SW_KEY, // Software key in a buffer - RS_HW_KEY // Hardware/OTP based key -}; - -/** - * @enum rs_crypto_key_slots - * @brief RS defined key slots - */ -enum rs_crypto_key_slot { - RS_FSBL_RSA2048_PUBK_HASH_SLOT, - RS_FSBL_ECDSA256_PUBK_HASH_SLOT, - RS_FSBL_AES16_ENC_KEY_SLOT, - RS_FSBL_AES32_ENC_KEY_SLOT, - RS_ACPU_RSA2048_PUBK_HASH_SLOT, - RS_ACPU_ECDSA256_PUBK_HASH_SLOT, - RS_ACPU_AES16_ENC_KEY_SLOT, - RS_ACPU_AES32_ENC_KEY_SLOT, - RS_XCB_RSA2048_PUBK_HASH_SLOT, - RS_XCB_ECDSA256_PUBK_HASH_SLOT, - RS_XCB_AES16_ENC_KEY_SLOT, - RS_XCB_AES32_ENC_KEY_SLOT, - RS_LIFECYCLE_BITS_SLOT, - RS_CHIP_ID_SLOT, - RS_INVALID_KEY_SLOT, - RS_ALL_KEY_SLOTS // Used to indicate an operation on all valid key slots - // above -}; - -/** - * @enum rs_crypto_hash_type - * @brief Types of cryptographic hash algorithms - */ -enum rs_crypto_hash_type { SHA256 = 0x10, SHA384 = 0x11, SHA512 = 0x12 }; - -/** - * @enum rs_crypto_tfr_type - * @brief Types of secure transfer type in case of peripherals - */ -enum rs_crypto_tfr_type { - RS_SECURE_TX, // Write to peripheral - RS_SECURE_RX // Read from peripheral -}; - -enum rs_status { OK = 0, WOULD_BLOCK = 1, ERROR = 2 } __attribute__((packed)); - -typedef void (*rs_dma_callback_t)(void* app_data, int ch, int status); - /***************************************************************************** * Register structures ****************************************************************************/ @@ -625,52 +464,26 @@ struct pufcc_pkc_regs { volatile uint32_t ecp_data[512]; }; -struct pufcc_dma_dev { - struct pufcc_dma_regs *regs; - bool is_dev_free; - struct pufcc_sg_dma_desc *dma_descs; - uint32_t num_descriptors; - void *callback_args; - rs_dma_callback_t callback; -}; - /** - * @struct rs_crypto_addr + * @struct pufs_crypto_addr * @brief Address info for cryptographic operations */ -struct rs_crypto_addr { +struct pufs_crypto_addr { uint32_t read_addr; uint32_t write_addr; uint32_t len; - enum rs_crypto_tfr_type tfr_type; // Transfer type (read or write) in case of + enum pufs_crypto_tfr_type tfr_type; // Transfer type (read or write) in case of // peripherals, otherwise don't care bool periph_rw; // Indicates if data transfer involves a peripheral - struct rs_crypto_addr *next; // In case data lies at multiple locations + struct pufs_crypto_addr *next; // In case data lies at multiple locations }; /** - * @struct rs_crypto_key - * @brief Generic cryptographic key structure - */ -struct rs_crypto_key { - enum rs_crypto_key_src key_src; - uint8_t *key_addr; // For software key in a buffer - enum rs_crypto_key_slot key_slot; // For HW/OTP/eFuse based key - uint32_t key_len; - uint8_t *iv; - uint32_t iv_len; - bool readback_iv; // If true, read back updated IV value corresponding to - // number of processed data blocks during decryption into - // the iv buffer above. In this case iv buffer must be - // writable. -}; - -/** - * @struct rs_crypto_rsa2048_puk + * @struct pufs_crypto_rsa2048_puk * @brief RSA 2048 public key structure */ -struct rs_crypto_rsa2048_puk { - uint8_t n[RS_RSA_2048_LEN]; // Modulus +struct pufs_crypto_rsa2048_puk { + uint8_t n[PUFS_RSA_2048_LEN]; // Modulus uint32_t e; // Exponent }; @@ -679,96 +492,35 @@ struct rs_crypto_rsa2048_puk { * @brief ECDSA256 public key */ struct rs_crypto_ec256_puk { - uint8_t x[RS_EC256_QLEN]; - uint8_t y[RS_EC256_QLEN]; + uint8_t x[PUFS_EC256_QLEN]; + uint8_t y[PUFS_EC256_QLEN]; }; /** - * @struct rs_crypto_ec256_sig + * @struct pufs_crypto_ec256_sig * @brief ECDSA256 signature */ -struct rs_crypto_ec256_sig { - uint8_t r[RS_EC256_QLEN]; - uint8_t s[RS_EC256_QLEN]; +struct pufs_crypto_ec256_sig { + uint8_t r[PUFS_EC256_QLEN]; + uint8_t s[PUFS_EC256_QLEN]; }; /** - * @struct rs_crypto_hash + * @struct pufs_crypto_hash * @brief Hash structure */ -struct rs_crypto_hash { - uint8_t val[RS_SHA_MAX_LEN]; +struct pufs_crypto_hash { + uint8_t val[PUFS_SHA_MAX_LEN]; uint32_t len; }; -/** - * @enum rs_crypto_key_manifest - * @brief Key manifest structure - */ -struct rs_crypto_key_manifest { - uint32_t key_mask; // Key availability bitmask according to - // 'rs_crypto_key_slot' enum above - uint8_t fsbl_rsa2048_pubk_hash[32]; - uint8_t fsbl_ecdsa256_pubk_hash[32]; - uint8_t fsbl_aes128_enc_key[16]; - uint8_t fsbl_aes256_enc_key[32]; - uint8_t acpu_rsa2048_pubk_hash[32]; - uint8_t acpu_ecdsa256_pubk_hash[32]; - uint8_t acpu_aes128_enc_key[16]; - uint8_t acpu_aes256_enc_key[32]; - uint8_t xcb_rsa2048_pubk_hash[32]; - uint8_t xcb_ecdsa256_pubk_hash[32]; - uint8_t xcb_aes128_enc_key[16]; - uint8_t xcb_aes256_enc_key[32]; -}; - -enum rs_dma_addr_adjust { - RS_DMA_ADDR_ADJUST_INCREMENT = 0x0, - RS_DMA_ADDR_ADJUST_DECREMENT = 0x1, - RS_DMA_ADDR_ADJUST_FIXED = 0x2, -}; - -struct rs_dma_block_config { - uintptr_t src_addr; - uintptr_t dst_addr; - uint32_t block_size; - struct rs_dma_block_config* next_block; - enum rs_dma_addr_adjust src_addr_adjust; - enum rs_dma_addr_adjust dst_addr_adjust; +/* Device constant configuration parameters */ +struct pufcc_config { + void (*irq_init)(void); + uint32_t base; + uint32_t irq_num; }; -struct rs_dma_config { - // peripheral combination. Platform dependent - uint8_t dma_slot __attribute__((aligned(4))); - // What type of DMA transfer this is - uint8_t xfer_dir __attribute__((aligned(4))); - // enable callback on transfer complete - uint8_t complete_callback_en __attribute__((aligned(4))); - // enable callback on transfer error - uint8_t err_callback_en __attribute__((aligned(4))); - // select software or hardware handshaking on the source - uint8_t src_handshake_mode __attribute__((aligned(4))); - // select software or hardware handshaking on the dest - uint8_t dst_handshake_mode __attribute__((aligned(4))); - // priority of the transfer - uint8_t xfer_priority __attribute__((aligned(4))); - // width of src data in bytes - uint16_t src_data_size __attribute__((aligned(4))); - // width of dst data in bytes - uint16_t dst_data_size __attribute__((aligned(4))); - // length of data to be retrieved in each src transfer step - uint16_t src_burst_len __attribute__((aligned(4))); - // length of data to be written in each dest transfer step - uint16_t dst_burst_len __attribute__((aligned(4))); - // total amount of transfer blocks to be used - uint32_t block_count __attribute__((aligned(4))); - // first transfer descriptor - struct rs_dma_block_config* head_block __attribute__((aligned(4))); - // arguments to be passed as app_data to the dma callback - void* callback_args __attribute__((aligned(4))); - rs_dma_callback_t callback __attribute__((aligned(4))); -} __attribute__((aligned(4))); - /* The following macro can be used to write register values. REG_WRITE_32(Destination_Addr, Source_Addr) From 591feccb1b7d5bbb514082d2dd288e1896c82409 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 11 Sep 2024 23:02:21 +0500 Subject: [PATCH 03/58] PUFcc Support in Progress --- drivers/crypto/crypto_pufs.c | 102 +++++++++++++++-------- drivers/crypto/crypto_pufs.h | 2 +- soc/rapidsilicon/virgo/Kconfig | 2 +- soc/rapidsilicon/virgo/Kconfig.defconfig | 8 +- 4 files changed, 72 insertions(+), 42 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 7e1da6fd61322..ab0a564f5de0e 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -2,9 +2,9 @@ #include -#include #include #include +#include #define LOG_LEVEL CONFIG_CRYPTO_LOG_LEVEL #include @@ -888,18 +888,6 @@ enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, return PUFCC_SUCCESS; } -// static void pufs_irq_handler(const struct device *dev) { -// int status = (dev->regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); -// struct pufcc_intrpt_reg *intrpt_reg_ptr = -// (struct pufcc_intrpt_reg *)&dev->regs->interrupt; - -// // Clear and disable interrupt -// intrpt_reg_ptr->intrpt_st = 1; // Set to clear -// intrpt_reg_ptr->intrpt_en = 0; - -// dev->callback(dev->callback_args, 0, status); -// } - /** * @fn rsa_p1v15_verify * @brief Verify input RSA2048 decrypted message according to PKCS#1 v1.5 RSA @@ -1048,26 +1036,68 @@ static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, return PUFCC_SUCCESS; } -// static int crypto_pufs_init(const struct device *dev) { -// enum pufcc_status status; - -// // Initialize base addresses of different PUFcc modules -// dma_regs = (struct pufcc_dma_regs *)dev->config; -// rt_regs = (struct pufcc_rt_regs *)(base_addr + PUFCC_RT_OFFSET); -// otp_mem = (struct pufcc_otp_mem *)(base_addr + PUFCC_RT_OFFSET + -// PUFCC_RT_OTP_OFFSET); -// hmac_regs = (struct pufcc_hmac_regs *)(base_addr + PUFCC_HMAC_OFFSET); -// crypto_regs = (struct pufcc_crypto_regs *)(base_addr + PUFCC_CRYPTO_OFFSET); -// sp38a_regs = (struct pufcc_sp38a_regs *)(base_addr + PUFCC_SP38A_OFFSET); -// pkc_regs = (struct pufcc_pkc_regs *)(base_addr + PUFCC_PKC_OFFSET); - -// // Wait for OTP setup -// status = pufcc_otp_setup_wait(); - -// return status; -// } - -// DEVICE_DT_INST_DEFINE(0, crypto_pufs_init, NULL, -// &crypto_stm32_dev_data, -// &crypto_stm32_dev_config, POST_KERNEL, -// CONFIG_CRYPTO_INIT_PRIORITY, (void *)&crypto_enc_funcs); \ No newline at end of file +static int crypto_pufs_init(const struct device *dev) { + enum pufcc_status status; + + // Initialize base addresses of different PUFcc modules + dma_regs = (struct pufcc_dma_regs *)((struct pufs_config*)dev->config)->base; + rt_regs = (struct pufcc_rt_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_RT_OFFSET); + otp_mem = (struct pufcc_otp_mem *)(((struct pufs_config*)dev->config)->base + PUFCC_RT_OFFSET + + PUFCC_RT_OTP_OFFSET); + hmac_regs = (struct pufcc_hmac_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_HMAC_OFFSET); + crypto_regs = (struct pufcc_crypto_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_CRYPTO_OFFSET); + sp38a_regs = (struct pufcc_sp38a_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_SP38A_OFFSET); + pkc_regs = (struct pufcc_pkc_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_PKC_OFFSET); + + // Wait for OTP setup + status = pufcc_otp_setup_wait(); + + return status; +} + +static void pufs_irq_handler(void) { // TODO + // int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); + struct pufcc_intrpt_reg *intrpt_reg_ptr = + (struct pufcc_intrpt_reg *)&dma_regs->interrupt; + + // Clear and disable interrupt + intrpt_reg_ptr->intrpt_st = 1; // Set to clear + intrpt_reg_ptr->intrpt_en = 0; + + // dev->callback(dev->callback_args, 0, status); +} + +void pufs_irq_Init(void) { + IRQ_CONNECT( + DT_INST_IRQN(0), + DT_INST_IRQ(0, priority), + pufs_irq_handler, + 0, // TODO pass here hash, sign and dec callback struct + 0 + ); + + // enable PUFs IRQ + irq_enable(DT_INST_IRQN(0)); +} + +static struct crypto_driver_api crypto_dec_funcs = { + .cipher_begin_session = NULL, /* TBD */ + .cipher_free_session = NULL, /* TBD */ + .cipher_async_callback_set = NULL, /* TBD */ + .hash_begin_session = NULL, /* TBD */ + .hash_free_session = NULL, /* TBD */ + .hash_async_callback_set = NULL, /* TBD */ + .query_hw_caps = NULL /* TBD */ +}; + +static const struct pufs_config pufs_configuration = { + .base = DT_INST_REG_ADDR(0), + .irq_num = DT_INST_IRQN(0), + .irq_init = pufs_irq_Init +}; + + +DEVICE_DT_INST_DEFINE(0, crypto_pufs_init, NULL, + NULL, + &pufs_configuration, POST_KERNEL, + CONFIG_CRYPTO_INIT_PRIORITY, (void *)&crypto_dec_funcs); \ No newline at end of file diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index 6d186d84f9a4b..edfadf96d4e2a 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -515,7 +515,7 @@ struct pufs_crypto_hash { }; /* Device constant configuration parameters */ -struct pufcc_config { +struct pufs_config { void (*irq_init)(void); uint32_t base; uint32_t irq_num; diff --git a/soc/rapidsilicon/virgo/Kconfig b/soc/rapidsilicon/virgo/Kconfig index 428b56f7e5cbf..185fef7356901 100644 --- a/soc/rapidsilicon/virgo/Kconfig +++ b/soc/rapidsilicon/virgo/Kconfig @@ -28,7 +28,7 @@ if GEN_IRQ_VECTOR_TABLE endchoice config RISCV_MCAUSE_EXCEPTION_MASK - default 0x1F + default 0x32 endif diff --git a/soc/rapidsilicon/virgo/Kconfig.defconfig b/soc/rapidsilicon/virgo/Kconfig.defconfig index 7e05011ae8502..760cc620aded2 100644 --- a/soc/rapidsilicon/virgo/Kconfig.defconfig +++ b/soc/rapidsilicon/virgo/Kconfig.defconfig @@ -29,18 +29,18 @@ config NUM_2ND_LEVEL_AGGREGATORS default 1 config 2ND_LVL_ISR_TBL_OFFSET - default 16 + default 12 config 2ND_LVL_INTR_00_OFFSET - default 16 + default 11 config MAX_IRQ_PER_AGGREGATOR - default 16 + default 52 config 2ND_LEVEL_INTERRUPT_BITS default 8 config NUM_IRQS - default 32 + default 50 endif # SOC_SERIES_VIRGO \ No newline at end of file From c0efa739d46a491e34e4c6b2debc54ab79134626 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 12 Sep 2024 21:12:46 +0500 Subject: [PATCH 04/58] PUFcc Support in Progress --- drivers/crypto/crypto_pufs.c | 57 +++++++++++++++++++++++------------- drivers/crypto/crypto_pufs.h | 21 ++++++++++++- 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index ab0a564f5de0e..271ead8154da5 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -4,7 +4,6 @@ #include #include -#include #define LOG_LEVEL CONFIG_CRYPTO_LOG_LEVEL #include @@ -1052,10 +1051,13 @@ static int crypto_pufs_init(const struct device *dev) { // Wait for OTP setup status = pufcc_otp_setup_wait(); + // Connect the IRQ + ((struct pufs_config*)dev->config)->irq_init((struct pufs_config*)dev->config); + return status; } -static void pufs_irq_handler(void) { // TODO +static void pufs_irq_handler(const struct device *dev) { // TODO // int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); struct pufcc_intrpt_reg *intrpt_reg_ptr = (struct pufcc_intrpt_reg *)&dma_regs->interrupt; @@ -1064,40 +1066,53 @@ static void pufs_irq_handler(void) { // TODO intrpt_reg_ptr->intrpt_st = 1; // Set to clear intrpt_reg_ptr->intrpt_en = 0; - // dev->callback(dev->callback_args, 0, status); + // Disable IRQ as the next asynch callback registeration shall enable it again. + irq_disable(((struct pufs_config*)dev->config)->irq_num); } -void pufs_irq_Init(void) { +static void pufs_irq_Init(const struct pufs_config *inConfig) { IRQ_CONNECT( DT_INST_IRQN(0), DT_INST_IRQ(0, priority), pufs_irq_handler, - 0, // TODO pass here hash, sign and dec callback struct + DEVICE_DT_INST_GET(0), 0 ); - - // enable PUFs IRQ - irq_enable(DT_INST_IRQN(0)); + /* + * The IRQs will only be enabled in + * xyz_async_callback_set interfaces + * Inside the IRQ Handler we will disable + * the IRQ since we support only single + * session at any moment. + */ } -static struct crypto_driver_api crypto_dec_funcs = { - .cipher_begin_session = NULL, /* TBD */ - .cipher_free_session = NULL, /* TBD */ - .cipher_async_callback_set = NULL, /* TBD */ - .hash_begin_session = NULL, /* TBD */ - .hash_free_session = NULL, /* TBD */ - .hash_async_callback_set = NULL, /* TBD */ - .query_hw_caps = NULL /* TBD */ +static struct crypto_driver_api s_crypto_funcs = { + .cipher_begin_session = NULL, /* TODO */ + .cipher_free_session = NULL, /* TODO */ + .cipher_async_callback_set = NULL, /* TODO */ + .hash_begin_session = NULL, /* TODO */ + .hash_free_session = NULL, /* TODO */ + .hash_async_callback_set = NULL, /* TODO */ + .query_hw_caps = NULL /* TODO */ +}; + +static struct pufs_data s_pufs_session_data = { + .pufs_session_type = PUFS_SESSION_UNDEFINED, + .session_callback = NULL }; -static const struct pufs_config pufs_configuration = { +static const struct pufs_config s_pufs_configuration = { .base = DT_INST_REG_ADDR(0), .irq_num = DT_INST_IRQN(0), - .irq_init = pufs_irq_Init + .irq_init = pufs_irq_Init, + .irq_priority = DT_INST_IRQ(0, priority), + .dev = DEVICE_DT_INST_GET(0) }; DEVICE_DT_INST_DEFINE(0, crypto_pufs_init, NULL, - NULL, - &pufs_configuration, POST_KERNEL, - CONFIG_CRYPTO_INIT_PRIORITY, (void *)&crypto_dec_funcs); \ No newline at end of file + &s_pufs_session_data, + &s_pufs_configuration, POST_KERNEL, + CONFIG_CRYPTO_INIT_PRIORITY, (void *)&s_crypto_funcs); + \ No newline at end of file diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index edfadf96d4e2a..1229deb0427c4 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -12,6 +12,7 @@ #include #include #include +#include /*** Generic PUFcc defines ***/ #define PUFCC_WORD_SIZE 4 @@ -234,6 +235,13 @@ enum pufs_crypto_tfr_type { PUFS_SECURE_RX // Read from peripheral }; +enum pufs_session_type { + PUFS_SESSION_SIGN_VERIFICATION = 0, + PUFS_SESSION_HASH_CALCULATION, + PUFS_SESSION_DECRYPTION, + PUFS_SESSION_UNDEFINED +}; + // Scatter gather DMA descriptor struct struct pufcc_sg_dma_desc { uint32_t read_addr; @@ -514,11 +522,22 @@ struct pufs_crypto_hash { uint32_t len; }; +/* Generic Callback Signature for different Sessions */ +typedef void (*session_completion_cb)(void *completed, int status); + +/* Device constant configuration parameters */ +struct pufs_data { + enum pufs_session_type pufs_session_type; + session_completion_cb session_callback; +}; + /* Device constant configuration parameters */ struct pufs_config { - void (*irq_init)(void); + void (*irq_init)(const struct pufs_config*); uint32_t base; uint32_t irq_num; + uint32_t irq_priority; + const struct device *dev; }; /* From 134fa253e78f7e92bfcc975f7125eaeb265d467f Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 16 Sep 2024 16:26:43 +0500 Subject: [PATCH 05/58] PUFcc Support in Progress --- drivers/crypto/crypto_pufs.c | 3 +- include/zephyr/crypto/crypto.h | 10 ++ include/zephyr/crypto/sign.h | 179 +++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+), 2 deletions(-) create mode 100644 include/zephyr/crypto/sign.h diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 271ead8154da5..67b0e9e37cfdc 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -114,7 +114,7 @@ enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, * @brief Calculates SHA256 hash * * @param[in] data_addr Data address info - * @param[in] hash Pointer to hash strcut to return hash value in + * @param[in] hash Pointer to hash struct to return hash value in * @return PUFCC_SUCCESS on success, otherwise an error code. */ enum pufcc_status pufcc_calc_sha256_hash(struct pufs_crypto_addr *data_addr, @@ -1115,4 +1115,3 @@ DEVICE_DT_INST_DEFINE(0, crypto_pufs_init, NULL, &s_pufs_session_data, &s_pufs_configuration, POST_KERNEL, CONFIG_CRYPTO_INIT_PRIORITY, (void *)&s_crypto_funcs); - \ No newline at end of file diff --git a/include/zephyr/crypto/crypto.h b/include/zephyr/crypto/crypto.h index b2e0b0f6e4439..d85e1a97509cb 100644 --- a/include/zephyr/crypto/crypto.h +++ b/include/zephyr/crypto/crypto.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "cipher.h" /** @@ -88,6 +89,15 @@ __subsystem struct crypto_driver_api { /* Register async hash op completion callback with the driver */ int (*hash_async_callback_set)(const struct device *dev, hash_completion_cb cb); + + /* Setup a signature session */ + int (*sign_begin_session)(const struct device *dev, struct sign_ctx *ctx, + enum sign_algo algo); + /* Tear down an established signature session */ + int (*sign_free_session)(const struct device *dev, struct sign_ctx *ctx); + /* Register async signature op completion callback with the driver */ + int (*sign_async_callback_set)(const struct device *dev, + sign_completion_cb cb); }; /* Following are the public API a user app may call. diff --git a/include/zephyr/crypto/sign.h b/include/zephyr/crypto/sign.h new file mode 100644 index 0000000000000..0f7dacab7efa9 --- /dev/null +++ b/include/zephyr/crypto/sign.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2024 Rapid Silicon + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Crypto Signature APIs + * + * This file contains the Crypto Abstraction layer APIs. + */ +#ifndef ZEPHYR_INCLUDE_CRYPTO_SIGN_H_ +#define ZEPHYR_INCLUDE_CRYPTO_SIGN_H_ + + +/** + * @addtogroup crypto_sign + * @{ + */ + + +/** + * Hash algorithm + */ +enum sign_algo { + CRYPTO_SIGN_ALGO_RSA2048 = 0, + CRYPTO_SIGN_ALGO_ECDSA256 = 1 +}; + +/* Forward declarations */ +struct sign_ctx; +struct sign_pkt; + + +typedef int (*sign_op_t)(struct sign_ctx *ctx, struct sign_pkt *pkt, + bool finish); + +/* Function signatures for sign verification using standard signing algorithms + * like RSA2048, ECDSA256. + */ +typedef int (*rsa_op_t)(struct sign_ctx *ctx, struct sign_pkt *pkt, bool finish); + +typedef int (*ecdsa_op_t)(struct sign_ctx *ctx, struct sign_pkt *pkt, bool finish); + +struct sign_ops { + + enum sign_algo signing_algo; + + union { + sign_op_t sign_op_hndlr; + rsa_op_t rsa_crypt_hndlr; + ecdsa_op_t ecdsa_crypt_hndlr; + }; +}; + +/** + * Structure encoding session parameters. + * + * Refer to comments for individual fields to know the contract + * in terms of who fills what and when w.r.t begin_session() call. + */ +struct sign_ctx { + + /** Place for driver to return function pointers to be invoked per + * sign operation. To be populated by crypto driver on return from + * begin_session() based on the algo/mode chosen by the app. + */ + struct sign_ops ops; + + /** To be populated by the app before calling begin_session() */ + union { + /* Cryptographic key to be used in this session */ + const uint8_t *bit_stream; + /* For cases where key is protected and is not + * available to caller + */ + void *handle; + } pub_key; + + /** To be populated by the app before calling begin_session() */ + union { + /* Signature to be used in this session */ + const uint8_t *bit_stream; + /* For cases where signature is protected and is not + * available to caller + */ + void *handle; + } signature; + + /** The device driver instance this crypto context relates to. Will be + * populated by the begin_session() API. + */ + const struct device *device; + + /** If the driver supports multiple simultaneously crypto sessions, this + * will identify the specific driver state this crypto session relates + * to. Since dynamic memory allocation is not possible, it is + * suggested that at build time drivers allocate space for the + * max simultaneous sessions they intend to support. To be populated + * by the driver on return from begin_session(). + */ + void *drv_sessn_state; + + /** Place for the user app to put info relevant stuff for resuming when + * completion callback happens for async ops. Totally managed by the + * app. + */ + void *app_sessn_state; + + /** Cryptographic keylength in bytes. To be populated by the app + * before calling begin_session() + */ + uint16_t pub_key_len; + + /** Signature length in bytes. To be populated by the app + * before calling begin_session() + */ + uint16_t sign_len; + + /** How certain fields are to be interpreted for this session. + * (A bitmask of CAP_* below.) + * To be populated by the app before calling begin_session(). + * An app can obtain the capability flags supported by a hw/driver + * by calling crypto_query_hwcaps(). + */ + uint16_t flags; +}; + +/** + * Structure encoding IO parameters of one cryptographic + * operation like encrypt/decrypt. + * + * The fields which has not been explicitly called out has to + * be filled up by the app before making the sign_xxx_op() + * call. + */ +struct sign_pkt { + + /** Start address of input buffer */ + uint8_t *in_buf; + + /** Bytes to be operated upon */ + int in_len; + + /** Start of the output buffer, to be allocated by + * the application. Can be NULL for in-place ops. To be populated + * with contents by the driver on return from op / async callback. + */ + uint8_t *out_buf; + + /** Size of the out_buf area allocated by the application. Drivers + * should not write past the size of output buffer. + */ + int out_buf_max; + + /** To be populated by driver on return from sign_xxx_op() and + * holds the size of the actual result. + */ + int out_len; + + /** Context this packet relates to. This can be useful to get the + * session details, especially for async ops. Will be populated by the + * sign_xxx_op() API based on the ctx parameter. + */ + struct sign_ctx *ctx; +}; + +/* Prototype for the application function to be invoked by the crypto driver + * on completion of an async request. The app may get the session context + * via the pkt->ctx field. + */ +typedef void (*sign_completion_cb)(struct sign_pkt *completed, int status); + + +/** + * @} + */ +#endif /* ZEPHYR_INCLUDE_CRYPTO_SIGN_H_ */ From 15c0e6c693d27c1ba8a03498b02dd5a7a47687ed Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 18 Sep 2024 21:57:48 +0500 Subject: [PATCH 06/58] PUFcc Support in Progress --- include/zephyr/crypto/crypto.h | 125 ++++++++++++++++++++++++++++++++- include/zephyr/crypto/hash.h | 5 ++ include/zephyr/crypto/sign.h | 25 ++++--- 3 files changed, 143 insertions(+), 12 deletions(-) diff --git a/include/zephyr/crypto/crypto.h b/include/zephyr/crypto/crypto.h index d85e1a97509cb..44c76ec80a532 100644 --- a/include/zephyr/crypto/crypto.h +++ b/include/zephyr/crypto/crypto.h @@ -41,14 +41,14 @@ * supported config during the session setup. */ #define CAP_OPAQUE_KEY_HNDL BIT(0) -#define CAP_RAW_KEY BIT(1) +#define CAP_RAW_KEY BIT(1) /* TBD to define */ #define CAP_KEY_LOADING_API BIT(2) /** Whether the output is placed in separate buffer or not */ #define CAP_INPLACE_OPS BIT(3) -#define CAP_SEPARATE_IO_BUFS BIT(4) +#define CAP_SEPARATE_IO_BUFS BIT(4) /** * These denotes if the output (completion of a cipher_xxx_op) is conveyed @@ -481,7 +481,7 @@ static inline int hash_compute(struct hash_ctx *ctx, struct hash_pkt *pkt) } /** - * @brief Perform a cryptographic multipart hash operation. + * @brief Perform a cryptographic multipart hash operation. * * This function can be called zero or more times, passing a slice of the * the data. The hash is calculated using all the given pieces. @@ -503,4 +503,123 @@ static inline int hash_update(struct hash_ctx *ctx, struct hash_pkt *pkt) * @} */ +/** + * @brief Setup a signing / sign_verification session + * + * Initializes one time parameters, like the algorithm which may + * remain constant for all operations in the session. The state may be + * cached in hardware and/or driver data state variables. + * + * @param dev Pointer to the device structure for the driver instance. + * @param ctx Pointer to the context structure. Various one time + * parameters like session capabilities and algorithm are + * supplied via this structure. The structure documentation + * specifies which fields are to be populated by the app + * before making this call. + * @param algo The algorithm to be used in this session. e.g RSA2048 or ECDSA256 + * + * @return 0 on success, negative errno code on fail. + */ +static inline int sign_begin_session(const struct device *dev, + struct sign_ctx *ctx, + enum sign_algo algo) +{ + uint32_t flags; + struct crypto_driver_api *api; + + api = (struct crypto_driver_api *) dev->api; + ctx->device = dev; + + flags = (ctx->flags & (CAP_INPLACE_OPS | CAP_SEPARATE_IO_BUFS)); + __ASSERT(flags != 0U, "IO buffer type missing"); + __ASSERT(flags != (CAP_INPLACE_OPS | CAP_SEPARATE_IO_BUFS), + "conflicting options for IO buffer type"); + + flags = (ctx->flags & (CAP_SYNC_OPS | CAP_ASYNC_OPS)); + __ASSERT(flags != 0U, "sync/async type missing"); + __ASSERT(flags != (CAP_SYNC_OPS | CAP_ASYNC_OPS), + "conflicting options for sync/async"); + + + return api->sign_begin_session(dev, ctx, algo); +} + +/** + * @brief Cleanup a signing / sign_verification session + * + * Clears the hardware and/or driver state of a session. @see sign_begin_session + * + * @param dev Pointer to the device structure for the driver instance. + * @param ctx Pointer to the crypto signing / sign_verification context structure of the session + * to be freed. + * + * @return 0 on success, negative errno code on fail. + */ +static inline int sign_free_session(const struct device *dev, + struct sign_ctx *ctx) +{ + struct crypto_driver_api *api; + + api = (struct crypto_driver_api *) dev->api; + + return api->sign_free_session(dev, ctx); +} + +/** + * @brief Registers an async signing / sign_verification completion callback with the driver + * + * The application can register an async signing / sign_verification completion callback + * handler to be invoked by the driver, on completion of a prior request submitted via + * sign_op_handler. Based on crypto device hardware semantics, this is likely to + * be invoked from an ISR context. + * + * @param dev Pointer to the device structure for the driver instance. + * @param cb Pointer to application callback to be called by the driver. + * + * @return 0 on success, -ENOTSUP if the driver does not support async op, + * negative errno code on other error. + */ +static inline int sign_callback_set(const struct device *dev, + sign_completion_cb cb) +{ + struct crypto_driver_api *api; + + api = (struct crypto_driver_api *) dev->api; + + if (api->sign_async_callback_set) { + return api->sign_async_callback_set(dev, cb); + } + + return -ENOTSUP; +} + +/** + * @brief Perform a cryptographic signing / verification operation. + * + * @param ctx Pointer to the sign context of this op. + * @param pkt Structure holding the input. + * @return 0 on success, negative errno code on fail. + */ +static inline int sign_op_handler(struct sign_ctx *ctx, struct sign_pkt *pkt) +{ + pkt->ctx = ctx; + + if(ctx->ops.signing_algo == CRYPTO_SIGN_ALGO_RSA2048) { + pkt->ctx = ctx; + if(ctx->ops.rsa_crypt_hndlr == NULL) { + return -EBADFD; + } + return ctx->ops.rsa_crypt_hndlr(ctx, pkt); + } + else if(ctx->ops.signing_algo == CRYPTO_SIGN_ALGO_ECDSA256) { + if(ctx->ops.ecdsa_crypt_hndlr == NULL) { + return -EBADFD; + } + return ctx->ops.ecdsa_crypt_hndlr(ctx, pkt); + } + + return -ENOTSUP; + +} + #endif /* ZEPHYR_INCLUDE_CRYPTO_H_ */ diff --git a/include/zephyr/crypto/hash.h b/include/zephyr/crypto/hash.h index c2f548406c86f..f7775e058ed2c 100644 --- a/include/zephyr/crypto/hash.h +++ b/include/zephyr/crypto/hash.h @@ -90,6 +90,11 @@ struct hash_pkt { /** Start address of input buffer */ uint8_t *in_buf; + /** Start address of previously calculated hash / digest. + * It is useful where hash is calculated in chunks. + */ + uint8_t *in_hash; + /** Bytes to be operated upon */ size_t in_len; diff --git a/include/zephyr/crypto/sign.h b/include/zephyr/crypto/sign.h index 0f7dacab7efa9..057901e778573 100644 --- a/include/zephyr/crypto/sign.h +++ b/include/zephyr/crypto/sign.h @@ -21,34 +21,41 @@ /** - * Hash algorithm + * Signing algorithm */ enum sign_algo { CRYPTO_SIGN_ALGO_RSA2048 = 0, CRYPTO_SIGN_ALGO_ECDSA256 = 1 }; +/** + * Signing Mode + */ +enum sign_mode { + CRYPTO_SIGN_COMPUTE = 0, + CRYPTO_SIGN_VERIFY = 1 +}; + /* Forward declarations */ struct sign_ctx; struct sign_pkt; - -typedef int (*sign_op_t)(struct sign_ctx *ctx, struct sign_pkt *pkt, - bool finish); - /* Function signatures for sign verification using standard signing algorithms * like RSA2048, ECDSA256. */ -typedef int (*rsa_op_t)(struct sign_ctx *ctx, struct sign_pkt *pkt, bool finish); - -typedef int (*ecdsa_op_t)(struct sign_ctx *ctx, struct sign_pkt *pkt, bool finish); +typedef int (*rsa_op_t)(struct sign_ctx *ctx, struct sign_pkt *pkt); +typedef int (*ecdsa_op_t)(struct sign_ctx *ctx, struct sign_pkt *pkt); struct sign_ops { + /* + The signing algorithm and mode shall be set by the User. + */ enum sign_algo signing_algo; + enum sign_mode signing_mode; + // This anonymous union members are to be set by the driver. union { - sign_op_t sign_op_hndlr; rsa_op_t rsa_crypt_hndlr; ecdsa_op_t ecdsa_crypt_hndlr; }; From dbc00489989ef8040bfceed2c011b88dff8eb1a9 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 18 Sep 2024 22:31:36 +0500 Subject: [PATCH 07/58] PUFcc Support in Progress --- drivers/crypto/crypto_pufs.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 67b0e9e37cfdc..54f322e908343 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -1094,6 +1094,9 @@ static struct crypto_driver_api s_crypto_funcs = { .hash_begin_session = NULL, /* TODO */ .hash_free_session = NULL, /* TODO */ .hash_async_callback_set = NULL, /* TODO */ + .sign_begin_session = NULL, /* TODO */ + .sign_free_session = NULL, /* TODO */ + .sign_async_callback_set = NULL, /* TODO */ .query_hw_caps = NULL /* TODO */ }; From 3614618f3c944fd118a2b0ed97d96be95477d9de Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 18 Sep 2024 23:35:26 +0500 Subject: [PATCH 08/58] PUFcc Support in Progress --- drivers/crypto/crypto_pufs.c | 54 +++++++++++++++++++++++++++++------- drivers/crypto/crypto_pufs.h | 10 +++++-- 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 54f322e908343..dddb923d833df 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -117,7 +117,7 @@ enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, * @param[in] hash Pointer to hash struct to return hash value in * @return PUFCC_SUCCESS on success, otherwise an error code. */ -enum pufcc_status pufcc_calc_sha256_hash(struct pufs_crypto_addr *data_addr, +static enum pufcc_status pufcc_calc_sha256_hash(struct pufs_crypto_addr *data_addr, struct pufs_crypto_hash *hash) { enum pufcc_status status; struct pufcc_intrpt_reg intrpt_reg = {0}; @@ -233,7 +233,7 @@ enum pufcc_status pufcc_calc_sha256_hash(struct pufs_crypto_addr *data_addr, * @param[out] hash_out Pointer to hash strcut to return hash value in * @return PUFCC_SUCCESS on success, otherwise an error code. */ -enum pufcc_status pufcc_calc_sha256_hash_sg(struct pufs_crypto_addr *data_addr, +static enum pufcc_status pufcc_calc_sha256_hash_sg(struct pufs_crypto_addr *data_addr, bool first, bool last, uint32_t *prev_len, struct pufs_crypto_hash *hash_in, @@ -376,7 +376,7 @@ enum pufcc_status pufcc_calc_sha256_hash_sg(struct pufs_crypto_addr *data_addr, * * @return PUFCC_SUCCESS on success, otherwise an error code */ -enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, +static enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, uint32_t in_len, uint32_t prev_len, enum pufcc_key_type key_type, uint32_t key_addr, uint32_t key_len, @@ -495,7 +495,7 @@ enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, * @param[in] pub_key RSA2048 public key * @return PUFCC_SUCCESS on success, otherwise an error code. */ -enum pufcc_status pufcc_rsa2048_sign_verify( +static enum pufcc_status pufcc_rsa2048_sign_verify( uint8_t *sig, struct pufs_crypto_addr *msg_addr, struct pufs_crypto_rsa2048_puk *pub_key) { enum pufcc_status status = PUFCC_SUCCESS; @@ -567,7 +567,7 @@ enum pufcc_status pufcc_rsa2048_sign_verify( * @param[in] pub_key ECDSA256 public key * @return PUFCC_SUCCESS on success, otherwise an error code. */ -enum pufcc_status pufcc_ecdsa256_sign_verify( +static enum pufcc_status pufcc_ecdsa256_sign_verify( struct pufs_crypto_ec256_sig *sig, struct pufs_crypto_addr *msg_addr, struct rs_crypto_ec256_puk *pub_key) { uint32_t temp32, prev_len = 0; @@ -661,7 +661,7 @@ enum pufcc_status pufcc_ecdsa256_sign_verify( * * @return PUFCC_SUCCESS if OTP is setup successfully, otherwise an error code */ -enum pufcc_status pufcc_otp_setup_wait(void) { +static enum pufcc_status pufcc_otp_setup_wait(void) { enum pufcc_status status = busy_wait(&rt_regs->status, PUFCC_RT_ERROR_MASK); return status; @@ -1052,12 +1052,12 @@ static int crypto_pufs_init(const struct device *dev) { status = pufcc_otp_setup_wait(); // Connect the IRQ - ((struct pufs_config*)dev->config)->irq_init((struct pufs_config*)dev->config); + ((struct pufs_config*)dev->config)->irq_init(); return status; } -static void pufs_irq_handler(const struct device *dev) { // TODO +static void pufs_irq_handler(const struct device *dev) { // TODO callback invocation in it // int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); struct pufcc_intrpt_reg *intrpt_reg_ptr = (struct pufcc_intrpt_reg *)&dma_regs->interrupt; @@ -1070,7 +1070,7 @@ static void pufs_irq_handler(const struct device *dev) { // TODO irq_disable(((struct pufs_config*)dev->config)->irq_num); } -static void pufs_irq_Init(const struct pufs_config *inConfig) { +static void pufs_irq_Init(void) { IRQ_CONNECT( DT_INST_IRQN(0), DT_INST_IRQ(0, priority), @@ -1087,6 +1087,40 @@ static void pufs_irq_Init(const struct pufs_config *inConfig) { */ } +/******************************************************** + * Following set of APIs are in compliance with the + * Zephyr user level Crypto API. These APIs will then + * subsequently call local functions for performing + * various crypto related operations. +*********************************************************/ + +/* Query the hardware capabilities */ +int pufs_query_hw_caps(const struct device *dev) +{ + return -ENOTSUP; +} + +/* Setup a crypto session */ +int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx *ctx, + enum cipher_algo algo, enum cipher_mode mode, + enum cipher_op op_type) +{ + return -ENOTSUP; +} + +/* Tear down an established session */ +int pufs_cipher_free_session(const struct device *dev, struct cipher_ctx *ctx) +{ + return -ENOTSUP; +} + +/* Register async crypto op completion callback with the driver */ +int cipher_async_callback_set(const struct device *dev, + cipher_completion_cb cb) +{ + return -ENOTSUP; +} + static struct crypto_driver_api s_crypto_funcs = { .cipher_begin_session = NULL, /* TODO */ .cipher_free_session = NULL, /* TODO */ @@ -1102,7 +1136,7 @@ static struct crypto_driver_api s_crypto_funcs = { static struct pufs_data s_pufs_session_data = { .pufs_session_type = PUFS_SESSION_UNDEFINED, - .session_callback = NULL + .session_callback = {NULL} }; static const struct pufs_config s_pufs_configuration = { diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index 1229deb0427c4..43f22390b7643 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -523,17 +523,21 @@ struct pufs_crypto_hash { }; /* Generic Callback Signature for different Sessions */ -typedef void (*session_completion_cb)(void *completed, int status); +struct crypto_callbacks { + cipher_completion_cb cipher_cb; + hash_completion_cb hash_cb; + sign_completion_cb sign_cb; +}; /* Device constant configuration parameters */ struct pufs_data { enum pufs_session_type pufs_session_type; - session_completion_cb session_callback; + struct crypto_callbacks session_callback; }; /* Device constant configuration parameters */ struct pufs_config { - void (*irq_init)(const struct pufs_config*); + void (*irq_init)(void); uint32_t base; uint32_t irq_num; uint32_t irq_priority; From 92b19997f803b306ac1d66794dbebde93af1a6c2 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 19 Sep 2024 10:47:48 +0500 Subject: [PATCH 09/58] PUFcc Support in Progress --- drivers/crypto/crypto_pufs.c | 86 +++++++++++++++++++++++++++------- drivers/crypto/crypto_pufs.h | 2 +- include/zephyr/crypto/crypto.h | 30 ++++++++---- 3 files changed, 91 insertions(+), 27 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index dddb923d833df..f8607c7f13414 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -1,3 +1,10 @@ +/* + * Copyright (c) 2024 Rapid Silicon + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + #include "crypto_pufs.h" #include @@ -1094,14 +1101,19 @@ static void pufs_irq_Init(void) { * various crypto related operations. *********************************************************/ -/* Query the hardware capabilities */ -int pufs_query_hw_caps(const struct device *dev) +/* Query the driver capabilities */ +static int pufs_query_hw_caps(const struct device *dev) { - return -ENOTSUP; + return ( + CAP_RAW_KEY | CAP_INPLACE_OPS | \ + CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | \ + CAP_ASYNC_OPS | CAP_NO_IV_PREFIX | \ + CAP_NO_ENCRYPTION | CAP_NO_SIGNING + ); } /* Setup a crypto session */ -int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx *ctx, +static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx *ctx, enum cipher_algo algo, enum cipher_mode mode, enum cipher_op op_type) { @@ -1109,29 +1121,69 @@ int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx *ctx, } /* Tear down an established session */ -int pufs_cipher_free_session(const struct device *dev, struct cipher_ctx *ctx) +static int pufs_cipher_free_session(const struct device *dev, struct cipher_ctx *ctx) { return -ENOTSUP; } /* Register async crypto op completion callback with the driver */ -int cipher_async_callback_set(const struct device *dev, - cipher_completion_cb cb) +static int pufs_cipher_async_callback_set(const struct device *dev, + cipher_completion_cb cb) +{ + return -ENOTSUP; +} + +/* Setup a hash session */ +static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ctx, + enum hash_algo algo) +{ + return -ENOTSUP; +} + +/* Tear down an established hash session */ +static int pufs_hash_free_session(const struct device *dev, struct hash_ctx *ctx) +{ + return -ENOTSUP; +} + +/* Register async hash op completion callback with the driver */ +static int pufs_hash_async_callback_set(const struct device *dev, + hash_completion_cb cb) +{ + return -ENOTSUP; +} + +/* Setup a signature session */ +static int pufs_sign_begin_session(const struct device *dev, struct sign_ctx *ctx, + enum sign_algo algo) +{ + return -ENOTSUP; +} + +/* Tear down an established signature session */ +static int pufs_sign_free_session(const struct device *dev, struct sign_ctx *ctx) +{ + return -ENOTSUP; +} + +/* Register async signature op completion callback with the driver */ +static int pufs_sign_async_callback_set(const struct device *dev, + sign_completion_cb cb) { return -ENOTSUP; } static struct crypto_driver_api s_crypto_funcs = { - .cipher_begin_session = NULL, /* TODO */ - .cipher_free_session = NULL, /* TODO */ - .cipher_async_callback_set = NULL, /* TODO */ - .hash_begin_session = NULL, /* TODO */ - .hash_free_session = NULL, /* TODO */ - .hash_async_callback_set = NULL, /* TODO */ - .sign_begin_session = NULL, /* TODO */ - .sign_free_session = NULL, /* TODO */ - .sign_async_callback_set = NULL, /* TODO */ - .query_hw_caps = NULL /* TODO */ + .cipher_begin_session = pufs_cipher_begin_session, + .cipher_free_session = pufs_cipher_free_session, + .cipher_async_callback_set = pufs_cipher_async_callback_set, + .hash_begin_session = pufs_hash_begin_session, + .hash_free_session = pufs_hash_free_session, + .hash_async_callback_set = pufs_hash_async_callback_set, + .sign_begin_session = pufs_sign_begin_session, + .sign_free_session = pufs_sign_free_session, + .sign_async_callback_set = pufs_sign_async_callback_set, + .query_hw_caps = pufs_query_hw_caps }; static struct pufs_data s_pufs_session_data = { diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index 43f22390b7643..e08165ff19d01 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Muhammad Junaid Aslam + * Copyright (c) 2024 Rapid Silicon * * SPDX-License-Identifier: Apache-2.0 * diff --git a/include/zephyr/crypto/crypto.h b/include/zephyr/crypto/crypto.h index 44c76ec80a532..e23d05ec1d6a4 100644 --- a/include/zephyr/crypto/crypto.h +++ b/include/zephyr/crypto/crypto.h @@ -40,28 +40,40 @@ * capabilities via provided API (crypto_query_hwcaps()), and choose a * supported config during the session setup. */ -#define CAP_OPAQUE_KEY_HNDL BIT(0) -#define CAP_RAW_KEY BIT(1) +#define CAP_OPAQUE_KEY_HNDL BIT(0) +#define CAP_RAW_KEY BIT(1) /* TBD to define */ -#define CAP_KEY_LOADING_API BIT(2) +#define CAP_KEY_LOADING_API BIT(2) /** Whether the output is placed in separate buffer or not */ -#define CAP_INPLACE_OPS BIT(3) -#define CAP_SEPARATE_IO_BUFS BIT(4) +#define CAP_INPLACE_OPS BIT(3) +#define CAP_SEPARATE_IO_BUFS BIT(4) /** * These denotes if the output (completion of a cipher_xxx_op) is conveyed * by the op function returning, or it is conveyed by an async notification */ -#define CAP_SYNC_OPS BIT(5) -#define CAP_ASYNC_OPS BIT(6) +#define CAP_SYNC_OPS BIT(5) +#define CAP_ASYNC_OPS BIT(6) /** Whether the hardware/driver supports autononce feature */ -#define CAP_AUTONONCE BIT(7) +#define CAP_AUTONONCE BIT(7) /** Don't prefix IV to cipher blocks */ -#define CAP_NO_IV_PREFIX BIT(8) +#define CAP_NO_IV_PREFIX BIT(8) + +/** Whether the driver supports encryption or not */ +#define CAP_NO_ENCRYPTION BIT(9) + +/** Whether the driver supports decryption or not */ +#define CAP_NO_DECRYPTION BIT(10) + +/** Whether the driver supports signing or not */ +#define CAP_NO_SIGNING BIT(11) + +/** Whether the driver supports sign verification or not */ +#define CAP_NO_SIGN_VERIFICATION BIT(12) /* More flags to be added as necessary */ From ff29a695326f787164ef6d70748213439066ed7a Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 19 Sep 2024 20:08:14 +0500 Subject: [PATCH 10/58] Continuing FSBL PUFcc integration with Zephyr Crypto APIs --- drivers/crypto/crypto_pufs.c | 185 ++++++++++++++++++++++----------- include/zephyr/crypto/crypto.h | 28 ++--- include/zephyr/crypto/hash.h | 30 +++++- 3 files changed, 165 insertions(+), 78 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index f8607c7f13414..9317552673b23 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -35,7 +35,7 @@ LOG_MODULE_REGISTER(crypto_puf_security); ****************************************************************************/ uint8_t __pufcc_descriptors[BUFFER_SIZE]; static struct pufcc_sg_dma_desc *sg_dma_descs = - (struct pufcc_sg_dma_desc *)&__pufcc_descriptors; + (struct pufcc_sg_dma_desc *)__pufcc_descriptors; static uint8_t pufcc_buffer[BUFFER_SIZE]; // PUFcc microprogram for RSA2048 @@ -120,12 +120,13 @@ enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, * @fn pufcc_calc_sha256_hash * @brief Calculates SHA256 hash * - * @param[in] data_addr Data address info - * @param[in] hash Pointer to hash struct to return hash value in - * @return PUFCC_SUCCESS on success, otherwise an error code. + * @param[in] ctx Context of the hash computation session. + * @param[in] pkt Input and output data related parameters for hash calculation. + * @return PUFCC_SUCCESS on success, otherwise an error code. */ -static enum pufcc_status pufcc_calc_sha256_hash(struct pufs_crypto_addr *data_addr, - struct pufs_crypto_hash *hash) { +static enum pufcc_status pufcc_calc_sha256_hash(struct hash_ctx *ctx, + struct hash_pkt *pkt) +{ enum pufcc_status status; struct pufcc_intrpt_reg intrpt_reg = {0}; struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; @@ -158,10 +159,10 @@ static enum pufcc_status pufcc_calc_sha256_hash(struct pufs_crypto_addr *data_ad REG_WRITE_32(&dma_regs->cfg_0, &dma_cfg_0_reg); // Set data source address in dsc_cfg_0 register - dma_regs->dsc_cfg_0 = data_addr->read_addr; + dma_regs->dsc_cfg_0 = (uint32_t)pkt->in_buf; // Set data length in dsc_cfg_2 register - dma_regs->dsc_cfg_2 = data_addr->len; + dma_regs->dsc_cfg_2 = pkt->in_len; // Set the dsc_cfg_4 register to values defined above REG_WRITE_32(&dma_regs->dsc_cfg_4, &dma_dsc_cfg_4_reg); @@ -198,10 +199,10 @@ static enum pufcc_status pufcc_calc_sha256_hash(struct pufs_crypto_addr *data_ad // Read the calculated hash for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { - ((uint32_t *)hash->val)[i] = be2le(crypto_regs->dgst_out[i]); + ((uint32_t *)pkt->out_buf)[i] = be2le(crypto_regs->dgst_out[i]); } - hash->len = PUFCC_SHA_256_LEN; + pkt->out_len = PUFCC_SHA_256_LEN; return PUFCC_SUCCESS; } @@ -210,45 +211,29 @@ static enum pufcc_status pufcc_calc_sha256_hash(struct pufs_crypto_addr *data_ad * @fn pufcc_calc_sha256_hash_sg * @brief Calculates SHA256 hash of non-contiguous data. * All non contiguous data addresses can be passed in as a single linked - * list in the form of 'pufs_crypto_addr' struct as 'data_addr' parameter + * list in the form of 'hash_pkr' struct as 'pkt' parameter * or this function can be invoked multiple times with partial data - * address info in the linked list by setting the 'first' and 'last' + * address info in the linked list by setting the 'head' and 'tail' * params accordingly as detailed below against each param. In case of * partial data address info and hence multiple invocations, we also need * to pass in previously calculated hash values to every invocation - * after the first one and the accumulated length of all previous + * after the head one and the accumulated length of all previous * messages/data. * * Note: In case of multiple data chunks either in a single linked list * or as partial linked lists using multiple invocations the sizes of all * chunks must be multiples of 64 bytes except the last chunk. * - * @param[in] data_addr A linked list of data address info - * @param[in] first Boolean to indicate if 'data_addr' contains the first - * data block - * @param[in] last Boolean to indicate if 'data_addr' contains the last - * data block - * Note: 'first' and 'last' can both be true if - * 'data_addr' linked list contains both first and last - * data blocks or if it contains a single data block that - * is both first as well last. - * @param[in] prev_len Pointer to accumulated length of previously processed - * data; 0 for first invocation. Currently processed data - * length will be added to this value. - * @param[in] hash_in Hash of the data bocks processed already; can be NULL - * for first invocation. - * @param[out] hash_out Pointer to hash strcut to return hash value in - * @return PUFCC_SUCCESS on success, otherwise an error code. + * @param[in] ctx Context of the hash computation session. + * @param[in] pkt Input and output data related parameters for hash calculation. + * @return PUFCC_SUCCESS on success, otherwise an error code. */ -static enum pufcc_status pufcc_calc_sha256_hash_sg(struct pufs_crypto_addr *data_addr, - bool first, bool last, - uint32_t *prev_len, - struct pufs_crypto_hash *hash_in, - struct pufs_crypto_hash *hash_out) { +static enum pufcc_status pufcc_calc_sha256_hash_sg(struct hash_ctx *ctx, + struct hash_pkt *pkt) { enum pufcc_status status; uint32_t plen = 0; uint8_t desc_count = 0; - struct pufs_crypto_addr *curr_addr = data_addr; + bool lvHead = pkt->head, lvTail = pkt->tail; struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; struct pufcc_dma_key_cfg0_reg dma_key_cfg0_reg = {0}; @@ -256,7 +241,7 @@ static enum pufcc_status pufcc_calc_sha256_hash_sg(struct pufs_crypto_addr *data struct pufcc_start_reg start_reg = {0}; struct pufcc_hmac_config_reg hmac_config_reg = {0}; - if (!first) plen = *prev_len; + if (!lvHead) plen = *pkt->prev_len; // Set DMA 'intrpt' register values intrpt_reg.intrpt_st = 1; // Write 1 to clear interrupt @@ -273,16 +258,16 @@ static enum pufcc_status pufcc_calc_sha256_hash_sg(struct pufs_crypto_addr *data dma_key_cfg0_reg.key_dst = PUFCC_DMA_KEY_DST_HASH; // Set previous hash value if it's not the first data block - if (!first) { + if (!lvHead) { for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { - crypto_regs->dgst_in[i] = be2le(((uint32_t *)hash_in->val)[i]); + crypto_regs->dgst_in[i] = be2le(((uint32_t *)pkt->in_hash)[i]); } } // Set SGDMA descriptors do { - sg_dma_descs[desc_count].read_addr = be2le(curr_addr->read_addr); - sg_dma_descs[desc_count].length = be2le(curr_addr->len); + sg_dma_descs[desc_count].read_addr = be2le((uint32_t)pkt->in_buf); + sg_dma_descs[desc_count].length = be2le(pkt->in_len); sg_dma_descs[desc_count].next = be2le((uint32_t)&sg_dma_descs[desc_count + 1]); @@ -293,33 +278,33 @@ static enum pufcc_status pufcc_calc_sha256_hash_sg(struct pufs_crypto_addr *data *(uint32_t *)&dma_dsc_cfg_4_reg = 0; dma_dsc_cfg_4_reg.offset = plen % 16; - plen += curr_addr->len; - curr_addr = curr_addr->next; + plen += pkt->in_len; + pkt = pkt->next; - if (!desc_count && first) { + if (!desc_count && lvHead) { dma_dsc_cfg_4_reg.head = 1; } // Mark this descriptor as last if there is no more data - if (!curr_addr) { + if (!pkt) { dma_dsc_cfg_4_reg.dn_pause = 1; - if (last) { + if (lvTail) { dma_dsc_cfg_4_reg.tail = 1; } } sg_dma_descs[desc_count].dsc_cfg_4 = be2le(*(uint32_t *)&dma_dsc_cfg_4_reg); desc_count++; - } while (curr_addr && ((desc_count * sizeof(struct pufcc_sg_dma_desc)) < + } while (pkt && ((desc_count * sizeof(struct pufcc_sg_dma_desc)) < SG_DMA_MAX_DSCS_SIZE)); - if (curr_addr) { + if (pkt) { // No enough descriptors available return PUFCC_E_OVERFLOW; } // Update accumulated data length - *prev_len = plen; + *pkt->prev_len = plen; /*** Configure DMA registers ***/ // Enable SGDMA in dma_cfg_0 register @@ -352,10 +337,11 @@ static enum pufcc_status pufcc_calc_sha256_hash_sg(struct pufs_crypto_addr *data // Read the calculated hash value for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { - ((uint32_t *)hash_out->val)[i] = be2le(crypto_regs->dgst_out[i]); + ((uint32_t *)pkt->out_buf)[i] = be2le(crypto_regs->dgst_out[i]); } - hash_out->len = PUFCC_SHA_256_LEN; + pkt->out_len = PUFCC_SHA_256_LEN; + return PUFCC_SUCCESS; } @@ -581,11 +567,11 @@ static enum pufcc_status pufcc_ecdsa256_sign_verify( enum pufcc_status status; struct pufs_crypto_hash hash; - // Calculate hash of the message - if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != - PUFCC_SUCCESS) { - return PUFCC_E_ERROR; - } + // Calculate hash of the message: TODO update here + // if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != + // PUFCC_SUCCESS) { + // return PUFCC_E_ERROR; + // } // Set the EC NIST P256 parameters after reversing them reverse(pufcc_buffer, ecc_param_nistp256.prime, PUFCC_ECDSA_256_LEN); @@ -938,11 +924,11 @@ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, return PUFCC_E_VERFAIL; } - // Calculate hash of the message - if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != - PUFCC_SUCCESS) { - return PUFCC_E_ERROR; - } + // Calculate hash of the message: TODO Update here + // if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != + // PUFCC_SUCCESS) { + // return PUFCC_E_ERROR; + // } if (memcmp(dec_msg + i + 19, hash.val, hash.len) != 0) { return PUFCC_E_VERFAIL; @@ -1101,14 +1087,73 @@ static void pufs_irq_Init(void) { * various crypto related operations. *********************************************************/ +static int block_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt) +{ + return -ENOTSUP; +} + +/* Function signatures for encryption/ decryption using standard cipher modes + * like CBC, CTR, CCM. + */ +static int pufs_cbc_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, + uint8_t *iv) +{ + return -ENOTSUP; +} + +static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t *ctr) +{ + return -ENOTSUP; // TODO replace with the following + // return pufcc_decrypt_aes(...); +} + +static int pufs_ccm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, + uint8_t *nonce) +{ + return -ENOTSUP; +} + +static int pufs_gcm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, + uint8_t *nonce) +{ + return -ENOTSUP; +} + +static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) +{ + enum pufcc_status lvStatus = PUFCC_SUCCESS; + + if(!ctx->started) { + lvStatus = pufcc_calc_sha256_hash(ctx, pkt); + } else { + lvStatus = pufcc_calc_sha256_hash_sg(ctx, pkt); + } + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) PUFs Error Code:%d\n", __func__, __LINE__, lvStatus); + return -ECANCELED; + } + + return PUFCC_SUCCESS; +} + +static int pufs_rsa_op(struct sign_ctx *ctx, struct sign_pkt *pkt) +{ + return -ENOTSUP; // TODO replace with rsa sign verify call +} + +static int pufs_ecdsa_op(struct sign_ctx *ctx, struct sign_pkt *pkt) +{ + return -ENOTSUP; // TODO replace with ecdsa sign verify call +} + /* Query the driver capabilities */ static int pufs_query_hw_caps(const struct device *dev) { return ( CAP_RAW_KEY | CAP_INPLACE_OPS | \ CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | \ - CAP_ASYNC_OPS | CAP_NO_IV_PREFIX | \ - CAP_NO_ENCRYPTION | CAP_NO_SIGNING + CAP_NO_IV_PREFIX | CAP_NO_ENCRYPTION | CAP_NO_SIGNING ); } @@ -1137,7 +1182,21 @@ static int pufs_cipher_async_callback_set(const struct device *dev, static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ctx, enum hash_algo algo) { - return -ENOTSUP; + ctx->device = dev; + + uint16_t lvHashFlags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS), lvHashFlagsMask = 0xFFFF; + + if(algo != CRYPTO_HASH_ALGO_SHA256) { + return -ENOTSUP; + } + + if((ctx->flags & lvHashFlagsMask) != (lvHashFlags)) { + return -ENOTSUP; + } + + ctx->hash_hndlr = pufs_hash_op; + + return PUFCC_SUCCESS; } /* Tear down an established hash session */ diff --git a/include/zephyr/crypto/crypto.h b/include/zephyr/crypto/crypto.h index e23d05ec1d6a4..2ab5f4438dc43 100644 --- a/include/zephyr/crypto/crypto.h +++ b/include/zephyr/crypto/crypto.h @@ -40,40 +40,40 @@ * capabilities via provided API (crypto_query_hwcaps()), and choose a * supported config during the session setup. */ -#define CAP_OPAQUE_KEY_HNDL BIT(0) -#define CAP_RAW_KEY BIT(1) +#define CAP_OPAQUE_KEY_HNDL BIT(0) +#define CAP_RAW_KEY BIT(1) /* TBD to define */ -#define CAP_KEY_LOADING_API BIT(2) +#define CAP_KEY_LOADING_API BIT(2) /** Whether the output is placed in separate buffer or not */ -#define CAP_INPLACE_OPS BIT(3) -#define CAP_SEPARATE_IO_BUFS BIT(4) +#define CAP_INPLACE_OPS BIT(3) +#define CAP_SEPARATE_IO_BUFS BIT(4) /** * These denotes if the output (completion of a cipher_xxx_op) is conveyed * by the op function returning, or it is conveyed by an async notification */ -#define CAP_SYNC_OPS BIT(5) -#define CAP_ASYNC_OPS BIT(6) +#define CAP_SYNC_OPS BIT(5) +#define CAP_ASYNC_OPS BIT(6) /** Whether the hardware/driver supports autononce feature */ -#define CAP_AUTONONCE BIT(7) +#define CAP_AUTONONCE BIT(7) /** Don't prefix IV to cipher blocks */ -#define CAP_NO_IV_PREFIX BIT(8) +#define CAP_NO_IV_PREFIX BIT(8) /** Whether the driver supports encryption or not */ -#define CAP_NO_ENCRYPTION BIT(9) +#define CAP_NO_ENCRYPTION BIT(9) /** Whether the driver supports decryption or not */ -#define CAP_NO_DECRYPTION BIT(10) +#define CAP_NO_DECRYPTION BIT(10) /** Whether the driver supports signing or not */ -#define CAP_NO_SIGNING BIT(11) +#define CAP_NO_SIGNING BIT(11) /** Whether the driver supports sign verification or not */ -#define CAP_NO_SIGN_VERIFICATION BIT(12) +#define CAP_NO_SIGN_VERIFY BIT(12) /* More flags to be added as necessary */ @@ -478,7 +478,7 @@ static inline int hash_callback_set(const struct device *dev, } /** - * @brief Perform a cryptographic hash function. + * @brief Perform a cryptographic hash function. * * @param ctx Pointer to the hash context of this op. * @param pkt Structure holding the input/output. diff --git a/include/zephyr/crypto/hash.h b/include/zephyr/crypto/hash.h index f7775e058ed2c..c0de515ec3aee 100644 --- a/include/zephyr/crypto/hash.h +++ b/include/zephyr/crypto/hash.h @@ -83,7 +83,8 @@ struct hash_ctx { * operation. * * The fields which has not been explicitly called out has to - * be filled up by the app before calling hash_compute(). + * be filled up by the app before calling hash_compute() or + * hash_update(). */ struct hash_pkt { @@ -98,6 +99,9 @@ struct hash_pkt { /** Bytes to be operated upon */ size_t in_len; + /** Bytes previously operated upon */ + size_t *prev_len; + /** * Start of the output buffer, to be allocated by * the application. Can be NULL for in-place ops. To be populated @@ -105,6 +109,30 @@ struct hash_pkt { */ uint8_t *out_buf; + /** Bytes in returned hash (out_buf) */ + size_t out_len; + + /** + * The pointer is for creating a linkedlist of + * incoming data in case the hash is calculated in chunks + * where data might be coming from different places. + */ + struct hash_pkt *next; + + /** + * Whether this linkedlist contains head or not. + * This boolean shall be initialized only once in + * the beginning of every new linkedlist construction. + */ + bool head; + + /** + * Whether this linkedlist contains tail or not. + * This boolean shall be initialized only once in + * the beginning of every new linkedlist construction. + */ + bool tail; + /** * Context this packet relates to. This can be useful to get the * session details, especially for async ops. From b9b85b817e404ec82fc42d2dbf8fae8ff815b243 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 20 Sep 2024 16:40:53 +0500 Subject: [PATCH 11/58] Continuing FSBL PUFcc integration with Zephyr Crypto APIs --- drivers/crypto/crypto_pufs.c | 84 +++++++++++++++++++++++++++++------- drivers/crypto/crypto_pufs.h | 16 +++++++ 2 files changed, 84 insertions(+), 16 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 9317552673b23..136515a838f55 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -1051,14 +1051,18 @@ static int crypto_pufs_init(const struct device *dev) { } static void pufs_irq_handler(const struct device *dev) { // TODO callback invocation in it - // int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); + int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -ECANCELED : 0); struct pufcc_intrpt_reg *intrpt_reg_ptr = (struct pufcc_intrpt_reg *)&dma_regs->interrupt; + struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; + // Clear and disable interrupt intrpt_reg_ptr->intrpt_st = 1; // Set to clear intrpt_reg_ptr->intrpt_en = 0; + // TODO call callback function here + // Disable IRQ as the next asynch callback registeration shall enable it again. irq_disable(((struct pufs_config*)dev->config)->irq_num); } @@ -1123,6 +1127,9 @@ static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) { enum pufcc_status lvStatus = PUFCC_SUCCESS; + ((struct pufs_data*)ctx->device->data)->pufs_pkt.hash_pkt = pkt; + ((struct pufs_data*)ctx->device->data)->pufs_ctx.hash_ctx = ctx; + if(!ctx->started) { lvStatus = pufcc_calc_sha256_hash(ctx, pkt); } else { @@ -1152,7 +1159,7 @@ static int pufs_query_hw_caps(const struct device *dev) { return ( CAP_RAW_KEY | CAP_INPLACE_OPS | \ - CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | \ + CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_ASYNC_OPS | \ CAP_NO_IV_PREFIX | CAP_NO_ENCRYPTION | CAP_NO_SIGNING ); } @@ -1172,19 +1179,26 @@ static int pufs_cipher_free_session(const struct device *dev, struct cipher_ctx } /* Register async crypto op completion callback with the driver */ -static int pufs_cipher_async_callback_set(const struct device *dev, - cipher_completion_cb cb) +static int pufs_cipher_async_callback_set(const struct device *dev, cipher_completion_cb cb) { - return -ENOTSUP; + if((pufs_query_hw_caps(dev) & CAP_ASYNC_OPS) != CAP_ASYNC_OPS) { + return -ENOTSUP; + } + + ((struct pufs_data*)dev->data)->session_callback.cipher_cb = cb; + + // Enable IRQ. + irq_enable(((struct pufs_config*)dev->config)->irq_num); + + return PUFCC_SUCCESS; } /* Setup a hash session */ -static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ctx, - enum hash_algo algo) +static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ctx, enum hash_algo algo) { - ctx->device = dev; + struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; - uint16_t lvHashFlags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS), lvHashFlagsMask = 0xFFFF; + uint16_t lvHashFlags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_ASYNC_OPS), lvHashFlagsMask = 0xFFFF; if(algo != CRYPTO_HASH_ALGO_SHA256) { return -ENOTSUP; @@ -1194,6 +1208,20 @@ static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ct return -ENOTSUP; } + if(lvPufsData->pufs_session_type != PUFS_SESSION_UNDEFINED) { + + LOG_ERR( + "%s(%d) An Existing %s Session in Progress\n", __func__, __LINE__, \ + ((lvPufsData->pufs_session_type == PUFS_SESSION_HASH_CALCULATION)?"Hash":\ + ((lvPufsData->pufs_session_type == PUFS_SESSION_DECRYPTION)?"Decryption":\ + ((lvPufsData->pufs_session_type == PUFS_SESSION_SIGN_VERIFICATION)?"Sign_Verification":"Unknown"))) + ); + + return -ENOTSUP; + } else { + lvPufsData->pufs_session_type = PUFS_SESSION_HASH_CALCULATION; + } + ctx->hash_hndlr = pufs_hash_op; return PUFCC_SUCCESS; @@ -1202,14 +1230,30 @@ static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ct /* Tear down an established hash session */ static int pufs_hash_free_session(const struct device *dev, struct hash_ctx *ctx) { - return -ENOTSUP; + ctx->device = NULL; + + ctx->started = false; + + ctx->flags = 0x00; + + ctx->hash_hndlr = NULL; + + return PUFCC_SUCCESS; } /* Register async hash op completion callback with the driver */ -static int pufs_hash_async_callback_set(const struct device *dev, - hash_completion_cb cb) +static int pufs_hash_async_callback_set(const struct device *dev, hash_completion_cb cb) { - return -ENOTSUP; + if((pufs_query_hw_caps(dev) & CAP_ASYNC_OPS) != CAP_ASYNC_OPS) { + return -ENOTSUP; + } + + ((struct pufs_data*)dev->data)->session_callback.hash_cb = cb; + + // Enable IRQ. + irq_enable(((struct pufs_config*)dev->config)->irq_num); + + return PUFCC_SUCCESS; } /* Setup a signature session */ @@ -1226,10 +1270,18 @@ static int pufs_sign_free_session(const struct device *dev, struct sign_ctx *ctx } /* Register async signature op completion callback with the driver */ -static int pufs_sign_async_callback_set(const struct device *dev, - sign_completion_cb cb) +static int pufs_sign_async_callback_set(const struct device *dev, sign_completion_cb cb) { - return -ENOTSUP; + if((pufs_query_hw_caps(dev) & CAP_ASYNC_OPS) != CAP_ASYNC_OPS) { + return -ENOTSUP; + } + + ((struct pufs_data*)dev->data)->session_callback.sign_cb = cb; + + // Enable IRQ. + irq_enable(((struct pufs_config*)dev->config)->irq_num); + + return PUFCC_SUCCESS; } static struct crypto_driver_api s_crypto_funcs = { diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index e08165ff19d01..cefd2b9cb00db 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -529,10 +529,26 @@ struct crypto_callbacks { sign_completion_cb sign_cb; }; +/* Cipher, Hash and Sign session contexts */ +struct pufs_crypto_ctx { + struct hash_ctx *hash_ctx; + struct cipher_ctx *cipher_ctx; + struct sign_ctx *sign_ctx; +}; + +/* Cipher, Hash and Sign pkts */ +struct pufs_crypto_pkt { + struct hash_pkt *hash_pkt; + struct cipher_pkt *cipher_pkt; + struct sign_pkt *sign_pkt; +}; + /* Device constant configuration parameters */ struct pufs_data { enum pufs_session_type pufs_session_type; struct crypto_callbacks session_callback; + struct pufs_crypto_ctx pufs_ctx; + struct pufs_crypto_pkt pufs_pkt; }; /* Device constant configuration parameters */ From 8a89b48b9cbba49c714ff267f78e4d06165e79cb Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 20 Sep 2024 18:03:08 +0500 Subject: [PATCH 12/58] Continuing FSBL PUFcc integration with Zephyr Crypto APIs --- drivers/crypto/crypto_pufs.c | 66 ++++++++++++++++++------------------ drivers/crypto/crypto_pufs.h | 2 -- include/zephyr/crypto/sign.h | 18 ++-------- 3 files changed, 35 insertions(+), 51 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 136515a838f55..59933efc297db 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -113,6 +113,12 @@ static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, enum pufcc_otp_lock *lock_val); +static char *session_to_str(enum pufs_session_type inSession) { + return ((inSession == PUFS_SESSION_HASH_CALCULATION)?"Hash":\ + ((inSession == PUFS_SESSION_DECRYPTION)?"Decryption":\ + ((inSession == PUFS_SESSION_SIGN_VERIFICATION)?"Sign_Verification":"Unknown"))); +} + /***************************************************************************** * API functions ****************************************************************************/ @@ -560,9 +566,10 @@ static enum pufcc_status pufcc_rsa2048_sign_verify( * @param[in] pub_key ECDSA256 public key * @return PUFCC_SUCCESS on success, otherwise an error code. */ -static enum pufcc_status pufcc_ecdsa256_sign_verify( - struct pufs_crypto_ec256_sig *sig, struct pufs_crypto_addr *msg_addr, - struct rs_crypto_ec256_puk *pub_key) { +static enum pufcc_status pufcc_ecdsa256_sign_verify(struct sign_ctx *ctx, struct sign_pkt *pkt) { + + struct pufs_crypto_ec256_sig *sig = (struct pufs_crypto_ec256_sig *)ctx->sig; + struct rs_crypto_ec256_puk *pub_key = (struct rs_crypto_ec256_puk *)ctx->pub_key; uint32_t temp32, prev_len = 0; enum pufcc_status status; struct pufs_crypto_hash hash; @@ -1057,14 +1064,11 @@ static void pufs_irq_handler(const struct device *dev) { // TODO callback invoca struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; + // TODO call callback function here + // Clear and disable interrupt intrpt_reg_ptr->intrpt_st = 1; // Set to clear intrpt_reg_ptr->intrpt_en = 0; - - // TODO call callback function here - - // Disable IRQ as the next asynch callback registeration shall enable it again. - irq_disable(((struct pufs_config*)dev->config)->irq_num); } static void pufs_irq_Init(void) { @@ -1075,13 +1079,9 @@ static void pufs_irq_Init(void) { DEVICE_DT_INST_GET(0), 0 ); - /* - * The IRQs will only be enabled in - * xyz_async_callback_set interfaces - * Inside the IRQ Handler we will disable - * the IRQ since we support only single - * session at any moment. - */ + + // Enable IRQ. + irq_enable(DT_INST_IRQN(0)); } /******************************************************** @@ -1187,9 +1187,6 @@ static int pufs_cipher_async_callback_set(const struct device *dev, cipher_compl ((struct pufs_data*)dev->data)->session_callback.cipher_cb = cb; - // Enable IRQ. - irq_enable(((struct pufs_config*)dev->config)->irq_num); - return PUFCC_SUCCESS; } @@ -1210,12 +1207,8 @@ static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ct if(lvPufsData->pufs_session_type != PUFS_SESSION_UNDEFINED) { - LOG_ERR( - "%s(%d) An Existing %s Session in Progress\n", __func__, __LINE__, \ - ((lvPufsData->pufs_session_type == PUFS_SESSION_HASH_CALCULATION)?"Hash":\ - ((lvPufsData->pufs_session_type == PUFS_SESSION_DECRYPTION)?"Decryption":\ - ((lvPufsData->pufs_session_type == PUFS_SESSION_SIGN_VERIFICATION)?"Sign_Verification":"Unknown"))) - ); + LOG_ERR("%s(%d) An Existing %s Session in Progress\n", __func__, __LINE__, \ + session_to_str(lvPufsData->pufs_session_type)); return -ENOTSUP; } else { @@ -1230,6 +1223,8 @@ static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ct /* Tear down an established hash session */ static int pufs_hash_free_session(const struct device *dev, struct hash_ctx *ctx) { + struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; + ctx->device = NULL; ctx->started = false; @@ -1238,6 +1233,17 @@ static int pufs_hash_free_session(const struct device *dev, struct hash_ctx *ctx ctx->hash_hndlr = NULL; + if(lvPufsData->pufs_session_type != PUFS_SESSION_HASH_CALCULATION) { + LOG_ERR("%s(%d) Cannot Free %s Session\n", __func__, __LINE__, \ + session_to_str(lvPufsData->pufs_session_type)); + return -ENOEXEC; + } else { + lvPufsData->pufs_session_type = PUFS_SESSION_UNDEFINED; + lvPufsData->session_callback.hash_cb = NULL; + lvPufsData->pufs_ctx.hash_ctx = NULL; + lvPufsData->pufs_pkt.hash_pkt = NULL; + } + return PUFCC_SUCCESS; } @@ -1250,9 +1256,6 @@ static int pufs_hash_async_callback_set(const struct device *dev, hash_completio ((struct pufs_data*)dev->data)->session_callback.hash_cb = cb; - // Enable IRQ. - irq_enable(((struct pufs_config*)dev->config)->irq_num); - return PUFCC_SUCCESS; } @@ -1278,9 +1281,6 @@ static int pufs_sign_async_callback_set(const struct device *dev, sign_completio ((struct pufs_data*)dev->data)->session_callback.sign_cb = cb; - // Enable IRQ. - irq_enable(((struct pufs_config*)dev->config)->irq_num); - return PUFCC_SUCCESS; } @@ -1299,14 +1299,14 @@ static struct crypto_driver_api s_crypto_funcs = { static struct pufs_data s_pufs_session_data = { .pufs_session_type = PUFS_SESSION_UNDEFINED, - .session_callback = {NULL} + .session_callback = {NULL}, + .pufs_ctx = {NULL}, + .pufs_pkt = {NULL} }; static const struct pufs_config s_pufs_configuration = { .base = DT_INST_REG_ADDR(0), - .irq_num = DT_INST_IRQN(0), .irq_init = pufs_irq_Init, - .irq_priority = DT_INST_IRQ(0, priority), .dev = DEVICE_DT_INST_GET(0) }; diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index cefd2b9cb00db..404dff3631683 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -555,8 +555,6 @@ struct pufs_data { struct pufs_config { void (*irq_init)(void); uint32_t base; - uint32_t irq_num; - uint32_t irq_priority; const struct device *dev; }; diff --git a/include/zephyr/crypto/sign.h b/include/zephyr/crypto/sign.h index 057901e778573..598e810f7115a 100644 --- a/include/zephyr/crypto/sign.h +++ b/include/zephyr/crypto/sign.h @@ -76,24 +76,10 @@ struct sign_ctx { struct sign_ops ops; /** To be populated by the app before calling begin_session() */ - union { - /* Cryptographic key to be used in this session */ - const uint8_t *bit_stream; - /* For cases where key is protected and is not - * available to caller - */ - void *handle; - } pub_key; + const uint8_t *pub_key; /** To be populated by the app before calling begin_session() */ - union { - /* Signature to be used in this session */ - const uint8_t *bit_stream; - /* For cases where signature is protected and is not - * available to caller - */ - void *handle; - } signature; + const uint8_t *sig; /** The device driver instance this crypto context relates to. Will be * populated by the begin_session() API. From 212ef9b4be180a6ef43ab48881c8b3b6c6bde6ec Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 20 Sep 2024 19:12:31 +0500 Subject: [PATCH 13/58] Continuing FSBL PUFcc integration with Zephyr Crypto APIs for sign verification --- drivers/crypto/crypto_pufs.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 59933efc297db..6e6869d7fbfd7 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -574,11 +574,31 @@ static enum pufcc_status pufcc_ecdsa256_sign_verify(struct sign_ctx *ctx, struct enum pufcc_status status; struct pufs_crypto_hash hash; - // Calculate hash of the message: TODO update here - // if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != - // PUFCC_SUCCESS) { - // return PUFCC_E_ERROR; - // } + struct hash_ctx lvHashCtx = { + .device = ctx->device, + .drv_sessn_state = NULL, + .hash_hndlr = NULL, + .started = false, + .flags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS) + }; + + struct hash_pkt lvHashPkt = { + .in_buf = pkt->in_buf, + .in_hash = NULL, + .in_len = pkt->in_len, + .prev_len = &prev_len, + .out_buf = (uint8_t*)hash.val, + .out_len = 0, + .next = NULL, + .head = true, + .tail = true, + .ctx = &lvHashCtx + }; + + // Calculate hash of the message + if (pufcc_calc_sha256_hash_sg(&lvHashCtx, &lvHashPkt) != PUFCC_SUCCESS) { + return PUFCC_E_ERROR; + } // Set the EC NIST P256 parameters after reversing them reverse(pufcc_buffer, ecc_param_nistp256.prime, PUFCC_ECDSA_256_LEN); From 33e6811a003aee865781f34b2890707b00ad7ae2 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 23 Sep 2024 14:39:41 +0500 Subject: [PATCH 14/58] Continuing FSBL PUFcc integration with Zephyr Crypto APIs for sign verification --- drivers/crypto/crypto_pufs.c | 123 +++++++++++++++++++++++++++++++---- drivers/crypto/crypto_pufs.h | 1 + 2 files changed, 110 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 6e6869d7fbfd7..314091eb2b346 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -22,6 +22,10 @@ LOG_MODULE_REGISTER(crypto_puf_security); #error No PUF Security HW Crypto Accelerator in device tree #endif +#define PUFS_HW_CAP (CAP_RAW_KEY | CAP_INPLACE_OPS | \ + CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_ASYNC_OPS | \ + CAP_NO_IV_PREFIX | CAP_NO_ENCRYPTION | CAP_NO_SIGNING) + /***************************************************************************** * Macros ****************************************************************************/ @@ -951,11 +955,33 @@ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, return PUFCC_E_VERFAIL; } - // Calculate hash of the message: TODO Update here - // if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != - // PUFCC_SUCCESS) { - // return PUFCC_E_ERROR; - // } + // Calculate hash of the message + + struct hash_ctx lvHashCtx = { + .device = NULL, + .drv_sessn_state = NULL, + .hash_hndlr = NULL, + .started = false, + .flags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS) + }; + + struct hash_pkt lvHashPkt = { + .in_buf = msg_addr->read_addr, + .in_hash = NULL, + .in_len = msg_addr->len, + .prev_len = &prev_len, + .out_buf = (uint8_t*)hash.val, + .out_len = 0, + .next = NULL, + .head = true, + .tail = true, + .ctx = &lvHashCtx + }; + + if (pufcc_calc_sha256_hash_sg(&lvHashCtx, &lvHashPkt) != + PUFCC_SUCCESS) { + return PUFCC_E_ERROR; + } if (memcmp(dec_msg + i + 19, hash.val, hash.len) != 0) { return PUFCC_E_VERFAIL; @@ -1089,6 +1115,8 @@ static void pufs_irq_handler(const struct device *dev) { // TODO callback invoca // Clear and disable interrupt intrpt_reg_ptr->intrpt_st = 1; // Set to clear intrpt_reg_ptr->intrpt_en = 0; + + irq_disable(((struct pufs_config *)dev->config)->irq_num); } static void pufs_irq_Init(void) { @@ -1100,8 +1128,13 @@ static void pufs_irq_Init(void) { 0 ); - // Enable IRQ. - irq_enable(DT_INST_IRQN(0)); + /** + * IRQ for PUFcc will be abled inside the + * interfaces which enable asynch operation + * callback registeration. When the IRQ is + * received, then that will be disabled inside + * the pufs_irq_hander. + */ } /******************************************************** @@ -1177,11 +1210,7 @@ static int pufs_ecdsa_op(struct sign_ctx *ctx, struct sign_pkt *pkt) /* Query the driver capabilities */ static int pufs_query_hw_caps(const struct device *dev) { - return ( - CAP_RAW_KEY | CAP_INPLACE_OPS | \ - CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_ASYNC_OPS | \ - CAP_NO_IV_PREFIX | CAP_NO_ENCRYPTION | CAP_NO_SIGNING - ); + return PUFS_HW_CAP; } /* Setup a crypto session */ @@ -1195,7 +1224,37 @@ static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx /* Tear down an established session */ static int pufs_cipher_free_session(const struct device *dev, struct cipher_ctx *ctx) { - return -ENOTSUP; + struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; + + ctx->device = NULL; + + ctx->flags = 0x00; + + ctx->ops.block_crypt_hndlr = NULL; + ctx->ops.cbc_crypt_hndlr = NULL; + ctx->ops.ctr_crypt_hndlr = NULL; + ctx->ops.ccm_crypt_hndlr = NULL; + ctx->ops.gcm_crypt_hndlr = NULL; + + ctx->key.bit_stream = NULL; + ctx->key.handle = NULL; + + ctx->drv_sessn_state = NULL; + + ctx->app_sessn_state = NULL; + + if(lvPufsData->pufs_session_type != PUFS_SESSION_DECRYPTION) { + LOG_ERR("%s(%d) Cannot Free %s Session\n", __func__, __LINE__, \ + session_to_str(lvPufsData->pufs_session_type)); + return -ENOEXEC; + } else { + lvPufsData->pufs_session_type = PUFS_SESSION_UNDEFINED; + lvPufsData->session_callback.cipher_cb = NULL; + lvPufsData->pufs_ctx.cipher_ctx = NULL; + lvPufsData->pufs_pkt.cipher_pkt = NULL; + } + + return PUFCC_SUCCESS; } /* Register async crypto op completion callback with the driver */ @@ -1207,6 +1266,8 @@ static int pufs_cipher_async_callback_set(const struct device *dev, cipher_compl ((struct pufs_data*)dev->data)->session_callback.cipher_cb = cb; + irq_enable(((struct pufs_config *)dev->config)->irq_num); + return PUFCC_SUCCESS; } @@ -1276,6 +1337,8 @@ static int pufs_hash_async_callback_set(const struct device *dev, hash_completio ((struct pufs_data*)dev->data)->session_callback.hash_cb = cb; + irq_enable(((struct pufs_config *)dev->config)->irq_num); + return PUFCC_SUCCESS; } @@ -1289,7 +1352,36 @@ static int pufs_sign_begin_session(const struct device *dev, struct sign_ctx *ct /* Tear down an established signature session */ static int pufs_sign_free_session(const struct device *dev, struct sign_ctx *ctx) { - return -ENOTSUP; + struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; + + ctx->device = NULL; + + ctx->flags = 0x00; + + ctx->ops.rsa_crypt_hndlr = NULL; + + ctx->ops.ecdsa_crypt_hndlr = NULL; + + ctx->pub_key = NULL; + + ctx->sig = NULL; + + ctx->drv_sessn_state = NULL; + + ctx->app_sessn_state = NULL; + + if(lvPufsData->pufs_session_type != PUFS_SESSION_SIGN_VERIFICATION) { + LOG_ERR("%s(%d) Cannot Free %s Session\n", __func__, __LINE__, \ + session_to_str(lvPufsData->pufs_session_type)); + return -ENOEXEC; + } else { + lvPufsData->pufs_session_type = PUFS_SESSION_UNDEFINED; + lvPufsData->session_callback.sign_cb = NULL; + lvPufsData->pufs_ctx.sign_ctx = NULL; + lvPufsData->pufs_pkt.sign_pkt = NULL; + } + + return PUFCC_SUCCESS; } /* Register async signature op completion callback with the driver */ @@ -1301,6 +1393,8 @@ static int pufs_sign_async_callback_set(const struct device *dev, sign_completio ((struct pufs_data*)dev->data)->session_callback.sign_cb = cb; + irq_enable(((struct pufs_config *)dev->config)->irq_num); + return PUFCC_SUCCESS; } @@ -1327,6 +1421,7 @@ static struct pufs_data s_pufs_session_data = { static const struct pufs_config s_pufs_configuration = { .base = DT_INST_REG_ADDR(0), .irq_init = pufs_irq_Init, + .irq_num = DT_INST_IRQN(0), .dev = DEVICE_DT_INST_GET(0) }; diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index 404dff3631683..66ba3a0903236 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -555,6 +555,7 @@ struct pufs_data { struct pufs_config { void (*irq_init)(void); uint32_t base; + uint32_t irq_num; const struct device *dev; }; From f28c9c500ff8e77dd1733b050082f7b44d114acc Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 24 Sep 2024 10:25:01 +0500 Subject: [PATCH 15/58] PUFcc integration. Callback Handlers and Cipher Integration Remaining --- drivers/crypto/crypto_pufs.c | 221 +++++++++++++++++++++-------------- include/zephyr/crypto/hash.h | 2 +- include/zephyr/crypto/sign.h | 3 +- 3 files changed, 137 insertions(+), 89 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 314091eb2b346..26a95d18aa941 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -130,9 +130,9 @@ static char *session_to_str(enum pufs_session_type inSession) { * @fn pufcc_calc_sha256_hash * @brief Calculates SHA256 hash * - * @param[in] ctx Context of the hash computation session. - * @param[in] pkt Input and output data related parameters for hash calculation. - * @return PUFCC_SUCCESS on success, otherwise an error code. + * @param[in] ctx Context of the ecdsa hash calculation. + * @param[inout] pkt Input and output data related parameters for hash calculation. + * @return PUFCC_SUCCESS on success, otherwise an error code. */ static enum pufcc_status pufcc_calc_sha256_hash(struct hash_ctx *ctx, struct hash_pkt *pkt) @@ -234,9 +234,9 @@ static enum pufcc_status pufcc_calc_sha256_hash(struct hash_ctx *ctx, * or as partial linked lists using multiple invocations the sizes of all * chunks must be multiples of 64 bytes except the last chunk. * - * @param[in] ctx Context of the hash computation session. - * @param[in] pkt Input and output data related parameters for hash calculation. - * @return PUFCC_SUCCESS on success, otherwise an error code. + * @param[in] ctx Context of the scatter gather hash calculation. + * @param[inout] pkt Input and output data related parameters for hash calculation. + * @return PUFCC_SUCCESS on success, otherwise an error code. */ static enum pufcc_status pufcc_calc_sha256_hash_sg(struct hash_ctx *ctx, struct hash_pkt *pkt) { @@ -493,17 +493,21 @@ static enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, * @fn pufcc_rsa2048_sign_verify * @brief Verify RSA2048 signature of the input message data * - * @param[in] sig Address of the message signature - * @param[in] msg_addr Address of the message data - * @param[in] pub_key RSA2048 public key + * @param[in] ctx Context of the ecdsa sign verification. + * @param[inout] pkt Input and output data related parameters for sign verification. * @return PUFCC_SUCCESS on success, otherwise an error code. */ -static enum pufcc_status pufcc_rsa2048_sign_verify( - uint8_t *sig, struct pufs_crypto_addr *msg_addr, - struct pufs_crypto_rsa2048_puk *pub_key) { +static int pufcc_rsa2048_sign_verify(struct sign_ctx *ctx, struct sign_pkt *pkt) { enum pufcc_status status = PUFCC_SUCCESS; uint32_t temp32; uint8_t dec_msg[PUFCC_RSA_2048_LEN]; + const uint8_t *sig = ctx->sig; + struct pufs_crypto_rsa2048_puk *pub_key = (struct pufs_crypto_rsa2048_puk *)ctx->pub_key; + + struct pufs_crypto_addr msg_addr = { + .read_addr = (uint32_t)pkt->in_buf, + .len = pkt->in_len + }; // Configure signature scheme temp32 = 0; @@ -547,7 +551,8 @@ static enum pufcc_status pufcc_rsa2048_sign_verify( status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); if (status != PUFCC_SUCCESS) { - return status; + LOG_ERR("%s(%d) PUFs Error:%d\n", __func__, __LINE__, (int)status); + return -ECANCELED; } // Read decrypted message from proper offset in ECP data field and reverse it @@ -556,21 +561,25 @@ static enum pufcc_status pufcc_rsa2048_sign_verify( PUFCC_RSA_2048_LEN); reverse(dec_msg, pufcc_buffer, PUFCC_RSA_2048_LEN); - status = rsa_p1v15_verify(dec_msg, msg_addr); + status = rsa_p1v15_verify(dec_msg, &msg_addr); - return status; + if (status != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) PUFs Verification Error:%d\n", __func__, __LINE__, (int)status); + return -ECANCELED; + } + + return PUFCC_SUCCESS; } /** * @fn pufcc_ecdsa256_sign_verify * @brief Verify ECDSA256 signature of the input message data * - * @param[in] sig Address of the message signature - * @param[in] msg_addr Address of the message data - * @param[in] pub_key ECDSA256 public key - * @return PUFCC_SUCCESS on success, otherwise an error code. + * @param[in] ctx Context of the ecdsa sign verification. + * @param[in] pkt Input and output data related parameters for sign verification. + * @return PUFCC_SUCCESS on success, otherwise an error code. */ -static enum pufcc_status pufcc_ecdsa256_sign_verify(struct sign_ctx *ctx, struct sign_pkt *pkt) { +static int pufcc_ecdsa256_sign_verify(struct sign_ctx *ctx, struct sign_pkt *pkt) { struct pufs_crypto_ec256_sig *sig = (struct pufs_crypto_ec256_sig *)ctx->sig; struct rs_crypto_ec256_puk *pub_key = (struct rs_crypto_ec256_puk *)ctx->pub_key; @@ -676,7 +685,12 @@ static enum pufcc_status pufcc_ecdsa256_sign_verify(struct sign_ctx *ctx, struct // Poll on busy status status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); - return status; + if (status != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) PUFs Verification Error:%d\n", __func__, __LINE__, (int)status); + return -ECANCELED; + } + + return PUFCC_SUCCESS; } /** @@ -966,11 +980,11 @@ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, }; struct hash_pkt lvHashPkt = { - .in_buf = msg_addr->read_addr, + .in_buf = (uint8_t *)msg_addr->read_addr, .in_hash = NULL, .in_len = msg_addr->len, .prev_len = &prev_len, - .out_buf = (uint8_t*)hash.val, + .out_buf = (uint8_t*)hash.val, /*hash.val is an array*/ .out_len = 0, .next = NULL, .head = true, @@ -1104,11 +1118,11 @@ static int crypto_pufs_init(const struct device *dev) { } static void pufs_irq_handler(const struct device *dev) { // TODO callback invocation in it - int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -ECANCELED : 0); + // int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -ECANCELED : 0); struct pufcc_intrpt_reg *intrpt_reg_ptr = (struct pufcc_intrpt_reg *)&dma_regs->interrupt; - struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; + // struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; // TODO call callback function here @@ -1144,18 +1158,10 @@ static void pufs_irq_Init(void) { * various crypto related operations. *********************************************************/ -static int block_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt) -{ - return -ENOTSUP; -} - -/* Function signatures for encryption/ decryption using standard cipher modes - * like CBC, CTR, CCM. - */ -static int pufs_cbc_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, - uint8_t *iv) +/* Query the driver capabilities */ +static int pufs_query_hw_caps(const struct device *dev) { - return -ENOTSUP; + return PUFS_HW_CAP; } static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t *ctr) @@ -1164,56 +1170,7 @@ static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t * // return pufcc_decrypt_aes(...); } -static int pufs_ccm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, - uint8_t *nonce) -{ - return -ENOTSUP; -} - -static int pufs_gcm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, - uint8_t *nonce) -{ - return -ENOTSUP; -} - -static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) -{ - enum pufcc_status lvStatus = PUFCC_SUCCESS; - - ((struct pufs_data*)ctx->device->data)->pufs_pkt.hash_pkt = pkt; - ((struct pufs_data*)ctx->device->data)->pufs_ctx.hash_ctx = ctx; - - if(!ctx->started) { - lvStatus = pufcc_calc_sha256_hash(ctx, pkt); - } else { - lvStatus = pufcc_calc_sha256_hash_sg(ctx, pkt); - } - - if(lvStatus != PUFCC_SUCCESS) { - LOG_ERR("%s(%d) PUFs Error Code:%d\n", __func__, __LINE__, lvStatus); - return -ECANCELED; - } - - return PUFCC_SUCCESS; -} - -static int pufs_rsa_op(struct sign_ctx *ctx, struct sign_pkt *pkt) -{ - return -ENOTSUP; // TODO replace with rsa sign verify call -} - -static int pufs_ecdsa_op(struct sign_ctx *ctx, struct sign_pkt *pkt) -{ - return -ENOTSUP; // TODO replace with ecdsa sign verify call -} - -/* Query the driver capabilities */ -static int pufs_query_hw_caps(const struct device *dev) -{ - return PUFS_HW_CAP; -} - -/* Setup a crypto session */ +/* TODO Setup a crypto session */ static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx *ctx, enum cipher_algo algo, enum cipher_mode mode, enum cipher_op op_type) @@ -1271,9 +1228,34 @@ static int pufs_cipher_async_callback_set(const struct device *dev, cipher_compl return PUFCC_SUCCESS; } +static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) +{ + enum pufcc_status lvStatus = PUFCC_SUCCESS; + + ((struct pufs_data*)ctx->device->data)->pufs_pkt.hash_pkt = pkt; + ((struct pufs_data*)ctx->device->data)->pufs_ctx.hash_ctx = ctx; + + if(!ctx->started) { // started flag indicates if chunkwise hash calculation was started + lvStatus = pufcc_calc_sha256_hash(ctx, pkt); + } else { + lvStatus = pufcc_calc_sha256_hash_sg(ctx, pkt); + } + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) PUFs Error Code:%d\n", __func__, __LINE__, lvStatus); + return -ECANCELED; + } + + return PUFCC_SUCCESS; +} + /* Setup a hash session */ static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ctx, enum hash_algo algo) { + ctx->device = dev; + + ((struct pufs_data *)dev->data)->pufs_ctx.hash_ctx = ctx; + struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; uint16_t lvHashFlags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_ASYNC_OPS), lvHashFlagsMask = 0xFFFF; @@ -1346,7 +1328,47 @@ static int pufs_hash_async_callback_set(const struct device *dev, hash_completio static int pufs_sign_begin_session(const struct device *dev, struct sign_ctx *ctx, enum sign_algo algo) { - return -ENOTSUP; + ctx->device = dev; + + ((struct pufs_data *)dev->data)->pufs_ctx.sign_ctx = ctx; + + struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; + + uint16_t lvHashFlags = (CAP_INPLACE_OPS | CAP_SYNC_OPS | CAP_ASYNC_OPS), lvHashFlagsMask = 0xFFFF; + + if((algo != CRYPTO_SIGN_ALGO_ECDSA256) || (algo != CRYPTO_SIGN_ALGO_RSA2048)) { + return -ENOTSUP; + } else { + if(algo == CRYPTO_SIGN_ALGO_ECDSA256) { + ctx->ops.signing_algo = CRYPTO_SIGN_ALGO_ECDSA256; + } else { + ctx->ops.signing_algo = CRYPTO_SIGN_ALGO_RSA2048; + } + } + + if((ctx->flags & lvHashFlagsMask) != (lvHashFlags)) { + return -ENOTSUP; + } + + if(ctx->ops.signing_mode != CRYPTO_SIGN_VERIFY) { + return -ENOTSUP; + } + + if(lvPufsData->pufs_session_type != PUFS_SESSION_UNDEFINED) { + + LOG_ERR("%s(%d) An Existing %s Session in Progress\n", __func__, __LINE__, \ + session_to_str(lvPufsData->pufs_session_type)); + + return -ENOTSUP; + } else { + lvPufsData->pufs_session_type = PUFS_SESSION_SIGN_VERIFICATION; + } + + ctx->ops.rsa_crypt_hndlr = pufcc_rsa2048_sign_verify; + + ctx->ops.ecdsa_crypt_hndlr = pufcc_ecdsa256_sign_verify; + + return PUFCC_SUCCESS; } /* Tear down an established signature session */ @@ -1398,6 +1420,31 @@ static int pufs_sign_async_callback_set(const struct device *dev, sign_completio return PUFCC_SUCCESS; } +/* Following cipher operations are not supported yet. + */ +__unused static int block_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt) +{ + return -ENOTSUP; +} + +__unused static int pufs_cbc_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, + uint8_t *iv) +{ + return -ENOTSUP; +} + +__unused static int pufs_ccm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, + uint8_t *nonce) +{ + return -ENOTSUP; +} + +__unused static int pufs_gcm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, + uint8_t *nonce) +{ + return -ENOTSUP; +} + static struct crypto_driver_api s_crypto_funcs = { .cipher_begin_session = pufs_cipher_begin_session, .cipher_free_session = pufs_cipher_free_session, diff --git a/include/zephyr/crypto/hash.h b/include/zephyr/crypto/hash.h index c0de515ec3aee..4beab045564f3 100644 --- a/include/zephyr/crypto/hash.h +++ b/include/zephyr/crypto/hash.h @@ -100,7 +100,7 @@ struct hash_pkt { size_t in_len; /** Bytes previously operated upon */ - size_t *prev_len; + uint32_t *prev_len; /** * Start of the output buffer, to be allocated by diff --git a/include/zephyr/crypto/sign.h b/include/zephyr/crypto/sign.h index 598e810f7115a..f2c784da5525f 100644 --- a/include/zephyr/crypto/sign.h +++ b/include/zephyr/crypto/sign.h @@ -41,7 +41,8 @@ struct sign_ctx; struct sign_pkt; /* Function signatures for sign verification using standard signing algorithms - * like RSA2048, ECDSA256. + * like RSA2048, ECDSA256. These will be filled up by the driver for later + * calls as per the algorithm type. */ typedef int (*rsa_op_t)(struct sign_ctx *ctx, struct sign_pkt *pkt); typedef int (*ecdsa_op_t)(struct sign_ctx *ctx, struct sign_pkt *pkt); From 89028d66a7bddc50330d182bd61e4cfb9de1ef65 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 24 Sep 2024 10:48:40 +0500 Subject: [PATCH 16/58] PUFcc integration. Cipher Integration Remaining --- drivers/crypto/crypto_pufs.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 26a95d18aa941..04653d9d1d00a 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -1117,14 +1117,29 @@ static int crypto_pufs_init(const struct device *dev) { return status; } -static void pufs_irq_handler(const struct device *dev) { // TODO callback invocation in it - // int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -ECANCELED : 0); +static void pufs_irq_handler(const struct device *dev) { + + int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -ECANCELED : PUFCC_SUCCESS); + struct pufcc_intrpt_reg *intrpt_reg_ptr = (struct pufcc_intrpt_reg *)&dma_regs->interrupt; - // struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; + struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; - // TODO call callback function here + switch(lvPufsData->pufs_session_type) { + case(PUFS_SESSION_SIGN_VERIFICATION): { + lvPufsData->session_callback.sign_cb(lvPufsData->pufs_pkt.sign_pkt, status); + } break; + case(PUFS_SESSION_HASH_CALCULATION): { + lvPufsData->session_callback.hash_cb(lvPufsData->pufs_pkt.hash_pkt, status); + } break; + case(PUFS_SESSION_DECRYPTION): { + lvPufsData->session_callback.cipher_cb(lvPufsData->pufs_pkt.cipher_pkt, status); + } break; + case(PUFS_SESSION_UNDEFINED): { + LOG_ERR("%s(%d) Unsupported Session %d\n", __func__, __LINE__, lvPufsData->pufs_session_type); + } break; + } // Clear and disable interrupt intrpt_reg_ptr->intrpt_st = 1; // Set to clear From 3c6d087513c601fe3a9b1a53ac4a76d43654611e Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 24 Sep 2024 13:28:34 +0500 Subject: [PATCH 17/58] PUFcc integration. Cipher Integration In Progress --- drivers/crypto/crypto_pufs.c | 97 ++++++++++++++++++++++++++++-------- drivers/crypto/crypto_pufs.h | 2 +- 2 files changed, 76 insertions(+), 23 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 04653d9d1d00a..7f6f1ecb2f769 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -504,6 +504,9 @@ static int pufcc_rsa2048_sign_verify(struct sign_ctx *ctx, struct sign_pkt *pkt) const uint8_t *sig = ctx->sig; struct pufs_crypto_rsa2048_puk *pub_key = (struct pufs_crypto_rsa2048_puk *)ctx->pub_key; + ((struct pufs_data*)ctx->device->data)->pufs_pkt.sign_pkt = pkt; + ((struct pufs_data*)ctx->device->data)->pufs_ctx.sign_ctx = ctx; + struct pufs_crypto_addr msg_addr = { .read_addr = (uint32_t)pkt->in_buf, .len = pkt->in_len @@ -587,6 +590,9 @@ static int pufcc_ecdsa256_sign_verify(struct sign_ctx *ctx, struct sign_pkt *pkt enum pufcc_status status; struct pufs_crypto_hash hash; + ((struct pufs_data*)ctx->device->data)->pufs_pkt.sign_pkt = pkt; + ((struct pufs_data*)ctx->device->data)->pufs_ctx.sign_ctx = ctx; + struct hash_ctx lvHashCtx = { .device = ctx->device, .drv_sessn_state = NULL, @@ -1128,13 +1134,13 @@ static void pufs_irq_handler(const struct device *dev) { switch(lvPufsData->pufs_session_type) { case(PUFS_SESSION_SIGN_VERIFICATION): { - lvPufsData->session_callback.sign_cb(lvPufsData->pufs_pkt.sign_pkt, status); + lvPufsData->pufs_session_callback.sign_cb(lvPufsData->pufs_pkt.sign_pkt, status); } break; case(PUFS_SESSION_HASH_CALCULATION): { - lvPufsData->session_callback.hash_cb(lvPufsData->pufs_pkt.hash_pkt, status); + lvPufsData->pufs_session_callback.hash_cb(lvPufsData->pufs_pkt.hash_pkt, status); } break; case(PUFS_SESSION_DECRYPTION): { - lvPufsData->session_callback.cipher_cb(lvPufsData->pufs_pkt.cipher_pkt, status); + lvPufsData->pufs_session_callback.cipher_cb(lvPufsData->pufs_pkt.cipher_pkt, status); } break; case(PUFS_SESSION_UNDEFINED): { LOG_ERR("%s(%d) Unsupported Session %d\n", __func__, __LINE__, lvPufsData->pufs_session_type); @@ -1145,6 +1151,7 @@ static void pufs_irq_handler(const struct device *dev) { intrpt_reg_ptr->intrpt_st = 1; // Set to clear intrpt_reg_ptr->intrpt_en = 0; + // After execution of a callback, the irq is disabled. irq_disable(((struct pufs_config *)dev->config)->irq_num); } @@ -1181,8 +1188,12 @@ static int pufs_query_hw_caps(const struct device *dev) static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t *ctr) { - return -ENOTSUP; // TODO replace with the following - // return pufcc_decrypt_aes(...); + ((struct pufs_data*)ctx->device->data)->pufs_pkt.cipher_pkt = pkt; + ((struct pufs_data*)ctx->device->data)->pufs_ctx.cipher_ctx = ctx; + + return 0; // TODO Continue + // return pufcc_decrypt_aes() + } /* TODO Setup a crypto session */ @@ -1190,7 +1201,44 @@ static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx enum cipher_algo algo, enum cipher_mode mode, enum cipher_op op_type) { - return -ENOTSUP; + ctx->device = dev; + + ((struct pufs_data *)dev->data)->pufs_ctx.cipher_ctx = ctx; + + struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; + + uint16_t lvHashFlags = ( + CAP_NO_ENCRYPTION | CAP_SYNC_OPS | + CAP_ASYNC_OPS | CAP_NO_IV_PREFIX | + CAP_RAW_KEY | CAP_SEPARATE_IO_BUFS + ), \ + lvHashFlagsMask = 0xFFFF; + + if(algo != CRYPTO_CIPHER_ALGO_AES) { + LOG_ERR("%s(%d) UnSupported Algo. Only AES Supported\n", __func__, __LINE__); + return -ENOTSUP; + } + + if(mode != CRYPTO_CIPHER_MODE_CTR) { + LOG_ERR("%s(%d) UnSupported Algo Only CRT128 Supported\n", __func__, __LINE__); + return -ENOTSUP; + } else { + ctx->ops.ctr_crypt_hndlr = pufs_ctr_op; + } + + if(op_type != CRYPTO_CIPHER_OP_DECRYPT) { + LOG_ERR("%s(%d) UnSupported Operation. Only Decryption Supported\n", __func__, __LINE__); + return -ENOTSUP; + } + + if((ctx->flags & lvHashFlagsMask) != (lvHashFlags)) { + LOG_ERR("%s(%d) UnSupported Flags. Supported Flags_Mask:%d\n", __func__, __LINE__, lvHashFlags); + return -ENOTSUP; + } + + ctx->ops.cipher_mode = mode; + + return PUFCC_SUCCESS; } /* Tear down an established session */ @@ -1221,7 +1269,7 @@ static int pufs_cipher_free_session(const struct device *dev, struct cipher_ctx return -ENOEXEC; } else { lvPufsData->pufs_session_type = PUFS_SESSION_UNDEFINED; - lvPufsData->session_callback.cipher_cb = NULL; + lvPufsData->pufs_session_callback.cipher_cb = NULL; lvPufsData->pufs_ctx.cipher_ctx = NULL; lvPufsData->pufs_pkt.cipher_pkt = NULL; } @@ -1233,10 +1281,12 @@ static int pufs_cipher_free_session(const struct device *dev, struct cipher_ctx static int pufs_cipher_async_callback_set(const struct device *dev, cipher_completion_cb cb) { if((pufs_query_hw_caps(dev) & CAP_ASYNC_OPS) != CAP_ASYNC_OPS) { + LOG_ERR("%s(%d) Session:%s Does not Support Async Ops\n", __func__, __LINE__, \ + session_to_str(((struct pufs_data *)dev->data)->pufs_session_type)); return -ENOTSUP; } - ((struct pufs_data*)dev->data)->session_callback.cipher_cb = cb; + ((struct pufs_data*)dev->data)->pufs_session_callback.cipher_cb = cb; irq_enable(((struct pufs_config *)dev->config)->irq_num); @@ -1276,18 +1326,18 @@ static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ct uint16_t lvHashFlags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_ASYNC_OPS), lvHashFlagsMask = 0xFFFF; if(algo != CRYPTO_HASH_ALGO_SHA256) { + LOG_ERR("%s(%d) UnSupported Hash Algo. Only SHA256 Supported\n", __func__, __LINE__); return -ENOTSUP; } if((ctx->flags & lvHashFlagsMask) != (lvHashFlags)) { + LOG_ERR("%s(%d) UnSupported Flags. Supported Flags_Mask:%d\n", __func__, __LINE__, lvHashFlags); return -ENOTSUP; } if(lvPufsData->pufs_session_type != PUFS_SESSION_UNDEFINED) { - LOG_ERR("%s(%d) An Existing %s Session in Progress\n", __func__, __LINE__, \ session_to_str(lvPufsData->pufs_session_type)); - return -ENOTSUP; } else { lvPufsData->pufs_session_type = PUFS_SESSION_HASH_CALCULATION; @@ -1317,7 +1367,7 @@ static int pufs_hash_free_session(const struct device *dev, struct hash_ctx *ctx return -ENOEXEC; } else { lvPufsData->pufs_session_type = PUFS_SESSION_UNDEFINED; - lvPufsData->session_callback.hash_cb = NULL; + lvPufsData->pufs_session_callback.hash_cb = NULL; lvPufsData->pufs_ctx.hash_ctx = NULL; lvPufsData->pufs_pkt.hash_pkt = NULL; } @@ -1329,10 +1379,12 @@ static int pufs_hash_free_session(const struct device *dev, struct hash_ctx *ctx static int pufs_hash_async_callback_set(const struct device *dev, hash_completion_cb cb) { if((pufs_query_hw_caps(dev) & CAP_ASYNC_OPS) != CAP_ASYNC_OPS) { + LOG_ERR("%s(%d) Session:%s Does not Support Async Ops\n", __func__, __LINE__, \ + session_to_str(((struct pufs_data *)dev->data)->pufs_session_type)); return -ENOTSUP; } - ((struct pufs_data*)dev->data)->session_callback.hash_cb = cb; + ((struct pufs_data*)dev->data)->pufs_session_callback.hash_cb = cb; irq_enable(((struct pufs_config *)dev->config)->irq_num); @@ -1352,37 +1404,36 @@ static int pufs_sign_begin_session(const struct device *dev, struct sign_ctx *ct uint16_t lvHashFlags = (CAP_INPLACE_OPS | CAP_SYNC_OPS | CAP_ASYNC_OPS), lvHashFlagsMask = 0xFFFF; if((algo != CRYPTO_SIGN_ALGO_ECDSA256) || (algo != CRYPTO_SIGN_ALGO_RSA2048)) { + LOG_ERR("%s(%d) Unupported Algo:%d. Supported Algo \n", __func__, __LINE__, algo); return -ENOTSUP; } else { if(algo == CRYPTO_SIGN_ALGO_ECDSA256) { - ctx->ops.signing_algo = CRYPTO_SIGN_ALGO_ECDSA256; + ctx->ops.signing_algo = CRYPTO_SIGN_ALGO_ECDSA256; + ctx->ops.ecdsa_crypt_hndlr = pufcc_ecdsa256_sign_verify; } else { ctx->ops.signing_algo = CRYPTO_SIGN_ALGO_RSA2048; + ctx->ops.rsa_crypt_hndlr = pufcc_rsa2048_sign_verify; } } if((ctx->flags & lvHashFlagsMask) != (lvHashFlags)) { + LOG_ERR("%s(%d) UnSupported Flags. Supported Flags_Mask:%d\n", __func__, __LINE__, lvHashFlags); return -ENOTSUP; } if(ctx->ops.signing_mode != CRYPTO_SIGN_VERIFY) { + LOG_ERR("%s(%d) UnSupported Signing Action. Only Sign Verification Supported\n", __func__, __LINE__); return -ENOTSUP; } if(lvPufsData->pufs_session_type != PUFS_SESSION_UNDEFINED) { - LOG_ERR("%s(%d) An Existing %s Session in Progress\n", __func__, __LINE__, \ session_to_str(lvPufsData->pufs_session_type)); - return -ENOTSUP; } else { lvPufsData->pufs_session_type = PUFS_SESSION_SIGN_VERIFICATION; } - ctx->ops.rsa_crypt_hndlr = pufcc_rsa2048_sign_verify; - - ctx->ops.ecdsa_crypt_hndlr = pufcc_ecdsa256_sign_verify; - return PUFCC_SUCCESS; } @@ -1413,7 +1464,7 @@ static int pufs_sign_free_session(const struct device *dev, struct sign_ctx *ctx return -ENOEXEC; } else { lvPufsData->pufs_session_type = PUFS_SESSION_UNDEFINED; - lvPufsData->session_callback.sign_cb = NULL; + lvPufsData->pufs_session_callback.sign_cb = NULL; lvPufsData->pufs_ctx.sign_ctx = NULL; lvPufsData->pufs_pkt.sign_pkt = NULL; } @@ -1425,10 +1476,12 @@ static int pufs_sign_free_session(const struct device *dev, struct sign_ctx *ctx static int pufs_sign_async_callback_set(const struct device *dev, sign_completion_cb cb) { if((pufs_query_hw_caps(dev) & CAP_ASYNC_OPS) != CAP_ASYNC_OPS) { + LOG_ERR("%s(%d) Session:%s Does not Support Async Ops\n", __func__, __LINE__, \ + session_to_str(((struct pufs_data *)dev->data)->pufs_session_type)); return -ENOTSUP; } - ((struct pufs_data*)dev->data)->session_callback.sign_cb = cb; + ((struct pufs_data*)dev->data)->pufs_session_callback.sign_cb = cb; irq_enable(((struct pufs_config *)dev->config)->irq_num); @@ -1475,7 +1528,7 @@ static struct crypto_driver_api s_crypto_funcs = { static struct pufs_data s_pufs_session_data = { .pufs_session_type = PUFS_SESSION_UNDEFINED, - .session_callback = {NULL}, + .pufs_session_callback = {NULL}, .pufs_ctx = {NULL}, .pufs_pkt = {NULL} }; diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index 66ba3a0903236..d298d92075499 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -546,7 +546,7 @@ struct pufs_crypto_pkt { /* Device constant configuration parameters */ struct pufs_data { enum pufs_session_type pufs_session_type; - struct crypto_callbacks session_callback; + struct crypto_callbacks pufs_session_callback; struct pufs_crypto_ctx pufs_ctx; struct pufs_crypto_pkt pufs_pkt; }; From 011506e6684e088d2fa93971370ff86c87615686 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 24 Sep 2024 17:35:24 +0500 Subject: [PATCH 18/58] Primary Integration Done. --- drivers/crypto/crypto_pufs.c | 18 +++++++++++++++--- include/zephyr/crypto/cipher.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 7f6f1ecb2f769..07fb4798326aa 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -1191,9 +1191,13 @@ static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t * ((struct pufs_data*)ctx->device->data)->pufs_pkt.cipher_pkt = pkt; ((struct pufs_data*)ctx->device->data)->pufs_ctx.cipher_ctx = ctx; - return 0; // TODO Continue - // return pufcc_decrypt_aes() - + return pufcc_decrypt_aes( + (uint32_t)pkt->out_buf, (uint32_t)pkt->in_buf, + (uint32_t)pkt->in_len, pkt->prev_len, ctx->key_source, + (uint32_t)ctx->key.bit_stream, ctx->keylen, (uint32_t)ctr, + (uint32_t)ctx->mode_params.ctr_info.ctr_len, + pkt->auto_increment, ctx->mode_params.ctr_info.readback_ctr + ); } /* TODO Setup a crypto session */ @@ -1236,6 +1240,14 @@ static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx return -ENOTSUP; } + if(lvPufsData->pufs_session_type != PUFS_SESSION_UNDEFINED) { + LOG_ERR("%s(%d) An Existing %s Session in Progress\n", __func__, __LINE__, \ + session_to_str(lvPufsData->pufs_session_type)); + return -ENOTSUP; + } else { + lvPufsData->pufs_session_type = PUFS_SESSION_DECRYPTION; + } + ctx->ops.cipher_mode = mode; return PUFCC_SUCCESS; diff --git a/include/zephyr/crypto/cipher.h b/include/zephyr/crypto/cipher.h index 71d8e590b41be..1e898b9df90c6 100644 --- a/include/zephyr/crypto/cipher.h +++ b/include/zephyr/crypto/cipher.h @@ -24,6 +24,13 @@ * @{ */ +/** + * Encryption Key Source + */ +enum cipher_key_source { + CRYPTO_KEY_SW = 0, + CRYPTO_KEY_OTP = 1 +}; /** Cipher Algorithm */ enum cipher_algo { @@ -94,6 +101,14 @@ struct ctr_params { * such that ivlen + ctr_len = keylen */ uint32_t ctr_len; + + /** + * Check whether we want to readback the ctr (iv) + * for the cases where we might be doing chunk wise + * decryption and each chunk could be encrypted with + * a separate IV for strengthening the security. + */ + bool readback_ctr; }; struct gcm_params { @@ -125,6 +140,12 @@ struct cipher_ctx { void *handle; } key; + /* + * This indicates if the encryption key will be provided by + * software or it has to be fetched from secure (OTP) memory. + */ + enum cipher_key_source key_source; + /** The device driver instance this crypto context relates to. Will be * populated by the begin_session() API. */ @@ -191,6 +212,11 @@ struct cipher_pkt { */ uint8_t *out_buf; + /** + * Should the destination address be auto incrementing + */ + bool auto_increment; + /** Size of the out_buf area allocated by the application. Drivers * should not write past the size of output buffer. */ @@ -201,6 +227,12 @@ struct cipher_pkt { */ int out_len; + /** + * Bytes previously operated upon. This information is useful + * if the decryption is performed in chunks. + * */ + uint32_t prev_len; + /** Context this packet relates to. This can be useful to get the * session details, especially for async ops. Will be populated by the * cipher_xxx_op() API based on the ctx parameter. From 1fc4d7421d831e05a885218fa2c34d62630b6a71 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 24 Sep 2024 18:04:05 +0500 Subject: [PATCH 19/58] Primary Integration Done. Added comments and initialized unused pointers for reference to non-implementation --- drivers/crypto/crypto_pufs.c | 64 ++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 28 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 07fb4798326aa..2780450e2fc38 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -1180,7 +1180,12 @@ static void pufs_irq_Init(void) { * various crypto related operations. *********************************************************/ -/* Query the driver capabilities */ +/** + * Query the driver capabilities + * Not all the Modules of PUFs support all flags. + * Please Check individual cipher/hash/sign_begin_session + * interfaces to get the information of supported flags. + * */ static int pufs_query_hw_caps(const struct device *dev) { return PUFS_HW_CAP; @@ -1200,7 +1205,31 @@ static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t * ); } -/* TODO Setup a crypto session */ +/* Following cipher operations (block, cbc, ccm and gcm) are not supported yet. + */ +__unused static int pufs_block_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt) +{ + return -ENOTSUP; +} + +__unused static int pufs_cbc_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, + uint8_t *iv) +{ + return -ENOTSUP; +} + +__unused static int pufs_ccm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, + uint8_t *nonce) +{ + return -ENOTSUP; +} + +__unused static int pufs_gcm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, + uint8_t *nonce) +{ + return -ENOTSUP; +} + static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx *ctx, enum cipher_algo algo, enum cipher_mode mode, enum cipher_op op_type) @@ -1224,10 +1253,14 @@ static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx } if(mode != CRYPTO_CIPHER_MODE_CTR) { - LOG_ERR("%s(%d) UnSupported Algo Only CRT128 Supported\n", __func__, __LINE__); + LOG_ERR("%s(%d) UnSupported Algo. Only CTR Mode Supported\n", __func__, __LINE__); return -ENOTSUP; } else { ctx->ops.ctr_crypt_hndlr = pufs_ctr_op; + ctx->ops.block_crypt_hndlr = pufs_block_op; + ctx->ops.cbc_crypt_hndlr = pufs_cbc_op; + ctx->ops.ccm_crypt_hndlr = pufs_ccm_op; + ctx->ops.gcm_crypt_hndlr = pufs_gcm_op; } if(op_type != CRYPTO_CIPHER_OP_DECRYPT) { @@ -1500,31 +1533,6 @@ static int pufs_sign_async_callback_set(const struct device *dev, sign_completio return PUFCC_SUCCESS; } -/* Following cipher operations are not supported yet. - */ -__unused static int block_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt) -{ - return -ENOTSUP; -} - -__unused static int pufs_cbc_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, - uint8_t *iv) -{ - return -ENOTSUP; -} - -__unused static int pufs_ccm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, - uint8_t *nonce) -{ - return -ENOTSUP; -} - -__unused static int pufs_gcm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, - uint8_t *nonce) -{ - return -ENOTSUP; -} - static struct crypto_driver_api s_crypto_funcs = { .cipher_begin_session = pufs_cipher_begin_session, .cipher_free_session = pufs_cipher_free_session, From 78e91483181f9c25bc0edde0466f0853c348c4eb Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 25 Sep 2024 13:59:18 +0500 Subject: [PATCH 20/58] Removed OTP Part since a new API+Driver of OTP shall be created. --- drivers/crypto/crypto_pufs.c | 283 +---------------------------------- drivers/crypto/crypto_pufs.h | 111 -------------- 2 files changed, 1 insertion(+), 393 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 2780450e2fc38..bee3c6f73207b 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -96,8 +96,6 @@ struct pufcc_ecc_param ecc_param_nistp256 = { // Base register addresses of different PUFcc modules static struct pufcc_dma_regs *dma_regs; -static struct pufcc_rt_regs *rt_regs; -static struct pufcc_otp_mem *otp_mem; static struct pufcc_hmac_regs *hmac_regs; static struct pufcc_crypto_regs *crypto_regs; static struct pufcc_sp38a_regs *sp38a_regs; @@ -108,14 +106,10 @@ static struct pufcc_pkc_regs *pkc_regs; ****************************************************************************/ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, struct pufs_crypto_addr *msg_addr); -static enum pufcc_status otp_range_check(uint32_t addr, uint32_t len); -static int rwlck_index_get(uint32_t idx); static void reverse(uint8_t *dst, const uint8_t *src, size_t len); static uint32_t be2le(uint32_t var); static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, uint32_t error_mask); -enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, - enum pufcc_otp_lock *lock_val); static char *session_to_str(enum pufs_session_type inSession) { return ((inSession == PUFS_SESSION_HASH_CALCULATION)?"Hash":\ @@ -699,238 +693,6 @@ static int pufcc_ecdsa256_sign_verify(struct sign_ctx *ctx, struct sign_pkt *pkt return PUFCC_SUCCESS; } -/** - * @fn pufcc_otp_setup_wait - * @brief Wait for the PUFrt module setup during power on - * - * @return PUFCC_SUCCESS if OTP is setup successfully, otherwise an error code - */ -static enum pufcc_status pufcc_otp_setup_wait(void) { - enum pufcc_status status = busy_wait(&rt_regs->status, PUFCC_RT_ERROR_MASK); - - return status; -} - -/** - * @fn pufcc_program_otp - * @brief Write data to an OTP slot. - * PUFcc OTP memory contains 1024 bytes and is divided into 32 - * individual slots of 32 bytes each. - * - * @param[in] in_buf Buffer containing data to be written to OTP - * @param[in] len Length of the input buffer - * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 - * @return PUFCC_SUCCESS on success, otherwise an error code. - */ -enum pufcc_status pufcc_program_otp(const uint8_t *in_buf, uint32_t len, - enum pufcc_otp_slot otp_slot) { - enum pufcc_status check; - uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; - uint32_t start_index = addr / PUFCC_WORD_SIZE; - enum pufcc_otp_lock lock = PUFCC_OTP_NA; - - if ((check = otp_range_check(addr, len)) != PUFCC_SUCCESS) return check; - - // Return error if write access is locked - pufcc_get_otp_rwlck(otp_slot, &lock); - if (lock != PUFCC_OTP_RW) return PUFCC_E_DENY; - - // Program the OTP slot - for (uint32_t i = 0; i < len; i += 4) { - union { - uint32_t word; - uint8_t byte[4]; - } otp_word; - for (int8_t j = 3; j >= 0; j--) // reserve, default 0xff - otp_word.byte[j] = ((i + 3 - j) < len) ? in_buf[i + 3 - j] : 0xff; - - otp_mem->otp[start_index + (i / 4)] = otp_word.word; - } - - return PUFCC_SUCCESS; -} - -/** - * @fn pufcc_read_otp - * @brief Read data from an OTP slot. - * PUFcc OTP memory contains 1024 bytes and is divided into 32 - * individual slots of 32 bytes each. - * - * @param[in] out_buf Buffer to read data into - * @param[in] len Length of the data to read - * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 - * @return PUFCC_SUCCESS on success, otherwise an error code. - */ -enum pufcc_status pufcc_read_otp(uint8_t *out_buf, uint32_t len, - enum pufcc_otp_slot otp_slot) { - enum pufcc_status check; - uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; - uint32_t word, start_index, wlen; - enum pufcc_otp_lock lock = PUFCC_OTP_RW; // default value - - if ((check = otp_range_check(addr, len)) != PUFCC_SUCCESS) return check; - - // Return error if read access is locked - pufcc_get_otp_rwlck(otp_slot, &lock); - if (lock == PUFCC_OTP_NA) return PUFCC_E_DENY; - - wlen = len / PUFCC_WORD_SIZE; - start_index = addr / PUFCC_WORD_SIZE; - - if (wlen > 0) { - memcpy(out_buf, (void *)(otp_mem->otp + start_index), - wlen * PUFCC_WORD_SIZE); - - uint32_t *out32 = (uint32_t *)out_buf; - for (size_t i = 0; i < wlen; ++i) *(out32 + i) = be2le(*(out32 + i)); - } - - if (len % PUFCC_WORD_SIZE != 0) { - out_buf += wlen * PUFCC_WORD_SIZE; - word = be2le(*(otp_mem->otp + start_index + wlen)); - memcpy(out_buf, &word, len % PUFCC_WORD_SIZE); - } - - return PUFCC_SUCCESS; -} - -/** - * @fn pufcc_lock_otp - * @brief Lock an OTP key slot according to passed-in lock value. - * - * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 - * @param[in] len Length of the OTP slot to be locked - * @param[in] lock Value of the lock to be placed - * @return PUFCC_SUCCESS on success, otherwise an error code. - */ -enum pufcc_status pufcc_lock_otp(enum pufcc_otp_slot otp_slot, uint32_t len, - enum pufcc_otp_lock lock) { - enum pufcc_status check; - uint32_t lock_val = lock, shift = 0, start = 0, end = 0, mask = 0, val32 = 0; - int rwlock_index; - uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; - - if ((check = otp_range_check(addr, len)) != PUFCC_SUCCESS) return check; - - // Set end and start indices of OTP words - end = (len + 3) / 4; - start = addr / PUFCC_WORD_SIZE; - - for (uint32_t i = 0; i < end; i++) { - int idx = start + i; - - // Get the index of RWLCK register corresponding to current OTP word index - if ((rwlock_index = rwlck_index_get(idx)) == -1) { - return PUFCC_E_ERROR; - } - - // Get shift size for lock value to be written to RWLCK register according - // to OTP word index - shift = (idx % PUFCC_OTP_WORDS_PER_RWLCK_REG) * - PUFCC_OTP_RWLCK_REG_BITS_PER_OTP_WORD; - // Update lock value for current 'rwlock_index' - val32 |= lock_val << shift; - // Update mask value for current 'rwlock_index' - mask |= 0xF << shift; - - // If we have fully utilized RWLCK register at 'rwlock_index' or this is - // the end of OTP range that we are locking then write the lock value in - // RWLCK register at 'rwlock_index' - if (shift == 28 || i == end - 1) { - // Read modify write - val32 |= (rt_regs->pif[rwlock_index] & (~mask)); - rt_regs->pif[rwlock_index] = val32; - - // Clear values for next iteration - val32 = 0; - mask = 0; - } - } - - return PUFCC_SUCCESS; -} - -/** - * @fn pufcc_zeroize_otp - * @brief Zeroize an OTP key slot (32 bytes) permanently. - * - * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 - * @return PUFCC_SUCCESS on success, otherwise an error code. - */ -enum pufcc_status pufcc_zeroize_otp(enum pufcc_otp_slot otp_slot) { - enum pufcc_status status; - - if (otp_slot < PUFCC_OTPKEY_0 || otp_slot > PUFCC_OTPKEY_31) { - status = PUFCC_E_INVALID; - } else { - uint32_t zeroize_cmd = - (otp_slot - PUFCC_OTPKEY_0) + PUFCC_OTP_ZEROIZE_BASE_CMD; - - rt_regs->otp_zeroize = zeroize_cmd; - - // Wait on busy status - status = busy_wait(&rt_regs->status, PUFCC_RT_ERROR_MASK); - } - - return status; -} - -/** - * @fn pufcc_get_otp_rwlck - * @brief Get the read write lock value of passed-in OTP slot. This function - * assumes that the lock value of all the words of an OTP is same as that - * of the first word of that slot - * - * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 - * @param[out] lock_val Lock address to return the lock value in - * @return PUFCC_SUCCESS on success, otherwise and error code - */ -enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, - enum pufcc_otp_lock *lock_val) { - enum pufcc_status check; - uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; - - if ((check = otp_range_check(addr, 4)) != PUFCC_SUCCESS) return check; - - // Get OTP word index - int index = addr / PUFCC_WORD_SIZE; - - // Get offset of the lock value within RWLCK register corresponding to this - // OTP word - int rwlck_offset = (index % PUFCC_OTP_WORDS_PER_RWLCK_REG) * - PUFCC_OTP_RWLCK_REG_BITS_PER_OTP_WORD; - - // Get the index of RWLCK register corresponding to current OTP word index - // read lock value at that index - index = rwlck_index_get(index); - uint32_t lck = (rt_regs->pif[index] >> rwlck_offset) & PUFCC_PIF_RWLCK_MASK; - - switch (lck) { - // Read write access - case PUFCC_OTP_RWLCK_RW_0: - case PUFCC_OTP_RWLCK_RW_1: - case PUFCC_OTP_RWLCK_RW_2: - case PUFCC_OTP_RWLCK_RW_3: - case PUFCC_OTP_RWLCK_RW_4: - *lock_val = PUFCC_OTP_RW; - break; - - // Read only access - case PUFCC_OTP_RWLCK_RO_0: - case PUFCC_OTP_RWLCK_RO_1: - case PUFCC_OTP_RWLCK_RO_2: - *lock_val = PUFCC_OTP_RO; - break; - - // All other values indicate no access - default: - *lock_val = PUFCC_OTP_NA; - break; - } - - return PUFCC_SUCCESS; -} - /** * @fn rsa_p1v15_verify * @brief Verify input RSA2048 decrypted message according to PKCS#1 v1.5 RSA @@ -1010,23 +772,6 @@ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, return PUFCC_SUCCESS; } -/** - * @fn rwlck_index_get - * @brief Get the index of RWLCK register corresponding to passed-in OTP word - * index. - * - * @param[in] idx OTP word index for which to get the RWLCK register index for - * @return Index of the RWLCK register - */ -static int rwlck_index_get(uint32_t idx) { - uint32_t rwlck_idx = idx / PUFCC_OTP_WORDS_PER_RWLCK_REG; - - if (rwlck_idx >= PUFCC_PIF_MAX_RWLOCK_REGS) return -1; - - // Return the actual index of RWCLK register in PIF registers group - return PUFCC_PIF_RWLCK_START_INDEX + rwlck_idx; -} - /** * @fn reverse * @brief Reverse input byte array. @@ -1053,25 +798,6 @@ static uint32_t be2le(uint32_t var) { ((0x0000ff00 & var) << 8) | ((0x000000ff & var) << 24)); } -/** - * @fn otp_range_check - * @brief Check range validity of the input OTP address - * - * @param[in] addr OTP address - * @param[in] len Length of OTP after OTP address - * @return 4 byte word with reversed endianness - * @return PUFCC_SUCCESS if OTP address and range is valid, otherwise - * an error code. - */ -static enum pufcc_status otp_range_check(uint32_t addr, uint32_t len) { - // word-aligned OTP address check - if ((addr % PUFCC_WORD_SIZE) != 0) return PUFCC_E_ALIGN; - // OTP boundary check - if ((len > PUFCC_OTP_LEN) || (addr > (PUFCC_OTP_LEN - len))) - return PUFCC_E_OVERFLOW; - return PUFCC_SUCCESS; -} - /** * @fn busy_wait * @brief Waits on busy bit of the passed-in status register till it gets @@ -1102,25 +828,18 @@ static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, } static int crypto_pufs_init(const struct device *dev) { - enum pufcc_status status; // Initialize base addresses of different PUFcc modules dma_regs = (struct pufcc_dma_regs *)((struct pufs_config*)dev->config)->base; - rt_regs = (struct pufcc_rt_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_RT_OFFSET); - otp_mem = (struct pufcc_otp_mem *)(((struct pufs_config*)dev->config)->base + PUFCC_RT_OFFSET + - PUFCC_RT_OTP_OFFSET); hmac_regs = (struct pufcc_hmac_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_HMAC_OFFSET); crypto_regs = (struct pufcc_crypto_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_CRYPTO_OFFSET); sp38a_regs = (struct pufcc_sp38a_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_SP38A_OFFSET); pkc_regs = (struct pufcc_pkc_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_PKC_OFFSET); - // Wait for OTP setup - status = pufcc_otp_setup_wait(); - // Connect the IRQ ((struct pufs_config*)dev->config)->irq_init(); - return status; + return PUFCC_SUCCESS; } static void pufs_irq_handler(const struct device *dev) { diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index d298d92075499..9283ba2694996 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -18,37 +18,6 @@ #define PUFCC_WORD_SIZE 4 #define PUFCC_BUSY_BIT_MASK 0x00000001 -/*** RT and OTP defines ***/ -#define PUFCC_RT_OFFSET 0x3000 -#define PUFCC_RT_OTP_OFFSET 0x400 -#define PUFCC_RT_ERROR_MASK 0x0000001e -#define PUFCC_OTP_LEN 1024 -#define PUFCC_OTP_KEY_LEN 32 -#define PUFCC_OTP_ZEROIZE_BASE_CMD 0x80 - -// One read/write lock register controls 8 OTP words -#define PUFCC_OTP_WORDS_PER_RWLCK_REG 8 - -// 4 bits are reserved for lock value of one OTP word in read/write lock -// register -#define PUFCC_OTP_RWLCK_REG_BITS_PER_OTP_WORD 4 -#define PUFCC_PIF_RWLCK_MASK 0xF -#define PUFCC_PIF_MAX_RWLOCK_REGS \ - (PUFCC_OTP_LEN / PUFCC_WORD_SIZE / PUFCC_OTP_WORDS_PER_RWLCK_REG) - -// Start index of the RWLCK register in PIF registers group -#define PUFCC_PIF_RWLCK_START_INDEX 32 - -// Define all possible OTP lock values -#define PUFCC_OTP_RWLCK_RW_0 0x0 // Read Write access -#define PUFCC_OTP_RWLCK_RW_1 0x1 // Read Write access -#define PUFCC_OTP_RWLCK_RW_2 0x2 // Read Write access -#define PUFCC_OTP_RWLCK_RW_3 0x4 // Read Write access -#define PUFCC_OTP_RWLCK_RW_4 0x8 // Read Write access -#define PUFCC_OTP_RWLCK_RO_0 0x3 // Read Only access -#define PUFCC_OTP_RWLCK_RO_1 0x7 // Read Only access -#define PUFCC_OTP_RWLCK_RO_2 0xb // Read Only access - /*** DMA defines ***/ #define PUFCC_DMA_KEY_DST_HASH 0x1 #define PUFCC_DMA_KEY_DST_SP38A 0x8 @@ -152,49 +121,6 @@ enum pufcc_status { PUFCC_E_TIMEOUT, // Operation timed out. }; -// PUFcc key slots; 32 slots of 256 bits each -enum pufcc_otp_slot { - PUFCC_OTPKEY_0, // OTP key slot 0, 256 bits - PUFCC_OTPKEY_1, // OTP key slot 1, 256 bits - PUFCC_OTPKEY_2, // OTP key slot 2, 256 bits - PUFCC_OTPKEY_3, // OTP key slot 3, 256 bits - PUFCC_OTPKEY_4, // OTP key slot 4, 256 bits - PUFCC_OTPKEY_5, // OTP key slot 5, 256 bits - PUFCC_OTPKEY_6, // OTP key slot 6, 256 bits - PUFCC_OTPKEY_7, // OTP key slot 7, 256 bits - PUFCC_OTPKEY_8, // OTP key slot 8, 256 bits - PUFCC_OTPKEY_9, // OTP key slot 9, 256 bits - PUFCC_OTPKEY_10, // OTP key slot 10, 256 bits - PUFCC_OTPKEY_11, // OTP key slot 11, 256 bits - PUFCC_OTPKEY_12, // OTP key slot 12, 256 bits - PUFCC_OTPKEY_13, // OTP key slot 13, 256 bits - PUFCC_OTPKEY_14, // OTP key slot 14, 256 bits - PUFCC_OTPKEY_15, // OTP key slot 15, 256 bits - PUFCC_OTPKEY_16, // OTP key slot 16, 256 bits - PUFCC_OTPKEY_17, // OTP key slot 17, 256 bits - PUFCC_OTPKEY_18, // OTP key slot 18, 256 bits - PUFCC_OTPKEY_19, // OTP key slot 19, 256 bits - PUFCC_OTPKEY_20, // OTP key slot 20, 256 bits - PUFCC_OTPKEY_21, // OTP key slot 21, 256 bits - PUFCC_OTPKEY_22, // OTP key slot 22, 256 bits - PUFCC_OTPKEY_23, // OTP key slot 23, 256 bits - PUFCC_OTPKEY_24, // OTP key slot 24, 256 bits - PUFCC_OTPKEY_25, // OTP key slot 25, 256 bits - PUFCC_OTPKEY_26, // OTP key slot 26, 256 bits - PUFCC_OTPKEY_27, // OTP key slot 27, 256 bits - PUFCC_OTPKEY_28, // OTP key slot 28, 256 bits - PUFCC_OTPKEY_29, // OTP key slot 29, 256 bits - PUFCC_OTPKEY_30, // OTP key slot 30, 256 bits - PUFCC_OTPKEY_31, // OTP key slot 31, 256 bits -}; - -// OTP lock types -enum pufcc_otp_lock { - PUFCC_OTP_NA = 0xF, // No-Access - PUFCC_OTP_RO = 0x3, // Read-Only - PUFCC_OTP_RW = 0x0, // Read-Write -}; - // PUFcc read/write types enum pufcc_dma_rw_type { AUTO_INCREMENT, FIXED_RW }; @@ -344,43 +270,6 @@ struct pufcc_ecc_param { /***************************************************************************** * PUFcc register maps ****************************************************************************/ -// OTP memory map -struct pufcc_otp_mem { - uint32_t otp[256]; -}; - -struct pufcc_rt_regs { - volatile uint32_t pif[64]; - uint32_t _pad1[64]; - volatile uint32_t ptr[16]; - volatile uint32_t ptc[16]; - volatile uint32_t ptm[2]; - uint32_t _pad2[6]; - volatile uint32_t rn; - volatile uint32_t rn_status; - volatile uint32_t healthcfg; - volatile uint32_t feature; - volatile uint32_t interrupt; - volatile uint32_t otp_psmsk[2]; - volatile uint32_t puf_psmsk; - volatile uint32_t version; - volatile uint32_t status; - volatile uint32_t cfg; - volatile uint32_t set_pin; - volatile uint32_t auto_repair; - volatile uint32_t ini_off_chk; - volatile uint32_t repair_pgn; - volatile uint32_t repair_reg; - volatile uint32_t puf_qty_chk; - volatile uint32_t puf_enroll; - volatile uint32_t puf_zeroize; - volatile uint32_t set_flag; - volatile uint32_t otp_zeroize; - uint32_t _pad3[3]; - volatile uint32_t puf[64]; - volatile uint32_t otp[256]; -}; - // DMA module register map struct pufcc_dma_regs { volatile uint32_t version; From bdda9c9ac0ae23667626ae30b40f6f7f84d9cdcd Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 26 Sep 2024 00:08:30 +0500 Subject: [PATCH 21/58] Corrected the CONFIG_RISCV_EXCEPTION_MASK value from 0x1F to 0xFF --- drivers/crypto/crypto_pufs.c | 1 - soc/rapidsilicon/virgo/Kconfig | 3 --- soc/rapidsilicon/virgo/Kconfig.defconfig | 12 ++++++------ 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index bee3c6f73207b..b5e4d52b78f78 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -1279,7 +1279,6 @@ static const struct pufs_config s_pufs_configuration = { .dev = DEVICE_DT_INST_GET(0) }; - DEVICE_DT_INST_DEFINE(0, crypto_pufs_init, NULL, &s_pufs_session_data, &s_pufs_configuration, POST_KERNEL, diff --git a/soc/rapidsilicon/virgo/Kconfig b/soc/rapidsilicon/virgo/Kconfig index 185fef7356901..2fdbbd380b702 100644 --- a/soc/rapidsilicon/virgo/Kconfig +++ b/soc/rapidsilicon/virgo/Kconfig @@ -27,9 +27,6 @@ if GEN_IRQ_VECTOR_TABLE default IRQ_VECTOR_TABLE_JUMP_BY_ADDRESS endchoice - config RISCV_MCAUSE_EXCEPTION_MASK - default 0x32 - endif config SOC_ANDES_V5_EXECIT diff --git a/soc/rapidsilicon/virgo/Kconfig.defconfig b/soc/rapidsilicon/virgo/Kconfig.defconfig index 760cc620aded2..4a11fd26a7d32 100644 --- a/soc/rapidsilicon/virgo/Kconfig.defconfig +++ b/soc/rapidsilicon/virgo/Kconfig.defconfig @@ -25,22 +25,22 @@ config RISCV_SOC_INTERRUPT_INIT config RISCV_GP default y +config RISCV_MCAUSE_EXCEPTION_MASK + default 0xFFF + config NUM_2ND_LEVEL_AGGREGATORS default 1 config 2ND_LVL_ISR_TBL_OFFSET - default 12 + default 0 config 2ND_LVL_INTR_00_OFFSET - default 11 + default 0 config MAX_IRQ_PER_AGGREGATOR default 52 -config 2ND_LEVEL_INTERRUPT_BITS - default 8 - config NUM_IRQS - default 50 + default 52 endif # SOC_SERIES_VIRGO \ No newline at end of file From cc2fb46988f490179fbb74a250ce781633391b1e Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 26 Sep 2024 19:31:19 +0500 Subject: [PATCH 22/58] Refactoring crypto_pufs.c to retain pufcc.c in a modular way --- drivers/crypto/CMakeLists.txt | 2 +- drivers/crypto/crypto_pufs.c | 884 ++-------------------- drivers/crypto/crypto_pufs.h | 402 +--------- drivers/crypto/pufcc.c | 1343 +++++++++++++++++++++++++++++++++ drivers/crypto/pufcc.h | 642 ++++++++++++++++ include/zephyr/crypto/hash.h | 8 +- 6 files changed, 2052 insertions(+), 1229 deletions(-) create mode 100644 drivers/crypto/pufcc.c create mode 100644 drivers/crypto/pufcc.h diff --git a/drivers/crypto/CMakeLists.txt b/drivers/crypto/CMakeLists.txt index 222bf000875ab..2d4e57fc5edea 100644 --- a/drivers/crypto/CMakeLists.txt +++ b/drivers/crypto/CMakeLists.txt @@ -12,5 +12,5 @@ zephyr_library_sources_ifdef(CONFIG_CRYPTO_NPCX_SHA crypto_npcx_sha.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCHP_XEC_SYMCR crypto_mchp_xec_symcr.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_IT8XXX2_SHA crypto_it8xxx2_sha.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCUX_DCP crypto_mcux_dcp.c) -zephyr_library_sources_ifdef(CONFIG_CRYPTO_PUF_SECURITY crypto_pufs.c) +zephyr_library_sources_ifdef(CONFIG_CRYPTO_PUF_SECURITY crypto_pufs.c pufcc.c) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index b5e4d52b78f78..f4bfa261b3e45 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -26,828 +26,31 @@ LOG_MODULE_REGISTER(crypto_puf_security); CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_ASYNC_OPS | \ CAP_NO_IV_PREFIX | CAP_NO_ENCRYPTION | CAP_NO_SIGNING) -/***************************************************************************** - * Macros - ****************************************************************************/ -#define SG_DMA_MAX_DSCS_SIZE (512 - 8) // Enough for 15 descriptors -#define BUFFER_SIZE 512 -#define PUFCC_MAX_BUSY_COUNT 8000000 // Max busy count for processing 10MB data -#define CTR_MODE_BLOCK_SIZE 16 - -/***************************************************************************** - * Local variable declarations - ****************************************************************************/ -uint8_t __pufcc_descriptors[BUFFER_SIZE]; -static struct pufcc_sg_dma_desc *sg_dma_descs = - (struct pufcc_sg_dma_desc *)__pufcc_descriptors; -static uint8_t pufcc_buffer[BUFFER_SIZE]; - -// PUFcc microprogram for RSA2048 -static uint32_t rsa_2048_mprog[] = { - 0x33cdac81, 0x6817434e, 0x4283ad5d, 0x27499978, 0x8a000040, 0x0a1080c0, - 0xc3800b00, 0x081810c6, 0xfc000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000}; - -// PUFcc microprogram for ECDSA256 -static uint32_t p256_ecdsa_mprog[] = { - 0xb1703302, 0x0f91d3f8, 0x004ae67d, 0x8f7093c5, 0x8a000068, 0x0a014088, - 0xc3000000, 0xa0624000, 0x43000100, 0x20824000, 0x0a014090, 0xc3000000, - 0x20624800, 0x43000100, 0xa0824800, 0x0a014090, 0xc3000600, 0x8900101e, - 0x8e000028, 0x8a000068, 0x8a014800, 0x8a028070, 0x43000400, 0x0901101e, - 0x8e000028, 0x8a000068, 0x8a014800, 0x0a028088, 0x43000400, 0x0902101e, - 0x8e000048, 0x8a028058, 0x0a03c060, 0x92050020, 0x8a064808, 0x41801600, - 0x8900101e, 0x09011028, 0x8e000048, 0x0a028078, 0x8a03c080, 0x92050020, - 0x8a064810, 0x41801600, 0x0902101e, 0x89031028, 0x8e000048, 0x8a028800, - 0x0a03c808, 0x0a050810, 0x0a064818, 0xc1000700, 0x20a25000, 0x8900101e, - 0x8e000028, 0x8a000068, 0x8a014800, 0x43000200, 0x8900101e, 0x1c110800, - 0x18025800, 0xfc000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000}; - -// EC NIST-P256 parameters -struct pufcc_ecc_param ecc_param_nistp256 = { - "\xff\xff\xff\xff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" - "\xff\xff", // prime - "\xff\xff\xff\xff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" - "\xff\xfc", // a - "\x5a\xc6\x35\xd8\xaa\x3a\x93\xe7\xb3\xeb\xbd\x55\x76\x98\x86" - "\xbc\x65\x1d\x06\xb0\xcc\x53\xb0\xf6\x3b\xce\x3c\x3e\x27\xd2" - "\x60\x4b", // b - "\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" - "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98" - "\xc2\x96", // px - "\x4f\xe3\x42\xe2\xfe\x1a\x7f\x9b\x8e\xe7\xeb\x4a\x7c\x0f\x9e" - "\x16\x2b\xce\x33\x57\x6b\x31\x5e\xce\xcb\xb6\x40\x68\x37\xbf" - "\x51\xf5", // py - "\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff" - "\xff\xbc\xe6\xfa\xad\xa7\x17\x9e\x84\xf3\xb9\xca\xc2\xfc\x63" - "\x25\x51" // order -}; - -// Base register addresses of different PUFcc modules -static struct pufcc_dma_regs *dma_regs; -static struct pufcc_hmac_regs *hmac_regs; -static struct pufcc_crypto_regs *crypto_regs; -static struct pufcc_sp38a_regs *sp38a_regs; -static struct pufcc_pkc_regs *pkc_regs; - -/***************************************************************************** - * Local function declarations - ****************************************************************************/ -static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, - struct pufs_crypto_addr *msg_addr); -static void reverse(uint8_t *dst, const uint8_t *src, size_t len); -static uint32_t be2le(uint32_t var); -static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, - uint32_t error_mask); - static char *session_to_str(enum pufs_session_type inSession) { return ((inSession == PUFS_SESSION_HASH_CALCULATION)?"Hash":\ ((inSession == PUFS_SESSION_DECRYPTION)?"Decryption":\ ((inSession == PUFS_SESSION_SIGN_VERIFICATION)?"Sign_Verification":"Unknown"))); } -/***************************************************************************** - * API functions - ****************************************************************************/ -/** - * @fn pufcc_calc_sha256_hash - * @brief Calculates SHA256 hash - * - * @param[in] ctx Context of the ecdsa hash calculation. - * @param[inout] pkt Input and output data related parameters for hash calculation. - * @return PUFCC_SUCCESS on success, otherwise an error code. - */ -static enum pufcc_status pufcc_calc_sha256_hash(struct hash_ctx *ctx, - struct hash_pkt *pkt) -{ - enum pufcc_status status; - struct pufcc_intrpt_reg intrpt_reg = {0}; - struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; - struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; - struct pufcc_dma_key_cfg0_reg dma_key_cfg0_reg = {0}; - struct pufcc_start_reg start_reg = {0}; - - // Set 'intrpt' register values - intrpt_reg.intrpt_st = 1; // Write 1 to clear interrupt - intrpt_reg.intrpt_en = 0; // Disable interrupt - - // Set dma_dsc_cfg_4 reg values - dma_dsc_cfg_4_reg.head = 1; - dma_dsc_cfg_4_reg.tail = 1; - - // set values for key_cfg_0 register - dma_key_cfg0_reg.key_dst = PUFCC_DMA_KEY_DST_HASH; - - // Set values for start register - start_reg.start_p = 1; // Start operation bit - - // Set values for HMAC config register - struct pufcc_hmac_config_reg hmac_config_reg = { - .variant = PUFCC_HMAC_VARIANT_SHA256, // Shah 256 - .function = PUFCC_HMAC_FUNCTION_HASH, // Hash - }; - - /*** Configure DMA registers ***/ - // Set dma_cfg_0 register - REG_WRITE_32(&dma_regs->cfg_0, &dma_cfg_0_reg); - - // Set data source address in dsc_cfg_0 register - dma_regs->dsc_cfg_0 = (uint32_t)pkt->in_buf; - - // Set data length in dsc_cfg_2 register - dma_regs->dsc_cfg_2 = pkt->in_len; - - // Set the dsc_cfg_4 register to values defined above - REG_WRITE_32(&dma_regs->dsc_cfg_4, &dma_dsc_cfg_4_reg); - - // Set the key_cfg_0 register to values defined above - REG_WRITE_32(&dma_regs->key_cfg_0, &dma_key_cfg0_reg); - - // Write intrpt register to values defined above - REG_WRITE_32(&dma_regs->interrupt, &intrpt_reg); - - /** Configure HMAC registers **/ - // Set the config register to values defined above - REG_WRITE_32(&hmac_regs->cfg, &hmac_config_reg); - - // Write previous length in HMAC plen register - hmac_regs->plen = hmac_regs->alen; - - // Write intrpt register to values defined above - REG_WRITE_32(&hmac_regs->interrupt, &intrpt_reg); - - // Start the DMA operation by writing to its start register - REG_WRITE_32(&dma_regs->start, &start_reg); - - // Poll on busy status - status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); - - if (status != PUFCC_SUCCESS) { - return status; - } - - if (hmac_regs->status) { - return PUFCC_E_ERROR; - } - - // Read the calculated hash - for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { - ((uint32_t *)pkt->out_buf)[i] = be2le(crypto_regs->dgst_out[i]); - } - - pkt->out_len = PUFCC_SHA_256_LEN; - - return PUFCC_SUCCESS; -} - -/** - * @fn pufcc_calc_sha256_hash_sg - * @brief Calculates SHA256 hash of non-contiguous data. - * All non contiguous data addresses can be passed in as a single linked - * list in the form of 'hash_pkr' struct as 'pkt' parameter - * or this function can be invoked multiple times with partial data - * address info in the linked list by setting the 'head' and 'tail' - * params accordingly as detailed below against each param. In case of - * partial data address info and hence multiple invocations, we also need - * to pass in previously calculated hash values to every invocation - * after the head one and the accumulated length of all previous - * messages/data. - * - * Note: In case of multiple data chunks either in a single linked list - * or as partial linked lists using multiple invocations the sizes of all - * chunks must be multiples of 64 bytes except the last chunk. - * - * @param[in] ctx Context of the scatter gather hash calculation. - * @param[inout] pkt Input and output data related parameters for hash calculation. - * @return PUFCC_SUCCESS on success, otherwise an error code. - */ -static enum pufcc_status pufcc_calc_sha256_hash_sg(struct hash_ctx *ctx, - struct hash_pkt *pkt) { - enum pufcc_status status; - uint32_t plen = 0; - uint8_t desc_count = 0; - bool lvHead = pkt->head, lvTail = pkt->tail; - struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; - struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; - struct pufcc_dma_key_cfg0_reg dma_key_cfg0_reg = {0}; - struct pufcc_intrpt_reg intrpt_reg = {0}; - struct pufcc_start_reg start_reg = {0}; - struct pufcc_hmac_config_reg hmac_config_reg = {0}; - - if (!lvHead) plen = *pkt->prev_len; - - // Set DMA 'intrpt' register values - intrpt_reg.intrpt_st = 1; // Write 1 to clear interrupt - intrpt_reg.intrpt_en = 0; // Disable interrupt - - // Set values for start register - start_reg.start_p = 1; // Start operation - - // Set values for HMAC config register - hmac_config_reg.variant = PUFCC_HMAC_VARIANT_SHA256; - hmac_config_reg.function = PUFCC_HMAC_FUNCTION_HASH; - - // Set key_cfg_0 for hash calculation - dma_key_cfg0_reg.key_dst = PUFCC_DMA_KEY_DST_HASH; - - // Set previous hash value if it's not the first data block - if (!lvHead) { - for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { - crypto_regs->dgst_in[i] = be2le(((uint32_t *)pkt->in_hash)[i]); - } - } - - // Set SGDMA descriptors - do { - sg_dma_descs[desc_count].read_addr = be2le((uint32_t)pkt->in_buf); - sg_dma_descs[desc_count].length = be2le(pkt->in_len); - sg_dma_descs[desc_count].next = - be2le((uint32_t)&sg_dma_descs[desc_count + 1]); - - sg_dma_descs[desc_count].key_cfg = be2le(*(uint32_t *)&dma_key_cfg0_reg); - sg_dma_descs[desc_count].cypt_cfg[0] = be2le(*(uint32_t *)&hmac_config_reg); - sg_dma_descs[desc_count].cypt_cfg[1] = be2le(plen); - - *(uint32_t *)&dma_dsc_cfg_4_reg = 0; - dma_dsc_cfg_4_reg.offset = plen % 16; - - plen += pkt->in_len; - pkt = pkt->next; - - if (!desc_count && lvHead) { - dma_dsc_cfg_4_reg.head = 1; - } - - // Mark this descriptor as last if there is no more data - if (!pkt) { - dma_dsc_cfg_4_reg.dn_pause = 1; - if (lvTail) { - dma_dsc_cfg_4_reg.tail = 1; - } - } - - sg_dma_descs[desc_count].dsc_cfg_4 = be2le(*(uint32_t *)&dma_dsc_cfg_4_reg); - desc_count++; - } while (pkt && ((desc_count * sizeof(struct pufcc_sg_dma_desc)) < - SG_DMA_MAX_DSCS_SIZE)); - - if (pkt) { - // No enough descriptors available - return PUFCC_E_OVERFLOW; - } - - // Update accumulated data length - *pkt->prev_len = plen; - - /*** Configure DMA registers ***/ - // Enable SGDMA in dma_cfg_0 register - dma_cfg_0_reg.sg_en = 1; - REG_WRITE_32(&dma_regs->cfg_0, &dma_cfg_0_reg); - - // Set dsc_cfg_2 register to indicate it's an SGDMA operation - dma_regs->dsc_cfg_2 = PUFCC_DMA_DSC_CFG2_SGDMA_VAL; - - // Set starting address of SGDMA descriptors in dma_dsc_cfg3 register - dma_regs->dsc_cfg_3 = (uint32_t)sg_dma_descs; - - // Clear and disable DMA and HMAC interrupts - REG_WRITE_32(&dma_regs->interrupt, &intrpt_reg); - REG_WRITE_32(&hmac_regs->interrupt, &intrpt_reg); - - // Start the DMA operation by writing to its start register - REG_WRITE_32(&dma_regs->start, &start_reg); - - // Poll on busy status - status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); - - if (status != PUFCC_SUCCESS) { - return status; - } - - if (hmac_regs->status) { - return PUFCC_E_ERROR; - } - - // Read the calculated hash value - for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { - ((uint32_t *)pkt->out_buf)[i] = be2le(crypto_regs->dgst_out[i]); - } - - pkt->out_len = PUFCC_SHA_256_LEN; - - return PUFCC_SUCCESS; -} - -/** - * @fn pufcc_decrypt_aes - * @brief Decrypt passed in data using AES decryption algorithm - * - * @param[in] out_addr Address to write decrypted data to - * @param[in] in_addr Address of the encrypted data - * @param[in] in_len Length of the input data in bytes - * @param[in] prev_len Length of the previously decrypted data in case - * decrypting data in chunks; 0 for first or single - * chunk - * @param[in] key_type Key type i.e. SW or OTP - * @param[in] key_addr Address or OTP slot of the decryption key - * @param[in] key_len Length of the decryption key - * @param[in] iv_addr IV address - * @param[in] iv_len IV length - * @param[in] write_type Write type i.e. write decrypted data to fixed address - * or auto-increment the destination address - * @param[in] readback_iv If true, read back updated IV value corresponding to - * number of processed data blocks into passed in - * iv_addr buffer. In this case iv_addr buffer must be - * writable. - * - * @return PUFCC_SUCCESS on success, otherwise an error code - */ -static enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, - uint32_t in_len, uint32_t prev_len, - enum pufcc_key_type key_type, - uint32_t key_addr, uint32_t key_len, - uint32_t iv_addr, uint32_t iv_len, - enum pufcc_dma_rw_type write_type, - bool readback_iv) { - enum pufcc_status status; - uint32_t temp32; - - // Configure DMA intrpt register - temp32 = 0; - struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; - intrpt_reg->intrpt_st = 1; // Write 1 to clear interrupt - REG_WRITE_32(&dma_regs->interrupt, intrpt_reg); - - // Set dma_cfg_0 register - temp32 = 0; - REG_WRITE_32(&dma_regs->cfg_0, &temp32); - - struct pufcc_dma_cfg_1_reg *cfg_1_reg = (struct pufcc_dma_cfg_1_reg *)&temp32; - cfg_1_reg->rbst_max = 0xF; - cfg_1_reg->rbst_min = 0xF; - cfg_1_reg->wbst_max = 0xF; - cfg_1_reg->wbst_min = 0xF; - - REG_WRITE_32(&dma_regs->cfg_1, cfg_1_reg); - - // Set data source address in dsc_cfg_0 register - REG_WRITE_32(&dma_regs->dsc_cfg_0, &in_addr); - - // Set decrypted data destination address in dsc_cfg_1 register - REG_WRITE_32(&dma_regs->dsc_cfg_1, &out_addr); - - // Set data length in dsc_cfg_2 register - REG_WRITE_32(&dma_regs->dsc_cfg_2, &in_len); - - // Configure dma_dsc_cfg_4 register - temp32 = 0; - struct pufcc_dma_dsc_cfg_4_reg *dsc_cfg_4_reg = - (struct pufcc_dma_dsc_cfg_4_reg *)&temp32; - dsc_cfg_4_reg->fw = write_type; - dsc_cfg_4_reg->fr = AUTO_INCREMENT; // Autoincrement source address - dsc_cfg_4_reg->offset = prev_len % CTR_MODE_BLOCK_SIZE; - REG_WRITE_32(&dma_regs->dsc_cfg_4, dsc_cfg_4_reg); - - // Configure key_cfg_0 register - struct pufcc_dma_key_cfg0_reg *key_cfg_0_reg = - (struct pufcc_dma_key_cfg0_reg *)&temp32; - key_cfg_0_reg->key_src = key_type; - key_cfg_0_reg->key_dst = PUFCC_DMA_KEY_DST_SP38A; // SP38a - key_cfg_0_reg->key_size = key_len * 8; // Key length in bits - - // Configure the decryption key - if (key_type == PUFCC_SW_KEY) { - for (uint32_t i = 0; i < (key_len / PUFCC_WORD_SIZE); i++) { - crypto_regs->sw_key[i] = be2le(((uint32_t *)key_addr)[i]); - } - } else { - key_cfg_0_reg->key_idx = (enum pufcc_key_type)key_addr; - } - - REG_WRITE_32(&dma_regs->key_cfg_0, key_cfg_0_reg); - - // Configure IV - for (uint32_t i = 0; i < (iv_len / PUFCC_WORD_SIZE); i++) { - crypto_regs->iv[i] = be2le(((uint32_t *)iv_addr)[i]); - } - - // Configure SP38a intrpt register - temp32 = 0; - intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; - intrpt_reg->intrpt_st = 1; // Clear interrupt by writing 1 - REG_WRITE_32(&sp38a_regs->interrupt, intrpt_reg); - - // Configure SP38a config register - struct pufcc_sp38a_config_reg *sp38a_config_reg = - (struct pufcc_sp38a_config_reg *)&temp32; - sp38a_config_reg->variant = - (key_len == PUFCC_CRYPTO_AES128_KEY_LEN ? PUFCC_AES128 : PUFCC_AES256); - sp38a_config_reg->mode = PUFCC_CTR128; - sp38a_config_reg->enc_dec = 0; // Decryption - REG_WRITE_32(&sp38a_regs->cfg, sp38a_config_reg); - - // Start DMA operation - struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; - start_reg->start_p = 1; - REG_WRITE_32(&dma_regs->start, start_reg); - - // Poll on busy status - status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); - - if (status != PUFCC_SUCCESS) { - return status; - } - - if (sp38a_regs->status & PUFCC_SP38A_STATUS_ERROR_MASK) { - return PUFCC_E_ERROR; - } - - // Read back updated IV - if (readback_iv) { - for (uint8_t i = 0; i < iv_len / PUFCC_WORD_SIZE; i++) { - ((uint32_t *)iv_addr)[i] = be2le(crypto_regs->iv[i]); - } - } - - return PUFCC_SUCCESS; -} - -/** - * @fn pufcc_rsa2048_sign_verify - * @brief Verify RSA2048 signature of the input message data - * - * @param[in] ctx Context of the ecdsa sign verification. - * @param[inout] pkt Input and output data related parameters for sign verification. - * @return PUFCC_SUCCESS on success, otherwise an error code. - */ -static int pufcc_rsa2048_sign_verify(struct sign_ctx *ctx, struct sign_pkt *pkt) { - enum pufcc_status status = PUFCC_SUCCESS; - uint32_t temp32; - uint8_t dec_msg[PUFCC_RSA_2048_LEN]; - const uint8_t *sig = ctx->sig; - struct pufs_crypto_rsa2048_puk *pub_key = (struct pufs_crypto_rsa2048_puk *)ctx->pub_key; - - ((struct pufs_data*)ctx->device->data)->pufs_pkt.sign_pkt = pkt; - ((struct pufs_data*)ctx->device->data)->pufs_ctx.sign_ctx = ctx; - - struct pufs_crypto_addr msg_addr = { - .read_addr = (uint32_t)pkt->in_buf, - .len = pkt->in_len - }; - - // Configure signature scheme - temp32 = 0; - struct pufcc_pkc_ecp_ec_reg *ecp_ec_reg = - (struct pufcc_pkc_ecp_ec_reg *)&temp32; - ecp_ec_reg->field = PUFCC_RSA_2048; - REG_WRITE_32(&pkc_regs->ecp_ec, ecp_ec_reg); - - // Reverse public key modulus - reverse(pufcc_buffer, pub_key->n, PUFCC_RSA_2048_LEN); - - // Write reversed public key modulus to ECP data field at proper offset - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET, - pufcc_buffer, PUFCC_RSA_2048_LEN); - - // Write public key exponent to ecp_e_short register - REG_WRITE_32(&pkc_regs->ecp_e_short, &pub_key->e); - - // Reverse signature - reverse(pufcc_buffer, sig, PUFCC_RSA_2048_LEN); - - // Write reversed signature to ECP data field at proper offset - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, - pufcc_buffer, PUFCC_RSA_2048_LEN); - - // Write microprogram for RSA2048 - memcpy((void *)&pkc_regs->ecp_mac, rsa_2048_mprog, sizeof(rsa_2048_mprog)); - - // Clear and disable PKC interrupt - temp32 = 0; - struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; - intrpt_reg->intrpt_st = 1; - REG_WRITE_32(&pkc_regs->interrupt, intrpt_reg); - - // Start PKC operation - struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; - start_reg->start_p = 1; - REG_WRITE_32(&pkc_regs->start, start_reg); - - // Poll on busy status - status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); - - if (status != PUFCC_SUCCESS) { - LOG_ERR("%s(%d) PUFs Error:%d\n", __func__, __LINE__, (int)status); - return -ECANCELED; - } - - // Read decrypted message from proper offset in ECP data field and reverse it - memcpy(pufcc_buffer, - (uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, - PUFCC_RSA_2048_LEN); - reverse(dec_msg, pufcc_buffer, PUFCC_RSA_2048_LEN); - - status = rsa_p1v15_verify(dec_msg, &msg_addr); - - if (status != PUFCC_SUCCESS) { - LOG_ERR("%s(%d) PUFs Verification Error:%d\n", __func__, __LINE__, (int)status); - return -ECANCELED; - } - - return PUFCC_SUCCESS; -} - -/** - * @fn pufcc_ecdsa256_sign_verify - * @brief Verify ECDSA256 signature of the input message data - * - * @param[in] ctx Context of the ecdsa sign verification. - * @param[in] pkt Input and output data related parameters for sign verification. - * @return PUFCC_SUCCESS on success, otherwise an error code. - */ -static int pufcc_ecdsa256_sign_verify(struct sign_ctx *ctx, struct sign_pkt *pkt) { - - struct pufs_crypto_ec256_sig *sig = (struct pufs_crypto_ec256_sig *)ctx->sig; - struct rs_crypto_ec256_puk *pub_key = (struct rs_crypto_ec256_puk *)ctx->pub_key; - uint32_t temp32, prev_len = 0; - enum pufcc_status status; - struct pufs_crypto_hash hash; - - ((struct pufs_data*)ctx->device->data)->pufs_pkt.sign_pkt = pkt; - ((struct pufs_data*)ctx->device->data)->pufs_ctx.sign_ctx = ctx; - - struct hash_ctx lvHashCtx = { - .device = ctx->device, - .drv_sessn_state = NULL, - .hash_hndlr = NULL, - .started = false, - .flags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS) - }; - - struct hash_pkt lvHashPkt = { - .in_buf = pkt->in_buf, - .in_hash = NULL, - .in_len = pkt->in_len, - .prev_len = &prev_len, - .out_buf = (uint8_t*)hash.val, - .out_len = 0, - .next = NULL, - .head = true, - .tail = true, - .ctx = &lvHashCtx - }; - - // Calculate hash of the message - if (pufcc_calc_sha256_hash_sg(&lvHashCtx, &lvHashPkt) != PUFCC_SUCCESS) { - return PUFCC_E_ERROR; - } - - // Set the EC NIST P256 parameters after reversing them - reverse(pufcc_buffer, ecc_param_nistp256.prime, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PRIME_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); - - reverse(pufcc_buffer, ecc_param_nistp256.a, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_A_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); - - reverse(pufcc_buffer, ecc_param_nistp256.b, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_B_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); - - reverse(pufcc_buffer, ecc_param_nistp256.px, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PX_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); - - reverse(pufcc_buffer, ecc_param_nistp256.py, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PY_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); - - reverse(pufcc_buffer, ecc_param_nistp256.order, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_ORDER_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); - - // Configure signature scheme - temp32 = 0; - struct pufcc_pkc_ecp_ec_reg *ecp_ec_reg = - (struct pufcc_pkc_ecp_ec_reg *)&temp32; - ecp_ec_reg->field = PUFCC_ECDSA256; - ecp_ec_reg->h = 1; // EC cofactor h - REG_WRITE_32(&pkc_regs->ecp_ec, ecp_ec_reg); - - // Write microprogram for ECDSA 256 - memcpy((void *)&pkc_regs->ecp_mac, p256_ecdsa_mprog, - sizeof(p256_ecdsa_mprog)); - - // Set the hash, public key & signature in PKC module after reversing each - reverse(pufcc_buffer, hash.val, PUFCC_SHA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_HASH_OFFSET, - pufcc_buffer, PUFCC_SHA_256_LEN); - - reverse(pufcc_buffer, pub_key->x, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBX_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); - - reverse(pufcc_buffer, pub_key->y, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBY_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); - - reverse(pufcc_buffer, sig->r, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_R_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); - - reverse(pufcc_buffer, sig->s, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_S_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); - - // Clear and disable PKC interrupt - temp32 = 0; - struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; - intrpt_reg->intrpt_st = 1; - REG_WRITE_32(&pkc_regs->interrupt, intrpt_reg); - - // Start PKC operation - struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; - start_reg->start_p = 1; - REG_WRITE_32(&pkc_regs->start, start_reg); - - // Poll on busy status - status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); - - if (status != PUFCC_SUCCESS) { - LOG_ERR("%s(%d) PUFs Verification Error:%d\n", __func__, __LINE__, (int)status); - return -ECANCELED; - } - - return PUFCC_SUCCESS; -} - -/** - * @fn rsa_p1v15_verify - * @brief Verify input RSA2048 decrypted message according to PKCS#1 v1.5 RSA - * verification standard. - * @param[in] dec_msg Input RSA decrypted message - * @param[in] msg_addr Address of the original data that was RSA signed - * @return PUFCC_SUCCESS on success, otherwise an error code. - */ -static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, - struct pufs_crypto_addr *msg_addr) { - uint32_t i, prev_len = 0; - struct pufs_crypto_hash hash; - uint8_t pret[19] = {0x30, 0, 0x30, 0x0d, 0x06, 0x09, 0x60, - 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, - 0, 0x05, 0x00, 0x04, 0}; - - if ((dec_msg[0] != 0x00) || (dec_msg[1] != 0x01)) { - return PUFCC_E_VERFAIL; - } - - for (i = 2; i < PUFCC_RSA_2048_LEN; i++) { - if (dec_msg[i] != 0xff) { - break; - } - } - - if (dec_msg[i++] != 0x00) { - return PUFCC_E_VERFAIL; - } - - // Verify that decrypted message has SHA256 hash - if (dec_msg[i + 14] == 1) { - pret[1] = 0x31; - pret[14] = 0x01; - pret[18] = 0x20; - } else { - return PUFCC_E_INVALID; - } - - if ((memcmp(dec_msg + i, pret, 19) != 0) || - ((i + 19 + pret[18]) != PUFCC_RSA_2048_LEN)) { - return PUFCC_E_VERFAIL; - } - - // Calculate hash of the message - - struct hash_ctx lvHashCtx = { - .device = NULL, - .drv_sessn_state = NULL, - .hash_hndlr = NULL, - .started = false, - .flags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS) - }; - - struct hash_pkt lvHashPkt = { - .in_buf = (uint8_t *)msg_addr->read_addr, - .in_hash = NULL, - .in_len = msg_addr->len, - .prev_len = &prev_len, - .out_buf = (uint8_t*)hash.val, /*hash.val is an array*/ - .out_len = 0, - .next = NULL, - .head = true, - .tail = true, - .ctx = &lvHashCtx - }; - - if (pufcc_calc_sha256_hash_sg(&lvHashCtx, &lvHashPkt) != - PUFCC_SUCCESS) { - return PUFCC_E_ERROR; - } - - if (memcmp(dec_msg + i + 19, hash.val, hash.len) != 0) { - return PUFCC_E_VERFAIL; - } - - return PUFCC_SUCCESS; -} - -/** - * @fn reverse - * @brief Reverse input byte array. - * - * @param[in] dst Destination address of the reversed byte array - * @param[in] src Address of the input byte array - * @param[in] len Length of the input byte array to be reversed - */ -static void reverse(uint8_t *dst, const uint8_t *src, size_t len) { - for (size_t i = 0, j = len - 1; i < len; i++, j--) { - dst[i] = src[j]; - } -} - -/** - * @fn be2le - * @brief Reverse endianness of the input 4 byte word - * - * @param[in] var Input 4 byte variable - * @return 4 byte word with reversed endianness - */ -static uint32_t be2le(uint32_t var) { - return (((0xff000000 & var) >> 24) | ((0x00ff0000 & var) >> 8) | - ((0x0000ff00 & var) << 8) | ((0x000000ff & var) << 24)); -} - -/** - * @fn busy_wait - * @brief Waits on busy bit of the passed-in status register till it gets - * cleared or it times out. - * - * @param[in] status_reg_addr Status register's address - * @param[in] error_mask Bitmask of error bits in passed-in status register - * @return PUFCC_SUCCESS if busy bit gets cleared without an - * error, otherwise an error code. - */ -static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, - uint32_t error_mask) { - uint32_t status; - int32_t busy_count = PUFCC_MAX_BUSY_COUNT; - - do { - status = sys_read32((mem_addr_t)status_reg_addr); - busy_count--; - } while ((status & PUFCC_BUSY_BIT_MASK) && (busy_count > 0)); - - if (status & PUFCC_BUSY_BIT_MASK) { - return PUFCC_E_TIMEOUT; - } else if (status & error_mask) { - return PUFCC_E_ERROR; - } - - return PUFCC_SUCCESS; -} - static int crypto_pufs_init(const struct device *dev) { // Initialize base addresses of different PUFcc modules - dma_regs = (struct pufcc_dma_regs *)((struct pufs_config*)dev->config)->base; - hmac_regs = (struct pufcc_hmac_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_HMAC_OFFSET); - crypto_regs = (struct pufcc_crypto_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_CRYPTO_OFFSET); - sp38a_regs = (struct pufcc_sp38a_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_SP38A_OFFSET); - pkc_regs = (struct pufcc_pkc_regs *)(((struct pufs_config*)dev->config)->base + PUFCC_PKC_OFFSET); + enum pufcc_status lvStatus = pufcc_init((struct pufcc_dma_regs *)((struct pufs_config*)dev->config)->base); - // Connect the IRQ - ((struct pufs_config*)dev->config)->irq_init(); + if(lvStatus == PUFCC_SUCCESS) { + // Connect the IRQ + ((struct pufs_config*)dev->config)->irq_init(); + } else { + return -ENODEV; + } return PUFCC_SUCCESS; } static void pufs_irq_handler(const struct device *dev) { - int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -ECANCELED : PUFCC_SUCCESS); - - struct pufcc_intrpt_reg *intrpt_reg_ptr = - (struct pufcc_intrpt_reg *)&dma_regs->interrupt; + // Clear and disable the interrupts from the pufcc register map + int status = pufcc_clear_and_disable_intr(); struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; @@ -866,10 +69,6 @@ static void pufs_irq_handler(const struct device *dev) { } break; } - // Clear and disable interrupt - intrpt_reg_ptr->intrpt_st = 1; // Set to clear - intrpt_reg_ptr->intrpt_en = 0; - // After execution of a callback, the irq is disabled. irq_disable(((struct pufs_config *)dev->config)->irq_num); } @@ -912,41 +111,50 @@ static int pufs_query_hw_caps(const struct device *dev) static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t *ctr) { + enum pufcc_status lvStatus = PUFCC_SUCCESS; + ((struct pufs_data*)ctx->device->data)->pufs_pkt.cipher_pkt = pkt; ((struct pufs_data*)ctx->device->data)->pufs_ctx.cipher_ctx = ctx; - return pufcc_decrypt_aes( - (uint32_t)pkt->out_buf, (uint32_t)pkt->in_buf, - (uint32_t)pkt->in_len, pkt->prev_len, ctx->key_source, - (uint32_t)ctx->key.bit_stream, ctx->keylen, (uint32_t)ctr, - (uint32_t)ctx->mode_params.ctr_info.ctr_len, - pkt->auto_increment, ctx->mode_params.ctr_info.readback_ctr - ); + lvStatus = pufcc_decrypt_aes( + (uint32_t)pkt->out_buf, (uint32_t)pkt->in_buf, + (uint32_t)pkt->in_len, pkt->prev_len, ctx->key_source, + (uint32_t)ctx->key.bit_stream, ctx->keylen, (uint32_t)ctr, + (uint32_t)ctx->mode_params.ctr_info.ctr_len, + pkt->auto_increment, ctx->mode_params.ctr_info.readback_ctr + ); + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) PUFcc Error Code:%d\n", lvStatus); + return -ECANCELED; + } + + return 0; } /* Following cipher operations (block, cbc, ccm and gcm) are not supported yet. */ __unused static int pufs_block_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt) { - return -ENOTSUP; + return -ENOSYS; } __unused static int pufs_cbc_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t *iv) { - return -ENOTSUP; + return -ENOSYS; } __unused static int pufs_ccm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, uint8_t *nonce) { - return -ENOTSUP; + return -ENOSYS; } __unused static int pufs_gcm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, uint8_t *nonce) { - return -ENOTSUP; + return -ENOSYS; } static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx *ctx, @@ -1065,9 +273,39 @@ static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) ((struct pufs_data*)ctx->device->data)->pufs_ctx.hash_ctx = ctx; if(!ctx->started) { // started flag indicates if chunkwise hash calculation was started - lvStatus = pufcc_calc_sha256_hash(ctx, pkt); + struct rs_crypto_addr data_addr = { + .read_addr = pkt->in_buf, + .write_addr = pkt->out_buf, + .len = pkt->in_len + }; + struct rs_crypto_hash hash_out = { + .val = pkt->out_buf, + .len = pkt->out_len + }; + lvStatus = pufcc_calc_sha256_hash(&data_addr, &hash_out); } else { - lvStatus = pufcc_calc_sha256_hash_sg(ctx, pkt); + struct rs_crypto_addr data_addr = { + .read_addr = pkt->in_buf, + .write_addr = pkt->out_buf, + .len = pkt->in_len, + . + }; + struct rs_crypto_hash hash_in = { + .val = pkt->out_buf, + .len = pkt->out_len + }; + struct rs_crypto_hash hash_out = { + .val = pkt->out_buf, + .len = pkt->out_len + }; + lvStatus = pufcc_calc_sha256_hash_sg( + &data_addr, + pkt->head, + pkt->tail, + pkt->prev_len, + &hash_in, + &hash_out + ); } if(lvStatus != PUFCC_SUCCESS) { diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index 9283ba2694996..09746214c07b4 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -8,159 +8,9 @@ #ifndef ZEPHYR_DRIVERS_CRYPTO_PUFS_H_ #define ZEPHYR_DRIVERS_CRYPTO_PUFS_H_ -#include -#include -#include -#include +#include "pufcc.h" #include -/*** Generic PUFcc defines ***/ -#define PUFCC_WORD_SIZE 4 -#define PUFCC_BUSY_BIT_MASK 0x00000001 - -/*** DMA defines ***/ -#define PUFCC_DMA_KEY_DST_HASH 0x1 -#define PUFCC_DMA_KEY_DST_SP38A 0x8 -#define PUFCC_DMA_DSC_CFG2_SGDMA_VAL 0x20 -#define PUFCC_DMA_ERROR_MASK 0xFFFFFFFE - -/*** HMAC defines ***/ -#define PUFCC_HMAC_OFFSET 0x0800 -#define PUFCC_HMAC_SW_KEY_MAXLEN 64 -#define PUFCC_SHA_256_LEN 32 -#define PUFCC_HMAC_FUNCTION_HASH 0x0 -#define PUFCC_HMAC_VARIANT_SHA256 0x03 - -/*** Crypto defines ***/ -#define PUFCC_CRYPTO_OFFSET 0x0100 -#define PUFCC_CRYPTO_SW_KEY_MAXLEN 64 // The byte length of CRYPTO_SW_KEY_ADDR -#define PUFCC_CRYPTO_DGST_LEN 64 // The byte length of CRYPTO_DGST field -#define PUFCC_CRYPTO_IV_MAXLEN 16 -#define PUFCC_CRYPTO_AES128_KEY_LEN 16 -#define PUFCC_CRYPTO_AES256_KEY_LEN 32 - -/*** SP38a defines ***/ -#define PUFCC_SP38A_OFFSET 0x0200 -#define PUFCC_SP38A_STATUS_ERROR_MASK 0xfffff0c0 - -/*** PKC defines ***/ -#define PUFCC_PKC_OFFSET 0x1000 -#define PUFCC_RSA_2048_LEN 256 -#define PUFCC_ECDSA_256_LEN 32 -#define PUFCC_DATA_RSA2048_MODULUS_OFFSET 256 -#define PUFCC_DATA_RSA2048_SIGN_OFFSET 768 -#define PUFCC_DATA_ECDSA_PRIME_OFFSET 256 -#define PUFCC_PKC_ERROR_MASK 0xFFFFFFFE -#define PUFCC_DATA_ECDSA_EC_A_OFFSET \ - (PUFCC_DATA_ECDSA_PRIME_OFFSET + PUFCC_ECDSA_256_LEN) - -#define PUFCC_DATA_ECDSA_EC_B_OFFSET \ - (PUFCC_DATA_ECDSA_EC_A_OFFSET + PUFCC_ECDSA_256_LEN) - -#define PUFCC_DATA_ECDSA_PX_OFFSET \ - (PUFCC_DATA_ECDSA_EC_B_OFFSET + PUFCC_ECDSA_256_LEN) - -#define PUFCC_DATA_ECDSA_PY_OFFSET \ - (PUFCC_DATA_ECDSA_PX_OFFSET + PUFCC_ECDSA_256_LEN) - -#define PUFCC_DATA_ECDSA_ORDER_OFFSET \ - (PUFCC_DATA_ECDSA_PY_OFFSET + PUFCC_ECDSA_256_LEN) - -#define PUFCC_DATA_ECDSA_HASH_OFFSET \ - (PUFCC_DATA_ECDSA_ORDER_OFFSET + PUFCC_ECDSA_256_LEN) - -#define PUFCC_DATA_ECDSA_PUBX_OFFSET \ - (PUFCC_DATA_ECDSA_HASH_OFFSET + PUFCC_ECDSA_256_LEN) - -#define PUFCC_DATA_ECDSA_PUBY_OFFSET \ - (PUFCC_DATA_ECDSA_PUBX_OFFSET + PUFCC_ECDSA_256_LEN) - -#define PUFCC_DATA_ECDSA_SIG_R_OFFSET \ - (PUFCC_DATA_ECDSA_PUBY_OFFSET + PUFCC_ECDSA_256_LEN) - -#define PUFCC_DATA_ECDSA_SIG_S_OFFSET \ - (PUFCC_DATA_ECDSA_SIG_R_OFFSET + PUFCC_ECDSA_256_LEN) - -/** - * @brief SHA lengths - */ -#define PUFS_SHA_MAX_LEN 64 -#define PUFS_SHA256_LEN 32 - -/** - * @brief ECDSA256 quadrant and key lengths - */ -#define PUFS_EC256_QLEN 32 -#define PUFS_EC256_KEY_LEN (32 * 2) - -/** - * @brief RSA 2048 public key modulus length - * - */ -#define PUFS_RSA_2048_LEN 256 - -/***************************************************************************** - * Enumerations - ****************************************************************************/ -// PUFcc status codes -enum pufcc_status { - PUFCC_SUCCESS, // Success. - PUFCC_E_ALIGN, // Address alignment mismatch. - PUFCC_E_OVERFLOW, // Space overflow. - PUFCC_E_UNDERFLOW, // Size too small. - PUFCC_E_INVALID, // Invalid argument. - PUFCC_E_BUSY, // Resource is occupied. - PUFCC_E_UNAVAIL, // Resource is unavailable. - PUFCC_E_FIRMWARE, // Firmware error. - PUFCC_E_VERFAIL, // Invalid public key or digital signature. - PUFCC_E_ECMPROG, // Invalid ECC microprogram. - PUFCC_E_DENY, // Access denied. - PUFCC_E_UNSUPPORT, // Not support. - PUFCC_E_INFINITY, // Point at infinity. - PUFCC_E_ERROR, // Unspecific error. - PUFCC_E_TIMEOUT, // Operation timed out. -}; - -// PUFcc read/write types -enum pufcc_dma_rw_type { AUTO_INCREMENT, FIXED_RW }; - -// PUFcc key types -enum pufcc_key_type { PUFCC_SW_KEY, PUFCC_OTP_KEY }; - -// PUFcc SP38a variants -enum pufcc_sp38a_variant { - PUFCC_AES128, - PUFCC_AES192, - PUFCC_AES256, - PUFCC_SM4 -}; - -// PUFcc PKC schemes -enum pufcc_pkc_scheme { PUFCC_RSA_2048 = 0x86, PUFCC_ECDSA256 = 0x82 }; - -// PUFcc SP38a modes -enum pufcc_sp38a_mode { - PUFCC_ECB_CLR, - PUFCC_CFB, - PUFCC_OFB, - PUFCC_CBC_CLR, - PUFCC_CBC_CTS1, - PUFCC_CBC_CTS2, - PUFCC_CBC_CTS3, - PUFCC_CTR32, - PUFCC_CTR64, - PUFCC_CTR128 -}; - -/** - * @enum pufs_crypto_tfr_type - * @brief Types of secure transfer type in case of peripherals - */ -enum pufs_crypto_tfr_type { - PUFS_SECURE_TX, // Write to peripheral - PUFS_SECURE_RX // Read from peripheral -}; - enum pufs_session_type { PUFS_SESSION_SIGN_VERIFICATION = 0, PUFS_SESSION_HASH_CALCULATION, @@ -168,249 +18,6 @@ enum pufs_session_type { PUFS_SESSION_UNDEFINED }; -// Scatter gather DMA descriptor struct -struct pufcc_sg_dma_desc { - uint32_t read_addr; - uint32_t write_addr; - uint32_t length; - uint32_t next; - uint32_t dsc_cfg_4; - uint32_t key_cfg; - uint32_t cypt_cfg[2]; -}; - -/***************************************************************************** - * Register structures - ****************************************************************************/ -// General register structs -struct pufcc_intrpt_reg { - uint32_t intrpt_st : 1; - uint32_t reserved1 : 15; - uint32_t intrpt_en : 1; - uint32_t reserved2 : 15; -}; - -struct pufcc_start_reg { - uint32_t start_p : 1; - uint32_t reserved : 31; -}; - -// DMA register structs -struct pufcc_dma_cfg_0_reg { - uint32_t rng_en : 1; - uint32_t sg_en : 1; - uint32_t reserved : 30; -}; - -struct pufcc_dma_cfg_1_reg { - uint8_t rbst_max; - uint8_t wbst_max; - uint8_t rbst_min; - uint8_t wbst_min; -}; - -struct pufcc_dma_dsc_cfg_4_reg { - uint32_t wprot : 8; - uint32_t rprot : 8; - uint32_t fw : 1; - uint32_t fr : 1; - uint32_t reserved : 5; - uint32_t no_cypt : 1; - uint32_t offset : 4; - uint32_t dn_pause : 1; - uint32_t dn_intrpt : 1; - uint32_t tail : 1; - uint32_t head : 1; -}; - -struct pufcc_dma_key_cfg0_reg { - uint32_t key_src : 4; - uint32_t key_dst : 4; - uint32_t key_size : 11; - uint32_t reserved1 : 5; - uint32_t key_idx : 5; - uint32_t reserved2 : 3; -}; - -// HMAC register structs -struct pufcc_hmac_config_reg { - uint32_t variant : 4; - uint32_t reserved : 4; - uint32_t function : 1; - uint32_t reserved2 : 23; -}; - -// PUFcc SP38a register structs -struct pufcc_sp38a_config_reg { - uint32_t variant : 2; - uint32_t reserved1 : 2; - uint32_t mode : 4; - uint32_t enc_dec : 1; - uint32_t reserved2 : 23; -}; - -// PKC register register structs -struct pufcc_pkc_ecp_ec_reg { - uint32_t reserved1 : 8; - uint32_t field : 8; // PKC scheme - uint32_t h : 4; // EC cofactor h - uint32_t reserved2 : 12; -}; - -// ECC parameters structure -struct pufcc_ecc_param { - const void *prime; // Field modulus - const void *a; // EC parameter a - const void *b; // EC parameter b - const void *px; // x-coordinate of base point P - const void *py; // y-coordinate of base point P - const void *order; // Subgroup order -}; - -/***************************************************************************** - * PUFcc register maps - ****************************************************************************/ -// DMA module register map -struct pufcc_dma_regs { - volatile uint32_t version; - volatile uint32_t interrupt; - volatile uint32_t feature; - uint32_t _pad1; - volatile uint32_t status_0; - volatile uint32_t status_1; - uint32_t _pad2[2]; - volatile uint32_t start; - volatile uint32_t cfg_0; - volatile uint32_t cfg_1; - uint32_t _pad3[2]; - volatile uint32_t dsc_cfg_0; - volatile uint32_t dsc_cfg_1; - volatile uint32_t dsc_cfg_2; - volatile uint32_t dsc_cfg_3; - volatile uint32_t dsc_cfg_4; - uint32_t _pad4[2]; - volatile uint32_t dsc_cur_0; - volatile uint32_t dsc_cur_1; - volatile uint32_t dsc_cur_2; - volatile uint32_t dsc_cur_3; - volatile uint32_t dsc_cur_4; - uint32_t _pad5[2]; - volatile uint32_t key_cfg_0; - volatile uint32_t cl_cfg_0; -}; - -// HMAC module register map -struct pufcc_hmac_regs { - volatile uint32_t version; - volatile uint32_t interrupt; - volatile uint32_t feature; - uint32_t _pad1; - volatile uint32_t status; - uint32_t _pad2; - volatile uint32_t cfg; - uint32_t _pad3; - volatile uint32_t plen; - uint32_t _pad4[3]; - volatile uint32_t alen; - uint32_t _pad5[3]; - volatile uint8_t sw_key[PUFCC_HMAC_SW_KEY_MAXLEN]; -}; - -// Crypto module register map -struct pufcc_crypto_regs { - volatile uint32_t version; - volatile uint32_t interrupt; - volatile uint32_t feature; - uint32_t _pad1[5]; - volatile uint32_t iv_out[PUFCC_CRYPTO_IV_MAXLEN / PUFCC_WORD_SIZE]; - volatile uint32_t iv[PUFCC_CRYPTO_IV_MAXLEN / PUFCC_WORD_SIZE]; - volatile uint32_t sw_key[PUFCC_CRYPTO_SW_KEY_MAXLEN / PUFCC_WORD_SIZE]; - volatile uint32_t dgst_in[PUFCC_CRYPTO_DGST_LEN / PUFCC_WORD_SIZE]; - volatile uint32_t dgst_out[PUFCC_CRYPTO_DGST_LEN / PUFCC_WORD_SIZE]; -}; - -// SP38a module register map -struct pufcc_sp38a_regs { - volatile uint32_t version; - volatile uint32_t interrupt; - volatile uint32_t feature; - uint32_t _pad1; - volatile uint32_t status; - uint32_t _pad2; - volatile uint32_t cfg; -}; - -// PKC module register map -struct pufcc_pkc_regs { - volatile uint32_t version; - volatile uint32_t interrupt; - volatile uint32_t start; - volatile uint32_t status; - volatile uint32_t ecp_err_code; - volatile uint32_t ecp_err_pc; - volatile uint32_t ecp_err_cmd; - volatile uint32_t mp_version; - uint32_t _pad1[56]; - volatile uint32_t ecp_ec; - volatile uint32_t ecp_keysel; - volatile uint32_t ecp_otpkba; - volatile uint32_t ecp_key_usage; - volatile uint32_t ecp_e_short; - uint32_t _pad2[55]; - volatile uint32_t ecp_mac[4]; - volatile uint32_t ecp_data[512]; -}; - -/** - * @struct pufs_crypto_addr - * @brief Address info for cryptographic operations - */ -struct pufs_crypto_addr { - uint32_t read_addr; - uint32_t write_addr; - uint32_t len; - enum pufs_crypto_tfr_type tfr_type; // Transfer type (read or write) in case of - // peripherals, otherwise don't care - bool periph_rw; // Indicates if data transfer involves a peripheral - struct pufs_crypto_addr *next; // In case data lies at multiple locations -}; - -/** - * @struct pufs_crypto_rsa2048_puk - * @brief RSA 2048 public key structure - */ -struct pufs_crypto_rsa2048_puk { - uint8_t n[PUFS_RSA_2048_LEN]; // Modulus - uint32_t e; // Exponent -}; - -/** - * @struct rs_crypto_ec256_puk - * @brief ECDSA256 public key - */ -struct rs_crypto_ec256_puk { - uint8_t x[PUFS_EC256_QLEN]; - uint8_t y[PUFS_EC256_QLEN]; -}; - -/** - * @struct pufs_crypto_ec256_sig - * @brief ECDSA256 signature - */ -struct pufs_crypto_ec256_sig { - uint8_t r[PUFS_EC256_QLEN]; - uint8_t s[PUFS_EC256_QLEN]; -}; - -/** - * @struct pufs_crypto_hash - * @brief Hash structure - */ -struct pufs_crypto_hash { - uint8_t val[PUFS_SHA_MAX_LEN]; - uint32_t len; -}; - /* Generic Callback Signature for different Sessions */ struct crypto_callbacks { cipher_completion_cb cipher_cb; @@ -448,11 +55,4 @@ struct pufs_config { const struct device *dev; }; -/* -The following macro can be used to write register values. -REG_WRITE_32(Destination_Addr, Source_Addr) -*/ -#define REG_WRITE_32(Destination_Addr, Source_Addr) \ - *(uint32_t *)Destination_Addr = *(uint32_t *)Source_Addr; - #endif /* ZEPHYR_DRIVERS_CRYPTO_CRYPTO_STM32_PRIV_H_ */ diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c new file mode 100644 index 0000000000000..46e3d8dde5647 --- /dev/null +++ b/drivers/crypto/pufcc.c @@ -0,0 +1,1343 @@ +#include "pufcc.h" + +#include + +#ifndef RS_RTOS_PORT + #include "profiling_util.h" + #include "rs_crypto.h" + #include "rs_util.h" +#else + #include + #include +#endif + +/***************************************************************************** + * Macros + ****************************************************************************/ +#define SG_DMA_MAX_DSCS_SIZE (512 - 8) // Enough for 15 descriptors +#define BUFFER_SIZE 512 +#define PUFCC_MAX_BUSY_COUNT 8000000 // Max busy count for processing 10MB data +#define CTR_MODE_BLOCK_SIZE 16 + +/***************************************************************************** + * Local variable declarations + ****************************************************************************/ +#ifndef RS_RTOS_PORT +extern uint32_t __pufcc_descriptors; +#else + uint32_t __pufcc_descriptors[BUFFER_SIZE]; +#endif +static struct pufcc_sg_dma_desc *sg_dma_descs = + (struct pufcc_sg_dma_desc *)&__pufcc_descriptors; +static uint8_t pufcc_buffer[BUFFER_SIZE]; + +// PUFcc microprogram for RSA2048 +static uint32_t rsa_2048_mprog[] = { + 0x33cdac81, 0x6817434e, 0x4283ad5d, 0x27499978, 0x8a000040, 0x0a1080c0, + 0xc3800b00, 0x081810c6, 0xfc000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}; + +// PUFcc microprogram for ECDSA256 +static uint32_t p256_ecdsa_mprog[] = { + 0xb1703302, 0x0f91d3f8, 0x004ae67d, 0x8f7093c5, 0x8a000068, 0x0a014088, + 0xc3000000, 0xa0624000, 0x43000100, 0x20824000, 0x0a014090, 0xc3000000, + 0x20624800, 0x43000100, 0xa0824800, 0x0a014090, 0xc3000600, 0x8900101e, + 0x8e000028, 0x8a000068, 0x8a014800, 0x8a028070, 0x43000400, 0x0901101e, + 0x8e000028, 0x8a000068, 0x8a014800, 0x0a028088, 0x43000400, 0x0902101e, + 0x8e000048, 0x8a028058, 0x0a03c060, 0x92050020, 0x8a064808, 0x41801600, + 0x8900101e, 0x09011028, 0x8e000048, 0x0a028078, 0x8a03c080, 0x92050020, + 0x8a064810, 0x41801600, 0x0902101e, 0x89031028, 0x8e000048, 0x8a028800, + 0x0a03c808, 0x0a050810, 0x0a064818, 0xc1000700, 0x20a25000, 0x8900101e, + 0x8e000028, 0x8a000068, 0x8a014800, 0x43000200, 0x8900101e, 0x1c110800, + 0x18025800, 0xfc000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000}; + +// EC NIST-P256 parameters +struct pufcc_ecc_param ecc_param_nistp256 = { + "\xff\xff\xff\xff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff", // prime + "\xff\xff\xff\xff\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xfc", // a + "\x5a\xc6\x35\xd8\xaa\x3a\x93\xe7\xb3\xeb\xbd\x55\x76\x98\x86" + "\xbc\x65\x1d\x06\xb0\xcc\x53\xb0\xf6\x3b\xce\x3c\x3e\x27\xd2" + "\x60\x4b", // b + "\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" + "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98" + "\xc2\x96", // px + "\x4f\xe3\x42\xe2\xfe\x1a\x7f\x9b\x8e\xe7\xeb\x4a\x7c\x0f\x9e" + "\x16\x2b\xce\x33\x57\x6b\x31\x5e\xce\xcb\xb6\x40\x68\x37\xbf" + "\x51\xf5", // py + "\xff\xff\xff\xff\x00\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff" + "\xff\xbc\xe6\xfa\xad\xa7\x17\x9e\x84\xf3\xb9\xca\xc2\xfc\x63" + "\x25\x51" // order +}; + +// Base register addresses of different PUFcc modules +static struct pufcc_dma_regs *dma_regs; +static struct pufcc_rt_regs *rt_regs; +static struct pufcc_otp_mem *otp_mem; +static struct pufcc_hmac_regs *hmac_regs; +static struct pufcc_crypto_regs *crypto_regs; +static struct pufcc_sp38a_regs *sp38a_regs; +static struct pufcc_pkc_regs *pkc_regs; + +/***************************************************************************** + * Local function declarations + ****************************************************************************/ +static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, + struct rs_crypto_addr *msg_addr); +static enum pufcc_status otp_range_check(uint32_t addr, uint32_t len); +static int rwlck_index_get(uint32_t idx); +static void reverse(uint8_t *dst, const uint8_t *src, size_t len); +static uint32_t be2le(uint32_t var); +static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, + uint32_t error_mask); + +/***************************************************************************** + * API functions + ****************************************************************************/ +/** + * @fn pufcc_calc_sha256_hash + * @brief Calculates SHA256 hash + * + * @param[in] data_addr Data address info + * @param[in] hash Pointer to hash strcut to return hash value in + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_calc_sha256_hash(struct rs_crypto_addr *data_addr, + struct rs_crypto_hash *hash) { + enum pufcc_status status; + struct pufcc_intrpt_reg intrpt_reg = {0}; + struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; + struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; + struct pufcc_dma_key_cfg0_reg dma_key_cfg0_reg = {0}; + struct pufcc_start_reg start_reg = {0}; + + // Set 'intrpt' register values + intrpt_reg.intrpt_st = 1; // Write 1 to clear interrupt + intrpt_reg.intrpt_en = 0; // Disable interrupt + + // Set dma_dsc_cfg_4 reg values + dma_dsc_cfg_4_reg.head = 1; + dma_dsc_cfg_4_reg.tail = 1; + + // set values for key_cfg_0 register + dma_key_cfg0_reg.key_dst = PUFCC_DMA_KEY_DST_HASH; + + // Set values for start register + start_reg.start_p = 1; // Start operation bit + + // Set values for HMAC config register + struct pufcc_hmac_config_reg hmac_config_reg = { + .variant = PUFCC_HMAC_VARIANT_SHA256, // Shah 256 + .function = PUFCC_HMAC_FUNCTION_HASH, // Hash + }; + + /*** Configure DMA registers ***/ + // Set dma_cfg_0 register + REG_WRITE_32(&dma_regs->cfg_0, &dma_cfg_0_reg); + + // Set data source address in dsc_cfg_0 register + dma_regs->dsc_cfg_0 = data_addr->read_addr; + + // Set data length in dsc_cfg_2 register + dma_regs->dsc_cfg_2 = data_addr->len; + + // Set the dsc_cfg_4 register to values defined above + REG_WRITE_32(&dma_regs->dsc_cfg_4, &dma_dsc_cfg_4_reg); + + // Set the key_cfg_0 register to values defined above + REG_WRITE_32(&dma_regs->key_cfg_0, &dma_key_cfg0_reg); + + // Write intrpt register to values defined above + REG_WRITE_32(&dma_regs->interrupt, &intrpt_reg); + + /** Configure HMAC registers **/ + // Set the config register to values defined above + REG_WRITE_32(&hmac_regs->cfg, &hmac_config_reg); + + // Write previous length in HMAC plen register + hmac_regs->plen = hmac_regs->alen; + + // Write intrpt register to values defined above + REG_WRITE_32(&hmac_regs->interrupt, &intrpt_reg); + + // Start the DMA operation by writing to its start register + REG_WRITE_32(&dma_regs->start, &start_reg); + + // Poll on busy status + status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); + + if (status != PUFCC_SUCCESS) { + return status; + } + + if (hmac_regs->status) { + return PUFCC_E_ERROR; + } + + // Read the calculated hash + for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { + ((uint32_t *)hash->val)[i] = be2le(crypto_regs->dgst_out[i]); + } + + hash->len = PUFCC_SHA_256_LEN; + + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_calc_sha256_hash_sg + * @brief Calculates SHA256 hash of non-contiguous data. + * All non contiguous data addresses can be passed in as a single linked + * list in the form of 'rs_crypto_addr' struct as 'data_addr' parameter + * or this function can be invoked multiple times with partial data + * address info in the linked list by setting the 'first' and 'last' + * params accordingly as detailed below against each param. In case of + * partial data address info and hence multiple invocations, we also need + * to pass in previously calculated hash values to every invocation + * after the first one and the accumulated length of all previous + * messages/data. + * + * Note: In case of multiple data chunks either in a single linked list + * or as partial linked lists using multiple invocations the sizes of all + * chunks must be multiples of 64 bytes except the last chunk. + * + * @param[in] data_addr A linked list of data address info + * @param[in] first Boolean to indicate if 'data_addr' contains the first + * data block + * @param[in] last Boolean to indicate if 'data_addr' contains the last + * data block + * Note: 'first' and 'last' can both be true if + * 'data_addr' linked list contains both first and last + * data blocks or if it contains a single data block that + * is both first as well last. + * @param[in] prev_len Pointer to accumulated length of previously processed + * data; 0 for first invocation. Currently processed data + * length will be added to this value. + * @param[in] hash_in Hash of the data bocks processed already; can be NULL + * for first invocation. + * @param[out] hash_out Pointer to hash strcut to return hash value in + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, + bool first, bool last, + uint32_t *prev_len, + struct rs_crypto_hash *hash_in, + struct rs_crypto_hash *hash_out) { + enum pufcc_status status; + uint32_t plen = 0; + uint8_t desc_count = 0; + struct rs_crypto_addr *curr_addr = data_addr; + struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; + struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; + struct pufcc_dma_key_cfg0_reg dma_key_cfg0_reg = {0}; + struct pufcc_intrpt_reg intrpt_reg = {0}; + struct pufcc_start_reg start_reg = {0}; + struct pufcc_hmac_config_reg hmac_config_reg = {0}; + + if (!first) plen = *prev_len; + + // Set DMA 'intrpt' register values + intrpt_reg.intrpt_st = 1; // Write 1 to clear interrupt + intrpt_reg.intrpt_en = 0; // Disable interrupt + + // Set values for start register + start_reg.start_p = 1; // Start operation + + // Set values for HMAC config register + hmac_config_reg.variant = PUFCC_HMAC_VARIANT_SHA256; + hmac_config_reg.function = PUFCC_HMAC_FUNCTION_HASH; + + // Set key_cfg_0 for hash calculation + dma_key_cfg0_reg.key_dst = PUFCC_DMA_KEY_DST_HASH; + + // Set previous hash value if it's not the first data block + if (!first) { + for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { + crypto_regs->dgst_in[i] = be2le(((uint32_t *)hash_in->val)[i]); + } + } + + // Set SGDMA descriptors + do { + sg_dma_descs[desc_count].read_addr = be2le(curr_addr->read_addr); + sg_dma_descs[desc_count].length = be2le(curr_addr->len); + sg_dma_descs[desc_count].next = + be2le((uint32_t)&sg_dma_descs[desc_count + 1]); + + sg_dma_descs[desc_count].key_cfg = be2le(*(uint32_t *)&dma_key_cfg0_reg); + sg_dma_descs[desc_count].cypt_cfg[0] = be2le(*(uint32_t *)&hmac_config_reg); + sg_dma_descs[desc_count].cypt_cfg[1] = be2le(plen); + + *(uint32_t *)&dma_dsc_cfg_4_reg = 0; + dma_dsc_cfg_4_reg.offset = plen % 16; + + plen += curr_addr->len; + curr_addr = curr_addr->next; + + if (!desc_count && first) { + dma_dsc_cfg_4_reg.head = 1; + } + + // Mark this descriptor as last if there is no more data + if (!curr_addr) { + dma_dsc_cfg_4_reg.dn_pause = 1; + if (last) { + dma_dsc_cfg_4_reg.tail = 1; + } + } + + sg_dma_descs[desc_count].dsc_cfg_4 = be2le(*(uint32_t *)&dma_dsc_cfg_4_reg); + desc_count++; + } while (curr_addr && ((desc_count * sizeof(struct pufcc_sg_dma_desc)) < + SG_DMA_MAX_DSCS_SIZE)); + + if (curr_addr) { + // No enough descriptors available + return PUFCC_E_OVERFLOW; + } + + // Update accumulated data length + *prev_len = plen; + + /*** Configure DMA registers ***/ + // Enable SGDMA in dma_cfg_0 register + dma_cfg_0_reg.sg_en = 1; + REG_WRITE_32(&dma_regs->cfg_0, &dma_cfg_0_reg); + + // Set dsc_cfg_2 register to indicate it's an SGDMA operation + dma_regs->dsc_cfg_2 = PUFCC_DMA_DSC_CFG2_SGDMA_VAL; + + // Set starting address of SGDMA descriptors in dma_dsc_cfg3 register + dma_regs->dsc_cfg_3 = (uint32_t)sg_dma_descs; + + // Clear and disable DMA and HMAC interrupts + REG_WRITE_32(&dma_regs->interrupt, &intrpt_reg); + REG_WRITE_32(&hmac_regs->interrupt, &intrpt_reg); + + // Start the DMA operation by writing to its start register + REG_WRITE_32(&dma_regs->start, &start_reg); + + // Poll on busy status + status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); + + if (status != PUFCC_SUCCESS) { + return status; + } + + if (hmac_regs->status) { + return PUFCC_E_ERROR; + } + + // Read the calculated hash value + for (uint8_t i = 0; i < (PUFCC_SHA_256_LEN / PUFCC_WORD_SIZE); i++) { + ((uint32_t *)hash_out->val)[i] = be2le(crypto_regs->dgst_out[i]); + } + + hash_out->len = PUFCC_SHA_256_LEN; + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_decrypt_aes + * @brief Decrypt passed in data using AES decryption algorithm + * + * @param[in] out_addr Address to write decrypted data to + * @param[in] in_addr Address of the encrypted data + * @param[in] in_len Length of the input data in bytes + * @param[in] prev_len Length of the previously decrypted data in case + * decrypting data in chunks; 0 for first or single + * chunk + * @param[in] key_type Key type i.e. SW or OTP + * @param[in] key_addr Address or OTP slot of the decryption key + * @param[in] key_len Length of the decryption key + * @param[in] iv_addr IV address + * @param[in] iv_len IV length + * @param[in] write_type Write type i.e. write decrypted data to fixed address + * or auto-increment the destination address + * @param[in] readback_iv If true, read back updated IV value corresponding to + * number of processed data blocks into passed in + * iv_addr buffer. In this case iv_addr buffer must be + * writable. + * + * @return PUFCC_SUCCESS on success, otherwise an error code + */ +enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, + uint32_t in_len, uint32_t prev_len, + enum pufcc_key_type key_type, + uint32_t key_addr, uint32_t key_len, + uint32_t iv_addr, uint32_t iv_len, + enum pufcc_dma_rw_type write_type, + bool readback_iv) { + enum pufcc_status status; + uint32_t temp32; + + // Configure DMA intrpt register + temp32 = 0; + struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; + intrpt_reg->intrpt_st = 1; // Write 1 to clear interrupt + REG_WRITE_32(&dma_regs->interrupt, intrpt_reg); + + // Set dma_cfg_0 register + temp32 = 0; + REG_WRITE_32(&dma_regs->cfg_0, &temp32); + + struct pufcc_dma_cfg_1_reg *cfg_1_reg = (struct pufcc_dma_cfg_1_reg *)&temp32; + cfg_1_reg->rbst_max = 0xF; + cfg_1_reg->rbst_min = 0xF; + cfg_1_reg->wbst_max = 0xF; + cfg_1_reg->wbst_min = 0xF; + REG_WRITE_32(&dma_regs->cfg_1, cfg_1_reg); + + // Set data source address in dsc_cfg_0 register + REG_WRITE_32(&dma_regs->dsc_cfg_0, &in_addr); + + // Set decrypted data destination address in dsc_cfg_1 register + REG_WRITE_32(&dma_regs->dsc_cfg_1, &out_addr); + + // Set data length in dsc_cfg_2 register + REG_WRITE_32(&dma_regs->dsc_cfg_2, &in_len); + + // Configure dma_dsc_cfg_4 register + temp32 = 0; + struct pufcc_dma_dsc_cfg_4_reg *dsc_cfg_4_reg = + (struct pufcc_dma_dsc_cfg_4_reg *)&temp32; + dsc_cfg_4_reg->fw = write_type; + dsc_cfg_4_reg->fr = AUTO_INCREMENT; // Autoincrement source address + dsc_cfg_4_reg->offset = prev_len % CTR_MODE_BLOCK_SIZE; + REG_WRITE_32(&dma_regs->dsc_cfg_4, dsc_cfg_4_reg); + + // Configure key_cfg_0 register + struct pufcc_dma_key_cfg0_reg *key_cfg_0_reg = + (struct pufcc_dma_key_cfg0_reg *)&temp32; + key_cfg_0_reg->key_src = key_type; + key_cfg_0_reg->key_dst = PUFCC_DMA_KEY_DST_SP38A; // SP38a + key_cfg_0_reg->key_size = key_len * 8; // Key length in bits + + // Configure the decryption key + if (key_type == PUFCC_SW_KEY) { + for (uint32_t i = 0; i < (key_len / PUFCC_WORD_SIZE); i++) { + crypto_regs->sw_key[i] = be2le(((uint32_t *)key_addr)[i]); + } + } else { + key_cfg_0_reg->key_idx = (enum pufcc_key_type)key_addr; + } + + REG_WRITE_32(&dma_regs->key_cfg_0, key_cfg_0_reg); + + // Configure IV + for (uint32_t i = 0; i < (iv_len / PUFCC_WORD_SIZE); i++) { + crypto_regs->iv[i] = be2le(((uint32_t *)iv_addr)[i]); + } + + // Configure SP38a intrpt register + temp32 = 0; + intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; + intrpt_reg->intrpt_st = 1; // Clear interrupt by writing 1 + REG_WRITE_32(&sp38a_regs->interrupt, intrpt_reg); + + // Configure SP38a config register + struct pufcc_sp38a_config_reg *sp38a_config_reg = + (struct pufcc_sp38a_config_reg *)&temp32; + sp38a_config_reg->variant = + (key_len == PUFCC_CRYPTO_AES128_KEY_LEN ? PUFCC_AES128 : PUFCC_AES256); + sp38a_config_reg->mode = PUFCC_CTR128; + sp38a_config_reg->enc_dec = 0; // Decryption + REG_WRITE_32(&sp38a_regs->cfg, sp38a_config_reg); + + // Start DMA operation + struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; + start_reg->start_p = 1; + REG_WRITE_32(&dma_regs->start, start_reg); + + // Poll on busy status + status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); + + if (status != PUFCC_SUCCESS) { + return status; + } + + if (sp38a_regs->status & PUFCC_SP38A_STATUS_ERROR_MASK) { + return PUFCC_E_ERROR; + } + + // Read back updated IV + if (readback_iv) { + for (uint8_t i = 0; i < iv_len / PUFCC_WORD_SIZE; i++) { + ((uint32_t *)iv_addr)[i] = be2le(crypto_regs->iv[i]); + } + } + + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_rsa2048_sign_verify + * @brief Verify RSA2048 signature of the input message data + * + * @param[in] sig Address of the message signature + * @param[in] msg_addr Address of the message data + * @param[in] pub_key RSA2048 public key + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_rsa2048_sign_verify( + uint8_t *sig, struct rs_crypto_addr *msg_addr, + struct rs_crypto_rsa2048_puk *pub_key) { + enum pufcc_status status = PUFCC_SUCCESS; + uint32_t temp32; + uint8_t dec_msg[PUFCC_RSA_2048_LEN]; + + // Configure signature scheme + temp32 = 0; + struct pufcc_pkc_ecp_ec_reg *ecp_ec_reg = + (struct pufcc_pkc_ecp_ec_reg *)&temp32; + ecp_ec_reg->field = PUFCC_RSA_2048; + REG_WRITE_32(&pkc_regs->ecp_ec, ecp_ec_reg); + + // Reverse public key modulus + reverse(pufcc_buffer, pub_key->n, PUFCC_RSA_2048_LEN); + + // Write reversed public key modulus to ECP data field at proper offset + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET, + pufcc_buffer, PUFCC_RSA_2048_LEN); + + // Write public key exponent to ecp_e_short register + REG_WRITE_32(&pkc_regs->ecp_e_short, &pub_key->e); + + // Reverse signature + reverse(pufcc_buffer, sig, PUFCC_RSA_2048_LEN); + + // Write reversed signature to ECP data field at proper offset + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, + pufcc_buffer, PUFCC_RSA_2048_LEN); + + // Write microprogram for RSA2048 + memcpy((void *)&pkc_regs->ecp_mac, rsa_2048_mprog, sizeof(rsa_2048_mprog)); + + // Clear and disable PKC interrupt + temp32 = 0; + struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; + intrpt_reg->intrpt_st = 1; + REG_WRITE_32(&pkc_regs->interrupt, intrpt_reg); + + // Start PKC operation + struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; + start_reg->start_p = 1; + REG_WRITE_32(&pkc_regs->start, start_reg); + + // Poll on busy status + status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); + + if (status != PUFCC_SUCCESS) { + return status; + } + + // Read decrypted message from proper offset in ECP data field and reverse it + memcpy(pufcc_buffer, + (uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, + PUFCC_RSA_2048_LEN); + reverse(dec_msg, pufcc_buffer, PUFCC_RSA_2048_LEN); + + status = rsa_p1v15_verify(dec_msg, msg_addr); + + return status; +} + +/** + * @fn pufcc_ecdsa256_sign_verify + * @brief Verify ECDSA256 signature of the input message data + * + * @param[in] sig Address of the message signature + * @param[in] msg_addr Address of the message data + * @param[in] pub_key ECDSA256 public key + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_ecdsa256_sign_verify( + struct rs_crypto_ec256_sig *sig, struct rs_crypto_addr *msg_addr, + struct rs_crypto_ec256_puk *pub_key) { + uint32_t temp32, prev_len = 0; + enum pufcc_status status; + struct rs_crypto_hash hash; + + // Calculate hash of the message + if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != + PUFCC_SUCCESS) { + return PUFCC_E_ERROR; + } + +#ifndef RS_RTOS_PORT + RS_PROFILE_CHECKPOINT("msg hash calc"); +#endif + + // Set the EC NIST P256 parameters after reversing them + reverse(pufcc_buffer, ecc_param_nistp256.prime, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PRIME_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, ecc_param_nistp256.a, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_A_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, ecc_param_nistp256.b, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_B_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, ecc_param_nistp256.px, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PX_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, ecc_param_nistp256.py, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PY_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, ecc_param_nistp256.order, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_ORDER_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + // Configure signature scheme + temp32 = 0; + struct pufcc_pkc_ecp_ec_reg *ecp_ec_reg = + (struct pufcc_pkc_ecp_ec_reg *)&temp32; + ecp_ec_reg->field = PUFCC_ECDSA256; + ecp_ec_reg->h = 1; // EC cofactor h + REG_WRITE_32(&pkc_regs->ecp_ec, ecp_ec_reg); + + // Write microprogram for ECDSA 256 + memcpy((void *)&pkc_regs->ecp_mac, p256_ecdsa_mprog, + sizeof(p256_ecdsa_mprog)); + + // Set the hash, public key & signature in PKC module after reversing each + reverse(pufcc_buffer, hash.val, PUFCC_SHA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_HASH_OFFSET, + pufcc_buffer, PUFCC_SHA_256_LEN); + + reverse(pufcc_buffer, pub_key->x, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBX_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, pub_key->y, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBY_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, sig->r, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_R_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + + reverse(pufcc_buffer, sig->s, PUFCC_ECDSA_256_LEN); + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_S_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + +#ifndef RS_RTOS_PORT + RS_PROFILE_CHECKPOINT("misc verif ops"); +#endif + + // Clear and disable PKC interrupt + temp32 = 0; + struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; + intrpt_reg->intrpt_st = 1; + REG_WRITE_32(&pkc_regs->interrupt, intrpt_reg); + + // Start PKC operation + struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; + start_reg->start_p = 1; + REG_WRITE_32(&pkc_regs->start, start_reg); + + // Poll on busy status + status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); + +#ifndef RS_RTOS_PORT + RS_PROFILE_CHECKPOINT("PKC op"); +#endif + + return status; +} + +#ifndef RS_RTOS_PORT + + /** + * @fn pufcc_dma_transfer + * @brief Transfer data using PUFcc DMA + * + * @param[in] src_addr Source data address + * @param[in] dest_addr Destination data address + * @param[in] len Length of the data to be transferred + * @param[in] fixed_read Read data from a fixed address + * @param[in] fixed_write Write data to a fixed address + * @return PUFCC_SUCCESS on success, otherwise an error code + */ + enum pufcc_status pufcc_dma_transfer(uint32_t src_addr, uint32_t dest_addr, + uint32_t len, bool fixed_read, + bool fixed_write) { + enum pufcc_status status; + uint32_t temp32 = 0; + + // Configure DMA intrpt register + struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; + intrpt_reg->intrpt_st = 1; // Write 1 to clear interrupt + REG_WRITE_32(&dma_regs->interrupt, intrpt_reg); + + // Set dma_cfg_0 register + temp32 = 0; // rng_en = 0, sg_en = 0 + REG_WRITE_32(&dma_regs->cfg_0, &temp32); + + struct pufcc_dma_cfg_1_reg *cfg_1_reg = (struct pufcc_dma_cfg_1_reg *)&temp32; + cfg_1_reg->rbst_max = 0xF; + cfg_1_reg->rbst_min = 0xF; + cfg_1_reg->wbst_max = 0xF; + cfg_1_reg->wbst_min = 0xF; + REG_WRITE_32(&dma_regs->cfg_1, cfg_1_reg); + + // Set data source address in dsc_cfg_0 register + REG_WRITE_32(&dma_regs->dsc_cfg_0, &src_addr); + + // Set decrypted data destination address in dsc_cfg_1 register + REG_WRITE_32(&dma_regs->dsc_cfg_1, &dest_addr); + + // Set data length in dsc_cfg_2 register + REG_WRITE_32(&dma_regs->dsc_cfg_2, &len); + + // Configure dma_dsc_cfg_4 register + temp32 = 0; + struct pufcc_dma_dsc_cfg_4_reg *dsc_cfg_4_reg = + (struct pufcc_dma_dsc_cfg_4_reg *)&temp32; + dsc_cfg_4_reg->fw = fixed_write; + dsc_cfg_4_reg->fr = fixed_read; + dsc_cfg_4_reg->no_cypt = true; // Bypass crypto modules + REG_WRITE_32(&dma_regs->dsc_cfg_4, dsc_cfg_4_reg); + + // Start DMA operation + struct pufcc_start_reg *start_reg = (struct pufcc_start_reg *)&temp32; + start_reg->start_p = 1; + REG_WRITE_32(&dma_regs->start, start_reg); + + // Poll on busy status + status = busy_wait(&dma_regs->status_0, PUFCC_DMA_ERROR_MASK); + + return status; + } + +#endif + +/** + * @fn pufcc_otp_setup_wait + * @brief Wait for the PUFrt module setup during power on + * + * @return PUFCC_SUCCESS if OTP is setup successfully, otherwise an error code + */ +enum pufcc_status pufcc_otp_setup_wait(void) { + enum pufcc_status status = busy_wait(&rt_regs->status, PUFCC_RT_ERROR_MASK); + + return status; +} + +/** + * @fn pufcc_program_otp + * @brief Write data to an OTP slot. + * PUFcc OTP memory contains 1024 bytes and is divided into 32 + * individual slots of 32 bytes each. + * + * @param[in] in_buf Buffer containing data to be written to OTP + * @param[in] len Length of the input buffer + * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_program_otp(const uint8_t *in_buf, uint32_t len, + enum pufcc_otp_slot otp_slot) { + enum pufcc_status check; + uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; + uint32_t start_index = addr / PUFCC_WORD_SIZE; + enum pufcc_otp_lock lock; + + if ((check = otp_range_check(addr, len)) != PUFCC_SUCCESS) return check; + + // Return error if write access is locked + pufcc_get_otp_rwlck(otp_slot, &lock); + if (lock != PUFCC_OTP_RW) return PUFCC_E_DENY; + + // Program the OTP slot + for (uint32_t i = 0; i < len; i += 4) { + union { + uint32_t word; + uint8_t byte[4]; + } otp_word; + for (int8_t j = 3; j >= 0; j--) // reserve, default 0xff + otp_word.byte[j] = ((i + 3 - j) < len) ? in_buf[i + 3 - j] : 0xff; + + otp_mem->otp[start_index + (i / 4)] = otp_word.word; + } + + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_read_otp + * @brief Read data from an OTP slot. + * PUFcc OTP memory contains 1024 bytes and is divided into 32 + * individual slots of 32 bytes each. + * + * @param[in] out_buf Buffer to read data into + * @param[in] len Length of the data to read + * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_read_otp(uint8_t *out_buf, uint32_t len, + enum pufcc_otp_slot otp_slot) { + enum pufcc_status check; + uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; + uint32_t word, start_index, wlen; + enum pufcc_otp_lock lock = PUFCC_OTP_RW; // default value + + if ((check = otp_range_check(addr, len)) != PUFCC_SUCCESS) return check; + + // Return error if read access is locked + pufcc_get_otp_rwlck(otp_slot, &lock); + if (lock == PUFCC_OTP_NA) return PUFCC_E_DENY; + + wlen = len / PUFCC_WORD_SIZE; + start_index = addr / PUFCC_WORD_SIZE; + + if (wlen > 0) { + memcpy(out_buf, (void *)(otp_mem->otp + start_index), + wlen * PUFCC_WORD_SIZE); + + uint32_t *out32 = (uint32_t *)out_buf; + for (size_t i = 0; i < wlen; ++i) *(out32 + i) = be2le(*(out32 + i)); + } + + if (len % PUFCC_WORD_SIZE != 0) { + out_buf += wlen * PUFCC_WORD_SIZE; + word = be2le(*(otp_mem->otp + start_index + wlen)); + memcpy(out_buf, &word, len % PUFCC_WORD_SIZE); + } + + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_lock_otp + * @brief Lock an OTP key slot according to passed-in lock value. + * + * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 + * @param[in] len Length of the OTP slot to be locked + * @param[in] lock Value of the lock to be placed + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_lock_otp(enum pufcc_otp_slot otp_slot, uint32_t len, + enum pufcc_otp_lock lock) { + enum pufcc_status check; + uint32_t lock_val = lock, shift = 0, start = 0, end = 0, mask = 0, val32 = 0; + int rwlock_index; + uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; + + if ((check = otp_range_check(addr, len)) != PUFCC_SUCCESS) return check; + + // Set end and start indices of OTP words + end = (len + 3) / 4; + start = addr / PUFCC_WORD_SIZE; + + for (uint32_t i = 0; i < end; i++) { + int idx = start + i; + + // Get the index of RWLCK register corresponding to current OTP word index + if ((rwlock_index = rwlck_index_get(idx)) == -1) { + return PUFCC_E_ERROR; + } + + // Get shift size for lock value to be written to RWLCK register according + // to OTP word index + shift = (idx % PUFCC_OTP_WORDS_PER_RWLCK_REG) * + PUFCC_OTP_RWLCK_REG_BITS_PER_OTP_WORD; + // Update lock value for current 'rwlock_index' + val32 |= lock_val << shift; + // Update mask value for current 'rwlock_index' + mask |= 0xF << shift; + + // If we have fully utilized RWLCK register at 'rwlock_index' or this is + // the end of OTP range that we are locking then write the lock value in + // RWLCK register at 'rwlock_index' + if (shift == 28 || i == end - 1) { + // Read modify write + val32 |= (rt_regs->pif[rwlock_index] & (~mask)); + rt_regs->pif[rwlock_index] = val32; + + // Clear values for next iteration + val32 = 0; + mask = 0; + } + } + + return PUFCC_SUCCESS; +} + +/** + * @fn pufcc_zeroize_otp + * @brief Zeroize an OTP key slot (32 bytes) permanently. + * + * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +enum pufcc_status pufcc_zeroize_otp(enum pufcc_otp_slot otp_slot) { + enum pufcc_status status; + + if (otp_slot < PUFCC_OTPKEY_0 || otp_slot > PUFCC_OTPKEY_31) { + status = PUFCC_E_INVALID; + } else { + uint32_t zeroize_cmd = + (otp_slot - PUFCC_OTPKEY_0) + PUFCC_OTP_ZEROIZE_BASE_CMD; + + rt_regs->otp_zeroize = zeroize_cmd; + + // Wait on busy status + status = busy_wait(&rt_regs->status, PUFCC_RT_ERROR_MASK); + } + + return status; +} + +/** + * @fn pufcc_get_otp_rwlck + * @brief Get the read write lock value of passed-in OTP slot. This function + * assumes that the lock value of all the words of an OTP is same as that + * of the first word of that slot + * + * @param[in] otp_slot OTP slot; PUFCC_OTPKEY_0 ~ PUFCC_OTPKEY_31 + * @param[out] lock_val Lock address to return the lock value in + * @return PUFCC_SUCCESS on success, otherwise and error code + */ +enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, + enum pufcc_otp_lock *lock_val) { + enum pufcc_status check; + uint16_t addr = otp_slot * PUFCC_OTP_KEY_LEN; + + if ((check = otp_range_check(addr, 4)) != PUFCC_SUCCESS) return check; + + // Get OTP word index + int index = addr / PUFCC_WORD_SIZE; + + // Get offset of the lock value within RWLCK register corresponding to this + // OTP word + int rwlck_offset = (index % PUFCC_OTP_WORDS_PER_RWLCK_REG) * + PUFCC_OTP_RWLCK_REG_BITS_PER_OTP_WORD; + + // Get the index of RWLCK register corresponding to current OTP word index + // read lock value at that index + index = rwlck_index_get(index); + uint32_t lck = (rt_regs->pif[index] >> rwlck_offset) & PUFCC_PIF_RWLCK_MASK; + + switch (lck) { + // Read write access + case PUFCC_OTP_RWLCK_RW_0: + case PUFCC_OTP_RWLCK_RW_1: + case PUFCC_OTP_RWLCK_RW_2: + case PUFCC_OTP_RWLCK_RW_3: + case PUFCC_OTP_RWLCK_RW_4: + *lock_val = PUFCC_OTP_RW; + break; + + // Read only access + case PUFCC_OTP_RWLCK_RO_0: + case PUFCC_OTP_RWLCK_RO_1: + case PUFCC_OTP_RWLCK_RO_2: + *lock_val = PUFCC_OTP_RO; + break; + + // All other values indicate no access + default: + *lock_val = PUFCC_OTP_NA; + break; + } + + return PUFCC_SUCCESS; +} + +#ifndef RS_RTOS_PORT + + int pufcc_dma_request_channel(struct pufcc_dma_dev *dev) { + if (dev->is_dev_free) { + dev->is_dev_free = false; + return 0; + } + + return -1; + } + + void pufcc_dma_release_channel(struct pufcc_dma_dev *dev, int channel) { + (void)channel; + dev->is_dev_free = true; + } + + enum rs_status pufcc_dma_config_descriptor_memory(struct pufcc_dma_dev *dev, + int channel, uintptr_t addr, + size_t max_descriptors) { + // Check that channel is valid and is in use + if ((channel != 0) || (dev->is_dev_free)) { + return ERROR; + } + + dev->dma_descs = (struct pufcc_sg_dma_desc *)addr; + dev->num_descriptors = max_descriptors; + return OK; + } + + enum rs_status pufcc_dma_config_xfer(struct pufcc_dma_dev *dev, int channel, + struct rs_dma_config *config) { + uint8_t desc_count = 0; + struct rs_dma_block_config *current_block = config->head_block; + struct pufcc_dma_cfg_0_reg dma_cfg_0_reg = {0}; + struct pufcc_dma_cfg_1_reg cfg_1_reg = {0}; + struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; + struct pufcc_intrpt_reg intrpt_reg = {0}; + + // Check that channel is valid and is in use and required descriptors for this + // transactions are available + if ((channel != 0) || (dev->is_dev_free) || + (config->block_count > dev->num_descriptors)) { + return ERROR; + } + + // Write 1 to clear interrupt + intrpt_reg.intrpt_st = 1; + + // Setup interrupt + if (config->complete_callback_en) { + intrpt_reg.intrpt_en = 1; + } else { + intrpt_reg.intrpt_en = 0; + } + + // Set SGDMA descriptors + do { + dev->dma_descs[desc_count].read_addr = + be2le((uint32_t)current_block->src_addr); + dev->dma_descs[desc_count].write_addr = + be2le((uint32_t)current_block->dst_addr); + dev->dma_descs[desc_count].length = be2le(current_block->block_size); + dev->dma_descs[desc_count].next = + be2le((uint32_t)&dev->dma_descs[desc_count + 1]); + + dev->dma_descs[desc_count].key_cfg = 0; + dev->dma_descs[desc_count].cypt_cfg[0] = 0; + dev->dma_descs[desc_count].cypt_cfg[1] = 0; + + *(uint32_t *)&dma_dsc_cfg_4_reg = 0; + if (current_block->src_addr_adjust == RS_DMA_ADDR_ADJUST_FIXED) { + dma_dsc_cfg_4_reg.fr = 1; + } else if (current_block->src_addr_adjust != RS_DMA_ADDR_ADJUST_INCREMENT) { + return ERROR; + } + + if (current_block->dst_addr_adjust == RS_DMA_ADDR_ADJUST_FIXED) { + dma_dsc_cfg_4_reg.fw = 1; + } else if (current_block->dst_addr_adjust != RS_DMA_ADDR_ADJUST_INCREMENT) { + return ERROR; + } + + // Bypass crypto modules + dma_dsc_cfg_4_reg.no_cypt = true; + + if (!desc_count) { + dma_dsc_cfg_4_reg.head = true; + } + + current_block = current_block->next_block; + + // Mark this descriptor as last if there is no more data + if (!current_block) { + dma_dsc_cfg_4_reg.dn_pause = true; + dma_dsc_cfg_4_reg.tail = true; + + if (config->complete_callback_en) { + dma_dsc_cfg_4_reg.dn_intrpt = true; + } + } + + dev->dma_descs[desc_count].dsc_cfg_4 = + be2le(*(uint32_t *)&dma_dsc_cfg_4_reg); + + desc_count++; + } while (current_block && (desc_count < dev->num_descriptors)); + + if (current_block) { + // No enough descriptors available + return ERROR; + } + + /*** Configure DMA registers ***/ + // Enable SGDMA in dma_cfg_0 register + dma_cfg_0_reg.sg_en = 1; + REG_WRITE_32(&dev->regs->cfg_0, &dma_cfg_0_reg); + + cfg_1_reg.rbst_max = 0xF; + cfg_1_reg.rbst_min = 0xF; + cfg_1_reg.wbst_max = 0xF; + cfg_1_reg.wbst_min = 0xF; + REG_WRITE_32(&dev->regs->cfg_1, &cfg_1_reg); + + // Set dsc_cfg_2 register to indicate it's an SGDMA operation + dev->regs->dsc_cfg_2 = PUFCC_DMA_DSC_CFG2_SGDMA_VAL; + + // Set starting address of SGDMA descriptors in dma_dsc_cfg3 register + dev->regs->dsc_cfg_3 = (uint32_t)dev->dma_descs; + + // Write interrupt register with values populated above + REG_WRITE_32(&dev->regs->interrupt, &intrpt_reg); + + // Set up call backs + dev->callback = config->callback; + dev->callback_args = config->callback_args; + + return OK; + } + + enum rs_status pufcc_dma_start_xfer(struct pufcc_dma_dev *dev, int channel) { + struct pufcc_start_reg start_reg = {0}; + + // Check that channel number is valid and the channel has been requested + if ((channel != 0) || (dev->is_dev_free)) { + return ERROR; + } + + // Start the DMA operation by writing to its start register + start_reg.start_p = 1; + REG_WRITE_32(&dev->regs->start, &start_reg); + + return OK; + } + + enum rs_status pufcc_dma_stop_xfer(struct pufcc_dma_dev *dev, int channel) { + struct pufcc_sg_dma_desc *next_desc_ptr; + struct pufcc_dma_dsc_cfg_4_reg dma_dsc_cfg_4_reg = {0}; + + // check the channel number is valid and the channel has been requested + if ((channel != 0) || dev->is_dev_free) { + return ERROR; + } + + // Get pointer to next descriptor in queue + next_desc_ptr = (struct pufcc_sg_dma_desc *)dev->regs->dsc_cur_3; + + // Make sure that this descriptor lies within descriptor memory; it will lie + // outside the memory if last descriptor is already being processed + if (((uint32_t)next_desc_ptr > (uint32_t)dev->dma_descs) && + ((uint32_t)next_desc_ptr < + ((uint32_t)dev->dma_descs + + (dev->num_descriptors * sizeof(struct pufcc_sg_dma_desc))))) { + // Set up descriptor to stop DMA operation + *(uint32_t *)&dma_dsc_cfg_4_reg = next_desc_ptr->dsc_cfg_4; + dma_dsc_cfg_4_reg.dn_pause = true; + dma_dsc_cfg_4_reg.tail = true; + } + + return OK; + } + + void pufcc_dma_irq_handler(struct pufcc_dma_dev *dev) { + int status = (dev->regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); + struct pufcc_intrpt_reg *intrpt_reg_ptr = + (struct pufcc_intrpt_reg *)&dev->regs->interrupt; + + // Clear and disable interrupt + intrpt_reg_ptr->intrpt_st = 1; // Set to clear + intrpt_reg_ptr->intrpt_en = 0; + + dev->callback(dev->callback_args, 0, status); + } + +#else + + int pufcc_clear_and_disable_intr(void) { + int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); + struct pufcc_intrpt_reg *intrpt_reg_ptr = + (struct pufcc_intrpt_reg *)&dma_regs->interrupt; + + // Clear and disable interrupt + intrpt_reg_ptr->intrpt_st = 1; // Set to clear + intrpt_reg_ptr->intrpt_en = 0; + + return status; + } + +#endif + +/** + * @fn rsa_p1v15_verify + * @brief Verify input RSA2048 decrypted message according to PKCS#1 v1.5 RSA + * verification standard. + * @param[in] dec_msg Input RSA decrypted message + * @param[in] msg_addr Address of the original data that was RSA signed + * @return PUFCC_SUCCESS on success, otherwise an error code. + */ +static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, + struct rs_crypto_addr *msg_addr) { + uint32_t i, prev_len = 0; + struct rs_crypto_hash hash; + uint8_t pret[19] = {0x30, 0, 0x30, 0x0d, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, + 0, 0x05, 0x00, 0x04, 0}; + + if ((dec_msg[0] != 0x00) || (dec_msg[1] != 0x01)) { + return PUFCC_E_VERFAIL; + } + + for (i = 2; i < PUFCC_RSA_2048_LEN; i++) { + if (dec_msg[i] != 0xff) { + break; + } + } + + if (dec_msg[i++] != 0x00) { + return PUFCC_E_VERFAIL; + } + + // Verify that decrypted message has SHA256 hash + if (dec_msg[i + 14] == 1) { + pret[1] = 0x31; + pret[14] = 0x01; + pret[18] = 0x20; + } else { + return PUFCC_E_INVALID; + } + + if ((memcmp(dec_msg + i, pret, 19) != 0) || + ((i + 19 + pret[18]) != PUFCC_RSA_2048_LEN)) { + return PUFCC_E_VERFAIL; + } + + // Calculate hash of the message + if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != + PUFCC_SUCCESS) { + return PUFCC_E_ERROR; + } + + if (memcmp(dec_msg + i + 19, hash.val, hash.len) != 0) { + return PUFCC_E_VERFAIL; + } + + return PUFCC_SUCCESS; +} + +/** + * @fn rwlck_index_get + * @brief Get the index of RWLCK register corresponding to passed-in OTP word + * index. + * + * @param[in] idx OTP word index for which to get the RWLCK register index for + * @return Index of the RWLCK register + */ +static int rwlck_index_get(uint32_t idx) { + uint32_t rwlck_idx = idx / PUFCC_OTP_WORDS_PER_RWLCK_REG; + + if (rwlck_idx >= PUFCC_PIF_MAX_RWLOCK_REGS) return -1; + + // Return the actual index of RWCLK register in PIF registers group + return PUFCC_PIF_RWLCK_START_INDEX + rwlck_idx; +} + +/** + * @fn reverse + * @brief Reverse input byte array. + * + * @param[in] dst Destination address of the reversed byte array + * @param[in] src Address of the input byte array + * @param[in] len Length of the input byte array to be reversed + */ +static void reverse(uint8_t *dst, const uint8_t *src, size_t len) { + for (size_t i = 0, j = len - 1; i < len; i++, j--) { + dst[i] = src[j]; + } +} + +/** + * @fn be2le + * @brief Reverse endianness of the input 4 byte word + * + * @param[in] var Input 4 byte variable + * @return 4 byte word with reversed endianness + */ +static uint32_t be2le(uint32_t var) { + return (((0xff000000 & var) >> 24) | ((0x00ff0000 & var) >> 8) | + ((0x0000ff00 & var) << 8) | ((0x000000ff & var) << 24)); +} + +/** + * @fn otp_range_check + * @brief Check range validity of the input OTP address + * + * @param[in] addr OTP address + * @param[in] len Length of OTP after OTP address + * @return 4 byte word with reversed endianness + * @return PUFCC_SUCCESS if OTP address and range is valid, otherwise + * an error code. + */ +static enum pufcc_status otp_range_check(uint32_t addr, uint32_t len) { + // word-aligned OTP address check + if ((addr % PUFCC_WORD_SIZE) != 0) return PUFCC_E_ALIGN; + // OTP boundary check + if ((len > PUFCC_OTP_LEN) || (addr > (PUFCC_OTP_LEN - len))) + return PUFCC_E_OVERFLOW; + return PUFCC_SUCCESS; +} + +/** + * @fn busy_wait + * @brief Waits on busy bit of the passed-in status register till it gets + * cleared or it times out. + * + * @param[in] status_reg_addr Status register's address + * @param[in] error_mask Bitmask of error bits in passed-in status register + * @return PUFCC_SUCCESS if busy bit gets cleared without an + * error, otherwise an error code. + */ +static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, + uint32_t error_mask) { + uint32_t status; + int32_t busy_count = PUFCC_MAX_BUSY_COUNT; + + do { + #ifndef RS_RTOS_PORT + status = read_reg(status_reg_addr); + #else + status = sys_read32((mem_addr_t)status_reg_addr); + #endif + busy_count--; + } while ((status & PUFCC_BUSY_BIT_MASK) && (busy_count > 0)); + + if (status & PUFCC_BUSY_BIT_MASK) { + return PUFCC_E_TIMEOUT; + } else if (status & error_mask) { + return PUFCC_E_ERROR; + } + + return PUFCC_SUCCESS; +} + +enum pufcc_status pufcc_init(uint32_t base_addr) { + enum pufcc_status status; + + // Initialize base addresses of different PUFcc modules + dma_regs = (struct pufcc_dma_regs *)base_addr; + rt_regs = (struct pufcc_rt_regs *)(base_addr + PUFCC_RT_OFFSET); + otp_mem = (struct pufcc_otp_mem *)(base_addr + PUFCC_RT_OFFSET + + PUFCC_RT_OTP_OFFSET); + hmac_regs = (struct pufcc_hmac_regs *)(base_addr + PUFCC_HMAC_OFFSET); + crypto_regs = (struct pufcc_crypto_regs *)(base_addr + PUFCC_CRYPTO_OFFSET); + sp38a_regs = (struct pufcc_sp38a_regs *)(base_addr + PUFCC_SP38A_OFFSET); + pkc_regs = (struct pufcc_pkc_regs *)(base_addr + PUFCC_PKC_OFFSET); + + // Wait for OTP setup + status = pufcc_otp_setup_wait(); + + return status; +} diff --git a/drivers/crypto/pufcc.h b/drivers/crypto/pufcc.h new file mode 100644 index 0000000000000..22e0da207d88c --- /dev/null +++ b/drivers/crypto/pufcc.h @@ -0,0 +1,642 @@ +#ifndef _PUFCC_H_ +#define _PUFCC_H_ + +#include + +#define RS_RTOS_PORT + +#ifndef RS_RTOS_PORT + #include "rs_crypto.h" + #include "rs_dma.h" +#else + #include + #include +#endif + +/*** Generic PUFcc defines ***/ +#define PUFCC_WORD_SIZE 4 +#define PUFCC_BUSY_BIT_MASK 0x00000001 + +/*** RT and OTP defines ***/ +#define PUFCC_RT_OFFSET 0x3000 +#define PUFCC_RT_OTP_OFFSET 0x400 +#define PUFCC_RT_ERROR_MASK 0x0000001e +#define PUFCC_OTP_LEN 1024 +#define PUFCC_OTP_KEY_LEN 32 +#define PUFCC_OTP_ZEROIZE_BASE_CMD 0x80 + +// One read/write lock register controls 8 OTP words +#define PUFCC_OTP_WORDS_PER_RWLCK_REG 8 + +// 4 bits are reserved for lock value of one OTP word in read/write lock +// register +#define PUFCC_OTP_RWLCK_REG_BITS_PER_OTP_WORD 4 +#define PUFCC_PIF_RWLCK_MASK 0xF +#define PUFCC_PIF_MAX_RWLOCK_REGS \ + (PUFCC_OTP_LEN / PUFCC_WORD_SIZE / PUFCC_OTP_WORDS_PER_RWLCK_REG) + +// Start index of the RWLCK register in PIF registers group +#define PUFCC_PIF_RWLCK_START_INDEX 32 + +// Define all possible OTP lock values +#define PUFCC_OTP_RWLCK_RW_0 0x0 // Read Write access +#define PUFCC_OTP_RWLCK_RW_1 0x1 // Read Write access +#define PUFCC_OTP_RWLCK_RW_2 0x2 // Read Write access +#define PUFCC_OTP_RWLCK_RW_3 0x4 // Read Write access +#define PUFCC_OTP_RWLCK_RW_4 0x8 // Read Write access +#define PUFCC_OTP_RWLCK_RO_0 0x3 // Read Only access +#define PUFCC_OTP_RWLCK_RO_1 0x7 // Read Only access +#define PUFCC_OTP_RWLCK_RO_2 0xb // Read Only access + +/*** DMA defines ***/ +#define PUFCC_DMA_KEY_DST_HASH 0x1 +#define PUFCC_DMA_KEY_DST_SP38A 0x8 +#define PUFCC_DMA_DSC_CFG2_SGDMA_VAL 0x20 +#define PUFCC_DMA_ERROR_MASK 0xFFFFFFFE + +/*** HMAC defines ***/ +#define PUFCC_HMAC_OFFSET 0x0800 +#define PUFCC_HMAC_SW_KEY_MAXLEN 64 +#define PUFCC_SHA_256_LEN 32 +#define PUFCC_HMAC_FUNCTION_HASH 0x0 +#define PUFCC_HMAC_VARIANT_SHA256 0x03 + +/*** Crypto defines ***/ +#define PUFCC_CRYPTO_OFFSET 0x0100 +#define PUFCC_CRYPTO_SW_KEY_MAXLEN 64 // The byte length of CRYPTO_SW_KEY_ADDR +#define PUFCC_CRYPTO_DGST_LEN 64 // The byte length of CRYPTO_DGST field +#define PUFCC_CRYPTO_IV_MAXLEN 16 +#define PUFCC_CRYPTO_AES128_KEY_LEN 16 +#define PUFCC_CRYPTO_AES256_KEY_LEN 32 + +/*** SP38a defines ***/ +#define PUFCC_SP38A_OFFSET 0x0200 +#define PUFCC_SP38A_STATUS_ERROR_MASK 0xfffff0c0 + +/*** PKC defines ***/ +#define PUFCC_PKC_OFFSET 0x1000 +#define PUFCC_RSA_2048_LEN 256 +#define PUFCC_ECDSA_256_LEN 32 +#define PUFCC_DATA_RSA2048_MODULUS_OFFSET 256 +#define PUFCC_DATA_RSA2048_SIGN_OFFSET 768 +#define PUFCC_DATA_ECDSA_PRIME_OFFSET 256 +#define PUFCC_PKC_ERROR_MASK 0xFFFFFFFE +#define PUFCC_DATA_ECDSA_EC_A_OFFSET \ + (PUFCC_DATA_ECDSA_PRIME_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_EC_B_OFFSET \ + (PUFCC_DATA_ECDSA_EC_A_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_PX_OFFSET \ + (PUFCC_DATA_ECDSA_EC_B_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_PY_OFFSET \ + (PUFCC_DATA_ECDSA_PX_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_ORDER_OFFSET \ + (PUFCC_DATA_ECDSA_PY_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_HASH_OFFSET \ + (PUFCC_DATA_ECDSA_ORDER_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_PUBX_OFFSET \ + (PUFCC_DATA_ECDSA_HASH_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_PUBY_OFFSET \ + (PUFCC_DATA_ECDSA_PUBX_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_SIG_R_OFFSET \ + (PUFCC_DATA_ECDSA_PUBY_OFFSET + PUFCC_ECDSA_256_LEN) + +#define PUFCC_DATA_ECDSA_SIG_S_OFFSET \ + (PUFCC_DATA_ECDSA_SIG_R_OFFSET + PUFCC_ECDSA_256_LEN) + +// PUFcc status codes +enum pufcc_status { + PUFCC_SUCCESS, // Success. + PUFCC_E_ALIGN, // Address alignment mismatch. + PUFCC_E_OVERFLOW, // Space overflow. + PUFCC_E_UNDERFLOW, // Size too small. + PUFCC_E_INVALID, // Invalid argument. + PUFCC_E_BUSY, // Resource is occupied. + PUFCC_E_UNAVAIL, // Resource is unavailable. + PUFCC_E_FIRMWARE, // Firmware error. + PUFCC_E_VERFAIL, // Invalid public key or digital signature. + PUFCC_E_ECMPROG, // Invalid ECC microprogram. + PUFCC_E_DENY, // Access denied. + PUFCC_E_UNSUPPORT, // Not support. + PUFCC_E_INFINITY, // Point at infinity. + PUFCC_E_ERROR, // Unspecific error. + PUFCC_E_TIMEOUT, // Operation timed out. +}; + +// PUFcc key slots; 32 slots of 256 bits each +enum pufcc_otp_slot { + PUFCC_OTPKEY_0, // OTP key slot 0, 256 bits + PUFCC_OTPKEY_1, // OTP key slot 1, 256 bits + PUFCC_OTPKEY_2, // OTP key slot 2, 256 bits + PUFCC_OTPKEY_3, // OTP key slot 3, 256 bits + PUFCC_OTPKEY_4, // OTP key slot 4, 256 bits + PUFCC_OTPKEY_5, // OTP key slot 5, 256 bits + PUFCC_OTPKEY_6, // OTP key slot 6, 256 bits + PUFCC_OTPKEY_7, // OTP key slot 7, 256 bits + PUFCC_OTPKEY_8, // OTP key slot 8, 256 bits + PUFCC_OTPKEY_9, // OTP key slot 9, 256 bits + PUFCC_OTPKEY_10, // OTP key slot 10, 256 bits + PUFCC_OTPKEY_11, // OTP key slot 11, 256 bits + PUFCC_OTPKEY_12, // OTP key slot 12, 256 bits + PUFCC_OTPKEY_13, // OTP key slot 13, 256 bits + PUFCC_OTPKEY_14, // OTP key slot 14, 256 bits + PUFCC_OTPKEY_15, // OTP key slot 15, 256 bits + PUFCC_OTPKEY_16, // OTP key slot 16, 256 bits + PUFCC_OTPKEY_17, // OTP key slot 17, 256 bits + PUFCC_OTPKEY_18, // OTP key slot 18, 256 bits + PUFCC_OTPKEY_19, // OTP key slot 19, 256 bits + PUFCC_OTPKEY_20, // OTP key slot 20, 256 bits + PUFCC_OTPKEY_21, // OTP key slot 21, 256 bits + PUFCC_OTPKEY_22, // OTP key slot 22, 256 bits + PUFCC_OTPKEY_23, // OTP key slot 23, 256 bits + PUFCC_OTPKEY_24, // OTP key slot 24, 256 bits + PUFCC_OTPKEY_25, // OTP key slot 25, 256 bits + PUFCC_OTPKEY_26, // OTP key slot 26, 256 bits + PUFCC_OTPKEY_27, // OTP key slot 27, 256 bits + PUFCC_OTPKEY_28, // OTP key slot 28, 256 bits + PUFCC_OTPKEY_29, // OTP key slot 29, 256 bits + PUFCC_OTPKEY_30, // OTP key slot 30, 256 bits + PUFCC_OTPKEY_31, // OTP key slot 31, 256 bits +}; + +// OTP lock types +enum pufcc_otp_lock { + PUFCC_OTP_NA = 0xF, // No-Access + PUFCC_OTP_RO = 0x3, // Read-Only + PUFCC_OTP_RW = 0x0, // Read-Write +}; + +// PUFcc read/write types +enum pufcc_dma_rw_type { AUTO_INCREMENT, FIXED_RW }; + +// PUFcc key types +enum pufcc_key_type { PUFCC_SW_KEY, PUFCC_OTP_KEY }; + +// PUFcc SP38a variants +enum pufcc_sp38a_variant { + PUFCC_AES128, + PUFCC_AES192, + PUFCC_AES256, + PUFCC_SM4 +}; + +// PUFcc PKC schemes +enum pufcc_pkc_scheme { PUFCC_RSA_2048 = 0x86, PUFCC_ECDSA256 = 0x82 }; + +// PUFcc SP38a modes +enum pufcc_sp38a_mode { + PUFCC_ECB_CLR, + PUFCC_CFB, + PUFCC_OFB, + PUFCC_CBC_CLR, + PUFCC_CBC_CTS1, + PUFCC_CBC_CTS2, + PUFCC_CBC_CTS3, + PUFCC_CTR32, + PUFCC_CTR64, + PUFCC_CTR128 +}; + +// Scatter gather DMA descriptor struct +struct pufcc_sg_dma_desc { + uint32_t read_addr; + uint32_t write_addr; + uint32_t length; + uint32_t next; + uint32_t dsc_cfg_4; + uint32_t key_cfg; + uint32_t cypt_cfg[2]; +}; + +/***************************************************************************** + * Register structures + ****************************************************************************/ +// General register structs +struct pufcc_intrpt_reg { + uint32_t intrpt_st : 1; + uint32_t reserved1 : 15; + uint32_t intrpt_en : 1; + uint32_t reserved2 : 15; +}; + +struct pufcc_start_reg { + uint32_t start_p : 1; + uint32_t reserved : 31; +}; + +// DMA register structs +struct pufcc_dma_cfg_0_reg { + uint32_t rng_en : 1; + uint32_t sg_en : 1; + uint32_t reserved : 30; +}; + +struct pufcc_dma_cfg_1_reg { + uint8_t rbst_max; + uint8_t wbst_max; + uint8_t rbst_min; + uint8_t wbst_min; +}; + +struct pufcc_dma_dsc_cfg_4_reg { + uint32_t wprot : 8; + uint32_t rprot : 8; + uint32_t fw : 1; + uint32_t fr : 1; + uint32_t reserved : 5; + uint32_t no_cypt : 1; + uint32_t offset : 4; + uint32_t dn_pause : 1; + uint32_t dn_intrpt : 1; + uint32_t tail : 1; + uint32_t head : 1; +}; + +struct pufcc_dma_key_cfg0_reg { + uint32_t key_src : 4; + uint32_t key_dst : 4; + uint32_t key_size : 11; + uint32_t reserved1 : 5; + uint32_t key_idx : 5; + uint32_t reserved2 : 3; +}; + +// HMAC register structs +struct pufcc_hmac_config_reg { + uint32_t variant : 4; + uint32_t reserved : 4; + uint32_t function : 1; + uint32_t reserved2 : 23; +}; + +// PUFcc SP38a register structs +struct pufcc_sp38a_config_reg { + uint32_t variant : 2; + uint32_t reserved1 : 2; + uint32_t mode : 4; + uint32_t enc_dec : 1; + uint32_t reserved2 : 23; +}; + +// PKC register register structs +struct pufcc_pkc_ecp_ec_reg { + uint32_t reserved1 : 8; + uint32_t field : 8; // PKC scheme + uint32_t h : 4; // EC cofactor h + uint32_t reserved2 : 12; +}; + +// ECC parameters structure +struct pufcc_ecc_param { + const void *prime; // Field modulus + const void *a; // EC parameter a + const void *b; // EC parameter b + const void *px; // x-coordinate of base point P + const void *py; // y-coordinate of base point P + const void *order; // Subgroup order +}; + +/***************************************************************************** + * PUFcc register maps + ****************************************************************************/ +// OTP memory map +struct pufcc_otp_mem { + uint32_t otp[256]; +}; + +struct pufcc_rt_regs { + volatile uint32_t pif[64]; + uint32_t _pad1[64]; + volatile uint32_t ptr[16]; + volatile uint32_t ptc[16]; + volatile uint32_t ptm[2]; + uint32_t _pad2[6]; + volatile uint32_t rn; + volatile uint32_t rn_status; + volatile uint32_t healthcfg; + volatile uint32_t feature; + volatile uint32_t interrupt; + volatile uint32_t otp_psmsk[2]; + volatile uint32_t puf_psmsk; + volatile uint32_t version; + volatile uint32_t status; + volatile uint32_t cfg; + volatile uint32_t set_pin; + volatile uint32_t auto_repair; + volatile uint32_t ini_off_chk; + volatile uint32_t repair_pgn; + volatile uint32_t repair_reg; + volatile uint32_t puf_qty_chk; + volatile uint32_t puf_enroll; + volatile uint32_t puf_zeroize; + volatile uint32_t set_flag; + volatile uint32_t otp_zeroize; + uint32_t _pad3[3]; + volatile uint32_t puf[64]; + volatile uint32_t otp[256]; +}; + +// DMA module register map +struct pufcc_dma_regs { + volatile uint32_t version; + volatile uint32_t interrupt; + volatile uint32_t feature; + uint32_t _pad1; + volatile uint32_t status_0; + volatile uint32_t status_1; + uint32_t _pad2[2]; + volatile uint32_t start; + volatile uint32_t cfg_0; + volatile uint32_t cfg_1; + uint32_t _pad3[2]; + volatile uint32_t dsc_cfg_0; + volatile uint32_t dsc_cfg_1; + volatile uint32_t dsc_cfg_2; + volatile uint32_t dsc_cfg_3; + volatile uint32_t dsc_cfg_4; + uint32_t _pad4[2]; + volatile uint32_t dsc_cur_0; + volatile uint32_t dsc_cur_1; + volatile uint32_t dsc_cur_2; + volatile uint32_t dsc_cur_3; + volatile uint32_t dsc_cur_4; + uint32_t _pad5[2]; + volatile uint32_t key_cfg_0; + volatile uint32_t cl_cfg_0; +}; + +// HMAC module register map +struct pufcc_hmac_regs { + volatile uint32_t version; + volatile uint32_t interrupt; + volatile uint32_t feature; + uint32_t _pad1; + volatile uint32_t status; + uint32_t _pad2; + volatile uint32_t cfg; + uint32_t _pad3; + volatile uint32_t plen; + uint32_t _pad4[3]; + volatile uint32_t alen; + uint32_t _pad5[3]; + volatile uint8_t sw_key[PUFCC_HMAC_SW_KEY_MAXLEN]; +}; + +// Crypto module register map +struct pufcc_crypto_regs { + volatile uint32_t version; + volatile uint32_t interrupt; + volatile uint32_t feature; + uint32_t _pad1[5]; + volatile uint32_t iv_out[PUFCC_CRYPTO_IV_MAXLEN / PUFCC_WORD_SIZE]; + volatile uint32_t iv[PUFCC_CRYPTO_IV_MAXLEN / PUFCC_WORD_SIZE]; + volatile uint32_t sw_key[PUFCC_CRYPTO_SW_KEY_MAXLEN / PUFCC_WORD_SIZE]; + volatile uint32_t dgst_in[PUFCC_CRYPTO_DGST_LEN / PUFCC_WORD_SIZE]; + volatile uint32_t dgst_out[PUFCC_CRYPTO_DGST_LEN / PUFCC_WORD_SIZE]; +}; + +// SP38a module register map +struct pufcc_sp38a_regs { + volatile uint32_t version; + volatile uint32_t interrupt; + volatile uint32_t feature; + uint32_t _pad1; + volatile uint32_t status; + uint32_t _pad2; + volatile uint32_t cfg; +}; + +// PKC module register map +struct pufcc_pkc_regs { + volatile uint32_t version; + volatile uint32_t interrupt; + volatile uint32_t start; + volatile uint32_t status; + volatile uint32_t ecp_err_code; + volatile uint32_t ecp_err_pc; + volatile uint32_t ecp_err_cmd; + volatile uint32_t mp_version; + uint32_t _pad1[56]; + volatile uint32_t ecp_ec; + volatile uint32_t ecp_keysel; + volatile uint32_t ecp_otpkba; + volatile uint32_t ecp_key_usage; + volatile uint32_t ecp_e_short; + uint32_t _pad2[55]; + volatile uint32_t ecp_mac[4]; + volatile uint32_t ecp_data[512]; +}; + +#ifndef RS_RTOS_PORT + struct pufcc_dma_dev { + struct pufcc_dma_regs *regs; + bool is_dev_free; + struct pufcc_sg_dma_desc *dma_descs; + uint32_t num_descriptors; + void *callback_args; + rs_dma_callback_t callback; + }; +#endif + +#ifdef RS_RTOS_PORT + + /** + * @enum rs_crypto_tfr_type + * @brief Types of secure transfer type in case of peripherals + */ + enum rs_crypto_tfr_type { + RS_SECURE_TX, // Write to peripheral + RS_SECURE_RX // Read from peripheral + }; + + /** + * @struct rs_crypto_addr + * @brief Address info for cryptographic operations + */ + struct rs_crypto_addr { + uint32_t read_addr; + uint32_t write_addr; + uint32_t len; + enum rs_crypto_tfr_type tfr_type; // Transfer type (read or write) in case of + // peripherals, otherwise don't care + bool periph_rw; // Indicates if data transfer involves a peripheral + struct rs_crypto_addr *next; // In case data lies at multiple locations + }; + + /* + The following macro can be used to write register values. + REG_WRITE_32(Destination_Addr, Source_Addr) + */ + #define REG_WRITE_32(Destination_Addr, Source_Addr) \ + *(uint32_t *)Destination_Addr = *(uint32_t *)Source_Addr; + + /** + * @brief SHA lengths + */ + #define RS_SHA_MAX_LEN 64 + #define RS_SHA256_LEN 32 + + /** + * @brief ECDSA256 quadrant and key lengths + */ + #define RS_EC256_QLEN 32 + #define RS_EC256_KEY_LEN (32 * 2) + + /** + * @brief RSA 2048 public key modulus length + * + */ + #define RS_RSA_2048_LEN 256 + + /** + * @brief RSA 2048 public key exponent length + */ + #define RS_RSA_E_LEN 4 + + /** + * @brief RSA 2048 public key length + */ + #define RS_RSA_2048_KEY_LEN (RS_RSA_2048_LEN + RS_RSA_E_LEN) + + /** + * @brief IV length for AES-CTR128 + */ + #define RS_AES_CTR128_IV_EN 16 + + /** + * @brief Key length for AES128 + */ + #define RS_AES16_KEY_LEN 16 + + /** + * @brief Key length for AES256 + */ + #define RS_AES32_KEY_LEN 32 + + enum rs_status { + OK = 0, + WOULD_BLOCK = 1, + ERROR = 2 + }; + + /** + * @struct rs_crypto_rsa2048_puk + * @brief RSA 2048 public key structure + */ + struct rs_crypto_rsa2048_puk { + uint8_t n[RS_RSA_2048_LEN]; // Modulus + uint32_t e; // Exponent + }; + + /** + * @struct rs_crypto_ec256_puk + * @brief ECDSA256 public key + */ + struct rs_crypto_ec256_puk { + uint8_t x[RS_EC256_QLEN]; + uint8_t y[RS_EC256_QLEN]; + }; + + /** + * @struct rs_crypto_ec256_sig + * @brief ECDSA256 signature + */ + struct rs_crypto_ec256_sig { + uint8_t r[RS_EC256_QLEN]; + uint8_t s[RS_EC256_QLEN]; + }; + + /** + * @struct rs_crypto_hash + * @brief Hash structure + */ + struct rs_crypto_hash { + uint8_t val[RS_SHA_MAX_LEN]; + uint32_t len; + }; + +#endif + +/***************************************************************************** + * API declarations + ****************************************************************************/ +enum pufcc_status pufcc_calc_sha256_hash(struct rs_crypto_addr *data_addr, + struct rs_crypto_hash *hash); + +enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, + bool first, bool last, + uint32_t *prev_len, + struct rs_crypto_hash *hash_in, + struct rs_crypto_hash *hash_out); + +enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, + uint32_t in_len, uint32_t prev_len, + enum pufcc_key_type key_type, + uint32_t key_addr, uint32_t key_len, + uint32_t iv_addr, uint32_t iv_len, + enum pufcc_dma_rw_type write_type, + bool readback_iv); + +enum pufcc_status pufcc_rsa2048_sign_verify( + uint8_t *sig, struct rs_crypto_addr *msg_addr, + struct rs_crypto_rsa2048_puk *pub_key); + +enum pufcc_status pufcc_ecdsa256_sign_verify( + struct rs_crypto_ec256_sig *sig, struct rs_crypto_addr *msg_addr, + struct rs_crypto_ec256_puk *pub_key); + +#ifndef RS_RTOS_PORT + enum pufcc_status pufcc_dma_transfer(uint32_t src_addr, uint32_t dest_addr, + uint32_t len, bool fixed_read, + bool fixed_write); +#endif + +enum pufcc_status pufcc_otp_setup_wait(void); + +enum pufcc_status pufcc_program_otp(const uint8_t *in_buf, uint32_t len, + enum pufcc_otp_slot otp_slot); + +enum pufcc_status pufcc_read_otp(uint8_t *out_buf, uint32_t len, + enum pufcc_otp_slot otp_slot); + +enum pufcc_status pufcc_lock_otp(enum pufcc_otp_slot otp_slot, uint32_t len, + enum pufcc_otp_lock lock); + +enum pufcc_status pufcc_zeroize_otp(enum pufcc_otp_slot otp_slot); + +enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, + enum pufcc_otp_lock *lock_val); + +#ifndef RS_RTOS_PORT + int pufcc_dma_request_channel(struct pufcc_dma_dev *dev); + + void pufcc_dma_release_channel(struct pufcc_dma_dev *dev, int channel); + + enum rs_status pufcc_dma_config_descriptor_memory(struct pufcc_dma_dev *dev, + int channel, uintptr_t addr, + size_t max_descriptors); + + enum rs_status pufcc_dma_config_xfer(struct pufcc_dma_dev *dev, int channel, + struct rs_dma_config *config); + + enum rs_status pufcc_dma_start_xfer(struct pufcc_dma_dev *dev, int channel); + + enum rs_status pufcc_dma_stop_xfer(struct pufcc_dma_dev *dev, int channel); + + void pufcc_dma_irq_handler(struct pufcc_dma_dev *dev); +#else + + int pufcc_clear_and_disable_intr(void); + +#endif + +enum pufcc_status pufcc_init(uint32_t base_addr); + +#endif // _PUFCC_H_ diff --git a/include/zephyr/crypto/hash.h b/include/zephyr/crypto/hash.h index 4beab045564f3..50f6ef07e1069 100644 --- a/include/zephyr/crypto/hash.h +++ b/include/zephyr/crypto/hash.h @@ -91,14 +91,14 @@ struct hash_pkt { /** Start address of input buffer */ uint8_t *in_buf; + /** Bytes to be operated upon */ + size_t in_len; + /** Start address of previously calculated hash / digest. * It is useful where hash is calculated in chunks. */ uint8_t *in_hash; - - /** Bytes to be operated upon */ - size_t in_len; - + /** Bytes previously operated upon */ uint32_t *prev_len; From cc9f079350ad0ddadc9e14b27799e605cc1b2980 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 27 Sep 2024 22:16:45 +0500 Subject: [PATCH 23/58] isolated pufcc and crypto_pufs source files --- drivers/crypto/crypto_pufs.c | 150 +++++++++++++++++++++++++++++------ drivers/crypto/crypto_pufs.h | 4 + drivers/crypto/pufcc.c | 16 ++-- include/zephyr/crypto/sign.h | 14 +++- 4 files changed, 152 insertions(+), 32 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index f4bfa261b3e45..5195355bd4b0e 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -32,10 +32,42 @@ static char *session_to_str(enum pufs_session_type inSession) { ((inSession == PUFS_SESSION_SIGN_VERIFICATION)?"Sign_Verification":"Unknown"))); } +uint8_t __pufcc_descriptors[BUFFER_SIZE]; + +static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data_addr) { + uint8_t desc_count = 0; + + if((pkt == NULL) || (data_addr == NULL)) { + LOG_ERR("%s(%d) NULL pointer(s)\n", __func__, __LINE__); + return -EBADFD; + } + + // Set SGDMA descriptors + do { + data_addr->read_addr = (uint32_t)pkt->in_buf; + data_addr->len = pkt->in_len; + desc_count++; + if((desc_count * sizeof(struct pufcc_sg_dma_desc)) < BUFFER_SIZE){ + data_addr->next = data_addr+1; + } else { + break; + } + } while (pkt); + + if (pkt) { + // No enough descriptors available + LOG_ERR("%s(%d) Not More Than %d Elements Allowed. Desc_Count:%d\n", \ + __func__, __LINE__, (BUFFER_SIZE/sizeof(struct pufcc_sg_dma_desc)), desc_count); + return -ENOTEMPTY; + } + + return PUFCC_SUCCESS; +} + static int crypto_pufs_init(const struct device *dev) { // Initialize base addresses of different PUFcc modules - enum pufcc_status lvStatus = pufcc_init((struct pufcc_dma_regs *)((struct pufs_config*)dev->config)->base); + enum pufcc_status lvStatus = pufcc_init(((struct pufs_config*)dev->config)->base); if(lvStatus == PUFCC_SUCCESS) { // Connect the IRQ @@ -125,7 +157,7 @@ static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t * ); if(lvStatus != PUFCC_SUCCESS) { - LOG_ERR("%s(%d) PUFcc Error Code:%d\n", lvStatus); + LOG_ERR("%s(%d) PUFcc Error Code:%d\n", __func__, __LINE__, lvStatus); return -ECANCELED; } @@ -273,39 +305,54 @@ static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) ((struct pufs_data*)ctx->device->data)->pufs_ctx.hash_ctx = ctx; if(!ctx->started) { // started flag indicates if chunkwise hash calculation was started + struct rs_crypto_addr data_addr = { - .read_addr = pkt->in_buf, - .write_addr = pkt->out_buf, + .read_addr = (uint32_t)pkt->in_buf, + .write_addr = (uint32_t)pkt->out_buf, .len = pkt->in_len }; - struct rs_crypto_hash hash_out = { - .val = pkt->out_buf, - .len = pkt->out_len - }; + + struct rs_crypto_hash hash_out = {0}; + lvStatus = pufcc_calc_sha256_hash(&data_addr, &hash_out); + + /* Copy output hash values calculated by PUFcc */ + memcpy((void*)pkt->out_buf, (void*)hash_out.val, hash_out.len); + pkt->out_len = hash_out.len; + } else { - struct rs_crypto_addr data_addr = { - .read_addr = pkt->in_buf, - .write_addr = pkt->out_buf, - .len = pkt->in_len, - . - }; - struct rs_crypto_hash hash_in = { - .val = pkt->out_buf, - .len = pkt->out_len - }; - struct rs_crypto_hash hash_out = { - .val = pkt->out_buf, - .len = pkt->out_len - }; + + struct rs_crypto_addr lvHash_Data_Addr[BUFFER_SIZE]; + + if(fill_rs_crypto_addr(pkt, lvHash_Data_Addr) != PUFCC_SUCCESS) { + return -ENOTEMPTY; + } + + struct rs_crypto_hash hash_in = {0}; + + hash_in.len = pkt->in_len; + /* Copy input hash values for operating upon */ + memcpy((void*)hash_in.val, (void*)pkt->in_buf, hash_in.len); + + struct rs_crypto_hash hash_out = {0}; + lvStatus = pufcc_calc_sha256_hash_sg( - &data_addr, + lvHash_Data_Addr, pkt->head, pkt->tail, pkt->prev_len, &hash_in, &hash_out ); + + /* Copy output hash values calculated by PUFcc */ + memcpy((void*)pkt->out_buf, (void*)hash_out.val, (size_t)hash_out.len); + pkt->out_len = hash_out.len; + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) PUFs Error Code:%d\n", __func__, __LINE__, lvStatus); + return -ECANCELED; + } } if(lvStatus != PUFCC_SUCCESS) { @@ -393,6 +440,59 @@ static int pufs_hash_async_callback_set(const struct device *dev, hash_completio return PUFCC_SUCCESS; } +int pufs_sign_rsa_op(struct sign_ctx *ctx, struct sign_pkt *pkt) +{ + enum pufcc_status lvStatus = PUFCC_SUCCESS; + + ((struct pufs_data*)ctx->device->data)->pufs_pkt.sign_pkt = pkt; + ((struct pufs_data*)ctx->device->data)->pufs_ctx.sign_ctx = ctx; + + struct rs_crypto_addr msg_addr = { + .read_addr = (uint32_t)pkt->in_buf, + .len = pkt->in_len + }; + + lvStatus = pufcc_rsa2048_sign_verify( + (uint8_t *)ctx->sig, + &msg_addr, + (struct rs_crypto_rsa2048_puk *)ctx->pub_key + ); + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) PUFs Error Code:%d\n", __func__, __LINE__, lvStatus); + return -ECANCELED; + } + + return PUFCC_SUCCESS; +} + +int pufs_sign_ecdsa_op(struct sign_ctx *ctx, struct sign_pkt *pkt) +{ + enum pufcc_status lvStatus = PUFCC_SUCCESS; + + ((struct pufs_data*)ctx->device->data)->pufs_pkt.sign_pkt = pkt; + ((struct pufs_data*)ctx->device->data)->pufs_ctx.sign_ctx = ctx; + + struct rs_crypto_addr msg_addr = { + .read_addr = (uint32_t)pkt->in_buf, + .len = pkt->in_len, + .next = NULL + }; + + lvStatus = pufcc_ecdsa256_sign_verify( + (struct rs_crypto_ec256_sig *)ctx->sig, + &msg_addr, + (struct rs_crypto_ec256_puk *)ctx->pub_key + ); + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) PUFs Error Code:%d\n", __func__, __LINE__, lvStatus); + return -ECANCELED; + } + + return PUFCC_SUCCESS; +} + /* Setup a signature session */ static int pufs_sign_begin_session(const struct device *dev, struct sign_ctx *ctx, enum sign_algo algo) @@ -411,10 +511,10 @@ static int pufs_sign_begin_session(const struct device *dev, struct sign_ctx *ct } else { if(algo == CRYPTO_SIGN_ALGO_ECDSA256) { ctx->ops.signing_algo = CRYPTO_SIGN_ALGO_ECDSA256; - ctx->ops.ecdsa_crypt_hndlr = pufcc_ecdsa256_sign_verify; + ctx->ops.ecdsa_crypt_hndlr = pufs_sign_ecdsa_op; } else { ctx->ops.signing_algo = CRYPTO_SIGN_ALGO_RSA2048; - ctx->ops.rsa_crypt_hndlr = pufcc_rsa2048_sign_verify; + ctx->ops.rsa_crypt_hndlr = pufs_sign_rsa_op; } } diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index 09746214c07b4..63cd58de74bb4 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -11,6 +11,10 @@ #include "pufcc.h" #include +#define BUFFER_SIZE 512 + +extern uint8_t __pufcc_descriptors[BUFFER_SIZE]; + enum pufs_session_type { PUFS_SESSION_SIGN_VERIFICATION = 0, PUFS_SESSION_HASH_CALCULATION, diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 46e3d8dde5647..ad99146f7e72f 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -9,13 +9,16 @@ #else #include #include + #include "crypto_pufs.h" #endif /***************************************************************************** * Macros ****************************************************************************/ #define SG_DMA_MAX_DSCS_SIZE (512 - 8) // Enough for 15 descriptors -#define BUFFER_SIZE 512 +#ifndef RS_RTOS_PORT + #define BUFFER_SIZE 512 +#endif #define PUFCC_MAX_BUSY_COUNT 8000000 // Max busy count for processing 10MB data #define CTR_MODE_BLOCK_SIZE 16 @@ -23,12 +26,15 @@ * Local variable declarations ****************************************************************************/ #ifndef RS_RTOS_PORT -extern uint32_t __pufcc_descriptors; + extern uint32_t __pufcc_descriptors; + static struct pufcc_sg_dma_desc *sg_dma_descs = + (struct pufcc_sg_dma_desc *)&__pufcc_descriptors; #else - uint32_t __pufcc_descriptors[BUFFER_SIZE]; + static struct pufcc_sg_dma_desc *sg_dma_descs = + (struct pufcc_sg_dma_desc *)__pufcc_descriptors; #endif -static struct pufcc_sg_dma_desc *sg_dma_descs = - (struct pufcc_sg_dma_desc *)&__pufcc_descriptors; + + static uint8_t pufcc_buffer[BUFFER_SIZE]; // PUFcc microprogram for RSA2048 diff --git a/include/zephyr/crypto/sign.h b/include/zephyr/crypto/sign.h index f2c784da5525f..0d13b8a351f43 100644 --- a/include/zephyr/crypto/sign.h +++ b/include/zephyr/crypto/sign.h @@ -76,10 +76,20 @@ struct sign_ctx { */ struct sign_ops ops; - /** To be populated by the app before calling begin_session() */ + /** + * To be populated by the app before calling begin_session() + * In case of ecdsa, the public key should have {x, y} + * coordinates respectively. In case of RSA2048, the public key + * should have the modulus and exponent {n, e} respectively. + * */ const uint8_t *pub_key; - /** To be populated by the app before calling begin_session() */ + /** + * To be populated by the app before calling begin_session() + * In case of ecdsa, the signature should be constituted of two + * integer arrays of {r, s} respectively. In case of RSA2048 the signature + * is a normal array of integer values. + */ const uint8_t *sig; /** The device driver instance this crypto context relates to. Will be From 53dafad426c1a574b48e21754a1c702dc1682df8 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Sun, 29 Sep 2024 21:58:03 +0500 Subject: [PATCH 24/58] Crypto OTP Mem API in progress --- include/zephyr/crypto/cipher.h | 1 + include/zephyr/crypto/crypto.h | 1 + include/zephyr/crypto/crypto_otp_mem.h | 172 +++++++++++++++++++++++++ include/zephyr/crypto/hash.h | 1 + include/zephyr/crypto/sign.h | 2 +- 5 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 include/zephyr/crypto/crypto_otp_mem.h diff --git a/include/zephyr/crypto/cipher.h b/include/zephyr/crypto/cipher.h index 1e898b9df90c6..cc967bde51836 100644 --- a/include/zephyr/crypto/cipher.h +++ b/include/zephyr/crypto/cipher.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016 Intel Corporation. + * 2024 Rapid Silicon. * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/zephyr/crypto/crypto.h b/include/zephyr/crypto/crypto.h index 2ab5f4438dc43..d5bf33e5e8e7b 100644 --- a/include/zephyr/crypto/crypto.h +++ b/include/zephyr/crypto/crypto.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2016 Intel Corporation. + * 2024 Rapid Silicon. * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/zephyr/crypto/crypto_otp_mem.h b/include/zephyr/crypto/crypto_otp_mem.h new file mode 100644 index 0000000000000..b87e82cb92201 --- /dev/null +++ b/include/zephyr/crypto/crypto_otp_mem.h @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2024 Rapid Silicon. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Crypto Engine's OTP (One Time Programmable) Memory APIs. + * + * + * This file contains the Crypto Engine's OTP memory APIs + * for reading, writing, zeroizing and locking the OTP + * memory contents. + * + * [Experimental] Users should note that the APIs can change + * as a part of ongoing development. + */ + +#ifndef ZEPHYR_INCLUDE_CRYPTO_OTP_MEM_H_ +#define ZEPHYR_INCLUDE_CRYPTO_OTP_MEM_H_ + +#include +#include +#include +#include +#include + +/** + * @brief Crypto OTP Mem APIs + * @defgroup crypto OTP Mem + * @since 1.7 + * @version 1.0.0 + * @ingroup os_services + * @{ + */ + +/* ctx.flags values. Not all drivers support all flags. + * A user app can query the supported hw / driver + * capabilities via provided API (crypto_query_hwcaps()), and choose a + * supported config during the session setup. + */ +#define CAP_READ_OTP BIT(0) +#define CAP_WRITE_OTP BIT(1) + +#define CAP_LOCK_OTP BIT(2) + +/** Whether to permanently zeroiz the OTP */ +#define CAP_ZEROIZ_OTP BIT(3) + +/** + * These denotes if the output is conveyed + * by the op function returning, or it is conveyed by an async notification + */ +#define CAP_SYNC_OPS BIT(5) +#define CAP_ASYNC_OPS BIT(6) + +/* More flags to be added as necessary */ + +// OTP lock types +enum crypto_otp_lock { + CRYPTO_OTP_RW = 0x0, // Read-Write + CRYPTO_OTP_RO = 0x3, // Read-Only + CRYPTO_OTP_NA = 0xF, // No-Access +}; + +/** @brief Crypto OTP Memory driver API definition. */ +__subsystem struct otp_driver_api { + /* Get the driver capability flags for OTP Memory operations */ + int (*query_hw_caps)(const struct device *dev); + + /** + * otp_info API returns the total number of slots + * and number of bytes per slot. + */ + int (*otp_info)( + const struct device *dev, + uint16_t *totalSlots, + uint16_t *bytesPerSlot + ); + + /** + * otp_read API returns the number of bytes + * from the selected OTP Slot. Use otp_info + * to get total number of slots and bytes per slot. + */ + int (*otp_read)( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ); + + /** + * otp_write API writes the number of bytes + * to the selected OTP Slot. Use otp_info + * to get total number of slots and bytes per slot. + */ + int (*otp_write)( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ); + + /** + * otp_zeroize API zeroize the selected OTP Slot + * Permanently. Use otp_info to get total number + * of slots and bytes per slot. + */ + int (*otp_zeroize)( + const struct device *dev, + uint16_t otp_slot + ); + + /** + * otp_lock API locks the selected OTP slot as per + * the crypto_otp_lock. Use otp_info to get total + * number of slots and bytes per slot. + */ + int (*otp_lock)( + const struct device *dev, + uint16_t otp_slot, + enum crypto_otp_lock lock + ); + + /** + * otp_get_rwlck API gets the selected OTP Slots's + * lock status. + */ + int (*otp_get_rwlck)( + const struct device *dev, + uint16_t otp_slot, + enum crypto_otp_lock *lock + ); +}; + +/* Following are the public API a user app may call. */ + +/** + * @brief Query the crypto otp driver capabilities + * + * This API is used by the app to query the capabilities supported by the + * crypto otp memory driver. Based on this the app can specify a subset of + * the supported options to be honored for a session during cipher_begin_session(). + * + * @param dev Pointer to the device structure for the driver instance. + * + * @return bitmask of supported options. + */ +__syscall int crypto_query_hwcaps(const struct device *dev); + +static inline int z_impl_crypto_query_hwcaps(const struct device *dev) +{ + struct otp_driver_api *api; + int tmp; + + api = (struct otp_driver_api *) dev->api; + + tmp = api->query_hw_caps(dev); + + __ASSERT((tmp & (CAP_READ_OTP | CAP_WRITE_OTP)) != 0, + "Driver should support at least Read or Write to the OTP Memory"); + + __ASSERT((tmp & (CAP_SYNC_OPS | CAP_ASYNC_OPS)) != 0, + "Driver should support at least Synch or Asynch operation"); + + return tmp; + +} + +#endif /* ZEPHYR_INCLUDE_CRYPTO_OTP_MEM_H_ */ diff --git a/include/zephyr/crypto/hash.h b/include/zephyr/crypto/hash.h index 50f6ef07e1069..f86d44e68aa9d 100644 --- a/include/zephyr/crypto/hash.h +++ b/include/zephyr/crypto/hash.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2022 Intel Corporation. + * 2024 Rapid Silicon. * * SPDX-License-Identifier: Apache-2.0 */ diff --git a/include/zephyr/crypto/sign.h b/include/zephyr/crypto/sign.h index 0d13b8a351f43..99e4aa083c243 100644 --- a/include/zephyr/crypto/sign.h +++ b/include/zephyr/crypto/sign.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024 Rapid Silicon + * Copyright (c) 2024 Rapid Silicon. * * SPDX-License-Identifier: Apache-2.0 */ From 82f418436260c0d812c85d57f68dd6b775b4bc9c Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 30 Sep 2024 12:55:52 +0500 Subject: [PATCH 25/58] Crypto OTP Mem API in progress --- include/zephyr/crypto/crypto_otp_mem.h | 181 +++++++++++++++++++++++-- 1 file changed, 169 insertions(+), 12 deletions(-) diff --git a/include/zephyr/crypto/crypto_otp_mem.h b/include/zephyr/crypto/crypto_otp_mem.h index b87e82cb92201..ddf2d74b9eb37 100644 --- a/include/zephyr/crypto/crypto_otp_mem.h +++ b/include/zephyr/crypto/crypto_otp_mem.h @@ -58,7 +58,7 @@ /* More flags to be added as necessary */ // OTP lock types -enum crypto_otp_lock { +enum crypto_otp_set_lock { CRYPTO_OTP_RW = 0x0, // Read-Write CRYPTO_OTP_RO = 0x3, // Read-Only CRYPTO_OTP_NA = 0xF, // No-Access @@ -67,7 +67,7 @@ enum crypto_otp_lock { /** @brief Crypto OTP Memory driver API definition. */ __subsystem struct otp_driver_api { /* Get the driver capability flags for OTP Memory operations */ - int (*query_hw_caps)(const struct device *dev); + int (*otp_hw_caps)(const struct device *dev); /** * otp_info API returns the total number of slots @@ -114,24 +114,24 @@ __subsystem struct otp_driver_api { ); /** - * otp_lock API locks the selected OTP slot as per - * the crypto_otp_lock. Use otp_info to get total + * otp_set_lock API locks the selected OTP slot as per + * the crypto_otp_set_lock. Use otp_info to get total * number of slots and bytes per slot. */ - int (*otp_lock)( + int (*otp_set_lock)( const struct device *dev, uint16_t otp_slot, - enum crypto_otp_lock lock + enum crypto_otp_set_lock lock ); /** - * otp_get_rwlck API gets the selected OTP Slots's + * otp_get_lock API gets the selected OTP Slots's * lock status. */ - int (*otp_get_rwlck)( + int (*otp_get_lock)( const struct device *dev, uint16_t otp_slot, - enum crypto_otp_lock *lock + enum crypto_otp_set_lock *lock ); }; @@ -148,16 +148,16 @@ __subsystem struct otp_driver_api { * * @return bitmask of supported options. */ -__syscall int crypto_query_hwcaps(const struct device *dev); +__syscall int otp_query_hwcaps(const struct device *dev); -static inline int z_impl_crypto_query_hwcaps(const struct device *dev) +static inline int z_impl_otp_query_hwcaps(const struct device *dev) { struct otp_driver_api *api; int tmp; api = (struct otp_driver_api *) dev->api; - tmp = api->query_hw_caps(dev); + tmp = api->otp_hw_caps(dev); __ASSERT((tmp & (CAP_READ_OTP | CAP_WRITE_OTP)) != 0, "Driver should support at least Read or Write to the OTP Memory"); @@ -169,4 +169,161 @@ static inline int z_impl_crypto_query_hwcaps(const struct device *dev) } +/** + * @brief Query the crypto otp information. + * + * This API is used by the app to query the otp memory information. + * It provides the total number of slots available in the otp and the + * number of bytes per slot. + * + * @param[in] dev Pointer to the device structure for the driver instance. + * @param[out] totalSlots total number of available otp slots. + * @param[out] bytesPerSlot number of bytes per slot. + * + * @return error code. + */ +__syscall int (*otp_info)( + const struct device *dev, + uint16_t *totalSlots, + uint16_t *bytesPerSlot + ); +static inline int z_impl_otp_info( + const struct device *dev, + uint16_t *totalSlots, + uint16_t *bytesPerSlot + ) +{ + +} + +/** + * @brief Read the crypto otp slot + * + * This API is used to read a certain number of bytes from an otp slot. + * + * @param dev Pointer to the device structure for the driver instance. + * @param[in] otp_slot the slot number of the otp to read from. + * @param[out] data The bytes returned. + * @param[in] len The number of bytes to read. + * + * @return error code. + */ +__syscall int (*otp_read)( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ); +static inline int z_impl_otp_read( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ) +{ + +} + +/** + * @brief Write to the crypto otp slot + * + * This API is used to write a certain number of bytes to an otp slot. + * + * @param dev Pointer to the device structure for the driver instance. + * @param[in] otp_slot the slot number of the otp to write to. + * @param[out] data The bytes written to the selected otp slot. + * @param[in] len The number of bytes to read. + * + * @return error code. + */ +__syscall int (*otp_write)( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ); +static inline int z_impl_otp_write( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ) +{ + +} + +/** + * @brief Zeroize the crypto otp slot + * + * This API is used to zeroize a an otp slot. + * + * @param dev Pointer to the device structure for the driver instance. + * @param[in] otp_slot the slot number to zeroize. + * + * @return error code. + */ +__syscall int (*otp_zeroize)( + const struct device *dev, + uint16_t otp_slot + ); +static inline int z_impl_otp_zeoirze( + const struct device *dev, + uint16_t otp_slot + ) +{ + +} + +/** + * @brief Set the crypto otp slot a particular lock value. The lock + * value can be referenced from crypto_otp_set_lock enumeration. + * + * This API is used to set a lock value to an otp slot. + * + * @param dev Pointer to the device structure for the driver instance. + * @param[in] otp_slot the slot number to lock. + * @param[in] lock The lock value to assign to an otp slot. + * + * @return error code. + */ +__syscall int (*otp_set_lock)( + const struct device *dev, + uint16_t otp_slot, + enum crypto_otp_set_lock lock + ); +static inline int z_impl_otp_set_lock( + const struct device *dev, + uint16_t otp_slot, + enum crypto_otp_set_lock lock + ) +{ + +} + +/** + * @brief Get the lock value of a particular crypto otp slot. The lock + * value can be referenced from crypto_otp_set_lock enumeration. + * + * This API is used to get a lock value of an otp slot. + * + * @param dev Pointer to the device structure for the driver instance. + * @param[in] otp_slot the slot number to lock. + * @param[out] lock The current lock value of an otp slot. + * + * @return error code. + */ +__syscall int (*otp_get_lock)( + const struct device *dev, + uint16_t otp_slot, + enum crypto_otp_set_lock *lock + ); +static inline int z_impl_otp_get_lock( + const struct device *dev, + uint16_t otp_slot, + enum crypto_otp_set_lock *lock + ) +{ + +} + #endif /* ZEPHYR_INCLUDE_CRYPTO_OTP_MEM_H_ */ From 126e0a4da8535d6632a3986f47b7e8ccb949c401 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 30 Sep 2024 15:15:03 +0500 Subject: [PATCH 26/58] Crypto OTP Mem API in progress --- include/zephyr/crypto/crypto_otp_mem.h | 92 ++++++++++++++++---------- 1 file changed, 58 insertions(+), 34 deletions(-) diff --git a/include/zephyr/crypto/crypto_otp_mem.h b/include/zephyr/crypto/crypto_otp_mem.h index ddf2d74b9eb37..7847a940f5f49 100644 --- a/include/zephyr/crypto/crypto_otp_mem.h +++ b/include/zephyr/crypto/crypto_otp_mem.h @@ -148,9 +148,9 @@ __subsystem struct otp_driver_api { * * @return bitmask of supported options. */ -__syscall int otp_query_hwcaps(const struct device *dev); +__syscall int otp_query_hw_caps(const struct device *dev); -static inline int z_impl_otp_query_hwcaps(const struct device *dev) +static inline int z_impl_otp_query_hw_aps(const struct device *dev) { struct otp_driver_api *api; int tmp; @@ -182,18 +182,22 @@ static inline int z_impl_otp_query_hwcaps(const struct device *dev) * * @return error code. */ -__syscall int (*otp_info)( - const struct device *dev, - uint16_t *totalSlots, - uint16_t *bytesPerSlot - ); +__syscall int otp_info( + const struct device *dev, + uint16_t *totalSlots, + uint16_t *bytesPerSlot + ); static inline int z_impl_otp_info( const struct device *dev, uint16_t *totalSlots, uint16_t *bytesPerSlot ) { + struct otp_driver_api *api; + + api = (struct otp_driver_api *) dev->api; + return api->otp_info(dev, totalSlots, bytesPerSlot); } /** @@ -208,12 +212,12 @@ static inline int z_impl_otp_info( * * @return error code. */ -__syscall int (*otp_read)( - const struct device *dev, - uint16_t otp_slot, - uint8_t *data, - uint32_t len - ); +__syscall int otp_read( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ); static inline int z_impl_otp_read( const struct device *dev, uint16_t otp_slot, @@ -221,7 +225,11 @@ static inline int z_impl_otp_read( uint32_t len ) { + struct otp_driver_api *api; + + api = (struct otp_driver_api *) dev->api; + return api->otp_read(dev, otp_slot, data, len); } /** @@ -236,12 +244,12 @@ static inline int z_impl_otp_read( * * @return error code. */ -__syscall int (*otp_write)( - const struct device *dev, - uint16_t otp_slot, - uint8_t *data, - uint32_t len - ); +__syscall int otp_write( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ); static inline int z_impl_otp_write( const struct device *dev, uint16_t otp_slot, @@ -249,7 +257,11 @@ static inline int z_impl_otp_write( uint32_t len ) { + struct otp_driver_api *api; + api = (struct otp_driver_api *) dev->api; + + return api->otp_write(dev, otp_slot, data, len); } /** @@ -262,16 +274,20 @@ static inline int z_impl_otp_write( * * @return error code. */ -__syscall int (*otp_zeroize)( - const struct device *dev, - uint16_t otp_slot - ); +__syscall int otp_zeroize( + const struct device *dev, + uint16_t otp_slot + ); static inline int z_impl_otp_zeoirze( const struct device *dev, uint16_t otp_slot ) { + struct otp_driver_api *api; + api = (struct otp_driver_api *) dev->api; + + return api->otp_zeroize(dev, otp_slot); } /** @@ -286,18 +302,22 @@ static inline int z_impl_otp_zeoirze( * * @return error code. */ -__syscall int (*otp_set_lock)( +__syscall int otp_set_lock( const struct device *dev, uint16_t otp_slot, enum crypto_otp_set_lock lock - ); + ); static inline int z_impl_otp_set_lock( - const struct device *dev, - uint16_t otp_slot, - enum crypto_otp_set_lock lock - ) + const struct device *dev, + uint16_t otp_slot, + enum crypto_otp_set_lock lock + ) { + struct otp_driver_api *api; + api = (struct otp_driver_api *) dev->api; + + return api->otp_set_lock(dev, otp_slot, lock); } /** @@ -312,18 +332,22 @@ static inline int z_impl_otp_set_lock( * * @return error code. */ -__syscall int (*otp_get_lock)( - const struct device *dev, - uint16_t otp_slot, - enum crypto_otp_set_lock *lock - ); +__syscall int otp_get_lock( + const struct device *dev, + uint16_t otp_slot, + enum crypto_otp_set_lock *lock + ); static inline int z_impl_otp_get_lock( const struct device *dev, uint16_t otp_slot, enum crypto_otp_set_lock *lock ) { + struct otp_driver_api *api; + + api = (struct otp_driver_api *) dev->api; + return api->otp_get_lock(dev, otp_slot, lock); } #endif /* ZEPHYR_INCLUDE_CRYPTO_OTP_MEM_H_ */ From 993c47e47e502b5a493dd75d799ab2a9922ec697 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 30 Sep 2024 16:27:18 +0500 Subject: [PATCH 27/58] Crypto OTP Mem API in progress --- .../rapidsilicon/virgo_proto/virgo_proto.dts | 4 ++ drivers/crypto/CMakeLists.txt | 1 + drivers/crypto/Kconfig.pufs | 25 +++++-- drivers/crypto/crypto_pufs.c | 3 +- drivers/crypto/crypto_pufs.h | 1 - drivers/crypto/crypto_pufs_otp.c | 70 +++++++++++++++++++ dts/riscv/rapidsilicon/rapidsi_virgo.dtsi | 7 +- 7 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 drivers/crypto/crypto_pufs_otp.c diff --git a/boards/rapidsilicon/virgo_proto/virgo_proto.dts b/boards/rapidsilicon/virgo_proto/virgo_proto.dts index 0943a164c1c69..6f6fe852be2c0 100644 --- a/boards/rapidsilicon/virgo_proto/virgo_proto.dts +++ b/boards/rapidsilicon/virgo_proto/virgo_proto.dts @@ -51,6 +51,10 @@ status = "okay"; }; + &pufs_otp { + status = "okay"; + }; + &pufs { status = "okay"; }; diff --git a/drivers/crypto/CMakeLists.txt b/drivers/crypto/CMakeLists.txt index 2d4e57fc5edea..0d1e09825f035 100644 --- a/drivers/crypto/CMakeLists.txt +++ b/drivers/crypto/CMakeLists.txt @@ -13,4 +13,5 @@ zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCHP_XEC_SYMCR crypto_mchp_xec_symcr. zephyr_library_sources_ifdef(CONFIG_CRYPTO_IT8XXX2_SHA crypto_it8xxx2_sha.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCUX_DCP crypto_mcux_dcp.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_PUF_SECURITY crypto_pufs.c pufcc.c) +zephyr_library_sources_ifdef(CONFIG_CRYPTO_PUF_SECURITY_OTP crypto_pufs_otp.c pufcc.c) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) diff --git a/drivers/crypto/Kconfig.pufs b/drivers/crypto/Kconfig.pufs index 834a25989e782..784dcdff139d0 100644 --- a/drivers/crypto/Kconfig.pufs +++ b/drivers/crypto/Kconfig.pufs @@ -3,9 +3,26 @@ # Copyright (c) 2024 Muhammad Junaid Aslam # SPDX-License-Identifier: Apache-2.0 -menuconfig CRYPTO_PUF_SECURITY - bool "PUF security Cryptographic Accelerator driver" +menuconfig PUFCC_SECURITY + bool "PUF Security Hardware" default y - depends on DT_HAS_PUFSECURITY_PUFCC_ENABLED help - Enable PUF Security based Cryptographic Accelerator driver. + Enable PUF Security Hardware. + + if PUFCC_SECURITY + + config CRYPTO_PUF_SECURITY + bool "PUF security Cryptographic Accelerator driver" + default n + depends on DT_HAS_PUFSECURITY_PUFCC_ENABLED + help + Enable PUF Security based Cryptographic Accelerator driver. + + config CRYPTO_PUF_SECURITY_OTP + bool "PUF security One Time Programmable Memory" + default n + depends on DT_HAS_PUFSECURITY_PUFCC_OTP_ENABLED + help + Enable PUF Security based One Time Programmable Memory. + + endif diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 5195355bd4b0e..10488f0ed78af 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -613,8 +613,7 @@ static struct pufs_data s_pufs_session_data = { static const struct pufs_config s_pufs_configuration = { .base = DT_INST_REG_ADDR(0), .irq_init = pufs_irq_Init, - .irq_num = DT_INST_IRQN(0), - .dev = DEVICE_DT_INST_GET(0) + .irq_num = DT_INST_IRQN(0) }; DEVICE_DT_INST_DEFINE(0, crypto_pufs_init, NULL, diff --git a/drivers/crypto/crypto_pufs.h b/drivers/crypto/crypto_pufs.h index 63cd58de74bb4..0f19c4d4d0ba8 100644 --- a/drivers/crypto/crypto_pufs.h +++ b/drivers/crypto/crypto_pufs.h @@ -56,7 +56,6 @@ struct pufs_config { void (*irq_init)(void); uint32_t base; uint32_t irq_num; - const struct device *dev; }; #endif /* ZEPHYR_DRIVERS_CRYPTO_CRYPTO_STM32_PRIV_H_ */ diff --git a/drivers/crypto/crypto_pufs_otp.c b/drivers/crypto/crypto_pufs_otp.c new file mode 100644 index 0000000000000..b7076a7d29e60 --- /dev/null +++ b/drivers/crypto/crypto_pufs_otp.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024 Rapid Silicon + * + * SPDX-License-Identifier: Apache-2.0 + * + */ + +#include "pufcc.h" +#include "crypto_otp_mem.h" + +#include + +#include +#include + +#define LOG_LEVEL CONFIG_CRYPTO_LOG_LEVEL +#include +LOG_MODULE_REGISTER(crypto_puf_security_otp); + +#if DT_HAS_COMPAT_STATUS_OKAY(pufsecurity_pufcc_otp) + #define DT_DRV_COMPAT pufsecurity_pufcc_otp +#else + #error No PUF Security HW Crypto OTP in device tree +#endif + +#define OTP_HW_CAP (CAP_READ_OTP | CAP_WRITE_OTP | \ + CAP_LOCK_OTP | CAP_ZEROIZ_OTP | CAP_SYNC_OPS) + +/* Device constant configuration parameters */ +struct pufs_otp_config { + uint32_t base; +}; + +/** + * Query the driver capabilities + * Not all the Modules of PUFs support all flags. + * Please Check individual cipher/hash/sign_begin_session + * interfaces to get the information of supported flags. + * */ +static int crypto_pufs_otp_query_hw_caps(const struct device *dev) +{ + return OTP_HW_CAP; +} + +static int crypto_pufs_otp_init(const struct device *dev) { + + // Initialize base addresses of different PUFcc modules + enum pufcc_status lvStatus = pufcc_init(((struct pufs_otp_config*)dev->config)->base); + + return PUFCC_SUCCESS; +} + +static struct otp_driver_api s_crypto_otp_funcs = { + .otp_hw_caps = crypto_pufs_otp_query_hw_caps, + .otp_get_lock = NULL, + .otp_info = NULL, + .otp_read = NULL, + .otp_set_lock = NULL, + .otp_write = NULL, + .otp_zeroize = NULL +}; + +static const struct pufs_otp_config s_pufs_otp_configuration = { + .base = DT_REG_ADDR(DT_PARENT(DT_DRV_INST(0))), +}; + +DEVICE_DT_INST_DEFINE(0, crypto_pufs_otp_init, NULL, + NULL, + &s_pufs_otp_configuration, POST_KERNEL, + CONFIG_CRYPTO_INIT_PRIORITY, (void *)&s_crypto_otp_funcs); diff --git a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi index bc3387638762f..4dcd950d5720b 100644 --- a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi +++ b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi @@ -186,7 +186,12 @@ reg = <0xA0130000 DT_SIZE_K(64)>; interrupts = <33 3>; interrupt-parent = < &eclic >; - status = "disabled"; + status = "disabled"; + + pufs_otp: pufcc_otp { + compatible = "pufsecurity,pufcc_otp"; + status = "disabled"; + }; }; fpga_cfg: cfg-ctrl@A0710000 { From 6f51268519920e6663ca85d8829fb81494b0541d Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 30 Sep 2024 18:27:38 +0500 Subject: [PATCH 28/58] Crypto OTP Mem API in progress --- .../rapidsilicon/virgo_proto/virgo_proto.dts | 2 +- drivers/crypto/Kconfig.pufs | 22 +++++++++---------- drivers/crypto/crypto_pufs_otp.c | 4 ++-- dts/riscv/rapidsilicon/rapidsi_virgo.dtsi | 11 +++++----- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/boards/rapidsilicon/virgo_proto/virgo_proto.dts b/boards/rapidsilicon/virgo_proto/virgo_proto.dts index 6f6fe852be2c0..b75ffb8707d30 100644 --- a/boards/rapidsilicon/virgo_proto/virgo_proto.dts +++ b/boards/rapidsilicon/virgo_proto/virgo_proto.dts @@ -51,7 +51,7 @@ status = "okay"; }; - &pufs_otp { + &otp { status = "okay"; }; diff --git a/drivers/crypto/Kconfig.pufs b/drivers/crypto/Kconfig.pufs index 784dcdff139d0..379786d1b7107 100644 --- a/drivers/crypto/Kconfig.pufs +++ b/drivers/crypto/Kconfig.pufs @@ -5,24 +5,24 @@ menuconfig PUFCC_SECURITY bool "PUF Security Hardware" - default y help Enable PUF Security Hardware. if PUFCC_SECURITY - - config CRYPTO_PUF_SECURITY - bool "PUF security Cryptographic Accelerator driver" - default n - depends on DT_HAS_PUFSECURITY_PUFCC_ENABLED - help - Enable PUF Security based Cryptographic Accelerator driver. + + # config CRYPTO_PUF_SECURITY + # bool "PUF security Cryptographic Accelerator driver" + # default y + # depends on DT_HAS_PUFSECURITY_PUFCC_ENABLED + # help + # Enable PUF Security based Cryptographic Accelerator driver. config CRYPTO_PUF_SECURITY_OTP bool "PUF security One Time Programmable Memory" - default n - depends on DT_HAS_PUFSECURITY_PUFCC_OTP_ENABLED + default y + depends on DT_HAS_PUFSECURITY_OTP_ENABLED help Enable PUF Security based One Time Programmable Memory. - + endif + \ No newline at end of file diff --git a/drivers/crypto/crypto_pufs_otp.c b/drivers/crypto/crypto_pufs_otp.c index b7076a7d29e60..6b3d32c12ce94 100644 --- a/drivers/crypto/crypto_pufs_otp.c +++ b/drivers/crypto/crypto_pufs_otp.c @@ -17,8 +17,8 @@ #include LOG_MODULE_REGISTER(crypto_puf_security_otp); -#if DT_HAS_COMPAT_STATUS_OKAY(pufsecurity_pufcc_otp) - #define DT_DRV_COMPAT pufsecurity_pufcc_otp +#if DT_HAS_COMPAT_STATUS_OKAY(pufsecurity_otp) + #define DT_DRV_COMPAT pufsecurity_otp #else #error No PUF Security HW Crypto OTP in device tree #endif diff --git a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi index 4dcd950d5720b..30a846f870b84 100644 --- a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi +++ b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi @@ -186,12 +186,13 @@ reg = <0xA0130000 DT_SIZE_K(64)>; interrupts = <33 3>; interrupt-parent = < &eclic >; - status = "disabled"; - - pufs_otp: pufcc_otp { - compatible = "pufsecurity,pufcc_otp"; - status = "disabled"; + status = "okay"; + + otp: otp { + compatible = "pufsecurity,otp"; + status = "okay"; }; + }; fpga_cfg: cfg-ctrl@A0710000 { From a70472f745d4ac792273a6598dc45d7c0fd744c7 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 1 Oct 2024 11:09:26 +0500 Subject: [PATCH 29/58] Crypto OTP Mem API Done./riscv32-elf-gdb Testing Remaning --- .../rapidsilicon/virgo_proto/virgo_proto.dts | 2 +- drivers/crypto/CMakeLists.txt | 5 +- drivers/crypto/Kconfig.pufs | 14 +- drivers/crypto/crypto_pufs_otp.c | 122 ++++++++++++++++- drivers/crypto/pufcc.h | 3 + dts/bindings/crypto/pufsecurity,otp.yaml | 10 ++ dts/riscv/rapidsilicon/rapidsi_virgo.dtsi | 6 +- include/zephyr/crypto/crypto_otp_mem.h | 129 +++++++++--------- samples/hello_world/src/main.c | 16 ++- 9 files changed, 221 insertions(+), 86 deletions(-) create mode 100644 dts/bindings/crypto/pufsecurity,otp.yaml diff --git a/boards/rapidsilicon/virgo_proto/virgo_proto.dts b/boards/rapidsilicon/virgo_proto/virgo_proto.dts index b75ffb8707d30..6f6fe852be2c0 100644 --- a/boards/rapidsilicon/virgo_proto/virgo_proto.dts +++ b/boards/rapidsilicon/virgo_proto/virgo_proto.dts @@ -51,7 +51,7 @@ status = "okay"; }; - &otp { + &pufs_otp { status = "okay"; }; diff --git a/drivers/crypto/CMakeLists.txt b/drivers/crypto/CMakeLists.txt index 0d1e09825f035..d76295c58742e 100644 --- a/drivers/crypto/CMakeLists.txt +++ b/drivers/crypto/CMakeLists.txt @@ -12,6 +12,7 @@ zephyr_library_sources_ifdef(CONFIG_CRYPTO_NPCX_SHA crypto_npcx_sha.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCHP_XEC_SYMCR crypto_mchp_xec_symcr.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_IT8XXX2_SHA crypto_it8xxx2_sha.c) zephyr_library_sources_ifdef(CONFIG_CRYPTO_MCUX_DCP crypto_mcux_dcp.c) -zephyr_library_sources_ifdef(CONFIG_CRYPTO_PUF_SECURITY crypto_pufs.c pufcc.c) -zephyr_library_sources_ifdef(CONFIG_CRYPTO_PUF_SECURITY_OTP crypto_pufs_otp.c pufcc.c) +zephyr_library_sources_ifdef(CONFIG_PUFCC_SECURITY pufcc.c) +zephyr_library_sources_ifdef(CONFIG_CRYPTO_PUF_SECURITY crypto_pufs.c) +zephyr_library_sources_ifdef(CONFIG_CRYPTO_PUF_SECURITY_OTP crypto_pufs_otp.c) zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS) diff --git a/drivers/crypto/Kconfig.pufs b/drivers/crypto/Kconfig.pufs index 379786d1b7107..719fbe00f160c 100644 --- a/drivers/crypto/Kconfig.pufs +++ b/drivers/crypto/Kconfig.pufs @@ -10,16 +10,16 @@ menuconfig PUFCC_SECURITY if PUFCC_SECURITY - # config CRYPTO_PUF_SECURITY - # bool "PUF security Cryptographic Accelerator driver" - # default y - # depends on DT_HAS_PUFSECURITY_PUFCC_ENABLED - # help - # Enable PUF Security based Cryptographic Accelerator driver. + config CRYPTO_PUF_SECURITY + bool "PUF security Cryptographic Accelerator driver" + default n + depends on DT_HAS_PUFSECURITY_PUFCC_ENABLED + help + Enable PUF Security based Cryptographic Accelerator driver. config CRYPTO_PUF_SECURITY_OTP bool "PUF security One Time Programmable Memory" - default y + default n depends on DT_HAS_PUFSECURITY_OTP_ENABLED help Enable PUF Security based One Time Programmable Memory. diff --git a/drivers/crypto/crypto_pufs_otp.c b/drivers/crypto/crypto_pufs_otp.c index 6b3d32c12ce94..fb1d77f4310cb 100644 --- a/drivers/crypto/crypto_pufs_otp.c +++ b/drivers/crypto/crypto_pufs_otp.c @@ -6,7 +6,7 @@ */ #include "pufcc.h" -#include "crypto_otp_mem.h" +#include #include @@ -47,17 +47,125 @@ static int crypto_pufs_otp_init(const struct device *dev) { // Initialize base addresses of different PUFcc modules enum pufcc_status lvStatus = pufcc_init(((struct pufs_otp_config*)dev->config)->base); + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) Error\n", __func__, __LINE__); + return -ENODEV; + } + + return PUFCC_SUCCESS; +} + +static int crypto_pufs_otp_info( + const struct device *dev, + uint16_t *totalSlots, + uint16_t *bytesPerSlot + ) +{ + *totalSlots = PUFCC_TOTAL_SLOTS; + *bytesPerSlot = (PUFCC_OTP_LEN / PUFCC_OTP_KEY_LEN); + return PUFCC_SUCCESS; +} + +static int crypto_pufs_otp_read( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ) +{ + enum pufcc_status lvStatus = PUFCC_SUCCESS; + + lvStatus = pufcc_read_otp(data, len, otp_slot); + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) Error: %d\n", __func__, __LINE__, lvStatus); + return -ECANCELED; + } + + return PUFCC_SUCCESS; +} + +static int crypto_pufs_otp_write( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ) +{ + enum pufcc_status lvStatus = PUFCC_SUCCESS; + + lvStatus = pufcc_program_otp((const uint8_t *)data, len, otp_slot); + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) Error: %d\n", __func__, __LINE__, lvStatus); + return -ECANCELED; + } + return PUFCC_SUCCESS; } +static int crypto_pufs_otp_zeroize( + const struct device *dev, + uint16_t otp_slot + ) +{ + enum pufcc_status lvStatus = PUFCC_SUCCESS; + + lvStatus = pufcc_zeroize_otp(otp_slot); + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) Error: %d\n", __func__, __LINE__, lvStatus); + return -ECANCELED; + } + + return PUFCC_SUCCESS; +} + +static int crypto_pufs_otp_set_lock( + const struct device *dev, + uint16_t otp_slot, + uint16_t len, + enum crypto_otp_set_lock lock + ) +{ + enum pufcc_status lvStatus = PUFCC_SUCCESS; + + lvStatus = pufcc_lock_otp(otp_slot, len, lock); + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) Error: %d\n", __func__, __LINE__, lvStatus); + return -ECANCELED; + } + + return PUFCC_SUCCESS; +} + +static int crypto_pufs_otp_get_lock( + const struct device *dev, + uint16_t otp_slot, + enum crypto_otp_set_lock *lock + ) +{ + enum pufcc_status lvStatus = PUFCC_SUCCESS; + + lvStatus = pufcc_get_otp_rwlck(otp_slot, (enum pufcc_otp_lock*)lock); + + if(lvStatus != PUFCC_SUCCESS) { + LOG_ERR("%s(%d) Error: %d\n", __func__, __LINE__, lvStatus); + return -ECANCELED; + } + + return PUFCC_SUCCESS; +} + static struct otp_driver_api s_crypto_otp_funcs = { .otp_hw_caps = crypto_pufs_otp_query_hw_caps, - .otp_get_lock = NULL, - .otp_info = NULL, - .otp_read = NULL, - .otp_set_lock = NULL, - .otp_write = NULL, - .otp_zeroize = NULL + .otp_get_lock = crypto_pufs_otp_get_lock, + .otp_info = crypto_pufs_otp_info, + .otp_read = crypto_pufs_otp_read, + .otp_set_lock = crypto_pufs_otp_set_lock, + .otp_write = crypto_pufs_otp_write, + .otp_zeroize = crypto_pufs_otp_zeroize }; static const struct pufs_otp_config s_pufs_otp_configuration = { diff --git a/drivers/crypto/pufcc.h b/drivers/crypto/pufcc.h index 22e0da207d88c..99b57070dd486 100644 --- a/drivers/crypto/pufcc.h +++ b/drivers/crypto/pufcc.h @@ -164,6 +164,9 @@ enum pufcc_otp_slot { PUFCC_OTPKEY_29, // OTP key slot 29, 256 bits PUFCC_OTPKEY_30, // OTP key slot 30, 256 bits PUFCC_OTPKEY_31, // OTP key slot 31, 256 bits +#ifdef RS_RTOS_PORT + PUFCC_TOTAL_SLOTS // OTP Number of slots. +#endif }; // OTP lock types diff --git a/dts/bindings/crypto/pufsecurity,otp.yaml b/dts/bindings/crypto/pufsecurity,otp.yaml new file mode 100644 index 0000000000000..5c139483a2b4d --- /dev/null +++ b/dts/bindings/crypto/pufsecurity,otp.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2024, Rapid Silicon +# SPDX-License-Identifier: Apache-2.0 + +description: | + PUF security IP PUFcc also contains the one time programmable + memory region. That region can be accessed using this driver. + +compatible: "pufsecurity,otp" + +include: [base.yaml] diff --git a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi index 30a846f870b84..061e0d86f3ea1 100644 --- a/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi +++ b/dts/riscv/rapidsilicon/rapidsi_virgo.dtsi @@ -186,11 +186,11 @@ reg = <0xA0130000 DT_SIZE_K(64)>; interrupts = <33 3>; interrupt-parent = < &eclic >; - status = "okay"; + status = "disabled"; - otp: otp { + pufs_otp: pufcc_otp { compatible = "pufsecurity,otp"; - status = "okay"; + status = "disabled"; }; }; diff --git a/include/zephyr/crypto/crypto_otp_mem.h b/include/zephyr/crypto/crypto_otp_mem.h index 7847a940f5f49..1300083871ce5 100644 --- a/include/zephyr/crypto/crypto_otp_mem.h +++ b/include/zephyr/crypto/crypto_otp_mem.h @@ -25,6 +25,7 @@ #include #include #include +#include /** * @brief Crypto OTP Mem APIs @@ -121,6 +122,7 @@ __subsystem struct otp_driver_api { int (*otp_set_lock)( const struct device *dev, uint16_t otp_slot, + uint16_t len, enum crypto_otp_set_lock lock ); @@ -148,15 +150,18 @@ __subsystem struct otp_driver_api { * * @return bitmask of supported options. */ -__syscall int otp_query_hw_caps(const struct device *dev); -static inline int z_impl_otp_query_hw_aps(const struct device *dev) +static inline int otp_query_hw_aps(const struct device *dev) { struct otp_driver_api *api; int tmp; api = (struct otp_driver_api *) dev->api; + if (api->otp_hw_caps == NULL) { + return -ENOSYS; + } + tmp = api->otp_hw_caps(dev); __ASSERT((tmp & (CAP_READ_OTP | CAP_WRITE_OTP)) != 0, @@ -182,21 +187,20 @@ static inline int z_impl_otp_query_hw_aps(const struct device *dev) * * @return error code. */ -__syscall int otp_info( - const struct device *dev, - uint16_t *totalSlots, - uint16_t *bytesPerSlot - ); -static inline int z_impl_otp_info( - const struct device *dev, - uint16_t *totalSlots, - uint16_t *bytesPerSlot - ) +static inline int otp_info( + const struct device *dev, + uint16_t *totalSlots, + uint16_t *bytesPerSlot + ) { struct otp_driver_api *api; api = (struct otp_driver_api *) dev->api; + if (api->otp_info == NULL) { + return -ENOSYS; + } + return api->otp_info(dev, totalSlots, bytesPerSlot); } @@ -212,23 +216,21 @@ static inline int z_impl_otp_info( * * @return error code. */ -__syscall int otp_read( - const struct device *dev, - uint16_t otp_slot, - uint8_t *data, - uint32_t len - ); -static inline int z_impl_otp_read( - const struct device *dev, - uint16_t otp_slot, - uint8_t *data, - uint32_t len - ) +static inline int otp_read( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ) { struct otp_driver_api *api; api = (struct otp_driver_api *) dev->api; + if (api->otp_read == NULL) { + return -ENOSYS; + } + return api->otp_read(dev, otp_slot, data, len); } @@ -244,23 +246,21 @@ static inline int z_impl_otp_read( * * @return error code. */ -__syscall int otp_write( - const struct device *dev, - uint16_t otp_slot, - uint8_t *data, - uint32_t len - ); -static inline int z_impl_otp_write( - const struct device *dev, - uint16_t otp_slot, - uint8_t *data, - uint32_t len - ) +static inline int otp_write( + const struct device *dev, + uint16_t otp_slot, + uint8_t *data, + uint32_t len + ) { struct otp_driver_api *api; api = (struct otp_driver_api *) dev->api; + if (api->otp_write == NULL) { + return -ENOSYS; + } + return api->otp_write(dev, otp_slot, data, len); } @@ -274,19 +274,19 @@ static inline int z_impl_otp_write( * * @return error code. */ -__syscall int otp_zeroize( - const struct device *dev, - uint16_t otp_slot - ); -static inline int z_impl_otp_zeoirze( - const struct device *dev, - uint16_t otp_slot - ) +static inline int otp_zeoirze( + const struct device *dev, + uint16_t otp_slot + ) { struct otp_driver_api *api; api = (struct otp_driver_api *) dev->api; + if (api->otp_zeroize == NULL) { + return -ENOSYS; + } + return api->otp_zeroize(dev, otp_slot); } @@ -302,22 +302,22 @@ static inline int z_impl_otp_zeoirze( * * @return error code. */ -__syscall int otp_set_lock( - const struct device *dev, - uint16_t otp_slot, - enum crypto_otp_set_lock lock - ); -static inline int z_impl_otp_set_lock( - const struct device *dev, - uint16_t otp_slot, - enum crypto_otp_set_lock lock - ) +static inline int otp_set_lock( + const struct device *dev, + uint16_t otp_slot, + uint16_t len, + enum crypto_otp_set_lock lock + ) { struct otp_driver_api *api; api = (struct otp_driver_api *) dev->api; - return api->otp_set_lock(dev, otp_slot, lock); + if (api->otp_set_lock == NULL) { + return -ENOSYS; + } + + return api->otp_set_lock(dev, otp_slot, len, lock); } /** @@ -332,21 +332,20 @@ static inline int z_impl_otp_set_lock( * * @return error code. */ -__syscall int otp_get_lock( - const struct device *dev, - uint16_t otp_slot, - enum crypto_otp_set_lock *lock - ); -static inline int z_impl_otp_get_lock( - const struct device *dev, - uint16_t otp_slot, - enum crypto_otp_set_lock *lock - ) +static inline int otp_get_lock( + const struct device *dev, + uint16_t otp_slot, + enum crypto_otp_set_lock *lock + ) { struct otp_driver_api *api; api = (struct otp_driver_api *) dev->api; + if (api->otp_get_lock == NULL) { + return -ENOSYS; + } + return api->otp_get_lock(dev, otp_slot, lock); } diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 071e84822a5c2..15c69189ad9c3 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -280,6 +280,20 @@ int main(void) const struct device *flash = DEVICE_DT_GET(DT_NODELABEL(m25p32)); const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma0)); const struct device *pit = DEVICE_DT_GET(DT_NODELABEL(pit0)); + const struct device *pufs = DEVICE_DT_GET(DT_NODELABEL(pufs)); + const struct device *pufs_otp = DEVICE_DT_GET(DT_NODELABEL(pufs_otp)); + + if((pufs == NULL) || (!device_is_ready(pufs))) { + printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); + } + + if((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { + printf("%s pufs_otp has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%s pufs_otp Object is Created %s\n", ATTR_INF, ATTR_RST); + } if((pvt == NULL) || (!device_is_ready(pvt))) { printf("%s pvt has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); @@ -309,7 +323,7 @@ int main(void) } if((pit == NULL) || !device_is_ready(pit)) { - printf("%s flash has status disabled or driver is not initialized...%s\n", ATTR_ERR,ATTR_RST); + printf("%s pit has status disabled or driver is not initialized...%s\n", ATTR_ERR,ATTR_RST); } else { CounterTest(pit); } From 646c37030de02d7b886ce96f79c5da4827c5ac3a Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 1 Oct 2024 19:37:40 +0500 Subject: [PATCH 30/58] Crypto OTP Mem API Tested! --- drivers/crypto/crypto_pufs_otp.c | 4 +- include/zephyr/crypto/crypto_otp_mem.h | 16 +++---- samples/hello_world/src/main.c | 59 ++++++++++++++++++++++++++ 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/drivers/crypto/crypto_pufs_otp.c b/drivers/crypto/crypto_pufs_otp.c index fb1d77f4310cb..7f918591cd8a9 100644 --- a/drivers/crypto/crypto_pufs_otp.c +++ b/drivers/crypto/crypto_pufs_otp.c @@ -125,7 +125,7 @@ static int crypto_pufs_otp_set_lock( const struct device *dev, uint16_t otp_slot, uint16_t len, - enum crypto_otp_set_lock lock + enum crypto_otp_lock lock ) { enum pufcc_status lvStatus = PUFCC_SUCCESS; @@ -143,7 +143,7 @@ static int crypto_pufs_otp_set_lock( static int crypto_pufs_otp_get_lock( const struct device *dev, uint16_t otp_slot, - enum crypto_otp_set_lock *lock + enum crypto_otp_lock *lock ) { enum pufcc_status lvStatus = PUFCC_SUCCESS; diff --git a/include/zephyr/crypto/crypto_otp_mem.h b/include/zephyr/crypto/crypto_otp_mem.h index 1300083871ce5..13a806014c6b0 100644 --- a/include/zephyr/crypto/crypto_otp_mem.h +++ b/include/zephyr/crypto/crypto_otp_mem.h @@ -59,7 +59,7 @@ /* More flags to be added as necessary */ // OTP lock types -enum crypto_otp_set_lock { +enum crypto_otp_lock { CRYPTO_OTP_RW = 0x0, // Read-Write CRYPTO_OTP_RO = 0x3, // Read-Only CRYPTO_OTP_NA = 0xF, // No-Access @@ -116,14 +116,14 @@ __subsystem struct otp_driver_api { /** * otp_set_lock API locks the selected OTP slot as per - * the crypto_otp_set_lock. Use otp_info to get total + * the crypto_otp_lock. Use otp_info to get total * number of slots and bytes per slot. */ int (*otp_set_lock)( const struct device *dev, uint16_t otp_slot, uint16_t len, - enum crypto_otp_set_lock lock + enum crypto_otp_lock lock ); /** @@ -133,7 +133,7 @@ __subsystem struct otp_driver_api { int (*otp_get_lock)( const struct device *dev, uint16_t otp_slot, - enum crypto_otp_set_lock *lock + enum crypto_otp_lock *lock ); }; @@ -292,7 +292,7 @@ static inline int otp_zeoirze( /** * @brief Set the crypto otp slot a particular lock value. The lock - * value can be referenced from crypto_otp_set_lock enumeration. + * value can be referenced from crypto_otp_lock enumeration. * * This API is used to set a lock value to an otp slot. * @@ -306,7 +306,7 @@ static inline int otp_set_lock( const struct device *dev, uint16_t otp_slot, uint16_t len, - enum crypto_otp_set_lock lock + enum crypto_otp_lock lock ) { struct otp_driver_api *api; @@ -322,7 +322,7 @@ static inline int otp_set_lock( /** * @brief Get the lock value of a particular crypto otp slot. The lock - * value can be referenced from crypto_otp_set_lock enumeration. + * value can be referenced from crypto_otp_lock enumeration. * * This API is used to get a lock value of an otp slot. * @@ -335,7 +335,7 @@ static inline int otp_set_lock( static inline int otp_get_lock( const struct device *dev, uint16_t otp_slot, - enum crypto_otp_set_lock *lock + enum crypto_otp_lock *lock ) { struct otp_driver_api *api; diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 15c69189ad9c3..2d44523751fc2 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #define ATTR_INF "\x1b[32;1m" // ANSI_COLOR_GREEN @@ -260,6 +261,63 @@ void CounterTest(const struct device *pit) } } +void pufs_otp_test(const struct device *pufs_otp) +{ + uint8_t slot_data[32] = {0}; + + uint16_t totalSlots = 0, bytesPerSlot = 0; + if(otp_info(pufs_otp, &totalSlots, &bytesPerSlot) != 0) { + printf("%s%s(%d) OTP_Info Failed%s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } else { + printf("%s%s(%d) OTP_Info... Slots:%d Bytes Per Slot:%d%s\n", \ + ATTR_INF,__func__,__LINE__, totalSlots, bytesPerSlot, ATTR_RST); + } + + for(uint8_t i = 0; i < bytesPerSlot; i++) { + slot_data[i] = (i+i)*2; + } + if(otp_write(pufs_otp, 12, slot_data, 18) != 0) { + printf("%s%s(%d) otp_write Failed%s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } else { + memset(slot_data, 0, bytesPerSlot); + if(otp_read(pufs_otp, 12, slot_data, 18) != 0) { + printf("%s%s(%d) otp_read Failed%s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } else { + printf("%s",ATTR_INF); + for(uint8_t i = 0; i < bytesPerSlot; i++) { + printf("%d ", slot_data[i]); + } printf("\n"); + printf("%s",ATTR_RST); + } + } + if(otp_set_lock(pufs_otp, 12, 18, CRYPTO_OTP_RO) != 0) { + printf("%s%s(%d) otp_set_lock Failed%s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } else { + enum crypto_otp_lock lvLock = CRYPTO_OTP_RW; + if(otp_get_lock(pufs_otp, 12, &lvLock) != 0) { + printf("%s%s(%d) otp_get_lock Failed%s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } else { + printf("%s%s(%d) otp_lock: %d %s\n", \ + ATTR_INF,__func__,__LINE__,lvLock,ATTR_RST); + } + for(uint8_t i = 0; i < bytesPerSlot; i++) { + slot_data[i] = (i+i)*2; + } + if(otp_write(pufs_otp, 12, slot_data, 18) != 0) { + printf("%s%s(%d) otp_write Failed as Expected %s\n", \ + ATTR_RST,__func__,__LINE__,ATTR_RST); + } else { + printf("%s%s(%d) otp_write Passed UnExpectedly %s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } + } +} + int main(void) { int Cnt = 0; @@ -293,6 +351,7 @@ int main(void) printf("%s pufs_otp has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); } else { printf("%s pufs_otp Object is Created %s\n", ATTR_INF, ATTR_RST); + pufs_otp_test(pufs_otp); } if((pvt == NULL) || (!device_is_ready(pvt))) { From 3d55660e9330cbdcfb22569a3ed0506a64a23b5a Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 2 Oct 2024 17:35:22 +0500 Subject: [PATCH 31/58] Asynch support to be integrated into PUFcc.c via pufcc native callbacks. For now, removing support --- drivers/crypto/crypto_pufs.c | 43 ++++++++++++++++++++-------------- drivers/crypto/pufcc.c | 3 +++ drivers/crypto/pufcc.h | 3 +++ samples/hello_world/src/main.c | 16 +++++++++++++ 4 files changed, 48 insertions(+), 17 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 10488f0ed78af..4644b62bbb985 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -23,7 +23,7 @@ LOG_MODULE_REGISTER(crypto_puf_security); #endif #define PUFS_HW_CAP (CAP_RAW_KEY | CAP_INPLACE_OPS | \ - CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_ASYNC_OPS | \ + CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | \ CAP_NO_IV_PREFIX | CAP_NO_ENCRYPTION | CAP_NO_SIGNING) static char *session_to_str(enum pufs_session_type inSession) { @@ -86,19 +86,28 @@ static void pufs_irq_handler(const struct device *dev) { struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; - switch(lvPufsData->pufs_session_type) { - case(PUFS_SESSION_SIGN_VERIFICATION): { - lvPufsData->pufs_session_callback.sign_cb(lvPufsData->pufs_pkt.sign_pkt, status); - } break; - case(PUFS_SESSION_HASH_CALCULATION): { - lvPufsData->pufs_session_callback.hash_cb(lvPufsData->pufs_pkt.hash_pkt, status); - } break; - case(PUFS_SESSION_DECRYPTION): { - lvPufsData->pufs_session_callback.cipher_cb(lvPufsData->pufs_pkt.cipher_pkt, status); - } break; - case(PUFS_SESSION_UNDEFINED): { - LOG_ERR("%s(%d) Unsupported Session %d\n", __func__, __LINE__, lvPufsData->pufs_session_type); - } break; + if((pufs_query_hw_caps(dev) & CAP_ASYNC_OPS) == CAP_ASYNC_OPS) + { + switch(lvPufsData->pufs_session_type) { + case(PUFS_SESSION_SIGN_VERIFICATION): { + if(lvPufsData->pufs_session_callback.sign_cb != NULL) { + lvPufsData->pufs_session_callback.sign_cb(lvPufsData->pufs_pkt.sign_pkt, status); + } + } break; + case(PUFS_SESSION_HASH_CALCULATION): { + if(lvPufsData->pufs_session_callback.hash_cb != NULL) { + lvPufsData->pufs_session_callback.hash_cb(lvPufsData->pufs_pkt.hash_pkt, status); + } + } break; + case(PUFS_SESSION_DECRYPTION): { + if(lvPufsData->pufs_session_callback.cipher_cb != NULL) { + lvPufsData->pufs_session_callback.cipher_cb(lvPufsData->pufs_pkt.cipher_pkt, status); + } + } break; + case(PUFS_SESSION_UNDEFINED): { + LOG_ERR("%s(%d) Unsupported Session %d\n", __func__, __LINE__, lvPufsData->pufs_session_type); + } break; + } } // After execution of a callback, the irq is disabled. @@ -201,7 +210,7 @@ static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx uint16_t lvHashFlags = ( CAP_NO_ENCRYPTION | CAP_SYNC_OPS | - CAP_ASYNC_OPS | CAP_NO_IV_PREFIX | + CAP_NO_IV_PREFIX | CAP_RAW_KEY | CAP_SEPARATE_IO_BUFS ), \ lvHashFlagsMask = 0xFFFF; @@ -372,7 +381,7 @@ static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ct struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; - uint16_t lvHashFlags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_ASYNC_OPS), lvHashFlagsMask = 0xFFFF; + uint16_t lvHashFlags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS), lvHashFlagsMask = 0xFFFF; if(algo != CRYPTO_HASH_ALGO_SHA256) { LOG_ERR("%s(%d) UnSupported Hash Algo. Only SHA256 Supported\n", __func__, __LINE__); @@ -503,7 +512,7 @@ static int pufs_sign_begin_session(const struct device *dev, struct sign_ctx *ct struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; - uint16_t lvHashFlags = (CAP_INPLACE_OPS | CAP_SYNC_OPS | CAP_ASYNC_OPS), lvHashFlagsMask = 0xFFFF; + uint16_t lvHashFlags = (CAP_INPLACE_OPS | CAP_SYNC_OPS), lvHashFlagsMask = 0xFFFF; if((algo != CRYPTO_SIGN_ALGO_ECDSA256) || (algo != CRYPTO_SIGN_ALGO_RSA2048)) { LOG_ERR("%s(%d) Unupported Algo:%d. Supported Algo \n", __func__, __LINE__, algo); diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index ad99146f7e72f..4b8afd4831fff 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -10,6 +10,9 @@ #include #include #include "crypto_pufs.h" + static volatile bool s_Asynch_Operation = false; + void pufcc_set_asynch_ops_flag(bool Val) {s_Asynch_Operation = Val;} + bool pufcc_get_asynch_ops_flag(void) {return s_Asynch_Operation;} #endif /***************************************************************************** diff --git a/drivers/crypto/pufcc.h b/drivers/crypto/pufcc.h index 99b57070dd486..286aaf6fb7111 100644 --- a/drivers/crypto/pufcc.h +++ b/drivers/crypto/pufcc.h @@ -599,6 +599,9 @@ enum pufcc_status pufcc_ecdsa256_sign_verify( enum pufcc_status pufcc_dma_transfer(uint32_t src_addr, uint32_t dest_addr, uint32_t len, bool fixed_read, bool fixed_write); +#else + bool pufcc_get_asynch_ops_flag(void); + void pufcc_set_asynch_ops_flag(bool Val); #endif enum pufcc_status pufcc_otp_setup_wait(void); diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 2d44523751fc2..c76f7d33117c6 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -318,6 +318,22 @@ void pufs_otp_test(const struct device *pufs_otp) } } +void pufs_test(const struct device *pufs) +{ + static const uint8_t *pufs_sample_data = "This is Rapid Silicon'z Zephyr Port"; + static const uint8_t pufs_sample_data_sha256[] = { + 0xfa,0x71,0xc2,0x19,0xea,0x58,0x4d,0xac, + 0x36,0xd5,0x3e,0xca,0xe4,0x2a,0x8c,0x14, + 0x4b,0xc1,0xc0,0x03,0xfd,0x36,0x3f,0x71, + 0xd9,0x30,0x96,0xc4,0xaa,0x64,0xe0,0x4c + }; + const uint8_t pufs_sample_data_len = strlen(pufs_sample_data); + printf("%s%s(%d) Length of sample data to operate on %s\n", \ + ATTR_INF,__func__,__LINE__,ATTR_RST); + + +} + int main(void) { int Cnt = 0; From b8c57ed031965b11761f1610d2255b25283cf48e Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Wed, 2 Oct 2024 19:15:58 +0500 Subject: [PATCH 32/58] Hash testing done! --- drivers/crypto/crypto_pufs.c | 2 + samples/hello_world/src/main.c | 83 ++++++++++++++++++++++++++++++---- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 4644b62bbb985..9143d24492539 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -34,6 +34,8 @@ static char *session_to_str(enum pufs_session_type inSession) { uint8_t __pufcc_descriptors[BUFFER_SIZE]; +static int pufs_query_hw_caps(const struct device *dev); + static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data_addr) { uint8_t desc_count = 0; diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index c76f7d33117c6..f49b895c39596 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -10,6 +10,8 @@ #include #include #include +#include + #include #define ATTR_INF "\x1b[32;1m" // ANSI_COLOR_GREEN @@ -241,13 +243,13 @@ void CounterTest(const struct device *pit) lvCntTopCfg.ticks = 6000; int lvErrorCode = 0; - /* + lvErrorCode = counter_set_channel_alarm(pit, 0, &lvCntAlarmCfg); if(lvErrorCode < 0) { printf("%s%s(%d) counter Alarm set error code:%d %s\n", \ ATTR_ERR,__func__,__LINE__,lvErrorCode,ATTR_RST); } - */ + /* lvErrorCode = counter_set_top_value(pit, &lvCntTopCfg); if(lvErrorCode < 0) { printf("%s%s(%d) counter setting top error code:%d %s\n", \ @@ -259,6 +261,7 @@ void CounterTest(const struct device *pit) ATTR_ERR,__func__,__LINE__,lvErrorCode,ATTR_RST); } } + */ } void pufs_otp_test(const struct device *pufs_otp) @@ -318,9 +321,11 @@ void pufs_otp_test(const struct device *pufs_otp) } } -void pufs_test(const struct device *pufs) +void pufs_hash_test(const struct device *pufs) { - static const uint8_t *pufs_sample_data = "This is Rapid Silicon'z Zephyr Port"; + int status = 0; + static uint8_t *pufs_sample_data = "This is Rapid Silicon'z Zephyr Port"; + static uint8_t pufs_sample_data_sha256_out[32] = {0}; static const uint8_t pufs_sample_data_sha256[] = { 0xfa,0x71,0xc2,0x19,0xea,0x58,0x4d,0xac, 0x36,0xd5,0x3e,0xca,0xe4,0x2a,0x8c,0x14, @@ -328,10 +333,67 @@ void pufs_test(const struct device *pufs) 0xd9,0x30,0x96,0xc4,0xaa,0x64,0xe0,0x4c }; const uint8_t pufs_sample_data_len = strlen(pufs_sample_data); - printf("%s%s(%d) Length of sample data to operate on %s\n", \ - ATTR_INF,__func__,__LINE__,ATTR_RST); - - + printf("%s%s(%d) Length of sample data to operate on:%d %s\n", \ + ATTR_INF,__func__,__LINE__,pufs_sample_data_len,ATTR_RST); + struct hash_ctx lvHashCtx = { + .device = pufs, + .drv_sessn_state = NULL, + .flags = CAP_SYNC_OPS | CAP_SEPARATE_IO_BUFS, + .started = false + }; + + struct hash_pkt lvHashPkt = { + .ctx = &lvHashCtx, + .head = true, + .tail = true, + .in_buf = pufs_sample_data, + .in_hash = NULL, + .in_len = pufs_sample_data_len, + .next = NULL, + .out_buf = pufs_sample_data_sha256_out, + .prev_len = 0, + .out_len = 0 + }; + + status = hash_begin_session(pufs, &lvHashCtx, CRYPTO_HASH_ALGO_SHA256); + if(status != 0) { + printf("%s%s(%d) hash_begin_session status = %d %s\n", \ + ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + } else { + status = hash_compute(&lvHashCtx, &lvHashPkt); + } + if(status != 0) { + printf("%s%s(%d) hash_compute status = %d %s\n", \ + ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + } else { + for(uint8_t i = 0; i < lvHashPkt.out_len; i++) { + if(lvHashPkt.out_buf[i] != pufs_sample_data_sha256[i]) { + printf("%s%s(%d) out_buf[%d]0x%02x != in_buf[%d]:0x%02x %s\n", \ + ATTR_ERR,__func__,__LINE__,\ + i,lvHashPkt.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); + status = -EINVAL; + } else { + printf("%s%s(%d) out_buf[%d]0x%02x == in_buf[%d]:0x%02x %s\n", \ + ATTR_INF,__func__,__LINE__,\ + i,lvHashPkt.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); + } + } + if(status != 0) { + printf("%s%s(%d) hash_comparison failed%s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } else { + printf("%s%s(%d) hash_comparison Passed = %d %s\n", \ + ATTR_INF,__func__,__LINE__,status,ATTR_RST); + } + status = hash_free_session(pufs, &lvHashCtx); + if(status != 0) { + printf("%s%s(%d) hash_free_session status = %d %s\n", \ + ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + } else { + printf("%s%s(%d) hash_free_session Passed = %d %s\n", \ + ATTR_INF,__func__,__LINE__,status,ATTR_RST); + } + } } int main(void) @@ -361,6 +423,7 @@ int main(void) printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); + pufs_hash_test(pufs); } if((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { @@ -374,7 +437,7 @@ int main(void) printf("%s pvt has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); } else { printf("%s pvt Object is Created %s\n", ATTR_INF, ATTR_RST); - errorcode = sensor_channel_get(pvt, SENSOR_CHAN_DIE_TEMP, &lvTemp); + errorcode = sensor_channel_get(pvt, SENSOR_CHAN_DIE_TEMP, &lvTemp); if(errorcode == 0) { printf("%s Error fetching temperature value. Error code:%u%s\n", ATTR_ERR, errorcode,ATTR_RST); } @@ -405,7 +468,7 @@ int main(void) while(true) { printf( - "%s%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Build[Date:%s Time:%s]\n", + "%s%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Build[Date:%s Time:%s]\r", ATTR_RST, Cnt++, CONFIG_BOARD_TARGET, chip_id, vendor_id, From 2168d17ab9fa274f183ba7f8a2ae519e7e44b008 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 3 Oct 2024 23:21:19 +0500 Subject: [PATCH 33/58] Hash SG debugging in progress --- drivers/crypto/crypto_pufs.c | 48 ++++++++------- drivers/crypto/pufcc.c | 3 + include/zephyr/crypto/hash.h | 29 ++++++++-- samples/hello_world/src/main.c | 103 ++++++++++++++++++++++++++++++++- 4 files changed, 158 insertions(+), 25 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 9143d24492539..dfac96c4704e7 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -46,14 +46,17 @@ static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data // Set SGDMA descriptors do { - data_addr->read_addr = (uint32_t)pkt->in_buf; - data_addr->len = pkt->in_len; - desc_count++; + data_addr[desc_count].read_addr = (uint32_t)pkt->in_buf; + data_addr[desc_count].len = pkt->in_len; + if((desc_count * sizeof(struct pufcc_sg_dma_desc)) < BUFFER_SIZE){ - data_addr->next = data_addr+1; + data_addr[desc_count].next = &data_addr[desc_count+1]; + printf("%s(%d) pkt:%p pkt->next:%p\r\n", __func__, __LINE__, pkt, pkt->next); + pkt = pkt->next; } else { break; } + desc_count++; } while (pkt); if (pkt) { @@ -61,6 +64,8 @@ static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data LOG_ERR("%s(%d) Not More Than %d Elements Allowed. Desc_Count:%d\n", \ __func__, __LINE__, (BUFFER_SIZE/sizeof(struct pufcc_sg_dma_desc)), desc_count); return -ENOTEMPTY; + } else { + LOG_INF("%s(%d) Num_Desc_Elements:%d\r\n", __func__, __LINE__, desc_count); } return PUFCC_SUCCESS; @@ -333,36 +338,39 @@ static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) } else { - struct rs_crypto_addr lvHash_Data_Addr[BUFFER_SIZE]; + uint8_t lvHash_Data_Addr[BUFFER_SIZE] = {0}; + struct hash_pkt *lvPkt = &pkt[0]; - if(fill_rs_crypto_addr(pkt, lvHash_Data_Addr) != PUFCC_SUCCESS) { + if(fill_rs_crypto_addr(pkt, (struct rs_crypto_addr*)lvHash_Data_Addr) != PUFCC_SUCCESS) { return -ENOTEMPTY; } struct rs_crypto_hash hash_in = {0}; - hash_in.len = pkt->in_len; - /* Copy input hash values for operating upon */ - memcpy((void*)hash_in.val, (void*)pkt->in_buf, hash_in.len); + hash_in.len = lvPkt->in_hash_len; + + if(lvPkt->in_hash != NULL) { + /* Copy input hash values for operating upon */ + memcpy((void*)hash_in.val, (void*)lvPkt->in_hash, hash_in.len); + } else { + LOG_INF("%s(%d) in_hash_len:%d\r\n", __func__, __LINE__, hash_in.len); + } struct rs_crypto_hash hash_out = {0}; lvStatus = pufcc_calc_sha256_hash_sg( - lvHash_Data_Addr, - pkt->head, - pkt->tail, - pkt->prev_len, + (struct rs_crypto_addr*)lvHash_Data_Addr, + lvPkt->head, + lvPkt->tail, + lvPkt->prev_len, &hash_in, &hash_out ); - /* Copy output hash values calculated by PUFcc */ - memcpy((void*)pkt->out_buf, (void*)hash_out.val, (size_t)hash_out.len); - pkt->out_len = hash_out.len; - - if(lvStatus != PUFCC_SUCCESS) { - LOG_ERR("%s(%d) PUFs Error Code:%d\n", __func__, __LINE__, lvStatus); - return -ECANCELED; + if(lvStatus == PUFCC_SUCCESS) { + /* Copy output hash values calculated by PUFcc */ + memcpy((void*)lvPkt->out_buf, (void*)hash_out.val, (size_t)hash_out.len); + lvPkt->out_len = hash_out.len; } } diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 4b8afd4831fff..4475340d36fa5 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -294,10 +294,12 @@ enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, dma_dsc_cfg_4_reg.offset = plen % 16; plen += curr_addr->len; + printf("%s(%d) curr_addr:%p curr_addr->next:%p\r\n", __func__, __LINE__, curr_addr, curr_addr->next); curr_addr = curr_addr->next; if (!desc_count && first) { dma_dsc_cfg_4_reg.head = 1; + printf("%s(%d) has head\r\n", __func__, __LINE__); } // Mark this descriptor as last if there is no more data @@ -305,6 +307,7 @@ enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, dma_dsc_cfg_4_reg.dn_pause = 1; if (last) { dma_dsc_cfg_4_reg.tail = 1; + printf("%s(%d) has tail\r\n", __func__, __LINE__); } } diff --git a/include/zephyr/crypto/hash.h b/include/zephyr/crypto/hash.h index f86d44e68aa9d..b0a2da0c71447 100644 --- a/include/zephyr/crypto/hash.h +++ b/include/zephyr/crypto/hash.h @@ -97,20 +97,38 @@ struct hash_pkt { /** Start address of previously calculated hash / digest. * It is useful where hash is calculated in chunks. + * This will be filled only once in the very first + * element of struct hash_pkt type linkedlist. */ uint8_t *in_hash; + /** + * Length of previously calculated hash + * This will be filled only once in the very first + * element of struct hash_pkt type linkedlist. + * */ + size_t in_hash_len; - /** Bytes previously operated upon */ + /** Bytes previously operated upon + * This will be filled only once in the very first + * element of struct hash_pkt type linkedlist. + */ uint32_t *prev_len; /** * Start of the output buffer, to be allocated by * the application. Can be NULL for in-place ops. To be populated * with contents by the driver on return from op / async callback. + * In case of a multipart hash calculation, the output hash + * shall be placed in the memory pointed by the out_buf pointer of + * the first element of the struct hash_pkt type linkedlist. */ uint8_t *out_buf; - /** Bytes in returned hash (out_buf) */ + /** Bytes in returned hash (out_buf) + * In case of a multipart hash calculation, the output hash + * shall be placed in the memory pointed by the out_buf pointer of + * the first element of the struct hash_pkt type linkedlist. + */ size_t out_len; /** @@ -123,20 +141,23 @@ struct hash_pkt { /** * Whether this linkedlist contains head or not. * This boolean shall be initialized only once in - * the beginning of every new linkedlist construction. + * the first element of every new linkedlist. */ bool head; /** * Whether this linkedlist contains tail or not. * This boolean shall be initialized only once in - * the beginning of every new linkedlist construction. + * the first element of every new linkedlist. */ bool tail; /** * Context this packet relates to. This can be useful to get the * session details, especially for async ops. + * In case of a multipart hash calculation, the output hash + * shall be placed in the memory pointed by the out_buf pointer of + * the first element of the struct hash_pkt type linkedlist. */ struct hash_ctx *ctx; }; diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index f49b895c39596..ca18e8099e6f1 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -321,6 +321,106 @@ void pufs_otp_test(const struct device *pufs_otp) } } + +void pufs_hash_sg_test(const struct device *pufs) +{ + int status = 0; + static uint8_t *pufs_sample_data1 = "This is Rapid Silicon'z Zephyr Port"; + static uint8_t *pufs_sample_data2 = "Zephyr Port"; + static uint8_t pufs_sample_data_sha256_out[32] = {0}; + static const uint8_t pufs_sample_data_sha256[] = { + 0xfa,0x71,0xc2,0x19,0xea,0x58,0x4d,0xac, + 0x36,0xd5,0x3e,0xca,0xe4,0x2a,0x8c,0x14, + 0x4b,0xc1,0xc0,0x03,0xfd,0x36,0x3f,0x71, + 0xd9,0x30,0x96,0xc4,0xaa,0x64,0xe0,0x4c + }; + const uint8_t pufs_sample_data1_len = strlen(pufs_sample_data1); + const uint8_t pufs_sample_data2_len = strlen(pufs_sample_data2); + printf("%s%s(%d) Length of sample data to operate on:%d %s\n", \ + ATTR_INF,__func__,__LINE__,pufs_sample_data1_len+pufs_sample_data2_len,ATTR_RST); + struct hash_ctx lvHashCtx = { + .device = pufs, + .drv_sessn_state = NULL, + .flags = CAP_SYNC_OPS | CAP_SEPARATE_IO_BUFS, + .started = true + }; + + struct hash_pkt lvHashPkt[2] = { + { + .ctx = &lvHashCtx, + .head = true, + .tail = true, + .in_buf = pufs_sample_data1, + .in_hash = NULL, + .in_hash_len = 0, + .in_len = pufs_sample_data1_len, + .next = NULL,//&lvHashPkt[1], + .out_buf = pufs_sample_data_sha256_out, + .prev_len = 0, + .out_len = 0 + } + // , + // { + // .ctx = &lvHashCtx, + // .head = true, + // .tail = true, + // .in_buf = pufs_sample_data2, + // .in_hash = NULL, + // .in_hash_len = 0, + // .in_len = pufs_sample_data2_len, + // .next = NULL, + // .out_buf = NULL, + // .prev_len = 0, + // .out_len = 0 + // } + }; + // printf("AddrlvHashPkt[0]:%p AddrlvHashPkt[1]:%p Diff:%d\r\n", \ + // &lvHashPkt[0], lvHashPkt[0].next, (((uint32_t)lvHashPkt[0].next) - ((uint32_t)&lvHashPkt[0]))); + // printf("Size struct hash pkt:%d\r\n", sizeof(struct hash_pkt)); + // printf("data1_size:%d data2_size:%d\r\n", pufs_sample_data1_len, pufs_sample_data2_len); + + status = hash_begin_session(pufs, &lvHashCtx, CRYPTO_HASH_ALGO_SHA256); + if(status != 0) { + printf("%s%s(%d) hash_begin_session status = %d %s\n", \ + ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + } else { + status = hash_compute(&lvHashCtx, lvHashPkt); + } + if(status != 0) { + printf("%s%s(%d) hash_compute status = %d %s\n", \ + ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + } else { + for(uint8_t i = 0; i < lvHashPkt[0].out_len; i++) { + if(lvHashPkt[0].out_buf[i] != pufs_sample_data_sha256[i]) { + printf("%s%s(%d) out_buf[%d]0x%02x != in_buf[%d]:0x%02x %s\n", \ + ATTR_ERR,__func__,__LINE__,\ + i,lvHashPkt[0].out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); + status = -EINVAL; + } else { + printf("%s%s(%d) out_buf[%d]0x%02x == in_buf[%d]:0x%02x %s\n", \ + ATTR_INF,__func__,__LINE__,\ + i,lvHashPkt[0].out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); + } + } + if(status != 0) { + printf("%s%s(%d) hash_comparison failed%s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } else { + printf("%s%s(%d) hash_comparison Passed = %d %s\n", \ + ATTR_INF,__func__,__LINE__,status,ATTR_RST); + } + status = hash_free_session(pufs, &lvHashCtx); + if(status != 0) { + printf("%s%s(%d) hash_free_session status = %d %s\n", \ + ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + } else { + printf("%s%s(%d) hash_free_session Passed = %d %s\n", \ + ATTR_INF,__func__,__LINE__,status,ATTR_RST); + } + } +} + + void pufs_hash_test(const struct device *pufs) { int status = 0; @@ -354,7 +454,6 @@ void pufs_hash_test(const struct device *pufs) .prev_len = 0, .out_len = 0 }; - status = hash_begin_session(pufs, &lvHashCtx, CRYPTO_HASH_ALGO_SHA256); if(status != 0) { printf("%s%s(%d) hash_begin_session status = %d %s\n", \ @@ -424,6 +523,8 @@ int main(void) } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); pufs_hash_test(pufs); + pufs_hash_sg_test(pufs); + while(1); } if((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { From 1635b68702dfd9c8d52f1adfae261546f29d1858 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 4 Oct 2024 10:35:24 +0500 Subject: [PATCH 34/58] Hash SG debugging in progress --- drivers/crypto/crypto_pufs.c | 17 ++++++++++++----- drivers/crypto/pufcc.c | 2 -- samples/hello_world/src/main.c | 6 +++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index dfac96c4704e7..b12a095f77175 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -45,19 +45,26 @@ static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data } // Set SGDMA descriptors - do { + while(true) { + printf("%s(%d) pkt:%p pkt->next:%p\r\n", __func__, __LINE__, pkt, pkt->next); + data_addr[desc_count].read_addr = (uint32_t)pkt->in_buf; data_addr[desc_count].len = pkt->in_len; + data_addr[desc_count].periph_rw = false; - if((desc_count * sizeof(struct pufcc_sg_dma_desc)) < BUFFER_SIZE){ - data_addr[desc_count].next = &data_addr[desc_count+1]; - printf("%s(%d) pkt:%p pkt->next:%p\r\n", __func__, __LINE__, pkt, pkt->next); + if((desc_count * sizeof(struct pufcc_sg_dma_desc)) < BUFFER_SIZE){ pkt = pkt->next; } else { break; } + if(pkt != NULL) { + data_addr[desc_count].next = &data_addr[desc_count+1]; + } else { + data_addr[desc_count].next = NULL; + break; + } desc_count++; - } while (pkt); + } if (pkt) { // No enough descriptors available diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 4475340d36fa5..de24eca2ea068 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -299,7 +299,6 @@ enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, if (!desc_count && first) { dma_dsc_cfg_4_reg.head = 1; - printf("%s(%d) has head\r\n", __func__, __LINE__); } // Mark this descriptor as last if there is no more data @@ -307,7 +306,6 @@ enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, dma_dsc_cfg_4_reg.dn_pause = 1; if (last) { dma_dsc_cfg_4_reg.tail = 1; - printf("%s(%d) has tail\r\n", __func__, __LINE__); } } diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index ca18e8099e6f1..f0b1c3516dadc 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -345,7 +345,7 @@ void pufs_hash_sg_test(const struct device *pufs) .started = true }; - struct hash_pkt lvHashPkt[2] = { + struct hash_pkt lvHashPkt[1] = { { .ctx = &lvHashCtx, .head = true, @@ -374,7 +374,7 @@ void pufs_hash_sg_test(const struct device *pufs) // .out_len = 0 // } }; - // printf("AddrlvHashPkt[0]:%p AddrlvHashPkt[1]:%p Diff:%d\r\n", \ + // printf("AddrlvHashPkt[0]:%p AddrlvHashPkt[1]:%p Diff:%d\r\n", // &lvHashPkt[0], lvHashPkt[0].next, (((uint32_t)lvHashPkt[0].next) - ((uint32_t)&lvHashPkt[0]))); // printf("Size struct hash pkt:%d\r\n", sizeof(struct hash_pkt)); // printf("data1_size:%d data2_size:%d\r\n", pufs_sample_data1_len, pufs_sample_data2_len); @@ -522,7 +522,7 @@ int main(void) printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); - pufs_hash_test(pufs); + // pufs_hash_test(pufs); pufs_hash_sg_test(pufs); while(1); } From 7502d9d078e66b2eb1305eecf2d90f7b08f839bd Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 4 Oct 2024 12:39:51 +0500 Subject: [PATCH 35/58] Hash SG debugging in progress --- drivers/crypto/crypto_pufs.c | 21 ++++++-- drivers/crypto/pufcc.c | 7 ++- samples/hello_world/src/main.c | 90 +++++++++++++++++----------------- 3 files changed, 67 insertions(+), 51 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index b12a095f77175..66646ec33dd41 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -44,9 +44,10 @@ static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data return -EBADFD; } - // Set SGDMA descriptors + // Set SGDMA descriptors input data while(true) { - printf("%s(%d) pkt:%p pkt->next:%p\r\n", __func__, __LINE__, pkt, pkt->next); + printf("%s(%d) desc_count:%d pkt:%p pkt->next:%p\r\n", \ + __func__, __LINE__, desc_count, pkt, pkt->next); data_addr[desc_count].read_addr = (uint32_t)pkt->in_buf; data_addr[desc_count].len = pkt->in_len; @@ -59,8 +60,14 @@ static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data } if(pkt != NULL) { data_addr[desc_count].next = &data_addr[desc_count+1]; + printf("%s(%d) data_rd_addr:0x%08x data:%p data->next:%p\r\n", \ + __func__, __LINE__, data_addr[desc_count].read_addr, \ + &data_addr[desc_count], data_addr[desc_count].next); } else { data_addr[desc_count].next = NULL; + printf("%s(%d) data_rd_addr:0x%08x data:%p data->next:%p\r\n", \ + __func__, __LINE__, data_addr[desc_count].read_addr, \ + &data_addr[desc_count], data_addr[desc_count].next); break; } desc_count++; @@ -72,7 +79,7 @@ static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data __func__, __LINE__, (BUFFER_SIZE/sizeof(struct pufcc_sg_dma_desc)), desc_count); return -ENOTEMPTY; } else { - LOG_INF("%s(%d) Num_Desc_Elements:%d\r\n", __func__, __LINE__, desc_count); + LOG_INF("%s(%d) Num_Desc_Elements:%d\r\n", __func__, __LINE__, desc_count+1); } return PUFCC_SUCCESS; @@ -329,6 +336,8 @@ static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) if(!ctx->started) { // started flag indicates if chunkwise hash calculation was started + LOG_INF("%s(%d) Normal Hash Calculation\r\n", __func__, __LINE__); + struct rs_crypto_addr data_addr = { .read_addr = (uint32_t)pkt->in_buf, .write_addr = (uint32_t)pkt->out_buf, @@ -345,10 +354,12 @@ static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) } else { - uint8_t lvHash_Data_Addr[BUFFER_SIZE] = {0}; + LOG_INF("%s(%d) Scatter Gather Hash Calculation\r\n", __func__, __LINE__); + + struct rs_crypto_addr lvHash_Data_Addr[(BUFFER_SIZE/sizeof(struct rs_crypto_addr))] = {0}; struct hash_pkt *lvPkt = &pkt[0]; - if(fill_rs_crypto_addr(pkt, (struct rs_crypto_addr*)lvHash_Data_Addr) != PUFCC_SUCCESS) { + if(fill_rs_crypto_addr(pkt, lvHash_Data_Addr) != PUFCC_SUCCESS) { return -ENOTEMPTY; } diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index de24eca2ea068..d3468ea23242e 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -294,7 +294,11 @@ enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, dma_dsc_cfg_4_reg.offset = plen % 16; plen += curr_addr->len; - printf("%s(%d) curr_addr:%p curr_addr->next:%p\r\n", __func__, __LINE__, curr_addr, curr_addr->next); + + printf("%s(%d) curr_addr:%p (rd_addr:0x%08x len:%d data:%s)\r\n", \ + __func__, __LINE__, curr_addr, be2le(sg_dma_descs[desc_count].read_addr), \ + be2le(sg_dma_descs[desc_count].length), (char*)be2le(sg_dma_descs[desc_count].read_addr)); + curr_addr = curr_addr->next; if (!desc_count && first) { @@ -304,6 +308,7 @@ enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, // Mark this descriptor as last if there is no more data if (!curr_addr) { dma_dsc_cfg_4_reg.dn_pause = 1; + printf("%s(%d) No More Data\r\n", __func__, __LINE__); if (last) { dma_dsc_cfg_4_reg.tail = 1; } diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index f0b1c3516dadc..d5a2df977b0d1 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -325,19 +325,22 @@ void pufs_otp_test(const struct device *pufs_otp) void pufs_hash_sg_test(const struct device *pufs) { int status = 0; - static uint8_t *pufs_sample_data1 = "This is Rapid Silicon'z Zephyr Port"; - static uint8_t *pufs_sample_data2 = "Zephyr Port"; + // static uint8_t *pufs_sample_data1 = "This is Rapid Silicon'z_Zephyr_Port"; + static uint8_t *pufs_sample_data1 = "This is Rapid Silicon'z_"; + static uint8_t *pufs_sample_data2 = "Zephyr_Port"; static uint8_t pufs_sample_data_sha256_out[32] = {0}; static const uint8_t pufs_sample_data_sha256[] = { - 0xfa,0x71,0xc2,0x19,0xea,0x58,0x4d,0xac, - 0x36,0xd5,0x3e,0xca,0xe4,0x2a,0x8c,0x14, - 0x4b,0xc1,0xc0,0x03,0xfd,0x36,0x3f,0x71, - 0xd9,0x30,0x96,0xc4,0xaa,0x64,0xe0,0x4c + 0x63,0xb9,0x67,0xb5,0x43,0x6e,0x4a,0xe2, + 0x24,0x03,0x91,0xb4,0xa6,0xca,0xf2,0x22, + 0x09,0x34,0x1c,0x6f,0x52,0x6a,0x33,0xc6, + 0xe2,0x02,0x86,0xb9,0xd8,0x7d,0xfb,0x69 }; const uint8_t pufs_sample_data1_len = strlen(pufs_sample_data1); const uint8_t pufs_sample_data2_len = strlen(pufs_sample_data2); + printf("%s%s(%d) Length of sample data to operate on:%d %s\n", \ - ATTR_INF,__func__,__LINE__,pufs_sample_data1_len+pufs_sample_data2_len,ATTR_RST); + ATTR_INF,__func__,__LINE__,pufs_sample_data1_len+pufs_sample_data2_len,ATTR_RST); + struct hash_ctx lvHashCtx = { .device = pufs, .drv_sessn_state = NULL, @@ -345,61 +348,58 @@ void pufs_hash_sg_test(const struct device *pufs) .started = true }; - struct hash_pkt lvHashPkt[1] = { - { - .ctx = &lvHashCtx, - .head = true, - .tail = true, - .in_buf = pufs_sample_data1, - .in_hash = NULL, - .in_hash_len = 0, - .in_len = pufs_sample_data1_len, - .next = NULL,//&lvHashPkt[1], - .out_buf = pufs_sample_data_sha256_out, - .prev_len = 0, - .out_len = 0 - } - // , - // { - // .ctx = &lvHashCtx, - // .head = true, - // .tail = true, - // .in_buf = pufs_sample_data2, - // .in_hash = NULL, - // .in_hash_len = 0, - // .in_len = pufs_sample_data2_len, - // .next = NULL, - // .out_buf = NULL, - // .prev_len = 0, - // .out_len = 0 - // } - }; - // printf("AddrlvHashPkt[0]:%p AddrlvHashPkt[1]:%p Diff:%d\r\n", - // &lvHashPkt[0], lvHashPkt[0].next, (((uint32_t)lvHashPkt[0].next) - ((uint32_t)&lvHashPkt[0]))); - // printf("Size struct hash pkt:%d\r\n", sizeof(struct hash_pkt)); - // printf("data1_size:%d data2_size:%d\r\n", pufs_sample_data1_len, pufs_sample_data2_len); + struct hash_pkt lvHashPkt1 = {0}, lvHashPkt2 = {0}; + + lvHashPkt1.ctx = &lvHashCtx; + lvHashPkt1.head = true; + lvHashPkt1.tail = true; + lvHashPkt1.in_buf = pufs_sample_data1; + lvHashPkt1.in_hash = NULL; + lvHashPkt1.in_hash_len = 0; + lvHashPkt1.in_len = pufs_sample_data1_len; + lvHashPkt1.next = &lvHashPkt2; + lvHashPkt1.out_buf = pufs_sample_data_sha256_out; + lvHashPkt1.out_len = 0; + lvHashPkt1.prev_len = 0; + + lvHashPkt2.ctx = &lvHashCtx; + lvHashPkt2.head = true; + lvHashPkt2.tail = true; + lvHashPkt2.in_buf = pufs_sample_data2; + lvHashPkt2.in_hash = NULL; + lvHashPkt2.in_hash_len = 0; + lvHashPkt2.in_len = pufs_sample_data2_len; + lvHashPkt2.next = NULL; + lvHashPkt2.out_buf = pufs_sample_data_sha256_out; + lvHashPkt2.out_len = 0; + lvHashPkt2.prev_len = 0; + + printf("AddrlvHashPkt1.rd_addr:0x%08x AddrlvHashPkt2.rd_addr:0x%08x\r\n", + (uint32_t)lvHashPkt1.in_buf, (uint32_t)lvHashPkt2.in_buf); + printf("Size struct hash pkt:%d\r\n", sizeof(struct hash_pkt)); + printf("data1_size:%d data2_size:%d\r\n", pufs_sample_data1_len, pufs_sample_data2_len); status = hash_begin_session(pufs, &lvHashCtx, CRYPTO_HASH_ALGO_SHA256); if(status != 0) { printf("%s%s(%d) hash_begin_session status = %d %s\n", \ ATTR_ERR,__func__,__LINE__,status,ATTR_RST); } else { - status = hash_compute(&lvHashCtx, lvHashPkt); + status = hash_compute(&lvHashCtx, &lvHashPkt1); } if(status != 0) { printf("%s%s(%d) hash_compute status = %d %s\n", \ ATTR_ERR,__func__,__LINE__,status,ATTR_RST); } else { - for(uint8_t i = 0; i < lvHashPkt[0].out_len; i++) { - if(lvHashPkt[0].out_buf[i] != pufs_sample_data_sha256[i]) { + for(uint8_t i = 0; i < lvHashPkt1.out_len; i++) { + if(lvHashPkt1.out_buf[i] != pufs_sample_data_sha256[i]) { printf("%s%s(%d) out_buf[%d]0x%02x != in_buf[%d]:0x%02x %s\n", \ ATTR_ERR,__func__,__LINE__,\ - i,lvHashPkt[0].out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); + i,lvHashPkt1.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); status = -EINVAL; } else { printf("%s%s(%d) out_buf[%d]0x%02x == in_buf[%d]:0x%02x %s\n", \ ATTR_INF,__func__,__LINE__,\ - i,lvHashPkt[0].out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); + i,lvHashPkt1.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); } } if(status != 0) { From 66a5b2ba3a5ca52d08323d223bc446df2cbc2186 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 4 Oct 2024 13:39:15 +0500 Subject: [PATCH 36/58] Hash SG debugging in progress --- samples/hello_world/src/main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index d5a2df977b0d1..65f9b22a7b0f8 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -326,8 +326,8 @@ void pufs_hash_sg_test(const struct device *pufs) { int status = 0; // static uint8_t *pufs_sample_data1 = "This is Rapid Silicon'z_Zephyr_Port"; - static uint8_t *pufs_sample_data1 = "This is Rapid Silicon'z_"; - static uint8_t *pufs_sample_data2 = "Zephyr_Port"; + static uint8_t *pufs_sample_data2 = "This is Rapid Silicon'z_"; + static uint8_t *pufs_sample_data1 = "Zephyr_Port"; static uint8_t pufs_sample_data_sha256_out[32] = {0}; static const uint8_t pufs_sample_data_sha256[] = { 0x63,0xb9,0x67,0xb5,0x43,0x6e,0x4a,0xe2, @@ -337,7 +337,7 @@ void pufs_hash_sg_test(const struct device *pufs) }; const uint8_t pufs_sample_data1_len = strlen(pufs_sample_data1); const uint8_t pufs_sample_data2_len = strlen(pufs_sample_data2); - + printf("%s%s(%d) Length of sample data to operate on:%d %s\n", \ ATTR_INF,__func__,__LINE__,pufs_sample_data1_len+pufs_sample_data2_len,ATTR_RST); From 9a99a8bb38554f8dab35b94e8fce31dee28b74a0 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 7 Oct 2024 12:01:11 +0500 Subject: [PATCH 37/58] Hash SG Test Passed! --- drivers/crypto/crypto_pufs.c | 16 ------ drivers/crypto/pufcc.c | 6 --- samples/hello_world/src/main.c | 95 +++++++++++++++++++++++++--------- 3 files changed, 70 insertions(+), 47 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 66646ec33dd41..5ed922e4f7890 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -46,8 +46,6 @@ static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data // Set SGDMA descriptors input data while(true) { - printf("%s(%d) desc_count:%d pkt:%p pkt->next:%p\r\n", \ - __func__, __LINE__, desc_count, pkt, pkt->next); data_addr[desc_count].read_addr = (uint32_t)pkt->in_buf; data_addr[desc_count].len = pkt->in_len; @@ -60,14 +58,8 @@ static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data } if(pkt != NULL) { data_addr[desc_count].next = &data_addr[desc_count+1]; - printf("%s(%d) data_rd_addr:0x%08x data:%p data->next:%p\r\n", \ - __func__, __LINE__, data_addr[desc_count].read_addr, \ - &data_addr[desc_count], data_addr[desc_count].next); } else { data_addr[desc_count].next = NULL; - printf("%s(%d) data_rd_addr:0x%08x data:%p data->next:%p\r\n", \ - __func__, __LINE__, data_addr[desc_count].read_addr, \ - &data_addr[desc_count], data_addr[desc_count].next); break; } desc_count++; @@ -78,8 +70,6 @@ static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data LOG_ERR("%s(%d) Not More Than %d Elements Allowed. Desc_Count:%d\n", \ __func__, __LINE__, (BUFFER_SIZE/sizeof(struct pufcc_sg_dma_desc)), desc_count); return -ENOTEMPTY; - } else { - LOG_INF("%s(%d) Num_Desc_Elements:%d\r\n", __func__, __LINE__, desc_count+1); } return PUFCC_SUCCESS; @@ -336,8 +326,6 @@ static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) if(!ctx->started) { // started flag indicates if chunkwise hash calculation was started - LOG_INF("%s(%d) Normal Hash Calculation\r\n", __func__, __LINE__); - struct rs_crypto_addr data_addr = { .read_addr = (uint32_t)pkt->in_buf, .write_addr = (uint32_t)pkt->out_buf, @@ -354,8 +342,6 @@ static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) } else { - LOG_INF("%s(%d) Scatter Gather Hash Calculation\r\n", __func__, __LINE__); - struct rs_crypto_addr lvHash_Data_Addr[(BUFFER_SIZE/sizeof(struct rs_crypto_addr))] = {0}; struct hash_pkt *lvPkt = &pkt[0]; @@ -370,8 +356,6 @@ static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) if(lvPkt->in_hash != NULL) { /* Copy input hash values for operating upon */ memcpy((void*)hash_in.val, (void*)lvPkt->in_hash, hash_in.len); - } else { - LOG_INF("%s(%d) in_hash_len:%d\r\n", __func__, __LINE__, hash_in.len); } struct rs_crypto_hash hash_out = {0}; diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index d3468ea23242e..4b8afd4831fff 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -294,11 +294,6 @@ enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, dma_dsc_cfg_4_reg.offset = plen % 16; plen += curr_addr->len; - - printf("%s(%d) curr_addr:%p (rd_addr:0x%08x len:%d data:%s)\r\n", \ - __func__, __LINE__, curr_addr, be2le(sg_dma_descs[desc_count].read_addr), \ - be2le(sg_dma_descs[desc_count].length), (char*)be2le(sg_dma_descs[desc_count].read_addr)); - curr_addr = curr_addr->next; if (!desc_count && first) { @@ -308,7 +303,6 @@ enum pufcc_status pufcc_calc_sha256_hash_sg(struct rs_crypto_addr *data_addr, // Mark this descriptor as last if there is no more data if (!curr_addr) { dma_dsc_cfg_4_reg.dn_pause = 1; - printf("%s(%d) No More Data\r\n", __func__, __LINE__); if (last) { dma_dsc_cfg_4_reg.tail = 1; } diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 65f9b22a7b0f8..9254e6ae53976 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -213,7 +213,7 @@ void Flash_Test(const struct device *flash, const struct device *dma, uint32_t F void CounterCallBack(const struct device *dev, void *UserData) { uint32_t *lvData = ((uint32_t*)UserData); - printf("andestech_atcpit100 %s # %d\n", __func__, *lvData); + printf("\nandestech_atcpit100 %s # %d\n", __func__, *lvData); *lvData += 1; } @@ -222,7 +222,7 @@ void CounterAlarmCallBack(const struct device *dev, void *UserData) { uint32_t *lvData = ((uint32_t*)UserData); - printf("andestech_atcpit100 %s # %d\n", __func__, *lvData); + printf("\nandestech_atcpit100 %s # %d\n", __func__, *lvData); } static uint32_t s_CallBackData = 0; @@ -267,8 +267,9 @@ void CounterTest(const struct device *pit) void pufs_otp_test(const struct device *pufs_otp) { uint8_t slot_data[32] = {0}; - + enum crypto_otp_lock lvLock = CRYPTO_OTP_RW; uint16_t totalSlots = 0, bytesPerSlot = 0; + if(otp_info(pufs_otp, &totalSlots, &bytesPerSlot) != 0) { printf("%s%s(%d) OTP_Info Failed%s\n", \ ATTR_ERR,__func__,__LINE__,ATTR_RST); @@ -276,18 +277,38 @@ void pufs_otp_test(const struct device *pufs_otp) printf("%s%s(%d) OTP_Info... Slots:%d Bytes Per Slot:%d%s\n", \ ATTR_INF,__func__,__LINE__, totalSlots, bytesPerSlot, ATTR_RST); } + + if(otp_get_lock(pufs_otp, 12, &lvLock) != 0) { + printf("%s%s(%d) otp_get_lock Failed%s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } else { + printf("%s%s(%d) otp_lock: %d %s\n", \ + ATTR_INF,__func__,__LINE__,lvLock,ATTR_RST); + } for(uint8_t i = 0; i < bytesPerSlot; i++) { slot_data[i] = (i+i)*2; } if(otp_write(pufs_otp, 12, slot_data, 18) != 0) { - printf("%s%s(%d) otp_write Failed%s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + if(lvLock != CRYPTO_OTP_RW) { + printf("%s%s(%d) otp_write Failed as Expected %s\n", \ + ATTR_RST,__func__,__LINE__,ATTR_RST); + } else { + printf("%s%s(%d) otp_write Failed unExpectedly %s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } } else { + printf("%s%s(%d) otp_write Passed %s\n", \ + ATTR_RST,__func__,__LINE__,ATTR_RST); memset(slot_data, 0, bytesPerSlot); if(otp_read(pufs_otp, 12, slot_data, 18) != 0) { - printf("%s%s(%d) otp_read Failed%s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + if(lvLock == CRYPTO_OTP_NA) { + printf("%s%s(%d) otp_read Failed as Expected %s\n", \ + ATTR_RST,__func__,__LINE__,ATTR_RST); + } else { + printf("%s%s(%d) otp_read Failed unExpectedly %s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } } else { printf("%s",ATTR_INF); for(uint8_t i = 0; i < bytesPerSlot; i++) { @@ -300,7 +321,6 @@ void pufs_otp_test(const struct device *pufs_otp) printf("%s%s(%d) otp_set_lock Failed%s\n", \ ATTR_ERR,__func__,__LINE__,ATTR_RST); } else { - enum crypto_otp_lock lvLock = CRYPTO_OTP_RW; if(otp_get_lock(pufs_otp, 12, &lvLock) != 0) { printf("%s%s(%d) otp_get_lock Failed%s\n", \ ATTR_ERR,__func__,__LINE__,ATTR_RST); @@ -312,8 +332,13 @@ void pufs_otp_test(const struct device *pufs_otp) slot_data[i] = (i+i)*2; } if(otp_write(pufs_otp, 12, slot_data, 18) != 0) { - printf("%s%s(%d) otp_write Failed as Expected %s\n", \ - ATTR_RST,__func__,__LINE__,ATTR_RST); + if(lvLock != CRYPTO_OTP_RW) { + printf("%s%s(%d) otp_write Failed as Expected %s\n", \ + ATTR_RST,__func__,__LINE__,ATTR_RST); + } else { + printf("%s%s(%d) otp_write Failed unExpectedly %s\n", \ + ATTR_ERR,__func__,__LINE__,ATTR_RST); + } } else { printf("%s%s(%d) otp_write Passed UnExpectedly %s\n", \ ATTR_ERR,__func__,__LINE__,ATTR_RST); @@ -325,21 +350,29 @@ void pufs_otp_test(const struct device *pufs_otp) void pufs_hash_sg_test(const struct device *pufs) { int status = 0; - // static uint8_t *pufs_sample_data1 = "This is Rapid Silicon'z_Zephyr_Port"; - static uint8_t *pufs_sample_data2 = "This is Rapid Silicon'z_"; - static uint8_t *pufs_sample_data1 = "Zephyr_Port"; + static uint8_t pufs_sample_data1[] = { + "My name is Junaid and I work at the Rapid Silicon and WorkFromH." + }; + static uint8_t pufs_sample_data2[] = { + "My name is Junaid and I work at the Rapid Silicon and WorkFromH." + }; + static uint8_t pufs_sample_data3[] = { + "123456789123456789" + }; + static uint8_t pufs_sample_data_sha256_out[32] = {0}; static const uint8_t pufs_sample_data_sha256[] = { - 0x63,0xb9,0x67,0xb5,0x43,0x6e,0x4a,0xe2, - 0x24,0x03,0x91,0xb4,0xa6,0xca,0xf2,0x22, - 0x09,0x34,0x1c,0x6f,0x52,0x6a,0x33,0xc6, - 0xe2,0x02,0x86,0xb9,0xd8,0x7d,0xfb,0x69 + 0xb2,0x69,0xec,0xc6,0x0f,0x13,0x37,0xf3, + 0xf3,0xf8,0x29,0xc1,0x0e,0xc5,0x83,0xa6, + 0x82,0x25,0x97,0x32,0x71,0x78,0xd1,0xb8, + 0xe5,0x95,0x05,0xd1,0xbe,0xe7,0x43,0xca }; const uint8_t pufs_sample_data1_len = strlen(pufs_sample_data1); const uint8_t pufs_sample_data2_len = strlen(pufs_sample_data2); + const uint8_t pufs_sample_data3_len = strlen(pufs_sample_data3); printf("%s%s(%d) Length of sample data to operate on:%d %s\n", \ - ATTR_INF,__func__,__LINE__,pufs_sample_data1_len+pufs_sample_data2_len,ATTR_RST); + ATTR_INF,__func__,__LINE__,pufs_sample_data1_len+pufs_sample_data2_len+pufs_sample_data3_len,ATTR_RST); struct hash_ctx lvHashCtx = { .device = pufs, @@ -348,7 +381,7 @@ void pufs_hash_sg_test(const struct device *pufs) .started = true }; - struct hash_pkt lvHashPkt1 = {0}, lvHashPkt2 = {0}; + struct hash_pkt lvHashPkt1 = {0}, lvHashPkt2 = {0}, lvHashPkt3 = {0}; lvHashPkt1.ctx = &lvHashCtx; lvHashPkt1.head = true; @@ -369,15 +402,28 @@ void pufs_hash_sg_test(const struct device *pufs) lvHashPkt2.in_hash = NULL; lvHashPkt2.in_hash_len = 0; lvHashPkt2.in_len = pufs_sample_data2_len; - lvHashPkt2.next = NULL; + lvHashPkt2.next = &lvHashPkt3; lvHashPkt2.out_buf = pufs_sample_data_sha256_out; lvHashPkt2.out_len = 0; lvHashPkt2.prev_len = 0; - printf("AddrlvHashPkt1.rd_addr:0x%08x AddrlvHashPkt2.rd_addr:0x%08x\r\n", - (uint32_t)lvHashPkt1.in_buf, (uint32_t)lvHashPkt2.in_buf); + lvHashPkt3.ctx = &lvHashCtx; + lvHashPkt3.head = true; + lvHashPkt3.tail = true; + lvHashPkt3.in_buf = pufs_sample_data3; + lvHashPkt3.in_hash = NULL; + lvHashPkt3.in_hash_len = 0; + lvHashPkt3.in_len = pufs_sample_data3_len; + lvHashPkt3.next = NULL; + lvHashPkt3.out_buf = pufs_sample_data_sha256_out; + lvHashPkt3.out_len = 0; + lvHashPkt3.prev_len = 0; + + printf("Pkt1.rd_addr:0x%08x Pkt2.rd_addr:0x%08x Pkt3.rd_addr:0x%08x\r\n", + (uint32_t)lvHashPkt1.in_buf, (uint32_t)lvHashPkt2.in_buf, (uint32_t)lvHashPkt3.in_buf); printf("Size struct hash pkt:%d\r\n", sizeof(struct hash_pkt)); - printf("data1_size:%d data2_size:%d\r\n", pufs_sample_data1_len, pufs_sample_data2_len); + printf("data1_size:%d data2_size:%d data3_size:%d\r\n", \ + pufs_sample_data1_len, pufs_sample_data2_len, pufs_sample_data3_len); status = hash_begin_session(pufs, &lvHashCtx, CRYPTO_HASH_ALGO_SHA256); if(status != 0) { @@ -522,9 +568,8 @@ int main(void) printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); - // pufs_hash_test(pufs); + pufs_hash_test(pufs); pufs_hash_sg_test(pufs); - while(1); } if((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { From 310ebc0b768217870d0e7b4aa2b01de0f02ab648 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 7 Oct 2024 19:40:46 +0500 Subject: [PATCH 38/58] Hash SG Test Passed! --- samples/hello_world/src/main.c | 100 +++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 9254e6ae53976..946123db7935f 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -541,6 +541,105 @@ void pufs_hash_test(const struct device *pufs) } } +void pufs_decryption_test(const struct device *pufs) +{ + /* + Plain Text: This is Junaid Aslam from Rapid Silicon doing Decryption Test... + IV: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f + Key: 0x30,0x13,0x53,0x33,0x44,0x12,0xff,0x22,0x31,0x53,0xbb,0x13,0x07,0x19,0x84,0x0d,0xd5,0x3c,0x3f,0xc0,0x09,0x83,0x11,0x35,0x30,0x2d,0xdc,0xc0,0x0b,0xb9,0x4e,0x30 + + Cipher Text: 0x9c,0x87,0xe4,0xef,0xd5,0xeb,0xf3,0xb7,0xb6,0xff,0x58,0xfb,0x05,0x5b,0x26,0xa5,0x61,0xd9,0xaa,0xf4,0xa1,0x3c,0xb2,0x28,0x94,0xe3,0x49, + 0x91,0xba,0xc0,0x46,0x83,0x60,0x86,0xb2,0x6e,0xf0,0x59,0xa6,0x6c,0xc8,0x21,0xb1,0x4f,0xfc,0x55,0x6a,0x45,0x8a,0x1d,0xd8,0x03,0x48,0xc3,0xe4,0x68,0x32, + 0xd8,0x7e,0x40,0x9e,0xf7,0x88,0x57 + */ + int lvStatus = 0; + struct cipher_ctx lvCipherCtx = {0}; + struct cipher_pkt lvCipherPkt = {0}; + + const uint8_t enc32_key[] = { + 0x30,0x13,0x53,0x33, + 0x44,0x12,0xff,0x22, + 0x31,0x53,0xbb,0x13, + 0x07,0x19,0x84,0x0d, + 0xd5,0x3c,0x3f,0xc0, + 0x09,0x83,0x11,0x35, + 0x30,0x2d,0xdc,0xc0, + 0x0b,0xb9,0x4e,0x30 + }; + const uint8_t iv[] = { + 0x00,0x01,0x02,0x03, + 0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b, + 0x0c,0x0d,0x0e,0x0f + }; + + const uint8_t cipher_text[] = { + 0x9c,0x87,0xe4,0xef,0xd5,0xeb,0xf3,0xb7, + 0xb6,0xff,0x58,0xfb,0x05,0x5b,0x26,0xa5, + 0x61,0xd9,0xaa,0xf4,0xa1,0x3c,0xb2,0x28, + 0x94,0xe3,0x49,0x91,0xba,0xc0,0x46,0x83, + 0x60,0x86,0xb2,0x6e,0xf0,0x59,0xa6,0x6c, + 0xc8,0x21,0xb1,0x4f,0xfc,0x55,0x6a,0x45, + 0x8a,0x1d,0xd8,0x03,0x48,0xc3,0xe4,0x68, + 0x32,0xd8,0x7e,0x40,0x9e,0xf7,0x88,0x57 + }; + + const uint8_t *plain_text = "This is Junaid Aslam from Rapid Silicon doing Decryption Test..."; + const uint8_t decrypted_text[256] = {0}; + + lvCipherCtx.app_sessn_state = NULL; + lvCipherCtx.device = pufs; + lvCipherCtx.flags = ( + CAP_RAW_KEY | + CAP_SEPARATE_IO_BUFS | + CAP_SYNC_OPS | + CAP_NO_IV_PREFIX | + CAP_NO_ENCRYPTION + ); + lvCipherCtx.key.bit_stream = enc32_key; + lvCipherCtx.key_source = CRYPTO_KEY_SW; + lvCipherCtx.keylen = 32; + lvCipherCtx.mode_params.ctr_info.ctr_len = 16; + lvCipherCtx.mode_params.ctr_info.readback_ctr = false; + lvCipherCtx.ops.cipher_mode = CRYPTO_CIPHER_MODE_CTR; + + lvCipherPkt.auto_increment = true; + lvCipherPkt.ctx = &lvCipherCtx; + lvCipherPkt.in_buf = cipher_text; + lvCipherPkt.in_len = strlen(cipher_text); + lvCipherPkt.out_buf = decrypted_text; + lvCipherPkt.prev_len = 0; + + printf("%s Decrypting %d bytes %s\n", ATTR_INF, lvCipherPkt.in_len, ATTR_RST); + + lvStatus = cipher_begin_session( + pufs, + &lvCipherCtx, + CRYPTO_CIPHER_ALGO_AES, + CRYPTO_CIPHER_MODE_CTR, + CRYPTO_CIPHER_OP_DECRYPT + ); + if(lvStatus != 0) { + printf("%s cipher_begin_session Failed! %s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%s cipher_begin_session Success! %s\n", ATTR_ERR, ATTR_RST); + } + + lvStatus = cipher_ctr_op(&lvCipherCtx, &lvCipherPkt, iv); + if(lvStatus != 0) { + printf("%s cipher_ctr_op Failed! %s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%s cipher_ctr_op Success! %s\n", ATTR_ERR, ATTR_RST); + } + + lvStatus = cipher_free_session(pufs, &lvCipherCtx); + if(lvStatus != 0) { + printf("%s cipher_free_session Failed! %s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%s cipher_free_session Success! %s\n", ATTR_ERR, ATTR_RST); + } +} + int main(void) { int Cnt = 0; @@ -568,6 +667,7 @@ int main(void) printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); + pufs_decryption_test(pufs); while(true); pufs_hash_test(pufs); pufs_hash_sg_test(pufs); } From 6d52e406adf98b5d029911df735529cacaf1144c Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 7 Oct 2024 21:29:45 +0500 Subject: [PATCH 39/58] Decryption test in progress! --- drivers/crypto/crypto_pufs.c | 31 +------------------------------ drivers/crypto/pufcc.c | 3 ++- include/zephyr/crypto/crypto.h | 1 - samples/hello_world/src/main.c | 26 ++++++++++++++++++-------- 4 files changed, 21 insertions(+), 40 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 5ed922e4f7890..8be661544646d 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -167,7 +167,7 @@ static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t * ((struct pufs_data*)ctx->device->data)->pufs_pkt.cipher_pkt = pkt; ((struct pufs_data*)ctx->device->data)->pufs_ctx.cipher_ctx = ctx; - + lvStatus = pufcc_decrypt_aes( (uint32_t)pkt->out_buf, (uint32_t)pkt->in_buf, (uint32_t)pkt->in_len, pkt->prev_len, ctx->key_source, @@ -184,31 +184,6 @@ static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t * return 0; } -/* Following cipher operations (block, cbc, ccm and gcm) are not supported yet. - */ -__unused static int pufs_block_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt) -{ - return -ENOSYS; -} - -__unused static int pufs_cbc_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, - uint8_t *iv) -{ - return -ENOSYS; -} - -__unused static int pufs_ccm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, - uint8_t *nonce) -{ - return -ENOSYS; -} - -__unused static int pufs_gcm_op(struct cipher_ctx *ctx, struct cipher_aead_pkt *pkt, - uint8_t *nonce) -{ - return -ENOSYS; -} - static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx *ctx, enum cipher_algo algo, enum cipher_mode mode, enum cipher_op op_type) @@ -236,10 +211,6 @@ static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx return -ENOTSUP; } else { ctx->ops.ctr_crypt_hndlr = pufs_ctr_op; - ctx->ops.block_crypt_hndlr = pufs_block_op; - ctx->ops.cbc_crypt_hndlr = pufs_cbc_op; - ctx->ops.ccm_crypt_hndlr = pufs_ccm_op; - ctx->ops.gcm_crypt_hndlr = pufs_gcm_op; } if(op_type != CRYPTO_CIPHER_OP_DECRYPT) { diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 4b8afd4831fff..57735c25218a1 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -392,7 +392,8 @@ enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, bool readback_iv) { enum pufcc_status status; uint32_t temp32; - + printf("%s(%d) outAddress:0x%08x inLength:%d in_addr:0x%08x keylen:%d key_addr:0x%08x key_type:%d\r\n", \ + __func__, __LINE__, out_addr, in_len, in_addr, key_len, key_addr, key_type); // Configure DMA intrpt register temp32 = 0; struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; diff --git a/include/zephyr/crypto/crypto.h b/include/zephyr/crypto/crypto.h index d5bf33e5e8e7b..163f5a9c3d664 100644 --- a/include/zephyr/crypto/crypto.h +++ b/include/zephyr/crypto/crypto.h @@ -325,7 +325,6 @@ static inline int cipher_ctr_op(struct cipher_ctx *ctx, { __ASSERT(ctx->ops.cipher_mode == CRYPTO_CIPHER_MODE_CTR, "CTR mode " "session invoking a different mode handler"); - pkt->ctx = ctx; return ctx->ops.ctr_crypt_hndlr(ctx, pkt, iv); } diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 946123db7935f..2a977f95fb37f 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -596,7 +596,7 @@ void pufs_decryption_test(const struct device *pufs) CAP_NO_IV_PREFIX | CAP_NO_ENCRYPTION ); - lvCipherCtx.key.bit_stream = enc32_key; + lvCipherCtx.key.bit_stream = &enc32_key[0]; lvCipherCtx.key_source = CRYPTO_KEY_SW; lvCipherCtx.keylen = 32; lvCipherCtx.mode_params.ctr_info.ctr_len = 16; @@ -605,9 +605,9 @@ void pufs_decryption_test(const struct device *pufs) lvCipherPkt.auto_increment = true; lvCipherPkt.ctx = &lvCipherCtx; - lvCipherPkt.in_buf = cipher_text; - lvCipherPkt.in_len = strlen(cipher_text); - lvCipherPkt.out_buf = decrypted_text; + lvCipherPkt.in_buf = (uint8_t*)cipher_text; + lvCipherPkt.in_len = (sizeof(cipher_text)/sizeof(cipher_text[0])); + lvCipherPkt.out_buf = (uint8_t*)&decrypted_text[0]; lvCipherPkt.prev_len = 0; printf("%s Decrypting %d bytes %s\n", ATTR_INF, lvCipherPkt.in_len, ATTR_RST); @@ -622,14 +622,24 @@ void pufs_decryption_test(const struct device *pufs) if(lvStatus != 0) { printf("%s cipher_begin_session Failed! %s\n", ATTR_ERR, ATTR_RST); } else { - printf("%s cipher_begin_session Success! %s\n", ATTR_ERR, ATTR_RST); + printf("%s cipher_begin_session Success! %s\n", ATTR_INF, ATTR_RST); + + printf("%s(%d) outAddress:0x%08x\r\n", __func__, __LINE__, (uint32_t)decrypted_text); + printf("OriginalPlaintext:%s\n", plain_text); + printf("OriginalPlaintext:%s\n", plain_text); } - lvStatus = cipher_ctr_op(&lvCipherCtx, &lvCipherPkt, iv); + lvStatus = cipher_ctr_op(&lvCipherCtx, &lvCipherPkt, (uint8_t*)iv); if(lvStatus != 0) { - printf("%s cipher_ctr_op Failed! %s\n", ATTR_ERR, ATTR_RST); + printf("%s cipher_ctr_op Failed! Status:%d %s\n", ATTR_ERR, lvStatus, ATTR_RST); } else { - printf("%s cipher_ctr_op Success! %s\n", ATTR_ERR, ATTR_RST); + printf("%s cipher_ctr_op Success! %s\n", ATTR_INF, ATTR_RST); + printf("Decrypted:%d bytes Got:%s\n", lvCipherPkt.out_len, lvCipherPkt.out_buf); + if(strcmp(plain_text, decrypted_text) != 0) { + printf("%s cipher decryption Failed! %s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%s cipher decryption Passed! %s\n", ATTR_INF, ATTR_RST); + } } lvStatus = cipher_free_session(pufs, &lvCipherCtx); From 3cbe6fe541376c8be95de83130aff7222c67bf47 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 8 Oct 2024 15:18:18 +0500 Subject: [PATCH 40/58] Decryption test passed! --- drivers/crypto/crypto_pufs.c | 9 ++- drivers/crypto/pufcc.c | 3 +- samples/hello_world/src/main.c | 119 ++++++++++++++++++++------------- 3 files changed, 82 insertions(+), 49 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 8be661544646d..565e2cfd97729 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -164,16 +164,23 @@ static int pufs_query_hw_caps(const struct device *dev) static int pufs_ctr_op(struct cipher_ctx *ctx, struct cipher_pkt *pkt, uint8_t *ctr) { enum pufcc_status lvStatus = PUFCC_SUCCESS; + enum pufcc_dma_rw_type write_type; ((struct pufs_data*)ctx->device->data)->pufs_pkt.cipher_pkt = pkt; ((struct pufs_data*)ctx->device->data)->pufs_ctx.cipher_ctx = ctx; + + if(pkt->auto_increment) { + write_type = AUTO_INCREMENT; + } else { + write_type = FIXED_RW; + } lvStatus = pufcc_decrypt_aes( (uint32_t)pkt->out_buf, (uint32_t)pkt->in_buf, (uint32_t)pkt->in_len, pkt->prev_len, ctx->key_source, (uint32_t)ctx->key.bit_stream, ctx->keylen, (uint32_t)ctr, (uint32_t)ctx->mode_params.ctr_info.ctr_len, - pkt->auto_increment, ctx->mode_params.ctr_info.readback_ctr + write_type, ctx->mode_params.ctr_info.readback_ctr ); if(lvStatus != PUFCC_SUCCESS) { diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 57735c25218a1..4b8afd4831fff 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -392,8 +392,7 @@ enum pufcc_status pufcc_decrypt_aes(uint32_t out_addr, uint32_t in_addr, bool readback_iv) { enum pufcc_status status; uint32_t temp32; - printf("%s(%d) outAddress:0x%08x inLength:%d in_addr:0x%08x keylen:%d key_addr:0x%08x key_type:%d\r\n", \ - __func__, __LINE__, out_addr, in_len, in_addr, key_len, key_addr, key_type); + // Configure DMA intrpt register temp32 = 0; struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 2a977f95fb37f..e502006f4dd51 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -17,6 +17,7 @@ #define ATTR_INF "\x1b[32;1m" // ANSI_COLOR_GREEN #define ATTR_ERR "\x1b[31;1m" // ANSI_COLOR_RED #define ATTR_RST "\x1b[37;1m" // ANSI_COLOR_RESET +#define ATTR_HIL "\x1b[33;1m" // ANSI_COLOR_HIGHLIGHT #define FLASH_RW_SIZE 255 #define FLASH_BASE_ADDR 0xB0000000 @@ -545,47 +546,66 @@ void pufs_decryption_test(const struct device *pufs) { /* Plain Text: This is Junaid Aslam from Rapid Silicon doing Decryption Test... - IV: 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f - Key: 0x30,0x13,0x53,0x33,0x44,0x12,0xff,0x22,0x31,0x53,0xbb,0x13,0x07,0x19,0x84,0x0d,0xd5,0x3c,0x3f,0xc0,0x09,0x83,0x11,0x35,0x30,0x2d,0xdc,0xc0,0x0b,0xb9,0x4e,0x30 - - Cipher Text: 0x9c,0x87,0xe4,0xef,0xd5,0xeb,0xf3,0xb7,0xb6,0xff,0x58,0xfb,0x05,0x5b,0x26,0xa5,0x61,0xd9,0xaa,0xf4,0xa1,0x3c,0xb2,0x28,0x94,0xe3,0x49, - 0x91,0xba,0xc0,0x46,0x83,0x60,0x86,0xb2,0x6e,0xf0,0x59,0xa6,0x6c,0xc8,0x21,0xb1,0x4f,0xfc,0x55,0x6a,0x45,0x8a,0x1d,0xd8,0x03,0x48,0xc3,0xe4,0x68,0x32, - 0xd8,0x7e,0x40,0x9e,0xf7,0x88,0x57 + IV: 0xaa,0x34,0x55,0x32,0xe9,0x58,0xaa,0xf3,0xc0,0xde,0x20,0xa6,0xa9,0x21,0x44,0xe8 + Key: + 0x30,0x13,0x53,0x33,0x44,0x12,0xff,0x22,0x31,0x53,0xbb,0x13,0x07,0x19,0x84,0x0d, + 0xd5,0x3c,0x3f,0xc0,0x09,0x83,0x11,0x35,0x30,0x2d,0xdc,0xc0,0x0b,0xb9,0x4e,0x30 + + Cipher Text: + 0xd0,0x07,0x29,0x7b,0x56,0x2c,0x2c,0xa7, + 0x43,0x24,0x68,0xd8,0x58,0xb4,0xc1,0x9f, + 0x7c,0x05,0x7c,0x98,0x03,0x28,0x19,0x9d, + 0x93,0xff,0x85,0xd7,0xdb,0x8f,0xf1,0x07, + 0x18,0xa5,0x1f,0x99,0x04,0x73,0x84,0x4f, + 0x4f,0x79,0xba,0x2e,0x70,0x82,0xb1,0x39, + 0x5d,0x3f,0x3e,0xf8,0x44,0x81,0xf6,0x89, + 0x17,0x3a,0x29,0x43,0x0a,0x41,0x24,0xff, + 0x57,0xa8,0xbb,0x0b,0x0e,0xcf,0xb3,0xed, + 0x8e,0x1d,0x49,0x03,0x86,0x77,0x61,0x68, + 0x59,0x7c,0xf0,0x61,0x98,0x11,0x1b,0xe5, + 0xe3,0x95,0x6d,0x81,0x49,0xdc,0xa0,0x4b, + 0x97,0xb4,0xe6,0x40,0xd5,0x26,0xb6,0xb7, + 0xd8,0xab,0x61,0xc1,0xa7,0x5a,0xdc,0x5e, + 0xa9,0x25,0x6f,0xcd,0x25,0xb6,0xd0,0x42, + 0xa1,0xd8,0xd5,0xdc,0xcf,0xc6,0xaa,0xdf */ int lvStatus = 0; + struct cipher_ctx lvCipherCtx = {0}; struct cipher_pkt lvCipherPkt = {0}; - const uint8_t enc32_key[] = { - 0x30,0x13,0x53,0x33, - 0x44,0x12,0xff,0x22, - 0x31,0x53,0xbb,0x13, - 0x07,0x19,0x84,0x0d, - 0xd5,0x3c,0x3f,0xc0, - 0x09,0x83,0x11,0x35, - 0x30,0x2d,0xdc,0xc0, - 0x0b,0xb9,0x4e,0x30 + uint8_t enc32_key[] = { + 0x30,0x13,0x53,0x33,0x44,0x12,0xff,0x22, + 0x31,0x53,0xbb,0x13,0x07,0x19,0x84,0x0d, + 0xd5,0x3c,0x3f,0xc0,0x09,0x83,0x11,0x35, + 0x30,0x2d,0xdc,0xc0,0x0b,0xb9,0x4e,0x30 }; - const uint8_t iv[] = { - 0x00,0x01,0x02,0x03, - 0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b, - 0x0c,0x0d,0x0e,0x0f + uint8_t iv[] = { + 0xaa,0x34,0x55,0x32,0xe9,0x58,0xaa,0xf3, + 0xc0,0xde,0x20,0xa6,0xa9,0x21,0x44,0xe8 }; - const uint8_t cipher_text[] = { - 0x9c,0x87,0xe4,0xef,0xd5,0xeb,0xf3,0xb7, - 0xb6,0xff,0x58,0xfb,0x05,0x5b,0x26,0xa5, - 0x61,0xd9,0xaa,0xf4,0xa1,0x3c,0xb2,0x28, - 0x94,0xe3,0x49,0x91,0xba,0xc0,0x46,0x83, - 0x60,0x86,0xb2,0x6e,0xf0,0x59,0xa6,0x6c, - 0xc8,0x21,0xb1,0x4f,0xfc,0x55,0x6a,0x45, - 0x8a,0x1d,0xd8,0x03,0x48,0xc3,0xe4,0x68, - 0x32,0xd8,0x7e,0x40,0x9e,0xf7,0x88,0x57 - }; - - const uint8_t *plain_text = "This is Junaid Aslam from Rapid Silicon doing Decryption Test..."; - const uint8_t decrypted_text[256] = {0}; + uint8_t cipher_text[] = { + 0xd0,0x07,0x29,0x7b,0x56,0x2c,0x2c,0xa7, + 0x43,0x24,0x68,0xd8,0x58,0xb4,0xc1,0x9f, + 0x7c,0x05,0x7c,0x98,0x03,0x28,0x19,0x9d, + 0x93,0xff,0x85,0xd7,0xdb,0x8f,0xf1,0x07, + 0x18,0xa5,0x1f,0x99,0x04,0x73,0x84,0x4f, + 0x4f,0x79,0xba,0x2e,0x70,0x82,0xb1,0x39, + 0x5d,0x3f,0x3e,0xf8,0x44,0x81,0xf6,0x89, + 0x17,0x3a,0x29,0x43,0x0a,0x41,0x24,0xff, + 0x57,0xa8,0xbb,0x0b,0x0e,0xcf,0xb3,0xed, + 0x8e,0x1d,0x49,0x03,0x86,0x77,0x61,0x68, + 0x59,0x7c,0xf0,0x61,0x98,0x11,0x1b,0xe5, + 0xe3,0x95,0x6d,0x81,0x49,0xdc,0xa0,0x4b, + 0x97,0xb4,0xe6,0x40,0xd5,0x26,0xb6,0xb7, + 0xd8,0xab,0x61,0xc1,0xa7,0x5a,0xdc,0x5e, + 0xa9,0x25,0x6f,0xcd,0x25,0xb6,0xd0,0x42, + 0xa1,0xd8,0xd5,0xdc,0xcf,0xc6,0xaa,0xdf + }; + + uint8_t *plain_text = "Plain Text: This is Junaid Aslam from Rapid Silicon doing Decryption Test...\n"; + uint8_t decrypted_text[256] = {0}; lvCipherCtx.app_sessn_state = NULL; lvCipherCtx.device = pufs; @@ -596,7 +616,7 @@ void pufs_decryption_test(const struct device *pufs) CAP_NO_IV_PREFIX | CAP_NO_ENCRYPTION ); - lvCipherCtx.key.bit_stream = &enc32_key[0]; + lvCipherCtx.key.bit_stream = enc32_key; lvCipherCtx.key_source = CRYPTO_KEY_SW; lvCipherCtx.keylen = 32; lvCipherCtx.mode_params.ctr_info.ctr_len = 16; @@ -605,9 +625,9 @@ void pufs_decryption_test(const struct device *pufs) lvCipherPkt.auto_increment = true; lvCipherPkt.ctx = &lvCipherCtx; - lvCipherPkt.in_buf = (uint8_t*)cipher_text; + lvCipherPkt.in_buf = cipher_text; lvCipherPkt.in_len = (sizeof(cipher_text)/sizeof(cipher_text[0])); - lvCipherPkt.out_buf = (uint8_t*)&decrypted_text[0]; + lvCipherPkt.out_buf = decrypted_text; lvCipherPkt.prev_len = 0; printf("%s Decrypting %d bytes %s\n", ATTR_INF, lvCipherPkt.in_len, ATTR_RST); @@ -622,20 +642,27 @@ void pufs_decryption_test(const struct device *pufs) if(lvStatus != 0) { printf("%s cipher_begin_session Failed! %s\n", ATTR_ERR, ATTR_RST); } else { - printf("%s cipher_begin_session Success! %s\n", ATTR_INF, ATTR_RST); - - printf("%s(%d) outAddress:0x%08x\r\n", __func__, __LINE__, (uint32_t)decrypted_text); - printf("OriginalPlaintext:%s\n", plain_text); - printf("OriginalPlaintext:%s\n", plain_text); + printf("%s cipher_begin_session Success! %s\n", ATTR_INF, ATTR_RST); } lvStatus = cipher_ctr_op(&lvCipherCtx, &lvCipherPkt, (uint8_t*)iv); if(lvStatus != 0) { printf("%s cipher_ctr_op Failed! Status:%d %s\n", ATTR_ERR, lvStatus, ATTR_RST); } else { - printf("%s cipher_ctr_op Success! %s\n", ATTR_INF, ATTR_RST); - printf("Decrypted:%d bytes Got:%s\n", lvCipherPkt.out_len, lvCipherPkt.out_buf); - if(strcmp(plain_text, decrypted_text) != 0) { + printf("%s cipher_ctr_op Success! %s\n\n", ATTR_INF, ATTR_RST); + printf("%s Original: %s%s\n", ATTR_HIL,plain_text,ATTR_RST); + printf("%s Result: %s%s\n", ATTR_HIL,lvCipherPkt.out_buf,ATTR_RST); + bool comparison_ok = true; + for(int i = 0; i < strlen(lvCipherPkt.out_buf); i++) { + if(lvCipherPkt.out_buf[i] != plain_text[i]) { + // printf("Orig[%d]:0x%02x(%c) != Res[%d]:0x%02x(%c)\n", i, plain_text[i], plain_text[i], i, lvCipherPkt.out_buf[i], lvCipherPkt.out_buf[i]); + comparison_ok = false; break; + } + // else { + // printf("Orig[%d]:0x%02x(%c) == Res[%d]:0x%02x(%c)\n", i, plain_text[i], plain_text[i], i, lvCipherPkt.out_buf[i], lvCipherPkt.out_buf[i]); + // } + } + if(!comparison_ok) { printf("%s cipher decryption Failed! %s\n", ATTR_ERR, ATTR_RST); } else { printf("%s cipher decryption Passed! %s\n", ATTR_INF, ATTR_RST); @@ -646,7 +673,7 @@ void pufs_decryption_test(const struct device *pufs) if(lvStatus != 0) { printf("%s cipher_free_session Failed! %s\n", ATTR_ERR, ATTR_RST); } else { - printf("%s cipher_free_session Success! %s\n", ATTR_ERR, ATTR_RST); + printf("%s cipher_free_session Success! %s\n", ATTR_INF, ATTR_RST); } } @@ -677,7 +704,7 @@ int main(void) printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); - pufs_decryption_test(pufs); while(true); + pufs_decryption_test(pufs); pufs_hash_test(pufs); pufs_hash_sg_test(pufs); } From ef0ba411477e2fcb5c93d5da1c0a98d02fc22b94 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 10 Oct 2024 20:33:34 +0500 Subject: [PATCH 41/58] Updated the PUFcc RS_RTOS_PORT flag definition through KConfig --- drivers/crypto/Kconfig.pufs | 6 ++++ drivers/crypto/crypto_pufs.c | 21 ++++++----- drivers/crypto/pufcc.c | 64 +++++++++++++++++----------------- drivers/crypto/pufcc.h | 32 ++++++++--------- samples/hello_world/src/main.c | 59 ++++++++++++++++++------------- 5 files changed, 96 insertions(+), 86 deletions(-) diff --git a/drivers/crypto/Kconfig.pufs b/drivers/crypto/Kconfig.pufs index 719fbe00f160c..0170695c1d874 100644 --- a/drivers/crypto/Kconfig.pufs +++ b/drivers/crypto/Kconfig.pufs @@ -5,15 +5,20 @@ menuconfig PUFCC_SECURITY bool "PUF Security Hardware" + depends on DT_HAS_PUFSECURITY_PUFCC_ENABLED help Enable PUF Security Hardware. if PUFCC_SECURITY + config RS_RTOS_PORT + bool + config CRYPTO_PUF_SECURITY bool "PUF security Cryptographic Accelerator driver" default n depends on DT_HAS_PUFSECURITY_PUFCC_ENABLED + select RS_RTOS_PORT help Enable PUF Security based Cryptographic Accelerator driver. @@ -21,6 +26,7 @@ menuconfig PUFCC_SECURITY bool "PUF security One Time Programmable Memory" default n depends on DT_HAS_PUFSECURITY_OTP_ENABLED + select RS_RTOS_PORT help Enable PUF Security based One Time Programmable Memory. diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 565e2cfd97729..baa78c0233710 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -201,12 +201,11 @@ static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; - uint16_t lvHashFlags = ( + uint16_t lvHashFlagsMask = ( CAP_NO_ENCRYPTION | CAP_SYNC_OPS | CAP_NO_IV_PREFIX | CAP_RAW_KEY | CAP_SEPARATE_IO_BUFS - ), \ - lvHashFlagsMask = 0xFFFF; + ); if(algo != CRYPTO_CIPHER_ALGO_AES) { LOG_ERR("%s(%d) UnSupported Algo. Only AES Supported\n", __func__, __LINE__); @@ -225,8 +224,8 @@ static int pufs_cipher_begin_session(const struct device *dev, struct cipher_ctx return -ENOTSUP; } - if((ctx->flags & lvHashFlagsMask) != (lvHashFlags)) { - LOG_ERR("%s(%d) UnSupported Flags. Supported Flags_Mask:%d\n", __func__, __LINE__, lvHashFlags); + if(ctx->flags & (~lvHashFlagsMask)) { + LOG_ERR("%s(%d) UnSupported Flags. Supported Flags_Mask:%d\n", __func__, __LINE__, lvHashFlagsMask); return -ENOTSUP; } @@ -371,15 +370,15 @@ static int pufs_hash_begin_session(const struct device *dev, struct hash_ctx *ct struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; - uint16_t lvHashFlags = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS), lvHashFlagsMask = 0xFFFF; + uint16_t lvHashFlagsMask = (CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS); if(algo != CRYPTO_HASH_ALGO_SHA256) { LOG_ERR("%s(%d) UnSupported Hash Algo. Only SHA256 Supported\n", __func__, __LINE__); return -ENOTSUP; } - if((ctx->flags & lvHashFlagsMask) != (lvHashFlags)) { - LOG_ERR("%s(%d) UnSupported Flags. Supported Flags_Mask:%d\n", __func__, __LINE__, lvHashFlags); + if((ctx->flags & (~lvHashFlagsMask))) { + LOG_ERR("%s(%d) UnSupported Flags. Supported Flags_Mask:%d\n", __func__, __LINE__, lvHashFlagsMask); return -ENOTSUP; } @@ -502,7 +501,7 @@ static int pufs_sign_begin_session(const struct device *dev, struct sign_ctx *ct struct pufs_data *lvPufsData = (struct pufs_data*)dev->data; - uint16_t lvHashFlags = (CAP_INPLACE_OPS | CAP_SYNC_OPS), lvHashFlagsMask = 0xFFFF; + uint16_t lvHashFlagsMask = (CAP_INPLACE_OPS | CAP_SYNC_OPS); if((algo != CRYPTO_SIGN_ALGO_ECDSA256) || (algo != CRYPTO_SIGN_ALGO_RSA2048)) { LOG_ERR("%s(%d) Unupported Algo:%d. Supported Algo \n", __func__, __LINE__, algo); @@ -517,8 +516,8 @@ static int pufs_sign_begin_session(const struct device *dev, struct sign_ctx *ct } } - if((ctx->flags & lvHashFlagsMask) != (lvHashFlags)) { - LOG_ERR("%s(%d) UnSupported Flags. Supported Flags_Mask:%d\n", __func__, __LINE__, lvHashFlags); + if((ctx->flags & (~lvHashFlagsMask))) { + LOG_ERR("%s(%d) UnSupported Flags. Supported Flags_Mask:%d\n", __func__, __LINE__, lvHashFlagsMask); return -ENOTSUP; } diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 4b8afd4831fff..bef66ac5329fc 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -2,24 +2,24 @@ #include -#ifndef RS_RTOS_PORT - #include "profiling_util.h" - #include "rs_crypto.h" - #include "rs_util.h" -#else +#if CONFIG_RS_RTOS_PORT #include #include #include "crypto_pufs.h" static volatile bool s_Asynch_Operation = false; void pufcc_set_asynch_ops_flag(bool Val) {s_Asynch_Operation = Val;} bool pufcc_get_asynch_ops_flag(void) {return s_Asynch_Operation;} +#else + #include "profiling_util.h" + #include "rs_crypto.h" + #include "rs_util.h" #endif /***************************************************************************** * Macros ****************************************************************************/ #define SG_DMA_MAX_DSCS_SIZE (512 - 8) // Enough for 15 descriptors -#ifndef RS_RTOS_PORT +#if !CONFIG_RS_RTOS_PORT #define BUFFER_SIZE 512 #endif #define PUFCC_MAX_BUSY_COUNT 8000000 // Max busy count for processing 10MB data @@ -28,13 +28,13 @@ /***************************************************************************** * Local variable declarations ****************************************************************************/ -#ifndef RS_RTOS_PORT - extern uint32_t __pufcc_descriptors; +#if CONFIG_RS_RTOS_PORT static struct pufcc_sg_dma_desc *sg_dma_descs = - (struct pufcc_sg_dma_desc *)&__pufcc_descriptors; + (struct pufcc_sg_dma_desc *)__pufcc_descriptors; #else + extern uint32_t __pufcc_descriptors; static struct pufcc_sg_dma_desc *sg_dma_descs = - (struct pufcc_sg_dma_desc *)__pufcc_descriptors; + (struct pufcc_sg_dma_desc *)&__pufcc_descriptors; #endif @@ -586,7 +586,7 @@ enum pufcc_status pufcc_ecdsa256_sign_verify( return PUFCC_E_ERROR; } -#ifndef RS_RTOS_PORT +#if !CONFIG_RS_RTOS_PORT RS_PROFILE_CHECKPOINT("msg hash calc"); #endif @@ -648,7 +648,7 @@ enum pufcc_status pufcc_ecdsa256_sign_verify( memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_S_OFFSET, pufcc_buffer, PUFCC_ECDSA_256_LEN); -#ifndef RS_RTOS_PORT +#if !CONFIG_RS_RTOS_PORT RS_PROFILE_CHECKPOINT("misc verif ops"); #endif @@ -666,14 +666,14 @@ enum pufcc_status pufcc_ecdsa256_sign_verify( // Poll on busy status status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); -#ifndef RS_RTOS_PORT +#if !CONFIG_RS_RTOS_PORT RS_PROFILE_CHECKPOINT("PKC op"); #endif return status; } -#ifndef RS_RTOS_PORT +#if !CONFIG_RS_RTOS_PORT /** * @fn pufcc_dma_transfer @@ -971,7 +971,21 @@ enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, return PUFCC_SUCCESS; } -#ifndef RS_RTOS_PORT +#if CONFIG_RS_RTOS_PORT + + int pufcc_clear_and_disable_intr(void) { + int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); + struct pufcc_intrpt_reg *intrpt_reg_ptr = + (struct pufcc_intrpt_reg *)&dma_regs->interrupt; + + // Clear and disable interrupt + intrpt_reg_ptr->intrpt_st = 1; // Set to clear + intrpt_reg_ptr->intrpt_en = 0; + + return status; + } + +#else int pufcc_dma_request_channel(struct pufcc_dma_dev *dev) { if (dev->is_dev_free) { @@ -1164,20 +1178,6 @@ enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, dev->callback(dev->callback_args, 0, status); } -#else - - int pufcc_clear_and_disable_intr(void) { - int status = (dma_regs->status_0 & PUFCC_DMA_ERROR_MASK ? -1 : 0); - struct pufcc_intrpt_reg *intrpt_reg_ptr = - (struct pufcc_intrpt_reg *)&dma_regs->interrupt; - - // Clear and disable interrupt - intrpt_reg_ptr->intrpt_st = 1; // Set to clear - intrpt_reg_ptr->intrpt_en = 0; - - return status; - } - #endif /** @@ -1315,10 +1315,10 @@ static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, int32_t busy_count = PUFCC_MAX_BUSY_COUNT; do { - #ifndef RS_RTOS_PORT - status = read_reg(status_reg_addr); - #else + #if CONFIG_RS_RTOS_PORT status = sys_read32((mem_addr_t)status_reg_addr); + #else + status = read_reg(status_reg_addr); #endif busy_count--; } while ((status & PUFCC_BUSY_BIT_MASK) && (busy_count > 0)); diff --git a/drivers/crypto/pufcc.h b/drivers/crypto/pufcc.h index 286aaf6fb7111..565332a113b94 100644 --- a/drivers/crypto/pufcc.h +++ b/drivers/crypto/pufcc.h @@ -3,14 +3,12 @@ #include -#define RS_RTOS_PORT - -#ifndef RS_RTOS_PORT - #include "rs_crypto.h" - #include "rs_dma.h" -#else +#if CONFIG_RS_RTOS_PORT #include #include +#else + #include "rs_crypto.h" + #include "rs_dma.h" #endif /*** Generic PUFcc defines ***/ @@ -164,7 +162,7 @@ enum pufcc_otp_slot { PUFCC_OTPKEY_29, // OTP key slot 29, 256 bits PUFCC_OTPKEY_30, // OTP key slot 30, 256 bits PUFCC_OTPKEY_31, // OTP key slot 31, 256 bits -#ifdef RS_RTOS_PORT +#if CONFIG_RS_RTOS_PORT PUFCC_TOTAL_SLOTS // OTP Number of slots. #endif }; @@ -437,7 +435,7 @@ struct pufcc_pkc_regs { volatile uint32_t ecp_data[512]; }; -#ifndef RS_RTOS_PORT +#if !CONFIG_RS_RTOS_PORT struct pufcc_dma_dev { struct pufcc_dma_regs *regs; bool is_dev_free; @@ -448,7 +446,7 @@ struct pufcc_pkc_regs { }; #endif -#ifdef RS_RTOS_PORT +#if CONFIG_RS_RTOS_PORT /** * @enum rs_crypto_tfr_type @@ -595,13 +593,13 @@ enum pufcc_status pufcc_ecdsa256_sign_verify( struct rs_crypto_ec256_sig *sig, struct rs_crypto_addr *msg_addr, struct rs_crypto_ec256_puk *pub_key); -#ifndef RS_RTOS_PORT +#if CONFIG_RS_RTOS_PORT + bool pufcc_get_asynch_ops_flag(void); + void pufcc_set_asynch_ops_flag(bool Val); +#else enum pufcc_status pufcc_dma_transfer(uint32_t src_addr, uint32_t dest_addr, uint32_t len, bool fixed_read, bool fixed_write); -#else - bool pufcc_get_asynch_ops_flag(void); - void pufcc_set_asynch_ops_flag(bool Val); #endif enum pufcc_status pufcc_otp_setup_wait(void); @@ -620,7 +618,9 @@ enum pufcc_status pufcc_zeroize_otp(enum pufcc_otp_slot otp_slot); enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, enum pufcc_otp_lock *lock_val); -#ifndef RS_RTOS_PORT +#if CONFIG_RS_RTOS_PORT + int pufcc_clear_and_disable_intr(void); +#else int pufcc_dma_request_channel(struct pufcc_dma_dev *dev); void pufcc_dma_release_channel(struct pufcc_dma_dev *dev, int channel); @@ -637,10 +637,6 @@ enum pufcc_status pufcc_get_otp_rwlck(enum pufcc_otp_slot otp_slot, enum rs_status pufcc_dma_stop_xfer(struct pufcc_dma_dev *dev, int channel); void pufcc_dma_irq_handler(struct pufcc_dma_dev *dev); -#else - - int pufcc_clear_and_disable_intr(void); - #endif enum pufcc_status pufcc_init(uint32_t base_addr); diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index e502006f4dd51..c68430e3d2ef4 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -67,9 +67,9 @@ void Flash_Test(const struct device *flash, const struct device *dma, uint32_t F printf("%s Writing the following data After Erasing Flash%s\n", ATTR_INF,ATTR_RST); for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { flash_data_write[i] = ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1)+((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1); - printf("%s %d%s", ATTR_INF, flash_data_write[i],i%FORMATTER==0?"\n":""); + // printf("%s %d%s", ATTR_INF, flash_data_write[i],i%FORMATTER==0?"\n":""); } - printf("\n"); + // printf("\n"); errorcode = flash_write(flash, FLASH_ADDR, flash_data_write, FLASH_RW_SIZE); } @@ -110,9 +110,9 @@ void Flash_Test(const struct device *flash, const struct device *dma, uint32_t F printf("%s %d%s", ATTR_ERR, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); memmaptestfail = true; } - else { - printf("%s %d%s", ATTR_INF, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); - } + // else { + // printf("%s %d%s", ATTR_INF, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + // } } printf("\n"); if(memmaptestfail) { printf("%s CPU Memory mapped read failed\n", ATTR_ERR); @@ -194,9 +194,9 @@ void Flash_Test(const struct device *flash, const struct device *dma, uint32_t F printf("%s %d%s", ATTR_ERR, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); memmaptestfail = true; } - else { - printf("%s %d%s", ATTR_INF, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); - } + // else { + // printf("%s %d%s", ATTR_INF, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); + // } } printf("\n"); if(memmaptestfail) { @@ -347,7 +347,6 @@ void pufs_otp_test(const struct device *pufs_otp) } } - void pufs_hash_sg_test(const struct device *pufs) { int status = 0; @@ -439,14 +438,14 @@ void pufs_hash_sg_test(const struct device *pufs) } else { for(uint8_t i = 0; i < lvHashPkt1.out_len; i++) { if(lvHashPkt1.out_buf[i] != pufs_sample_data_sha256[i]) { - printf("%s%s(%d) out_buf[%d]0x%02x != in_buf[%d]:0x%02x %s\n", \ - ATTR_ERR,__func__,__LINE__,\ - i,lvHashPkt1.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); + // printf("%s%s(%d) out_buf[%d]0x%02x != in_buf[%d]:0x%02x %s\n", + // ATTR_ERR,__func__,__LINE__, + // i,lvHashPkt1.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); status = -EINVAL; } else { - printf("%s%s(%d) out_buf[%d]0x%02x == in_buf[%d]:0x%02x %s\n", \ - ATTR_INF,__func__,__LINE__,\ - i,lvHashPkt1.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); + // printf("%s%s(%d) out_buf[%d]0x%02x == in_buf[%d]:0x%02x %s\n", + // ATTR_INF,__func__,__LINE__, + // i,lvHashPkt1.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); } } if(status != 0) { @@ -467,7 +466,6 @@ void pufs_hash_sg_test(const struct device *pufs) } } - void pufs_hash_test(const struct device *pufs) { int status = 0; @@ -514,14 +512,14 @@ void pufs_hash_test(const struct device *pufs) } else { for(uint8_t i = 0; i < lvHashPkt.out_len; i++) { if(lvHashPkt.out_buf[i] != pufs_sample_data_sha256[i]) { - printf("%s%s(%d) out_buf[%d]0x%02x != in_buf[%d]:0x%02x %s\n", \ - ATTR_ERR,__func__,__LINE__,\ - i,lvHashPkt.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); + // printf("%s%s(%d) out_buf[%d]0x%02x != in_buf[%d]:0x%02x %s\n", + // ATTR_ERR,__func__,__LINE__, + // i,lvHashPkt.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); status = -EINVAL; } else { - printf("%s%s(%d) out_buf[%d]0x%02x == in_buf[%d]:0x%02x %s\n", \ - ATTR_INF,__func__,__LINE__,\ - i,lvHashPkt.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); + // printf("%s%s(%d) out_buf[%d]0x%02x == in_buf[%d]:0x%02x %s\n", + // ATTR_INF,__func__,__LINE__, + // i,lvHashPkt.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); } } if(status != 0) { @@ -649,9 +647,9 @@ void pufs_decryption_test(const struct device *pufs) if(lvStatus != 0) { printf("%s cipher_ctr_op Failed! Status:%d %s\n", ATTR_ERR, lvStatus, ATTR_RST); } else { - printf("%s cipher_ctr_op Success! %s\n\n", ATTR_INF, ATTR_RST); - printf("%s Original: %s%s\n", ATTR_HIL,plain_text,ATTR_RST); - printf("%s Result: %s%s\n", ATTR_HIL,lvCipherPkt.out_buf,ATTR_RST); + printf("%s cipher_ctr_op Success! %s\n", ATTR_INF, ATTR_RST); + printf("%s Original: %s%s", ATTR_HIL,plain_text,ATTR_RST); + printf("%s Result: %s%s", ATTR_HIL,lvCipherPkt.out_buf,ATTR_RST); bool comparison_ok = true; for(int i = 0; i < strlen(lvCipherPkt.out_buf); i++) { if(lvCipherPkt.out_buf[i] != plain_text[i]) { @@ -677,6 +675,16 @@ void pufs_decryption_test(const struct device *pufs) } } +void pufs_rsa2048_verify_test(const struct device *dev) +{ + +} + +void pufs_ecdsa256_verify_test(const struct device *dev) +{ + +} + int main(void) { int Cnt = 0; @@ -704,6 +712,7 @@ int main(void) printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); + // pufs_rsa2048_verify_test(pufs); while(true); // TODO Remove while pufs_decryption_test(pufs); pufs_hash_test(pufs); pufs_hash_sg_test(pufs); From db8f147281e48794462a98ddc559c9d1ba2714a6 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 10 Oct 2024 20:39:18 +0500 Subject: [PATCH 42/58] RSA2048 signature verification in progress --- samples/hello_world/src/main.c | 33 ++++++++------------------------- 1 file changed, 8 insertions(+), 25 deletions(-) diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index c68430e3d2ef4..7864c247da5fc 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -542,31 +542,6 @@ void pufs_hash_test(const struct device *pufs) void pufs_decryption_test(const struct device *pufs) { - /* - Plain Text: This is Junaid Aslam from Rapid Silicon doing Decryption Test... - IV: 0xaa,0x34,0x55,0x32,0xe9,0x58,0xaa,0xf3,0xc0,0xde,0x20,0xa6,0xa9,0x21,0x44,0xe8 - Key: - 0x30,0x13,0x53,0x33,0x44,0x12,0xff,0x22,0x31,0x53,0xbb,0x13,0x07,0x19,0x84,0x0d, - 0xd5,0x3c,0x3f,0xc0,0x09,0x83,0x11,0x35,0x30,0x2d,0xdc,0xc0,0x0b,0xb9,0x4e,0x30 - - Cipher Text: - 0xd0,0x07,0x29,0x7b,0x56,0x2c,0x2c,0xa7, - 0x43,0x24,0x68,0xd8,0x58,0xb4,0xc1,0x9f, - 0x7c,0x05,0x7c,0x98,0x03,0x28,0x19,0x9d, - 0x93,0xff,0x85,0xd7,0xdb,0x8f,0xf1,0x07, - 0x18,0xa5,0x1f,0x99,0x04,0x73,0x84,0x4f, - 0x4f,0x79,0xba,0x2e,0x70,0x82,0xb1,0x39, - 0x5d,0x3f,0x3e,0xf8,0x44,0x81,0xf6,0x89, - 0x17,0x3a,0x29,0x43,0x0a,0x41,0x24,0xff, - 0x57,0xa8,0xbb,0x0b,0x0e,0xcf,0xb3,0xed, - 0x8e,0x1d,0x49,0x03,0x86,0x77,0x61,0x68, - 0x59,0x7c,0xf0,0x61,0x98,0x11,0x1b,0xe5, - 0xe3,0x95,0x6d,0x81,0x49,0xdc,0xa0,0x4b, - 0x97,0xb4,0xe6,0x40,0xd5,0x26,0xb6,0xb7, - 0xd8,0xab,0x61,0xc1,0xa7,0x5a,0xdc,0x5e, - 0xa9,0x25,0x6f,0xcd,0x25,0xb6,0xd0,0x42, - 0xa1,0xd8,0xd5,0xdc,0xcf,0xc6,0xaa,0xdf - */ int lvStatus = 0; struct cipher_ctx lvCipherCtx = {0}; @@ -677,6 +652,14 @@ void pufs_decryption_test(const struct device *pufs) void pufs_rsa2048_verify_test(const struct device *dev) { + int lvStatus = 0; + + struct sign_ctx lvCipherCtx = {0}; + struct sign_pkt lvCipherPkt = {0}; + + const uint8_t pub_key[272] = {0}; // TODO Fill + const uint8_t sig[256] = {0}; // TODO Fill + const uint8_t *in_buf = "RSA2048 Signature Verification Test"; } From f0a97a74e674c6f1e7071c03a833a274af57a483 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 11 Oct 2024 21:38:52 +0500 Subject: [PATCH 43/58] RSA2048 signature verification in progress --- samples/hello_world/src/main.c | 722 +++++++++++++++++---------------- 1 file changed, 376 insertions(+), 346 deletions(-) diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 7864c247da5fc..bfd32453b44e1 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -14,115 +14,137 @@ #include -#define ATTR_INF "\x1b[32;1m" // ANSI_COLOR_GREEN -#define ATTR_ERR "\x1b[31;1m" // ANSI_COLOR_RED -#define ATTR_RST "\x1b[37;1m" // ANSI_COLOR_RESET -#define ATTR_HIL "\x1b[33;1m" // ANSI_COLOR_HIGHLIGHT +#define ATTR_INF "\x1b[32;1m" // ANSI_COLOR_GREEN +#define ATTR_ERR "\x1b[31;1m" // ANSI_COLOR_RED +#define ATTR_RST "\x1b[37;1m" // ANSI_COLOR_RESET +#define ATTR_HIL "\x1b[33;1m" // ANSI_COLOR_HIGHLIGHT -#define FLASH_RW_SIZE 255 +#define FLASH_RW_SIZE 255 #define FLASH_BASE_ADDR 0xB0000000 -void Flash_Test(const struct device *flash, const struct device *dma, uint32_t FLASH_ADDR, uint8_t EVEN_ODD_MUL, uint8_t FORMATTER) { +void Flash_Test(const struct device *flash, const struct device *dma, uint32_t FLASH_ADDR, + uint8_t EVEN_ODD_MUL, uint8_t FORMATTER) +{ int errorcode = 0; uint8_t flash_data_write[FLASH_RW_SIZE] = {0}; uint8_t flash_data_read[FLASH_RW_SIZE] = {0}; errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE); - if(errorcode < 0) { - printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode,ATTR_RST); - } - else { - printf("%s Reading Back Before Erasing Flash%s\n", ATTR_INF,ATTR_RST); + if (errorcode < 0) { + printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode, + ATTR_RST); + } else { + printf("%s Reading Back Before Erasing Flash%s\n", ATTR_INF, ATTR_RST); // for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { // printf("%s %d%s", ATTR_INF, flash_data_read[i],i%FORMATTER==0?"\n":""); // } printf("\n"); } errorcode = flash_erase(flash, FLASH_ADDR, 0x1000); - if(errorcode < 0) { - printf("%s\nError Erasing the flash at 0x%08x offset errorcode:%d%s\n", ATTR_ERR, FLASH_ADDR, errorcode, ATTR_RST); + if (errorcode < 0) { + printf("%s\nError Erasing the flash at 0x%08x offset errorcode:%d%s\n", ATTR_ERR, + FLASH_ADDR, errorcode, ATTR_RST); } else { printf("%s\nSuccessfully Erased Flash\n", ATTR_RST); errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE); - if(errorcode < 0) { - printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode,ATTR_RST); + if (errorcode < 0) { + printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode, + ATTR_RST); } else { - printf("%s Reading Back After Erasing Area of Flash%s\n", ATTR_INF,ATTR_RST); - for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if(flash_data_read[i] != 0xff) { + printf("%s Reading Back After Erasing Area of Flash%s\n", ATTR_INF, + ATTR_RST); + for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if (flash_data_read[i] != 0xff) { errorcode = -1; } } } - if(errorcode == -1) { - printf("%s\nFlash erase at 0x%08x did not produce correct results%s\n", ATTR_ERR, FLASH_ADDR,ATTR_RST); + if (errorcode == -1) { + printf("%s\nFlash erase at 0x%08x did not produce correct results%s\n", + ATTR_ERR, FLASH_ADDR, ATTR_RST); // for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - // printf("%s 0x%02x%s", ATTR_INF, flash_data_read[i],i%FORMATTER==0?"\n":""); - // } printf("\n"); + // printf("%s 0x%02x%s", ATTR_INF, + // flash_data_read[i],i%FORMATTER==0?"\n":""); } printf("\n"); } else { - printf("%s\nSuccessfully performed erase to flash with code:%d%s\n", ATTR_INF, errorcode,ATTR_RST); + printf("%s\nSuccessfully performed erase to flash with code:%d%s\n", + ATTR_INF, errorcode, ATTR_RST); } errorcode = 0; } - if(errorcode == 0) { - printf("%s Writing the following data After Erasing Flash%s\n", ATTR_INF,ATTR_RST); - for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - flash_data_write[i] = ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1)+((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1); + if (errorcode == 0) { + printf("%s Writing the following data After Erasing Flash%s\n", ATTR_INF, ATTR_RST); + for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + flash_data_write[i] = ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1) + + ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1); // printf("%s %d%s", ATTR_INF, flash_data_write[i],i%FORMATTER==0?"\n":""); - } + } // printf("\n"); errorcode = flash_write(flash, FLASH_ADDR, flash_data_write, FLASH_RW_SIZE); } - if(errorcode < 0) { - printf("%s \nError writing to flash with code:%d%s\n", ATTR_ERR, errorcode,ATTR_RST); + if (errorcode < 0) { + printf("%s \nError writing to flash with code:%d%s\n", ATTR_ERR, errorcode, + ATTR_RST); } else { - printf("%s \nSuccessfully written to flash with code:%d Resetting the reading buffer....%s\n", ATTR_INF, errorcode,ATTR_RST); + printf("%s \nSuccessfully written to flash with code:%d Resetting the reading " + "buffer....%s\n", + ATTR_INF, errorcode, ATTR_RST); memset(flash_data_read, 0, FLASH_RW_SIZE); errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE); - if(errorcode < 0) { - printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode,ATTR_RST); + if (errorcode < 0) { + printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode, + ATTR_RST); } else { - printf("%s Successfully Read from flash with code:%d%s\n", ATTR_INF, errorcode,ATTR_RST); - bool Data_Validated = true; uint8_t Mismatch_count = 0; - for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if(flash_data_read[i] != flash_data_write[i]) { - Data_Validated = false; Mismatch_count++; - printf("%s %d - Read:%d != Write:%d%s\n", ATTR_ERR, i, flash_data_read[i], flash_data_write[i],ATTR_RST); - } + printf("%s Successfully Read from flash with code:%d%s\n", ATTR_INF, + errorcode, ATTR_RST); + bool Data_Validated = true; + uint8_t Mismatch_count = 0; + for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if (flash_data_read[i] != flash_data_write[i]) { + Data_Validated = false; + Mismatch_count++; + printf("%s %d - Read:%d != Write:%d%s\n", ATTR_ERR, i, + flash_data_read[i], flash_data_write[i], ATTR_RST); + } } - if(!Data_Validated) { - printf("%s Flash Integrity Check Failed With %d Mismatched Entries%s\n", ATTR_ERR,Mismatch_count,ATTR_RST); - } else{ - printf("%s Flash Integrity Check Passed!!!%s\n", ATTR_INF,ATTR_RST); + if (!Data_Validated) { + printf("%s Flash Integrity Check Failed With %d Mismatched " + "Entries%s\n", + ATTR_ERR, Mismatch_count, ATTR_RST); + } else { + printf("%s Flash Integrity Check Passed!!!%s\n", ATTR_INF, + ATTR_RST); } } } - if(errorcode == 0) - { - uint8_t *MemMapReadAddr = (uint8_t*)(FLASH_BASE_ADDR + FLASH_ADDR); + if (errorcode == 0) { + uint8_t *MemMapReadAddr = (uint8_t *)(FLASH_BASE_ADDR + FLASH_ADDR); uint8_t MemMapReadDestAddr[FLASH_RW_SIZE]; - { + { printf("CPU Memory Mapped Reading Test from address:%p\n", MemMapReadAddr); bool memmaptestfail = false; - for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if(MemMapReadAddr[i] != flash_data_write[i]) { - printf("%s %d%s", ATTR_ERR, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if (MemMapReadAddr[i] != flash_data_write[i]) { + printf("%s %d%s", ATTR_ERR, MemMapReadAddr[i], + i % FORMATTER == 0 ? "\n" : ""); memmaptestfail = true; - } + } // else { - // printf("%s %d%s", ATTR_INF, MemMapReadAddr[i],i%FORMATTER==0?"\n":""); + // printf("%s %d%s", ATTR_INF, + // MemMapReadAddr[i],i%FORMATTER==0?"\n":""); // } - } printf("\n"); - if(memmaptestfail) { - printf("%s CPU Memory mapped read failed\n", ATTR_ERR); + } + printf("\n"); + if (memmaptestfail) { + printf("%s CPU Memory mapped read failed\n", ATTR_ERR); } else { - printf("%s CPU Memory mapped read passed\n", ATTR_INF); + printf("%s CPU Memory mapped read passed\n", ATTR_INF); } - } + } - if(dma != NULL) { - printf("%s DMA Memory Mapped Reading Test from address:%p\n", ATTR_RST, MemMapReadAddr); + if (dma != NULL) { + printf("%s DMA Memory Mapped Reading Test from address:%p\n", ATTR_RST, + MemMapReadAddr); // Configure DMA Block struct dma_block_config lv_dma_block_config = { .block_size = FLASH_RW_SIZE, @@ -141,45 +163,42 @@ void Flash_Test(const struct device *flash, const struct device *dma, uint32_t F .source_gather_en = 0, .source_gather_interval = 0, .source_reload_en = 0, - ._reserved = 0 - }; + ._reserved = 0}; // Configure DMA - struct dma_config lv_Dma_Config = { - .block_count = 1, - .channel_direction = MEMORY_TO_MEMORY, - .channel_priority = 1, - .complete_callback_en = 0, - .cyclic = 0, - .dest_burst_length = 1, - .dest_chaining_en = 0, - .dest_data_size = 1, - .dest_handshake = 1, - .dma_callback = NULL, - .dma_slot = 0, - .error_callback_dis = 1, - .head_block = &lv_dma_block_config, - .linked_channel = 0, - .source_burst_length = 1, - .source_chaining_en = 0, - .source_data_size = 1, - .user_data = NULL - }; + struct dma_config lv_Dma_Config = {.block_count = 1, + .channel_direction = MEMORY_TO_MEMORY, + .channel_priority = 1, + .complete_callback_en = 0, + .cyclic = 0, + .dest_burst_length = 1, + .dest_chaining_en = 0, + .dest_data_size = 1, + .dest_handshake = 1, + .dma_callback = NULL, + .dma_slot = 0, + .error_callback_dis = 1, + .head_block = &lv_dma_block_config, + .linked_channel = 0, + .source_burst_length = 1, + .source_chaining_en = 0, + .source_data_size = 1, + .user_data = NULL}; struct dma_status stat = {0}; printf("%s DMA Configuration...\n", ATTR_RST); int dma_error = dma_config(dma, 1, &lv_Dma_Config); k_msleep(10); - if(dma_error) { + if (dma_error) { printf("%s Error %d Configuration...\n", ATTR_RST, dma_error); - } else { + } else { // Call DMA Read printf("%s DMA Starting...\n", ATTR_INF); dma_error = dma_start(dma, 1); k_msleep(10); } (void)dma_get_status(dma, 1, &stat); - while(stat.pending_length > 1) { + while (stat.pending_length > 1) { dma_error = dma_get_status(dma, 1, &stat); - if(dma_error) { + if (dma_error) { printf("Error %d dma_status...\n", dma_error); break; } else { @@ -187,22 +206,24 @@ void Flash_Test(const struct device *flash, const struct device *dma, uint32_t F } } - if(!dma_error) { + if (!dma_error) { bool memmaptestfail = false; - for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if(MemMapReadDestAddr[i] != flash_data_write[i]) { - printf("%s %d%s", ATTR_ERR, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); + for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if (MemMapReadDestAddr[i] != flash_data_write[i]) { + printf("%s %d%s", ATTR_ERR, MemMapReadDestAddr[i], + i % FORMATTER == 0 ? "\n" : ""); memmaptestfail = true; - } + } // else { - // printf("%s %d%s", ATTR_INF, MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); + // printf("%s %d%s", ATTR_INF, + // MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); // } - } + } printf("\n"); - if(memmaptestfail) { - printf("%s DMA Memory mapped read failed\n", ATTR_ERR); + if (memmaptestfail) { + printf("%s DMA Memory mapped read failed\n", ATTR_ERR); } else { - printf("%s DMA Memory mapped read passed\n", ATTR_INF); + printf("%s DMA Memory mapped read passed\n", ATTR_INF); } } else { printf("Error %d DMA Start...\n", dma_error); @@ -213,16 +234,14 @@ void Flash_Test(const struct device *flash, const struct device *dma, uint32_t F void CounterCallBack(const struct device *dev, void *UserData) { - uint32_t *lvData = ((uint32_t*)UserData); + uint32_t *lvData = ((uint32_t *)UserData); printf("\nandestech_atcpit100 %s # %d\n", __func__, *lvData); *lvData += 1; } -void CounterAlarmCallBack(const struct device *dev, - uint8_t chan_id, uint32_t ticks, - void *UserData) +void CounterAlarmCallBack(const struct device *dev, uint8_t chan_id, uint32_t ticks, void *UserData) { - uint32_t *lvData = ((uint32_t*)UserData); + uint32_t *lvData = ((uint32_t *)UserData); printf("\nandestech_atcpit100 %s # %d\n", __func__, *lvData); } @@ -234,22 +253,22 @@ void CounterTest(const struct device *pit) lvCntAlarmCfg.callback = CounterAlarmCallBack; lvCntAlarmCfg.flags = COUNTER_ALARM_CFG_EXPIRE_WHEN_LATE; lvCntAlarmCfg.ticks = 24000; - lvCntAlarmCfg.user_data = (void*)&s_CallBackData; + lvCntAlarmCfg.user_data = (void *)&s_CallBackData; struct counter_top_cfg lvCntTopCfg = {0}; lvCntTopCfg.callback = CounterCallBack; - lvCntTopCfg.user_data = (void*)&s_CallBackData; + lvCntTopCfg.user_data = (void *)&s_CallBackData; lvCntTopCfg.flags = COUNTER_TOP_CFG_DONT_RESET; lvCntTopCfg.ticks = 6000; int lvErrorCode = 0; - + lvErrorCode = counter_set_channel_alarm(pit, 0, &lvCntAlarmCfg); - if(lvErrorCode < 0) { - printf("%s%s(%d) counter Alarm set error code:%d %s\n", \ - ATTR_ERR,__func__,__LINE__,lvErrorCode,ATTR_RST); - } + if (lvErrorCode < 0) { + printf("%s%s(%d) counter Alarm set error code:%d %s\n", ATTR_ERR, __func__, + __LINE__, lvErrorCode, ATTR_RST); + } /* lvErrorCode = counter_set_top_value(pit, &lvCntTopCfg); if(lvErrorCode < 0) { @@ -268,81 +287,78 @@ void CounterTest(const struct device *pit) void pufs_otp_test(const struct device *pufs_otp) { uint8_t slot_data[32] = {0}; - enum crypto_otp_lock lvLock = CRYPTO_OTP_RW; + enum crypto_otp_lock lvLock = CRYPTO_OTP_RW; uint16_t totalSlots = 0, bytesPerSlot = 0; - if(otp_info(pufs_otp, &totalSlots, &bytesPerSlot) != 0) { - printf("%s%s(%d) OTP_Info Failed%s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + if (otp_info(pufs_otp, &totalSlots, &bytesPerSlot) != 0) { + printf("%s%s(%d) OTP_Info Failed%s\n", ATTR_ERR, __func__, __LINE__, ATTR_RST); } else { - printf("%s%s(%d) OTP_Info... Slots:%d Bytes Per Slot:%d%s\n", \ - ATTR_INF,__func__,__LINE__, totalSlots, bytesPerSlot, ATTR_RST); + printf("%s%s(%d) OTP_Info... Slots:%d Bytes Per Slot:%d%s\n", ATTR_INF, __func__, + __LINE__, totalSlots, bytesPerSlot, ATTR_RST); } - - if(otp_get_lock(pufs_otp, 12, &lvLock) != 0) { - printf("%s%s(%d) otp_get_lock Failed%s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + + if (otp_get_lock(pufs_otp, 12, &lvLock) != 0) { + printf("%s%s(%d) otp_get_lock Failed%s\n", ATTR_ERR, __func__, __LINE__, ATTR_RST); } else { - printf("%s%s(%d) otp_lock: %d %s\n", \ - ATTR_INF,__func__,__LINE__,lvLock,ATTR_RST); + printf("%s%s(%d) otp_lock: %d %s\n", ATTR_INF, __func__, __LINE__, lvLock, + ATTR_RST); } - for(uint8_t i = 0; i < bytesPerSlot; i++) { - slot_data[i] = (i+i)*2; + for (uint8_t i = 0; i < bytesPerSlot; i++) { + slot_data[i] = (i + i) * 2; } - if(otp_write(pufs_otp, 12, slot_data, 18) != 0) { - if(lvLock != CRYPTO_OTP_RW) { - printf("%s%s(%d) otp_write Failed as Expected %s\n", \ - ATTR_RST,__func__,__LINE__,ATTR_RST); + if (otp_write(pufs_otp, 12, slot_data, 18) != 0) { + if (lvLock != CRYPTO_OTP_RW) { + printf("%s%s(%d) otp_write Failed as Expected %s\n", ATTR_RST, __func__, + __LINE__, ATTR_RST); } else { - printf("%s%s(%d) otp_write Failed unExpectedly %s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + printf("%s%s(%d) otp_write Failed unExpectedly %s\n", ATTR_ERR, __func__, + __LINE__, ATTR_RST); } } else { - printf("%s%s(%d) otp_write Passed %s\n", \ - ATTR_RST,__func__,__LINE__,ATTR_RST); + printf("%s%s(%d) otp_write Passed %s\n", ATTR_RST, __func__, __LINE__, ATTR_RST); memset(slot_data, 0, bytesPerSlot); - if(otp_read(pufs_otp, 12, slot_data, 18) != 0) { - if(lvLock == CRYPTO_OTP_NA) { - printf("%s%s(%d) otp_read Failed as Expected %s\n", \ - ATTR_RST,__func__,__LINE__,ATTR_RST); + if (otp_read(pufs_otp, 12, slot_data, 18) != 0) { + if (lvLock == CRYPTO_OTP_NA) { + printf("%s%s(%d) otp_read Failed as Expected %s\n", ATTR_RST, + __func__, __LINE__, ATTR_RST); } else { - printf("%s%s(%d) otp_read Failed unExpectedly %s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + printf("%s%s(%d) otp_read Failed unExpectedly %s\n", ATTR_ERR, + __func__, __LINE__, ATTR_RST); } } else { - printf("%s",ATTR_INF); - for(uint8_t i = 0; i < bytesPerSlot; i++) { + printf("%s", ATTR_INF); + for (uint8_t i = 0; i < bytesPerSlot; i++) { printf("%d ", slot_data[i]); - } printf("\n"); - printf("%s",ATTR_RST); + } + printf("\n"); + printf("%s", ATTR_RST); } } - if(otp_set_lock(pufs_otp, 12, 18, CRYPTO_OTP_RO) != 0) { - printf("%s%s(%d) otp_set_lock Failed%s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + if (otp_set_lock(pufs_otp, 12, 18, CRYPTO_OTP_RO) != 0) { + printf("%s%s(%d) otp_set_lock Failed%s\n", ATTR_ERR, __func__, __LINE__, ATTR_RST); } else { - if(otp_get_lock(pufs_otp, 12, &lvLock) != 0) { - printf("%s%s(%d) otp_get_lock Failed%s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + if (otp_get_lock(pufs_otp, 12, &lvLock) != 0) { + printf("%s%s(%d) otp_get_lock Failed%s\n", ATTR_ERR, __func__, __LINE__, + ATTR_RST); } else { - printf("%s%s(%d) otp_lock: %d %s\n", \ - ATTR_INF,__func__,__LINE__,lvLock,ATTR_RST); + printf("%s%s(%d) otp_lock: %d %s\n", ATTR_INF, __func__, __LINE__, lvLock, + ATTR_RST); } - for(uint8_t i = 0; i < bytesPerSlot; i++) { - slot_data[i] = (i+i)*2; + for (uint8_t i = 0; i < bytesPerSlot; i++) { + slot_data[i] = (i + i) * 2; } - if(otp_write(pufs_otp, 12, slot_data, 18) != 0) { - if(lvLock != CRYPTO_OTP_RW) { - printf("%s%s(%d) otp_write Failed as Expected %s\n", \ - ATTR_RST,__func__,__LINE__,ATTR_RST); + if (otp_write(pufs_otp, 12, slot_data, 18) != 0) { + if (lvLock != CRYPTO_OTP_RW) { + printf("%s%s(%d) otp_write Failed as Expected %s\n", ATTR_RST, + __func__, __LINE__, ATTR_RST); } else { - printf("%s%s(%d) otp_write Failed unExpectedly %s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + printf("%s%s(%d) otp_write Failed unExpectedly %s\n", ATTR_ERR, + __func__, __LINE__, ATTR_RST); } } else { - printf("%s%s(%d) otp_write Passed UnExpectedly %s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + printf("%s%s(%d) otp_write Passed UnExpectedly %s\n", ATTR_ERR, __func__, + __LINE__, ATTR_RST); } } } @@ -351,35 +367,27 @@ void pufs_hash_sg_test(const struct device *pufs) { int status = 0; static uint8_t pufs_sample_data1[] = { - "My name is Junaid and I work at the Rapid Silicon and WorkFromH." - }; + "My name is Junaid and I work at the Rapid Silicon and WorkFromH."}; static uint8_t pufs_sample_data2[] = { - "My name is Junaid and I work at the Rapid Silicon and WorkFromH." - }; - static uint8_t pufs_sample_data3[] = { - "123456789123456789" - }; + "My name is Junaid and I work at the Rapid Silicon and WorkFromH."}; + static uint8_t pufs_sample_data3[] = {"123456789123456789"}; static uint8_t pufs_sample_data_sha256_out[32] = {0}; static const uint8_t pufs_sample_data_sha256[] = { - 0xb2,0x69,0xec,0xc6,0x0f,0x13,0x37,0xf3, - 0xf3,0xf8,0x29,0xc1,0x0e,0xc5,0x83,0xa6, - 0x82,0x25,0x97,0x32,0x71,0x78,0xd1,0xb8, - 0xe5,0x95,0x05,0xd1,0xbe,0xe7,0x43,0xca - }; + 0xb2, 0x69, 0xec, 0xc6, 0x0f, 0x13, 0x37, 0xf3, 0xf3, 0xf8, 0x29, + 0xc1, 0x0e, 0xc5, 0x83, 0xa6, 0x82, 0x25, 0x97, 0x32, 0x71, 0x78, + 0xd1, 0xb8, 0xe5, 0x95, 0x05, 0xd1, 0xbe, 0xe7, 0x43, 0xca}; const uint8_t pufs_sample_data1_len = strlen(pufs_sample_data1); const uint8_t pufs_sample_data2_len = strlen(pufs_sample_data2); const uint8_t pufs_sample_data3_len = strlen(pufs_sample_data3); - printf("%s%s(%d) Length of sample data to operate on:%d %s\n", \ - ATTR_INF,__func__,__LINE__,pufs_sample_data1_len+pufs_sample_data2_len+pufs_sample_data3_len,ATTR_RST); + printf("%s%s(%d) Length of sample data to operate on:%d %s\n", ATTR_INF, __func__, __LINE__, + pufs_sample_data1_len + pufs_sample_data2_len + pufs_sample_data3_len, ATTR_RST); - struct hash_ctx lvHashCtx = { - .device = pufs, - .drv_sessn_state = NULL, - .flags = CAP_SYNC_OPS | CAP_SEPARATE_IO_BUFS, - .started = true - }; + struct hash_ctx lvHashCtx = {.device = pufs, + .drv_sessn_state = NULL, + .flags = CAP_SYNC_OPS | CAP_SEPARATE_IO_BUFS, + .started = true}; struct hash_pkt lvHashPkt1 = {0}, lvHashPkt2 = {0}, lvHashPkt3 = {0}; @@ -419,49 +427,50 @@ void pufs_hash_sg_test(const struct device *pufs) lvHashPkt3.out_len = 0; lvHashPkt3.prev_len = 0; - printf("Pkt1.rd_addr:0x%08x Pkt2.rd_addr:0x%08x Pkt3.rd_addr:0x%08x\r\n", - (uint32_t)lvHashPkt1.in_buf, (uint32_t)lvHashPkt2.in_buf, (uint32_t)lvHashPkt3.in_buf); + printf("Pkt1.rd_addr:0x%08x Pkt2.rd_addr:0x%08x Pkt3.rd_addr:0x%08x\r\n", + (uint32_t)lvHashPkt1.in_buf, (uint32_t)lvHashPkt2.in_buf, + (uint32_t)lvHashPkt3.in_buf); printf("Size struct hash pkt:%d\r\n", sizeof(struct hash_pkt)); - printf("data1_size:%d data2_size:%d data3_size:%d\r\n", \ - pufs_sample_data1_len, pufs_sample_data2_len, pufs_sample_data3_len); + printf("data1_size:%d data2_size:%d data3_size:%d\r\n", pufs_sample_data1_len, + pufs_sample_data2_len, pufs_sample_data3_len); status = hash_begin_session(pufs, &lvHashCtx, CRYPTO_HASH_ALGO_SHA256); - if(status != 0) { - printf("%s%s(%d) hash_begin_session status = %d %s\n", \ - ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + if (status != 0) { + printf("%s%s(%d) hash_begin_session status = %d %s\n", ATTR_ERR, __func__, __LINE__, + status, ATTR_RST); } else { status = hash_compute(&lvHashCtx, &lvHashPkt1); } - if(status != 0) { - printf("%s%s(%d) hash_compute status = %d %s\n", \ - ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + if (status != 0) { + printf("%s%s(%d) hash_compute status = %d %s\n", ATTR_ERR, __func__, __LINE__, + status, ATTR_RST); } else { - for(uint8_t i = 0; i < lvHashPkt1.out_len; i++) { - if(lvHashPkt1.out_buf[i] != pufs_sample_data_sha256[i]) { - // printf("%s%s(%d) out_buf[%d]0x%02x != in_buf[%d]:0x%02x %s\n", + for (uint8_t i = 0; i < lvHashPkt1.out_len; i++) { + if (lvHashPkt1.out_buf[i] != pufs_sample_data_sha256[i]) { + // printf("%s%s(%d) out_buf[%d]0x%02x != in_buf[%d]:0x%02x %s\n", // ATTR_ERR,__func__,__LINE__, // i,lvHashPkt1.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); status = -EINVAL; } else { - // printf("%s%s(%d) out_buf[%d]0x%02x == in_buf[%d]:0x%02x %s\n", + // printf("%s%s(%d) out_buf[%d]0x%02x == in_buf[%d]:0x%02x %s\n", // ATTR_INF,__func__,__LINE__, // i,lvHashPkt1.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); } } - if(status != 0) { - printf("%s%s(%d) hash_comparison failed%s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + if (status != 0) { + printf("%s%s(%d) hash_comparison failed%s\n", ATTR_ERR, __func__, __LINE__, + ATTR_RST); } else { - printf("%s%s(%d) hash_comparison Passed = %d %s\n", \ - ATTR_INF,__func__,__LINE__,status,ATTR_RST); + printf("%s%s(%d) hash_comparison Passed = %d %s\n", ATTR_INF, __func__, + __LINE__, status, ATTR_RST); } status = hash_free_session(pufs, &lvHashCtx); - if(status != 0) { - printf("%s%s(%d) hash_free_session status = %d %s\n", \ - ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + if (status != 0) { + printf("%s%s(%d) hash_free_session status = %d %s\n", ATTR_ERR, __func__, + __LINE__, status, ATTR_RST); } else { - printf("%s%s(%d) hash_free_session Passed = %d %s\n", \ - ATTR_INF,__func__,__LINE__,status,ATTR_RST); + printf("%s%s(%d) hash_free_session Passed = %d %s\n", ATTR_INF, __func__, + __LINE__, status, ATTR_RST); } } } @@ -472,46 +481,40 @@ void pufs_hash_test(const struct device *pufs) static uint8_t *pufs_sample_data = "This is Rapid Silicon'z Zephyr Port"; static uint8_t pufs_sample_data_sha256_out[32] = {0}; static const uint8_t pufs_sample_data_sha256[] = { - 0xfa,0x71,0xc2,0x19,0xea,0x58,0x4d,0xac, - 0x36,0xd5,0x3e,0xca,0xe4,0x2a,0x8c,0x14, - 0x4b,0xc1,0xc0,0x03,0xfd,0x36,0x3f,0x71, - 0xd9,0x30,0x96,0xc4,0xaa,0x64,0xe0,0x4c - }; + 0xfa, 0x71, 0xc2, 0x19, 0xea, 0x58, 0x4d, 0xac, 0x36, 0xd5, 0x3e, + 0xca, 0xe4, 0x2a, 0x8c, 0x14, 0x4b, 0xc1, 0xc0, 0x03, 0xfd, 0x36, + 0x3f, 0x71, 0xd9, 0x30, 0x96, 0xc4, 0xaa, 0x64, 0xe0, 0x4c}; const uint8_t pufs_sample_data_len = strlen(pufs_sample_data); - printf("%s%s(%d) Length of sample data to operate on:%d %s\n", \ - ATTR_INF,__func__,__LINE__,pufs_sample_data_len,ATTR_RST); - struct hash_ctx lvHashCtx = { - .device = pufs, - .drv_sessn_state = NULL, - .flags = CAP_SYNC_OPS | CAP_SEPARATE_IO_BUFS, - .started = false - }; - - struct hash_pkt lvHashPkt = { - .ctx = &lvHashCtx, - .head = true, - .tail = true, - .in_buf = pufs_sample_data, - .in_hash = NULL, - .in_len = pufs_sample_data_len, - .next = NULL, - .out_buf = pufs_sample_data_sha256_out, - .prev_len = 0, - .out_len = 0 - }; + printf("%s%s(%d) Length of sample data to operate on:%d %s\n", ATTR_INF, __func__, __LINE__, + pufs_sample_data_len, ATTR_RST); + struct hash_ctx lvHashCtx = {.device = pufs, + .drv_sessn_state = NULL, + .flags = CAP_SYNC_OPS | CAP_SEPARATE_IO_BUFS, + .started = false}; + + struct hash_pkt lvHashPkt = {.ctx = &lvHashCtx, + .head = true, + .tail = true, + .in_buf = pufs_sample_data, + .in_hash = NULL, + .in_len = pufs_sample_data_len, + .next = NULL, + .out_buf = pufs_sample_data_sha256_out, + .prev_len = 0, + .out_len = 0}; status = hash_begin_session(pufs, &lvHashCtx, CRYPTO_HASH_ALGO_SHA256); - if(status != 0) { - printf("%s%s(%d) hash_begin_session status = %d %s\n", \ - ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + if (status != 0) { + printf("%s%s(%d) hash_begin_session status = %d %s\n", ATTR_ERR, __func__, __LINE__, + status, ATTR_RST); } else { status = hash_compute(&lvHashCtx, &lvHashPkt); } - if(status != 0) { - printf("%s%s(%d) hash_compute status = %d %s\n", \ - ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + if (status != 0) { + printf("%s%s(%d) hash_compute status = %d %s\n", ATTR_ERR, __func__, __LINE__, + status, ATTR_RST); } else { - for(uint8_t i = 0; i < lvHashPkt.out_len; i++) { - if(lvHashPkt.out_buf[i] != pufs_sample_data_sha256[i]) { + for (uint8_t i = 0; i < lvHashPkt.out_len; i++) { + if (lvHashPkt.out_buf[i] != pufs_sample_data_sha256[i]) { // printf("%s%s(%d) out_buf[%d]0x%02x != in_buf[%d]:0x%02x %s\n", // ATTR_ERR,__func__,__LINE__, // i,lvHashPkt.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); @@ -522,20 +525,20 @@ void pufs_hash_test(const struct device *pufs) // i,lvHashPkt.out_buf[i],i,pufs_sample_data_sha256[i],ATTR_RST); } } - if(status != 0) { - printf("%s%s(%d) hash_comparison failed%s\n", \ - ATTR_ERR,__func__,__LINE__,ATTR_RST); + if (status != 0) { + printf("%s%s(%d) hash_comparison failed%s\n", ATTR_ERR, __func__, __LINE__, + ATTR_RST); } else { - printf("%s%s(%d) hash_comparison Passed = %d %s\n", \ - ATTR_INF,__func__,__LINE__,status,ATTR_RST); + printf("%s%s(%d) hash_comparison Passed = %d %s\n", ATTR_INF, __func__, + __LINE__, status, ATTR_RST); } status = hash_free_session(pufs, &lvHashCtx); - if(status != 0) { - printf("%s%s(%d) hash_free_session status = %d %s\n", \ - ATTR_ERR,__func__,__LINE__,status,ATTR_RST); + if (status != 0) { + printf("%s%s(%d) hash_free_session status = %d %s\n", ATTR_ERR, __func__, + __LINE__, status, ATTR_RST); } else { - printf("%s%s(%d) hash_free_session Passed = %d %s\n", \ - ATTR_INF,__func__,__LINE__,status,ATTR_RST); + printf("%s%s(%d) hash_free_session Passed = %d %s\n", ATTR_INF, __func__, + __LINE__, status, ATTR_RST); } } } @@ -547,49 +550,33 @@ void pufs_decryption_test(const struct device *pufs) struct cipher_ctx lvCipherCtx = {0}; struct cipher_pkt lvCipherPkt = {0}; - uint8_t enc32_key[] = { - 0x30,0x13,0x53,0x33,0x44,0x12,0xff,0x22, - 0x31,0x53,0xbb,0x13,0x07,0x19,0x84,0x0d, - 0xd5,0x3c,0x3f,0xc0,0x09,0x83,0x11,0x35, - 0x30,0x2d,0xdc,0xc0,0x0b,0xb9,0x4e,0x30 - }; - uint8_t iv[] = { - 0xaa,0x34,0x55,0x32,0xe9,0x58,0xaa,0xf3, - 0xc0,0xde,0x20,0xa6,0xa9,0x21,0x44,0xe8 - }; + uint8_t enc32_key[] = {0x30, 0x13, 0x53, 0x33, 0x44, 0x12, 0xff, 0x22, 0x31, 0x53, 0xbb, + 0x13, 0x07, 0x19, 0x84, 0x0d, 0xd5, 0x3c, 0x3f, 0xc0, 0x09, 0x83, + 0x11, 0x35, 0x30, 0x2d, 0xdc, 0xc0, 0x0b, 0xb9, 0x4e, 0x30}; + uint8_t iv[] = {0xaa, 0x34, 0x55, 0x32, 0xe9, 0x58, 0xaa, 0xf3, + 0xc0, 0xde, 0x20, 0xa6, 0xa9, 0x21, 0x44, 0xe8}; uint8_t cipher_text[] = { - 0xd0,0x07,0x29,0x7b,0x56,0x2c,0x2c,0xa7, - 0x43,0x24,0x68,0xd8,0x58,0xb4,0xc1,0x9f, - 0x7c,0x05,0x7c,0x98,0x03,0x28,0x19,0x9d, - 0x93,0xff,0x85,0xd7,0xdb,0x8f,0xf1,0x07, - 0x18,0xa5,0x1f,0x99,0x04,0x73,0x84,0x4f, - 0x4f,0x79,0xba,0x2e,0x70,0x82,0xb1,0x39, - 0x5d,0x3f,0x3e,0xf8,0x44,0x81,0xf6,0x89, - 0x17,0x3a,0x29,0x43,0x0a,0x41,0x24,0xff, - 0x57,0xa8,0xbb,0x0b,0x0e,0xcf,0xb3,0xed, - 0x8e,0x1d,0x49,0x03,0x86,0x77,0x61,0x68, - 0x59,0x7c,0xf0,0x61,0x98,0x11,0x1b,0xe5, - 0xe3,0x95,0x6d,0x81,0x49,0xdc,0xa0,0x4b, - 0x97,0xb4,0xe6,0x40,0xd5,0x26,0xb6,0xb7, - 0xd8,0xab,0x61,0xc1,0xa7,0x5a,0xdc,0x5e, - 0xa9,0x25,0x6f,0xcd,0x25,0xb6,0xd0,0x42, - 0xa1,0xd8,0xd5,0xdc,0xcf,0xc6,0xaa,0xdf - }; - - uint8_t *plain_text = "Plain Text: This is Junaid Aslam from Rapid Silicon doing Decryption Test...\n"; + 0xd0, 0x07, 0x29, 0x7b, 0x56, 0x2c, 0x2c, 0xa7, 0x43, 0x24, 0x68, 0xd8, 0x58, + 0xb4, 0xc1, 0x9f, 0x7c, 0x05, 0x7c, 0x98, 0x03, 0x28, 0x19, 0x9d, 0x93, 0xff, + 0x85, 0xd7, 0xdb, 0x8f, 0xf1, 0x07, 0x18, 0xa5, 0x1f, 0x99, 0x04, 0x73, 0x84, + 0x4f, 0x4f, 0x79, 0xba, 0x2e, 0x70, 0x82, 0xb1, 0x39, 0x5d, 0x3f, 0x3e, 0xf8, + 0x44, 0x81, 0xf6, 0x89, 0x17, 0x3a, 0x29, 0x43, 0x0a, 0x41, 0x24, 0xff, 0x57, + 0xa8, 0xbb, 0x0b, 0x0e, 0xcf, 0xb3, 0xed, 0x8e, 0x1d, 0x49, 0x03, 0x86, 0x77, + 0x61, 0x68, 0x59, 0x7c, 0xf0, 0x61, 0x98, 0x11, 0x1b, 0xe5, 0xe3, 0x95, 0x6d, + 0x81, 0x49, 0xdc, 0xa0, 0x4b, 0x97, 0xb4, 0xe6, 0x40, 0xd5, 0x26, 0xb6, 0xb7, + 0xd8, 0xab, 0x61, 0xc1, 0xa7, 0x5a, 0xdc, 0x5e, 0xa9, 0x25, 0x6f, 0xcd, 0x25, + 0xb6, 0xd0, 0x42, 0xa1, 0xd8, 0xd5, 0xdc, 0xcf, 0xc6, 0xaa, 0xdf}; + + uint8_t *plain_text = + "Plain Text: This is Junaid Aslam from Rapid Silicon doing Decryption Test...\n"; uint8_t decrypted_text[256] = {0}; lvCipherCtx.app_sessn_state = NULL; lvCipherCtx.device = pufs; - lvCipherCtx.flags = ( - CAP_RAW_KEY | - CAP_SEPARATE_IO_BUFS | - CAP_SYNC_OPS | - CAP_NO_IV_PREFIX | - CAP_NO_ENCRYPTION - ); - lvCipherCtx.key.bit_stream = enc32_key; + lvCipherCtx.flags = (CAP_RAW_KEY | CAP_SEPARATE_IO_BUFS | CAP_SYNC_OPS | CAP_NO_IV_PREFIX | + CAP_NO_ENCRYPTION); + lvCipherCtx.key.bit_stream = enc32_key; lvCipherCtx.key_source = CRYPTO_KEY_SW; lvCipherCtx.keylen = 32; lvCipherCtx.mode_params.ctr_info.ctr_len = 16; @@ -599,43 +586,42 @@ void pufs_decryption_test(const struct device *pufs) lvCipherPkt.auto_increment = true; lvCipherPkt.ctx = &lvCipherCtx; lvCipherPkt.in_buf = cipher_text; - lvCipherPkt.in_len = (sizeof(cipher_text)/sizeof(cipher_text[0])); + lvCipherPkt.in_len = (sizeof(cipher_text) / sizeof(cipher_text[0])); lvCipherPkt.out_buf = decrypted_text; lvCipherPkt.prev_len = 0; printf("%s Decrypting %d bytes %s\n", ATTR_INF, lvCipherPkt.in_len, ATTR_RST); - lvStatus = cipher_begin_session( - pufs, - &lvCipherCtx, - CRYPTO_CIPHER_ALGO_AES, - CRYPTO_CIPHER_MODE_CTR, - CRYPTO_CIPHER_OP_DECRYPT - ); - if(lvStatus != 0) { + lvStatus = cipher_begin_session(pufs, &lvCipherCtx, CRYPTO_CIPHER_ALGO_AES, + CRYPTO_CIPHER_MODE_CTR, CRYPTO_CIPHER_OP_DECRYPT); + if (lvStatus != 0) { printf("%s cipher_begin_session Failed! %s\n", ATTR_ERR, ATTR_RST); } else { - printf("%s cipher_begin_session Success! %s\n", ATTR_INF, ATTR_RST); + printf("%s cipher_begin_session Success! %s\n", ATTR_INF, ATTR_RST); + lvStatus = cipher_ctr_op(&lvCipherCtx, &lvCipherPkt, (uint8_t *)iv); } - lvStatus = cipher_ctr_op(&lvCipherCtx, &lvCipherPkt, (uint8_t*)iv); - if(lvStatus != 0) { + if (lvStatus != 0) { printf("%s cipher_ctr_op Failed! Status:%d %s\n", ATTR_ERR, lvStatus, ATTR_RST); } else { printf("%s cipher_ctr_op Success! %s\n", ATTR_INF, ATTR_RST); - printf("%s Original: %s%s", ATTR_HIL,plain_text,ATTR_RST); - printf("%s Result: %s%s", ATTR_HIL,lvCipherPkt.out_buf,ATTR_RST); + printf("%s Original: %s%s", ATTR_HIL, plain_text, ATTR_RST); + printf("%s Result: %s%s", ATTR_HIL, lvCipherPkt.out_buf, ATTR_RST); bool comparison_ok = true; - for(int i = 0; i < strlen(lvCipherPkt.out_buf); i++) { - if(lvCipherPkt.out_buf[i] != plain_text[i]) { - // printf("Orig[%d]:0x%02x(%c) != Res[%d]:0x%02x(%c)\n", i, plain_text[i], plain_text[i], i, lvCipherPkt.out_buf[i], lvCipherPkt.out_buf[i]); - comparison_ok = false; break; - } + for (int i = 0; i < strlen(lvCipherPkt.out_buf); i++) { + if (lvCipherPkt.out_buf[i] != plain_text[i]) { + // printf("Orig[%d]:0x%02x(%c) != Res[%d]:0x%02x(%c)\n", i, + // plain_text[i], plain_text[i], i, lvCipherPkt.out_buf[i], + // lvCipherPkt.out_buf[i]); + comparison_ok = false; + break; + } // else { - // printf("Orig[%d]:0x%02x(%c) == Res[%d]:0x%02x(%c)\n", i, plain_text[i], plain_text[i], i, lvCipherPkt.out_buf[i], lvCipherPkt.out_buf[i]); + // printf("Orig[%d]:0x%02x(%c) == Res[%d]:0x%02x(%c)\n", i, plain_text[i], + // plain_text[i], i, lvCipherPkt.out_buf[i], lvCipherPkt.out_buf[i]); // } } - if(!comparison_ok) { + if (!comparison_ok) { printf("%s cipher decryption Failed! %s\n", ATTR_ERR, ATTR_RST); } else { printf("%s cipher decryption Passed! %s\n", ATTR_INF, ATTR_RST); @@ -643,29 +629,70 @@ void pufs_decryption_test(const struct device *pufs) } lvStatus = cipher_free_session(pufs, &lvCipherCtx); - if(lvStatus != 0) { + if (lvStatus != 0) { printf("%s cipher_free_session Failed! %s\n", ATTR_ERR, ATTR_RST); } else { printf("%s cipher_free_session Success! %s\n", ATTR_INF, ATTR_RST); - } + } } -void pufs_rsa2048_verify_test(const struct device *dev) +void pufs_rsa2048_verify_test(const struct device *pufs) { int lvStatus = 0; - struct sign_ctx lvCipherCtx = {0}; - struct sign_pkt lvCipherPkt = {0}; + struct sign_ctx lvSignCtx = {0}; + struct sign_pkt lvSignPkt = {0}; + + const uint32_t pub_key[] = { + 0x37c2cac9, 0x8c32e765, 0xa15e1200, 0x25c486b2, 0x8734d7b4, 0xfa26c29d, 0x2ff972ae, + 0x0adebf22, 0xff6f29e6, 0x3c50778d, 0xfa02d8da, 0x78600d02, 0xbca88565, 0x163ca9be, + 0x73f0da10, 0x3ed20b1c, 0xcce46d11, 0x2a49278f, 0x12248db6, 0xe50b6755, 0xa431193c, + 0x6c308699, 0xe0c41dbf, 0x50c791fe, 0xd3f876b9, 0x7cf1df93, 0x16941322, 0xaa1ead8f, + 0xe3753f54, 0xc9bb7bcc, 0x79200bff, 0x7d76c2d4, 0xa7acc7f7, 0xff567a99, 0xbfa4f5dc, + 0x064238c8, 0xe9699208, 0xa6b5daf3, 0xa3a2ad30, 0x32bafe37, 0x54e1dacb, 0xda540799, + 0x95547760, 0x302cd650, 0x9d428238, 0x62bbdadd, 0xe531a353, 0x282e8f7d, 0x973e7ba1, + 0x0dd65973, 0x4ab77a02, 0x53ca63ae, 0x176010c2, 0x58bc890d, 0x025f55f8, 0x0e1e579b, + 0xe19cdb04, 0x4bb6caf5, 0xad438b2c, 0xeda4466b, 0x3cabf8dc, 0x0785aca7, 0xd0350f09, + 0x79cac3c1, 0x00010001}; + + const uint32_t sig[] = { + 0xf235912c, 0x1ba1ab22, 0xedcac05d, 0xb1c5d360, 0x98a735cc, 0x7b00bf6e, 0xde43e386, + 0x0d1ac161, 0x1388ef49, 0x740168d7, 0x5ba73228, 0xa9737ae4, 0x7cd97822, 0x2a9fdbf1, + 0x0d60a575, 0xdb5f54a3, 0x320a729b, 0x2f008675, 0x66cd9746, 0x6fbb0c91, 0x23c027d7, + 0xa80b41bc, 0x0baef3d2, 0x9d49dd28, 0xfe2419e1, 0xece8386f, 0x01fa3a75, 0xe1c61fba, + 0xab4863b9, 0xb0568810, 0x5fe37145, 0xfbf37a1e, 0xa4756054, 0xa1e614c4, 0xc4a7ca37, + 0x80d03784, 0x43b28dbb, 0x1bb7cc27, 0x5bbf74f0, 0xaaf5196b, 0xc300c3f8, 0xc5e58f0a, + 0x9a0230df, 0x6aa94d93, 0xd0308e50, 0xccf6719c, 0x8f96f414, 0xaf5f9cb7, 0x98b563ef, + 0x345a8867, 0xdfe77c95, 0xebc2ba9f, 0xa8f1914c, 0x3de9cbd8, 0x2f421af6, 0x42883c94, + 0x0bf207ba, 0x349c7739, 0x7cf10f2b, 0x337eaf18, 0x733f2eb6, 0xd7e63340, 0x0ed1b921, + 0x4c11b7f9}; + + const uint32_t in_buf[] = {}; + + lvStatus = sign_begin_session(pufs, &lvSignCtx, CRYPTO_SIGN_ALGO_RSA2048); + if (lvStatus != 0) { + printf("%s sign_begin_session Failed! %s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%s sign_begin_session Success! %s\n", ATTR_INF, ATTR_RST); + lvStatus = sign_op_handler(&lvSignCtx, &lvSignPkt); + } - const uint8_t pub_key[272] = {0}; // TODO Fill - const uint8_t sig[256] = {0}; // TODO Fill - const uint8_t *in_buf = "RSA2048 Signature Verification Test"; + if (lvStatus != 0) { + printf("%s sign_op_handler Failed! Status:%d %s\n", ATTR_ERR, lvStatus, ATTR_RST); + } else { + printf("%s sign_op_handler Success! %s\n", ATTR_INF, ATTR_RST); + } + lvStatus = sign_free_session(pufs, &lvSignCtx); + if (lvStatus != 0) { + printf("%s sign_free_session Failed! %s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%s sign_free_session Success! %s\n", ATTR_INF, ATTR_RST); + } } void pufs_ecdsa256_verify_test(const struct device *dev) { - } int main(void) @@ -673,11 +700,9 @@ int main(void) int Cnt = 0; uint8_t chip_id = 0, vendor_id = 0; - printf( - "%s SPI_(%d)_IRQ_Reg_Val:[0x%08x]; DMA_(%d)_IRQ_Reg_Val:[0x%08x]\n", ATTR_RST, \ - IRQ_ID_SPI, scu_get_irq_reg_val(IRQ_ID_SPI), \ - IRQ_ID_SYSTEM_DMA, scu_get_irq_reg_val(IRQ_ID_SYSTEM_DMA) - ); + printf("%s SPI_(%d)_IRQ_Reg_Val:[0x%08x]; DMA_(%d)_IRQ_Reg_Val:[0x%08x]\n", ATTR_RST, + IRQ_ID_SPI, scu_get_irq_reg_val(IRQ_ID_SPI), IRQ_ID_SYSTEM_DMA, + scu_get_irq_reg_val(IRQ_ID_SYSTEM_DMA)); soc_get_id(&chip_id, &vendor_id); @@ -691,8 +716,9 @@ int main(void) const struct device *pufs = DEVICE_DT_GET(DT_NODELABEL(pufs)); const struct device *pufs_otp = DEVICE_DT_GET(DT_NODELABEL(pufs_otp)); - if((pufs == NULL) || (!device_is_ready(pufs))) { - printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); + if ((pufs == NULL) || (!device_is_ready(pufs))) { + printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, + ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); // pufs_rsa2048_verify_test(pufs); while(true); // TODO Remove while @@ -701,54 +727,58 @@ int main(void) pufs_hash_sg_test(pufs); } - if((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { - printf("%s pufs_otp has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); + if ((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { + printf("%s pufs_otp has status disabled or driver is not initialized...%s\n", + ATTR_ERR, ATTR_RST); } else { printf("%s pufs_otp Object is Created %s\n", ATTR_INF, ATTR_RST); pufs_otp_test(pufs_otp); } - if((pvt == NULL) || (!device_is_ready(pvt))) { - printf("%s pvt has status disabled or driver is not initialized...%s\n", ATTR_ERR, ATTR_RST); + if ((pvt == NULL) || (!device_is_ready(pvt))) { + printf("%s pvt has status disabled or driver is not initialized...%s\n", ATTR_ERR, + ATTR_RST); } else { printf("%s pvt Object is Created %s\n", ATTR_INF, ATTR_RST); errorcode = sensor_channel_get(pvt, SENSOR_CHAN_DIE_TEMP, &lvTemp); - if(errorcode == 0) { - printf("%s Error fetching temperature value. Error code:%u%s\n", ATTR_ERR, errorcode,ATTR_RST); + if (errorcode == 0) { + printf("%s Error fetching temperature value. Error code:%u%s\n", ATTR_ERR, + errorcode, ATTR_RST); } errorcode = sensor_channel_get(pvt, SENSOR_CHAN_VOLTAGE, &lvVolt); - if(errorcode == 0) { - printf("%s Error fetching Voltage value. Error code:%u%s\n", ATTR_ERR, errorcode,ATTR_RST); + if (errorcode == 0) { + printf("%s Error fetching Voltage value. Error code:%u%s\n", ATTR_ERR, + errorcode, ATTR_RST); } - printf("%s Die Temperature:%d Voltage:%d%s\n", ATTR_INF, lvTemp.val1, lvVolt.val1,ATTR_RST); + printf("%s Die Temperature:%d Voltage:%d%s\n", ATTR_INF, lvTemp.val1, lvVolt.val1, + ATTR_RST); } - if(spi == NULL) { - printf("%s spi has status disabled...%s\n", ATTR_ERR,ATTR_RST); - } else { - printf("%s spi Object is Created. Test Via DMA\n", ATTR_INF); - if(flash == NULL) { - printf("%s flash has status disabled or not initialized properly...%s\n", ATTR_ERR,ATTR_RST); + if (spi == NULL) { + printf("%s spi has status disabled...%s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%s spi Object is Created. Test Via DMA\n", ATTR_INF); + if (flash == NULL) { + printf("%s flash has status disabled or not initialized properly...%s\n", + ATTR_ERR, ATTR_RST); } else { - printf("%s flash Object is Created. Initialize to Test Via DMA%s\n", ATTR_INF,ATTR_RST); + printf("%s flash Object is Created. Initialize to Test Via DMA%s\n", + ATTR_INF, ATTR_RST); Flash_Test(flash, dma, 0x1000, 0, 20); } } - if((pit == NULL) || !device_is_ready(pit)) { - printf("%s pit has status disabled or driver is not initialized...%s\n", ATTR_ERR,ATTR_RST); + if ((pit == NULL) || !device_is_ready(pit)) { + printf("%s pit has status disabled or driver is not initialized...%s\n", ATTR_ERR, + ATTR_RST); } else { CounterTest(pit); } - while(true) { - printf( - "%s%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Build[Date:%s Time:%s]\r", - ATTR_RST, Cnt++, - CONFIG_BOARD_TARGET, - chip_id, vendor_id, - __DATE__, __TIME__ - ); + while (true) { + printf("%s%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Build[Date:%s Time:%s]\r", + ATTR_RST, Cnt++, CONFIG_BOARD_TARGET, chip_id, vendor_id, __DATE__, + __TIME__); k_msleep(1000); } From c0cbd49b95f905505a6f2984a063cc225b0833cd Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 11 Oct 2024 21:40:26 +0500 Subject: [PATCH 44/58] RSA2048 signature verification in progress --- samples/hello_world/src/main.c | 50 +++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index bfd32453b44e1..c267c49f8b9a7 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -667,7 +667,55 @@ void pufs_rsa2048_verify_test(const struct device *pufs) 0x0bf207ba, 0x349c7739, 0x7cf10f2b, 0x337eaf18, 0x733f2eb6, 0xd7e63340, 0x0ed1b921, 0x4c11b7f9}; - const uint32_t in_buf[] = {}; + const uint32_t in_buf[] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; lvStatus = sign_begin_session(pufs, &lvSignCtx, CRYPTO_SIGN_ALGO_RSA2048); if (lvStatus != 0) { From 3e4443f15f1165fc6e46f4b3251c2876a149bddd Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 14 Oct 2024 13:40:28 +0500 Subject: [PATCH 45/58] RSA2048 signature verification in progress --- drivers/crypto/crypto_pufs.c | 2 +- drivers/crypto/pufcc.c | 9 ++++ samples/hello_world/src/main.c | 77 +++++++++++++++++++++++----------- 3 files changed, 63 insertions(+), 25 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index baa78c0233710..494fd5b1a8c71 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -503,7 +503,7 @@ static int pufs_sign_begin_session(const struct device *dev, struct sign_ctx *ct uint16_t lvHashFlagsMask = (CAP_INPLACE_OPS | CAP_SYNC_OPS); - if((algo != CRYPTO_SIGN_ALGO_ECDSA256) || (algo != CRYPTO_SIGN_ALGO_RSA2048)) { + if((algo != CRYPTO_SIGN_ALGO_ECDSA256) && (algo != CRYPTO_SIGN_ALGO_RSA2048)) { LOG_ERR("%s(%d) Unupported Algo:%d. Supported Algo \n", __func__, __LINE__, algo); return -ENOTSUP; } else { diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index bef66ac5329fc..66a8f9c2e83fa 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -550,6 +550,7 @@ enum pufcc_status pufcc_rsa2048_sign_verify( status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); if (status != PUFCC_SUCCESS) { + printf("%s(%d)\n", __func__,__LINE__); return status; } @@ -1197,6 +1198,7 @@ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, 0, 0x05, 0x00, 0x04, 0}; if ((dec_msg[0] != 0x00) || (dec_msg[1] != 0x01)) { + printf("%s(%d)\n", __func__,__LINE__); return PUFCC_E_VERFAIL; } @@ -1207,6 +1209,7 @@ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, } if (dec_msg[i++] != 0x00) { + printf("%s(%d)\n", __func__,__LINE__); return PUFCC_E_VERFAIL; } @@ -1216,21 +1219,25 @@ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, pret[14] = 0x01; pret[18] = 0x20; } else { + printf("%s(%d)\n", __func__,__LINE__); return PUFCC_E_INVALID; } if ((memcmp(dec_msg + i, pret, 19) != 0) || ((i + 19 + pret[18]) != PUFCC_RSA_2048_LEN)) { + printf("%s(%d)\n", __func__,__LINE__); return PUFCC_E_VERFAIL; } // Calculate hash of the message if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != PUFCC_SUCCESS) { + printf("%s(%d)\n", __func__,__LINE__); return PUFCC_E_ERROR; } if (memcmp(dec_msg + i + 19, hash.val, hash.len) != 0) { + printf("%s(%d)\n", __func__,__LINE__); return PUFCC_E_VERFAIL; } @@ -1324,8 +1331,10 @@ static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, } while ((status & PUFCC_BUSY_BIT_MASK) && (busy_count > 0)); if (status & PUFCC_BUSY_BIT_MASK) { + printf("%s(%d)\n", __func__,__LINE__); return PUFCC_E_TIMEOUT; } else if (status & error_mask) { + printf("%s(%d) status 0x%08x\n", __func__,__LINE__, status); return PUFCC_E_ERROR; } diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index c267c49f8b9a7..12470f633622c 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -643,29 +643,44 @@ void pufs_rsa2048_verify_test(const struct device *pufs) struct sign_ctx lvSignCtx = {0}; struct sign_pkt lvSignPkt = {0}; - const uint32_t pub_key[] = { - 0x37c2cac9, 0x8c32e765, 0xa15e1200, 0x25c486b2, 0x8734d7b4, 0xfa26c29d, 0x2ff972ae, - 0x0adebf22, 0xff6f29e6, 0x3c50778d, 0xfa02d8da, 0x78600d02, 0xbca88565, 0x163ca9be, - 0x73f0da10, 0x3ed20b1c, 0xcce46d11, 0x2a49278f, 0x12248db6, 0xe50b6755, 0xa431193c, - 0x6c308699, 0xe0c41dbf, 0x50c791fe, 0xd3f876b9, 0x7cf1df93, 0x16941322, 0xaa1ead8f, - 0xe3753f54, 0xc9bb7bcc, 0x79200bff, 0x7d76c2d4, 0xa7acc7f7, 0xff567a99, 0xbfa4f5dc, - 0x064238c8, 0xe9699208, 0xa6b5daf3, 0xa3a2ad30, 0x32bafe37, 0x54e1dacb, 0xda540799, - 0x95547760, 0x302cd650, 0x9d428238, 0x62bbdadd, 0xe531a353, 0x282e8f7d, 0x973e7ba1, - 0x0dd65973, 0x4ab77a02, 0x53ca63ae, 0x176010c2, 0x58bc890d, 0x025f55f8, 0x0e1e579b, - 0xe19cdb04, 0x4bb6caf5, 0xad438b2c, 0xeda4466b, 0x3cabf8dc, 0x0785aca7, 0xd0350f09, - 0x79cac3c1, 0x00010001}; - - const uint32_t sig[] = { - 0xf235912c, 0x1ba1ab22, 0xedcac05d, 0xb1c5d360, 0x98a735cc, 0x7b00bf6e, 0xde43e386, - 0x0d1ac161, 0x1388ef49, 0x740168d7, 0x5ba73228, 0xa9737ae4, 0x7cd97822, 0x2a9fdbf1, - 0x0d60a575, 0xdb5f54a3, 0x320a729b, 0x2f008675, 0x66cd9746, 0x6fbb0c91, 0x23c027d7, - 0xa80b41bc, 0x0baef3d2, 0x9d49dd28, 0xfe2419e1, 0xece8386f, 0x01fa3a75, 0xe1c61fba, - 0xab4863b9, 0xb0568810, 0x5fe37145, 0xfbf37a1e, 0xa4756054, 0xa1e614c4, 0xc4a7ca37, - 0x80d03784, 0x43b28dbb, 0x1bb7cc27, 0x5bbf74f0, 0xaaf5196b, 0xc300c3f8, 0xc5e58f0a, - 0x9a0230df, 0x6aa94d93, 0xd0308e50, 0xccf6719c, 0x8f96f414, 0xaf5f9cb7, 0x98b563ef, - 0x345a8867, 0xdfe77c95, 0xebc2ba9f, 0xa8f1914c, 0x3de9cbd8, 0x2f421af6, 0x42883c94, - 0x0bf207ba, 0x349c7739, 0x7cf10f2b, 0x337eaf18, 0x733f2eb6, 0xd7e63340, 0x0ed1b921, - 0x4c11b7f9}; + const uint8_t pub_key[] = { + 0xc9,0xca,0xc2,0x37,0x65,0xe7,0x32,0x8c,0x00,0x12,0x5e,0xa1,0xb2,0x86,0xc4,0x25, + 0xb4,0xd7,0x34,0x87,0x9d,0xc2,0x26,0xfa,0xae,0x72,0xf9,0x2f,0x22,0xbf,0xde,0x0a, + 0xe6,0x29,0x6f,0xff,0x8d,0x77,0x50,0x3c,0xda,0xd8,0x02,0xfa,0x02,0x0d,0x60,0x78, + 0x65,0x85,0xa8,0xbc,0xbe,0xa9,0x3c,0x16,0x10,0xda,0xf0,0x73,0x1c,0x0b,0xd2,0x3e, + 0x11,0x6d,0xe4,0xcc,0x8f,0x27,0x49,0x2a,0xb6,0x8d,0x24,0x12,0x55,0x67,0x0b,0xe5, + 0x3c,0x19,0x31,0xa4,0x99,0x86,0x30,0x6c,0xbf,0x1d,0xc4,0xe0,0xfe,0x91,0xc7,0x50, + 0xb9,0x76,0xf8,0xd3,0x93,0xdf,0xf1,0x7c,0x22,0x13,0x94,0x16,0x8f,0xad,0x1e,0xaa, + 0x54,0x3f,0x75,0xe3,0xcc,0x7b,0xbb,0xc9,0xff,0x0b,0x20,0x79,0xd4,0xc2,0x76,0x7d, + 0xf7,0xc7,0xac,0xa7,0x99,0x7a,0x56,0xff,0xdc,0xf5,0xa4,0xbf,0xc8,0x38,0x42,0x06, + 0x08,0x92,0x69,0xe9,0xf3,0xda,0xb5,0xa6,0x30,0xad,0xa2,0xa3,0x37,0xfe,0xba,0x32, + 0xcb,0xda,0xe1,0x54,0x99,0x07,0x54,0xda,0x60,0x77,0x54,0x95,0x50,0xd6,0x2c,0x30, + 0x38,0x82,0x42,0x9d,0xdd,0xda,0xbb,0x62,0x53,0xa3,0x31,0xe5,0x7d,0x8f,0x2e,0x28, + 0xa1,0x7b,0x3e,0x97,0x73,0x59,0xd6,0x0d,0x02,0x7a,0xb7,0x4a,0xae,0x63,0xca,0x53, + 0xc2,0x10,0x60,0x17,0x0d,0x89,0xbc,0x58,0xf8,0x55,0x5f,0x02,0x9b,0x57,0x1e,0x0e, + 0x04,0xdb,0x9c,0xe1,0xf5,0xca,0xb6,0x4b,0x2c,0x8b,0x43,0xad,0x6b,0x46,0xa4,0xed, + 0xdc,0xf8,0xab,0x3c,0xa7,0xac,0x85,0x07,0x09,0x0f,0x35,0xd0,0xc1,0xc3,0xca,0x79, + 0x01,0x00,0x01,0x00 + }; + + const uint8_t sig[] = { + 0x8f,0xa7,0xe1,0xeb,0xed,0x03,0x6e,0x2e,0x4e,0x35,0xe1,0x4e,0x4d,0xaa,0x52,0x20, + 0x58,0xb9,0x4c,0xbb,0x32,0x02,0x0e,0x23,0x15,0xb0,0x2c,0x86,0xe7,0xe9,0xde,0x58, + 0x4e,0xf5,0xe8,0xfd,0xbe,0x44,0x6e,0xc9,0xf8,0x71,0x72,0x60,0xa7,0xce,0x3e,0x98, + 0x08,0x0c,0x77,0xe8,0x9b,0x59,0xc7,0x0d,0xf8,0x8f,0x0e,0x59,0xe6,0x88,0x01,0x69, + 0x5e,0xaf,0xdf,0x66,0x68,0x5a,0x33,0xf6,0x8f,0x11,0x0b,0x2c,0x90,0xa7,0x33,0x37, + 0x42,0x8f,0x93,0x9c,0x52,0x88,0xe2,0x3c,0xa7,0xcd,0x74,0x2c,0xde,0x40,0xad,0x7d, + 0x99,0x02,0xa8,0xe7,0x77,0x26,0xe9,0xa3,0xd7,0x8c,0x32,0x4b,0xe1,0x76,0x09,0x76, + 0xe4,0x52,0xa1,0x92,0xc3,0xf6,0x25,0x42,0x36,0x72,0xd8,0xb3,0x7e,0xbe,0xa9,0x43, + 0x76,0x20,0xb1,0xbb,0x75,0x39,0x43,0x66,0x19,0x30,0x3e,0x35,0xe2,0x26,0x09,0x01, + 0x53,0x84,0xd0,0x00,0xd6,0xfc,0x5c,0x04,0x56,0xd6,0x63,0xc7,0xee,0xfa,0x73,0xe8, + 0xc1,0x2d,0xfc,0xb1,0xe3,0xf6,0x30,0x05,0xff,0xe3,0x64,0x70,0x2f,0x2a,0x06,0xc6, + 0x20,0xd1,0xa3,0xe1,0x4f,0xad,0x28,0xf7,0x1e,0x9b,0x15,0xa7,0x92,0x3a,0x3e,0x8f, + 0x7f,0x04,0xbe,0x97,0x7b,0xd2,0xa4,0x75,0x49,0xd7,0xc4,0x5f,0xce,0x52,0x4d,0x19, + 0xba,0xcc,0x99,0x01,0xec,0xe3,0xe3,0x0d,0xd5,0x6d,0x0b,0x83,0x3e,0x54,0x35,0xff, + 0x15,0x9d,0x0b,0x5b,0xb7,0xed,0x58,0x82,0x9e,0x00,0xe5,0xfe,0x55,0x2f,0x69,0xed, + 0x9a,0x27,0xbe,0x5f,0xe6,0x6e,0xa6,0x9f,0x4d,0x67,0x13,0x39,0xc3,0x85,0x12,0x67 + }; const uint32_t in_buf[] = { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, @@ -717,11 +732,25 @@ void pufs_rsa2048_verify_test(const struct device *pufs) 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + lvSignCtx.app_sessn_state = NULL; + lvSignCtx.device = pufs; + lvSignCtx.drv_sessn_state = NULL; + lvSignCtx.flags = (CAP_INPLACE_OPS | CAP_SYNC_OPS); + lvSignCtx.pub_key = pub_key; + lvSignCtx.sig = sig; + lvSignCtx.ops.signing_algo = CRYPTO_SIGN_ALGO_RSA2048; + lvSignCtx.ops.signing_mode = CRYPTO_SIGN_VERIFY; + + lvSignPkt.ctx = &lvSignCtx; + lvSignPkt.in_buf = (uint8_t*)in_buf; + lvSignPkt.in_len = sizeof(in_buf); + lvStatus = sign_begin_session(pufs, &lvSignCtx, CRYPTO_SIGN_ALGO_RSA2048); if (lvStatus != 0) { printf("%s sign_begin_session Failed! %s\n", ATTR_ERR, ATTR_RST); } else { printf("%s sign_begin_session Success! %s\n", ATTR_INF, ATTR_RST); + printf("%s in_buf_len:%d bytes %s\n", ATTR_INF, lvSignPkt.in_len, ATTR_RST); lvStatus = sign_op_handler(&lvSignCtx, &lvSignPkt); } @@ -769,7 +798,7 @@ int main(void) ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); - // pufs_rsa2048_verify_test(pufs); while(true); // TODO Remove while + pufs_rsa2048_verify_test(pufs); while(true); // TODO Remove while pufs_decryption_test(pufs); pufs_hash_test(pufs); pufs_hash_sg_test(pufs); From 4f876d9eb8f89ca71563109385feb45f64891ec0 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 14 Oct 2024 23:08:46 +0500 Subject: [PATCH 46/58] RSA2048 signature verification in progress --- drivers/crypto/pufcc.c | 2 + include/zephyr/crypto/sign.h | 2 +- samples/hello_world/src/main.c | 204 +++++++++++++++++++-------------- 3 files changed, 121 insertions(+), 87 deletions(-) diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 66a8f9c2e83fa..47082cfd3c3d5 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -510,6 +510,7 @@ enum pufcc_status pufcc_rsa2048_sign_verify( // Configure signature scheme temp32 = 0; + struct pufcc_pkc_ecp_ec_reg *ecp_ec_reg = (struct pufcc_pkc_ecp_ec_reg *)&temp32; ecp_ec_reg->field = PUFCC_RSA_2048; @@ -524,6 +525,7 @@ enum pufcc_status pufcc_rsa2048_sign_verify( // Write public key exponent to ecp_e_short register REG_WRITE_32(&pkc_regs->ecp_e_short, &pub_key->e); + printf("%s(%d) pubKey_expo:0x%08x\n", __func__,__LINE__, pub_key->e); // Reverse signature reverse(pufcc_buffer, sig, PUFCC_RSA_2048_LEN); diff --git a/include/zephyr/crypto/sign.h b/include/zephyr/crypto/sign.h index 99e4aa083c243..fe05f3164275b 100644 --- a/include/zephyr/crypto/sign.h +++ b/include/zephyr/crypto/sign.h @@ -142,7 +142,7 @@ struct sign_ctx { struct sign_pkt { /** Start address of input buffer */ - uint8_t *in_buf; + const uint8_t *in_buf; /** Bytes to be operated upon */ int in_len; diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 12470f633622c..a31b76f83bf02 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -644,93 +644,122 @@ void pufs_rsa2048_verify_test(const struct device *pufs) struct sign_pkt lvSignPkt = {0}; const uint8_t pub_key[] = { - 0xc9,0xca,0xc2,0x37,0x65,0xe7,0x32,0x8c,0x00,0x12,0x5e,0xa1,0xb2,0x86,0xc4,0x25, - 0xb4,0xd7,0x34,0x87,0x9d,0xc2,0x26,0xfa,0xae,0x72,0xf9,0x2f,0x22,0xbf,0xde,0x0a, - 0xe6,0x29,0x6f,0xff,0x8d,0x77,0x50,0x3c,0xda,0xd8,0x02,0xfa,0x02,0x0d,0x60,0x78, - 0x65,0x85,0xa8,0xbc,0xbe,0xa9,0x3c,0x16,0x10,0xda,0xf0,0x73,0x1c,0x0b,0xd2,0x3e, - 0x11,0x6d,0xe4,0xcc,0x8f,0x27,0x49,0x2a,0xb6,0x8d,0x24,0x12,0x55,0x67,0x0b,0xe5, - 0x3c,0x19,0x31,0xa4,0x99,0x86,0x30,0x6c,0xbf,0x1d,0xc4,0xe0,0xfe,0x91,0xc7,0x50, - 0xb9,0x76,0xf8,0xd3,0x93,0xdf,0xf1,0x7c,0x22,0x13,0x94,0x16,0x8f,0xad,0x1e,0xaa, - 0x54,0x3f,0x75,0xe3,0xcc,0x7b,0xbb,0xc9,0xff,0x0b,0x20,0x79,0xd4,0xc2,0x76,0x7d, - 0xf7,0xc7,0xac,0xa7,0x99,0x7a,0x56,0xff,0xdc,0xf5,0xa4,0xbf,0xc8,0x38,0x42,0x06, - 0x08,0x92,0x69,0xe9,0xf3,0xda,0xb5,0xa6,0x30,0xad,0xa2,0xa3,0x37,0xfe,0xba,0x32, - 0xcb,0xda,0xe1,0x54,0x99,0x07,0x54,0xda,0x60,0x77,0x54,0x95,0x50,0xd6,0x2c,0x30, - 0x38,0x82,0x42,0x9d,0xdd,0xda,0xbb,0x62,0x53,0xa3,0x31,0xe5,0x7d,0x8f,0x2e,0x28, - 0xa1,0x7b,0x3e,0x97,0x73,0x59,0xd6,0x0d,0x02,0x7a,0xb7,0x4a,0xae,0x63,0xca,0x53, - 0xc2,0x10,0x60,0x17,0x0d,0x89,0xbc,0x58,0xf8,0x55,0x5f,0x02,0x9b,0x57,0x1e,0x0e, - 0x04,0xdb,0x9c,0xe1,0xf5,0xca,0xb6,0x4b,0x2c,0x8b,0x43,0xad,0x6b,0x46,0xa4,0xed, - 0xdc,0xf8,0xab,0x3c,0xa7,0xac,0x85,0x07,0x09,0x0f,0x35,0xd0,0xc1,0xc3,0xca,0x79, - 0x01,0x00,0x01,0x00 - }; + 0xc9, 0xca, 0xc2, 0x37, 0x65, 0xe7, 0x32, 0x8c, 0x00, 0x12, 0x5e, 0xa1, 0xb2, 0x86, + 0xc4, 0x25, 0xb4, 0xd7, 0x34, 0x87, 0x9d, 0xc2, 0x26, 0xfa, 0xae, 0x72, 0xf9, 0x2f, + 0x22, 0xbf, 0xde, 0x0a, 0xe6, 0x29, 0x6f, 0xff, 0x8d, 0x77, 0x50, 0x3c, 0xda, 0xd8, + 0x02, 0xfa, 0x02, 0x0d, 0x60, 0x78, 0x65, 0x85, 0xa8, 0xbc, 0xbe, 0xa9, 0x3c, 0x16, + 0x10, 0xda, 0xf0, 0x73, 0x1c, 0x0b, 0xd2, 0x3e, 0x11, 0x6d, 0xe4, 0xcc, 0x8f, 0x27, + 0x49, 0x2a, 0xb6, 0x8d, 0x24, 0x12, 0x55, 0x67, 0x0b, 0xe5, 0x3c, 0x19, 0x31, 0xa4, + 0x99, 0x86, 0x30, 0x6c, 0xbf, 0x1d, 0xc4, 0xe0, 0xfe, 0x91, 0xc7, 0x50, 0xb9, 0x76, + 0xf8, 0xd3, 0x93, 0xdf, 0xf1, 0x7c, 0x22, 0x13, 0x94, 0x16, 0x8f, 0xad, 0x1e, 0xaa, + 0x54, 0x3f, 0x75, 0xe3, 0xcc, 0x7b, 0xbb, 0xc9, 0xff, 0x0b, 0x20, 0x79, 0xd4, 0xc2, + 0x76, 0x7d, 0xf7, 0xc7, 0xac, 0xa7, 0x99, 0x7a, 0x56, 0xff, 0xdc, 0xf5, 0xa4, 0xbf, + 0xc8, 0x38, 0x42, 0x06, 0x08, 0x92, 0x69, 0xe9, 0xf3, 0xda, 0xb5, 0xa6, 0x30, 0xad, + 0xa2, 0xa3, 0x37, 0xfe, 0xba, 0x32, 0xcb, 0xda, 0xe1, 0x54, 0x99, 0x07, 0x54, 0xda, + 0x60, 0x77, 0x54, 0x95, 0x50, 0xd6, 0x2c, 0x30, 0x38, 0x82, 0x42, 0x9d, 0xdd, 0xda, + 0xbb, 0x62, 0x53, 0xa3, 0x31, 0xe5, 0x7d, 0x8f, 0x2e, 0x28, 0xa1, 0x7b, 0x3e, 0x97, + 0x73, 0x59, 0xd6, 0x0d, 0x02, 0x7a, 0xb7, 0x4a, 0xae, 0x63, 0xca, 0x53, 0xc2, 0x10, + 0x60, 0x17, 0x0d, 0x89, 0xbc, 0x58, 0xf8, 0x55, 0x5f, 0x02, 0x9b, 0x57, 0x1e, 0x0e, + 0x04, 0xdb, 0x9c, 0xe1, 0xf5, 0xca, 0xb6, 0x4b, 0x2c, 0x8b, 0x43, 0xad, 0x6b, 0x46, + 0xa4, 0xed, 0xdc, 0xf8, 0xab, 0x3c, 0xa7, 0xac, 0x85, 0x07, 0x09, 0x0f, 0x35, 0xd0, + 0xc1, 0xc3, 0xca, 0x79, 0x01, 0x00, 0x01, 0x00}; const uint8_t sig[] = { - 0x8f,0xa7,0xe1,0xeb,0xed,0x03,0x6e,0x2e,0x4e,0x35,0xe1,0x4e,0x4d,0xaa,0x52,0x20, - 0x58,0xb9,0x4c,0xbb,0x32,0x02,0x0e,0x23,0x15,0xb0,0x2c,0x86,0xe7,0xe9,0xde,0x58, - 0x4e,0xf5,0xe8,0xfd,0xbe,0x44,0x6e,0xc9,0xf8,0x71,0x72,0x60,0xa7,0xce,0x3e,0x98, - 0x08,0x0c,0x77,0xe8,0x9b,0x59,0xc7,0x0d,0xf8,0x8f,0x0e,0x59,0xe6,0x88,0x01,0x69, - 0x5e,0xaf,0xdf,0x66,0x68,0x5a,0x33,0xf6,0x8f,0x11,0x0b,0x2c,0x90,0xa7,0x33,0x37, - 0x42,0x8f,0x93,0x9c,0x52,0x88,0xe2,0x3c,0xa7,0xcd,0x74,0x2c,0xde,0x40,0xad,0x7d, - 0x99,0x02,0xa8,0xe7,0x77,0x26,0xe9,0xa3,0xd7,0x8c,0x32,0x4b,0xe1,0x76,0x09,0x76, - 0xe4,0x52,0xa1,0x92,0xc3,0xf6,0x25,0x42,0x36,0x72,0xd8,0xb3,0x7e,0xbe,0xa9,0x43, - 0x76,0x20,0xb1,0xbb,0x75,0x39,0x43,0x66,0x19,0x30,0x3e,0x35,0xe2,0x26,0x09,0x01, - 0x53,0x84,0xd0,0x00,0xd6,0xfc,0x5c,0x04,0x56,0xd6,0x63,0xc7,0xee,0xfa,0x73,0xe8, - 0xc1,0x2d,0xfc,0xb1,0xe3,0xf6,0x30,0x05,0xff,0xe3,0x64,0x70,0x2f,0x2a,0x06,0xc6, - 0x20,0xd1,0xa3,0xe1,0x4f,0xad,0x28,0xf7,0x1e,0x9b,0x15,0xa7,0x92,0x3a,0x3e,0x8f, - 0x7f,0x04,0xbe,0x97,0x7b,0xd2,0xa4,0x75,0x49,0xd7,0xc4,0x5f,0xce,0x52,0x4d,0x19, - 0xba,0xcc,0x99,0x01,0xec,0xe3,0xe3,0x0d,0xd5,0x6d,0x0b,0x83,0x3e,0x54,0x35,0xff, - 0x15,0x9d,0x0b,0x5b,0xb7,0xed,0x58,0x82,0x9e,0x00,0xe5,0xfe,0x55,0x2f,0x69,0xed, - 0x9a,0x27,0xbe,0x5f,0xe6,0x6e,0xa6,0x9f,0x4d,0x67,0x13,0x39,0xc3,0x85,0x12,0x67 - }; + 0xb9, 0x5f, 0x69, 0xef, 0x37, 0x5b, 0x03, 0xc4, 0xf3, 0x8d, 0x1d, 0x56, 0xad, 0x97, + 0xb6, 0x3d, 0x2a, 0x9c, 0x91, 0x97, 0xc2, 0xb8, 0x9d, 0xf2, 0x33, 0x15, 0x60, 0xd4, + 0xa8, 0x5e, 0xa1, 0x59, 0x15, 0x9a, 0x57, 0x96, 0xfc, 0x26, 0xae, 0x9d, 0x25, 0xba, + 0xbf, 0x77, 0x78, 0x26, 0xe7, 0x50, 0x7b, 0x3b, 0xf1, 0xcf, 0xd3, 0xda, 0x80, 0x5d, + 0xcd, 0xd1, 0xaf, 0xc5, 0x1a, 0x69, 0xb0, 0x37, 0x61, 0xde, 0x3c, 0x8a, 0x13, 0x2d, + 0x35, 0xfb, 0x10, 0xd9, 0x87, 0x05, 0xf0, 0xe6, 0x23, 0x93, 0x6c, 0xb3, 0x9f, 0x8a, + 0xe4, 0x02, 0x5b, 0x62, 0x0c, 0x8c, 0x47, 0x85, 0x30, 0x47, 0x5e, 0x44, 0xd3, 0x91, + 0xfd, 0x95, 0xe0, 0xc9, 0x50, 0x65, 0xf1, 0xfa, 0x6e, 0x2b, 0x48, 0xdd, 0xd2, 0x3e, + 0x42, 0xf4, 0x81, 0xdc, 0xb2, 0x4a, 0xcb, 0xdd, 0x61, 0xe0, 0x38, 0x36, 0x44, 0x06, + 0x3f, 0x93, 0x4f, 0x80, 0x9b, 0xff, 0xbb, 0x08, 0x1a, 0xfa, 0xaf, 0x28, 0x2d, 0x72, + 0x27, 0x79, 0x58, 0x79, 0x4e, 0xcb, 0x96, 0x45, 0x12, 0x41, 0xd4, 0x78, 0xd9, 0x32, + 0x26, 0xea, 0x59, 0xd9, 0x18, 0x92, 0xa3, 0xf8, 0x14, 0xf7, 0xc8, 0x67, 0xa5, 0xec, + 0x86, 0xc6, 0xa8, 0x7a, 0x25, 0xa9, 0x55, 0xb3, 0x49, 0x56, 0x36, 0x8e, 0x2b, 0x25, + 0x3b, 0xab, 0xe7, 0x64, 0x6c, 0xfd, 0x5e, 0x23, 0xb5, 0x30, 0x43, 0xad, 0xef, 0x6e, + 0x69, 0xed, 0xcf, 0x2a, 0xba, 0xf7, 0xc0, 0xbe, 0xf0, 0xe6, 0xd0, 0x40, 0xcf, 0xe5, + 0xc0, 0x5c, 0xa5, 0x60, 0xa1, 0x2c, 0xe6, 0xd3, 0xd8, 0xfa, 0x5c, 0xe2, 0x7e, 0xc5, + 0x88, 0x12, 0x19, 0x85, 0x93, 0x10, 0x74, 0x75, 0xad, 0x9c, 0x21, 0x8f, 0xcd, 0x22, + 0xf4, 0xb0, 0xae, 0xec, 0x9f, 0xfc, 0xde, 0x61, 0x03, 0x13, 0x4f, 0x1d, 0x1f, 0x54, + 0xfd, 0xec, 0x61, 0x82}; const uint32_t in_buf[] = { - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000}; + 0x001c0001, 0x31303050, 0x31303043, 0x00000001, 0x00000800, 0x000007ac, 0xc1d80142, + 0x4c425346, 0x00010001, 0x00000001, 0x00000540, 0xa020005c, 0xa020005c, 0x00000040, + 0x00000000, 0x00000020, 0x00000104, 0x1c000100, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xd4ac0000, 0x01180000, 0x61e02000, 0x80800004, 0x00001187, 0x00461e02, + 0x18780800, 0xe0200001, 0x80000461, 0x00118780, 0x461e0200, 0x78080000, 0x20000118, + 0x000461e0, 0x11878080, 0x1e020000, 0x08000046, 0x00011878, 0x0461e020, 0x87808000, + 0x02000011, 0x0000461e, 0x01187808, 0x61e02000, 0x80800004, 0x00001187, 0x00461e02, + 0x18780800, 0xe0200001, 0x80000461, 0x00118780, 0x461e0200, 0x78080000, 0x20000118, + 0x000461e0, 0x11878080, 0x1e020000, 0x08000046, 0x00011878, 0x0461e020, 0x87808000, + 0x02000011, 0x0000461e, 0x01187808, 0x61e02000, 0x80800004, 0x00001187, 0x00461e02, + 0x18780800, 0xe0200001, 0x80000461, 0x00118780, 0x461e0200, 0x78080000, 0x40080018, + 0x200061e0, 0x01878100, 0x1e040080, 0x10020006, 0x08001878, 0x0061e040, 0x87810020, + 0x04008001, 0x0200061e, 0x00187810, 0x61e04008, 0x81002000, 0x00800187, 0x00061e04, + 0x18781002, 0xe0400800, 0x00200061, 0x80018781, 0x061e0400, 0x78100200, 0x40080018, + 0x200061e0, 0x01878100, 0x1e040080, 0x10020006, 0x08001878, 0x0061e040, 0x87810020, + 0x04008001, 0x0200061e, 0x00187810, 0x61e04008, 0x81002000, 0x00800187, 0x00061e04, + 0x18781002, 0xe0400800, 0x00200061, 0x80018781, 0x061e0400, 0x78100200, 0x40080018, + 0x200061e0, 0x01878100, 0x1e040080, 0x10020006, 0x08001878, 0x0061e040, 0x87810020, + 0x04008001, 0x0200061e, 0x1e01f810, 0x00000000, 0x02000600, 0x00187810, 0x61e04008, + 0x81002000, 0x00800187, 0x00061e04, 0x18781002, 0xe0400800, 0x00200061, 0x80018781, + 0x061e0400, 0x78100200, 0x40080018, 0x200061e0, 0x01878100, 0x1e040080, 0x10020006, + 0x08001878, 0x0061e040, 0x87810020, 0x04008001, 0x0200061e, 0x00187810, 0x61e04008, + 0x81002000, 0x00800187, 0x00061e04, 0x18781002, 0xe0400800, 0x00200061, 0x80018781, + 0x061e0400, 0x78100200, 0x40080018, 0x200061e0, 0x01878100, 0x1e040080, 0x10020006, + 0x08001878, 0x0061e040, 0x87810020, 0x04008001, 0x0200061e, 0x00187810, 0x61e04008, + 0x81002000, 0x00800187, 0x00061e04, 0x18781002, 0xe0400800, 0x00200061, 0x80018781, + 0x461e0400, 0x78080000, 0x20000118, 0x000461e0, 0x11878080, 0x1e020000, 0x08000046, + 0x00011878, 0x0461e020, 0x87808000, 0x02000011, 0x0000461e, 0x01187808, 0x61e02000, + 0x80800004, 0x00001187, 0x00461e02, 0x18780800, 0xe0200001, 0x80000461, 0x00118780, + 0x461e0200, 0x78080000, 0x20000118, 0x000461e0, 0x11878080, 0x1e020000, 0x08000046, + 0x00011878, 0x0461e020, 0x87808000, 0x02000011, 0x0000461e, 0x01187808, 0x61e02000, + 0x80800004, 0x00001187, 0x00461e02, 0x18780800, 0xe0200001, 0x80000461, 0x00118780, + 0x461e0200, 0x78080000, 0x20000118, 0x000461e0, 0x11878080, 0x1e020000, 0x08000046, + 0x00011878, 0x0461e020, 0x87808000, 0x02000011, 0x000007fe, 0x00000000, 0xae36d32c, + 0x14303ef3, 0x4f34b247, 0xd0002090, 0x50000000, 0x04045010, 0x00003400, 0x14041400, + 0x0008c101, 0x230f0100, 0x3c040000, 0x1000008c, 0x000230f0, 0x08c3c040, 0x0f010000, + 0x04000023, 0x00008c3c, 0x0230f010, 0xc3c04000, 0x01000008, 0x0000230f, 0x008c3c04, + 0x30f01000, 0xc0400002, 0x000008c3, 0x00230f01, 0x8c3c0400, 0xf0100000, 0x40000230, + 0x0008c3c0, 0x230f0100, 0x3c040000, 0x1000008c, 0x000230f0, 0x08c3c040, 0x0f010000, + 0x04000023, 0x00008c3c, 0x0230f010, 0xc3c04000, 0x01000008, 0x0000230f, 0x008c3c04, + 0x30f01000, 0xc0400002, 0x000008c3, 0x00230f01, 0x8c3c0400, 0xf0100000, 0x40000230, + 0x0008c3c0, 0x230f0100, 0x3c040000, 0x1000008c, 0x000230f0, 0x08c3c040, 0x0f010000, + 0x04000023, 0x00008c3c, 0x0230f010, 0xc3c04000, 0x02004000, 0x0100030f, 0x000c3c08, + 0x30f02004, 0xc0801000, 0x004000c3, 0x00030f02, 0x0c3c0801, 0xf0200400, 0x80100030, + 0x4000c3c0, 0x030f0200, 0x3c080100, 0x2004000c, 0x100030f0, 0x00c3c080, 0x0f020040, + 0x08010003, 0x04000c3c, 0x0030f020, 0xc3c08010, 0x02004000, 0x0100030f, 0x000c3c08, + 0x30f02004, 0xc0801000, 0x004000c3, 0x00030f02, 0x0c3c0801, 0xf0200400, 0x80100030, + 0x4000c3c0, 0x030f0200, 0x3c080100, 0x2004000c, 0x100030f0, 0x00c3c080, 0x0f020040, + 0x08010003, 0x04000c3c, 0x0030f020, 0xc3c08010, 0x02004000, 0x0100030f, 0x000c3c08, + 0x30f02004, 0xc0801000, 0x004000c3, 0x00030f02, 0x0c3c0801, 0xf0200400, 0x80100030, + 0x00f00fc0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x37c2cac9, 0x8c32e765, 0xa15e1200, 0x25c486b2, 0x8734d7b4, + 0xfa26c29d, 0x2ff972ae, 0x0adebf22, 0xff6f29e6, 0x3c50778d, 0xfa02d8da, 0x78600d02, + 0xbca88565, 0x163ca9be, 0x73f0da10, 0x3ed20b1c, 0xcce46d11, 0x2a49278f, 0x12248db6, + 0xe50b6755, 0xa431193c, 0x6c308699, 0xe0c41dbf, 0x50c791fe, 0xd3f876b9, 0x7cf1df93, + 0x16941322, 0xaa1ead8f, 0xe3753f54, 0xc9bb7bcc, 0x79200bff, 0x7d76c2d4, 0xa7acc7f7, + 0xff567a99, 0xbfa4f5dc, 0x064238c8, 0xe9699208, 0xa6b5daf3, 0xa3a2ad30, 0x32bafe37, + 0x54e1dacb, 0xda540799, 0x95547760, 0x302cd650, 0x9d428238, 0x62bbdadd, 0xe531a353, + 0x282e8f7d, 0x973e7ba1, 0x0dd65973, 0x4ab77a02, 0x53ca63ae, 0x176010c2, 0x58bc890d, + 0x025f55f8, 0x0e1e579b, 0xe19cdb04, 0x4bb6caf5, 0xad438b2c, 0xeda4466b, 0x3cabf8dc, + 0x0785aca7, 0xd0350f09, 0x79cac3c1, 0x00010001, 0x00000000, 0x00000000, 0x00000000, + 0xef695fb9, 0xc4035b37, 0x561d8df3, 0x3db697ad, 0x97919c2a, 0xf29db8c2, 0xd4601533, + 0x59a15ea8, 0x96579a15, 0x9dae26fc, 0x77bfba25, 0x50e72678, 0xcff13b7b, 0x5d80dad3, + 0xc5afd1cd, 0x37b0691a, 0x8a3cde61, 0xfb352d13, 0x0587d910, 0x9323e6f0, 0x8a9fb36c, + 0x625b02e4, 0x85478c0c, 0x445e4730, 0x95fd91d3, 0x6550c9e0, 0x2b6efaf1, 0x3ed2dd48, + 0xdc81f442, 0xddcb4ab2, 0x3638e061, 0x933f0644, 0xff9b804f, 0xfa1a08bb, 0x722d28af, + 0x79587927, 0x4596cb4e, 0x78d44112, 0xea2632d9, 0x9218d959, 0xf714f8a3, 0xeca567c8, + 0x7aa8c686, 0xb355a925, 0x8e365649, 0xab3b252b, 0xfd6c64e7, 0x30b5235e, 0x6eefad43, + 0x2acfed69, 0xbec0f7ba, 0x40d0e6f0, 0x5cc0e5cf, 0x2ca160a5, 0xfad8d3e6, 0xc57ee25c, + 0x85191288, 0x75741093, 0x8f219cad, 0xb0f422cd, 0xfc9fecae, 0x130361de, 0x541f1d4f, + 0x8261ecfd, 0xa554c3b8, 0x00007ef9, 0x00000004, 0x00000000, 0xa558d2c0, 0x00007ef9, + 0xa557a038, 0x00007ef9, 0xa5576900, 0x00007ef9, 0x00000005, 0x00000000, 0xa558d2c0, + 0x00007ef9, 0xa557a040, 0x00007ef9, 0xa5576900, 0x00007ef9, 0xbfaab6b0, 0x00005cf3, + 0xa5576700}; lvSignCtx.app_sessn_state = NULL; lvSignCtx.device = pufs; @@ -742,7 +771,7 @@ void pufs_rsa2048_verify_test(const struct device *pufs) lvSignCtx.ops.signing_mode = CRYPTO_SIGN_VERIFY; lvSignPkt.ctx = &lvSignCtx; - lvSignPkt.in_buf = (uint8_t*)in_buf; + lvSignPkt.in_buf = (uint8_t *)in_buf; lvSignPkt.in_len = sizeof(in_buf); lvStatus = sign_begin_session(pufs, &lvSignCtx, CRYPTO_SIGN_ALGO_RSA2048); @@ -750,7 +779,8 @@ void pufs_rsa2048_verify_test(const struct device *pufs) printf("%s sign_begin_session Failed! %s\n", ATTR_ERR, ATTR_RST); } else { printf("%s sign_begin_session Success! %s\n", ATTR_INF, ATTR_RST); - printf("%s in_buf_len:%d bytes %s\n", ATTR_INF, lvSignPkt.in_len, ATTR_RST); + printf("%s in_buf_addr:0x%08x in_buf_len:%d bytes %s\n", ATTR_INF, + (uint32_t)lvSignPkt.in_buf, lvSignPkt.in_len, ATTR_RST); lvStatus = sign_op_handler(&lvSignCtx, &lvSignPkt); } @@ -798,7 +828,9 @@ int main(void) ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); - pufs_rsa2048_verify_test(pufs); while(true); // TODO Remove while + pufs_rsa2048_verify_test(pufs); + while (true) + ; // TODO Remove while pufs_decryption_test(pufs); pufs_hash_test(pufs); pufs_hash_sg_test(pufs); From 69e9b921793a103f109840ecab9e7209cc3d8877 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 17 Oct 2024 21:15:18 +0500 Subject: [PATCH 47/58] RSA2048 signature verification in progress --- drivers/crypto/crypto_pufs.c | 65 +- drivers/crypto/pufcc.c | 67 +- drivers/crypto/pufcc.h | 4 +- include/zephyr/crypto/sign.h | 7 + samples/hello_world/src/main.c | 1107 ++++++++++++++++++++++++++++---- soc/rapidsilicon/virgo/scu.c | 12 +- soc/rapidsilicon/virgo/scu.h | 12 + 7 files changed, 1113 insertions(+), 161 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index 494fd5b1a8c71..e19095af916bc 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -36,7 +36,7 @@ uint8_t __pufcc_descriptors[BUFFER_SIZE]; static int pufs_query_hw_caps(const struct device *dev); -static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data_addr) { +static int fill_rs_crypto_hash_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data_addr) { uint8_t desc_count = 0; if((pkt == NULL) || (data_addr == NULL)) { @@ -67,8 +67,46 @@ static int fill_rs_crypto_addr(struct hash_pkt *pkt, struct rs_crypto_addr *data if (pkt) { // No enough descriptors available - LOG_ERR("%s(%d) Not More Than %d Elements Allowed. Desc_Count:%d\n", \ - __func__, __LINE__, (BUFFER_SIZE/sizeof(struct pufcc_sg_dma_desc)), desc_count); + LOG_ERR("%s(%d) Not More Than %d Elements Allowed. Count:%d\n", \ + __func__, __LINE__, (BUFFER_SIZE/sizeof(struct pufcc_sg_dma_desc)), desc_count+1); + return -ENOTEMPTY; + } + + return PUFCC_SUCCESS; +} + +static int fill_rs_crypto_sign_addr(struct sign_pkt *pkt, struct rs_crypto_addr *data_addr) { + + uint8_t desc_count = 0; + + if((pkt == NULL) || (data_addr == NULL)) { + LOG_ERR("%s(%d) NULL pointer(s)\n", __func__, __LINE__); + return -EBADFD; + } + + while(true) { + + data_addr[desc_count].read_addr = (uint32_t)pkt->in_buf; + data_addr[desc_count].len = pkt->in_len; + + if((desc_count * sizeof(struct pufcc_sg_dma_desc)) < BUFFER_SIZE){ + pkt = pkt->next; + } else { + break; + } + if(pkt != NULL) { + data_addr[desc_count].next = &data_addr[desc_count+1]; + } else { + data_addr[desc_count].next = NULL; + break; + } + desc_count++; + } + + if (pkt) { + // No enough descriptors available + LOG_ERR("%s(%d) Not More Than %d Elements Allowed. Count:%d\n", \ + __func__, __LINE__, (BUFFER_SIZE/sizeof(struct pufcc_sg_dma_desc)), desc_count+1); return -ENOTEMPTY; } @@ -321,9 +359,10 @@ static int pufs_hash_op(struct hash_ctx *ctx, struct hash_pkt *pkt, bool finish) struct rs_crypto_addr lvHash_Data_Addr[(BUFFER_SIZE/sizeof(struct rs_crypto_addr))] = {0}; struct hash_pkt *lvPkt = &pkt[0]; + int error = fill_rs_crypto_hash_addr(pkt, lvHash_Data_Addr); - if(fill_rs_crypto_addr(pkt, lvHash_Data_Addr) != PUFCC_SUCCESS) { - return -ENOTEMPTY; + if(error != PUFCC_SUCCESS) { + return error; } struct rs_crypto_hash hash_in = {0}; @@ -438,21 +477,27 @@ static int pufs_hash_async_callback_set(const struct device *dev, hash_completio return PUFCC_SUCCESS; } +/////////////////////////////////////////////////////////////// int pufs_sign_rsa_op(struct sign_ctx *ctx, struct sign_pkt *pkt) { enum pufcc_status lvStatus = PUFCC_SUCCESS; + int error = 0; + ((struct pufs_data*)ctx->device->data)->pufs_pkt.sign_pkt = pkt; ((struct pufs_data*)ctx->device->data)->pufs_ctx.sign_ctx = ctx; - struct rs_crypto_addr msg_addr = { - .read_addr = (uint32_t)pkt->in_buf, - .len = pkt->in_len - }; + struct rs_crypto_addr msg_addr[(BUFFER_SIZE/sizeof(struct rs_crypto_addr))] = {0}; + + error = fill_rs_crypto_sign_addr(pkt, msg_addr); + + if(error != PUFCC_SUCCESS) { + return error; + } lvStatus = pufcc_rsa2048_sign_verify( (uint8_t *)ctx->sig, - &msg_addr, + msg_addr, (struct rs_crypto_rsa2048_puk *)ctx->pub_key ); diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 47082cfd3c3d5..576afcca5e199 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -93,13 +93,13 @@ struct pufcc_ecc_param ecc_param_nistp256 = { }; // Base register addresses of different PUFcc modules -static struct pufcc_dma_regs *dma_regs; -static struct pufcc_rt_regs *rt_regs; -static struct pufcc_otp_mem *otp_mem; -static struct pufcc_hmac_regs *hmac_regs; -static struct pufcc_crypto_regs *crypto_regs; -static struct pufcc_sp38a_regs *sp38a_regs; -static struct pufcc_pkc_regs *pkc_regs; +static volatile struct pufcc_dma_regs *dma_regs; +static volatile struct pufcc_rt_regs *rt_regs; +static volatile struct pufcc_otp_mem *otp_mem; +static volatile struct pufcc_hmac_regs *hmac_regs; +static volatile struct pufcc_crypto_regs *crypto_regs; +static volatile struct pufcc_sp38a_regs *sp38a_regs; +static volatile struct pufcc_pkc_regs *pkc_regs; /***************************************************************************** * Local function declarations @@ -507,17 +507,29 @@ enum pufcc_status pufcc_rsa2048_sign_verify( enum pufcc_status status = PUFCC_SUCCESS; uint32_t temp32; uint8_t dec_msg[PUFCC_RSA_2048_LEN]; - // Configure signature scheme temp32 = 0; - + printf("%s(%d) msg-1st-word:0x%08x\r\r\n", __func__, __LINE__, \ + *(uint32_t*)msg_addr->read_addr); struct pufcc_pkc_ecp_ec_reg *ecp_ec_reg = (struct pufcc_pkc_ecp_ec_reg *)&temp32; ecp_ec_reg->field = PUFCC_RSA_2048; REG_WRITE_32(&pkc_regs->ecp_ec, ecp_ec_reg); + // .... Public key print TODO + printf("%s(%d) Public Key\r\n", __func__, __LINE__); + for(int i = 0; i < 256; i++) { + printf("0x%02x%s", pub_key->n[i], (i+1)%16==0?"\r\n":","); + } printf("\r\n"); + //////////////////////////// // Reverse public key modulus reverse(pufcc_buffer, pub_key->n, PUFCC_RSA_2048_LEN); + // .... Reversed Public key print TODO + // printf("%s(%d) Reversed Public Key\r\n", __func__, __LINE__); + // for(int i = 0; i < 256; i++) { + // printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); + // } printf("\r\n"); + //////////////////////////// // Write reversed public key modulus to ECP data field at proper offset memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET, @@ -525,10 +537,22 @@ enum pufcc_status pufcc_rsa2048_sign_verify( // Write public key exponent to ecp_e_short register REG_WRITE_32(&pkc_regs->ecp_e_short, &pub_key->e); - printf("%s(%d) pubKey_expo:0x%08x\n", __func__,__LINE__, pub_key->e); - + printf("%s(%d) pubKey_expo:0x%08x\r\n", __func__,__LINE__, pub_key->e); + + // .... Signature print TODO + printf("%s(%d) Signature\r\n", __func__, __LINE__); + for(int i = 0; i < 256; i++) { + printf("0x%02x%s", sig[i], (i+1)%16==0?"\r\n":","); + } printf("\r\n"); + //////////////////////////// // Reverse signature reverse(pufcc_buffer, sig, PUFCC_RSA_2048_LEN); + // .... Reversed Signature print TODO + // printf("%s(%d) Reversed Signature\r\n", __func__, __LINE__); + // for(int i = 0; i < 256; i++) { + // printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); + // } printf("\r\n"); + //////////////////////////// // Write reversed signature to ECP data field at proper offset memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, @@ -552,7 +576,7 @@ enum pufcc_status pufcc_rsa2048_sign_verify( status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); if (status != PUFCC_SUCCESS) { - printf("%s(%d)\n", __func__,__LINE__); + printf("%s(%d) ecp_err_code:0x%x\r\n", __func__,__LINE__, pkc_regs->ecp_err_code); return status; } @@ -561,7 +585,7 @@ enum pufcc_status pufcc_rsa2048_sign_verify( (uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, PUFCC_RSA_2048_LEN); reverse(dec_msg, pufcc_buffer, PUFCC_RSA_2048_LEN); - + status = rsa_p1v15_verify(dec_msg, msg_addr); return status; @@ -1200,7 +1224,7 @@ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, 0, 0x05, 0x00, 0x04, 0}; if ((dec_msg[0] != 0x00) || (dec_msg[1] != 0x01)) { - printf("%s(%d)\n", __func__,__LINE__); + printf("%s(%d)\r\n", __func__,__LINE__); return PUFCC_E_VERFAIL; } @@ -1211,7 +1235,7 @@ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, } if (dec_msg[i++] != 0x00) { - printf("%s(%d)\n", __func__,__LINE__); + printf("%s(%d)\r\n", __func__,__LINE__); return PUFCC_E_VERFAIL; } @@ -1221,25 +1245,25 @@ static enum pufcc_status rsa_p1v15_verify(const uint8_t *dec_msg, pret[14] = 0x01; pret[18] = 0x20; } else { - printf("%s(%d)\n", __func__,__LINE__); + printf("%s(%d)\r\n", __func__,__LINE__); return PUFCC_E_INVALID; } if ((memcmp(dec_msg + i, pret, 19) != 0) || ((i + 19 + pret[18]) != PUFCC_RSA_2048_LEN)) { - printf("%s(%d)\n", __func__,__LINE__); + printf("%s(%d)\r\n", __func__,__LINE__); return PUFCC_E_VERFAIL; } // Calculate hash of the message if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != PUFCC_SUCCESS) { - printf("%s(%d)\n", __func__,__LINE__); + printf("%s(%d)\r\n", __func__,__LINE__); return PUFCC_E_ERROR; } if (memcmp(dec_msg + i + 19, hash.val, hash.len) != 0) { - printf("%s(%d)\n", __func__,__LINE__); + printf("%s(%d)\r\n", __func__,__LINE__); return PUFCC_E_VERFAIL; } @@ -1333,10 +1357,11 @@ static enum pufcc_status busy_wait(volatile uint32_t *status_reg_addr, } while ((status & PUFCC_BUSY_BIT_MASK) && (busy_count > 0)); if (status & PUFCC_BUSY_BIT_MASK) { - printf("%s(%d)\n", __func__,__LINE__); + printf("%s(%d)\r\n", __func__,__LINE__); return PUFCC_E_TIMEOUT; } else if (status & error_mask) { - printf("%s(%d) status 0x%08x\n", __func__,__LINE__, status); + printf("%s(%d) status 0x%08x ecp_err_code:0x%x\r\n", \ + __func__,__LINE__, status, pkc_regs->ecp_err_code); return PUFCC_E_ERROR; } diff --git a/drivers/crypto/pufcc.h b/drivers/crypto/pufcc.h index 565332a113b94..a53a56522cc2c 100644 --- a/drivers/crypto/pufcc.h +++ b/drivers/crypto/pufcc.h @@ -424,13 +424,13 @@ struct pufcc_pkc_regs { volatile uint32_t ecp_err_pc; volatile uint32_t ecp_err_cmd; volatile uint32_t mp_version; - uint32_t _pad1[56]; + volatile uint32_t _pad1[56]; volatile uint32_t ecp_ec; volatile uint32_t ecp_keysel; volatile uint32_t ecp_otpkba; volatile uint32_t ecp_key_usage; volatile uint32_t ecp_e_short; - uint32_t _pad2[55]; + volatile uint32_t _pad2[55]; volatile uint32_t ecp_mac[4]; volatile uint32_t ecp_data[512]; }; diff --git a/include/zephyr/crypto/sign.h b/include/zephyr/crypto/sign.h index fe05f3164275b..33c5cacfe5da1 100644 --- a/include/zephyr/crypto/sign.h +++ b/include/zephyr/crypto/sign.h @@ -163,6 +163,13 @@ struct sign_pkt { */ int out_len; + /** + * The pointer is for creating a linkedlist of + * incoming data in case the sign is calculated / verified + * in chunks where data might be coming from different places. + */ + struct sign_pkt *next; + /** Context this packet relates to. This can be useful to get the * session details, especially for async ops. Will be populated by the * sign_xxx_op() API based on the ctx parameter. diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index a31b76f83bf02..d5cabfb3803fa 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -636,6 +636,922 @@ void pufs_decryption_test(const struct device *pufs) } } +// const uint32_t in_buf[] = { +// 0x4c425346, 0x00010001, 0x00000001, 0x00002e80, 0xa020005c, 0xa020005c, 0x00000040, +// 0x00000000, 0x00000020, 0x00000104, 0x3c000100, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0xa54a0000, 0xa02000b7, 0x06408067, 0x30405073, 0x34405073, 0x41014081, +// 0x42014181, 0x43014281, 0x44014381, 0x46814481, 0x47814701, 0x48814801, 0x49814901, +// 0x4a814a01, 0x4b814b01, 0x4c814c01, 0x4d814d01, 0x4e814e01, 0x4f814f01, 0x00100197, +// 0x75c18193, 0xf14023f3, 0x00000293, 0x0072f463, 0x01d0106f, 0x0018128b, 0x62858116, +// 0x80028293, 0x025382b3, 0x40510133, 0x006f840a, 0x12ef0040, 0x25731290, 0x10eff140, +// 0xc91576e0, 0x8c1f978b, 0x8b9f960b, 0x40c78633, 0x950b4581, 0x10ef8b9f, 0x960b0530, +// 0x978b801f, 0x35b78b9f, 0x8633a020, 0x859340c7, 0x950bde85, 0x10ef801f, 0x27b77c60, +// 0x8793a020, 0x90737fc7, 0x07938007, 0xa0732000, 0x07b77d07, 0x8793a020, 0x90734037, +// 0x84303057, 0x20078793, 0x30779073, 0xfc2027f3, 0x01c7f85b, 0xa02007b7, 0x30178793, +// 0x7ec79073, 0xe2000737, 0x00074783, 0xf7938420, 0xe7930817, 0x05130047, 0x0023c085, +// 0x00ef00f7, 0x10ef6890, 0xe51944a0, 0x05138420, 0x00efc245, 0xa0016790, 0x05138420, +// 0x00efc405, 0xbfd566d0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, +// 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, +// 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, +// 0xa0201528, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa020157c, 0xa0200472, +// 0xa020159a, 0xa0200504, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, +// 0xa02005b6, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, +// 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, +// 0xa0200472, 0xa0200472, 0xa0200472, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0xc006711d, 0xc416c212, 0xc81ec61a, 0xcc2eca2a, +// 0xd036ce32, 0xd43ed23a, 0xd846d642, 0xdc76da72, 0xc0fede7a, 0x7ee8d073, 0x7ef95073, +// 0x7ed090f3, 0x42a24212, 0x43c24332, 0x45e24552, 0x56824672, 0x57a25712, 0x58c25832, +// 0x5ee25e52, 0x4f865f72, 0x70734096, 0x90733004, 0x40a63420, 0x34109073, 0x345020f3, +// 0xfc0094e3, 0x61254082, 0x30200073, 0x00000013, 0x00000013, 0x00000013, 0x00000013, +// 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, +// 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, +// 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, +// 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, +// 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0xc0067119, 0xc416c212, 0xc81ec61a, +// 0xcc2eca2a, 0xd036ce32, 0xd43ed23a, 0xd846d642, 0xdc76da72, 0xc0fede7a, 0x341022f3, +// 0x30002373, 0xc49ac296, 0x34202573, 0x10ef858a, 0x77f34220, 0x42963004, 0x90734326, +// 0x10733412, 0x40823003, 0x42a24212, 0x43c24332, 0x45e24552, 0x56824672, 0x57a25712, +// 0x58c25832, 0x5ee25e52, 0x4f865f72, 0x00736109, 0x80823020, 0xff950793, 0x07db8030, +// 0x67410cf7, 0xc3980705, 0xe20017b7, 0x00178713, 0x0ca7075b, 0x078d4685, 0xe2000837, +// 0x00d70023, 0x00251593, 0x00084683, 0x0ca7855b, 0x00054703, 0x1016a6db, 0x00d71733, +// 0x57334621, 0x478940d7, 0x96b38020, 0x8f5500d7, 0x00238810, 0x470300e5, 0x275b0008, +// 0x5f5b1017, 0x47830087, 0x07330005, 0xd7b340e6, 0x97b340e7, 0xe79300e7, 0x8c140017, +// 0x00f50023, 0xe20017b7, 0x97ae0789, 0x77138004, 0x80230fe7, 0x808200e7, 0x970b1101, +// 0xca4a81df, 0xc25ac652, 0xce06c05e, 0xc84ecc26, 0x4318c456, 0x81df9b0b, 0x03072a83, +// 0x9a0b4901, 0x4b8581df, 0x01090993, 0x00890493, 0x013b99b3, 0x012b97b3, 0x009b94b3, +// 0x0159f9b3, 0x9b638cdd, 0xf7b30009, 0x567d00fa, 0x4609e391, 0x0154f7b3, 0xa801e399, +// 0x27834601, 0x2503068b, 0x85ca048b, 0x27839782, 0xf4b3000a, 0xe4b30154, 0x09050134, +// 0x0b11db84, 0xba79685b, 0x44e240f2, 0x49c24952, 0x4aa24a32, 0x4b824b12, 0x80826105, +// 0x07b7cd99, 0x5bd8a042, 0x765b4581, 0x47030057, 0x45850005, 0x4505d398, 0x8d4d05c2, +// 0x45018082, 0x978bbfe5, 0x4394805f, 0x42d875c1, 0x15f94a90, 0x80148f6d, 0xc2d89a79, +// 0x00c03633, 0x4b884bd8, 0x40c00633, 0x87024581, 0x3fa012ef, 0x77938a3e, 0x8aaa0038, +// 0x89b28b2e, 0x893a8bb6, 0x84b28c42, 0x84bae785, 0x40e60cb3, 0x56fda031, 0x801085da, +// 0x9a820485, 0x009c8633, 0xff44e9e3, 0x64634481, 0x04b3012a, 0x94ce412a, 0x852694ca, +// 0x41248633, 0x00091c63, 0x001c785b, 0x413484b3, 0x00998533, 0x0144ed63, 0x3d60106f, +// 0x87b3197d, 0xc503012b, 0x56fd0007, 0x9a8285da, 0x862abfc9, 0x85da56fd, 0x04858010, +// 0xbfd99a82, 0x3a2012ef, 0x48528342, 0x47c28e3e, 0x4418735b, 0x00187e93, 0x8963cb91, +// 0x1663000e, 0x7f13000e, 0x036300c8, 0x17fd000f, 0x03000f13, 0x59dba801, 0x8fb30007, +// 0x070500e6, 0x01ef8023, 0xff1769e3, 0x0f934f7d, 0x86630300, 0x7463000e, 0x7c6300f7, +// 0x755b02ef, 0x7f5b0648, 0xcf0d42a8, 0x00e88463, 0x02f71a63, 0xfff70893, 0x02088563, +// 0x555b1779, 0x87460303, 0x02236c5b, 0xeb6348fd, 0x800004e8, 0x06200313, 0x82b3a015, +// 0x802300e6, 0x070501f2, 0x4701bf5d, 0xbf03605b, 0x7e5b48fd, 0xe9634258, 0x800002e8, +// 0x07800313, 0x84040705, 0xe16348fd, 0x800002e8, 0x03000313, 0x84040705, 0xe96348fd, +// 0x006300e8, 0x8000020e, 0x02d00313, 0x84040705, 0x106f3d45, 0xede32f40, 0x8000fee8, +// 0x05800313, 0x765bb7e1, 0x80000028, 0x02b00313, 0x715bb7c5, 0x8000be38, 0x02000313, +// 0x7159bfd1, 0xced2d2ca, 0xccd6893a, 0xc6e2cada, 0xc2eac4e6, 0xd6868f55, 0xd0ced4a6, +// 0xc0eec8de, 0x8a2a5c66, 0x8b328aae, 0x8d468cb6, 0x7c13e319, 0x745bfefc, 0x498100ac, +// 0x0493c335, 0x745b0610, 0x0493005c, 0x0d930410, 0x49810201, 0x14d94ba5, 0x86ea8642, +// 0x85ca8566, 0xcc42ce3e, 0x4c4010ef, 0x48628c04, 0xe66347f2, 0x051306ab, 0x8c040305, +// 0x80238642, 0x86ea00ad, 0x85ca8566, 0xcc42ce3e, 0x25c010ef, 0x47f24862, 0x69630985, +// 0x146301a9, 0xe563012d, 0x0d85010c, 0x0209eadb, 0x58c65756, 0x1014c03a, 0x865a874e, +// 0x855285d6, 0x3da9c262, 0x54a650b6, 0x59865916, 0x4ae64a76, 0x4bc64b56, 0x4ca64c36, +// 0x4d864d16, 0x80826165, 0x892e8caa, 0x9526b741, 0x12efbf69, 0x71791d40, 0xe2994e86, +// 0xfefefe93, 0x00aef35b, 0x0313c2b1, 0xf45b0610, 0x0313005e, 0x8f360410, 0x01010f93, +// 0x43a54681, 0xff630e13, 0x02ff72b3, 0x0ff2f313, 0x0253ed63, 0x03030313, 0x0ff37313, +// 0x006f8023, 0x53330685, 0x656302ff, 0x0f8500ff, 0x0006eddb, 0x88c2c046, 0x87ba883e, +// 0x08148736, 0x33f9c276, 0x106f6145, 0x8f1a1900, 0x9372b7c1, 0x711db7f1, 0x8936caca, +// 0xde62c0de, 0x8baada6a, 0x8d328c2e, 0x8636854a, 0x86ba85ba, 0xc4d6c6d2, 0xdc66c2da, +// 0xcca6ce86, 0xd86ec8ce, 0x8abe8b3a, 0x8a468cc2, 0x629010ef, 0x8c10e51d, 0x8607a603, +// 0x8647a683, 0x85da854a, 0x611010ef, 0x00a04d63, 0xa6038c10, 0xa6838687, 0x854a86c7, +// 0x10ef85da, 0x59635ff0, 0x88d20205, 0x87d68866, 0x86ca875a, 0x85e2866a, 0x2699855e, +// 0x44e640f6, 0x49c64956, 0x4aa64a36, 0x4b864b16, 0x5ce25c72, 0x5dc25d52, 0x80826125, +// 0x46814601, 0x85da854a, 0x5c1010ef, 0x84dace4a, 0x00055663, 0x800004b7, 0x0164c4b3, +// 0x400a7593, 0x735bc82e, 0x4a9940aa, 0x7944a55b, 0xc0150513, 0x4c5010ef, 0xa6038c10, +// 0xa6838707, 0x10ef8747, 0x8c105520, 0x8787a603, 0x87c7a683, 0x312010ef, 0xa75b8c10, +// 0xa6034c04, 0xa6838807, 0x07b78847, 0x8fd93ff0, 0xca2ec82a, 0x85be854a, 0x2ec010ef, +// 0xa6038c10, 0xa6838887, 0x10ef88c7, 0x48425160, 0x862a48d2, 0x854286ae, 0x10ef85c6, +// 0x10ef2d40, 0x89aa39d0, 0x461010ef, 0xa6038410, 0xa6838906, 0xc82a8946, 0x10efca2e, +// 0x84104ea0, 0x8986a603, 0x89c6a683, 0x2aa010ef, 0x373010ef, 0x47d24742, 0xa6038410, +// 0xa6838a06, 0x85be8a46, 0x853a8daa, 0x4c0010ef, 0x856ec82a, 0x10efca2e, 0x841041b0, +// 0x8a86a603, 0x8ac6a683, 0x3ffd8d93, 0x4a4010ef, 0x47d24742, 0x86ae862a, 0x85be853a, +// 0x25c010ef, 0x86ae862a, 0xd22ed02a, 0x488010ef, 0x57925702, 0x86be863a, 0xca2ec82a, +// 0x85be853a, 0xd63ed43a, 0x23e010ef, 0xa6038410, 0xd02a8b06, 0x8b46a683, 0xd22e4542, +// 0x10ef45d2, 0x3e376f60, 0x2603a020, 0x26838b8e, 0x10ef8bce, 0x862a2180, 0x454286ae, +// 0x10ef45d2, 0x84106da0, 0x8c06a603, 0x8c46a683, 0x1fe010ef, 0x86ae862a, 0x45d24542, +// 0x6c0010ef, 0x572257b2, 0x8c1086be, 0xc82aca2e, 0x8c87a503, 0x8cc7a583, 0x10ef863a, +// 0x48421d20, 0x862a48d2, 0x854286ae, 0x10ef85c6, 0x53021c80, 0x862a5392, 0x851a86ae, +// 0x10ef859e, 0x8c106860, 0x8d07a603, 0x8d47a683, 0x1aa010ef, 0x97934701, 0x863a014d, +// 0x10ef86be, 0x862a3ce0, 0xc82a86ae, 0x854aca2e, 0x10ef85a6, 0x47423f70, 0x3e3747d2, +// 0x4f63a020, 0xc83a1005, 0x8d93ca3e, 0x07930639, 0xbdb30c60, 0x0d9101b7, 0x04ba715b, +// 0xa6038c10, 0xa6838d87, 0x854a8dc7, 0x10ef85a6, 0x47633bf0, 0x8c101005, 0x8e07a603, +// 0x8e47a683, 0x85a6854a, 0x3ad010ef, 0x0e055c63, 0x0f59d863, 0x413a8ab3, 0x6a131afd, +// 0x4d81400a, 0x48014981, 0x019df463, 0x41bc8833, 0x002a7593, 0x755bd02e, 0x8363001a, +// 0x4801000d, 0x00098c63, 0x46d24642, 0x854a85a6, 0x10efd442, 0x58225ce0, 0xce2a84ae, +// 0x46814601, 0x85da854a, 0x10efc842, 0x48423570, 0x00055563, 0x800007b7, 0x45f28cbd, +// 0x889378fd, 0x86ae7ff8, 0x011a78b3, 0x872687d6, 0x85e2866a, 0x2079855e, 0xd40d84e3, +// 0x04500793, 0x405a745b, 0x06500793, 0x00150493, 0x56fd862a, 0x85e2853e, 0xd6939b82, +// 0xc63341f9, 0x47950136, 0xc03e8020, 0x88938626, 0x4801fffd, 0xd71347a9, 0x85e201f9, +// 0x3105855e, 0x83e35482, 0x04b3d004, 0x053341a5, 0xfde3009d, 0x862acf94, 0x85e256fd, +// 0x04858010, 0xb7f59b82, 0x8b8e2603, 0x8bce2683, 0x85be853a, 0x524010ef, 0xc82a19fd, +// 0xbdd1ca2e, 0xbf214a81, 0xf00a8fe3, 0x400a7593, 0xf0058be3, 0xbf011afd, 0xd2ca7159, +// 0xc8de8936, 0x8baec6e2, 0xc02a8c32, 0x854a8636, 0x85ba86ba, 0xd0ced4a6, 0xccd6ced2, +// 0xcadad686, 0xc2eac4e6, 0x89bac0ee, 0x8ac284be, 0x10ef8a46, 0xcd0926f0, 0x88528410, +// 0x470d87d6, 0x8f468693, 0x86624502, 0xf0ef85de, 0xa85993bf, 0xa6038c10, 0xa6838687, +// 0x854a86c7, 0x10ef85ce, 0x59632430, 0x84100005, 0x87d68852, 0x86934711, 0xbfc98f86, +// 0xa6038c10, 0xa6838607, 0x854a8647, 0x10ef85ce, 0x506321b0, 0x795b02a0, 0x8410002a, +// 0x8ec68693, 0x88524711, 0xb76d87d6, 0x86938410, 0x470d8e86, 0x8c10bfcd, 0x9007a603, +// 0x9047a683, 0x85ce854a, 0x1e9010ef, 0x00a04d63, 0xa6038c10, 0xa6839087, 0x854a90c7, +// 0x10ef85ce, 0x59631d70, 0x45020205, 0x885688d2, 0x86ca87a6, 0x8662874e, 0x369585de, +// 0x54a650b6, 0x59865916, 0x4ae64a76, 0x4bc64b56, 0x4ca64c36, 0x4d864d16, 0x80826165, +// 0x46814601, 0x85ce854a, 0x199010ef, 0x10055063, 0x86ce864a, 0x45814501, 0x719000ef, +// 0x892a89ae, 0xc22e4585, 0x0eaa765b, 0x47a54c81, 0x03000713, 0x0097fc63, 0x020c8613, +// 0x002606b3, 0x80230c85, 0x14fd00e6, 0xbe0ce6db, 0x854a85ce, 0x7b6010ef, 0xa0203737, +// 0xc9870713, 0x0e97075b, 0x430c4350, 0x8b2ac632, 0x10efc42e, 0x862a0670, 0x854a86ae, +// 0x00ef85ce, 0x46226bf0, 0x3db746b2, 0x10efa020, 0xca2e0ea0, 0x10efc82a, 0x8d2a7e20, +// 0x0b9010ef, 0x47d24742, 0x86ae862a, 0x85be853a, 0x695000ef, 0x898da703, 0x89cda783, +// 0x86be863a, 0xce2ecc2a, 0x0ed010ef, 0xa703c86e, 0xa783898d, 0x486289cd, 0x596348f2, +// 0x0d0504a0, 0x10ef856a, 0x862a07b0, 0x452286ae, 0x10ef45b2, 0x44630cb0, 0x0b0500a0, +// 0xc4b94d01, 0x45a54629, 0x080ce7db, 0x003a7793, 0x1017ef5b, 0x100a8d63, 0xe5814592, +// 0x00ca7793, 0x1afdc391, 0x071347fd, 0xa8cd0300, 0xbf19c202, 0xbf194499, 0x86be863a, +// 0x85c68542, 0x085010ef, 0xfc0541e3, 0x000d0463, 0xba0d7d5b, 0xbf550d05, 0x10ef855a, +// 0x862a79a0, 0x854a86ae, 0x00ef85ce, 0x44c25f30, 0xa9038d2a, 0xa9838984, 0x864a89c4, +// 0x8dae86ce, 0x04d010ef, 0x00055a63, 0x86ce864a, 0x85ee856a, 0x039010ef, 0x00a05563, +// 0x000b735b, 0x46a90b05, 0x76b3a89d, 0x0c8502cd, 0x020c8793, 0x00278533, 0x869314fd, +// 0x0fa30306, 0x56b3fed5, 0xe56302cd, 0x94e603a5, 0x03000693, 0xb40cd8db, 0x001c8713, +// 0x009c9e63, 0x100c8804, 0x00b48cb3, 0x02e00693, 0xfedc8023, 0xbf658cba, 0xb72d8d36, +// 0x8cb38814, 0x80230025, 0x8cba00dc, 0x6733bfc1, 0x0c8502db, 0x020c8613, 0x4b33960a, +// 0x071302db, 0x0fa30307, 0x03e3fee6, 0xe2dbf00b, 0xbdfdbe0c, 0x86b38804, 0x0c850024, +// 0x00e68023, 0x015cf963, 0xff97f8e3, 0x87d68852, 0x10148766, 0x47fdbb25, 0xff97eae3, +// 0xc8994492, 0x10048814, 0x009587b3, 0x02d00713, 0x80230c85, 0xbfe9fee7, 0x002a795b, +// 0x100c8804, 0x00b487b3, 0x02b00713, 0x735bb7e5, 0x8814bc3a, 0x87b31004, 0x07130095, +// 0xbfd90200, 0x23d002ef, 0x89ae892a, 0x4a054481, 0x409a05b3, 0x00998533, 0x3c05a5db, +// 0x57939902, 0x94be0105, 0xa4db8c04, 0x535b3c04, 0x006fbe15, 0xcd192470, 0x227002ef, +// 0x07a31141, 0x840000a1, 0x00f10593, 0x59450513, 0x01413f75, 0x2330006f, 0x71198082, +// 0xc0dec2da, 0x3bb76b05, 0xde62a020, 0xa0203c37, 0xcacacca6, 0x0913c6d2, 0xc4d60641, +// 0x44818a2a, 0xa0201ab7, 0x800b0b13, 0x918b8b93, 0x910c0c13, 0xc8cece86, 0xda6adc66, +// 0xd2aed86e, 0xd6b6d4b2, 0xdabed8ba, 0xdec6dcc2, 0x4503d64a, 0xe90d000a, 0x862657f9, +// 0x0097f363, 0x102c5679, 0x56fd4501, 0x40f63fbd, 0x49c64956, 0x4aa64a36, 0x4b864b16, +// 0x5ce25c72, 0x5dc25d52, 0x44e68526, 0x80826109, 0x58db0a05, 0x89930055, 0x56fd0014, +// 0x102c8626, 0x4881aa05, 0x02b00713, 0xdddba801, 0xe1db02d7, 0xe8930307, 0x8a360018, +// 0x000a4783, 0x001a0693, 0x02b7d5db, 0xfef763e3, 0x0207d4db, 0x0237d5db, 0xfd078713, +// 0x46258810, 0x06e66563, 0x46a54981, 0xa01d45a9, 0x0028e893, 0xe893b7f9, 0xb7e10048, +// 0x0088e893, 0xe893b7c9, 0xbf750108, 0x02b989b3, 0x89938a32, 0x99bafd09, 0x000a4703, +// 0x001a0613, 0xfd070793, 0xf3e38c14, 0x4783fef6, 0xeadb000a, 0x46830ce7, 0x4625001a, +// 0xfd068713, 0x07938810, 0xe893001a, 0x60634008, 0x4d810ae6, 0x45294625, 0x4981a03d, +// 0xbca7ebdb, 0x00092983, 0x00490793, 0x0009d663, 0x0028e893, 0x413009b3, 0x8a36893e, +// 0x8db3bf6d, 0x87ae02ad, 0xfd0d8d93, 0xc6839db6, 0x85930007, 0x87130017, 0x8810fd06, +// 0xfee673e3, 0x8a138004, 0x06930017, 0x5edb06c0, 0xe56346c7, 0x53db06e6, 0x5bdb4887, +// 0x8a3e48a7, 0x000a4503, 0x07800793, 0xe8e30a05, 0x0793eea7, 0xe2630570, 0x079308a7, +// 0x5d5b0450, 0xe7634855, 0x6cdb08a7, 0x8993ac55, 0x56fd0014, 0x102c8626, 0x02500513, +// 0x3d3184ce, 0x4d81b559, 0xbaa6e4db, 0x00092d83, 0x00490713, 0x000dd363, 0x07934d81, +// 0x893a002a, 0x87d2bf41, 0xb7694d81, 0x414754db, 0xf9a76fdb, 0x1008e893, 0xc703bf61, +// 0x6bdb0017, 0xe893fec7, 0x8a133008, 0xb7590027, 0x0017c703, 0x408755db, 0x0808e893, +// 0xe893bfa5, 0xb7e50c08, 0x2008e893, 0x0793b7b5, 0x8c14fa85, 0x02000713, 0xe4f76de3, +// 0x0cfb87db, 0x8782439c, 0x5465515b, 0xe475655b, 0x0df57793, 0x4077e65b, 0x0168e8b3, +// 0x0fd57513, 0x4055635b, 0x07138414, 0x9b610079, 0x09134314, 0x43580087, 0x87ee884e, +// 0x102c8626, 0xf0ef8800, 0xa21de38f, 0x6b8558db, 0x6b85555b, 0x6af556db, 0x6a2556db, +// 0xfef8f893, 0x56db47a9, 0x54db4095, 0xf8934045, 0xf45bff38, 0xf89300a8, 0xf713ffe8, +// 0x54db2008, 0x66db4095, 0xc7314845, 0x7913091d, 0x2503ff89, 0x27030049, 0x56130009, +// 0x8f3141f5, 0x40c706b3, 0x00a645b3, 0x00d73733, 0x40c58633, 0xc446883e, 0x00890c93, +// 0x57934881, 0x073301f5, 0xc24e40e6, 0x8626c06e, 0x8800102c, 0xc72ff0ef, 0x896684aa, +// 0x2703bb99, 0x0c930009, 0xf15b0049, 0x56930288, 0xc63341f7, 0xc04600e6, 0x88ce886e, +// 0x8020837d, 0x102c8626, 0xf0ef8800, 0xbfc9d18f, 0x0068f45b, 0xbff18810, 0xbc78fd5b, +// 0x3c07375b, 0xc305bfc9, 0x7913091d, 0x8c00ff89, 0x00492703, 0xc446883e, 0x00890c93, +// 0x47814881, 0xc06ec24e, 0x8c00bf59, 0x00490c93, 0x0088f75b, 0x886ec046, 0x470188ce, +// 0xf55bbf45, 0xf6930068, 0xb7fd0ff6, 0xbe78f65b, 0x3c06a6db, 0x8414b7d5, 0x00790713, +// 0x43149b61, 0x00870913, 0x884e4358, 0x862687ee, 0x8800102c, 0x8cdff0ef, 0xb94584aa, +// 0x0028f593, 0x4c85c82e, 0x4218f85b, 0xa0294c81, 0x102c56fd, 0x31358010, 0x01948633, +// 0xe9e30c85, 0x4781ff3c, 0x00098463, 0xfff98793, 0x4c8994be, 0x00098463, 0x00198c93, +// 0x00094503, 0x56fd8626, 0x8d13102c, 0x3ef50014, 0x0d9344c2, 0xc4850049, 0x866a84e6, +// 0x56fda809, 0x8010102c, 0x00160913, 0x048536cd, 0xe8e3864a, 0x4701ff34, 0x0199e463, +// 0x41998733, 0x896e9d3a, 0xb91584ea, 0x00490593, 0x8c00ca2e, 0x9363876e, 0x577d000d, +// 0xe2918936, 0x974a8962, 0xc60387ca, 0xc2190007, 0x02f71463, 0x40d78cb3, 0x4008fd13, +// 0x00a8f55b, 0x019df363, 0xf5938cee, 0xc82e0028, 0x4418f15b, 0x88b38626, 0xa831409c, +// 0xbfc10785, 0x00160713, 0x102c56fd, 0xce468010, 0x36b5cc3a, 0x48f24762, 0x0733863a, +// 0x63e30116, 0x4701ff37, 0x0199e463, 0x41998733, 0x001c8793, 0x0cb394ba, 0x872600f7, +// 0x409706b3, 0xc50396ca, 0xc5190006, 0x000d0d63, 0xfffd8693, 0x000d9863, 0xc0b944c2, +// 0x84b3863a, 0xa02d40ec, 0x08938db6, 0x863a0017, 0x102c56fd, 0x3e11cc46, 0x874648e2, +// 0x56fdb7e1, 0x8010102c, 0x00160913, 0x3601c83a, 0x864a4742, 0x00c486b3, 0xff36e5e3, +// 0xe4634681, 0x86b30199, 0x97364199, 0x84ba4952, 0x8c00b6b9, 0x0218e893, 0xc0468626, +// 0x00490993, 0x886e48a1, 0x470147c1, 0x8800102c, 0xb1aff0ef, 0x84aa894e, 0x8414b62d, +// 0xb3b547c1, 0xb3a547a1, 0xb3954789, 0x4bc002ef, 0xa05207b7, 0x0187a983, 0x09374481, +// 0x4a05a052, 0xa0203ab7, 0x0209f85b, 0x01492683, 0x009a17b3, 0xfff7c713, 0x2a238f75, +// 0x270300e9, 0xd6130189, 0x8fd94024, 0x0034f593, 0x99ca8513, 0x00f92c23, 0xa8bff0ef, +// 0xd9930485, 0xe55b0019, 0xa979bd04, 0x482002ef, 0xa08004b7, 0x84205ccc, 0x9cc50513, +// 0xa6bff0ef, 0xe7935cdc, 0xdcdc03f7, 0x02efa169, 0xa7ab4640, 0x8420803f, 0x051353ec, +// 0xf0ef9f45, 0xa72ba4df, 0x537c803f, 0x0017e793, 0xa1a5d37c, 0x442002ef, 0xa01104b7, +// 0x9073409c, 0x67893407, 0xa0112737, 0x28078793, 0x0793c35c, 0xc71c3f60, 0x474140dc, +// 0x4727e793, 0x07b7c0dc, 0xcbd8a042, 0x08000713, 0x4739d7d8, 0xa223d398, 0x474d0207, +// 0x471dd7d8, 0x17b7d798, 0x43d8a011, 0xfdf77713, 0x43d8c3d8, 0xe7f77713, 0x10076713, +// 0x4798c3d8, 0xfdf77713, 0x4798c798, 0xe7f77713, 0x10076713, 0x43d8c798, 0xc3d88014, +// 0x80144798, 0x07b7c798, 0xcdaba071, 0x43988aff, 0x7807275b, 0x4398c398, 0x14074063, +// 0x06b74398, 0x8f558000, 0x4398c398, 0x12075863, 0x9b3d4398, 0x4398c398, 0x5247725b, +// 0x67134398, 0xc3980107, 0xfb5b439c, 0x84201047, 0xa1c50513, 0x977ff0ef, 0x0ac48713, +// 0x8420431c, 0x1007e793, 0xa583c31c, 0x05130ac4, 0xf0efa485, 0x842095df, 0xaa050513, +// 0x953ff0ef, 0x05138420, 0xf0efab85, 0x960b949f, 0x56838a5f, 0x47850126, 0x0cd7ee63, +// 0x07138030, 0x431c0f07, 0x869376c1, 0x8ff53ff6, 0x869366ad, 0x84204006, 0x05138fd5, +// 0xc31cad45, 0x917ff0ef, 0x05138420, 0xf0efaf45, 0x679990df, 0xa0120737, 0xaa578793, +// 0xcf1c8420, 0xb6050513, 0x7e600793, 0xa01104b7, 0xf0efcb1c, 0x40dc8edf, 0xf7938420, +// 0xc0dcbff7, 0x051340dc, 0xe793b785, 0xc0dc4007, 0x8d3ff0ef, 0x05138420, 0xf0efb905, +// 0x84938c9f, 0x409c0f04, 0xe0020737, 0x8ff9177d, 0x00080737, 0xc09c8fd9, 0xa0133737, +// 0x8aefcfab, 0x007a17b7, 0x20078793, 0xa01336b7, 0x2c46a703, 0x0a07705b, 0xfbfd17fd, +// 0x07138030, 0x431c0f07, 0x869376c1, 0x8ff53ff6, 0x66858420, 0x05138fd5, 0xc31cbc85, +// 0xf0ef4489, 0xa059871f, 0x05138420, 0xf0efa6c5, 0xb721865f, 0xa0800737, 0x05b74b5c, +// 0x15fdff00, 0xcb5c8fed, 0x82855b1c, 0x0077e793, 0x4b0cdb1c, 0xf593421c, 0x079ef605, +// 0x424c8fcd, 0x059216fd, 0x460c8fcd, 0x058e8420, 0x464c8fcd, 0x01064603, 0x8fcd058a, +// 0xcb1c8fd1, 0x0513433c, 0xf793b145, 0x8eddf007, 0xf0efc334, 0x842080df, 0xb2c50513, +// 0x803ff0ef, 0x05138420, 0xb5f5b485, 0xf33d8b79, 0x05138420, 0x4481bac5, 0xfeaff0ef, +// 0xe20007b7, 0x85a38004, 0x67f30007, 0x84203004, 0xbe850513, 0xfd2ff0ef, 0xe0ef454d, +// 0x4561c4bf, 0xc45fe0ef, 0xe0ef4569, 0x456dc3ff, 0xc39fe0ef, 0x02100513, 0xc31fe0ef, +// 0xaae18526, 0x0073c501, 0xbff51050, 0x80824505, 0xce061101, 0xca4acc26, 0x26f3c84e, +// 0x67053420, 0xf7b3177d, 0xc66300e6, 0x44810406, 0x02e78863, 0xa0203937, 0xc7c90913, +// 0xa02009b7, 0x012487b3, 0x0007c783, 0x00f10593, 0x59498513, 0x07a30485, 0xf0ef00f1, +// 0xe35bf0ef, 0xa001bf94, 0x05138420, 0xf0efc605, 0x40f2f4cf, 0x495244e2, 0x610549c2, +// 0x07138082, 0x68e30310, 0x0737fef7, 0x0713a020, 0x07db2007, 0x439c0cf7, 0xbff19782, +// 0x0000a001, 0x82aac63d, 0xf31383b2, 0x9316fe03, 0x02655863, 0x41d44190, 0x45dc4598, +// 0xc154c110, 0xc55cc518, 0x49d44990, 0x4ddc4d98, 0xc954c910, 0xcd5ccd18, 0x02058593, +// 0x02050513, 0xfc654ce3, 0xffc3f313, 0x00530333, 0x00655863, 0x05914190, 0x0511c110, +// 0xfe654ce3, 0x00728333, 0x00655a63, 0x0005c603, 0x00230585, 0x050500c5, 0xfe654ae3, +// 0x80828516, 0x03b3832a, 0x769300c5, 0xce810035, 0xffc68693, 0x40d507b3, 0x06f3e463, +// 0x00b50023, 0x9de30505, 0x0d63fea7, 0x05e20475, 0x0085d793, 0xd79395be, 0x95be0105, +// 0x40a38633, 0x02000713, 0xfe067693, 0x00a687b3, 0x7693e285, 0xca8dffc6, 0x40d70633, +// 0x00a687b3, 0x82058736, 0x00000697, 0x00c686b3, 0x00c68067, 0xcd0ccd4c, 0xc90cc94c, +// 0xc50cc54c, 0xc10cc14c, 0x17e3953a, 0xbf6dfef5, 0x1de3879e, 0x851af875, 0x71398082, +// 0xc66e4301, 0x7139a019, 0xc86a5341, 0xcc62ca66, 0xa019ce5e, 0x53017139, 0xd256d05a, +// 0xd64ed452, 0xda26d84a, 0xde06dc22, 0x40610133, 0x11418282, 0xc226c04a, 0xc606c422, +// 0x4db28282, 0x4d020141, 0x4c224c92, 0x01414bb2, 0x4a924b02, 0x49b24a22, 0x49020141, +// 0x44224492, 0x014140b2, 0x00008082, 0xa0494701, 0x01065a93, 0x01051893, 0x0108d793, +// 0xd7338141, 0xf5b30355, 0x18930355, 0xd6930106, 0x05c20108, 0x05338dc9, 0xbfb302d7, +// 0x8e6300a5, 0x177d000f, 0xbfb395b2, 0x986300c5, 0xbfb3000f, 0x846300a5, 0x177d000f, +// 0x8d8995b2, 0x0355f533, 0x0355d5b3, 0x8d5d0542, 0x02b686b3, 0x00d53fb3, 0x000f8e63, +// 0x15fd9532, 0x00c53fb3, 0x000f9863, 0x00d53fb3, 0x000f8463, 0x15fd9532, 0x07428d15, +// 0x80828dd9, 0xc0267179, 0xc44ec24a, 0xc856c652, 0xcc06ca22, 0x892e84aa, 0x8a3689b2, +// 0xeac5843a, 0x01393fb3, 0x020f8e63, 0x00ef854e, 0xce2a4ab0, 0x99b3cd19, 0x089300a9, +// 0x87b30200, 0xd7b340a8, 0x193300f4, 0x693300a9, 0x94b300f9, 0x852600a4, 0x864e85ca, +// 0xd02e3f05, 0x478184aa, 0xa0b9d23e, 0x854ece21, 0x471000ef, 0xe519ce2a, 0x41390933, +// 0xd23e4785, 0x02c0006f, 0x02000893, 0x40a88fb3, 0x00a999b3, 0xd733864e, 0x17b301f4, +// 0x94b300a9, 0xe53300a4, 0x55b300e7, 0x35ed01f9, 0x892ad22e, 0x85ca8526, 0x3df9864e, +// 0x84aad02e, 0x46f2c479, 0xd4b34901, 0xa87d00d4, 0x0339d933, 0x0339f4b3, 0x45014581, +// 0xc004cc55, 0x01242223, 0x3fb3a855, 0x97e30149, 0x8552fe0f, 0x3fd000ef, 0xc955ce2a, +// 0x02000893, 0x40a88733, 0x00e9d7b3, 0x00aa1633, 0x8a328e5d, 0x00a999b3, 0x00e4d6b3, +// 0x00a494b3, 0x00a91533, 0x00e955b3, 0x3dad8d55, 0x892ad02e, 0x03358533, 0x0335b5b3, +// 0x00b93fb3, 0x000f9863, 0x03259263, 0x00a4bfb3, 0x000f8e63, 0x85b35682, 0x16fd4145, +// 0x06b3d036, 0x3fb34135, 0x85b300d5, 0x853641f5, 0xd2364681, 0x8533c80d, 0x05b340a4, +// 0xbfb340b9, 0x85b300a4, 0x46f241f5, 0x02000893, 0x40d88733, 0x00e59933, 0x00d554b3, +// 0x0124e4b3, 0x00d5d933, 0x2223c004, 0x55020124, 0x02412583, 0x49124482, 0x4a3249a2, +// 0x44524ac2, 0x614540e2, 0x46818082, 0x012a3fb3, 0x000f9663, 0x0134bfb3, 0x000f9e63, +// 0xd03e4785, 0x41348733, 0x41490933, 0x00e4bfb3, 0x41f90933, 0xa01184ba, 0xd236d036, +// 0xbf65f855, 0xc0061141, 0x3d2d0058, 0x45a24512, 0x01414082, 0x00008082, 0x80000737, +// 0x97138eb9, 0x11010015, 0xc24ac026, 0xc652c44e, 0xca06c856, 0x00169493, 0x800000b7, +// 0x00973fb3, 0x000f9863, 0x02971063, 0x00c53fb3, 0x000f8c63, 0x8a2e89aa, 0x85b68532, +// 0x86d2864e, 0x00159713, 0x00169493, 0xf6b38ead, 0x59130016, 0xda930157, 0x1a130154, +// 0x999300a7, 0x079300a4, 0x80637ff0, 0x6fb31d27, 0x886300a7, 0xefb31a0f, 0x8e6300c4, +// 0x04b3120f, 0xbf934159, 0x88630404, 0x5793120f, 0x6a330155, 0x052e00fa, 0x01565793, +// 0x00f9e9b3, 0x3f93062e, 0x9d630029, 0x6a33040f, 0x8463001a, 0xe9b3000a, 0x87930019, +// 0x9363fff4, 0x84be000a, 0x0893c0a1, 0x87b30200, 0x5c634098, 0x173300f0, 0x97b300f6, +// 0xd9b300f9, 0x56330099, 0x8e5d0096, 0x04b3a829, 0x879340f0, 0x97330207, 0x8f5100f9, +// 0x8726e091, 0x0099d633, 0xc3194981, 0x00266613, 0x1663c6e9, 0x14630159, 0x0f63013a, +// 0x3fb310c5, 0x9863013a, 0x1d63000f, 0x3fb3013a, 0x896300c5, 0x197d000f, 0x01f99713, +// 0x0019d993, 0x8e598205, 0x8d11872a, 0x00a73fb3, 0x41fa0a33, 0x413a0a33, 0x00293f93, +// 0x0a0f9263, 0x020a1563, 0x02093f93, 0x020f9163, 0x45018a2a, 0x1c631901, 0xa8310009, +// 0x0c63197d, 0x57130009, 0x0a0601f5, 0x6a330506, 0x3fb300ea, 0x95e3001a, 0x0513fe0f, +// 0x3f934005, 0x9a7e4005, 0x01fa3fb3, 0x5793997e, 0x8b8500b5, 0x8d1d84aa, 0x00a4bfb3, +// 0x41fa0a33, 0x17930a06, 0x5a13014a, 0x812d00ca, 0x17938d5d, 0x6a330149, 0xf5b300fa, +// 0xe5b30015, 0x44820145, 0x49a24912, 0x4ac24a32, 0x610540d2, 0x95328082, 0x00c53fb3, +// 0x3fb39a7e, 0x9a4e01fa, 0x000f9f63, 0x013a3fb3, 0x000f9b63, 0xf8091be3, 0x1713812d, +// 0x5a13015a, 0x8d5900ba, 0x0893bf7d, 0x87b37fe0, 0xc3854128, 0x00157f93, 0x00256793, +// 0x000f8363, 0x1713853e, 0x5a1301fa, 0x8105001a, 0x09058d59, 0x4501bfb9, 0x7ff00a37, +// 0xdad1b779, 0x45814501, 0x6a33b779, 0x156300aa, 0x92e3001a, 0xd2c1f957, 0x05b74501, +// 0xbfa5fff8, 0xc0261101, 0xc44ec24a, 0xc856c652, 0xcc0eca22, 0x1141ce06, 0x00159713, +// 0x99138355, 0x549300b5, 0x69330155, 0x14930099, 0x043700b5, 0x97938000, 0x83d50016, +// 0x00b69a13, 0x01565993, 0x013a6a33, 0x00b61993, 0xfab38ead, 0x06930086, 0xcb6d7ff0, +// 0x14e68e63, 0x00896933, 0x18078d63, 0x16f68463, 0x008a6a33, 0x8513c656, 0x972ac027, +// 0x034936b3, 0x03490633, 0x0344b5b3, 0x03448533, 0x00b60a33, 0x00ba3fb3, 0x01f68ab3, +// 0x033936b3, 0x03390633, 0x00a60933, 0x00a93fb3, 0x3fb39a7e, 0x9afe01fa, 0x3fb39a36, +// 0x9afe00da, 0x0334b5b3, 0x03348533, 0x3fb3992e, 0x9a7e00b9, 0x01fa3fb3, 0x01fa85b3, +// 0x00a96933, 0x001a6513, 0x00091363, 0xaf938552, 0x99630005, 0x8faa000f, 0x3fb3952a, +// 0x95ae01f5, 0x177d95fe, 0x5c634ab2, 0x089314e0, 0x87b37ff0, 0x5d6340e8, 0x05130cf0, +// 0x3f934005, 0x86634005, 0x95fe000f, 0x01f5bfb3, 0x5613977e, 0x8a0500b5, 0x812d8d11, +// 0x01559613, 0x05868d51, 0x179381b1, 0x8ddd0147, 0x0155e5b3, 0x44820141, 0x49a24912, +// 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, 0x00996fb3, 0x040f8563, 0x01f4df93, +// 0x997e994a, 0x156394a6, 0x89260009, 0x17014481, 0x85ca4501, 0x95aea019, 0xbfb30505, +// 0x9ce30085, 0x05e3fe0f, 0x8f09ee05, 0x02000893, 0x40a88633, 0x00c4d633, 0x00a494b3, +// 0x00a91933, 0x00c96933, 0x8363b5f1, 0x85d604f6, 0x44820141, 0x49a24912, 0x4ac24a32, +// 0x41e24452, 0x610540f2, 0x00008067, 0x00996933, 0x02891263, 0x1613e791, 0x6633001a, +// 0xca190136, 0x00f69663, 0x013a6a33, 0x008a1663, 0x05b74501, 0xbf897ff0, 0x05b74501, +// 0x0141fff8, 0x49124482, 0x4a3249a2, 0x44524ac2, 0x40f241e2, 0x80676105, 0x65330000, +// 0xdd51013a, 0x01f9df93, 0x9a7e9a52, 0x156399ce, 0x8a4e000a, 0x17814981, 0x85d24501, +// 0x95aea019, 0xbfb30505, 0x9ce30085, 0x03e3fe0f, 0x8f89e405, 0x02000893, 0x40a88633, +// 0x00c9d633, 0x00a999b3, 0x00aa1a33, 0x00ca6a33, 0x4481b525, 0x86b34885, 0xbf9340e8, +// 0x9b630206, 0x84aa000f, 0x4581852e, 0xc5091681, 0x0206bf93, 0x020f8d63, 0x0893c29d, +// 0x86330200, 0x993340d8, 0x17b300c5, 0x553300c5, 0xd5b300d5, 0x653300d5, 0x8cdd0125, +// 0x6513c099, 0x05130015, 0x3f934005, 0x95fe4005, 0x01f5d713, 0x4501bd9d, 0x0000bded, +// 0xc0261101, 0xc44ec24a, 0xc856c652, 0xcc0eca22, 0x1141ce06, 0x00159713, 0x99138355, +// 0x549300b5, 0x69330155, 0x14930099, 0x043700b5, 0x97938000, 0x83d50016, 0x00b69a13, +// 0x01565993, 0x013a6a33, 0x00b61993, 0xfab38ead, 0x06930086, 0x08637ff0, 0x84632207, +// 0x69332ce6, 0x8d630089, 0x85632e07, 0x6a332ef6, 0x8f1d008a, 0x3ff70713, 0x15938085, +// 0x8ccd01f9, 0x00195913, 0x010a5613, 0x02c956b3, 0x02c97933, 0x010a1893, 0x0108d593, +// 0x02d587b3, 0xd5130942, 0x69330104, 0x854a00a9, 0x40f90933, 0x01253fb3, 0x000f8863, +// 0x995216fd, 0x01493fb3, 0xfe0f8ce3, 0x02c95833, 0x02c97933, 0x87b38642, 0x094202c5, +// 0x01049893, 0x0108d513, 0x00a96933, 0x0933854a, 0x3fb340f9, 0x88630125, 0x167d000f, +// 0x3fb39952, 0x8ce30149, 0x06c2fe0f, 0xb5b396b2, 0x85330336, 0x04b30336, 0x854a40a0, +// 0x40b90933, 0x01253fb3, 0x854ac499, 0x9663197d, 0x3fb3000f, 0x81630125, 0x16fd020f, +// 0xb53394ce, 0x99520134, 0x01493fb3, 0x0905c511, 0x000f9663, 0x00193f93, 0xfe0f83e3, +// 0x01491763, 0x892685ce, 0x45014601, 0x5593a041, 0x5633010a, 0x793302b9, 0x189302b9, +// 0xd513010a, 0x0fb30108, 0x094202c5, 0x0104d793, 0x00f96933, 0x093387ca, 0xbfb341f9, +// 0x88630127, 0x167d000f, 0x3fb39952, 0x8ce30149, 0x5833fe0f, 0x793302b9, 0x85c202b9, +// 0x02b507b3, 0x98930942, 0xd5130104, 0x69330108, 0x854a00a9, 0x40f90933, 0x01253fb3, +// 0x000f8863, 0x995215fd, 0x01493fb3, 0xfe0f8ce3, 0x962e0642, 0x033635b3, 0x03360533, +// 0x40a004b3, 0x0933854a, 0x3fb340b9, 0xc4990125, 0x197d854a, 0x000f9663, 0x01253fb3, +// 0x020f8163, 0x94ce167d, 0x0134b533, 0x3fb39952, 0xc5110149, 0x96630905, 0x3f93000f, +// 0x83e30019, 0xaf93fe0f, 0x99630006, 0x8fb2000f, 0x3fb39632, 0x96b601f6, 0x177d96fe, +// 0x00996933, 0x00166513, 0x00091363, 0x85b68532, 0x16e05f63, 0x7ff00893, 0x40e887b3, +// 0x0ef05b63, 0x40050513, 0x40053f93, 0x000f8663, 0xbfb395fe, 0x977e01f5, 0x00b55613, +// 0x8d118a05, 0x9613812d, 0x8d510155, 0x81b10586, 0x01471793, 0xe5b38ddd, 0x01410155, +// 0x49124482, 0x4a3249a2, 0x44524ac2, 0x40f241e2, 0x80676105, 0x6fb30000, 0x85630099, +// 0xdf93040f, 0x994a01f4, 0x94a6997e, 0x00091563, 0x44818926, 0x45011701, 0xa01985ca, +// 0x050595ae, 0x0085bfb3, 0xfe0f9ce3, 0xda0507e3, 0x08938f09, 0x86330200, 0xd63340a8, +// 0x94b300c4, 0x193300a4, 0x693300a9, 0xbb4100c9, 0x02f68463, 0x6fb3e789, 0x8363013a, +// 0x85d6020f, 0x44820141, 0x49a24912, 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, +// 0x013a6a33, 0xfe8a01e3, 0x05b74501, 0x0141fff8, 0x49124482, 0x4a3249a2, 0x44524ac2, +// 0x40f241e2, 0x80676105, 0x69330000, 0x1fe30099, 0x8de3fc89, 0x4501fcf6, 0x7ff005b7, +// 0x0155e5b3, 0x44820141, 0x49a24912, 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, +// 0x013a6a33, 0xfa8a18e3, 0xb7614501, 0x013a6fb3, 0xfc0f87e3, 0x01f9df93, 0x9a7e9a52, +// 0x156399ce, 0x8a4e000a, 0x17814981, 0x85d24501, 0x95aea019, 0xbfb30505, 0x9ce30085, +// 0x02e3fe0f, 0x8f89ce05, 0x02000893, 0x40a88633, 0x00c9d633, 0x00a999b3, 0x00aa1a33, +// 0x00ca6a33, 0x4481b1d9, 0x86b34885, 0xbf9340e8, 0x9b630206, 0x84aa000f, 0x4581852e, +// 0xc5091681, 0x0206bf93, 0x020f8d63, 0x0893c29d, 0x86330200, 0x993340d8, 0x17b300c5, +// 0x553300c5, 0xd5b300d5, 0x653300d5, 0x8cdd0125, 0x6513c099, 0x05130015, 0x3f934005, +// 0x95fe4005, 0x01f5d713, 0x4501bd81, 0x9693bdf9, 0x571300b5, 0x8ed90155, 0x80000737, +// 0x97138ed9, 0x83550015, 0x41e00893, 0x40e88633, 0x02c05363, 0x02000713, 0x00e63fb3, +// 0x000f9363, 0xd6b34681, 0xaf9300c6, 0x84630005, 0x06b3000f, 0x853640d0, 0xc1198082, +// 0x0015e593, 0x7ff00737, 0x00b73fb3, 0x000f8563, 0x80000537, 0x05378082, 0x157d8000, +// 0x00008082, 0x00b59693, 0x01555713, 0x07378ed9, 0x8ed98000, 0x00159713, 0x08938355, +// 0x863341e0, 0x2f9340e8, 0x93630006, 0x0713020f, 0x3fb30200, 0x936300e6, 0x4681000f, +// 0x00c6d6b3, 0x0005af93, 0x000f8463, 0x40d006b3, 0x80828536, 0xe593c119, 0x07370015, +// 0x3fb37ff0, 0x856300b7, 0x0537000f, 0x80828000, 0x8082557d, 0xc0261141, 0x4581c206, +// 0x86ae87ae, 0xc239862a, 0x00062f93, 0x000f8a63, 0x800007b7, 0x40c00633, 0x05b3c581, +// 0x167d40b0, 0x41e00693, 0xc02a1141, 0xc432c22e, 0x1141c636, 0x8532c03e, 0x872a2215, +// 0x01414782, 0x45924502, 0x46b24622, 0x8e990141, 0x00e61633, 0x00b5d713, 0x01561493, +// 0x14938f45, 0x80b10016, 0x94938fc5, 0x8fc50146, 0x85be853a, 0x40924482, 0x80820141, +// 0xc0261141, 0x4581c206, 0x862a86ae, 0x0693c60d, 0x110141e0, 0xc22ec02a, 0xc636c432, +// 0x8532c83a, 0x87aa20e1, 0x45924502, 0x46b24622, 0x61054742, 0x16338e9d, 0xd71300f6, +// 0x149300b5, 0x8f450156, 0x00161793, 0x949383b1, 0x8fc50146, 0x85be853a, 0x40924482, +// 0x80820141, 0xa011577d, 0x47814705, 0xffe00e37, 0x00159293, 0x00a7bfb3, 0x01f28eb3, +// 0x01de3fb3, 0x060f9863, 0x00169393, 0x00c7bfb3, 0x01f38eb3, 0x01de3fb3, 0x040f9e63, +// 0x00d5c733, 0x04074063, 0x0005af93, 0x000f9f63, 0x40c50733, 0x00e53fb3, 0x40d58533, +// 0x41f50533, 0x00e7bfb3, 0x857ee111, 0x07338082, 0x3fb340a6, 0x853300e6, 0x053340b6, +// 0xbfb341f5, 0xe11100e7, 0x8082857e, 0x0072e7b3, 0x00c56733, 0xc7818fd9, 0xc1914505, +// 0x8082852e, 0x8082853a, 0x736367c1, 0x079302f5, 0x07130ff0, 0xe9630200, 0x37b704a7, +// 0x8793a020, 0x97aace87, 0x0007c503, 0x40a70533, 0x00008067, 0x010007b7, 0x00f57e63, +// 0xa02037b7, 0x87938141, 0x97aace87, 0x0007c503, 0x05334741, 0x808240a7, 0xa02037b7, +// 0x87938161, 0x97aace87, 0x0007c503, 0x05334721, 0x808240a7, 0xa02037b7, 0x87938121, +// 0x97aace87, 0x0007c503, 0x05334761, 0x808240a7, 0x00e688b3, 0x02000513, 0xa0200537, +// 0xa02036b7, 0xfd6a8513, 0x0ff77713, 0x00092683, 0xa02037b7, 0x0007c703, 0x00176713, +// 0x00688023, 0x0208e893, 0x020c8493, 0x020c8593, 0x0ff57513, 0x0ff7f793, 0x40d606b3, +// 0xa0110737, 0xa0203537, 0xa02007b7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0xffffffff, 0x7fefffff, 0xffffffff, 0xffefffff, 0x509f79fb, 0x3fd34413, +// 0x8b60c8b3, 0x3fc68a28, 0x00000000, 0x3ff80000, 0x636f4361, 0x3fd287a7, 0x0979a371, +// 0x400a934f, 0x00000000, 0x3fe00000, 0xbbb55516, 0x40026bb1, 0xfefa39ef, 0x3fe62e42, +// 0x00000000, 0x402c0000, 0x00000000, 0x40240000, 0x00000000, 0x40180000, 0x00000000, +// 0x40000000, 0x00000000, 0x3ff00000, 0xeb1c432d, 0x3f1a36e2, 0x00000000, 0x412e8480, +// 0x00696e66, 0x2b696e66, 0x00000000, 0x006e616e, 0x2d696e66, 0x00000000, 0x00000000, +// 0x41cdcd65, 0x00000000, 0xc1cdcd65, 0x6c756e28, 0x0000296c, 0xa020126c, 0xa020107e, +// 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, +// 0xa020107e, 0xa020126c, 0xa0201394, 0xa020126c, 0xa0201238, 0xa0201374, 0xa0201238, +// 0xa020107e, 0xa020126c, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, +// 0xa020126c, 0xa02014f6, 0xa020107e, 0xa020107e, 0xa0201410, 0xa020107e, 0xa020126c, +// 0xa020107e, 0xa020107e, 0xa020126c, 0x666e695b, 0x67205d6f, 0x203a7470, 0x20717269, +// 0x65636572, 0x64657669, 0x206e6f20, 0x656d6974, 0x75252072, 0x6863202c, 0x0d752520, +// 0x0000000a, 0x666e695b, 0x73205d6f, 0x203a6970, 0x20717269, 0x65636572, 0x64657669, +// 0x6f63202c, 0x203a6564, 0x78257830, 0x00000a0d, 0x666e695b, 0x67205d6f, 0x3a6f6970, +// 0x71726920, 0x63657220, 0x65766965, 0x76202c64, 0x203a6c61, 0x58257830, 0x00000a0d, +// 0x666e695b, 0x6f205d6f, 0x203a6566, 0x47504665, 0x6e612041, 0x43502064, 0x65522042, +// 0x20746573, 0x65737341, 0x64657472, 0x00000a0d, 0x666e695b, 0x73205d6f, 0x203a7563, +// 0x6c6f7349, 0x6f697461, 0x664f5f6e, 0x203d2066, 0x78257830, 0x00000a0d, 0x7272655b, +// 0x205d726f, 0x3a65666f, 0x72724520, 0x4120726f, 0x72657373, 0x676e6974, 0x50466520, +// 0x202c4147, 0x20424350, 0x65736552, 0x0a0d7374, 0x00000000, 0x666e695b, 0x78205d6f, +// 0x203a4243, 0x74696e49, 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x71205d6f, 0x3a697073, +// 0x696e4920, 0x74732074, 0x0d747261, 0x0000000a, 0x7665735b, 0x5d657265, 0x70737120, +// 0x49203a69, 0x2074696e, 0x6c696166, 0x0a0d6465, 0x00000000, 0x7665735b, 0x5d657265, +// 0x616c6620, 0x203a6873, 0x74696e49, 0x69616620, 0x0d64656c, 0x0000000a, 0x666e695b, +// 0x71205d6f, 0x3a697073, 0x696e4920, 0x4b4f2074, 0x00000a0d, 0x666e695b, 0x66205d6f, +// 0x6873616c, 0x6e49203a, 0x73207469, 0x74726174, 0x00000a0d, 0x666e695b, 0x66205d6f, +// 0x6873616c, 0x6e49203a, 0x4f207469, 0x000a0d4b, 0x666e695b, 0x77205d6f, 0x203a7464, +// 0x74696e49, 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x64205d6f, 0x203a616d, 0x74696e49, +// 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x63205d6f, 0x74707972, 0x49203a6f, 0x2074696e, +// 0x72617473, 0x000a0d74, 0x666e695b, 0x63205d6f, 0x74707972, 0x49203a6f, 0x2074696e, +// 0x0a0d4b4f, 0x00000000, 0x7665735b, 0x5d657265, 0x79726320, 0x3a6f7470, 0x696e4920, +// 0x61662074, 0x64656c69, 0x00000a0d, 0x666e695b, 0x69205d6f, 0x7265746e, 0x74707572, +// 0x49203a73, 0x2074696e, 0x0a0d4b4f, 0x00000000, 0x666e695b, 0x66205d6f, 0x3a6c6273, +// 0x696e4920, 0x74732074, 0x0d747261, 0x0000000a, 0x666e695b, 0x66205d6f, 0x3a6c6273, +// 0x696e4920, 0x75532074, 0x73656363, 0x000a0d73, 0x7665735b, 0x5d657265, 0x62736620, +// 0x49203a6c, 0x2074696e, 0x6c696146, 0x0a0d6465, 0x00000000, 0x666e695b, 0x77205d6f, +// 0x203a7464, 0x20717269, 0x65636572, 0x64657669, 0x00000a0d, 0x78450a0d, 0x74706563, +// 0x2e6e6f69, 0x636f4c20, 0x676e696b, 0x0d2e2e2e, 0x0000000a, 0x00000000, 0x3ff00000, +// 0x00000000, 0x40240000, 0x00000000, 0x40590000, 0x00000000, 0x408f4000, 0x00000000, +// 0x40c38800, 0x00000000, 0x40f86a00, 0x00000000, 0x412e8480, 0x00000000, 0x416312d0, +// 0x00000000, 0x4197d784, 0x00000000, 0x41cdcd65, 0x02020100, 0x03030303, 0x04040404, +// 0x04040404, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x06060606, 0x06060606, +// 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x07070707, +// 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, +// 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, +// 0x07070707, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, +// 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, +// 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, +// 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, +// 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0xa0510000, 0xa0130000, +// 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xa0600000, 0x000000ff, +// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +// 0x00000000, 0x00000000, 0x00000000, 0x37c2cac9, 0x8c32e765, 0xa15e1200, 0x25c486b2, +// 0x8734d7b4, 0xfa26c29d, 0x2ff972ae, 0x0adebf22, 0xff6f29e6, 0x3c50778d, 0xfa02d8da, +// 0x78600d02, 0xbca88565, 0x163ca9be, 0x73f0da10, 0x3ed20b1c, 0xcce46d11, 0x2a49278f, +// 0x12248db6, 0xe50b6755, 0xa431193c, 0x6c308699, 0xe0c41dbf, 0x50c791fe, 0xd3f876b9, +// 0x7cf1df93, 0x16941322, 0xaa1ead8f, 0xe3753f54, 0xc9bb7bcc, 0x79200bff, 0x7d76c2d4, +// 0xa7acc7f7, 0xff567a99, 0xbfa4f5dc, 0x064238c8, 0xe9699208, 0xa6b5daf3, 0xa3a2ad30, +// 0x32bafe37, 0x54e1dacb, 0xda540799, 0x95547760, 0x302cd650, 0x9d428238, 0x62bbdadd, +// 0xe531a353, 0x282e8f7d, 0x973e7ba1, 0x0dd65973, 0x4ab77a02, 0x53ca63ae, 0x176010c2, +// 0x58bc890d, 0x025f55f8, 0x0e1e579b, 0xe19cdb04, 0x4bb6caf5, 0xad438b2c, 0xeda4466b, +// 0x3cabf8dc, 0x0785aca7, 0xd0350f09, 0x79cac3c1, 0x00010001, 0x00000000, 0x00000000, +// 0x00000000}; // */ + +const uint32_t bop_image_addr[] = { + 0x4c425346, 0x00010001, 0x00000001, 0x00002e80, 0xa020005c, 0xa020005c, 0x00000040, + 0x00000000, 0x00000020, 0x00000104, 0x3c000100, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xa54a0000, 0xa02000b7, 0x06408067, 0x30405073, 0x34405073, 0x41014081, + 0x42014181, 0x43014281, 0x44014381, 0x46814481, 0x47814701, 0x48814801, 0x49814901, + 0x4a814a01, 0x4b814b01, 0x4c814c01, 0x4d814d01, 0x4e814e01, 0x4f814f01, 0x00100197, + 0x75c18193, 0xf14023f3, 0x00000293, 0x0072f463, 0x01d0106f, 0x0018128b, 0x62858116, + 0x80028293, 0x025382b3, 0x40510133, 0x006f840a, 0x12ef0040, 0x25731290, 0x10eff140, + 0xc91576e0, 0x8c1f978b, 0x8b9f960b, 0x40c78633, 0x950b4581, 0x10ef8b9f, 0x960b0530, + 0x978b801f, 0x35b78b9f, 0x8633a020, 0x859340c7, 0x950bde85, 0x10ef801f, 0x27b77c60, + 0x8793a020, 0x90737fc7, 0x07938007, 0xa0732000, 0x07b77d07, 0x8793a020, 0x90734037, + 0x84303057, 0x20078793, 0x30779073, 0xfc2027f3, 0x01c7f85b, 0xa02007b7, 0x30178793, + 0x7ec79073, 0xe2000737, 0x00074783, 0xf7938420, 0xe7930817, 0x05130047, 0x0023c085, + 0x00ef00f7, 0x10ef6890, 0xe51944a0, 0x05138420, 0x00efc245, 0xa0016790, 0x05138420, + 0x00efc405, 0xbfd566d0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, + 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, + 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, + 0xa0201528, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa020157c, 0xa0200472, + 0xa020159a, 0xa0200504, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, + 0xa02005b6, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, + 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, + 0xa0200472, 0xa0200472, 0xa0200472, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0xc006711d, 0xc416c212, 0xc81ec61a, 0xcc2eca2a, + 0xd036ce32, 0xd43ed23a, 0xd846d642, 0xdc76da72, 0xc0fede7a, 0x7ee8d073, 0x7ef95073, + 0x7ed090f3, 0x42a24212, 0x43c24332, 0x45e24552, 0x56824672, 0x57a25712, 0x58c25832, + 0x5ee25e52, 0x4f865f72, 0x70734096, 0x90733004, 0x40a63420, 0x34109073, 0x345020f3, + 0xfc0094e3, 0x61254082, 0x30200073, 0x00000013, 0x00000013, 0x00000013, 0x00000013, + 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, + 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, + 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, + 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, + 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0xc0067119, 0xc416c212, 0xc81ec61a, + 0xcc2eca2a, 0xd036ce32, 0xd43ed23a, 0xd846d642, 0xdc76da72, 0xc0fede7a, 0x341022f3, + 0x30002373, 0xc49ac296, 0x34202573, 0x10ef858a, 0x77f34220, 0x42963004, 0x90734326, + 0x10733412, 0x40823003, 0x42a24212, 0x43c24332, 0x45e24552, 0x56824672, 0x57a25712, + 0x58c25832, 0x5ee25e52, 0x4f865f72, 0x00736109, 0x80823020, 0xff950793, 0x07db8030, + 0x67410cf7, 0xc3980705, 0xe20017b7, 0x00178713, 0x0ca7075b, 0x078d4685, 0xe2000837, + 0x00d70023, 0x00251593, 0x00084683, 0x0ca7855b, 0x00054703, 0x1016a6db, 0x00d71733, + 0x57334621, 0x478940d7, 0x96b38020, 0x8f5500d7, 0x00238810, 0x470300e5, 0x275b0008, + 0x5f5b1017, 0x47830087, 0x07330005, 0xd7b340e6, 0x97b340e7, 0xe79300e7, 0x8c140017, + 0x00f50023, 0xe20017b7, 0x97ae0789, 0x77138004, 0x80230fe7, 0x808200e7, 0x970b1101, + 0xca4a81df, 0xc25ac652, 0xce06c05e, 0xc84ecc26, 0x4318c456, 0x81df9b0b, 0x03072a83, + 0x9a0b4901, 0x4b8581df, 0x01090993, 0x00890493, 0x013b99b3, 0x012b97b3, 0x009b94b3, + 0x0159f9b3, 0x9b638cdd, 0xf7b30009, 0x567d00fa, 0x4609e391, 0x0154f7b3, 0xa801e399, + 0x27834601, 0x2503068b, 0x85ca048b, 0x27839782, 0xf4b3000a, 0xe4b30154, 0x09050134, + 0x0b11db84, 0xba79685b, 0x44e240f2, 0x49c24952, 0x4aa24a32, 0x4b824b12, 0x80826105, + 0x07b7cd99, 0x5bd8a042, 0x765b4581, 0x47030057, 0x45850005, 0x4505d398, 0x8d4d05c2, + 0x45018082, 0x978bbfe5, 0x4394805f, 0x42d875c1, 0x15f94a90, 0x80148f6d, 0xc2d89a79, + 0x00c03633, 0x4b884bd8, 0x40c00633, 0x87024581, 0x3fa012ef, 0x77938a3e, 0x8aaa0038, + 0x89b28b2e, 0x893a8bb6, 0x84b28c42, 0x84bae785, 0x40e60cb3, 0x56fda031, 0x801085da, + 0x9a820485, 0x009c8633, 0xff44e9e3, 0x64634481, 0x04b3012a, 0x94ce412a, 0x852694ca, + 0x41248633, 0x00091c63, 0x001c785b, 0x413484b3, 0x00998533, 0x0144ed63, 0x3d60106f, + 0x87b3197d, 0xc503012b, 0x56fd0007, 0x9a8285da, 0x862abfc9, 0x85da56fd, 0x04858010, + 0xbfd99a82, 0x3a2012ef, 0x48528342, 0x47c28e3e, 0x4418735b, 0x00187e93, 0x8963cb91, + 0x1663000e, 0x7f13000e, 0x036300c8, 0x17fd000f, 0x03000f13, 0x59dba801, 0x8fb30007, + 0x070500e6, 0x01ef8023, 0xff1769e3, 0x0f934f7d, 0x86630300, 0x7463000e, 0x7c6300f7, + 0x755b02ef, 0x7f5b0648, 0xcf0d42a8, 0x00e88463, 0x02f71a63, 0xfff70893, 0x02088563, + 0x555b1779, 0x87460303, 0x02236c5b, 0xeb6348fd, 0x800004e8, 0x06200313, 0x82b3a015, + 0x802300e6, 0x070501f2, 0x4701bf5d, 0xbf03605b, 0x7e5b48fd, 0xe9634258, 0x800002e8, + 0x07800313, 0x84040705, 0xe16348fd, 0x800002e8, 0x03000313, 0x84040705, 0xe96348fd, + 0x006300e8, 0x8000020e, 0x02d00313, 0x84040705, 0x106f3d45, 0xede32f40, 0x8000fee8, + 0x05800313, 0x765bb7e1, 0x80000028, 0x02b00313, 0x715bb7c5, 0x8000be38, 0x02000313, + 0x7159bfd1, 0xced2d2ca, 0xccd6893a, 0xc6e2cada, 0xc2eac4e6, 0xd6868f55, 0xd0ced4a6, + 0xc0eec8de, 0x8a2a5c66, 0x8b328aae, 0x8d468cb6, 0x7c13e319, 0x745bfefc, 0x498100ac, + 0x0493c335, 0x745b0610, 0x0493005c, 0x0d930410, 0x49810201, 0x14d94ba5, 0x86ea8642, + 0x85ca8566, 0xcc42ce3e, 0x4c4010ef, 0x48628c04, 0xe66347f2, 0x051306ab, 0x8c040305, + 0x80238642, 0x86ea00ad, 0x85ca8566, 0xcc42ce3e, 0x25c010ef, 0x47f24862, 0x69630985, + 0x146301a9, 0xe563012d, 0x0d85010c, 0x0209eadb, 0x58c65756, 0x1014c03a, 0x865a874e, + 0x855285d6, 0x3da9c262, 0x54a650b6, 0x59865916, 0x4ae64a76, 0x4bc64b56, 0x4ca64c36, + 0x4d864d16, 0x80826165, 0x892e8caa, 0x9526b741, 0x12efbf69, 0x71791d40, 0xe2994e86, + 0xfefefe93, 0x00aef35b, 0x0313c2b1, 0xf45b0610, 0x0313005e, 0x8f360410, 0x01010f93, + 0x43a54681, 0xff630e13, 0x02ff72b3, 0x0ff2f313, 0x0253ed63, 0x03030313, 0x0ff37313, + 0x006f8023, 0x53330685, 0x656302ff, 0x0f8500ff, 0x0006eddb, 0x88c2c046, 0x87ba883e, + 0x08148736, 0x33f9c276, 0x106f6145, 0x8f1a1900, 0x9372b7c1, 0x711db7f1, 0x8936caca, + 0xde62c0de, 0x8baada6a, 0x8d328c2e, 0x8636854a, 0x86ba85ba, 0xc4d6c6d2, 0xdc66c2da, + 0xcca6ce86, 0xd86ec8ce, 0x8abe8b3a, 0x8a468cc2, 0x629010ef, 0x8c10e51d, 0x8607a603, + 0x8647a683, 0x85da854a, 0x611010ef, 0x00a04d63, 0xa6038c10, 0xa6838687, 0x854a86c7, + 0x10ef85da, 0x59635ff0, 0x88d20205, 0x87d68866, 0x86ca875a, 0x85e2866a, 0x2699855e, + 0x44e640f6, 0x49c64956, 0x4aa64a36, 0x4b864b16, 0x5ce25c72, 0x5dc25d52, 0x80826125, + 0x46814601, 0x85da854a, 0x5c1010ef, 0x84dace4a, 0x00055663, 0x800004b7, 0x0164c4b3, + 0x400a7593, 0x735bc82e, 0x4a9940aa, 0x7944a55b, 0xc0150513, 0x4c5010ef, 0xa6038c10, + 0xa6838707, 0x10ef8747, 0x8c105520, 0x8787a603, 0x87c7a683, 0x312010ef, 0xa75b8c10, + 0xa6034c04, 0xa6838807, 0x07b78847, 0x8fd93ff0, 0xca2ec82a, 0x85be854a, 0x2ec010ef, + 0xa6038c10, 0xa6838887, 0x10ef88c7, 0x48425160, 0x862a48d2, 0x854286ae, 0x10ef85c6, + 0x10ef2d40, 0x89aa39d0, 0x461010ef, 0xa6038410, 0xa6838906, 0xc82a8946, 0x10efca2e, + 0x84104ea0, 0x8986a603, 0x89c6a683, 0x2aa010ef, 0x373010ef, 0x47d24742, 0xa6038410, + 0xa6838a06, 0x85be8a46, 0x853a8daa, 0x4c0010ef, 0x856ec82a, 0x10efca2e, 0x841041b0, + 0x8a86a603, 0x8ac6a683, 0x3ffd8d93, 0x4a4010ef, 0x47d24742, 0x86ae862a, 0x85be853a, + 0x25c010ef, 0x86ae862a, 0xd22ed02a, 0x488010ef, 0x57925702, 0x86be863a, 0xca2ec82a, + 0x85be853a, 0xd63ed43a, 0x23e010ef, 0xa6038410, 0xd02a8b06, 0x8b46a683, 0xd22e4542, + 0x10ef45d2, 0x3e376f60, 0x2603a020, 0x26838b8e, 0x10ef8bce, 0x862a2180, 0x454286ae, + 0x10ef45d2, 0x84106da0, 0x8c06a603, 0x8c46a683, 0x1fe010ef, 0x86ae862a, 0x45d24542, + 0x6c0010ef, 0x572257b2, 0x8c1086be, 0xc82aca2e, 0x8c87a503, 0x8cc7a583, 0x10ef863a, + 0x48421d20, 0x862a48d2, 0x854286ae, 0x10ef85c6, 0x53021c80, 0x862a5392, 0x851a86ae, + 0x10ef859e, 0x8c106860, 0x8d07a603, 0x8d47a683, 0x1aa010ef, 0x97934701, 0x863a014d, + 0x10ef86be, 0x862a3ce0, 0xc82a86ae, 0x854aca2e, 0x10ef85a6, 0x47423f70, 0x3e3747d2, + 0x4f63a020, 0xc83a1005, 0x8d93ca3e, 0x07930639, 0xbdb30c60, 0x0d9101b7, 0x04ba715b, + 0xa6038c10, 0xa6838d87, 0x854a8dc7, 0x10ef85a6, 0x47633bf0, 0x8c101005, 0x8e07a603, + 0x8e47a683, 0x85a6854a, 0x3ad010ef, 0x0e055c63, 0x0f59d863, 0x413a8ab3, 0x6a131afd, + 0x4d81400a, 0x48014981, 0x019df463, 0x41bc8833, 0x002a7593, 0x755bd02e, 0x8363001a, + 0x4801000d, 0x00098c63, 0x46d24642, 0x854a85a6, 0x10efd442, 0x58225ce0, 0xce2a84ae, + 0x46814601, 0x85da854a, 0x10efc842, 0x48423570, 0x00055563, 0x800007b7, 0x45f28cbd, + 0x889378fd, 0x86ae7ff8, 0x011a78b3, 0x872687d6, 0x85e2866a, 0x2079855e, 0xd40d84e3, + 0x04500793, 0x405a745b, 0x06500793, 0x00150493, 0x56fd862a, 0x85e2853e, 0xd6939b82, + 0xc63341f9, 0x47950136, 0xc03e8020, 0x88938626, 0x4801fffd, 0xd71347a9, 0x85e201f9, + 0x3105855e, 0x83e35482, 0x04b3d004, 0x053341a5, 0xfde3009d, 0x862acf94, 0x85e256fd, + 0x04858010, 0xb7f59b82, 0x8b8e2603, 0x8bce2683, 0x85be853a, 0x524010ef, 0xc82a19fd, + 0xbdd1ca2e, 0xbf214a81, 0xf00a8fe3, 0x400a7593, 0xf0058be3, 0xbf011afd, 0xd2ca7159, + 0xc8de8936, 0x8baec6e2, 0xc02a8c32, 0x854a8636, 0x85ba86ba, 0xd0ced4a6, 0xccd6ced2, + 0xcadad686, 0xc2eac4e6, 0x89bac0ee, 0x8ac284be, 0x10ef8a46, 0xcd0926f0, 0x88528410, + 0x470d87d6, 0x8f468693, 0x86624502, 0xf0ef85de, 0xa85993bf, 0xa6038c10, 0xa6838687, + 0x854a86c7, 0x10ef85ce, 0x59632430, 0x84100005, 0x87d68852, 0x86934711, 0xbfc98f86, + 0xa6038c10, 0xa6838607, 0x854a8647, 0x10ef85ce, 0x506321b0, 0x795b02a0, 0x8410002a, + 0x8ec68693, 0x88524711, 0xb76d87d6, 0x86938410, 0x470d8e86, 0x8c10bfcd, 0x9007a603, + 0x9047a683, 0x85ce854a, 0x1e9010ef, 0x00a04d63, 0xa6038c10, 0xa6839087, 0x854a90c7, + 0x10ef85ce, 0x59631d70, 0x45020205, 0x885688d2, 0x86ca87a6, 0x8662874e, 0x369585de, + 0x54a650b6, 0x59865916, 0x4ae64a76, 0x4bc64b56, 0x4ca64c36, 0x4d864d16, 0x80826165, + 0x46814601, 0x85ce854a, 0x199010ef, 0x10055063, 0x86ce864a, 0x45814501, 0x719000ef, + 0x892a89ae, 0xc22e4585, 0x0eaa765b, 0x47a54c81, 0x03000713, 0x0097fc63, 0x020c8613, + 0x002606b3, 0x80230c85, 0x14fd00e6, 0xbe0ce6db, 0x854a85ce, 0x7b6010ef, 0xa0203737, + 0xc9870713, 0x0e97075b, 0x430c4350, 0x8b2ac632, 0x10efc42e, 0x862a0670, 0x854a86ae, + 0x00ef85ce, 0x46226bf0, 0x3db746b2, 0x10efa020, 0xca2e0ea0, 0x10efc82a, 0x8d2a7e20, + 0x0b9010ef, 0x47d24742, 0x86ae862a, 0x85be853a, 0x695000ef, 0x898da703, 0x89cda783, + 0x86be863a, 0xce2ecc2a, 0x0ed010ef, 0xa703c86e, 0xa783898d, 0x486289cd, 0x596348f2, + 0x0d0504a0, 0x10ef856a, 0x862a07b0, 0x452286ae, 0x10ef45b2, 0x44630cb0, 0x0b0500a0, + 0xc4b94d01, 0x45a54629, 0x080ce7db, 0x003a7793, 0x1017ef5b, 0x100a8d63, 0xe5814592, + 0x00ca7793, 0x1afdc391, 0x071347fd, 0xa8cd0300, 0xbf19c202, 0xbf194499, 0x86be863a, + 0x85c68542, 0x085010ef, 0xfc0541e3, 0x000d0463, 0xba0d7d5b, 0xbf550d05, 0x10ef855a, + 0x862a79a0, 0x854a86ae, 0x00ef85ce, 0x44c25f30, 0xa9038d2a, 0xa9838984, 0x864a89c4, + 0x8dae86ce, 0x04d010ef, 0x00055a63, 0x86ce864a, 0x85ee856a, 0x039010ef, 0x00a05563, + 0x000b735b, 0x46a90b05, 0x76b3a89d, 0x0c8502cd, 0x020c8793, 0x00278533, 0x869314fd, + 0x0fa30306, 0x56b3fed5, 0xe56302cd, 0x94e603a5, 0x03000693, 0xb40cd8db, 0x001c8713, + 0x009c9e63, 0x100c8804, 0x00b48cb3, 0x02e00693, 0xfedc8023, 0xbf658cba, 0xb72d8d36, + 0x8cb38814, 0x80230025, 0x8cba00dc, 0x6733bfc1, 0x0c8502db, 0x020c8613, 0x4b33960a, + 0x071302db, 0x0fa30307, 0x03e3fee6, 0xe2dbf00b, 0xbdfdbe0c, 0x86b38804, 0x0c850024, + 0x00e68023, 0x015cf963, 0xff97f8e3, 0x87d68852, 0x10148766, 0x47fdbb25, 0xff97eae3, + 0xc8994492, 0x10048814, 0x009587b3, 0x02d00713, 0x80230c85, 0xbfe9fee7, 0x002a795b, + 0x100c8804, 0x00b487b3, 0x02b00713, 0x735bb7e5, 0x8814bc3a, 0x87b31004, 0x07130095, + 0xbfd90200, 0x23d002ef, 0x89ae892a, 0x4a054481, 0x409a05b3, 0x00998533, 0x3c05a5db, + 0x57939902, 0x94be0105, 0xa4db8c04, 0x535b3c04, 0x006fbe15, 0xcd192470, 0x227002ef, + 0x07a31141, 0x840000a1, 0x00f10593, 0x59450513, 0x01413f75, 0x2330006f, 0x71198082, + 0xc0dec2da, 0x3bb76b05, 0xde62a020, 0xa0203c37, 0xcacacca6, 0x0913c6d2, 0xc4d60641, + 0x44818a2a, 0xa0201ab7, 0x800b0b13, 0x918b8b93, 0x910c0c13, 0xc8cece86, 0xda6adc66, + 0xd2aed86e, 0xd6b6d4b2, 0xdabed8ba, 0xdec6dcc2, 0x4503d64a, 0xe90d000a, 0x862657f9, + 0x0097f363, 0x102c5679, 0x56fd4501, 0x40f63fbd, 0x49c64956, 0x4aa64a36, 0x4b864b16, + 0x5ce25c72, 0x5dc25d52, 0x44e68526, 0x80826109, 0x58db0a05, 0x89930055, 0x56fd0014, + 0x102c8626, 0x4881aa05, 0x02b00713, 0xdddba801, 0xe1db02d7, 0xe8930307, 0x8a360018, + 0x000a4783, 0x001a0693, 0x02b7d5db, 0xfef763e3, 0x0207d4db, 0x0237d5db, 0xfd078713, + 0x46258810, 0x06e66563, 0x46a54981, 0xa01d45a9, 0x0028e893, 0xe893b7f9, 0xb7e10048, + 0x0088e893, 0xe893b7c9, 0xbf750108, 0x02b989b3, 0x89938a32, 0x99bafd09, 0x000a4703, + 0x001a0613, 0xfd070793, 0xf3e38c14, 0x4783fef6, 0xeadb000a, 0x46830ce7, 0x4625001a, + 0xfd068713, 0x07938810, 0xe893001a, 0x60634008, 0x4d810ae6, 0x45294625, 0x4981a03d, + 0xbca7ebdb, 0x00092983, 0x00490793, 0x0009d663, 0x0028e893, 0x413009b3, 0x8a36893e, + 0x8db3bf6d, 0x87ae02ad, 0xfd0d8d93, 0xc6839db6, 0x85930007, 0x87130017, 0x8810fd06, + 0xfee673e3, 0x8a138004, 0x06930017, 0x5edb06c0, 0xe56346c7, 0x53db06e6, 0x5bdb4887, + 0x8a3e48a7, 0x000a4503, 0x07800793, 0xe8e30a05, 0x0793eea7, 0xe2630570, 0x079308a7, + 0x5d5b0450, 0xe7634855, 0x6cdb08a7, 0x8993ac55, 0x56fd0014, 0x102c8626, 0x02500513, + 0x3d3184ce, 0x4d81b559, 0xbaa6e4db, 0x00092d83, 0x00490713, 0x000dd363, 0x07934d81, + 0x893a002a, 0x87d2bf41, 0xb7694d81, 0x414754db, 0xf9a76fdb, 0x1008e893, 0xc703bf61, + 0x6bdb0017, 0xe893fec7, 0x8a133008, 0xb7590027, 0x0017c703, 0x408755db, 0x0808e893, + 0xe893bfa5, 0xb7e50c08, 0x2008e893, 0x0793b7b5, 0x8c14fa85, 0x02000713, 0xe4f76de3, + 0x0cfb87db, 0x8782439c, 0x5465515b, 0xe475655b, 0x0df57793, 0x4077e65b, 0x0168e8b3, + 0x0fd57513, 0x4055635b, 0x07138414, 0x9b610079, 0x09134314, 0x43580087, 0x87ee884e, + 0x102c8626, 0xf0ef8800, 0xa21de38f, 0x6b8558db, 0x6b85555b, 0x6af556db, 0x6a2556db, + 0xfef8f893, 0x56db47a9, 0x54db4095, 0xf8934045, 0xf45bff38, 0xf89300a8, 0xf713ffe8, + 0x54db2008, 0x66db4095, 0xc7314845, 0x7913091d, 0x2503ff89, 0x27030049, 0x56130009, + 0x8f3141f5, 0x40c706b3, 0x00a645b3, 0x00d73733, 0x40c58633, 0xc446883e, 0x00890c93, + 0x57934881, 0x073301f5, 0xc24e40e6, 0x8626c06e, 0x8800102c, 0xc72ff0ef, 0x896684aa, + 0x2703bb99, 0x0c930009, 0xf15b0049, 0x56930288, 0xc63341f7, 0xc04600e6, 0x88ce886e, + 0x8020837d, 0x102c8626, 0xf0ef8800, 0xbfc9d18f, 0x0068f45b, 0xbff18810, 0xbc78fd5b, + 0x3c07375b, 0xc305bfc9, 0x7913091d, 0x8c00ff89, 0x00492703, 0xc446883e, 0x00890c93, + 0x47814881, 0xc06ec24e, 0x8c00bf59, 0x00490c93, 0x0088f75b, 0x886ec046, 0x470188ce, + 0xf55bbf45, 0xf6930068, 0xb7fd0ff6, 0xbe78f65b, 0x3c06a6db, 0x8414b7d5, 0x00790713, + 0x43149b61, 0x00870913, 0x884e4358, 0x862687ee, 0x8800102c, 0x8cdff0ef, 0xb94584aa, + 0x0028f593, 0x4c85c82e, 0x4218f85b, 0xa0294c81, 0x102c56fd, 0x31358010, 0x01948633, + 0xe9e30c85, 0x4781ff3c, 0x00098463, 0xfff98793, 0x4c8994be, 0x00098463, 0x00198c93, + 0x00094503, 0x56fd8626, 0x8d13102c, 0x3ef50014, 0x0d9344c2, 0xc4850049, 0x866a84e6, + 0x56fda809, 0x8010102c, 0x00160913, 0x048536cd, 0xe8e3864a, 0x4701ff34, 0x0199e463, + 0x41998733, 0x896e9d3a, 0xb91584ea, 0x00490593, 0x8c00ca2e, 0x9363876e, 0x577d000d, + 0xe2918936, 0x974a8962, 0xc60387ca, 0xc2190007, 0x02f71463, 0x40d78cb3, 0x4008fd13, + 0x00a8f55b, 0x019df363, 0xf5938cee, 0xc82e0028, 0x4418f15b, 0x88b38626, 0xa831409c, + 0xbfc10785, 0x00160713, 0x102c56fd, 0xce468010, 0x36b5cc3a, 0x48f24762, 0x0733863a, + 0x63e30116, 0x4701ff37, 0x0199e463, 0x41998733, 0x001c8793, 0x0cb394ba, 0x872600f7, + 0x409706b3, 0xc50396ca, 0xc5190006, 0x000d0d63, 0xfffd8693, 0x000d9863, 0xc0b944c2, + 0x84b3863a, 0xa02d40ec, 0x08938db6, 0x863a0017, 0x102c56fd, 0x3e11cc46, 0x874648e2, + 0x56fdb7e1, 0x8010102c, 0x00160913, 0x3601c83a, 0x864a4742, 0x00c486b3, 0xff36e5e3, + 0xe4634681, 0x86b30199, 0x97364199, 0x84ba4952, 0x8c00b6b9, 0x0218e893, 0xc0468626, + 0x00490993, 0x886e48a1, 0x470147c1, 0x8800102c, 0xb1aff0ef, 0x84aa894e, 0x8414b62d, + 0xb3b547c1, 0xb3a547a1, 0xb3954789, 0x4bc002ef, 0xa05207b7, 0x0187a983, 0x09374481, + 0x4a05a052, 0xa0203ab7, 0x0209f85b, 0x01492683, 0x009a17b3, 0xfff7c713, 0x2a238f75, + 0x270300e9, 0xd6130189, 0x8fd94024, 0x0034f593, 0x99ca8513, 0x00f92c23, 0xa8bff0ef, + 0xd9930485, 0xe55b0019, 0xa979bd04, 0x482002ef, 0xa08004b7, 0x84205ccc, 0x9cc50513, + 0xa6bff0ef, 0xe7935cdc, 0xdcdc03f7, 0x02efa169, 0xa7ab4640, 0x8420803f, 0x051353ec, + 0xf0ef9f45, 0xa72ba4df, 0x537c803f, 0x0017e793, 0xa1a5d37c, 0x442002ef, 0xa01104b7, + 0x9073409c, 0x67893407, 0xa0112737, 0x28078793, 0x0793c35c, 0xc71c3f60, 0x474140dc, + 0x4727e793, 0x07b7c0dc, 0xcbd8a042, 0x08000713, 0x4739d7d8, 0xa223d398, 0x474d0207, + 0x471dd7d8, 0x17b7d798, 0x43d8a011, 0xfdf77713, 0x43d8c3d8, 0xe7f77713, 0x10076713, + 0x4798c3d8, 0xfdf77713, 0x4798c798, 0xe7f77713, 0x10076713, 0x43d8c798, 0xc3d88014, + 0x80144798, 0x07b7c798, 0xcdaba071, 0x43988aff, 0x7807275b, 0x4398c398, 0x14074063, + 0x06b74398, 0x8f558000, 0x4398c398, 0x12075863, 0x9b3d4398, 0x4398c398, 0x5247725b, + 0x67134398, 0xc3980107, 0xfb5b439c, 0x84201047, 0xa1c50513, 0x977ff0ef, 0x0ac48713, + 0x8420431c, 0x1007e793, 0xa583c31c, 0x05130ac4, 0xf0efa485, 0x842095df, 0xaa050513, + 0x953ff0ef, 0x05138420, 0xf0efab85, 0x960b949f, 0x56838a5f, 0x47850126, 0x0cd7ee63, + 0x07138030, 0x431c0f07, 0x869376c1, 0x8ff53ff6, 0x869366ad, 0x84204006, 0x05138fd5, + 0xc31cad45, 0x917ff0ef, 0x05138420, 0xf0efaf45, 0x679990df, 0xa0120737, 0xaa578793, + 0xcf1c8420, 0xb6050513, 0x7e600793, 0xa01104b7, 0xf0efcb1c, 0x40dc8edf, 0xf7938420, + 0xc0dcbff7, 0x051340dc, 0xe793b785, 0xc0dc4007, 0x8d3ff0ef, 0x05138420, 0xf0efb905, + 0x84938c9f, 0x409c0f04, 0xe0020737, 0x8ff9177d, 0x00080737, 0xc09c8fd9, 0xa0133737, + 0x8aefcfab, 0x007a17b7, 0x20078793, 0xa01336b7, 0x2c46a703, 0x0a07705b, 0xfbfd17fd, + 0x07138030, 0x431c0f07, 0x869376c1, 0x8ff53ff6, 0x66858420, 0x05138fd5, 0xc31cbc85, + 0xf0ef4489, 0xa059871f, 0x05138420, 0xf0efa6c5, 0xb721865f, 0xa0800737, 0x05b74b5c, + 0x15fdff00, 0xcb5c8fed, 0x82855b1c, 0x0077e793, 0x4b0cdb1c, 0xf593421c, 0x079ef605, + 0x424c8fcd, 0x059216fd, 0x460c8fcd, 0x058e8420, 0x464c8fcd, 0x01064603, 0x8fcd058a, + 0xcb1c8fd1, 0x0513433c, 0xf793b145, 0x8eddf007, 0xf0efc334, 0x842080df, 0xb2c50513, + 0x803ff0ef, 0x05138420, 0xb5f5b485, 0xf33d8b79, 0x05138420, 0x4481bac5, 0xfeaff0ef, + 0xe20007b7, 0x85a38004, 0x67f30007, 0x84203004, 0xbe850513, 0xfd2ff0ef, 0xe0ef454d, + 0x4561c4bf, 0xc45fe0ef, 0xe0ef4569, 0x456dc3ff, 0xc39fe0ef, 0x02100513, 0xc31fe0ef, + 0xaae18526, 0x0073c501, 0xbff51050, 0x80824505, 0xce061101, 0xca4acc26, 0x26f3c84e, + 0x67053420, 0xf7b3177d, 0xc66300e6, 0x44810406, 0x02e78863, 0xa0203937, 0xc7c90913, + 0xa02009b7, 0x012487b3, 0x0007c783, 0x00f10593, 0x59498513, 0x07a30485, 0xf0ef00f1, + 0xe35bf0ef, 0xa001bf94, 0x05138420, 0xf0efc605, 0x40f2f4cf, 0x495244e2, 0x610549c2, + 0x07138082, 0x68e30310, 0x0737fef7, 0x0713a020, 0x07db2007, 0x439c0cf7, 0xbff19782, + 0x0000a001, 0x82aac63d, 0xf31383b2, 0x9316fe03, 0x02655863, 0x41d44190, 0x45dc4598, + 0xc154c110, 0xc55cc518, 0x49d44990, 0x4ddc4d98, 0xc954c910, 0xcd5ccd18, 0x02058593, + 0x02050513, 0xfc654ce3, 0xffc3f313, 0x00530333, 0x00655863, 0x05914190, 0x0511c110, + 0xfe654ce3, 0x00728333, 0x00655a63, 0x0005c603, 0x00230585, 0x050500c5, 0xfe654ae3, + 0x80828516, 0x03b3832a, 0x769300c5, 0xce810035, 0xffc68693, 0x40d507b3, 0x06f3e463, + 0x00b50023, 0x9de30505, 0x0d63fea7, 0x05e20475, 0x0085d793, 0xd79395be, 0x95be0105, + 0x40a38633, 0x02000713, 0xfe067693, 0x00a687b3, 0x7693e285, 0xca8dffc6, 0x40d70633, + 0x00a687b3, 0x82058736, 0x00000697, 0x00c686b3, 0x00c68067, 0xcd0ccd4c, 0xc90cc94c, + 0xc50cc54c, 0xc10cc14c, 0x17e3953a, 0xbf6dfef5, 0x1de3879e, 0x851af875, 0x71398082, + 0xc66e4301, 0x7139a019, 0xc86a5341, 0xcc62ca66, 0xa019ce5e, 0x53017139, 0xd256d05a, + 0xd64ed452, 0xda26d84a, 0xde06dc22, 0x40610133, 0x11418282, 0xc226c04a, 0xc606c422, + 0x4db28282, 0x4d020141, 0x4c224c92, 0x01414bb2, 0x4a924b02, 0x49b24a22, 0x49020141, + 0x44224492, 0x014140b2, 0x00008082, 0xa0494701, 0x01065a93, 0x01051893, 0x0108d793, + 0xd7338141, 0xf5b30355, 0x18930355, 0xd6930106, 0x05c20108, 0x05338dc9, 0xbfb302d7, + 0x8e6300a5, 0x177d000f, 0xbfb395b2, 0x986300c5, 0xbfb3000f, 0x846300a5, 0x177d000f, + 0x8d8995b2, 0x0355f533, 0x0355d5b3, 0x8d5d0542, 0x02b686b3, 0x00d53fb3, 0x000f8e63, + 0x15fd9532, 0x00c53fb3, 0x000f9863, 0x00d53fb3, 0x000f8463, 0x15fd9532, 0x07428d15, + 0x80828dd9, 0xc0267179, 0xc44ec24a, 0xc856c652, 0xcc06ca22, 0x892e84aa, 0x8a3689b2, + 0xeac5843a, 0x01393fb3, 0x020f8e63, 0x00ef854e, 0xce2a4ab0, 0x99b3cd19, 0x089300a9, + 0x87b30200, 0xd7b340a8, 0x193300f4, 0x693300a9, 0x94b300f9, 0x852600a4, 0x864e85ca, + 0xd02e3f05, 0x478184aa, 0xa0b9d23e, 0x854ece21, 0x471000ef, 0xe519ce2a, 0x41390933, + 0xd23e4785, 0x02c0006f, 0x02000893, 0x40a88fb3, 0x00a999b3, 0xd733864e, 0x17b301f4, + 0x94b300a9, 0xe53300a4, 0x55b300e7, 0x35ed01f9, 0x892ad22e, 0x85ca8526, 0x3df9864e, + 0x84aad02e, 0x46f2c479, 0xd4b34901, 0xa87d00d4, 0x0339d933, 0x0339f4b3, 0x45014581, + 0xc004cc55, 0x01242223, 0x3fb3a855, 0x97e30149, 0x8552fe0f, 0x3fd000ef, 0xc955ce2a, + 0x02000893, 0x40a88733, 0x00e9d7b3, 0x00aa1633, 0x8a328e5d, 0x00a999b3, 0x00e4d6b3, + 0x00a494b3, 0x00a91533, 0x00e955b3, 0x3dad8d55, 0x892ad02e, 0x03358533, 0x0335b5b3, + 0x00b93fb3, 0x000f9863, 0x03259263, 0x00a4bfb3, 0x000f8e63, 0x85b35682, 0x16fd4145, + 0x06b3d036, 0x3fb34135, 0x85b300d5, 0x853641f5, 0xd2364681, 0x8533c80d, 0x05b340a4, + 0xbfb340b9, 0x85b300a4, 0x46f241f5, 0x02000893, 0x40d88733, 0x00e59933, 0x00d554b3, + 0x0124e4b3, 0x00d5d933, 0x2223c004, 0x55020124, 0x02412583, 0x49124482, 0x4a3249a2, + 0x44524ac2, 0x614540e2, 0x46818082, 0x012a3fb3, 0x000f9663, 0x0134bfb3, 0x000f9e63, + 0xd03e4785, 0x41348733, 0x41490933, 0x00e4bfb3, 0x41f90933, 0xa01184ba, 0xd236d036, + 0xbf65f855, 0xc0061141, 0x3d2d0058, 0x45a24512, 0x01414082, 0x00008082, 0x80000737, + 0x97138eb9, 0x11010015, 0xc24ac026, 0xc652c44e, 0xca06c856, 0x00169493, 0x800000b7, + 0x00973fb3, 0x000f9863, 0x02971063, 0x00c53fb3, 0x000f8c63, 0x8a2e89aa, 0x85b68532, + 0x86d2864e, 0x00159713, 0x00169493, 0xf6b38ead, 0x59130016, 0xda930157, 0x1a130154, + 0x999300a7, 0x079300a4, 0x80637ff0, 0x6fb31d27, 0x886300a7, 0xefb31a0f, 0x8e6300c4, + 0x04b3120f, 0xbf934159, 0x88630404, 0x5793120f, 0x6a330155, 0x052e00fa, 0x01565793, + 0x00f9e9b3, 0x3f93062e, 0x9d630029, 0x6a33040f, 0x8463001a, 0xe9b3000a, 0x87930019, + 0x9363fff4, 0x84be000a, 0x0893c0a1, 0x87b30200, 0x5c634098, 0x173300f0, 0x97b300f6, + 0xd9b300f9, 0x56330099, 0x8e5d0096, 0x04b3a829, 0x879340f0, 0x97330207, 0x8f5100f9, + 0x8726e091, 0x0099d633, 0xc3194981, 0x00266613, 0x1663c6e9, 0x14630159, 0x0f63013a, + 0x3fb310c5, 0x9863013a, 0x1d63000f, 0x3fb3013a, 0x896300c5, 0x197d000f, 0x01f99713, + 0x0019d993, 0x8e598205, 0x8d11872a, 0x00a73fb3, 0x41fa0a33, 0x413a0a33, 0x00293f93, + 0x0a0f9263, 0x020a1563, 0x02093f93, 0x020f9163, 0x45018a2a, 0x1c631901, 0xa8310009, + 0x0c63197d, 0x57130009, 0x0a0601f5, 0x6a330506, 0x3fb300ea, 0x95e3001a, 0x0513fe0f, + 0x3f934005, 0x9a7e4005, 0x01fa3fb3, 0x5793997e, 0x8b8500b5, 0x8d1d84aa, 0x00a4bfb3, + 0x41fa0a33, 0x17930a06, 0x5a13014a, 0x812d00ca, 0x17938d5d, 0x6a330149, 0xf5b300fa, + 0xe5b30015, 0x44820145, 0x49a24912, 0x4ac24a32, 0x610540d2, 0x95328082, 0x00c53fb3, + 0x3fb39a7e, 0x9a4e01fa, 0x000f9f63, 0x013a3fb3, 0x000f9b63, 0xf8091be3, 0x1713812d, + 0x5a13015a, 0x8d5900ba, 0x0893bf7d, 0x87b37fe0, 0xc3854128, 0x00157f93, 0x00256793, + 0x000f8363, 0x1713853e, 0x5a1301fa, 0x8105001a, 0x09058d59, 0x4501bfb9, 0x7ff00a37, + 0xdad1b779, 0x45814501, 0x6a33b779, 0x156300aa, 0x92e3001a, 0xd2c1f957, 0x05b74501, + 0xbfa5fff8, 0xc0261101, 0xc44ec24a, 0xc856c652, 0xcc0eca22, 0x1141ce06, 0x00159713, + 0x99138355, 0x549300b5, 0x69330155, 0x14930099, 0x043700b5, 0x97938000, 0x83d50016, + 0x00b69a13, 0x01565993, 0x013a6a33, 0x00b61993, 0xfab38ead, 0x06930086, 0xcb6d7ff0, + 0x14e68e63, 0x00896933, 0x18078d63, 0x16f68463, 0x008a6a33, 0x8513c656, 0x972ac027, + 0x034936b3, 0x03490633, 0x0344b5b3, 0x03448533, 0x00b60a33, 0x00ba3fb3, 0x01f68ab3, + 0x033936b3, 0x03390633, 0x00a60933, 0x00a93fb3, 0x3fb39a7e, 0x9afe01fa, 0x3fb39a36, + 0x9afe00da, 0x0334b5b3, 0x03348533, 0x3fb3992e, 0x9a7e00b9, 0x01fa3fb3, 0x01fa85b3, + 0x00a96933, 0x001a6513, 0x00091363, 0xaf938552, 0x99630005, 0x8faa000f, 0x3fb3952a, + 0x95ae01f5, 0x177d95fe, 0x5c634ab2, 0x089314e0, 0x87b37ff0, 0x5d6340e8, 0x05130cf0, + 0x3f934005, 0x86634005, 0x95fe000f, 0x01f5bfb3, 0x5613977e, 0x8a0500b5, 0x812d8d11, + 0x01559613, 0x05868d51, 0x179381b1, 0x8ddd0147, 0x0155e5b3, 0x44820141, 0x49a24912, + 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, 0x00996fb3, 0x040f8563, 0x01f4df93, + 0x997e994a, 0x156394a6, 0x89260009, 0x17014481, 0x85ca4501, 0x95aea019, 0xbfb30505, + 0x9ce30085, 0x05e3fe0f, 0x8f09ee05, 0x02000893, 0x40a88633, 0x00c4d633, 0x00a494b3, + 0x00a91933, 0x00c96933, 0x8363b5f1, 0x85d604f6, 0x44820141, 0x49a24912, 0x4ac24a32, + 0x41e24452, 0x610540f2, 0x00008067, 0x00996933, 0x02891263, 0x1613e791, 0x6633001a, + 0xca190136, 0x00f69663, 0x013a6a33, 0x008a1663, 0x05b74501, 0xbf897ff0, 0x05b74501, + 0x0141fff8, 0x49124482, 0x4a3249a2, 0x44524ac2, 0x40f241e2, 0x80676105, 0x65330000, + 0xdd51013a, 0x01f9df93, 0x9a7e9a52, 0x156399ce, 0x8a4e000a, 0x17814981, 0x85d24501, + 0x95aea019, 0xbfb30505, 0x9ce30085, 0x03e3fe0f, 0x8f89e405, 0x02000893, 0x40a88633, + 0x00c9d633, 0x00a999b3, 0x00aa1a33, 0x00ca6a33, 0x4481b525, 0x86b34885, 0xbf9340e8, + 0x9b630206, 0x84aa000f, 0x4581852e, 0xc5091681, 0x0206bf93, 0x020f8d63, 0x0893c29d, + 0x86330200, 0x993340d8, 0x17b300c5, 0x553300c5, 0xd5b300d5, 0x653300d5, 0x8cdd0125, + 0x6513c099, 0x05130015, 0x3f934005, 0x95fe4005, 0x01f5d713, 0x4501bd9d, 0x0000bded, + 0xc0261101, 0xc44ec24a, 0xc856c652, 0xcc0eca22, 0x1141ce06, 0x00159713, 0x99138355, + 0x549300b5, 0x69330155, 0x14930099, 0x043700b5, 0x97938000, 0x83d50016, 0x00b69a13, + 0x01565993, 0x013a6a33, 0x00b61993, 0xfab38ead, 0x06930086, 0x08637ff0, 0x84632207, + 0x69332ce6, 0x8d630089, 0x85632e07, 0x6a332ef6, 0x8f1d008a, 0x3ff70713, 0x15938085, + 0x8ccd01f9, 0x00195913, 0x010a5613, 0x02c956b3, 0x02c97933, 0x010a1893, 0x0108d593, + 0x02d587b3, 0xd5130942, 0x69330104, 0x854a00a9, 0x40f90933, 0x01253fb3, 0x000f8863, + 0x995216fd, 0x01493fb3, 0xfe0f8ce3, 0x02c95833, 0x02c97933, 0x87b38642, 0x094202c5, + 0x01049893, 0x0108d513, 0x00a96933, 0x0933854a, 0x3fb340f9, 0x88630125, 0x167d000f, + 0x3fb39952, 0x8ce30149, 0x06c2fe0f, 0xb5b396b2, 0x85330336, 0x04b30336, 0x854a40a0, + 0x40b90933, 0x01253fb3, 0x854ac499, 0x9663197d, 0x3fb3000f, 0x81630125, 0x16fd020f, + 0xb53394ce, 0x99520134, 0x01493fb3, 0x0905c511, 0x000f9663, 0x00193f93, 0xfe0f83e3, + 0x01491763, 0x892685ce, 0x45014601, 0x5593a041, 0x5633010a, 0x793302b9, 0x189302b9, + 0xd513010a, 0x0fb30108, 0x094202c5, 0x0104d793, 0x00f96933, 0x093387ca, 0xbfb341f9, + 0x88630127, 0x167d000f, 0x3fb39952, 0x8ce30149, 0x5833fe0f, 0x793302b9, 0x85c202b9, + 0x02b507b3, 0x98930942, 0xd5130104, 0x69330108, 0x854a00a9, 0x40f90933, 0x01253fb3, + 0x000f8863, 0x995215fd, 0x01493fb3, 0xfe0f8ce3, 0x962e0642, 0x033635b3, 0x03360533, + 0x40a004b3, 0x0933854a, 0x3fb340b9, 0xc4990125, 0x197d854a, 0x000f9663, 0x01253fb3, + 0x020f8163, 0x94ce167d, 0x0134b533, 0x3fb39952, 0xc5110149, 0x96630905, 0x3f93000f, + 0x83e30019, 0xaf93fe0f, 0x99630006, 0x8fb2000f, 0x3fb39632, 0x96b601f6, 0x177d96fe, + 0x00996933, 0x00166513, 0x00091363, 0x85b68532, 0x16e05f63, 0x7ff00893, 0x40e887b3, + 0x0ef05b63, 0x40050513, 0x40053f93, 0x000f8663, 0xbfb395fe, 0x977e01f5, 0x00b55613, + 0x8d118a05, 0x9613812d, 0x8d510155, 0x81b10586, 0x01471793, 0xe5b38ddd, 0x01410155, + 0x49124482, 0x4a3249a2, 0x44524ac2, 0x40f241e2, 0x80676105, 0x6fb30000, 0x85630099, + 0xdf93040f, 0x994a01f4, 0x94a6997e, 0x00091563, 0x44818926, 0x45011701, 0xa01985ca, + 0x050595ae, 0x0085bfb3, 0xfe0f9ce3, 0xda0507e3, 0x08938f09, 0x86330200, 0xd63340a8, + 0x94b300c4, 0x193300a4, 0x693300a9, 0xbb4100c9, 0x02f68463, 0x6fb3e789, 0x8363013a, + 0x85d6020f, 0x44820141, 0x49a24912, 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, + 0x013a6a33, 0xfe8a01e3, 0x05b74501, 0x0141fff8, 0x49124482, 0x4a3249a2, 0x44524ac2, + 0x40f241e2, 0x80676105, 0x69330000, 0x1fe30099, 0x8de3fc89, 0x4501fcf6, 0x7ff005b7, + 0x0155e5b3, 0x44820141, 0x49a24912, 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, + 0x013a6a33, 0xfa8a18e3, 0xb7614501, 0x013a6fb3, 0xfc0f87e3, 0x01f9df93, 0x9a7e9a52, + 0x156399ce, 0x8a4e000a, 0x17814981, 0x85d24501, 0x95aea019, 0xbfb30505, 0x9ce30085, + 0x02e3fe0f, 0x8f89ce05, 0x02000893, 0x40a88633, 0x00c9d633, 0x00a999b3, 0x00aa1a33, + 0x00ca6a33, 0x4481b1d9, 0x86b34885, 0xbf9340e8, 0x9b630206, 0x84aa000f, 0x4581852e, + 0xc5091681, 0x0206bf93, 0x020f8d63, 0x0893c29d, 0x86330200, 0x993340d8, 0x17b300c5, + 0x553300c5, 0xd5b300d5, 0x653300d5, 0x8cdd0125, 0x6513c099, 0x05130015, 0x3f934005, + 0x95fe4005, 0x01f5d713, 0x4501bd81, 0x9693bdf9, 0x571300b5, 0x8ed90155, 0x80000737, + 0x97138ed9, 0x83550015, 0x41e00893, 0x40e88633, 0x02c05363, 0x02000713, 0x00e63fb3, + 0x000f9363, 0xd6b34681, 0xaf9300c6, 0x84630005, 0x06b3000f, 0x853640d0, 0xc1198082, + 0x0015e593, 0x7ff00737, 0x00b73fb3, 0x000f8563, 0x80000537, 0x05378082, 0x157d8000, + 0x00008082, 0x00b59693, 0x01555713, 0x07378ed9, 0x8ed98000, 0x00159713, 0x08938355, + 0x863341e0, 0x2f9340e8, 0x93630006, 0x0713020f, 0x3fb30200, 0x936300e6, 0x4681000f, + 0x00c6d6b3, 0x0005af93, 0x000f8463, 0x40d006b3, 0x80828536, 0xe593c119, 0x07370015, + 0x3fb37ff0, 0x856300b7, 0x0537000f, 0x80828000, 0x8082557d, 0xc0261141, 0x4581c206, + 0x86ae87ae, 0xc239862a, 0x00062f93, 0x000f8a63, 0x800007b7, 0x40c00633, 0x05b3c581, + 0x167d40b0, 0x41e00693, 0xc02a1141, 0xc432c22e, 0x1141c636, 0x8532c03e, 0x872a2215, + 0x01414782, 0x45924502, 0x46b24622, 0x8e990141, 0x00e61633, 0x00b5d713, 0x01561493, + 0x14938f45, 0x80b10016, 0x94938fc5, 0x8fc50146, 0x85be853a, 0x40924482, 0x80820141, + 0xc0261141, 0x4581c206, 0x862a86ae, 0x0693c60d, 0x110141e0, 0xc22ec02a, 0xc636c432, + 0x8532c83a, 0x87aa20e1, 0x45924502, 0x46b24622, 0x61054742, 0x16338e9d, 0xd71300f6, + 0x149300b5, 0x8f450156, 0x00161793, 0x949383b1, 0x8fc50146, 0x85be853a, 0x40924482, + 0x80820141, 0xa011577d, 0x47814705, 0xffe00e37, 0x00159293, 0x00a7bfb3, 0x01f28eb3, + 0x01de3fb3, 0x060f9863, 0x00169393, 0x00c7bfb3, 0x01f38eb3, 0x01de3fb3, 0x040f9e63, + 0x00d5c733, 0x04074063, 0x0005af93, 0x000f9f63, 0x40c50733, 0x00e53fb3, 0x40d58533, + 0x41f50533, 0x00e7bfb3, 0x857ee111, 0x07338082, 0x3fb340a6, 0x853300e6, 0x053340b6, + 0xbfb341f5, 0xe11100e7, 0x8082857e, 0x0072e7b3, 0x00c56733, 0xc7818fd9, 0xc1914505, + 0x8082852e, 0x8082853a, 0x736367c1, 0x079302f5, 0x07130ff0, 0xe9630200, 0x37b704a7, + 0x8793a020, 0x97aace87, 0x0007c503, 0x40a70533, 0x00008067, 0x010007b7, 0x00f57e63, + 0xa02037b7, 0x87938141, 0x97aace87, 0x0007c503, 0x05334741, 0x808240a7, 0xa02037b7, + 0x87938161, 0x97aace87, 0x0007c503, 0x05334721, 0x808240a7, 0xa02037b7, 0x87938121, + 0x97aace87, 0x0007c503, 0x05334761, 0x808240a7, 0x00e688b3, 0x02000513, 0xa0200537, + 0xa02036b7, 0xfd6a8513, 0x0ff77713, 0x00092683, 0xa02037b7, 0x0007c703, 0x00176713, + 0x00688023, 0x0208e893, 0x020c8493, 0x020c8593, 0x0ff57513, 0x0ff7f793, 0x40d606b3, + 0xa0110737, 0xa0203537, 0xa02007b7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0xffffffff, 0x7fefffff, 0xffffffff, 0xffefffff, 0x509f79fb, 0x3fd34413, + 0x8b60c8b3, 0x3fc68a28, 0x00000000, 0x3ff80000, 0x636f4361, 0x3fd287a7, 0x0979a371, + 0x400a934f, 0x00000000, 0x3fe00000, 0xbbb55516, 0x40026bb1, 0xfefa39ef, 0x3fe62e42, + 0x00000000, 0x402c0000, 0x00000000, 0x40240000, 0x00000000, 0x40180000, 0x00000000, + 0x40000000, 0x00000000, 0x3ff00000, 0xeb1c432d, 0x3f1a36e2, 0x00000000, 0x412e8480, + 0x00696e66, 0x2b696e66, 0x00000000, 0x006e616e, 0x2d696e66, 0x00000000, 0x00000000, + 0x41cdcd65, 0x00000000, 0xc1cdcd65, 0x6c756e28, 0x0000296c, 0xa020126c, 0xa020107e, + 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, + 0xa020107e, 0xa020126c, 0xa0201394, 0xa020126c, 0xa0201238, 0xa0201374, 0xa0201238, + 0xa020107e, 0xa020126c, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, + 0xa020126c, 0xa02014f6, 0xa020107e, 0xa020107e, 0xa0201410, 0xa020107e, 0xa020126c, + 0xa020107e, 0xa020107e, 0xa020126c, 0x666e695b, 0x67205d6f, 0x203a7470, 0x20717269, + 0x65636572, 0x64657669, 0x206e6f20, 0x656d6974, 0x75252072, 0x6863202c, 0x0d752520, + 0x0000000a, 0x666e695b, 0x73205d6f, 0x203a6970, 0x20717269, 0x65636572, 0x64657669, + 0x6f63202c, 0x203a6564, 0x78257830, 0x00000a0d, 0x666e695b, 0x67205d6f, 0x3a6f6970, + 0x71726920, 0x63657220, 0x65766965, 0x76202c64, 0x203a6c61, 0x58257830, 0x00000a0d, + 0x666e695b, 0x6f205d6f, 0x203a6566, 0x47504665, 0x6e612041, 0x43502064, 0x65522042, + 0x20746573, 0x65737341, 0x64657472, 0x00000a0d, 0x666e695b, 0x73205d6f, 0x203a7563, + 0x6c6f7349, 0x6f697461, 0x664f5f6e, 0x203d2066, 0x78257830, 0x00000a0d, 0x7272655b, + 0x205d726f, 0x3a65666f, 0x72724520, 0x4120726f, 0x72657373, 0x676e6974, 0x50466520, + 0x202c4147, 0x20424350, 0x65736552, 0x0a0d7374, 0x00000000, 0x666e695b, 0x78205d6f, + 0x203a4243, 0x74696e49, 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x71205d6f, 0x3a697073, + 0x696e4920, 0x74732074, 0x0d747261, 0x0000000a, 0x7665735b, 0x5d657265, 0x70737120, + 0x49203a69, 0x2074696e, 0x6c696166, 0x0a0d6465, 0x00000000, 0x7665735b, 0x5d657265, + 0x616c6620, 0x203a6873, 0x74696e49, 0x69616620, 0x0d64656c, 0x0000000a, 0x666e695b, + 0x71205d6f, 0x3a697073, 0x696e4920, 0x4b4f2074, 0x00000a0d, 0x666e695b, 0x66205d6f, + 0x6873616c, 0x6e49203a, 0x73207469, 0x74726174, 0x00000a0d, 0x666e695b, 0x66205d6f, + 0x6873616c, 0x6e49203a, 0x4f207469, 0x000a0d4b, 0x666e695b, 0x77205d6f, 0x203a7464, + 0x74696e49, 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x64205d6f, 0x203a616d, 0x74696e49, + 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x63205d6f, 0x74707972, 0x49203a6f, 0x2074696e, + 0x72617473, 0x000a0d74, 0x666e695b, 0x63205d6f, 0x74707972, 0x49203a6f, 0x2074696e, + 0x0a0d4b4f, 0x00000000, 0x7665735b, 0x5d657265, 0x79726320, 0x3a6f7470, 0x696e4920, + 0x61662074, 0x64656c69, 0x00000a0d, 0x666e695b, 0x69205d6f, 0x7265746e, 0x74707572, + 0x49203a73, 0x2074696e, 0x0a0d4b4f, 0x00000000, 0x666e695b, 0x66205d6f, 0x3a6c6273, + 0x696e4920, 0x74732074, 0x0d747261, 0x0000000a, 0x666e695b, 0x66205d6f, 0x3a6c6273, + 0x696e4920, 0x75532074, 0x73656363, 0x000a0d73, 0x7665735b, 0x5d657265, 0x62736620, + 0x49203a6c, 0x2074696e, 0x6c696146, 0x0a0d6465, 0x00000000, 0x666e695b, 0x77205d6f, + 0x203a7464, 0x20717269, 0x65636572, 0x64657669, 0x00000a0d, 0x78450a0d, 0x74706563, + 0x2e6e6f69, 0x636f4c20, 0x676e696b, 0x0d2e2e2e, 0x0000000a, 0x00000000, 0x3ff00000, + 0x00000000, 0x40240000, 0x00000000, 0x40590000, 0x00000000, 0x408f4000, 0x00000000, + 0x40c38800, 0x00000000, 0x40f86a00, 0x00000000, 0x412e8480, 0x00000000, 0x416312d0, + 0x00000000, 0x4197d784, 0x00000000, 0x41cdcd65, 0x02020100, 0x03030303, 0x04040404, + 0x04040404, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x06060606, 0x06060606, + 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x07070707, + 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, + 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, + 0x07070707, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, + 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, + 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, + 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, + 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0xa0510000, 0xa0130000, + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xa0600000, 0x000000ff, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x37c2cac9, 0x8c32e765, 0xa15e1200, 0x25c486b2, + 0x8734d7b4, 0xfa26c29d, 0x2ff972ae, 0x0adebf22, 0xff6f29e6, 0x3c50778d, 0xfa02d8da, + 0x78600d02, 0xbca88565, 0x163ca9be, 0x73f0da10, 0x3ed20b1c, 0xcce46d11, 0x2a49278f, + 0x12248db6, 0xe50b6755, 0xa431193c, 0x6c308699, 0xe0c41dbf, 0x50c791fe, 0xd3f876b9, + 0x7cf1df93, 0x16941322, 0xaa1ead8f, 0xe3753f54, 0xc9bb7bcc, 0x79200bff, 0x7d76c2d4, + 0xa7acc7f7, 0xff567a99, 0xbfa4f5dc, 0x064238c8, 0xe9699208, 0xa6b5daf3, 0xa3a2ad30, + 0x32bafe37, 0x54e1dacb, 0xda540799, 0x95547760, 0x302cd650, 0x9d428238, 0x62bbdadd, + 0xe531a353, 0x282e8f7d, 0x973e7ba1, 0x0dd65973, 0x4ab77a02, 0x53ca63ae, 0x176010c2, + 0x58bc890d, 0x025f55f8, 0x0e1e579b, 0xe19cdb04, 0x4bb6caf5, 0xad438b2c, 0xeda4466b, + 0x3cabf8dc, 0x0785aca7, 0xd0350f09, 0x79cac3c1, 0x00010001, 0x00000000, 0x00000000, + 0x00000000, 0xbb83b022, 0x95ebceca, 0x65fa7889, 0x3092c012, 0x9fcf0e0d, 0x88b9f5da, + 0xde074aae, 0xe06efe7f, 0x2caeace7, 0xa73adfae, 0xec7820db, 0xadf063a8, 0xe8bf5d84, + 0xd9dfe2c6, 0x746e5076, 0x45854a56, 0xdaa7c7d7, 0x63b79c9d, 0xb164694f, 0x69fa5ab0, + 0xc9ec14f7, 0xd6eac96f, 0x2b3ea0f2, 0xfd059077, 0x61dfb118, 0xf1f2951b, 0xf1c77f79, + 0xd16e9614, 0xb68ea35a, 0xd1ad833c, 0x8bed955a, 0xbb987f4b, 0x7f3c4c05, 0xfda5448b, + 0xec0591e4, 0xa844ae64, 0x392e6acc, 0x14e86521, 0x3f7fbd46, 0x4542bb46, 0x917fb21f, + 0x5a670490, 0x24cb8fee, 0xf720c30d, 0x377276bb, 0x782292ff, 0x5d14ddf0, 0x26c96e27, + 0x6db31b9a, 0x3301a1cf, 0xc70b0fdc, 0x231fe84d, 0xb0d83ebd, 0x0af5374a, 0x3e99435f, + 0x25aaa297, 0xcceec8a7, 0x2b4169ce, 0x67a065bc, 0x647152e6, 0x72b519ea, 0x81ffa154, + 0xee1d6e39, 0x166c4034 +}; + +struct rs_bop_header { + uint32_t bop_id; + uint16_t bop_hdr_version; + uint16_t sign_tool_version; + uint32_t binary_version; + uint32_t binary_len; + uint32_t load_addr; + uint32_t entry_addr; + uint32_t offset_to_binary; + uint32_t offset_to_next_header; + uint8_t sig_algo; + uint8_t option; + uint8_t enc_algo; + uint8_t iv_len; + uint16_t pub_key_len; + uint16_t enc_key_len; + uint16_t sig_len; + uint8_t compression_algo; + uint8_t bin_pad_bytes; // Number of padding bytes in the payload binary or + // bitstream + uint16_t xcb_header_size; + uint8_t padding[16]; // To make BOP header 64 bytes for scatter gather hash + // calculation + uint16_t crc_16; +}; + void pufs_rsa2048_verify_test(const struct device *pufs) { int lvStatus = 0; @@ -643,123 +1559,59 @@ void pufs_rsa2048_verify_test(const struct device *pufs) struct sign_ctx lvSignCtx = {0}; struct sign_pkt lvSignPkt = {0}; - const uint8_t pub_key[] = { - 0xc9, 0xca, 0xc2, 0x37, 0x65, 0xe7, 0x32, 0x8c, 0x00, 0x12, 0x5e, 0xa1, 0xb2, 0x86, - 0xc4, 0x25, 0xb4, 0xd7, 0x34, 0x87, 0x9d, 0xc2, 0x26, 0xfa, 0xae, 0x72, 0xf9, 0x2f, - 0x22, 0xbf, 0xde, 0x0a, 0xe6, 0x29, 0x6f, 0xff, 0x8d, 0x77, 0x50, 0x3c, 0xda, 0xd8, - 0x02, 0xfa, 0x02, 0x0d, 0x60, 0x78, 0x65, 0x85, 0xa8, 0xbc, 0xbe, 0xa9, 0x3c, 0x16, - 0x10, 0xda, 0xf0, 0x73, 0x1c, 0x0b, 0xd2, 0x3e, 0x11, 0x6d, 0xe4, 0xcc, 0x8f, 0x27, - 0x49, 0x2a, 0xb6, 0x8d, 0x24, 0x12, 0x55, 0x67, 0x0b, 0xe5, 0x3c, 0x19, 0x31, 0xa4, - 0x99, 0x86, 0x30, 0x6c, 0xbf, 0x1d, 0xc4, 0xe0, 0xfe, 0x91, 0xc7, 0x50, 0xb9, 0x76, - 0xf8, 0xd3, 0x93, 0xdf, 0xf1, 0x7c, 0x22, 0x13, 0x94, 0x16, 0x8f, 0xad, 0x1e, 0xaa, - 0x54, 0x3f, 0x75, 0xe3, 0xcc, 0x7b, 0xbb, 0xc9, 0xff, 0x0b, 0x20, 0x79, 0xd4, 0xc2, - 0x76, 0x7d, 0xf7, 0xc7, 0xac, 0xa7, 0x99, 0x7a, 0x56, 0xff, 0xdc, 0xf5, 0xa4, 0xbf, - 0xc8, 0x38, 0x42, 0x06, 0x08, 0x92, 0x69, 0xe9, 0xf3, 0xda, 0xb5, 0xa6, 0x30, 0xad, - 0xa2, 0xa3, 0x37, 0xfe, 0xba, 0x32, 0xcb, 0xda, 0xe1, 0x54, 0x99, 0x07, 0x54, 0xda, - 0x60, 0x77, 0x54, 0x95, 0x50, 0xd6, 0x2c, 0x30, 0x38, 0x82, 0x42, 0x9d, 0xdd, 0xda, - 0xbb, 0x62, 0x53, 0xa3, 0x31, 0xe5, 0x7d, 0x8f, 0x2e, 0x28, 0xa1, 0x7b, 0x3e, 0x97, - 0x73, 0x59, 0xd6, 0x0d, 0x02, 0x7a, 0xb7, 0x4a, 0xae, 0x63, 0xca, 0x53, 0xc2, 0x10, - 0x60, 0x17, 0x0d, 0x89, 0xbc, 0x58, 0xf8, 0x55, 0x5f, 0x02, 0x9b, 0x57, 0x1e, 0x0e, - 0x04, 0xdb, 0x9c, 0xe1, 0xf5, 0xca, 0xb6, 0x4b, 0x2c, 0x8b, 0x43, 0xad, 0x6b, 0x46, - 0xa4, 0xed, 0xdc, 0xf8, 0xab, 0x3c, 0xa7, 0xac, 0x85, 0x07, 0x09, 0x0f, 0x35, 0xd0, - 0xc1, 0xc3, 0xca, 0x79, 0x01, 0x00, 0x01, 0x00}; - - const uint8_t sig[] = { - 0xb9, 0x5f, 0x69, 0xef, 0x37, 0x5b, 0x03, 0xc4, 0xf3, 0x8d, 0x1d, 0x56, 0xad, 0x97, - 0xb6, 0x3d, 0x2a, 0x9c, 0x91, 0x97, 0xc2, 0xb8, 0x9d, 0xf2, 0x33, 0x15, 0x60, 0xd4, - 0xa8, 0x5e, 0xa1, 0x59, 0x15, 0x9a, 0x57, 0x96, 0xfc, 0x26, 0xae, 0x9d, 0x25, 0xba, - 0xbf, 0x77, 0x78, 0x26, 0xe7, 0x50, 0x7b, 0x3b, 0xf1, 0xcf, 0xd3, 0xda, 0x80, 0x5d, - 0xcd, 0xd1, 0xaf, 0xc5, 0x1a, 0x69, 0xb0, 0x37, 0x61, 0xde, 0x3c, 0x8a, 0x13, 0x2d, - 0x35, 0xfb, 0x10, 0xd9, 0x87, 0x05, 0xf0, 0xe6, 0x23, 0x93, 0x6c, 0xb3, 0x9f, 0x8a, - 0xe4, 0x02, 0x5b, 0x62, 0x0c, 0x8c, 0x47, 0x85, 0x30, 0x47, 0x5e, 0x44, 0xd3, 0x91, - 0xfd, 0x95, 0xe0, 0xc9, 0x50, 0x65, 0xf1, 0xfa, 0x6e, 0x2b, 0x48, 0xdd, 0xd2, 0x3e, - 0x42, 0xf4, 0x81, 0xdc, 0xb2, 0x4a, 0xcb, 0xdd, 0x61, 0xe0, 0x38, 0x36, 0x44, 0x06, - 0x3f, 0x93, 0x4f, 0x80, 0x9b, 0xff, 0xbb, 0x08, 0x1a, 0xfa, 0xaf, 0x28, 0x2d, 0x72, - 0x27, 0x79, 0x58, 0x79, 0x4e, 0xcb, 0x96, 0x45, 0x12, 0x41, 0xd4, 0x78, 0xd9, 0x32, - 0x26, 0xea, 0x59, 0xd9, 0x18, 0x92, 0xa3, 0xf8, 0x14, 0xf7, 0xc8, 0x67, 0xa5, 0xec, - 0x86, 0xc6, 0xa8, 0x7a, 0x25, 0xa9, 0x55, 0xb3, 0x49, 0x56, 0x36, 0x8e, 0x2b, 0x25, - 0x3b, 0xab, 0xe7, 0x64, 0x6c, 0xfd, 0x5e, 0x23, 0xb5, 0x30, 0x43, 0xad, 0xef, 0x6e, - 0x69, 0xed, 0xcf, 0x2a, 0xba, 0xf7, 0xc0, 0xbe, 0xf0, 0xe6, 0xd0, 0x40, 0xcf, 0xe5, - 0xc0, 0x5c, 0xa5, 0x60, 0xa1, 0x2c, 0xe6, 0xd3, 0xd8, 0xfa, 0x5c, 0xe2, 0x7e, 0xc5, - 0x88, 0x12, 0x19, 0x85, 0x93, 0x10, 0x74, 0x75, 0xad, 0x9c, 0x21, 0x8f, 0xcd, 0x22, - 0xf4, 0xb0, 0xae, 0xec, 0x9f, 0xfc, 0xde, 0x61, 0x03, 0x13, 0x4f, 0x1d, 0x1f, 0x54, - 0xfd, 0xec, 0x61, 0x82}; - - const uint32_t in_buf[] = { - 0x001c0001, 0x31303050, 0x31303043, 0x00000001, 0x00000800, 0x000007ac, 0xc1d80142, - 0x4c425346, 0x00010001, 0x00000001, 0x00000540, 0xa020005c, 0xa020005c, 0x00000040, - 0x00000000, 0x00000020, 0x00000104, 0x1c000100, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0xd4ac0000, 0x01180000, 0x61e02000, 0x80800004, 0x00001187, 0x00461e02, - 0x18780800, 0xe0200001, 0x80000461, 0x00118780, 0x461e0200, 0x78080000, 0x20000118, - 0x000461e0, 0x11878080, 0x1e020000, 0x08000046, 0x00011878, 0x0461e020, 0x87808000, - 0x02000011, 0x0000461e, 0x01187808, 0x61e02000, 0x80800004, 0x00001187, 0x00461e02, - 0x18780800, 0xe0200001, 0x80000461, 0x00118780, 0x461e0200, 0x78080000, 0x20000118, - 0x000461e0, 0x11878080, 0x1e020000, 0x08000046, 0x00011878, 0x0461e020, 0x87808000, - 0x02000011, 0x0000461e, 0x01187808, 0x61e02000, 0x80800004, 0x00001187, 0x00461e02, - 0x18780800, 0xe0200001, 0x80000461, 0x00118780, 0x461e0200, 0x78080000, 0x40080018, - 0x200061e0, 0x01878100, 0x1e040080, 0x10020006, 0x08001878, 0x0061e040, 0x87810020, - 0x04008001, 0x0200061e, 0x00187810, 0x61e04008, 0x81002000, 0x00800187, 0x00061e04, - 0x18781002, 0xe0400800, 0x00200061, 0x80018781, 0x061e0400, 0x78100200, 0x40080018, - 0x200061e0, 0x01878100, 0x1e040080, 0x10020006, 0x08001878, 0x0061e040, 0x87810020, - 0x04008001, 0x0200061e, 0x00187810, 0x61e04008, 0x81002000, 0x00800187, 0x00061e04, - 0x18781002, 0xe0400800, 0x00200061, 0x80018781, 0x061e0400, 0x78100200, 0x40080018, - 0x200061e0, 0x01878100, 0x1e040080, 0x10020006, 0x08001878, 0x0061e040, 0x87810020, - 0x04008001, 0x0200061e, 0x1e01f810, 0x00000000, 0x02000600, 0x00187810, 0x61e04008, - 0x81002000, 0x00800187, 0x00061e04, 0x18781002, 0xe0400800, 0x00200061, 0x80018781, - 0x061e0400, 0x78100200, 0x40080018, 0x200061e0, 0x01878100, 0x1e040080, 0x10020006, - 0x08001878, 0x0061e040, 0x87810020, 0x04008001, 0x0200061e, 0x00187810, 0x61e04008, - 0x81002000, 0x00800187, 0x00061e04, 0x18781002, 0xe0400800, 0x00200061, 0x80018781, - 0x061e0400, 0x78100200, 0x40080018, 0x200061e0, 0x01878100, 0x1e040080, 0x10020006, - 0x08001878, 0x0061e040, 0x87810020, 0x04008001, 0x0200061e, 0x00187810, 0x61e04008, - 0x81002000, 0x00800187, 0x00061e04, 0x18781002, 0xe0400800, 0x00200061, 0x80018781, - 0x461e0400, 0x78080000, 0x20000118, 0x000461e0, 0x11878080, 0x1e020000, 0x08000046, - 0x00011878, 0x0461e020, 0x87808000, 0x02000011, 0x0000461e, 0x01187808, 0x61e02000, - 0x80800004, 0x00001187, 0x00461e02, 0x18780800, 0xe0200001, 0x80000461, 0x00118780, - 0x461e0200, 0x78080000, 0x20000118, 0x000461e0, 0x11878080, 0x1e020000, 0x08000046, - 0x00011878, 0x0461e020, 0x87808000, 0x02000011, 0x0000461e, 0x01187808, 0x61e02000, - 0x80800004, 0x00001187, 0x00461e02, 0x18780800, 0xe0200001, 0x80000461, 0x00118780, - 0x461e0200, 0x78080000, 0x20000118, 0x000461e0, 0x11878080, 0x1e020000, 0x08000046, - 0x00011878, 0x0461e020, 0x87808000, 0x02000011, 0x000007fe, 0x00000000, 0xae36d32c, - 0x14303ef3, 0x4f34b247, 0xd0002090, 0x50000000, 0x04045010, 0x00003400, 0x14041400, - 0x0008c101, 0x230f0100, 0x3c040000, 0x1000008c, 0x000230f0, 0x08c3c040, 0x0f010000, - 0x04000023, 0x00008c3c, 0x0230f010, 0xc3c04000, 0x01000008, 0x0000230f, 0x008c3c04, - 0x30f01000, 0xc0400002, 0x000008c3, 0x00230f01, 0x8c3c0400, 0xf0100000, 0x40000230, - 0x0008c3c0, 0x230f0100, 0x3c040000, 0x1000008c, 0x000230f0, 0x08c3c040, 0x0f010000, - 0x04000023, 0x00008c3c, 0x0230f010, 0xc3c04000, 0x01000008, 0x0000230f, 0x008c3c04, - 0x30f01000, 0xc0400002, 0x000008c3, 0x00230f01, 0x8c3c0400, 0xf0100000, 0x40000230, - 0x0008c3c0, 0x230f0100, 0x3c040000, 0x1000008c, 0x000230f0, 0x08c3c040, 0x0f010000, - 0x04000023, 0x00008c3c, 0x0230f010, 0xc3c04000, 0x02004000, 0x0100030f, 0x000c3c08, - 0x30f02004, 0xc0801000, 0x004000c3, 0x00030f02, 0x0c3c0801, 0xf0200400, 0x80100030, - 0x4000c3c0, 0x030f0200, 0x3c080100, 0x2004000c, 0x100030f0, 0x00c3c080, 0x0f020040, - 0x08010003, 0x04000c3c, 0x0030f020, 0xc3c08010, 0x02004000, 0x0100030f, 0x000c3c08, - 0x30f02004, 0xc0801000, 0x004000c3, 0x00030f02, 0x0c3c0801, 0xf0200400, 0x80100030, - 0x4000c3c0, 0x030f0200, 0x3c080100, 0x2004000c, 0x100030f0, 0x00c3c080, 0x0f020040, - 0x08010003, 0x04000c3c, 0x0030f020, 0xc3c08010, 0x02004000, 0x0100030f, 0x000c3c08, - 0x30f02004, 0xc0801000, 0x004000c3, 0x00030f02, 0x0c3c0801, 0xf0200400, 0x80100030, - 0x00f00fc0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x37c2cac9, 0x8c32e765, 0xa15e1200, 0x25c486b2, 0x8734d7b4, - 0xfa26c29d, 0x2ff972ae, 0x0adebf22, 0xff6f29e6, 0x3c50778d, 0xfa02d8da, 0x78600d02, - 0xbca88565, 0x163ca9be, 0x73f0da10, 0x3ed20b1c, 0xcce46d11, 0x2a49278f, 0x12248db6, - 0xe50b6755, 0xa431193c, 0x6c308699, 0xe0c41dbf, 0x50c791fe, 0xd3f876b9, 0x7cf1df93, - 0x16941322, 0xaa1ead8f, 0xe3753f54, 0xc9bb7bcc, 0x79200bff, 0x7d76c2d4, 0xa7acc7f7, - 0xff567a99, 0xbfa4f5dc, 0x064238c8, 0xe9699208, 0xa6b5daf3, 0xa3a2ad30, 0x32bafe37, - 0x54e1dacb, 0xda540799, 0x95547760, 0x302cd650, 0x9d428238, 0x62bbdadd, 0xe531a353, - 0x282e8f7d, 0x973e7ba1, 0x0dd65973, 0x4ab77a02, 0x53ca63ae, 0x176010c2, 0x58bc890d, - 0x025f55f8, 0x0e1e579b, 0xe19cdb04, 0x4bb6caf5, 0xad438b2c, 0xeda4466b, 0x3cabf8dc, - 0x0785aca7, 0xd0350f09, 0x79cac3c1, 0x00010001, 0x00000000, 0x00000000, 0x00000000, - 0xef695fb9, 0xc4035b37, 0x561d8df3, 0x3db697ad, 0x97919c2a, 0xf29db8c2, 0xd4601533, - 0x59a15ea8, 0x96579a15, 0x9dae26fc, 0x77bfba25, 0x50e72678, 0xcff13b7b, 0x5d80dad3, - 0xc5afd1cd, 0x37b0691a, 0x8a3cde61, 0xfb352d13, 0x0587d910, 0x9323e6f0, 0x8a9fb36c, - 0x625b02e4, 0x85478c0c, 0x445e4730, 0x95fd91d3, 0x6550c9e0, 0x2b6efaf1, 0x3ed2dd48, - 0xdc81f442, 0xddcb4ab2, 0x3638e061, 0x933f0644, 0xff9b804f, 0xfa1a08bb, 0x722d28af, - 0x79587927, 0x4596cb4e, 0x78d44112, 0xea2632d9, 0x9218d959, 0xf714f8a3, 0xeca567c8, - 0x7aa8c686, 0xb355a925, 0x8e365649, 0xab3b252b, 0xfd6c64e7, 0x30b5235e, 0x6eefad43, - 0x2acfed69, 0xbec0f7ba, 0x40d0e6f0, 0x5cc0e5cf, 0x2ca160a5, 0xfad8d3e6, 0xc57ee25c, - 0x85191288, 0x75741093, 0x8f219cad, 0xb0f422cd, 0xfc9fecae, 0x130361de, 0x541f1d4f, - 0x8261ecfd, 0xa554c3b8, 0x00007ef9, 0x00000004, 0x00000000, 0xa558d2c0, 0x00007ef9, - 0xa557a038, 0x00007ef9, 0xa5576900, 0x00007ef9, 0x00000005, 0x00000000, 0xa558d2c0, - 0x00007ef9, 0xa557a040, 0x00007ef9, 0xa5576900, 0x00007ef9, 0xbfaab6b0, 0x00005cf3, - 0xa5576700}; + // const uint8_t pub_key[] = { + // 0xc9, 0xca, 0xc2, 0x37, 0x65, 0xe7, 0x32, 0x8c, 0x00, 0x12, 0x5e, 0xa1, 0xb2, 0x86, + // 0xc4, 0x25, 0xb4, 0xd7, 0x34, 0x87, 0x9d, 0xc2, 0x26, 0xfa, 0xae, 0x72, 0xf9, 0x2f, + // 0x22, 0xbf, 0xde, 0x0a, 0xe6, 0x29, 0x6f, 0xff, 0x8d, 0x77, 0x50, 0x3c, 0xda, 0xd8, + // 0x02, 0xfa, 0x02, 0x0d, 0x60, 0x78, 0x65, 0x85, 0xa8, 0xbc, 0xbe, 0xa9, 0x3c, 0x16, + // 0x10, 0xda, 0xf0, 0x73, 0x1c, 0x0b, 0xd2, 0x3e, 0x11, 0x6d, 0xe4, 0xcc, 0x8f, 0x27, + // 0x49, 0x2a, 0xb6, 0x8d, 0x24, 0x12, 0x55, 0x67, 0x0b, 0xe5, 0x3c, 0x19, 0x31, 0xa4, + // 0x99, 0x86, 0x30, 0x6c, 0xbf, 0x1d, 0xc4, 0xe0, 0xfe, 0x91, 0xc7, 0x50, 0xb9, 0x76, + // 0xf8, 0xd3, 0x93, 0xdf, 0xf1, 0x7c, 0x22, 0x13, 0x94, 0x16, 0x8f, 0xad, 0x1e, 0xaa, + // 0x54, 0x3f, 0x75, 0xe3, 0xcc, 0x7b, 0xbb, 0xc9, 0xff, 0x0b, 0x20, 0x79, 0xd4, 0xc2, + // 0x76, 0x7d, 0xf7, 0xc7, 0xac, 0xa7, 0x99, 0x7a, 0x56, 0xff, 0xdc, 0xf5, 0xa4, 0xbf, + // 0xc8, 0x38, 0x42, 0x06, 0x08, 0x92, 0x69, 0xe9, 0xf3, 0xda, 0xb5, 0xa6, 0x30, 0xad, + // 0xa2, 0xa3, 0x37, 0xfe, 0xba, 0x32, 0xcb, 0xda, 0xe1, 0x54, 0x99, 0x07, 0x54, 0xda, + // 0x60, 0x77, 0x54, 0x95, 0x50, 0xd6, 0x2c, 0x30, 0x38, 0x82, 0x42, 0x9d, 0xdd, 0xda, + // 0xbb, 0x62, 0x53, 0xa3, 0x31, 0xe5, 0x7d, 0x8f, 0x2e, 0x28, 0xa1, 0x7b, 0x3e, 0x97, + // 0x73, 0x59, 0xd6, 0x0d, 0x02, 0x7a, 0xb7, 0x4a, 0xae, 0x63, 0xca, 0x53, 0xc2, 0x10, + // 0x60, 0x17, 0x0d, 0x89, 0xbc, 0x58, 0xf8, 0x55, 0x5f, 0x02, 0x9b, 0x57, 0x1e, 0x0e, + // 0x04, 0xdb, 0x9c, 0xe1, 0xf5, 0xca, 0xb6, 0x4b, 0x2c, 0x8b, 0x43, 0xad, 0x6b, 0x46, + // 0xa4, 0xed, 0xdc, 0xf8, 0xab, 0x3c, 0xa7, 0xac, 0x85, 0x07, 0x09, 0x0f, 0x35, 0xd0, + // 0xc1, 0xc3, 0xca, 0x79, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + + // const uint8_t sig[] = { + // 0x22, 0xb0, 0x83, 0xbb, 0xca, 0xce, 0xeb, 0x95, 0x89, 0x78, 0xfa, 0x65, 0x12, 0xc0, + // 0x92, 0x30, 0x0d, 0x0e, 0xcf, 0x9f, 0xda, 0xf5, 0xb9, 0x88, 0xae, 0x4a, 0x07, 0xde, + // 0x7f, 0xfe, 0x6e, 0xe0, 0xe7, 0xac, 0xae, 0x2c, 0xae, 0xdf, 0x3a, 0xa7, 0xdb, 0x20, + // 0x78, 0xec, 0xa8, 0x63, 0xf0, 0xad, 0x84, 0x5d, 0xbf, 0xe8, 0xc6, 0xe2, 0xdf, 0xd9, + // 0x76, 0x50, 0x6e, 0x74, 0x56, 0x4a, 0x85, 0x45, 0xd7, 0xc7, 0xa7, 0xda, 0x9d, 0x9c, + // 0xb7, 0x63, 0x4f, 0x69, 0x64, 0xb1, 0xb0, 0x5a, 0xfa, 0x69, 0xf7, 0x14, 0xec, 0xc9, + // 0x6f, 0xc9, 0xea, 0xd6, 0xf2, 0xa0, 0x3e, 0x2b, 0x77, 0x90, 0x05, 0xfd, 0x18, 0xb1, + // 0xdf, 0x61, 0x1b, 0x95, 0xf2, 0xf1, 0x79, 0x7f, 0xc7, 0xf1, 0x14, 0x96, 0x6e, 0xd1, + // 0x5a, 0xa3, 0x8e, 0xb6, 0x3c, 0x83, 0xad, 0xd1, 0x5a, 0x95, 0xed, 0x8b, 0x4b, 0x7f, + // 0x98, 0xbb, 0x05, 0x4c, 0x3c, 0x7f, 0x8b, 0x44, 0xa5, 0xfd, 0xe4, 0x91, 0x05, 0xec, + // 0x64, 0xae, 0x44, 0xa8, 0xcc, 0x6a, 0x2e, 0x39, 0x21, 0x65, 0xe8, 0x14, 0x46, 0xbd, + // 0x7f, 0x3f, 0x46, 0xbb, 0x42, 0x45, 0x1f, 0xb2, 0x7f, 0x91, 0x90, 0x04, 0x67, 0x5a, + // 0xee, 0x8f, 0xcb, 0x24, 0x0d, 0xc3, 0x20, 0xf7, 0xbb, 0x76, 0x72, 0x37, 0xff, 0x92, + // 0x22, 0x78, 0xf0, 0xdd, 0x14, 0x5d, 0x27, 0x6e, 0xc9, 0x26, 0x9a, 0x1b, 0xb3, 0x6d, + // 0xcf, 0xa1, 0x01, 0x33, 0xdc, 0x0f, 0x0b, 0xc7, 0x4d, 0xe8, 0x1f, 0x23, 0xbd, 0x3e, + // 0xd8, 0xb0, 0x4a, 0x37, 0xf5, 0x0a, 0x5f, 0x43, 0x99, 0x3e, 0x97, 0xa2, 0xaa, 0x25, + // 0xa7, 0xc8, 0xee, 0xcc, 0xce, 0x69, 0x41, 0x2b, 0xbc, 0x65, 0xa0, 0x67, 0xe6, 0x52, + // 0x71, 0x64, 0xea, 0x19, 0xb5, 0x72, 0x54, 0xa1, 0xff, 0x81, 0x39, 0x6e, 0x1d, 0xee, + // 0x34, 0x40, 0x6c, 0x16}; + + uint32_t pub_key_padding = 12; + + struct rs_bop_header *bop_hdr = (struct rs_bop_header *)bop_image_addr; + + uint8_t *pub_key = (uint8_t *)bop_image_addr + bop_hdr->offset_to_binary + + bop_hdr->binary_len + bop_hdr->iv_len; + uint8_t *sig = + (uint8_t *)pub_key + bop_hdr->pub_key_len + pub_key_padding; + + printf("Bop_Binary_1st_Word:0x%08x\n", *(uint32_t*)bop_hdr); lvSignCtx.app_sessn_state = NULL; lvSignCtx.device = pufs; @@ -771,15 +1623,16 @@ void pufs_rsa2048_verify_test(const struct device *pufs) lvSignCtx.ops.signing_mode = CRYPTO_SIGN_VERIFY; lvSignPkt.ctx = &lvSignCtx; - lvSignPkt.in_buf = (uint8_t *)in_buf; - lvSignPkt.in_len = sizeof(in_buf); + lvSignPkt.in_buf = (uint8_t *)bop_hdr; + lvSignPkt.in_len = bop_hdr->binary_len+sizeof(struct rs_bop_header)+272; + lvSignPkt.next = NULL; lvStatus = sign_begin_session(pufs, &lvSignCtx, CRYPTO_SIGN_ALGO_RSA2048); if (lvStatus != 0) { - printf("%s sign_begin_session Failed! %s\n", ATTR_ERR, ATTR_RST); + printf("\n%ssign_begin_session Failed! %s\n", ATTR_ERR, ATTR_RST); } else { - printf("%s sign_begin_session Success! %s\n", ATTR_INF, ATTR_RST); - printf("%s in_buf_addr:0x%08x in_buf_len:%d bytes %s\n", ATTR_INF, + printf("%ssign_begin_session Success! %s\n", ATTR_INF, ATTR_RST); + printf("\n%sin_buf_addr:0x%08x in_buf_len:%d bytes %s\n", ATTR_INF, (uint32_t)lvSignPkt.in_buf, lvSignPkt.in_len, ATTR_RST); lvStatus = sign_op_handler(&lvSignCtx, &lvSignPkt); } @@ -812,6 +1665,7 @@ int main(void) scu_get_irq_reg_val(IRQ_ID_SYSTEM_DMA)); soc_get_id(&chip_id, &vendor_id); + scu_assert_reset(); int errorcode = 0; struct sensor_value lvTemp = {0}, lvVolt = {0}; @@ -824,16 +1678,15 @@ int main(void) const struct device *pufs_otp = DEVICE_DT_GET(DT_NODELABEL(pufs_otp)); if ((pufs == NULL) || (!device_is_ready(pufs))) { - printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, - ATTR_RST); + printf("%s pufs has status disabled or driver is not initialized...%s\n",\ + ATTR_ERR, ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); - pufs_rsa2048_verify_test(pufs); - while (true) - ; // TODO Remove while pufs_decryption_test(pufs); pufs_hash_test(pufs); pufs_hash_sg_test(pufs); + pufs_rsa2048_verify_test(pufs); + while (true); // TODO Remove while } if ((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { diff --git a/soc/rapidsilicon/virgo/scu.c b/soc/rapidsilicon/virgo/scu.c index 871a3525aff1c..55580486222ae 100644 --- a/soc/rapidsilicon/virgo/scu.c +++ b/soc/rapidsilicon/virgo/scu.c @@ -8,7 +8,8 @@ typedef struct { volatile uint32_t idrev; /* 0x00 */ - volatile uint32_t reserved[10]; /* 0x04 - 0x28 */ + volatile uint32_t sw_rst_control; /* 0x04 */ + volatile uint32_t reserved[9]; /* 0x08 - 0x28 */ volatile uint32_t irq_map_mask[32]; /* 0x2C - 0xA8 */ } scu_registers_t; @@ -19,6 +20,15 @@ typedef struct { static volatile scu_registers_t *s_scu_regs = NULL; #endif +void scu_assert_reset(void) +{ + uint32_t reset_flags = + (VIRGO_SCU_SW_RST_CTRL_MSK_BUS | VIRGO_SCU_SW_RST_CTRL_MSK_PER | + VIRGO_SCU_SW_RST_CTRL_MSK_FPGA0 | VIRGO_SCU_SW_RST_CTRL_MSK_FPGA1 | + VIRGO_SCU_SW_RST_CTRL_MSK_DMA); + s_scu_regs->sw_rst_control |= reset_flags; +} + void soc_get_id(uint8_t *chip_id, uint8_t *vendor_id) { *chip_id = ((s_scu_regs->idrev & SCU_CHIP_ID_MASK) >> SCU_CHIP_ID_OFFSET); diff --git a/soc/rapidsilicon/virgo/scu.h b/soc/rapidsilicon/virgo/scu.h index 13b538b6dd3c2..c8357d2c2b98c 100644 --- a/soc/rapidsilicon/virgo/scu.h +++ b/soc/rapidsilicon/virgo/scu.h @@ -23,6 +23,16 @@ #define SCU_IRQ_MAP_TO_FPGA 0x4 #define SCU_IRQ_MAP_MASK 0x7 +/// Software reset control +enum virgo_scu_sw_rst_ctrl_msk { + VIRGO_SCU_SW_RST_CTRL_MSK_SYSTEM = (0x1UL << 0), + VIRGO_SCU_SW_RST_CTRL_MSK_BUS = (0x1UL << 1), + VIRGO_SCU_SW_RST_CTRL_MSK_PER = (0x1UL << 4), + VIRGO_SCU_SW_RST_CTRL_MSK_FPGA0 = (0x1UL << 5), + VIRGO_SCU_SW_RST_CTRL_MSK_FPGA1 = (0x1UL << 6), + VIRGO_SCU_SW_RST_CTRL_MSK_DMA = (0x1UL << 10), +}; + /********************************* * The following table is aligned * with respect to the scu map and @@ -73,6 +83,8 @@ void scu_irq_enable(enum map_mask_control_irq_id IRQn); void scu_irq_disable(enum map_mask_control_irq_id IRQn); uint32_t scu_get_irq_reg_val(enum map_mask_control_irq_id IRQn); +void scu_assert_reset(void); + #define SCU_CHIP_ID_OFFSET 16 #define SCU_CHIP_ID_MASK 0x00FF0000 From a07d024f5c0b509b54af17b28ea62ee7353c66d1 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Fri, 18 Oct 2024 10:03:08 +0500 Subject: [PATCH 48/58] defconfig update for the virgo_proto board --- .../virgo_proto/virgo_proto_defconfig | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/boards/rapidsilicon/virgo_proto/virgo_proto_defconfig b/boards/rapidsilicon/virgo_proto/virgo_proto_defconfig index f43104211eb1c..fa0b85cc06913 100644 --- a/boards/rapidsilicon/virgo_proto/virgo_proto_defconfig +++ b/boards/rapidsilicon/virgo_proto/virgo_proto_defconfig @@ -34,4 +34,30 @@ CONFIG_HWINFO_ANDES=n # CONFIG_SOC_ANDES_V5_EXECIT=y # Sys Clock HW Cycles for Virgo Proto used by mtimer -CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=13333333 \ No newline at end of file +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=13333333 + +# Enabling the SPI Peripheral +CONFIG_SPI=y + +# Enabling the Crypto Peripheral +CONFIG_CRYPTO=y +CONFIG_PUFCC_SECURITY=y +CONFIG_CRYPTO_PUF_SECURITY=y +CONFIG_CRYPTO_PUF_SECURITY_OTP=y + +# Enabling the DMA Peripheral +CONFIG_DMA=y +CONFIG_DMA_ANDES_ATCDMAC100=y + +# Enabling the SPI and Flash Peripheral +CONFIG_FLASH=y +CONFIG_SPI_NOR_SFDP_DEVICETREE=y +CONFIG_SPI_ANDES_ATCSPI200=y + +# Enabling the Counter Peripheral +CONFIG_COUNTER=y +CONFIG_COUNTER_ANDES_ATCPIT100=y + +# Enabling the Sensor Peripheral +CONFIG_SENSOR=y +CONFIG_DTI_PVT=y From 6d3ca3672168c18e401b6c13b07dd4cc6c50c18e Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 21 Oct 2024 18:48:11 +0500 Subject: [PATCH 49/58] RSA2048 signature verification in progress, modulus copy success with word transaction --- drivers/crypto/pufcc.c | 48 ++++++++++++++++------------------ samples/hello_world/src/main.c | 43 ------------------------------ 2 files changed, 22 insertions(+), 69 deletions(-) diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 576afcca5e199..869526876de4c 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -6,6 +6,7 @@ #include #include #include "crypto_pufs.h" + #include static volatile bool s_Asynch_Operation = false; void pufcc_set_asynch_ops_flag(bool Val) {s_Asynch_Operation = Val;} bool pufcc_get_asynch_ops_flag(void) {return s_Asynch_Operation;} @@ -509,8 +510,7 @@ enum pufcc_status pufcc_rsa2048_sign_verify( uint8_t dec_msg[PUFCC_RSA_2048_LEN]; // Configure signature scheme temp32 = 0; - printf("%s(%d) msg-1st-word:0x%08x\r\r\n", __func__, __LINE__, \ - *(uint32_t*)msg_addr->read_addr); + struct pufcc_pkc_ecp_ec_reg *ecp_ec_reg = (struct pufcc_pkc_ecp_ec_reg *)&temp32; ecp_ec_reg->field = PUFCC_RSA_2048; @@ -525,34 +525,32 @@ enum pufcc_status pufcc_rsa2048_sign_verify( // Reverse public key modulus reverse(pufcc_buffer, pub_key->n, PUFCC_RSA_2048_LEN); // .... Reversed Public key print TODO - // printf("%s(%d) Reversed Public Key\r\n", __func__, __LINE__); - // for(int i = 0; i < 256; i++) { - // printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); - // } printf("\r\n"); - //////////////////////////// - - // Write reversed public key modulus to ECP data field at proper offset - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET, - pufcc_buffer, PUFCC_RSA_2048_LEN); + printf("%s(%d) original Reversed Public Key\r\n", __func__, __LINE__); + for(int i = 0; i < 256; i++) { + printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); + } printf("\r\n"); + uint32_t *ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET/4; + uint32_t *buf_ptr = (uint32_t*)pufcc_buffer; + // memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET, + // pufcc_buffer, PUFCC_RSA_2048_LEN); + printf("%s(%d) manual Copy Reversed Public Key at %p\r\n", __func__, __LINE__, ptr); + for(int i = 0; i < PUFCC_RSA_2048_LEN/4; i++) { + *ptr++ = *buf_ptr++; + // printf("%p 0x%08x =? 0x%08x\r\n", (ptr-1), *(buf_ptr-1), *(ptr-1)); + } //printf("\r\n"); + // .... Reversed Public key print TODO + uint8_t *_8ptr = (uint8_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET; + printf("%s(%d) manual Copy Read Reversed Public Key at %p\r\n", __func__, __LINE__, _8ptr); + for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { + printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); + } printf("\r\n"); + //////////////////////////// // Write public key exponent to ecp_e_short register REG_WRITE_32(&pkc_regs->ecp_e_short, &pub_key->e); - printf("%s(%d) pubKey_expo:0x%08x\r\n", __func__,__LINE__, pub_key->e); - // .... Signature print TODO - printf("%s(%d) Signature\r\n", __func__, __LINE__); - for(int i = 0; i < 256; i++) { - printf("0x%02x%s", sig[i], (i+1)%16==0?"\r\n":","); - } printf("\r\n"); - //////////////////////////// // Reverse signature reverse(pufcc_buffer, sig, PUFCC_RSA_2048_LEN); - // .... Reversed Signature print TODO - // printf("%s(%d) Reversed Signature\r\n", __func__, __LINE__); - // for(int i = 0; i < 256; i++) { - // printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); - // } printf("\r\n"); - //////////////////////////// // Write reversed signature to ECP data field at proper offset memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, @@ -561,7 +559,6 @@ enum pufcc_status pufcc_rsa2048_sign_verify( // Write microprogram for RSA2048 memcpy((void *)&pkc_regs->ecp_mac, rsa_2048_mprog, sizeof(rsa_2048_mprog)); - // Clear and disable PKC interrupt temp32 = 0; struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; intrpt_reg->intrpt_st = 1; @@ -576,7 +573,6 @@ enum pufcc_status pufcc_rsa2048_sign_verify( status = busy_wait(&pkc_regs->status, PUFCC_PKC_ERROR_MASK); if (status != PUFCC_SUCCESS) { - printf("%s(%d) ecp_err_code:0x%x\r\n", __func__,__LINE__, pkc_regs->ecp_err_code); return status; } diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index d5cabfb3803fa..29c093a3f53a6 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -1559,49 +1559,6 @@ void pufs_rsa2048_verify_test(const struct device *pufs) struct sign_ctx lvSignCtx = {0}; struct sign_pkt lvSignPkt = {0}; - // const uint8_t pub_key[] = { - // 0xc9, 0xca, 0xc2, 0x37, 0x65, 0xe7, 0x32, 0x8c, 0x00, 0x12, 0x5e, 0xa1, 0xb2, 0x86, - // 0xc4, 0x25, 0xb4, 0xd7, 0x34, 0x87, 0x9d, 0xc2, 0x26, 0xfa, 0xae, 0x72, 0xf9, 0x2f, - // 0x22, 0xbf, 0xde, 0x0a, 0xe6, 0x29, 0x6f, 0xff, 0x8d, 0x77, 0x50, 0x3c, 0xda, 0xd8, - // 0x02, 0xfa, 0x02, 0x0d, 0x60, 0x78, 0x65, 0x85, 0xa8, 0xbc, 0xbe, 0xa9, 0x3c, 0x16, - // 0x10, 0xda, 0xf0, 0x73, 0x1c, 0x0b, 0xd2, 0x3e, 0x11, 0x6d, 0xe4, 0xcc, 0x8f, 0x27, - // 0x49, 0x2a, 0xb6, 0x8d, 0x24, 0x12, 0x55, 0x67, 0x0b, 0xe5, 0x3c, 0x19, 0x31, 0xa4, - // 0x99, 0x86, 0x30, 0x6c, 0xbf, 0x1d, 0xc4, 0xe0, 0xfe, 0x91, 0xc7, 0x50, 0xb9, 0x76, - // 0xf8, 0xd3, 0x93, 0xdf, 0xf1, 0x7c, 0x22, 0x13, 0x94, 0x16, 0x8f, 0xad, 0x1e, 0xaa, - // 0x54, 0x3f, 0x75, 0xe3, 0xcc, 0x7b, 0xbb, 0xc9, 0xff, 0x0b, 0x20, 0x79, 0xd4, 0xc2, - // 0x76, 0x7d, 0xf7, 0xc7, 0xac, 0xa7, 0x99, 0x7a, 0x56, 0xff, 0xdc, 0xf5, 0xa4, 0xbf, - // 0xc8, 0x38, 0x42, 0x06, 0x08, 0x92, 0x69, 0xe9, 0xf3, 0xda, 0xb5, 0xa6, 0x30, 0xad, - // 0xa2, 0xa3, 0x37, 0xfe, 0xba, 0x32, 0xcb, 0xda, 0xe1, 0x54, 0x99, 0x07, 0x54, 0xda, - // 0x60, 0x77, 0x54, 0x95, 0x50, 0xd6, 0x2c, 0x30, 0x38, 0x82, 0x42, 0x9d, 0xdd, 0xda, - // 0xbb, 0x62, 0x53, 0xa3, 0x31, 0xe5, 0x7d, 0x8f, 0x2e, 0x28, 0xa1, 0x7b, 0x3e, 0x97, - // 0x73, 0x59, 0xd6, 0x0d, 0x02, 0x7a, 0xb7, 0x4a, 0xae, 0x63, 0xca, 0x53, 0xc2, 0x10, - // 0x60, 0x17, 0x0d, 0x89, 0xbc, 0x58, 0xf8, 0x55, 0x5f, 0x02, 0x9b, 0x57, 0x1e, 0x0e, - // 0x04, 0xdb, 0x9c, 0xe1, 0xf5, 0xca, 0xb6, 0x4b, 0x2c, 0x8b, 0x43, 0xad, 0x6b, 0x46, - // 0xa4, 0xed, 0xdc, 0xf8, 0xab, 0x3c, 0xa7, 0xac, 0x85, 0x07, 0x09, 0x0f, 0x35, 0xd0, - // 0xc1, 0xc3, 0xca, 0x79, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - - // const uint8_t sig[] = { - // 0x22, 0xb0, 0x83, 0xbb, 0xca, 0xce, 0xeb, 0x95, 0x89, 0x78, 0xfa, 0x65, 0x12, 0xc0, - // 0x92, 0x30, 0x0d, 0x0e, 0xcf, 0x9f, 0xda, 0xf5, 0xb9, 0x88, 0xae, 0x4a, 0x07, 0xde, - // 0x7f, 0xfe, 0x6e, 0xe0, 0xe7, 0xac, 0xae, 0x2c, 0xae, 0xdf, 0x3a, 0xa7, 0xdb, 0x20, - // 0x78, 0xec, 0xa8, 0x63, 0xf0, 0xad, 0x84, 0x5d, 0xbf, 0xe8, 0xc6, 0xe2, 0xdf, 0xd9, - // 0x76, 0x50, 0x6e, 0x74, 0x56, 0x4a, 0x85, 0x45, 0xd7, 0xc7, 0xa7, 0xda, 0x9d, 0x9c, - // 0xb7, 0x63, 0x4f, 0x69, 0x64, 0xb1, 0xb0, 0x5a, 0xfa, 0x69, 0xf7, 0x14, 0xec, 0xc9, - // 0x6f, 0xc9, 0xea, 0xd6, 0xf2, 0xa0, 0x3e, 0x2b, 0x77, 0x90, 0x05, 0xfd, 0x18, 0xb1, - // 0xdf, 0x61, 0x1b, 0x95, 0xf2, 0xf1, 0x79, 0x7f, 0xc7, 0xf1, 0x14, 0x96, 0x6e, 0xd1, - // 0x5a, 0xa3, 0x8e, 0xb6, 0x3c, 0x83, 0xad, 0xd1, 0x5a, 0x95, 0xed, 0x8b, 0x4b, 0x7f, - // 0x98, 0xbb, 0x05, 0x4c, 0x3c, 0x7f, 0x8b, 0x44, 0xa5, 0xfd, 0xe4, 0x91, 0x05, 0xec, - // 0x64, 0xae, 0x44, 0xa8, 0xcc, 0x6a, 0x2e, 0x39, 0x21, 0x65, 0xe8, 0x14, 0x46, 0xbd, - // 0x7f, 0x3f, 0x46, 0xbb, 0x42, 0x45, 0x1f, 0xb2, 0x7f, 0x91, 0x90, 0x04, 0x67, 0x5a, - // 0xee, 0x8f, 0xcb, 0x24, 0x0d, 0xc3, 0x20, 0xf7, 0xbb, 0x76, 0x72, 0x37, 0xff, 0x92, - // 0x22, 0x78, 0xf0, 0xdd, 0x14, 0x5d, 0x27, 0x6e, 0xc9, 0x26, 0x9a, 0x1b, 0xb3, 0x6d, - // 0xcf, 0xa1, 0x01, 0x33, 0xdc, 0x0f, 0x0b, 0xc7, 0x4d, 0xe8, 0x1f, 0x23, 0xbd, 0x3e, - // 0xd8, 0xb0, 0x4a, 0x37, 0xf5, 0x0a, 0x5f, 0x43, 0x99, 0x3e, 0x97, 0xa2, 0xaa, 0x25, - // 0xa7, 0xc8, 0xee, 0xcc, 0xce, 0x69, 0x41, 0x2b, 0xbc, 0x65, 0xa0, 0x67, 0xe6, 0x52, - // 0x71, 0x64, 0xea, 0x19, 0xb5, 0x72, 0x54, 0xa1, 0xff, 0x81, 0x39, 0x6e, 0x1d, 0xee, - // 0x34, 0x40, 0x6c, 0x16}; - uint32_t pub_key_padding = 12; struct rs_bop_header *bop_hdr = (struct rs_bop_header *)bop_image_addr; From 14a06437b085c148b63294e0fd018b4b39ee8c0f Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 21 Oct 2024 23:18:22 +0500 Subject: [PATCH 50/58] RSA2048 signature verification success... Cleanup with RS_RTOS_PORT Usage remaining --- drivers/crypto/pufcc.c | 50 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 869526876de4c..bdbac98ad5f6b 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -521,19 +521,20 @@ enum pufcc_status pufcc_rsa2048_sign_verify( for(int i = 0; i < 256; i++) { printf("0x%02x%s", pub_key->n[i], (i+1)%16==0?"\r\n":","); } printf("\r\n"); - //////////////////////////// // Reverse public key modulus reverse(pufcc_buffer, pub_key->n, PUFCC_RSA_2048_LEN); + //////////////////////////// // .... Reversed Public key print TODO printf("%s(%d) original Reversed Public Key\r\n", __func__, __LINE__); for(int i = 0; i < 256; i++) { printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); } printf("\r\n"); - uint32_t *ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET/4; - uint32_t *buf_ptr = (uint32_t*)pufcc_buffer; + //////////////////////////// // memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET, // pufcc_buffer, PUFCC_RSA_2048_LEN); - printf("%s(%d) manual Copy Reversed Public Key at %p\r\n", __func__, __LINE__, ptr); + //////////////////////////// + uint32_t *ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET/4; + uint32_t *buf_ptr = (uint32_t*)pufcc_buffer; for(int i = 0; i < PUFCC_RSA_2048_LEN/4; i++) { *ptr++ = *buf_ptr++; // printf("%p 0x%08x =? 0x%08x\r\n", (ptr-1), *(buf_ptr-1), *(ptr-1)); @@ -551,14 +552,45 @@ enum pufcc_status pufcc_rsa2048_sign_verify( // Reverse signature reverse(pufcc_buffer, sig, PUFCC_RSA_2048_LEN); - + //////////////////////////// + // .... Reversed Signature print TODO + printf("%s(%d) original Reversed Signature\r\n", __func__, __LINE__); + for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { + printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); + } printf("\r\n"); + //////////////////////////// // Write reversed signature to ECP data field at proper offset - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, - pufcc_buffer, PUFCC_RSA_2048_LEN); + // memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, + // pufcc_buffer, PUFCC_RSA_2048_LEN); + //////////////////////////// + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + printf("%s(%d) manual Copy Reversed Signature at %p\r\n", __func__, __LINE__, ptr); + for(int i = 0; i < PUFCC_RSA_2048_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + _8ptr = (uint8_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET; + printf("%s(%d) memcpy Read Reversed Signature at %p\r\n", __func__, __LINE__, _8ptr); + for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { + printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); + } printf("\r\n"); + //////////////////////////// // Write microprogram for RSA2048 - memcpy((void *)&pkc_regs->ecp_mac, rsa_2048_mprog, sizeof(rsa_2048_mprog)); - + // memcpy((void *)&pkc_regs->ecp_mac, rsa_2048_mprog, sizeof(rsa_2048_mprog)); + //////////////////////////// + ptr = (uint32_t*)&pkc_regs->ecp_mac; + buf_ptr = (uint32_t*)rsa_2048_mprog; + printf("%s(%d) manual Copy Reversed Microprogram at %p\r\n", __func__, __LINE__, ptr); + for(int i = 0; i < sizeof(rsa_2048_mprog)/4; i++) { + *ptr++ = *buf_ptr++; + } + _8ptr = (uint8_t*)&pkc_regs->ecp_mac; + printf("%s(%d) Manual copy Read Microprogram %p\r\n", __func__, __LINE__, _8ptr); + for(int i = 0; i < sizeof(rsa_2048_mprog); i++) { + printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); + } printf("\r\n"); + //////////////////////////// temp32 = 0; struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; intrpt_reg->intrpt_st = 1; From f2067c586d227d77d2e8a138d7133e208eea3ad3 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 21 Oct 2024 23:19:51 +0500 Subject: [PATCH 51/58] RSA2048 signature verification success... Cleanup with RS_RTOS_PORT Usage remaining --- samples/hello_world/src/main.c | 441 --------------------------------- 1 file changed, 441 deletions(-) diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 29c093a3f53a6..0f7cce5d23381 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -636,446 +636,6 @@ void pufs_decryption_test(const struct device *pufs) } } -// const uint32_t in_buf[] = { -// 0x4c425346, 0x00010001, 0x00000001, 0x00002e80, 0xa020005c, 0xa020005c, 0x00000040, -// 0x00000000, 0x00000020, 0x00000104, 0x3c000100, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0xa54a0000, 0xa02000b7, 0x06408067, 0x30405073, 0x34405073, 0x41014081, -// 0x42014181, 0x43014281, 0x44014381, 0x46814481, 0x47814701, 0x48814801, 0x49814901, -// 0x4a814a01, 0x4b814b01, 0x4c814c01, 0x4d814d01, 0x4e814e01, 0x4f814f01, 0x00100197, -// 0x75c18193, 0xf14023f3, 0x00000293, 0x0072f463, 0x01d0106f, 0x0018128b, 0x62858116, -// 0x80028293, 0x025382b3, 0x40510133, 0x006f840a, 0x12ef0040, 0x25731290, 0x10eff140, -// 0xc91576e0, 0x8c1f978b, 0x8b9f960b, 0x40c78633, 0x950b4581, 0x10ef8b9f, 0x960b0530, -// 0x978b801f, 0x35b78b9f, 0x8633a020, 0x859340c7, 0x950bde85, 0x10ef801f, 0x27b77c60, -// 0x8793a020, 0x90737fc7, 0x07938007, 0xa0732000, 0x07b77d07, 0x8793a020, 0x90734037, -// 0x84303057, 0x20078793, 0x30779073, 0xfc2027f3, 0x01c7f85b, 0xa02007b7, 0x30178793, -// 0x7ec79073, 0xe2000737, 0x00074783, 0xf7938420, 0xe7930817, 0x05130047, 0x0023c085, -// 0x00ef00f7, 0x10ef6890, 0xe51944a0, 0x05138420, 0x00efc245, 0xa0016790, 0x05138420, -// 0x00efc405, 0xbfd566d0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, -// 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, -// 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, -// 0xa0201528, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa020157c, 0xa0200472, -// 0xa020159a, 0xa0200504, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, -// 0xa02005b6, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, -// 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, -// 0xa0200472, 0xa0200472, 0xa0200472, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0xc006711d, 0xc416c212, 0xc81ec61a, 0xcc2eca2a, -// 0xd036ce32, 0xd43ed23a, 0xd846d642, 0xdc76da72, 0xc0fede7a, 0x7ee8d073, 0x7ef95073, -// 0x7ed090f3, 0x42a24212, 0x43c24332, 0x45e24552, 0x56824672, 0x57a25712, 0x58c25832, -// 0x5ee25e52, 0x4f865f72, 0x70734096, 0x90733004, 0x40a63420, 0x34109073, 0x345020f3, -// 0xfc0094e3, 0x61254082, 0x30200073, 0x00000013, 0x00000013, 0x00000013, 0x00000013, -// 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, -// 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, -// 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, -// 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, -// 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0xc0067119, 0xc416c212, 0xc81ec61a, -// 0xcc2eca2a, 0xd036ce32, 0xd43ed23a, 0xd846d642, 0xdc76da72, 0xc0fede7a, 0x341022f3, -// 0x30002373, 0xc49ac296, 0x34202573, 0x10ef858a, 0x77f34220, 0x42963004, 0x90734326, -// 0x10733412, 0x40823003, 0x42a24212, 0x43c24332, 0x45e24552, 0x56824672, 0x57a25712, -// 0x58c25832, 0x5ee25e52, 0x4f865f72, 0x00736109, 0x80823020, 0xff950793, 0x07db8030, -// 0x67410cf7, 0xc3980705, 0xe20017b7, 0x00178713, 0x0ca7075b, 0x078d4685, 0xe2000837, -// 0x00d70023, 0x00251593, 0x00084683, 0x0ca7855b, 0x00054703, 0x1016a6db, 0x00d71733, -// 0x57334621, 0x478940d7, 0x96b38020, 0x8f5500d7, 0x00238810, 0x470300e5, 0x275b0008, -// 0x5f5b1017, 0x47830087, 0x07330005, 0xd7b340e6, 0x97b340e7, 0xe79300e7, 0x8c140017, -// 0x00f50023, 0xe20017b7, 0x97ae0789, 0x77138004, 0x80230fe7, 0x808200e7, 0x970b1101, -// 0xca4a81df, 0xc25ac652, 0xce06c05e, 0xc84ecc26, 0x4318c456, 0x81df9b0b, 0x03072a83, -// 0x9a0b4901, 0x4b8581df, 0x01090993, 0x00890493, 0x013b99b3, 0x012b97b3, 0x009b94b3, -// 0x0159f9b3, 0x9b638cdd, 0xf7b30009, 0x567d00fa, 0x4609e391, 0x0154f7b3, 0xa801e399, -// 0x27834601, 0x2503068b, 0x85ca048b, 0x27839782, 0xf4b3000a, 0xe4b30154, 0x09050134, -// 0x0b11db84, 0xba79685b, 0x44e240f2, 0x49c24952, 0x4aa24a32, 0x4b824b12, 0x80826105, -// 0x07b7cd99, 0x5bd8a042, 0x765b4581, 0x47030057, 0x45850005, 0x4505d398, 0x8d4d05c2, -// 0x45018082, 0x978bbfe5, 0x4394805f, 0x42d875c1, 0x15f94a90, 0x80148f6d, 0xc2d89a79, -// 0x00c03633, 0x4b884bd8, 0x40c00633, 0x87024581, 0x3fa012ef, 0x77938a3e, 0x8aaa0038, -// 0x89b28b2e, 0x893a8bb6, 0x84b28c42, 0x84bae785, 0x40e60cb3, 0x56fda031, 0x801085da, -// 0x9a820485, 0x009c8633, 0xff44e9e3, 0x64634481, 0x04b3012a, 0x94ce412a, 0x852694ca, -// 0x41248633, 0x00091c63, 0x001c785b, 0x413484b3, 0x00998533, 0x0144ed63, 0x3d60106f, -// 0x87b3197d, 0xc503012b, 0x56fd0007, 0x9a8285da, 0x862abfc9, 0x85da56fd, 0x04858010, -// 0xbfd99a82, 0x3a2012ef, 0x48528342, 0x47c28e3e, 0x4418735b, 0x00187e93, 0x8963cb91, -// 0x1663000e, 0x7f13000e, 0x036300c8, 0x17fd000f, 0x03000f13, 0x59dba801, 0x8fb30007, -// 0x070500e6, 0x01ef8023, 0xff1769e3, 0x0f934f7d, 0x86630300, 0x7463000e, 0x7c6300f7, -// 0x755b02ef, 0x7f5b0648, 0xcf0d42a8, 0x00e88463, 0x02f71a63, 0xfff70893, 0x02088563, -// 0x555b1779, 0x87460303, 0x02236c5b, 0xeb6348fd, 0x800004e8, 0x06200313, 0x82b3a015, -// 0x802300e6, 0x070501f2, 0x4701bf5d, 0xbf03605b, 0x7e5b48fd, 0xe9634258, 0x800002e8, -// 0x07800313, 0x84040705, 0xe16348fd, 0x800002e8, 0x03000313, 0x84040705, 0xe96348fd, -// 0x006300e8, 0x8000020e, 0x02d00313, 0x84040705, 0x106f3d45, 0xede32f40, 0x8000fee8, -// 0x05800313, 0x765bb7e1, 0x80000028, 0x02b00313, 0x715bb7c5, 0x8000be38, 0x02000313, -// 0x7159bfd1, 0xced2d2ca, 0xccd6893a, 0xc6e2cada, 0xc2eac4e6, 0xd6868f55, 0xd0ced4a6, -// 0xc0eec8de, 0x8a2a5c66, 0x8b328aae, 0x8d468cb6, 0x7c13e319, 0x745bfefc, 0x498100ac, -// 0x0493c335, 0x745b0610, 0x0493005c, 0x0d930410, 0x49810201, 0x14d94ba5, 0x86ea8642, -// 0x85ca8566, 0xcc42ce3e, 0x4c4010ef, 0x48628c04, 0xe66347f2, 0x051306ab, 0x8c040305, -// 0x80238642, 0x86ea00ad, 0x85ca8566, 0xcc42ce3e, 0x25c010ef, 0x47f24862, 0x69630985, -// 0x146301a9, 0xe563012d, 0x0d85010c, 0x0209eadb, 0x58c65756, 0x1014c03a, 0x865a874e, -// 0x855285d6, 0x3da9c262, 0x54a650b6, 0x59865916, 0x4ae64a76, 0x4bc64b56, 0x4ca64c36, -// 0x4d864d16, 0x80826165, 0x892e8caa, 0x9526b741, 0x12efbf69, 0x71791d40, 0xe2994e86, -// 0xfefefe93, 0x00aef35b, 0x0313c2b1, 0xf45b0610, 0x0313005e, 0x8f360410, 0x01010f93, -// 0x43a54681, 0xff630e13, 0x02ff72b3, 0x0ff2f313, 0x0253ed63, 0x03030313, 0x0ff37313, -// 0x006f8023, 0x53330685, 0x656302ff, 0x0f8500ff, 0x0006eddb, 0x88c2c046, 0x87ba883e, -// 0x08148736, 0x33f9c276, 0x106f6145, 0x8f1a1900, 0x9372b7c1, 0x711db7f1, 0x8936caca, -// 0xde62c0de, 0x8baada6a, 0x8d328c2e, 0x8636854a, 0x86ba85ba, 0xc4d6c6d2, 0xdc66c2da, -// 0xcca6ce86, 0xd86ec8ce, 0x8abe8b3a, 0x8a468cc2, 0x629010ef, 0x8c10e51d, 0x8607a603, -// 0x8647a683, 0x85da854a, 0x611010ef, 0x00a04d63, 0xa6038c10, 0xa6838687, 0x854a86c7, -// 0x10ef85da, 0x59635ff0, 0x88d20205, 0x87d68866, 0x86ca875a, 0x85e2866a, 0x2699855e, -// 0x44e640f6, 0x49c64956, 0x4aa64a36, 0x4b864b16, 0x5ce25c72, 0x5dc25d52, 0x80826125, -// 0x46814601, 0x85da854a, 0x5c1010ef, 0x84dace4a, 0x00055663, 0x800004b7, 0x0164c4b3, -// 0x400a7593, 0x735bc82e, 0x4a9940aa, 0x7944a55b, 0xc0150513, 0x4c5010ef, 0xa6038c10, -// 0xa6838707, 0x10ef8747, 0x8c105520, 0x8787a603, 0x87c7a683, 0x312010ef, 0xa75b8c10, -// 0xa6034c04, 0xa6838807, 0x07b78847, 0x8fd93ff0, 0xca2ec82a, 0x85be854a, 0x2ec010ef, -// 0xa6038c10, 0xa6838887, 0x10ef88c7, 0x48425160, 0x862a48d2, 0x854286ae, 0x10ef85c6, -// 0x10ef2d40, 0x89aa39d0, 0x461010ef, 0xa6038410, 0xa6838906, 0xc82a8946, 0x10efca2e, -// 0x84104ea0, 0x8986a603, 0x89c6a683, 0x2aa010ef, 0x373010ef, 0x47d24742, 0xa6038410, -// 0xa6838a06, 0x85be8a46, 0x853a8daa, 0x4c0010ef, 0x856ec82a, 0x10efca2e, 0x841041b0, -// 0x8a86a603, 0x8ac6a683, 0x3ffd8d93, 0x4a4010ef, 0x47d24742, 0x86ae862a, 0x85be853a, -// 0x25c010ef, 0x86ae862a, 0xd22ed02a, 0x488010ef, 0x57925702, 0x86be863a, 0xca2ec82a, -// 0x85be853a, 0xd63ed43a, 0x23e010ef, 0xa6038410, 0xd02a8b06, 0x8b46a683, 0xd22e4542, -// 0x10ef45d2, 0x3e376f60, 0x2603a020, 0x26838b8e, 0x10ef8bce, 0x862a2180, 0x454286ae, -// 0x10ef45d2, 0x84106da0, 0x8c06a603, 0x8c46a683, 0x1fe010ef, 0x86ae862a, 0x45d24542, -// 0x6c0010ef, 0x572257b2, 0x8c1086be, 0xc82aca2e, 0x8c87a503, 0x8cc7a583, 0x10ef863a, -// 0x48421d20, 0x862a48d2, 0x854286ae, 0x10ef85c6, 0x53021c80, 0x862a5392, 0x851a86ae, -// 0x10ef859e, 0x8c106860, 0x8d07a603, 0x8d47a683, 0x1aa010ef, 0x97934701, 0x863a014d, -// 0x10ef86be, 0x862a3ce0, 0xc82a86ae, 0x854aca2e, 0x10ef85a6, 0x47423f70, 0x3e3747d2, -// 0x4f63a020, 0xc83a1005, 0x8d93ca3e, 0x07930639, 0xbdb30c60, 0x0d9101b7, 0x04ba715b, -// 0xa6038c10, 0xa6838d87, 0x854a8dc7, 0x10ef85a6, 0x47633bf0, 0x8c101005, 0x8e07a603, -// 0x8e47a683, 0x85a6854a, 0x3ad010ef, 0x0e055c63, 0x0f59d863, 0x413a8ab3, 0x6a131afd, -// 0x4d81400a, 0x48014981, 0x019df463, 0x41bc8833, 0x002a7593, 0x755bd02e, 0x8363001a, -// 0x4801000d, 0x00098c63, 0x46d24642, 0x854a85a6, 0x10efd442, 0x58225ce0, 0xce2a84ae, -// 0x46814601, 0x85da854a, 0x10efc842, 0x48423570, 0x00055563, 0x800007b7, 0x45f28cbd, -// 0x889378fd, 0x86ae7ff8, 0x011a78b3, 0x872687d6, 0x85e2866a, 0x2079855e, 0xd40d84e3, -// 0x04500793, 0x405a745b, 0x06500793, 0x00150493, 0x56fd862a, 0x85e2853e, 0xd6939b82, -// 0xc63341f9, 0x47950136, 0xc03e8020, 0x88938626, 0x4801fffd, 0xd71347a9, 0x85e201f9, -// 0x3105855e, 0x83e35482, 0x04b3d004, 0x053341a5, 0xfde3009d, 0x862acf94, 0x85e256fd, -// 0x04858010, 0xb7f59b82, 0x8b8e2603, 0x8bce2683, 0x85be853a, 0x524010ef, 0xc82a19fd, -// 0xbdd1ca2e, 0xbf214a81, 0xf00a8fe3, 0x400a7593, 0xf0058be3, 0xbf011afd, 0xd2ca7159, -// 0xc8de8936, 0x8baec6e2, 0xc02a8c32, 0x854a8636, 0x85ba86ba, 0xd0ced4a6, 0xccd6ced2, -// 0xcadad686, 0xc2eac4e6, 0x89bac0ee, 0x8ac284be, 0x10ef8a46, 0xcd0926f0, 0x88528410, -// 0x470d87d6, 0x8f468693, 0x86624502, 0xf0ef85de, 0xa85993bf, 0xa6038c10, 0xa6838687, -// 0x854a86c7, 0x10ef85ce, 0x59632430, 0x84100005, 0x87d68852, 0x86934711, 0xbfc98f86, -// 0xa6038c10, 0xa6838607, 0x854a8647, 0x10ef85ce, 0x506321b0, 0x795b02a0, 0x8410002a, -// 0x8ec68693, 0x88524711, 0xb76d87d6, 0x86938410, 0x470d8e86, 0x8c10bfcd, 0x9007a603, -// 0x9047a683, 0x85ce854a, 0x1e9010ef, 0x00a04d63, 0xa6038c10, 0xa6839087, 0x854a90c7, -// 0x10ef85ce, 0x59631d70, 0x45020205, 0x885688d2, 0x86ca87a6, 0x8662874e, 0x369585de, -// 0x54a650b6, 0x59865916, 0x4ae64a76, 0x4bc64b56, 0x4ca64c36, 0x4d864d16, 0x80826165, -// 0x46814601, 0x85ce854a, 0x199010ef, 0x10055063, 0x86ce864a, 0x45814501, 0x719000ef, -// 0x892a89ae, 0xc22e4585, 0x0eaa765b, 0x47a54c81, 0x03000713, 0x0097fc63, 0x020c8613, -// 0x002606b3, 0x80230c85, 0x14fd00e6, 0xbe0ce6db, 0x854a85ce, 0x7b6010ef, 0xa0203737, -// 0xc9870713, 0x0e97075b, 0x430c4350, 0x8b2ac632, 0x10efc42e, 0x862a0670, 0x854a86ae, -// 0x00ef85ce, 0x46226bf0, 0x3db746b2, 0x10efa020, 0xca2e0ea0, 0x10efc82a, 0x8d2a7e20, -// 0x0b9010ef, 0x47d24742, 0x86ae862a, 0x85be853a, 0x695000ef, 0x898da703, 0x89cda783, -// 0x86be863a, 0xce2ecc2a, 0x0ed010ef, 0xa703c86e, 0xa783898d, 0x486289cd, 0x596348f2, -// 0x0d0504a0, 0x10ef856a, 0x862a07b0, 0x452286ae, 0x10ef45b2, 0x44630cb0, 0x0b0500a0, -// 0xc4b94d01, 0x45a54629, 0x080ce7db, 0x003a7793, 0x1017ef5b, 0x100a8d63, 0xe5814592, -// 0x00ca7793, 0x1afdc391, 0x071347fd, 0xa8cd0300, 0xbf19c202, 0xbf194499, 0x86be863a, -// 0x85c68542, 0x085010ef, 0xfc0541e3, 0x000d0463, 0xba0d7d5b, 0xbf550d05, 0x10ef855a, -// 0x862a79a0, 0x854a86ae, 0x00ef85ce, 0x44c25f30, 0xa9038d2a, 0xa9838984, 0x864a89c4, -// 0x8dae86ce, 0x04d010ef, 0x00055a63, 0x86ce864a, 0x85ee856a, 0x039010ef, 0x00a05563, -// 0x000b735b, 0x46a90b05, 0x76b3a89d, 0x0c8502cd, 0x020c8793, 0x00278533, 0x869314fd, -// 0x0fa30306, 0x56b3fed5, 0xe56302cd, 0x94e603a5, 0x03000693, 0xb40cd8db, 0x001c8713, -// 0x009c9e63, 0x100c8804, 0x00b48cb3, 0x02e00693, 0xfedc8023, 0xbf658cba, 0xb72d8d36, -// 0x8cb38814, 0x80230025, 0x8cba00dc, 0x6733bfc1, 0x0c8502db, 0x020c8613, 0x4b33960a, -// 0x071302db, 0x0fa30307, 0x03e3fee6, 0xe2dbf00b, 0xbdfdbe0c, 0x86b38804, 0x0c850024, -// 0x00e68023, 0x015cf963, 0xff97f8e3, 0x87d68852, 0x10148766, 0x47fdbb25, 0xff97eae3, -// 0xc8994492, 0x10048814, 0x009587b3, 0x02d00713, 0x80230c85, 0xbfe9fee7, 0x002a795b, -// 0x100c8804, 0x00b487b3, 0x02b00713, 0x735bb7e5, 0x8814bc3a, 0x87b31004, 0x07130095, -// 0xbfd90200, 0x23d002ef, 0x89ae892a, 0x4a054481, 0x409a05b3, 0x00998533, 0x3c05a5db, -// 0x57939902, 0x94be0105, 0xa4db8c04, 0x535b3c04, 0x006fbe15, 0xcd192470, 0x227002ef, -// 0x07a31141, 0x840000a1, 0x00f10593, 0x59450513, 0x01413f75, 0x2330006f, 0x71198082, -// 0xc0dec2da, 0x3bb76b05, 0xde62a020, 0xa0203c37, 0xcacacca6, 0x0913c6d2, 0xc4d60641, -// 0x44818a2a, 0xa0201ab7, 0x800b0b13, 0x918b8b93, 0x910c0c13, 0xc8cece86, 0xda6adc66, -// 0xd2aed86e, 0xd6b6d4b2, 0xdabed8ba, 0xdec6dcc2, 0x4503d64a, 0xe90d000a, 0x862657f9, -// 0x0097f363, 0x102c5679, 0x56fd4501, 0x40f63fbd, 0x49c64956, 0x4aa64a36, 0x4b864b16, -// 0x5ce25c72, 0x5dc25d52, 0x44e68526, 0x80826109, 0x58db0a05, 0x89930055, 0x56fd0014, -// 0x102c8626, 0x4881aa05, 0x02b00713, 0xdddba801, 0xe1db02d7, 0xe8930307, 0x8a360018, -// 0x000a4783, 0x001a0693, 0x02b7d5db, 0xfef763e3, 0x0207d4db, 0x0237d5db, 0xfd078713, -// 0x46258810, 0x06e66563, 0x46a54981, 0xa01d45a9, 0x0028e893, 0xe893b7f9, 0xb7e10048, -// 0x0088e893, 0xe893b7c9, 0xbf750108, 0x02b989b3, 0x89938a32, 0x99bafd09, 0x000a4703, -// 0x001a0613, 0xfd070793, 0xf3e38c14, 0x4783fef6, 0xeadb000a, 0x46830ce7, 0x4625001a, -// 0xfd068713, 0x07938810, 0xe893001a, 0x60634008, 0x4d810ae6, 0x45294625, 0x4981a03d, -// 0xbca7ebdb, 0x00092983, 0x00490793, 0x0009d663, 0x0028e893, 0x413009b3, 0x8a36893e, -// 0x8db3bf6d, 0x87ae02ad, 0xfd0d8d93, 0xc6839db6, 0x85930007, 0x87130017, 0x8810fd06, -// 0xfee673e3, 0x8a138004, 0x06930017, 0x5edb06c0, 0xe56346c7, 0x53db06e6, 0x5bdb4887, -// 0x8a3e48a7, 0x000a4503, 0x07800793, 0xe8e30a05, 0x0793eea7, 0xe2630570, 0x079308a7, -// 0x5d5b0450, 0xe7634855, 0x6cdb08a7, 0x8993ac55, 0x56fd0014, 0x102c8626, 0x02500513, -// 0x3d3184ce, 0x4d81b559, 0xbaa6e4db, 0x00092d83, 0x00490713, 0x000dd363, 0x07934d81, -// 0x893a002a, 0x87d2bf41, 0xb7694d81, 0x414754db, 0xf9a76fdb, 0x1008e893, 0xc703bf61, -// 0x6bdb0017, 0xe893fec7, 0x8a133008, 0xb7590027, 0x0017c703, 0x408755db, 0x0808e893, -// 0xe893bfa5, 0xb7e50c08, 0x2008e893, 0x0793b7b5, 0x8c14fa85, 0x02000713, 0xe4f76de3, -// 0x0cfb87db, 0x8782439c, 0x5465515b, 0xe475655b, 0x0df57793, 0x4077e65b, 0x0168e8b3, -// 0x0fd57513, 0x4055635b, 0x07138414, 0x9b610079, 0x09134314, 0x43580087, 0x87ee884e, -// 0x102c8626, 0xf0ef8800, 0xa21de38f, 0x6b8558db, 0x6b85555b, 0x6af556db, 0x6a2556db, -// 0xfef8f893, 0x56db47a9, 0x54db4095, 0xf8934045, 0xf45bff38, 0xf89300a8, 0xf713ffe8, -// 0x54db2008, 0x66db4095, 0xc7314845, 0x7913091d, 0x2503ff89, 0x27030049, 0x56130009, -// 0x8f3141f5, 0x40c706b3, 0x00a645b3, 0x00d73733, 0x40c58633, 0xc446883e, 0x00890c93, -// 0x57934881, 0x073301f5, 0xc24e40e6, 0x8626c06e, 0x8800102c, 0xc72ff0ef, 0x896684aa, -// 0x2703bb99, 0x0c930009, 0xf15b0049, 0x56930288, 0xc63341f7, 0xc04600e6, 0x88ce886e, -// 0x8020837d, 0x102c8626, 0xf0ef8800, 0xbfc9d18f, 0x0068f45b, 0xbff18810, 0xbc78fd5b, -// 0x3c07375b, 0xc305bfc9, 0x7913091d, 0x8c00ff89, 0x00492703, 0xc446883e, 0x00890c93, -// 0x47814881, 0xc06ec24e, 0x8c00bf59, 0x00490c93, 0x0088f75b, 0x886ec046, 0x470188ce, -// 0xf55bbf45, 0xf6930068, 0xb7fd0ff6, 0xbe78f65b, 0x3c06a6db, 0x8414b7d5, 0x00790713, -// 0x43149b61, 0x00870913, 0x884e4358, 0x862687ee, 0x8800102c, 0x8cdff0ef, 0xb94584aa, -// 0x0028f593, 0x4c85c82e, 0x4218f85b, 0xa0294c81, 0x102c56fd, 0x31358010, 0x01948633, -// 0xe9e30c85, 0x4781ff3c, 0x00098463, 0xfff98793, 0x4c8994be, 0x00098463, 0x00198c93, -// 0x00094503, 0x56fd8626, 0x8d13102c, 0x3ef50014, 0x0d9344c2, 0xc4850049, 0x866a84e6, -// 0x56fda809, 0x8010102c, 0x00160913, 0x048536cd, 0xe8e3864a, 0x4701ff34, 0x0199e463, -// 0x41998733, 0x896e9d3a, 0xb91584ea, 0x00490593, 0x8c00ca2e, 0x9363876e, 0x577d000d, -// 0xe2918936, 0x974a8962, 0xc60387ca, 0xc2190007, 0x02f71463, 0x40d78cb3, 0x4008fd13, -// 0x00a8f55b, 0x019df363, 0xf5938cee, 0xc82e0028, 0x4418f15b, 0x88b38626, 0xa831409c, -// 0xbfc10785, 0x00160713, 0x102c56fd, 0xce468010, 0x36b5cc3a, 0x48f24762, 0x0733863a, -// 0x63e30116, 0x4701ff37, 0x0199e463, 0x41998733, 0x001c8793, 0x0cb394ba, 0x872600f7, -// 0x409706b3, 0xc50396ca, 0xc5190006, 0x000d0d63, 0xfffd8693, 0x000d9863, 0xc0b944c2, -// 0x84b3863a, 0xa02d40ec, 0x08938db6, 0x863a0017, 0x102c56fd, 0x3e11cc46, 0x874648e2, -// 0x56fdb7e1, 0x8010102c, 0x00160913, 0x3601c83a, 0x864a4742, 0x00c486b3, 0xff36e5e3, -// 0xe4634681, 0x86b30199, 0x97364199, 0x84ba4952, 0x8c00b6b9, 0x0218e893, 0xc0468626, -// 0x00490993, 0x886e48a1, 0x470147c1, 0x8800102c, 0xb1aff0ef, 0x84aa894e, 0x8414b62d, -// 0xb3b547c1, 0xb3a547a1, 0xb3954789, 0x4bc002ef, 0xa05207b7, 0x0187a983, 0x09374481, -// 0x4a05a052, 0xa0203ab7, 0x0209f85b, 0x01492683, 0x009a17b3, 0xfff7c713, 0x2a238f75, -// 0x270300e9, 0xd6130189, 0x8fd94024, 0x0034f593, 0x99ca8513, 0x00f92c23, 0xa8bff0ef, -// 0xd9930485, 0xe55b0019, 0xa979bd04, 0x482002ef, 0xa08004b7, 0x84205ccc, 0x9cc50513, -// 0xa6bff0ef, 0xe7935cdc, 0xdcdc03f7, 0x02efa169, 0xa7ab4640, 0x8420803f, 0x051353ec, -// 0xf0ef9f45, 0xa72ba4df, 0x537c803f, 0x0017e793, 0xa1a5d37c, 0x442002ef, 0xa01104b7, -// 0x9073409c, 0x67893407, 0xa0112737, 0x28078793, 0x0793c35c, 0xc71c3f60, 0x474140dc, -// 0x4727e793, 0x07b7c0dc, 0xcbd8a042, 0x08000713, 0x4739d7d8, 0xa223d398, 0x474d0207, -// 0x471dd7d8, 0x17b7d798, 0x43d8a011, 0xfdf77713, 0x43d8c3d8, 0xe7f77713, 0x10076713, -// 0x4798c3d8, 0xfdf77713, 0x4798c798, 0xe7f77713, 0x10076713, 0x43d8c798, 0xc3d88014, -// 0x80144798, 0x07b7c798, 0xcdaba071, 0x43988aff, 0x7807275b, 0x4398c398, 0x14074063, -// 0x06b74398, 0x8f558000, 0x4398c398, 0x12075863, 0x9b3d4398, 0x4398c398, 0x5247725b, -// 0x67134398, 0xc3980107, 0xfb5b439c, 0x84201047, 0xa1c50513, 0x977ff0ef, 0x0ac48713, -// 0x8420431c, 0x1007e793, 0xa583c31c, 0x05130ac4, 0xf0efa485, 0x842095df, 0xaa050513, -// 0x953ff0ef, 0x05138420, 0xf0efab85, 0x960b949f, 0x56838a5f, 0x47850126, 0x0cd7ee63, -// 0x07138030, 0x431c0f07, 0x869376c1, 0x8ff53ff6, 0x869366ad, 0x84204006, 0x05138fd5, -// 0xc31cad45, 0x917ff0ef, 0x05138420, 0xf0efaf45, 0x679990df, 0xa0120737, 0xaa578793, -// 0xcf1c8420, 0xb6050513, 0x7e600793, 0xa01104b7, 0xf0efcb1c, 0x40dc8edf, 0xf7938420, -// 0xc0dcbff7, 0x051340dc, 0xe793b785, 0xc0dc4007, 0x8d3ff0ef, 0x05138420, 0xf0efb905, -// 0x84938c9f, 0x409c0f04, 0xe0020737, 0x8ff9177d, 0x00080737, 0xc09c8fd9, 0xa0133737, -// 0x8aefcfab, 0x007a17b7, 0x20078793, 0xa01336b7, 0x2c46a703, 0x0a07705b, 0xfbfd17fd, -// 0x07138030, 0x431c0f07, 0x869376c1, 0x8ff53ff6, 0x66858420, 0x05138fd5, 0xc31cbc85, -// 0xf0ef4489, 0xa059871f, 0x05138420, 0xf0efa6c5, 0xb721865f, 0xa0800737, 0x05b74b5c, -// 0x15fdff00, 0xcb5c8fed, 0x82855b1c, 0x0077e793, 0x4b0cdb1c, 0xf593421c, 0x079ef605, -// 0x424c8fcd, 0x059216fd, 0x460c8fcd, 0x058e8420, 0x464c8fcd, 0x01064603, 0x8fcd058a, -// 0xcb1c8fd1, 0x0513433c, 0xf793b145, 0x8eddf007, 0xf0efc334, 0x842080df, 0xb2c50513, -// 0x803ff0ef, 0x05138420, 0xb5f5b485, 0xf33d8b79, 0x05138420, 0x4481bac5, 0xfeaff0ef, -// 0xe20007b7, 0x85a38004, 0x67f30007, 0x84203004, 0xbe850513, 0xfd2ff0ef, 0xe0ef454d, -// 0x4561c4bf, 0xc45fe0ef, 0xe0ef4569, 0x456dc3ff, 0xc39fe0ef, 0x02100513, 0xc31fe0ef, -// 0xaae18526, 0x0073c501, 0xbff51050, 0x80824505, 0xce061101, 0xca4acc26, 0x26f3c84e, -// 0x67053420, 0xf7b3177d, 0xc66300e6, 0x44810406, 0x02e78863, 0xa0203937, 0xc7c90913, -// 0xa02009b7, 0x012487b3, 0x0007c783, 0x00f10593, 0x59498513, 0x07a30485, 0xf0ef00f1, -// 0xe35bf0ef, 0xa001bf94, 0x05138420, 0xf0efc605, 0x40f2f4cf, 0x495244e2, 0x610549c2, -// 0x07138082, 0x68e30310, 0x0737fef7, 0x0713a020, 0x07db2007, 0x439c0cf7, 0xbff19782, -// 0x0000a001, 0x82aac63d, 0xf31383b2, 0x9316fe03, 0x02655863, 0x41d44190, 0x45dc4598, -// 0xc154c110, 0xc55cc518, 0x49d44990, 0x4ddc4d98, 0xc954c910, 0xcd5ccd18, 0x02058593, -// 0x02050513, 0xfc654ce3, 0xffc3f313, 0x00530333, 0x00655863, 0x05914190, 0x0511c110, -// 0xfe654ce3, 0x00728333, 0x00655a63, 0x0005c603, 0x00230585, 0x050500c5, 0xfe654ae3, -// 0x80828516, 0x03b3832a, 0x769300c5, 0xce810035, 0xffc68693, 0x40d507b3, 0x06f3e463, -// 0x00b50023, 0x9de30505, 0x0d63fea7, 0x05e20475, 0x0085d793, 0xd79395be, 0x95be0105, -// 0x40a38633, 0x02000713, 0xfe067693, 0x00a687b3, 0x7693e285, 0xca8dffc6, 0x40d70633, -// 0x00a687b3, 0x82058736, 0x00000697, 0x00c686b3, 0x00c68067, 0xcd0ccd4c, 0xc90cc94c, -// 0xc50cc54c, 0xc10cc14c, 0x17e3953a, 0xbf6dfef5, 0x1de3879e, 0x851af875, 0x71398082, -// 0xc66e4301, 0x7139a019, 0xc86a5341, 0xcc62ca66, 0xa019ce5e, 0x53017139, 0xd256d05a, -// 0xd64ed452, 0xda26d84a, 0xde06dc22, 0x40610133, 0x11418282, 0xc226c04a, 0xc606c422, -// 0x4db28282, 0x4d020141, 0x4c224c92, 0x01414bb2, 0x4a924b02, 0x49b24a22, 0x49020141, -// 0x44224492, 0x014140b2, 0x00008082, 0xa0494701, 0x01065a93, 0x01051893, 0x0108d793, -// 0xd7338141, 0xf5b30355, 0x18930355, 0xd6930106, 0x05c20108, 0x05338dc9, 0xbfb302d7, -// 0x8e6300a5, 0x177d000f, 0xbfb395b2, 0x986300c5, 0xbfb3000f, 0x846300a5, 0x177d000f, -// 0x8d8995b2, 0x0355f533, 0x0355d5b3, 0x8d5d0542, 0x02b686b3, 0x00d53fb3, 0x000f8e63, -// 0x15fd9532, 0x00c53fb3, 0x000f9863, 0x00d53fb3, 0x000f8463, 0x15fd9532, 0x07428d15, -// 0x80828dd9, 0xc0267179, 0xc44ec24a, 0xc856c652, 0xcc06ca22, 0x892e84aa, 0x8a3689b2, -// 0xeac5843a, 0x01393fb3, 0x020f8e63, 0x00ef854e, 0xce2a4ab0, 0x99b3cd19, 0x089300a9, -// 0x87b30200, 0xd7b340a8, 0x193300f4, 0x693300a9, 0x94b300f9, 0x852600a4, 0x864e85ca, -// 0xd02e3f05, 0x478184aa, 0xa0b9d23e, 0x854ece21, 0x471000ef, 0xe519ce2a, 0x41390933, -// 0xd23e4785, 0x02c0006f, 0x02000893, 0x40a88fb3, 0x00a999b3, 0xd733864e, 0x17b301f4, -// 0x94b300a9, 0xe53300a4, 0x55b300e7, 0x35ed01f9, 0x892ad22e, 0x85ca8526, 0x3df9864e, -// 0x84aad02e, 0x46f2c479, 0xd4b34901, 0xa87d00d4, 0x0339d933, 0x0339f4b3, 0x45014581, -// 0xc004cc55, 0x01242223, 0x3fb3a855, 0x97e30149, 0x8552fe0f, 0x3fd000ef, 0xc955ce2a, -// 0x02000893, 0x40a88733, 0x00e9d7b3, 0x00aa1633, 0x8a328e5d, 0x00a999b3, 0x00e4d6b3, -// 0x00a494b3, 0x00a91533, 0x00e955b3, 0x3dad8d55, 0x892ad02e, 0x03358533, 0x0335b5b3, -// 0x00b93fb3, 0x000f9863, 0x03259263, 0x00a4bfb3, 0x000f8e63, 0x85b35682, 0x16fd4145, -// 0x06b3d036, 0x3fb34135, 0x85b300d5, 0x853641f5, 0xd2364681, 0x8533c80d, 0x05b340a4, -// 0xbfb340b9, 0x85b300a4, 0x46f241f5, 0x02000893, 0x40d88733, 0x00e59933, 0x00d554b3, -// 0x0124e4b3, 0x00d5d933, 0x2223c004, 0x55020124, 0x02412583, 0x49124482, 0x4a3249a2, -// 0x44524ac2, 0x614540e2, 0x46818082, 0x012a3fb3, 0x000f9663, 0x0134bfb3, 0x000f9e63, -// 0xd03e4785, 0x41348733, 0x41490933, 0x00e4bfb3, 0x41f90933, 0xa01184ba, 0xd236d036, -// 0xbf65f855, 0xc0061141, 0x3d2d0058, 0x45a24512, 0x01414082, 0x00008082, 0x80000737, -// 0x97138eb9, 0x11010015, 0xc24ac026, 0xc652c44e, 0xca06c856, 0x00169493, 0x800000b7, -// 0x00973fb3, 0x000f9863, 0x02971063, 0x00c53fb3, 0x000f8c63, 0x8a2e89aa, 0x85b68532, -// 0x86d2864e, 0x00159713, 0x00169493, 0xf6b38ead, 0x59130016, 0xda930157, 0x1a130154, -// 0x999300a7, 0x079300a4, 0x80637ff0, 0x6fb31d27, 0x886300a7, 0xefb31a0f, 0x8e6300c4, -// 0x04b3120f, 0xbf934159, 0x88630404, 0x5793120f, 0x6a330155, 0x052e00fa, 0x01565793, -// 0x00f9e9b3, 0x3f93062e, 0x9d630029, 0x6a33040f, 0x8463001a, 0xe9b3000a, 0x87930019, -// 0x9363fff4, 0x84be000a, 0x0893c0a1, 0x87b30200, 0x5c634098, 0x173300f0, 0x97b300f6, -// 0xd9b300f9, 0x56330099, 0x8e5d0096, 0x04b3a829, 0x879340f0, 0x97330207, 0x8f5100f9, -// 0x8726e091, 0x0099d633, 0xc3194981, 0x00266613, 0x1663c6e9, 0x14630159, 0x0f63013a, -// 0x3fb310c5, 0x9863013a, 0x1d63000f, 0x3fb3013a, 0x896300c5, 0x197d000f, 0x01f99713, -// 0x0019d993, 0x8e598205, 0x8d11872a, 0x00a73fb3, 0x41fa0a33, 0x413a0a33, 0x00293f93, -// 0x0a0f9263, 0x020a1563, 0x02093f93, 0x020f9163, 0x45018a2a, 0x1c631901, 0xa8310009, -// 0x0c63197d, 0x57130009, 0x0a0601f5, 0x6a330506, 0x3fb300ea, 0x95e3001a, 0x0513fe0f, -// 0x3f934005, 0x9a7e4005, 0x01fa3fb3, 0x5793997e, 0x8b8500b5, 0x8d1d84aa, 0x00a4bfb3, -// 0x41fa0a33, 0x17930a06, 0x5a13014a, 0x812d00ca, 0x17938d5d, 0x6a330149, 0xf5b300fa, -// 0xe5b30015, 0x44820145, 0x49a24912, 0x4ac24a32, 0x610540d2, 0x95328082, 0x00c53fb3, -// 0x3fb39a7e, 0x9a4e01fa, 0x000f9f63, 0x013a3fb3, 0x000f9b63, 0xf8091be3, 0x1713812d, -// 0x5a13015a, 0x8d5900ba, 0x0893bf7d, 0x87b37fe0, 0xc3854128, 0x00157f93, 0x00256793, -// 0x000f8363, 0x1713853e, 0x5a1301fa, 0x8105001a, 0x09058d59, 0x4501bfb9, 0x7ff00a37, -// 0xdad1b779, 0x45814501, 0x6a33b779, 0x156300aa, 0x92e3001a, 0xd2c1f957, 0x05b74501, -// 0xbfa5fff8, 0xc0261101, 0xc44ec24a, 0xc856c652, 0xcc0eca22, 0x1141ce06, 0x00159713, -// 0x99138355, 0x549300b5, 0x69330155, 0x14930099, 0x043700b5, 0x97938000, 0x83d50016, -// 0x00b69a13, 0x01565993, 0x013a6a33, 0x00b61993, 0xfab38ead, 0x06930086, 0xcb6d7ff0, -// 0x14e68e63, 0x00896933, 0x18078d63, 0x16f68463, 0x008a6a33, 0x8513c656, 0x972ac027, -// 0x034936b3, 0x03490633, 0x0344b5b3, 0x03448533, 0x00b60a33, 0x00ba3fb3, 0x01f68ab3, -// 0x033936b3, 0x03390633, 0x00a60933, 0x00a93fb3, 0x3fb39a7e, 0x9afe01fa, 0x3fb39a36, -// 0x9afe00da, 0x0334b5b3, 0x03348533, 0x3fb3992e, 0x9a7e00b9, 0x01fa3fb3, 0x01fa85b3, -// 0x00a96933, 0x001a6513, 0x00091363, 0xaf938552, 0x99630005, 0x8faa000f, 0x3fb3952a, -// 0x95ae01f5, 0x177d95fe, 0x5c634ab2, 0x089314e0, 0x87b37ff0, 0x5d6340e8, 0x05130cf0, -// 0x3f934005, 0x86634005, 0x95fe000f, 0x01f5bfb3, 0x5613977e, 0x8a0500b5, 0x812d8d11, -// 0x01559613, 0x05868d51, 0x179381b1, 0x8ddd0147, 0x0155e5b3, 0x44820141, 0x49a24912, -// 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, 0x00996fb3, 0x040f8563, 0x01f4df93, -// 0x997e994a, 0x156394a6, 0x89260009, 0x17014481, 0x85ca4501, 0x95aea019, 0xbfb30505, -// 0x9ce30085, 0x05e3fe0f, 0x8f09ee05, 0x02000893, 0x40a88633, 0x00c4d633, 0x00a494b3, -// 0x00a91933, 0x00c96933, 0x8363b5f1, 0x85d604f6, 0x44820141, 0x49a24912, 0x4ac24a32, -// 0x41e24452, 0x610540f2, 0x00008067, 0x00996933, 0x02891263, 0x1613e791, 0x6633001a, -// 0xca190136, 0x00f69663, 0x013a6a33, 0x008a1663, 0x05b74501, 0xbf897ff0, 0x05b74501, -// 0x0141fff8, 0x49124482, 0x4a3249a2, 0x44524ac2, 0x40f241e2, 0x80676105, 0x65330000, -// 0xdd51013a, 0x01f9df93, 0x9a7e9a52, 0x156399ce, 0x8a4e000a, 0x17814981, 0x85d24501, -// 0x95aea019, 0xbfb30505, 0x9ce30085, 0x03e3fe0f, 0x8f89e405, 0x02000893, 0x40a88633, -// 0x00c9d633, 0x00a999b3, 0x00aa1a33, 0x00ca6a33, 0x4481b525, 0x86b34885, 0xbf9340e8, -// 0x9b630206, 0x84aa000f, 0x4581852e, 0xc5091681, 0x0206bf93, 0x020f8d63, 0x0893c29d, -// 0x86330200, 0x993340d8, 0x17b300c5, 0x553300c5, 0xd5b300d5, 0x653300d5, 0x8cdd0125, -// 0x6513c099, 0x05130015, 0x3f934005, 0x95fe4005, 0x01f5d713, 0x4501bd9d, 0x0000bded, -// 0xc0261101, 0xc44ec24a, 0xc856c652, 0xcc0eca22, 0x1141ce06, 0x00159713, 0x99138355, -// 0x549300b5, 0x69330155, 0x14930099, 0x043700b5, 0x97938000, 0x83d50016, 0x00b69a13, -// 0x01565993, 0x013a6a33, 0x00b61993, 0xfab38ead, 0x06930086, 0x08637ff0, 0x84632207, -// 0x69332ce6, 0x8d630089, 0x85632e07, 0x6a332ef6, 0x8f1d008a, 0x3ff70713, 0x15938085, -// 0x8ccd01f9, 0x00195913, 0x010a5613, 0x02c956b3, 0x02c97933, 0x010a1893, 0x0108d593, -// 0x02d587b3, 0xd5130942, 0x69330104, 0x854a00a9, 0x40f90933, 0x01253fb3, 0x000f8863, -// 0x995216fd, 0x01493fb3, 0xfe0f8ce3, 0x02c95833, 0x02c97933, 0x87b38642, 0x094202c5, -// 0x01049893, 0x0108d513, 0x00a96933, 0x0933854a, 0x3fb340f9, 0x88630125, 0x167d000f, -// 0x3fb39952, 0x8ce30149, 0x06c2fe0f, 0xb5b396b2, 0x85330336, 0x04b30336, 0x854a40a0, -// 0x40b90933, 0x01253fb3, 0x854ac499, 0x9663197d, 0x3fb3000f, 0x81630125, 0x16fd020f, -// 0xb53394ce, 0x99520134, 0x01493fb3, 0x0905c511, 0x000f9663, 0x00193f93, 0xfe0f83e3, -// 0x01491763, 0x892685ce, 0x45014601, 0x5593a041, 0x5633010a, 0x793302b9, 0x189302b9, -// 0xd513010a, 0x0fb30108, 0x094202c5, 0x0104d793, 0x00f96933, 0x093387ca, 0xbfb341f9, -// 0x88630127, 0x167d000f, 0x3fb39952, 0x8ce30149, 0x5833fe0f, 0x793302b9, 0x85c202b9, -// 0x02b507b3, 0x98930942, 0xd5130104, 0x69330108, 0x854a00a9, 0x40f90933, 0x01253fb3, -// 0x000f8863, 0x995215fd, 0x01493fb3, 0xfe0f8ce3, 0x962e0642, 0x033635b3, 0x03360533, -// 0x40a004b3, 0x0933854a, 0x3fb340b9, 0xc4990125, 0x197d854a, 0x000f9663, 0x01253fb3, -// 0x020f8163, 0x94ce167d, 0x0134b533, 0x3fb39952, 0xc5110149, 0x96630905, 0x3f93000f, -// 0x83e30019, 0xaf93fe0f, 0x99630006, 0x8fb2000f, 0x3fb39632, 0x96b601f6, 0x177d96fe, -// 0x00996933, 0x00166513, 0x00091363, 0x85b68532, 0x16e05f63, 0x7ff00893, 0x40e887b3, -// 0x0ef05b63, 0x40050513, 0x40053f93, 0x000f8663, 0xbfb395fe, 0x977e01f5, 0x00b55613, -// 0x8d118a05, 0x9613812d, 0x8d510155, 0x81b10586, 0x01471793, 0xe5b38ddd, 0x01410155, -// 0x49124482, 0x4a3249a2, 0x44524ac2, 0x40f241e2, 0x80676105, 0x6fb30000, 0x85630099, -// 0xdf93040f, 0x994a01f4, 0x94a6997e, 0x00091563, 0x44818926, 0x45011701, 0xa01985ca, -// 0x050595ae, 0x0085bfb3, 0xfe0f9ce3, 0xda0507e3, 0x08938f09, 0x86330200, 0xd63340a8, -// 0x94b300c4, 0x193300a4, 0x693300a9, 0xbb4100c9, 0x02f68463, 0x6fb3e789, 0x8363013a, -// 0x85d6020f, 0x44820141, 0x49a24912, 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, -// 0x013a6a33, 0xfe8a01e3, 0x05b74501, 0x0141fff8, 0x49124482, 0x4a3249a2, 0x44524ac2, -// 0x40f241e2, 0x80676105, 0x69330000, 0x1fe30099, 0x8de3fc89, 0x4501fcf6, 0x7ff005b7, -// 0x0155e5b3, 0x44820141, 0x49a24912, 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, -// 0x013a6a33, 0xfa8a18e3, 0xb7614501, 0x013a6fb3, 0xfc0f87e3, 0x01f9df93, 0x9a7e9a52, -// 0x156399ce, 0x8a4e000a, 0x17814981, 0x85d24501, 0x95aea019, 0xbfb30505, 0x9ce30085, -// 0x02e3fe0f, 0x8f89ce05, 0x02000893, 0x40a88633, 0x00c9d633, 0x00a999b3, 0x00aa1a33, -// 0x00ca6a33, 0x4481b1d9, 0x86b34885, 0xbf9340e8, 0x9b630206, 0x84aa000f, 0x4581852e, -// 0xc5091681, 0x0206bf93, 0x020f8d63, 0x0893c29d, 0x86330200, 0x993340d8, 0x17b300c5, -// 0x553300c5, 0xd5b300d5, 0x653300d5, 0x8cdd0125, 0x6513c099, 0x05130015, 0x3f934005, -// 0x95fe4005, 0x01f5d713, 0x4501bd81, 0x9693bdf9, 0x571300b5, 0x8ed90155, 0x80000737, -// 0x97138ed9, 0x83550015, 0x41e00893, 0x40e88633, 0x02c05363, 0x02000713, 0x00e63fb3, -// 0x000f9363, 0xd6b34681, 0xaf9300c6, 0x84630005, 0x06b3000f, 0x853640d0, 0xc1198082, -// 0x0015e593, 0x7ff00737, 0x00b73fb3, 0x000f8563, 0x80000537, 0x05378082, 0x157d8000, -// 0x00008082, 0x00b59693, 0x01555713, 0x07378ed9, 0x8ed98000, 0x00159713, 0x08938355, -// 0x863341e0, 0x2f9340e8, 0x93630006, 0x0713020f, 0x3fb30200, 0x936300e6, 0x4681000f, -// 0x00c6d6b3, 0x0005af93, 0x000f8463, 0x40d006b3, 0x80828536, 0xe593c119, 0x07370015, -// 0x3fb37ff0, 0x856300b7, 0x0537000f, 0x80828000, 0x8082557d, 0xc0261141, 0x4581c206, -// 0x86ae87ae, 0xc239862a, 0x00062f93, 0x000f8a63, 0x800007b7, 0x40c00633, 0x05b3c581, -// 0x167d40b0, 0x41e00693, 0xc02a1141, 0xc432c22e, 0x1141c636, 0x8532c03e, 0x872a2215, -// 0x01414782, 0x45924502, 0x46b24622, 0x8e990141, 0x00e61633, 0x00b5d713, 0x01561493, -// 0x14938f45, 0x80b10016, 0x94938fc5, 0x8fc50146, 0x85be853a, 0x40924482, 0x80820141, -// 0xc0261141, 0x4581c206, 0x862a86ae, 0x0693c60d, 0x110141e0, 0xc22ec02a, 0xc636c432, -// 0x8532c83a, 0x87aa20e1, 0x45924502, 0x46b24622, 0x61054742, 0x16338e9d, 0xd71300f6, -// 0x149300b5, 0x8f450156, 0x00161793, 0x949383b1, 0x8fc50146, 0x85be853a, 0x40924482, -// 0x80820141, 0xa011577d, 0x47814705, 0xffe00e37, 0x00159293, 0x00a7bfb3, 0x01f28eb3, -// 0x01de3fb3, 0x060f9863, 0x00169393, 0x00c7bfb3, 0x01f38eb3, 0x01de3fb3, 0x040f9e63, -// 0x00d5c733, 0x04074063, 0x0005af93, 0x000f9f63, 0x40c50733, 0x00e53fb3, 0x40d58533, -// 0x41f50533, 0x00e7bfb3, 0x857ee111, 0x07338082, 0x3fb340a6, 0x853300e6, 0x053340b6, -// 0xbfb341f5, 0xe11100e7, 0x8082857e, 0x0072e7b3, 0x00c56733, 0xc7818fd9, 0xc1914505, -// 0x8082852e, 0x8082853a, 0x736367c1, 0x079302f5, 0x07130ff0, 0xe9630200, 0x37b704a7, -// 0x8793a020, 0x97aace87, 0x0007c503, 0x40a70533, 0x00008067, 0x010007b7, 0x00f57e63, -// 0xa02037b7, 0x87938141, 0x97aace87, 0x0007c503, 0x05334741, 0x808240a7, 0xa02037b7, -// 0x87938161, 0x97aace87, 0x0007c503, 0x05334721, 0x808240a7, 0xa02037b7, 0x87938121, -// 0x97aace87, 0x0007c503, 0x05334761, 0x808240a7, 0x00e688b3, 0x02000513, 0xa0200537, -// 0xa02036b7, 0xfd6a8513, 0x0ff77713, 0x00092683, 0xa02037b7, 0x0007c703, 0x00176713, -// 0x00688023, 0x0208e893, 0x020c8493, 0x020c8593, 0x0ff57513, 0x0ff7f793, 0x40d606b3, -// 0xa0110737, 0xa0203537, 0xa02007b7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0xffffffff, 0x7fefffff, 0xffffffff, 0xffefffff, 0x509f79fb, 0x3fd34413, -// 0x8b60c8b3, 0x3fc68a28, 0x00000000, 0x3ff80000, 0x636f4361, 0x3fd287a7, 0x0979a371, -// 0x400a934f, 0x00000000, 0x3fe00000, 0xbbb55516, 0x40026bb1, 0xfefa39ef, 0x3fe62e42, -// 0x00000000, 0x402c0000, 0x00000000, 0x40240000, 0x00000000, 0x40180000, 0x00000000, -// 0x40000000, 0x00000000, 0x3ff00000, 0xeb1c432d, 0x3f1a36e2, 0x00000000, 0x412e8480, -// 0x00696e66, 0x2b696e66, 0x00000000, 0x006e616e, 0x2d696e66, 0x00000000, 0x00000000, -// 0x41cdcd65, 0x00000000, 0xc1cdcd65, 0x6c756e28, 0x0000296c, 0xa020126c, 0xa020107e, -// 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, -// 0xa020107e, 0xa020126c, 0xa0201394, 0xa020126c, 0xa0201238, 0xa0201374, 0xa0201238, -// 0xa020107e, 0xa020126c, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, -// 0xa020126c, 0xa02014f6, 0xa020107e, 0xa020107e, 0xa0201410, 0xa020107e, 0xa020126c, -// 0xa020107e, 0xa020107e, 0xa020126c, 0x666e695b, 0x67205d6f, 0x203a7470, 0x20717269, -// 0x65636572, 0x64657669, 0x206e6f20, 0x656d6974, 0x75252072, 0x6863202c, 0x0d752520, -// 0x0000000a, 0x666e695b, 0x73205d6f, 0x203a6970, 0x20717269, 0x65636572, 0x64657669, -// 0x6f63202c, 0x203a6564, 0x78257830, 0x00000a0d, 0x666e695b, 0x67205d6f, 0x3a6f6970, -// 0x71726920, 0x63657220, 0x65766965, 0x76202c64, 0x203a6c61, 0x58257830, 0x00000a0d, -// 0x666e695b, 0x6f205d6f, 0x203a6566, 0x47504665, 0x6e612041, 0x43502064, 0x65522042, -// 0x20746573, 0x65737341, 0x64657472, 0x00000a0d, 0x666e695b, 0x73205d6f, 0x203a7563, -// 0x6c6f7349, 0x6f697461, 0x664f5f6e, 0x203d2066, 0x78257830, 0x00000a0d, 0x7272655b, -// 0x205d726f, 0x3a65666f, 0x72724520, 0x4120726f, 0x72657373, 0x676e6974, 0x50466520, -// 0x202c4147, 0x20424350, 0x65736552, 0x0a0d7374, 0x00000000, 0x666e695b, 0x78205d6f, -// 0x203a4243, 0x74696e49, 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x71205d6f, 0x3a697073, -// 0x696e4920, 0x74732074, 0x0d747261, 0x0000000a, 0x7665735b, 0x5d657265, 0x70737120, -// 0x49203a69, 0x2074696e, 0x6c696166, 0x0a0d6465, 0x00000000, 0x7665735b, 0x5d657265, -// 0x616c6620, 0x203a6873, 0x74696e49, 0x69616620, 0x0d64656c, 0x0000000a, 0x666e695b, -// 0x71205d6f, 0x3a697073, 0x696e4920, 0x4b4f2074, 0x00000a0d, 0x666e695b, 0x66205d6f, -// 0x6873616c, 0x6e49203a, 0x73207469, 0x74726174, 0x00000a0d, 0x666e695b, 0x66205d6f, -// 0x6873616c, 0x6e49203a, 0x4f207469, 0x000a0d4b, 0x666e695b, 0x77205d6f, 0x203a7464, -// 0x74696e49, 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x64205d6f, 0x203a616d, 0x74696e49, -// 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x63205d6f, 0x74707972, 0x49203a6f, 0x2074696e, -// 0x72617473, 0x000a0d74, 0x666e695b, 0x63205d6f, 0x74707972, 0x49203a6f, 0x2074696e, -// 0x0a0d4b4f, 0x00000000, 0x7665735b, 0x5d657265, 0x79726320, 0x3a6f7470, 0x696e4920, -// 0x61662074, 0x64656c69, 0x00000a0d, 0x666e695b, 0x69205d6f, 0x7265746e, 0x74707572, -// 0x49203a73, 0x2074696e, 0x0a0d4b4f, 0x00000000, 0x666e695b, 0x66205d6f, 0x3a6c6273, -// 0x696e4920, 0x74732074, 0x0d747261, 0x0000000a, 0x666e695b, 0x66205d6f, 0x3a6c6273, -// 0x696e4920, 0x75532074, 0x73656363, 0x000a0d73, 0x7665735b, 0x5d657265, 0x62736620, -// 0x49203a6c, 0x2074696e, 0x6c696146, 0x0a0d6465, 0x00000000, 0x666e695b, 0x77205d6f, -// 0x203a7464, 0x20717269, 0x65636572, 0x64657669, 0x00000a0d, 0x78450a0d, 0x74706563, -// 0x2e6e6f69, 0x636f4c20, 0x676e696b, 0x0d2e2e2e, 0x0000000a, 0x00000000, 0x3ff00000, -// 0x00000000, 0x40240000, 0x00000000, 0x40590000, 0x00000000, 0x408f4000, 0x00000000, -// 0x40c38800, 0x00000000, 0x40f86a00, 0x00000000, 0x412e8480, 0x00000000, 0x416312d0, -// 0x00000000, 0x4197d784, 0x00000000, 0x41cdcd65, 0x02020100, 0x03030303, 0x04040404, -// 0x04040404, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x06060606, 0x06060606, -// 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x07070707, -// 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, -// 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, -// 0x07070707, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, -// 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, -// 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, -// 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, -// 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0xa0510000, 0xa0130000, -// 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xa0600000, 0x000000ff, -// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, -// 0x00000000, 0x00000000, 0x00000000, 0x37c2cac9, 0x8c32e765, 0xa15e1200, 0x25c486b2, -// 0x8734d7b4, 0xfa26c29d, 0x2ff972ae, 0x0adebf22, 0xff6f29e6, 0x3c50778d, 0xfa02d8da, -// 0x78600d02, 0xbca88565, 0x163ca9be, 0x73f0da10, 0x3ed20b1c, 0xcce46d11, 0x2a49278f, -// 0x12248db6, 0xe50b6755, 0xa431193c, 0x6c308699, 0xe0c41dbf, 0x50c791fe, 0xd3f876b9, -// 0x7cf1df93, 0x16941322, 0xaa1ead8f, 0xe3753f54, 0xc9bb7bcc, 0x79200bff, 0x7d76c2d4, -// 0xa7acc7f7, 0xff567a99, 0xbfa4f5dc, 0x064238c8, 0xe9699208, 0xa6b5daf3, 0xa3a2ad30, -// 0x32bafe37, 0x54e1dacb, 0xda540799, 0x95547760, 0x302cd650, 0x9d428238, 0x62bbdadd, -// 0xe531a353, 0x282e8f7d, 0x973e7ba1, 0x0dd65973, 0x4ab77a02, 0x53ca63ae, 0x176010c2, -// 0x58bc890d, 0x025f55f8, 0x0e1e579b, 0xe19cdb04, 0x4bb6caf5, 0xad438b2c, 0xeda4466b, -// 0x3cabf8dc, 0x0785aca7, 0xd0350f09, 0x79cac3c1, 0x00010001, 0x00000000, 0x00000000, -// 0x00000000}; // */ - const uint32_t bop_image_addr[] = { 0x4c425346, 0x00010001, 0x00000001, 0x00002e80, 0xa020005c, 0xa020005c, 0x00000040, 0x00000000, 0x00000020, 0x00000104, 0x3c000100, 0x00000000, 0x00000000, 0x00000000, @@ -1643,7 +1203,6 @@ int main(void) pufs_hash_test(pufs); pufs_hash_sg_test(pufs); pufs_rsa2048_verify_test(pufs); - while (true); // TODO Remove while } if ((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { From d1557478b23507e96753ddf31abdb0107ed3342b Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Mon, 21 Oct 2024 23:32:07 +0500 Subject: [PATCH 52/58] Flash test failing --- drivers/crypto/pufcc.c | 58 +++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index bdbac98ad5f6b..bd9ef649c585b 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -517,18 +517,18 @@ enum pufcc_status pufcc_rsa2048_sign_verify( REG_WRITE_32(&pkc_regs->ecp_ec, ecp_ec_reg); // .... Public key print TODO - printf("%s(%d) Public Key\r\n", __func__, __LINE__); - for(int i = 0; i < 256; i++) { - printf("0x%02x%s", pub_key->n[i], (i+1)%16==0?"\r\n":","); - } printf("\r\n"); + // printf("%s(%d) Public Key\r\n", __func__, __LINE__); + // for(int i = 0; i < 256; i++) { + // printf("0x%02x%s", pub_key->n[i], (i+1)%16==0?"\r\n":","); + // } printf("\r\n"); // Reverse public key modulus reverse(pufcc_buffer, pub_key->n, PUFCC_RSA_2048_LEN); //////////////////////////// // .... Reversed Public key print TODO - printf("%s(%d) original Reversed Public Key\r\n", __func__, __LINE__); - for(int i = 0; i < 256; i++) { - printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); - } printf("\r\n"); + // printf("%s(%d) original Reversed Public Key\r\n", __func__, __LINE__); + // for(int i = 0; i < 256; i++) { + // printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); + // } printf("\r\n"); //////////////////////////// // memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET, // pufcc_buffer, PUFCC_RSA_2048_LEN); @@ -540,11 +540,11 @@ enum pufcc_status pufcc_rsa2048_sign_verify( // printf("%p 0x%08x =? 0x%08x\r\n", (ptr-1), *(buf_ptr-1), *(ptr-1)); } //printf("\r\n"); // .... Reversed Public key print TODO - uint8_t *_8ptr = (uint8_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET; - printf("%s(%d) manual Copy Read Reversed Public Key at %p\r\n", __func__, __LINE__, _8ptr); - for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { - printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); - } printf("\r\n"); + // uint8_t *_8ptr = (uint8_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET; + // printf("%s(%d) manual Copy Read Reversed Public Key at %p\r\n", __func__, __LINE__, _8ptr); + // for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { + // printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); + // } printf("\r\n"); //////////////////////////// // Write public key exponent to ecp_e_short register @@ -554,10 +554,10 @@ enum pufcc_status pufcc_rsa2048_sign_verify( reverse(pufcc_buffer, sig, PUFCC_RSA_2048_LEN); //////////////////////////// // .... Reversed Signature print TODO - printf("%s(%d) original Reversed Signature\r\n", __func__, __LINE__); - for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { - printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); - } printf("\r\n"); + // printf("%s(%d) original Reversed Signature\r\n", __func__, __LINE__); + // for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { + // printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); + // } printf("\r\n"); //////////////////////////// // Write reversed signature to ECP data field at proper offset // memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, @@ -565,15 +565,15 @@ enum pufcc_status pufcc_rsa2048_sign_verify( //////////////////////////// ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET/4; buf_ptr = (uint32_t*)pufcc_buffer; - printf("%s(%d) manual Copy Reversed Signature at %p\r\n", __func__, __LINE__, ptr); + // printf("%s(%d) manual Copy Reversed Signature at %p\r\n", __func__, __LINE__, ptr); for(int i = 0; i < PUFCC_RSA_2048_LEN/4; i++) { *ptr++ = *buf_ptr++; } - _8ptr = (uint8_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET; - printf("%s(%d) memcpy Read Reversed Signature at %p\r\n", __func__, __LINE__, _8ptr); - for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { - printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); - } printf("\r\n"); + // _8ptr = (uint8_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET; + // printf("%s(%d) memcpy Read Reversed Signature at %p\r\n", __func__, __LINE__, _8ptr); + // for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { + // printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); + // } printf("\r\n"); //////////////////////////// // Write microprogram for RSA2048 @@ -581,15 +581,15 @@ enum pufcc_status pufcc_rsa2048_sign_verify( //////////////////////////// ptr = (uint32_t*)&pkc_regs->ecp_mac; buf_ptr = (uint32_t*)rsa_2048_mprog; - printf("%s(%d) manual Copy Reversed Microprogram at %p\r\n", __func__, __LINE__, ptr); + // printf("%s(%d) manual Copy Reversed Microprogram at %p\r\n", __func__, __LINE__, ptr); for(int i = 0; i < sizeof(rsa_2048_mprog)/4; i++) { *ptr++ = *buf_ptr++; } - _8ptr = (uint8_t*)&pkc_regs->ecp_mac; - printf("%s(%d) Manual copy Read Microprogram %p\r\n", __func__, __LINE__, _8ptr); - for(int i = 0; i < sizeof(rsa_2048_mprog); i++) { - printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); - } printf("\r\n"); + // _8ptr = (uint8_t*)&pkc_regs->ecp_mac; + // printf("%s(%d) Manual copy Read Microprogram %p\r\n", __func__, __LINE__, _8ptr); + // for(int i = 0; i < sizeof(rsa_2048_mprog); i++) { + // printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); + // } printf("\r\n"); //////////////////////////// temp32 = 0; struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; From 557f35b16e007fe1e19ceff5d0c1dc9acc05dce9 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 22 Oct 2024 14:24:37 +0500 Subject: [PATCH 53/58] Flash test passed. Needed correction in defconfig file --- boards/rapidsilicon/virgo_proto/virgo_proto_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/boards/rapidsilicon/virgo_proto/virgo_proto_defconfig b/boards/rapidsilicon/virgo_proto/virgo_proto_defconfig index fa0b85cc06913..484687bbd6b06 100644 --- a/boards/rapidsilicon/virgo_proto/virgo_proto_defconfig +++ b/boards/rapidsilicon/virgo_proto/virgo_proto_defconfig @@ -38,6 +38,7 @@ CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=13333333 # Enabling the SPI Peripheral CONFIG_SPI=y +CONFIG_SPI_NOR=y # Enabling the Crypto Peripheral CONFIG_CRYPTO=y @@ -53,6 +54,7 @@ CONFIG_DMA_ANDES_ATCDMAC100=y CONFIG_FLASH=y CONFIG_SPI_NOR_SFDP_DEVICETREE=y CONFIG_SPI_ANDES_ATCSPI200=y +CONFIG_ANDES_SPI_DMA_MODE=n # Enabling the Counter Peripheral CONFIG_COUNTER=y From 8ebfe8cab8b334c0df61b94442b99e13952914b8 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 22 Oct 2024 17:26:48 +0500 Subject: [PATCH 54/58] Updated PUFcc file with compilation flags --- drivers/crypto/pufcc.c | 96 ++---- samples/hello_world/src/main.c | 565 ++++++--------------------------- 2 files changed, 125 insertions(+), 536 deletions(-) diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index bd9ef649c585b..66116150f519d 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -516,81 +516,49 @@ enum pufcc_status pufcc_rsa2048_sign_verify( ecp_ec_reg->field = PUFCC_RSA_2048; REG_WRITE_32(&pkc_regs->ecp_ec, ecp_ec_reg); - // .... Public key print TODO - // printf("%s(%d) Public Key\r\n", __func__, __LINE__); - // for(int i = 0; i < 256; i++) { - // printf("0x%02x%s", pub_key->n[i], (i+1)%16==0?"\r\n":","); - // } printf("\r\n"); // Reverse public key modulus reverse(pufcc_buffer, pub_key->n, PUFCC_RSA_2048_LEN); - //////////////////////////// - // .... Reversed Public key print TODO - // printf("%s(%d) original Reversed Public Key\r\n", __func__, __LINE__); - // for(int i = 0; i < 256; i++) { - // printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); - // } printf("\r\n"); - //////////////////////////// - // memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET, - // pufcc_buffer, PUFCC_RSA_2048_LEN); - //////////////////////////// - uint32_t *ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET/4; - uint32_t *buf_ptr = (uint32_t*)pufcc_buffer; - for(int i = 0; i < PUFCC_RSA_2048_LEN/4; i++) { - *ptr++ = *buf_ptr++; - // printf("%p 0x%08x =? 0x%08x\r\n", (ptr-1), *(buf_ptr-1), *(ptr-1)); - } //printf("\r\n"); - // .... Reversed Public key print TODO - // uint8_t *_8ptr = (uint8_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET; - // printf("%s(%d) manual Copy Read Reversed Public Key at %p\r\n", __func__, __LINE__, _8ptr); - // for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { - // printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); - // } printf("\r\n"); - //////////////////////////// + + #if !CONFIG_RS_RTOS_PORT + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET, + pufcc_buffer, PUFCC_RSA_2048_LEN); + #else + uint32_t *ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_MODULUS_OFFSET/4; + uint32_t *buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_RSA_2048_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #endif // Write public key exponent to ecp_e_short register REG_WRITE_32(&pkc_regs->ecp_e_short, &pub_key->e); // Reverse signature reverse(pufcc_buffer, sig, PUFCC_RSA_2048_LEN); - //////////////////////////// - // .... Reversed Signature print TODO - // printf("%s(%d) original Reversed Signature\r\n", __func__, __LINE__); - // for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { - // printf("0x%02x%s", pufcc_buffer[i], (i+1)%16==0?"\r\n":","); - // } printf("\r\n"); - //////////////////////////// + // Write reversed signature to ECP data field at proper offset - // memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, - // pufcc_buffer, PUFCC_RSA_2048_LEN); - //////////////////////////// - ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET/4; - buf_ptr = (uint32_t*)pufcc_buffer; - // printf("%s(%d) manual Copy Reversed Signature at %p\r\n", __func__, __LINE__, ptr); - for(int i = 0; i < PUFCC_RSA_2048_LEN/4; i++) { - *ptr++ = *buf_ptr++; - } - // _8ptr = (uint8_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET; - // printf("%s(%d) memcpy Read Reversed Signature at %p\r\n", __func__, __LINE__, _8ptr); - // for(int i = 0; i < PUFCC_RSA_2048_LEN; i++) { - // printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); - // } printf("\r\n"); - //////////////////////////// + #if !CONFIG_RS_RTOS_PORT + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET, + pufcc_buffer, PUFCC_RSA_2048_LEN); + #else + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_RSA2048_SIGN_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_RSA_2048_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #endif // Write microprogram for RSA2048 - // memcpy((void *)&pkc_regs->ecp_mac, rsa_2048_mprog, sizeof(rsa_2048_mprog)); - //////////////////////////// - ptr = (uint32_t*)&pkc_regs->ecp_mac; - buf_ptr = (uint32_t*)rsa_2048_mprog; - // printf("%s(%d) manual Copy Reversed Microprogram at %p\r\n", __func__, __LINE__, ptr); - for(int i = 0; i < sizeof(rsa_2048_mprog)/4; i++) { - *ptr++ = *buf_ptr++; - } - // _8ptr = (uint8_t*)&pkc_regs->ecp_mac; - // printf("%s(%d) Manual copy Read Microprogram %p\r\n", __func__, __LINE__, _8ptr); - // for(int i = 0; i < sizeof(rsa_2048_mprog); i++) { - // printf("0x%02x%s", *_8ptr++, (i+1)%16==0?"\r\n":","); - // } printf("\r\n"); - //////////////////////////// + #if !CONFIG_RS_RTOS_PORT + memcpy((void *)&pkc_regs->ecp_mac, rsa_2048_mprog, sizeof(rsa_2048_mprog)); + #else + ptr = (uint32_t*)&pkc_regs->ecp_mac; + buf_ptr = (uint32_t*)rsa_2048_mprog; + for(int i = 0; i < sizeof(rsa_2048_mprog)/4; i++) { + *ptr++ = *buf_ptr++; + } + #endif + temp32 = 0; struct pufcc_intrpt_reg *intrpt_reg = (struct pufcc_intrpt_reg *)&temp32; intrpt_reg->intrpt_st = 1; diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 0f7cce5d23381..3255bb696d767 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -636,480 +636,102 @@ void pufs_decryption_test(const struct device *pufs) } } -const uint32_t bop_image_addr[] = { - 0x4c425346, 0x00010001, 0x00000001, 0x00002e80, 0xa020005c, 0xa020005c, 0x00000040, - 0x00000000, 0x00000020, 0x00000104, 0x3c000100, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0xa54a0000, 0xa02000b7, 0x06408067, 0x30405073, 0x34405073, 0x41014081, - 0x42014181, 0x43014281, 0x44014381, 0x46814481, 0x47814701, 0x48814801, 0x49814901, - 0x4a814a01, 0x4b814b01, 0x4c814c01, 0x4d814d01, 0x4e814e01, 0x4f814f01, 0x00100197, - 0x75c18193, 0xf14023f3, 0x00000293, 0x0072f463, 0x01d0106f, 0x0018128b, 0x62858116, - 0x80028293, 0x025382b3, 0x40510133, 0x006f840a, 0x12ef0040, 0x25731290, 0x10eff140, - 0xc91576e0, 0x8c1f978b, 0x8b9f960b, 0x40c78633, 0x950b4581, 0x10ef8b9f, 0x960b0530, - 0x978b801f, 0x35b78b9f, 0x8633a020, 0x859340c7, 0x950bde85, 0x10ef801f, 0x27b77c60, - 0x8793a020, 0x90737fc7, 0x07938007, 0xa0732000, 0x07b77d07, 0x8793a020, 0x90734037, - 0x84303057, 0x20078793, 0x30779073, 0xfc2027f3, 0x01c7f85b, 0xa02007b7, 0x30178793, - 0x7ec79073, 0xe2000737, 0x00074783, 0xf7938420, 0xe7930817, 0x05130047, 0x0023c085, - 0x00ef00f7, 0x10ef6890, 0xe51944a0, 0x05138420, 0x00efc245, 0xa0016790, 0x05138420, - 0x00efc405, 0xbfd566d0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, +const uint32_t bop_rsa_image_addr[] = { + 0x4c425346, 0x00010001, 0x00000001, 0x00000540, 0xa020005c, 0xa020005c, 0x00000040, + 0x00000000, 0x00000020, 0x00000104, 0x00000100, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x467b0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, - 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, - 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, - 0xa0201528, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa020157c, 0xa0200472, - 0xa020159a, 0xa0200504, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, - 0xa02005b6, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, - 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, 0xa0200472, - 0xa0200472, 0xa0200472, 0xa0200472, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0xc006711d, 0xc416c212, 0xc81ec61a, 0xcc2eca2a, - 0xd036ce32, 0xd43ed23a, 0xd846d642, 0xdc76da72, 0xc0fede7a, 0x7ee8d073, 0x7ef95073, - 0x7ed090f3, 0x42a24212, 0x43c24332, 0x45e24552, 0x56824672, 0x57a25712, 0x58c25832, - 0x5ee25e52, 0x4f865f72, 0x70734096, 0x90733004, 0x40a63420, 0x34109073, 0x345020f3, - 0xfc0094e3, 0x61254082, 0x30200073, 0x00000013, 0x00000013, 0x00000013, 0x00000013, - 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, - 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, - 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, - 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0x00000013, - 0x00000013, 0x00000013, 0x00000013, 0x00000013, 0xc0067119, 0xc416c212, 0xc81ec61a, - 0xcc2eca2a, 0xd036ce32, 0xd43ed23a, 0xd846d642, 0xdc76da72, 0xc0fede7a, 0x341022f3, - 0x30002373, 0xc49ac296, 0x34202573, 0x10ef858a, 0x77f34220, 0x42963004, 0x90734326, - 0x10733412, 0x40823003, 0x42a24212, 0x43c24332, 0x45e24552, 0x56824672, 0x57a25712, - 0x58c25832, 0x5ee25e52, 0x4f865f72, 0x00736109, 0x80823020, 0xff950793, 0x07db8030, - 0x67410cf7, 0xc3980705, 0xe20017b7, 0x00178713, 0x0ca7075b, 0x078d4685, 0xe2000837, - 0x00d70023, 0x00251593, 0x00084683, 0x0ca7855b, 0x00054703, 0x1016a6db, 0x00d71733, - 0x57334621, 0x478940d7, 0x96b38020, 0x8f5500d7, 0x00238810, 0x470300e5, 0x275b0008, - 0x5f5b1017, 0x47830087, 0x07330005, 0xd7b340e6, 0x97b340e7, 0xe79300e7, 0x8c140017, - 0x00f50023, 0xe20017b7, 0x97ae0789, 0x77138004, 0x80230fe7, 0x808200e7, 0x970b1101, - 0xca4a81df, 0xc25ac652, 0xce06c05e, 0xc84ecc26, 0x4318c456, 0x81df9b0b, 0x03072a83, - 0x9a0b4901, 0x4b8581df, 0x01090993, 0x00890493, 0x013b99b3, 0x012b97b3, 0x009b94b3, - 0x0159f9b3, 0x9b638cdd, 0xf7b30009, 0x567d00fa, 0x4609e391, 0x0154f7b3, 0xa801e399, - 0x27834601, 0x2503068b, 0x85ca048b, 0x27839782, 0xf4b3000a, 0xe4b30154, 0x09050134, - 0x0b11db84, 0xba79685b, 0x44e240f2, 0x49c24952, 0x4aa24a32, 0x4b824b12, 0x80826105, - 0x07b7cd99, 0x5bd8a042, 0x765b4581, 0x47030057, 0x45850005, 0x4505d398, 0x8d4d05c2, - 0x45018082, 0x978bbfe5, 0x4394805f, 0x42d875c1, 0x15f94a90, 0x80148f6d, 0xc2d89a79, - 0x00c03633, 0x4b884bd8, 0x40c00633, 0x87024581, 0x3fa012ef, 0x77938a3e, 0x8aaa0038, - 0x89b28b2e, 0x893a8bb6, 0x84b28c42, 0x84bae785, 0x40e60cb3, 0x56fda031, 0x801085da, - 0x9a820485, 0x009c8633, 0xff44e9e3, 0x64634481, 0x04b3012a, 0x94ce412a, 0x852694ca, - 0x41248633, 0x00091c63, 0x001c785b, 0x413484b3, 0x00998533, 0x0144ed63, 0x3d60106f, - 0x87b3197d, 0xc503012b, 0x56fd0007, 0x9a8285da, 0x862abfc9, 0x85da56fd, 0x04858010, - 0xbfd99a82, 0x3a2012ef, 0x48528342, 0x47c28e3e, 0x4418735b, 0x00187e93, 0x8963cb91, - 0x1663000e, 0x7f13000e, 0x036300c8, 0x17fd000f, 0x03000f13, 0x59dba801, 0x8fb30007, - 0x070500e6, 0x01ef8023, 0xff1769e3, 0x0f934f7d, 0x86630300, 0x7463000e, 0x7c6300f7, - 0x755b02ef, 0x7f5b0648, 0xcf0d42a8, 0x00e88463, 0x02f71a63, 0xfff70893, 0x02088563, - 0x555b1779, 0x87460303, 0x02236c5b, 0xeb6348fd, 0x800004e8, 0x06200313, 0x82b3a015, - 0x802300e6, 0x070501f2, 0x4701bf5d, 0xbf03605b, 0x7e5b48fd, 0xe9634258, 0x800002e8, - 0x07800313, 0x84040705, 0xe16348fd, 0x800002e8, 0x03000313, 0x84040705, 0xe96348fd, - 0x006300e8, 0x8000020e, 0x02d00313, 0x84040705, 0x106f3d45, 0xede32f40, 0x8000fee8, - 0x05800313, 0x765bb7e1, 0x80000028, 0x02b00313, 0x715bb7c5, 0x8000be38, 0x02000313, - 0x7159bfd1, 0xced2d2ca, 0xccd6893a, 0xc6e2cada, 0xc2eac4e6, 0xd6868f55, 0xd0ced4a6, - 0xc0eec8de, 0x8a2a5c66, 0x8b328aae, 0x8d468cb6, 0x7c13e319, 0x745bfefc, 0x498100ac, - 0x0493c335, 0x745b0610, 0x0493005c, 0x0d930410, 0x49810201, 0x14d94ba5, 0x86ea8642, - 0x85ca8566, 0xcc42ce3e, 0x4c4010ef, 0x48628c04, 0xe66347f2, 0x051306ab, 0x8c040305, - 0x80238642, 0x86ea00ad, 0x85ca8566, 0xcc42ce3e, 0x25c010ef, 0x47f24862, 0x69630985, - 0x146301a9, 0xe563012d, 0x0d85010c, 0x0209eadb, 0x58c65756, 0x1014c03a, 0x865a874e, - 0x855285d6, 0x3da9c262, 0x54a650b6, 0x59865916, 0x4ae64a76, 0x4bc64b56, 0x4ca64c36, - 0x4d864d16, 0x80826165, 0x892e8caa, 0x9526b741, 0x12efbf69, 0x71791d40, 0xe2994e86, - 0xfefefe93, 0x00aef35b, 0x0313c2b1, 0xf45b0610, 0x0313005e, 0x8f360410, 0x01010f93, - 0x43a54681, 0xff630e13, 0x02ff72b3, 0x0ff2f313, 0x0253ed63, 0x03030313, 0x0ff37313, - 0x006f8023, 0x53330685, 0x656302ff, 0x0f8500ff, 0x0006eddb, 0x88c2c046, 0x87ba883e, - 0x08148736, 0x33f9c276, 0x106f6145, 0x8f1a1900, 0x9372b7c1, 0x711db7f1, 0x8936caca, - 0xde62c0de, 0x8baada6a, 0x8d328c2e, 0x8636854a, 0x86ba85ba, 0xc4d6c6d2, 0xdc66c2da, - 0xcca6ce86, 0xd86ec8ce, 0x8abe8b3a, 0x8a468cc2, 0x629010ef, 0x8c10e51d, 0x8607a603, - 0x8647a683, 0x85da854a, 0x611010ef, 0x00a04d63, 0xa6038c10, 0xa6838687, 0x854a86c7, - 0x10ef85da, 0x59635ff0, 0x88d20205, 0x87d68866, 0x86ca875a, 0x85e2866a, 0x2699855e, - 0x44e640f6, 0x49c64956, 0x4aa64a36, 0x4b864b16, 0x5ce25c72, 0x5dc25d52, 0x80826125, - 0x46814601, 0x85da854a, 0x5c1010ef, 0x84dace4a, 0x00055663, 0x800004b7, 0x0164c4b3, - 0x400a7593, 0x735bc82e, 0x4a9940aa, 0x7944a55b, 0xc0150513, 0x4c5010ef, 0xa6038c10, - 0xa6838707, 0x10ef8747, 0x8c105520, 0x8787a603, 0x87c7a683, 0x312010ef, 0xa75b8c10, - 0xa6034c04, 0xa6838807, 0x07b78847, 0x8fd93ff0, 0xca2ec82a, 0x85be854a, 0x2ec010ef, - 0xa6038c10, 0xa6838887, 0x10ef88c7, 0x48425160, 0x862a48d2, 0x854286ae, 0x10ef85c6, - 0x10ef2d40, 0x89aa39d0, 0x461010ef, 0xa6038410, 0xa6838906, 0xc82a8946, 0x10efca2e, - 0x84104ea0, 0x8986a603, 0x89c6a683, 0x2aa010ef, 0x373010ef, 0x47d24742, 0xa6038410, - 0xa6838a06, 0x85be8a46, 0x853a8daa, 0x4c0010ef, 0x856ec82a, 0x10efca2e, 0x841041b0, - 0x8a86a603, 0x8ac6a683, 0x3ffd8d93, 0x4a4010ef, 0x47d24742, 0x86ae862a, 0x85be853a, - 0x25c010ef, 0x86ae862a, 0xd22ed02a, 0x488010ef, 0x57925702, 0x86be863a, 0xca2ec82a, - 0x85be853a, 0xd63ed43a, 0x23e010ef, 0xa6038410, 0xd02a8b06, 0x8b46a683, 0xd22e4542, - 0x10ef45d2, 0x3e376f60, 0x2603a020, 0x26838b8e, 0x10ef8bce, 0x862a2180, 0x454286ae, - 0x10ef45d2, 0x84106da0, 0x8c06a603, 0x8c46a683, 0x1fe010ef, 0x86ae862a, 0x45d24542, - 0x6c0010ef, 0x572257b2, 0x8c1086be, 0xc82aca2e, 0x8c87a503, 0x8cc7a583, 0x10ef863a, - 0x48421d20, 0x862a48d2, 0x854286ae, 0x10ef85c6, 0x53021c80, 0x862a5392, 0x851a86ae, - 0x10ef859e, 0x8c106860, 0x8d07a603, 0x8d47a683, 0x1aa010ef, 0x97934701, 0x863a014d, - 0x10ef86be, 0x862a3ce0, 0xc82a86ae, 0x854aca2e, 0x10ef85a6, 0x47423f70, 0x3e3747d2, - 0x4f63a020, 0xc83a1005, 0x8d93ca3e, 0x07930639, 0xbdb30c60, 0x0d9101b7, 0x04ba715b, - 0xa6038c10, 0xa6838d87, 0x854a8dc7, 0x10ef85a6, 0x47633bf0, 0x8c101005, 0x8e07a603, - 0x8e47a683, 0x85a6854a, 0x3ad010ef, 0x0e055c63, 0x0f59d863, 0x413a8ab3, 0x6a131afd, - 0x4d81400a, 0x48014981, 0x019df463, 0x41bc8833, 0x002a7593, 0x755bd02e, 0x8363001a, - 0x4801000d, 0x00098c63, 0x46d24642, 0x854a85a6, 0x10efd442, 0x58225ce0, 0xce2a84ae, - 0x46814601, 0x85da854a, 0x10efc842, 0x48423570, 0x00055563, 0x800007b7, 0x45f28cbd, - 0x889378fd, 0x86ae7ff8, 0x011a78b3, 0x872687d6, 0x85e2866a, 0x2079855e, 0xd40d84e3, - 0x04500793, 0x405a745b, 0x06500793, 0x00150493, 0x56fd862a, 0x85e2853e, 0xd6939b82, - 0xc63341f9, 0x47950136, 0xc03e8020, 0x88938626, 0x4801fffd, 0xd71347a9, 0x85e201f9, - 0x3105855e, 0x83e35482, 0x04b3d004, 0x053341a5, 0xfde3009d, 0x862acf94, 0x85e256fd, - 0x04858010, 0xb7f59b82, 0x8b8e2603, 0x8bce2683, 0x85be853a, 0x524010ef, 0xc82a19fd, - 0xbdd1ca2e, 0xbf214a81, 0xf00a8fe3, 0x400a7593, 0xf0058be3, 0xbf011afd, 0xd2ca7159, - 0xc8de8936, 0x8baec6e2, 0xc02a8c32, 0x854a8636, 0x85ba86ba, 0xd0ced4a6, 0xccd6ced2, - 0xcadad686, 0xc2eac4e6, 0x89bac0ee, 0x8ac284be, 0x10ef8a46, 0xcd0926f0, 0x88528410, - 0x470d87d6, 0x8f468693, 0x86624502, 0xf0ef85de, 0xa85993bf, 0xa6038c10, 0xa6838687, - 0x854a86c7, 0x10ef85ce, 0x59632430, 0x84100005, 0x87d68852, 0x86934711, 0xbfc98f86, - 0xa6038c10, 0xa6838607, 0x854a8647, 0x10ef85ce, 0x506321b0, 0x795b02a0, 0x8410002a, - 0x8ec68693, 0x88524711, 0xb76d87d6, 0x86938410, 0x470d8e86, 0x8c10bfcd, 0x9007a603, - 0x9047a683, 0x85ce854a, 0x1e9010ef, 0x00a04d63, 0xa6038c10, 0xa6839087, 0x854a90c7, - 0x10ef85ce, 0x59631d70, 0x45020205, 0x885688d2, 0x86ca87a6, 0x8662874e, 0x369585de, - 0x54a650b6, 0x59865916, 0x4ae64a76, 0x4bc64b56, 0x4ca64c36, 0x4d864d16, 0x80826165, - 0x46814601, 0x85ce854a, 0x199010ef, 0x10055063, 0x86ce864a, 0x45814501, 0x719000ef, - 0x892a89ae, 0xc22e4585, 0x0eaa765b, 0x47a54c81, 0x03000713, 0x0097fc63, 0x020c8613, - 0x002606b3, 0x80230c85, 0x14fd00e6, 0xbe0ce6db, 0x854a85ce, 0x7b6010ef, 0xa0203737, - 0xc9870713, 0x0e97075b, 0x430c4350, 0x8b2ac632, 0x10efc42e, 0x862a0670, 0x854a86ae, - 0x00ef85ce, 0x46226bf0, 0x3db746b2, 0x10efa020, 0xca2e0ea0, 0x10efc82a, 0x8d2a7e20, - 0x0b9010ef, 0x47d24742, 0x86ae862a, 0x85be853a, 0x695000ef, 0x898da703, 0x89cda783, - 0x86be863a, 0xce2ecc2a, 0x0ed010ef, 0xa703c86e, 0xa783898d, 0x486289cd, 0x596348f2, - 0x0d0504a0, 0x10ef856a, 0x862a07b0, 0x452286ae, 0x10ef45b2, 0x44630cb0, 0x0b0500a0, - 0xc4b94d01, 0x45a54629, 0x080ce7db, 0x003a7793, 0x1017ef5b, 0x100a8d63, 0xe5814592, - 0x00ca7793, 0x1afdc391, 0x071347fd, 0xa8cd0300, 0xbf19c202, 0xbf194499, 0x86be863a, - 0x85c68542, 0x085010ef, 0xfc0541e3, 0x000d0463, 0xba0d7d5b, 0xbf550d05, 0x10ef855a, - 0x862a79a0, 0x854a86ae, 0x00ef85ce, 0x44c25f30, 0xa9038d2a, 0xa9838984, 0x864a89c4, - 0x8dae86ce, 0x04d010ef, 0x00055a63, 0x86ce864a, 0x85ee856a, 0x039010ef, 0x00a05563, - 0x000b735b, 0x46a90b05, 0x76b3a89d, 0x0c8502cd, 0x020c8793, 0x00278533, 0x869314fd, - 0x0fa30306, 0x56b3fed5, 0xe56302cd, 0x94e603a5, 0x03000693, 0xb40cd8db, 0x001c8713, - 0x009c9e63, 0x100c8804, 0x00b48cb3, 0x02e00693, 0xfedc8023, 0xbf658cba, 0xb72d8d36, - 0x8cb38814, 0x80230025, 0x8cba00dc, 0x6733bfc1, 0x0c8502db, 0x020c8613, 0x4b33960a, - 0x071302db, 0x0fa30307, 0x03e3fee6, 0xe2dbf00b, 0xbdfdbe0c, 0x86b38804, 0x0c850024, - 0x00e68023, 0x015cf963, 0xff97f8e3, 0x87d68852, 0x10148766, 0x47fdbb25, 0xff97eae3, - 0xc8994492, 0x10048814, 0x009587b3, 0x02d00713, 0x80230c85, 0xbfe9fee7, 0x002a795b, - 0x100c8804, 0x00b487b3, 0x02b00713, 0x735bb7e5, 0x8814bc3a, 0x87b31004, 0x07130095, - 0xbfd90200, 0x23d002ef, 0x89ae892a, 0x4a054481, 0x409a05b3, 0x00998533, 0x3c05a5db, - 0x57939902, 0x94be0105, 0xa4db8c04, 0x535b3c04, 0x006fbe15, 0xcd192470, 0x227002ef, - 0x07a31141, 0x840000a1, 0x00f10593, 0x59450513, 0x01413f75, 0x2330006f, 0x71198082, - 0xc0dec2da, 0x3bb76b05, 0xde62a020, 0xa0203c37, 0xcacacca6, 0x0913c6d2, 0xc4d60641, - 0x44818a2a, 0xa0201ab7, 0x800b0b13, 0x918b8b93, 0x910c0c13, 0xc8cece86, 0xda6adc66, - 0xd2aed86e, 0xd6b6d4b2, 0xdabed8ba, 0xdec6dcc2, 0x4503d64a, 0xe90d000a, 0x862657f9, - 0x0097f363, 0x102c5679, 0x56fd4501, 0x40f63fbd, 0x49c64956, 0x4aa64a36, 0x4b864b16, - 0x5ce25c72, 0x5dc25d52, 0x44e68526, 0x80826109, 0x58db0a05, 0x89930055, 0x56fd0014, - 0x102c8626, 0x4881aa05, 0x02b00713, 0xdddba801, 0xe1db02d7, 0xe8930307, 0x8a360018, - 0x000a4783, 0x001a0693, 0x02b7d5db, 0xfef763e3, 0x0207d4db, 0x0237d5db, 0xfd078713, - 0x46258810, 0x06e66563, 0x46a54981, 0xa01d45a9, 0x0028e893, 0xe893b7f9, 0xb7e10048, - 0x0088e893, 0xe893b7c9, 0xbf750108, 0x02b989b3, 0x89938a32, 0x99bafd09, 0x000a4703, - 0x001a0613, 0xfd070793, 0xf3e38c14, 0x4783fef6, 0xeadb000a, 0x46830ce7, 0x4625001a, - 0xfd068713, 0x07938810, 0xe893001a, 0x60634008, 0x4d810ae6, 0x45294625, 0x4981a03d, - 0xbca7ebdb, 0x00092983, 0x00490793, 0x0009d663, 0x0028e893, 0x413009b3, 0x8a36893e, - 0x8db3bf6d, 0x87ae02ad, 0xfd0d8d93, 0xc6839db6, 0x85930007, 0x87130017, 0x8810fd06, - 0xfee673e3, 0x8a138004, 0x06930017, 0x5edb06c0, 0xe56346c7, 0x53db06e6, 0x5bdb4887, - 0x8a3e48a7, 0x000a4503, 0x07800793, 0xe8e30a05, 0x0793eea7, 0xe2630570, 0x079308a7, - 0x5d5b0450, 0xe7634855, 0x6cdb08a7, 0x8993ac55, 0x56fd0014, 0x102c8626, 0x02500513, - 0x3d3184ce, 0x4d81b559, 0xbaa6e4db, 0x00092d83, 0x00490713, 0x000dd363, 0x07934d81, - 0x893a002a, 0x87d2bf41, 0xb7694d81, 0x414754db, 0xf9a76fdb, 0x1008e893, 0xc703bf61, - 0x6bdb0017, 0xe893fec7, 0x8a133008, 0xb7590027, 0x0017c703, 0x408755db, 0x0808e893, - 0xe893bfa5, 0xb7e50c08, 0x2008e893, 0x0793b7b5, 0x8c14fa85, 0x02000713, 0xe4f76de3, - 0x0cfb87db, 0x8782439c, 0x5465515b, 0xe475655b, 0x0df57793, 0x4077e65b, 0x0168e8b3, - 0x0fd57513, 0x4055635b, 0x07138414, 0x9b610079, 0x09134314, 0x43580087, 0x87ee884e, - 0x102c8626, 0xf0ef8800, 0xa21de38f, 0x6b8558db, 0x6b85555b, 0x6af556db, 0x6a2556db, - 0xfef8f893, 0x56db47a9, 0x54db4095, 0xf8934045, 0xf45bff38, 0xf89300a8, 0xf713ffe8, - 0x54db2008, 0x66db4095, 0xc7314845, 0x7913091d, 0x2503ff89, 0x27030049, 0x56130009, - 0x8f3141f5, 0x40c706b3, 0x00a645b3, 0x00d73733, 0x40c58633, 0xc446883e, 0x00890c93, - 0x57934881, 0x073301f5, 0xc24e40e6, 0x8626c06e, 0x8800102c, 0xc72ff0ef, 0x896684aa, - 0x2703bb99, 0x0c930009, 0xf15b0049, 0x56930288, 0xc63341f7, 0xc04600e6, 0x88ce886e, - 0x8020837d, 0x102c8626, 0xf0ef8800, 0xbfc9d18f, 0x0068f45b, 0xbff18810, 0xbc78fd5b, - 0x3c07375b, 0xc305bfc9, 0x7913091d, 0x8c00ff89, 0x00492703, 0xc446883e, 0x00890c93, - 0x47814881, 0xc06ec24e, 0x8c00bf59, 0x00490c93, 0x0088f75b, 0x886ec046, 0x470188ce, - 0xf55bbf45, 0xf6930068, 0xb7fd0ff6, 0xbe78f65b, 0x3c06a6db, 0x8414b7d5, 0x00790713, - 0x43149b61, 0x00870913, 0x884e4358, 0x862687ee, 0x8800102c, 0x8cdff0ef, 0xb94584aa, - 0x0028f593, 0x4c85c82e, 0x4218f85b, 0xa0294c81, 0x102c56fd, 0x31358010, 0x01948633, - 0xe9e30c85, 0x4781ff3c, 0x00098463, 0xfff98793, 0x4c8994be, 0x00098463, 0x00198c93, - 0x00094503, 0x56fd8626, 0x8d13102c, 0x3ef50014, 0x0d9344c2, 0xc4850049, 0x866a84e6, - 0x56fda809, 0x8010102c, 0x00160913, 0x048536cd, 0xe8e3864a, 0x4701ff34, 0x0199e463, - 0x41998733, 0x896e9d3a, 0xb91584ea, 0x00490593, 0x8c00ca2e, 0x9363876e, 0x577d000d, - 0xe2918936, 0x974a8962, 0xc60387ca, 0xc2190007, 0x02f71463, 0x40d78cb3, 0x4008fd13, - 0x00a8f55b, 0x019df363, 0xf5938cee, 0xc82e0028, 0x4418f15b, 0x88b38626, 0xa831409c, - 0xbfc10785, 0x00160713, 0x102c56fd, 0xce468010, 0x36b5cc3a, 0x48f24762, 0x0733863a, - 0x63e30116, 0x4701ff37, 0x0199e463, 0x41998733, 0x001c8793, 0x0cb394ba, 0x872600f7, - 0x409706b3, 0xc50396ca, 0xc5190006, 0x000d0d63, 0xfffd8693, 0x000d9863, 0xc0b944c2, - 0x84b3863a, 0xa02d40ec, 0x08938db6, 0x863a0017, 0x102c56fd, 0x3e11cc46, 0x874648e2, - 0x56fdb7e1, 0x8010102c, 0x00160913, 0x3601c83a, 0x864a4742, 0x00c486b3, 0xff36e5e3, - 0xe4634681, 0x86b30199, 0x97364199, 0x84ba4952, 0x8c00b6b9, 0x0218e893, 0xc0468626, - 0x00490993, 0x886e48a1, 0x470147c1, 0x8800102c, 0xb1aff0ef, 0x84aa894e, 0x8414b62d, - 0xb3b547c1, 0xb3a547a1, 0xb3954789, 0x4bc002ef, 0xa05207b7, 0x0187a983, 0x09374481, - 0x4a05a052, 0xa0203ab7, 0x0209f85b, 0x01492683, 0x009a17b3, 0xfff7c713, 0x2a238f75, - 0x270300e9, 0xd6130189, 0x8fd94024, 0x0034f593, 0x99ca8513, 0x00f92c23, 0xa8bff0ef, - 0xd9930485, 0xe55b0019, 0xa979bd04, 0x482002ef, 0xa08004b7, 0x84205ccc, 0x9cc50513, - 0xa6bff0ef, 0xe7935cdc, 0xdcdc03f7, 0x02efa169, 0xa7ab4640, 0x8420803f, 0x051353ec, - 0xf0ef9f45, 0xa72ba4df, 0x537c803f, 0x0017e793, 0xa1a5d37c, 0x442002ef, 0xa01104b7, - 0x9073409c, 0x67893407, 0xa0112737, 0x28078793, 0x0793c35c, 0xc71c3f60, 0x474140dc, - 0x4727e793, 0x07b7c0dc, 0xcbd8a042, 0x08000713, 0x4739d7d8, 0xa223d398, 0x474d0207, - 0x471dd7d8, 0x17b7d798, 0x43d8a011, 0xfdf77713, 0x43d8c3d8, 0xe7f77713, 0x10076713, - 0x4798c3d8, 0xfdf77713, 0x4798c798, 0xe7f77713, 0x10076713, 0x43d8c798, 0xc3d88014, - 0x80144798, 0x07b7c798, 0xcdaba071, 0x43988aff, 0x7807275b, 0x4398c398, 0x14074063, - 0x06b74398, 0x8f558000, 0x4398c398, 0x12075863, 0x9b3d4398, 0x4398c398, 0x5247725b, - 0x67134398, 0xc3980107, 0xfb5b439c, 0x84201047, 0xa1c50513, 0x977ff0ef, 0x0ac48713, - 0x8420431c, 0x1007e793, 0xa583c31c, 0x05130ac4, 0xf0efa485, 0x842095df, 0xaa050513, - 0x953ff0ef, 0x05138420, 0xf0efab85, 0x960b949f, 0x56838a5f, 0x47850126, 0x0cd7ee63, - 0x07138030, 0x431c0f07, 0x869376c1, 0x8ff53ff6, 0x869366ad, 0x84204006, 0x05138fd5, - 0xc31cad45, 0x917ff0ef, 0x05138420, 0xf0efaf45, 0x679990df, 0xa0120737, 0xaa578793, - 0xcf1c8420, 0xb6050513, 0x7e600793, 0xa01104b7, 0xf0efcb1c, 0x40dc8edf, 0xf7938420, - 0xc0dcbff7, 0x051340dc, 0xe793b785, 0xc0dc4007, 0x8d3ff0ef, 0x05138420, 0xf0efb905, - 0x84938c9f, 0x409c0f04, 0xe0020737, 0x8ff9177d, 0x00080737, 0xc09c8fd9, 0xa0133737, - 0x8aefcfab, 0x007a17b7, 0x20078793, 0xa01336b7, 0x2c46a703, 0x0a07705b, 0xfbfd17fd, - 0x07138030, 0x431c0f07, 0x869376c1, 0x8ff53ff6, 0x66858420, 0x05138fd5, 0xc31cbc85, - 0xf0ef4489, 0xa059871f, 0x05138420, 0xf0efa6c5, 0xb721865f, 0xa0800737, 0x05b74b5c, - 0x15fdff00, 0xcb5c8fed, 0x82855b1c, 0x0077e793, 0x4b0cdb1c, 0xf593421c, 0x079ef605, - 0x424c8fcd, 0x059216fd, 0x460c8fcd, 0x058e8420, 0x464c8fcd, 0x01064603, 0x8fcd058a, - 0xcb1c8fd1, 0x0513433c, 0xf793b145, 0x8eddf007, 0xf0efc334, 0x842080df, 0xb2c50513, - 0x803ff0ef, 0x05138420, 0xb5f5b485, 0xf33d8b79, 0x05138420, 0x4481bac5, 0xfeaff0ef, - 0xe20007b7, 0x85a38004, 0x67f30007, 0x84203004, 0xbe850513, 0xfd2ff0ef, 0xe0ef454d, - 0x4561c4bf, 0xc45fe0ef, 0xe0ef4569, 0x456dc3ff, 0xc39fe0ef, 0x02100513, 0xc31fe0ef, - 0xaae18526, 0x0073c501, 0xbff51050, 0x80824505, 0xce061101, 0xca4acc26, 0x26f3c84e, - 0x67053420, 0xf7b3177d, 0xc66300e6, 0x44810406, 0x02e78863, 0xa0203937, 0xc7c90913, - 0xa02009b7, 0x012487b3, 0x0007c783, 0x00f10593, 0x59498513, 0x07a30485, 0xf0ef00f1, - 0xe35bf0ef, 0xa001bf94, 0x05138420, 0xf0efc605, 0x40f2f4cf, 0x495244e2, 0x610549c2, - 0x07138082, 0x68e30310, 0x0737fef7, 0x0713a020, 0x07db2007, 0x439c0cf7, 0xbff19782, - 0x0000a001, 0x82aac63d, 0xf31383b2, 0x9316fe03, 0x02655863, 0x41d44190, 0x45dc4598, - 0xc154c110, 0xc55cc518, 0x49d44990, 0x4ddc4d98, 0xc954c910, 0xcd5ccd18, 0x02058593, - 0x02050513, 0xfc654ce3, 0xffc3f313, 0x00530333, 0x00655863, 0x05914190, 0x0511c110, - 0xfe654ce3, 0x00728333, 0x00655a63, 0x0005c603, 0x00230585, 0x050500c5, 0xfe654ae3, - 0x80828516, 0x03b3832a, 0x769300c5, 0xce810035, 0xffc68693, 0x40d507b3, 0x06f3e463, - 0x00b50023, 0x9de30505, 0x0d63fea7, 0x05e20475, 0x0085d793, 0xd79395be, 0x95be0105, - 0x40a38633, 0x02000713, 0xfe067693, 0x00a687b3, 0x7693e285, 0xca8dffc6, 0x40d70633, - 0x00a687b3, 0x82058736, 0x00000697, 0x00c686b3, 0x00c68067, 0xcd0ccd4c, 0xc90cc94c, - 0xc50cc54c, 0xc10cc14c, 0x17e3953a, 0xbf6dfef5, 0x1de3879e, 0x851af875, 0x71398082, - 0xc66e4301, 0x7139a019, 0xc86a5341, 0xcc62ca66, 0xa019ce5e, 0x53017139, 0xd256d05a, - 0xd64ed452, 0xda26d84a, 0xde06dc22, 0x40610133, 0x11418282, 0xc226c04a, 0xc606c422, - 0x4db28282, 0x4d020141, 0x4c224c92, 0x01414bb2, 0x4a924b02, 0x49b24a22, 0x49020141, - 0x44224492, 0x014140b2, 0x00008082, 0xa0494701, 0x01065a93, 0x01051893, 0x0108d793, - 0xd7338141, 0xf5b30355, 0x18930355, 0xd6930106, 0x05c20108, 0x05338dc9, 0xbfb302d7, - 0x8e6300a5, 0x177d000f, 0xbfb395b2, 0x986300c5, 0xbfb3000f, 0x846300a5, 0x177d000f, - 0x8d8995b2, 0x0355f533, 0x0355d5b3, 0x8d5d0542, 0x02b686b3, 0x00d53fb3, 0x000f8e63, - 0x15fd9532, 0x00c53fb3, 0x000f9863, 0x00d53fb3, 0x000f8463, 0x15fd9532, 0x07428d15, - 0x80828dd9, 0xc0267179, 0xc44ec24a, 0xc856c652, 0xcc06ca22, 0x892e84aa, 0x8a3689b2, - 0xeac5843a, 0x01393fb3, 0x020f8e63, 0x00ef854e, 0xce2a4ab0, 0x99b3cd19, 0x089300a9, - 0x87b30200, 0xd7b340a8, 0x193300f4, 0x693300a9, 0x94b300f9, 0x852600a4, 0x864e85ca, - 0xd02e3f05, 0x478184aa, 0xa0b9d23e, 0x854ece21, 0x471000ef, 0xe519ce2a, 0x41390933, - 0xd23e4785, 0x02c0006f, 0x02000893, 0x40a88fb3, 0x00a999b3, 0xd733864e, 0x17b301f4, - 0x94b300a9, 0xe53300a4, 0x55b300e7, 0x35ed01f9, 0x892ad22e, 0x85ca8526, 0x3df9864e, - 0x84aad02e, 0x46f2c479, 0xd4b34901, 0xa87d00d4, 0x0339d933, 0x0339f4b3, 0x45014581, - 0xc004cc55, 0x01242223, 0x3fb3a855, 0x97e30149, 0x8552fe0f, 0x3fd000ef, 0xc955ce2a, - 0x02000893, 0x40a88733, 0x00e9d7b3, 0x00aa1633, 0x8a328e5d, 0x00a999b3, 0x00e4d6b3, - 0x00a494b3, 0x00a91533, 0x00e955b3, 0x3dad8d55, 0x892ad02e, 0x03358533, 0x0335b5b3, - 0x00b93fb3, 0x000f9863, 0x03259263, 0x00a4bfb3, 0x000f8e63, 0x85b35682, 0x16fd4145, - 0x06b3d036, 0x3fb34135, 0x85b300d5, 0x853641f5, 0xd2364681, 0x8533c80d, 0x05b340a4, - 0xbfb340b9, 0x85b300a4, 0x46f241f5, 0x02000893, 0x40d88733, 0x00e59933, 0x00d554b3, - 0x0124e4b3, 0x00d5d933, 0x2223c004, 0x55020124, 0x02412583, 0x49124482, 0x4a3249a2, - 0x44524ac2, 0x614540e2, 0x46818082, 0x012a3fb3, 0x000f9663, 0x0134bfb3, 0x000f9e63, - 0xd03e4785, 0x41348733, 0x41490933, 0x00e4bfb3, 0x41f90933, 0xa01184ba, 0xd236d036, - 0xbf65f855, 0xc0061141, 0x3d2d0058, 0x45a24512, 0x01414082, 0x00008082, 0x80000737, - 0x97138eb9, 0x11010015, 0xc24ac026, 0xc652c44e, 0xca06c856, 0x00169493, 0x800000b7, - 0x00973fb3, 0x000f9863, 0x02971063, 0x00c53fb3, 0x000f8c63, 0x8a2e89aa, 0x85b68532, - 0x86d2864e, 0x00159713, 0x00169493, 0xf6b38ead, 0x59130016, 0xda930157, 0x1a130154, - 0x999300a7, 0x079300a4, 0x80637ff0, 0x6fb31d27, 0x886300a7, 0xefb31a0f, 0x8e6300c4, - 0x04b3120f, 0xbf934159, 0x88630404, 0x5793120f, 0x6a330155, 0x052e00fa, 0x01565793, - 0x00f9e9b3, 0x3f93062e, 0x9d630029, 0x6a33040f, 0x8463001a, 0xe9b3000a, 0x87930019, - 0x9363fff4, 0x84be000a, 0x0893c0a1, 0x87b30200, 0x5c634098, 0x173300f0, 0x97b300f6, - 0xd9b300f9, 0x56330099, 0x8e5d0096, 0x04b3a829, 0x879340f0, 0x97330207, 0x8f5100f9, - 0x8726e091, 0x0099d633, 0xc3194981, 0x00266613, 0x1663c6e9, 0x14630159, 0x0f63013a, - 0x3fb310c5, 0x9863013a, 0x1d63000f, 0x3fb3013a, 0x896300c5, 0x197d000f, 0x01f99713, - 0x0019d993, 0x8e598205, 0x8d11872a, 0x00a73fb3, 0x41fa0a33, 0x413a0a33, 0x00293f93, - 0x0a0f9263, 0x020a1563, 0x02093f93, 0x020f9163, 0x45018a2a, 0x1c631901, 0xa8310009, - 0x0c63197d, 0x57130009, 0x0a0601f5, 0x6a330506, 0x3fb300ea, 0x95e3001a, 0x0513fe0f, - 0x3f934005, 0x9a7e4005, 0x01fa3fb3, 0x5793997e, 0x8b8500b5, 0x8d1d84aa, 0x00a4bfb3, - 0x41fa0a33, 0x17930a06, 0x5a13014a, 0x812d00ca, 0x17938d5d, 0x6a330149, 0xf5b300fa, - 0xe5b30015, 0x44820145, 0x49a24912, 0x4ac24a32, 0x610540d2, 0x95328082, 0x00c53fb3, - 0x3fb39a7e, 0x9a4e01fa, 0x000f9f63, 0x013a3fb3, 0x000f9b63, 0xf8091be3, 0x1713812d, - 0x5a13015a, 0x8d5900ba, 0x0893bf7d, 0x87b37fe0, 0xc3854128, 0x00157f93, 0x00256793, - 0x000f8363, 0x1713853e, 0x5a1301fa, 0x8105001a, 0x09058d59, 0x4501bfb9, 0x7ff00a37, - 0xdad1b779, 0x45814501, 0x6a33b779, 0x156300aa, 0x92e3001a, 0xd2c1f957, 0x05b74501, - 0xbfa5fff8, 0xc0261101, 0xc44ec24a, 0xc856c652, 0xcc0eca22, 0x1141ce06, 0x00159713, - 0x99138355, 0x549300b5, 0x69330155, 0x14930099, 0x043700b5, 0x97938000, 0x83d50016, - 0x00b69a13, 0x01565993, 0x013a6a33, 0x00b61993, 0xfab38ead, 0x06930086, 0xcb6d7ff0, - 0x14e68e63, 0x00896933, 0x18078d63, 0x16f68463, 0x008a6a33, 0x8513c656, 0x972ac027, - 0x034936b3, 0x03490633, 0x0344b5b3, 0x03448533, 0x00b60a33, 0x00ba3fb3, 0x01f68ab3, - 0x033936b3, 0x03390633, 0x00a60933, 0x00a93fb3, 0x3fb39a7e, 0x9afe01fa, 0x3fb39a36, - 0x9afe00da, 0x0334b5b3, 0x03348533, 0x3fb3992e, 0x9a7e00b9, 0x01fa3fb3, 0x01fa85b3, - 0x00a96933, 0x001a6513, 0x00091363, 0xaf938552, 0x99630005, 0x8faa000f, 0x3fb3952a, - 0x95ae01f5, 0x177d95fe, 0x5c634ab2, 0x089314e0, 0x87b37ff0, 0x5d6340e8, 0x05130cf0, - 0x3f934005, 0x86634005, 0x95fe000f, 0x01f5bfb3, 0x5613977e, 0x8a0500b5, 0x812d8d11, - 0x01559613, 0x05868d51, 0x179381b1, 0x8ddd0147, 0x0155e5b3, 0x44820141, 0x49a24912, - 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, 0x00996fb3, 0x040f8563, 0x01f4df93, - 0x997e994a, 0x156394a6, 0x89260009, 0x17014481, 0x85ca4501, 0x95aea019, 0xbfb30505, - 0x9ce30085, 0x05e3fe0f, 0x8f09ee05, 0x02000893, 0x40a88633, 0x00c4d633, 0x00a494b3, - 0x00a91933, 0x00c96933, 0x8363b5f1, 0x85d604f6, 0x44820141, 0x49a24912, 0x4ac24a32, - 0x41e24452, 0x610540f2, 0x00008067, 0x00996933, 0x02891263, 0x1613e791, 0x6633001a, - 0xca190136, 0x00f69663, 0x013a6a33, 0x008a1663, 0x05b74501, 0xbf897ff0, 0x05b74501, - 0x0141fff8, 0x49124482, 0x4a3249a2, 0x44524ac2, 0x40f241e2, 0x80676105, 0x65330000, - 0xdd51013a, 0x01f9df93, 0x9a7e9a52, 0x156399ce, 0x8a4e000a, 0x17814981, 0x85d24501, - 0x95aea019, 0xbfb30505, 0x9ce30085, 0x03e3fe0f, 0x8f89e405, 0x02000893, 0x40a88633, - 0x00c9d633, 0x00a999b3, 0x00aa1a33, 0x00ca6a33, 0x4481b525, 0x86b34885, 0xbf9340e8, - 0x9b630206, 0x84aa000f, 0x4581852e, 0xc5091681, 0x0206bf93, 0x020f8d63, 0x0893c29d, - 0x86330200, 0x993340d8, 0x17b300c5, 0x553300c5, 0xd5b300d5, 0x653300d5, 0x8cdd0125, - 0x6513c099, 0x05130015, 0x3f934005, 0x95fe4005, 0x01f5d713, 0x4501bd9d, 0x0000bded, - 0xc0261101, 0xc44ec24a, 0xc856c652, 0xcc0eca22, 0x1141ce06, 0x00159713, 0x99138355, - 0x549300b5, 0x69330155, 0x14930099, 0x043700b5, 0x97938000, 0x83d50016, 0x00b69a13, - 0x01565993, 0x013a6a33, 0x00b61993, 0xfab38ead, 0x06930086, 0x08637ff0, 0x84632207, - 0x69332ce6, 0x8d630089, 0x85632e07, 0x6a332ef6, 0x8f1d008a, 0x3ff70713, 0x15938085, - 0x8ccd01f9, 0x00195913, 0x010a5613, 0x02c956b3, 0x02c97933, 0x010a1893, 0x0108d593, - 0x02d587b3, 0xd5130942, 0x69330104, 0x854a00a9, 0x40f90933, 0x01253fb3, 0x000f8863, - 0x995216fd, 0x01493fb3, 0xfe0f8ce3, 0x02c95833, 0x02c97933, 0x87b38642, 0x094202c5, - 0x01049893, 0x0108d513, 0x00a96933, 0x0933854a, 0x3fb340f9, 0x88630125, 0x167d000f, - 0x3fb39952, 0x8ce30149, 0x06c2fe0f, 0xb5b396b2, 0x85330336, 0x04b30336, 0x854a40a0, - 0x40b90933, 0x01253fb3, 0x854ac499, 0x9663197d, 0x3fb3000f, 0x81630125, 0x16fd020f, - 0xb53394ce, 0x99520134, 0x01493fb3, 0x0905c511, 0x000f9663, 0x00193f93, 0xfe0f83e3, - 0x01491763, 0x892685ce, 0x45014601, 0x5593a041, 0x5633010a, 0x793302b9, 0x189302b9, - 0xd513010a, 0x0fb30108, 0x094202c5, 0x0104d793, 0x00f96933, 0x093387ca, 0xbfb341f9, - 0x88630127, 0x167d000f, 0x3fb39952, 0x8ce30149, 0x5833fe0f, 0x793302b9, 0x85c202b9, - 0x02b507b3, 0x98930942, 0xd5130104, 0x69330108, 0x854a00a9, 0x40f90933, 0x01253fb3, - 0x000f8863, 0x995215fd, 0x01493fb3, 0xfe0f8ce3, 0x962e0642, 0x033635b3, 0x03360533, - 0x40a004b3, 0x0933854a, 0x3fb340b9, 0xc4990125, 0x197d854a, 0x000f9663, 0x01253fb3, - 0x020f8163, 0x94ce167d, 0x0134b533, 0x3fb39952, 0xc5110149, 0x96630905, 0x3f93000f, - 0x83e30019, 0xaf93fe0f, 0x99630006, 0x8fb2000f, 0x3fb39632, 0x96b601f6, 0x177d96fe, - 0x00996933, 0x00166513, 0x00091363, 0x85b68532, 0x16e05f63, 0x7ff00893, 0x40e887b3, - 0x0ef05b63, 0x40050513, 0x40053f93, 0x000f8663, 0xbfb395fe, 0x977e01f5, 0x00b55613, - 0x8d118a05, 0x9613812d, 0x8d510155, 0x81b10586, 0x01471793, 0xe5b38ddd, 0x01410155, - 0x49124482, 0x4a3249a2, 0x44524ac2, 0x40f241e2, 0x80676105, 0x6fb30000, 0x85630099, - 0xdf93040f, 0x994a01f4, 0x94a6997e, 0x00091563, 0x44818926, 0x45011701, 0xa01985ca, - 0x050595ae, 0x0085bfb3, 0xfe0f9ce3, 0xda0507e3, 0x08938f09, 0x86330200, 0xd63340a8, - 0x94b300c4, 0x193300a4, 0x693300a9, 0xbb4100c9, 0x02f68463, 0x6fb3e789, 0x8363013a, - 0x85d6020f, 0x44820141, 0x49a24912, 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, - 0x013a6a33, 0xfe8a01e3, 0x05b74501, 0x0141fff8, 0x49124482, 0x4a3249a2, 0x44524ac2, - 0x40f241e2, 0x80676105, 0x69330000, 0x1fe30099, 0x8de3fc89, 0x4501fcf6, 0x7ff005b7, - 0x0155e5b3, 0x44820141, 0x49a24912, 0x4ac24a32, 0x41e24452, 0x610540f2, 0x00008067, - 0x013a6a33, 0xfa8a18e3, 0xb7614501, 0x013a6fb3, 0xfc0f87e3, 0x01f9df93, 0x9a7e9a52, - 0x156399ce, 0x8a4e000a, 0x17814981, 0x85d24501, 0x95aea019, 0xbfb30505, 0x9ce30085, - 0x02e3fe0f, 0x8f89ce05, 0x02000893, 0x40a88633, 0x00c9d633, 0x00a999b3, 0x00aa1a33, - 0x00ca6a33, 0x4481b1d9, 0x86b34885, 0xbf9340e8, 0x9b630206, 0x84aa000f, 0x4581852e, - 0xc5091681, 0x0206bf93, 0x020f8d63, 0x0893c29d, 0x86330200, 0x993340d8, 0x17b300c5, - 0x553300c5, 0xd5b300d5, 0x653300d5, 0x8cdd0125, 0x6513c099, 0x05130015, 0x3f934005, - 0x95fe4005, 0x01f5d713, 0x4501bd81, 0x9693bdf9, 0x571300b5, 0x8ed90155, 0x80000737, - 0x97138ed9, 0x83550015, 0x41e00893, 0x40e88633, 0x02c05363, 0x02000713, 0x00e63fb3, - 0x000f9363, 0xd6b34681, 0xaf9300c6, 0x84630005, 0x06b3000f, 0x853640d0, 0xc1198082, - 0x0015e593, 0x7ff00737, 0x00b73fb3, 0x000f8563, 0x80000537, 0x05378082, 0x157d8000, - 0x00008082, 0x00b59693, 0x01555713, 0x07378ed9, 0x8ed98000, 0x00159713, 0x08938355, - 0x863341e0, 0x2f9340e8, 0x93630006, 0x0713020f, 0x3fb30200, 0x936300e6, 0x4681000f, - 0x00c6d6b3, 0x0005af93, 0x000f8463, 0x40d006b3, 0x80828536, 0xe593c119, 0x07370015, - 0x3fb37ff0, 0x856300b7, 0x0537000f, 0x80828000, 0x8082557d, 0xc0261141, 0x4581c206, - 0x86ae87ae, 0xc239862a, 0x00062f93, 0x000f8a63, 0x800007b7, 0x40c00633, 0x05b3c581, - 0x167d40b0, 0x41e00693, 0xc02a1141, 0xc432c22e, 0x1141c636, 0x8532c03e, 0x872a2215, - 0x01414782, 0x45924502, 0x46b24622, 0x8e990141, 0x00e61633, 0x00b5d713, 0x01561493, - 0x14938f45, 0x80b10016, 0x94938fc5, 0x8fc50146, 0x85be853a, 0x40924482, 0x80820141, - 0xc0261141, 0x4581c206, 0x862a86ae, 0x0693c60d, 0x110141e0, 0xc22ec02a, 0xc636c432, - 0x8532c83a, 0x87aa20e1, 0x45924502, 0x46b24622, 0x61054742, 0x16338e9d, 0xd71300f6, - 0x149300b5, 0x8f450156, 0x00161793, 0x949383b1, 0x8fc50146, 0x85be853a, 0x40924482, - 0x80820141, 0xa011577d, 0x47814705, 0xffe00e37, 0x00159293, 0x00a7bfb3, 0x01f28eb3, - 0x01de3fb3, 0x060f9863, 0x00169393, 0x00c7bfb3, 0x01f38eb3, 0x01de3fb3, 0x040f9e63, - 0x00d5c733, 0x04074063, 0x0005af93, 0x000f9f63, 0x40c50733, 0x00e53fb3, 0x40d58533, - 0x41f50533, 0x00e7bfb3, 0x857ee111, 0x07338082, 0x3fb340a6, 0x853300e6, 0x053340b6, - 0xbfb341f5, 0xe11100e7, 0x8082857e, 0x0072e7b3, 0x00c56733, 0xc7818fd9, 0xc1914505, - 0x8082852e, 0x8082853a, 0x736367c1, 0x079302f5, 0x07130ff0, 0xe9630200, 0x37b704a7, - 0x8793a020, 0x97aace87, 0x0007c503, 0x40a70533, 0x00008067, 0x010007b7, 0x00f57e63, - 0xa02037b7, 0x87938141, 0x97aace87, 0x0007c503, 0x05334741, 0x808240a7, 0xa02037b7, - 0x87938161, 0x97aace87, 0x0007c503, 0x05334721, 0x808240a7, 0xa02037b7, 0x87938121, - 0x97aace87, 0x0007c503, 0x05334761, 0x808240a7, 0x00e688b3, 0x02000513, 0xa0200537, - 0xa02036b7, 0xfd6a8513, 0x0ff77713, 0x00092683, 0xa02037b7, 0x0007c703, 0x00176713, - 0x00688023, 0x0208e893, 0x020c8493, 0x020c8593, 0x0ff57513, 0x0ff7f793, 0x40d606b3, - 0xa0110737, 0xa0203537, 0xa02007b7, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0xffffffff, 0x7fefffff, 0xffffffff, 0xffefffff, 0x509f79fb, 0x3fd34413, - 0x8b60c8b3, 0x3fc68a28, 0x00000000, 0x3ff80000, 0x636f4361, 0x3fd287a7, 0x0979a371, - 0x400a934f, 0x00000000, 0x3fe00000, 0xbbb55516, 0x40026bb1, 0xfefa39ef, 0x3fe62e42, - 0x00000000, 0x402c0000, 0x00000000, 0x40240000, 0x00000000, 0x40180000, 0x00000000, - 0x40000000, 0x00000000, 0x3ff00000, 0xeb1c432d, 0x3f1a36e2, 0x00000000, 0x412e8480, - 0x00696e66, 0x2b696e66, 0x00000000, 0x006e616e, 0x2d696e66, 0x00000000, 0x00000000, - 0x41cdcd65, 0x00000000, 0xc1cdcd65, 0x6c756e28, 0x0000296c, 0xa020126c, 0xa020107e, - 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, - 0xa020107e, 0xa020126c, 0xa0201394, 0xa020126c, 0xa0201238, 0xa0201374, 0xa0201238, - 0xa020107e, 0xa020126c, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, 0xa020107e, - 0xa020126c, 0xa02014f6, 0xa020107e, 0xa020107e, 0xa0201410, 0xa020107e, 0xa020126c, - 0xa020107e, 0xa020107e, 0xa020126c, 0x666e695b, 0x67205d6f, 0x203a7470, 0x20717269, - 0x65636572, 0x64657669, 0x206e6f20, 0x656d6974, 0x75252072, 0x6863202c, 0x0d752520, - 0x0000000a, 0x666e695b, 0x73205d6f, 0x203a6970, 0x20717269, 0x65636572, 0x64657669, - 0x6f63202c, 0x203a6564, 0x78257830, 0x00000a0d, 0x666e695b, 0x67205d6f, 0x3a6f6970, - 0x71726920, 0x63657220, 0x65766965, 0x76202c64, 0x203a6c61, 0x58257830, 0x00000a0d, - 0x666e695b, 0x6f205d6f, 0x203a6566, 0x47504665, 0x6e612041, 0x43502064, 0x65522042, - 0x20746573, 0x65737341, 0x64657472, 0x00000a0d, 0x666e695b, 0x73205d6f, 0x203a7563, - 0x6c6f7349, 0x6f697461, 0x664f5f6e, 0x203d2066, 0x78257830, 0x00000a0d, 0x7272655b, - 0x205d726f, 0x3a65666f, 0x72724520, 0x4120726f, 0x72657373, 0x676e6974, 0x50466520, - 0x202c4147, 0x20424350, 0x65736552, 0x0a0d7374, 0x00000000, 0x666e695b, 0x78205d6f, - 0x203a4243, 0x74696e49, 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x71205d6f, 0x3a697073, - 0x696e4920, 0x74732074, 0x0d747261, 0x0000000a, 0x7665735b, 0x5d657265, 0x70737120, - 0x49203a69, 0x2074696e, 0x6c696166, 0x0a0d6465, 0x00000000, 0x7665735b, 0x5d657265, - 0x616c6620, 0x203a6873, 0x74696e49, 0x69616620, 0x0d64656c, 0x0000000a, 0x666e695b, - 0x71205d6f, 0x3a697073, 0x696e4920, 0x4b4f2074, 0x00000a0d, 0x666e695b, 0x66205d6f, - 0x6873616c, 0x6e49203a, 0x73207469, 0x74726174, 0x00000a0d, 0x666e695b, 0x66205d6f, - 0x6873616c, 0x6e49203a, 0x4f207469, 0x000a0d4b, 0x666e695b, 0x77205d6f, 0x203a7464, - 0x74696e49, 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x64205d6f, 0x203a616d, 0x74696e49, - 0x0d4b4f20, 0x0000000a, 0x666e695b, 0x63205d6f, 0x74707972, 0x49203a6f, 0x2074696e, - 0x72617473, 0x000a0d74, 0x666e695b, 0x63205d6f, 0x74707972, 0x49203a6f, 0x2074696e, - 0x0a0d4b4f, 0x00000000, 0x7665735b, 0x5d657265, 0x79726320, 0x3a6f7470, 0x696e4920, - 0x61662074, 0x64656c69, 0x00000a0d, 0x666e695b, 0x69205d6f, 0x7265746e, 0x74707572, - 0x49203a73, 0x2074696e, 0x0a0d4b4f, 0x00000000, 0x666e695b, 0x66205d6f, 0x3a6c6273, - 0x696e4920, 0x74732074, 0x0d747261, 0x0000000a, 0x666e695b, 0x66205d6f, 0x3a6c6273, - 0x696e4920, 0x75532074, 0x73656363, 0x000a0d73, 0x7665735b, 0x5d657265, 0x62736620, - 0x49203a6c, 0x2074696e, 0x6c696146, 0x0a0d6465, 0x00000000, 0x666e695b, 0x77205d6f, - 0x203a7464, 0x20717269, 0x65636572, 0x64657669, 0x00000a0d, 0x78450a0d, 0x74706563, - 0x2e6e6f69, 0x636f4c20, 0x676e696b, 0x0d2e2e2e, 0x0000000a, 0x00000000, 0x3ff00000, - 0x00000000, 0x40240000, 0x00000000, 0x40590000, 0x00000000, 0x408f4000, 0x00000000, - 0x40c38800, 0x00000000, 0x40f86a00, 0x00000000, 0x412e8480, 0x00000000, 0x416312d0, - 0x00000000, 0x4197d784, 0x00000000, 0x41cdcd65, 0x02020100, 0x03030303, 0x04040404, - 0x04040404, 0x05050505, 0x05050505, 0x05050505, 0x05050505, 0x06060606, 0x06060606, - 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x06060606, 0x07070707, - 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, - 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, 0x07070707, - 0x07070707, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, - 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, - 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, - 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, - 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0x08080808, 0xa0510000, 0xa0130000, - 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xa0600000, 0x000000ff, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00020000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x37c2cac9, 0x8c32e765, 0xa15e1200, 0x25c486b2, - 0x8734d7b4, 0xfa26c29d, 0x2ff972ae, 0x0adebf22, 0xff6f29e6, 0x3c50778d, 0xfa02d8da, - 0x78600d02, 0xbca88565, 0x163ca9be, 0x73f0da10, 0x3ed20b1c, 0xcce46d11, 0x2a49278f, - 0x12248db6, 0xe50b6755, 0xa431193c, 0x6c308699, 0xe0c41dbf, 0x50c791fe, 0xd3f876b9, - 0x7cf1df93, 0x16941322, 0xaa1ead8f, 0xe3753f54, 0xc9bb7bcc, 0x79200bff, 0x7d76c2d4, - 0xa7acc7f7, 0xff567a99, 0xbfa4f5dc, 0x064238c8, 0xe9699208, 0xa6b5daf3, 0xa3a2ad30, - 0x32bafe37, 0x54e1dacb, 0xda540799, 0x95547760, 0x302cd650, 0x9d428238, 0x62bbdadd, - 0xe531a353, 0x282e8f7d, 0x973e7ba1, 0x0dd65973, 0x4ab77a02, 0x53ca63ae, 0x176010c2, - 0x58bc890d, 0x025f55f8, 0x0e1e579b, 0xe19cdb04, 0x4bb6caf5, 0xad438b2c, 0xeda4466b, - 0x3cabf8dc, 0x0785aca7, 0xd0350f09, 0x79cac3c1, 0x00010001, 0x00000000, 0x00000000, - 0x00000000, 0xbb83b022, 0x95ebceca, 0x65fa7889, 0x3092c012, 0x9fcf0e0d, 0x88b9f5da, - 0xde074aae, 0xe06efe7f, 0x2caeace7, 0xa73adfae, 0xec7820db, 0xadf063a8, 0xe8bf5d84, - 0xd9dfe2c6, 0x746e5076, 0x45854a56, 0xdaa7c7d7, 0x63b79c9d, 0xb164694f, 0x69fa5ab0, - 0xc9ec14f7, 0xd6eac96f, 0x2b3ea0f2, 0xfd059077, 0x61dfb118, 0xf1f2951b, 0xf1c77f79, - 0xd16e9614, 0xb68ea35a, 0xd1ad833c, 0x8bed955a, 0xbb987f4b, 0x7f3c4c05, 0xfda5448b, - 0xec0591e4, 0xa844ae64, 0x392e6acc, 0x14e86521, 0x3f7fbd46, 0x4542bb46, 0x917fb21f, - 0x5a670490, 0x24cb8fee, 0xf720c30d, 0x377276bb, 0x782292ff, 0x5d14ddf0, 0x26c96e27, - 0x6db31b9a, 0x3301a1cf, 0xc70b0fdc, 0x231fe84d, 0xb0d83ebd, 0x0af5374a, 0x3e99435f, - 0x25aaa297, 0xcceec8a7, 0x2b4169ce, 0x67a065bc, 0x647152e6, 0x72b519ea, 0x81ffa154, - 0xee1d6e39, 0x166c4034 -}; + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x37c2cac9, 0x8c32e765, 0xa15e1200, 0x25c486b2, 0x8734d7b4, + 0xfa26c29d, 0x2ff972ae, 0x0adebf22, 0xff6f29e6, 0x3c50778d, 0xfa02d8da, 0x78600d02, + 0xbca88565, 0x163ca9be, 0x73f0da10, 0x3ed20b1c, 0xcce46d11, 0x2a49278f, 0x12248db6, + 0xe50b6755, 0xa431193c, 0x6c308699, 0xe0c41dbf, 0x50c791fe, 0xd3f876b9, 0x7cf1df93, + 0x16941322, 0xaa1ead8f, 0xe3753f54, 0xc9bb7bcc, 0x79200bff, 0x7d76c2d4, 0xa7acc7f7, + 0xff567a99, 0xbfa4f5dc, 0x064238c8, 0xe9699208, 0xa6b5daf3, 0xa3a2ad30, 0x32bafe37, + 0x54e1dacb, 0xda540799, 0x95547760, 0x302cd650, 0x9d428238, 0x62bbdadd, 0xe531a353, + 0x282e8f7d, 0x973e7ba1, 0x0dd65973, 0x4ab77a02, 0x53ca63ae, 0x176010c2, 0x58bc890d, + 0x025f55f8, 0x0e1e579b, 0xe19cdb04, 0x4bb6caf5, 0xad438b2c, 0xeda4466b, 0x3cabf8dc, + 0x0785aca7, 0xd0350f09, 0x79cac3c1, 0x00010001, 0x00000000, 0x00000000, 0x00000000, + 0xebe1a78f, 0x2e6e03ed, 0x4ee1354e, 0x2052aa4d, 0xbb4cb958, 0x230e0232, 0x862cb015, + 0x58dee9e7, 0xfde8f54e, 0xc96e44be, 0x607271f8, 0x983ecea7, 0xe8770c08, 0x0dc7599b, + 0x590e8ff8, 0x690188e6, 0x66dfaf5e, 0xf6335a68, 0x2c0b118f, 0x3733a790, 0x9c938f42, + 0x3ce28852, 0x2c74cda7, 0x7dad40de, 0xe7a80299, 0xa3e92677, 0x4b328cd7, 0x760976e1, + 0x92a152e4, 0x4225f6c3, 0xb3d87236, 0x43a9be7e, 0xbbb12076, 0x66433975, 0x353e3019, + 0x010926e2, 0x00d08453, 0x045cfcd6, 0xc763d656, 0xe873faee, 0xb1fc2dc1, 0x0530f6e3, + 0x7064e3ff, 0xc6062a2f, 0xe1a3d120, 0xf728ad4f, 0xa7159b1e, 0x8f3e3a92, 0x97be047f, + 0x75a4d27b, 0x5fc4d749, 0x194d52ce, 0x0199ccba, 0x0de3e3ec, 0x830b6dd5, 0xff35543e, + 0x5b0b9d15, 0x8258edb7, 0xfee5009e, 0xed692f55, 0x5fbe279a, 0x9fa66ee6, 0x3913674d, + 0x671285c3}; struct rs_bop_header { - uint32_t bop_id; - uint16_t bop_hdr_version; - uint16_t sign_tool_version; - uint32_t binary_version; - uint32_t binary_len; - uint32_t load_addr; - uint32_t entry_addr; - uint32_t offset_to_binary; - uint32_t offset_to_next_header; - uint8_t sig_algo; - uint8_t option; - uint8_t enc_algo; - uint8_t iv_len; - uint16_t pub_key_len; - uint16_t enc_key_len; - uint16_t sig_len; - uint8_t compression_algo; - uint8_t bin_pad_bytes; // Number of padding bytes in the payload binary or - // bitstream - uint16_t xcb_header_size; - uint8_t padding[16]; // To make BOP header 64 bytes for scatter gather hash - // calculation - uint16_t crc_16; + uint32_t bop_id; + uint16_t bop_hdr_version; + uint16_t sign_tool_version; + uint32_t binary_version; + uint32_t binary_len; + uint32_t load_addr; + uint32_t entry_addr; + uint32_t offset_to_binary; + uint32_t offset_to_next_header; + uint8_t sig_algo; + uint8_t option; + uint8_t enc_algo; + uint8_t iv_len; + uint16_t pub_key_len; + uint16_t enc_key_len; + uint16_t sig_len; + uint8_t compression_algo; + uint8_t bin_pad_bytes; // Number of padding bytes in the payload binary or + // bitstream + uint16_t xcb_header_size; + uint8_t padding[16]; // To make BOP header 64 bytes for scatter gather hash + // calculation + uint16_t crc_16; }; void pufs_rsa2048_verify_test(const struct device *pufs) @@ -1119,16 +741,15 @@ void pufs_rsa2048_verify_test(const struct device *pufs) struct sign_ctx lvSignCtx = {0}; struct sign_pkt lvSignPkt = {0}; - uint32_t pub_key_padding = 12; + uint32_t pub_key_padding = 12; - struct rs_bop_header *bop_hdr = (struct rs_bop_header *)bop_image_addr; + struct rs_bop_header *bop_hdr = (struct rs_bop_header *)bop_rsa_image_addr; - uint8_t *pub_key = (uint8_t *)bop_image_addr + bop_hdr->offset_to_binary + - bop_hdr->binary_len + bop_hdr->iv_len; - uint8_t *sig = - (uint8_t *)pub_key + bop_hdr->pub_key_len + pub_key_padding; + uint8_t *pub_key = (uint8_t *)bop_rsa_image_addr + bop_hdr->offset_to_binary + + bop_hdr->binary_len + bop_hdr->iv_len; + uint8_t *sig = (uint8_t *)pub_key + bop_hdr->pub_key_len + pub_key_padding; - printf("Bop_Binary_1st_Word:0x%08x\n", *(uint32_t*)bop_hdr); + printf("Bop_Binary_1st_Word:0x%08x\n", *(uint32_t *)bop_hdr); lvSignCtx.app_sessn_state = NULL; lvSignCtx.device = pufs; @@ -1141,7 +762,7 @@ void pufs_rsa2048_verify_test(const struct device *pufs) lvSignPkt.ctx = &lvSignCtx; lvSignPkt.in_buf = (uint8_t *)bop_hdr; - lvSignPkt.in_len = bop_hdr->binary_len+sizeof(struct rs_bop_header)+272; + lvSignPkt.in_len = bop_hdr->binary_len + sizeof(struct rs_bop_header) + 272; lvSignPkt.next = NULL; lvStatus = sign_begin_session(pufs, &lvSignCtx, CRYPTO_SIGN_ALGO_RSA2048); @@ -1195,8 +816,8 @@ int main(void) const struct device *pufs_otp = DEVICE_DT_GET(DT_NODELABEL(pufs_otp)); if ((pufs == NULL) || (!device_is_ready(pufs))) { - printf("%s pufs has status disabled or driver is not initialized...%s\n",\ - ATTR_ERR, ATTR_RST); + printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, + ATTR_RST); } else { printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); pufs_decryption_test(pufs); From 21ffcbf874e05a65f6d03090bafa819392ba1151 Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 22 Oct 2024 18:42:27 +0500 Subject: [PATCH 55/58] EC256 Unit test Created. To Fix PUFcc Driver with Manual word size copy --- drivers/crypto/crypto_pufs.c | 15 ++-- samples/hello_world/src/main.c | 121 ++++++++++++++++++++++++++++++--- 2 files changed, 119 insertions(+), 17 deletions(-) diff --git a/drivers/crypto/crypto_pufs.c b/drivers/crypto/crypto_pufs.c index e19095af916bc..b69e76e5715bb 100644 --- a/drivers/crypto/crypto_pufs.c +++ b/drivers/crypto/crypto_pufs.c @@ -511,20 +511,23 @@ int pufs_sign_rsa_op(struct sign_ctx *ctx, struct sign_pkt *pkt) int pufs_sign_ecdsa_op(struct sign_ctx *ctx, struct sign_pkt *pkt) { + int error = 0; enum pufcc_status lvStatus = PUFCC_SUCCESS; ((struct pufs_data*)ctx->device->data)->pufs_pkt.sign_pkt = pkt; ((struct pufs_data*)ctx->device->data)->pufs_ctx.sign_ctx = ctx; - struct rs_crypto_addr msg_addr = { - .read_addr = (uint32_t)pkt->in_buf, - .len = pkt->in_len, - .next = NULL - }; + struct rs_crypto_addr msg_addr[(BUFFER_SIZE/sizeof(struct rs_crypto_addr))] = {0}; + + error = fill_rs_crypto_sign_addr(pkt, msg_addr); + + if(error != PUFCC_SUCCESS) { + return error; + } lvStatus = pufcc_ecdsa256_sign_verify( (struct rs_crypto_ec256_sig *)ctx->sig, - &msg_addr, + msg_addr, (struct rs_crypto_ec256_puk *)ctx->pub_key ); diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index 3255bb696d767..e96bf6801f2fb 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -636,6 +636,63 @@ void pufs_decryption_test(const struct device *pufs) } } +const uint32_t bop_ec256_image_addr[] = { + 0x4c425346, 0x00010001, 0x00000001, 0x00000540, 0xa020005c, 0xa020005c, 0x00000040, + 0x00000000, 0x00000010, 0x00000040, 0x00000040, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x5bef0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x5a41e854, 0xbd7831f5, 0x8a722abc, 0x0f194645, 0xfca0b124, + 0x4c32ac0f, 0x119da725, 0x017d57f0, 0xc3c72358, 0xf5a403c4, 0x35f48b62, 0xe3bcf592, + 0xe0ae8930, 0xe0ef26dc, 0xad99438b, 0xbc0b8b9e, 0xf746712e, 0x36b64de7, 0x1b2dd12b, + 0x016f428d, 0xa6375c54, 0xb19e1329, 0x29abce2e, 0x01d2ef46, 0x4522360f, 0x4646a2b0, + 0x4b9e632d, 0x65bd20b3, 0xa9a48e98, 0x78cdc0d2, 0xb80be124, 0x72e406e9}; + const uint32_t bop_rsa_image_addr[] = { 0x4c425346, 0x00010001, 0x00000001, 0x00000540, 0xa020005c, 0xa020005c, 0x00000040, 0x00000000, 0x00000020, 0x00000104, 0x00000100, 0x00000000, 0x00000000, 0x00000000, @@ -749,8 +806,6 @@ void pufs_rsa2048_verify_test(const struct device *pufs) bop_hdr->binary_len + bop_hdr->iv_len; uint8_t *sig = (uint8_t *)pub_key + bop_hdr->pub_key_len + pub_key_padding; - printf("Bop_Binary_1st_Word:0x%08x\n", *(uint32_t *)bop_hdr); - lvSignCtx.app_sessn_state = NULL; lvSignCtx.device = pufs; lvSignCtx.drv_sessn_state = NULL; @@ -767,30 +822,73 @@ void pufs_rsa2048_verify_test(const struct device *pufs) lvStatus = sign_begin_session(pufs, &lvSignCtx, CRYPTO_SIGN_ALGO_RSA2048); if (lvStatus != 0) { - printf("\n%ssign_begin_session Failed! %s\n", ATTR_ERR, ATTR_RST); + printf("\n%ssign_begin_session RSA2048 Failed! %s\n", ATTR_ERR, ATTR_RST); } else { - printf("%ssign_begin_session Success! %s\n", ATTR_INF, ATTR_RST); - printf("\n%sin_buf_addr:0x%08x in_buf_len:%d bytes %s\n", ATTR_INF, - (uint32_t)lvSignPkt.in_buf, lvSignPkt.in_len, ATTR_RST); + printf("%ssign_begin_session RSA2048 Success! %s\n", ATTR_INF, ATTR_RST); lvStatus = sign_op_handler(&lvSignCtx, &lvSignPkt); } if (lvStatus != 0) { - printf("%s sign_op_handler Failed! Status:%d %s\n", ATTR_ERR, lvStatus, ATTR_RST); + printf("%s sign_op_handler RSA2048 Failed! Status:%d %s\n", ATTR_ERR, lvStatus, ATTR_RST); } else { - printf("%s sign_op_handler Success! %s\n", ATTR_INF, ATTR_RST); + printf("%s sign_op_handler RSA2048 Success! %s\n", ATTR_INF, ATTR_RST); } lvStatus = sign_free_session(pufs, &lvSignCtx); if (lvStatus != 0) { - printf("%s sign_free_session Failed! %s\n", ATTR_ERR, ATTR_RST); + printf("%s sign_free_session RSA2048 Failed! %s\n", ATTR_ERR, ATTR_RST); } else { - printf("%s sign_free_session Success! %s\n", ATTR_INF, ATTR_RST); + printf("%s sign_free_session RSA2048 Success! %s\n", ATTR_INF, ATTR_RST); } } -void pufs_ecdsa256_verify_test(const struct device *dev) +void pufs_ecdsa256_verify_test(const struct device *pufs) { + int lvStatus = 0; + + struct sign_ctx lvSignCtx = {0}; + struct sign_pkt lvSignPkt = {0}; + + struct rs_bop_header *bop_hdr = (struct rs_bop_header *)bop_ec256_image_addr; + + uint8_t *pub_key = (uint8_t *)bop_ec256_image_addr + bop_hdr->offset_to_binary + + bop_hdr->binary_len + bop_hdr->iv_len; + uint8_t *sig = (uint8_t *)pub_key + bop_hdr->pub_key_len; + + lvSignCtx.app_sessn_state = NULL; + lvSignCtx.device = pufs; + lvSignCtx.drv_sessn_state = NULL; + lvSignCtx.flags = (CAP_INPLACE_OPS | CAP_SYNC_OPS); + lvSignCtx.pub_key = pub_key; + lvSignCtx.sig = sig; + lvSignCtx.ops.signing_algo = CRYPTO_SIGN_ALGO_ECDSA256; + lvSignCtx.ops.signing_mode = CRYPTO_SIGN_VERIFY; + + lvSignPkt.ctx = &lvSignCtx; + lvSignPkt.in_buf = (uint8_t *)bop_hdr; + lvSignPkt.in_len = bop_hdr->binary_len + sizeof(struct rs_bop_header) + 64; // 64 = public key x(32) + y(32) + lvSignPkt.next = NULL; + + lvStatus = sign_begin_session(pufs, &lvSignCtx, CRYPTO_SIGN_ALGO_ECDSA256); + if (lvStatus != 0) { + printf("\n%ssign_begin_session ECDSA256 Failed! %s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%ssign_begin_session ECDSA256 Success! %s\n", ATTR_INF, ATTR_RST); + lvStatus = sign_op_handler(&lvSignCtx, &lvSignPkt); + } + + if (lvStatus != 0) { + printf("%s sign_op_handler ECDSA256 Failed! Status:%d %s\n", ATTR_ERR, lvStatus, ATTR_RST); + } else { + printf("%s sign_op_handler ECDSA256 Success! %s\n", ATTR_INF, ATTR_RST); + } + + lvStatus = sign_free_session(pufs, &lvSignCtx); + if (lvStatus != 0) { + printf("%s sign_free_session ECDSA256 Failed! %s\n", ATTR_ERR, ATTR_RST); + } else { + printf("%s sign_free_session ECDSA256 Success! %s\n", ATTR_INF, ATTR_RST); + } } int main(void) @@ -824,6 +922,7 @@ int main(void) pufs_hash_test(pufs); pufs_hash_sg_test(pufs); pufs_rsa2048_verify_test(pufs); + pufs_ecdsa256_verify_test(pufs); } if ((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { From 71a7056a864e82a20b21f1b8ce3ae21859d5f0ba Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Tue, 22 Oct 2024 18:59:17 +0500 Subject: [PATCH 56/58] EC256 Unit test Created and Sign Verification Passed! --- drivers/crypto/pufcc.c | 146 ++++++++++++++++++++++++++++++++++------- 1 file changed, 121 insertions(+), 25 deletions(-) diff --git a/drivers/crypto/pufcc.c b/drivers/crypto/pufcc.c index 66116150f519d..c44c77bf5f64d 100644 --- a/drivers/crypto/pufcc.c +++ b/drivers/crypto/pufcc.c @@ -601,7 +601,7 @@ enum pufcc_status pufcc_ecdsa256_sign_verify( struct rs_crypto_ec256_puk *pub_key) { uint32_t temp32, prev_len = 0; enum pufcc_status status; - struct rs_crypto_hash hash; + struct rs_crypto_hash hash; // Calculate hash of the message if (pufcc_calc_sha256_hash_sg(msg_addr, true, true, &prev_len, NULL, &hash) != @@ -615,28 +615,76 @@ enum pufcc_status pufcc_ecdsa256_sign_verify( // Set the EC NIST P256 parameters after reversing them reverse(pufcc_buffer, ecc_param_nistp256.prime, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PRIME_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); + #if CONFIG_RS_RTOS_PORT + uint32_t *ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PRIME_OFFSET/4; + uint32_t *buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PRIME_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + #endif reverse(pufcc_buffer, ecc_param_nistp256.a, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_A_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_A_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_A_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + #endif reverse(pufcc_buffer, ecc_param_nistp256.b, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_B_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_B_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_EC_B_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + #endif reverse(pufcc_buffer, ecc_param_nistp256.px, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PX_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PX_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PX_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + #endif reverse(pufcc_buffer, ecc_param_nistp256.py, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PY_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PY_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PY_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + #endif reverse(pufcc_buffer, ecc_param_nistp256.order, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_ORDER_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_ORDER_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_ORDER_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + #endif // Configure signature scheme temp32 = 0; @@ -647,29 +695,77 @@ enum pufcc_status pufcc_ecdsa256_sign_verify( REG_WRITE_32(&pkc_regs->ecp_ec, ecp_ec_reg); // Write microprogram for ECDSA 256 - memcpy((void *)&pkc_regs->ecp_mac, p256_ecdsa_mprog, - sizeof(p256_ecdsa_mprog)); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_mac; + buf_ptr = (uint32_t*)p256_ecdsa_mprog; + for(int i = 0; i < sizeof(p256_ecdsa_mprog)/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((void *)&pkc_regs->ecp_mac, p256_ecdsa_mprog, + sizeof(p256_ecdsa_mprog)); + #endif // Set the hash, public key & signature in PKC module after reversing each reverse(pufcc_buffer, hash.val, PUFCC_SHA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_HASH_OFFSET, - pufcc_buffer, PUFCC_SHA_256_LEN); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_HASH_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_HASH_OFFSET, + pufcc_buffer, PUFCC_SHA_256_LEN); + #endif reverse(pufcc_buffer, pub_key->x, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBX_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBX_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBX_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + #endif reverse(pufcc_buffer, pub_key->y, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBY_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBY_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_PUBY_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + #endif reverse(pufcc_buffer, sig->r, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_R_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_R_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_R_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + #endif reverse(pufcc_buffer, sig->s, PUFCC_ECDSA_256_LEN); - memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_S_OFFSET, - pufcc_buffer, PUFCC_ECDSA_256_LEN); + #if CONFIG_RS_RTOS_PORT + ptr = (uint32_t*)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_S_OFFSET/4; + buf_ptr = (uint32_t*)pufcc_buffer; + for(int i = 0; i < PUFCC_ECDSA_256_LEN/4; i++) { + *ptr++ = *buf_ptr++; + } + #else + memcpy((uint8_t *)&pkc_regs->ecp_data + PUFCC_DATA_ECDSA_SIG_S_OFFSET, + pufcc_buffer, PUFCC_ECDSA_256_LEN); + #endif #if !CONFIG_RS_RTOS_PORT RS_PROFILE_CHECKPOINT("misc verif ops"); From 662de508c48e1a331c4a7bb4500a648710430acd Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Thu, 24 Oct 2024 11:47:10 +0500 Subject: [PATCH 57/58] Updated Unit tests with compilation flags --- dts/bindings/syscon/rapidsi,scu.yaml | 12 + samples/hello_world/src/main.c | 512 ++++++++++++++------------- 2 files changed, 282 insertions(+), 242 deletions(-) create mode 100644 dts/bindings/syscon/rapidsi,scu.yaml diff --git a/dts/bindings/syscon/rapidsi,scu.yaml b/dts/bindings/syscon/rapidsi,scu.yaml new file mode 100644 index 0000000000000..697db9d5aed4e --- /dev/null +++ b/dts/bindings/syscon/rapidsi,scu.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2024 Rapid Silicon +# SPDX-License-Identifier: Apache-2.0 + +description: System Controller Registers R/W + +compatible: "rapidsi,scu" + +include: base.yaml + +properties: + reg: + required: true diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index e96bf6801f2fb..4977e19e9925a 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -19,219 +19,222 @@ #define ATTR_RST "\x1b[37;1m" // ANSI_COLOR_RESET #define ATTR_HIL "\x1b[33;1m" // ANSI_COLOR_HIGHLIGHT -#define FLASH_RW_SIZE 255 -#define FLASH_BASE_ADDR 0xB0000000 - -void Flash_Test(const struct device *flash, const struct device *dma, uint32_t FLASH_ADDR, - uint8_t EVEN_ODD_MUL, uint8_t FORMATTER) -{ - int errorcode = 0; - uint8_t flash_data_write[FLASH_RW_SIZE] = {0}; - uint8_t flash_data_read[FLASH_RW_SIZE] = {0}; - errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE); - if (errorcode < 0) { - printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode, - ATTR_RST); - } else { - printf("%s Reading Back Before Erasing Flash%s\n", ATTR_INF, ATTR_RST); - // for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - // printf("%s %d%s", ATTR_INF, flash_data_read[i],i%FORMATTER==0?"\n":""); - // } printf("\n"); - } - errorcode = flash_erase(flash, FLASH_ADDR, 0x1000); - if (errorcode < 0) { - printf("%s\nError Erasing the flash at 0x%08x offset errorcode:%d%s\n", ATTR_ERR, - FLASH_ADDR, errorcode, ATTR_RST); - } else { - printf("%s\nSuccessfully Erased Flash\n", ATTR_RST); +#if (CONFIG_SPI_ANDES_ATCSPI200 && CONFIG_SPI_NOR) + #define FLASH_RW_SIZE 255 + #define FLASH_BASE_ADDR 0xB0000000 + + void Flash_Test(const struct device *flash, const struct device *dma, uint32_t FLASH_ADDR, + uint8_t EVEN_ODD_MUL, uint8_t FORMATTER) + { + int errorcode = 0; + uint8_t flash_data_write[FLASH_RW_SIZE] = {0}; + uint8_t flash_data_read[FLASH_RW_SIZE] = {0}; errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE); if (errorcode < 0) { printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode, - ATTR_RST); + ATTR_RST); } else { - printf("%s Reading Back After Erasing Area of Flash%s\n", ATTR_INF, - ATTR_RST); - for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if (flash_data_read[i] != 0xff) { - errorcode = -1; - } - } - } - if (errorcode == -1) { - printf("%s\nFlash erase at 0x%08x did not produce correct results%s\n", - ATTR_ERR, FLASH_ADDR, ATTR_RST); + printf("%s Reading Back Before Erasing Flash%s\n", ATTR_INF, ATTR_RST); // for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - // printf("%s 0x%02x%s", ATTR_INF, - // flash_data_read[i],i%FORMATTER==0?"\n":""); } printf("\n"); - } else { - printf("%s\nSuccessfully performed erase to flash with code:%d%s\n", - ATTR_INF, errorcode, ATTR_RST); - } - errorcode = 0; - } - - if (errorcode == 0) { - printf("%s Writing the following data After Erasing Flash%s\n", ATTR_INF, ATTR_RST); - for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - flash_data_write[i] = ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1) + - ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1); - // printf("%s %d%s", ATTR_INF, flash_data_write[i],i%FORMATTER==0?"\n":""); + // printf("%s %d%s", ATTR_INF, flash_data_read[i],i%FORMATTER==0?"\n":""); + // } printf("\n"); } - // printf("\n"); - errorcode = flash_write(flash, FLASH_ADDR, flash_data_write, FLASH_RW_SIZE); - } - - if (errorcode < 0) { - printf("%s \nError writing to flash with code:%d%s\n", ATTR_ERR, errorcode, - ATTR_RST); - } else { - printf("%s \nSuccessfully written to flash with code:%d Resetting the reading " - "buffer....%s\n", - ATTR_INF, errorcode, ATTR_RST); - memset(flash_data_read, 0, FLASH_RW_SIZE); - errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE); + errorcode = flash_erase(flash, FLASH_ADDR, 0x1000); if (errorcode < 0) { - printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode, - ATTR_RST); + printf("%s\nError Erasing the flash at 0x%08x offset errorcode:%d%s\n", ATTR_ERR, + FLASH_ADDR, errorcode, ATTR_RST); } else { - printf("%s Successfully Read from flash with code:%d%s\n", ATTR_INF, - errorcode, ATTR_RST); - bool Data_Validated = true; - uint8_t Mismatch_count = 0; - for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if (flash_data_read[i] != flash_data_write[i]) { - Data_Validated = false; - Mismatch_count++; - printf("%s %d - Read:%d != Write:%d%s\n", ATTR_ERR, i, - flash_data_read[i], flash_data_write[i], ATTR_RST); + printf("%s\nSuccessfully Erased Flash\n", ATTR_RST); + errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE); + if (errorcode < 0) { + printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode, + ATTR_RST); + } else { + printf("%s Reading Back After Erasing Area of Flash%s\n", ATTR_INF, + ATTR_RST); + for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if (flash_data_read[i] != 0xff) { + errorcode = -1; + } } } - if (!Data_Validated) { - printf("%s Flash Integrity Check Failed With %d Mismatched " - "Entries%s\n", - ATTR_ERR, Mismatch_count, ATTR_RST); + if (errorcode == -1) { + printf("%s\nFlash erase at 0x%08x did not produce correct results%s\n", + ATTR_ERR, FLASH_ADDR, ATTR_RST); + // for(uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + // printf("%s 0x%02x%s", ATTR_INF, + // flash_data_read[i],i%FORMATTER==0?"\n":""); } printf("\n"); } else { - printf("%s Flash Integrity Check Passed!!!%s\n", ATTR_INF, - ATTR_RST); + printf("%s\nSuccessfully performed erase to flash with code:%d%s\n", + ATTR_INF, errorcode, ATTR_RST); } + errorcode = 0; } - } - if (errorcode == 0) { - uint8_t *MemMapReadAddr = (uint8_t *)(FLASH_BASE_ADDR + FLASH_ADDR); - uint8_t MemMapReadDestAddr[FLASH_RW_SIZE]; - { - printf("CPU Memory Mapped Reading Test from address:%p\n", MemMapReadAddr); - bool memmaptestfail = false; + if (errorcode == 0) { + printf("%s Writing the following data After Erasing Flash%s\n", ATTR_INF, ATTR_RST); for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if (MemMapReadAddr[i] != flash_data_write[i]) { - printf("%s %d%s", ATTR_ERR, MemMapReadAddr[i], - i % FORMATTER == 0 ? "\n" : ""); - memmaptestfail = true; - } - // else { - // printf("%s %d%s", ATTR_INF, - // MemMapReadAddr[i],i%FORMATTER==0?"\n":""); - // } - } - printf("\n"); - if (memmaptestfail) { - printf("%s CPU Memory mapped read failed\n", ATTR_ERR); - } else { - printf("%s CPU Memory mapped read passed\n", ATTR_INF); + flash_data_write[i] = ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1) + + ((rand() % (FLASH_RW_SIZE - 1 + 1)) + 1); + // printf("%s %d%s", ATTR_INF, flash_data_write[i],i%FORMATTER==0?"\n":""); } + // printf("\n"); + errorcode = flash_write(flash, FLASH_ADDR, flash_data_write, FLASH_RW_SIZE); } - if (dma != NULL) { - printf("%s DMA Memory Mapped Reading Test from address:%p\n", ATTR_RST, - MemMapReadAddr); - // Configure DMA Block - struct dma_block_config lv_dma_block_config = { - .block_size = FLASH_RW_SIZE, - .dest_addr_adj = DMA_ADDR_ADJ_INCREMENT, - .dest_address = (uint32_t)&MemMapReadDestAddr[0], - .dest_reload_en = 0, - .dest_scatter_count = 0, - .dest_scatter_en = 0, - .dest_scatter_interval = 0, - .fifo_mode_control = 0, - .flow_control_mode = 0, - .next_block = NULL, - .source_addr_adj = DMA_ADDR_ADJ_INCREMENT, - .source_address = (uint32_t)&MemMapReadAddr[0], - .source_gather_count = 0, - .source_gather_en = 0, - .source_gather_interval = 0, - .source_reload_en = 0, - ._reserved = 0}; - // Configure DMA - struct dma_config lv_Dma_Config = {.block_count = 1, - .channel_direction = MEMORY_TO_MEMORY, - .channel_priority = 1, - .complete_callback_en = 0, - .cyclic = 0, - .dest_burst_length = 1, - .dest_chaining_en = 0, - .dest_data_size = 1, - .dest_handshake = 1, - .dma_callback = NULL, - .dma_slot = 0, - .error_callback_dis = 1, - .head_block = &lv_dma_block_config, - .linked_channel = 0, - .source_burst_length = 1, - .source_chaining_en = 0, - .source_data_size = 1, - .user_data = NULL}; - struct dma_status stat = {0}; - printf("%s DMA Configuration...\n", ATTR_RST); - int dma_error = dma_config(dma, 1, &lv_Dma_Config); - k_msleep(10); - if (dma_error) { - printf("%s Error %d Configuration...\n", ATTR_RST, dma_error); + if (errorcode < 0) { + printf("%s \nError writing to flash with code:%d%s\n", ATTR_ERR, errorcode, + ATTR_RST); + } else { + printf("%s \nSuccessfully written to flash with code:%d Resetting the reading " + "buffer....%s\n", + ATTR_INF, errorcode, ATTR_RST); + memset(flash_data_read, 0, FLASH_RW_SIZE); + errorcode = flash_read(flash, FLASH_ADDR, flash_data_read, FLASH_RW_SIZE); + if (errorcode < 0) { + printf("%s Error reading from flash with code:%d%s\n", ATTR_ERR, errorcode, + ATTR_RST); } else { - // Call DMA Read - printf("%s DMA Starting...\n", ATTR_INF); - dma_error = dma_start(dma, 1); - k_msleep(10); - } - (void)dma_get_status(dma, 1, &stat); - while (stat.pending_length > 1) { - dma_error = dma_get_status(dma, 1, &stat); - if (dma_error) { - printf("Error %d dma_status...\n", dma_error); - break; + printf("%s Successfully Read from flash with code:%d%s\n", ATTR_INF, + errorcode, ATTR_RST); + bool Data_Validated = true; + uint8_t Mismatch_count = 0; + for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if (flash_data_read[i] != flash_data_write[i]) { + Data_Validated = false; + Mismatch_count++; + printf("%s %d - Read:%d != Write:%d%s\n", ATTR_ERR, i, + flash_data_read[i], flash_data_write[i], ATTR_RST); + } + } + if (!Data_Validated) { + printf("%s Flash Integrity Check Failed With %d Mismatched " + "Entries%s\n", + ATTR_ERR, Mismatch_count, ATTR_RST); } else { - printf("dma_pending_length:%d \n", stat.pending_length); + printf("%s Flash Integrity Check Passed!!!%s\n", ATTR_INF, + ATTR_RST); } } + } - if (!dma_error) { + if (errorcode == 0) { + uint8_t *MemMapReadAddr = (uint8_t *)(FLASH_BASE_ADDR + FLASH_ADDR); + uint8_t MemMapReadDestAddr[FLASH_RW_SIZE]; + { + printf("CPU Memory Mapped Reading Test from address:%p\n", MemMapReadAddr); bool memmaptestfail = false; for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { - if (MemMapReadDestAddr[i] != flash_data_write[i]) { - printf("%s %d%s", ATTR_ERR, MemMapReadDestAddr[i], - i % FORMATTER == 0 ? "\n" : ""); + if (MemMapReadAddr[i] != flash_data_write[i]) { + printf("%s %d%s", ATTR_ERR, MemMapReadAddr[i], + i % FORMATTER == 0 ? "\n" : ""); memmaptestfail = true; } // else { // printf("%s %d%s", ATTR_INF, - // MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); + // MemMapReadAddr[i],i%FORMATTER==0?"\n":""); // } } printf("\n"); if (memmaptestfail) { - printf("%s DMA Memory mapped read failed\n", ATTR_ERR); + printf("%s CPU Memory mapped read failed\n", ATTR_ERR); } else { - printf("%s DMA Memory mapped read passed\n", ATTR_INF); + printf("%s CPU Memory mapped read passed\n", ATTR_INF); + } + } + + if (dma != NULL) { + printf("%s DMA Memory Mapped Reading Test from address:%p\n", ATTR_RST, + MemMapReadAddr); + // Configure DMA Block + struct dma_block_config lv_dma_block_config = { + .block_size = FLASH_RW_SIZE, + .dest_addr_adj = DMA_ADDR_ADJ_INCREMENT, + .dest_address = (uint32_t)&MemMapReadDestAddr[0], + .dest_reload_en = 0, + .dest_scatter_count = 0, + .dest_scatter_en = 0, + .dest_scatter_interval = 0, + .fifo_mode_control = 0, + .flow_control_mode = 0, + .next_block = NULL, + .source_addr_adj = DMA_ADDR_ADJ_INCREMENT, + .source_address = (uint32_t)&MemMapReadAddr[0], + .source_gather_count = 0, + .source_gather_en = 0, + .source_gather_interval = 0, + .source_reload_en = 0, + ._reserved = 0}; + // Configure DMA + struct dma_config lv_Dma_Config = {.block_count = 1, + .channel_direction = MEMORY_TO_MEMORY, + .channel_priority = 1, + .complete_callback_en = 0, + .cyclic = 0, + .dest_burst_length = 1, + .dest_chaining_en = 0, + .dest_data_size = 1, + .dest_handshake = 1, + .dma_callback = NULL, + .dma_slot = 0, + .error_callback_dis = 1, + .head_block = &lv_dma_block_config, + .linked_channel = 0, + .source_burst_length = 1, + .source_chaining_en = 0, + .source_data_size = 1, + .user_data = NULL}; + struct dma_status stat = {0}; + printf("%s DMA Configuration...\n", ATTR_RST); + int dma_error = dma_config(dma, 1, &lv_Dma_Config); + k_msleep(10); + if (dma_error) { + printf("%s Error %d Configuration...\n", ATTR_RST, dma_error); + } else { + // Call DMA Read + printf("%s DMA Starting...\n", ATTR_INF); + dma_error = dma_start(dma, 1); + k_msleep(10); + } + (void)dma_get_status(dma, 1, &stat); + while (stat.pending_length > 1) { + dma_error = dma_get_status(dma, 1, &stat); + if (dma_error) { + printf("Error %d dma_status...\n", dma_error); + break; + } else { + printf("dma_pending_length:%d \n", stat.pending_length); + } + } + + if (!dma_error) { + bool memmaptestfail = false; + for (uint8_t i = 0; i < FLASH_RW_SIZE; i++) { + if (MemMapReadDestAddr[i] != flash_data_write[i]) { + printf("%s %d%s", ATTR_ERR, MemMapReadDestAddr[i], + i % FORMATTER == 0 ? "\n" : ""); + memmaptestfail = true; + } + // else { + // printf("%s %d%s", ATTR_INF, + // MemMapReadDestAddr[i],i%FORMATTER==0?"\n":""); + // } + } + printf("\n"); + if (memmaptestfail) { + printf("%s DMA Memory mapped read failed\n", ATTR_ERR); + } else { + printf("%s DMA Memory mapped read passed\n", ATTR_INF); + } + } else { + printf("Error %d DMA Start...\n", dma_error); } - } else { - printf("Error %d DMA Start...\n", dma_error); } } } -} +#endif +#if CONFIG_COUNTER_ANDES_ATCPIT100 void CounterCallBack(const struct device *dev, void *UserData) { uint32_t *lvData = ((uint32_t *)UserData); @@ -283,7 +286,9 @@ void CounterTest(const struct device *pit) } */ } +#endif +#if CONFIG_CRYPTO_PUF_SECURITY_OTP void pufs_otp_test(const struct device *pufs_otp) { uint8_t slot_data[32] = {0}; @@ -362,7 +367,8 @@ void pufs_otp_test(const struct device *pufs_otp) } } } - +#endif +#if CONFIG_CRYPTO_PUF_SECURITY void pufs_hash_sg_test(const struct device *pufs) { int status = 0; @@ -890,88 +896,110 @@ void pufs_ecdsa256_verify_test(const struct device *pufs) printf("%s sign_free_session ECDSA256 Success! %s\n", ATTR_INF, ATTR_RST); } } +#endif int main(void) { int Cnt = 0; uint8_t chip_id = 0, vendor_id = 0; - printf("%s SPI_(%d)_IRQ_Reg_Val:[0x%08x]; DMA_(%d)_IRQ_Reg_Val:[0x%08x]\n", ATTR_RST, - IRQ_ID_SPI, scu_get_irq_reg_val(IRQ_ID_SPI), IRQ_ID_SYSTEM_DMA, - scu_get_irq_reg_val(IRQ_ID_SYSTEM_DMA)); + #if DT_HAS_RAPIDSI_SCU_ENABLED + printf("%s SPI_(%d)_IRQ_Reg_Val:[0x%08x]; DMA_(%d)_IRQ_Reg_Val:[0x%08x]\n", ATTR_RST, + IRQ_ID_SPI, scu_get_irq_reg_val(IRQ_ID_SPI), IRQ_ID_SYSTEM_DMA, + scu_get_irq_reg_val(IRQ_ID_SYSTEM_DMA)); - soc_get_id(&chip_id, &vendor_id); - scu_assert_reset(); + soc_get_id(&chip_id, &vendor_id); + scu_assert_reset(); + #endif int errorcode = 0; struct sensor_value lvTemp = {0}, lvVolt = {0}; - const struct device *pvt = DEVICE_DT_GET(DT_NODELABEL(pvt0)); - const struct device *spi = DEVICE_DT_GET(DT_NODELABEL(spi0)); - const struct device *flash = DEVICE_DT_GET(DT_NODELABEL(m25p32)); - const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma0)); - const struct device *pit = DEVICE_DT_GET(DT_NODELABEL(pit0)); - const struct device *pufs = DEVICE_DT_GET(DT_NODELABEL(pufs)); - const struct device *pufs_otp = DEVICE_DT_GET(DT_NODELABEL(pufs_otp)); - - if ((pufs == NULL) || (!device_is_ready(pufs))) { - printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, - ATTR_RST); - } else { - printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); - pufs_decryption_test(pufs); - pufs_hash_test(pufs); - pufs_hash_sg_test(pufs); - pufs_rsa2048_verify_test(pufs); - pufs_ecdsa256_verify_test(pufs); - } - - if ((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { - printf("%s pufs_otp has status disabled or driver is not initialized...%s\n", - ATTR_ERR, ATTR_RST); - } else { - printf("%s pufs_otp Object is Created %s\n", ATTR_INF, ATTR_RST); - pufs_otp_test(pufs_otp); - } + #if CONFIG_DTI_PVT + const struct device *pvt = DEVICE_DT_GET(DT_NODELABEL(pvt0)); + #endif + #if (CONFIG_SPI_ANDES_ATCSPI200 && CONFIG_SPI_NOR) + const struct device *spi = DEVICE_DT_GET(DT_NODELABEL(spi0)); + const struct device *flash = DEVICE_DT_GET(DT_NODELABEL(m25p32)); + #endif + #if CONFIG_DMA_ANDES_ATCDMAC100 + const struct device *dma = DEVICE_DT_GET(DT_NODELABEL(dma0)); + #endif + #if CONFIG_COUNTER_ANDES_ATCPIT100 + const struct device *pit = DEVICE_DT_GET(DT_NODELABEL(pit0)); + #endif + #if CONFIG_CRYPTO_PUF_SECURITY + const struct device *pufs = DEVICE_DT_GET(DT_NODELABEL(pufs)); + #endif + #if CONFIG_CRYPTO_PUF_SECURITY_OTP + const struct device *pufs_otp = DEVICE_DT_GET(DT_NODELABEL(pufs_otp)); + #endif + + #if CONFIG_CRYPTO_PUF_SECURITY + if ((pufs == NULL) || (!device_is_ready(pufs))) { + printf("%s pufs has status disabled or driver is not initialized...%s\n", ATTR_ERR, + ATTR_RST); + } else { + printf("%s pufs Object is Created %s\n", ATTR_INF, ATTR_RST); + pufs_decryption_test(pufs); + pufs_hash_test(pufs); + pufs_hash_sg_test(pufs); + pufs_rsa2048_verify_test(pufs); + pufs_ecdsa256_verify_test(pufs); + } + #endif - if ((pvt == NULL) || (!device_is_ready(pvt))) { - printf("%s pvt has status disabled or driver is not initialized...%s\n", ATTR_ERR, - ATTR_RST); - } else { - printf("%s pvt Object is Created %s\n", ATTR_INF, ATTR_RST); - errorcode = sensor_channel_get(pvt, SENSOR_CHAN_DIE_TEMP, &lvTemp); - if (errorcode == 0) { - printf("%s Error fetching temperature value. Error code:%u%s\n", ATTR_ERR, - errorcode, ATTR_RST); + #if CONFIG_CRYPTO_PUF_SECURITY_OTP + if ((pufs_otp == NULL) || (!device_is_ready(pufs_otp))) { + printf("%s pufs_otp has status disabled or driver is not initialized...%s\n", + ATTR_ERR, ATTR_RST); + } else { + printf("%s pufs_otp Object is Created %s\n", ATTR_INF, ATTR_RST); + pufs_otp_test(pufs_otp); } - errorcode = sensor_channel_get(pvt, SENSOR_CHAN_VOLTAGE, &lvVolt); - if (errorcode == 0) { - printf("%s Error fetching Voltage value. Error code:%u%s\n", ATTR_ERR, - errorcode, ATTR_RST); + #endif + #if CONFIG_DTI_PVT + if ((pvt == NULL) || (!device_is_ready(pvt))) { + printf("%s pvt has status disabled or driver is not initialized...%s\n", ATTR_ERR, + ATTR_RST); + } else { + printf("%s pvt Object is Created %s\n", ATTR_INF, ATTR_RST); + errorcode = sensor_channel_get(pvt, SENSOR_CHAN_DIE_TEMP, &lvTemp); + if (errorcode == 0) { + printf("%s Error fetching temperature value. Error code:%u%s\n", ATTR_ERR, + errorcode, ATTR_RST); + } + errorcode = sensor_channel_get(pvt, SENSOR_CHAN_VOLTAGE, &lvVolt); + if (errorcode == 0) { + printf("%s Error fetching Voltage value. Error code:%u%s\n", ATTR_ERR, + errorcode, ATTR_RST); + } + printf("%s Die Temperature:%d Voltage:%d%s\n", ATTR_INF, lvTemp.val1, lvVolt.val1, + ATTR_RST); } - printf("%s Die Temperature:%d Voltage:%d%s\n", ATTR_INF, lvTemp.val1, lvVolt.val1, - ATTR_RST); - } - - if (spi == NULL) { - printf("%s spi has status disabled...%s\n", ATTR_ERR, ATTR_RST); - } else { - printf("%s spi Object is Created. Test Via DMA\n", ATTR_INF); - if (flash == NULL) { - printf("%s flash has status disabled or not initialized properly...%s\n", - ATTR_ERR, ATTR_RST); + #endif + #if (CONFIG_SPI_ANDES_ATCSPI200 && CONFIG_SPI_NOR) + if (spi == NULL) { + printf("%s spi has status disabled...%s\n", ATTR_ERR, ATTR_RST); } else { - printf("%s flash Object is Created. Initialize to Test Via DMA%s\n", - ATTR_INF, ATTR_RST); - Flash_Test(flash, dma, 0x1000, 0, 20); + printf("%s spi Object is Created. Test Via DMA\n", ATTR_INF); + if (flash == NULL) { + printf("%s flash has status disabled or not initialized properly...%s\n", + ATTR_ERR, ATTR_RST); + } else { + printf("%s flash Object is Created. Initialize to Test Via DMA%s\n", + ATTR_INF, ATTR_RST); + Flash_Test(flash, dma, 0x1000, 0, 20); + } } - } - - if ((pit == NULL) || !device_is_ready(pit)) { - printf("%s pit has status disabled or driver is not initialized...%s\n", ATTR_ERR, - ATTR_RST); - } else { - CounterTest(pit); - } + #endif + #if CONFIG_COUNTER_ANDES_ATCPIT100 + if ((pit == NULL) || !device_is_ready(pit)) { + printf("%s pit has status disabled or driver is not initialized...%s\n", ATTR_ERR, + ATTR_RST); + } else { + CounterTest(pit); + } + #endif while (true) { printf("%s%d - %s [CHIP_ID:0x%02x VENDOR_ID:0x%02x] Build[Date:%s Time:%s]\r", From 339cc6dbb6578318313540fda7c15a8dd16083cd Mon Sep 17 00:00:00 2001 From: junaidaslamRS Date: Sun, 27 Oct 2024 14:12:36 +0500 Subject: [PATCH 58/58] Update to Cipher context structure for supporting secure fpga bitstream loading. --- include/zephyr/crypto/cipher.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/zephyr/crypto/cipher.h b/include/zephyr/crypto/cipher.h index cc967bde51836..f022f1bae4229 100644 --- a/include/zephyr/crypto/cipher.h +++ b/include/zephyr/crypto/cipher.h @@ -98,6 +98,11 @@ struct ccm_params { }; struct ctr_params { + /* + This is a pointer to the IV (initialization vector) + provided as input to the counter mode cipher API. + */ + uint8_t *iv; /* CTR mode counter is a split counter composed of iv and counter * such that ivlen + ctr_len = keylen */