[git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-138-g3ee6588
by Jussi Kivilinna
cvs at cvs.gnupg.org
Wed Jan 2 20:35:57 CET 2019
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU crypto library".
The branch, master has been updated
via 3ee6588de8311b461ef8707c70ff86d2b252966d (commit)
via 4871f11745f33c5c5051bfe6f325ac1c10764b04 (commit)
via edde61f325e4b345f17c47369f3b6b1400656f04 (commit)
from 3028a221d39c1b593ea0c1bcbfccd33959769692 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 3ee6588de8311b461ef8707c70ff86d2b252966d
Author: Jussi Kivilinna <jussi.kivilinna at iki.fi>
Date: Wed Jan 2 21:25:44 2019 +0200
Process CCM/EAX/GCM/Poly1305 AEAD cipher modes input in 24 KiB chucks
* cipher/cipher-ccm.c (_gcry_cipher_ccm_encrypt)
(_gcry_cipher_ccm_decrypt): Process data in 24 KiB chunks.
* cipher/cipher-eax.c (_gcry_cipher_eax_encrypt)
(_gcry_cipher_eax_decrypt): Ditto.
* cipher/cipher-gcm.c (_gcry_cipher_gcm_encrypt)
(_gcry_cipher_gcm_decrypt): Ditto.
* cipher/cipher-poly1305.c (_gcry_cipher_poly1305_encrypt)
(_gcry_cipher_poly1305_decrypt): Ditto.
--
Patch changes AEAD modes to process input in 24 KiB chuncks to improve
cache locality when processing large buffers.
Huge buffer test in tests/benchmark show 0.7% improvement for AES-CCM
and AES-EAX, 6% for AES-GCM and 4% for Chacha20-Poly1305 on Intel Core
i7-4790K.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
diff --git a/cipher/cipher-ccm.c b/cipher/cipher-ccm.c
index e71c6f1..fd284ca 100644
--- a/cipher/cipher-ccm.c
+++ b/cipher/cipher-ccm.c
@@ -319,7 +319,9 @@ _gcry_cipher_ccm_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
size_t outbuflen, const unsigned char *inbuf,
size_t inbuflen)
{
- unsigned int burn;
+ gcry_err_code_t err = 0;
+ unsigned int burn = 0;
+ unsigned int nburn;
if (outbuflen < inbuflen)
return GPG_ERR_BUFFER_TOO_SHORT;
@@ -329,12 +331,32 @@ _gcry_cipher_ccm_encrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
if (inbuflen > c->u_mode.ccm.encryptlen)
return GPG_ERR_INV_LENGTH;
- c->u_mode.ccm.encryptlen -= inbuflen;
- burn = do_cbc_mac (c, inbuf, inbuflen, 0);
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done before encryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for encryption. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ c->u_mode.ccm.encryptlen -= currlen;
+ nburn = do_cbc_mac (c, inbuf, currlen, 0);
+ burn = nburn > burn ? nburn : burn;
+
+ err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, currlen);
+ if (err)
+ break;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
if (burn)
_gcry_burn_stack (burn + sizeof(void *) * 5);
-
- return _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ return err;
}
@@ -343,8 +365,9 @@ _gcry_cipher_ccm_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
size_t outbuflen, const unsigned char *inbuf,
size_t inbuflen)
{
- gcry_err_code_t err;
- unsigned int burn;
+ gcry_err_code_t err = 0;
+ unsigned int burn = 0;
+ unsigned int nburn;
if (outbuflen < inbuflen)
return GPG_ERR_BUFFER_TOO_SHORT;
@@ -354,14 +377,30 @@ _gcry_cipher_ccm_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
if (inbuflen > c->u_mode.ccm.encryptlen)
return GPG_ERR_INV_LENGTH;
- err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
- if (err)
- return err;
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done after decryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for checksumming. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, currlen);
+ if (err)
+ break;
+
+ c->u_mode.ccm.encryptlen -= currlen;
+ nburn = do_cbc_mac (c, outbuf, currlen, 0);
+ burn = nburn > burn ? nburn : burn;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
- c->u_mode.ccm.encryptlen -= inbuflen;
- burn = do_cbc_mac (c, outbuf, inbuflen, 0);
if (burn)
_gcry_burn_stack (burn + sizeof(void *) * 5);
-
return err;
}
diff --git a/cipher/cipher-eax.c b/cipher/cipher-eax.c
index 3b17bb6..08f815a 100644
--- a/cipher/cipher-eax.c
+++ b/cipher/cipher-eax.c
@@ -48,11 +48,31 @@ _gcry_cipher_eax_encrypt (gcry_cipher_hd_t c,
return err;
}
- err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
- if (err != 0)
- return err;
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done after encryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for checksumming. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, currlen);
+ if (err != 0)
+ return err;
- return _gcry_cmac_write (c, &c->u_mode.eax.cmac_ciphertext, outbuf, inbuflen);
+ err = _gcry_cmac_write (c, &c->u_mode.eax.cmac_ciphertext, outbuf,
+ currlen);
+ if (err != 0)
+ return err;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
+ return 0;
}
@@ -75,11 +95,31 @@ _gcry_cipher_eax_decrypt (gcry_cipher_hd_t c,
return err;
}
- err = _gcry_cmac_write (c, &c->u_mode.eax.cmac_ciphertext, inbuf, inbuflen);
- if (err != 0)
- return err;
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done before decryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for decryption. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ err = _gcry_cmac_write (c, &c->u_mode.eax.cmac_ciphertext, inbuf,
+ currlen);
+ if (err != 0)
+ return err;
- return _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+ err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, currlen);
+ if (err != 0)
+ return err;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
+ return 0;
}
diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c
index 32ec9fa..f9ddbc5 100644
--- a/cipher/cipher-gcm.c
+++ b/cipher/cipher-gcm.c
@@ -666,11 +666,26 @@ _gcry_cipher_gcm_encrypt (gcry_cipher_hd_t c,
return GPG_ERR_INV_LENGTH;
}
- err = gcm_ctr_encrypt(c, outbuf, outbuflen, inbuf, inbuflen);
- if (err != 0)
- return err;
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
- do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, outbuf, inbuflen, 0);
+ /* Since checksumming is done after encryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for checksumming. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ err = gcm_ctr_encrypt(c, outbuf, outbuflen, inbuf, currlen);
+ if (err != 0)
+ return err;
+
+ do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, outbuf, currlen, 0);
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
return 0;
}
@@ -682,6 +697,7 @@ _gcry_cipher_gcm_decrypt (gcry_cipher_hd_t c,
const byte *inbuf, size_t inbuflen)
{
static const unsigned char zerobuf[MAX_BLOCKSIZE];
+ gcry_err_code_t err;
if (c->spec->blocksize != GCRY_GCM_BLOCK_LEN)
return GPG_ERR_CIPHER_ALGO;
@@ -711,9 +727,28 @@ _gcry_cipher_gcm_decrypt (gcry_cipher_hd_t c,
return GPG_ERR_INV_LENGTH;
}
- do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, inbuf, inbuflen, 0);
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done before decryption, process input in
+ * 24KiB chunks to keep data loaded in L1 cache for decryption. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
- return gcm_ctr_encrypt(c, outbuf, outbuflen, inbuf, inbuflen);
+ do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, inbuf, currlen, 0);
+
+ err = gcm_ctr_encrypt(c, outbuf, outbuflen, inbuf, currlen);
+ if (err)
+ return err;
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
+
+ return 0;
}
diff --git a/cipher/cipher-poly1305.c b/cipher/cipher-poly1305.c
index 82537aa..607586b 100644
--- a/cipher/cipher-poly1305.c
+++ b/cipher/cipher-poly1305.c
@@ -164,9 +164,24 @@ _gcry_cipher_poly1305_encrypt (gcry_cipher_hd_t c,
return GPG_ERR_INV_LENGTH;
}
- c->spec->stencrypt(&c->context.c, outbuf, (byte*)inbuf, inbuflen);
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done after encryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for checksumming. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ c->spec->stencrypt(&c->context.c, outbuf, (byte*)inbuf, currlen);
- _gcry_poly1305_update (&c->u_mode.poly1305.ctx, outbuf, inbuflen);
+ _gcry_poly1305_update (&c->u_mode.poly1305.ctx, outbuf, currlen);
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
return 0;
}
@@ -202,9 +217,25 @@ _gcry_cipher_poly1305_decrypt (gcry_cipher_hd_t c,
return GPG_ERR_INV_LENGTH;
}
- _gcry_poly1305_update (&c->u_mode.poly1305.ctx, inbuf, inbuflen);
+ while (inbuflen)
+ {
+ size_t currlen = inbuflen;
+
+ /* Since checksumming is done before decryption, process input in 24KiB
+ * chunks to keep data loaded in L1 cache for decryption. */
+ if (currlen > 24 * 1024)
+ currlen = 24 * 1024;
+
+ _gcry_poly1305_update (&c->u_mode.poly1305.ctx, inbuf, currlen);
+
+ c->spec->stdecrypt(&c->context.c, outbuf, (byte*)inbuf, currlen);
+
+ outbuf += currlen;
+ inbuf += currlen;
+ outbuflen -= currlen;
+ inbuflen -= currlen;
+ }
- c->spec->stdecrypt(&c->context.c, outbuf, (byte*)inbuf, inbuflen);
return 0;
}
commit 4871f11745f33c5c5051bfe6f325ac1c10764b04
Author: Jussi Kivilinna <jussi.kivilinna at iki.fi>
Date: Wed Jan 2 21:25:44 2019 +0200
tests/benchmark: add Chacha20-Poly1305 benchmarking
* tests/benchmark.c (cipher_bench): Add Chacha20-Poly1305.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
diff --git a/tests/benchmark.c b/tests/benchmark.c
index f9974fc..418f929 100644
--- a/tests/benchmark.c
+++ b/tests/benchmark.c
@@ -825,7 +825,7 @@ cipher_bench ( const char *algoname )
int doublekey;
} modes[] = {
{ GCRY_CIPHER_MODE_ECB, " ECB/Stream", 1, 0xffffffffU },
- { GCRY_CIPHER_MODE_CBC, " CBC", 1, 0xffffffffU },
+ { GCRY_CIPHER_MODE_CBC, " CBC/Poly1305", 1, 0xffffffffU },
{ GCRY_CIPHER_MODE_CFB, " CFB", 0, 0xffffffffU },
{ GCRY_CIPHER_MODE_OFB, " OFB", 0, 0xffffffffU },
{ GCRY_CIPHER_MODE_CTR, " CTR", 0, 0xffffffffU },
@@ -840,6 +840,8 @@ cipher_bench ( const char *algoname )
{ GCRY_CIPHER_MODE_EAX, " EAX", 0, 0xffffffffU,
NULL, 0, 8, 8 },
{ GCRY_CIPHER_MODE_STREAM, "", 0, 0xffffffffU },
+ { GCRY_CIPHER_MODE_POLY1305, "", 0, 0xffffffffU,
+ NULL, 1, 16, 12 },
{0}
};
int modeidx;
@@ -931,9 +933,14 @@ cipher_bench ( const char *algoname )
for (modeidx=0; modes[modeidx].mode; modeidx++)
{
size_t modekeylen = keylen * (!!modes[modeidx].doublekey + 1);
+ int is_stream = modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM
+ || modes[modeidx].mode == GCRY_CIPHER_MODE_POLY1305;
- if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM)
- || (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM))
+ if ((blklen > 1 && is_stream) || (blklen == 1 && !is_stream))
+ continue;
+
+ if (modes[modeidx].mode == GCRY_CIPHER_MODE_POLY1305
+ && algo != GCRY_CIPHER_CHACHA20)
continue;
if (modes[modeidx].req_blocksize > 0
commit edde61f325e4b345f17c47369f3b6b1400656f04
Author: Jussi Kivilinna <jussi.kivilinna at iki.fi>
Date: Wed Jan 2 21:25:44 2019 +0200
tests/benchmark: add --huge-buffers option for cipher tests
* tests/benchmark.c (huge_buffers, cipher_encrypt, cipher_decrypt): New.
(cipher_bench): Add 'max_inlen' to modes structure; add huge buffers
mode selection.
(main): Add '--huge-buffers'.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
diff --git a/tests/benchmark.c b/tests/benchmark.c
index 59ea32c..f9974fc 100644
--- a/tests/benchmark.c
+++ b/tests/benchmark.c
@@ -37,9 +37,12 @@
#define PGM "benchmark"
#include "t-common.h"
-/* Do encryption tests with large buffers. */
+/* Do encryption tests with large buffers (100 KiB). */
static int large_buffers;
+/* Do encryption tests with huge buffers (256 MiB). */
+static int huge_buffers;
+
/* Number of cipher repetitions. */
static int cipher_repetitions;
@@ -743,6 +746,60 @@ static void ccm_aead_init(gcry_cipher_hd_t hd, size_t buflen, int authlen)
}
+static gcry_error_t
+cipher_encrypt (gcry_cipher_hd_t h, char *out, size_t outsize,
+ const char *in, size_t inlen, size_t max_inlen)
+{
+ gcry_error_t ret;
+
+ while (inlen)
+ {
+ size_t currlen = inlen;
+
+ if (currlen > max_inlen)
+ currlen = max_inlen;
+
+ ret = gcry_cipher_encrypt(h, out, outsize, in, currlen);
+ if (ret)
+ return ret;
+
+ out += currlen;
+ in += currlen;
+ outsize -= currlen;
+ inlen -= currlen;
+ }
+
+ return 0;
+}
+
+
+static gcry_error_t
+cipher_decrypt (gcry_cipher_hd_t h, char *out, size_t outsize,
+ const char *in, size_t inlen, size_t max_inlen)
+{
+ gcry_error_t ret;
+
+ while (inlen)
+ {
+ size_t currlen = inlen;
+
+ if (currlen > max_inlen)
+ currlen = max_inlen;
+
+ ret = gcry_cipher_decrypt(h, out, outsize, in, currlen);
+ if (ret)
+ return ret;
+
+ out += currlen;
+ in += currlen;
+ outsize -= currlen;
+ inlen -= currlen;
+ }
+
+ return 0;
+}
+
+
static void
cipher_bench ( const char *algoname )
{
@@ -760,34 +817,34 @@ cipher_bench ( const char *algoname )
int mode;
const char *name;
int blocked;
+ unsigned int max_inlen;
void (* const aead_init)(gcry_cipher_hd_t hd, size_t buflen, int authlen);
int req_blocksize;
int authlen;
int noncelen;
int doublekey;
} modes[] = {
- { GCRY_CIPHER_MODE_ECB, " ECB/Stream", 1 },
- { GCRY_CIPHER_MODE_CBC, " CBC", 1 },
- { GCRY_CIPHER_MODE_CFB, " CFB", 0 },
- { GCRY_CIPHER_MODE_OFB, " OFB", 0 },
- { GCRY_CIPHER_MODE_CTR, " CTR", 0 },
- { GCRY_CIPHER_MODE_XTS, " XTS", 0,
+ { GCRY_CIPHER_MODE_ECB, " ECB/Stream", 1, 0xffffffffU },
+ { GCRY_CIPHER_MODE_CBC, " CBC", 1, 0xffffffffU },
+ { GCRY_CIPHER_MODE_CFB, " CFB", 0, 0xffffffffU },
+ { GCRY_CIPHER_MODE_OFB, " OFB", 0, 0xffffffffU },
+ { GCRY_CIPHER_MODE_CTR, " CTR", 0, 0xffffffffU },
+ { GCRY_CIPHER_MODE_XTS, " XTS", 0, 16 << 20,
NULL, GCRY_XTS_BLOCK_LEN, 0, 0, 1 },
- { GCRY_CIPHER_MODE_CCM, " CCM", 0,
- ccm_aead_init, GCRY_CCM_BLOCK_LEN, 8 },
- { GCRY_CIPHER_MODE_GCM, " GCM", 0,
+ { GCRY_CIPHER_MODE_CCM, " CCM", 0, 0xffffffffU,
+ ccm_aead_init, GCRY_CCM_BLOCK_LEN, 8, },
+ { GCRY_CIPHER_MODE_GCM, " GCM", 0, 0xffffffffU,
NULL, GCRY_GCM_BLOCK_LEN, GCRY_GCM_BLOCK_LEN },
- { GCRY_CIPHER_MODE_OCB, " OCB", 1,
+ { GCRY_CIPHER_MODE_OCB, " OCB", 1, 0xffffffffU,
NULL, 16, 16, 15 },
- { GCRY_CIPHER_MODE_EAX, " EAX", 0,
+ { GCRY_CIPHER_MODE_EAX, " EAX", 0, 0xffffffffU,
NULL, 0, 8, 8 },
- { GCRY_CIPHER_MODE_STREAM, "", 0 },
+ { GCRY_CIPHER_MODE_STREAM, "", 0, 0xffffffffU },
{0}
};
int modeidx;
gcry_error_t err = GPG_ERR_NO_ERROR;
-
if (!algoname)
{
for (i=1; i < 400; i++)
@@ -796,7 +853,12 @@ cipher_bench ( const char *algoname )
return;
}
- if (large_buffers)
+ if (huge_buffers)
+ {
+ allocated_buflen = 256 * 1024 * 1024;
+ repetitions = 4;
+ }
+ else if (large_buffers)
{
allocated_buflen = 1024 * 100;
repetitions = 10;
@@ -945,14 +1007,16 @@ cipher_bench ( const char *algoname )
{
(*modes[modeidx].aead_init) (hd, buflen, modes[modeidx].authlen);
gcry_cipher_final (hd);
- err = gcry_cipher_encrypt (hd, outbuf, buflen, buf, buflen);
+ err = cipher_encrypt (hd, outbuf, buflen, buf, buflen,
+ modes[modeidx].max_inlen);
if (err)
break;
err = gcry_cipher_gettag (hd, outbuf, modes[modeidx].authlen);
}
else
{
- err = gcry_cipher_encrypt (hd, outbuf, buflen, buf, buflen);
+ err = cipher_encrypt (hd, outbuf, buflen, buf, buflen,
+ modes[modeidx].max_inlen);
}
}
stop_timer ();
@@ -1024,7 +1088,8 @@ cipher_bench ( const char *algoname )
{
(*modes[modeidx].aead_init) (hd, buflen, modes[modeidx].authlen);
gcry_cipher_final (hd);
- err = gcry_cipher_decrypt (hd, outbuf, buflen, buf, buflen);
+ err = cipher_decrypt (hd, outbuf, buflen, buf, buflen,
+ modes[modeidx].max_inlen);
if (err)
break;
err = gcry_cipher_checktag (hd, outbuf, modes[modeidx].authlen);
@@ -1034,7 +1099,8 @@ cipher_bench ( const char *algoname )
else
{
gcry_cipher_final (hd);
- err = gcry_cipher_decrypt (hd, outbuf, buflen, buf, buflen);
+ err = cipher_decrypt (hd, outbuf, buflen, buf, buflen,
+ modes[modeidx].max_inlen);
}
}
stop_timer ();
@@ -1741,6 +1807,11 @@ main( int argc, char **argv )
large_buffers = 1;
argc--; argv++;
}
+ else if (!strcmp (*argv, "--huge-buffers"))
+ {
+ huge_buffers = 1;
+ argc--; argv++;
+ }
else if (!strcmp (*argv, "--cipher-repetitions"))
{
argc--; argv++;
-----------------------------------------------------------------------
Summary of changes:
cipher/cipher-ccm.c | 65 ++++++++++++++++++++-----
cipher/cipher-eax.c | 56 ++++++++++++++++++----
cipher/cipher-gcm.c | 47 ++++++++++++++++---
cipher/cipher-poly1305.c | 39 +++++++++++++--
tests/benchmark.c | 120 ++++++++++++++++++++++++++++++++++++++---------
5 files changed, 275 insertions(+), 52 deletions(-)
hooks/post-receive
--
The GNU crypto library
http://git.gnupg.org
_______________________________________________
Gnupg-commits mailing list
Gnupg-commits at gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-commits
More information about the Gcrypt-devel
mailing list