Skip to content

Commit 5111deb

Browse files
authored
feat: add pure mlkem_1024 definition (#5468)
1 parent d83ebbb commit 5111deb

11 files changed

+166
-27
lines changed

crypto/s2n_ecc_evp.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ static EC_POINT *s2n_ecc_evp_blob_to_point(struct s2n_blob *blob, const EC_KEY *
5151
static int s2n_ecc_evp_generate_key_nist_curves(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
5252
static int s2n_ecc_evp_generate_own_key(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
5353
static int s2n_ecc_evp_compute_shared_secret(EVP_PKEY *own_key, EVP_PKEY *peer_public, uint16_t iana_id, struct s2n_blob *shared_secret);
54+
static int s2n_ecc_evp_generate_key_noop(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
5455

5556
/* IANA values can be found here: https://tools.ietf.org/html/rfc8446#appendix-B.3.1.4 */
5657

@@ -101,6 +102,14 @@ const struct s2n_ecc_named_curve s2n_unsupported_curve = {
101102
.generate_key = s2n_ecc_evp_generate_key_nist_curves,
102103
};
103104

105+
const struct s2n_ecc_named_curve s2n_ecc_curve_none = {
106+
.iana_id = 0,
107+
.name = "none",
108+
.libcrypto_nid = 0,
109+
.share_size = 0,
110+
.generate_key = s2n_ecc_evp_generate_key_noop,
111+
};
112+
104113
/* All curves that s2n supports. New curves MUST be added here.
105114
* This list is a super set of all the curves present in s2n_ecc_preferences list.
106115
*/
@@ -166,6 +175,11 @@ static int s2n_ecc_evp_generate_key_nist_curves(const struct s2n_ecc_named_curve
166175
return 0;
167176
}
168177

178+
static int s2n_ecc_evp_generate_key_noop(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey)
179+
{
180+
POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
181+
}
182+
169183
static int s2n_ecc_evp_generate_own_key(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey)
170184
{
171185
POSIX_ENSURE_REF(named_curve);

crypto/s2n_ecc_evp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ extern const struct s2n_ecc_named_curve s2n_ecc_curve_secp256r1;
4444
extern const struct s2n_ecc_named_curve s2n_ecc_curve_secp384r1;
4545
extern const struct s2n_ecc_named_curve s2n_ecc_curve_secp521r1;
4646
extern const struct s2n_ecc_named_curve s2n_ecc_curve_x25519;
47+
extern const struct s2n_ecc_named_curve s2n_ecc_curve_none;
4748

4849
/* BoringSSL only supports using EVP_PKEY_X25519 with "modern" EC EVP APIs. BoringSSL has a note to possibly add this in
4950
* the future. See https://github.com/google/boringssl/blob/master/crypto/evp/p_x25519_asn1.c#L233

tests/unit/kats/generate_pq_hybrid_tls13_handshake_kats.py renamed to tests/unit/kats/generate_pq_hybrid_and_pure_tls13_handshake_kats.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22
import hmac
33

44
# The PEM-encoded ECC private keys were used to generate the ECC shared secrets
5-
# are located in in s2n/tests/unit/s2n_tls13_hybrid_shared_secret_test.c with
5+
# are located in in s2n/tests/unit/s2n_tls13_hybrid_pq_shared_secret_test.c and
6+
# s2n/tests/unit/s2n_tls13_pure_pq_shared_secret_test.c with
67
# names like "CLIENT_{CURVE}_PRIV_KEY" and "SERVER_{CURVE}_PRIV_KEY".
78

89
# We aren't really concerned with the actual bytes of the transcript, only the hash.
910
# The transcript_hash values were calculated as:
1011
# hashlib.sha256(b"client_hello || server_hello").hexdigest()
1112
# hashlib.sha384(b"client_hello || server_hello").hexdigest()
12-
# The string "client_hello || server_hello" is used in s2n/tests/unit/s2n_tls13_hybrid_shared_secret_test.c.
13+
# The string "client_hello || server_hello" is used in s2n/tests/unit/s2n_tls13_hybrid_pq_shared_secret_test.c and
14+
# s2n/tests/unit/s2n_tls13_pure_pq_shared_secret_test.c
1315

1416
# The PQ shared secrets come from the first test vector in the corresponding NIST KAT.
1517
input_vectors = [
@@ -250,6 +252,20 @@
250252
"pq_shared_secret": "23f211b84a6ee20c8c29f6e5314c91b414e940513d380add17bd724ab3a13a52",
251253
"transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
252254
},
255+
{
256+
"group_name": "MLKEM1024",
257+
"cipher_suite": "TLS_AES_128_GCM_SHA256",
258+
"ec_shared_secret": "",
259+
"pq_shared_secret": "B408D5D115713F0A93047DBBEA832E4340787686D59A9A2D106BD662BA0AA035",
260+
"transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
261+
},
262+
{
263+
"group_name": "MLKEM1024",
264+
"cipher_suite": "TLS_AES_256_GCM_SHA384",
265+
"ec_shared_secret": "",
266+
"pq_shared_secret": "B408D5D115713F0A93047DBBEA832E4340787686D59A9A2D106BD662BA0AA035",
267+
"transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
268+
}
253269
]
254270

255271

@@ -278,6 +294,9 @@ def compute_secrets(input_vector: dict):
278294
if (input_vector["group_name"] == "X25519MLKEM768"):
279295
shared_secret = bytes.fromhex(input_vector["pq_shared_secret"] + input_vector["ec_shared_secret"])
280296

297+
if input_vector["group_name"].startswith("MLKEM"):
298+
shared_secret = bytes.fromhex(input_vector["pq_shared_secret"])
299+
281300
hash_alg = input_vector["cipher_suite"].split("_")[-1].lower()
282301
zeros = bytearray([0] * hashlib.new(hash_alg).digest_size)
283302
transcript_hash = bytes.fromhex(input_vector["transcript_hash"])

tests/unit/s2n_ecc_preferences_test.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,19 @@ int main(int argc, char **argv)
4545
EXPECT_FALSE(s2n_ecc_preferences_includes_curve(&s2n_ecc_preferences_20201021, TLS_EC_CURVE_ECDH_X25519));
4646
};
4747

48+
/* Test: validate all ecc preferences */
49+
{
50+
for (size_t policy_index = 0; security_policy_selection[policy_index].version != NULL; policy_index++) {
51+
const struct s2n_security_policy *security_policy = security_policy_selection[policy_index].security_policy;
52+
const struct s2n_ecc_preferences *ecc_preferences = security_policy->ecc_preferences;
53+
EXPECT_NOT_NULL(ecc_preferences);
54+
55+
for (size_t curve_index = 0; curve_index < ecc_preferences->count; curve_index++) {
56+
/* Ensure no placeholder curve "s2n_ecc_curve_none" is included in all security policies */
57+
EXPECT_NOT_EQUAL(ecc_preferences->ecc_curves[curve_index], &s2n_ecc_curve_none);
58+
}
59+
}
60+
};
61+
4862
END_TEST();
4963
}

tests/unit/s2n_kem_preferences_test.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ int main(int argc, char **argv)
7070
if (s2n_libcrypto_supports_mlkem()) {
7171
EXPECT_TRUE(s2n_kem_group_is_available(&s2n_secp256r1_mlkem_768));
7272
EXPECT_TRUE(s2n_kem_group_is_available(&s2n_secp384r1_mlkem_1024));
73+
EXPECT_TRUE(s2n_kem_group_is_available(&s2n_pure_mlkem_1024));
7374
if (s2n_is_evp_apis_supported()) {
7475
EXPECT_TRUE(s2n_kem_group_is_available(&s2n_x25519_mlkem_768));
7576
} else {
@@ -86,6 +87,7 @@ int main(int argc, char **argv)
8687
EXPECT_FALSE(s2n_kem_group_is_available(&s2n_secp256r1_mlkem_768));
8788
EXPECT_FALSE(s2n_kem_group_is_available(&s2n_x25519_mlkem_768));
8889
EXPECT_FALSE(s2n_kem_group_is_available(&s2n_secp384r1_mlkem_1024));
90+
EXPECT_FALSE(s2n_kem_group_is_available(&s2n_pure_mlkem_1024));
8991
}
9092
};
9193

tests/unit/s2n_tls13_hybrid_shared_secret_test.c renamed to tests/unit/s2n_tls13_hybrid_pq_shared_secret_test.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -607,46 +607,46 @@ int main(int argc, char **argv)
607607

608608
for (size_t i = 0; i < s2n_array_len(modes); i++) {
609609
/* Failures because of NULL arguments */
610-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(NULL, NULL), S2N_ERR_NULL);
610+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(NULL, NULL), S2N_ERR_NULL);
611611
struct s2n_connection *conn = NULL;
612612
EXPECT_NOT_NULL(conn = s2n_connection_new(modes[i]));
613-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(conn, NULL), S2N_ERR_NULL);
613+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(conn, NULL), S2N_ERR_NULL);
614614
DEFER_CLEANUP(struct s2n_blob calculated_shared_secret = { 0 }, s2n_free);
615-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(NULL, &calculated_shared_secret), S2N_ERR_NULL);
615+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(NULL, &calculated_shared_secret), S2N_ERR_NULL);
616616

