Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

create rfc9151 security policy #3431

Merged
merged 7 commits into from
Aug 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions docs/USAGE-GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ if (s2n_negotiate(conn, &blocked) < 0) {

### Blinding

Blinding is a mitigation against timing side-channels which in some cases can leak information about encrypted data. By default s2n-tls will cause a thread to sleep between 10 and 30 seconds whenever tampering is detected.
Blinding is a mitigation against timing side-channels which in some cases can leak information about encrypted data. By default s2n-tls will cause a thread to sleep between 10 and 30 seconds whenever tampering is detected.

Setting the `S2N_SELF_SERVICE_BLINDING` option with `s2n_connection_set_blinding()` turns off this behavior. This is useful for applications that are handling many connections in a single thread. In that case, if `s2n_recv()` or `s2n_negotiate()` return an error, self-service applications must call `s2n_connection_get_delay()` and pause activity on the connection for the specified number of nanoseconds before calling `close()` or `shutdown()`. `s2n_shutdown()` will fail if called before the blinding delay elapses.

Expand All @@ -337,8 +337,8 @@ If you are trying to use FIPS mode, you must enable FIPS in your libcrypto libra

## Security Policies

s2n-tls uses pre-made security policies to help avoid common misconfiguration mistakes for TLS.
s2n-tls uses pre-made security policies to help avoid common misconfiguration mistakes for TLS.

`s2n_config_set_cipher_preferences()` sets a security policy, which includes the cipher/kem/signature/ecc preferences and protocol version.

The following chart maps the security policy version to protocol version and ciphersuites supported:
Expand Down Expand Up @@ -366,13 +366,16 @@ The following chart maps the security policy version to protocol version and cip
| "20190801" | | X | X | X | X | X | X | | X | | | | X |
| "20190802" | | X | X | X | X | X | X | | X | | | | X |
| "20200207" | | X | X | X | X | X | X | | X | | | | |
| "rfc9151" | | | | X | X | | | X | X | | | X | X |

The "default" and "default_tls13" version is special in that it will be updated with future s2n-tls changes and ciphersuites and protocol versions may be added and removed, or their internal order of preference might change. Numbered versions are fixed and will never change.

"20160411" follows the same general preference order as "default". The main difference is it has a CBC cipher suite at the top. This is to accommodate certain Java clients that have poor GCM implementations. Users of s2n-tls who have found GCM to be hurting performance for their clients should consider this version.

"20170405" is a FIPS compliant cipher suite preference list based on approved algorithms in the [FIPS 140-2 Annex A](http://csrc.nist.gov/publications/fips/fips140-2/fips1402annexa.pdf). Similarly to "20160411", this preference list has CBC cipher suites at the top to accommodate certain Java clients. Users of s2n-tls who plan to enable FIPS mode should consider this version.

The "rfc9151" security policy is derived from [Commercial National Security Algorithm (CNSA) Suite Profile for TLS and DTLS 1.2 and 1.3](https://datatracker.ietf.org/doc/html/rfc9151).

s2n-tls does not expose an API to control the order of preference for each ciphersuite or protocol version. s2n-tls follows the following order:

*NOTE*: All ChaCha20-Poly1305 cipher suites will not be available if s2n-tls is not built with an Openssl 1.1.1 libcrypto. The
Expand Down Expand Up @@ -408,6 +411,7 @@ The following chart maps the security policy version to the signature scheme sup
| "20190801" | X | X | X | X |
| "20190802" | X | X | X | X |
| "20200207" | X | X | X | X |
| "rfc9151" | X | X | | X |

Note that the default_tls13 security policy will never support legacy SHA-1 algorithms in TLS1.3, but will support
legacy SHA-1 algorithms in CertificateVerify messages if TLS1.2 has been negotiated.
Expand Down Expand Up @@ -437,6 +441,7 @@ The following chart maps the security policy version to the supported curves/gro
| "20190801" | X | X | X |
| "20190802" | X | X | |
| "20200207" | X | X | X |
| "rfc9151" | | X | |

## Certificates and Authentication

Expand All @@ -448,11 +453,11 @@ Authentication is usually the most expensive part of the handshake. To avoid the

To validate the peer’s certificate, the local “trust store” must contain a certificate that can authenticate the peer’s certificate.

By default, s2n-tls will be initialized with the common trust store locations for the host operating system. To completely override those locations, call `s2n_config_wipe_trust_store()`. To add certificates to the trust store, call `s2n_config_set_verification_ca_location()` or `s2n_config_add_pem_to_trust_store()`.
By default, s2n-tls will be initialized with the common trust store locations for the host operating system. To completely override those locations, call `s2n_config_wipe_trust_store()`. To add certificates to the trust store, call `s2n_config_set_verification_ca_location()` or `s2n_config_add_pem_to_trust_store()`.

### Server Authentication

A server must have a certificate and private key pair to prove its identity. s2n-tls supports RSA, RSA-PSS, and ECDSA certificates, and allows one of each type to be added to a config.
A server must have a certificate and private key pair to prove its identity. s2n-tls supports RSA, RSA-PSS, and ECDSA certificates, and allows one of each type to be added to a config.

Create a new certificate and key pair by calling `s2n_cert_chain_and_key_new()`, then load the pem-encoded data with `s2n_cert_chain_and_key_load_pem_bytes()`. Call `s2n_config_add_cert_chain_and_key_to_store()` to add the certificate and key pair to the config. When a certificate and key pair is no longer needed, it must be cleaned up with `s2n_cert_chain_and_key_free()`.

Expand Down
16 changes: 16 additions & 0 deletions tls/s2n_cipher_preferences.c
Original file line number Diff line number Diff line change
Expand Up @@ -1768,4 +1768,20 @@ const struct s2n_cipher_preferences cipher_preferences_20210816_gcm = {
.suites = cipher_suites_20210816_gcm,
};

struct s2n_cipher_suite *cipher_suites_rfc9151[] = {
/* TLS1.2 */
&s2n_ecdhe_ecdsa_with_aes_256_gcm_sha384,
&s2n_ecdhe_rsa_with_aes_256_gcm_sha384,
&s2n_rsa_with_aes_256_gcm_sha384,
&s2n_dhe_rsa_with_aes_256_gcm_sha384,

/* TLS1.3 */
&s2n_tls13_aes_256_gcm_sha384,
};

const struct s2n_cipher_preferences cipher_preferences_rfc9151 = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

out of curiosity, is there a reason why we are not using a date version string eg something like 20220822?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://github.com/aws/s2n-tls/blob/main/docs/USAGE-GUIDE.md

Numbered versions are fixed and will never change.

we try to avoid numbered version where possible since the numbers dont really mean much and since policy cant ever change, it will become outdated at some point.

Copy link
Contributor

@camshaft camshaft Aug 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't say we avoid them; they're all over. Outside of default, I think all of them are date-versioned. However, in this case I actually think the RFC number is a pretty reasonable version since RFCs are unable to change after being published. So we still have immutability and it actually means something as opposed to some arbitrary date.

.count = s2n_array_len(cipher_suites_rfc9151),
.suites = cipher_suites_rfc9151,
};

/* clang-format on */
1 change: 1 addition & 0 deletions tls/s2n_cipher_preferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ extern const struct s2n_cipher_preferences cipher_preferences_20190801;
extern const struct s2n_cipher_preferences cipher_preferences_20190120;
extern const struct s2n_cipher_preferences cipher_preferences_20190121;
extern const struct s2n_cipher_preferences cipher_preferences_20190122;
extern const struct s2n_cipher_preferences cipher_preferences_rfc9151;
extern const struct s2n_cipher_preferences cipher_preferences_20210816;
extern const struct s2n_cipher_preferences cipher_preferences_20210816_gcm;
extern const struct s2n_cipher_preferences cipher_preferences_20210825;
Expand Down
19 changes: 18 additions & 1 deletion tls/s2n_security_policies.c
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,19 @@ const struct s2n_security_policy security_policy_20210816_gcm = {
.ecc_preferences = &s2n_ecc_preferences_20210816,
};

/*
* This security policy is derived from the following specification:
* https://datatracker.ietf.org/doc/html/rfc9151
*/
const struct s2n_security_policy security_policy_rfc9151 = {
.minimum_protocol_version = S2N_TLS12,
.cipher_preferences = &cipher_preferences_rfc9151,
.kem_preferences = &kem_preferences_null,
.signature_preferences = &s2n_signature_preferences_rfc9151,
.certificate_signature_preferences = &s2n_certificate_signature_preferences_rfc9151,
.ecc_preferences = &s2n_ecc_preferences_20210816,
};

const struct s2n_security_policy security_policy_test_all = {
.minimum_protocol_version = S2N_SSLv3,
.cipher_preferences = &cipher_preferences_test_all,
Expand Down Expand Up @@ -834,6 +847,7 @@ struct s2n_security_policy_selection security_policy_selection[] = {
{ .version="20201021", .security_policy=&security_policy_20201021, .ecc_extension_required=0, .pq_kem_extension_required=0 },
{ .version="20210816", .security_policy=&security_policy_20210816, .ecc_extension_required=0, .pq_kem_extension_required=0 },
{ .version="20210816_GCM", .security_policy=&security_policy_20210816_gcm, .ecc_extension_required=0, .pq_kem_extension_required=0 },
{ .version="rfc9151", .security_policy=&security_policy_rfc9151, .ecc_extension_required=0, .pq_kem_extension_required=0 },
{ .version="test_all", .security_policy=&security_policy_test_all, .ecc_extension_required=0, .pq_kem_extension_required=0 },
{ .version="test_all_fips", .security_policy=&security_policy_test_all_fips, .ecc_extension_required=0, .pq_kem_extension_required=0 },
{ .version="test_all_ecdsa", .security_policy=&security_policy_test_all_ecdsa, .ecc_extension_required=0, .pq_kem_extension_required=0 },
Expand Down Expand Up @@ -1084,7 +1098,10 @@ S2N_RESULT s2n_validate_certificate_signature_preferences(const struct s2n_signa
}
}

/* The Openssl function used to parse signatures off certificates does not differentiate between any rsa pss
/*
* https://github.com/aws/s2n-tls/issues/3435
*
* The Openssl function used to parse signatures off certificates does not differentiate between any rsa pss
* signature schemes. Therefore a security policy with a certificate signatures preference list must include
* all rsa_pss signature schemes. */
RESULT_ENSURE(rsa_pss_scheme_count == NUM_RSA_PSS_SCHEMES || rsa_pss_scheme_count == 0, S2N_ERR_INVALID_SECURITY_POLICY);
Expand Down
49 changes: 49 additions & 0 deletions tls/s2n_signature_scheme.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,3 +377,52 @@ const struct s2n_signature_preferences s2n_signature_preferences_20210816 = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_20210816),
.signature_schemes = s2n_sig_scheme_pref_list_20210816
};

const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_rfc9151[] = {
/* ECDSA - TLS 1.3 */
&s2n_ecdsa_secp384r1_sha384,

/* RSA PSS - TLS 1.3 */
&s2n_rsa_pss_pss_sha384,

/* ECDSA - TLS 1.2 */
&s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */

/* RSA */
&s2n_rsa_pss_rsae_sha384,

&s2n_rsa_pkcs1_sha384,
};

const struct s2n_signature_scheme* const s2n_cert_sig_scheme_pref_list_rfc9151[] = {
/* ECDSA - TLS 1.3 */
&s2n_ecdsa_secp384r1_sha384,

/* RSA PSS
* https://github.com/aws/s2n-tls/issues/3435
*
* The Openssl function used to parse signatures off certificates does not differentiate
* between any rsa pss signature schemes. Therefore a security policy with a certificate
* signatures preference list must include all rsa_pss signature schemes.
*
* Since only sha384 is allowed by rfc9151, this certificate signing policy does not
* support rsa_pss.
*/

/* ECDSA - TLS 1.2 */
&s2n_ecdsa_sha384, /* same iana value as TLS 1.3 s2n_ecdsa_secp384r1_sha384 */

/* RSA */
&s2n_rsa_pkcs1_sha384,
};


const struct s2n_signature_preferences s2n_signature_preferences_rfc9151 = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_rfc9151),
.signature_schemes = s2n_sig_scheme_pref_list_rfc9151
};

const struct s2n_signature_preferences s2n_certificate_signature_preferences_rfc9151 = {
.count = s2n_array_len(s2n_cert_sig_scheme_pref_list_rfc9151),
.signature_schemes = s2n_cert_sig_scheme_pref_list_rfc9151
};
2 changes: 2 additions & 0 deletions tls/s2n_signature_scheme.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ extern const struct s2n_signature_preferences s2n_signature_preferences_20140601
extern const struct s2n_signature_preferences s2n_signature_preferences_20200207;
extern const struct s2n_signature_preferences s2n_signature_preferences_20201021;
extern const struct s2n_signature_preferences s2n_signature_preferences_20210816;
extern const struct s2n_signature_preferences s2n_signature_preferences_rfc9151;
extern const struct s2n_signature_preferences s2n_certificate_signature_preferences_rfc9151;
extern const struct s2n_signature_preferences s2n_signature_preferences_default_fips;
extern const struct s2n_signature_preferences s2n_signature_preferences_null;

Expand Down