1
2
3
4
5
6#ifndef __DESC_PDCP_H__
7#define __DESC_PDCP_H__
8
9#include "rta.h"
10#include "common.h"
11
12
13
14
15
16
17
18
19
20
21
22#define PDCP_NULL_MAX_FRAME_LEN 0x00002FFF
23
24
25
26
27#define PDCP_MAC_I_LEN 0x00000004
28
29
30
31
32
33
34#define PDCP_MAX_FRAME_LEN_STATUS 0xF1
35
36
37
38
39
40
41
42
43#define PDCP_C_PLANE_SN_MASK 0x1F000000
44#define PDCP_C_PLANE_SN_MASK_BE 0x0000001F
45
46
47
48
49
50
51#define PDCP_7BIT_SN_MASK 0x7F000000
52#define PDCP_7BIT_SN_MASK_BE 0x0000007F
53
54
55
56
57
58
59#define PDCP_12BIT_SN_MASK 0xFF0F0000
60#define PDCP_12BIT_SN_MASK_BE 0x00000FFF
61
62
63
64
65
66
67
68
69#define PDCP_U_PLANE_15BIT_SN_MASK 0xFF7F0000
70#define PDCP_U_PLANE_15BIT_SN_MASK_BE 0x00007FFF
71
72
73
74
75
76
77#define PDCP_U_PLANE_18BIT_SN_MASK 0xFFFF0300
78#define PDCP_U_PLANE_18BIT_SN_MASK_BE 0x0003FFFF
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93#define PDCP_BEARER_MASK 0x00000004FFFFFFFFull
94#define PDCP_BEARER_MASK_BE 0xFFFFFFFF04000000ull
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109#define PDCP_DIR_MASK 0x00000000000000F8ull
110#define PDCP_DIR_MASK_BE 0xF800000000000000ull
111
112
113
114
115
116
117#define PDCP_NULL_INT_MAC_I_VAL 0x00000000
118
119
120
121
122
123
124#define PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS 0x0A
125
126
127
128
129
130#define PDCP_DPOVRD_HFN_OV_EN 0x80000000
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148#define PDCP_P4080REV2_HFN_OV_BUFLEN 4
149
150
151
152
153
154
155
156
157
158
159enum cipher_type_pdcp {
160 PDCP_CIPHER_TYPE_NULL,
161 PDCP_CIPHER_TYPE_SNOW,
162 PDCP_CIPHER_TYPE_AES,
163 PDCP_CIPHER_TYPE_ZUC,
164 PDCP_CIPHER_TYPE_INVALID
165};
166
167
168
169
170
171
172
173
174
175
176enum auth_type_pdcp {
177 PDCP_AUTH_TYPE_NULL,
178 PDCP_AUTH_TYPE_SNOW,
179 PDCP_AUTH_TYPE_AES,
180 PDCP_AUTH_TYPE_ZUC,
181 PDCP_AUTH_TYPE_INVALID
182};
183
184
185
186
187
188
189
190enum pdcp_dir {
191 PDCP_DIR_UPLINK = 0,
192 PDCP_DIR_DOWNLINK = 1,
193 PDCP_DIR_INVALID
194};
195
196
197
198
199
200
201
202enum pdcp_plane {
203 PDCP_CONTROL_PLANE,
204 PDCP_DATA_PLANE,
205 PDCP_SHORT_MAC
206};
207
208
209
210
211
212
213
214
215
216enum pdcp_sn_size {
217 PDCP_SN_SIZE_5 = 5,
218 PDCP_SN_SIZE_7 = 7,
219 PDCP_SN_SIZE_12 = 12,
220 PDCP_SN_SIZE_15 = 15,
221 PDCP_SN_SIZE_18 = 18
222};
223
224
225
226
227#define PDCP_C_PLANE_PDB_HFN_SHIFT 5
228#define PDCP_C_PLANE_PDB_BEARER_SHIFT 27
229#define PDCP_C_PLANE_PDB_DIR_SHIFT 26
230#define PDCP_C_PLANE_PDB_HFN_THR_SHIFT 5
231
232#define PDCP_U_PLANE_PDB_OPT_SHORT_SN 0x2
233#define PDCP_U_PLANE_PDB_OPT_15B_SN 0x4
234#define PDCP_U_PLANE_PDB_OPT_18B_SN 0x6
235#define PDCP_U_PLANE_PDB_SHORT_SN_HFN_SHIFT 7
236#define PDCP_U_PLANE_PDB_LONG_SN_HFN_SHIFT 12
237#define PDCP_U_PLANE_PDB_15BIT_SN_HFN_SHIFT 15
238#define PDCP_U_PLANE_PDB_18BIT_SN_HFN_SHIFT 18
239#define PDCP_U_PLANE_PDB_BEARER_SHIFT 27
240#define PDCP_U_PLANE_PDB_DIR_SHIFT 26
241#define PDCP_U_PLANE_PDB_SHORT_SN_HFN_THR_SHIFT 7
242#define PDCP_U_PLANE_PDB_LONG_SN_HFN_THR_SHIFT 12
243#define PDCP_U_PLANE_PDB_15BIT_SN_HFN_THR_SHIFT 15
244#define PDCP_U_PLANE_PDB_18BIT_SN_HFN_THR_SHIFT 18
245
246struct pdcp_pdb {
247 union {
248 uint32_t opt;
249 uint32_t rsvd;
250 } opt_res;
251 uint32_t hfn_res;
252
253
254 uint32_t bearer_dir_res;
255
256
257 uint32_t hfn_thr_res;
258
259
260
261};
262
263
264
265
266enum pdb_type_e {
267 PDCP_PDB_TYPE_NO_PDB,
268 PDCP_PDB_TYPE_FULL_PDB,
269 PDCP_PDB_TYPE_REDUCED_PDB,
270 PDCP_PDB_TYPE_INVALID
271};
272
273
274
275
276
277
278
279static inline int
280rta_inline_pdcp_query(enum auth_type_pdcp auth_alg,
281 enum cipher_type_pdcp cipher_alg,
282 enum pdcp_sn_size sn_size,
283 int8_t hfn_ovd)
284{
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300 if ((rta_sec_era == RTA_SEC_ERA_8) && hfn_ovd &&
301 (sn_size == PDCP_SN_SIZE_18) &&
302 ((cipher_alg == PDCP_CIPHER_TYPE_SNOW &&
303 auth_alg == PDCP_AUTH_TYPE_AES) ||
304 (cipher_alg == PDCP_CIPHER_TYPE_AES &&
305 auth_alg == PDCP_AUTH_TYPE_SNOW) ||
306 (cipher_alg == PDCP_CIPHER_TYPE_SNOW &&
307 auth_alg == PDCP_AUTH_TYPE_SNOW) ||
308 (cipher_alg == PDCP_CIPHER_TYPE_ZUC &&
309 auth_alg == PDCP_AUTH_TYPE_SNOW))) {
310
311 return 1;
312 }
313
314 return 0;
315}
316
317
318
319
320
321
322
323static inline int
324pdcp_insert_cplane_null_op(struct program *p,
325 bool swap __maybe_unused,
326 struct alginfo *cipherdata __maybe_unused,
327 struct alginfo *authdata __maybe_unused,
328 unsigned int dir,
329 enum pdcp_sn_size sn_size __maybe_unused,
330 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
331{
332 LABEL(local_offset);
333 REFERENCE(move_cmd_read_descbuf);
334 REFERENCE(move_cmd_write_descbuf);
335
336 if (rta_sec_era > RTA_SEC_ERA_2) {
337 MATHB(p, SEQINSZ, ADD, ZERO, VSEQINSZ, 4, 0);
338 if (dir == OP_TYPE_ENCAP_PROTOCOL)
339 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
340 IMMED2);
341 else
342 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
343 IMMED2);
344 } else {
345 MATHB(p, SEQINSZ, ADD, ONE, VSEQINSZ, 4, 0);
346 MATHB(p, VSEQINSZ, SUB, ONE, VSEQINSZ, 4, 0);
347
348 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
349 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
350 IMMED2);
351 MATHB(p, VSEQINSZ, SUB, ONE, MATH0, 4, 0);
352 } else {
353 MATHB(p, VSEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQINSZ, 4,
354 IMMED2);
355 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
356 IMMED2);
357 MATHB(p, VSEQOUTSZ, SUB, ONE, MATH0, 4, 0);
358 }
359
360 MATHB(p, MATH0, ADD, ONE, MATH0, 4, 0);
361
362
363
364
365
366
367
368
369
370
371
372
373 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH0, 0, 6,
374 IMMED);
375 move_cmd_write_descbuf = MOVE(p, MATH0, 0, DESCBUF, 0, 8,
376 WAITCOMP | IMMED);
377 }
378 MATHB(p, VSEQINSZ, SUB, PDCP_NULL_MAX_FRAME_LEN, NONE, 4,
379 IMMED2);
380 JUMP(p, PDCP_MAX_FRAME_LEN_STATUS, HALT_STATUS, ALL_FALSE, MATH_N);
381
382 if (rta_sec_era > RTA_SEC_ERA_2) {
383 if (dir == OP_TYPE_ENCAP_PROTOCOL)
384 MATHB(p, VSEQINSZ, ADD, ZERO, MATH0, 4, 0);
385 else
386 MATHB(p, VSEQOUTSZ, ADD, ZERO, MATH0, 4, 0);
387 }
388 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
389 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
390
391 if (rta_sec_era > RTA_SEC_ERA_2) {
392 MOVE(p, AB1, 0, OFIFO, 0, MATH0, 0);
393 } else {
394 SET_LABEL(p, local_offset);
395
396
397 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
398
399 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
400
401 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
402 }
403
404 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
405 MATHB(p, MATH1, XOR, MATH1, MATH0, 8, 0);
406 MOVE(p, MATH0, 0, OFIFO, 0, 4, IMMED);
407 }
408
409 if (rta_sec_era < RTA_SEC_ERA_3) {
410 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
411 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
412 }
413
414 return 0;
415}
416
417static inline int
418insert_copy_frame_op(struct program *p,
419 struct alginfo *cipherdata __maybe_unused,
420 unsigned int dir __maybe_unused)
421{
422 LABEL(local_offset);
423 REFERENCE(move_cmd_read_descbuf);
424 REFERENCE(move_cmd_write_descbuf);
425
426 if (rta_sec_era > RTA_SEC_ERA_2) {
427 MATHB(p, SEQINSZ, ADD, ZERO, VSEQINSZ, 4, 0);
428 MATHB(p, SEQINSZ, ADD, ZERO, VSEQOUTSZ, 4, 0);
429 } else {
430 MATHB(p, SEQINSZ, ADD, ONE, VSEQINSZ, 4, 0);
431 MATHB(p, VSEQINSZ, SUB, ONE, VSEQINSZ, 4, 0);
432 MATHB(p, SEQINSZ, ADD, ONE, VSEQOUTSZ, 4, 0);
433 MATHB(p, VSEQOUTSZ, SUB, ONE, VSEQOUTSZ, 4, 0);
434 MATHB(p, VSEQINSZ, SUB, ONE, MATH0, 4, 0);
435 MATHB(p, MATH0, ADD, ONE, MATH0, 4, 0);
436
437
438
439
440
441
442
443
444
445
446
447
448 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH0, 0, 6,
449 IMMED);
450 move_cmd_write_descbuf = MOVE(p, MATH0, 0, DESCBUF, 0, 8,
451 WAITCOMP | IMMED);
452 }
453 MATHB(p, SEQINSZ, SUB, PDCP_NULL_MAX_FRAME_LEN, NONE, 4,
454 IFB | IMMED2);
455 JUMP(p, PDCP_MAX_FRAME_LEN_STATUS, HALT_STATUS, ALL_FALSE, MATH_N);
456
457 if (rta_sec_era > RTA_SEC_ERA_2)
458 MATHB(p, VSEQINSZ, ADD, ZERO, MATH0, 4, 0);
459
460 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
461 if (rta_sec_era > RTA_SEC_ERA_2) {
462 MOVE(p, AB1, 0, OFIFO, 0, MATH0, 0);
463 } else {
464 SET_LABEL(p, local_offset);
465
466
467 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
468
469
470 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
471
472
473 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
474 }
475
476 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
477
478 if (rta_sec_era < RTA_SEC_ERA_3) {
479 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
480 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
481 }
482 return 0;
483}
484
485static inline int
486pdcp_insert_cplane_int_only_op(struct program *p,
487 bool swap __maybe_unused,
488 struct alginfo *cipherdata __maybe_unused,
489 struct alginfo *authdata, unsigned int dir,
490 enum pdcp_sn_size sn_size,
491 unsigned char era_2_sw_hfn_ovrd)
492{
493 uint32_t offset = 0, length = 0, sn_mask = 0;
494
495
496 if (rta_sec_era >= RTA_SEC_ERA_8 && sn_size == PDCP_SN_SIZE_12) {
497 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
498 authdata->keylen, INLINE_KEY(authdata));
499
500 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
501 (uint16_t)authdata->algtype);
502 return 0;
503 }
504
505
506 switch (sn_size) {
507 case PDCP_SN_SIZE_5:
508 offset = 7;
509 length = 1;
510 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
511 PDCP_C_PLANE_SN_MASK_BE;
512 break;
513 case PDCP_SN_SIZE_18:
514 offset = 5;
515 length = 3;
516 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
517 PDCP_U_PLANE_18BIT_SN_MASK_BE;
518 break;
519 case PDCP_SN_SIZE_7:
520 case PDCP_SN_SIZE_12:
521 case PDCP_SN_SIZE_15:
522 pr_err("Invalid sn_size for %s\n", __func__);
523 return -ENOTSUP;
524
525 }
526 LABEL(local_offset);
527 REFERENCE(move_cmd_read_descbuf);
528 REFERENCE(move_cmd_write_descbuf);
529
530 switch (authdata->algtype) {
531 case PDCP_AUTH_TYPE_SNOW:
532
533 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
534 authdata->keylen, INLINE_KEY(authdata));
535 SEQLOAD(p, MATH0, offset, length, 0);
536 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
537
538 if (rta_sec_era > RTA_SEC_ERA_2 ||
539 (rta_sec_era == RTA_SEC_ERA_2 &&
540 era_2_sw_hfn_ovrd == 0)) {
541 SEQINPTR(p, 0, length, RTO);
542 } else {
543 SEQINPTR(p, 0, 5, RTO);
544 SEQFIFOLOAD(p, SKIP, 4, 0);
545 }
546
547 if (swap == false) {
548 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
549 IFB | IMMED2);
550 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
551
552 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
553
554 MATHB(p, MATH2, AND, PDCP_BEARER_MASK, MATH2, 8,
555 IMMED2);
556 MOVEB(p, DESCBUF, 0x0C, MATH3, 0, 4, WAITCOMP | IMMED);
557 MATHB(p, MATH3, AND, PDCP_DIR_MASK, MATH3, 8, IMMED2);
558 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
559 MOVEB(p, MATH2, 0, CONTEXT2, 0, 0x0C, WAITCOMP | IMMED);
560 } else {
561 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
562 IFB | IMMED2);
563 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
564
565 MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
566 MATHB(p, MATH2, AND, PDCP_BEARER_MASK_BE, MATH2, 8,
567 IMMED2);
568
569 MOVE(p, DESCBUF, 0x0C, MATH3, 0, 4, WAITCOMP | IMMED);
570 MATHB(p, MATH3, AND, PDCP_DIR_MASK_BE, MATH3, 8,
571 IMMED2);
572 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
573 MOVE(p, MATH2, 0, CONTEXT2, 0, 0x0C, WAITCOMP | IMMED);
574 }
575
576 if (dir == OP_TYPE_DECAP_PROTOCOL) {
577 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4,
578 IMMED2);
579 } else {
580 if (rta_sec_era > RTA_SEC_ERA_2) {
581 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4,
582 0);
583 } else {
584 MATHB(p, SEQINSZ, ADD, ONE, MATH1, 4,
585 0);
586 MATHB(p, MATH1, SUB, ONE, MATH1, 4,
587 0);
588 }
589 }
590
591 if (rta_sec_era > RTA_SEC_ERA_2) {
592 MATHB(p, MATH1, SUB, ZERO, VSEQINSZ, 4, 0);
593 MATHB(p, MATH1, SUB, ZERO, VSEQOUTSZ, 4, 0);
594 } else {
595 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
596 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
597
598
599
600
601
602
603
604
605
606
607
608
609 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH1, 0, 6,
610 IMMED);
611 move_cmd_write_descbuf = MOVE(p, MATH1, 0, DESCBUF, 0,
612 8, WAITCOMP | IMMED);
613 }
614
615 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
616 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9, OP_ALG_AAI_F9,
617 OP_ALG_AS_INITFINAL,
618 dir == OP_TYPE_ENCAP_PROTOCOL ?
619 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
620 DIR_ENC);
621
622 if (rta_sec_era > RTA_SEC_ERA_2) {
623 SEQFIFOLOAD(p, MSGINSNOOP, 0,
624 VLF | LAST1 | LAST2 | FLUSH1);
625 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
626 } else {
627 SEQFIFOLOAD(p, MSGINSNOOP, 0,
628 VLF | LAST1 | LAST2 | FLUSH1);
629 SET_LABEL(p, local_offset);
630
631
632 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
633
634
635
636
637 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
638
639 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
640 }
641
642 if (dir == OP_TYPE_DECAP_PROTOCOL)
643 SEQFIFOLOAD(p, ICV2, 4, LAST2);
644 else
645 SEQSTORE(p, CONTEXT2, 0, 4, 0);
646
647 break;
648
649 case PDCP_AUTH_TYPE_AES:
650
651 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
652 authdata->keylen, INLINE_KEY(authdata));
653 SEQLOAD(p, MATH0, offset, length, 0);
654 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
655 if (rta_sec_era > RTA_SEC_ERA_2 ||
656 (rta_sec_era == RTA_SEC_ERA_2 &&
657 era_2_sw_hfn_ovrd == 0)) {
658 SEQINPTR(p, 0, length, RTO);
659 } else {
660 SEQINPTR(p, 0, 5, RTO);
661 SEQFIFOLOAD(p, SKIP, 4, 0);
662 }
663
664 if (swap == false) {
665 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
666 IFB | IMMED2);
667 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
668
669 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
670 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
671 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 8, IMMED);
672 } else {
673 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
674 IFB | IMMED2);
675 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
676
677 MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
678 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
679 MOVE(p, MATH2, 0, IFIFOAB1, 0, 8, IMMED);
680 }
681
682 if (dir == OP_TYPE_DECAP_PROTOCOL) {
683 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4,
684 IMMED2);
685 } else {
686 if (rta_sec_era > RTA_SEC_ERA_2) {
687 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4,
688 0);
689 } else {
690 MATHB(p, SEQINSZ, ADD, ONE, MATH1, 4,
691 0);
692 MATHB(p, MATH1, SUB, ONE, MATH1, 4,
693 0);
694 }
695 }
696
697 if (rta_sec_era > RTA_SEC_ERA_2) {
698 MATHB(p, MATH1, SUB, ZERO, VSEQINSZ, 4, 0);
699 MATHB(p, MATH1, SUB, ZERO, VSEQOUTSZ, 4, 0);
700 } else {
701 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
702 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
703
704
705
706
707
708
709
710
711
712
713
714
715 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH1, 0, 6,
716 IMMED);
717 move_cmd_write_descbuf = MOVE(p, MATH1, 0, DESCBUF, 0,
718 8, WAITCOMP | IMMED);
719 }
720 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
721 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
722 OP_ALG_AAI_CMAC,
723 OP_ALG_AS_INITFINAL,
724 dir == OP_TYPE_ENCAP_PROTOCOL ?
725 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
726 DIR_ENC);
727
728 if (rta_sec_era > RTA_SEC_ERA_2) {
729 MOVE(p, AB2, 0, OFIFO, 0, MATH1, 0);
730 SEQFIFOLOAD(p, MSGINSNOOP, 0,
731 VLF | LAST1 | LAST2 | FLUSH1);
732 } else {
733 SEQFIFOLOAD(p, MSGINSNOOP, 0,
734 VLF | LAST1 | LAST2 | FLUSH1);
735 SET_LABEL(p, local_offset);
736
737
738 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
739
740
741
742
743
744 MOVE(p, IFIFOAB2, 0, OFIFO, 0, 0, IMMED);
745
746
747 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
748 }
749
750 if (dir == OP_TYPE_DECAP_PROTOCOL)
751 SEQFIFOLOAD(p, ICV1, 4, LAST1 | FLUSH1);
752 else
753 SEQSTORE(p, CONTEXT1, 0, 4, 0);
754
755 break;
756
757 case PDCP_AUTH_TYPE_ZUC:
758 if (rta_sec_era < RTA_SEC_ERA_5) {
759 pr_err("Invalid era for selected algorithm\n");
760 return -ENOTSUP;
761 }
762
763 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
764 authdata->keylen, INLINE_KEY(authdata));
765 SEQLOAD(p, MATH0, offset, length, 0);
766 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
767 SEQINPTR(p, 0, length, RTO);
768 if (swap == false) {
769 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
770 IFB | IMMED2);
771 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
772
773 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
774 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
775 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
776
777 } else {
778 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
779 IFB | IMMED2);
780 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
781
782 MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
783 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
784 MOVE(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
785 }
786 if (dir == OP_TYPE_DECAP_PROTOCOL)
787 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4,
788 IMMED2);
789 else
790 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4, 0);
791
792 MATHB(p, MATH1, SUB, ZERO, VSEQINSZ, 4, 0);
793 MATHB(p, MATH1, SUB, ZERO, VSEQOUTSZ, 4, 0);
794 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
795 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
796 OP_ALG_AAI_F9,
797 OP_ALG_AS_INITFINAL,
798 dir == OP_TYPE_ENCAP_PROTOCOL ?
799 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
800 DIR_ENC);
801 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
802 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
803
804 if (dir == OP_TYPE_DECAP_PROTOCOL)
805 SEQFIFOLOAD(p, ICV2, 4, LAST2);
806 else
807 SEQSTORE(p, CONTEXT2, 0, 4, 0);
808
809 break;
810
811 default:
812 pr_err("%s: Invalid integrity algorithm selected: %d\n",
813 "pdcp_insert_cplane_int_only_op", authdata->algtype);
814 return -EINVAL;
815 }
816
817 if (rta_sec_era < RTA_SEC_ERA_3) {
818 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
819 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
820 }
821
822 return 0;
823}
824
825static inline int
826pdcp_insert_cplane_enc_only_op(struct program *p,
827 bool swap __maybe_unused,
828 struct alginfo *cipherdata,
829 struct alginfo *authdata __maybe_unused,
830 unsigned int dir,
831 enum pdcp_sn_size sn_size,
832 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
833{
834 uint32_t offset = 0, length = 0, sn_mask = 0;
835
836 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
837 cipherdata->keylen, INLINE_KEY(cipherdata));
838
839 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18 &&
840 !(rta_sec_era == RTA_SEC_ERA_8 &&
841 authdata->algtype == 0))
842 || (rta_sec_era == RTA_SEC_ERA_10)) {
843 if (sn_size == PDCP_SN_SIZE_5)
844 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED,
845 (uint16_t)cipherdata->algtype << 8);
846 else
847 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
848 (uint16_t)cipherdata->algtype << 8);
849 return 0;
850 }
851
852 switch (sn_size) {
853 case PDCP_SN_SIZE_5:
854 offset = 7;
855 length = 1;
856 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
857 PDCP_C_PLANE_SN_MASK_BE;
858 break;
859 case PDCP_SN_SIZE_18:
860 offset = 5;
861 length = 3;
862 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
863 PDCP_U_PLANE_18BIT_SN_MASK_BE;
864 break;
865 case PDCP_SN_SIZE_12:
866 offset = 6;
867 length = 2;
868 sn_mask = (swap == false) ? PDCP_12BIT_SN_MASK :
869 PDCP_12BIT_SN_MASK_BE;
870 break;
871 case PDCP_SN_SIZE_7:
872 case PDCP_SN_SIZE_15:
873 pr_err("Invalid sn_size for %s\n", __func__);
874 return -ENOTSUP;
875 }
876
877 SEQLOAD(p, MATH0, offset, length, 0);
878 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
879 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
880 SEQSTORE(p, MATH0, offset, length, 0);
881 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
882 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
883 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
884
885 switch (cipherdata->algtype) {
886 case PDCP_CIPHER_TYPE_SNOW:
887 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
888
889 if (rta_sec_era > RTA_SEC_ERA_2) {
890 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
891 } else {
892 MATHB(p, SEQINSZ, SUB, ONE, MATH1, 4, 0);
893 MATHB(p, MATH1, ADD, ONE, VSEQINSZ, 4, 0);
894 }
895
896 if (dir == OP_TYPE_ENCAP_PROTOCOL)
897 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
898 IMMED2);
899 else
900 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
901 IMMED2);
902 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
903 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
904 OP_ALG_AAI_F8,
905 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
906 dir == OP_TYPE_ENCAP_PROTOCOL ?
907 DIR_ENC : DIR_DEC);
908 break;
909
910 case PDCP_CIPHER_TYPE_AES:
911 MOVEB(p, MATH2, 0, CONTEXT1, 0x10, 0x10, WAITCOMP | IMMED);
912
913 if (rta_sec_era > RTA_SEC_ERA_2) {
914 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
915 } else {
916 MATHB(p, SEQINSZ, SUB, ONE, MATH1, 4, 0);
917 MATHB(p, MATH1, ADD, ONE, VSEQINSZ, 4, 0);
918 }
919
920 if (dir == OP_TYPE_ENCAP_PROTOCOL)
921 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
922 IMMED2);
923 else
924 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
925 IMMED2);
926
927 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
928 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
929 OP_ALG_AAI_CTR,
930 OP_ALG_AS_INITFINAL,
931 ICV_CHECK_DISABLE,
932 dir == OP_TYPE_ENCAP_PROTOCOL ?
933 DIR_ENC : DIR_DEC);
934 break;
935
936 case PDCP_CIPHER_TYPE_ZUC:
937 if (rta_sec_era < RTA_SEC_ERA_5) {
938 pr_err("Invalid era for selected algorithm\n");
939 return -ENOTSUP;
940 }
941
942 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
943 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
944 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
945 if (dir == OP_TYPE_ENCAP_PROTOCOL)
946 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
947 IMMED2);
948 else
949 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
950 IMMED2);
951
952 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
953 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
954 OP_ALG_AAI_F8,
955 OP_ALG_AS_INITFINAL,
956 ICV_CHECK_DISABLE,
957 dir == OP_TYPE_ENCAP_PROTOCOL ?
958 DIR_ENC : DIR_DEC);
959 break;
960
961 default:
962 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
963 "pdcp_insert_cplane_enc_only_op", cipherdata->algtype);
964 return -EINVAL;
965 }
966
967 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
968 SEQFIFOLOAD(p, MSG1, 0, VLF);
969 FIFOLOAD(p, MSG1, PDCP_NULL_INT_MAC_I_VAL, 4,
970 LAST1 | FLUSH1 | IMMED);
971 } else {
972 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
973 MOVE(p, OFIFO, 0, MATH1, 4, PDCP_MAC_I_LEN, WAITCOMP | IMMED);
974 MATHB(p, MATH1, XOR, PDCP_NULL_INT_MAC_I_VAL, NONE, 4, IMMED2);
975 JUMP(p, PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS,
976 HALT_STATUS, ALL_FALSE, MATH_Z);
977 }
978
979 return 0;
980}
981
982static inline int
983pdcp_insert_uplane_snow_snow_op(struct program *p,
984 bool swap __maybe_unused,
985 struct alginfo *cipherdata,
986 struct alginfo *authdata,
987 unsigned int dir,
988 enum pdcp_sn_size sn_size,
989 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
990{
991 uint32_t offset = 0, length = 0, sn_mask = 0;
992
993 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
994 cipherdata->keylen, INLINE_KEY(cipherdata));
995 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
996 INLINE_KEY(authdata));
997
998 if (rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) {
999 int pclid;
1000
1001 if (sn_size == PDCP_SN_SIZE_5)
1002 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1003 else
1004 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1005
1006 PROTOCOL(p, dir, pclid,
1007 ((uint16_t)cipherdata->algtype << 8) |
1008 (uint16_t)authdata->algtype);
1009
1010 return 0;
1011 }
1012
1013 switch (sn_size) {
1014 case PDCP_SN_SIZE_5:
1015 offset = 7;
1016 length = 1;
1017 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1018 PDCP_C_PLANE_SN_MASK_BE;
1019 break;
1020 case PDCP_SN_SIZE_18:
1021 offset = 5;
1022 length = 3;
1023 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1024 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1025 break;
1026 case PDCP_SN_SIZE_7:
1027 case PDCP_SN_SIZE_12:
1028 case PDCP_SN_SIZE_15:
1029 pr_err("Invalid sn_size for %s\n", __func__);
1030 return -ENOTSUP;
1031 }
1032
1033 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1034 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
1035
1036 SEQLOAD(p, MATH0, offset, length, 0);
1037 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1038 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1039 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1040
1041 SEQSTORE(p, MATH0, offset, length, 0);
1042 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1043 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
1044 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
1045 MOVEB(p, MATH1, 0, CONTEXT1, 0, 8, IMMED);
1046 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, WAITCOMP | IMMED);
1047 if (swap == false) {
1048 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK),
1049 MATH2, 4, IMMED2);
1050 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK),
1051 MATH3, 4, IMMED2);
1052 } else {
1053 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE),
1054 MATH2, 4, IMMED2);
1055 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE),
1056 MATH3, 4, IMMED2);
1057 }
1058 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
1059
1060 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
1061 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
1062 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1063 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1064 } else {
1065 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1066 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQINSZ, 4, IMMED2);
1067 }
1068
1069 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1070 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1071 else
1072 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1073
1074 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
1075 OP_ALG_AAI_F9,
1076 OP_ALG_AS_INITFINAL,
1077 dir == OP_TYPE_ENCAP_PROTOCOL ?
1078 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1079 DIR_DEC);
1080 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1081 OP_ALG_AAI_F8,
1082 OP_ALG_AS_INITFINAL,
1083 ICV_CHECK_DISABLE,
1084 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1085
1086 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1087 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1088 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1089 } else {
1090 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
1091 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
1092 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
1093
1094 if (rta_sec_era >= RTA_SEC_ERA_6)
1095 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
1096
1097 MOVE(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
1098
1099 NFIFOADD(p, IFIFO, ICV2, 4, LAST2);
1100
1101 if (rta_sec_era <= RTA_SEC_ERA_2) {
1102
1103 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
1104 MOVE(p, MATH0, 0, IFIFOAB2, 0, 4, WAITCOMP | IMMED);
1105 } else {
1106 MOVE(p, MATH0, 0, IFIFO, 0, 4, WAITCOMP | IMMED);
1107 }
1108 }
1109
1110 return 0;
1111}
1112
1113static inline int
1114pdcp_insert_uplane_zuc_zuc_op(struct program *p,
1115 bool swap __maybe_unused,
1116 struct alginfo *cipherdata,
1117 struct alginfo *authdata,
1118 unsigned int dir,
1119 enum pdcp_sn_size sn_size,
1120 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1121{
1122 uint32_t offset = 0, length = 0, sn_mask = 0;
1123
1124 LABEL(keyjump);
1125 REFERENCE(pkeyjump);
1126
1127 if (rta_sec_era < RTA_SEC_ERA_5) {
1128 pr_err("Invalid era for selected algorithm\n");
1129 return -ENOTSUP;
1130 }
1131
1132 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
1133 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1134 cipherdata->keylen, INLINE_KEY(cipherdata));
1135 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1136 INLINE_KEY(authdata));
1137
1138 SET_LABEL(p, keyjump);
1139 PATCH_JUMP(p, pkeyjump, keyjump);
1140
1141 if (rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) {
1142 int pclid;
1143
1144 if (sn_size == PDCP_SN_SIZE_5)
1145 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1146 else
1147 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1148
1149 PROTOCOL(p, dir, pclid,
1150 ((uint16_t)cipherdata->algtype << 8) |
1151 (uint16_t)authdata->algtype);
1152
1153 return 0;
1154 }
1155
1156 switch (sn_size) {
1157 case PDCP_SN_SIZE_5:
1158 offset = 7;
1159 length = 1;
1160 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1161 PDCP_C_PLANE_SN_MASK_BE;
1162 break;
1163 case PDCP_SN_SIZE_18:
1164 offset = 5;
1165 length = 3;
1166 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1167 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1168 break;
1169 case PDCP_SN_SIZE_7:
1170 case PDCP_SN_SIZE_12:
1171 case PDCP_SN_SIZE_15:
1172 pr_err("Invalid sn_size for %s\n", __func__);
1173 return -ENOTSUP;
1174 }
1175
1176 SEQLOAD(p, MATH0, offset, length, 0);
1177 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1178 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1179 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1180 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1181
1182 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
1183 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1184 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1185
1186 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
1187
1188 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1189 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1190 else
1191 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1192
1193 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1194 SEQSTORE(p, MATH0, offset, length, 0);
1195
1196 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1197 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1198 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1199 } else {
1200 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1201 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | FLUSH1);
1202 }
1203
1204 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
1205 OP_ALG_AAI_F9,
1206 OP_ALG_AS_INITFINAL,
1207 dir == OP_TYPE_ENCAP_PROTOCOL ?
1208 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1209 DIR_ENC);
1210
1211 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
1212 OP_ALG_AAI_F8,
1213 OP_ALG_AS_INITFINAL,
1214 ICV_CHECK_DISABLE,
1215 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1216
1217 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1218 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1219 } else {
1220
1221 MOVEB(p, OFIFO, 0, MATH0, 0, 4, IMMED);
1222
1223 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1224 NFIFOENTRY_DEST_CLASS2 |
1225 NFIFOENTRY_DTYPE_ICV |
1226 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
1227 MOVEB(p, MATH0, 0, ALTSOURCE, 0, 4, WAITCOMP | IMMED);
1228 }
1229
1230
1231 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
1232 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
1233
1234 return 0;
1235}
1236
1237static inline int
1238pdcp_insert_uplane_aes_aes_op(struct program *p,
1239 bool swap __maybe_unused,
1240 struct alginfo *cipherdata,
1241 struct alginfo *authdata,
1242 unsigned int dir,
1243 enum pdcp_sn_size sn_size,
1244 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1245{
1246 uint32_t offset = 0, length = 0, sn_mask = 0;
1247
1248 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18)) {
1249
1250 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
1251 authdata->keylen, INLINE_KEY(authdata));
1252
1253
1254 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1255 cipherdata->keylen, INLINE_KEY(cipherdata));
1256
1257 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
1258 ((uint16_t)cipherdata->algtype << 8) |
1259 (uint16_t)authdata->algtype);
1260 return 0;
1261 }
1262
1263
1264 switch (sn_size) {
1265 case PDCP_SN_SIZE_18:
1266 offset = 5;
1267 length = 3;
1268 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1269 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1270 break;
1271
1272 default:
1273 pr_err("Invalid sn_size for %s\n", __func__);
1274 return -ENOTSUP;
1275 }
1276
1277 SEQLOAD(p, MATH0, offset, length, 0);
1278 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1279 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1280
1281 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1282 MOVEB(p, DESCBUF, 8, MATH2, 0, 0x08, WAITCOMP | IMMED);
1283 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1284 SEQSTORE(p, MATH0, offset, length, 0);
1285
1286 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1287 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1288 authdata->keylen, INLINE_KEY(authdata));
1289 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 0x08, IMMED);
1290 MOVEB(p, MATH0, offset, IFIFOAB1, 0, length, IMMED);
1291
1292 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1293 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1294
1295 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1296 OP_ALG_AAI_CMAC,
1297 OP_ALG_AS_INITFINAL,
1298 ICV_CHECK_DISABLE,
1299 DIR_DEC);
1300 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1301 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
1302
1303 LOAD(p, CLRW_RESET_CLS1_CHA |
1304 CLRW_CLR_C1KEY |
1305 CLRW_CLR_C1CTX |
1306 CLRW_CLR_C1ICV |
1307 CLRW_CLR_C1DATAS |
1308 CLRW_CLR_C1MODE,
1309 CLRW, 0, 4, IMMED);
1310
1311 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1312 cipherdata->keylen, INLINE_KEY(cipherdata));
1313
1314 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
1315 SEQINPTR(p, 0, PDCP_NULL_MAX_FRAME_LEN, RTO);
1316
1317 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1318 OP_ALG_AAI_CTR,
1319 OP_ALG_AS_INITFINAL,
1320 ICV_CHECK_DISABLE,
1321 DIR_ENC);
1322
1323 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1324
1325 SEQFIFOLOAD(p, SKIP, length, 0);
1326
1327 SEQFIFOLOAD(p, MSG1, 0, VLF);
1328 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1329 } else {
1330 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
1331 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
1332
1333 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1334 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1335
1336 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1337 cipherdata->keylen, INLINE_KEY(cipherdata));
1338
1339 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1340 OP_ALG_AAI_CTR,
1341 OP_ALG_AS_INITFINAL,
1342 ICV_CHECK_DISABLE,
1343 DIR_DEC);
1344
1345 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1346 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1347
1348 MOVEB(p, OFIFO, 0, MATH3, 0, 4, IMMED);
1349
1350 LOAD(p, CLRW_RESET_CLS1_CHA |
1351 CLRW_CLR_C1KEY |
1352 CLRW_CLR_C1CTX |
1353 CLRW_CLR_C1ICV |
1354 CLRW_CLR_C1DATAS |
1355 CLRW_CLR_C1MODE,
1356 CLRW, 0, 4, IMMED);
1357
1358 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1359 authdata->keylen, INLINE_KEY(authdata));
1360
1361 SEQINPTR(p, 0, 0, SOP);
1362
1363 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1364 OP_ALG_AAI_CMAC,
1365 OP_ALG_AS_INITFINAL,
1366 ICV_CHECK_ENABLE,
1367 DIR_DEC);
1368
1369 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1370
1371 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
1372
1373 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1374
1375 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1376 NFIFOENTRY_DEST_CLASS1 |
1377 NFIFOENTRY_DTYPE_ICV |
1378 NFIFOENTRY_LC1 |
1379 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
1380 MOVEB(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
1381 }
1382
1383 return 0;
1384}
1385
1386static inline int
1387pdcp_insert_cplane_acc_op(struct program *p,
1388 bool swap __maybe_unused,
1389 struct alginfo *cipherdata,
1390 struct alginfo *authdata,
1391 unsigned int dir,
1392 enum pdcp_sn_size sn_size,
1393 unsigned char era_2_hfn_ovrd __maybe_unused)
1394{
1395
1396 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1397 INLINE_KEY(authdata));
1398
1399
1400 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1401 cipherdata->keylen, INLINE_KEY(cipherdata));
1402
1403 if (sn_size == PDCP_SN_SIZE_5)
1404 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL,
1405 (uint16_t)cipherdata->algtype);
1406 else
1407 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
1408 ((uint16_t)cipherdata->algtype << 8) |
1409 (uint16_t)authdata->algtype);
1410
1411 return 0;
1412}
1413
1414static inline int
1415pdcp_insert_cplane_snow_aes_op(struct program *p,
1416 bool swap __maybe_unused,
1417 struct alginfo *cipherdata,
1418 struct alginfo *authdata,
1419 unsigned int dir,
1420 enum pdcp_sn_size sn_size,
1421 unsigned char era_2_sw_hfn_ovrd)
1422{
1423 uint32_t offset = 0, length = 0, sn_mask = 0;
1424
1425 LABEL(back_to_sd_offset);
1426 LABEL(end_desc);
1427 LABEL(local_offset);
1428 LABEL(jump_to_beginning);
1429 LABEL(fifo_load_mac_i_offset);
1430 REFERENCE(seqin_ptr_read);
1431 REFERENCE(seqin_ptr_write);
1432 REFERENCE(seq_out_read);
1433 REFERENCE(jump_back_to_sd_cmd);
1434 REFERENCE(move_mac_i_to_desc_buf);
1435
1436 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
1437 (rta_sec_era == RTA_SEC_ERA_10)) {
1438 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1439 cipherdata->keylen, INLINE_KEY(cipherdata));
1440 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
1441 authdata->keylen, INLINE_KEY(authdata));
1442
1443 if (sn_size == PDCP_SN_SIZE_5)
1444 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED,
1445 ((uint16_t)cipherdata->algtype << 8) |
1446 (uint16_t)authdata->algtype);
1447 else
1448 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
1449 ((uint16_t)cipherdata->algtype << 8) |
1450 (uint16_t)authdata->algtype);
1451
1452 return 0;
1453 }
1454
1455 switch (sn_size) {
1456 case PDCP_SN_SIZE_5:
1457 offset = 7;
1458 length = 1;
1459 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1460 PDCP_C_PLANE_SN_MASK_BE;
1461 break;
1462 case PDCP_SN_SIZE_18:
1463 offset = 5;
1464 length = 3;
1465 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1466 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1467 break;
1468 case PDCP_SN_SIZE_7:
1469 case PDCP_SN_SIZE_12:
1470 case PDCP_SN_SIZE_15:
1471 pr_err("Invalid sn_size for %s\n", __func__);
1472 return -ENOTSUP;
1473
1474 }
1475
1476 SEQLOAD(p, MATH0, offset, length, 0);
1477 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1478 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1479 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1480 MOVEB(p, DESCBUF, 4, MATH2, 0, 0x08, WAITCOMP | IMMED);
1481 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1482 SEQSTORE(p, MATH0, offset, length, 0);
1483 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1484 if (rta_sec_era > RTA_SEC_ERA_2 ||
1485 (rta_sec_era == RTA_SEC_ERA_2 &&
1486 era_2_sw_hfn_ovrd == 0)) {
1487 SEQINPTR(p, 0, length, RTO);
1488 } else {
1489 SEQINPTR(p, 0, 5, RTO);
1490 SEQFIFOLOAD(p, SKIP, 4, 0);
1491 }
1492 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1493 authdata->keylen, INLINE_KEY(authdata));
1494 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 0x08, IMMED);
1495
1496 if (rta_sec_era > RTA_SEC_ERA_2) {
1497 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1498 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4, 0);
1499 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN - 1, VSEQOUTSZ,
1500 4, IMMED2);
1501 } else {
1502 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
1503 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN - 1, VSEQOUTSZ,
1504 4, IMMED2);
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527 if (era_2_sw_hfn_ovrd)
1528 MATHB(p, VSEQOUTSZ, ADD, ONE, MATH1, 4,
1529 0);
1530 else
1531 MATHB(p, SEQINSZ, ADD, MATH3, MATH1, 4,
1532 0);
1533 }
1534
1535
1536
1537
1538 seqin_ptr_read = MOVE(p, DESCBUF, 0, MATH1, 0, 6, IMMED);
1539 seqin_ptr_write = MOVE(p, MATH1, 0, DESCBUF, 0, 8,
1540 WAITCOMP | IMMED);
1541 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1542 OP_ALG_AAI_CMAC,
1543 OP_ALG_AS_INITFINAL,
1544 ICV_CHECK_DISABLE,
1545 DIR_DEC);
1546 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1547 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
1548 if (rta_sec_era <= RTA_SEC_ERA_3)
1549 LOAD(p, CLRW_CLR_C1KEY |
1550 CLRW_CLR_C1CTX |
1551 CLRW_CLR_C1ICV |
1552 CLRW_CLR_C1DATAS |
1553 CLRW_CLR_C1MODE,
1554 CLRW, 0, 4, IMMED);
1555 else
1556 LOAD(p, CLRW_RESET_CLS1_CHA |
1557 CLRW_CLR_C1KEY |
1558 CLRW_CLR_C1CTX |
1559 CLRW_CLR_C1ICV |
1560 CLRW_CLR_C1DATAS |
1561 CLRW_CLR_C1MODE,
1562 CLRW, 0, 4, IMMED);
1563
1564 if (rta_sec_era <= RTA_SEC_ERA_3)
1565 LOAD(p, CCTRL_RESET_CHA_ALL, CCTRL, 0, 4, IMMED);
1566
1567 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1568 cipherdata->keylen, INLINE_KEY(cipherdata));
1569 SET_LABEL(p, local_offset);
1570 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1571 SEQINPTR(p, 0, 0, RTO);
1572
1573 if (rta_sec_era == RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
1574 SEQFIFOLOAD(p, SKIP, 5, 0);
1575 MATHB(p, SEQINSZ, ADD, ONE, SEQINSZ, 4, 0);
1576 }
1577
1578 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
1579 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1580 OP_ALG_AAI_F8,
1581 OP_ALG_AS_INITFINAL,
1582 ICV_CHECK_DISABLE,
1583 DIR_ENC);
1584 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1585
1586 if (rta_sec_era > RTA_SEC_ERA_2 ||
1587 (rta_sec_era == RTA_SEC_ERA_2 &&
1588 era_2_sw_hfn_ovrd == 0))
1589 SEQFIFOLOAD(p, SKIP, length, 0);
1590
1591 SEQFIFOLOAD(p, MSG1, 0, VLF);
1592 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1593 PATCH_MOVE(p, seqin_ptr_read, local_offset);
1594 PATCH_MOVE(p, seqin_ptr_write, local_offset);
1595 } else {
1596 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1597
1598 if (rta_sec_era >= RTA_SEC_ERA_5)
1599 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
1600
1601 if (rta_sec_era > RTA_SEC_ERA_2)
1602 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1603 else
1604 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
1605
1606 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1607
1608
1609
1610
1611
1612 if (p->ps)
1613 WORD(p, 0x168B0004);
1614 else
1615 WORD(p, 0x16880404);
1616
1617 jump_back_to_sd_cmd = JUMP(p, 0, LOCAL_JUMP, ALL_TRUE, 0);
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627 if (p->ps)
1628 seq_out_read = MOVE(p, DESCBUF, 0, MATH1, 0, 20,
1629 WAITCOMP | IMMED);
1630 else
1631 seq_out_read = MOVE(p, DESCBUF, 0, MATH1, 0, 16,
1632 WAITCOMP | IMMED);
1633
1634 MATHB(p, MATH1, XOR, CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR, MATH1, 4,
1635 IMMED2);
1636
1637
1638
1639
1640
1641 if (p->ps)
1642 MOVE(p, MATH1, 0, DESCBUF, 0, 24, IMMED);
1643 else
1644 MOVE(p, MATH1, 0, DESCBUF, 0, 20, IMMED);
1645
1646 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1647 cipherdata->keylen, INLINE_KEY(cipherdata));
1648
1649 if (rta_sec_era >= RTA_SEC_ERA_4)
1650 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
1651 else
1652 MOVE(p, CONTEXT1, 0, MATH3, 0, 8, IMMED);
1653
1654 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1655 OP_ALG_AAI_F8,
1656 OP_ALG_AS_INITFINAL,
1657 ICV_CHECK_DISABLE,
1658 DIR_DEC);
1659 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1660 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1661
1662 if (rta_sec_era <= RTA_SEC_ERA_3)
1663 move_mac_i_to_desc_buf = MOVE(p, OFIFO, 0, DESCBUF, 0,
1664 4, WAITCOMP | IMMED);
1665 else
1666 MOVE(p, OFIFO, 0, MATH3, 0, 4, IMMED);
1667
1668 if (rta_sec_era <= RTA_SEC_ERA_3)
1669 LOAD(p, CCTRL_RESET_CHA_ALL, CCTRL, 0, 4, IMMED);
1670 else
1671 LOAD(p, CLRW_RESET_CLS1_CHA |
1672 CLRW_CLR_C1KEY |
1673 CLRW_CLR_C1CTX |
1674 CLRW_CLR_C1ICV |
1675 CLRW_CLR_C1DATAS |
1676 CLRW_CLR_C1MODE,
1677 CLRW, 0, 4, IMMED);
1678
1679 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1680 authdata->keylen, INLINE_KEY(authdata));
1681
1682
1683
1684
1685
1686 SET_LABEL(p, jump_to_beginning);
1687 JUMP(p, 1 - jump_to_beginning, LOCAL_JUMP, ALL_TRUE, 0);
1688 SET_LABEL(p, back_to_sd_offset);
1689 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1690 OP_ALG_AAI_CMAC,
1691 OP_ALG_AS_INITFINAL,
1692 ICV_CHECK_ENABLE,
1693 DIR_DEC);
1694
1695
1696 MATHI(p, VSEQOUTSZ, ADD, length, VSEQINSZ, 4, IMMED2);
1697
1698 if (rta_sec_era <= RTA_SEC_ERA_3)
1699 MOVE(p, MATH3, 0, IFIFOAB1, 0, 8, IMMED);
1700 else
1701 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
1702
1703 if (rta_sec_era == RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd)
1704 SEQFIFOLOAD(p, SKIP, 4, 0);
1705
1706 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1707
1708 if (rta_sec_era >= RTA_SEC_ERA_4) {
1709 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1710 NFIFOENTRY_DEST_CLASS1 |
1711 NFIFOENTRY_DTYPE_ICV |
1712 NFIFOENTRY_LC1 |
1713 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
1714 MOVE(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
1715 } else {
1716 SET_LABEL(p, fifo_load_mac_i_offset);
1717 FIFOLOAD(p, ICV1, fifo_load_mac_i_offset, 4,
1718 LAST1 | FLUSH1 | IMMED);
1719 }
1720
1721 SET_LABEL(p, end_desc);
1722
1723 if (!p->ps) {
1724 PATCH_MOVE(p, seq_out_read, end_desc + 1);
1725 PATCH_JUMP(p, jump_back_to_sd_cmd,
1726 back_to_sd_offset + jump_back_to_sd_cmd - 5);
1727
1728 if (rta_sec_era <= RTA_SEC_ERA_3)
1729 PATCH_MOVE(p, move_mac_i_to_desc_buf,
1730 fifo_load_mac_i_offset + 1);
1731 } else {
1732 PATCH_MOVE(p, seq_out_read, end_desc + 2);
1733 PATCH_JUMP(p, jump_back_to_sd_cmd,
1734 back_to_sd_offset + jump_back_to_sd_cmd - 5);
1735
1736 if (rta_sec_era <= RTA_SEC_ERA_3)
1737 PATCH_MOVE(p, move_mac_i_to_desc_buf,
1738 fifo_load_mac_i_offset + 1);
1739 }
1740 }
1741
1742 return 0;
1743}
1744
1745static inline int
1746pdcp_insert_cplane_aes_snow_op(struct program *p,
1747 bool swap __maybe_unused,
1748 struct alginfo *cipherdata,
1749 struct alginfo *authdata,
1750 unsigned int dir,
1751 enum pdcp_sn_size sn_size,
1752 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1753{
1754 uint32_t offset = 0, length = 0, sn_mask = 0;
1755
1756 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1757 cipherdata->keylen, INLINE_KEY(cipherdata));
1758 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1759 INLINE_KEY(authdata));
1760
1761 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
1762 (rta_sec_era == RTA_SEC_ERA_10)) {
1763 int pclid;
1764
1765 if (sn_size == PDCP_SN_SIZE_5)
1766 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1767 else
1768 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1769
1770 PROTOCOL(p, dir, pclid,
1771 ((uint16_t)cipherdata->algtype << 8) |
1772 (uint16_t)authdata->algtype);
1773
1774 return 0;
1775 }
1776
1777 switch (sn_size) {
1778 case PDCP_SN_SIZE_5:
1779 offset = 7;
1780 length = 1;
1781 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1782 PDCP_C_PLANE_SN_MASK_BE;
1783 break;
1784 case PDCP_SN_SIZE_18:
1785 offset = 5;
1786 length = 3;
1787 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1788 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1789 break;
1790 case PDCP_SN_SIZE_7:
1791 case PDCP_SN_SIZE_12:
1792 case PDCP_SN_SIZE_15:
1793 pr_err("Invalid sn_size for %s\n", __func__);
1794 return -ENOTSUP;
1795
1796 }
1797
1798 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1799 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
1800
1801 SEQLOAD(p, MATH0, offset, length, 0);
1802 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1803 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1804 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1805
1806 SEQSTORE(p, MATH0, offset, length, 0);
1807 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1808 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
1809 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
1810 MOVEB(p, MATH1, 0, CONTEXT1, 16, 8, IMMED);
1811 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, IMMED);
1812 if (swap == false) {
1813 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK), MATH2, 4,
1814 IMMED2);
1815 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK), MATH3, 4,
1816 IMMED2);
1817 } else {
1818 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE), MATH2,
1819 4, IMMED2);
1820 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE), MATH3,
1821 4, IMMED2);
1822 }
1823 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
1824 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
1825 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
1826 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1827 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1828 } else {
1829 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4, IMMED2);
1830
1831 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
1832 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
1833 }
1834
1835 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1836 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1837 else
1838 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1839
1840 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
1841 OP_ALG_AAI_F9,
1842 OP_ALG_AS_INITFINAL,
1843 dir == OP_TYPE_ENCAP_PROTOCOL ?
1844 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1845 DIR_DEC);
1846 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1847 OP_ALG_AAI_CTR,
1848 OP_ALG_AS_INITFINAL,
1849 ICV_CHECK_DISABLE,
1850 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1851
1852 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1853 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1854 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1855 } else {
1856 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
1857 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
1858 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
1859
1860 if (rta_sec_era >= RTA_SEC_ERA_6)
1861 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
1862
1863 MOVE(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
1864
1865 NFIFOADD(p, IFIFO, ICV2, 4, LAST2);
1866
1867 if (rta_sec_era <= RTA_SEC_ERA_2) {
1868
1869 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
1870 MOVE(p, MATH0, 0, IFIFOAB2, 0, 4, WAITCOMP | IMMED);
1871 } else {
1872 MOVE(p, MATH0, 0, IFIFO, 0, 4, WAITCOMP | IMMED);
1873 }
1874 }
1875
1876 return 0;
1877}
1878
1879static inline int
1880pdcp_insert_cplane_snow_zuc_op(struct program *p,
1881 bool swap __maybe_unused,
1882 struct alginfo *cipherdata,
1883 struct alginfo *authdata,
1884 unsigned int dir,
1885 enum pdcp_sn_size sn_size,
1886 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1887{
1888 uint32_t offset = 0, length = 0, sn_mask = 0;
1889
1890 LABEL(keyjump);
1891 REFERENCE(pkeyjump);
1892
1893 if (rta_sec_era < RTA_SEC_ERA_5) {
1894 pr_err("Invalid era for selected algorithm\n");
1895 return -ENOTSUP;
1896 }
1897
1898 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
1899 (rta_sec_era == RTA_SEC_ERA_10)) {
1900 int pclid;
1901 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1902 cipherdata->keylen, INLINE_KEY(cipherdata));
1903 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1904 INLINE_KEY(authdata));
1905
1906 if (sn_size == PDCP_SN_SIZE_5)
1907 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1908 else
1909 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1910
1911 PROTOCOL(p, dir, pclid,
1912 ((uint16_t)cipherdata->algtype << 8) |
1913 (uint16_t)authdata->algtype);
1914 return 0;
1915 }
1916
1917 switch (sn_size) {
1918 case PDCP_SN_SIZE_5:
1919 offset = 7;
1920 length = 1;
1921 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1922 PDCP_C_PLANE_SN_MASK_BE;
1923 break;
1924 case PDCP_SN_SIZE_18:
1925 offset = 5;
1926 length = 3;
1927 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1928 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1929 break;
1930 case PDCP_SN_SIZE_7:
1931 case PDCP_SN_SIZE_12:
1932 case PDCP_SN_SIZE_15:
1933 pr_err("Invalid sn_size for %s\n", __func__);
1934 return -ENOTSUP;
1935
1936 }
1937
1938 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
1939 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1940 cipherdata->keylen, INLINE_KEY(cipherdata));
1941 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1942 INLINE_KEY(authdata));
1943
1944 SET_LABEL(p, keyjump);
1945 SEQLOAD(p, MATH0, offset, length, 0);
1946 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1947 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1948 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1949
1950 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1951 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
1952 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1953 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1954 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
1955
1956 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1957 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1958 else
1959 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1960
1961 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1962 SEQSTORE(p, MATH0, offset, length, 0);
1963
1964 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1965 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1966 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1967 } else {
1968 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1969 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | FLUSH1);
1970 }
1971
1972 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
1973 OP_ALG_AAI_F9,
1974 OP_ALG_AS_INITFINAL,
1975 dir == OP_TYPE_ENCAP_PROTOCOL ?
1976 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1977 DIR_ENC);
1978
1979 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1980 OP_ALG_AAI_F8,
1981 OP_ALG_AS_INITFINAL,
1982 ICV_CHECK_DISABLE,
1983 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1984 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1985 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1986 } else {
1987
1988 MOVE(p, OFIFO, 0, MATH0, 0, 4, IMMED);
1989 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1990 NFIFOENTRY_DEST_CLASS2 |
1991 NFIFOENTRY_DTYPE_ICV |
1992 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
1993 MOVE(p, MATH0, 0, ALTSOURCE, 0, 4, WAITCOMP | IMMED);
1994 }
1995
1996
1997 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
1998 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
1999
2000 PATCH_JUMP(p, pkeyjump, keyjump);
2001 return 0;
2002}
2003
2004static inline int
2005pdcp_insert_cplane_aes_zuc_op(struct program *p,
2006 bool swap __maybe_unused,
2007 struct alginfo *cipherdata,
2008 struct alginfo *authdata,
2009 unsigned int dir,
2010 enum pdcp_sn_size sn_size,
2011 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
2012{
2013 uint32_t offset = 0, length = 0, sn_mask = 0;
2014 LABEL(keyjump);
2015 REFERENCE(pkeyjump);
2016
2017 if (rta_sec_era < RTA_SEC_ERA_5) {
2018 pr_err("Invalid era for selected algorithm\n");
2019 return -ENOTSUP;
2020 }
2021
2022 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
2023 (rta_sec_era == RTA_SEC_ERA_10)) {
2024 int pclid;
2025 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2026 cipherdata->keylen, INLINE_KEY(cipherdata));
2027 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2028 INLINE_KEY(authdata));
2029
2030 if (sn_size == PDCP_SN_SIZE_5)
2031 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
2032 else
2033 pclid = OP_PCLID_LTE_PDCP_USER_RN;
2034
2035 PROTOCOL(p, dir, pclid,
2036 ((uint16_t)cipherdata->algtype << 8) |
2037 (uint16_t)authdata->algtype);
2038
2039 return 0;
2040 }
2041
2042 switch (sn_size) {
2043 case PDCP_SN_SIZE_5:
2044 offset = 7;
2045 length = 1;
2046 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
2047 PDCP_C_PLANE_SN_MASK_BE;
2048 break;
2049 case PDCP_SN_SIZE_18:
2050 offset = 5;
2051 length = 3;
2052 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2053 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2054 break;
2055 case PDCP_SN_SIZE_7:
2056 case PDCP_SN_SIZE_12:
2057 case PDCP_SN_SIZE_15:
2058 pr_err("Invalid sn_size for %s\n", __func__);
2059 return -ENOTSUP;
2060
2061 }
2062 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
2063 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2064 cipherdata->keylen, INLINE_KEY(cipherdata));
2065 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2066 INLINE_KEY(authdata));
2067
2068 SET_LABEL(p, keyjump);
2069
2070 SEQLOAD(p, MATH0, offset, length, 0);
2071 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2072 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
2073 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2074
2075 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2076 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
2077 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
2078 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
2079 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
2080
2081 if (dir == OP_TYPE_ENCAP_PROTOCOL)
2082 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2083 else
2084 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2085
2086 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2087 SEQSTORE(p, MATH0, offset, length, 0);
2088
2089 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2090 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2091 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
2092 } else {
2093 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
2094 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | FLUSH1);
2095 }
2096
2097 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
2098 OP_ALG_AAI_F9,
2099 OP_ALG_AS_INITFINAL,
2100 dir == OP_TYPE_ENCAP_PROTOCOL ?
2101 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
2102 DIR_ENC);
2103
2104 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2105 OP_ALG_AAI_CTR,
2106 OP_ALG_AS_INITFINAL,
2107 ICV_CHECK_DISABLE,
2108 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
2109
2110 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2111 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
2112 } else {
2113
2114 MOVE(p, OFIFO, 0, MATH0, 0, 4, IMMED);
2115
2116 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
2117 NFIFOENTRY_DEST_CLASS2 |
2118 NFIFOENTRY_DTYPE_ICV |
2119 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
2120 MOVE(p, MATH0, 0, ALTSOURCE, 0, 4, WAITCOMP | IMMED);
2121 }
2122
2123
2124 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
2125 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
2126
2127 PATCH_JUMP(p, pkeyjump, keyjump);
2128
2129 return 0;
2130}
2131
2132static inline int
2133pdcp_insert_cplane_zuc_snow_op(struct program *p,
2134 bool swap __maybe_unused,
2135 struct alginfo *cipherdata,
2136 struct alginfo *authdata,
2137 unsigned int dir,
2138 enum pdcp_sn_size sn_size,
2139 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
2140{
2141 uint32_t offset = 0, length = 0, sn_mask = 0;
2142 LABEL(keyjump);
2143 REFERENCE(pkeyjump);
2144
2145 if (rta_sec_era < RTA_SEC_ERA_5) {
2146 pr_err("Invalid era for selected algorithm\n");
2147 return -ENOTSUP;
2148 }
2149
2150 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
2151 (rta_sec_era == RTA_SEC_ERA_10)) {
2152 int pclid;
2153 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2154 cipherdata->keylen, INLINE_KEY(cipherdata));
2155 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2156 INLINE_KEY(authdata));
2157
2158 if (sn_size == PDCP_SN_SIZE_5)
2159 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
2160 else
2161 pclid = OP_PCLID_LTE_PDCP_USER_RN;
2162
2163 PROTOCOL(p, dir, pclid,
2164 ((uint16_t)cipherdata->algtype << 8) |
2165 (uint16_t)authdata->algtype);
2166
2167 return 0;
2168 }
2169
2170 switch (sn_size) {
2171 case PDCP_SN_SIZE_5:
2172 offset = 7;
2173 length = 1;
2174 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
2175 PDCP_C_PLANE_SN_MASK_BE;
2176 break;
2177 case PDCP_SN_SIZE_18:
2178 offset = 5;
2179 length = 3;
2180 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2181 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2182 break;
2183 case PDCP_SN_SIZE_7:
2184 case PDCP_SN_SIZE_12:
2185 case PDCP_SN_SIZE_15:
2186 pr_err("Invalid sn_size for %s\n", __func__);
2187 return -ENOTSUP;
2188
2189 }
2190 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
2191 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2192 cipherdata->keylen, INLINE_KEY(cipherdata));
2193 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2194 INLINE_KEY(authdata));
2195
2196 SET_LABEL(p, keyjump);
2197 SEQLOAD(p, MATH0, offset, length, 0);
2198 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2199 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
2200 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2201
2202 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2203 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
2204 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
2205 MOVEB(p, MATH1, 0, CONTEXT1, 0, 8, IMMED);
2206 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, IMMED);
2207 if (swap == false) {
2208 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK), MATH2,
2209 4, IMMED2);
2210 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK), MATH3,
2211 4, IMMED2);
2212 } else {
2213 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE), MATH2,
2214 4, IMMED2);
2215 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE), MATH3,
2216 4, IMMED2);
2217 }
2218 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
2219 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
2220 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
2221
2222 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2223 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2224 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2225 } else {
2226 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2227 MATHB(p, VSEQOUTSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2228 }
2229
2230 SEQSTORE(p, MATH0, offset, length, 0);
2231
2232 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2233 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2234 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
2235 } else {
2236 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
2237 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
2238 }
2239
2240 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
2241 OP_ALG_AAI_F9,
2242 OP_ALG_AS_INITFINAL,
2243 dir == OP_TYPE_ENCAP_PROTOCOL ?
2244 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
2245 DIR_DEC);
2246
2247 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2248 OP_ALG_AAI_F8,
2249 OP_ALG_AS_INITFINAL,
2250 ICV_CHECK_DISABLE,
2251 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
2252
2253 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2254 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
2255 } else {
2256 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
2257 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
2258
2259 if (rta_sec_era >= RTA_SEC_ERA_6)
2260
2261
2262
2263
2264
2265 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
2266
2267
2268 MOVEB(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
2269
2270 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
2271 NFIFOENTRY_DEST_CLASS2 |
2272 NFIFOENTRY_DTYPE_ICV |
2273 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
2274 MOVEB(p, MATH0, 0, ALTSOURCE, 0, 4, IMMED);
2275 }
2276
2277 PATCH_JUMP(p, pkeyjump, keyjump);
2278 return 0;
2279}
2280
2281static inline int
2282pdcp_insert_cplane_zuc_aes_op(struct program *p,
2283 bool swap __maybe_unused,
2284 struct alginfo *cipherdata,
2285 struct alginfo *authdata,
2286 unsigned int dir,
2287 enum pdcp_sn_size sn_size,
2288 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
2289{
2290 uint32_t offset = 0, length = 0, sn_mask = 0;
2291 if (rta_sec_era < RTA_SEC_ERA_5) {
2292 pr_err("Invalid era for selected algorithm\n");
2293 return -ENOTSUP;
2294 }
2295
2296 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
2297 (rta_sec_era == RTA_SEC_ERA_10)) {
2298 int pclid;
2299
2300 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2301 cipherdata->keylen, INLINE_KEY(cipherdata));
2302 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
2303 authdata->keylen, INLINE_KEY(authdata));
2304
2305 if (sn_size == PDCP_SN_SIZE_5)
2306 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
2307 else
2308 pclid = OP_PCLID_LTE_PDCP_USER_RN;
2309
2310 PROTOCOL(p, dir, pclid,
2311 ((uint16_t)cipherdata->algtype << 8) |
2312 (uint16_t)authdata->algtype);
2313 return 0;
2314 }
2315
2316 switch (sn_size) {
2317 case PDCP_SN_SIZE_5:
2318 offset = 7;
2319 length = 1;
2320 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
2321 PDCP_C_PLANE_SN_MASK_BE;
2322 break;
2323 case PDCP_SN_SIZE_18:
2324 offset = 5;
2325 length = 3;
2326 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2327 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2328 break;
2329 case PDCP_SN_SIZE_7:
2330 case PDCP_SN_SIZE_12:
2331 case PDCP_SN_SIZE_15:
2332 pr_err("Invalid sn_size for %s\n", __func__);
2333 return -ENOTSUP;
2334 }
2335
2336 SEQLOAD(p, MATH0, offset, length, 0);
2337 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2338 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2339
2340 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2341 MOVEB(p, DESCBUF, 4, MATH2, 0, 0x08, WAITCOMP | IMMED);
2342 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
2343 SEQSTORE(p, MATH0, offset, length, 0);
2344 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2345 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
2346 authdata->keylen, INLINE_KEY(authdata));
2347 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 0x08, IMMED);
2348 MOVEB(p, MATH0, offset, IFIFOAB1, 0, length, IMMED);
2349
2350 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2351 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2352
2353 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2354 OP_ALG_AAI_CMAC,
2355 OP_ALG_AS_INITFINAL,
2356 ICV_CHECK_DISABLE,
2357 DIR_DEC);
2358 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2359 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
2360 LOAD(p, CLRW_RESET_CLS1_CHA |
2361 CLRW_CLR_C1KEY |
2362 CLRW_CLR_C1CTX |
2363 CLRW_CLR_C1ICV |
2364 CLRW_CLR_C1DATAS |
2365 CLRW_CLR_C1MODE,
2366 CLRW, 0, 4, IMMED);
2367
2368 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2369 cipherdata->keylen, INLINE_KEY(cipherdata));
2370
2371 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
2372 SEQINPTR(p, 0, PDCP_NULL_MAX_FRAME_LEN, RTO);
2373
2374 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2375 OP_ALG_AAI_F8,
2376 OP_ALG_AS_INITFINAL,
2377 ICV_CHECK_DISABLE,
2378 DIR_ENC);
2379 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2380
2381 SEQFIFOLOAD(p, SKIP, length, 0);
2382
2383 SEQFIFOLOAD(p, MSG1, 0, VLF);
2384 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
2385 } else {
2386 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
2387
2388 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
2389
2390 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2391
2392 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2393
2394 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2395 cipherdata->keylen, INLINE_KEY(cipherdata));
2396
2397 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
2398
2399 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2400 OP_ALG_AAI_F8,
2401 OP_ALG_AS_INITFINAL,
2402 ICV_CHECK_DISABLE,
2403 DIR_DEC);
2404 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
2405 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2406
2407 MOVEB(p, OFIFO, 0, MATH3, 0, 4, IMMED);
2408
2409 LOAD(p, CLRW_RESET_CLS1_CHA |
2410 CLRW_CLR_C1KEY |
2411 CLRW_CLR_C1CTX |
2412 CLRW_CLR_C1ICV |
2413 CLRW_CLR_C1DATAS |
2414 CLRW_CLR_C1MODE,
2415 CLRW, 0, 4, IMMED);
2416
2417 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
2418 authdata->keylen, INLINE_KEY(authdata));
2419
2420 SEQINPTR(p, 0, 0, SOP);
2421
2422 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2423 OP_ALG_AAI_CMAC,
2424 OP_ALG_AS_INITFINAL,
2425 ICV_CHECK_ENABLE,
2426 DIR_DEC);
2427
2428 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2429
2430 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
2431
2432 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2433
2434 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
2435 NFIFOENTRY_DEST_CLASS1 |
2436 NFIFOENTRY_DTYPE_ICV |
2437 NFIFOENTRY_LC1 |
2438 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
2439 MOVEB(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
2440 }
2441
2442 return 0;
2443}
2444
2445static inline int
2446pdcp_insert_uplane_no_int_op(struct program *p,
2447 bool swap __maybe_unused,
2448 struct alginfo *cipherdata,
2449 unsigned int dir,
2450 enum pdcp_sn_size sn_size)
2451{
2452 int op;
2453 uint32_t sn_mask;
2454
2455
2456 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2457 cipherdata->keylen, INLINE_KEY(cipherdata));
2458
2459 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size == PDCP_SN_SIZE_15) ||
2460 (rta_sec_era >= RTA_SEC_ERA_10)) {
2461 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER,
2462 (uint16_t)cipherdata->algtype);
2463 return 0;
2464 }
2465
2466 if (sn_size == PDCP_SN_SIZE_15) {
2467 SEQLOAD(p, MATH0, 6, 2, 0);
2468 sn_mask = (swap == false) ? PDCP_U_PLANE_15BIT_SN_MASK :
2469 PDCP_U_PLANE_15BIT_SN_MASK_BE;
2470 } else {
2471 SEQLOAD(p, MATH0, 5, 3, 0);
2472 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2473 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2474 }
2475 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2476 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2477
2478 if (sn_size == PDCP_SN_SIZE_15)
2479 SEQSTORE(p, MATH0, 6, 2, 0);
2480 else
2481 SEQSTORE(p, MATH0, 5, 3, 0);
2482
2483 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2484 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
2485 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
2486
2487 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
2488 MATHB(p, SEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
2489
2490 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2491
2492 op = dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC;
2493 switch (cipherdata->algtype) {
2494 case PDCP_CIPHER_TYPE_SNOW:
2495 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
2496 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
2497 OP_ALG_AAI_F8,
2498 OP_ALG_AS_INITFINAL,
2499 ICV_CHECK_DISABLE,
2500 op);
2501 break;
2502
2503 case PDCP_CIPHER_TYPE_AES:
2504 MOVEB(p, MATH2, 0, CONTEXT1, 0x10, 0x10, WAITCOMP | IMMED);
2505 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2506 OP_ALG_AAI_CTR,
2507 OP_ALG_AS_INITFINAL,
2508 ICV_CHECK_DISABLE,
2509 op);
2510 break;
2511
2512 case PDCP_CIPHER_TYPE_ZUC:
2513 if (rta_sec_era < RTA_SEC_ERA_5) {
2514 pr_err("Invalid era for selected algorithm\n");
2515 return -ENOTSUP;
2516 }
2517 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
2518 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
2519
2520 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2521 OP_ALG_AAI_F8,
2522 OP_ALG_AS_INITFINAL,
2523 ICV_CHECK_DISABLE,
2524 op);
2525 break;
2526
2527 default:
2528 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
2529 "pdcp_insert_uplane_15bit_op", cipherdata->algtype);
2530 return -EINVAL;
2531 }
2532
2533 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2534
2535 return 0;
2536}
2537
2538
2539
2540
2541
2542static inline int
2543insert_hfn_ov_op(struct program *p,
2544 uint32_t shift,
2545 enum pdb_type_e pdb_type,
2546 unsigned char era_2_sw_hfn_ovrd)
2547{
2548 uint32_t imm = PDCP_DPOVRD_HFN_OV_EN;
2549 uint16_t hfn_pdb_offset;
2550 LABEL(keyjump);
2551 REFERENCE(pkeyjump);
2552
2553 if (rta_sec_era == RTA_SEC_ERA_2 && !era_2_sw_hfn_ovrd)
2554 return 0;
2555
2556 switch (pdb_type) {
2557 case PDCP_PDB_TYPE_NO_PDB:
2558
2559
2560
2561
2562
2563
2564 return 0;
2565
2566 case PDCP_PDB_TYPE_REDUCED_PDB:
2567 hfn_pdb_offset = 4;
2568 break;
2569
2570 case PDCP_PDB_TYPE_FULL_PDB:
2571 hfn_pdb_offset = 8;
2572 break;
2573
2574 default:
2575 return -EINVAL;
2576 }
2577
2578 if (rta_sec_era > RTA_SEC_ERA_2) {
2579 MATHB(p, DPOVRD, AND, imm, NONE, 8, IFB | IMMED2);
2580 } else {
2581 SEQLOAD(p, MATH0, 4, 4, 0);
2582 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2583 MATHB(p, MATH0, AND, imm, NONE, 8, IFB | IMMED2);
2584 SEQSTORE(p, MATH0, 4, 4, 0);
2585 }
2586
2587 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, MATH_Z);
2588
2589 if (rta_sec_era > RTA_SEC_ERA_2)
2590 MATHI(p, DPOVRD, LSHIFT, shift, MATH0, 4, IMMED2);
2591 else
2592 MATHB(p, MATH0, LSHIFT, shift, MATH0, 4, IMMED2);
2593
2594 MATHB(p, MATH0, SHLD, MATH0, MATH0, 8, 0);
2595 MOVE(p, MATH0, 0, DESCBUF, hfn_pdb_offset, 4, IMMED);
2596
2597 if (rta_sec_era >= RTA_SEC_ERA_8)
2598
2599
2600
2601
2602
2603 MATHB(p, DPOVRD, AND, ZERO, DPOVRD, 4, STL);
2604
2605 SET_LABEL(p, keyjump);
2606 PATCH_JUMP(p, pkeyjump, keyjump);
2607 return 0;
2608}
2609
2610
2611
2612
2613static inline enum pdb_type_e
2614cnstr_pdcp_c_plane_pdb(struct program *p,
2615 uint32_t hfn,
2616 enum pdcp_sn_size sn_size,
2617 unsigned char bearer,
2618 unsigned char direction,
2619 uint32_t hfn_threshold,
2620 struct alginfo *cipherdata,
2621 struct alginfo *authdata)
2622{
2623 struct pdcp_pdb pdb;
2624 enum pdb_type_e
2625 pdb_mask[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
2626 {
2627 PDCP_PDB_TYPE_NO_PDB,
2628 PDCP_PDB_TYPE_FULL_PDB,
2629 PDCP_PDB_TYPE_FULL_PDB,
2630 PDCP_PDB_TYPE_FULL_PDB
2631 },
2632 {
2633 PDCP_PDB_TYPE_FULL_PDB,
2634 PDCP_PDB_TYPE_FULL_PDB,
2635 PDCP_PDB_TYPE_REDUCED_PDB,
2636 PDCP_PDB_TYPE_REDUCED_PDB
2637 },
2638 {
2639 PDCP_PDB_TYPE_FULL_PDB,
2640 PDCP_PDB_TYPE_REDUCED_PDB,
2641 PDCP_PDB_TYPE_FULL_PDB,
2642 PDCP_PDB_TYPE_REDUCED_PDB
2643 },
2644 {
2645 PDCP_PDB_TYPE_FULL_PDB,
2646 PDCP_PDB_TYPE_REDUCED_PDB,
2647 PDCP_PDB_TYPE_REDUCED_PDB,
2648 PDCP_PDB_TYPE_FULL_PDB
2649 },
2650 };
2651
2652 if (rta_sec_era >= RTA_SEC_ERA_8) {
2653 memset(&pdb, 0x00, sizeof(struct pdcp_pdb));
2654
2655
2656
2657
2658 if (sn_size == PDCP_SN_SIZE_12) {
2659 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_LONG_SN_HFN_SHIFT;
2660 pdb.bearer_dir_res = (uint32_t)
2661 ((bearer << PDCP_U_PLANE_PDB_BEARER_SHIFT) |
2662 (direction << PDCP_U_PLANE_PDB_DIR_SHIFT));
2663
2664 pdb.hfn_thr_res =
2665 hfn_threshold << PDCP_U_PLANE_PDB_LONG_SN_HFN_THR_SHIFT;
2666
2667 } else {
2668
2669
2670
2671
2672
2673
2674
2675 pdb.opt_res.rsvd = 0x00000002;
2676
2677
2678 pdb.hfn_res = hfn << PDCP_C_PLANE_PDB_HFN_SHIFT;
2679 pdb.bearer_dir_res = (uint32_t)
2680 ((bearer << PDCP_C_PLANE_PDB_BEARER_SHIFT) |
2681 (direction << PDCP_C_PLANE_PDB_DIR_SHIFT));
2682 pdb.hfn_thr_res =
2683 hfn_threshold << PDCP_C_PLANE_PDB_HFN_THR_SHIFT;
2684 }
2685
2686
2687 __rta_out32(p, pdb.opt_res.opt);
2688 __rta_out32(p, pdb.hfn_res);
2689 __rta_out32(p, pdb.bearer_dir_res);
2690 __rta_out32(p, pdb.hfn_thr_res);
2691
2692 return PDCP_PDB_TYPE_FULL_PDB;
2693 }
2694
2695 switch (pdb_mask[cipherdata->algtype][authdata->algtype]) {
2696 case PDCP_PDB_TYPE_NO_PDB:
2697 break;
2698
2699 case PDCP_PDB_TYPE_REDUCED_PDB:
2700 __rta_out32(p, (hfn << PDCP_C_PLANE_PDB_HFN_SHIFT));
2701 __rta_out32(p,
2702 (uint32_t)((bearer <<
2703 PDCP_C_PLANE_PDB_BEARER_SHIFT) |
2704 (direction <<
2705 PDCP_C_PLANE_PDB_DIR_SHIFT)));
2706 break;
2707
2708 case PDCP_PDB_TYPE_FULL_PDB:
2709 memset(&pdb, 0x00, sizeof(struct pdcp_pdb));
2710
2711
2712
2713
2714 pdb.opt_res.rsvd = 0x00000002;
2715
2716
2717 pdb.hfn_res = hfn << PDCP_C_PLANE_PDB_HFN_SHIFT;
2718 pdb.bearer_dir_res = (uint32_t)
2719 ((bearer << PDCP_C_PLANE_PDB_BEARER_SHIFT) |
2720 (direction << PDCP_C_PLANE_PDB_DIR_SHIFT));
2721 pdb.hfn_thr_res =
2722 hfn_threshold << PDCP_C_PLANE_PDB_HFN_THR_SHIFT;
2723
2724
2725 __rta_out32(p, pdb.opt_res.opt);
2726 __rta_out32(p, pdb.hfn_res);
2727 __rta_out32(p, pdb.bearer_dir_res);
2728 __rta_out32(p, pdb.hfn_thr_res);
2729
2730 break;
2731
2732 default:
2733 return PDCP_PDB_TYPE_INVALID;
2734 }
2735
2736 return pdb_mask[cipherdata->algtype][authdata->algtype];
2737}
2738
2739
2740
2741
2742static inline enum pdb_type_e
2743cnstr_pdcp_u_plane_pdb(struct program *p,
2744 enum pdcp_sn_size sn_size,
2745 uint32_t hfn, unsigned short bearer,
2746 unsigned short direction,
2747 uint32_t hfn_threshold,
2748 struct alginfo *cipherdata,
2749 struct alginfo *authdata)
2750{
2751 struct pdcp_pdb pdb;
2752 enum pdb_type_e pdb_type = PDCP_PDB_TYPE_FULL_PDB;
2753 enum pdb_type_e
2754 pdb_mask[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
2755 {
2756 PDCP_PDB_TYPE_NO_PDB,
2757 PDCP_PDB_TYPE_FULL_PDB,
2758 PDCP_PDB_TYPE_FULL_PDB,
2759 PDCP_PDB_TYPE_FULL_PDB
2760 },
2761 {
2762 PDCP_PDB_TYPE_FULL_PDB,
2763 PDCP_PDB_TYPE_FULL_PDB,
2764 PDCP_PDB_TYPE_REDUCED_PDB,
2765 PDCP_PDB_TYPE_REDUCED_PDB
2766 },
2767 {
2768 PDCP_PDB_TYPE_FULL_PDB,
2769 PDCP_PDB_TYPE_REDUCED_PDB,
2770 PDCP_PDB_TYPE_FULL_PDB,
2771 PDCP_PDB_TYPE_REDUCED_PDB
2772 },
2773 {
2774 PDCP_PDB_TYPE_FULL_PDB,
2775 PDCP_PDB_TYPE_REDUCED_PDB,
2776 PDCP_PDB_TYPE_REDUCED_PDB,
2777 PDCP_PDB_TYPE_FULL_PDB
2778 },
2779 };
2780
2781
2782
2783
2784
2785 memset(&pdb, 0x00, sizeof(struct pdcp_pdb));
2786
2787 switch (sn_size) {
2788 case PDCP_SN_SIZE_7:
2789 pdb.opt_res.opt |= PDCP_U_PLANE_PDB_OPT_SHORT_SN;
2790 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_SHORT_SN_HFN_SHIFT;
2791 pdb.hfn_thr_res =
2792 hfn_threshold<<PDCP_U_PLANE_PDB_SHORT_SN_HFN_THR_SHIFT;
2793 break;
2794
2795 case PDCP_SN_SIZE_12:
2796 pdb.opt_res.opt &= (uint32_t)(~PDCP_U_PLANE_PDB_OPT_SHORT_SN);
2797 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_LONG_SN_HFN_SHIFT;
2798 pdb.hfn_thr_res =
2799 hfn_threshold<<PDCP_U_PLANE_PDB_LONG_SN_HFN_THR_SHIFT;
2800 break;
2801
2802 case PDCP_SN_SIZE_15:
2803 pdb.opt_res.opt = (uint32_t)(PDCP_U_PLANE_PDB_OPT_15B_SN);
2804 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_15BIT_SN_HFN_SHIFT;
2805 pdb.hfn_thr_res =
2806 hfn_threshold<<PDCP_U_PLANE_PDB_15BIT_SN_HFN_THR_SHIFT;
2807 break;
2808
2809 case PDCP_SN_SIZE_18:
2810 pdb.opt_res.opt = (uint32_t)(PDCP_U_PLANE_PDB_OPT_18B_SN);
2811 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_18BIT_SN_HFN_SHIFT;
2812 pdb.hfn_thr_res =
2813 hfn_threshold<<PDCP_U_PLANE_PDB_18BIT_SN_HFN_THR_SHIFT;
2814
2815 if (rta_sec_era <= RTA_SEC_ERA_8) {
2816 if (cipherdata && authdata)
2817 pdb_type = pdb_mask[cipherdata->algtype]
2818 [authdata->algtype];
2819 }
2820 break;
2821
2822 default:
2823 pr_err("Invalid Sequence Number Size setting in PDB\n");
2824 return -EINVAL;
2825 }
2826
2827 pdb.bearer_dir_res = (uint32_t)
2828 ((bearer << PDCP_U_PLANE_PDB_BEARER_SHIFT) |
2829 (direction << PDCP_U_PLANE_PDB_DIR_SHIFT));
2830
2831 switch (pdb_type) {
2832 case PDCP_PDB_TYPE_NO_PDB:
2833 break;
2834
2835 case PDCP_PDB_TYPE_REDUCED_PDB:
2836 __rta_out32(p, pdb.hfn_res);
2837 __rta_out32(p, pdb.bearer_dir_res);
2838 break;
2839
2840 case PDCP_PDB_TYPE_FULL_PDB:
2841
2842 __rta_out32(p, pdb.opt_res.opt);
2843 __rta_out32(p, pdb.hfn_res);
2844 __rta_out32(p, pdb.bearer_dir_res);
2845 __rta_out32(p, pdb.hfn_thr_res);
2846
2847 break;
2848
2849 default:
2850 return PDCP_PDB_TYPE_INVALID;
2851 }
2852
2853 return pdb_type;
2854}
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883static inline int
2884cnstr_shdsc_pdcp_c_plane_encap(uint32_t *descbuf,
2885 bool ps,
2886 bool swap,
2887 uint32_t hfn,
2888 enum pdcp_sn_size sn_size,
2889 unsigned char bearer,
2890 unsigned char direction,
2891 uint32_t hfn_threshold,
2892 struct alginfo *cipherdata,
2893 struct alginfo *authdata,
2894 unsigned char era_2_sw_hfn_ovrd)
2895{
2896 static int
2897 (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])
2898 (struct program*, bool swap, struct alginfo *,
2899 struct alginfo *, unsigned int, enum pdcp_sn_size,
2900 unsigned char __maybe_unused) = {
2901 {
2902 pdcp_insert_cplane_null_op,
2903 pdcp_insert_cplane_int_only_op,
2904 pdcp_insert_cplane_int_only_op,
2905 pdcp_insert_cplane_int_only_op
2906 },
2907 {
2908 pdcp_insert_cplane_enc_only_op,
2909 pdcp_insert_cplane_acc_op,
2910 pdcp_insert_cplane_snow_aes_op,
2911 pdcp_insert_cplane_snow_zuc_op
2912 },
2913 {
2914 pdcp_insert_cplane_enc_only_op,
2915 pdcp_insert_cplane_aes_snow_op,
2916 pdcp_insert_cplane_acc_op,
2917 pdcp_insert_cplane_aes_zuc_op
2918 },
2919 {
2920 pdcp_insert_cplane_enc_only_op,
2921 pdcp_insert_cplane_zuc_snow_op,
2922 pdcp_insert_cplane_zuc_aes_op,
2923 pdcp_insert_cplane_acc_op
2924 },
2925 };
2926 static enum rta_share_type
2927 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
2928 {
2929 SHR_WAIT,
2930 SHR_ALWAYS,
2931 SHR_ALWAYS,
2932 SHR_ALWAYS
2933 },
2934 {
2935 SHR_ALWAYS,
2936 SHR_ALWAYS,
2937 SHR_WAIT,
2938 SHR_WAIT
2939 },
2940 {
2941 SHR_ALWAYS,
2942 SHR_ALWAYS,
2943 SHR_ALWAYS,
2944 SHR_WAIT
2945 },
2946 {
2947 SHR_ALWAYS,
2948 SHR_WAIT,
2949 SHR_WAIT,
2950 SHR_ALWAYS
2951 },
2952 };
2953 enum pdb_type_e pdb_type;
2954 struct program prg;
2955 struct program *p = &prg;
2956 int err;
2957 LABEL(pdb_end);
2958
2959 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
2960 pr_err("Cannot select SW HFN override for other era than 2");
2961 return -EINVAL;
2962 }
2963
2964 if (sn_size != PDCP_SN_SIZE_12 && sn_size != PDCP_SN_SIZE_5) {
2965 pr_err("C-plane supports only 5-bit and 12-bit sequence numbers\n");
2966 return -EINVAL;
2967 }
2968
2969 PROGRAM_CNTXT_INIT(p, descbuf, 0);
2970 if (swap)
2971 PROGRAM_SET_BSWAP(p);
2972 if (ps)
2973 PROGRAM_SET_36BIT_ADDR(p);
2974
2975 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
2976
2977 pdb_type = cnstr_pdcp_c_plane_pdb(p,
2978 hfn,
2979 sn_size,
2980 bearer,
2981 direction,
2982 hfn_threshold,
2983 cipherdata,
2984 authdata);
2985
2986 SET_LABEL(p, pdb_end);
2987
2988 err = insert_hfn_ov_op(p, sn_size, pdb_type,
2989 era_2_sw_hfn_ovrd);
2990 if (err)
2991 return err;
2992
2993 err = pdcp_cp_fp[cipherdata->algtype][authdata->algtype](p,
2994 swap,
2995 cipherdata,
2996 authdata,
2997 OP_TYPE_ENCAP_PROTOCOL,
2998 sn_size,
2999 era_2_sw_hfn_ovrd);
3000 if (err)
3001 return err;
3002
3003 PATCH_HDR(p, 0, pdb_end);
3004
3005 return PROGRAM_FINALIZE(p);
3006}
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037static inline int
3038cnstr_shdsc_pdcp_c_plane_decap(uint32_t *descbuf,
3039 bool ps,
3040 bool swap,
3041 uint32_t hfn,
3042 enum pdcp_sn_size sn_size,
3043 unsigned char bearer,
3044 unsigned char direction,
3045 uint32_t hfn_threshold,
3046 struct alginfo *cipherdata,
3047 struct alginfo *authdata,
3048 unsigned char era_2_sw_hfn_ovrd)
3049{
3050 static int
3051 (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])
3052 (struct program*, bool swap, struct alginfo *,
3053 struct alginfo *, unsigned int, enum pdcp_sn_size,
3054 unsigned char) = {
3055 {
3056 pdcp_insert_cplane_null_op,
3057 pdcp_insert_cplane_int_only_op,
3058 pdcp_insert_cplane_int_only_op,
3059 pdcp_insert_cplane_int_only_op
3060 },
3061 {
3062 pdcp_insert_cplane_enc_only_op,
3063 pdcp_insert_cplane_acc_op,
3064 pdcp_insert_cplane_snow_aes_op,
3065 pdcp_insert_cplane_snow_zuc_op
3066 },
3067 {
3068 pdcp_insert_cplane_enc_only_op,
3069 pdcp_insert_cplane_aes_snow_op,
3070 pdcp_insert_cplane_acc_op,
3071 pdcp_insert_cplane_aes_zuc_op
3072 },
3073 {
3074 pdcp_insert_cplane_enc_only_op,
3075 pdcp_insert_cplane_zuc_snow_op,
3076 pdcp_insert_cplane_zuc_aes_op,
3077 pdcp_insert_cplane_acc_op
3078 },
3079 };
3080 static enum rta_share_type
3081 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
3082 {
3083 SHR_WAIT,
3084 SHR_ALWAYS,
3085 SHR_ALWAYS,
3086 SHR_ALWAYS
3087 },
3088 {
3089 SHR_ALWAYS,
3090 SHR_ALWAYS,
3091 SHR_WAIT,
3092 SHR_WAIT
3093 },
3094 {
3095 SHR_ALWAYS,
3096 SHR_ALWAYS,
3097 SHR_ALWAYS,
3098 SHR_WAIT
3099 },
3100 {
3101 SHR_ALWAYS,
3102 SHR_WAIT,
3103 SHR_WAIT,
3104 SHR_ALWAYS
3105 },
3106 };
3107 enum pdb_type_e pdb_type;
3108 struct program prg;
3109 struct program *p = &prg;
3110 int err;
3111 LABEL(pdb_end);
3112
3113 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
3114 pr_err("Cannot select SW HFN override for other era than 2");
3115 return -EINVAL;
3116 }
3117
3118 if (sn_size != PDCP_SN_SIZE_12 && sn_size != PDCP_SN_SIZE_5) {
3119 pr_err("C-plane supports only 5-bit and 12-bit sequence numbers\n");
3120 return -EINVAL;
3121 }
3122
3123 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3124 if (swap)
3125 PROGRAM_SET_BSWAP(p);
3126 if (ps)
3127 PROGRAM_SET_36BIT_ADDR(p);
3128
3129 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
3130
3131 pdb_type = cnstr_pdcp_c_plane_pdb(p,
3132 hfn,
3133 sn_size,
3134 bearer,
3135 direction,
3136 hfn_threshold,
3137 cipherdata,
3138 authdata);
3139
3140 SET_LABEL(p, pdb_end);
3141
3142 err = insert_hfn_ov_op(p, sn_size, pdb_type,
3143 era_2_sw_hfn_ovrd);
3144 if (err)
3145 return err;
3146
3147 err = pdcp_cp_fp[cipherdata->algtype][authdata->algtype](p,
3148 swap,
3149 cipherdata,
3150 authdata,
3151 OP_TYPE_DECAP_PROTOCOL,
3152 sn_size,
3153 era_2_sw_hfn_ovrd);
3154 if (err)
3155 return err;
3156
3157 PATCH_HDR(p, 0, pdb_end);
3158
3159 return PROGRAM_FINALIZE(p);
3160}
3161
3162static int
3163pdcp_insert_uplane_with_int_op(struct program *p,
3164 bool swap __maybe_unused,
3165 struct alginfo *cipherdata,
3166 struct alginfo *authdata,
3167 enum pdcp_sn_size sn_size,
3168 unsigned char era_2_sw_hfn_ovrd,
3169 unsigned int dir)
3170{
3171 static int
3172 (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])
3173 (struct program*, bool swap, struct alginfo *,
3174 struct alginfo *, unsigned int, enum pdcp_sn_size,
3175 unsigned char __maybe_unused) = {
3176 {
3177 pdcp_insert_cplane_null_op,
3178 pdcp_insert_cplane_int_only_op,
3179 pdcp_insert_cplane_int_only_op,
3180 pdcp_insert_cplane_int_only_op
3181 },
3182 {
3183 pdcp_insert_cplane_enc_only_op,
3184 pdcp_insert_uplane_snow_snow_op,
3185 pdcp_insert_cplane_snow_aes_op,
3186 pdcp_insert_cplane_snow_zuc_op
3187 },
3188 {
3189 pdcp_insert_cplane_enc_only_op,
3190 pdcp_insert_cplane_aes_snow_op,
3191 pdcp_insert_uplane_aes_aes_op,
3192 pdcp_insert_cplane_aes_zuc_op
3193 },
3194 {
3195 pdcp_insert_cplane_enc_only_op,
3196 pdcp_insert_cplane_zuc_snow_op,
3197 pdcp_insert_cplane_zuc_aes_op,
3198 pdcp_insert_uplane_zuc_zuc_op
3199 },
3200 };
3201 int err;
3202
3203 err = pdcp_cp_fp[cipherdata->algtype][authdata->algtype](p,
3204 swap,
3205 cipherdata,
3206 authdata,
3207 dir,
3208 sn_size,
3209 era_2_sw_hfn_ovrd);
3210 if (err)
3211 return err;
3212
3213 return 0;
3214}
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244static inline int
3245cnstr_shdsc_pdcp_u_plane_encap(uint32_t *descbuf,
3246 bool ps,
3247 bool swap,
3248 enum pdcp_sn_size sn_size,
3249 uint32_t hfn,
3250 unsigned short bearer,
3251 unsigned short direction,
3252 uint32_t hfn_threshold,
3253 struct alginfo *cipherdata,
3254 struct alginfo *authdata,
3255 unsigned char era_2_sw_hfn_ovrd)
3256{
3257 struct program prg;
3258 struct program *p = &prg;
3259 int err;
3260 enum pdb_type_e pdb_type;
3261 static enum rta_share_type
3262 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
3263 {
3264 SHR_WAIT,
3265 SHR_ALWAYS,
3266 SHR_ALWAYS,
3267 SHR_ALWAYS
3268 },
3269 {
3270 SHR_ALWAYS,
3271 SHR_ALWAYS,
3272 SHR_WAIT,
3273 SHR_WAIT
3274 },
3275 {
3276 SHR_ALWAYS,
3277 SHR_ALWAYS,
3278 SHR_ALWAYS,
3279 SHR_WAIT
3280 },
3281 {
3282 SHR_ALWAYS,
3283 SHR_WAIT,
3284 SHR_WAIT,
3285 SHR_ALWAYS
3286 },
3287 };
3288 LABEL(pdb_end);
3289
3290 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
3291 pr_err("Cannot select SW HFN ovrd for other era than 2");
3292 return -EINVAL;
3293 }
3294
3295 if (authdata && !authdata->algtype && rta_sec_era < RTA_SEC_ERA_8) {
3296 pr_err("Cannot use u-plane auth with era < 8");
3297 return -EINVAL;
3298 }
3299
3300 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3301 if (swap)
3302 PROGRAM_SET_BSWAP(p);
3303 if (ps)
3304 PROGRAM_SET_36BIT_ADDR(p);
3305
3306 if (authdata)
3307 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
3308 else
3309 SHR_HDR(p, SHR_ALWAYS, 0, 0);
3310 pdb_type = cnstr_pdcp_u_plane_pdb(p, sn_size, hfn,
3311 bearer, direction, hfn_threshold,
3312 cipherdata, authdata);
3313 if (pdb_type == PDCP_PDB_TYPE_INVALID) {
3314 pr_err("Error creating PDCP UPlane PDB\n");
3315 return -EINVAL;
3316 }
3317 SET_LABEL(p, pdb_end);
3318
3319 err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd);
3320 if (err)
3321 return err;
3322
3323 switch (sn_size) {
3324 case PDCP_SN_SIZE_7:
3325 case PDCP_SN_SIZE_12:
3326 switch (cipherdata->algtype) {
3327 case PDCP_CIPHER_TYPE_ZUC:
3328 if (rta_sec_era < RTA_SEC_ERA_5) {
3329 pr_err("Invalid era for selected algorithm\n");
3330 return -ENOTSUP;
3331 }
3332
3333 case PDCP_CIPHER_TYPE_AES:
3334 case PDCP_CIPHER_TYPE_SNOW:
3335 case PDCP_CIPHER_TYPE_NULL:
3336 if (rta_sec_era == RTA_SEC_ERA_8 &&
3337 authdata && authdata->algtype == 0){
3338 err = pdcp_insert_uplane_with_int_op(p, swap,
3339 cipherdata, authdata,
3340 sn_size, era_2_sw_hfn_ovrd,
3341 OP_TYPE_ENCAP_PROTOCOL);
3342 if (err)
3343 return err;
3344 break;
3345 }
3346
3347 if (pdb_type != PDCP_PDB_TYPE_FULL_PDB) {
3348 pr_err("PDB type must be FULL for PROTO desc\n");
3349 return -EINVAL;
3350 }
3351
3352
3353 if (authdata && authdata->algtype) {
3354 KEY(p, KEY2, authdata->key_enc_flags,
3355 (uint64_t)authdata->key, authdata->keylen,
3356 INLINE_KEY(authdata));
3357 }
3358
3359 KEY(p, KEY1, cipherdata->key_enc_flags,
3360 (uint64_t)cipherdata->key, cipherdata->keylen,
3361 INLINE_KEY(cipherdata));
3362
3363 if (authdata)
3364 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
3365 OP_PCLID_LTE_PDCP_USER_RN,
3366 ((uint16_t)cipherdata->algtype << 8) |
3367 (uint16_t)authdata->algtype);
3368 else
3369 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
3370 OP_PCLID_LTE_PDCP_USER,
3371 (uint16_t)cipherdata->algtype);
3372 break;
3373 default:
3374 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
3375 "cnstr_pcl_shdsc_pdcp_u_plane_decap",
3376 cipherdata->algtype);
3377 return -EINVAL;
3378 }
3379 break;
3380
3381 case PDCP_SN_SIZE_15:
3382 case PDCP_SN_SIZE_18:
3383 if (authdata) {
3384 err = pdcp_insert_uplane_with_int_op(p, swap,
3385 cipherdata, authdata,
3386 sn_size, era_2_sw_hfn_ovrd,
3387 OP_TYPE_ENCAP_PROTOCOL);
3388 if (err)
3389 return err;
3390
3391 break;
3392 }
3393
3394 switch (cipherdata->algtype) {
3395 case PDCP_CIPHER_TYPE_NULL:
3396 insert_copy_frame_op(p,
3397 cipherdata,
3398 OP_TYPE_ENCAP_PROTOCOL);
3399 break;
3400
3401 default:
3402 err = pdcp_insert_uplane_no_int_op(p, swap, cipherdata,
3403 OP_TYPE_ENCAP_PROTOCOL, sn_size);
3404 if (err)
3405 return err;
3406 break;
3407 }
3408 break;
3409
3410 case PDCP_SN_SIZE_5:
3411 default:
3412 pr_err("Invalid SN size selected\n");
3413 return -ENOTSUP;
3414 }
3415
3416 PATCH_HDR(p, 0, pdb_end);
3417 return PROGRAM_FINALIZE(p);
3418}
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447static inline int
3448cnstr_shdsc_pdcp_u_plane_decap(uint32_t *descbuf,
3449 bool ps,
3450 bool swap,
3451 enum pdcp_sn_size sn_size,
3452 uint32_t hfn,
3453 unsigned short bearer,
3454 unsigned short direction,
3455 uint32_t hfn_threshold,
3456 struct alginfo *cipherdata,
3457 struct alginfo *authdata,
3458 unsigned char era_2_sw_hfn_ovrd)
3459{
3460 struct program prg;
3461 struct program *p = &prg;
3462 int err;
3463 enum pdb_type_e pdb_type;
3464 static enum rta_share_type
3465 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
3466 {
3467 SHR_WAIT,
3468 SHR_ALWAYS,
3469 SHR_ALWAYS,
3470 SHR_ALWAYS
3471 },
3472 {
3473 SHR_ALWAYS,
3474 SHR_ALWAYS,
3475 SHR_WAIT,
3476 SHR_WAIT
3477 },
3478 {
3479 SHR_ALWAYS,
3480 SHR_ALWAYS,
3481 SHR_ALWAYS,
3482 SHR_WAIT
3483 },
3484 {
3485 SHR_ALWAYS,
3486 SHR_WAIT,
3487 SHR_WAIT,
3488 SHR_ALWAYS
3489 },
3490 };
3491
3492 LABEL(pdb_end);
3493
3494 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
3495 pr_err("Cannot select SW HFN override for other era than 2");
3496 return -EINVAL;
3497 }
3498
3499 if (authdata && !authdata->algtype && rta_sec_era < RTA_SEC_ERA_8) {
3500 pr_err("Cannot use u-plane auth with era < 8");
3501 return -EINVAL;
3502 }
3503
3504 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3505 if (swap)
3506 PROGRAM_SET_BSWAP(p);
3507 if (ps)
3508 PROGRAM_SET_36BIT_ADDR(p);
3509 if (authdata)
3510 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
3511 else
3512 SHR_HDR(p, SHR_ALWAYS, 0, 0);
3513
3514 pdb_type = cnstr_pdcp_u_plane_pdb(p, sn_size, hfn, bearer,
3515 direction, hfn_threshold,
3516 cipherdata, authdata);
3517 if (pdb_type == PDCP_PDB_TYPE_INVALID) {
3518 pr_err("Error creating PDCP UPlane PDB\n");
3519 return -EINVAL;
3520 }
3521 SET_LABEL(p, pdb_end);
3522
3523 err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd);
3524 if (err)
3525 return err;
3526
3527 switch (sn_size) {
3528 case PDCP_SN_SIZE_7:
3529 case PDCP_SN_SIZE_12:
3530 switch (cipherdata->algtype) {
3531 case PDCP_CIPHER_TYPE_ZUC:
3532 if (rta_sec_era < RTA_SEC_ERA_5) {
3533 pr_err("Invalid era for selected algorithm\n");
3534 return -ENOTSUP;
3535 }
3536
3537 case PDCP_CIPHER_TYPE_AES:
3538 case PDCP_CIPHER_TYPE_SNOW:
3539 case PDCP_CIPHER_TYPE_NULL:
3540 if (pdb_type != PDCP_PDB_TYPE_FULL_PDB) {
3541 pr_err("PDB type must be FULL for PROTO desc\n");
3542 return -EINVAL;
3543 }
3544
3545
3546 if (authdata && authdata->algtype)
3547 KEY(p, KEY2, authdata->key_enc_flags,
3548 (uint64_t)authdata->key, authdata->keylen,
3549 INLINE_KEY(authdata));
3550 else if (authdata && authdata->algtype == 0) {
3551 err = pdcp_insert_uplane_with_int_op(p, swap,
3552 cipherdata, authdata,
3553 sn_size, era_2_sw_hfn_ovrd,
3554 OP_TYPE_DECAP_PROTOCOL);
3555 if (err)
3556 return err;
3557 break;
3558 }
3559
3560
3561 KEY(p, KEY1, cipherdata->key_enc_flags,
3562 cipherdata->key, cipherdata->keylen,
3563 INLINE_KEY(cipherdata));
3564 if (authdata)
3565 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
3566 OP_PCLID_LTE_PDCP_USER_RN,
3567 ((uint16_t)cipherdata->algtype << 8) |
3568 (uint16_t)authdata->algtype);
3569 else
3570 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
3571 OP_PCLID_LTE_PDCP_USER,
3572 (uint16_t)cipherdata->algtype);
3573 break;
3574 default:
3575 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
3576 "cnstr_pcl_shdsc_pdcp_u_plane_decap",
3577 cipherdata->algtype);
3578 return -EINVAL;
3579 }
3580 break;
3581
3582 case PDCP_SN_SIZE_15:
3583 case PDCP_SN_SIZE_18:
3584 if (authdata) {
3585 err = pdcp_insert_uplane_with_int_op(p, swap,
3586 cipherdata, authdata,
3587 sn_size, era_2_sw_hfn_ovrd,
3588 OP_TYPE_DECAP_PROTOCOL);
3589 if (err)
3590 return err;
3591
3592 break;
3593 }
3594
3595 switch (cipherdata->algtype) {
3596 case PDCP_CIPHER_TYPE_NULL:
3597 insert_copy_frame_op(p,
3598 cipherdata,
3599 OP_TYPE_DECAP_PROTOCOL);
3600 break;
3601
3602 default:
3603 err = pdcp_insert_uplane_no_int_op(p, swap, cipherdata,
3604 OP_TYPE_DECAP_PROTOCOL, sn_size);
3605 if (err)
3606 return err;
3607 break;
3608 }
3609 break;
3610
3611 case PDCP_SN_SIZE_5:
3612 default:
3613 pr_err("Invalid SN size selected\n");
3614 return -ENOTSUP;
3615 }
3616
3617 PATCH_HDR(p, 0, pdb_end);
3618 return PROGRAM_FINALIZE(p);
3619}
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638static inline int
3639cnstr_shdsc_pdcp_short_mac(uint32_t *descbuf,
3640 bool ps,
3641 bool swap,
3642 struct alginfo *authdata)
3643{
3644 struct program prg;
3645 struct program *p = &prg;
3646 uint32_t iv[3] = {0, 0, 0};
3647 LABEL(local_offset);
3648 REFERENCE(move_cmd_read_descbuf);
3649 REFERENCE(move_cmd_write_descbuf);
3650
3651 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3652 if (swap)
3653 PROGRAM_SET_BSWAP(p);
3654 if (ps)
3655 PROGRAM_SET_36BIT_ADDR(p);
3656
3657 SHR_HDR(p, SHR_ALWAYS, 1, 0);
3658
3659 if (rta_sec_era > RTA_SEC_ERA_2) {
3660 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
3661 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4, 0);
3662 } else {
3663 MATHB(p, SEQINSZ, ADD, ONE, MATH1, 4, 0);
3664 MATHB(p, MATH1, SUB, ONE, MATH1, 4, 0);
3665 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
3666 MOVE(p, MATH1, 0, MATH0, 0, 8, IMMED);
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH0, 0, 6,
3680 IMMED);
3681 move_cmd_write_descbuf = MOVE(p, MATH0, 0, DESCBUF, 0, 8,
3682 WAITCOMP | IMMED);
3683 }
3684 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
3685
3686 switch (authdata->algtype) {
3687 case PDCP_AUTH_TYPE_NULL:
3688 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3689 if (rta_sec_era > RTA_SEC_ERA_2) {
3690 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
3691 } else {
3692 SET_LABEL(p, local_offset);
3693
3694
3695 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
3696
3697
3698
3699
3700 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
3701
3702
3703 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
3704 }
3705
3706 LOAD(p, (uintptr_t)iv, MATH0, 0, 8, IMMED | COPY);
3707 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | LAST2 | FLUSH1);
3708 SEQSTORE(p, MATH0, 0, 4, 0);
3709
3710 break;
3711
3712 case PDCP_AUTH_TYPE_SNOW:
3713 iv[0] = 0xFFFFFFFF;
3714 iv[1] = swap ? swab32(0x04000000) : 0x04000000;
3715 iv[2] = swap ? swab32(0xF8000000) : 0xF8000000;
3716
3717 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
3718 authdata->keylen, INLINE_KEY(authdata));
3719 LOAD(p, (uintptr_t)&iv, CONTEXT2, 0, 12, IMMED | COPY);
3720 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
3721 OP_ALG_AAI_F9,
3722 OP_ALG_AS_INITFINAL,
3723 ICV_CHECK_DISABLE,
3724 DIR_ENC);
3725 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3726
3727 if (rta_sec_era > RTA_SEC_ERA_2) {
3728 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
3729 } else {
3730 SET_LABEL(p, local_offset);
3731
3732
3733
3734 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
3735
3736
3737
3738
3739 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
3740
3741
3742 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
3743 }
3744 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
3745 SEQSTORE(p, CONTEXT2, 0, 4, 0);
3746
3747 break;
3748
3749 case PDCP_AUTH_TYPE_AES:
3750 iv[0] = 0xFFFFFFFF;
3751 iv[1] = swap ? swab32(0xFC000000) : 0xFC000000;
3752 iv[2] = 0x00000000;
3753
3754 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
3755 authdata->keylen, INLINE_KEY(authdata));
3756 LOAD(p, (uintptr_t)&iv, MATH0, 0, 8, IMMED | COPY);
3757 MOVE(p, MATH0, 0, IFIFOAB1, 0, 8, IMMED);
3758 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
3759 OP_ALG_AAI_CMAC,
3760 OP_ALG_AS_INITFINAL,
3761 ICV_CHECK_DISABLE,
3762 DIR_ENC);
3763 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3764
3765 if (rta_sec_era > RTA_SEC_ERA_2) {
3766 MOVE(p, AB2, 0, OFIFO, 0, MATH1, 0);
3767 } else {
3768 SET_LABEL(p, local_offset);
3769
3770
3771 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
3772
3773
3774
3775
3776 MOVE(p, IFIFOAB2, 0, OFIFO, 0, 0, IMMED);
3777
3778
3779 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
3780 }
3781 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
3782 SEQSTORE(p, CONTEXT1, 0, 4, 0);
3783
3784 break;
3785
3786 case PDCP_AUTH_TYPE_ZUC:
3787 if (rta_sec_era < RTA_SEC_ERA_5) {
3788 pr_err("Invalid era for selected algorithm\n");
3789 return -ENOTSUP;
3790 }
3791 iv[0] = 0xFFFFFFFF;
3792 iv[1] = swap ? swab32(0xFC000000) : 0xFC000000;
3793 iv[2] = 0x00000000;
3794
3795 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
3796 authdata->keylen, INLINE_KEY(authdata));
3797 LOAD(p, (uintptr_t)&iv, CONTEXT2, 0, 12, IMMED | COPY);
3798 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
3799 OP_ALG_AAI_F9,
3800 OP_ALG_AS_INITFINAL,
3801 ICV_CHECK_DISABLE,
3802 DIR_ENC);
3803 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3804 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
3805 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
3806 SEQSTORE(p, CONTEXT2, 0, 4, 0);
3807
3808 break;
3809
3810 default:
3811 pr_err("%s: Invalid integrity algorithm selected: %d\n",
3812 "cnstr_shdsc_pdcp_short_mac", authdata->algtype);
3813 return -EINVAL;
3814 }
3815
3816
3817 if (rta_sec_era < RTA_SEC_ERA_3) {
3818 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
3819 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
3820 }
3821
3822 return PROGRAM_FINALIZE(p);
3823}
3824
3825#endif
3826