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) {
diff --git a/sim/mcuboot-sys/build.rs b/sim/mcuboot-sys/build.rs
index 49739f6..440c4ae 100644
--- a/sim/mcuboot-sys/build.rs
+++ b/sim/mcuboot-sys/build.rs
@@ -178,6 +178,7 @@
             conf.file("../../ext/tinycrypt/lib/source/sha256.c");
             conf.file("../../ext/tinycrypt/lib/source/aes_encrypt.c");
             conf.file("../../ext/tinycrypt/lib/source/aes_decrypt.c");
+            conf.file("../../ext/tinycrypt/lib/source/ctr_mode.c");
         }
 
         if sig_ed25519 {