@@ -11,6 +11,7 @@
obj-y += swupdate.o \
cpio_utils.o \
crypto.o \
+ decrypt_keys.o \
notifier.o \
handler.o \
bootloader.o \
@@ -608,7 +608,7 @@ int copyfile(struct swupdate_copy *args)
}
if (args->encrypted) {
- aes_key = (unsigned char *)get_aes_key();
+ aes_key = (unsigned char *)swupdate_get_decrypt_key();
if (args->imgivt && strlen(args->imgivt)) {
if (!is_hex_str(args->imgivt) || ascii_to_bin(ivtbuf, sizeof(ivtbuf), args->imgivt)) {
ERROR("Invalid image ivt");
@@ -617,7 +617,7 @@ int copyfile(struct swupdate_copy *args)
ivt = ivtbuf;
} else
ivt = get_aes_ivt();
- decrypt_state.dcrypt = swupdate_DECRYPT_init(aes_key, get_aes_keylen(), ivt, AES_CBC);
+ decrypt_state.dcrypt = swupdate_DECRYPT_init(aes_key, swupdate_get_decrypt_keylen(), ivt, AES_CBC);
if (!decrypt_state.dcrypt) {
ERROR("decrypt initialization failure, aborting");
ret = -EFAULT;
new file mode 100644
@@ -0,0 +1,150 @@
+/*
+ * (C) Copyright 2025
+ * Stefano Babic, stefano.babic@swupdate.org.
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "util.h"
+#include "generated/autoconf.h"
+
+/*
+ * key is 256 bit for max aes_256
+ * or is a pkcs#11 URL
+ * keylen is the actual aes key length
+ * ivt is 128 bit
+ */
+struct decryption_key {
+ char *key;
+ char keylen;
+ unsigned char ivt[AES_BLK_SIZE];
+};
+
+static struct decryption_key *decrypt_keys = NULL;
+
+int set_aes_key(const char *key, const char *ivt)
+{
+ int ret;
+ size_t keylen;
+ bool is_pkcs11 = false;
+
+ /*
+ * Allocates the global structure just once
+ */
+ if (!decrypt_keys) {
+ decrypt_keys = (struct decryption_key *)calloc(1, sizeof(*decrypt_keys));
+ if (!decrypt_keys)
+ return -ENOMEM;
+ }
+
+ if (strlen(ivt) != (AES_BLK_SIZE*2) || !is_hex_str(ivt)) {
+ ERROR("Invalid ivt");
+ return -EINVAL;
+ }
+
+ ret = ascii_to_bin(decrypt_keys->ivt, sizeof(decrypt_keys->ivt), ivt);
+ keylen = strlen(key);
+
+ if (!strcmp("pkcs11", key)) {
+ is_pkcs11 = true;
+ decrypt_keys->keylen = keylen;
+
+ } else {
+ switch (keylen) {
+ case AES_128_KEY_LEN * 2:
+ case AES_192_KEY_LEN * 2:
+ case AES_256_KEY_LEN * 2:
+ // valid hex string size for AES 128/192/256
+ decrypt_keys->keylen = keylen / 2;
+ break;
+ default:
+ ERROR("Invalid decrypt_keys length");
+ return -EINVAL;
+ }
+ }
+
+ if (decrypt_keys->key)
+ free(decrypt_keys->key);
+
+ decrypt_keys->key = calloc(1, keylen + 1);
+ if (!decrypt_keys->key)
+ return -ENOMEM;
+
+ if (is_pkcs11) {
+ strncpy(decrypt_keys->key, key, keylen);
+ } else {
+ ret |= !is_hex_str(key);
+ ret |= ascii_to_bin((unsigned char *)decrypt_keys->key, decrypt_keys->keylen, key);
+ }
+
+ if (ret) {
+ ERROR("Invalid decrypt_keys");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int load_decryption_key(char *fname)
+{
+ FILE *fp;
+ char *b1 = NULL, *b2 = NULL;
+ int ret;
+
+ fp = fopen(fname, "r");
+ if (!fp)
+ return -EBADF;
+
+ ret = fscanf(fp, "%ms %ms", &b1, &b2);
+ switch (ret) {
+ case 2:
+ DEBUG("Read decryption key and initialization vector from file %s.", fname);
+ break;
+ default:
+ if (b1 != NULL)
+ free(b1);
+ fprintf(stderr, "File with decryption key is not in the format <key> <ivt>\n");
+ fclose(fp);
+ return -EINVAL;
+ }
+ fclose(fp);
+
+ ret = set_aes_key(b1, b2);
+
+ if (b1 != NULL)
+ free(b1);
+ if (b2 != NULL)
+ free(b2);
+
+ if (ret) {
+ fprintf(stderr, "Keys are invalid\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+char *swupdate_get_decrypt_key(void) {
+ if (!decrypt_keys)
+ return NULL;
+ return decrypt_keys->key;
+}
+
+char swupdate_get_decrypt_keylen(void) {
+ if (!decrypt_keys)
+ return -1;
+ return decrypt_keys->keylen;
+}
+
+unsigned char *get_aes_ivt(void) {
+ if (!decrypt_keys)
+ return NULL;
+ return decrypt_keys->ivt;
+}
@@ -37,20 +37,6 @@
#include "util.h"
#include "generated/autoconf.h"
-/*
- * key is 256 bit for max aes_256
- * or is a pkcs#11 URL
- * keylen is the actual aes key length
- * ivt is 128 bit
- */
-struct decryption_key {
- char *key;
- char keylen;
- unsigned char ivt[AES_BLK_SIZE];
-};
-
-static struct decryption_key *aes_key = NULL;
-
/*
* Configuration file for fw_env.config
*/
@@ -506,63 +492,6 @@ int count_elem_list(struct imglist *list)
return count;
}
-int load_decryption_key(char *fname)
-{
- FILE *fp;
- char *b1 = NULL, *b2 = NULL;
- int ret;
-
- fp = fopen(fname, "r");
- if (!fp)
- return -EBADF;
-
- ret = fscanf(fp, "%ms %ms", &b1, &b2);
- switch (ret) {
- case 2:
- DEBUG("Read decryption key and initialization vector from file %s.", fname);
- break;
- default:
- if (b1 != NULL)
- free(b1);
- fprintf(stderr, "File with decryption key is not in the format <key> <ivt>\n");
- fclose(fp);
- return -EINVAL;
- }
- fclose(fp);
-
- ret = set_aes_key(b1, b2);
-
- if (b1 != NULL)
- free(b1);
- if (b2 != NULL)
- free(b2);
-
- if (ret) {
- fprintf(stderr, "Keys are invalid\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-char *get_aes_key(void) {
- if (!aes_key)
- return NULL;
- return aes_key->key;
-}
-
-char get_aes_keylen(void) {
- if (!aes_key)
- return -1;
- return aes_key->keylen;
-}
-
-unsigned char *get_aes_ivt(void) {
- if (!aes_key)
- return NULL;
- return aes_key->ivt;
-}
-
bool is_hex_str(const char *ascii) {
unsigned int i, size;
@@ -580,69 +509,6 @@ bool is_hex_str(const char *ascii) {
return true;
}
-int set_aes_key(const char *key, const char *ivt)
-{
- int ret;
- size_t keylen;
- bool is_pkcs11 = false;
-
- /*
- * Allocates the global structure just once
- */
- if (!aes_key) {
- aes_key = (struct decryption_key *)calloc(1, sizeof(*aes_key));
- if (!aes_key)
- return -ENOMEM;
- }
-
- if (strlen(ivt) != (AES_BLK_SIZE*2) || !is_hex_str(ivt)) {
- ERROR("Invalid ivt");
- return -EINVAL;
- }
-
- ret = ascii_to_bin(aes_key->ivt, sizeof(aes_key->ivt), ivt);
- keylen = strlen(key);
-
- if (!strcmp("pkcs11", key)) {
- is_pkcs11 = true;
- aes_key->keylen = keylen;
-
- } else {
- switch (keylen) {
- case AES_128_KEY_LEN * 2:
- case AES_192_KEY_LEN * 2:
- case AES_256_KEY_LEN * 2:
- // valid hex string size for AES 128/192/256
- aes_key->keylen = keylen / 2;
- break;
- default:
- ERROR("Invalid aes_key length");
- return -EINVAL;
- }
- }
-
- if (aes_key->key)
- free(aes_key->key);
-
- aes_key->key = calloc(1, keylen + 1);
- if (!aes_key->key)
- return -ENOMEM;
-
- if (is_pkcs11) {
- strncpy(aes_key->key, key, keylen);
- } else {
- ret |= !is_hex_str(key);
- ret |= ascii_to_bin((unsigned char *)aes_key->key, aes_key->keylen, key);
- }
-
- if (ret) {
- ERROR("Invalid aes_key");
- return -EINVAL;
- }
-
- return 0;
-}
-
const char *get_fwenv_config(void) {
if (!fwenv_config)
#if defined(CONFIG_UBOOT)
@@ -289,8 +289,8 @@ void set_fwenv_config(const char *fname);
/* Decryption key functions */
int load_decryption_key(char *fname);
-char *get_aes_key(void);
-char get_aes_keylen(void);
+char *swupdate_get_decrypt_key(void);
+char swupdate_get_decrypt_keylen(void);
unsigned char *get_aes_ivt(void);
int set_aes_key(const char *key, const char *ivt);