aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/restricted/aws/s2n/crypto
diff options
context:
space:
mode:
authororivej <orivej@yandex-team.ru>2022-02-10 16:44:49 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:49 +0300
commit718c552901d703c502ccbefdfc3c9028d608b947 (patch)
tree46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/restricted/aws/s2n/crypto
parente9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff)
downloadydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/restricted/aws/s2n/crypto')
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_aes_gcm.c728
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c550
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c206
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c286
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_certificate.c1068
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_certificate.h150
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_cipher.c112
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_cipher.h208
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_composite_cipher_aes_sha.c726
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_crypto.h44
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_dhe.c678
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_dhe.h72
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_drbg.c456
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_drbg.h132
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.c1002
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.h178
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c346
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h86
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_evp.c94
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_evp.h90
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_fips.c80
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_fips.h38
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_hash.c1294
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_hash.h208
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_hkdf.c252
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_hkdf.h62
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_hmac.c696
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_hmac.h158
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_openssl.h98
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_openssl_evp.h44
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h44
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_pkey.c470
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_pkey.h146
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa.c380
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa.h80
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c482
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.h90
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c412
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.h74
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_sequence.c116
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_sequence.h46
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_signature.h58
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_null.c128
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c188
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c676
-rw-r--r--contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h178
46 files changed, 6855 insertions, 6855 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 55418362d0..d5ee2063aa 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
@@ -1,364 +1,364 @@
-/*
- * 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 <openssl/aes.h>
-#include <openssl/evp.h>
-
-#include "crypto/s2n_cipher.h"
-
-#include "tls/s2n_crypto.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
-#define S2N_AEAD_AES_GCM_AVAILABLE
-#endif
-
-static uint8_t s2n_aead_cipher_aes128_gcm_available()
-{
-#if defined(S2N_AEAD_AES_GCM_AVAILABLE)
- return (EVP_aead_aes_128_gcm() ? 1 : 0);
-#else
- return (EVP_aes_128_gcm() ? 1 : 0);
-#endif
-}
-
-static uint8_t s2n_aead_cipher_aes256_gcm_available()
-{
-#if defined(S2N_AEAD_AES_GCM_AVAILABLE)
- return (EVP_aead_aes_256_gcm() ? 1 : 0);
-#else
- return (EVP_aes_256_gcm() ? 1 : 0);
-#endif
-}
-
-#if defined(S2N_AEAD_AES_GCM_AVAILABLE) /* BoringSSL and AWS-LC AEAD API implementation */
-
-static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
-{
- notnull_check(in);
- notnull_check(out);
- notnull_check(iv);
- notnull_check(key);
- notnull_check(aad);
-
- /* The size of the |in| blob includes the size of the data and the size of the AES-GCM tag */
- gte_check(in->size, S2N_TLS_GCM_TAG_LEN);
- gte_check(out->size, in->size);
- eq_check(iv->size, S2N_TLS_GCM_IV_LEN);
-
- /* Adjust input length to account for the Tag length */
- size_t in_len = in->size - S2N_TLS_GCM_TAG_LEN;
- size_t out_len = 0;
-
- GUARD_OSSL(EVP_AEAD_CTX_seal(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
-
- S2N_ERROR_IF((in_len + S2N_TLS_GCM_TAG_LEN) != out_len, S2N_ERR_ENCRYPT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
-{
- notnull_check(in);
- notnull_check(out);
- notnull_check(iv);
- notnull_check(key);
- notnull_check(aad);
-
- gte_check(in->size, S2N_TLS_GCM_TAG_LEN);
- gte_check(out->size, in->size - S2N_TLS_GCM_TAG_LEN);
- eq_check(iv->size, S2N_TLS_GCM_IV_LEN);
-
- size_t out_len = 0;
-
- GUARD_OSSL(EVP_AEAD_CTX_open(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in->size, aad->data, aad->size), S2N_ERR_DECRYPT);
-
- S2N_ERROR_IF((in->size - S2N_TLS_GCM_TAG_LEN) != out_len, S2N_ERR_ENCRYPT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes128_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- notnull_check(key);
- notnull_check(in);
-
- eq_check(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
-
- GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes256_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- notnull_check(key);
- notnull_check(in);
-
- eq_check(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
-
- GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes128_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- notnull_check(key);
- notnull_check(in);
-
- eq_check(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
-
- GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes256_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- notnull_check(key);
- notnull_check(in);
-
- eq_check(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
-
- GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes_gcm_init(struct s2n_session_key *key)
-{
- notnull_check(key);
-
- EVP_AEAD_CTX_zero(key->evp_aead_ctx);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes_gcm_destroy_key(struct s2n_session_key *key)
-{
- notnull_check(key);
-
- EVP_AEAD_CTX_cleanup(key->evp_aead_ctx);
-
- return S2N_SUCCESS;
-}
-
-#else /* Standard AES-GCM implementation */
-
-static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
-{
- /* The size of the |in| blob includes the size of the data and the size of the ChaCha20-Poly1305 tag */
- gte_check(in->size, S2N_TLS_GCM_TAG_LEN);
- gte_check(out->size, in->size);
- eq_check(iv->size, S2N_TLS_GCM_IV_LEN);
-
- /* Initialize the IV */
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
-
- /* Adjust input length and buffer pointer to account for the Tag length */
- int in_len = in->size - S2N_TLS_GCM_TAG_LEN;
- uint8_t *tag_data = out->data + out->size - S2N_TLS_GCM_TAG_LEN;
-
- int out_len;
- /* Specify the AAD */
- GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
-
- /* Encrypt the data */
- GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &out_len, in->data, in_len), S2N_ERR_ENCRYPT);
-
- /* When using AES-GCM, *out_len is the number of bytes written by EVP_EncryptUpdate. Since the tag is not written during this call, we do not take S2N_TLS_GCM_TAG_LEN into account */
- S2N_ERROR_IF(in_len != out_len, S2N_ERR_ENCRYPT);
-
- /* Finalize */
- GUARD_OSSL(EVP_EncryptFinal_ex(key->evp_cipher_ctx, out->data, &out_len), S2N_ERR_ENCRYPT);
-
- /* write the tag */
- GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_GET_TAG, S2N_TLS_GCM_TAG_LEN, tag_data), S2N_ERR_ENCRYPT);
-
- /* When using AES-GCM, EVP_EncryptFinal_ex does not write any bytes. So, we should expect *out_len = 0. */
- S2N_ERROR_IF(0 != out_len, S2N_ERR_ENCRYPT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(in->size, S2N_TLS_GCM_TAG_LEN);
- gte_check(out->size, in->size);
- eq_check(iv->size, S2N_TLS_GCM_IV_LEN);
-
- /* Initialize the IV */
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
-
- /* Adjust input length and buffer pointer to account for the Tag length */
- int in_len = in->size - S2N_TLS_GCM_TAG_LEN;
- uint8_t *tag_data = in->data + in->size - S2N_TLS_GCM_TAG_LEN;
-
- /* Set the TAG */
- GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_TAG, S2N_TLS_GCM_TAG_LEN, tag_data), S2N_ERR_DECRYPT);
-
- int out_len;
- /* Specify the AAD */
- GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_DECRYPT);
-
- int evp_decrypt_rc = 1;
- /* Decrypt the data, but don't short circuit tag verification. EVP_Decrypt* return 0 on failure, 1 for success. */
- evp_decrypt_rc &= EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &out_len, in->data, in_len);
-
- /* Verify the tag */
- evp_decrypt_rc &= EVP_DecryptFinal_ex(key->evp_cipher_ctx, out->data, &out_len);
-
- S2N_ERROR_IF(evp_decrypt_rc != 1, S2N_ERR_DECRYPT);
-
- /* While we verify the content of out_len in s2n_aead_cipher_aes_gcm_encrypt, we refrain from this here. This is to avoid doing any branching before the ciphertext is verified. */
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes128_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
-
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
-
- EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
-
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes256_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
-
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
-
- EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
-
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes128_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
-
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
-
- EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
-
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes256_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
-
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
-
- EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
-
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes_gcm_init(struct s2n_session_key *key)
-{
- s2n_evp_ctx_init(key->evp_cipher_ctx);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_aead_cipher_aes_gcm_destroy_key(struct s2n_session_key *key)
-{
- EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
-
- return S2N_SUCCESS;
-}
-
-#endif
-
-struct s2n_cipher s2n_aes128_gcm = {
- .key_material_size = S2N_TLS_AES_128_GCM_KEY_LEN,
- .type = S2N_AEAD,
- .io.aead = {
- .record_iv_size = S2N_TLS_GCM_EXPLICIT_IV_LEN,
- .fixed_iv_size = S2N_TLS_GCM_FIXED_IV_LEN,
- .tag_size = S2N_TLS_GCM_TAG_LEN,
- .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
- .encrypt = s2n_aead_cipher_aes_gcm_encrypt},
- .is_available = s2n_aead_cipher_aes128_gcm_available,
- .init = s2n_aead_cipher_aes_gcm_init,
- .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,
-};
-
-struct s2n_cipher s2n_aes256_gcm = {
- .key_material_size = S2N_TLS_AES_256_GCM_KEY_LEN,
- .type = S2N_AEAD,
- .io.aead = {
- .record_iv_size = S2N_TLS_GCM_EXPLICIT_IV_LEN,
- .fixed_iv_size = S2N_TLS_GCM_FIXED_IV_LEN,
- .tag_size = S2N_TLS_GCM_TAG_LEN,
- .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
- .encrypt = s2n_aead_cipher_aes_gcm_encrypt},
- .is_available = s2n_aead_cipher_aes256_gcm_available,
- .init = s2n_aead_cipher_aes_gcm_init,
- .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,
-};
-
-/* TLS 1.3 GCM ciphers */
-struct s2n_cipher s2n_tls13_aes128_gcm = {
- .key_material_size = S2N_TLS_AES_128_GCM_KEY_LEN,
- .type = S2N_AEAD,
- .io.aead = {
- .record_iv_size = S2N_TLS13_RECORD_IV_LEN,
- .fixed_iv_size = S2N_TLS13_FIXED_IV_LEN,
- .tag_size = S2N_TLS_GCM_TAG_LEN,
- .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
- .encrypt = s2n_aead_cipher_aes_gcm_encrypt},
- .is_available = s2n_aead_cipher_aes128_gcm_available,
- .init = s2n_aead_cipher_aes_gcm_init,
- .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,
-};
-
-struct s2n_cipher s2n_tls13_aes256_gcm = {
- .key_material_size = S2N_TLS_AES_256_GCM_KEY_LEN,
- .type = S2N_AEAD,
- .io.aead = {
- .record_iv_size = S2N_TLS13_RECORD_IV_LEN,
- .fixed_iv_size = S2N_TLS13_FIXED_IV_LEN,
- .tag_size = S2N_TLS_GCM_TAG_LEN,
- .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
- .encrypt = s2n_aead_cipher_aes_gcm_encrypt},
- .is_available = s2n_aead_cipher_aes256_gcm_available,
- .init = s2n_aead_cipher_aes_gcm_init,
- .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,
-};
+/*
+ * 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 <openssl/aes.h>
+#include <openssl/evp.h>
+
+#include "crypto/s2n_cipher.h"
+
+#include "tls/s2n_crypto.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+#define S2N_AEAD_AES_GCM_AVAILABLE
+#endif
+
+static uint8_t s2n_aead_cipher_aes128_gcm_available()
+{
+#if defined(S2N_AEAD_AES_GCM_AVAILABLE)
+ return (EVP_aead_aes_128_gcm() ? 1 : 0);
+#else
+ return (EVP_aes_128_gcm() ? 1 : 0);
+#endif
+}
+
+static uint8_t s2n_aead_cipher_aes256_gcm_available()
+{
+#if defined(S2N_AEAD_AES_GCM_AVAILABLE)
+ return (EVP_aead_aes_256_gcm() ? 1 : 0);
+#else
+ return (EVP_aes_256_gcm() ? 1 : 0);
+#endif
+}
+
+#if defined(S2N_AEAD_AES_GCM_AVAILABLE) /* BoringSSL and AWS-LC AEAD API implementation */
+
+static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
+{
+ notnull_check(in);
+ notnull_check(out);
+ notnull_check(iv);
+ notnull_check(key);
+ notnull_check(aad);
+
+ /* The size of the |in| blob includes the size of the data and the size of the AES-GCM tag */
+ gte_check(in->size, S2N_TLS_GCM_TAG_LEN);
+ gte_check(out->size, in->size);
+ eq_check(iv->size, S2N_TLS_GCM_IV_LEN);
+
+ /* Adjust input length to account for the Tag length */
+ size_t in_len = in->size - S2N_TLS_GCM_TAG_LEN;
+ size_t out_len = 0;
+
+ GUARD_OSSL(EVP_AEAD_CTX_seal(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
+
+ S2N_ERROR_IF((in_len + S2N_TLS_GCM_TAG_LEN) != out_len, S2N_ERR_ENCRYPT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
+{
+ notnull_check(in);
+ notnull_check(out);
+ notnull_check(iv);
+ notnull_check(key);
+ notnull_check(aad);
+
+ gte_check(in->size, S2N_TLS_GCM_TAG_LEN);
+ gte_check(out->size, in->size - S2N_TLS_GCM_TAG_LEN);
+ eq_check(iv->size, S2N_TLS_GCM_IV_LEN);
+
+ size_t out_len = 0;
+
+ GUARD_OSSL(EVP_AEAD_CTX_open(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in->size, aad->data, aad->size), S2N_ERR_DECRYPT);
+
+ S2N_ERROR_IF((in->size - S2N_TLS_GCM_TAG_LEN) != out_len, S2N_ERR_ENCRYPT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes128_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ notnull_check(key);
+ notnull_check(in);
+
+ eq_check(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
+
+ GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes256_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ notnull_check(key);
+ notnull_check(in);
+
+ eq_check(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
+
+ GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes128_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ notnull_check(key);
+ notnull_check(in);
+
+ eq_check(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
+
+ GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes256_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ notnull_check(key);
+ notnull_check(in);
+
+ eq_check(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
+
+ GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm(), in->data, in->size, S2N_TLS_GCM_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes_gcm_init(struct s2n_session_key *key)
+{
+ notnull_check(key);
+
+ EVP_AEAD_CTX_zero(key->evp_aead_ctx);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes_gcm_destroy_key(struct s2n_session_key *key)
+{
+ notnull_check(key);
+
+ EVP_AEAD_CTX_cleanup(key->evp_aead_ctx);
+
+ return S2N_SUCCESS;
+}
+
+#else /* Standard AES-GCM implementation */
+
+static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
+{
+ /* The size of the |in| blob includes the size of the data and the size of the ChaCha20-Poly1305 tag */
+ gte_check(in->size, S2N_TLS_GCM_TAG_LEN);
+ gte_check(out->size, in->size);
+ eq_check(iv->size, S2N_TLS_GCM_IV_LEN);
+
+ /* Initialize the IV */
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
+
+ /* Adjust input length and buffer pointer to account for the Tag length */
+ int in_len = in->size - S2N_TLS_GCM_TAG_LEN;
+ uint8_t *tag_data = out->data + out->size - S2N_TLS_GCM_TAG_LEN;
+
+ int out_len;
+ /* Specify the AAD */
+ GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
+
+ /* Encrypt the data */
+ GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &out_len, in->data, in_len), S2N_ERR_ENCRYPT);
+
+ /* When using AES-GCM, *out_len is the number of bytes written by EVP_EncryptUpdate. Since the tag is not written during this call, we do not take S2N_TLS_GCM_TAG_LEN into account */
+ S2N_ERROR_IF(in_len != out_len, S2N_ERR_ENCRYPT);
+
+ /* Finalize */
+ GUARD_OSSL(EVP_EncryptFinal_ex(key->evp_cipher_ctx, out->data, &out_len), S2N_ERR_ENCRYPT);
+
+ /* write the tag */
+ GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_GET_TAG, S2N_TLS_GCM_TAG_LEN, tag_data), S2N_ERR_ENCRYPT);
+
+ /* When using AES-GCM, EVP_EncryptFinal_ex does not write any bytes. So, we should expect *out_len = 0. */
+ S2N_ERROR_IF(0 != out_len, S2N_ERR_ENCRYPT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(in->size, S2N_TLS_GCM_TAG_LEN);
+ gte_check(out->size, in->size);
+ eq_check(iv->size, S2N_TLS_GCM_IV_LEN);
+
+ /* Initialize the IV */
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
+
+ /* Adjust input length and buffer pointer to account for the Tag length */
+ int in_len = in->size - S2N_TLS_GCM_TAG_LEN;
+ uint8_t *tag_data = in->data + in->size - S2N_TLS_GCM_TAG_LEN;
+
+ /* Set the TAG */
+ GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_TAG, S2N_TLS_GCM_TAG_LEN, tag_data), S2N_ERR_DECRYPT);
+
+ int out_len;
+ /* Specify the AAD */
+ GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_DECRYPT);
+
+ int evp_decrypt_rc = 1;
+ /* Decrypt the data, but don't short circuit tag verification. EVP_Decrypt* return 0 on failure, 1 for success. */
+ evp_decrypt_rc &= EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &out_len, in->data, in_len);
+
+ /* Verify the tag */
+ evp_decrypt_rc &= EVP_DecryptFinal_ex(key->evp_cipher_ctx, out->data, &out_len);
+
+ S2N_ERROR_IF(evp_decrypt_rc != 1, S2N_ERR_DECRYPT);
+
+ /* While we verify the content of out_len in s2n_aead_cipher_aes_gcm_encrypt, we refrain from this here. This is to avoid doing any branching before the ciphertext is verified. */
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes128_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
+
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
+
+ EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
+
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes256_gcm_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
+
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
+
+ EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
+
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes128_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, S2N_TLS_AES_128_GCM_KEY_LEN);
+
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
+
+ EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
+
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes256_gcm_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, S2N_TLS_AES_256_GCM_KEY_LEN);
+
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_gcm(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
+
+ EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_IVLEN, S2N_TLS_GCM_IV_LEN, NULL);
+
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes_gcm_init(struct s2n_session_key *key)
+{
+ s2n_evp_ctx_init(key->evp_cipher_ctx);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_aead_cipher_aes_gcm_destroy_key(struct s2n_session_key *key)
+{
+ EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
+
+ return S2N_SUCCESS;
+}
+
+#endif
+
+struct s2n_cipher s2n_aes128_gcm = {
+ .key_material_size = S2N_TLS_AES_128_GCM_KEY_LEN,
+ .type = S2N_AEAD,
+ .io.aead = {
+ .record_iv_size = S2N_TLS_GCM_EXPLICIT_IV_LEN,
+ .fixed_iv_size = S2N_TLS_GCM_FIXED_IV_LEN,
+ .tag_size = S2N_TLS_GCM_TAG_LEN,
+ .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
+ .encrypt = s2n_aead_cipher_aes_gcm_encrypt},
+ .is_available = s2n_aead_cipher_aes128_gcm_available,
+ .init = s2n_aead_cipher_aes_gcm_init,
+ .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,
+};
+
+struct s2n_cipher s2n_aes256_gcm = {
+ .key_material_size = S2N_TLS_AES_256_GCM_KEY_LEN,
+ .type = S2N_AEAD,
+ .io.aead = {
+ .record_iv_size = S2N_TLS_GCM_EXPLICIT_IV_LEN,
+ .fixed_iv_size = S2N_TLS_GCM_FIXED_IV_LEN,
+ .tag_size = S2N_TLS_GCM_TAG_LEN,
+ .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
+ .encrypt = s2n_aead_cipher_aes_gcm_encrypt},
+ .is_available = s2n_aead_cipher_aes256_gcm_available,
+ .init = s2n_aead_cipher_aes_gcm_init,
+ .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,
+};
+
+/* TLS 1.3 GCM ciphers */
+struct s2n_cipher s2n_tls13_aes128_gcm = {
+ .key_material_size = S2N_TLS_AES_128_GCM_KEY_LEN,
+ .type = S2N_AEAD,
+ .io.aead = {
+ .record_iv_size = S2N_TLS13_RECORD_IV_LEN,
+ .fixed_iv_size = S2N_TLS13_FIXED_IV_LEN,
+ .tag_size = S2N_TLS_GCM_TAG_LEN,
+ .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
+ .encrypt = s2n_aead_cipher_aes_gcm_encrypt},
+ .is_available = s2n_aead_cipher_aes128_gcm_available,
+ .init = s2n_aead_cipher_aes_gcm_init,
+ .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,
+};
+
+struct s2n_cipher s2n_tls13_aes256_gcm = {
+ .key_material_size = S2N_TLS_AES_256_GCM_KEY_LEN,
+ .type = S2N_AEAD,
+ .io.aead = {
+ .record_iv_size = S2N_TLS13_RECORD_IV_LEN,
+ .fixed_iv_size = S2N_TLS13_FIXED_IV_LEN,
+ .tag_size = S2N_TLS_GCM_TAG_LEN,
+ .decrypt = s2n_aead_cipher_aes_gcm_decrypt,
+ .encrypt = s2n_aead_cipher_aes_gcm_encrypt},
+ .is_available = s2n_aead_cipher_aes256_gcm_available,
+ .init = s2n_aead_cipher_aes_gcm_init,
+ .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,
+};
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c b/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c
index 5c395a4b26..00dba89271 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_aead_cipher_chacha20_poly1305.c
@@ -1,275 +1,275 @@
-/*
- * 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 <openssl/evp.h>
-
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_openssl.h"
-
-#include "tls/s2n_crypto.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-/* We support two different backing implementations of ChaCha20-Poly1305: one
- * implementation for OpenSSL (>= 1.1.0, see
- * https://www.openssl.org/news/cl110.txt) and one implementation for BoringSSL
- * and AWS-LC. LibreSSL supports ChaCha20-Poly1305, but the interface is
- * different.
- * Note, the order in the if/elif below matters because both BoringSSL and
- * AWS-LC define OPENSSL_VERSION_NUMBER. */
-#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
-#define S2N_CHACHA20_POLY1305_AVAILABLE_BSSL_AWSLC
-#elif (S2N_OPENSSL_VERSION_AT_LEAST(1,1,0))
-#define S2N_CHACHA20_POLY1305_AVAILABLE_OSSL
-#endif
-
-static uint8_t s2n_aead_chacha20_poly1305_available(void)
-{
-#if defined(S2N_CHACHA20_POLY1305_AVAILABLE_OSSL) || defined(S2N_CHACHA20_POLY1305_AVAILABLE_BSSL_AWSLC)
- return 1;
-#else
- return 0;
-#endif
-}
-
-#if defined(S2N_CHACHA20_POLY1305_AVAILABLE_OSSL) /* OpenSSL implementation */
-
-static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
- /* The size of the |in| blob includes the size of the data and the size of the ChaCha20-Poly1305 tag */
- gte_check(out->size, in->size);
- eq_check(iv->size, S2N_TLS_CHACHA20_POLY1305_IV_LEN);
-
- /* Initialize the IV */
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
-
- /* Adjust input length and buffer pointer to account for the Tag length */
- int in_len = in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
- uint8_t *tag_data = out->data + out->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
-
- int out_len;
- /* Specify the AAD */
- GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
-
- /* Encrypt the data */
- GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &out_len, in->data, in_len), S2N_ERR_ENCRYPT);
-
- /* For OpenSSL 1.1.0 and 1.1.1, when using ChaCha20-Poly1305, *out_len is the number of bytes written by EVP_EncryptUpdate. Since the tag is not written during this call, we do not take S2N_TLS_CHACHA20_POLY1305_TAG_LEN into account */
- S2N_ERROR_IF(in_len != out_len, S2N_ERR_ENCRYPT);
-
- /* Finalize */
- GUARD_OSSL(EVP_EncryptFinal_ex(key->evp_cipher_ctx, out->data, &out_len), S2N_ERR_ENCRYPT);
-
- /* Write the tag */
- GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_GET_TAG, S2N_TLS_CHACHA20_POLY1305_TAG_LEN, tag_data), S2N_ERR_ENCRYPT);
-
- /* For OpenSSL 1.1.0 and 1.1.1, when using ChaCha20-Poly1305, EVP_EncryptFinal_ex does not write any bytes. So, we should expect *out_len = 0. */
- S2N_ERROR_IF(0 != out_len, S2N_ERR_ENCRYPT);
-
- return 0;
-}
-
-static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
- gte_check(out->size, in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
- eq_check(iv->size, S2N_TLS_CHACHA20_POLY1305_IV_LEN);
-
- /* Initialize the IV */
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
-
- /* Adjust input length and buffer pointer to account for the Tag length */
- int in_len = in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
- uint8_t *tag_data = in->data + in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
-
- /* Set the TAG */
- GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_TAG, S2N_TLS_CHACHA20_POLY1305_TAG_LEN, tag_data), S2N_ERR_DECRYPT);
-
- int out_len;
- /* Specify the AAD */
- GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_DECRYPT);
-
- int evp_decrypt_rc = 1;
- /* Decrypt the data, but don't short circuit tag verification. EVP_Decrypt* return 0 on failure, 1 for success. */
- evp_decrypt_rc &= EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &out_len, in->data, in_len);
-
- /* Verify the tag */
- evp_decrypt_rc &= EVP_DecryptFinal_ex(key->evp_cipher_ctx, out->data, &out_len);
-
- S2N_ERROR_IF(evp_decrypt_rc != 1, S2N_ERR_DECRYPT);
-
- /* While we verify the content of out_len in s2n_aead_chacha20_poly1305_encrypt, we refrain from this here. This is to avoid doing any branching before the ciphertext is verified. */
-
- return 0;
-}
-
-static int s2n_aead_chacha20_poly1305_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, S2N_TLS_CHACHA20_POLY1305_KEY_LEN);
-
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_chacha20_poly1305(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
-
- EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_IVLEN, S2N_TLS_CHACHA20_POLY1305_IV_LEN, NULL);
-
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_aead_chacha20_poly1305_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, S2N_TLS_CHACHA20_POLY1305_KEY_LEN);
-
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_chacha20_poly1305(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
-
- EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_IVLEN, S2N_TLS_CHACHA20_POLY1305_IV_LEN, NULL);
-
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_aead_chacha20_poly1305_init(struct s2n_session_key *key)
-{
- s2n_evp_ctx_init(key->evp_cipher_ctx);
-
- return 0;
-}
-
-static int s2n_aead_chacha20_poly1305_destroy_key(struct s2n_session_key *key)
-{
- EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
-
- return 0;
-}
-
-#elif defined(S2N_CHACHA20_POLY1305_AVAILABLE_BSSL_AWSLC) /* BoringSSL and AWS-LC implementation */
-
-static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
- /* The size of the |in| blob includes the size of the data and the size of the ChaCha20-Poly1305 tag */
- gte_check(out->size, in->size);
- eq_check(iv->size, S2N_TLS_CHACHA20_POLY1305_IV_LEN);
-
- /* Adjust input length to account for the Tag length */
- size_t in_len = in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
- size_t out_len = 0;
-
- GUARD_OSSL(EVP_AEAD_CTX_seal(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
-
- S2N_ERROR_IF((in_len + S2N_TLS_CHACHA20_POLY1305_TAG_LEN) != out_len, S2N_ERR_ENCRYPT);
-
- return 0;
-}
-
-static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
- gte_check(out->size, in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
- eq_check(iv->size, S2N_TLS_CHACHA20_POLY1305_IV_LEN);
-
- size_t out_len = 0;
-
- GUARD_OSSL(EVP_AEAD_CTX_open(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in->size, aad->data, aad->size), S2N_ERR_DECRYPT);
-
- S2N_ERROR_IF((in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN) != out_len, S2N_ERR_ENCRYPT);
-
- return 0;
-}
-
-static int s2n_aead_chacha20_poly1305_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, S2N_TLS_CHACHA20_POLY1305_KEY_LEN);
-
- GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_chacha20_poly1305(), in->data, in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_aead_chacha20_poly1305_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, S2N_TLS_CHACHA20_POLY1305_KEY_LEN);
-
- GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_chacha20_poly1305(), in->data, in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_aead_chacha20_poly1305_init(struct s2n_session_key *key)
-{
- EVP_AEAD_CTX_zero(key->evp_aead_ctx);
-
- return 0;
-}
-
-static int s2n_aead_chacha20_poly1305_destroy_key(struct s2n_session_key *key)
-{
- EVP_AEAD_CTX_cleanup(key->evp_aead_ctx);
-
- return 0;
-}
-
-#else /* No ChaCha20-Poly1305 implementation exists for chosen cryptographic provider (E.g Openssl 1.0.x) */
-
-static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
-{
- S2N_ERROR(S2N_ERR_ENCRYPT);
-}
-
-static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
-{
- S2N_ERROR(S2N_ERR_DECRYPT);
-}
-
-static int s2n_aead_chacha20_poly1305_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- S2N_ERROR(S2N_ERR_KEY_INIT);
-}
-
-static int s2n_aead_chacha20_poly1305_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- S2N_ERROR(S2N_ERR_KEY_INIT);
-}
-
-static int s2n_aead_chacha20_poly1305_init(struct s2n_session_key *key)
-{
- S2N_ERROR(S2N_ERR_KEY_INIT);
-}
-
-static int s2n_aead_chacha20_poly1305_destroy_key(struct s2n_session_key *key)
-{
- S2N_ERROR(S2N_ERR_KEY_DESTROY);
-}
-
-#endif
-
-struct s2n_cipher s2n_chacha20_poly1305 = {
- .key_material_size = S2N_TLS_CHACHA20_POLY1305_KEY_LEN,
- .type = S2N_AEAD,
- .io.aead = {
- .record_iv_size = S2N_TLS_CHACHA20_POLY1305_EXPLICIT_IV_LEN,
- .fixed_iv_size = S2N_TLS_CHACHA20_POLY1305_FIXED_IV_LEN,
- .tag_size = S2N_TLS_CHACHA20_POLY1305_TAG_LEN,
- .decrypt = s2n_aead_chacha20_poly1305_decrypt,
- .encrypt = s2n_aead_chacha20_poly1305_encrypt},
- .is_available = s2n_aead_chacha20_poly1305_available,
- .init = s2n_aead_chacha20_poly1305_init,
- .set_encryption_key = s2n_aead_chacha20_poly1305_set_encryption_key,
- .set_decryption_key = s2n_aead_chacha20_poly1305_set_decryption_key,
- .destroy_key = s2n_aead_chacha20_poly1305_destroy_key,
-};
+/*
+ * 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 <openssl/evp.h>
+
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_openssl.h"
+
+#include "tls/s2n_crypto.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+/* We support two different backing implementations of ChaCha20-Poly1305: one
+ * implementation for OpenSSL (>= 1.1.0, see
+ * https://www.openssl.org/news/cl110.txt) and one implementation for BoringSSL
+ * and AWS-LC. LibreSSL supports ChaCha20-Poly1305, but the interface is
+ * different.
+ * Note, the order in the if/elif below matters because both BoringSSL and
+ * AWS-LC define OPENSSL_VERSION_NUMBER. */
+#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+#define S2N_CHACHA20_POLY1305_AVAILABLE_BSSL_AWSLC
+#elif (S2N_OPENSSL_VERSION_AT_LEAST(1,1,0))
+#define S2N_CHACHA20_POLY1305_AVAILABLE_OSSL
+#endif
+
+static uint8_t s2n_aead_chacha20_poly1305_available(void)
+{
+#if defined(S2N_CHACHA20_POLY1305_AVAILABLE_OSSL) || defined(S2N_CHACHA20_POLY1305_AVAILABLE_BSSL_AWSLC)
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+#if defined(S2N_CHACHA20_POLY1305_AVAILABLE_OSSL) /* OpenSSL implementation */
+
+static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
+ /* The size of the |in| blob includes the size of the data and the size of the ChaCha20-Poly1305 tag */
+ gte_check(out->size, in->size);
+ eq_check(iv->size, S2N_TLS_CHACHA20_POLY1305_IV_LEN);
+
+ /* Initialize the IV */
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
+
+ /* Adjust input length and buffer pointer to account for the Tag length */
+ int in_len = in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
+ uint8_t *tag_data = out->data + out->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
+
+ int out_len;
+ /* Specify the AAD */
+ GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
+
+ /* Encrypt the data */
+ GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &out_len, in->data, in_len), S2N_ERR_ENCRYPT);
+
+ /* For OpenSSL 1.1.0 and 1.1.1, when using ChaCha20-Poly1305, *out_len is the number of bytes written by EVP_EncryptUpdate. Since the tag is not written during this call, we do not take S2N_TLS_CHACHA20_POLY1305_TAG_LEN into account */
+ S2N_ERROR_IF(in_len != out_len, S2N_ERR_ENCRYPT);
+
+ /* Finalize */
+ GUARD_OSSL(EVP_EncryptFinal_ex(key->evp_cipher_ctx, out->data, &out_len), S2N_ERR_ENCRYPT);
+
+ /* Write the tag */
+ GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_GET_TAG, S2N_TLS_CHACHA20_POLY1305_TAG_LEN, tag_data), S2N_ERR_ENCRYPT);
+
+ /* For OpenSSL 1.1.0 and 1.1.1, when using ChaCha20-Poly1305, EVP_EncryptFinal_ex does not write any bytes. So, we should expect *out_len = 0. */
+ S2N_ERROR_IF(0 != out_len, S2N_ERR_ENCRYPT);
+
+ return 0;
+}
+
+static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
+ gte_check(out->size, in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
+ eq_check(iv->size, S2N_TLS_CHACHA20_POLY1305_IV_LEN);
+
+ /* Initialize the IV */
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
+
+ /* Adjust input length and buffer pointer to account for the Tag length */
+ int in_len = in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
+ uint8_t *tag_data = in->data + in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
+
+ /* Set the TAG */
+ GUARD_OSSL(EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_GCM_SET_TAG, S2N_TLS_CHACHA20_POLY1305_TAG_LEN, tag_data), S2N_ERR_DECRYPT);
+
+ int out_len;
+ /* Specify the AAD */
+ GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_DECRYPT);
+
+ int evp_decrypt_rc = 1;
+ /* Decrypt the data, but don't short circuit tag verification. EVP_Decrypt* return 0 on failure, 1 for success. */
+ evp_decrypt_rc &= EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &out_len, in->data, in_len);
+
+ /* Verify the tag */
+ evp_decrypt_rc &= EVP_DecryptFinal_ex(key->evp_cipher_ctx, out->data, &out_len);
+
+ S2N_ERROR_IF(evp_decrypt_rc != 1, S2N_ERR_DECRYPT);
+
+ /* While we verify the content of out_len in s2n_aead_chacha20_poly1305_encrypt, we refrain from this here. This is to avoid doing any branching before the ciphertext is verified. */
+
+ return 0;
+}
+
+static int s2n_aead_chacha20_poly1305_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, S2N_TLS_CHACHA20_POLY1305_KEY_LEN);
+
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_chacha20_poly1305(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
+
+ EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_IVLEN, S2N_TLS_CHACHA20_POLY1305_IV_LEN, NULL);
+
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_aead_chacha20_poly1305_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, S2N_TLS_CHACHA20_POLY1305_KEY_LEN);
+
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_chacha20_poly1305(), NULL, NULL, NULL), S2N_ERR_KEY_INIT);
+
+ EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_IVLEN, S2N_TLS_CHACHA20_POLY1305_IV_LEN, NULL);
+
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_aead_chacha20_poly1305_init(struct s2n_session_key *key)
+{
+ s2n_evp_ctx_init(key->evp_cipher_ctx);
+
+ return 0;
+}
+
+static int s2n_aead_chacha20_poly1305_destroy_key(struct s2n_session_key *key)
+{
+ EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
+
+ return 0;
+}
+
+#elif defined(S2N_CHACHA20_POLY1305_AVAILABLE_BSSL_AWSLC) /* BoringSSL and AWS-LC implementation */
+
+static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
+ /* The size of the |in| blob includes the size of the data and the size of the ChaCha20-Poly1305 tag */
+ gte_check(out->size, in->size);
+ eq_check(iv->size, S2N_TLS_CHACHA20_POLY1305_IV_LEN);
+
+ /* Adjust input length to account for the Tag length */
+ size_t in_len = in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN;
+ size_t out_len = 0;
+
+ GUARD_OSSL(EVP_AEAD_CTX_seal(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in_len, aad->data, aad->size), S2N_ERR_ENCRYPT);
+
+ S2N_ERROR_IF((in_len + S2N_TLS_CHACHA20_POLY1305_TAG_LEN) != out_len, S2N_ERR_ENCRYPT);
+
+ return 0;
+}
+
+static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
+ gte_check(out->size, in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN);
+ eq_check(iv->size, S2N_TLS_CHACHA20_POLY1305_IV_LEN);
+
+ size_t out_len = 0;
+
+ GUARD_OSSL(EVP_AEAD_CTX_open(key->evp_aead_ctx, out->data, &out_len, out->size, iv->data, iv->size, in->data, in->size, aad->data, aad->size), S2N_ERR_DECRYPT);
+
+ S2N_ERROR_IF((in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN) != out_len, S2N_ERR_ENCRYPT);
+
+ return 0;
+}
+
+static int s2n_aead_chacha20_poly1305_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, S2N_TLS_CHACHA20_POLY1305_KEY_LEN);
+
+ GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_chacha20_poly1305(), in->data, in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_aead_chacha20_poly1305_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, S2N_TLS_CHACHA20_POLY1305_KEY_LEN);
+
+ GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_chacha20_poly1305(), in->data, in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_aead_chacha20_poly1305_init(struct s2n_session_key *key)
+{
+ EVP_AEAD_CTX_zero(key->evp_aead_ctx);
+
+ return 0;
+}
+
+static int s2n_aead_chacha20_poly1305_destroy_key(struct s2n_session_key *key)
+{
+ EVP_AEAD_CTX_cleanup(key->evp_aead_ctx);
+
+ return 0;
+}
+
+#else /* No ChaCha20-Poly1305 implementation exists for chosen cryptographic provider (E.g Openssl 1.0.x) */
+
+static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
+{
+ S2N_ERROR(S2N_ERR_ENCRYPT);
+}
+
+static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *aad, struct s2n_blob *in, struct s2n_blob *out)
+{
+ S2N_ERROR(S2N_ERR_DECRYPT);
+}
+
+static int s2n_aead_chacha20_poly1305_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ S2N_ERROR(S2N_ERR_KEY_INIT);
+}
+
+static int s2n_aead_chacha20_poly1305_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ S2N_ERROR(S2N_ERR_KEY_INIT);
+}
+
+static int s2n_aead_chacha20_poly1305_init(struct s2n_session_key *key)
+{
+ S2N_ERROR(S2N_ERR_KEY_INIT);
+}
+
+static int s2n_aead_chacha20_poly1305_destroy_key(struct s2n_session_key *key)
+{
+ S2N_ERROR(S2N_ERR_KEY_DESTROY);
+}
+
+#endif
+
+struct s2n_cipher s2n_chacha20_poly1305 = {
+ .key_material_size = S2N_TLS_CHACHA20_POLY1305_KEY_LEN,
+ .type = S2N_AEAD,
+ .io.aead = {
+ .record_iv_size = S2N_TLS_CHACHA20_POLY1305_EXPLICIT_IV_LEN,
+ .fixed_iv_size = S2N_TLS_CHACHA20_POLY1305_FIXED_IV_LEN,
+ .tag_size = S2N_TLS_CHACHA20_POLY1305_TAG_LEN,
+ .decrypt = s2n_aead_chacha20_poly1305_decrypt,
+ .encrypt = s2n_aead_chacha20_poly1305_encrypt},
+ .is_available = s2n_aead_chacha20_poly1305_available,
+ .init = s2n_aead_chacha20_poly1305_init,
+ .set_encryption_key = s2n_aead_chacha20_poly1305_set_encryption_key,
+ .set_decryption_key = s2n_aead_chacha20_poly1305_set_decryption_key,
+ .destroy_key = s2n_aead_chacha20_poly1305_destroy_key,
+};
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c b/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c
index dcd190bd8a..b992d6bc83 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c
@@ -1,103 +1,103 @@
-/*
- * 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 <openssl/evp.h>
-
-#include "error/s2n_errno.h"
-
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_openssl.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-static uint8_t s2n_cbc_cipher_3des_available()
-{
- return (EVP_des_ede3_cbc() ? 1 : 0);
-}
-
-static int s2n_cbc_cipher_3des_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(out->size, in->size);
-
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
-
- int len = out->size;
- GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
- S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
-
- return 0;
-}
-
-static int s2n_cbc_cipher_3des_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(out->size, in->size);
-
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
-
- int len = out->size;
- GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_DECRYPT);
-
- return 0;
-}
-
-static int s2n_cbc_cipher_3des_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 192 / 8);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_des_ede3_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_cbc_cipher_3des_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 192 / 8);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_des_ede3_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_cbc_cipher_3des_init(struct s2n_session_key *key)
-{
- s2n_evp_ctx_init(key->evp_cipher_ctx);
-
- return 0;
-}
-
-static int s2n_cbc_cipher_3des_destroy_key(struct s2n_session_key *key)
-{
- EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
-
- return 0;
-}
-
-struct s2n_cipher s2n_3des = {
- .key_material_size = 24,
- .type = S2N_CBC,
- .io.cbc = {
- .block_size = 8,
- .record_iv_size = 8,
- .decrypt = s2n_cbc_cipher_3des_decrypt,
- .encrypt = s2n_cbc_cipher_3des_encrypt},
- .is_available = s2n_cbc_cipher_3des_available,
- .init = s2n_cbc_cipher_3des_init,
- .set_decryption_key = s2n_cbc_cipher_3des_set_decryption_key,
- .set_encryption_key = s2n_cbc_cipher_3des_set_encryption_key,
- .destroy_key = s2n_cbc_cipher_3des_destroy_key,
-};
+/*
+ * 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 <openssl/evp.h>
+
+#include "error/s2n_errno.h"
+
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_openssl.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+static uint8_t s2n_cbc_cipher_3des_available()
+{
+ return (EVP_des_ede3_cbc() ? 1 : 0);
+}
+
+static int s2n_cbc_cipher_3des_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(out->size, in->size);
+
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
+
+ int len = out->size;
+ GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
+ S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
+
+ return 0;
+}
+
+static int s2n_cbc_cipher_3des_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(out->size, in->size);
+
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
+
+ int len = out->size;
+ GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_DECRYPT);
+
+ return 0;
+}
+
+static int s2n_cbc_cipher_3des_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 192 / 8);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_des_ede3_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_cbc_cipher_3des_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 192 / 8);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_des_ede3_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_cbc_cipher_3des_init(struct s2n_session_key *key)
+{
+ s2n_evp_ctx_init(key->evp_cipher_ctx);
+
+ return 0;
+}
+
+static int s2n_cbc_cipher_3des_destroy_key(struct s2n_session_key *key)
+{
+ EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
+
+ return 0;
+}
+
+struct s2n_cipher s2n_3des = {
+ .key_material_size = 24,
+ .type = S2N_CBC,
+ .io.cbc = {
+ .block_size = 8,
+ .record_iv_size = 8,
+ .decrypt = s2n_cbc_cipher_3des_decrypt,
+ .encrypt = s2n_cbc_cipher_3des_encrypt},
+ .is_available = s2n_cbc_cipher_3des_available,
+ .init = s2n_cbc_cipher_3des_init,
+ .set_decryption_key = s2n_cbc_cipher_3des_set_decryption_key,
+ .set_encryption_key = s2n_cbc_cipher_3des_set_encryption_key,
+ .destroy_key = s2n_cbc_cipher_3des_destroy_key,
+};
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c b/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c
index 2a0fbaf66e..1dee9b56f7 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c
@@ -1,143 +1,143 @@
-/*
- * 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 <openssl/aes.h>
-
-#include "error/s2n_errno.h"
-
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_openssl.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-static uint8_t s2n_cbc_cipher_aes128_available()
-{
- return (EVP_aes_128_cbc() ? 1 : 0);
-}
-
-static uint8_t s2n_cbc_cipher_aes256_available()
-{
- return (EVP_aes_256_cbc() ? 1 : 0);
-}
-
-static int s2n_cbc_cipher_aes_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(out->size, in->size);
-
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
-
- int len = out->size;
- GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
- S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
-
- return 0;
-}
-
-int s2n_cbc_cipher_aes_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(out->size, in->size);
-
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
- int len = out->size;
- GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_DECRYPT);
-
- return 0;
-}
-
-int s2n_cbc_cipher_aes128_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 128 / 8);
-
- /* Always returns 1 */
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_cbc_cipher_aes128_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 128 / 8);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_cbc_cipher_aes256_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 256 / 8);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-int s2n_cbc_cipher_aes256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 256 / 8);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_cbc_cipher_aes_init(struct s2n_session_key *key)
-{
- s2n_evp_ctx_init(key->evp_cipher_ctx);
-
- return 0;
-}
-
-static int s2n_cbc_cipher_aes_destroy_key(struct s2n_session_key *key)
-{
- EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
-
- return 0;
-}
-
-struct s2n_cipher s2n_aes128 = {
- .key_material_size = 16,
- .type = S2N_CBC,
- .io.cbc = {
- .block_size = 16,
- .record_iv_size = 16,
- .decrypt = s2n_cbc_cipher_aes_decrypt,
- .encrypt = s2n_cbc_cipher_aes_encrypt},
- .is_available = s2n_cbc_cipher_aes128_available,
- .init = s2n_cbc_cipher_aes_init,
- .set_decryption_key = s2n_cbc_cipher_aes128_set_decryption_key,
- .set_encryption_key = s2n_cbc_cipher_aes128_set_encryption_key,
- .destroy_key = s2n_cbc_cipher_aes_destroy_key,
-};
-
-struct s2n_cipher s2n_aes256 = {
- .key_material_size = 32,
- .type = S2N_CBC,
- .io.cbc = {
- .block_size = 16,
- .record_iv_size = 16,
- .decrypt = s2n_cbc_cipher_aes_decrypt,
- .encrypt = s2n_cbc_cipher_aes_encrypt},
- .is_available = s2n_cbc_cipher_aes256_available,
- .init = s2n_cbc_cipher_aes_init,
- .set_decryption_key = s2n_cbc_cipher_aes256_set_decryption_key,
- .set_encryption_key = s2n_cbc_cipher_aes256_set_encryption_key,
- .destroy_key = s2n_cbc_cipher_aes_destroy_key,
-};
+/*
+ * 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 <openssl/aes.h>
+
+#include "error/s2n_errno.h"
+
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_openssl.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+static uint8_t s2n_cbc_cipher_aes128_available()
+{
+ return (EVP_aes_128_cbc() ? 1 : 0);
+}
+
+static uint8_t s2n_cbc_cipher_aes256_available()
+{
+ return (EVP_aes_256_cbc() ? 1 : 0);
+}
+
+static int s2n_cbc_cipher_aes_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(out->size, in->size);
+
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
+
+ int len = out->size;
+ GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
+ S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
+
+ return 0;
+}
+
+int s2n_cbc_cipher_aes_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(out->size, in->size);
+
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
+ int len = out->size;
+ GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_DECRYPT);
+
+ return 0;
+}
+
+int s2n_cbc_cipher_aes128_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 128 / 8);
+
+ /* Always returns 1 */
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_cbc_cipher_aes128_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 128 / 8);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_128_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_cbc_cipher_aes256_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 256 / 8);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+int s2n_cbc_cipher_aes256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 256 / 8);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_cbc_cipher_aes_init(struct s2n_session_key *key)
+{
+ s2n_evp_ctx_init(key->evp_cipher_ctx);
+
+ return 0;
+}
+
+static int s2n_cbc_cipher_aes_destroy_key(struct s2n_session_key *key)
+{
+ EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
+
+ return 0;
+}
+
+struct s2n_cipher s2n_aes128 = {
+ .key_material_size = 16,
+ .type = S2N_CBC,
+ .io.cbc = {
+ .block_size = 16,
+ .record_iv_size = 16,
+ .decrypt = s2n_cbc_cipher_aes_decrypt,
+ .encrypt = s2n_cbc_cipher_aes_encrypt},
+ .is_available = s2n_cbc_cipher_aes128_available,
+ .init = s2n_cbc_cipher_aes_init,
+ .set_decryption_key = s2n_cbc_cipher_aes128_set_decryption_key,
+ .set_encryption_key = s2n_cbc_cipher_aes128_set_encryption_key,
+ .destroy_key = s2n_cbc_cipher_aes_destroy_key,
+};
+
+struct s2n_cipher s2n_aes256 = {
+ .key_material_size = 32,
+ .type = S2N_CBC,
+ .io.cbc = {
+ .block_size = 16,
+ .record_iv_size = 16,
+ .decrypt = s2n_cbc_cipher_aes_decrypt,
+ .encrypt = s2n_cbc_cipher_aes_encrypt},
+ .is_available = s2n_cbc_cipher_aes256_available,
+ .init = s2n_cbc_cipher_aes_init,
+ .set_decryption_key = s2n_cbc_cipher_aes256_set_decryption_key,
+ .set_encryption_key = s2n_cbc_cipher_aes256_set_encryption_key,
+ .destroy_key = s2n_cbc_cipher_aes_destroy_key,
+};
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_certificate.c b/contrib/restricted/aws/s2n/crypto/s2n_certificate.c
index 39646c3f28..988a5f6971 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_certificate.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_certificate.c
@@ -1,534 +1,534 @@
-/*
- * 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.
- */
-
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-#include <s2n.h>
-#include <openssl/x509v3.h>
-#include <openssl/pem.h>
-#include <string.h>
-#include <strings.h>
-
-#include "crypto/s2n_certificate.h"
-#include "utils/s2n_array.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_mem.h"
-
-#include "tls/extensions/s2n_extension_list.h"
-#include "tls/s2n_connection.h"
-
-int s2n_cert_set_cert_type(struct s2n_cert *cert, s2n_pkey_type pkey_type)
-{
- notnull_check(cert);
- cert->pkey_type = pkey_type;
- GUARD(s2n_pkey_setup_for_type(&cert->public_key, pkey_type));
- return 0;
-}
-
-int s2n_create_cert_chain_from_stuffer(struct s2n_cert_chain *cert_chain_out, struct s2n_stuffer *chain_in_stuffer)
-{
- DEFER_CLEANUP(struct s2n_stuffer cert_out_stuffer = {0}, s2n_stuffer_free);
- GUARD(s2n_stuffer_growable_alloc(&cert_out_stuffer, 2048));
-
- struct s2n_cert **insert = &cert_chain_out->head;
- uint32_t chain_size = 0;
- do {
- struct s2n_cert *new_node = NULL;
-
- if (s2n_stuffer_certificate_from_pem(chain_in_stuffer, &cert_out_stuffer) < 0) {
- if (chain_size == 0) {
- S2N_ERROR(S2N_ERR_NO_CERTIFICATE_IN_PEM);
- }
- break;
- }
- struct s2n_blob mem = {0};
- GUARD(s2n_alloc(&mem, sizeof(struct s2n_cert)));
- new_node = (struct s2n_cert *)(void *)mem.data;
-
- if (s2n_alloc(&new_node->raw, s2n_stuffer_data_available(&cert_out_stuffer)) != S2N_SUCCESS) {
- GUARD(s2n_free(&mem));
- S2N_ERROR_PRESERVE_ERRNO();
- }
- if (s2n_stuffer_read(&cert_out_stuffer, &new_node->raw) != S2N_SUCCESS) {
- GUARD(s2n_free(&mem));
- S2N_ERROR_PRESERVE_ERRNO();
- }
-
- /* Additional 3 bytes for the length field in the protocol */
- chain_size += new_node->raw.size + 3;
- new_node->next = NULL;
- *insert = new_node;
- insert = &new_node->next;
- } while (s2n_stuffer_data_available(chain_in_stuffer));
-
- /* Leftover data at this point means one of two things:
- * A bug in s2n's PEM parsing OR a malformed PEM in the user's chain.
- * Be conservative and fail instead of using a partial chain.
- */
- S2N_ERROR_IF(s2n_stuffer_data_available(chain_in_stuffer) > 0, S2N_ERR_INVALID_PEM);
-
- cert_chain_out->chain_size = chain_size;
-
- return 0;
-}
-
-int s2n_cert_chain_and_key_set_cert_chain_from_stuffer(struct s2n_cert_chain_and_key *cert_and_key, struct s2n_stuffer *chain_in_stuffer)
-{
- return s2n_create_cert_chain_from_stuffer(cert_and_key->cert_chain, chain_in_stuffer);
-}
-
-int s2n_cert_chain_and_key_set_cert_chain(struct s2n_cert_chain_and_key *cert_and_key, const char *cert_chain_pem)
-{
- struct s2n_stuffer chain_in_stuffer = {0};
-
- /* Turn the chain into a stuffer */
- GUARD(s2n_stuffer_alloc_ro_from_string(&chain_in_stuffer, cert_chain_pem));
- int rc = s2n_cert_chain_and_key_set_cert_chain_from_stuffer(cert_and_key, &chain_in_stuffer);
-
- GUARD(s2n_stuffer_free(&chain_in_stuffer));
-
- return rc;
-}
-
-int s2n_cert_chain_and_key_set_private_key(struct s2n_cert_chain_and_key *cert_and_key, const char *private_key_pem)
-{
- DEFER_CLEANUP(struct s2n_stuffer key_in_stuffer = {0}, s2n_stuffer_free);
- DEFER_CLEANUP(struct s2n_stuffer key_out_stuffer = {0}, s2n_stuffer_free);
- struct s2n_blob key_blob = {0};
-
- GUARD(s2n_pkey_zero_init(cert_and_key->private_key));
-
- /* Put the private key pem in a stuffer */
- GUARD(s2n_stuffer_alloc_ro_from_string(&key_in_stuffer, private_key_pem));
- GUARD(s2n_stuffer_growable_alloc(&key_out_stuffer, strlen(private_key_pem)));
-
- /* Convert pem to asn1 and asn1 to the private key. Handles both PKCS#1 and PKCS#8 formats */
- GUARD(s2n_stuffer_private_key_from_pem(&key_in_stuffer, &key_out_stuffer));
- key_blob.size = s2n_stuffer_data_available(&key_out_stuffer);
- key_blob.data = s2n_stuffer_raw_read(&key_out_stuffer, key_blob.size);
- notnull_check(key_blob.data);
-
- /* Get key type and create appropriate key context */
- GUARD(s2n_asn1der_to_private_key(cert_and_key->private_key, &key_blob));
-
- return 0;
-}
-
-int s2n_cert_chain_and_key_set_ocsp_data(struct s2n_cert_chain_and_key *chain_and_key, const uint8_t *data, uint32_t length)
-{
- notnull_check(chain_and_key);
- GUARD(s2n_free(&chain_and_key->ocsp_status));
- if (data && length) {
- GUARD(s2n_alloc(&chain_and_key->ocsp_status, length));
- memcpy_check(chain_and_key->ocsp_status.data, data, length);
- }
- return 0;
-}
-
-int s2n_cert_chain_and_key_set_sct_list(struct s2n_cert_chain_and_key *chain_and_key, const uint8_t *data, uint32_t length)
-{
- notnull_check(chain_and_key);
- GUARD(s2n_free(&chain_and_key->sct_list));
- if (data && length) {
- GUARD(s2n_alloc(&chain_and_key->sct_list, length));
- memcpy_check(chain_and_key->sct_list.data, data, length);
- }
- return 0;
-}
-
-struct s2n_cert_chain_and_key *s2n_cert_chain_and_key_new(void)
-{
- struct s2n_cert_chain_and_key *chain_and_key;
- struct s2n_blob chain_and_key_mem, cert_chain_mem, pkey_mem;
-
- GUARD_PTR(s2n_alloc(&chain_and_key_mem, sizeof(struct s2n_cert_chain_and_key)));
- chain_and_key = (struct s2n_cert_chain_and_key *)(void *)chain_and_key_mem.data;
-
- /* Allocate the memory for the chain and key */
- if (s2n_alloc(&cert_chain_mem, sizeof(struct s2n_cert_chain)) != S2N_SUCCESS) {
- goto cleanup;
- }
- chain_and_key->cert_chain = (struct s2n_cert_chain *)(void *)cert_chain_mem.data;
-
- if (s2n_alloc(&pkey_mem, sizeof(s2n_cert_private_key)) != S2N_SUCCESS) {
- goto cleanup;
- }
- chain_and_key->private_key = (s2n_cert_private_key *)(void *)pkey_mem.data;
-
- chain_and_key->cert_chain->head = NULL;
- if (s2n_pkey_zero_init(chain_and_key->private_key) != S2N_SUCCESS) {
- goto cleanup;
- }
- memset(&chain_and_key->ocsp_status, 0, sizeof(chain_and_key->ocsp_status));
- memset(&chain_and_key->sct_list, 0, sizeof(chain_and_key->sct_list));
- chain_and_key->cn_names = s2n_array_new(sizeof(struct s2n_blob));
- if (!chain_and_key->cn_names) {
- goto cleanup;
- }
-
- chain_and_key->san_names = s2n_array_new(sizeof(struct s2n_blob));
- if (!chain_and_key->san_names) {
- goto cleanup;
- }
-
- chain_and_key->context = NULL;
-
- return chain_and_key;
- cleanup:
- s2n_free(&pkey_mem);
- s2n_free(&cert_chain_mem);
- s2n_free(&chain_and_key_mem);
- return NULL;
-}
-
-DEFINE_POINTER_CLEANUP_FUNC(GENERAL_NAMES *, GENERAL_NAMES_free);
-
-int s2n_cert_chain_and_key_load_sans(struct s2n_cert_chain_and_key *chain_and_key, X509 *x509_cert)
-{
- notnull_check(chain_and_key->san_names);
-
- DEFER_CLEANUP(GENERAL_NAMES *san_names = X509_get_ext_d2i(x509_cert, NID_subject_alt_name, NULL, NULL), GENERAL_NAMES_free_pointer);
- if (san_names == NULL) {
- /* No SAN extension */
- return 0;
- }
-
- const int num_san_names = sk_GENERAL_NAME_num(san_names);
- for (int i = 0; i < num_san_names; i++) {
- GENERAL_NAME *san_name = sk_GENERAL_NAME_value(san_names, i);
- if (!san_name) {
- continue;
- }
-
- if (san_name->type == GEN_DNS) {
- /* Decoding isn't necessary here since a DNS SAN name is ASCII(type V_ASN1_IA5STRING) */
- unsigned char *san_str = san_name->d.dNSName->data;
- const size_t san_str_len = san_name->d.dNSName->length;
- struct s2n_blob *san_blob = NULL;
- GUARD_AS_POSIX(s2n_array_pushback(chain_and_key->san_names, (void **)&san_blob));
- if (!san_blob) {
- S2N_ERROR(S2N_ERR_NULL_SANS);
- }
-
- if (s2n_alloc(san_blob, san_str_len)) {
- S2N_ERROR_PRESERVE_ERRNO();
- }
-
- memcpy_check(san_blob->data, san_str, san_str_len);
- san_blob->size = san_str_len;
- /* normalize san_blob to lowercase */
- GUARD(s2n_blob_char_to_lower(san_blob));
- }
- }
-
- return 0;
-}
-
-/* Parse CN names from the Subject of the leaf certificate. Technically there can by multiple CNs
- * in the Subject but practically very few certificates in the wild will have more than one CN.
- * Since the data for this certificate is coming from the application and not from an untrusted
- * source, we will try our best to parse all of the CNs.
- *
- * A recent CAB thread proposed removing support for multiple CNs:
- * https://cabforum.org/pipermail/public/2016-April/007242.html
- */
-
-DEFINE_POINTER_CLEANUP_FUNC(unsigned char *, OPENSSL_free);
-
-int s2n_cert_chain_and_key_load_cns(struct s2n_cert_chain_and_key *chain_and_key, X509 *x509_cert)
-{
- notnull_check(chain_and_key->cn_names);
-
- X509_NAME *subject = X509_get_subject_name(x509_cert);
- if (!subject) {
- return 0;
- }
-
- int lastpos = -1;
- while((lastpos = X509_NAME_get_index_by_NID(subject, NID_commonName, lastpos)) >= 0) {
- X509_NAME_ENTRY *name_entry = X509_NAME_get_entry(subject, lastpos);
- if (!name_entry) {
- continue;
- }
-
- ASN1_STRING *asn1_str = X509_NAME_ENTRY_get_data(name_entry);
- if (!asn1_str) {
- continue;
- }
-
- /* We need to try and decode the CN since it may be encoded as unicode with a
- * direct ASCII equivalent. Any non ASCII bytes in the string will fail later when we
- * actually compare hostnames.
- */
- DEFER_CLEANUP(unsigned char *utf8_str, OPENSSL_free_pointer);
- const int utf8_out_len = ASN1_STRING_to_UTF8(&utf8_str, asn1_str);
- if (utf8_out_len < 0) {
- /* On failure, ASN1_STRING_to_UTF8 does not allocate any memory */
- continue;
- } else if (utf8_out_len == 0) {
- /* We still need to free memory here see https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7521 */
- OPENSSL_free(utf8_str);
- } else {
- struct s2n_blob *cn_name = NULL;
- GUARD_AS_POSIX(s2n_array_pushback(chain_and_key->cn_names, (void **)&cn_name));
- if (cn_name == NULL) {
- S2N_ERROR(S2N_ERR_NULL_CN_NAME);
- }
-
- if (s2n_alloc(cn_name, utf8_out_len) < 0) {
- S2N_ERROR_PRESERVE_ERRNO();
- }
- memcpy_check(cn_name->data, utf8_str, utf8_out_len);
- cn_name->size = utf8_out_len;
- /* normalize cn_name to lowercase */
- GUARD(s2n_blob_char_to_lower(cn_name));
- }
- }
-
- return 0;
-}
-
-static int s2n_cert_chain_and_key_set_names(struct s2n_cert_chain_and_key *chain_and_key, struct s2n_blob *leaf_bytes)
-{
- const unsigned char *leaf_der = leaf_bytes->data;
- X509 *cert = d2i_X509(NULL, &leaf_der, leaf_bytes->size);
- if (!cert) {
- S2N_ERROR(S2N_ERR_INVALID_PEM);
- }
-
- GUARD(s2n_cert_chain_and_key_load_sans(chain_and_key, cert));
- /* For current use cases, we *could* avoid populating the common names if any sans were loaded in
- * s2n_cert_chain_and_key_load_sans. Let's unconditionally populate this field to avoid surprises
- * in the future.
- */
- GUARD(s2n_cert_chain_and_key_load_cns(chain_and_key, cert));
-
- X509_free(cert);
- return 0;
-}
-
-int s2n_cert_chain_and_key_load_pem(struct s2n_cert_chain_and_key *chain_and_key, const char *chain_pem, const char *private_key_pem)
-{
- notnull_check(chain_and_key);
-
- GUARD(s2n_cert_chain_and_key_set_cert_chain(chain_and_key, chain_pem));
- GUARD(s2n_cert_chain_and_key_set_private_key(chain_and_key, private_key_pem));
-
- /* Parse the leaf cert for the public key and certificate type */
- DEFER_CLEANUP(struct s2n_pkey public_key = {0}, s2n_pkey_free);
- s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN;
- GUARD(s2n_asn1der_to_public_key_and_type(&public_key, &pkey_type, &chain_and_key->cert_chain->head->raw));
- S2N_ERROR_IF(pkey_type == S2N_PKEY_TYPE_UNKNOWN, S2N_ERR_CERT_TYPE_UNSUPPORTED);
- GUARD(s2n_cert_set_cert_type(chain_and_key->cert_chain->head, pkey_type));
-
- /* Validate the leaf cert's public key matches the provided private key */
- GUARD(s2n_pkey_match(&public_key, chain_and_key->private_key));
-
- /* Populate name information from the SAN/CN for the leaf certificate */
- GUARD(s2n_cert_chain_and_key_set_names(chain_and_key, &chain_and_key->cert_chain->head->raw));
-
- return 0;
-}
-
-int s2n_cert_chain_and_key_free(struct s2n_cert_chain_and_key *cert_and_key)
-{
- if (cert_and_key == NULL) {
- return 0;
- }
-
- /* Walk the chain and free the certs */
- if (cert_and_key->cert_chain) {
- struct s2n_cert *node = cert_and_key->cert_chain->head;
- while (node) {
- /* Free the cert */
- GUARD(s2n_free(&node->raw));
- /* update head so it won't point to freed memory */
- cert_and_key->cert_chain->head = node->next;
- /* Free the node */
- GUARD(s2n_free_object((uint8_t **)&node, sizeof(struct s2n_cert)));
- node = cert_and_key->cert_chain->head;
- }
-
- GUARD(s2n_free_object((uint8_t **)&cert_and_key->cert_chain, sizeof(struct s2n_cert_chain)));
- }
-
- if (cert_and_key->private_key) {
- GUARD(s2n_pkey_free(cert_and_key->private_key));
- GUARD(s2n_free_object((uint8_t **)&cert_and_key->private_key, sizeof(s2n_cert_private_key)));
- }
-
- uint32_t len = 0;
-
- if (cert_and_key->san_names) {
- GUARD_AS_POSIX(s2n_array_num_elements(cert_and_key->san_names, &len));
- for (uint32_t i = 0; i < len; i++) {
- struct s2n_blob *san_name = NULL;
- GUARD_AS_POSIX(s2n_array_get(cert_and_key->san_names, i, (void **)&san_name));
- GUARD(s2n_free(san_name));
- }
- GUARD_AS_POSIX(s2n_array_free(cert_and_key->san_names));
- cert_and_key->san_names = NULL;
- }
-
- if (cert_and_key->cn_names) {
- GUARD_AS_POSIX(s2n_array_num_elements(cert_and_key->cn_names, &len));
- for (uint32_t i = 0; i < len; i++) {
- struct s2n_blob *cn_name = NULL;
- GUARD_AS_POSIX(s2n_array_get(cert_and_key->cn_names, i, (void **)&cn_name));
- GUARD(s2n_free(cn_name));
- }
- GUARD_AS_POSIX(s2n_array_free(cert_and_key->cn_names));
- cert_and_key->cn_names = NULL;
- }
-
- GUARD(s2n_free(&cert_and_key->ocsp_status));
- GUARD(s2n_free(&cert_and_key->sct_list));
-
- GUARD(s2n_free_object((uint8_t **)&cert_and_key, sizeof(struct s2n_cert_chain_and_key)));
- return 0;
-}
-
-int s2n_send_cert_chain(struct s2n_connection *conn, struct s2n_stuffer *out, struct s2n_cert_chain_and_key *chain_and_key)
-{
- notnull_check(conn);
- notnull_check(out);
- notnull_check(chain_and_key);
- struct s2n_cert_chain *chain = chain_and_key->cert_chain;
- notnull_check(chain);
- struct s2n_cert *cur_cert = chain->head;
- notnull_check(cur_cert);
-
- struct s2n_stuffer_reservation cert_chain_size = {0};
- GUARD(s2n_stuffer_reserve_uint24(out, &cert_chain_size));
-
- /* Send certs and extensions (in TLS 1.3) */
- bool first_entry = true;
- while (cur_cert) {
- notnull_check(cur_cert);
- GUARD(s2n_stuffer_write_uint24(out, cur_cert->raw.size));
- GUARD(s2n_stuffer_write_bytes(out, cur_cert->raw.data, cur_cert->raw.size));
-
- /* According to https://tools.ietf.org/html/rfc8446#section-4.4.2,
- * If an extension applies to the entire chain, it SHOULD be included in
- * the first CertificateEntry.
- * While the spec allow extensions to be included in other certificate
- * entries, only the first matter to use here */
- if (conn->actual_protocol_version >= S2N_TLS13) {
- if (first_entry) {
- GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_CERTIFICATE, conn, out));
- first_entry = false;
- } else {
- GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_EMPTY, conn, out));
- }
- }
- cur_cert = cur_cert->next;
- }
-
- GUARD(s2n_stuffer_write_vector_size(&cert_chain_size));
-
- return 0;
-}
-
-int s2n_send_empty_cert_chain(struct s2n_stuffer *out)
-{
- notnull_check(out);
- GUARD(s2n_stuffer_write_uint24(out, 0));
- return 0;
-}
-
-static int s2n_does_cert_san_match_hostname(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name)
-{
- notnull_check(chain_and_key);
- notnull_check(dns_name);
-
- struct s2n_array *san_names = chain_and_key->san_names;
- uint32_t len = 0;
- GUARD_AS_POSIX(s2n_array_num_elements(san_names, &len));
- for (uint32_t i = 0; i < len; i++) {
- struct s2n_blob *san_name = NULL;
- GUARD_AS_POSIX(s2n_array_get(san_names, i, (void **)&san_name));
- notnull_check(san_name);
- if ((dns_name->size == san_name->size) && (strncasecmp((const char *) dns_name->data, (const char *) san_name->data, dns_name->size) == 0)) {
- return 1;
- }
- }
-
- return 0;
-}
-
-static int s2n_does_cert_cn_match_hostname(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name)
-{
- notnull_check(chain_and_key);
- notnull_check(dns_name);
-
- struct s2n_array *cn_names = chain_and_key->cn_names;
- uint32_t len = 0;
- GUARD_AS_POSIX(s2n_array_num_elements(cn_names, &len));
- for (uint32_t i = 0; i < len; i++) {
- struct s2n_blob *cn_name = NULL;
- GUARD_AS_POSIX(s2n_array_get(cn_names, i, (void **)&cn_name));
- notnull_check(cn_name);
- if ((dns_name->size == cn_name->size) && (strncasecmp((const char *) dns_name->data, (const char *) cn_name->data, dns_name->size) == 0)) {
- return 1;
- }
- }
-
- return 0;
-}
-
-int s2n_cert_chain_and_key_matches_dns_name(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name)
-{
- uint32_t len = 0;
- GUARD_AS_POSIX(s2n_array_num_elements(chain_and_key->san_names, &len));
- if (len > 0) {
- if (s2n_does_cert_san_match_hostname(chain_and_key, dns_name)) {
- return 1;
- }
- } else {
- /* Per https://tools.ietf.org/html/rfc6125#section-6.4.4 we only will
- * consider the CN for matching if no valid DNS entries are provided
- * in a SAN.
- */
- if (s2n_does_cert_cn_match_hostname(chain_and_key, dns_name)) {
- return 1;
- }
- }
-
- return 0;
-}
-
-int s2n_cert_chain_and_key_set_ctx(struct s2n_cert_chain_and_key *cert_and_key, void *ctx)
-{
- cert_and_key->context = ctx;
- return 0;
-}
-
-void *s2n_cert_chain_and_key_get_ctx(struct s2n_cert_chain_and_key *cert_and_key)
-{
- return cert_and_key->context;
-}
-
-s2n_pkey_type s2n_cert_chain_and_key_get_pkey_type(struct s2n_cert_chain_and_key *chain_and_key)
-{
- return chain_and_key->cert_chain->head->pkey_type;
-}
-
-s2n_cert_private_key *s2n_cert_chain_and_key_get_private_key(struct s2n_cert_chain_and_key *chain_and_key)
-{
- ENSURE_REF_PTR(chain_and_key);
- return chain_and_key->private_key;
-}
+/*
+ * 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.
+ */
+
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE
+#endif
+
+#include <s2n.h>
+#include <openssl/x509v3.h>
+#include <openssl/pem.h>
+#include <string.h>
+#include <strings.h>
+
+#include "crypto/s2n_certificate.h"
+#include "utils/s2n_array.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_mem.h"
+
+#include "tls/extensions/s2n_extension_list.h"
+#include "tls/s2n_connection.h"
+
+int s2n_cert_set_cert_type(struct s2n_cert *cert, s2n_pkey_type pkey_type)
+{
+ notnull_check(cert);
+ cert->pkey_type = pkey_type;
+ GUARD(s2n_pkey_setup_for_type(&cert->public_key, pkey_type));
+ return 0;
+}
+
+int s2n_create_cert_chain_from_stuffer(struct s2n_cert_chain *cert_chain_out, struct s2n_stuffer *chain_in_stuffer)
+{
+ DEFER_CLEANUP(struct s2n_stuffer cert_out_stuffer = {0}, s2n_stuffer_free);
+ GUARD(s2n_stuffer_growable_alloc(&cert_out_stuffer, 2048));
+
+ struct s2n_cert **insert = &cert_chain_out->head;
+ uint32_t chain_size = 0;
+ do {
+ struct s2n_cert *new_node = NULL;
+
+ if (s2n_stuffer_certificate_from_pem(chain_in_stuffer, &cert_out_stuffer) < 0) {
+ if (chain_size == 0) {
+ S2N_ERROR(S2N_ERR_NO_CERTIFICATE_IN_PEM);
+ }
+ break;
+ }
+ struct s2n_blob mem = {0};
+ GUARD(s2n_alloc(&mem, sizeof(struct s2n_cert)));
+ new_node = (struct s2n_cert *)(void *)mem.data;
+
+ if (s2n_alloc(&new_node->raw, s2n_stuffer_data_available(&cert_out_stuffer)) != S2N_SUCCESS) {
+ GUARD(s2n_free(&mem));
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+ if (s2n_stuffer_read(&cert_out_stuffer, &new_node->raw) != S2N_SUCCESS) {
+ GUARD(s2n_free(&mem));
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+
+ /* Additional 3 bytes for the length field in the protocol */
+ chain_size += new_node->raw.size + 3;
+ new_node->next = NULL;
+ *insert = new_node;
+ insert = &new_node->next;
+ } while (s2n_stuffer_data_available(chain_in_stuffer));
+
+ /* Leftover data at this point means one of two things:
+ * A bug in s2n's PEM parsing OR a malformed PEM in the user's chain.
+ * Be conservative and fail instead of using a partial chain.
+ */
+ S2N_ERROR_IF(s2n_stuffer_data_available(chain_in_stuffer) > 0, S2N_ERR_INVALID_PEM);
+
+ cert_chain_out->chain_size = chain_size;
+
+ return 0;
+}
+
+int s2n_cert_chain_and_key_set_cert_chain_from_stuffer(struct s2n_cert_chain_and_key *cert_and_key, struct s2n_stuffer *chain_in_stuffer)
+{
+ return s2n_create_cert_chain_from_stuffer(cert_and_key->cert_chain, chain_in_stuffer);
+}
+
+int s2n_cert_chain_and_key_set_cert_chain(struct s2n_cert_chain_and_key *cert_and_key, const char *cert_chain_pem)
+{
+ struct s2n_stuffer chain_in_stuffer = {0};
+
+ /* Turn the chain into a stuffer */
+ GUARD(s2n_stuffer_alloc_ro_from_string(&chain_in_stuffer, cert_chain_pem));
+ int rc = s2n_cert_chain_and_key_set_cert_chain_from_stuffer(cert_and_key, &chain_in_stuffer);
+
+ GUARD(s2n_stuffer_free(&chain_in_stuffer));
+
+ return rc;
+}
+
+int s2n_cert_chain_and_key_set_private_key(struct s2n_cert_chain_and_key *cert_and_key, const char *private_key_pem)
+{
+ DEFER_CLEANUP(struct s2n_stuffer key_in_stuffer = {0}, s2n_stuffer_free);
+ DEFER_CLEANUP(struct s2n_stuffer key_out_stuffer = {0}, s2n_stuffer_free);
+ struct s2n_blob key_blob = {0};
+
+ GUARD(s2n_pkey_zero_init(cert_and_key->private_key));
+
+ /* Put the private key pem in a stuffer */
+ GUARD(s2n_stuffer_alloc_ro_from_string(&key_in_stuffer, private_key_pem));
+ GUARD(s2n_stuffer_growable_alloc(&key_out_stuffer, strlen(private_key_pem)));
+
+ /* Convert pem to asn1 and asn1 to the private key. Handles both PKCS#1 and PKCS#8 formats */
+ GUARD(s2n_stuffer_private_key_from_pem(&key_in_stuffer, &key_out_stuffer));
+ key_blob.size = s2n_stuffer_data_available(&key_out_stuffer);
+ key_blob.data = s2n_stuffer_raw_read(&key_out_stuffer, key_blob.size);
+ notnull_check(key_blob.data);
+
+ /* Get key type and create appropriate key context */
+ GUARD(s2n_asn1der_to_private_key(cert_and_key->private_key, &key_blob));
+
+ return 0;
+}
+
+int s2n_cert_chain_and_key_set_ocsp_data(struct s2n_cert_chain_and_key *chain_and_key, const uint8_t *data, uint32_t length)
+{
+ notnull_check(chain_and_key);
+ GUARD(s2n_free(&chain_and_key->ocsp_status));
+ if (data && length) {
+ GUARD(s2n_alloc(&chain_and_key->ocsp_status, length));
+ memcpy_check(chain_and_key->ocsp_status.data, data, length);
+ }
+ return 0;
+}
+
+int s2n_cert_chain_and_key_set_sct_list(struct s2n_cert_chain_and_key *chain_and_key, const uint8_t *data, uint32_t length)
+{
+ notnull_check(chain_and_key);
+ GUARD(s2n_free(&chain_and_key->sct_list));
+ if (data && length) {
+ GUARD(s2n_alloc(&chain_and_key->sct_list, length));
+ memcpy_check(chain_and_key->sct_list.data, data, length);
+ }
+ return 0;
+}
+
+struct s2n_cert_chain_and_key *s2n_cert_chain_and_key_new(void)
+{
+ struct s2n_cert_chain_and_key *chain_and_key;
+ struct s2n_blob chain_and_key_mem, cert_chain_mem, pkey_mem;
+
+ GUARD_PTR(s2n_alloc(&chain_and_key_mem, sizeof(struct s2n_cert_chain_and_key)));
+ chain_and_key = (struct s2n_cert_chain_and_key *)(void *)chain_and_key_mem.data;
+
+ /* Allocate the memory for the chain and key */
+ if (s2n_alloc(&cert_chain_mem, sizeof(struct s2n_cert_chain)) != S2N_SUCCESS) {
+ goto cleanup;
+ }
+ chain_and_key->cert_chain = (struct s2n_cert_chain *)(void *)cert_chain_mem.data;
+
+ if (s2n_alloc(&pkey_mem, sizeof(s2n_cert_private_key)) != S2N_SUCCESS) {
+ goto cleanup;
+ }
+ chain_and_key->private_key = (s2n_cert_private_key *)(void *)pkey_mem.data;
+
+ chain_and_key->cert_chain->head = NULL;
+ if (s2n_pkey_zero_init(chain_and_key->private_key) != S2N_SUCCESS) {
+ goto cleanup;
+ }
+ memset(&chain_and_key->ocsp_status, 0, sizeof(chain_and_key->ocsp_status));
+ memset(&chain_and_key->sct_list, 0, sizeof(chain_and_key->sct_list));
+ chain_and_key->cn_names = s2n_array_new(sizeof(struct s2n_blob));
+ if (!chain_and_key->cn_names) {
+ goto cleanup;
+ }
+
+ chain_and_key->san_names = s2n_array_new(sizeof(struct s2n_blob));
+ if (!chain_and_key->san_names) {
+ goto cleanup;
+ }
+
+ chain_and_key->context = NULL;
+
+ return chain_and_key;
+ cleanup:
+ s2n_free(&pkey_mem);
+ s2n_free(&cert_chain_mem);
+ s2n_free(&chain_and_key_mem);
+ return NULL;
+}
+
+DEFINE_POINTER_CLEANUP_FUNC(GENERAL_NAMES *, GENERAL_NAMES_free);
+
+int s2n_cert_chain_and_key_load_sans(struct s2n_cert_chain_and_key *chain_and_key, X509 *x509_cert)
+{
+ notnull_check(chain_and_key->san_names);
+
+ DEFER_CLEANUP(GENERAL_NAMES *san_names = X509_get_ext_d2i(x509_cert, NID_subject_alt_name, NULL, NULL), GENERAL_NAMES_free_pointer);
+ if (san_names == NULL) {
+ /* No SAN extension */
+ return 0;
+ }
+
+ const int num_san_names = sk_GENERAL_NAME_num(san_names);
+ for (int i = 0; i < num_san_names; i++) {
+ GENERAL_NAME *san_name = sk_GENERAL_NAME_value(san_names, i);
+ if (!san_name) {
+ continue;
+ }
+
+ if (san_name->type == GEN_DNS) {
+ /* Decoding isn't necessary here since a DNS SAN name is ASCII(type V_ASN1_IA5STRING) */
+ unsigned char *san_str = san_name->d.dNSName->data;
+ const size_t san_str_len = san_name->d.dNSName->length;
+ struct s2n_blob *san_blob = NULL;
+ GUARD_AS_POSIX(s2n_array_pushback(chain_and_key->san_names, (void **)&san_blob));
+ if (!san_blob) {
+ S2N_ERROR(S2N_ERR_NULL_SANS);
+ }
+
+ if (s2n_alloc(san_blob, san_str_len)) {
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+
+ memcpy_check(san_blob->data, san_str, san_str_len);
+ san_blob->size = san_str_len;
+ /* normalize san_blob to lowercase */
+ GUARD(s2n_blob_char_to_lower(san_blob));
+ }
+ }
+
+ return 0;
+}
+
+/* Parse CN names from the Subject of the leaf certificate. Technically there can by multiple CNs
+ * in the Subject but practically very few certificates in the wild will have more than one CN.
+ * Since the data for this certificate is coming from the application and not from an untrusted
+ * source, we will try our best to parse all of the CNs.
+ *
+ * A recent CAB thread proposed removing support for multiple CNs:
+ * https://cabforum.org/pipermail/public/2016-April/007242.html
+ */
+
+DEFINE_POINTER_CLEANUP_FUNC(unsigned char *, OPENSSL_free);
+
+int s2n_cert_chain_and_key_load_cns(struct s2n_cert_chain_and_key *chain_and_key, X509 *x509_cert)
+{
+ notnull_check(chain_and_key->cn_names);
+
+ X509_NAME *subject = X509_get_subject_name(x509_cert);
+ if (!subject) {
+ return 0;
+ }
+
+ int lastpos = -1;
+ while((lastpos = X509_NAME_get_index_by_NID(subject, NID_commonName, lastpos)) >= 0) {
+ X509_NAME_ENTRY *name_entry = X509_NAME_get_entry(subject, lastpos);
+ if (!name_entry) {
+ continue;
+ }
+
+ ASN1_STRING *asn1_str = X509_NAME_ENTRY_get_data(name_entry);
+ if (!asn1_str) {
+ continue;
+ }
+
+ /* We need to try and decode the CN since it may be encoded as unicode with a
+ * direct ASCII equivalent. Any non ASCII bytes in the string will fail later when we
+ * actually compare hostnames.
+ */
+ DEFER_CLEANUP(unsigned char *utf8_str, OPENSSL_free_pointer);
+ const int utf8_out_len = ASN1_STRING_to_UTF8(&utf8_str, asn1_str);
+ if (utf8_out_len < 0) {
+ /* On failure, ASN1_STRING_to_UTF8 does not allocate any memory */
+ continue;
+ } else if (utf8_out_len == 0) {
+ /* We still need to free memory here see https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2017-7521 */
+ OPENSSL_free(utf8_str);
+ } else {
+ struct s2n_blob *cn_name = NULL;
+ GUARD_AS_POSIX(s2n_array_pushback(chain_and_key->cn_names, (void **)&cn_name));
+ if (cn_name == NULL) {
+ S2N_ERROR(S2N_ERR_NULL_CN_NAME);
+ }
+
+ if (s2n_alloc(cn_name, utf8_out_len) < 0) {
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+ memcpy_check(cn_name->data, utf8_str, utf8_out_len);
+ cn_name->size = utf8_out_len;
+ /* normalize cn_name to lowercase */
+ GUARD(s2n_blob_char_to_lower(cn_name));
+ }
+ }
+
+ return 0;
+}
+
+static int s2n_cert_chain_and_key_set_names(struct s2n_cert_chain_and_key *chain_and_key, struct s2n_blob *leaf_bytes)
+{
+ const unsigned char *leaf_der = leaf_bytes->data;
+ X509 *cert = d2i_X509(NULL, &leaf_der, leaf_bytes->size);
+ if (!cert) {
+ S2N_ERROR(S2N_ERR_INVALID_PEM);
+ }
+
+ GUARD(s2n_cert_chain_and_key_load_sans(chain_and_key, cert));
+ /* For current use cases, we *could* avoid populating the common names if any sans were loaded in
+ * s2n_cert_chain_and_key_load_sans. Let's unconditionally populate this field to avoid surprises
+ * in the future.
+ */
+ GUARD(s2n_cert_chain_and_key_load_cns(chain_and_key, cert));
+
+ X509_free(cert);
+ return 0;
+}
+
+int s2n_cert_chain_and_key_load_pem(struct s2n_cert_chain_and_key *chain_and_key, const char *chain_pem, const char *private_key_pem)
+{
+ notnull_check(chain_and_key);
+
+ GUARD(s2n_cert_chain_and_key_set_cert_chain(chain_and_key, chain_pem));
+ GUARD(s2n_cert_chain_and_key_set_private_key(chain_and_key, private_key_pem));
+
+ /* Parse the leaf cert for the public key and certificate type */
+ DEFER_CLEANUP(struct s2n_pkey public_key = {0}, s2n_pkey_free);
+ s2n_pkey_type pkey_type = S2N_PKEY_TYPE_UNKNOWN;
+ GUARD(s2n_asn1der_to_public_key_and_type(&public_key, &pkey_type, &chain_and_key->cert_chain->head->raw));
+ S2N_ERROR_IF(pkey_type == S2N_PKEY_TYPE_UNKNOWN, S2N_ERR_CERT_TYPE_UNSUPPORTED);
+ GUARD(s2n_cert_set_cert_type(chain_and_key->cert_chain->head, pkey_type));
+
+ /* Validate the leaf cert's public key matches the provided private key */
+ GUARD(s2n_pkey_match(&public_key, chain_and_key->private_key));
+
+ /* Populate name information from the SAN/CN for the leaf certificate */
+ GUARD(s2n_cert_chain_and_key_set_names(chain_and_key, &chain_and_key->cert_chain->head->raw));
+
+ return 0;
+}
+
+int s2n_cert_chain_and_key_free(struct s2n_cert_chain_and_key *cert_and_key)
+{
+ if (cert_and_key == NULL) {
+ return 0;
+ }
+
+ /* Walk the chain and free the certs */
+ if (cert_and_key->cert_chain) {
+ struct s2n_cert *node = cert_and_key->cert_chain->head;
+ while (node) {
+ /* Free the cert */
+ GUARD(s2n_free(&node->raw));
+ /* update head so it won't point to freed memory */
+ cert_and_key->cert_chain->head = node->next;
+ /* Free the node */
+ GUARD(s2n_free_object((uint8_t **)&node, sizeof(struct s2n_cert)));
+ node = cert_and_key->cert_chain->head;
+ }
+
+ GUARD(s2n_free_object((uint8_t **)&cert_and_key->cert_chain, sizeof(struct s2n_cert_chain)));
+ }
+
+ if (cert_and_key->private_key) {
+ GUARD(s2n_pkey_free(cert_and_key->private_key));
+ GUARD(s2n_free_object((uint8_t **)&cert_and_key->private_key, sizeof(s2n_cert_private_key)));
+ }
+
+ uint32_t len = 0;
+
+ if (cert_and_key->san_names) {
+ GUARD_AS_POSIX(s2n_array_num_elements(cert_and_key->san_names, &len));
+ for (uint32_t i = 0; i < len; i++) {
+ struct s2n_blob *san_name = NULL;
+ GUARD_AS_POSIX(s2n_array_get(cert_and_key->san_names, i, (void **)&san_name));
+ GUARD(s2n_free(san_name));
+ }
+ GUARD_AS_POSIX(s2n_array_free(cert_and_key->san_names));
+ cert_and_key->san_names = NULL;
+ }
+
+ if (cert_and_key->cn_names) {
+ GUARD_AS_POSIX(s2n_array_num_elements(cert_and_key->cn_names, &len));
+ for (uint32_t i = 0; i < len; i++) {
+ struct s2n_blob *cn_name = NULL;
+ GUARD_AS_POSIX(s2n_array_get(cert_and_key->cn_names, i, (void **)&cn_name));
+ GUARD(s2n_free(cn_name));
+ }
+ GUARD_AS_POSIX(s2n_array_free(cert_and_key->cn_names));
+ cert_and_key->cn_names = NULL;
+ }
+
+ GUARD(s2n_free(&cert_and_key->ocsp_status));
+ GUARD(s2n_free(&cert_and_key->sct_list));
+
+ GUARD(s2n_free_object((uint8_t **)&cert_and_key, sizeof(struct s2n_cert_chain_and_key)));
+ return 0;
+}
+
+int s2n_send_cert_chain(struct s2n_connection *conn, struct s2n_stuffer *out, struct s2n_cert_chain_and_key *chain_and_key)
+{
+ notnull_check(conn);
+ notnull_check(out);
+ notnull_check(chain_and_key);
+ struct s2n_cert_chain *chain = chain_and_key->cert_chain;
+ notnull_check(chain);
+ struct s2n_cert *cur_cert = chain->head;
+ notnull_check(cur_cert);
+
+ struct s2n_stuffer_reservation cert_chain_size = {0};
+ GUARD(s2n_stuffer_reserve_uint24(out, &cert_chain_size));
+
+ /* Send certs and extensions (in TLS 1.3) */
+ bool first_entry = true;
+ while (cur_cert) {
+ notnull_check(cur_cert);
+ GUARD(s2n_stuffer_write_uint24(out, cur_cert->raw.size));
+ GUARD(s2n_stuffer_write_bytes(out, cur_cert->raw.data, cur_cert->raw.size));
+
+ /* According to https://tools.ietf.org/html/rfc8446#section-4.4.2,
+ * If an extension applies to the entire chain, it SHOULD be included in
+ * the first CertificateEntry.
+ * While the spec allow extensions to be included in other certificate
+ * entries, only the first matter to use here */
+ if (conn->actual_protocol_version >= S2N_TLS13) {
+ if (first_entry) {
+ GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_CERTIFICATE, conn, out));
+ first_entry = false;
+ } else {
+ GUARD(s2n_extension_list_send(S2N_EXTENSION_LIST_EMPTY, conn, out));
+ }
+ }
+ cur_cert = cur_cert->next;
+ }
+
+ GUARD(s2n_stuffer_write_vector_size(&cert_chain_size));
+
+ return 0;
+}
+
+int s2n_send_empty_cert_chain(struct s2n_stuffer *out)
+{
+ notnull_check(out);
+ GUARD(s2n_stuffer_write_uint24(out, 0));
+ return 0;
+}
+
+static int s2n_does_cert_san_match_hostname(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name)
+{
+ notnull_check(chain_and_key);
+ notnull_check(dns_name);
+
+ struct s2n_array *san_names = chain_and_key->san_names;
+ uint32_t len = 0;
+ GUARD_AS_POSIX(s2n_array_num_elements(san_names, &len));
+ for (uint32_t i = 0; i < len; i++) {
+ struct s2n_blob *san_name = NULL;
+ GUARD_AS_POSIX(s2n_array_get(san_names, i, (void **)&san_name));
+ notnull_check(san_name);
+ if ((dns_name->size == san_name->size) && (strncasecmp((const char *) dns_name->data, (const char *) san_name->data, dns_name->size) == 0)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int s2n_does_cert_cn_match_hostname(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name)
+{
+ notnull_check(chain_and_key);
+ notnull_check(dns_name);
+
+ struct s2n_array *cn_names = chain_and_key->cn_names;
+ uint32_t len = 0;
+ GUARD_AS_POSIX(s2n_array_num_elements(cn_names, &len));
+ for (uint32_t i = 0; i < len; i++) {
+ struct s2n_blob *cn_name = NULL;
+ GUARD_AS_POSIX(s2n_array_get(cn_names, i, (void **)&cn_name));
+ notnull_check(cn_name);
+ if ((dns_name->size == cn_name->size) && (strncasecmp((const char *) dns_name->data, (const char *) cn_name->data, dns_name->size) == 0)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int s2n_cert_chain_and_key_matches_dns_name(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name)
+{
+ uint32_t len = 0;
+ GUARD_AS_POSIX(s2n_array_num_elements(chain_and_key->san_names, &len));
+ if (len > 0) {
+ if (s2n_does_cert_san_match_hostname(chain_and_key, dns_name)) {
+ return 1;
+ }
+ } else {
+ /* Per https://tools.ietf.org/html/rfc6125#section-6.4.4 we only will
+ * consider the CN for matching if no valid DNS entries are provided
+ * in a SAN.
+ */
+ if (s2n_does_cert_cn_match_hostname(chain_and_key, dns_name)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+int s2n_cert_chain_and_key_set_ctx(struct s2n_cert_chain_and_key *cert_and_key, void *ctx)
+{
+ cert_and_key->context = ctx;
+ return 0;
+}
+
+void *s2n_cert_chain_and_key_get_ctx(struct s2n_cert_chain_and_key *cert_and_key)
+{
+ return cert_and_key->context;
+}
+
+s2n_pkey_type s2n_cert_chain_and_key_get_pkey_type(struct s2n_cert_chain_and_key *chain_and_key)
+{
+ return chain_and_key->cert_chain->head->pkey_type;
+}
+
+s2n_cert_private_key *s2n_cert_chain_and_key_get_private_key(struct s2n_cert_chain_and_key *chain_and_key)
+{
+ ENSURE_REF_PTR(chain_and_key);
+ return chain_and_key->private_key;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_certificate.h b/contrib/restricted/aws/s2n/crypto/s2n_certificate.h
index 2395595641..28b87a44e9 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_certificate.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_certificate.h
@@ -1,75 +1,75 @@
-/*
- * 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 <stdint.h>
-
-#include <openssl/x509.h>
-
-#include <s2n.h>
-#include "crypto/s2n_pkey.h"
-#include "stuffer/s2n_stuffer.h"
-
-#define S2N_CERT_TYPE_COUNT S2N_PKEY_TYPE_SENTINEL
-
-struct s2n_cert {
- s2n_pkey_type pkey_type;
- s2n_cert_public_key public_key;
- struct s2n_blob raw;
- struct s2n_cert *next;
-};
-
-struct s2n_cert_chain {
- uint32_t chain_size;
- struct s2n_cert *head;
-};
-
-struct s2n_cert_chain_and_key {
- struct s2n_cert_chain *cert_chain;
- s2n_cert_private_key *private_key;
- struct s2n_blob ocsp_status;
- struct s2n_blob sct_list;
- /* DNS type SubjectAlternative names from the leaf certificate to match
- * with the server_name extension. We ignore non-DNS SANs here since the
- * server_name extension only supports DNS.
- */
- struct s2n_array *san_names;
- /* CommonName values from the leaf certificate's Subject to match with the
- * server_name extension. Decoded as UTF8.
- */
- struct s2n_array *cn_names;
- /* Application defined data related to this cert. */
- void *context;
-};
-
-struct certs_by_type {
- struct s2n_cert_chain_and_key *certs[S2N_CERT_TYPE_COUNT];
-};
-
-int s2n_cert_chain_and_key_set_ocsp_data(struct s2n_cert_chain_and_key *chain_and_key, const uint8_t *data, uint32_t length);
-int s2n_cert_chain_and_key_set_sct_list(struct s2n_cert_chain_and_key *chain_and_key, const uint8_t *data, uint32_t length);
-/* Exposed for fuzzing */
-int s2n_cert_chain_and_key_load_cns(struct s2n_cert_chain_and_key *chain_and_key, X509 *x509_cert);
-int s2n_cert_chain_and_key_load_sans(struct s2n_cert_chain_and_key *chain_and_key, X509 *x509_cert);
-int s2n_cert_chain_and_key_matches_dns_name(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name);
-
-int s2n_cert_set_cert_type(struct s2n_cert *cert, s2n_pkey_type pkey_type);
-int s2n_send_cert_chain(struct s2n_connection *conn, struct s2n_stuffer *out, struct s2n_cert_chain_and_key *chain_and_key);
-int s2n_send_empty_cert_chain(struct s2n_stuffer *out);
-int s2n_create_cert_chain_from_stuffer(struct s2n_cert_chain *cert_chain_out, struct s2n_stuffer *chain_in_stuffer);
-int s2n_cert_chain_and_key_set_cert_chain(struct s2n_cert_chain_and_key *cert_and_key, const char *cert_chain_pem);
-int s2n_cert_chain_and_key_set_private_key(struct s2n_cert_chain_and_key *cert_and_key, const char *private_key_pem);
-s2n_pkey_type s2n_cert_chain_and_key_get_pkey_type(struct s2n_cert_chain_and_key *chain_and_key);
+/*
+ * 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 <stdint.h>
+
+#include <openssl/x509.h>
+
+#include <s2n.h>
+#include "crypto/s2n_pkey.h"
+#include "stuffer/s2n_stuffer.h"
+
+#define S2N_CERT_TYPE_COUNT S2N_PKEY_TYPE_SENTINEL
+
+struct s2n_cert {
+ s2n_pkey_type pkey_type;
+ s2n_cert_public_key public_key;
+ struct s2n_blob raw;
+ struct s2n_cert *next;
+};
+
+struct s2n_cert_chain {
+ uint32_t chain_size;
+ struct s2n_cert *head;
+};
+
+struct s2n_cert_chain_and_key {
+ struct s2n_cert_chain *cert_chain;
+ s2n_cert_private_key *private_key;
+ struct s2n_blob ocsp_status;
+ struct s2n_blob sct_list;
+ /* DNS type SubjectAlternative names from the leaf certificate to match
+ * with the server_name extension. We ignore non-DNS SANs here since the
+ * server_name extension only supports DNS.
+ */
+ struct s2n_array *san_names;
+ /* CommonName values from the leaf certificate's Subject to match with the
+ * server_name extension. Decoded as UTF8.
+ */
+ struct s2n_array *cn_names;
+ /* Application defined data related to this cert. */
+ void *context;
+};
+
+struct certs_by_type {
+ struct s2n_cert_chain_and_key *certs[S2N_CERT_TYPE_COUNT];
+};
+
+int s2n_cert_chain_and_key_set_ocsp_data(struct s2n_cert_chain_and_key *chain_and_key, const uint8_t *data, uint32_t length);
+int s2n_cert_chain_and_key_set_sct_list(struct s2n_cert_chain_and_key *chain_and_key, const uint8_t *data, uint32_t length);
+/* Exposed for fuzzing */
+int s2n_cert_chain_and_key_load_cns(struct s2n_cert_chain_and_key *chain_and_key, X509 *x509_cert);
+int s2n_cert_chain_and_key_load_sans(struct s2n_cert_chain_and_key *chain_and_key, X509 *x509_cert);
+int s2n_cert_chain_and_key_matches_dns_name(const struct s2n_cert_chain_and_key *chain_and_key, const struct s2n_blob *dns_name);
+
+int s2n_cert_set_cert_type(struct s2n_cert *cert, s2n_pkey_type pkey_type);
+int s2n_send_cert_chain(struct s2n_connection *conn, struct s2n_stuffer *out, struct s2n_cert_chain_and_key *chain_and_key);
+int s2n_send_empty_cert_chain(struct s2n_stuffer *out);
+int s2n_create_cert_chain_from_stuffer(struct s2n_cert_chain *cert_chain_out, struct s2n_stuffer *chain_in_stuffer);
+int s2n_cert_chain_and_key_set_cert_chain(struct s2n_cert_chain_and_key *cert_and_key, const char *cert_chain_pem);
+int s2n_cert_chain_and_key_set_private_key(struct s2n_cert_chain_and_key *cert_and_key, const char *private_key_pem);
+s2n_pkey_type s2n_cert_chain_and_key_get_pkey_type(struct s2n_cert_chain_and_key *chain_and_key);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_cipher.c b/contrib/restricted/aws/s2n/crypto/s2n_cipher.c
index 8a83980518..85333651cb 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_cipher.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_cipher.c
@@ -1,56 +1,56 @@
-/*
- * 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 <openssl/evp.h>
-#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
-#error #include <openssl/mem.h>
-#endif
-
-#include "crypto/s2n_cipher.h"
-
-#include "utils/s2n_safety.h"
-
-int s2n_session_key_alloc(struct s2n_session_key *key)
-{
- eq_check(key->evp_cipher_ctx, NULL);
- notnull_check(key->evp_cipher_ctx = EVP_CIPHER_CTX_new());
-#if defined(S2N_CIPHER_AEAD_API_AVAILABLE)
- eq_check(key->evp_aead_ctx, NULL);
- key->evp_aead_ctx = OPENSSL_malloc(sizeof(EVP_AEAD_CTX));
- if (key->evp_aead_ctx == NULL) {
- EVP_CIPHER_CTX_free(key->evp_cipher_ctx);
- S2N_ERROR_PRESERVE_ERRNO();
- }
- EVP_AEAD_CTX_zero(key->evp_aead_ctx);
-#endif
-
- return 0;
-}
-
-int s2n_session_key_free(struct s2n_session_key *key)
-{
- if (key->evp_cipher_ctx != NULL) {
- EVP_CIPHER_CTX_free(key->evp_cipher_ctx);
- key->evp_cipher_ctx = NULL;
- }
-#if defined(S2N_CIPHER_AEAD_API_AVAILABLE)
- if (key->evp_aead_ctx != NULL) {
- EVP_AEAD_CTX_free(key->evp_aead_ctx);
- key->evp_aead_ctx = NULL;
- }
-#endif
-
- return 0;
-}
+/*
+ * 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 <openssl/evp.h>
+#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+#error #include <openssl/mem.h>
+#endif
+
+#include "crypto/s2n_cipher.h"
+
+#include "utils/s2n_safety.h"
+
+int s2n_session_key_alloc(struct s2n_session_key *key)
+{
+ eq_check(key->evp_cipher_ctx, NULL);
+ notnull_check(key->evp_cipher_ctx = EVP_CIPHER_CTX_new());
+#if defined(S2N_CIPHER_AEAD_API_AVAILABLE)
+ eq_check(key->evp_aead_ctx, NULL);
+ key->evp_aead_ctx = OPENSSL_malloc(sizeof(EVP_AEAD_CTX));
+ if (key->evp_aead_ctx == NULL) {
+ EVP_CIPHER_CTX_free(key->evp_cipher_ctx);
+ S2N_ERROR_PRESERVE_ERRNO();
+ }
+ EVP_AEAD_CTX_zero(key->evp_aead_ctx);
+#endif
+
+ return 0;
+}
+
+int s2n_session_key_free(struct s2n_session_key *key)
+{
+ if (key->evp_cipher_ctx != NULL) {
+ EVP_CIPHER_CTX_free(key->evp_cipher_ctx);
+ key->evp_cipher_ctx = NULL;
+ }
+#if defined(S2N_CIPHER_AEAD_API_AVAILABLE)
+ if (key->evp_aead_ctx != NULL) {
+ EVP_AEAD_CTX_free(key->evp_aead_ctx);
+ key->evp_aead_ctx = NULL;
+ }
+#endif
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_cipher.h b/contrib/restricted/aws/s2n/crypto/s2n_cipher.h
index 811f3e081d..ed1b122828 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_cipher.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_cipher.h
@@ -1,104 +1,104 @@
-/*
- * 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 <openssl/evp.h>
-#include <openssl/aes.h>
-#include <openssl/rc4.h>
-#include <openssl/des.h>
-#include <openssl/rsa.h>
-#include <openssl/dh.h>
-
-#include "crypto/s2n_crypto.h"
-
-#include "utils/s2n_blob.h"
-
-#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
-#define S2N_CIPHER_AEAD_API_AVAILABLE
-#endif
-
-struct s2n_session_key {
- EVP_CIPHER_CTX *evp_cipher_ctx;
-#if defined(S2N_CIPHER_AEAD_API_AVAILABLE)
- EVP_AEAD_CTX *evp_aead_ctx;
-#endif
-};
-
-struct s2n_stream_cipher {
- int (*decrypt) (struct s2n_session_key * key, struct s2n_blob * in, struct s2n_blob * out);
- int (*encrypt) (struct s2n_session_key * key, struct s2n_blob * in, struct s2n_blob * out);
-};
-
-struct s2n_cbc_cipher {
- uint8_t block_size;
- uint8_t record_iv_size;
- int (*decrypt) (struct s2n_session_key * key, struct s2n_blob * iv, struct s2n_blob * in, struct s2n_blob * out);
- int (*encrypt) (struct s2n_session_key * key, struct s2n_blob * iv, struct s2n_blob * in, struct s2n_blob * out);
-};
-
-struct s2n_aead_cipher {
- uint8_t fixed_iv_size;
- uint8_t record_iv_size;
- uint8_t tag_size;
- int (*decrypt) (struct s2n_session_key * key, struct s2n_blob * iv, struct s2n_blob * add, struct s2n_blob * in, struct s2n_blob * out);
- int (*encrypt) (struct s2n_session_key * key, struct s2n_blob * iv, struct s2n_blob * add, struct s2n_blob * in, struct s2n_blob * out);
-};
-
-struct s2n_composite_cipher {
- uint8_t block_size;
- uint8_t record_iv_size;
- uint8_t mac_key_size;
- int (*decrypt) (struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out);
- int (*encrypt) (struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out);
- int (*set_mac_write_key) (struct s2n_session_key *key, uint8_t *mac_key, uint32_t mac_size);
- int (*initial_hmac) (struct s2n_session_key *key, uint8_t *sequence_number, uint8_t content_type, uint16_t protocol_version,
- uint16_t payload_and_eiv_len, int *extra);
-};
-
-struct s2n_cipher {
- enum { S2N_STREAM, S2N_CBC, S2N_AEAD, S2N_COMPOSITE } type;
- union {
- struct s2n_stream_cipher stream;
- struct s2n_aead_cipher aead;
- struct s2n_cbc_cipher cbc;
- struct s2n_composite_cipher comp;
- } io;
- uint8_t key_material_size;
- 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);
-};
-
-extern int s2n_session_key_alloc(struct s2n_session_key *key);
-extern int s2n_session_key_free(struct s2n_session_key *key);
-
-extern struct s2n_cipher s2n_null_cipher;
-extern struct s2n_cipher s2n_rc4;
-extern struct s2n_cipher s2n_aes128;
-extern struct s2n_cipher s2n_aes256;
-extern struct s2n_cipher s2n_3des;
-extern struct s2n_cipher s2n_aes128_gcm;
-extern struct s2n_cipher s2n_aes256_gcm;
-extern struct s2n_cipher s2n_aes128_sha;
-extern struct s2n_cipher s2n_aes256_sha;
-extern struct s2n_cipher s2n_aes128_sha256;
-extern struct s2n_cipher s2n_aes256_sha256;
-extern struct s2n_cipher s2n_chacha20_poly1305;
-
-extern struct s2n_cipher s2n_tls13_aes128_gcm;
-extern struct s2n_cipher s2n_tls13_aes256_gcm;
+/*
+ * 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 <openssl/evp.h>
+#include <openssl/aes.h>
+#include <openssl/rc4.h>
+#include <openssl/des.h>
+#include <openssl/rsa.h>
+#include <openssl/dh.h>
+
+#include "crypto/s2n_crypto.h"
+
+#include "utils/s2n_blob.h"
+
+#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+#define S2N_CIPHER_AEAD_API_AVAILABLE
+#endif
+
+struct s2n_session_key {
+ EVP_CIPHER_CTX *evp_cipher_ctx;
+#if defined(S2N_CIPHER_AEAD_API_AVAILABLE)
+ EVP_AEAD_CTX *evp_aead_ctx;
+#endif
+};
+
+struct s2n_stream_cipher {
+ int (*decrypt) (struct s2n_session_key * key, struct s2n_blob * in, struct s2n_blob * out);
+ int (*encrypt) (struct s2n_session_key * key, struct s2n_blob * in, struct s2n_blob * out);
+};
+
+struct s2n_cbc_cipher {
+ uint8_t block_size;
+ uint8_t record_iv_size;
+ int (*decrypt) (struct s2n_session_key * key, struct s2n_blob * iv, struct s2n_blob * in, struct s2n_blob * out);
+ int (*encrypt) (struct s2n_session_key * key, struct s2n_blob * iv, struct s2n_blob * in, struct s2n_blob * out);
+};
+
+struct s2n_aead_cipher {
+ uint8_t fixed_iv_size;
+ uint8_t record_iv_size;
+ uint8_t tag_size;
+ int (*decrypt) (struct s2n_session_key * key, struct s2n_blob * iv, struct s2n_blob * add, struct s2n_blob * in, struct s2n_blob * out);
+ int (*encrypt) (struct s2n_session_key * key, struct s2n_blob * iv, struct s2n_blob * add, struct s2n_blob * in, struct s2n_blob * out);
+};
+
+struct s2n_composite_cipher {
+ uint8_t block_size;
+ uint8_t record_iv_size;
+ uint8_t mac_key_size;
+ int (*decrypt) (struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out);
+ int (*encrypt) (struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out);
+ int (*set_mac_write_key) (struct s2n_session_key *key, uint8_t *mac_key, uint32_t mac_size);
+ int (*initial_hmac) (struct s2n_session_key *key, uint8_t *sequence_number, uint8_t content_type, uint16_t protocol_version,
+ uint16_t payload_and_eiv_len, int *extra);
+};
+
+struct s2n_cipher {
+ enum { S2N_STREAM, S2N_CBC, S2N_AEAD, S2N_COMPOSITE } type;
+ union {
+ struct s2n_stream_cipher stream;
+ struct s2n_aead_cipher aead;
+ struct s2n_cbc_cipher cbc;
+ struct s2n_composite_cipher comp;
+ } io;
+ uint8_t key_material_size;
+ 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);
+};
+
+extern int s2n_session_key_alloc(struct s2n_session_key *key);
+extern int s2n_session_key_free(struct s2n_session_key *key);
+
+extern struct s2n_cipher s2n_null_cipher;
+extern struct s2n_cipher s2n_rc4;
+extern struct s2n_cipher s2n_aes128;
+extern struct s2n_cipher s2n_aes256;
+extern struct s2n_cipher s2n_3des;
+extern struct s2n_cipher s2n_aes128_gcm;
+extern struct s2n_cipher s2n_aes256_gcm;
+extern struct s2n_cipher s2n_aes128_sha;
+extern struct s2n_cipher s2n_aes256_sha;
+extern struct s2n_cipher s2n_aes128_sha256;
+extern struct s2n_cipher s2n_aes256_sha256;
+extern struct s2n_cipher s2n_chacha20_poly1305;
+
+extern struct s2n_cipher s2n_tls13_aes128_gcm;
+extern struct s2n_cipher s2n_tls13_aes256_gcm;
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_composite_cipher_aes_sha.c b/contrib/restricted/aws/s2n/crypto/s2n_composite_cipher_aes_sha.c
index 60eee634b3..f4cb75ca33 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_composite_cipher_aes_sha.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_composite_cipher_aes_sha.c
@@ -1,363 +1,363 @@
-/*
- * 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 <openssl/aes.h>
-#include <openssl/evp.h>
-#include <openssl/sha.h>
-
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_fips.h"
-#include "crypto/s2n_openssl.h"
-
-#include "tls/s2n_crypto.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-/* LibreSSL, BoringSSL and AWS-LC support the cipher, but the interface is different from Openssl's. We
- * should define a separate s2n_cipher struct for LibreSSL, BoringSSL and AWS-LC.
- */
-#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
-/* Symbols for AES-SHA1-CBC composite ciphers were added in Openssl 1.0.1
- * These composite ciphers exhibit erratic behavior in LibreSSL releases.
- */
-#if S2N_OPENSSL_VERSION_AT_LEAST(1,0,1)
-#define S2N_AES_SHA1_COMPOSITE_AVAILABLE
-#endif
-/* Symbols for AES-SHA256-CBC composite ciphers were added in Openssl 1.0.2
- * See https://www.openssl.org/news/cl102.txt
- * These composite ciphers exhibit erratic behavior in LibreSSL releases.
- */
-#if S2N_OPENSSL_VERSION_AT_LEAST(1,0,2)
-#define S2N_AES_SHA256_COMPOSITE_AVAILABLE
-#endif
-
-#endif
-
-/* Silly accessors, but we avoid using version macro guards in multiple places */
-static const EVP_CIPHER *s2n_evp_aes_128_cbc_hmac_sha1(void)
-{
- #if defined(S2N_AES_SHA1_COMPOSITE_AVAILABLE)
- return EVP_aes_128_cbc_hmac_sha1();
- #else
- return NULL;
- #endif
-}
-
-static const EVP_CIPHER *s2n_evp_aes_256_cbc_hmac_sha1(void)
-{
- #if defined(S2N_AES_SHA1_COMPOSITE_AVAILABLE)
- return EVP_aes_256_cbc_hmac_sha1();
- #else
- return NULL;
- #endif
-}
-
-static const EVP_CIPHER *s2n_evp_aes_128_cbc_hmac_sha256(void)
-{
- #if defined(S2N_AES_SHA256_COMPOSITE_AVAILABLE)
- return EVP_aes_128_cbc_hmac_sha256();
- #else
- return NULL;
- #endif
-}
-
-static const EVP_CIPHER *s2n_evp_aes_256_cbc_hmac_sha256(void)
-{
- #if defined(S2N_AES_SHA256_COMPOSITE_AVAILABLE)
- return EVP_aes_256_cbc_hmac_sha256();
- #else
- return NULL;
- #endif
-}
-
-static uint8_t s2n_composite_cipher_aes128_sha_available(void)
-{
- /* EVP_aes_128_cbc_hmac_sha1() returns NULL if the implementations aren't available.
- * See https://github.com/openssl/openssl/blob/master/crypto/evp/e_aes_cbc_hmac_sha1.c#L952
- *
- * Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
- * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
- * ciphers cause OpenSSL errors due to the lack of the flag.
- */
- return (!s2n_is_in_fips_mode() && s2n_evp_aes_128_cbc_hmac_sha1() ? 1 : 0);
-}
-
-static uint8_t s2n_composite_cipher_aes256_sha_available(void)
-{
- /* Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
- * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
- * ciphers cause OpenSSL errors due to the lack of the flag.
- */
- return (!s2n_is_in_fips_mode() && s2n_evp_aes_256_cbc_hmac_sha1() ? 1 : 0);
-}
-
-static uint8_t s2n_composite_cipher_aes128_sha256_available(void)
-{
- /* Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
- * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
- * ciphers cause OpenSSL errors due to the lack of the flag.
- */
- return (!s2n_is_in_fips_mode() && s2n_evp_aes_128_cbc_hmac_sha256() ? 1 : 0);
-}
-
-static uint8_t s2n_composite_cipher_aes256_sha256_available(void)
-{
- /* Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
- * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
- * ciphers cause OpenSSL errors due to the lack of the flag.
- */
- return (!s2n_is_in_fips_mode() && s2n_evp_aes_256_cbc_hmac_sha256() ? 1 : 0);
-}
-
-static int s2n_composite_cipher_aes_sha_initial_hmac(struct s2n_session_key *key, uint8_t *sequence_number, uint8_t content_type,
- uint16_t protocol_version, uint16_t payload_and_eiv_len, int *extra)
-{
- /* BoringSSL and AWS-LC do not support these composite ciphers with the existing EVP API, and they took out the
- * constants used below. This method should never be called with BoringSSL or AWS-LC because the isAvaliable checked
- * will fail. Instead of defining a possibly dangerous default or hard coding this to 0x16 error out with BoringSSL and AWS-LC.
- */
-#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
- S2N_ERROR(S2N_ERR_NO_SUPPORTED_LIBCRYPTO_API);
-#else
- uint8_t ctrl_buf[S2N_TLS12_AAD_LEN];
- struct s2n_blob ctrl_blob = { .data = ctrl_buf, .size = S2N_TLS12_AAD_LEN };
- struct s2n_stuffer ctrl_stuffer = {0};
- GUARD(s2n_stuffer_init(&ctrl_stuffer, &ctrl_blob));
-
- GUARD(s2n_stuffer_write_bytes(&ctrl_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
- GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, content_type));
- GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, protocol_version / 10));
- GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, protocol_version % 10));
- GUARD(s2n_stuffer_write_uint16(&ctrl_stuffer, payload_and_eiv_len));
-
- /* This will unnecessarily mangle the input buffer, which is fine since it's temporary
- * Return value will be length of digest, padding, and padding length byte.
- * See https://github.com/openssl/openssl/blob/master/crypto/evp/e_aes_cbc_hmac_sha1.c#L814
- * and https://github.com/openssl/openssl/blob/4f0c475719defd7c051964ef9964cc6e5b3a63bf/ssl/record/ssl3_record.c#L743
- */
- int ctrl_ret = EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_TLS1_AAD, S2N_TLS12_AAD_LEN, ctrl_buf);
-
- S2N_ERROR_IF(ctrl_ret < 0, S2N_ERR_INITIAL_HMAC);
-
- *extra = ctrl_ret;
- return 0;
-#endif
-}
-
-static int s2n_composite_cipher_aes_sha_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
-{
- eq_check(out->size, in->size);
-
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
- GUARD_OSSL(EVP_Cipher(key->evp_cipher_ctx, out->data, in->data, in->size), S2N_ERR_ENCRYPT);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes_sha_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
-{
- eq_check(out->size, in->size);
-
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
- GUARD_OSSL(EVP_Cipher(key->evp_cipher_ctx, out->data, in->data, in->size), S2N_ERR_DECRYPT);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes_sha_set_mac_write_key(struct s2n_session_key *key, uint8_t *mac_key, uint32_t mac_size)
-{
- eq_check(mac_size, SHA_DIGEST_LENGTH);
-
- EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, mac_size, mac_key);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes_sha256_set_mac_write_key(struct s2n_session_key *key, uint8_t *mac_key, uint32_t mac_size)
-{
- eq_check(mac_size, SHA256_DIGEST_LENGTH);
-
- EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, mac_size, mac_key);
-
- return 0;
-}
-
-
-static int s2n_composite_cipher_aes128_sha_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 16);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha1(), NULL, in->data, NULL);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes128_sha_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 16);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha1(), NULL, in->data, NULL);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes256_sha_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 32);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha1(), NULL, in->data, NULL);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes256_sha_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 32);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha1(), NULL, in->data, NULL);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes128_sha256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 16);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha256(), NULL, in->data, NULL);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes128_sha256_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 16);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha256(), NULL, in->data, NULL);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes256_sha256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 32);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha256(), NULL, in->data, NULL);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes256_sha256_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 32);
-
- EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
- EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha256(), NULL, in->data, NULL);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes_sha_init(struct s2n_session_key *key)
-{
- s2n_evp_ctx_init(key->evp_cipher_ctx);
-
- return 0;
-}
-
-static int s2n_composite_cipher_aes_sha_destroy_key(struct s2n_session_key *key)
-{
- EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
-
- return 0;
-}
-
-struct s2n_cipher s2n_aes128_sha = {
- .key_material_size = 16,
- .type = S2N_COMPOSITE,
- .io.comp = {
- .block_size = 16,
- .record_iv_size = 16,
- .mac_key_size = SHA_DIGEST_LENGTH,
- .decrypt = s2n_composite_cipher_aes_sha_decrypt,
- .encrypt = s2n_composite_cipher_aes_sha_encrypt,
- .set_mac_write_key = s2n_composite_cipher_aes_sha_set_mac_write_key,
- .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
- .is_available = s2n_composite_cipher_aes128_sha_available,
- .init = s2n_composite_cipher_aes_sha_init,
- .set_encryption_key = s2n_composite_cipher_aes128_sha_set_encryption_key,
- .set_decryption_key = s2n_composite_cipher_aes128_sha_set_decryption_key,
- .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
-};
-
-struct s2n_cipher s2n_aes256_sha = {
- .key_material_size = 32,
- .type = S2N_COMPOSITE,
- .io.comp = {
- .block_size = 16,
- .record_iv_size = 16,
- .mac_key_size = SHA_DIGEST_LENGTH,
- .decrypt = s2n_composite_cipher_aes_sha_decrypt,
- .encrypt = s2n_composite_cipher_aes_sha_encrypt,
- .set_mac_write_key = s2n_composite_cipher_aes_sha_set_mac_write_key,
- .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
- .is_available = s2n_composite_cipher_aes256_sha_available,
- .init = s2n_composite_cipher_aes_sha_init,
- .set_encryption_key = s2n_composite_cipher_aes256_sha_set_encryption_key,
- .set_decryption_key = s2n_composite_cipher_aes256_sha_set_decryption_key,
- .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
-};
-
-struct s2n_cipher s2n_aes128_sha256 = {
- .key_material_size = 16,
- .type = S2N_COMPOSITE,
- .io.comp = {
- .block_size = 16,
- .record_iv_size = 16,
- .mac_key_size = SHA256_DIGEST_LENGTH,
- .decrypt = s2n_composite_cipher_aes_sha_decrypt,
- .encrypt = s2n_composite_cipher_aes_sha_encrypt,
- .set_mac_write_key = s2n_composite_cipher_aes_sha256_set_mac_write_key,
- .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
- .is_available = s2n_composite_cipher_aes128_sha256_available,
- .init = s2n_composite_cipher_aes_sha_init,
- .set_encryption_key = s2n_composite_cipher_aes128_sha256_set_encryption_key,
- .set_decryption_key = s2n_composite_cipher_aes128_sha256_set_decryption_key,
- .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
-};
-
-struct s2n_cipher s2n_aes256_sha256 = {
- .key_material_size = 32,
- .type = S2N_COMPOSITE,
- .io.comp = {
- .block_size = 16,
- .record_iv_size = 16,
- .mac_key_size = SHA256_DIGEST_LENGTH,
- .decrypt = s2n_composite_cipher_aes_sha_decrypt,
- .encrypt = s2n_composite_cipher_aes_sha_encrypt,
- .set_mac_write_key = s2n_composite_cipher_aes_sha256_set_mac_write_key,
- .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
- .is_available = s2n_composite_cipher_aes256_sha256_available,
- .init = s2n_composite_cipher_aes_sha_init,
- .set_encryption_key = s2n_composite_cipher_aes256_sha256_set_encryption_key,
- .set_decryption_key = s2n_composite_cipher_aes256_sha256_set_decryption_key,
- .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
-};
+/*
+ * 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 <openssl/aes.h>
+#include <openssl/evp.h>
+#include <openssl/sha.h>
+
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_fips.h"
+#include "crypto/s2n_openssl.h"
+
+#include "tls/s2n_crypto.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+/* LibreSSL, BoringSSL and AWS-LC support the cipher, but the interface is different from Openssl's. We
+ * should define a separate s2n_cipher struct for LibreSSL, BoringSSL and AWS-LC.
+ */
+#if !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
+/* Symbols for AES-SHA1-CBC composite ciphers were added in Openssl 1.0.1
+ * These composite ciphers exhibit erratic behavior in LibreSSL releases.
+ */
+#if S2N_OPENSSL_VERSION_AT_LEAST(1,0,1)
+#define S2N_AES_SHA1_COMPOSITE_AVAILABLE
+#endif
+/* Symbols for AES-SHA256-CBC composite ciphers were added in Openssl 1.0.2
+ * See https://www.openssl.org/news/cl102.txt
+ * These composite ciphers exhibit erratic behavior in LibreSSL releases.
+ */
+#if S2N_OPENSSL_VERSION_AT_LEAST(1,0,2)
+#define S2N_AES_SHA256_COMPOSITE_AVAILABLE
+#endif
+
+#endif
+
+/* Silly accessors, but we avoid using version macro guards in multiple places */
+static const EVP_CIPHER *s2n_evp_aes_128_cbc_hmac_sha1(void)
+{
+ #if defined(S2N_AES_SHA1_COMPOSITE_AVAILABLE)
+ return EVP_aes_128_cbc_hmac_sha1();
+ #else
+ return NULL;
+ #endif
+}
+
+static const EVP_CIPHER *s2n_evp_aes_256_cbc_hmac_sha1(void)
+{
+ #if defined(S2N_AES_SHA1_COMPOSITE_AVAILABLE)
+ return EVP_aes_256_cbc_hmac_sha1();
+ #else
+ return NULL;
+ #endif
+}
+
+static const EVP_CIPHER *s2n_evp_aes_128_cbc_hmac_sha256(void)
+{
+ #if defined(S2N_AES_SHA256_COMPOSITE_AVAILABLE)
+ return EVP_aes_128_cbc_hmac_sha256();
+ #else
+ return NULL;
+ #endif
+}
+
+static const EVP_CIPHER *s2n_evp_aes_256_cbc_hmac_sha256(void)
+{
+ #if defined(S2N_AES_SHA256_COMPOSITE_AVAILABLE)
+ return EVP_aes_256_cbc_hmac_sha256();
+ #else
+ return NULL;
+ #endif
+}
+
+static uint8_t s2n_composite_cipher_aes128_sha_available(void)
+{
+ /* EVP_aes_128_cbc_hmac_sha1() returns NULL if the implementations aren't available.
+ * See https://github.com/openssl/openssl/blob/master/crypto/evp/e_aes_cbc_hmac_sha1.c#L952
+ *
+ * Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
+ * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
+ * ciphers cause OpenSSL errors due to the lack of the flag.
+ */
+ return (!s2n_is_in_fips_mode() && s2n_evp_aes_128_cbc_hmac_sha1() ? 1 : 0);
+}
+
+static uint8_t s2n_composite_cipher_aes256_sha_available(void)
+{
+ /* Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
+ * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
+ * ciphers cause OpenSSL errors due to the lack of the flag.
+ */
+ return (!s2n_is_in_fips_mode() && s2n_evp_aes_256_cbc_hmac_sha1() ? 1 : 0);
+}
+
+static uint8_t s2n_composite_cipher_aes128_sha256_available(void)
+{
+ /* Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
+ * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
+ * ciphers cause OpenSSL errors due to the lack of the flag.
+ */
+ return (!s2n_is_in_fips_mode() && s2n_evp_aes_128_cbc_hmac_sha256() ? 1 : 0);
+}
+
+static uint8_t s2n_composite_cipher_aes256_sha256_available(void)
+{
+ /* Composite ciphers cannot be used when FIPS mode is set. Ciphers require the
+ * EVP_CIPH_FLAG_FIPS OpenSSL flag to be set for use when in FIPS mode, and composite
+ * ciphers cause OpenSSL errors due to the lack of the flag.
+ */
+ return (!s2n_is_in_fips_mode() && s2n_evp_aes_256_cbc_hmac_sha256() ? 1 : 0);
+}
+
+static int s2n_composite_cipher_aes_sha_initial_hmac(struct s2n_session_key *key, uint8_t *sequence_number, uint8_t content_type,
+ uint16_t protocol_version, uint16_t payload_and_eiv_len, int *extra)
+{
+ /* BoringSSL and AWS-LC do not support these composite ciphers with the existing EVP API, and they took out the
+ * constants used below. This method should never be called with BoringSSL or AWS-LC because the isAvaliable checked
+ * will fail. Instead of defining a possibly dangerous default or hard coding this to 0x16 error out with BoringSSL and AWS-LC.
+ */
+#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC)
+ S2N_ERROR(S2N_ERR_NO_SUPPORTED_LIBCRYPTO_API);
+#else
+ uint8_t ctrl_buf[S2N_TLS12_AAD_LEN];
+ struct s2n_blob ctrl_blob = { .data = ctrl_buf, .size = S2N_TLS12_AAD_LEN };
+ struct s2n_stuffer ctrl_stuffer = {0};
+ GUARD(s2n_stuffer_init(&ctrl_stuffer, &ctrl_blob));
+
+ GUARD(s2n_stuffer_write_bytes(&ctrl_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN));
+ GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, content_type));
+ GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, protocol_version / 10));
+ GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, protocol_version % 10));
+ GUARD(s2n_stuffer_write_uint16(&ctrl_stuffer, payload_and_eiv_len));
+
+ /* This will unnecessarily mangle the input buffer, which is fine since it's temporary
+ * Return value will be length of digest, padding, and padding length byte.
+ * See https://github.com/openssl/openssl/blob/master/crypto/evp/e_aes_cbc_hmac_sha1.c#L814
+ * and https://github.com/openssl/openssl/blob/4f0c475719defd7c051964ef9964cc6e5b3a63bf/ssl/record/ssl3_record.c#L743
+ */
+ int ctrl_ret = EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_TLS1_AAD, S2N_TLS12_AAD_LEN, ctrl_buf);
+
+ S2N_ERROR_IF(ctrl_ret < 0, S2N_ERR_INITIAL_HMAC);
+
+ *extra = ctrl_ret;
+ return 0;
+#endif
+}
+
+static int s2n_composite_cipher_aes_sha_encrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
+{
+ eq_check(out->size, in->size);
+
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
+ GUARD_OSSL(EVP_Cipher(key->evp_cipher_ctx, out->data, in->data, in->size), S2N_ERR_ENCRYPT);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes_sha_decrypt(struct s2n_session_key *key, struct s2n_blob *iv, struct s2n_blob *in, struct s2n_blob *out)
+{
+ eq_check(out->size, in->size);
+
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT);
+ GUARD_OSSL(EVP_Cipher(key->evp_cipher_ctx, out->data, in->data, in->size), S2N_ERR_DECRYPT);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes_sha_set_mac_write_key(struct s2n_session_key *key, uint8_t *mac_key, uint32_t mac_size)
+{
+ eq_check(mac_size, SHA_DIGEST_LENGTH);
+
+ EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, mac_size, mac_key);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes_sha256_set_mac_write_key(struct s2n_session_key *key, uint8_t *mac_key, uint32_t mac_size)
+{
+ eq_check(mac_size, SHA256_DIGEST_LENGTH);
+
+ EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, mac_size, mac_key);
+
+ return 0;
+}
+
+
+static int s2n_composite_cipher_aes128_sha_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 16);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha1(), NULL, in->data, NULL);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes128_sha_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 16);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha1(), NULL, in->data, NULL);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes256_sha_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 32);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha1(), NULL, in->data, NULL);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes256_sha_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 32);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha1(), NULL, in->data, NULL);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes128_sha256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 16);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha256(), NULL, in->data, NULL);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes128_sha256_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 16);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_128_cbc_hmac_sha256(), NULL, in->data, NULL);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes256_sha256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 32);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_EncryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha256(), NULL, in->data, NULL);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes256_sha256_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 32);
+
+ EVP_CIPHER_CTX_set_padding(key->evp_cipher_ctx, EVP_CIPH_NO_PADDING);
+ EVP_DecryptInit_ex(key->evp_cipher_ctx, s2n_evp_aes_256_cbc_hmac_sha256(), NULL, in->data, NULL);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes_sha_init(struct s2n_session_key *key)
+{
+ s2n_evp_ctx_init(key->evp_cipher_ctx);
+
+ return 0;
+}
+
+static int s2n_composite_cipher_aes_sha_destroy_key(struct s2n_session_key *key)
+{
+ EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
+
+ return 0;
+}
+
+struct s2n_cipher s2n_aes128_sha = {
+ .key_material_size = 16,
+ .type = S2N_COMPOSITE,
+ .io.comp = {
+ .block_size = 16,
+ .record_iv_size = 16,
+ .mac_key_size = SHA_DIGEST_LENGTH,
+ .decrypt = s2n_composite_cipher_aes_sha_decrypt,
+ .encrypt = s2n_composite_cipher_aes_sha_encrypt,
+ .set_mac_write_key = s2n_composite_cipher_aes_sha_set_mac_write_key,
+ .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
+ .is_available = s2n_composite_cipher_aes128_sha_available,
+ .init = s2n_composite_cipher_aes_sha_init,
+ .set_encryption_key = s2n_composite_cipher_aes128_sha_set_encryption_key,
+ .set_decryption_key = s2n_composite_cipher_aes128_sha_set_decryption_key,
+ .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
+};
+
+struct s2n_cipher s2n_aes256_sha = {
+ .key_material_size = 32,
+ .type = S2N_COMPOSITE,
+ .io.comp = {
+ .block_size = 16,
+ .record_iv_size = 16,
+ .mac_key_size = SHA_DIGEST_LENGTH,
+ .decrypt = s2n_composite_cipher_aes_sha_decrypt,
+ .encrypt = s2n_composite_cipher_aes_sha_encrypt,
+ .set_mac_write_key = s2n_composite_cipher_aes_sha_set_mac_write_key,
+ .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
+ .is_available = s2n_composite_cipher_aes256_sha_available,
+ .init = s2n_composite_cipher_aes_sha_init,
+ .set_encryption_key = s2n_composite_cipher_aes256_sha_set_encryption_key,
+ .set_decryption_key = s2n_composite_cipher_aes256_sha_set_decryption_key,
+ .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
+};
+
+struct s2n_cipher s2n_aes128_sha256 = {
+ .key_material_size = 16,
+ .type = S2N_COMPOSITE,
+ .io.comp = {
+ .block_size = 16,
+ .record_iv_size = 16,
+ .mac_key_size = SHA256_DIGEST_LENGTH,
+ .decrypt = s2n_composite_cipher_aes_sha_decrypt,
+ .encrypt = s2n_composite_cipher_aes_sha_encrypt,
+ .set_mac_write_key = s2n_composite_cipher_aes_sha256_set_mac_write_key,
+ .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
+ .is_available = s2n_composite_cipher_aes128_sha256_available,
+ .init = s2n_composite_cipher_aes_sha_init,
+ .set_encryption_key = s2n_composite_cipher_aes128_sha256_set_encryption_key,
+ .set_decryption_key = s2n_composite_cipher_aes128_sha256_set_decryption_key,
+ .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
+};
+
+struct s2n_cipher s2n_aes256_sha256 = {
+ .key_material_size = 32,
+ .type = S2N_COMPOSITE,
+ .io.comp = {
+ .block_size = 16,
+ .record_iv_size = 16,
+ .mac_key_size = SHA256_DIGEST_LENGTH,
+ .decrypt = s2n_composite_cipher_aes_sha_decrypt,
+ .encrypt = s2n_composite_cipher_aes_sha_encrypt,
+ .set_mac_write_key = s2n_composite_cipher_aes_sha256_set_mac_write_key,
+ .initial_hmac = s2n_composite_cipher_aes_sha_initial_hmac },
+ .is_available = s2n_composite_cipher_aes256_sha256_available,
+ .init = s2n_composite_cipher_aes_sha_init,
+ .set_encryption_key = s2n_composite_cipher_aes256_sha256_set_encryption_key,
+ .set_decryption_key = s2n_composite_cipher_aes256_sha256_set_decryption_key,
+ .destroy_key = s2n_composite_cipher_aes_sha_destroy_key,
+};
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_crypto.h b/contrib/restricted/aws/s2n/crypto/s2n_crypto.h
index 86e029c361..7f815038e6 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_crypto.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_crypto.h
@@ -1,22 +1,22 @@
-/*
- * 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 <openssl/aes.h>
-#include <openssl/rc4.h>
-#include <openssl/des.h>
-#include <openssl/rsa.h>
-#include <openssl/dh.h>
+/*
+ * 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 <openssl/aes.h>
+#include <openssl/rc4.h>
+#include <openssl/des.h>
+#include <openssl/rsa.h>
+#include <openssl/dh.h>
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_dhe.c b/contrib/restricted/aws/s2n/crypto/s2n_dhe.c
index 9304a4b46f..d755f94789 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_dhe.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_dhe.c
@@ -1,339 +1,339 @@
-/*
- * 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 "crypto/s2n_dhe.h"
-
-#include <openssl/bn.h>
-#include <openssl/dh.h>
-#include <openssl/evp.h>
-#include <stdint.h>
-
-#include "crypto/s2n_openssl.h"
-#include "error/s2n_errno.h"
-#include "stuffer/s2n_stuffer.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_safety.h"
-
-#define S2N_MIN_DH_PRIME_SIZE_BYTES (2048 / 8)
-
-/* Caller is not responsible for freeing values returned by these accessors
- * Per https://www.openssl.org/docs/man1.1.0/crypto/DH_get0_pqg.html
- */
-static const BIGNUM *s2n_get_Ys_dh_param(struct s2n_dh_params *dh_params)
-{
- const BIGNUM *Ys;
-
-/* DH made opaque in Openssl 1.1.0 */
-#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER)
- DH_get0_key(dh_params->dh, &Ys, NULL);
-#else
- Ys = dh_params->dh->pub_key;
-#endif
-
- return Ys;
-}
-
-static const BIGNUM *s2n_get_p_dh_param(struct s2n_dh_params *dh_params)
-{
- const BIGNUM *p;
-#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER)
- DH_get0_pqg(dh_params->dh, &p, NULL, NULL);
-#else
- p = dh_params->dh->p;
-#endif
-
- return p;
-}
-
-static const BIGNUM *s2n_get_g_dh_param(struct s2n_dh_params *dh_params)
-{
- const BIGNUM *g;
-#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER)
- DH_get0_pqg(dh_params->dh, NULL, NULL, &g);
-#else
- g = dh_params->dh->g;
-#endif
-
- return g;
-}
-
-static int s2n_check_p_g_dh_params(struct s2n_dh_params *dh_params)
-{
- notnull_check(dh_params);
- notnull_check(dh_params->dh);
-
- const BIGNUM *p = s2n_get_p_dh_param(dh_params);
- const BIGNUM *g = s2n_get_g_dh_param(dh_params);
-
- notnull_check(g);
- notnull_check(p);
-
- S2N_ERROR_IF(DH_size(dh_params->dh) < S2N_MIN_DH_PRIME_SIZE_BYTES, S2N_ERR_DH_PARAMS_CREATE);
- S2N_ERROR_IF(BN_is_zero(g), S2N_ERR_DH_PARAMS_CREATE);
- S2N_ERROR_IF(BN_is_zero(p), S2N_ERR_DH_PARAMS_CREATE);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_check_pub_key_dh_params(struct s2n_dh_params *dh_params)
-{
- const BIGNUM *pub_key = s2n_get_Ys_dh_param(dh_params);
-
- notnull_check(pub_key);
-
- S2N_ERROR_IF(BN_is_zero(pub_key), S2N_ERR_DH_PARAMS_CREATE);
-
- return S2N_SUCCESS;
-}
-
-static int s2n_set_p_g_Ys_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *p, struct s2n_blob *g,
- struct s2n_blob *Ys)
-{
- ENSURE_POSIX(p->size <= INT_MAX, S2N_ERR_INTEGER_OVERFLOW);
- ENSURE_POSIX(g->size <= INT_MAX, S2N_ERR_INTEGER_OVERFLOW);
- ENSURE_POSIX(Ys->size <= INT_MAX, S2N_ERR_INTEGER_OVERFLOW);
- BIGNUM *bn_p = BN_bin2bn(( const unsigned char * )p->data, p->size, NULL);
- BIGNUM *bn_g = BN_bin2bn(( const unsigned char * )g->data, g->size, NULL);
- BIGNUM *bn_Ys = BN_bin2bn(( const unsigned char * )Ys->data, Ys->size, NULL);
-
-#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER)
- /* Per https://www.openssl.org/docs/man1.1.0/crypto/DH_get0_pqg.html:
- * values that have been passed in should not be freed directly after this function has been called
- */
- GUARD_OSSL(DH_set0_pqg(dh_params->dh, bn_p, NULL, bn_g), S2N_ERR_DH_PARAMS_CREATE);
-
- /* Same as DH_set0_pqg */
- GUARD_OSSL(DH_set0_key(dh_params->dh, bn_Ys, NULL), S2N_ERR_DH_PARAMS_CREATE);
-#else
- dh_params->dh->p = bn_p;
- dh_params->dh->g = bn_g;
- dh_params->dh->pub_key = bn_Ys;
-#endif
-
- return S2N_SUCCESS;
-}
-
-int s2n_check_all_dh_params(struct s2n_dh_params *dh_params)
-{
- GUARD(s2n_check_p_g_dh_params(dh_params));
- GUARD(s2n_check_pub_key_dh_params(dh_params));
-
- return S2N_SUCCESS;
-}
-
-int s2n_pkcs3_to_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *pkcs3)
-{
- notnull_check(dh_params);
- PRECONDITION_POSIX(s2n_blob_validate(pkcs3));
-
- uint8_t *original_ptr = pkcs3->data;
- dh_params->dh = d2i_DHparams(NULL, ( const unsigned char ** )( void * )&pkcs3->data, pkcs3->size);
- GUARD(s2n_check_p_g_dh_params(dh_params));
- if (pkcs3->data - original_ptr != pkcs3->size) {
- DH_free(dh_params->dh);
- S2N_ERROR(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);
- S2N_ERROR(S2N_ERR_DH_TOO_SMALL);
- }
-
- /* Check the generator and prime */
- GUARD(s2n_dh_params_check(dh_params));
-
- return S2N_SUCCESS;
-}
-
-int s2n_dh_p_g_Ys_to_dh_params(struct s2n_dh_params *server_dh_params, struct s2n_blob *p, struct s2n_blob *g,
- struct s2n_blob *Ys)
-{
- ENSURE_POSIX_REF(server_dh_params);
- PRECONDITION_POSIX(s2n_blob_validate(p));
- PRECONDITION_POSIX(s2n_blob_validate(g));
- PRECONDITION_POSIX(s2n_blob_validate(Ys));
-
- server_dh_params->dh = DH_new();
- ENSURE_POSIX(server_dh_params->dh != NULL, S2N_ERR_DH_PARAMS_CREATE);
-
- GUARD(s2n_set_p_g_Ys_dh_params(server_dh_params, p, g, Ys));
- GUARD(s2n_check_all_dh_params(server_dh_params));
-
- return S2N_SUCCESS;
-}
-
-int s2n_dh_params_to_p_g_Ys(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *out, struct s2n_blob *output)
-{
- GUARD(s2n_check_all_dh_params(server_dh_params));
- PRECONDITION_POSIX(s2n_stuffer_validate(out));
- PRECONDITION_POSIX(s2n_blob_validate(output));
-
- const BIGNUM *bn_p = s2n_get_p_dh_param(server_dh_params);
- const BIGNUM *bn_g = s2n_get_g_dh_param(server_dh_params);
- const BIGNUM *bn_Ys = s2n_get_Ys_dh_param(server_dh_params);
-
- uint16_t p_size = BN_num_bytes(bn_p);
- uint16_t g_size = BN_num_bytes(bn_g);
- uint16_t Ys_size = BN_num_bytes(bn_Ys);
- uint8_t *p = NULL;
- uint8_t *g = NULL;
- uint8_t *Ys = NULL;
-
- output->data = s2n_stuffer_raw_write(out, 0);
- notnull_check(output->data);
-
- GUARD(s2n_stuffer_write_uint16(out, p_size));
- p = s2n_stuffer_raw_write(out, p_size);
- notnull_check(p);
- ENSURE_POSIX(BN_bn2bin(bn_p, p) == p_size, S2N_ERR_DH_SERIALIZING);
-
- GUARD(s2n_stuffer_write_uint16(out, g_size));
- g = s2n_stuffer_raw_write(out, g_size);
- notnull_check(g);
- ENSURE_POSIX(BN_bn2bin(bn_g, g) == g_size, S2N_ERR_DH_SERIALIZING);
-
- GUARD(s2n_stuffer_write_uint16(out, Ys_size));
- Ys = s2n_stuffer_raw_write(out, Ys_size);
- notnull_check(Ys);
- ENSURE_POSIX(BN_bn2bin(bn_Ys, Ys) == Ys_size, S2N_ERR_DH_SERIALIZING);
-
- output->size = p_size + 2 + g_size + 2 + Ys_size + 2;
-
- return S2N_SUCCESS;
-}
-
-int s2n_dh_compute_shared_secret_as_client(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_out,
- struct s2n_blob *shared_key)
-{
- struct s2n_dh_params client_params = { 0 };
- uint8_t * client_pub_key = NULL;
- uint16_t client_pub_key_size = 0;
- int shared_key_size = 0;
-
- GUARD(s2n_dh_params_check(server_dh_params));
- GUARD(s2n_dh_params_copy(server_dh_params, &client_params));
- GUARD(s2n_dh_generate_ephemeral_key(&client_params));
- GUARD(s2n_alloc(shared_key, DH_size(server_dh_params->dh)));
-
- const BIGNUM *client_pub_key_bn = s2n_get_Ys_dh_param(&client_params);
- ENSURE_POSIX_REF(client_pub_key_bn);
- client_pub_key_size = BN_num_bytes(client_pub_key_bn);
- GUARD(s2n_stuffer_write_uint16(Yc_out, client_pub_key_size));
- client_pub_key = s2n_stuffer_raw_write(Yc_out, client_pub_key_size);
- if (client_pub_key == NULL) {
- GUARD(s2n_free(shared_key));
- GUARD(s2n_dh_params_free(&client_params));
- S2N_ERROR(S2N_ERR_DH_WRITING_PUBLIC_KEY);
- }
-
- if (BN_bn2bin(client_pub_key_bn, client_pub_key) != client_pub_key_size) {
- GUARD(s2n_free(shared_key));
- GUARD(s2n_dh_params_free(&client_params));
- S2N_ERROR(S2N_ERR_DH_COPYING_PUBLIC_KEY);
- }
-
- /* server_dh_params already validated */
- const BIGNUM *server_pub_key_bn = s2n_get_Ys_dh_param(server_dh_params);
- shared_key_size = DH_compute_key(shared_key->data, server_pub_key_bn, client_params.dh);
- if (shared_key_size < 0) {
- GUARD(s2n_free(shared_key));
- GUARD(s2n_dh_params_free(&client_params));
- S2N_ERROR(S2N_ERR_DH_SHARED_SECRET);
- }
-
- shared_key->size = shared_key_size;
-
- GUARD(s2n_dh_params_free(&client_params));
-
- return S2N_SUCCESS;
-}
-
-int s2n_dh_compute_shared_secret_as_server(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_in,
- struct s2n_blob *shared_key)
-{
- uint16_t Yc_length = 0;
- struct s2n_blob Yc = { 0 };
- int shared_key_size = 0;
- BIGNUM * pub_key = NULL;
-
- GUARD(s2n_check_all_dh_params(server_dh_params));
-
- GUARD(s2n_stuffer_read_uint16(Yc_in, &Yc_length));
- Yc.size = Yc_length;
- Yc.data = s2n_stuffer_raw_read(Yc_in, Yc.size);
- notnull_check(Yc.data);
-
- pub_key = BN_bin2bn(( const unsigned char * )Yc.data, Yc.size, NULL);
- notnull_check(pub_key);
- int server_dh_params_size = DH_size(server_dh_params->dh);
- ENSURE_POSIX(server_dh_params_size <= INT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
- GUARD(s2n_alloc(shared_key, server_dh_params_size));
-
- shared_key_size = DH_compute_key(shared_key->data, pub_key, server_dh_params->dh);
- if (shared_key_size <= 0) {
- BN_free(pub_key);
- S2N_ERROR(S2N_ERR_DH_SHARED_SECRET);
- }
-
- shared_key->size = shared_key_size;
-
- BN_free(pub_key);
-
- return S2N_SUCCESS;
-}
-
-int s2n_dh_params_check(struct s2n_dh_params *dh_params)
-{
- notnull_check(dh_params);
- notnull_check(dh_params->dh);
- int codes = 0;
-
- GUARD_OSSL(DH_check(dh_params->dh, &codes), S2N_ERR_DH_PARAMETER_CHECK);
- ENSURE_POSIX(codes == 0, S2N_ERR_DH_PARAMETER_CHECK);
-
- return S2N_SUCCESS;
-}
-
-int s2n_dh_params_copy(struct s2n_dh_params *from, struct s2n_dh_params *to)
-{
- GUARD(s2n_check_p_g_dh_params(from));
- notnull_check(to);
-
- to->dh = DHparams_dup(from->dh);
- ENSURE_POSIX(to->dh != NULL, S2N_ERR_DH_COPYING_PARAMETERS);
-
- return S2N_SUCCESS;
-}
-
-int s2n_dh_generate_ephemeral_key(struct s2n_dh_params *dh_params)
-{
- GUARD(s2n_check_p_g_dh_params(dh_params));
-
- GUARD_OSSL(DH_generate_key(dh_params->dh), S2N_ERR_DH_GENERATING_PARAMETERS);
-
- return S2N_SUCCESS;
-}
-
-int s2n_dh_params_free(struct s2n_dh_params *dh_params)
-{
- notnull_check(dh_params);
- DH_free(dh_params->dh);
- dh_params->dh = NULL;
-
- return S2N_SUCCESS;
-}
+/*
+ * 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 "crypto/s2n_dhe.h"
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/evp.h>
+#include <stdint.h>
+
+#include "crypto/s2n_openssl.h"
+#include "error/s2n_errno.h"
+#include "stuffer/s2n_stuffer.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_safety.h"
+
+#define S2N_MIN_DH_PRIME_SIZE_BYTES (2048 / 8)
+
+/* Caller is not responsible for freeing values returned by these accessors
+ * Per https://www.openssl.org/docs/man1.1.0/crypto/DH_get0_pqg.html
+ */
+static const BIGNUM *s2n_get_Ys_dh_param(struct s2n_dh_params *dh_params)
+{
+ const BIGNUM *Ys;
+
+/* DH made opaque in Openssl 1.1.0 */
+#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER)
+ DH_get0_key(dh_params->dh, &Ys, NULL);
+#else
+ Ys = dh_params->dh->pub_key;
+#endif
+
+ return Ys;
+}
+
+static const BIGNUM *s2n_get_p_dh_param(struct s2n_dh_params *dh_params)
+{
+ const BIGNUM *p;
+#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER)
+ DH_get0_pqg(dh_params->dh, &p, NULL, NULL);
+#else
+ p = dh_params->dh->p;
+#endif
+
+ return p;
+}
+
+static const BIGNUM *s2n_get_g_dh_param(struct s2n_dh_params *dh_params)
+{
+ const BIGNUM *g;
+#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER)
+ DH_get0_pqg(dh_params->dh, NULL, NULL, &g);
+#else
+ g = dh_params->dh->g;
+#endif
+
+ return g;
+}
+
+static int s2n_check_p_g_dh_params(struct s2n_dh_params *dh_params)
+{
+ notnull_check(dh_params);
+ notnull_check(dh_params->dh);
+
+ const BIGNUM *p = s2n_get_p_dh_param(dh_params);
+ const BIGNUM *g = s2n_get_g_dh_param(dh_params);
+
+ notnull_check(g);
+ notnull_check(p);
+
+ S2N_ERROR_IF(DH_size(dh_params->dh) < S2N_MIN_DH_PRIME_SIZE_BYTES, S2N_ERR_DH_PARAMS_CREATE);
+ S2N_ERROR_IF(BN_is_zero(g), S2N_ERR_DH_PARAMS_CREATE);
+ S2N_ERROR_IF(BN_is_zero(p), S2N_ERR_DH_PARAMS_CREATE);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_check_pub_key_dh_params(struct s2n_dh_params *dh_params)
+{
+ const BIGNUM *pub_key = s2n_get_Ys_dh_param(dh_params);
+
+ notnull_check(pub_key);
+
+ S2N_ERROR_IF(BN_is_zero(pub_key), S2N_ERR_DH_PARAMS_CREATE);
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_set_p_g_Ys_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *p, struct s2n_blob *g,
+ struct s2n_blob *Ys)
+{
+ ENSURE_POSIX(p->size <= INT_MAX, S2N_ERR_INTEGER_OVERFLOW);
+ ENSURE_POSIX(g->size <= INT_MAX, S2N_ERR_INTEGER_OVERFLOW);
+ ENSURE_POSIX(Ys->size <= INT_MAX, S2N_ERR_INTEGER_OVERFLOW);
+ BIGNUM *bn_p = BN_bin2bn(( const unsigned char * )p->data, p->size, NULL);
+ BIGNUM *bn_g = BN_bin2bn(( const unsigned char * )g->data, g->size, NULL);
+ BIGNUM *bn_Ys = BN_bin2bn(( const unsigned char * )Ys->data, Ys->size, NULL);
+
+#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER)
+ /* Per https://www.openssl.org/docs/man1.1.0/crypto/DH_get0_pqg.html:
+ * values that have been passed in should not be freed directly after this function has been called
+ */
+ GUARD_OSSL(DH_set0_pqg(dh_params->dh, bn_p, NULL, bn_g), S2N_ERR_DH_PARAMS_CREATE);
+
+ /* Same as DH_set0_pqg */
+ GUARD_OSSL(DH_set0_key(dh_params->dh, bn_Ys, NULL), S2N_ERR_DH_PARAMS_CREATE);
+#else
+ dh_params->dh->p = bn_p;
+ dh_params->dh->g = bn_g;
+ dh_params->dh->pub_key = bn_Ys;
+#endif
+
+ return S2N_SUCCESS;
+}
+
+int s2n_check_all_dh_params(struct s2n_dh_params *dh_params)
+{
+ GUARD(s2n_check_p_g_dh_params(dh_params));
+ GUARD(s2n_check_pub_key_dh_params(dh_params));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_pkcs3_to_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *pkcs3)
+{
+ notnull_check(dh_params);
+ PRECONDITION_POSIX(s2n_blob_validate(pkcs3));
+
+ uint8_t *original_ptr = pkcs3->data;
+ dh_params->dh = d2i_DHparams(NULL, ( const unsigned char ** )( void * )&pkcs3->data, pkcs3->size);
+ GUARD(s2n_check_p_g_dh_params(dh_params));
+ if (pkcs3->data - original_ptr != pkcs3->size) {
+ DH_free(dh_params->dh);
+ S2N_ERROR(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);
+ S2N_ERROR(S2N_ERR_DH_TOO_SMALL);
+ }
+
+ /* Check the generator and prime */
+ GUARD(s2n_dh_params_check(dh_params));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_dh_p_g_Ys_to_dh_params(struct s2n_dh_params *server_dh_params, struct s2n_blob *p, struct s2n_blob *g,
+ struct s2n_blob *Ys)
+{
+ ENSURE_POSIX_REF(server_dh_params);
+ PRECONDITION_POSIX(s2n_blob_validate(p));
+ PRECONDITION_POSIX(s2n_blob_validate(g));
+ PRECONDITION_POSIX(s2n_blob_validate(Ys));
+
+ server_dh_params->dh = DH_new();
+ ENSURE_POSIX(server_dh_params->dh != NULL, S2N_ERR_DH_PARAMS_CREATE);
+
+ GUARD(s2n_set_p_g_Ys_dh_params(server_dh_params, p, g, Ys));
+ GUARD(s2n_check_all_dh_params(server_dh_params));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_dh_params_to_p_g_Ys(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *out, struct s2n_blob *output)
+{
+ GUARD(s2n_check_all_dh_params(server_dh_params));
+ PRECONDITION_POSIX(s2n_stuffer_validate(out));
+ PRECONDITION_POSIX(s2n_blob_validate(output));
+
+ const BIGNUM *bn_p = s2n_get_p_dh_param(server_dh_params);
+ const BIGNUM *bn_g = s2n_get_g_dh_param(server_dh_params);
+ const BIGNUM *bn_Ys = s2n_get_Ys_dh_param(server_dh_params);
+
+ uint16_t p_size = BN_num_bytes(bn_p);
+ uint16_t g_size = BN_num_bytes(bn_g);
+ uint16_t Ys_size = BN_num_bytes(bn_Ys);
+ uint8_t *p = NULL;
+ uint8_t *g = NULL;
+ uint8_t *Ys = NULL;
+
+ output->data = s2n_stuffer_raw_write(out, 0);
+ notnull_check(output->data);
+
+ GUARD(s2n_stuffer_write_uint16(out, p_size));
+ p = s2n_stuffer_raw_write(out, p_size);
+ notnull_check(p);
+ ENSURE_POSIX(BN_bn2bin(bn_p, p) == p_size, S2N_ERR_DH_SERIALIZING);
+
+ GUARD(s2n_stuffer_write_uint16(out, g_size));
+ g = s2n_stuffer_raw_write(out, g_size);
+ notnull_check(g);
+ ENSURE_POSIX(BN_bn2bin(bn_g, g) == g_size, S2N_ERR_DH_SERIALIZING);
+
+ GUARD(s2n_stuffer_write_uint16(out, Ys_size));
+ Ys = s2n_stuffer_raw_write(out, Ys_size);
+ notnull_check(Ys);
+ ENSURE_POSIX(BN_bn2bin(bn_Ys, Ys) == Ys_size, S2N_ERR_DH_SERIALIZING);
+
+ output->size = p_size + 2 + g_size + 2 + Ys_size + 2;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_dh_compute_shared_secret_as_client(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_out,
+ struct s2n_blob *shared_key)
+{
+ struct s2n_dh_params client_params = { 0 };
+ uint8_t * client_pub_key = NULL;
+ uint16_t client_pub_key_size = 0;
+ int shared_key_size = 0;
+
+ GUARD(s2n_dh_params_check(server_dh_params));
+ GUARD(s2n_dh_params_copy(server_dh_params, &client_params));
+ GUARD(s2n_dh_generate_ephemeral_key(&client_params));
+ GUARD(s2n_alloc(shared_key, DH_size(server_dh_params->dh)));
+
+ const BIGNUM *client_pub_key_bn = s2n_get_Ys_dh_param(&client_params);
+ ENSURE_POSIX_REF(client_pub_key_bn);
+ client_pub_key_size = BN_num_bytes(client_pub_key_bn);
+ GUARD(s2n_stuffer_write_uint16(Yc_out, client_pub_key_size));
+ client_pub_key = s2n_stuffer_raw_write(Yc_out, client_pub_key_size);
+ if (client_pub_key == NULL) {
+ GUARD(s2n_free(shared_key));
+ GUARD(s2n_dh_params_free(&client_params));
+ S2N_ERROR(S2N_ERR_DH_WRITING_PUBLIC_KEY);
+ }
+
+ if (BN_bn2bin(client_pub_key_bn, client_pub_key) != client_pub_key_size) {
+ GUARD(s2n_free(shared_key));
+ GUARD(s2n_dh_params_free(&client_params));
+ S2N_ERROR(S2N_ERR_DH_COPYING_PUBLIC_KEY);
+ }
+
+ /* server_dh_params already validated */
+ const BIGNUM *server_pub_key_bn = s2n_get_Ys_dh_param(server_dh_params);
+ shared_key_size = DH_compute_key(shared_key->data, server_pub_key_bn, client_params.dh);
+ if (shared_key_size < 0) {
+ GUARD(s2n_free(shared_key));
+ GUARD(s2n_dh_params_free(&client_params));
+ S2N_ERROR(S2N_ERR_DH_SHARED_SECRET);
+ }
+
+ shared_key->size = shared_key_size;
+
+ GUARD(s2n_dh_params_free(&client_params));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_dh_compute_shared_secret_as_server(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_in,
+ struct s2n_blob *shared_key)
+{
+ uint16_t Yc_length = 0;
+ struct s2n_blob Yc = { 0 };
+ int shared_key_size = 0;
+ BIGNUM * pub_key = NULL;
+
+ GUARD(s2n_check_all_dh_params(server_dh_params));
+
+ GUARD(s2n_stuffer_read_uint16(Yc_in, &Yc_length));
+ Yc.size = Yc_length;
+ Yc.data = s2n_stuffer_raw_read(Yc_in, Yc.size);
+ notnull_check(Yc.data);
+
+ pub_key = BN_bin2bn(( const unsigned char * )Yc.data, Yc.size, NULL);
+ notnull_check(pub_key);
+ int server_dh_params_size = DH_size(server_dh_params->dh);
+ ENSURE_POSIX(server_dh_params_size <= INT32_MAX, S2N_ERR_INTEGER_OVERFLOW);
+ GUARD(s2n_alloc(shared_key, server_dh_params_size));
+
+ shared_key_size = DH_compute_key(shared_key->data, pub_key, server_dh_params->dh);
+ if (shared_key_size <= 0) {
+ BN_free(pub_key);
+ S2N_ERROR(S2N_ERR_DH_SHARED_SECRET);
+ }
+
+ shared_key->size = shared_key_size;
+
+ BN_free(pub_key);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_dh_params_check(struct s2n_dh_params *dh_params)
+{
+ notnull_check(dh_params);
+ notnull_check(dh_params->dh);
+ int codes = 0;
+
+ GUARD_OSSL(DH_check(dh_params->dh, &codes), S2N_ERR_DH_PARAMETER_CHECK);
+ ENSURE_POSIX(codes == 0, S2N_ERR_DH_PARAMETER_CHECK);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_dh_params_copy(struct s2n_dh_params *from, struct s2n_dh_params *to)
+{
+ GUARD(s2n_check_p_g_dh_params(from));
+ notnull_check(to);
+
+ to->dh = DHparams_dup(from->dh);
+ ENSURE_POSIX(to->dh != NULL, S2N_ERR_DH_COPYING_PARAMETERS);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_dh_generate_ephemeral_key(struct s2n_dh_params *dh_params)
+{
+ GUARD(s2n_check_p_g_dh_params(dh_params));
+
+ GUARD_OSSL(DH_generate_key(dh_params->dh), S2N_ERR_DH_GENERATING_PARAMETERS);
+
+ return S2N_SUCCESS;
+}
+
+int s2n_dh_params_free(struct s2n_dh_params *dh_params)
+{
+ notnull_check(dh_params);
+ DH_free(dh_params->dh);
+ dh_params->dh = NULL;
+
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_dhe.h b/contrib/restricted/aws/s2n/crypto/s2n_dhe.h
index f9e004e5e5..483462a413 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_dhe.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_dhe.h
@@ -1,36 +1,36 @@
-/*
- * 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 <openssl/dh.h>
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "utils/s2n_blob.h"
-
-struct s2n_dh_params {
- DH *dh;
-};
-
-extern int s2n_pkcs3_to_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *pkcs3);
-extern int s2n_dh_p_g_Ys_to_dh_params(struct s2n_dh_params *server_dh_params, struct s2n_blob *p, struct s2n_blob *g, struct s2n_blob *ys);
-extern int s2n_dh_params_to_p_g_Ys(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *out, struct s2n_blob *output);
-extern int s2n_dh_compute_shared_secret_as_server(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_in, struct s2n_blob *shared_key);
-extern int s2n_dh_compute_shared_secret_as_client(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_out, struct s2n_blob *shared_key);
-extern int s2n_dh_params_copy(struct s2n_dh_params *from, struct s2n_dh_params *to);
-extern int s2n_dh_params_check(struct s2n_dh_params *dh_params);
-extern int s2n_dh_generate_ephemeral_key(struct s2n_dh_params *dh_params);
-extern int s2n_dh_params_free(struct s2n_dh_params *dh_params);
+/*
+ * 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 <openssl/dh.h>
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "utils/s2n_blob.h"
+
+struct s2n_dh_params {
+ DH *dh;
+};
+
+extern int s2n_pkcs3_to_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *pkcs3);
+extern int s2n_dh_p_g_Ys_to_dh_params(struct s2n_dh_params *server_dh_params, struct s2n_blob *p, struct s2n_blob *g, struct s2n_blob *ys);
+extern int s2n_dh_params_to_p_g_Ys(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *out, struct s2n_blob *output);
+extern int s2n_dh_compute_shared_secret_as_server(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_in, struct s2n_blob *shared_key);
+extern int s2n_dh_compute_shared_secret_as_client(struct s2n_dh_params *server_dh_params, struct s2n_stuffer *Yc_out, struct s2n_blob *shared_key);
+extern int s2n_dh_params_copy(struct s2n_dh_params *from, struct s2n_dh_params *to);
+extern int s2n_dh_params_check(struct s2n_dh_params *dh_params);
+extern int s2n_dh_generate_ephemeral_key(struct s2n_dh_params *dh_params);
+extern int s2n_dh_params_free(struct s2n_dh_params *dh_params);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_drbg.c b/contrib/restricted/aws/s2n/crypto/s2n_drbg.c
index abcd819e04..bd1e78cc47 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_drbg.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_drbg.c
@@ -1,228 +1,228 @@
-/*
- * 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 <sys/param.h>
-
-#include <openssl/evp.h>
-
-#include "crypto/s2n_drbg.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_blob.h"
-
-#define s2n_drbg_key_size(drgb) EVP_CIPHER_CTX_key_length((drbg)->ctx)
-#define s2n_drbg_seed_size(drgb) (S2N_DRBG_BLOCK_SIZE + s2n_drbg_key_size(drgb))
-
-/* This function is the same as s2n_increment_sequence_number
- but it does not check for overflow, since overflow is
- acceptable in DRBG */
-int s2n_increment_drbg_counter(struct s2n_blob *counter)
-{
- for (int i = counter->size - 1; i >= 0; i--) {
- counter->data[i] += 1;
- if (counter->data[i]) {
- break;
- }
-
- /* seq[i] wrapped, so let it carry */
- }
- return 0;
-}
-
-static int s2n_drbg_block_encrypt(EVP_CIPHER_CTX * ctx, uint8_t in[S2N_DRBG_BLOCK_SIZE], uint8_t out[S2N_DRBG_BLOCK_SIZE])
-{
- notnull_check(ctx);
- int len = S2N_DRBG_BLOCK_SIZE;
- GUARD_OSSL(EVP_EncryptUpdate(ctx, out, &len, in, S2N_DRBG_BLOCK_SIZE), S2N_ERR_DRBG);
- eq_check(len, S2N_DRBG_BLOCK_SIZE);
-
- return 0;
-}
-
-static int s2n_drbg_bits(struct s2n_drbg *drbg, struct s2n_blob *out)
-{
- notnull_check(drbg);
- notnull_check(drbg->ctx);
- notnull_check(out);
-
- struct s2n_blob value = {0};
- GUARD(s2n_blob_init(&value, drbg->v, sizeof(drbg->v)));
- int block_aligned_size = out->size - (out->size % S2N_DRBG_BLOCK_SIZE);
-
- /* Per NIST SP800-90A 10.2.1.2: */
- for (int i = 0; i < block_aligned_size; i += S2N_DRBG_BLOCK_SIZE) {
- GUARD(s2n_increment_drbg_counter(&value));
- GUARD(s2n_drbg_block_encrypt(drbg->ctx, drbg->v, out->data + i));
- drbg->bytes_used += S2N_DRBG_BLOCK_SIZE;
- }
-
- if (out->size <= block_aligned_size) {
- return 0;
- }
-
- uint8_t spare_block[S2N_DRBG_BLOCK_SIZE];
- GUARD(s2n_increment_drbg_counter(&value));
- GUARD(s2n_drbg_block_encrypt(drbg->ctx, drbg->v, spare_block));
- drbg->bytes_used += S2N_DRBG_BLOCK_SIZE;
-
- memcpy_check(out->data + block_aligned_size, spare_block, out->size - block_aligned_size);
-
- return 0;
-}
-
-static int s2n_drbg_update(struct s2n_drbg *drbg, struct s2n_blob *provided_data)
-{
- notnull_check(drbg);
- notnull_check(drbg->ctx);
-
- s2n_stack_blob(temp_blob, s2n_drbg_seed_size(drgb), S2N_DRBG_MAX_SEED_SIZE);
-
- eq_check(provided_data->size, s2n_drbg_seed_size(drbg));
-
- GUARD(s2n_drbg_bits(drbg, &temp_blob));
-
- /* XOR in the provided data */
- for (int i = 0; i < provided_data->size; i++) {
- temp_blob.data[i] ^= provided_data->data[i];
- }
-
- /* Update the key and value */
- GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, NULL, NULL, temp_blob.data, NULL), S2N_ERR_DRBG);
-
- memcpy_check(drbg->v, temp_blob.data + s2n_drbg_key_size(drbg), S2N_DRBG_BLOCK_SIZE);
-
- return 0;
-}
-
-static int s2n_drbg_mix_in_entropy(struct s2n_drbg *drbg, struct s2n_blob *entropy, struct s2n_blob *ps)
-{
- notnull_check(drbg);
- notnull_check(drbg->ctx);
- notnull_check(entropy);
-
- gte_check(entropy->size, ps->size);
-
- for (int i = 0; i < ps->size; i++) {
- entropy->data[i] ^= ps->data[i];
- }
-
- GUARD(s2n_drbg_update(drbg, entropy));
-
- return 0;
-}
-
-static int s2n_drbg_seed(struct s2n_drbg *drbg, struct s2n_blob *ps)
-{
- s2n_stack_blob(blob, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
-
- GUARD_AS_POSIX(s2n_get_seed_entropy(&blob));
- GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps));
-
- drbg->bytes_used = 0;
-
- return 0;
-}
-
-static int s2n_drbg_mix(struct s2n_drbg *drbg, struct s2n_blob *ps)
-{
- s2n_stack_blob(blob, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
-
- GUARD_AS_POSIX(s2n_get_mix_entropy(&blob));
- GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps));
-
- drbg->mixes += 1;
-
- return 0;
-}
-
-int s2n_drbg_instantiate(struct s2n_drbg *drbg, struct s2n_blob *personalization_string, const s2n_drbg_mode mode)
-{
- notnull_check(drbg);
-
- drbg->ctx = EVP_CIPHER_CTX_new();
- S2N_ERROR_IF(!drbg->ctx, S2N_ERR_DRBG);
-
- s2n_evp_ctx_init(drbg->ctx);
-
- switch(mode) {
- case S2N_AES_128_CTR_NO_DF_PR:
- GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_128_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG);
- break;
- case S2N_AES_256_CTR_NO_DF_PR:
- GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_256_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG);
- break;
- default:
- S2N_ERROR(S2N_ERR_DRBG);
- }
-
- lte_check(s2n_drbg_key_size(drbg), S2N_DRBG_MAX_KEY_SIZE);
- lte_check(s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
-
- static const uint8_t zero_key[S2N_DRBG_MAX_KEY_SIZE] = {0};
-
- /* Start off with zeroed data, per 10.2.1.3.1 item 4 and 5 */
- memset(drbg->v, 0, sizeof(drbg->v));
- GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, NULL, NULL, zero_key, NULL), S2N_ERR_DRBG);
-
- /* Copy the personalization string */
- s2n_stack_blob(ps, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
- GUARD(s2n_blob_zero(&ps));
-
- memcpy_check(ps.data, personalization_string->data, MIN(ps.size, personalization_string->size));
-
- /* Seed the DRBG */
- GUARD(s2n_drbg_seed(drbg, &ps));
-
- return 0;
-}
-
-int s2n_drbg_generate(struct s2n_drbg *drbg, struct s2n_blob *blob)
-{
- notnull_check(drbg);
- notnull_check(drbg->ctx);
- s2n_stack_blob(zeros, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
-
- S2N_ERROR_IF(blob->size > S2N_DRBG_GENERATE_LIMIT, S2N_ERR_DRBG_REQUEST_SIZE);
-
- /* Always mix in additional entropy, for prediction resistance */
- GUARD(s2n_drbg_mix(drbg, &zeros));
- GUARD(s2n_drbg_bits(drbg, blob));
- GUARD(s2n_drbg_update(drbg, &zeros));
-
- return 0;
-}
-
-int s2n_drbg_wipe(struct s2n_drbg *drbg)
-{
- notnull_check(drbg);
- if (drbg->ctx) {
- GUARD_OSSL(EVP_CIPHER_CTX_cleanup(drbg->ctx), S2N_ERR_DRBG);
-
- EVP_CIPHER_CTX_free(drbg->ctx);
- drbg->ctx = NULL;
- }
-
- *drbg = (struct s2n_drbg) {0};
- return 0;
-}
-
-int s2n_drbg_bytes_used(struct s2n_drbg *drbg, uint64_t *bytes_used)
-{
- notnull_check(drbg);
- notnull_check(bytes_used);
- *bytes_used = drbg->bytes_used;
- return 0;
-}
+/*
+ * 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 <sys/param.h>
+
+#include <openssl/evp.h>
+
+#include "crypto/s2n_drbg.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_blob.h"
+
+#define s2n_drbg_key_size(drgb) EVP_CIPHER_CTX_key_length((drbg)->ctx)
+#define s2n_drbg_seed_size(drgb) (S2N_DRBG_BLOCK_SIZE + s2n_drbg_key_size(drgb))
+
+/* This function is the same as s2n_increment_sequence_number
+ but it does not check for overflow, since overflow is
+ acceptable in DRBG */
+int s2n_increment_drbg_counter(struct s2n_blob *counter)
+{
+ for (int i = counter->size - 1; i >= 0; i--) {
+ counter->data[i] += 1;
+ if (counter->data[i]) {
+ break;
+ }
+
+ /* seq[i] wrapped, so let it carry */
+ }
+ return 0;
+}
+
+static int s2n_drbg_block_encrypt(EVP_CIPHER_CTX * ctx, uint8_t in[S2N_DRBG_BLOCK_SIZE], uint8_t out[S2N_DRBG_BLOCK_SIZE])
+{
+ notnull_check(ctx);
+ int len = S2N_DRBG_BLOCK_SIZE;
+ GUARD_OSSL(EVP_EncryptUpdate(ctx, out, &len, in, S2N_DRBG_BLOCK_SIZE), S2N_ERR_DRBG);
+ eq_check(len, S2N_DRBG_BLOCK_SIZE);
+
+ return 0;
+}
+
+static int s2n_drbg_bits(struct s2n_drbg *drbg, struct s2n_blob *out)
+{
+ notnull_check(drbg);
+ notnull_check(drbg->ctx);
+ notnull_check(out);
+
+ struct s2n_blob value = {0};
+ GUARD(s2n_blob_init(&value, drbg->v, sizeof(drbg->v)));
+ int block_aligned_size = out->size - (out->size % S2N_DRBG_BLOCK_SIZE);
+
+ /* Per NIST SP800-90A 10.2.1.2: */
+ for (int i = 0; i < block_aligned_size; i += S2N_DRBG_BLOCK_SIZE) {
+ GUARD(s2n_increment_drbg_counter(&value));
+ GUARD(s2n_drbg_block_encrypt(drbg->ctx, drbg->v, out->data + i));
+ drbg->bytes_used += S2N_DRBG_BLOCK_SIZE;
+ }
+
+ if (out->size <= block_aligned_size) {
+ return 0;
+ }
+
+ uint8_t spare_block[S2N_DRBG_BLOCK_SIZE];
+ GUARD(s2n_increment_drbg_counter(&value));
+ GUARD(s2n_drbg_block_encrypt(drbg->ctx, drbg->v, spare_block));
+ drbg->bytes_used += S2N_DRBG_BLOCK_SIZE;
+
+ memcpy_check(out->data + block_aligned_size, spare_block, out->size - block_aligned_size);
+
+ return 0;
+}
+
+static int s2n_drbg_update(struct s2n_drbg *drbg, struct s2n_blob *provided_data)
+{
+ notnull_check(drbg);
+ notnull_check(drbg->ctx);
+
+ s2n_stack_blob(temp_blob, s2n_drbg_seed_size(drgb), S2N_DRBG_MAX_SEED_SIZE);
+
+ eq_check(provided_data->size, s2n_drbg_seed_size(drbg));
+
+ GUARD(s2n_drbg_bits(drbg, &temp_blob));
+
+ /* XOR in the provided data */
+ for (int i = 0; i < provided_data->size; i++) {
+ temp_blob.data[i] ^= provided_data->data[i];
+ }
+
+ /* Update the key and value */
+ GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, NULL, NULL, temp_blob.data, NULL), S2N_ERR_DRBG);
+
+ memcpy_check(drbg->v, temp_blob.data + s2n_drbg_key_size(drbg), S2N_DRBG_BLOCK_SIZE);
+
+ return 0;
+}
+
+static int s2n_drbg_mix_in_entropy(struct s2n_drbg *drbg, struct s2n_blob *entropy, struct s2n_blob *ps)
+{
+ notnull_check(drbg);
+ notnull_check(drbg->ctx);
+ notnull_check(entropy);
+
+ gte_check(entropy->size, ps->size);
+
+ for (int i = 0; i < ps->size; i++) {
+ entropy->data[i] ^= ps->data[i];
+ }
+
+ GUARD(s2n_drbg_update(drbg, entropy));
+
+ return 0;
+}
+
+static int s2n_drbg_seed(struct s2n_drbg *drbg, struct s2n_blob *ps)
+{
+ s2n_stack_blob(blob, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
+
+ GUARD_AS_POSIX(s2n_get_seed_entropy(&blob));
+ GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps));
+
+ drbg->bytes_used = 0;
+
+ return 0;
+}
+
+static int s2n_drbg_mix(struct s2n_drbg *drbg, struct s2n_blob *ps)
+{
+ s2n_stack_blob(blob, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
+
+ GUARD_AS_POSIX(s2n_get_mix_entropy(&blob));
+ GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps));
+
+ drbg->mixes += 1;
+
+ return 0;
+}
+
+int s2n_drbg_instantiate(struct s2n_drbg *drbg, struct s2n_blob *personalization_string, const s2n_drbg_mode mode)
+{
+ notnull_check(drbg);
+
+ drbg->ctx = EVP_CIPHER_CTX_new();
+ S2N_ERROR_IF(!drbg->ctx, S2N_ERR_DRBG);
+
+ s2n_evp_ctx_init(drbg->ctx);
+
+ switch(mode) {
+ case S2N_AES_128_CTR_NO_DF_PR:
+ GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_128_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG);
+ break;
+ case S2N_AES_256_CTR_NO_DF_PR:
+ GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_256_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG);
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_DRBG);
+ }
+
+ lte_check(s2n_drbg_key_size(drbg), S2N_DRBG_MAX_KEY_SIZE);
+ lte_check(s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
+
+ static const uint8_t zero_key[S2N_DRBG_MAX_KEY_SIZE] = {0};
+
+ /* Start off with zeroed data, per 10.2.1.3.1 item 4 and 5 */
+ memset(drbg->v, 0, sizeof(drbg->v));
+ GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, NULL, NULL, zero_key, NULL), S2N_ERR_DRBG);
+
+ /* Copy the personalization string */
+ s2n_stack_blob(ps, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
+ GUARD(s2n_blob_zero(&ps));
+
+ memcpy_check(ps.data, personalization_string->data, MIN(ps.size, personalization_string->size));
+
+ /* Seed the DRBG */
+ GUARD(s2n_drbg_seed(drbg, &ps));
+
+ return 0;
+}
+
+int s2n_drbg_generate(struct s2n_drbg *drbg, struct s2n_blob *blob)
+{
+ notnull_check(drbg);
+ notnull_check(drbg->ctx);
+ s2n_stack_blob(zeros, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE);
+
+ S2N_ERROR_IF(blob->size > S2N_DRBG_GENERATE_LIMIT, S2N_ERR_DRBG_REQUEST_SIZE);
+
+ /* Always mix in additional entropy, for prediction resistance */
+ GUARD(s2n_drbg_mix(drbg, &zeros));
+ GUARD(s2n_drbg_bits(drbg, blob));
+ GUARD(s2n_drbg_update(drbg, &zeros));
+
+ return 0;
+}
+
+int s2n_drbg_wipe(struct s2n_drbg *drbg)
+{
+ notnull_check(drbg);
+ if (drbg->ctx) {
+ GUARD_OSSL(EVP_CIPHER_CTX_cleanup(drbg->ctx), S2N_ERR_DRBG);
+
+ EVP_CIPHER_CTX_free(drbg->ctx);
+ drbg->ctx = NULL;
+ }
+
+ *drbg = (struct s2n_drbg) {0};
+ return 0;
+}
+
+int s2n_drbg_bytes_used(struct s2n_drbg *drbg, uint64_t *bytes_used)
+{
+ notnull_check(drbg);
+ notnull_check(bytes_used);
+ *bytes_used = drbg->bytes_used;
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_drbg.h b/contrib/restricted/aws/s2n/crypto/s2n_drbg.h
index 58562d17eb..dbd72ad8ff 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_drbg.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_drbg.h
@@ -1,66 +1,66 @@
-/*
- * 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 <openssl/evp.h>
-
-#include "crypto/s2n_hash.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_result.h"
-
-#define S2N_DRBG_BLOCK_SIZE 16
-#define S2N_DRBG_MAX_KEY_SIZE 32
-#define S2N_DRBG_MAX_SEED_SIZE (S2N_DRBG_BLOCK_SIZE + S2N_DRBG_MAX_KEY_SIZE)
-
-/* The maximum size of any one request: from NIST SP800-90A 10.2.1 Table 3 */
-#define S2N_DRBG_GENERATE_LIMIT 8192
-
-/* We reseed after 2^35 bytes have been generated: from NIST SP800-90A 10.2.1 Table 3 */
-#define S2N_DRBG_RESEED_LIMIT 34359738368
-
-struct s2n_drbg {
- /* Track how many bytes have been used */
- uint64_t bytes_used;
-
- EVP_CIPHER_CTX *ctx;
-
- /* The current DRBG 'value' */
- uint8_t v[S2N_DRBG_BLOCK_SIZE];
-
- /* Used only by the unit tests: how many times has entropy been mixed in */
- uint64_t mixes;
-};
-
-/*
- * S2N_AES_128_CTR_NO_DF_PR is a deterministic random bit generator using AES 128 in counter mode (AES_128_CTR). It does not
- * use a derivation function (NO_DF) on the seed but does have prediction resistance (PR).
- *
- * S2N_AES_256_CTR_NO_DF_PR is a deterministic random bit generator using AES 256 in counter mode (AES_128_CTR). It does not
- * use a derivation function on the seed but does have prediction resistance.
- */
-typedef enum {S2N_AES_128_CTR_NO_DF_PR, S2N_AES_256_CTR_NO_DF_PR} s2n_drbg_mode;
-
-/* Per NIST SP 800-90C 6.3
- *
- * s2n's DRBG does provide prediction resistance
- * and does not support the additional_input parameter (which per 800-90C may be zero).
- *
- * The security strength provided by s2n's DRBG is either 128 or 256 bits depending on the s2n_drbg_mode passed in.
- */
-extern int s2n_drbg_instantiate(struct s2n_drbg *drbg, struct s2n_blob *personalization_string, const s2n_drbg_mode mode);
-extern int s2n_drbg_generate(struct s2n_drbg *drbg, struct s2n_blob *returned_bits);
-extern int s2n_drbg_wipe(struct s2n_drbg *drbg);
-extern int s2n_drbg_bytes_used(struct s2n_drbg *drbg, uint64_t *bytes_used);
+/*
+ * 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 <openssl/evp.h>
+
+#include "crypto/s2n_hash.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_result.h"
+
+#define S2N_DRBG_BLOCK_SIZE 16
+#define S2N_DRBG_MAX_KEY_SIZE 32
+#define S2N_DRBG_MAX_SEED_SIZE (S2N_DRBG_BLOCK_SIZE + S2N_DRBG_MAX_KEY_SIZE)
+
+/* The maximum size of any one request: from NIST SP800-90A 10.2.1 Table 3 */
+#define S2N_DRBG_GENERATE_LIMIT 8192
+
+/* We reseed after 2^35 bytes have been generated: from NIST SP800-90A 10.2.1 Table 3 */
+#define S2N_DRBG_RESEED_LIMIT 34359738368
+
+struct s2n_drbg {
+ /* Track how many bytes have been used */
+ uint64_t bytes_used;
+
+ EVP_CIPHER_CTX *ctx;
+
+ /* The current DRBG 'value' */
+ uint8_t v[S2N_DRBG_BLOCK_SIZE];
+
+ /* Used only by the unit tests: how many times has entropy been mixed in */
+ uint64_t mixes;
+};
+
+/*
+ * S2N_AES_128_CTR_NO_DF_PR is a deterministic random bit generator using AES 128 in counter mode (AES_128_CTR). It does not
+ * use a derivation function (NO_DF) on the seed but does have prediction resistance (PR).
+ *
+ * S2N_AES_256_CTR_NO_DF_PR is a deterministic random bit generator using AES 256 in counter mode (AES_128_CTR). It does not
+ * use a derivation function on the seed but does have prediction resistance.
+ */
+typedef enum {S2N_AES_128_CTR_NO_DF_PR, S2N_AES_256_CTR_NO_DF_PR} s2n_drbg_mode;
+
+/* Per NIST SP 800-90C 6.3
+ *
+ * s2n's DRBG does provide prediction resistance
+ * and does not support the additional_input parameter (which per 800-90C may be zero).
+ *
+ * The security strength provided by s2n's DRBG is either 128 or 256 bits depending on the s2n_drbg_mode passed in.
+ */
+extern int s2n_drbg_instantiate(struct s2n_drbg *drbg, struct s2n_blob *personalization_string, const s2n_drbg_mode mode);
+extern int s2n_drbg_generate(struct s2n_drbg *drbg, struct s2n_blob *returned_bits);
+extern int s2n_drbg_wipe(struct s2n_drbg *drbg);
+extern int s2n_drbg_bytes_used(struct s2n_drbg *drbg, uint64_t *bytes_used);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.c b/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.c
index 7ae2a73094..b94c534bea 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.c
@@ -1,501 +1,501 @@
-/*
- * 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 "crypto/s2n_ecc_evp.h"
-
-#include <openssl/ecdh.h>
-#include <openssl/evp.h>
-#if defined(OPENSSL_IS_AWSLC)
-#error #include <openssl/mem.h>
-#endif
-
-#include <stdint.h>
-
-#include "tls/s2n_tls_parameters.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_safety.h"
-
-#define TLS_EC_CURVE_TYPE_NAMED 3
-
-DEFINE_POINTER_CLEANUP_FUNC(EVP_PKEY *, EVP_PKEY_free);
-DEFINE_POINTER_CLEANUP_FUNC(EVP_PKEY_CTX *, EVP_PKEY_CTX_free);
-DEFINE_POINTER_CLEANUP_FUNC(EC_KEY *, EC_KEY_free);
-
-#if !EVP_APIS_SUPPORTED
-DEFINE_POINTER_CLEANUP_FUNC(EC_POINT *, EC_POINT_free);
-#endif
-
-#if EVP_APIS_SUPPORTED
-static int s2n_ecc_evp_generate_key_x25519(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
-#else
-static int s2n_ecc_evp_write_point_data_snug(const EC_POINT *point, const EC_GROUP *group, struct s2n_blob *out);
-static int s2n_ecc_evp_calculate_point_length(const EC_POINT *point, const EC_GROUP *group, uint8_t *length);
-static EC_POINT *s2n_ecc_evp_blob_to_point(struct s2n_blob *blob, const EC_KEY *ec_key);
-#endif
-static int s2n_ecc_evp_generate_key_nist_curves(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
-static int s2n_ecc_evp_generate_own_key(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
-static int s2n_ecc_evp_compute_shared_secret(EVP_PKEY *own_key, EVP_PKEY *peer_public, uint16_t iana_id, struct s2n_blob *shared_secret);
-
-/* IANA values can be found here: https://tools.ietf.org/html/rfc8446#appendix-B.3.1.4 */
-
-const struct s2n_ecc_named_curve s2n_ecc_curve_secp256r1 =
-{
- .iana_id = TLS_EC_CURVE_SECP_256_R1,
- .libcrypto_nid = NID_X9_62_prime256v1,
- .name = "secp256r1",
- .share_size = SECP256R1_SHARE_SIZE,
- .generate_key = s2n_ecc_evp_generate_key_nist_curves,
-};
-
-const struct s2n_ecc_named_curve s2n_ecc_curve_secp384r1 =
-{
- .iana_id = TLS_EC_CURVE_SECP_384_R1,
- .libcrypto_nid = NID_secp384r1,
- .name = "secp384r1",
- .share_size = SECP384R1_SHARE_SIZE,
- .generate_key = s2n_ecc_evp_generate_key_nist_curves,
-};
-
-const struct s2n_ecc_named_curve s2n_ecc_curve_secp521r1 =
-{
- .iana_id = TLS_EC_CURVE_SECP_521_R1,
- .libcrypto_nid = NID_secp521r1,
- .name = "secp521r1",
- .share_size = SECP521R1_SHARE_SIZE,
- .generate_key = s2n_ecc_evp_generate_key_nist_curves,
-};
-
-#if EVP_APIS_SUPPORTED
-const struct s2n_ecc_named_curve s2n_ecc_curve_x25519 = {
- .iana_id = TLS_EC_CURVE_ECDH_X25519,
- .libcrypto_nid = NID_X25519,
- .name = "x25519",
- .share_size = X25519_SHARE_SIZE,
- .generate_key = s2n_ecc_evp_generate_key_x25519,
-};
-#else
-const struct s2n_ecc_named_curve s2n_ecc_curve_x25519 = {0};
-#endif
-
-/* All curves that s2n supports. New curves MUST be added here.
- * This list is a super set of all the curves present in s2n_ecc_preferences list.
- */
-const struct s2n_ecc_named_curve *const s2n_all_supported_curves_list[] = {
- &s2n_ecc_curve_secp256r1,
- &s2n_ecc_curve_secp384r1,
-#if EVP_APIS_SUPPORTED
- &s2n_ecc_curve_x25519,
-#endif
- &s2n_ecc_curve_secp521r1,
-};
-
-const size_t s2n_all_supported_curves_list_len = s2n_array_len(s2n_all_supported_curves_list);
-
-
-int s2n_is_evp_apis_supported()
-{
- return EVP_APIS_SUPPORTED;
-}
-
-#if EVP_APIS_SUPPORTED
-static int s2n_ecc_evp_generate_key_x25519(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey) {
-
- DEFER_CLEANUP(EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(named_curve->libcrypto_nid, NULL),
- EVP_PKEY_CTX_free_pointer);
- S2N_ERROR_IF(pctx == NULL, S2N_ERR_ECDHE_GEN_KEY);
-
- GUARD_OSSL(EVP_PKEY_keygen_init(pctx), S2N_ERR_ECDHE_GEN_KEY);
- GUARD_OSSL(EVP_PKEY_keygen(pctx, evp_pkey), S2N_ERR_ECDHE_GEN_KEY);
- S2N_ERROR_IF(evp_pkey == NULL, S2N_ERR_ECDHE_GEN_KEY);
-
- return 0;
-}
-#endif
-
-static int s2n_ecc_evp_generate_key_nist_curves(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey) {
-
- DEFER_CLEANUP(EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free_pointer);
- S2N_ERROR_IF(pctx == NULL, S2N_ERR_ECDHE_GEN_KEY);
-
- GUARD_OSSL(EVP_PKEY_paramgen_init(pctx), S2N_ERR_ECDHE_GEN_KEY);
- GUARD_OSSL(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, named_curve->libcrypto_nid), S2N_ERR_ECDHE_GEN_KEY);
-
- DEFER_CLEANUP(EVP_PKEY *params = NULL, EVP_PKEY_free_pointer);
- GUARD_OSSL(EVP_PKEY_paramgen(pctx, &params), S2N_ERR_ECDHE_GEN_KEY);
- S2N_ERROR_IF(params == NULL, S2N_ERR_ECDHE_GEN_KEY);
-
- DEFER_CLEANUP(EVP_PKEY_CTX *kctx = EVP_PKEY_CTX_new(params, NULL), EVP_PKEY_CTX_free_pointer);
- S2N_ERROR_IF(kctx == NULL, S2N_ERR_ECDHE_GEN_KEY);
-
- GUARD_OSSL(EVP_PKEY_keygen_init(kctx), S2N_ERR_ECDHE_GEN_KEY);
- GUARD_OSSL(EVP_PKEY_keygen(kctx, evp_pkey), S2N_ERR_ECDHE_GEN_KEY);
- S2N_ERROR_IF(evp_pkey == NULL, S2N_ERR_ECDHE_GEN_KEY);
-
- return 0;
-}
-
-static int s2n_ecc_evp_generate_own_key(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey) {
- notnull_check(named_curve);
- S2N_ERROR_IF(named_curve->generate_key == NULL, S2N_ERR_ECDHE_GEN_KEY);
-
- return named_curve->generate_key(named_curve, evp_pkey);
-}
-
-static int s2n_ecc_evp_compute_shared_secret(EVP_PKEY *own_key, EVP_PKEY *peer_public, uint16_t iana_id, struct s2n_blob *shared_secret) {
- notnull_check(peer_public);
- notnull_check(own_key);
-
- /* From RFC 8446 Section 4.2.8.2: For the curves secp256r1 and secp384r1 peers MUST validate each other's
- * public value Q by ensuring that the point is a valid point on the elliptic curve.
- * For the curve x25519 the peer public-key validation check doesn't apply.
- */
- if (iana_id == TLS_EC_CURVE_SECP_256_R1 || iana_id == TLS_EC_CURVE_SECP_384_R1) {
- DEFER_CLEANUP(EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(peer_public), EC_KEY_free_pointer);
- S2N_ERROR_IF(ec_key == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
- GUARD_OSSL(EC_KEY_check_key(ec_key), S2N_ERR_ECDHE_SHARED_SECRET);
- }
-
- size_t shared_secret_size;
-
- DEFER_CLEANUP(EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(own_key, NULL), EVP_PKEY_CTX_free_pointer);
- S2N_ERROR_IF(ctx == NULL, S2N_ERR_ECDHE_SHARED_SECRET);
-
- GUARD_OSSL(EVP_PKEY_derive_init(ctx), S2N_ERR_ECDHE_SHARED_SECRET);
- GUARD_OSSL(EVP_PKEY_derive_set_peer(ctx, peer_public), S2N_ERR_ECDHE_SHARED_SECRET);
- GUARD_OSSL(EVP_PKEY_derive(ctx, NULL, &shared_secret_size), S2N_ERR_ECDHE_SHARED_SECRET);
- GUARD(s2n_alloc(shared_secret, shared_secret_size));
-
- if (EVP_PKEY_derive(ctx, shared_secret->data, &shared_secret_size) != 1) {
- GUARD(s2n_free(shared_secret));
- S2N_ERROR(S2N_ERR_ECDHE_SHARED_SECRET);
- }
-
- return 0;
-}
-
-int s2n_ecc_evp_generate_ephemeral_key(struct s2n_ecc_evp_params *ecc_evp_params) {
- notnull_check(ecc_evp_params->negotiated_curve);
- S2N_ERROR_IF(ecc_evp_params->evp_pkey != NULL, S2N_ERR_ECDHE_GEN_KEY);
- S2N_ERROR_IF(s2n_ecc_evp_generate_own_key(ecc_evp_params->negotiated_curve, &ecc_evp_params->evp_pkey) != 0,
- S2N_ERR_ECDHE_GEN_KEY);
- S2N_ERROR_IF(ecc_evp_params->evp_pkey == NULL, S2N_ERR_ECDHE_GEN_KEY);
- return 0;
-}
-
-int s2n_ecc_evp_compute_shared_secret_from_params(struct s2n_ecc_evp_params *private_ecc_evp_params,
- struct s2n_ecc_evp_params *public_ecc_evp_params,
- struct s2n_blob *shared_key) {
- notnull_check(private_ecc_evp_params->negotiated_curve);
- notnull_check(private_ecc_evp_params->evp_pkey);
- notnull_check(public_ecc_evp_params->negotiated_curve);
- notnull_check(public_ecc_evp_params->evp_pkey);
- S2N_ERROR_IF(private_ecc_evp_params->negotiated_curve->iana_id != public_ecc_evp_params->negotiated_curve->iana_id,
- S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
- GUARD(s2n_ecc_evp_compute_shared_secret(private_ecc_evp_params->evp_pkey, public_ecc_evp_params->evp_pkey,
- private_ecc_evp_params->negotiated_curve->iana_id, shared_key));
- return 0;
-}
-
-int s2n_ecc_evp_compute_shared_secret_as_server(struct s2n_ecc_evp_params *ecc_evp_params,
- struct s2n_stuffer *Yc_in, struct s2n_blob *shared_key) {
- notnull_check(ecc_evp_params->negotiated_curve);
- notnull_check(ecc_evp_params->evp_pkey);
- notnull_check(Yc_in);
-
- uint8_t client_public_len;
- struct s2n_blob client_public_blob = {0};
-
- DEFER_CLEANUP(EVP_PKEY *peer_key = EVP_PKEY_new(), EVP_PKEY_free_pointer);
- S2N_ERROR_IF(peer_key == NULL, S2N_ERR_BAD_MESSAGE);
- GUARD(s2n_stuffer_read_uint8(Yc_in, &client_public_len));
- client_public_blob.size = client_public_len;
- client_public_blob.data = s2n_stuffer_raw_read(Yc_in, client_public_blob.size);
- notnull_check(client_public_blob.data);
-
-#if EVP_APIS_SUPPORTED
- if (ecc_evp_params->negotiated_curve->libcrypto_nid == NID_X25519) {
- GUARD(EVP_PKEY_set_type(peer_key, ecc_evp_params->negotiated_curve->libcrypto_nid));
- } else {
- DEFER_CLEANUP(EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free_pointer);
- S2N_ERROR_IF(pctx == NULL, S2N_ERR_ECDHE_SERIALIZING);
- GUARD_OSSL(EVP_PKEY_paramgen_init(pctx), S2N_ERR_ECDHE_SERIALIZING);
- GUARD_OSSL(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ecc_evp_params->negotiated_curve->libcrypto_nid), S2N_ERR_ECDHE_SERIALIZING);
- GUARD_OSSL(EVP_PKEY_paramgen(pctx, &peer_key), S2N_ERR_ECDHE_SERIALIZING);
- }
- GUARD_OSSL(EVP_PKEY_set1_tls_encodedpoint(peer_key, client_public_blob.data, client_public_blob.size),
- S2N_ERR_ECDHE_SERIALIZING);
-#else
- DEFER_CLEANUP(EC_KEY *ec_key = EC_KEY_new_by_curve_name(ecc_evp_params->negotiated_curve->libcrypto_nid),
- EC_KEY_free_pointer);
- S2N_ERROR_IF(ec_key == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
-
- DEFER_CLEANUP(EC_POINT *point = s2n_ecc_evp_blob_to_point(&client_public_blob, ec_key), EC_POINT_free_pointer);
- S2N_ERROR_IF(point == NULL, S2N_ERR_BAD_MESSAGE);
-
- int success = EC_KEY_set_public_key(ec_key, point);
- GUARD_OSSL(EVP_PKEY_set1_EC_KEY(peer_key, ec_key), S2N_ERR_ECDHE_SERIALIZING);
- S2N_ERROR_IF(success == 0, S2N_ERR_BAD_MESSAGE);
-#endif
-
- return s2n_ecc_evp_compute_shared_secret(ecc_evp_params->evp_pkey, peer_key,
- ecc_evp_params->negotiated_curve->iana_id, shared_key);
-
-}
-
-int s2n_ecc_evp_compute_shared_secret_as_client(struct s2n_ecc_evp_params *ecc_evp_params,
- struct s2n_stuffer *Yc_out, struct s2n_blob *shared_key) {
-
- DEFER_CLEANUP(struct s2n_ecc_evp_params client_params = {0}, s2n_ecc_evp_params_free);
-
- notnull_check(ecc_evp_params->negotiated_curve);
- client_params.negotiated_curve = ecc_evp_params->negotiated_curve;
- GUARD(s2n_ecc_evp_generate_own_key(client_params.negotiated_curve, &client_params.evp_pkey));
- S2N_ERROR_IF(client_params.evp_pkey == NULL, S2N_ERR_ECDHE_GEN_KEY);
-
- if (s2n_ecc_evp_compute_shared_secret(client_params.evp_pkey, ecc_evp_params->evp_pkey,
- ecc_evp_params->negotiated_curve->iana_id, shared_key) != S2N_SUCCESS) {
- S2N_ERROR(S2N_ERR_ECDHE_SHARED_SECRET);
- }
-
- GUARD(s2n_stuffer_write_uint8(Yc_out, client_params.negotiated_curve->share_size));
-
- if (s2n_ecc_evp_write_params_point(&client_params, Yc_out) != 0) {
- S2N_ERROR(S2N_ERR_ECDHE_SERIALIZING);
- }
- return 0;
-
-}
-
-#if (!EVP_APIS_SUPPORTED)
-static int s2n_ecc_evp_calculate_point_length(const EC_POINT *point, const EC_GROUP *group, uint8_t *length) {
- size_t ret = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
- S2N_ERROR_IF(ret == 0, S2N_ERR_ECDHE_SERIALIZING);
- S2N_ERROR_IF(ret > UINT8_MAX, S2N_ERR_ECDHE_SERIALIZING);
- *length = (uint8_t)ret;
- return 0;
-}
-
-static int s2n_ecc_evp_write_point_data_snug(const EC_POINT *point, const EC_GROUP *group, struct s2n_blob *out) {
- size_t ret = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, out->data, out->size, NULL);
- S2N_ERROR_IF(ret != out->size, S2N_ERR_ECDHE_SERIALIZING);
- return 0;
-}
-
-static EC_POINT *s2n_ecc_evp_blob_to_point(struct s2n_blob *blob, const EC_KEY *ec_key) {
- const EC_GROUP *group = EC_KEY_get0_group(ec_key);
- EC_POINT *point = EC_POINT_new(group);
- if (point == NULL) {
- S2N_ERROR_PTR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
- }
- if (EC_POINT_oct2point(group, point, blob->data, blob->size, NULL) != 1) {
- EC_POINT_free(point);
- S2N_ERROR_PTR(S2N_ERR_BAD_MESSAGE);
- }
- return point;
-}
-#endif
-
-int s2n_ecc_evp_read_params_point(struct s2n_stuffer *in, int point_size, struct s2n_blob *point_blob) {
- notnull_check(in);
- notnull_check(point_blob);
- gte_check(point_size, 0);
-
- /* Extract point from stuffer */
- point_blob->size = point_size;
- point_blob->data = s2n_stuffer_raw_read(in, point_size);
- notnull_check(point_blob->data);
-
- return 0;
-}
-
-int s2n_ecc_evp_read_params(struct s2n_stuffer *in, struct s2n_blob *data_to_verify,
- struct s2n_ecdhe_raw_server_params *raw_server_ecc_params) {
- notnull_check(in);
- uint8_t curve_type;
- uint8_t point_length;
-
- /* Remember where we started reading the data */
- data_to_verify->data = s2n_stuffer_raw_read(in, 0);
- notnull_check(data_to_verify->data);
-
- /* Read the curve */
- GUARD(s2n_stuffer_read_uint8(in, &curve_type));
- S2N_ERROR_IF(curve_type != TLS_EC_CURVE_TYPE_NAMED, S2N_ERR_BAD_MESSAGE);
- raw_server_ecc_params->curve_blob.data = s2n_stuffer_raw_read(in, 2);
- notnull_check(raw_server_ecc_params->curve_blob.data);
- raw_server_ecc_params->curve_blob.size = 2;
-
- /* Read the point */
- GUARD(s2n_stuffer_read_uint8(in, &point_length));
-
- GUARD(s2n_ecc_evp_read_params_point(in, point_length, &raw_server_ecc_params->point_blob));
-
- /* curve type (1) + iana (2) + key share size (1) + key share */
- data_to_verify->size = point_length + 4;
-
- return 0;
-}
-
-int s2n_ecc_evp_write_params_point(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out) {
- notnull_check(ecc_evp_params);
- notnull_check(ecc_evp_params->negotiated_curve);
- notnull_check(ecc_evp_params->evp_pkey);
- notnull_check(out);
-
-#if EVP_APIS_SUPPORTED
- struct s2n_blob point_blob = {0};
- uint8_t *encoded_point = NULL;
-
- size_t size = EVP_PKEY_get1_tls_encodedpoint(ecc_evp_params->evp_pkey, &encoded_point);
- if (size != ecc_evp_params->negotiated_curve->share_size) {
- OPENSSL_free(encoded_point);
- S2N_ERROR(S2N_ERR_ECDHE_SERIALIZING);
- }
- else {
- point_blob.data = s2n_stuffer_raw_write(out, ecc_evp_params->negotiated_curve->share_size);
- notnull_check(point_blob.data);
- memcpy_check(point_blob.data, encoded_point, size);
- OPENSSL_free(encoded_point);
- }
-#else
- uint8_t point_len;
- struct s2n_blob point_blob = {0};
-
- DEFER_CLEANUP(EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(ecc_evp_params->evp_pkey), EC_KEY_free_pointer);
- S2N_ERROR_IF(ec_key == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
- const EC_POINT *point = EC_KEY_get0_public_key(ec_key);
- const EC_GROUP *group = EC_KEY_get0_group(ec_key);
- S2N_ERROR_IF(point == NULL || group == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
-
- GUARD(s2n_ecc_evp_calculate_point_length(point, group, &point_len));
- S2N_ERROR_IF(point_len != ecc_evp_params->negotiated_curve->share_size, S2N_ERR_ECDHE_SERIALIZING);
- point_blob.data = s2n_stuffer_raw_write(out, point_len);
- notnull_check(point_blob.data);
- point_blob.size = point_len;
-
- GUARD(s2n_ecc_evp_write_point_data_snug(point, group, &point_blob));
-#endif
- return 0;
-}
-
-int s2n_ecc_evp_write_params(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out,
- struct s2n_blob *written) {
- notnull_check(ecc_evp_params);
- notnull_check(ecc_evp_params->negotiated_curve);
- notnull_check(ecc_evp_params->evp_pkey);
- notnull_check(out);
- notnull_check(written);
-
- uint8_t key_share_size = ecc_evp_params->negotiated_curve->share_size;
- /* Remember where the written data starts */
- written->data = s2n_stuffer_raw_write(out, 0);
- notnull_check(written->data);
-
- GUARD(s2n_stuffer_write_uint8(out, TLS_EC_CURVE_TYPE_NAMED));
- GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->iana_id));
- GUARD(s2n_stuffer_write_uint8(out, key_share_size));
-
- GUARD(s2n_ecc_evp_write_params_point(ecc_evp_params, out));
-
- /* key share + key share size (1) + iana (2) + curve type (1) */
- written->size = key_share_size + 4;
-
- return written->size;
-}
-
-int s2n_ecc_evp_parse_params_point(struct s2n_blob *point_blob, struct s2n_ecc_evp_params *ecc_evp_params) {
- notnull_check(point_blob->data);
- notnull_check(ecc_evp_params->negotiated_curve);
- S2N_ERROR_IF(point_blob->size != ecc_evp_params->negotiated_curve->share_size, S2N_ERR_ECDHE_SERIALIZING);
-
-#if EVP_APIS_SUPPORTED
- if (ecc_evp_params->negotiated_curve->libcrypto_nid == NID_X25519) {
- if (ecc_evp_params->evp_pkey == NULL) {
- ecc_evp_params->evp_pkey = EVP_PKEY_new();
- }
- S2N_ERROR_IF(ecc_evp_params->evp_pkey == NULL, S2N_ERR_BAD_MESSAGE);
- GUARD(EVP_PKEY_set_type(ecc_evp_params->evp_pkey, ecc_evp_params->negotiated_curve->libcrypto_nid));
- }
- else {
- DEFER_CLEANUP(EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free_pointer);
- S2N_ERROR_IF(pctx == NULL, S2N_ERR_ECDHE_SERIALIZING);
- GUARD_OSSL(EVP_PKEY_paramgen_init(pctx), S2N_ERR_ECDHE_SERIALIZING);
- GUARD_OSSL(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ecc_evp_params->negotiated_curve->libcrypto_nid), S2N_ERR_ECDHE_SERIALIZING);
- GUARD_OSSL(EVP_PKEY_paramgen(pctx, &ecc_evp_params->evp_pkey), S2N_ERR_ECDHE_SERIALIZING);
- }
- GUARD_OSSL(EVP_PKEY_set1_tls_encodedpoint(ecc_evp_params->evp_pkey, point_blob->data, point_blob->size),
- S2N_ERR_ECDHE_SERIALIZING);
-#else
- if (ecc_evp_params->evp_pkey == NULL) {
- ecc_evp_params->evp_pkey = EVP_PKEY_new();
- }
- S2N_ERROR_IF(ecc_evp_params->evp_pkey == NULL, S2N_ERR_BAD_MESSAGE);
- /* Create a key to store the point */
- DEFER_CLEANUP(EC_KEY *ec_key = EC_KEY_new_by_curve_name(ecc_evp_params->negotiated_curve->libcrypto_nid),
- EC_KEY_free_pointer);
- S2N_ERROR_IF(ec_key == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
-
- /* Parse and store the server public point */
- DEFER_CLEANUP(EC_POINT *point = s2n_ecc_evp_blob_to_point(point_blob, ec_key), EC_POINT_free_pointer);
- S2N_ERROR_IF(point == NULL, S2N_ERR_BAD_MESSAGE);
-
- /* Set the point as the public key */
- int success = EC_KEY_set_public_key(ec_key, point);
-
- GUARD_OSSL(EVP_PKEY_set1_EC_KEY(ecc_evp_params->evp_pkey,ec_key), S2N_ERR_ECDHE_SERIALIZING);
-
- /* EC_KEY_set_public_key returns 1 on success, 0 on failure */
- S2N_ERROR_IF(success == 0, S2N_ERR_BAD_MESSAGE);
-
-#endif
- return 0;
-}
-
-int s2n_ecc_evp_parse_params(struct s2n_ecdhe_raw_server_params *raw_server_ecc_params,
- struct s2n_ecc_evp_params *ecc_evp_params) {
- S2N_ERROR_IF(
- s2n_ecc_evp_find_supported_curve(&raw_server_ecc_params->curve_blob, &ecc_evp_params->negotiated_curve) != 0,
- S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
- return s2n_ecc_evp_parse_params_point(&raw_server_ecc_params->point_blob, ecc_evp_params);
-}
-
-int s2n_ecc_evp_find_supported_curve(struct s2n_blob *iana_ids, const struct s2n_ecc_named_curve **found) {
- struct s2n_stuffer iana_ids_in = {0};
-
- GUARD(s2n_stuffer_init(&iana_ids_in, iana_ids));
- GUARD(s2n_stuffer_write(&iana_ids_in, iana_ids));
- for (int i = 0; i < s2n_all_supported_curves_list_len; i++) {
- const struct s2n_ecc_named_curve *supported_curve = s2n_all_supported_curves_list[i];
- for (int j = 0; j < iana_ids->size / 2; j++) {
- uint16_t iana_id;
- GUARD(s2n_stuffer_read_uint16(&iana_ids_in, &iana_id));
- if (supported_curve->iana_id == iana_id) {
- *found = supported_curve;
- return 0;
- }
- }
- GUARD(s2n_stuffer_reread(&iana_ids_in));
- }
-
- S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
-}
-
-int s2n_ecc_evp_params_free(struct s2n_ecc_evp_params *ecc_evp_params) {
- if (ecc_evp_params->evp_pkey != NULL) {
- EVP_PKEY_free(ecc_evp_params->evp_pkey);
- ecc_evp_params->evp_pkey = NULL;
- }
- return 0;
-}
+/*
+ * 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 "crypto/s2n_ecc_evp.h"
+
+#include <openssl/ecdh.h>
+#include <openssl/evp.h>
+#if defined(OPENSSL_IS_AWSLC)
+#error #include <openssl/mem.h>
+#endif
+
+#include <stdint.h>
+
+#include "tls/s2n_tls_parameters.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_safety.h"
+
+#define TLS_EC_CURVE_TYPE_NAMED 3
+
+DEFINE_POINTER_CLEANUP_FUNC(EVP_PKEY *, EVP_PKEY_free);
+DEFINE_POINTER_CLEANUP_FUNC(EVP_PKEY_CTX *, EVP_PKEY_CTX_free);
+DEFINE_POINTER_CLEANUP_FUNC(EC_KEY *, EC_KEY_free);
+
+#if !EVP_APIS_SUPPORTED
+DEFINE_POINTER_CLEANUP_FUNC(EC_POINT *, EC_POINT_free);
+#endif
+
+#if EVP_APIS_SUPPORTED
+static int s2n_ecc_evp_generate_key_x25519(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
+#else
+static int s2n_ecc_evp_write_point_data_snug(const EC_POINT *point, const EC_GROUP *group, struct s2n_blob *out);
+static int s2n_ecc_evp_calculate_point_length(const EC_POINT *point, const EC_GROUP *group, uint8_t *length);
+static EC_POINT *s2n_ecc_evp_blob_to_point(struct s2n_blob *blob, const EC_KEY *ec_key);
+#endif
+static int s2n_ecc_evp_generate_key_nist_curves(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
+static int s2n_ecc_evp_generate_own_key(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
+static int s2n_ecc_evp_compute_shared_secret(EVP_PKEY *own_key, EVP_PKEY *peer_public, uint16_t iana_id, struct s2n_blob *shared_secret);
+
+/* IANA values can be found here: https://tools.ietf.org/html/rfc8446#appendix-B.3.1.4 */
+
+const struct s2n_ecc_named_curve s2n_ecc_curve_secp256r1 =
+{
+ .iana_id = TLS_EC_CURVE_SECP_256_R1,
+ .libcrypto_nid = NID_X9_62_prime256v1,
+ .name = "secp256r1",
+ .share_size = SECP256R1_SHARE_SIZE,
+ .generate_key = s2n_ecc_evp_generate_key_nist_curves,
+};
+
+const struct s2n_ecc_named_curve s2n_ecc_curve_secp384r1 =
+{
+ .iana_id = TLS_EC_CURVE_SECP_384_R1,
+ .libcrypto_nid = NID_secp384r1,
+ .name = "secp384r1",
+ .share_size = SECP384R1_SHARE_SIZE,
+ .generate_key = s2n_ecc_evp_generate_key_nist_curves,
+};
+
+const struct s2n_ecc_named_curve s2n_ecc_curve_secp521r1 =
+{
+ .iana_id = TLS_EC_CURVE_SECP_521_R1,
+ .libcrypto_nid = NID_secp521r1,
+ .name = "secp521r1",
+ .share_size = SECP521R1_SHARE_SIZE,
+ .generate_key = s2n_ecc_evp_generate_key_nist_curves,
+};
+
+#if EVP_APIS_SUPPORTED
+const struct s2n_ecc_named_curve s2n_ecc_curve_x25519 = {
+ .iana_id = TLS_EC_CURVE_ECDH_X25519,
+ .libcrypto_nid = NID_X25519,
+ .name = "x25519",
+ .share_size = X25519_SHARE_SIZE,
+ .generate_key = s2n_ecc_evp_generate_key_x25519,
+};
+#else
+const struct s2n_ecc_named_curve s2n_ecc_curve_x25519 = {0};
+#endif
+
+/* All curves that s2n supports. New curves MUST be added here.
+ * This list is a super set of all the curves present in s2n_ecc_preferences list.
+ */
+const struct s2n_ecc_named_curve *const s2n_all_supported_curves_list[] = {
+ &s2n_ecc_curve_secp256r1,
+ &s2n_ecc_curve_secp384r1,
+#if EVP_APIS_SUPPORTED
+ &s2n_ecc_curve_x25519,
+#endif
+ &s2n_ecc_curve_secp521r1,
+};
+
+const size_t s2n_all_supported_curves_list_len = s2n_array_len(s2n_all_supported_curves_list);
+
+
+int s2n_is_evp_apis_supported()
+{
+ return EVP_APIS_SUPPORTED;
+}
+
+#if EVP_APIS_SUPPORTED
+static int s2n_ecc_evp_generate_key_x25519(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey) {
+
+ DEFER_CLEANUP(EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(named_curve->libcrypto_nid, NULL),
+ EVP_PKEY_CTX_free_pointer);
+ S2N_ERROR_IF(pctx == NULL, S2N_ERR_ECDHE_GEN_KEY);
+
+ GUARD_OSSL(EVP_PKEY_keygen_init(pctx), S2N_ERR_ECDHE_GEN_KEY);
+ GUARD_OSSL(EVP_PKEY_keygen(pctx, evp_pkey), S2N_ERR_ECDHE_GEN_KEY);
+ S2N_ERROR_IF(evp_pkey == NULL, S2N_ERR_ECDHE_GEN_KEY);
+
+ return 0;
+}
+#endif
+
+static int s2n_ecc_evp_generate_key_nist_curves(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey) {
+
+ DEFER_CLEANUP(EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free_pointer);
+ S2N_ERROR_IF(pctx == NULL, S2N_ERR_ECDHE_GEN_KEY);
+
+ GUARD_OSSL(EVP_PKEY_paramgen_init(pctx), S2N_ERR_ECDHE_GEN_KEY);
+ GUARD_OSSL(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, named_curve->libcrypto_nid), S2N_ERR_ECDHE_GEN_KEY);
+
+ DEFER_CLEANUP(EVP_PKEY *params = NULL, EVP_PKEY_free_pointer);
+ GUARD_OSSL(EVP_PKEY_paramgen(pctx, &params), S2N_ERR_ECDHE_GEN_KEY);
+ S2N_ERROR_IF(params == NULL, S2N_ERR_ECDHE_GEN_KEY);
+
+ DEFER_CLEANUP(EVP_PKEY_CTX *kctx = EVP_PKEY_CTX_new(params, NULL), EVP_PKEY_CTX_free_pointer);
+ S2N_ERROR_IF(kctx == NULL, S2N_ERR_ECDHE_GEN_KEY);
+
+ GUARD_OSSL(EVP_PKEY_keygen_init(kctx), S2N_ERR_ECDHE_GEN_KEY);
+ GUARD_OSSL(EVP_PKEY_keygen(kctx, evp_pkey), S2N_ERR_ECDHE_GEN_KEY);
+ S2N_ERROR_IF(evp_pkey == NULL, S2N_ERR_ECDHE_GEN_KEY);
+
+ return 0;
+}
+
+static int s2n_ecc_evp_generate_own_key(const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey) {
+ notnull_check(named_curve);
+ S2N_ERROR_IF(named_curve->generate_key == NULL, S2N_ERR_ECDHE_GEN_KEY);
+
+ return named_curve->generate_key(named_curve, evp_pkey);
+}
+
+static int s2n_ecc_evp_compute_shared_secret(EVP_PKEY *own_key, EVP_PKEY *peer_public, uint16_t iana_id, struct s2n_blob *shared_secret) {
+ notnull_check(peer_public);
+ notnull_check(own_key);
+
+ /* From RFC 8446 Section 4.2.8.2: For the curves secp256r1 and secp384r1 peers MUST validate each other's
+ * public value Q by ensuring that the point is a valid point on the elliptic curve.
+ * For the curve x25519 the peer public-key validation check doesn't apply.
+ */
+ if (iana_id == TLS_EC_CURVE_SECP_256_R1 || iana_id == TLS_EC_CURVE_SECP_384_R1) {
+ DEFER_CLEANUP(EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(peer_public), EC_KEY_free_pointer);
+ S2N_ERROR_IF(ec_key == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+ GUARD_OSSL(EC_KEY_check_key(ec_key), S2N_ERR_ECDHE_SHARED_SECRET);
+ }
+
+ size_t shared_secret_size;
+
+ DEFER_CLEANUP(EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(own_key, NULL), EVP_PKEY_CTX_free_pointer);
+ S2N_ERROR_IF(ctx == NULL, S2N_ERR_ECDHE_SHARED_SECRET);
+
+ GUARD_OSSL(EVP_PKEY_derive_init(ctx), S2N_ERR_ECDHE_SHARED_SECRET);
+ GUARD_OSSL(EVP_PKEY_derive_set_peer(ctx, peer_public), S2N_ERR_ECDHE_SHARED_SECRET);
+ GUARD_OSSL(EVP_PKEY_derive(ctx, NULL, &shared_secret_size), S2N_ERR_ECDHE_SHARED_SECRET);
+ GUARD(s2n_alloc(shared_secret, shared_secret_size));
+
+ if (EVP_PKEY_derive(ctx, shared_secret->data, &shared_secret_size) != 1) {
+ GUARD(s2n_free(shared_secret));
+ S2N_ERROR(S2N_ERR_ECDHE_SHARED_SECRET);
+ }
+
+ return 0;
+}
+
+int s2n_ecc_evp_generate_ephemeral_key(struct s2n_ecc_evp_params *ecc_evp_params) {
+ notnull_check(ecc_evp_params->negotiated_curve);
+ S2N_ERROR_IF(ecc_evp_params->evp_pkey != NULL, S2N_ERR_ECDHE_GEN_KEY);
+ S2N_ERROR_IF(s2n_ecc_evp_generate_own_key(ecc_evp_params->negotiated_curve, &ecc_evp_params->evp_pkey) != 0,
+ S2N_ERR_ECDHE_GEN_KEY);
+ S2N_ERROR_IF(ecc_evp_params->evp_pkey == NULL, S2N_ERR_ECDHE_GEN_KEY);
+ return 0;
+}
+
+int s2n_ecc_evp_compute_shared_secret_from_params(struct s2n_ecc_evp_params *private_ecc_evp_params,
+ struct s2n_ecc_evp_params *public_ecc_evp_params,
+ struct s2n_blob *shared_key) {
+ notnull_check(private_ecc_evp_params->negotiated_curve);
+ notnull_check(private_ecc_evp_params->evp_pkey);
+ notnull_check(public_ecc_evp_params->negotiated_curve);
+ notnull_check(public_ecc_evp_params->evp_pkey);
+ S2N_ERROR_IF(private_ecc_evp_params->negotiated_curve->iana_id != public_ecc_evp_params->negotiated_curve->iana_id,
+ S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+ GUARD(s2n_ecc_evp_compute_shared_secret(private_ecc_evp_params->evp_pkey, public_ecc_evp_params->evp_pkey,
+ private_ecc_evp_params->negotiated_curve->iana_id, shared_key));
+ return 0;
+}
+
+int s2n_ecc_evp_compute_shared_secret_as_server(struct s2n_ecc_evp_params *ecc_evp_params,
+ struct s2n_stuffer *Yc_in, struct s2n_blob *shared_key) {
+ notnull_check(ecc_evp_params->negotiated_curve);
+ notnull_check(ecc_evp_params->evp_pkey);
+ notnull_check(Yc_in);
+
+ uint8_t client_public_len;
+ struct s2n_blob client_public_blob = {0};
+
+ DEFER_CLEANUP(EVP_PKEY *peer_key = EVP_PKEY_new(), EVP_PKEY_free_pointer);
+ S2N_ERROR_IF(peer_key == NULL, S2N_ERR_BAD_MESSAGE);
+ GUARD(s2n_stuffer_read_uint8(Yc_in, &client_public_len));
+ client_public_blob.size = client_public_len;
+ client_public_blob.data = s2n_stuffer_raw_read(Yc_in, client_public_blob.size);
+ notnull_check(client_public_blob.data);
+
+#if EVP_APIS_SUPPORTED
+ if (ecc_evp_params->negotiated_curve->libcrypto_nid == NID_X25519) {
+ GUARD(EVP_PKEY_set_type(peer_key, ecc_evp_params->negotiated_curve->libcrypto_nid));
+ } else {
+ DEFER_CLEANUP(EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free_pointer);
+ S2N_ERROR_IF(pctx == NULL, S2N_ERR_ECDHE_SERIALIZING);
+ GUARD_OSSL(EVP_PKEY_paramgen_init(pctx), S2N_ERR_ECDHE_SERIALIZING);
+ GUARD_OSSL(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ecc_evp_params->negotiated_curve->libcrypto_nid), S2N_ERR_ECDHE_SERIALIZING);
+ GUARD_OSSL(EVP_PKEY_paramgen(pctx, &peer_key), S2N_ERR_ECDHE_SERIALIZING);
+ }
+ GUARD_OSSL(EVP_PKEY_set1_tls_encodedpoint(peer_key, client_public_blob.data, client_public_blob.size),
+ S2N_ERR_ECDHE_SERIALIZING);
+#else
+ DEFER_CLEANUP(EC_KEY *ec_key = EC_KEY_new_by_curve_name(ecc_evp_params->negotiated_curve->libcrypto_nid),
+ EC_KEY_free_pointer);
+ S2N_ERROR_IF(ec_key == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+
+ DEFER_CLEANUP(EC_POINT *point = s2n_ecc_evp_blob_to_point(&client_public_blob, ec_key), EC_POINT_free_pointer);
+ S2N_ERROR_IF(point == NULL, S2N_ERR_BAD_MESSAGE);
+
+ int success = EC_KEY_set_public_key(ec_key, point);
+ GUARD_OSSL(EVP_PKEY_set1_EC_KEY(peer_key, ec_key), S2N_ERR_ECDHE_SERIALIZING);
+ S2N_ERROR_IF(success == 0, S2N_ERR_BAD_MESSAGE);
+#endif
+
+ return s2n_ecc_evp_compute_shared_secret(ecc_evp_params->evp_pkey, peer_key,
+ ecc_evp_params->negotiated_curve->iana_id, shared_key);
+
+}
+
+int s2n_ecc_evp_compute_shared_secret_as_client(struct s2n_ecc_evp_params *ecc_evp_params,
+ struct s2n_stuffer *Yc_out, struct s2n_blob *shared_key) {
+
+ DEFER_CLEANUP(struct s2n_ecc_evp_params client_params = {0}, s2n_ecc_evp_params_free);
+
+ notnull_check(ecc_evp_params->negotiated_curve);
+ client_params.negotiated_curve = ecc_evp_params->negotiated_curve;
+ GUARD(s2n_ecc_evp_generate_own_key(client_params.negotiated_curve, &client_params.evp_pkey));
+ S2N_ERROR_IF(client_params.evp_pkey == NULL, S2N_ERR_ECDHE_GEN_KEY);
+
+ if (s2n_ecc_evp_compute_shared_secret(client_params.evp_pkey, ecc_evp_params->evp_pkey,
+ ecc_evp_params->negotiated_curve->iana_id, shared_key) != S2N_SUCCESS) {
+ S2N_ERROR(S2N_ERR_ECDHE_SHARED_SECRET);
+ }
+
+ GUARD(s2n_stuffer_write_uint8(Yc_out, client_params.negotiated_curve->share_size));
+
+ if (s2n_ecc_evp_write_params_point(&client_params, Yc_out) != 0) {
+ S2N_ERROR(S2N_ERR_ECDHE_SERIALIZING);
+ }
+ return 0;
+
+}
+
+#if (!EVP_APIS_SUPPORTED)
+static int s2n_ecc_evp_calculate_point_length(const EC_POINT *point, const EC_GROUP *group, uint8_t *length) {
+ size_t ret = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
+ S2N_ERROR_IF(ret == 0, S2N_ERR_ECDHE_SERIALIZING);
+ S2N_ERROR_IF(ret > UINT8_MAX, S2N_ERR_ECDHE_SERIALIZING);
+ *length = (uint8_t)ret;
+ return 0;
+}
+
+static int s2n_ecc_evp_write_point_data_snug(const EC_POINT *point, const EC_GROUP *group, struct s2n_blob *out) {
+ size_t ret = EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, out->data, out->size, NULL);
+ S2N_ERROR_IF(ret != out->size, S2N_ERR_ECDHE_SERIALIZING);
+ return 0;
+}
+
+static EC_POINT *s2n_ecc_evp_blob_to_point(struct s2n_blob *blob, const EC_KEY *ec_key) {
+ const EC_GROUP *group = EC_KEY_get0_group(ec_key);
+ EC_POINT *point = EC_POINT_new(group);
+ if (point == NULL) {
+ S2N_ERROR_PTR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+ }
+ if (EC_POINT_oct2point(group, point, blob->data, blob->size, NULL) != 1) {
+ EC_POINT_free(point);
+ S2N_ERROR_PTR(S2N_ERR_BAD_MESSAGE);
+ }
+ return point;
+}
+#endif
+
+int s2n_ecc_evp_read_params_point(struct s2n_stuffer *in, int point_size, struct s2n_blob *point_blob) {
+ notnull_check(in);
+ notnull_check(point_blob);
+ gte_check(point_size, 0);
+
+ /* Extract point from stuffer */
+ point_blob->size = point_size;
+ point_blob->data = s2n_stuffer_raw_read(in, point_size);
+ notnull_check(point_blob->data);
+
+ return 0;
+}
+
+int s2n_ecc_evp_read_params(struct s2n_stuffer *in, struct s2n_blob *data_to_verify,
+ struct s2n_ecdhe_raw_server_params *raw_server_ecc_params) {
+ notnull_check(in);
+ uint8_t curve_type;
+ uint8_t point_length;
+
+ /* Remember where we started reading the data */
+ data_to_verify->data = s2n_stuffer_raw_read(in, 0);
+ notnull_check(data_to_verify->data);
+
+ /* Read the curve */
+ GUARD(s2n_stuffer_read_uint8(in, &curve_type));
+ S2N_ERROR_IF(curve_type != TLS_EC_CURVE_TYPE_NAMED, S2N_ERR_BAD_MESSAGE);
+ raw_server_ecc_params->curve_blob.data = s2n_stuffer_raw_read(in, 2);
+ notnull_check(raw_server_ecc_params->curve_blob.data);
+ raw_server_ecc_params->curve_blob.size = 2;
+
+ /* Read the point */
+ GUARD(s2n_stuffer_read_uint8(in, &point_length));
+
+ GUARD(s2n_ecc_evp_read_params_point(in, point_length, &raw_server_ecc_params->point_blob));
+
+ /* curve type (1) + iana (2) + key share size (1) + key share */
+ data_to_verify->size = point_length + 4;
+
+ return 0;
+}
+
+int s2n_ecc_evp_write_params_point(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out) {
+ notnull_check(ecc_evp_params);
+ notnull_check(ecc_evp_params->negotiated_curve);
+ notnull_check(ecc_evp_params->evp_pkey);
+ notnull_check(out);
+
+#if EVP_APIS_SUPPORTED
+ struct s2n_blob point_blob = {0};
+ uint8_t *encoded_point = NULL;
+
+ size_t size = EVP_PKEY_get1_tls_encodedpoint(ecc_evp_params->evp_pkey, &encoded_point);
+ if (size != ecc_evp_params->negotiated_curve->share_size) {
+ OPENSSL_free(encoded_point);
+ S2N_ERROR(S2N_ERR_ECDHE_SERIALIZING);
+ }
+ else {
+ point_blob.data = s2n_stuffer_raw_write(out, ecc_evp_params->negotiated_curve->share_size);
+ notnull_check(point_blob.data);
+ memcpy_check(point_blob.data, encoded_point, size);
+ OPENSSL_free(encoded_point);
+ }
+#else
+ uint8_t point_len;
+ struct s2n_blob point_blob = {0};
+
+ DEFER_CLEANUP(EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(ecc_evp_params->evp_pkey), EC_KEY_free_pointer);
+ S2N_ERROR_IF(ec_key == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+ const EC_POINT *point = EC_KEY_get0_public_key(ec_key);
+ const EC_GROUP *group = EC_KEY_get0_group(ec_key);
+ S2N_ERROR_IF(point == NULL || group == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+
+ GUARD(s2n_ecc_evp_calculate_point_length(point, group, &point_len));
+ S2N_ERROR_IF(point_len != ecc_evp_params->negotiated_curve->share_size, S2N_ERR_ECDHE_SERIALIZING);
+ point_blob.data = s2n_stuffer_raw_write(out, point_len);
+ notnull_check(point_blob.data);
+ point_blob.size = point_len;
+
+ GUARD(s2n_ecc_evp_write_point_data_snug(point, group, &point_blob));
+#endif
+ return 0;
+}
+
+int s2n_ecc_evp_write_params(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out,
+ struct s2n_blob *written) {
+ notnull_check(ecc_evp_params);
+ notnull_check(ecc_evp_params->negotiated_curve);
+ notnull_check(ecc_evp_params->evp_pkey);
+ notnull_check(out);
+ notnull_check(written);
+
+ uint8_t key_share_size = ecc_evp_params->negotiated_curve->share_size;
+ /* Remember where the written data starts */
+ written->data = s2n_stuffer_raw_write(out, 0);
+ notnull_check(written->data);
+
+ GUARD(s2n_stuffer_write_uint8(out, TLS_EC_CURVE_TYPE_NAMED));
+ GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->iana_id));
+ GUARD(s2n_stuffer_write_uint8(out, key_share_size));
+
+ GUARD(s2n_ecc_evp_write_params_point(ecc_evp_params, out));
+
+ /* key share + key share size (1) + iana (2) + curve type (1) */
+ written->size = key_share_size + 4;
+
+ return written->size;
+}
+
+int s2n_ecc_evp_parse_params_point(struct s2n_blob *point_blob, struct s2n_ecc_evp_params *ecc_evp_params) {
+ notnull_check(point_blob->data);
+ notnull_check(ecc_evp_params->negotiated_curve);
+ S2N_ERROR_IF(point_blob->size != ecc_evp_params->negotiated_curve->share_size, S2N_ERR_ECDHE_SERIALIZING);
+
+#if EVP_APIS_SUPPORTED
+ if (ecc_evp_params->negotiated_curve->libcrypto_nid == NID_X25519) {
+ if (ecc_evp_params->evp_pkey == NULL) {
+ ecc_evp_params->evp_pkey = EVP_PKEY_new();
+ }
+ S2N_ERROR_IF(ecc_evp_params->evp_pkey == NULL, S2N_ERR_BAD_MESSAGE);
+ GUARD(EVP_PKEY_set_type(ecc_evp_params->evp_pkey, ecc_evp_params->negotiated_curve->libcrypto_nid));
+ }
+ else {
+ DEFER_CLEANUP(EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_id(EVP_PKEY_EC, NULL), EVP_PKEY_CTX_free_pointer);
+ S2N_ERROR_IF(pctx == NULL, S2N_ERR_ECDHE_SERIALIZING);
+ GUARD_OSSL(EVP_PKEY_paramgen_init(pctx), S2N_ERR_ECDHE_SERIALIZING);
+ GUARD_OSSL(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ecc_evp_params->negotiated_curve->libcrypto_nid), S2N_ERR_ECDHE_SERIALIZING);
+ GUARD_OSSL(EVP_PKEY_paramgen(pctx, &ecc_evp_params->evp_pkey), S2N_ERR_ECDHE_SERIALIZING);
+ }
+ GUARD_OSSL(EVP_PKEY_set1_tls_encodedpoint(ecc_evp_params->evp_pkey, point_blob->data, point_blob->size),
+ S2N_ERR_ECDHE_SERIALIZING);
+#else
+ if (ecc_evp_params->evp_pkey == NULL) {
+ ecc_evp_params->evp_pkey = EVP_PKEY_new();
+ }
+ S2N_ERROR_IF(ecc_evp_params->evp_pkey == NULL, S2N_ERR_BAD_MESSAGE);
+ /* Create a key to store the point */
+ DEFER_CLEANUP(EC_KEY *ec_key = EC_KEY_new_by_curve_name(ecc_evp_params->negotiated_curve->libcrypto_nid),
+ EC_KEY_free_pointer);
+ S2N_ERROR_IF(ec_key == NULL, S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+
+ /* Parse and store the server public point */
+ DEFER_CLEANUP(EC_POINT *point = s2n_ecc_evp_blob_to_point(point_blob, ec_key), EC_POINT_free_pointer);
+ S2N_ERROR_IF(point == NULL, S2N_ERR_BAD_MESSAGE);
+
+ /* Set the point as the public key */
+ int success = EC_KEY_set_public_key(ec_key, point);
+
+ GUARD_OSSL(EVP_PKEY_set1_EC_KEY(ecc_evp_params->evp_pkey,ec_key), S2N_ERR_ECDHE_SERIALIZING);
+
+ /* EC_KEY_set_public_key returns 1 on success, 0 on failure */
+ S2N_ERROR_IF(success == 0, S2N_ERR_BAD_MESSAGE);
+
+#endif
+ return 0;
+}
+
+int s2n_ecc_evp_parse_params(struct s2n_ecdhe_raw_server_params *raw_server_ecc_params,
+ struct s2n_ecc_evp_params *ecc_evp_params) {
+ S2N_ERROR_IF(
+ s2n_ecc_evp_find_supported_curve(&raw_server_ecc_params->curve_blob, &ecc_evp_params->negotiated_curve) != 0,
+ S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+ return s2n_ecc_evp_parse_params_point(&raw_server_ecc_params->point_blob, ecc_evp_params);
+}
+
+int s2n_ecc_evp_find_supported_curve(struct s2n_blob *iana_ids, const struct s2n_ecc_named_curve **found) {
+ struct s2n_stuffer iana_ids_in = {0};
+
+ GUARD(s2n_stuffer_init(&iana_ids_in, iana_ids));
+ GUARD(s2n_stuffer_write(&iana_ids_in, iana_ids));
+ for (int i = 0; i < s2n_all_supported_curves_list_len; i++) {
+ const struct s2n_ecc_named_curve *supported_curve = s2n_all_supported_curves_list[i];
+ for (int j = 0; j < iana_ids->size / 2; j++) {
+ uint16_t iana_id;
+ GUARD(s2n_stuffer_read_uint16(&iana_ids_in, &iana_id));
+ if (supported_curve->iana_id == iana_id) {
+ *found = supported_curve;
+ return 0;
+ }
+ }
+ GUARD(s2n_stuffer_reread(&iana_ids_in));
+ }
+
+ S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE);
+}
+
+int s2n_ecc_evp_params_free(struct s2n_ecc_evp_params *ecc_evp_params) {
+ if (ecc_evp_params->evp_pkey != NULL) {
+ EVP_PKEY_free(ecc_evp_params->evp_pkey);
+ ecc_evp_params->evp_pkey = NULL;
+ }
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.h b/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.h
index f9b8c8f7e2..e8905f2d28 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.h
@@ -1,89 +1,89 @@
-/*
- * 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 <openssl/evp.h>
-
-#include "crypto/s2n_hash.h"
-#include "tls/s2n_kex_data.h"
-#include "stuffer/s2n_stuffer.h"
-#include "tls/s2n_tls_parameters.h"
-#include "utils/s2n_safety.h"
-
-/* Share sizes are described here: https://tools.ietf.org/html/rfc8446#section-4.2.8.2
- * and include the extra "legacy_form" byte */
-#define SECP256R1_SHARE_SIZE ((32 * 2 ) + 1)
-#define SECP384R1_SHARE_SIZE ((48 * 2 ) + 1)
-#define SECP521R1_SHARE_SIZE ((66 * 2 ) + 1)
-#define X25519_SHARE_SIZE (32)
-
-struct s2n_ecc_named_curve {
- /* See https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 */
- uint16_t iana_id;
- /* See nid_list in openssl/ssl/t1_lib.c */
- int libcrypto_nid;
- const char *name;
- const uint8_t share_size;
- int (*generate_key) (const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
-};
-
-extern const struct s2n_ecc_named_curve s2n_ecc_curve_secp256r1;
-extern const struct s2n_ecc_named_curve s2n_ecc_curve_secp384r1;
-extern const struct s2n_ecc_named_curve s2n_ecc_curve_secp521r1;
-extern const struct s2n_ecc_named_curve s2n_ecc_curve_x25519;
-
-/* BoringSSL only supports using EVP_PKEY_X25519 with "modern" EC EVP APIs. BoringSSL has a note to possibly add this in
- * the future. See https://github.com/google/boringssl/blob/master/crypto/evp/p_x25519_asn1.c#L233
- */
-#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
- #define EVP_APIS_SUPPORTED 1
- #define S2N_ECC_EVP_SUPPORTED_CURVES_COUNT 4
-#else
- #define EVP_APIS_SUPPORTED 0
- #define S2N_ECC_EVP_SUPPORTED_CURVES_COUNT 3
-#endif
-
-extern const struct s2n_ecc_named_curve *const s2n_all_supported_curves_list[];
-extern const size_t s2n_all_supported_curves_list_len;
-
-struct s2n_ecc_evp_params {
- const struct s2n_ecc_named_curve *negotiated_curve;
- EVP_PKEY *evp_pkey;
-};
-
-int s2n_ecc_evp_generate_ephemeral_key(struct s2n_ecc_evp_params *ecc_evp_params);
-int s2n_ecc_evp_compute_shared_secret_from_params(struct s2n_ecc_evp_params *private_ecc_evp_params,
- struct s2n_ecc_evp_params *public_ecc_evp_params,
- struct s2n_blob *shared_key);
-int s2n_ecc_evp_write_params_point(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out);
-int s2n_ecc_evp_read_params_point(struct s2n_stuffer *in, int point_size, struct s2n_blob *point_blob);
-int s2n_ecc_evp_compute_shared_secret_from_params(struct s2n_ecc_evp_params *private_ecc_evp_params,
- struct s2n_ecc_evp_params *public_ecc_evp_params,
- struct s2n_blob *shared_key);
-int s2n_ecc_evp_compute_shared_secret_as_server(struct s2n_ecc_evp_params *server_ecc_evp_params,
- struct s2n_stuffer *Yc_in, struct s2n_blob *shared_key);
-int s2n_ecc_evp_compute_shared_secret_as_client(struct s2n_ecc_evp_params *server_ecc_evp_params,
- struct s2n_stuffer *Yc_out, struct s2n_blob *shared_key);
-int s2n_ecc_evp_parse_params_point(struct s2n_blob *point_blob, struct s2n_ecc_evp_params *ecc_evp_params);
-int s2n_ecc_evp_write_params(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out,
- struct s2n_blob *written);
-int s2n_ecc_evp_read_params(struct s2n_stuffer *in, struct s2n_blob *data_to_verify,
- struct s2n_ecdhe_raw_server_params *raw_server_ecc_params);
-int s2n_ecc_evp_parse_params(struct s2n_ecdhe_raw_server_params *raw_server_ecc_params,
- struct s2n_ecc_evp_params *ecc_evp_params);
-int s2n_ecc_evp_find_supported_curve(struct s2n_blob *iana_ids, const struct s2n_ecc_named_curve **found);
-int s2n_ecc_evp_params_free(struct s2n_ecc_evp_params *ecc_evp_params);
-int s2n_is_evp_apis_supported();
+/*
+ * 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 <openssl/evp.h>
+
+#include "crypto/s2n_hash.h"
+#include "tls/s2n_kex_data.h"
+#include "stuffer/s2n_stuffer.h"
+#include "tls/s2n_tls_parameters.h"
+#include "utils/s2n_safety.h"
+
+/* Share sizes are described here: https://tools.ietf.org/html/rfc8446#section-4.2.8.2
+ * and include the extra "legacy_form" byte */
+#define SECP256R1_SHARE_SIZE ((32 * 2 ) + 1)
+#define SECP384R1_SHARE_SIZE ((48 * 2 ) + 1)
+#define SECP521R1_SHARE_SIZE ((66 * 2 ) + 1)
+#define X25519_SHARE_SIZE (32)
+
+struct s2n_ecc_named_curve {
+ /* See https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 */
+ uint16_t iana_id;
+ /* See nid_list in openssl/ssl/t1_lib.c */
+ int libcrypto_nid;
+ const char *name;
+ const uint8_t share_size;
+ int (*generate_key) (const struct s2n_ecc_named_curve *named_curve, EVP_PKEY **evp_pkey);
+};
+
+extern const struct s2n_ecc_named_curve s2n_ecc_curve_secp256r1;
+extern const struct s2n_ecc_named_curve s2n_ecc_curve_secp384r1;
+extern const struct s2n_ecc_named_curve s2n_ecc_curve_secp521r1;
+extern const struct s2n_ecc_named_curve s2n_ecc_curve_x25519;
+
+/* BoringSSL only supports using EVP_PKEY_X25519 with "modern" EC EVP APIs. BoringSSL has a note to possibly add this in
+ * the future. See https://github.com/google/boringssl/blob/master/crypto/evp/p_x25519_asn1.c#L233
+ */
+#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0) && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL)
+ #define EVP_APIS_SUPPORTED 1
+ #define S2N_ECC_EVP_SUPPORTED_CURVES_COUNT 4
+#else
+ #define EVP_APIS_SUPPORTED 0
+ #define S2N_ECC_EVP_SUPPORTED_CURVES_COUNT 3
+#endif
+
+extern const struct s2n_ecc_named_curve *const s2n_all_supported_curves_list[];
+extern const size_t s2n_all_supported_curves_list_len;
+
+struct s2n_ecc_evp_params {
+ const struct s2n_ecc_named_curve *negotiated_curve;
+ EVP_PKEY *evp_pkey;
+};
+
+int s2n_ecc_evp_generate_ephemeral_key(struct s2n_ecc_evp_params *ecc_evp_params);
+int s2n_ecc_evp_compute_shared_secret_from_params(struct s2n_ecc_evp_params *private_ecc_evp_params,
+ struct s2n_ecc_evp_params *public_ecc_evp_params,
+ struct s2n_blob *shared_key);
+int s2n_ecc_evp_write_params_point(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out);
+int s2n_ecc_evp_read_params_point(struct s2n_stuffer *in, int point_size, struct s2n_blob *point_blob);
+int s2n_ecc_evp_compute_shared_secret_from_params(struct s2n_ecc_evp_params *private_ecc_evp_params,
+ struct s2n_ecc_evp_params *public_ecc_evp_params,
+ struct s2n_blob *shared_key);
+int s2n_ecc_evp_compute_shared_secret_as_server(struct s2n_ecc_evp_params *server_ecc_evp_params,
+ struct s2n_stuffer *Yc_in, struct s2n_blob *shared_key);
+int s2n_ecc_evp_compute_shared_secret_as_client(struct s2n_ecc_evp_params *server_ecc_evp_params,
+ struct s2n_stuffer *Yc_out, struct s2n_blob *shared_key);
+int s2n_ecc_evp_parse_params_point(struct s2n_blob *point_blob, struct s2n_ecc_evp_params *ecc_evp_params);
+int s2n_ecc_evp_write_params(struct s2n_ecc_evp_params *ecc_evp_params, struct s2n_stuffer *out,
+ struct s2n_blob *written);
+int s2n_ecc_evp_read_params(struct s2n_stuffer *in, struct s2n_blob *data_to_verify,
+ struct s2n_ecdhe_raw_server_params *raw_server_ecc_params);
+int s2n_ecc_evp_parse_params(struct s2n_ecdhe_raw_server_params *raw_server_ecc_params,
+ struct s2n_ecc_evp_params *ecc_evp_params);
+int s2n_ecc_evp_find_supported_curve(struct s2n_blob *iana_ids, const struct s2n_ecc_named_curve **found);
+int s2n_ecc_evp_params_free(struct s2n_ecc_evp_params *ecc_evp_params);
+int s2n_is_evp_apis_supported();
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c
index d1d37d1bee..05893201ca 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c
@@ -1,173 +1,173 @@
-/*
- * 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 <openssl/ec.h>
-#include <openssl/ecdsa.h>
-#include <openssl/x509.h>
-#include "stuffer/s2n_stuffer.h"
-
-#include "error/s2n_errno.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_safety.h"
-
-#include "crypto/s2n_ecdsa.h"
-#include "crypto/s2n_ecc_evp.h"
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_openssl.h"
-#include "crypto/s2n_pkey.h"
-
-int s2n_ecdsa_der_signature_size(const struct s2n_pkey *pkey)
-{
- const struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
- notnull_check(ecdsa_key->ec_key);
-
- return ECDSA_size(ecdsa_key->ec_key);
-}
-
-static int s2n_ecdsa_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature)
-{
- sig_alg_check(sig_alg, S2N_SIGNATURE_ECDSA);
-
- const s2n_ecdsa_private_key *key = &priv->key.ecdsa_key;
- notnull_check(key->ec_key);
-
- uint8_t digest_length;
- GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
- lte_check(digest_length, S2N_MAX_DIGEST_LEN);
-
- uint8_t digest_out[S2N_MAX_DIGEST_LEN];
- GUARD(s2n_hash_digest(digest, digest_out, digest_length));
-
- unsigned int signature_size = signature->size;
- GUARD_OSSL(ECDSA_sign(0, digest_out, digest_length, signature->data, &signature_size, key->ec_key), S2N_ERR_SIGN);
- S2N_ERROR_IF(signature_size > signature->size, S2N_ERR_SIZE_MISMATCH);
- signature->size = signature_size;
-
- GUARD(s2n_hash_reset(digest));
-
- return 0;
-}
-
-static int s2n_ecdsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature)
-{
- sig_alg_check(sig_alg, S2N_SIGNATURE_ECDSA);
-
- const s2n_ecdsa_public_key *key = &pub->key.ecdsa_key;
- notnull_check(key->ec_key);
-
- uint8_t digest_length;
- GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
- lte_check(digest_length, S2N_MAX_DIGEST_LEN);
-
- uint8_t digest_out[S2N_MAX_DIGEST_LEN];
- GUARD(s2n_hash_digest(digest, digest_out, digest_length));
-
- /* ECDSA_verify ignores the first parameter */
- GUARD_OSSL(ECDSA_verify(0, digest_out, digest_length, signature->data, signature->size, key->ec_key), S2N_ERR_VERIFY_SIGNATURE);
-
- GUARD(s2n_hash_reset(digest));
-
- return 0;
-}
-
-static int s2n_ecdsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
-{
- uint8_t input[16] = { 1 };
- DEFER_CLEANUP(struct s2n_blob signature = { 0 }, s2n_free);
- DEFER_CLEANUP(struct s2n_hash_state state_in = { 0 }, s2n_hash_free);
- DEFER_CLEANUP(struct s2n_hash_state state_out = { 0 }, s2n_hash_free);
-
- /* s2n_hash_new only allocates memory when using high-level EVP hashes, currently restricted to FIPS mode. */
- GUARD(s2n_hash_new(&state_in));
- GUARD(s2n_hash_new(&state_out));
-
- GUARD(s2n_hash_init(&state_in, S2N_HASH_SHA1));
- GUARD(s2n_hash_init(&state_out, S2N_HASH_SHA1));
- GUARD(s2n_hash_update(&state_in, input, sizeof(input)));
- GUARD(s2n_hash_update(&state_out, input, sizeof(input)));
-
- GUARD(s2n_alloc(&signature, s2n_ecdsa_der_signature_size(priv)));
-
- GUARD(s2n_ecdsa_sign(priv, S2N_SIGNATURE_ECDSA, &state_in, &signature));
- GUARD(s2n_ecdsa_verify(pub, S2N_SIGNATURE_ECDSA, &state_out, &signature));
-
- return 0;
-}
-
-static int s2n_ecdsa_key_free(struct s2n_pkey *pkey)
-{
- struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
- if (ecdsa_key->ec_key == NULL) {
- return 0;
- }
-
- EC_KEY_free(ecdsa_key->ec_key);
- ecdsa_key->ec_key = NULL;
-
- return 0;
-}
-
-static int s2n_ecdsa_check_key_exists(const struct s2n_pkey *pkey)
-{
- const struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
- notnull_check(ecdsa_key->ec_key);
- return 0;
-}
-
-int s2n_evp_pkey_to_ecdsa_private_key(s2n_ecdsa_private_key *ecdsa_key, EVP_PKEY *evp_private_key)
-{
- EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_private_key);
- S2N_ERROR_IF(ec_key == NULL, S2N_ERR_DECODE_PRIVATE_KEY);
-
- ecdsa_key->ec_key = ec_key;
- return 0;
-}
-
-int s2n_evp_pkey_to_ecdsa_public_key(s2n_ecdsa_public_key *ecdsa_key, EVP_PKEY *evp_public_key)
-{
- EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_public_key);
- S2N_ERROR_IF(ec_key == NULL, S2N_ERR_DECODE_CERTIFICATE);
-
- ecdsa_key->ec_key = ec_key;
- return 0;
-}
-
-int s2n_ecdsa_pkey_init(struct s2n_pkey *pkey) {
- pkey->size = &s2n_ecdsa_der_signature_size;
- pkey->sign = &s2n_ecdsa_sign;
- pkey->verify = &s2n_ecdsa_verify;
- pkey->encrypt = NULL; /* No function for encryption */
- pkey->decrypt = NULL; /* No function for decryption */
- pkey->match = &s2n_ecdsa_keys_match;
- pkey->free = &s2n_ecdsa_key_free;
- pkey->check_key = &s2n_ecdsa_check_key_exists;
- return 0;
-}
-
-int s2n_ecdsa_pkey_matches_curve(const struct s2n_ecdsa_key *ecdsa_key, const struct s2n_ecc_named_curve *curve)
-{
- notnull_check(ecdsa_key);
- notnull_check(ecdsa_key->ec_key);
- notnull_check(curve);
-
- int curve_id = EC_GROUP_get_curve_name(EC_KEY_get0_group(ecdsa_key->ec_key));
- eq_check(curve_id, curve->libcrypto_nid);
-
- return 0;
-}
+/*
+ * 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 <openssl/ec.h>
+#include <openssl/ecdsa.h>
+#include <openssl/x509.h>
+#include "stuffer/s2n_stuffer.h"
+
+#include "error/s2n_errno.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_safety.h"
+
+#include "crypto/s2n_ecdsa.h"
+#include "crypto/s2n_ecc_evp.h"
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_openssl.h"
+#include "crypto/s2n_pkey.h"
+
+int s2n_ecdsa_der_signature_size(const struct s2n_pkey *pkey)
+{
+ const struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
+ notnull_check(ecdsa_key->ec_key);
+
+ return ECDSA_size(ecdsa_key->ec_key);
+}
+
+static int s2n_ecdsa_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature)
+{
+ sig_alg_check(sig_alg, S2N_SIGNATURE_ECDSA);
+
+ const s2n_ecdsa_private_key *key = &priv->key.ecdsa_key;
+ notnull_check(key->ec_key);
+
+ uint8_t digest_length;
+ GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
+ lte_check(digest_length, S2N_MAX_DIGEST_LEN);
+
+ uint8_t digest_out[S2N_MAX_DIGEST_LEN];
+ GUARD(s2n_hash_digest(digest, digest_out, digest_length));
+
+ unsigned int signature_size = signature->size;
+ GUARD_OSSL(ECDSA_sign(0, digest_out, digest_length, signature->data, &signature_size, key->ec_key), S2N_ERR_SIGN);
+ S2N_ERROR_IF(signature_size > signature->size, S2N_ERR_SIZE_MISMATCH);
+ signature->size = signature_size;
+
+ GUARD(s2n_hash_reset(digest));
+
+ return 0;
+}
+
+static int s2n_ecdsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature)
+{
+ sig_alg_check(sig_alg, S2N_SIGNATURE_ECDSA);
+
+ const s2n_ecdsa_public_key *key = &pub->key.ecdsa_key;
+ notnull_check(key->ec_key);
+
+ uint8_t digest_length;
+ GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
+ lte_check(digest_length, S2N_MAX_DIGEST_LEN);
+
+ uint8_t digest_out[S2N_MAX_DIGEST_LEN];
+ GUARD(s2n_hash_digest(digest, digest_out, digest_length));
+
+ /* ECDSA_verify ignores the first parameter */
+ GUARD_OSSL(ECDSA_verify(0, digest_out, digest_length, signature->data, signature->size, key->ec_key), S2N_ERR_VERIFY_SIGNATURE);
+
+ GUARD(s2n_hash_reset(digest));
+
+ return 0;
+}
+
+static int s2n_ecdsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
+{
+ uint8_t input[16] = { 1 };
+ DEFER_CLEANUP(struct s2n_blob signature = { 0 }, s2n_free);
+ DEFER_CLEANUP(struct s2n_hash_state state_in = { 0 }, s2n_hash_free);
+ DEFER_CLEANUP(struct s2n_hash_state state_out = { 0 }, s2n_hash_free);
+
+ /* s2n_hash_new only allocates memory when using high-level EVP hashes, currently restricted to FIPS mode. */
+ GUARD(s2n_hash_new(&state_in));
+ GUARD(s2n_hash_new(&state_out));
+
+ GUARD(s2n_hash_init(&state_in, S2N_HASH_SHA1));
+ GUARD(s2n_hash_init(&state_out, S2N_HASH_SHA1));
+ GUARD(s2n_hash_update(&state_in, input, sizeof(input)));
+ GUARD(s2n_hash_update(&state_out, input, sizeof(input)));
+
+ GUARD(s2n_alloc(&signature, s2n_ecdsa_der_signature_size(priv)));
+
+ GUARD(s2n_ecdsa_sign(priv, S2N_SIGNATURE_ECDSA, &state_in, &signature));
+ GUARD(s2n_ecdsa_verify(pub, S2N_SIGNATURE_ECDSA, &state_out, &signature));
+
+ return 0;
+}
+
+static int s2n_ecdsa_key_free(struct s2n_pkey *pkey)
+{
+ struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
+ if (ecdsa_key->ec_key == NULL) {
+ return 0;
+ }
+
+ EC_KEY_free(ecdsa_key->ec_key);
+ ecdsa_key->ec_key = NULL;
+
+ return 0;
+}
+
+static int s2n_ecdsa_check_key_exists(const struct s2n_pkey *pkey)
+{
+ const struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key;
+ notnull_check(ecdsa_key->ec_key);
+ return 0;
+}
+
+int s2n_evp_pkey_to_ecdsa_private_key(s2n_ecdsa_private_key *ecdsa_key, EVP_PKEY *evp_private_key)
+{
+ EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_private_key);
+ S2N_ERROR_IF(ec_key == NULL, S2N_ERR_DECODE_PRIVATE_KEY);
+
+ ecdsa_key->ec_key = ec_key;
+ return 0;
+}
+
+int s2n_evp_pkey_to_ecdsa_public_key(s2n_ecdsa_public_key *ecdsa_key, EVP_PKEY *evp_public_key)
+{
+ EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(evp_public_key);
+ S2N_ERROR_IF(ec_key == NULL, S2N_ERR_DECODE_CERTIFICATE);
+
+ ecdsa_key->ec_key = ec_key;
+ return 0;
+}
+
+int s2n_ecdsa_pkey_init(struct s2n_pkey *pkey) {
+ pkey->size = &s2n_ecdsa_der_signature_size;
+ pkey->sign = &s2n_ecdsa_sign;
+ pkey->verify = &s2n_ecdsa_verify;
+ pkey->encrypt = NULL; /* No function for encryption */
+ pkey->decrypt = NULL; /* No function for decryption */
+ pkey->match = &s2n_ecdsa_keys_match;
+ pkey->free = &s2n_ecdsa_key_free;
+ pkey->check_key = &s2n_ecdsa_check_key_exists;
+ return 0;
+}
+
+int s2n_ecdsa_pkey_matches_curve(const struct s2n_ecdsa_key *ecdsa_key, const struct s2n_ecc_named_curve *curve)
+{
+ notnull_check(ecdsa_key);
+ notnull_check(ecdsa_key->ec_key);
+ notnull_check(curve);
+
+ int curve_id = EC_GROUP_get_curve_name(EC_KEY_get0_group(ecdsa_key->ec_key));
+ eq_check(curve_id, curve->libcrypto_nid);
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h
index 6911cf4387..84216a99be 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h
@@ -1,43 +1,43 @@
-/*
- * 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 <openssl/ecdsa.h>
-#include <stdint.h>
-#include <s2n.h>
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_ecc_evp.h"
-#include "crypto/s2n_hash.h"
-
-#include "utils/s2n_blob.h"
-
-/* Forward declaration to avoid the circular dependency with s2n_pkey.h */
-struct s2n_pkey;
-
-struct s2n_ecdsa_key {
- EC_KEY *ec_key;
-};
-
-typedef struct s2n_ecdsa_key s2n_ecdsa_public_key;
-typedef struct s2n_ecdsa_key s2n_ecdsa_private_key;
-
-extern int s2n_ecdsa_pkey_init(struct s2n_pkey *pkey);
-extern int s2n_ecdsa_pkey_matches_curve(const struct s2n_ecdsa_key *ecdsa_key, const struct s2n_ecc_named_curve *curve);
-
-extern int s2n_evp_pkey_to_ecdsa_public_key(s2n_ecdsa_public_key *ecdsa_key, EVP_PKEY *pkey);
-extern int s2n_evp_pkey_to_ecdsa_private_key(s2n_ecdsa_private_key *ecdsa_key, EVP_PKEY *pkey);
+/*
+ * 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 <openssl/ecdsa.h>
+#include <stdint.h>
+#include <s2n.h>
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_ecc_evp.h"
+#include "crypto/s2n_hash.h"
+
+#include "utils/s2n_blob.h"
+
+/* Forward declaration to avoid the circular dependency with s2n_pkey.h */
+struct s2n_pkey;
+
+struct s2n_ecdsa_key {
+ EC_KEY *ec_key;
+};
+
+typedef struct s2n_ecdsa_key s2n_ecdsa_public_key;
+typedef struct s2n_ecdsa_key s2n_ecdsa_private_key;
+
+extern int s2n_ecdsa_pkey_init(struct s2n_pkey *pkey);
+extern int s2n_ecdsa_pkey_matches_curve(const struct s2n_ecdsa_key *ecdsa_key, const struct s2n_ecc_named_curve *curve);
+
+extern int s2n_evp_pkey_to_ecdsa_public_key(s2n_ecdsa_public_key *ecdsa_key, EVP_PKEY *pkey);
+extern int s2n_evp_pkey_to_ecdsa_private_key(s2n_ecdsa_private_key *ecdsa_key, EVP_PKEY *pkey);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_evp.c b/contrib/restricted/aws/s2n/crypto/s2n_evp.c
index 11aac21f75..a8fad67b48 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_evp.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_evp.c
@@ -1,47 +1,47 @@
-/*
- * 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 "crypto/s2n_evp.h"
-#include "crypto/s2n_fips.h"
-#include "error/s2n_errno.h"
-#include "utils/s2n_safety.h"
-
-int s2n_digest_allow_md5_for_fips(struct s2n_evp_digest *evp_digest)
-{
- notnull_check(evp_digest);
- /* This is only to be used for EVP digests that will require MD5 to be used
- * to comply with the TLS 1.0 and 1.1 RFC's for the PRF. MD5 cannot be used
- * outside of the TLS 1.0 and 1.1 PRF when in FIPS mode.
- */
- S2N_ERROR_IF(!s2n_is_in_fips_mode() || (evp_digest->ctx == NULL), S2N_ERR_ALLOW_MD5_FOR_FIPS_FAILED);
-
-#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
- EVP_MD_CTX_set_flags(evp_digest->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
-#endif
- return S2N_SUCCESS;
-}
-
-S2N_RESULT s2n_digest_is_md5_allowed_for_fips(struct s2n_evp_digest *evp_digest, bool *out)
-{
- ENSURE_REF(out);
- *out = false;
-#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
- if (evp_digest && evp_digest->ctx && s2n_is_in_fips_mode() && EVP_MD_CTX_test_flags(evp_digest->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) {
- /* s2n is in FIPS mode and the EVP digest allows MD5. */
- *out = true;
- }
-#endif
- return S2N_RESULT_OK;
-}
+/*
+ * 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 "crypto/s2n_evp.h"
+#include "crypto/s2n_fips.h"
+#include "error/s2n_errno.h"
+#include "utils/s2n_safety.h"
+
+int s2n_digest_allow_md5_for_fips(struct s2n_evp_digest *evp_digest)
+{
+ notnull_check(evp_digest);
+ /* This is only to be used for EVP digests that will require MD5 to be used
+ * to comply with the TLS 1.0 and 1.1 RFC's for the PRF. MD5 cannot be used
+ * outside of the TLS 1.0 and 1.1 PRF when in FIPS mode.
+ */
+ S2N_ERROR_IF(!s2n_is_in_fips_mode() || (evp_digest->ctx == NULL), S2N_ERR_ALLOW_MD5_FOR_FIPS_FAILED);
+
+#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
+ EVP_MD_CTX_set_flags(evp_digest->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
+#endif
+ return S2N_SUCCESS;
+}
+
+S2N_RESULT s2n_digest_is_md5_allowed_for_fips(struct s2n_evp_digest *evp_digest, bool *out)
+{
+ ENSURE_REF(out);
+ *out = false;
+#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
+ if (evp_digest && evp_digest->ctx && s2n_is_in_fips_mode() && EVP_MD_CTX_test_flags(evp_digest->ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW)) {
+ /* s2n is in FIPS mode and the EVP digest allows MD5. */
+ *out = true;
+ }
+#endif
+ return S2N_RESULT_OK;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_evp.h b/contrib/restricted/aws/s2n/crypto/s2n_evp.h
index 92d30bccc8..80a059df2b 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_evp.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_evp.h
@@ -1,45 +1,45 @@
-/*
- * 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 <openssl/evp.h>
-
-#include "crypto/s2n_openssl.h"
-#include "utils/s2n_result.h"
-
-struct s2n_evp_digest {
- const EVP_MD *md;
- EVP_MD_CTX *ctx;
-};
-
-struct s2n_evp_hmac_state {
- struct s2n_evp_digest evp_digest;
- EVP_PKEY *mac_key;
-};
-
-/* Define API's that change based on the OpenSSL Major Version. */
-#if S2N_OPENSSL_VERSION_AT_LEAST(1,1,0) && !defined(LIBRESSL_VERSION_NUMBER)
-#define S2N_EVP_MD_CTX_NEW() (EVP_MD_CTX_new())
-#define S2N_EVP_MD_CTX_RESET(md_ctx) (EVP_MD_CTX_reset(md_ctx))
-#define S2N_EVP_MD_CTX_FREE(md_ctx) (EVP_MD_CTX_free(md_ctx))
-#else
-#define S2N_EVP_MD_CTX_NEW() (EVP_MD_CTX_create())
-#define S2N_EVP_MD_CTX_RESET(md_ctx) (EVP_MD_CTX_cleanup(md_ctx))
-#define S2N_EVP_MD_CTX_FREE(md_ctx) (EVP_MD_CTX_destroy(md_ctx))
-#endif
-
-extern int s2n_digest_allow_md5_for_fips(struct s2n_evp_digest *evp_digest);
-extern S2N_RESULT s2n_digest_is_md5_allowed_for_fips(struct s2n_evp_digest *evp_digest, bool *out);
+/*
+ * 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 <openssl/evp.h>
+
+#include "crypto/s2n_openssl.h"
+#include "utils/s2n_result.h"
+
+struct s2n_evp_digest {
+ const EVP_MD *md;
+ EVP_MD_CTX *ctx;
+};
+
+struct s2n_evp_hmac_state {
+ struct s2n_evp_digest evp_digest;
+ EVP_PKEY *mac_key;
+};
+
+/* Define API's that change based on the OpenSSL Major Version. */
+#if S2N_OPENSSL_VERSION_AT_LEAST(1,1,0) && !defined(LIBRESSL_VERSION_NUMBER)
+#define S2N_EVP_MD_CTX_NEW() (EVP_MD_CTX_new())
+#define S2N_EVP_MD_CTX_RESET(md_ctx) (EVP_MD_CTX_reset(md_ctx))
+#define S2N_EVP_MD_CTX_FREE(md_ctx) (EVP_MD_CTX_free(md_ctx))
+#else
+#define S2N_EVP_MD_CTX_NEW() (EVP_MD_CTX_create())
+#define S2N_EVP_MD_CTX_RESET(md_ctx) (EVP_MD_CTX_cleanup(md_ctx))
+#define S2N_EVP_MD_CTX_FREE(md_ctx) (EVP_MD_CTX_destroy(md_ctx))
+#endif
+
+extern int s2n_digest_allow_md5_for_fips(struct s2n_evp_digest *evp_digest);
+extern S2N_RESULT s2n_digest_is_md5_allowed_for_fips(struct s2n_evp_digest *evp_digest, bool *out);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_fips.c b/contrib/restricted/aws/s2n/crypto/s2n_fips.c
index d939cc3b53..d8ae231c15 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_fips.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_fips.c
@@ -1,40 +1,40 @@
-/*
- * 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 <openssl/crypto.h>
-
-#include "crypto/s2n_fips.h"
-
-static int s2n_fips_mode = 0;
-
-int s2n_fips_init(void)
-{
- s2n_fips_mode = 0;
-
-#ifdef OPENSSL_FIPS
- /* FIPS mode can be entered only if OPENSSL_FIPS is defined */
- if (FIPS_mode()) {
- s2n_fips_mode = 1;
- }
-#endif
-
- return 0;
-}
-
-/* Return 1 if FIPS mode is enabled, 0 otherwise. FIPS mode must be enabled prior to calling s2n_init(). */
-int s2n_is_in_fips_mode(void)
-{
- return s2n_fips_mode;
-}
+/*
+ * 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 <openssl/crypto.h>
+
+#include "crypto/s2n_fips.h"
+
+static int s2n_fips_mode = 0;
+
+int s2n_fips_init(void)
+{
+ s2n_fips_mode = 0;
+
+#ifdef OPENSSL_FIPS
+ /* FIPS mode can be entered only if OPENSSL_FIPS is defined */
+ if (FIPS_mode()) {
+ s2n_fips_mode = 1;
+ }
+#endif
+
+ return 0;
+}
+
+/* Return 1 if FIPS mode is enabled, 0 otherwise. FIPS mode must be enabled prior to calling s2n_init(). */
+int s2n_is_in_fips_mode(void)
+{
+ return s2n_fips_mode;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_fips.h b/contrib/restricted/aws/s2n/crypto/s2n_fips.h
index 23c3ea4bd0..7f54a24371 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_fips.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_fips.h
@@ -1,19 +1,19 @@
-/*
- * 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
-
-extern int s2n_fips_init(void);
-extern int s2n_is_in_fips_mode(void);
+/*
+ * 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
+
+extern int s2n_fips_init(void);
+extern int s2n_is_in_fips_mode(void);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hash.c b/contrib/restricted/aws/s2n/crypto/s2n_hash.c
index 0a3ad28130..9aef3bd400 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_hash.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_hash.c
@@ -1,647 +1,647 @@
-/*
- * 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 "error/s2n_errno.h"
-
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_hmac.h"
-#include "crypto/s2n_openssl.h"
-#include "crypto/s2n_fips.h"
-
-#include "utils/s2n_safety.h"
-
-int s2n_hash_hmac_alg(s2n_hash_algorithm hash_alg, s2n_hmac_algorithm *out)
-{
- ENSURE_POSIX(S2N_MEM_IS_READABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
- switch(hash_alg) {
- case S2N_HASH_NONE: *out = S2N_HMAC_NONE; break;
- case S2N_HASH_MD5: *out = S2N_HMAC_MD5; break;
- case S2N_HASH_SHA1: *out = S2N_HMAC_SHA1; break;
- case S2N_HASH_SHA224: *out = S2N_HMAC_SHA224; break;
- case S2N_HASH_SHA256: *out = S2N_HMAC_SHA256; break;
- case S2N_HASH_SHA384: *out = S2N_HMAC_SHA384; break;
- case S2N_HASH_SHA512: *out = S2N_HMAC_SHA512; break;
- case S2N_HASH_MD5_SHA1: /* Fall through ... */
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
- return S2N_SUCCESS;
-}
-
-int s2n_hash_digest_size(s2n_hash_algorithm alg, uint8_t *out)
-{
- notnull_check(out);
- switch (alg) {
- case S2N_HASH_NONE: *out = 0; break;
- case S2N_HASH_MD5: *out = MD5_DIGEST_LENGTH; break;
- case S2N_HASH_SHA1: *out = SHA_DIGEST_LENGTH; break;
- case S2N_HASH_SHA224: *out = SHA224_DIGEST_LENGTH; break;
- case S2N_HASH_SHA256: *out = SHA256_DIGEST_LENGTH; break;
- case S2N_HASH_SHA384: *out = SHA384_DIGEST_LENGTH; break;
- case S2N_HASH_SHA512: *out = SHA512_DIGEST_LENGTH; break;
- case S2N_HASH_MD5_SHA1: *out = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; break;
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
- return S2N_SUCCESS;
-}
-
-/* NOTE: s2n_hash_const_time_get_currently_in_hash_block takes advantage of the fact that
- * hash_block_size is a power of 2. This is true for all hashes we currently support
- * If this ever becomes untrue, this would require fixing*/
-int s2n_hash_block_size(s2n_hash_algorithm alg, uint64_t *block_size)
-{
- ENSURE_POSIX(S2N_MEM_IS_READABLE(block_size, sizeof(*block_size)), S2N_ERR_PRECONDITION_VIOLATION);
- switch(alg) {
- case S2N_HASH_NONE: *block_size = 64; break;
- case S2N_HASH_MD5: *block_size = 64; break;
- case S2N_HASH_SHA1: *block_size = 64; break;
- case S2N_HASH_SHA224: *block_size = 64; break;
- case S2N_HASH_SHA256: *block_size = 64; break;
- case S2N_HASH_SHA384: *block_size = 128; break;
- case S2N_HASH_SHA512: *block_size = 128; break;
- case S2N_HASH_MD5_SHA1: *block_size = 64; break;
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
- return S2N_SUCCESS;
-}
-
-/* Return true if hash algorithm is available, false otherwise. */
-bool s2n_hash_is_available(s2n_hash_algorithm alg)
-{
- switch (alg) {
- case S2N_HASH_MD5:
- case S2N_HASH_MD5_SHA1:
- /* return false if in FIPS mode, as MD5 algs are not available in FIPS mode. */
- return !s2n_is_in_fips_mode();
- case S2N_HASH_NONE:
- case S2N_HASH_SHA1:
- case S2N_HASH_SHA224:
- case S2N_HASH_SHA256:
- case S2N_HASH_SHA384:
- case S2N_HASH_SHA512:
- return true;
- case S2N_HASH_SENTINEL:
- return false;
- }
- return false;
-}
-
-int s2n_hash_is_ready_for_input(struct s2n_hash_state *state)
-{
- PRECONDITION_POSIX(s2n_hash_state_validate(state));
- return state->is_ready_for_input;
-}
-
-static int s2n_low_level_hash_new(struct s2n_hash_state *state)
-{
- /* s2n_hash_new will always call the corresponding implementation of the s2n_hash
- * being used. For the s2n_low_level_hash implementation, new is a no-op.
- */
-
- state->is_ready_for_input = 0;
- state->currently_in_hash = 0;
- return S2N_SUCCESS;
-}
-
-static int s2n_low_level_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg)
-{
- switch (alg) {
- case S2N_HASH_NONE:
- break;
- case S2N_HASH_MD5:
- GUARD_OSSL(MD5_Init(&state->digest.low_level.md5), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_SHA1:
- GUARD_OSSL(SHA1_Init(&state->digest.low_level.sha1), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_SHA224:
- GUARD_OSSL(SHA224_Init(&state->digest.low_level.sha224), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_SHA256:
- GUARD_OSSL(SHA256_Init(&state->digest.low_level.sha256), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_SHA384:
- GUARD_OSSL(SHA384_Init(&state->digest.low_level.sha384), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_SHA512:
- GUARD_OSSL(SHA512_Init(&state->digest.low_level.sha512), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_MD5_SHA1:
- GUARD_OSSL(SHA1_Init(&state->digest.low_level.md5_sha1.sha1), S2N_ERR_HASH_INIT_FAILED);;
- GUARD_OSSL(MD5_Init(&state->digest.low_level.md5_sha1.md5), S2N_ERR_HASH_INIT_FAILED);;
- break;
-
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
-
- state->alg = alg;
- state->is_ready_for_input = 1;
- state->currently_in_hash = 0;
-
- return 0;
-}
-
-static int s2n_low_level_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size)
-{
- ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
-
- switch (state->alg) {
- case S2N_HASH_NONE:
- break;
- case S2N_HASH_MD5:
- GUARD_OSSL(MD5_Update(&state->digest.low_level.md5, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- break;
- case S2N_HASH_SHA1:
- GUARD_OSSL(SHA1_Update(&state->digest.low_level.sha1, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- break;
- case S2N_HASH_SHA224:
- GUARD_OSSL(SHA224_Update(&state->digest.low_level.sha224, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- break;
- case S2N_HASH_SHA256:
- GUARD_OSSL(SHA256_Update(&state->digest.low_level.sha256, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- break;
- case S2N_HASH_SHA384:
- GUARD_OSSL(SHA384_Update(&state->digest.low_level.sha384, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- break;
- case S2N_HASH_SHA512:
- GUARD_OSSL(SHA512_Update(&state->digest.low_level.sha512, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- break;
- case S2N_HASH_MD5_SHA1:
- GUARD_OSSL(SHA1_Update(&state->digest.low_level.md5_sha1.sha1, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- GUARD_OSSL(MD5_Update(&state->digest.low_level.md5_sha1.md5, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- break;
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
-
- ENSURE_POSIX(size <= (UINT64_MAX - state->currently_in_hash), S2N_ERR_INTEGER_OVERFLOW);
- state->currently_in_hash += size;
-
- return S2N_SUCCESS;
-}
-
-static int s2n_low_level_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size)
-{
- ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
-
- switch (state->alg) {
- case S2N_HASH_NONE:
- break;
- case S2N_HASH_MD5:
- eq_check(size, MD5_DIGEST_LENGTH);
- GUARD_OSSL(MD5_Final(out, &state->digest.low_level.md5), S2N_ERR_HASH_DIGEST_FAILED);
- break;
- case S2N_HASH_SHA1:
- eq_check(size, SHA_DIGEST_LENGTH);
- GUARD_OSSL(SHA1_Final(out, &state->digest.low_level.sha1), S2N_ERR_HASH_DIGEST_FAILED);
- break;
- case S2N_HASH_SHA224:
- eq_check(size, SHA224_DIGEST_LENGTH);
- GUARD_OSSL(SHA224_Final(out, &state->digest.low_level.sha224), S2N_ERR_HASH_DIGEST_FAILED);
- break;
- case S2N_HASH_SHA256:
- eq_check(size, SHA256_DIGEST_LENGTH);
- GUARD_OSSL(SHA256_Final(out, &state->digest.low_level.sha256), S2N_ERR_HASH_DIGEST_FAILED);
- break;
- case S2N_HASH_SHA384:
- eq_check(size, SHA384_DIGEST_LENGTH);
- GUARD_OSSL(SHA384_Final(out, &state->digest.low_level.sha384), S2N_ERR_HASH_DIGEST_FAILED);
- break;
- case S2N_HASH_SHA512:
- eq_check(size, SHA512_DIGEST_LENGTH);
- GUARD_OSSL(SHA512_Final(out, &state->digest.low_level.sha512), S2N_ERR_HASH_DIGEST_FAILED);
- break;
- case S2N_HASH_MD5_SHA1:
- eq_check(size, MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH);
- GUARD_OSSL(SHA1_Final(((uint8_t *) out) + MD5_DIGEST_LENGTH, &state->digest.low_level.md5_sha1.sha1), S2N_ERR_HASH_DIGEST_FAILED);
- GUARD_OSSL(MD5_Final(out, &state->digest.low_level.md5_sha1.md5), S2N_ERR_HASH_DIGEST_FAILED);
- break;
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
-
- state->currently_in_hash = 0;
- state->is_ready_for_input = 0;
- return 0;
-}
-
-static int s2n_low_level_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from)
-{
- memcpy_check(to, from, sizeof(struct s2n_hash_state));
- return 0;
-}
-
-static int s2n_low_level_hash_reset(struct s2n_hash_state *state)
-{
- /* hash_init resets the ready_for_input and currently_in_hash fields. */
- return s2n_low_level_hash_init(state, state->alg);
-}
-
-static int s2n_low_level_hash_free(struct s2n_hash_state *state)
-{
- /* s2n_hash_free will always call the corresponding implementation of the s2n_hash
- * being used. For the s2n_low_level_hash implementation, free is a no-op.
- */
- state->is_ready_for_input = 0;
- return S2N_SUCCESS;
-}
-
-static int s2n_evp_hash_new(struct s2n_hash_state *state)
-{
- notnull_check(state->digest.high_level.evp.ctx = S2N_EVP_MD_CTX_NEW());
- notnull_check(state->digest.high_level.evp_md5_secondary.ctx = S2N_EVP_MD_CTX_NEW());
- state->is_ready_for_input = 0;
- state->currently_in_hash = 0;
-
- return S2N_SUCCESS;
-}
-
-static int s2n_evp_hash_allow_md5_for_fips(struct s2n_hash_state *state)
-{
- /* This is only to be used for s2n_hash_states that will require MD5 to be used
- * to comply with the TLS 1.0 and 1.1 RFC's for the PRF. MD5 cannot be used
- * outside of the TLS 1.0 and 1.1 PRF when in FIPS mode. When needed, this must
- * be called prior to s2n_hash_init().
- */
- GUARD(s2n_digest_allow_md5_for_fips(&state->digest.high_level.evp_md5_secondary));
- return s2n_digest_allow_md5_for_fips(&state->digest.high_level.evp);
-}
-
-static int s2n_evp_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg)
-{
- notnull_check(state->digest.high_level.evp.ctx);
- notnull_check(state->digest.high_level.evp_md5_secondary.ctx);
- switch (alg) {
- case S2N_HASH_NONE:
- break;
- case S2N_HASH_MD5:
- GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_md5(), NULL), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_SHA1:
- GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha1(), NULL), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_SHA224:
- GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha224(), NULL), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_SHA256:
- GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha256(), NULL), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_SHA384:
- GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha384(), NULL), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_SHA512:
- GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha512(), NULL), S2N_ERR_HASH_INIT_FAILED);
- break;
- case S2N_HASH_MD5_SHA1:
- GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha1(), NULL), S2N_ERR_HASH_INIT_FAILED);
- GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp_md5_secondary.ctx, EVP_md5(), NULL), S2N_ERR_HASH_INIT_FAILED);
- break;
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
-
- state->alg = alg;
- state->is_ready_for_input = 1;
- state->currently_in_hash = 0;
-
- return S2N_SUCCESS;
-}
-
-static int s2n_evp_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size)
-{
- ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
-
- switch (state->alg) {
- case S2N_HASH_NONE:
- break;
- case S2N_HASH_MD5:
- case S2N_HASH_SHA1:
- case S2N_HASH_SHA224:
- case S2N_HASH_SHA256:
- case S2N_HASH_SHA384:
- case S2N_HASH_SHA512:
- notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
- GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- break;
- case S2N_HASH_MD5_SHA1:
- notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
- notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp_md5_secondary.ctx));
- GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp_md5_secondary.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED);
- break;
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
-
- ENSURE_POSIX(size <= (UINT64_MAX - state->currently_in_hash), S2N_ERR_INTEGER_OVERFLOW);
- state->currently_in_hash += size;
-
- return S2N_SUCCESS;
-}
-
-static int s2n_evp_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size)
-{
- ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
-
- unsigned int digest_size = size;
- uint8_t expected_digest_size;
- GUARD(s2n_hash_digest_size(state->alg, &expected_digest_size));
- eq_check(digest_size, expected_digest_size);
-
- /* Used for S2N_HASH_MD5_SHA1 case to specify the exact size of each digest. */
- uint8_t sha1_digest_size;
- unsigned int sha1_primary_digest_size;
- unsigned int md5_secondary_digest_size;
-
- switch (state->alg) {
- case S2N_HASH_NONE:
- break;
- case S2N_HASH_MD5:
- case S2N_HASH_SHA1:
- case S2N_HASH_SHA224:
- case S2N_HASH_SHA256:
- case S2N_HASH_SHA384:
- case S2N_HASH_SHA512:
- notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
- ENSURE_POSIX(EVP_MD_CTX_size(state->digest.high_level.evp.ctx) <= digest_size, S2N_ERR_HASH_DIGEST_FAILED);
- GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp.ctx, out, &digest_size), S2N_ERR_HASH_DIGEST_FAILED);
- break;
- case S2N_HASH_MD5_SHA1:
- notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
- notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp_md5_secondary.ctx));
- GUARD(s2n_hash_digest_size(S2N_HASH_SHA1, &sha1_digest_size));
- sha1_primary_digest_size = sha1_digest_size;
- md5_secondary_digest_size = digest_size - sha1_primary_digest_size;
- ENSURE_POSIX(EVP_MD_CTX_size(state->digest.high_level.evp.ctx) <= sha1_digest_size, S2N_ERR_HASH_DIGEST_FAILED);
- ENSURE_POSIX(EVP_MD_CTX_size(state->digest.high_level.evp_md5_secondary.ctx) <= md5_secondary_digest_size, S2N_ERR_HASH_DIGEST_FAILED);
-
- GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp.ctx, ((uint8_t *) out) + MD5_DIGEST_LENGTH, &sha1_primary_digest_size), S2N_ERR_HASH_DIGEST_FAILED);
- GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp_md5_secondary.ctx, out, &md5_secondary_digest_size), S2N_ERR_HASH_DIGEST_FAILED);
- break;
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
-
- state->currently_in_hash = 0;
- state->is_ready_for_input = 0;
- return S2N_SUCCESS;
-}
-
-static int s2n_evp_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from)
-{
- bool is_md5_allowed_for_fips = false;
- switch (from->alg) {
- case S2N_HASH_NONE:
- break;
- case S2N_HASH_MD5:
- GUARD_AS_POSIX(s2n_digest_is_md5_allowed_for_fips(&from->digest.high_level.evp, &is_md5_allowed_for_fips));
- if (is_md5_allowed_for_fips) {
- GUARD(s2n_hash_allow_md5_for_fips(to));
- }
- FALL_THROUGH;
- case S2N_HASH_SHA1:
- case S2N_HASH_SHA224:
- case S2N_HASH_SHA256:
- case S2N_HASH_SHA384:
- case S2N_HASH_SHA512:
- notnull_check(to->digest.high_level.evp.ctx);
- GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp.ctx, from->digest.high_level.evp.ctx), S2N_ERR_HASH_COPY_FAILED);
- break;
- case S2N_HASH_MD5_SHA1:
- notnull_check(to->digest.high_level.evp.ctx);
- notnull_check(to->digest.high_level.evp_md5_secondary.ctx);
- GUARD_AS_POSIX(s2n_digest_is_md5_allowed_for_fips(&from->digest.high_level.evp, &is_md5_allowed_for_fips));
- if (is_md5_allowed_for_fips) {
- GUARD(s2n_hash_allow_md5_for_fips(to));
- }
- GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp.ctx, from->digest.high_level.evp.ctx), S2N_ERR_HASH_COPY_FAILED);
- GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp_md5_secondary.ctx, from->digest.high_level.evp_md5_secondary.ctx), S2N_ERR_HASH_COPY_FAILED);
- break;
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
-
- to->hash_impl = from->hash_impl;
- to->alg = from->alg;
- to->is_ready_for_input = from->is_ready_for_input;
- to->currently_in_hash = from->currently_in_hash;
-
- return S2N_SUCCESS;
-}
-
-static int s2n_evp_hash_reset(struct s2n_hash_state *state)
-{
- int reset_md5_for_fips = 0;
- bool is_md5_allowed_for_fips = false;
- GUARD_AS_POSIX(s2n_digest_is_md5_allowed_for_fips(&state->digest.high_level.evp, &is_md5_allowed_for_fips));
- if ((state->alg == S2N_HASH_MD5 || state->alg == S2N_HASH_MD5_SHA1) && is_md5_allowed_for_fips) {
- reset_md5_for_fips = 1;
- }
-
- GUARD_OSSL(S2N_EVP_MD_CTX_RESET(state->digest.high_level.evp.ctx), S2N_ERR_HASH_WIPE_FAILED);
-
- if (state->alg == S2N_HASH_MD5_SHA1) {
- GUARD_OSSL(S2N_EVP_MD_CTX_RESET(state->digest.high_level.evp_md5_secondary.ctx), S2N_ERR_HASH_WIPE_FAILED);
- }
-
- if (reset_md5_for_fips) {
- GUARD(s2n_hash_allow_md5_for_fips(state));
- }
-
- /* hash_init resets the ready_for_input and currently_in_hash fields. */
- return s2n_evp_hash_init(state, state->alg);
-}
-
-static int s2n_evp_hash_free(struct s2n_hash_state *state)
-{
- S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp.ctx);
- S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp_md5_secondary.ctx);
- state->digest.high_level.evp.ctx = NULL;
- state->digest.high_level.evp_md5_secondary.ctx = NULL;
- state->is_ready_for_input = 0;
- return S2N_SUCCESS;
-}
-
-static const struct s2n_hash s2n_low_level_hash = {
- .alloc = &s2n_low_level_hash_new,
- .allow_md5_for_fips = NULL,
- .init = &s2n_low_level_hash_init,
- .update = &s2n_low_level_hash_update,
- .digest = &s2n_low_level_hash_digest,
- .copy = &s2n_low_level_hash_copy,
- .reset = &s2n_low_level_hash_reset,
- .free = &s2n_low_level_hash_free,
-};
-
-static const struct s2n_hash s2n_evp_hash = {
- .alloc = &s2n_evp_hash_new,
- .allow_md5_for_fips = &s2n_evp_hash_allow_md5_for_fips,
- .init = &s2n_evp_hash_init,
- .update = &s2n_evp_hash_update,
- .digest = &s2n_evp_hash_digest,
- .copy = &s2n_evp_hash_copy,
- .reset = &s2n_evp_hash_reset,
- .free = &s2n_evp_hash_free,
-};
-
-static int s2n_hash_set_impl(struct s2n_hash_state *state)
-{
- state->hash_impl = s2n_is_in_fips_mode() ? &s2n_evp_hash : &s2n_low_level_hash;
-
- return S2N_SUCCESS;
-}
-
-int s2n_hash_new(struct s2n_hash_state *state)
-{
- notnull_check(state);
- /* Set hash_impl on initial hash creation.
- * When in FIPS mode, the EVP API's must be used for hashes.
- */
- GUARD(s2n_hash_set_impl(state));
-
- notnull_check(state->hash_impl->alloc);
-
- GUARD(state->hash_impl->alloc(state));
- return S2N_SUCCESS;
-}
-
-S2N_RESULT s2n_hash_state_validate(struct s2n_hash_state *state)
-{
- ENSURE_REF(state);
- ENSURE_REF(state->hash_impl);
- return S2N_RESULT_OK;
-}
-
-int s2n_hash_allow_md5_for_fips(struct s2n_hash_state *state)
-{
- notnull_check(state);
- /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
- * When in FIPS mode, the EVP API's must be used for hashes.
- */
- GUARD(s2n_hash_set_impl(state));
-
- notnull_check(state->hash_impl->allow_md5_for_fips);
-
- return state->hash_impl->allow_md5_for_fips(state);
-}
-
-int s2n_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg)
-{
- notnull_check(state);
- /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
- * When in FIPS mode, the EVP API's must be used for hashes.
- */
- GUARD(s2n_hash_set_impl(state));
-
- bool is_md5_allowed_for_fips = false;
- GUARD_AS_POSIX(s2n_digest_is_md5_allowed_for_fips(&state->digest.high_level.evp, &is_md5_allowed_for_fips));
-
- if (s2n_hash_is_available(alg) ||
- ((alg == S2N_HASH_MD5 || alg == S2N_HASH_MD5_SHA1) && is_md5_allowed_for_fips)) {
- /* s2n will continue to initialize an "unavailable" hash when s2n is in FIPS mode and
- * FIPS is forcing the hash to be made available.
- */
- notnull_check(state->hash_impl->init);
-
- return state->hash_impl->init(state, alg);
- } else {
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
-}
-
-int s2n_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size)
-{
- PRECONDITION_POSIX(s2n_hash_state_validate(state));
- ENSURE_POSIX(S2N_MEM_IS_READABLE(data, size), S2N_ERR_PRECONDITION_VIOLATION);
- notnull_check(state->hash_impl->update);
-
- return state->hash_impl->update(state, data, size);
-}
-
-int s2n_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size)
-{
- PRECONDITION_POSIX(s2n_hash_state_validate(state));
- ENSURE_POSIX(S2N_MEM_IS_READABLE(out, size), S2N_ERR_PRECONDITION_VIOLATION);
- notnull_check(state->hash_impl->digest);
-
- return state->hash_impl->digest(state, out, size);
-}
-
-int s2n_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from)
-{
- PRECONDITION_POSIX(s2n_hash_state_validate(to));
- PRECONDITION_POSIX(s2n_hash_state_validate(from));
- notnull_check(from->hash_impl->copy);
-
- return from->hash_impl->copy(to, from);
-}
-
-int s2n_hash_reset(struct s2n_hash_state *state)
-{
- notnull_check(state);
- /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
- * When in FIPS mode, the EVP API's must be used for hashes.
- */
- GUARD(s2n_hash_set_impl(state));
-
- notnull_check(state->hash_impl->reset);
-
- return state->hash_impl->reset(state);
-}
-
-int s2n_hash_free(struct s2n_hash_state *state)
-{
- if (state == NULL)
- {
- return S2N_SUCCESS;
- }
- /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
- * When in FIPS mode, the EVP API's must be used for hashes.
- */
- GUARD(s2n_hash_set_impl(state));
-
- notnull_check(state->hash_impl->free);
-
- return state->hash_impl->free(state);
-}
-
-int s2n_hash_get_currently_in_hash_total(struct s2n_hash_state *state, uint64_t *out)
-{
- PRECONDITION_POSIX(s2n_hash_state_validate(state));
- ENSURE_POSIX(S2N_MEM_IS_READABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
- ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
-
- *out = state->currently_in_hash;
- return S2N_SUCCESS;
-}
-
-
-/* Calculate, in constant time, the number of bytes currently in the hash_block */
-int s2n_hash_const_time_get_currently_in_hash_block(struct s2n_hash_state *state, uint64_t *out)
-{
- PRECONDITION_POSIX(s2n_hash_state_validate(state));
- ENSURE_POSIX(S2N_MEM_IS_READABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
- ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
- uint64_t hash_block_size;
- GUARD(s2n_hash_block_size(state->alg, &hash_block_size));
-
- /* Requires that hash_block_size is a power of 2. This is true for all hashes we currently support
- * If this ever becomes untrue, this would require fixing this*/
- *out = state->currently_in_hash & (hash_block_size - 1);
- return S2N_SUCCESS;
-}
+/*
+ * 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 "error/s2n_errno.h"
+
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_hmac.h"
+#include "crypto/s2n_openssl.h"
+#include "crypto/s2n_fips.h"
+
+#include "utils/s2n_safety.h"
+
+int s2n_hash_hmac_alg(s2n_hash_algorithm hash_alg, s2n_hmac_algorithm *out)
+{
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
+ switch(hash_alg) {
+ case S2N_HASH_NONE: *out = S2N_HMAC_NONE; break;
+ case S2N_HASH_MD5: *out = S2N_HMAC_MD5; break;
+ case S2N_HASH_SHA1: *out = S2N_HMAC_SHA1; break;
+ case S2N_HASH_SHA224: *out = S2N_HMAC_SHA224; break;
+ case S2N_HASH_SHA256: *out = S2N_HMAC_SHA256; break;
+ case S2N_HASH_SHA384: *out = S2N_HMAC_SHA384; break;
+ case S2N_HASH_SHA512: *out = S2N_HMAC_SHA512; break;
+ case S2N_HASH_MD5_SHA1: /* Fall through ... */
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+ return S2N_SUCCESS;
+}
+
+int s2n_hash_digest_size(s2n_hash_algorithm alg, uint8_t *out)
+{
+ notnull_check(out);
+ switch (alg) {
+ case S2N_HASH_NONE: *out = 0; break;
+ case S2N_HASH_MD5: *out = MD5_DIGEST_LENGTH; break;
+ case S2N_HASH_SHA1: *out = SHA_DIGEST_LENGTH; break;
+ case S2N_HASH_SHA224: *out = SHA224_DIGEST_LENGTH; break;
+ case S2N_HASH_SHA256: *out = SHA256_DIGEST_LENGTH; break;
+ case S2N_HASH_SHA384: *out = SHA384_DIGEST_LENGTH; break;
+ case S2N_HASH_SHA512: *out = SHA512_DIGEST_LENGTH; break;
+ case S2N_HASH_MD5_SHA1: *out = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; break;
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+ return S2N_SUCCESS;
+}
+
+/* NOTE: s2n_hash_const_time_get_currently_in_hash_block takes advantage of the fact that
+ * hash_block_size is a power of 2. This is true for all hashes we currently support
+ * If this ever becomes untrue, this would require fixing*/
+int s2n_hash_block_size(s2n_hash_algorithm alg, uint64_t *block_size)
+{
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(block_size, sizeof(*block_size)), S2N_ERR_PRECONDITION_VIOLATION);
+ switch(alg) {
+ case S2N_HASH_NONE: *block_size = 64; break;
+ case S2N_HASH_MD5: *block_size = 64; break;
+ case S2N_HASH_SHA1: *block_size = 64; break;
+ case S2N_HASH_SHA224: *block_size = 64; break;
+ case S2N_HASH_SHA256: *block_size = 64; break;
+ case S2N_HASH_SHA384: *block_size = 128; break;
+ case S2N_HASH_SHA512: *block_size = 128; break;
+ case S2N_HASH_MD5_SHA1: *block_size = 64; break;
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+ return S2N_SUCCESS;
+}
+
+/* Return true if hash algorithm is available, false otherwise. */
+bool s2n_hash_is_available(s2n_hash_algorithm alg)
+{
+ switch (alg) {
+ case S2N_HASH_MD5:
+ case S2N_HASH_MD5_SHA1:
+ /* return false if in FIPS mode, as MD5 algs are not available in FIPS mode. */
+ return !s2n_is_in_fips_mode();
+ case S2N_HASH_NONE:
+ case S2N_HASH_SHA1:
+ case S2N_HASH_SHA224:
+ case S2N_HASH_SHA256:
+ case S2N_HASH_SHA384:
+ case S2N_HASH_SHA512:
+ return true;
+ case S2N_HASH_SENTINEL:
+ return false;
+ }
+ return false;
+}
+
+int s2n_hash_is_ready_for_input(struct s2n_hash_state *state)
+{
+ PRECONDITION_POSIX(s2n_hash_state_validate(state));
+ return state->is_ready_for_input;
+}
+
+static int s2n_low_level_hash_new(struct s2n_hash_state *state)
+{
+ /* s2n_hash_new will always call the corresponding implementation of the s2n_hash
+ * being used. For the s2n_low_level_hash implementation, new is a no-op.
+ */
+
+ state->is_ready_for_input = 0;
+ state->currently_in_hash = 0;
+ return S2N_SUCCESS;
+}
+
+static int s2n_low_level_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg)
+{
+ switch (alg) {
+ case S2N_HASH_NONE:
+ break;
+ case S2N_HASH_MD5:
+ GUARD_OSSL(MD5_Init(&state->digest.low_level.md5), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_SHA1:
+ GUARD_OSSL(SHA1_Init(&state->digest.low_level.sha1), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_SHA224:
+ GUARD_OSSL(SHA224_Init(&state->digest.low_level.sha224), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_SHA256:
+ GUARD_OSSL(SHA256_Init(&state->digest.low_level.sha256), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_SHA384:
+ GUARD_OSSL(SHA384_Init(&state->digest.low_level.sha384), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_SHA512:
+ GUARD_OSSL(SHA512_Init(&state->digest.low_level.sha512), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_MD5_SHA1:
+ GUARD_OSSL(SHA1_Init(&state->digest.low_level.md5_sha1.sha1), S2N_ERR_HASH_INIT_FAILED);;
+ GUARD_OSSL(MD5_Init(&state->digest.low_level.md5_sha1.md5), S2N_ERR_HASH_INIT_FAILED);;
+ break;
+
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+
+ state->alg = alg;
+ state->is_ready_for_input = 1;
+ state->currently_in_hash = 0;
+
+ return 0;
+}
+
+static int s2n_low_level_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size)
+{
+ ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
+
+ switch (state->alg) {
+ case S2N_HASH_NONE:
+ break;
+ case S2N_HASH_MD5:
+ GUARD_OSSL(MD5_Update(&state->digest.low_level.md5, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ break;
+ case S2N_HASH_SHA1:
+ GUARD_OSSL(SHA1_Update(&state->digest.low_level.sha1, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ break;
+ case S2N_HASH_SHA224:
+ GUARD_OSSL(SHA224_Update(&state->digest.low_level.sha224, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ break;
+ case S2N_HASH_SHA256:
+ GUARD_OSSL(SHA256_Update(&state->digest.low_level.sha256, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ break;
+ case S2N_HASH_SHA384:
+ GUARD_OSSL(SHA384_Update(&state->digest.low_level.sha384, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ break;
+ case S2N_HASH_SHA512:
+ GUARD_OSSL(SHA512_Update(&state->digest.low_level.sha512, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ break;
+ case S2N_HASH_MD5_SHA1:
+ GUARD_OSSL(SHA1_Update(&state->digest.low_level.md5_sha1.sha1, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ GUARD_OSSL(MD5_Update(&state->digest.low_level.md5_sha1.md5, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+
+ ENSURE_POSIX(size <= (UINT64_MAX - state->currently_in_hash), S2N_ERR_INTEGER_OVERFLOW);
+ state->currently_in_hash += size;
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_low_level_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size)
+{
+ ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
+
+ switch (state->alg) {
+ case S2N_HASH_NONE:
+ break;
+ case S2N_HASH_MD5:
+ eq_check(size, MD5_DIGEST_LENGTH);
+ GUARD_OSSL(MD5_Final(out, &state->digest.low_level.md5), S2N_ERR_HASH_DIGEST_FAILED);
+ break;
+ case S2N_HASH_SHA1:
+ eq_check(size, SHA_DIGEST_LENGTH);
+ GUARD_OSSL(SHA1_Final(out, &state->digest.low_level.sha1), S2N_ERR_HASH_DIGEST_FAILED);
+ break;
+ case S2N_HASH_SHA224:
+ eq_check(size, SHA224_DIGEST_LENGTH);
+ GUARD_OSSL(SHA224_Final(out, &state->digest.low_level.sha224), S2N_ERR_HASH_DIGEST_FAILED);
+ break;
+ case S2N_HASH_SHA256:
+ eq_check(size, SHA256_DIGEST_LENGTH);
+ GUARD_OSSL(SHA256_Final(out, &state->digest.low_level.sha256), S2N_ERR_HASH_DIGEST_FAILED);
+ break;
+ case S2N_HASH_SHA384:
+ eq_check(size, SHA384_DIGEST_LENGTH);
+ GUARD_OSSL(SHA384_Final(out, &state->digest.low_level.sha384), S2N_ERR_HASH_DIGEST_FAILED);
+ break;
+ case S2N_HASH_SHA512:
+ eq_check(size, SHA512_DIGEST_LENGTH);
+ GUARD_OSSL(SHA512_Final(out, &state->digest.low_level.sha512), S2N_ERR_HASH_DIGEST_FAILED);
+ break;
+ case S2N_HASH_MD5_SHA1:
+ eq_check(size, MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH);
+ GUARD_OSSL(SHA1_Final(((uint8_t *) out) + MD5_DIGEST_LENGTH, &state->digest.low_level.md5_sha1.sha1), S2N_ERR_HASH_DIGEST_FAILED);
+ GUARD_OSSL(MD5_Final(out, &state->digest.low_level.md5_sha1.md5), S2N_ERR_HASH_DIGEST_FAILED);
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+
+ state->currently_in_hash = 0;
+ state->is_ready_for_input = 0;
+ return 0;
+}
+
+static int s2n_low_level_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from)
+{
+ memcpy_check(to, from, sizeof(struct s2n_hash_state));
+ return 0;
+}
+
+static int s2n_low_level_hash_reset(struct s2n_hash_state *state)
+{
+ /* hash_init resets the ready_for_input and currently_in_hash fields. */
+ return s2n_low_level_hash_init(state, state->alg);
+}
+
+static int s2n_low_level_hash_free(struct s2n_hash_state *state)
+{
+ /* s2n_hash_free will always call the corresponding implementation of the s2n_hash
+ * being used. For the s2n_low_level_hash implementation, free is a no-op.
+ */
+ state->is_ready_for_input = 0;
+ return S2N_SUCCESS;
+}
+
+static int s2n_evp_hash_new(struct s2n_hash_state *state)
+{
+ notnull_check(state->digest.high_level.evp.ctx = S2N_EVP_MD_CTX_NEW());
+ notnull_check(state->digest.high_level.evp_md5_secondary.ctx = S2N_EVP_MD_CTX_NEW());
+ state->is_ready_for_input = 0;
+ state->currently_in_hash = 0;
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_evp_hash_allow_md5_for_fips(struct s2n_hash_state *state)
+{
+ /* This is only to be used for s2n_hash_states that will require MD5 to be used
+ * to comply with the TLS 1.0 and 1.1 RFC's for the PRF. MD5 cannot be used
+ * outside of the TLS 1.0 and 1.1 PRF when in FIPS mode. When needed, this must
+ * be called prior to s2n_hash_init().
+ */
+ GUARD(s2n_digest_allow_md5_for_fips(&state->digest.high_level.evp_md5_secondary));
+ return s2n_digest_allow_md5_for_fips(&state->digest.high_level.evp);
+}
+
+static int s2n_evp_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg)
+{
+ notnull_check(state->digest.high_level.evp.ctx);
+ notnull_check(state->digest.high_level.evp_md5_secondary.ctx);
+ switch (alg) {
+ case S2N_HASH_NONE:
+ break;
+ case S2N_HASH_MD5:
+ GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_md5(), NULL), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_SHA1:
+ GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha1(), NULL), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_SHA224:
+ GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha224(), NULL), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_SHA256:
+ GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha256(), NULL), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_SHA384:
+ GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha384(), NULL), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_SHA512:
+ GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha512(), NULL), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ case S2N_HASH_MD5_SHA1:
+ GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha1(), NULL), S2N_ERR_HASH_INIT_FAILED);
+ GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp_md5_secondary.ctx, EVP_md5(), NULL), S2N_ERR_HASH_INIT_FAILED);
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+
+ state->alg = alg;
+ state->is_ready_for_input = 1;
+ state->currently_in_hash = 0;
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_evp_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size)
+{
+ ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
+
+ switch (state->alg) {
+ case S2N_HASH_NONE:
+ break;
+ case S2N_HASH_MD5:
+ case S2N_HASH_SHA1:
+ case S2N_HASH_SHA224:
+ case S2N_HASH_SHA256:
+ case S2N_HASH_SHA384:
+ case S2N_HASH_SHA512:
+ notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
+ GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ break;
+ case S2N_HASH_MD5_SHA1:
+ notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
+ notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp_md5_secondary.ctx));
+ GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp_md5_secondary.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED);
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+
+ ENSURE_POSIX(size <= (UINT64_MAX - state->currently_in_hash), S2N_ERR_INTEGER_OVERFLOW);
+ state->currently_in_hash += size;
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_evp_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size)
+{
+ ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
+
+ unsigned int digest_size = size;
+ uint8_t expected_digest_size;
+ GUARD(s2n_hash_digest_size(state->alg, &expected_digest_size));
+ eq_check(digest_size, expected_digest_size);
+
+ /* Used for S2N_HASH_MD5_SHA1 case to specify the exact size of each digest. */
+ uint8_t sha1_digest_size;
+ unsigned int sha1_primary_digest_size;
+ unsigned int md5_secondary_digest_size;
+
+ switch (state->alg) {
+ case S2N_HASH_NONE:
+ break;
+ case S2N_HASH_MD5:
+ case S2N_HASH_SHA1:
+ case S2N_HASH_SHA224:
+ case S2N_HASH_SHA256:
+ case S2N_HASH_SHA384:
+ case S2N_HASH_SHA512:
+ notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
+ ENSURE_POSIX(EVP_MD_CTX_size(state->digest.high_level.evp.ctx) <= digest_size, S2N_ERR_HASH_DIGEST_FAILED);
+ GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp.ctx, out, &digest_size), S2N_ERR_HASH_DIGEST_FAILED);
+ break;
+ case S2N_HASH_MD5_SHA1:
+ notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp.ctx));
+ notnull_check(EVP_MD_CTX_md(state->digest.high_level.evp_md5_secondary.ctx));
+ GUARD(s2n_hash_digest_size(S2N_HASH_SHA1, &sha1_digest_size));
+ sha1_primary_digest_size = sha1_digest_size;
+ md5_secondary_digest_size = digest_size - sha1_primary_digest_size;
+ ENSURE_POSIX(EVP_MD_CTX_size(state->digest.high_level.evp.ctx) <= sha1_digest_size, S2N_ERR_HASH_DIGEST_FAILED);
+ ENSURE_POSIX(EVP_MD_CTX_size(state->digest.high_level.evp_md5_secondary.ctx) <= md5_secondary_digest_size, S2N_ERR_HASH_DIGEST_FAILED);
+
+ GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp.ctx, ((uint8_t *) out) + MD5_DIGEST_LENGTH, &sha1_primary_digest_size), S2N_ERR_HASH_DIGEST_FAILED);
+ GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp_md5_secondary.ctx, out, &md5_secondary_digest_size), S2N_ERR_HASH_DIGEST_FAILED);
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+
+ state->currently_in_hash = 0;
+ state->is_ready_for_input = 0;
+ return S2N_SUCCESS;
+}
+
+static int s2n_evp_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from)
+{
+ bool is_md5_allowed_for_fips = false;
+ switch (from->alg) {
+ case S2N_HASH_NONE:
+ break;
+ case S2N_HASH_MD5:
+ GUARD_AS_POSIX(s2n_digest_is_md5_allowed_for_fips(&from->digest.high_level.evp, &is_md5_allowed_for_fips));
+ if (is_md5_allowed_for_fips) {
+ GUARD(s2n_hash_allow_md5_for_fips(to));
+ }
+ FALL_THROUGH;
+ case S2N_HASH_SHA1:
+ case S2N_HASH_SHA224:
+ case S2N_HASH_SHA256:
+ case S2N_HASH_SHA384:
+ case S2N_HASH_SHA512:
+ notnull_check(to->digest.high_level.evp.ctx);
+ GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp.ctx, from->digest.high_level.evp.ctx), S2N_ERR_HASH_COPY_FAILED);
+ break;
+ case S2N_HASH_MD5_SHA1:
+ notnull_check(to->digest.high_level.evp.ctx);
+ notnull_check(to->digest.high_level.evp_md5_secondary.ctx);
+ GUARD_AS_POSIX(s2n_digest_is_md5_allowed_for_fips(&from->digest.high_level.evp, &is_md5_allowed_for_fips));
+ if (is_md5_allowed_for_fips) {
+ GUARD(s2n_hash_allow_md5_for_fips(to));
+ }
+ GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp.ctx, from->digest.high_level.evp.ctx), S2N_ERR_HASH_COPY_FAILED);
+ GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp_md5_secondary.ctx, from->digest.high_level.evp_md5_secondary.ctx), S2N_ERR_HASH_COPY_FAILED);
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+
+ to->hash_impl = from->hash_impl;
+ to->alg = from->alg;
+ to->is_ready_for_input = from->is_ready_for_input;
+ to->currently_in_hash = from->currently_in_hash;
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_evp_hash_reset(struct s2n_hash_state *state)
+{
+ int reset_md5_for_fips = 0;
+ bool is_md5_allowed_for_fips = false;
+ GUARD_AS_POSIX(s2n_digest_is_md5_allowed_for_fips(&state->digest.high_level.evp, &is_md5_allowed_for_fips));
+ if ((state->alg == S2N_HASH_MD5 || state->alg == S2N_HASH_MD5_SHA1) && is_md5_allowed_for_fips) {
+ reset_md5_for_fips = 1;
+ }
+
+ GUARD_OSSL(S2N_EVP_MD_CTX_RESET(state->digest.high_level.evp.ctx), S2N_ERR_HASH_WIPE_FAILED);
+
+ if (state->alg == S2N_HASH_MD5_SHA1) {
+ GUARD_OSSL(S2N_EVP_MD_CTX_RESET(state->digest.high_level.evp_md5_secondary.ctx), S2N_ERR_HASH_WIPE_FAILED);
+ }
+
+ if (reset_md5_for_fips) {
+ GUARD(s2n_hash_allow_md5_for_fips(state));
+ }
+
+ /* hash_init resets the ready_for_input and currently_in_hash fields. */
+ return s2n_evp_hash_init(state, state->alg);
+}
+
+static int s2n_evp_hash_free(struct s2n_hash_state *state)
+{
+ S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp.ctx);
+ S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp_md5_secondary.ctx);
+ state->digest.high_level.evp.ctx = NULL;
+ state->digest.high_level.evp_md5_secondary.ctx = NULL;
+ state->is_ready_for_input = 0;
+ return S2N_SUCCESS;
+}
+
+static const struct s2n_hash s2n_low_level_hash = {
+ .alloc = &s2n_low_level_hash_new,
+ .allow_md5_for_fips = NULL,
+ .init = &s2n_low_level_hash_init,
+ .update = &s2n_low_level_hash_update,
+ .digest = &s2n_low_level_hash_digest,
+ .copy = &s2n_low_level_hash_copy,
+ .reset = &s2n_low_level_hash_reset,
+ .free = &s2n_low_level_hash_free,
+};
+
+static const struct s2n_hash s2n_evp_hash = {
+ .alloc = &s2n_evp_hash_new,
+ .allow_md5_for_fips = &s2n_evp_hash_allow_md5_for_fips,
+ .init = &s2n_evp_hash_init,
+ .update = &s2n_evp_hash_update,
+ .digest = &s2n_evp_hash_digest,
+ .copy = &s2n_evp_hash_copy,
+ .reset = &s2n_evp_hash_reset,
+ .free = &s2n_evp_hash_free,
+};
+
+static int s2n_hash_set_impl(struct s2n_hash_state *state)
+{
+ state->hash_impl = s2n_is_in_fips_mode() ? &s2n_evp_hash : &s2n_low_level_hash;
+
+ return S2N_SUCCESS;
+}
+
+int s2n_hash_new(struct s2n_hash_state *state)
+{
+ notnull_check(state);
+ /* Set hash_impl on initial hash creation.
+ * When in FIPS mode, the EVP API's must be used for hashes.
+ */
+ GUARD(s2n_hash_set_impl(state));
+
+ notnull_check(state->hash_impl->alloc);
+
+ GUARD(state->hash_impl->alloc(state));
+ return S2N_SUCCESS;
+}
+
+S2N_RESULT s2n_hash_state_validate(struct s2n_hash_state *state)
+{
+ ENSURE_REF(state);
+ ENSURE_REF(state->hash_impl);
+ return S2N_RESULT_OK;
+}
+
+int s2n_hash_allow_md5_for_fips(struct s2n_hash_state *state)
+{
+ notnull_check(state);
+ /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
+ * When in FIPS mode, the EVP API's must be used for hashes.
+ */
+ GUARD(s2n_hash_set_impl(state));
+
+ notnull_check(state->hash_impl->allow_md5_for_fips);
+
+ return state->hash_impl->allow_md5_for_fips(state);
+}
+
+int s2n_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg)
+{
+ notnull_check(state);
+ /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
+ * When in FIPS mode, the EVP API's must be used for hashes.
+ */
+ GUARD(s2n_hash_set_impl(state));
+
+ bool is_md5_allowed_for_fips = false;
+ GUARD_AS_POSIX(s2n_digest_is_md5_allowed_for_fips(&state->digest.high_level.evp, &is_md5_allowed_for_fips));
+
+ if (s2n_hash_is_available(alg) ||
+ ((alg == S2N_HASH_MD5 || alg == S2N_HASH_MD5_SHA1) && is_md5_allowed_for_fips)) {
+ /* s2n will continue to initialize an "unavailable" hash when s2n is in FIPS mode and
+ * FIPS is forcing the hash to be made available.
+ */
+ notnull_check(state->hash_impl->init);
+
+ return state->hash_impl->init(state, alg);
+ } else {
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+}
+
+int s2n_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size)
+{
+ PRECONDITION_POSIX(s2n_hash_state_validate(state));
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(data, size), S2N_ERR_PRECONDITION_VIOLATION);
+ notnull_check(state->hash_impl->update);
+
+ return state->hash_impl->update(state, data, size);
+}
+
+int s2n_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size)
+{
+ PRECONDITION_POSIX(s2n_hash_state_validate(state));
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(out, size), S2N_ERR_PRECONDITION_VIOLATION);
+ notnull_check(state->hash_impl->digest);
+
+ return state->hash_impl->digest(state, out, size);
+}
+
+int s2n_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from)
+{
+ PRECONDITION_POSIX(s2n_hash_state_validate(to));
+ PRECONDITION_POSIX(s2n_hash_state_validate(from));
+ notnull_check(from->hash_impl->copy);
+
+ return from->hash_impl->copy(to, from);
+}
+
+int s2n_hash_reset(struct s2n_hash_state *state)
+{
+ notnull_check(state);
+ /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
+ * When in FIPS mode, the EVP API's must be used for hashes.
+ */
+ GUARD(s2n_hash_set_impl(state));
+
+ notnull_check(state->hash_impl->reset);
+
+ return state->hash_impl->reset(state);
+}
+
+int s2n_hash_free(struct s2n_hash_state *state)
+{
+ if (state == NULL)
+ {
+ return S2N_SUCCESS;
+ }
+ /* Ensure that hash_impl is set, as it may have been reset for s2n_hash_state on s2n_connection_wipe.
+ * When in FIPS mode, the EVP API's must be used for hashes.
+ */
+ GUARD(s2n_hash_set_impl(state));
+
+ notnull_check(state->hash_impl->free);
+
+ return state->hash_impl->free(state);
+}
+
+int s2n_hash_get_currently_in_hash_total(struct s2n_hash_state *state, uint64_t *out)
+{
+ PRECONDITION_POSIX(s2n_hash_state_validate(state));
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
+ ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
+
+ *out = state->currently_in_hash;
+ return S2N_SUCCESS;
+}
+
+
+/* Calculate, in constant time, the number of bytes currently in the hash_block */
+int s2n_hash_const_time_get_currently_in_hash_block(struct s2n_hash_state *state, uint64_t *out)
+{
+ PRECONDITION_POSIX(s2n_hash_state_validate(state));
+ ENSURE_POSIX(S2N_MEM_IS_READABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION);
+ ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY);
+ uint64_t hash_block_size;
+ GUARD(s2n_hash_block_size(state->alg, &hash_block_size));
+
+ /* Requires that hash_block_size is a power of 2. This is true for all hashes we currently support
+ * If this ever becomes untrue, this would require fixing this*/
+ *out = state->currently_in_hash & (hash_block_size - 1);
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hash.h b/contrib/restricted/aws/s2n/crypto/s2n_hash.h
index 2ca40e77ca..ad5ac74830 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_hash.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_hash.h
@@ -1,104 +1,104 @@
-/*
- * 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 <stdint.h>
-#include <stdbool.h>
-
-#include <openssl/md5.h>
-#include <openssl/sha.h>
-
-#include "crypto/s2n_evp.h"
-
-#define S2N_MAX_DIGEST_LEN SHA512_DIGEST_LENGTH
-
-typedef enum {
- S2N_HASH_NONE=0,
- S2N_HASH_MD5,
- S2N_HASH_SHA1,
- S2N_HASH_SHA224,
- S2N_HASH_SHA256,
- S2N_HASH_SHA384,
- S2N_HASH_SHA512,
- S2N_HASH_MD5_SHA1,
- /* Don't add any hash algorithms below S2N_HASH_SENTINEL */
- S2N_HASH_SENTINEL
-} s2n_hash_algorithm;
-
-/* The low_level_digest stores all OpenSSL structs that are alg-specific to be used with OpenSSL's low-level hash API's. */
-union s2n_hash_low_level_digest {
- MD5_CTX md5;
- SHA_CTX sha1;
- SHA256_CTX sha224;
- SHA256_CTX sha256;
- SHA512_CTX sha384;
- SHA512_CTX sha512;
- struct {
- MD5_CTX md5;
- SHA_CTX sha1;
- } md5_sha1;
-};
-
-/* The evp_digest stores all OpenSSL structs to be used with OpenSSL's EVP hash API's. */
-struct s2n_hash_evp_digest {
- struct s2n_evp_digest evp;
- /* Always store a secondary evp_digest to allow resetting a hash_state to MD5_SHA1 from another alg. */
- struct s2n_evp_digest evp_md5_secondary;
-};
-
-/* s2n_hash_state stores the s2n_hash implementation being used (low-level or EVP),
- * the hash algorithm being used at the time, and either low_level or high_level (EVP) OpenSSL digest structs.
- */
-struct s2n_hash_state {
- const struct s2n_hash *hash_impl;
- s2n_hash_algorithm alg;
- uint8_t is_ready_for_input;
- uint64_t currently_in_hash;
- union {
- union s2n_hash_low_level_digest low_level;
- struct s2n_hash_evp_digest high_level;
- } digest;
-};
-
-/* The s2n hash implementation is abstracted to allow for separate implementations, using
- * either OpenSSL's low-level algorithm-specific API's or OpenSSL's EVP API's.
- */
-struct s2n_hash {
- int (*alloc) (struct s2n_hash_state *state);
- int (*allow_md5_for_fips) (struct s2n_hash_state *state);
- int (*init) (struct s2n_hash_state *state, s2n_hash_algorithm alg);
- int (*update) (struct s2n_hash_state *state, const void *data, uint32_t size);
- int (*digest) (struct s2n_hash_state *state, void *out, uint32_t size);
- int (*copy) (struct s2n_hash_state *to, struct s2n_hash_state *from);
- int (*reset) (struct s2n_hash_state *state);
- int (*free) (struct s2n_hash_state *state);
-};
-
-extern int s2n_hash_digest_size(s2n_hash_algorithm alg, uint8_t *out);
-extern int s2n_hash_block_size(s2n_hash_algorithm alg, uint64_t *block_size);
-extern bool s2n_hash_is_available(s2n_hash_algorithm alg);
-extern int s2n_hash_is_ready_for_input(struct s2n_hash_state *state);
-extern int s2n_hash_new(struct s2n_hash_state *state);
-S2N_RESULT s2n_hash_state_validate(struct s2n_hash_state *state);
-extern int s2n_hash_allow_md5_for_fips(struct s2n_hash_state *state);
-extern int s2n_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg);
-extern int s2n_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size);
-extern int s2n_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size);
-extern int s2n_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from);
-extern int s2n_hash_reset(struct s2n_hash_state *state);
-extern int s2n_hash_free(struct s2n_hash_state *state);
-extern int s2n_hash_get_currently_in_hash_total(struct s2n_hash_state *state, uint64_t *out);
-extern int s2n_hash_const_time_get_currently_in_hash_block(struct s2n_hash_state *state, uint64_t *out);
+/*
+ * 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 <stdint.h>
+#include <stdbool.h>
+
+#include <openssl/md5.h>
+#include <openssl/sha.h>
+
+#include "crypto/s2n_evp.h"
+
+#define S2N_MAX_DIGEST_LEN SHA512_DIGEST_LENGTH
+
+typedef enum {
+ S2N_HASH_NONE=0,
+ S2N_HASH_MD5,
+ S2N_HASH_SHA1,
+ S2N_HASH_SHA224,
+ S2N_HASH_SHA256,
+ S2N_HASH_SHA384,
+ S2N_HASH_SHA512,
+ S2N_HASH_MD5_SHA1,
+ /* Don't add any hash algorithms below S2N_HASH_SENTINEL */
+ S2N_HASH_SENTINEL
+} s2n_hash_algorithm;
+
+/* The low_level_digest stores all OpenSSL structs that are alg-specific to be used with OpenSSL's low-level hash API's. */
+union s2n_hash_low_level_digest {
+ MD5_CTX md5;
+ SHA_CTX sha1;
+ SHA256_CTX sha224;
+ SHA256_CTX sha256;
+ SHA512_CTX sha384;
+ SHA512_CTX sha512;
+ struct {
+ MD5_CTX md5;
+ SHA_CTX sha1;
+ } md5_sha1;
+};
+
+/* The evp_digest stores all OpenSSL structs to be used with OpenSSL's EVP hash API's. */
+struct s2n_hash_evp_digest {
+ struct s2n_evp_digest evp;
+ /* Always store a secondary evp_digest to allow resetting a hash_state to MD5_SHA1 from another alg. */
+ struct s2n_evp_digest evp_md5_secondary;
+};
+
+/* s2n_hash_state stores the s2n_hash implementation being used (low-level or EVP),
+ * the hash algorithm being used at the time, and either low_level or high_level (EVP) OpenSSL digest structs.
+ */
+struct s2n_hash_state {
+ const struct s2n_hash *hash_impl;
+ s2n_hash_algorithm alg;
+ uint8_t is_ready_for_input;
+ uint64_t currently_in_hash;
+ union {
+ union s2n_hash_low_level_digest low_level;
+ struct s2n_hash_evp_digest high_level;
+ } digest;
+};
+
+/* The s2n hash implementation is abstracted to allow for separate implementations, using
+ * either OpenSSL's low-level algorithm-specific API's or OpenSSL's EVP API's.
+ */
+struct s2n_hash {
+ int (*alloc) (struct s2n_hash_state *state);
+ int (*allow_md5_for_fips) (struct s2n_hash_state *state);
+ int (*init) (struct s2n_hash_state *state, s2n_hash_algorithm alg);
+ int (*update) (struct s2n_hash_state *state, const void *data, uint32_t size);
+ int (*digest) (struct s2n_hash_state *state, void *out, uint32_t size);
+ int (*copy) (struct s2n_hash_state *to, struct s2n_hash_state *from);
+ int (*reset) (struct s2n_hash_state *state);
+ int (*free) (struct s2n_hash_state *state);
+};
+
+extern int s2n_hash_digest_size(s2n_hash_algorithm alg, uint8_t *out);
+extern int s2n_hash_block_size(s2n_hash_algorithm alg, uint64_t *block_size);
+extern bool s2n_hash_is_available(s2n_hash_algorithm alg);
+extern int s2n_hash_is_ready_for_input(struct s2n_hash_state *state);
+extern int s2n_hash_new(struct s2n_hash_state *state);
+S2N_RESULT s2n_hash_state_validate(struct s2n_hash_state *state);
+extern int s2n_hash_allow_md5_for_fips(struct s2n_hash_state *state);
+extern int s2n_hash_init(struct s2n_hash_state *state, s2n_hash_algorithm alg);
+extern int s2n_hash_update(struct s2n_hash_state *state, const void *data, uint32_t size);
+extern int s2n_hash_digest(struct s2n_hash_state *state, void *out, uint32_t size);
+extern int s2n_hash_copy(struct s2n_hash_state *to, struct s2n_hash_state *from);
+extern int s2n_hash_reset(struct s2n_hash_state *state);
+extern int s2n_hash_free(struct s2n_hash_state *state);
+extern int s2n_hash_get_currently_in_hash_total(struct s2n_hash_state *state, uint64_t *out);
+extern int s2n_hash_const_time_get_currently_in_hash_block(struct s2n_hash_state *state, uint64_t *out);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c b/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c
index cefd528fdf..9282bbdfb4 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c
@@ -1,126 +1,126 @@
-/*
- * 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 <stdio.h>
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_hmac.h"
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_mem.h"
-
-#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,
- const struct s2n_blob *key, struct s2n_blob *pseudo_rand_key)
-{
- uint8_t hmac_size;
- GUARD(s2n_hmac_digest_size(alg, &hmac_size));
- pseudo_rand_key->size = hmac_size;
- GUARD(s2n_hmac_init(hmac, alg, salt->data, salt->size));
- GUARD(s2n_hmac_update(hmac, key->data, key->size));
- GUARD(s2n_hmac_digest(hmac, pseudo_rand_key->data, pseudo_rand_key->size));
-
- GUARD(s2n_hmac_reset(hmac));
-
- return 0;
-}
-
-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)
-{
- uint8_t prev[MAX_DIGEST_SIZE] = { 0 };
-
- uint32_t done_len = 0;
- uint8_t hash_len;
- GUARD(s2n_hmac_digest_size(alg, &hash_len));
- uint32_t total_rounds = output->size / hash_len;
- if (output->size % hash_len) {
- total_rounds++;
- }
-
- S2N_ERROR_IF(total_rounds > MAX_HKDF_ROUNDS || total_rounds == 0, S2N_ERR_HKDF_OUTPUT_SIZE);
-
- for (uint32_t curr_round = 1; curr_round <= total_rounds; curr_round++) {
- uint32_t cat_len;
- GUARD(s2n_hmac_init(hmac, alg, pseudo_rand_key->data, pseudo_rand_key->size));
- if (curr_round != 1) {
- GUARD(s2n_hmac_update(hmac, prev, hash_len));
- }
- GUARD(s2n_hmac_update(hmac, info->data, info->size));
- GUARD(s2n_hmac_update(hmac, &curr_round, 1));
- GUARD(s2n_hmac_digest(hmac, prev, hash_len));
-
- cat_len = hash_len;
- if (done_len + hash_len > output->size) {
- cat_len = output->size - done_len;
- }
-
- memcpy_check(output->data + done_len, prev, cat_len);
-
- done_len += cat_len;
-
- GUARD(s2n_hmac_reset(hmac));
- }
-
- return 0;
-}
-
-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)
-{
- /* 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.
- */
- lte_check(label->size, 12);
-
- GUARD(s2n_blob_init(&hkdf_label_blob, hkdf_label_buf, sizeof(hkdf_label_buf)));
- GUARD(s2n_stuffer_init(&hkdf_label, &hkdf_label_blob));
- GUARD(s2n_stuffer_write_uint16(&hkdf_label, output->size));
- GUARD(s2n_stuffer_write_uint8(&hkdf_label, label->size + sizeof("tls13 ") - 1));
- GUARD(s2n_stuffer_write_str(&hkdf_label, "tls13 "));
- GUARD(s2n_stuffer_write(&hkdf_label, label));
- GUARD(s2n_stuffer_write_uint8(&hkdf_label, context->size));
- GUARD(s2n_stuffer_write(&hkdf_label, context));
-
- hkdf_label_blob.size = s2n_stuffer_data_available(&hkdf_label);
- GUARD(s2n_hkdf_expand(hmac, alg, secret, &hkdf_label_blob, output));
-
- return 0;
-}
-
-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 = {.data = prk_pad,.size = sizeof(prk_pad) };
-
- GUARD(s2n_hkdf_extract(hmac, alg, salt, key, &pseudo_rand_key));
- GUARD(s2n_hkdf_expand(hmac, alg, &pseudo_rand_key, info, output));
-
- return 0;
-}
+/*
+ * 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 <stdio.h>
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_hmac.h"
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_mem.h"
+
+#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,
+ const struct s2n_blob *key, struct s2n_blob *pseudo_rand_key)
+{
+ uint8_t hmac_size;
+ GUARD(s2n_hmac_digest_size(alg, &hmac_size));
+ pseudo_rand_key->size = hmac_size;
+ GUARD(s2n_hmac_init(hmac, alg, salt->data, salt->size));
+ GUARD(s2n_hmac_update(hmac, key->data, key->size));
+ GUARD(s2n_hmac_digest(hmac, pseudo_rand_key->data, pseudo_rand_key->size));
+
+ GUARD(s2n_hmac_reset(hmac));
+
+ return 0;
+}
+
+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)
+{
+ uint8_t prev[MAX_DIGEST_SIZE] = { 0 };
+
+ uint32_t done_len = 0;
+ uint8_t hash_len;
+ GUARD(s2n_hmac_digest_size(alg, &hash_len));
+ uint32_t total_rounds = output->size / hash_len;
+ if (output->size % hash_len) {
+ total_rounds++;
+ }
+
+ S2N_ERROR_IF(total_rounds > MAX_HKDF_ROUNDS || total_rounds == 0, S2N_ERR_HKDF_OUTPUT_SIZE);
+
+ for (uint32_t curr_round = 1; curr_round <= total_rounds; curr_round++) {
+ uint32_t cat_len;
+ GUARD(s2n_hmac_init(hmac, alg, pseudo_rand_key->data, pseudo_rand_key->size));
+ if (curr_round != 1) {
+ GUARD(s2n_hmac_update(hmac, prev, hash_len));
+ }
+ GUARD(s2n_hmac_update(hmac, info->data, info->size));
+ GUARD(s2n_hmac_update(hmac, &curr_round, 1));
+ GUARD(s2n_hmac_digest(hmac, prev, hash_len));
+
+ cat_len = hash_len;
+ if (done_len + hash_len > output->size) {
+ cat_len = output->size - done_len;
+ }
+
+ memcpy_check(output->data + done_len, prev, cat_len);
+
+ done_len += cat_len;
+
+ GUARD(s2n_hmac_reset(hmac));
+ }
+
+ return 0;
+}
+
+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)
+{
+ /* 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.
+ */
+ lte_check(label->size, 12);
+
+ GUARD(s2n_blob_init(&hkdf_label_blob, hkdf_label_buf, sizeof(hkdf_label_buf)));
+ GUARD(s2n_stuffer_init(&hkdf_label, &hkdf_label_blob));
+ GUARD(s2n_stuffer_write_uint16(&hkdf_label, output->size));
+ GUARD(s2n_stuffer_write_uint8(&hkdf_label, label->size + sizeof("tls13 ") - 1));
+ GUARD(s2n_stuffer_write_str(&hkdf_label, "tls13 "));
+ GUARD(s2n_stuffer_write(&hkdf_label, label));
+ GUARD(s2n_stuffer_write_uint8(&hkdf_label, context->size));
+ GUARD(s2n_stuffer_write(&hkdf_label, context));
+
+ hkdf_label_blob.size = s2n_stuffer_data_available(&hkdf_label);
+ GUARD(s2n_hkdf_expand(hmac, alg, secret, &hkdf_label_blob, output));
+
+ return 0;
+}
+
+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 = {.data = prk_pad,.size = sizeof(prk_pad) };
+
+ GUARD(s2n_hkdf_extract(hmac, alg, salt, key, &pseudo_rand_key));
+ GUARD(s2n_hkdf_expand(hmac, alg, &pseudo_rand_key, info, output));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hkdf.h b/contrib/restricted/aws/s2n/crypto/s2n_hkdf.h
index 9df0e766ba..a0759ba305 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_hkdf.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_hkdf.h
@@ -1,31 +1,31 @@
-/*
- * 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 <stdint.h>
-
-#include "utils/s2n_blob.h"
-
-#include "crypto/s2n_hmac.h"
-
-extern 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);
-
-extern 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);
-
-extern 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);
+/*
+ * 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 <stdint.h>
+
+#include "utils/s2n_blob.h"
+
+#include "crypto/s2n_hmac.h"
+
+extern 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);
+
+extern 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);
+
+extern 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);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hmac.c b/contrib/restricted/aws/s2n/crypto/s2n_hmac.c
index 8f5acf045a..5362be79ba 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_hmac.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_hmac.c
@@ -1,350 +1,350 @@
-/*
- * 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 <openssl/md5.h>
-#include <openssl/sha.h>
-
-#include "error/s2n_errno.h"
-
-#include "crypto/s2n_hmac.h"
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_fips.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_mem.h"
-
-#include <stdint.h>
-
-
-int s2n_hmac_hash_alg(s2n_hmac_algorithm hmac_alg, s2n_hash_algorithm *out)
-{
- switch(hmac_alg) {
- case S2N_HMAC_NONE: *out = S2N_HASH_NONE; break;
- case S2N_HMAC_MD5: *out = S2N_HASH_MD5; break;
- case S2N_HMAC_SHA1: *out = S2N_HASH_SHA1; break;
- case S2N_HMAC_SHA224: *out = S2N_HASH_SHA224; break;
- case S2N_HMAC_SHA256: *out = S2N_HASH_SHA256; break;
- case S2N_HMAC_SHA384: *out = S2N_HASH_SHA384; break;
- case S2N_HMAC_SHA512: *out = S2N_HASH_SHA512; break;
- case S2N_HMAC_SSLv3_MD5: *out = S2N_HASH_MD5; break;
- case S2N_HMAC_SSLv3_SHA1: *out = S2N_HASH_SHA1; break;
- default:
- S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM);
- }
- return 0;
-}
-
-int s2n_hmac_digest_size(s2n_hmac_algorithm hmac_alg, uint8_t *out)
-{
- s2n_hash_algorithm hash_alg;
- GUARD(s2n_hmac_hash_alg(hmac_alg, &hash_alg));
- GUARD(s2n_hash_digest_size(hash_alg, out));
- return 0;
-}
-
-/* Return 1 if hmac algorithm is available, 0 otherwise. */
-int s2n_hmac_is_available(s2n_hmac_algorithm hmac_alg)
-{
- int is_available = 0;
- switch(hmac_alg) {
- case S2N_HMAC_MD5:
- case S2N_HMAC_SSLv3_MD5:
- case S2N_HMAC_SSLv3_SHA1:
- /* Set is_available to 0 if in FIPS mode, as MD5/SSLv3 algs are not available in FIPS mode. */
- is_available = !s2n_is_in_fips_mode();
- break;
- case S2N_HMAC_NONE:
- case S2N_HMAC_SHA1:
- case S2N_HMAC_SHA224:
- case S2N_HMAC_SHA256:
- case S2N_HMAC_SHA384:
- case S2N_HMAC_SHA512:
- is_available = 1;
- break;
- default:
- S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM);
- }
-
- return is_available;
-}
-
-static int s2n_sslv3_mac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen)
-{
- for (int i = 0; i < state->xor_pad_size; i++) {
- state->xor_pad[i] = 0x36;
- }
-
- GUARD(s2n_hash_update(&state->inner_just_key, key, klen));
- GUARD(s2n_hash_update(&state->inner_just_key, state->xor_pad, state->xor_pad_size));
-
- for (int i = 0; i < state->xor_pad_size; i++) {
- state->xor_pad[i] = 0x5c;
- }
-
- GUARD(s2n_hash_update(&state->outer_just_key, key, klen));
- GUARD(s2n_hash_update(&state->outer_just_key, state->xor_pad, state->xor_pad_size));
-
- return 0;
-}
-
-static int s2n_tls_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen)
-{
- memset(&state->xor_pad, 0, sizeof(state->xor_pad));
-
- if (klen > state->xor_pad_size) {
- GUARD(s2n_hash_update(&state->outer, key, klen));
- GUARD(s2n_hash_digest(&state->outer, state->digest_pad, state->digest_size));
- memcpy_check(state->xor_pad, state->digest_pad, state->digest_size);
- } else {
- memcpy_check(state->xor_pad, key, klen);
- }
-
- for (int i = 0; i < state->xor_pad_size; i++) {
- state->xor_pad[i] ^= 0x36;
- }
-
- GUARD(s2n_hash_update(&state->inner_just_key, state->xor_pad, state->xor_pad_size));
-
- /* 0x36 xor 0x5c == 0x6a */
- for (int i = 0; i < state->xor_pad_size; i++) {
- state->xor_pad[i] ^= 0x6a;
- }
-
- GUARD(s2n_hash_update(&state->outer_just_key, state->xor_pad, state->xor_pad_size));
- return 0;
-}
-
-int s2n_hmac_xor_pad_size(s2n_hmac_algorithm hmac_alg, uint16_t *xor_pad_size)
-{
- switch(hmac_alg) {
- case S2N_HMAC_NONE: *xor_pad_size = 64; break;
- case S2N_HMAC_MD5: *xor_pad_size = 64; break;
- case S2N_HMAC_SHA1: *xor_pad_size = 64; break;
- case S2N_HMAC_SHA224: *xor_pad_size = 64; break;
- case S2N_HMAC_SHA256: *xor_pad_size = 64; break;
- case S2N_HMAC_SHA384: *xor_pad_size = 128; break;
- case S2N_HMAC_SHA512: *xor_pad_size = 128; break;
- case S2N_HMAC_SSLv3_MD5: *xor_pad_size = 48; break;
- case S2N_HMAC_SSLv3_SHA1: *xor_pad_size = 40; break;
- default:
- S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM);
- }
- return 0;
-}
-
-int s2n_hmac_hash_block_size(s2n_hmac_algorithm hmac_alg, uint16_t *block_size)
-{
- switch(hmac_alg) {
- case S2N_HMAC_NONE: *block_size = 64; break;
- case S2N_HMAC_MD5: *block_size = 64; break;
- case S2N_HMAC_SHA1: *block_size = 64; break;
- case S2N_HMAC_SHA224: *block_size = 64; break;
- case S2N_HMAC_SHA256: *block_size = 64; break;
- case S2N_HMAC_SHA384: *block_size = 128; break;
- case S2N_HMAC_SHA512: *block_size = 128; break;
- case S2N_HMAC_SSLv3_MD5: *block_size = 64; break;
- case S2N_HMAC_SSLv3_SHA1: *block_size = 64; break;
- default:
- S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM);
- }
- return 0;
-}
-
-int s2n_hmac_new(struct s2n_hmac_state *state)
-{
- GUARD(s2n_hash_new(&state->inner));
- GUARD(s2n_hash_new(&state->inner_just_key));
- GUARD(s2n_hash_new(&state->outer));
- GUARD(s2n_hash_new(&state->outer_just_key));
-
- return 0;
-}
-
-int s2n_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen)
-{
- if (!s2n_hmac_is_available(alg)) {
- /* Prevent hmacs from being used if they are not available. */
- S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM);
- }
-
- state->alg = alg;
- GUARD(s2n_hmac_hash_block_size(alg, &state->hash_block_size));
- state->currently_in_hash_block = 0;
- GUARD(s2n_hmac_xor_pad_size(alg, &state->xor_pad_size));
- GUARD(s2n_hmac_digest_size(alg, &state->digest_size));
-
- gte_check(sizeof(state->xor_pad), state->xor_pad_size);
- gte_check(sizeof(state->digest_pad), state->digest_size);
- /* key needs to be as large as the biggest block size */
- gte_check(sizeof(state->xor_pad), state->hash_block_size);
-
- s2n_hash_algorithm hash_alg;
- GUARD(s2n_hmac_hash_alg(alg, &hash_alg));
-
- GUARD(s2n_hash_init(&state->inner, hash_alg));
- GUARD(s2n_hash_init(&state->inner_just_key, hash_alg));
- GUARD(s2n_hash_init(&state->outer, hash_alg));
- GUARD(s2n_hash_init(&state->outer_just_key, hash_alg));
-
- if (alg == S2N_HMAC_SSLv3_SHA1 || alg == S2N_HMAC_SSLv3_MD5) {
- GUARD(s2n_sslv3_mac_init(state, alg, key, klen));
- } else {
- GUARD(s2n_tls_hmac_init(state, alg, key, klen));
- }
-
- /* Once we have produced inner_just_key and outer_just_key, don't need the key material in xor_pad, so wipe it.
- * Since xor_pad is used as a source of bytes in s2n_hmac_digest_two_compression_rounds,
- * this also prevents uninitilized bytes being used.
- */
- memset(&state->xor_pad, 0, sizeof(state->xor_pad));
- GUARD(s2n_hmac_reset(state));
-
- return 0;
-}
-
-int s2n_hmac_update(struct s2n_hmac_state *state, const void *in, uint32_t size)
-{
- /* Keep track of how much of the current hash block is full
- *
- * Why the 4294949760 constant in this code? 4294949760 is the highest 32-bit
- * value that is congruent to 0 modulo all of our HMAC block sizes, that is also
- * at least 16k smaller than 2^32. It therefore has no effect on the mathematical
- * result, and no valid record size can cause it to overflow.
+/*
+ * 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 <openssl/md5.h>
+#include <openssl/sha.h>
+
+#include "error/s2n_errno.h"
+
+#include "crypto/s2n_hmac.h"
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_fips.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_mem.h"
+
+#include <stdint.h>
+
+
+int s2n_hmac_hash_alg(s2n_hmac_algorithm hmac_alg, s2n_hash_algorithm *out)
+{
+ switch(hmac_alg) {
+ case S2N_HMAC_NONE: *out = S2N_HASH_NONE; break;
+ case S2N_HMAC_MD5: *out = S2N_HASH_MD5; break;
+ case S2N_HMAC_SHA1: *out = S2N_HASH_SHA1; break;
+ case S2N_HMAC_SHA224: *out = S2N_HASH_SHA224; break;
+ case S2N_HMAC_SHA256: *out = S2N_HASH_SHA256; break;
+ case S2N_HMAC_SHA384: *out = S2N_HASH_SHA384; break;
+ case S2N_HMAC_SHA512: *out = S2N_HASH_SHA512; break;
+ case S2N_HMAC_SSLv3_MD5: *out = S2N_HASH_MD5; break;
+ case S2N_HMAC_SSLv3_SHA1: *out = S2N_HASH_SHA1; break;
+ default:
+ S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM);
+ }
+ return 0;
+}
+
+int s2n_hmac_digest_size(s2n_hmac_algorithm hmac_alg, uint8_t *out)
+{
+ s2n_hash_algorithm hash_alg;
+ GUARD(s2n_hmac_hash_alg(hmac_alg, &hash_alg));
+ GUARD(s2n_hash_digest_size(hash_alg, out));
+ return 0;
+}
+
+/* Return 1 if hmac algorithm is available, 0 otherwise. */
+int s2n_hmac_is_available(s2n_hmac_algorithm hmac_alg)
+{
+ int is_available = 0;
+ switch(hmac_alg) {
+ case S2N_HMAC_MD5:
+ case S2N_HMAC_SSLv3_MD5:
+ case S2N_HMAC_SSLv3_SHA1:
+ /* Set is_available to 0 if in FIPS mode, as MD5/SSLv3 algs are not available in FIPS mode. */
+ is_available = !s2n_is_in_fips_mode();
+ break;
+ case S2N_HMAC_NONE:
+ case S2N_HMAC_SHA1:
+ case S2N_HMAC_SHA224:
+ case S2N_HMAC_SHA256:
+ case S2N_HMAC_SHA384:
+ case S2N_HMAC_SHA512:
+ is_available = 1;
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM);
+ }
+
+ return is_available;
+}
+
+static int s2n_sslv3_mac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen)
+{
+ for (int i = 0; i < state->xor_pad_size; i++) {
+ state->xor_pad[i] = 0x36;
+ }
+
+ GUARD(s2n_hash_update(&state->inner_just_key, key, klen));
+ GUARD(s2n_hash_update(&state->inner_just_key, state->xor_pad, state->xor_pad_size));
+
+ for (int i = 0; i < state->xor_pad_size; i++) {
+ state->xor_pad[i] = 0x5c;
+ }
+
+ GUARD(s2n_hash_update(&state->outer_just_key, key, klen));
+ GUARD(s2n_hash_update(&state->outer_just_key, state->xor_pad, state->xor_pad_size));
+
+ return 0;
+}
+
+static int s2n_tls_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen)
+{
+ memset(&state->xor_pad, 0, sizeof(state->xor_pad));
+
+ if (klen > state->xor_pad_size) {
+ GUARD(s2n_hash_update(&state->outer, key, klen));
+ GUARD(s2n_hash_digest(&state->outer, state->digest_pad, state->digest_size));
+ memcpy_check(state->xor_pad, state->digest_pad, state->digest_size);
+ } else {
+ memcpy_check(state->xor_pad, key, klen);
+ }
+
+ for (int i = 0; i < state->xor_pad_size; i++) {
+ state->xor_pad[i] ^= 0x36;
+ }
+
+ GUARD(s2n_hash_update(&state->inner_just_key, state->xor_pad, state->xor_pad_size));
+
+ /* 0x36 xor 0x5c == 0x6a */
+ for (int i = 0; i < state->xor_pad_size; i++) {
+ state->xor_pad[i] ^= 0x6a;
+ }
+
+ GUARD(s2n_hash_update(&state->outer_just_key, state->xor_pad, state->xor_pad_size));
+ return 0;
+}
+
+int s2n_hmac_xor_pad_size(s2n_hmac_algorithm hmac_alg, uint16_t *xor_pad_size)
+{
+ switch(hmac_alg) {
+ case S2N_HMAC_NONE: *xor_pad_size = 64; break;
+ case S2N_HMAC_MD5: *xor_pad_size = 64; break;
+ case S2N_HMAC_SHA1: *xor_pad_size = 64; break;
+ case S2N_HMAC_SHA224: *xor_pad_size = 64; break;
+ case S2N_HMAC_SHA256: *xor_pad_size = 64; break;
+ case S2N_HMAC_SHA384: *xor_pad_size = 128; break;
+ case S2N_HMAC_SHA512: *xor_pad_size = 128; break;
+ case S2N_HMAC_SSLv3_MD5: *xor_pad_size = 48; break;
+ case S2N_HMAC_SSLv3_SHA1: *xor_pad_size = 40; break;
+ default:
+ S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM);
+ }
+ return 0;
+}
+
+int s2n_hmac_hash_block_size(s2n_hmac_algorithm hmac_alg, uint16_t *block_size)
+{
+ switch(hmac_alg) {
+ case S2N_HMAC_NONE: *block_size = 64; break;
+ case S2N_HMAC_MD5: *block_size = 64; break;
+ case S2N_HMAC_SHA1: *block_size = 64; break;
+ case S2N_HMAC_SHA224: *block_size = 64; break;
+ case S2N_HMAC_SHA256: *block_size = 64; break;
+ case S2N_HMAC_SHA384: *block_size = 128; break;
+ case S2N_HMAC_SHA512: *block_size = 128; break;
+ case S2N_HMAC_SSLv3_MD5: *block_size = 64; break;
+ case S2N_HMAC_SSLv3_SHA1: *block_size = 64; break;
+ default:
+ S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM);
+ }
+ return 0;
+}
+
+int s2n_hmac_new(struct s2n_hmac_state *state)
+{
+ GUARD(s2n_hash_new(&state->inner));
+ GUARD(s2n_hash_new(&state->inner_just_key));
+ GUARD(s2n_hash_new(&state->outer));
+ GUARD(s2n_hash_new(&state->outer_just_key));
+
+ return 0;
+}
+
+int s2n_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen)
+{
+ if (!s2n_hmac_is_available(alg)) {
+ /* Prevent hmacs from being used if they are not available. */
+ S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM);
+ }
+
+ state->alg = alg;
+ GUARD(s2n_hmac_hash_block_size(alg, &state->hash_block_size));
+ state->currently_in_hash_block = 0;
+ GUARD(s2n_hmac_xor_pad_size(alg, &state->xor_pad_size));
+ GUARD(s2n_hmac_digest_size(alg, &state->digest_size));
+
+ gte_check(sizeof(state->xor_pad), state->xor_pad_size);
+ gte_check(sizeof(state->digest_pad), state->digest_size);
+ /* key needs to be as large as the biggest block size */
+ gte_check(sizeof(state->xor_pad), state->hash_block_size);
+
+ s2n_hash_algorithm hash_alg;
+ GUARD(s2n_hmac_hash_alg(alg, &hash_alg));
+
+ GUARD(s2n_hash_init(&state->inner, hash_alg));
+ GUARD(s2n_hash_init(&state->inner_just_key, hash_alg));
+ GUARD(s2n_hash_init(&state->outer, hash_alg));
+ GUARD(s2n_hash_init(&state->outer_just_key, hash_alg));
+
+ if (alg == S2N_HMAC_SSLv3_SHA1 || alg == S2N_HMAC_SSLv3_MD5) {
+ GUARD(s2n_sslv3_mac_init(state, alg, key, klen));
+ } else {
+ GUARD(s2n_tls_hmac_init(state, alg, key, klen));
+ }
+
+ /* Once we have produced inner_just_key and outer_just_key, don't need the key material in xor_pad, so wipe it.
+ * Since xor_pad is used as a source of bytes in s2n_hmac_digest_two_compression_rounds,
+ * this also prevents uninitilized bytes being used.
+ */
+ memset(&state->xor_pad, 0, sizeof(state->xor_pad));
+ GUARD(s2n_hmac_reset(state));
+
+ return 0;
+}
+
+int s2n_hmac_update(struct s2n_hmac_state *state, const void *in, uint32_t size)
+{
+ /* Keep track of how much of the current hash block is full
*
- * The value was found with the following python code;
+ * Why the 4294949760 constant in this code? 4294949760 is the highest 32-bit
+ * value that is congruent to 0 modulo all of our HMAC block sizes, that is also
+ * at least 16k smaller than 2^32. It therefore has no effect on the mathematical
+ * result, and no valid record size can cause it to overflow.
+ *
+ * The value was found with the following python code;
+ *
+ * x = (2 ** 32) - (2 ** 14)
+ * while True:
+ * if x % 40 | x % 48 | x % 64 | x % 128 == 0:
+ * break
+ * x -= 1
+ * print x
*
- * x = (2 ** 32) - (2 ** 14)
- * while True:
- * if x % 40 | x % 48 | x % 64 | x % 128 == 0:
- * break
- * x -= 1
- * print x
- *
- * What it does do however is ensure that the mod operation takes a
- * constant number of instruction cycles, regardless of the size of the
- * input. On some platforms, including Intel, the operation can take a
- * smaller number of cycles if the input is "small".
- */
- state->currently_in_hash_block += (4294949760 + size) % state->hash_block_size;
- state->currently_in_hash_block %= state->hash_block_size;
-
- return s2n_hash_update(&state->inner, in, size);
-}
-
-int s2n_hmac_digest(struct s2n_hmac_state *state, void *out, uint32_t size)
-{
- GUARD(s2n_hash_digest(&state->inner, state->digest_pad, state->digest_size));
- GUARD(s2n_hash_copy(&state->outer, &state->outer_just_key));
- GUARD(s2n_hash_update(&state->outer, state->digest_pad, state->digest_size));
-
- return s2n_hash_digest(&state->outer, out, size);
-}
-
-int s2n_hmac_digest_two_compression_rounds(struct s2n_hmac_state *state, void *out, uint32_t size)
-{
- /* Do the "real" work of this function. */
- GUARD(s2n_hmac_digest(state, out, size));
-
- /* If there were 9 or more bytes of space left in the current hash block
- * then the serialized length, plus an 0x80 byte, will have fit in that block.
- * If there were fewer than 9 then adding the length will have caused an extra
- * compression block round. This digest function always does two compression rounds,
- * even if there is no need for the second.
- *
- * 17 bytes if the block size is 128.
- */
- const uint8_t space_left = (state->hash_block_size == 128) ? 17 : 9;
- if (state->currently_in_hash_block > (state->hash_block_size - space_left)) {
- return 0;
- }
-
- /* Can't reuse a hash after it has been finalized, so reset and push another block in */
- GUARD(s2n_hash_reset(&state->inner));
-
- /* No-op s2n_hash_update to normalize timing and guard against Lucky13. This does not affect the value of *out. */
- return s2n_hash_update(&state->inner, state->xor_pad, state->hash_block_size);
-}
-
-int s2n_hmac_free(struct s2n_hmac_state *state)
-{
- GUARD(s2n_hash_free(&state->inner));
- GUARD(s2n_hash_free(&state->inner_just_key));
- GUARD(s2n_hash_free(&state->outer));
- GUARD(s2n_hash_free(&state->outer_just_key));
-
- return 0;
-}
-
-int s2n_hmac_reset(struct s2n_hmac_state *state)
-{
- GUARD(s2n_hash_copy(&state->inner, &state->inner_just_key));
-
- uint64_t bytes_in_hash;
- GUARD(s2n_hash_get_currently_in_hash_total(&state->inner, &bytes_in_hash));
- /* The length of the key is not private, so don't need to do tricky math here */
- state->currently_in_hash_block = bytes_in_hash % state->hash_block_size;
- return 0;
-}
-
-int s2n_hmac_digest_verify(const void *a, const void *b, uint32_t len)
-{
- return 0 - !s2n_constant_time_equals(a, b, len);
-}
-
-int s2n_hmac_copy(struct s2n_hmac_state *to, struct s2n_hmac_state *from)
-{
- /* memcpy cannot be used on s2n_hmac_state as the underlying s2n_hash implementation's
- * copy must be used. This is enforced when the s2n_hash implementation is s2n_evp_hash.
- */
- to->alg = from->alg;
- to->hash_block_size = from->hash_block_size;
- to->currently_in_hash_block = from->currently_in_hash_block;
- to->xor_pad_size = from->xor_pad_size;
- to->digest_size = from->digest_size;
-
- GUARD(s2n_hash_copy(&to->inner, &from->inner));
- GUARD(s2n_hash_copy(&to->inner_just_key, &from->inner_just_key));
- GUARD(s2n_hash_copy(&to->outer, &from->outer));
- GUARD(s2n_hash_copy(&to->outer_just_key, &from->outer_just_key));
-
-
- memcpy_check(to->xor_pad, from->xor_pad, sizeof(to->xor_pad));
- memcpy_check(to->digest_pad, from->digest_pad, sizeof(to->digest_pad));
-
- return 0;
-}
-
-
-/* Preserve the handlers for hmac state pointers to avoid re-allocation
- * Only valid if the HMAC is in EVP mode
- */
-int s2n_hmac_save_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac)
-{
- backup->inner = hmac->inner.digest.high_level;
- backup->inner_just_key = hmac->inner_just_key.digest.high_level;
- backup->outer = hmac->outer.digest.high_level;
- backup->outer_just_key = hmac->outer_just_key.digest.high_level;
- return 0;
-}
-
-int s2n_hmac_restore_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac)
-{
- hmac->inner.digest.high_level = backup->inner;
- hmac->inner_just_key.digest.high_level = backup->inner_just_key;
- hmac->outer.digest.high_level = backup->outer;
- hmac->outer_just_key.digest.high_level = backup->outer_just_key;
- return 0;
-}
+ * What it does do however is ensure that the mod operation takes a
+ * constant number of instruction cycles, regardless of the size of the
+ * input. On some platforms, including Intel, the operation can take a
+ * smaller number of cycles if the input is "small".
+ */
+ state->currently_in_hash_block += (4294949760 + size) % state->hash_block_size;
+ state->currently_in_hash_block %= state->hash_block_size;
+
+ return s2n_hash_update(&state->inner, in, size);
+}
+
+int s2n_hmac_digest(struct s2n_hmac_state *state, void *out, uint32_t size)
+{
+ GUARD(s2n_hash_digest(&state->inner, state->digest_pad, state->digest_size));
+ GUARD(s2n_hash_copy(&state->outer, &state->outer_just_key));
+ GUARD(s2n_hash_update(&state->outer, state->digest_pad, state->digest_size));
+
+ return s2n_hash_digest(&state->outer, out, size);
+}
+
+int s2n_hmac_digest_two_compression_rounds(struct s2n_hmac_state *state, void *out, uint32_t size)
+{
+ /* Do the "real" work of this function. */
+ GUARD(s2n_hmac_digest(state, out, size));
+
+ /* If there were 9 or more bytes of space left in the current hash block
+ * then the serialized length, plus an 0x80 byte, will have fit in that block.
+ * If there were fewer than 9 then adding the length will have caused an extra
+ * compression block round. This digest function always does two compression rounds,
+ * even if there is no need for the second.
+ *
+ * 17 bytes if the block size is 128.
+ */
+ const uint8_t space_left = (state->hash_block_size == 128) ? 17 : 9;
+ if (state->currently_in_hash_block > (state->hash_block_size - space_left)) {
+ return 0;
+ }
+
+ /* Can't reuse a hash after it has been finalized, so reset and push another block in */
+ GUARD(s2n_hash_reset(&state->inner));
+
+ /* No-op s2n_hash_update to normalize timing and guard against Lucky13. This does not affect the value of *out. */
+ return s2n_hash_update(&state->inner, state->xor_pad, state->hash_block_size);
+}
+
+int s2n_hmac_free(struct s2n_hmac_state *state)
+{
+ GUARD(s2n_hash_free(&state->inner));
+ GUARD(s2n_hash_free(&state->inner_just_key));
+ GUARD(s2n_hash_free(&state->outer));
+ GUARD(s2n_hash_free(&state->outer_just_key));
+
+ return 0;
+}
+
+int s2n_hmac_reset(struct s2n_hmac_state *state)
+{
+ GUARD(s2n_hash_copy(&state->inner, &state->inner_just_key));
+
+ uint64_t bytes_in_hash;
+ GUARD(s2n_hash_get_currently_in_hash_total(&state->inner, &bytes_in_hash));
+ /* The length of the key is not private, so don't need to do tricky math here */
+ state->currently_in_hash_block = bytes_in_hash % state->hash_block_size;
+ return 0;
+}
+
+int s2n_hmac_digest_verify(const void *a, const void *b, uint32_t len)
+{
+ return 0 - !s2n_constant_time_equals(a, b, len);
+}
+
+int s2n_hmac_copy(struct s2n_hmac_state *to, struct s2n_hmac_state *from)
+{
+ /* memcpy cannot be used on s2n_hmac_state as the underlying s2n_hash implementation's
+ * copy must be used. This is enforced when the s2n_hash implementation is s2n_evp_hash.
+ */
+ to->alg = from->alg;
+ to->hash_block_size = from->hash_block_size;
+ to->currently_in_hash_block = from->currently_in_hash_block;
+ to->xor_pad_size = from->xor_pad_size;
+ to->digest_size = from->digest_size;
+
+ GUARD(s2n_hash_copy(&to->inner, &from->inner));
+ GUARD(s2n_hash_copy(&to->inner_just_key, &from->inner_just_key));
+ GUARD(s2n_hash_copy(&to->outer, &from->outer));
+ GUARD(s2n_hash_copy(&to->outer_just_key, &from->outer_just_key));
+
+
+ memcpy_check(to->xor_pad, from->xor_pad, sizeof(to->xor_pad));
+ memcpy_check(to->digest_pad, from->digest_pad, sizeof(to->digest_pad));
+
+ return 0;
+}
+
+
+/* Preserve the handlers for hmac state pointers to avoid re-allocation
+ * Only valid if the HMAC is in EVP mode
+ */
+int s2n_hmac_save_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac)
+{
+ backup->inner = hmac->inner.digest.high_level;
+ backup->inner_just_key = hmac->inner_just_key.digest.high_level;
+ backup->outer = hmac->outer.digest.high_level;
+ backup->outer_just_key = hmac->outer_just_key.digest.high_level;
+ return 0;
+}
+
+int s2n_hmac_restore_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac)
+{
+ hmac->inner.digest.high_level = backup->inner;
+ hmac->inner_just_key.digest.high_level = backup->inner_just_key;
+ hmac->outer.digest.high_level = backup->outer;
+ hmac->outer_just_key.digest.high_level = backup->outer_just_key;
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hmac.h b/contrib/restricted/aws/s2n/crypto/s2n_hmac.h
index b54966f8c3..e2be24dd05 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_hmac.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_hmac.h
@@ -1,79 +1,79 @@
-/*
- * 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 <stdint.h>
-
-#include "crypto/s2n_hash.h"
-
-typedef enum {
- S2N_HMAC_NONE,
- S2N_HMAC_MD5,
- S2N_HMAC_SHA1,
- S2N_HMAC_SHA224,
- S2N_HMAC_SHA256,
- S2N_HMAC_SHA384,
- S2N_HMAC_SHA512,
- S2N_HMAC_SSLv3_MD5,
- S2N_HMAC_SSLv3_SHA1
-} s2n_hmac_algorithm;
-
-struct s2n_hmac_state {
- s2n_hmac_algorithm alg;
-
- uint16_t hash_block_size;
- uint32_t currently_in_hash_block;
- uint16_t xor_pad_size;
- uint8_t digest_size;
-
- struct s2n_hash_state inner;
- struct s2n_hash_state inner_just_key;
- struct s2n_hash_state outer;
- struct s2n_hash_state outer_just_key;
-
-
- /* key needs to be as large as the biggest block size */
- uint8_t xor_pad[128];
-
- /* For storing the inner digest */
- uint8_t digest_pad[SHA512_DIGEST_LENGTH];
-};
-
-struct s2n_hmac_evp_backup {
- struct s2n_hash_evp_digest inner;
- struct s2n_hash_evp_digest inner_just_key;
- struct s2n_hash_evp_digest outer;
- struct s2n_hash_evp_digest outer_just_key;
-};
-
-extern int s2n_hmac_digest_size(s2n_hmac_algorithm alg, uint8_t *out);
-extern int s2n_hmac_is_available(s2n_hmac_algorithm alg);
-extern int s2n_hmac_hash_alg(s2n_hmac_algorithm hmac_alg, s2n_hash_algorithm *out);
-extern int s2n_hash_hmac_alg(s2n_hash_algorithm hash_alg, s2n_hmac_algorithm *out);
-
-extern int s2n_hmac_new(struct s2n_hmac_state *state);
-extern int s2n_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen);
-extern int s2n_hmac_update(struct s2n_hmac_state *state, const void *in, uint32_t size);
-extern int s2n_hmac_digest(struct s2n_hmac_state *state, void *out, uint32_t size);
-extern int s2n_hmac_digest_two_compression_rounds(struct s2n_hmac_state *state, void *out, uint32_t size);
-extern int s2n_hmac_digest_verify(const void *a, const void *b, uint32_t len);
-extern int s2n_hmac_free(struct s2n_hmac_state *state);
-extern int s2n_hmac_reset(struct s2n_hmac_state *state);
-extern int s2n_hmac_copy(struct s2n_hmac_state *to, struct s2n_hmac_state *from);
-extern int s2n_hmac_save_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac);
-extern int s2n_hmac_restore_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac);
-
-
+/*
+ * 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 <stdint.h>
+
+#include "crypto/s2n_hash.h"
+
+typedef enum {
+ S2N_HMAC_NONE,
+ S2N_HMAC_MD5,
+ S2N_HMAC_SHA1,
+ S2N_HMAC_SHA224,
+ S2N_HMAC_SHA256,
+ S2N_HMAC_SHA384,
+ S2N_HMAC_SHA512,
+ S2N_HMAC_SSLv3_MD5,
+ S2N_HMAC_SSLv3_SHA1
+} s2n_hmac_algorithm;
+
+struct s2n_hmac_state {
+ s2n_hmac_algorithm alg;
+
+ uint16_t hash_block_size;
+ uint32_t currently_in_hash_block;
+ uint16_t xor_pad_size;
+ uint8_t digest_size;
+
+ struct s2n_hash_state inner;
+ struct s2n_hash_state inner_just_key;
+ struct s2n_hash_state outer;
+ struct s2n_hash_state outer_just_key;
+
+
+ /* key needs to be as large as the biggest block size */
+ uint8_t xor_pad[128];
+
+ /* For storing the inner digest */
+ uint8_t digest_pad[SHA512_DIGEST_LENGTH];
+};
+
+struct s2n_hmac_evp_backup {
+ struct s2n_hash_evp_digest inner;
+ struct s2n_hash_evp_digest inner_just_key;
+ struct s2n_hash_evp_digest outer;
+ struct s2n_hash_evp_digest outer_just_key;
+};
+
+extern int s2n_hmac_digest_size(s2n_hmac_algorithm alg, uint8_t *out);
+extern int s2n_hmac_is_available(s2n_hmac_algorithm alg);
+extern int s2n_hmac_hash_alg(s2n_hmac_algorithm hmac_alg, s2n_hash_algorithm *out);
+extern int s2n_hash_hmac_alg(s2n_hash_algorithm hash_alg, s2n_hmac_algorithm *out);
+
+extern int s2n_hmac_new(struct s2n_hmac_state *state);
+extern int s2n_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen);
+extern int s2n_hmac_update(struct s2n_hmac_state *state, const void *in, uint32_t size);
+extern int s2n_hmac_digest(struct s2n_hmac_state *state, void *out, uint32_t size);
+extern int s2n_hmac_digest_two_compression_rounds(struct s2n_hmac_state *state, void *out, uint32_t size);
+extern int s2n_hmac_digest_verify(const void *a, const void *b, uint32_t len);
+extern int s2n_hmac_free(struct s2n_hmac_state *state);
+extern int s2n_hmac_reset(struct s2n_hmac_state *state);
+extern int s2n_hmac_copy(struct s2n_hmac_state *to, struct s2n_hmac_state *from);
+extern int s2n_hmac_save_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac);
+extern int s2n_hmac_restore_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac);
+
+
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_openssl.h b/contrib/restricted/aws/s2n/crypto/s2n_openssl.h
index 92c53c26fd..a7ec6c8739 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_openssl.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_openssl.h
@@ -1,49 +1,49 @@
-/*
- * 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
-
-/**
- * openssl with OPENSSL_VERSION_NUMBER < 0x10100003L made data type details unavailable
- * libressl use openssl with data type details available, but mandatorily set
- * OPENSSL_VERSION_NUMBER = 0x20000000L, insane!
- * https://github.com/aws/aws-sdk-cpp/pull/507/commits/2c99f1fe0c4b4683280caeb161538d4724d6a179
- */
-#if defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x20000000L)
-#undef OPENSSL_VERSION_NUMBER
-#define OPENSSL_VERSION_NUMBER 0x1000107fL
-#endif
-
-/* Per https://wiki.openssl.org/index.php/Manual:OPENSSL_VERSION_NUMBER(3)
- * OPENSSL_VERSION_NUMBER in hex is: MNNFFRBB major minor fix final beta/patch.
- * bitwise: MMMMNNNNNNNNFFFFFFFFRRRRBBBBBBBB
- * For our purposes we're only concerned about major/minor/fix. Patch versions don't usually introduce
- * features.
- */
-
-#define S2N_OPENSSL_VERSION_AT_LEAST(major, minor, fix) \
- (OPENSSL_VERSION_NUMBER >= ((major << 28) + (minor << 20) + (fix << 12)))
-
-#if (S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0)) && (!defined(OPENSSL_IS_BORINGSSL)) && (!defined(OPENSSL_IS_AWSLC))
-#define s2n_evp_ctx_init(ctx) GUARD_OSSL(EVP_CIPHER_CTX_init(ctx), S2N_ERR_DRBG)
-#else
-#define s2n_evp_ctx_init(ctx) EVP_CIPHER_CTX_init(ctx)
-#endif
-
-#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_FIPS) && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_AWSLC)
-#define S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND 1
-#else
-#define S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND 0
-#endif
+/*
+ * 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
+
+/**
+ * openssl with OPENSSL_VERSION_NUMBER < 0x10100003L made data type details unavailable
+ * libressl use openssl with data type details available, but mandatorily set
+ * OPENSSL_VERSION_NUMBER = 0x20000000L, insane!
+ * https://github.com/aws/aws-sdk-cpp/pull/507/commits/2c99f1fe0c4b4683280caeb161538d4724d6a179
+ */
+#if defined(LIBRESSL_VERSION_NUMBER) && (OPENSSL_VERSION_NUMBER == 0x20000000L)
+#undef OPENSSL_VERSION_NUMBER
+#define OPENSSL_VERSION_NUMBER 0x1000107fL
+#endif
+
+/* Per https://wiki.openssl.org/index.php/Manual:OPENSSL_VERSION_NUMBER(3)
+ * OPENSSL_VERSION_NUMBER in hex is: MNNFFRBB major minor fix final beta/patch.
+ * bitwise: MMMMNNNNNNNNFFFFFFFFRRRRBBBBBBBB
+ * For our purposes we're only concerned about major/minor/fix. Patch versions don't usually introduce
+ * features.
+ */
+
+#define S2N_OPENSSL_VERSION_AT_LEAST(major, minor, fix) \
+ (OPENSSL_VERSION_NUMBER >= ((major << 28) + (minor << 20) + (fix << 12)))
+
+#if (S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0)) && (!defined(OPENSSL_IS_BORINGSSL)) && (!defined(OPENSSL_IS_AWSLC))
+#define s2n_evp_ctx_init(ctx) GUARD_OSSL(EVP_CIPHER_CTX_init(ctx), S2N_ERR_DRBG)
+#else
+#define s2n_evp_ctx_init(ctx) EVP_CIPHER_CTX_init(ctx)
+#endif
+
+#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_FIPS) && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_AWSLC)
+#define S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND 1
+#else
+#define S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND 0
+#endif
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_openssl_evp.h b/contrib/restricted/aws/s2n/crypto/s2n_openssl_evp.h
index 4b033bf2b2..1c9b874ac2 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_openssl_evp.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_openssl_evp.h
@@ -1,22 +1,22 @@
-/*
- * 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 <openssl/evp.h>
-
-#include "utils/s2n_safety.h"
-
-DEFINE_POINTER_CLEANUP_FUNC(EVP_PKEY*, EVP_PKEY_free);
+/*
+ * 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 <openssl/evp.h>
+
+#include "utils/s2n_safety.h"
+
+DEFINE_POINTER_CLEANUP_FUNC(EVP_PKEY*, EVP_PKEY_free);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h b/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h
index 812b7233ba..38d89c8d7a 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h
@@ -1,22 +1,22 @@
-/*
- * 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 <openssl/x509.h>
-
-#include "utils/s2n_safety.h"
-
-DEFINE_POINTER_CLEANUP_FUNC(X509*, X509_free);
+/*
+ * 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 <openssl/x509.h>
+
+#include "utils/s2n_safety.h"
+
+DEFINE_POINTER_CLEANUP_FUNC(X509*, X509_free);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_pkey.c b/contrib/restricted/aws/s2n/crypto/s2n_pkey.c
index 9123e88080..b280cc0854 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_pkey.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_pkey.c
@@ -1,235 +1,235 @@
-/*
- * 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 <openssl/evp.h>
-#include <crypto/s2n_openssl_evp.h>
-#include <crypto/s2n_openssl_x509.h>
-
-#include "error/s2n_errno.h"
-#include "crypto/s2n_rsa_pss.h"
-#include "crypto/s2n_pkey.h"
-
-#include "utils/s2n_safety.h"
-
-int s2n_pkey_zero_init(struct s2n_pkey *pkey)
-{
- pkey->pkey = NULL;
- pkey->size = NULL;
- pkey->sign = NULL;
- pkey->verify = NULL;
- pkey->encrypt = NULL;
- pkey->decrypt = NULL;
- pkey->match = NULL;
- pkey->free = NULL;
- pkey->check_key = NULL;
- return 0;
-}
-
-int s2n_pkey_setup_for_type(struct s2n_pkey *pkey, s2n_pkey_type pkey_type)
-{
- switch(pkey_type) {
- case S2N_PKEY_TYPE_RSA:
- return s2n_rsa_pkey_init(pkey);
- case S2N_PKEY_TYPE_ECDSA:
- return s2n_ecdsa_pkey_init(pkey);
- case S2N_PKEY_TYPE_RSA_PSS:
- return s2n_rsa_pss_pkey_init(pkey);
- case S2N_PKEY_TYPE_SENTINEL:
- case S2N_PKEY_TYPE_UNKNOWN:
- S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
- }
- S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
-}
-
-int s2n_pkey_check_key_exists(const struct s2n_pkey *pkey)
-{
- notnull_check(pkey->pkey);
- notnull_check(pkey->check_key);
-
- return pkey->check_key(pkey);
-}
-
-int s2n_pkey_size(const struct s2n_pkey *pkey)
-{
- notnull_check(pkey->size);
-
- return pkey->size(pkey);
-}
-
-int s2n_pkey_sign(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature)
-{
- notnull_check(pkey->sign);
-
- return pkey->sign(pkey, sig_alg, digest, signature);
-}
-
-int s2n_pkey_verify(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature)
-{
- notnull_check(pkey);
- notnull_check(pkey->verify);
-
- return pkey->verify(pkey, sig_alg, digest, signature);
-}
-
-int s2n_pkey_encrypt(const struct s2n_pkey *pkey, struct s2n_blob *in, struct s2n_blob *out)
-{
- notnull_check(pkey->encrypt);
-
- return pkey->encrypt(pkey, in, out);
-}
-
-int s2n_pkey_decrypt(const struct s2n_pkey *pkey, struct s2n_blob *in, struct s2n_blob *out)
-{
- notnull_check(pkey->decrypt);
-
- return pkey->decrypt(pkey, in, out);
-}
-
-int s2n_pkey_match(const struct s2n_pkey *pub_key, const struct s2n_pkey *priv_key)
-{
- notnull_check(pub_key->match);
-
- S2N_ERROR_IF(pub_key->match != priv_key->match, S2N_ERR_KEY_MISMATCH);
-
- return pub_key->match(pub_key, priv_key);
-}
-
-int s2n_pkey_free(struct s2n_pkey *key)
-{
- if (key != NULL && key->free != NULL) {
- GUARD(key->free(key));
- }
-
- if (key->pkey != NULL) {
- EVP_PKEY_free(key->pkey);
- key->pkey = NULL;
- }
-
- return S2N_SUCCESS;
-}
-
-int s2n_asn1der_to_private_key(struct s2n_pkey *priv_key, struct s2n_blob *asn1der)
-{
- uint8_t *key_to_parse = asn1der->data;
-
- /* Detect key type */
- DEFER_CLEANUP(EVP_PKEY *evp_private_key = d2i_AutoPrivateKey(NULL, (const unsigned char **)(void *)&key_to_parse, asn1der->size),
- EVP_PKEY_free_pointer);
- S2N_ERROR_IF(evp_private_key == NULL, S2N_ERR_DECODE_PRIVATE_KEY);
-
- /* If key parsing is successful, d2i_AutoPrivateKey increments *key_to_parse to the byte following the parsed data */
- uint32_t parsed_len = key_to_parse - asn1der->data;
- if (parsed_len != asn1der->size) {
- S2N_ERROR(S2N_ERR_DECODE_PRIVATE_KEY);
- }
-
- /* Initialize s2n_pkey according to key type */
- int type = EVP_PKEY_base_id(evp_private_key);
-
- int ret;
- switch (type) {
- case EVP_PKEY_RSA:
- ret = s2n_rsa_pkey_init(priv_key);
- if (ret != 0) {
- break;
- }
- ret = s2n_evp_pkey_to_rsa_private_key(&priv_key->key.rsa_key, evp_private_key);
- break;
- case EVP_PKEY_RSA_PSS:
- ret = s2n_rsa_pss_pkey_init(priv_key);
- if (ret != 0) {
- break;
- }
- ret = s2n_evp_pkey_to_rsa_pss_private_key(&priv_key->key.rsa_key, evp_private_key);
- break;
- case EVP_PKEY_EC:
- ret = s2n_ecdsa_pkey_init(priv_key);
- if (ret != 0) {
- break;
- }
- ret = s2n_evp_pkey_to_ecdsa_private_key(&priv_key->key.ecdsa_key, evp_private_key);
- break;
- default:
- S2N_ERROR(S2N_ERR_DECODE_PRIVATE_KEY);
- }
-
- priv_key->pkey = evp_private_key;
- /* Reset to avoid DEFER_CLEANUP freeing our key */
- evp_private_key = NULL;
-
- return ret;
-}
-
-int s2n_asn1der_to_public_key_and_type(struct s2n_pkey *pub_key, s2n_pkey_type *pkey_type_out, struct s2n_blob *asn1der)
-{
- uint8_t *cert_to_parse = asn1der->data;
- DEFER_CLEANUP(X509 *cert = NULL, X509_free_pointer);
-
- cert = d2i_X509(NULL, (const unsigned char **)(void *)&cert_to_parse, asn1der->size);
- S2N_ERROR_IF(cert == NULL, S2N_ERR_DECODE_CERTIFICATE);
-
- /* If cert parsing is successful, d2i_X509 increments *cert_to_parse to the byte following the parsed data */
- uint32_t parsed_len = cert_to_parse - asn1der->data;
-
- /* Some TLS clients in the wild send one extra trailing byte after the Certificate.
- * Allow this in s2n for backwards compatibility with existing clients. */
- uint32_t trailing_bytes = asn1der->size - parsed_len;
- ENSURE_POSIX(trailing_bytes <= 1, S2N_ERR_DECODE_CERTIFICATE);
-
- DEFER_CLEANUP(EVP_PKEY *evp_public_key = X509_get_pubkey(cert), EVP_PKEY_free_pointer);
- S2N_ERROR_IF(evp_public_key == NULL, S2N_ERR_DECODE_CERTIFICATE);
-
- /* Check for success in decoding certificate according to type */
- int type = EVP_PKEY_base_id(evp_public_key);
-
- int ret;
- switch (type) {
- case EVP_PKEY_RSA:
- ret = s2n_rsa_pkey_init(pub_key);
- if (ret != 0) {
- break;
- }
- ret = s2n_evp_pkey_to_rsa_public_key(&pub_key->key.rsa_key, evp_public_key);
- *pkey_type_out = S2N_PKEY_TYPE_RSA;
- break;
- case EVP_PKEY_RSA_PSS:
- ret = s2n_rsa_pss_pkey_init(pub_key);
- if (ret != 0) {
- break;
- }
- ret = s2n_evp_pkey_to_rsa_pss_public_key(&pub_key->key.rsa_key, evp_public_key);
- *pkey_type_out = S2N_PKEY_TYPE_RSA_PSS;
- break;
- case EVP_PKEY_EC:
- ret = s2n_ecdsa_pkey_init(pub_key);
- if (ret != 0) {
- break;
- }
- ret = s2n_evp_pkey_to_ecdsa_public_key(&pub_key->key.ecdsa_key, evp_public_key);
- *pkey_type_out = S2N_PKEY_TYPE_ECDSA;
- break;
- default:
- S2N_ERROR(S2N_ERR_DECODE_CERTIFICATE);
- }
-
- pub_key->pkey = evp_public_key;
- /* Reset to avoid DEFER_CLEANUP freeing our key */
- evp_public_key = NULL;
-
- return ret;
-}
-
+/*
+ * 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 <openssl/evp.h>
+#include <crypto/s2n_openssl_evp.h>
+#include <crypto/s2n_openssl_x509.h>
+
+#include "error/s2n_errno.h"
+#include "crypto/s2n_rsa_pss.h"
+#include "crypto/s2n_pkey.h"
+
+#include "utils/s2n_safety.h"
+
+int s2n_pkey_zero_init(struct s2n_pkey *pkey)
+{
+ pkey->pkey = NULL;
+ pkey->size = NULL;
+ pkey->sign = NULL;
+ pkey->verify = NULL;
+ pkey->encrypt = NULL;
+ pkey->decrypt = NULL;
+ pkey->match = NULL;
+ pkey->free = NULL;
+ pkey->check_key = NULL;
+ return 0;
+}
+
+int s2n_pkey_setup_for_type(struct s2n_pkey *pkey, s2n_pkey_type pkey_type)
+{
+ switch(pkey_type) {
+ case S2N_PKEY_TYPE_RSA:
+ return s2n_rsa_pkey_init(pkey);
+ case S2N_PKEY_TYPE_ECDSA:
+ return s2n_ecdsa_pkey_init(pkey);
+ case S2N_PKEY_TYPE_RSA_PSS:
+ return s2n_rsa_pss_pkey_init(pkey);
+ case S2N_PKEY_TYPE_SENTINEL:
+ case S2N_PKEY_TYPE_UNKNOWN:
+ S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
+ }
+ S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED);
+}
+
+int s2n_pkey_check_key_exists(const struct s2n_pkey *pkey)
+{
+ notnull_check(pkey->pkey);
+ notnull_check(pkey->check_key);
+
+ return pkey->check_key(pkey);
+}
+
+int s2n_pkey_size(const struct s2n_pkey *pkey)
+{
+ notnull_check(pkey->size);
+
+ return pkey->size(pkey);
+}
+
+int s2n_pkey_sign(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature)
+{
+ notnull_check(pkey->sign);
+
+ return pkey->sign(pkey, sig_alg, digest, signature);
+}
+
+int s2n_pkey_verify(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature)
+{
+ notnull_check(pkey);
+ notnull_check(pkey->verify);
+
+ return pkey->verify(pkey, sig_alg, digest, signature);
+}
+
+int s2n_pkey_encrypt(const struct s2n_pkey *pkey, struct s2n_blob *in, struct s2n_blob *out)
+{
+ notnull_check(pkey->encrypt);
+
+ return pkey->encrypt(pkey, in, out);
+}
+
+int s2n_pkey_decrypt(const struct s2n_pkey *pkey, struct s2n_blob *in, struct s2n_blob *out)
+{
+ notnull_check(pkey->decrypt);
+
+ return pkey->decrypt(pkey, in, out);
+}
+
+int s2n_pkey_match(const struct s2n_pkey *pub_key, const struct s2n_pkey *priv_key)
+{
+ notnull_check(pub_key->match);
+
+ S2N_ERROR_IF(pub_key->match != priv_key->match, S2N_ERR_KEY_MISMATCH);
+
+ return pub_key->match(pub_key, priv_key);
+}
+
+int s2n_pkey_free(struct s2n_pkey *key)
+{
+ if (key != NULL && key->free != NULL) {
+ GUARD(key->free(key));
+ }
+
+ if (key->pkey != NULL) {
+ EVP_PKEY_free(key->pkey);
+ key->pkey = NULL;
+ }
+
+ return S2N_SUCCESS;
+}
+
+int s2n_asn1der_to_private_key(struct s2n_pkey *priv_key, struct s2n_blob *asn1der)
+{
+ uint8_t *key_to_parse = asn1der->data;
+
+ /* Detect key type */
+ DEFER_CLEANUP(EVP_PKEY *evp_private_key = d2i_AutoPrivateKey(NULL, (const unsigned char **)(void *)&key_to_parse, asn1der->size),
+ EVP_PKEY_free_pointer);
+ S2N_ERROR_IF(evp_private_key == NULL, S2N_ERR_DECODE_PRIVATE_KEY);
+
+ /* If key parsing is successful, d2i_AutoPrivateKey increments *key_to_parse to the byte following the parsed data */
+ uint32_t parsed_len = key_to_parse - asn1der->data;
+ if (parsed_len != asn1der->size) {
+ S2N_ERROR(S2N_ERR_DECODE_PRIVATE_KEY);
+ }
+
+ /* Initialize s2n_pkey according to key type */
+ int type = EVP_PKEY_base_id(evp_private_key);
+
+ int ret;
+ switch (type) {
+ case EVP_PKEY_RSA:
+ ret = s2n_rsa_pkey_init(priv_key);
+ if (ret != 0) {
+ break;
+ }
+ ret = s2n_evp_pkey_to_rsa_private_key(&priv_key->key.rsa_key, evp_private_key);
+ break;
+ case EVP_PKEY_RSA_PSS:
+ ret = s2n_rsa_pss_pkey_init(priv_key);
+ if (ret != 0) {
+ break;
+ }
+ ret = s2n_evp_pkey_to_rsa_pss_private_key(&priv_key->key.rsa_key, evp_private_key);
+ break;
+ case EVP_PKEY_EC:
+ ret = s2n_ecdsa_pkey_init(priv_key);
+ if (ret != 0) {
+ break;
+ }
+ ret = s2n_evp_pkey_to_ecdsa_private_key(&priv_key->key.ecdsa_key, evp_private_key);
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_DECODE_PRIVATE_KEY);
+ }
+
+ priv_key->pkey = evp_private_key;
+ /* Reset to avoid DEFER_CLEANUP freeing our key */
+ evp_private_key = NULL;
+
+ return ret;
+}
+
+int s2n_asn1der_to_public_key_and_type(struct s2n_pkey *pub_key, s2n_pkey_type *pkey_type_out, struct s2n_blob *asn1der)
+{
+ uint8_t *cert_to_parse = asn1der->data;
+ DEFER_CLEANUP(X509 *cert = NULL, X509_free_pointer);
+
+ cert = d2i_X509(NULL, (const unsigned char **)(void *)&cert_to_parse, asn1der->size);
+ S2N_ERROR_IF(cert == NULL, S2N_ERR_DECODE_CERTIFICATE);
+
+ /* If cert parsing is successful, d2i_X509 increments *cert_to_parse to the byte following the parsed data */
+ uint32_t parsed_len = cert_to_parse - asn1der->data;
+
+ /* Some TLS clients in the wild send one extra trailing byte after the Certificate.
+ * Allow this in s2n for backwards compatibility with existing clients. */
+ uint32_t trailing_bytes = asn1der->size - parsed_len;
+ ENSURE_POSIX(trailing_bytes <= 1, S2N_ERR_DECODE_CERTIFICATE);
+
+ DEFER_CLEANUP(EVP_PKEY *evp_public_key = X509_get_pubkey(cert), EVP_PKEY_free_pointer);
+ S2N_ERROR_IF(evp_public_key == NULL, S2N_ERR_DECODE_CERTIFICATE);
+
+ /* Check for success in decoding certificate according to type */
+ int type = EVP_PKEY_base_id(evp_public_key);
+
+ int ret;
+ switch (type) {
+ case EVP_PKEY_RSA:
+ ret = s2n_rsa_pkey_init(pub_key);
+ if (ret != 0) {
+ break;
+ }
+ ret = s2n_evp_pkey_to_rsa_public_key(&pub_key->key.rsa_key, evp_public_key);
+ *pkey_type_out = S2N_PKEY_TYPE_RSA;
+ break;
+ case EVP_PKEY_RSA_PSS:
+ ret = s2n_rsa_pss_pkey_init(pub_key);
+ if (ret != 0) {
+ break;
+ }
+ ret = s2n_evp_pkey_to_rsa_pss_public_key(&pub_key->key.rsa_key, evp_public_key);
+ *pkey_type_out = S2N_PKEY_TYPE_RSA_PSS;
+ break;
+ case EVP_PKEY_EC:
+ ret = s2n_ecdsa_pkey_init(pub_key);
+ if (ret != 0) {
+ break;
+ }
+ ret = s2n_evp_pkey_to_ecdsa_public_key(&pub_key->key.ecdsa_key, evp_public_key);
+ *pkey_type_out = S2N_PKEY_TYPE_ECDSA;
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_DECODE_CERTIFICATE);
+ }
+
+ pub_key->pkey = evp_public_key;
+ /* Reset to avoid DEFER_CLEANUP freeing our key */
+ evp_public_key = NULL;
+
+ return ret;
+}
+
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_pkey.h b/contrib/restricted/aws/s2n/crypto/s2n_pkey.h
index 1da8f785c6..c39468695a 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_pkey.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_pkey.h
@@ -1,73 +1,73 @@
-/*
- * 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 <openssl/evp.h>
-
-#include "crypto/s2n_signature.h"
-#include "crypto/s2n_ecdsa.h"
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_rsa.h"
-
-#include "utils/s2n_blob.h"
-
-/* Public/Private Key Type */
-typedef enum {
- S2N_PKEY_TYPE_UNKNOWN = -1,
- S2N_PKEY_TYPE_RSA = 0,
- S2N_PKEY_TYPE_ECDSA,
- S2N_PKEY_TYPE_RSA_PSS,
- S2N_PKEY_TYPE_SENTINEL
-} s2n_pkey_type;
-
-/* Structure that models a public or private key and type-specific operations */
-struct s2n_pkey {
- /* Legacy OpenSSL APIs operate on specific keys, but the more recent
- * APIs all operate on EVP_PKEY. Let's store both for backwards compatibility. */
- union {
- struct s2n_rsa_key rsa_key;
- struct s2n_ecdsa_key ecdsa_key;
- } key;
- EVP_PKEY *pkey;
-
- int (*size)(const struct s2n_pkey *key);
- int (*sign)(const struct s2n_pkey *priv_key, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature);
- int (*verify)(const struct s2n_pkey *pub_key, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature);
- int (*encrypt)(const struct s2n_pkey *key, struct s2n_blob *in, struct s2n_blob *out);
- int (*decrypt)(const struct s2n_pkey *key, struct s2n_blob *in, struct s2n_blob *out);
- int (*match)(const struct s2n_pkey *pub_key, const struct s2n_pkey *priv_key);
- int (*free)(struct s2n_pkey *key);
- int (*check_key)(const struct s2n_pkey *key);
-};
-
-int s2n_pkey_zero_init(struct s2n_pkey *pkey);
-int s2n_pkey_setup_for_type(struct s2n_pkey *pkey, s2n_pkey_type pkey_type);
-int s2n_pkey_check_key_exists(const struct s2n_pkey *pkey);
-
-int s2n_pkey_size(const struct s2n_pkey *pkey);
-int s2n_pkey_sign(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature);
-int s2n_pkey_verify(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature);
-int s2n_pkey_encrypt(const struct s2n_pkey *pkey, struct s2n_blob *in, struct s2n_blob *out);
-int s2n_pkey_decrypt(const struct s2n_pkey *pkey, struct s2n_blob *in, struct s2n_blob *out);
-int s2n_pkey_match(const struct s2n_pkey *pub_key, const struct s2n_pkey *priv_key);
-int s2n_pkey_free(struct s2n_pkey *pkey);
-
-int s2n_asn1der_to_private_key(struct s2n_pkey *priv_key, struct s2n_blob *asn1der);
-int s2n_asn1der_to_public_key_and_type(struct s2n_pkey *pub_key, s2n_pkey_type *pkey_type, struct s2n_blob *asn1der);
+/*
+ * 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 <openssl/evp.h>
+
+#include "crypto/s2n_signature.h"
+#include "crypto/s2n_ecdsa.h"
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_rsa.h"
+
+#include "utils/s2n_blob.h"
+
+/* Public/Private Key Type */
+typedef enum {
+ S2N_PKEY_TYPE_UNKNOWN = -1,
+ S2N_PKEY_TYPE_RSA = 0,
+ S2N_PKEY_TYPE_ECDSA,
+ S2N_PKEY_TYPE_RSA_PSS,
+ S2N_PKEY_TYPE_SENTINEL
+} s2n_pkey_type;
+
+/* Structure that models a public or private key and type-specific operations */
+struct s2n_pkey {
+ /* Legacy OpenSSL APIs operate on specific keys, but the more recent
+ * APIs all operate on EVP_PKEY. Let's store both for backwards compatibility. */
+ union {
+ struct s2n_rsa_key rsa_key;
+ struct s2n_ecdsa_key ecdsa_key;
+ } key;
+ EVP_PKEY *pkey;
+
+ int (*size)(const struct s2n_pkey *key);
+ int (*sign)(const struct s2n_pkey *priv_key, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature);
+ int (*verify)(const struct s2n_pkey *pub_key, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature);
+ int (*encrypt)(const struct s2n_pkey *key, struct s2n_blob *in, struct s2n_blob *out);
+ int (*decrypt)(const struct s2n_pkey *key, struct s2n_blob *in, struct s2n_blob *out);
+ int (*match)(const struct s2n_pkey *pub_key, const struct s2n_pkey *priv_key);
+ int (*free)(struct s2n_pkey *key);
+ int (*check_key)(const struct s2n_pkey *key);
+};
+
+int s2n_pkey_zero_init(struct s2n_pkey *pkey);
+int s2n_pkey_setup_for_type(struct s2n_pkey *pkey, s2n_pkey_type pkey_type);
+int s2n_pkey_check_key_exists(const struct s2n_pkey *pkey);
+
+int s2n_pkey_size(const struct s2n_pkey *pkey);
+int s2n_pkey_sign(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature);
+int s2n_pkey_verify(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature);
+int s2n_pkey_encrypt(const struct s2n_pkey *pkey, struct s2n_blob *in, struct s2n_blob *out);
+int s2n_pkey_decrypt(const struct s2n_pkey *pkey, struct s2n_blob *in, struct s2n_blob *out);
+int s2n_pkey_match(const struct s2n_pkey *pub_key, const struct s2n_pkey *priv_key);
+int s2n_pkey_free(struct s2n_pkey *pkey);
+
+int s2n_asn1der_to_private_key(struct s2n_pkey *priv_key, struct s2n_blob *asn1der);
+int s2n_asn1der_to_public_key_and_type(struct s2n_pkey *pub_key, s2n_pkey_type *pkey_type, struct s2n_blob *asn1der);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa.c
index 38eba11e0b..88b6603e7a 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa.c
@@ -1,190 +1,190 @@
-/*
- * 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 <openssl/evp.h>
-#include <openssl/rsa.h>
-#include <stdint.h>
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_drbg.h"
-#include "crypto/s2n_rsa.h"
-#include "crypto/s2n_rsa_signing.h"
-#include "crypto/s2n_pkey.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_blob.h"
-
-static int s2n_rsa_modulus_check(RSA *rsa)
-{
- /* RSA was made opaque starting in Openssl 1.1.0 */
- #if S2N_OPENSSL_VERSION_AT_LEAST(1,1,0) && !defined(LIBRESSL_VERSION_NUMBER)
- const BIGNUM *n = NULL;
- /* RSA still owns the memory for n */
- RSA_get0_key(rsa, &n, NULL, NULL);
- notnull_check(n);
- #else
- notnull_check(rsa->n);
- #endif
- return 0;
-}
-
-static int s2n_rsa_encrypted_size(const struct s2n_pkey *key)
-{
- const struct s2n_rsa_key *rsa_key = &key->key.rsa_key;
- notnull_check(rsa_key->rsa);
- GUARD(s2n_rsa_modulus_check(rsa_key->rsa));
-
- return RSA_size(rsa_key->rsa);
-}
-
-static int s2n_rsa_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature)
-{
- switch(sig_alg) {
- case S2N_SIGNATURE_RSA:
- return s2n_rsa_pkcs1v15_sign(priv, digest, signature);
- case S2N_SIGNATURE_RSA_PSS_RSAE:
- return s2n_rsa_pss_sign(priv, digest, signature);
- default:
- S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_rsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature)
-{
- switch(sig_alg) {
- case S2N_SIGNATURE_RSA:
- return s2n_rsa_pkcs1v15_verify(pub, digest, signature);
- case S2N_SIGNATURE_RSA_PSS_RSAE:
- return s2n_rsa_pss_verify(pub, digest, signature);
- default:
- S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
- }
-
- return S2N_SUCCESS;
-}
-
-static int s2n_rsa_encrypt(const struct s2n_pkey *pub, struct s2n_blob *in, struct s2n_blob *out)
-{
- S2N_ERROR_IF(out->size < s2n_rsa_encrypted_size(pub), S2N_ERR_NOMEM);
-
- const s2n_rsa_public_key *key = &pub->key.rsa_key;
- int r = RSA_public_encrypt(in->size, (unsigned char *)in->data, (unsigned char *)out->data, key->rsa, RSA_PKCS1_PADDING);
- S2N_ERROR_IF(r != out->size, S2N_ERR_SIZE_MISMATCH);
-
- return 0;
-}
-
-static int s2n_rsa_decrypt(const struct s2n_pkey *priv, struct s2n_blob *in, struct s2n_blob *out)
-{
- unsigned char intermediate[4096];
- const int expected_size = s2n_rsa_encrypted_size(priv);
-
- GUARD(expected_size);
- S2N_ERROR_IF(expected_size > sizeof(intermediate), S2N_ERR_NOMEM);
- S2N_ERROR_IF(out->size > sizeof(intermediate), S2N_ERR_NOMEM);
-
- GUARD_AS_POSIX(s2n_get_public_random_data(out));
-
- const s2n_rsa_private_key *key = &priv->key.rsa_key;
- int r = RSA_private_decrypt(in->size, (unsigned char *)in->data, intermediate, key->rsa, RSA_NO_PADDING);
- S2N_ERROR_IF(r != expected_size, S2N_ERR_SIZE_MISMATCH);
-
- s2n_constant_time_pkcs1_unpad_or_dont(out->data, intermediate, r, out->size);
-
- return 0;
-}
-
-static int s2n_rsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
-{
- uint8_t plain_inpad[36] = {1}, plain_outpad[36] = {0}, encpad[8192];
- struct s2n_blob plain_in = { 0 }, plain_out = { 0 }, enc = { 0 };
-
- plain_in.data = plain_inpad;
- plain_in.size = sizeof(plain_inpad);
-
- enc.data = encpad;
- enc.size = s2n_rsa_encrypted_size(pub);
- lte_check(enc.size, sizeof(encpad));
- GUARD(s2n_rsa_encrypt(pub, &plain_in, &enc));
-
- plain_out.data = plain_outpad;
- plain_out.size = sizeof(plain_outpad);
- GUARD(s2n_rsa_decrypt(priv, &enc, &plain_out));
-
- S2N_ERROR_IF(memcmp(plain_in.data, plain_out.data, plain_in.size), S2N_ERR_KEY_MISMATCH);
-
- return 0;
-}
-
-static int s2n_rsa_key_free(struct s2n_pkey *pkey)
-{
- struct s2n_rsa_key *rsa_key = &pkey->key.rsa_key;
- if (rsa_key->rsa == NULL) {
- return 0;
- }
-
- RSA_free(rsa_key->rsa);
- rsa_key->rsa = NULL;
-
- return 0;
-}
-
-static int s2n_rsa_check_key_exists(const struct s2n_pkey *pkey)
-{
- const struct s2n_rsa_key *rsa_key = &pkey->key.rsa_key;
- notnull_check(rsa_key->rsa);
- return 0;
-}
-
-int s2n_evp_pkey_to_rsa_public_key(s2n_rsa_public_key *rsa_key, EVP_PKEY *evp_public_key)
-{
- RSA *rsa = EVP_PKEY_get1_RSA(evp_public_key);
- S2N_ERROR_IF(rsa == NULL, S2N_ERR_DECODE_CERTIFICATE);
-
- rsa_key->rsa = rsa;
- return 0;
-}
-
-int s2n_evp_pkey_to_rsa_private_key(s2n_rsa_private_key *rsa_key, EVP_PKEY *evp_private_key)
-{
- RSA *rsa = EVP_PKEY_get1_RSA(evp_private_key);
- S2N_ERROR_IF(rsa == NULL, S2N_ERR_DECODE_PRIVATE_KEY);
-
- rsa_key->rsa = rsa;
- return 0;
-}
-
-int s2n_rsa_pkey_init(struct s2n_pkey *pkey)
-{
- pkey->size = &s2n_rsa_encrypted_size;
- pkey->sign = &s2n_rsa_sign;
- pkey->verify = &s2n_rsa_verify;
- pkey->encrypt = &s2n_rsa_encrypt;
- pkey->decrypt = &s2n_rsa_decrypt;
- pkey->match = &s2n_rsa_keys_match;
- pkey->free = &s2n_rsa_key_free;
- pkey->check_key = &s2n_rsa_check_key_exists;
- return 0;
-}
-
+/*
+ * 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 <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <stdint.h>
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_drbg.h"
+#include "crypto/s2n_rsa.h"
+#include "crypto/s2n_rsa_signing.h"
+#include "crypto/s2n_pkey.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_blob.h"
+
+static int s2n_rsa_modulus_check(RSA *rsa)
+{
+ /* RSA was made opaque starting in Openssl 1.1.0 */
+ #if S2N_OPENSSL_VERSION_AT_LEAST(1,1,0) && !defined(LIBRESSL_VERSION_NUMBER)
+ const BIGNUM *n = NULL;
+ /* RSA still owns the memory for n */
+ RSA_get0_key(rsa, &n, NULL, NULL);
+ notnull_check(n);
+ #else
+ notnull_check(rsa->n);
+ #endif
+ return 0;
+}
+
+static int s2n_rsa_encrypted_size(const struct s2n_pkey *key)
+{
+ const struct s2n_rsa_key *rsa_key = &key->key.rsa_key;
+ notnull_check(rsa_key->rsa);
+ GUARD(s2n_rsa_modulus_check(rsa_key->rsa));
+
+ return RSA_size(rsa_key->rsa);
+}
+
+static int s2n_rsa_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature)
+{
+ switch(sig_alg) {
+ case S2N_SIGNATURE_RSA:
+ return s2n_rsa_pkcs1v15_sign(priv, digest, signature);
+ case S2N_SIGNATURE_RSA_PSS_RSAE:
+ return s2n_rsa_pss_sign(priv, digest, signature);
+ default:
+ S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_rsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature)
+{
+ switch(sig_alg) {
+ case S2N_SIGNATURE_RSA:
+ return s2n_rsa_pkcs1v15_verify(pub, digest, signature);
+ case S2N_SIGNATURE_RSA_PSS_RSAE:
+ return s2n_rsa_pss_verify(pub, digest, signature);
+ default:
+ S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
+ }
+
+ return S2N_SUCCESS;
+}
+
+static int s2n_rsa_encrypt(const struct s2n_pkey *pub, struct s2n_blob *in, struct s2n_blob *out)
+{
+ S2N_ERROR_IF(out->size < s2n_rsa_encrypted_size(pub), S2N_ERR_NOMEM);
+
+ const s2n_rsa_public_key *key = &pub->key.rsa_key;
+ int r = RSA_public_encrypt(in->size, (unsigned char *)in->data, (unsigned char *)out->data, key->rsa, RSA_PKCS1_PADDING);
+ S2N_ERROR_IF(r != out->size, S2N_ERR_SIZE_MISMATCH);
+
+ return 0;
+}
+
+static int s2n_rsa_decrypt(const struct s2n_pkey *priv, struct s2n_blob *in, struct s2n_blob *out)
+{
+ unsigned char intermediate[4096];
+ const int expected_size = s2n_rsa_encrypted_size(priv);
+
+ GUARD(expected_size);
+ S2N_ERROR_IF(expected_size > sizeof(intermediate), S2N_ERR_NOMEM);
+ S2N_ERROR_IF(out->size > sizeof(intermediate), S2N_ERR_NOMEM);
+
+ GUARD_AS_POSIX(s2n_get_public_random_data(out));
+
+ const s2n_rsa_private_key *key = &priv->key.rsa_key;
+ int r = RSA_private_decrypt(in->size, (unsigned char *)in->data, intermediate, key->rsa, RSA_NO_PADDING);
+ S2N_ERROR_IF(r != expected_size, S2N_ERR_SIZE_MISMATCH);
+
+ s2n_constant_time_pkcs1_unpad_or_dont(out->data, intermediate, r, out->size);
+
+ return 0;
+}
+
+static int s2n_rsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
+{
+ uint8_t plain_inpad[36] = {1}, plain_outpad[36] = {0}, encpad[8192];
+ struct s2n_blob plain_in = { 0 }, plain_out = { 0 }, enc = { 0 };
+
+ plain_in.data = plain_inpad;
+ plain_in.size = sizeof(plain_inpad);
+
+ enc.data = encpad;
+ enc.size = s2n_rsa_encrypted_size(pub);
+ lte_check(enc.size, sizeof(encpad));
+ GUARD(s2n_rsa_encrypt(pub, &plain_in, &enc));
+
+ plain_out.data = plain_outpad;
+ plain_out.size = sizeof(plain_outpad);
+ GUARD(s2n_rsa_decrypt(priv, &enc, &plain_out));
+
+ S2N_ERROR_IF(memcmp(plain_in.data, plain_out.data, plain_in.size), S2N_ERR_KEY_MISMATCH);
+
+ return 0;
+}
+
+static int s2n_rsa_key_free(struct s2n_pkey *pkey)
+{
+ struct s2n_rsa_key *rsa_key = &pkey->key.rsa_key;
+ if (rsa_key->rsa == NULL) {
+ return 0;
+ }
+
+ RSA_free(rsa_key->rsa);
+ rsa_key->rsa = NULL;
+
+ return 0;
+}
+
+static int s2n_rsa_check_key_exists(const struct s2n_pkey *pkey)
+{
+ const struct s2n_rsa_key *rsa_key = &pkey->key.rsa_key;
+ notnull_check(rsa_key->rsa);
+ return 0;
+}
+
+int s2n_evp_pkey_to_rsa_public_key(s2n_rsa_public_key *rsa_key, EVP_PKEY *evp_public_key)
+{
+ RSA *rsa = EVP_PKEY_get1_RSA(evp_public_key);
+ S2N_ERROR_IF(rsa == NULL, S2N_ERR_DECODE_CERTIFICATE);
+
+ rsa_key->rsa = rsa;
+ return 0;
+}
+
+int s2n_evp_pkey_to_rsa_private_key(s2n_rsa_private_key *rsa_key, EVP_PKEY *evp_private_key)
+{
+ RSA *rsa = EVP_PKEY_get1_RSA(evp_private_key);
+ S2N_ERROR_IF(rsa == NULL, S2N_ERR_DECODE_PRIVATE_KEY);
+
+ rsa_key->rsa = rsa;
+ return 0;
+}
+
+int s2n_rsa_pkey_init(struct s2n_pkey *pkey)
+{
+ pkey->size = &s2n_rsa_encrypted_size;
+ pkey->sign = &s2n_rsa_sign;
+ pkey->verify = &s2n_rsa_verify;
+ pkey->encrypt = &s2n_rsa_encrypt;
+ pkey->decrypt = &s2n_rsa_decrypt;
+ pkey->match = &s2n_rsa_keys_match;
+ pkey->free = &s2n_rsa_key_free;
+ pkey->check_key = &s2n_rsa_check_key_exists;
+ return 0;
+}
+
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa.h b/contrib/restricted/aws/s2n/crypto/s2n_rsa.h
index 3d153eaf3d..e6673fbe02 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa.h
@@ -1,40 +1,40 @@
-/*
- * 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 <stdint.h>
-#include <s2n.h>
-
-#include <openssl/rsa.h>
-
-#include "crypto/s2n_hash.h"
-
-#include "utils/s2n_blob.h"
-
-/* Forward declaration to avoid the circular dependency with s2n_pkey.h */
-struct s2n_pkey;
-
-struct s2n_rsa_key {
- RSA *rsa;
-};
-
-typedef struct s2n_rsa_key s2n_rsa_public_key;
-typedef struct s2n_rsa_key s2n_rsa_private_key;
-
-extern int s2n_rsa_pkey_init(struct s2n_pkey *pkey);
-
-extern int s2n_evp_pkey_to_rsa_public_key(s2n_rsa_public_key *rsa_key, EVP_PKEY *pkey);
-extern int s2n_evp_pkey_to_rsa_private_key(s2n_rsa_private_key *rsa_key, EVP_PKEY *pkey);
+/*
+ * 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 <stdint.h>
+#include <s2n.h>
+
+#include <openssl/rsa.h>
+
+#include "crypto/s2n_hash.h"
+
+#include "utils/s2n_blob.h"
+
+/* Forward declaration to avoid the circular dependency with s2n_pkey.h */
+struct s2n_pkey;
+
+struct s2n_rsa_key {
+ RSA *rsa;
+};
+
+typedef struct s2n_rsa_key s2n_rsa_public_key;
+typedef struct s2n_rsa_key s2n_rsa_private_key;
+
+extern int s2n_rsa_pkey_init(struct s2n_pkey *pkey);
+
+extern int s2n_evp_pkey_to_rsa_public_key(s2n_rsa_public_key *rsa_key, EVP_PKEY *pkey);
+extern int s2n_evp_pkey_to_rsa_private_key(s2n_rsa_private_key *rsa_key, EVP_PKEY *pkey);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c
index 1bb444b25c..7fd13ff2b6 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c
@@ -1,241 +1,241 @@
-/*
- * 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 <openssl/evp.h>
-#include <openssl/rsa.h>
-#include <stdint.h>
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_openssl.h"
-#include "crypto/s2n_rsa.h"
-#include "crypto/s2n_rsa_pss.h"
-#include "crypto/s2n_rsa_signing.h"
-#include "crypto/s2n_pkey.h"
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_random.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-/* Checks whether PSS Certs is supported */
-int s2n_is_rsa_pss_certs_supported()
-{
- return RSA_PSS_CERTS_SUPPORTED;
-}
-
-#if RSA_PSS_CERTS_SUPPORTED
-
-static int s2n_rsa_pss_size(const struct s2n_pkey *key)
-{
- notnull_check(key);
-
- /* For more info, see: https://www.openssl.org/docs/man1.1.0/man3/EVP_PKEY_size.html */
- return EVP_PKEY_size(key->pkey);
-}
-
-static int s2n_rsa_is_private_key(RSA *rsa_key)
-{
- const BIGNUM *d = NULL;
- RSA_get0_key(rsa_key, NULL, NULL, &d);
-
- if (d != NULL) {
- return 1;
- }
- return 0;
-}
-
-int s2n_rsa_pss_key_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature_out)
-{
- notnull_check(priv);
- sig_alg_check(sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
-
- /* Not Possible to Sign with Public Key */
- S2N_ERROR_IF(!s2n_rsa_is_private_key(priv->key.rsa_key.rsa), S2N_ERR_KEY_MISMATCH);
-
- return s2n_rsa_pss_sign(priv, digest, signature_out);
-}
-
-int s2n_rsa_pss_key_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg,
- struct s2n_hash_state *digest, struct s2n_blob *signature_in)
-{
- notnull_check(pub);
- sig_alg_check(sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
-
- /* Using Private Key to Verify means the public/private keys were likely swapped, and likely indicates a bug. */
- S2N_ERROR_IF(s2n_rsa_is_private_key(pub->key.rsa_key.rsa), S2N_ERR_KEY_MISMATCH);
-
- return s2n_rsa_pss_verify(pub, digest, signature_in);
-}
-
-static int s2n_rsa_pss_validate_sign_verify_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
-{
- /* Generate a random blob to sign and verify */
- s2n_stack_blob(random_data, RSA_PSS_SIGN_VERIFY_RANDOM_BLOB_SIZE, RSA_PSS_SIGN_VERIFY_RANDOM_BLOB_SIZE);
- GUARD_AS_POSIX(s2n_get_private_random_data(&random_data));
-
- /* Sign/Verify API's only accept Hashes, so hash our Random Data */
- DEFER_CLEANUP(struct s2n_hash_state sign_hash = {0}, s2n_hash_free);
- DEFER_CLEANUP(struct s2n_hash_state verify_hash = {0}, s2n_hash_free);
- GUARD(s2n_hash_new(&sign_hash));
- GUARD(s2n_hash_new(&verify_hash));
- GUARD(s2n_hash_init(&sign_hash, S2N_HASH_SHA256));
- GUARD(s2n_hash_init(&verify_hash, S2N_HASH_SHA256));
- GUARD(s2n_hash_update(&sign_hash, random_data.data, random_data.size));
- GUARD(s2n_hash_update(&verify_hash, random_data.data, random_data.size));
-
- /* Sign and Verify the Hash of the Random Blob */
- s2n_stack_blob(signature_data, RSA_PSS_SIGN_VERIFY_SIGNATURE_SIZE, RSA_PSS_SIGN_VERIFY_SIGNATURE_SIZE);
- GUARD(s2n_rsa_pss_key_sign(priv, S2N_SIGNATURE_RSA_PSS_PSS, &sign_hash, &signature_data));
- GUARD(s2n_rsa_pss_key_verify(pub, S2N_SIGNATURE_RSA_PSS_PSS, &verify_hash, &signature_data));
-
- return 0;
-}
-
-static int s2n_rsa_validate_params_equal(const RSA *pub, const RSA *priv)
-{
- const BIGNUM *pub_val_e = NULL;
- const BIGNUM *pub_val_n = NULL;
- RSA_get0_key(pub, &pub_val_n, &pub_val_e, NULL);
-
- const BIGNUM *priv_val_e = NULL;
- const BIGNUM *priv_val_n = NULL;
- RSA_get0_key(priv, &priv_val_n, &priv_val_e, NULL);
-
- if (pub_val_e == NULL || priv_val_e == NULL) {
- S2N_ERROR(S2N_ERR_KEY_CHECK);
- }
-
- if (pub_val_n == NULL || priv_val_n == NULL) {
- S2N_ERROR(S2N_ERR_KEY_CHECK);
- }
-
- S2N_ERROR_IF(BN_cmp(pub_val_e, priv_val_e) != 0, S2N_ERR_KEY_MISMATCH);
- S2N_ERROR_IF(BN_cmp(pub_val_n, priv_val_n) != 0, S2N_ERR_KEY_MISMATCH);
-
- return 0;
-}
-
-static int s2n_rsa_validate_params_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
-{
- notnull_check(pub);
- notnull_check(priv);
-
- /* OpenSSL Documentation Links:
- * - https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_get0_RSA.html
- * - https://www.openssl.org/docs/manmaster/man3/RSA_get0_key.html
- */
- RSA *pub_rsa_key = pub->key.rsa_key.rsa;
- RSA *priv_rsa_key = priv->key.rsa_key.rsa;
-
- notnull_check(pub_rsa_key);
- notnull_check(priv_rsa_key);
-
- GUARD(s2n_rsa_validate_params_equal(pub_rsa_key, priv_rsa_key));
-
- return 0;
-}
-
-
-static int s2n_rsa_pss_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
-{
- notnull_check(pub);
- notnull_check(pub->pkey);
- notnull_check(priv);
- notnull_check(priv->pkey);
-
- GUARD(s2n_rsa_validate_params_match(pub, priv));
-
- /* Validate that verify(sign(message)) for a random message is verified correctly */
- GUARD(s2n_rsa_pss_validate_sign_verify_match(pub, priv));
-
- return 0;
-}
-
-static int s2n_rsa_pss_key_free(struct s2n_pkey *pkey)
-{
- /* This object does not own the reference to the key --
- * s2n_pkey handles it. */
-
- return 0;
-}
-
-int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey) {
- RSA *pub_rsa_key = EVP_PKEY_get0_RSA(pkey);
-
- S2N_ERROR_IF(s2n_rsa_is_private_key(pub_rsa_key), S2N_ERR_KEY_MISMATCH);
-
- rsa_key->rsa = pub_rsa_key;
- return 0;
-}
-
-int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey)
-{
- RSA *priv_rsa_key = EVP_PKEY_get0_RSA(pkey);
- notnull_check(priv_rsa_key);
-
- /* Documentation: https://www.openssl.org/docs/man1.1.1/man3/RSA_check_key.html */
- S2N_ERROR_IF(!s2n_rsa_is_private_key(priv_rsa_key), S2N_ERR_KEY_MISMATCH);
-
- /* Check that the mandatory properties of a RSA Private Key are valid.
- * - Documentation: https://www.openssl.org/docs/man1.1.1/man3/RSA_check_key.html
- */
- GUARD_OSSL(RSA_check_key(priv_rsa_key), S2N_ERR_KEY_CHECK);
-
- rsa_key->rsa = priv_rsa_key;
- return 0;
-}
-
-int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey)
-{
- GUARD(s2n_rsa_pkey_init(pkey));
-
- pkey->size = &s2n_rsa_pss_size;
- pkey->sign = &s2n_rsa_pss_key_sign;
- pkey->verify = &s2n_rsa_pss_key_verify;
-
- /* RSA PSS only supports Sign and Verify.
- * RSA PSS should never be used for Key Exchange. ECDHE should be used instead since it provides Forward Secrecy. */
- pkey->encrypt = NULL; /* No function for encryption */
- pkey->decrypt = NULL; /* No function for decryption */
-
- pkey->match = &s2n_rsa_pss_keys_match;
- pkey->free = &s2n_rsa_pss_key_free;
-
- return 0;
-}
-
-#else
-
-int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_pss_key, EVP_PKEY *pkey)
-{
- S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED);
-}
-
-int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_pss_key, EVP_PKEY *pkey)
-{
- S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED);
-}
-
-int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey)
-{
- S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED);
-}
-
-#endif
+/*
+ * 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 <openssl/evp.h>
+#include <openssl/rsa.h>
+#include <stdint.h>
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_openssl.h"
+#include "crypto/s2n_rsa.h"
+#include "crypto/s2n_rsa_pss.h"
+#include "crypto/s2n_rsa_signing.h"
+#include "crypto/s2n_pkey.h"
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_random.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+/* Checks whether PSS Certs is supported */
+int s2n_is_rsa_pss_certs_supported()
+{
+ return RSA_PSS_CERTS_SUPPORTED;
+}
+
+#if RSA_PSS_CERTS_SUPPORTED
+
+static int s2n_rsa_pss_size(const struct s2n_pkey *key)
+{
+ notnull_check(key);
+
+ /* For more info, see: https://www.openssl.org/docs/man1.1.0/man3/EVP_PKEY_size.html */
+ return EVP_PKEY_size(key->pkey);
+}
+
+static int s2n_rsa_is_private_key(RSA *rsa_key)
+{
+ const BIGNUM *d = NULL;
+ RSA_get0_key(rsa_key, NULL, NULL, &d);
+
+ if (d != NULL) {
+ return 1;
+ }
+ return 0;
+}
+
+int s2n_rsa_pss_key_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature_out)
+{
+ notnull_check(priv);
+ sig_alg_check(sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
+
+ /* Not Possible to Sign with Public Key */
+ S2N_ERROR_IF(!s2n_rsa_is_private_key(priv->key.rsa_key.rsa), S2N_ERR_KEY_MISMATCH);
+
+ return s2n_rsa_pss_sign(priv, digest, signature_out);
+}
+
+int s2n_rsa_pss_key_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg,
+ struct s2n_hash_state *digest, struct s2n_blob *signature_in)
+{
+ notnull_check(pub);
+ sig_alg_check(sig_alg, S2N_SIGNATURE_RSA_PSS_PSS);
+
+ /* Using Private Key to Verify means the public/private keys were likely swapped, and likely indicates a bug. */
+ S2N_ERROR_IF(s2n_rsa_is_private_key(pub->key.rsa_key.rsa), S2N_ERR_KEY_MISMATCH);
+
+ return s2n_rsa_pss_verify(pub, digest, signature_in);
+}
+
+static int s2n_rsa_pss_validate_sign_verify_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
+{
+ /* Generate a random blob to sign and verify */
+ s2n_stack_blob(random_data, RSA_PSS_SIGN_VERIFY_RANDOM_BLOB_SIZE, RSA_PSS_SIGN_VERIFY_RANDOM_BLOB_SIZE);
+ GUARD_AS_POSIX(s2n_get_private_random_data(&random_data));
+
+ /* Sign/Verify API's only accept Hashes, so hash our Random Data */
+ DEFER_CLEANUP(struct s2n_hash_state sign_hash = {0}, s2n_hash_free);
+ DEFER_CLEANUP(struct s2n_hash_state verify_hash = {0}, s2n_hash_free);
+ GUARD(s2n_hash_new(&sign_hash));
+ GUARD(s2n_hash_new(&verify_hash));
+ GUARD(s2n_hash_init(&sign_hash, S2N_HASH_SHA256));
+ GUARD(s2n_hash_init(&verify_hash, S2N_HASH_SHA256));
+ GUARD(s2n_hash_update(&sign_hash, random_data.data, random_data.size));
+ GUARD(s2n_hash_update(&verify_hash, random_data.data, random_data.size));
+
+ /* Sign and Verify the Hash of the Random Blob */
+ s2n_stack_blob(signature_data, RSA_PSS_SIGN_VERIFY_SIGNATURE_SIZE, RSA_PSS_SIGN_VERIFY_SIGNATURE_SIZE);
+ GUARD(s2n_rsa_pss_key_sign(priv, S2N_SIGNATURE_RSA_PSS_PSS, &sign_hash, &signature_data));
+ GUARD(s2n_rsa_pss_key_verify(pub, S2N_SIGNATURE_RSA_PSS_PSS, &verify_hash, &signature_data));
+
+ return 0;
+}
+
+static int s2n_rsa_validate_params_equal(const RSA *pub, const RSA *priv)
+{
+ const BIGNUM *pub_val_e = NULL;
+ const BIGNUM *pub_val_n = NULL;
+ RSA_get0_key(pub, &pub_val_n, &pub_val_e, NULL);
+
+ const BIGNUM *priv_val_e = NULL;
+ const BIGNUM *priv_val_n = NULL;
+ RSA_get0_key(priv, &priv_val_n, &priv_val_e, NULL);
+
+ if (pub_val_e == NULL || priv_val_e == NULL) {
+ S2N_ERROR(S2N_ERR_KEY_CHECK);
+ }
+
+ if (pub_val_n == NULL || priv_val_n == NULL) {
+ S2N_ERROR(S2N_ERR_KEY_CHECK);
+ }
+
+ S2N_ERROR_IF(BN_cmp(pub_val_e, priv_val_e) != 0, S2N_ERR_KEY_MISMATCH);
+ S2N_ERROR_IF(BN_cmp(pub_val_n, priv_val_n) != 0, S2N_ERR_KEY_MISMATCH);
+
+ return 0;
+}
+
+static int s2n_rsa_validate_params_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
+{
+ notnull_check(pub);
+ notnull_check(priv);
+
+ /* OpenSSL Documentation Links:
+ * - https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_get0_RSA.html
+ * - https://www.openssl.org/docs/manmaster/man3/RSA_get0_key.html
+ */
+ RSA *pub_rsa_key = pub->key.rsa_key.rsa;
+ RSA *priv_rsa_key = priv->key.rsa_key.rsa;
+
+ notnull_check(pub_rsa_key);
+ notnull_check(priv_rsa_key);
+
+ GUARD(s2n_rsa_validate_params_equal(pub_rsa_key, priv_rsa_key));
+
+ return 0;
+}
+
+
+static int s2n_rsa_pss_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv)
+{
+ notnull_check(pub);
+ notnull_check(pub->pkey);
+ notnull_check(priv);
+ notnull_check(priv->pkey);
+
+ GUARD(s2n_rsa_validate_params_match(pub, priv));
+
+ /* Validate that verify(sign(message)) for a random message is verified correctly */
+ GUARD(s2n_rsa_pss_validate_sign_verify_match(pub, priv));
+
+ return 0;
+}
+
+static int s2n_rsa_pss_key_free(struct s2n_pkey *pkey)
+{
+ /* This object does not own the reference to the key --
+ * s2n_pkey handles it. */
+
+ return 0;
+}
+
+int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey) {
+ RSA *pub_rsa_key = EVP_PKEY_get0_RSA(pkey);
+
+ S2N_ERROR_IF(s2n_rsa_is_private_key(pub_rsa_key), S2N_ERR_KEY_MISMATCH);
+
+ rsa_key->rsa = pub_rsa_key;
+ return 0;
+}
+
+int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey)
+{
+ RSA *priv_rsa_key = EVP_PKEY_get0_RSA(pkey);
+ notnull_check(priv_rsa_key);
+
+ /* Documentation: https://www.openssl.org/docs/man1.1.1/man3/RSA_check_key.html */
+ S2N_ERROR_IF(!s2n_rsa_is_private_key(priv_rsa_key), S2N_ERR_KEY_MISMATCH);
+
+ /* Check that the mandatory properties of a RSA Private Key are valid.
+ * - Documentation: https://www.openssl.org/docs/man1.1.1/man3/RSA_check_key.html
+ */
+ GUARD_OSSL(RSA_check_key(priv_rsa_key), S2N_ERR_KEY_CHECK);
+
+ rsa_key->rsa = priv_rsa_key;
+ return 0;
+}
+
+int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey)
+{
+ GUARD(s2n_rsa_pkey_init(pkey));
+
+ pkey->size = &s2n_rsa_pss_size;
+ pkey->sign = &s2n_rsa_pss_key_sign;
+ pkey->verify = &s2n_rsa_pss_key_verify;
+
+ /* RSA PSS only supports Sign and Verify.
+ * RSA PSS should never be used for Key Exchange. ECDHE should be used instead since it provides Forward Secrecy. */
+ pkey->encrypt = NULL; /* No function for encryption */
+ pkey->decrypt = NULL; /* No function for decryption */
+
+ pkey->match = &s2n_rsa_pss_keys_match;
+ pkey->free = &s2n_rsa_pss_key_free;
+
+ return 0;
+}
+
+#else
+
+int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_pss_key, EVP_PKEY *pkey)
+{
+ S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED);
+}
+
+int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_pss_key, EVP_PKEY *pkey)
+{
+ S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED);
+}
+
+int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey)
+{
+ S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED);
+}
+
+#endif
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.h b/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.h
index 70516551fb..6d69e9431d 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.h
@@ -1,45 +1,45 @@
-/*
- * 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 <stdint.h>
-#include <s2n.h>
-
-#include "crypto/s2n_openssl.h"
-#include "crypto/s2n_rsa.h"
-#include "crypto/s2n_rsa_signing.h"
-
-#define RSA_PSS_SIGN_VERIFY_RANDOM_BLOB_SIZE 32
-#define RSA_PSS_SIGN_VERIFY_SIGNATURE_SIZE 256
-
-#ifndef EVP_PKEY_RSA_PSS
-#define EVP_PKEY_RSA_PSS EVP_PKEY_NONE
-#endif
-
-/* OpenSSL 1.1.1d 10 Sep 2019 is broken, so disable on that version. For further info see: crypto/evp/p_lib.c:469
- *
- * This feature requires this Openssl commit for Openssl 1.1.x versions: openssl/openssl@4088b92
- */
-#if RSA_PSS_SIGNING_SUPPORTED && OPENSSL_VERSION_NUMBER > 0x1010104fL
-#define RSA_PSS_CERTS_SUPPORTED 1
-#else
-#define RSA_PSS_CERTS_SUPPORTED 0
-#endif
-
-int s2n_is_rsa_pss_certs_supported();
-int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey);
-int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey);
-int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey);
+/*
+ * 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 <stdint.h>
+#include <s2n.h>
+
+#include "crypto/s2n_openssl.h"
+#include "crypto/s2n_rsa.h"
+#include "crypto/s2n_rsa_signing.h"
+
+#define RSA_PSS_SIGN_VERIFY_RANDOM_BLOB_SIZE 32
+#define RSA_PSS_SIGN_VERIFY_SIGNATURE_SIZE 256
+
+#ifndef EVP_PKEY_RSA_PSS
+#define EVP_PKEY_RSA_PSS EVP_PKEY_NONE
+#endif
+
+/* OpenSSL 1.1.1d 10 Sep 2019 is broken, so disable on that version. For further info see: crypto/evp/p_lib.c:469
+ *
+ * This feature requires this Openssl commit for Openssl 1.1.x versions: openssl/openssl@4088b92
+ */
+#if RSA_PSS_SIGNING_SUPPORTED && OPENSSL_VERSION_NUMBER > 0x1010104fL
+#define RSA_PSS_CERTS_SUPPORTED 1
+#else
+#define RSA_PSS_CERTS_SUPPORTED 0
+#endif
+
+int s2n_is_rsa_pss_certs_supported();
+int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey);
+int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey);
+int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pkey);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c
index 313565380f..3ac4fbf4d0 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c
@@ -1,206 +1,206 @@
-/*
- * 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 <openssl/evp.h>
-#include <openssl/rsa.h>
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_hash.h"
-#include "crypto/s2n_rsa_pss.h"
-#include "crypto/s2n_rsa_signing.h"
-#include "crypto/s2n_pkey.h"
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_safety.h"
-
-static int s2n_hash_alg_to_NID[] = {
- [S2N_HASH_MD5_SHA1] = NID_md5_sha1,
- [S2N_HASH_SHA1] = NID_sha1,
- [S2N_HASH_SHA224] = NID_sha224,
- [S2N_HASH_SHA256] = NID_sha256,
- [S2N_HASH_SHA384] = NID_sha384,
- [S2N_HASH_SHA512] = NID_sha512 };
-
-int s2n_hash_NID_type(s2n_hash_algorithm alg, int *out)
-{
- switch(alg) {
- case S2N_HASH_MD5_SHA1:
- case S2N_HASH_SHA1:
- case S2N_HASH_SHA224:
- case S2N_HASH_SHA256:
- case S2N_HASH_SHA384:
- case S2N_HASH_SHA512:
- *out = s2n_hash_alg_to_NID[alg];
- break;
- default:
- S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
- }
- return 0;
-}
-
-int s2n_rsa_pkcs1v15_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature)
-{
- uint8_t digest_length;
- int NID_type;
- GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
- GUARD(s2n_hash_NID_type(digest->alg, &NID_type));
- lte_check(digest_length, S2N_MAX_DIGEST_LEN);
-
- const s2n_rsa_private_key *key = &priv->key.rsa_key;
-
- uint8_t digest_out[S2N_MAX_DIGEST_LEN];
- GUARD(s2n_hash_digest(digest, digest_out, digest_length));
-
- unsigned int signature_size = signature->size;
- GUARD_OSSL(RSA_sign(NID_type, digest_out, digest_length, signature->data, &signature_size, key->rsa), S2N_ERR_SIGN);
- S2N_ERROR_IF(signature_size > signature->size, S2N_ERR_SIZE_MISMATCH);
- signature->size = signature_size;
-
- return 0;
-}
-
-int s2n_rsa_pkcs1v15_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature)
-{
- uint8_t digest_length;
- int digest_NID_type;
- GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
- GUARD(s2n_hash_NID_type(digest->alg, &digest_NID_type));
- lte_check(digest_length, S2N_MAX_DIGEST_LEN);
-
- const s2n_rsa_public_key *key = &pub->key.rsa_key;
-
- uint8_t digest_out[S2N_MAX_DIGEST_LEN];
- GUARD(s2n_hash_digest(digest, digest_out, digest_length));
-
- GUARD_OSSL(RSA_verify(digest_NID_type, digest_out, digest_length, signature->data, signature->size, key->rsa), S2N_ERR_VERIFY_SIGNATURE);
-
- return 0;
-}
-
-/* this function returns whether RSA PSS signing is supported */
-int s2n_is_rsa_pss_signing_supported()
-{
- return RSA_PSS_SIGNING_SUPPORTED;
-}
-
-#if RSA_PSS_SIGNING_SUPPORTED
-
-const EVP_MD* s2n_hash_alg_to_evp_alg(s2n_hash_algorithm alg)
-{
- switch (alg) {
- case S2N_HASH_MD5_SHA1:
- return EVP_md5_sha1();
- case S2N_HASH_SHA1:
- return EVP_sha1();
- case S2N_HASH_SHA224:
- return EVP_sha224();
- case S2N_HASH_SHA256:
- return EVP_sha256();
- case S2N_HASH_SHA384:
- return EVP_sha384();
- case S2N_HASH_SHA512:
- return EVP_sha512();
- default:
- return NULL;
- }
-}
-
-/* On some versions of OpenSSL, "EVP_PKEY_CTX_set_signature_md()" is just a macro that casts digest_alg to "void*",
- * which fails to compile when the "-Werror=cast-qual" compiler flag is enabled. So we work around this OpenSSL
- * issue by turning off this compiler check for this one function with a cast through. */
-static int s2n_evp_pkey_ctx_set_rsa_signature_digest(EVP_PKEY_CTX *ctx, const EVP_MD* digest_alg)
-{
- GUARD_OSSL(EVP_PKEY_CTX_set_signature_md(ctx,(EVP_MD*) (uintptr_t) digest_alg), S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
- GUARD_OSSL(EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, (EVP_MD*) (uintptr_t) digest_alg), S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
- return 0;
-}
-
-static void s2n_evp_pkey_ctx_free(EVP_PKEY_CTX **ctx)
-{
- EVP_PKEY_CTX_free(*ctx);
-}
-
-int s2n_rsa_pss_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature_out)
-{
- notnull_check(priv);
-
- uint8_t digest_length;
- uint8_t digest_data[S2N_MAX_DIGEST_LEN];
- GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
- GUARD(s2n_hash_digest(digest, digest_data, digest_length));
-
- const EVP_MD* digest_alg = s2n_hash_alg_to_evp_alg(digest->alg);
- notnull_check(digest_alg);
-
- /* For more info see: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_sign.html */
- DEFER_CLEANUP(EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(priv->pkey, NULL), s2n_evp_pkey_ctx_free);
- notnull_check(ctx);
-
- size_t signature_len = signature_out->size;
- GUARD_OSSL(EVP_PKEY_sign_init(ctx), S2N_ERR_SIGN);
- GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_SIGN);
- GUARD(s2n_evp_pkey_ctx_set_rsa_signature_digest(ctx, digest_alg));
- GUARD_OSSL(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_DIGEST), S2N_ERR_SIGN);
-
- /* Calling EVP_PKEY_sign() with NULL will only update the signature_len parameter so users can validate sizes. */
- GUARD_OSSL(EVP_PKEY_sign(ctx, NULL, &signature_len, digest_data, digest_length), S2N_ERR_SIGN);
- S2N_ERROR_IF(signature_len > signature_out->size, S2N_ERR_SIZE_MISMATCH);
-
- /* Actually sign the the digest */
- GUARD_OSSL(EVP_PKEY_sign(ctx, signature_out->data, &signature_len, digest_data, digest_length), S2N_ERR_SIGN);
- signature_out->size = signature_len;
-
- return 0;
-}
-
-int s2n_rsa_pss_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature_in)
-{
- notnull_check(pub);
-
- uint8_t digest_length;
- uint8_t digest_data[S2N_MAX_DIGEST_LEN];
- GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
- GUARD(s2n_hash_digest(digest, digest_data, digest_length));
- const EVP_MD* digest_alg = s2n_hash_alg_to_evp_alg(digest->alg);
- notnull_check(digest_alg);
-
- /* For more info see: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_verify.html */
- DEFER_CLEANUP(EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pub->pkey, NULL), s2n_evp_pkey_ctx_free);
- notnull_check(ctx);
-
- GUARD_OSSL(EVP_PKEY_verify_init(ctx), S2N_ERR_VERIFY_SIGNATURE);
- GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_SIGN);
- GUARD(s2n_evp_pkey_ctx_set_rsa_signature_digest(ctx, digest_alg));
- GUARD_OSSL(EVP_PKEY_verify(ctx, signature_in->data, signature_in->size, digest_data, digest_length), S2N_ERR_VERIFY_SIGNATURE);
-
- return 0;
-}
-
-#else
-
-int s2n_rsa_pss_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature_out)
-{
- S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED);
-}
-
-int s2n_rsa_pss_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature_in)
-{
- S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED);
-}
-
-#endif
+/*
+ * 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 <openssl/evp.h>
+#include <openssl/rsa.h>
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_hash.h"
+#include "crypto/s2n_rsa_pss.h"
+#include "crypto/s2n_rsa_signing.h"
+#include "crypto/s2n_pkey.h"
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_safety.h"
+
+static int s2n_hash_alg_to_NID[] = {
+ [S2N_HASH_MD5_SHA1] = NID_md5_sha1,
+ [S2N_HASH_SHA1] = NID_sha1,
+ [S2N_HASH_SHA224] = NID_sha224,
+ [S2N_HASH_SHA256] = NID_sha256,
+ [S2N_HASH_SHA384] = NID_sha384,
+ [S2N_HASH_SHA512] = NID_sha512 };
+
+int s2n_hash_NID_type(s2n_hash_algorithm alg, int *out)
+{
+ switch(alg) {
+ case S2N_HASH_MD5_SHA1:
+ case S2N_HASH_SHA1:
+ case S2N_HASH_SHA224:
+ case S2N_HASH_SHA256:
+ case S2N_HASH_SHA384:
+ case S2N_HASH_SHA512:
+ *out = s2n_hash_alg_to_NID[alg];
+ break;
+ default:
+ S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM);
+ }
+ return 0;
+}
+
+int s2n_rsa_pkcs1v15_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature)
+{
+ uint8_t digest_length;
+ int NID_type;
+ GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
+ GUARD(s2n_hash_NID_type(digest->alg, &NID_type));
+ lte_check(digest_length, S2N_MAX_DIGEST_LEN);
+
+ const s2n_rsa_private_key *key = &priv->key.rsa_key;
+
+ uint8_t digest_out[S2N_MAX_DIGEST_LEN];
+ GUARD(s2n_hash_digest(digest, digest_out, digest_length));
+
+ unsigned int signature_size = signature->size;
+ GUARD_OSSL(RSA_sign(NID_type, digest_out, digest_length, signature->data, &signature_size, key->rsa), S2N_ERR_SIGN);
+ S2N_ERROR_IF(signature_size > signature->size, S2N_ERR_SIZE_MISMATCH);
+ signature->size = signature_size;
+
+ return 0;
+}
+
+int s2n_rsa_pkcs1v15_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature)
+{
+ uint8_t digest_length;
+ int digest_NID_type;
+ GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
+ GUARD(s2n_hash_NID_type(digest->alg, &digest_NID_type));
+ lte_check(digest_length, S2N_MAX_DIGEST_LEN);
+
+ const s2n_rsa_public_key *key = &pub->key.rsa_key;
+
+ uint8_t digest_out[S2N_MAX_DIGEST_LEN];
+ GUARD(s2n_hash_digest(digest, digest_out, digest_length));
+
+ GUARD_OSSL(RSA_verify(digest_NID_type, digest_out, digest_length, signature->data, signature->size, key->rsa), S2N_ERR_VERIFY_SIGNATURE);
+
+ return 0;
+}
+
+/* this function returns whether RSA PSS signing is supported */
+int s2n_is_rsa_pss_signing_supported()
+{
+ return RSA_PSS_SIGNING_SUPPORTED;
+}
+
+#if RSA_PSS_SIGNING_SUPPORTED
+
+const EVP_MD* s2n_hash_alg_to_evp_alg(s2n_hash_algorithm alg)
+{
+ switch (alg) {
+ case S2N_HASH_MD5_SHA1:
+ return EVP_md5_sha1();
+ case S2N_HASH_SHA1:
+ return EVP_sha1();
+ case S2N_HASH_SHA224:
+ return EVP_sha224();
+ case S2N_HASH_SHA256:
+ return EVP_sha256();
+ case S2N_HASH_SHA384:
+ return EVP_sha384();
+ case S2N_HASH_SHA512:
+ return EVP_sha512();
+ default:
+ return NULL;
+ }
+}
+
+/* On some versions of OpenSSL, "EVP_PKEY_CTX_set_signature_md()" is just a macro that casts digest_alg to "void*",
+ * which fails to compile when the "-Werror=cast-qual" compiler flag is enabled. So we work around this OpenSSL
+ * issue by turning off this compiler check for this one function with a cast through. */
+static int s2n_evp_pkey_ctx_set_rsa_signature_digest(EVP_PKEY_CTX *ctx, const EVP_MD* digest_alg)
+{
+ GUARD_OSSL(EVP_PKEY_CTX_set_signature_md(ctx,(EVP_MD*) (uintptr_t) digest_alg), S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
+ GUARD_OSSL(EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, (EVP_MD*) (uintptr_t) digest_alg), S2N_ERR_INVALID_SIGNATURE_ALGORITHM);
+ return 0;
+}
+
+static void s2n_evp_pkey_ctx_free(EVP_PKEY_CTX **ctx)
+{
+ EVP_PKEY_CTX_free(*ctx);
+}
+
+int s2n_rsa_pss_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature_out)
+{
+ notnull_check(priv);
+
+ uint8_t digest_length;
+ uint8_t digest_data[S2N_MAX_DIGEST_LEN];
+ GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
+ GUARD(s2n_hash_digest(digest, digest_data, digest_length));
+
+ const EVP_MD* digest_alg = s2n_hash_alg_to_evp_alg(digest->alg);
+ notnull_check(digest_alg);
+
+ /* For more info see: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_sign.html */
+ DEFER_CLEANUP(EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(priv->pkey, NULL), s2n_evp_pkey_ctx_free);
+ notnull_check(ctx);
+
+ size_t signature_len = signature_out->size;
+ GUARD_OSSL(EVP_PKEY_sign_init(ctx), S2N_ERR_SIGN);
+ GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_SIGN);
+ GUARD(s2n_evp_pkey_ctx_set_rsa_signature_digest(ctx, digest_alg));
+ GUARD_OSSL(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_DIGEST), S2N_ERR_SIGN);
+
+ /* Calling EVP_PKEY_sign() with NULL will only update the signature_len parameter so users can validate sizes. */
+ GUARD_OSSL(EVP_PKEY_sign(ctx, NULL, &signature_len, digest_data, digest_length), S2N_ERR_SIGN);
+ S2N_ERROR_IF(signature_len > signature_out->size, S2N_ERR_SIZE_MISMATCH);
+
+ /* Actually sign the the digest */
+ GUARD_OSSL(EVP_PKEY_sign(ctx, signature_out->data, &signature_len, digest_data, digest_length), S2N_ERR_SIGN);
+ signature_out->size = signature_len;
+
+ return 0;
+}
+
+int s2n_rsa_pss_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature_in)
+{
+ notnull_check(pub);
+
+ uint8_t digest_length;
+ uint8_t digest_data[S2N_MAX_DIGEST_LEN];
+ GUARD(s2n_hash_digest_size(digest->alg, &digest_length));
+ GUARD(s2n_hash_digest(digest, digest_data, digest_length));
+ const EVP_MD* digest_alg = s2n_hash_alg_to_evp_alg(digest->alg);
+ notnull_check(digest_alg);
+
+ /* For more info see: https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_verify.html */
+ DEFER_CLEANUP(EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(pub->pkey, NULL), s2n_evp_pkey_ctx_free);
+ notnull_check(ctx);
+
+ GUARD_OSSL(EVP_PKEY_verify_init(ctx), S2N_ERR_VERIFY_SIGNATURE);
+ GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_SIGN);
+ GUARD(s2n_evp_pkey_ctx_set_rsa_signature_digest(ctx, digest_alg));
+ GUARD_OSSL(EVP_PKEY_verify(ctx, signature_in->data, signature_in->size, digest_data, digest_length), S2N_ERR_VERIFY_SIGNATURE);
+
+ return 0;
+}
+
+#else
+
+int s2n_rsa_pss_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature_out)
+{
+ S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED);
+}
+
+int s2n_rsa_pss_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature_in)
+{
+ S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED);
+}
+
+#endif
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.h b/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.h
index 6013768a96..94c33dfa24 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.h
@@ -1,37 +1,37 @@
-/*
- * 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 <s2n.h>
-
-#include "utils/s2n_blob.h"
-#include "crypto/s2n_openssl.h"
-#include "crypto/s2n_rsa.h"
-
-/* Check for libcrypto 1.1 for RSA PSS Signing and EV_Key usage */
-#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 1) && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
-#define RSA_PSS_SIGNING_SUPPORTED 1
-#else
-#define RSA_PSS_SIGNING_SUPPORTED 0
-#endif
-
-int s2n_rsa_pkcs1v15_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature);
-int s2n_rsa_pkcs1v15_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature);
-
-int s2n_rsa_pss_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature_out);
-int s2n_rsa_pss_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature_in);
-
-int s2n_is_rsa_pss_signing_supported();
+/*
+ * 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 <s2n.h>
+
+#include "utils/s2n_blob.h"
+#include "crypto/s2n_openssl.h"
+#include "crypto/s2n_rsa.h"
+
+/* Check for libcrypto 1.1 for RSA PSS Signing and EV_Key usage */
+#if S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 1) && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_IS_AWSLC)
+#define RSA_PSS_SIGNING_SUPPORTED 1
+#else
+#define RSA_PSS_SIGNING_SUPPORTED 0
+#endif
+
+int s2n_rsa_pkcs1v15_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature);
+int s2n_rsa_pkcs1v15_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature);
+
+int s2n_rsa_pss_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature_out);
+int s2n_rsa_pss_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature_in);
+
+int s2n_is_rsa_pss_signing_supported();
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_sequence.c b/contrib/restricted/aws/s2n/crypto/s2n_sequence.c
index 2211653817..1deac1b522 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_sequence.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_sequence.c
@@ -1,58 +1,58 @@
-/*
- * 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 "crypto/s2n_sequence.h"
-
-#include "tls/s2n_crypto.h"
-
-#include "error/s2n_errno.h"
-
-#include "utils/s2n_blob.h"
-
-#define SEQUENCE_NUMBER_POWER 8
-
-int s2n_increment_sequence_number(struct s2n_blob *sequence_number)
-{
- for (int i = sequence_number->size - 1; i >= 0; i--) {
- sequence_number->data[i] += 1;
- if (sequence_number->data[i]) {
- break;
- }
-
- /* RFC 5246 6.1: If a TLS implementation would need to wrap a sequence number, it must
- * renegotiate instead. We don't support renegotiation. Caller needs to create a new session.
- * This condition is very unlikely. It requires 2^64 - 1 records to be sent.
- */
- S2N_ERROR_IF(i == 0, S2N_ERR_RECORD_LIMIT);
-
- /* seq[i] wrapped, so let it carry */
- }
-
- return 0;
-}
-
-int s2n_sequence_number_to_uint64(struct s2n_blob *sequence_number, uint64_t *output)
-{
- notnull_check(sequence_number);
-
- uint8_t shift = 0;
- *output = 0;
-
- for (int i = sequence_number->size - 1; i >= 0; i--) {
- *output += ((uint64_t) sequence_number->data[i]) << shift;
- shift += SEQUENCE_NUMBER_POWER;
- }
- return S2N_SUCCESS;
-}
+/*
+ * 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 "crypto/s2n_sequence.h"
+
+#include "tls/s2n_crypto.h"
+
+#include "error/s2n_errno.h"
+
+#include "utils/s2n_blob.h"
+
+#define SEQUENCE_NUMBER_POWER 8
+
+int s2n_increment_sequence_number(struct s2n_blob *sequence_number)
+{
+ for (int i = sequence_number->size - 1; i >= 0; i--) {
+ sequence_number->data[i] += 1;
+ if (sequence_number->data[i]) {
+ break;
+ }
+
+ /* RFC 5246 6.1: If a TLS implementation would need to wrap a sequence number, it must
+ * renegotiate instead. We don't support renegotiation. Caller needs to create a new session.
+ * This condition is very unlikely. It requires 2^64 - 1 records to be sent.
+ */
+ S2N_ERROR_IF(i == 0, S2N_ERR_RECORD_LIMIT);
+
+ /* seq[i] wrapped, so let it carry */
+ }
+
+ return 0;
+}
+
+int s2n_sequence_number_to_uint64(struct s2n_blob *sequence_number, uint64_t *output)
+{
+ notnull_check(sequence_number);
+
+ uint8_t shift = 0;
+ *output = 0;
+
+ for (int i = sequence_number->size - 1; i >= 0; i--) {
+ *output += ((uint64_t) sequence_number->data[i]) << shift;
+ shift += SEQUENCE_NUMBER_POWER;
+ }
+ return S2N_SUCCESS;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_sequence.h b/contrib/restricted/aws/s2n/crypto/s2n_sequence.h
index 6fd824458a..c91e4d8783 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_sequence.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_sequence.h
@@ -1,23 +1,23 @@
-/*
- * 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 "crypto/s2n_sequence.h"
-
-#include "utils/s2n_blob.h"
-
-extern int s2n_increment_sequence_number(struct s2n_blob *sequence_number);
-int s2n_sequence_number_to_uint64(struct s2n_blob *sequence_number, uint64_t *output);
+/*
+ * 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 "crypto/s2n_sequence.h"
+
+#include "utils/s2n_blob.h"
+
+extern int s2n_increment_sequence_number(struct s2n_blob *sequence_number);
+int s2n_sequence_number_to_uint64(struct s2n_blob *sequence_number, uint64_t *output);
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_signature.h b/contrib/restricted/aws/s2n/crypto/s2n_signature.h
index 0206578a5a..0a5d2c5d37 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_signature.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_signature.h
@@ -1,29 +1,29 @@
-/* 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 "tls/s2n_tls_parameters.h"
-
-#define sig_alg_check(a, b) do { if ( (a) != (b) ) { S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM); } } while(0)
-
-typedef enum {
- S2N_SIGNATURE_ANONYMOUS = TLS_SIGNATURE_ALGORITHM_ANONYMOUS,
- S2N_SIGNATURE_RSA = TLS_SIGNATURE_ALGORITHM_RSA,
- S2N_SIGNATURE_ECDSA = TLS_SIGNATURE_ALGORITHM_ECDSA,
-
- /* Use Private Range for RSA PSS */
- S2N_SIGNATURE_RSA_PSS_RSAE = TLS_SIGNATURE_ALGORITHM_PRIVATE,
- S2N_SIGNATURE_RSA_PSS_PSS
-} s2n_signature_algorithm;
+/* 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 "tls/s2n_tls_parameters.h"
+
+#define sig_alg_check(a, b) do { if ( (a) != (b) ) { S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM); } } while(0)
+
+typedef enum {
+ S2N_SIGNATURE_ANONYMOUS = TLS_SIGNATURE_ALGORITHM_ANONYMOUS,
+ S2N_SIGNATURE_RSA = TLS_SIGNATURE_ALGORITHM_RSA,
+ S2N_SIGNATURE_ECDSA = TLS_SIGNATURE_ALGORITHM_ECDSA,
+
+ /* Use Private Range for RSA PSS */
+ S2N_SIGNATURE_RSA_PSS_RSAE = TLS_SIGNATURE_ALGORITHM_PRIVATE,
+ S2N_SIGNATURE_RSA_PSS_PSS
+} s2n_signature_algorithm;
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_null.c b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_null.c
index ef09ea0a0f..8922a1c9e0 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_null.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_null.c
@@ -1,64 +1,64 @@
-/*
- * 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 "error/s2n_errno.h"
-
-#include "crypto/s2n_cipher.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-static uint8_t s2n_stream_cipher_null_available()
-{
- return 1;
-}
-
-static int s2n_stream_cipher_null_endecrypt(struct s2n_session_key *key, struct s2n_blob *in, struct s2n_blob *out)
-{
- S2N_ERROR_IF(out->size < in->size, S2N_ERR_SIZE_MISMATCH);
-
- if (in->data != out->data) {
- memcpy_check(out->data, in->data, out->size);
- }
- return 0;
-}
-
-static int s2n_stream_cipher_null_get_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- return 0;
-}
-
-static int s2n_stream_cipher_null_destroy_key(struct s2n_session_key *key)
-{
- return 0;
-}
-
-static int s2n_stream_cipher_null_init(struct s2n_session_key *key)
-{
- return 0;
-}
-
-struct s2n_cipher s2n_null_cipher = {
- .type = S2N_STREAM,
- .key_material_size = 0,
- .io.stream = {
- .decrypt = s2n_stream_cipher_null_endecrypt,
- .encrypt = s2n_stream_cipher_null_endecrypt},
- .is_available = s2n_stream_cipher_null_available,
- .init = s2n_stream_cipher_null_init,
- .set_encryption_key = s2n_stream_cipher_null_get_key,
- .set_decryption_key = s2n_stream_cipher_null_get_key,
- .destroy_key = s2n_stream_cipher_null_destroy_key,
-};
+/*
+ * 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 "error/s2n_errno.h"
+
+#include "crypto/s2n_cipher.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+static uint8_t s2n_stream_cipher_null_available()
+{
+ return 1;
+}
+
+static int s2n_stream_cipher_null_endecrypt(struct s2n_session_key *key, struct s2n_blob *in, struct s2n_blob *out)
+{
+ S2N_ERROR_IF(out->size < in->size, S2N_ERR_SIZE_MISMATCH);
+
+ if (in->data != out->data) {
+ memcpy_check(out->data, in->data, out->size);
+ }
+ return 0;
+}
+
+static int s2n_stream_cipher_null_get_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ return 0;
+}
+
+static int s2n_stream_cipher_null_destroy_key(struct s2n_session_key *key)
+{
+ return 0;
+}
+
+static int s2n_stream_cipher_null_init(struct s2n_session_key *key)
+{
+ return 0;
+}
+
+struct s2n_cipher s2n_null_cipher = {
+ .type = S2N_STREAM,
+ .key_material_size = 0,
+ .io.stream = {
+ .decrypt = s2n_stream_cipher_null_endecrypt,
+ .encrypt = s2n_stream_cipher_null_endecrypt},
+ .is_available = s2n_stream_cipher_null_available,
+ .init = s2n_stream_cipher_null_init,
+ .set_encryption_key = s2n_stream_cipher_null_get_key,
+ .set_decryption_key = s2n_stream_cipher_null_get_key,
+ .destroy_key = s2n_stream_cipher_null_destroy_key,
+};
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 78c5ea3d8b..8177af6d75 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c
@@ -1,94 +1,94 @@
-/*
- * 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 <openssl/rc4.h>
-
-#include "crypto/s2n_cipher.h"
-#include "crypto/s2n_openssl.h"
-
-#include "utils/s2n_safety.h"
-#include "utils/s2n_blob.h"
-
-static uint8_t s2n_stream_cipher_rc4_available()
-{
- return (EVP_rc4() ? 1 : 0);
-}
-
-static int s2n_stream_cipher_rc4_encrypt(struct s2n_session_key *key, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(out->size, in->size);
-
- int len = out->size;
- GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
-
- S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
-
- return 0;
-}
-
-static int s2n_stream_cipher_rc4_decrypt(struct s2n_session_key *key, struct s2n_blob *in, struct s2n_blob *out)
-{
- gte_check(out->size, in->size);
-
- int len = out->size;
- GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
-
- S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
-
- return 0;
-}
-
-static int s2n_stream_cipher_rc4_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 16);
- GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_rc4(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_stream_cipher_rc4_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
-{
- eq_check(in->size, 16);
- GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_rc4(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
-
- return 0;
-}
-
-static int s2n_stream_cipher_rc4_init(struct s2n_session_key *key)
-{
- s2n_evp_ctx_init(key->evp_cipher_ctx);
-
- return 0;
-}
-
-static int s2n_stream_cipher_rc4_destroy_key(struct s2n_session_key *key)
-{
- EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
-
- return 0;
-}
-
-struct s2n_cipher s2n_rc4 = {
- .type = S2N_STREAM,
- .key_material_size = 16,
- .io.stream = {
- .decrypt = s2n_stream_cipher_rc4_decrypt,
- .encrypt = s2n_stream_cipher_rc4_encrypt},
- .is_available = s2n_stream_cipher_rc4_available,
- .init = s2n_stream_cipher_rc4_init,
- .set_decryption_key = s2n_stream_cipher_rc4_set_decryption_key,
- .set_encryption_key = s2n_stream_cipher_rc4_set_encryption_key,
- .destroy_key = s2n_stream_cipher_rc4_destroy_key,
-};
+/*
+ * 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 <openssl/rc4.h>
+
+#include "crypto/s2n_cipher.h"
+#include "crypto/s2n_openssl.h"
+
+#include "utils/s2n_safety.h"
+#include "utils/s2n_blob.h"
+
+static uint8_t s2n_stream_cipher_rc4_available()
+{
+ return (EVP_rc4() ? 1 : 0);
+}
+
+static int s2n_stream_cipher_rc4_encrypt(struct s2n_session_key *key, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(out->size, in->size);
+
+ int len = out->size;
+ GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
+
+ S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
+
+ return 0;
+}
+
+static int s2n_stream_cipher_rc4_decrypt(struct s2n_session_key *key, struct s2n_blob *in, struct s2n_blob *out)
+{
+ gte_check(out->size, in->size);
+
+ int len = out->size;
+ GUARD_OSSL(EVP_DecryptUpdate(key->evp_cipher_ctx, out->data, &len, in->data, in->size), S2N_ERR_ENCRYPT);
+
+ S2N_ERROR_IF(len != in->size, S2N_ERR_ENCRYPT);
+
+ return 0;
+}
+
+static int s2n_stream_cipher_rc4_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 16);
+ GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_rc4(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_stream_cipher_rc4_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in)
+{
+ eq_check(in->size, 16);
+ GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_rc4(), NULL, in->data, NULL), S2N_ERR_KEY_INIT);
+
+ return 0;
+}
+
+static int s2n_stream_cipher_rc4_init(struct s2n_session_key *key)
+{
+ s2n_evp_ctx_init(key->evp_cipher_ctx);
+
+ return 0;
+}
+
+static int s2n_stream_cipher_rc4_destroy_key(struct s2n_session_key *key)
+{
+ EVP_CIPHER_CTX_cleanup(key->evp_cipher_ctx);
+
+ return 0;
+}
+
+struct s2n_cipher s2n_rc4 = {
+ .type = S2N_STREAM,
+ .key_material_size = 16,
+ .io.stream = {
+ .decrypt = s2n_stream_cipher_rc4_decrypt,
+ .encrypt = s2n_stream_cipher_rc4_encrypt},
+ .is_available = s2n_stream_cipher_rc4_available,
+ .init = s2n_stream_cipher_rc4_init,
+ .set_decryption_key = s2n_stream_cipher_rc4_set_decryption_key,
+ .set_encryption_key = s2n_stream_cipher_rc4_set_encryption_key,
+ .destroy_key = s2n_stream_cipher_rc4_destroy_key,
+};
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c
index 978ce2431e..b0e814ce55 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c
+++ b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c
@@ -1,338 +1,338 @@
-/*
- * 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 <stdio.h>
-
-#include "error/s2n_errno.h"
-
-#include "stuffer/s2n_stuffer.h"
-
-#include "crypto/s2n_hmac.h"
-#include "crypto/s2n_hkdf.h"
-#include "crypto/s2n_tls13_keys.h"
-
-#include "utils/s2n_blob.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_safety.h"
-
-/*
- * There are 9 keys that can be generated by the end of a TLS 1.3 handshake.
- * We currently support the following, more will be supported
- * when the relevant TLS 1.3 features are worked on.
- *
- * [x] binder_key
- * [ ] client_early_traffic_secret
- * [ ] early_exporter_master_secret
- * [x] client_handshake_traffic_secret
- * [x] server_handshake_traffic_secret
- * [x] client_application_traffic_secret_0
- * [x] server_application_traffic_secret_0
- * [ ] exporter_master_secret
- * [ ] resumption_master_secret
- *
- * The TLS 1.3 key generation can be divided into 3 phases
- * 1. early secrets
- * 2. handshake secrets
- * 3. master secrets
- *
- * In each phase, secrets are first extracted with HKDF-Extract that takes in
- * both an ikm (input keying material) and a salt. Some keys can be derived/expanded
- * from the extract before a "tls13 derived" Derive-Secret is used to
- * derive the input salt for the next phase.
- */
-
-/*
- * Define TLS 1.3 HKDF labels as specified in
- * https://tools.ietf.org/html/rfc8446#section-7.1
- */
-S2N_BLOB_LABEL(s2n_tls13_label_derived_secret, "derived")
-
-S2N_BLOB_LABEL(s2n_tls13_label_external_psk_binder_key, "ext binder")
-S2N_BLOB_LABEL(s2n_tls13_label_resumption_psk_binder_key, "res binder")
-
-S2N_BLOB_LABEL(s2n_tls13_label_client_early_traffic_secret, "c e traffic")
-S2N_BLOB_LABEL(s2n_tls13_label_early_exporter_master_secret, "e exp master")
-
-S2N_BLOB_LABEL(s2n_tls13_label_client_handshake_traffic_secret, "c hs traffic")
-S2N_BLOB_LABEL(s2n_tls13_label_server_handshake_traffic_secret, "s hs traffic")
-
-S2N_BLOB_LABEL(s2n_tls13_label_client_application_traffic_secret, "c ap traffic")
-S2N_BLOB_LABEL(s2n_tls13_label_server_application_traffic_secret, "s ap traffic")
-
-S2N_BLOB_LABEL(s2n_tls13_label_exporter_master_secret, "exp master")
-S2N_BLOB_LABEL(s2n_tls13_label_resumption_master_secret, "res master")
-
-/*
- * Traffic secret labels
- */
-S2N_BLOB_LABEL(s2n_tls13_label_traffic_secret_key, "key")
-S2N_BLOB_LABEL(s2n_tls13_label_traffic_secret_iv, "iv")
-
-/*
- * TLS 1.3 Finished label
- */
-S2N_BLOB_LABEL(s2n_tls13_label_finished, "finished")
-
-/*
- * TLS 1.3 KeyUpdate label
- */
-S2N_BLOB_LABEL(s2n_tls13_label_application_traffic_secret_update, "traffic upd")
-
-static const struct s2n_blob zero_length_blob = { .data = NULL, .size = 0 };
-
-/* Message transcript hash based on selected HMAC algorithm */
-static int s2n_tls13_transcript_message_hash(struct s2n_tls13_keys *keys, const struct s2n_blob *message, struct s2n_blob *message_digest)
-{
- notnull_check(keys);
- notnull_check(message);
- notnull_check(message_digest);
-
- DEFER_CLEANUP(struct s2n_hash_state hash_state, s2n_hash_free);
- GUARD(s2n_hash_new(&hash_state));
- GUARD(s2n_hash_init(&hash_state, keys->hash_algorithm));
- GUARD(s2n_hash_update(&hash_state, message->data, message->size));
- GUARD(s2n_hash_digest(&hash_state, message_digest->data, message_digest->size));
-
- return 0;
-}
-
-/*
- * Initializes the tls13_keys struct
- */
-int s2n_tls13_keys_init(struct s2n_tls13_keys *keys, s2n_hmac_algorithm alg)
-{
- notnull_check(keys);
-
- keys->hmac_algorithm = alg;
- GUARD(s2n_hmac_hash_alg(alg, &keys->hash_algorithm));
- GUARD(s2n_hash_digest_size(keys->hash_algorithm, &keys->size));
- GUARD(s2n_blob_init(&keys->extract_secret, keys->extract_secret_bytes, keys->size));
- GUARD(s2n_blob_init(&keys->derive_secret, keys->derive_secret_bytes, keys->size));
- GUARD(s2n_hmac_new(&keys->hmac));
-
- return 0;
-}
-
-/*
- * Frees any allocation
- */
-int s2n_tls13_keys_free(struct s2n_tls13_keys *keys) {
- notnull_check(keys);
-
- GUARD(s2n_hmac_free(&keys->hmac));
-
- return 0;
-}
-
-/*
- * Derives binder_key from PSK.
- */
-int s2n_tls13_derive_binder_key(struct s2n_tls13_keys *keys, struct s2n_psk *psk)
-{
- notnull_check(keys);
- notnull_check(psk);
-
- struct s2n_blob *early_secret = &keys->extract_secret;
- struct s2n_blob *binder_key = &keys->derive_secret;
-
- /* Extract the early secret */
- GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, &zero_length_blob,
- &psk->secret, early_secret));
-
- /* Choose the correct label for the psk type */
- const struct s2n_blob *label_blob;
- if (psk->type == S2N_PSK_TYPE_EXTERNAL) {
- label_blob = &s2n_tls13_label_external_psk_binder_key;
- } else {
- label_blob = &s2n_tls13_label_resumption_psk_binder_key;
- }
-
- /* Derive the binder_key */
- s2n_tls13_key_blob(message_digest, keys->size);
- GUARD(s2n_tls13_transcript_message_hash(keys, &zero_length_blob, &message_digest));
- GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, early_secret,
- label_blob, &message_digest, binder_key));
-
- return S2N_SUCCESS;
-}
-
-/*
- * Derives early secrets
- */
-int s2n_tls13_derive_early_secrets(struct s2n_tls13_keys *keys)
-{
- notnull_check(keys);
-
- s2n_tls13_key_blob(psk_ikm, keys->size); /* in 1-RTT, PSK is 0-filled of key length */
-
- /* Early Secret */
- GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, &zero_length_blob, &psk_ikm, &keys->extract_secret));
-
- /* client_early_traffic_secret and early_exporter_master_secret can be derived here */
-
- /* derive next secret */
- s2n_tls13_key_blob(message_digest, keys->size);
- GUARD(s2n_tls13_transcript_message_hash(keys, &zero_length_blob, &message_digest));
- GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret,
- &s2n_tls13_label_derived_secret, &message_digest, &keys->derive_secret));
-
- return 0;
-}
-
-/*
- * Derives handshake secrets
- */
-int s2n_tls13_derive_handshake_secrets(struct s2n_tls13_keys *keys,
- const struct s2n_blob *ecdhe,
- struct s2n_hash_state *client_server_hello_hash,
- struct s2n_blob *client_secret,
- struct s2n_blob *server_secret)
-{
- notnull_check(keys);
- notnull_check(ecdhe);
- notnull_check(client_server_hello_hash);
- notnull_check(client_secret);
- notnull_check(server_secret);
-
- /* Handshake Secret */
- GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, &keys->derive_secret, ecdhe, &keys->extract_secret));
-
- s2n_tls13_key_blob(message_digest, keys->size);
-
- /* copy the hash */
- DEFER_CLEANUP(struct s2n_hash_state hkdf_hash_copy, s2n_hash_free);
- GUARD(s2n_hash_new(&hkdf_hash_copy));
- GUARD(s2n_hash_copy(&hkdf_hash_copy, client_server_hello_hash));
- s2n_hash_digest(&hkdf_hash_copy, message_digest.data, message_digest.size);
-
- /* produce client + server traffic secrets */
- GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret,
- &s2n_tls13_label_client_handshake_traffic_secret, &message_digest, client_secret));
- GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret,
- &s2n_tls13_label_server_handshake_traffic_secret, &message_digest, server_secret));
-
- /* derive next secret */
- GUARD(s2n_tls13_transcript_message_hash(keys, &zero_length_blob, &message_digest));
- GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret,
- &s2n_tls13_label_derived_secret, &message_digest, &keys->derive_secret));
-
- return 0;
-}
-
-int s2n_tls13_extract_master_secret(struct s2n_tls13_keys *keys)
-{
- s2n_tls13_key_blob(empty_key, keys->size);
-
- /* Extract master secret from derived secret */
- GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, &keys->derive_secret, &empty_key, &keys->extract_secret));
-
- return S2N_SUCCESS;
-}
-
-int s2n_tls13_derive_application_secret(struct s2n_tls13_keys *keys, struct s2n_hash_state *hashes, struct s2n_blob *secret_blob, s2n_mode mode)
-{
- notnull_check(keys);
- notnull_check(hashes);
- notnull_check(secret_blob);
-
- const struct s2n_blob *label_blob;
- if (mode == S2N_CLIENT) {
- label_blob = &s2n_tls13_label_client_application_traffic_secret;
- } else {
- label_blob = &s2n_tls13_label_server_application_traffic_secret;
- }
-
- /* Sanity check that input hash is of expected type */
- S2N_ERROR_IF(keys->hash_algorithm != hashes->alg, S2N_ERR_HASH_INVALID_ALGORITHM);
-
- s2n_tls13_key_blob(message_digest, keys->size);
-
- /* copy the hashes into the message_digest */
- DEFER_CLEANUP(struct s2n_hash_state hkdf_hash_copy, s2n_hash_free);
- GUARD(s2n_hash_new(&hkdf_hash_copy));
- GUARD(s2n_hash_copy(&hkdf_hash_copy, hashes));
- GUARD(s2n_hash_digest(&hkdf_hash_copy, message_digest.data, message_digest.size));
-
- /* Derive traffic secret from master secret */
- GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret,
- label_blob, &message_digest, secret_blob));
-
- return S2N_SUCCESS;
-}
-
-/*
- * Derive Traffic Key and IV based on input secret
- */
-int s2n_tls13_derive_traffic_keys(struct s2n_tls13_keys *keys, struct s2n_blob *secret, struct s2n_blob *key, struct s2n_blob *iv)
-{
- notnull_check(keys);
- notnull_check(secret);
- notnull_check(key);
- notnull_check(iv);
-
- GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret,
- &s2n_tls13_label_traffic_secret_key, &zero_length_blob, key));
- GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret,
- &s2n_tls13_label_traffic_secret_iv, &zero_length_blob, iv));
- return 0;
-}
-
-/*
- * Generate finished key for compute finished hashes/MACs
- * https://tools.ietf.org/html/rfc8446#section-4.4.4
- */
-int s2n_tls13_derive_finished_key(struct s2n_tls13_keys *keys, struct s2n_blob *secret_key, struct s2n_blob *output_finish_key)
-{
- GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret_key, &s2n_tls13_label_finished, &zero_length_blob, output_finish_key));
-
- return 0;
-}
-
-/*
- * Compute finished verify data using HMAC
- * with a finished key and hash state
- * https://tools.ietf.org/html/rfc8446#section-4.4.4
- */
-int s2n_tls13_calculate_finished_mac(struct s2n_tls13_keys *keys, struct s2n_blob *finished_key, struct s2n_hash_state *hash_state, struct s2n_blob *finished_verify)
-{
- /* Set up a blob to contain hash */
- s2n_tls13_key_blob(transcript_hash, keys->size);
-
- /* Make a copy of the hash state */
- DEFER_CLEANUP(struct s2n_hash_state hash_state_copy, s2n_hash_free);
- GUARD(s2n_hash_new(&hash_state_copy));
- GUARD(s2n_hash_copy(&hash_state_copy, hash_state));
- GUARD(s2n_hash_digest(&hash_state_copy, transcript_hash.data, transcript_hash.size));
-
- GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, finished_key, &transcript_hash, finished_verify));
-
- return 0;
-}
-
-/*
- * Derives next generation of traffic secret
- */
-int s2n_tls13_update_application_traffic_secret(struct s2n_tls13_keys *keys, struct s2n_blob *old_secret, struct s2n_blob *new_secret)
-{
- notnull_check(keys);
- notnull_check(old_secret);
- notnull_check(new_secret);
-
- GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, old_secret,
- &s2n_tls13_label_application_traffic_secret_update, &zero_length_blob, new_secret));
-
- return 0;
-}
+/*
+ * 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 <stdio.h>
+
+#include "error/s2n_errno.h"
+
+#include "stuffer/s2n_stuffer.h"
+
+#include "crypto/s2n_hmac.h"
+#include "crypto/s2n_hkdf.h"
+#include "crypto/s2n_tls13_keys.h"
+
+#include "utils/s2n_blob.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_safety.h"
+
+/*
+ * There are 9 keys that can be generated by the end of a TLS 1.3 handshake.
+ * We currently support the following, more will be supported
+ * when the relevant TLS 1.3 features are worked on.
+ *
+ * [x] binder_key
+ * [ ] client_early_traffic_secret
+ * [ ] early_exporter_master_secret
+ * [x] client_handshake_traffic_secret
+ * [x] server_handshake_traffic_secret
+ * [x] client_application_traffic_secret_0
+ * [x] server_application_traffic_secret_0
+ * [ ] exporter_master_secret
+ * [ ] resumption_master_secret
+ *
+ * The TLS 1.3 key generation can be divided into 3 phases
+ * 1. early secrets
+ * 2. handshake secrets
+ * 3. master secrets
+ *
+ * In each phase, secrets are first extracted with HKDF-Extract that takes in
+ * both an ikm (input keying material) and a salt. Some keys can be derived/expanded
+ * from the extract before a "tls13 derived" Derive-Secret is used to
+ * derive the input salt for the next phase.
+ */
+
+/*
+ * Define TLS 1.3 HKDF labels as specified in
+ * https://tools.ietf.org/html/rfc8446#section-7.1
+ */
+S2N_BLOB_LABEL(s2n_tls13_label_derived_secret, "derived")
+
+S2N_BLOB_LABEL(s2n_tls13_label_external_psk_binder_key, "ext binder")
+S2N_BLOB_LABEL(s2n_tls13_label_resumption_psk_binder_key, "res binder")
+
+S2N_BLOB_LABEL(s2n_tls13_label_client_early_traffic_secret, "c e traffic")
+S2N_BLOB_LABEL(s2n_tls13_label_early_exporter_master_secret, "e exp master")
+
+S2N_BLOB_LABEL(s2n_tls13_label_client_handshake_traffic_secret, "c hs traffic")
+S2N_BLOB_LABEL(s2n_tls13_label_server_handshake_traffic_secret, "s hs traffic")
+
+S2N_BLOB_LABEL(s2n_tls13_label_client_application_traffic_secret, "c ap traffic")
+S2N_BLOB_LABEL(s2n_tls13_label_server_application_traffic_secret, "s ap traffic")
+
+S2N_BLOB_LABEL(s2n_tls13_label_exporter_master_secret, "exp master")
+S2N_BLOB_LABEL(s2n_tls13_label_resumption_master_secret, "res master")
+
+/*
+ * Traffic secret labels
+ */
+S2N_BLOB_LABEL(s2n_tls13_label_traffic_secret_key, "key")
+S2N_BLOB_LABEL(s2n_tls13_label_traffic_secret_iv, "iv")
+
+/*
+ * TLS 1.3 Finished label
+ */
+S2N_BLOB_LABEL(s2n_tls13_label_finished, "finished")
+
+/*
+ * TLS 1.3 KeyUpdate label
+ */
+S2N_BLOB_LABEL(s2n_tls13_label_application_traffic_secret_update, "traffic upd")
+
+static const struct s2n_blob zero_length_blob = { .data = NULL, .size = 0 };
+
+/* Message transcript hash based on selected HMAC algorithm */
+static int s2n_tls13_transcript_message_hash(struct s2n_tls13_keys *keys, const struct s2n_blob *message, struct s2n_blob *message_digest)
+{
+ notnull_check(keys);
+ notnull_check(message);
+ notnull_check(message_digest);
+
+ DEFER_CLEANUP(struct s2n_hash_state hash_state, s2n_hash_free);
+ GUARD(s2n_hash_new(&hash_state));
+ GUARD(s2n_hash_init(&hash_state, keys->hash_algorithm));
+ GUARD(s2n_hash_update(&hash_state, message->data, message->size));
+ GUARD(s2n_hash_digest(&hash_state, message_digest->data, message_digest->size));
+
+ return 0;
+}
+
+/*
+ * Initializes the tls13_keys struct
+ */
+int s2n_tls13_keys_init(struct s2n_tls13_keys *keys, s2n_hmac_algorithm alg)
+{
+ notnull_check(keys);
+
+ keys->hmac_algorithm = alg;
+ GUARD(s2n_hmac_hash_alg(alg, &keys->hash_algorithm));
+ GUARD(s2n_hash_digest_size(keys->hash_algorithm, &keys->size));
+ GUARD(s2n_blob_init(&keys->extract_secret, keys->extract_secret_bytes, keys->size));
+ GUARD(s2n_blob_init(&keys->derive_secret, keys->derive_secret_bytes, keys->size));
+ GUARD(s2n_hmac_new(&keys->hmac));
+
+ return 0;
+}
+
+/*
+ * Frees any allocation
+ */
+int s2n_tls13_keys_free(struct s2n_tls13_keys *keys) {
+ notnull_check(keys);
+
+ GUARD(s2n_hmac_free(&keys->hmac));
+
+ return 0;
+}
+
+/*
+ * Derives binder_key from PSK.
+ */
+int s2n_tls13_derive_binder_key(struct s2n_tls13_keys *keys, struct s2n_psk *psk)
+{
+ notnull_check(keys);
+ notnull_check(psk);
+
+ struct s2n_blob *early_secret = &keys->extract_secret;
+ struct s2n_blob *binder_key = &keys->derive_secret;
+
+ /* Extract the early secret */
+ GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, &zero_length_blob,
+ &psk->secret, early_secret));
+
+ /* Choose the correct label for the psk type */
+ const struct s2n_blob *label_blob;
+ if (psk->type == S2N_PSK_TYPE_EXTERNAL) {
+ label_blob = &s2n_tls13_label_external_psk_binder_key;
+ } else {
+ label_blob = &s2n_tls13_label_resumption_psk_binder_key;
+ }
+
+ /* Derive the binder_key */
+ s2n_tls13_key_blob(message_digest, keys->size);
+ GUARD(s2n_tls13_transcript_message_hash(keys, &zero_length_blob, &message_digest));
+ GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, early_secret,
+ label_blob, &message_digest, binder_key));
+
+ return S2N_SUCCESS;
+}
+
+/*
+ * Derives early secrets
+ */
+int s2n_tls13_derive_early_secrets(struct s2n_tls13_keys *keys)
+{
+ notnull_check(keys);
+
+ s2n_tls13_key_blob(psk_ikm, keys->size); /* in 1-RTT, PSK is 0-filled of key length */
+
+ /* Early Secret */
+ GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, &zero_length_blob, &psk_ikm, &keys->extract_secret));
+
+ /* client_early_traffic_secret and early_exporter_master_secret can be derived here */
+
+ /* derive next secret */
+ s2n_tls13_key_blob(message_digest, keys->size);
+ GUARD(s2n_tls13_transcript_message_hash(keys, &zero_length_blob, &message_digest));
+ GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret,
+ &s2n_tls13_label_derived_secret, &message_digest, &keys->derive_secret));
+
+ return 0;
+}
+
+/*
+ * Derives handshake secrets
+ */
+int s2n_tls13_derive_handshake_secrets(struct s2n_tls13_keys *keys,
+ const struct s2n_blob *ecdhe,
+ struct s2n_hash_state *client_server_hello_hash,
+ struct s2n_blob *client_secret,
+ struct s2n_blob *server_secret)
+{
+ notnull_check(keys);
+ notnull_check(ecdhe);
+ notnull_check(client_server_hello_hash);
+ notnull_check(client_secret);
+ notnull_check(server_secret);
+
+ /* Handshake Secret */
+ GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, &keys->derive_secret, ecdhe, &keys->extract_secret));
+
+ s2n_tls13_key_blob(message_digest, keys->size);
+
+ /* copy the hash */
+ DEFER_CLEANUP(struct s2n_hash_state hkdf_hash_copy, s2n_hash_free);
+ GUARD(s2n_hash_new(&hkdf_hash_copy));
+ GUARD(s2n_hash_copy(&hkdf_hash_copy, client_server_hello_hash));
+ s2n_hash_digest(&hkdf_hash_copy, message_digest.data, message_digest.size);
+
+ /* produce client + server traffic secrets */
+ GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret,
+ &s2n_tls13_label_client_handshake_traffic_secret, &message_digest, client_secret));
+ GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret,
+ &s2n_tls13_label_server_handshake_traffic_secret, &message_digest, server_secret));
+
+ /* derive next secret */
+ GUARD(s2n_tls13_transcript_message_hash(keys, &zero_length_blob, &message_digest));
+ GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret,
+ &s2n_tls13_label_derived_secret, &message_digest, &keys->derive_secret));
+
+ return 0;
+}
+
+int s2n_tls13_extract_master_secret(struct s2n_tls13_keys *keys)
+{
+ s2n_tls13_key_blob(empty_key, keys->size);
+
+ /* Extract master secret from derived secret */
+ GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, &keys->derive_secret, &empty_key, &keys->extract_secret));
+
+ return S2N_SUCCESS;
+}
+
+int s2n_tls13_derive_application_secret(struct s2n_tls13_keys *keys, struct s2n_hash_state *hashes, struct s2n_blob *secret_blob, s2n_mode mode)
+{
+ notnull_check(keys);
+ notnull_check(hashes);
+ notnull_check(secret_blob);
+
+ const struct s2n_blob *label_blob;
+ if (mode == S2N_CLIENT) {
+ label_blob = &s2n_tls13_label_client_application_traffic_secret;
+ } else {
+ label_blob = &s2n_tls13_label_server_application_traffic_secret;
+ }
+
+ /* Sanity check that input hash is of expected type */
+ S2N_ERROR_IF(keys->hash_algorithm != hashes->alg, S2N_ERR_HASH_INVALID_ALGORITHM);
+
+ s2n_tls13_key_blob(message_digest, keys->size);
+
+ /* copy the hashes into the message_digest */
+ DEFER_CLEANUP(struct s2n_hash_state hkdf_hash_copy, s2n_hash_free);
+ GUARD(s2n_hash_new(&hkdf_hash_copy));
+ GUARD(s2n_hash_copy(&hkdf_hash_copy, hashes));
+ GUARD(s2n_hash_digest(&hkdf_hash_copy, message_digest.data, message_digest.size));
+
+ /* Derive traffic secret from master secret */
+ GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret,
+ label_blob, &message_digest, secret_blob));
+
+ return S2N_SUCCESS;
+}
+
+/*
+ * Derive Traffic Key and IV based on input secret
+ */
+int s2n_tls13_derive_traffic_keys(struct s2n_tls13_keys *keys, struct s2n_blob *secret, struct s2n_blob *key, struct s2n_blob *iv)
+{
+ notnull_check(keys);
+ notnull_check(secret);
+ notnull_check(key);
+ notnull_check(iv);
+
+ GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret,
+ &s2n_tls13_label_traffic_secret_key, &zero_length_blob, key));
+ GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret,
+ &s2n_tls13_label_traffic_secret_iv, &zero_length_blob, iv));
+ return 0;
+}
+
+/*
+ * Generate finished key for compute finished hashes/MACs
+ * https://tools.ietf.org/html/rfc8446#section-4.4.4
+ */
+int s2n_tls13_derive_finished_key(struct s2n_tls13_keys *keys, struct s2n_blob *secret_key, struct s2n_blob *output_finish_key)
+{
+ GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret_key, &s2n_tls13_label_finished, &zero_length_blob, output_finish_key));
+
+ return 0;
+}
+
+/*
+ * Compute finished verify data using HMAC
+ * with a finished key and hash state
+ * https://tools.ietf.org/html/rfc8446#section-4.4.4
+ */
+int s2n_tls13_calculate_finished_mac(struct s2n_tls13_keys *keys, struct s2n_blob *finished_key, struct s2n_hash_state *hash_state, struct s2n_blob *finished_verify)
+{
+ /* Set up a blob to contain hash */
+ s2n_tls13_key_blob(transcript_hash, keys->size);
+
+ /* Make a copy of the hash state */
+ DEFER_CLEANUP(struct s2n_hash_state hash_state_copy, s2n_hash_free);
+ GUARD(s2n_hash_new(&hash_state_copy));
+ GUARD(s2n_hash_copy(&hash_state_copy, hash_state));
+ GUARD(s2n_hash_digest(&hash_state_copy, transcript_hash.data, transcript_hash.size));
+
+ GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, finished_key, &transcript_hash, finished_verify));
+
+ return 0;
+}
+
+/*
+ * Derives next generation of traffic secret
+ */
+int s2n_tls13_update_application_traffic_secret(struct s2n_tls13_keys *keys, struct s2n_blob *old_secret, struct s2n_blob *new_secret)
+{
+ notnull_check(keys);
+ notnull_check(old_secret);
+ notnull_check(new_secret);
+
+ GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, old_secret,
+ &s2n_tls13_label_application_traffic_secret_update, &zero_length_blob, new_secret));
+
+ return 0;
+}
diff --git a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h
index c572f6edfd..19631c8aa8 100644
--- a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h
+++ b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h
@@ -1,89 +1,89 @@
-/*
- * 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 <stdint.h>
-
-#include "crypto/s2n_hmac.h"
-#include "crypto/s2n_hkdf.h"
-#include "stuffer/s2n_stuffer.h"
-#include "tls/s2n_tls_parameters.h"
-#include "tls/s2n_psk.h"
-#include "utils/s2n_blob.h"
-#include "utils/s2n_safety.h"
-#include "utils/s2n_mem.h"
-#include "utils/s2n_safety.h"
-
-#define S2N_TLS13_SECRET_MAX_LEN SHA384_DIGEST_LENGTH
-
-struct s2n_tls13_keys {
- s2n_hmac_algorithm hmac_algorithm;
- s2n_hash_algorithm hash_algorithm;
-
- uint8_t size;
-
- /* we only need to keep these 2 rolling secrets at any point,
- * since other secrets to be used can be generated from these
- */
- struct s2n_blob extract_secret;
- struct s2n_blob derive_secret;
- uint8_t extract_secret_bytes[S2N_TLS13_SECRET_MAX_LEN];
- uint8_t derive_secret_bytes[S2N_TLS13_SECRET_MAX_LEN];
-
- struct s2n_hmac_state hmac;
-};
-
-/* Defines TLS 1.3 HKDF Labels */
-extern const struct s2n_blob s2n_tls13_label_derived_secret;
-extern const struct s2n_blob s2n_tls13_label_external_psk_binder_key;
-extern const struct s2n_blob s2n_tls13_label_resumption_psk_binder_key;
-
-extern const struct s2n_blob s2n_tls13_label_client_early_traffic_secret;
-extern const struct s2n_blob s2n_tls13_label_early_exporter_master_secret;
-
-extern const struct s2n_blob s2n_tls13_label_client_handshake_traffic_secret;
-extern const struct s2n_blob s2n_tls13_label_server_handshake_traffic_secret;
-
-extern const struct s2n_blob s2n_tls13_label_client_application_traffic_secret;
-extern const struct s2n_blob s2n_tls13_label_server_application_traffic_secret;
-
-extern const struct s2n_blob s2n_tls13_label_exporter_master_secret;
-extern const struct s2n_blob s2n_tls13_label_resumption_master_secret;
-
-/* Traffic secret labels */
-
-extern const struct s2n_blob s2n_tls13_label_traffic_secret_key;
-extern const struct s2n_blob s2n_tls13_label_traffic_secret_iv;
-
-#define s2n_tls13_key_blob(name, bytes) \
- s2n_stack_blob(name, bytes, S2N_TLS13_SECRET_MAX_LEN)
-
-int s2n_tls13_keys_init(struct s2n_tls13_keys *handshake, s2n_hmac_algorithm alg);
-int s2n_tls13_keys_free(struct s2n_tls13_keys *keys);
-int s2n_tls13_derive_binder_key(struct s2n_tls13_keys *keys, struct s2n_psk *psk);
-int s2n_tls13_derive_early_secrets(struct s2n_tls13_keys *handshake);
-int s2n_tls13_derive_handshake_secrets(struct s2n_tls13_keys *handshake,
- const struct s2n_blob *ecdhe,
- struct s2n_hash_state *client_server_hello_hash,
- struct s2n_blob *client_secret,
- struct s2n_blob *server_secret);
-int s2n_tls13_extract_master_secret(struct s2n_tls13_keys *handshake);
-int s2n_tls13_derive_application_secret(struct s2n_tls13_keys *handshake, struct s2n_hash_state *hashes, struct s2n_blob *secret_blob, s2n_mode mode);
-
-int s2n_tls13_derive_traffic_keys(struct s2n_tls13_keys *handshake, struct s2n_blob *secret, struct s2n_blob *key, struct s2n_blob *iv);
-int s2n_tls13_derive_finished_key(struct s2n_tls13_keys *keys, struct s2n_blob *secret_key, struct s2n_blob *output_finish_key);
-int s2n_tls13_calculate_finished_mac(struct s2n_tls13_keys *keys, struct s2n_blob *finished_key, struct s2n_hash_state *hash_state, struct s2n_blob *finished_verify);
-int s2n_tls13_update_application_traffic_secret(struct s2n_tls13_keys *keys, struct s2n_blob *old_secret, struct s2n_blob *new_secret);
+/*
+ * 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 <stdint.h>
+
+#include "crypto/s2n_hmac.h"
+#include "crypto/s2n_hkdf.h"
+#include "stuffer/s2n_stuffer.h"
+#include "tls/s2n_tls_parameters.h"
+#include "tls/s2n_psk.h"
+#include "utils/s2n_blob.h"
+#include "utils/s2n_safety.h"
+#include "utils/s2n_mem.h"
+#include "utils/s2n_safety.h"
+
+#define S2N_TLS13_SECRET_MAX_LEN SHA384_DIGEST_LENGTH
+
+struct s2n_tls13_keys {
+ s2n_hmac_algorithm hmac_algorithm;
+ s2n_hash_algorithm hash_algorithm;
+
+ uint8_t size;
+
+ /* we only need to keep these 2 rolling secrets at any point,
+ * since other secrets to be used can be generated from these
+ */
+ struct s2n_blob extract_secret;
+ struct s2n_blob derive_secret;
+ uint8_t extract_secret_bytes[S2N_TLS13_SECRET_MAX_LEN];
+ uint8_t derive_secret_bytes[S2N_TLS13_SECRET_MAX_LEN];
+
+ struct s2n_hmac_state hmac;
+};
+
+/* Defines TLS 1.3 HKDF Labels */
+extern const struct s2n_blob s2n_tls13_label_derived_secret;
+extern const struct s2n_blob s2n_tls13_label_external_psk_binder_key;
+extern const struct s2n_blob s2n_tls13_label_resumption_psk_binder_key;
+
+extern const struct s2n_blob s2n_tls13_label_client_early_traffic_secret;
+extern const struct s2n_blob s2n_tls13_label_early_exporter_master_secret;
+
+extern const struct s2n_blob s2n_tls13_label_client_handshake_traffic_secret;
+extern const struct s2n_blob s2n_tls13_label_server_handshake_traffic_secret;
+
+extern const struct s2n_blob s2n_tls13_label_client_application_traffic_secret;
+extern const struct s2n_blob s2n_tls13_label_server_application_traffic_secret;
+
+extern const struct s2n_blob s2n_tls13_label_exporter_master_secret;
+extern const struct s2n_blob s2n_tls13_label_resumption_master_secret;
+
+/* Traffic secret labels */
+
+extern const struct s2n_blob s2n_tls13_label_traffic_secret_key;
+extern const struct s2n_blob s2n_tls13_label_traffic_secret_iv;
+
+#define s2n_tls13_key_blob(name, bytes) \
+ s2n_stack_blob(name, bytes, S2N_TLS13_SECRET_MAX_LEN)
+
+int s2n_tls13_keys_init(struct s2n_tls13_keys *handshake, s2n_hmac_algorithm alg);
+int s2n_tls13_keys_free(struct s2n_tls13_keys *keys);
+int s2n_tls13_derive_binder_key(struct s2n_tls13_keys *keys, struct s2n_psk *psk);
+int s2n_tls13_derive_early_secrets(struct s2n_tls13_keys *handshake);
+int s2n_tls13_derive_handshake_secrets(struct s2n_tls13_keys *handshake,
+ const struct s2n_blob *ecdhe,
+ struct s2n_hash_state *client_server_hello_hash,
+ struct s2n_blob *client_secret,
+ struct s2n_blob *server_secret);
+int s2n_tls13_extract_master_secret(struct s2n_tls13_keys *handshake);
+int s2n_tls13_derive_application_secret(struct s2n_tls13_keys *handshake, struct s2n_hash_state *hashes, struct s2n_blob *secret_blob, s2n_mode mode);
+
+int s2n_tls13_derive_traffic_keys(struct s2n_tls13_keys *handshake, struct s2n_blob *secret, struct s2n_blob *key, struct s2n_blob *iv);
+int s2n_tls13_derive_finished_key(struct s2n_tls13_keys *keys, struct s2n_blob *secret_key, struct s2n_blob *output_finish_key);
+int s2n_tls13_calculate_finished_mac(struct s2n_tls13_keys *keys, struct s2n_blob *finished_key, struct s2n_hash_state *hash_state, struct s2n_blob *finished_verify);
+int s2n_tls13_update_application_traffic_secret(struct s2n_tls13_keys *keys, struct s2n_blob *old_secret, struct s2n_blob *new_secret);