@@ -1474,21 +1474,35 @@ add_selected_version(Extensions) ->
14741474 Extensions #{server_hello_selected_version => SupportedVersions }.
14751475
14761476kse_remove_private_key (# key_share_entry {
1477- group = Group ,
1478- key_exchange =
1479- # 'ECPrivateKey' {publicKey = PublicKey }}) ->
1477+ group = Group ,
1478+ key_exchange =
1479+ # 'ECPrivateKey' {publicKey = PublicKey }}) ->
14801480 # key_share_entry {
14811481 group = Group ,
14821482 key_exchange = PublicKey };
14831483kse_remove_private_key (# key_share_entry {
1484- group = Group ,
1485- key_exchange =
1486- {PublicKey , _ }}) ->
1484+ group = Group ,
1485+ key_exchange =
1486+ {# 'ECPrivateKey' {publicKey = PublicKey1 },
1487+ {PublicKey2 , _ }}}) ->
1488+ # key_share_entry {
1489+ group = Group ,
1490+ key_exchange = <<PublicKey1 /binary , PublicKey2 /binary >>};
1491+ kse_remove_private_key (# key_share_entry {
1492+ group = Group ,
1493+ key_exchange =
1494+ {{PublicKey1 , _ }, {PublicKey2 , _ }}}) ->
1495+ # key_share_entry {
1496+ group = Group ,
1497+ key_exchange = <<PublicKey1 /binary , PublicKey2 /binary >>};
1498+ kse_remove_private_key (# key_share_entry {
1499+ group = Group ,
1500+ key_exchange =
1501+ {PublicKey , _ }}) ->
14871502 # key_share_entry {
14881503 group = Group ,
14891504 key_exchange = PublicKey }.
14901505
1491-
14921506signature_algs_ext (undefined ) ->
14931507 undefined ;
14941508signature_algs_ext (SignatureSchemes0 ) ->
@@ -2665,7 +2679,6 @@ encode_versions(Versions) ->
26652679
26662680encode_client_shares (ClientShares ) ->
26672681 << << (encode_key_share_entry (KeyShareEntry0 ))/binary >> || KeyShareEntry0 <- ClientShares >>.
2668-
26692682encode_key_share_entry (# key_share_entry {group = Group ,
26702683 key_exchange = KeyExchange }) ->
26712684 Len = byte_size (KeyExchange ),
@@ -3057,13 +3070,15 @@ decode_extensions(<<?UINT16(?KEY_SHARE_EXT), ?UINT16(Len),
30573070decode_extensions (<<? UINT16 (? KEY_SHARE_EXT ), ? UINT16 (Len ),
30583071 ExtData :Len /binary , Rest /binary >>,
30593072 Version , MessageType = server_hello , Acc ) ->
3060- <<? UINT16 (Group ),? UINT16 (KeyLen ),KeyExchange :KeyLen /binary >> = ExtData ,
3073+ <<? UINT16 (EnumGroup ),? UINT16 (KeyLen ),KeyExchange0 :KeyLen /binary >> = ExtData ,
3074+ Group = tls_v1 :enum_to_group (EnumGroup ),
3075+ KeyExchange = maybe_dec_server_hybrid_share (Group , KeyExchange0 ),
30613076 decode_extensions (Rest , Version , MessageType ,
30623077 Acc #{key_share =>
30633078 # key_share_server_hello {
30643079 server_share =
30653080 # key_share_entry {
3066- group = tls_v1 : enum_to_group ( Group ) ,
3081+ group = Group ,
30673082 key_exchange = KeyExchange }}});
30683083
30693084decode_extensions (<<? UINT16 (? KEY_SHARE_EXT ), ? UINT16 (Len ),
@@ -3204,8 +3219,53 @@ dec_hashsign(Value) ->
32043219 [HashSign ] = decode_sign_alg (? TLS_1_2 , Value ),
32053220 HashSign .
32063221
3222+ maybe_dec_server_hybrid_share (x25519mlkem768 , <<MLKem :1088 /binary , X25519 :32 /binary >>) ->
3223+ % % Concatenation of an ML-KEM ciphertext returned from
3224+ % % encapsulation to the client's encapsulation key The size of the
3225+ % % server share is 1120 bytes (1088 bytes for the ML-KEM part and
3226+ % % 32 bytes for X25519).
3227+ % % Note exception algorithm should be in reveres order of name due to legacy reason
3228+ {MLKem , X25519 };
3229+ maybe_dec_server_hybrid_share (secp256r1mlkem768 , <<Secp256r1 :65 /binary , MLKem :1088 /binary >>) ->
3230+ % % Concatenation of the server's ephemeral secp256r1 share encoded
3231+ % % in the same way as the client share and an ML-KEM The size of
3232+ % % the server share is 1153 bytes (1088 bytes for the ML-KEM part
3233+ % % and 65 bytes for secp256r1).
3234+ {Secp256r1 , MLKem };
3235+ maybe_dec_server_hybrid_share (secp384r1mlkem1024 , <<Secp384r1 :97 /binary , MLKem :1568 /binary >>) ->
3236+ % % Concatenation of the server's ephemeral secp384r1 share encoded
3237+ % % in the same way as the client share and an ML-KEM ciphertext
3238+ % % returned from encapsulation to the client's encapsulation key
3239+ % % The size of the server share is 1665 bytes (1568 bytes for the
3240+ % % ML-KEM part and 97 bytes for secp384r1)
3241+ {Secp384r1 , MLKem };
3242+ maybe_dec_server_hybrid_share (_ , Share ) ->
3243+ % % Not hybrid
3244+ Share .
3245+
3246+ maybe_dec_client_hybrid_share (x25519mlkem768 , <<MLKem :1184 /binary , X25519 :32 /binary >>) ->
3247+ % % Concatenation of the client's ML-KEM-768 encapsulation key and
3248+ % % the client's X25519 ephemeral share. The size of the client share
3249+ % % is 1216 bytes (1184 bytes for the ML-KEM part and 32 bytes for
3250+ % % X25519).
3251+ % % Note exception algorithm should be in reveres order of name due to legacy reason
3252+ {MLKem , X25519 };
3253+ maybe_dec_client_hybrid_share (secp256r1mlkem768 , <<Secp256r1 :65 /binary , MLKem :1184 /binary >>) ->
3254+ % % Concatenation of the secp256r1 ephemeral share and ML-KEM-768
3255+ % % encapsulation key The size of the client share is 1249 bytes (65
3256+ % % bytes for the secp256r1 part and 1184 bytes for ML-KEM). Ignore
3257+ % % unknown names (only host_name is supported)
3258+ {Secp256r1 , MLKem };
3259+ maybe_dec_client_hybrid_share (secp384r1mlkem1024 , <<Secp384r1 :97 /binary , MLKem :1568 /binary >>) ->
3260+ % % Concatenation of the secp384r1 ephemeral share and the
3261+ % % ML-KEM-1024 encapsulation key. The size of the client share
3262+ % % is 1665 bytes (97 bytes for the secp384r1 and the 1568 for the
3263+ % % ML-KEM).
3264+ {Secp384r1 , MLKem };
3265+ maybe_dec_client_hybrid_share (_ , Share ) ->
3266+ % % Not hybrid
3267+ Share .
32073268
3208- % % Ignore unknown names (only host_name is supported)
32093269dec_sni (<<? BYTE (? SNI_NAMETYPE_HOST_NAME ), ? UINT16 (Len ),
32103270 HostName :Len /binary , _ /binary >>) ->
32113271 # sni {hostname = binary_to_list (HostName )};
@@ -3231,12 +3291,13 @@ decode_client_shares(ClientShares) ->
32313291% %
32323292decode_client_shares (<<>>, Acc ) ->
32333293 lists :reverse (Acc );
3234- decode_client_shares (<<? UINT16 (Group0 ),? UINT16 (Len ),KeyExchange :Len /binary ,Rest /binary >>, Acc ) ->
3294+ decode_client_shares (<<? UINT16 (Group0 ),? UINT16 (Len ),KeyExchange0 :Len /binary ,Rest /binary >>, Acc ) ->
32353295 case tls_v1 :enum_to_group (Group0 ) of
32363296 undefined ->
32373297 % % Ignore key_share with unknown group
32383298 decode_client_shares (Rest , Acc );
32393299 Group ->
3300+ KeyExchange = maybe_dec_client_hybrid_share (Group , KeyExchange0 ),
32403301 decode_client_shares (Rest , [# key_share_entry {
32413302 group = Group ,
32423303 key_exchange = KeyExchange
0 commit comments