[U-Boot] [PATCH] imx6: Added DEK blob generator command

From: Raul Cardenas Ulises.Cardenas@freescale.com
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 SHA-256 key is randomly generated to encrypt the DEK. This key is itself encrypted with the OTP Secret key from SoC. The ending blob consists of the encrypted SHA-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 ---
arch/arm/imx-common/Makefile | 1 + arch/arm/imx-common/cmd_dek.c | 89 +++++++++++++++++++ arch/arm/imx-common/timer.c | 17 ++++ arch/arm/include/asm/arch-mx6/imx-regs.h | 4 + doc/README.mxc_hab | 48 ++++++++++ drivers/crypto/fsl/Makefile | 2 +- drivers/crypto/fsl/desc.h | 15 ++++ drivers/crypto/fsl/fsl_blob.c | 50 +++++++++++ drivers/crypto/fsl/jobdesc.c | 142 +++++++++++++++++++++++++++++- drivers/crypto/fsl/jobdesc.h | 5 ++ drivers/crypto/fsl/jr.c | 24 ++++- include/fsl_sec.h | 60 +++++++++++++ 12 files changed, 451 insertions(+), 6 deletions(-) create mode 100644 arch/arm/imx-common/cmd_dek.c
diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile index 25a9d4c..606482f 100644 --- a/arch/arm/imx-common/Makefile +++ b/arch/arm/imx-common/Makefile @@ -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 $@ $< diff --git a/arch/arm/imx-common/cmd_dek.c b/arch/arm/imx-common/cmd_dek.c new file mode 100644 index 0000000..e3748d2 --- /dev/null +++ b/arch/arm/imx-common/cmd_dek.c @@ -0,0 +1,89 @@ +/* + * Command for encapsulating DEK blob + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#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: - Address of data to be encapsulated +* @len: - Size of data to be encapsulated +* +* Returns zero on success,and negative on error. +*/ +__weak int blob_encap_dek(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 = (uint8_t *)src_addr; + dst_ptr = (uint8_t *)dst_addr; + + 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 +); diff --git a/arch/arm/imx-common/timer.c b/arch/arm/imx-common/timer.c index 65ef60b..e522990 100644 --- a/arch/arm/imx-common/timer.c +++ b/arch/arm/imx-common/timer.c @@ -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; +} diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index c968600..8642021 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -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)
diff --git a/doc/README.mxc_hab b/doc/README.mxc_hab index 43e64a2..46ed0df 100644 --- a/doc/README.mxc_hab +++ b/doc/README.mxc_hab @@ -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 transfered 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. diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile index c0cf642..4aa91e4 100644 --- a/drivers/crypto/fsl/Makefile +++ b/drivers/crypto/fsl/Makefile @@ -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 diff --git a/drivers/crypto/fsl/desc.h b/drivers/crypto/fsl/desc.h index 504f2b0..bb82734 100644 --- a/drivers/crypto/fsl/desc.h +++ b/drivers/crypto/fsl/desc.h @@ -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. @@ -273,6 +280,13 @@ #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) diff --git a/drivers/crypto/fsl/fsl_blob.c b/drivers/crypto/fsl/fsl_blob.c index bc01075..f9dc85a 100644 --- a/drivers/crypto/fsl/fsl_blob.c +++ b/drivers/crypto/fsl/fsl_blob.c @@ -7,6 +7,7 @@
#include <common.h> #include <malloc.h> +#include <fsl_sec.h> #include "jobdesc.h" #include "desc.h" #include "jr.h" @@ -59,3 +60,52 @@ int blob_encrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len) free(desc); return ret; } + +#ifdef CONFIG_CMD_DEKBLOB +int blob_dek(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 -1; + } + + 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); + + size = roundup(out_sz, ARCH_DMA_MINALIGN); + invalidate_dcache_range((unsigned long)dst, (unsigned long)dst+size); + + /* Print DEK Blob */ + puts("DEK Blob\n"); + for (i = 0; i < out_sz; i++) + printf("%02X", ((uint8_t *)dst)[i]); + + puts("\n\n"); + + free(desc); + return ret; +} +#endif diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c index cc0dced..4dc73ae 100644 --- a/drivers/crypto/fsl/jobdesc.c +++ b/drivers/crypto/fsl/jobdesc.c @@ -9,12 +9,150 @@ */
#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. + * + * @param page Number of the page to allocate. + * @param partition Number of the partition to allocate. + */ +uint32_t 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; +} + +uint32_t inline_cnstr_jobdesc_blob_dek(uint32_t *desc, 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((uint32_t *)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, diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h index 84b3edd..d20c18c 100644 --- a/drivers/crypto/fsl/jobdesc.h +++ b/drivers/crypto/fsl/jobdesc.h @@ -14,6 +14,11 @@
#define KEY_IDNFR_SZ_BYTES 16
+#ifdef CONFIG_CMD_DEKBLOB +uint32_t inline_cnstr_jobdesc_blob_dek(uint32_t *desc, 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); diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index f9d4938..8b76c1b 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -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,22 @@ 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 & ~(ARCH_DMA_MINALIGN - 1); + unsigned long end = ALIGN(start + sizeof(struct jr_info) * JR_SIZE , + ARCH_DMA_MINALIGN); + flush_dcache_range(start, end); + + jr.input_ring[head] = desc_phys_addr; + start = (unsigned long)jr.input_ring & ~(ARCH_DMA_MINALIGN - 1); + end = ALIGN(start + sizeof(dma_addr_t)*JR_SIZE , ARCH_DMA_MINALIGN); + flush_dcache_range(start, end); + jr.head = (head + 1) & (jr.size - 1);
sec_out32(®s->irja, 1); @@ -187,6 +198,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; diff --git a/include/fsl_sec.h b/include/fsl_sec.h index aa850a3..95fbb6b 100644 --- a/include/fsl_sec.h +++ b/include/fsl_sec.h @@ -11,6 +11,13 @@ #include <common.h> #include <asm/io.h>
+#ifdef CONFIG_ARM +#define sec_in32(a) __raw_readl(a) +#define sec_out32(a, v) __raw_writel(v, a) +#define sec_in16(a) __raw_readw(a) +#define sec_clrbits32 clrbits_le32 +#define sec_setbits32 setbits_le32 +#elif CONFIG_PPC #ifdef CONFIG_SYS_FSL_SEC_LE #define sec_in32(a) in_le32(a) #define sec_out32(a, v) out_le32(a, v) @@ -26,6 +33,7 @@ #else #error Neither CONFIG_SYS_FSL_SEC_LE nor CONFIG_SYS_FSL_SEC_BE is defined #endif +#endif /* ARCHITECURE */
/* Security Engine Block (MS = Most Sig., LS = Least Sig.) */ #if CONFIG_SYS_FSL_SEC_COMPAT >= 4 @@ -175,7 +183,59 @@ struct jr_regs { u32 jrcr; };
+#ifdef CONFIG_MX6 + +#define SMCSJR_PO (3 << 6) +#define SMCSJR_AERR (3 << 12) +#define SMCSJR_CERR (3 << 14) +#define CAAM_SMPO_0 CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC +#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 ERROR_IN_PAGE_ALLOC (1) +#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)) + +/* 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 */ + +/* 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 + +#define PARTITION_1 1 +#define PAGE_1 1 + +#endif + int sec_init(void); + +int blob_dek(u8 *src, u8 *dst, u8 len); + #endif
#endif /* __FSL_SEC_H */

