xref: /dpdk/lib/pdcp/pdcp_entity.h (revision e9fd1ebf981f361844aea9ec94e17f4bda5e1479)
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 *
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 *
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 *
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
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
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
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
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
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
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
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
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