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