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