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
rk_pka_ram_ctrl_enable(void)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
rk_pka_ram_ctrl_disable(void)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
rk_pka_wait_on_ram_ready(void)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
rk_pka_wait_on_pipe_ready(void)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
rk_pka_wait_on_done(void)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
rk_pka_set_startmemaddr_reg(u32 start_mem_addr)53 void rk_pka_set_startmemaddr_reg(u32 start_mem_addr)
54 {
55 crypto_write(start_mem_addr, CRYPTO_PKA_MON_READ);
56 }
57
rk_pka_set_N_NP_T0_T1_reg(u32 N,u32 NP,u32 T0,u32 T1)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
rk_pka_set_default_N_NP_T0_T1_reg(void)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
rk_pka_get_status(u32 * status)74 void rk_pka_get_status(u32 *status)
75 {
76 rk_pka_wait_on_done();
77 *status = crypto_read(CRYPTO_PKA_STATUS);
78 }
79
rk_pka_get_status_alu_outzero(u32 * status)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
rk_pka_get_status_mod_overfl(u32 * status)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
rk_pka_get_status_div_byzero(u32 * status)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
rk_pka_get_status_carry(u32 * status)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
rk_pka_get_status_alu_signout(u32 * status)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
rk_pka_get_status_modinv_ofzero(u32 * status)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
rk_pka_get_status_opcode(u32 * status)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
rk_pka_get_status_tag(u32 * status)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
rk_pka_set_regsize(u32 size_bits,u32 entry_num)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
rk_pka_read_regsize(u32 * size_bits,u32 entry_num)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
rk_pka_set_regaddr(u32 vir_reg,u32 phys_addr)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
rk_pka_get_regaddr(u32 vir_reg,u32 * phys_addr)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
rk_pka_read_regaddr(u32 vir_reg,u32 * phys_addr)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
rk_pka_make_full_opcode(u32 opcode,u32 len_id,u32 is_a_immed,u32 op_a,u32 is_b_immed,u32 op_b,u32 res_discard,u32 res,u32 tag)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
rk_pka_hw_load_value2pka_mem(u32 addr,u32 val)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
rk_pka_hw_load_block2pka_mem(u32 addr,u32 * ptr,u32 size_words)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
rk_pka_hw_reverse_load_block2pka_mem(u32 addr,u32 * ptr,u32 size_words)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
rk_pka_hw_clear_pka_mem(u32 addr,u32 size_words)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
rk_pka_hw_read_value_from_pka_mem(u32 addr,u32 * val)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
rk_pka_hw_read_block_from_pka_mem(u32 addr,u32 * ptr,u32 size_words)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
rk_pka_hw_reverse_read_block_from_pka_mem(u32 addr,u32 * ptr,u32 size_words)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
rk_pka_exec_operation(u32 opcode,u8 len_id,u8 is_a_immed,s8 op_a,u8 is_b_immed,s8 op_b,u8 res_discard,s8 res,u8 tag)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
rk_pka_set_sizes_tab(u32 regs_sizes_ptr[RK_PKA_MAX_REGS_COUNT],u32 count_of_sizes,u32 max_size_bits,u32 is_default_map)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
rk_pka_set_map_tab(struct rk_pka_regs_map * regs_map_ptr,u32 * count_of_regs,u32 maxsize_words,u32 N_NP_T0_T1,u32 is_default_map)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
rk_pka_clear_block_of_regs(u8 first_reg,u8 count_of_regs,u8 len_id)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
rk_pka_init(u32 regs_sizes_ptr[RK_PKA_MAX_REGS_COUNT],u32 count_of_sizes,struct rk_pka_regs_map * regs_map_ptr,u32 count_of_regs,u32 op_size_bits,u32 regsize_words,u32 N_NP_T0_T1,u32 is_default_map)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
rk_pka_finish(void)491 void rk_pka_finish(void)
492 {
493 RK_PKA_Terminate(0);
494 rk_pka_ram_ctrl_disable();
495 PKA_CLK_DISABLE();
496 }
497
rk_pka_copy_data_into_reg(s8 dst_reg,u8 len_id,u32 * src_ptr,u32 size_words)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(®_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
rk_pka_copy_data_from_reg(u32 * dst_ptr,u32 size_words,s8 src_reg)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
rk_pka_calcNp_and_initmodop(u32 len_id,u32 mod_size_bits,s8 r_t0,s8 r_t1,s8 r_t2)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 */
rk_pka_div_long_num(u8 len_id,s8 op_a,u32 s,s8 op_b,s8 res,s8 r_t1,s8 r_t2)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 */
rk_calcNp_and_initmodop(u32 * N_ptr,u32 N_size_bits,u32 * NP_ptr,u8 np_create_flag,s8 r_t0,s8 r_t1,s8 r_t2)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 */
mpa_highest_bit_index(const struct mpa_num * src)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| */
rk_abs_add(void * a,void * b,void * c)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*/
rk_mod(void * a,void * b,void * c)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*/
rk_exptmod(void * a,void * b,void * c,void * d)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*/
rk_exptmod_np(void * m,void * e,void * n,void * np,void * d)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