diff --git a/CMakeLists.txt b/CMakeLists.txt index ab90ef7cad3..9f9b3977106 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ set(INSTALL_LIB_DIR lib CACHE PATH "Installaction directory for libraries") set(INSTALL_INCLUDE_DIR include CACHE PATH "installaction directory for header files") set(INSTALL_CMAKE_DIR lib/cmake CACHE PATH "Installation directory for cmake files") +option(S2N_NO_PQ "Disables all Post Quantum Crypto code. You likely want this for older compilers or uncommon platforms.") option(S2N_NO_PQ_ASM "Turns off the ASM for PQ Crypto even if it's available for the toolchain. You likely want this on older compilers." OFF) ##header files @@ -23,13 +24,6 @@ file(GLOB ERROR_HEADERS "error/*.h" ) -file(GLOB PQ_HEADERS - "pq-crypto/*.h" - "pq-crypto/bike_r1/*.h" - "pq-crypto/bike_r2/*.h" - "pq-crypto/sike_r1/*.h" -) - file(GLOB STUFFER_HEADERS "stuffer/*.h" ) @@ -51,18 +45,32 @@ file(GLOB ERROR_SRC "error/*.c" ) -# The SIKE code #includes .c files directly, including all sike_r*/*.c breaks the build due to duplicates -file(GLOB PQ_SRC - "pq-crypto/*.c" - "pq-crypto/bike_r1/*.c" - "pq-crypto/bike_r2/*.c" - "pq-crypto/sike_r1/fp_generic_r1.c" - "pq-crypto/sike_r1/P503_r1.c" - "pq-crypto/sike_r1/sike_r1_kem.c" - "pq-crypto/sike_r1/fips202_r1.c" - "pq-crypto/sike_r2/fips202.c" - "pq-crypto/sike_r2/P434.c" - ) +if(S2N_NO_PQ) + message(STATUS "S2N_NO_PQ flag was detected - Disabling Post Quantum Crypto") + # If all Post Quantum Code is disabled, also disable PQ assembly optimized code + set(S2N_NO_PQ_ASM ON) +else() + file(GLOB PQ_HEADERS + "pq-crypto/*.h" + "pq-crypto/bike_r1/*.h" + "pq-crypto/bike_r2/*.h" + "pq-crypto/sike_r1/*.h" + "pq-crypto/sike_r2/*.h" + ) + + # The SIKE code #includes .c files directly, including all sike_r*/*.c breaks the build due to duplicates + file(GLOB PQ_SRC + "pq-crypto/*.c" + "pq-crypto/bike_r1/*.c" + "pq-crypto/bike_r2/*.c" + "pq-crypto/sike_r1/fp_generic_r1.c" + "pq-crypto/sike_r1/P503_r1.c" + "pq-crypto/sike_r1/sike_r1_kem.c" + "pq-crypto/sike_r1/fips202_r1.c" + "pq-crypto/sike_r2/fips202.c" + "pq-crypto/sike_r2/P434.c" + ) +endif() file(GLOB STUFFER_SRC "stuffer/*.c" @@ -160,6 +168,10 @@ if(S2N_NO_PQ_ASM) target_compile_options(${PROJECT_NAME} PUBLIC -DS2N_NO_PQ_ASM) endif() +if(S2N_NO_PQ) + target_compile_options(${PROJECT_NAME} PUBLIC -DS2N_NO_PQ) +endif() + target_compile_options(${PROJECT_NAME} PUBLIC -fPIC) target_compile_definitions(${PROJECT_NAME} PRIVATE -D_POSIX_C_SOURCE=200809L) diff --git a/tests/unit/s2n_bike_r1_kat_test.c b/tests/unit/s2n_bike_r1_kat_test.c index 9ce2d975e6d..7aaed20f508 100644 --- a/tests/unit/s2n_bike_r1_kat_test.c +++ b/tests/unit/s2n_bike_r1_kat_test.c @@ -26,11 +26,17 @@ int main(int argc, char **argv, char **envp) { BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); } EXPECT_SUCCESS(s2n_test_kem_with_kat(&s2n_bike1_l1_r1, RSP_FILE)); + +#endif + END_TEST(); } diff --git a/tests/unit/s2n_bike_r1_kem_test.c b/tests/unit/s2n_bike_r1_kem_test.c index bc5a4aea7a8..ff9688c2b28 100644 --- a/tests/unit/s2n_bike_r1_kem_test.c +++ b/tests/unit/s2n_bike_r1_kem_test.c @@ -19,13 +19,16 @@ int main(int argc, char **argv) { + BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + unsigned char publicKey[BIKE1_L1_R1_PUBLIC_KEY_BYTES]; unsigned char privateKey[BIKE1_L1_R1_SECRET_KEY_BYTES]; unsigned char clientSharedSecretPlaintext[BIKE1_L1_R1_SHARED_SECRET_BYTES]; unsigned char serverSharedSecretPlaintext[BIKE1_L1_R1_SHARED_SECRET_BYTES]; unsigned char encryptedSecret[BIKE1_L1_R1_CIPHERTEXT_BYTES]; - BEGIN_TEST(); if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); @@ -36,6 +39,8 @@ int main(int argc, char **argv) EXPECT_SUCCESS(BIKE1_L1_R1_crypto_kem_dec(serverSharedSecretPlaintext, encryptedSecret, privateKey)); EXPECT_BYTEARRAY_EQUAL(serverSharedSecretPlaintext, clientSharedSecretPlaintext, BIKE1_L1_R1_SHARED_SECRET_BYTES); +#endif + END_TEST(); } diff --git a/tests/unit/s2n_bike_r2_kat_test.c b/tests/unit/s2n_bike_r2_kat_test.c index bce0dade77b..a97249a49a4 100644 --- a/tests/unit/s2n_bike_r2_kat_test.c +++ b/tests/unit/s2n_bike_r2_kat_test.c @@ -26,11 +26,17 @@ int main(int argc, char **argv, char **envp) { BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); } EXPECT_SUCCESS(s2n_test_kem_with_kat(&s2n_bike1_l1_r2, RSP_FILE)); + +#endif + END_TEST(); } diff --git a/tests/unit/s2n_bike_r2_kem_test.c b/tests/unit/s2n_bike_r2_kem_test.c index 844fa8ca3e7..5a640d5fd0f 100644 --- a/tests/unit/s2n_bike_r2_kem_test.c +++ b/tests/unit/s2n_bike_r2_kem_test.c @@ -19,13 +19,16 @@ int main(int argc, char **argv) { + BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + unsigned char publicKey[BIKE1_L1_R2_PUBLIC_KEY_BYTES]; unsigned char privateKey[BIKE1_L1_R2_SECRET_KEY_BYTES]; unsigned char clientSharedSecretPlaintext[BIKE1_L1_R2_SHARED_SECRET_BYTES]; unsigned char serverSharedSecretPlaintext[BIKE1_L1_R2_SHARED_SECRET_BYTES]; unsigned char encryptedSecret[BIKE1_L1_R2_CIPHERTEXT_BYTES]; - BEGIN_TEST(); if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); @@ -36,6 +39,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(BIKE1_L1_R2_crypto_kem_dec(serverSharedSecretPlaintext, encryptedSecret, privateKey)); EXPECT_BYTEARRAY_EQUAL(serverSharedSecretPlaintext, clientSharedSecretPlaintext, BIKE1_L1_R2_SHARED_SECRET_BYTES); +#endif END_TEST(); } diff --git a/tests/unit/s2n_cipher_preference_test.c b/tests/unit/s2n_cipher_preference_test.c index 6b9eea54958..080fac5abeb 100644 --- a/tests/unit/s2n_cipher_preference_test.c +++ b/tests/unit/s2n_cipher_preference_test.c @@ -43,8 +43,12 @@ int main(int argc, char **argv) EXPECT_TRUE(s2n_ecc_extension_required(preferences)); EXPECT_TRUE(s2n_pq_kem_extension_required(preferences)); EXPECT_EQUAL(4, preferences->kem_count); +#if !defined(S2N_NO_PQ) EXPECT_NOT_NULL(preferences->kems); EXPECT_EQUAL(preferences->kems, pq_kems_r2r1); +#else + EXPECT_NULL(preferences->kems); +#endif preferences = NULL; EXPECT_SUCCESS(s2n_find_cipher_pref_from_version("KMS-TLS-1-0-2018-10", &preferences)); @@ -53,6 +57,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(0, preferences->kem_count); EXPECT_NULL(preferences->kems); +#if !defined(S2N_NO_PQ) preferences = NULL; EXPECT_SUCCESS(s2n_find_cipher_pref_from_version("KMS-PQ-TLS-1-0-2019-06", &preferences)); EXPECT_TRUE(s2n_ecc_extension_required(preferences)); @@ -84,6 +89,20 @@ int main(int argc, char **argv) EXPECT_EQUAL(4, preferences->kem_count); EXPECT_NOT_NULL(preferences->kems); EXPECT_EQUAL(preferences->kems, pq_kems_r2r1); +#else + preferences = NULL; + EXPECT_FAILURE(s2n_find_cipher_pref_from_version("KMS-PQ-TLS-1-0-2019-06", &preferences)); + EXPECT_EQUAL(preferences, NULL); + + EXPECT_FAILURE(s2n_find_cipher_pref_from_version("PQ-SIKE-TEST-TLS-1-0-2019-11", &preferences)); + EXPECT_EQUAL(preferences, NULL); + + EXPECT_FAILURE(s2n_find_cipher_pref_from_version("PQ-SIKE-TEST-TLS-1-0-2020-02", &preferences)); + EXPECT_EQUAL(preferences, NULL); + + EXPECT_FAILURE(s2n_find_cipher_pref_from_version("KMS-PQ-TLS-1-0-2020-02", &preferences)); + EXPECT_EQUAL(preferences, NULL); +#endif preferences = NULL; EXPECT_SUCCESS(s2n_find_cipher_pref_from_version("20141001", &preferences)); diff --git a/tests/unit/s2n_hybrid_ecdhe_bike_r1_test.c b/tests/unit/s2n_hybrid_ecdhe_bike_r1_test.c index 3282b4dcb64..2c8cb6b2c24 100644 --- a/tests/unit/s2n_hybrid_ecdhe_bike_r1_test.c +++ b/tests/unit/s2n_hybrid_ecdhe_bike_r1_test.c @@ -27,6 +27,9 @@ int main(int argc, char **argv) { BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); @@ -34,5 +37,8 @@ int main(int argc, char **argv) { EXPECT_SUCCESS(s2n_test_hybrid_ecdhe_kem_with_kat(&s2n_bike1_l1_r1, &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384, "KMS-PQ-TLS-1-0-2019-06", RSP_FILE_NAME, SERVER_KEY_MESSAGE_LENGTH, CLIENT_KEY_MESSAGE_LENGTH)); + +#endif + END_TEST(); } diff --git a/tests/unit/s2n_hybrid_ecdhe_bike_r2_test.c b/tests/unit/s2n_hybrid_ecdhe_bike_r2_test.c index 50c27f299cf..9200cd23653 100644 --- a/tests/unit/s2n_hybrid_ecdhe_bike_r2_test.c +++ b/tests/unit/s2n_hybrid_ecdhe_bike_r2_test.c @@ -26,6 +26,9 @@ int main(int argc, char **argv) { BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); @@ -33,5 +36,8 @@ int main(int argc, char **argv) { EXPECT_SUCCESS(s2n_test_hybrid_ecdhe_kem_with_kat(&s2n_bike1_l1_r2, &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384, "KMS-PQ-TLS-1-0-2020-02", RSP_FILE_NAME, SERVER_KEY_MESSAGE_LENGTH, CLIENT_KEY_MESSAGE_LENGTH)); + +#endif + END_TEST(); } diff --git a/tests/unit/s2n_hybrid_ecdhe_sike_r1_test.c b/tests/unit/s2n_hybrid_ecdhe_sike_r1_test.c index 4d65eb69fce..362000e91c6 100644 --- a/tests/unit/s2n_hybrid_ecdhe_sike_r1_test.c +++ b/tests/unit/s2n_hybrid_ecdhe_sike_r1_test.c @@ -27,6 +27,9 @@ int main(int argc, char **argv) { BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); @@ -34,5 +37,8 @@ int main(int argc, char **argv) { EXPECT_SUCCESS(s2n_test_hybrid_ecdhe_kem_with_kat(&s2n_sike_p503_r1, &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384, "KMS-PQ-TLS-1-0-2019-06", RSP_FILE_NAME, SERVER_KEY_MESSAGE_LENGTH, CLIENT_KEY_MESSAGE_LENGTH)); + +#endif + END_TEST(); } diff --git a/tests/unit/s2n_hybrid_ecdhe_sike_r2_test.c b/tests/unit/s2n_hybrid_ecdhe_sike_r2_test.c index 9a2fb21e6e7..d8cfa5327eb 100644 --- a/tests/unit/s2n_hybrid_ecdhe_sike_r2_test.c +++ b/tests/unit/s2n_hybrid_ecdhe_sike_r2_test.c @@ -26,11 +26,17 @@ int main(int argc, char **argv) { BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); } EXPECT_SUCCESS(s2n_test_hybrid_ecdhe_kem_with_kat(&s2n_sike_p434_r2, &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384, "KMS-PQ-TLS-1-0-2020-02", RSP_FILE_NAME, SERVER_KEY_MESSAGE_LENGTH, CLIENT_KEY_MESSAGE_LENGTH)); + +#endif + END_TEST(); } diff --git a/tests/unit/s2n_kem_test.c b/tests/unit/s2n_kem_test.c index 700644aa37b..8afe50798e1 100644 --- a/tests/unit/s2n_kem_test.c +++ b/tests/unit/s2n_kem_test.c @@ -94,6 +94,8 @@ int main(int argc, char **argv) END_TEST(); } +#if !defined(S2N_NO_PQ) + { /* Regression test for network parsing data of expected sizes */ EXPECT_EQUAL(sizeof(kem_extension_size), 2); @@ -300,5 +302,7 @@ int main(int argc, char **argv) EXPECT_EQUAL(compatible_params->kems[1]->kem_extension_id, s2n_sike_p434_r2.kem_extension_id); } +#endif + END_TEST(); } diff --git a/tests/unit/s2n_kex_with_kem_test.c b/tests/unit/s2n_kex_with_kem_test.c index 08a3400beac..3c21bb90aa3 100644 --- a/tests/unit/s2n_kex_with_kem_test.c +++ b/tests/unit/s2n_kex_with_kem_test.c @@ -152,6 +152,9 @@ static int assert_kex_fips_checks(struct s2n_cipher_suite *cipher_suite, const c int main(int argc, char **argv) { BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode. So we verify functions s2n_check_kem() and * s2n_configure_kem() (in s2n_kex.c) are performing their FIPS checks appropriately. */ @@ -198,5 +201,7 @@ int main(int argc, char **argv) S2N_ERR_KEM_UNSUPPORTED_PARAMS); } +#endif + END_TEST(); } diff --git a/tests/unit/s2n_sike_r1_kat_test.c b/tests/unit/s2n_sike_r1_kat_test.c index 7f8861552d5..92a1c186375 100644 --- a/tests/unit/s2n_sike_r1_kat_test.c +++ b/tests/unit/s2n_sike_r1_kat_test.c @@ -27,11 +27,16 @@ int main(int argc, char **argv, char **envp) { BEGIN_TEST(); +#if !defined(S2N_NO_PQ) + if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); } EXPECT_SUCCESS(s2n_test_kem_with_kat(&s2n_sike_p503_r1, RSP_FILE)); + +#endif + END_TEST(); } diff --git a/tests/unit/s2n_sike_r1_kem_test.c b/tests/unit/s2n_sike_r1_kem_test.c index 28e03cf0821..386087ee06b 100644 --- a/tests/unit/s2n_sike_r1_kem_test.c +++ b/tests/unit/s2n_sike_r1_kem_test.c @@ -19,14 +19,16 @@ int main(int argc, char **argv) { + BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + unsigned char pub_key[SIKE_P503_R1_PUBLIC_KEY_BYTES] = {0}; unsigned char priv_key[SIKE_P503_R1_SECRET_KEY_BYTES] = {0}; unsigned char c_shared_secret[SIKE_P503_R1_SHARED_SECRET_BYTES]; unsigned char s_shared_secret[SIKE_P503_R1_SHARED_SECRET_BYTES]; unsigned char ciphertext[SIKE_P503_R1_CIPHERTEXT_BYTES]; - BEGIN_TEST(); - if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); @@ -37,5 +39,7 @@ int main(int argc, char **argv) EXPECT_SUCCESS(SIKE_P503_r1_crypto_kem_dec(s_shared_secret, ciphertext, priv_key)); EXPECT_BYTEARRAY_EQUAL(s_shared_secret, c_shared_secret, SIKE_P503_R1_SHARED_SECRET_BYTES); +#endif + END_TEST(); } diff --git a/tests/unit/s2n_sike_r2_kat_test.c b/tests/unit/s2n_sike_r2_kat_test.c index 730491d8753..6cca8d002ac 100644 --- a/tests/unit/s2n_sike_r2_kat_test.c +++ b/tests/unit/s2n_sike_r2_kat_test.c @@ -27,11 +27,16 @@ int main(int argc, char **argv, char **envp) { BEGIN_TEST(); +#if !defined(S2N_NO_PQ) + if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ END_TEST(); } EXPECT_SUCCESS(s2n_test_kem_with_kat(&s2n_sike_p434_r2, RSP_FILE)); + +#endif + END_TEST(); } diff --git a/tests/unit/s2n_sike_r2_kem_test.c b/tests/unit/s2n_sike_r2_kem_test.c index d1907253226..deb6fce588f 100644 --- a/tests/unit/s2n_sike_r2_kem_test.c +++ b/tests/unit/s2n_sike_r2_kem_test.c @@ -18,18 +18,22 @@ int main(int argc, char **argv) { + BEGIN_TEST(); + +#if !defined(S2N_NO_PQ) + unsigned char pub_key[SIKE_P434_R2_PUBLIC_KEY_BYTES] = {0}; unsigned char priv_key[SIKE_P434_R2_SECRET_KEY_BYTES] = {0}; unsigned char c_shared_secret[SIKE_P434_R2_SHARED_SECRET_BYTES]; unsigned char s_shared_secret[SIKE_P434_R2_SHARED_SECRET_BYTES]; unsigned char ciphertext[SIKE_P434_R2_CIPHERTEXT_BYTES]; - BEGIN_TEST(); - EXPECT_SUCCESS(SIKE_P434_r2_crypto_kem_keypair(pub_key, priv_key)); EXPECT_SUCCESS(SIKE_P434_r2_crypto_kem_enc(ciphertext, c_shared_secret, pub_key)); EXPECT_SUCCESS(SIKE_P434_r2_crypto_kem_dec(s_shared_secret, ciphertext, priv_key)); EXPECT_BYTEARRAY_EQUAL(s_shared_secret, c_shared_secret, SIKE_P434_R2_SHARED_SECRET_BYTES); +#endif + END_TEST(); } diff --git a/tests/unit/s2n_sike_r2_verify_included_code_test.c b/tests/unit/s2n_sike_r2_verify_included_code_test.c index 8485125c354..9aebfaccc21 100644 --- a/tests/unit/s2n_sike_r2_verify_included_code_test.c +++ b/tests/unit/s2n_sike_r2_verify_included_code_test.c @@ -20,6 +20,7 @@ int main(int argc, char **argv) { BEGIN_TEST(); +#if !defined(S2N_NO_PQ) if (s2n_is_in_fips_mode()) { /* There is no support for PQ KEMs while in FIPS mode */ @@ -38,7 +39,9 @@ int main(int argc, char **argv) EXPECT_EQUAL(sike_r2_fp_code_identifier(), GENERIC_C_CODE_IDENTIFIER); #else FAIL_MSG("Neither S2N_PQ_ASM nor S2N_PQ_GENERIC was defined. One of those must be defined."); -#endif +#endif /* defined(S2N_PQ_ASM) */ + +#endif /* !defined(S2N_NO_PQ) */ END_TEST(); } diff --git a/tls/s2n_cipher_preferences.c b/tls/s2n_cipher_preferences.c index 04daac3deb9..61c79549aa8 100644 --- a/tls/s2n_cipher_preferences.c +++ b/tls/s2n_cipher_preferences.c @@ -32,6 +32,8 @@ &s2n_tls13_aes_128_gcm_sha256, \ &s2n_tls13_chacha20_poly1305_sha256 \ + +#if !defined(S2N_NO_PQ) /* Extension list for round 1 PQ KEMs, in order of preference */ const struct s2n_kem *pq_kems_r1[2] = { &s2n_bike1_l1_r1, @@ -58,6 +60,8 @@ const struct s2n_kem *pq_kems_sike_r2r1[2] = { &s2n_sike_p503_r1, }; +#endif + /* s2n's list of cipher suites, in order of preferences, as of 2019-08-01 */ struct s2n_cipher_suite *cipher_suites_20190801[] = { S2N_TLS13_CIPHER_SUITES_20190801, @@ -867,6 +871,8 @@ const struct s2n_cipher_preferences cipher_preferences_kms_tls_1_0_2018_10 = { .kems = NULL, }; +#if !defined(S2N_NO_PQ) + struct s2n_cipher_suite *cipher_suites_kms_pq_tls_1_0_2019_06[] = { &s2n_ecdhe_bike_rsa_with_aes_256_gcm_sha384, &s2n_ecdhe_sike_rsa_with_aes_256_gcm_sha384, @@ -934,6 +940,8 @@ const struct s2n_cipher_preferences cipher_preferences_pq_sike_test_tls_1_0_2020 .kems = pq_kems_sike_r2r1, }; +#endif + struct s2n_cipher_suite *cipher_suites_kms_fips_tls_1_2_2018_10[] = { &s2n_ecdhe_rsa_with_aes_256_gcm_sha384, &s2n_ecdhe_rsa_with_aes_128_gcm_sha256, @@ -980,10 +988,12 @@ struct { { .version="CloudFront-TLS-1-2-2018", .preferences=&cipher_preferences_cloudfront_tls_1_2_2018, .ecc_extension_required=0, .pq_kem_extension_required=0}, { .version="CloudFront-TLS-1-2-2019", .preferences=&cipher_preferences_cloudfront_tls_1_2_2019, .ecc_extension_required=0, .pq_kem_extension_required=0}, { .version="KMS-TLS-1-0-2018-10", .preferences=&cipher_preferences_kms_tls_1_0_2018_10, .ecc_extension_required=0, .pq_kem_extension_required=0}, +#if !defined(S2N_NO_PQ) { .version="KMS-PQ-TLS-1-0-2019-06", .preferences=&cipher_preferences_kms_pq_tls_1_0_2019_06, .ecc_extension_required=0, .pq_kem_extension_required=0}, { .version="KMS-PQ-TLS-1-0-2020-02", .preferences=&cipher_preferences_kms_pq_tls_1_0_2020_02, .ecc_extension_required=0, .pq_kem_extension_required=0}, { .version="PQ-SIKE-TEST-TLS-1-0-2019-11", .preferences=&cipher_preferences_pq_sike_test_tls_1_0_2019_11, .ecc_extension_required=0, .pq_kem_extension_required=0}, { .version="PQ-SIKE-TEST-TLS-1-0-2020-02", .preferences=&cipher_preferences_pq_sike_test_tls_1_0_2020_02, .ecc_extension_required=0, .pq_kem_extension_required=0}, +#endif { .version="KMS-FIPS-TLS-1-2-2018-10", .preferences=&cipher_preferences_kms_fips_tls_1_2_2018_10, .ecc_extension_required=0, .pq_kem_extension_required=0}, { .version="20140601", .preferences=&cipher_preferences_20140601, .ecc_extension_required=0, .pq_kem_extension_required=0}, { .version="20141001", .preferences=&cipher_preferences_20141001, .ecc_extension_required=0, .pq_kem_extension_required=0}, diff --git a/tls/s2n_cipher_preferences.h b/tls/s2n_cipher_preferences.h index 5b8973b51dc..ee85b5c798a 100644 --- a/tls/s2n_cipher_preferences.h +++ b/tls/s2n_cipher_preferences.h @@ -28,11 +28,15 @@ struct s2n_cipher_preferences { const struct s2n_kem **kems; }; +#if !defined(S2N_NO_PQ) + extern const struct s2n_kem *pq_kems_r1[2]; extern const struct s2n_kem *pq_kems_r2r1[4]; extern const struct s2n_kem *pq_kems_sike_r1[1]; extern const struct s2n_kem *pq_kems_sike_r2r1[2]; +#endif + extern const struct s2n_cipher_preferences cipher_preferences_20140601; extern const struct s2n_cipher_preferences cipher_preferences_20141001; extern const struct s2n_cipher_preferences cipher_preferences_20150202; diff --git a/tls/s2n_cipher_suites.c b/tls/s2n_cipher_suites.c index 35b179aaf1d..709485b8e44 100644 --- a/tls/s2n_cipher_suites.c +++ b/tls/s2n_cipher_suites.c @@ -775,8 +775,13 @@ const struct s2n_cipher_preferences cipher_preferences_test_all = { .count = s2n_array_len(s2n_all_cipher_suites), .suites = s2n_all_cipher_suites, .minimum_protocol_version = S2N_SSLv3, +#if !defined(S2N_NO_PQ) .kem_count = s2n_array_len(pq_kems_r2r1), .kems = pq_kems_r2r1, +#else + .kem_count = 0, + .kems = NULL, +#endif }; /* All of the cipher suites that s2n can negotiate when in FIPS mode, diff --git a/tls/s2n_kem.c b/tls/s2n_kem.c index fdca75eb2c0..7af537bd6c9 100644 --- a/tls/s2n_kem.c +++ b/tls/s2n_kem.c @@ -13,11 +13,6 @@ * permissions and limitations under the License. */ -#include "pq-crypto/bike_r1/bike_r1_kem.h" -#include "pq-crypto/bike_r2/bike_r2_kem.h" -#include "pq-crypto/sike_r1/sike_r1_kem.h" -#include "pq-crypto/sike_r2/sike_r2_kem.h" - #include "stuffer/s2n_stuffer.h" #include "tls/s2n_tls_parameters.h" @@ -26,6 +21,13 @@ #include "utils/s2n_mem.h" #include "utils/s2n_safety.h" +#if !defined(S2N_NO_PQ) + +#include "pq-crypto/bike_r1/bike_r1_kem.h" +#include "pq-crypto/bike_r2/bike_r2_kem.h" +#include "pq-crypto/sike_r1/sike_r1_kem.h" +#include "pq-crypto/sike_r2/sike_r2_kem.h" + /* The names below come from https://tools.ietf.org/html/draft-campagna-tls-bike-sike-hybrid-02#section-5.1.6 */ const struct s2n_kem s2n_bike1_l1_r1 = { .name = "BIKE1r1-Level1", @@ -100,6 +102,14 @@ const struct s2n_iana_to_kem kem_mapping[2] = { } }; +#else + +/* Compiler warns that zero-length arrays are undefined according to the C standard. So make kem_mapping NULL if + * Post Quantum ciphers are disabled, and have s2n_cipher_suite_to_kem() detect NULL and treat it as zero-length. */ +const struct s2n_iana_to_kem *kem_mapping = NULL; + +#endif + int s2n_kem_generate_keypair(struct s2n_kem_keypair *kem_keys) { notnull_check(kem_keys); @@ -236,6 +246,9 @@ int s2n_kem_free(struct s2n_kem_keypair *kem_keys) int s2n_cipher_suite_to_kem(const uint8_t iana_value[S2N_TLS_CIPHER_SUITE_LEN], const struct s2n_iana_to_kem **compatible_params) { + /* cppcheck-suppress knownConditionTrueFalse */ + S2N_ERROR_IF(kem_mapping == NULL, S2N_ERR_KEM_UNSUPPORTED_PARAMS); + for (int i = 0; i < s2n_array_len(kem_mapping); i++) { const struct s2n_iana_to_kem *candidate = &kem_mapping[i]; if (memcmp(iana_value, candidate->iana_value, S2N_TLS_CIPHER_SUITE_LEN) == 0) { diff --git a/tls/s2n_kem.h b/tls/s2n_kem.h index ad8afa71e7e..3a9f26a1d7b 100644 --- a/tls/s2n_kem.h +++ b/tls/s2n_kem.h @@ -44,11 +44,15 @@ struct s2n_iana_to_kem { uint8_t kem_count; }; +#if !defined(S2N_NO_PQ) + extern const struct s2n_kem s2n_bike1_l1_r1; extern const struct s2n_kem s2n_bike1_l1_r2; extern const struct s2n_kem s2n_sike_p503_r1; extern const struct s2n_kem s2n_sike_p434_r2; +#endif + extern int s2n_kem_generate_keypair(struct s2n_kem_keypair *kem_keys); extern int s2n_kem_encapsulate(const struct s2n_kem_keypair *kem_keys, struct s2n_blob *shared_secret, diff --git a/utils/s2n_safety.h b/utils/s2n_safety.h index 8ddf8537014..228190933e1 100644 --- a/utils/s2n_safety.h +++ b/utils/s2n_safety.h @@ -162,7 +162,7 @@ extern int s2n_constant_time_pkcs1_unpad_or_dont(uint8_t * dst, const uint8_t * } \ struct __useless_struct_to_allow_trailing_semicolon__ -#define s2n_array_len(array) (sizeof(array) / sizeof(array[0])) +#define s2n_array_len(array) ((array != NULL) ? (sizeof(array) / sizeof(array[0])) : 0) extern int s2n_mul_overflow(uint32_t a, uint32_t b, uint32_t* out);