]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
imx6: Added DEK blob generator command
authorRaul Cardenas <Ulises.Cardenas@freescale.com>
Fri, 27 Feb 2015 17:22:06 +0000 (11:22 -0600)
committerLothar Waßmann <LW@KARO-electronics.de>
Tue, 1 Sep 2015 12:10:23 +0000 (14:10 +0200)
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>
12 files changed:
arch/arm/imx-common/Makefile
arch/arm/imx-common/cmd_dek.c [new file with mode: 0644]
arch/arm/imx-common/timer.c
arch/arm/include/asm/arch-mx6/imx-regs.h
doc/README.mxc_hab
drivers/crypto/fsl/Makefile
drivers/crypto/fsl/desc.h
drivers/crypto/fsl/fsl_blob.c
drivers/crypto/fsl/jobdesc.c
drivers/crypto/fsl/jobdesc.h
drivers/crypto/fsl/jr.c
include/fsl_sec.h

index 25a9d4ce125692c933f646a2deee3feed292b6fd..606482f7a38fc138f1b0bd88d9cbc7141dc75545 100644 (file)
@@ -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 (file)
index 0000000..d93d5fb
--- /dev/null
@@ -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
+);
index b1f51611d5eeb311fbfed756e4b2e41fdc8960ff..d471b9a47a55083cdcaf69eb7f7cf043aa5d6130 100644 (file)
@@ -190,3 +190,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;
+}
index b23866a6a1ba0422ee75328ae45b628800f746b7..8f47fd7803a4184dd4613fe2f07916d9b582f6d6 100644 (file)
@@ -11,7 +11,7 @@
 
 #define ARCH_MXC
 
-#define CONFIG_SYS_CACHELINE_SIZE       64
+#define CONFIG_SYS_CACHELINE_SIZE      64
 
 #define ROMCP_ARB_BASE_ADDR            0x00000000
 #define ROMCP_ARB_END_ADDR             0x000FFFFF
@@ -90,8 +90,8 @@
 #define AIPS2_ARB_BASE_ADDR            0x02100000
 #define AIPS2_ARB_END_ADDR             0x021FFFFF
 #ifdef CONFIG_SOC_MX6SX
-#define AIPS3_ARB_BASE_ADDR             0x02200000
-#define AIPS3_ARB_END_ADDR              0x022FFFFF
+#define AIPS3_ARB_BASE_ADDR            0x02200000
+#define AIPS3_ARB_END_ADDR             0x022FFFFF
 #define WEIM_ARB_BASE_ADDR             0x50000000
 #define WEIM_ARB_END_ADDR              0x57FFFFFF
 #define QSPI0_AMBA_BASE                        0x60000000
 #endif
 
 /* Defines for Blocks connected via AIPS (SkyBlue) */
-#define ATZ1_BASE_ADDR             AIPS1_ARB_BASE_ADDR
-#define ATZ2_BASE_ADDR             AIPS2_ARB_BASE_ADDR
-#define AIPS1_BASE_ADDR                    AIPS1_ON_BASE_ADDR
-#define AIPS2_BASE_ADDR                    AIPS2_ON_BASE_ADDR
-
-#define SPDIF_BASE_ADDR                    (ATZ1_BASE_ADDR + 0x04000)
-#define ECSPI1_BASE_ADDR           (ATZ1_BASE_ADDR + 0x08000)
-#define ECSPI2_BASE_ADDR           (ATZ1_BASE_ADDR + 0x0C000)
-#define ECSPI3_BASE_ADDR           (ATZ1_BASE_ADDR + 0x10000)
-#define ECSPI4_BASE_ADDR           (ATZ1_BASE_ADDR + 0x14000)
+#define ATZ1_BASE_ADDR                 AIPS1_ARB_BASE_ADDR
+#define ATZ2_BASE_ADDR                 AIPS2_ARB_BASE_ADDR
+#define AIPS1_BASE_ADDR                        AIPS1_ON_BASE_ADDR
+#define AIPS2_BASE_ADDR                        AIPS2_ON_BASE_ADDR
+
+#define SPDIF_BASE_ADDR                        (ATZ1_BASE_ADDR + 0x04000)
+#define ECSPI1_BASE_ADDR               (ATZ1_BASE_ADDR + 0x08000)
+#define ECSPI2_BASE_ADDR               (ATZ1_BASE_ADDR + 0x0C000)
+#define ECSPI3_BASE_ADDR               (ATZ1_BASE_ADDR + 0x10000)
+#define ECSPI4_BASE_ADDR               (ATZ1_BASE_ADDR + 0x14000)
 #ifdef CONFIG_SOC_MX6SL
