diff options
author | Damjan Marion <damarion@cisco.com> | 2019-04-24 15:20:35 +0200 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2019-04-25 01:36:12 +0000 |
commit | d1bed687231bb64cf7761da37431ba61bc32b6d8 (patch) | |
tree | 891af80a873db9dda53c18e95f5eeb9366a1cb07 /src/vnet | |
parent | 20bc56ab58189ad9fa24feaaca3e76ea8e636140 (diff) |
crypto: improve key handling
Change-Id: If96f661d507305da4b96cac7b1a8f14ba90676ad
Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/crypto/crypto.c | 78 | ||||
-rw-r--r-- | src/vnet/crypto/crypto.h | 51 | ||||
-rw-r--r-- | src/vnet/ipsec/esp.h | 3 | ||||
-rw-r--r-- | src/vnet/ipsec/esp_decrypt.c | 5 | ||||
-rw-r--r-- | src/vnet/ipsec/esp_encrypt.c | 5 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec.c | 13 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec.h | 2 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_if.c | 13 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_sa.c | 18 | ||||
-rw-r--r-- | src/vnet/ipsec/ipsec_sa.h | 10 | ||||
-rw-r--r-- | src/vnet/lisp-cp/control.c | 36 |
11 files changed, 208 insertions, 26 deletions
diff --git a/src/vnet/crypto/crypto.c b/src/vnet/crypto/crypto.c index dbdb58b16f6..b748e47fd3d 100644 --- a/src/vnet/crypto/crypto.c +++ b/src/vnet/crypto/crypto.c @@ -129,7 +129,7 @@ vnet_crypto_set_handler (char *alg_name, char *engine) return 0; } -vlib_error_t * +void vnet_crypto_register_ops_handler (vlib_main_t * vm, u32 engine_index, vnet_crypto_op_id_t opt, vnet_crypto_ops_handler_t * fn) @@ -145,7 +145,7 @@ vnet_crypto_register_ops_handler (vlib_main_t * vm, u32 engine_index, { otd->active_engine_index = engine_index; cm->ops_handlers[opt] = fn; - return 0; + return; } ae = vec_elt_at_index (cm->engines, otd->active_engine_index); if (ae->priority < e->priority) @@ -154,7 +154,79 @@ vnet_crypto_register_ops_handler (vlib_main_t * vm, u32 engine_index, cm->ops_handlers[opt] = fn; } - return 0; + return; +} + +void +vnet_crypto_register_key_handler (vlib_main_t * vm, u32 engine_index, + vnet_crypto_key_handler_t * key_handler) +{ + vnet_crypto_main_t *cm = &crypto_main; + vnet_crypto_engine_t *e = vec_elt_at_index (cm->engines, engine_index); + e->key_op_handler = key_handler; + return; +} + +u32 +vnet_crypto_key_add (vlib_main_t * vm, vnet_crypto_alg_t alg, u8 * data, + u16 length) +{ + u32 index; + vnet_crypto_main_t *cm = &crypto_main; + vnet_crypto_engine_t *engine; + vnet_crypto_key_t *key; + pool_get_zero (cm->keys, key); + index = key - cm->keys; + key->alg = alg; + vec_validate_aligned (key->data, length - 1, CLIB_CACHE_LINE_BYTES); + clib_memcpy (key->data, data, length); + + /* *INDENT-OFF* */ + vec_foreach (engine, cm->engines) + if (engine->key_op_handler) + engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_ADD, index); + /* *INDENT-ON* */ + return index; +} + +void +vnet_crypto_key_del (vlib_main_t * vm, vnet_crypto_key_index_t index) +{ + vnet_crypto_main_t *cm = &crypto_main; + vnet_crypto_engine_t *engine; + vnet_crypto_key_t *key = pool_elt_at_index (cm->keys, index); + + /* *INDENT-OFF* */ + vec_foreach (engine, cm->engines) + if (engine->key_op_handler) + engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_DEL, index); + /* *INDENT-ON* */ + + clib_memset (key->data, 0, vec_len (key->data)); + vec_free (key->data); + pool_put (cm->keys, key); +} + +void +vnet_crypto_key_modify (vlib_main_t * vm, vnet_crypto_key_index_t index, + vnet_crypto_alg_t alg, u8 * data, u16 length) +{ + vnet_crypto_main_t *cm = &crypto_main; + vnet_crypto_engine_t *engine; + vnet_crypto_key_t *key = pool_elt_at_index (cm->keys, index); + + if (vec_len (key->data)) + clib_memset (key->data, 0, vec_len (key->data)); + vec_free (key->data); + vec_validate_aligned (key->data, length - 1, CLIB_CACHE_LINE_BYTES); + clib_memcpy (key->data, data, length); + key->alg = alg; + + /* *INDENT-OFF* */ + vec_foreach (engine, cm->engines) + if (engine->key_op_handler) + engine->key_op_handler (vm, VNET_CRYPTO_KEY_OP_MODIFY, index); + /* *INDENT-ON* */ } static void diff --git a/src/vnet/crypto/crypto.h b/src/vnet/crypto/crypto.h index 901c363342b..6ab32ec22bf 100644 --- a/src/vnet/crypto/crypto.h +++ b/src/vnet/crypto/crypto.h @@ -68,6 +68,13 @@ typedef enum typedef enum { + VNET_CRYPTO_KEY_OP_ADD, + VNET_CRYPTO_KEY_OP_DEL, + VNET_CRYPTO_KEY_OP_MODIFY, +} vnet_crypto_key_op_t; + +typedef enum +{ #define _(n, s) VNET_CRYPTO_OP_STATUS_##n, foreach_crypto_op_status #undef _ @@ -77,6 +84,7 @@ typedef enum /* *INDENT-OFF* */ typedef enum { + VNET_CRYPTO_ALG_NONE = 0, #define _(n, s) VNET_CRYPTO_ALG_##n, foreach_crypto_cipher_alg foreach_crypto_aead_alg @@ -87,6 +95,12 @@ typedef enum VNET_CRYPTO_N_ALGS, } vnet_crypto_alg_t; +typedef struct +{ + u8 *data; + vnet_crypto_alg_t alg:8; +} vnet_crypto_key_t; + typedef enum { VNET_CRYPTO_OP_NONE = 0, @@ -115,10 +129,10 @@ typedef struct u8 flags; #define VNET_CRYPTO_OP_FLAG_INIT_IV (1 << 0) #define VNET_CRYPTO_OP_FLAG_HMAC_CHECK (1 << 1) + u32 key_index; u32 len, salt; u16 aad_len; - u8 key_len, iv_len, digest_len, tag_len; - u8 *key; + u8 iv_len, digest_len, tag_len; u8 *iv; u8 *src; u8 *dst; @@ -141,23 +155,30 @@ typedef struct clib_bitmap_t *act_queues; } vnet_crypto_thread_t; +typedef u32 vnet_crypto_key_index_t; + typedef u32 (vnet_crypto_ops_handler_t) (vlib_main_t * vm, vnet_crypto_op_t * ops[], u32 n_ops); +typedef void (vnet_crypto_key_handler_t) (vlib_main_t * vm, + vnet_crypto_key_op_t kop, + vnet_crypto_key_index_t idx); + u32 vnet_crypto_register_engine (vlib_main_t * vm, char *name, int prio, char *desc); -vlib_error_t *vnet_crypto_register_ops_handler (vlib_main_t * vm, - u32 provider_index, - vnet_crypto_op_id_t opt, - vnet_crypto_ops_handler_t * - f); +void vnet_crypto_register_ops_handler (vlib_main_t * vm, u32 engine_index, + vnet_crypto_op_id_t opt, + vnet_crypto_ops_handler_t * oph); +void vnet_crypto_register_key_handler (vlib_main_t * vm, u32 engine_index, + vnet_crypto_key_handler_t * keyh); typedef struct { char *name; char *desc; int priority; + vnet_crypto_key_handler_t *key_op_handler; vnet_crypto_ops_handler_t *ops_handlers[VNET_CRYPTO_N_OP_IDS]; } vnet_crypto_engine_t; @@ -168,6 +189,7 @@ typedef struct vnet_crypto_ops_handler_t **ops_handlers; vnet_crypto_op_data_t opt_data[VNET_CRYPTO_N_OP_IDS]; vnet_crypto_engine_t *engines; + vnet_crypto_key_t *keys; uword *engine_index_by_name; uword *alg_index_by_name; } vnet_crypto_main_t; @@ -180,9 +202,14 @@ 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); +u32 vnet_crypto_key_add (vlib_main_t * vm, vnet_crypto_alg_t alg, + u8 * data, u16 length); +void vnet_crypto_key_del (vlib_main_t * vm, vnet_crypto_key_index_t index); +void vnet_crypto_key_modify (vlib_main_t * vm, vnet_crypto_key_index_t index, + vnet_crypto_alg_t alg, u8 * data, u16 len); + format_function_t format_vnet_crypto_alg; format_function_t format_vnet_crypto_engine; format_function_t format_vnet_crypto_op; @@ -197,6 +224,7 @@ vnet_crypto_op_init (vnet_crypto_op_t * op, vnet_crypto_op_id_t type) clib_memset (op, 0xfe, sizeof (*op)); op->op = type; op->flags = 0; + op->key_index = ~0; } static_always_inline vnet_crypto_op_type_t @@ -207,6 +235,13 @@ vnet_crypto_get_op_type (vnet_crypto_op_id_t id) return od->type; } +static_always_inline vnet_crypto_key_t * +vnet_crypto_get_key (vnet_crypto_key_index_t index) +{ + vnet_crypto_main_t *cm = &crypto_main; + return vec_elt_at_index (cm->keys, index); +} + #endif /* included_vnet_crypto_crypto_h */ /* diff --git a/src/vnet/ipsec/esp.h b/src/vnet/ipsec/esp.h index 052bbfc1d88..070726faa34 100644 --- a/src/vnet/ipsec/esp.h +++ b/src/vnet/ipsec/esp.h @@ -112,8 +112,7 @@ hmac_calc (vlib_main_t * vm, ipsec_sa_t * sa, u8 * data, int data_len, return 0; vnet_crypto_op_init (op, sa->integ_op_id); - op->key = sa->integ_key.data; - op->key_len = sa->integ_key.len; + op->key_index = sa->integ_key_index; op->src = data; op->len = data_len; op->digest = signature; diff --git a/src/vnet/ipsec/esp_decrypt.c b/src/vnet/ipsec/esp_decrypt.c index e74c1bb908a..5d1f20604d5 100644 --- a/src/vnet/ipsec/esp_decrypt.c +++ b/src/vnet/ipsec/esp_decrypt.c @@ -203,8 +203,7 @@ esp_decrypt_inline (vlib_main_t * vm, vec_add2_aligned (ptd->integ_ops, op, 1, CLIB_CACHE_LINE_BYTES); vnet_crypto_op_init (op, sa0->integ_op_id); - op->key = sa0->integ_key.data; - op->key_len = sa0->integ_key.len; + op->key_index = sa0->integ_key_index; op->src = payload; op->flags = VNET_CRYPTO_OP_FLAG_HMAC_CHECK; op->user_data = b - bufs; @@ -231,7 +230,7 @@ esp_decrypt_inline (vlib_main_t * vm, vnet_crypto_op_t *op; vec_add2_aligned (ptd->crypto_ops, op, 1, CLIB_CACHE_LINE_BYTES); vnet_crypto_op_init (op, sa0->crypto_dec_op_id); - op->key = sa0->crypto_key.data; + op->key_index = sa0->crypto_key_index; op->iv = payload; if (ipsec_sa_is_set_IS_AEAD (sa0)) diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index 5db10b520e3..af56302bafb 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -441,7 +441,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vnet_crypto_op_init (op, sa0->crypto_enc_op_id); op->iv = payload - iv_sz; op->src = op->dst = payload; - op->key = sa0->crypto_key.data; + op->key_index = sa0->crypto_key_index; op->len = payload_len - icv_sz; op->flags = VNET_CRYPTO_OP_FLAG_INIT_IV; op->user_data = b - bufs; @@ -469,8 +469,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vnet_crypto_op_init (op, sa0->integ_op_id); op->src = payload - iv_sz - sizeof (esp_header_t); op->digest = payload + payload_len - icv_sz; - op->key = sa0->integ_key.data; - op->key_len = sa0->integ_key.len; + op->key_index = sa0->integ_key_index; op->digest_len = icv_sz; op->len = payload_len - icv_sz + iv_sz + sizeof (esp_header_t); op->user_data = b - bufs; diff --git a/src/vnet/ipsec/ipsec.c b/src/vnet/ipsec/ipsec.c index 73c5cf4d7ab..c530a44e870 100644 --- a/src/vnet/ipsec/ipsec.c +++ b/src/vnet/ipsec/ipsec.c @@ -264,43 +264,51 @@ ipsec_init (vlib_main_t * vm) a = im->crypto_algs + IPSEC_CRYPTO_ALG_DES_CBC; a->enc_op_id = VNET_CRYPTO_OP_DES_CBC_ENC; a->dec_op_id = VNET_CRYPTO_OP_DES_CBC_DEC; + a->alg = VNET_CRYPTO_ALG_DES_CBC; a->iv_size = a->block_size = 8; a = im->crypto_algs + IPSEC_CRYPTO_ALG_3DES_CBC; a->enc_op_id = VNET_CRYPTO_OP_3DES_CBC_ENC; a->dec_op_id = VNET_CRYPTO_OP_3DES_CBC_DEC; + a->alg = VNET_CRYPTO_ALG_3DES_CBC; a->iv_size = a->block_size = 8; a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_CBC_128; a->enc_op_id = VNET_CRYPTO_OP_AES_128_CBC_ENC; a->dec_op_id = VNET_CRYPTO_OP_AES_128_CBC_DEC; + a->alg = VNET_CRYPTO_ALG_AES_128_CBC; a->iv_size = a->block_size = 16; a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_CBC_192; a->enc_op_id = VNET_CRYPTO_OP_AES_192_CBC_ENC; a->dec_op_id = VNET_CRYPTO_OP_AES_192_CBC_DEC; + a->alg = VNET_CRYPTO_ALG_AES_192_CBC; a->iv_size = a->block_size = 16; a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_CBC_256; a->enc_op_id = VNET_CRYPTO_OP_AES_256_CBC_ENC; a->dec_op_id = VNET_CRYPTO_OP_AES_256_CBC_DEC; + a->alg = VNET_CRYPTO_ALG_AES_256_CBC; a->iv_size = a->block_size = 16; a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_GCM_128; a->enc_op_id = VNET_CRYPTO_OP_AES_128_GCM_ENC; a->dec_op_id = VNET_CRYPTO_OP_AES_128_GCM_DEC; + a->alg = VNET_CRYPTO_ALG_AES_128_GCM; a->iv_size = a->block_size = 8; a->icv_size = 16; a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_GCM_192; a->enc_op_id = VNET_CRYPTO_OP_AES_192_GCM_ENC; a->dec_op_id = VNET_CRYPTO_OP_AES_192_GCM_DEC; + a->alg = VNET_CRYPTO_ALG_AES_192_GCM; a->iv_size = a->block_size = 8; a->icv_size = 16; a = im->crypto_algs + IPSEC_CRYPTO_ALG_AES_GCM_256; a->enc_op_id = VNET_CRYPTO_OP_AES_256_GCM_ENC; a->dec_op_id = VNET_CRYPTO_OP_AES_256_GCM_DEC; + a->alg = VNET_CRYPTO_ALG_AES_256_GCM; a->iv_size = a->block_size = 8; a->icv_size = 16; @@ -309,22 +317,27 @@ ipsec_init (vlib_main_t * vm) i = &im->integ_algs[IPSEC_INTEG_ALG_SHA1_96]; i->op_id = VNET_CRYPTO_OP_SHA1_HMAC; + i->alg = VNET_CRYPTO_ALG_HMAC_SHA1; i->icv_size = 12; i = &im->integ_algs[IPSEC_INTEG_ALG_SHA_256_96]; i->op_id = VNET_CRYPTO_OP_SHA1_HMAC; + i->alg = VNET_CRYPTO_ALG_HMAC_SHA256; i->icv_size = 12; i = &im->integ_algs[IPSEC_INTEG_ALG_SHA_256_128]; i->op_id = VNET_CRYPTO_OP_SHA256_HMAC; + i->alg = VNET_CRYPTO_ALG_HMAC_SHA256; i->icv_size = 16; i = &im->integ_algs[IPSEC_INTEG_ALG_SHA_384_192]; i->op_id = VNET_CRYPTO_OP_SHA384_HMAC; + i->alg = VNET_CRYPTO_ALG_HMAC_SHA512; i->icv_size = 24; i = &im->integ_algs[IPSEC_INTEG_ALG_SHA_512_256]; i->op_id = VNET_CRYPTO_OP_SHA512_HMAC; + i->alg = VNET_CRYPTO_ALG_HMAC_SHA512; i->icv_size = 32; vec_validate_aligned (im->ptd, vlib_num_workers (), CLIB_CACHE_LINE_BYTES); diff --git a/src/vnet/ipsec/ipsec.h b/src/vnet/ipsec/ipsec.h index 110bbcb3e5a..232390c0690 100644 --- a/src/vnet/ipsec/ipsec.h +++ b/src/vnet/ipsec/ipsec.h @@ -68,6 +68,7 @@ typedef struct { vnet_crypto_op_id_t enc_op_id; vnet_crypto_op_id_t dec_op_id; + vnet_crypto_alg_t alg; u8 iv_size; u8 block_size; u8 icv_size; @@ -76,6 +77,7 @@ typedef struct typedef struct { vnet_crypto_op_id_t op_id; + vnet_crypto_alg_t alg; u8 icv_size; } ipsec_main_integ_alg_t; diff --git a/src/vnet/ipsec/ipsec_if.c b/src/vnet/ipsec/ipsec_if.c index 8d0eef21ae0..9f64634c51e 100644 --- a/src/vnet/ipsec/ipsec_if.c +++ b/src/vnet/ipsec/ipsec_if.c @@ -510,6 +510,7 @@ int ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index, ipsec_if_set_key_type_t type, u8 alg, u8 * key) { + vlib_main_t *vm = vlib_get_main (); ipsec_main_t *im = &ipsec_main; vnet_hw_interface_t *hi; ipsec_tunnel_if_t *t; @@ -526,24 +527,36 @@ ipsec_set_interface_key (vnet_main_t * vnm, u32 hw_if_index, sa = pool_elt_at_index (im->sad, t->output_sa_index); ipsec_sa_set_crypto_alg (sa, alg); ipsec_mk_key (&sa->crypto_key, key, vec_len (key)); + sa->crypto_calg = im->crypto_algs[alg].alg; + vnet_crypto_key_modify (vm, sa->crypto_key_index, sa->crypto_calg, + key, vec_len (key)); } else if (type == IPSEC_IF_SET_KEY_TYPE_LOCAL_INTEG) { sa = pool_elt_at_index (im->sad, t->output_sa_index); ipsec_sa_set_integ_alg (sa, alg); ipsec_mk_key (&sa->integ_key, key, vec_len (key)); + sa->integ_calg = im->integ_algs[alg].alg; + vnet_crypto_key_modify (vm, sa->integ_key_index, sa->integ_calg, + key, vec_len (key)); } else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_CRYPTO) { sa = pool_elt_at_index (im->sad, t->input_sa_index); ipsec_sa_set_crypto_alg (sa, alg); ipsec_mk_key (&sa->crypto_key, key, vec_len (key)); + sa->crypto_calg = im->crypto_algs[alg].alg; + vnet_crypto_key_modify (vm, sa->crypto_key_index, sa->crypto_calg, + key, vec_len (key)); } else if (type == IPSEC_IF_SET_KEY_TYPE_REMOTE_INTEG) { sa = pool_elt_at_index (im->sad, t->input_sa_index); ipsec_sa_set_integ_alg (sa, alg); ipsec_mk_key (&sa->integ_key, key, vec_len (key)); + sa->integ_calg = im->integ_algs[alg].alg; + vnet_crypto_key_modify (vm, sa->integ_key_index, sa->integ_calg, + key, vec_len (key)); } else return VNET_API_ERROR_INVALID_VALUE; diff --git a/src/vnet/ipsec/ipsec_sa.c b/src/vnet/ipsec/ipsec_sa.c index 8f41c95159b..2d2e90a1d27 100644 --- a/src/vnet/ipsec/ipsec_sa.c +++ b/src/vnet/ipsec/ipsec_sa.c @@ -100,6 +100,7 @@ ipsec_sa_set_crypto_alg (ipsec_sa_t * sa, ipsec_crypto_alg_t crypto_alg) sa->crypto_block_size = im->crypto_algs[crypto_alg].block_size; sa->crypto_enc_op_id = im->crypto_algs[crypto_alg].enc_op_id; sa->crypto_dec_op_id = im->crypto_algs[crypto_alg].dec_op_id; + sa->crypto_calg = im->crypto_algs[crypto_alg].alg; ASSERT (sa->crypto_iv_size <= ESP_MAX_IV_SIZE); ASSERT (sa->crypto_block_size <= ESP_MAX_BLOCK_SIZE); if (IPSEC_CRYPTO_ALG_IS_GCM (crypto_alg)) @@ -116,6 +117,7 @@ ipsec_sa_set_integ_alg (ipsec_sa_t * sa, ipsec_integ_alg_t integ_alg) sa->integ_alg = integ_alg; sa->integ_icv_size = im->integ_algs[integ_alg].icv_size; sa->integ_op_id = im->integ_algs[integ_alg].op_id; + sa->integ_calg = im->integ_algs[integ_alg].alg; ASSERT (sa->integ_icv_size <= ESP_MAX_ICV_SIZE); } @@ -133,6 +135,7 @@ ipsec_sa_add (u32 id, const ip46_address_t * tun_src, const ip46_address_t * tun_dst, u32 * sa_out_index) { + vlib_main_t *vm = vlib_get_main (); ipsec_main_t *im = &ipsec_main; clib_error_t *err; ipsec_sa_t *sa; @@ -164,6 +167,13 @@ ipsec_sa_add (u32 id, ip46_address_copy (&sa->tunnel_src_addr, tun_src); ip46_address_copy (&sa->tunnel_dst_addr, tun_dst); + sa->crypto_key_index = vnet_crypto_key_add (vm, + im->crypto_algs[crypto_alg].alg, + (u8 *) ck->data, ck->len); + sa->integ_key_index = vnet_crypto_key_add (vm, + im->integ_algs[integ_alg].alg, + (u8 *) ik->data, ik->len); + err = ipsec_check_support_cb (im, sa); if (err) { @@ -253,6 +263,7 @@ ipsec_sa_add (u32 id, u32 ipsec_sa_del (u32 id) { + vlib_main_t *vm = vlib_get_main (); ipsec_main_t *im = &ipsec_main; ipsec_sa_t *sa = 0; uword *p; @@ -286,6 +297,8 @@ ipsec_sa_del (u32 id) dpo_reset (&sa->dpo[IPSEC_PROTOCOL_AH]); dpo_reset (&sa->dpo[IPSEC_PROTOCOL_ESP]); } + vnet_crypto_key_del (vm, sa->crypto_key_index); + vnet_crypto_key_del (vm, sa->integ_key_index); pool_put (im->sad, sa); return 0; } @@ -320,6 +333,7 @@ ipsec_is_sa_used (u32 sa_index) int ipsec_set_sa_key (u32 id, const ipsec_key_t * ck, const ipsec_key_t * ik) { + vlib_main_t *vm = vlib_get_main (); ipsec_main_t *im = &ipsec_main; uword *p; u32 sa_index; @@ -337,12 +351,16 @@ ipsec_set_sa_key (u32 id, const ipsec_key_t * ck, const ipsec_key_t * ik) if (ck) { clib_memcpy (&sa->crypto_key, ck, sizeof (sa->crypto_key)); + vnet_crypto_key_modify (vm, sa->crypto_key_index, sa->crypto_calg, + (u8 *) ck->data, ck->len); } /* new integ key */ if (ik) { clib_memcpy (&sa->integ_key, 0, sizeof (sa->integ_key)); + vnet_crypto_key_modify (vm, sa->integ_key_index, sa->integ_calg, + (u8 *) ik->data, ik->len); } if (ck || ik) diff --git a/src/vnet/ipsec/ipsec_sa.h b/src/vnet/ipsec/ipsec_sa.h index d1b44c3165f..40850766ce1 100644 --- a/src/vnet/ipsec/ipsec_sa.h +++ b/src/vnet/ipsec/ipsec_sa.h @@ -125,9 +125,11 @@ typedef struct u32 last_seq_hi; u64 replay_window; - vnet_crypto_op_id_t crypto_enc_op_id; - vnet_crypto_op_id_t crypto_dec_op_id; - vnet_crypto_op_id_t integ_op_id; + vnet_crypto_key_index_t crypto_key_index; + vnet_crypto_key_index_t integ_key_index; + vnet_crypto_op_id_t crypto_enc_op_id:16; + vnet_crypto_op_id_t crypto_dec_op_id:16; + vnet_crypto_op_id_t integ_op_id:16; dpo_id_t dpo[IPSEC_N_PROTOCOLS]; @@ -149,9 +151,11 @@ typedef struct ipsec_crypto_alg_t crypto_alg; ipsec_key_t crypto_key; + vnet_crypto_alg_t crypto_calg; ipsec_integ_alg_t integ_alg; ipsec_key_t integ_key; + vnet_crypto_alg_t integ_calg; ip46_address_t tunnel_src_addr; ip46_address_t tunnel_dst_addr; diff --git a/src/vnet/lisp-cp/control.c b/src/vnet/lisp-cp/control.c index 340217c661e..f8e9c1d5b44 100644 --- a/src/vnet/lisp-cp/control.c +++ b/src/vnet/lisp-cp/control.c @@ -2725,6 +2725,22 @@ build_map_register_record_list (lisp_cp_main_t * lcm) return recs; } +static vnet_crypto_alg_t +lisp_key_type_to_crypto_alg (lisp_key_type_t key_id) +{ + switch (key_id) + { + case HMAC_SHA_1_96: + return VNET_CRYPTO_ALG_HMAC_SHA1; + case HMAC_SHA_256_128: + return VNET_CRYPTO_ALG_HMAC_SHA256; + default: + clib_warning ("unsupported encryption key type: %d!", key_id); + break; + } + return VNET_CRYPTO_ALG_NONE; +} + static vnet_crypto_op_id_t lisp_key_type_to_crypto_op (lisp_key_type_t key_id) { @@ -2750,17 +2766,23 @@ update_map_register_auth_data (map_register_hdr_t * map_reg_hdr, MREG_KEY_ID (map_reg_hdr) = clib_host_to_net_u16 (key_id); MREG_AUTH_DATA_LEN (map_reg_hdr) = clib_host_to_net_u16 (auth_data_len); vnet_crypto_op_t _op, *op = &_op; + vnet_crypto_key_index_t ki; vnet_crypto_op_init (op, lisp_key_type_to_crypto_op (key_id)); - op->key = key; - op->key_len = vec_len (key); op->len = msg_len; op->digest = MREG_DATA (map_reg_hdr); op->src = (u8 *) map_reg_hdr; op->digest_len = 0; op->iv = 0; + ki = vnet_crypto_key_add (lcm->vlib_main, + lisp_key_type_to_crypto_alg (key_id), key, + vec_len (key)); + + op->key_index = ki; + vnet_crypto_process_ops (lcm->vlib_main, op, 1); + vnet_crypto_key_del (lcm->vlib_main, ki); return 0; } @@ -3926,6 +3948,7 @@ is_auth_data_valid (map_notify_hdr_t * h, u32 msg_len, u16 auth_data_len; int result; vnet_crypto_op_t _op, *op = &_op; + vnet_crypto_key_index_t ki; u8 out[EVP_MAX_MD_SIZE] = { 0, }; auth_data_len = auth_data_len_by_key_id (key_id); @@ -3943,15 +3966,20 @@ is_auth_data_valid (map_notify_hdr_t * h, u32 msg_len, clib_memset (MNOTIFY_DATA (h), 0, auth_data_len); vnet_crypto_op_init (op, lisp_key_type_to_crypto_op (key_id)); - op->key = key; - op->key_len = vec_len (key); op->len = msg_len; op->digest = out; op->src = (u8 *) h; op->digest_len = 0; op->iv = 0; + ki = vnet_crypto_key_add (lcm->vlib_main, + lisp_key_type_to_crypto_alg (key_id), key, + vec_len (key)); + + op->key_index = ki; + vnet_crypto_process_ops (lcm->vlib_main, op, 1); + vnet_crypto_key_del (lcm->vlib_main, ki); result = memcmp (out, auth_data, auth_data_len); |