aboutsummaryrefslogtreecommitdiff
path: root/common/env_common.c
diff options
context:
space:
mode:
authorMarek Vasut2014-03-05 19:59:51 +0100
committerTom Rini2014-03-21 16:44:02 -0400
commita4223b746db5c2db2e1a1d4f0bb20e30484b1667 (patch)
treefd79a07f7ad91a74aaa214c149df5488a5a57a44 /common/env_common.c
parent7ce1526ed2bf7a7499a843d38b30095fa2894659 (diff)
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. Signed-off-by: Marek Vasut <marex@denx.de>
Diffstat (limited to 'common/env_common.c')
-rw-r--r--common/env_common.c62
1 files changed, 62 insertions, 0 deletions
diff --git a/common/env_common.c b/common/env_common.c
index fe35ff4360c..cd7b4cd1dfb 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;