Fix in-place decryption for EVP_chacha20_poly1305()
authortb <tb@openbsd.org>
Wed, 22 May 2024 14:02:08 +0000 (14:02 +0000)
committertb <tb@openbsd.org>
Wed, 22 May 2024 14:02:08 +0000 (14:02 +0000)
Take the MAC before clobbering the input value on decryption. Fixes hangs
during the QUIC handshake with HAProxy using TLS_CHACHA20_POLY1305_SHA256.

Found, issue pinpointed, and initial fix tested by Lucas Gabriel Vuotto:
Let me take this opportunity to thank the HAProxy team for going out of
their way to keep supporting LibreSSL. It's much appreciated.

See https://github.com/haproxy/haproxy/issues/2569

tweak/ok jsing

lib/libcrypto/evp/e_chacha20poly1305.c

index cc2e015..816a8aa 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: e_chacha20poly1305.c,v 1.35 2024/04/09 13:52:41 beck Exp $ */
+/* $OpenBSD: e_chacha20poly1305.c,v 1.36 2024/05/22 14:02:08 tb Exp $ */
 
 /*
  * Copyright (c) 2022 Joel Sing <jsing@openbsd.org>
@@ -493,6 +493,8 @@ chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
 
        /* Update with AD or plaintext/ciphertext. */
        if (in != NULL) {
+               if (!ctx->encrypt || out == NULL)
+                       CRYPTO_poly1305_update(&cpx->poly1305, in, len);
                if (out == NULL) {
                        cpx->ad_len += len;
                        cpx->in_ad = 1;
@@ -502,8 +504,6 @@ chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
                }
                if (ctx->encrypt && out != NULL)
                        CRYPTO_poly1305_update(&cpx->poly1305, out, len);
-               else
-                       CRYPTO_poly1305_update(&cpx->poly1305, in, len);
 
                return len;
        }