617617
/* Failures because classic (non-hybrid) parameters were configured */
618618
conn->kex_params.server_ecc_evp_params.negotiated_curve = &s2n_ecc_curve_secp256r1;
619-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(conn, &calculated_shared_secret), S2N_ERR_SAFETY);
619+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(conn, &calculated_shared_secret), S2N_ERR_SAFETY);
620620
conn->kex_params.server_ecc_evp_params.negotiated_curve = NULL;
621621
EXPECT_SUCCESS(read_priv_ecc(&conn->kex_params.server_ecc_evp_params.evp_pkey, test_vector->client_ecc_key));
622-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(conn, &calculated_shared_secret), S2N_ERR_SAFETY);
622+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(conn, &calculated_shared_secret), S2N_ERR_SAFETY);
623623
EXPECT_SUCCESS(s2n_ecc_evp_params_free(&conn->kex_params.server_ecc_evp_params));
624624

625625
/* Failure because the chosen_client_kem_group_params is NULL */
626-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
626+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
627627

628628
/* Failures because the kem_group_params aren't set */
629-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
629+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
630630
conn->kex_params.server_kem_group_params.ecc_params.negotiated_curve = test_vector->kem_group->curve;
631-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
631+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
632632
conn->kex_params.client_kem_group_params.ecc_params.negotiated_curve = test_vector->kem_group->curve;
633633

