@@ -18,6 +18,9 @@ endif
lib-$(CONFIG_SIGALG_RAWRSA) += swupdate_rsa_verify.o
lib-$(CONFIG_SIGALG_RSAPSS) += swupdate_rsa_verify.o
endif
+ifeq ($(CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION),y)
+lib-$(CONFIG_ENCRYPTED_IMAGES) += swupdate_cms_decrypt.o
+endif
ifeq ($(CONFIG_SSL_IMPL_OPENSSL),y)
lib-$(CONFIG_SIGALG_CMS) += swupdate_cms_verify.o
endif
new file mode 100644
@@ -0,0 +1,115 @@
+/*
+ * (C) Copyright 2024
+ * Michael Glembotzki, iris-GmbH infrared & intelligent sensors, michael.glembotzki@iris-sensing.com
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Code mostly taken from openssl examples
+ */
+#include <sys/stat.h>
+#include "swupdate.h"
+#include "sslapi.h"
+#include "util.h"
+
+int swupdate_dgst_add_asym_keypair(struct swupdate_cfg *sw, const char *keypair_file)
+{
+ X509 *asym_decryption_cert = NULL;
+ EVP_PKEY *asym_decryption_key = NULL;
+ BIO *tbio = NULL;
+ struct swupdate_digest *dgst = sw->dgst;
+ int ret = 0;
+
+ if (!dgst) {
+ dgst = calloc(1, sizeof(*dgst));
+ if (!dgst) {
+ ret = 1;
+ goto err;
+ }
+ }
+
+ tbio = BIO_new_file(keypair_file, "r");
+
+ if (!tbio) {
+ ERROR("%s cannot be opened", keypair_file);
+ ret = 1;
+ goto err;
+ }
+
+ asym_decryption_cert = PEM_read_bio_X509(tbio, NULL, 0, NULL);
+ if (!asym_decryption_cert)
+ WARN("Decryption cert not found");
+
+ BIO_reset(tbio);
+
+ asym_decryption_key = PEM_read_bio_PrivateKey(tbio, NULL, 0, NULL);
+ BIO_free(tbio);
+ if (!asym_decryption_key) {
+ ERROR("Decryption key not found");
+ ret = 1;
+ goto err;
+ }
+
+ dgst->asym_decryption_cert = asym_decryption_cert;
+ dgst->asym_decryption_key = asym_decryption_key;
+
+ return ret;
+
+err:
+ if (dgst)
+ free(dgst);
+
+ return ret;
+}
+
+int swupdate_decrypt_file(struct swupdate_digest *dgst, const char *infile, const char *outfile)
+{
+ BIO *in = NULL, *out = NULL;
+ CMS_ContentInfo *cms = NULL;
+ int ret = 0;
+
+ if (!dgst || !infile || !outfile)
+ return 1;
+
+ /* Open CMS message to decrypt */
+ in = BIO_new_file(infile, "rb");
+ if (!in) {
+ ERROR("%s cannot be opened", infile);
+ ret = 1;
+ goto err;
+ }
+
+ /* Parse message */
+ cms = d2i_CMS_bio(in, NULL);
+ if (!cms) {
+ ERROR("%s cannot be parsed as DER-encoded CMS blob", infile);
+ ret = 1;
+ goto err;
+ }
+
+ out = BIO_new_file(outfile, "wb");
+ if (!out) {
+ ERROR("%s cannot be opened", outfile);
+ ret = 1;
+ goto err;
+ }
+
+ if (chmod(outfile, 0600)) {
+ ERROR("Setting file permissions");
+ ret = 1;
+ goto err;
+ }
+
+ /* Decrypt CMS message */
+ if (!CMS_decrypt(cms, dgst->asym_decryption_key, dgst->asym_decryption_cert, NULL, out, 0)) {
+ ERR_print_errors_fp(stderr);
+ ERROR("Decrypting %s failed", infile);
+ ret = 1;
+ goto err;
+ }
+
+err:
+ BIO_free(in);
+ BIO_free(out);
+ CMS_ContentInfo_free(cms);
+ return ret;
+}
@@ -113,6 +113,10 @@ struct swupdate_digest {
int verbose;
char *gpgme_protocol;
#endif
+#ifdef CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION
+ EVP_PKEY *asym_decryption_key;
+ X509 *asym_decryption_cert;
+#endif
};
#if OPENSSL_VERSION_NUMBER < 0x10100000L
@@ -222,6 +226,11 @@ UNUSED static inline struct swupdate_digest *swupdate_DECRYPT_init(
#define swupdate_DECRYPT_cleanup(p)
#endif
+#ifdef CONFIG_ASYM_ENCRYPTED_SW_DESCRIPTION
+int swupdate_dgst_add_asym_keypair(struct swupdate_cfg *sw, const char *keypair_file);
+int swupdate_decrypt_file(struct swupdate_digest *dgst, const char *infile, const char *outfile);
+#endif
+
#ifndef SSL_PURPOSE_DEFAULT
#define SSL_PURPOSE_EMAIL_PROT -1
#define SSL_PURPOSE_CODE_SIGN -1
Decryption with OpenSSL CMS is limited to entire files, preventing the ability to decrypt data in chunks, as is possible with symmetric decryption. Signed-off-by: Michael Glembotzki <Michael.Glembotzki@iris-sensing.com> --- corelib/Makefile | 3 + corelib/swupdate_cms_decrypt.c | 115 +++++++++++++++++++++++++++++++++ include/sslapi.h | 9 +++ 3 files changed, 127 insertions(+) create mode 100644 corelib/swupdate_cms_decrypt.c