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 "hal/ecc_types.h"
12 #include "soc/ecc_mult_reg.h"
13 #include "soc/pcr_struct.h"
14 #include "soc/pcr_reg.h"
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 typedef enum {
21     ECC_PARAM_PX = 0x0,
22     ECC_PARAM_PY,
23     ECC_PARAM_K,
24     ECC_PARAM_QX,
25     ECC_PARAM_QY,
26     ECC_PARAM_QZ,
27 } ecc_ll_param_t;
28 
ecc_ll_power_up(void)29 static inline void ecc_ll_power_up(void)
30 {
31     REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD);
32     REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PD);
33 }
34 
ecc_ll_power_down(void)35 static inline void ecc_ll_power_down(void)
36 {
37     REG_CLR_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_FORCE_PU);
38     REG_SET_BIT(PCR_ECC_PD_CTRL_REG, PCR_ECC_MEM_PD);
39 }
40 
ecc_ll_enable_interrupt(void)41 static inline void ecc_ll_enable_interrupt(void)
42 {
43     REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 1);
44 }
45 
ecc_ll_disable_interrupt(void)46 static inline void ecc_ll_disable_interrupt(void)
47 {
48     REG_SET_FIELD(ECC_MULT_INT_ENA_REG, ECC_MULT_CALC_DONE_INT_ENA, 0);
49 }
50 
ecc_ll_clear_interrupt(void)51 static inline void ecc_ll_clear_interrupt(void)
52 {
53     REG_SET_FIELD(ECC_MULT_INT_CLR_REG, ECC_MULT_CALC_DONE_INT_CLR, 1);
54 }
55 
ecc_ll_set_mode(ecc_mode_t mode)56 static inline void ecc_ll_set_mode(ecc_mode_t mode)
57 {
58     switch(mode) {
59         case ECC_MODE_POINT_MUL:
60             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 0);
61             break;
62         case ECC_MODE_VERIFY:
63             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 2);
64             break;
65         case ECC_MODE_VERIFY_THEN_POINT_MUL:
66             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 3);
67             break;
68         case ECC_MODE_JACOBIAN_POINT_MUL:
69             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 4);
70             break;
71         case ECC_MODE_POINT_ADD:
72             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 5);
73             break;
74         case ECC_MODE_JACOBIAN_POINT_VERIFY:
75             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 6);
76             break;
77         case ECC_MODE_POINT_VERIFY_JACOBIAN_MUL:
78             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 7);
79             break;
80         case ECC_MODE_MOD_ADD:
81             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 8);
82             break;
83         case ECC_MODE_MOD_SUB:
84             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 9);
85             break;
86         case ECC_MODE_MOD_MUL:
87             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 10);
88             break;
89         case ECC_MODE_INVERSE_MUL:
90             REG_SET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE, 11);
91             break;
92         default:
93             HAL_ASSERT(false && "Unsupported mode");
94             break;
95     }
96 }
97 
ecc_ll_set_curve(ecc_curve_t curve)98 static inline void ecc_ll_set_curve(ecc_curve_t curve)
99 {
100     switch(curve) {
101         case ECC_CURVE_SECP256R1:
102             REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
103             break;
104         case ECC_CURVE_SECP192R1:
105             REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
106             break;
107         default:
108             HAL_ASSERT(false && "Unsupported curve");
109             return;
110     }
111 }
112 
ecc_ll_set_mod_base(ecc_mod_base_t base)113 static inline void ecc_ll_set_mod_base(ecc_mod_base_t base)
114 {
115     switch(base) {
116         case ECC_MOD_N:
117             REG_CLR_BIT(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE);
118             break;
119         case ECC_MOD_P:
120             REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE);
121             break;
122         default:
123             HAL_ASSERT(false && "Unsupported curve");
124             return;
125     }
126 }
127 
ecc_ll_write_param(ecc_ll_param_t param,const uint8_t * buf,uint16_t len)128 static inline void ecc_ll_write_param(ecc_ll_param_t param, const uint8_t *buf, uint16_t len)
129 {
130     uint32_t reg;
131     uint32_t word;
132     switch (param) {
133         case ECC_PARAM_PX:
134             reg = ECC_MULT_PX_MEM;
135             break;
136         case ECC_PARAM_PY:
137             reg = ECC_MULT_PY_MEM;
138             break;
139         case ECC_PARAM_K:
140             reg = ECC_MULT_K_MEM;
141             break;
142         case ECC_PARAM_QX:
143             reg = ECC_MULT_QX_MEM;
144             break;
145         case ECC_PARAM_QY:
146             reg = ECC_MULT_QY_MEM;
147             break;
148         case ECC_PARAM_QZ:
149             reg = ECC_MULT_QZ_MEM;
150             break;
151         default:
152             HAL_ASSERT(false && "Invalid parameter");
153             return;
154     }
155 
156     for (int i = 0; i < len; i += 4) {
157         memcpy(&word, buf + i, 4);
158         REG_WRITE(reg + i, word);
159     }
160 }
161 
ecc_ll_start_calc(void)162 static inline void ecc_ll_start_calc(void)
163 {
164     REG_SET_BIT(ECC_MULT_CONF_REG, ECC_MULT_START);
165 }
166 
ecc_ll_is_calc_finished(void)167 static inline int ecc_ll_is_calc_finished(void)
168 {
169     return REG_GET_FIELD(ECC_MULT_INT_RAW_REG, ECC_MULT_CALC_DONE_INT_RAW);
170 }
171 
ecc_ll_get_mode(void)172 static inline ecc_mode_t ecc_ll_get_mode(void)
173 {
174     return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_WORK_MODE);
175 }
176 
ecc_ll_get_verification_result(void)177 static inline int ecc_ll_get_verification_result(void)
178 {
179     return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_VERIFICATION_RESULT);
180 }
181 
ecc_ll_get_curve(void)182 static inline ecc_curve_t ecc_ll_get_curve(void)
183 {
184     return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_KEY_LENGTH);
185 }
186 
ecc_ll_get_mod_base(void)187 static inline ecc_mod_base_t ecc_ll_get_mod_base(void)
188 {
189     return REG_GET_FIELD(ECC_MULT_CONF_REG, ECC_MULT_MOD_BASE);
190 }
191 
ecc_ll_read_param(ecc_ll_param_t param,uint8_t * buf,uint16_t len)192 static inline void ecc_ll_read_param(ecc_ll_param_t param, uint8_t *buf, uint16_t len)
193 {
194     uint32_t reg;
195     switch (param) {
196         case ECC_PARAM_PX:
197             reg = ECC_MULT_PX_MEM;
198             break;
199         case ECC_PARAM_PY:
200             reg = ECC_MULT_PY_MEM;
201             break;
202         case ECC_PARAM_K:
203             reg = ECC_MULT_K_MEM;
204             break;
205         case ECC_PARAM_QX:
206             reg = ECC_MULT_QX_MEM;
207             break;
208         case ECC_PARAM_QY:
209             reg = ECC_MULT_QY_MEM;
210             break;
211         case ECC_PARAM_QZ:
212             reg = ECC_MULT_QZ_MEM;
213             break;
214         default:
215             HAL_ASSERT(false && "Invalid parameter");
216             return;
217     }
218 
219     memcpy(buf, (void *)reg, len);
220 }
221 
222 #ifdef __cplusplus
223 }
224 #endif
225