FD.io VPP  v17.01.1-3-gc6833f8
Vector Packet Processing
esp.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Intel and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef __DPDK_ESP_H__
16 #define __DPDK_ESP_H__
17 
19 #include <vnet/ipsec/ipsec.h>
20 #include <vnet/ipsec/esp.h>
21 
22 typedef struct
23 {
24  enum rte_crypto_cipher_algorithm algo;
28 
29 typedef struct
30 {
31  enum rte_crypto_auth_algorithm algo;
34 
35 typedef struct
36 {
40 
42 
45 {
49 
51 
52  c = &em->esp_crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_128];
53  c->algo = RTE_CRYPTO_CIPHER_AES_CBC;
54  c->key_len = 16;
55  c->iv_len = 16;
56 
57  c = &em->esp_crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_192];
58  c->algo = RTE_CRYPTO_CIPHER_AES_CBC;
59  c->key_len = 24;
60  c->iv_len = 16;
61 
62  c = &em->esp_crypto_algs[IPSEC_CRYPTO_ALG_AES_CBC_256];
63  c->algo = RTE_CRYPTO_CIPHER_AES_CBC;
64  c->key_len = 32;
65  c->iv_len = 16;
66 
67  c = &em->esp_crypto_algs[IPSEC_CRYPTO_ALG_AES_GCM_128];
68  c->algo = RTE_CRYPTO_CIPHER_AES_GCM;
69  c->key_len = 16;
70  c->iv_len = 8;
71 
73 
74  i = &em->esp_integ_algs[IPSEC_INTEG_ALG_SHA1_96];
75  i->algo = RTE_CRYPTO_AUTH_SHA1_HMAC;
76  i->trunc_size = 12;
77 
78  i = &em->esp_integ_algs[IPSEC_INTEG_ALG_SHA_256_96];
79  i->algo = RTE_CRYPTO_AUTH_SHA256_HMAC;
80  i->trunc_size = 12;
81 
82  i = &em->esp_integ_algs[IPSEC_INTEG_ALG_SHA_256_128];
83  i->algo = RTE_CRYPTO_AUTH_SHA256_HMAC;
84  i->trunc_size = 16;
85 
86  i = &em->esp_integ_algs[IPSEC_INTEG_ALG_SHA_384_192];
87  i->algo = RTE_CRYPTO_AUTH_SHA384_HMAC;
88  i->trunc_size = 24;
89 
90  i = &em->esp_integ_algs[IPSEC_INTEG_ALG_SHA_512_256];
91  i->algo = RTE_CRYPTO_AUTH_SHA512_HMAC;
92  i->trunc_size = 32;
93 
94  i = &em->esp_integ_algs[IPSEC_INTEG_ALG_AES_GCM_128];
95  i->algo = RTE_CRYPTO_AUTH_AES_GCM;
96  i->trunc_size = 16;
97 }
98 
100 add_del_sa_sess (u32 sa_index, u8 is_add)
101 {
104  u8 skip_master = vlib_num_workers () > 0;
105 
106  /* *INDENT-OFF* */
107  vec_foreach (cwm, dcm->workers_main)
108  {
109  crypto_sa_session_t *sa_sess;
110  u8 is_outbound;
111 
112  if (skip_master)
113  {
114  skip_master = 0;
115  continue;
116  }
117 
118  for (is_outbound = 0; is_outbound < 2; is_outbound++)
119  {
120  if (is_add)
121  {
122  pool_get (cwm->sa_sess_d[is_outbound], sa_sess);
123  }
124  else
125  {
126  u8 dev_id;
127 
128  sa_sess = pool_elt_at_index (cwm->sa_sess_d[is_outbound], sa_index);
129  dev_id = cwm->qp_data[sa_sess->qp_index].dev_id;
130 
131  if (!sa_sess->sess)
132  continue;
133 
134  if (rte_cryptodev_sym_session_free(dev_id, sa_sess->sess))
135  {
136  clib_warning("failed to free session");
137  return -1;
138  }
139  memset(sa_sess, 0, sizeof(sa_sess[0]));
140  }
141  }
142  }
143  /* *INDENT-OFF* */
144 
145  return 0;
146 }
147 
150  struct rte_crypto_sym_xform *cipher_xform)
151 {
152  switch (crypto_algo)
153  {
154  case IPSEC_CRYPTO_ALG_NONE:
155  cipher_xform->cipher.algo = RTE_CRYPTO_CIPHER_NULL;
156  break;
157  case IPSEC_CRYPTO_ALG_AES_CBC_128:
158  case IPSEC_CRYPTO_ALG_AES_CBC_192:
159  case IPSEC_CRYPTO_ALG_AES_CBC_256:
160  cipher_xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_CBC;
161  break;
162  case IPSEC_CRYPTO_ALG_AES_GCM_128:
163  cipher_xform->cipher.algo = RTE_CRYPTO_CIPHER_AES_GCM;
164  break;
165  default:
166  return -1;
167  }
168 
169  cipher_xform->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
170 
171  return 0;
172 }
173 
176  struct rte_crypto_sym_xform *auth_xform, int use_esn)
177 {
178  switch (integ_alg) {
179  case IPSEC_INTEG_ALG_NONE:
180  auth_xform->auth.algo = RTE_CRYPTO_AUTH_NULL;
181  auth_xform->auth.digest_length = 0;
182  break;
183  case IPSEC_INTEG_ALG_SHA1_96:
184  auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA1_HMAC;
185  auth_xform->auth.digest_length = 12;
186  break;
187  case IPSEC_INTEG_ALG_SHA_256_96:
188  auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA256_HMAC;
189  auth_xform->auth.digest_length = 12;
190  break;
191  case IPSEC_INTEG_ALG_SHA_256_128:
192  auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA256_HMAC;
193  auth_xform->auth.digest_length = 16;
194  break;
195  case IPSEC_INTEG_ALG_SHA_384_192:
196  auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA384_HMAC;
197  auth_xform->auth.digest_length = 24;
198  break;
199  case IPSEC_INTEG_ALG_SHA_512_256:
200  auth_xform->auth.algo = RTE_CRYPTO_AUTH_SHA512_HMAC;
201  auth_xform->auth.digest_length = 32;
202  break;
203  case IPSEC_INTEG_ALG_AES_GCM_128:
204  auth_xform->auth.algo = RTE_CRYPTO_AUTH_AES_GCM;
205  auth_xform->auth.digest_length = 16;
206  auth_xform->auth.add_auth_data_length = use_esn? 12 : 8;
207  break;
208  default:
209  return -1;
210  }
211 
212  auth_xform->type = RTE_CRYPTO_SYM_XFORM_AUTH;
213 
214  return 0;
215 }
216 
219 {
220  u32 cpu_index = os_get_cpu_number();
222  crypto_worker_main_t *cwm = &dcm->workers_main[cpu_index];
223  struct rte_crypto_sym_xform cipher_xform = {0};
224  struct rte_crypto_sym_xform auth_xform = {0};
225  struct rte_crypto_sym_xform *xfs;
226  uword key = 0, *data;
228 
229  if (sa->crypto_alg == IPSEC_CRYPTO_ALG_AES_GCM_128)
230  {
231  sa->crypto_key_len -= 4;
232  clib_memcpy(&sa->salt, &sa->crypto_key[sa->crypto_key_len], 4);
233  }
234  else
235  {
236  sa->salt = (u32) rand();
237  }
238 
239  cipher_xform.type = RTE_CRYPTO_SYM_XFORM_CIPHER;
240  cipher_xform.cipher.key.data = sa->crypto_key;
241  cipher_xform.cipher.key.length = sa->crypto_key_len;
242 
243  auth_xform.type = RTE_CRYPTO_SYM_XFORM_AUTH;
244  auth_xform.auth.key.data = sa->integ_key;
245  auth_xform.auth.key.length = sa->integ_key_len;
246 
247  if (translate_crypto_algo(sa->crypto_alg, &cipher_xform) < 0)
248  return -1;
249  p_key->cipher_algo = cipher_xform.cipher.algo;
250 
251  if (translate_integ_algo(sa->integ_alg, &auth_xform, sa->use_esn) < 0)
252  return -1;
253  p_key->auth_algo = auth_xform.auth.algo;
254 
255  if (is_outbound)
256  {
257  cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_ENCRYPT;
258  auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_GENERATE;
259  cipher_xform.next = &auth_xform;
260  xfs = &cipher_xform;
261  }
262  else
263  {
264  cipher_xform.cipher.op = RTE_CRYPTO_CIPHER_OP_DECRYPT;
265  auth_xform.auth.op = RTE_CRYPTO_AUTH_OP_VERIFY;
266  auth_xform.next = &cipher_xform;
267  xfs = &auth_xform;
268  }
269 
270  p_key->is_outbound = is_outbound;
271 
272  data = hash_get(cwm->algo_qp_map, key);
273  if (!data)
274  return -1;
275 
276  sa_sess->sess =
277  rte_cryptodev_sym_session_create(cwm->qp_data[*data].dev_id, xfs);
278 
279  if (!sa_sess->sess)
280  return -1;
281 
282  sa_sess->qp_index = (u8)*data;
283 
284  return 0;
285 }
286 
287 #endif /* __DPDK_ESP_H__ */
288 
289 /*
290  * fd.io coding-style-patch-verification: ON
291  *
292  * Local Variables:
293  * eval: (c-set-style "gnu")
294  * End:
295  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:396
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
static_always_inline int add_del_sa_sess(u32 sa_index, u8 is_add)
Definition: esp.h:100
ipsec_integ_alg_t integ_alg
Definition: ipsec.h:102
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
u8 crypto_key[128]
Definition: ipsec.h:100
uword * algo_qp_map
Definition: ipsec.h:78
#define static_always_inline
Definition: clib.h:85
u8 integ_key[128]
Definition: ipsec.h:104
u8 use_esn
Definition: ipsec.h:106
#define clib_warning(format, args...)
Definition: error.h:59
dpdk_esp_integ_alg_t * esp_integ_algs
Definition: esp.h:38
ipsec_integ_alg_t
Definition: ipsec.h:78
static_always_inline int create_sym_sess(ipsec_sa_t *sa, crypto_sa_session_t *sa_sess, u8 is_outbound)
Definition: esp.h:218
dpdk_esp_crypto_alg_t * esp_crypto_algs
Definition: esp.h:37
static_always_inline int translate_crypto_algo(ipsec_crypto_alg_t crypto_algo, struct rte_crypto_sym_xform *cipher_xform)
Definition: esp.h:149
dpdk_crypto_main_t dpdk_crypto_main
Definition: ipsec.h:87
#define hash_get(h, key)
Definition: hash.h:248
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
u32 salt
Definition: ipsec.h:114
uword os_get_cpu_number(void)
Definition: unix-misc.c:224
ipsec_crypto_alg_t
Definition: ipsec.h:49
svmdb_client_t * c
dpdk_esp_main_t dpdk_esp_main
Definition: esp.h:41
#define clib_memcpy(a, b, c)
Definition: string.h:69
static_always_inline void dpdk_esp_init()
Definition: esp.h:44
enum rte_crypto_auth_algorithm algo
Definition: esp.h:31
unsigned int u32
Definition: types.h:88
crypto_worker_main_t * workers_main
Definition: ipsec.h:84
u8 integ_key_len
Definition: ipsec.h:103
crypto_qp_data_t * qp_data
Definition: ipsec.h:77
crypto_sa_session_t * sa_sess_d[2]
Definition: ipsec.h:76
u64 uword
Definition: types.h:112
u8 crypto_key_len
Definition: ipsec.h:99
static_always_inline int translate_integ_algo(ipsec_integ_alg_t integ_alg, struct rte_crypto_sym_xform *auth_xform, int use_esn)
Definition: esp.h:175
unsigned char u8
Definition: types.h:56
ipsec_crypto_alg_t crypto_alg
Definition: ipsec.h:98
static u32 vlib_num_workers()
Definition: threads.h:340
#define vec_foreach(var, vec)
Vector iterator.
enum rte_crypto_cipher_algorithm algo
Definition: esp.h:24