-#define UART5_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x18000)
-#define UART1_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x20000)
-#define UART2_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x24000)
-#define SSI1_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x28000)
-#define SSI2_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x2C000)
-#define SSI3_IPS_BASE_ADDR         (ATZ1_BASE_ADDR + 0x30000)
-#define UART3_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x34000)
-#define UART4_IPS_BASE_ADDR        (ATZ1_BASE_ADDR + 0x38000)
+#define UART5_IPS_BASE_ADDR            (ATZ1_BASE_ADDR + 0x18000)
+#define UART1_IPS_BASE_ADDR            (ATZ1_BASE_ADDR + 0x20000)
+#define UART2_IPS_BASE_ADDR            (ATZ1_BASE_ADDR + 0x24000)
+#define SSI1_IPS_BASE_ADDR             (ATZ1_BASE_ADDR + 0x28000)
+#define SSI2_IPS_BASE_ADDR             (ATZ1_BASE_ADDR + 0x2C000)
+#define SSI3_IPS_BASE_ADDR             (ATZ1_BASE_ADDR + 0x30000)
+#define UART3_IPS_BASE_ADDR            (ATZ1_BASE_ADDR + 0x34000)
+#define UART4_IPS_BASE_ADDR            (ATZ1_BASE_ADDR + 0x38000)
 #else
 #ifndef CONFIG_SOC_MX6SX
-#define ECSPI5_BASE_ADDR           (ATZ1_BASE_ADDR + 0x18000)
+#define ECSPI5_BASE_ADDR               (ATZ1_BASE_ADDR + 0x18000)
 #endif
-#define UART1_BASE                 (ATZ1_BASE_ADDR + 0x20000)
-#define ESAI1_BASE_ADDR                    (ATZ1_BASE_ADDR + 0x24000)
-#define SSI1_BASE_ADDR             (ATZ1_BASE_ADDR + 0x28000)
-#define SSI2_BASE_ADDR             (ATZ1_BASE_ADDR + 0x2C000)
-#define SSI3_BASE_ADDR             (ATZ1_BASE_ADDR + 0x30000)
-#define ASRC_BASE_ADDR             (ATZ1_BASE_ADDR + 0x34000)
+#define UART1_BASE                     (ATZ1_BASE_ADDR + 0x20000)
+#define ESAI1_BASE_ADDR                        (ATZ1_BASE_ADDR + 0x24000)
+#define SSI1_BASE_ADDR                 (ATZ1_BASE_ADDR + 0x28000)
+#define SSI2_BASE_ADDR                 (ATZ1_BASE_ADDR + 0x2C000)
+#define SSI3_BASE_ADDR                 (ATZ1_BASE_ADDR + 0x30000)
+#define ASRC_BASE_ADDR                 (ATZ1_BASE_ADDR + 0x34000)
 #endif
 
 #ifndef CONFIG_SOC_MX6SX
-#define SPBA_BASE_ADDR             (ATZ1_BASE_ADDR + 0x3C000)
-#define VPU_BASE_ADDR              (ATZ1_BASE_ADDR + 0x40000)
+#define SPBA_BASE_ADDR                 (ATZ1_BASE_ADDR + 0x3C000)
+#define VPU_BASE_ADDR                  (ATZ1_BASE_ADDR + 0x40000)
 #endif
