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     #include "bootutil/enc_key_public.h"
25     #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE BOOT_ENC_KEY_SIZE
26     #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE (16)
27 #endif /* MCUBOOT_USE_MBED_TLS */
28 
29 #if defined(MCUBOOT_USE_TINYCRYPT)
30     #if defined(MCUBOOT_AES_256)
31         #error "Cannot use AES-256 for encryption with Tinycrypt library."
32     #endif
33     #include <string.h>
34     #include <tinycrypt/aes.h>
35     #include <tinycrypt/ctr_mode.h>
36     #include <tinycrypt/constants.h>
37     #define BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE TC_AES_KEY_SIZE
38     #define BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE TC_AES_BLOCK_SIZE
39 #endif /* MCUBOOT_USE_TINYCRYPT */
40 
41 #include <stdint.h>
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 #if defined(MCUBOOT_USE_MBED_TLS)
48 typedef mbedtls_aes_context bootutil_aes_ctr_context;
bootutil_aes_ctr_init(bootutil_aes_ctr_context * ctx)49 static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
50 {
51     (void)mbedtls_aes_init(ctx);
52 }
53 
bootutil_aes_ctr_drop(bootutil_aes_ctr_context * ctx)54 static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
55 {
56     mbedtls_aes_free(ctx);
57 }
58 
bootutil_aes_ctr_set_key(bootutil_aes_ctr_context * ctx,const uint8_t * k)59 static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
60 {
61     return mbedtls_aes_setkey_enc(ctx, k, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE * 8);
62 }
63 
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)64 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)
65 {
66     uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
67     return mbedtls_aes_crypt_ctr(ctx, mlen, &blk_off, counter, stream_block, m, c);
68 }
69 
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)70 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)
71 {
72     uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
73     return mbedtls_aes_crypt_ctr(ctx, clen, &blk_off, counter, stream_block, c, m);
74 }
75 #endif /* MCUBOOT_USE_MBED_TLS */
76 
77 #if defined(MCUBOOT_USE_TINYCRYPT)
78 typedef struct tc_aes_key_sched_struct bootutil_aes_ctr_context;
bootutil_aes_ctr_init(bootutil_aes_ctr_context * ctx)79 static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
80 {
81     (void)ctx;
82 }
83 
bootutil_aes_ctr_drop(bootutil_aes_ctr_context * ctx)84 static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
85 {
86     (void)ctx;
87 }
88 
bootutil_aes_ctr_set_key(bootutil_aes_ctr_context * ctx,const uint8_t * k)89 static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
90 {
91     int rc;
92     rc = tc_aes128_set_encrypt_key(ctx, k);
93     if (rc != TC_CRYPTO_SUCCESS) {
94         return -1;
95     }
96     return 0;
97 }
98 
_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)99 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)
100 {
101     int rc;
102     rc = tc_ctr_mode(out, inlen, in, inlen, counter, &blk_off, ctx);
103     if (rc != TC_CRYPTO_SUCCESS) {
104         return -1;
105     }
106     return 0;
107 }
108 
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)109 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)
110 {
111     return _bootutil_aes_ctr_crypt(ctx, counter, m, mlen, blk_off, c);
112 }
113 
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)114 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)
115 {
116     return _bootutil_aes_ctr_crypt(ctx, counter, c, clen, blk_off, m);
117 }
118 #endif /* MCUBOOT_USE_TINYCRYPT */
119 
120 #ifdef __cplusplus
121 }
122 #endif
123 
124 #endif /* __BOOTUTIL_CRYPTO_AES_CTR_H_ */
125