MLK-18703: crypto: caam: Add init TRNG into SPL or U-Boot
The following reasons lead to instantiate the TRNG into U-Boot/SPL: - On some i.MX platforms Linux Kernel could not instantiate RNG - RNG could be used/needed by M4/M0 cores before Kernel stage - Having the RNG instantiation implemented only once for almost i.MX platforms Signed-off-by: Aymen Sghaier <aymen.sghaier@nxp.com>
This commit is contained in:
parent
4da1ab91f8
commit
1f4134c85f
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
* Copyright 2018 NXP
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
|
|
@ -29,67 +30,75 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <memalign.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/crm_regs.h>
|
||||
#include "fsl_caam_internal.h"
|
||||
#include "fsl/desc_constr.h"
|
||||
#include <fsl_caam.h>
|
||||
|
||||
/*---------- Global variables ----------*/
|
||||
/* Input job ring - single entry input ring */
|
||||
uint32_t g_input_ring[JOB_RING_ENTRIES] = {0};
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static void rng_init(void);
|
||||
static void caam_clock_enable(void);
|
||||
static int do_cfg_jrqueue(void);
|
||||
static int do_job(u32 *desc);
|
||||
static int jr_reset(void);
|
||||
|
||||
/* Output job ring - single entry output ring (consists of two words) */
|
||||
uint32_t g_output_ring[2*JOB_RING_ENTRIES] = {0, 0};
|
||||
|
||||
uint32_t decap_dsc[] =
|
||||
{
|
||||
DECAP_BLOB_DESC1,
|
||||
DECAP_BLOB_DESC2,
|
||||
DECAP_BLOB_DESC3,
|
||||
DECAP_BLOB_DESC4,
|
||||
DECAP_BLOB_DESC5,
|
||||
DECAP_BLOB_DESC6,
|
||||
DECAP_BLOB_DESC7,
|
||||
DECAP_BLOB_DESC8,
|
||||
DECAP_BLOB_DESC9
|
||||
/*
|
||||
* Structures
|
||||
*/
|
||||
/* Definition of input ring object */
|
||||
struct inring_entry {
|
||||
u32 desc; /* Pointer to input descriptor */
|
||||
};
|
||||
|
||||
uint32_t encap_dsc[] =
|
||||
{
|
||||
ENCAP_BLOB_DESC1,
|
||||
ENCAP_BLOB_DESC2,
|
||||
ENCAP_BLOB_DESC3,
|
||||
ENCAP_BLOB_DESC4,
|
||||
ENCAP_BLOB_DESC5,
|
||||
ENCAP_BLOB_DESC6,
|
||||
ENCAP_BLOB_DESC7,
|
||||
ENCAP_BLOB_DESC8,
|
||||
ENCAP_BLOB_DESC9
|
||||
/* Definition of output ring object */
|
||||
struct outring_entry {
|
||||
u32 desc; /* Pointer to output descriptor */
|
||||
u32 status; /* Status of the Job Ring */
|
||||
};
|
||||
|
||||
uint32_t hwrng_dsc[6] = {0};
|
||||
uint32_t rng_inst_dsc[] =
|
||||
{
|
||||
RNG_INST_DESC1,
|
||||
RNG_INST_DESC2,
|
||||
RNG_INST_DESC3,
|
||||
RNG_INST_DESC4,
|
||||
RNG_INST_DESC5,
|
||||
RNG_INST_DESC6,
|
||||
RNG_INST_DESC7,
|
||||
RNG_INST_DESC8,
|
||||
RNG_INST_DESC9
|
||||
/* Main job ring data structure */
|
||||
struct jr_data_st {
|
||||
struct inring_entry *inrings;
|
||||
struct outring_entry *outrings;
|
||||
u32 status; /* Ring buffers init status */
|
||||
u32 *desc; /* Pointer to output descriptor */
|
||||
u32 raw_addr[DESC_MAX_SIZE * 2];
|
||||
};
|
||||
|
||||
static uint8_t skeymod[] = {
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
static struct jr_data_st g_jrdata = {0};
|
||||
|
||||
static u8 skeymod[] = {
|
||||
0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08,
|
||||
0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
* Local functions
|
||||
*/
|
||||
static void dump_error(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* arm v7 need 64 align */
|
||||
#define ALIGN_MASK 0xffffffc0
|
||||
debug("Dump CAAM Error\n");
|
||||
debug("MCFGR 0x%08X\n", __raw_readl(CAAM_MCFGR));
|
||||
debug("FAR 0x%08X\n", __raw_readl(CAAM_FAR));
|
||||
debug("FAMR 0x%08X\n", __raw_readl(CAAM_FAMR));
|
||||
debug("FADR 0x%08X\n", __raw_readl(CAAM_FADR));
|
||||
debug("CSTA 0x%08X\n", __raw_readl(CAAM_STA));
|
||||
debug("RTMCTL 0x%X\n", __raw_readl(CAAM_RTMCTL));
|
||||
debug("RTSTATUS 0x%X\n", __raw_readl(CAAM_RTSTATUS));
|
||||
debug("RDSTA 0x%X\n", __raw_readl(CAAM_RDSTA));
|
||||
|
||||
for (i = 0; i < desc_len(g_jrdata.desc); i++)
|
||||
debug("desc[%d]: 0x%08x\n", i, g_jrdata.desc[i]);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Secure memory run command.
|
||||
|
|
@ -97,13 +106,13 @@ static uint8_t skeymod[] = {
|
|||
* @param sec_mem_cmd Secure memory command register
|
||||
* @return cmd_status Secure memory command status register
|
||||
*/
|
||||
uint32_t secmem_set_cmd_1(uint32_t sec_mem_cmd)
|
||||
u32 secmem_set_cmd_1(u32 sec_mem_cmd)
|
||||
{
|
||||
uint32_t temp_reg;
|
||||
u32 temp_reg;
|
||||
__raw_writel(sec_mem_cmd, CAAM_SMCJR0);
|
||||
do {
|
||||
temp_reg = __raw_readl(CAAM_SMCSJR0);
|
||||
} while(temp_reg & CMD_COMPLETE);
|
||||
} while (temp_reg & CMD_COMPLETE);
|
||||
|
||||
return temp_reg;
|
||||
}
|
||||
|
|
@ -118,77 +127,34 @@ uint32_t secmem_set_cmd_1(uint32_t sec_mem_cmd)
|
|||
*
|
||||
* @return SUCCESS or ERROR_XXX
|
||||
*/
|
||||
uint32_t caam_decap_blob(uint32_t plain_text, uint32_t blob_addr, uint32_t size)
|
||||
u32 caam_decap_blob(u32 plain_text, u32 blob_addr, u32 size)
|
||||
{
|
||||
uint32_t ret = SUCCESS;
|
||||
u32 ret = SUCCESS;
|
||||
u32 key_sz = sizeof(skeymod);
|
||||
u32 *decap_desc = g_jrdata.desc;
|
||||
|
||||
/* Buffer that holds blob */
|
||||
/* prepare job descriptor */
|
||||
init_job_desc(decap_desc, 0);
|
||||
append_load(decap_desc, PTR2CAAMDMA(skeymod), key_sz,
|
||||
LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
|
||||
append_seq_in_ptr_intlen(decap_desc, blob_addr, size + 48, 0);
|
||||
append_seq_out_ptr_intlen(decap_desc, plain_text, size, 0);
|
||||
append_operation(decap_desc, OP_TYPE_DECAP_PROTOCOL | OP_PCLID_BLOB);
|
||||
|
||||
|
||||
/* TODO: Fix Hardcoded Descriptor */
|
||||
decap_dsc[0] = (uint32_t)0xB0800008;
|
||||
decap_dsc[1] = (uint32_t)0x14400010;
|
||||
decap_dsc[2] = (uint32_t)skeymod;
|
||||
decap_dsc[3] = (uint32_t)0xF0000000 | (0x0000ffff & (size+48) );
|
||||
decap_dsc[4] = blob_addr;
|
||||
decap_dsc[5] = (uint32_t)0xF8000000 | (0x0000ffff & (size));
|
||||
decap_dsc[6] = (uint32_t)(uint8_t*)plain_text;
|
||||
decap_dsc[7] = (uint32_t)0x860D0000;
|
||||
|
||||
/* uncomment when using descriptor from "fsl_caam_internal.h"
|
||||
does not use key modifier. */
|
||||
flush_dcache_range((uintptr_t)blob_addr & ALIGN_MASK,
|
||||
((uintptr_t)blob_addr & ALIGN_MASK)
|
||||
+ ROUND(2 * size, ARCH_DMA_MINALIGN));
|
||||
flush_dcache_range((uintptr_t)plain_text & ALIGN_MASK,
|
||||
(plain_text & ALIGN_MASK)
|
||||
+ ROUND(2 * size, ARCH_DMA_MINALIGN));
|
||||
|
||||
/* Run descriptor with result written to blob buffer */
|
||||
/* Add job to input ring */
|
||||
g_input_ring[0] = (uint32_t)decap_dsc;
|
||||
ret = do_job(decap_desc);
|
||||
|
||||
flush_dcache_range((uint32_t)blob_addr & ALIGN_MASK,
|
||||
(((uint32_t)blob_addr + 2 * size + 64) & ALIGN_MASK));
|
||||
flush_dcache_range((uint32_t)plain_text & ALIGN_MASK,
|
||||
(((uint32_t)plain_text + 2 * size + 64) & ALIGN_MASK));
|
||||
flush_dcache_range((uint32_t)decap_dsc & ALIGN_MASK,
|
||||
((uint32_t)decap_dsc & ALIGN_MASK) + 128);
|
||||
flush_dcache_range((uint32_t)g_input_ring & ALIGN_MASK,
|
||||
((uint32_t)g_input_ring & ALIGN_MASK) + 128);
|
||||
|
||||
invalidate_dcache_range((uint32_t)decap_dsc & ALIGN_MASK,
|
||||
((uint32_t)decap_dsc & ALIGN_MASK) + 128);
|
||||
invalidate_dcache_range((uint32_t)g_input_ring & ALIGN_MASK,
|
||||
((uint32_t)g_input_ring & ALIGN_MASK) + 128);
|
||||
invalidate_dcache_range((uint32_t)blob_addr & ALIGN_MASK,
|
||||
(((uint32_t)blob_addr + 2 * size + 64) & ALIGN_MASK));
|
||||
invalidate_dcache_range((uint32_t)plain_text & ALIGN_MASK,
|
||||
(((uint32_t)plain_text + 2 * size + 64) & ALIGN_MASK));
|
||||
/* Increment jobs added */
|
||||
__raw_writel(1, CAAM_IRJAR0);
|
||||
|
||||
/* Wait for job ring to complete the job: 1 completed job expected */
|
||||
while(__raw_readl(CAAM_ORSFR0) != 1);
|
||||
|
||||
// TODO: check if Secure memory is cacheable.
|
||||
flush_dcache_range((uint32_t)g_output_ring & ALIGN_MASK,
|
||||
((uint32_t)g_output_ring & ALIGN_MASK) + 128);
|
||||
invalidate_dcache_range((uint32_t)g_output_ring & ALIGN_MASK,
|
||||
((uint32_t)g_output_ring & ALIGN_MASK) + 128);
|
||||
/* check that descriptor address is the one expected in the output ring */
|
||||
if(g_output_ring[0] == (uint32_t)decap_dsc)
|
||||
{
|
||||
/* check if any error is reported in the output ring */
|
||||
if ((g_output_ring[1] & JOB_RING_STS) != 0)
|
||||
{
|
||||
printf("Error: blob decap job completed with errors 0x%X\n",
|
||||
g_output_ring[1]);
|
||||
if (ret != SUCCESS) {
|
||||
dump_error();
|
||||
printf("Error: blob decap job failed 0x%x\n", ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error: blob decap job output ring descriptor address does" \
|
||||
" not match\n");
|
||||
}
|
||||
|
||||
|
||||
/* Remove job from Job Ring Output Queue */
|
||||
__raw_writel(1, CAAM_ORJRR0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -201,129 +167,73 @@ uint32_t caam_decap_blob(uint32_t plain_text, uint32_t blob_addr, uint32_t size)
|
|||
*
|
||||
* @return SUCCESS or ERROR_XXX
|
||||
*/
|
||||
uint32_t caam_gen_blob(uint32_t plain_data_addr, uint32_t blob_addr, uint32_t size)
|
||||
u32 caam_gen_blob(u32 plain_data_addr, u32 blob_addr, u32 size)
|
||||
{
|
||||
uint32_t ret = SUCCESS;
|
||||
|
||||
u32 ret = SUCCESS;
|
||||
u32 key_sz = sizeof(skeymod);
|
||||
u32 *encap_desc = g_jrdata.desc;
|
||||
/* Buffer to hold the resulting blob */
|
||||
uint8_t *blob = (uint8_t *)blob_addr;
|
||||
u8 *blob = (u8 *)CAAMDMA2PTR(blob_addr);
|
||||
|
||||
/* initialize the blob array */
|
||||
memset(blob,0,size);
|
||||
|
||||
/* prepare job descriptor */
|
||||
init_job_desc(encap_desc, 0);
|
||||
append_load(encap_desc, PTR2CAAMDMA(skeymod), key_sz,
|
||||
LDST_CLASS_2_CCB | LDST_SRCDST_BYTE_KEY);
|
||||
append_seq_in_ptr_intlen(encap_desc, plain_data_addr, size, 0);
|
||||
append_seq_out_ptr_intlen(encap_desc, PTR2CAAMDMA(blob), size + 48, 0);
|
||||
append_operation(encap_desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB);
|
||||
|
||||
/* TODO: Fix Hardcoded Descriptor */
|
||||
encap_dsc[0] = (uint32_t)0xB0800008;
|
||||
encap_dsc[1] = (uint32_t)0x14400010;
|
||||
encap_dsc[2] = (uint32_t)skeymod;
|
||||
encap_dsc[3] = (uint32_t)0xF0000000 | (0x0000ffff & (size));
|
||||
encap_dsc[4] = (uint32_t)plain_data_addr;
|
||||
encap_dsc[5] = (uint32_t)0xF8000000 | (0x0000ffff & (size+48));
|
||||
encap_dsc[6] = (uint32_t)blob;
|
||||
encap_dsc[7] = (uint32_t)0x870D0000;
|
||||
flush_dcache_range((uintptr_t)plain_data_addr & ALIGN_MASK,
|
||||
(plain_data_addr & ALIGN_MASK)
|
||||
+ ROUND(2 * size, ARCH_DMA_MINALIGN));
|
||||
flush_dcache_range((uintptr_t)blob & ALIGN_MASK,
|
||||
((uintptr_t)blob & ALIGN_MASK)
|
||||
+ ROUND(2 * size, ARCH_DMA_MINALIGN));
|
||||
|
||||
/* Run descriptor with result written to blob buffer */
|
||||
/* Add job to input ring */
|
||||
g_input_ring[0] = (uint32_t)encap_dsc;
|
||||
ret = do_job(encap_desc);
|
||||
|
||||
flush_dcache_range((uint32_t)plain_data_addr & ALIGN_MASK,
|
||||
(((uint32_t)plain_data_addr + 2 * size + 64) & ALIGN_MASK));
|
||||
flush_dcache_range((uint32_t)encap_dsc & ALIGN_MASK,
|
||||
((uint32_t)encap_dsc & ALIGN_MASK) + 128);
|
||||
flush_dcache_range((uint32_t)blob & ALIGN_MASK,
|
||||
(((uint32_t)blob + 2 * size + 64) & ALIGN_MASK));
|
||||
flush_dcache_range((uint32_t)g_input_ring & ALIGN_MASK,
|
||||
((uint32_t)g_input_ring & ALIGN_MASK) + 128);
|
||||
|
||||
invalidate_dcache_range((uint32_t)blob & ALIGN_MASK,
|
||||
(((uint32_t)blob + 2 * size + 64) & ALIGN_MASK));
|
||||
/* Increment jobs added */
|
||||
__raw_writel(1, CAAM_IRJAR0);
|
||||
|
||||
/* Wait for job ring to complete the job: 1 completed job expected */
|
||||
while(__raw_readl(CAAM_ORSFR0) != 1);
|
||||
|
||||
// flush cache
|
||||
flush_dcache_range((uint32_t)g_output_ring & ALIGN_MASK,
|
||||
((uint32_t)g_output_ring & ALIGN_MASK) + 128);
|
||||
/* check that descriptor address is the one expected in the output ring */
|
||||
if(g_output_ring[0] == (uint32_t)encap_dsc)
|
||||
{
|
||||
/* check if any error is reported in the output ring */
|
||||
if ((g_output_ring[1] & JOB_RING_STS) != 0)
|
||||
{
|
||||
printf("Error: blob encap job completed with errors 0x%X\n",
|
||||
g_output_ring[1]);
|
||||
if (ret != SUCCESS) {
|
||||
dump_error();
|
||||
printf("Error: blob encap job failed 0x%x\n", ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error: blob encap job output ring descriptor address does" \
|
||||
" not match\n");
|
||||
}
|
||||
|
||||
/* Remove job from Job Ring Output Queue */
|
||||
__raw_writel(1, CAAM_ORJRR0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t caam_hwrng(uint8_t *output_ptr, uint32_t output_len) {
|
||||
uint32_t ret = SUCCESS;
|
||||
|
||||
u32 caam_hwrng(u8 *output_ptr, u32 output_len)
|
||||
{
|
||||
u32 ret = SUCCESS;
|
||||
u32 *hwrng_desc = g_jrdata.desc;
|
||||
/* Buffer to hold the resulting output*/
|
||||
uint8_t *output = (uint8_t *)output_ptr;
|
||||
u8 *output = (u8 *)output_ptr;
|
||||
|
||||
/* initialize the output array */
|
||||
memset(output,0,output_len);
|
||||
|
||||
int n = 0;
|
||||
hwrng_dsc[n++] = (uint32_t)0xB0800004;
|
||||
hwrng_dsc[n++] = (uint32_t)0x82500000;
|
||||
hwrng_dsc[n++] = (uint32_t)0x60340000| (0x0000ffff & output_len);
|
||||
hwrng_dsc[n++] = (uint32_t)output;
|
||||
/* prepare job descriptor */
|
||||
init_job_desc(hwrng_desc, 0);
|
||||
append_operation(hwrng_desc, OP_ALG_ALGSEL_RNG | OP_TYPE_CLASS1_ALG);
|
||||
append_fifo_store(hwrng_desc, PTR2CAAMDMA(output),
|
||||
output_len, FIFOST_TYPE_RNGSTORE);
|
||||
|
||||
/* Run descriptor with result written to blob buffer */
|
||||
/* Add job to input ring */
|
||||
// flush cache
|
||||
g_input_ring[0] = (uint32_t)hwrng_dsc;
|
||||
/* flush cache */
|
||||
flush_dcache_range((uintptr_t)hwrng_desc & ALIGN_MASK,
|
||||
((uintptr_t)hwrng_desc & ALIGN_MASK)
|
||||
+ ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
|
||||
|
||||
flush_dcache_range((uint32_t)hwrng_dsc & ALIGN_MASK,
|
||||
((uint32_t)hwrng_dsc & ALIGN_MASK) + 128);
|
||||
flush_dcache_range((uint32_t)g_input_ring & ALIGN_MASK,
|
||||
((uint32_t)g_input_ring & ALIGN_MASK) + 128);
|
||||
invalidate_dcache_range((uint32_t)hwrng_dsc & ALIGN_MASK,
|
||||
((uint32_t)hwrng_dsc & ALIGN_MASK) + 128);
|
||||
invalidate_dcache_range((uint32_t)g_input_ring & ALIGN_MASK,
|
||||
((uint32_t)g_input_ring & ALIGN_MASK) + 128);
|
||||
invalidate_dcache_range((uint32_t)output & ALIGN_MASK,
|
||||
(((uint32_t)output + 2 * output_len + 64) & ALIGN_MASK));
|
||||
/* Increment jobs added */
|
||||
__raw_writel(1, CAAM_IRJAR0);
|
||||
ret = do_job(hwrng_desc);
|
||||
|
||||
/* Wait for job ring to complete the job: 1 completed job expected */
|
||||
size_t timeout = 100000;
|
||||
while(__raw_readl(CAAM_ORSFR0) != 1 && timeout--);
|
||||
flush_dcache_range((uint32_t)g_output_ring & ALIGN_MASK,
|
||||
((uint32_t)g_output_ring & ALIGN_MASK) + 128);
|
||||
flush_dcache_range((uintptr_t)output & ALIGN_MASK,
|
||||
((uintptr_t)output & ALIGN_MASK)
|
||||
+ ROUND(2 * output_len, ARCH_DMA_MINALIGN));
|
||||
|
||||
/* check that descriptor address is the one expected in the output ring */
|
||||
if(g_output_ring[0] == (uint32_t)hwrng_dsc) {
|
||||
/* check if any error is reported in the output ring */
|
||||
if ((g_output_ring[1] & JOB_RING_STS) != 0) {
|
||||
printf("Error: RNG job completed with errors 0x%X\n",
|
||||
g_output_ring[1]);
|
||||
ret = -1;
|
||||
if (ret != SUCCESS) {
|
||||
dump_error();
|
||||
printf("Error: RNG generate failed 0x%x\n", ret);
|
||||
}
|
||||
} else {
|
||||
printf("Error: RNG output ring descriptor address does" \
|
||||
" not match\n");
|
||||
ret = -1;
|
||||
|
||||
}
|
||||
|
||||
/* Remove job from Job Ring Output Queue */
|
||||
__raw_writel(1, CAAM_ORJRR0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -334,112 +244,496 @@ uint32_t caam_hwrng(uint8_t *output_ptr, uint32_t output_len) {
|
|||
*/
|
||||
void caam_open(void)
|
||||
{
|
||||
uint32_t temp_reg;
|
||||
//uint32_t addr;
|
||||
u32 temp_reg;
|
||||
int ret;
|
||||
|
||||
/* switch on the clock */
|
||||
#if defined(CONFIG_MX6)
|
||||
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
|
||||
temp_reg = __raw_readl(&mxc_ccm->CCGR0);
|
||||
temp_reg |= MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK |
|
||||
MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
|
||||
MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK;
|
||||
__raw_writel(temp_reg, &mxc_ccm->CCGR0);
|
||||
#elif defined(CONFIG_MX7)
|
||||
HW_CCM_CCGR_SET(36, MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK);
|
||||
#ifndef CONFIG_ARCH_IMX8
|
||||
caam_clock_enable();
|
||||
#endif
|
||||
|
||||
/* MID for CAAM - already done by HAB in ROM during preconfigure,
|
||||
* That is JROWN for JR0/1 = 1 (TZ, Secure World, ARM)
|
||||
* JRNSMID and JRSMID for JR0/1 = 2 (TZ, Secure World, CAAM)
|
||||
*
|
||||
* However, still need to initialize Job Rings as these are torn
|
||||
* down by HAB for each command
|
||||
/* reset the CAAM */
|
||||
temp_reg = __raw_readl(CAAM_MCFGR) |
|
||||
CAAM_MCFGR_DMARST | CAAM_MCFGR_SWRST;
|
||||
__raw_writel(temp_reg, CAAM_MCFGR);
|
||||
while (__raw_readl(CAAM_MCFGR) & CAAM_MCFGR_DMARST)
|
||||
;
|
||||
|
||||
jr_reset();
|
||||
ret = do_cfg_jrqueue();
|
||||
|
||||
if (ret != SUCCESS) {
|
||||
printf("Error CAAM JR initialization\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if the RNG is already instantiated */
|
||||
temp_reg = __raw_readl(CAAM_RDSTA);
|
||||
if (temp_reg == (RDSTA_IF0 | RDSTA_IF1 | RDSTA_SKVN)) {
|
||||
printf("RNG already instantiated 0x%X\n", temp_reg);
|
||||
return;
|
||||
}
|
||||
|
||||
rng_init();
|
||||
}
|
||||
|
||||
static void caam_clock_enable(void)
|
||||
{
|
||||
#if defined(CONFIG_ARCH_MX6)
|
||||
struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
|
||||
u32 reg;
|
||||
|
||||
reg = __raw_readl(&mxc_ccm->CCGR0);
|
||||
|
||||
reg |= (MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK |
|
||||
MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
|
||||
MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK);
|
||||
|
||||
__raw_writel(reg, &mxc_ccm->CCGR0);
|
||||
|
||||
#ifndef CONFIG_MX6UL
|
||||
/* EMI slow clk */
|
||||
reg = __raw_readl(&mxc_ccm->CCGR6);
|
||||
reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
|
||||
|
||||
__raw_writel(reg, &mxc_ccm->CCGR6);
|
||||
#endif
|
||||
|
||||
#elif defined(CONFIG_ARCH_MX7)
|
||||
HW_CCM_CCGR_SET(36, MXC_CCM_CCGR36_CAAM_DOMAIN0_MASK);
|
||||
#elif defined(CONFIG_ARCH_MX7ULP)
|
||||
pcc_clock_enable(PER_CLK_CAAM, true);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void kick_trng(u32 ent_delay)
|
||||
{
|
||||
u32 samples = 512; /* number of bits to generate and test */
|
||||
u32 mono_min = 195;
|
||||
u32 mono_max = 317;
|
||||
u32 mono_range = mono_max - mono_min;
|
||||
u32 poker_min = 1031;
|
||||
u32 poker_max = 1600;
|
||||
u32 poker_range = poker_max - poker_min + 1;
|
||||
u32 retries = 2;
|
||||
u32 lrun_max = 32;
|
||||
s32 run_1_min = 27;
|
||||
s32 run_1_max = 107;
|
||||
s32 run_1_range = run_1_max - run_1_min;
|
||||
s32 run_2_min = 7;
|
||||
s32 run_2_max = 62;
|
||||
s32 run_2_range = run_2_max - run_2_min;
|
||||
s32 run_3_min = 0;
|
||||
s32 run_3_max = 39;
|
||||
s32 run_3_range = run_3_max - run_3_min;
|
||||
s32 run_4_min = -1;
|
||||
s32 run_4_max = 26;
|
||||
s32 run_4_range = run_4_max - run_4_min;
|
||||
s32 run_5_min = -1;
|
||||
s32 run_5_max = 18;
|
||||
s32 run_5_range = run_5_max - run_5_min;
|
||||
s32 run_6_min = -1;
|
||||
s32 run_6_max = 17;
|
||||
s32 run_6_range = run_6_max - run_6_min;
|
||||
u32 val;
|
||||
|
||||
/* Put RNG in program mode */
|
||||
setbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
|
||||
/* Configure the RNG Entropy Delay
|
||||
* Performance-wise, it does not make sense to
|
||||
* set the delay to a value that is lower
|
||||
* than the last one that worked (i.e. the state handles
|
||||
* were instantiated properly. Thus, instead of wasting
|
||||
* time trying to set the values controlling the sample
|
||||
* frequency, the function simply returns.
|
||||
*/
|
||||
val = __raw_readl(CAAM_RTSDCTL);
|
||||
val &= BM_TRNG_ENT_DLY;
|
||||
val >>= BS_TRNG_ENT_DLY;
|
||||
if (ent_delay < val) {
|
||||
/* Put RNG4 into run mode */
|
||||
clrbits_le32(CAAM_RTMCTL, RTMCTL_PGM);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Initialize job ring addresses */
|
||||
__raw_writel((uint32_t)g_input_ring, CAAM_IRBAR0); // input ring address
|
||||
__raw_writel((uint32_t)g_output_ring, CAAM_ORBAR0); // output ring address
|
||||
val = (ent_delay << BS_TRNG_ENT_DLY) | samples;
|
||||
__raw_writel(val, CAAM_RTSDCTL);
|
||||
|
||||
/* Initialize job ring sizes to 1 */
|
||||
__raw_writel(JOB_RING_ENTRIES, CAAM_IRSR0);
|
||||
__raw_writel(JOB_RING_ENTRIES, CAAM_ORSR0);
|
||||
/* min. freq. count, equal to 1/2 of the entropy sample length */
|
||||
__raw_writel(ent_delay >> 1, CAAM_RTFRQMIN);
|
||||
|
||||
/* HAB disables interrupts for JR0 so do the same here */
|
||||
temp_reg = __raw_readl(CAAM_JRCFGR0_LS) | JRCFG_LS_IMSK;
|
||||
__raw_writel(temp_reg, CAAM_JRCFGR0_LS);
|
||||
/* max. freq. count, equal to 32 times the entropy sample length */
|
||||
__raw_writel(ent_delay << 5, CAAM_RTFRQMAX);
|
||||
|
||||
/********* Initialize and instantiate the RNG *******************/
|
||||
/* if RNG already instantiated then skip it */
|
||||
if ((__raw_readl(CAAM_RDSTA) & RDSTA_IF0) != RDSTA_IF0)
|
||||
{
|
||||
/* Enter TRNG Program mode */
|
||||
__raw_writel(RTMCTL_PGM, CAAM_RTMCTL);
|
||||
__raw_writel((retries << 16) | lrun_max, CAAM_RTSCMISC);
|
||||
__raw_writel(poker_max, CAAM_RTPKRMAX);
|
||||
__raw_writel(poker_range, CAAM_RTPKRRNG);
|
||||
__raw_writel((mono_range << 16) | mono_max, CAAM_RTSCML);
|
||||
__raw_writel((run_1_range << 16) | run_1_max, CAAM_RTSCR1L);
|
||||
__raw_writel((run_2_range << 16) | run_2_max, CAAM_RTSCR2L);
|
||||
__raw_writel((run_3_range << 16) | run_3_max, CAAM_RTSCR3L);
|
||||
__raw_writel((run_4_range << 16) | run_4_max, CAAM_RTSCR4L);
|
||||
__raw_writel((run_5_range << 16) | run_5_max, CAAM_RTSCR5L);
|
||||
__raw_writel((run_6_range << 16) | run_6_max, CAAM_RTSCR6PL);
|
||||
|
||||
/* Set OSC_DIV field to TRNG */
|
||||
temp_reg = __raw_readl(CAAM_RTMCTL) | (RNG_TRIM_OSC_DIV << 2);
|
||||
__raw_writel(temp_reg, CAAM_RTMCTL);
|
||||
|
||||
/* Set delay */
|
||||
__raw_writel(((RNG_TRIM_ENT_DLY << 16) | 0x09C4), CAAM_RTSDCTL);
|
||||
__raw_writel((RNG_TRIM_ENT_DLY >> 1), CAAM_RTFRQMIN);
|
||||
__raw_writel((RNG_TRIM_ENT_DLY << 4), CAAM_RTFRQMAX);
|
||||
|
||||
/* Resume TRNG Run mode */
|
||||
temp_reg = __raw_readl(CAAM_RTMCTL) ^ RTMCTL_PGM;
|
||||
__raw_writel(temp_reg, CAAM_RTMCTL);
|
||||
val = __raw_readl(CAAM_RTMCTL);
|
||||
/*
|
||||
* Select raw sampling in both entropy shifter
|
||||
* and statistical checker
|
||||
*/
|
||||
val &= ~BM_TRNG_SAMP_MODE;
|
||||
val |= TRNG_SAMP_MODE_RAW_ES_SC;
|
||||
/* Put RNG4 into run mode */
|
||||
val &= ~RTMCTL_PGM;
|
||||
/*test with sample mode only */
|
||||
__raw_writel(val, CAAM_RTMCTL);
|
||||
|
||||
/* Clear the ERR bit in RTMCTL if set. The TRNG error can occur when the
|
||||
* RNG clock is not within 1/2x to 8x the system clock.
|
||||
* This error is possible if ROM code does not initialize the system PLLs
|
||||
* immediately after PoR.
|
||||
*/
|
||||
temp_reg = __raw_readl(CAAM_RTMCTL) | RTMCTL_ERR;
|
||||
__raw_writel(temp_reg, CAAM_RTMCTL);
|
||||
/* setbits_le32(CAAM_RTMCTL, RTMCTL_ERR); */
|
||||
}
|
||||
|
||||
/* Run descriptor to instantiate the RNG */
|
||||
/* Add job to input ring */
|
||||
g_input_ring[0] = (uint32_t)rng_inst_dsc;
|
||||
/*
|
||||
* Descriptors to instantiate SH0, SH1, load the keys
|
||||
*/
|
||||
static const u32 rng_inst_sh0_desc[] = {
|
||||
/* Header, don't setup the size */
|
||||
CAAM_HDR_CTYPE | CAAM_HDR_ONE | CAAM_HDR_START_INDEX(0),
|
||||
/* Operation instantiation (sh0) */
|
||||
CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(0) | ALGO_RNG_INSTANTIATE,
|
||||
};
|
||||
|
||||
flush_dcache_range((uint32_t)g_input_ring & 0xffffffe0,
|
||||
((uint32_t)g_input_ring & 0xffffffe0) + 128);
|
||||
/* Increment jobs added */
|
||||
static const u32 rng_inst_sh1_desc[] = {
|
||||
/* wait for done - Jump to next entry */
|
||||
CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
|
||||
| CAAM_JUMP_OFFSET(1),
|
||||
/* Clear written register (write 1) */
|
||||
CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
|
||||
0x00000001,
|
||||
/* Operation instantiation (sh1) */
|
||||
CAAM_PROTOP_CTYPE | CAAM_C1_RNG | ALGO_RNG_SH(1)
|
||||
| ALGO_RNG_INSTANTIATE,
|
||||
};
|
||||
|
||||
static const u32 rng_inst_load_keys[] = {
|
||||
/* wait for done - Jump to next entry */
|
||||
CAAM_C1_JUMP | CAAM_JUMP_LOCAL | CAAM_JUMP_TST_ALL_COND_TRUE
|
||||
| CAAM_JUMP_OFFSET(1),
|
||||
/* Clear written register (write 1) */
|
||||
CAAM_C0_LOAD_IMM | CAAM_DST_CLEAR_WRITTEN | sizeof(u32),
|
||||
0x00000001,
|
||||
/* Generate the Key */
|
||||
CAAM_PROTOP_CTYPE | CAAM_C1_RNG | BM_ALGO_RNG_SK | ALGO_RNG_GENERATE,
|
||||
};
|
||||
|
||||
static void do_inst_desc(u32 *desc, u32 status)
|
||||
{
|
||||
u32 *pdesc = desc;
|
||||
u8 desc_len;
|
||||
bool add_sh0 = false;
|
||||
bool add_sh1 = false;
|
||||
bool load_keys = false;
|
||||
|
||||
/*
|
||||
* Modify the the descriptor to remove if necessary:
|
||||
* - The key loading
|
||||
* - One of the SH already instantiated
|
||||
*/
|
||||
desc_len = RNG_DESC_SH0_SIZE;
|
||||
if ((status & RDSTA_IF0) != RDSTA_IF0)
|
||||
add_sh0 = true;
|
||||
|
||||
if ((status & RDSTA_IF1) != RDSTA_IF1) {
|
||||
add_sh1 = true;
|
||||
if (add_sh0)
|
||||
desc_len += RNG_DESC_SH1_SIZE;
|
||||
}
|
||||
|
||||
if ((status & RDSTA_SKVN) != RDSTA_SKVN) {
|
||||
load_keys = true;
|
||||
desc_len += RNG_DESC_KEYS_SIZE;
|
||||
}
|
||||
|
||||
/* Copy the SH0 descriptor anyway */
|
||||
memcpy(pdesc, rng_inst_sh0_desc, sizeof(rng_inst_sh0_desc));
|
||||
pdesc += RNG_DESC_SH0_SIZE;
|
||||
|
||||
if (load_keys) {
|
||||
debug("RNG - Load keys\n");
|
||||
memcpy(pdesc, rng_inst_load_keys, sizeof(rng_inst_load_keys));
|
||||
pdesc += RNG_DESC_KEYS_SIZE;
|
||||
}
|
||||
|
||||
if (add_sh1) {
|
||||
if (add_sh0) {
|
||||
debug("RNG - Instantiation of SH0 and SH1\n");
|
||||
/* Add the sh1 descriptor */
|
||||
memcpy(pdesc, rng_inst_sh1_desc,
|
||||
sizeof(rng_inst_sh1_desc));
|
||||
} else {
|
||||
debug("RNG - Instantiation of SH1 only\n");
|
||||
/* Modify the SH0 descriptor to instantiate only SH1 */
|
||||
desc[1] &= ~BM_ALGO_RNG_SH;
|
||||
desc[1] |= ALGO_RNG_SH(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Setup the descriptor size */
|
||||
desc[0] &= ~(0x3F);
|
||||
desc[0] |= CAAM_HDR_DESCLEN(desc_len);
|
||||
}
|
||||
|
||||
static int jr_reset(void)
|
||||
{
|
||||
/*
|
||||
* Function reset the Job Ring HW
|
||||
* Reset is done in 2 steps:
|
||||
* - Flush all pending jobs (Set RESET bit)
|
||||
* - Reset the Job Ring (Set RESET bit second time)
|
||||
*/
|
||||
u16 timeout = 10000;
|
||||
u32 reg_val;
|
||||
|
||||
/* Mask interrupts to poll for reset completion status */
|
||||
setbits_le32(CAAM_JRCFGR0_LS, BM_JRCFGR_LS_IMSK);
|
||||
|
||||
/* Initiate flush (required prior to reset) */
|
||||
__raw_writel(JRCR_RESET, CAAM_JRCR0);
|
||||
do {
|
||||
reg_val = __raw_readl(CAAM_JRINTR0);
|
||||
reg_val &= BM_JRINTR_HALT;
|
||||
} while ((reg_val == JRINTR_HALT_ONGOING) && --timeout);
|
||||
|
||||
if (!timeout || reg_val != JRINTR_HALT_DONE) {
|
||||
printf("Failed to flush job ring\n");
|
||||
return ERROR_ANY;
|
||||
}
|
||||
|
||||
/* Initiate reset */
|
||||
timeout = 100;
|
||||
__raw_writel(JRCR_RESET, CAAM_JRCR0);
|
||||
do {
|
||||
reg_val = __raw_readl(CAAM_JRCR0);
|
||||
} while ((reg_val & JRCR_RESET) && --timeout);
|
||||
|
||||
if (!timeout) {
|
||||
printf("Failed to reset job ring\n");
|
||||
return ERROR_ANY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_job(u32 *desc)
|
||||
{
|
||||
int ret;
|
||||
phys_addr_t p_desc = virt_to_phys(desc);
|
||||
|
||||
if (__raw_readl(CAAM_IRSAR0) == 0)
|
||||
return ERROR_ANY;
|
||||
g_jrdata.inrings[0].desc = p_desc;
|
||||
|
||||
flush_dcache_range((uintptr_t)g_jrdata.inrings & ALIGN_MASK,
|
||||
((uintptr_t)g_jrdata.inrings & ALIGN_MASK)
|
||||
+ ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
|
||||
flush_dcache_range((uintptr_t)desc & ALIGN_MASK,
|
||||
((uintptr_t)desc & ALIGN_MASK)
|
||||
+ ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
|
||||
|
||||
/* Inform HW that a new JR is available */
|
||||
__raw_writel(1, CAAM_IRJAR0);
|
||||
while (__raw_readl(CAAM_ORSFR0) == 0)
|
||||
;
|
||||
|
||||
/* Wait for job ring to complete the job: 1 completed job expected */
|
||||
while(__raw_readl(CAAM_ORSFR0) != 1);
|
||||
flush_dcache_range((uintptr_t)g_jrdata.outrings & ALIGN_MASK,
|
||||
((uintptr_t)g_jrdata.outrings & ALIGN_MASK)
|
||||
+ ROUND(DESC_MAX_SIZE, ARCH_DMA_MINALIGN));
|
||||
|
||||
|
||||
invalidate_dcache_range((uint32_t)g_output_ring & 0xffffffe0,
|
||||
((uint32_t)g_output_ring & 0xffffffe0) + 128);
|
||||
|
||||
/* check that descriptor address is the one expected in the out ring */
|
||||
if(g_output_ring[0] == (uint32_t)rng_inst_dsc)
|
||||
{
|
||||
/* check if any error is reported in the output ring */
|
||||
if ((g_output_ring[1] & JOB_RING_STS) != 0)
|
||||
{
|
||||
printf("Error: RNG instantiation errors g_output_ring[1]: 0x%X\n"
|
||||
, g_output_ring[1]);
|
||||
printf("RTMCTL 0x%X\n", __raw_readl(CAAM_RTMCTL));
|
||||
printf("RTSTATUS 0x%X\n", __raw_readl(CAAM_RTSTATUS));
|
||||
printf("RTSTA 0x%X\n", __raw_readl(CAAM_RDSTA));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Error: RNG job output ring descriptor address does " \
|
||||
"not match: 0x%X != 0x%X \n", g_output_ring[0], rng_inst_dsc[0]);
|
||||
if (PTR2CAAMDMA(desc) == g_jrdata.outrings[0].desc) {
|
||||
ret = g_jrdata.outrings[0].status;
|
||||
} else {
|
||||
dump_error();
|
||||
ret = ERROR_ANY;
|
||||
}
|
||||
|
||||
/* ensure that the RNG was correctly instantiated */
|
||||
temp_reg = __raw_readl(CAAM_RDSTA);
|
||||
if (temp_reg != (RDSTA_IF0 | RDSTA_SKVN))
|
||||
{
|
||||
printf("Error: RNG instantiation failed 0x%X\n", temp_reg);
|
||||
}
|
||||
/* Remove job from Job Ring Output Queue */
|
||||
/* Acknowledge interrupt */
|
||||
setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
|
||||
|
||||
/* Remove the JR from the output list even if no JR caller found */
|
||||
__raw_writel(1, CAAM_ORJRR0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int do_cfg_jrqueue(void)
|
||||
{
|
||||
u32 value = 0;
|
||||
phys_addr_t ip_base;
|
||||
phys_addr_t op_base;
|
||||
|
||||
/* check if already configured after relocation */
|
||||
if (g_jrdata.status & RING_RELOC_INIT)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* jr configuration needs to be updated once, after relocation to ensure
|
||||
* using the right buffers.
|
||||
* When buffers are updated after relocation the flag RING_RELOC_INIT
|
||||
* is used to prevent extra updates
|
||||
*/
|
||||
if (gd->flags & GD_FLG_RELOC) {
|
||||
g_jrdata.inrings = (struct inring_entry *)
|
||||
memalign(ARCH_DMA_MINALIGN,
|
||||
ARCH_DMA_MINALIGN);
|
||||
g_jrdata.outrings = (struct outring_entry *)
|
||||
memalign(ARCH_DMA_MINALIGN,
|
||||
ARCH_DMA_MINALIGN);
|
||||
g_jrdata.desc = (u32 *)
|
||||
memalign(ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
|
||||
g_jrdata.status |= RING_RELOC_INIT;
|
||||
} else {
|
||||
u32 align_idx = 0;
|
||||
|
||||
/* Ensure 64bits buffers addresses alignment */
|
||||
if ((uintptr_t)g_jrdata.raw_addr & 0x7)
|
||||
align_idx = 1;
|
||||
g_jrdata.inrings = (struct inring_entry *)
|
||||
(&g_jrdata.raw_addr[align_idx]);
|
||||
g_jrdata.outrings = (struct outring_entry *)
|
||||
(&g_jrdata.raw_addr[align_idx + 2]);
|
||||
g_jrdata.desc = (u32 *)(&g_jrdata.raw_addr[align_idx + 4]);
|
||||
g_jrdata.status |= RING_EARLY_INIT;
|
||||
}
|
||||
|
||||
if (!g_jrdata.inrings || !g_jrdata.outrings)
|
||||
return ERROR_ANY;
|
||||
|
||||
/* Configure the HW Job Rings */
|
||||
ip_base = virt_to_phys((void *)g_jrdata.inrings);
|
||||
op_base = virt_to_phys((void *)g_jrdata.outrings);
|
||||
__raw_writel(ip_base, CAAM_IRBAR0);
|
||||
__raw_writel(1, CAAM_IRSR0);
|
||||
|
||||
__raw_writel(op_base, CAAM_ORBAR0);
|
||||
__raw_writel(1, CAAM_ORSR0);
|
||||
|
||||
setbits_le32(CAAM_JRINTR0, JRINTR_JRI);
|
||||
|
||||
/*
|
||||
* Configure interrupts but disable it:
|
||||
* Optimization to generate an interrupt either when there are
|
||||
* half of the job done or when there is a job done and
|
||||
* 10 clock cycles elapse without new job complete
|
||||
*/
|
||||
value = 10 << BS_JRCFGR_LS_ICTT;
|
||||
value |= (1 << BS_JRCFGR_LS_ICDCT) & BM_JRCFGR_LS_ICDCT;
|
||||
value |= BM_JRCFGR_LS_ICEN;
|
||||
value |= BM_JRCFGR_LS_IMSK;
|
||||
__raw_writel(value, CAAM_JRCFGR0_LS);
|
||||
|
||||
/* Enable deco watchdog */
|
||||
setbits_le32(CAAM_MCFGR, BM_MCFGR_WDE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void do_clear_rng_error(void)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = __raw_readl(CAAM_RTMCTL);
|
||||
|
||||
if (val & (RTMCTL_ERR | RTMCTL_FCT_FAIL)) {
|
||||
setbits_le32(CAAM_RTMCTL, RTMCTL_ERR);
|
||||
val = __raw_readl(CAAM_RTMCTL);
|
||||
}
|
||||
}
|
||||
|
||||
static int do_instantiation(void)
|
||||
{
|
||||
int ret = ERROR_ANY;
|
||||
u32 cha_vid_ls;
|
||||
u32 ent_delay;
|
||||
u32 status;
|
||||
|
||||
if (!g_jrdata.desc) {
|
||||
printf("%d: CAAM Descriptor allocation error\n", __LINE__);
|
||||
return ERROR_ANY;
|
||||
}
|
||||
|
||||
cha_vid_ls = __raw_readl(CAAM_CHAVID_LS);
|
||||
|
||||
/*
|
||||
* If SEC has RNG version >= 4 and RNG state handle has not been
|
||||
* already instantiated, do RNG instantiation
|
||||
*/
|
||||
if (((cha_vid_ls & BM_CHAVID_LS_RNGVID) >> BS_CHAVID_LS_RNGVID) < 4) {
|
||||
printf("%d: RNG already instantiated\n", __LINE__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ent_delay = TRNG_SDCTL_ENT_DLY_MIN;
|
||||
|
||||
do {
|
||||
/* Read the CAAM RNG status */
|
||||
status = __raw_readl(CAAM_RDSTA);
|
||||
|
||||
if ((status & RDSTA_IF0) != RDSTA_IF0) {
|
||||
/* Configure the RNG entropy delay */
|
||||
kick_trng(ent_delay);
|
||||
ent_delay += 400;
|
||||
}
|
||||
|
||||
do_clear_rng_error();
|
||||
|
||||
if ((status & (RDSTA_IF0 | RDSTA_IF1)) !=
|
||||
(RDSTA_IF0 | RDSTA_IF1)) {
|
||||
/* Prepare the instantiation descriptor */
|
||||
do_inst_desc(g_jrdata.desc, status);
|
||||
|
||||
/* Run Job */
|
||||
ret = do_job(g_jrdata.desc);
|
||||
|
||||
if (ret == ERROR_ANY) {
|
||||
/* CAAM JR failure ends here */
|
||||
printf("RNG Instantiation error\n");
|
||||
dump_error();
|
||||
goto end_instantation;
|
||||
}
|
||||
} else {
|
||||
ret = SUCCESS;
|
||||
printf("RNG instantiation done (%d)\n", ent_delay);
|
||||
goto end_instantation;
|
||||
}
|
||||
} while (ent_delay < TRNG_SDCTL_ENT_DLY_MAX);
|
||||
|
||||
printf("RNG Instantation Failure - Entropy delay (%d)\n", ent_delay);
|
||||
ret = ERROR_ANY;
|
||||
|
||||
end_instantation:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rng_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = jr_reset();
|
||||
if (ret != SUCCESS) {
|
||||
printf("Error CAAM JR reset\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = do_instantiation();
|
||||
|
||||
if (ret != SUCCESS)
|
||||
printf("Error do_instantiation\n");
|
||||
|
||||
jr_reset();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
* Copyright 2018 NXP
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
|
|
@ -40,69 +41,82 @@
|
|||
#define SEC_MEM_PAGE3 (CAAM_SEC_RAM_START_ADDR + 0x3000)
|
||||
|
||||
/* Configuration and special key registers */
|
||||
#define CAAM_MCFGR CONFIG_SYS_FSL_SEC_ADDR + 0x0004
|
||||
#define CAAM_SCFGR CONFIG_SYS_FSL_SEC_ADDR + 0x000c
|
||||
#define CAAM_JR0MIDR CONFIG_SYS_FSL_SEC_ADDR + 0x0010
|
||||
#define CAAM_JR1MIDR CONFIG_SYS_FSL_SEC_ADDR + 0x0018
|
||||
#define CAAM_DECORR CONFIG_SYS_FSL_SEC_ADDR + 0x009c
|
||||
#define CAAM_DECO0MID CONFIG_SYS_FSL_SEC_ADDR + 0x00a0
|
||||
#define CAAM_DAR CONFIG_SYS_FSL_SEC_ADDR + 0x0120
|
||||
#define CAAM_DRR CONFIG_SYS_FSL_SEC_ADDR + 0x0124
|
||||
#define CAAM_JDKEKR CONFIG_SYS_FSL_SEC_ADDR + 0x0400
|
||||
#define CAAM_TDKEKR CONFIG_SYS_FSL_SEC_ADDR + 0x0420
|
||||
#define CAAM_TDSKR CONFIG_SYS_FSL_SEC_ADDR + 0x0440
|
||||
#define CAAM_SKNR CONFIG_SYS_FSL_SEC_ADDR + 0x04e0
|
||||
#define CAAM_SMSTA CONFIG_SYS_FSL_SEC_ADDR + 0x0FB4
|
||||
#define CAAM_STA CONFIG_SYS_FSL_SEC_ADDR + 0x0FD4
|
||||
#define CAAM_SMPO_0 CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC
|
||||
#define CAAM_MCFGR (CONFIG_SYS_FSL_SEC_ADDR + 0x0004)
|
||||
#define CAAM_SCFGR (CONFIG_SYS_FSL_SEC_ADDR + 0x000c)
|
||||
#define CAAM_JR0MIDR (CONFIG_SYS_FSL_SEC_ADDR + 0x0010)
|
||||
#define CAAM_JR1MIDR (CONFIG_SYS_FSL_SEC_ADDR + 0x0018)
|
||||
#define CAAM_DECORR (CONFIG_SYS_FSL_SEC_ADDR + 0x009c)
|
||||
#define CAAM_DECO0MID (CONFIG_SYS_FSL_SEC_ADDR + 0x00a0)
|
||||
#define CAAM_DAR (CONFIG_SYS_FSL_SEC_ADDR + 0x0120)
|
||||
#define CAAM_DRR (CONFIG_SYS_FSL_SEC_ADDR + 0x0124)
|
||||
#define CAAM_JDKEKR (CONFIG_SYS_FSL_SEC_ADDR + 0x0400)
|
||||
#define CAAM_TDKEKR (CONFIG_SYS_FSL_SEC_ADDR + 0x0420)
|
||||
#define CAAM_TDSKR (CONFIG_SYS_FSL_SEC_ADDR + 0x0440)
|
||||
#define CAAM_SKNR (CONFIG_SYS_FSL_SEC_ADDR + 0x04e0)
|
||||
#define CAAM_SMSTA (CONFIG_SYS_FSL_SEC_ADDR + 0x0FB4)
|
||||
#define CAAM_STA (CONFIG_SYS_FSL_SEC_ADDR + 0x0FD4)
|
||||
#define CAAM_SMPO_0 (CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC)
|
||||
#define CAAM_CHAVID_LS (CONFIG_SYS_FSL_SEC_ADDR + 0x0FEC)
|
||||
#define CAAM_FAR (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC0)
|
||||
#define CAAM_FAMR (CONFIG_SYS_FSL_SEC_ADDR + 0x0FC8)
|
||||
#define CAAM_FADR (CONFIG_SYS_FSL_SEC_ADDR + 0x0FCC)
|
||||
|
||||
/* RNG registers */
|
||||
#define CAAM_RTMCTL CONFIG_SYS_FSL_SEC_ADDR + 0x0600
|
||||
#define CAAM_RTSDCTL CONFIG_SYS_FSL_SEC_ADDR + 0x0610
|
||||
#define CAAM_RTFRQMIN CONFIG_SYS_FSL_SEC_ADDR + 0x0618
|
||||
#define CAAM_RTFRQMAX CONFIG_SYS_FSL_SEC_ADDR + 0x061C
|
||||
#define CAAM_RTSTATUS CONFIG_SYS_FSL_SEC_ADDR + 0x063C
|
||||
#define CAAM_RDSTA CONFIG_SYS_FSL_SEC_ADDR + 0x06C0
|
||||
#define CAAM_RTMCTL (CONFIG_SYS_FSL_SEC_ADDR + 0x0600)
|
||||
#define CAAM_RTSCMISC (CONFIG_SYS_FSL_SEC_ADDR + 0x0604)
|
||||
#define CAAM_RTPKRRNG (CONFIG_SYS_FSL_SEC_ADDR + 0x0608)
|
||||
#define CAAM_RTPKRMAX (CONFIG_SYS_FSL_SEC_ADDR + 0x060C)
|
||||
#define CAAM_RTSDCTL (CONFIG_SYS_FSL_SEC_ADDR + 0x0610)
|
||||
#define CAAM_RTFRQMIN (CONFIG_SYS_FSL_SEC_ADDR + 0x0618)
|
||||
#define CAAM_RTFRQMAX (CONFIG_SYS_FSL_SEC_ADDR + 0x061C)
|
||||
#define CAAM_RTSCML (CONFIG_SYS_FSL_SEC_ADDR + 0x0620)
|
||||
#define CAAM_RTSCR1L (CONFIG_SYS_FSL_SEC_ADDR + 0x0624)
|
||||
#define CAAM_RTSCR2L (CONFIG_SYS_FSL_SEC_ADDR + 0x0628)
|
||||
#define CAAM_RTSCR3L (CONFIG_SYS_FSL_SEC_ADDR + 0x062C)
|
||||
#define CAAM_RTSCR4L (CONFIG_SYS_FSL_SEC_ADDR + 0x0630)
|
||||
#define CAAM_RTSCR5L (CONFIG_SYS_FSL_SEC_ADDR + 0x0634)
|
||||
#define CAAM_RTSCR6PL (CONFIG_SYS_FSL_SEC_ADDR + 0x0638)
|
||||
#define CAAM_RTSTATUS (CONFIG_SYS_FSL_SEC_ADDR + 0x063C)
|
||||
#define CAAM_RDSTA (CONFIG_SYS_FSL_SEC_ADDR + 0x06C0)
|
||||
|
||||
/* Job Ring 0 registers */
|
||||
#define CAAM_IRBAR0 CONFIG_SYS_FSL_SEC_ADDR + 0x1004
|
||||
#define CAAM_IRSR0 CONFIG_SYS_FSL_SEC_ADDR + 0x100c
|
||||
#define CAAM_IRSAR0 CONFIG_SYS_FSL_SEC_ADDR + 0x1014
|
||||
#define CAAM_IRJAR0 CONFIG_SYS_FSL_SEC_ADDR + 0x101c
|
||||
#define CAAM_ORBAR0 CONFIG_SYS_FSL_SEC_ADDR + 0x1024
|
||||
#define CAAM_ORSR0 CONFIG_SYS_FSL_SEC_ADDR + 0x102c
|
||||
#define CAAM_ORJRR0 CONFIG_SYS_FSL_SEC_ADDR + 0x1034
|
||||
#define CAAM_ORSFR0 CONFIG_SYS_FSL_SEC_ADDR + 0x103c
|
||||
#define CAAM_JRSTAR0 CONFIG_SYS_FSL_SEC_ADDR + 0x1044
|
||||
#define CAAM_JRINTR0 CONFIG_SYS_FSL_SEC_ADDR + 0x104c
|
||||
#define CAAM_JRCFGR0_MS CONFIG_SYS_FSL_SEC_ADDR + 0x1050
|
||||
#define CAAM_JRCFGR0_LS CONFIG_SYS_FSL_SEC_ADDR + 0x1054
|
||||
#define CAAM_IRRIR0 CONFIG_SYS_FSL_SEC_ADDR + 0x105c
|
||||
#define CAAM_ORWIR0 CONFIG_SYS_FSL_SEC_ADDR + 0x1064
|
||||
#define CAAM_JRCR0 CONFIG_SYS_FSL_SEC_ADDR + 0x106c
|
||||
#define CAAM_SMCJR0 CONFIG_SYS_FSL_SEC_ADDR + 0x10f4
|
||||
#define CAAM_SMCSJR0 CONFIG_SYS_FSL_SEC_ADDR + 0x10fc
|
||||
#define CAAM_IRBAR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x1004)
|
||||
#define CAAM_IRSR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x100c)
|
||||
#define CAAM_IRSAR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x1014)
|
||||
#define CAAM_IRJAR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x101c)
|
||||
#define CAAM_ORBAR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x1024)
|
||||
#define CAAM_ORSR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x102c)
|
||||
#define CAAM_ORJRR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x1034)
|
||||
#define CAAM_ORSFR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x103c)
|
||||
#define CAAM_JRSTAR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x1044)
|
||||
#define CAAM_JRINTR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x104c)
|
||||
#define CAAM_JRCFGR0_MS (CONFIG_SYS_FSL_SEC_ADDR + 0x1050)
|
||||
#define CAAM_JRCFGR0_LS (CONFIG_SYS_FSL_SEC_ADDR + 0x1054)
|
||||
#define CAAM_IRRIR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x105c)
|
||||
#define CAAM_ORWIR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x1064)
|
||||
#define CAAM_JRCR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x106c)
|
||||
#define CAAM_SMCJR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x10f4)
|
||||
#define CAAM_SMCSJR0 (CONFIG_SYS_FSL_SEC_ADDR + 0x10fc)
|
||||
#define CAAM_SMAPJR0(y) (CONFIG_SYS_FSL_SEC_ADDR + 0x1104 + y*16)
|
||||
#define CAAM_SMAG2JR0(y) (CONFIG_SYS_FSL_SEC_ADDR + 0x1108 + y*16)
|
||||
#define CAAM_SMAG1JR0(y) (CONFIG_SYS_FSL_SEC_ADDR + 0x110C + y*16)
|
||||
#define CAAM_SMAPJR0_PRTN1 CONFIG_SYS_FSL_SEC_ADDR + 0x1114
|
||||
#define CAAM_SMAG2JR0_PRTN1 CONFIG_SYS_FSL_SEC_ADDR + 0x1118
|
||||
#define CAAM_SMAG1JR0_PRTN1 CONFIG_SYS_FSL_SEC_ADDR + 0x111c
|
||||
#define CAAM_SMPO CONFIG_SYS_FSL_SEC_ADDR + 0x1fbc
|
||||
#define CAAM_SMAPJR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x1114)
|
||||
#define CAAM_SMAG2JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x1118)
|
||||
#define CAAM_SMAG1JR0_PRTN1 (CONFIG_SYS_FSL_SEC_ADDR + 0x111c)
|
||||
#define CAAM_SMPO (CONFIG_SYS_FSL_SEC_ADDR + 0x1fbc)
|
||||
|
||||
#define JRCFG_LS_IMSK 0x00000001 /* Interrupt Mask */
|
||||
#define JR_MID 2 /* Matches ROM configuration */
|
||||
#define KS_G1 (1 << JR_MID) /* CAAM only */
|
||||
#define PERM 0x0000B008 /* Clear on release,
|
||||
* lock SMAP
|
||||
* lock SMAG
|
||||
* group 1 Blob
|
||||
#define DESC_MAX_SIZE (0x40) /* Descriptor max size */
|
||||
#define JRCFG_LS_IMSK (0x01) /* Interrupt Mask */
|
||||
#define JR_MID (0x02) /* Matches ROM configuration */
|
||||
#define KS_G1 BIT(JR_MID) /* CAAM only */
|
||||
#define PERM (0x0000B008) /* Clear on release, lock SMAP,
|
||||
* lock SMAG and group 1 Blob
|
||||
*/
|
||||
|
||||
#define CMD_PAGE_ALLOC 0x1
|
||||
#define CMD_PAGE_DEALLOC 0x2
|
||||
#define CMD_PART_DEALLOC 0x3
|
||||
#define CMD_INQUIRY 0x5
|
||||
#define CMD_PAGE_ALLOC (0x1)
|
||||
#define CMD_PAGE_DEALLOC (0x2)
|
||||
#define CMD_PART_DEALLOC (0x3)
|
||||
#define CMD_INQUIRY (0x5)
|
||||
#define PAGE(x) (x << 16)
|
||||
#define PARTITION(x) (x << 8)
|
||||
|
||||
|
|
@ -111,27 +125,55 @@
|
|||
#define CMD_COMPLETE (3 << 14)
|
||||
|
||||
#define SMCSJR_PO (3 << 6)
|
||||
#define PAGE_AVAILABLE 0
|
||||
#define PAGE_AVAILABLE (0)
|
||||
#define PAGE_OWNED (3 << 6)
|
||||
|
||||
#define PARTITION_OWNER(x) (0x3 << (x*2))
|
||||
|
||||
#define CAAM_BUSY_MASK 0x00000001 /* BUSY from status reg */
|
||||
#define CAAM_IDLE_MASK 0x00000002 /* IDLE from status reg */
|
||||
#define CAAM_BUSY_MASK (0x00000001) /* BUSY from status reg */
|
||||
#define CAAM_IDLE_MASK (0x00000002) /* IDLE from status reg */
|
||||
#define CAAM_MCFGR_SWRST BIT(31) /* CAAM SW reset */
|
||||
#define CAAM_MCFGR_DMARST BIT(28) /* CAAM DMA reset */
|
||||
|
||||
#define JOB_RING_ENTRIES 1
|
||||
#define JOB_RING_ENTRIES (1)
|
||||
#define JOB_RING_STS (0xF << 28)
|
||||
|
||||
/** OSC_DIV in RNG trim fuses */
|
||||
#define RNG_TRIM_OSC_DIV 0
|
||||
#define RNG_TRIM_OSC_DIV (0)
|
||||
/** ENT_DLY multiplier in RNG trim fuses */
|
||||
//#define RNG_TRIM_ENT_DLY 200*4
|
||||
#define RNG_TRIM_ENT_DLY 3200
|
||||
#define TRNG_SDCTL_ENT_DLY_MIN (3200)
|
||||
#define TRNG_SDCTL_ENT_DLY_MAX (4800)
|
||||
|
||||
#define RTMCTL_PGM (1 << 16)
|
||||
#define RTMCTL_ERR (1 << 12)
|
||||
#define RDSTA_IF0 1
|
||||
#define RDSTA_SKVN (1 << 30)
|
||||
#define RTMCTL_PGM BIT(16)
|
||||
#define RTMCTL_ERR BIT(12)
|
||||
#define RTMCTL_RST BIT(6)
|
||||
#define RDSTA_IF0 (1)
|
||||
#define RDSTA_IF1 (2)
|
||||
#define RDSTA_SKVN BIT(30)
|
||||
#define JRCR_RESET (1)
|
||||
#define RTMCTL_FCT_FAIL BIT(8)
|
||||
|
||||
#define BS_TRNG_ENT_DLY (16)
|
||||
#define BM_TRNG_ENT_DLY (0xffff << BS_TRNG_ENT_DLY)
|
||||
#define BM_TRNG_SAMP_MODE (3)
|
||||
#define TRNG_SAMP_MODE_RAW_ES_SC (1)
|
||||
#define BS_JRINTR_HALT (2)
|
||||
#define BM_JRINTR_HALT (0x3 << BS_JRINTR_HALT)
|
||||
#define JRINTR_HALT_ONGOING (0x1 << BS_JRINTR_HALT)
|
||||
#define JRINTR_HALT_DONE (0x2 << BS_JRINTR_HALT)
|
||||
#define JRINTR_JRI (0x1)
|
||||
#define BS_JRCFGR_LS_ICTT (16)
|
||||
#define BM_JRCFGR_LS_ICTT (0xFFFF << BS_JRCFGR_LS_ICTT)
|
||||
#define BS_JRCFGR_LS_ICDCT (8)
|
||||
#define BM_JRCFGR_LS_ICDCT (0xFF << BS_JRCFGR_LS_ICDCT)
|
||||
#define BS_JRCFGR_LS_ICEN (1)
|
||||
#define BM_JRCFGR_LS_ICEN (0x1 << BS_JRCFGR_LS_ICEN)
|
||||
#define BS_JRCFGR_LS_IMSK (0)
|
||||
#define BM_JRCFGR_LS_IMSK (0x1 << BS_JRCFGR_LS_IMSK)
|
||||
#define BS_CHAVID_LS_RNGVID (16)
|
||||
#define BM_CHAVID_LS_RNGVID (0xF << BS_CHAVID_LS_RNGVID)
|
||||
#define BS_MCFGR_WDE (30)
|
||||
#define BM_MCFGR_WDE (0x1 << BS_MCFGR_WDE)
|
||||
|
||||
typedef enum {
|
||||
PAGE_0,
|
||||
|
|
@ -151,251 +193,63 @@ typedef enum {
|
|||
PARTITION_7,
|
||||
} partition_num_e;
|
||||
|
||||
/*****************************************
|
||||
*----- Blob decapsulate descriptor -----*
|
||||
*****************************************/
|
||||
/* 1. Header
|
||||
*
|
||||
* 1011 0000 1000 0000 0000 0000 0000 1001
|
||||
* |||| | ||||
|
||||
* ++++-+-- Header ++++-- 9 words in descriptor
|
||||
|
||||
/*
|
||||
* Local defines
|
||||
*/
|
||||
#define DECAP_BLOB_DESC1 0xB0800009
|
||||
/* arm v7 need 64 align */
|
||||
#define ALIGN_MASK ~(ARCH_DMA_MINALIGN - 1)
|
||||
/* caam dma and pointer conversion for arm and arm64 architectures */
|
||||
#ifdef CONFIG_IMX_CONFIG
|
||||
#define PTR2CAAMDMA(x) (u32)((uintptr_t)(x) & 0xffffffff)
|
||||
#define CAAMDMA2PTR(x) (uintptr_t)((x) & 0xffffffff)
|
||||
#else
|
||||
#define PTR2CAAMDMA(x) (uintptr_t)(x)
|
||||
#define CAAMDMA2PTR(x) (uintptr_t)(x)
|
||||
#endif
|
||||
#define RING_EARLY_INIT (0x01)
|
||||
#define RING_RELOC_INIT (0x02)
|
||||
|
||||
/* 2. Load command KEY 2 immediate
|
||||
*
|
||||
* 0001 0100 1100 0000 0000 1100 0000 1000
|
||||
* |||| ||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| ||| |||| |||| |||| |||| ++++-++++-- Length
|
||||
* |||| ||| |||| |||| ++++-++++-- Offset
|
||||
* |||| ||| |+++-++++-- DST (Destination Register) Key2
|
||||
* |||| ||| +-- IMM (Immediate flag)
|
||||
* |||| |++-- class 2
|
||||
* ++++-+-- Load command
|
||||
*/
|
||||
#define DECAP_BLOB_DESC2 0x14C00C08
|
||||
#define CAAM_HDR_CTYPE (0x16u << 27)
|
||||
#define CAAM_HDR_ONE BIT(23)
|
||||
#define CAAM_HDR_START_INDEX(x) (((x) & 0x3F) << 16)
|
||||
#define CAAM_HDR_DESCLEN(x) ((x) & 0x3F)
|
||||
#define CAAM_PROTOP_CTYPE (0x10u << 27)
|
||||
|
||||
/* 3. 8 bytes for load command above - aad data
|
||||
*
|
||||
* 0000 0000 0001 0000 0101 0101 0110 0110
|
||||
* |||| |||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| |||| |||| |||| |||| |||| ++++-++++-- CCM Mode
|
||||
* |||| |||| |||| |||| ++++-++++-- AES
|
||||
* |||| |||| ++++-++++-- Length
|
||||
* ++++-++++-- Flag
|
||||
*/
|
||||
#define DECAP_BLOB_DESC3 0x00105566
|
||||
#define DECAP_BLOB_DESC4 0x00000000
|
||||
/* State Handle */
|
||||
#define BS_ALGO_RNG_SH (4)
|
||||
#define BM_ALGO_RNG_SH (0x3 << BS_ALGO_RNG_SH)
|
||||
#define ALGO_RNG_SH(id) (((id) << BS_ALGO_RNG_SH) & BM_ALGO_RNG_SH)
|
||||
|
||||
/* 5. SEQ In Ptr
|
||||
*
|
||||
* 1111 0000 0000 0000 0000 0000 0100 0000
|
||||
* |||| | |||| |||| |||| ||||
|
||||
* |||| | ++++-++++-++++-++++-- Length in bytes (64)
|
||||
* ++++-+-- Seq In Ptr
|
||||
*/
|
||||
#define DECAP_BLOB_DESC5 0xF0000400
|
||||
//#define DECAP_BLOB_DESC5 0xF0000040
|
||||
/* Secure Key */
|
||||
#define BS_ALGO_RNG_SK (12)
|
||||
#define BM_ALGO_RNG_SK BIT(BS_ALGO_RNG_SK)
|
||||
|
||||
/* 6. Pointer for above SEQ In ptr command */
|
||||
/* Address is provided during run time */
|
||||
#define DECAP_BLOB_DESC6 0x00000000
|
||||
/* State */
|
||||
#define BS_ALGO_RNG_AS (2)
|
||||
#define BM_ALGO_RNG_AS (0x3 << BS_ALGO_RNG_AS)
|
||||
#define ALGO_RNG_GENERATE (0x0 << BS_ALGO_RNG_AS)
|
||||
#define ALGO_RNG_INSTANTIATE BIT(BS_ALGO_RNG_AS)
|
||||
|
||||
/* 7. SEQ Out Ptr
|
||||
*
|
||||
* 1111 1000 0000 0000 0000 0000 0001 0000
|
||||
* |||| | |||| |||| |||| ||||
|
||||
* |||| | ++++-++++-++++-++++-- Length in bytes (16)
|
||||
* ++++-+-- Seq In Ptr
|
||||
*/
|
||||
#define DECAP_BLOB_DESC7 0xF80003d0
|
||||
//#define DECAP_BLOB_DESC7 0xF8000010
|
||||
#define CAAM_C1_RNG ((0x50 << 16) | (2 << 24))
|
||||
|
||||
/* 8. Pointer for above SEQ Out ptr command */
|
||||
/* Address could be changed during run time */
|
||||
#define DECAP_BLOB_DESC8 SEC_MEM_PAGE1
|
||||
#define BS_JUMP_LOCAL_OFFSET (0)
|
||||
#define BM_JUMP_LOCAL_OFFSET (0xFF << BS_JUMP_LOCAL_OFFSET)
|
||||
|
||||
/* 9. Protocol
|
||||
*
|
||||
* 1000 0110 0000 1101 0000 0000 0000 1000
|
||||
* |||| |||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| |||| |||| |||| ++++-++++-++++-++++-- Proto Info = sec mem blob
|
||||
* |||| |||| ++++-++++-- Protocol ID = Blob
|
||||
* |||| |+++-- Optype - decapsulation protocol
|
||||
* ++++-+-- Seq In Ptr
|
||||
*/
|
||||
#define DECAP_BLOB_DESC9 0x860D0008
|
||||
#define CAAM_C1_JUMP ((0x14u << 27) | (1 << 25))
|
||||
#define CAAM_JUMP_LOCAL (0 << 20)
|
||||
#define CAAM_JUMP_TST_ALL_COND_TRUE (0 << 16)
|
||||
#define CAAM_JUMP_OFFSET(off) (((off) << BS_JUMP_LOCAL_OFFSET) \
|
||||
& BM_JUMP_LOCAL_OFFSET)
|
||||
|
||||
/*****************************************
|
||||
*----- Blob encapsulate descriptor -----*
|
||||
*****************************************/
|
||||
/* Blob Header
|
||||
*
|
||||
* 1011 0000 1000 0000 0000 0000 0000 1001
|
||||
* |||| | |
|
||||
* ++++-+-- Header +-- 9 words in descriptor
|
||||
*/
|
||||
#define ENCAP_BLOB_DESC1 0xB0800009
|
||||
#define CAAM_C0_LOAD_IMM ((0x2 << 27) | (1 << 23))
|
||||
#define CAAM_DST_CLEAR_WRITTEN (0x8 << 16)
|
||||
|
||||
/* 2. Load command KEY 2 immediate
|
||||
*
|
||||
* 0001 0100 1100 0000 0000 1100 0000 1000
|
||||
* |||| ||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| ||| |||| |||| |||| |||| ++++-++++-- Length
|
||||
* |||| ||| |||| |||| ++++-++++-- Offset
|
||||
* |||| ||| |+++-++++-- DST (Destination Register) Key2
|
||||
* |||| ||| +-- IMM (Immediate flag)
|
||||
* |||| |++-- class 2
|
||||
* ++++-+-- Load command
|
||||
*/
|
||||
#define ENCAP_BLOB_DESC2 0x14C00C08
|
||||
|
||||
/* 3. 8 bytes for load command above - aad data
|
||||
*
|
||||
* 0000 0000 0001 0000 0101 0101 0110 0110
|
||||
* |||| |||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| |||| |||| |||| |||| |||| ++++-++++-- CCM Mode
|
||||
* |||| |||| |||| |||| ++++-++++-- AES
|
||||
* |||| |||| ++++-++++-- Length
|
||||
* ++++-++++-- Flag
|
||||
*/
|
||||
#define ENCAP_BLOB_DESC3 0x00105566
|
||||
#define ENCAP_BLOB_DESC4 0x00000000
|
||||
|
||||
/* 5. SEQ In Ptr
|
||||
*
|
||||
* 1111 0000 0000 0000 0000 0000 0001 0000
|
||||
* |||| | |||| |||| |||| ||||
|
||||
* |||| | ++++-++++-++++-++++-- Length in bytes (16)
|
||||
* ++++-+-- Seq In Ptr
|
||||
*/
|
||||
#define ENCAP_BLOB_DESC5 0xF00003d0
|
||||
//#define ENCAP_BLOB_DESC5 0xF0000010
|
||||
|
||||
/* 6. Pointer for above SEQ In ptr command */
|
||||
/* Address could be changed during run time */
|
||||
#define ENCAP_BLOB_DESC6 SEC_MEM_PAGE1
|
||||
|
||||
/* 7. SEQ Out Ptr
|
||||
*
|
||||
* 1111 1000 0000 0000 0000 0000 0100 0000
|
||||
* |||| | |||| |||| |||| ||||
|
||||
* |||| | ++++-++++-++++-++++-- Length in bytes (64)
|
||||
* ++++-+-- Seq Out Ptr
|
||||
*/
|
||||
#define ENCAP_BLOB_DESC7 0xF8000400
|
||||
//#define ENCAP_BLOB_DESC7 0xF8000040
|
||||
|
||||
/* 8. Pointer for above SEQ Out ptr command */
|
||||
/* Address is provided during run time */
|
||||
#define ENCAP_BLOB_DESC8 0x00000000
|
||||
|
||||
/* 9. Protocol
|
||||
*
|
||||
* 1000 0111 0000 1101 0000 0000 0000 1000
|
||||
* |||| |||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| |||| |||| |||| ++++-++++-++++-++++-- Proto Info = sec mem blob
|
||||
* |||| |||| ++++-++++-- Protocol ID = Blob
|
||||
* |||| |+++-- Optype - encapsulation protocol
|
||||
* ++++-+-- Seq In Ptr
|
||||
*/
|
||||
#define ENCAP_BLOB_DESC9 0x870D0008
|
||||
|
||||
/****************************************
|
||||
*----- Data encryption descriptor -----*
|
||||
****************************************/
|
||||
/* 1. Header
|
||||
*
|
||||
* 1011 0000 1000 0000 0000 0000 0000 1000
|
||||
* |||| | | ||||
|
||||
* ++++-+-- Header +-++++-- 8 words in descriptor
|
||||
*/
|
||||
#define ENCRYPT_DESC1 0xB0800008
|
||||
|
||||
/* 2. Load AES-128 key from secure memory
|
||||
*
|
||||
* 0010 0010 0000 0000 0000 0000 0001 0000
|
||||
* |||| | | |||| |||| |||| ||||
|
||||
* |||| | | ++++-++++-++++-++++-- 16 bytes
|
||||
* |||| | +-- Load FIFO with data for Class 1 CHA
|
||||
* ++++-+-- FIFO Load
|
||||
*/
|
||||
#define ENCRYPT_DESC2 0x02200010
|
||||
|
||||
/* 3. Pointer to key data in secure memory */
|
||||
/* Address is provided during run time */
|
||||
#define ENCRYPT_DESC3 0x00000000
|
||||
|
||||
/* 4. Algorith Operation - Decrypt with ECB mode
|
||||
*
|
||||
* 1000 0010 0001 0000 0000 0010 0000 1101
|
||||
* |||| |||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| |||| |||| |||| |||| |||| |||| |||+-- Encrypt
|
||||
* |||| |||| |||| |||| |||| |||| |||| ++-- Initialize/Finalize
|
||||
* |||| |||| |||| |||| ---+-++++-++++-- ECB mode
|
||||
* |||| |||| ++++-++++-- AES
|
||||
* |||| |+++-- Optype: Class 1 algorithm
|
||||
* ++++-+-- ALGORITHM OP.
|
||||
*/
|
||||
#define ENCRYPT_DESC4 0x8210020D
|
||||
|
||||
/* 5. Load 16 bytes of message data
|
||||
*
|
||||
* 0010 0010 0001 0010 0000 0000 0001 0000
|
||||
* |||| |||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| |||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| |||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| |||| |||| |||| ++++-++++-++++-++++-- Msg Length = 16Bytes
|
||||
* |||| |||| ||++-++++-- Input data type: Msg data LC1=1
|
||||
* |||| |||| |+-- EXT: No extended length
|
||||
* |||| |||| +-- IMM: data begins at the location pointed to by the next word
|
||||
* |||| |||++-SGT/VLF: FIFO Load-Pointer points to actual data
|
||||
* |||| |++-- Load FIFO with data for Class 1 CHA
|
||||
* ++++-+-- FIFO Load
|
||||
*/
|
||||
#define ENCRYPT_DESC5 0x22120010
|
||||
|
||||
/* 6. Pointer to plain text test vector message */
|
||||
/* Address is provided during run time */
|
||||
#define ENCRYPT_DESC6 0x00000000
|
||||
|
||||
/* 7. FIFO STORE - encrypted result.
|
||||
* 0110 0000 0011 0000 0000 0000 0001 0000
|
||||
* |||| |||| |||| |||| |||| |||| |||| ||||
|
||||
* |||| |||| |||| |||| ++++-++++-++++-++++-- Length = 16Bytes
|
||||
* |||| |||| ||++-++++-- Output data type: Msg Data
|
||||
* |||| |||| |+-- EXT: No extended length
|
||||
* |||| |||| +-- CONT: No continue
|
||||
* |||| |||+-- SGT/VLF: Pointer points to actual data
|
||||
* |||| |++-- AUX: None
|
||||
* ++++-+-- FIFO Store
|
||||
*/
|
||||
#define ENCRYPT_DESC7 0x60300010
|
||||
|
||||
/* 8. Pointer to ciphered text buffer */
|
||||
/* Address is provided during run time */
|
||||
#define ENCRYPT_DESC8 0x00000000
|
||||
|
||||
/*********************************************************************
|
||||
*----- Descriptor to instantiate RNG in non-deterministic mode -----*
|
||||
*********************************************************************/
|
||||
// Header
|
||||
#define RNG_INST_DESC1 0xB0800009
|
||||
// Class 1 context load for personalization string, 8bytes
|
||||
#define RNG_INST_DESC2 0x12A00008
|
||||
// 8 bytes of personalization string (8-byte UID + zeros)
|
||||
#define RNG_INST_DESC3 0x01020304
|
||||
#define RNG_INST_DESC4 0x05060708
|
||||
// Instantiate State Handle 0 using entropy from TRNG
|
||||
// without prediction resistance
|
||||
#define RNG_INST_DESC5 0x82500404
|
||||
// Wait for Class 1 done
|
||||
#define RNG_INST_DESC6 0xA2000001
|
||||
// Immediate 4 byte load to clear written register
|
||||
#define RNG_INST_DESC7 0x10880004
|
||||
// Clear primary mode bit
|
||||
#define RNG_INST_DESC8 0x00000001
|
||||
// Generate secure keys without prediction resistance
|
||||
#define RNG_INST_DESC9 0x82501000
|
||||
#define RNG_DESC_SH0_SIZE (ARRAY_SIZE(rng_inst_sh0_desc))
|
||||
#define RNG_DESC_SH1_SIZE (ARRAY_SIZE(rng_inst_sh1_desc))
|
||||
#define RNG_DESC_KEYS_SIZE (ARRAY_SIZE(rng_inst_load_keys))
|
||||
#define RNG_DESC_MAX_SIZE (RNG_DESC_SH0_SIZE + \
|
||||
RNG_DESC_SH1_SIZE + \
|
||||
RNG_DESC_KEYS_SIZE)
|
||||
|
||||
#endif /* __CAAM_INTERNAL_H__ */
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2012-2016, Freescale Semiconductor, Inc.
|
||||
* All rights reserved.
|
||||
* Copyright 2018 NXP
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
|
|
@ -37,6 +38,7 @@
|
|||
#define SUCCESS (0)
|
||||
#endif
|
||||
|
||||
#define ERROR_ANY (-1)
|
||||
#define ERROR_IN_PAGE_ALLOC (1)
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue