From 3a2c35d85017aa38921604572cc26e945597f838 Mon Sep 17 00:00:00 2001 From: "Diaz de Grenu, Jose" Date: Tue, 23 Aug 2016 17:53:58 +0200 Subject: [PATCH] meta-digi: meta-digi-arm: add environment encryption support to fw_* utils This patch adds the functionality to automatically detect if the enviroment is encrypted (through the device tree). If it is, the environment is encrypted and decrypted as required in a transparent way for the user. https://jira.digi.com/browse/DEL-2836 Signed-off-by: Diaz de Grenu, Jose --- ...ent-support-for-environment-encrypti.patch | 301 ++++++++++++++++++ ...upport-to-unlock-emmc-boot-partition.patch | 6 +- .../u-boot/u-boot-fw-utils_%.bbappend | 5 +- 3 files changed, 308 insertions(+), 4 deletions(-) create mode 100644 meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0001-tools-env-implement-support-for-environment-encrypti.patch diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0001-tools-env-implement-support-for-environment-encrypti.patch b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0001-tools-env-implement-support-for-environment-encrypti.patch new file mode 100644 index 000000000..922ca71d6 --- /dev/null +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0001-tools-env-implement-support-for-environment-encrypti.patch @@ -0,0 +1,301 @@ +From: "Diaz de Grenu, Jose" +Date: Tue, 23 Aug 2016 13:05:05 +0200 +Subject: [PATCH] tools: env: implement support for environment encryption by + CAAM + +https://jira.digi.com/browse/DEL-2836 + +Signed-off-by: Diaz de Grenu, Jose +--- + configs/sandbox_defconfig | 1 + + tools/env/Makefile | 2 +- + tools/env/caam_keyblob.h | 45 +++++++++++++++ + tools/env/fw_env.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 187 insertions(+), 1 deletion(-) + create mode 100644 tools/env/caam_keyblob.h + +diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig +index 598519dbb2fc..81dd4d445c0e 100644 +--- a/configs/sandbox_defconfig ++++ b/configs/sandbox_defconfig +@@ -44,3 +44,4 @@ CONFIG_UNIT_TEST=y + CONFIG_UT_TIME=y + CONFIG_UT_DM=y + CONFIG_UT_ENV=y ++CONFIG_MD5=y +diff --git a/tools/env/Makefile b/tools/env/Makefile +index 40164f7a35fa..de4766ddf8dd 100644 +--- a/tools/env/Makefile ++++ b/tools/env/Makefile +@@ -25,7 +25,7 @@ hostprogs-y := fw_printenv + + fw_printenv-objs := fw_env.o fw_env_main.o \ + crc32.o ctype.o linux_string.o \ +- env_attr.o env_flags.o aes.o ++ env_attr.o env_flags.o aes.o ../../lib/md5.o + + quiet_cmd_crosstools_strip = STRIP $^ + cmd_crosstools_strip = $(STRIP) $^; touch $@ +diff --git a/tools/env/caam_keyblob.h b/tools/env/caam_keyblob.h +new file mode 100644 +index 000000000000..1e33b3f01a05 +--- /dev/null ++++ b/tools/env/caam_keyblob.h +@@ -0,0 +1,45 @@ ++/* ++ * CAAM public-level include definitions for the key blob ++ * ++ * Copyright (C) 2015 Freescale Semiconductor, Inc. ++ */ ++ ++#ifndef CAAM_KEYBLOB_H ++#define CAAM_KEYBLOB_H ++ ++ ++#include ++#include ++ ++struct caam_kb_data { ++ char *rawkey; ++ size_t rawkey_len; ++ char *keyblob; ++ size_t keyblob_len; ++ char *keymod; ++ size_t keymod_len; ++}; ++ ++ ++#define CAAM_KB_MAGIC 'I' ++ ++/** ++ * DOC: CAAM_KB_ENCRYPT - generate a key blob from raw key ++ * ++ * Takes an caam_kb_data struct and returns it with the key blob ++ */ ++#define CAAM_KB_ENCRYPT _IOWR(CAAM_KB_MAGIC, 0, \ ++ struct caam_kb_data) ++ ++/** ++ * DOC: CAAM_KB_DECRYPT - get keys from a key blob ++ * ++ * Takes an caam_kb_data struct and returns it with the raw key. ++ */ ++#define CAAM_KB_DECRYPT _IOWR(CAAM_KB_MAGIC, 1, struct caam_kb_data) ++ ++#ifndef GENMEM_KEYMOD_LEN ++#define GENMEM_KEYMOD_LEN 16 ++#endif ++ ++#endif /* CAAM_KEYBLOB_H */ +\ No newline at end of file +diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c +index daa02a760e37..09f06c874b17 100644 +--- a/tools/env/fw_env.c ++++ b/tools/env/fw_env.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + #include + + #ifdef MTD_OLD +@@ -31,10 +32,19 @@ + # include + #endif + ++#include "caam_keyblob.h" + #include "fw_env.h" + + #include + ++/* ++ * The BLOB includes a random AES-256 key (32 bytes) and a ++ * Message Authentication Code (MAC) (16 bytes) ++ */ ++#define BLOB_OVERHEAD 48 ++#define CAAM_KEY_DEV "/dev/caam_kb" ++ ++#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) + #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) + + #define WHITESPACE(c) ((c == '\t') || (c == ' ')) +@@ -109,6 +119,8 @@ static int aes_flag; + static uint8_t aes_key[AES_KEY_LENGTH] = { 0 }; + static int env_aes_cbc_crypt(char *data, const int enc); + ++static int caam_encryption_flag; ++ + static int HaveRedundEnv = 0; + + static unsigned char active_flag = 1; +@@ -236,6 +248,103 @@ static int parse_aes_key(char *key) + return 0; + } + ++static void check_caam_encryption(void) ++{ ++ const char *dt_prop = "/proc/device-tree/digi,uboot-env,encrypted"; ++ ++ if (access(dt_prop, F_OK) != -1) ++ caam_encryption_flag = 1; ++} ++ ++static int env_caam_get_keymod(unsigned char output[16]) ++{ ++ int i; ++ int len; ++ int fd; ++ char buff[32]; ++ uint32_t ocotp_hwid[2]; ++ const char *ocotp_hwid_file[2] = { ++ "/sys/fsl_otp/HW_OCOTP_MAC0", ++ "/sys/fsl_otp/HW_OCOTP_MAC1" ++ }; ++ ++ for (i = 0; i < ARRAY_SIZE(ocotp_hwid); i++) { ++ fd = open(ocotp_hwid_file[i], O_RDONLY); ++ if (fd < 0) ++ return fd; ++ len = read(fd, buff, sizeof(buff)); ++ if (len < 0) { ++ close(fd); ++ return -1; ++ } ++ /* drop last character (new line) */ ++ buff[len - 1] = '\0'; ++ ocotp_hwid[i] = strtoul(buff, NULL, 0); ++ close(fd); ++ } ++ ++ md5((unsigned char *)(&ocotp_hwid), sizeof(ocotp_hwid), output); ++ ++ return 0; ++} ++ ++static int env_caam_crypt(char *data, const int enc) ++{ ++ struct caam_kb_data enc_data; ++ int fd; ++ int ret = 0; ++ const int len = getenvsize(); ++ int ioctl_mode; ++ char *buffer; ++ unsigned char key_modifier[16]; ++ ++ ret = env_caam_get_keymod(key_modifier); ++ if (ret) ++ return ret; ++ ++ enc_data.keymod = (char *)key_modifier; ++ enc_data.keymod_len = sizeof(key_modifier); ++ ++ enc_data.keyblob_len = len; ++ enc_data.rawkey_len = len - BLOB_OVERHEAD; ++ ++ buffer = malloc(len); ++ if (!buffer) { ++ printf("Could not allocate memory\n"); ++ return -1; ++ } ++ ++ if (enc) { ++ enc_data.rawkey = data; ++ ioctl_mode = CAAM_KB_ENCRYPT; ++ enc_data.keyblob = buffer; ++ } else { ++ enc_data.keyblob = data; ++ ioctl_mode = CAAM_KB_DECRYPT; ++ enc_data.rawkey = buffer; ++ } ++ ++ if ((fd = open(CAAM_KEY_DEV, O_RDWR)) < 0) { ++ ret = fd; ++ goto free; ++ } ++ ++ ret = ioctl(fd, ioctl_mode, &enc_data); ++ if (ret) { ++ printf("CAAM_KEY_DEV ioctl failed: %d\n", ret); ++ goto out; ++ } ++ ++ memcpy(data, buffer, len); ++ ++out: ++ close(fd); ++free: ++ free(buffer); ++ ++ return ret; ++} ++ + /* + * Print the current definition of one, or more, or all + * environment variables +@@ -259,6 +368,8 @@ int fw_printenv (int argc, char *argv[]) + argc -= 2; + } + ++ check_caam_encryption(); ++ + if (fw_env_open()) + return -1; + +@@ -334,6 +445,15 @@ int fw_env_close(void) + } + } + ++ if (caam_encryption_flag) { ++ ret = env_caam_crypt(environment.data, 1); ++ if (ret) { ++ fprintf(stderr, ++ "Error: can't encrypt env for flash\n"); ++ return ret; ++ } ++ } ++ + /* + * Update CRC + */ +@@ -504,6 +624,8 @@ int fw_setenv(int argc, char *argv[]) + argc -= 2; + } + ++ check_caam_encryption(); ++ + if (argc < 2) { + errno = EINVAL; + return -1; +@@ -1229,6 +1351,15 @@ int fw_env_open(void) + return ret; + } + ++ if (caam_encryption_flag) { ++ ret = env_caam_crypt(environment.data, 0); ++ if (ret) { ++ fprintf(stderr, ++ "Error: can't decrypt environment\n"); ++ return ret; ++ } ++ } ++ + crc0_ok = (crc0 == *environment.crc); + if (!HaveRedundEnv) { + if (!crc0_ok) { +@@ -1286,6 +1417,15 @@ int fw_env_open(void) + return ret; + } + ++ if (caam_encryption_flag) { ++ ret = env_caam_crypt(redundant->data, 0); ++ if (ret) { ++ fprintf(stderr, ++ "Error: can't decrypt environment\n"); ++ return ret; ++ } ++ } ++ + crc1_ok = (crc1 == redundant->crc); + flag1 = redundant->flags; + diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0002-fw_env-add-support-to-unlock-emmc-boot-partition.patch b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0002-fw_env-add-support-to-unlock-emmc-boot-partition.patch index e283118ee..f1c50aa56 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0002-fw_env-add-support-to-unlock-emmc-boot-partition.patch +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils/0002-fw_env-add-support-to-unlock-emmc-boot-partition.patch @@ -8,10 +8,10 @@ Signed-off-by: Javier Viguera 1 file changed, 33 insertions(+) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c -index 698fe5181bc0..d7e61a467e73 100644 +index 09f06c874b17..ae6c69eca0ad 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c -@@ -1097,6 +1097,27 @@ static int flash_read (int fd) +@@ -1218,6 +1218,27 @@ static int flash_read (int fd) return 0; } @@ -39,7 +39,7 @@ index 698fe5181bc0..d7e61a467e73 100644 static int flash_io (int mode) { int fd_current, fd_target, rc, dev_target; -@@ -1129,8 +1150,20 @@ static int flash_io (int mode) +@@ -1250,8 +1271,20 @@ static int flash_io (int mode) fd_target = fd_current; } diff --git a/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend index 89240d47b..028c6f255 100644 --- a/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend +++ b/meta-digi-arm/recipes-bsp/u-boot/u-boot-fw-utils_%.bbappend @@ -2,7 +2,10 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${BPN}:" -SRC_URI += "file://fw_env.config" +SRC_URI += " \ + file://fw_env.config \ + file://0001-tools-env-implement-support-for-environment-encrypti.patch \ +" SRC_URI_append_ccimx6 = " file://0002-fw_env-add-support-to-unlock-emmc-boot-partition.patch" # We do not have a platform defconfig in this version of u-boot, so just use the generic