diff mbox series

swupdate_decrypt: add option to harden logging

Message ID 20230720122551.186074-1-raimar.sandner@sick.de
State Changes Requested
Delegated to: Stefano Babic
Headers show
Series swupdate_decrypt: add option to harden logging | expand

Commit Message

Raimar Sandner July 20, 2023, 12:25 p.m. UTC
For streamed AES-CBC encrypted images, an adversary can target each
16-byte block of encrypted data within an image and decrypt it, if they
can apply a huge amount of manipulated firmware updates and observe the
logged messages. On average, 2048 update attempts are needed for each
block.

For use cases where this scenario poses a risk, a config option is
introduced to suppress logging messages related to a hash mismatch and
errors in the decryption finalization (padding) of a streamed image.

Signed-off-by: Raimar Sandner <raimar.sandner@sick.de>
---
 Kconfig                            | 14 ++++++++++++++
 core/cpio_utils.c                  |  2 ++
 corelib/swupdate_decrypt.c         |  2 ++
 corelib/swupdate_decrypt_mbedtls.c |  2 ++
 corelib/swupdate_decrypt_pkcs11.c  |  4 ++++
 5 files changed, 24 insertions(+)

Comments

Stefano Babic July 20, 2023, 12:57 p.m. UTC | #1
On 20.07.23 14:25, Raimar Sandner wrote:
> For streamed AES-CBC encrypted images, an adversary can target each
> 16-byte block of encrypted data within an image and decrypt it, if they
> can apply a huge amount of manipulated firmware updates and observe the
> logged messages. On average, 2048 update attempts are needed for each
> block.
> 
> For use cases where this scenario poses a risk, a config option is
> introduced to suppress logging messages related to a hash mismatch and
> errors in the decryption finalization (padding) of a streamed image.

Thanks, it worked, applied !

Best regards,
Stefano Babic