-#define AIPS1_ON_BASE_ADDR         (ATZ1_BASE_ADDR + 0x7C000)
-
-#define AIPS1_OFF_BASE_ADDR        (ATZ1_BASE_ADDR + 0x80000)
-#define PWM1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x0000)
-#define PWM2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x4000)
-#define PWM3_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x8000)
-#define PWM4_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0xC000)
-#define CAN1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x10000)
-#define CAN2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x14000)
-#define GPT1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x18000)
-#define GPIO1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x1C000)
-#define GPIO2_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x20000)
-#define GPIO3_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x24000)
-#define GPIO4_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x28000)
-#define GPIO5_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x2C000)
-#define GPIO6_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x30000)
-#define GPIO7_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x34000)
-#define KPP_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x38000)
-#define WDOG1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x3C000)
-#define WDOG2_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x40000)
-#define CCM_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x44000)
-#define ANATOP_BASE_ADDR           (AIPS1_OFF_BASE_ADDR + 0x48000)
-#define USB_PHY0_BASE_ADDR         (AIPS1_OFF_BASE_ADDR + 0x49000)
-#define USB_PHY1_BASE_ADDR         (AIPS1_OFF_BASE_ADDR + 0x4a000)
-#define SNVS_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x4C000)
-#define EPIT1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x50000)
-#define EPIT2_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x54000)
-#define SRC_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x58000)
-#define GPC_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x5C000)
-#define IOMUXC_BASE_ADDR           (AIPS1_OFF_BASE_ADDR + 0x60000)
+#define AIPS1_ON_BASE_ADDR             (ATZ1_BASE_ADDR + 0x7C000)
+
+#define AIPS1_OFF_BASE_ADDR            (ATZ1_BASE_ADDR + 0x80000)
+#define PWM1_BASE_ADDR                 (AIPS1_OFF_BASE_ADDR + 0x0000)
+#define PWM2_BASE_ADDR                 (AIPS1_OFF_BASE_ADDR + 0x4000)
+#define PWM3_BASE_ADDR                 (AIPS1_OFF_BASE_ADDR + 0x8000)
+#define PWM4_BASE_ADDR                 (AIPS1_OFF_BASE_ADDR + 0xC000)
+#define CAN1_BASE_ADDR                 (AIPS1_OFF_BASE_ADDR + 0x10000)
+#define CAN2_BASE_ADDR                 (AIPS1_OFF_BASE_ADDR + 0x14000)
+#define GPT1_BASE_ADDR                 (AIPS1_OFF_BASE_ADDR + 0x18000)
+#define GPIO1_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x1C000)
+#define GPIO2_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x20000)
+#define GPIO3_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x24000)
+#define GPIO4_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x28000)
+#define GPIO5_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x2C000)
+#define GPIO6_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x30000)
+#define GPIO7_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x34000)
+#define KPP_BASE_ADDR                  (AIPS1_OFF_BASE_ADDR + 0x38000)
+#define WDOG1_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x3C000)
+#define WDOG2_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x40000)
+#define CCM_BASE_ADDR                  (AIPS1_OFF_BASE_ADDR + 0x44000)
+#define ANATOP_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x48000)
+#define USB_PHY0_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x49000)
+#define USB_PHY1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x4a000)
+#define SNVS_BASE_ADDR                 (AIPS1_OFF_BASE_ADDR + 0x4C000)
+#define EPIT1_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x50000)
+#define EPIT2_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x54000)
+#define SRC_BASE_ADDR                  (AIPS1_OFF_BASE_ADDR + 0x58000)
+#define GPC_BASE_ADDR                  (AIPS1_OFF_BASE_ADDR + 0x5C000)
+#define IOMUXC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x60000)
 #ifdef CONFIG_SOC_MX6SL
-#define CSI_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x64000)
-#define SIPIX_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x68000)
-#define SDMA_PORT_HOST_BASE_ADDR    (AIPS1_OFF_BASE_ADDR + 0x6C000)
+#define CSI_BASE_ADDR                  (AIPS1_OFF_BASE_ADDR + 0x64000)
+#define SIPIX_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x68000)
+#define SDMA_PORT_HOST_BASE_ADDR       (AIPS1_OFF_BASE_ADDR + 0x6C000)
 #elif defined(CONFIG_SOC_MX6SX)
-#define CANFD1_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x68000)
-#define SDMA_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x6C000)
-#define CANFD2_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x70000)
-#define SEMAPHORE1_BASE_ADDR        (AIPS1_OFF_BASE_ADDR + 0x74000)
-#define SEMAPHORE2_BASE_ADDR        (AIPS1_OFF_BASE_ADDR + 0x78000)
-#define RDC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x7C000)
+#define CANFD1_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x68000)
+#define SDMA_BASE_ADDR                 (AIPS1_OFF_BASE_ADDR + 0x6C000)
+#define CANFD2_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x70000)
+#define SEMAPHORE1_BASE_ADDR           (AIPS1_OFF_BASE_ADDR + 0x74000)
+#define SEMAPHORE2_BASE_ADDR           (AIPS1_OFF_BASE_ADDR + 0x78000)
+#define RDC_BASE_ADDR                  (AIPS1_OFF_BASE_ADDR + 0x7C000)
 #else
