Skip to content

Commit 7166902

Browse files
authored
feat: add secp384r1_mlkem_1024 kem group (#5395)
1 parent 0b89213 commit 7166902

File tree

8 files changed

+108
-4
lines changed

8 files changed

+108
-4
lines changed

tests/policy_snapshot/snapshots/test_all

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ pq:
7171
- kem groups:
7272
-- X25519MLKEM768
7373
-- SecP256r1MLKEM768
74+
-- SecP384r1MLKEM1024
7475
-- SecP256r1Kyber768Draft00
7576
-- X25519Kyber768Draft00
7677
-- secp384r1_kyber-768-r3

tests/unit/kats/generate_pq_hybrid_tls13_handshake_kats.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,20 @@
236236
"pq_shared_secret": "B408D5D115713F0A93047DBBEA832E4340787686D59A9A2D106BD662BA0AA035",
237237
"transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
238238
},
239+
{
240+
"group_name": "SecP384r1MLKEM1024",
241+
"cipher_suite": "TLS_AES_128_GCM_SHA256",
242+
"ec_shared_secret": "b72536062cd8e8eced91046e33413b027cabde0576747aa47863b8dcb914100585c600fafc8ff4927a34abb0aa6b3b68",
243+
"pq_shared_secret": "23f211b84a6ee20c8c29f6e5314c91b414e940513d380add17bd724ab3a13a52",
244+
"transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
245+
},
246+
{
247+
"group_name": "SecP384r1MLKEM1024",
248+
"cipher_suite": "TLS_AES_256_GCM_SHA384",
249+
"ec_shared_secret": "b72536062cd8e8eced91046e33413b027cabde0576747aa47863b8dcb914100585c600fafc8ff4927a34abb0aa6b3b68",
250+
"pq_shared_secret": "23f211b84a6ee20c8c29f6e5314c91b414e940513d380add17bd724ab3a13a52",
251+
"transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
252+
},
239253
]
240254

241255

tests/unit/s2n_kem_preferences_test.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ int main(int argc, char **argv)
2727

2828
EXPECT_FALSE(s2n_kem_preferences_includes_tls13_kem_group(&kem_preferences_null, TLS_PQ_KEM_GROUP_ID_SECP256R1_MLKEM_768));
2929
EXPECT_FALSE(s2n_kem_preferences_includes_tls13_kem_group(&kem_preferences_null, TLS_PQ_KEM_GROUP_ID_X25519_MLKEM_768));
30+
EXPECT_FALSE(s2n_kem_preferences_includes_tls13_kem_group(&kem_preferences_null, TLS_PQ_KEM_GROUP_ID_SECP384R1_MLKEM_1024));
3031
EXPECT_FALSE(s2n_kem_preferences_includes_tls13_kem_group(&kem_preferences_null, TLS_PQ_KEM_GROUP_ID_X25519_KYBER_512_R3));
3132
EXPECT_FALSE(s2n_kem_preferences_includes_tls13_kem_group(&kem_preferences_null, TLS_PQ_KEM_GROUP_ID_X25519_KYBER_768_R3));
3233
EXPECT_FALSE(s2n_kem_preferences_includes_tls13_kem_group(&kem_preferences_null, TLS_PQ_KEM_GROUP_ID_SECP256R1_KYBER_512_R3));
@@ -44,6 +45,7 @@ int main(int argc, char **argv)
4445

