]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
aarch64: fix AES-GCM in-place encryption and decryption
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 22 May 2017 12:41:56 +0000 (14:41 +0200)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Mon, 22 May 2017 21:25:51 +0000 (23:25 +0200)
Resolves #204

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
lib/accelerated/aarch64/aes-gcm-aarch64.c

index c571d0294f4dc90cec452ac9422ccbfaa0a64537..8d2bc1dce2248cb2e72de69fd2f1001d306abcde 100644 (file)
@@ -152,6 +152,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,
@@ -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++) {