API Reference Manual 1.51.0
Loading...
Searching...
No Matches
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
17ipsec_cache_t *ipsec_cache;
18
19void 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
46int 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;
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 {
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 {
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
177ipsec_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
204ipsec_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
218int 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.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
#define ODP_SHM_INVALID
Invalid shared memory block.
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.