1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2023 Marvell.
3 */
4
5 #ifndef PDCP_ENTITY_H
6 #define PDCP_ENTITY_H
7
8 #include <rte_common.h>
9 #include <rte_crypto_sym.h>
10 #include <rte_mempool.h>
11 #include <rte_pdcp.h>
12 #include <rte_security.h>
13
14 #include "pdcp_reorder.h"
15
16 struct entity_priv;
17
18 #define PDCP_HFN_MIN 0
19
20 /* IV generation function based on the entity configuration */
21 typedef void (*iv_gen_t)(struct rte_crypto_op *cop, const struct entity_priv *en_priv,
22 uint32_t count);
23
24 struct entity_state {
25 uint32_t rx_next;
26 uint32_t tx_next;
27 uint32_t rx_deliv;
28 uint32_t rx_reord;
29 };
30
31 union auth_iv_partial {
32 /* For AES-CMAC, there is no IV, but message gets prepended */
33 struct {
34 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
35 uint64_t count : 32;
36 uint64_t zero_38_39 : 2;
37 uint64_t direction : 1;
38 uint64_t bearer : 5;
39 uint64_t zero_40_63 : 24;
40 #else
41 uint64_t count : 32;
42 uint64_t bearer : 5;
43 uint64_t direction : 1;
44 uint64_t zero_38_39 : 2;
45 uint64_t zero_40_63 : 24;
46 #endif
47 } aes_cmac;
48 struct {
49 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
50 uint64_t count : 32;
51 uint64_t zero_37_39 : 3;
52 uint64_t bearer : 5;
53 uint64_t zero_40_63 : 24;
54
55 uint64_t rsvd_65_71 : 7;
56 uint64_t direction_64 : 1;
57 uint64_t rsvd_72_111 : 40;
58 uint64_t rsvd_113_119 : 7;
59 uint64_t direction_112 : 1;
60 uint64_t rsvd_120_127 : 8;
61 #else
62 uint64_t count : 32;
63 uint64_t bearer : 5;
64 uint64_t zero_37_39 : 3;
65 uint64_t zero_40_63 : 24;
66
67 uint64_t direction_64 : 1;
68 uint64_t rsvd_65_71 : 7;
69 uint64_t rsvd_72_111 : 40;
70 uint64_t direction_112 : 1;
71 uint64_t rsvd_113_119 : 7;
72 uint64_t rsvd_120_127 : 8;
73 #endif
74 } zs;
75 uint64_t u64[2];
76 };
77
78 union cipher_iv_partial {
79 struct {
80 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
81 uint64_t count : 32;
82 uint64_t zero_38_39 : 2;
83 uint64_t direction : 1;
84 uint64_t bearer : 5;
85 uint64_t zero_40_63 : 24;
86 #else
87 uint64_t count : 32;
88 uint64_t bearer : 5;
89 uint64_t direction : 1;
90 uint64_t zero_38_39 : 2;
91 uint64_t zero_40_63 : 24;
92 #endif
93 uint64_t zero_64_127;
94 } aes_ctr;
95 struct {
96 #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
97 uint64_t count : 32;
98 uint64_t zero_38_39 : 2;
99 uint64_t direction : 1;
100 uint64_t bearer : 5;
101 uint64_t zero_40_63 : 24;
102 #else
103 uint64_t count : 32;
104 uint64_t bearer : 5;
105 uint64_t direction : 1;
106 uint64_t zero_38_39 : 2;
107 uint64_t zero_40_63 : 24;
108 #endif
109 uint64_t rsvd_64_127;
110 } zs;
111 uint64_t u64[2];
112 };
113
114 enum timer_state {
115 TIMER_STOP,
116 TIMER_RUNNING,
117 TIMER_EXPIRED,
118 };
119
120 struct pdcp_t_reordering {
121 /** Represent timer state */
122 enum timer_state state;
123 /** User defined callback handles */
124 struct rte_pdcp_t_reordering handle;
125 };
126
127 struct pdcp_cnt_bitmap {
128 /** Number of entries that can be stored. */
129 uint32_t size;
130 /** Bitmap of the count values already received.*/
131 struct rte_bitmap *bmp;
132 };
133
134 /*
135 * Layout of PDCP entity: [rte_pdcp_entity] [entity_priv] [entity_dl/ul] [reorder/bitmap]
136 */
137
138 struct entity_priv {
139 /** Crypto sym session. */
140 struct rte_cryptodev_sym_session *crypto_sess;
141 /** Entity specific IV generation function. */
142 iv_gen_t iv_gen;
143 /** Pre-prepared auth IV. */
144 union auth_iv_partial auth_iv_part;
145 /** Pre-prepared cipher IV. */
146 union cipher_iv_partial cipher_iv_part;
147 /** Entity state variables. */
148 struct entity_state state;
149 /** Flags. */
150 struct {
151 /** PDCP PDU has 4 byte MAC-I. */
152 uint64_t is_authenticated : 1;
153 /** Cipher offset & length in bits. */
154 uint64_t is_cipher_in_bits : 1;
155 /** Auth offset & length in bits. */
156 uint64_t is_auth_in_bits : 1;
157 /** Is UL/transmitting PDCP entity. */
158 uint64_t is_ul_entity : 1;
159 /** Is NULL auth. */
160 uint64_t is_null_auth : 1;
161 /** Is status report required.*/
162 uint64_t is_status_report_required : 1;
163 /** Is out-of-order delivery enabled */
164 uint64_t is_out_of_order_delivery : 1;
165 } flags;
166 /** Crypto op pool. */
167 struct rte_mempool *cop_pool;
168 /** Control PDU pool. */
169 struct rte_mempool *ctrl_pdu_pool;
170 /** PDCP header size. */
171 uint8_t hdr_sz;
172 /** PDCP AAD size. For AES-CMAC, additional message is prepended for the operation. */
173 uint8_t aad_sz;
174 /** PDCP cipher skip size. When enabled, SDAP header needs to be skipped from ciphering */
175 uint8_t cipher_skip_sz;
176 /** Device ID of the device to be used for offload. */
177 uint8_t dev_id;
178 };
179
180 struct entity_priv_dl_part {
181 /** PDCP would need to track the count values that are already received.*/
182 struct pdcp_cnt_bitmap bitmap;
183 /** t-Reordering handles */
184 struct pdcp_t_reordering t_reorder;
185 /** Reorder packet buffer */
186 struct pdcp_reorder reorder;
187 /** Bitmap memory region */
188 uint8_t bitmap_mem[];
189 };
190
191 struct entity_priv_ul_part {
192 /*
193 * NOTE: when re-establish is supported, plain PDCP packets & COUNT values need to be
194 * cached.
195 */
196 uint8_t dummy;
197 };
198
199 static inline struct entity_priv *
entity_priv_get(const struct rte_pdcp_entity * entity)200 entity_priv_get(const struct rte_pdcp_entity *entity) {
201 return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity));
202 }
203
204 static inline struct entity_priv_dl_part *
entity_dl_part_get(const struct rte_pdcp_entity * entity)205 entity_dl_part_get(const struct rte_pdcp_entity *entity) {
206 return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) + sizeof(struct entity_priv));
207 }
208
209 static inline struct entity_priv_ul_part *
entity_ul_part_get(const struct rte_pdcp_entity * entity)210 entity_ul_part_get(const struct rte_pdcp_entity *entity) {
211 return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) + sizeof(struct entity_priv));
212 }
213
214 static inline int
pdcp_hdr_size_get(enum rte_security_pdcp_sn_size sn_size)215 pdcp_hdr_size_get(enum rte_security_pdcp_sn_size sn_size)
216 {
217 return RTE_ALIGN_MUL_CEIL(sn_size, 8) / 8;
218 }
219
220 static inline uint32_t
pdcp_window_size_get(enum rte_security_pdcp_sn_size sn_size)221 pdcp_window_size_get(enum rte_security_pdcp_sn_size sn_size)
222 {
223 return 1 << (sn_size - 1);
224 }
225
226 static inline uint32_t
pdcp_sn_mask_get(enum rte_security_pdcp_sn_size sn_size)227 pdcp_sn_mask_get(enum rte_security_pdcp_sn_size sn_size)
228 {
229 return (1 << sn_size) - 1;
230 }
231
232 static inline uint32_t
pdcp_sn_from_count_get(uint32_t count,enum rte_security_pdcp_sn_size sn_size)233 pdcp_sn_from_count_get(uint32_t count, enum rte_security_pdcp_sn_size sn_size)
234 {
235 return (count & pdcp_sn_mask_get(sn_size));
236 }
237
238 static inline uint32_t
pdcp_hfn_mask_get(enum rte_security_pdcp_sn_size sn_size)239 pdcp_hfn_mask_get(enum rte_security_pdcp_sn_size sn_size)
240 {
241 return ~pdcp_sn_mask_get(sn_size);
242 }
243
244 static inline uint32_t
pdcp_hfn_from_count_get(uint32_t count,enum rte_security_pdcp_sn_size sn_size)245 pdcp_hfn_from_count_get(uint32_t count, enum rte_security_pdcp_sn_size sn_size)
246 {
247 return (count & pdcp_hfn_mask_get(sn_size)) >> sn_size;
248 }
249
250 static inline uint32_t
pdcp_count_from_hfn_sn_get(uint32_t hfn,uint32_t sn,enum rte_security_pdcp_sn_size sn_size)251 pdcp_count_from_hfn_sn_get(uint32_t hfn, uint32_t sn, enum rte_security_pdcp_sn_size sn_size)
252 {
253 return (((hfn << sn_size) & pdcp_hfn_mask_get(sn_size)) | (sn & pdcp_sn_mask_get(sn_size)));
254 }
255
256 static inline uint32_t
pdcp_hfn_max(enum rte_security_pdcp_sn_size sn_size)257 pdcp_hfn_max(enum rte_security_pdcp_sn_size sn_size)
258 {
259 return (1 << (32 - sn_size)) - 1;
260 }
261
262 #endif /* PDCP_ENTITY_H */
263