Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 Intel Corporation
3 : : */
4 : :
5 : : #ifndef _CRYPTO_H_
6 : : #define _CRYPTO_H_
7 : :
8 : : /**
9 : : * @file crypto.h
10 : : * Contains crypto specific functions/structures/macros used internally
11 : : * by ipsec library.
12 : : */
13 : :
14 : : /*
15 : : * AES-CTR counter block format.
16 : : */
17 : :
18 : : struct __rte_packed_begin aesctr_cnt_blk {
19 : : uint32_t nonce;
20 : : uint64_t iv;
21 : : uint32_t cnt;
22 : : } __rte_packed_end;
23 : :
24 : : /*
25 : : * CHACHA20-POLY1305 devices have some specific requirements
26 : : * for IV and AAD formats.
27 : : * Ideally that to be done by the driver itself.
28 : : */
29 : :
30 : : struct __rte_packed_begin aead_chacha20_poly1305_iv {
31 : : uint32_t salt;
32 : : uint64_t iv;
33 : : uint32_t cnt;
34 : : } __rte_packed_end;
35 : :
36 : : struct __rte_packed_begin aead_chacha20_poly1305_aad {
37 : : uint32_t spi;
38 : : /*
39 : : * RFC 4106, section 5:
40 : : * Two formats of the AAD are defined:
41 : : * one for 32-bit sequence numbers, and one for 64-bit ESN.
42 : : */
43 : : union {
44 : : uint32_t u32[2];
45 : : uint64_t u64;
46 : : } sqn;
47 : : uint32_t align0; /* align to 16B boundary */
48 : : } __rte_packed_end;
49 : :
50 : : struct __rte_packed_begin chacha20_poly1305_esph_iv {
51 : : struct rte_esp_hdr esph;
52 : : uint64_t iv;
53 : : } __rte_packed_end;
54 : :
55 : : /*
56 : : * AES-GCM devices have some specific requirements for IV and AAD formats.
57 : : * Ideally that to be done by the driver itself.
58 : : */
59 : :
60 : : struct __rte_packed_begin aead_gcm_iv {
61 : : uint32_t salt;
62 : : uint64_t iv;
63 : : uint32_t cnt;
64 : : } __rte_packed_end;
65 : :
66 : : struct __rte_packed_begin aead_gcm_aad {
67 : : uint32_t spi;
68 : : /*
69 : : * RFC 4106, section 5:
70 : : * Two formats of the AAD are defined:
71 : : * one for 32-bit sequence numbers, and one for 64-bit ESN.
72 : : */
73 : : union {
74 : : uint32_t u32[2];
75 : : uint64_t u64;
76 : : } sqn;
77 : : uint32_t align0; /* align to 16B boundary */
78 : : } __rte_packed_end;
79 : :
80 : : struct __rte_packed_begin gcm_esph_iv {
81 : : struct rte_esp_hdr esph;
82 : : uint64_t iv;
83 : : } __rte_packed_end;
84 : :
85 : : /*
86 : : * AES-CCM devices have some specific requirements for IV and AAD formats.
87 : : * Ideally that to be done by the driver itself.
88 : : */
89 : : union __rte_packed_begin aead_ccm_salt {
90 : : uint32_t salt;
91 : : struct inner {
92 : : uint8_t salt8[3];
93 : : uint8_t ccm_flags;
94 : : } inner;
95 : : } __rte_packed_end;
96 : :
97 : :
98 : : struct __rte_packed_begin aead_ccm_iv {
99 : : uint8_t ccm_flags;
100 : : uint8_t salt[3];
101 : : uint64_t iv;
102 : : uint32_t cnt;
103 : : } __rte_packed_end;
104 : :
105 : : struct __rte_packed_begin aead_ccm_aad {
106 : : uint8_t padding[18];
107 : : uint32_t spi;
108 : : /*
109 : : * RFC 4309, section 5:
110 : : * Two formats of the AAD are defined:
111 : : * one for 32-bit sequence numbers, and one for 64-bit ESN.
112 : : */
113 : : union {
114 : : uint32_t u32[2];
115 : : uint64_t u64;
116 : : } sqn;
117 : : uint32_t align0; /* align to 16B boundary */
118 : : } __rte_packed_end;
119 : :
120 : : struct __rte_packed_begin ccm_esph_iv {
121 : : struct rte_esp_hdr esph;
122 : : uint64_t iv;
123 : : } __rte_packed_end;
124 : :
125 : :
126 : : static inline void
127 : : aes_ctr_cnt_blk_fill(struct aesctr_cnt_blk *ctr, uint64_t iv, uint32_t nonce)
128 : : {
129 : 0 : ctr->nonce = nonce;
130 : 0 : ctr->iv = iv;
131 : 0 : ctr->cnt = rte_cpu_to_be_32(1);
132 : 0 : }
133 : :
134 : : static inline void
135 : : aead_chacha20_poly1305_iv_fill(struct aead_chacha20_poly1305_iv
136 : : *chacha20_poly1305,
137 : : uint64_t iv, uint32_t salt)
138 : : {
139 : 0 : chacha20_poly1305->salt = salt;
140 : 0 : chacha20_poly1305->iv = iv;
141 : 0 : chacha20_poly1305->cnt = rte_cpu_to_be_32(1);
142 : 0 : }
143 : :
144 : : static inline void
145 : : aead_gcm_iv_fill(struct aead_gcm_iv *gcm, uint64_t iv, uint32_t salt)
146 : : {
147 : 0 : gcm->salt = salt;
148 : 0 : gcm->iv = iv;
149 : 0 : gcm->cnt = rte_cpu_to_be_32(1);
150 : 0 : }
151 : :
152 : : static inline void
153 : : aead_ccm_iv_fill(struct aead_ccm_iv *ccm, uint64_t iv, uint32_t salt)
154 : : {
155 : : union aead_ccm_salt tsalt;
156 : :
157 : : tsalt.salt = salt;
158 : 0 : ccm->ccm_flags = tsalt.inner.ccm_flags;
159 : 0 : ccm->salt[0] = tsalt.inner.salt8[0];
160 : 0 : ccm->salt[1] = tsalt.inner.salt8[1];
161 : 0 : ccm->salt[2] = tsalt.inner.salt8[2];
162 : 0 : ccm->iv = iv;
163 : 0 : ccm->cnt = rte_cpu_to_be_32(1);
164 : 0 : }
165 : :
166 : :
167 : : /*
168 : : * RFC 4106, 5 AAD Construction
169 : : * spi and sqn should already be converted into network byte order.
170 : : * Make sure that not used bytes are zeroed.
171 : : */
172 : : static inline void
173 : : aead_gcm_aad_fill(struct aead_gcm_aad *aad, rte_be32_t spi, rte_be64_t sqn,
174 : : int esn)
175 : : {
176 : 0 : aad->spi = spi;
177 [ # # ]: 0 : if (esn)
178 : 0 : aad->sqn.u64 = sqn;
179 : : else {
180 : 0 : aad->sqn.u32[0] = sqn_low32(sqn);
181 : 0 : aad->sqn.u32[1] = 0;
182 : : }
183 : 0 : aad->align0 = 0;
184 : 0 : }
185 : :
186 : : /*
187 : : * RFC 4309, 5 AAD Construction
188 : : * spi and sqn should already be converted into network byte order.
189 : : * Make sure that not used bytes are zeroed.
190 : : */
191 : : static inline void
192 : : aead_ccm_aad_fill(struct aead_ccm_aad *aad, rte_be32_t spi, rte_be64_t sqn,
193 : : int esn)
194 : : {
195 : 0 : aad->spi = spi;
196 [ # # ]: 0 : if (esn)
197 : 0 : aad->sqn.u64 = sqn;
198 : : else {
199 : 0 : aad->sqn.u32[0] = sqn_low32(sqn);
200 : 0 : aad->sqn.u32[1] = 0;
201 : : }
202 : 0 : aad->align0 = 0;
203 : 0 : }
204 : :
205 : : static inline void
206 : : gen_iv(uint64_t iv[IPSEC_MAX_IV_QWORD], rte_be64_t sqn)
207 : : {
208 : 0 : iv[0] = sqn;
209 : 0 : iv[1] = 0;
210 : : }
211 : :
212 : :
213 : : /*
214 : : * RFC 7634, 2.1 AAD Construction
215 : : * spi and sqn should already be converted into network byte order.
216 : : * Make sure that not used bytes are zeroed.
217 : : */
218 : : static inline void
219 : : aead_chacha20_poly1305_aad_fill(struct aead_chacha20_poly1305_aad *aad,
220 : : rte_be32_t spi, rte_be64_t sqn,
221 : : int esn)
222 : : {
223 : 0 : aad->spi = spi;
224 [ # # ]: 0 : if (esn)
225 : 0 : aad->sqn.u64 = sqn;
226 : : else {
227 : 0 : aad->sqn.u32[0] = sqn_low32(sqn);
228 : 0 : aad->sqn.u32[1] = 0;
229 : : }
230 : 0 : aad->align0 = 0;
231 : 0 : }
232 : :
233 : : /*
234 : : * Helper routine to copy IV
235 : : * Right now we support only algorithms with IV length equals 0/8/16 bytes.
236 : : */
237 : : static inline void
238 : : copy_iv(uint64_t dst[IPSEC_MAX_IV_QWORD],
239 : : const uint64_t src[IPSEC_MAX_IV_QWORD], uint32_t len)
240 : : {
241 : : RTE_BUILD_BUG_ON(IPSEC_MAX_IV_SIZE != 2 * sizeof(uint64_t));
242 : :
243 [ # # # # : 0 : switch (len) {
# # ]
244 : 0 : case IPSEC_MAX_IV_SIZE:
245 : 0 : dst[1] = src[1];
246 : : /* fallthrough */
247 : 0 : case sizeof(uint64_t):
248 : 0 : dst[0] = src[0];
249 : : /* fallthrough */
250 : : case 0:
251 : : break;
252 [ # # # # ]: 0 : default:
253 : : /* should never happen */
254 : : RTE_ASSERT(NULL);
255 : : }
256 : : }
257 : :
258 : : /*
259 : : * from RFC 4303 3.3.2.1.4:
260 : : * If the ESN option is enabled for the SA, the high-order 32
261 : : * bits of the sequence number are appended after the Next Header field
262 : : * for purposes of this computation, but are not transmitted.
263 : : */
264 : :
265 : : /*
266 : : * Helper function that moves ICV by 4B below, and inserts SQN.hibits.
267 : : * icv parameter points to the new start of ICV.
268 : : */
269 : : static inline void
270 : : insert_sqh(uint32_t sqh, void *picv, uint32_t icv_len)
271 : : {
272 : : uint32_t *icv;
273 : : int32_t i;
274 : :
275 : : RTE_ASSERT(icv_len % sizeof(uint32_t) == 0);
276 : :
277 : : icv = picv;
278 : 0 : icv_len = icv_len / sizeof(uint32_t);
279 [ # # ]: 0 : for (i = icv_len; i-- != 0; icv[i] = icv[i - 1])
280 : : ;
281 : :
282 : 0 : icv[i] = sqh;
283 : 0 : }
284 : :
285 : : /*
286 : : * Helper function that moves ICV by 4B up, and removes SQN.hibits.
287 : : * icv parameter points to the new start of ICV.
288 : : */
289 : : static inline void
290 : : remove_sqh(void *picv, uint32_t icv_len)
291 : : {
292 : : uint32_t i, *icv;
293 : :
294 : : RTE_ASSERT(icv_len % sizeof(uint32_t) == 0);
295 : :
296 : : icv = picv;
297 : 0 : icv_len = icv_len / sizeof(uint32_t);
298 [ # # ]: 0 : for (i = 0; i != icv_len; i++)
299 : 0 : icv[i] = icv[i + 1];
300 : : }
301 : :
302 : : /*
303 : : * setup crypto ops for LOOKASIDE_NONE (pure crypto) type of devices.
304 : : */
305 : : static inline void
306 : : lksd_none_cop_prepare(struct rte_crypto_op *cop,
307 : : struct rte_cryptodev_sym_session *cs, struct rte_mbuf *mb)
308 : : {
309 : : struct rte_crypto_sym_op *sop;
310 : :
311 : : sop = cop->sym;
312 : 0 : cop->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
313 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
314 : 0 : cop->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
315 : 0 : sop->m_src = mb;
316 : : __rte_crypto_sym_op_attach_sym_session(sop, cs);
317 : : }
318 : :
319 : : #endif /* _CRYPTO_H_ */
|