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_HMAC_SHA256_H_
11 #define __BOOTUTIL_CRYPTO_HMAC_SHA256_H_
12 
13 #include "mcuboot_config/mcuboot_config.h"
14 
15 #if (defined(MCUBOOT_USE_MBED_TLS) + \
16      defined(MCUBOOT_USE_TINYCRYPT)) != 1
17     #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
18 #endif
19 
20 #if defined(MCUBOOT_USE_MBED_TLS)
21     #include <stdint.h>
22     #include <stddef.h>
23     #include <mbedtls/cmac.h>
24     #include <mbedtls/md.h>
25 #endif /* MCUBOOT_USE_MBED_TLS */
26 
27 #if defined(MCUBOOT_USE_TINYCRYPT)
28     #include <tinycrypt/sha256.h>
29     #include <tinycrypt/utils.h>
30     #include <tinycrypt/constants.h>
31     #include <tinycrypt/hmac.h>
32 #endif /* MCUBOOT_USE_TINYCRYPT */
33 
34 #include <stdint.h>
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 #if defined(MCUBOOT_USE_TINYCRYPT)
41 typedef struct tc_hmac_state_struct bootutil_hmac_sha256_context;
bootutil_hmac_sha256_init(bootutil_hmac_sha256_context * ctx)42 static inline void bootutil_hmac_sha256_init(bootutil_hmac_sha256_context *ctx)
43 {
44     (void)ctx;
45 }
46 
bootutil_hmac_sha256_drop(bootutil_hmac_sha256_context * ctx)47 static inline void bootutil_hmac_sha256_drop(bootutil_hmac_sha256_context *ctx)
48 {
49     (void)ctx;
50 }
51 
bootutil_hmac_sha256_set_key(bootutil_hmac_sha256_context * ctx,const uint8_t * key,unsigned int key_size)52 static inline int bootutil_hmac_sha256_set_key(bootutil_hmac_sha256_context *ctx, const uint8_t *key, unsigned int key_size)
53 {
54     int rc;
55     rc = tc_hmac_set_key(ctx, key, key_size);
56     if (rc != TC_CRYPTO_SUCCESS) {
57         return -1;
58     }
59     rc = tc_hmac_init(ctx);
60     if (rc != TC_CRYPTO_SUCCESS) {
61         return -1;
62     }
63     return 0;
64 }
65 
bootutil_hmac_sha256_update(bootutil_hmac_sha256_context * ctx,const void * data,unsigned int data_length)66 static inline int bootutil_hmac_sha256_update(bootutil_hmac_sha256_context *ctx, const void *data, unsigned int data_length)
67 {
68     int rc;
69     rc = tc_hmac_update(ctx, data, data_length);
70     if (rc != TC_CRYPTO_SUCCESS) {
71         return -1;
72     }
73     return 0;
74 }
75 
bootutil_hmac_sha256_finish(bootutil_hmac_sha256_context * ctx,uint8_t * tag,unsigned int taglen)76 static inline int bootutil_hmac_sha256_finish(bootutil_hmac_sha256_context *ctx, uint8_t *tag, unsigned int taglen)
77 {
78     int rc;
79     rc = tc_hmac_final(tag, taglen, ctx);
80     if (rc != TC_CRYPTO_SUCCESS) {
81         return -1;
82     }
83     return 0;
84 }
85 #endif /* MCUBOOT_USE_TINYCRYPT */
86 
87 #if defined(MCUBOOT_USE_MBED_TLS)
88 /**
89  * The generic message-digest context.
90  */
91 typedef mbedtls_md_context_t bootutil_hmac_sha256_context;
92 
bootutil_hmac_sha256_init(bootutil_hmac_sha256_context * ctx)93 static inline void bootutil_hmac_sha256_init(bootutil_hmac_sha256_context *ctx)
94 {
95     mbedtls_md_init(ctx);
96 }
97 
bootutil_hmac_sha256_drop(bootutil_hmac_sha256_context * ctx)98 static inline void bootutil_hmac_sha256_drop(bootutil_hmac_sha256_context *ctx)
99 {
100     mbedtls_md_free(ctx);
101 }
102 
bootutil_hmac_sha256_set_key(bootutil_hmac_sha256_context * ctx,const uint8_t * key,unsigned int key_size)103 static inline int bootutil_hmac_sha256_set_key(bootutil_hmac_sha256_context *ctx, const uint8_t *key, unsigned int key_size)
104 {
105     int rc;
106 
107     rc = mbedtls_md_setup(ctx, mbedtls_md_info_from_string("SHA256"), 1);
108     if (rc != 0) {
109         return rc;
110     }
111     rc = mbedtls_md_hmac_starts(ctx, key, key_size);
112     return rc;
113 }
114 
bootutil_hmac_sha256_update(bootutil_hmac_sha256_context * ctx,const void * data,unsigned int data_length)115 static inline int bootutil_hmac_sha256_update(bootutil_hmac_sha256_context *ctx, const void *data, unsigned int data_length)
116 {
117     return mbedtls_md_hmac_update(ctx, data, data_length);
118 }
119 
bootutil_hmac_sha256_finish(bootutil_hmac_sha256_context * ctx,uint8_t * tag,unsigned int taglen)120 static inline int bootutil_hmac_sha256_finish(bootutil_hmac_sha256_context *ctx, uint8_t *tag, unsigned int taglen)
121 {
122     (void)taglen;
123     /*
124      * HMAC the key and check that our received MAC matches the generated tag
125      */
126     return mbedtls_md_hmac_finish(ctx, tag);
127 }
128 #endif /* MCUBOOT_USE_MBED_TLS */
129 
130 #ifdef __cplusplus
131 }
132 #endif
133 
134 #endif /* __BOOTUTIL_CRYPTO_HMAC_SHA256_H_ */
135