diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl index d99249fc1a15..2b2514553890 100644 --- a/lib/ssl/src/ssl.erl +++ b/lib/ssl/src/ssl.erl @@ -693,8 +693,7 @@ Options common to both client and server side. Used to limit the size of valid TLS handshake packets to avoid DoS attacks. - Integer (24 bits, unsigned). Defaults to `256*1024` before OTP-26 or if SLH-DSA algorithms - are configured, otherwise the default is `256*1024`/2. + Integer (24 bits, unsigned). Defaults to `262144` since OTP 29.0 - **`{hibernate_after, HibernateTimeout}`** - Hibernate inactive connection processes. @@ -751,7 +750,7 @@ Common certificate related options to both client and server. connection will be selected. The different signature algorithms are prioritized in the following - order: `eddsa`, `ecdsa`, `rsa_pss_pss`, `rsa`, and `dsa`. If more + order: `mldsa`, `slhdsa`, `eddsa`, `ecdsa`, `rsa_pss_pss`, `rsa`, and `dsa`. If more than one key is supplied for the same signature algorithm, they will be prioritized by strength (except for _engine keys_; see the next paragraph). This offers flexibility to, for instance, configure a @@ -769,7 +768,7 @@ Common certificate related options to both client and server. > #### Note {: .info } > - > `eddsa` certificates are only supported by TLS-1.3 implementations that do not support `dsa` + > `mldsa`, `slhdsa`, `eddsa` certificates are only supported by TLS-1.3 implementations that do not support `dsa` > certificates. `rsa_pss_pss` (RSA certificates using Probabilistic Signature > Scheme) are supported in TLS-1.2 and TLS-1.3, but some TLS-1.2 implementations > do not support `rsa_pss_pss`. @@ -1392,7 +1391,7 @@ The following options are specific to the client side, or have different semantics for the client and server: - **`{psk_groups, Groups}`** - key exchange groups that the client -will send pre share keys for, defaults to first group in +will send pre shared keys for, defaults to the first group in supported_groups. Must be a subset of supported_groups and will be sent in the same order as they appear in supported_groups. @@ -1445,7 +1444,7 @@ different semantics for the client and server. > #### Change {: .info } > > The default for `Verify` was changed to `verify_peer` in - > Erlang/OTP 26. + > Erlang/OTP 26.0. - **`{cacerts, CACerts}`** - Trusted certificates @@ -1864,7 +1863,7 @@ Certificate related options for a server. `true`, the server fails if the client does not have a certificate to send, that is, sends an empty certificate. If set to `false`, it fails only if the client sends an invalid certificate (an empty certificate is considered valid). - Defaults to `true`, the default value was changed in OTP-26.0. + Defaults to `true`, the default value was changed in OTP 26.0. - **`{certificate_authorities, ServerCertAuth}`** - Inter-operate hint option @@ -3047,25 +3046,29 @@ Example: ```erlang 1> ssl:signature_algs(default, 'tlsv1.3'). -[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512, - ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256, - ecdsa_brainpoolP512r1tls13_sha512, - ecdsa_brainpoolP384r1tls13_sha384, - ecdsa_brainpoolP256r1tls13_sha256,rsa_pss_pss_sha512, - rsa_pss_pss_sha384,rsa_pss_pss_sha256,rsa_pss_rsae_sha512, - rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,mldsa44,mldsa65, - mldsa87,rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256, +[mldsa87,mldsa65,mldsa44,slh_dsa_shake_256f,slh_dsa_shake_256s, + slh_dsa_sha2_256f,slh_dsa_sha2_256s,slh_dsa_shake_192f,slh_dsa_shake_192s, + slh_dsa_sha2_192f,slh_dsa_sha2_192s,slh_dsa_shake_128f,slh_dsa_shake_128s, + slh_dsa_sha2_128f,slh_dsa_sha2_128s,eddsa_ed25519,eddsa_ed448, + ecdsa_secp521r1_sha512,ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256, + ecdsa_brainpoolP512r1tls13_sha512,ecdsa_brainpoolP384r1tls13_sha384, + ecdsa_brainpoolP256r1tls13_sha256,rsa_pss_pss_sha512,rsa_pss_pss_sha384, + rsa_pss_pss_sha256,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384, + rsa_pss_rsae_sha256,rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256, {sha512,ecdsa}, {sha384,ecdsa}, - {sha256,ecdsa}] + {sha256,ecdsa}]. 2> ssl:signature_algs(all, 'tlsv1.3'). -[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,ecdsa_secp384r1_sha384, - ecdsa_secp256r1_sha256,ecdsa_brainpoolP512r1tls13_sha512, - ecdsa_brainpoolP384r1tls13_sha384,ecdsa_brainpoolP256r1tls13_sha256, - rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,rsa_pss_rsae_sha512, - rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,mldsa44,mldsa65,mldsa87, - rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256, +[mldsa87,mldsa65,mldsa44,slh_dsa_shake_256f,slh_dsa_shake_256s, + slh_dsa_sha2_256f,slh_dsa_sha2_256s,slh_dsa_shake_192f,slh_dsa_shake_192s, + slh_dsa_sha2_192f,slh_dsa_sha2_192s,slh_dsa_shake_128f,slh_dsa_shake_128s, + slh_dsa_sha2_128f,slh_dsa_sha2_128s,eddsa_ed25519,eddsa_ed448, + ecdsa_secp521r1_sha512,ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256, + ecdsa_brainpoolP512r1tls13_sha512,ecdsa_brainpoolP384r1tls13_sha384, + ecdsa_brainpoolP256r1tls13_sha256,rsa_pss_pss_sha512,rsa_pss_pss_sha384, + rsa_pss_pss_sha256,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384, + rsa_pss_rsae_sha256,rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256, {sha512,ecdsa}, {sha384,ecdsa}, {sha256,ecdsa}, @@ -3078,15 +3081,15 @@ Example: {sha,dsa}] 3> [ssl:signature_algs(exclusive, 'tlsv1.3'). -[eddsa_ed25519,eddsa_ed448,ecdsa_secp521r1_sha512,ecdsa_secp384r1_sha384, - ecdsa_secp256r1_sha256,ecdsa_brainpoolP512r1tls13_sha512, - ecdsa_brainpoolP384r1tls13_sha384,ecdsa_brainpoolP256r1tls13_sha256, - rsa_pss_pss_sha512,rsa_pss_pss_sha384,rsa_pss_pss_sha256,rsa_pss_rsae_sha512, - rsa_pss_rsae_sha384,rsa_pss_rsae_sha256,mldsa44,mldsa65,mldsa87, - rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256,slh_dsa_shake_256f, - slh_dsa_shake_256s,slh_dsa_sha2_256f,slh_dsa_sha2_256s,slh_dsa_shake_192f, - slh_dsa_shake_192s,slh_dsa_sha2_192f,slh_dsa_sha2_192s,slh_dsa_shake_128f, - slh_dsa_shake_128s,slh_dsa_sha2_128f,slh_dsa_sha2_128s] +[mldsa87,mldsa65,mldsa44,slh_dsa_shake_256f,slh_dsa_shake_256s, + slh_dsa_sha2_256f,slh_dsa_sha2_256s,slh_dsa_shake_192f,slh_dsa_shake_192s, + slh_dsa_sha2_192f,slh_dsa_sha2_192s,slh_dsa_shake_128f,slh_dsa_shake_128s, + slh_dsa_sha2_128f,slh_dsa_sha2_128s,eddsa_ed25519,eddsa_ed448, + ecdsa_secp521r1_sha512,ecdsa_secp384r1_sha384,ecdsa_secp256r1_sha256, + ecdsa_brainpoolP512r1tls13_sha512,ecdsa_brainpoolP384r1tls13_sha384, + ecdsa_brainpoolP256r1tls13_sha256,rsa_pss_pss_sha512,rsa_pss_pss_sha384, + rsa_pss_pss_sha256,rsa_pss_rsae_sha512,rsa_pss_rsae_sha384, + rsa_pss_rsae_sha256,rsa_pkcs1_sha512,rsa_pkcs1_sha384,rsa_pkcs1_sha256] ``` > #### Note {: .info } @@ -3112,15 +3115,13 @@ signature_algs(default, 'tlsv1.2') -> signature_algs(all, 'tlsv1.3') -> tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.3'), tls_record:protocol_version_name('tlsv1.2')]) ++ - tls_v1:slh_dsa_schemes() ++ [ecdsa_sha1, rsa_pkcs1_sha1 | tls_v1:legacy_signature_algs_pre_13()] -- [{sha, ecdsa}, {sha, rsa}]; signature_algs(all, 'tlsv1.2') -> tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.2')]) ++ tls_v1:legacy_signature_algs_pre_13(); signature_algs(exclusive, 'tlsv1.3') -> - tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.3')]) ++ - tls_v1:slh_dsa_schemes(); + tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.3')]); signature_algs(exclusive, 'tlsv1.2') -> Algs = tls_v1:default_signature_algs([tls_record:protocol_version_name('tlsv1.2')]), Algs ++ tls_v1:legacy_signature_algs_pre_13(); @@ -3178,7 +3179,7 @@ eccs(Other) -> -doc """ Returns all supported groups in TLS 1.3. -Existed since OTP 22.0; documented as of OTP 27. +Existed since OTP 22.0; documented as of OTP 27.0. """. -spec groups() -> [group()]. %%-------------------------------------------------------------------- @@ -3193,7 +3194,7 @@ groups() -> -doc """ Returns default supported groups in TLS 1.3. -Existed since OTP 22.0; documented as of OTP 27. +Existed since OTP 22.0; documented as of OTP 27.0. """. %%-------------------------------------------------------------------- diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl index 5f66bf10224d..6e81a7c24569 100644 --- a/lib/ssl/src/ssl_certificate.erl +++ b/lib/ssl/src/ssl_certificate.erl @@ -361,7 +361,7 @@ available_cert_key_pairs(CertKeyGroups) -> %% Create the prioritized list of cert key pairs that %% are availble for use in the negotiated version available_cert_key_pairs(CertKeyGroups, ?TLS_1_3) -> - RevAlgos = [slhdsa, mldsa, rsa, rsa_pss_pss, ecdsa, eddsa], + RevAlgos = [rsa, rsa_pss_pss, ecdsa, eddsa, slhdsa, mldsa], cert_key_group_to_list(RevAlgos, CertKeyGroups, []); available_cert_key_pairs(CertKeyGroups, ?TLS_1_2) -> RevAlgos = [dsa, rsa, rsa_pss_pss, ecdsa], diff --git a/lib/ssl/src/ssl_config.erl b/lib/ssl/src/ssl_config.erl index 2e52b2f34590..13087fe9c05b 100644 --- a/lib/ssl/src/ssl_config.erl +++ b/lib/ssl/src/ssl_config.erl @@ -1469,10 +1469,10 @@ opt_supported_groups(UserOpts, #{versions := TlsVsns} = Opts, Env) -> opt_psk_groups(undefined, _, _, _) -> undefined; -opt_psk_groups(#supported_groups{supported_groups = SupportedGroups}, UserOpts, Opts, _Env) -> +opt_psk_groups(#supported_groups{supported_groups = [First| _] = SupportedGroups}, + UserOpts, Opts, _Env) -> %% Version dependency already asserted when SupportedGroups is supported - %% so is psk_groups - First = hd(SupportedGroups), + %% hence so is psk_groups case get_opt_list(psk_groups, [First], UserOpts, Opts) of {default, Default} -> Default; @@ -1495,30 +1495,11 @@ opt_crl(UserOpts, Opts, _Env) -> opt_handshake(UserOpts, Opts, _Env) -> {_, HS} = get_opt_of(handshake, [hello, full], full, UserOpts, Opts), - DefaultMaxHS = default_max_hs(Opts), - - {_, MHSS} = get_opt_int(max_handshake_size, 1, ?MAX_UNIT24 , DefaultMaxHS, + {_, MHSS} = get_opt_int(max_handshake_size, 1, ?MAX_UNIT24 , ?DEFAULT_MAX_HANDSHAKE_SIZE, UserOpts, Opts), Opts#{handshake => HS, max_handshake_size => MHSS}. -default_max_hs(#{signature_algs:= undefined}) -> - ?DEFAULT_MAX_HANDSHAKE_SIZE; -default_max_hs(#{signature_algs:= Algs}) -> - %%% In OTP-26 max handshake_size was lowered by half for most - %%% handshakes would fit that size and OpenSSL had a lower default - Set = sets:intersection(sets:from_list(Algs, [{version, 2}]), - sets:from_list(tls_v1:slh_dsa_schemes(), - [{version, 2}])), - case sets:is_empty(Set) of - true -> - ?DEFAULT_MAX_HANDSHAKE_SIZE; - false -> - %% SLH_DSA creates fairly big handshake sizes so raise limit back - %% if these algorithms are supported, - ?DEFAULT_MAX_HANDSHAKE_SIZE * 2 - end. - opt_use_srtp(UserOpts, #{protocol := Protocol} = Opts, _Env) -> UseSRTP = case get_opt_map(use_srtp, undefined, UserOpts, Opts) of {old, UseSRTP0} -> diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl index 6b2d933e7a8e..608cb9c35f0a 100644 --- a/lib/ssl/src/ssl_handshake.hrl +++ b/lib/ssl/src/ssl_handshake.hrl @@ -87,12 +87,10 @@ -define(FINISHED, 20). -define(MAX_UNIT24, 8388607). -%% Usually the biggest handshake message will be the message conveying the -%% certificate chain. This size should be sufficient for usual certificate -%% chains, certificates without special extensions have a typical size of -%% 1-2kB. By dividing the old default value by 2 we still have a slightly -%% bigger margin than OpenSSL --define(DEFAULT_MAX_HANDSHAKE_SIZE, ((256*1024) div 2)). +%% As of OTP-29 when PQC-algorithm SLH-DSA is supported by default +%% handshakes need to allowed to be bigger by default to handle +%% normal SLH-DSA keys. +-define(DEFAULT_MAX_HANDSHAKE_SIZE, 256*1024). -record(random, { gmt_unix_time, % uint32 diff --git a/lib/ssl/src/tls_v1.erl b/lib/ssl/src/tls_v1.erl index 31fcee3b10e1..5ae6e16bf3d7 100644 --- a/lib/ssl/src/tls_v1.erl +++ b/lib/ssl/src/tls_v1.erl @@ -1045,24 +1045,24 @@ signature_schemes(_, _) -> []. default_signature_schemes(Version) -> - Default = [eddsa_ed25519, - eddsa_ed448, - ecdsa_secp521r1_sha512, - ecdsa_secp384r1_sha384, - ecdsa_secp256r1_sha256, - ecdsa_brainpoolP512r1tls13_sha512, - ecdsa_brainpoolP384r1tls13_sha384, - ecdsa_brainpoolP256r1tls13_sha256, - rsa_pss_pss_sha512, - rsa_pss_pss_sha384, - rsa_pss_pss_sha256, - rsa_pss_rsae_sha512, - rsa_pss_rsae_sha384, - rsa_pss_rsae_sha256, - mldsa44, + Default = [mldsa87, mldsa65, - mldsa87 - ], + mldsa44] ++ slh_dsa_schemes() ++ + [eddsa_ed25519, + eddsa_ed448, + ecdsa_secp521r1_sha512, + ecdsa_secp384r1_sha384, + ecdsa_secp256r1_sha256, + ecdsa_brainpoolP512r1tls13_sha512, + ecdsa_brainpoolP384r1tls13_sha384, + ecdsa_brainpoolP256r1tls13_sha256, + rsa_pss_pss_sha512, + rsa_pss_pss_sha384, + rsa_pss_pss_sha256, + rsa_pss_rsae_sha512, + rsa_pss_rsae_sha384, + rsa_pss_rsae_sha256 + ], signature_schemes(Version, Default). legacy_signature_schemes(Version) -> @@ -1248,48 +1248,37 @@ ecc_curves(Version) when is_tuple(Version) -> ecc_curves(TLSCurves); ecc_curves(TLSCurves) -> [pubkey_cert_records:namedCurves(Curve) || Curve <- TLSCurves]. - + groups() -> TLSGroups = groups(all), groups(TLSGroups). -spec groups(all | default | TLSGroups :: list()) -> [ssl:group()]. groups(all) -> - [x25519, - x448, - secp521r1, - secp384r1, - secp256r1, - brainpoolP256r1tls13, - brainpoolP384r1tls13, - brainpoolP512r1tls13, - mlkem512, - mlkem768, - mlkem1024, - x25519mlkem768, - secp384r1mlkem1024, - secp256r1mlkem768, - ffdhe2048, - ffdhe3072, - ffdhe4096, - ffdhe6144, - ffdhe8192]; + default_pqc_hybrid_groups() ++ + [x25519, + x448, + secp521r1, + secp384r1, + secp256r1, + brainpoolP256r1tls13, + brainpoolP384r1tls13, + brainpoolP512r1tls13 + ] ++ + other_pqc_hybrid_groups() ++ + pqc_plain_groups() ++ + dhe_groups(); groups(default) -> - [x25519, - x448, - secp521r1, - secp384r1, - secp256r1, - brainpoolP512r1tls13, - brainpoolP384r1tls13, - brainpoolP256r1tls13, - mlkem512, - mlkem768, - mlkem1024, - x25519mlkem768, - secp384r1mlkem1024, - secp256r1mlkem768 - ]; + default_pqc_hybrid_groups() ++ + [x25519, + x448, + secp521r1, + secp384r1, + secp256r1, + brainpoolP512r1tls13, + brainpoolP384r1tls13, + brainpoolP256r1tls13 + ]; groups(TLSGroups) when is_list(TLSGroups) -> CryptoGroups = crypto_supported_groups(), lists:filter(fun(x25519mlkem768) -> @@ -1305,6 +1294,25 @@ groups(TLSGroups) when is_list(TLSGroups) -> proplists:get_bool(maybe_group_to_curve(Group), CryptoGroups) end, TLSGroups). +default_pqc_hybrid_groups() -> + [x25519mlkem768]. + +other_pqc_hybrid_groups()-> + [secp384r1mlkem1024, + secp256r1mlkem768]. + +pqc_plain_groups() -> + [mlkem1024, + mlkem768, + mlkem512]. + +dhe_groups() -> + [ffdhe2048, + ffdhe3072, + ffdhe4096, + ffdhe6144, + ffdhe8192]. + default_groups() -> TLSGroups = groups(default), groups(TLSGroups). diff --git a/lib/ssl/test/ssl_api_SUITE.erl b/lib/ssl/test/ssl_api_SUITE.erl index 01f4b0d55c3f..ae86f71f881e 100644 --- a/lib/ssl/test/ssl_api_SUITE.erl +++ b/lib/ssl/test/ssl_api_SUITE.erl @@ -2233,7 +2233,8 @@ customize_defaults(Opts, Role, Host) -> end, case proplists:get_value(protocol, Opts, tls) of dtls -> - {ok, #config{ssl=DOpts}} = ssl_config:handle_options([{protocol, dtls}|NoVerify], Role, Host), + {ok, #config{ssl=DOpts}} = + ssl_config:handle_options([{protocol, dtls}|NoVerify], Role, Host), {DOpts, DefOpts ++ Opts}; tls -> {ok, #config{ssl=DOpts}} = ssl_config:handle_options(NoVerify, Role, Host), @@ -2959,7 +2960,7 @@ options_fallback(_Config) -> ok. options_handshake(_Config) -> %% handshake - ?OK(#{handshake := full, max_handshake_size := 131072}, + ?OK(#{handshake := full, max_handshake_size := 262144}, [], client), ?OK(#{handshake := hello, max_handshake_size := 123800}, [{handshake, hello}, {max_handshake_size, 123800}], client),