@@ -507,6 +507,18 @@ config ENCRYPTED_SW_DESCRIPTION
if this is set. It is a compile time option, and mix of plain and
encrypted sw-descriptions is not possible.
+config ASYM_ENCRYPTED_SW_DESCRIPTION
+ bool "Asymmetrical encrypted sw-description"
+ depends on ENCRYPTED_SW_DESCRIPTION && !PKCS11
+ depends on SSL_IMPL_OPENSSL
+ default n
+ help
+ This option enables support for asymmetrical encrypted sw-description,
+ making it possible to encrypt images device specific. The artifacts
+ persist in being symmetrically encrypted by retrieving an AES key from
+ the sw-description, which may be the same or distinct for each artifact.
+ Cryptographic Message Syntax (CMS) with OpenSSL is used for encryption.
+
config ENCRYPTED_IMAGES_HARDEN_LOGGING
bool "Harden logging for encrypted images"
default n
@@ -445,6 +445,11 @@ static int __swupdate_copy(int fdin, unsigned char *inbuf, void *out, size_t nby
unsigned char *aes_key = NULL;
unsigned char *ivt = NULL;
unsigned char ivtbuf[AES_BLK_SIZE];
+#ifdef CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION
+ unsigned char aeskeybuf[AES_256_KEY_LEN];
+ char keylen_ascii;
+#endif
+ char keylen;
struct InputState input_state = {
.fdin = fdin,
@@ -514,7 +519,40 @@ static int __swupdate_copy(int fdin, unsigned char *inbuf, void *out, size_t nby
}
if (encrypted) {
+#ifdef CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION
+ if(!imgaeskey) {
+ return -EINVAL;
+ }
+
+ keylen_ascii = strlen(imgaeskey);
+ switch (keylen_ascii) {
+ 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
+ keylen = keylen_ascii / 2;
+ break;
+ default:
+ ERROR("Invalid image aes_key length");
+ return -EINVAL;
+ }
+
+ if (!imgivt || strlen(imgivt) != (AES_BLK_SIZE*2)) {
+ ERROR("Invalid image ivt length");
+ return -EINVAL;
+ }
+
+ if (is_hex_str(imgivt) || ascii_to_bin(ivtbuf, sizeof(ivtbuf), imgivt) ||
+ is_hex_str(imgaeskey) || ascii_to_bin(aeskeybuf, keylen, imgaeskey)) {
+ ERROR("Setting aes_key or ivt");
+ return -EINVAL;
+ }
+
+ aes_key = aeskeybuf;
+ ivt = ivtbuf;
+#else
aes_key = get_aes_key();
+ keylen = get_aes_keylen();
if (imgivt) {
if (strlen(imgivt) != (AES_BLK_SIZE * 2) ||
is_hex_str(imgivt) ||
@@ -525,7 +563,8 @@ static int __swupdate_copy(int fdin, unsigned char *inbuf, void *out, size_t nby
ivt = ivtbuf;
} else
ivt = get_aes_ivt();
- decrypt_state.dcrypt = swupdate_DECRYPT_init(aes_key, get_aes_keylen(), ivt);
+#endif
+ decrypt_state.dcrypt = swupdate_DECRYPT_init(aes_key, keylen, ivt);
if (!decrypt_state.dcrypt) {
ERROR("decrypt initialization failure, aborting");
ret = -EFAULT;
@@ -498,6 +498,13 @@ void cleanup_files(struct swupdate_cfg *software) {
free(fn);
}
#endif
+
+#ifdef CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION
+ if (asprintf(&fn, "%s%s.enc", TMPDIR, SW_DESCRIPTION_FILENAME) != ENOMEM_ASPRINTF) {
+ remove_sw_file(fn);
+ free(fn);
+ }
+#endif
}
int preupdatecmd(struct swupdate_cfg *swcfg)
@@ -45,6 +45,7 @@
#include "state.h"
#include "bootloader.h"
#include "hw-compatibility.h"
+#include "sslapi.h"
#define BUFF_SIZE 4096
#define PERCENT_LB_INDEX 4
@@ -144,11 +145,14 @@ static int extract_files(int fd, struct swupdate_cfg *software)
int fdout;
struct img_type *img, *part;
char output_file[MAX_IMAGE_FNAME];
+#ifdef CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION
+ char enc_output_file[MAX_IMAGE_FNAME];
+#endif
const char* TMPDIR = get_tmpdir();
bool installed_directly = false;
bool encrypted_sw_desc = false;
-#ifdef CONFIG_ENCRYPTED_SW_DESCRIPTION
+#if defined(CONFIG_ENCRYPTED_SW_DESCRIPTION) && !defined(CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION)
encrypted_sw_desc = true;
#endif
@@ -168,6 +172,16 @@ static int extract_files(int fd, struct swupdate_cfg *software)
if (extract_file_to_tmp(fd, SW_DESCRIPTION_FILENAME, &offset, encrypted_sw_desc) < 0 )
return -1;
+#ifdef CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION
+ snprintf(output_file, sizeof(output_file), "%s%s", TMPDIR, SW_DESCRIPTION_FILENAME);
+ snprintf(enc_output_file, sizeof(enc_output_file), "%s.enc", output_file);
+ if (rename(output_file, enc_output_file))
+ return -1;
+
+ if (swupdate_decrypt_file(software->dgst, enc_output_file, output_file))
+ return -1;
+#endif
+
status = STREAM_WAIT_SIGNATURE;
break;
@@ -381,10 +395,13 @@ static int save_stream(int fdin, struct swupdate_cfg *software)
unsigned int tmpsize;
unsigned long offset;
char output_file[MAX_IMAGE_FNAME];
+#ifdef CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION
+ char enc_output_file[MAX_IMAGE_FNAME];
+#endif
const char* TMPDIR = get_tmpdir();
bool encrypted_sw_desc = false;
-#ifdef CONFIG_ENCRYPTED_SW_DESCRIPTION
+#if defined(CONFIG_ENCRYPTED_SW_DESCRIPTION) && !defined(CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION)
encrypted_sw_desc = true;
#endif
if (fdin < 0)
@@ -452,6 +469,20 @@ static int save_stream(int fdin, struct swupdate_cfg *software)
ret = -EINVAL;
goto no_copy_output;
}
+
+#ifdef CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION
+ snprintf(output_file, sizeof(output_file), "%s%s", TMPDIR, SW_DESCRIPTION_FILENAME);
+ snprintf(enc_output_file, sizeof(enc_output_file), "%s.enc", output_file);
+ if (rename(output_file, enc_output_file)) {
+ ret = -EINVAL;
+ goto no_copy_output;
+ }
+ if (swupdate_decrypt_file(software->dgst, enc_output_file, output_file)) {
+ ret = -EINVAL;
+ goto no_copy_output;
+ }
+#endif
+
#ifdef CONFIG_SIGNED_IMAGES
snprintf(output_file, sizeof(output_file), "%s.sig", SW_DESCRIPTION_FILENAME);
if (extract_file_to_tmp(tmpfd, output_file, &offset, false) < 0 ) {
Signed-off-by: Michael Glembotzki <Michael.Glembotzki@iris-sensing.com> --- Kconfig | 12 ++++++++++++ core/cpio_utils.c | 41 ++++++++++++++++++++++++++++++++++++++++- core/installer.c | 7 +++++++ core/stream_interface.c | 35 +++++++++++++++++++++++++++++++++-- 4 files changed, 92 insertions(+), 3 deletions(-)