* [U-Boot] [PATCH 1/3] env: Add env_export() wrapper
@ 2014-02-06 3:45 Marek Vasut
2014-02-06 3:45 ` [U-Boot] [PATCH 2/3] env: Implement support for encrypting environment Marek Vasut
2014-02-06 3:45 ` [U-Boot] [PATCH 3/3] env: Implement support for AES encryption into fw_* tools Marek Vasut
0 siblings, 2 replies; 6+ messages in thread
From: Marek Vasut @ 2014-02-06 3:45 UTC (permalink / raw)
To: u-boot
Implement env_export() wrapper, so that all implementers of saveenv() don't
have to call hexport_r(), crc32() etc. sequence . This trims down a bit of
code duplication.
Signed-off-by: Marek Vasut <marex@denx.de>
---
common/env_common.c | 17 +++++++++++++++++
common/env_dataflash.c | 17 ++++++-----------
common/env_eeprom.c | 12 +++---------
common/env_fat.c | 12 +++---------
common/env_flash.c | 21 ++++++---------------
common/env_mmc.c | 12 ++----------
common/env_nand.c | 13 ++++---------
common/env_nvram.c | 12 +++---------
common/env_onenand.c | 13 ++++---------
common/env_sf.c | 24 +++++++-----------------
common/env_ubi.c | 27 ++++++++-------------------
include/environment.h | 3 +++
12 files changed, 66 insertions(+), 117 deletions(-)
diff --git a/common/env_common.c b/common/env_common.c
index c0bfc2f..fe35ff4 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -172,6 +172,23 @@ int env_import(const char *buf, int check)
return 0;
}
+/* Emport the environment and generate CRC for it. */
+int env_export(env_t *env_out)
+{
+ char *res;
+ ssize_t len;
+
+ res = (char *)env_out->data;
+ len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
+ if (len < 0) {
+ error("Cannot export environment: errno = %d\n", errno);
+ return 1;
+ }
+ env_out->crc = crc32(0, env_out->data, ENV_SIZE);
+
+ return 0;
+}
+
void env_relocate(void)
{
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
diff --git a/common/env_dataflash.c b/common/env_dataflash.c
index b53b87e..034e323 100644
--- a/common/env_dataflash.c
+++ b/common/env_dataflash.c
@@ -56,17 +56,12 @@ void env_relocate_spec(void)
int saveenv(void)
{
- env_t env_new;
- ssize_t len;
- char *res;
-
- res = (char *)&env_new.data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- return 1;
- }
- env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+ env_t env_new;
+ int ret;
+
+ ret = env_export(&env_new);
+ if (ret)
+ return ret;
return write_dataflash(CONFIG_ENV_ADDR,
(unsigned long)&env_new,
diff --git a/common/env_eeprom.c b/common/env_eeprom.c
index 0db2bb6..490ac73 100644
--- a/common/env_eeprom.c
+++ b/common/env_eeprom.c
@@ -98,8 +98,6 @@ void env_relocate_spec(void)
int saveenv(void)
{
env_t env_new;
- ssize_t len;
- char *res;
int rc;
unsigned int off = CONFIG_ENV_OFFSET;
#ifdef CONFIG_ENV_OFFSET_REDUND
@@ -109,13 +107,9 @@ int saveenv(void)
BUG_ON(env_ptr != NULL);
- res = (char *)&env_new.data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- return 1;
- }
- env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+ rc = env_export(&env_new);
+ if (rc)
+ return rc;
#ifdef CONFIG_ENV_OFFSET_REDUND
if (gd->env_valid == 1) {
diff --git a/common/env_fat.c b/common/env_fat.c
index 708fd13..aad0487 100644
--- a/common/env_fat.c
+++ b/common/env_fat.c
@@ -37,19 +37,14 @@ int env_init(void)
int saveenv(void)
{
env_t env_new;
- ssize_t len;
- char *res;
block_dev_desc_t *dev_desc = NULL;
int dev = FAT_ENV_DEVICE;
int part = FAT_ENV_PART;
int err;
- res = (char *)&env_new.data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- return 1;
- }
+ err = env_export(&env_new);
+ if (err)
+ return err;
#ifdef CONFIG_MMC
if (strcmp(FAT_ENV_INTERFACE, "mmc") == 0) {
@@ -79,7 +74,6 @@ int saveenv(void)
return 1;
}
- env_new.crc = crc32(0, env_new.data, ENV_SIZE);
err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t));
if (err == -1) {
printf("\n** Unable to write \"%s\" from %s%d:%d **\n",
diff --git a/common/env_flash.c b/common/env_flash.c
index 7d5a4cf..b3ad908 100644
--- a/common/env_flash.c
+++ b/common/env_flash.c
@@ -106,8 +106,7 @@ int env_init(void)
int saveenv(void)
{
env_t env_new;
- ssize_t len;
- char *res, *saved_data = NULL;
+ char *saved_data = NULL;
char flag = OBSOLETE_FLAG, new_flag = ACTIVE_FLAG;
int rc = 1;
#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
@@ -125,13 +124,9 @@ int saveenv(void)
if (flash_sect_protect(0, (ulong)flash_addr_new, end_addr_new))
goto done;
- res = (char *)&env_new.data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- goto done;
- }
- env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+ rc = env_export(&env_new);
+ if (rc)
+ return rc;
env_new.flags = new_flag;
#if CONFIG_ENV_SECT_SIZE > CONFIG_ENV_SIZE
@@ -258,13 +253,9 @@ int saveenv(void)
if (flash_sect_protect(0, (long)flash_addr, end_addr))
goto done;
- res = (char *)&env_new.data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
+ rc = env_export(&env_new);
+ if (rc)
goto done;
- }
- env_new.crc = crc32(0, env_new.data, ENV_SIZE);
puts("Erasing Flash...");
if (flash_sect_erase((long)flash_addr, end_addr))
diff --git a/common/env_mmc.c b/common/env_mmc.c
index 045428c..c99fc75 100644
--- a/common/env_mmc.c
+++ b/common/env_mmc.c
@@ -118,8 +118,6 @@ static unsigned char env_flags;
int saveenv(void)
{
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
- ssize_t len;
- char *res;
struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);
u32 offset;
int ret, copy = 0;
@@ -127,15 +125,9 @@ int saveenv(void)
if (init_mmc_for_env(mmc))
return 1;
- res = (char *)&env_new->data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- ret = 1;
+ ret = env_export(env_new);
+ if (ret)
goto fini;
- }
-
- env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE);
#ifdef CONFIG_ENV_OFFSET_REDUND
env_new->flags = ++env_flags; /* increase the serial */
diff --git a/common/env_nand.c b/common/env_nand.c
index 695a9ee..b94545d 100644
--- a/common/env_nand.c
+++ b/common/env_nand.c
@@ -181,8 +181,6 @@ int saveenv(void)
{
int ret = 0;
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
- ssize_t len;
- char *res;
int env_idx = 0;
static const struct env_location location[] = {
{
@@ -207,13 +205,10 @@ int saveenv(void)
if (CONFIG_ENV_RANGE < CONFIG_ENV_SIZE)
return 1;
- res = (char *)&env_new->data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- return 1;
- }
- env_new->crc = crc32(0, env_new->data, ENV_SIZE);
+ ret = env_export(&env_new);
+ if (ret)
+ return ret;
+
#ifdef CONFIG_ENV_OFFSET_REDUND
env_new->flags = ++env_flags; /* increase the serial */
env_idx = (gd->env_valid == 1);
diff --git a/common/env_nvram.c b/common/env_nvram.c
index 0866cde..524f07d 100644
--- a/common/env_nvram.c
+++ b/common/env_nvram.c
@@ -69,17 +69,11 @@ void env_relocate_spec(void)
int saveenv(void)
{
env_t env_new;
- ssize_t len;
- char *res;
int rcode = 0;
- res = (char *)&env_new.data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- return 1;
- }
- env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+ rcode = env_export(&env_new);
+ if (rcode)
+ return rcode;
#ifdef CONFIG_SYS_NVRAM_ACCESS_ROUTINE
nvram_write(CONFIG_ENV_ADDR, &env_new, CONFIG_ENV_SIZE);
diff --git a/common/env_onenand.c b/common/env_onenand.c
index 4b44632..cc3d670 100644
--- a/common/env_onenand.c
+++ b/common/env_onenand.c
@@ -66,8 +66,7 @@ void env_relocate_spec(void)
int saveenv(void)
{
env_t env_new;
- ssize_t len;
- char *res;
+ int ret;
struct mtd_info *mtd = &onenand_mtd;
#ifdef CONFIG_ENV_ADDR_FLEX
struct onenand_chip *this = &onenand_chip;
@@ -78,13 +77,9 @@ int saveenv(void)
.callback = NULL,
};
- res = (char *)&env_new.data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- return 1;
- }
- env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+ ret = env_export(&env_new);
+ if (ret)
+ return ret;
instr.len = CONFIG_ENV_SIZE;
#ifdef CONFIG_ENV_ADDR_FLEX
diff --git a/common/env_sf.c b/common/env_sf.c
index 9f806fb..3395684 100644
--- a/common/env_sf.c
+++ b/common/env_sf.c
@@ -47,8 +47,7 @@ static struct spi_flash *env_flash;
int saveenv(void)
{
env_t env_new;
- ssize_t len;
- char *res, *saved_buffer = NULL, flag = OBSOLETE_FLAG;
+ char *saved_buffer = NULL, flag = OBSOLETE_FLAG;
u32 saved_size, saved_offset, sector = 1;
int ret;
@@ -62,13 +61,9 @@ int saveenv(void)
}
}
- res = (char *)&env_new.data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- return 1;
- }
- env_new.crc = crc32(0, env_new.data, ENV_SIZE);
+ ret = env_export(&env_new);
+ if (ret)
+ return ret;
env_new.flags = ACTIVE_FLAG;
if (gd->env_valid == 1) {
@@ -225,10 +220,9 @@ out:
int saveenv(void)
{
u32 saved_size, saved_offset, sector = 1;
- char *res, *saved_buffer = NULL;
+ char *saved_buffer = NULL;
int ret = 1;
env_t env_new;
- ssize_t len;
if (!env_flash) {
env_flash = spi_flash_probe(CONFIG_ENV_SPI_BUS,
@@ -260,13 +254,9 @@ int saveenv(void)
sector++;
}
- res = (char *)&env_new.data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
+ ret = env_export(&env_new);
+ if (ret)
goto done;
- }
- env_new.crc = crc32(0, env_new.data, ENV_SIZE);
puts("Erasing SPI flash...");
ret = spi_flash_erase(env_flash, CONFIG_ENV_OFFSET,
diff --git a/common/env_ubi.c b/common/env_ubi.c
index c0828a4..77bbfa6 100644
--- a/common/env_ubi.c
+++ b/common/env_ubi.c
@@ -37,15 +37,11 @@ static unsigned char env_flags;
int saveenv(void)
{
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
- ssize_t len;
- char *res;
+ int ret;
- res = (char *)&env_new->data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- return 1;
- }
+ ret = env_export(env_new);
+ if (ret)
+ return ret;
if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
printf("\n** Cannot find mtd partition \"%s\"\n",
@@ -53,7 +49,6 @@ int saveenv(void)
return 1;
}
- env_new->crc = crc32(0, env_new->data, ENV_SIZE);
env_new->flags = ++env_flags; /* increase the serial */
if (gd->env_valid == 1) {
@@ -86,15 +81,11 @@ int saveenv(void)
int saveenv(void)
{
ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1);
- ssize_t len;
- char *res;
+ int ret;
- res = (char *)&env_new->data;
- len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
- if (len < 0) {
- error("Cannot export environment: errno = %d\n", errno);
- return 1;
- }
+ ret = env_export(env_new);
+ if (ret)
+ return ret;
if (ubi_part(CONFIG_ENV_UBI_PART, NULL)) {
printf("\n** Cannot find mtd partition \"%s\"\n",
@@ -102,8 +93,6 @@ int saveenv(void)
return 1;
}
- env_new->crc = crc32(0, env_new->data, ENV_SIZE);
-
if (ubi_volume_write(CONFIG_ENV_UBI_VOLUME, (void *)env_new,
CONFIG_ENV_SIZE)) {
printf("\n** Unable to write env to %s:%s **\n",
diff --git a/include/environment.h b/include/environment.h
index 46a3554..f797595 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -201,6 +201,9 @@ int set_default_vars(int nvars, char * const vars[]);
/* Import from binary representation into hash table */
int env_import(const char *buf, int check);
+/* Export from hash table into binary representation */
+int env_export(env_t *env_out);
+
#endif /* DO_DEPS_ONLY */
#endif /* _ENVIRONMENT_H_ */
--
1.8.5.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [U-Boot] [PATCH 2/3] env: Implement support for encrypting environment
2014-02-06 3:45 [U-Boot] [PATCH 1/3] env: Add env_export() wrapper Marek Vasut
@ 2014-02-06 3:45 ` Marek Vasut
2014-02-06 3:45 ` [U-Boot] [PATCH 3/3] env: Implement support for AES encryption into fw_* tools Marek Vasut
1 sibling, 0 replies; 6+ messages in thread
From: Marek Vasut @ 2014-02-06 3:45 UTC (permalink / raw)
To: u-boot
Add function which allows encrypting the whole environment block with
AES-128-CBC. The key for the environment is retrieved by env_aes_cbc_get_key()
function, which must be implemented on a per-board basis.
Signed-off-by: Marek Vasut <marex@denx.de>
---
common/env_common.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++
include/environment.h | 12 +++++++++-
2 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/common/env_common.c b/common/env_common.c
index fe35ff4..cd7b4cd 100644
--- a/common/env_common.c
+++ b/common/env_common.c
@@ -140,6 +140,52 @@ int set_default_vars(int nvars, char * const vars[])
H_NOCLEAR | H_INTERACTIVE, nvars, vars);
}
+#ifdef CONFIG_ENV_AES
+#include <aes.h>
+/**
+ * env_aes_cbc_get_key() - Get AES-128-CBC key for the environment
+ *
+ * This function shall return 16-byte array containing AES-128 key used
+ * to encrypt and decrypt the environment. This function must be overriden
+ * by the implementer as otherwise the environment encryption will not
+ * work.
+ */
+__weak uint8_t *env_aes_cbc_get_key(void)
+{
+ return NULL;
+}
+
+static int env_aes_cbc_crypt(env_t *env, const int enc)
+{
+ unsigned char *data = env->data;
+ uint8_t *key;
+ uint8_t key_exp[AES_EXPAND_KEY_LENGTH];
+ uint32_t aes_blocks;
+
+ key = env_aes_cbc_get_key();
+ if (!key)
+ return -EINVAL;
+
+ /* First we expand the key. */
+ aes_expand_key(key, key_exp);
+
+ /* Calculate the number of AES blocks to encrypt. */
+ aes_blocks = ENV_SIZE / AES_KEY_LENGTH;
+
+ if (enc)
+ aes_cbc_encrypt_blocks(key_exp, data, data, aes_blocks);
+ else
+ aes_cbc_decrypt_blocks(key_exp, data, data, aes_blocks);
+
+ return 0;
+}
+#else
+static inline int env_aes_cbc_crypt(env_t *env, const int enc)
+{
+ return 0;
+}
+#endif
+
/*
* Check if CRC is valid and (if yes) import the environment.
* Note that "buf" may or may not be aligned.
@@ -147,6 +193,7 @@ int set_default_vars(int nvars, char * const vars[])
int env_import(const char *buf, int check)
{
env_t *ep = (env_t *)buf;
+ int ret;
if (check) {
uint32_t crc;
@@ -159,6 +206,14 @@ int env_import(const char *buf, int check)
}
}
+ /* Decrypt the env if desired. */
+ ret = env_aes_cbc_crypt(ep, 0);
+ if (ret) {
+ error("Failed to decrypt env!\n");
+ set_default_env("!import failed");
+ return ret;
+ }
+
if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0,
0, NULL)) {
gd->flags |= GD_FLG_ENV_READY;
@@ -177,6 +232,7 @@ int env_export(env_t *env_out)
{
char *res;
ssize_t len;
+ int ret;
res = (char *)env_out->data;
len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);
@@ -184,6 +240,12 @@ int env_export(env_t *env_out)
error("Cannot export environment: errno = %d\n", errno);
return 1;
}
+
+ /* Encrypt the env if desired. */
+ ret = env_aes_cbc_crypt(env_out, 1);
+ if (ret)
+ return ret;
+
env_out->crc = crc32(0, env_out->data, ENV_SIZE);
return 0;
diff --git a/include/environment.h b/include/environment.h
index f797595..08679ae 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -146,7 +146,12 @@ extern unsigned long nand_env_oob_offset;
extern char *env_name_spec;
#endif
+#ifdef CONFIG_ENV_AES
+/* Make sure the payload is multiple of AES block size */
+#define ENV_SIZE ((CONFIG_ENV_SIZE - ENV_HEADER_SIZE) & ~(16 - 1))
+#else
#define ENV_SIZE (CONFIG_ENV_SIZE - ENV_HEADER_SIZE)
+#endif
typedef struct environment_s {
uint32_t crc; /* CRC32 over data bytes */
@@ -154,7 +159,12 @@ typedef struct environment_s {
unsigned char flags; /* active/obsolete flags */
#endif
unsigned char data[ENV_SIZE]; /* Environment data */
-} env_t;
+} env_t
+#ifdef CONFIG_ENV_AES
+/* Make sure the env is aligned to block size. */
+__attribute__((aligned(16)))
+#endif
+;
#ifdef ENV_IS_EMBEDDED
extern env_t environment;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [U-Boot] [PATCH 3/3] env: Implement support for AES encryption into fw_* tools
2014-02-06 3:45 [U-Boot] [PATCH 1/3] env: Add env_export() wrapper Marek Vasut
2014-02-06 3:45 ` [U-Boot] [PATCH 2/3] env: Implement support for encrypting environment Marek Vasut
@ 2014-02-06 3:45 ` Marek Vasut
2014-02-06 12:16 ` Wolfgang Denk
1 sibling, 1 reply; 6+ messages in thread
From: Marek Vasut @ 2014-02-06 3:45 UTC (permalink / raw)
To: u-boot
Implement support for encrypting/decrypting the environment block
into the tools/env/fw_* tools. The cipher used is AES 128 CBC and
the implementation depends solely on components internal to U-Boot.
To allow building against the internal AES library, the library did
need minor adjustments to not include U-Boot's headers which are not
wanted to be included and define missing types.
Signed-off-by: Marek Vasut <marex@denx.de>
---
include/aes.h | 7 +++
lib/aes.c | 4 ++
tools/env/Makefile | 1 +
tools/env/fw_env.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++-
tools/env/fw_env_main.c | 17 +++++--
5 files changed, 151 insertions(+), 7 deletions(-)
diff --git a/include/aes.h b/include/aes.h
index 4897e6f..891d833 100644
--- a/include/aes.h
+++ b/include/aes.h
@@ -8,6 +8,13 @@
#ifndef _AES_REF_H_
#define _AES_REF_H_
+#ifdef USE_HOSTCC
+/* Define compat stuff for use in fw_* tools. */
+typedef unsigned char u8;
+typedef unsigned int u32;
+#define debug(...) do {} while(0)
+#endif
+
/*
* AES encryption library, with small code size, supporting only 128-bit AES
*
diff --git a/lib/aes.c b/lib/aes.c
index 8b23e10..aec2afa 100644
--- a/lib/aes.c
+++ b/lib/aes.c
@@ -22,7 +22,11 @@
* REDISTRIBUTION OF THIS SOFTWARE.
*/
+#ifndef USE_HOSTCC
#include <common.h>
+#else
+#include <string.h>
+#endif
#include "aes.h"
/* forward s-box */
diff --git a/tools/env/Makefile b/tools/env/Makefile
index 27892f7..ae19200 100644
--- a/tools/env/Makefile
+++ b/tools/env/Makefile
@@ -10,6 +10,7 @@ include $(TOPDIR)/config.mk
HOSTSRCS := $(SRCTREE)/lib/crc32.c fw_env.c fw_env_main.c
HOSTSRCS += $(SRCTREE)/lib/ctype.c $(SRCTREE)/lib/linux_string.c
HOSTSRCS += $(SRCTREE)/common/env_attr.c $(SRCTREE)/common/env_flags.c
+HOSTSRCS += $(SRCTREE)/lib/aes.c
HEADERS := fw_env.h $(OBJTREE)/include/config.h
# Compile for a hosted environment on the target
diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c
index 577ce2d..807ec1b 100644
--- a/tools/env/fw_env.c
+++ b/tools/env/fw_env.c
@@ -31,6 +31,10 @@
#include "fw_env.h"
+#include <aes.h>
+
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
#define WHITESPACE(c) ((c == '\t') || (c == ' '))
#define min(x, y) ({ \
@@ -98,6 +102,11 @@ static struct environment environment = {
.flag_scheme = FLAG_NONE,
};
+/* Is AES encryption used? */
+static int aes_flag = 0;
+static uint8_t aes_key[AES_KEY_LENGTH] = {0};
+static int env_aes_cbc_crypt(char *data, const int enc);
+
static int HaveRedundEnv = 0;
static unsigned char active_flag = 1;
@@ -120,6 +129,10 @@ static inline ulong getenvsize (void)
if (HaveRedundEnv)
rc -= sizeof (char);
+
+ if (aes_flag)
+ rc &= ~(AES_KEY_LENGTH - 1);
+
return rc;
}
@@ -191,6 +204,36 @@ char *fw_getdefenv(char *name)
return NULL;
}
+static int parse_aes_key(char *key)
+{
+ char tmp[5] = { '0', 'x', 0, 0, 0 };
+ unsigned long ul;
+ int i;
+
+ if (strnlen(key, 64) != 32) {
+ fprintf (stderr, "## Error: "
+ "`-a' option requires 16-byte AES key\n");
+ return -1;
+ }
+
+ for (i = 0; i < 16; i++) {
+ tmp[2] = key[0];
+ tmp[3] = key[1];
+ errno = 0;
+ ul = strtoul(tmp, NULL, 16);
+ if (errno) {
+ fprintf (stderr, "## Error: "
+ "`-a' option requires valid AES key\n");
+ return -1;
+ }
+ aes_key[i] = ul & 0xff;
+ key += 2;
+ }
+ aes_flag = 1;
+
+ return 0;
+}
+
/*
* Print the current definition of one, or more, or all
* environment variables
@@ -201,6 +244,19 @@ int fw_printenv (int argc, char *argv[])
int i, n_flag;
int rc = 0;
+ if (argc >= 2 && strcmp (argv[1], "-a") == 0) {
+ if (argc < 3) {
+ fprintf (stderr, "## Error: "
+ "`-a' option requires AES key\n");
+ return -1;
+ }
+ rc = parse_aes_key(argv[2]);
+ if (rc)
+ return rc;
+ argv += 2;
+ argc -= 2;
+ }
+
if (fw_env_open())
return -1;
@@ -266,6 +322,16 @@ int fw_printenv (int argc, char *argv[])
int fw_env_close(void)
{
+ int ret;
+ if (aes_flag) {
+ ret = env_aes_cbc_crypt(environment.data, 1);
+ if (ret) {
+ fprintf(stderr,
+ "Error: can't encrypt env for flash\n");
+ return ret;
+ }
+ }
+
/*
* Update CRC
*/
@@ -413,7 +479,7 @@ int fw_env_write(char *name, char *value)
*/
int fw_setenv(int argc, char *argv[])
{
- int i;
+ int i, rc;
size_t len;
char *name;
char *value = NULL;
@@ -423,6 +489,24 @@ int fw_setenv(int argc, char *argv[])
return -1;
}
+ if (strcmp (argv[1], "-a") == 0) {
+ if (argc < 3) {
+ fprintf (stderr, "## Error: "
+ "`-a' option requires AES key\n");
+ return -1;
+ }
+ rc = parse_aes_key(argv[2]);
+ if (rc)
+ return rc;
+ argv += 2;
+ argc -= 2;
+ }
+
+ if (argc < 2) {
+ errno = EINVAL;
+ return -1;
+ }
+
if (fw_env_open()) {
fprintf(stderr, "Error: environment not initialized\n");
return -1;
@@ -900,6 +984,28 @@ static int flash_flag_obsolete (int dev, int fd, off_t offset)
return rc;
}
+/* Encrypt or decrypt the environment before writing or reading it. */
+static int env_aes_cbc_crypt(char *payload, const int enc)
+{
+ uint8_t *data = (uint8_t *)payload;
+ const int len = getenvsize();
+ uint8_t key_exp[AES_EXPAND_KEY_LENGTH];
+ uint32_t aes_blocks;
+
+ /* First we expand the key. */
+ aes_expand_key(aes_key, key_exp);
+
+ /* Calculate the number of AES blocks to encrypt. */
+ aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH);
+
+ if (enc)
+ aes_cbc_encrypt_blocks(key_exp, data, data, aes_blocks);
+ else
+ aes_cbc_decrypt_blocks(key_exp, data, data, aes_blocks);
+
+ return 0;
+}
+
static int flash_write (int fd_current, int fd_target, int dev_target)
{
int rc;
@@ -923,6 +1029,7 @@ static int flash_write (int fd_current, int fd_target, int dev_target)
fprintf(stderr, "Writing new environment@0x%lx on %s\n",
DEVOFFSET (dev_target), DEVNAME (dev_target));
#endif
+
rc = flash_write_buf(dev_target, fd_target, environment.image,
CUR_ENVSIZE, DEVOFFSET(dev_target),
DEVTYPE(dev_target));
@@ -981,8 +1088,10 @@ static int flash_read (int fd)
rc = flash_read_buf(dev_current, fd, environment.image, CUR_ENVSIZE,
DEVOFFSET (dev_current), mtdinfo.type);
+ if (rc != CUR_ENVSIZE)
+ return -1;
- return (rc != CUR_ENVSIZE) ? -1 : 0;
+ return 0;
}
static int flash_io (int mode)
@@ -1075,6 +1184,8 @@ int fw_env_open(void)
unsigned char flag1;
void *addr1;
+ int ret;
+
struct env_image_single *single;
struct env_image_redundant *redundant;
@@ -1109,6 +1220,13 @@ int fw_env_open(void)
return -1;
crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE);
+
+ if (aes_flag) {
+ ret = env_aes_cbc_crypt(environment.data, 0);
+ if (ret)
+ return ret;
+ }
+
crc0_ok = (crc0 == *environment.crc);
if (!HaveRedundEnv) {
if (!crc0_ok) {
@@ -1159,6 +1277,13 @@ int fw_env_open(void)
}
crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE);
+
+ if (aes_flag) {
+ ret = env_aes_cbc_crypt(redundant->data, 0);
+ if (ret)
+ return ret;
+ }
+
crc1_ok = (crc1 == redundant->crc);
flag1 = redundant->flags;
diff --git a/tools/env/fw_env_main.c b/tools/env/fw_env_main.c
index 2b85d78..ce50d58 100644
--- a/tools/env/fw_env_main.c
+++ b/tools/env/fw_env_main.c
@@ -9,18 +9,22 @@
* Command line user interface to firmware (=U-Boot) environment.
*
* Implements:
- * fw_printenv [[ -n name ] | [ name ... ]]
+ * fw_printenv [ -a key ] [[ -n name ] | [ name ... ]]
* - prints the value of a single environment variable
* "name", the ``name=value'' pairs of one or more
* environment variables "name", or the whole
* environment if no names are specified.
- * fw_setenv name [ value ... ]
+ * fw_setenv [ -a key ] name [ value ... ]
* - If a name without any values is given, the variable
* with this name is deleted from the environment;
* otherwise, all "value" arguments are concatenated,
* separated by single blank characters, and the
* resulting string is assigned to the environment
* variable "name"
+ *
+ * If '-a key' is specified, the env block is encrypted with AES 128 CBC.
+ * The 'key' argument is in the format of 32 hexadecimal numbers (16 bytes
+ * of AES key), eg. '-a aabbccddeeff00112233445566778899'.
*/
#include <fcntl.h>
@@ -46,8 +50,8 @@ void usage(void)
fprintf(stderr, "fw_printenv/fw_setenv, "
"a command line interface to U-Boot environment\n\n"
- "usage:\tfw_printenv [-n] [variable name]\n"
- "\tfw_setenv [variable name] [variable value]\n"
+ "usage:\tfw_printenv [-a key] [-n] [variable name]\n"
+ "\tfw_setenv [-a key] [variable name] [variable value]\n"
"\tfw_setenv -s [ file ]\n"
"\tfw_setenv -s - < [ file ]\n\n"
"The file passed as argument contains only pairs "
@@ -94,9 +98,12 @@ int main(int argc, char *argv[])
cmdname = p + 1;
}
- while ((c = getopt_long (argc, argv, "ns:h",
+ while ((c = getopt_long (argc, argv, "a:ns:h",
long_options, NULL)) != EOF) {
switch (c) {
+ case 'a':
+ /* AES key, handled later */
+ break;
case 'n':
/* handled in fw_printenv */
break;
--
1.8.5.3
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [U-Boot] [PATCH 3/3] env: Implement support for AES encryption into fw_* tools
2014-02-06 3:45 ` [U-Boot] [PATCH 3/3] env: Implement support for AES encryption into fw_* tools Marek Vasut
@ 2014-02-06 12:16 ` Wolfgang Denk
2014-02-06 19:41 ` Marek Vasut
0 siblings, 1 reply; 6+ messages in thread
From: Wolfgang Denk @ 2014-02-06 12:16 UTC (permalink / raw)
To: u-boot
Dear Marek Vasut,
In message <1391658352-24754-3-git-send-email-marex@denx.de> you wrote:
> Implement support for encrypting/decrypting the environment block
> into the tools/env/fw_* tools. The cipher used is AES 128 CBC and
> the implementation depends solely on components internal to U-Boot.
...
> +#ifdef USE_HOSTCC
> +/* Define compat stuff for use in fw_* tools. */
> +typedef unsigned char u8;
> +typedef unsigned int u32;
> +#define debug(...) do {} while(0)
If we need this for the host environment, then you should provide a
useful implementation (output to STDERR).
Also, this is causing checkpatch warnings: space required before the
open parenthesis '('
> --- a/tools/env/fw_env.c
> +++ b/tools/env/fw_env.c
...
> +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
Checkpatch says: space required after that ',' (ctx:VxV)
> +static int aes_flag = 0;
ERROR: do not initialise statics to 0 or NULL
> + fprintf (stderr, "## Error: "
> + "`-a' option requires valid AES key\n");
WARNING: space prohibited between function name and open parenthesis '('
More checkpatch issues suppressed. Please fix all of these!
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
A fanatic is a person who can't change his mind and won't change the
subject. - Winston Churchill
^ permalink raw reply [flat|nested] 6+ messages in thread
* [U-Boot] [PATCH 3/3] env: Implement support for AES encryption into fw_* tools
2014-02-06 12:16 ` Wolfgang Denk
@ 2014-02-06 19:41 ` Marek Vasut
2014-02-06 20:26 ` Wolfgang Denk
0 siblings, 1 reply; 6+ messages in thread
From: Marek Vasut @ 2014-02-06 19:41 UTC (permalink / raw)
To: u-boot
On Thursday, February 06, 2014 at 01:16:31 PM, Wolfgang Denk wrote:
[...]
All input considered, thanks! I have but a quick question -- why does the fw_*
tools source look _so_ bad ? Don't you think it needs quite some cleanup ? What
do you think please?
Best regards,
Marek Vasut
^ permalink raw reply [flat|nested] 6+ messages in thread
* [U-Boot] [PATCH 3/3] env: Implement support for AES encryption into fw_* tools
2014-02-06 19:41 ` Marek Vasut
@ 2014-02-06 20:26 ` Wolfgang Denk
0 siblings, 0 replies; 6+ messages in thread
From: Wolfgang Denk @ 2014-02-06 20:26 UTC (permalink / raw)
To: u-boot
Dear Marek,
In message <201402062041.23537.marex@denx.de> you wrote:
>
> [...]
>
> All input considered, thanks! I have but a quick question -- why does the fw_*
> tools source look _so_ bad ? ...
Because it was written more than a decade ago, when rules were not as
strict yet, and personal preferences took hold?
> ... Don't you think it needs quite some cleanup ? What
> do you think please?
Cleanup patches are always welcome...
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
A list is only as strong as its weakest link. -- Don Knuth
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-02-06 20:26 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-02-06 3:45 [U-Boot] [PATCH 1/3] env: Add env_export() wrapper Marek Vasut
2014-02-06 3:45 ` [U-Boot] [PATCH 2/3] env: Implement support for encrypting environment Marek Vasut
2014-02-06 3:45 ` [U-Boot] [PATCH 3/3] env: Implement support for AES encryption into fw_* tools Marek Vasut
2014-02-06 12:16 ` Wolfgang Denk
2014-02-06 19:41 ` Marek Vasut
2014-02-06 20:26 ` Wolfgang Denk
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox