• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 #pragma once
19 
20 #include "reg_include/register_b91.h"
21 
22 #define GET_WORD_LEN(bitLen) (((bitLen) + 31) / 32)
23 #define GET_BYTE_LEN(bitLen) (((bitLen) + 7) / 8)
24 
25 #define PKE_BASE         (0X80110000)
26 #define reg_pke_a_ram(a) ((volatile unsigned long *)(PKE_BASE + 0x0400 + (a) * (0x24)))
27 #define reg_pke_b_ram(b) ((volatile unsigned long *)(PKE_BASE + 0x1000 + (b) * (0x24)))
28 
29 /********* oprand length *********/
30 #define PKE_OPERAND_MAX_WORD_LEN (0x08)
31 #define PKE_OPERAND_MAX_BIT_LEN  (0x100)
32 #define ECC_MAX_WORD_LEN         PKE_OPERAND_MAX_WORD_LEN
33 #define ECC_MAX_BIT_LEN          PKE_OPERAND_MAX_BIT_LEN
34 
35 #ifndef NULL
36 #define NULL 0
37 #endif
38 
39 /**
40  * eccp curve
41  */
42 typedef struct {
43     unsigned int eccp_p_bitLen;  // bit length of prime p
44     unsigned int eccp_n_bitLen;  // bit length of order n
45     unsigned int *eccp_p;
46     unsigned int *eccp_p_h;
47     unsigned int *eccp_p_n1;
48     unsigned int *eccp_a;
49     unsigned int *eccp_b;
50     unsigned int *eccp_Gx;
51     unsigned int *eccp_Gy;
52     unsigned int *eccp_n;
53     unsigned int *eccp_n_h;
54     unsigned int *eccp_n_n1;
55 } eccp_curve_t;
56 
57 /**
58  * mont curve
59  */
60 typedef struct {
61     unsigned int mont_p_bitLen;  // bit length of prime p
62     unsigned int *mont_p;
63     unsigned int *mont_p_h;
64     unsigned int *mont_p_n1;
65     unsigned int *mont_a24;
66     unsigned int *mont_u;
67     unsigned int *mont_v;
68     unsigned int *mont_n;
69     unsigned int *mont_n_h;
70     unsigned int *mont_n_n1;
71     unsigned int *mont_h;
72 } mont_curve_t;
73 
74 /**
75  * edward curve
76  */
77 typedef struct {
78     unsigned int edward_p_bitLen;  // bit length of prime p
79     unsigned int *edward_p;
80     unsigned int *edward_p_h;
81     unsigned int *edward_p_n1;
82     unsigned int *edward_d;
83     unsigned int *edward_Gx;
84     unsigned int *edward_Gy;
85     unsigned int *edward_n;
86     unsigned int *edward_n_h;
87     unsigned int *edward_n_n1;
88     unsigned int *edward_h;
89 } edward_curve_t;
90 
91 /**
92  * pke return code
93  */
94 typedef enum {
95     PKE_SUCCESS = 0,
96     PKE_ACTIVE_STOP,
97     PKE_MOD_INV_NOT_EXIST,
98     PKE_POINT_NOT_ON_CURVE,
99     PKE_INVALID_MICRO_CODE,
100     PKE_POINTOR_NULL,
101     PKE_INVALID_INPUT,
102 } pke_ret_code_e;
103 
104 /**
105  * pke exe cfg
106  */
107 typedef enum {
108     PKE_EXE_CFG_ALL_NON_MONT = 0x15,
109     PKE_EXE_CFG_ALL_MONT = 0x2A,
110 } pke_exe_cfg_e;
111 
112 /**
113  * pke micro code
114  */
115 typedef enum {
116     PKE_MICROCODE_PDBL = 0x04,
117     PKE_MICROCODE_PADD = 0x08,
118     PKE_MICROCODE_PVER = 0x0C,
119     PKE_MICROCODE_PMUL = 0x10,
120     PKE_MICROCODE_MODMUL = 0x18,
121     PKE_MICROCODE_MODINV = 0x1C,
122     PKE_MICROCODE_MODADD = 0x20,
123     PKE_MICROCODE_MODSUB = 0x24,
124     PKE_MICROCODE_CAL_PRE_MON = 0x28,
125     PKE_MICROCODE_C25519_PMUL = 0x34,
126     PKE_MICROCODE_Ed25519_PMUL = 0x38,
127     PKE_MICROCODE_Ed25519_PADD = 0x3C,
128 } pke_microcode_e;
129 
130 /**
131  * @brief		This function serves to get pke status.
132  * @param[in] 	status	- the interrupt status to be obtained.
133  * @return		pke status.
134  */
pke_get_irq_status(pke_status_e status)135 static inline unsigned int pke_get_irq_status(pke_status_e status)
136 {
137     return reg_pke_stat & status;
138 }
139 
140 /**
141  * @brief		This function serves to clear pke status.
142  * @param[in] 	status	- the interrupt status that needs to be cleared.
143  * @return		none.
144  */
pke_clr_irq_status(pke_status_e status)145 static inline void pke_clr_irq_status(pke_status_e status)
146 {
147     BM_CLR(reg_pke_stat, status);
148 }
149 
150 /**
151  * @brief		This function serves to enable pke interrupt function.
152  * @param[in] 	mask - the irq mask.
153  * @return		none.
154  */
pke_set_irq_mask(pke_conf_e mask)155 static inline void pke_set_irq_mask(pke_conf_e mask)
156 {
157     BM_SET(reg_pke_conf, mask);
158 }
159 
160 /**
161  * @brief		This function serves to disable PKE interrupt function.
162  * @param[in] 	mask - the irq mask.
163  * @return		none.
164  */
pke_clr_irq_mask(pke_conf_e mask)165 static inline void pke_clr_irq_mask(pke_conf_e mask)
166 {
167     BM_CLR(reg_pke_conf, mask);
168 }
169 
170 /**
171  * @brief		set operation micro code.
172  * @param[in]   addr	- pke micro code.
173  * @return		none.
174  */
pke_set_microcode(pke_microcode_e addr)175 static inline void pke_set_microcode(pke_microcode_e addr)
176 {
177     reg_pke_mc_ptr = addr;
178 }
179 
180 /**
181  * @brief		set exe config.
182  * @param[in]	cfg	- pke exe conf.
183  * @return		none.
184  */
pke_set_exe_cfg(pke_exe_cfg_e cfg)185 static inline void pke_set_exe_cfg(pke_exe_cfg_e cfg)
186 {
187     reg_pke_exe_conf = cfg;
188 }
189 
190 /**
191  * @brief		start pke calculate.
192  * @return		none.
193  */
pke_opr_start(void)194 static inline void pke_opr_start(void)
195 {
196     BM_SET(reg_pke_ctrl, FLD_PKE_CTRL_START);
197 }
198 
199 /**
200  * @brief		This is used to indicate the reason when the pke stopped.
201  * @return     	0 - normal stop.
202  * 				1 - received a termination request(CTRL.STOP is high).
203  * 				2 - no valid modulo inverse.
204  * 				3 - point is not on the curve(CTRL.CMD:PVER).
205  * 				4 - invalid microcode.
206  */
pke_check_rt_code(void)207 static inline unsigned char pke_check_rt_code(void)
208 {
209     return (unsigned char)(reg_pke_rt_code & FLD_PKE_RT_CODE_STOP_LOG);
210 }
211 
212 /**
213  * @brief		set operand width please make sure 0 < bitLen <= 256.
214  * @param[in]	bitLen	- operand width.
215  * @return		none.
216  */
pke_set_operand_width(unsigned int bitLen)217 static inline void pke_set_operand_width(unsigned int bitLen)
218 {
219     BM_CLR(reg_pke_conf, FLD_PKE_CONF_PARTIAL_RADIX);
220     BM_SET(reg_pke_conf, GET_WORD_LEN(bitLen) << 16);
221     BM_CLR(reg_pke_conf, FLD_PKE_CONF_BASE_RADIX);
222     BM_SET(reg_pke_conf, 2 << 24);
223 }
224 
225 /**
226  * @brief		compare big integer a and b.
227  * @param[in] 	a 			- value.
228  * @param[in] 	aWordLen  	- the length of a.
229  * @param[in] 	b			- value.
230  * @param[in] 	bWordLen	- the length of b.
231  * @return		0:a=b,   1:a>b,   -1: a<b.
232  */
233 signed int big_integer_compare(unsigned int *a, unsigned int aWordLen, unsigned int *b, unsigned int bWordLen);
234 
235 /**
236  * @brief		c = a - b.
237  * @param[in]   a 		- integer a.
238  * @param[in]   b 		- integer b.
239  * @param[in]   wordLen	- the length of a and b.
240  * @param[out]  c 		- integer c = a - b.
241  * @return		none.
242  */
243 void sub_u32(unsigned int *a, unsigned int *b, unsigned int *c, unsigned int wordLen);
244 
245 /**
246  * @brief		a = a/(2^n).
247  * @param[in]   a			- big integer a.
248  * @param[in]   aWordLen	- word length of a.
249  * @param[in]   n			- exponent of 2^n.
250  * @return		word length of a = a/(2^n).
251  * @attention:	1. make sure aWordLen is real word length of a.
252  *     			2. a may be 0, then aWordLen is 0, to make sure aWordLen-1 is available, so data
253  *        		   type of aWordLen is int32_t, not uint32_t.
254  */
255 unsigned int div2n_u32(unsigned int a[], signed int aWordLen, unsigned int n);
256 
257 /**
258  * @brief		load the pre-calculated mont parameters H(R^2 mod modulus) and
259  * 				n1( - modulus ^(-1) mod 2^w ).
260  * @param[in] 	H 	  	- R^2 mod modulus.
261  * @param[in] 	n1 	  	- modulus ^(-1) mod 2^w, here w is 32 acutally.
262  * @param[in] 	wordLen - word length of modulus or H.
263  * @return: 	none.
264  */
265 void pke_load_pre_calc_mont(unsigned int *H, unsigned int *n1, unsigned int wordLen);
266 
267 /**
268  * @brief		calc h(R^2 mod modulus) and n1( - modulus ^(-1) mod 2^w ) for modmul, pointMul. etc.
269  * 				here w is bit width of word, i,e. 32.
270  * @param[in]   modulus - input, modulus.
271  * @param[in]   wordLen - input, word length of modulus or H.
272  * @return      PKE_SUCCESS(success), other(error).
273  */
274 unsigned char pke_calc_pre_mont(const unsigned int *modulus, unsigned int wordLen);
275 
276 /**
277  * @brief       out = a*b mod modulus.
278  * @param[in]   modulus	- modulus.
279  * @param[in]   a 		- integer a.
280  * @param[in]   b 		- integer b.
281  * @param[in]   wordLen	- word length of modulus, a, b.
282  * @param[out]  out		- out = a*b mod modulus.
283  * @return      PKE_SUCCESS(success), other(error).
284  */
285 unsigned char pke_mod_mul(const unsigned int *modulus, const unsigned int *a, const unsigned int *b, unsigned int *out,
286                           unsigned int wordLen);
287 
288 /**
289  * @brief       ainv = a^(-1) mod modulus.
290  * @param[in]   modulus		- modulus.
291  * @param[in]   a 			- integer a.
292  * @param[in]   modWordLen	- word length of modulus, ainv.
293  * @param[in]   aWordLen 	- word length of integer a.
294  * @param[out]	ainv 		- ainv = a^(-1) mod modulus.
295  * @return: 	PKE_SUCCESS(success), other(inverse not exists or error).
296  */
297 unsigned char pke_mod_inv(const unsigned int *modulus, const unsigned int *a, unsigned int *ainv,
298                           unsigned int modWordLen, unsigned int aWordLen);
299 
300 /**
301  * @brief       out = (a+b) mod modulus.
302  * @param[in]   modulus - modulus.
303  * @param[in]   a 		- integer a.
304  * @param[in]   b 		- integer b.
305  * @param[in]   wordLen - word length of modulus, a, b.
306  * @param[out]  out 	- out = a+b mod modulus.
307  * @return      PKE_SUCCESS(success), other(error).
308  */
309 unsigned char pke_mod_add(const unsigned int *modulus, const unsigned int *a, const unsigned int *b, unsigned int *out,
310                           unsigned int wordLen);
311 
312 /**
313  * @brief       out = (a-b) mod modulus.
314  * @param[in]   modulus	- input, modulus.
315  * @param[in]  	a		- input, integer a.
316  * @param[in]   b		- input, integer b.
317  * @param[in]   wordLen - input, word length of modulus, a, b.
318  * @param[out]  out		- output, out = a-b mod modulus.
319  * @return      PKE_SUCCESS(success), other(error).
320  */
321 unsigned char pke_mod_sub(const unsigned int *modulus, const unsigned int *a, const unsigned int *b, unsigned int *out,
322                           unsigned int wordLen);
323 
324 /**
325  * @brief		c = a mod b.
326  * @param[in]   a 		 	- integer a.
327  * @param[in]   b 		 	- integer b.
328  * @param[in]   aWordLen	- word length of a.
329  * @param[in]   bWordLen	- word length of b.
330  * @param[in]   b_h			- parameter b_h.
331  * @param[in]   b_n1		- parameter b_n1.
332  * @param[out]  c			- c = a mod b.
333  * @return		PKE_SUCCESS(success), other(error).
334  */
335 unsigned char pke_mod(unsigned int *a, unsigned int aWordLen, unsigned int *b, unsigned int *b_h, unsigned int *b_n1,
336                       unsigned int bWordLen, unsigned int *c);
337 
338 /**
339  * @brief       ECCP curve point del point, Q=2P.
340  * @param[in]   curve	- ECCP_CURVE struct pointer.
341  * @param[in]   Px 		- x coordinate of point P.
342  * @param[in]   Py 		- y coordinate of point P.
343  * @param[out]  Qx 		- x coordinate of point Q=2P.
344  * @param[out]  Qy 		- y coordinate of point Q=2P.
345  * @return      PKE_SUCCESS(success), other(error).
346  */
347 unsigned char pke_eccp_point_del(eccp_curve_t *curve, unsigned int *Px, unsigned int *Py, unsigned int *Qx,
348                                  unsigned int *Qy);
349 
350 /**
351  * @brief       check whether the input point P is on ECCP curve or not.
352  * @param[in]   curve	- ECCP_CURVE struct pointer.
353  * @param[in]   Px		- x coordinate of point P.
354  * @param[in]   Py		- y coordinate of point P.
355  * @return      PKE_SUCCESS(success, on the curve), other(error or not on the curve).
356  */
357 unsigned char pke_eccp_point_verify(eccp_curve_t *curve, unsigned int *Px, unsigned int *Py);
358 
359 /**
360  * @brief       ECCP curve point mul(random point), Q=[k]P.
361  * @param[in]   curve	- ECCP_CURVE struct pointer.
362  * @param[in]   k	 	- scalar.
363  * @param[in]   Px 		- x coordinate of point P.
364  * @param[in]   Py 		- y coordinate of point P.
365  * @param[out]  Qx 		- x coordinate of point Q=[k]P.
366  * @param[out]  Qy 		- y coordinate of point Q=[k]P.
367  * @return      PKE_SUCCESS(success), other(error).
368  */
369 unsigned char pke_eccp_point_mul(eccp_curve_t *curve, unsigned int *k, unsigned int *Px, unsigned int *Py,
370                                  unsigned int *Qx, unsigned int *Qy);
371 
372 /**
373  * @brief       ECCP curve point add, Q=P1+P2.
374  * @param[in]   curve	- eccp curve struct pointer.
375  * @param[in]   P1x 	- x coordinate of point P1.
376  * @param[in]   P1y 	- y coordinate of point P1.
377  * @param[in]   P2x 	- x coordinate of point P2.
378  * @param[in]   P2y 	- y coordinate of point P2.
379  * @param[out]  Qx 		- x coordinate of point Q=P1+P2.
380  * @param[out]  Qy 		- y coordinate of point Q=P1+P2.
381  * @return      PKE_SUCCESS(success), other(error).
382  */
383 unsigned char pke_eccp_point_add(eccp_curve_t *curve, unsigned int *P1x, unsigned int *P1y, unsigned int *P2x,
384                                  unsigned int *P2y, unsigned int *Qx, unsigned int *Qy);
385 
386 /**
387  * @brief       c25519 point mul(random point), Q=[k]P.
388  * @param[in]   curve	- c25519 curve struct pointer.
389  * @param[in]  	k		- scalar.
390  * @param[in]   Pu		- u coordinate of point P.
391  * @param[out]  Qu		- u coordinate of point Q=[k]P.
392  * @return      PKE_SUCCESS(success), other(error).
393  */
394 unsigned char pke_x25519_point_mul(mont_curve_t *curve, unsigned int *k, unsigned int *Pu, unsigned int *Qu);
395 
396 /**
397  * @brief       edwards25519 curve point mul(random point), Q=[k]P.
398  * @param[in]   curve	- edwards25519 curve struct pointer.
399  * @param[in]  	k		- scalar.
400  * @param[in]   Px 		- x coordinate of point P.
401  * @param[in]   Py 		- y coordinate of point P.
402  * @param[out]  Qx 		- x coordinate of point Q=[k]P.
403  * @param[out]  Qy 		- y coordinate of point Q=[k]P.
404  * @return      PKE_SUCCESS(success), other(error).
405  */
406 unsigned char pke_ed25519_point_mul(edward_curve_t *curve, unsigned int *k, unsigned int *Px, unsigned int *Py,
407                                     unsigned int *Qx, unsigned int *Qy);
408 
409 /**
410  * @brief       edwards25519 point add, Q=P1+P2.
411  * @param[in]   curve	- edwards25519 curve struct pointer.
412  * @param[in]   P1x 	- x coordinate of point P1.
413  * @param[in]   P1y 	- y coordinate of point P1.
414  * @param[in]   P2x 	- x coordinate of point P2.
415  * @param[in]   P2y 	- y coordinate of point P2.
416  * @param[out]  Qx 		- x coordinate of point Q=P1+P2.
417  * @param[out]  Qy 		- y coordinate of point Q=P1+P2.
418  * @return      PKE_SUCCESS(success), other(error).
419  */
420 unsigned char pke_ed25519_point_add(edward_curve_t *curve, unsigned int *P1x, unsigned int *P1y, unsigned int *P2x,
421                                     unsigned int *P2y, unsigned int *Qx, unsigned int *Qy);
422