API Reference Manual  1.46.0
ipsec_crypto/odp_ipsec_sa_db.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2014-2018 Linaro Limited
3  */
4 
7 /* enable strtok */
8 #ifndef _GNU_SOURCE
9 #define _GNU_SOURCE
10 #endif
11 
12 #include <stdlib.h>
13 #include <string.h>
14 
15 #include <odp_api.h>
16 #include <odp/helper/odph_api.h>
17 
18 #include <odp_ipsec_sa_db.h>
19 
20 odp_bool_t sa_config_supported(const sa_db_entry_t *sa, int *sa_flags);
21 
23 static sa_db_t *sa_db;
24 
26 static tun_db_t *tun_db;
27 
28 void init_sa_db(void)
29 {
30  odp_shm_t shm;
31 
32  shm = odp_shm_reserve("shm_sa_db",
33  sizeof(sa_db_t),
34  ODP_CACHE_LINE_SIZE,
35  0);
36 
37  if (shm == ODP_SHM_INVALID) {
38  ODPH_ERR("Error: shared mem reserve failed.\n");
39  exit(EXIT_FAILURE);
40  }
41 
42  sa_db = odp_shm_addr(shm);
43 
44  if (sa_db == NULL) {
45  ODPH_ERR("Error: shared mem alloc failed.\n");
46  exit(EXIT_FAILURE);
47  }
48  memset(sa_db, 0, sizeof(*sa_db));
49 }
50 
51 void init_tun_db(void)
52 {
53  odp_shm_t shm;
54 
55  shm = odp_shm_reserve("shm_tun_db",
56  sizeof(tun_db_t),
57  ODP_CACHE_LINE_SIZE,
58  0);
59 
60  if (shm == ODP_SHM_INVALID) {
61  ODPH_ERR("Error: shared mem reserve failed.\n");
62  exit(EXIT_FAILURE);
63  }
64 
65  tun_db = odp_shm_addr(shm);
66 
67  if (!tun_db) {
68  ODPH_ERR("Error: shared mem alloc failed.\n");
69  exit(EXIT_FAILURE);
70  }
71  memset(tun_db, 0, sizeof(*tun_db));
72 }
73 
74 int create_sa_db_entry(char *input, odp_bool_t cipher)
75 {
76  int pos = 0;
77  char *local;
78  char *str;
79  char *save;
80  char *token;
81  sa_db_entry_t *entry = &sa_db->array[sa_db->index];
82 
83  /* Verify we have a good entry */
84  if (MAX_DB <= sa_db->index)
85  return -1;
86 
87  /* Make a local copy */
88  local = malloc(strlen(input) + 1);
89  if (NULL == local)
90  return -1;
91  strcpy(local, input);
92 
93  /* Set cipher versus auth */
94  entry->alg.cipher = cipher;
95 
96  /* Setup for using "strtok_r" to search input string */
97  str = local;
98  save = NULL;
99 
100  /* Parse tokens separated by ',' */
101  while (NULL != (token = strtok_r(str, ",", &save))) {
102  str = NULL; /* reset str for subsequent strtok_r calls */
103 
104  /* Parse token based on its position */
105  switch (pos) {
106  case 0:
107  parse_ipv4_string(token, &entry->src_ip, NULL);
108  break;
109  case 1:
110  parse_ipv4_string(token, &entry->dst_ip, NULL);
111  break;
112  case 2:
113  if (cipher) {
114  if (0 == strcmp(token, "3des")) {
115  entry->alg.u.cipher =
117  entry->block_len = 8;
118  entry->iv_len = 8;
119  } else {
120  entry->alg.u.cipher =
122  }
123  } else {
124  if (0 == strcmp(token, "md5")) {
125  entry->alg.u.auth =
127  entry->icv_len = 12;
128  } else if (!strcmp(token, "sha1")) {
129  entry->alg.u.auth =
131  entry->icv_len = 12;
132  } else if (!strcmp(token, "sha256")) {
133  entry->alg.u.auth =
135  entry->icv_len = 16;
136  } else {
137  entry->alg.u.auth = ODP_AUTH_ALG_NULL;
138  }
139  }
140  break;
141  case 3:
142  entry->spi = strtol(token, NULL, 16);
143  break;
144  case 4:
145  parse_key_string(token,
146  &entry->key,
147  &entry->alg);
148  break;
149  default:
150  printf("ERROR: extra token \"%s\" at position %d\n",
151  token, pos);
152  break;
153  }
154 
155  /* Advance to next position */
156  pos++;
157  }
158 
159  /* Verify we parsed exactly the number of tokens we expected */
160  if (5 != pos) {
161  printf("ERROR: \"%s\" contains %d tokens, expected 5\n",
162  input,
163  pos);
164  free(local);
165  return -1;
166  }
167 
168  if (!sa_config_supported(entry, &entry->flags)) {
169  free(local);
170  return -1;
171  }
172 
173  /* Add route to the list */
174  sa_db->index++;
175  entry->next = sa_db->list;
176  sa_db->list = entry;
177 
178  free(local);
179  return 0;
180 }
181 
182 int create_tun_db_entry(char *input)
183 {
184  int pos = 0;
185  char *local;
186  char *str;
187  char *save;
188  char *token;
189  tun_db_entry_t *entry = &tun_db->array[tun_db->index];
190 
191  /* Verify we have a good entry */
192  if (MAX_DB <= tun_db->index)
193  return -1;
194 
195  /* Make a local copy */
196  local = malloc(strlen(input) + 1);
197  if (NULL == local)
198  return -1;
199  strcpy(local, input);
200 
201  /* Setup for using "strtok_r" to search input string */
202  str = local;
203  save = NULL;
204 
205  /* Parse tokens separated by ',' */
206  while (NULL != (token = strtok_r(str, ",", &save))) {
207  str = NULL; /* reset str for subsequent strtok_r calls */
208 
209  /* Parse token based on its position */
210  switch (pos) {
211  case 0:
212  parse_ipv4_string(token, &entry->src_ip, NULL);
213  break;
214  case 1:
215  parse_ipv4_string(token, &entry->dst_ip, NULL);
216  break;
217  case 2:
218  parse_ipv4_string(token, &entry->tun_src_ip, NULL);
219  break;
220  case 3:
221  parse_ipv4_string(token, &entry->tun_dst_ip, NULL);
222  break;
223  default:
224  printf("ERROR: extra token \"%s\" at position %d\n",
225  token, pos);
226  break;
227  }
228  pos++;
229  }
230 
231  /* Verify we parsed exactly the number of tokens we expected */
232  if (4 != pos) {
233  printf("ERROR: \"%s\" contains %d tokens, expected 4\n",
234  input,
235  pos);
236  free(local);
237  return -1;
238  }
239 
240  /* Add route to the list */
241  tun_db->index++;
242  entry->next = tun_db->list;
243  tun_db->list = entry;
244 
245  free(local);
246  return 0;
247 }
248 
249 tun_db_entry_t *find_tun_db_entry(uint32_t ip_src,
250  uint32_t ip_dst)
251 {
252  tun_db_entry_t *entry = NULL;
253 
254  /* Scan all entries and return first match */
255  for (entry = tun_db->list; NULL != entry; entry = entry->next) {
256  if (entry->src_ip != ip_src)
257  continue;
258  if (entry->dst_ip != ip_dst)
259  continue;
260  break;
261  }
262  return entry;
263 }
264 
265 void dump_sa_db(void)
266 {
267  sa_db_entry_t *entry;
268 
269  printf("\n"
270  "Security association table\n"
271  "--------------------------\n");
272 
273  for (entry = sa_db->list; NULL != entry; entry = entry->next) {
274  uint32_t idx;
275  char src_ip_str[MAX_STRING];
276  char dst_ip_str[MAX_STRING];
277  uint8_t *p = entry->key.data;
278 
279 
280  printf(" %s %s %s %X %d ",
281  entry->alg.cipher ? "esp" : "ah ",
282  ipv4_addr_str(src_ip_str, entry->src_ip),
283  ipv4_addr_str(dst_ip_str, entry->dst_ip),
284  entry->spi,
285  entry->alg.cipher ?
286  (int)entry->alg.u.cipher :
287  (int)entry->alg.u.auth);
288 
289  /* Brute force key display */
290  for (idx = 0; idx < entry->key.length; idx++)
291  printf("%02X", *p++);
292 
293  printf("\n");
294  }
295 }
296 
297 sa_db_entry_t *find_sa_db_entry(ip_addr_range_t *src,
298  ip_addr_range_t *dst,
299  odp_bool_t cipher)
300 {
301  sa_db_entry_t *entry = NULL;
302 
303  /* Scan all entries and return first match */
304  for (entry = sa_db->list; NULL != entry; entry = entry->next) {
305  if (cipher != entry->alg.cipher)
306  continue;
307  if (!match_ip_range(entry->src_ip, src))
308  continue;
309  if (!match_ip_range(entry->dst_ip, dst))
310  continue;
311  break;
312  }
313  return entry;
314 }
315 
316 void dump_tun_db(void)
317 {
318  tun_db_entry_t *entry;
319 
320  printf("\n"
321  "Tunnel table\n"
322  "--------------------------\n");
323 
324  for (entry = tun_db->list; NULL != entry; entry = entry->next) {
325  char src_ip_str[MAX_STRING];
326  char dst_ip_str[MAX_STRING];
327  char tun_src_ip_str[MAX_STRING];
328  char tun_dst_ip_str[MAX_STRING];
329 
330  printf(" %s:%s %s:%s ",
331  ipv4_addr_str(src_ip_str, entry->src_ip),
332  ipv4_addr_str(dst_ip_str, entry->dst_ip),
333  ipv4_addr_str(tun_src_ip_str, entry->tun_src_ip),
334  ipv4_addr_str(tun_dst_ip_str, entry->tun_dst_ip)
335  );
336 
337  printf("\n");
338  }
339 }
@ ODP_CIPHER_ALG_3DES_CBC
Triple DES with cipher block chaining.
@ ODP_CIPHER_ALG_NULL
No cipher algorithm specified.
@ ODP_AUTH_ALG_NULL
No authentication algorithm specified.
@ ODP_AUTH_ALG_MD5_HMAC
HMAC-MD5.
@ ODP_AUTH_ALG_SHA1_HMAC
HMAC-SHA-1.
@ ODP_AUTH_ALG_SHA256_HMAC
HMAC-SHA-256.
#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.