-#define DCIC1_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x64000)
-#define DCIC2_BASE_ADDR                    (AIPS1_OFF_BASE_ADDR + 0x68000)
-#define DMA_REQ_PORT_HOST_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x6C000)
+#define DCIC1_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x64000)
+#define DCIC2_BASE_ADDR                        (AIPS1_OFF_BASE_ADDR + 0x68000)
+#define DMA_REQ_PORT_HOST_BASE_ADDR    (AIPS1_OFF_BASE_ADDR + 0x6C000)
 #endif
 
-#define AIPS2_ON_BASE_ADDR         (ATZ2_BASE_ADDR + 0x7C000)
-#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 USB_PL301_BASE_ADDR        (AIPS2_OFF_BASE_ADDR + 0x0000)
-#define USB_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x4000)
+#define AIPS2_ON_BASE_ADDR             (ATZ2_BASE_ADDR + 0x7C000)
+#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 ENET_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x8000)
+#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)
+
+#define ENET_BASE_ADDR                 (AIPS2_OFF_BASE_ADDR + 0x8000)
 #ifdef CONFIG_SOC_MX6SL
-#define MSHC_IPS_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0xC000)
+#define MSHC_IPS_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0xC000)
 #else
-#define MLB_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0xC000)
+#define MLB_BASE_ADDR                  (AIPS2_OFF_BASE_ADDR + 0xC000)
 #endif
 
-#define USDHC1_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x10000)
-#define USDHC2_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x14000)
-#define USDHC3_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x18000)
-#define USDHC4_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x1C000)
-#define I2C1_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x20000)
-#define I2C2_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x24000)
-#define I2C3_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x28000)
-#define ROMCP_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x2C000)
-#define MMDC_P0_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x30000)
+#define USDHC1_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0x10000)
+#define USDHC2_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0x14000)
+#define USDHC3_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0x18000)
+#define USDHC4_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0x1C000)
+#define I2C1_BASE_ADDR                 (AIPS2_OFF_BASE_ADDR + 0x20000)
+#define I2C2_BASE_ADDR                 (AIPS2_OFF_BASE_ADDR + 0x24000)
+#define I2C3_BASE_ADDR                 (AIPS2_OFF_BASE_ADDR + 0x28000)
+#define ROMCP_BASE_ADDR                        (AIPS2_OFF_BASE_ADDR + 0x2C000)
+#define MMDC_P0_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x30000)
 #ifdef CONFIG_SOC_MX6SL
-#define RNGB_IPS_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x34000)
+#define RNGB_IPS_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x34000)
 #elif defined(CONFIG_SOC_MX6SX)
-#define ENET2_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x34000)
+#define ENET2_BASE_ADDR                        (AIPS2_OFF_BASE_ADDR + 0x34000)
 #else
-#define MMDC_P1_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x34000)
+#define MMDC_P1_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x34000)
 #endif
 
-#define WEIM_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x38000)
-#define OCOTP_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x3C000)
-#define CSU_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x40000)
-#define IP2APB_PERFMON1_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x44000)
-#define IP2APB_PERFMON2_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x48000)
+#define WEIM_BASE_ADDR                 (AIPS2_OFF_BASE_ADDR + 0x38000)
+#define OCOTP_BASE_ADDR                        (AIPS2_OFF_BASE_ADDR + 0x3C000)
+#define CSU_BASE_ADDR                  (AIPS2_OFF_BASE_ADDR + 0x40000)
+#define IP2APB_PERFMON1_BASE_ADDR      (AIPS2_OFF_BASE_ADDR + 0x44000)
+#define IP2APB_PERFMON2_BASE_ADDR      (AIPS2_OFF_BASE_ADDR + 0x48000)
 #ifdef CONFIG_SOC_MX6SX
-#define DEBUG_MONITOR_BASE_ADDR     (AIPS2_OFF_BASE_ADDR + 0x4C000)
+#define DEBUG_MONITOR_BASE_ADDR                (AIPS2_OFF_BASE_ADDR + 0x4C000)
 #else
-#define IP2APB_PERFMON3_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x4C000)
+#define IP2APB_PERFMON3_BASE_ADDR      (AIPS2_OFF_BASE_ADDR + 0x4C000)
 #endif
