diff options
author | Berenger Foucher <berenger.foucher@stagiaires.ssi.gouv.fr> | 2018-08-30 16:33:53 +0200 |
---|---|---|
committer | Damjan Marion <dmarion@me.com> | 2018-08-30 17:13:10 +0000 |
commit | 2ce8bd9621902b8078fdcd9a95fd366f24d56ab3 (patch) | |
tree | f809fda434b104d37f0756e3424cb477543d5925 /src/vnet | |
parent | 7c922dc404c2c0a2d67d53ca05db1c1ae1598f44 (diff) |
Add SHA2 support to IKEv2 implementation
The following patch adds a stronger cryptographic suite to IKEv2 implementation.
The following algorithms can now be used for integrity checking in IKEv2 implementation (responder and initiator):
- hmac-sha2-256-128
- hmac-sha2-384-192
- hmac-sha2-512-256
The default integrity checking method was set to hmac-sha2-256-128.
The default PRF function was set sha2-256.
Change-Id: Ia82b4cbbf3067b19b8487040dbefbaf4c9319548
Signed-off-by: Berenger Foucher <berenger.foucher@stagiaires.ssi.gouv.fr>
Diffstat (limited to 'src/vnet')
-rw-r--r-- | src/vnet/ipsec/ikev2.c | 33 | ||||
-rw-r--r-- | src/vnet/ipsec/ikev2_crypto.c | 64 |
2 files changed, 89 insertions, 8 deletions
diff --git a/src/vnet/ipsec/ikev2.c b/src/vnet/ipsec/ikev2.c index 34ab87c3e56..05a4bab2bc6 100644 --- a/src/vnet/ipsec/ikev2.c +++ b/src/vnet/ipsec/ikev2.c @@ -1480,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) { @@ -1550,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; } @@ -1580,7 +1594,7 @@ 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); a.remote_integ_key_len = vec_len (rem_ikey); @@ -2043,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) @@ -2163,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); @@ -2458,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, @@ -2476,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]; @@ -2501,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; @@ -2510,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; } @@ -2521,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; diff --git a/src/vnet/ipsec/ikev2_crypto.c b/src/vnet/ipsec/ikev2_crypto.c index 5a35dfc5503..d595570de44 100644 --- a/src/vnet/ipsec/ikev2_crypto.c +++ b/src/vnet/ipsec/ikev2_crypto.c @@ -339,6 +339,15 @@ ikev2_calc_integr (ikev2_sa_transform_t * tr, v8 * key, u8 * data, int len) r = vec_new (u8, tr->key_len); + if (tr->md == EVP_sha1 ()) + { + clib_warning ("integrity checking with sha1"); + } + else if (tr->md == EVP_sha256 ()) + { + clib_warning ("integrity checking with sha256"); + } + /* verify integrity of data */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L hctx = HMAC_CTX_new (); @@ -780,6 +789,9 @@ ikev2_crypto_init (ikev2_main_t * km) ikev2_sa_transform_t *tr; /* vector of supported transforms - in order of preference */ + + //Encryption + vec_add2 (km->supported_transforms, tr, 1); tr->type = IKEV2_TRANSFORM_TYPE_ENCR; tr->encr_type = IKEV2_TRANSFORM_ENCR_TYPE_AES_CBC; @@ -801,6 +813,28 @@ ikev2_crypto_init (ikev2_main_t * km) tr->block_size = 128 / 8; tr->cipher = EVP_aes_128_cbc (); + //PRF + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_PRF; + tr->prf_type = IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA2_256; + tr->key_len = 256 / 8; + tr->key_trunc = 256 / 8; + tr->md = EVP_sha256 (); + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_PRF; + tr->prf_type = IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA2_384; + tr->key_len = 384 / 8; + tr->key_trunc = 384 / 8; + tr->md = EVP_sha384 (); + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_PRF; + tr->prf_type = IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA2_512; + tr->key_len = 512 / 8; + tr->key_trunc = 512 / 8; + tr->md = EVP_sha512 (); + vec_add2 (km->supported_transforms, tr, 1); tr->type = IKEV2_TRANSFORM_TYPE_PRF; tr->prf_type = IKEV2_TRANSFORM_PRF_TYPE_PRF_HMAC_SHA1; @@ -808,6 +842,35 @@ ikev2_crypto_init (ikev2_main_t * km) tr->key_trunc = 160 / 8; tr->md = EVP_sha1 (); + //Integrity + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_INTEG; + tr->integ_type = IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA2_256_128; + tr->key_len = 256 / 8; + tr->key_trunc = 128 / 8; + tr->md = EVP_sha256 (); + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_INTEG; + tr->integ_type = IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA2_384_192; + tr->key_len = 384 / 8; + tr->key_trunc = 192 / 8; + tr->md = EVP_sha384 (); + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_INTEG; + tr->integ_type = IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA2_512_256; + tr->key_len = 512 / 8; + tr->key_trunc = 256 / 8; + tr->md = EVP_sha512 (); + + vec_add2 (km->supported_transforms, tr, 1); + tr->type = IKEV2_TRANSFORM_TYPE_INTEG; + tr->integ_type = IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_160; + tr->key_len = 160 / 8; + tr->key_trunc = 160 / 8; + tr->md = EVP_sha1 (); + vec_add2 (km->supported_transforms, tr, 1); tr->type = IKEV2_TRANSFORM_TYPE_INTEG; tr->integ_type = IKEV2_TRANSFORM_INTEG_TYPE_AUTH_HMAC_SHA1_96; @@ -815,6 +878,7 @@ ikev2_crypto_init (ikev2_main_t * km) tr->key_trunc = 96 / 8; tr->md = EVP_sha1 (); + #if defined(OPENSSL_NO_CISCO_FECDH) vec_add2 (km->supported_transforms, tr, 1); tr->type = IKEV2_TRANSFORM_TYPE_DH; |