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_SIGN_EC384)
38 #define IMAGE_HASH_SIZE (48)
39 #define EXPECTED_HASH_TLV IMAGE_TLV_SHA384
40 #else
41 #define IMAGE_HASH_SIZE (32)
42 #define EXPECTED_HASH_TLV IMAGE_TLV_SHA256
43 #endif /* MCUBOOT_SIGN_EC384 */
44
45 /* Universal defines for SHA-256 */
46 #define BOOTUTIL_CRYPTO_SHA256_BLOCK_SIZE (64)
47 #define BOOTUTIL_CRYPTO_SHA256_DIGEST_SIZE (32)
48
49 #if defined(MCUBOOT_USE_PSA_CRYPTO)
50
51 #include <psa/crypto.h>
52
53 #elif defined(MCUBOOT_USE_MBED_TLS)
54
55 #include <mbedtls/sha256.h>
56 #include <mbedtls/version.h>
57 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
58 #include <mbedtls/compat-2.x.h>
59 #endif
60
61 #endif /* MCUBOOT_USE_MBED_TLS */
62
63 #if defined(MCUBOOT_USE_TINYCRYPT)
64 #include <tinycrypt/sha256.h>
65 #include <tinycrypt/constants.h>
66 #endif /* MCUBOOT_USE_TINYCRYPT */
67
68 #if defined(MCUBOOT_USE_CC310)
69 #include <cc310_glue.h>
70 #endif /* MCUBOOT_USE_CC310 */
71
72 #include <stdint.h>
73
74 #ifdef __cplusplus
75 extern "C" {
76 #endif
77
78 #if defined(MCUBOOT_USE_PSA_CRYPTO)
79
80 typedef psa_hash_operation_t bootutil_sha_context;
81
bootutil_sha_init(bootutil_sha_context * ctx)82 static inline int bootutil_sha_init(bootutil_sha_context *ctx)
83 {
84 *ctx = psa_hash_operation_init();
85 #if defined(MCUBOOT_SIGN_EC384)
86 psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_384);
87 #else
88 psa_status_t status = psa_hash_setup(ctx, PSA_ALG_SHA_256);
89 #endif
90 return (int)status;
91 }
92
bootutil_sha_drop(bootutil_sha_context * ctx)93 static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
94 {
95 return (int)psa_hash_abort(ctx);
96 }
97
bootutil_sha_update(bootutil_sha_context * ctx,const void * data,uint32_t data_len)98 static inline int bootutil_sha_update(bootutil_sha_context *ctx,
99 const void *data,
100 uint32_t data_len)
101 {
102 return (int)psa_hash_update(ctx, data, data_len);
103 }
104
bootutil_sha_finish(bootutil_sha_context * ctx,uint8_t * output)105 static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
106 uint8_t *output)
107 {
108 size_t hash_length = 0;
109 /* Assumes the output buffer is at least the expected size of the hash */
110 #if defined(MCUBOOT_SIGN_EC384)
111 return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_384), &hash_length);
112 #else
113 return (int)psa_hash_finish(ctx, output, PSA_HASH_LENGTH(PSA_ALG_SHA_256), &hash_length);
114 #endif
115 }
116
117 #elif defined(MCUBOOT_USE_MBED_TLS)
118
119 typedef mbedtls_sha256_context bootutil_sha_context;
120
121 static inline int bootutil_sha_init(bootutil_sha_context *ctx)
122 {
123 mbedtls_sha256_init(ctx);
124 return mbedtls_sha256_starts_ret(ctx, 0);
125 }
126
127 static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
128 {
129 /* XXX: config defines MBEDTLS_PLATFORM_NO_STD_FUNCTIONS so no need to free */
130 /* (void)mbedtls_sha256_free(ctx); */
131 (void)ctx;
132 return 0;
133 }
134
135 static inline int bootutil_sha_update(bootutil_sha_context *ctx,
136 const void *data,
137 uint32_t data_len)
138 {
139 return mbedtls_sha256_update_ret(ctx, data, data_len);
140 }
141
142 static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
143 uint8_t *output)
144 {
145 return mbedtls_sha256_finish_ret(ctx, output);
146 }
147
148 #endif /* MCUBOOT_USE_MBED_TLS */
149
150 #if defined(MCUBOOT_USE_TINYCRYPT)
151 typedef struct tc_sha256_state_struct bootutil_sha_context;
152
bootutil_sha_init(bootutil_sha_context * ctx)153 static inline int bootutil_sha_init(bootutil_sha_context *ctx)
154 {
155 tc_sha256_init(ctx);
156 return 0;
157 }
158
bootutil_sha_drop(bootutil_sha_context * ctx)159 static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
160 {
161 (void)ctx;
162 return 0;
163 }
164
bootutil_sha_update(bootutil_sha_context * ctx,const void * data,uint32_t data_len)165 static inline int bootutil_sha_update(bootutil_sha_context *ctx,
166 const void *data,
167 uint32_t data_len)
168 {
169 return tc_sha256_update(ctx, data, data_len);
170 }
171
bootutil_sha_finish(bootutil_sha_context * ctx,uint8_t * output)172 static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
173 uint8_t *output)
174 {
175 return tc_sha256_final(output, ctx);
176 }
177 #endif /* MCUBOOT_USE_TINYCRYPT */
178
179 #if defined(MCUBOOT_USE_CC310)
bootutil_sha_init(bootutil_sha_context * ctx)180 static inline int bootutil_sha_init(bootutil_sha_context *ctx)
181 {
182 cc310_sha256_init(ctx);
183 return 0;
184 }
185
bootutil_sha_drop(bootutil_sha_context * ctx)186 static inline int bootutil_sha_drop(bootutil_sha_context *ctx)
187 {
188 (void)ctx;
189 nrf_cc310_disable();
190 return 0;
191 }
192
bootutil_sha_update(bootutil_sha_context * ctx,const void * data,uint32_t data_len)193 static inline int bootutil_sha_update(bootutil_sha_context *ctx,
194 const void *data,
195 uint32_t data_len)
196 {
197 cc310_sha256_update(ctx, data, data_len);
198 return 0;
199 }
200
bootutil_sha_finish(bootutil_sha_context * ctx,uint8_t * output)201 static inline int bootutil_sha_finish(bootutil_sha_context *ctx,
202 uint8_t *output)
203 {
204 cc310_sha256_finalize(ctx, output);
205 return 0;
206 }
207 #endif /* MCUBOOT_USE_CC310 */
208
209 #ifdef __cplusplus
210 }
211 #endif
212
213 #endif /* __BOOTUTIL_CRYPTO_SHA_H_ */
214