-#define IP2APB_TZASC1_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x50000)
+#define IP2APB_TZASC1_BASE_ADDR                (AIPS2_OFF_BASE_ADDR + 0x50000)
 #ifdef CONFIG_SOC_MX6SX
-#define SAI1_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x54000)
+#define SAI1_BASE_ADDR                 (AIPS2_OFF_BASE_ADDR + 0x54000)
 #else
-#define IP2APB_TZASC2_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x54000)
+#define IP2APB_TZASC2_BASE_ADDR                (AIPS2_OFF_BASE_ADDR + 0x54000)
 #endif
-#define AUDMUX_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x58000)
+#define AUDMUX_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0x58000)
 #ifdef CONFIG_SOC_MX6SX
-#define SAI2_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x5C000)
-#define QSPI0_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x60000)
-#define QSPI1_BASE_ADDR                    (AIPS2_OFF_BASE_ADDR + 0x64000)
+#define SAI2_BASE_ADDR                 (AIPS2_OFF_BASE_ADDR + 0x5C000)
+#define QSPI0_BASE_ADDR                        (AIPS2_OFF_BASE_ADDR + 0x60000)
+#define QSPI1_BASE_ADDR                        (AIPS2_OFF_BASE_ADDR + 0x64000)
 #else
-#define MIPI_CSI2_BASE_ADDR        (AIPS2_OFF_BASE_ADDR + 0x5C000)
-#define MIPI_DSI_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x60000)
-#define VDOA_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x64000)
+#define MIPI_CSI2_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x5C000)
+#define MIPI_DSI_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x60000)
+#define VDOA_BASE_ADDR                 (AIPS2_OFF_BASE_ADDR + 0x64000)
 #endif
-#define UART2_BASE                 (AIPS2_OFF_BASE_ADDR + 0x68000)
-#define UART3_BASE                 (AIPS2_OFF_BASE_ADDR + 0x6C000)
-#define UART4_BASE                 (AIPS2_OFF_BASE_ADDR + 0x70000)
-#define UART5_BASE                 (AIPS2_OFF_BASE_ADDR + 0x74000)
-#define IP2APB_USBPHY1_BASE_ADDR    (AIPS2_OFF_BASE_ADDR + 0x78000)
-#define IP2APB_USBPHY2_BASE_ADDR    (AIPS2_OFF_BASE_ADDR + 0x7C000)
+#define UART2_BASE                     (AIPS2_OFF_BASE_ADDR + 0x68000)
+#define UART3_BASE                     (AIPS2_OFF_BASE_ADDR + 0x6C000)
+#define UART4_BASE                     (AIPS2_OFF_BASE_ADDR + 0x70000)
+#define UART5_BASE                     (AIPS2_OFF_BASE_ADDR + 0x74000)
+#define IP2APB_USBPHY1_BASE_ADDR       (AIPS2_OFF_BASE_ADDR + 0x78000)
+#define IP2APB_USBPHY2_BASE_ADDR       (AIPS2_OFF_BASE_ADDR + 0x7C000)
 
 #ifdef CONFIG_SOC_MX6SX
