1 /* 2 * (C) Copyright 2000-2010 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 4 * 5 * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> 6 * Andreas Heppel <aheppel@sysgo.de> 7 * 8 * SPDX-License-Identifier: GPL-2.0+ 9 */ 10 11 #include <common.h> 12 #include <command.h> 13 #include <environment.h> 14 #include <linux/stddef.h> 15 #include <search.h> 16 #include <errno.h> 17 #include <malloc.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 21 /************************************************************************ 22 * Default settings to be used when no valid environment is found 23 */ 24 #include <env_default.h> 25 26 struct hsearch_data env_htab = { 27 .change_ok = env_flags_validate, 28 }; 29 30 /* 31 * Read an environment variable as a boolean 32 * Return -1 if variable does not exist (default to true) 33 */ 34 int env_get_yesno(const char *var) 35 { 36 char *s = env_get(var); 37 38 if (s == NULL) 39 return -1; 40 return (*s == '1' || *s == 'y' || *s == 'Y' || *s == 't' || *s == 'T') ? 41 1 : 0; 42 } 43 44 __weak void board_env_fixup(void) {} 45 46 /* 47 * Look up the variable from the default environment 48 */ 49 char *env_get_default(const char *name) 50 { 51 char *ret_val; 52 unsigned long really_valid = gd->env_valid; 53 unsigned long real_gd_flags = gd->flags; 54 55 /* Pretend that the image is bad. */ 56 gd->flags &= ~GD_FLG_ENV_READY; 57 gd->env_valid = ENV_INVALID; 58 ret_val = env_get(name); 59 gd->env_valid = really_valid; 60 gd->flags = real_gd_flags; 61 return ret_val; 62 } 63 64 void set_default_env(const char *s) 65 { 66 int flags = 0; 67 68 if (sizeof(default_environment) > ENV_SIZE) { 69 puts("*** Error - default environment is too large\n\n"); 70 return; 71 } 72 73 if (s) { 74 if (*s == '!') { 75 printf("*** Warning - %s, " 76 "using default environment\n\n", 77 s + 1); 78 } else { 79 flags = H_INTERACTIVE; 80 puts(s); 81 } 82 } else { 83 puts("Using default environment\n\n"); 84 } 85 86 if (himport_r(&env_htab, (char *)default_environment, 87 sizeof(default_environment), '\0', flags, 0, 88 0, NULL) == 0) 89 pr_err("Environment import failed: errno = %d\n", errno); 90 91 gd->flags |= GD_FLG_ENV_READY; 92 gd->flags |= GD_FLG_ENV_DEFAULT; 93 94 board_env_fixup(); 95 } 96 97 98 /* [re]set individual variables to their value in the default environment */ 99 int set_default_vars(int nvars, char * const vars[]) 100 { 101 /* 102 * Special use-case: import from default environment 103 * (and use \0 as a separator) 104 */ 105 return himport_r(&env_htab, (const char *)default_environment, 106 sizeof(default_environment), '\0', 107 H_NOCLEAR | H_INTERACTIVE, 0, nvars, vars); 108 } 109 110 #ifdef CONFIG_ENV_AES 111 #include <uboot_aes.h> 112 /** 113 * env_aes_cbc_get_key() - Get AES-128-CBC key for the environment 114 * 115 * This function shall return 16-byte array containing AES-128 key used 116 * to encrypt and decrypt the environment. This function must be overridden 117 * by the implementer as otherwise the environment encryption will not 118 * work. 119 */ 120 __weak uint8_t *env_aes_cbc_get_key(void) 121 { 122 return NULL; 123 } 124 125 static int env_aes_cbc_crypt(env_t *env, const int enc) 126 { 127 unsigned char *data = env->data; 128 uint8_t *key; 129 uint8_t key_exp[AES_EXPAND_KEY_LENGTH]; 130 uint32_t aes_blocks; 131 132 key = env_aes_cbc_get_key(); 133 if (!key) 134 return -EINVAL; 135 136 /* First we expand the key. */ 137 aes_expand_key(key, key_exp); 138 139 /* Calculate the number of AES blocks to encrypt. */ 140 aes_blocks = ENV_SIZE / AES_KEY_LENGTH; 141 142 if (enc) 143 aes_cbc_encrypt_blocks(key_exp, data, data, aes_blocks); 144 else 145 aes_cbc_decrypt_blocks(key_exp, data, data, aes_blocks); 146 147 return 0; 148 } 149 #else 150 static inline int env_aes_cbc_crypt(env_t *env, const int enc) 151 { 152 return 0; 153 } 154 #endif 155 156 /* 157 * Check if CRC is valid and (if yes) import the environment. 158 * Note that "buf" may or may not be aligned. 159 */ 160 int env_import(const char *buf, int check) 161 { 162 env_t *ep = (env_t *)buf; 163 int ret; 164 165 if (check) { 166 uint32_t crc; 167 168 memcpy(&crc, &ep->crc, sizeof(crc)); 169 170 if (crc32(0, ep->data, ENV_SIZE) != crc) { 171 set_default_env("!bad CRC"); 172 return 0; 173 } 174 } 175 176 /* Decrypt the env if desired. */ 177 ret = env_aes_cbc_crypt(ep, 0); 178 if (ret) { 179 pr_err("Failed to decrypt env!\n"); 180 set_default_env("!import failed"); 181 return ret; 182 } 183 184 if (himport_r(&env_htab, (char *)ep->data, ENV_SIZE, '\0', 0, 0, 185 0, NULL)) { 186 gd->flags |= GD_FLG_ENV_READY; 187 return 1; 188 } 189 190 pr_err("Cannot import environment: errno = %d\n", errno); 191 192 set_default_env("!import failed"); 193 194 return 0; 195 } 196 197 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT 198 static unsigned char env_flags; 199 200 int env_import_redund(const char *buf1, const char *buf2) 201 { 202 int crc1_ok, crc2_ok; 203 env_t *ep, *tmp_env1, *tmp_env2; 204 205 tmp_env1 = (env_t *)buf1; 206 tmp_env2 = (env_t *)buf2; 207 208 crc1_ok = crc32(0, tmp_env1->data, ENV_SIZE) == 209 tmp_env1->crc; 210 crc2_ok = crc32(0, tmp_env2->data, ENV_SIZE) == 211 tmp_env2->crc; 212 213 if (!crc1_ok && !crc2_ok) { 214 set_default_env("!bad CRC"); 215 return 0; 216 } else if (crc1_ok && !crc2_ok) { 217 gd->env_valid = ENV_VALID; 218 } else if (!crc1_ok && crc2_ok) { 219 gd->env_valid = ENV_REDUND; 220 } else { 221 /* both ok - check serial */ 222 if (tmp_env1->flags == 255 && tmp_env2->flags == 0) 223 gd->env_valid = ENV_REDUND; 224 else if (tmp_env2->flags == 255 && tmp_env1->flags == 0) 225 gd->env_valid = ENV_VALID; 226 else if (tmp_env1->flags > tmp_env2->flags) 227 gd->env_valid = ENV_VALID; 228 else if (tmp_env2->flags > tmp_env1->flags) 229 gd->env_valid = ENV_REDUND; 230 else /* flags are equal - almost impossible */ 231 gd->env_valid = ENV_VALID; 232 } 233 234 if (gd->env_valid == ENV_VALID) 235 ep = tmp_env1; 236 else 237 ep = tmp_env2; 238 239 env_flags = ep->flags; 240 return env_import((char *)ep, 0); 241 } 242 #endif /* CONFIG_SYS_REDUNDAND_ENVIRONMENT */ 243 244 /* Export the environment and generate CRC for it. */ 245 int env_export(env_t *env_out) 246 { 247 char *res; 248 ssize_t len; 249 int ret; 250 251 res = (char *)env_out->data; 252 len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL); 253 if (len < 0) { 254 pr_err("Cannot export environment: errno = %d\n", errno); 255 return 1; 256 } 257 258 /* Encrypt the env if desired. */ 259 ret = env_aes_cbc_crypt(env_out, 1); 260 if (ret) 261 return ret; 262 263 env_out->crc = crc32(0, env_out->data, ENV_SIZE); 264 265 #ifdef CONFIG_SYS_REDUNDAND_ENVIRONMENT 266 env_out->flags = ++env_flags; /* increase the serial */ 267 #endif 268 269 return 0; 270 } 271 272 void env_relocate(void) 273 { 274 #if defined(CONFIG_NEEDS_MANUAL_RELOC) 275 env_reloc(); 276 env_htab.change_ok += gd->reloc_off; 277 #endif 278 if (gd->env_valid == ENV_INVALID) { 279 #if defined(CONFIG_ENV_IS_NOWHERE) || defined(CONFIG_SPL_BUILD) 280 /* Environment not changable */ 281 set_default_env(NULL); 282 #else 283 bootstage_error(BOOTSTAGE_ID_NET_CHECKSUM); 284 set_default_env("!bad CRC"); 285 #endif 286 } else { 287 env_load(); 288 } 289 } 290 291 #if defined(CONFIG_AUTO_COMPLETE) && !defined(CONFIG_SPL_BUILD) 292 int env_complete(char *var, int maxv, char *cmdv[], int bufsz, char *buf) 293 { 294 ENTRY *match; 295 int found, idx; 296 297 idx = 0; 298 found = 0; 299 cmdv[0] = NULL; 300 301 while ((idx = hmatch_r(var, idx, &match, &env_htab))) { 302 int vallen = strlen(match->key) + 1; 303 304 if (found >= maxv - 2 || bufsz < vallen) 305 break; 306 307 cmdv[found++] = buf; 308 memcpy(buf, match->key, vallen); 309 buf += vallen; 310 bufsz -= vallen; 311 } 312 313 qsort(cmdv, found, sizeof(cmdv[0]), strcmp_compar); 314 315 if (idx) 316 cmdv[found++] = "..."; 317 318 cmdv[found] = NULL; 319 return found; 320 } 321 #endif 322