diff options
author | Yves-Alexis Perez <corsac@debian.org> | 2013-11-01 13:32:07 +0100 |
---|---|---|
committer | Yves-Alexis Perez <corsac@debian.org> | 2013-11-01 13:32:07 +0100 |
commit | 5313d2d78ca150515f7f5eb39801c100690b6b29 (patch) | |
tree | c78e420367283bb1b16f14210b12687cdfbd26eb /src/libcharon/encoding/payloads | |
parent | 6b99c8d9cff7b3e8ae8f3204b99e7ea40f791349 (diff) | |
download | vyos-strongswan-5313d2d78ca150515f7f5eb39801c100690b6b29.tar.gz vyos-strongswan-5313d2d78ca150515f7f5eb39801c100690b6b29.zip |
Imported Upstream version 5.1.1
Diffstat (limited to 'src/libcharon/encoding/payloads')
-rw-r--r-- | src/libcharon/encoding/payloads/encryption_payload.c | 14 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/encryption_payload.h | 4 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/proposal_substructure.c | 130 | ||||
-rw-r--r-- | src/libcharon/encoding/payloads/sa_payload.c | 20 |
4 files changed, 124 insertions, 44 deletions
diff --git a/src/libcharon/encoding/payloads/encryption_payload.c b/src/libcharon/encoding/payloads/encryption_payload.c index 6ba1b23a0..6a9f9c3bd 100644 --- a/src/libcharon/encoding/payloads/encryption_payload.c +++ b/src/libcharon/encoding/payloads/encryption_payload.c @@ -309,10 +309,11 @@ static chunk_t append_header(private_encryption_payload_t *this, chunk_t assoc) } METHOD(encryption_payload_t, encrypt, status_t, - private_encryption_payload_t *this, chunk_t assoc) + private_encryption_payload_t *this, u_int64_t mid, chunk_t assoc) { chunk_t iv, plain, padding, icv, crypt; generator_t *generator; + iv_gen_t *iv_gen; rng_t *rng; size_t bs; @@ -329,6 +330,13 @@ METHOD(encryption_payload_t, encrypt, status_t, return NOT_SUPPORTED; } + iv_gen = this->aead->get_iv_gen(this->aead); + if (!iv_gen) + { + DBG1(DBG_ENC, "encrypting encryption payload failed, no IV generator"); + return NOT_SUPPORTED; + } + assoc = append_header(this, assoc); generator = generator_create(); @@ -356,7 +364,7 @@ METHOD(encryption_payload_t, encrypt, status_t, crypt = chunk_create(plain.ptr, plain.len + padding.len); generator->destroy(generator); - if (!rng->get_bytes(rng, iv.len, iv.ptr) || + if (!iv_gen->get_iv(iv_gen, mid, iv.len, iv.ptr) || !rng->get_bytes(rng, padding.len - 1, padding.ptr)) { DBG1(DBG_ENC, "encrypting encryption payload failed, no IV or padding"); @@ -388,7 +396,7 @@ METHOD(encryption_payload_t, encrypt, status_t, } METHOD(encryption_payload_t, encrypt_v1, status_t, - private_encryption_payload_t *this, chunk_t iv) + private_encryption_payload_t *this, u_int64_t mid, chunk_t iv) { generator_t *generator; chunk_t plain, padding; diff --git a/src/libcharon/encoding/payloads/encryption_payload.h b/src/libcharon/encoding/payloads/encryption_payload.h index 5c6069339..f4fc7d667 100644 --- a/src/libcharon/encoding/payloads/encryption_payload.h +++ b/src/libcharon/encoding/payloads/encryption_payload.h @@ -71,13 +71,15 @@ struct encryption_payload_t { /** * Generate, encrypt and sign contained payloads. * + * @param mid message ID * @param assoc associated data * @return * - SUCCESS if encryption successful * - FAILED if encryption failed * - INVALID_STATE if aead not supplied, but needed */ - status_t (*encrypt) (encryption_payload_t *this, chunk_t assoc); + status_t (*encrypt) (encryption_payload_t *this, u_int64_t mid, + chunk_t assoc); /** * Decrypt, verify and parse contained payloads. diff --git a/src/libcharon/encoding/payloads/proposal_substructure.c b/src/libcharon/encoding/payloads/proposal_substructure.c index 3cf22aefd..cb9b359b3 100644 --- a/src/libcharon/encoding/payloads/proposal_substructure.c +++ b/src/libcharon/encoding/payloads/proposal_substructure.c @@ -246,6 +246,24 @@ typedef enum { } ikev1_esp_auth_transid_it; /** + * IKEv1 Transform ID AH authentication algorithm. + */ +typedef enum { + IKEV1_AH_HMAC_MD5 = 2, + IKEV1_AH_HMAC_SHA = 3, + IKEV1_AH_DES_MAC = 4, + IKEV1_AH_HMAC_SHA2_256 = 5, + IKEV1_AH_HMAC_SHA2_384 = 6, + IKEV1_AH_HMAC_SHA2_512 = 7, + IKEV1_AH_RIPEMD = 8, + IKEV1_AH_AES_XCBC_MAC = 9, + IKEV1_AH_RSA = 10, + IKEV1_AH_AES_128_GMAC = 11, + IKEV1_AH_AES_192_GMAC = 12, + IKEV1_AH_AES_256_GMAC = 13, +} ikev1_ah_transid_t; + +/** * IKEv1 ESP Encapsulation mode. */ typedef enum { @@ -637,6 +655,22 @@ static algo_map_t map_esp_auth[] = { }; /** + * AH authentication algorithm mapping + */ +static algo_map_t map_ah[] = { + { IKEV1_AH_HMAC_MD5, AUTH_HMAC_MD5_96 }, + { IKEV1_AH_HMAC_SHA, AUTH_HMAC_SHA1_96 }, + { IKEV1_AH_DES_MAC, AUTH_DES_MAC }, + { IKEV1_AH_HMAC_SHA2_256, AUTH_HMAC_SHA2_256_128 }, + { IKEV1_AH_HMAC_SHA2_384, AUTH_HMAC_SHA2_384_192 }, + { IKEV1_AH_HMAC_SHA2_512, AUTH_HMAC_SHA2_512_256 }, + { IKEV1_AH_AES_XCBC_MAC, AUTH_AES_XCBC_96 }, + { IKEV1_AH_AES_128_GMAC, AUTH_AES_128_GMAC }, + { IKEV1_AH_AES_192_GMAC, AUTH_AES_192_GMAC }, + { IKEV1_AH_AES_256_GMAC, AUTH_AES_256_GMAC }, +}; + +/** * Get IKEv2 algorithm from IKEv1 identifier */ static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value) @@ -713,7 +747,8 @@ static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value) /** * Get IKEv2 algorithm from IKEv1 ESP transaction ID */ -static u_int16_t get_alg_from_ikev1_transid(transform_type_t type, u_int16_t value) +static u_int16_t get_alg_from_ikev1_transid(protocol_id_t proto, + transform_type_t type, u_int16_t value) { algo_map_t *map; u_int16_t def; @@ -727,8 +762,16 @@ static u_int16_t get_alg_from_ikev1_transid(transform_type_t type, u_int16_t val def = ENCR_UNDEFINED; break; case INTEGRITY_ALGORITHM: - map = map_esp_auth; - count = countof(map_esp_auth); + if (proto == PROTO_ESP) + { + map = map_esp_auth; + count = countof(map_esp_auth); + } + else + { + map = map_ah; + count = countof(map_ah); + } def = AUTH_UNDEFINED; break; default: @@ -745,9 +788,10 @@ static u_int16_t get_alg_from_ikev1_transid(transform_type_t type, u_int16_t val } /** - * Get IKEv1 ESP transaction ID from IKEv2 identifier + * Get IKEv1 ESP/AH transaction ID from IKEv2 identifier */ -static u_int16_t get_ikev1_transid_from_alg(transform_type_t type, u_int16_t value) +static u_int16_t get_ikev1_transid_from_alg(protocol_id_t proto, + transform_type_t type, u_int16_t value) { algo_map_t *map; int i, count; @@ -759,8 +803,16 @@ static u_int16_t get_ikev1_transid_from_alg(transform_type_t type, u_int16_t val count = countof(map_esp_encr); break; case INTEGRITY_ALGORITHM: - map = map_esp_auth; - count = countof(map_esp_auth); + if (proto == PROTO_ESP) + { + map = map_esp_auth; + count = countof(map_esp_auth); + } + else + { + map = map_ah; + count = countof(map_ah); + } break; default: return 0; @@ -889,10 +941,10 @@ static void add_to_proposal_v1_ike(proposal_t *proposal, } /** - * Add an ESP transform to a proposal for IKEv1 + * Add an ESP/AH transform to a proposal for IKEv1 */ -static void add_to_proposal_v1_esp(proposal_t *proposal, - transform_substructure_t *transform) +static void add_to_proposal_v1(proposal_t *proposal, + transform_substructure_t *transform, protocol_id_t proto) { transform_attribute_type_t type; transform_attribute_t *tattr; @@ -911,7 +963,7 @@ static void add_to_proposal_v1_esp(proposal_t *proposal, break; case TATTR_PH2_AUTH_ALGORITHM: proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM, - get_alg_from_ikev1_transid(INTEGRITY_ALGORITHM, + get_alg_from_ikev1_transid(proto, INTEGRITY_ALGORITHM, value), 0); break; case TATTR_PH2_GROUP: @@ -927,12 +979,15 @@ static void add_to_proposal_v1_esp(proposal_t *proposal, /* TODO-IKEv1: handle ESN attribute */ proposal->add_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0); - encr = get_alg_from_ikev1_transid(ENCRYPTION_ALGORITHM, - transform->get_transform_id(transform)); - if (encr) + if (proto == PROTO_ESP) { - proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, - key_length); + encr = get_alg_from_ikev1_transid(proto, ENCRYPTION_ALGORITHM, + transform->get_transform_id(transform)); + if (encr) + { + proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, + key_length); + } } } @@ -977,7 +1032,8 @@ METHOD(proposal_substructure_t, get_proposals, void, add_to_proposal_v1_ike(proposal, transform); break; case PROTO_ESP: - add_to_proposal_v1_esp(proposal, transform); + case PROTO_AH: + add_to_proposal_v1(proposal, transform, this->protocol_id); break; default: break; @@ -1072,6 +1128,7 @@ METHOD(proposal_substructure_t, get_lifetime, u_int32_t, return get_life_duration(this, TATTR_PH1_LIFE_TYPE, IKEV1_LIFE_TYPE_SECONDS, TATTR_PH1_LIFE_DURATION); case PROTO_ESP: + case PROTO_AH: duration = get_life_duration(this, TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_SECONDS, TATTR_PH2_SA_LIFE_DURATION); if (!duration) @@ -1090,6 +1147,7 @@ METHOD(proposal_substructure_t, get_lifebytes, u_int64_t, switch (this->protocol_id) { case PROTO_ESP: + case PROTO_AH: return 1000 * get_life_duration(this, TATTR_PH2_SA_LIFE_TYPE, IKEV1_LIFE_TYPE_KILOBYTES, TATTR_PH2_SA_LIFE_DURATION); case PROTO_IKE: @@ -1281,24 +1339,26 @@ static void set_from_proposal_v1_ike(private_proposal_substructure_t *this, } /** - * Add an IKEv1 ESP proposal to the substructure + * Add an IKEv1 ESP/AH proposal to the substructure */ -static void set_from_proposal_v1_esp(private_proposal_substructure_t *this, +static void set_from_proposal_v1(private_proposal_substructure_t *this, proposal_t *proposal, u_int32_t lifetime, u_int64_t lifebytes, ipsec_mode_t mode, encap_t udp, int number) { transform_substructure_t *transform = NULL; u_int16_t alg, key_size; enumerator_t *enumerator; + protocol_id_t proto; + proto = proposal->get_protocol(proposal); enumerator = proposal->create_enumerator(proposal, ENCRYPTION_ALGORITHM); if (enumerator->enumerate(enumerator, &alg, &key_size)) { - alg = get_ikev1_transid_from_alg(ENCRYPTION_ALGORITHM, alg); + alg = get_ikev1_transid_from_alg(proto, ENCRYPTION_ALGORITHM, alg); if (alg) { - transform = transform_substructure_create_type(TRANSFORM_SUBSTRUCTURE_V1, - number, alg); + transform = transform_substructure_create_type( + TRANSFORM_SUBSTRUCTURE_V1, number, alg); if (key_size) { transform->add_transform_attribute(transform, @@ -1308,17 +1368,18 @@ static void set_from_proposal_v1_esp(private_proposal_substructure_t *this, } } enumerator->destroy(enumerator); - if (!transform) - { - return; - } enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM); if (enumerator->enumerate(enumerator, &alg, &key_size)) { - alg = get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM, alg); + alg = get_ikev1_transid_from_alg(proto, INTEGRITY_ALGORITHM, alg); if (alg) { + if (!transform) + { + transform = transform_substructure_create_type( + TRANSFORM_SUBSTRUCTURE_V1, number, alg); + } transform->add_transform_attribute(transform, transform_attribute_create_value(TRANSFORM_ATTRIBUTE_V1, TATTR_PH2_AUTH_ALGORITHM, alg)); @@ -1326,6 +1387,11 @@ static void set_from_proposal_v1_esp(private_proposal_substructure_t *this, } enumerator->destroy(enumerator); + if (!transform) + { + return; + } + enumerator = proposal->create_enumerator(proposal, DIFFIE_HELLMAN_GROUP); if (enumerator->enumerate(enumerator, &alg, &key_size)) { @@ -1493,8 +1559,9 @@ proposal_substructure_t *proposal_substructure_create_from_proposal_v1( set_from_proposal_v1_ike(this, proposal, lifetime, auth, 1); break; case PROTO_ESP: - set_from_proposal_v1_esp(this, proposal, lifetime, - lifebytes, mode, udp, 1); + case PROTO_AH: + set_from_proposal_v1(this, proposal, lifetime, + lifebytes, mode, udp, 1); break; default: break; @@ -1535,8 +1602,9 @@ proposal_substructure_t *proposal_substructure_create_from_proposals_v1( auth, ++number); break; case PROTO_ESP: - set_from_proposal_v1_esp(this, proposal, lifetime, - lifebytes, mode, udp, ++number); + case PROTO_AH: + set_from_proposal_v1(this, proposal, lifetime, + lifebytes, mode, udp, ++number); break; default: break; diff --git a/src/libcharon/encoding/payloads/sa_payload.c b/src/libcharon/encoding/payloads/sa_payload.c index 613412014..3a5bb43a6 100644 --- a/src/libcharon/encoding/payloads/sa_payload.c +++ b/src/libcharon/encoding/payloads/sa_payload.c @@ -341,10 +341,10 @@ METHOD(sa_payload_t, get_ipcomp_proposals, linked_list_t*, { int current_proposal = -1, unsupported_proposal = -1; enumerator_t *enumerator; - proposal_substructure_t *substruct, *esp = NULL, *ipcomp = NULL; + proposal_substructure_t *substruct, *espah = NULL, *ipcomp = NULL; linked_list_t *list; - /* we currently only support the combination ESP+IPComp, find the first */ + /* we currently only support the combination ESP|AH+IPComp, find the first */ enumerator = this->proposals->create_enumerator(this->proposals); while (enumerator->enumerate(enumerator, &substruct)) { @@ -355,25 +355,27 @@ METHOD(sa_payload_t, get_ipcomp_proposals, linked_list_t*, { continue; } - if (protocol_id != PROTO_ESP && protocol_id != PROTO_IPCOMP) + if (protocol_id != PROTO_ESP && protocol_id != PROTO_AH && + protocol_id != PROTO_IPCOMP) { /* unsupported combination */ - esp = ipcomp = NULL; + espah = ipcomp = NULL; unsupported_proposal = current_proposal; continue; } if (proposal_number != current_proposal) { /* start of a new proposal */ - if (esp && ipcomp) + if (espah && ipcomp) { /* previous proposal is valid */ break; } - esp = ipcomp = NULL; + espah = ipcomp = NULL; current_proposal = proposal_number; } switch (protocol_id) { case PROTO_ESP: - esp = substruct; + case PROTO_AH: + espah = substruct; break; case PROTO_IPCOMP: ipcomp = substruct; @@ -383,9 +385,9 @@ METHOD(sa_payload_t, get_ipcomp_proposals, linked_list_t*, enumerator->destroy(enumerator); list = linked_list_create(); - if (esp && ipcomp && ipcomp->get_cpi(ipcomp, cpi)) + if (espah && ipcomp && ipcomp->get_cpi(ipcomp, cpi)) { - esp->get_proposals(esp, list); + espah->get_proposals(espah, list); } return list; } |