Bootutil/Crypto: add encryption with mbedTLS
Signed-off-by: Bohdan Kovalchuk <bohd@cypress.com>
Signed-off-by: Roman Okhrimenko <roman.okhrimenko@infineon.com>
diff --git a/boot/bootutil/include/bootutil/crypto/ecdh_p256.h b/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
index 19d6a06..a37d50a 100644
--- a/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
+++ b/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
@@ -12,10 +12,17 @@
#include "mcuboot_config/mcuboot_config.h"
-#if (defined(MCUBOOT_USE_TINYCRYPT)) != 1
- #error "One crypto backend must be defined: TINYCRYPT"
+#if (defined(MCUBOOT_USE_MBED_TLS) + \
+ defined(MCUBOOT_USE_TINYCRYPT)) != 1
+ #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
#endif
+#if defined(MCUBOOT_USE_MBED_TLS)
+ #include <mbedtls/ecp.h>
+ #include <mbedtls/ecdh.h>
+ #define EC256_PUBK_LEN (65)
+#endif /* MCUBOOT_USE_MBED_TLS */
+
#if defined(MCUBOOT_USE_TINYCRYPT)
#include <tinycrypt/ecc_dh.h>
#include <tinycrypt/constants.h>
@@ -43,12 +50,16 @@
int rc;
(void)ctx;
- rc = uECC_valid_public_key(pk, uECC_secp256r1());
+ if (pk[0] != 0x04) {
+ return -1;
+ }
+
+ rc = uECC_valid_public_key(&pk[1], uECC_secp256r1());
if (rc != 0) {
return -1;
}
- rc = uECC_shared_secret(pk, sk, z, uECC_secp256r1());
+ rc = uECC_shared_secret(&pk[1], sk, z, uECC_secp256r1());
if (rc != TC_CRYPTO_SUCCESS) {
return -1;
}
@@ -56,6 +67,72 @@
}
#endif /* MCUBOOT_USE_TINYCRYPT */
+#if defined(MCUBOOT_USE_MBED_TLS)
+typedef struct bootutil_ecdh_p256_context {
+ mbedtls_ecp_group grp;
+ mbedtls_ecp_point P;
+ mbedtls_mpi z;
+ mbedtls_mpi d;
+} bootutil_ecdh_p256_context;
+
+static inline void bootutil_ecdh_p256_init(bootutil_ecdh_p256_context *ctx)
+{
+ mbedtls_mpi_init(&ctx->z);
+ mbedtls_mpi_init(&ctx->d);
+
+ mbedtls_ecp_group_init(&ctx->grp);
+ mbedtls_ecp_point_init(&ctx->P);
+
+ if (mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP256R1) != 0) {
+ mbedtls_ecp_group_free(&ctx->grp);
+ mbedtls_ecp_point_free(&ctx->P);
+ }
+}
+
+static inline void bootutil_ecdh_p256_drop(bootutil_ecdh_p256_context *ctx)
+{
+ mbedtls_mpi_free(&ctx->d);
+ mbedtls_mpi_free(&ctx->z);
+ mbedtls_ecp_group_free(&ctx->grp);
+ mbedtls_ecp_point_free(&ctx->P);
+}
+
+static inline int bootutil_ecdh_p256_shared_secret(bootutil_ecdh_p256_context *ctx, const uint8_t *pk, const uint8_t *sk, uint8_t *z)
+{
+ int rc;
+
+ rc = mbedtls_ecp_point_read_binary(&ctx->grp,
+ &ctx->P,
+ pk,
+ EC256_PUBK_LEN);
+ if (rc != 0) {
+ mbedtls_ecp_group_free(&ctx->grp);
+ mbedtls_ecp_point_free(&ctx->P);
+ return -1;
+ }
+
+ rc = mbedtls_ecp_check_pubkey(&ctx->grp, &ctx->P);
+ if (rc != 0) {
+ mbedtls_ecp_group_free(&ctx->grp);
+ mbedtls_ecp_point_free(&ctx->P);
+ return -1;
+ }
+
+ mbedtls_mpi_read_binary(&ctx->d, sk, NUM_ECC_BYTES);
+
+ rc = mbedtls_ecdh_compute_shared(&ctx->grp,
+ &ctx->z,
+ &ctx->P,
+ &ctx->d,
+ NULL,
+ NULL);
+
+ mbedtls_mpi_write_binary(&ctx->z, z, NUM_ECC_BYTES);
+
+ return rc;
+}
+#endif /* MCUBOOT_USE_MBED_TLS */
+
#ifdef __cplusplus
}
#endif
diff --git a/boot/bootutil/include/bootutil/crypto/hmac_sha256.h b/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
index c834124..49d372a 100644
--- a/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
+++ b/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
@@ -12,10 +12,19 @@
#include "mcuboot_config/mcuboot_config.h"
-#if (defined(MCUBOOT_USE_TINYCRYPT)) != 1
- #error "One crypto backend must be defined: TINYCRYPT"
+#if (defined(MCUBOOT_USE_MBED_TLS) + \
+ defined(MCUBOOT_USE_TINYCRYPT)) != 1
+ #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
#endif
+#if defined(MCUBOOT_USE_MBED_TLS)
+ #include <stdint.h>
+ #include <stddef.h>
+ #include <mbedtls/cmac.h>
+ #include <mbedtls/md.h>
+ #include <mbedtls/md_internal.h>
+#endif /* MCUBOOT_USE_MBED_TLS */
+
#if defined(MCUBOOT_USE_TINYCRYPT)
#include <tinycrypt/sha256.h>
#include <tinycrypt/utils.h>
@@ -76,6 +85,49 @@
}
#endif /* MCUBOOT_USE_TINYCRYPT */
+#if defined(MCUBOOT_USE_MBED_TLS)
+/**
+ * The generic message-digest context.
+ */
+typedef mbedtls_md_context_t bootutil_hmac_sha256_context;
+
+static inline void bootutil_hmac_sha256_init(bootutil_hmac_sha256_context *ctx)
+{
+ mbedtls_md_init(ctx);
+}
+
+static inline void bootutil_hmac_sha256_drop(bootutil_hmac_sha256_context *ctx)
+{
+ mbedtls_md_free(ctx);
+}
+
+static inline int bootutil_hmac_sha256_set_key(bootutil_hmac_sha256_context *ctx, const uint8_t *key, unsigned int key_size)
+{
+ int rc;
+
+ rc = mbedtls_md_setup(ctx, mbedtls_md_info_from_string("SHA256"), 1);
+ if (rc != 0) {
+ return rc;
+ }
+ rc = mbedtls_md_hmac_starts(ctx, key, key_size);
+ return rc;
+}
+
+static inline int bootutil_hmac_sha256_update(bootutil_hmac_sha256_context *ctx, const void *data, unsigned int data_length)
+{
+ return mbedtls_md_hmac_update(ctx, data, data_length);
+}
+
+static inline int bootutil_hmac_sha256_finish(bootutil_hmac_sha256_context *ctx, uint8_t *tag, unsigned int taglen)
+{
+ (void)taglen;
+ /*
+ * HMAC the key and check that our received MAC matches the generated tag
+ */
+ return mbedtls_md_hmac_finish(ctx, tag);
+}
+#endif /* MCUBOOT_USE_MBED_TLS */
+
#ifdef __cplusplus
}
#endif
diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c
index aff2d45..d14855b 100644
--- a/boot/bootutil/src/encrypted.c
+++ b/boot/bootutil/src/encrypted.c
@@ -437,7 +437,7 @@
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_KW128
#elif defined(MCUBOOT_ENCRYPT_EC256)
# define EXPECTED_ENC_TLV IMAGE_TLV_ENC_EC256
-# define EC_PUBK_INDEX (1)
+# define EC_PUBK_INDEX (0)
# define EC_TAG_INDEX (65)
# define EC_CIPHERKEY_INDEX (65 + 32)
_Static_assert(EC_CIPHERKEY_INDEX + 16 == EXPECTED_ENC_LEN,
@@ -526,11 +526,6 @@
return rc;
}
- /* is EC point uncompressed? */
- if (buf[0] != 0x04) {
- return -1;
- }
-
/*
* First "element" in the TLV is the curve point (public key)
*/
@@ -603,7 +598,7 @@
return -1;
}
- /* Assumes the tag bufer is at least sizeof(hmac_tag_size(state)) bytes */
+ /* Assumes the tag buffer is at least sizeof(hmac_tag_size(state)) bytes */
rc = bootutil_hmac_sha256_finish(&hmac, tag, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
if (rc != 0) {
(void)bootutil_hmac_sha256_drop(&hmac);