|
25 | 25 | #include "tls/s2n_tls13.h" |
26 | 26 | #include "tls/s2n_tls13_handshake.h" |
27 | 27 | #include "tls/s2n_connection.h" |
| 28 | +#include "crypto/s2n_fips.h" |
28 | 29 |
|
29 | 30 | /* This include is required to access static function s2n_server_hello_parse */ |
30 | 31 | #include "tls/s2n_server_hello.c" |
@@ -106,7 +107,7 @@ int main(int argc, char **argv) |
106 | 107 | EXPECT_SUCCESS(s2n_connection_free(conn)); |
107 | 108 | } |
108 | 109 |
|
109 | | - /* Test success case for s2n_server_hello_retry_recv */ |
| 110 | + /* Test ECC success case for s2n_server_hello_retry_recv */ |
110 | 111 | { |
111 | 112 | struct s2n_config *server_config; |
112 | 113 | struct s2n_config *client_config; |
@@ -168,8 +169,164 @@ int main(int argc, char **argv) |
168 | 169 | EXPECT_SUCCESS(s2n_connection_free(server_conn)); |
169 | 170 | EXPECT_SUCCESS(s2n_connection_free(client_conn)); |
170 | 171 | EXPECT_SUCCESS(s2n_cert_chain_and_key_free(tls13_chain_and_key)); |
171 | | - |
172 | 172 | } |
| 173 | +#if !defined(S2N_NO_PQ) |
| 174 | + { |
| 175 | + const struct s2n_kem_group *test_kem_groups[] = { |
| 176 | + &s2n_secp256r1_sike_p434_r2, |
| 177 | + &s2n_secp256r1_bike1_l1_r2, |
| 178 | + }; |
| 179 | + |
| 180 | + const struct s2n_kem_preferences test_kem_prefs = { |
| 181 | + .kem_count = 0, |
| 182 | + .kems = NULL, |
| 183 | + .tls13_kem_group_count = s2n_array_len(test_kem_groups), |
| 184 | + .tls13_kem_groups = test_kem_groups, |
| 185 | + }; |
| 186 | + |
| 187 | + const struct s2n_security_policy test_security_policy = { |
| 188 | + .minimum_protocol_version = S2N_SSLv3, |
| 189 | + .cipher_preferences = &cipher_preferences_test_all_tls13, |
| 190 | + .kem_preferences = &test_kem_prefs, |
| 191 | + .signature_preferences = &s2n_signature_preferences_20200207, |
| 192 | + .ecc_preferences = &s2n_ecc_preferences_20200310, |
| 193 | + }; |
| 194 | + |
| 195 | + if (s2n_is_in_fips_mode()) { |
| 196 | + struct s2n_connection *conn; |
| 197 | + EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); |
| 198 | + conn->actual_protocol_version = S2N_TLS13; |
| 199 | + conn->security_policy_override = &test_security_policy; |
| 200 | + |
| 201 | + const struct s2n_kem_preferences *kem_pref = NULL; |
| 202 | + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); |
| 203 | + EXPECT_NOT_NULL(kem_pref); |
| 204 | + |
| 205 | + conn->secure.server_kem_group_params.kem_group = kem_pref->tls13_kem_groups[0]; |
| 206 | + EXPECT_NULL(conn->secure.server_ecc_evp_params.negotiated_curve); |
| 207 | + |
| 208 | + EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_PQ_KEMS_DISALLOWED_IN_FIPS); |
| 209 | + |
| 210 | + EXPECT_SUCCESS(s2n_connection_free(conn)); |
| 211 | + } else { |
| 212 | + /* s2n_server_hello_retry_recv must fail when a keyshare for a matching PQ KEM was already present */ |
| 213 | + { |
| 214 | + struct s2n_connection *conn; |
| 215 | + EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); |
| 216 | + conn->actual_protocol_version = S2N_TLS13; |
| 217 | + conn->security_policy_override = &test_security_policy; |
| 218 | + |
| 219 | + const struct s2n_kem_preferences *kem_pref = NULL; |
| 220 | + GUARD(s2n_connection_get_kem_preferences(conn, &kem_pref)); |
| 221 | + EXPECT_NOT_NULL(kem_pref); |
| 222 | + |
| 223 | + conn->secure.server_kem_group_params.kem_group = kem_pref->tls13_kem_groups[0]; |
| 224 | + EXPECT_NULL(conn->secure.server_ecc_evp_params.negotiated_curve); |
| 225 | + |
| 226 | + struct s2n_kem_group_params *client_params = &conn->secure.client_kem_group_params[0]; |
| 227 | + client_params->kem_group = kem_pref->tls13_kem_groups[0]; |
| 228 | + client_params->kem_params.kem = kem_pref->tls13_kem_groups[0]->kem; |
| 229 | + client_params->ecc_params.negotiated_curve = kem_pref->tls13_kem_groups[0]->curve; |
| 230 | + |
| 231 | + EXPECT_NULL(client_params->ecc_params.evp_pkey); |
| 232 | + EXPECT_NULL(client_params->kem_params.private_key.data); |
| 233 | + |
| 234 | + kem_public_key_size public_key_size = kem_pref->tls13_kem_groups[0]->kem->public_key_length; |
| 235 | + EXPECT_SUCCESS(s2n_alloc(&client_params->kem_params.public_key, public_key_size)); |
| 236 | + |
| 237 | + EXPECT_SUCCESS(s2n_kem_generate_keypair(&client_params->kem_params)); |
| 238 | + EXPECT_NOT_NULL(client_params->kem_params.private_key.data); |
| 239 | + EXPECT_SUCCESS(s2n_ecc_evp_generate_ephemeral_key(&client_params->ecc_params)); |
| 240 | + EXPECT_NOT_NULL(client_params->ecc_params.evp_pkey); |
| 241 | + |
| 242 | + EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_INVALID_HELLO_RETRY); |
| 243 | + |
| 244 | + EXPECT_SUCCESS(s2n_free(&client_params->kem_params.public_key)); |
| 245 | + EXPECT_SUCCESS(s2n_connection_free(conn)); |
| 246 | + } |
| 247 | + /* s2n_server_hello_retry_recv must fail if the server chose a PQ KEM |
| 248 | + * that wasn't in the client's supported_groups */ |
| 249 | + { |
| 250 | + struct s2n_connection *conn; |
| 251 | + EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); |
| 252 | + conn->actual_protocol_version = S2N_TLS13; |
| 253 | + conn->security_policy_override = &test_security_policy; |
| 254 | + |
| 255 | + /* test_security_policy does not include kyber */ |
| 256 | + conn->secure.server_kem_group_params.kem_group = &s2n_secp256r1_kyber_512_r2; |
| 257 | + EXPECT_NULL(conn->secure.server_ecc_evp_params.negotiated_curve); |
| 258 | + |
| 259 | + EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_INVALID_HELLO_RETRY); |
| 260 | + |
| 261 | + EXPECT_SUCCESS(s2n_connection_free(conn)); |
| 262 | + } |
| 263 | + /* Test failure if exactly one of {named_curve, kem_group} isn't non-null */ |
| 264 | + { |
| 265 | + struct s2n_connection *conn; |
| 266 | + EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); |
| 267 | + conn->actual_protocol_version = S2N_TLS13; |
| 268 | + conn->security_policy_override = &test_security_policy; |
| 269 | + |
| 270 | + conn->secure.server_kem_group_params.kem_group = &s2n_secp256r1_sike_p434_r2; |
| 271 | + conn->secure.server_ecc_evp_params.negotiated_curve = &s2n_ecc_curve_secp256r1; |
| 272 | + |
| 273 | + EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_INVALID_HELLO_RETRY); |
| 274 | + |
| 275 | + conn->secure.server_kem_group_params.kem_group = NULL; |
| 276 | + conn->secure.server_ecc_evp_params.negotiated_curve = NULL; |
| 277 | + |
| 278 | + EXPECT_FAILURE_WITH_ERRNO(s2n_server_hello_retry_recv(conn), S2N_ERR_INVALID_HELLO_RETRY); |
| 279 | + |
| 280 | + EXPECT_SUCCESS(s2n_connection_free(conn)); |
| 281 | + } |
| 282 | + /* Test PQ KEM success case for s2n_server_hello_retry_recv. */ |
| 283 | + { |
| 284 | + struct s2n_config *config; |
| 285 | + struct s2n_connection *conn; |
| 286 | + |
| 287 | + struct s2n_cert_chain_and_key *tls13_chain_and_key; |
| 288 | + char tls13_cert_chain[S2N_MAX_TEST_PEM_SIZE] = {0}; |
| 289 | + char tls13_private_key[S2N_MAX_TEST_PEM_SIZE] = {0}; |
| 290 | + |
| 291 | + EXPECT_NOT_NULL(config = s2n_config_new()); |
| 292 | + EXPECT_NOT_NULL(conn = s2n_connection_new(S2N_CLIENT)); |
| 293 | + conn->security_policy_override = &test_security_policy; |
| 294 | + |
| 295 | + EXPECT_NOT_NULL(tls13_chain_and_key = s2n_cert_chain_and_key_new()); |
| 296 | + EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_CERT_CHAIN, tls13_cert_chain, S2N_MAX_TEST_PEM_SIZE)); |
| 297 | + EXPECT_SUCCESS(s2n_read_test_pem(S2N_ECDSA_P384_PKCS1_KEY, tls13_private_key, S2N_MAX_TEST_PEM_SIZE)); |
| 298 | + EXPECT_SUCCESS(s2n_cert_chain_and_key_load_pem(tls13_chain_and_key, tls13_cert_chain, tls13_private_key)); |
| 299 | + EXPECT_SUCCESS(s2n_config_add_cert_chain_and_key_to_store(config, tls13_chain_and_key)); |
| 300 | + |
| 301 | + /* Client sends ClientHello containing key share for p256+SIKE |
| 302 | + * (but indicates support for p256+BIKE in supported_groups) */ |
| 303 | + EXPECT_SUCCESS(s2n_client_hello_send(conn)); |
| 304 | + |
| 305 | + EXPECT_SUCCESS(s2n_stuffer_wipe(&conn->handshake.io)); |
| 306 | + |
| 307 | + /* Server responds with HRR indicating p256+BIKE as choice for negotiation; |
| 308 | + * the last 6 bytes (0033 0002 2F23) are the key share extension with p256+BIKE */ |
| 309 | + DEFER_CLEANUP(struct s2n_stuffer hrr = {0}, s2n_stuffer_free); |
| 310 | + EXPECT_SUCCESS(s2n_stuffer_alloc_ro_from_hex_string(&hrr, |
| 311 | + "0303CF21AD74E59A6111BE1D8C021E65B891C2A211167ABB8C5E079E09E2C8A8339C00130200000C002B00020304003300022F23")); |
| 312 | + |
| 313 | + EXPECT_SUCCESS(s2n_stuffer_copy(&hrr, &conn->handshake.io, s2n_stuffer_data_available(&hrr))); |
| 314 | + conn->handshake.message_number = HELLO_RETRY_MSG_NO; |
| 315 | + /* Read the message off the wire */ |
| 316 | + EXPECT_SUCCESS(s2n_server_hello_parse(conn)); |
| 317 | + conn->actual_protocol_version_established = 1; |
| 318 | + |
| 319 | + EXPECT_SUCCESS(s2n_conn_set_handshake_type(conn)); |
| 320 | + /* Client receives the HelloRetryRequest message */ |
| 321 | + EXPECT_SUCCESS(s2n_server_hello_retry_recv(conn)); |
| 322 | + |
| 323 | + EXPECT_SUCCESS(s2n_config_free(config)); |
| 324 | + EXPECT_SUCCESS(s2n_connection_free(conn)); |
| 325 | + EXPECT_SUCCESS(s2n_cert_chain_and_key_free(tls13_chain_and_key)); |
| 326 | + } |
| 327 | + } |
| 328 | + } |
| 329 | +#endif |
173 | 330 | } |
174 | 331 |
|
175 | 332 | /* Verify that the hash transcript recreation function is called correctly, |
|
0 commit comments