From jussi.kivilinna at iki.fi Sat Dec 1 12:39:21 2018 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 1 Dec 2018 13:39:21 +0200 Subject: [PATCH] rijndael-aesni: interleave last CTR encryption round with xoring Message-ID: <154366436144.10697.8253308414774859608.stgit@localhost.localdomain> * cipher/rijndael-aesni.c (do_aesni_ctr_8): Interleave aesenclast with input xoring. -- Structure of 'aesenclast' instruction allows reordering last encryption round and xoring of input block for small ~0.5% improvement in performance. Intel i7-4970K @ 4.0 Ghz: AES | nanosecs/byte mebibytes/sec cycles/byte CTR enc | 0.159 ns/B 6002 MiB/s 0.636 c/B CTR dec | 0.159 ns/B 6001 MiB/s 0.636 c/B Signed-off-by: Jussi Kivilinna --- cipher/rijndael-aesni.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c index 483387cde..ec9f4d4a5 100644 --- a/cipher/rijndael-aesni.c +++ b/cipher/rijndael-aesni.c @@ -1657,14 +1657,6 @@ do_aesni_ctr_8 (const RIJNDAEL_context *ctx, "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" - "aesenclast %%xmm1, %%xmm0\n\t" - "aesenclast %%xmm1, %%xmm2\n\t" - "aesenclast %%xmm1, %%xmm3\n\t" - "aesenclast %%xmm1, %%xmm4\n\t" - "aesenclast %%xmm1, %%xmm8\n\t" - "aesenclast %%xmm1, %%xmm9\n\t" - "aesenclast %%xmm1, %%xmm10\n\t" - "aesenclast %%xmm1, %%xmm11\n\t" : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) @@ -1674,22 +1666,30 @@ do_aesni_ctr_8 (const RIJNDAEL_context *ctx, "movdqu 1*16(%[src]), %%xmm13\n\t" /* Get block 2. */ "movdqu 2*16(%[src]), %%xmm14\n\t" /* Get block 3. */ "movdqu 3*16(%[src]), %%xmm15\n\t" /* Get block 4. */ - "movdqu 4*16(%[src]), %%xmm1\n\t" /* Get block 5. */ - "pxor %%xmm12, %%xmm0\n\t" /* EncCTR-1 ^= input */ + "movdqu 4*16(%[src]), %%xmm7\n\t" /* Get block 5. */ + "pxor %%xmm1, %%xmm12\n\t" /* block1 ^= lastkey */ + "aesenclast %%xmm12, %%xmm0\n\t" "movdqu 5*16(%[src]), %%xmm12\n\t" /* Get block 6. */ - "pxor %%xmm13, %%xmm2\n\t" /* EncCTR-2 ^= input */ + "pxor %%xmm1, %%xmm13\n\t" /* block2 ^= lastkey */ + "aesenclast %%xmm13, %%xmm2\n\t" "movdqu 6*16(%[src]), %%xmm13\n\t" /* Get block 7. */ - "pxor %%xmm14, %%xmm3\n\t" /* EncCTR-3 ^= input */ + "pxor %%xmm1, %%xmm14\n\t" /* block3 ^= lastkey */ + "aesenclast %%xmm14, %%xmm3\n\t" "movdqu 7*16(%[src]), %%xmm14\n\t" /* Get block 8. */ - "pxor %%xmm15, %%xmm4\n\t" /* EncCTR-4 ^= input */ + "pxor %%xmm1, %%xmm15\n\t" /* block4 ^= lastkey */ + "aesenclast %%xmm15, %%xmm4\n\t" "movdqu %%xmm0, 0*16(%[dst])\n\t" /* Store block 1 */ - "pxor %%xmm1, %%xmm8\n\t" /* EncCTR-5 ^= input */ + "pxor %%xmm1, %%xmm7\n\t" /* block5 ^= lastkey */ + "aesenclast %%xmm7, %%xmm8\n\t" "movdqu %%xmm0, 0*16(%[dst])\n\t" /* Store block 1 */ - "pxor %%xmm12, %%xmm9\n\t" /* EncCTR-6 ^= input */ + "pxor %%xmm1, %%xmm12\n\t" /* block6 ^= lastkey */ + "aesenclast %%xmm12, %%xmm9\n\t" "movdqu %%xmm2, 1*16(%[dst])\n\t" /* Store block 2. */ - "pxor %%xmm13, %%xmm10\n\t" /* EncCTR-7 ^= input */ + "pxor %%xmm1, %%xmm13\n\t" /* block7 ^= lastkey */ + "aesenclast %%xmm13, %%xmm10\n\t" "movdqu %%xmm3, 2*16(%[dst])\n\t" /* Store block 3. */ - "pxor %%xmm14, %%xmm11\n\t" /* EncCTR-8 ^= input */ + "pxor %%xmm1, %%xmm14\n\t" /* block8 ^= lastkey */ + "aesenclast %%xmm14, %%xmm11\n\t" "movdqu %%xmm4, 3*16(%[dst])\n\t" /* Store block 4. */ "movdqu %%xmm8, 4*16(%[dst])\n\t" /* Store block 8. */ "movdqu %%xmm9, 5*16(%[dst])\n\t" /* Store block 9. */ From cvs at cvs.gnupg.org Sat Dec 1 13:01:32 2018 From: cvs at cvs.gnupg.org (by Jussi Kivilinna) Date: Sat, 01 Dec 2018 13:01:32 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-133-g66d2b7f Message-ID: 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 66d2b7fc17258f1424f4ca4adb1096e48b818bd0 (commit) via 168668228c7c49e70612cb4d602d6d603a2add2c (commit) from 9d9c4fd18b445ff414d11678285d54af3afdb222 (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 66d2b7fc17258f1424f4ca4adb1096e48b818bd0 Author: Jussi Kivilinna Date: Sat Dec 1 12:21:14 2018 +0200 rijndael-aesni: interleave last CTR encryption round with xoring * cipher/rijndael-aesni.c (do_aesni_ctr_8): Interleave aesenclast with input xoring. -- Structure of 'aesenclast' instruction allows reordering last encryption round and xoring of input block for small ~0.5% improvement in performance. Intel i7-4790K @ 4.0 Ghz: AES | nanosecs/byte mebibytes/sec cycles/byte CTR enc | 0.159 ns/B 6002 MiB/s 0.636 c/B CTR dec | 0.159 ns/B 6001 MiB/s 0.636 c/B Signed-off-by: Jussi Kivilinna diff --git a/cipher/rijndael-aesni.c b/cipher/rijndael-aesni.c index 483387c..ec9f4d4 100644 --- a/cipher/rijndael-aesni.c +++ b/cipher/rijndael-aesni.c @@ -1657,14 +1657,6 @@ do_aesni_ctr_8 (const RIJNDAEL_context *ctx, "movdqa 0xe0(%[key]), %%xmm1\n" ".Lenclast%=:\n\t" - "aesenclast %%xmm1, %%xmm0\n\t" - "aesenclast %%xmm1, %%xmm2\n\t" - "aesenclast %%xmm1, %%xmm3\n\t" - "aesenclast %%xmm1, %%xmm4\n\t" - "aesenclast %%xmm1, %%xmm8\n\t" - "aesenclast %%xmm1, %%xmm9\n\t" - "aesenclast %%xmm1, %%xmm10\n\t" - "aesenclast %%xmm1, %%xmm11\n\t" : : [key] "r" (ctx->keyschenc), [rounds] "r" (ctx->rounds) @@ -1674,22 +1666,30 @@ do_aesni_ctr_8 (const RIJNDAEL_context *ctx, "movdqu 1*16(%[src]), %%xmm13\n\t" /* Get block 2. */ "movdqu 2*16(%[src]), %%xmm14\n\t" /* Get block 3. */ "movdqu 3*16(%[src]), %%xmm15\n\t" /* Get block 4. */ - "movdqu 4*16(%[src]), %%xmm1\n\t" /* Get block 5. */ - "pxor %%xmm12, %%xmm0\n\t" /* EncCTR-1 ^= input */ + "movdqu 4*16(%[src]), %%xmm7\n\t" /* Get block 5. */ + "pxor %%xmm1, %%xmm12\n\t" /* block1 ^= lastkey */ + "aesenclast %%xmm12, %%xmm0\n\t" "movdqu 5*16(%[src]), %%xmm12\n\t" /* Get block 6. */ - "pxor %%xmm13, %%xmm2\n\t" /* EncCTR-2 ^= input */ + "pxor %%xmm1, %%xmm13\n\t" /* block2 ^= lastkey */ + "aesenclast %%xmm13, %%xmm2\n\t" "movdqu 6*16(%[src]), %%xmm13\n\t" /* Get block 7. */ - "pxor %%xmm14, %%xmm3\n\t" /* EncCTR-3 ^= input */ + "pxor %%xmm1, %%xmm14\n\t" /* block3 ^= lastkey */ + "aesenclast %%xmm14, %%xmm3\n\t" "movdqu 7*16(%[src]), %%xmm14\n\t" /* Get block 8. */ - "pxor %%xmm15, %%xmm4\n\t" /* EncCTR-4 ^= input */ + "pxor %%xmm1, %%xmm15\n\t" /* block4 ^= lastkey */ + "aesenclast %%xmm15, %%xmm4\n\t" "movdqu %%xmm0, 0*16(%[dst])\n\t" /* Store block 1 */ - "pxor %%xmm1, %%xmm8\n\t" /* EncCTR-5 ^= input */ + "pxor %%xmm1, %%xmm7\n\t" /* block5 ^= lastkey */ + "aesenclast %%xmm7, %%xmm8\n\t" "movdqu %%xmm0, 0*16(%[dst])\n\t" /* Store block 1 */ - "pxor %%xmm12, %%xmm9\n\t" /* EncCTR-6 ^= input */ + "pxor %%xmm1, %%xmm12\n\t" /* block6 ^= lastkey */ + "aesenclast %%xmm12, %%xmm9\n\t" "movdqu %%xmm2, 1*16(%[dst])\n\t" /* Store block 2. */ - "pxor %%xmm13, %%xmm10\n\t" /* EncCTR-7 ^= input */ + "pxor %%xmm1, %%xmm13\n\t" /* block7 ^= lastkey */ + "aesenclast %%xmm13, %%xmm10\n\t" "movdqu %%xmm3, 2*16(%[dst])\n\t" /* Store block 3. */ - "pxor %%xmm14, %%xmm11\n\t" /* EncCTR-8 ^= input */ + "pxor %%xmm1, %%xmm14\n\t" /* block8 ^= lastkey */ + "aesenclast %%xmm14, %%xmm11\n\t" "movdqu %%xmm4, 3*16(%[dst])\n\t" /* Store block 4. */ "movdqu %%xmm8, 4*16(%[dst])\n\t" /* Store block 8. */ "movdqu %%xmm9, 5*16(%[dst])\n\t" /* Store block 9. */ commit 168668228c7c49e70612cb4d602d6d603a2add2c Author: Jussi Kivilinna Date: Tue Nov 13 22:08:50 2018 +0200 Use explicit_bzero for wipememory * configure.ac (AC_CHECK_FUNCS): Check for 'explicit_bzero'. * src/g10lib.h (wipememory2): Use _gcry_fast_wipememory if _SET is zero. (_gcry_fast_wipememory): New. (_gcry_wipememory2): Rename to... (_gcry_fast_wipememory2): ...this. * src/misc.c (_gcry_wipememory): New. (_gcry_wipememory2): Rename to... (_gcry_fast_wipememory2): ...this. (_gcry_fast_wipememory2) [HAVE_EXPLICIT_BZERO]: Use explicit_bzero if SET is zero. (_gcry_burn_stack): Use _gcry_fast_wipememory. -- Signed-off-by: Jussi Kivilinna diff --git a/configure.ac b/configure.ac index 9803d51..5843884 100644 --- a/configure.ac +++ b/configure.ac @@ -1772,6 +1772,7 @@ AC_CHECK_FUNCS(strtoul memmove stricmp atexit raise) AC_CHECK_FUNCS(strerror rand mmap getpagesize sysconf waitpid wait4) AC_CHECK_FUNCS(gettimeofday getrusage gethrtime clock_gettime syslog) AC_CHECK_FUNCS(syscall fcntl ftruncate flockfile) +AC_CHECK_FUNCS(explicit_bzero) GNUPG_CHECK_MLOCK diff --git a/src/g10lib.h b/src/g10lib.h index 9b21478..694c2d8 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -334,15 +334,16 @@ void __gcry_burn_stack (unsigned int bytes); do { __gcry_burn_stack (bytes); \ __gcry_burn_stack_dummy (); } while(0) - /* To avoid that a compiler optimizes certain memset calls away, these macros may be used instead. For small constant length buffers, memory wiping is inlined. For non-constant or large length buffers, - memory is wiped with memset through _gcry_wipememory. */ -void _gcry_wipememory2(void *ptr, int set, size_t len); + memory is wiped with memset through _gcry_fast_wipememory. */ #define wipememory2(_ptr,_set,_len) do { \ if (!CONSTANT_P(_len) || _len > 64) { \ - _gcry_wipememory2((void *)_ptr, _set, _len); \ + if (CONSTANT_P(_set) && (_set) == 0) \ + _gcry_fast_wipememory((void *)_ptr, _len); \ + else \ + _gcry_fast_wipememory2((void *)_ptr, _set, _len); \ } else {\ volatile char *_vptr = (volatile char *)(_ptr); \ size_t _vlen = (_len); \ @@ -353,6 +354,9 @@ void _gcry_wipememory2(void *ptr, int set, size_t len); } while(0) #define wipememory(_ptr,_len) wipememory2(_ptr,0,_len) +void _gcry_fast_wipememory(void *ptr, size_t len); +void _gcry_fast_wipememory2(void *ptr, int set, size_t len); + #if defined(HAVE_GCC_ATTRIBUTE_PACKED) && \ defined(HAVE_GCC_ATTRIBUTE_ALIGNED) && \ defined(HAVE_GCC_ATTRIBUTE_MAY_ALIAS) diff --git a/src/misc.c b/src/misc.c index 420ce74..bb39e1c 100644 --- a/src/misc.c +++ b/src/misc.c @@ -32,6 +32,8 @@ static int verbosity_level = 0; +/* Prevent compiler from optimizing away the call to memset by accessing + memset through volatile pointer. */ static void *(*volatile memset_ptr)(void *, int, size_t) = (void *)memset; static void (*fatal_error_handler)(void*,int, const char*) = NULL; @@ -500,8 +502,37 @@ _gcry_strtokenize (const char *string, const char *delim) void -_gcry_wipememory2 (void *ptr, int set, size_t len) +_gcry_fast_wipememory (void *ptr, size_t len) { + /* Note: This function is called from wipememory/wipememory2 only if LEN + is large or unknown at compile time. New wipe function alternatives + need to be checked before adding to this function. New implementations + need to be faster than wipememory/wipememory2 macros in 'misc.h'. + + Following implementations were found to have suboptimal performance: + + - [_WIN32/mingw32] SecureZeroMemory; Inline function, equivalent to + volatile byte buffer set: while(buflen--) (volatile char *)(buf++)=set; + */ +#ifdef HAVE_EXPLICIT_BZERO + explicit_bzero (ptr, len); +#else + memset_ptr (ptr, 0, len); +#endif +} + + +void +_gcry_fast_wipememory2 (void *ptr, int set, size_t len) +{ +#ifdef HAVE_EXPLICIT_BZERO + if (set == 0) + { + explicit_bzero (ptr, len); + return; + } +#endif + memset_ptr (ptr, set, len); } @@ -514,11 +545,11 @@ __gcry_burn_stack (unsigned int bytes) unsigned int buflen = ((!bytes + bytes) + 63) & ~63; char buf[buflen]; - memset_ptr (buf, 0, buflen); + _gcry_fast_wipememory (buf, buflen); #else volatile char buf[64]; - wipememory (buf, sizeof buf); + _gcry_fast_wipememory (buf, sizeof buf); if (bytes > sizeof buf) _gcry_burn_stack (bytes - sizeof buf); ----------------------------------------------------------------------- Summary of changes: cipher/rijndael-aesni.c | 34 +++++++++++++++++----------------- configure.ac | 1 + src/g10lib.h | 12 ++++++++---- src/misc.c | 37 ++++++++++++++++++++++++++++++++++--- 4 files changed, 60 insertions(+), 24 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 From jancar.jj at gmail.com Sun Dec 9 16:32:18 2018 From: jancar.jj at gmail.com (=?UTF-8?B?SsOhbiBKYW7EjcOhcg==?=) Date: Sun, 9 Dec 2018 16:32:18 +0100 Subject: ECDH loads parameters as signed In-Reply-To: <26eebcb1-9c0f-ff9c-24c2-40a8c7a2b92f@gmail.com> References: <87pnvsg0ss.fsf@wheatstone.g10code.de> <26eebcb1-9c0f-ff9c-24c2-40a8c7a2b92f@gmail.com> Message-ID: <7f08e4bb-820a-63bf-ff08-2250b82d4763@gmail.com> On 31/10/2018 12:10, J?n Jan??r wrote: > > > On 31/10/2018 00:32, J?n Jan??r wrote: >> >> >> On 29/10/2018 17:44, Werner Koch wrote: >>> On Mon, 29 Oct 2018 15:41, jancar.jj at gmail.com said: >>> >>>> Any updates on this? Such exporting and loading parameters back should >>>> work. The same problem appears in ECDSA. >>> >>> I considered to include this in 1.8.4 but given that I have seen no >>> further comments your patch first needs closer investigations. We need >>> to check the history to see why the code was written this way. Even if >>> your issue is a bug (in the sense of a wrong/different implementation) >>> we can't simply change it and risk that other applications break. >> >> The use of sexp_extract_param with the signed prefix was introduced in >> 6bd5d18c, which moved the sexp parsing from gcry_pk_encrypt to >> ecc_encrypt_raw. Previously the keyparams S-exp was parsed using a loop and: >> >> gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_STD); >> >> as in 6bd5d18c: cipher/pubkey.c (sexp_elements_extract_ecc). >> >> However, before 6bd5d18c, which introduced eddsa, this was done using: > > Sorry, the eddsa introduction should have been commit 63cd34744, > mis-copied the id. Hi all, Any news on this? It has been a month. My rationale is further explained in: https://lists.gnupg.org/pipermail/gcrypt-devel/2018-October/004574.html Cheers, J?n Jan??r -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: OpenPGP digital signature URL: From cvs at cvs.gnupg.org Wed Dec 12 08:58:05 2018 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Wed, 12 Dec 2018 08:58:05 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-134-g876f728 Message-ID: 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 876f7280e8604bc99ddda0526339ec5ec6b23c4b (commit) from 66d2b7fc17258f1424f4ca4adb1096e48b818bd0 (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 876f7280e8604bc99ddda0526339ec5ec6b23c4b Author: Werner Koch Date: Wed Dec 12 08:34:10 2018 +0100 secmem: Prepare for easier debugging. * src/secmem.c (_gcry_secmem_dump_stats): Factor code out to ... (secmem_dump_stats_internal): new. -- This allows to insert call to the dump function during debug sessions inside of the allocators or call secmem_dump_stats_internal from gdb. Signed-off-by: Werner Koch diff --git a/src/secmem.c b/src/secmem.c index b6f07c5..b36c44f 100644 --- a/src/secmem.c +++ b/src/secmem.c @@ -118,6 +118,13 @@ GPGRT_LOCK_DEFINE (secmem_lock); #define ADDR_TO_BLOCK(addr) \ (memblock_t *) (void *) ((char *) addr - BLOCK_HEAD_SIZE) +/* Prototypes. */ +static void secmem_dump_stats_internal (int extended); + + +/* + * Functions + */ /* Memory barrier */ static inline void @@ -657,11 +664,18 @@ _gcry_secmem_malloc_internal (size_t size, int xhint) return &mb->aligned.c; } - /* If we are called from xmalloc style function resort to the + /* If we are called from xmalloc style functions resort to the * overflow pools to return memory. We don't do this in FIPS mode, - * though. */ + * though. If the auto-expand option is active we do the expanding + * also for the standard malloc functions. + * + * The idea of using them by default only for the xmalloc function + * is so that a user can control whether memory will be allocated in + * the initial created mlock protected secmem area or may also be + * allocated from the overflow pools. */ if ((xhint || auto_expand) && !fips_mode ()) { + /* Check whether we can allocate from the overflow pools. */ for (pool = pool->next; pool; pool = pool->next) { mb = mb_get_new (pool, (memblock_t *) pool->mem, size); @@ -900,12 +914,19 @@ _gcry_secmem_term () void _gcry_secmem_dump_stats (int extended) { + SECMEM_LOCK; + secmem_dump_stats_internal (extended); + SECMEM_UNLOCK; +} + + +static void +secmem_dump_stats_internal (int extended) +{ pooldesc_t *pool; memblock_t *mb; int i, poolno; - SECMEM_LOCK; - for (pool = &mainpool, poolno = 0; pool; pool = pool->next, poolno++) { if (!extended) @@ -928,5 +949,4 @@ _gcry_secmem_dump_stats (int extended) mb->size); } } - SECMEM_UNLOCK; } ----------------------------------------------------------------------- Summary of changes: src/secmem.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 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 From cvs at cvs.gnupg.org Wed Dec 19 02:33:17 2018 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Wed, 19 Dec 2018 02:33:17 +0100 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.8.1-135-g3028a22 Message-ID: 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 3028a221d39c1b593ea0c1bcbfccd33959769692 (commit) from 876f7280e8604bc99ddda0526339ec5ec6b23c4b (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 3028a221d39c1b593ea0c1bcbfccd33959769692 Author: NIIBE Yutaka Date: Wed Dec 19 10:28:32 2018 +0900 random: Add finalizer for rndjent. * random/rand-internal.h (_gcry_rndjent_fini): New. * random/rndjent.c (_gcry_rndjent_fini): New. * random/rndlinux.c (_gcry_rndlinux_gather_random): Call the finalizer when GCRYCTL_CLOSE_RANDOM_DEVICE. -- GnuPG-bug-id: 3731 Signed-off-by: NIIBE Yutaka diff --git a/random/rand-internal.h b/random/rand-internal.h index 2bc05f4..d99c667 100644 --- a/random/rand-internal.h +++ b/random/rand-internal.h @@ -132,6 +132,7 @@ size_t _gcry_rndjent_poll (void (*add)(const void*, enum random_origins origin, size_t length); void _gcry_rndjent_dump_stats (void); +void _gcry_rndjent_fini (void); /*-- rndhw.c --*/ int _gcry_rndhw_failed_p (void); diff --git a/random/rndjent.c b/random/rndjent.c index 3740ddd..3d01290 100644 --- a/random/rndjent.c +++ b/random/rndjent.c @@ -370,3 +370,20 @@ _gcry_rndjent_dump_stats (void) } #endif /*USE_JENT*/ } + + +void +_gcry_rndjent_fini (void) +{ +#ifdef USE_JENT + lock_rng (); + + if (jent_rng_is_initialized) + { + jent_entropy_collector_free (jent_rng_collector); + jent_rng_collector = NULL; + } + + unlock_rng (); +#endif +} diff --git a/random/rndlinux.c b/random/rndlinux.c index fefc3c3..3d41cd3 100644 --- a/random/rndlinux.c +++ b/random/rndlinux.c @@ -156,6 +156,8 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t, close (fd_urandom); fd_urandom = -1; } + + _gcry_rndjent_fini (); return 0; } ----------------------------------------------------------------------- Summary of changes: random/rand-internal.h | 1 + random/rndjent.c | 17 +++++++++++++++++ random/rndlinux.c | 2 ++ 3 files changed, 20 insertions(+) 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 From jussi.kivilinna at iki.fi Sat Dec 29 23:39:00 2018 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 30 Dec 2018 00:39:00 +0200 Subject: [PATCH 1/3] tests/benchmark: add --huge-buffers option for cipher tests Message-ID: <154612314011.16205.13139749075512503704.stgit@localhost.localdomain> * 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 --- 0 files changed diff --git a/tests/benchmark.c b/tests/benchmark.c index 59ea32c66..f9974fc48 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++; From jussi.kivilinna at iki.fi Sat Dec 29 23:39:05 2018 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 30 Dec 2018 00:39:05 +0200 Subject: [PATCH 2/3] tests/benchmark: add Chacha20-Poly1305 benchmarking In-Reply-To: <154612314011.16205.13139749075512503704.stgit@localhost.localdomain> References: <154612314011.16205.13139749075512503704.stgit@localhost.localdomain> Message-ID: <154612314548.16205.11220471487374691931.stgit@localhost.localdomain> * tests/benchmark.c (cipher_bench): Add Chacha20-Poly1305. -- Signed-off-by: Jussi Kivilinna --- 0 files changed diff --git a/tests/benchmark.c b/tests/benchmark.c index f9974fc48..418f92913 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 From jussi.kivilinna at iki.fi Sat Dec 29 23:39:11 2018 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sun, 30 Dec 2018 00:39:11 +0200 Subject: [PATCH 3/3] Process CCM/EAX/GCM/Poly1305 AEAD cipher modes input in 24 KiB chucks In-Reply-To: <154612314011.16205.13139749075512503704.stgit@localhost.localdomain> References: <154612314011.16205.13139749075512503704.stgit@localhost.localdomain> Message-ID: <154612315085.16205.2486590587507475950.stgit@localhost.localdomain> * 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 --- 0 files changed diff --git a/cipher/cipher-ccm.c b/cipher/cipher-ccm.c index e71c6f159..fd284caa5 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 3b17bb648..08f815a9e 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 32ec9fa06..f9ddbc568 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 82537aa4d..607586b55 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; }