[PATCH 3/4] Add x86 HW acceleration for GCM-SIV counter mode

Jussi Kivilinna jussi.kivilinna at iki.fi
Fri Aug 13 17:01:28 CEST 2021


* cipher/cipher-gcm-siv.c (do_ctr_le32): Use bulk function if
available.
* cipher/cipher-internal.h (cipher_bulk_ops): Add 'ctr32le_enc'.
* cipher/rijndael-aesni.c (_gcry_aes_aesni_ctr32le_enc): New.
* cipher/rijndael-vaes-avx2-amd64.S
(_gcry_vaes_avx2_ctr32le_enc_amd64, .Lle_addd_*): New.
* cipher/rijndael-vaes.c (_gcry_vaes_avx2_ctr32le_enc_amd64)
(_gcry_aes_vaes_ctr32le_enc): New.
* cipher/rijndael.c (_gcry_aes_aesni_ctr32le_enc)
(_gcry_aes_vaes_ctr32le_enc): New prototypes.
(do_setkey): Add setup of 'bulk_ops->ctr32le_enc' for AES-NI and
VAES.
* tests/basic.c (check_gcm_siv_cipher): Add large test-vector for
bulk ops testing.
--

Counter mode in GCM-SIV is little-endian on first 4 bytes of
of counter block, unlike regular CTR mode which works on
big-endian full block.

Benchmark on AMD Ryzen 7 5800X:

Before:
 AES            |  nanosecs/byte   mebibytes/sec   cycles/byte  auto Mhz
    GCM-SIV enc |      1.00 ns/B     953.2 MiB/s      4.85 c/B      4850
    GCM-SIV dec |      1.01 ns/B     940.1 MiB/s      4.92 c/B      4850
   GCM-SIV auth |     0.118 ns/B      8051 MiB/s     0.575 c/B      4850

After (~6x faster):
 AES            |  nanosecs/byte   mebibytes/sec   cycles/byte  auto Mhz
    GCM-SIV enc |     0.150 ns/B      6367 MiB/s     0.727 c/B      4850
    GCM-SIV dec |     0.161 ns/B      5909 MiB/s     0.783 c/B      4850
   GCM-SIV auth |     0.118 ns/B      8051 MiB/s     0.574 c/B      4850

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 cipher/cipher-gcm-siv.c           |  26 ++-
 cipher/cipher-internal.h          |   2 +
 cipher/rijndael-aesni.c           | 192 +++++++++++++++++
 cipher/rijndael-vaes-avx2-amd64.S | 328 ++++++++++++++++++++++++++++++
 cipher/rijndael-vaes.c            |  21 ++
 cipher/rijndael.c                 |  10 +-
 tests/basic.c                     | 139 +++++++++++++
 7 files changed, 708 insertions(+), 10 deletions(-)

diff --git a/cipher/cipher-gcm-siv.c b/cipher/cipher-gcm-siv.c
index b735d199..813cf579 100644
--- a/cipher/cipher-gcm-siv.c
+++ b/cipher/cipher-gcm-siv.c
@@ -178,12 +178,21 @@ do_ctr_le32 (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
   gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
   unsigned char tmp[GCRY_SIV_BLOCK_LEN];
   unsigned int burn = 0, nburn;
-  size_t n;
+  size_t nblocks;
 
   if (inbuflen == 0)
     return;
 
-  n = GCRY_SIV_BLOCK_LEN;
+  /* Use a bulk method if available.  */
+  nblocks = inbuflen / GCRY_SIV_BLOCK_LEN;
+  if (nblocks && c->bulk.ctr32le_enc)
+    {
+      c->bulk.ctr32le_enc (c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks);
+      inbuf  += nblocks * GCRY_SIV_BLOCK_LEN;
+      outbuf += nblocks * GCRY_SIV_BLOCK_LEN;
+      inbuflen -= nblocks * GCRY_SIV_BLOCK_LEN;
+    }
+
   do
     {
       nburn = enc_fn (c->context.c, tmp, c->u_ctr.ctr);
@@ -195,20 +204,19 @@ do_ctr_le32 (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
 	break;
       cipher_block_xor(outbuf, inbuf, tmp, GCRY_SIV_BLOCK_LEN);
 
-      inbuflen -= n;
-      outbuf += n;
-      inbuf += n;
+      inbuflen -= GCRY_SIV_BLOCK_LEN;
+      outbuf += GCRY_SIV_BLOCK_LEN;
+      inbuf += GCRY_SIV_BLOCK_LEN;
     }
   while (inbuflen);
 
   if (inbuflen)
     {
-      n = inbuflen;
       buf_xor(outbuf, inbuf, tmp, inbuflen);
 
-      inbuflen -= n;
-      outbuf += n;
-      inbuf += n;
+      outbuf += inbuflen;
+      inbuf += inbuflen;
+      inbuflen -= inbuflen;
     }
 
   wipememory (tmp, sizeof(tmp));
diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h
index 8b04cff7..0bc85b1a 100644
--- a/cipher/cipher-internal.h
+++ b/cipher/cipher-internal.h
@@ -157,6 +157,8 @@ typedef struct cipher_bulk_ops
 		  const void *inbuf_arg, size_t nblocks);
   void (*ctr_enc)(void *context, unsigned char *iv, void *outbuf_arg,
 		  const void *inbuf_arg, size_t nblocks);
+  void (*ctr32le_enc)(void *context, unsigned char *iv, void *outbuf_arg,
+		      const void *inbuf_arg, size_t nblocks);
   size_t (*ocb_crypt)(gcry_cipher_hd_t c, void *outbuf_arg,
 		      const void *inbuf_arg, size_t nblocks, int encrypt);
   size_t (*ocb_auth)(gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks);
diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c
index 9dde0489..34a4a447 100644
--- a/cipher/rijndael-aesni.c
+++ b/cipher/rijndael-aesni.c
@@ -1854,6 +1854,198 @@ _gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *ctr,
 }
 
 
