Line data Source code
1 : /*
2 : * Copyright (c) 2018 Cisco 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 :
16 : #include <stdbool.h>
17 : #include <vlib/vlib.h>
18 : #include <vnet/crypto/crypto.h>
19 :
20 : vnet_crypto_main_t crypto_main;
21 :
22 : static_always_inline void
23 1 : crypto_set_op_status (vnet_crypto_op_t * ops[], u32 n_ops, int status)
24 : {
25 2 : while (n_ops--)
26 : {
27 1 : ops[0]->status = status;
28 1 : ops++;
29 : }
30 1 : }
31 :
32 : static_always_inline u32
33 339696 : vnet_crypto_process_ops_call_handler (vlib_main_t * vm,
34 : vnet_crypto_main_t * cm,
35 : vnet_crypto_op_id_t opt,
36 : vnet_crypto_op_t * ops[],
37 : vnet_crypto_op_chunk_t * chunks,
38 : u32 n_ops)
39 : {
40 339696 : u32 rv = 0;
41 339696 : if (n_ops == 0)
42 169809 : return 0;
43 :
44 169887 : if (chunks)
45 : {
46 :
47 3755 : if (cm->chained_ops_handlers[opt] == 0)
48 0 : crypto_set_op_status (ops, n_ops,
49 : VNET_CRYPTO_OP_STATUS_FAIL_NO_HANDLER);
50 : else
51 3755 : rv = (cm->chained_ops_handlers[opt]) (vm, ops, chunks, n_ops);
52 : }
53 : else
54 : {
55 166132 : if (cm->ops_handlers[opt] == 0)
56 1 : crypto_set_op_status (ops, n_ops,
57 : VNET_CRYPTO_OP_STATUS_FAIL_NO_HANDLER);
58 : else
59 166131 : rv = (cm->ops_handlers[opt]) (vm, ops, n_ops);
60 : }
61 169887 : return rv;
62 : }
63 :
64 : static_always_inline u32
65 169809 : vnet_crypto_process_ops_inline (vlib_main_t * vm, vnet_crypto_op_t ops[],
66 : vnet_crypto_op_chunk_t * chunks, u32 n_ops)
67 169809 : {
68 169809 : vnet_crypto_main_t *cm = &crypto_main;
69 169809 : const int op_q_size = VLIB_FRAME_SIZE;
70 169809 : vnet_crypto_op_t *op_queue[op_q_size];
71 169809 : vnet_crypto_op_id_t opt, current_op_type = ~0;
72 169809 : u32 n_op_queue = 0;
73 169809 : u32 rv = 0, i;
74 :
75 169809 : ASSERT (n_ops >= 1);
76 :
77 1055400 : for (i = 0; i < n_ops; i++)
78 : {
79 885589 : opt = ops[i].op;
80 :
81 885589 : if (current_op_type != opt || n_op_queue >= op_q_size)
82 : {
83 169887 : rv += vnet_crypto_process_ops_call_handler (vm, cm, current_op_type,
84 : op_queue, chunks,
85 : n_op_queue);
86 169887 : n_op_queue = 0;
87 169887 : current_op_type = opt;
88 : }
89 :
90 885589 : op_queue[n_op_queue++] = &ops[i];
91 : }
92 :
93 169809 : rv += vnet_crypto_process_ops_call_handler (vm, cm, current_op_type,
94 : op_queue, chunks, n_op_queue);
95 169809 : return rv;
96 : }
97 :
98 : u32
99 166060 : vnet_crypto_process_ops (vlib_main_t * vm, vnet_crypto_op_t ops[], u32 n_ops)
100 : {
101 166060 : return vnet_crypto_process_ops_inline (vm, ops, 0, n_ops);
102 : }
103 :
104 : u32
105 3749 : vnet_crypto_process_chained_ops (vlib_main_t * vm, vnet_crypto_op_t ops[],
106 : vnet_crypto_op_chunk_t * chunks, u32 n_ops)
107 : {
108 3749 : return vnet_crypto_process_ops_inline (vm, ops, chunks, n_ops);
109 : }
110 :
111 : u32
112 2236 : vnet_crypto_register_engine (vlib_main_t * vm, char *name, int prio,
113 : char *desc)
114 : {
115 2236 : vnet_crypto_main_t *cm = &crypto_main;
116 : vnet_crypto_engine_t *p;
117 :
118 2236 : vec_add2 (cm->engines, p, 1);
119 2236 : p->name = name;
120 2236 : p->desc = desc;
121 2236 : p->priority = prio;
122 :
123 4472 : hash_set_mem (cm->engine_index_by_name, p->name, p - cm->engines);
124 :
125 2236 : return p - cm->engines;
126 : }
127 :
128 : static_always_inline void
129 19028 : crypto_set_active_engine (vnet_crypto_op_data_t * od,
130 : vnet_crypto_op_id_t id, u32 ei,
131 : crypto_op_class_type_t oct)
132 : {
133 19028 : vnet_crypto_main_t *cm = &crypto_main;
134 19028 : vnet_crypto_engine_t *ce = vec_elt_at_index (cm->engines, ei);
135 :
136 19028 : if (oct == CRYPTO_OP_BOTH || oct == CRYPTO_OP_CHAINED)
137 : {
138 12320 : if (ce->chained_ops_handlers[id])
139 : {
140 6622 : od->active_engine_index_chained = ei;
141 6622 : cm->chained_ops_handlers[id] = ce->chained_ops_handlers[id];
142 : }
143 : }
144 :
145 19028 : if (oct == CRYPTO_OP_BOTH || oct == CRYPTO_OP_SIMPLE)
146 : {
147 19028 : if (ce->ops_handlers[id])
148 : {
149 16476 : od->active_engine_index_simple = ei;
150 16476 : cm->ops_handlers[id] = ce->ops_handlers[id];
151 : }
152 : }
153 19028 : }
154 :
155 : int
156 11638 : vnet_crypto_set_handler2 (char *alg_name, char *engine,
157 : crypto_op_class_type_t oct)
158 : {
159 : uword *p;
160 11638 : vnet_crypto_main_t *cm = &crypto_main;
161 : vnet_crypto_alg_data_t *ad;
162 : int i;
163 :
164 11638 : p = hash_get_mem (cm->alg_index_by_name, alg_name);
165 11638 : if (!p)
166 0 : return -1;
167 :
168 11638 : ad = vec_elt_at_index (cm->algs, p[0]);
169 :
170 11638 : p = hash_get_mem (cm->engine_index_by_name, engine);
171 11638 : if (!p)
172 3542 : return -1;
173 :
174 56672 : for (i = 0; i < VNET_CRYPTO_OP_N_TYPES; i++)
175 : {
176 : vnet_crypto_op_data_t *od;
177 48576 : vnet_crypto_op_id_t id = ad->op_by_type[i];
178 48576 : if (id == 0)
179 36256 : continue;
180 :
181 12320 : od = cm->opt_data + id;
182 12320 : crypto_set_active_engine (od, id, p[0], oct);
183 : }
184 :
185 8096 : return 0;
186 : }
187 :
188 : int
189 10587 : vnet_crypto_is_set_handler (vnet_crypto_alg_t alg)
190 : {
191 10587 : vnet_crypto_main_t *cm = &crypto_main;
192 10587 : vnet_crypto_op_id_t opt = 0;
193 : int i;
194 :
195 10587 : if (alg > vec_len (cm->algs))
196 0 : return 0;
197 :
198 33455 : for (i = 0; i < VNET_CRYPTO_OP_N_TYPES; i++)
199 33455 : if ((opt = cm->algs[alg].op_by_type[i]) != 0)
200 10587 : break;
201 :
202 10587 : return NULL != cm->ops_handlers[opt];
203 : }
204 :
205 : void
206 44720 : vnet_crypto_register_ops_handler_inline (vlib_main_t * vm, u32 engine_index,
207 : vnet_crypto_op_id_t opt,
208 : vnet_crypto_ops_handler_t * fn,
209 : vnet_crypto_chained_ops_handler_t *
210 : cfn)
211 : {
212 44720 : vnet_crypto_main_t *cm = &crypto_main;
213 44720 : vnet_crypto_engine_t *ae, *e = vec_elt_at_index (cm->engines, engine_index);
214 44720 : vnet_crypto_op_data_t *otd = cm->opt_data + opt;
215 44720 : vec_validate_aligned (cm->ops_handlers, VNET_CRYPTO_N_OP_IDS - 1,
216 : CLIB_CACHE_LINE_BYTES);
217 44720 : vec_validate_aligned (cm->chained_ops_handlers, VNET_CRYPTO_N_OP_IDS - 1,
218 : CLIB_CACHE_LINE_BYTES);
219 :
220 44720 : if (fn)
221 : {
222 40248 : e->ops_handlers[opt] = fn;
223 40248 : if (otd->active_engine_index_simple == ~0)
224 : {
225 19565 : otd->active_engine_index_simple = engine_index;
226 19565 : cm->ops_handlers[opt] = fn;
227 : }
228 :
229 40248 : ae = vec_elt_at_index (cm->engines, otd->active_engine_index_simple);
230 40248 : if (ae->priority < e->priority)
231 6708 : crypto_set_active_engine (otd, opt, engine_index, CRYPTO_OP_SIMPLE);
232 : }
233 :
234 44720 : if (cfn)
235 : {
236 24037 : e->chained_ops_handlers[opt] = cfn;
237 24037 : if (otd->active_engine_index_chained == ~0)
238 : {
239 19565 : otd->active_engine_index_chained = engine_index;
240 19565 : cm->chained_ops_handlers[opt] = cfn;
241 : }
242 :
243 24037 : ae = vec_elt_at_index (cm->engines, otd->active_engine_index_chained);
244 24037 : if (ae->priority < e->priority)
245 0 : crypto_set_active_engine (otd, opt, engine_index, CRYPTO_OP_CHAINED);
246 : }
247 :
248 44720 : return;
249 : }
250 :
251 : void
252 20683 : vnet_crypto_register_ops_handler (vlib_main_t * vm, u32 engine_index,
253 : vnet_crypto_op_id_t opt,
254 : vnet_crypto_ops_handler_t * fn)
255 : {
256 20683 : vnet_crypto_register_ops_handler_inline (vm, engine_index, opt, fn, 0);
257 20683 : }
258 :
259 : void
260 4472 : vnet_crypto_register_chained_ops_handler (vlib_main_t * vm, u32 engine_index,
261 : vnet_crypto_op_id_t opt,
262 : vnet_crypto_chained_ops_handler_t *
263 : fn)
264 : {
265 4472 : vnet_crypto_register_ops_handler_inline (vm, engine_index, opt, 0, fn);
266 4472 : }
267 :
268 : void
269 19565 : vnet_crypto_register_ops_handlers (vlib_main_t * vm, u32 engine_index,
270 : vnet_crypto_op_id_t opt,
271 : vnet_crypto_ops_handler_t * fn,
272 : vnet_crypto_chained_ops_handler_t * cfn)
273 : {
274 19565 : vnet_crypto_register_ops_handler_inline (vm, engine_index, opt, fn, cfn);
275 19565 : }
276 :
277 : void
278 40248 : vnet_crypto_register_enqueue_handler (vlib_main_t *vm, u32 engine_index,
279 : vnet_crypto_async_op_id_t opt,
280 : vnet_crypto_frame_enqueue_t *enqueue_hdl)
281 : {
282 40248 : vnet_crypto_main_t *cm = &crypto_main;
283 40248 : vnet_crypto_engine_t *ae, *e = vec_elt_at_index (cm->engines, engine_index);
284 40248 : vnet_crypto_async_op_data_t *otd = cm->async_opt_data + opt;
285 40248 : vec_validate_aligned (cm->enqueue_handlers, VNET_CRYPTO_ASYNC_OP_N_IDS,
286 : CLIB_CACHE_LINE_BYTES);
287 :
288 40248 : if (!enqueue_hdl)
289 0 : return;
290 :
291 40248 : e->enqueue_handlers[opt] = enqueue_hdl;
292 40248 : if (otd->active_engine_index_async == ~0)
293 : {
294 40248 : otd->active_engine_index_async = engine_index;
295 40248 : cm->enqueue_handlers[opt] = enqueue_hdl;
296 : }
297 :
298 40248 : ae = vec_elt_at_index (cm->engines, otd->active_engine_index_async);
299 40248 : if (ae->priority <= e->priority)
300 : {
301 40248 : otd->active_engine_index_async = engine_index;
302 40248 : cm->enqueue_handlers[opt] = enqueue_hdl;
303 : }
304 :
305 40248 : return;
306 : }
307 :
308 : static int
309 118508 : engine_index_cmp (void *v1, void *v2)
310 : {
311 118508 : u32 *a1 = v1;
312 118508 : u32 *a2 = v2;
313 :
314 118508 : if (*a1 > *a2)
315 0 : return 1;
316 118508 : if (*a1 < *a2)
317 0 : return -1;
318 118508 : return 0;
319 : }
320 :
321 : static void
322 559 : vnet_crypto_update_cm_dequeue_handlers (void)
323 : {
324 559 : vnet_crypto_main_t *cm = &crypto_main;
325 : vnet_crypto_async_op_data_t *otd;
326 : vnet_crypto_engine_t *e;
327 559 : u32 *active_engines = 0, *ei, last_ei = ~0, i;
328 :
329 559 : vec_reset_length (cm->dequeue_handlers);
330 :
331 41366 : for (i = 0; i < VNET_CRYPTO_ASYNC_OP_N_IDS; i++)
332 : {
333 40807 : otd = cm->async_opt_data + i;
334 40807 : if (otd->active_engine_index_async == ~0)
335 0 : continue;
336 40807 : e = cm->engines + otd->active_engine_index_async;
337 40807 : if (!e->dequeue_handler)
338 559 : continue;
339 40248 : vec_add1 (active_engines, otd->active_engine_index_async);
340 : }
341 :
342 559 : vec_sort_with_function (active_engines, engine_index_cmp);
343 :
344 40807 : vec_foreach (ei, active_engines)
345 : {
346 40248 : if (ei[0] == last_ei)
347 39689 : continue;
348 559 : if (ei[0] == ~0)
349 0 : continue;
350 :
351 559 : e = cm->engines + ei[0];
352 559 : vec_add1 (cm->dequeue_handlers, e->dequeue_handler);
353 559 : last_ei = ei[0];
354 : }
355 :
356 559 : vec_free (active_engines);
357 559 : }
358 :
359 : void
360 559 : vnet_crypto_register_dequeue_handler (vlib_main_t *vm, u32 engine_index,
361 : vnet_crypto_frame_dequeue_t *deq_fn)
362 : {
363 559 : vnet_crypto_main_t *cm = &crypto_main;
364 559 : vnet_crypto_engine_t *e = vec_elt_at_index (cm->engines, engine_index);
365 :
366 559 : if (!deq_fn)
367 0 : return;
368 :
369 559 : e->dequeue_handler = deq_fn;
370 :
371 559 : vnet_crypto_update_cm_dequeue_handlers ();
372 :
373 559 : return;
374 : }
375 :
376 : void
377 1677 : vnet_crypto_register_key_handler (vlib_main_t * vm, u32 engine_index,
378 : vnet_crypto_key_handler_t * key_handler)
379 : {
380 1677 : vnet_crypto_main_t *cm = &crypto_main;
381 1677 : vnet_crypto_engine_t *e = vec_elt_at_index (cm->engines, engine_index);
382 1677 : e->key_op_handler = key_handler;
383 1677 : return;
384 : }
385 :
386 : static int
387 12854 : vnet_crypto_key_len_check (vnet_crypto_alg_t alg, u16 length)
388 : {
389 12854 : switch (alg)
390 : {
391 0 : case VNET_CRYPTO_N_ALGS:
392 0 : return 0;
393 442 : case VNET_CRYPTO_ALG_NONE:
394 442 : return 1;
395 :
396 : #define _(n, s, l) \
397 : case VNET_CRYPTO_ALG_##n: \
398 : if ((l) == length) \
399 : return 1; \
400 : break;
401 7522 : foreach_crypto_cipher_alg foreach_crypto_aead_alg
402 : #undef _
403 : /* HMAC allows any key length */
404 : #define _(n, s) \
405 : case VNET_CRYPTO_ALG_HMAC_##n: \
406 : return 1;
407 4890 : foreach_crypto_hmac_alg
408 : #undef _
409 :
410 : #define _(n, s) \
411 : case VNET_CRYPTO_ALG_HASH_##n: \
412 : return 1;
413 0 : foreach_crypto_hash_alg
414 : #undef _
415 : }
416 :
417 0 : return 0;
418 : }
419 :
420 : u32
421 12854 : vnet_crypto_key_add (vlib_main_t * vm, vnet_crypto_alg_t alg, u8 * data,
422 : u16 length)
423 : {
424 : u32 index;
425 12854 : vnet_crypto_main_t *cm = &crypto_main;
426 : vnet_crypto_engine_t *engine;
427 : vnet_crypto_key_t *key;
428 :
429 12854 : u8 need_barrier_sync = 0;
430 :
431 12854 : if (!vnet_crypto_key_len_check (alg, length))
432 0 : return ~0;
433 :
434 12854 : need_barrier_sync = pool_get_will_expand (cm->keys);
435 : /* If the cm->keys will expand, stop the parade. */
436 12854 : if (need_barrier_sync)
437 1338 : vlib_worker_thread_barrier_sync (vm);
438 :
439 12854 : pool_get_zero (cm->keys, key);
440 :
441 12854 : if (need_barrier_sync)
442 1338 : vlib_worker_thread_barrier_release (vm);
443 :
444 12854 : index = key - cm->keys;
445 12854 : key->type = VNET_CRYPTO_KEY_TYPE_DATA;
446 12854 : key->alg = alg;
447 12854 : vec_validate_aligned (key->data, length - 1, CLIB_CACHE_LINE_BYTES);
448 12854 : clib_memcpy (key->data, data, length);
449 : /* *INDENT-OFF* */
450 64270 : vec_foreach (engine, cm->engines)
451 51416 : if (engine->key_op_handler)
452 38562 : engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_ADD, index);
453 : /* *INDENT-ON* */
454 12854 : return index;
455 : }
456 :
457 : void
458 12807 : vnet_crypto_key_del (vlib_main_t * vm, vnet_crypto_key_index_t index)
459 : {
460 12807 : vnet_crypto_main_t *cm = &crypto_main;
461 : vnet_crypto_engine_t *engine;
462 12807 : vnet_crypto_key_t *key = pool_elt_at_index (cm->keys, index);
463 :
464 : /* *INDENT-OFF* */
465 64035 : vec_foreach (engine, cm->engines)
466 51228 : if (engine->key_op_handler)
467 38421 : engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_DEL, index);
468 : /* *INDENT-ON* */
469 :
470 12807 : if (key->type == VNET_CRYPTO_KEY_TYPE_DATA)
471 : {
472 12807 : clib_memset (key->data, 0xfe, vec_len (key->data));
473 12807 : vec_free (key->data);
474 : }
475 0 : else if (key->type == VNET_CRYPTO_KEY_TYPE_LINK)
476 : {
477 0 : key->index_crypto = key->index_integ = ~0;
478 : }
479 :
480 12807 : pool_put (cm->keys, key);
481 12807 : }
482 :
483 : vnet_crypto_async_alg_t
484 4404 : vnet_crypto_link_algs (vnet_crypto_alg_t crypto_alg,
485 : vnet_crypto_alg_t integ_alg)
486 : {
487 : #define _(c, h, s, k ,d) \
488 : if (crypto_alg == VNET_CRYPTO_ALG_##c && \
489 : integ_alg == VNET_CRYPTO_ALG_HMAC_##h) \
490 : return VNET_CRYPTO_ALG_##c##_##h##_TAG##d;
491 4404 : foreach_crypto_link_async_alg
492 : #undef _
493 0 : return ~0;
494 : }
495 :
496 : u32
497 4404 : vnet_crypto_key_add_linked (vlib_main_t * vm,
498 : vnet_crypto_key_index_t index_crypto,
499 : vnet_crypto_key_index_t index_integ)
500 : {
501 : u32 index;
502 4404 : vnet_crypto_main_t *cm = &crypto_main;
503 : vnet_crypto_engine_t *engine;
504 : vnet_crypto_key_t *key_crypto, *key_integ, *key;
505 : vnet_crypto_async_alg_t linked_alg;
506 :
507 4404 : key_crypto = pool_elt_at_index (cm->keys, index_crypto);
508 4404 : key_integ = pool_elt_at_index (cm->keys, index_integ);
509 :
510 4404 : linked_alg = vnet_crypto_link_algs (key_crypto->alg, key_integ->alg);
511 4404 : if (linked_alg == ~0)
512 0 : return ~0;
513 :
514 4404 : pool_get_zero (cm->keys, key);
515 4404 : index = key - cm->keys;
516 4404 : key->type = VNET_CRYPTO_KEY_TYPE_LINK;
517 4404 : key->index_crypto = index_crypto;
518 4404 : key->index_integ = index_integ;
519 4404 : key->async_alg = linked_alg;
520 :
521 : /* *INDENT-OFF* */
522 22020 : vec_foreach (engine, cm->engines)
523 17616 : if (engine->key_op_handler)
524 13212 : engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_ADD, index);
525 : /* *INDENT-ON* */
526 :
527 4404 : return index;
528 : }
529 :
530 : static_always_inline void
531 0 : crypto_set_active_async_engine (vnet_crypto_async_op_data_t * od,
532 : vnet_crypto_async_op_id_t id, u32 ei)
533 : {
534 0 : vnet_crypto_main_t *cm = &crypto_main;
535 0 : vnet_crypto_engine_t *ce = vec_elt_at_index (cm->engines, ei);
536 :
537 0 : if (ce->enqueue_handlers[id] && ce->dequeue_handler)
538 : {
539 0 : od->active_engine_index_async = ei;
540 0 : cm->enqueue_handlers[id] = ce->enqueue_handlers[id];
541 : }
542 0 : }
543 :
544 : int
545 0 : vnet_crypto_set_async_handler2 (char *alg_name, char *engine)
546 : {
547 : uword *p;
548 0 : vnet_crypto_main_t *cm = &crypto_main;
549 : vnet_crypto_async_alg_data_t *ad;
550 : int i;
551 :
552 0 : p = hash_get_mem (cm->async_alg_index_by_name, alg_name);
553 0 : if (!p)
554 0 : return -1;
555 :
556 0 : ad = vec_elt_at_index (cm->async_algs, p[0]);
557 :
558 0 : p = hash_get_mem (cm->engine_index_by_name, engine);
559 0 : if (!p)
560 0 : return -1;
561 :
562 0 : for (i = 0; i < VNET_CRYPTO_ASYNC_OP_N_TYPES; i++)
563 : {
564 : vnet_crypto_async_op_data_t *od;
565 0 : vnet_crypto_async_op_id_t id = ad->op_by_type[i];
566 0 : if (id == 0)
567 0 : continue;
568 :
569 0 : od = cm->async_opt_data + id;
570 0 : crypto_set_active_async_engine (od, id, p[0]);
571 : }
572 :
573 0 : vnet_crypto_update_cm_dequeue_handlers ();
574 :
575 0 : return 0;
576 : }
577 :
578 : u32
579 7267 : vnet_crypto_register_post_node (vlib_main_t * vm, char *post_node_name)
580 : {
581 7267 : vnet_crypto_main_t *cm = &crypto_main;
582 7267 : vnet_crypto_async_next_node_t *nn = 0;
583 : vlib_node_t *cc, *pn;
584 7267 : uword index = vec_len (cm->next_nodes);
585 :
586 7267 : pn = vlib_get_node_by_name (vm, (u8 *) post_node_name);
587 7267 : if (!pn)
588 0 : return ~0;
589 :
590 : /* *INDENT-OFF* */
591 50869 : vec_foreach (nn, cm->next_nodes)
592 : {
593 43602 : if (nn->node_idx == pn->index)
594 0 : return nn->next_idx;
595 : }
596 : /* *INDENT-ON* */
597 :
598 7267 : vec_validate (cm->next_nodes, index);
599 7267 : nn = vec_elt_at_index (cm->next_nodes, index);
600 :
601 7267 : cc = vlib_get_node_by_name (vm, (u8 *) "crypto-dispatch");
602 7267 : nn->next_idx = vlib_node_add_named_next (vm, cc->index, post_node_name);
603 7267 : nn->node_idx = pn->index;
604 :
605 7267 : return nn->next_idx;
606 : }
607 :
608 : int
609 0 : vnet_crypto_is_set_async_handler (vnet_crypto_async_op_id_t op)
610 : {
611 0 : vnet_crypto_main_t *cm = &crypto_main;
612 :
613 0 : return (op < vec_len (cm->enqueue_handlers) &&
614 0 : NULL != cm->enqueue_handlers[op]);
615 : }
616 :
617 : static void
618 6708 : vnet_crypto_init_cipher_data (vnet_crypto_alg_t alg, vnet_crypto_op_id_t eid,
619 : vnet_crypto_op_id_t did, char *name, u8 is_aead)
620 : {
621 : vnet_crypto_op_type_t eopt, dopt;
622 6708 : vnet_crypto_main_t *cm = &crypto_main;
623 :
624 6708 : cm->algs[alg].name = name;
625 6708 : cm->opt_data[eid].alg = cm->opt_data[did].alg = alg;
626 6708 : cm->opt_data[eid].active_engine_index_simple = ~0;
627 6708 : cm->opt_data[did].active_engine_index_simple = ~0;
628 6708 : cm->opt_data[eid].active_engine_index_chained = ~0;
629 6708 : cm->opt_data[did].active_engine_index_chained = ~0;
630 6708 : if (is_aead)
631 : {
632 2236 : eopt = VNET_CRYPTO_OP_TYPE_AEAD_ENCRYPT;
633 2236 : dopt = VNET_CRYPTO_OP_TYPE_AEAD_DECRYPT;
634 : }
635 : else
636 : {
637 4472 : eopt = VNET_CRYPTO_OP_TYPE_ENCRYPT;
638 4472 : dopt = VNET_CRYPTO_OP_TYPE_DECRYPT;
639 : }
640 6708 : cm->opt_data[eid].type = eopt;
641 6708 : cm->opt_data[did].type = dopt;
642 6708 : cm->algs[alg].op_by_type[eopt] = eid;
643 6708 : cm->algs[alg].op_by_type[dopt] = did;
644 13416 : hash_set_mem (cm->alg_index_by_name, name, alg);
645 6708 : }
646 :
647 : static void
648 2795 : vnet_crypto_init_hash_data (vnet_crypto_alg_t alg, vnet_crypto_op_id_t id,
649 : char *name)
650 : {
651 2795 : vnet_crypto_main_t *cm = &crypto_main;
652 2795 : cm->algs[alg].name = name;
653 2795 : cm->algs[alg].op_by_type[VNET_CRYPTO_OP_TYPE_HASH] = id;
654 2795 : cm->opt_data[id].alg = alg;
655 2795 : cm->opt_data[id].active_engine_index_simple = ~0;
656 2795 : cm->opt_data[id].active_engine_index_chained = ~0;
657 2795 : cm->opt_data[id].type = VNET_CRYPTO_OP_TYPE_HASH;
658 5590 : hash_set_mem (cm->alg_index_by_name, name, alg);
659 2795 : }
660 :
661 : static void
662 3354 : vnet_crypto_init_hmac_data (vnet_crypto_alg_t alg,
663 : vnet_crypto_op_id_t id, char *name)
664 : {
665 3354 : vnet_crypto_main_t *cm = &crypto_main;
666 3354 : cm->algs[alg].name = name;
667 3354 : cm->algs[alg].op_by_type[VNET_CRYPTO_OP_TYPE_HMAC] = id;
668 3354 : cm->opt_data[id].alg = alg;
669 3354 : cm->opt_data[id].active_engine_index_simple = ~0;
670 3354 : cm->opt_data[id].active_engine_index_chained = ~0;
671 3354 : cm->opt_data[id].type = VNET_CRYPTO_OP_TYPE_HMAC;
672 6708 : hash_set_mem (cm->alg_index_by_name, name, alg);
673 3354 : }
674 :
675 : static void
676 20124 : vnet_crypto_init_async_data (vnet_crypto_async_alg_t alg,
677 : vnet_crypto_async_op_id_t eid,
678 : vnet_crypto_async_op_id_t did, char *name)
679 : {
680 20124 : vnet_crypto_main_t *cm = &crypto_main;
681 :
682 20124 : cm->async_algs[alg].name = name;
683 20124 : cm->async_algs[alg].op_by_type[VNET_CRYPTO_ASYNC_OP_TYPE_ENCRYPT] = eid;
684 20124 : cm->async_algs[alg].op_by_type[VNET_CRYPTO_ASYNC_OP_TYPE_DECRYPT] = did;
685 20124 : cm->async_opt_data[eid].type = VNET_CRYPTO_ASYNC_OP_TYPE_ENCRYPT;
686 20124 : cm->async_opt_data[eid].alg = alg;
687 20124 : cm->async_opt_data[eid].active_engine_index_async = ~0;
688 20124 : cm->async_opt_data[eid].active_engine_index_async = ~0;
689 20124 : cm->async_opt_data[did].type = VNET_CRYPTO_ASYNC_OP_TYPE_DECRYPT;
690 20124 : cm->async_opt_data[did].alg = alg;
691 20124 : cm->async_opt_data[did].active_engine_index_async = ~0;
692 20124 : cm->async_opt_data[did].active_engine_index_async = ~0;
693 40248 : hash_set_mem (cm->async_alg_index_by_name, name, alg);
694 20124 : }
695 :
696 : clib_error_t *
697 559 : vnet_crypto_init (vlib_main_t * vm)
698 : {
699 559 : vnet_crypto_main_t *cm = &crypto_main;
700 559 : vlib_thread_main_t *tm = vlib_get_thread_main ();
701 559 : vnet_crypto_thread_t *ct = 0;
702 :
703 559 : cm->engine_index_by_name = hash_create_string ( /* size */ 0,
704 : sizeof (uword));
705 559 : cm->alg_index_by_name = hash_create_string (0, sizeof (uword));
706 559 : cm->async_alg_index_by_name = hash_create_string (0, sizeof (uword));
707 559 : vec_validate_aligned (cm->threads, tm->n_vlib_mains, CLIB_CACHE_LINE_BYTES);
708 1731 : vec_foreach (ct, cm->threads)
709 1172 : pool_init_fixed (ct->frame_pool, VNET_CRYPTO_FRAME_POOL_SIZE);
710 559 : vec_validate (cm->algs, VNET_CRYPTO_N_ALGS);
711 559 : vec_validate (cm->async_algs, VNET_CRYPTO_N_ASYNC_ALGS);
712 :
713 : #define _(n, s, l) \
714 : vnet_crypto_init_cipher_data (VNET_CRYPTO_ALG_##n, \
715 : VNET_CRYPTO_OP_##n##_ENC, \
716 : VNET_CRYPTO_OP_##n##_DEC, s, 0);
717 559 : foreach_crypto_cipher_alg;
718 : #undef _
719 : #define _(n, s, l) \
720 : vnet_crypto_init_cipher_data (VNET_CRYPTO_ALG_##n, \
721 : VNET_CRYPTO_OP_##n##_ENC, \
722 : VNET_CRYPTO_OP_##n##_DEC, s, 1);
723 559 : foreach_crypto_aead_alg;
724 : #undef _
725 : #define _(n, s) \
726 : vnet_crypto_init_hmac_data (VNET_CRYPTO_ALG_HMAC_##n, \
727 : VNET_CRYPTO_OP_##n##_HMAC, "hmac-" s);
728 559 : foreach_crypto_hmac_alg;
729 : #undef _
730 : #define _(n, s) \
731 : vnet_crypto_init_hash_data (VNET_CRYPTO_ALG_HASH_##n, \
732 : VNET_CRYPTO_OP_##n##_HASH, s);
733 559 : foreach_crypto_hash_alg;
734 : #undef _
735 : #define _(n, s, k, t, a) \
736 : vnet_crypto_init_async_data (VNET_CRYPTO_ALG_##n##_TAG##t##_AAD##a, \
737 : VNET_CRYPTO_OP_##n##_TAG##t##_AAD##a##_ENC, \
738 : VNET_CRYPTO_OP_##n##_TAG##t##_AAD##a##_DEC, \
739 : s);
740 559 : foreach_crypto_aead_async_alg
741 : #undef _
742 : #define _(c, h, s, k ,d) \
743 : vnet_crypto_init_async_data (VNET_CRYPTO_ALG_##c##_##h##_TAG##d, \
744 : VNET_CRYPTO_OP_##c##_##h##_TAG##d##_ENC, \
745 : VNET_CRYPTO_OP_##c##_##h##_TAG##d##_DEC, \
746 : s);
747 559 : foreach_crypto_link_async_alg
748 : #undef _
749 559 : cm->crypto_node_index =
750 559 : vlib_get_node_by_name (vm, (u8 *) "crypto-dispatch")->index;
751 :
752 559 : return 0;
753 : }
754 :
755 50399 : VLIB_INIT_FUNCTION (vnet_crypto_init);
756 :
757 : /*
758 : * fd.io coding-style-patch-verification: ON
759 : *
760 : * Local Variables:
761 : * eval: (c-set-style "gnu")
762 : * End:
763 : */
|