From dcdc1f6a9bd8abaa41b5eacd9310787cf96f4c4e Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 19 Apr 2016 22:43:39 +0200 Subject: tools/env: pass key as argument to env_aes_cbc_crypt Signed-off-by: Andreas Fenkart --- tools/env/fw_env.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'tools/env') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 06cf63daa4e..0c448079cc3 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -106,7 +106,7 @@ static struct environment environment = { .flag_scheme = FLAG_NONE, }; -static int env_aes_cbc_crypt(char *data, const int enc); +static int env_aes_cbc_crypt(char *data, const int enc, uint8_t *key); static int HaveRedundEnv = 0; @@ -304,7 +304,8 @@ int fw_env_close(void) { int ret; if (common_args.aes_flag) { - ret = env_aes_cbc_crypt(environment.data, 1); + ret = env_aes_cbc_crypt(environment.data, 1, + common_args.aes_key); if (ret) { fprintf(stderr, "Error: can't encrypt env for flash\n"); @@ -949,7 +950,7 @@ static int flash_flag_obsolete (int dev, int fd, off_t offset) } /* Encrypt or decrypt the environment before writing or reading it. */ -static int env_aes_cbc_crypt(char *payload, const int enc) +static int env_aes_cbc_crypt(char *payload, const int enc, uint8_t *key) { uint8_t *data = (uint8_t *)payload; const int len = getenvsize(); @@ -957,7 +958,7 @@ static int env_aes_cbc_crypt(char *payload, const int enc) uint32_t aes_blocks; /* First we expand the key. */ - aes_expand_key(common_args.aes_key, key_exp); + aes_expand_key(key, key_exp); /* Calculate the number of AES blocks to encrypt. */ aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH); @@ -1186,7 +1187,8 @@ int fw_env_open(void) crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE); if (common_args.aes_flag) { - ret = env_aes_cbc_crypt(environment.data, 0); + ret = env_aes_cbc_crypt(environment.data, 0, + common_args.aes_key); if (ret) return ret; } @@ -1243,7 +1245,8 @@ int fw_env_open(void) crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE); if (common_args.aes_flag) { - ret = env_aes_cbc_crypt(redundant->data, 0); + ret = env_aes_cbc_crypt(redundant->data, 0, + common_args.aes_key); if (ret) return ret; } -- cgit v1.2.3 From c3a23e8b5f7c13d9de389d25d756a7da64bc5144 Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 19 Apr 2016 22:43:40 +0200 Subject: tools/env: remove 'extern' from function prototype in fw_env.h checkpatch complains about in succeding patch. Prefer to fix all declarations in a dedicated patch. Signed-off-by: Andreas Fenkart --- tools/env/fw_env.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'tools/env') diff --git a/tools/env/fw_env.h b/tools/env/fw_env.h index 57149e733ba..7345922911f 100644 --- a/tools/env/fw_env.h +++ b/tools/env/fw_env.h @@ -78,12 +78,12 @@ extern struct setenv_args setenv_args; int parse_aes_key(char *key, uint8_t *bin_key); -extern int fw_printenv(int argc, char *argv[]); -extern char *fw_getenv (char *name); -extern int fw_setenv (int argc, char *argv[]); -extern int fw_parse_script(char *fname); -extern int fw_env_open(void); -extern int fw_env_write(char *name, char *value); -extern int fw_env_close(void); +int fw_printenv(int argc, char *argv[]); +char *fw_getenv(char *name); +int fw_setenv(int argc, char *argv[]); +int fw_parse_script(char *fname); +int fw_env_open(void); +int fw_env_write(char *name, char *value); +int fw_env_close(void); -extern unsigned long crc32 (unsigned long, const unsigned char *, unsigned); +unsigned long crc32(unsigned long, const unsigned char *, unsigned); -- cgit v1.2.3 From cedb341e7f44f4686c8c0afb149a9f7940be110a Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 19 Apr 2016 22:43:41 +0200 Subject: tools/env: fw_printenv pass value_only as argument Signed-off-by: Andreas Fenkart --- tools/env/fw_env.c | 6 +++--- tools/env/fw_env.h | 4 ++-- tools/env/fw_env_main.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools/env') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 0c448079cc3..aa394858a08 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -239,7 +239,7 @@ int parse_aes_key(char *key, uint8_t *bin_key) * Print the current definition of one, or more, or all * environment variables */ -int fw_printenv (int argc, char *argv[]) +int fw_printenv(int argc, char *argv[], int value_only) { char *env, *nxt; int i, rc = 0; @@ -262,7 +262,7 @@ int fw_printenv (int argc, char *argv[]) return 0; } - if (printenv_args.name_suppress && argc != 1) { + if (value_only && argc != 1) { fprintf(stderr, "## Error: `-n' option requires exactly one argument\n"); return -1; @@ -283,7 +283,7 @@ int fw_printenv (int argc, char *argv[]) } val = envmatch (name, env); if (val) { - if (!printenv_args.name_suppress) { + if (!value_only) { fputs (name, stdout); putc ('=', stdout); } diff --git a/tools/env/fw_env.h b/tools/env/fw_env.h index 7345922911f..d4daeeafd97 100644 --- a/tools/env/fw_env.h +++ b/tools/env/fw_env.h @@ -67,7 +67,7 @@ struct common_args { extern struct common_args common_args; struct printenv_args { - int name_suppress; + int value_only; }; extern struct printenv_args printenv_args; @@ -78,7 +78,7 @@ extern struct setenv_args setenv_args; int parse_aes_key(char *key, uint8_t *bin_key); -int fw_printenv(int argc, char *argv[]); +int fw_printenv(int argc, char *argv[], int value_only); char *fw_getenv(char *name); int fw_setenv(int argc, char *argv[]); int fw_parse_script(char *fname); diff --git a/tools/env/fw_env_main.c b/tools/env/fw_env_main.c index 3706d8f1a61..2a45a0de287 100644 --- a/tools/env/fw_env_main.c +++ b/tools/env/fw_env_main.c @@ -151,7 +151,7 @@ int parse_printenv_args(int argc, char *argv[]) EOF) { switch (c) { case 'n': - printenv_args.name_suppress = 1; + printenv_args.value_only = 1; break; case 'a': case 'c': @@ -240,7 +240,7 @@ int main(int argc, char *argv[]) } if (do_printenv) { - if (fw_printenv(argc, argv) != 0) + if (fw_printenv(argc, argv, printenv_args.value_only)) retval = EXIT_FAILURE; } else { if (!setenv_args.script_file) { -- cgit v1.2.3 From f71cee4bfc9a8f9be40a49ec2da84f4344e398fc Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 19 Apr 2016 22:43:42 +0200 Subject: tools/env: compute size of usable area only once for double buffering to work, redundant buffers must have equal size Signed-off-by: Andreas Fenkart --- tools/env/fw_env.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) (limited to 'tools/env') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index aa394858a08..1654ac0e46b 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -75,7 +75,8 @@ static int dev_current; #define CUR_ENVSIZE ENVSIZE(dev_current) -#define ENV_SIZE getenvsize() +static unsigned long usable_envsize; +#define ENV_SIZE usable_envsize struct env_image_single { uint32_t crc; /* CRC32 over data bytes */ @@ -124,18 +125,6 @@ static int parse_config (void); #if defined(CONFIG_FILE) static int get_config (char *); #endif -static inline ulong getenvsize (void) -{ - ulong rc = CUR_ENVSIZE - sizeof(uint32_t); - - if (HaveRedundEnv) - rc -= sizeof (char); - - if (common_args.aes_flag) - rc &= ~(AES_KEY_LENGTH - 1); - - return rc; -} static char *skip_chars(char *s) { @@ -953,7 +942,7 @@ static int flash_flag_obsolete (int dev, int fd, off_t offset) static int env_aes_cbc_crypt(char *payload, const int enc, uint8_t *key) { uint8_t *data = (uint8_t *)payload; - const int len = getenvsize(); + const int len = usable_envsize; uint8_t key_exp[AES_EXPAND_KEY_LENGTH]; uint32_t aes_blocks; @@ -1382,6 +1371,21 @@ static int parse_config () DEVNAME (1), strerror (errno)); return -1; } + + if (HaveRedundEnv && ENVSIZE(0) != ENVSIZE(1)) { + ENVSIZE(0) = ENVSIZE(1) = min(ENVSIZE(0), ENVSIZE(1)); + fprintf(stderr, + "Redundant environments have inequal size, set to 0x%08lx\n", + ENVSIZE(1)); + } + + usable_envsize = CUR_ENVSIZE - sizeof(uint32_t); + if (HaveRedundEnv) + usable_envsize -= sizeof(char); + + if (common_args.aes_flag) + usable_envsize &= ~(AES_KEY_LENGTH - 1); + return 0; } -- cgit v1.2.3 From 81974f4479d19c441c4a089aedd238c251626b3e Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 5 Apr 2016 23:13:42 +0200 Subject: tools/env: no global variable sharing between application and library Signed-off-by: Andreas Fenkart --- tools/env/fw_env.c | 50 +++++++++++++++++++++++-------------------------- tools/env/fw_env.h | 25 +++++++------------------ tools/env/fw_env_main.c | 28 +++++++++++++++++---------- 3 files changed, 48 insertions(+), 55 deletions(-) (limited to 'tools/env') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 1654ac0e46b..52e0bec0897 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -35,10 +35,6 @@ #include "fw_env.h" -struct common_args common_args; -struct printenv_args printenv_args; -struct setenv_args setenv_args; - #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) #define min(x, y) ({ \ @@ -120,7 +116,7 @@ static unsigned char obsolete_flag = 0; static int flash_io (int mode); static char *envmatch (char * s1, char * s2); -static int parse_config (void); +static int parse_config(struct env_opts *opts); #if defined(CONFIG_FILE) static int get_config (char *); @@ -228,12 +224,12 @@ int parse_aes_key(char *key, uint8_t *bin_key) * Print the current definition of one, or more, or all * environment variables */ -int fw_printenv(int argc, char *argv[], int value_only) +int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts) { char *env, *nxt; int i, rc = 0; - if (fw_env_open()) + if (fw_env_open(opts)) return -1; if (argc == 0) { /* Print all env variables */ @@ -289,12 +285,13 @@ int fw_printenv(int argc, char *argv[], int value_only) return rc; } -int fw_env_close(void) +int fw_env_close(struct env_opts *opts) { int ret; - if (common_args.aes_flag) { + + if (opts->aes_flag) { ret = env_aes_cbc_crypt(environment.data, 1, - common_args.aes_key); + opts->aes_key); if (ret) { fprintf(stderr, "Error: can't encrypt env for flash\n"); @@ -447,7 +444,7 @@ int fw_env_write(char *name, char *value) * modified or deleted * */ -int fw_setenv(int argc, char *argv[]) +int fw_setenv(int argc, char *argv[], struct env_opts *opts) { int i; size_t len; @@ -461,7 +458,7 @@ int fw_setenv(int argc, char *argv[]) return -1; } - if (fw_env_open()) { + if (fw_env_open(opts)) { fprintf(stderr, "Error: environment not initialized\n"); return -1; } @@ -497,7 +494,7 @@ int fw_setenv(int argc, char *argv[]) free(value); - return fw_env_close(); + return fw_env_close(opts); } /* @@ -517,7 +514,7 @@ int fw_setenv(int argc, char *argv[]) * 0 - OK * -1 - Error */ -int fw_parse_script(char *fname) +int fw_parse_script(char *fname, struct env_opts *opts) { FILE *fp; char dump[1024]; /* Maximum line length in the file */ @@ -527,7 +524,7 @@ int fw_parse_script(char *fname) int len; int ret = 0; - if (fw_env_open()) { + if (fw_env_open(opts)) { fprintf(stderr, "Error: environment not initialized\n"); return -1; } @@ -615,10 +612,9 @@ int fw_parse_script(char *fname) if (strcmp(fname, "-") != 0) fclose(fp); - ret |= fw_env_close(); + ret |= fw_env_close(opts); return ret; - } /* @@ -1128,7 +1124,7 @@ static char *envmatch (char * s1, char * s2) /* * Prevent confusion if running from erased flash memory */ -int fw_env_open(void) +int fw_env_open(struct env_opts *opts) { int crc0, crc0_ok; unsigned char flag0; @@ -1143,7 +1139,7 @@ int fw_env_open(void) struct env_image_single *single; struct env_image_redundant *redundant; - if (parse_config ()) /* should fill envdevices */ + if (parse_config(opts)) /* should fill envdevices */ return -1; addr0 = calloc(1, CUR_ENVSIZE); @@ -1175,9 +1171,9 @@ int fw_env_open(void) crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE); - if (common_args.aes_flag) { + if (opts->aes_flag) { ret = env_aes_cbc_crypt(environment.data, 0, - common_args.aes_key); + opts->aes_key); if (ret) return ret; } @@ -1233,9 +1229,9 @@ int fw_env_open(void) crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE); - if (common_args.aes_flag) { + if (opts->aes_flag) { ret = env_aes_cbc_crypt(redundant->data, 0, - common_args.aes_key); + opts->aes_key); if (ret) return ret; } @@ -1312,7 +1308,7 @@ int fw_env_open(void) } -static int parse_config () +static int parse_config(struct env_opts *opts) { struct stat st; @@ -1321,9 +1317,9 @@ static int parse_config () common_args.config_file = CONFIG_FILE; /* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */ - if (get_config(common_args.config_file)) { + if (get_config(opts->config_file)) { fprintf(stderr, "Cannot parse config file '%s': %m\n", - common_args.config_file); + opts->config_file); return -1; } #else @@ -1383,7 +1379,7 @@ static int parse_config () if (HaveRedundEnv) usable_envsize -= sizeof(char); - if (common_args.aes_flag) + if (opts->aes_flag) usable_envsize &= ~(AES_KEY_LENGTH - 1); return 0; diff --git a/tools/env/fw_env.h b/tools/env/fw_env.h index d4daeeafd97..dac964d933f 100644 --- a/tools/env/fw_env.h +++ b/tools/env/fw_env.h @@ -57,33 +57,22 @@ "bootm" #endif -struct common_args { +struct env_opts { #ifdef CONFIG_FILE char *config_file; #endif - uint8_t aes_key[AES_KEY_LENGTH]; int aes_flag; /* Is AES encryption used? */ + uint8_t aes_key[AES_KEY_LENGTH]; }; -extern struct common_args common_args; - -struct printenv_args { - int value_only; -}; -extern struct printenv_args printenv_args; - -struct setenv_args { - char *script_file; -}; -extern struct setenv_args setenv_args; int parse_aes_key(char *key, uint8_t *bin_key); -int fw_printenv(int argc, char *argv[], int value_only); +int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts); char *fw_getenv(char *name); -int fw_setenv(int argc, char *argv[]); -int fw_parse_script(char *fname); -int fw_env_open(void); +int fw_setenv(int argc, char *argv[], struct env_opts *opts); +int fw_parse_script(char *fname, struct env_opts *opts); +int fw_env_open(struct env_opts *opts); int fw_env_write(char *name, char *value); -int fw_env_close(void); +int fw_env_close(struct env_opts *opts); unsigned long crc32(unsigned long, const unsigned char *, unsigned); diff --git a/tools/env/fw_env_main.c b/tools/env/fw_env_main.c index 2a45a0de287..7a17b28f40b 100644 --- a/tools/env/fw_env_main.c +++ b/tools/env/fw_env_main.c @@ -49,6 +49,14 @@ static struct option long_options[] = { {NULL, 0, NULL, 0} }; +static struct env_opts env_opts; + +/* setenv options */ +static int noheader; + +/* getenv options */ +static char *script_file; + void usage_printenv(void) { @@ -108,22 +116,22 @@ static void parse_common_args(int argc, char *argv[]) int c; #ifdef CONFIG_FILE - common_args.config_file = CONFIG_FILE; + env_opts.config_file = CONFIG_FILE; #endif while ((c = getopt_long(argc, argv, ":a:c:h", long_options, NULL)) != EOF) { switch (c) { case 'a': - if (parse_aes_key(optarg, common_args.aes_key)) { + if (parse_aes_key(optarg, env_opts.aes_key)) { fprintf(stderr, "AES key parse error\n"); exit(EXIT_FAILURE); } - common_args.aes_flag = 1; + env_opts.aes_flag = 1; break; #ifdef CONFIG_FILE case 'c': - common_args.config_file = optarg; + env_opts.config_file = optarg; break; #endif case 'h': @@ -151,7 +159,7 @@ int parse_printenv_args(int argc, char *argv[]) EOF) { switch (c) { case 'n': - printenv_args.value_only = 1; + noheader = 1; break; case 'a': case 'c': @@ -177,7 +185,7 @@ int parse_setenv_args(int argc, char *argv[]) EOF) { switch (c) { case 's': - setenv_args.script_file = optarg; + script_file = optarg; break; case 'a': case 'c': @@ -240,14 +248,14 @@ int main(int argc, char *argv[]) } if (do_printenv) { - if (fw_printenv(argc, argv, printenv_args.value_only)) + if (fw_printenv(argc, argv, noheader, &env_opts) != 0) retval = EXIT_FAILURE; } else { - if (!setenv_args.script_file) { - if (fw_setenv(argc, argv) != 0) + if (!script_file) { + if (fw_setenv(argc, argv, &env_opts) != 0) retval = EXIT_FAILURE; } else { - if (fw_parse_script(setenv_args.script_file) != 0) + if (fw_parse_script(script_file, &env_opts) != 0) retval = EXIT_FAILURE; } } -- cgit v1.2.3 From 14070e69ad6d01abf65c06150dc9302bca1b7973 Mon Sep 17 00:00:00 2001 From: Andreas Fenkart Date: Tue, 31 May 2016 09:21:56 +0200 Subject: tools/env: allow to pass NULL for environment options If users of the library are happy with the default, e.g. config file name. They can pass NULL as the opts pointer. This simplifies the transition of existing library users. FIXES a compile error. since common_args has been removed by a previous patch Signed-off-by: Andreas Fenkart --- tools/env/fw_env.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'tools/env') diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 52e0bec0897..692abda7318 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -35,6 +35,12 @@ #include "fw_env.h" +struct env_opts default_opts = { +#ifdef CONFIG_FILE + .config_file = CONFIG_FILE +#endif +}; + #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) #define min(x, y) ({ \ @@ -229,6 +235,9 @@ int fw_printenv(int argc, char *argv[], int value_only, struct env_opts *opts) char *env, *nxt; int i, rc = 0; + if (!opts) + opts = &default_opts; + if (fw_env_open(opts)) return -1; @@ -289,6 +298,9 @@ int fw_env_close(struct env_opts *opts) { int ret; + if (!opts) + opts = &default_opts; + if (opts->aes_flag) { ret = env_aes_cbc_crypt(environment.data, 1, opts->aes_key); @@ -452,6 +464,9 @@ int fw_setenv(int argc, char *argv[], struct env_opts *opts) char *value = NULL; int valc; + if (!opts) + opts = &default_opts; + if (argc < 1) { fprintf(stderr, "## Error: variable name missing\n"); errno = EINVAL; @@ -524,6 +539,9 @@ int fw_parse_script(char *fname, struct env_opts *opts) int len; int ret = 0; + if (!opts) + opts = &default_opts; + if (fw_env_open(opts)) { fprintf(stderr, "Error: environment not initialized\n"); return -1; @@ -1139,6 +1157,9 @@ int fw_env_open(struct env_opts *opts) struct env_image_single *single; struct env_image_redundant *redundant; + if (!opts) + opts = &default_opts; + if (parse_config(opts)) /* should fill envdevices */ return -1; @@ -1312,10 +1333,10 @@ static int parse_config(struct env_opts *opts) { struct stat st; -#if defined(CONFIG_FILE) - if (!common_args.config_file) - common_args.config_file = CONFIG_FILE; + if (!opts) + opts = &default_opts; +#if defined(CONFIG_FILE) /* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */ if (get_config(opts->config_file)) { fprintf(stderr, "Cannot parse config file '%s': %m\n", -- cgit v1.2.3