xref: /rk3399_rockchip-uboot/drivers/crypto/rockchip/crypto_v2_pka.c (revision d6f8cec4d54b00221a4e2560b3576fe70b46b8cf)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
4  */
5 
6 #include <common.h>
7 #include <crypto.h>
8 #include <dm.h>
9 #include <linux/errno.h>
10 #include <rockchip/crypto_v2.h>
11 #include <rockchip/crypto_v2_pka.h>
12 
13 #define CRYPT_OK	(0)
14 #define CRYPT_ERROR	(-1)
15 
16 void rk_pka_ram_ctrl_enable(void)
17 {
18 	crypto_write(CRYPTO_RAM_CTL_SEL_MASK | CRYPTO_RAM_CTL_PKA, CRYPTO_RAM_CTL);
19 }
20 
21 void rk_pka_ram_ctrl_disable(void)
22 {
23 	crypto_write(CRYPTO_RAM_CTL_SEL_MASK | CRYPTO_RAM_CTL_CPU, CRYPTO_RAM_CTL);
24 }
25 
26 void rk_pka_wait_on_ram_ready(void)
27 {
28 	u32 output_reg_val;
29 
30 	do {
31 		output_reg_val = crypto_read(CRYPTO_RAM_ST);
32 	} while ((output_reg_val & 0x01) != CRYPTO_CLK_RAM_RDY);
33 }
34 
35 void rk_pka_wait_on_pipe_ready(void)
36 {
37 	u32 output_reg_val;
38 
39 	do {
40 		output_reg_val = crypto_read(CRYPTO_PKA_PIPE_RDY);
41 	} while ((output_reg_val & 0x01) != RK_PKA_PIPE_READY);
42 }
43 
44 void rk_pka_wait_on_done(void)
45 {
46 	u32 output_reg_val;
47 
48 	do {
49 		output_reg_val = crypto_read(CRYPTO_PKA_DONE);
50 	} while ((output_reg_val & 0x01) != RK_PKA_OP_DONE);
51 }
52 
53 void rk_pka_set_startmemaddr_reg(u32 start_mem_addr)
54 {
55 	crypto_write(start_mem_addr, CRYPTO_PKA_MON_READ);
56 }
57 
58 void rk_pka_set_N_NP_T0_T1_reg(u32 N, u32 NP, u32 T0,
59 			       u32 T1)
60 {
61 	rk_pka_wait_on_done();
62 	crypto_write((u32)((N) << RK_PKA_N_NP_T0_T1_REG_N_POS |
63 				(NP) << RK_PKA_N_NP_T0_T1_REG_NP_POS |
64 				(T0) << RK_PKA_N_NP_T0_T1_REG_T0_POS |
65 				(T1) << RK_PKA_N_NP_T0_T1_REG_T1_POS),
66 				CRYPTO_N_NP_T0_T1_ADDR);
67 }
68 
69 void rk_pka_set_default_N_NP_T0_T1_reg(void)
70 {
71 	crypto_write(RK_PKA_N_NP_T0_T1_REG_DEFAULT_VAL, CRYPTO_N_NP_T0_T1_ADDR);
72 }
73 
74 void rk_pka_get_status(u32 *status)
75 {
76 	rk_pka_wait_on_done();
77 	*status = crypto_read(CRYPTO_PKA_STATUS);
78 }
79 
80 void rk_pka_get_status_alu_outzero(u32 *status)
81 {
82 	rk_pka_wait_on_done();
83 	*status = crypto_read(CRYPTO_PKA_STATUS);
84 	*status = ((*status) >> RK_PKA_STATUS_ALU_OUT_ZERO_POS) & 1UL;
85 }
86 
87 void rk_pka_get_status_mod_overfl(u32 *status)
88 {
89 	rk_pka_wait_on_done();
90 	*status = crypto_read(CRYPTO_PKA_STATUS);
91 	*status = ((*status) >> RK_PKA_STATUS_ALU_MODOVRFLW_POS) & 1;
92 }
93 
94 void rk_pka_get_status_div_byzero(u32 *status)
95 {
96 	rk_pka_wait_on_done();
97 	*status = crypto_read(CRYPTO_PKA_STATUS);
98 	*status = ((*status) >> RK_PKA_STATUS_DIV_BY_ZERO_POS) & 1;
99 }
100 
101 void rk_pka_get_status_carry(u32 *status)
102 {
103 	rk_pka_wait_on_done();
104 	*status = crypto_read(CRYPTO_PKA_STATUS);
105 	*status = ((*status) >> RK_PKA_STATUS_ALU_CARRY_POS) & 1;
106 }
107 
108 void rk_pka_get_status_alu_signout(u32 *status)
109 {
110 	rk_pka_wait_on_done();
111 	*status = crypto_read(CRYPTO_PKA_STATUS);
112 	*status = ((*status) >> RK_PKA_STATUS_ALU_SIGN_OUT_POS) & 1;
113 }
114 
115 void rk_pka_get_status_modinv_ofzero(u32 *status)
116 {
117 	rk_pka_wait_on_done();
118 	*status = crypto_read(CRYPTO_PKA_STATUS);
119 	*status = ((*status) >> RK_PKA_STATUS_MODINV_OF_ZERO_POS) & 1;
120 }
121 
122 void rk_pka_get_status_opcode(u32 *status)
123 {
124 	rk_pka_wait_on_done();
125 	*status = crypto_read(CRYPTO_PKA_STATUS);
126 	*status = ((*status) >> RK_PKA_STATUS_OPCODE_POS) &
127 			  RK_PKA_STATUS_OPCODE_MASK;
128 }
129 
130 void rk_pka_get_status_tag(u32 *status)
131 {
132 	rk_pka_wait_on_done();
133 	*status = crypto_read(CRYPTO_PKA_STATUS);
134 	*status = ((*status) >> RK_PKA_STATUS_TAG_POS) & RK_PKA_STATUS_TAG_MASK;
135 }
136 
137 void rk_pka_set_regsize(u32 size_bits, u32 entry_num)
138 {
139 	rk_pka_wait_on_done();
140 	crypto_write(size_bits, CRYPTO_PKA_L0 + 4 * (entry_num));
141 }
142 
143 void rk_pka_read_regsize(u32 *size_bits, u32 entry_num)
144 {
145 	rk_pka_wait_on_done();
146 	*size_bits = crypto_read(CRYPTO_PKA_L0 + 4 * (entry_num));
147 }
148 
149 void rk_pka_set_regaddr(u32 vir_reg, u32 phys_addr)
150 {
151 	rk_pka_wait_on_done();
152 	crypto_write(phys_addr, CRYPTO_MEMORY_MAP0 + 4 * (vir_reg));
153 }
154 
155 void rk_pka_get_regaddr(u32 vir_reg, u32 *phys_addr)
156 {
157 	*phys_addr = crypto_read(CRYPTO_MEMORY_MAP0 + 4 * (vir_reg));
158 }
159 
160 void rk_pka_read_regaddr(u32 vir_reg, u32 *phys_addr)
161 {
162 	rk_pka_wait_on_done();
163 	*phys_addr = crypto_read(CRYPTO_MEMORY_MAP0 + 4 * (vir_reg));
164 }
165 
166 u32 rk_pka_make_full_opcode(u32 opcode, u32 len_id,
167 			    u32 is_a_immed, u32 op_a,
168 			    u32 is_b_immed, u32 op_b,
169 			    u32 res_discard, u32 res,
170 			    u32 tag)
171 {
172 	u32 full_opcode;
173 
174 	full_opcode =
175 		(((u32)(opcode) & 31) << RK_PKA_OPCODE_OPERATION_ID_POS |
176 		((u32)(len_id) & 7) << RK_PKA_OPCODE_LEN_POS |
177 		((u32)(is_a_immed) & 1) << RK_PKA_OPCODE_OPERAND_1_IMMED_POS |
178 		((u32)(op_a) & 31)	<< RK_PKA_OPCODE_OPERAND_1_POS	|
179 		((u32)(is_b_immed) & 1) << RK_PKA_OPCODE_OPERAND_2_IMMED_POS |
180 		((u32)(op_b) & 31) << RK_PKA_OPCODE_OPERAND_2_POS	|
181 		((u32)(res_discard) & 1) << RK_PKA_OPCODE_R_DISCARD_POS	|
182 		((u32)(res) & 31) << RK_PKA_OPCODE_RESULT_POS |
183 		((u32)(tag) & 31) << RK_PKA_OPCODE_TAG_POS);
184 	return full_opcode;
185 }
186 
187 void rk_pka_hw_load_value2pka_mem(u32 addr, u32 val)
188 {
189 	u32 *vaddr;
190 
191 	vaddr = (u32 *)((addr) + RK_PKA_DATA_REGS_MEMORY_OFFSET_ADDR);
192 	rk_pka_ram_ctrl_disable();
193 	rk_pka_wait_on_ram_ready();
194 	*vaddr = val;
195 	rk_pka_ram_ctrl_enable();
196 }
197 
198 void rk_pka_hw_load_block2pka_mem(u32 addr, u32 *ptr,
199 				  u32 size_words)
200 {
201 	u8 *vaddr =
202 		(u8 *)((addr) + RK_PKA_DATA_REGS_MEMORY_OFFSET_ADDR);
203 
204 	rk_pka_ram_ctrl_disable();
205 	rk_pka_wait_on_ram_ready();
206 	RK_PKA_FastMemCpy(vaddr, (u8 *)ptr, size_words);
207 	rk_pka_ram_ctrl_enable();
208 }
209 
210 void rk_pka_hw_reverse_load_block2pka_mem(u32 addr, u32 *ptr,
211 					  u32 size_words)
212 {
213 	u8 *vaddr =
214 		(u8 *)((addr) + RK_PKA_DATA_REGS_MEMORY_OFFSET_ADDR);
215 
216 	rk_pka_ram_ctrl_disable();
217 	rk_pka_wait_on_ram_ready();
218 	RK_PKA_ReverseMemcpy(vaddr, (u8 *)ptr, size_words);
219 	rk_pka_ram_ctrl_enable();
220 }
221 
222 void rk_pka_hw_clear_pka_mem(u32 addr, u32 size_words)
223 {
224 	u8 *vaddr =
225 		(u8 *)((addr) + RK_PKA_DATA_REGS_MEMORY_OFFSET_ADDR);
226 
227 	rk_pka_ram_ctrl_disable();
228 	rk_pka_wait_on_ram_ready();
229 	RK_PKA_MemSetZero(vaddr, size_words);
230 	rk_pka_ram_ctrl_enable();
231 }
232 
233 void rk_pka_hw_read_value_from_pka_mem(u32 addr, u32 *val)
234 {
235 	u32 *vaddr;
236 
237 	vaddr = (u32 *)((addr) + RK_PKA_DATA_REGS_MEMORY_OFFSET_ADDR);
238 	rk_pka_ram_ctrl_disable();
239 	rk_pka_wait_on_ram_ready();
240 	*val = *vaddr;
241 	rk_pka_ram_ctrl_enable();
242 }
243 
244 void rk_pka_hw_read_block_from_pka_mem(u32 addr, u32 *ptr,
245 				       u32 size_words)
246 {
247 	u8 *vaddr =
248 		(u8 *)((addr) + RK_PKA_DATA_REGS_MEMORY_OFFSET_ADDR);
249 
250 	rk_pka_ram_ctrl_disable();
251 	rk_pka_wait_on_ram_ready();
252 	RK_PKA_FastMemCpy((u8 *)(ptr), vaddr, size_words);
253 	rk_pka_ram_ctrl_enable();
254 }
255 
256 void rk_pka_hw_reverse_read_block_from_pka_mem(u32 addr, u32 *ptr,
257 					       u32 size_words)
258 {
259 	u8 *vaddr =
260 		(u8 *)((addr) + RK_PKA_DATA_REGS_MEMORY_OFFSET_ADDR);
261 
262 	rk_pka_ram_ctrl_disable();
263 	rk_pka_wait_on_ram_ready();
264 	RK_PKA_ReverseMemcpy((u8 *)(ptr), vaddr,
265 			     size_words * sizeof(u32));
266 	rk_pka_ram_ctrl_enable();
267 }
268 
269 u32 rk_pka_exec_operation(u32 opcode, u8 len_id,
270 			  u8 is_a_immed, s8 op_a,
271 			  u8 is_b_immed, s8 op_b,
272 			  u8 res_discard, s8 res, u8 tag)
273 {
274 	u32 status;
275 	u32 full_opcode;
276 	u32 error = CRYPT_OK;
277 
278 	if (res == RES_DISCARD) {
279 		res_discard = 1;
280 		res = 0;
281 	}
282 
283 	full_opcode = rk_pka_make_full_opcode(opcode, len_id,
284 					      is_a_immed, op_a,
285 					      is_b_immed, op_b,
286 					      res_discard, res, tag);
287 
288 	/* write full opcode into PKA CRYPTO_OPCODE register */
289 	crypto_write(full_opcode, CRYPTO_OPCODE);
290 
291 	/*************************************************/
292 	/* finishing operations for different cases      */
293 	/*************************************************/
294 	switch (opcode) {
295 	case PKA_Div:
296 		/* for Div operation check, that op_b != 0*/
297 		rk_pka_get_status_div_byzero(&status);
298 		if (status == 1) {
299 			error = RK_PKA_DIVIDER_IS_NULL_ERROR;
300 			goto end;
301 		}
302 		break;
303 	case PKA_Terminate:
304 		/* wait for PKA done bit */
305 		rk_pka_wait_on_done();
306 		break;
307 	default:
308 		/* wait for PKA pipe ready bit */
309 		rk_pka_wait_on_pipe_ready();
310 	}
311 
312 end:
313 	return error;
314 }
315 
316 u32 rk_pka_set_sizes_tab(u32 regs_sizes_ptr[RK_PKA_MAX_REGS_COUNT],
317 			 u32 count_of_sizes, u32 max_size_bits,
318 			 u32 is_default_map)
319 {
320 	u32 i;
321 	u32 error;
322 	u32 max_size, min_size, maxsize_words;
323 
324 	error = CRYPT_OK;
325 	max_size = 0;
326 	min_size = 0xFFFFFFFF;
327 
328 	if (is_default_map > 1)
329 		return  RK_PKA_SET_MAP_MODE_ERROR;
330 
331 	/* 1. Case of user defined settings */
332 	if (is_default_map == 0) {
333 		/* find maximal and minimal sizes  */
334 		for (i = 0; i < count_of_sizes; i++) {
335 			if (max_size < regs_sizes_ptr[i] &&
336 			    regs_sizes_ptr[i] != 0xFFFFFFFF)
337 				max_size = regs_sizes_ptr[i];
338 
339 			if (min_size > regs_sizes_ptr[i])
340 				min_size = regs_sizes_ptr[i];
341 		}
342 
343 		/* set sizes into PKA registers sizes table */
344 		for (i = 0; i < count_of_sizes; i++)
345 			crypto_write(regs_sizes_ptr[i], CRYPTO_PKA_L0 + 4 * i);
346 	} else {
347 		/* 2. Case of default settings */
348 		maxsize_words = (max_size_bits + 31) / 32;
349 		/* write exact size into first table entry */
350 		crypto_write(max_size_bits, CRYPTO_PKA_L0);
351 
352 		/* write size with extra word into tab[1] = tab[0] + 32 */
353 		crypto_write(32 * maxsize_words + 32, CRYPTO_PKA_L0 + 4);
354 
355 		/* count of entries, which was set */
356 		count_of_sizes = 2;
357 	}
358 
359 	for (i = count_of_sizes; i < 8; i++)
360 		crypto_write(0xFFFFFFFF, CRYPTO_PKA_L0 + 4 * i);
361 
362 	return error;
363 }
364 
365 u32 rk_pka_set_map_tab(struct rk_pka_regs_map *regs_map_ptr,
366 		       u32 *count_of_regs, u32 maxsize_words,
367 		       u32 N_NP_T0_T1, u32 is_default_map)
368 {
369 	u32 i;
370 	u32 error;
371 	u32 cur_addr;
372 	u32 default_max_size, default_count_of_regs;
373 
374 	error = CRYPT_OK;
375 	cur_addr = 0;
376 
377 	if (is_default_map == 1) {
378 		default_max_size = 32 * maxsize_words;
379 		default_count_of_regs =
380 			min(32, (8 * RK_PKA_MAX_REGS_MEM_SIZE_BYTES) /
381 				default_max_size);
382 
383 		for (i = 0; i < 32 - 2; i++) {
384 			if (i < default_count_of_regs - 2) {
385 				crypto_write(cur_addr,
386 					     CRYPTO_MEMORY_MAP0 + 4 * i);
387 				cur_addr = cur_addr + default_max_size / 8;
388 			} else {
389 				crypto_write(0xFFC, CRYPTO_MEMORY_MAP0 + 4 * i);
390 			}
391 		}
392 		crypto_write(cur_addr, CRYPTO_MEMORY_MAP0 + 4 * 30);
393 		cur_addr = cur_addr + default_max_size / 8;
394 		crypto_write(cur_addr, CRYPTO_MEMORY_MAP0 + 4 * 31);
395 		*count_of_regs = default_count_of_regs;
396 		crypto_write((u32)RK_PKA_N_NP_T0_T1_REG_DEFAULT_VAL,
397 			     CRYPTO_N_NP_T0_T1_ADDR);
398 	}
399 
400 	if (is_default_map == 0) {
401 		for (i = 0; i < *count_of_regs; i++)
402 			crypto_write(regs_map_ptr->regs_addr[i],
403 				     CRYPTO_MEMORY_MAP0 +
404 				     4 * regs_map_ptr->reges_num[i]);
405 
406 		crypto_write(N_NP_T0_T1, CRYPTO_N_NP_T0_T1_ADDR);
407 	}
408 
409 	return error;
410 }
411 
412 u32 rk_pka_clear_block_of_regs(u8 first_reg, u8 count_of_regs,
413 			       u8 len_id)
414 {
415 	u32 i;
416 	u32 size, addr;
417 	s32 count_temps;
418 
419 	rk_pka_read_regsize(&size, len_id);
420 
421 	count_temps = 0;
422 
423 	if (first_reg + count_of_regs > 30) {
424 		count_temps = min((count_of_regs + first_reg - 30), 2);
425 		count_of_regs = 30;
426 	} else {
427 		count_temps = 2;
428 	}
429 
430 	/* clear ordinary registers */
431 	for (i = 0; i < count_of_regs; i++)
432 		RK_PKA_Clr(len_id, first_reg + i/*regNum*/, 0/*tag*/);
433 
434 	/* clear PKA temp registers using macros (without PKA operations */
435 	if (count_temps > 0) {
436 		/* calculate size of register in words */
437 		size = (size + 31) / 32;
438 		rk_pka_wait_on_done();
439 		rk_pka_get_regaddr(30/*vir_reg*/, &addr/*phys_addr*/);
440 		rk_pka_hw_clear_pka_mem(addr, size);
441 
442 		if (count_temps > 1) {
443 			rk_pka_get_regaddr(31/*vir_reg*/, &addr/*phys_addr*/);
444 			rk_pka_hw_clear_pka_mem(addr, size);
445 		}
446 	}
447 	return CRYPT_OK;
448 }
449 
450 u32 rk_pka_init(u32 regs_sizes_ptr[RK_PKA_MAX_REGS_COUNT], u32 count_of_sizes,
451 		struct rk_pka_regs_map *regs_map_ptr, u32 count_of_regs,
452 		u32 op_size_bits, u32 regsize_words,
453 		u32 N_NP_T0_T1, u32 is_default_map)
454 {
455 	u32 addr;
456 	u32 error;
457 
458 	error = CRYPT_OK;
459 
460 	PKA_CLK_ENABLE();
461 	rk_pka_ram_ctrl_enable();
462 
463 	error = rk_pka_set_sizes_tab(regs_sizes_ptr, count_of_sizes,
464 				     op_size_bits, is_default_map);
465 
466 	if (error != CRYPT_OK)
467 		return error;
468 
469 	error = rk_pka_set_map_tab(regs_map_ptr, &count_of_regs, regsize_words,
470 				   N_NP_T0_T1, is_default_map);
471 
472 	if (error != CRYPT_OK)
473 		return error;
474 
475 	/* set size of register into RegsSizesTable */
476 	crypto_write(32 * regsize_words, CRYPTO_PKA_L0 + 3 * 4);
477 
478 	/* clean PKA data memory */
479 	rk_pka_clear_block_of_regs(0, count_of_regs - 2, 3);
480 
481 	/* clean temp PKA registers 30,31 */
482 	rk_pka_wait_on_done();
483 	rk_pka_get_regaddr(30/*vir_reg*/, &addr/*phys_addr*/);
484 	rk_pka_hw_clear_pka_mem(addr, regsize_words);
485 	rk_pka_get_regaddr(31/*vir_reg*/, &addr/*phys_addr*/);
486 	rk_pka_hw_clear_pka_mem(addr, regsize_words);
487 
488 	return error;
489 }
490 
491 void rk_pka_finish(void)
492 {
493 	RK_PKA_Terminate(0);
494 	rk_pka_ram_ctrl_disable();
495 	PKA_CLK_DISABLE();
496 }
497 
498 void rk_pka_copy_data_into_reg(s8 dst_reg, u8 len_id,
499 			       u32 *src_ptr, u32 size_words)
500 {
501 	u32 cur_addr;
502 	u32 reg_size;
503 
504 	RK_PKA_Terminate(0);
505 
506 	rk_pka_read_regaddr(dst_reg, &cur_addr);
507 
508 	rk_pka_read_regsize(&reg_size, len_id);
509 	reg_size = (reg_size + 31) / 32;
510 
511 	rk_pka_hw_load_block2pka_mem(cur_addr, src_ptr, size_words);
512 	cur_addr = cur_addr + sizeof(u32) * size_words;
513 
514 	rk_pka_hw_clear_pka_mem(cur_addr, reg_size - size_words);
515 }
516 
517 void rk_pka_copy_data_from_reg(u32 *dst_ptr, u32 size_words,
518 			       s8 src_reg)
519 {
520 	u32 cur_addr;
521 
522 	crypto_write(0, CRYPTO_OPCODE);
523 
524 	rk_pka_wait_on_done();
525 
526 	rk_pka_read_regaddr(src_reg, &cur_addr);
527 
528 	rk_pka_hw_read_block_from_pka_mem(cur_addr, dst_ptr, size_words);
529 }
530 
531 u32 rk_pka_calcNp_and_initmodop(u32 len_id, u32 mod_size_bits,
532 				s8 r_t0, s8 r_t1, s8 r_t2)
533 {
534 	u32 i;
535 	u32 s;
536 	u32 error;
537 	u32 num_bits, num_words;
538 
539 	/* Set s = 132 */
540 	s = 132;
541 
542 	/*-------------------------------------------------------------------*/
543 	/* Step 1,2. Set registers: Set op_a = 2^(sizeN+32)                  */
544 	/*           Registers using: 0 - N (is set in register 0,           */
545 	/*           1 - NP, temp regs: r_t0 (A), r_t1, r_t2.                */
546 	/*           len_id: 0 - exact size, 1 - exact+32 bit                */
547 	/*-------------------------------------------------------------------*/
548 
549 	/* set register r_t0 = 0 */
550 	RK_PKA_Clr(len_id + 1, r_t0/*op_a*/, 0/*tag*/); /* r2 = 0 */
551 
552 	/* calculate bit position of said bit in the word */
553 	num_bits = mod_size_bits % 32;
554 	num_words = mod_size_bits / 32;
555 
556 	/* set 1 into register r_t0 */
557 	RK_PKA_Set0(len_id + 1, r_t0/*op_a*/, r_t0/*res*/, 0/*tag*/);
558 
559 	/* shift 1 to num_bits+31 position */
560 	if (num_bits > 0)
561 		RK_PKA_SHL0(len_id + 1, r_t0/*op_a*/, num_bits - 1/*s*/,
562 			    r_t0/*res*/, 0/*tag*/);
563 
564 	/* shift to word position */
565 	for (i = 0; i < num_words; i++)
566 		RK_PKA_SHL0(len_id + 1, r_t0/*op_a*/, 31/*s*/,
567 			    r_t0/*res*/, 0/*tag*/);
568 
569 	/*-------------------------------------------------------------------*/
570 	/* Step 3.  Dividing:  (op_a * 2**s) / N                             */
571 	/*-------------------------------------------------------------------*/
572 	error = rk_pka_div_long_num(len_id,        /*len_id*/
573 				    r_t0,          /*op_a*/
574 				    s,            /*shift*/
575 				    0,            /*op_b = N*/
576 				    1,            /*res NP*/
577 				    r_t1,          /*temp reg*/
578 				    r_t2           /*temp reg*/);
579 
580 	return error;
581 
582 }  /* END OF LLF_PKI_PKA_ExecCalcNpAndInitModOp */
583 
584 /***********   LLF_PKI_PKA_DivLongNum function      **********************/
585 /**
586  * @brief The function divides long number A*(2^S) by B:
587  *            res =  A*(2^S) / B,  remainder A = A*(2^S) % B.
588  *        where: A,B - are numbers of size, which is not grate than,
589  *		 maximal operands size,
590  *		 and B > 2^S;
591  *               S  - exponent of binary factor of A.
592  *               ^  - exponentiation operator.
593  *
594  *        The function algorithm:
595  *
596  *        1. Let nWords = S/32; nBits = S % 32;
597  *        2. Set res = 0, r_t1 = op_a;
598  *        3. for(i=0; i<=nWords; i++) do:
599  *            3.1. if(i < nWords )
600  *                   s1 = 32;
601  *                 else
602  *                   s1 = nBits;
603  *            3.2. r_t1 = r_t1 << s1;
604  *            3.3. call PKA_div for calculating the quotient and remainder:
605  *                      r_t2 = floor(r_t1/op_b) //quotient;
606  *                      r_t1 = r_t1 % op_b   //remainder (is in r_t1 register);
607  *            3.4. res = (res << s1) + r_t2;
608  *           end do;
609  *        4. Exit.
610  *
611  *        Assuming:
612  *                  - 5 PKA registers are used: op_a, op_b, res, r_t1, r_t2.
613  *                  - The registers sizes and mapping tables are set on
614  *                    default mode according to operands size.
615  *                  - The PKA clocks are initialized.
616  *        NOTE !   Operand op_a shall be overwritten by remainder.
617  *
618  * @param[in] len_id    - ID of operation size (modSize+32).
619  * @param[in] op_a      - Operand A: virtual register pointer of A.
620  * @param[in] S        - exponent of binary factor of A.
621  * @param[in] op_b      - Operand B: virtual register pointer of B.
622  * @param[in] res      - Virtual register pointer for result quotient.
623  * @param[in] r_t1      - Virtual pointer to remainder.
624  * @param[in] r_t2      - Virtual pointer of temp register.
625  * @param[in] VirtualHwBaseAddr -  Virtual HW base address, passed by user.
626  *
627  * @return CRYSError_t - On success CRYPT_OK is returned:
628  *
629  */
630 u32 rk_pka_div_long_num(u8 len_id, s8 op_a, u32 s,
631 			s8 op_b, s8 res, s8 r_t1, s8 r_t2)
632 {
633 	s8 s1;
634 	u32  i;
635 	u32  n_bits, n_words;
636 
637 	/* calculate shifting parameters (words and bits ) */
638 	n_words = ((u32)s + 31) / 32;
639 	n_bits = (u32)s % 32;
640 
641 	/* copy operand op_a (including extra word) into temp reg r_t1 */
642 	RK_PKA_Copy(len_id + 1, r_t1/*dst*/, op_a/*src*/, 0 /*tag*/);
643 
644 	/* set res = 0 (including extra word) */
645 	RK_PKA_Clear(len_id + 1, res/*dst*/, 0 /*tag*/);
646 
647 	/* set s1 = 0 for first dividing in loop */
648 	s1 = 0;
649 
650 	/*----------------------------------------------------*/
651 	/* Step 1.  Shifting and dividing loop                */
652 	/*----------------------------------------------------*/
653 	for (i = 0; i < n_words; i++) {
654 		/* 3.1 set shift value s1  */
655 		if (i > 0)
656 			s1 = 32;
657 		else
658 			s1 = n_bits;
659 
660 		/* 3.2. shift: r_t1 = r_t1 * 2**s1 (in code (s1-1),
661 		 * because PKA performs s+1 shifts)
662 		 */
663 		if (s1 > 0)
664 			RK_PKA_SHL0(len_id + 1, r_t1/*op_a*/, (s1 - 1)/*s*/,
665 				    r_t1/*res*/, 0/*tag*/);
666 
667 		/* 3.3. perform PKA_Div for calculating a quotient
668 		 * r_t2 = floor(r_t1 / N)
669 		and remainder r_t1 = r_t1 % op_b
670 		 */
671 		RK_PKA_Div(len_id + 1, r_t1/*op_a*/, op_b/*B*/, r_t2/*res*/,
672 			   0/*tag*/);
673 
674 		/* 3.4. res = res * 2**s1 + res;   */
675 		if (s1 > 0)
676 			RK_PKA_SHL0(len_id + 1, res /*op_a*/, (s1 - 1)/*s*/,
677 				    res /*res*/, 0 /*tag*/);
678 
679 		RK_PKA_Add(len_id + 1, res/*op_a*/, r_t2/*op_b*/, res/*res*/,
680 			   0/*tag*/);
681 	}
682 
683 	rk_pka_wait_on_done();
684 	return CRYPT_OK;
685 }  /* END OF LLF_PKI_PKA_DivLongNum */
686 
687 /******LLF_PKI_CalcNpAndInitModOp function (physical pointers)***************/
688 /**
689  * @brief The function initializes  modulus and Barret tag NP,
690  *	      used in modular PKA operations.
691  *
692  *        The function does the following:
693  *          - calculates mod size in bits and sets it into PKA table sizes;
694  *          - if parameter NpCreateFlag = PKA_CreateNP, then the function
695  *            writes the modulus and the tag into registers
696  *            r0 and r1 accordingly;
697  *          - if NpCreateFlag= PKA_SetNP, the function calls the
698  *            LLF_PKI_PKA_ExecCalcNpAndInitModOp, which calculates the Barret
699  *            tag NP and initializes PKA registers; then the function outputs
700  *            calcu1lated NP value.
701  *
702  *       Assumings: - The registers mapping table is set on default mode,
703  *            according to modulus size:
704  *         -- count of allowed registers is not less, than 7 (including 3
705  *            registers r_t0,r_t2,rT3 for internal calculations and 4 default
706  *            special registers N,NP,T0,T1);
707  *         -- modulus exact and exact+32 bit sizes should be set into first
708  *            two entries of sizes-table accordingly.
709  *
710  * @param[in]  N_ptr        - The pointer to the buffer, containing modulus N,
711  * @param[in]  N_sizeBits   - The size of modulus in bytes, must be
712  *				16 <= N_sizeBytes <= 264.
713  * @param[out] NP_ptr       - The pointer to the buffer, containing
714  *				result - modulus tag NP.
715  * @param[in]  NpCreateFlag - Parameter, defining whether the NP shall be
716  *				taken from NP buffer and set into
717  *                            PKA register NP ( NpCreateFlag= PKA_CreateNP= 1 )
718  *                            or it shall be calculated and send to
719  *                            NP buffer ( NpCreateFlag= PKA_SetNP= 0 ).
720  * @param[in]  r_t0,r_t1,r_t2  - Virtual pointers to temp registers
721  *						  (sequence numbers).
722  * @param[in]  VirtualHwBaseAddr -  Virtual HW base address, passed by user.
723  *
724  * @return CRYSError_t - On success CRYPT_OK is returned,
725  *				on failure an error code:
726  *				LLF_PKI_PKA_ILLEGAL_PTR_ERROR
727  *				LLF_PKI_PKA_ILLEGAL_OPERAND_LEN_ERROR
728  *
729  */
730 u32 rk_calcNp_and_initmodop(u32 *N_ptr, u32 N_size_bits,
731 			    u32 *NP_ptr, u8 np_create_flag,
732 			    s8 r_t0, s8 r_t1, s8 r_t2)
733 {
734 	u32 N_size_words;
735 	u32 error = CRYPT_OK;
736 
737 	/* calculate size of modulus in bytes and in words */
738 	N_size_words = (N_size_bits + 31) / 32;
739 
740 	/* copy modulus N into r0 register */
741 	rk_pka_copy_data_into_reg(0/*dst_reg*/, 1/*len_id*/, N_ptr/*src_ptr*/,
742 				  N_size_words);
743 
744 	/* if np_create_flag == PKA_SetNP, then set NP into PKA register r1 */
745 	if (np_create_flag == RK_PKA_SET_NP) {
746 		/* copy the NP into r1 register NP */
747 		rk_pka_copy_data_into_reg(1/*dst_reg*/, 1/*len_id*/,
748 					  NP_ptr/*src_ptr*/,
749 					  RK_PKA_BARRETT_IN_WORDS);
750 	} else {
751 		/*---------------------------------------------------------*/
752 		/*     execute calculation of NP and initialization of PKA */
753 		/*---------------------------------------------------------*/
754 
755 		rk_pka_calcNp_and_initmodop(0/*len_id*/, N_size_bits,
756 					    r_t0, r_t1, r_t2);
757 
758 		/* output of NP value */
759 		rk_pka_copy_data_from_reg(NP_ptr/*dst_ptr*/,
760 					  RK_PKA_BARRETT_IN_WORDS,
761 					  1/*srcReg*/);
762 	}
763 	/* End of the function */
764 	return error;
765 } /* END OF LLF_PKI_CalcNpAndInitModOp */
766 
767 #define RK_NEG_SIGN -1
768 #define RK_POS_SIGN  1
769 
770 #define RK_WORD_SIZE                  32
771 
772 #define rk_mpanum_is_zero(x) ((x)->size == 0)
773 #define rk_mpanum_neg(x) ((x)->size = -((x)->size))
774 #define rk_mpanum_size(x) ((int)((x)->size >= 0 ? \
775 				 (x)->size : -(x)->size))
776 #define rk_mpanum_sign(x) ((x)->size >= 0 ? RK_POS_SIGN : RK_NEG_SIGN)
777 #define rk_mpanum_msw(x) ((x)->d[rk_mpanum_size(x) - 1])
778 
779 /*  --------------------------------------------------------------------
780  *  Function:  mpa_highest_bit_index
781  *  Returns the index of the highest 1 in |src|.
782  *  The index starts at 0 for the least significant bit.
783  *  If src == zero, it will return -1
784  *
785  */
786 static int mpa_highest_bit_index(const struct mpa_num *src)
787 {
788 	u32 w;
789 	u32 b;
790 
791 	if (rk_mpanum_is_zero(src))
792 		return -1;
793 
794 	w = rk_mpanum_msw(src);
795 
796 	for (b = 0; b < RK_WORD_SIZE; b++) {
797 		w >>= 1;
798 		if (w == 0)
799 			break;
800 	}
801 	return (int)(rk_mpanum_size(src) - 1) * RK_WORD_SIZE + b;
802 }
803 
804 
805 /* c = |a| + |b| */
806 int rk_abs_add(void *a, void *b, void *c)
807 {
808 	int max_word_size;
809 	u32 error = CRYPT_OK;
810 	struct mpa_num *m_a, *m_b, *m_c;
811 
812 	m_a = (struct mpa_num *)a;
813 	m_b = (struct mpa_num *)b;
814 	m_c = (struct mpa_num *)c;
815 
816 	max_word_size = rk_mpanum_size(m_a);
817 	if (max_word_size < rk_mpanum_size(m_b))
818 		max_word_size = rk_mpanum_size(m_b);
819 
820 	error = RK_PKA_DefaultInitPKA(max_word_size * 32, max_word_size + 1);
821 	if (error != CRYPT_OK)
822 		goto exit;
823 
824 	rk_pka_copy_data_into_reg(2/*dst_reg*/, 1/*len_id*/, m_a->d,
825 				  rk_mpanum_size(m_a));
826 	rk_pka_copy_data_into_reg(3/*dst_reg*/, 1/*len_id*/, m_b->d,
827 				  rk_mpanum_size(m_b));
828 	RK_PKA_Add(1/*len_id*/, 2/*op_a*/, 3/*op_b*/, 4/*res*/, 0/*tag*/);
829 	rk_pka_copy_data_from_reg(m_c->d, max_word_size + 1,
830 				  4/*srcReg*/);
831 
832 	m_c->size = rk_check_size(m_c->d,  max_word_size + 1);
833 
834 	rk_pka_clear_block_of_regs(0/*FirstReg*/, 5/*Count*/, 1/*len_id*/);
835 	rk_pka_clear_block_of_regs(30/*FirstReg*/, 2/*Count*/, 1/*len_id*/);
836 	rk_pka_finish();
837 
838 exit:
839 	return error;
840 }
841 
842 /*c = a % b*/
843 int rk_mod(void *a, void *b, void *c)
844 {
845 	int max_word_size;
846 	u32 error = CRYPT_OK;
847 	struct mpa_num *m_a, *m_b, *m_c;
848 
849 	m_a = (struct mpa_num *)a;
850 	m_b = (struct mpa_num *)b;
851 	m_c = (struct mpa_num *)c;
852 
853 	if (!a || !b || !c || rk_mpanum_size(m_b) == 0) {
854 		error = CRYPT_ERROR;
855 		goto exit;
856 	}
857 
858 	max_word_size = rk_mpanum_size(m_a);
859 	if (max_word_size < rk_mpanum_size(m_b))
860 		max_word_size = rk_mpanum_size(m_b);
861 
862 	error = RK_PKA_DefaultInitPKA(max_word_size * 32, max_word_size + 1);
863 	if (error != CRYPT_OK)
864 		goto exit;
865 
866 	rk_pka_copy_data_into_reg(2/*dst_reg*/, 1/*len_id*/,
867 				  m_a->d/*src_ptr*/,
868 				  rk_mpanum_size(m_a));
869 	rk_pka_copy_data_into_reg(3/*dst_reg*/, 1/*len_id*/,
870 				  m_b->d/*src_ptr*/,
871 				  rk_mpanum_size(m_b));
872 	RK_PKA_Div(0/*len_id*/, 2/*op_a*/, 3/*op_b*/, 4/*res*/, 0/*tag*/);
873 	rk_pka_copy_data_from_reg(m_c->d,  max_word_size, 2/*srcReg*/);
874 	m_c->size = rk_check_size(m_c->d, max_word_size);
875 
876 	rk_pka_clear_block_of_regs(0/*FirstReg*/, 5/*Count*/, 1/*len_id*/);
877 	rk_pka_clear_block_of_regs(30/*FirstReg*/, 2/*Count*/, 1/*len_id*/);
878 	rk_pka_finish();
879 
880 exit:
881 	return error;
882 }
883 
884 /*d = (a ^ b) % c*/
885 int rk_exptmod(void *a, void *b, void *c, void *d)
886 {
887 	struct mpa_num *tmpa;
888 	u32 op_Np[5];
889 	u32 error = CRYPT_OK;
890 	int max_word_size, exact_size;
891 	struct mpa_num *m_b, *m_c, *m_d;
892 
893 	m_b = (struct mpa_num *)b;
894 	m_c = (struct mpa_num *)c;
895 	m_d = (struct mpa_num *)d;
896 
897 	if (rk_mpa_alloc(&tmpa, NULL, RK_MAX_RSA_BWORDS) != 0)
898 		return CRYPT_ERROR;
899 
900 	error = rk_mod(a, c, tmpa);
901 	if (error) {
902 		error = CRYPT_ERROR;
903 		goto exit;
904 	}
905 
906 	if (!a || !b || !c || !d || rk_mpanum_size(m_c) == 0) {
907 		error = CRYPT_ERROR;
908 		goto exit;
909 	}
910 
911 	max_word_size = rk_mpanum_size(tmpa);
912 	if (max_word_size < rk_mpanum_size(m_b))
913 		max_word_size = rk_mpanum_size(m_b);
914 	if (max_word_size < rk_mpanum_size(m_c))
915 		max_word_size = rk_mpanum_size(m_c);
916 
917 	error = RK_PKA_DefaultInitPKA(max_word_size * 32, max_word_size + 1);
918 	if (error != CRYPT_OK)
919 		goto exit;
920 
921 	/* write exact size into first table entry */
922 	exact_size = mpa_highest_bit_index(m_c) + 1;
923 	crypto_write(exact_size, CRYPTO_PKA_L0);
924 
925 	/* write size with extra word into tab[1] = tab[0] + 32 */
926 	crypto_write(exact_size + 32, CRYPTO_PKA_L0 + 4);
927 
928 	/* calculate NP by initialization PKA for modular operations */
929 	error = rk_calcNp_and_initmodop(
930 					(m_c)->d, /*in N*/
931 					exact_size, /*in N size*/
932 					op_Np, /*out NP*/
933 					RK_PKA_CREATE_NP, /*in caculate NP*/
934 					2, /*in *r_t0*/
935 					3, /*in r_t1*/
936 					4 /*in r_t2*/);
937 	if (error != CRYPT_OK) {
938 		printf("rk_calcNp_and_initmodop fail");
939 		goto exit;
940 	}
941 	rk_pka_clear_block_of_regs(2/* FirstReg*/, 3, 1/*len_id*/);
942 
943 	rk_pka_copy_data_into_reg(2/*dst_reg*/, 1/*len_id*/,
944 				  tmpa->d/*src_ptr*/,
945 				  rk_mpanum_size(tmpa));
946 	rk_pka_copy_data_into_reg(3/*dst_reg*/, 1/*len_id*/,
947 				  (m_b)->d/*src_ptr*/,
948 				  rk_mpanum_size(m_b));
949 	rk_pka_copy_data_into_reg(0/*dst_reg*/, 1/*len_id*/,
950 				  m_c->d/*src_ptr*/,
951 				  rk_mpanum_size(m_c));
952 	RK_PKA_ModExp(0, 2, 3, 4, 0);
953 	rk_pka_copy_data_from_reg(m_d->d,  max_word_size, 4/*srcReg*/);
954 
955 	m_d->size = rk_check_size(m_d->d, max_word_size);
956 
957 	rk_pka_clear_block_of_regs(0/*FirstReg*/, 5/*Count*/, 1/*len_id*/);
958 	rk_pka_clear_block_of_regs(30/*FirstReg*/, 2/*Count*/, 1/*len_id*/);
959 	rk_pka_finish();
960 
961 exit:
962 	rk_mpa_free(&tmpa);
963 	return error;
964 }
965 
966 /*d = (a ^ b) % c*/
967 int rk_exptmod_np(void *m, void *e, void *n, void *np, void *d)
968 {
969 	struct mpa_num *tmpa;
970 	u32 op_Np[5];
971 	u32 error = CRYPT_OK;
972 	int max_word_size, exact_size;
973 	struct mpa_num *m_e, *m_n, *m_np, *m_d;
974 
975 	m_e = (struct mpa_num *)e;
976 	m_n = (struct mpa_num *)n;
977 	m_np = (struct mpa_num *)np;
978 	m_d = (struct mpa_num *)d;
979 
980 	if (rk_mpa_alloc(&tmpa, NULL, RK_MAX_RSA_BWORDS) != 0)
981 		return CRYPT_ERROR;
982 
983 	error = rk_mod(m, n, tmpa);
984 	if (error) {
985 		error = CRYPT_ERROR;
986 		goto exit;
987 	}
988 
989 	if (!m || !e || !n || !d || rk_mpanum_size(m_n) == 0) {
990 		error = CRYPT_ERROR;
991 		goto exit;
992 	}
993 
994 	max_word_size = rk_mpanum_size(tmpa);
995 	if (max_word_size < rk_mpanum_size(m_e))
996 		max_word_size = rk_mpanum_size(m_e);
997 	if (max_word_size < rk_mpanum_size(m_n))
998 		max_word_size = rk_mpanum_size(m_n);
999 
1000 	error = RK_PKA_DefaultInitPKA(max_word_size * 32, max_word_size + 1);
1001 	if (error != CRYPT_OK)
1002 		goto exit;
1003 
1004 	/* write exact size into first table entry */
1005 	exact_size = mpa_highest_bit_index(m_n) + 1;
1006 	crypto_write(exact_size, CRYPTO_PKA_L0);
1007 
1008 	/* write size with extra word into tab[1] = tab[0] + 32 */
1009 	crypto_write(exact_size + 32, CRYPTO_PKA_L0 + 4);
1010 
1011 	/* calculate NP by initialization PKA for modular operations */
1012 	if (m_np && m_np->d)
1013 		error = rk_calcNp_and_initmodop((m_n)->d, /*in N*/
1014 						exact_size,	/*in N size*/
1015 						m_np->d,	/*out NP*/
1016 						RK_PKA_SET_NP, /*in set NP*/
1017 						2,	/*in *r_t0*/
1018 						3,	/*in r_t1*/
1019 						4	/*in r_t2*/);
1020 	else
1021 		error = rk_calcNp_and_initmodop((m_n)->d,/*in N*/
1022 						exact_size,	/*in N size*/
1023 						op_Np,	/*out NP*/
1024 						RK_PKA_CREATE_NP,
1025 						2,	/*in *r_t0*/
1026 						3,	/*in r_t1*/
1027 						4	/*in r_t2*/);
1028 	if (error != CRYPT_OK) {
1029 		printf("rk_calcNp_and_initmodop fail");
1030 		goto exit;
1031 	}
1032 	rk_pka_clear_block_of_regs(2/* FirstReg*/, 3, 1/*len_id*/);
1033 
1034 	rk_pka_copy_data_into_reg(2/*dst_reg*/, 1/*len_id*/,
1035 				  (tmpa)->d/*src_ptr*/,
1036 				  rk_mpanum_size(tmpa));
1037 	rk_pka_copy_data_into_reg(3/*dst_reg*/, 1/*len_id*/,
1038 				  m_e->d/*src_ptr*/,
1039 				  rk_mpanum_size(m_e));
1040 	rk_pka_copy_data_into_reg(0/*dst_reg*/, 1/*len_id*/,
1041 				  (m_n)->d/*src_ptr*/,
1042 				  rk_mpanum_size(m_n));
1043 	RK_PKA_ModExp(0, 2, 3, 4, 0);
1044 	rk_pka_copy_data_from_reg(m_d->d, max_word_size, 4/*srcReg*/);
1045 
1046 	m_d->size = rk_check_size(m_d->d, max_word_size);
1047 
1048 	rk_pka_clear_block_of_regs(0/*FirstReg*/, 5/*Count*/, 1/*len_id*/);
1049 	rk_pka_clear_block_of_regs(30/*FirstReg*/, 2/*Count*/, 1/*len_id*/);
1050 	rk_pka_finish();
1051 
1052 exit:
1053 	rk_mpa_free(&tmpa);
1054 	return error;
1055 }
1056