4546
EXPECT_TRUE(s2n_kem_preferences_includes_tls13_kem_group(&test_prefs, TLS_PQ_KEM_GROUP_ID_SECP256R1_MLKEM_768));
4647
EXPECT_TRUE(s2n_kem_preferences_includes_tls13_kem_group(&test_prefs, TLS_PQ_KEM_GROUP_ID_X25519_MLKEM_768));
48+
EXPECT_TRUE(s2n_kem_preferences_includes_tls13_kem_group(&test_prefs, TLS_PQ_KEM_GROUP_ID_SECP384R1_MLKEM_1024));
4749
EXPECT_TRUE(s2n_kem_preferences_includes_tls13_kem_group(&test_prefs, TLS_PQ_KEM_GROUP_ID_X25519_KYBER_512_R3));
4850
EXPECT_TRUE(s2n_kem_preferences_includes_tls13_kem_group(&test_prefs, TLS_PQ_KEM_GROUP_ID_X25519_KYBER_768_R3));
4951
EXPECT_TRUE(s2n_kem_preferences_includes_tls13_kem_group(&test_prefs, TLS_PQ_KEM_GROUP_ID_SECP256R1_KYBER_512_R3));
@@ -67,6 +69,7 @@ int main(int argc, char **argv)
6769

6870
if (s2n_libcrypto_supports_mlkem()) {
6971
EXPECT_TRUE(s2n_kem_group_is_available(&s2n_secp256r1_mlkem_768));
72+
EXPECT_TRUE(s2n_kem_group_is_available(&s2n_secp384r1_mlkem_1024));
7073
if (s2n_is_evp_apis_supported()) {
7174
EXPECT_TRUE(s2n_kem_group_is_available(&s2n_x25519_mlkem_768));
7275
} else {
@@ -82,6 +85,7 @@ int main(int argc, char **argv)
8285
EXPECT_FALSE(s2n_kem_group_is_available(&s2n_secp521r1_kyber_1024_r3));
8386
EXPECT_FALSE(s2n_kem_group_is_available(&s2n_secp256r1_mlkem_768));
8487
EXPECT_FALSE(s2n_kem_group_is_available(&s2n_x25519_mlkem_768));
88+
EXPECT_FALSE(s2n_kem_group_is_available(&s2n_secp384r1_mlkem_1024));
8589
}
8690
};
8791

