aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/s2n/crypto
diff options
context:
space:
mode:
authorrobot-contrib <robot-contrib@yandex-team.com>2023-10-23 21:53:30 +0300
committerrobot-contrib <robot-contrib@yandex-team.com>2023-10-23 22:17:19 +0300
commit185aad3f5de6274260a161e58d92312d91813770 (patch)
tree39b2a93a9a649bffaaea9e405b00ceeea0d13c11 /contrib/restricted/aws/s2n/crypto
parenta14514f8c6ab647d334ae41253e65f69ee9b5fa6 (diff)
downloadydb-185aad3f5de6274260a161e58d92312d91813770.tar.gz
Update contrib/restricted/aws/s2n to 1.3.54
Diffstat (limited to 'contrib/restricted/aws/s2n/crypto')
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c72
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_cipher.h4
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_dhe.c25
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c5
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_hkdf.c214
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_hkdf.h12
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_hmac.c31
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_hmac.h2
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_ktls_crypto.h63
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c11
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_libcrypto.h2
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.c25
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h5
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa.c5
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c72
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c7
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h2
17 files changed, 456 insertions, 101 deletions
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c b/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c
index 5fb83b3df7..0d7a8f2d84 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c
@@ -17,6 +17,7 @@
#include <openssl/evp.h>
#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_ktls_crypto.h"
#include "tls/s2n_crypto.h"
#include "utils/s2n_blob.h"
#include "utils/s2n_safety.h"
@@ -376,6 +377,74 @@ static int s2n_aead_cipher_aes_gcm_destroy_key(struct s2n_session_key *key)
#endif
+static S2N_RESULT s2n_aead_cipher_aes128_gcm_set_ktls_info(struct s2n_ktls_crypto_info_inputs *in,
+ struct s2n_ktls_crypto_info *out)
+{
+ RESULT_ENSURE_REF(in);
+ RESULT_ENSURE_REF(out);
+
+ s2n_ktls_crypto_info_tls12_aes_gcm_128 *crypto_info = &out->ciphers.aes_gcm_128;
+ crypto_info->info.version = TLS_1_2_VERSION;
+ crypto_info->info.cipher_type = TLS_CIPHER_AES_GCM_128;
+
+ RESULT_ENSURE_LTE(sizeof(crypto_info->key), in->key.size);
+ RESULT_CHECKED_MEMCPY(crypto_info->key, in->key.data, sizeof(crypto_info->key));
+
+ RESULT_ENSURE_LTE(sizeof(crypto_info->iv), in->iv.size);
+ RESULT_CHECKED_MEMCPY(crypto_info->iv, in->iv.data, sizeof(crypto_info->iv));
+
+ RESULT_ENSURE_LTE(sizeof(crypto_info->rec_seq), in->seq.size);
+ RESULT_CHECKED_MEMCPY(crypto_info->rec_seq, in->seq.data, sizeof(crypto_info->rec_seq));
+
+ /* The salt is a prefix of the IV
+ *
+ *= https://www.rfc-editor.org/rfc/rfc4106#section-4
+ *# The salt field is a four-octet value that is assigned at the
+ *# beginning of the security association, and then remains constant
+ *# for the life of the security association.
+ */
+ RESULT_ENSURE_LTE(sizeof(crypto_info->salt), in->iv.size);
+ RESULT_CHECKED_MEMCPY(crypto_info->salt, in->iv.data, sizeof(crypto_info->salt));
+
+ RESULT_GUARD_POSIX(s2n_blob_init(&out->value, (uint8_t *) (void *) crypto_info,
+ sizeof(s2n_ktls_crypto_info_tls12_aes_gcm_128)));
+ return S2N_RESULT_OK;
+}
+
+static S2N_RESULT s2n_aead_cipher_aes256_gcm_set_ktls_info(
+ struct s2n_ktls_crypto_info_inputs *in, struct s2n_ktls_crypto_info *out)
+{
+ RESULT_ENSURE_REF(in);
+ RESULT_ENSURE_REF(out);
+
+ s2n_ktls_crypto_info_tls12_aes_gcm_256 *crypto_info = &out->ciphers.aes_gcm_256;
+ crypto_info->info.version = TLS_1_2_VERSION;
+ crypto_info->info.cipher_type = TLS_CIPHER_AES_GCM_256;
+
+ RESULT_ENSURE_LTE(sizeof(crypto_info->key), in->key.size);
+ RESULT_CHECKED_MEMCPY(crypto_info->key, in->key.data, sizeof(crypto_info->key));
+
+ RESULT_ENSURE_LTE(sizeof(crypto_info->iv), in->iv.size);
+ RESULT_CHECKED_MEMCPY(crypto_info->iv, in->iv.data, sizeof(crypto_info->iv));
+
+ RESULT_ENSURE_LTE(sizeof(crypto_info->rec_seq), in->seq.size);
+ RESULT_CHECKED_MEMCPY(crypto_info->rec_seq, in->seq.data, sizeof(crypto_info->rec_seq));
+
+ /* The salt is a prefix of the IV
+ *
+ *= https://www.rfc-editor.org/rfc/rfc4106#section-4
+ *# The salt field is a four-octet value that is assigned at the
+ *# beginning of the security association, and then remains constant
+ *# for the life of the security association.
+ */
+ RESULT_ENSURE_LTE(sizeof(crypto_info->salt), in->iv.size);
+ RESULT_CHECKED_MEMCPY(crypto_info->salt, in->iv.data, sizeof(crypto_info->salt));
+
+ RESULT_GUARD_POSIX(s2n_blob_init(&out->value, (uint8_t *) (void *) crypto_info,
+ sizeof(s2n_ktls_crypto_info_tls12_aes_gcm_256)));
+ return S2N_RESULT_OK;
+}
+
const struct s2n_cipher s2n_aes128_gcm = {
.key_material_size = S2N_TLS_AES_128_GCM_KEY_LEN,
.type = S2N_AEAD,
@@ -390,7 +459,7 @@ const struct s2n_cipher s2n_aes128_gcm = {
.set_encryption_key = s2n_aead_cipher_aes128_gcm_set_encryption_key,
.set_decryption_key = s2n_aead_cipher_aes128_gcm_set_decryption_key,
.destroy_key = s2n_aead_cipher_aes_gcm_destroy_key,
- .ktls_supported = true,
+ .set_ktls_info = s2n_aead_cipher_aes128_gcm_set_ktls_info,
};
const struct s2n_cipher s2n_aes256_gcm = {
@@ -407,6 +476,7 @@ const struct s2n_cipher s2n_aes256_gcm = {
.set_encryption_key = s2n_aead_cipher_aes256_gcm_set_encryption_key,
.set_decryption_key = s2n_aead_cipher_aes256_gcm_set_decryption_key,
.destroy_key = s2n_aead_cipher_aes_gcm_destroy_key,
+ .set_ktls_info = s2n_aead_cipher_aes256_gcm_set_ktls_info,
};
/* TLS 1.3 GCM ciphers */
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_cipher.h b/contrib/restricted/aws/s2n/crypto/s2n_cipher.h
index 18ac7cdccf..47c724ea63 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_cipher.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_cipher.h
@@ -23,6 +23,7 @@
#include <openssl/rsa.h>
#include "crypto/s2n_crypto.h"
+#include "crypto/s2n_ktls_crypto.h"
#include "utils/s2n_blob.h"
#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
@@ -81,12 +82,13 @@ struct s2n_cipher {
struct s2n_composite_cipher comp;
} io;
uint8_t key_material_size;
- bool ktls_supported;
uint8_t (*is_available)(void);
int (*init)(struct s2n_session_key *key);
int (*set_decryption_key)(struct s2n_session_key *key, struct s2n_blob *in);
int (*set_encryption_key)(struct s2n_session_key *key, struct s2n_blob *in);
int (*destroy_key)(struct s2n_session_key *key);
+ S2N_RESULT (*set_ktls_info)(struct s2n_ktls_crypto_info_inputs *inputs,
+ struct s2n_ktls_crypto_info *crypto_info);
};
int s2n_session_key_alloc(struct s2n_session_key *key);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_dhe.c b/contrib/restricted/aws/s2n/crypto/s2n_dhe.c
index aa5b629c09..da8f845e3b 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_dhe.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_dhe.c
@@ -138,24 +138,29 @@ int s2n_pkcs3_to_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *pkc
{
POSIX_ENSURE_REF(dh_params);
POSIX_PRECONDITION(s2n_blob_validate(pkcs3));
+ DEFER_CLEANUP(struct s2n_dh_params temp_dh_params = { 0 }, s2n_dh_params_free);
uint8_t *original_ptr = pkcs3->data;
- dh_params->dh = d2i_DHparams(NULL, (const unsigned char **) (void *) &pkcs3->data, pkcs3->size);
- POSIX_GUARD(s2n_check_p_g_dh_params(dh_params));
- if (pkcs3->data && (pkcs3->data - original_ptr != pkcs3->size)) {
- DH_free(dh_params->dh);
- POSIX_BAIL(S2N_ERR_INVALID_PKCS3);
+ temp_dh_params.dh = d2i_DHparams(NULL, (const unsigned char **) (void *) &pkcs3->data, pkcs3->size);
+
+ POSIX_GUARD(s2n_check_p_g_dh_params(&temp_dh_params));
+
+ if (pkcs3->data) {
+ POSIX_ENSURE_GTE(pkcs3->data, original_ptr);
+ POSIX_ENSURE((uint32_t) (pkcs3->data - original_ptr) == pkcs3->size, S2N_ERR_INVALID_PKCS3);
}
+
pkcs3->data = original_ptr;
/* Require at least 2048 bits for the DH size */
- if (DH_size(dh_params->dh) < S2N_MIN_DH_PRIME_SIZE_BYTES) {
- DH_free(dh_params->dh);
- POSIX_BAIL(S2N_ERR_DH_TOO_SMALL);
- }
+ POSIX_ENSURE(DH_size(temp_dh_params.dh) >= S2N_MIN_DH_PRIME_SIZE_BYTES, S2N_ERR_DH_TOO_SMALL);
/* Check the generator and prime */
- POSIX_GUARD(s2n_dh_params_check(dh_params));
+ POSIX_GUARD(s2n_dh_params_check(&temp_dh_params));
+
+ dh_params->dh = temp_dh_params.dh;
+
+ ZERO_TO_DISABLE_DEFER_CLEANUP(temp_dh_params);
return S2N_SUCCESS;
}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c
index e4da43f7f0..2761f93327 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c
@@ -40,13 +40,12 @@ EC_KEY *s2n_unsafe_ecdsa_get_non_const(const struct s2n_ecdsa_key *ecdsa_key)
{
PTR_ENSURE_REF(ecdsa_key);
- /* pragma gcc diagnostic was added in gcc 4.6 */
-#if defined(__clang__) || S2N_GCC_VERSION_AT_LEAST(4, 6, 0)
+#ifdef S2N_DIAGNOSTICS_PUSH_SUPPORTED
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
EC_KEY *out_ec_key = (EC_KEY *) ecdsa_key->ec_key;
-#if defined(__clang__) || S2N_GCC_VERSION_AT_LEAST(4, 6, 0)
+#ifdef S2N_DIAGNOSTICS_POP_SUPPORTED
#pragma GCC diagnostic pop
#endif
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c b/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c
index dd666ae653..da5a16ad3f 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c
@@ -13,8 +13,9 @@
* permissions and limitations under the License.
*/
-#include <stdio.h>
+#include "crypto/s2n_hkdf.h"
+#include "crypto/s2n_fips.h"
#include "crypto/s2n_hmac.h"
#include "error/s2n_errno.h"
#include "stuffer/s2n_stuffer.h"
@@ -22,28 +23,43 @@
#include "utils/s2n_mem.h"
#include "utils/s2n_safety.h"
+#ifdef S2N_LIBCRYPTO_SUPPORTS_HKDF
+ #error #include <openssl/hkdf.h>
+#endif
+
#define MAX_DIGEST_SIZE 64 /* Current highest is SHA512 */
#define MAX_HKDF_ROUNDS 255
/* Reference: RFC 5869 */
-int s2n_hkdf_extract(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
+struct s2n_hkdf_impl {
+ int (*hkdf)(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
+ const struct s2n_blob *key, const struct s2n_blob *info, struct s2n_blob *output);
+ int (*hkdf_extract)(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
+ const struct s2n_blob *key, struct s2n_blob *pseudo_rand_key);
+ int (*hkdf_expand)(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *pseudo_rand_key,
+ const struct s2n_blob *info, struct s2n_blob *output);
+};
+
+static int s2n_custom_hkdf_extract(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
const struct s2n_blob *key, struct s2n_blob *pseudo_rand_key)
{
- uint8_t hmac_size;
+ uint8_t hmac_size = 0;
POSIX_GUARD(s2n_hmac_digest_size(alg, &hmac_size));
+ POSIX_ENSURE(hmac_size <= pseudo_rand_key->size, S2N_ERR_HKDF_OUTPUT_SIZE);
pseudo_rand_key->size = hmac_size;
+
POSIX_GUARD(s2n_hmac_init(hmac, alg, salt->data, salt->size));
POSIX_GUARD(s2n_hmac_update(hmac, key->data, key->size));
POSIX_GUARD(s2n_hmac_digest(hmac, pseudo_rand_key->data, pseudo_rand_key->size));
POSIX_GUARD(s2n_hmac_reset(hmac));
- return 0;
+ return S2N_SUCCESS;
}
-static int s2n_hkdf_expand(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *pseudo_rand_key,
- const struct s2n_blob *info, struct s2n_blob *output)
+static int s2n_custom_hkdf_expand(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg,
+ const struct s2n_blob *pseudo_rand_key, const struct s2n_blob *info, struct s2n_blob *output)
{
uint8_t prev[MAX_DIGEST_SIZE] = { 0 };
@@ -56,7 +72,8 @@ static int s2n_hkdf_expand(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg,
total_rounds++;
}
- S2N_ERROR_IF(total_rounds > MAX_HKDF_ROUNDS || total_rounds == 0, S2N_ERR_HKDF_OUTPUT_SIZE);
+ POSIX_ENSURE(total_rounds > 0, S2N_ERR_HKDF_OUTPUT_SIZE);
+ POSIX_ENSURE(total_rounds <= MAX_HKDF_ROUNDS, S2N_ERR_HKDF_OUTPUT_SIZE);
for (uint32_t curr_round = 1; curr_round <= total_rounds; curr_round++) {
uint32_t cat_len;
@@ -80,21 +97,167 @@ static int s2n_hkdf_expand(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg,
POSIX_GUARD(s2n_hmac_reset(hmac));
}
- return 0;
+ return S2N_SUCCESS;
+}
+
+static int s2n_custom_hkdf(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
+ const struct s2n_blob *key, const struct s2n_blob *info, struct s2n_blob *output)
+{
+ uint8_t prk_pad[MAX_DIGEST_SIZE] = { 0 };
+ struct s2n_blob pseudo_rand_key = { 0 };
+ POSIX_GUARD(s2n_blob_init(&pseudo_rand_key, prk_pad, sizeof(prk_pad)));
+
+ POSIX_GUARD(s2n_custom_hkdf_extract(hmac, alg, salt, key, &pseudo_rand_key));
+ POSIX_GUARD(s2n_custom_hkdf_expand(hmac, alg, &pseudo_rand_key, info, output));
+
+ return S2N_SUCCESS;
+}
+
+const struct s2n_hkdf_impl s2n_custom_hkdf_impl = {
+ .hkdf = &s2n_custom_hkdf,
+ .hkdf_extract = &s2n_custom_hkdf_extract,
+ .hkdf_expand = &s2n_custom_hkdf_expand,
+};
+
+#ifdef S2N_LIBCRYPTO_SUPPORTS_HKDF
+static int s2n_libcrypto_hkdf_extract(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
+ const struct s2n_blob *key, struct s2n_blob *pseudo_rand_key)
+{
+ const EVP_MD *digest = NULL;
+ POSIX_GUARD_RESULT(s2n_hmac_md_from_alg(alg, &digest));
+
+ /* The out_len argument of HKDF_extract is set to the number of bytes written to out_key, and
+ * is not used to ensure that out_key is large enough to contain the PRK. Ensure that the PRK
+ * output will fit in the blob.
+ */
+ uint8_t hmac_size = 0;
+ POSIX_GUARD(s2n_hmac_digest_size(alg, &hmac_size));
+ POSIX_ENSURE(hmac_size <= pseudo_rand_key->size, S2N_ERR_HKDF_OUTPUT_SIZE);
+
+ size_t bytes_written = 0;
+ POSIX_GUARD_OSSL(HKDF_extract(pseudo_rand_key->data, &bytes_written, digest, key->data, key->size,
+ salt->data, salt->size),
+ S2N_ERR_HKDF);
+
+ /* HKDF_extract updates the out_len argument based on the digest size. Update the blob's size based on this. */
+ POSIX_ENSURE_LTE(bytes_written, pseudo_rand_key->size);
+ pseudo_rand_key->size = bytes_written;
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_libcrypto_hkdf_expand(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg,
+ const struct s2n_blob *pseudo_rand_key, const struct s2n_blob *info, struct s2n_blob *output)
+{
+ POSIX_ENSURE(output->size > 0, S2N_ERR_HKDF_OUTPUT_SIZE);
+
+ const EVP_MD *digest = NULL;
+ POSIX_GUARD_RESULT(s2n_hmac_md_from_alg(alg, &digest));
+
+ POSIX_GUARD_OSSL(HKDF_expand(output->data, output->size, digest, pseudo_rand_key->data, pseudo_rand_key->size,
+ info->data, info->size),
+ S2N_ERR_HKDF);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_libcrypto_hkdf(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
+ const struct s2n_blob *key, const struct s2n_blob *info, struct s2n_blob *output)
+{
+ POSIX_ENSURE(output->size > 0, S2N_ERR_HKDF_OUTPUT_SIZE);
+
+ const EVP_MD *digest = NULL;
+ POSIX_GUARD_RESULT(s2n_hmac_md_from_alg(alg, &digest));
+
+ POSIX_GUARD_OSSL(HKDF(output->data, output->size, digest, key->data, key->size, salt->data, salt->size,
+ info->data, info->size),
+ S2N_ERR_HKDF);
+
+ return S2N_SUCCESS;
+}
+#else
+static int s2n_libcrypto_hkdf_extract(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
+ const struct s2n_blob *key, struct s2n_blob *pseudo_rand_key)
+{
+ POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
+}
+
+static int s2n_libcrypto_hkdf_expand(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg,
+ const struct s2n_blob *pseudo_rand_key, const struct s2n_blob *info, struct s2n_blob *output)
+{
+ POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
+}
+
+static int s2n_libcrypto_hkdf(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
+ const struct s2n_blob *key, const struct s2n_blob *info, struct s2n_blob *output)
+{
+ POSIX_BAIL(S2N_ERR_UNIMPLEMENTED);
+}
+#endif /* S2N_LIBCRYPTO_SUPPORTS_HKDF */
+
+const struct s2n_hkdf_impl s2n_libcrypto_hkdf_impl = {
+ .hkdf = &s2n_libcrypto_hkdf,
+ .hkdf_extract = &s2n_libcrypto_hkdf_extract,
+ .hkdf_expand = &s2n_libcrypto_hkdf_expand,
+};
+
+static const struct s2n_hkdf_impl *s2n_get_hkdf_implementation()
+{
+ /* By default, s2n-tls uses a custom HKDF implementation. When operating in FIPS mode, the
+ * FIPS-validated libcrypto implementation is used instead, if an implementation is provided.
+ */
+ if (s2n_is_in_fips_mode() && s2n_libcrypto_supports_hkdf()) {
+ return &s2n_libcrypto_hkdf_impl;
+ }
+
+ return &s2n_custom_hkdf_impl;
+}
+
+int s2n_hkdf_extract(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
+ const struct s2n_blob *key, struct s2n_blob *pseudo_rand_key)
+{
+ POSIX_ENSURE_REF(hmac);
+ POSIX_ENSURE_REF(salt);
+ POSIX_ENSURE_REF(key);
+ POSIX_ENSURE_REF(pseudo_rand_key);
+
+ const struct s2n_hkdf_impl *hkdf_implementation = s2n_get_hkdf_implementation();
+ POSIX_ENSURE_REF(hkdf_implementation);
+
+ POSIX_GUARD(hkdf_implementation->hkdf_extract(hmac, alg, salt, key, pseudo_rand_key));
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_hkdf_expand(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *pseudo_rand_key,
+ const struct s2n_blob *info, struct s2n_blob *output)
+{
+ POSIX_ENSURE_REF(hmac);
+ POSIX_ENSURE_REF(pseudo_rand_key);
+ POSIX_ENSURE_REF(info);
+ POSIX_ENSURE_REF(output);
+
+ const struct s2n_hkdf_impl *hkdf_implementation = s2n_get_hkdf_implementation();
+ POSIX_ENSURE_REF(hkdf_implementation);
+
+ POSIX_GUARD(hkdf_implementation->hkdf_expand(hmac, alg, pseudo_rand_key, info, output));
+
+ return S2N_SUCCESS;
}
int s2n_hkdf_expand_label(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *secret, const struct s2n_blob *label,
const struct s2n_blob *context, struct s2n_blob *output)
{
+ POSIX_ENSURE_REF(label);
+ POSIX_ENSURE_REF(context);
+ POSIX_ENSURE_REF(output);
+
/* Per RFC8446: 7.1, a HKDF label is a 2 byte length field, and two 1...255 byte arrays with a one byte length field each. */
uint8_t hkdf_label_buf[2 + 256 + 256];
struct s2n_blob hkdf_label_blob = { 0 };
struct s2n_stuffer hkdf_label = { 0 };
- /* RFC8446 specifies that labels must be 12 characters or less, to avoid
- ** incurring two hash rounds.
- */
- POSIX_ENSURE_LTE(label->size, 12);
+ POSIX_ENSURE_LTE(label->size, S2N_MAX_HKDF_EXPAND_LABEL_LENGTH);
POSIX_GUARD(s2n_blob_init(&hkdf_label_blob, hkdf_label_buf, sizeof(hkdf_label_buf)));
POSIX_GUARD(s2n_stuffer_init(&hkdf_label, &hkdf_label_blob));
@@ -108,18 +271,31 @@ int s2n_hkdf_expand_label(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, c
hkdf_label_blob.size = s2n_stuffer_data_available(&hkdf_label);
POSIX_GUARD(s2n_hkdf_expand(hmac, alg, secret, &hkdf_label_blob, output));
- return 0;
+ return S2N_SUCCESS;
}
int s2n_hkdf(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
const struct s2n_blob *key, const struct s2n_blob *info, struct s2n_blob *output)
{
- uint8_t prk_pad[MAX_DIGEST_SIZE];
- struct s2n_blob pseudo_rand_key = { 0 };
- POSIX_GUARD(s2n_blob_init(&pseudo_rand_key, prk_pad, sizeof(prk_pad)));
+ POSIX_ENSURE_REF(hmac);
+ POSIX_ENSURE_REF(salt);
+ POSIX_ENSURE_REF(key);
+ POSIX_ENSURE_REF(info);
+ POSIX_ENSURE_REF(output);
- POSIX_GUARD(s2n_hkdf_extract(hmac, alg, salt, key, &pseudo_rand_key));
- POSIX_GUARD(s2n_hkdf_expand(hmac, alg, &pseudo_rand_key, info, output));
+ const struct s2n_hkdf_impl *hkdf_implementation = s2n_get_hkdf_implementation();
+ POSIX_ENSURE_REF(hkdf_implementation);
- return 0;
+ POSIX_GUARD(hkdf_implementation->hkdf(hmac, alg, salt, key, info, output));
+
+ return S2N_SUCCESS;
+}
+
+bool s2n_libcrypto_supports_hkdf()
+{
+#ifdef S2N_LIBCRYPTO_SUPPORTS_HKDF
+ return true;
+#else
+ return false;
+#endif
}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hkdf.h b/contrib/restricted/aws/s2n/crypto/s2n_hkdf.h
index cb9424e7d7..8dc53636e7 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_hkdf.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_hkdf.h
@@ -20,6 +20,16 @@
#include "crypto/s2n_hmac.h"
#include "utils/s2n_blob.h"
+/*
+ * Label structure is `opaque label<7..255> = "tls13 " + Label` per RFC8446.
+ * So, we have 255-sizeof("tls13 ") = 249, the maximum label length.
+ *
+ * Note that all labels defined by RFC 8446 are <12 characters, which
+ * avoids an extra hash iteration. However, the exporter functionality
+ * (s2n_connection_tls_exporter) allows for longer labels.
+ */
+#define S2N_MAX_HKDF_EXPAND_LABEL_LENGTH 249
+
int s2n_hkdf(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *salt,
const struct s2n_blob *key, const struct s2n_blob *info, struct s2n_blob *output);
@@ -28,3 +38,5 @@ int s2n_hkdf_extract(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const
int s2n_hkdf_expand_label(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s2n_blob *secret, const struct s2n_blob *label,
const struct s2n_blob *context, struct s2n_blob *output);
+
+bool s2n_libcrypto_supports_hkdf();
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hmac.c b/contrib/restricted/aws/s2n/crypto/s2n_hmac.c
index d2bb4e6684..20be85ffee 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_hmac.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_hmac.c
@@ -396,3 +396,34 @@ int s2n_hmac_restore_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s
POSIX_POSTCONDITION(s2n_hmac_state_validate(hmac));
return S2N_SUCCESS;
}
+
+S2N_RESULT s2n_hmac_md_from_alg(s2n_hmac_algorithm alg, const EVP_MD **md)
+{
+ RESULT_ENSURE_REF(md);
+
+ switch (alg) {
+ case S2N_HMAC_SSLv3_MD5:
+ case S2N_HMAC_MD5:
+ *md = EVP_md5();
+ break;
+ case S2N_HMAC_SSLv3_SHA1:
+ case S2N_HMAC_SHA1:
+ *md = EVP_sha1();
+ break;
+ case S2N_HMAC_SHA224:
+ *md = EVP_sha224();
+ break;
+ case S2N_HMAC_SHA256:
+ *md = EVP_sha256();
+ break;
+ case S2N_HMAC_SHA384:
+ *md = EVP_sha384();
+ break;
+ case S2N_HMAC_SHA512:
+ *md = EVP_sha512();
+ break;
+ default:
+ RESULT_BAIL(S2N_ERR_P_HASH_INVALID_ALGORITHM);
+ }
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hmac.h b/contrib/restricted/aws/s2n/crypto/s2n_hmac.h
index fe532ca5c8..81b96c06ea 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_hmac.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_hmac.h
@@ -77,3 +77,5 @@ int s2n_hmac_reset(struct s2n_hmac_state *state);
int s2n_hmac_copy(struct s2n_hmac_state *to, struct s2n_hmac_state *from);
int s2n_hmac_save_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac);
int s2n_hmac_restore_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac);
+
+S2N_RESULT s2n_hmac_md_from_alg(s2n_hmac_algorithm alg, const EVP_MD **md);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_ktls_crypto.h b/contrib/restricted/aws/s2n/crypto/s2n_ktls_crypto.h
new file mode 100644
index 0000000000..b665e913fe
--- /dev/null
+++ b/contrib/restricted/aws/s2n/crypto/s2n_ktls_crypto.h
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include "utils/s2n_blob.h"
+
+/* clang-format off */
+#if defined(S2N_KTLS_SUPPORTED)
+ #include <linux/tls.h>
+
+ typedef struct tls12_crypto_info_aes_gcm_128 s2n_ktls_crypto_info_tls12_aes_gcm_128;
+ typedef struct tls12_crypto_info_aes_gcm_256 s2n_ktls_crypto_info_tls12_aes_gcm_256;
+#else
+ #define TLS_1_2_VERSION 0
+
+ #define TLS_CIPHER_AES_GCM_128 0
+ typedef struct s2n_ktls_crypto_info_stub s2n_ktls_crypto_info_tls12_aes_gcm_128;
+ #define TLS_CIPHER_AES_GCM_256 0
+ typedef struct s2n_ktls_crypto_info_stub s2n_ktls_crypto_info_tls12_aes_gcm_256;
+#endif
+/* clang-format on */
+
+/* To avoid compile-time errors, this must contain every field that we reference
+ * from any crypto_info. However, it is only a placeholder-- it should never
+ * actually be used.
+ */
+struct s2n_ktls_crypto_info_stub {
+ struct {
+ uint8_t version;
+ uint8_t cipher_type;
+ } info;
+ uint8_t iv[1];
+ uint8_t key[1];
+ uint8_t salt[1];
+ uint8_t rec_seq[1];
+};
+
+struct s2n_ktls_crypto_info {
+ struct s2n_blob value;
+ union {
+ s2n_ktls_crypto_info_tls12_aes_gcm_128 aes_gcm_128;
+ s2n_ktls_crypto_info_tls12_aes_gcm_256 aes_gcm_256;
+ } ciphers;
+};
+
+struct s2n_ktls_crypto_info_inputs {
+ struct s2n_blob iv;
+ struct s2n_blob key;
+ struct s2n_blob seq;
+};
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c
index d92da10a08..9e40500da6 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c
@@ -118,7 +118,7 @@ bool s2n_libcrypto_is_awslc()
#endif
}
-static uint64_t s2n_libcrypto_awslc_api_version(void)
+uint64_t s2n_libcrypto_awslc_api_version(void)
{
#if defined(OPENSSL_IS_AWSLC)
return AWSLC_API_VERSION;
@@ -191,3 +191,12 @@ unsigned long s2n_get_openssl_version(void)
{
return OPENSSL_VERSION_NUMBER;
}
+
+bool s2n_libcrypto_supports_flag_no_check_time()
+{
+#ifdef S2N_LIBCRYPTO_SUPPORTS_FLAG_NO_CHECK_TIME
+ return true;
+#else
+ return false;
+#endif
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.h b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.h
index 34d9ef2aac..9e7aff882b 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.h
@@ -18,3 +18,5 @@
#include "utils/s2n_result.h"
S2N_RESULT s2n_libcrypto_validate_runtime(void);
+
+bool s2n_libcrypto_supports_flag_no_check_time();
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.c b/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.c
index f0909fd897..bc659e28a8 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.c
@@ -17,10 +17,25 @@
#include "api/s2n.h"
-int s2n_openssl_x509_stack_pop_free(STACK_OF(X509) **cert_chain)
+S2N_CLEANUP_RESULT s2n_openssl_x509_stack_pop_free(STACK_OF(X509) **cert_chain)
{
- if (*cert_chain != NULL) {
- sk_X509_pop_free(*cert_chain, X509_free);
- }
- return S2N_SUCCESS;
+ RESULT_ENSURE_REF(*cert_chain);
+ sk_X509_pop_free(*cert_chain, X509_free);
+ *cert_chain = NULL;
+ return S2N_RESULT_OK;
+}
+
+S2N_CLEANUP_RESULT s2n_openssl_asn1_time_free_pointer(ASN1_GENERALIZEDTIME **time_ptr)
+{
+ /* The ANS1_*TIME structs are just typedef wrappers around ASN1_STRING
+ *
+ * The ASN1_TIME, ASN1_UTCTIME and ASN1_GENERALIZEDTIME structures are
+ * represented as an ASN1_STRING internally and can be freed up using
+ * ASN1_STRING_free().
+ * https://www.openssl.org/docs/man1.1.1/man3/ASN1_TIME_to_tm.html
+ */
+ RESULT_ENSURE_REF(*time_ptr);
+ ASN1_STRING_free((ASN1_STRING *) *time_ptr);
+ *time_ptr = NULL;
+ return S2N_RESULT_OK;
}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h b/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h
index 1eb2069054..aac6d87315 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h
@@ -15,6 +15,7 @@
#pragma once
+#include <openssl/asn1.h>
#include <openssl/x509.h>
#include <stdint.h>
@@ -22,4 +23,6 @@
DEFINE_POINTER_CLEANUP_FUNC(X509 *, X509_free);
-int s2n_openssl_x509_stack_pop_free(STACK_OF(X509) **cert_chain);
+S2N_CLEANUP_RESULT s2n_openssl_x509_stack_pop_free(STACK_OF(X509) **cert_chain);
+
+S2N_CLEANUP_RESULT s2n_openssl_asn1_time_free_pointer(ASN1_GENERALIZEDTIME **time);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa.c
index 9fc1d4b5ca..96ce8f4140 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa.c
@@ -36,13 +36,12 @@ RSA *s2n_unsafe_rsa_get_non_const(const struct s2n_rsa_key *rsa_key)
{
PTR_ENSURE_REF(rsa_key);
- /* pragma gcc diagnostic was added in gcc 4.6 */
-#if defined(__clang__) || S2N_GCC_VERSION_AT_LEAST(4, 6, 0)
+#ifdef S2N_DIAGNOSTICS_PUSH_SUPPORTED
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
#endif
RSA *out_rsa_key = (RSA *) rsa_key->rsa;
-#if defined(__clang__) || S2N_GCC_VERSION_AT_LEAST(4, 6, 0)
+#ifdef S2N_DIAGNOSTICS_POP_SUPPORTED
#pragma GCC diagnostic pop
#endif
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c
index 4c4bc14914..30be7e6a43 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c
@@ -21,60 +21,28 @@
#include "utils/s2n_blob.h"
#include "utils/s2n_safety.h"
-#if S2N_OPENSSL_VERSION_AT_LEAST(3, 0, 0)
- #error #include "openssl/provider.h"
-DEFINE_POINTER_CLEANUP_FUNC(OSSL_LIB_CTX *, OSSL_LIB_CTX_free);
-#endif
-
-static EVP_CIPHER *s2n_rc4_cipher = NULL;
-
-S2N_RESULT s2n_rc4_init()
-{
- /* In Openssl-3.0, RC4 is only available from the "legacy" provider,
- * which is not loaded in the default library context.
- */
-#if defined(S2N_LIBCRYPTO_SUPPORTS_EVP_RC4) && S2N_OPENSSL_VERSION_AT_LEAST(3, 0, 0)
- DEFER_CLEANUP(OSSL_LIB_CTX *lib_ctx = OSSL_LIB_CTX_new(), OSSL_LIB_CTX_free_pointer);
- RESULT_ENSURE_REF(lib_ctx);
- RESULT_ENSURE_REF(OSSL_PROVIDER_load(lib_ctx, "legacy"));
- s2n_rc4_cipher = EVP_CIPHER_fetch(lib_ctx, "rc4", "provider=legacy");
- RESULT_ENSURE_REF(s2n_rc4_cipher);
-#endif
- return S2N_RESULT_OK;
-}
-
-S2N_RESULT s2n_rc4_cleanup()
+static const EVP_CIPHER *s2n_evp_rc4()
{
-#if S2N_OPENSSL_VERSION_AT_LEAST(3, 0, 0)
- EVP_CIPHER_free(s2n_rc4_cipher);
+#ifdef S2N_LIBCRYPTO_SUPPORTS_EVP_RC4
+ return EVP_rc4();
+#else
+ return NULL;
#endif
- return S2N_RESULT_OK;
}
-static S2N_RESULT s2n_get_rc4_cipher(const EVP_CIPHER **cipher)
+static uint8_t s2n_stream_cipher_rc4_available()
{
- RESULT_ENSURE_REF(cipher);
- *cipher = NULL;
if (s2n_is_in_fips_mode()) {
- *cipher = NULL;
- } else if (s2n_rc4_cipher) {
- *cipher = s2n_rc4_cipher;
-#if S2N_LIBCRYPTO_SUPPORTS_EVP_RC4
- } else {
- *cipher = EVP_rc4();
-#endif
+ return 0;
}
- RESULT_ENSURE(*cipher, S2N_ERR_UNIMPLEMENTED);
- return S2N_RESULT_OK;
-}
-
-static uint8_t s2n_stream_cipher_rc4_available()
-{
- const EVP_CIPHER *cipher = NULL;
- if (s2n_result_is_ok(s2n_get_rc4_cipher(&cipher)) && cipher) {
- return 1;
+ /* RC4 MIGHT be available in Openssl-3.0, depending on whether or not the
+ * "legacy" provider is loaded. However, for simplicity, assume that RC4
+ * is unavailable.
+ */
+ if (S2N_OPENSSL_VERSION_AT_LEAST(3, 0, 0)) {
+ return 0;
}
- return 0;
+ return (s2n_evp_rc4() ? 1 : 0);
}
static int s2n_stream_cipher_rc4_encrypt(struct s2n_session_key *key, struct s2n_blob *in, struct s2n_blob *out)
@@ -106,11 +74,7 @@ static int s2n_stream_cipher_rc4_decrypt(struct s2n_session_key *key, struct s2n
static int s2n_stream_cipher_rc4_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
{
POSIX_ENSURE_EQ(in->size, 16);
-
- const EVP_CIPHER *evp_rc4 = NULL;
- POSIX_GUARD_RESULT(s2n_get_rc4_cipher(&evp_rc4));
-
- POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, evp_rc4, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+ POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_rc4(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
return S2N_SUCCESS;
}
@@ -118,11 +82,7 @@ static int s2n_stream_cipher_rc4_set_encryption_key(struct s2n_session_key *key,
static int s2n_stream_cipher_rc4_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
{
POSIX_ENSURE_EQ(in->size, 16);
-
- const EVP_CIPHER *evp_rc4 = NULL;
- POSIX_GUARD_RESULT(s2n_get_rc4_cipher(&evp_rc4));
-
- POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, evp_rc4, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+ POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_rc4(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
return S2N_SUCCESS;
}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c
index 3b5c284080..91d7aae5e0 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c
@@ -37,7 +37,7 @@
* [x] server_handshake_traffic_secret
* [x] client_application_traffic_secret_0
* [x] server_application_traffic_secret_0
- * [ ] exporter_master_secret
+ * [x] exporter_master_secret
* [x] resumption_master_secret
*
* The TLS 1.3 key generation can be divided into 3 phases
@@ -80,6 +80,11 @@ S2N_BLOB_LABEL(s2n_tls13_label_traffic_secret_key, "key")
S2N_BLOB_LABEL(s2n_tls13_label_traffic_secret_iv, "iv")
/*
+ * TLS 1.3 Exporter label
+ */
+S2N_BLOB_LABEL(s2n_tls13_label_exporter, "exporter")
+
+/*
* TLS 1.3 Finished label
*/
S2N_BLOB_LABEL(s2n_tls13_label_finished, "finished")
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h
index 5bd7455dc2..ac96ceb51f 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h
@@ -70,6 +70,8 @@ extern const struct s2n_blob s2n_tls13_label_resumption_master_secret;
extern const struct s2n_blob s2n_tls13_label_finished;
+extern const struct s2n_blob s2n_tls13_label_exporter;
+
/* Traffic secret labels */
extern const struct s2n_blob s2n_tls13_label_traffic_secret_key;