LCOV - code coverage report
Current view: top level - vnet/crypto - crypto.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 311 371 83.8 %
Date: 2023-10-26 01:39:38 Functions: 31 35 88.6 %

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

Generated by: LCOV version 1.14