Hi Ulises,
-----Original Message----- From: Ulises.Cardenas@freescale.com [mailto:Ulises.Cardenas@freescale.com] Sent: Thursday, February 05, 2015 2:38 AM To: Gupta Ruchika-R66431 Cc: u-boot@lists.denx.de; Estevam Fabio-R49496; sbabic@denx.de; Ulises Cardenas Casas; Garg Nitin-B37173 Subject: [PATCH] imx6: Added DEK blob generator command
From: Raul Cardenas Ulises.Cardenas@freescale.com
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 SHA-256 key is randomly generated to encrypt the DEK. This key is itself encrypted with the OTP Secret key from SoC. The ending blob consists of the encrypted SHA-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
arch/arm/imx-common/Makefile | 1 + arch/arm/imx-common/cmd_dek.c | 89 +++++++++++++++++++ arch/arm/imx-common/timer.c | 17 ++++ arch/arm/include/asm/arch-mx6/imx-regs.h | 4 + doc/README.mxc_hab | 48 ++++++++++ drivers/crypto/fsl/Makefile | 2 +- drivers/crypto/fsl/desc.h | 15 ++++ drivers/crypto/fsl/fsl_blob.c | 50 +++++++++++ drivers/crypto/fsl/jobdesc.c | 142 +++++++++++++++++++++++++++++- drivers/crypto/fsl/jobdesc.h | 5 ++ drivers/crypto/fsl/jr.c | 24 ++++- include/fsl_sec.h | 60 +++++++++++++ 12 files changed, 451 insertions(+), 6 deletions(-) create mode 100644 arch/arm/imx-common/cmd_dek.c
diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile index 25a9d4c..606482f 100644 --- a/arch/arm/imx-common/Makefile +++ b/arch/arm/imx-common/Makefile @@ -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 $@ $< diff --git a/arch/arm/imx-common/cmd_dek.c b/arch/arm/imx-common/cmd_dek.c new file mode 100644 index 0000000..e3748d2 --- /dev/null +++ b/arch/arm/imx-common/cmd_dek.c @@ -0,0 +1,89 @@ +/*
- Command for encapsulating DEK blob
- SPDX-License-Identifier: GPL-2.0+
- */
+#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: - Address of data to be encapsulated +* @len: - Size of data to be encapsulated +* +* Returns zero on success,and negative on error. +*/ +__weak int blob_encap_dek(u8 *src, u8 *dst, u32 len) {
This should not be a weak function.
- 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 = (uint8_t *)src_addr;
- dst_ptr = (uint8_t *)dst_addr;
- 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
+); diff --git a/arch/arm/imx-common/timer.c b/arch/arm/imx-common/timer.c index 65ef60b..e522990 100644 --- a/arch/arm/imx-common/timer.c +++ b/arch/arm/imx-common/timer.c @@ -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;
+} diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index c968600..8642021 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -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)
diff --git a/doc/README.mxc_hab b/doc/README.mxc_hab index 43e64a2..46ed0df 100644 --- a/doc/README.mxc_hab +++ b/doc/README.mxc_hab @@ -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 transfered 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.
diff --git a/drivers/crypto/fsl/Makefile b/drivers/crypto/fsl/Makefile index c0cf642..4aa91e4 100644 --- a/drivers/crypto/fsl/Makefile +++ b/drivers/crypto/fsl/Makefile @@ -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 diff --git a/drivers/crypto/fsl/desc.h b/drivers/crypto/fsl/desc.h index 504f2b0..bb82734 100644 --- a/drivers/crypto/fsl/desc.h +++ b/drivers/crypto/fsl/desc.h @@ -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.
@@ -273,6 +280,13 @@ #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) diff --git a/drivers/crypto/fsl/fsl_blob.c b/drivers/crypto/fsl/fsl_blob.c index bc01075..f9dc85a 100644 --- a/drivers/crypto/fsl/fsl_blob.c +++ b/drivers/crypto/fsl/fsl_blob.c @@ -7,6 +7,7 @@
#include <common.h> #include <malloc.h> +#include <fsl_sec.h> #include "jobdesc.h" #include "desc.h" #include "jr.h" @@ -59,3 +60,52 @@ int blob_encrypt(u8 *key_mod, u8 *src, u8 *dst, u8 len) free(desc); return ret; }
+#ifdef CONFIG_CMD_DEKBLOB +int blob_dek(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 -1;
- }
- 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);
- size = roundup(out_sz, ARCH_DMA_MINALIGN);
- invalidate_dcache_range((unsigned long)dst, (unsigned long)dst+size);
- /* Print DEK Blob */
- puts("DEK Blob\n");
- for (i = 0; i < out_sz; i++)
printf("%02X", ((uint8_t *)dst)[i]);
- puts("\n\n");
- free(desc);
- return ret;
+} +#endif diff --git a/drivers/crypto/fsl/jobdesc.c b/drivers/crypto/fsl/jobdesc.c index cc0dced..4dc73ae 100644 --- a/drivers/crypto/fsl/jobdesc.c +++ b/drivers/crypto/fsl/jobdesc.c @@ -9,12 +9,150 @@ */
#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.
- @param page Number of the page to allocate.
- @param partition Number of the partition to allocate.
- */
+uint32_t 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;
+}
+uint32_t inline_cnstr_jobdesc_blob_dek(uint32_t *desc, 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((uint32_t *)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, diff --git a/drivers/crypto/fsl/jobdesc.h b/drivers/crypto/fsl/jobdesc.h index 84b3edd..d20c18c 100644 --- a/drivers/crypto/fsl/jobdesc.h +++ b/drivers/crypto/fsl/jobdesc.h @@ -14,6 +14,11 @@
#define KEY_IDNFR_SZ_BYTES 16
+#ifdef CONFIG_CMD_DEKBLOB +uint32_t inline_cnstr_jobdesc_blob_dek(uint32_t *desc, 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); diff --git a/drivers/crypto/fsl/jr.c b/drivers/crypto/fsl/jr.c index f9d4938..8b76c1b 100644 --- a/drivers/crypto/fsl/jr.c +++ b/drivers/crypto/fsl/jr.c @@ -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,
if (!jr.input_ring) return -1; jr.output_ring =JR_SIZE * sizeof(dma_addr_t));
(struct op_ring *)malloc(JR_SIZE * sizeof(struct op_ring));
(struct op_ring *)memalign(ARCH_DMA_MINALIGN,
if (!jr.output_ring) return -1;JR_SIZE * sizeof(struct op_ring));
@@ -163,13 +165,22 @@ 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 & ~(ARCH_DMA_MINALIGN -
1);
- unsigned long end = ALIGN(start + sizeof(struct jr_info) * JR_SIZE ,
ARCH_DMA_MINALIGN);
- flush_dcache_range(start, end);
- jr.input_ring[head] = desc_phys_addr;
- start = (unsigned long)jr.input_ring & ~(ARCH_DMA_MINALIGN - 1);
- end = ALIGN(start + sizeof(dma_addr_t)*JR_SIZE , ARCH_DMA_MINALIGN);
- flush_dcache_range(start, end);
Here the address passed to the
jr.head = (head + 1) & (jr.size - 1);
sec_out32(®s->irja, 1);
@@ -187,6 +198,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; diff --git
a/include/fsl_sec.h b/include/fsl_sec.h index aa850a3..95fbb6b 100644 --- a/include/fsl_sec.h +++ b/include/fsl_sec.h @@ -11,6 +11,13 @@ #include <common.h> #include <asm/io.h>
+#ifdef CONFIG_ARM +#define sec_in32(a) __raw_readl(a) +#define sec_out32(a, v) __raw_writel(v, a) +#define sec_in16(a) __raw_readw(a) +#define sec_clrbits32 clrbits_le32 +#define sec_setbits32 setbits_le32 +#elif CONFIG_PPC #ifdef CONFIG_SYS_FSL_SEC_LE #define sec_in32(a) in_le32(a) #define sec_out32(a, v) out_le32(a, v) @@ -26,6 +33,7 @@ #else #error Neither CONFIG_SYS_FSL_SEC_LE nor CONFIG_SYS_FSL_SEC_BE is defined #endif +#endif /* ARCHITECURE */
/* Security Engine Block (MS = Most Sig., LS = Least Sig.) */ #if CONFIG_SYS_FSL_SEC_COMPAT >= 4 @@ -175,7 +183,59 @@ struct jr_regs { u32 jrcr; };
+#ifdef CONFIG_MX6
+#define SMCSJR_PO (3 << 6) +#define SMCSJR_AERR (3 << 12) +#define SMCSJR_CERR (3 << 14) +#define CAAM_SMPO_0 CONFIG_SYS_FSL_SEC_ADDR + 0x1FBC +#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 ERROR_IN_PAGE_ALLOC (1) +#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))
+/* 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 */
+/* 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
+#define PARTITION_1 1 +#define PAGE_1 1
+#endif
int sec_init(void);
+int blob_dek(u8 *src, u8 *dst, u8 len);
#endif
#endif /* __FSL_SEC_H */
1.7.9.5
Regards, Ruchika
participants (2)
-
Ruchika Gupta
-
Ulises.Cardenas@freescale.com