+void ASM_FUNC_ATTR
+_gcry_aes_aesni_ctr32le_enc (RIJNDAEL_context *ctx, unsigned char *ctr,
+			     unsigned char *outbuf, const unsigned char *inbuf,
+			     size_t nblocks)
+{
+  static const byte le_addd_const[8][16] __attribute__ ((aligned (16))) =
+    {
+      { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+      { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+      { 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+      { 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+      { 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+      { 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+      { 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+      { 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+    };
+  aesni_prepare_2_7_variable;
+
+  aesni_prepare ();
+  aesni_prepare_2_7();
+
+  asm volatile ("movdqa %[ctr], %%xmm5\n\t"  /* Preload CTR */
+		: /* No output */
+		: [ctr] "m" (*ctr)
+		: "memory");
+
+#ifdef __x86_64__
+  if (nblocks >= 8)
+    {
+      aesni_prepare_8_15_variable;
+
+      aesni_prepare_8_15();
+
+      for ( ;nblocks >= 8 ; nblocks -= 8 )
+	{
+	  asm volatile
+	    ("movdqa (%[key]), %%xmm0\n\t"
+
+	     "movdqa %%xmm5,         %%xmm1\n\t" /* load input blocks */
+	     "movdqa %%xmm5,         %%xmm2\n\t"
+	     "movdqa %%xmm5,         %%xmm3\n\t"
+	     "movdqa %%xmm5,         %%xmm4\n\t"
+	     "movdqa %%xmm5,         %%xmm8\n\t"
+	     "movdqa %%xmm5,         %%xmm9\n\t"
+	     "movdqa %%xmm5,         %%xmm10\n\t"
+	     "movdqa %%xmm5,         %%xmm11\n\t"
+
+	     "paddd 0*16(%[addd]),   %%xmm2\n\t"
+	     "paddd 1*16(%[addd]),   %%xmm3\n\t"
+	     "paddd 2*16(%[addd]),   %%xmm4\n\t"
+	     "paddd 3*16(%[addd]),   %%xmm8\n\t"
+	     "paddd 4*16(%[addd]),   %%xmm9\n\t"
+	     "paddd 5*16(%[addd]),   %%xmm10\n\t"
+	     "paddd 6*16(%[addd]),   %%xmm11\n\t"
+
+	     "pxor   %%xmm0, %%xmm1\n\t"     /* xmm1 ^= key[0] */
+	     "pxor   %%xmm0, %%xmm2\n\t"     /* xmm2 ^= key[0] */
+	     "pxor   %%xmm0, %%xmm3\n\t"     /* xmm3 ^= key[0] */
+	     "pxor   %%xmm0, %%xmm4\n\t"     /* xmm4 ^= key[0] */
+	     "pxor   %%xmm0, %%xmm8\n\t"     /* xmm8 ^= key[0] */
+	     "pxor   %%xmm0, %%xmm9\n\t"     /* xmm9 ^= key[0] */
+	     "pxor   %%xmm0, %%xmm10\n\t"    /* xmm10 ^= key[0] */
+	     "pxor   %%xmm0, %%xmm11\n\t"    /* xmm11 ^= key[0] */
+
+	     "movdqu 0*16(%[inbuf]), %%xmm6\n\t"
+	     "movdqu 1*16(%[inbuf]), %%xmm7\n\t"
+	     "movdqu 2*16(%[inbuf]), %%xmm12\n\t"
+	     "movdqu 3*16(%[inbuf]), %%xmm13\n\t"
+	     "movdqu 4*16(%[inbuf]), %%xmm14\n\t"
+	     "movdqu 5*16(%[inbuf]), %%xmm15\n\t"
+
+	     "paddd 7*16(%[addd]),   %%xmm5\n\t"
+	     : /* No output */
+	     : [addd] "r" (&le_addd_const[0][0]),
+	       [inbuf] "r" (inbuf),
+	       [key] "r" (ctx->keyschenc)
+	     : "memory");
+
+	  do_aesni_enc_vec8 (ctx);
+
+	  asm volatile
+	    ("pxor %%xmm0, %%xmm6\n\t"
+	     "pxor %%xmm0, %%xmm7\n\t"
+	     "pxor %%xmm0, %%xmm12\n\t"
+	     "pxor %%xmm0, %%xmm13\n\t"
+	     "pxor %%xmm0, %%xmm14\n\t"
+	     "pxor %%xmm0, %%xmm15\n\t"
+	     "aesenclast %%xmm6, %%xmm1\n\t"
+	     "aesenclast %%xmm7, %%xmm2\n\t"
+	     "movdqu 6*16(%[inbuf]), %%xmm6\n\t"
+	     "movdqu 7*16(%[inbuf]), %%xmm7\n\t"
+	     "aesenclast %%xmm12, %%xmm3\n\t"
+	     "aesenclast %%xmm13, %%xmm4\n\t"
+	     "pxor %%xmm0, %%xmm6\n\t"
+	     "pxor %%xmm0, %%xmm7\n\t"
+	     "aesenclast %%xmm14, %%xmm8\n\t"
+	     "aesenclast %%xmm15, %%xmm9\n\t"
+	     "aesenclast %%xmm6, %%xmm10\n\t"
+	     "aesenclast %%xmm7, %%xmm11\n\t"
+	     "movdqu %%xmm1, 0*16(%[outbuf])\n\t"
+	     "movdqu %%xmm2, 1*16(%[outbuf])\n\t"
+	     "movdqu %%xmm3, 2*16(%[outbuf])\n\t"
+	     "movdqu %%xmm4, 3*16(%[outbuf])\n\t"
+	     "movdqu %%xmm8, 4*16(%[outbuf])\n\t"
+	     "movdqu %%xmm9, 5*16(%[outbuf])\n\t"
+	     "movdqu %%xmm10, 6*16(%[outbuf])\n\t"
+	     "movdqu %%xmm11, 7*16(%[outbuf])\n\t"
+	     : /* No output */
+	     : [inbuf] "r" (inbuf),
+	       [outbuf] "r" (outbuf)
+	     : "memory");
+
+	  outbuf += 8*BLOCKSIZE;
+	  inbuf  += 8*BLOCKSIZE;
+	}
+
+      aesni_cleanup_8_15();
+    }
+#endif
+
+  for ( ;nblocks >= 4 ; nblocks -= 4 )
+    {
+      asm volatile
+	("movdqa %%xmm5,         %%xmm1\n\t" /* load input blocks */
+	 "movdqa %%xmm5,         %%xmm2\n\t"
+	 "movdqa %%xmm5,         %%xmm3\n\t"
+	 "movdqa %%xmm5,         %%xmm4\n\t"
+	 "paddd 0*16(%[addd]),   %%xmm2\n\t"
+	 "paddd 1*16(%[addd]),   %%xmm3\n\t"
+	 "paddd 2*16(%[addd]),   %%xmm4\n\t"
+	 "paddd 3*16(%[addd]),   %%xmm5\n\t"
+	 "movdqu 0*16(%[inbuf]), %%xmm6\n\t"
+	 "movdqu 1*16(%[inbuf]), %%xmm7\n\t"
+	 : /* No output */
+	 : [addd] "r" (&le_addd_const[0][0]),
+	   [inbuf] "r" (inbuf)
+	 : "memory");
+
+      do_aesni_enc_vec4 (ctx);
+
+      asm volatile
+	("pxor %%xmm6, %%xmm1\n\t"
+	 "pxor %%xmm7, %%xmm2\n\t"
+	 "movdqu 2*16(%[inbuf]), %%xmm6\n\t"
+	 "movdqu 3*16(%[inbuf]), %%xmm7\n\t"
+	 "movdqu %%xmm1, 0*16(%[outbuf])\n\t"
+	 "movdqu %%xmm2, 1*16(%[outbuf])\n\t"
+	 "pxor %%xmm6, %%xmm3\n\t"
+	 "pxor %%xmm7, %%xmm4\n\t"
+	 "movdqu %%xmm3, 2*16(%[outbuf])\n\t"
+	 "movdqu %%xmm4, 3*16(%[outbuf])\n\t"
+	 : /* No output */
+	 : [inbuf] "r" (inbuf),
+	   [outbuf] "r" (outbuf)
+	 : "memory");
+
+      outbuf += 4*BLOCKSIZE;
+      inbuf  += 4*BLOCKSIZE;
+    }
+
+  for ( ;nblocks; nblocks-- )
+    {
+      asm volatile ("movdqa %%xmm5, %%xmm0\n\t"
+		    "paddd %[add_one], %%xmm5\n\t"
+		    "movdqu %[inbuf], %%xmm6\n\t"
+		    :
+		    : [add_one] "m" (*le_addd_const[0]),
+		      [inbuf] "m" (*inbuf)
+		    : "memory" );
+
+      do_aesni_enc (ctx);
+
+      asm volatile ("pxor %%xmm0, %%xmm6\n\t"
+		    "movdqu %%xmm6, %[outbuf]\n\t"
+		    : [outbuf] "=m" (*outbuf)
+		    :
+		    : "memory" );
+
+      outbuf += BLOCKSIZE;
+      inbuf  += BLOCKSIZE;
+    }
+
+  asm volatile ("movdqa %%xmm5, %[ctr]\n\t"
+                : [ctr] "=m" (*ctr)
+                :
+                : "memory" );
+
+  aesni_cleanup ();
+  aesni_cleanup_2_7 ();
+}
+
+
 unsigned int ASM_FUNC_ATTR
 _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst,
                          const unsigned char *src)
diff --git a/cipher/rijndael-vaes-avx2-amd64.S b/cipher/rijndael-vaes-avx2-amd64.S
index c4deea9b..d4ecf59f 100644
--- a/cipher/rijndael-vaes-avx2-amd64.S
+++ b/cipher/rijndael-vaes-avx2-amd64.S
@@ -1107,6 +1107,290 @@ _gcry_vaes_avx2_ctr_enc_amd64:
 	CFI_ENDPROC();
 ELF(.size _gcry_vaes_avx2_ctr_enc_amd64,.-_gcry_vaes_avx2_ctr_enc_amd64)
 
+/**********************************************************************
+  Little-endian 32-bit CTR-mode encryption (GCM-SIV)
+ **********************************************************************/
+ELF(.type _gcry_vaes_avx2_ctr32le_enc_amd64, at function)
+.globl _gcry_vaes_avx2_ctr32le_enc_amd64
+_gcry_vaes_avx2_ctr32le_enc_amd64:
+	/* input:
+	 *	%rdi: round keys
+	 *	%rsi: counter
+	 *	%rdx: dst
+	 *	%rcx: src
+	 *	%r8:  nblocks
+	 *	%r9:  nrounds
+	 */
+	CFI_STARTPROC();
+
+	vbroadcasti128 (%rsi), %ymm15; // CTR
+
+	/* Process 16 blocks per loop. */
+.align 8
+.Lctr32le_enc_blk16:
+	cmpq $16, %r8;
+	jb .Lctr32le_enc_blk8;
+
+	leaq -16(%r8), %r8;
+
+	vbroadcasti128 (0 * 16)(%rdi), %ymm8;
+
+	/* Increment counters. */
+	vpaddd .Lle_addd_0 rRIP, %ymm15, %ymm0;
+	vpaddd .Lle_addd_2 rRIP, %ymm15, %ymm1;
+	vpaddd .Lle_addd_4 rRIP, %ymm15, %ymm2;
+	vpaddd .Lle_addd_6 rRIP, %ymm15, %ymm3;
+	vpaddd .Lle_addd_8 rRIP, %ymm15, %ymm4;
+	vpaddd .Lle_addd_10 rRIP, %ymm15, %ymm5;
+	vpaddd .Lle_addd_12 rRIP, %ymm15, %ymm6;
+	vpaddd .Lle_addd_14 rRIP, %ymm15, %ymm7;
+
+	vpaddd .Lle_addd_16_2 rRIP, %ymm15, %ymm15;
+
+	/* AES rounds */
+	XOR8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (1 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (2 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (3 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (4 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (5 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (6 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (7 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (8 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (9 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (10 * 16)(%rdi), %ymm8;
+	cmpl $12, %r9d;
+	jb .Lctr32le_enc_blk16_last;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (11 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (12 * 16)(%rdi), %ymm8;
+	jz .Lctr32le_enc_blk16_last;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (13 * 16)(%rdi), %ymm8;
+	VAESENC8(%ymm8, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7);
+	vbroadcasti128 (14 * 16)(%rdi), %ymm8;
+
+	/* Last round and output handling. */
+  .Lctr32le_enc_blk16_last:
+	vpxor (0 * 16)(%rcx), %ymm8, %ymm9; /* Xor src to last round key. */
+	vpxor (2 * 16)(%rcx), %ymm8, %ymm10;
+	vpxor (4 * 16)(%rcx), %ymm8, %ymm11;
+	vpxor (6 * 16)(%rcx), %ymm8, %ymm12;
+	vaesenclast %ymm9, %ymm0, %ymm0;
+	vaesenclast %ymm10, %ymm1, %ymm1;
+	vaesenclast %ymm11, %ymm2, %ymm2;
+	vaesenclast %ymm12, %ymm3, %ymm3;
+	vpxor (8 * 16)(%rcx), %ymm8, %ymm9;
+	vpxor (10 * 16)(%rcx), %ymm8, %ymm10;
+	vpxor (12 * 16)(%rcx), %ymm8, %ymm11;
+	vpxor (14 * 16)(%rcx), %ymm8, %ymm8;
+	leaq (16 * 16)(%rcx), %rcx;
+	vaesenclast %ymm9, %ymm4, %ymm4;
+	vaesenclast %ymm10, %ymm5, %ymm5;
+	vaesenclast %ymm11, %ymm6, %ymm6;
+	vaesenclast %ymm8, %ymm7, %ymm7;
+	vmovdqu %ymm0, (0 * 16)(%rdx);
+	vmovdqu %ymm1, (2 * 16)(%rdx);
+	vmovdqu %ymm2, (4 * 16)(%rdx);
+	vmovdqu %ymm3, (6 * 16)(%rdx);
+	vmovdqu %ymm4, (8 * 16)(%rdx);
+	vmovdqu %ymm5, (10 * 16)(%rdx);
+	vmovdqu %ymm6, (12 * 16)(%rdx);
+	vmovdqu %ymm7, (14 * 16)(%rdx);
+	leaq (16 * 16)(%rdx), %rdx;
+
+	jmp .Lctr32le_enc_blk16;
+
+	/* Handle trailing eight blocks. */
+.align 8
+.Lctr32le_enc_blk8:
+	cmpq $8, %r8;
+	jb .Lctr32le_enc_blk4;
+
+	leaq -8(%r8), %r8;
+
+	vbroadcasti128 (0 * 16)(%rdi), %ymm4;
+
+	/* Increment counters. */
+	vpaddd .Lle_addd_0 rRIP, %ymm15, %ymm0;
+	vpaddd .Lle_addd_2 rRIP, %ymm15, %ymm1;
+	vpaddd .Lle_addd_4 rRIP, %ymm15, %ymm2;
+	vpaddd .Lle_addd_6 rRIP, %ymm15, %ymm3;
+
+	vpaddd .Lle_addd_8_2 rRIP, %ymm15, %ymm15;
+
+	/* AES rounds */
+	XOR4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (1 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (2 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (3 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (4 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (5 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (6 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (7 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (8 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (9 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (10 * 16)(%rdi), %ymm4;
+	cmpl $12, %r9d;
+	jb .Lctr32le_enc_blk8_last;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (11 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (12 * 16)(%rdi), %ymm4;
+	jz .Lctr32le_enc_blk8_last;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (13 * 16)(%rdi), %ymm4;
+	VAESENC4(%ymm4, %ymm0, %ymm1, %ymm2, %ymm3);
+	vbroadcasti128 (14 * 16)(%rdi), %ymm4;
+
+	/* Last round and output handling. */
+  .Lctr32le_enc_blk8_last:
+	vpxor (0 * 16)(%rcx), %ymm4, %ymm5; /* Xor src to last round key. */
+	vpxor (2 * 16)(%rcx), %ymm4, %ymm6;
+	vpxor (4 * 16)(%rcx), %ymm4, %ymm7;
+	vpxor (6 * 16)(%rcx), %ymm4, %ymm4;
+	leaq (8 * 16)(%rcx), %rcx;
+	vaesenclast %ymm5, %ymm0, %ymm0;
+	vaesenclast %ymm6, %ymm1, %ymm1;
+	vaesenclast %ymm7, %ymm2, %ymm2;
+	vaesenclast %ymm4, %ymm3, %ymm3;
+	vmovdqu %ymm0, (0 * 16)(%rdx);
+	vmovdqu %ymm1, (2 * 16)(%rdx);
+	vmovdqu %ymm2, (4 * 16)(%rdx);
+	vmovdqu %ymm3, (6 * 16)(%rdx);
+	leaq (8 * 16)(%rdx), %rdx;
+
+	/* Handle trailing four blocks. */
+.align 8
+.Lctr32le_enc_blk4:
+	cmpq $4, %r8;
+	jb .Lctr32le_enc_blk1;
+
+	leaq -4(%r8), %r8;
+
+	vbroadcasti128 (0 * 16)(%rdi), %ymm4;
+
+	/* Increment counters. */
+	vpaddd .Lle_addd_0 rRIP, %ymm15, %ymm0;
+	vpaddd .Lle_addd_2 rRIP, %ymm15, %ymm1;
+
+	vpaddd .Lle_addd_4_2 rRIP, %ymm15, %ymm15;
+
+	/* AES rounds */
+	XOR2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (1 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (2 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (3 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (4 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (5 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (6 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (7 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (8 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (9 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (10 * 16)(%rdi), %ymm4;
+	cmpl $12, %r9d;
+	jb .Lctr32le_enc_blk4_last;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (11 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (12 * 16)(%rdi), %ymm4;
+	jz .Lctr32le_enc_blk4_last;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (13 * 16)(%rdi), %ymm4;
+	VAESENC2(%ymm4, %ymm0, %ymm1);
+	vbroadcasti128 (14 * 16)(%rdi), %ymm4;
+
+	/* Last round and output handling. */
+  .Lctr32le_enc_blk4_last:
+	vpxor (0 * 16)(%rcx), %ymm4, %ymm5; /* Xor src to last round key. */
+	vpxor (2 * 16)(%rcx), %ymm4, %ymm6;
+	leaq (4 * 16)(%rcx), %rcx;
+	vaesenclast %ymm5, %ymm0, %ymm0;
+	vaesenclast %ymm6, %ymm1, %ymm1;
+	vmovdqu %ymm0, (0 * 16)(%rdx);
+	vmovdqu %ymm1, (2 * 16)(%rdx);
+	leaq (4 * 16)(%rdx), %rdx;
+
+	/* Process trailing one to three blocks, one per loop. */
+.align 8
+.Lctr32le_enc_blk1:
+	cmpq $1, %r8;
+	jb .Ldone_ctr32le_enc;
+
+	leaq -1(%r8), %r8;
+
+	/* Load and increament counter. */
+	vmovdqu %xmm15, %xmm0;
+	vpaddd .Lle_addd_1 rRIP, %xmm15, %xmm15;
+
+	/* AES rounds. */
+	vpxor (0 * 16)(%rdi), %xmm0, %xmm0;
+	vaesenc (1 * 16)(%rdi), %xmm0, %xmm0;
+	vaesenc (2 * 16)(%rdi), %xmm0, %xmm0;
+	vaesenc (3 * 16)(%rdi), %xmm0, %xmm0;
+	vaesenc (4 * 16)(%rdi), %xmm0, %xmm0;
+	vaesenc (5 * 16)(%rdi), %xmm0, %xmm0;
+	vaesenc (6 * 16)(%rdi), %xmm0, %xmm0;
+	vaesenc (7 * 16)(%rdi), %xmm0, %xmm0;
+	vaesenc (8 * 16)(%rdi), %xmm0, %xmm0;
+	vaesenc (9 * 16)(%rdi), %xmm0, %xmm0;
+	vmovdqa (10 * 16)(%rdi), %xmm1;
+	cmpl $12, %r9d;
+	jb .Lctr32le_enc_blk1_last;
+	vaesenc %xmm1, %xmm0, %xmm0;
+	vaesenc (11 * 16)(%rdi), %xmm0, %xmm0;
+	vmovdqa (12 * 16)(%rdi), %xmm1;
+	jz .Lctr32le_enc_blk1_last;
+	vaesenc %xmm1, %xmm0, %xmm0;
+	vaesenc (13 * 16)(%rdi), %xmm0, %xmm0;
+	vmovdqa (14 * 16)(%rdi), %xmm1;
+
+	/* Last round and output handling. */
+  .Lctr32le_enc_blk1_last:
+	vpxor (%rcx), %xmm1, %xmm1; /* Xor src to last round key. */
+	leaq 16(%rcx), %rcx;
+	vaesenclast %xmm1, %xmm0, %xmm0; /* Last round and xor with xmm1. */
+	vmovdqu %xmm0, (%rdx);
+	leaq 16(%rdx), %rdx;
+
+	jmp .Lctr32le_enc_blk1;
+
+.align 8
+.Ldone_ctr32le_enc:
+	vmovdqu %xmm15, (%rsi);
+	vzeroall;
+	ret
+	CFI_ENDPROC();
+ELF(.size _gcry_vaes_avx2_ctr32le_enc_amd64,.-_gcry_vaes_avx2_ctr32le_enc_amd64)
+
 /**********************************************************************
   OCB-mode encryption/decryption
  **********************************************************************/
@@ -2677,6 +2961,50 @@ _gcry_vaes_consts:
 	.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14
 .Lbige_addb_15:
 	.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15
+
+.Lle_addd_0:
+	.byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_1:
+	.byte 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_2:
+	.byte 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_3:
+	.byte 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_4:
+	.byte 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_5:
+	.byte 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_6:
+	.byte 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_7:
+	.byte 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_8:
+	.byte 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_9:
+	.byte 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_10:
+	.byte 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_11:
+	.byte 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_12:
+	.byte 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_13:
+	.byte 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_14:
+	.byte 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_15:
+	.byte 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+
+.Lle_addd_4_2:
+	.byte 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	.byte 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_8_2:
+	.byte 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	.byte 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+.Lle_addd_16_2:
+	.byte 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	.byte 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+
 .Lxts_gfmul_clmul:
 	.long 0x00, 0x87, 0x00, 0x00
 	.long 0x00, 0x87, 0x00, 0x00
diff --git a/cipher/rijndael-vaes.c b/cipher/rijndael-vaes.c
index 56afce17..0d7d1367 100644
--- a/cipher/rijndael-vaes.c
+++ b/cipher/rijndael-vaes.c
@@ -65,6 +65,14 @@ extern void _gcry_vaes_avx2_ctr_enc_amd64 (const void *keysched,
 					   size_t nblocks,
 					   unsigned int nrounds) ASM_FUNC_ABI;
 
+extern void _gcry_vaes_avx2_ctr32le_enc_amd64 (const void *keysched,
+					       unsigned char *ctr,
+					       void *outbuf_arg,
+					       const void *inbuf_arg,
+					       size_t nblocks,
+					       unsigned int nrounds)
+						ASM_FUNC_ABI;
+
 extern void _gcry_vaes_avx2_ocb_crypt_amd64 (const void *keysched,
 					     unsigned int blkn,
 					     void *outbuf_arg,
@@ -127,6 +135,19 @@ _gcry_aes_vaes_ctr_enc (void *context, unsigned char *iv,
   _gcry_vaes_avx2_ctr_enc_amd64 (keysched, iv, outbuf, inbuf, nblocks, nrounds);
 }
 
+void
+_gcry_aes_vaes_ctr32le_enc (void *context, unsigned char *iv,
+			    void *outbuf, const void *inbuf,
+			    size_t nblocks)
+{
+  RIJNDAEL_context *ctx = context;
+  const void *keysched = ctx->keyschenc32;
+  unsigned int nrounds = ctx->rounds;
+
+  _gcry_vaes_avx2_ctr32le_enc_amd64 (keysched, iv, outbuf, inbuf, nblocks,
+				     nrounds);
+}
+
 size_t
 _gcry_aes_vaes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
 			  const void *inbuf_arg, size_t nblocks,
diff --git a/cipher/rijndael.c b/cipher/rijndael.c
index 8df9aac3..c096321f 100644
--- a/cipher/rijndael.c
+++ b/cipher/rijndael.c
@@ -86,6 +86,9 @@ extern void _gcry_aes_aesni_cbc_enc (void *context, unsigned char *iv,
 extern void _gcry_aes_aesni_ctr_enc (void *context, unsigned char *ctr,
                                      void *outbuf_arg, const void *inbuf_arg,
                                      size_t nblocks);
+extern void _gcry_aes_aesni_ctr32le_enc (void *context, unsigned char *ctr,
+					 void *outbuf_arg,
+					 const void *inbuf_arg, size_t nblocks);
 extern void _gcry_aes_aesni_cfb_dec (void *context, unsigned char *iv,
                                      void *outbuf_arg, const void *inbuf_arg,
                                      size_t nblocks);
@@ -114,6 +117,9 @@ extern void _gcry_aes_vaes_cbc_dec (void *context, unsigned char *iv,
 extern void _gcry_aes_vaes_ctr_enc (void *context, unsigned char *ctr,
 				    void *outbuf_arg, const void *inbuf_arg,
 				    size_t nblocks);
+extern void _gcry_aes_vaes_ctr32le_enc (void *context, unsigned char *ctr,
+					void *outbuf_arg, const void *inbuf_arg,
+					size_t nblocks);
 extern size_t _gcry_aes_vaes_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg,
 					const void *inbuf_arg, size_t nblocks,
 					int encrypt);
@@ -497,6 +503,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen,
       bulk_ops->cbc_enc = _gcry_aes_aesni_cbc_enc;
       bulk_ops->cbc_dec = _gcry_aes_aesni_cbc_dec;
       bulk_ops->ctr_enc = _gcry_aes_aesni_ctr_enc;
+      bulk_ops->ctr32le_enc = _gcry_aes_aesni_ctr32le_enc;
       bulk_ops->ocb_crypt = _gcry_aes_aesni_ocb_crypt;
       bulk_ops->ocb_auth = _gcry_aes_aesni_ocb_auth;
       bulk_ops->xts_crypt = _gcry_aes_aesni_xts_crypt;
@@ -509,6 +516,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen,
 	  bulk_ops->cfb_dec = _gcry_aes_vaes_cfb_dec;
 	  bulk_ops->cbc_dec = _gcry_aes_vaes_cbc_dec;
 	  bulk_ops->ctr_enc = _gcry_aes_vaes_ctr_enc;
+	  bulk_ops->ctr32le_enc = _gcry_aes_vaes_ctr32le_enc;
 	  bulk_ops->ocb_crypt = _gcry_aes_vaes_ocb_crypt;
 	  bulk_ops->xts_crypt = _gcry_aes_vaes_xts_crypt;
 	}
@@ -516,7 +524,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen,
     }
 #endif
 #ifdef USE_PADLOCK
-  else if (hwfeatures & HWF_PADLOCK_AES && keylen == 128/8)
+  else if ((hwfeatures & HWF_PADLOCK_AES) && keylen == 128/8)
     {
       ctx->encrypt_fn = _gcry_aes_padlock_encrypt;
       ctx->decrypt_fn = _gcry_aes_padlock_decrypt;
diff --git a/tests/basic.c b/tests/basic.c
index 148aaec6..4ce90165 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -5916,6 +5916,145 @@ check_gcm_siv_cipher (void)
 	"\x18\xce\x4f\x0b\x8c\xb4\xd0\xca\xc6\x5f\xea\x8f\x79\x25\x7b\x20"
 	"\x88\x8e\x53\xe7\x22\x99\xe5\x6d",
 	"\xff\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+      },
+      /* Large block testing */
+      {
+	GCRY_CIPHER_AES128,
+	"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+	"\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+	"\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+	"",
+	0,
+	"\x72\x94\x7b\x5d\x3c\x14\xc0\xa6\x27\x8d\x8d\xee\xbd\xe8\x8c\x6a"
+	"\x21\x34\xce\x64\x8f\x01\x01\xc6\xe4\x5d\xed\x2e\xb9\xec\xac\x53"
+	"\xf2\x07\xed\x60\xc8\xa2\x2f\x2e\x83\x0e\xf2\xbc\x42\x51\x24\x3b"
+	"\x41\x4f\x26\x84\xf0\x25\x69\x3f\x38\x29\xfb\xe9\xbb\x1a\x94\xd1"
+	"\x94\x0c\xce\xad\x8e\x66\xeb\xda\xc9\x1c\x72\x5a\x7f\x95\x4f\x9c"
+	"\x02\x27\x79\x8f\xe7\x51\x51\x3d\x1e\x2c\x4e\xcd\x07\xe5\xd1\xf0"
+	"\x6c\x95\x82\x37\x00\x50\x5e\xff\x82\xfb\x69\x0b\x4e\x7f\x10\x12"
+	"\x7d\x18\x7f\xa8\x88\x59\xfb\x55\x9b\x70\x36\xfc\xde\x75\xed\x77"
+	"\xf9\x09\x87\x29\x30\x7c\x81\x41\x12\xc2\xbd\xcd\x9f\x86\x98\x38"
+	"\x96\x44\x4c\xda\x2e\xbe\x7a\xfb\xdd\x4a\x4e\xa0\x84\x94\xd5\x76"
+	"\xa6\xae\x02\xcb\x1b\xd4\xd8\xcb\xa5\x24\x28\xe1\x3c\x1e\xdc\x3d"
+	"\x25\x50\xe7\xfb\x92\xad\xd9\x80\x33\xe0\xb2\x50\x07\xd4\x43\x40"
+	"\x41\x63\x98\x63\xa6\x1a\xfc\x56\x84\x3f\xf7\x4f\x31\xe7\xfe\xc5"
+	"\x73\x52\xfd\x6d\x9b\xbb\x9b\xf8\x19\xf8\xdc\x9f\x3a\x88\xa6\x7c"
+	"\xf3\x6b\xbe\xde\xda\x05\x2e\x79\x54\xb9\x3e\x59\x43\x0a\x1b\x16"
+	"\xcf\x94\x97\x71\x03\x74\x12\x37\xaf\xd4\x0a\x4b\x30\x16\x9b\x8b"
+	"\x9f\xae\x78\x46\x83\xde\x34\xc5\x31\x71\x67\x5e\xdb\x8d\x93\x71"
+	"\x90\x03\x72\x00\x9f\x4e\x1e\x7d\xf3\x3f\xf8\x31\xe7\xf6\xb4\x6d"
+	"\x8d\xdc\xa0\x85\x32\x7b\x32\x40\x8c\xa9\x90\x69\xac\x03\xdb\xd4"
+	"\xa5\x62\x9c\xfd\x78\xde\xc8\x4a\x18\x67\xa0\xee\x5e\x1e\xad\x1a"
+	"\x1c\xee\x78\xbd\xea\xdc\xc8\x34\xd1\x92\x20\xa7\x0d\x12\x90\x88"
+	"\x91\xe4\x6c\x3c\x06\x78\x13\x00\xdc\xc7\x3e\xd7\x91\xf7\xc1\xd6"
+	"\x5a\x99\x95\x23\xb5\xd8\x3d\x0f\x12\xaf\x25\xd8\xcf\xe8\x27\x7f"
+	"\xbc\x7c\xe2\xad\x34\x66\x7f\xfb\xf5\xa8\x11\xc1\xe6\x04\x37\x41"
+	"\xaf\x96\xb3\xb7\xee\x05\xf5\xd7\x7c\xc6\xfe\x2e\xa9\x07\x47\x08"
+	"\xa4\x50\x65\xc0\x2e\xd7\x27\xd8\x70\x8c\xf1\x12\x30\x4a\x82\xf6"
+	"\xb7\x68\xdb\x9d\x73\xc2\x82\x3d\x44\xda\xfb\xdd\x03\xc1\xdc\xfc"
+	"\x3f\x7f\x2e\xe2\xd3\x73\x24\xaf\xd1\x35\xa9\x4f\x3a\xad\x9d\x5c"
+	"\xd7\xc6\xa3\xb1\x11\xf1\xbb\xa0\x23\xe1\x22\x88\x5b\x10\xb3\xd6"
+	"\x01\x78\x5f\x9e\x4d\x96\x7b\xeb\x81\x6b\xce\x2d\xf5\x6a\xd1\xa8"
+	"\xb7\x56\xdd\xd0\x4b\xb0\xc9\x64\x7a\x2f\x63\xcb\xd6\x61\x84\x4b"
+	"\x9e\x4d\x0b\x2c\x99\xbc\xa2\x94\xf5\x07\x20\xe6\xe9\xc2\xd2\xa6"
+	"\x1c\x37\xd5\x88\x01\x71\xe2\x16\xcd\x10\x7a\x07\x8b\xf3\xb5\x49"
+	"\x75\xbe\x0b\xe1\xb2\x28\x15\x88\x2b\xb4\xee\x34\xfd\x67\x30\xd8"
+	"\xdc\x38\x90\x66\xb6\x51\x90\xb3\xdb\xee\x4e\x66\xc3\x05\xdf\xee"
+	"\x32\xac\x8b\xa2\x00\xcc\xff\xa2\x52\x19\x79\x7e\x6c\xc9\x68\xb2"
+	"\xab\xe4\x69\x11\xea\x00\xc9\x2b\x58\x77\x8b\x6c\x28\x0e\x40\x42"
+	"\xcc\xa7\xb2\x58\xed\x5e\x0b\x19\x49\xe5\x5e\xb1\xb5\x24\x61\x63"
+	"\x7d\x5b\x6a\x7d\x3d\xc1\x6e\x09\x64\x43\x66\x31\x3c\xb0\x26\x2e"
+	"\xc8\x27\xf6\x5a\x5f\x22\x94\x42\x62\x2a\xf6\x5a\x7d\xc2\x4a\x0d"
+	"\xd2\xad\xaa\x0e\xb2\xa4\x29\x1c\xb8\x3b\xaa\xc9\x1d\x1a\x30\xf8"
+	"\x0b\x35\xb2\x84\x75\xc3\x08\x0c\xe5\x36\xa9\xff\xfe\xb9\xc2\xb7"
+	"\x51\xab\x2d\x9d\x3e\x1c\x08\x8c\x6c\x64\xe1\xd9\x97\xf4\xfc\x4d"
+	"\x77\x6d\x0e\xce\x73\x0b\x7f\x57\x41\xed\xdf\x96\x11\xb3\xcc\x61"
+	"\xe8\x12\x31\x16\x72\x4c\x10\xd4\x52\x14\x4c\x83\xaa\x3c\x29\x6c"
+	"\x51\x40\x9a\x4d\x9b\xd0\xe6\x7f\xad\x31\x54\x88\x90\xe1\xa8\x0e"
+	"\xd8\xf4\x84\x11\xdb\x02\x41\xff\xb0\x8a\x92\x95\x97\xd6\x98\x8a"
+	"\xa0\x43\xda\x70\xbb\x17\xd0\x5a\x81\x3e\xf7\xcf\xc9\x33\xd9\x76"
+	"\x2f\x53\xa2\xac\xa0\x8a\x73\xe4\x0c\x81\xbe\x26\x01\x3f\x6d\x79"
+	"\x8a\x37\x59\x5b\x0a\x9a\x10\x6b\x04\x30\xed\xda\x11\x73\x73\xd9"
+	"\xa2\x9a\xf8\x8e\x67\x82\x5a\x8d\xc0\x52\xe8\x42\x89\xcd\x9c\xb1"
+	"\x5c\x3d\xd4\x75\x03\x71\x03\x3f\xdc\x6b\x79\xb4\x02\xb6\xac\xc4"
+	"\x11\x0f\x61\xc8\xf7\x5d\xc6\xbf\x48\x02\xa3\xdc\xa8\x37\x10\x85"
+	"\xb2\x8d\xbd\xb0\x79\x09\xb0\x5f\x30\x6c\x40\xba\x03\xbb\x22\xcc"
+	"\x80\xa1\xc3\x91\x88\x25\x92\xbe\xa6\xfa\x14\x77\x56\xb3\xc0\xb5"
+	"\x69\x8c\x6f\xed\x21\xaf\x0c\x79\x07\x64\xa2\xea\xeb\x47\x2c\x1e"
+	"\x7d\x6c\x12\xae\x75\xc4\xee\x12\x46\x72\x87\x65\x73\x51\xee\xf8"
+	"\x08\x63\x20\xa1\x61\xca\x73\x8f\xdf\xcb\x97\xf8\xfc\xb0\x56\xea"
+	"\x34\x9d\xce\xb8\x91\xb8\xfc\xec\x76\xd0\x71\xb7\x92\xc9\xb2\x28"
+	"\xee\x0b\x5d\x7c\x4a\xf6\x73\x4d\xc2\x5b\x5b\xae\x7b\xa6\x9c\xba"
+	"\x29\x7d\x7d\x3c\x29\x01\x04\x2d\xd1\x6c\x8d\x8d\xe5\xb4\x6b\xf9"
+	"\x2a\x83\xb8\x14\x00\x1c\x91\x72\x5e\x8f\x13\x56\x6d\x9b\x6d\x27"
+	"\xe8\x22\x55\x4b\x2f\x8a\x31\x16\x98\x03\x51\x73\xa7\x2e\x18\x81"
+	"\x51\x0a\x8f\x6d\x17\xd0\xea\x04\x1c\x11\xb9\x6b\x8e\xaa\x76",
+	1023,
+	"\x24\x28\x57\xa0\x3c\x12\xe2\x6a\x65\x97\x96\x75\xb3\x75\x67\x4c"
+	"\xd0\xc8\xa7\x07\x7d\x55\x10\xbc\x11\xfe\x45\xbe\x74\x27\x74\xa3"
+	"\x8b\xb8\x51\x0d\x2e\xf0\x0c\x83\xed\xe4\x8b\x15\xf2\xae\xd8\xd5"
+	"\xed\xd8\x76\x0d\x0b\x5b\x7b\x5a\x17\x83\xf3\x37\xe5\x81\x90\xe8"
+	"\x15\xb4\xec\xf8\x5a\x00\x72\xf2\xbb\x68\x0a\xc9\x6c\x4a\x80\x45"
+	"\x04\xa5\x7e\xfa\xf3\x45\x08\x65\xd0\xd6\xcd\x08\xd1\x1f\x45\x6b"
+	"\x23\xa9\x0f\xe1\x10\x90\x26\x48\x23\x23\xd2\x60\xc4\x16\x31\x03"
+	"\x30\xbe\xf0\xd0\xa0\xa7\xcf\xaa\xe6\x27\x0e\xd6\x7b\x79\xf1\x2b"
+	"\x29\x27\x57\x5a\xb7\xf5\xf8\xb4\x35\x3c\xb5\x10\xb8\xbf\xbe\xad"
+	"\xdb\x9b\x3d\x35\x63\xac\x9b\xfe\x86\x69\x2c\x54\xf5\x7c\x7f\xd6"
+	"\xcd\x33\x9f\x57\x7f\xce\x72\x18\x60\x2e\x20\x33\xc9\x13\x9f\x60"
+	"\x5f\x67\x24\xc2\xbb\x9e\x63\x80\xcf\x96\xb9\xf0\xf1\x9e\xcc\x5a"
+	"\x61\x02\x6d\xab\x4c\xf7\x13\xe4\x48\x0f\x9f\xc9\x24\x8e\x40\x06"
+	"\x53\x30\xac\xd9\xe8\xf5\xcd\xd4\xcf\x99\x1f\x3c\x08\x74\x38\x7e"
+	"\x0b\x76\x0d\xc3\xbd\x2a\x75\x3a\x55\x0c\xc6\xd3\x50\x59\x53\xf2"
+	"\x14\x1d\x09\xb0\xfa\x8d\xc2\x5e\x6b\x79\xed\x5e\x10\xcc\x1c\xbe"
+	"\x03\x75\x6d\x23\x44\xe8\xd6\x4d\x8f\xe4\xd6\x1a\x16\x83\x79\x72"
+	"\xdc\x51\x25\x61\x75\xe7\x00\x09\xdf\xfe\x0c\x6c\x99\xa8\xb0\xfc"
+	"\xbf\xb6\x7f\xae\x0a\x75\x2e\xd4\x69\xfe\xf1\xb7\x68\xbe\x07\xf0"
+	"\x9c\xa3\x82\x1f\x4d\x06\xa7\x73\x53\xbd\x98\x99\x93\x1b\xc9\xb6"
+	"\x04\x5e\xc0\xc1\xd8\x53\x7e\x6f\xd9\x4e\xa0\x37\xab\x71\x92\xc7"
+	"\x97\x4b\x80\x40\x14\xd0\xd0\xee\x93\xfb\xd5\x76\xce\xd7\x9e\x74"
+	"\xee\x5d\xe6\x79\xb2\x92\xbb\xff\x63\x19\x61\x64\xcc\x60\x80\x8b"
+	"\x9c\x1f\x38\x01\x43\xf7\xa6\xcd\x20\x5d\x1d\x2a\x2a\x25\xf4\xd5"
+	"\x17\x3d\x9c\xd2\x56\x8c\x76\x4e\xa0\xba\x24\x55\x55\xd4\x87\x78"
+	"\xde\x30\xe8\x6f\x39\xa5\x22\x91\x2b\x7b\x20\x6f\xf6\x44\xff\xec"
+	"\x29\x4e\xc8\x30\xf7\x23\x18\xef\xb8\x33\xfb\x5f\xf2\xe2\xd8\xc1"
+	"\xe3\x0f\x24\x19\xff\x99\x7e\xa2\xdb\x78\xde\xc3\x92\x47\x9b\x32"
+	"\xd6\xfa\xb7\x34\x14\xa4\xde\xd0\xa4\x6f\x7b\x03\x90\x80\x7a\x1e"
+	"\xb7\xc7\xc3\x75\x98\xa6\x76\xfc\xa6\x38\xa3\xf6\x17\xe8\x90\x25"
+	"\x28\x66\x41\x78\xe9\x70\x44\xbc\x62\x64\xf5\xaa\xd8\x62\x09\xf3"
+	"\xff\x05\xd5\x4e\xea\x8d\xf0\x0e\x4e\x3c\x37\xbe\x30\xe6\x69\x15"
+	"\xc5\x7b\xa6\x67\x1a\x74\xca\x4f\x0f\x5c\xf3\xac\x20\xaa\xc3\xad"
+	"\xf5\xb3\x58\x8e\x22\x53\x3d\xe8\x0a\x1b\x33\x88\xf1\x8d\x9c\xc8"
+	"\x5a\xb6\xd3\xde\x1a\x7a\x21\x12\x1e\x70\x0e\x52\x90\x24\xe0\x1c"
+	"\xaa\x04\x79\xbc\x58\x42\xcb\xe1\x42\x82\xbe\xeb\x17\xd6\xd9\x8c"
+	"\xc5\xe8\x77\xde\x77\xb5\x31\xf5\x7f\x09\x8b\x7d\x59\x6e\xbd\xe0"
+	"\x7b\x0f\xe6\x29\x37\x7b\x19\x90\x69\x33\x0a\xbe\x50\xa5\x11\xba"
+	"\xc5\x90\x78\x31\xfc\x1e\x6c\x8e\x50\x99\x2b\xd9\x50\x39\xaa\x80"
+	"\x19\x59\xae\x1e\x7a\x7d\xea\xbe\x92\x0e\xc1\xd4\x99\x71\x50\xb2"
+	"\x46\x0e\x39\x73\x45\x92\x8e\xd7\xb3\xcd\xf7\x37\x8e\x78\x2b\x2b"
+	"\xba\x33\xc1\x3e\xdd\xac\x9d\x09\xcd\xb0\x7e\x78\x05\x70\x44\x98"
+	"\x8d\xcd\xf3\xf4\x55\x07\x6a\x75\x66\x6a\xd2\xf2\x4a\x95\x6b\x07"
+	"\xfc\x8d\x6d\xe9\x40\xc5\x94\x19\xb5\x29\x5c\xaa\xb0\x7b\x2b\x8d"
+	"\x64\x41\xfd\x10\x58\xba\x6c\x1f\x7e\x88\x5f\x77\x8c\xe0\x3a\xda"
+	"\x7d\xed\xc4\xf1\x30\xce\x8d\x47\xd8\xe2\x8c\xca\xea\xf8\xb7\x73"
+	"\x9d\xb4\xfc\x06\x09\x17\x20\x00\x96\xe4\xd2\x07\x01\x10\x44\xef"
+	"\x7e\x18\x74\xac\xba\xe3\x26\x0d\x11\x27\xbf\xf3\xbb\x06\x1c\x49"
+	"\xd7\xae\x79\xe1\xaf\xd8\x66\x48\x03\xb6\x08\x66\x79\x11\xc5\x68"
+	"\x47\xbc\x4b\xfe\xc4\xa6\x7b\x3a\x66\xcd\x9f\x93\x70\xc2\x42\xd9"
+	"\xac\x54\x36\x73\x1b\x3a\x89\x1f\x13\xc7\x63\x9e\x43\xbf\xdd\xd7"
+	"\x54\xc7\xda\x6f\x74\x83\x81\x27\x19\xb3\xde\x1a\x14\xec\x0b\x96"
+	"\xee\x12\x02\xd1\x9f\x30\xe1\xef\xb8\xb4\xe9\xa4\x72\xc1\x48\xbc"
+	"\x23\x21\x64\x32\x0d\xac\x49\x6e\x53\x80\x37\x10\x2d\xcf\x6f\x11"
+	"\xf3\xd0\xf3\x02\xb6\x9d\x6e\x3c\x44\x39\x4d\xee\x8b\x8f\xea\xfa"
+	"\x20\xf4\x98\x67\x9c\xe3\x12\x82\xa8\xbe\x1c\x3a\x1c\x51\x81\x9d"
+	"\xc0\xfe\x46\x79\xd0\x19\x6b\xf1\x5d\xbb\x4d\xde\x42\xc9\x72\x93"
+	"\x62\x65\xb5\x88\xb1\x5f\x92\xfe\x56\x56\x58\xfb\x7a\x81\x7c\x02"
+	"\xb0\xc0\x53\x84\x6f\x13\x20\x53\xec\x49\x93\xae\x7e\x3c\x3f\xdf"
+	"\xe7\xba\xa0\x40\x24\x10\xd4\xe6\xf5\xed\x65\xd3\x21\x36\xb1\xe6"
+	"\x11\x0a\x47\xbc\xd3\x21\x33\x30\x03\x37\x8c\x45\xe5\xdd\xb0\xd5"
+	"\xcb\x80\x42\xdd\x84\xd6\x70\xf0\xbb\x5b\x44\xe0\x84\x8b\x83\x7c"
+	"\xcb\xec\x6a\x28\xa3\xf3\x4a\x6c\x0d\xb0\x79\x34\x13\x10\x64\xfc"
+	"\xee\x12\x55\x82\x25\x25\x30\xb9\xa6\xf8\x3c\x81\x36\xcd\xef",
+	"\xce\xc3\x13\x6c\x40\x2a\xcc\x51\xa1\xce\xb3\xed\xe8\xa6\x5b\x04",
       }
     };
 
-- 
2.30.2




More information about the Gcrypt-devel mailing list