tls/s2n_signature_scheme.c (388 lines of code) (raw):
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
#include "tls/s2n_signature_scheme.h"
#include "api/s2n.h"
#include "crypto/s2n_ecc_evp.h"
#include "crypto/s2n_hash.h"
#include "crypto/s2n_signature.h"
#include "tls/s2n_connection.h"
#include "utils/s2n_safety.h"
const struct s2n_signature_scheme s2n_null_sig_scheme = {
.iana_value = 0,
.iana_name = "null_sha0",
.hash_alg = S2N_HASH_NONE,
.sig_alg = S2N_SIGNATURE_ANONYMOUS,
.libcrypto_nid = 0,
.signature_curve = NULL,
.maximum_protocol_version = 0,
};
/* RSA PKCS1 */
const struct s2n_signature_scheme s2n_rsa_pkcs1_md5_sha1 = {
.iana_value = TLS_SIGNATURE_SCHEME_PRIVATE_INTERNAL_RSA_PKCS1_MD5_SHA1,
.iana_name = "legacy_rsa_pkcs1_md5_sha1",
.hash_alg = S2N_HASH_MD5_SHA1,
.sig_alg = S2N_SIGNATURE_RSA,
.libcrypto_nid = NID_md5_sha1,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 or sha1 */
};
const struct s2n_signature_scheme s2n_rsa_pkcs1_sha1 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA1,
.iana_name = "rsa_pkcs1_sha1",
.hash_alg = S2N_HASH_SHA1,
.sig_alg = S2N_SIGNATURE_RSA,
.libcrypto_nid = NID_sha1WithRSAEncryption,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 or sha1 */
};
const struct s2n_signature_scheme s2n_rsa_pkcs1_sha224 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA224,
.iana_name = "legacy_rsa_pkcs1_sha224",
.hash_alg = S2N_HASH_SHA224,
.sig_alg = S2N_SIGNATURE_RSA,
.libcrypto_nid = NID_sha224WithRSAEncryption,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
};
const struct s2n_signature_scheme s2n_rsa_pkcs1_sha256 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA256,
.iana_name = "rsa_pkcs1_sha256",
.hash_alg = S2N_HASH_SHA256,
.sig_alg = S2N_SIGNATURE_RSA,
.libcrypto_nid = NID_sha256WithRSAEncryption,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
};
const struct s2n_signature_scheme s2n_rsa_pkcs1_sha384 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA384,
.iana_name = "rsa_pkcs1_sha384",
.hash_alg = S2N_HASH_SHA384,
.sig_alg = S2N_SIGNATURE_RSA,
.libcrypto_nid = NID_sha384WithRSAEncryption,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
};
const struct s2n_signature_scheme s2n_rsa_pkcs1_sha512 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PKCS1_SHA512,
.iana_name = "rsa_pkcs1_sha512",
.hash_alg = S2N_HASH_SHA512,
.sig_alg = S2N_SIGNATURE_RSA,
.libcrypto_nid = NID_sha512WithRSAEncryption,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support pkcs1 */
};
/* TLS 1.2 Compatible ECDSA Signature Schemes */
const struct s2n_signature_scheme s2n_ecdsa_sha1 = {
.iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA1,
.iana_name = "ecdsa_sha1",
.hash_alg = S2N_HASH_SHA1,
.sig_alg = S2N_SIGNATURE_ECDSA,
.libcrypto_nid = NID_ecdsa_with_SHA1,
.signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
.maximum_protocol_version = S2N_TLS12, /* TLS1.3 does not support sha1 and requires a signature curve */
};
const struct s2n_signature_scheme s2n_ecdsa_sha224 = {
.iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA224,
.iana_name = "legacy_ecdsa_sha224",
.hash_alg = S2N_HASH_SHA224,
.sig_alg = S2N_SIGNATURE_ECDSA,
.libcrypto_nid = NID_ecdsa_with_SHA224,
.signature_curve = NULL, /* Decided by supported_groups Extension in TLS 1.2 and before */
.maximum_protocol_version = S2N_TLS12, /* TLS1.3 requires a signature curve */
};
const struct s2n_signature_scheme s2n_ecdsa_sha256 = {
.iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA256,
.iana_name = "ecdsa_sha256",
.hash_alg = S2N_HASH_SHA256,
.sig_alg = S2N_SIGNATURE_ECDSA,
.libcrypto_nid = NID_ecdsa_with_SHA256,
.signature_curve = &s2n_ecc_curve_secp256r1, /* Hardcoded for TLS 1.3 */
};
const struct s2n_signature_scheme s2n_ecdsa_sha384 = {
.iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA384,
.iana_name = "ecdsa_sha384",
.hash_alg = S2N_HASH_SHA384,
.sig_alg = S2N_SIGNATURE_ECDSA,
.libcrypto_nid = NID_ecdsa_with_SHA384,
.signature_curve = &s2n_ecc_curve_secp384r1, /* Hardcoded for TLS 1.3 */
};
const struct s2n_signature_scheme s2n_ecdsa_sha512 = {
.iana_value = TLS_SIGNATURE_SCHEME_ECDSA_SHA512,
.iana_name = "ecdsa_sha512",
.hash_alg = S2N_HASH_SHA512,
.sig_alg = S2N_SIGNATURE_ECDSA,
.libcrypto_nid = NID_ecdsa_with_SHA512,
.signature_curve = &s2n_ecc_curve_secp521r1, /* Hardcoded for TLS 1.3 */
};
/**
* RSA-PSS-RSAE
*/
const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha256 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA256,
.iana_name = "rsa_pss_rsae_sha256",
.hash_alg = S2N_HASH_SHA256,
.sig_alg = S2N_SIGNATURE_RSA_PSS_RSAE,
.libcrypto_nid = NID_rsassaPss,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
};
const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha384 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA384,
.iana_name = "rsa_pss_rsae_sha384",
.hash_alg = S2N_HASH_SHA384,
.sig_alg = S2N_SIGNATURE_RSA_PSS_RSAE,
.libcrypto_nid = NID_rsassaPss,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
};
const struct s2n_signature_scheme s2n_rsa_pss_rsae_sha512 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_RSAE_SHA512,
.iana_name = "rsa_pss_rsae_sha512",
.hash_alg = S2N_HASH_SHA512,
.sig_alg = S2N_SIGNATURE_RSA_PSS_RSAE,
.libcrypto_nid = NID_rsassaPss,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
};
/**
* RSA-PSS-PSS
*/
const struct s2n_signature_scheme s2n_rsa_pss_pss_sha256 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA256,
.iana_name = "rsa_pss_pss_sha256",
.hash_alg = S2N_HASH_SHA256,
.sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
.libcrypto_nid = NID_rsassaPss,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.minimum_protocol_version = S2N_TLS12,
};
const struct s2n_signature_scheme s2n_rsa_pss_pss_sha384 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA384,
.iana_name = "rsa_pss_pss_sha384",
.hash_alg = S2N_HASH_SHA384,
.sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
.libcrypto_nid = NID_rsassaPss,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.minimum_protocol_version = S2N_TLS12,
};
const struct s2n_signature_scheme s2n_rsa_pss_pss_sha512 = {
.iana_value = TLS_SIGNATURE_SCHEME_RSA_PSS_PSS_SHA512,
.iana_name = "rsa_pss_pss_sha512",
.hash_alg = S2N_HASH_SHA512,
.sig_alg = S2N_SIGNATURE_RSA_PSS_PSS,
.libcrypto_nid = NID_rsassaPss,
.signature_curve = NULL, /* Elliptic Curve not needed for RSA */
.minimum_protocol_version = S2N_TLS12,
};
/* ALL signature schemes, including the legacy default s2n_rsa_pkcs1_md5_sha1 scheme.
* New signature schemes must be added to this list.
*/
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_all[] = {
&s2n_rsa_pkcs1_md5_sha1,
&s2n_rsa_pkcs1_sha1,
&s2n_rsa_pkcs1_sha224,
&s2n_rsa_pkcs1_sha256,
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
&s2n_ecdsa_sha1,
&s2n_ecdsa_sha224,
&s2n_ecdsa_sha256,
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
&s2n_rsa_pss_rsae_sha256,
&s2n_rsa_pss_rsae_sha384,
&s2n_rsa_pss_rsae_sha512,
&s2n_rsa_pss_pss_sha256,
&s2n_rsa_pss_pss_sha384,
&s2n_rsa_pss_pss_sha512,
};
const struct s2n_signature_preferences s2n_signature_preferences_all = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_all),
.signature_schemes = s2n_sig_scheme_pref_list_all,
};
/* Chosen based on AWS server recommendations as of 05/24.
*
* The recommendations do not include PKCS1, but we must include it anyway for
* compatibility with older versions of our own defaults. Our old defaults only
* supported PKCS1 for RSA, so would be unable to negotiate with a new default
* that didn't include PKCS1.
*/
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20240501[] = {
/* ECDSA */
&s2n_ecdsa_sha256,
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
/* RSA-PSS */
&s2n_rsa_pss_pss_sha256,
&s2n_rsa_pss_pss_sha384,
&s2n_rsa_pss_pss_sha512,
/* RSA */
&s2n_rsa_pss_rsae_sha256,
&s2n_rsa_pss_rsae_sha384,
&s2n_rsa_pss_rsae_sha512,
/* Legacy RSA with PKCS1 */
&s2n_rsa_pkcs1_sha256,
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
};
const struct s2n_signature_preferences s2n_signature_preferences_20240501 = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_20240501),
.signature_schemes = s2n_sig_scheme_pref_list_20240501,
};
/* All Supported SignatureSchemes. */
/* No MD5 to avoid SLOTH Vulnerability */
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20140601[] = {
/* RSA PKCS1 */
&s2n_rsa_pkcs1_sha256,
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
&s2n_rsa_pkcs1_sha224,
/* ECDSA */
&s2n_ecdsa_sha256,
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
&s2n_ecdsa_sha224,
/* SHA-1 Legacy */
&s2n_rsa_pkcs1_sha1,
&s2n_ecdsa_sha1,
};
/* The original preference list, but with rsa_pss supported. */
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20200207[] = {
/* RSA PSS */
&s2n_rsa_pss_pss_sha256,
&s2n_rsa_pss_pss_sha384,
&s2n_rsa_pss_pss_sha512,
&s2n_rsa_pss_rsae_sha256,
&s2n_rsa_pss_rsae_sha384,
&s2n_rsa_pss_rsae_sha512,
/* RSA PKCS1 */
&s2n_rsa_pkcs1_sha256,
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
&s2n_rsa_pkcs1_sha224,
/* ECDSA */
&s2n_ecdsa_sha256,
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
&s2n_ecdsa_sha224,
/* SHA-1 Legacy */
&s2n_rsa_pkcs1_sha1,
&s2n_ecdsa_sha1,
};
/*
* These signature schemes were chosen based on the following specification:
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-52r2.pdf
*/
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_default_fips[] = {
/* RSA PKCS1 - TLS1.2 */
&s2n_rsa_pkcs1_sha256,
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
/* ECDSA */
&s2n_ecdsa_sha256,
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
&s2n_ecdsa_sha224,
};
const struct s2n_signature_preferences s2n_signature_preferences_default_fips = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_default_fips),
.signature_schemes = s2n_sig_scheme_pref_list_default_fips,
};
/*
* FIPS compliant.
* Supports TLS1.3.
* Prefers PSS over PKCS1.
*/
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20230317[] = {
/* RSA */
&s2n_rsa_pss_rsae_sha256,
&s2n_rsa_pss_rsae_sha384,
&s2n_rsa_pss_rsae_sha512,
&s2n_rsa_pkcs1_sha256,
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
/* TLS1.2 with ECDSA */
&s2n_ecdsa_sha256,
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
/* TLS1.3 with RSA-PSS */
&s2n_rsa_pss_pss_sha256,
&s2n_rsa_pss_pss_sha384,
&s2n_rsa_pss_pss_sha512,
};
const struct s2n_signature_preferences s2n_signature_preferences_20230317 = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_20230317),
.signature_schemes = s2n_sig_scheme_pref_list_20230317,
};
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20201021[] = {
/* RSA PSS */
&s2n_rsa_pss_pss_sha256,
&s2n_rsa_pss_pss_sha384,
&s2n_rsa_pss_pss_sha512,
&s2n_rsa_pss_rsae_sha256,
&s2n_rsa_pss_rsae_sha384,
&s2n_rsa_pss_rsae_sha512,
/* RSA PKCS1 */
&s2n_rsa_pkcs1_sha256,
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
&s2n_rsa_pkcs1_sha224,
/* ECDSA */
&s2n_ecdsa_sha256,
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
&s2n_ecdsa_sha224,
/* SHA-1 Legacy */
&s2n_rsa_pkcs1_sha1,
&s2n_ecdsa_sha1,
};
const struct s2n_signature_preferences s2n_signature_preferences_20140601 = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_20140601),
.signature_schemes = s2n_sig_scheme_pref_list_20140601,
};
const struct s2n_signature_preferences s2n_signature_preferences_20200207 = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_20200207),
.signature_schemes = s2n_sig_scheme_pref_list_20200207,
};
const struct s2n_signature_preferences s2n_signature_preferences_20201021 = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_20201021),
.signature_schemes = s2n_sig_scheme_pref_list_20201021,
};
const struct s2n_signature_preferences s2n_signature_preferences_null = {
.count = 0,
.signature_schemes = NULL,
};
/* TLS1.3 supported signature schemes, without SHA-1 legacy algorithms */
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20201110[] = {
/* RSA PSS */
&s2n_rsa_pss_pss_sha256,
&s2n_rsa_pss_pss_sha384,
&s2n_rsa_pss_pss_sha512,
&s2n_rsa_pss_rsae_sha256,
&s2n_rsa_pss_rsae_sha384,
&s2n_rsa_pss_rsae_sha512,
/* RSA PKCS1 */
&s2n_rsa_pkcs1_sha256,
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
&s2n_rsa_pkcs1_sha224,
/* ECDSA */
&s2n_ecdsa_sha256,
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
&s2n_ecdsa_sha224,
};
const struct s2n_signature_preferences s2n_certificate_signature_preferences_20201110 = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_20201110),
.signature_schemes = s2n_sig_scheme_pref_list_20201110,
};
/* Based on s2n_sig_scheme_pref_list_20140601 but with all hashes < SHA-384 removed */
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20210816[] = {
/* RSA PKCS1 */
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
/* ECDSA */
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
};
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 */
&s2n_ecdsa_sha384,
/* RSA PSS - TLS 1.3 */
&s2n_rsa_pss_pss_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 */
&s2n_ecdsa_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.
*/
/* 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
};
/*
* Legacy compatibility policy based on s2n_sig_scheme_pref_list_20201021 with ECDSA prioritized.
* This list also removes ECDSA+SHA224, which is not known to be relied on by any legitimate
* use cases.
*/
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_20240521[] = {
/* ECDSA */
&s2n_ecdsa_sha256,
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
/* RSA PSS */
&s2n_rsa_pss_pss_sha256,
&s2n_rsa_pss_pss_sha384,
&s2n_rsa_pss_pss_sha512,
&s2n_rsa_pss_rsae_sha256,
&s2n_rsa_pss_rsae_sha384,
&s2n_rsa_pss_rsae_sha512,
/* RSA PKCS1 */
&s2n_rsa_pkcs1_sha256,
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
&s2n_rsa_pkcs1_sha224,
/* SHA-1 Legacy */
&s2n_ecdsa_sha1,
&s2n_rsa_pkcs1_sha1,
};
const struct s2n_signature_preferences s2n_signature_preferences_20240521 = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_20240521),
.signature_schemes = s2n_sig_scheme_pref_list_20240521
};
const struct s2n_signature_scheme* const s2n_sig_scheme_pref_list_test_all_fips[] = {
/* RSA PSS */
&s2n_rsa_pss_pss_sha256,
&s2n_rsa_pss_pss_sha384,
&s2n_rsa_pss_pss_sha512,
&s2n_rsa_pss_rsae_sha256,
&s2n_rsa_pss_rsae_sha384,
&s2n_rsa_pss_rsae_sha512,
/* RSA PKCS1 */
&s2n_rsa_pkcs1_sha256,
&s2n_rsa_pkcs1_sha384,
&s2n_rsa_pkcs1_sha512,
&s2n_rsa_pkcs1_sha224,
/* ECDSA */
&s2n_ecdsa_sha256,
&s2n_ecdsa_sha384,
&s2n_ecdsa_sha512,
&s2n_ecdsa_sha224,
};
const struct s2n_signature_preferences s2n_signature_preferences_test_all_fips = {
.count = s2n_array_len(s2n_sig_scheme_pref_list_test_all_fips),
.signature_schemes = s2n_sig_scheme_pref_list_test_all_fips,
};