From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.haj.ipfire.org (localhost [127.0.0.1]) by mail02.haj.ipfire.org (Postfix) with ESMTP id 4ZyjVG3dZKz331l for ; Thu, 15 May 2025 08:07:02 +0000 (UTC) Received: from mail01.ipfire.org (mail01.haj.ipfire.org [172.28.1.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) client-signature RSA-PSS (4096 bits)) (Client CN "mail01.haj.ipfire.org", Issuer "R10" (verified OK)) by mail02.haj.ipfire.org (Postfix) with ESMTPS id 4ZyjVC0Lh1z2yTm for ; Thu, 15 May 2025 08:06:59 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mail01.ipfire.org (Postfix) with ESMTPSA id 4ZyjV44VpLz2Mg for ; Thu, 15 May 2025 08:06:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003rsa; t=1747296418; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=nniYtx5alVQ3XMAIVQhNI23BPiRYknCIuRwNvPCJ0Xs=; b=Pt181HHSUrtPsn4eIaB1TdIMfZkEbdafgYAzEXXAxnUd53TQz/0vwrFCiqP2mGvA5QtBKN kJBMeBs/oKQWi1WSXKbSb8imy1rrExa45QqwURUN7gJ4jg7o4dVMfX2IRFhw8aD657KRUL ZxDiaobYQcQt1ZbR38fnp4AIxFwYb2LCjrp0wwQa8WQukRBDNJYAnJ5Ah+RPDWxMxxvzyT aKnoqZmpDNkkaluX7yi5epqFJwVAk6rpCldeZsmGcy9Ijp16rWFlS7vdNfVP+j+Xz0ovPH A7XizsFqdYFADFql4MPbJM6mcai+e3XtENbvDik5SbFI5eFtU4OaMW3IPLrwhw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=ipfire.org; s=202003ed25519; t=1747296418; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=nniYtx5alVQ3XMAIVQhNI23BPiRYknCIuRwNvPCJ0Xs=; b=lT4pDTn6od4Y5gGvDvg821TiJhvp4wkwyykSe6cc8e1hTKgSkvqksrx+oTFWTZMIVkF55c iq7fo/Z2xvxxNxBw== Message-ID: <8baae50f-cf7b-4af0-81ec-89d898966993@ipfire.org> Date: Thu, 15 May 2025 08:06:00 +0000 Precedence: list List-Id: List-Subscribe: , List-Unsubscribe: , List-Post: List-Help: Sender: Mail-Followup-To: MIME-Version: 1.0 To: "IPFire: Development" From: =?UTF-8?Q?Peter_M=C3=BCller?= Subject: [PATCH 1/2] vpnmain.cgi: Use ML-KEM only as a hybrid with Curve 25519 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit 887778e0888d51eb9942ae310a43f6d2813efad3, the post-quantum key exchange algorithm ML-KEM was introduced, due to its support being added in strongSwan 6.0. However, using PQC key exchanges is commonly recommended only in conjunction with a traditional one, to avoid encrypted traffic becoming subject to trivial decryption in case a PQC algorithm proves weak, broken, or backdoored. OpenSSH, for instance, combines ML-KEM 768 with Curve 25519 (mlkem768x25519-sha256), rather than using ML-KEM alone. This patch changes the chipher suites offered for IPsec connections to always use ML-KEM as a hybrid with Curve 25519. This is possible due to strongSwan 6.0 having added support for IKE intermediary key exchanges (RFC 9370); see https://docs.strongswan.org/docs/latest/config/proposals.html#_key_exchange_methods for additional information. We can reasonably assume an IPsec peer supporting ML-KEM will also support Curve 25519, as this has been around for much longer, and is used quite commonly. Even if this is not the case, or if the IPsec peer does not implement RFC 9370, any IPsec connection using our default cipher selection will fall back to Curve 448, Curve 25519, or other, hence continue working. IPsec connections already created will need their ciphers to be changed once during the Core Update routine where this patch will be incorporated. Tested-by: Peter Müller Signed-off-by: Peter Müller --- html/cgi-bin/vpnmain.cgi | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/html/cgi-bin/vpnmain.cgi b/html/cgi-bin/vpnmain.cgi index 4f81fecdf..154b94033 100644 --- a/html/cgi-bin/vpnmain.cgi +++ b/html/cgi-bin/vpnmain.cgi @@ -2374,11 +2374,11 @@ END #use default advanced value $cgiparams{'IKE_ENCRYPTION'} = 'chacha20poly1305|aes256gcm128|aes256'; #[18]; $cgiparams{'IKE_INTEGRITY'} = 'sha2_512|sha2_256'; #[19]; - $cgiparams{'IKE_GROUPTYPE'} = 'mlkem1024|mlkem768|mlkem512|curve448|curve25519|e521|e384|4096|3072'; #[20]; + $cgiparams{'IKE_GROUPTYPE'} = 'x25519-ke1_mlkem1024|x25519-ke1_mlkem768|x25519-ke1_mlkem512|curve448|curve25519|e521|e384|4096|3072'; #[20]; $cgiparams{'IKE_LIFETIME'} = '3'; #[16]; $cgiparams{'ESP_ENCRYPTION'} = 'chacha20poly1305|aes256gcm128|aes256'; #[21]; $cgiparams{'ESP_INTEGRITY'} = 'sha2_512|sha2_256'; #[22]; - $cgiparams{'ESP_GROUPTYPE'} = 'mlkem1024|mlkem768|mlkem512|curve448|curve25519|e521|e384|4096|3072'; #[23]; + $cgiparams{'ESP_GROUPTYPE'} = 'x25519-ke1_mlkem1024|x25519-ke1_mlkem768|x25519-ke1_mlkem512|curve448|curve25519|e521|e384|4096|3072'; #[23]; $cgiparams{'ESP_KEYLIFE'} = '1'; #[17]; $cgiparams{'COMPRESSION'} = 'off'; #[13]; $cgiparams{'ONLY_PROPOSED'} = 'on'; #[24]; @@ -2759,7 +2759,7 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || goto ADVANCED_ERROR; } foreach my $val (@temp) { - if ($val !~ /^(mlkem(1024|768|512)|curve448|curve25519|e521|e384|e256|e224|e192|e512bp|e384bp|e256bp|e224bp|768|1024|1536|2048|3072|4096|6144|8192)$/) { + if ($val !~ /^(x25519-ke1_mlkem(1024|768|512)|curve448|curve25519|e521|e384|e256|e224|e192|e512bp|e384bp|e256bp|e224bp|768|1024|1536|2048|3072|4096|6144|8192)$/) { $errormessage = $Lang::tr{'invalid input'}; goto ADVANCED_ERROR; } @@ -2800,7 +2800,7 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || goto ADVANCED_ERROR; } foreach my $val (@temp) { - if ($val !~ /^(mlkem(1024|768|512)|curve448|curve25519|e521|e384|e256|e224|e192|e512bp|e384bp|e256bp|e224bp|768|1024|1536|2048|3072|4096|6144|8192|none)$/) { + if ($val !~ /^(x25519-ke1_mlkem(1024|768|512)|curve448|curve25519|e521|e384|e256|e224|e192|e512bp|e384bp|e256bp|e224bp|768|1024|1536|2048|3072|4096|6144|8192|none)$/) { $errormessage = $Lang::tr{'invalid input'}; goto ADVANCED_ERROR; } @@ -2940,9 +2940,9 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || $checked{'IKE_INTEGRITY'}{'aesxcbc'} = ''; @temp = split('\|', $cgiparams{'IKE_INTEGRITY'}); foreach my $key (@temp) {$checked{'IKE_INTEGRITY'}{$key} = "selected='selected'"; } - $checked{'IKE_GROUPTYPE'}{'mlkem1024'} = ''; - $checked{'IKE_GROUPTYPE'}{'mlkem768'} = ''; - $checked{'IKE_GROUPTYPE'}{'mlkem512'} = ''; + $checked{'IKE_GROUPTYPE'}{'x25519-ke1_mlkem1024'} = ''; + $checked{'IKE_GROUPTYPE'}{'x25519-ke1_mlkem768'} = ''; + $checked{'IKE_GROUPTYPE'}{'x25519-ke1_mlkem512'} = ''; $checked{'IKE_GROUPTYPE'}{'curve448'} = ''; $checked{'IKE_GROUPTYPE'}{'curve25519'} = ''; $checked{'IKE_GROUPTYPE'}{'768'} = ''; @@ -2983,9 +2983,9 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || $checked{'ESP_INTEGRITY'}{'aesxcbc'} = ''; @temp = split('\|', $cgiparams{'ESP_INTEGRITY'}); foreach my $key (@temp) {$checked{'ESP_INTEGRITY'}{$key} = "selected='selected'"; } - $checked{'ESP_GROUPTYPE'}{'mlkem1024'} = ''; - $checked{'ESP_GROUPTYPE'}{'mlkem768'} = ''; - $checked{'ESP_GROUPTYPE'}{'mlkem512'} = ''; + $checked{'ESP_GROUPTYPE'}{'x25519-ke1_mlkem1024'} = ''; + $checked{'ESP_GROUPTYPE'}{'x25519-ke1_mlkem768'} = ''; + $checked{'ESP_GROUPTYPE'}{'x25519-ke1_mlkem512'} = ''; $checked{'ESP_GROUPTYPE'}{'curve448'} = ''; $checked{'ESP_GROUPTYPE'}{'curve25519'} = ''; $checked{'ESP_GROUPTYPE'}{'768'} = ''; @@ -3151,9 +3151,9 @@ if(($cgiparams{'ACTION'} eq $Lang::tr{'advanced'}) || $Lang::tr{'grouptype'} - - - + + + @@ -3757,7 +3757,7 @@ sub make_algos($$$$$) { if ($mode eq "ike") { push(@algo, $int); - if ($grp =~ m/^mlkem(\d+)$/) { + if ($grp =~ m/^x25519-ke1_mlkem(\d+)$/) { push(@algo, "$grp"); } elsif ($grp =~ m/^e(.*)$/) { push(@algo, "ecp$1"); @@ -3776,7 +3776,7 @@ sub make_algos($$$$$) { if (!$pfs || $grp eq "none") { # noop - } elsif ($grp =~ m/^mlkem(\d+)$/) { + } elsif ($grp =~ m/^x25519-ke1_mlkem(\d+)$/) { push(@algo, "$grp"); } elsif ($grp =~ m/^e(.*)$/) { push(@algo, "ecp$1"); -- 2.43.0