634634
/* Failures because the ECC private keys are NULL */
635-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
635+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
636636
EXPECT_SUCCESS(read_priv_ecc(&conn->kex_params.client_kem_group_params.ecc_params.evp_pkey, test_vector->client_ecc_key));
637-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
637+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
638638
EXPECT_SUCCESS(read_priv_ecc(&conn->kex_params.server_kem_group_params.ecc_params.evp_pkey, test_vector->server_ecc_key));
639639

640640
/* Failure because pq_shared_secret is NULL */
641-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
641+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
642642
EXPECT_SUCCESS(s2n_dup(test_vector->pq_secret, &conn->kex_params.client_kem_group_params.kem_params.shared_secret));
643643

644644
/* Failure because the kem_group is NULL */
645-
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_hybrid_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
645+
EXPECT_FAILURE_WITH_ERRNO(s2n_tls13_compute_pq_shared_secret(conn, &calculated_shared_secret), S2N_ERR_NULL);
646646
conn->kex_params.server_kem_group_params.kem_group = test_vector->kem_group;
647647

648648
/* Finally, success */
649-
EXPECT_SUCCESS(s2n_tls13_compute_pq_hybrid_shared_secret(conn, &calculated_shared_secret));
649+
EXPECT_SUCCESS(s2n_tls13_compute_pq_shared_secret(conn, &calculated_shared_secret));
650650

