From 1f9f343fcff716e5c426e2b02dc674d8163a56b0 Mon Sep 17 00:00:00 2001 From: Alex Weibel Date: Thu, 9 Jan 2025 16:07:36 -0800 Subject: [PATCH] Migrate PQ Python code to TLS 1.3 (#4999) --- tests/integrationv2/common.py | 12 -- tests/integrationv2/test_pq_handshake.py | 161 ++++------------------- 2 files changed, 23 insertions(+), 150 deletions(-) diff --git a/tests/integrationv2/common.py b/tests/integrationv2/common.py index 35ba091cd79..aea215a8225 100644 --- a/tests/integrationv2/common.py +++ b/tests/integrationv2/common.py @@ -318,18 +318,6 @@ class Ciphers(object): KMS_TLS_1_0_2018_10 = Cipher( "KMS-TLS-1-0-2018-10", Protocols.TLS10, False, False, s2n=True) - KMS_PQ_TLS_1_0_2019_06 = Cipher( - "KMS-PQ-TLS-1-0-2019-06", Protocols.TLS10, False, False, s2n=True, pq=True) - KMS_PQ_TLS_1_0_2020_02 = Cipher( - "KMS-PQ-TLS-1-0-2020-02", Protocols.TLS10, False, False, s2n=True, pq=True) - KMS_PQ_TLS_1_0_2020_07 = Cipher( - "KMS-PQ-TLS-1-0-2020-07", Protocols.TLS10, False, False, s2n=True, pq=True) - PQ_SIKE_TEST_TLS_1_0_2019_11 = Cipher( - "PQ-SIKE-TEST-TLS-1-0-2019-11", Protocols.TLS10, False, False, s2n=True, pq=True) - PQ_SIKE_TEST_TLS_1_0_2020_02 = Cipher( - "PQ-SIKE-TEST-TLS-1-0-2020-02", Protocols.TLS10, False, False, s2n=True, pq=True) - PQ_TLS_1_0_2020_12 = Cipher( - "PQ-TLS-1-0-2020-12", Protocols.TLS10, False, False, s2n=True, pq=True) PQ_TLS_1_0_2023_01 = Cipher( "PQ-TLS-1-0-2023-01-24", Protocols.TLS10, False, False, s2n=True, pq=True) PQ_TLS_1_3_2023_06_01 = Cipher( diff --git a/tests/integrationv2/test_pq_handshake.py b/tests/integrationv2/test_pq_handshake.py index 5dce6804d5b..73f218e1cfc 100644 --- a/tests/integrationv2/test_pq_handshake.py +++ b/tests/integrationv2/test_pq_handshake.py @@ -14,13 +14,7 @@ CIPHERS = [ None, # `None` will default to the appropriate `test_all` cipher preference in the S2N client provider - Ciphers.KMS_PQ_TLS_1_0_2019_06, - Ciphers.KMS_PQ_TLS_1_0_2020_02, - Ciphers.KMS_PQ_TLS_1_0_2020_07, - Ciphers.PQ_SIKE_TEST_TLS_1_0_2019_11, - Ciphers.PQ_SIKE_TEST_TLS_1_0_2020_02, Ciphers.KMS_TLS_1_0_2018_10, - Ciphers.PQ_TLS_1_0_2020_12, Ciphers.PQ_TLS_1_3_2023_06_01, ] @@ -32,124 +26,35 @@ ] EXPECTED_RESULTS = { - # The tuple keys have the form (client_{cipher, kem_group}, server_{cipher, kem_group}) - (Ciphers.KMS_PQ_TLS_1_0_2019_06, Ciphers.KMS_PQ_TLS_1_0_2019_06): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.KMS_PQ_TLS_1_0_2019_06, Ciphers.KMS_PQ_TLS_1_0_2020_02): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.KMS_PQ_TLS_1_0_2019_06, Ciphers.KMS_PQ_TLS_1_0_2020_07): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - - (Ciphers.KMS_PQ_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2019_06): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.KMS_PQ_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2020_02): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.KMS_PQ_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2020_07): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - - (Ciphers.KMS_PQ_TLS_1_0_2020_07, Ciphers.KMS_PQ_TLS_1_0_2019_06): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.KMS_PQ_TLS_1_0_2020_07, Ciphers.KMS_PQ_TLS_1_0_2020_02): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.KMS_PQ_TLS_1_0_2020_07, Ciphers.KMS_PQ_TLS_1_0_2020_07): - {"cipher": "ECDHE-KYBER-RSA-AES256-GCM-SHA384", - "kem": "kyber512r3", "kem_group": None}, - - (Ciphers.PQ_SIKE_TEST_TLS_1_0_2019_11, Ciphers.KMS_PQ_TLS_1_0_2019_06): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.PQ_SIKE_TEST_TLS_1_0_2019_11, Ciphers.KMS_PQ_TLS_1_0_2020_02): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.PQ_SIKE_TEST_TLS_1_0_2019_11, Ciphers.KMS_PQ_TLS_1_0_2020_07): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - - (Ciphers.PQ_SIKE_TEST_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2019_06): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.PQ_SIKE_TEST_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2020_02): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.PQ_SIKE_TEST_TLS_1_0_2020_02, Ciphers.KMS_PQ_TLS_1_0_2020_07): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - - (Ciphers.KMS_PQ_TLS_1_0_2019_06, Ciphers.KMS_TLS_1_0_2018_10): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.KMS_PQ_TLS_1_0_2020_02, Ciphers.KMS_TLS_1_0_2018_10): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.KMS_PQ_TLS_1_0_2020_07, Ciphers.KMS_TLS_1_0_2018_10): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - - (Ciphers.KMS_TLS_1_0_2018_10, Ciphers.KMS_PQ_TLS_1_0_2019_06): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.KMS_TLS_1_0_2018_10, Ciphers.KMS_PQ_TLS_1_0_2020_02): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - (Ciphers.KMS_TLS_1_0_2018_10, Ciphers.KMS_PQ_TLS_1_0_2020_07): - {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", - "kem": None, "kem_group": None}, - - # The expected kem_group string for this case purposefully excludes a curve; - # depending on how s2n was compiled, the curve may be either x25519 or one - # of the NIST curves. - (Ciphers.PQ_TLS_1_0_2020_12, Ciphers.PQ_TLS_1_0_2020_12): - {"cipher": "TLS_AES_256_GCM_SHA384", - "kem": None, "kem_group": "_kyber-512-r3"}, - (Ciphers.PQ_TLS_1_0_2020_12, Ciphers.PQ_TLS_1_0_2023_01): - {"cipher": "TLS_AES_256_GCM_SHA384", - "kem": None, "kem_group": "_kyber-512-r3"}, + # The tuple keys have the form: + # (client_{cipher, kem_group}, server_{cipher, kem_group}): {"cipher": {expected_cipher}, "kem_group": {expected_kem_group}} (Ciphers.PQ_TLS_1_0_2023_01, Ciphers.PQ_TLS_1_0_2023_01): {"cipher": "TLS_AES_256_GCM_SHA384", - "kem": None, "kem_group": "_kyber-512-r3"}, - (Ciphers.PQ_TLS_1_0_2023_01, Ciphers.PQ_TLS_1_0_2020_12): - {"cipher": "TLS_AES_256_GCM_SHA384", - "kem": None, "kem_group": "_kyber-512-r3"}, - (Ciphers.PQ_TLS_1_0_2020_12, Ciphers.KMS_PQ_TLS_1_0_2020_07): - {"cipher": "ECDHE-KYBER-RSA-AES256-GCM-SHA384", - "kem": "kyber512r3", "kem_group": None}, - (Ciphers.KMS_PQ_TLS_1_0_2020_07, Ciphers.PQ_TLS_1_0_2020_12): - {"cipher": "ECDHE-KYBER-RSA-AES256-GCM-SHA384", - "kem": "kyber512r3", "kem_group": None}, - (Ciphers.PQ_TLS_1_0_2020_12, KemGroups.P256_KYBER512R3): - {"cipher": "AES256_GCM_SHA384", "kem": None, - "kem_group": "secp256r1_kyber-512-r3"}, - (KemGroups.P256_KYBER512R3, Ciphers.PQ_TLS_1_0_2020_12): - {"cipher": "AES256_GCM_SHA384", "kem": None, - "kem_group": "secp256r1_kyber-512-r3"}, - (KemGroups.P256_KYBER512R3, Ciphers.PQ_TLS_1_0_2023_01): - {"cipher": "AES256_GCM_SHA384", "kem": None, - "kem_group": "secp256r1_kyber-512-r3"}, - (KemGroups.P256_KYBER512R3, Ciphers.PQ_TLS_1_3_2023_06_01): - {"cipher": "AES256_GCM_SHA384", "kem": None, - "kem_group": "secp256r1_kyber-512-r3"}, + "kem_group": "_kyber-512-r3"}, (KemGroups.P384_KYBER768R3, Ciphers.PQ_TLS_1_3_2023_06_01): - {"cipher": "AES256_GCM_SHA384", "kem": None, - "kem_group": "secp384r1_kyber-768-r3"}, + {"cipher": "AES256_GCM_SHA384", + "kem_group": "secp384r1_kyber-768-r3"}, (KemGroups.P521_KYBER1024R3, Ciphers.PQ_TLS_1_3_2023_06_01): - {"cipher": "AES256_GCM_SHA384", "kem": None, - "kem_group": "secp521r1_kyber-1024-r3"}, + {"cipher": "AES256_GCM_SHA384", + "kem_group": "secp521r1_kyber-1024-r3"}, (Ciphers.PQ_TLS_1_3_2023_06_01, KemGroups.X25519Kyber768Draft00): {"cipher": "TLS_AES_256_GCM_SHA384", - "kem": None, "kem_group": "X25519Kyber768Draft00"}, (Ciphers.PQ_TLS_1_3_2023_06_01, KemGroups.SecP256r1Kyber768Draft00): {"cipher": "TLS_AES_256_GCM_SHA384", - "kem": None, "kem_group": "SecP256r1Kyber768Draft00"}, + (Ciphers.PQ_TLS_1_3_2023_06_01, Ciphers.PQ_TLS_1_3_2023_06_01): + {"cipher": "TLS_AES_256_GCM_SHA384", + "kem_group": "SecP256r1Kyber768Draft00"}, + (Ciphers.PQ_TLS_1_3_2023_06_01, Ciphers.KMS_TLS_1_0_2018_10): + {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", + "kem_group": None}, + (Ciphers.KMS_TLS_1_0_2018_10, Ciphers.PQ_TLS_1_3_2023_06_01): + {"cipher": "ECDHE-RSA-AES128-GCM-SHA256", + "kem_group": None}, + (Ciphers.KMS_TLS_1_0_2018_10, Ciphers.KMS_TLS_1_0_2018_10): + {"cipher": "ECDHE-RSA-AES256-GCM-SHA384", + "kem_group": None}, } """ @@ -185,16 +90,12 @@ def assert_s2n_negotiation_parameters(s2n_results, expected_result): if expected_result is not None: assert to_bytes( ("Cipher negotiated: " + expected_result['cipher'])) in s2n_results.stdout - if expected_result['kem']: - assert to_bytes( - ("KEM: " + expected_result['kem'])) in s2n_results.stdout - assert to_bytes(PQ_ENABLED_FLAG) in s2n_results.stdout if expected_result['kem_group']: # Purposefully leave off the "KEM Group: " prefix in order to perform partial matches # without specifying the curve. assert to_bytes(expected_result['kem_group']) in s2n_results.stdout assert to_bytes(PQ_ENABLED_FLAG) in s2n_results.stdout - if not expected_result['kem'] and not expected_result['kem_group']: + if not expected_result['kem_group']: assert to_bytes(PQ_ENABLED_FLAG) not in s2n_results.stdout assert to_bytes("Curve:") in s2n_results.stdout @@ -224,22 +125,6 @@ def test_nothing(): @pytest.mark.parametrize("other_provider", [S2N], ids=get_parameter_name) def test_s2nc_to_s2nd_pq_handshake(managed_process, protocol, certificate, client_cipher, server_cipher, provider, other_provider): - # Incorrect cipher is negotiated when both ciphers are PQ_TLS_1_0_2020_12 with - # openssl 1.0.2, boringssl, and libressl libcryptos - if all([ - client_cipher == Ciphers.PQ_TLS_1_0_2020_12, - server_cipher == Ciphers.PQ_TLS_1_0_2020_12, - any([ - libcrypto in get_flag(S2N_PROVIDER_VERSION) - for libcrypto in [ - "boringssl", - "libressl", - "openssl-1.0.2" - ] - ]) - ]): - pytest.skip() - port = next(available_ports) client_options = ProviderOptions( @@ -267,7 +152,7 @@ def test_s2nc_to_s2nd_pq_handshake(managed_process, protocol, certificate, clien # If PQ is not enabled in s2n, we expect classic handshakes to be negotiated. # Leave the expected cipher blank, as there are multiple possibilities - the # important thing is that kem and kem_group are NONE. - expected_result = {"cipher": "", "kem": None, "kem_group": None} + expected_result = {"cipher": "", "kem_group": None} # Client and server are both s2n; can make meaningful assertions about negotiation for both for results in client.get_results(): @@ -359,7 +244,7 @@ def test_s2nd_to_awslc_pq_handshake(managed_process, s2n_server_policy, awslc_cl @pytest.mark.uncollect_if(func=invalid_test_parameters) @pytest.mark.parametrize("protocol", [Protocols.TLS13], ids=get_parameter_name) -@pytest.mark.parametrize("cipher", [Ciphers.PQ_TLS_1_0_2020_12], ids=get_parameter_name) +@pytest.mark.parametrize("cipher", [Ciphers.PQ_TLS_1_3_2023_06_01], ids=get_parameter_name) @pytest.mark.parametrize("kem_group", KEM_GROUPS, ids=get_parameter_name) def test_s2nc_to_oqs_openssl_pq_handshake(managed_process, protocol, cipher, kem_group): # If PQ is not enabled in s2n, there is no reason to test against oqs_openssl @@ -401,7 +286,7 @@ def test_s2nc_to_oqs_openssl_pq_handshake(managed_process, protocol, cipher, kem @pytest.mark.uncollect_if(func=invalid_test_parameters) @pytest.mark.parametrize("protocol", [Protocols.TLS13], ids=get_parameter_name) -@pytest.mark.parametrize("cipher", [Ciphers.PQ_TLS_1_0_2020_12], ids=get_parameter_name) +@pytest.mark.parametrize("cipher", [Ciphers.PQ_TLS_1_3_2023_06_01], ids=get_parameter_name) @pytest.mark.parametrize("kem_group", KEM_GROUPS, ids=get_parameter_name) def test_oqs_openssl_to_s2nd_pq_handshake(managed_process, protocol, cipher, kem_group): # If PQ is not enabled in s2n, there is no reason to test against oqs_openssl