tests/unit/s2n_tls13_hybrid_shared_secret_test.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ struct hybrid_test_vector {
138138
#define KYBER768R3_SECRET "914CB67FE5C38E73BF74181C0AC50428DEDF7750A98058F7D536708774535B29"
139139
#define KYBER1024R3_SECRET "B10F7394926AD3B49C5D62D5AEB531D5757538BCC0DA9E550D438F1B61BD7419"
140140
#define MLKEM768_SECRET "B408D5D115713F0A93047DBBEA832E4340787686D59A9A2D106BD662BA0AA035"
141+
#define MLKEM1024_SECRET "23f211b84a6ee20c8c29f6e5314c91b414e940513d380add17bd724ab3a13a52"
141142

142143
#define X25519_KYBER512R3_HYBRID_SECRET (X25519_SHARED_SECRET KYBER512R3_SECRET)
143144
#define X25519_KYBER768R3_HYBRID_SECRET (X25519_SHARED_SECRET KYBER768R3_SECRET)
@@ -147,6 +148,7 @@ struct hybrid_test_vector {
147148
#define SECP521R1_KYBER1024R3_HYBRID_SECRET (SECP521R1_SHARED_SECRET KYBER1024R3_SECRET)
148149
#define X25519_MLKEM768_HYBRID_SECRET (MLKEM768_SECRET X25519_SHARED_SECRET)
149150
#define SECP256R1_MLKEM768_HYBRID_SECRET (SECP256R1_SHARED_SECRET MLKEM768_SECRET)
151+
#define SECP384R1_MLKEM1024_HYBRID_SECRET (SECP384R1_SHARED_SECRET MLKEM1024_SECRET)
150152

151153
/* The expected traffic secrets were calculated from an independent Python implementation located in the KAT directory,
152154
* using the ECDHE & PQ secrets defined above. */
@@ -190,6 +192,11 @@ struct hybrid_test_vector {
190192
#define AES_256_X25519_MLKEM768_CLIENT_TRAFFIC_SECRET "44eb9e15ef082936fe7a2c169be644ff16b47fb2a91f7223069cbd8d9b063a034f0936234e60a733a30db6d7226d984d"
191193
#define AES_256_X25519_MLKEM768_SERVER_TRAFFIC_SECRET "852b46f0e3cdc222badc0b85f4cfb4f332c2d8ea8c9695d6024e129b5056d2c534191ee76bff50148f19a88f81897112"
192194

195+
#define AES_128_SECP384R1_MLKEM1024_CLIENT_TRAFFIC_SECRET "367b160926dc977e255fa5fdd15c51a3942f98a492db05d74777ed4498882179"
196+
#define AES_128_SECP384R1_MLKEM1024_SERVER_TRAFFIC_SECRET "93c1dcb54fa694957f8decde496944533d64a6e11884bfb8c928cd3b9e954836"
197+
#define AES_256_SECP384R1_MLKEM1024_CLIENT_TRAFFIC_SECRET "900c6409a1f1d748006759b8276a2ae7b74dca44d9c4e52083952e7cf1c868cba34c270b802dea59a7a8a00b919ff061"
198+
#define AES_256_SECP384R1_MLKEM1024_SERVER_TRAFFIC_SECRET "ccabea1600385fdd3587429d701aae0efcf6acac0bab0f194d571d78fa8755a0d0a58364c07c14fbe288a67843b68530"
199+
193200
/* A fake transcript string to hash when deriving handshake secrets */
194201
#define FAKE_TRANSCRIPT "client_hello || server_hello"
195202

@@ -431,6 +438,39 @@ int main(int argc, char **argv)
431438
.expected_server_traffic_secret = &aes_256_secp256r1_mlkem768_server_secret,
432439
};
433440

441+
S2N_BLOB_FROM_HEX(mlkem1024_secret, MLKEM1024_SECRET);
442+
S2N_BLOB_FROM_HEX(secp384r1_mlkem1024_hybrid_secret, SECP384R1_MLKEM1024_HYBRID_SECRET);
443+
444+
S2N_BLOB_FROM_HEX(aes_128_secp384r1_mlkem1024_client_secret, AES_128_SECP384R1_MLKEM1024_CLIENT_TRAFFIC_SECRET);
445+
S2N_BLOB_FROM_HEX(aes_128_secp384r1_mlkem1024_server_secret, AES_128_SECP384R1_MLKEM1024_SERVER_TRAFFIC_SECRET);
446+
447+
const struct hybrid_test_vector aes_128_sha_256_secp384r1_mlkem1024_vector = {
448+
.cipher_suite = &s2n_tls13_aes_128_gcm_sha256,
449+
.transcript = FAKE_TRANSCRIPT,
450+
.kem_group = &s2n_secp384r1_mlkem_1024,
451+
.client_ecc_key = CLIENT_SECP384R1_PRIV_KEY,
452+
.server_ecc_key = SERVER_SECP384R1_PRIV_KEY,
453+
.pq_secret = &mlkem1024_secret,
454+
.expected_hybrid_secret = &secp384r1_mlkem1024_hybrid_secret,
455+
.expected_client_traffic_secret = &aes_128_secp384r1_mlkem1024_client_secret,
456+
.expected_server_traffic_secret = &aes_128_secp384r1_mlkem1024_server_secret,
457+
};
458+
459+
S2N_BLOB_FROM_HEX(aes_256_secp384r1_mlkem1024_client_secret, AES_256_SECP384R1_MLKEM1024_CLIENT_TRAFFIC_SECRET);
460+
S2N_BLOB_FROM_HEX(aes_256_secp384r1_mlkem1024_server_secret, AES_256_SECP384R1_MLKEM1024_SERVER_TRAFFIC_SECRET);
461+
462+
const struct hybrid_test_vector aes_256_sha_384_secp384r1_mlkem1024_vector = {
463+
.cipher_suite = &s2n_tls13_aes_256_gcm_sha384,
464+
.transcript = FAKE_TRANSCRIPT,
465+
.kem_group = &s2n_secp384r1_mlkem_1024,
466+
.client_ecc_key = CLIENT_SECP384R1_PRIV_KEY,
467+
.server_ecc_key = SERVER_SECP384R1_PRIV_KEY,
468+
.pq_secret = &mlkem1024_secret,
469+
.expected_hybrid_secret = &secp384r1_mlkem1024_hybrid_secret,
470+
.expected_client_traffic_secret = &aes_256_secp384r1_mlkem1024_client_secret,
471+
.expected_server_traffic_secret = &aes_256_secp384r1_mlkem1024_server_secret,
472+
};
473+
434474
S2N_BLOB_FROM_HEX(aes_128_x25519_mlkem768_client_secret, AES_128_X25519_MLKEM768_CLIENT_TRAFFIC_SECRET);
435475
S2N_BLOB_FROM_HEX(aes_128_x25519_mlkem768_server_secret, AES_128_X25519_MLKEM768_SERVER_TRAFFIC_SECRET);
436476

@@ -476,6 +516,8 @@ int main(int argc, char **argv)
476516
&aes_256_sha_384_x25519_kyber768r3_vector,
477517
&aes_128_sha_256_secp256r1_mlkem768_vector,
478518
&aes_256_sha_384_secp256r1_mlkem768_vector,
519+
&aes_128_sha_256_secp384r1_mlkem1024_vector,
520+
&aes_256_sha_384_secp384r1_mlkem1024_vector,
479521
&aes_128_sha_256_x25519_mlkem768_vector,
480522
&aes_256_sha_384_x25519_mlkem768_vector,
481523
};

tests/unit/s2n_tls13_pq_handshake_test.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,26 @@ int main()
446446
.ecc_preferences = &s2n_ecc_preferences_20240603,
447447
};
448448