651651
EXPECT_SUCCESS(s2n_connection_free(conn));
652652
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* A copy of the License is located at
6+
*
7+
* http://aws.amazon.com/apache2.0
8+
*
9+
* or in the "license" file accompanying this file. This file is distributed
10+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
11+
* express or implied. See the License for the specific language governing
12+
* permissions and limitations under the License.
13+
*/
14+
15+
#include "api/s2n.h"
16+
#include "crypto/s2n_pq.h"
17+
#include "tests/s2n_test.h"
18+
#include "tests/testlib/s2n_testlib.h"
19+
#include "tls/s2n_connection.h"
20+
#include "tls/s2n_tls13_handshake.c"
21+
#include "utils/s2n_blob.h"
22+
#include "utils/s2n_mem.h"
23+
#include "utils/s2n_safety.h"
24+
25+
#define MLKEM1024_SECRET "B408D5D115713F0A93047DBBEA832E4340787686D59A9A2D106BD662BA0AA035"
26+
27+
int main(int argc, char **argv)
28+
{
29+
BEGIN_TEST();
30+
31+
/* Test: TLS 1.3 pure ML-KEM-1024 shared secret computation */
32+
{
33+
S2N_BLOB_FROM_HEX(expected_secret, MLKEM1024_SECRET);
34+
35+
DEFER_CLEANUP(struct s2n_connection *client_conn = NULL, s2n_connection_ptr_free);
36+
DEFER_CLEANUP(struct s2n_connection *server_conn = NULL, s2n_connection_ptr_free);
37+
EXPECT_NOT_NULL(client_conn = s2n_connection_new(S2N_CLIENT));
38+
EXPECT_NOT_NULL(server_conn = s2n_connection_new(S2N_SERVER));
39+
40+
client_conn->kex_params.server_kem_group_params.kem_group = &s2n_pure_mlkem_1024;
41+
client_conn->kex_params.client_kem_group_params.kem_group = &s2n_pure_mlkem_1024;
42+
server_conn->kex_params.server_kem_group_params.kem_group = &s2n_pure_mlkem_1024;
43+
server_conn->kex_params.client_kem_group_params.kem_group = &s2n_pure_mlkem_1024;
44+
45+
client_conn->kex_params.server_kem_group_params.kem_params.kem = s2n_pure_mlkem_1024.kem;
46+
client_conn->kex_params.client_kem_group_params.kem_params.kem = s2n_pure_mlkem_1024.kem;
47+
server_conn->kex_params.server_kem_group_params.kem_params.kem = s2n_pure_mlkem_1024.kem;
48+
server_conn->kex_params.client_kem_group_params.kem_params.kem = s2n_pure_mlkem_1024.kem;
49+
50+
POSIX_GUARD(s2n_dup(&expected_secret,
51+
&client_conn->kex_params.client_kem_group_params.kem_params.shared_secret));
52+
POSIX_GUARD(s2n_dup(&expected_secret,
53+
&server_conn->kex_params.client_kem_group_params.kem_params.shared_secret));
54+
55+
DEFER_CLEANUP(struct s2n_blob client_secret = { 0 }, s2n_free);
56+
DEFER_CLEANUP(struct s2n_blob server_secret = { 0 }, s2n_free);
57+
58+
EXPECT_SUCCESS(s2n_tls13_compute_shared_secret(client_conn, &client_secret));
59+
EXPECT_SUCCESS(s2n_tls13_compute_shared_secret(server_conn, &server_secret));
60+
61+
S2N_BLOB_EXPECT_EQUAL(client_secret, server_secret);
62+
63+
EXPECT_EQUAL(client_secret.size, expected_secret.size);
64+
EXPECT_BYTEARRAY_EQUAL(client_secret.data, expected_secret.data, expected_secret.size);
65+
};
66+
67+
END_TEST();
68+
}

