|
| 1 | +/* |
| 2 | + * This module provides a thin abstraction over some of the crypto |
| 3 | + * primitives to make it easier to swap out the used crypto library. |
| 4 | + * |
| 5 | + * At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or |
| 6 | + * MCUBOOT_USE_TINYCRYPT. It is a compile error there is not exactly |
| 7 | + * one of these defined. |
| 8 | + */ |
| 9 | + |
| 10 | +#ifndef __BOOTUTIL_CRYPTO_AES_CTR_H_ |
| 11 | +#define __BOOTUTIL_CRYPTO_AES_CTR_H_ |
| 12 | + |
| 13 | +#include <string.h> |
| 14 | + |
| 15 | +#include "mcuboot_config/mcuboot_config.h" |
| 16 | + |
| 17 | +#if (defined(MCUBOOT_USE_MBED_TLS) + \ |
| 18 | + defined(MCUBOOT_USE_TINYCRYPT)) != 1 |
| 19 | + #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT" |
| 20 | +#endif |
| 21 | + |
| 22 | +#if defined(MCUBOOT_USE_MBED_TLS) |
| 23 | + #include <mbedtls/aes.h> |
| 24 | + #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE (16) |
| 25 | + #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16) |
| 26 | +#endif /* MCUBOOT_USE_MBED_TLS */ |
| 27 | + |
| 28 | +#if defined(MCUBOOT_USE_TINYCRYPT) |
| 29 | + #include <string.h> |
| 30 | + #include <tinycrypt/aes.h> |
| 31 | + #include <tinycrypt/ctr_mode.h> |
| 32 | + #include <tinycrypt/constants.h> |
| 33 | + #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE TC_AES_KEY_SIZE |
| 34 | + #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE TC_AES_BLOCK_SIZE |
| 35 | +#endif /* MCUBOOT_USE_TINYCRYPT */ |
| 36 | + |
| 37 | +#include <stdint.h> |
| 38 | + |
| 39 | +#ifdef __cplusplus |
| 40 | +extern "C" { |
| 41 | +#endif |
| 42 | + |
| 43 | +#if defined(MCUBOOT_USE_MBED_TLS) |
| 44 | +typedef mbedtls_aes_context bootutil_aes_ctr_context; |
| 45 | +static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx) |
| 46 | +{ |
| 47 | + (void)mbedtls_aes_init(ctx); |
| 48 | +} |
| 49 | + |
| 50 | +static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx) |
| 51 | +{ |
| 52 | + /* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */ |
| 53 | + /* (void)mbedtls_aes_free(ctx); */ |
| 54 | + (void)ctx; |
| 55 | +} |
| 56 | + |
| 57 | +static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k) |
| 58 | +{ |
| 59 | + return mbedtls_aes_setkey_enc(ctx, k, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE * 8); |
| 60 | +} |
| 61 | + |
| 62 | +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) |
| 63 | +{ |
| 64 | + uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE]; |
| 65 | + int rc; |
| 66 | + rc = mbedtls_aes_crypt_ctr(ctx, mlen, &blk_off, counter, stream_block, m, c); |
| 67 | + memset(stream_block, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE); |
| 68 | + return rc; |
| 69 | +} |
| 70 | + |
| 71 | +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) |
| 72 | +{ |
| 73 | + uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE]; |
| 74 | + int rc; |
| 75 | + rc = mbedtls_aes_crypt_ctr(ctx, clen, &blk_off, counter, stream_block, c, m); |
| 76 | + memset(stream_block, 0, BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE); |
| 77 | + return rc; |
| 78 | +} |
| 79 | +#endif /* MCUBOOT_USE_MBED_TLS */ |
| 80 | + |
| 81 | +#if defined(MCUBOOT_USE_TINYCRYPT) |
| 82 | +typedef struct tc_aes_key_sched_struct bootutil_aes_ctr_context; |
| 83 | +static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx) |
| 84 | +{ |
| 85 | + (void)ctx; |
| 86 | +} |
| 87 | + |
| 88 | +static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx) |
| 89 | +{ |
| 90 | + (void)ctx; |
| 91 | +} |
| 92 | + |
| 93 | +static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k) |
| 94 | +{ |
| 95 | + int rc; |
| 96 | + rc = tc_aes128_set_encrypt_key(ctx, k); |
| 97 | + if (rc != TC_CRYPTO_SUCCESS) { |
| 98 | + return -1; |
| 99 | + } |
| 100 | + return 0; |
| 101 | +} |
| 102 | + |
| 103 | +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) |
| 104 | +{ |
| 105 | + uint8_t buf[16]; |
| 106 | + uint32_t buflen; |
| 107 | + int rc; |
| 108 | + if (blk_off == 0) { |
| 109 | + rc = tc_ctr_mode(out, inlen, in, inlen, counter, ctx); |
| 110 | + if (rc != TC_CRYPTO_SUCCESS) { |
| 111 | + return -1; |
| 112 | + } |
| 113 | + } else if (blk_off < 16) { |
| 114 | + buflen = ((inlen + blk_off <= 16) ? inlen : (16 - blk_off)); |
| 115 | + inlen -= buflen; |
| 116 | + memcpy(&buf[blk_off], &in[0], buflen); |
| 117 | + rc = tc_ctr_mode(buf, 16, buf, 16, counter, ctx); |
| 118 | + if (rc != TC_CRYPTO_SUCCESS) { |
| 119 | + return -1; |
| 120 | + } |
| 121 | + memcpy(&out[0], &buf[blk_off], buflen); |
| 122 | + memset(&buf[0], 0, 16); |
| 123 | + if (inlen > 0) { |
| 124 | + rc = tc_ctr_mode(&out[buflen], inlen, &in[buflen], inlen, counter, ctx); |
| 125 | + } |
| 126 | + if (rc != TC_CRYPTO_SUCCESS) { |
| 127 | + return -1; |
| 128 | + } |
| 129 | + } else { |
| 130 | + return -1; |
| 131 | + } |
| 132 | + return 0; |
| 133 | +} |
| 134 | + |
| 135 | +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) |
| 136 | +{ |
| 137 | + return _bootutil_aes_ctr_crypt(ctx, counter, m, mlen, blk_off, c); |
| 138 | +} |
| 139 | + |
| 140 | +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) |
| 141 | +{ |
| 142 | + return _bootutil_aes_ctr_crypt(ctx, counter, c, clen, blk_off, m); |
| 143 | +} |
| 144 | +#endif /* MCUBOOT_USE_TINYCRYPT */ |
| 145 | + |
| 146 | +#ifdef __cplusplus |
| 147 | +} |
| 148 | +#endif |
| 149 | + |
| 150 | +#endif /* __BOOTUTIL_CRYPTO_AES_CTR_H_ */ |
0 commit comments