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;
75  if (CRYPTO_API_SYNC == api_mode) {
76  params.op_mode = ODP_CRYPTO_SYNC;
78  entry->async = FALSE;
79  } else {
80  params.op_mode = ODP_CRYPTO_ASYNC;
81  params.compl_queue = completionq;
82  entry->async = TRUE;
83  }
84 
85  entry->sa_flags = 0;
86 
87  /* Cipher */
88  if (cipher_sa) {
89  params.cipher_alg = cipher_sa->alg.u.cipher;
90  params.cipher_key.data = cipher_sa->key.data;
91  params.cipher_key.length = cipher_sa->key.length;
92  params.cipher_iv_len = cipher_sa->iv_len;
93  mode = cipher_sa->mode;
94  if (cipher_sa->flags & BIT_MODE_CIPHER)
95  entry->sa_flags |= BIT_MODE_CIPHER;
96  } else {
98  params.cipher_iv_len = 0;
99  }
100 
101  /* Auth */
102  if (auth_sa) {
103  params.auth_alg = auth_sa->alg.u.auth;
104  params.auth_key.data = auth_sa->key.data;
105  params.auth_key.length = auth_sa->key.length;
106  params.auth_digest_len = auth_sa->icv_len;
107  mode = auth_sa->mode;
108  params.hash_result_in_auth_range = true;
109  if (auth_sa->flags & BIT_MODE_AUTH)
110  entry->sa_flags |= BIT_MODE_AUTH;
111  } else {
112  params.auth_alg = ODP_AUTH_ALG_NULL;
113  }
114 
115  /* Synchronous session create for now */
116  if (odp_crypto_session_create(&params, &session, &ses_create_rc))
117  return -1;
118  if (ODP_CRYPTO_SES_ERR_NONE != ses_create_rc)
119  return -1;
120 
121  /* Copy remainder */
122  if (cipher_sa) {
123  entry->src_ip = cipher_sa->src_ip;
124  entry->dst_ip = cipher_sa->dst_ip;
125  entry->esp.alg = cipher_sa->alg.u.cipher;
126  entry->esp.spi = cipher_sa->spi;
127  entry->esp.block_len = cipher_sa->block_len;
128  entry->esp.iv_len = cipher_sa->iv_len;
129  memcpy(&entry->esp.key, &cipher_sa->key, sizeof(ipsec_key_t));
130  }
131  if (auth_sa) {
132  entry->src_ip = auth_sa->src_ip;
133  entry->dst_ip = auth_sa->dst_ip;
134  entry->ah.alg = auth_sa->alg.u.auth;
135  entry->ah.spi = auth_sa->spi;
136  entry->ah.icv_len = auth_sa->icv_len;
137  memcpy(&entry->ah.key, &auth_sa->key, sizeof(ipsec_key_t));
138  }
139 
140  if (tun) {
141  entry->tun_src_ip = tun->tun_src_ip;
142  entry->tun_dst_ip = tun->tun_dst_ip;
143  mode = IPSEC_SA_MODE_TUNNEL;
144 
145  int ret;
146 
147  if (!in) {
148  /* init tun hdr id */
149  ret = odp_random_data((uint8_t *)
150  &entry->state.tun_hdr_id,
151  sizeof(entry->state.tun_hdr_id),
152  1);
153  if (ret != sizeof(entry->state.tun_hdr_id))
154  return -1;
155  }
156  }
157  entry->mode = mode;
158 
159  /* Initialize state */
160  entry->state.esp_seq = 0;
161  entry->state.ah_seq = 0;
162  entry->state.session = session;
163 
164  /* Add entry to the appropriate list */
165  ipsec_cache->index++;
166  if (in) {
167  entry->next = ipsec_cache->in_list;
168  ipsec_cache->in_list = entry;
169  } else {
170  entry->next = ipsec_cache->out_list;
171  ipsec_cache->out_list = entry;
172  }
173 
174  return 0;
175 }
176 
177 ipsec_cache_entry_t *find_ipsec_cache_entry_in(uint32_t src_ip,
178  uint32_t dst_ip,
179  odph_ahhdr_t *ah,
180  odph_esphdr_t *esp)
181 {
182  ipsec_cache_entry_t *entry = ipsec_cache->in_list;
183 
184  /* Look for a hit */
185  for (; NULL != entry; entry = entry->next) {
186  if ((entry->src_ip != src_ip) || (entry->dst_ip != dst_ip))
187  if ((entry->tun_src_ip != src_ip) ||
188  (entry->tun_dst_ip != dst_ip))
189  continue;
190  if (ah &&
191  ((!entry->ah.alg) ||
192  (entry->ah.spi != odp_be_to_cpu_32(ah->spi))))
193  continue;
194  if (esp &&
195  ((!entry->esp.alg) ||
196  (entry->esp.spi != odp_be_to_cpu_32(esp->spi))))
197  continue;
198  break;
199  }
200 
201  return entry;
202 }
203 
204 ipsec_cache_entry_t *find_ipsec_cache_entry_out(uint32_t src_ip,
205  uint32_t dst_ip,
206  uint8_t proto ODP_UNUSED)
207 {
208  ipsec_cache_entry_t *entry = ipsec_cache->out_list;
209 
210  /* Look for a hit */
211  for (; NULL != entry; entry = entry->next) {
212  if ((entry->src_ip == src_ip) && (entry->dst_ip == dst_ip))
213  break;
214  }
215  return entry;
216 }
217 
218 int destroy_ipsec_cache(void)
219 {
220  ipsec_cache_entry_t *entry;
221  int i;
222  int ret = 0;
223 
224  for (i = 0; i < MAX_DB; i++) {
225  entry = &ipsec_cache->array[i];
226  if (entry->state.session != ODP_CRYPTO_SESSION_INVALID)
227  ret += odp_crypto_session_destroy(entry->state.session);
228  }
229 
230  return ret;
231 }
#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_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.
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.