return EVP_aes_256_gcm();
#endif
-#if !defined(OPENSSL_IS_AWSLC) && (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x4000000fL)
+#if (!defined(LIBRESSL_VERSION_NUMBER) || LIBRESSL_VERSION_NUMBER >= 0x4000000fL)
/* WT: LibreSSL has an issue with CHACHA20 running in-place till 3.9.2
* included, but the fix is already identified and will be merged
* into next major version. Given that on machines without AES-NI
* Thanks to Theo Buehler for his help!
*/
case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
+# ifdef QUIC_AEAD_API
+ return EVP_aead_chacha20_poly1305();
+# else
return EVP_chacha20_poly1305();
+# endif
#endif
#if !defined(USE_OPENSSL_WOLFSSL) && !defined(OPENSSL_IS_AWSLC)
case TLS1_3_CK_AES_128_CCM_SHA256:
static inline const EVP_CIPHER *tls_hp(const SSL_CIPHER *cipher)
{
switch (SSL_CIPHER_get_id(cipher)) {
-#if !defined(OPENSSL_IS_AWSLC)
case TLS1_3_CK_CHACHA20_POLY1305_SHA256:
+#ifdef QUIC_AEAD_API
+ return EVP_CIPHER_CHACHA20;
+#else
return EVP_chacha20();
#endif
case TLS1_3_CK_AES_128_CCM_SHA256:
}
/* RX HP protection */
+#ifdef QUIC_AEAD_API
+ if (ctx->rx.hp_ctx != EVP_CIPHER_CTX_CHACHA20)
+ EVP_CIPHER_CTX_free(ctx->rx.hp_ctx);
+#else
EVP_CIPHER_CTX_free(ctx->rx.hp_ctx);
+#endif
/* RX AEAD decryption */
QUIC_AEAD_CTX_free(ctx->rx.ctx);
pool_free(pool_head_quic_tls_iv, ctx->rx.iv);
pool_free(pool_head_quic_tls_key, ctx->rx.key);
/* TX HP protection */
+#ifdef QUIC_AEAD_API
+ if (ctx->tx.hp_ctx != EVP_CIPHER_CTX_CHACHA20)
+ EVP_CIPHER_CTX_free(ctx->tx.hp_ctx);
+#else
EVP_CIPHER_CTX_free(ctx->tx.hp_ctx);
+#endif
/* TX AEAD encryption */
QUIC_AEAD_CTX_free(ctx->tx.ctx);
pool_free(pool_head_quic_tls_iv, ctx->tx.iv);
{
size_t aead_keylen = (size_t)QUIC_AEAD_key_length(aead);
size_t aead_ivlen = (size_t)QUIC_AEAD_iv_length(aead);
+#ifdef QUIC_AEAD_API
+ size_t hp_len = 0;
+
+ if (hp == EVP_CIPHER_CHACHA20)
+ hp_len = 32;
+ else if (hp)
+ hp_len = (size_t)EVP_CIPHER_key_length(hp);
+#else
size_t hp_len = hp ? (size_t)EVP_CIPHER_key_length(hp) : 0;
+#endif
if (aead_keylen > keylen || aead_ivlen > ivlen || hp_len > hp_keylen)
return 0;
{
EVP_CIPHER_CTX *ctx;
+#ifdef QUIC_AEAD_API
+
+ if (hp == EVP_CIPHER_CHACHA20) {
+ *hp_ctx = EVP_CIPHER_CTX_CHACHA20;
+ return 1;
+ }
+#endif
+
ctx = EVP_CIPHER_CTX_new();
if (!ctx)
return 0;
{
int ret = 0;
+#ifdef QUIC_AEAD_API
+
+ if (ctx == EVP_CIPHER_CTX_CHACHA20) {
+ uint32_t counter;
+ /* According to RFC 9001, 5.4.4. ChaCha20-Based Header Protection:
+ * The first 4 bytes of the sampled ciphertext are the block counter.
+ * The remaining 12 bytes are used as the nonce.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ counter = (uint32_t)in[0] + (uint32_t)(in[1] << 8) + (uint32_t)(in[2] << 16) + (uint32_t)(in[3] << 24);
+#else
+ memcpy(&counter, in, sizeof(counter));
+#endif
+ CRYPTO_chacha_20(out, out, inlen, key, in + sizeof(counter), counter);
+ return 1;
+ }
+
+#endif
+
if (!EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, in) ||
!EVP_EncryptUpdate(ctx, out, &ret, out, inlen) ||
!EVP_EncryptFinal_ex(ctx, out, &ret))
{
EVP_CIPHER_CTX *ctx;
+#ifdef QUIC_AEAD_API
+
+ if (hp == EVP_CIPHER_CHACHA20) {
+ *hp_ctx = EVP_CIPHER_CTX_CHACHA20;
+ return 1;
+ }
+#endif
+
ctx = EVP_CIPHER_CTX_new();
if (!ctx)
return 0;
{
int ret = 0;
+#ifdef QUIC_AEAD_API
+ if (ctx == EVP_CIPHER_CTX_CHACHA20) {
+ uint32_t counter;
+
+ /* According to RFC 9001, 5.4.4. ChaCha20-Based Header Protection:
+ * The first 4 bytes of the sampled ciphertext are the block counter.
+ * The remaining 12 bytes are used as the nonce.
+ */
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ counter = (uint32_t)in[0] + (uint32_t)(in[1] << 8) + (uint32_t)(in[2] << 16) + (uint32_t)(in[3] << 24);
+#else
+ memcpy(&counter, in, sizeof(counter));
+#endif
+ CRYPTO_chacha_20(out, out, inlen, key, in + sizeof(counter), counter);
+ return 1;
+ }
+
+#endif
+
if (!EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, in) ||
!EVP_DecryptUpdate(ctx, out, &ret, out, inlen) ||
!EVP_DecryptFinal_ex(ctx, out, &ret))