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     /* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
57     /* (void)mbedtls_aes_free(ctx); */
58     (void)ctx;
59 }
60 
bootutil_aes_ctr_set_key(bootutil_aes_ctr_context * ctx,const uint8_t * k)61 static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
62 {
63     return mbedtls_aes_setkey_enc(ctx, k, BOOTUTIL_CRYPTO_AES_CTR_KEY_SIZE * 8);
64 }
65 
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)66 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)
67 {
68     uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
69     return mbedtls_aes_crypt_ctr(ctx, mlen, &blk_off, counter, stream_block, m, c);
70 }
71 
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 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)
73 {
74     uint8_t stream_block[BOOTUTIL_CRYPTO_AES_CTR_BLOCK_SIZE];
75     return mbedtls_aes_crypt_ctr(ctx, clen, &blk_off, counter, stream_block, c, m);
76 }
77 #endif /* MCUBOOT_USE_MBED_TLS */
78 
79 #if defined(MCUBOOT_USE_TINYCRYPT)
80 typedef struct tc_aes_key_sched_struct bootutil_aes_ctr_context;
bootutil_aes_ctr_init(bootutil_aes_ctr_context * ctx)81 static inline void bootutil_aes_ctr_init(bootutil_aes_ctr_context *ctx)
82 {
83     (void)ctx;
84 }
85 
bootutil_aes_ctr_drop(bootutil_aes_ctr_context * ctx)86 static inline void bootutil_aes_ctr_drop(bootutil_aes_ctr_context *ctx)
87 {
88     (void)ctx;
89 }
90 
bootutil_aes_ctr_set_key(bootutil_aes_ctr_context * ctx,const uint8_t * k)91 static inline int bootutil_aes_ctr_set_key(bootutil_aes_ctr_context *ctx, const uint8_t *k)
92 {
93     int rc;
94     rc = tc_aes128_set_encrypt_key(ctx, k);
95     if (rc != TC_CRYPTO_SUCCESS) {
96         return -1;
97     }
98     return 0;
99 }
100 
_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)101 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)
102 {
103     int rc;
104     rc = tc_ctr_mode(out, inlen, in, inlen, counter, &blk_off, ctx);
105     if (rc != TC_CRYPTO_SUCCESS) {
106         return -1;
107     }
108     return 0;
109 }
110 
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)111 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)
112 {
113     return _bootutil_aes_ctr_crypt(ctx, counter, m, mlen, blk_off, c);
114 }
115 
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)116 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)
117 {
118     return _bootutil_aes_ctr_crypt(ctx, counter, c, clen, blk_off, m);
119 }
120 #endif /* MCUBOOT_USE_TINYCRYPT */
121 
122 #ifdef __cplusplus
123 }
124 #endif
125 
126 #endif /* __BOOTUTIL_CRYPTO_AES_CTR_H_ */
127