diff mbox series

[v5,05/16] crypto: prepare to support multiple cipher

Message ID 20250904115704.58413-6-Michael.Glembotzki@iris-sensing.com
State Changes Requested
Delegated to: Stefano Babic
Headers show
Series Add support for asymmetric decryption | expand

Commit Message

Michael Glembotzki Sept. 4, 2025, 11:49 a.m. UTC
From: Stefano Babic <stefano.babic@swupdate.org>

This is a preparation to introduce other cipher than aes-cbc.

Signed-off-by: Stefano Babic <stefano.babic@swupdate.org>
---
 core/cpio_utils.c                 |  2 +-
 core/crypto.c                     |  4 +--
 crypto/swupdate_decrypt_mbedtls.c |  5 ++-
 crypto/swupdate_decrypt_openssl.c |  5 ++-
 crypto/swupdate_decrypt_wolfssl.c |  6 +++-
 include/swupdate_aes.h            | 54 +++++++++++++++++++++++++++++++
 include/swupdate_crypto.h         |  5 +--
 include/swupdate_image.h          |  2 ++
 parser/parser.c                   | 12 +++++--
 9 files changed, 85 insertions(+), 10 deletions(-)
 create mode 100644 include/swupdate_aes.h
diff mbox series

Patch

diff --git a/core/cpio_utils.c b/core/cpio_utils.c
index 10a39914..0768998a 100644
--- a/core/cpio_utils.c
+++ b/core/cpio_utils.c
@@ -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);
+		decrypt_state.dcrypt = swupdate_DECRYPT_init(aes_key, get_aes_keylen(), ivt, AES_CBC);
 		if (!decrypt_state.dcrypt) {
 			ERROR("decrypt initialization failure, aborting");
 			ret = -EFAULT;
diff --git a/core/crypto.c b/core/crypto.c
index b41c477c..62deac9d 100644
--- a/core/crypto.c
+++ b/core/crypto.c
@@ -139,14 +139,14 @@  void print_registered_cryptolib(void)
 	}
 }
 
