X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fipsec%2Fesp_encrypt.c;h=5db10b520e3977350591e25bb0dbc7877960aebe;hb=1b582b8e9264ca2514a5118ca0de0a3a5b8f5ba4;hp=c2069e52b33339a6c5cbc5c6a83705542a0a8a5d;hpb=a03d18238350f9941357caca28957395ad737810;p=vpp.git diff --git a/src/vnet/ipsec/esp_encrypt.c b/src/vnet/ipsec/esp_encrypt.c index c2069e52b33..5db10b520e3 100644 --- a/src/vnet/ipsec/esp_encrypt.c +++ b/src/vnet/ipsec/esp_encrypt.c @@ -112,19 +112,26 @@ esp_add_footer_and_icv (vlib_buffer_t * b, u8 block_size, u8 icv_sz) static_always_inline void esp_update_ip4_hdr (ip4_header_t * ip4, u16 len, int is_transport, int is_udp) { - ip_csum_t sum = ip4->checksum; - u16 old_len = 0; + ip_csum_t sum; + u16 old_len; + + len = clib_net_to_host_u16 (len); + old_len = ip4->length; if (is_transport) { u8 prot = is_udp ? IP_PROTOCOL_UDP : IP_PROTOCOL_IPSEC_ESP; - old_len = ip4->length; - sum = ip_csum_update (sum, ip4->protocol, prot, ip4_header_t, protocol); + + sum = ip_csum_update (ip4->checksum, ip4->protocol, + prot, ip4_header_t, protocol); ip4->protocol = prot; + + sum = ip_csum_update (sum, old_len, len, ip4_header_t, length); } + else + sum = ip_csum_update (ip4->checksum, old_len, len, ip4_header_t, length); - ip4->length = len = clib_net_to_host_u16 (len); - sum = ip_csum_update (ip4->checksum, old_len, len, ip4_header_t, length); + ip4->length = len; ip4->checksum = ip_csum_fold (sum); } @@ -280,7 +287,7 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, current_sa_packets = current_sa_bytes = 0; spi = clib_net_to_host_u32 (sa0->spi); block_sz = sa0->crypto_block_size; - icv_sz = sa0->integ_trunc_size; + icv_sz = sa0->integ_icv_size; iv_sz = sa0->crypto_iv_size; } @@ -402,14 +409,16 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, ip6_header_t *ip6 = (ip6_header_t *) (ip_hdr); *next_hdr_ptr = ip6->protocol; ip6->protocol = IP_PROTOCOL_IPSEC_ESP; - ip6->payload_length = payload_len + hdr_len - l2_len - ip_len; + ip6->payload_length = + clib_host_to_net_u16 (payload_len + hdr_len - l2_len - + ip_len); } else { u16 len; ip4_header_t *ip4 = (ip4_header_t *) (ip_hdr); *next_hdr_ptr = ip4->protocol; - len = payload_len + hdr_len + l2_len; + len = payload_len + hdr_len - l2_len; if (udp) { esp_update_ip4_hdr (ip4, len, /* is_transport */ 1, 1); @@ -425,35 +434,50 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, esp->spi = spi; esp->seq = clib_net_to_host_u32 (sa0->seq); - if (sa0->crypto_enc_op_type) + if (sa0->crypto_enc_op_id) { vnet_crypto_op_t *op; vec_add2_aligned (ptd->crypto_ops, op, 1, CLIB_CACHE_LINE_BYTES); - vnet_crypto_op_init (op, sa0->crypto_enc_op_type); + 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->len = payload_len - icv_sz; op->flags = VNET_CRYPTO_OP_FLAG_INIT_IV; op->user_data = b - bufs; + op->salt = sa0->salt; + + if (ipsec_sa_is_set_IS_AEAD (sa0)) + { + /* + * construct the AAD in a scratch space in front + * of the IP header. + */ + op->aad = payload - hdr_len - sizeof (esp_aead_t); + + esp_aad_fill (op, esp, sa0); + + op->tag = payload + op->len; + op->tag_len = 16; + } } - if (sa0->integ_op_type) + if (sa0->integ_op_id) { vnet_crypto_op_t *op; vec_add2_aligned (ptd->integ_ops, op, 1, CLIB_CACHE_LINE_BYTES); - vnet_crypto_op_init (op, sa0->integ_op_type); + vnet_crypto_op_init (op, sa0->integ_op_id); op->src = payload - iv_sz - sizeof (esp_header_t); - op->dst = payload + payload_len - icv_sz; + op->digest = payload + payload_len - icv_sz; op->key = sa0->integ_key.data; op->key_len = sa0->integ_key.len; - op->hmac_trunc_len = icv_sz; + op->digest_len = icv_sz; op->len = payload_len - icv_sz + iv_sz + sizeof (esp_header_t); op->user_data = b - bufs; if (ipsec_sa_is_set_USE_ESN (sa0)) { u32 seq_hi = clib_net_to_host_u32 (sa0->seq_hi); - clib_memcpy_fast (op->dst, &seq_hi, sizeof (seq_hi)); + clib_memcpy_fast (op->digest, &seq_hi, sizeof (seq_hi)); op->len += sizeof (seq_hi); } } @@ -484,7 +508,6 @@ esp_encrypt_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_increment_combined_counter (&ipsec_sa_counters, thread_index, current_sa_index, current_sa_packets, current_sa_bytes); - esp_process_ops (vm, node, ptd->crypto_ops, bufs, nexts); esp_process_ops (vm, node, ptd->integ_ops, bufs, nexts); @@ -563,14 +586,18 @@ VLIB_REGISTER_NODE (esp4_encrypt_tun_node) = { .n_errors = ARRAY_LEN(esp_encrypt_error_strings), .error_strings = esp_encrypt_error_strings, + + .n_next_nodes = 1, + .next_nodes = { + [ESP_ENCRYPT_NEXT_DROP] = "ip4-drop", + }, }; VNET_FEATURE_INIT (esp4_encrypt_tun_feat_node, static) = { .arc_name = "ip4-output", .node_name = "esp4-encrypt-tun", - .runs_before = VNET_FEATURES ("ip4-frag", - "adj-midchain-tx"), + .runs_before = VNET_FEATURES ("adj-midchain-tx"), }; /* *INDENT-ON* */ @@ -590,14 +617,18 @@ VLIB_REGISTER_NODE (esp6_encrypt_tun_node) = { .n_errors = ARRAY_LEN(esp_encrypt_error_strings), .error_strings = esp_encrypt_error_strings, + + .n_next_nodes = 1, + .next_nodes = { + [ESP_ENCRYPT_NEXT_DROP] = "ip6-drop", + }, }; VNET_FEATURE_INIT (esp6_encrypt_tun_feat_node, static) = { .arc_name = "ip6-output", .node_name = "esp6-encrypt-tun", - .runs_before = VNET_FEATURES ("ip6-frag", - "adj-midchain-tx"), + .runs_before = VNET_FEATURES ("adj-midchain-tx"), }; /* *INDENT-ON* */