> 
> Signed-off-by: Raimar Sandner <raimar.sandner@sick.de>
> ---
>   Kconfig                            | 14 ++++++++++++++
>   core/cpio_utils.c                  |  2 ++
>   corelib/swupdate_decrypt.c         |  2 ++
>   corelib/swupdate_decrypt_mbedtls.c |  2 ++
>   corelib/swupdate_decrypt_pkcs11.c  |  4 ++++
>   5 files changed, 24 insertions(+)
> 
> diff --git a/Kconfig b/Kconfig
> index 0bf3ae1..397de99 100644
> --- a/Kconfig
> +++ b/Kconfig
> @@ -505,6 +505,20 @@ 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 ENCRYPTED_IMAGES_HARDEN_LOGGING
> +	bool "Harden logging for encrypted images"
> +	default n
> +	depends on ENCRYPTED_IMAGES
> +	help
> +	  This option addresses a theoretical weakness of the AES-CBC encryption in
> +	  combination with streamed images. An adversary can target each 16-byte
> +	  block of encrypted data within an image and decrypt it, if they can apply a
> +	  huge amount of manipulated firmware updates and observe the logged
> +	  messages. On average, 2048 update attempts are needed for each block.
> +	  Select if this scenario poses a risk. If set, log messages related to a
> +	  hash mismatch and errors in the decryption finalization (padding) of a
> +	  streamed image are suppressed.
> +
>   config PKCS11
>   	bool "Enable PKCS#11 cryptographic operations"
>   	default n
> diff --git a/core/cpio_utils.c b/core/cpio_utils.c
> index bcf4818..248b8e2 100644
> --- a/core/cpio_utils.c
> +++ b/core/cpio_utils.c
> @@ -634,8 +634,10 @@ static int __swupdate_copy(int fdin, unsigned char *inbuf, void *out, size_t nby
>   			hash_to_ascii(hash, hashstring);
>   			hash_to_ascii(md_value, newhashstring);
>   
> +#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING
>   			ERROR("HASH mismatch : %s <--> %s",
>   				hashstring, newhashstring);
> +#endif
>   			ret = -EFAULT;
>   			goto copyfile_exit;
>   		}
> diff --git a/corelib/swupdate_decrypt.c b/corelib/swupdate_decrypt.c
> index 9fa8dcb..dadf92a 100644
> --- a/corelib/swupdate_decrypt.c
> +++ b/corelib/swupdate_decrypt.c
> @@ -98,9 +98,11 @@ int swupdate_DECRYPT_final(struct swupdate_digest *dgst, unsigned char *buf,
>   		return -EINVAL;
>   
>   	if (EVP_DecryptFinal_ex(SSL_GET_CTXDEC(dgst), buf, outlen) != 1) {
> +#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING
>   		const char *reason = ERR_reason_error_string(ERR_peek_error());
>   		ERROR("Final: Decryption error 0x%lx, reason: %s", ERR_get_error(),
>   			reason != NULL ? reason : "unknown");
> +#endif
>   		return -EFAULT;
>   	}
>   
> diff --git a/corelib/swupdate_decrypt_mbedtls.c b/corelib/swupdate_decrypt_mbedtls.c
> index ffc6d9b..cccbe8d 100644
> --- a/corelib/swupdate_decrypt_mbedtls.c
> +++ b/corelib/swupdate_decrypt_mbedtls.c
> @@ -103,7 +103,9 @@ int swupdate_DECRYPT_final(struct swupdate_digest *dgst, unsigned char *buf,
>   
>   	error = mbedtls_cipher_finish(&dgst->mbedtls_cipher_context, buf, &olen);
>   	if (error) {
> +#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING
>   		ERROR("mbedtls_cipher_finish: %d", error);
> +#endif
>   		return -EFAULT;
>   	}
>   	*outlen = olen;
> diff --git a/corelib/swupdate_decrypt_pkcs11.c b/corelib/swupdate_decrypt_pkcs11.c
> index 8a20ed4..63672c5 100644
> --- a/corelib/swupdate_decrypt_pkcs11.c
> +++ b/corelib/swupdate_decrypt_pkcs11.c
> @@ -156,13 +156,17 @@ int swupdate_DECRYPT_final(struct swupdate_digest *dgst, unsigned char *buf, int
>   {
>   	unsigned char last_oct = dgst->last_decr[AES_BLK_SIZE - 1];
>   	if (last_oct > AES_BLK_SIZE || last_oct == 0) {
> +#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING
>   		ERROR("AES: Invalid PKCS#7 padding.");
> +#endif
>   		return -EFAULT;
>   	}
>   
>   	for (int i = 2; i <= last_oct; i++) {
>   		if (dgst->last_decr[AES_BLK_SIZE - i] != last_oct) {
> +#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING
>   			ERROR("AES: Invalid PKCS#7 padding.");
> +#endif
>   			return -EFAULT;
>   		}
>   	}
diff mbox series

Patch

diff --git a/Kconfig b/Kconfig
index 0bf3ae1..397de99 100644
--- a/Kconfig
+++ b/Kconfig
@@ -505,6 +505,20 @@  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 ENCRYPTED_IMAGES_HARDEN_LOGGING
+	bool "Harden logging for encrypted images"
+	default n
+	depends on ENCRYPTED_IMAGES
+	help
+	  This option addresses a theoretical weakness of the AES-CBC encryption in
+	  combination with streamed images. An adversary can target each 16-byte
+	  block of encrypted data within an image and decrypt it, if they can apply a
+	  huge amount of manipulated firmware updates and observe the logged
+	  messages. On average, 2048 update attempts are needed for each block.
+	  Select if this scenario poses a risk. If set, log messages related to a
+	  hash mismatch and errors in the decryption finalization (padding) of a
+	  streamed image are suppressed.
+
 config PKCS11
 	bool "Enable PKCS#11 cryptographic operations"
 	default n
diff --git a/core/cpio_utils.c b/core/cpio_utils.c
index bcf4818..248b8e2 100644
--- a/core/cpio_utils.c
+++ b/core/cpio_utils.c
@@ -634,8 +634,10 @@  static int __swupdate_copy(int fdin, unsigned char *inbuf, void *out, size_t nby
 			hash_to_ascii(hash, hashstring);
 			hash_to_ascii(md_value, newhashstring);
 
+#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING
 			ERROR("HASH mismatch : %s <--> %s",
 				hashstring, newhashstring);
+#endif
 			ret = -EFAULT;
 			goto copyfile_exit;
 		}
diff --git a/corelib/swupdate_decrypt.c b/corelib/swupdate_decrypt.c
index 9fa8dcb..dadf92a 100644
--- a/corelib/swupdate_decrypt.c
+++ b/corelib/swupdate_decrypt.c
@@ -98,9 +98,11 @@  int swupdate_DECRYPT_final(struct swupdate_digest *dgst, unsigned char *buf,
 		return -EINVAL;
 
 	if (EVP_DecryptFinal_ex(SSL_GET_CTXDEC(dgst), buf, outlen) != 1) {
+#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING
 		const char *reason = ERR_reason_error_string(ERR_peek_error());
 		ERROR("Final: Decryption error 0x%lx, reason: %s", ERR_get_error(),
 			reason != NULL ? reason : "unknown");
+#endif
 		return -EFAULT;
 	}
 
diff --git a/corelib/swupdate_decrypt_mbedtls.c b/corelib/swupdate_decrypt_mbedtls.c
index ffc6d9b..cccbe8d 100644
--- a/corelib/swupdate_decrypt_mbedtls.c
+++ b/corelib/swupdate_decrypt_mbedtls.c
@@ -103,7 +103,9 @@  int swupdate_DECRYPT_final(struct swupdate_digest *dgst, unsigned char *buf,
 
 	error = mbedtls_cipher_finish(&dgst->mbedtls_cipher_context, buf, &olen);
 	if (error) {
+#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING
 		ERROR("mbedtls_cipher_finish: %d", error);
+#endif
 		return -EFAULT;
 	}
 	*outlen = olen;
diff --git a/corelib/swupdate_decrypt_pkcs11.c b/corelib/swupdate_decrypt_pkcs11.c
index 8a20ed4..63672c5 100644
--- a/corelib/swupdate_decrypt_pkcs11.c
+++ b/corelib/swupdate_decrypt_pkcs11.c
@@ -156,13 +156,17 @@  int swupdate_DECRYPT_final(struct swupdate_digest *dgst, unsigned char *buf, int
 {
 	unsigned char last_oct = dgst->last_decr[AES_BLK_SIZE - 1];
 	if (last_oct > AES_BLK_SIZE || last_oct == 0) {
+#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING
 		ERROR("AES: Invalid PKCS#7 padding.");
+#endif
 		return -EFAULT;
 	}
 
 	for (int i = 2; i <= last_oct; i++) {
 		if (dgst->last_decr[AES_BLK_SIZE - i] != last_oct) {
+#ifndef CONFIG_ENCRYPTED_IMAGES_HARDEN_LOGGING
 			ERROR("AES: Invalid PKCS#7 padding.");
+#endif
 			return -EFAULT;
 		}
 	}