forked from nrfconnect/sdk-nrf
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bl_crypto.h
230 lines (194 loc) · 6.74 KB
/
bl_crypto.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/
#ifndef BOOTLOADER_CRYPTO_H__
#define BOOTLOADER_CRYPTO_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <zephyr/types.h>
#include <fw_info.h>
/** @defgroup bl_crypto Bootloader crypto functions
* @{
*/
/* Placeholder defines. Values should be updated, if no existing errors can be
* used instead. */
#define EHASHINV 101
#define ESIGINV 102
#if CONFIG_SB_CRYPTO_OBERON_SHA256
#include <ocrypto_sha256.h>
#define SHA256_CTX_SIZE sizeof(ocrypto_sha256_ctx)
typedef ocrypto_sha256_ctx bl_sha256_ctx_t;
#elif CONFIG_SB_CRYPTO_CC310_SHA256
#include <nrf_cc310_bl_hash_sha256.h>
#define SHA256_CTX_SIZE sizeof(nrf_cc310_bl_hash_context_sha256_t)
typedef nrf_cc310_bl_hash_context_sha256_t bl_sha256_ctx_t;
#else
#define SHA256_CTX_SIZE 256
// uint32_t to make sure it is aligned equally as the other contexts.
typedef uint32_t bl_sha256_ctx_t[SHA256_CTX_SIZE/4];
#endif
/**
* @brief Initialize bootloader crypto module.
*
* @retval 0 On success.
* @retval -EFAULT If crypto module reported an error.
*/
int bl_crypto_init(void);
/**
* @brief Verify a signature using configured signature and SHA-256
*
* Verifies the public key against the public key hash, then verifies the hash
* of the signed data against the signature using the public key.
*
* @param[in] public_key Public key.
* @param[in] public_key_hash Expected hash of the public key. This is the
* root of trust.
* @param[in] signature Firmware signature.
* @param[in] firmware Firmware.
* @param[in] firmware_len Length of firmware.
*
* @retval 0 On success.
* @retval -EHASHINV If public_key_hash didn't match public_key.
* @retval -ESIGINV If signature validation failed.
* @return Any error code from @ref bl_sha256_init, @ref bl_sha256_update,
* @ref bl_sha256_finalize, or @ref bl_secp256r1_validate if something
* else went wrong.
*
* @remark No parameter can be NULL.
*/
int bl_root_of_trust_verify(const uint8_t *public_key,
const uint8_t *public_key_hash,
const uint8_t *signature,
const uint8_t *firmware,
const uint32_t firmware_len);
/* Typedef for use in EXT_API declaration */
typedef int (*bl_root_of_trust_verify_t)(
const uint8_t *public_key,
const uint8_t *public_key_hash,
const uint8_t *signature,
const uint8_t *firmware,
const uint32_t firmware_len);
/**
* @brief Implementation of rot_verify that is safe to be called from EXT_API.
*
* See @ref bl_root_of_trust_verify for docs.
*/
int bl_root_of_trust_verify_external(const uint8_t *public_key,
const uint8_t *public_key_hash,
const uint8_t *signature,
const uint8_t *firmware,
const uint32_t firmware_len);
/**
* @brief Initialize a sha256 operation context variable.
*
* @param[out] ctx Context to be initialized.
*
* @retval 0 On success.
* @retval -EINVAL If @p ctx was NULL.
*/
int bl_sha256_init(bl_sha256_ctx_t *ctx);
/* Typedef for use in EXT_API declaration */
typedef int (*bl_sha256_init_t)(bl_sha256_ctx_t *ctx);
/**
* @brief Hash a portion of data.
*
* @note @p ctx must be initialized before being used in this function.
* An uninitialized @p ctx might not be reported as an error. Also,
* @p ctx must not be used if it has been finalized, though this might
* also not be reported as an error.
*
* @param[in] ctx Context variable. Must have been initialized.
* @param[in] data Data to hash.
* @param[in] data_len Length of @p data.
*
* @retval 0 On success.
* @retval -EINVAL If @p ctx was NULL, uninitialized, or corrupted.
* @retval -ENOSYS If the context has already been finalized.
*/
int bl_sha256_update(bl_sha256_ctx_t *ctx, const uint8_t *data, uint32_t data_len);
/* Typedef for use in EXT_API declaration */
typedef int (*bl_sha256_update_t)(bl_sha256_ctx_t *ctx, const uint8_t *data,
uint32_t data_len);
/**
* @brief Finalize a hash result.
*
* @param[in] ctx Context variable.
* @param[out] output Where to put the resulting digest. Must be at least
* 32 bytes long.
*
* @retval 0 On success.
* @retval -EINVAL If @p ctx was NULL or corrupted, or @p output was NULL.
*/
int bl_sha256_finalize(bl_sha256_ctx_t *ctx, uint8_t *output);
/* Typedef for use in EXT_API declaration */
typedef int (*bl_sha256_finalize_t)(bl_sha256_ctx_t *ctx, uint8_t *output);
/**
* @brief Calculate a digest and verify it directly.
*
* @param[in] data The data to hash.
* @param[in] data_len The length of @p data.
* @param[in] expected The expected digest over @p data.
*
* @retval 0 If the procedure succeeded and the resulting digest is
* identical to @p expected.
* @retval -EHASHINV If the procedure succeeded, but the digests don't match.
* @return Any error code from @ref bl_sha256_init, @ref bl_sha256_update, or
* @ref bl_sha256_finalize if something else went wrong.
*/
int bl_sha256_verify(const uint8_t *data, uint32_t data_len, const uint8_t *expected);
/* Typedef for use in EXT_API declaration */
typedef int (*bl_sha256_verify_t)(const uint8_t *data, uint32_t data_len,
const uint8_t *expected);
/**
* @brief Validate a secp256r1 signature.
*
* @param[in] hash The hash to validate against.
* @param[in] hash_len The length of the hash.
* @param[in] signature The signature to validate.
* @param[in] public_key The public key to validate with.
*
* @retval 0 The operation succeeded and the signature is valid for the
* hash.
* @retval -EINVAL A parameter was NULL, or the @p hash_len was not 32 bytes.
* @retval -ESIGINV The signature validation failed.
*/
int bl_secp256r1_validate(const uint8_t *hash,
uint32_t hash_len,
const uint8_t *signature,
const uint8_t *public_key);
/* Typedef for use in EXT_API declaration */
typedef int (*bl_secp256r1_validate_t)(
const uint8_t *hash,
uint32_t hash_len,
const uint8_t *signature,
const uint8_t *public_key);
/**
* @brief Structure describing the BL_ROT_VERIFY EXT_API.
*/
struct bl_rot_verify_ext_api {
bl_root_of_trust_verify_t bl_root_of_trust_verify;
};
/**
* @brief Structure describing the BL_SHA256 EXT_API.
*/
struct bl_sha256_ext_api {
bl_sha256_init_t bl_sha256_init;
bl_sha256_update_t bl_sha256_update;
bl_sha256_finalize_t bl_sha256_finalize;
bl_sha256_verify_t bl_sha256_verify;
uint32_t bl_sha256_ctx_size;
};
/**
* @brief Structure describing the BL_SECP256R1 EXT_API.
*/
struct bl_secp256r1_ext_api {
bl_secp256r1_validate_t bl_secp256r1_validate;
};
/** @} */
#ifdef __cplusplus
}
#endif
#endif