X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fipsec%2Fikev2.c;h=d85feee4274dfa5a7d08b5007d1dbfeb727e88da;hb=eba31ecebed1a7d168da17194cab7a8955761f2b;hp=2c1074d814bfce8481bdd5445ab64c7715276f7d;hpb=68b0fb0c620c7451ef1a6380c43c39de6614db51;p=vpp.git diff --git a/src/vnet/ipsec/ikev2.c b/src/vnet/ipsec/ikev2.c index 2c1074d814b..d85feee4274 100644 --- a/src/vnet/ipsec/ikev2.c +++ b/src/vnet/ipsec/ikev2.c @@ -17,12 +17,15 @@ #include #include #include +#include #include #include #include #include #include +ikev2_main_t ikev2_main; + static int ikev2_delete_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, ikev2_child_sa_t * child); @@ -158,7 +161,7 @@ ikev2_select_proposal (ikev2_sa_proposal_t * proposals, { bitmap |= 1 << transform->type; vec_add2 (rv->transforms, new_t, 1); - clib_memcpy (new_t, transform, sizeof (*new_t)); + clib_memcpy_fast (new_t, transform, sizeof (*new_t)); new_t->attrs = vec_dup (transform->attrs); } } @@ -303,16 +306,16 @@ static void ikev2_delete_sa (ikev2_sa_t * sa) { ikev2_main_t *km = &ikev2_main; - u32 cpu_index = os_get_cpu_number (); + u32 thread_index = vlib_get_thread_index (); uword *p; ikev2_sa_free_all_vec (sa); - p = hash_get (km->per_thread_data[cpu_index].sa_by_rspi, sa->rspi); + p = hash_get (km->per_thread_data[thread_index].sa_by_rspi, sa->rspi); if (p) { - hash_unset (km->per_thread_data[cpu_index].sa_by_rspi, sa->rspi); - pool_put (km->per_thread_data[cpu_index].sas, sa); + hash_unset (km->per_thread_data[thread_index].sa_by_rspi, sa->rspi); + pool_put (km->per_thread_data[thread_index].sas, sa); } } @@ -466,37 +469,37 @@ ikev2_calc_keys (ikev2_sa_t * sa) /* SK_d */ sa->sk_d = vec_new (u8, tr_prf->key_trunc); - clib_memcpy (sa->sk_d, keymat + pos, tr_prf->key_trunc); + clib_memcpy_fast (sa->sk_d, keymat + pos, tr_prf->key_trunc); pos += tr_prf->key_trunc; /* SK_ai */ sa->sk_ai = vec_new (u8, tr_integ->key_len); - clib_memcpy (sa->sk_ai, keymat + pos, tr_integ->key_len); + clib_memcpy_fast (sa->sk_ai, keymat + pos, tr_integ->key_len); pos += tr_integ->key_len; /* SK_ar */ sa->sk_ar = vec_new (u8, tr_integ->key_len); - clib_memcpy (sa->sk_ar, keymat + pos, tr_integ->key_len); + clib_memcpy_fast (sa->sk_ar, keymat + pos, tr_integ->key_len); pos += tr_integ->key_len; /* SK_ei */ sa->sk_ei = vec_new (u8, tr_encr->key_len); - clib_memcpy (sa->sk_ei, keymat + pos, tr_encr->key_len); + clib_memcpy_fast (sa->sk_ei, keymat + pos, tr_encr->key_len); pos += tr_encr->key_len; /* SK_er */ sa->sk_er = vec_new (u8, tr_encr->key_len); - clib_memcpy (sa->sk_er, keymat + pos, tr_encr->key_len); + clib_memcpy_fast (sa->sk_er, keymat + pos, tr_encr->key_len); pos += tr_encr->key_len; /* SK_pi */ sa->sk_pi = vec_new (u8, tr_prf->key_len); - clib_memcpy (sa->sk_pi, keymat + pos, tr_prf->key_len); + clib_memcpy_fast (sa->sk_pi, keymat + pos, tr_prf->key_len); pos += tr_prf->key_len; /* SK_pr */ sa->sk_pr = vec_new (u8, tr_prf->key_len); - clib_memcpy (sa->sk_pr, keymat + pos, tr_prf->key_len); + clib_memcpy_fast (sa->sk_pr, keymat + pos, tr_prf->key_len); pos += tr_prf->key_len; vec_free (keymat); @@ -526,22 +529,22 @@ ikev2_calc_child_keys (ikev2_sa_t * sa, ikev2_child_sa_t * child) /* SK_ei */ child->sk_ei = vec_new (u8, ctr_encr->key_len); - clib_memcpy (child->sk_ei, keymat + pos, ctr_encr->key_len); + clib_memcpy_fast (child->sk_ei, keymat + pos, ctr_encr->key_len); pos += ctr_encr->key_len; /* SK_ai */ child->sk_ai = vec_new (u8, ctr_integ->key_len); - clib_memcpy (child->sk_ai, keymat + pos, ctr_integ->key_len); + clib_memcpy_fast (child->sk_ai, keymat + pos, ctr_integ->key_len); pos += ctr_integ->key_len; /* SK_er */ child->sk_er = vec_new (u8, ctr_encr->key_len); - clib_memcpy (child->sk_er, keymat + pos, ctr_encr->key_len); + clib_memcpy_fast (child->sk_er, keymat + pos, ctr_encr->key_len); pos += ctr_encr->key_len; /* SK_ar */ child->sk_ar = vec_new (u8, ctr_integ->key_len); - clib_memcpy (child->sk_ar, keymat + pos, ctr_integ->key_len); + clib_memcpy_fast (child->sk_ar, keymat + pos, ctr_integ->key_len); pos += ctr_integ->key_len; ASSERT (pos == len); @@ -776,29 +779,31 @@ ikev2_initial_contact_cleanup (ikev2_sa_t * sa) ikev2_sa_t *tmp; u32 i, *delete = 0; ikev2_child_sa_t *c; - u32 cpu_index = os_get_cpu_number (); + u32 thread_index = vlib_get_thread_index (); if (!sa->initial_contact) return; /* find old IKE SAs with the same authenticated identity */ /* *INDENT-OFF* */ - pool_foreach (tmp, km->per_thread_data[cpu_index].sas, ({ + pool_foreach (tmp, km->per_thread_data[thread_index].sas, ({ if (tmp->i_id.type != sa->i_id.type || vec_len(tmp->i_id.data) != vec_len(sa->i_id.data) || memcmp(sa->i_id.data, tmp->i_id.data, vec_len(sa->i_id.data))) continue; if (sa->rspi != tmp->rspi) - vec_add1(delete, tmp - km->per_thread_data[cpu_index].sas); + vec_add1(delete, tmp - km->per_thread_data[thread_index].sas); })); /* *INDENT-ON* */ for (i = 0; i < vec_len (delete); i++) { - tmp = pool_elt_at_index (km->per_thread_data[cpu_index].sas, delete[i]); - vec_foreach (c, tmp->childs) - ikev2_delete_tunnel_interface (km->vnet_main, tmp, c); + tmp = + pool_elt_at_index (km->per_thread_data[thread_index].sas, delete[i]); + vec_foreach (c, + tmp->childs) ikev2_delete_tunnel_interface (km->vnet_main, + tmp, c); ikev2_delete_sa (tmp); } @@ -873,25 +878,26 @@ ikev2_process_auth_req (vlib_main_t * vm, ikev2_sa_t * sa, ike_header_t * ike) first_child_sa->i_proposals = ikev2_parse_sa_payload (ikep); } } - else if (payload == IKEV2_PAYLOAD_IDI || payload == IKEV2_PAYLOAD_IDR) /* 35, 36 */ + else if (payload == IKEV2_PAYLOAD_IDI) /* 35 */ { ike_id_payload_header_t *id = (ike_id_payload_header_t *) ikep; - if (sa->is_initiator) - { - sa->r_id.type = id->id_type; - vec_free (sa->r_id.data); - vec_add (sa->r_id.data, id->payload, plen - sizeof (*id)); - } - else - { - sa->i_id.type = id->id_type; - vec_free (sa->i_id.data); - vec_add (sa->i_id.data, id->payload, plen - sizeof (*id)); - } + sa->i_id.type = id->id_type; + vec_free (sa->i_id.data); + vec_add (sa->i_id.data, id->payload, plen - sizeof (*id)); - clib_warning ("received payload %s, len %u id_type %u", - (payload == IKEV2_PAYLOAD_IDI ? "IDi" : "IDr"), + clib_warning ("received payload IDi, len %u id_type %u", + plen - sizeof (*id), id->id_type); + } + else if (payload == IKEV2_PAYLOAD_IDR) /* 36 */ + { + ike_id_payload_header_t *id = (ike_id_payload_header_t *) ikep; + + sa->r_id.type = id->id_type; + vec_free (sa->r_id.data); + vec_add (sa->r_id.data, id->payload, plen - sizeof (*id)); + + clib_warning ("received payload IDr len %u id_type %u", plen - sizeof (*id), id->id_type); } else if (payload == IKEV2_PAYLOAD_AUTH) /* 39 */ @@ -1100,7 +1106,7 @@ ikev2_process_create_child_sa_req (vlib_main_t * vm, ikev2_sa_t * sa, } else if (payload == IKEV2_PAYLOAD_NONCE) { - clib_memcpy (nonce, ikep->payload, plen - sizeof (*ikep)); + clib_memcpy_fast (nonce, ikep->payload, plen - sizeof (*ikep)); } else if (payload == IKEV2_PAYLOAD_TSI) { @@ -1474,6 +1480,7 @@ ikev2_create_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, ikev2_sa_transform_t *tr; ikev2_sa_proposal_t *proposals; u8 encr_type = 0; + u8 integ_type = 0; if (!child->r_proposals) { @@ -1481,20 +1488,20 @@ ikev2_create_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, return 1; } - memset (&a, 0, sizeof (a)); + clib_memset (&a, 0, sizeof (a)); a.is_add = 1; if (sa->is_initiator) { - a.local_ip.as_u32 = sa->iaddr.as_u32; - a.remote_ip.as_u32 = sa->raddr.as_u32; + a.local_ip.ip4.as_u32 = sa->iaddr.as_u32; + a.remote_ip.ip4.as_u32 = sa->raddr.as_u32; proposals = child->i_proposals; a.local_spi = child->r_proposals[0].spi; a.remote_spi = child->i_proposals[0].spi; } else { - a.local_ip.as_u32 = sa->raddr.as_u32; - a.remote_ip.as_u32 = sa->iaddr.as_u32; + a.local_ip.ip4.as_u32 = sa->raddr.as_u32; + a.remote_ip.ip4.as_u32 = sa->iaddr.as_u32; proposals = child->r_proposals; a.local_spi = child->i_proposals[0].spi; a.remote_spi = child->r_proposals[0].spi; @@ -1544,8 +1551,21 @@ ikev2_create_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, tr = ikev2_sa_get_td_for_type (proposals, IKEV2_TRANSFORM_TYPE_INTEG); if (tr) { - if (tr->integ_type != IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96) - { + switch (tr->integ_type) + { + case IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA2_256_128: + integ_type = IPSEC_INTEG_ALG_SHA_256_128; + break; + case IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA2_384_192: + integ_type = IPSEC_INTEG_ALG_SHA_384_192; + break; + case IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA2_512_256: + integ_type = IPSEC_INTEG_ALG_SHA_512_256; + break; + case IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96: + integ_type = IPSEC_INTEG_ALG_SHA1_96; + break; + default: ikev2_set_state (sa, IKEV2_STATE_NO_PROPOSAL_CHOSEN); return 1; } @@ -1574,17 +1594,17 @@ ikev2_create_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, rem_ckey = child->sk_ei; } - a.integ_alg = IPSEC_INTEG_ALG_SHA1_96; + a.integ_alg = integ_type; a.local_integ_key_len = vec_len (loc_ikey); - clib_memcpy (a.local_integ_key, loc_ikey, a.local_integ_key_len); + clib_memcpy_fast (a.local_integ_key, loc_ikey, a.local_integ_key_len); a.remote_integ_key_len = vec_len (rem_ikey); - clib_memcpy (a.remote_integ_key, rem_ikey, a.remote_integ_key_len); + clib_memcpy_fast (a.remote_integ_key, rem_ikey, a.remote_integ_key_len); a.crypto_alg = encr_type; a.local_crypto_key_len = vec_len (loc_ckey); - clib_memcpy (a.local_crypto_key, loc_ckey, a.local_crypto_key_len); + clib_memcpy_fast (a.local_crypto_key, loc_ckey, a.local_crypto_key_len); a.remote_crypto_key_len = vec_len (rem_ckey); - clib_memcpy (a.remote_crypto_key, rem_ckey, a.remote_crypto_key_len); + clib_memcpy_fast (a.remote_crypto_key, rem_ckey, a.remote_crypto_key_len); if (sa->profile && sa->profile->lifetime) { @@ -1592,8 +1612,16 @@ ikev2_create_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, + sa->profile->lifetime; if (sa->profile->lifetime_jitter) { + // This is not much better than rand(3), which Coverity warns + // is unsuitable for security applications; random_u32 is + // however fast. If this perturbance to the expiration time + // needs to use a better RNG then we may need to use something + // like /dev/urandom which has significant overhead. + u32 rnd = (u32) (vlib_time_now (vnm->vlib_main) * 1e6); + rnd = random_u32 (&rnd); + child->time_to_expiration += - 1 + (rand () % sa->profile->lifetime_jitter); + 1 + (rnd % sa->profile->lifetime_jitter); } } @@ -1614,8 +1642,8 @@ ikev2_delete_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, return 0; a.is_add = 0; - a.local_ip.as_u32 = sa->iaddr.as_u32; - a.remote_ip.as_u32 = sa->raddr.as_u32; + a.local_ip.ip4.as_u32 = sa->iaddr.as_u32; + a.remote_ip.ip4.as_u32 = sa->raddr.as_u32; a.local_spi = child->r_proposals[0].spi; a.remote_spi = child->i_proposals[0].spi; } @@ -1625,8 +1653,8 @@ ikev2_delete_tunnel_interface (vnet_main_t * vnm, ikev2_sa_t * sa, return 0; a.is_add = 0; - a.local_ip.as_u32 = sa->raddr.as_u32; - a.remote_ip.as_u32 = sa->iaddr.as_u32; + a.local_ip.ip4.as_u32 = sa->raddr.as_u32; + a.remote_ip.ip4.as_u32 = sa->iaddr.as_u32; a.local_spi = child->i_proposals[0].spi; a.remote_spi = child->r_proposals[0].spi; } @@ -1804,7 +1832,7 @@ ikev2_generate_message (ikev2_sa_t * sa, ike_header_t * ike, void *user) ikev2_sa_proposal_t *proposals = (ikev2_sa_proposal_t *) user; ikev2_notify_t notify; u8 *data = vec_new (u8, 4); - memset (¬ify, 0, sizeof (notify)); + clib_memset (¬ify, 0, sizeof (notify)); notify.protocol_id = IKEV2_PROTOCOL_ESP; notify.spi = sa->childs[0].i_proposals->spi; *(u32 *) data = clib_host_to_net_u32 (notify.spi); @@ -1870,7 +1898,7 @@ ikev2_generate_message (ikev2_sa_t * sa, ike_header_t * ike, void *user) tlen += vec_len (chain->data); ike->nextpayload = chain->first_payload_type; ike->length = clib_host_to_net_u32 (tlen); - clib_memcpy (ike->payload, chain->data, vec_len (chain->data)); + clib_memcpy_fast (ike->payload, chain->data, vec_len (chain->data)); /* store whole IKE payload - needed for PSK auth */ vec_free (sa->last_sa_init_res_packet_data); @@ -1902,8 +1930,8 @@ ikev2_generate_message (ikev2_sa_t * sa, ike_header_t * ike, void *user) ikev2_calc_integr (tr_integ, sa->is_initiator ? sa->sk_ai : sa->sk_ar, (u8 *) ike, tlen - tr_integ->key_trunc); - clib_memcpy (ike->payload + tlen - tr_integ->key_trunc - sizeof (*ike), - integ, tr_integ->key_trunc); + clib_memcpy_fast (ike->payload + tlen - tr_integ->key_trunc - + sizeof (*ike), integ, tr_integ->key_trunc); /* store whole IKE payload - needed for retransmit */ vec_free (sa->last_res_packet_data); @@ -1922,10 +1950,10 @@ ikev2_retransmit_sa_init (ike_header_t * ike, { ikev2_main_t *km = &ikev2_main; ikev2_sa_t *sa; - u32 cpu_index = os_get_cpu_number (); + u32 thread_index = vlib_get_thread_index (); /* *INDENT-OFF* */ - pool_foreach (sa, km->per_thread_data[cpu_index].sas, ({ + pool_foreach (sa, km->per_thread_data[thread_index].sas, ({ if (sa->ispi == clib_net_to_host_u64(ike->ispi) && sa->iaddr.as_u32 == iaddr.as_u32 && sa->raddr.as_u32 == raddr.as_u32) @@ -1958,7 +1986,7 @@ ikev2_retransmit_sa_init (ike_header_t * ike, ike->flags = tmp->flags; ike->msgid = tmp->msgid; ike->length = tmp->length; - clib_memcpy(ike->payload, tmp->payload, + clib_memcpy_fast(ike->payload, tmp->payload, clib_net_to_host_u32(tmp->length) - sizeof(*ike)); clib_warning("IKE_SA_INIT retransmit from %U to %U", format_ip4_address, &raddr, @@ -2010,8 +2038,8 @@ ikev2_retransmit_resp (ikev2_sa_t * sa, ike_header_t * ike) ike->flags = tmp->flags; ike->msgid = tmp->msgid; ike->length = tmp->length; - clib_memcpy (ike->payload, tmp->payload, - clib_net_to_host_u32 (tmp->length) - sizeof (*ike)); + clib_memcpy_fast (ike->payload, tmp->payload, + clib_net_to_host_u32 (tmp->length) - sizeof (*ike)); clib_warning ("IKE msgid %u retransmit from %U to %U", msg_id, format_ip4_address, &sa->raddr, @@ -2029,6 +2057,7 @@ ikev2_retransmit_resp (ikev2_sa_t * sa, ike_header_t * ike) } } + static uword ikev2_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) @@ -2036,7 +2065,7 @@ ikev2_node_fn (vlib_main_t * vm, u32 n_left_from, *from, *to_next; ikev2_next_t next_index; ikev2_main_t *km = &ikev2_main; - u32 cpu_index = os_get_cpu_number (); + u32 thread_index = vlib_get_thread_index (); from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -2087,7 +2116,7 @@ ikev2_node_fn (vlib_main_t * vm, if (ike0->exchange == IKEV2_EXCHANGE_SA_INIT) { sa0 = &sa; - memset (sa0, 0, sizeof (*sa0)); + clib_memset (sa0, 0, sizeof (*sa0)); if (ike0->flags & IKEV2_HDR_FLAG_INITIATOR) { @@ -2134,11 +2163,14 @@ ikev2_node_fn (vlib_main_t * vm, if (sa0->state == IKEV2_STATE_SA_INIT) { /* add SA to the pool */ - pool_get (km->per_thread_data[cpu_index].sas, sa0); - clib_memcpy (sa0, &sa, sizeof (*sa0)); - hash_set (km->per_thread_data[cpu_index].sa_by_rspi, + pool_get (km->per_thread_data[thread_index].sas, + sa0); + clib_memcpy_fast (sa0, &sa, sizeof (*sa0)); + hash_set (km-> + per_thread_data[thread_index].sa_by_rspi, sa0->rspi, - sa0 - km->per_thread_data[cpu_index].sas); + sa0 - + km->per_thread_data[thread_index].sas); } else { @@ -2146,7 +2178,7 @@ ikev2_node_fn (vlib_main_t * vm, } } } - else + else //received sa_init without initiator flag { ikev2_process_sa_init_resp (vm, sa0, ike0); @@ -2169,11 +2201,11 @@ ikev2_node_fn (vlib_main_t * vm, if (sa0->state == IKEV2_STATE_SA_INIT) { /* add SA to the pool */ - pool_get (km->per_thread_data[cpu_index].sas, sa0); - clib_memcpy (sa0, &sa, sizeof (*sa0)); - hash_set (km->per_thread_data[cpu_index].sa_by_rspi, + pool_get (km->per_thread_data[thread_index].sas, sa0); + clib_memcpy_fast (sa0, &sa, sizeof (*sa0)); + hash_set (km->per_thread_data[thread_index].sa_by_rspi, sa0->rspi, - sa0 - km->per_thread_data[cpu_index].sas); + sa0 - km->per_thread_data[thread_index].sas); } else { @@ -2184,12 +2216,13 @@ ikev2_node_fn (vlib_main_t * vm, else if (ike0->exchange == IKEV2_EXCHANGE_IKE_AUTH) { uword *p; - p = hash_get (km->per_thread_data[cpu_index].sa_by_rspi, + p = hash_get (km->per_thread_data[thread_index].sa_by_rspi, clib_net_to_host_u64 (ike0->rspi)); if (p) { - sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas, - p[0]); + sa0 = + pool_elt_at_index (km->per_thread_data[thread_index].sas, + p[0]); r = ikev2_retransmit_resp (sa0, ike0); if (r == 1) @@ -2240,12 +2273,13 @@ ikev2_node_fn (vlib_main_t * vm, else if (ike0->exchange == IKEV2_EXCHANGE_INFORMATIONAL) { uword *p; - p = hash_get (km->per_thread_data[cpu_index].sa_by_rspi, + p = hash_get (km->per_thread_data[thread_index].sa_by_rspi, clib_net_to_host_u64 (ike0->rspi)); if (p) { - sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas, - p[0]); + sa0 = + pool_elt_at_index (km->per_thread_data[thread_index].sas, + p[0]); r = ikev2_retransmit_resp (sa0, ike0); if (r == 1) @@ -2305,12 +2339,13 @@ ikev2_node_fn (vlib_main_t * vm, else if (ike0->exchange == IKEV2_EXCHANGE_CREATE_CHILD_SA) { uword *p; - p = hash_get (km->per_thread_data[cpu_index].sa_by_rspi, + p = hash_get (km->per_thread_data[thread_index].sa_by_rspi, clib_net_to_host_u64 (ike0->rspi)); if (p) { - sa0 = pool_elt_at_index (km->per_thread_data[cpu_index].sas, - p[0]); + sa0 = + pool_elt_at_index (km->per_thread_data[thread_index].sas, + p[0]); r = ikev2_retransmit_resp (sa0, ike0); if (r == 1) @@ -2438,7 +2473,7 @@ VLIB_REGISTER_NODE (ikev2_node,static) = { }; /* *INDENT-ON* */ - +// set ikev2 proposals when vpp is used as initiator static clib_error_t * ikev2_set_initiator_proposals (vlib_main_t * vm, ikev2_sa_t * sa, ikev2_transforms_set * ts, @@ -2456,7 +2491,7 @@ ikev2_set_initiator_proposals (vlib_main_t * vm, ikev2_sa_t * sa, vec_foreach (td, km->supported_transforms) { if (td->type == IKEV2_TRANSFORM_TYPE_ENCR - && td->encr_type == IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC + && td->encr_type == ts->crypto_alg && td->key_len == ts->crypto_key_size / 8) { u16 attr[2]; @@ -2481,7 +2516,7 @@ ikev2_set_initiator_proposals (vlib_main_t * vm, ikev2_sa_t * sa, vec_foreach (td, km->supported_transforms) { if (td->type == IKEV2_TRANSFORM_TYPE_INTEG - && td->integ_type == IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96) + && td->integ_type == ts->integ_alg) { vec_add1 (proposal->transforms, *td); error = 0; @@ -2490,6 +2525,8 @@ ikev2_set_initiator_proposals (vlib_main_t * vm, ikev2_sa_t * sa, } if (error) { + clib_warning + ("Didn't find any supported algorithm for IKEV2_TRANSFORM_TYPE_INTEG"); r = clib_error_return (0, "Unsupported algorithm"); return r; } @@ -2501,7 +2538,7 @@ ikev2_set_initiator_proposals (vlib_main_t * vm, ikev2_sa_t * sa, vec_foreach (td, km->supported_transforms) { if (td->type == IKEV2_TRANSFORM_TYPE_PRF - && td->prf_type == IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA1) + && td->prf_type == IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA2_256) { vec_add1 (proposal->transforms, *td); error = 0; @@ -2654,7 +2691,7 @@ ikev2_add_del_profile (vlib_main_t * vm, u8 * name, int is_add) return clib_error_return (0, "policy %v already exists", name); pool_get (km->profiles, p); - memset (p, 0, sizeof (*p)); + clib_memset (p, 0, sizeof (*p)); p->name = vec_dup (name); p->responder.sw_if_index = ~0; uword index = p - km->profiles; @@ -2919,7 +2956,7 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name) /* Prepare the SA and the IKE payload */ ikev2_sa_t sa; - memset (&sa, 0, sizeof (ikev2_sa_t)); + clib_memset (&sa, 0, sizeof (ikev2_sa_t)); ikev2_payload_chain_t *chain = 0; ikev2_payload_new_chain (chain); @@ -2956,20 +2993,20 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name) u8 *nat_detection_sha1 = vec_new (u8, 20); u64 tmpspi = clib_host_to_net_u64 (sa.ispi); - clib_memcpy (&nat_detection_source[0], &tmpspi, sizeof (tmpspi)); + clib_memcpy_fast (&nat_detection_source[0], &tmpspi, sizeof (tmpspi)); tmpspi = clib_host_to_net_u64 (sa.rspi); - clib_memcpy (&nat_detection_source[8], &tmpspi, sizeof (tmpspi)); + clib_memcpy_fast (&nat_detection_source[8], &tmpspi, sizeof (tmpspi)); u16 tmpport = clib_host_to_net_u16 (500); - clib_memcpy (&nat_detection_source[8 + 8 + 4], &tmpport, - sizeof (tmpport)); + clib_memcpy_fast (&nat_detection_source[8 + 8 + 4], &tmpport, + sizeof (tmpport)); u32 tmpip = clib_host_to_net_u32 (if_ip->as_u32); - clib_memcpy (&nat_detection_source[8 + 8], &tmpip, sizeof (tmpip)); + clib_memcpy_fast (&nat_detection_source[8 + 8], &tmpip, sizeof (tmpip)); SHA1 (nat_detection_source, sizeof (nat_detection_source), nat_detection_sha1); ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_NAT_DETECTION_SOURCE_IP, nat_detection_sha1); tmpip = clib_host_to_net_u32 (p->responder.ip4.as_u32); - clib_memcpy (&nat_detection_source[8 + 8], &tmpip, sizeof (tmpip)); + clib_memcpy_fast (&nat_detection_source[8 + 8], &tmpip, sizeof (tmpip)); SHA1 (nat_detection_source, sizeof (nat_detection_source), nat_detection_sha1); ikev2_payload_add_notify (chain, @@ -2979,18 +3016,18 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name) u8 *sig_hash_algo = vec_new (u8, 8); u64 tmpsig = clib_host_to_net_u64 (0x0001000200030004); - clib_memcpy (sig_hash_algo, &tmpsig, sizeof (tmpsig)); + clib_memcpy_fast (sig_hash_algo, &tmpsig, sizeof (tmpsig)); ikev2_payload_add_notify (chain, IKEV2_NOTIFY_MSG_SIGNATURE_HASH_ALGORITHMS, sig_hash_algo); vec_free (sig_hash_algo); - /* Buffer update and bolierplate */ + /* Buffer update and boilerplate */ len += vec_len (chain->data); ike0->nextpayload = chain->first_payload_type; ike0->length = clib_host_to_net_u32 (len); - clib_memcpy (ike0->payload, chain->data, vec_len (chain->data)); + clib_memcpy_fast (ike0->payload, chain->data, vec_len (chain->data)); ikev2_payload_destroy_chain (chain); ike0->version = IKE_VERSION_2; @@ -3010,14 +3047,19 @@ ikev2_initiate_sa_init (vlib_main_t * vm, u8 * name) sa.i_auth.method = p->auth.method; sa.i_auth.hex = p->auth.hex; sa.i_auth.data = vec_dup (p->auth.data); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L + clib_memcpy_fast (sa.i_auth.key, p->auth.key, + EVP_PKEY_size (p->auth.key)); +#else sa.i_auth.key = vec_dup (p->auth.key); +#endif vec_add (sa.childs[0].tsi, &p->loc_ts, 1); vec_add (sa.childs[0].tsr, &p->rem_ts, 1); /* add SA to the pool */ ikev2_sa_t *sa0 = 0; pool_get (km->sais, sa0); - clib_memcpy (sa0, &sa, sizeof (*sa0)); + clib_memcpy_fast (sa0, &sa, sizeof (*sa0)); hash_set (km->sa_by_ispi, sa0->ispi, sa0 - km->sais); ikev2_send_ike (vm, if_ip, &p->responder.ip4, bi0, len); @@ -3255,7 +3297,7 @@ ikev2_init (vlib_main_t * vm) vlib_thread_main_t *tm = vlib_get_thread_main (); int thread_id; - memset (km, 0, sizeof (ikev2_main_t)); + clib_memset (km, 0, sizeof (ikev2_main_t)); km->vnet_main = vnet_get_main (); km->vlib_main = vm; @@ -3305,7 +3347,7 @@ ikev2_mngr_process_child_sa (ikev2_sa_t * sa, ikev2_child_sa_t * csa) else if (csa->rekey_retries > 0) { csa->rekey_retries--; - clib_warning ("Rekeing Child SA 0x%x, retries left %d", + clib_warning ("Rekeying Child SA 0x%x, retries left %d", csa->i_proposals->spi, csa->rekey_retries); if (csa->rekey_retries == 0) { @@ -3334,6 +3376,7 @@ ikev2_mngr_process_ipsec_sa (ipsec_sa_t * ipsec_sa) ikev2_sa_t *fsa = 0; ikev2_child_sa_t *fchild = 0; f64 now = vlib_time_now (vm); + vlib_counter_t counts; /* Search for the SA and child SA */ vec_foreach (tkm, km->per_thread_data) @@ -3352,11 +3395,13 @@ ikev2_mngr_process_ipsec_sa (ipsec_sa_t * ipsec_sa) })); /* *INDENT-ON* */ } + vlib_get_combined_counter (&ipsec_sa_counters, + ipsec_sa->stat_index, &counts); if (fchild && fsa && fsa->profile && fsa->profile->lifetime_maxdata) { if (!fchild->is_expired - && ipsec_sa->total_data_size > fsa->profile->lifetime_maxdata) + && counts.bytes > fsa->profile->lifetime_maxdata) { fchild->time_to_expiration = now; }