-void *swupdate_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv)
+void *swupdate_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv, cipher_t cipher)
 {
 	swupdate_decrypt_lib *lib;
 	if (!get_cryptolib())
 		return NULL;
 
 	lib = (swupdate_decrypt_lib *)current[DECRYPTLIB]->lib;
-	return lib->DECRYPT_init(key, keylen, iv);
+	return lib->DECRYPT_init(key, keylen, iv, cipher);
 }
 
 int swupdate_DECRYPT_update(void *dgst, unsigned char *buf, 
diff --git a/crypto/swupdate_decrypt_mbedtls.c b/crypto/swupdate_decrypt_mbedtls.c
index c87a2c3d..abff9cec 100644
--- a/crypto/swupdate_decrypt_mbedtls.c
+++ b/crypto/swupdate_decrypt_mbedtls.c
@@ -12,7 +12,7 @@ 
 
 static swupdate_decrypt_lib mbedtls;
 
-static void *mbedtls_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv)
+static void *mbedtls_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv, cipher_t cipher)
 {
 	struct mbedtls_digest *dgst;
 	mbedtls_cipher_type_t cipher_type;
@@ -20,6 +20,9 @@  static void *mbedtls_DECRYPT_init(unsigned char *key, char keylen, unsigned char
 	int key_bitlen;
 	int error;
 
+	/* Temporary to remove warning */
+	cipher = cipher;
+
 	if ((key == NULL) || (iv == NULL)) {
 		ERROR("no key or iv provided for decryption!");
 		return NULL;
diff --git a/crypto/swupdate_decrypt_openssl.c b/crypto/swupdate_decrypt_openssl.c
index 3f632d6d..e6ea3ffd 100644
--- a/crypto/swupdate_decrypt_openssl.c
+++ b/crypto/swupdate_decrypt_openssl.c
@@ -22,12 +22,15 @@ 
 static void openssl_probe(void);
 
 static swupdate_decrypt_lib openssl;
-static void *openssl_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv)
+static void *openssl_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv, cipher_t reqcipher)
 {
 	struct openssl_digest *dgst;
 	const EVP_CIPHER *cipher;
 	int ret;
 
+	/* Temporary to remove warning */
+	reqcipher = reqcipher;
+
 	if ((key == NULL) || (iv == NULL)) {
 		ERROR("no key or iv provided for decryption!");
 		return NULL;
diff --git a/crypto/swupdate_decrypt_wolfssl.c b/crypto/swupdate_decrypt_wolfssl.c
index e63eed02..015fcd3c 100644
--- a/crypto/swupdate_decrypt_wolfssl.c
+++ b/crypto/swupdate_decrypt_wolfssl.c
@@ -26,7 +26,8 @@  static void wolfssl_debug(int __attribute__ ((__unused__)) level, const char *co
 #endif
 
 static void *wolfssl_DECRYPT_init(unsigned char *key,
-					char __attribute__ ((__unused__)) keylen, unsigned char *iv)
+					char __attribute__ ((__unused__)) keylen, unsigned char *iv,
+					cipher_t cipher)
 {
 	struct wolfssl_digest *dgst;
 	const char *library;
@@ -43,6 +44,9 @@  static void *wolfssl_DECRYPT_init(unsigned char *key,
 		return NULL;
 	}
 
+	/* Temporary to remove warning */
+	cipher = cipher;
+
 	dgst = calloc(1, sizeof(*dgst));
 	if (!dgst) {
 		return NULL;
diff --git a/include/swupdate_aes.h b/include/swupdate_aes.h
new file mode 100644
index 00000000..acb69573
--- /dev/null
+++ b/include/swupdate_aes.h
@@ -0,0 +1,54 @@ 
+/*
+ * (C) Copyright 2025
+ * Stefano Babic, stefano.babic@swupdate.org.
+ *
+ * SPDX-License-Identifier:     GPL-2.0-only
+ *
+ */
+
+#pragma once
+#include <stdbool.h>
+#include <string.h>
+
+/*
+ * Add global definitions to set the cipher.
+ * Each implementation must map the generic enum
+ * to the library specific code
+ */
+
+typedef enum {
+	AES_CBC,
+	AES_CBC_128,
+	AES_CBC_192,
+	AES_CBC_256,
+	AES_CTR,
+	AES_CTR_128,
+	AES_CTR_192,
+	AES_CTR_256,
+	AES_UNKNOWN
+} cipher_t;
+
+typedef struct {
+	cipher_t cipher;
+	const char *ciphername;
+} map_cipher_t;
+
+static map_cipher_t map_cipher[] = {
+	{AES_CBC, "aes-cbc"},
+	{AES_CBC_128, "aes-cbc-128"},
+	{AES_CBC_192, "aes-cbc-192"},
+	{AES_CBC_256, "aes-cbc-256"},
+	{AES_CBC_128, "aes-cbc-128"},
+	{AES_CTR_128, "aes-ctr-128"},
+	{AES_CTR_192, "aes-ctr-192"},
+	{AES_CTR_256, "aes-ctr-256"},
+	{AES_CTR_128, "aes-ctr-128"}
+};
+
+static inline cipher_t map_name_cipher (const char *name) {
+	for (int count = 0; count < sizeof(map_cipher)/sizeof(map_cipher_t); count++) {
+		if (!strcmp(map_cipher[count].ciphername, name))
+			return map_cipher[count].cipher;
+	}
+	return AES_UNKNOWN;
+}
diff --git a/include/swupdate_crypto.h b/include/swupdate_crypto.h
index 243b6068..aa9da964 100644
--- a/include/swupdate_crypto.h
+++ b/include/swupdate_crypto.h
@@ -8,6 +8,7 @@ 
 
 #pragma once
 #include <stdbool.h>
+#include <swupdate_aes.h>
 
 #define SHA_DEFAULT	"sha256"
 
@@ -37,7 +38,7 @@  typedef enum {
 } ssl_cert_purpose_t;
 
 typedef struct {
-	void *(*DECRYPT_init)(unsigned char *key, char keylen, unsigned char *iv);
+	void *(*DECRYPT_init)(unsigned char *key, char keylen, unsigned char *iv, cipher_t cipher);
 	int (*DECRYPT_update)(void *ctx, unsigned char *buf, 
 				int *outlen, const unsigned char *cryptbuf, int inlen);
 
@@ -116,7 +117,7 @@  int swupdate_verify_file(void *ctx, const char *sigfile,
 				const char *file, const char *signer_name);
 int swupdate_HASH_compare(const unsigned char *hash1, const unsigned char *hash2);
 
-void *swupdate_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv);
+void *swupdate_DECRYPT_init(unsigned char *key, char keylen, unsigned char *iv, cipher_t cipher);
 int swupdate_DECRYPT_update(void *ctx, unsigned char *buf, 
 				int *outlen, const unsigned char *cryptbuf, int inlen);
 int swupdate_DECRYPT_final(void *ctx, unsigned char *buf,
diff --git a/include/swupdate_image.h b/include/swupdate_image.h
index 26ace794..8c58a40c 100644
--- a/include/swupdate_image.h
+++ b/include/swupdate_image.h
@@ -13,6 +13,7 @@ 
 #include "globals.h"
 #include "swupdate_dict.h"
 #include "lua_util.h"
+#include "swupdate_aes.h"
 
 typedef enum {
 	FLASH,
@@ -56,6 +57,7 @@  struct img_type {
 	int compressed;
 	bool preserve_attributes; /* whether to preserve attributes in archives */
 	bool is_encrypted;
+	cipher_t cipher;
 	char ivt_ascii[33];
 	bool install_directly;
 	int is_script;
diff --git a/parser/parser.c b/parser/parser.c
index 72868cb1..a2d8ff51 100644
--- a/parser/parser.c
+++ b/parser/parser.c
@@ -24,6 +24,7 @@ 
 #include "parselib.h"
 #include "parsers.h"
 #include "swupdate_dict.h"
+#include "swupdate_aes.h"
 #include "lua_util.h"
 
 #define MODULE_NAME	"PARSER"
@@ -439,7 +440,7 @@  static void get_ivt_value(parsertype p, void *elem, char *ivt_ascii)
 static int parse_common_attributes(parsertype p, void *elem, struct img_type *image, struct swupdate_cfg *cfg)
 {
 	char seek_str[MAX_SEEK_STRING_SIZE];
-	const char* compressed;
+	const char *compressed, *encrypted;
 	unsigned long offset = 0;
 
 	/*
@@ -498,7 +499,14 @@  static int parse_common_attributes(parsertype p, void *elem, struct img_type *im
 	GET_FIELD_BOOL(p, elem, "preserve-attributes", &image->preserve_attributes);
 	GET_FIELD_BOOL(p, elem, "install-if-different", &image->id.install_if_different);
 	GET_FIELD_BOOL(p, elem, "install-if-higher", &image->id.install_if_higher);
-	GET_FIELD_BOOL(p, elem, "encrypted", &image->is_encrypted);
+
+	if ((encrypted = get_field_string(p, elem, "encrypted")) != NULL) {
+		image->is_encrypted = true;
+		image->cipher = map_name_cipher(encrypted);
+	} else {
+		GET_FIELD_BOOL(p, elem, "encrypted", &image->is_encrypted);
+		image->cipher = AES_CBC;
+	}
 	get_ivt_value(p, elem, image->ivt_ascii);
 
 	if (is_image_installed(&cfg->installed_sw_list, image)) {