449+
const struct s2n_kem_group *mlkem1024_test_groups[] = {
450+
&s2n_secp384r1_mlkem_1024,
451+
};
452+
453+
const struct s2n_kem_preferences mlkem1024_test_prefs = {
454+
.kem_count = 0,
455+
.kems = NULL,
456+
.tls13_kem_group_count = s2n_array_len(mlkem1024_test_groups),
457+
.tls13_kem_groups = mlkem1024_test_groups,
458+
.tls13_pq_hybrid_draft_revision = 5
459+
};
460+
461+
const struct s2n_security_policy mlkem1024_test_policy = {
462+
.minimum_protocol_version = S2N_TLS13,
463+
.cipher_preferences = &cipher_preferences_20190801,
464+
.kem_preferences = &mlkem1024_test_prefs,
465+
.signature_preferences = &s2n_signature_preferences_20200207,
466+
.ecc_preferences = &s2n_ecc_preferences_20240603,
467+
};
468+
449469
const struct s2n_security_policy ecc_retry_policy = {
450470
.minimum_protocol_version = security_policy_pq_tls_1_0_2020_12.minimum_protocol_version,
451471
.cipher_preferences = security_policy_pq_tls_1_0_2020_12.cipher_preferences,
@@ -508,10 +528,12 @@ int main()
508528

509529
/* ML-KEM is only available on newer versions of AWS-LC. If it's
510530
* unavailable, we must downgrade the assertions to Kyber or EC. */
511-
const struct s2n_kem_group *null_if_no_mlkem = &s2n_x25519_mlkem_768;
531+
const struct s2n_kem_group *null_if_no_mlkem_768 = &s2n_x25519_mlkem_768;
532+
const struct s2n_kem_group *null_if_no_mlkem_1024 = &s2n_secp384r1_mlkem_1024;
512533
const struct s2n_ecc_named_curve *ec_if_no_mlkem = NULL;
513534
if (!s2n_libcrypto_supports_mlkem()) {
514-
null_if_no_mlkem = NULL;
535+
null_if_no_mlkem_768 = NULL;
536+
null_if_no_mlkem_1024 = NULL;
515537
ec_if_no_mlkem = default_curve;
516538
}
517539

@@ -733,7 +755,17 @@ int main()
733755
{
734756
.client_policy = &mlkem768_test_policy,
735757
.server_policy = &mlkem768_test_policy,
736-
.expected_kem_group = null_if_no_mlkem,
758+
.expected_kem_group = null_if_no_mlkem_768,
759+
.expected_curve = ec_if_no_mlkem,
760+
.hrr_expected = false,
761+
.len_prefix_expected = false,
762+
},
763+
764+
/* Confirm that MLKEM1024 is negotiable */
765+
{
766+
.client_policy = &mlkem1024_test_policy,
767+
.server_policy = &mlkem1024_test_policy,
768+
.expected_kem_group = null_if_no_mlkem_1024,
737769
.expected_curve = ec_if_no_mlkem,
738770
.hrr_expected = false,
739771
.len_prefix_expected = false,

tls/s2n_kem.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ const struct s2n_kem_group s2n_x25519_mlkem_768 = {
134134
.send_kem_first = 1,
135135
};
136136

137+
const struct s2n_kem_group s2n_secp384r1_mlkem_1024 = {
138+
.name = "SecP384r1MLKEM1024",
139+
.iana_id = TLS_PQ_KEM_GROUP_ID_SECP384R1_MLKEM_1024,
140+
.curve = &s2n_ecc_curve_secp384r1,
141+
.kem = &s2n_mlkem_1024,
142+
.send_kem_first = 0,
143+
};
144+
137145
const struct s2n_kem_group s2n_secp256r1_kyber_512_r3 = {
138146
.name = "secp256r1_kyber-512-r3",
139147
.iana_id = TLS_PQ_KEM_GROUP_ID_SECP256R1_KYBER_512_R3,
@@ -185,6 +193,7 @@ const struct s2n_kem_group s2n_x25519_kyber_768_r3 = {
185193
const struct s2n_kem_group *ALL_SUPPORTED_KEM_GROUPS[] = {
186194
&s2n_x25519_mlkem_768,
187195
&s2n_secp256r1_mlkem_768,
196+
&s2n_secp384r1_mlkem_1024,
188197
&s2n_secp256r1_kyber_768_r3,
189198
&s2n_x25519_kyber_768_r3,
190199
&s2n_secp384r1_kyber_768_r3,

tls/s2n_kem.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,12 @@ extern const struct s2n_kem s2n_kyber_512_r3;
102102
extern const struct s2n_kem s2n_kyber_768_r3;
103103
extern const struct s2n_kem s2n_kyber_1024_r3;
104104

105-
#define S2N_KEM_GROUPS_COUNT 8
105+
#define S2N_KEM_GROUPS_COUNT 9
106106
extern const struct s2n_kem_group *ALL_SUPPORTED_KEM_GROUPS[S2N_KEM_GROUPS_COUNT];
107107

108108
/* NIST curve KEM Groups */
109109
extern const struct s2n_kem_group s2n_secp256r1_mlkem_768;
110+
extern const struct s2n_kem_group s2n_secp384r1_mlkem_1024;
110111
extern const struct s2n_kem_group s2n_secp256r1_kyber_512_r3;
111112
extern const struct s2n_kem_group s2n_secp256r1_kyber_768_r3;
112113
extern const struct s2n_kem_group s2n_secp384r1_kyber_768_r3;

tls/s2n_tls_parameters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
*/
7171
#define TLS_PQ_KEM_GROUP_ID_SECP256R1_MLKEM_768 0x11EB
7272
#define TLS_PQ_KEM_GROUP_ID_X25519_MLKEM_768 0x11EC
73+
#define TLS_PQ_KEM_GROUP_ID_SECP384R1_MLKEM_1024 0x11ED
7374
#define TLS_PQ_KEM_GROUP_ID_X25519_KYBER_512_R3 0x2F39
7475
#define TLS_PQ_KEM_GROUP_ID_SECP256R1_KYBER_512_R3 0x2F3A
7576
#define TLS_PQ_KEM_GROUP_ID_SECP384R1_KYBER_768_R3 0x2F3C

0 commit comments

Comments
 (0)