Bug#867581: libgnutls30: AES256-GCM emits all-zeros ciphertext on aarch64 with hardware acceleration (upstream bug report)

Catalin Marinas catalin.marinas at arm.com
Fri Jul 7 14:43:44 UTC 2017


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>
-------------- next part --------------
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++) {
-------------- next part --------------
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++) {


More information about the Pkg-gnutls-maint mailing list