]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
proposal: Add supported KE methods to default ESP/AH proposals, but optional
authorTobias Brunner <tobias@strongswan.org>
Mon, 31 Mar 2025 14:28:47 +0000 (16:28 +0200)
committerTobias Brunner <tobias@strongswan.org>
Thu, 10 Apr 2025 06:31:10 +0000 (08:31 +0200)
This allows accepting clients that send proposals with non-optional KE
methods during rekeying, while still accepting clients that use the
previous non-KE default proposals.

src/libstrongswan/crypto/proposal/proposal.c

index 944486a5a17f7f02cabd7911c4131837d0718bf4..16151730fac867a086dcbae57ca1debb0f87f2bd 100644 (file)
@@ -1015,16 +1015,98 @@ proposal_t *proposal_create(protocol_id_t protocol, uint8_t number)
        return proposal_create_v1(protocol, number, 0);
 }
 
+/**
+ * Add supporte KE methods to proposal
+ */
+static void add_supported_ke_methods(private_proposal_t *this)
+{
+       enumerator_t *enumerator;
+       key_exchange_method_t ke;
+       const char *plugin_name;
+
+       /* Round 1 adds ECC with at least 128 bit security strength */
+       enumerator = lib->crypto->create_ke_enumerator(lib->crypto);
+       while (enumerator->enumerate(enumerator, &ke, &plugin_name))
+       {
+               switch (ke)
+               {
+                       case ECP_256_BIT:
+                       case ECP_384_BIT:
+                       case ECP_521_BIT:
+                       case ECP_256_BP:
+                       case ECP_384_BP:
+                       case ECP_512_BP:
+                       case CURVE_25519:
+                       case CURVE_448:
+                               add_algorithm(this, KEY_EXCHANGE_METHOD, ke, 0);
+                               break;
+                       default:
+                               break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       /* Round 2 adds other algorithms with at least 128 bit security strength */
+       enumerator = lib->crypto->create_ke_enumerator(lib->crypto);
+       while (enumerator->enumerate(enumerator, &ke, &plugin_name))
+       {
+               switch (ke)
+               {
+                       case MODP_3072_BIT:
+                       case MODP_4096_BIT:
+                       case MODP_6144_BIT:
+                       case MODP_8192_BIT:
+                               add_algorithm(this, KEY_EXCHANGE_METHOD, ke, 0);
+                               break;
+                       default:
+                               break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       /* Round 3 adds algorithms with less than 128 bit security strength */
+       enumerator = lib->crypto->create_ke_enumerator(lib->crypto);
+       while (enumerator->enumerate(enumerator, &ke, &plugin_name))
+       {
+               switch (ke)
+               {
+                       case MODP_NULL:
+                               /* only for testing purposes */
+                               break;
+                       case MODP_768_BIT:
+                       case MODP_1024_BIT:
+                       case MODP_1536_BIT:
+                               /* weak */
+                               break;
+                       case MODP_1024_160:
+                       case MODP_2048_224:
+                       case MODP_2048_256:
+                               /* RFC 5114 primes are of questionable source */
+                               break;
+                       case ECP_224_BIT:
+                       case ECP_224_BP:
+                       case ECP_192_BIT:
+                               /* rarely used */
+                               break;
+                       case MODP_2048_BIT:
+                               add_algorithm(this, KEY_EXCHANGE_METHOD, ke, 0);
+                               break;
+                       default:
+                               break;
+               }
+       }
+       enumerator->destroy(enumerator);
+}
+
 /**
  * Add supported IKE algorithms to proposal
  */
-static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
+static bool add_supported_ike(private_proposal_t *this, bool aead)
 {
        enumerator_t *enumerator;
        encryption_algorithm_t encryption;
        integrity_algorithm_t integrity;
        pseudo_random_function_t prf;
-       key_exchange_method_t group;
        const char *plugin_name;
 
        if (aead)
@@ -1215,78 +1297,7 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
        }
        enumerator->destroy(enumerator);
 
-       /* Round 1 adds ECC with at least 128 bit security strength */
-       enumerator = lib->crypto->create_ke_enumerator(lib->crypto);
-       while (enumerator->enumerate(enumerator, &group, &plugin_name))
-       {
-               switch (group)
-               {
-                       case ECP_256_BIT:
-                       case ECP_384_BIT:
-                       case ECP_521_BIT:
-                       case ECP_256_BP:
-                       case ECP_384_BP:
-                       case ECP_512_BP:
-                       case CURVE_25519:
-                       case CURVE_448:
-                               add_algorithm(this, KEY_EXCHANGE_METHOD, group, 0);
-                               break;
-                       default:
-                               break;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       /* Round 2 adds other algorithms with at least 128 bit security strength */
-       enumerator = lib->crypto->create_ke_enumerator(lib->crypto);
-       while (enumerator->enumerate(enumerator, &group, &plugin_name))
-       {
-               switch (group)
-               {
-                       case MODP_3072_BIT:
-                       case MODP_4096_BIT:
-                       case MODP_6144_BIT:
-                       case MODP_8192_BIT:
-                               add_algorithm(this, KEY_EXCHANGE_METHOD, group, 0);
-                               break;
-                       default:
-                               break;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       /* Round 3 adds algorithms with less than 128 bit security strength */
-       enumerator = lib->crypto->create_ke_enumerator(lib->crypto);
-       while (enumerator->enumerate(enumerator, &group, &plugin_name))
-       {
-               switch (group)
-               {
-                       case MODP_NULL:
-                               /* only for testing purposes */
-                               break;
-                       case MODP_768_BIT:
-                       case MODP_1024_BIT:
-                       case MODP_1536_BIT:
-                               /* weak */
-                               break;
-                       case MODP_1024_160:
-                       case MODP_2048_224:
-                       case MODP_2048_256:
-                               /* RFC 5114 primes are of questionable source */
-                               break;
-                       case ECP_224_BIT:
-                       case ECP_224_BP:
-                       case ECP_192_BIT:
-                               /* rarely used */
-                               break;
-                       case MODP_2048_BIT:
-                               add_algorithm(this, KEY_EXCHANGE_METHOD, group, 0);
-                               break;
-                       default:
-                               break;
-               }
-       }
-       enumerator->destroy(enumerator);
+       add_supported_ke_methods(this);
 
        return TRUE;
 }
@@ -1301,7 +1312,7 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
        switch (protocol)
        {
                case PROTO_IKE:
-                       if (!proposal_add_supported_ike(this, FALSE))
+                       if (!add_supported_ike(this, FALSE))
                        {
                                destroy(this);
                                return NULL;
@@ -1317,6 +1328,9 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
                        add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA1_96,       0);
                        add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_AES_XCBC_96,        0);
                        add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+                       /* add all supported KE methods, but make them optional */
+                       add_supported_ke_methods(this);
+                       add_algorithm(this, KEY_EXCHANGE_METHOD, KE_NONE, 0);
                        break;
                case PROTO_AH:
                        add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_256_128,  0);
@@ -1325,6 +1339,9 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
                        add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA1_96,       0);
                        add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_AES_XCBC_96,        0);
                        add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+                       /* add all supported KE methods, but make them optional */
+                       add_supported_ke_methods(this);
+                       add_algorithm(this, KEY_EXCHANGE_METHOD, KE_NONE, 0);
                        break;
                default:
                        break;
@@ -1343,7 +1360,7 @@ proposal_t *proposal_create_default_aead(protocol_id_t protocol)
        {
                case PROTO_IKE:
                        this = (private_proposal_t*)proposal_create(protocol, 0);
-                       if (!proposal_add_supported_ike(this, TRUE))
+                       if (!add_supported_ike(this, TRUE))
                        {
                                destroy(this);
                                return NULL;
@@ -1357,6 +1374,9 @@ proposal_t *proposal_create_default_aead(protocol_id_t protocol)
                        add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 192);
                        add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_GCM_ICV16, 256);
                        add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+                       /* add all supported KE methods, but make them optional */
+                       add_supported_ke_methods(this);
+                       add_algorithm(this, KEY_EXCHANGE_METHOD, KE_NONE, 0);
                        return &this->public;
                case PROTO_AH:
                default: