1
2
3
4
5#ifndef __DESC_SDAP_H__
6#define __DESC_SDAP_H__
7
8#include "rta.h"
9#include "common.h"
10#include "pdcp.h"
11
12
13
14
15
16
17#define SDAP_SUPPORT
18#ifdef SDAP_SUPPORT
19#define SDAP_BYTE_SIZE 1
20#define SDAP_BITS_SIZE (SDAP_BYTE_SIZE * 8)
21#endif
22
23static inline void key_loading_opti(struct program *p,
24 struct alginfo *cipherdata,
25 struct alginfo *authdata)
26{
27 LABEL(lbl_skip_key_loading_jump);
28 REFERENCE(ref_skip_key_loading_jump);
29
30
31
32
33
34
35
36
37
38 ref_skip_key_loading_jump =
39 JUMP(p, lbl_skip_key_loading_jump, LOCAL_JUMP, ALL_TRUE,
40 SHRD | SELF | BOTH);
41
42
43 if (cipherdata) {
44 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
45 cipherdata->keylen, INLINE_KEY(cipherdata));
46 }
47
48 if (authdata) {
49 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
50 authdata->keylen, INLINE_KEY(authdata));
51 }
52
53
54 SET_LABEL(p, lbl_skip_key_loading_jump);
55
56 PATCH_JUMP(p, ref_skip_key_loading_jump, lbl_skip_key_loading_jump);
57}
58
59static inline int pdcp_sdap_get_sn_parameters(enum pdcp_sn_size sn_size,
60 bool swap, uint32_t *offset,
61 uint32_t *length,
62 uint32_t *sn_mask)
63{
64 switch (sn_size) {
65 case PDCP_SN_SIZE_5:
66 *offset = 7;
67 *length = 1;
68 *sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
69 PDCP_C_PLANE_SN_MASK_BE;
70 break;
71 case PDCP_SN_SIZE_7:
72 *offset = 7;
73 *length = 1;
74 *sn_mask = (swap == false) ? PDCP_7BIT_SN_MASK :
75 PDCP_7BIT_SN_MASK_BE;
76 break;
77 case PDCP_SN_SIZE_12:
78 *offset = 6;
79 *length = 2;
80 *sn_mask = (swap == false) ? PDCP_12BIT_SN_MASK :
81 PDCP_12BIT_SN_MASK_BE;
82 break;
83 case PDCP_SN_SIZE_15:
84 *offset = 6;
85 *length = 2;
86 *sn_mask = (swap == false) ? PDCP_U_PLANE_15BIT_SN_MASK :
87 PDCP_U_PLANE_15BIT_SN_MASK_BE;
88 break;
89 case PDCP_SN_SIZE_18:
90 *offset = 5;
91 *length = 3;
92 *sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
93 PDCP_U_PLANE_18BIT_SN_MASK_BE;
94 break;
95 default:
96 pr_err("Invalid sn_size for %s\n", __func__);
97 return -ENOTSUP;
98 }
99
100#ifdef SDAP_SUPPORT
101 *length += SDAP_BYTE_SIZE;
102 *offset -= SDAP_BYTE_SIZE;
103#endif
104
105 return 0;
106}
107
108static inline int pdcp_sdap_insert_no_int_op(struct program *p,
109 bool swap __maybe_unused,
110 struct alginfo *cipherdata,
111 unsigned int dir,
112 enum pdcp_sn_size sn_size)
113{
114 int op;
115 uint32_t sn_mask = 0;
116 uint32_t length = 0;
117 uint32_t offset = 0;
118
119 if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
120 &sn_mask))
121 return -ENOTSUP;
122
123
124 key_loading_opti(p, cipherdata, NULL);
125
126 SEQLOAD(p, MATH0, offset, length, 0);
127 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
128#ifdef SDAP_SUPPORT
129 rta_mathi(p, MATH0,
130 ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
131 SDAP_BITS_SIZE, MATH1, 8, 0);
132 MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
133#else
134 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
135#endif
136
137 SEQSTORE(p, MATH0, offset, length, 0);
138
139 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
140 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
141 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
142
143 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
144 MATHB(p, SEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
145
146 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
147
148 op = dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC;
149 switch (cipherdata->algtype) {
150 case PDCP_CIPHER_TYPE_SNOW:
151
152 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
153 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8,
154 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op);
155 break;
156
157 case PDCP_CIPHER_TYPE_AES:
158
159 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, WAITCOMP | IMMED);
160 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CTR,
161 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op);
162 break;
163
164 case PDCP_CIPHER_TYPE_ZUC:
165 if (rta_sec_era < RTA_SEC_ERA_5) {
166 pr_err("Invalid era for selected algorithm\n");
167 return -ENOTSUP;
168 }
169
170 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
171 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
172
173 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE, OP_ALG_AAI_F8,
174 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op);
175 break;
176
177 default:
178 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
179 "pdcp_sdap_insert_15bit_op", cipherdata->algtype);
180 return -EINVAL;
181 }
182
183 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
184
185 return 0;
186}
187
188static inline int
189pdcp_sdap_insert_enc_only_op(struct program *p, bool swap __maybe_unused,
190 struct alginfo *cipherdata,
191 struct alginfo *authdata __maybe_unused,
192 unsigned int dir, enum pdcp_sn_size sn_size,
193 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
194{
195 uint32_t offset = 0, length = 0, sn_mask = 0;
196
197 if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
198 &sn_mask))
199 return -ENOTSUP;
200
201
202 key_loading_opti(p, cipherdata, NULL);
203
204
205 SEQLOAD(p, MATH0, offset, length, 0);
206 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
207
208#ifdef SDAP_SUPPORT
209 rta_mathi(p, MATH0,
210 ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
211 SDAP_BITS_SIZE, MATH1, 8, 0);
212 MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
213#else
214 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
215#endif
216
217
218 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
219
220 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
221
222 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
223
224
225 SEQSTORE(p, MATH0, offset, length, 0);
226
227 if (rta_sec_era > RTA_SEC_ERA_2) {
228 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
229 } else {
230 MATHB(p, SEQINSZ, SUB, ONE, MATH1, 4, 0);
231 MATHB(p, MATH1, ADD, ONE, VSEQINSZ, 4, 0);
232 }
233
234 if (dir == OP_TYPE_ENCAP_PROTOCOL)
235 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
236 else
237 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
238
239 switch (cipherdata->algtype) {
240 case PDCP_CIPHER_TYPE_SNOW:
241 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
242 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
243 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8,
244 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
245 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC :
246 DIR_DEC);
247 break;
248
249 case PDCP_CIPHER_TYPE_AES:
250 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, WAITCOMP | IMMED);
251
252 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
253 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CTR,
254 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
255 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC :
256 DIR_DEC);
257 break;
258
259 case PDCP_CIPHER_TYPE_ZUC:
260 if (rta_sec_era < RTA_SEC_ERA_5) {
261 pr_err("Invalid era for selected algorithm\n");
262 return -ENOTSUP;
263 }
264
265 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
266 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
267
268 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
269 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE, OP_ALG_AAI_F8,
270 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
271 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC :
272 DIR_DEC);
273 break;
274
275 default:
276 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
277 "pdcp_sdap_insert_enc_only_op", cipherdata->algtype);
278 return -EINVAL;
279 }
280
281 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
282 SEQFIFOLOAD(p, MSG1, 0, VLF);
283 FIFOLOAD(p, MSG1, PDCP_NULL_INT_MAC_I_VAL, 4,
284 LAST1 | FLUSH1 | IMMED);
285 } else {
286 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
287 MOVE(p, OFIFO, 0, MATH1, 4, PDCP_MAC_I_LEN, WAITCOMP | IMMED);
288 MATHB(p, MATH1, XOR, PDCP_NULL_INT_MAC_I_VAL, NONE, 4, IMMED2);
289 JUMP(p, PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS, HALT_STATUS,
290 ALL_FALSE, MATH_Z);
291 }
292
293 return 0;
294}
295
296
297
298
299
300
301
302
303
304
305
306
307
308static inline int
309pdcp_sdap_insert_snoop_op(struct program *p, bool swap __maybe_unused,
310 struct alginfo *cipherdata, struct alginfo *authdata,
311 unsigned int dir, enum pdcp_sn_size sn_size,
312 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
313{
314 uint32_t offset = 0, length = 0, sn_mask = 0;
315 uint32_t int_op_alg = 0;
316 uint32_t int_op_aai = 0;
317 uint32_t cipher_op_alg = 0;
318 uint32_t cipher_op_aai = 0;
319
320 if (authdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
321 if (rta_sec_era < RTA_SEC_ERA_5) {
322 pr_err("Invalid era for selected algorithm\n");
323 return -ENOTSUP;
324 }
325 }
326
327 if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
328 &sn_mask))
329 return -ENOTSUP;
330
331 if (dir == OP_TYPE_ENCAP_PROTOCOL)
332 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
333
334 key_loading_opti(p, cipherdata, authdata);
335
336
337
338
339 SEQLOAD(p, MATH0, offset, length, 0);
340
341 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
342
343
344 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
345
346#ifdef SDAP_SUPPORT
347
348
349
350 rta_mathi(p, MATH0,
351 ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
352 SDAP_BITS_SIZE, MATH1, 8, 0);
353
354 MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
355#else
356
357 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
358#endif
359
360
361 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
362
363
364
365
366
367
368 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
369
370 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
371
372
373 if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
374 MOVEB(p, MATH1, 0, CONTEXT1, 16, 8, IMMED);
375 } else {
376
377 MOVEB(p, MATH1, 0, CONTEXT1, 0, 8, IMMED);
378 }
379
380
381 if (authdata->algtype == PDCP_AUTH_TYPE_ZUC) {
382
383 MOVEB(p, MATH1, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
384 } else if (authdata->algtype == PDCP_AUTH_TYPE_SNOW) {
385 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, WAITCOMP | IMMED);
386
387
388
389
390
391
392
393
394 if (swap == false) {
395 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK),
396 MATH2, 4, IMMED2);
397 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK),
398 MATH3, 4, IMMED2);
399 } else {
400 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE),
401 MATH2, 4, IMMED2);
402 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE),
403 MATH3, 4, IMMED2);
404 }
405
406 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
407
408
409
410
411 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
412
413
414 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
415 }
416
417
418 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
419
420 MATHI(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
421 } else {
422
423 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
424
425 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQINSZ, 4, IMMED2);
426 }
427
428
429 SEQSTORE(p, MATH0, offset, length, 0);
430
431
432 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
433
434 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
435 } else {
436
437 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
438 }
439
440
441 if (authdata->algtype == PDCP_AUTH_TYPE_ZUC) {
442 int_op_alg = OP_ALG_ALGSEL_ZUCA;
443 int_op_aai = OP_ALG_AAI_F9;
444 } else if (authdata->algtype == PDCP_AUTH_TYPE_SNOW) {
445 int_op_alg = OP_ALG_ALGSEL_SNOW_F9;
446 int_op_aai = OP_ALG_AAI_F9;
447 } else {
448 pr_err("%s no support for auth alg: %d\n", __func__,
449 authdata->algtype);
450 return -1;
451 }
452
453
454 if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
455 cipher_op_alg = OP_ALG_ALGSEL_ZUCE;
456 cipher_op_aai = OP_ALG_AAI_F8;
457 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) {
458 cipher_op_alg = OP_ALG_ALGSEL_SNOW_F8;
459 cipher_op_aai = OP_ALG_AAI_F8;
460 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
461 cipher_op_alg = OP_ALG_ALGSEL_AES;
462 cipher_op_aai = OP_ALG_AAI_CTR;
463 } else {
464 pr_err("%s no support for cipher alg: %d\n", __func__,
465 authdata->algtype);
466 return -1;
467 }
468
469
470
471
472
473
474 ALG_OPERATION(p, int_op_alg, int_op_aai, OP_ALG_AS_INITFINAL,
475 dir == OP_TYPE_ENCAP_PROTOCOL ? ICV_CHECK_DISABLE :
476 ICV_CHECK_ENABLE,
477 DIR_ENC);
478
479
480 ALG_OPERATION(p, cipher_op_alg, cipher_op_aai, OP_ALG_AS_INITFINAL,
481 ICV_CHECK_DISABLE,
482 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
483
484
485 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
486
487
488
489
490
491 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
492
493
494
495
496 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
497 } else {
498
499
500
501
502
503
504
505 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
506
507
508 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
509
510
511
512
513 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
514
515 if (rta_sec_era >= RTA_SEC_ERA_6)
516 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
517
518
519
520 MOVE(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
521
522
523
524
525 NFIFOADD(p, IFIFO, ICV2, 4, LAST2);
526
527
528
529
530
531 if (rta_sec_era <= RTA_SEC_ERA_2) {
532
533 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
534 MOVE(p, MATH0, 0, IFIFOAB2, 0, 4, WAITCOMP | IMMED);
535 } else {
536 MOVE(p, MATH0, 0, IFIFO, 0, 4, WAITCOMP | IMMED);
537 }
538 }
539
540 if (authdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
541
542
543
544
545 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
546 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
547 }
548
549 return 0;
550}
551
552
553
554
555
556
557
558
559
560
561
562static inline int pdcp_sdap_insert_no_snoop_op(
563 struct program *p, bool swap __maybe_unused, struct alginfo *cipherdata,
564 struct alginfo *authdata, unsigned int dir, enum pdcp_sn_size sn_size,
565 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
566{
567 uint32_t offset = 0, length = 0, sn_mask = 0;
568 uint32_t cipher_alg_op = 0;
569 uint32_t cipher_alg_aai = 0;
570
571 if (authdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
572 if (rta_sec_era < RTA_SEC_ERA_5) {
573 pr_err("Invalid era for selected algorithm\n");
574 return -ENOTSUP;
575 }
576 }
577
578 if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
579 &sn_mask))
580 return -ENOTSUP;
581
582 SEQLOAD(p, MATH0, offset, length, 0);
583 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
584
585#ifdef SDAP_SUPPORT
586 rta_mathi(p, MATH0,
587 ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
588 SDAP_BITS_SIZE, MATH1, 8, 0);
589 MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
590#else
591 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
592#endif
593
594 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
595 MOVEB(p, DESCBUF, 8, MATH2, 0, 0x08, WAITCOMP | IMMED);
596 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
597
598 SEQSTORE(p, MATH0, offset, length, 0);
599
600 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
601
602 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
603 authdata->keylen, INLINE_KEY(authdata));
604
605
606 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 8, IMMED);
607
608
609 MOVEB(p, MATH0, offset, IFIFOAB1, 0, length, IMMED);
610
611
612 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
613 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
614
615
616 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CMAC,
617 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_DEC);
618
619
620 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
621
622
623 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
624
625
626 LOAD(p, CLRW_RESET_CLS1_CHA |
627 CLRW_CLR_C1KEY |
628 CLRW_CLR_C1CTX |
629 CLRW_CLR_C1ICV |
630 CLRW_CLR_C1DATAS |
631 CLRW_CLR_C1MODE,
632 CLRW, 0, 4, IMMED);
633
634
635 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
636 cipherdata->keylen, INLINE_KEY(cipherdata));
637
638
639 if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
640 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
641 cipher_alg_op = OP_ALG_ALGSEL_AES;
642 cipher_alg_aai = OP_ALG_AAI_CTR;
643 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
644
645 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
646 cipher_alg_op = OP_ALG_ALGSEL_ZUCE;
647 cipher_alg_aai = OP_ALG_AAI_F8;
648 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) {
649
650 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
651 cipher_alg_op = OP_ALG_ALGSEL_SNOW_F8;
652 cipher_alg_aai = OP_ALG_AAI_F8;
653 }
654
655
656 SEQINPTR(p, 0, PDCP_NULL_MAX_FRAME_LEN, RTO);
657
658
659 ALG_OPERATION(p, cipher_alg_op, cipher_alg_aai,
660 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
661
662
663 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
664
665
666 SEQFIFOLOAD(p, SKIP, length, 0);
667
668
669 SEQFIFOLOAD(p, MSG1, 0, VLF);
670
671
672 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
673 } else {
674
675 if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
676 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
677 cipher_alg_op = OP_ALG_ALGSEL_AES;
678 cipher_alg_aai = OP_ALG_AAI_CTR;
679 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
680
681 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
682 cipher_alg_op = OP_ALG_ALGSEL_ZUCE;
683 cipher_alg_aai = OP_ALG_AAI_F8;
684 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) {
685
686 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
687 cipher_alg_op = OP_ALG_ALGSEL_SNOW_F8;
688 cipher_alg_aai = OP_ALG_AAI_F8;
689 }
690 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
691
692
693 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
694
695
696 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
697
698
699 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
700 cipherdata->keylen, INLINE_KEY(cipherdata));
701
702
703 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
704
705
706 ALG_OPERATION(p, cipher_alg_op, cipher_alg_aai,
707 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_DEC);
708
709
710 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
711
712
713 MOVEB(p, OFIFO, 0, MATH3, 0, 4, IMMED);
714
715
716 LOAD(p, CLRW_RESET_CLS1_CHA |
717 CLRW_CLR_C1KEY |
718 CLRW_CLR_C1CTX |
719 CLRW_CLR_C1ICV |
720 CLRW_CLR_C1DATAS |
721 CLRW_CLR_C1MODE,
722 CLRW, 0, 4, IMMED);
723
724
725 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
726 authdata->keylen, INLINE_KEY(authdata));
727
728
729 SEQINPTR(p, 0, 0, SOP);
730
731
732 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CMAC,
733 OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
734
735
736 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
737
738 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
739
740 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
741
742
743 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
744 NFIFOENTRY_DEST_CLASS1 |
745 NFIFOENTRY_DTYPE_ICV |
746 NFIFOENTRY_LC1 |
747 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
748
749
750 MOVEB(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
751 }
752
753 return 0;
754}
755
756static int pdcp_sdap_insert_with_int_op(
757 struct program *p, bool swap __maybe_unused, struct alginfo *cipherdata,
758 struct alginfo *authdata, enum pdcp_sn_size sn_size,
759 unsigned char era_2_sw_hfn_ovrd, unsigned int dir)
760{
761 static int (
762 *pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])(
763 struct program *, bool swap, struct alginfo *, struct alginfo *,
764 unsigned int, enum pdcp_sn_size,
765 unsigned char __maybe_unused) = {
766 {
767
768 pdcp_insert_cplane_null_op,
769 pdcp_insert_cplane_int_only_op,
770 pdcp_insert_cplane_int_only_op,
771 pdcp_insert_cplane_int_only_op
772 },
773 {
774
775 pdcp_sdap_insert_enc_only_op,
776 pdcp_sdap_insert_snoop_op,
777 pdcp_sdap_insert_no_snoop_op,
778 pdcp_sdap_insert_snoop_op
779 },
780 {
781
782 pdcp_sdap_insert_enc_only_op,
783 pdcp_sdap_insert_snoop_op,
784 pdcp_sdap_insert_no_snoop_op,
785 pdcp_sdap_insert_snoop_op
786 },
787 {
788
789 pdcp_sdap_insert_enc_only_op,
790 pdcp_sdap_insert_snoop_op,
791 pdcp_sdap_insert_no_snoop_op,
792 pdcp_sdap_insert_snoop_op
793 },
794 };
795 int err;
796
797 err = pdcp_cp_fp[cipherdata->algtype]
798 [authdata->algtype](p, swap, cipherdata, authdata, dir,
799 sn_size, era_2_sw_hfn_ovrd);
800 if (err)
801 return err;
802
803 return 0;
804}
805
806static inline int
807cnstr_shdsc_pdcp_sdap_u_plane(uint32_t *descbuf,
808 bool ps,
809 bool swap,
810 enum pdcp_sn_size sn_size,
811 uint32_t hfn,
812 unsigned short bearer,
813 unsigned short direction,
814 uint32_t hfn_threshold,
815 struct alginfo *cipherdata,
816 struct alginfo *authdata,
817 unsigned char era_2_sw_hfn_ovrd,
818 uint32_t caps_mode)
819{
820 struct program prg;
821 struct program *p = &prg;
822 int err;
823 enum pdb_type_e pdb_type;
824 static enum rta_share_type
825 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
826 {
827
828 SHR_WAIT,
829 SHR_ALWAYS,
830 SHR_ALWAYS,
831 SHR_ALWAYS
832 },
833 {
834
835 SHR_ALWAYS,
836 SHR_ALWAYS,
837 SHR_WAIT,
838 SHR_WAIT
839 },
840 {
841
842 SHR_ALWAYS,
843 SHR_ALWAYS,
844 SHR_ALWAYS,
845 SHR_WAIT
846 },
847 {
848
849 SHR_ALWAYS,
850 SHR_WAIT,
851 SHR_WAIT,
852 SHR_WAIT
853 },
854 };
855
856 LABEL(pdb_end);
857
858
859 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
860 pr_err("Cannot select SW HFN ovrd for other era than 2");
861 return -EINVAL;
862 }
863
864
865 switch (cipherdata->algtype) {
866 case PDCP_CIPHER_TYPE_NULL:
867 case PDCP_CIPHER_TYPE_SNOW:
868 case PDCP_CIPHER_TYPE_AES:
869 case PDCP_CIPHER_TYPE_ZUC:
870 break;
871 default:
872 pr_err("Cipher algorithm not supported: %d\n",
873 cipherdata->algtype);
874 return -ENOTSUP;
875 }
876
877
878 if (authdata) {
879 switch (authdata->algtype) {
880 case PDCP_AUTH_TYPE_NULL:
881 case PDCP_AUTH_TYPE_SNOW:
882 case PDCP_AUTH_TYPE_AES:
883 case PDCP_AUTH_TYPE_ZUC:
884 break;
885 default:
886 pr_err("Auth algorithm not supported: %d\n",
887 authdata->algtype);
888 return -ENOTSUP;
889 }
890 }
891
892
893 switch (sn_size) {
894 case PDCP_SN_SIZE_5:
895 case PDCP_SN_SIZE_7:
896 case PDCP_SN_SIZE_12:
897 case PDCP_SN_SIZE_15:
898 case PDCP_SN_SIZE_18:
899 break;
900 default:
901 pr_err("SN size not supported: %d\n", sn_size);
902 return -ENOTSUP;
903 }
904
905
906 if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC &&
907 rta_sec_era < RTA_SEC_ERA_5) {
908 pr_err("ZUC algorithm not supported for era: %d\n",
909 rta_sec_era);
910 return -ENOTSUP;
911 }
912
913
914 PROGRAM_CNTXT_INIT(p, descbuf, 0);
915
916 if (swap)
917 PROGRAM_SET_BSWAP(p);
918
919 if (ps)
920 PROGRAM_SET_36BIT_ADDR(p);
921
922
923 if (authdata)
924 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype],
925 0, 0);
926 else
927 SHR_HDR(p, SHR_ALWAYS, 0, 0);
928
929
930 pdb_type = cnstr_pdcp_u_plane_pdb(p, sn_size, hfn, bearer, direction,
931 hfn_threshold, cipherdata, authdata);
932 if (pdb_type == PDCP_PDB_TYPE_INVALID) {
933 pr_err("Error creating PDCP UPlane PDB\n");
934 return -EINVAL;
935 }
936 SET_LABEL(p, pdb_end);
937
938
939 err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd);
940 if (err)
941 return err;
942
943
944 if (!authdata) {
945 if (cipherdata->algtype == PDCP_CIPHER_TYPE_NULL) {
946 insert_copy_frame_op(p, cipherdata,
947 OP_TYPE_ENCAP_PROTOCOL);
948 } else {
949 err = pdcp_sdap_insert_no_int_op(p, swap, cipherdata,
950 caps_mode,
951 sn_size);
952 if (err) {
953 pr_err("Fail pdcp_sdap_insert_no_int_op\n");
954 return err;
955 }
956 }
957 } else {
958 err = pdcp_sdap_insert_with_int_op(p, swap, cipherdata,
959 authdata, sn_size,
960 era_2_sw_hfn_ovrd,
961 caps_mode);
962 if (err) {
963 pr_err("Fail pdcp_sdap_insert_with_int_op\n");
964 return err;
965 }
966 }
967
968 PATCH_HDR(p, 0, pdb_end);
969
970 return PROGRAM_FINALIZE(p);
971}
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000static inline int
1001cnstr_shdsc_pdcp_sdap_u_plane_encap(uint32_t *descbuf,
1002 bool ps,
1003 bool swap,
1004 enum pdcp_sn_size sn_size,
1005 uint32_t hfn,
1006 unsigned short bearer,
1007 unsigned short direction,
1008 uint32_t hfn_threshold,
1009 struct alginfo *cipherdata,
1010 struct alginfo *authdata,
1011 unsigned char era_2_sw_hfn_ovrd)
1012{
1013 return cnstr_shdsc_pdcp_sdap_u_plane(descbuf, ps, swap, sn_size,
1014 hfn, bearer, direction, hfn_threshold, cipherdata,
1015 authdata, era_2_sw_hfn_ovrd, OP_TYPE_ENCAP_PROTOCOL);
1016}
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045static inline int
1046cnstr_shdsc_pdcp_sdap_u_plane_decap(uint32_t *descbuf,
1047 bool ps,
1048 bool swap,
1049 enum pdcp_sn_size sn_size,
1050 uint32_t hfn,
1051 unsigned short bearer,
1052 unsigned short direction,
1053 uint32_t hfn_threshold,
1054 struct alginfo *cipherdata,
1055 struct alginfo *authdata,
1056 unsigned char era_2_sw_hfn_ovrd)
1057{
1058 return cnstr_shdsc_pdcp_sdap_u_plane(descbuf, ps, swap, sn_size, hfn,
1059 bearer, direction, hfn_threshold, cipherdata, authdata,
1060 era_2_sw_hfn_ovrd, OP_TYPE_DECAP_PROTOCOL);
1061}
1062
1063#endif
1064