Add SSL_[CTX_]_set_compliance_policy. These functions aid in meeting specific compliance goals and allows configuration of things like TLS 1.3 cipher suites, which are otherwise not configurable. Change-Id: I668afc734a19ecd4b996eaa23be73ce259b13fa2 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/52625 Commit-Queue: Adam Langley <agl@google.com> Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/ssl/ssl_lib.cc b/ssl/ssl_lib.cc index 5e96bef..0b3febf 100644 --- a/ssl/ssl_lib.cc +++ b/ssl/ssl_lib.cc
@@ -519,7 +519,8 @@ allow_unknown_alpn_protos(false), false_start_allowed_without_alpn(false), handoff(false), - enable_early_data(false) { + enable_early_data(false), + only_fips_cipher_suites_in_tls13(false) { CRYPTO_MUTEX_init(&lock); CRYPTO_new_ex_data(&ex_data); } @@ -639,6 +640,8 @@ ssl->config->retain_only_sha256_of_client_certs = ctx->retain_only_sha256_of_client_certs; ssl->config->permute_extensions = ctx->permute_extensions; + ssl->config->only_fips_cipher_suites_in_tls13 = + ctx->only_fips_cipher_suites_in_tls13; if (!ssl->config->supported_group_list.CopyFrom(ctx->supported_group_list) || !ssl->config->alpn_client_proto_list.CopyFrom( @@ -3079,3 +3082,93 @@ ctx->legacy_ocsp_callback_arg = arg; return 1; } + +namespace fips202205 { + +// (References are to SP 800-52r2): + +// Section 3.4.2.2 +// "at least one of the NIST-approved curves, P-256 (secp256r1) and P384 +// (secp384r1), shall be supported as described in RFC 8422." +// +// Section 3.3.1 +// "The server shall be configured to only use cipher suites that are +// composed entirely of NIST approved algorithms" +static const int kCurves[] = {NID_X9_62_prime256v1, NID_secp384r1}; + +static const uint16_t kSigAlgs[] = { + SSL_SIGN_RSA_PKCS1_SHA256, + SSL_SIGN_RSA_PKCS1_SHA384, + SSL_SIGN_RSA_PKCS1_SHA512, + // Table 4.1: + // "The curve should be P-256 or P-384" + SSL_SIGN_ECDSA_SECP256R1_SHA256, + SSL_SIGN_ECDSA_SECP384R1_SHA384, + SSL_SIGN_RSA_PSS_RSAE_SHA256, + SSL_SIGN_RSA_PSS_RSAE_SHA384, + SSL_SIGN_RSA_PSS_RSAE_SHA512, +}; + +static const char kTLS12Ciphers[] = + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:" + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:" + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:" + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; + +static int Configure(SSL_CTX *ctx) { + ctx->only_fips_cipher_suites_in_tls13 = true; + + return + // Section 3.1: + // "Servers that support government-only applications shall be + // configured to use TLS 1.2 and should be configured to use TLS 1.3 + // as well. These servers should not be configured to use TLS 1.1 and + // shall not use TLS 1.0, SSL 3.0, or SSL 2.0. + SSL_CTX_set_min_proto_version(ctx, TLS1_2_VERSION) && + SSL_CTX_set_max_proto_version(ctx, TLS1_3_VERSION) && + // Sections 3.3.1.1.1 and 3.3.1.1.2 are ambiguous about whether + // HMAC-SHA-1 cipher suites are permitted with TLS 1.2. However, later the + // Encrypt-then-MAC extension is required for all CBC cipher suites and so + // it's easier to drop them. + SSL_CTX_set_strict_cipher_list(ctx, kTLS12Ciphers) && + SSL_CTX_set1_curves(ctx, kCurves, OPENSSL_ARRAY_SIZE(kCurves)) && + SSL_CTX_set_signing_algorithm_prefs(ctx, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)) && + SSL_CTX_set_verify_algorithm_prefs(ctx, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)); +} + +static int Configure(SSL *ssl) { + ssl->config->only_fips_cipher_suites_in_tls13 = true; + + // See |Configure(SSL_CTX)|, above, for reasoning. + return SSL_set_min_proto_version(ssl, TLS1_2_VERSION) && + SSL_set_max_proto_version(ssl, TLS1_3_VERSION) && + SSL_set_strict_cipher_list(ssl, kTLS12Ciphers) && + SSL_set1_curves(ssl, kCurves, OPENSSL_ARRAY_SIZE(kCurves)) && + SSL_set_signing_algorithm_prefs(ssl, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)) && + SSL_set_verify_algorithm_prefs(ssl, kSigAlgs, + OPENSSL_ARRAY_SIZE(kSigAlgs)); +} + +} // namespace fips202205 + +int SSL_CTX_set_compliance_policy(SSL_CTX *ctx, + enum ssl_compliance_policy_t policy) { + switch (policy) { + case ssl_compliance_policy_fips_202205: + return fips202205::Configure(ctx); + default: + return 0; + } +} + +int SSL_set_compliance_policy(SSL *ssl, enum ssl_compliance_policy_t policy) { + switch (policy) { + case ssl_compliance_policy_fips_202205: + return fips202205::Configure(ssl); + default: + return 0; + } +}