* SPDX-License-Identifier: GPL-2.0+
*/
+#define _GNU_SOURCE
+
+#include <compiler.h>
#include <errno.h>
#include <env_flags.h>
#include <fcntl.h>
#include <linux/stringify.h>
+#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include "fw_env.h"
-#include <aes.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 WHITESPACE(c) ((c == '\t') || (c == ' '))
-
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
.flag_scheme = FLAG_NONE,
};
-/* Is AES encryption used? */
-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 HaveRedundEnv = 0;
#endif
static inline ulong getenvsize (void)
{
- ulong rc = CUR_ENVSIZE - sizeof(long);
+ ulong rc = CUR_ENVSIZE - sizeof(uint32_t);
if (HaveRedundEnv)
rc -= sizeof (char);
- if (aes_flag)
+ if (common_args.aes_flag)
rc &= ~(AES_KEY_LENGTH - 1);
return rc;
}
-static char *fw_string_blank(char *s, int noblank)
+static char *skip_chars(char *s)
{
- int i;
- int len = strlen(s);
-
- for (i = 0; i < len; i++, s++) {
- if ((noblank && !WHITESPACE(*s)) ||
- (!noblank && WHITESPACE(*s)))
- break;
+ for (; *s != '\0'; s++) {
+ if (isblank(*s))
+ return s;
}
- if (i == len)
- return NULL;
+ return NULL;
+}
- return s;
+static char *skip_blanks(char *s)
+{
+ for (; *s != '\0'; s++) {
+ if (!isblank(*s))
+ return s;
+ }
+ return NULL;
}
/*
return NULL;
}
-static int parse_aes_key(char *key)
+int parse_aes_key(char *key, uint8_t *bin_key)
{
char tmp[5] = { '0', 'x', 0, 0, 0 };
unsigned long ul;
"## Error: '-a' option requires valid AES key\n");
return -1;
}
- aes_key[i] = ul & 0xff;
+ bin_key[i] = ul & 0xff;
key += 2;
}
- aes_flag = 1;
-
return 0;
}
int fw_printenv (int argc, char *argv[])
{
char *env, *nxt;
- 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;
- }
+ int i, rc = 0;
if (fw_env_open())
return -1;
- if (argc == 1) { /* Print all env variables */
+ if (argc == 0) { /* Print all env variables */
for (env = environment.data; *env; env = nxt + 1) {
for (nxt = env; *nxt; ++nxt) {
if (nxt >= &environment.data[ENV_SIZE]) {
return 0;
}
- if (strcmp (argv[1], "-n") == 0) {
- n_flag = 1;
- ++argv;
- --argc;
- if (argc != 2) {
- fprintf (stderr, "## Error: "
- "`-n' option requires exactly one argument\n");
- return -1;
- }
- } else {
- n_flag = 0;
+ if (printenv_args.name_suppress && argc != 1) {
+ fprintf(stderr,
+ "## Error: `-n' option requires exactly one argument\n");
+ return -1;
}
- for (i = 1; i < argc; ++i) { /* print single env variables */
+ for (i = 0; i < argc; ++i) { /* print single env variables */
char *name = argv[i];
char *val = NULL;
}
val = envmatch (name, env);
if (val) {
- if (!n_flag) {
+ if (!printenv_args.name_suppress) {
fputs (name, stdout);
putc ('=', stdout);
}
int fw_env_close(void)
{
int ret;
- if (aes_flag) {
+ if (common_args.aes_flag) {
ret = env_aes_cbc_crypt(environment.data, 1);
if (ret) {
fprintf(stderr,
*/
int fw_setenv(int argc, char *argv[])
{
- int i, rc;
+ int i;
size_t len;
- char *name;
+ char *name, **valv;
char *value = NULL;
+ int valc;
- if (argc < 2) {
- errno = EINVAL;
- 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) {
+ if (argc < 1) {
+ fprintf(stderr, "## Error: variable name missing\n");
errno = EINVAL;
return -1;
}
return -1;
}
- name = argv[1];
+ name = argv[0];
+ valv = argv + 1;
+ valc = argc - 1;
- if (env_flags_validate_env_set_params(argc, argv) < 0)
+ if (env_flags_validate_env_set_params(name, valv, valc) < 0)
return 1;
len = 0;
- for (i = 2; i < argc; ++i) {
- char *val = argv[i];
+ for (i = 0; i < valc; ++i) {
+ char *val = valv[i];
size_t val_len = strlen(val);
if (value)
}
/* Drop ending line feed / carriage return */
- while (len > 0 && (dump[len - 1] == '\n' ||
- dump[len - 1] == '\r')) {
- dump[len - 1] = '\0';
- len--;
- }
+ dump[--len] = '\0';
+ if (len && dump[len - 1] == '\r')
+ dump[--len] = '\0';
/* Skip comment or empty lines */
- if ((len == 0) || dump[0] == '#')
+ if (len == 0 || dump[0] == '#')
continue;
/*
* Search for variable's name,
* remove leading whitespaces
*/
- name = fw_string_blank(dump, 1);
+ name = skip_blanks(dump);
if (!name)
continue;
/* The first white space is the end of variable name */
- val = fw_string_blank(name, 0);
+ val = skip_chars(name);
len = strlen(name);
if (val) {
*val++ = '\0';
if ((val - name) < len)
- val = fw_string_blank(val, 1);
+ val = skip_blanks(val);
else
val = NULL;
}
uint32_t aes_blocks;
/* First we expand the key. */
- aes_expand_key(aes_key, key_exp);
+ aes_expand_key(common_args.aes_key, key_exp);
/* Calculate the number of AES blocks to encrypt. */
aes_blocks = DIV_ROUND_UP(len, AES_KEY_LENGTH);
crc0 = crc32 (0, (uint8_t *) environment.data, ENV_SIZE);
- if (aes_flag) {
+ if (common_args.aes_flag) {
ret = env_aes_cbc_crypt(environment.data, 0);
if (ret)
return ret;
crc1 = crc32 (0, (uint8_t *) redundant->data, ENV_SIZE);
- if (aes_flag) {
+ if (common_args.aes_flag) {
ret = env_aes_cbc_crypt(redundant->data, 0);
if (ret)
return ret;
#if defined(CONFIG_FILE)
/* Fills in DEVNAME(), ENVSIZE(), DEVESIZE(). Or don't. */
- if (get_config (CONFIG_FILE)) {
- fprintf (stderr,
- "Cannot parse config file: %s\n", strerror (errno));
+ if (get_config(common_args.config_file)) {
+ fprintf(stderr, "Cannot parse config file '%s': %m\n",
+ common_args.config_file);
return -1;
}
#else