-#define GIS_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x04000)
-#define DCIC1_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x0C000)
-#define DCIC2_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x10000)
-#define CSI1_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x14000)
-#define PXP_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x18000)
-#define CSI2_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x1C000)
-#define LCDIF1_BASE_ADDR           (AIPS3_ARB_BASE_ADDR + 0x20000)
-#define LCDIF2_BASE_ADDR           (AIPS3_ARB_BASE_ADDR + 0x24000)
-#define VADC_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x28000)
-#define VDEC_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x2C000)
-#define SPBA_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x3C000)
-#define AIPS3_CONFIG_BASE_ADDR     (AIPS3_ARB_BASE_ADDR + 0x7C000)
-#define ADC1_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x80000)
-#define ADC2_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x84000)
-#define WDOG3_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x88000)
-#define ECSPI5_BASE_ADDR           (AIPS3_ARB_BASE_ADDR + 0x8C000)
-#define HS_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x90000)
-#define MU_MCU_BASE_ADDR           (AIPS3_ARB_BASE_ADDR + 0x94000)
-#define CANFD_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0x98000)
-#define MU_DSP_BASE_ADDR           (AIPS3_ARB_BASE_ADDR + 0x9C000)
-#define UART6_BASE_ADDR                    (AIPS3_ARB_BASE_ADDR + 0xA0000)
-#define PWM5_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xA4000)
-#define PWM6_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xA8000)
-#define PWM7_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xAC000)
-#define PWM8_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xB0000)
+#define GIS_BASE_ADDR                  (AIPS3_ARB_BASE_ADDR + 0x04000)
+#define DCIC1_BASE_ADDR                        (AIPS3_ARB_BASE_ADDR + 0x0C000)
+#define DCIC2_BASE_ADDR                        (AIPS3_ARB_BASE_ADDR + 0x10000)
+#define CSI1_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0x14000)
+#define PXP_BASE_ADDR                  (AIPS3_ARB_BASE_ADDR + 0x18000)
+#define CSI2_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0x1C000)
+#define LCDIF1_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x20000)
+#define LCDIF2_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x24000)
+#define VADC_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0x28000)
+#define VDEC_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0x2C000)
+#define SPBA_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0x3C000)
+#define AIPS3_CONFIG_BASE_ADDR         (AIPS3_ARB_BASE_ADDR + 0x7C000)
+#define ADC1_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0x80000)
+#define ADC2_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0x84000)
+#define WDOG3_BASE_ADDR                        (AIPS3_ARB_BASE_ADDR + 0x88000)
+#define ECSPI5_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x8C000)
+#define HS_BASE_ADDR                   (AIPS3_ARB_BASE_ADDR + 0x90000)
+#define MU_MCU_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x94000)
+#define CANFD_BASE_ADDR                        (AIPS3_ARB_BASE_ADDR + 0x98000)
+#define MU_DSP_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x9C000)
+#define UART6_BASE_ADDR                        (AIPS3_ARB_BASE_ADDR + 0xA0000)
+#define PWM5_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0xA4000)
+#define PWM6_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0xA8000)
+#define PWM7_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0xAC000)
+#define PWM8_BASE_ADDR                 (AIPS3_ARB_BASE_ADDR + 0xB0000)
 #endif
 
-#define CHIP_REV_1_0                0x10
-#define CHIP_REV_1_2                0x12
-#define CHIP_REV_1_5                0x15
+#define CHIP_REV_1_0                   0x10
+#define CHIP_REV_1_2                   0x12
+#define CHIP_REV_1_5                   0x15
 #ifndef CONFIG_SOC_MX6SX
-#define IRAM_SIZE                   0x00040000
+#define IRAM_SIZE                      0x00040000
 #else
-#define IRAM_SIZE                   0x00020000
+#define IRAM_SIZE                      0x00020000
 #endif
-#define IMX_IIM_BASE                OCOTP_BASE_ADDR
+#define IMX_IIM_BASE                   OCOTP_BASE_ADDR
 #define FEC_QUIRK_ENET_MAC
 
 #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
index 43e64a2797ded0b94e6b3865b01752172ac1cef1..e9340dd14cd4a6f687116712f5cee86a7513f555 100644 (file)
@@ -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.
index c0cf64229ebe513688c6a85e61dac16689cdcb83..4aa91e4393192d6ae9e5b5a98905b702013790c6 100644 (file)
@@ -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
index 504f2b07d090b0c8722d115c2b82644f4db01103..18e2ec8d26ecb8c0816c7790ff2621ffee543b12 100644 (file)
 #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.
 #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
 #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)
index 9923bcbfe95b9117e36d040d6210649b21bfe2db..8b259212723cd13027549c884780da186fe89c43 100644 (file)
@@ -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
index cc0dcede7b787ed19cd815a2b73a18a5334f75cb..5695bef6fd2a5d77dd83a9994c418c38d287dc04 100644 (file)
  */
 
 #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,
index 84b3edd6e2f9ab5ad4b49e1da105143fc654400e..112404c74d638efa64465081363df607b98964e6 100644 (file)
 
 #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);
index f9d493883452016f59e2669495fb35295bca2f5a..f99d59480c816869cde1046e800b6e524f554ae3 100644 (file)
@@ -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(&regs->irja, 1);
@@ -187,6 +199,13 @@ static int jr_dequeue(void)
        void *arg = NULL;
 
        while (sec_in32(&regs->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)
index b6e6f04a34ce52d0da088b84f19ac5bdf2ae0ebf..dbfae68ef42c8a5a4bb29773b822b5db4610bf9c 100644 (file)
@@ -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 */