1 /*
2 * SPDX-License-Identifier: Apache-2.0
3 *
4 * Copyright (c) 2017-2019 Linaro LTD
5 * Copyright (c) 2017-2019 JUUL Labs
6 * Copyright (c) 2021-2023 Arm Limited
7 */
8
9 /*
10 * This module provides a thin abstraction over some of the crypto
11 * primitives to make it easier to swap out the used crypto library.
12 *
13 * At this point, the choices are: MCUBOOT_USE_MBED_TLS, MCUBOOT_USE_TINYCRYPT,
14 * MCUBOOT_USE_PSA_CRYPTO, MCUBOOT_USE_CC310. Note that support for MCUBOOT_USE_PSA_CRYPTO
15 * is still experimental and it might not support all the crypto abstractions
16 * that MCUBOOT_USE_MBED_TLS supports. For this reason, it's allowed to have
17 * both of them defined, and for crypto modules that support both abstractions,
18 * the MCUBOOT_USE_PSA_CRYPTO will take precedence.
19 */
20
21 #ifndef __BOOTUTIL_CRYPTO_SHA_H_
22 #define __BOOTUTIL_CRYPTO_SHA_H_
23
24 #include "mcuboot_config/mcuboot_config.h"
25 #include "mcuboot_config/mcuboot_logging.h"
26
27 #if defined(MCUBOOT_USE_PSA_CRYPTO) || defined(MCUBOOT_USE_MBED_TLS)
28 #define MCUBOOT_USE_PSA_OR_MBED_TLS
29 #endif /* MCUBOOT_USE_PSA_CRYPTO || MCUBOOT_USE_MBED_TLS */
30
31 #if (defined(MCUBOOT_USE_PSA_OR_MBED_TLS) + \
32 defined(MCUBOOT_USE_TINYCRYPT) + \
33 defined(MCUBOOT_USE_CC310)) != 1
34 #error "One crypto backend must be defined: either CC310/MBED_TLS/TINYCRYPT/PSA_CRYPTO"
35 #endif
36
37 #if defined(MCUBOOT_SHA512)
38 #define IMAGE_HASH_SIZE (64)
39 #define EXPECTED_HASH_TLV IMAGE_TLV_SHA512
40 #elif defined(MCUBOOT_SIGN_EC384)
41 #define IMAGE_HASH_SIZE (48)
42 #define EXPECTED_HASH_TLV IMAGE_TLV_SHA384
43 #else
44 #define IMAGE_HASH_SIZE (32)
45 #define EXPECTED_HASH_TLV IMAGE_TLV_SHA256
46 #endif /* MCUBOOT_SIGN */
47
48 /* Universal defines for SHA-256 */
49 #define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
50 #define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
51
52 #if defined(MCUBOOT_USE_PSA_CRYPTO)
53
54 #include <psa/crypto.h>
55
56 #elif defined(MCUBOOT_USE_MBED_TLS)
57
58 #ifdef MCUBOOT_SHA512
59 #include <mbedtls/sha512.h>
60 #else
61 #include <mbedtls/sha256.h>
62 #endif
63
64 #include <mbedtls/version.h>
65 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
66 #include <mbedtls/compat-2.x.h>
67 #endif
68
69 #endif /* MCUBOOT_USE_MBED_TLS */
70
71 #if defined(MCUBOOT_USE_TINYCRYPT)
72 #if defined(MCUBOOT_SHA512)
73 #include <tinycrypt/sha512.h>
74 #else
75 #include <tinycrypt/sha256.h>
76 #endif
77 #include <tinycrypt/constants.h>
78 #endif /* MCUBOOT_USE_TINYCRYPT */
79
80 #if defined(MCUBOOT_USE_CC310)
81 #include <cc310_glue.h>
82 #endif /* MCUBOOT_USE_CC310 */
83
84 #include <stdint.h>
85
86 #ifdef __cplusplus
87 extern "C" {
88 #endif
89
90 #if defined(MCUBOOT_USE_PSA_CRYPTO)
91
92 typedef psa_hash_operation_t bootutil_sha_context;
93
bootutil_sha_init(bootutil_sha_context * ctx)94 static inline int bootutil_sha_init(bootutil_sha_context *ctx)
95 {
96 *ctx = psa_hash_operation_init();
97 #if defined(MCUBOOT_SHA512)
98 psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_512);
99 #elif defined(MCUBOOT_SIGN_EC384)
100 psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_384);
101 #else
102 psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_256);
103 #endif
104 return (int)status;
105 }
106
bootutil_sha_drop(bootutil_sha_context * ctx)107 static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
108 {
109 return (int)psa_hash_abort(ctx);
110 }
111
bootutil_sha_update(bootutil_sha_context * ctx,const void * data,uint32_t data_len)112 static inline int bootutil_sha_update(bootutil_sha_context *ctx,
113 const void *data,
114 uint32_t data_len)
115 {
116 return (int)psa_hash_update(ctx, data, data_len);
117 }
118
bootutil_sha_finish(bootutil_sha_context * ctx,uint8_t * output)119 static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
120 uint8_t *output)
121 {
122 size_t hash_length = 0;
123 /* Assumes the output buffer is at least the expected size of the hash */
124 #if defined(MCUBOOT_SHA512)
125 return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_512), &hash_length);
126 #elif defined(MCUBOOT_SIGN_EC384)
127 return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_384), &hash_length);
128 #else
129 return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_256), &hash_length);
130 #endif
131 }
132
133 #elif defined(MCUBOOT_USE_MBED_TLS)
134
135 #ifdef MCUBOOT_SHA512
136 typedef mbedtls_sha512_context bootutil_sha_context;
137 #else
138 typedef mbedtls_sha256_context bootutil_sha_context;
139 #endif
140
141 static inline int bootutil_sha_init(bootutil_sha_context *ctx)
142 {
143 int ret;
144
145 #ifdef MCUBOOT_SHA512
146 mbedtls_sha512_init(ctx);
147 ret = mbedtls_sha512_starts_ret(ctx, 0);
148 #else
149 mbedtls_sha256_init(ctx);
150 ret = mbedtls_sha256_starts_ret(ctx, 0);
151 #endif
152
153 return ret;
154 }
155
156 static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
157 {
158 #ifdef MCUBOOT_SHA512
159 mbedtls_sha512_free(ctx);
160 #else
161 mbedtls_sha256_free(ctx);
162 #endif
163
164 return 0;
165 }
166
167 static inline int bootutil_sha_update(bootutil_sha_context *ctx,
168 const void *data,
169 uint32_t data_len)
170 {
171 int ret;
172
173 #ifdef MCUBOOT_SHA512
174 ret = mbedtls_sha512_update_ret(ctx, data, data_len);
175 #else
176 ret = mbedtls_sha256_update_ret(ctx, data, data_len);
177 #endif
178
179 return ret;
180 }
181
182 static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
183 uint8_t *output)
184 {
185 int ret;
186
187 #ifdef MCUBOOT_SHA512
188 ret = mbedtls_sha512_finish_ret(ctx, output);
189 #else
190 ret = mbedtls_sha256_finish_ret(ctx, output);
191 #endif
192
193 return ret;
194 }
195
196 #endif /* MCUBOOT_USE_MBED_TLS */
197
198 #if defined(MCUBOOT_USE_TINYCRYPT)
199 #if defined(MCUBOOT_SHA512)
200 typedef struct tc_sha512_state_struct bootutil_sha_context;
201 #else
202 typedef struct tc_sha256_state_struct bootutil_sha_context;
203 #endif
204
bootutil_sha_init(bootutil_sha_context * ctx)205 static inline int bootutil_sha_init(bootutil_sha_context *ctx)
206 {
207 #if defined(MCUBOOT_SHA512)
208 tc_sha512_init(ctx);
209 #else
210 tc_sha256_init(ctx);
211 #endif
212 return 0;
213 }
214
bootutil_sha_drop(bootutil_sha_context * ctx)215 static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
216 {
217 (void)ctx;
218 return 0;
219 }
220
bootutil_sha_update(bootutil_sha_context * ctx,const void * data,uint32_t data_len)221 static inline int bootutil_sha_update(bootutil_sha_context *ctx,
222 const void *data,
223 uint32_t data_len)
224 {
225 #if defined(MCUBOOT_SHA512)
226 return tc_sha512_update(ctx, data, data_len);
227 #else
228 return tc_sha256_update(ctx, data, data_len);
229 #endif
230 }
231
bootutil_sha_finish(bootutil_sha_context * ctx,uint8_t * output)232 static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
233 uint8_t *output)
234 {
235 #if defined(MCUBOOT_SHA512)
236 return tc_sha512_final(output, ctx);
237 #else
238 return tc_sha256_final(output, ctx);
239 #endif
240 }
241 #endif /* MCUBOOT_USE_TINYCRYPT */
242
243 #if defined(MCUBOOT_USE_CC310)
bootutil_sha_init(bootutil_sha_context * ctx)244 static inline int bootutil_sha_init(bootutil_sha_context *ctx)
245 {
246 cc310_sha256_init(ctx);
247 return 0;
248 }
249
bootutil_sha_drop(bootutil_sha_context * ctx)250 static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
251 {
252 (void)ctx;
253 nrf_cc310_disable();
254 return 0;
255 }
256
bootutil_sha_update(bootutil_sha_context * ctx,const void * data,uint32_t data_len)257 static inline int bootutil_sha_update(bootutil_sha_context *ctx,
258 const void *data,
259 uint32_t data_len)
260 {
261 cc310_sha256_update(ctx, data, data_len);
262 return 0;
263 }
264
bootutil_sha_finish(bootutil_sha_context * ctx,uint8_t * output)265 static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
266 uint8_t *output)
267 {
268 cc310_sha256_finalize(ctx, output);
269 return 0;
270 }
271 #endif /* MCUBOOT_USE_CC310 */
272
273 #ifdef __cplusplus
274 }
275 #endif
276
277 #endif /* __BOOTUTIL_CRYPTO_SHA_H_ */
278