mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-24 12:44:23 +08:00
imx6: Added DEK blob generator command
Freescale's SEC block has built-in Data Encryption Key(DEK) Blob Protocol which provides a method for protecting a DEK for non-secure memory storage. SEC block protects data in a data structure called a Secret Key Blob, which provides both confidentiality and integrity protection. Every time the blob encapsulation is executed, a AES-256 key is randomly generated to encrypt the DEK. This key is encrypted with the OTP Secret key from SoC. The resulting blob consists of the encrypted AES-256 key, the encrypted DEK, and a 16-bit MAC. During decapsulation, the reverse process is performed to get back the original DEK. A caveat to the blob decapsulation process, is that the DEK is decrypted in secure-memory and can only be read by FSL SEC HW. The DEK is used to decrypt data during encrypted boot. Commands added -------------- dek_blob - encapsulating DEK as a cryptgraphic blob Commands Syntax --------------- dek_blob src dst len Encapsulate and create blob of a len-bits DEK at address src and store the result at address dst. Signed-off-by: Raul Cardenas <Ulises.Cardenas@freescale.com> Signed-off-by: Nitin Garg <nitin.garg@freescale.com> Signed-off-by: Ulises Cardenas <ulises.cardenas@freescale.com> Signed-off-by: Ulises Cardenas-B45798 <Ulises.Cardenas@freescale.com>
This commit is contained in:
parent
b5cd10b911
commit
0200020bc2
@ -24,6 +24,7 @@ obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o
|
||||
endif
|
||||
obj-$(CONFIG_CMD_BMODE) += cmd_bmode.o
|
||||
obj-$(CONFIG_CMD_HDMIDETECT) += cmd_hdmidet.o
|
||||
obj-$(CONFIG_CMD_DEKBLOB) += cmd_dek.o
|
||||
|
||||
quiet_cmd_cpp_cfg = CFGS $@
|
||||
cmd_cpp_cfg = $(CPP) $(cpp_flags) -x c -o $@ $<
|
||||
|
91
arch/arm/imx-common/cmd_dek.c
Normal file
91
arch/arm/imx-common/cmd_dek.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2008-2015 Freescale Semiconductor, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Command for encapsulating DEK blob
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <environment.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/byteorder.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <fsl_sec.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/**
|
||||
* blob_dek() - Encapsulate the DEK as a blob using CAM's Key
|
||||
* @src: - Address of data to be encapsulated
|
||||
* @dst: - Desination address of encapsulated data
|
||||
* @len: - Size of data to be encapsulated
|
||||
*
|
||||
* Returns zero on success,and negative on error.
|
||||
*/
|
||||
static int blob_encap_dek(const u8 *src, u8 *dst, u32 len)
|
||||
{
|
||||
int ret = 0;
|
||||
u32 jr_size = 4;
|
||||
|
||||
u32 out_jr_size = sec_in32(CONFIG_SYS_FSL_JR0_ADDR + 0x102c);
|
||||
if (out_jr_size != jr_size) {
|
||||
hab_caam_clock_enable(1);
|
||||
sec_init();
|
||||
}
|
||||
|
||||
if (!((len == 128) | (len == 192) | (len == 256))) {
|
||||
debug("Invalid DEK size. Valid sizes are 128, 192 and 256b\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
len /= 8;
|
||||
ret = blob_dek(src, dst, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* do_dek_blob() - Handle the "dek_blob" command-line command
|
||||
* @cmdtp: Command data struct pointer
|
||||
* @flag: Command flag
|
||||
* @argc: Command-line argument count
|
||||
* @argv: Array of command-line arguments
|
||||
*
|
||||
* Returns zero on success, CMD_RET_USAGE in case of misuse and negative
|
||||
* on error.
|
||||
*/
|
||||
static int do_dek_blob(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
||||
{
|
||||
uint32_t src_addr, dst_addr, len;
|
||||
uint8_t *src_ptr, *dst_ptr;
|
||||
int ret = 0;
|
||||
|
||||
if (argc != 4)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
src_addr = simple_strtoul(argv[1], NULL, 16);
|
||||
dst_addr = simple_strtoul(argv[2], NULL, 16);
|
||||
len = simple_strtoul(argv[3], NULL, 10);
|
||||
|
||||
src_ptr = map_sysmem(src_addr, len/8);
|
||||
dst_ptr = map_sysmem(dst_addr, BLOB_SIZE(len/8));
|
||||
|
||||
ret = blob_encap_dek(src_ptr, dst_ptr, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***************************************************/
|
||||
static char dek_blob_help_text[] =
|
||||
"src dst len - Encapsulate and create blob of data\n"
|
||||
" $len bits long at address $src and\n"
|
||||
" store the result at address $dst.\n";
|
||||
|
||||
U_BOOT_CMD(
|
||||
dek_blob, 4, 1, do_dek_blob,
|
||||
"Data Encryption Key blob encapsulation",
|
||||
dek_blob_help_text
|
||||
);
|
@ -176,3 +176,20 @@ ulong get_tbclk(void)
|
||||
{
|
||||
return gpt_get_clk();
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is intended for SHORT delays only.
|
||||
* It will overflow at around 10 seconds @ 400MHz,
|
||||
* or 20 seconds @ 200MHz.
|
||||
*/
|
||||
unsigned long usec2ticks(unsigned long usec)
|
||||
{
|
||||
ulong ticks;
|
||||
|
||||
if (usec < 1000)
|
||||
ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000;
|
||||
else
|
||||
ticks = ((usec / 10) * (get_tbclk() / 100000));
|
||||
|
||||
return ticks;
|
||||
}
|
||||
|
@ -215,6 +215,10 @@
|
||||
#define AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000)
|
||||
#define CAAM_BASE_ADDR (ATZ2_BASE_ADDR)
|
||||
#define ARM_BASE_ADDR (ATZ2_BASE_ADDR + 0x40000)
|
||||
|
||||
#define CONFIG_SYS_FSL_SEC_ADDR CAAM_BASE_ADDR
|
||||
#define CONFIG_SYS_FSL_JR0_ADDR (CAAM_BASE_ADDR + 0x1000)
|
||||
|
||||
#define USB_PL301_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000)
|
||||
#define USB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000)
|
||||
|
||||
|
@ -46,3 +46,51 @@ cat u-boot.imx U-Boot_CSF_pad.bin > u-boot-signed.imx
|
||||
|
||||
NOTE: U-Boot_CSF.bin needs to be padded to the value specified in
|
||||
the imximage.cfg file.
|
||||
|
||||
Setup U-Boot Image for Encrypted Boot
|
||||
-------------------------------------
|
||||
An authenticated U-Boot image is used as starting point for
|
||||
Encrypted Boot. The image is encrypted by Freescale's Code
|
||||
Signing Tool (CST). The CST replaces only the image data of
|
||||
u-boot.imx with the encrypted data. The Initial Vector Table,
|
||||
DCD, and Boot data, remains in plaintext.
|
||||
|
||||
The image data is encrypted with a Encryption Key (DEK).
|
||||
Therefore, this key is needed to decrypt the data during the
|
||||
booting process. The DEK is protected by wrapping it in a Blob,
|
||||
which needs to be appended to the U-Boot image and specified in
|
||||
the CSF file.
|
||||
|
||||
The DEK blob is generated by an authenticated U-Boot image with
|
||||
the dek_blob cmd enabled. The image used for DEK blob generation
|
||||
needs to have the following configurations enabled:
|
||||
|
||||
CONFIG_SECURE_BOOT
|
||||
CONFIG_SYS_FSL_SEC_COMPAT 4 /* HAB version */
|
||||
CONFIG_FSL_CAAM
|
||||
CONFIG_CMD_DEKBLOB
|
||||
|
||||
Note: The encrypted boot feature is only supported by HABv4 or
|
||||
greater.
|
||||
|
||||
The dek_blob command then can be used to generate the DEK blob of
|
||||
a DEK previously loaded in memory. The command is used as follows:
|
||||
|
||||
dek_blob <DEK address> <Output Address> <Key Size in Bits>
|
||||
example: dek_blob 0x10800000 0x10801000 192
|
||||
|
||||
The resulting DEK blob then is used to construct the encrypted
|
||||
U-Boot image. Note that the blob needs to be transferred back
|
||||
to the host.Then the following commands are used to construct
|
||||
the final image.
|
||||
|
||||
objcopy -I binary -O binary --pad-to 0x2000 --gap-fill=0x00 \
|
||||
U-Boot_CSF.bin U-Boot_CSF_pad.bin
|
||||
cat u-boot.imx U-Boot_CSF_pad.bin > u-boot-signed.imx
|
||||
objcopy -I binary -O binary --pad-to <blob_dst> --gap-fill=0x00 \
|
||||
u-boot-signed.imx u-boot-signed-pad.bin
|
||||
cat u-boot-signed-pad.imx DEK_blob.bin > u-boot-encrypted.imx
|
||||
|
||||
NOTE: u-boot-signed.bin needs to be padded to the value
|
||||
equivalent to the address in which the DEK blob is specified
|
||||
in the CSF.
|
||||
|
@ -8,5 +8,5 @@
|
||||
|
||||
obj-y += sec.o
|
||||
obj-$(CONFIG_FSL_CAAM) += jr.o fsl_hash.o jobdesc.o error.o
|
||||
obj-$(CONFIG_CMD_BLOB) += fsl_blob.o
|
||||
obj-$(CONFIG_CMD_BLOB)$(CONFIG_CMD_DEKBLOB) += fsl_blob.o
|
||||
obj-$(CONFIG_RSA_FREESCALE_EXP) += fsl_rsa.o
|
||||
|
@ -12,11 +12,18 @@
|
||||
#ifndef DESC_H
|
||||
#define DESC_H
|
||||
|
||||
#define KEY_BLOB_SIZE 32
|
||||
#define MAC_SIZE 16
|
||||
|
||||
/* Max size of any CAAM descriptor in 32-bit words, inclusive of header */
|
||||
#define MAX_CAAM_DESCSIZE 64
|
||||
|
||||
/* Size of DEK Blob descriptor, inclusive of header */
|
||||
#define DEK_BLOB_DESCSIZE 9
|
||||
|
||||
/* Block size of any entity covered/uncovered with a KEK/TKEK */
|
||||
#define KEK_BLOCKSIZE 16
|
||||
|
||||
/*
|
||||
* Supported descriptor command types as they show up
|
||||
* inside a descriptor command word.
|
||||
@ -272,6 +279,13 @@
|
||||
#define LDLEN_SET_OFIFO_OFFSET_SHIFT 0
|
||||
#define LDLEN_SET_OFIFO_OFFSET_MASK (3 << LDLEN_SET_OFIFO_OFFSET_SHIFT)
|
||||
|
||||
/*
|
||||
* AAD Definitions
|
||||
*/
|
||||
#define AES_KEY_SHIFT 8
|
||||
#define LD_CCM_MODE 0x66
|
||||
#define KEY_AES_SRC (0x55 << AES_KEY_SHIFT)
|
||||
|
||||
/*
|
||||
* FIFO_LOAD/FIFO_STORE/SEQ_FIFO_LOAD/SEQ_FIFO_STORE
|
||||
* Command Constructs
|
||||
@ -418,6 +432,7 @@
|
||||
#define OP_PCLID_MASK (0xff << 16)
|
||||
|
||||
/* Assuming OP_TYPE = OP_TYPE_UNI_PROTOCOL */
|
||||
#define OP_PCLID_SECMEM 0x08
|
||||
#define OP_PCLID_BLOB (0x0d << OP_PCLID_SHIFT)
|
||||
#define OP_PCLID_SECRETKEY (0x11 << OP_PCLID_SHIFT)
|
||||
#define OP_PCLID_PUBLICKEYPAIR (0x14 << OP_PCLID_SHIFT)
|
||||
|
@ -7,6 +7,8 @@
|
||||
|
||||
#include <common.h>
|
||||
#include <malloc.h>
|
||||
#include <fsl_sec.h>
|
||||
#include <asm-generic/errno.h>
|
||||
#include "jobdesc.h"
|
||||
#include "desc.h"
|
||||
#include "jr.h"
|
||||
@ -59,3 +61,53 @@ int blob_encap(u8 *key_mod, u8 *src, u8 *dst, u32 len)
|
||||
free(desc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CMD_DEKBLOB
|
||||
int blob_dek(const u8 *src, u8 *dst, u8 len)
|
||||
{
|
||||
int ret, size, i = 0;
|
||||
u32 *desc;
|
||||
|
||||
int out_sz = WRP_HDR_SIZE + len + KEY_BLOB_SIZE + MAC_SIZE;
|
||||
|
||||
puts("\nEncapsulating provided DEK to form blob\n");
|
||||
desc = memalign(ARCH_DMA_MINALIGN,
|
||||
sizeof(uint32_t) * DEK_BLOB_DESCSIZE);
|
||||
if (!desc) {
|
||||
debug("Not enough memory for descriptor allocation\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
ret = inline_cnstr_jobdesc_blob_dek(desc, src, dst, len);
|
||||
if (ret) {
|
||||
debug("Error in Job Descriptor Construction: %d\n", ret);
|
||||
} else {
|
||||
size = roundup(sizeof(uint32_t) * DEK_BLOB_DESCSIZE,
|
||||
ARCH_DMA_MINALIGN);
|
||||
flush_dcache_range((unsigned long)desc,
|
||||
(unsigned long)desc + size);
|
||||
size = roundup(sizeof(uint8_t) * out_sz, ARCH_DMA_MINALIGN);
|
||||
flush_dcache_range((unsigned long)dst,
|
||||
(unsigned long)dst + size);
|
||||
|
||||
ret = run_descriptor_jr(desc);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
debug("Error in Encapsulation %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
size = roundup(out_sz, ARCH_DMA_MINALIGN);
|
||||
invalidate_dcache_range((unsigned long)dst, (unsigned long)dst+size);
|
||||
|
||||
puts("DEK Blob\n");
|
||||
for (i = 0; i < out_sz; i++)
|
||||
printf("%02X", ((uint8_t *)dst)[i]);
|
||||
printf("\n");
|
||||
|
||||
err:
|
||||
free(desc);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
@ -9,12 +9,157 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <fsl_sec.h>
|
||||
#include "desc_constr.h"
|
||||
#include "jobdesc.h"
|
||||
#include "rsa_caam.h"
|
||||
|
||||
#define KEY_BLOB_SIZE 32
|
||||
#define MAC_SIZE 16
|
||||
#ifdef CONFIG_MX6
|
||||
/*!
|
||||
* Secure memory run command
|
||||
*
|
||||
* @param sec_mem_cmd Secure memory command register
|
||||
* @return cmd_status Secure memory command status register
|
||||
*/
|
||||
uint32_t secmem_set_cmd(uint32_t sec_mem_cmd)
|
||||
{
|
||||
uint32_t temp_reg;
|
||||
|
||||
sec_out32(CAAM_SMCJR0, sec_mem_cmd);
|
||||
|
||||
do {
|
||||
temp_reg = sec_in32(CAAM_SMCSJR0);
|
||||
} while (temp_reg & CMD_COMPLETE);
|
||||
|
||||
return temp_reg;
|
||||
}
|
||||
|
||||
/*!
|
||||
* CAAM page allocation:
|
||||
* Allocates a partition from secure memory, with the id
|
||||
* equal to partion_num. This will de-allocate the page
|
||||
* if it is already allocated. The partition will have
|
||||
* full access permissions. The permissions are set before,
|
||||
* running a job descriptor. A memory page of secure RAM
|
||||
* is allocated for the partition.
|
||||
*
|
||||
* @param page Number of the page to allocate.
|
||||
* @param partition Number of the partition to allocate.
|
||||
* @return 0 on success, ERROR_IN_PAGE_ALLOC otherwise
|
||||
*/
|
||||
int caam_page_alloc(uint8_t page_num, uint8_t partition_num)
|
||||
{
|
||||
uint32_t temp_reg;
|
||||
|
||||
/*
|
||||
* De-Allocate partition_num if already allocated to ARM core
|
||||
*/
|
||||
if (sec_in32(CAAM_SMPO_0) & PARTITION_OWNER(partition_num)) {
|
||||
temp_reg = secmem_set_cmd(PARTITION(partition_num) |
|
||||
CMD_PART_DEALLOC);
|
||||
if (temp_reg & SMCSJR_AERR) {
|
||||
printf("Error: De-allocation status 0x%X\n", temp_reg);
|
||||
return ERROR_IN_PAGE_ALLOC;
|
||||
}
|
||||
}
|
||||
|
||||
/* set the access rights to allow full access */
|
||||
sec_out32(CAAM_SMAG1JR0(partition_num), 0xF);
|
||||
sec_out32(CAAM_SMAG2JR0(partition_num), 0xF);
|
||||
sec_out32(CAAM_SMAPJR0(partition_num), 0xFF);
|
||||
|
||||
/* Now need to allocate partition_num of secure RAM. */
|
||||
/* De-Allocate page_num by starting with a page inquiry command */
|
||||
temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_INQUIRY);
|
||||
|
||||
/* if the page is owned, de-allocate it */
|
||||
if ((temp_reg & SMCSJR_PO) == PAGE_OWNED) {
|
||||
temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_PAGE_DEALLOC);
|
||||
if (temp_reg & SMCSJR_AERR) {
|
||||
printf("Error: Allocation status 0x%X\n", temp_reg);
|
||||
return ERROR_IN_PAGE_ALLOC;
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate page_num to partition_num */
|
||||
temp_reg = secmem_set_cmd(PAGE(page_num) | PARTITION(partition_num)
|
||||
| CMD_PAGE_ALLOC);
|
||||
if (temp_reg & SMCSJR_AERR) {
|
||||
printf("Error: Allocation status 0x%X\n", temp_reg);
|
||||
return ERROR_IN_PAGE_ALLOC;
|
||||
}
|
||||
/* page inquiry command to ensure that the page was allocated */
|
||||
temp_reg = secmem_set_cmd(PAGE(page_num) | CMD_INQUIRY);
|
||||
|
||||
/* if the page is not owned => problem */
|
||||
if ((temp_reg & SMCSJR_PO) != PAGE_OWNED) {
|
||||
printf("Allocation of page %d in partition %d failed 0x%X\n",
|
||||
temp_reg, page_num, partition_num);
|
||||
|
||||
return ERROR_IN_PAGE_ALLOC;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int inline_cnstr_jobdesc_blob_dek(uint32_t *desc, const uint8_t *plain_txt,
|
||||
uint8_t *dek_blob, uint32_t in_sz)
|
||||
{
|
||||
uint32_t ret = 0;
|
||||
u32 aad_w1, aad_w2;
|
||||
/* output blob will have 32 bytes key blob in beginning and
|
||||
* 16 byte HMAC identifier at end of data blob */
|
||||
uint32_t out_sz = in_sz + KEY_BLOB_SIZE + MAC_SIZE;
|
||||
/* Setting HDR for blob */
|
||||
uint8_t wrapped_key_hdr[8] = {HDR_TAG, 0x00, WRP_HDR_SIZE + out_sz,
|
||||
HDR_PAR, HAB_MOD, HAB_ALG, in_sz, HAB_FLG};
|
||||
|
||||
/* initialize the blob array */
|
||||
memset(dek_blob, 0, out_sz + 8);
|
||||
/* Copy the header into the DEK blob buffer */
|
||||
memcpy(dek_blob, wrapped_key_hdr, sizeof(wrapped_key_hdr));
|
||||
|
||||
/* allocating secure memory */
|
||||
ret = caam_page_alloc(PAGE_1, PARTITION_1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Write DEK to secure memory */
|
||||
memcpy((uint32_t *)SEC_MEM_PAGE1, (uint32_t *)plain_txt, in_sz);
|
||||
|
||||
unsigned long start = (unsigned long)SEC_MEM_PAGE1 &
|
||||
~(ARCH_DMA_MINALIGN - 1);
|
||||
unsigned long end = ALIGN(start + 0x1000, ARCH_DMA_MINALIGN);
|
||||
flush_dcache_range(start, end);
|
||||
|
||||
/* Now configure the access rights of the partition */
|
||||
sec_out32(CAAM_SMAG1JR0(PARTITION_1), KS_G1); /* set group 1 */
|
||||
sec_out32(CAAM_SMAG2JR0(PARTITION_1), 0); /* clear group 2 */
|
||||
sec_out32(CAAM_SMAPJR0(PARTITION_1), PERM); /* set perm & locks */
|
||||
|
||||
/* construct aad for AES */
|
||||
aad_w1 = (in_sz << OP_ALG_ALGSEL_SHIFT) | KEY_AES_SRC | LD_CCM_MODE;
|
||||
aad_w2 = 0x0;
|
||||
|
||||
init_job_desc(desc, 0);
|
||||
|
||||
append_cmd(desc, CMD_LOAD | CLASS_2 | KEY_IMM | KEY_ENC |
|
||||
(0x0c << LDST_OFFSET_SHIFT) | 0x08);
|
||||
|
||||
append_u32(desc, aad_w1);
|
||||
|
||||
append_u32(desc, aad_w2);
|
||||
|
||||
append_cmd_ptr(desc, (dma_addr_t)SEC_MEM_PAGE1, in_sz, CMD_SEQ_IN_PTR);
|
||||
|
||||
append_cmd_ptr(desc, (dma_addr_t)dek_blob + 8, out_sz, CMD_SEQ_OUT_PTR);
|
||||
|
||||
append_operation(desc, OP_TYPE_ENCAP_PROTOCOL | OP_PCLID_BLOB |
|
||||
OP_PCLID_SECMEM);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
void inline_cnstr_jobdesc_hash(uint32_t *desc,
|
||||
const uint8_t *msg, uint32_t msgsz, uint8_t *digest,
|
||||
|
@ -14,6 +14,20 @@
|
||||
|
||||
#define KEY_IDNFR_SZ_BYTES 16
|
||||
|
||||
#ifdef CONFIG_CMD_DEKBLOB
|
||||
/* inline_cnstr_jobdesc_blob_dek:
|
||||
* Intializes and constructs the job descriptor for DEK encapsulation
|
||||
* using the given parameters.
|
||||
* @desc: reference to the job descriptor
|
||||
* @plain_txt: reference to the DEK
|
||||
* @enc_blob: reference where to store the blob
|
||||
* @in_sz: size in bytes of the DEK
|
||||
* @return: 0 on success, ECONSTRJDESC otherwise
|
||||
*/
|
||||
int inline_cnstr_jobdesc_blob_dek(uint32_t *desc, const uint8_t *plain_txt,
|
||||
uint8_t *enc_blob, uint32_t in_sz);
|
||||
#endif
|
||||
|
||||
void inline_cnstr_jobdesc_hash(uint32_t *desc,
|
||||
const uint8_t *msg, uint32_t msgsz, uint8_t *digest,
|
||||
u32 alg_type, uint32_t alg_size, int sg_tbl);
|
||||
|
@ -90,11 +90,13 @@ static int jr_init(void)
|
||||
jr.liodn = DEFAULT_JR_LIODN;
|
||||
#endif
|
||||
jr.size = JR_SIZE;
|
||||
jr.input_ring = (dma_addr_t *)malloc(JR_SIZE * sizeof(dma_addr_t));
|
||||
jr.input_ring = (dma_addr_t *)memalign(ARCH_DMA_MINALIGN,
|
||||
JR_SIZE * sizeof(dma_addr_t));
|
||||
if (!jr.input_ring)
|
||||
return -1;
|
||||
jr.output_ring =
|
||||
(struct op_ring *)malloc(JR_SIZE * sizeof(struct op_ring));
|
||||
(struct op_ring *)memalign(ARCH_DMA_MINALIGN,
|
||||
JR_SIZE * sizeof(struct op_ring));
|
||||
if (!jr.output_ring)
|
||||
return -1;
|
||||
|
||||
@ -163,13 +165,23 @@ static int jr_enqueue(uint32_t *desc_addr,
|
||||
CIRC_SPACE(jr.head, jr.tail, jr.size) <= 0)
|
||||
return -1;
|
||||
|
||||
jr.input_ring[head] = desc_phys_addr;
|
||||
jr.info[head].desc_phys_addr = desc_phys_addr;
|
||||
jr.info[head].desc_addr = (uint32_t)desc_addr;
|
||||
jr.info[head].callback = (void *)callback;
|
||||
jr.info[head].arg = arg;
|
||||
jr.info[head].op_done = 0;
|
||||
|
||||
unsigned long start = (unsigned long)&jr.info[head] &
|
||||
~(ARCH_DMA_MINALIGN - 1);
|
||||
unsigned long end = ALIGN(start + sizeof(struct jr_info),
|
||||
ARCH_DMA_MINALIGN);
|
||||
flush_dcache_range(start, end);
|
||||
|
||||
jr.input_ring[head] = desc_phys_addr;
|
||||
start = (unsigned long)&jr.input_ring[head] & ~(ARCH_DMA_MINALIGN - 1);
|
||||
end = ALIGN(start + sizeof(dma_addr_t), ARCH_DMA_MINALIGN);
|
||||
flush_dcache_range(start, end);
|
||||
|
||||
jr.head = (head + 1) & (jr.size - 1);
|
||||
|
||||
sec_out32(®s->irja, 1);
|
||||
@ -187,6 +199,13 @@ static int jr_dequeue(void)
|
||||
void *arg = NULL;
|
||||
|
||||
while (sec_in32(®s->orsf) && CIRC_CNT(jr.head, jr.tail, jr.size)) {
|
||||
unsigned long start = (unsigned long)jr.output_ring &
|
||||
~(ARCH_DMA_MINALIGN - 1);
|
||||
unsigned long end = ALIGN(start +
|
||||
sizeof(struct op_ring)*JR_SIZE,
|
||||
ARCH_DMA_MINALIGN);
|
||||
invalidate_dcache_range(start, end);
|
||||
|
||||
found = 0;
|
||||
|
||||
dma_addr_t op_desc = jr.output_ring[jr.tail].desc;
|
||||
@ -333,13 +352,17 @@ static int instantiate_rng(void)
|
||||
|
||||
memset(&op, 0, sizeof(struct result));
|
||||
|
||||
desc = malloc(sizeof(int) * 6);
|
||||
desc = memalign(ARCH_DMA_MINALIGN, sizeof(uint32_t) * 6);
|
||||
if (!desc) {
|
||||
printf("cannot allocate RNG init descriptor memory\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline_cnstr_jobdesc_rng_instantiation(desc);
|
||||
int size = roundup(sizeof(uint32_t) * 6, ARCH_DMA_MINALIGN);
|
||||
flush_dcache_range((unsigned long)desc,
|
||||
(unsigned long)desc + size);
|
||||
|
||||
ret = run_descriptor_jr(desc);
|
||||
|
||||
if (ret)
|
||||
|
@ -135,7 +135,7 @@ typedef struct ccsr_sec {
|
||||
#define CONFIG_JRSTARTR_JR0 0x00000001
|
||||
|
||||
struct jr_regs {
|
||||
#ifdef CONFIG_SYS_FSL_SEC_LE
|
||||
#if defined(CONFIG_SYS_FSL_SEC_LE) && !defined(CONFIG_MX6)
|
||||
u32 irba_l;
|
||||
u32 irba_h;
|
||||
#else
|
||||
@ -148,7 +148,7 @@ struct jr_regs {
|
||||
u32 irsa;
|
||||
u32 rsvd3;
|
||||
u32 irja;
|
||||
#ifdef CONFIG_SYS_FSL_SEC_LE
|
||||
#if defined(CONFIG_SYS_FSL_SEC_LE) && !defined(CONFIG_MX6)
|
||||
u32 orba_l;
|
||||
u32 orba_h;
|
||||
#else
|
||||
@ -180,7 +180,7 @@ struct jr_regs {
|
||||
* related information
|
||||
*/
|
||||
struct sg_entry {
|
||||
#ifdef CONFIG_SYS_FSL_SEC_LE
|
||||
#ifdef defined(CONFIG_SYS_FSL_SEC_LE) && !defined(CONFIG_MX6)
|
||||
uint32_t addr_lo; /* Memory Address - lo */
|
||||
uint16_t addr_hi; /* Memory Address of start of buffer - hi */
|
||||
uint16_t reserved_zero;
|
||||
@ -201,7 +201,79 @@ struct sg_entry {
|
||||
#define SG_ENTRY_OFFSET_SHIFT 0
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MX6
|
||||
/* CAAM Job Ring 0 Registers */
|
||||
/* Secure Memory Partition Owner register */
|
||||
#define SMCSJR_PO (3 << 6)
|
||||
/* JR Allocation Error */
|
||||
#define SMCSJR_AERR (3 << 12)
|
||||
/* Secure memory partition 0 page 0 owner register */
|
||||
#define CAAM_SMPO_0 CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC
|
||||
/* Secure memory command register */
|
||||
#define CAAM_SMCJR0 CONFIG_SYS_FSL_SEC_ADDR + 0x10f4
|
||||
/* Secure memory command status register */
|
||||
#define CAAM_SMCSJR0 CONFIG_SYS_FSL_SEC_ADDR + 0x10fc
|
||||
/* Secure memory access permissions register */
|
||||
#define CAAM_SMAPJR0(y) (CONFIG_SYS_FSL_SEC_ADDR + 0x1104 + y*16)
|
||||
/* Secure memory access group 2 register */
|
||||
#define CAAM_SMAG2JR0(y) (CONFIG_SYS_FSL_SEC_ADDR + 0x1108 + y*16)
|
||||
/* Secure memory access group 1 register */
|
||||
#define CAAM_SMAG1JR0(y) (CONFIG_SYS_FSL_SEC_ADDR + 0x110C + y*16)
|
||||
|
||||
/* Commands and macros for secure memory */
|
||||
#define CMD_PAGE_ALLOC 0x1
|
||||
#define CMD_PAGE_DEALLOC 0x2
|
||||
#define CMD_PART_DEALLOC 0x3
|
||||
#define CMD_INQUIRY 0x5
|
||||
#define CMD_COMPLETE (3 << 14)
|
||||
#define PAGE_AVAILABLE 0
|
||||
#define PAGE_OWNED (3 << 6)
|
||||
#define PAGE(x) (x << 16)
|
||||
#define PARTITION(x) (x << 8)
|
||||
#define PARTITION_OWNER(x) (0x3 << (x*2))
|
||||
|
||||
/* Address of secure 4kbyte pages */
|
||||
#define SEC_MEM_PAGE0 CAAM_ARB_BASE_ADDR
|
||||
#define SEC_MEM_PAGE1 (CAAM_ARB_BASE_ADDR + 0x1000)
|
||||
#define SEC_MEM_PAGE2 (CAAM_ARB_BASE_ADDR + 0x2000)
|
||||
#define SEC_MEM_PAGE3 (CAAM_ARB_BASE_ADDR + 0x3000)
|
||||
|
||||
#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 BLOB_SIZE(x) (x + 32 + 16) /* Blob buffer size */
|
||||
|
||||
/* HAB WRAPPED KEY header */
|
||||
#define WRP_HDR_SIZE 0x08
|
||||
#define HDR_TAG 0x81
|
||||
#define HDR_PAR 0x41
|
||||
/* HAB WRAPPED KEY Data */
|
||||
#define HAB_MOD 0x66
|
||||
#define HAB_ALG 0x55
|
||||
#define HAB_FLG 0x00
|
||||
|
||||
/* Partition and Page IDs */
|
||||
#define PARTITION_1 1
|
||||
#define PAGE_1 1
|
||||
|
||||
#define ERROR_IN_PAGE_ALLOC 1
|
||||
#define ECONSTRJDESC -1
|
||||
|
||||
#endif
|
||||
|
||||
int sec_init(void);
|
||||
|
||||
/* blob_dek:
|
||||
* Encapsulates the src in a secure blob and stores it dst
|
||||
* @src: reference to the plaintext
|
||||
* @dst: reference to the output adrress
|
||||
* @len: size in bytes of src
|
||||
* @return: 0 on success, error otherwise
|
||||
*/
|
||||
int blob_dek(const u8 *src, u8 *dst, u8 len);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* __FSL_SEC_H */
|
||||
|
Loading…
Reference in New Issue
Block a user