From 1469d54fcfe2d78fa45d40fd0c850955a2c29da7 Mon Sep 17 00:00:00 2001 From: Filip Tehlar Date: Mon, 25 Mar 2019 09:04:41 -0700 Subject: crypto: add set crypto handler CLI Change-Id: I40124f8d6e529256b1ccc6eb78dda9c5119b8951 Signed-off-by: Filip Tehlar --- src/vnet/crypto/cli.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ src/vnet/crypto/crypto.c | 55 +++++++++++++++++++++++++++----- src/vnet/crypto/crypto.h | 5 +++ 3 files changed, 135 insertions(+), 8 deletions(-) diff --git a/src/vnet/crypto/cli.c b/src/vnet/crypto/cli.c index d93577ed113..792cc4bf243 100644 --- a/src/vnet/crypto/cli.c +++ b/src/vnet/crypto/cli.c @@ -92,6 +92,89 @@ VLIB_CLI_COMMAND (show_crypto_handlers_command, static) = }; /* *INDENT-ON* */ +static clib_error_t * +set_crypto_handler_command_fn (vlib_main_t * vm, + unformat_input_t * input, + vlib_cli_command_t * cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + vnet_crypto_main_t *cm = &crypto_main; + int rc = 0; + char **args = 0, *s, **arg, *engine = 0; + int all = 0; + clib_error_t *error = 0; + + if (!unformat_user (input, unformat_line_input, line_input)) + return 0; + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "all")) + all = 1; + else if (unformat (line_input, "%s", &s)) + vec_add1 (args, s); + else + { + error = clib_error_return (0, "invalid params"); + goto done; + } + } + + if ((vec_len (args) < 2 && !all) || (vec_len (args) == 0 && all)) + { + error = clib_error_return (0, "missing cipher or engine!"); + goto done; + } + + engine = vec_elt_at_index (args, vec_len (args) - 1)[0]; + vec_del1 (args, vec_len (args) - 1); + + if (all) + { + char *key; + u8 *value; + + /* *INDENT-OFF* */ + hash_foreach_mem (key, value, cm->ops_handler_index_by_name, + ({ + (void) value; + rc += vnet_crypto_set_handler (key, engine); + })); + /* *INDENT-ON* */ + + if (rc) + vlib_cli_output (vm, "failed to set crypto engine!"); + } + else + { + vec_foreach (arg, args) + { + rc = vnet_crypto_set_handler (arg[0], engine); + if (rc) + { + vlib_cli_output (vm, "failed to set engine %s for %s!", + engine, arg[0]); + } + } + } + +done: + vec_free (engine); + vec_foreach (arg, args) vec_free (arg[0]); + vec_free (args); + unformat_free (line_input); + return error; +} + +/* *INDENT-OFF* */ +VLIB_CLI_COMMAND (set_crypto_handler_command, static) = +{ + .path = "set crypto handler", + .short_help = "set crypto handler cipher [cipher2 cipher3 ...] engine", + .function = set_crypto_handler_command_fn, +}; +/* *INDENT-ON* */ + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vnet/crypto/crypto.c b/src/vnet/crypto/crypto.c index a6f45be053f..ceedc93bbaf 100644 --- a/src/vnet/crypto/crypto.c +++ b/src/vnet/crypto/crypto.c @@ -51,9 +51,38 @@ vnet_crypto_register_engine (vlib_main_t * vm, char *name, int prio, p->desc = desc; p->priority = prio; + hash_set_mem (cm->engine_index_by_name, p->name, p - cm->engines); + return p - cm->engines; } +int +vnet_crypto_set_handler (char *ops_handler_name, char *engine) +{ + uword *p; + vnet_crypto_main_t *cm = &crypto_main; + vnet_crypto_op_type_t ot; + vnet_crypto_op_type_data_t *otd; + vnet_crypto_engine_t *ce; + + p = hash_get_mem (cm->ops_handler_index_by_name, ops_handler_name); + if (!p) + return -1; + + ot = p[0]; + otd = cm->opt_data + ot; + + p = hash_get_mem (cm->engine_index_by_name, engine); + if (!p) + return -1; + + ce = cm->engines + p[0]; + otd->active_engine_index = p[0]; + cm->ops_handlers[ot] = ce->ops_handlers[ot]; + + return 0; +} + vlib_error_t * vnet_crypto_register_ops_handler (vlib_main_t * vm, u32 engine_index, vnet_crypto_op_type_t opt, @@ -87,9 +116,13 @@ vnet_crypto_init (vlib_main_t * vm) { vnet_crypto_main_t *cm = &crypto_main; vlib_thread_main_t *tm = vlib_get_thread_main (); - const char *enc = "encrypt"; - const char *dec = "decrypt"; - const char *hmac = "hmac"; +#define CRYPTO_ENC_STR "encrypt" +#define CRYPTO_DEC_STR "decrypt" +#define CRYPTO_HMAC_STR "hmac" + + cm->engine_index_by_name = hash_create_string ( /* size */ 0, + sizeof (uword)); + cm->ops_handler_index_by_name = hash_create_string (0, sizeof (uword)); vec_validate_aligned (cm->threads, tm->n_vlib_mains, CLIB_CACHE_LINE_BYTES); vec_validate (cm->algs, VNET_CRYPTO_N_ALGS); @@ -98,18 +131,24 @@ vnet_crypto_init (vlib_main_t * vm) cm->algs[VNET_CRYPTO_ALG_##n].name = s; \ cm->opt_data[VNET_CRYPTO_OP_##n##_ENC].alg = VNET_CRYPTO_ALG_##n; \ cm->opt_data[VNET_CRYPTO_OP_##n##_DEC].alg = VNET_CRYPTO_ALG_##n; \ - cm->opt_data[VNET_CRYPTO_OP_##n##_ENC].desc = enc; \ - cm->opt_data[VNET_CRYPTO_OP_##n##_DEC].desc = dec; \ + cm->opt_data[VNET_CRYPTO_OP_##n##_ENC].desc = CRYPTO_ENC_STR; \ + cm->opt_data[VNET_CRYPTO_OP_##n##_DEC].desc = CRYPTO_DEC_STR; \ cm->opt_data[VNET_CRYPTO_OP_##n##_ENC].active_engine_index = ~0; \ - cm->opt_data[VNET_CRYPTO_OP_##n##_DEC].active_engine_index = ~0; + cm->opt_data[VNET_CRYPTO_OP_##n##_DEC].active_engine_index = ~0; \ + hash_set_mem (cm->ops_handler_index_by_name, CRYPTO_ENC_STR "-" s, \ + VNET_CRYPTO_OP_##n##_ENC); \ + hash_set_mem (cm->ops_handler_index_by_name, CRYPTO_DEC_STR "-" s, \ + VNET_CRYPTO_OP_##n##_DEC); foreach_crypto_alg; #undef _ #define _(n, s) \ cm->algs[VNET_CRYPTO_ALG_##n].name = s; \ cm->opt_data[VNET_CRYPTO_OP_##n##_HMAC].alg = VNET_CRYPTO_ALG_##n; \ - cm->opt_data[VNET_CRYPTO_OP_##n##_HMAC].desc = hmac; \ - cm->opt_data[VNET_CRYPTO_OP_##n##_HMAC].active_engine_index = ~0; + cm->opt_data[VNET_CRYPTO_OP_##n##_HMAC].desc = CRYPTO_HMAC_STR; \ + cm->opt_data[VNET_CRYPTO_OP_##n##_HMAC].active_engine_index = ~0; \ + hash_set_mem (cm->ops_handler_index_by_name, CRYPTO_HMAC_STR "-" s, \ + VNET_CRYPTO_OP_##n##_HMAC); foreach_hmac_alg; #undef _ diff --git a/src/vnet/crypto/crypto.h b/src/vnet/crypto/crypto.h index 4ce4d254725..ad6286ccfcb 100644 --- a/src/vnet/crypto/crypto.h +++ b/src/vnet/crypto/crypto.h @@ -140,6 +140,8 @@ typedef struct vnet_crypto_ops_handler_t **ops_handlers; vnet_crypto_op_type_data_t opt_data[VNET_CRYPTO_N_OP_TYPES]; vnet_crypto_engine_t *engines; + uword *engine_index_by_name; + uword *ops_handler_index_by_name; } vnet_crypto_main_t; extern vnet_crypto_main_t crypto_main; @@ -150,6 +152,9 @@ u32 vnet_crypto_submit_ops (vlib_main_t * vm, vnet_crypto_op_t ** jobs, u32 vnet_crypto_process_ops (vlib_main_t * vm, vnet_crypto_op_t ops[], u32 n_ops); + +int vnet_crypto_set_handler (char *ops_handler_name, char *engine); + format_function_t format_vnet_crypto_alg; format_function_t format_vnet_crypto_engine; format_function_t format_vnet_crypto_op; -- cgit 1.2.3-korg