diff options
author | thegeorg <thegeorg@yandex-team.ru> | 2022-05-10 22:16:03 +0300 |
---|---|---|
committer | thegeorg <thegeorg@yandex-team.ru> | 2022-05-10 22:16:03 +0300 |
commit | 09c71d918d4d0b0ebf67e1ab41aa90ddf587a3f2 (patch) | |
tree | dd44d2cb68e2845c2d4c367b66893f3e043a6e8e /contrib/restricted/aws/s2n/crypto | |
parent | 5eb4a8a2d487411924e1d1b27c454223dcf35005 (diff) | |
download | ydb-09c71d918d4d0b0ebf67e1ab41aa90ddf587a3f2.tar.gz |
Update contrib/restricted/aws/s2n to 1.3.12
ref:f8279d764b4c00974a63543a1364c91e2b81b7a6
Diffstat (limited to 'contrib/restricted/aws/s2n/crypto')
43 files changed, 1943 insertions, 1289 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..172736ac1e 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 @@ -49,22 +49,22 @@ static uint8_t s2n_aead_cipher_aes256_gcm_available() 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); + POSIX_ENSURE_REF(in); + POSIX_ENSURE_REF(out); + POSIX_ENSURE_REF(iv); + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_GTE(in->size, S2N_TLS_GCM_TAG_LEN); + POSIX_ENSURE_GTE(out->size, in->size); + POSIX_ENSURE_EQ(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); + POSIX_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); @@ -73,19 +73,19 @@ static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s 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); + POSIX_ENSURE_REF(in); + POSIX_ENSURE_REF(out); + POSIX_ENSURE_REF(iv); + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_GTE(in->size, S2N_TLS_GCM_TAG_LEN); + POSIX_ENSURE_GTE(out->size, in->size - S2N_TLS_GCM_TAG_LEN); + POSIX_ENSURE_EQ(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); + POSIX_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); @@ -94,55 +94,103 @@ static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s 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); + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(in); - eq_check(in->size, S2N_TLS_AES_128_GCM_KEY_LEN); + POSIX_ENSURE_EQ(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); + POSIX_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm_tls12(), 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); + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(in); - eq_check(in->size, S2N_TLS_AES_256_GCM_KEY_LEN); + POSIX_ENSURE_EQ(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); + POSIX_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm_tls12(), 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); + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(in); - eq_check(in->size, S2N_TLS_AES_128_GCM_KEY_LEN); + POSIX_ENSURE_EQ(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); + POSIX_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm_tls12(), 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); + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(in); - eq_check(in->size, S2N_TLS_AES_256_GCM_KEY_LEN); + POSIX_ENSURE_EQ(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); + POSIX_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm_tls12(), 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_encryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in) +{ + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(in); + + POSIX_ENSURE_EQ(in->size, S2N_TLS_AES_128_GCM_KEY_LEN); + + POSIX_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm_tls13(), 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_tls13(struct s2n_session_key *key, struct s2n_blob *in) +{ + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(in); + + POSIX_ENSURE_EQ(in->size, S2N_TLS_AES_256_GCM_KEY_LEN); + + POSIX_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm_tls13(), 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_tls13(struct s2n_session_key *key, struct s2n_blob *in) +{ + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(in); + + POSIX_ENSURE_EQ(in->size, S2N_TLS_AES_128_GCM_KEY_LEN); + + POSIX_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_128_gcm_tls13(), 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_tls13(struct s2n_session_key *key, struct s2n_blob *in) +{ + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(in); + + POSIX_ENSURE_EQ(in->size, S2N_TLS_AES_256_GCM_KEY_LEN); + + POSIX_GUARD_OSSL(EVP_AEAD_CTX_init(key->evp_aead_ctx, EVP_aead_aes_256_gcm_tls13(), 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); + POSIX_ENSURE_REF(key); EVP_AEAD_CTX_zero(key->evp_aead_ctx); @@ -151,7 +199,7 @@ static int s2n_aead_cipher_aes_gcm_init(struct s2n_session_key *key) static int s2n_aead_cipher_aes_gcm_destroy_key(struct s2n_session_key *key) { - notnull_check(key); + POSIX_ENSURE_REF(key); EVP_AEAD_CTX_cleanup(key->evp_aead_ctx); @@ -163,12 +211,12 @@ static int s2n_aead_cipher_aes_gcm_destroy_key(struct s2n_session_key *key) 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); + POSIX_ENSURE_GTE(in->size, S2N_TLS_GCM_TAG_LEN); + POSIX_ENSURE_GTE(out->size, in->size); + POSIX_ENSURE_EQ(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); + POSIX_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; @@ -176,19 +224,19 @@ static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s int out_len; /* Specify the AAD */ - GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_ENCRYPT); + POSIX_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); + POSIX_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); + POSIX_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); + POSIX_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); @@ -198,23 +246,23 @@ static int s2n_aead_cipher_aes_gcm_encrypt(struct s2n_session_key *key, struct s 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); + POSIX_ENSURE_GTE(in->size, S2N_TLS_GCM_TAG_LEN); + POSIX_ENSURE_GTE(out->size, in->size); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_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); + POSIX_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. */ @@ -232,52 +280,80 @@ static int s2n_aead_cipher_aes_gcm_decrypt(struct s2n_session_key *key, struct s 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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_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_aes128_gcm_set_encryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in) +{ + POSIX_GUARD(s2n_aead_cipher_aes128_gcm_set_encryption_key(key, in)); + + return S2N_SUCCESS; +} + +static int s2n_aead_cipher_aes256_gcm_set_encryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in) +{ + POSIX_GUARD(s2n_aead_cipher_aes256_gcm_set_encryption_key(key, in)); + + return S2N_SUCCESS; +} + +static int s2n_aead_cipher_aes128_gcm_set_decryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in) +{ + POSIX_GUARD(s2n_aead_cipher_aes128_gcm_set_decryption_key(key, in)); + + return S2N_SUCCESS; +} + +static int s2n_aead_cipher_aes256_gcm_set_decryption_key_tls13(struct s2n_session_key *key, struct s2n_blob *in) +{ + POSIX_GUARD(s2n_aead_cipher_aes256_gcm_set_decryption_key(key, in)); return S2N_SUCCESS; } @@ -342,8 +418,8 @@ struct s2n_cipher s2n_tls13_aes128_gcm = { .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, + .set_encryption_key = s2n_aead_cipher_aes128_gcm_set_encryption_key_tls13, + .set_decryption_key = s2n_aead_cipher_aes128_gcm_set_decryption_key_tls13, .destroy_key = s2n_aead_cipher_aes_gcm_destroy_key, }; @@ -358,7 +434,7 @@ struct s2n_cipher s2n_tls13_aes256_gcm = { .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, + .set_encryption_key = s2n_aead_cipher_aes256_gcm_set_encryption_key_tls13, + .set_decryption_key = s2n_aead_cipher_aes256_gcm_set_decryption_key_tls13, .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..a4db7815f2 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 @@ -49,13 +49,13 @@ static uint8_t s2n_aead_chacha20_poly1305_available(void) 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); + POSIX_ENSURE_GTE(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); + POSIX_ENSURE_GTE(out->size, in->size); + POSIX_ENSURE_EQ(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); + POSIX_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; @@ -63,19 +63,19 @@ static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struc int out_len; /* Specify the AAD */ - GUARD_OSSL(EVP_EncryptUpdate(key->evp_cipher_ctx, NULL, &out_len, aad->data, aad->size), S2N_ERR_ENCRYPT); + POSIX_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); + POSIX_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); + POSIX_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); + POSIX_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); @@ -85,23 +85,23 @@ static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struc 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); + POSIX_ENSURE_GTE(in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN); + POSIX_ENSURE_GTE(out->size, in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_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); + POSIX_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. */ @@ -119,26 +119,26 @@ static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struc 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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, in->data, NULL), S2N_ERR_KEY_INIT); return 0; } @@ -161,16 +161,16 @@ static int s2n_aead_chacha20_poly1305_destroy_key(struct s2n_session_key *key) 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); + POSIX_ENSURE_GTE(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); + POSIX_ENSURE_GTE(out->size, in->size); + POSIX_ENSURE_EQ(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); + POSIX_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); @@ -179,13 +179,13 @@ static int s2n_aead_chacha20_poly1305_encrypt(struct s2n_session_key *key, struc 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); + POSIX_ENSURE_GTE(in->size, S2N_TLS_CHACHA20_POLY1305_TAG_LEN); + POSIX_ENSURE_GTE(out->size, in->size - S2N_TLS_CHACHA20_POLY1305_TAG_LEN); + POSIX_ENSURE_EQ(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); + POSIX_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); @@ -194,18 +194,18 @@ static int s2n_aead_chacha20_poly1305_decrypt(struct s2n_session_key *key, struc 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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_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; } @@ -228,32 +228,32 @@ static int s2n_aead_chacha20_poly1305_destroy_key(struct s2n_session_key *key) 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); + POSIX_BAIL(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); + POSIX_BAIL(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); + POSIX_BAIL(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); + POSIX_BAIL(S2N_ERR_KEY_INIT); } static int s2n_aead_chacha20_poly1305_init(struct s2n_session_key *key) { - S2N_ERROR(S2N_ERR_KEY_INIT); + POSIX_BAIL(S2N_ERR_KEY_INIT); } static int s2n_aead_chacha20_poly1305_destroy_key(struct s2n_session_key *key) { - S2N_ERROR(S2N_ERR_KEY_DESTROY); + POSIX_BAIL(S2N_ERR_KEY_DESTROY); } #endif 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..9a3e440653 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_3des.c @@ -30,12 +30,12 @@ static uint8_t s2n_cbc_cipher_3des_available() 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); + POSIX_ENSURE_GTE(out->size, in->size); - GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT); + POSIX_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); + POSIX_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; @@ -43,32 +43,32 @@ static int s2n_cbc_cipher_3des_encrypt(struct s2n_session_key *key, struct s2n_b 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); + POSIX_ENSURE_GTE(out->size, in->size); - GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT); + POSIX_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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_des_ede3_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT); return 0; } 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..e737242ff0 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_cbc_cipher_aes.c @@ -35,12 +35,12 @@ static uint8_t s2n_cbc_cipher_aes256_available() 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); + POSIX_ENSURE_GTE(out->size, in->size); - GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT); + POSIX_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); + POSIX_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; @@ -48,52 +48,52 @@ static int s2n_cbc_cipher_aes_encrypt(struct s2n_session_key *key, struct s2n_bl 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); + POSIX_ENSURE_GTE(out->size, in->size); - GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT); + POSIX_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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_aes_256_cbc(), NULL, in->data, NULL), S2N_ERR_KEY_INIT); return 0; } diff --git a/contrib/restricted/aws/s2n/crypto/s2n_certificate.c b/contrib/restricted/aws/s2n/crypto/s2n_certificate.c index 39646c3f28..f1a71a0332 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_certificate.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_certificate.c @@ -17,13 +17,14 @@ # define _GNU_SOURCE #endif -#include <s2n.h> +#include "api/s2n.h" #include <openssl/x509v3.h> #include <openssl/pem.h> #include <string.h> #include <strings.h> #include "crypto/s2n_certificate.h" +#include "crypto/s2n_openssl_x509.h" #include "utils/s2n_array.h" #include "utils/s2n_safety.h" #include "utils/s2n_mem.h" @@ -33,16 +34,16 @@ int s2n_cert_set_cert_type(struct s2n_cert *cert, s2n_pkey_type pkey_type) { - notnull_check(cert); + POSIX_ENSURE_REF(cert); cert->pkey_type = pkey_type; - GUARD(s2n_pkey_setup_for_type(&cert->public_key, pkey_type)); + POSIX_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)); + POSIX_GUARD(s2n_stuffer_growable_alloc(&cert_out_stuffer, 2048)); struct s2n_cert **insert = &cert_chain_out->head; uint32_t chain_size = 0; @@ -51,20 +52,20 @@ int s2n_create_cert_chain_from_stuffer(struct s2n_cert_chain *cert_chain_out, st 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); + POSIX_BAIL(S2N_ERR_NO_CERTIFICATE_IN_PEM); } break; } struct s2n_blob mem = {0}; - GUARD(s2n_alloc(&mem, sizeof(struct s2n_cert))); + POSIX_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)); + POSIX_GUARD(s2n_free(&mem)); S2N_ERROR_PRESERVE_ERRNO(); } if (s2n_stuffer_read(&cert_out_stuffer, &new_node->raw) != S2N_SUCCESS) { - GUARD(s2n_free(&mem)); + POSIX_GUARD(s2n_free(&mem)); S2N_ERROR_PRESERVE_ERRNO(); } @@ -91,61 +92,93 @@ int s2n_cert_chain_and_key_set_cert_chain_from_stuffer(struct s2n_cert_chain_and return s2n_create_cert_chain_from_stuffer(cert_and_key->cert_chain, chain_in_stuffer); } +int s2n_cert_chain_and_key_set_cert_chain_bytes(struct s2n_cert_chain_and_key *cert_and_key, uint8_t *cert_chain_pem, uint32_t cert_chain_len) +{ + DEFER_CLEANUP(struct s2n_stuffer chain_in_stuffer = {0}, s2n_stuffer_free); + + POSIX_GUARD(s2n_stuffer_init_ro_from_string(&chain_in_stuffer, cert_chain_pem, cert_chain_len)); + POSIX_GUARD(s2n_cert_chain_and_key_set_cert_chain_from_stuffer(cert_and_key, &chain_in_stuffer)); + + return S2N_SUCCESS; +} + 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}; + DEFER_CLEANUP(struct s2n_stuffer chain_in_stuffer = {0}, s2n_stuffer_free); /* 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); + POSIX_GUARD(s2n_stuffer_alloc_ro_from_string(&chain_in_stuffer, cert_chain_pem)); + POSIX_GUARD(s2n_cert_chain_and_key_set_cert_chain_from_stuffer(cert_and_key, &chain_in_stuffer)); - GUARD(s2n_stuffer_free(&chain_in_stuffer)); + return S2N_SUCCESS; +} + +int s2n_cert_chain_and_key_set_private_key_from_stuffer(struct s2n_cert_chain_and_key *cert_and_key, struct s2n_stuffer *key_in_stuffer, struct s2n_stuffer *key_out_stuffer) +{ + struct s2n_blob key_blob = {0}; - return rc; + POSIX_GUARD(s2n_pkey_zero_init(cert_and_key->private_key)); + + /* Convert pem to asn1 and asn1 to the private key. Handles both PKCS#1 and PKCS#8 formats */ + POSIX_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); + POSIX_ENSURE_REF(key_blob.data); + + /* Get key type and create appropriate key context */ + POSIX_GUARD(s2n_asn1der_to_private_key(cert_and_key->private_key, &key_blob)); + + return S2N_SUCCESS; } -int s2n_cert_chain_and_key_set_private_key(struct s2n_cert_chain_and_key *cert_and_key, const char *private_key_pem) +int s2n_cert_chain_and_key_set_private_key_bytes(struct s2n_cert_chain_and_key *cert_and_key, uint8_t *private_key_pem, uint32_t private_key_len) { 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))); + POSIX_GUARD(s2n_stuffer_init_ro_from_string(&key_in_stuffer, private_key_pem, private_key_len)); + POSIX_GUARD(s2n_stuffer_growable_alloc(&key_out_stuffer, private_key_len)); - /* 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); + POSIX_GUARD(s2n_cert_chain_and_key_set_private_key_from_stuffer(cert_and_key, &key_in_stuffer, &key_out_stuffer)); - /* Get key type and create appropriate key context */ - GUARD(s2n_asn1der_to_private_key(cert_and_key->private_key, &key_blob)); + return S2N_SUCCESS; +} - return 0; +int s2n_cert_chain_and_key_set_private_key(struct s2n_cert_chain_and_key *cert_and_key, const char *private_key_pem) +{ + POSIX_ENSURE_REF(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); + + /* Put the private key pem in a stuffer */ + POSIX_GUARD(s2n_stuffer_alloc_ro_from_string(&key_in_stuffer, private_key_pem)); + POSIX_GUARD(s2n_stuffer_growable_alloc(&key_out_stuffer, strlen(private_key_pem))); + + POSIX_GUARD(s2n_cert_chain_and_key_set_private_key_from_stuffer(cert_and_key, &key_in_stuffer, &key_out_stuffer)); + + return S2N_SUCCESS; } 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)); + POSIX_ENSURE_REF(chain_and_key); + POSIX_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); + POSIX_GUARD(s2n_alloc(&chain_and_key->ocsp_status, length)); + POSIX_CHECKED_MEMCPY(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)); + POSIX_ENSURE_REF(chain_and_key); + POSIX_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); + POSIX_GUARD(s2n_alloc(&chain_and_key->sct_list, length)); + POSIX_CHECKED_MEMCPY(chain_and_key->sct_list.data, data, length); } return 0; } @@ -155,7 +188,7 @@ 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))); + PTR_GUARD_POSIX(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 */ @@ -199,7 +232,7 @@ 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); + POSIX_ENSURE_REF(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) { @@ -219,19 +252,19 @@ int s2n_cert_chain_and_key_load_sans(struct s2n_cert_chain_and_key *chain_and_ke 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)); + POSIX_GUARD_RESULT(s2n_array_pushback(chain_and_key->san_names, (void **)&san_blob)); if (!san_blob) { - S2N_ERROR(S2N_ERR_NULL_SANS); + POSIX_BAIL(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); + POSIX_CHECKED_MEMCPY(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)); + POSIX_GUARD(s2n_blob_char_to_lower(san_blob)); } } @@ -251,7 +284,7 @@ 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); + POSIX_ENSURE_REF(chain_and_key->cn_names); X509_NAME *subject = X509_get_subject_name(x509_cert); if (!subject) { @@ -284,18 +317,18 @@ int s2n_cert_chain_and_key_load_cns(struct s2n_cert_chain_and_key *chain_and_key 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)); + POSIX_GUARD_RESULT(s2n_array_pushback(chain_and_key->cn_names, (void **)&cn_name)); if (cn_name == NULL) { - S2N_ERROR(S2N_ERR_NULL_CN_NAME); + POSIX_BAIL(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); + POSIX_CHECKED_MEMCPY(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)); + POSIX_GUARD(s2n_blob_char_to_lower(cn_name)); } } @@ -307,41 +340,92 @@ static int s2n_cert_chain_and_key_set_names(struct s2n_cert_chain_and_key *chain 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); + POSIX_BAIL(S2N_ERR_INVALID_PEM); } - GUARD(s2n_cert_chain_and_key_load_sans(chain_and_key, cert)); + POSIX_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)); + POSIX_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) +int s2n_cert_chain_and_key_load(struct s2n_cert_chain_and_key *chain_and_key) { - 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)); + POSIX_ENSURE_REF(chain_and_key); + POSIX_ENSURE_REF(chain_and_key->cert_chain); + POSIX_ENSURE_REF(chain_and_key->cert_chain->head); + POSIX_ENSURE_REF(chain_and_key->private_key); + struct s2n_cert *head = chain_and_key->cert_chain->head; /* 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)); + POSIX_GUARD(s2n_asn1der_to_public_key_and_type(&public_key, &pkey_type, &head->raw)); + POSIX_ENSURE(pkey_type != S2N_PKEY_TYPE_UNKNOWN, S2N_ERR_CERT_TYPE_UNSUPPORTED); + POSIX_GUARD(s2n_cert_set_cert_type(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)); + if (s2n_pkey_check_key_exists(chain_and_key->private_key) == S2N_SUCCESS) { + POSIX_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)); + POSIX_GUARD(s2n_cert_chain_and_key_set_names(chain_and_key, &head->raw)); + + /* Populate ec curve libcrypto nid */ + if (pkey_type == S2N_PKEY_TYPE_ECDSA) { + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(public_key.key.ecdsa_key.ec_key)); + POSIX_ENSURE(nid > 0, S2N_ERR_CERT_TYPE_UNSUPPORTED); + POSIX_ENSURE(nid < UINT16_MAX, S2N_ERR_CERT_TYPE_UNSUPPORTED); + head->ec_curve_nid = nid; + } - return 0; + return S2N_SUCCESS; +} + +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) +{ + POSIX_ENSURE_REF(chain_and_key); + + POSIX_GUARD(s2n_cert_chain_and_key_set_cert_chain(chain_and_key, chain_pem)); + POSIX_GUARD(s2n_cert_chain_and_key_set_private_key(chain_and_key, private_key_pem)); + + POSIX_GUARD(s2n_cert_chain_and_key_load(chain_and_key)); + + return S2N_SUCCESS; +} + +int s2n_cert_chain_and_key_load_public_pem_bytes(struct s2n_cert_chain_and_key *chain_and_key, uint8_t *chain_pem, uint32_t chain_pem_len) +{ + POSIX_GUARD(s2n_cert_chain_and_key_set_cert_chain_bytes(chain_and_key, chain_pem, chain_pem_len)); + POSIX_GUARD(s2n_cert_chain_and_key_load(chain_and_key)); + return S2N_SUCCESS; +} + +int s2n_cert_chain_and_key_load_pem_bytes(struct s2n_cert_chain_and_key *chain_and_key, uint8_t *chain_pem, + uint32_t chain_pem_len, uint8_t *private_key_pem, uint32_t private_key_pem_len) +{ + POSIX_ENSURE_REF(chain_and_key); + + POSIX_GUARD(s2n_cert_chain_and_key_set_cert_chain_bytes(chain_and_key, chain_pem, chain_pem_len)); + POSIX_GUARD(s2n_cert_chain_and_key_set_private_key_bytes(chain_and_key, private_key_pem, private_key_pem_len)); + + POSIX_GUARD(s2n_cert_chain_and_key_load(chain_and_key)); + + return S2N_SUCCESS; +} + +S2N_CLEANUP_RESULT s2n_cert_chain_and_key_ptr_free(struct s2n_cert_chain_and_key **cert_and_key) +{ + RESULT_ENSURE_REF(cert_and_key); + RESULT_GUARD_POSIX(s2n_cert_chain_and_key_free(*cert_and_key)); + *cert_and_key = NULL; + return S2N_RESULT_OK; } int s2n_cert_chain_and_key_free(struct s2n_cert_chain_and_key *cert_and_key) @@ -355,72 +439,91 @@ int s2n_cert_chain_and_key_free(struct s2n_cert_chain_and_key *cert_and_key) struct s2n_cert *node = cert_and_key->cert_chain->head; while (node) { /* Free the cert */ - GUARD(s2n_free(&node->raw)); + POSIX_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))); + POSIX_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))); + POSIX_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))); + POSIX_GUARD(s2n_pkey_free(cert_and_key->private_key)); + POSIX_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)); + POSIX_GUARD_RESULT(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)); + POSIX_GUARD_RESULT(s2n_array_get(cert_and_key->san_names, i, (void **)&san_name)); + POSIX_GUARD(s2n_free(san_name)); } - GUARD_AS_POSIX(s2n_array_free(cert_and_key->san_names)); + POSIX_GUARD_RESULT(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)); + POSIX_GUARD_RESULT(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)); + POSIX_GUARD_RESULT(s2n_array_get(cert_and_key->cn_names, i, (void **)&cn_name)); + POSIX_GUARD(s2n_free(cn_name)); } - GUARD_AS_POSIX(s2n_array_free(cert_and_key->cn_names)); + POSIX_GUARD_RESULT(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)); + POSIX_GUARD(s2n_free(&cert_and_key->ocsp_status)); + POSIX_GUARD(s2n_free(&cert_and_key->sct_list)); - GUARD(s2n_free_object((uint8_t **)&cert_and_key, sizeof(struct s2n_cert_chain_and_key))); + POSIX_GUARD(s2n_free_object((uint8_t **)&cert_and_key, sizeof(struct s2n_cert_chain_and_key))); return 0; } +int s2n_cert_chain_free(struct s2n_cert_chain *cert_chain) +{ + /* Walk the chain and free the certs/nodes allocated prior to failure */ + if (cert_chain) { + struct s2n_cert *node = cert_chain->head; + while (node) { + /* Free the cert */ + POSIX_GUARD(s2n_free(&node->raw)); + /* update head so it won't point to freed memory */ + cert_chain->head = node->next; + /* Free the node */ + POSIX_GUARD(s2n_free_object((uint8_t **)&node, sizeof(struct s2n_cert))); + node = cert_chain->head; + } + } + + return S2N_SUCCESS; +} + 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); + POSIX_ENSURE_REF(conn); + POSIX_ENSURE_REF(out); + POSIX_ENSURE_REF(chain_and_key); struct s2n_cert_chain *chain = chain_and_key->cert_chain; - notnull_check(chain); + POSIX_ENSURE_REF(chain); struct s2n_cert *cur_cert = chain->head; - notnull_check(cur_cert); + POSIX_ENSURE_REF(cur_cert); struct s2n_stuffer_reservation cert_chain_size = {0}; - GUARD(s2n_stuffer_reserve_uint24(out, &cert_chain_size)); + POSIX_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)); + POSIX_ENSURE_REF(cur_cert); + POSIX_GUARD(s2n_stuffer_write_uint24(out, cur_cert->raw.size)); + POSIX_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 @@ -429,39 +532,39 @@ int s2n_send_cert_chain(struct s2n_connection *conn, struct s2n_stuffer *out, st * 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)); + POSIX_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)); + POSIX_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)); + POSIX_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)); + POSIX_ENSURE_REF(out); + POSIX_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); + POSIX_ENSURE_REF(chain_and_key); + POSIX_ENSURE_REF(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)); + POSIX_GUARD_RESULT(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); + POSIX_GUARD_RESULT(s2n_array_get(san_names, i, (void **)&san_name)); + POSIX_ENSURE_REF(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; } @@ -472,16 +575,16 @@ static int s2n_does_cert_san_match_hostname(const struct s2n_cert_chain_and_key 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); + POSIX_ENSURE_REF(chain_and_key); + POSIX_ENSURE_REF(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)); + POSIX_GUARD_RESULT(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); + POSIX_GUARD_RESULT(s2n_array_get(cn_names, i, (void **)&cn_name)); + POSIX_ENSURE_REF(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; } @@ -493,7 +596,7 @@ static int s2n_does_cert_cn_match_hostname(const struct s2n_cert_chain_and_key * 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)); + POSIX_GUARD_RESULT(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; @@ -524,11 +627,259 @@ void *s2n_cert_chain_and_key_get_ctx(struct s2n_cert_chain_and_key *cert_and_key s2n_pkey_type s2n_cert_chain_and_key_get_pkey_type(struct s2n_cert_chain_and_key *chain_and_key) { + if (chain_and_key == NULL + || chain_and_key->cert_chain == NULL + || chain_and_key->cert_chain->head == NULL) { + return S2N_PKEY_TYPE_UNKNOWN; + } 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); + PTR_ENSURE_REF(chain_and_key); return chain_and_key->private_key; } + +int s2n_cert_chain_get_length(const struct s2n_cert_chain_and_key *chain_and_key, uint32_t *cert_length) +{ + POSIX_ENSURE_REF(chain_and_key); + POSIX_ENSURE_REF(cert_length); + + struct s2n_cert *head_cert = chain_and_key->cert_chain->head; + POSIX_ENSURE_REF(head_cert); + *cert_length = 1; + struct s2n_cert *next_cert = head_cert->next; + while (next_cert != NULL) { + *cert_length += 1; + next_cert = next_cert->next; + } + + return S2N_SUCCESS; +} + +int s2n_cert_chain_get_cert(const struct s2n_cert_chain_and_key *chain_and_key, struct s2n_cert **out_cert, + const uint32_t cert_idx) +{ + POSIX_ENSURE_REF(chain_and_key); + POSIX_ENSURE_REF(out_cert); + + struct s2n_cert *cur_cert = chain_and_key->cert_chain->head; + POSIX_ENSURE_REF(cur_cert); + uint32_t counter = 0; + + struct s2n_cert *next_cert = cur_cert->next; + + while ((next_cert != NULL) && (counter < cert_idx)) { + cur_cert = next_cert; + next_cert = next_cert->next; + counter++; + } + + POSIX_ENSURE(counter == cert_idx, S2N_ERR_NO_CERT_FOUND); + POSIX_ENSURE(cur_cert != NULL, S2N_ERR_NO_CERT_FOUND); + *out_cert = cur_cert; + + return S2N_SUCCESS; +} + +int s2n_cert_get_der(const struct s2n_cert *cert, const uint8_t **out_cert_der, uint32_t *cert_length) +{ + POSIX_ENSURE_REF(cert); + POSIX_ENSURE_REF(out_cert_der); + POSIX_ENSURE_REF(cert_length); + + *cert_length = cert->raw.size; + *out_cert_der = cert->raw.data; + + return S2N_SUCCESS; +} + +static int s2n_asn1_obj_free(ASN1_OBJECT ** data) +{ + if (*data != NULL) { + ASN1_OBJECT_free(*data); + } + return S2N_SUCCESS; +} + +static int s2n_asn1_string_free(ASN1_STRING** data) +{ + if (*data != NULL) { + ASN1_STRING_free(*data); + } + return S2N_SUCCESS; +} + +static int s2n_utf8_string_from_extension_data(const uint8_t *extension_data, uint32_t extension_len, uint8_t *out_data, uint32_t *out_len) +{ + DEFER_CLEANUP(ASN1_STRING *asn1_str = NULL, s2n_asn1_string_free); + /* Note that d2i_ASN1_UTF8STRING increments *der_in to the byte following the parsed data. + * Using a temporary variable is mandatory to prevent memory free-ing errors. + * Ref to the warning section here for more information: + * https://www.openssl.org/docs/man1.1.0/man3/d2i_ASN1_UTF8STRING.html. + */ + const uint8_t *asn1_str_data = extension_data; + asn1_str = d2i_ASN1_UTF8STRING(NULL, (const unsigned char **)(void *)&asn1_str_data, extension_len); + POSIX_ENSURE(asn1_str != NULL, S2N_ERR_INVALID_X509_EXTENSION_TYPE); + /* ASN1_STRING_type() returns the type of `asn1_str`, using standard constants such as V_ASN1_OCTET_STRING. + * Ref: https://www.openssl.org/docs/man1.1.0/man3/ASN1_STRING_type.html. + */ + int type = ASN1_STRING_type(asn1_str); + POSIX_ENSURE(type == V_ASN1_UTF8STRING, S2N_ERR_INVALID_X509_EXTENSION_TYPE); + + int len = ASN1_STRING_length(asn1_str); + if (out_data != NULL) { + POSIX_ENSURE(*out_len >= len, S2N_ERR_INSUFFICIENT_MEM_SIZE); + /* ASN1_STRING_data() returns an internal pointer to the data. + * Since this is an internal pointer it should not be freed or modified in any way. + * Ref: https://www.openssl.org/docs/man1.0.2/man3/ASN1_STRING_data.html. + */ + unsigned char *internal_data = ASN1_STRING_data(asn1_str); + POSIX_ENSURE_REF(internal_data); + POSIX_CHECKED_MEMCPY(out_data, internal_data, len); + } + *out_len = len; + return S2N_SUCCESS; +} + +int s2n_cert_get_utf8_string_from_extension_data_length(const uint8_t *extension_data, uint32_t extension_len, uint32_t *utf8_str_len) +{ + POSIX_ENSURE_REF(extension_data); + POSIX_ENSURE_GT(extension_len, 0); + POSIX_ENSURE_REF(utf8_str_len); + + POSIX_GUARD(s2n_utf8_string_from_extension_data(extension_data, extension_len, NULL, utf8_str_len)); + + return S2N_SUCCESS; +} + +int s2n_cert_get_utf8_string_from_extension_data(const uint8_t *extension_data, uint32_t extension_len, uint8_t *out_data, uint32_t *out_len) +{ + POSIX_ENSURE_REF(extension_data); + POSIX_ENSURE_GT(extension_len, 0); + POSIX_ENSURE_REF(out_data); + POSIX_ENSURE_REF(out_len); + + POSIX_GUARD(s2n_utf8_string_from_extension_data(extension_data, extension_len, out_data, out_len)); + + return S2N_SUCCESS; +} + +static int s2n_parse_x509_extension(struct s2n_cert *cert, const uint8_t *oid, + uint8_t *ext_value, uint32_t *ext_value_len, bool *critical) +{ + POSIX_ENSURE_REF(cert->raw.data); + /* Obtain the openssl x509 cert from the ASN1 DER certificate input. + * Note that d2i_X509 increments *der_in to the byte following the parsed data. + * Using a temporary variable is mandatory to prevent memory free-ing errors. + * Ref to the warning section here for more information: + * https://www.openssl.org/docs/man1.1.0/man3/d2i_X509.html. + */ + uint8_t *der_in = cert->raw.data; + DEFER_CLEANUP(X509 *x509_cert = d2i_X509(NULL, (const unsigned char **)(void *)&der_in, cert->raw.size), + X509_free_pointer); + POSIX_ENSURE_REF(x509_cert); + + /* Retrieve the number of x509 extensions present in the certificate + * X509_get_ext_count returns the number of extensions in the x509 certificate. + * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_get_ext_count.html. + */ + int ext_count = X509_get_ext_count(x509_cert); + POSIX_ENSURE_GT(ext_count, 0); + + /* OBJ_txt2obj() converts the input text string into an ASN1_OBJECT structure. + * If no_name is 0 then long names and short names will be interpreted as well as numerical forms. + * If no_name is 1 only the numerical form is acceptable. + * Ref: https://www.openssl.org/docs/man1.1.0/man3/OBJ_txt2obj.html. + */ + DEFER_CLEANUP(ASN1_OBJECT *asn1_obj_in = OBJ_txt2obj((const char *)oid, 0), s2n_asn1_obj_free); + POSIX_ENSURE_REF(asn1_obj_in); + + for (size_t loc = 0; loc < ext_count; loc++) { + ASN1_OCTET_STRING *asn1_str = NULL; + bool match_found = false; + + /* Retrieve the x509 extension at location loc. + * X509_get_ext() retrieves extension loc from x. + * The index loc can take any value from 0 to X509_get_ext_count(x) - 1. + * The returned extension is an internal pointer which must not be freed up by the application. + * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_get_ext.html. + */ + X509_EXTENSION *x509_ext = X509_get_ext(x509_cert, loc); + POSIX_ENSURE_REF(x509_ext); + + /* Retrieve the extension object/OID/extnId. + * X509_EXTENSION_get_object() returns the extension type of `x509_ext` as an ASN1_OBJECT pointer. + * The returned pointer is an internal value which must not be freed up. + * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_EXTENSION_get_object.html. + */ + ASN1_OBJECT *asn1_obj = X509_EXTENSION_get_object(x509_ext); + POSIX_ENSURE_REF(asn1_obj); + + /* OBJ_cmp() compares two ASN1_OBJECT objects. If the two are identical 0 is returned. + * Ref: https://www.openssl.org/docs/man1.1.0/man3/OBJ_cmp.html. + */ + match_found = (0 == OBJ_cmp(asn1_obj_in, asn1_obj)); + + /* If match found, retrieve the corresponding OID value for the x509 extension */ + if (match_found) { + /* X509_EXTENSION_get_data() returns the data of extension `x509_ext`. + * The returned pointer is an internal value which must not be freed up. + * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_EXTENSION_get_data.html. + */ + asn1_str = X509_EXTENSION_get_data(x509_ext); + /* ASN1_STRING_length() returns the length of the content of `asn1_str`. + * Ref: https://www.openssl.org/docs/man1.1.0/man3/ASN1_STRING_length.html. + */ + int len = ASN1_STRING_length(asn1_str); + if (ext_value != NULL) { + POSIX_ENSURE(*ext_value_len >= len, S2N_ERR_INSUFFICIENT_MEM_SIZE); + /* ASN1_STRING_data() returns an internal pointer to the data. + * Since this is an internal pointer it should not be freed or modified in any way. + * Ref: https://www.openssl.org/docs/man1.0.2/man3/ASN1_STRING_data.html. + */ + unsigned char *internal_data = ASN1_STRING_data(asn1_str); + POSIX_ENSURE_REF(internal_data); + POSIX_CHECKED_MEMCPY(ext_value, internal_data, len); + } + if (critical != NULL) { + /* Retrieve the x509 extension's critical value. + * X509_EXTENSION_get_critical() returns the criticality of extension `x509_ext`, + * it returns 1 for critical and 0 for non-critical. + * Ref: https://www.openssl.org/docs/man1.1.0/man3/X509_EXTENSION_get_critical.html. + */ + *critical = X509_EXTENSION_get_critical(x509_ext); + } + *ext_value_len = len; + return S2N_SUCCESS; + } + } + + POSIX_BAIL(S2N_ERR_X509_EXTENSION_VALUE_NOT_FOUND); +} + +int s2n_cert_get_x509_extension_value_length(struct s2n_cert *cert, const uint8_t *oid, uint32_t *ext_value_len) +{ + POSIX_ENSURE_REF(cert); + POSIX_ENSURE_REF(oid); + POSIX_ENSURE_REF(ext_value_len); + + POSIX_GUARD(s2n_parse_x509_extension(cert, oid, NULL, ext_value_len, NULL)); + + return S2N_SUCCESS; +} + +int s2n_cert_get_x509_extension_value(struct s2n_cert *cert, const uint8_t *oid, + uint8_t *ext_value, uint32_t *ext_value_len, bool *critical) +{ + POSIX_ENSURE_REF(cert); + POSIX_ENSURE_REF(oid); + POSIX_ENSURE_REF(ext_value); + POSIX_ENSURE_REF(ext_value_len); + POSIX_ENSURE_REF(critical); + + POSIX_GUARD(s2n_parse_x509_extension(cert, oid, ext_value, ext_value_len, critical)); + + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/crypto/s2n_certificate.h b/contrib/restricted/aws/s2n/crypto/s2n_certificate.h index 2395595641..e78601c1ae 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_certificate.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_certificate.h @@ -19,7 +19,7 @@ #include <openssl/x509.h> -#include <s2n.h> +#include "api/s2n.h" #include "crypto/s2n_pkey.h" #include "stuffer/s2n_stuffer.h" @@ -27,6 +27,7 @@ struct s2n_cert { s2n_pkey_type pkey_type; + uint16_t ec_curve_nid; s2n_cert_public_key public_key; struct s2n_blob raw; struct s2n_cert *next; @@ -66,10 +67,21 @@ int s2n_cert_chain_and_key_load_cns(struct s2n_cert_chain_and_key *chain_and_key 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); +S2N_CLEANUP_RESULT s2n_cert_chain_and_key_ptr_free(struct s2n_cert_chain_and_key **cert_and_key); 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_bytes(struct s2n_cert_chain_and_key *cert_and_key, uint8_t *cert_chain_pem, uint32_t cert_chain_len); +int s2n_cert_chain_and_key_set_private_key_bytes(struct s2n_cert_chain_and_key *cert_and_key, uint8_t *private_key_pem, uint32_t private_key_len); 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); +int s2n_cert_chain_get_length(const struct s2n_cert_chain_and_key *chain_and_key, uint32_t *cert_length); +int s2n_cert_chain_get_cert(const struct s2n_cert_chain_and_key *chain_and_key, struct s2n_cert **out_cert, const uint32_t cert_idx); +int s2n_cert_get_der(const struct s2n_cert *cert, const uint8_t **out_cert_der, uint32_t *cert_length); +int s2n_cert_chain_free(struct s2n_cert_chain *cert_chain); +int s2n_cert_get_x509_extension_value_length(struct s2n_cert *cert, const uint8_t *oid, uint32_t *ext_value_len); +int s2n_cert_get_x509_extension_value(struct s2n_cert *cert, const uint8_t *oid, uint8_t *ext_value, uint32_t *ext_value_len, bool *critical); +int s2n_cert_get_utf8_string_from_extension_data_length(const uint8_t *extension_data, uint32_t extension_len, uint32_t *utf8_str_len); +int s2n_cert_get_utf8_string_from_extension_data(const uint8_t *extension_data, uint32_t extension_len, uint8_t *out_data, uint32_t *out_len); diff --git a/contrib/restricted/aws/s2n/crypto/s2n_cipher.c b/contrib/restricted/aws/s2n/crypto/s2n_cipher.c index 8a83980518..c01e44d8da 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_cipher.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_cipher.c @@ -24,10 +24,10 @@ 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()); + POSIX_ENSURE_EQ(key->evp_cipher_ctx, NULL); + POSIX_ENSURE_REF(key->evp_cipher_ctx = EVP_CIPHER_CTX_new()); #if defined(S2N_CIPHER_AEAD_API_AVAILABLE) - eq_check(key->evp_aead_ctx, NULL); + POSIX_ENSURE_EQ(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); 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..3be8de854f 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 @@ -130,18 +130,18 @@ static int s2n_composite_cipher_aes_sha_initial_hmac(struct s2n_session_key *key * 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); + POSIX_BAIL(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)); + POSIX_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)); + POSIX_GUARD(s2n_stuffer_write_bytes(&ctrl_stuffer, sequence_number, S2N_TLS_SEQUENCE_NUM_LEN)); + POSIX_GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, content_type)); + POSIX_GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, protocol_version / 10)); + POSIX_GUARD(s2n_stuffer_write_uint8(&ctrl_stuffer, protocol_version % 10)); + POSIX_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. @@ -150,7 +150,7 @@ static int s2n_composite_cipher_aes_sha_initial_hmac(struct s2n_session_key *key */ 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); + S2N_ERROR_IF(ctrl_ret <= 0, S2N_ERR_INITIAL_HMAC); *extra = ctrl_ret; return 0; @@ -159,27 +159,27 @@ static int s2n_composite_cipher_aes_sha_initial_hmac(struct s2n_session_key *key 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); + POSIX_ENSURE_EQ(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); + POSIX_GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT); + POSIX_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); + POSIX_ENSURE_EQ(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); + POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, NULL, NULL, NULL, iv->data), S2N_ERR_KEY_INIT); + POSIX_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); + POSIX_ENSURE_EQ(mac_size, SHA_DIGEST_LENGTH); EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, mac_size, mac_key); @@ -188,7 +188,7 @@ static int s2n_composite_cipher_aes_sha_set_mac_write_key(struct s2n_session_key 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); + POSIX_ENSURE_EQ(mac_size, SHA256_DIGEST_LENGTH); EVP_CIPHER_CTX_ctrl(key->evp_cipher_ctx, EVP_CTRL_AEAD_SET_MAC_KEY, mac_size, mac_key); @@ -198,7 +198,7 @@ static int s2n_composite_cipher_aes_sha256_set_mac_write_key(struct s2n_session_ static int s2n_composite_cipher_aes128_sha_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in) { - eq_check(in->size, 16); + POSIX_ENSURE_EQ(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); @@ -208,7 +208,7 @@ static int s2n_composite_cipher_aes128_sha_set_encryption_key(struct s2n_session static int s2n_composite_cipher_aes128_sha_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in) { - eq_check(in->size, 16); + POSIX_ENSURE_EQ(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); @@ -218,7 +218,7 @@ static int s2n_composite_cipher_aes128_sha_set_decryption_key(struct s2n_session static int s2n_composite_cipher_aes256_sha_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in) { - eq_check(in->size, 32); + POSIX_ENSURE_EQ(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); @@ -228,7 +228,7 @@ static int s2n_composite_cipher_aes256_sha_set_encryption_key(struct s2n_session static int s2n_composite_cipher_aes256_sha_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in) { - eq_check(in->size, 32); + POSIX_ENSURE_EQ(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); @@ -238,7 +238,7 @@ static int s2n_composite_cipher_aes256_sha_set_decryption_key(struct s2n_session static int s2n_composite_cipher_aes128_sha256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in) { - eq_check(in->size, 16); + POSIX_ENSURE_EQ(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); @@ -248,7 +248,7 @@ static int s2n_composite_cipher_aes128_sha256_set_encryption_key(struct s2n_sess static int s2n_composite_cipher_aes128_sha256_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in) { - eq_check(in->size, 16); + POSIX_ENSURE_EQ(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); @@ -258,7 +258,7 @@ static int s2n_composite_cipher_aes128_sha256_set_decryption_key(struct s2n_sess static int s2n_composite_cipher_aes256_sha256_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in) { - eq_check(in->size, 32); + POSIX_ENSURE_EQ(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); @@ -268,7 +268,7 @@ static int s2n_composite_cipher_aes256_sha256_set_encryption_key(struct s2n_sess static int s2n_composite_cipher_aes256_sha256_set_decryption_key(struct s2n_session_key *key, struct s2n_blob *in) { - eq_check(in->size, 32); + POSIX_ENSURE_EQ(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); diff --git a/contrib/restricted/aws/s2n/crypto/s2n_crypto.c b/contrib/restricted/aws/s2n/crypto/s2n_crypto.c new file mode 100644 index 0000000000..d9062f0578 --- /dev/null +++ b/contrib/restricted/aws/s2n/crypto/s2n_crypto.c @@ -0,0 +1,35 @@ +/* + * 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 <stdint.h> + +#include "api/s2n.h" +#include "crypto/s2n_crypto.h" + +/* OPENSSL_free is defined within <openssl/crypto.h> for OpenSSL Libcrypto + * and within <openssl/mem.h> for AWS_LC and BoringSSL */ +#if defined(OPENSSL_IS_BORINGSSL) || defined(OPENSSL_IS_AWSLC) +#error #include <openssl/mem.h> +#else +#include <openssl/crypto.h> +#endif + +int s2n_crypto_free(uint8_t** data) +{ + if (*data != NULL) { + OPENSSL_free(*data); + } + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/crypto/s2n_crypto.h b/contrib/restricted/aws/s2n/crypto/s2n_crypto.h index 86e029c361..8c5fc04266 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_crypto.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_crypto.h @@ -15,8 +15,12 @@ #pragma once +#include <stdint.h> + #include <openssl/aes.h> #include <openssl/rc4.h> #include <openssl/des.h> #include <openssl/rsa.h> #include <openssl/dh.h> + +int s2n_crypto_free(uint8_t** data); diff --git a/contrib/restricted/aws/s2n/crypto/s2n_dhe.c b/contrib/restricted/aws/s2n/crypto/s2n_dhe.c index 9304a4b46f..9f6bc31249 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_dhe.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_dhe.c @@ -72,14 +72,14 @@ static const BIGNUM *s2n_get_g_dh_param(struct s2n_dh_params *dh_params) static int s2n_check_p_g_dh_params(struct s2n_dh_params *dh_params) { - notnull_check(dh_params); - notnull_check(dh_params->dh); + POSIX_ENSURE_REF(dh_params); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_REF(g); + POSIX_ENSURE_REF(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); @@ -92,7 +92,7 @@ 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); + POSIX_ENSURE_REF(pub_key); S2N_ERROR_IF(BN_is_zero(pub_key), S2N_ERR_DH_PARAMS_CREATE); @@ -102,9 +102,9 @@ static int s2n_check_pub_key_dh_params(struct s2n_dh_params *dh_params) 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); + POSIX_ENSURE(p->size <= INT_MAX, S2N_ERR_INTEGER_OVERFLOW); + POSIX_ENSURE(g->size <= INT_MAX, S2N_ERR_INTEGER_OVERFLOW); + POSIX_ENSURE(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); @@ -113,10 +113,10 @@ static int s2n_set_p_g_Ys_dh_params(struct s2n_dh_params *dh_params, struct s2n_ /* 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); + POSIX_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); + POSIX_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; @@ -128,34 +128,34 @@ static int s2n_set_p_g_Ys_dh_params(struct s2n_dh_params *dh_params, struct s2n_ 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)); + POSIX_GUARD(s2n_check_p_g_dh_params(dh_params)); + POSIX_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)); + POSIX_ENSURE_REF(dh_params); + POSIX_PRECONDITION(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) { + POSIX_GUARD(s2n_check_p_g_dh_params(dh_params)); + if (pkcs3->data && (pkcs3->data - original_ptr != pkcs3->size)) { DH_free(dh_params->dh); - S2N_ERROR(S2N_ERR_INVALID_PKCS3); + POSIX_BAIL(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); + POSIX_BAIL(S2N_ERR_DH_TOO_SMALL); } /* Check the generator and prime */ - GUARD(s2n_dh_params_check(dh_params)); + POSIX_GUARD(s2n_dh_params_check(dh_params)); return S2N_SUCCESS; } @@ -163,25 +163,25 @@ int s2n_pkcs3_to_dh_params(struct s2n_dh_params *dh_params, struct s2n_blob *pkc 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)); + POSIX_ENSURE_REF(server_dh_params); + POSIX_PRECONDITION(s2n_blob_validate(p)); + POSIX_PRECONDITION(s2n_blob_validate(g)); + POSIX_PRECONDITION(s2n_blob_validate(Ys)); server_dh_params->dh = DH_new(); - ENSURE_POSIX(server_dh_params->dh != NULL, S2N_ERR_DH_PARAMS_CREATE); + POSIX_ENSURE(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)); + POSIX_GUARD(s2n_set_p_g_Ys_dh_params(server_dh_params, p, g, Ys)); + POSIX_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)); + POSIX_GUARD(s2n_check_all_dh_params(server_dh_params)); + POSIX_PRECONDITION(s2n_stuffer_validate(out)); + POSIX_PRECONDITION(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); @@ -195,22 +195,22 @@ int s2n_dh_params_to_p_g_Ys(struct s2n_dh_params *server_dh_params, struct s2n_s uint8_t *Ys = NULL; output->data = s2n_stuffer_raw_write(out, 0); - notnull_check(output->data); + POSIX_ENSURE_REF(output->data); - GUARD(s2n_stuffer_write_uint16(out, p_size)); + POSIX_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); + POSIX_ENSURE_REF(p); + POSIX_ENSURE(BN_bn2bin(bn_p, p) == p_size, S2N_ERR_DH_SERIALIZING); - GUARD(s2n_stuffer_write_uint16(out, g_size)); + POSIX_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); + POSIX_ENSURE_REF(g); + POSIX_ENSURE(BN_bn2bin(bn_g, g) == g_size, S2N_ERR_DH_SERIALIZING); - GUARD(s2n_stuffer_write_uint16(out, Ys_size)); + POSIX_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); + POSIX_ENSURE_REF(Ys); + POSIX_ENSURE(BN_bn2bin(bn_Ys, Ys) == Ys_size, S2N_ERR_DH_SERIALIZING); output->size = p_size + 2 + g_size + 2 + Ys_size + 2; @@ -225,40 +225,40 @@ int s2n_dh_compute_shared_secret_as_client(struct s2n_dh_params *server_dh_param 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))); + POSIX_GUARD(s2n_dh_params_check(server_dh_params)); + POSIX_GUARD(s2n_dh_params_copy(server_dh_params, &client_params)); + POSIX_GUARD(s2n_dh_generate_ephemeral_key(&client_params)); + POSIX_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); + POSIX_ENSURE_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)); + POSIX_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); + POSIX_GUARD(s2n_free(shared_key)); + POSIX_GUARD(s2n_dh_params_free(&client_params)); + POSIX_BAIL(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); + POSIX_GUARD(s2n_free(shared_key)); + POSIX_GUARD(s2n_dh_params_free(&client_params)); + POSIX_BAIL(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); + POSIX_GUARD(s2n_free(shared_key)); + POSIX_GUARD(s2n_dh_params_free(&client_params)); + POSIX_BAIL(S2N_ERR_DH_SHARED_SECRET); } shared_key->size = shared_key_size; - GUARD(s2n_dh_params_free(&client_params)); + POSIX_GUARD(s2n_dh_params_free(&client_params)); return S2N_SUCCESS; } @@ -271,23 +271,23 @@ int s2n_dh_compute_shared_secret_as_server(struct s2n_dh_params *server_dh_param int shared_key_size = 0; BIGNUM * pub_key = NULL; - GUARD(s2n_check_all_dh_params(server_dh_params)); + POSIX_GUARD(s2n_check_all_dh_params(server_dh_params)); - GUARD(s2n_stuffer_read_uint16(Yc_in, &Yc_length)); + POSIX_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); + POSIX_ENSURE_REF(Yc.data); pub_key = BN_bin2bn(( const unsigned char * )Yc.data, Yc.size, NULL); - notnull_check(pub_key); + POSIX_ENSURE_REF(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)); + POSIX_ENSURE(server_dh_params_size <= INT32_MAX, S2N_ERR_INTEGER_OVERFLOW); + POSIX_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); + POSIX_BAIL(S2N_ERR_DH_SHARED_SECRET); } shared_key->size = shared_key_size; @@ -299,39 +299,39 @@ int s2n_dh_compute_shared_secret_as_server(struct s2n_dh_params *server_dh_param int s2n_dh_params_check(struct s2n_dh_params *dh_params) { - notnull_check(dh_params); - notnull_check(dh_params->dh); + POSIX_ENSURE_REF(dh_params); + POSIX_ENSURE_REF(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); + POSIX_GUARD_OSSL(DH_check(dh_params->dh, &codes), S2N_ERR_DH_PARAMETER_CHECK); + POSIX_ENSURE(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); + POSIX_GUARD(s2n_check_p_g_dh_params(from)); + POSIX_ENSURE_REF(to); to->dh = DHparams_dup(from->dh); - ENSURE_POSIX(to->dh != NULL, S2N_ERR_DH_COPYING_PARAMETERS); + POSIX_ENSURE(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)); + POSIX_GUARD(s2n_check_p_g_dh_params(dh_params)); - GUARD_OSSL(DH_generate_key(dh_params->dh), S2N_ERR_DH_GENERATING_PARAMETERS); + POSIX_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); + POSIX_ENSURE_REF(dh_params); DH_free(dh_params->dh); dh_params->dh = NULL; diff --git a/contrib/restricted/aws/s2n/crypto/s2n_drbg.c b/contrib/restricted/aws/s2n/crypto/s2n_drbg.c index abcd819e04..242fd5ab9c 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_drbg.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_drbg.c @@ -23,206 +23,234 @@ #include "utils/s2n_random.h" #include "utils/s2n_blob.h" +static bool ignore_prediction_resistance_for_testing = false; + #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) +S2N_RESULT 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]) { + for (uint32_t i = counter->size; i > 0; i--) { + counter->data[i-1] += 1; + if (counter->data[i-1]) { break; } /* seq[i] wrapped, so let it carry */ } - return 0; + return S2N_RESULT_OK; } -static int s2n_drbg_block_encrypt(EVP_CIPHER_CTX * ctx, uint8_t in[S2N_DRBG_BLOCK_SIZE], uint8_t out[S2N_DRBG_BLOCK_SIZE]) +static S2N_RESULT 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); + RESULT_ENSURE_REF(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); + RESULT_GUARD_OSSL(EVP_EncryptUpdate(ctx, out, &len, in, S2N_DRBG_BLOCK_SIZE), S2N_ERR_DRBG); + RESULT_ENSURE_EQ(len, S2N_DRBG_BLOCK_SIZE); - return 0; + return S2N_RESULT_OK; } -static int s2n_drbg_bits(struct s2n_drbg *drbg, struct s2n_blob *out) +static S2N_RESULT s2n_drbg_bits(struct s2n_drbg *drbg, struct s2n_blob *out) { - notnull_check(drbg); - notnull_check(drbg->ctx); - notnull_check(out); + RESULT_ENSURE_REF(drbg); + RESULT_ENSURE_REF(drbg->ctx); + RESULT_ENSURE_REF(out); struct s2n_blob value = {0}; - GUARD(s2n_blob_init(&value, drbg->v, sizeof(drbg->v))); + RESULT_GUARD_POSIX(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)); + RESULT_GUARD(s2n_increment_drbg_counter(&value)); + RESULT_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; + return S2N_RESULT_OK; } 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)); + RESULT_GUARD(s2n_increment_drbg_counter(&value)); + RESULT_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); + RESULT_CHECKED_MEMCPY(out->data + block_aligned_size, spare_block, out->size - block_aligned_size); - return 0; + return S2N_RESULT_OK; } -static int s2n_drbg_update(struct s2n_drbg *drbg, struct s2n_blob *provided_data) +static S2N_RESULT s2n_drbg_update(struct s2n_drbg *drbg, struct s2n_blob *provided_data) { - notnull_check(drbg); - notnull_check(drbg->ctx); + RESULT_ENSURE_REF(drbg); + RESULT_ENSURE_REF(drbg->ctx); + RESULT_ENSURE_REF(provided_data); - s2n_stack_blob(temp_blob, s2n_drbg_seed_size(drgb), S2N_DRBG_MAX_SEED_SIZE); + RESULT_STACK_BLOB(temp_blob, s2n_drbg_seed_size(drgb), S2N_DRBG_MAX_SEED_SIZE); - eq_check(provided_data->size, s2n_drbg_seed_size(drbg)); + RESULT_ENSURE_EQ(provided_data->size, s2n_drbg_seed_size(drbg)); - GUARD(s2n_drbg_bits(drbg, &temp_blob)); + RESULT_GUARD(s2n_drbg_bits(drbg, &temp_blob)); /* XOR in the provided data */ - for (int i = 0; i < provided_data->size; i++) { + for (uint32_t 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); + RESULT_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); + RESULT_CHECKED_MEMCPY(drbg->v, temp_blob.data + s2n_drbg_key_size(drbg), S2N_DRBG_BLOCK_SIZE); - return 0; + return S2N_RESULT_OK; } -static int s2n_drbg_mix_in_entropy(struct s2n_drbg *drbg, struct s2n_blob *entropy, struct s2n_blob *ps) +static S2N_RESULT 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); + RESULT_ENSURE_REF(drbg); + RESULT_ENSURE_REF(drbg->ctx); + RESULT_ENSURE_REF(entropy); - gte_check(entropy->size, ps->size); + RESULT_ENSURE_GTE(entropy->size, ps->size); - for (int i = 0; i < ps->size; i++) { + for (uint32_t i = 0; i < ps->size; i++) { entropy->data[i] ^= ps->data[i]; } - GUARD(s2n_drbg_update(drbg, entropy)); + RESULT_GUARD(s2n_drbg_update(drbg, entropy)); - return 0; + return S2N_RESULT_OK; } -static int s2n_drbg_seed(struct s2n_drbg *drbg, struct s2n_blob *ps) +static S2N_RESULT 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); + RESULT_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)); + RESULT_GUARD(s2n_get_seed_entropy(&blob)); + RESULT_GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps)); drbg->bytes_used = 0; - return 0; + return S2N_RESULT_OK; } -static int s2n_drbg_mix(struct s2n_drbg *drbg, struct s2n_blob *ps) +static S2N_RESULT 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); + if (s2n_unlikely(ignore_prediction_resistance_for_testing)) { + RESULT_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST); + return S2N_RESULT_OK; + } + + RESULT_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)); + RESULT_GUARD(s2n_get_mix_entropy(&blob)); + RESULT_GUARD(s2n_drbg_mix_in_entropy(drbg, &blob, ps)); drbg->mixes += 1; - return 0; + return S2N_RESULT_OK; } -int s2n_drbg_instantiate(struct s2n_drbg *drbg, struct s2n_blob *personalization_string, const s2n_drbg_mode mode) +S2N_RESULT s2n_drbg_instantiate(struct s2n_drbg *drbg, struct s2n_blob *personalization_string, const s2n_drbg_mode mode) { - notnull_check(drbg); + RESULT_ENSURE_REF(drbg); + RESULT_ENSURE_REF(personalization_string); drbg->ctx = EVP_CIPHER_CTX_new(); - S2N_ERROR_IF(!drbg->ctx, S2N_ERR_DRBG); + RESULT_GUARD_PTR(drbg->ctx); - s2n_evp_ctx_init(drbg->ctx); + RESULT_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); + RESULT_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); + RESULT_GUARD_OSSL(EVP_EncryptInit_ex(drbg->ctx, EVP_aes_256_ecb(), NULL, NULL, NULL), S2N_ERR_DRBG); break; default: - S2N_ERROR(S2N_ERR_DRBG); + RESULT_BAIL(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); + RESULT_ENSURE_LTE(s2n_drbg_key_size(drbg), S2N_DRBG_MAX_KEY_SIZE); + RESULT_ENSURE_LTE(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); + RESULT_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)); + RESULT_STACK_BLOB(ps, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE); + RESULT_GUARD_POSIX(s2n_blob_zero(&ps)); - memcpy_check(ps.data, personalization_string->data, MIN(ps.size, personalization_string->size)); + RESULT_CHECKED_MEMCPY(ps.data, personalization_string->data, MIN(ps.size, personalization_string->size)); /* Seed the DRBG */ - GUARD(s2n_drbg_seed(drbg, &ps)); + RESULT_GUARD(s2n_drbg_seed(drbg, &ps)); - return 0; + return S2N_RESULT_OK; } -int s2n_drbg_generate(struct s2n_drbg *drbg, struct s2n_blob *blob) +S2N_RESULT 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; + RESULT_ENSURE_REF(drbg); + RESULT_ENSURE_REF(drbg->ctx); + + RESULT_STACK_BLOB(zeros, s2n_drbg_seed_size(drbg), S2N_DRBG_MAX_SEED_SIZE); + + RESULT_ENSURE(blob->size <= S2N_DRBG_GENERATE_LIMIT, S2N_ERR_DRBG_REQUEST_SIZE); + + /* Mix in additional entropy for every randomness generation call. This + * defense mechanism is referred to as "prediction resistance". + * If we ever relax this defense, we must: + * 1. Implement reseeding according to limit specified in + * NIST SP800-90A 10.2.1 Table 3. + * 2. Re-consider whether the current fork detection strategy is still + * sufficient. + */ + RESULT_GUARD(s2n_drbg_mix(drbg, &zeros)); + RESULT_GUARD(s2n_drbg_bits(drbg, blob)); + RESULT_GUARD(s2n_drbg_update(drbg, &zeros)); + + return S2N_RESULT_OK; } -int s2n_drbg_wipe(struct s2n_drbg *drbg) +S2N_RESULT s2n_drbg_wipe(struct s2n_drbg *drbg) { - notnull_check(drbg); + RESULT_ENSURE_REF(drbg); + if (drbg->ctx) { - GUARD_OSSL(EVP_CIPHER_CTX_cleanup(drbg->ctx), S2N_ERR_DRBG); + RESULT_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; + return S2N_RESULT_OK; } -int s2n_drbg_bytes_used(struct s2n_drbg *drbg, uint64_t *bytes_used) +S2N_RESULT s2n_drbg_bytes_used(struct s2n_drbg *drbg, uint64_t *bytes_used) { - notnull_check(drbg); - notnull_check(bytes_used); + RESULT_ENSURE_REF(drbg); + RESULT_ENSURE_REF(bytes_used); + *bytes_used = drbg->bytes_used; - return 0; + return S2N_RESULT_OK; +} + +S2N_RESULT s2n_ignore_prediction_resistance_for_testing(bool ignore_bool) { + RESULT_ENSURE(s2n_in_unit_test(), S2N_ERR_NOT_IN_UNIT_TEST); + + ignore_prediction_resistance_for_testing = ignore_bool; + + return S2N_RESULT_OK; } diff --git a/contrib/restricted/aws/s2n/crypto/s2n_drbg.h b/contrib/restricted/aws/s2n/crypto/s2n_drbg.h index 58562d17eb..f3a5661554 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_drbg.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_drbg.h @@ -28,9 +28,6 @@ /* 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; @@ -55,12 +52,15 @@ 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). + * s2n's DRBG uses 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. + * 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); +S2N_RESULT s2n_drbg_instantiate(struct s2n_drbg *drbg, struct s2n_blob *personalization_string, const s2n_drbg_mode mode); +S2N_RESULT s2n_drbg_generate(struct s2n_drbg *drbg, struct s2n_blob *returned_bits); +S2N_RESULT s2n_drbg_wipe(struct s2n_drbg *drbg); +S2N_RESULT s2n_drbg_bytes_used(struct s2n_drbg *drbg, uint64_t *bytes_used); +/* Use for testing only */ +S2N_RESULT s2n_ignore_prediction_resistance_for_testing(bool true_or_false); diff --git a/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.c b/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.c index 7ae2a73094..fa137ee1f0 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_ecc_evp.c @@ -89,6 +89,16 @@ const struct s2n_ecc_named_curve s2n_ecc_curve_x25519 = { const struct s2n_ecc_named_curve s2n_ecc_curve_x25519 = {0}; #endif +/* A fake / unsupported curve for use in triggering retries + * during testing. + */ +const struct s2n_ecc_named_curve s2n_unsupported_curve = { + .iana_id = 0, .name = "unsupported", + .libcrypto_nid = NID_X9_62_prime256v1, + .share_size = SECP256R1_SHARE_SIZE, + .generate_key = s2n_ecc_evp_generate_key_nist_curves, +}; + /* 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. */ @@ -116,8 +126,8 @@ static int s2n_ecc_evp_generate_key_x25519(const struct s2n_ecc_named_curve *nam 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); + POSIX_GUARD_OSSL(EVP_PKEY_keygen_init(pctx), S2N_ERR_ECDHE_GEN_KEY); + POSIX_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; @@ -129,42 +139,47 @@ static int s2n_ecc_evp_generate_key_nist_curves(const struct s2n_ecc_named_curve 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); + POSIX_GUARD_OSSL(EVP_PKEY_paramgen_init(pctx), S2N_ERR_ECDHE_GEN_KEY); + POSIX_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, ¶ms), S2N_ERR_ECDHE_GEN_KEY); + POSIX_GUARD_OSSL(EVP_PKEY_paramgen(pctx, ¶ms), 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); + POSIX_GUARD_OSSL(EVP_PKEY_keygen_init(kctx), S2N_ERR_ECDHE_GEN_KEY); + POSIX_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); + POSIX_ENSURE_REF(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. + POSIX_ENSURE_REF(peer_public); + POSIX_ENSURE_REF(own_key); + + /* From RFC 8446(TLS1.3) Section 4.2.8.2: For the curves secp256r1, secp384r1, and secp521r1, 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 and x448 the peer public-key validation check doesn't apply. + * From RFC 8422(TLS1.2) Section 5.11: With the NIST curves, each party MUST validate the public key sent by its peer + * in the ClientKeyExchange and ServerKeyExchange messages. A receiving party MUST check that the x and y parameters from + * the peer's public value satisfy the curve equation, y^2 = x^3 + ax + b mod p. + * Note that the `EC_KEY_check_key` validation is a MUST for only NIST curves, if a non-NIST curve is added to s2n-tls + * this is an additional validation step that increases security but decreases performance. */ - if (iana_id == TLS_EC_CURVE_SECP_256_R1 || iana_id == TLS_EC_CURVE_SECP_384_R1) { + if (iana_id != TLS_EC_CURVE_ECDH_X25519 && iana_id != TLS_EC_CURVE_ECDH_X448) { 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); + POSIX_GUARD_OSSL(EC_KEY_check_key(ec_key), S2N_ERR_ECDHE_SHARED_SECRET); } size_t shared_secret_size; @@ -172,21 +187,21 @@ static int s2n_ecc_evp_compute_shared_secret(EVP_PKEY *own_key, EVP_PKEY *peer_p 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)); + POSIX_GUARD_OSSL(EVP_PKEY_derive_init(ctx), S2N_ERR_ECDHE_SHARED_SECRET); + POSIX_GUARD_OSSL(EVP_PKEY_derive_set_peer(ctx, peer_public), S2N_ERR_ECDHE_SHARED_SECRET); + POSIX_GUARD_OSSL(EVP_PKEY_derive(ctx, NULL, &shared_secret_size), S2N_ERR_ECDHE_SHARED_SECRET); + POSIX_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); + POSIX_GUARD(s2n_free(shared_secret)); + POSIX_BAIL(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); + POSIX_ENSURE_REF(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); @@ -197,44 +212,44 @@ 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) { - 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); + POSIX_ENSURE_REF(private_ecc_evp_params->negotiated_curve); + POSIX_ENSURE_REF(private_ecc_evp_params->evp_pkey); + POSIX_ENSURE_REF(public_ecc_evp_params->negotiated_curve); + POSIX_ENSURE_REF(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, + POSIX_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); + POSIX_ENSURE_REF(ecc_evp_params->negotiated_curve); + POSIX_ENSURE_REF(ecc_evp_params->evp_pkey); + POSIX_ENSURE_REF(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)); + POSIX_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); + POSIX_ENSURE_REF(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)); + POSIX_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); + POSIX_GUARD_OSSL(EVP_PKEY_paramgen_init(pctx), S2N_ERR_ECDHE_SERIALIZING); + POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ecc_evp_params->negotiated_curve->libcrypto_nid), S2N_ERR_ECDHE_SERIALIZING); + POSIX_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), + POSIX_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), @@ -245,7 +260,7 @@ int s2n_ecc_evp_compute_shared_secret_as_server(struct s2n_ecc_evp_params *ecc_e 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); + POSIX_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 @@ -259,20 +274,20 @@ int s2n_ecc_evp_compute_shared_secret_as_client(struct s2n_ecc_evp_params *ecc_e DEFER_CLEANUP(struct s2n_ecc_evp_params client_params = {0}, s2n_ecc_evp_params_free); - notnull_check(ecc_evp_params->negotiated_curve); + POSIX_ENSURE_REF(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)); + POSIX_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); + POSIX_BAIL(S2N_ERR_ECDHE_SHARED_SECRET); } - GUARD(s2n_stuffer_write_uint8(Yc_out, client_params.negotiated_curve->share_size)); + POSIX_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); + POSIX_BAIL(S2N_ERR_ECDHE_SERIALIZING); } return 0; @@ -297,50 +312,50 @@ static EC_POINT *s2n_ecc_evp_blob_to_point(struct s2n_blob *blob, const 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); + PTR_BAIL(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); + PTR_BAIL(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); + POSIX_ENSURE_REF(in); + POSIX_ENSURE_REF(point_blob); + POSIX_ENSURE_GTE(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); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_REF(data_to_verify->data); /* Read the curve */ - GUARD(s2n_stuffer_read_uint8(in, &curve_type)); + POSIX_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); + POSIX_ENSURE_REF(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)); + POSIX_GUARD(s2n_stuffer_read_uint8(in, &point_length)); - GUARD(s2n_ecc_evp_read_params_point(in, point_length, &raw_server_ecc_params->point_blob)); + POSIX_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; @@ -349,10 +364,10 @@ int s2n_ecc_evp_read_params(struct s2n_stuffer *in, struct s2n_blob *data_to_ver } 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); + POSIX_ENSURE_REF(ecc_evp_params); + POSIX_ENSURE_REF(ecc_evp_params->negotiated_curve); + POSIX_ENSURE_REF(ecc_evp_params->evp_pkey); + POSIX_ENSURE_REF(out); #if EVP_APIS_SUPPORTED struct s2n_blob point_blob = {0}; @@ -361,12 +376,12 @@ int s2n_ecc_evp_write_params_point(struct s2n_ecc_evp_params *ecc_evp_params, st 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); + POSIX_BAIL(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); + POSIX_ENSURE_REF(point_blob.data); + POSIX_CHECKED_MEMCPY(point_blob.data, encoded_point, size); OPENSSL_free(encoded_point); } #else @@ -379,35 +394,35 @@ int s2n_ecc_evp_write_params_point(struct s2n_ecc_evp_params *ecc_evp_params, st 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)); + POSIX_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); + POSIX_ENSURE_REF(point_blob.data); point_blob.size = point_len; - GUARD(s2n_ecc_evp_write_point_data_snug(point, group, &point_blob)); + POSIX_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); + POSIX_ENSURE_REF(ecc_evp_params); + POSIX_ENSURE_REF(ecc_evp_params->negotiated_curve); + POSIX_ENSURE_REF(ecc_evp_params->evp_pkey); + POSIX_ENSURE_REF(out); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_REF(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)); + POSIX_GUARD(s2n_stuffer_write_uint8(out, TLS_EC_CURVE_TYPE_NAMED)); + POSIX_GUARD(s2n_stuffer_write_uint16(out, ecc_evp_params->negotiated_curve->iana_id)); + POSIX_GUARD(s2n_stuffer_write_uint8(out, key_share_size)); - GUARD(s2n_ecc_evp_write_params_point(ecc_evp_params, out)); + POSIX_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; @@ -416,8 +431,8 @@ int s2n_ecc_evp_write_params(struct s2n_ecc_evp_params *ecc_evp_params, struct s } 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); + POSIX_ENSURE_REF(point_blob->data); + POSIX_ENSURE_REF(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 @@ -426,16 +441,16 @@ int s2n_ecc_evp_parse_params_point(struct s2n_blob *point_blob, struct s2n_ecc_e 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)); + POSIX_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); + POSIX_GUARD_OSSL(EVP_PKEY_paramgen_init(pctx), S2N_ERR_ECDHE_SERIALIZING); + POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_ec_paramgen_curve_nid(pctx, ecc_evp_params->negotiated_curve->libcrypto_nid), S2N_ERR_ECDHE_SERIALIZING); + POSIX_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), + POSIX_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) { @@ -454,7 +469,7 @@ int s2n_ecc_evp_parse_params_point(struct s2n_blob *point_blob, struct s2n_ecc_e /* 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); + POSIX_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); @@ -474,22 +489,22 @@ int s2n_ecc_evp_parse_params(struct s2n_ecdhe_raw_server_params *raw_server_ecc_ 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++) { + POSIX_GUARD(s2n_stuffer_init(&iana_ids_in, iana_ids)); + POSIX_GUARD(s2n_stuffer_write(&iana_ids_in, iana_ids)); + for (size_t 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++) { + for (uint32_t j = 0; j < iana_ids->size / 2; j++) { uint16_t iana_id; - GUARD(s2n_stuffer_read_uint16(&iana_ids_in, &iana_id)); + POSIX_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)); + POSIX_GUARD(s2n_stuffer_reread(&iana_ids_in)); } - S2N_ERROR(S2N_ERR_ECDHE_UNSUPPORTED_CURVE); + POSIX_BAIL(S2N_ERR_ECDHE_UNSUPPORTED_CURVE); } int s2n_ecc_evp_params_free(struct s2n_ecc_evp_params *ecc_evp_params) { diff --git a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c index 240f0f87b1..23050ffea4 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.c @@ -27,48 +27,65 @@ #include "crypto/s2n_ecdsa.h" #include "crypto/s2n_ecc_evp.h" +#include "crypto/s2n_evp_signing.h" #include "crypto/s2n_hash.h" #include "crypto/s2n_openssl.h" #include "crypto/s2n_pkey.h" +#define S2N_ECDSA_TYPE 0 + S2N_RESULT s2n_ecdsa_der_signature_size(const struct s2n_pkey *pkey, uint32_t *size_out) { - ENSURE_REF(pkey); - ENSURE_REF(size_out); + RESULT_ENSURE_REF(pkey); + RESULT_ENSURE_REF(size_out); const struct s2n_ecdsa_key *ecdsa_key = &pkey->key.ecdsa_key; - ENSURE_REF(ecdsa_key->ec_key); + RESULT_ENSURE_REF(ecdsa_key->ec_key); const int size = ECDSA_size(ecdsa_key->ec_key); - GUARD_AS_RESULT(size); + RESULT_GUARD_POSIX(size); *size_out = size; return S2N_RESULT_OK; } +int s2n_ecdsa_sign_digest(const struct s2n_pkey *priv, struct s2n_blob *digest, struct s2n_blob *signature) +{ + POSIX_ENSURE_REF(priv); + POSIX_ENSURE_REF(digest); + POSIX_ENSURE_REF(signature); + + const s2n_ecdsa_private_key *key = &priv->key.ecdsa_key; + POSIX_ENSURE_REF(key->ec_key); + + unsigned int signature_size = signature->size; + POSIX_GUARD_OSSL(ECDSA_sign(S2N_ECDSA_TYPE, digest->data, digest->size, signature->data, &signature_size, key->ec_key), S2N_ERR_SIGN); + POSIX_ENSURE(signature_size <= signature->size, S2N_ERR_SIZE_MISMATCH); + signature->size = signature_size; + + return S2N_SUCCESS; +} + static int s2n_ecdsa_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg, struct s2n_hash_state *digest, struct s2n_blob *signature) { + POSIX_ENSURE_REF(digest); 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_length = 0; + POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); + POSIX_ENSURE_LTE(digest_length, S2N_MAX_DIGEST_LEN); - uint8_t digest_out[S2N_MAX_DIGEST_LEN]; - GUARD(s2n_hash_digest(digest, digest_out, digest_length)); + uint8_t digest_out[S2N_MAX_DIGEST_LEN] = { 0 }; + POSIX_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; + struct s2n_blob digest_blob = { 0 }; + POSIX_GUARD(s2n_blob_init(&digest_blob, digest_out, digest_length)); + POSIX_GUARD(s2n_ecdsa_sign_digest(priv, &digest_blob, signature)); - GUARD(s2n_hash_reset(digest)); + POSIX_GUARD(s2n_hash_reset(digest)); - return 0; + return S2N_SUCCESS; } static int s2n_ecdsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg, @@ -77,19 +94,19 @@ static int s2n_ecdsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg_check(sig_alg, S2N_SIGNATURE_ECDSA); const s2n_ecdsa_public_key *key = &pub->key.ecdsa_key; - notnull_check(key->ec_key); + POSIX_ENSURE_REF(key->ec_key); uint8_t digest_length; - GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); - lte_check(digest_length, S2N_MAX_DIGEST_LEN); + POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); + POSIX_ENSURE_LTE(digest_length, S2N_MAX_DIGEST_LEN); uint8_t digest_out[S2N_MAX_DIGEST_LEN]; - GUARD(s2n_hash_digest(digest, digest_out, digest_length)); + POSIX_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); + POSIX_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)); + POSIX_GUARD(s2n_hash_reset(digest)); return 0; } @@ -102,20 +119,20 @@ static int s2n_ecdsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pke 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)); + POSIX_GUARD(s2n_hash_new(&state_in)); + POSIX_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))); + POSIX_GUARD(s2n_hash_init(&state_in, S2N_HASH_SHA1)); + POSIX_GUARD(s2n_hash_init(&state_out, S2N_HASH_SHA1)); + POSIX_GUARD(s2n_hash_update(&state_in, input, sizeof(input))); + POSIX_GUARD(s2n_hash_update(&state_out, input, sizeof(input))); uint32_t size = 0; - GUARD_AS_POSIX(s2n_ecdsa_der_signature_size(priv, &size)); - GUARD(s2n_alloc(&signature, size)); + POSIX_GUARD_RESULT(s2n_ecdsa_der_signature_size(priv, &size)); + POSIX_GUARD(s2n_alloc(&signature, size)); - GUARD(s2n_ecdsa_sign(priv, S2N_SIGNATURE_ECDSA, &state_in, &signature)); - GUARD(s2n_ecdsa_verify(pub, S2N_SIGNATURE_ECDSA, &state_out, &signature)); + POSIX_GUARD(s2n_ecdsa_sign(priv, S2N_SIGNATURE_ECDSA, &state_in, &signature)); + POSIX_GUARD(s2n_ecdsa_verify(pub, S2N_SIGNATURE_ECDSA, &state_out, &signature)); return 0; } @@ -136,7 +153,7 @@ static int s2n_ecdsa_key_free(struct s2n_pkey *pkey) 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); + POSIX_ENSURE_REF(ecdsa_key->ec_key); return 0; } @@ -167,17 +184,18 @@ int s2n_ecdsa_pkey_init(struct s2n_pkey *pkey) { pkey->match = &s2n_ecdsa_keys_match; pkey->free = &s2n_ecdsa_key_free; pkey->check_key = &s2n_ecdsa_check_key_exists; + POSIX_GUARD_RESULT(s2n_evp_signing_set_pkey_overrides(pkey)); 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); + POSIX_ENSURE_REF(ecdsa_key); + POSIX_ENSURE_REF(ecdsa_key->ec_key); + POSIX_ENSURE_REF(curve); int curve_id = EC_GROUP_get_curve_name(EC_KEY_get0_group(ecdsa_key->ec_key)); - eq_check(curve_id, curve->libcrypto_nid); + POSIX_ENSURE_EQ(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..e4ad664349 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_ecdsa.h @@ -17,7 +17,7 @@ #include <openssl/ecdsa.h> #include <stdint.h> -#include <s2n.h> +#include "api/s2n.h" #include "stuffer/s2n_stuffer.h" diff --git a/contrib/restricted/aws/s2n/crypto/s2n_evp.c b/contrib/restricted/aws/s2n/crypto/s2n_evp.c index 11aac21f75..81fecdce5b 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_evp.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_evp.c @@ -20,7 +20,7 @@ int s2n_digest_allow_md5_for_fips(struct s2n_evp_digest *evp_digest) { - notnull_check(evp_digest); + POSIX_ENSURE_REF(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. @@ -35,13 +35,18 @@ int s2n_digest_allow_md5_for_fips(struct s2n_evp_digest *evp_digest) S2N_RESULT s2n_digest_is_md5_allowed_for_fips(struct s2n_evp_digest *evp_digest, bool *out) { - ENSURE_REF(out); + RESULT_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)) { + if (s2n_is_in_fips_mode() && evp_digest && evp_digest->ctx && 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; } +#else + if (s2n_is_in_fips_mode()) { + /* If s2n is in FIPS mode and built with AWS-LC or BoringSSL, there are no flags to check in the EVP digest to allow 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..6c443efba7 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_evp.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_evp.h @@ -16,6 +16,7 @@ #pragma once #include <openssl/evp.h> +#include <openssl/hmac.h> #include "crypto/s2n_openssl.h" #include "utils/s2n_result.h" @@ -27,7 +28,10 @@ struct s2n_evp_digest { struct s2n_evp_hmac_state { struct s2n_evp_digest evp_digest; - EVP_PKEY *mac_key; + union { + HMAC_CTX *hmac_ctx; + EVP_PKEY *evp_pkey; + } ctx; }; /* Define API's that change based on the OpenSSL Major Version. */ @@ -41,5 +45,12 @@ struct s2n_evp_hmac_state { #define S2N_EVP_MD_CTX_FREE(md_ctx) (EVP_MD_CTX_destroy(md_ctx)) #endif +/* 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. + */ +#define S2N_EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_set_signature_md(ctx, (EVP_MD*) (uintptr_t) md) + 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_evp_signing.c b/contrib/restricted/aws/s2n/crypto/s2n_evp_signing.c new file mode 100644 index 0000000000..147840c2dd --- /dev/null +++ b/contrib/restricted/aws/s2n/crypto/s2n_evp_signing.c @@ -0,0 +1,154 @@ +/* + * 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_evp.h" +#include "crypto/s2n_evp_signing.h" +#include "crypto/s2n_pkey.h" +#include "crypto/s2n_rsa_pss.h" + +#include "utils/s2n_safety.h" + +/* + * FIPS 140-3 requires that we don't pass raw digest bytes to the libcrypto signing methods. + * In order to do that, we need to use signing methods that both calculate the digest and + * perform the signature. + */ + +static S2N_RESULT s2n_evp_md_ctx_set_pkey_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pctx) +{ +#ifdef S2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + EVP_MD_CTX_set_pkey_ctx(ctx, pctx); + return S2N_RESULT_OK; +#else + RESULT_BAIL(S2N_ERR_UNIMPLEMENTED); +#endif +} + +static S2N_RESULT s2n_evp_pkey_set_rsa_pss_saltlen(EVP_PKEY_CTX *pctx) +{ +#if RSA_PSS_SIGNING_SUPPORTED + RESULT_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, RSA_PSS_SALTLEN_DIGEST), S2N_ERR_PKEY_CTX_INIT); + return S2N_RESULT_OK; +#else + RESULT_BAIL(S2N_ERR_UNIMPLEMENTED); +#endif +} + +bool s2n_evp_signing_supported() +{ +#ifdef S2N_LIBCRYPTO_SUPPORTS_EVP_MD_CTX_SET_PKEY_CTX + /* We can only use EVP signing if the hash state has an EVP_MD_CTX + * that we can pass to the EVP signing methods. + */ + return s2n_hash_evp_fully_supported(); +#else + return false; +#endif +} + +/* If using EVP signing, override the sign and verify pkey methods. + * The EVP methods can handle all pkey types / signature algorithms. + */ +S2N_RESULT s2n_evp_signing_set_pkey_overrides(struct s2n_pkey *pkey) +{ + if (s2n_evp_signing_supported()) { + RESULT_ENSURE_REF(pkey); + pkey->sign = &s2n_evp_sign; + pkey->verify = &s2n_evp_verify; + } + return S2N_RESULT_OK; +} + +static S2N_RESULT s2n_evp_signing_validate_hash_alg(s2n_signature_algorithm sig_alg, s2n_hash_algorithm hash_alg) +{ + switch(hash_alg) { + case S2N_HASH_NONE: + case S2N_HASH_MD5: + /* MD5 alone is never supported */ + RESULT_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM); + break; + case S2N_HASH_MD5_SHA1: + /* Only RSA supports MD5+SHA1. + * This should not be a problem, as we only allow MD5+SHA1 when + * falling back to TLS1.0 or 1.1, which only support RSA. + */ + RESULT_ENSURE(sig_alg == S2N_SIGNATURE_RSA, S2N_ERR_HASH_INVALID_ALGORITHM); + break; + default: + break; + } + /* Hash algorithm must be recognized and supported by EVP_MD */ + RESULT_ENSURE(s2n_hash_alg_to_evp_md(hash_alg) != NULL, S2N_ERR_HASH_INVALID_ALGORITHM); + return S2N_RESULT_OK; +} + +int s2n_evp_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg, + struct s2n_hash_state *hash_state, struct s2n_blob *signature) +{ + POSIX_ENSURE_REF(priv); + POSIX_ENSURE_REF(hash_state); + POSIX_ENSURE_REF(signature); + POSIX_ENSURE(s2n_evp_signing_supported(), S2N_ERR_HASH_NOT_READY); + POSIX_GUARD_RESULT(s2n_evp_signing_validate_hash_alg(sig_alg, hash_state->alg)); + + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(priv->pkey, NULL); + POSIX_ENSURE_REF(pctx); + POSIX_GUARD_OSSL(EVP_PKEY_sign_init(pctx), S2N_ERR_PKEY_CTX_INIT); + POSIX_GUARD_OSSL(S2N_EVP_PKEY_CTX_set_signature_md(pctx, s2n_hash_alg_to_evp_md(hash_state->alg)), S2N_ERR_PKEY_CTX_INIT); + + if (sig_alg == S2N_SIGNATURE_RSA_PSS_RSAE || sig_alg == S2N_SIGNATURE_RSA_PSS_PSS) { + POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_PKEY_CTX_INIT); + POSIX_GUARD_RESULT(s2n_evp_pkey_set_rsa_pss_saltlen(pctx)); + } + + EVP_MD_CTX *ctx = hash_state->digest.high_level.evp.ctx; + POSIX_ENSURE_REF(ctx); + POSIX_GUARD_RESULT(s2n_evp_md_ctx_set_pkey_ctx(ctx, pctx)); + + size_t signature_size = signature->size; + POSIX_GUARD_OSSL(EVP_DigestSignFinal(ctx, signature->data, &signature_size), S2N_ERR_SIGN); + POSIX_ENSURE(signature_size <= signature->size, S2N_ERR_SIZE_MISMATCH); + signature->size = signature_size; + return S2N_SUCCESS; +} + +int s2n_evp_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg, + struct s2n_hash_state *hash_state, struct s2n_blob *signature) +{ + POSIX_ENSURE_REF(pub); + POSIX_ENSURE_REF(hash_state); + POSIX_ENSURE_REF(signature); + POSIX_ENSURE(s2n_evp_signing_supported(), S2N_ERR_HASH_NOT_READY); + POSIX_GUARD_RESULT(s2n_evp_signing_validate_hash_alg(sig_alg, hash_state->alg)); + + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pub->pkey, NULL); + POSIX_ENSURE_REF(pctx); + POSIX_GUARD_OSSL(EVP_PKEY_verify_init(pctx), S2N_ERR_PKEY_CTX_INIT); + POSIX_GUARD_OSSL(S2N_EVP_PKEY_CTX_set_signature_md(pctx, s2n_hash_alg_to_evp_md(hash_state->alg)), S2N_ERR_PKEY_CTX_INIT); + + if (sig_alg == S2N_SIGNATURE_RSA_PSS_RSAE || sig_alg == S2N_SIGNATURE_RSA_PSS_PSS) { + POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_PKEY_CTX_INIT); + POSIX_GUARD_RESULT(s2n_evp_pkey_set_rsa_pss_saltlen(pctx)); + } + + EVP_MD_CTX *ctx = hash_state->digest.high_level.evp.ctx; + POSIX_ENSURE_REF(ctx); + POSIX_GUARD_RESULT(s2n_evp_md_ctx_set_pkey_ctx(ctx, pctx)); + + POSIX_GUARD_OSSL(EVP_DigestVerifyFinal(ctx, signature->data, signature->size), S2N_ERR_VERIFY_SIGNATURE); + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/crypto/s2n_evp_signing.h b/contrib/restricted/aws/s2n/crypto/s2n_evp_signing.h new file mode 100644 index 0000000000..872f63b682 --- /dev/null +++ b/contrib/restricted/aws/s2n/crypto/s2n_evp_signing.h @@ -0,0 +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 "api/s2n.h" + +#include "crypto/s2n_hash.h" +#include "crypto/s2n_signature.h" +#include "utils/s2n_blob.h" + +bool s2n_evp_signing_supported(); +S2N_RESULT s2n_evp_signing_set_pkey_overrides(struct s2n_pkey *pkey); +int s2n_evp_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig_alg, + struct s2n_hash_state *digest, struct s2n_blob *signature); +int s2n_evp_verify(const struct s2n_pkey *pub, s2n_signature_algorithm sig_alg, + struct s2n_hash_state *digest, struct s2n_blob *signature); diff --git a/contrib/restricted/aws/s2n/crypto/s2n_fips.c b/contrib/restricted/aws/s2n/crypto/s2n_fips.c index d939cc3b53..8843f4ebd9 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_fips.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_fips.c @@ -23,13 +23,19 @@ int s2n_fips_init(void) { s2n_fips_mode = 0; -#ifdef OPENSSL_FIPS - /* FIPS mode can be entered only if OPENSSL_FIPS is defined */ + /* FIPS mode can be checked if OpenSSL was configured and built for FIPS which then defines OPENSSL_FIPS. + * + * AWS-LC always defines FIPS_mode() that you can call and check what the library was built with. It does not define + * a public OPENSSL_FIPS/AWSLC_FIPS macro that we can (or need to) check here + * + * Note: FIPS_mode() does not change the FIPS state of libcrypto. This only returns the current state. Applications + * using s2n must call FIPS_mode_set(1) prior to s2n_init. + * */ +#if defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC) if (FIPS_mode()) { s2n_fips_mode = 1; } #endif - return 0; } diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hash.c b/contrib/restricted/aws/s2n/crypto/s2n_hash.c index 27a9358438..b2d817851d 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_hash.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_hash.c @@ -22,9 +22,52 @@ #include "utils/s2n_safety.h" +static bool s2n_use_custom_md5_sha1() +{ +#if defined(S2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH) + return false; +#else + return true; +#endif +} + +static bool s2n_use_evp_impl() +{ + return s2n_is_in_fips_mode(); +} + +bool s2n_hash_evp_fully_supported() +{ + return s2n_use_evp_impl() && !s2n_use_custom_md5_sha1(); +} + +const EVP_MD* s2n_hash_alg_to_evp_md(s2n_hash_algorithm alg) +{ + switch (alg) { + case S2N_HASH_MD5: + return EVP_md5(); + 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(); +#if defined(S2N_LIBCRYPTO_SUPPORTS_EVP_MD5_SHA1_HASH) + case S2N_HASH_MD5_SHA1: + return EVP_md5_sha1(); +#endif + default: + return NULL; + } +} + int s2n_hash_digest_size(s2n_hash_algorithm alg, uint8_t *out) { - ENSURE_POSIX(S2N_MEM_IS_WRITABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION); + POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION); switch (alg) { case S2N_HASH_NONE: *out = 0; break; case S2N_HASH_MD5: *out = MD5_DIGEST_LENGTH; break; @@ -35,7 +78,7 @@ int s2n_hash_digest_size(s2n_hash_algorithm alg, uint8_t *out) 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); + POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM); } return S2N_SUCCESS; } @@ -45,7 +88,7 @@ int s2n_hash_digest_size(s2n_hash_algorithm alg, uint8_t *out) * 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_WRITABLE(block_size, sizeof(*block_size)), S2N_ERR_PRECONDITION_VIOLATION); + POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(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; @@ -56,7 +99,7 @@ int s2n_hash_block_size(s2n_hash_algorithm alg, uint64_t *block_size) 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); + POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM); } return S2N_SUCCESS; } @@ -84,7 +127,7 @@ bool s2n_hash_is_available(s2n_hash_algorithm alg) int s2n_hash_is_ready_for_input(struct s2n_hash_state *state) { - PRECONDITION_POSIX(s2n_hash_state_validate(state)); + POSIX_PRECONDITION(s2n_hash_state_validate(state)); return state->is_ready_for_input; } @@ -94,8 +137,7 @@ static int s2n_low_level_hash_new(struct s2n_hash_state *state) * 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; + *state = (struct s2n_hash_state) { 0 }; return S2N_SUCCESS; } @@ -105,30 +147,30 @@ static int s2n_low_level_hash_init(struct s2n_hash_state *state, s2n_hash_algori case S2N_HASH_NONE: break; case S2N_HASH_MD5: - GUARD_OSSL(MD5_Init(&state->digest.low_level.md5), S2N_ERR_HASH_INIT_FAILED); + POSIX_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); + POSIX_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); + POSIX_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); + POSIX_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); + POSIX_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); + POSIX_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);; + POSIX_GUARD_OSSL(SHA1_Init(&state->digest.low_level.md5_sha1.sha1), S2N_ERR_HASH_INIT_FAILED);; + POSIX_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); + POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM); } state->alg = alg; @@ -140,38 +182,38 @@ static int s2n_low_level_hash_init(struct s2n_hash_state *state, s2n_hash_algori 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); + POSIX_ENSURE(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); + POSIX_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); + POSIX_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); + POSIX_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); + POSIX_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); + POSIX_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); + POSIX_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); + POSIX_GUARD_OSSL(SHA1_Update(&state->digest.low_level.md5_sha1.sha1, data, size), S2N_ERR_HASH_UPDATE_FAILED); + POSIX_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); + POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM); } - ENSURE_POSIX(size <= (UINT64_MAX - state->currently_in_hash), S2N_ERR_INTEGER_OVERFLOW); + POSIX_ENSURE(size <= (UINT64_MAX - state->currently_in_hash), S2N_ERR_INTEGER_OVERFLOW); state->currently_in_hash += size; return S2N_SUCCESS; @@ -179,42 +221,42 @@ static int s2n_low_level_hash_update(struct s2n_hash_state *state, const void *d 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); + POSIX_ENSURE(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); + POSIX_ENSURE_EQ(size, MD5_DIGEST_LENGTH); + POSIX_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); + POSIX_ENSURE_EQ(size, SHA_DIGEST_LENGTH); + POSIX_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); + POSIX_ENSURE_EQ(size, SHA224_DIGEST_LENGTH); + POSIX_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); + POSIX_ENSURE_EQ(size, SHA256_DIGEST_LENGTH); + POSIX_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); + POSIX_ENSURE_EQ(size, SHA384_DIGEST_LENGTH); + POSIX_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); + POSIX_ENSURE_EQ(size, SHA512_DIGEST_LENGTH); + POSIX_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); + POSIX_ENSURE_EQ(size, MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH); + POSIX_GUARD_OSSL(SHA1_Final(((uint8_t *) out) + MD5_DIGEST_LENGTH, &state->digest.low_level.md5_sha1.sha1), S2N_ERR_HASH_DIGEST_FAILED); + POSIX_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); + POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM); } state->currently_in_hash = 0; @@ -224,7 +266,7 @@ static int s2n_low_level_hash_digest(struct s2n_hash_state *state, void *out, ui 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)); + POSIX_CHECKED_MEMCPY(to, from, sizeof(struct s2n_hash_state)); return 0; } @@ -245,8 +287,11 @@ static int s2n_low_level_hash_free(struct s2n_hash_state *state) 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()); + POSIX_ENSURE_REF(state->digest.high_level.evp.ctx = S2N_EVP_MD_CTX_NEW()); + if (s2n_use_custom_md5_sha1()) { + POSIX_ENSURE_REF(state->digest.high_level.evp_md5_secondary.ctx = S2N_EVP_MD_CTX_NEW()); + } + state->is_ready_for_input = 0; state->currently_in_hash = 0; @@ -260,169 +305,122 @@ static int s2n_evp_hash_allow_md5_for_fips(struct s2n_hash_state *state) * 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); + POSIX_GUARD(s2n_digest_allow_md5_for_fips(&state->digest.high_level.evp)); + if (s2n_use_custom_md5_sha1()) { + POSIX_GUARD(s2n_digest_allow_md5_for_fips(&state->digest.high_level.evp_md5_secondary)); + } + return S2N_SUCCESS; } 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); - } + POSIX_ENSURE_REF(state->digest.high_level.evp.ctx); state->alg = alg; state->is_ready_for_input = 1; state->currently_in_hash = 0; + if (alg == S2N_HASH_NONE) { + return S2N_SUCCESS; + } + + if (alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1()) { + POSIX_ENSURE_REF(state->digest.high_level.evp_md5_secondary.ctx); + POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, EVP_sha1(), NULL), S2N_ERR_HASH_INIT_FAILED); + POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp_md5_secondary.ctx, EVP_md5(), NULL), S2N_ERR_HASH_INIT_FAILED); + return S2N_SUCCESS; + } + + POSIX_ENSURE_REF(s2n_hash_alg_to_evp_md(alg)); + POSIX_GUARD_OSSL(EVP_DigestInit_ex(state->digest.high_level.evp.ctx, s2n_hash_alg_to_evp_md(alg), NULL), S2N_ERR_HASH_INIT_FAILED); 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); + POSIX_ENSURE(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY); + POSIX_ENSURE(size <= (UINT64_MAX - state->currently_in_hash), S2N_ERR_INTEGER_OVERFLOW); + state->currently_in_hash += 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)); - 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); + if (state->alg == S2N_HASH_NONE) { + return S2N_SUCCESS; } - ENSURE_POSIX(size <= (UINT64_MAX - state->currently_in_hash), S2N_ERR_INTEGER_OVERFLOW); - state->currently_in_hash += size; + POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp.ctx)); + POSIX_GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED); + + if (state->alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1()) { + POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp_md5_secondary.ctx)); + POSIX_GUARD_OSSL(EVP_DigestUpdate(state->digest.high_level.evp_md5_secondary.ctx, data, size), S2N_ERR_HASH_UPDATE_FAILED); + } 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); + POSIX_ENSURE(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY); + + state->currently_in_hash = 0; + state->is_ready_for_input = 0; 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); + uint8_t expected_digest_size = 0; + POSIX_GUARD(s2n_hash_digest_size(state->alg, &expected_digest_size)); + POSIX_ENSURE_EQ(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; + if (state->alg == S2N_HASH_NONE) { + return S2N_SUCCESS; + } - 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); + POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp.ctx)); + + if (state->alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1()) { + POSIX_ENSURE_REF(EVP_MD_CTX_md(state->digest.high_level.evp_md5_secondary.ctx)); + + uint8_t sha1_digest_size = 0; + POSIX_GUARD(s2n_hash_digest_size(S2N_HASH_SHA1, &sha1_digest_size)); + + unsigned int sha1_primary_digest_size = sha1_digest_size; + unsigned int md5_secondary_digest_size = digest_size - sha1_primary_digest_size; + + POSIX_ENSURE(EVP_MD_CTX_size(state->digest.high_level.evp.ctx) <= sha1_digest_size, S2N_ERR_HASH_DIGEST_FAILED); + POSIX_ENSURE(EVP_MD_CTX_size(state->digest.high_level.evp_md5_secondary.ctx) <= md5_secondary_digest_size, S2N_ERR_HASH_DIGEST_FAILED); + + POSIX_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); + POSIX_GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp_md5_secondary.ctx, out, &md5_secondary_digest_size), S2N_ERR_HASH_DIGEST_FAILED); + return S2N_SUCCESS; } - state->currently_in_hash = 0; - state->is_ready_for_input = 0; + POSIX_ENSURE(EVP_MD_CTX_size(state->digest.high_level.evp.ctx) <= digest_size, S2N_ERR_HASH_DIGEST_FAILED); + POSIX_GUARD_OSSL(EVP_DigestFinal_ex(state->digest.high_level.evp.ctx, out, &digest_size), S2N_ERR_HASH_DIGEST_FAILED); 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; + if (from->alg == S2N_HASH_NONE) { + return S2N_SUCCESS; + } + + POSIX_ENSURE_REF(to->digest.high_level.evp.ctx); + POSIX_GUARD_OSSL(EVP_MD_CTX_copy_ex(to->digest.high_level.evp.ctx, from->digest.high_level.evp.ctx), S2N_ERR_HASH_COPY_FAILED); + + if (from->alg == S2N_HASH_MD5_SHA1 && s2n_use_custom_md5_sha1()) { + POSIX_ENSURE_REF(to->digest.high_level.evp_md5_secondary.ctx); + POSIX_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); + } + + bool is_md5_allowed_for_fips = false; + POSIX_GUARD_RESULT(s2n_digest_is_md5_allowed_for_fips(&from->digest.high_level.evp, &is_md5_allowed_for_fips)); + if (is_md5_allowed_for_fips && (from->alg == S2N_HASH_MD5 || from->alg == S2N_HASH_MD5_SHA1)) { + POSIX_GUARD(s2n_hash_allow_md5_for_fips(to)); + } return S2N_SUCCESS; } @@ -430,19 +428,18 @@ 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)); + POSIX_GUARD_RESULT(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); + POSIX_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 && s2n_use_custom_md5_sha1()) { + POSIX_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)); + POSIX_GUARD(s2n_hash_allow_md5_for_fips(state)); } /* hash_init resets the ready_for_input and currently_in_hash fields. */ @@ -452,9 +449,13 @@ static int s2n_evp_hash_reset(struct s2n_hash_state *state) 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; + + if (s2n_use_custom_md5_sha1()) { + S2N_EVP_MD_CTX_FREE(state->digest.high_level.evp_md5_secondary.ctx); + state->digest.high_level.evp_md5_secondary.ctx = NULL; + } + state->is_ready_for_input = 0; return S2N_SUCCESS; } @@ -483,104 +484,106 @@ static const struct s2n_hash s2n_evp_hash = { 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; - + state->hash_impl = &s2n_low_level_hash; + if (s2n_use_evp_impl()) { + state->hash_impl = &s2n_evp_hash; + } return S2N_SUCCESS; } int s2n_hash_new(struct s2n_hash_state *state) { - notnull_check(state); + POSIX_ENSURE_REF(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)); + POSIX_GUARD(s2n_hash_set_impl(state)); - notnull_check(state->hash_impl->alloc); + POSIX_ENSURE_REF(state->hash_impl->alloc); - GUARD(state->hash_impl->alloc(state)); + POSIX_GUARD(state->hash_impl->alloc(state)); return S2N_SUCCESS; } S2N_RESULT s2n_hash_state_validate(struct s2n_hash_state *state) { - ENSURE_REF(state); + RESULT_ENSURE_REF(state); return S2N_RESULT_OK; } int s2n_hash_allow_md5_for_fips(struct s2n_hash_state *state) { - notnull_check(state); + POSIX_ENSURE_REF(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)); + POSIX_GUARD(s2n_hash_set_impl(state)); - notnull_check(state->hash_impl->allow_md5_for_fips); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_REF(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)); + POSIX_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)); + POSIX_GUARD_RESULT(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); + POSIX_ENSURE_REF(state->hash_impl->init); return state->hash_impl->init(state, alg); } else { - S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM); + POSIX_BAIL(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); + POSIX_PRECONDITION(s2n_hash_state_validate(state)); + POSIX_ENSURE(S2N_MEM_IS_READABLE(data, size), S2N_ERR_PRECONDITION_VIOLATION); + POSIX_ENSURE_REF(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); + POSIX_PRECONDITION(s2n_hash_state_validate(state)); + POSIX_ENSURE(S2N_MEM_IS_READABLE(out, size), S2N_ERR_PRECONDITION_VIOLATION); + POSIX_ENSURE_REF(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); + POSIX_PRECONDITION(s2n_hash_state_validate(to)); + POSIX_PRECONDITION(s2n_hash_state_validate(from)); + POSIX_ENSURE_REF(from->hash_impl->copy); return from->hash_impl->copy(to, from); } int s2n_hash_reset(struct s2n_hash_state *state) { - notnull_check(state); + POSIX_ENSURE_REF(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)); + POSIX_GUARD(s2n_hash_set_impl(state)); - notnull_check(state->hash_impl->reset); + POSIX_ENSURE_REF(state->hash_impl->reset); return state->hash_impl->reset(state); } @@ -594,32 +597,31 @@ int s2n_hash_free(struct s2n_hash_state *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)); + POSIX_GUARD(s2n_hash_set_impl(state)); - notnull_check(state->hash_impl->free); + POSIX_ENSURE_REF(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_WRITABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION); - ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY); + POSIX_PRECONDITION(s2n_hash_state_validate(state)); + POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION); + POSIX_ENSURE(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_WRITABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION); - ENSURE_POSIX(state->is_ready_for_input, S2N_ERR_HASH_NOT_READY); + POSIX_PRECONDITION(s2n_hash_state_validate(state)); + POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION); + POSIX_ENSURE(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)); + POSIX_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*/ diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hash.h b/contrib/restricted/aws/s2n/crypto/s2n_hash.h index 2ca40e77ca..6ae9b13386 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_hash.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_hash.h @@ -87,6 +87,8 @@ struct s2n_hash { int (*free) (struct s2n_hash_state *state); }; +bool s2n_hash_evp_fully_supported(); +const EVP_MD* s2n_hash_alg_to_evp_md(s2n_hash_algorithm alg); 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); diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c b/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c index cefd528fdf..eda68149d8 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_hkdf.c @@ -34,13 +34,13 @@ int s2n_hkdf_extract(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const const struct s2n_blob *key, struct s2n_blob *pseudo_rand_key) { uint8_t hmac_size; - GUARD(s2n_hmac_digest_size(alg, &hmac_size)); + POSIX_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)); + POSIX_GUARD(s2n_hmac_init(hmac, alg, salt->data, salt->size)); + POSIX_GUARD(s2n_hmac_update(hmac, key->data, key->size)); + POSIX_GUARD(s2n_hmac_digest(hmac, pseudo_rand_key->data, pseudo_rand_key->size)); - GUARD(s2n_hmac_reset(hmac)); + POSIX_GUARD(s2n_hmac_reset(hmac)); return 0; } @@ -51,8 +51,9 @@ static int s2n_hkdf_expand(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, uint8_t prev[MAX_DIGEST_SIZE] = { 0 }; uint32_t done_len = 0; - uint8_t hash_len; - GUARD(s2n_hmac_digest_size(alg, &hash_len)); + uint8_t hash_len = 0; + POSIX_GUARD(s2n_hmac_digest_size(alg, &hash_len)); + POSIX_ENSURE_GT(hash_len, 0); uint32_t total_rounds = output->size / hash_len; if (output->size % hash_len) { total_rounds++; @@ -62,24 +63,24 @@ static int s2n_hkdf_expand(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, 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)); + POSIX_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)); + POSIX_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)); + POSIX_GUARD(s2n_hmac_update(hmac, info->data, info->size)); + POSIX_GUARD(s2n_hmac_update(hmac, &curr_round, 1)); + POSIX_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); + POSIX_CHECKED_MEMCPY(output->data + done_len, prev, cat_len); done_len += cat_len; - GUARD(s2n_hmac_reset(hmac)); + POSIX_GUARD(s2n_hmac_reset(hmac)); } return 0; @@ -96,19 +97,19 @@ int s2n_hkdf_expand_label(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, c /* RFC8446 specifies that labels must be 12 characters or less, to avoid ** incurring two hash rounds. */ - lte_check(label->size, 12); + POSIX_ENSURE_LTE(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)); + POSIX_GUARD(s2n_blob_init(&hkdf_label_blob, hkdf_label_buf, sizeof(hkdf_label_buf))); + POSIX_GUARD(s2n_stuffer_init(&hkdf_label, &hkdf_label_blob)); + POSIX_GUARD(s2n_stuffer_write_uint16(&hkdf_label, output->size)); + POSIX_GUARD(s2n_stuffer_write_uint8(&hkdf_label, label->size + sizeof("tls13 ") - 1)); + POSIX_GUARD(s2n_stuffer_write_str(&hkdf_label, "tls13 ")); + POSIX_GUARD(s2n_stuffer_write(&hkdf_label, label)); + POSIX_GUARD(s2n_stuffer_write_uint8(&hkdf_label, context->size)); + POSIX_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)); + POSIX_GUARD(s2n_hkdf_expand(hmac, alg, secret, &hkdf_label_blob, output)); return 0; } @@ -119,8 +120,8 @@ int s2n_hkdf(struct s2n_hmac_state *hmac, s2n_hmac_algorithm alg, const struct s 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)); + POSIX_GUARD(s2n_hkdf_extract(hmac, alg, salt, key, &pseudo_rand_key)); + POSIX_GUARD(s2n_hkdf_expand(hmac, alg, &pseudo_rand_key, info, output)); return 0; } diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hmac.c b/contrib/restricted/aws/s2n/crypto/s2n_hmac.c index 2689545abb..29ded952ce 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_hmac.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_hmac.c @@ -30,7 +30,7 @@ int s2n_hash_hmac_alg(s2n_hash_algorithm hash_alg, s2n_hmac_algorithm *out) { - ENSURE_POSIX(S2N_MEM_IS_WRITABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION); + POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(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; @@ -41,14 +41,14 @@ int s2n_hash_hmac_alg(s2n_hash_algorithm hash_alg, s2n_hmac_algorithm *out) case S2N_HASH_SHA512: *out = S2N_HMAC_SHA512; break; case S2N_HASH_MD5_SHA1: /* Fall through ... */ default: - S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM); + POSIX_BAIL(S2N_ERR_HASH_INVALID_ALGORITHM); } return S2N_SUCCESS; } int s2n_hmac_hash_alg(s2n_hmac_algorithm hmac_alg, s2n_hash_algorithm *out) { - ENSURE_POSIX(S2N_MEM_IS_WRITABLE(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION); + POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(out, sizeof(*out)), S2N_ERR_PRECONDITION_VIOLATION); switch(hmac_alg) { case S2N_HMAC_NONE: *out = S2N_HASH_NONE; break; case S2N_HMAC_MD5: *out = S2N_HASH_MD5; break; @@ -60,7 +60,7 @@ int s2n_hmac_hash_alg(s2n_hmac_algorithm hmac_alg, s2n_hash_algorithm *out) 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); + POSIX_BAIL(S2N_ERR_HMAC_INVALID_ALGORITHM); } return S2N_SUCCESS; } @@ -68,8 +68,8 @@ int s2n_hmac_hash_alg(s2n_hmac_algorithm hmac_alg, s2n_hash_algorithm *out) 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)); + POSIX_GUARD(s2n_hmac_hash_alg(hmac_alg, &hash_alg)); + POSIX_GUARD(s2n_hash_digest_size(hash_alg, out)); return S2N_SUCCESS; } @@ -99,15 +99,15 @@ static int s2n_sslv3_mac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm a 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)); + POSIX_GUARD(s2n_hash_update(&state->inner_just_key, key, klen)); + POSIX_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)); + POSIX_GUARD(s2n_hash_update(&state->outer_just_key, key, klen)); + POSIX_GUARD(s2n_hash_update(&state->outer_just_key, state->xor_pad, state->xor_pad_size)); return S2N_SUCCESS; } @@ -117,31 +117,31 @@ static int s2n_tls_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm al 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); + POSIX_GUARD(s2n_hash_update(&state->outer, key, klen)); + POSIX_GUARD(s2n_hash_digest(&state->outer, state->digest_pad, state->digest_size)); + POSIX_CHECKED_MEMCPY(state->xor_pad, state->digest_pad, state->digest_size); } else { - memcpy_check(state->xor_pad, key, klen); + POSIX_CHECKED_MEMCPY(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)); + POSIX_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)); + POSIX_GUARD(s2n_hash_update(&state->outer_just_key, state->xor_pad, state->xor_pad_size)); return S2N_SUCCESS; } int s2n_hmac_xor_pad_size(s2n_hmac_algorithm hmac_alg, uint16_t *xor_pad_size) { - ENSURE_POSIX(S2N_MEM_IS_WRITABLE(xor_pad_size, sizeof(*xor_pad_size)), S2N_ERR_PRECONDITION_VIOLATION); + POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(xor_pad_size, sizeof(*xor_pad_size)), S2N_ERR_PRECONDITION_VIOLATION); switch(hmac_alg) { case S2N_HMAC_NONE: *xor_pad_size = 64; break; case S2N_HMAC_MD5: *xor_pad_size = 64; break; @@ -153,14 +153,14 @@ int s2n_hmac_xor_pad_size(s2n_hmac_algorithm hmac_alg, uint16_t *xor_pad_size) 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); + POSIX_BAIL(S2N_ERR_HMAC_INVALID_ALGORITHM); } return S2N_SUCCESS; } int s2n_hmac_hash_block_size(s2n_hmac_algorithm hmac_alg, uint16_t *block_size) { - ENSURE_POSIX(S2N_MEM_IS_WRITABLE(block_size, sizeof(*block_size)), S2N_ERR_PRECONDITION_VIOLATION); + POSIX_ENSURE(S2N_MEM_IS_WRITABLE_CHECK(block_size, sizeof(*block_size)), S2N_ERR_PRECONDITION_VIOLATION); switch(hmac_alg) { case S2N_HMAC_NONE: *block_size = 64; break; case S2N_HMAC_MD5: *block_size = 64; break; @@ -172,63 +172,63 @@ int s2n_hmac_hash_block_size(s2n_hmac_algorithm hmac_alg, uint16_t *block_size) 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); + POSIX_BAIL(S2N_ERR_HMAC_INVALID_ALGORITHM); } return S2N_SUCCESS; } int s2n_hmac_new(struct s2n_hmac_state *state) { - ENSURE_POSIX_REF(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)); - POSTCONDITION_POSIX(s2n_hmac_state_validate(state)); + POSIX_ENSURE_REF(state); + POSIX_GUARD(s2n_hash_new(&state->inner)); + POSIX_GUARD(s2n_hash_new(&state->inner_just_key)); + POSIX_GUARD(s2n_hash_new(&state->outer)); + POSIX_GUARD(s2n_hash_new(&state->outer_just_key)); + POSIX_POSTCONDITION(s2n_hmac_state_validate(state)); return S2N_SUCCESS; } S2N_RESULT s2n_hmac_state_validate(struct s2n_hmac_state *state) { - ENSURE_REF(state); - GUARD_RESULT(s2n_hash_state_validate(&state->inner)); - GUARD_RESULT(s2n_hash_state_validate(&state->inner_just_key)); - GUARD_RESULT(s2n_hash_state_validate(&state->outer)); - GUARD_RESULT(s2n_hash_state_validate(&state->outer_just_key)); + RESULT_ENSURE_REF(state); + RESULT_GUARD(s2n_hash_state_validate(&state->inner)); + RESULT_GUARD(s2n_hash_state_validate(&state->inner_just_key)); + RESULT_GUARD(s2n_hash_state_validate(&state->outer)); + RESULT_GUARD(s2n_hash_state_validate(&state->outer_just_key)); return S2N_RESULT_OK; } int s2n_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const void *key, uint32_t klen) { - notnull_check(state); + POSIX_ENSURE_REF(state); if (!s2n_hmac_is_available(alg)) { /* Prevent hmacs from being used if they are not available. */ - S2N_ERROR(S2N_ERR_HMAC_INVALID_ALGORITHM); + POSIX_BAIL(S2N_ERR_HMAC_INVALID_ALGORITHM); } state->alg = alg; - GUARD(s2n_hmac_hash_block_size(alg, &state->hash_block_size)); + POSIX_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)); + POSIX_GUARD(s2n_hmac_xor_pad_size(alg, &state->xor_pad_size)); + POSIX_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); + POSIX_ENSURE_GTE(sizeof(state->xor_pad), state->xor_pad_size); + POSIX_ENSURE_GTE(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); + POSIX_ENSURE_GTE(sizeof(state->xor_pad), state->hash_block_size); s2n_hash_algorithm hash_alg; - GUARD(s2n_hmac_hash_alg(alg, &hash_alg)); + POSIX_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)); + POSIX_GUARD(s2n_hash_init(&state->inner, hash_alg)); + POSIX_GUARD(s2n_hash_init(&state->inner_just_key, hash_alg)); + POSIX_GUARD(s2n_hash_init(&state->outer, hash_alg)); + POSIX_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)); + POSIX_GUARD(s2n_sslv3_mac_init(state, alg, key, klen)); } else { - GUARD(s2n_tls_hmac_init(state, alg, key, klen)); + POSIX_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. @@ -236,15 +236,15 @@ int s2n_hmac_init(struct s2n_hmac_state *state, s2n_hmac_algorithm alg, const vo * this also prevents uninitilized bytes being used. */ memset(&state->xor_pad, 0, sizeof(state->xor_pad)); - GUARD(s2n_hmac_reset(state)); + POSIX_GUARD(s2n_hmac_reset(state)); return S2N_SUCCESS; } int s2n_hmac_update(struct s2n_hmac_state *state, const void *in, uint32_t size) { - PRECONDITION_POSIX(s2n_hmac_state_validate(state)); - ENSURE_POSIX(state->hash_block_size != 0, S2N_ERR_PRECONDITION_VIOLATION); + POSIX_PRECONDITION(s2n_hmac_state_validate(state)); + POSIX_ENSURE(state->hash_block_size != 0, S2N_ERR_PRECONDITION_VIOLATION); /* 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 @@ -267,9 +267,9 @@ int s2n_hmac_update(struct s2n_hmac_state *state, const void *in, uint32_t size) * smaller number of cycles if the input is "small". */ const uint32_t HIGHEST_32_BIT = 4294949760; - ENSURE_POSIX(size <= (UINT32_MAX - HIGHEST_32_BIT), S2N_ERR_INTEGER_OVERFLOW); + POSIX_ENSURE(size <= (UINT32_MAX - HIGHEST_32_BIT), S2N_ERR_INTEGER_OVERFLOW); uint32_t value = (HIGHEST_32_BIT + size) % state->hash_block_size; - GUARD(s2n_add_overflow(state->currently_in_hash_block, value, &state->currently_in_hash_block)); + POSIX_GUARD(s2n_add_overflow(state->currently_in_hash_block, value, &state->currently_in_hash_block)); state->currently_in_hash_block %= state->hash_block_size; return s2n_hash_update(&state->inner, in, size); @@ -277,10 +277,10 @@ int s2n_hmac_update(struct s2n_hmac_state *state, const void *in, uint32_t size) int s2n_hmac_digest(struct s2n_hmac_state *state, void *out, uint32_t size) { - PRECONDITION_POSIX(s2n_hmac_state_validate(state)); - 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)); + POSIX_PRECONDITION(s2n_hmac_state_validate(state)); + POSIX_GUARD(s2n_hash_digest(&state->inner, state->digest_pad, state->digest_size)); + POSIX_GUARD(s2n_hash_copy(&state->outer, &state->outer_just_key)); + POSIX_GUARD(s2n_hash_update(&state->outer, state->digest_pad, state->digest_size)); return s2n_hash_digest(&state->outer, out, size); } @@ -288,7 +288,7 @@ int s2n_hmac_digest(struct s2n_hmac_state *state, void *out, uint32_t 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)); + POSIX_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. @@ -304,7 +304,7 @@ int s2n_hmac_digest_two_compression_rounds(struct s2n_hmac_state *state, void *o } /* Can't reuse a hash after it has been finalized, so reset and push another block in */ - GUARD(s2n_hash_reset(&state->inner)); + POSIX_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); @@ -313,10 +313,10 @@ int s2n_hmac_digest_two_compression_rounds(struct s2n_hmac_state *state, void *o int s2n_hmac_free(struct s2n_hmac_state *state) { if (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)); + POSIX_GUARD(s2n_hash_free(&state->inner)); + POSIX_GUARD(s2n_hash_free(&state->inner_just_key)); + POSIX_GUARD(s2n_hash_free(&state->outer)); + POSIX_GUARD(s2n_hash_free(&state->outer_just_key)); } return S2N_SUCCESS; @@ -324,14 +324,14 @@ int s2n_hmac_free(struct s2n_hmac_state *state) int s2n_hmac_reset(struct s2n_hmac_state *state) { - PRECONDITION_POSIX(s2n_hmac_state_validate(state)); - ENSURE_POSIX(state->hash_block_size != 0, S2N_ERR_PRECONDITION_VIOLATION); - GUARD(s2n_hash_copy(&state->inner, &state->inner_just_key)); + POSIX_PRECONDITION(s2n_hmac_state_validate(state)); + POSIX_ENSURE(state->hash_block_size != 0, S2N_ERR_PRECONDITION_VIOLATION); + POSIX_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)); + POSIX_GUARD(s2n_hash_get_currently_in_hash_total(&state->inner, &bytes_in_hash)); bytes_in_hash %= state->hash_block_size; - ENSURE_POSIX(bytes_in_hash <= UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW); + POSIX_ENSURE(bytes_in_hash <= UINT32_MAX, S2N_ERR_INTEGER_OVERFLOW); /* 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; return S2N_SUCCESS; @@ -344,8 +344,8 @@ int s2n_hmac_digest_verify(const void *a, const void *b, uint32_t len) int s2n_hmac_copy(struct s2n_hmac_state *to, struct s2n_hmac_state *from) { - PRECONDITION_POSIX(s2n_hmac_state_validate(to)); - PRECONDITION_POSIX(s2n_hmac_state_validate(from)); + POSIX_PRECONDITION(s2n_hmac_state_validate(to)); + POSIX_PRECONDITION(s2n_hmac_state_validate(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. */ @@ -355,16 +355,16 @@ int s2n_hmac_copy(struct s2n_hmac_state *to, struct s2n_hmac_state *from) 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)); + POSIX_GUARD(s2n_hash_copy(&to->inner, &from->inner)); + POSIX_GUARD(s2n_hash_copy(&to->inner_just_key, &from->inner_just_key)); + POSIX_GUARD(s2n_hash_copy(&to->outer, &from->outer)); + POSIX_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)); - POSTCONDITION_POSIX(s2n_hmac_state_validate(to)); - POSTCONDITION_POSIX(s2n_hmac_state_validate(from)); + POSIX_CHECKED_MEMCPY(to->xor_pad, from->xor_pad, sizeof(to->xor_pad)); + POSIX_CHECKED_MEMCPY(to->digest_pad, from->digest_pad, sizeof(to->digest_pad)); + POSIX_POSTCONDITION(s2n_hmac_state_validate(to)); + POSIX_POSTCONDITION(s2n_hmac_state_validate(from)); return S2N_SUCCESS; } @@ -374,8 +374,8 @@ int s2n_hmac_copy(struct s2n_hmac_state *to, struct s2n_hmac_state *from) */ int s2n_hmac_save_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac) { - ENSURE_POSIX_REF(backup); - PRECONDITION_POSIX(s2n_hmac_state_validate(hmac)); + POSIX_ENSURE_REF(backup); + POSIX_PRECONDITION(s2n_hmac_state_validate(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; @@ -385,12 +385,12 @@ int s2n_hmac_save_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_ int s2n_hmac_restore_evp_hash_state(struct s2n_hmac_evp_backup* backup, struct s2n_hmac_state* hmac) { - ENSURE_POSIX_REF(backup); - PRECONDITION_POSIX(s2n_hmac_state_validate(hmac)); + POSIX_ENSURE_REF(backup); + POSIX_PRECONDITION(s2n_hmac_state_validate(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; - POSTCONDITION_POSIX(s2n_hmac_state_validate(hmac)); + POSIX_POSTCONDITION(s2n_hmac_state_validate(hmac)); return S2N_SUCCESS; } diff --git a/contrib/restricted/aws/s2n/crypto/s2n_hmac.h b/contrib/restricted/aws/s2n/crypto/s2n_hmac.h index 34f8314b2d..1a3d52a343 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_hmac.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_hmac.h @@ -44,7 +44,6 @@ struct s2n_hmac_state { 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]; diff --git a/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c new file mode 100644 index 0000000000..2fa5b003de --- /dev/null +++ b/contrib/restricted/aws/s2n/crypto/s2n_libcrypto.c @@ -0,0 +1,42 @@ +/* + * 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_crypto.h" +#include "crypto/s2n_openssl.h" + +/* + * Verifying libcrypto type via method should be preferred + * where possible, since it reduces #ifs and avoids potential + * bugs where the header containing the #define is not included. + */ + +bool s2n_libcrypto_is_awslc() +{ +#if defined(OPENSSL_IS_AWSLC) + return true; +#else + return false; +#endif +} + +bool s2n_libcrypto_is_boringssl() +{ +#if defined(OPENSSL_IS_BORINGSSL) + return true; +#else + return false; +#endif +} + diff --git a/contrib/restricted/aws/s2n/crypto/s2n_openssl.h b/contrib/restricted/aws/s2n/crypto/s2n_openssl.h index 92c53c26fd..a6cebf982f 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_openssl.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_openssl.h @@ -15,6 +15,8 @@ #pragma once +#include <stdbool.h> + /** * openssl with OPENSSL_VERSION_NUMBER < 0x10100003L made data type details unavailable * libressl use openssl with data type details available, but mandatorily set @@ -37,13 +39,18 @@ (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) +#define s2n_evp_ctx_init(ctx) POSIX_GUARD_OSSL(EVP_CIPHER_CTX_init(ctx), S2N_ERR_DRBG) +#define RESULT_EVP_CTX_INIT(ctx) RESULT_GUARD_OSSL(EVP_CIPHER_CTX_init(ctx), S2N_ERR_DRBG) #else #define s2n_evp_ctx_init(ctx) EVP_CIPHER_CTX_init(ctx) +#define RESULT_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) +#if !defined(OPENSSL_IS_BORINGSSL) && !defined(OPENSSL_FIPS) && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_AWSLC) && !defined(OPENSSL_NO_ENGINE) #define S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND 1 #else #define S2N_LIBCRYPTO_SUPPORTS_CUSTOM_RAND 0 #endif + +bool s2n_libcrypto_is_awslc(); +bool s2n_libcrypto_is_boringssl(); diff --git a/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.c b/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.c new file mode 100644 index 0000000000..a61805cee7 --- /dev/null +++ b/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.c @@ -0,0 +1,25 @@ +/* + * 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 "api/s2n.h" +#include "crypto/s2n_openssl_x509.h" + +int s2n_openssl_x509_stack_pop_free(STACK_OF(X509) **cert_chain) +{ + if (*cert_chain != NULL) { + sk_X509_pop_free(*cert_chain, X509_free); + } + return S2N_SUCCESS; +} diff --git a/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h b/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h index 812b7233ba..b27a7f5a92 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_openssl_x509.h @@ -15,8 +15,11 @@ #pragma once +#include <stdint.h> #include <openssl/x509.h> #include "utils/s2n_safety.h" DEFINE_POINTER_CLEANUP_FUNC(X509*, X509_free); + +int s2n_openssl_x509_stack_pop_free(STACK_OF(X509) **cert_chain); diff --git a/contrib/restricted/aws/s2n/crypto/s2n_pkey.c b/contrib/restricted/aws/s2n/crypto/s2n_pkey.c index 69c0c25178..377eb2585e 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_pkey.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_pkey.c @@ -14,8 +14,8 @@ */ #include <openssl/evp.h> -#include <crypto/s2n_openssl_evp.h> -#include <crypto/s2n_openssl_x509.h> +#include "crypto/s2n_openssl_evp.h" +#include "crypto/s2n_openssl_x509.h" #include "error/s2n_errno.h" #include "crypto/s2n_rsa_pss.h" @@ -51,26 +51,26 @@ int s2n_pkey_setup_for_type(struct s2n_pkey *pkey, s2n_pkey_type pkey_type) return s2n_rsa_pss_pkey_init(pkey); case S2N_PKEY_TYPE_SENTINEL: case S2N_PKEY_TYPE_UNKNOWN: - S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED); + POSIX_BAIL(S2N_ERR_CERT_TYPE_UNSUPPORTED); } - S2N_ERROR(S2N_ERR_CERT_TYPE_UNSUPPORTED); + POSIX_BAIL(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); + POSIX_ENSURE_REF(pkey->pkey); + POSIX_ENSURE_REF(pkey->check_key); return pkey->check_key(pkey); } S2N_RESULT s2n_pkey_size(const struct s2n_pkey *pkey, uint32_t *size_out) { - ENSURE_REF(pkey); - ENSURE_REF(pkey->size); - ENSURE_REF(size_out); + RESULT_ENSURE_REF(pkey); + RESULT_ENSURE_REF(pkey->size); + RESULT_ENSURE_REF(size_out); - GUARD_RESULT(pkey->size(pkey, size_out)); + RESULT_GUARD(pkey->size(pkey, size_out)); return S2N_RESULT_OK; } @@ -78,7 +78,7 @@ S2N_RESULT s2n_pkey_size(const struct s2n_pkey *pkey, uint32_t *size_out) 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); + POSIX_ENSURE_REF(pkey->sign); return pkey->sign(pkey, sig_alg, digest, signature); } @@ -86,29 +86,29 @@ int s2n_pkey_sign(const struct s2n_pkey *pkey, s2n_signature_algorithm sig_alg, 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); + POSIX_ENSURE_REF(pkey); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_REF(pub_key->match); S2N_ERROR_IF(pub_key->match != priv_key->match, S2N_ERR_KEY_MISMATCH); @@ -118,7 +118,7 @@ int s2n_pkey_match(const struct s2n_pkey *pub_key, const struct s2n_pkey *priv_k int s2n_pkey_free(struct s2n_pkey *key) { if (key != NULL && key->free != NULL) { - GUARD(key->free(key)); + POSIX_GUARD(key->free(key)); } if (key->pkey != NULL) { @@ -141,7 +141,7 @@ int s2n_asn1der_to_private_key(struct s2n_pkey *priv_key, struct s2n_blob *asn1d /* 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); + POSIX_BAIL(S2N_ERR_DECODE_PRIVATE_KEY); } /* Initialize s2n_pkey according to key type */ @@ -171,7 +171,7 @@ int s2n_asn1der_to_private_key(struct s2n_pkey *priv_key, struct s2n_blob *asn1d 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); + POSIX_BAIL(S2N_ERR_DECODE_PRIVATE_KEY); } priv_key->pkey = evp_private_key; @@ -195,7 +195,7 @@ int s2n_asn1der_to_public_key_and_type(struct s2n_pkey *pub_key, s2n_pkey_type * /* Some TLS clients in the wild send extra trailing bytes 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 <= S2N_MAX_ALLOWED_CERT_TRAILING_BYTES, S2N_ERR_DECODE_CERTIFICATE); + POSIX_ENSURE(trailing_bytes <= S2N_MAX_ALLOWED_CERT_TRAILING_BYTES, 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); @@ -230,7 +230,7 @@ int s2n_asn1der_to_public_key_and_type(struct s2n_pkey *pub_key, s2n_pkey_type * *pkey_type_out = S2N_PKEY_TYPE_ECDSA; break; default: - S2N_ERROR(S2N_ERR_DECODE_CERTIFICATE); + POSIX_BAIL(S2N_ERR_DECODE_CERTIFICATE); } pub_key->pkey = evp_public_key; diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa.c index cfce3054bf..164496f93f 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_rsa.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa.c @@ -22,6 +22,7 @@ #include "crypto/s2n_drbg.h" #include "crypto/s2n_hash.h" #include "crypto/s2n_pkey.h" +#include "crypto/s2n_evp_signing.h" #include "crypto/s2n_rsa_signing.h" #include "error/s2n_errno.h" #include "stuffer/s2n_stuffer.h" @@ -37,24 +38,24 @@ static S2N_RESULT s2n_rsa_modulus_check(RSA *rsa) const BIGNUM *n = NULL; /* RSA still owns the memory for n */ RSA_get0_key(rsa, &n, NULL, NULL); - ENSURE_REF(n); + RESULT_ENSURE_REF(n); #else - ENSURE_REF(rsa->n); + RESULT_ENSURE_REF(rsa->n); #endif return S2N_RESULT_OK; } static S2N_RESULT s2n_rsa_encrypted_size(const struct s2n_pkey *key, uint32_t *size_out) { - ENSURE_REF(key); - ENSURE_REF(size_out); + RESULT_ENSURE_REF(key); + RESULT_ENSURE_REF(size_out); const struct s2n_rsa_key *rsa_key = &key->key.rsa_key; - ENSURE_REF(rsa_key->rsa); - GUARD_RESULT(s2n_rsa_modulus_check(rsa_key->rsa)); + RESULT_ENSURE_REF(rsa_key->rsa); + RESULT_GUARD(s2n_rsa_modulus_check(rsa_key->rsa)); const int size = RSA_size(rsa_key->rsa); - GUARD_AS_RESULT(size); + RESULT_GUARD_POSIX(size); *size_out = size; return S2N_RESULT_OK; @@ -69,7 +70,7 @@ static int s2n_rsa_sign(const struct s2n_pkey *priv, s2n_signature_algorithm sig case S2N_SIGNATURE_RSA_PSS_RSAE: return s2n_rsa_pss_sign(priv, digest, signature); default: - S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM); + POSIX_BAIL(S2N_ERR_INVALID_SIGNATURE_ALGORITHM); } return S2N_SUCCESS; @@ -84,7 +85,7 @@ static int s2n_rsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm si case S2N_SIGNATURE_RSA_PSS_RSAE: return s2n_rsa_pss_verify(pub, digest, signature); default: - S2N_ERROR(S2N_ERR_INVALID_SIGNATURE_ALGORITHM); + POSIX_BAIL(S2N_ERR_INVALID_SIGNATURE_ALGORITHM); } return S2N_SUCCESS; @@ -93,7 +94,7 @@ static int s2n_rsa_verify(const struct s2n_pkey *pub, s2n_signature_algorithm si static int s2n_rsa_encrypt(const struct s2n_pkey *pub, struct s2n_blob *in, struct s2n_blob *out) { uint32_t size = 0; - GUARD_AS_POSIX(s2n_rsa_encrypted_size(pub, &size)); + POSIX_GUARD_RESULT(s2n_rsa_encrypted_size(pub, &size)); S2N_ERROR_IF(out->size < size, S2N_ERR_NOMEM); const s2n_rsa_public_key *key = &pub->key.rsa_key; @@ -109,12 +110,12 @@ static int s2n_rsa_decrypt(const struct s2n_pkey *priv, struct s2n_blob *in, str unsigned char intermediate[ 4096 ]; uint32_t expected_size = 0; - GUARD_AS_POSIX(s2n_rsa_encrypted_size(priv, &expected_size)); + POSIX_GUARD_RESULT(s2n_rsa_encrypted_size(priv, &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)); + POSIX_GUARD_RESULT(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); @@ -134,13 +135,13 @@ static int s2n_rsa_keys_match(const struct s2n_pkey *pub, const struct s2n_pkey plain_in.size = sizeof(plain_inpad); enc.data = encpad; - GUARD_AS_POSIX(s2n_rsa_encrypted_size(pub, &enc.size)); - lte_check(enc.size, sizeof(encpad)); - GUARD(s2n_rsa_encrypt(pub, &plain_in, &enc)); + POSIX_GUARD_RESULT(s2n_rsa_encrypted_size(pub, &enc.size)); + POSIX_ENSURE_LTE(enc.size, sizeof(encpad)); + POSIX_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)); + POSIX_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); @@ -161,7 +162,7 @@ static int s2n_rsa_key_free(struct s2n_pkey *pkey) 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); + POSIX_ENSURE_REF(rsa_key->rsa); return 0; } @@ -193,6 +194,7 @@ int s2n_rsa_pkey_init(struct s2n_pkey *pkey) pkey->match = &s2n_rsa_keys_match; pkey->free = &s2n_rsa_key_free; pkey->check_key = &s2n_rsa_check_key_exists; + POSIX_GUARD_RESULT(s2n_evp_signing_set_pkey_overrides(pkey)); return 0; } diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa.h b/contrib/restricted/aws/s2n/crypto/s2n_rsa.h index 3d153eaf3d..3bba4ff863 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_rsa.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa.h @@ -16,7 +16,7 @@ #pragma once #include <stdint.h> -#include <s2n.h> +#include "api/s2n.h" #include <openssl/rsa.h> diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c index 98fbd6ad23..da034d6ad3 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.c @@ -21,6 +21,7 @@ #include "stuffer/s2n_stuffer.h" +#include "crypto/s2n_evp_signing.h" #include "crypto/s2n_hash.h" #include "crypto/s2n_openssl.h" #include "crypto/s2n_rsa.h" @@ -43,12 +44,12 @@ int s2n_is_rsa_pss_certs_supported() static S2N_RESULT s2n_rsa_pss_size(const struct s2n_pkey *key, uint32_t *size_out) { - ENSURE_REF(key); - ENSURE_REF(size_out); + RESULT_ENSURE_REF(key); + RESULT_ENSURE_REF(size_out); /* For more info, see: https://www.openssl.org/docs/man1.1.0/man3/EVP_PKEY_size.html */ const int size = EVP_PKEY_size(key->pkey); - GUARD_AS_RESULT(size); + RESULT_GUARD_POSIX(size); *size_out = size; return S2N_RESULT_OK; @@ -68,7 +69,7 @@ static int s2n_rsa_is_private_key(RSA *rsa_key) 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); + POSIX_ENSURE_REF(priv); sig_alg_check(sig_alg, S2N_SIGNATURE_RSA_PSS_PSS); /* Not Possible to Sign with Public Key */ @@ -80,7 +81,7 @@ int s2n_rsa_pss_key_sign(const struct s2n_pkey *priv, s2n_signature_algorithm si 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); + POSIX_ENSURE_REF(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. */ @@ -93,22 +94,22 @@ static int s2n_rsa_pss_validate_sign_verify_match(const struct s2n_pkey *pub, co { /* 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)); + POSIX_GUARD_RESULT(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)); + POSIX_GUARD(s2n_hash_new(&sign_hash)); + POSIX_GUARD(s2n_hash_new(&verify_hash)); + POSIX_GUARD(s2n_hash_init(&sign_hash, S2N_HASH_SHA256)); + POSIX_GUARD(s2n_hash_init(&verify_hash, S2N_HASH_SHA256)); + POSIX_GUARD(s2n_hash_update(&sign_hash, random_data.data, random_data.size)); + POSIX_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)); + POSIX_GUARD(s2n_rsa_pss_key_sign(priv, S2N_SIGNATURE_RSA_PSS_PSS, &sign_hash, &signature_data)); + POSIX_GUARD(s2n_rsa_pss_key_verify(pub, S2N_SIGNATURE_RSA_PSS_PSS, &verify_hash, &signature_data)); return 0; } @@ -124,11 +125,11 @@ static int s2n_rsa_validate_params_equal(const RSA *pub, const RSA *priv) 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); + POSIX_BAIL(S2N_ERR_KEY_CHECK); } if (pub_val_n == NULL || priv_val_n == NULL) { - S2N_ERROR(S2N_ERR_KEY_CHECK); + POSIX_BAIL(S2N_ERR_KEY_CHECK); } S2N_ERROR_IF(BN_cmp(pub_val_e, priv_val_e) != 0, S2N_ERR_KEY_MISMATCH); @@ -139,8 +140,8 @@ static int s2n_rsa_validate_params_equal(const RSA *pub, const RSA *priv) static int s2n_rsa_validate_params_match(const struct s2n_pkey *pub, const struct s2n_pkey *priv) { - notnull_check(pub); - notnull_check(priv); + POSIX_ENSURE_REF(pub); + POSIX_ENSURE_REF(priv); /* OpenSSL Documentation Links: * - https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_get0_RSA.html @@ -149,10 +150,10 @@ static int s2n_rsa_validate_params_match(const struct s2n_pkey *pub, const struc 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); + POSIX_ENSURE_REF(pub_rsa_key); + POSIX_ENSURE_REF(priv_rsa_key); - GUARD(s2n_rsa_validate_params_equal(pub_rsa_key, priv_rsa_key)); + POSIX_GUARD(s2n_rsa_validate_params_equal(pub_rsa_key, priv_rsa_key)); return 0; } @@ -160,15 +161,15 @@ static int s2n_rsa_validate_params_match(const struct s2n_pkey *pub, const struc 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); + POSIX_ENSURE_REF(pub); + POSIX_ENSURE_REF(pub->pkey); + POSIX_ENSURE_REF(priv); + POSIX_ENSURE_REF(priv->pkey); - GUARD(s2n_rsa_validate_params_match(pub, priv)); + POSIX_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)); + POSIX_GUARD(s2n_rsa_pss_validate_sign_verify_match(pub, priv)); return 0; } @@ -193,7 +194,7 @@ int s2n_evp_pkey_to_rsa_pss_public_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *pk 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); + POSIX_ENSURE_REF(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); @@ -201,7 +202,7 @@ int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *p /* 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); + POSIX_GUARD_OSSL(RSA_check_key(priv_rsa_key), S2N_ERR_KEY_CHECK); rsa_key->rsa = priv_rsa_key; return 0; @@ -209,7 +210,7 @@ int s2n_evp_pkey_to_rsa_pss_private_key(struct s2n_rsa_key *rsa_key, EVP_PKEY *p int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey) { - GUARD(s2n_rsa_pkey_init(pkey)); + POSIX_GUARD(s2n_rsa_pkey_init(pkey)); pkey->size = &s2n_rsa_pss_size; pkey->sign = &s2n_rsa_pss_key_sign; @@ -223,6 +224,7 @@ int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey) pkey->match = &s2n_rsa_pss_keys_match; pkey->free = &s2n_rsa_pss_key_free; + POSIX_GUARD_RESULT(s2n_evp_signing_set_pkey_overrides(pkey)); return 0; } @@ -230,17 +232,17 @@ int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey) 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); + POSIX_BAIL(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); + POSIX_BAIL(S2N_RSA_PSS_NOT_SUPPORTED); } int s2n_rsa_pss_pkey_init(struct s2n_pkey *pkey) { - S2N_ERROR(S2N_RSA_PSS_NOT_SUPPORTED); + POSIX_BAIL(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..82431986f3 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa_pss.h @@ -16,7 +16,8 @@ #pragma once #include <stdint.h> -#include <s2n.h> +#include "api/s2n.h" +#include <openssl/bn.h> #include "crypto/s2n_openssl.h" #include "crypto/s2n_rsa.h" diff --git a/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c b/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c index 313565380f..57a31172b7 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.c @@ -34,7 +34,8 @@ static int s2n_hash_alg_to_NID[] = { [S2N_HASH_SHA224] = NID_sha224, [S2N_HASH_SHA256] = NID_sha256, [S2N_HASH_SHA384] = NID_sha384, - [S2N_HASH_SHA512] = NID_sha512 }; + [S2N_HASH_SHA512] = NID_sha512 +}; int s2n_hash_NID_type(s2n_hash_algorithm alg, int *out) { @@ -48,46 +49,63 @@ int s2n_hash_NID_type(s2n_hash_algorithm alg, int *out) *out = s2n_hash_alg_to_NID[alg]; break; default: - S2N_ERROR(S2N_ERR_HASH_INVALID_ALGORITHM); + POSIX_BAIL(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) +int s2n_rsa_pkcs1v15_sign_digest(const struct s2n_pkey *priv, s2n_hash_algorithm hash_alg, + struct s2n_blob *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); + POSIX_ENSURE_REF(priv); + POSIX_ENSURE_REF(digest); + POSIX_ENSURE_REF(signature); - const s2n_rsa_private_key *key = &priv->key.rsa_key; + int NID_type = 0; + POSIX_GUARD(s2n_hash_NID_type(hash_alg, &NID_type)); - uint8_t digest_out[S2N_MAX_DIGEST_LEN]; - GUARD(s2n_hash_digest(digest, digest_out, digest_length)); + const s2n_rsa_private_key *key = &priv->key.rsa_key; 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); + POSIX_GUARD_OSSL(RSA_sign(NID_type, digest->data, digest->size, signature->data, &signature_size, key->rsa), S2N_ERR_SIGN); + POSIX_ENSURE(signature_size <= signature->size, S2N_ERR_SIZE_MISMATCH); signature->size = signature_size; - return 0; + return S2N_SUCCESS; +} + +int s2n_rsa_pkcs1v15_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature) +{ + POSIX_ENSURE_REF(digest); + + uint8_t digest_length = 0; + POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); + POSIX_ENSURE_LTE(digest_length, S2N_MAX_DIGEST_LEN); + + uint8_t digest_out[S2N_MAX_DIGEST_LEN] = { 0 }; + POSIX_GUARD(s2n_hash_digest(digest, digest_out, digest_length)); + + struct s2n_blob digest_blob = { 0 }; + POSIX_GUARD(s2n_blob_init(&digest_blob, digest_out, digest_length)); + POSIX_GUARD(s2n_rsa_pkcs1v15_sign_digest(priv, digest->alg, &digest_blob, signature)); + + return S2N_SUCCESS; } 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); + POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); + POSIX_GUARD(s2n_hash_NID_type(digest->alg, &digest_NID_type)); + POSIX_ENSURE_LTE(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)); + POSIX_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); + POSIX_GUARD_OSSL(RSA_verify(digest_NID_type, digest_out, digest_length, signature->data, signature->size, key->rsa), S2N_ERR_VERIFY_SIGNATURE); return 0; } @@ -100,33 +118,10 @@ int s2n_is_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); + POSIX_GUARD_OSSL(S2N_EVP_PKEY_CTX_set_signature_md(ctx, digest_alg), S2N_ERR_INVALID_SIGNATURE_ALGORITHM); + POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, (EVP_MD*) (uintptr_t) digest_alg), S2N_ERR_INVALID_SIGNATURE_ALGORITHM); return 0; } @@ -135,72 +130,94 @@ 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) +int s2n_rsa_pss_sign_digest(const struct s2n_pkey *priv, s2n_hash_algorithm hash_alg, + struct s2n_blob *digest_in, 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)); + POSIX_ENSURE_REF(priv); + POSIX_ENSURE_REF(digest_in); + POSIX_ENSURE_REF(signature_out); - const EVP_MD* digest_alg = s2n_hash_alg_to_evp_alg(digest->alg); - notnull_check(digest_alg); + const EVP_MD* digest_alg = s2n_hash_alg_to_evp_md(hash_alg); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_REF(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); + POSIX_GUARD_OSSL(EVP_PKEY_sign_init(ctx), S2N_ERR_SIGN); + POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_SIGN); + POSIX_GUARD(s2n_evp_pkey_ctx_set_rsa_signature_digest(ctx, digest_alg)); + POSIX_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); + POSIX_GUARD_OSSL(EVP_PKEY_sign(ctx, NULL, &signature_len, digest_in->data, digest_in->size), S2N_ERR_SIGN); + POSIX_ENSURE(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); + /* Actually sign the digest */ + POSIX_GUARD_OSSL(EVP_PKEY_sign(ctx, signature_out->data, &signature_len, digest_in->data, digest_in->size), S2N_ERR_SIGN); signature_out->size = signature_len; - return 0; + return S2N_SUCCESS; +} + +int s2n_rsa_pss_sign(const struct s2n_pkey *priv, struct s2n_hash_state *digest, struct s2n_blob *signature_out) +{ + POSIX_ENSURE_REF(digest); + + uint8_t digest_length = 0; + uint8_t digest_data[S2N_MAX_DIGEST_LEN] = { 0 }; + POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); + POSIX_GUARD(s2n_hash_digest(digest, digest_data, digest_length)); + + struct s2n_blob digest_blob = { 0 }; + POSIX_GUARD(s2n_blob_init(&digest_blob, digest_data, digest_length)); + POSIX_GUARD(s2n_rsa_pss_sign_digest(priv, digest->alg, &digest_blob, signature_out)); + + return S2N_SUCCESS; } int s2n_rsa_pss_verify(const struct s2n_pkey *pub, struct s2n_hash_state *digest, struct s2n_blob *signature_in) { - notnull_check(pub); + POSIX_ENSURE_REF(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); + POSIX_GUARD(s2n_hash_digest_size(digest->alg, &digest_length)); + POSIX_GUARD(s2n_hash_digest(digest, digest_data, digest_length)); + const EVP_MD* digest_alg = s2n_hash_alg_to_evp_md(digest->alg); + POSIX_ENSURE_REF(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); + POSIX_ENSURE_REF(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); + POSIX_GUARD_OSSL(EVP_PKEY_verify_init(ctx), S2N_ERR_VERIFY_SIGNATURE); + POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING), S2N_ERR_VERIFY_SIGNATURE); + POSIX_GUARD(s2n_evp_pkey_ctx_set_rsa_signature_digest(ctx, digest_alg)); + POSIX_GUARD_OSSL(EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, RSA_PSS_SALTLEN_DIGEST), S2N_ERR_VERIFY_SIGNATURE); - return 0; + POSIX_GUARD_OSSL(EVP_PKEY_verify(ctx, signature_in->data, signature_in->size, + digest_data, digest_length), S2N_ERR_VERIFY_SIGNATURE); + return S2N_SUCCESS; } #else +int s2n_rsa_pss_sign_digest(const struct s2n_pkey *priv, s2n_hash_algorithm hash_alg, + struct s2n_blob *digest_in, struct s2n_blob *signature_out) +{ + POSIX_BAIL(S2N_RSA_PSS_NOT_SUPPORTED); +} + 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); + POSIX_BAIL(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); + POSIX_BAIL(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..bf14928426 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_rsa_signing.h @@ -15,14 +15,14 @@ #pragma once -#include <s2n.h> +#include "api/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) +#if (S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 1) || defined(OPENSSL_IS_AWSLC)) && !defined(LIBRESSL_VERSION_NUMBER) && !defined(OPENSSL_IS_BORINGSSL) #define RSA_PSS_SIGNING_SUPPORTED 1 #else #define RSA_PSS_SIGNING_SUPPORTED 0 diff --git a/contrib/restricted/aws/s2n/crypto/s2n_sequence.c b/contrib/restricted/aws/s2n/crypto/s2n_sequence.c index 2211653817..611d7ac5b4 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_sequence.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_sequence.c @@ -25,7 +25,8 @@ int s2n_increment_sequence_number(struct s2n_blob *sequence_number) { - for (int i = sequence_number->size - 1; i >= 0; i--) { + for (uint32_t j = sequence_number->size; j > 0; j--) { + uint32_t i = j - 1; sequence_number->data[i] += 1; if (sequence_number->data[i]) { break; @@ -45,13 +46,13 @@ int s2n_increment_sequence_number(struct s2n_blob *sequence_number) int s2n_sequence_number_to_uint64(struct s2n_blob *sequence_number, uint64_t *output) { - notnull_check(sequence_number); + POSIX_ENSURE_REF(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; + for (uint32_t i = sequence_number->size; i > 0; i--) { + *output += ((uint64_t) sequence_number->data[i-1]) << shift; shift += SEQUENCE_NUMBER_POWER; } return S2N_SUCCESS; diff --git a/contrib/restricted/aws/s2n/crypto/s2n_signature.h b/contrib/restricted/aws/s2n/crypto/s2n_signature.h index 0206578a5a..b097e93afb 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_signature.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_signature.h @@ -16,14 +16,14 @@ #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) +#define sig_alg_check(a, b) do { if ( (a) != (b) ) { POSIX_BAIL(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, + S2N_SIGNATURE_ANONYMOUS = S2N_TLS_SIGNATURE_ANONYMOUS, + S2N_SIGNATURE_RSA = S2N_TLS_SIGNATURE_RSA, + S2N_SIGNATURE_ECDSA = S2N_TLS_SIGNATURE_ECDSA, /* Use Private Range for RSA PSS */ - S2N_SIGNATURE_RSA_PSS_RSAE = TLS_SIGNATURE_ALGORITHM_PRIVATE, + S2N_SIGNATURE_RSA_PSS_RSAE = S2N_TLS_SIGNATURE_RSA_PSS_RSAE, 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..6e4681782b 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_null.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_null.c @@ -30,7 +30,7 @@ static int s2n_stream_cipher_null_endecrypt(struct s2n_session_key *key, struct S2N_ERROR_IF(out->size < in->size, S2N_ERR_SIZE_MISMATCH); if (in->data != out->data) { - memcpy_check(out->data, in->data, out->size); + POSIX_CHECKED_MEMCPY(out->data, in->data, out->size); } return 0; } 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..9cc41ff677 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_stream_cipher_rc4.c @@ -28,10 +28,10 @@ static uint8_t s2n_stream_cipher_rc4_available() 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); + POSIX_ENSURE_GTE(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); + POSIX_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); @@ -40,10 +40,10 @@ static int s2n_stream_cipher_rc4_encrypt(struct s2n_session_key *key, struct s2n 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); + POSIX_ENSURE_GTE(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); + POSIX_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); @@ -52,16 +52,16 @@ static int s2n_stream_cipher_rc4_decrypt(struct s2n_session_key *key, struct s2n static int s2n_stream_cipher_rc4_set_encryption_key(struct s2n_session_key *key, struct s2n_blob *in) { - eq_check(in->size, 16); - GUARD_OSSL(EVP_EncryptInit_ex(key->evp_cipher_ctx, EVP_rc4(), NULL, in->data, NULL), S2N_ERR_KEY_INIT); + POSIX_ENSURE_EQ(in->size, 16); + POSIX_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); + POSIX_ENSURE_EQ(in->size, 16); + POSIX_GUARD_OSSL(EVP_DecryptInit_ex(key->evp_cipher_ctx, EVP_rc4(), NULL, in->data, NULL), S2N_ERR_KEY_INIT); return 0; } diff --git a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c index 1b472937ad..83d5e64951 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c +++ b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.c @@ -34,7 +34,7 @@ * when the relevant TLS 1.3 features are worked on. * * [x] binder_key - * [ ] client_early_traffic_secret + * [x] client_early_traffic_secret * [ ] early_exporter_master_secret * [x] client_handshake_traffic_secret * [x] server_handshake_traffic_secret @@ -94,35 +94,19 @@ 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); + POSIX_ENSURE_REF(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)); + POSIX_GUARD(s2n_hmac_hash_alg(alg, &keys->hash_algorithm)); + POSIX_GUARD(s2n_hash_digest_size(keys->hash_algorithm, &keys->size)); + POSIX_GUARD(s2n_blob_init(&keys->extract_secret, keys->extract_secret_bytes, keys->size)); + POSIX_GUARD(s2n_blob_init(&keys->derive_secret, keys->derive_secret_bytes, keys->size)); + POSIX_GUARD(s2n_hmac_new(&keys->hmac)); return 0; } @@ -131,169 +115,26 @@ int s2n_tls13_keys_init(struct s2n_tls13_keys *keys, s2n_hmac_algorithm alg) * Frees any allocation */ int s2n_tls13_keys_free(struct s2n_tls13_keys *keys) { - notnull_check(keys); + POSIX_ENSURE_REF(keys); - GUARD(s2n_hmac_free(&keys->hmac)); + POSIX_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, struct s2n_psk *psk) -{ - notnull_check(keys); - - /* Early Secret */ - if (psk == NULL) { - /* in 1-RTT, PSK is 0-filled of key length */ - s2n_tls13_key_blob(psk_ikm, keys->size); - - GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, &zero_length_blob, &psk_ikm, &keys->extract_secret)); - } else { - /* Sanity check that an early secret exists */ - ne_check(psk->early_secret.size, 0); - keys->extract_secret = psk->early_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 S2N_SUCCESS; -} - -/* - * 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); + POSIX_ENSURE_REF(keys); + POSIX_ENSURE_REF(secret); + POSIX_ENSURE_REF(key); + POSIX_ENSURE_REF(iv); - GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret, + POSIX_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, + POSIX_GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret, &s2n_tls13_label_traffic_secret_iv, &zero_length_blob, iv)); return 0; } @@ -304,7 +145,7 @@ int s2n_tls13_derive_traffic_keys(struct s2n_tls13_keys *keys, struct s2n_blob * */ 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)); + POSIX_GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, secret_key, &s2n_tls13_label_finished, &zero_length_blob, output_finish_key)); return 0; } @@ -316,18 +157,10 @@ int s2n_tls13_derive_finished_key(struct s2n_tls13_keys *keys, struct s2n_blob * */ 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; + POSIX_GUARD(s2n_hash_digest(hash_state, transcript_hash.data, transcript_hash.size)); + POSIX_GUARD(s2n_hkdf_extract(&keys->hmac, keys->hmac_algorithm, finished_key, &transcript_hash, finished_verify)); + return S2N_SUCCESS; } /* @@ -335,50 +168,26 @@ int s2n_tls13_calculate_finished_mac(struct s2n_tls13_keys *keys, struct s2n_blo */ 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); + POSIX_ENSURE_REF(keys); + POSIX_ENSURE_REF(old_secret); + POSIX_ENSURE_REF(new_secret); - GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, old_secret, + POSIX_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; } -int s2n_tls13_derive_resumption_master_secret(struct s2n_tls13_keys *keys, struct s2n_hash_state *hashes, struct s2n_blob *secret_blob) -{ - notnull_check(keys); - notnull_check(hashes); - notnull_check(secret_blob); - - /* Sanity check that input hash is of expected type */ - ENSURE_POSIX(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 master session resumption from master secret */ - GUARD(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, &keys->extract_secret, - &s2n_tls13_label_resumption_master_secret, &message_digest, secret_blob)); - - return S2N_SUCCESS; -} - S2N_RESULT s2n_tls13_derive_session_ticket_secret(struct s2n_tls13_keys *keys, struct s2n_blob *resumption_secret, struct s2n_blob *ticket_nonce, struct s2n_blob *secret_blob) { - ENSURE_REF(keys); - ENSURE_REF(resumption_secret); - ENSURE_REF(ticket_nonce); - ENSURE_REF(secret_blob); + RESULT_ENSURE_REF(keys); + RESULT_ENSURE_REF(resumption_secret); + RESULT_ENSURE_REF(ticket_nonce); + RESULT_ENSURE_REF(secret_blob); /* Derive session ticket secret from master session resumption secret */ - GUARD_AS_RESULT(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, resumption_secret, + RESULT_GUARD_POSIX(s2n_hkdf_expand_label(&keys->hmac, keys->hmac_algorithm, resumption_secret, &s2n_tls13_label_session_ticket_secret, ticket_nonce, secret_blob)); return S2N_RESULT_OK; diff --git a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h index cf4e6185f4..48ef1bf01a 100644 --- a/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h +++ b/contrib/restricted/aws/s2n/crypto/s2n_tls13_keys.h @@ -27,6 +27,12 @@ #include "utils/s2n_mem.h" #include "utils/s2n_safety.h" +/* Unlike TLS1.2 secrets, TLS1.3 secret lengths vary depending + * on the hash algorithm used to calculate them. + * We allocate enough space for the largest possible secret. + * At the moment, that is 48 bytes for S2N_HASH_SHA384 and + * matches the TLS1.2 secret length. + */ #define S2N_TLS13_SECRET_MAX_LEN SHA384_DIGEST_LENGTH struct s2n_tls13_keys { @@ -63,6 +69,8 @@ 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; +extern const struct s2n_blob s2n_tls13_label_finished; + /* Traffic secret labels */ extern const struct s2n_blob s2n_tls13_label_traffic_secret_key; @@ -73,21 +81,10 @@ extern const struct s2n_blob s2n_tls13_label_traffic_secret_iv; 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, struct s2n_psk *psk); -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); - -int s2n_tls13_derive_resumption_master_secret(struct s2n_tls13_keys *keys, struct s2n_hash_state *hashes, struct s2n_blob *secret_blob); S2N_RESULT s2n_tls13_derive_session_ticket_secret(struct s2n_tls13_keys *keys, struct s2n_blob *resumption_secret, struct s2n_blob *ticket_nonce, struct s2n_blob *secret_blob); |