env: Add env_export() wrapper
PATCH v2 1/3 env: Add env_export() wrapper
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.
--- 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(-)
V2: Fix minor bug in env_nand.c where I was passing &env_new instead of env_new
common/env_common.c +17 -0
@@ -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 )
common/env_dataflash.c +6 -11
@@ -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,
common/env_eeprom.c +3 -9
@@ -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 ) {
common/env_fat.c +3 -9
@@ -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",
common/env_flash.c +6 -15
@@ -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))
common/env_mmc.c +2 -10
@@ -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 */
common/env_nand.c +4 -9
@@ -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 );
common/env_nvram.c +3 -9
@@ -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 );
common/env_onenand.c +4 -9
@@ -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
common/env_sf.c +7 -17
@@ -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,
common/env_ubi.c +8 -19
@@ -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",
include/environment.h +3 -0
@@ -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_ */
Signature · 1 line
1.8.5.2
PATCH 2/3 env: Implement support for encrypting environment
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.
--- common/env_common.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/environment.h | 12 +++++++++- 2 files changed, 73 insertions(+), 1 deletion(-)
NOTE: We have one style issue here, but we must keep using
__attribute__((aligned(16))) here as we're including this include/environment.h from tools as well.
common/env_common.c +62 -0
@@ -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 ;
include/environment.h +11 -1
@@ -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;
Signature · 1 line
1.8.5.2
PATCH 2/3 env: Implement support for encrypting environment
Quoted 5 lines · Marek Vasut
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 <[email protected]>
Applied to u-boot/next (with a reword to rewrap), thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140327/33e6de01/attachment.pgp>
PATCH v2 3/3 env: Implement support for AES encryption into fw_* tools
In reply to Marek VasutImplement 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.
--- include/aes.h | 7 +++ lib/aes.c | 4 ++ tools/env/Makefile | 2 +- tools/env/fw_env.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++- tools/env/fw_env_main.c | 17 +++++-- 5 files changed, 151 insertions(+), 8 deletions(-)
V2: Checkpatch cleanup
include/aes.h +7 -0
@@ -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 *
lib/aes.c +4 -0
@@ -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 */
tools/env/Makefile +1 -1
@@ -25,7 +25,7 @@ hostprogs-y := fw_printenv_unstripped fw_printenv_unstripped-objs := fw_env.o fw_env_main.o \ crc32.o ctype.o linux_string.o \ - env_attr.o env_flags.o + env_attr.o env_flags.o aes.o quiet_cmd_strip = STRIP $@ cmd_strip = $(STRIP) -o $@ $<
tools/env/fw_env.c +127 -2
214 lines not on this page · raw message
tools/env/fw_env_main.c +12 -5
@@ -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 ;
Signature · 1 line
1.8.5.2
PATCH v2 3/3 env: Implement support for AES encryption into fw_* tools
Quoted 9 lines · Marek Vasut
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 <[email protected]>
Applied to u-boot/next, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140327/52a66857/attachment.pgp>
PATCH v2 1/3 env: Add env_export() wrapper
In reply to Marek VasutQuoted 5 lines · Marek Vasut
Implement
env_export()wrapper, so that all implementers ofsaveenv()don't have to callhexport_r(),crc32()etc. sequence . This trims down a bit of code duplication.Signed-off-by Marek Vasut <[email protected]>
Applied to u-boot/next, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20140327/8640c49b/attachment.pgp>