ikev1: Use same map for AH and ESP authentication algorithms
authorTobias Brunner <tobias@strongswan.org>
Mon, 24 Nov 2014 16:28:27 +0000 (17:28 +0100)
committerTobias Brunner <tobias@strongswan.org>
Tue, 9 Dec 2014 10:08:14 +0000 (11:08 +0100)
The transform identifier used in AH transforms is not the same as the
authentication algorithm identifier used in the transform attributes in
AH (and ESP) transforms.

src/libcharon/encoding/payloads/proposal_substructure.c

index fb9e785..48dcfeb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Tobias Brunner
+ * Copyright (C) 2012-2014 Tobias Brunner
  * Copyright (C) 2005-2010 Martin Willi
  * Copyright (C) 2005 Jan Hutter
  * Hochschule fuer Technik Rapperswil
@@ -224,26 +224,7 @@ typedef enum {
        /* FreeS/WAN proprietary */
        IKEV1_ESP_ENCR_SERPENT = 252,
        IKEV1_ESP_ENCR_TWOFISH = 253,
-} ikev1_esp_encr_transid_t;
-
-/**
- * IKEv1 Transform ID ESP authentication algorithm.
- */
-typedef enum {
-       IKEV1_ESP_AUTH_HMAC_MD5 = 1,
-       IKEV1_ESP_AUTH_HMAC_SHA = 2,
-       IKEV1_ESP_AUTH_DES_MAC = 3,
-       IKEV1_ESP_AUTH_KPDK = 4,
-       IKEV1_ESP_AUTH_HMAC_SHA2_256 = 5,
-       IKEV1_ESP_AUTH_HMAC_SHA2_384 = 6,
-       IKEV1_ESP_AUTH_HMAC_SHA2_512 = 7,
-       IKEV1_ESP_AUTH_HMAC_RIPEMD = 8,
-       IKEV1_ESP_AUTH_AES_XCBC_MAC = 9,
-       IKEV1_ESP_AUTH_SIG_RSA = 10,
-       IKEV1_ESP_AUTH_AES_128_GMAC = 11,
-       IKEV1_ESP_AUTH_AES_192_GMAC = 12,
-       IKEV1_ESP_AUTH_AES_256_GMAC = 13,
-} ikev1_esp_auth_transid_it;
+} ikev1_esp_transid_t;
 
 /**
  * IKEv1 Transform ID AH authentication algorithm.
@@ -264,6 +245,25 @@ typedef enum {
 } ikev1_ah_transid_t;
 
 /**
+ * IKEv1 authentication algorithm.
+ */
+typedef enum {
+       IKEV1_AUTH_HMAC_MD5 = 1,
+       IKEV1_AUTH_HMAC_SHA = 2,
+       IKEV1_AUTH_DES_MAC = 3,
+       IKEV1_AUTH_KPDK = 4,
+       IKEV1_AUTH_HMAC_SHA2_256 = 5,
+       IKEV1_AUTH_HMAC_SHA2_384 = 6,
+       IKEV1_AUTH_HMAC_SHA2_512 = 7,
+       IKEV1_AUTH_HMAC_RIPEMD = 8,
+       IKEV1_AUTH_AES_XCBC_MAC = 9,
+       IKEV1_AUTH_SIG_RSA = 10,
+       IKEV1_AUTH_AES_128_GMAC = 11,
+       IKEV1_AUTH_AES_192_GMAC = 12,
+       IKEV1_AUTH_AES_256_GMAC = 13,
+} ikev1_auth_algo_t;
+
+/**
  * IKEv1 ESP Encapsulation mode.
  */
 typedef enum {
@@ -620,7 +620,7 @@ static algo_map_t map_prf[] = {
 /**
  * ESP encryption algorithm mapping
  */
-static algo_map_t map_esp_encr[] = {
+static algo_map_t map_esp[] = {
        { IKEV1_ESP_ENCR_DES_IV64,                              ENCR_DES_IV64 },
        { IKEV1_ESP_ENCR_DES,                                   ENCR_DES },
        { IKEV1_ESP_ENCR_3DES,                                  ENCR_3DES },
@@ -646,23 +646,6 @@ static algo_map_t map_esp_encr[] = {
 };
 
 /**
- * ESP authentication algorithm mapping
- */
-static algo_map_t map_esp_auth[] = {
-       { IKEV1_ESP_AUTH_HMAC_MD5,                      AUTH_HMAC_MD5_96 },
-       { IKEV1_ESP_AUTH_HMAC_SHA,                      AUTH_HMAC_SHA1_96 },
-       { IKEV1_ESP_AUTH_DES_MAC,                       AUTH_DES_MAC },
-       { IKEV1_ESP_AUTH_KPDK,                          AUTH_KPDK_MD5 },
-       { IKEV1_ESP_AUTH_HMAC_SHA2_256,         AUTH_HMAC_SHA2_256_128 },
-       { IKEV1_ESP_AUTH_HMAC_SHA2_384,         AUTH_HMAC_SHA2_384_192 },
-       { IKEV1_ESP_AUTH_HMAC_SHA2_512,         AUTH_HMAC_SHA2_512_256 },
-       { IKEV1_ESP_AUTH_AES_XCBC_MAC,          AUTH_AES_XCBC_96 },
-       { IKEV1_ESP_AUTH_AES_128_GMAC,          AUTH_AES_128_GMAC },
-       { IKEV1_ESP_AUTH_AES_192_GMAC,          AUTH_AES_192_GMAC },
-       { IKEV1_ESP_AUTH_AES_256_GMAC,          AUTH_AES_256_GMAC },
-};
-
-/**
  * AH authentication algorithm mapping
  */
 static algo_map_t map_ah[] = {
@@ -679,34 +662,30 @@ static algo_map_t map_ah[] = {
 };
 
 /**
- * Get IKEv2 algorithm from IKEv1 identifier
+ * ESP/AH authentication algorithm mapping
  */
-static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
+static algo_map_t map_auth[] = {
+       { IKEV1_AUTH_HMAC_MD5,                  AUTH_HMAC_MD5_96 },
+       { IKEV1_AUTH_HMAC_SHA,                  AUTH_HMAC_SHA1_96 },
+       { IKEV1_AUTH_DES_MAC,                   AUTH_DES_MAC },
+       { IKEV1_AUTH_KPDK,                              AUTH_KPDK_MD5 },
+       { IKEV1_AUTH_HMAC_SHA2_256,             AUTH_HMAC_SHA2_256_128 },
+       { IKEV1_AUTH_HMAC_SHA2_384,             AUTH_HMAC_SHA2_384_192 },
+       { IKEV1_AUTH_HMAC_SHA2_512,             AUTH_HMAC_SHA2_512_256 },
+       { IKEV1_AUTH_AES_XCBC_MAC,              AUTH_AES_XCBC_96 },
+       { IKEV1_AUTH_AES_128_GMAC,              AUTH_AES_128_GMAC },
+       { IKEV1_AUTH_AES_192_GMAC,              AUTH_AES_192_GMAC },
+       { IKEV1_AUTH_AES_256_GMAC,              AUTH_AES_256_GMAC },
+};
+
+/**
+ * Map an IKEv1 to an IKEv2 identifier
+ */
+static u_int16_t ikev2_from_ikev1(algo_map_t *map, int count, u_int16_t def,
+                                                                 u_int16_t value)
 {
-       algo_map_t *map;
-       u_int16_t def;
-       int i, count;
+       int i;
 
-       switch (type)
-       {
-               case ENCRYPTION_ALGORITHM:
-                       map = map_encr;
-                       count = countof(map_encr);
-                       def = ENCR_UNDEFINED;
-                       break;
-               case INTEGRITY_ALGORITHM:
-                       map = map_integ;
-                       count = countof(map_integ);
-                       def = AUTH_UNDEFINED;
-                       break;
-               case PSEUDO_RANDOM_FUNCTION:
-                       map = map_prf;
-                       count = countof(map_prf);
-                       def = PRF_UNDEFINED;
-                       break;
-               default:
-                       return 0;
-       }
        for (i = 0; i < count; i++)
        {
                if (map[i].ikev1 == value)
@@ -718,30 +697,12 @@ static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
 }
 
 /**
- * Get IKEv1 algorithm from IKEv2 identifier
+ * Map an IKEv2 to an IKEv1 identifier
  */
-static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
+static u_int16_t ikev1_from_ikev2(algo_map_t *map, int count, u_int16_t value)
 {
-       algo_map_t *map;
-       int i, count;
+       int i;
 
-       switch (type)
-       {
-               case ENCRYPTION_ALGORITHM:
-                       map = map_encr;
-                       count = countof(map_encr);
-                       break;
-               case INTEGRITY_ALGORITHM:
-                       map = map_integ;
-                       count = countof(map_integ);
-                       break;
-               case PSEUDO_RANDOM_FUNCTION:
-                       map = map_prf;
-                       count = countof(map_prf);
-                       break;
-               default:
-                       return 0;
-       }
        for (i = 0; i < count; i++)
        {
                if (map[i].ikev2 == value)
@@ -753,87 +714,96 @@ static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
 }
 
 /**
- * Get IKEv2 algorithm from IKEv1 ESP transaction ID
+ * Get IKEv2 algorithm from IKEv1 identifier
  */
-static u_int16_t get_alg_from_ikev1_transid(protocol_id_t proto,
-                                                                               transform_type_t type, u_int16_t value)
+static u_int16_t get_alg_from_ikev1(transform_type_t type, u_int16_t value)
 {
-       algo_map_t *map;
-       u_int16_t def;
-       int i, count;
-
        switch (type)
        {
                case ENCRYPTION_ALGORITHM:
-                       map = map_esp_encr;
-                       count = countof(map_esp_encr);
-                       def = ENCR_UNDEFINED;
-                       break;
+                       return ikev2_from_ikev1(map_encr, countof(map_encr),
+                                                                       ENCR_UNDEFINED, value);
                case INTEGRITY_ALGORITHM:
-                       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;
+                       return ikev2_from_ikev1(map_integ, countof(map_integ),
+                                                                       AUTH_UNDEFINED, value);
+               case PSEUDO_RANDOM_FUNCTION:
+                       return ikev2_from_ikev1(map_prf, countof(map_prf),
+                                                                       PRF_UNDEFINED, value);
                default:
                        return 0;
        }
-       for (i = 0; i < count; i++)
+}
+
+/**
+ * Get IKEv1 algorithm from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_from_alg(transform_type_t type, u_int16_t value)
+{
+       switch (type)
        {
-               if (map[i].ikev1 == value)
-               {
-                       return map[i].ikev2;
-               }
+               case ENCRYPTION_ALGORITHM:
+                       return ikev1_from_ikev2(map_encr, countof(map_encr), value);
+               case INTEGRITY_ALGORITHM:
+                       return ikev1_from_ikev2(map_integ, countof(map_integ), value);
+               case PSEUDO_RANDOM_FUNCTION:
+                       return ikev1_from_ikev2(map_prf, countof(map_prf), value);
+               default:
+                       return 0;
        }
-       return def;
 }
 
 /**
- * Get IKEv1 ESP/AH transaction ID from IKEv2 identifier
+ * Get IKEv2 algorithm from IKEv1 ESP/AH transform ID
  */
-static u_int16_t get_ikev1_transid_from_alg(protocol_id_t proto,
-                                                                               transform_type_t type, u_int16_t value)
+static u_int16_t get_alg_from_ikev1_transid(transform_type_t type,
+                                                                                       u_int16_t value)
 {
-       algo_map_t *map;
-       int i, count;
-
        switch (type)
        {
                case ENCRYPTION_ALGORITHM:
-                       map = map_esp_encr;
-                       count = countof(map_esp_encr);
-                       break;
+                       return ikev2_from_ikev1(map_esp, countof(map_esp),
+                                                                       ENCR_UNDEFINED, value);
                case INTEGRITY_ALGORITHM:
-                       if (proto == PROTO_ESP)
-                       {
-                               map = map_esp_auth;
-                               count = countof(map_esp_auth);
-                       }
-                       else
-                       {
-                               map = map_ah;
-                               count = countof(map_ah);
-                       }
-                       break;
+                       return ikev2_from_ikev1(map_ah, countof(map_ah),
+                                                                       AUTH_UNDEFINED, value);
                default:
                        return 0;
        }
-       for (i = 0; i < count; i++)
+}
+
+/**
+ * Get IKEv1 ESP/AH transform ID from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_transid_from_alg(transform_type_t type,
+                                                                                       u_int16_t value)
+{
+       switch (type)
        {
-               if (map[i].ikev2 == value)
-               {
-                       return map[i].ikev1;
-               }
+               case ENCRYPTION_ALGORITHM:
+                       return ikev1_from_ikev2(map_esp, countof(map_esp), value);
+               case INTEGRITY_ALGORITHM:
+                       return ikev1_from_ikev2(map_ah, countof(map_ah), value);
+               default:
+                       return 0;
        }
-       return 0;
 }
+
+/**
+ * Get IKEv1 authentication algorithm from IKEv2 identifier
+ */
+static u_int16_t get_alg_from_ikev1_auth(u_int16_t value)
+{
+       return ikev2_from_ikev1(map_auth, countof(map_auth), AUTH_UNDEFINED, value);
+}
+
+/**
+ * Get IKEv1 authentication algorithm from IKEv2 identifier
+ */
+static u_int16_t get_ikev1_auth_from_alg(u_int16_t value)
+{
+       return ikev1_from_ikev2(map_auth, countof(map_auth), value);
+}
+
 /**
  * Get IKEv1 authentication attribute from auth_method_t
  */
@@ -971,8 +941,7 @@ static void add_to_proposal_v1(proposal_t *proposal,
                                break;
                        case TATTR_PH2_AUTH_ALGORITHM:
                                proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM,
-                                               get_alg_from_ikev1_transid(proto, INTEGRITY_ALGORITHM,
-                                                                                                  value), 0);
+                                                                               get_alg_from_ikev1_auth(value), 0);
                                break;
                        case TATTR_PH2_GROUP:
                                proposal->add_algorithm(proposal, DIFFIE_HELLMAN_GROUP,
@@ -989,7 +958,7 @@ static void add_to_proposal_v1(proposal_t *proposal,
                                                        NO_EXT_SEQ_NUMBERS, 0);
        if (proto == PROTO_ESP)
        {
-               encr = get_alg_from_ikev1_transid(proto, ENCRYPTION_ALGORITHM,
+               encr = get_alg_from_ikev1_transid(ENCRYPTION_ALGORITHM,
                                                                        transform->get_transform_id(transform));
                if (encr)
                {
@@ -1354,19 +1323,17 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this,
                                ipsec_mode_t mode, encap_t udp, int number)
 {
        transform_substructure_t *transform = NULL;
-       u_int16_t alg, key_size;
+       u_int16_t alg, transid, 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(proto, ENCRYPTION_ALGORITHM, alg);
-               if (alg)
+               transid = get_ikev1_transid_from_alg(ENCRYPTION_ALGORITHM, alg);
+               if (transid)
                {
                        transform = transform_substructure_create_type(
-                                                                       PLV1_TRANSFORM_SUBSTRUCTURE, number, alg);
+                                                               PLV1_TRANSFORM_SUBSTRUCTURE, number, transid);
                        if (key_size)
                        {
                                transform->add_transform_attribute(transform,
@@ -1380,13 +1347,14 @@ static void set_from_proposal_v1(private_proposal_substructure_t *this,
        enumerator = proposal->create_enumerator(proposal, INTEGRITY_ALGORITHM);
        if (enumerator->enumerate(enumerator, &alg, &key_size))
        {
-               alg = get_ikev1_transid_from_alg(proto, INTEGRITY_ALGORITHM, alg);
-               if (alg)
+               transid = get_ikev1_transid_from_alg(INTEGRITY_ALGORITHM, alg);
+               alg = get_ikev1_auth_from_alg(alg);
+               if (transid && alg)
                {
                        if (!transform)
                        {
                                transform = transform_substructure_create_type(
-                                                                       PLV1_TRANSFORM_SUBSTRUCTURE, number, alg);
+                                                               PLV1_TRANSFORM_SUBSTRUCTURE, number, transid);
                        }
                        transform->add_transform_attribute(transform,
                                transform_attribute_create_value(PLV1_TRANSFORM_ATTRIBUTE,