3030#include "pq-crypto/s2n_pq.h"
3131
3232#define HELLO_RETRY_MSG_NO 1
33+ #define MEM_FOR_EXTENSION 4096
3334
3435static int s2n_generate_pq_hybrid_key_share_for_test (struct s2n_stuffer * out , struct s2n_kem_group_params * kem_group_params );
3536static int s2n_copy_pq_share (struct s2n_stuffer * from , struct s2n_blob * to , const struct s2n_kem_group * kem_group );
@@ -172,7 +173,7 @@ int main() {
172173 const struct s2n_kem_group * test_kem_group = kem_pref -> tls13_kem_groups [0 ];
173174
174175 DEFER_CLEANUP (struct s2n_stuffer key_share_extension = {0 }, s2n_stuffer_free );
175- EXPECT_SUCCESS (s2n_stuffer_growable_alloc (& key_share_extension , 4096 ));
176+ EXPECT_SUCCESS (s2n_stuffer_growable_alloc (& key_share_extension , MEM_FOR_EXTENSION ));
176177 EXPECT_SUCCESS (s2n_client_key_share_extension .send (conn , & key_share_extension ));
177178
178179 /* First, assert that the client saved its private keys correctly in the connection state
@@ -264,10 +265,9 @@ int main() {
264265 EXPECT_SUCCESS (s2n_connection_get_kem_preferences (conn , & kem_pref ));
265266 EXPECT_NOT_NULL (kem_pref );
266267
267- /* This is for pre-HRR set up; force the client to generate it's default hybrid key share
268- * so that we can confirm that s2n_send_hrr_pq_hybrid_keyshare wipes it correctly. */
268+ /* This is for pre-HRR set up: force the client to generate its default hybrid key share. */
269269 DEFER_CLEANUP (struct s2n_stuffer key_share_extension = {0 }, s2n_stuffer_free );
270- EXPECT_SUCCESS (s2n_stuffer_growable_alloc (& key_share_extension , 4096 ));
270+ EXPECT_SUCCESS (s2n_stuffer_growable_alloc (& key_share_extension , MEM_FOR_EXTENSION ));
271271 EXPECT_SUCCESS (s2n_client_key_share_extension .send (conn , & key_share_extension ));
272272 EXPECT_SUCCESS (s2n_stuffer_wipe (& key_share_extension ));
273273 /* Quick sanity check */
@@ -296,19 +296,18 @@ int main() {
296296 EXPECT_NOT_NULL (kem_group_params -> ecc_params .evp_pkey );
297297
298298 /* Assert that the client didn't generate/save any key shares that it wasn't supposed to */
299- for (size_t kem_group_index = 0 ;
300- kem_group_index < kem_pref -> tls13_kem_group_count ; kem_group_index ++ ) {
301- if (kem_group_index == chosen_index ) {
299+ for (size_t kem_group_i = 0 ; kem_group_i < kem_pref -> tls13_kem_group_count ; kem_group_i ++ ) {
300+ if (kem_group_i == chosen_index || kem_group_i == 0 ) {
302301 continue ;
303302 }
304- EXPECT_NULL (conn -> secure .client_kem_group_params [kem_group_index ].kem_group );
305- EXPECT_NULL (conn -> secure .client_kem_group_params [kem_group_index ].kem_params .kem );
306- EXPECT_NULL (conn -> secure .client_kem_group_params [kem_group_index ].kem_params .private_key .data );
307- EXPECT_EQUAL (conn -> secure .client_kem_group_params [kem_group_index ].kem_params .private_key .size ,0 );
308- EXPECT_NULL (conn -> secure .client_kem_group_params [kem_group_index ].ecc_params .negotiated_curve );
309- EXPECT_NULL (conn -> secure .client_kem_group_params [kem_group_index ].ecc_params .evp_pkey );
303+ EXPECT_NULL (conn -> secure .client_kem_group_params [kem_group_i ].kem_group );
304+ EXPECT_NULL (conn -> secure .client_kem_group_params [kem_group_i ].kem_params .kem );
305+ EXPECT_NULL (conn -> secure .client_kem_group_params [kem_group_i ].kem_params .private_key .data );
306+ EXPECT_EQUAL (conn -> secure .client_kem_group_params [kem_group_i ].kem_params .private_key .size ,0 );
307+ EXPECT_NULL (conn -> secure .client_kem_group_params [kem_group_i ].ecc_params .negotiated_curve );
308+ EXPECT_NULL (conn -> secure .client_kem_group_params [kem_group_i ].ecc_params .evp_pkey );
310309 }
311- for (size_t ecc_index = 0 ; ecc_index < S2N_ECC_EVP_SUPPORTED_CURVES_COUNT ; ecc_index ++ ) {
310+ for (size_t ecc_index = 1 ; ecc_index < S2N_ECC_EVP_SUPPORTED_CURVES_COUNT ; ecc_index ++ ) {
312311 EXPECT_NULL (conn -> secure .client_ecc_evp_params [ecc_index ].negotiated_curve );
313312 EXPECT_NULL (conn -> secure .client_ecc_evp_params [ecc_index ].evp_pkey );
314313 }
@@ -349,6 +348,89 @@ int main() {
349348
350349 EXPECT_SUCCESS (s2n_connection_free (conn ));
351350 }
351+
352+ /* Test sending in response to HRR for early data */
353+ {
354+ struct s2n_connection * conn = s2n_connection_new (S2N_CLIENT );
355+ conn -> security_policy_override = & test_security_policy ;
356+ EXPECT_NOT_NULL (conn );
357+
358+ const struct s2n_ecc_preferences * ecc_preferences = NULL ;
359+ EXPECT_SUCCESS (s2n_connection_get_ecc_preferences (conn , & ecc_preferences ));
360+ EXPECT_NOT_NULL (ecc_preferences );
361+
362+ const struct s2n_kem_preferences * kem_pref = NULL ;
363+ EXPECT_SUCCESS (s2n_connection_get_kem_preferences (conn , & kem_pref ));
364+ EXPECT_NOT_NULL (kem_pref );
365+
366+ struct s2n_stuffer first_extension = { 0 }, second_extension = { 0 };
367+ EXPECT_SUCCESS (s2n_stuffer_growable_alloc (& first_extension , MEM_FOR_EXTENSION ));
368+ EXPECT_SUCCESS (s2n_stuffer_growable_alloc (& second_extension , MEM_FOR_EXTENSION ));
369+
370+ EXPECT_SUCCESS (s2n_client_key_share_extension .send (conn , & first_extension ));
371+
372+ conn -> secure .server_kem_group_params .kem_group = conn -> secure .client_kem_group_params [0 ].kem_group ;
373+ conn -> secure .server_kem_group_params .ecc_params .negotiated_curve =
374+ conn -> secure .client_kem_group_params [0 ].ecc_params .negotiated_curve ;
375+
376+ /* Setup the client to have received a HelloRetryRequest */
377+ EXPECT_MEMCPY_SUCCESS (conn -> secure .server_random , hello_retry_req_random , S2N_TLS_RANDOM_DATA_LEN );
378+ EXPECT_SUCCESS (s2n_connection_set_all_protocol_versions (conn , S2N_TLS13 ));
379+ EXPECT_SUCCESS (s2n_set_connection_hello_retry_flags (conn ));
380+ conn -> early_data_state = S2N_EARLY_DATA_REJECTED ;
381+
382+ EXPECT_SUCCESS (s2n_client_key_share_extension .send (conn , & second_extension ));
383+
384+ /* Read the total length of both extensions.
385+ * The first keys extension contains multiple shares, so should be longer than the second. */
386+ uint16_t first_sent_key_shares_size = 0 , second_sent_key_shares_size = 0 ;
387+ EXPECT_SUCCESS (s2n_stuffer_read_uint16 (& first_extension , & first_sent_key_shares_size ));
388+ EXPECT_SUCCESS (s2n_stuffer_read_uint16 (& second_extension , & second_sent_key_shares_size ));
389+ EXPECT_EQUAL (first_sent_key_shares_size , s2n_stuffer_data_available (& first_extension ));
390+ EXPECT_EQUAL (second_sent_key_shares_size , s2n_stuffer_data_available (& second_extension ));
391+ EXPECT_TRUE (second_sent_key_shares_size < first_sent_key_shares_size );
392+
393+ /* Read the iana of the first share.
394+ * Both shares should contain the same iana, and it should be equal to the server's chosen kem group. */
395+ uint16_t first_sent_hybrid_iana_id = 0 , second_sent_hybrid_iana_id = 0 ;
396+ EXPECT_SUCCESS (s2n_stuffer_read_uint16 (& first_extension , & first_sent_hybrid_iana_id ));
397+ EXPECT_SUCCESS (s2n_stuffer_read_uint16 (& second_extension , & second_sent_hybrid_iana_id ));
398+ EXPECT_EQUAL (first_sent_hybrid_iana_id , conn -> secure .server_kem_group_params .kem_group -> iana_id );
399+ EXPECT_EQUAL (first_sent_hybrid_iana_id , second_sent_hybrid_iana_id );
400+
401+ /* Read the total share size, including both ecc and kem.
402+ * The first extension contains multiple shares, so should contain more data than the share size.
403+ * The second extension only contains one share, so should contain only the share size. */
404+ uint16_t first_total_hybrid_share_size = 0 , second_total_hybrid_share_size = 0 ;
405+ EXPECT_SUCCESS (s2n_stuffer_read_uint16 (& first_extension , & first_total_hybrid_share_size ));
406+ EXPECT_SUCCESS (s2n_stuffer_read_uint16 (& second_extension , & second_total_hybrid_share_size ));
407+ EXPECT_TRUE (first_total_hybrid_share_size < s2n_stuffer_data_available (& first_extension ));
408+ EXPECT_EQUAL (second_total_hybrid_share_size , s2n_stuffer_data_available (& second_extension ));
409+
410+ /* Read the ecc share size.
411+ * The ecc share should be identical for both, so the size should be the same. */
412+ uint16_t first_ecc_share_size = 0 , second_ecc_share_size = 0 ;
413+ EXPECT_SUCCESS (s2n_stuffer_read_uint16 (& first_extension , & first_ecc_share_size ));
414+ EXPECT_SUCCESS (s2n_stuffer_read_uint16 (& second_extension , & second_ecc_share_size ));
415+ EXPECT_EQUAL (first_ecc_share_size , second_ecc_share_size );
416+
417+ /* Read the ecc share.
418+ * The ecc share should be identical for both. */
419+ uint8_t * first_ecc_share_data = NULL , * second_ecc_share_data = NULL ;
420+ EXPECT_NOT_NULL (first_ecc_share_data = s2n_stuffer_raw_read (& first_extension , first_ecc_share_size ));
421+ EXPECT_NOT_NULL (second_ecc_share_data = s2n_stuffer_raw_read (& second_extension , second_ecc_share_size ));
422+ EXPECT_BYTEARRAY_EQUAL (first_ecc_share_data , second_ecc_share_data , first_ecc_share_size );
423+
424+ /* The pq share should take up the rest of the key share.
425+ * For now the pq share is different between extensions, so we can't assert anything else. */
426+ uint16_t second_pq_share_size = 0 ;
427+ EXPECT_SUCCESS (s2n_stuffer_read_uint16 (& second_extension , & second_pq_share_size ));
428+ EXPECT_EQUAL (second_pq_share_size , s2n_stuffer_data_available (& second_extension ));
429+
430+ EXPECT_SUCCESS (s2n_stuffer_free (& first_extension ));
431+ EXPECT_SUCCESS (s2n_stuffer_free (& second_extension ));
432+ EXPECT_SUCCESS (s2n_connection_free (conn ));
433+ }
352434 }
353435
354436 /* Test failure when server chooses a KEM group that is not in the client's preferences */
@@ -364,7 +446,7 @@ int main() {
364446 conn -> secure .server_kem_group_params .kem_group = & s2n_secp256r1_bike1_l1_r2 ;
365447
366448 DEFER_CLEANUP (struct s2n_stuffer key_share_extension = {0 }, s2n_stuffer_free );
367- EXPECT_SUCCESS (s2n_stuffer_growable_alloc (& key_share_extension , 4096 ));
449+ EXPECT_SUCCESS (s2n_stuffer_growable_alloc (& key_share_extension , MEM_FOR_EXTENSION ));
368450 EXPECT_FAILURE_WITH_ERRNO (s2n_client_key_share_extension .send (conn , & key_share_extension ), S2N_ERR_INVALID_HELLO_RETRY );
369451
370452 EXPECT_SUCCESS (s2n_connection_free (conn ));
0 commit comments