1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (c) 2020 Rockchip Electronics Co., Ltd.
4 */
5
6 #include <linux/iopoll.h>
7
8 #include "rk_crypto_core.h"
9 #include "rk_crypto_v2.h"
10 #include "rk_crypto_v2_reg.h"
11 #include "rk_crypto_v2_pka.h"
12
13 #define PKA_WORDS2BITS(words) ((words) * 32)
14 #define PKA_BITS2WORDS(bits) (((bits) + 31) / 32)
15
16 #define PKA_WORDS2BYTES(words) ((words) * 4)
17 #define PKA_BYTES2BITS(bytes) ((bytes) * 8)
18
19 /* PKA length set */
20 enum {
21 PKA_EXACT_LEN_ID = 0,
22 PKA_CALC_LEN_ID,
23 PKA_USED_LEN_MAX,
24 };
25
26 /********************* Private MACRO Definition ******************************/
27 #define PKA_POLL_PERIOD_US 1000
28 #define PKA_POLL_TIMEOUT_US 50000
29
30 /* for private key EXP_MOD operation */
31 #define PKA_MAX_POLL_PERIOD_US 20000
32 #define PKA_MAX_POLL_TIMEOUT_US 2000000
33
34 #define PKA_MAX_CALC_BITS 4096
35 #define PKA_MAX_CALC_WORDS PKA_BITS2WORDS(PKA_MAX_CALC_BITS)
36
37 /* PKA N_NP_T0_T1 register default (reset) value: N=0, NP=1, T0=30, T1=31 */
38 #define PKA_N 0UL
39 #define PKA_NP 1UL
40 #define PKA_T0 30UL /*tmp reg */
41 #define PKA_T1 31UL /*tmp reg */
42 #define PKA_TMP_REG_CNT 2
43
44 #define PKA_N_NP_T0_T1_REG_DEFAULT \
45 (PKA_N << CRYPTO_N_VIRTUAL_ADDR_SHIFT | \
46 PKA_NP << CRYPTO_NP_VIRTUAL_ADDR_SHIFT | \
47 PKA_T0 << CRYPTO_T0_VIRTUAL_ADDR_SHIFT | \
48 PKA_T1 << CRYPTO_T1_VIRTUAL_ADDR_SHIFT)
49
50 #define RES_DISCARD 0x3F
51
52 /* values for defining, that PKA entry is not in use */
53 #define PKA_ADDR_NOT_USED 0xFFC
54
55 /* Machine Opcodes definitions (according to HW CRS ) */
56
57 enum pka_opcode {
58 PKA_OPCODE_ADD = 0x04,
59 PKA_OPCODE_SUB,
60 PKA_OPCODE_MOD_ADD,
61 PKA_OPCODE_MOD_SUB,
62 PKA_OPCODE_AND,
63 PKA_OPCODE_OR,
64 PKA_OPCODE_XOR,
65 PKA_OPCODE_SHR0 = 0x0C,
66 PKA_OPCODE_SHR1,
67 PKA_OPCODE_SHL0,
68 PKA_OPCODE_SHL1,
69 PKA_OPCODE_LMUL,
70 PKA_OPCODE_MOD_MUL,
71 PKA_OPCODE_MOD_MUL_NR,
72 PKA_OPCODE_MOD_EXP,
73 PKA_OPCODE_DIV,
74 PKA_OPCODE_MOD_INV,
75 PKA_OPCODE_MOD_DIV,
76 PKA_OPCODE_HMUL,
77 PKA_OPCODE_TERMINATE,
78 };
79
80 #define PKA_CLK_ENABLE()
81 #define PKA_CLK_DISABLE()
82
83 #define PKA_READ(offset) readl_relaxed((pka_base) + (offset))
84 #define PKA_WRITE(val, offset) writel_relaxed((val), (pka_base) + (offset))
85
86 #define PKA_BIGNUM_WORDS(x) (rk_bn_get_size(x) / sizeof(u32))
87
88 #define PKA_RAM_FOR_PKA() PKA_WRITE((CRYPTO_RAM_PKA_RDY << CRYPTO_WRITE_MASK_SHIFT) | \
89 CRYPTO_RAM_PKA_RDY, CRYPTO_RAM_CTL)
90
91 #define PKA_RAM_FOR_CPU() do { \
92 PKA_WRITE((CRYPTO_RAM_PKA_RDY << CRYPTO_WRITE_MASK_SHIFT), CRYPTO_RAM_CTL); \
93 while ((PKA_READ(CRYPTO_RAM_ST) & 0x01) != CRYPTO_CLK_RAM_RDY) \
94 cpu_relax(); \
95 } while (0)
96
97 #define PKA_GET_SRAM_ADDR(addr) ((void *)(pka_base + CRYPTO_SRAM_BASE + (addr)))
98
99 /*************************************************************************
100 * Macros for calling PKA operations (names according to operation issue *
101 *************************************************************************/
102
103 /*--------------------------------------*/
104 /* 1. ADD - SUBTRACT operations */
105 /*--------------------------------------*/
106 /* Add: res = op_a + op_b */
107 #define RK_PKA_ADD(op_a, op_b, res) pka_exec_op(PKA_OPCODE_ADD, PKA_CALC_LEN_ID, \
108 0, (op_a), 0, (op_b), 0, (res), 0)
109
110 /* Clr: res = op_a & 0 - clears the operand A. */
111 #define RK_PKA_CLR(op_a) pka_exec_op(PKA_OPCODE_AND, PKA_CALC_LEN_ID, \
112 0, (op_a), 1, 0x00, 0, (op_a), 0)
113
114 /* Copy: OpDest = OpSrc || 0 */
115 #define RK_PKA_COPY(op_dest, op_src) pka_exec_op(PKA_OPCODE_OR, PKA_CALC_LEN_ID, \
116 0, (op_src), 1, 0x00, 0, (op_dest), 0)
117
118 /* Set0: res = op_a || 1 : set bit0 = 1, other bits are not changed */
119 #define RK_PKA_SET_0(op_a, res) pka_exec_op(PKA_OPCODE_OR, PKA_CALC_LEN_ID, \
120 0, (op_a), 1, 0x01, 0, (res), 0)
121
122 /*----------------------------------------------*/
123 /* 3. SHIFT operations */
124 /*----------------------------------------------*/
125 /* SHL0: res = op_a << (S+1) :
126 * shifts left operand A by S+1 bits, insert 0 to right most bits
127 */
128 #define RK_PKA_SHL0(op_a, S, res) pka_exec_op(PKA_OPCODE_SHL0, PKA_CALC_LEN_ID, \
129 0, (op_a), 0, (S), 0, (res), 0)
130
131 /* SHL1: res = op_a << (S+1) :
132 * shifts left operand A by S+1 bits, insert 1 to right most bits
133 */
134 #define RK_PKA_SHL1(op_a, S, res) pka_exec_op(PKA_OPCODE_SHL1, PKA_CALC_LEN_ID, \
135 0, (op_a), 0, (S), 0, (res), 0)
136
137 /*--------------------------------------------------------------*/
138 /* 2. Multiplication and other operations */
139 /* Note: See notes to RK_PKAExecOperation */
140 /*--------------------------------------------------------------*/
141
142 /* ModExp: res = op_a ** op_b mod N - modular exponentiation */
143 #define RK_PKA_MOD_EXP(op_a, op_b, res) \
144 pka_exec_op(PKA_OPCODE_MOD_EXP, PKA_EXACT_LEN_ID, 0, (op_a), \
145 0, (op_b), 0, (res), 0)
146
147 /* Divide: res = op_a / op_b , op_a = op_a mod op_b - division, */
148 #define RK_PKA_DIV(op_a, op_b, res) pka_exec_op(PKA_OPCODE_DIV, PKA_CALC_LEN_ID, \
149 0, (op_a), 0, (op_b), 0, (res), 0)
150
151 /* Terminate - special operation, which allows HOST access */
152 /* to PKA data memory registers after end of PKA operations */
153 #define RK_PKA_TERMINATE() pka_exec_op(PKA_OPCODE_TERMINATE, 0, 0, 0, 0, 0, 0, 0, 0)
154
155 /********************* Private Variable Definition ***************************/
156 static void __iomem *pka_base;
157
pka_word_memcpy(u32 * dst,u32 * src,u32 size)158 static void pka_word_memcpy(u32 *dst, u32 *src, u32 size)
159 {
160 u32 i;
161
162 for (i = 0; i < size; i++, dst++)
163 writel_relaxed(src[i], (void *)dst);
164 }
165
pka_word_memset(u32 * buff,u32 val,u32 size)166 static void pka_word_memset(u32 *buff, u32 val, u32 size)
167 {
168 u32 i;
169
170 for (i = 0; i < size; i++, buff++)
171 writel_relaxed(val, (void *)buff);
172 }
173
pka_wait_pipe_rdy(void)174 static int pka_wait_pipe_rdy(void)
175 {
176 u32 reg_val = 0;
177
178 return readx_poll_timeout(PKA_READ, CRYPTO_PKA_PIPE_RDY, reg_val,
179 reg_val, PKA_POLL_PERIOD_US, PKA_POLL_TIMEOUT_US);
180 }
181
pka_wait_done(void)182 static int pka_wait_done(void)
183 {
184 u32 reg_val = 0;
185
186 return readx_poll_timeout(PKA_READ, CRYPTO_PKA_DONE, reg_val,
187 reg_val, PKA_POLL_PERIOD_US, PKA_POLL_TIMEOUT_US);
188 }
189
pka_max_wait_done(void)190 static int pka_max_wait_done(void)
191 {
192 u32 reg_val = 0;
193
194 return readx_poll_timeout(PKA_READ, CRYPTO_PKA_DONE, reg_val,
195 reg_val, PKA_MAX_POLL_PERIOD_US, PKA_MAX_POLL_TIMEOUT_US);
196 }
197
pka_check_status(u32 mask)198 static u32 pka_check_status(u32 mask)
199 {
200 u32 status;
201
202 pka_wait_done();
203 status = PKA_READ(CRYPTO_PKA_STATUS);
204 status = status & mask;
205
206 return !!status;
207 }
pka_set_len_words(u32 words,u32 index)208 static void pka_set_len_words(u32 words, u32 index)
209 {
210 PKA_WRITE(PKA_WORDS2BITS(words), CRYPTO_PKA_L0 + index * sizeof(u32));
211 }
212
pka_get_len_words(u32 index)213 static u32 pka_get_len_words(u32 index)
214 {
215 pka_wait_done();
216 return PKA_BITS2WORDS(PKA_READ(CRYPTO_PKA_L0 + (index) * sizeof(u32)));
217 }
218
pka_set_map_addr(u32 addr,u32 index)219 static void pka_set_map_addr(u32 addr, u32 index)
220 {
221 PKA_WRITE(addr, CRYPTO_MEMORY_MAP0 + sizeof(u32) * index);
222 }
223
pka_get_map_addr(u32 index)224 static u32 pka_get_map_addr(u32 index)
225 {
226 pka_wait_done();
227 return PKA_READ(CRYPTO_MEMORY_MAP0 + sizeof(u32) * (index));
228 }
229
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)230 static u32 pka_make_full_opcode(u32 opcode, u32 len_id,
231 u32 is_a_immed, u32 op_a,
232 u32 is_b_immed, u32 op_b,
233 u32 res_discard, u32 res,
234 u32 tag)
235 {
236 u32 full_opcode;
237
238 full_opcode = ((opcode & 31) << CRYPTO_OPCODE_CODE_SHIFT |
239 (len_id & 7) << CRYPTO_OPCODE_LEN_SHIFT |
240 (is_a_immed & 1) << CRYPTO_OPCODE_A_IMMED_SHIFT |
241 (op_a & 31) << CRYPTO_OPCODE_A_SHIFT |
242 (is_b_immed & 1) << CRYPTO_OPCODE_B_IMMED_SHIFT |
243 (op_b & 31) << CRYPTO_OPCODE_B_SHIFT |
244 (res_discard & 1) << CRYPTO_OPCODE_R_DIS_SHIFT |
245 (res & 31) << CRYPTO_OPCODE_R_SHIFT |
246 (tag & 31) << CRYPTO_OPCODE_TAG_SHIFT);
247
248 return full_opcode;
249 }
250
pka_load_data(u32 addr,u32 * data,u32 size_words)251 static void pka_load_data(u32 addr, u32 *data, u32 size_words)
252 {
253 pka_wait_done();
254
255 PKA_RAM_FOR_CPU();
256 pka_word_memcpy(PKA_GET_SRAM_ADDR(addr), data, size_words);
257 PKA_RAM_FOR_PKA();
258 }
259
pka_clr_mem(u32 addr,u32 size_words)260 static void pka_clr_mem(u32 addr, u32 size_words)
261 {
262 pka_wait_done();
263
264 PKA_RAM_FOR_CPU();
265 pka_word_memset(PKA_GET_SRAM_ADDR(addr), 0x00, size_words);
266 PKA_RAM_FOR_PKA();
267 }
268
pka_read_data(u32 addr,u32 * data,u32 size_words)269 static void pka_read_data(u32 addr, u32 *data, u32 size_words)
270 {
271 pka_wait_done();
272
273 PKA_RAM_FOR_CPU();
274 pka_word_memcpy(data, PKA_GET_SRAM_ADDR(addr), size_words);
275 PKA_RAM_FOR_PKA();
276 }
277
pka_exec_op(enum pka_opcode opcode,u8 len_id,u8 is_a_immed,u8 op_a,u8 is_b_immed,u8 op_b,u8 res_discard,u8 res,u8 tag)278 static int pka_exec_op(enum pka_opcode opcode, u8 len_id,
279 u8 is_a_immed, u8 op_a, u8 is_b_immed, u8 op_b,
280 u8 res_discard, u8 res, u8 tag)
281 {
282 int ret = 0;
283 u32 full_opcode;
284
285 if (res == RES_DISCARD) {
286 res_discard = 1;
287 res = 0;
288 }
289
290 full_opcode = pka_make_full_opcode(opcode, len_id,
291 is_a_immed, op_a,
292 is_b_immed, op_b,
293 res_discard, res, tag);
294
295 /* write full opcode into PKA CRYPTO_OPCODE register */
296 PKA_WRITE(full_opcode, CRYPTO_OPCODE);
297
298 /*************************************************/
299 /* finishing operations for different cases */
300 /*************************************************/
301 switch (opcode) {
302 case PKA_OPCODE_DIV:
303 /* for Div operation check, that op_b != 0*/
304 if (pka_check_status(CRYPTO_PKA_DIV_BY_ZERO))
305 goto end;
306 break;
307 case PKA_OPCODE_TERMINATE:
308 /* wait for PKA done bit */
309 ret = pka_wait_done();
310 break;
311 default:
312 /* wait for PKA pipe ready bit */
313 ret = pka_wait_pipe_rdy();
314 }
315 end:
316 return ret;
317 }
318
pk_int_len_tbl(u32 exact_size_words,u32 calc_size_words)319 static int pk_int_len_tbl(u32 exact_size_words, u32 calc_size_words)
320 {
321 u32 i;
322
323 /* clear all length reg */
324 for (i = 0; i < CRYPTO_LEN_REG_NUM; i++)
325 pka_set_len_words(0, i);
326
327 /* Case of default settings */
328 /* write exact size into first table entry */
329 pka_set_len_words(exact_size_words, PKA_EXACT_LEN_ID);
330
331 /* write size with extra word into tab[1] = tab[0] + 32 */
332 pka_set_len_words(calc_size_words, PKA_CALC_LEN_ID);
333
334 return 0;
335 }
336
pka_int_map_tbl(u32 * regs_cnt,u32 max_size_words)337 static int pka_int_map_tbl(u32 *regs_cnt, u32 max_size_words)
338 {
339 u32 i;
340 u32 cur_addr = 0;
341 u32 max_size_bytes, default_regs_cnt;
342
343 max_size_bytes = PKA_WORDS2BYTES(max_size_words);
344 default_regs_cnt =
345 min_t(u32, CRYPTO_MAP_REG_NUM, CRYPTO_SRAM_SIZE / max_size_bytes);
346
347 /* clear all address */
348 for (i = 0; i < CRYPTO_MAP_REG_NUM; i++)
349 pka_set_map_addr(PKA_ADDR_NOT_USED, i);
350
351 /* set addresses of N,NP and user requested registers (excluding 2 temp registers T0,T1) */
352 for (i = 0; i < default_regs_cnt - PKA_TMP_REG_CNT; i++, cur_addr += max_size_bytes)
353 pka_set_map_addr(cur_addr, i);
354
355 /* set addresses of 2 temp registers: T0=30, T1=31 */
356 pka_set_map_addr(cur_addr, PKA_T0);
357 cur_addr += max_size_bytes;
358 pka_set_map_addr(cur_addr, PKA_T1);
359
360 /* output maximal count of allowed registers */
361 *regs_cnt = default_regs_cnt;
362
363 /* set default virtual addresses of N,NP,T0,T1 registers into N_NP_T0_T1_Reg */
364 PKA_WRITE((u32)PKA_N_NP_T0_T1_REG_DEFAULT, CRYPTO_N_NP_T0_T1_ADDR);
365
366 return 0;
367 }
368
pka_clear_regs_block(u8 first_reg,u8 regs_cnt)369 static int pka_clear_regs_block(u8 first_reg, u8 regs_cnt)
370 {
371 u32 i;
372 u32 size_words;
373 int cnt_tmps = 0;
374 u32 user_reg_num = CRYPTO_MAP_REG_NUM - PKA_TMP_REG_CNT;
375
376 /* calculate size_words of register in words */
377 size_words = pka_get_len_words(PKA_CALC_LEN_ID);
378
379 if (first_reg + regs_cnt > user_reg_num) {
380 cnt_tmps = min_t(u8, (regs_cnt + first_reg - user_reg_num), PKA_TMP_REG_CNT);
381 regs_cnt = user_reg_num;
382 } else {
383 cnt_tmps = PKA_TMP_REG_CNT;
384 }
385
386 /* clear ordinary registers */
387 for (i = first_reg; i < regs_cnt; i++)
388 RK_PKA_CLR(i);
389
390 pka_wait_done();
391
392 /* clear PKA temp registers (without PKA operations) */
393 if (cnt_tmps > 0) {
394 pka_clr_mem(pka_get_map_addr(PKA_T0), size_words);
395 if (cnt_tmps > 1)
396 pka_clr_mem(pka_get_map_addr(PKA_T1), size_words);
397
398 }
399
400 return 0;
401 }
402
pka_init(u32 exact_size_words)403 static int pka_init(u32 exact_size_words)
404 {
405 int ret;
406 u32 regs_cnt = 0;
407 u32 calc_size_words = exact_size_words + 1;
408
409 PKA_CLK_ENABLE();
410 PKA_RAM_FOR_PKA();
411
412 if (exact_size_words > PKA_MAX_CALC_WORDS)
413 return -1;
414
415 ret = pk_int_len_tbl(exact_size_words, calc_size_words);
416 if (ret)
417 goto exit;
418
419 ret = pka_int_map_tbl(®s_cnt, calc_size_words);
420 if (ret)
421 goto exit;
422
423 /* clean PKA data memory */
424 pka_clear_regs_block(0, regs_cnt - PKA_TMP_REG_CNT);
425
426 /* clean temp PKA registers 30,31 */
427 pka_clr_mem(pka_get_map_addr(PKA_T0), calc_size_words);
428 pka_clr_mem(pka_get_map_addr(PKA_T1), calc_size_words);
429
430 exit:
431 return ret;
432 }
433
pka_finish(void)434 static void pka_finish(void)
435 {
436 RK_PKA_TERMINATE();
437 PKA_CLK_DISABLE();
438 }
439
pka_copy_bn_into_reg(u8 dst_reg,struct rk_bignum * bn)440 static void pka_copy_bn_into_reg(u8 dst_reg, struct rk_bignum *bn)
441 {
442 u32 cur_addr;
443 u32 size_words, bn_words;
444
445 RK_PKA_TERMINATE();
446
447 bn_words = PKA_BIGNUM_WORDS(bn);
448 size_words = pka_get_len_words(PKA_CALC_LEN_ID);
449 cur_addr = pka_get_map_addr(dst_reg);
450
451 pka_load_data(cur_addr, bn->data, bn_words);
452 cur_addr += PKA_WORDS2BYTES(bn_words);
453
454 pka_clr_mem(cur_addr, size_words - bn_words);
455 }
456
pka_copy_bn_from_reg(struct rk_bignum * bn,u32 size_words,u8 src_reg,bool is_max_poll)457 static int pka_copy_bn_from_reg(struct rk_bignum *bn, u32 size_words, u8 src_reg, bool is_max_poll)
458 {
459 int ret;
460
461 PKA_WRITE(0, CRYPTO_OPCODE);
462
463 ret = is_max_poll ? pka_max_wait_done() : pka_wait_done();
464 if (ret)
465 return ret;
466
467 pka_read_data(pka_get_map_addr(src_reg), bn->data, size_words);
468
469 return 0;
470 }
471
472 /*********** pka_div_bignum function **********************/
473 /**
474 * @brief The function divides long number A*(2^S) by B:
475 * res = A*(2^S) / B, remainder A = A*(2^S) % B.
476 * where: A,B - are numbers of size, which is not grate than,
477 * maximal operands size,
478 * and B > 2^S;
479 * S - exponent of binary factor of A.
480 * ^ - exponentiation operator.
481 *
482 * The function algorithm:
483 *
484 * 1. Let nWords = S/32; nBits = S % 32;
485 * 2. Set res = 0, r_t1 = op_a;
486 * 3. for(i=0; i<=nWords; i++) do:
487 * 3.1. if(i < nWords )
488 * s1 = 32;
489 * else
490 * s1 = nBits;
491 * 3.2. r_t1 = r_t1 << s1;
492 * 3.3. call PKA_div for calculating the quotient and remainder:
493 * r_t2 = floor(r_t1/op_b) //quotient;
494 * r_t1 = r_t1 % op_b //remainder (is in r_t1 register);
495 * 3.4. res = (res << s1) + r_t2;
496 * end do;
497 * 4. Exit.
498 *
499 * Assuming:
500 * - 5 PKA registers are used: op_a, op_b, res, r_t1, r_t2.
501 * - The registers sizes and mapping tables are set on
502 * default mode according to operands size.
503 * - The PKA clocks are initialized.
504 * NOTE ! Operand op_a shall be overwritten by remainder.
505 *
506 * @param[in] len_id - ID of operation size (modSize+32).
507 * @param[in] op_a - Operand A: virtual register pointer of A.
508 * @param[in] S - exponent of binary factor of A.
509 * @param[in] op_b - Operand B: virtual register pointer of B.
510 * @param[in] res - Virtual register pointer for result quotient.
511 * @param[in] r_t1 - Virtual pointer to remainder.
512 * @param[in] r_t2 - Virtual pointer of temp register.
513 *
514 * @return int - On success 0 is returned:
515 *
516 */
pka_div_bignum(u8 op_a,u32 s,u8 op_b,u8 res,u8 r_t1,u8 r_t2)517 static int pka_div_bignum(u8 op_a, u32 s, u8 op_b, u8 res, u8 r_t1, u8 r_t2)
518 {
519 u8 s1;
520 u32 i;
521 u32 n_bits, n_words;
522
523 /* calculate shifting parameters (words and bits ) */
524 n_words = ((u32)s + 31) / 32;
525 n_bits = (u32)s % 32;
526
527 /* copy operand op_a (including extra word) into temp reg r_t1 */
528 RK_PKA_COPY(r_t1, op_a);
529
530 /* set res = 0 (including extra word) */
531 RK_PKA_CLR(res);
532
533 /*----------------------------------------------------*/
534 /* Step 1. Shifting and dividing loop */
535 /*----------------------------------------------------*/
536 for (i = 0; i < n_words; i++) {
537 /* 3.1 set shift value s1 */
538 s1 = i > 0 ? 32 : n_bits;
539
540 /* 3.2. shift: r_t1 = r_t1 * 2**s1 (in code (s1-1),
541 * because PKA performs s+1 shifts)
542 */
543 if (s1 > 0)
544 RK_PKA_SHL0(r_t1 /*op_a*/, (s1 - 1) /*s*/, r_t1 /*res*/);
545
546 /* 3.3. perform PKA_OPCODE_MOD_DIV for calculating a quotient
547 * r_t2 = floor(r_t1 / N)
548 * and remainder r_t1 = r_t1 % op_b
549 */
550 RK_PKA_DIV(r_t1 /*op_a*/, op_b /*B*/, r_t2 /*res*/);
551
552 /* 3.4. res = res * 2**s1 + res; */
553 if (s1 > 0)
554 RK_PKA_SHL0(res /*op_a*/, (s1 - 1) /*s*/, res /*res*/);
555
556 RK_PKA_ADD(res /*op_a*/, r_t2 /*op_b*/, res /*res*/);
557 }
558
559 pka_wait_done();
560
561 return 0;
562 } /* END OF pka_div_bignum */
563
pka_calc_and_init_np(struct rk_bignum * bn,u8 r_t0,u8 r_t1,u8 r_t2)564 static u32 pka_calc_and_init_np(struct rk_bignum *bn, u8 r_t0, u8 r_t1, u8 r_t2)
565 {
566 int ret;
567 u32 i;
568 u32 s;
569 u32 mod_size_bits;
570 u32 num_bits, num_words;
571
572 /* Set s = 132 */
573 s = 132;
574
575 mod_size_bits = PKA_BYTES2BITS(rk_bn_get_size(bn));
576
577 CRYPTO_TRACE("size_bits = %u", mod_size_bits);
578
579 /* copy modulus N into r0 register */
580 pka_copy_bn_into_reg(PKA_N, bn);
581
582 /*--------------------------------------------------------------*/
583 /* Step 1,2. Set registers: Set op_a = 2^(sizeN+32) */
584 /* Registers using: 0 - N (is set in register 0, */
585 /* 1 - NP, temp regs: r_t0 (A), r_t1, r_t2. */
586 /* len_id: 0 - exact size, 1 - exact+32 bit */
587 /*--------------------------------------------------------------*/
588
589 /* set register r_t0 = 0 */
590 RK_PKA_CLR(r_t0);
591
592 /* calculate bit position of said bit in the word */
593 num_bits = mod_size_bits % 32;
594 num_words = mod_size_bits / 32;
595
596 CRYPTO_TRACE("num_bits = %u, num_words = %u, size_bits = %u",
597 num_bits, num_words, mod_size_bits);
598
599 /* set 1 into register r_t0 */
600 RK_PKA_SET_0(r_t0 /*op_a*/, r_t0 /*res*/);
601
602 /* shift 1 to num_bits+31 position */
603 if (num_bits > 0)
604 RK_PKA_SHL0(r_t0 /*op_a*/, num_bits - 1 /*s*/, r_t0 /*res*/);
605
606 /* shift to word position */
607 for (i = 0; i < num_words; i++)
608 RK_PKA_SHL0(r_t0 /*op_a*/, 31 /*s*/, r_t0 /*res*/);
609
610 /*--------------------------------------------------------------*/
611 /* Step 3. Dividing: PKA_NP = (r_t0 * 2**s) / N */
612 /*--------------------------------------------------------------*/
613 ret = pka_div_bignum(r_t0, s, PKA_N, PKA_NP, r_t1, r_t2);
614
615 return ret;
616 } /* END OF pka_calc_and_init_np */
617
618 /********************* Public Function Definition ****************************/
619
rk_pka_set_crypto_base(void __iomem * base)620 void rk_pka_set_crypto_base(void __iomem *base)
621 {
622 pka_base = base;
623 }
624
625 /**
626 * @brief calculate exp mod. out = in ^ e mod n
627 * @param in: the point of input data bignum.
628 * @param e: the point of exponent bignum.
629 * @param n: the point of modulus bignum.
630 * @param out: the point of outputs bignum.
631 * @param pTmp: the point of tmpdata bignum.
632 * @return 0 for success
633 */
rk_pka_expt_mod(struct rk_bignum * in,struct rk_bignum * e,struct rk_bignum * n,struct rk_bignum * out)634 int rk_pka_expt_mod(struct rk_bignum *in,
635 struct rk_bignum *e,
636 struct rk_bignum *n,
637 struct rk_bignum *out)
638 {
639 int ret = -1;
640 u32 max_word_size;
641 bool is_max_poll;
642 u8 r_in = 2, r_e = 3, r_out = 4;
643 u8 r_t0 = 2, r_t1 = 3, r_t2 = 4;
644
645 if (!in || !e || !n || !out || PKA_BIGNUM_WORDS(n) == 0)
646 return -1;
647
648 max_word_size = PKA_BIGNUM_WORDS(n);
649
650 ret = pka_init(max_word_size);
651 if (ret) {
652 CRYPTO_TRACE("pka_init error\n");
653 goto exit;
654 }
655
656 /* calculate NP by initialization PKA for modular operations */
657 ret = pka_calc_and_init_np(n, r_t0, r_t1, r_t2);
658 if (ret) {
659 CRYPTO_TRACE("pka_calc_and_init_np error\n");
660 goto exit;
661 }
662
663 pka_clear_regs_block(r_in, 3);
664
665 pka_copy_bn_into_reg(r_in, in);
666 pka_copy_bn_into_reg(r_e, e);
667 pka_copy_bn_into_reg(PKA_N, n);
668
669 ret = RK_PKA_MOD_EXP(r_in, r_e, r_out);
670 if (ret) {
671 CRYPTO_TRACE("RK_PKA_MOD_EXP error\n");
672 goto exit;
673 }
674
675 /* e is usually 0x10001 in public key EXP_MOD operation */
676 is_max_poll = rk_bn_highest_bit(e) * 2 > rk_bn_highest_bit(n) ? true : false;
677
678 ret = pka_copy_bn_from_reg(out, max_word_size, r_out, is_max_poll);
679
680 exit:
681 pka_clear_regs_block(0, 5);
682 pka_clear_regs_block(30, 2);
683 pka_finish();
684
685 return ret;
686 }
687