API Reference Manual  1.49.0
ipsec_crypto/odp_ipsec_cache.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2014-2018 Linaro Limited
3  */
4 
7 #include <stdlib.h>
8 #include <string.h>
9 
10 #include <odp_api.h>
11 
12 #include <odp/helper/ipsec.h>
13 
14 #include <odp_ipsec_cache.h>
15 
17 ipsec_cache_t *ipsec_cache;
18 
19 void init_ipsec_cache(void)
20 {
21  odp_shm_t shm;
22  int i;
23 
24  shm = odp_shm_reserve("shm_ipsec_cache",
25  sizeof(ipsec_cache_t),
26  ODP_CACHE_LINE_SIZE,
27  0);
28  if (shm == ODP_SHM_INVALID) {
29  ODPH_ERR("Error: shared mem alloc failed.\n");
30  exit(EXIT_FAILURE);
31  }
32 
33  ipsec_cache = odp_shm_addr(shm);
34 
35  if (ipsec_cache == NULL) {
36  ODPH_ERR("Error: shared mem alloc failed.\n");
37  exit(EXIT_FAILURE);
38  }
39  memset(ipsec_cache, 0, sizeof(*ipsec_cache));
40 
41  for (i = 0; i < MAX_DB; i++)
42  ipsec_cache->array[i].state.session =
44 }
45 
46 int create_ipsec_cache_entry(sa_db_entry_t *cipher_sa,
47  sa_db_entry_t *auth_sa,
48  tun_db_entry_t *tun,
49  crypto_api_mode_e api_mode,
50  odp_bool_t in,
51  odp_queue_t completionq)
52 {
54  ipsec_cache_entry_t *entry;
55  odp_crypto_ses_create_err_t ses_create_rc;
56  odp_crypto_session_t session;
57  sa_mode_t mode = IPSEC_SA_MODE_TRANSPORT;
58 
59  /* Verify we have a good entry */
60  entry = &ipsec_cache->array[ipsec_cache->index];
61  if (MAX_DB <= ipsec_cache->index)
62  return -1;
63 
64  /* Verify SA mode match in case of cipher&auth */
65  if (cipher_sa && auth_sa &&
66  (cipher_sa->mode != auth_sa->mode))
67  return -1;
68 
70 
71  /* Setup parameters and call crypto library to create session */
74  params.auth_cipher_text = TRUE;
76  if (CRYPTO_API_SYNC == api_mode) {
77  params.op_mode = ODP_CRYPTO_SYNC;
79  entry->async = FALSE;
80  } else {
81  params.op_mode = ODP_CRYPTO_ASYNC;
82  params.compl_queue = completionq;
83  entry->async = TRUE;
84  }
85 
86  entry->sa_flags = 0;
87 
88  /* Cipher */
89  if (cipher_sa) {
90  params.cipher_alg = cipher_sa->alg.u.cipher;
91  params.cipher_key.data = cipher_sa->key.data;
92  params.cipher_key.length = cipher_sa->key.length;
93  params.cipher_iv_len = cipher_sa->iv_len;
94  mode = cipher_sa->mode;
95  if (cipher_sa->flags & BIT_MODE_CIPHER)
96  entry->sa_flags |= BIT_MODE_CIPHER;
97  } else {
99  params.cipher_iv_len = 0;
100  }
101 
102  /* Auth */
103  if (auth_sa) {
104  params.auth_alg = auth_sa->alg.u.auth;
105  params.auth_key.data = auth_sa->key.data;
106  params.auth_key.length = auth_sa->key.length;
107  params.auth_digest_len = auth_sa->icv_len;
108  mode = auth_sa->mode;
109  params.hash_result_in_auth_range = true;
110  if (auth_sa->flags & BIT_MODE_AUTH)
111  entry->sa_flags |= BIT_MODE_AUTH;
112  } else {
113  params.auth_alg = ODP_AUTH_ALG_NULL;
114  }
115 
116  /* Synchronous session create for now */
117  if (odp_crypto_session_create(&params, &session, &ses_create_rc))
118  return -1;
119  if (ODP_CRYPTO_SES_ERR_NONE != ses_create_rc)
120  return -1;
121 
122  /* Copy remainder */
123  if (cipher_sa) {
124  entry->src_ip = cipher_sa->src_ip;
125  entry->dst_ip = cipher_sa->dst_ip;
126  entry->esp.alg = cipher_sa->alg.u.cipher;
127  entry->esp.spi = cipher_sa->spi;
128  entry->esp.block_len = cipher_sa->block_len;
129  entry->esp.iv_len = cipher_sa->iv_len;
130  memcpy(&entry->esp.key, &cipher_sa->key, sizeof(ipsec_key_t));
131  }
132  if (auth_sa) {
133  entry->src_ip = auth_sa->src_ip;
134  entry->dst_ip = auth_sa->dst_ip;
135  entry->ah.alg = auth_sa->alg.u.auth;
136  entry->ah.spi = auth_sa->spi;
137  entry->ah.icv_len = auth_sa->icv_len;
138  memcpy(&entry->ah.key, &auth_sa->key, sizeof(ipsec_key_t));
139  }
140 
141  if (tun) {
142  entry->tun_src_ip = tun->tun_src_ip;
143  entry->tun_dst_ip = tun->tun_dst_ip;
144  mode = IPSEC_SA_MODE_TUNNEL;
145 
146  int ret;
147 
148  if (!in) {
149  /* init tun hdr id */
150  ret = odp_random_data((uint8_t *)
151  &entry->state.tun_hdr_id,
152  sizeof(entry->state.tun_hdr_id),
153  1);
154  if (ret != sizeof(entry->state.tun_hdr_id))
155  return -1;
156  }
157  }
158  entry->mode = mode;
159 
160  /* Initialize state */
161  entry->state.esp_seq = 0;
162  entry->state.ah_seq = 0;
163  entry->state.session = session;
164 
165  /* Add entry to the appropriate list */
166  ipsec_cache->index++;
167  if (in) {
168  entry->next = ipsec_cache->in_list;
169  ipsec_cache->in_list = entry;
170  } else {
171  entry->next = ipsec_cache->out_list;
172  ipsec_cache->out_list = entry;
173  }
174 
175  return 0;
176 }
177 
178 ipsec_cache_entry_t *find_ipsec_cache_entry_in(uint32_t src_ip,
179  uint32_t dst_ip,
180  odph_ahhdr_t *ah,
181  odph_esphdr_t *esp)
182 {
183  ipsec_cache_entry_t *entry = ipsec_cache->in_list;
184 
185  /* Look for a hit */
186  for (; NULL != entry; entry = entry->next) {
187  if ((entry->src_ip != src_ip) || (entry->dst_ip != dst_ip))
188  if ((entry->tun_src_ip != src_ip) ||
189  (entry->tun_dst_ip != dst_ip))
190  continue;
191  if (ah &&
192  ((!entry->ah.alg) ||
193  (entry->ah.spi != odp_be_to_cpu_32(ah->spi))))
194  continue;
195  if (esp &&
196  ((!entry->esp.alg) ||
197  (entry->esp.spi != odp_be_to_cpu_32(esp->spi))))
198  continue;
199  break;
200  }
201 
202  return entry;
203 }
204 
205 ipsec_cache_entry_t *find_ipsec_cache_entry_out(uint32_t src_ip,
206  uint32_t dst_ip,
207  uint8_t proto ODP_UNUSED)
208 {
209  ipsec_cache_entry_t *entry = ipsec_cache->out_list;
210 
211  /* Look for a hit */
212  for (; NULL != entry; entry = entry->next) {
213  if ((entry->src_ip == src_ip) && (entry->dst_ip == dst_ip))
214  break;
215  }
216  return entry;
217 }
218 
219 int destroy_ipsec_cache(void)
220 {
221  ipsec_cache_entry_t *entry;
222  int i;
223  int ret = 0;
224 
225  for (i = 0; i < MAX_DB; i++) {
226  entry = &ipsec_cache->array[i];
227  if (entry->state.session != ODP_CRYPTO_SESSION_INVALID)
228  ret += odp_crypto_session_destroy(entry->state.session);
229  }
230 
231  return ret;
232 }
#define ODP_UNUSED
Intentionally unused variables of functions.
Definition: spec/hints.h:54
uint32_t odp_be_to_cpu_32(odp_u32be_t be32)
Convert 32bit big endian to cpu native uint32_t.
void odp_crypto_session_param_init(odp_crypto_session_param_t *param)
Initialize crypto session parameters.
uint64_t odp_crypto_session_t
Crypto API opaque session handle.
int odp_crypto_session_create(const odp_crypto_session_param_t *param, odp_crypto_session_t *session, odp_crypto_ses_create_err_t *status)
Crypto session creation.
#define ODP_CRYPTO_SESSION_INVALID
Invalid session handle.
int odp_crypto_session_destroy(odp_crypto_session_t session)
Crypto session destroy.
odp_crypto_ses_create_err_t
Crypto API session creation return code.
@ ODP_CIPHER_ALG_NULL
No cipher algorithm specified.
@ ODP_CRYPTO_OP_TYPE_BASIC
Input packet data and metadata are copied to the output packet and then processed.
@ ODP_AUTH_ALG_NULL
No authentication algorithm specified.
@ ODP_CRYPTO_SES_ERR_NONE
Session created.
@ ODP_CRYPTO_OP_ENCODE
Encrypt and/or compute authentication ICV.
@ ODP_CRYPTO_OP_DECODE
Decrypt and/or verify authentication ICV.
@ ODP_CRYPTO_SYNC
Synchronous, return results immediately.
@ ODP_CRYPTO_ASYNC
Asynchronous, return results via posted event.
#define ODP_POOL_INVALID
Invalid pool.
#define ODP_QUEUE_INVALID
Invalid queue.
int32_t odp_random_data(uint8_t *buf, uint32_t len, odp_random_kind_t kind)
Generate random byte data.
#define ODP_SHM_INVALID
Invalid shared memory block.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags)
Reserve a contiguous block of shared memory.
bool odp_bool_t
Boolean type.
The OpenDataPlane API.
uint8_t * data
Key data.
uint32_t length
Key length in bytes.
Crypto API session creation parameters.
odp_bool_t auth_cipher_text
Authenticate cipher vs.
odp_crypto_key_t auth_key
Authentication key.
odp_crypto_op_type_t op_type
Crypto operation type.
odp_crypto_key_t cipher_key
Cipher key.
odp_queue_t compl_queue
Async mode completion event queue.
odp_pool_t output_pool
Output pool.
uint32_t cipher_iv_len
Cipher IV length.
odp_bool_t hash_result_in_auth_range
Hash result location may overlap authentication range.
uint32_t auth_digest_len
Authentication digest length in bytes.
odp_auth_alg_t auth_alg
Authentication algorithm.
odp_crypto_op_mode_t op_mode
Operation mode when using packet interface: sync or async.
odp_cipher_alg_t cipher_alg
Cipher algorithm.
odp_crypto_op_t op
Encode vs.