1 /*
2 * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #pragma once
7
8 #include <stdbool.h>
9 #include <string.h>
10 #include "hal/assert.h"
11 #include "soc/ecdsa_reg.h"
12 #include "hal/ecdsa_types.h"
13
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17
18 /**
19 * @brief Memory blocks of ECDSA parameters
20 */
21 typedef enum {
22 ECDSA_PARAM_R,
23 ECDSA_PARAM_S,
24 ECDSA_PARAM_Z,
25 ECDSA_PARAM_QAX,
26 ECDSA_PARAM_QAY
27 } ecdsa_ll_param_t;
28
29 /**
30 * @brief Interrupt types in ECDSA
31 */
32 typedef enum {
33 ECDSA_INT_CALC_DONE,
34 ECDSA_INT_SHA_RELEASE,
35 } ecdsa_ll_intr_type_t;
36
37 /**
38 * @brief Stages of ECDSA operation
39 */
40 typedef enum {
41 ECDSA_STAGE_START_CALC,
42 ECDSA_STAGE_LOAD_DONE,
43 ECDSA_STAGE_GET_DONE
44 } ecdsa_ll_stage_t;
45
46 /**
47 * @brief States of ECDSA peripheral
48 */
49 typedef enum {
50 ECDSA_STATE_IDLE,
51 ECDSA_STATE_LOAD,
52 ECDSA_STATE_GET,
53 ECDSA_STATE_BUSY
54 } ecdsa_ll_state_t;
55
56 /**
57 * @brief Types of SHA
58 */
59 typedef enum {
60 ECDSA_SHA_224,
61 ECDSA_SHA_256
62 } ecdsa_ll_sha_type_t;
63
64 /**
65 * @brief Operation modes of SHA
66 */
67 typedef enum {
68 ECDSA_MODE_SHA_START,
69 ECDSA_MODE_SHA_CONTINUE
70 } ecdsa_ll_sha_mode_t;
71
72 /**
73 * @brief Enable interrupt of a given type
74 *
75 * @param type Interrupt type
76 */
ecdsa_ll_enable_intr(ecdsa_ll_intr_type_t type)77 static inline void ecdsa_ll_enable_intr(ecdsa_ll_intr_type_t type)
78 {
79 switch (type) {
80 case ECDSA_INT_CALC_DONE:
81 REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_CALC_DONE_INT_ENA, 1);
82 break;
83 case ECDSA_INT_SHA_RELEASE:
84 REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_SHA_RELEASE_INT_ENA, 1);
85 break;
86 default:
87 HAL_ASSERT(false && "Unsupported interrupt type");
88 break;
89 }
90 }
91
92 /**
93 * @brief Disable interrupt of a given type
94 *
95 * @param type Interrupt type
96 */
ecdsa_ll_disable_intr(ecdsa_ll_intr_type_t type)97 static inline void ecdsa_ll_disable_intr(ecdsa_ll_intr_type_t type)
98 {
99 switch (type) {
100 case ECDSA_INT_CALC_DONE:
101 REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_CALC_DONE_INT_ENA, 0);
102 break;
103 case ECDSA_INT_SHA_RELEASE:
104 REG_SET_FIELD(ECDSA_INT_ENA_REG, ECDSA_SHA_RELEASE_INT_ENA, 0);
105 break;
106 default:
107 HAL_ASSERT(false && "Unsupported interrupt type");
108 break;
109 }
110 }
111
112 /**
113 * @brief Clear interrupt of a given type
114 *
115 * @param type Interrupt type
116 */
ecdsa_ll_clear_intr(ecdsa_ll_intr_type_t type)117 static inline void ecdsa_ll_clear_intr(ecdsa_ll_intr_type_t type)
118 {
119 switch (type) {
120 case ECDSA_INT_CALC_DONE:
121 REG_SET_FIELD(ECDSA_INT_CLR_REG, ECDSA_CALC_DONE_INT_CLR, 1);
122 break;
123 case ECDSA_INT_SHA_RELEASE:
124 REG_SET_FIELD(ECDSA_INT_CLR_REG, ECDSA_SHA_RELEASE_INT_CLR, 1);
125 break;
126 default:
127 HAL_ASSERT(false && "Unsupported interrupt type");
128 break;
129 }
130 }
131
132 /**
133 * @brief Set working mode of ECDSA
134 *
135 * @param mode Mode of operation
136 */
ecdsa_ll_set_mode(ecdsa_mode_t mode)137 static inline void ecdsa_ll_set_mode(ecdsa_mode_t mode)
138 {
139 switch (mode) {
140 case ECDSA_MODE_SIGN_VERIFY:
141 REG_SET_FIELD(ECDSA_CONF_REG, ECDSA_WORK_MODE, 0);
142 break;
143 case ECDSA_MODE_SIGN_GEN:
144 REG_SET_FIELD(ECDSA_CONF_REG, ECDSA_WORK_MODE, 1);
145 break;
146 default:
147 HAL_ASSERT(false && "Unsupported mode");
148 break;
149 }
150 }
151
152 /**
153 * @brief Set curve for ECDSA operation
154 *
155 * @param curve ECDSA curve
156 */
ecdsa_ll_set_curve(ecdsa_curve_t curve)157 static inline void ecdsa_ll_set_curve(ecdsa_curve_t curve)
158 {
159 switch (curve) {
160 case ECDSA_CURVE_SECP256R1:
161 REG_SET_BIT(ECDSA_CONF_REG, ECDSA_ECC_CURVE);
162 break;
163 case ECDSA_CURVE_SECP192R1:
164 REG_CLR_BIT(ECDSA_CONF_REG, ECDSA_ECC_CURVE);
165 break;
166 default:
167 HAL_ASSERT(false && "Unsupported curve");
168 return;
169 }
170 }
171
172 /**
173 * @brief Set the source of `Z` (SHA message)
174 *
175 * @param mode Mode of SHA generation
176 */
ecdsa_ll_set_z_mode(ecdsa_ll_sha_mode_t mode)177 static inline void ecdsa_ll_set_z_mode(ecdsa_ll_sha_mode_t mode)
178 {
179 switch (mode) {
180 case ECDSA_Z_USE_SHA_PERI:
181 REG_CLR_BIT(ECDSA_CONF_REG, ECDSA_SOFTWARE_SET_Z);
182 break;
183 case ECDSA_Z_USER_PROVIDED:
184 REG_SET_BIT(ECDSA_CONF_REG, ECDSA_SOFTWARE_SET_Z);
185 break;
186 default:
187 HAL_ASSERT(false && "Unsupported curve");
188 break;
189 }
190 }
191
192 /**
193 * @brief Set the stage of ECDSA operation
194 *
195 * @param stage Stage of operation
196 */
ecdsa_ll_set_stage(ecdsa_ll_stage_t stage)197 static inline void ecdsa_ll_set_stage(ecdsa_ll_stage_t stage)
198 {
199 switch (stage) {
200 case ECDSA_STAGE_START_CALC:
201 REG_SET_BIT(ECDSA_START_REG, ECDSA_START);
202 break;
203 case ECDSA_STAGE_LOAD_DONE:
204 REG_SET_BIT(ECDSA_START_REG, ECDSA_LOAD_DONE);
205 break;
206 case ECDSA_STAGE_GET_DONE:
207 REG_SET_BIT(ECDSA_START_REG, ECDSA_GET_DONE);
208 break;
209 default:
210 HAL_ASSERT(false && "Unsupported state");
211 break;
212 }
213 }
214
215 /**
216 * @brief Get the state of ECDSA peripheral
217 *
218 * @return State of ECDSA
219 */
ecdsa_ll_get_state(void)220 static inline ecdsa_ll_state_t ecdsa_ll_get_state(void)
221 {
222 return REG_GET_FIELD(ECDSA_STATE_REG, ECDSA_BUSY);
223 }
224
225 /**
226 * @brief Set the SHA type
227 *
228 * @param type Type of SHA
229 */
ecdsa_ll_sha_set_type(ecdsa_ll_sha_type_t type)230 static inline void ecdsa_ll_sha_set_type(ecdsa_ll_sha_type_t type)
231 {
232 switch (type) {
233 case ECDSA_SHA_224:
234 REG_SET_FIELD(ECDSA_SHA_MODE_REG, ECDSA_SHA_MODE, 1);
235 break;
236 case ECDSA_SHA_256:
237 REG_SET_FIELD(ECDSA_SHA_MODE_REG, ECDSA_SHA_MODE, 2);
238 break;
239 default:
240 HAL_ASSERT(false && "Unsupported type");
241 break;
242 }
243 }
244
245 /**
246 * @brief Set the SHA operation mode
247 *
248 * @param mode Mode of SHA operation
249 */
ecdsa_ll_sha_set_mode(ecdsa_ll_sha_mode_t mode)250 static inline void ecdsa_ll_sha_set_mode(ecdsa_ll_sha_mode_t mode)
251 {
252 switch (mode) {
253 case ECDSA_MODE_SHA_START:
254 REG_SET_BIT(ECDSA_SHA_START_REG, ECDSA_SHA_START);
255 break;
256 case ECDSA_MODE_SHA_CONTINUE:
257 REG_SET_BIT(ECDSA_SHA_CONTINUE_REG, ECDSA_SHA_CONTINUE);
258 break;
259 default:
260 HAL_ASSERT(false && "Unsupported type");
261 break;
262 }
263 }
264
265 /**
266 * @brief Check if SHA is busy
267 *
268 * @return - true, if SHA is busy
269 * - false, if SHA is IDLE
270 */
ecdsa_ll_sha_is_busy(void)271 static inline bool ecdsa_ll_sha_is_busy(void)
272 {
273 return REG_GET_BIT(ECDSA_SHA_BUSY_REG, ECDSA_SHA_BUSY);
274 }
275
276 /**
277 * @brief Write the ECDSA parameter
278 *
279 * @param param Parameter to be written
280 * @param buf Buffer containing data
281 * @param len Length of buffer
282 */
ecdsa_ll_write_param(ecdsa_ll_param_t param,const uint8_t * buf,uint16_t len)283 static inline void ecdsa_ll_write_param(ecdsa_ll_param_t param, const uint8_t *buf, uint16_t len)
284 {
285 uint32_t reg;
286 uint32_t word;
287 switch (param) {
288 case ECDSA_PARAM_R:
289 reg = ECDSA_R_MEM;
290 break;
291 case ECDSA_PARAM_S:
292 reg = ECDSA_S_MEM;
293 break;
294 case ECDSA_PARAM_Z:
295 reg = ECDSA_Z_MEM;
296 break;
297 case ECDSA_PARAM_QAX:
298 reg = ECDSA_QAX_MEM;
299 break;
300 case ECDSA_PARAM_QAY:
301 reg = ECDSA_QAY_MEM;
302 break;
303 default:
304 HAL_ASSERT(false && "Invalid parameter");
305 return;
306 }
307
308 for (int i = 0; i < len; i += 4) {
309 memcpy(&word, buf + i, 4);
310 REG_WRITE(reg + i, word);
311 }
312 }
313
314 /**
315 * @brief Read the ECDSA parameter
316 *
317 * @param param Parameter to be read
318 * @param buf Buffer where the data will be written
319 * @param len Length of buffer
320 */
ecdsa_ll_read_param(ecdsa_ll_param_t param,uint8_t * buf,uint16_t len)321 static inline void ecdsa_ll_read_param(ecdsa_ll_param_t param, uint8_t *buf, uint16_t len)
322 {
323 uint32_t reg;
324 switch (param) {
325 case ECDSA_PARAM_R:
326 reg = ECDSA_R_MEM;
327 break;
328 case ECDSA_PARAM_S:
329 reg = ECDSA_S_MEM;
330 break;
331 case ECDSA_PARAM_Z:
332 reg = ECDSA_Z_MEM;
333 break;
334 case ECDSA_PARAM_QAX:
335 reg = ECDSA_QAX_MEM;
336 break;
337 case ECDSA_PARAM_QAY:
338 reg = ECDSA_QAY_MEM;
339 break;
340 default:
341 HAL_ASSERT(false && "Invalid parameter");
342 return;
343 }
344
345 memcpy(buf, (void *)reg, len);
346 }
347
348 /**
349 * @brief Check if the ECDSA operation is successful
350 *
351 * @return - 1, if ECDSA operation succeeds
352 * - 0, otherwise
353 */
ecdsa_ll_get_operation_result(void)354 static inline int ecdsa_ll_get_operation_result(void)
355 {
356 return REG_GET_BIT(ECDSA_RESULT_REG, ECDSA_OPERATION_RESULT);
357 }
358
359 #ifdef __cplusplus
360 }
361 #endif
362