Package: libgnutls30
Version: 3.5.8-5+deb9u1
Severity: critical
Tags: patch
Justification: breaks unrelated software

Dear Maintainer,

   * What led up to the situation?

Unrelated gnome-terminal or xfce4-terminal crashing when significant output
(e.g. running 'yes'; apparently because of the corruption of the encrypted
scrollback buffer).

Issue noticed on a Cavium ThunderX running Debian Stretch.

   * What exactly did you do (or not do) that was effective (or
     ineffective)?

Patching libgnutls with
https://gitlab.com/gnutls/gnutls/commit/228b18dfbf934d8924d3305dc24d7b0162352eba
fixes the issue.

This fix is available in gnutls 3.5.13 (and testing+unstable) but not in 3.5.8
(stable). Please back-port the above patch to stable.

Upstream bug report: https://gitlab.com/gnutls/gnutls/issues/204

I marked it as 'critical' because it breaks unrelated packages, though I'm not
sure that's the appropriate severity level.

Thanks.



-- System Information:
Debian Release: 9.0
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: arm64 (aarch64)

Kernel: Linux 4.9.0-3-arm64 (SMP w/48 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8),
LANGUAGE=en_GB:en (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages libgnutls30 depends on:
ii  libc6        2.24-11+deb9u1
ii  libgmp10     2:6.1.2+dfsg-1
ii  libhogweed4  3.3-1+b1
ii  libidn11     1.33-1
ii  libnettle6   3.3-1+b1
ii  libp11-kit0  0.23.3-2
ii  libtasn1-6   4.10-1.1
ii  zlib1g       1:1.2.8.dfsg-5

libgnutls30 recommends no packages.

Versions of packages libgnutls30 suggests:
pn  gnutls-bin  <none>
diff --git a/lib/accelerated/aarch64/aes-gcm-aarch64.c 
b/lib/accelerated/aarch64/aes-gcm-aarch64.c
index c571d02..8d2bc1d 100644
--- a/lib/accelerated/aarch64/aes-gcm-aarch64.c
+++ b/lib/accelerated/aarch64/aes-gcm-aarch64.c
@@ -153,6 +153,27 @@ gcm_ghash(struct aes_gcm_ctx *ctx, const uint8_t * src, 
size_t src_size)
 }
 
 static void
+ctr32_encrypt_blocks_inplace(const unsigned char *in, unsigned char *out,
+                            size_t blocks, const AES_KEY *key,
+                            const unsigned char ivec[16])
+{
+       unsigned i;
+       uint8_t ctr[16];
+       uint8_t tmp[16];
+
+       memcpy(ctr, ivec, 16);
+
+       for (i=0;i<blocks;i++) {
+               aes_v8_encrypt(ctr, tmp, key);
+               memxor3(out, tmp, in, 16);
+
+               out += 16;
+               in += 16;
+               INCREMENT(16, ctr);
+       }
+}
+
+static void
 ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
                     size_t blocks, const AES_KEY *key,
                     const unsigned char ivec[16])
@@ -160,6 +181,9 @@ ctr32_encrypt_blocks(const unsigned char *in, unsigned char 
*out,
        unsigned i;
        uint8_t ctr[16];
 
+       if (in == out)
+               return ctr32_encrypt_blocks_inplace(in, out, blocks, key, ivec);
+
        memcpy(ctr, ivec, 16);
 
        for (i=0;i<blocks;i++) {
diff --git a/lib/accelerated/aarch64/aes-gcm-aarch64.c 
b/lib/accelerated/aarch64/aes-gcm-aarch64.c
index c571d02..8d2bc1d 100644
--- a/lib/accelerated/aarch64/aes-gcm-aarch64.c
+++ b/lib/accelerated/aarch64/aes-gcm-aarch64.c
@@ -153,6 +153,27 @@ gcm_ghash(struct aes_gcm_ctx *ctx, const uint8_t * src, 
size_t src_size)
 }
 
 static void
+ctr32_encrypt_blocks_inplace(const unsigned char *in, unsigned char *out,
+                            size_t blocks, const AES_KEY *key,
+                            const unsigned char ivec[16])
+{
+       unsigned i;
+       uint8_t ctr[16];
+       uint8_t tmp[16];
+
+       memcpy(ctr, ivec, 16);
+
+       for (i=0;i<blocks;i++) {
+               aes_v8_encrypt(ctr, tmp, key);
+               memxor3(out, tmp, in, 16);
+
+               out += 16;
+               in += 16;
+               INCREMENT(16, ctr);
+       }
+}
+
+static void
 ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
                     size_t blocks, const AES_KEY *key,
                     const unsigned char ivec[16])
@@ -160,6 +181,9 @@ ctr32_encrypt_blocks(const unsigned char *in, unsigned char 
*out,
        unsigned i;
        uint8_t ctr[16];
 
+       if (in == out)
+               return ctr32_encrypt_blocks_inplace(in, out, blocks, key, ivec);
+
        memcpy(ctr, ivec, 16);
 
        for (i=0;i<blocks;i++) {

Reply via email to