bootutil/crypto: Add a crypto backend for SHA256 based on PSA Crypto APIs

This patch adds a dedicated crypto backend based on PSA Crypto APIs to
implement SHA-256 operations. The enabling of the backend is controlled
by the MCUBOOT_USE_PSA_CRYPTO define.

Signed-off-by: Antonio de Angelis <Antonio.deAngelis@arm.com>
Change-Id: I6065f7fccb483eda54f0190457f33aa89c6a0796
diff --git a/boot/bootutil/include/bootutil/crypto/sha256.h b/boot/bootutil/include/bootutil/crypto/sha256.h
index b45cd63..0bdef2e 100644
--- a/boot/bootutil/include/bootutil/crypto/sha256.h
+++ b/boot/bootutil/include/bootutil/crypto/sha256.h
@@ -3,50 +3,62 @@
  *
  * Copyright (c) 2017-2019 Linaro LTD
  * Copyright (c) 2017-2019 JUUL Labs
- * Copyright (c) 2021 Arm Limited
+ * Copyright (c) 2021-2023 Arm Limited
  */
 
 /*
  * This module provides a thin abstraction over some of the crypto
  * primitives to make it easier to swap out the used crypto library.
  *
- * At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or
- * MCUBOOT_USE_TINYCRYPT.  It is a compile error there is not exactly
- * one of these defined.
+ * At this point, the choices are: MCUBOOT_USE_MBED_TLS, MCUBOOT_USE_TINYCRYPT,
+ * MCUBOOT_USE_PSA_CRYPTO, MCUBOOT_USE_CC310. Note that support for MCUBOOT_USE_PSA_CRYPTO
+ * is still experimental and it might not support all the crypto abstractions
+ * that MCUBOOT_USE_MBED_TLS supports. For this reason, it's allowed to have
+ * both of them defined, and for crypto modules that support both abstractions,
+ * the MCUBOOT_USE_PSA_CRYPTO will take precedence.
  */
 
 #ifndef __BOOTUTIL_CRYPTO_SHA256_H_
 #define __BOOTUTIL_CRYPTO_SHA256_H_
 
 #include "mcuboot_config/mcuboot_config.h"
+#include "mcuboot_config/mcuboot_logging.h"
 
-#if (defined(MCUBOOT_USE_MBED_TLS) + \
+#if defined(MCUBOOT_USE_PSA_CRYPTO) || defined(MCUBOOT_USE_MBED_TLS)
+#define MCUBOOT_USE_PSA_OR_MBED_TLS
+#endif /* MCUBOOT_USE_PSA_CRYPTO || MCUBOOT_USE_MBED_TLS */
+
+#if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS) + \
      defined(MCUBOOT_USE_TINYCRYPT) + \
      defined(MCUBOOT_USE_CC310)) != 1
-    #error "One crypto backend must be defined: either CC310, MBED_TLS or TINYCRYPT"
+    #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO"
 #endif
 
-#if defined(MCUBOOT_USE_MBED_TLS)
-    #include <mbedtls/sha256.h>
-    #include <mbedtls/version.h>
-    #if MBEDTLS_VERSION_NUMBER >= 0x03000000
-        #include <mbedtls/compat-2.x.h>
-    #endif
-    #define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
-    #define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
+/* Universal defines for SHA-256 */
+#define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
+#define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
+
+#if defined(MCUBOOT_USE_PSA_CRYPTO)
+
+#include <psa/crypto.h>
+
+#elif defined(MCUBOOT_USE_MBED_TLS)
+
+#include <mbedtls/sha256.h>
+#include <mbedtls/version.h>
+#if MBEDTLS_VERSION_NUMBER >= 0x03000000
+#include <mbedtls/compat-2.x.h>
+#endif
+
 #endif /* MCUBOOT_USE_MBED_TLS */
 
 #if defined(MCUBOOT_USE_TINYCRYPT)
     #include <tinycrypt/sha256.h>
     #include <tinycrypt/constants.h>
-    #define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE TC_SHA256_BLOCK_SIZE
-    #define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE TC_SHA256_DIGEST_SIZE
 #endif /* MCUBOOT_USE_TINYCRYPT */
 
 #if defined(MCUBOOT_USE_CC310)
     #include <cc310_glue.h>
-    #define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
-    #define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
 #endif /* MCUBOOT_USE_CC310 */
 
 #include <stdint.h>
@@ -55,7 +67,42 @@
 extern "C" {
 #endif
 
-#if defined(MCUBOOT_USE_MBED_TLS)
+#if defined(MCUBOOT_USE_PSA_CRYPTO)
+
+typedef psa_hash_operation_t bootutil_sha256_context;
+
+static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
+{
+    *ctx = psa_hash_operation_init();
+    psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_256);
+    if (status != PSA_SUCCESS) {
+        MCUBOOT_LOG_ERR("Failed setting up a hash operation for PSA Crypto APIs");
+        while(1) {}
+    }
+}
+
+static inline void bootutil_sha256_drop(bootutil_sha256_context *ctx)
+{
+    (void)psa_hash_abort(ctx);
+}
+
+static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
+                                         const void *data,
+                                         uint32_t data_len)
+{
+    return (int)psa_hash_update(ctx, data, data_len);
+}
+
+static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
+                                          uint8_t *output)
+{
+    size_t hash_length = 0;
+    /* Assumes the output buffer is at least the expected size of the hash */
+    return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_256), &hash_length);
+}
+
+#elif defined(MCUBOOT_USE_MBED_TLS)
+
 typedef mbedtls_sha256_context bootutil_sha256_context;
 
 static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
@@ -83,6 +130,7 @@
 {
     return mbedtls_sha256_finish_ret(ctx, output);
 }
+
 #endif /* MCUBOOT_USE_MBED_TLS */
 
 #if defined(MCUBOOT_USE_TINYCRYPT)