Abstracting mcuboot crypto functions for cleaner porting and less of an ifdef hell.
- The enc_context needs to initialize.
boot_enc_load seems to always be used to start the process, so calling
init inside makes sense.
- Handle boot_encrypt getting called with size of 0.
- No need to free contexts because Zephyr sets MBEDTLS_PLATFORM_NO_STD_FUNCTIONS.
I don't quite like this because it's implicit and will leak memory on
other ports.
Signed-off-by: Blaž Hrastnik <blaz@mxxn.io>
diff --git a/boot/bootutil/include/bootutil/crypto/aes_ctr.h b/boot/bootutil/include/bootutil/crypto/aes_ctr.h
new file mode 100644
index 0000000..bc82e15
--- /dev/null
+++ b/boot/bootutil/include/bootutil/crypto/aes_ctr.h
@@ -0,0 +1,150 @@
+/*
+ * 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.
+ */
+
+#ifndef __BOOTUTIL_CRYPTO_AES_CTR_H_
+#define __BOOTUTIL_CRYPTO_AES_CTR_H_
+
+#include <string.h>
+
+#include "mcuboot_config/mcuboot_config.h"
+
+#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/aes.h>
+ #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE (16)
+ #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16)
+#endif /* MCUBOOT_USE_MBED_TLS */
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+ #include <string.h>
+ #include <tinycrypt/aes.h>
+ #include <tinycrypt/ctr_mode.h>
+ #include <tinycrypt/constants.h>
+ #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE TC_AES_KEY_SIZE
+ #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE TC_AES_BLOCK_SIZE
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MCUBOOT_USE_MBED_TLS)
+typedef mbedtls_aes_context bootutil_aes_ctr_context;
+static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
+{
+ (void)mbedtls_aes_init(ctx);
+}
+
+static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
+{
+ /* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
+ /* (void)mbedtls_aes_free(ctx); */
+ (void)ctx;
+}
+
+static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
+{
+ return mbedtls_aes_setkey_enc(ctx, k, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE * 8);
+}
+
+static inline int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *m, uint32_t mlen, size_t blk_off, uint8_t *c)
+{
+ uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
+ int rc;
+ rc = mbedtls_aes_crypt_ctr(ctx, mlen, &blk_off, counter, stream_block, m, c);
+ memset(stream_block, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+ return rc;
+}
+
+static inline int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *c, uint32_t clen, size_t blk_off, uint8_t *m)
+{
+ uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
+ int rc;
+ rc = mbedtls_aes_crypt_ctr(ctx, clen, &blk_off, counter, stream_block, c, m);
+ memset(stream_block, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+ return rc;
+}
+#endif /* MCUBOOT_USE_MBED_TLS */
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+typedef struct tc_aes_key_sched_struct bootutil_aes_ctr_context;
+static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
+{
+ int rc;
+ rc = tc_aes128_set_encrypt_key(ctx, k);
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ return 0;
+}
+
+static int _bootutil_aes_ctr_crypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *in, uint32_t inlen, uint32_t blk_off, uint8_t *out)
+{
+ uint8_t buf[16];
+ uint32_t buflen;
+ int rc;
+ if (blk_off == 0) {
+ rc = tc_ctr_mode(out, inlen, in, inlen, counter, ctx);
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ } else if (blk_off < 16) {
+ buflen = ((inlen + blk_off <= 16) ? inlen : (16 - blk_off));
+ inlen -= buflen;
+ memcpy(&buf[blk_off], &in[0], buflen);
+ rc = tc_ctr_mode(buf, 16, buf, 16, counter, ctx);
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ memcpy(&out[0], &buf[blk_off], buflen);
+ memset(&buf[0], 0, 16);
+ if (inlen > 0) {
+ rc = tc_ctr_mode(&out[buflen], inlen, &in[buflen], inlen, counter, ctx);
+ }
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
+static inline int bootutil_aes_ctr_encrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *m, uint32_t mlen, uint32_t blk_off, uint8_t *c)
+{
+ return _bootutil_aes_ctr_crypt(ctx, counter, m, mlen, blk_off, c);
+}
+
+static inline int bootutil_aes_ctr_decrypt(bootutil_aes_ctr_context *ctx, uint8_t *counter, const uint8_t *c, uint32_t clen, uint32_t blk_off, uint8_t *m)
+{
+ return _bootutil_aes_ctr_crypt(ctx, counter, c, clen, blk_off, m);
+}
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOOTUTIL_CRYPTO_AES_CTR_H_ */
diff --git a/boot/bootutil/include/bootutil/crypto/aes_kw.h b/boot/bootutil/include/bootutil/crypto/aes_kw.h
new file mode 100644
index 0000000..925f46a
--- /dev/null
+++ b/boot/bootutil/include/bootutil/crypto/aes_kw.h
@@ -0,0 +1,141 @@
+/*
+ * 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.
+ */
+
+#ifndef __BOOTUTIL_CRYPTO_AES_KW_H_
+#define __BOOTUTIL_CRYPTO_AES_KW_H_
+
+#include "mcuboot_config/mcuboot_config.h"
+
+#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/aes.h>
+ #include <mbedtls/nist_kw.h>
+#endif /* MCUBOOT_USE_MBED_TLS */
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+ #include <tinycrypt/aes.h>
+ #include <tinycrypt/constants.h>
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MCUBOOT_USE_MBED_TLS)
+typedef mbedtls_nist_kw_context bootutil_aes_kw_context;
+static inline void bootutil_aes_kw_init(bootutil_aes_kw_context *ctx)
+{
+ (void)mbedtls_nist_kw_init(ctx);
+}
+
+static inline void bootutil_aes_kw_drop(bootutil_aes_kw_context *ctx)
+{
+ /* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
+ /* (void)mbedtls_aes_free(ctx); */
+ (void)ctx;
+}
+
+static inline int bootutil_aes_kw_set_unwrap_key(bootutil_aes_kw_context *ctx, const uint8_t *k, uint32_t klen)
+{
+ return mbedtls_nist_kw_setkey(ctx, MBEDTLS_CIPHER_ID_AES, k, klen * 8, 0);
+}
+
+static inline int bootutil_aes_kw_unwrap(bootutil_aes_kw_context *ctx, const uint8_t *wrapped_key, uint32_t wrapped_key_len, uint8_t *key, uint32_t key_len)
+{
+ size_t olen;
+ return mbedtls_nist_kw_unwrap(ctx, MBEDTLS_KW_MODE_KW, wrapped_key, wrapped_key_len, key, &olen, key_len);
+}
+#endif /* MCUBOOT_USE_MBED_TLS */
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+typedef struct tc_aes_key_sched_struct bootutil_aes_kw_context;
+static inline void bootutil_aes_kw_init(bootutil_aes_kw_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline void bootutil_aes_kw_drop(bootutil_aes_kw_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline int bootutil_aes_kw_set_unwrap_key(bootutil_aes_kw_context *ctx, const uint8_t *k, uint32_t klen)
+{
+ int rc;
+
+ if (klen != 16) {
+ return -1;
+ }
+
+ rc = tc_aes128_set_decrypt_key(ctx, k);
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Implements AES key unwrapping following RFC-3394 section 2.2.2, using
+ * tinycrypt for AES-128 decryption.
+ */
+static int bootutil_aes_kw_unwrap(bootutil_aes_kw_context *ctx, const uint8_t *wrapped_key, uint32_t wrapped_key_len, uint8_t *key, uint32_t key_len)
+{
+ uint8_t A[8];
+ uint8_t B[16];
+ int8_t i, j, k;
+
+ if (wrapped_key_len != 24 || key_len != 16) {
+ return -1;
+ }
+
+ for (k = 0; k < 8; k++) {
+ A[k] = wrapped_key[k];
+ key[k] = wrapped_key[8 + k];
+ key[8 + k] = wrapped_key[16 + k];
+ }
+
+ for (j = 5; j >= 0; j--) {
+ for (i = 2; i > 0; i--) {
+ for (k = 0; k < 8; k++) {
+ B[k] = A[k];
+ B[8 + k] = key[((i-1) * 8) + k];
+ }
+ B[7] ^= 2 * j + i;
+ if (tc_aes_decrypt((uint8_t *)&B, (uint8_t *)&B, ctx) != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ for (k = 0; k < 8; k++) {
+ A[k] = B[k];
+ key[((i-1) * 8) + k] = B[8 + k];
+ }
+ }
+ }
+
+ for (i = 0, k = 0; i < 8; i++) {
+ k |= A[i] ^ 0xa6;
+ }
+ if (k) {
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOOTUTIL_CRYPTO_AES_KW_H_ */
diff --git a/boot/bootutil/include/bootutil/crypto/ecdh_p256.h b/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
new file mode 100644
index 0000000..19d6a06
--- /dev/null
+++ b/boot/bootutil/include/bootutil/crypto/ecdh_p256.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#ifndef __BOOTUTIL_CRYPTO_ECDH_P256_H_
+#define __BOOTUTIL_CRYPTO_ECDH_P256_H_
+
+#include "mcuboot_config/mcuboot_config.h"
+
+#if (defined(MCUBOOT_USE_TINYCRYPT)) != 1
+ #error "One crypto backend must be defined: TINYCRYPT"
+#endif
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+ #include <tinycrypt/ecc_dh.h>
+ #include <tinycrypt/constants.h>
+ #define BOOTUTIL_CRYPTO_ECDH_P256_HASH_SIZE (4 * 8)
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+typedef uintptr_t bootutil_ecdh_p256_context;
+static inline void bootutil_ecdh_p256_init(bootutil_ecdh_p256_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline void bootutil_ecdh_p256_drop(bootutil_ecdh_p256_context *ctx)
+{
+ (void)ctx;
+}
+
+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;
+ (void)ctx;
+
+ rc = uECC_valid_public_key(pk, uECC_secp256r1());
+ if (rc != 0) {
+ return -1;
+ }
+
+ rc = uECC_shared_secret(pk, sk, z, uECC_secp256r1());
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ return 0;
+}
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOOTUTIL_CRYPTO_ECDH_P256_H_ */
diff --git a/boot/bootutil/include/bootutil/crypto/ecdh_x25519.h b/boot/bootutil/include/bootutil/crypto/ecdh_x25519.h
new file mode 100644
index 0000000..1d11b64
--- /dev/null
+++ b/boot/bootutil/include/bootutil/crypto/ecdh_x25519.h
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+#ifndef __BOOTUTIL_CRYPTO_ECDH_X25519_H_
+#define __BOOTUTIL_CRYPTO_ECDH_X25519_H_
+
+#include "mcuboot_config/mcuboot_config.h"
+
+#if (defined(MCUBOOT_USE_MBED_TLS) + \
+ defined(MCUBOOT_USE_TINYCRYPT)) != 1
+ #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MCUBOOT_USE_TINYCRYPT) || defined(MCUBOOT_USE_MBED_TLS)
+extern int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
+ const uint8_t peer_public_value[32]);
+
+typedef uintptr_t bootutil_ecdh_x25519_context;
+static inline void bootutil_ecdh_x25519_init(bootutil_ecdh_x25519_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline void bootutil_ecdh_x25519_drop(bootutil_ecdh_x25519_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline int bootutil_ecdh_x25519_shared_secret(bootutil_ecdh_x25519_context *ctx, const uint8_t *pk, const uint8_t *sk, uint8_t *z)
+{
+ int rc;
+ (void)ctx;
+
+ rc = X25519(z, sk, pk);
+ if (rc != 0) {
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOOTUTIL_CRYPTO_ECDH_X25519_H_ */
diff --git a/boot/bootutil/include/bootutil/crypto/ecdsa_p256.h b/boot/bootutil/include/bootutil/crypto/ecdsa_p256.h
new file mode 100644
index 0000000..a43b96e
--- /dev/null
+++ b/boot/bootutil/include/bootutil/crypto/ecdsa_p256.h
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+#ifndef __BOOTUTIL_CRYPTO_ECDSA_P256_H_
+#define __BOOTUTIL_CRYPTO_ECDSA_P256_H_
+
+#include "mcuboot_config/mcuboot_config.h"
+
+#if (defined(MCUBOOT_USE_TINYCRYPT) + \
+ defined(MCUBOOT_USE_CC310)) != 1
+ #error "One crypto backend must be defined: either CC310 or TINYCRYPT"
+#endif
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+ #include <tinycrypt/ecc_dsa.h>
+ #include <tinycrypt/constants.h>
+ #define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8)
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#if defined(MCUBOOT_USE_CC310)
+ #include <cc310_glue.h>
+ #define BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE (4 * 8)
+#endif /* MCUBOOT_USE_CC310 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+typedef uintptr_t bootutil_ecdsa_p256_context;
+static inline void bootutil_ecdsa_p256_init(bootutil_ecdsa_p256_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline void bootutil_ecdsa_p256_drop(bootutil_ecdsa_p256_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, const uint8_t *pk, const uint8_t *hash, const uint8_t *sig)
+{
+ int rc;
+ (void)ctx;
+ rc = uECC_verify(pk, hash, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE, sig, uECC_secp256r1());
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ return 0;
+}
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#if defined(MCUBOOT_USE_CC310)
+typedef uintptr_t bootutil_ecdsa_p256_context;
+static inline void bootutil_ecdsa_p256_init(bootutil_ecdsa_p256_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline void bootutil_ecdsa_p256_drop(bootutil_ecdsa_p256_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline int bootutil_ecdsa_p256_verify(bootutil_ecdsa_p256_context *ctx, const uint8_t *pk, const uint8_t *hash, const uint8_t *sig)
+{
+ (void)ctx;
+ return cc310_ecdsa_verify_secp256r1(hash, pk, sig, BOOTUTIL_CRYPTO_ECDSA_P256_HASH_SIZE);
+}
+#endif /* MCUBOOT_USE_CC310 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOOTUTIL_CRYPTO_ECDSA_P256_H_ */
diff --git a/boot/bootutil/include/bootutil/crypto/hmac_sha256.h b/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
new file mode 100644
index 0000000..c834124
--- /dev/null
+++ b/boot/bootutil/include/bootutil/crypto/hmac_sha256.h
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+#ifndef __BOOTUTIL_CRYPTO_HMAC_SHA256_H_
+#define __BOOTUTIL_CRYPTO_HMAC_SHA256_H_
+
+#include "mcuboot_config/mcuboot_config.h"
+
+#if (defined(MCUBOOT_USE_TINYCRYPT)) != 1
+ #error "One crypto backend must be defined: TINYCRYPT"
+#endif
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+ #include <tinycrypt/sha256.h>
+ #include <tinycrypt/utils.h>
+ #include <tinycrypt/constants.h>
+ #include <tinycrypt/hmac.h>
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+typedef struct tc_hmac_state_struct bootutil_hmac_sha256_context;
+static inline void bootutil_hmac_sha256_init(bootutil_hmac_sha256_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline void bootutil_hmac_sha256_drop(bootutil_hmac_sha256_context *ctx)
+{
+ (void)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 = tc_hmac_set_key(ctx, key, key_size);
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ rc = tc_hmac_init(ctx);
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ return 0;
+}
+
+static inline int bootutil_hmac_sha256_update(bootutil_hmac_sha256_context *ctx, const void *data, unsigned int data_length)
+{
+ int rc;
+ rc = tc_hmac_update(ctx, data, data_length);
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ return 0;
+}
+
+static inline int bootutil_hmac_sha256_finish(bootutil_hmac_sha256_context *ctx, uint8_t *tag, unsigned int taglen)
+{
+ int rc;
+ rc = tc_hmac_final(tag, taglen, ctx);
+ if (rc != TC_CRYPTO_SUCCESS) {
+ return -1;
+ }
+ return 0;
+}
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOOTUTIL_CRYPTO_HMAC_SHA256_H_ */
diff --git a/boot/bootutil/include/bootutil/crypto/sha256.h b/boot/bootutil/include/bootutil/crypto/sha256.h
new file mode 100644
index 0000000..00c3218
--- /dev/null
+++ b/boot/bootutil/include/bootutil/crypto/sha256.h
@@ -0,0 +1,141 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Copyright (c) 2017-2019 Linaro LTD
+ * Copyright (c) 2017-2019 JUUL Labs
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef __BOOTUTIL_CRYPTO_SHA256_H_
+#define __BOOTUTIL_CRYPTO_SHA256_H_
+
+#include "mcuboot_config/mcuboot_config.h"
+
+#if (defined(MCUBOOT_USE_MBED_TLS) + \
+ defined(MCUBOOT_USE_TINYCRYPT) + \
+ defined(MCUBOOT_USE_CC310)) != 1
+ #error "One crypto backend must be defined: either CC310, MBED_TLS or TINYCRYPT"
+#endif
+
+#if defined(MCUBOOT_USE_MBED_TLS)
+ #include <mbedtls/sha256.h>
+ #define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
+ #define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
+#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>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(MCUBOOT_USE_MBED_TLS)
+typedef mbedtls_sha256_context bootutil_sha256_context;
+
+static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
+{
+ mbedtls_sha256_init(ctx);
+ (void)mbedtls_sha256_starts_ret(ctx, 0);
+}
+
+static inline void bootutil_sha256_drop(bootutil_sha256_context *ctx)
+{
+ /* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
+ /* (void)mbedtls_sha256_free(ctx); */
+ (void)ctx;
+}
+
+static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
+ const void *data,
+ uint32_t data_len)
+{
+ return mbedtls_sha256_update_ret(ctx, data, data_len);
+}
+
+static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
+ uint8_t *output)
+{
+ return mbedtls_sha256_finish_ret(ctx, output);
+}
+#endif /* MCUBOOT_USE_MBED_TLS */
+
+#if defined(MCUBOOT_USE_TINYCRYPT)
+typedef struct tc_sha256_state_struct bootutil_sha256_context;
+static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
+{
+ tc_sha256_init(ctx);
+}
+
+static inline void bootutil_sha256_drop(bootutil_sha256_context *ctx)
+{
+ (void)ctx;
+}
+
+static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
+ const void *data,
+ uint32_t data_len)
+{
+ return tc_sha256_update(ctx, data, data_len);
+}
+
+static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
+ uint8_t *output)
+{
+ return tc_sha256_final(output, ctx);
+}
+#endif /* MCUBOOT_USE_TINYCRYPT */
+
+#if defined(MCUBOOT_USE_CC310)
+static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
+{
+ cc310_sha256_init(ctx);
+}
+
+static inline void bootutil_sha256_drop(bootutil_sha256_context *ctx)
+{
+ (void)ctx;
+ nrf_cc310_disable();
+}
+
+static inline int bootutil_sha256_update(bootutil_sha256_context *ctx,
+ const void *data,
+ uint32_t data_len)
+{
+ cc310_sha256_update(ctx, data, data_len);
+ return 0;
+}
+
+static inline int bootutil_sha256_finish(bootutil_sha256_context *ctx,
+ uint8_t *output)
+{
+ cc310_sha256_finalize(ctx, output);
+ return 0;
+}
+#endif /* MCUBOOT_USE_CC310 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __BOOTUTIL_CRYPTO_SHA256_H_ */
diff --git a/boot/bootutil/include/bootutil/enc_key.h b/boot/bootutil/include/bootutil/enc_key.h
index fbe90c3..bcbe897 100644
--- a/boot/bootutil/include/bootutil/enc_key.h
+++ b/boot/bootutil/include/bootutil/enc_key.h
@@ -30,15 +30,9 @@
#include <stdbool.h>
#include <stdint.h>
#include <flash_map_backend/flash_map_backend.h>
-#include "mcuboot_config/mcuboot_config.h"
+#include "bootutil/crypto/aes_ctr.h"
#include "bootutil/image.h"
-#if defined(MCUBOOT_USE_MBED_TLS)
-#include "mbedtls/aes.h"
-#else
-#include "tinycrypt/aes.h"
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -66,16 +60,14 @@
struct enc_key_data {
uint8_t valid;
-#if defined(MCUBOOT_USE_MBED_TLS)
- mbedtls_aes_context aes;
-#else
- struct tc_aes_key_sched_struct aes;
-#endif
+ bootutil_aes_ctr_context aes_ctr;
};
extern const struct bootutil_key bootutil_enc_key;
struct boot_status;
+int boot_enc_init(struct enc_key_data *enc_state, uint8_t slot);
+int boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot);
int boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot,
const struct boot_status *bs);
int boot_enc_load(struct enc_key_data *enc_state, int image_index,
diff --git a/boot/bootutil/include/bootutil/sha256.h b/boot/bootutil/include/bootutil/sha256.h
deleted file mode 100644
index f34d2b7..0000000
--- a/boot/bootutil/include/bootutil/sha256.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * SPDX-License-Identifier: Apache-2.0
- *
- * Copyright (c) 2017-2019 Linaro LTD
- * Copyright (c) 2017-2019 JUUL Labs
- */
-
-/*
- * 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.
- */
-
-#ifndef __BOOTUTIL_CRYPTO_H_
-#define __BOOTUTIL_CRYPTO_H_
-
-#include "mcuboot_config/mcuboot_config.h"
-
-#if (defined(MCUBOOT_USE_MBED_TLS) + \
- defined(MCUBOOT_USE_TINYCRYPT) + \
- defined(MCUBOOT_USE_CC310)) != 1
- #error "One crypto backend must be defined either CC310, MBED_TLS or TINYCRYPT"
-#endif
-
-#ifdef MCUBOOT_USE_MBED_TLS
- #include <mbedtls/sha256.h>
-#endif /* MCUBOOT_USE_MBED_TLS */
-
-#ifdef MCUBOOT_USE_TINYCRYPT
- #include <tinycrypt/sha256.h>
-#endif /* MCUBOOT_USE_TINYCRYPT */
-
-#ifdef MCUBOOT_USE_CC310
- #include <cc310_glue.h>
-#endif /* MCUBOOT_USE_CC310 */
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef MCUBOOT_USE_MBED_TLS
-typedef mbedtls_sha256_context bootutil_sha256_context;
-
-static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
-{
- mbedtls_sha256_init(ctx);
- (void)mbedtls_sha256_starts_ret(ctx, 0);
-}
-
-static inline void bootutil_sha256_update(bootutil_sha256_context *ctx,
- const void *data,
- uint32_t data_len)
-{
- (void)mbedtls_sha256_update_ret(ctx, data, data_len);
-}
-
-static inline void bootutil_sha256_finish(bootutil_sha256_context *ctx,
- uint8_t *output)
-{
- (void)mbedtls_sha256_finish_ret(ctx, output);
-}
-#endif /* MCUBOOT_USE_MBED_TLS */
-
-#ifdef MCUBOOT_USE_TINYCRYPT
-typedef struct tc_sha256_state_struct bootutil_sha256_context;
-static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
-{
- tc_sha256_init(ctx);
-}
-
-static inline void bootutil_sha256_update(bootutil_sha256_context *ctx,
- const void *data,
- uint32_t data_len)
-{
- tc_sha256_update(ctx, data, data_len);
-}
-
-static inline void bootutil_sha256_finish(bootutil_sha256_context *ctx,
- uint8_t *output)
-{
- tc_sha256_final(output, ctx);
-}
-#endif /* MCUBOOT_USE_TINYCRYPT */
-
-#ifdef MCUBOOT_USE_CC310
-static inline void bootutil_sha256_init(bootutil_sha256_context *ctx)
-{
- cc310_sha256_init(ctx);
-}
-
-static inline void bootutil_sha256_update(bootutil_sha256_context *ctx,
- const void *data,
- uint32_t data_len)
-{
- cc310_sha256_update(ctx, data, data_len);
-}
-
-static inline void bootutil_sha256_finish(bootutil_sha256_context *ctx,
- uint8_t *output)
-{
- cc310_sha256_finalize(ctx, output);
-}
-#endif /* MCUBOOT_USE_CC310 */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __BOOTUTIL_SIGN_KEY_H_ */
diff --git a/boot/bootutil/src/encrypted.c b/boot/bootutil/src/encrypted.c
index b62a31e..aff2d45 100644
--- a/boot/bootutil/src/encrypted.c
+++ b/boot/bootutil/src/encrypted.c
@@ -19,24 +19,20 @@
#endif
#if defined(MCUBOOT_ENCRYPT_KW)
-# if defined(MCUBOOT_USE_MBED_TLS)
-# include "mbedtls/nist_kw.h"
-# include "mbedtls/aes.h"
-# else
-# include "tinycrypt/aes.h"
-# endif
+#include "bootutil/crypto/aes_kw.h"
#endif
#if defined(MCUBOOT_ENCRYPT_EC256)
-#include "tinycrypt/ecc.h"
-#include "tinycrypt/ecc_dh.h"
+#include "bootutil/crypto/ecdh_p256.h"
+#endif
+
+#if defined(MCUBOOT_ENCRYPT_X25519)
+#include "bootutil/crypto/ecdh_x25519.h"
#endif
#if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
-#include "tinycrypt/utils.h"
-#include "tinycrypt/constants.h"
-#include "tinycrypt/ctr_mode.h"
-#include "tinycrypt/hmac.h"
+#include "bootutil/crypto/sha256.h"
+#include "bootutil/crypto/hmac_sha256.h"
#include "mbedtls/oid.h"
#include "mbedtls/asn1.h"
#endif
@@ -47,79 +43,49 @@
#include "bootutil_priv.h"
+#if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
+#if defined(_compare)
+static inline int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size)
+{
+ return _compare(a, b, size);
+}
+#else
+static int bootutil_constant_time_compare(const uint8_t *a, const uint8_t *b, size_t size)
+{
+ const uint8_t *tempa = a;
+ const uint8_t *tempb = b;
+ uint8_t result = 0;
+ unsigned int i;
+
+ for (i = 0; i < size; i++) {
+ result |= tempa[i] ^ tempb[i];
+ }
+ return result;
+}
+#endif
+#endif
+
#if defined(MCUBOOT_ENCRYPT_KW)
-#if defined(MCUBOOT_USE_MBED_TLS)
static int
key_unwrap(const uint8_t *wrapped, uint8_t *enckey)
{
- mbedtls_nist_kw_context kw;
+ bootutil_aes_kw_context aes_kw;
int rc;
- size_t olen;
- mbedtls_nist_kw_init(&kw);
-
- rc = mbedtls_nist_kw_setkey(&kw, MBEDTLS_CIPHER_ID_AES,
- bootutil_enc_key.key, *bootutil_enc_key.len * 8, 0);
- if (rc) {
+ bootutil_aes_kw_init(&aes_kw);
+ rc = bootutil_aes_kw_set_unwrap_key(&aes_kw, bootutil_enc_key.key, *bootutil_enc_key.len);
+ if (rc != 0) {
+ goto done;
+ }
+ rc = bootutil_aes_kw_unwrap(&aes_kw, wrapped, TLV_ENC_KW_SZ, enckey, BOOT_ENC_KEY_SIZE);
+ if (rc != 0) {
goto done;
}
- rc = mbedtls_nist_kw_unwrap(&kw, MBEDTLS_KW_MODE_KW, wrapped, TLV_ENC_KW_SZ,
- enckey, &olen, BOOT_ENC_KEY_SIZE);
-
done:
- mbedtls_nist_kw_free(&kw);
+ bootutil_aes_kw_drop(&aes_kw);
return rc;
}
-#else /* !MCUBOOT_USE_MBED_TLS */
-/*
- * Implements AES key unwrapping following RFC-3394 section 2.2.2, using
- * tinycrypt for AES-128 decryption.
- */
-static int
-key_unwrap(const uint8_t *wrapped, uint8_t *enckey)
-{
- struct tc_aes_key_sched_struct aes;
- uint8_t A[8];
- uint8_t B[16];
- int8_t i, j, k;
-
- if (tc_aes128_set_decrypt_key(&aes, bootutil_enc_key.key) == 0) {
- return -1;
- }
-
- for (k = 0; k < 8; k++) {
- A[k] = wrapped[k];
- enckey[k] = wrapped[8 + k];
- enckey[8 + k] = wrapped[16 + k];
- }
-
- for (j = 5; j >= 0; j--) {
- for (i = 2; i > 0; i--) {
- for (k = 0; k < 8; k++) {
- B[k] = A[k];
- B[8 + k] = enckey[((i-1) * 8) + k];
- }
- B[7] ^= 2 * j + i;
- if (tc_aes_decrypt((uint8_t *)&B, (uint8_t *)&B, &aes) == 0) {
- return -1;
- }
- for (k = 0; k < 8; k++) {
- A[k] = B[k];
- enckey[((i-1) * 8) + k] = B[8 + k];
- }
- }
- }
-
- for (i = 0, k = 0; i < 8; i++) {
- k |= A[i] ^ 0xa6;
- }
- if (k) {
- return -1;
- }
- return 0;
-}
-#endif /* MCUBOOT_USE_MBED_TLS */
#endif /* MCUBOOT_ENCRYPT_KW */
#if defined(MCUBOOT_ENCRYPT_RSA)
@@ -198,7 +164,7 @@
* curve keypair. See RFC5208 and RFC5915.
*/
static int
-parse_ec256_enckey(uint8_t **p, uint8_t *end, uint8_t *pk)
+parse_ec256_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
{
int rc;
size_t len;
@@ -259,7 +225,7 @@
return -12;
}
- memcpy(pk, *p, len);
+ memcpy(private_key, *p, len);
/* publicKey usually follows but is not parsed here */
@@ -272,14 +238,11 @@
static const uint8_t ec_pubkey_oid[] = MBEDTLS_OID_ISO_IDENTIFIED_ORG \
MBEDTLS_OID_ORG_GOV X25519_OID;
-extern int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32],
- const uint8_t peer_public_value[32]);
-
#define SHARED_KEY_LEN 32
#define PRIV_KEY_LEN 32
static int
-parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *pk)
+parse_x25519_enckey(uint8_t **p, uint8_t *end, uint8_t *private_key)
{
size_t len;
int version;
@@ -321,7 +284,7 @@
return -8;
}
- memcpy(pk, *p, PRIV_KEY_LEN);
+ memcpy(private_key, *p, PRIV_KEY_LEN);
return 0;
}
#endif /* defined(MCUBOOT_ENCRYPT_X25519) */
@@ -341,10 +304,10 @@
hkdf(uint8_t *ikm, uint16_t ikm_len, uint8_t *info, uint16_t info_len,
uint8_t *okm, uint16_t *okm_len)
{
- struct tc_hmac_state_struct hmac;
- uint8_t salt[TC_SHA256_DIGEST_SIZE];
- uint8_t prk[TC_SHA256_DIGEST_SIZE];
- uint8_t T[TC_SHA256_DIGEST_SIZE];
+ bootutil_hmac_sha256_context hmac;
+ uint8_t salt[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
+ uint8_t prk[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
+ uint8_t T[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
uint16_t off;
uint16_t len;
uint8_t counter;
@@ -359,25 +322,22 @@
return -1;
}
- memset(salt, 0, TC_SHA256_DIGEST_SIZE);
- rc = tc_hmac_set_key(&hmac, salt, TC_SHA256_DIGEST_SIZE);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
+ bootutil_hmac_sha256_init(&hmac);
+
+ memset(salt, 0, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
+ rc = bootutil_hmac_sha256_set_key(&hmac, salt, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
+ if (rc != 0) {
+ goto error;
}
- rc = tc_hmac_init(&hmac);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
+ rc = bootutil_hmac_sha256_update(&hmac, ikm, ikm_len);
+ if (rc != 0) {
+ goto error;
}
- rc = tc_hmac_update(&hmac, ikm, ikm_len);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
- }
-
- rc = tc_hmac_final(prk, TC_SHA256_DIGEST_SIZE, &hmac);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
+ rc = bootutil_hmac_sha256_finish(&hmac, prk, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
+ if (rc != 0) {
+ goto error;
}
/*
@@ -387,74 +347,82 @@
len = *okm_len;
counter = 1;
first = true;
- for (off = 0; len > 0; off += TC_SHA256_DIGEST_SIZE, ++counter) {
- rc = tc_hmac_set_key(&hmac, prk, TC_SHA256_DIGEST_SIZE);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
- }
+ for (off = 0; len > 0; off += BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE, ++counter) {
+ bootutil_hmac_sha256_init(&hmac);
- rc = tc_hmac_init(&hmac);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
+ rc = bootutil_hmac_sha256_set_key(&hmac, prk, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
+ if (rc != 0) {
+ goto error;
}
if (first) {
first = false;
} else {
- rc = tc_hmac_update(&hmac, T, TC_SHA256_DIGEST_SIZE);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
+ rc = bootutil_hmac_sha256_update(&hmac, T, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
+ if (rc != 0) {
+ goto error;
}
}
- rc = tc_hmac_update(&hmac, info, info_len);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
+ rc = bootutil_hmac_sha256_update(&hmac, info, info_len);
+ if (rc != 0) {
+ goto error;
}
- rc = tc_hmac_update(&hmac, &counter, 1);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
+ rc = bootutil_hmac_sha256_update(&hmac, &counter, 1);
+ if (rc != 0) {
+ goto error;
}
- rc = tc_hmac_final(T, TC_SHA256_DIGEST_SIZE, &hmac);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
+ rc = bootutil_hmac_sha256_finish(&hmac, T, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
+ if (rc != 0) {
+ goto error;
}
- if (len > TC_SHA256_DIGEST_SIZE) {
- memcpy(&okm[off], T, TC_SHA256_DIGEST_SIZE);
- len -= TC_SHA256_DIGEST_SIZE;
+ if (len > BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE) {
+ memcpy(&okm[off], T, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
+ len -= BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE;
} else {
memcpy(&okm[off], T, len);
len = 0;
}
}
+ bootutil_hmac_sha256_drop(&hmac);
return 0;
+
+error:
+ bootutil_hmac_sha256_drop(&hmac);
+ return -1;
}
#endif
int
+boot_enc_init(struct enc_key_data *enc_state, uint8_t slot)
+{
+ bootutil_aes_ctr_init(&enc_state[slot].aes_ctr);
+ return 0;
+}
+
+int
+boot_enc_drop(struct enc_key_data *enc_state, uint8_t slot)
+{
+ bootutil_aes_ctr_drop(&enc_state[slot].aes_ctr);
+ return 0;
+}
+
+int
boot_enc_set_key(struct enc_key_data *enc_state, uint8_t slot,
const struct boot_status *bs)
{
int rc;
-#if defined(MCUBOOT_USE_MBED_TLS)
- mbedtls_aes_init(&enc_state[slot].aes);
- rc = mbedtls_aes_setkey_enc(&enc_state[slot].aes, bs->enckey[slot],
- BOOT_ENC_KEY_SIZE_BITS);
- if (rc) {
- mbedtls_aes_free(&enc_state[slot].aes);
+ rc = bootutil_aes_ctr_set_key(&enc_state[slot].aes_ctr, bs->enckey[slot]);
+ if (rc != 0) {
+ boot_enc_drop(enc_state, slot);
+ enc_state[slot].valid = 0;
return -1;
}
-#else
- (void)rc;
-
- /* set_encrypt and set_decrypt do the same thing in tinycrypt */
- tc_aes128_set_encrypt_key(&enc_state[slot].aes, bs->enckey[slot]);
-#endif
enc_state[slot].valid = 1;
@@ -498,16 +466,22 @@
uint8_t *cpend;
size_t olen;
#endif
+#if defined(MCUBOOT_ENCRYPT_EC256)
+ bootutil_ecdh_p256_context ecdh_p256;
+#endif
+#if defined(MCUBOOT_ENCRYPT_X25519)
+ bootutil_ecdh_x25519_context ecdh_x25519;
+#endif
#if defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519)
- struct tc_hmac_state_struct hmac;
- struct tc_aes_key_sched_struct aes;
- uint8_t tag[TC_SHA256_DIGEST_SIZE];
+ bootutil_hmac_sha256_context hmac;
+ bootutil_aes_ctr_context aes_ctr;
+ uint8_t tag[BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
uint8_t shared[SHARED_KEY_LEN];
- uint8_t derived_key[TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE];
+ uint8_t derived_key[BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE];
uint8_t *cp;
uint8_t *cpend;
- uint8_t pk[PRIV_KEY_LEN];
- uint8_t counter[TC_AES_BLOCK_SIZE];
+ uint8_t private_key[PRIV_KEY_LEN];
+ uint8_t counter[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
uint16_t len;
#endif
int rc = -1;
@@ -547,7 +521,7 @@
* Load the stored EC256 decryption private key
*/
- rc = parse_ec256_enckey(&cp, cpend, pk);
+ rc = parse_ec256_enckey(&cp, cpend, private_key);
if (rc) {
return rc;
}
@@ -560,13 +534,11 @@
/*
* First "element" in the TLV is the curve point (public key)
*/
- rc = uECC_valid_public_key(&buf[EC_PUBK_INDEX], uECC_secp256r1());
- if (rc != 0) {
- return -1;
- }
+ bootutil_ecdh_p256_init(&ecdh_p256);
- rc = uECC_shared_secret(&buf[EC_PUBK_INDEX], pk, shared, uECC_secp256r1());
- if (rc != TC_CRYPTO_SUCCESS) {
+ rc = bootutil_ecdh_p256_shared_secret(&ecdh_p256, &buf[EC_PUBK_INDEX], private_key, shared);
+ bootutil_ecdh_p256_drop(&ecdh_p256);
+ if (rc != 0) {
return -1;
}
@@ -581,7 +553,7 @@
* Load the stored X25519 decryption private key
*/
- rc = parse_x25519_enckey(&cp, cpend, pk);
+ rc = parse_x25519_enckey(&cp, cpend, private_key);
if (rc) {
return rc;
}
@@ -590,7 +562,10 @@
* First "element" in the TLV is the curve point (public key)
*/
- rc = X25519(shared, pk, &buf[EC_PUBK_INDEX]);
+ bootutil_ecdh_x25519_init(&ecdh_x25519);
+
+ rc = bootutil_ecdh_x25519_shared_secret(&ecdh_x25519, &buf[EC_PUBK_INDEX], private_key, shared);
+ bootutil_ecdh_x25519_drop(&ecdh_x25519);
if (!rc) {
return -1;
}
@@ -603,10 +578,10 @@
* Expand shared secret to create keys for AES-128-CTR + HMAC-SHA256
*/
- len = TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE;
+ len = BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE;
rc = hkdf(shared, SHARED_KEY_LEN, (uint8_t *)"MCUBoot_ECIES_v1", 16,
derived_key, &len);
- if (rc != 0 || len != (TC_AES_KEY_SIZE + TC_SHA256_DIGEST_SIZE)) {
+ if (rc != 0 || len != (BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE + BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE)) {
return -1;
}
@@ -614,47 +589,59 @@
* HMAC the key and check that our received MAC matches the generated tag
*/
- rc = tc_hmac_set_key(&hmac, &derived_key[16], 32);
- if (rc != TC_CRYPTO_SUCCESS) {
+ bootutil_hmac_sha256_init(&hmac);
+
+ rc = bootutil_hmac_sha256_set_key(&hmac, &derived_key[16], 32);
+ if (rc != 0) {
+ (void)bootutil_hmac_sha256_drop(&hmac);
return -1;
}
- rc = tc_hmac_init(&hmac);
- if (rc != TC_CRYPTO_SUCCESS) {
- return -1;
- }
-
- rc = tc_hmac_update(&hmac, &buf[EC_CIPHERKEY_INDEX], 16);
- if (rc != TC_CRYPTO_SUCCESS) {
+ rc = bootutil_hmac_sha256_update(&hmac, &buf[EC_CIPHERKEY_INDEX], 16);
+ if (rc != 0) {
+ (void)bootutil_hmac_sha256_drop(&hmac);
return -1;
}
/* Assumes the tag bufer is at least sizeof(hmac_tag_size(state)) bytes */
- rc = tc_hmac_final(tag, TC_SHA256_DIGEST_SIZE, &hmac);
- if (rc != TC_CRYPTO_SUCCESS) {
+ rc = bootutil_hmac_sha256_finish(&hmac, tag, BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE);
+ if (rc != 0) {
+ (void)bootutil_hmac_sha256_drop(&hmac);
return -1;
}
- if (_compare(tag, &buf[EC_TAG_INDEX], 32) != 0) {
+ if (bootutil_constant_time_compare(tag, &buf[EC_TAG_INDEX], 32) != 0) {
+ (void)bootutil_hmac_sha256_drop(&hmac);
return -1;
}
+ bootutil_hmac_sha256_drop(&hmac);
+
/*
* Finally decrypt the received ciphered key
*/
- rc = tc_aes128_set_decrypt_key(&aes, derived_key);
- if (rc != TC_CRYPTO_SUCCESS) {
+ bootutil_aes_ctr_init(&aes_ctr);
+ if (rc != 0) {
+ bootutil_aes_ctr_drop(&aes_ctr);
return -1;
}
- memset(counter, 0, TC_AES_BLOCK_SIZE);
- rc = tc_ctr_mode(enckey, TC_AES_KEY_SIZE, &buf[EC_CIPHERKEY_INDEX],
- TC_AES_KEY_SIZE, counter, &aes);
- if (rc != TC_CRYPTO_SUCCESS) {
+ rc = bootutil_aes_ctr_set_key(&aes_ctr, derived_key);
+ if (rc != 0) {
+ bootutil_aes_ctr_drop(&aes_ctr);
return -1;
}
+ memset(counter, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE);
+ rc = bootutil_aes_ctr_decrypt(&aes_ctr, counter, &buf[EC_CIPHERKEY_INDEX], BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE, 0, enckey);
+ if (rc != 0) {
+ bootutil_aes_ctr_drop(&aes_ctr);
+ return -1;
+ }
+
+ bootutil_aes_ctr_drop(&aes_ctr);
+
rc = 0;
#endif /* defined(MCUBOOT_ENCRYPT_EC256) || defined(MCUBOOT_ENCRYPT_X25519) */
@@ -692,6 +679,9 @@
return 1;
}
+ /* Initialize the AES context */
+ boot_enc_init(enc_state, slot);
+
rc = bootutil_tlv_iter_begin(&it, hdr, fap, EXPECTED_ENC_TLV, false);
if (rc) {
return -1;
@@ -741,12 +731,15 @@
uint32_t blk_off, uint8_t *buf)
{
struct enc_key_data *enc;
- uint32_t i, j;
- uint8_t u8;
uint8_t nonce[16];
- uint8_t blk[16];
int rc;
+ /* boot_copy_region will call boot_encrypt with sz = 0 when skipping over
+ the TLVs. */
+ if (sz == 0) {
+ return;
+ }
+
memset(nonce, 0, 12);
off >>= 4;
nonce[12] = (uint8_t)(off >> 24);
@@ -762,25 +755,7 @@
enc = &enc_state[rc];
assert(enc->valid == 1);
- for (i = 0; i < sz; i++) {
- if (i == 0 || blk_off == 0) {
-#if defined(MCUBOOT_USE_MBED_TLS)
- mbedtls_aes_crypt_ecb(&enc->aes, MBEDTLS_AES_ENCRYPT, nonce, blk);
-#else
- tc_aes_encrypt(blk, nonce, &enc->aes);
-#endif
-
- for (j = 16; j > 0; --j) {
- if (++nonce[j - 1] != 0) {
- break;
- }
- }
- }
-
- u8 = *buf;
- *buf++ = u8 ^ blk[blk_off];
- blk_off = (blk_off + 1) & 0x0f;
- }
+ bootutil_aes_ctr_encrypt(&enc->aes_ctr, nonce, buf, sz, blk_off, buf);
}
/**
@@ -789,6 +764,10 @@
void
boot_enc_zeroize(struct enc_key_data *enc_state)
{
+ uint8_t slot;
+ for (slot = 0; slot < BOOT_NUM_SLOTS; slot++) {
+ (void)boot_enc_drop(enc_state, slot);
+ }
memset(enc_state, 0, sizeof(struct enc_key_data) * BOOT_NUM_SLOTS);
}
diff --git a/boot/bootutil/src/image_ec256.c b/boot/bootutil/src/image_ec256.c
index 84ece6a..ef99381 100644
--- a/boot/bootutil/src/image_ec256.c
+++ b/boot/bootutil/src/image_ec256.c
@@ -33,14 +33,7 @@
#include "mbedtls/oid.h"
#include "mbedtls/asn1.h"
-
-#ifdef MCUBOOT_USE_TINYCRYPT
-#include "tinycrypt/ecc_dsa.h"
-#endif
-#ifdef MCUBOOT_USE_CC310
-#include "cc310_glue.h"
-#define NUM_ECC_BYTES (4*8)
-#endif
+#include "bootutil/crypto/ecdsa_p256.h"
#include "bootutil_priv.h"
/*
@@ -96,6 +89,7 @@
}
(*cp)++;
+
return 0;
}
@@ -151,12 +145,12 @@
return 0;
}
-#ifdef MCUBOOT_USE_TINYCRYPT
int
bootutil_verify_sig(uint8_t *hash, uint32_t hlen, uint8_t *sig, size_t slen,
uint8_t key_id)
{
int rc;
+ bootutil_ecdsa_p256_context ctx;
uint8_t *pubkey;
uint8_t *end;
@@ -182,56 +176,10 @@
return -1;
}
- rc = uECC_verify(pubkey, hash, NUM_ECC_BYTES, signature, uECC_secp256r1());
- if (rc == 1) {
- return 0;
- } else {
- return -2;
- }
-}
-#endif /* MCUBOOT_USE_TINYCRYPT */
-#ifdef MCUBOOT_USE_CC310
-int
-bootutil_verify_sig(uint8_t *hash,
- uint32_t hlen,
- uint8_t *sig,
- size_t slen,
- uint8_t key_id)
-{
- int rc;
- uint8_t *pubkey;
- uint8_t *end;
- uint8_t signature[2 * NUM_ECC_BYTES];
-
- pubkey = (uint8_t *)bootutil_keys[key_id].key;
- end = pubkey + *bootutil_keys[key_id].len;
-
- rc = bootutil_import_key(&pubkey, end);
- if (rc) {
- return -1;
- }
-
- /* Decode signature */
- rc = bootutil_decode_sig(signature, sig, sig + slen);
- if (rc) {
- return -1;
- }
-
- /*
- * This is simplified, as the hash length is also 32 bytes.
- */
- if (hlen != NUM_ECC_BYTES) {
- return -1;
- }
-
- /* Initialize and verify in one go */
- rc = cc310_ecdsa_verify_secp256r1(hash, pubkey, signature, hlen);
-
- if (rc != 0) {
- return -2;
- }
-
+ bootutil_ecdsa_p256_init(&ctx);
+ rc = bootutil_ecdsa_p256_verify(&ctx, pubkey, hash, signature);
+ bootutil_ecdsa_p256_drop(&ctx);
return rc;
}
-#endif /* MCUBOOT_USE_CC310 */
+
#endif /* MCUBOOT_SIGN_EC256 */
diff --git a/boot/bootutil/src/image_rsa.c b/boot/bootutil/src/image_rsa.c
index e36b8ba..a94de5c 100644
--- a/boot/bootutil/src/image_rsa.c
+++ b/boot/bootutil/src/image_rsa.c
@@ -30,7 +30,7 @@
#ifdef MCUBOOT_SIGN_RSA
#include "bootutil/sign_key.h"
-#include "bootutil/sha256.h"
+#include "bootutil/crypto/sha256.h"
#include "mbedtls/rsa.h"
#include "mbedtls/asn1.h"
@@ -148,6 +148,8 @@
mask += bytes;
count -= bytes;
}
+
+ bootutil_sha256_drop(&ctx);
}
/*
@@ -260,6 +262,7 @@
bootutil_sha256_update(&shactx, hash, PSS_HLEN);
bootutil_sha256_update(&shactx, &db_mask[PSS_MASK_SALT_POS], PSS_SLEN);
bootutil_sha256_finish(&shactx, h2);
+ bootutil_sha256_drop(&shactx);
/* Step 14. If H = H', output "consistent". Otherwise, output
* "inconsistent". */
diff --git a/boot/bootutil/src/image_validate.c b/boot/bootutil/src/image_validate.c
index b5d259a..8865bb4 100644
--- a/boot/bootutil/src/image_validate.c
+++ b/boot/bootutil/src/image_validate.c
@@ -33,7 +33,7 @@
#include <flash_map_backend/flash_map_backend.h>
#include "bootutil/image.h"
-#include "bootutil/sha256.h"
+#include "bootutil/crypto/sha256.h"
#include "bootutil/sign_key.h"
#include "bootutil/security_cnt.h"
@@ -134,6 +134,7 @@
#endif
rc = flash_area_read(fap, off, tmp_buf, blk_sz);
if (rc) {
+ bootutil_sha256_drop(&sha256_ctx);
return rc;
}
#ifdef MCUBOOT_ENC_IMAGES
@@ -150,6 +151,7 @@
}
#endif /* MCUBOOT_RAM_LOAD */
bootutil_sha256_finish(&sha256_ctx, hash_result);
+ bootutil_sha256_drop(&sha256_ctx);
return 0;
}
@@ -213,9 +215,11 @@
bootutil_sha256_update(&sha256_ctx, key->key, *key->len);
bootutil_sha256_finish(&sha256_ctx, hash);
if (!memcmp(hash, keyhash, keyhash_len)) {
+ bootutil_sha256_drop(&sha256_ctx);
return i;
}
}
+ bootutil_sha256_drop(&sha256_ctx);
return -1;
}
#else
@@ -232,6 +236,7 @@
bootutil_sha256_init(&sha256_ctx);
bootutil_sha256_update(&sha256_ctx, key, key_len);
bootutil_sha256_finish(&sha256_ctx, hash);
+ bootutil_sha256_drop(&sha256_ctx);
rc = boot_retrieve_public_key_hash(image_index, key_hash, &key_hash_size);
if (rc) {