LCOV - code coverage report
Current view: top level - vnet/crypto - crypto.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 310 359 86.4 %
Date: 2023-07-05 22:20:52 Functions: 31 34 91.2 %

          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             :  */

Generated by: LCOV version 1.14