tls/s2n_kem.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,20 @@ const struct s2n_iana_to_kem kem_mapping[1] = {
110110
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml
111111
*/
112112

113+
/*
114+
* ML-KEM based pure PQ KEMs as specified by IETF and registered in IANA.
115+
*
116+
* https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8
117+
* https://datatracker.ietf.org/doc/draft-connolly-tls-mlkem-key-agreement/05/
118+
*/
119+
const struct s2n_kem_group s2n_pure_mlkem_1024 = {
120+
.name = "MLKEM1024",
121+
.iana_id = TLS_PQ_KEM_GROUP_ID_MLKEM_1024,
122+
.curve = &s2n_ecc_curve_none,
123+
.kem = &s2n_mlkem_1024,
124+
.send_kem_first = 0,
125+
};
126+
113127
/*
114128
* ML-KEM based hybrid KEMs as specified by IETF and registered in IANA.
115129
*

tls/s2n_kem.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ extern const struct s2n_kem_group s2n_x25519_mlkem_768;
118118
extern const struct s2n_kem_group s2n_x25519_kyber_512_r3;
119119
extern const struct s2n_kem_group s2n_x25519_kyber_768_r3;
120120

121+
/* Pure ML-KEM Groups */
122+
extern const struct s2n_kem_group s2n_pure_mlkem_1024;
123+
121124
S2N_RESULT s2n_kem_generate_keypair(struct s2n_kem_params *kem_params);
122125
S2N_RESULT s2n_kem_encapsulate(struct s2n_kem_params *kem_params, struct s2n_blob *ciphertext);
123126
S2N_RESULT s2n_kem_decapsulate(struct s2n_kem_params *kem_params, const struct s2n_blob *ciphertext);

tls/s2n_tls13_handshake.c

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,10 @@ int s2n_tls13_compute_ecc_shared_secret(struct s2n_connection *conn, struct s2n_
7373
}
7474

7575
/* Computes the ECDHE+PQKEM hybrid shared secret as defined in
76-
* https://tools.ietf.org/html/draft-stebila-tls-hybrid-design */
77-
int s2n_tls13_compute_pq_hybrid_shared_secret(struct s2n_connection *conn, struct s2n_blob *shared_secret)
76+
* https://tools.ietf.org/html/draft-stebila-tls-hybrid-design
77+
* Also supports "pure PQ" mode when kem_group->curve == &s2n_ecc_curve_none.
78+
*/
79+
int s2n_tls13_compute_pq_shared_secret(struct s2n_connection *conn, struct s2n_blob *shared_secret)
7880
{
7981
POSIX_ENSURE_REF(conn);
8082
POSIX_ENSURE_REF(shared_secret);
@@ -93,15 +95,6 @@ int s2n_tls13_compute_pq_hybrid_shared_secret(struct s2n_connection *conn, struc
9395
struct s2n_ecc_evp_params *client_ecc_params = &client_kem_group_params->ecc_params;
9496
POSIX_ENSURE_REF(client_ecc_params);
9597

96-
DEFER_CLEANUP(struct s2n_blob ecdhe_shared_secret = { 0 }, s2n_free_or_wipe);
97-
98-
/* Compute the ECDHE shared secret, and retrieve the PQ shared secret. */
99-
if (conn->mode == S2N_CLIENT) {
100-
POSIX_GUARD(s2n_ecc_evp_compute_shared_secret_from_params(client_ecc_params, server_ecc_params, &ecdhe_shared_secret));
101-
} else {
102-
POSIX_GUARD(s2n_ecc_evp_compute_shared_secret_from_params(server_ecc_params, client_ecc_params, &ecdhe_shared_secret));
103-
}
104-
10598
struct s2n_blob *pq_shared_secret = &client_kem_group_params->kem_params.shared_secret;
10699
POSIX_ENSURE_REF(pq_shared_secret);
107100
POSIX_ENSURE_REF(pq_shared_secret->data);
@@ -110,6 +103,16 @@ int s2n_tls13_compute_pq_hybrid_shared_secret(struct s2n_connection *conn, struc
110103
POSIX_ENSURE_REF(negotiated_kem_group);
111104
POSIX_ENSURE_REF(negotiated_kem_group->kem);
112105

106+
DEFER_CLEANUP(struct s2n_blob ecdhe_shared_secret = { 0 }, s2n_free_or_wipe);
107+
108+
if (negotiated_kem_group->curve == &s2n_ecc_curve_none) {
109+
POSIX_ENSURE_EQ(ecdhe_shared_secret.size, 0);
110+
} else if (conn->mode == S2N_CLIENT) {
111+
POSIX_GUARD(s2n_ecc_evp_compute_shared_secret_from_params(client_ecc_params, server_ecc_params, &ecdhe_shared_secret));
112+
} else {
113+
POSIX_GUARD(s2n_ecc_evp_compute_shared_secret_from_params(server_ecc_params, client_ecc_params, &ecdhe_shared_secret));
114+
}
115+
113116
POSIX_ENSURE_EQ(pq_shared_secret->size, negotiated_kem_group->kem->shared_secret_key_length);
114117

115118
/* Construct the concatenated/hybrid shared secret */
@@ -139,7 +142,7 @@ int s2n_tls13_compute_shared_secret(struct s2n_connection *conn, struct s2n_blob
139142
POSIX_ENSURE_REF(conn);
140143

141144
if (s2n_tls13_pq_hybrid_supported(conn)) {
142-
POSIX_GUARD(s2n_tls13_compute_pq_hybrid_shared_secret(conn, shared_secret));
145+
POSIX_GUARD(s2n_tls13_compute_pq_shared_secret(conn, shared_secret));
143146
} else {
144147
POSIX_GUARD(s2n_tls13_compute_ecc_shared_secret(conn, shared_secret));
145148
}

0 commit comments

Comments
 (0)