From jussi.kivilinna at iki.fi Wed Dec 2 20:08:36 2020 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Wed, 2 Dec 2020 21:08:36 +0200 Subject: [PATCH 1/3] chacha20-ppc: fix 32-bit counter overflow handling Message-ID: <20201202190838.2837479-1-jussi.kivilinna@iki.fi> * cipher/chacha20-ppc.c (vec_add_ctr_u64, ADD_U64): New. (_gcry_chacha20_ppc8_blocks1, _gcry_chacha20_ppc8_blocks4) (_gcry_chacha20_poly1305_ppc8_blocks4): Use ADD_U64 when incrementing counter. -- Patch fixes 32-bit overflow for PowerPC ChaCha20 implementation. In typical use case, overflow happens after 256 GiB bytes of output. Typical use case here means use of 96-bit or 64-bit IV which causes lower 32-bits of counter to start from zero. Signed-off-by: Jussi Kivilinna --- cipher/chacha20-ppc.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/cipher/chacha20-ppc.c b/cipher/chacha20-ppc.c index 985f2fcd..4a21b837 100644 --- a/cipher/chacha20-ppc.c +++ b/cipher/chacha20-ppc.c @@ -88,6 +88,24 @@ vec_store_le(vector4x_u32 vec, unsigned long offset, unsigned char *ptr) } +static ASM_FUNC_ATTR_INLINE vector4x_u32 +vec_add_ctr_u64(vector4x_u32 v, vector4x_u32 a) +{ +#ifdef WORDS_BIGENDIAN + static const vector16x_u8 swap32 = + { 4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11 }; + vector2x_u64 vec, add, sum; + + vec = (vector2x_u64)vec_perm((vector16x_u8)v, (vector16x_u8)v, swap32); + add = (vector2x_u64)vec_perm((vector16x_u8)a, (vector16x_u8)a, swap32); + sum = vec + add; + return (vector4x_u32)vec_perm((vector16x_u8)sum, (vector16x_u8)sum, swap32); +#else + return (vector4x_u32)((vector2x_u64)(v) + (vector2x_u64)(a)); +#endif +} + + /********************************************************************** 2-way && 1-way chacha20 **********************************************************************/ @@ -115,6 +133,9 @@ vec_store_le(vector4x_u32 vec, unsigned long offset, unsigned char *ptr) ROTATE(x1, rotate_7); \ WORD_ROL(x1, rol_x1); +#define ADD_U64(v,a) \ + (v = vec_add_ctr_u64(v, a)) + unsigned int ASM_FUNC_ATTR _gcry_chacha20_ppc8_blocks1(u32 *state, byte *dst, const byte *src, size_t nblks) @@ -152,7 +173,7 @@ _gcry_chacha20_ppc8_blocks1(u32 *state, byte *dst, const byte *src, v5 = state1; v6 = state2; v7 = state3; - v7 += counter_1; + ADD_U64(v7, counter_1); for (i = 20; i > 0; i -= 2) { @@ -166,12 +187,12 @@ _gcry_chacha20_ppc8_blocks1(u32 *state, byte *dst, const byte *src, v1 += state1; v2 += state2; v3 += state3; - state3 += counter_1; /* update counter */ + ADD_U64(state3, counter_1); /* update counter */ v4 += state0; v5 += state1; v6 += state2; v7 += state3; - state3 += counter_1; /* update counter */ + ADD_U64(state3, counter_1); /* update counter */ v0 ^= vec_load_le(0 * 16, src); v1 ^= vec_load_le(1 * 16, src); @@ -214,7 +235,7 @@ _gcry_chacha20_ppc8_blocks1(u32 *state, byte *dst, const byte *src, v1 += state1; v2 += state2; v3 += state3; - state3 += counter_1; /* update counter */ + ADD_U64(state3, counter_1); /* update counter */ v0 ^= vec_load_le(0 * 16, src); v1 ^= vec_load_le(1 * 16, src); @@ -339,7 +360,7 @@ _gcry_chacha20_ppc8_blocks4(u32 *state, byte *dst, const byte *src, v13 += vec_splat(state3, 1) - vec_cmplt(tmp, counters_0123); v14 += vec_splat(state3, 2); v15 += vec_splat(state3, 3); - state3 += counter_4; /* update counter */ + ADD_U64(state3, counter_4); /* update counter */ transpose_4x4(v0, v1, v2, v3); transpose_4x4(v4, v5, v6, v7); @@ -554,7 +575,7 @@ _gcry_chacha20_poly1305_ppc8_blocks4(u32 *state, byte *dst, const byte *src, v13 += vec_splat(state3, 1) - vec_cmplt(tmp, counters_0123); v14 += vec_splat(state3, 2); v15 += vec_splat(state3, 3); - state3 += counter_4; /* update counter */ + ADD_U64(state3, counter_4); /* update counter */ transpose_4x4(v0, v1, v2, v3); transpose_4x4(v4, v5, v6, v7); -- 2.27.0 From jussi.kivilinna at iki.fi Wed Dec 2 20:08:37 2020 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Wed, 2 Dec 2020 21:08:37 +0200 Subject: [PATCH 2/3] tests/basic: check 32-bit and 64-bit overflow for CTR and ChaCha20 In-Reply-To: <20201202190838.2837479-1-jussi.kivilinna@iki.fi> References: <20201202190838.2837479-1-jussi.kivilinna@iki.fi> Message-ID: <20201202190838.2837479-2-jussi.kivilinna@iki.fi> * tests/basic.c (check_one_cipher_ctr_reset) (check_one_cipher_ctr_overflow): New. (check_one_cipher): Add counter overflow tests for ChaCha20 and CTR mode. -- Patch adds counter overflow tests to check for correct counter handling in bulk processing implementations. Signed-off-by: Jussi Kivilinna --- tests/basic.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 232 insertions(+) diff --git a/tests/basic.c b/tests/basic.c index 1d12c4a2..4beeeed9 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -9415,6 +9415,210 @@ err_out_free: +static int +check_one_cipher_ctr_reset (gcry_cipher_hd_t hd, int algo, int mode, + u32 ctr_high_bits, int be_ctr, + int pass) +{ + unsigned char iv[16] = { 0 }; + unsigned char swap; + unsigned int ivlen; + u32 ctr_low_bits; + int err; + int i; + + /* This should be largest parallel block processing count in any + * implementation negated. Currently for CTR this is 32 and, for + * ChaCha20, count is 8. */ + ctr_low_bits = (mode == GCRY_CIPHER_MODE_CTR) ? -32 : -8; + + gcry_cipher_reset (hd); + + if (mode == GCRY_CIPHER_MODE_CTR) + ivlen = get_algo_mode_blklen(algo, GCRY_CIPHER_MODE_ECB); + else + ivlen = 16; + + /* Little-endian fill. */ + for (i = 0; i < 4; i++) + iv[i + 0] = (ctr_low_bits >> (i * 8)) & 0xff; + for (i = 0; i < 4; i++) + iv[i + 4] = (ctr_high_bits >> (i * 8)) & 0xff; + + if (be_ctr) + { + /* Swap to big-endian. */ + for (i = 0; i < ivlen / 2; i++) + { + swap = iv[i]; + iv[i] = iv[ivlen - (i + 1)]; + iv[ivlen - (i + 1)] = swap; + } + } + + clutter_vector_registers(); + if (mode == GCRY_CIPHER_MODE_CTR) + err = gcry_cipher_setctr (hd, iv, ivlen); + else + err = gcry_cipher_setiv (hd, iv, ivlen); + + if (err) + { + fail ("pass %d, algo %d, mode %d, gcry_cipher_setiv failed: %s\n", + pass, algo, mode, gpg_strerror (err)); + gcry_cipher_close (hd); + return -1; + } + + return 0; +} + +static int +check_one_cipher_ctr_overflow (int algo, int mode, int flags, + const char *key, size_t nkey, + const unsigned char *plain, size_t nplain, + unsigned long ctr_high_bits, int be_ctr, + int pass) +{ + gcry_cipher_hd_t hd; + unsigned char *out; + unsigned char *enc_result; + int keylen; + gcry_error_t err = 0; + unsigned int firstlen; + unsigned int leftlen; + unsigned int blklen; + unsigned int pos; + unsigned int i; + + out = malloc (nplain); + enc_result = malloc (nplain); + if (!out || !enc_result) + { + fail ("pass %d, algo %d, mode %d, malloc failed\n", + pass, algo, mode); + goto err_out_free; + } + + assert (nkey == 64); + assert (nplain > 0); + assert ((nplain % 16) == 0); + + keylen = gcry_cipher_get_algo_keylen (algo); + if (!keylen) + { + fail ("pass %d, algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n", + pass, algo, mode); + goto err_out_free; + } + + if (keylen < 40 / 8 || keylen > 32) + { + fail ("pass %d, algo %d, mode %d, keylength problem (%d)\n", + pass, algo, mode, keylen); + goto err_out_free; + } + + err = gcry_cipher_open (&hd, algo, mode, flags); + if (err) + { + fail ("pass %d, algo %d, mode %d, gcry_cipher_open failed: %s\n", + pass, algo, mode, gpg_strerror (err)); + goto err_out_free; + } + + clutter_vector_registers(); + err = gcry_cipher_setkey (hd, key, keylen); + if (err) + { + fail ("pass %d, algo %d, mode %d, gcry_cipher_setkey failed: %s\n", + pass, algo, mode, gpg_strerror (err)); + gcry_cipher_close (hd); + goto err_out_free; + } + + if (check_one_cipher_ctr_reset (hd, algo, mode, ctr_high_bits, be_ctr, + pass) < 0) + goto err_out_free; + + /* Non-bulk processing. */ + for (i = 0; i < nplain; i += 16) + { + clutter_vector_registers(); + err = gcry_cipher_encrypt (hd, out + i, 16, plain + i, 16); + if (err) + { + fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", + pass, algo, mode, gpg_strerror (err)); + gcry_cipher_close (hd); + goto err_out_free; + } + } + + memcpy (enc_result, out, nplain); + + /* Test with different bulk processing sizes. */ + for (blklen = 2 * 16; blklen <= 32 * 16; blklen *= 2) + { + /* Move bulk processing start offset, test at different spots to + * test bulk counter calculation throughly. */ + for (firstlen = 16; firstlen < 8 * 64; firstlen += 16) + { + if (check_one_cipher_ctr_reset (hd, algo, mode, ctr_high_bits, be_ctr, + pass) < 0) + goto err_out_free; + + clutter_vector_registers(); + err = gcry_cipher_encrypt (hd, out, firstlen, plain, firstlen); + if (err) + { + fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt " + "failed: %s\n", pass, algo, mode, gpg_strerror (err)); + gcry_cipher_close (hd); + goto err_out_free; + } + + leftlen = nplain - firstlen; + pos = firstlen; + while (leftlen) + { + unsigned int currlen = leftlen > blklen ? blklen : leftlen; + + clutter_vector_registers(); + err = gcry_cipher_encrypt (hd, out + pos, currlen, plain + pos, + currlen); + if (err) + { + fail ("pass %d, algo %d, mode %d, block len %d, first len %d," + "gcry_cipher_encrypt failed: %s\n", pass, algo, mode, + blklen, firstlen, gpg_strerror (err)); + gcry_cipher_close (hd); + goto err_out_free; + } + + pos += currlen; + leftlen -= currlen; + } + + if (memcmp (enc_result, out, nplain)) + fail ("pass %d, algo %d, mode %d, block len %d, first len %d, " + "encrypt mismatch\n", pass, algo, mode, blklen, firstlen); + } + } + + gcry_cipher_close (hd); + + free (enc_result); + free (out); + return 0; + +err_out_free: + free (enc_result); + free (out); + return -1; +} + + static void check_one_cipher (int algo, int mode, int flags) { @@ -9491,6 +9695,34 @@ check_one_cipher (int algo, int mode, int flags) 50)) goto out; + /* Pass 6: Counter overflow tests for ChaCha20 and CTR mode. */ + if (mode == GCRY_CIPHER_MODE_STREAM && algo == GCRY_CIPHER_CHACHA20) + { + /* 32bit overflow test (little-endian counter) */ + if (check_one_cipher_ctr_overflow (algo, mode, flags, key, 64, plain, + medium_buffer_size, 0UL, + 0, 60)) + goto out; + /* 64bit overflow test (little-endian counter) */ + if (check_one_cipher_ctr_overflow (algo, mode, flags, key, 64, plain, + medium_buffer_size, 0xffffffffUL, + 0, 61)) + goto out; + } + else if (mode == GCRY_CIPHER_MODE_CTR) + { + /* 32bit overflow test (big-endian counter) */ + if (check_one_cipher_ctr_overflow (algo, mode, flags, key, 64, plain, + medium_buffer_size, 0UL, + 1, 62)) + goto out; + /* 64bit overflow test (big-endian counter) */ + if (check_one_cipher_ctr_overflow (algo, mode, flags, key, 64, plain, + medium_buffer_size, 0xffffffffUL, + 1, 63)) + goto out; + } + out: free (plain); } -- 2.27.0 From jussi.kivilinna at iki.fi Wed Dec 2 20:08:38 2020 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Wed, 2 Dec 2020 21:08:38 +0200 Subject: [PATCH 3/3] Prevent link-time optimization from inlining __gcry_burn_stack In-Reply-To: <20201202190838.2837479-1-jussi.kivilinna@iki.fi> References: <20201202190838.2837479-1-jussi.kivilinna@iki.fi> Message-ID: <20201202190838.2837479-3-jussi.kivilinna@iki.fi> * src/g10lib.h (NOINLINE_FUNC): New attribute macro. * src/misc.c (__gcry_burn_stack): Add NOINLINE_FUNC attribute. -- LTO can cause inline of __gcry_burn_stack and result tail-call to _gcry_fast_wipememory and defeat tail-call prevention in _gcry_burn_stack macro. Mark __gcry_burn_stack with 'noinline' attribute to prevent unwanted inlining of this function in LTO builds. Signed-off-by: Jussi Kivilinna --- src/g10lib.h | 6 ++++++ src/misc.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/g10lib.h b/src/g10lib.h index c85e6649..ffd71018 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -75,6 +75,12 @@ #define GCC_ATTR_UNUSED #endif +#if __GNUC__ > 3 +#define NOINLINE_FUNC __attribute__((noinline)) +#else +#define NOINLINE_FUNC +#endif + #if __GNUC__ >= 3 #define LIKELY(expr) __builtin_expect( !!(expr), 1 ) #define UNLIKELY(expr) __builtin_expect( !!(expr), 0 ) diff --git a/src/misc.c b/src/misc.c index 283e3a72..4db2d9a4 100644 --- a/src/misc.c +++ b/src/misc.c @@ -545,7 +545,7 @@ _gcry_fast_wipememory2 (void *ptr, int set, size_t len) } -void +void NOINLINE_FUNC __gcry_burn_stack (unsigned int bytes) { #ifdef HAVE_VLA -- 2.27.0 From jussi.kivilinna at iki.fi Sat Dec 5 13:32:11 2020 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 5 Dec 2020 14:32:11 +0200 Subject: [PATCH 2/2] aarch64: mpi/longlong.h: fix operand size mismatch In-Reply-To: <20201205123211.221918-1-jussi.kivilinna@iki.fi> References: <20201205123211.221918-1-jussi.kivilinna@iki.fi> Message-ID: <20201205123211.221918-2-jussi.kivilinna@iki.fi> * mpi/longlong.h [__aarch64__] (count_leading_zeros): Use correctly sized temporary variable for asm output. -- Patch fixes clang-8 warning about differently sized inline assembly operands seen on aarch64. Signed-off-by: Jussi Kivilinna --- mpi/longlong.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mpi/longlong.h b/mpi/longlong.h index c0f24c85..6573c984 100644 --- a/mpi/longlong.h +++ b/mpi/longlong.h @@ -305,9 +305,13 @@ extern UDItype __udiv_qrnnd (); (ph) = __ph; \ } while (0) # define count_leading_zeros(count, x) \ - __asm__ ("clz %0, %1\n" \ - : "=r" ((count)) \ - : "r" ((UDItype)(x))) + do { \ + UDItype __co; \ + __asm__ ("clz %0, %1\n" \ + : "=r" (__co) \ + : "r" ((UDItype)(x))); \ + (count) = __co; \ + } while (0) #endif /* __aarch64__ */ /*************************************** -- 2.27.0 From jussi.kivilinna at iki.fi Sat Dec 5 13:32:10 2020 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Sat, 5 Dec 2020 14:32:10 +0200 Subject: [PATCH 1/2] aarch64: use configure check for assembly ELF directives support Message-ID: <20201205123211.221918-1-jussi.kivilinna@iki.fi> * configure.ac (gcry_cv_gcc_asm_elf_directives): New check. (HAVE_GCC_ASM_ELF_DIRECTIVES): New 'config.h' macro. * cipher/asm-common-aarch64.h (ELF): Change feature macro check from __ELF__ to HAVE_GCC_ASM_ELF_DIRECTIVES. -- Signed-off-by: Jussi Kivilinna --- cipher/asm-common-aarch64.h | 2 +- configure.ac | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/cipher/asm-common-aarch64.h b/cipher/asm-common-aarch64.h index 4ffc1b71..4e0b6d2e 100644 --- a/cipher/asm-common-aarch64.h +++ b/cipher/asm-common-aarch64.h @@ -23,7 +23,7 @@ #include -#ifdef __ELF__ +#ifdef HAVE_GCC_ASM_ELF_DIRECTIVES # define ELF(...) __VA_ARGS__ #else # define ELF(...) /*_*/ diff --git a/configure.ac b/configure.ac index e90d46e4..fda74056 100644 --- a/configure.ac +++ b/configure.ac @@ -1224,6 +1224,26 @@ if test "$gcry_cv_gcc_asm_cfi_directives" = "yes" ; then fi +# +# Check whether GCC assembler supports for ELF directives. +# +AC_CACHE_CHECK([whether GCC assembler supports for ELF directives], + [gcry_cv_gcc_asm_elf_directives], + [gcry_cv_gcc_asm_elf_directives=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[__asm__( + /* Test if ELF directives '.type' and '.size' are supported. */ + "asmfunc:\n\t" + ".size asmfunc,.-asmfunc;\n\t" + ".type asmfunc,STT_FUNC;\n\t" + );]])], + [gcry_cv_gcc_asm_elf_directives=yes])]) +if test "$gcry_cv_gcc_asm_elf_directives" = "yes" ; then + AC_DEFINE(HAVE_GCC_ASM_ELF_DIRECTIVES,1, + [Defined if underlying assembler supports for ELF directives]) +fi + + # # Check whether underscores in symbols are required. This needs to be # done before setting up the assembler stuff. -- 2.27.0 From stefbon at gmail.com Mon Dec 14 08:13:19 2020 From: stefbon at gmail.com (Stef Bon) Date: Mon, 14 Dec 2020 08:13:19 +0100 Subject: New functions like gcry_ecc_mul_point. Message-ID: Hi, I;m using libgrypt for my ssh library for all crypto: hashing, publickey, key-agreement (Diffie-Hellman dh and ecdh), encryption etc. Doing ecdh is hard since the way to get from buffers holding keys to ecc multiplication is hard. But here is this new function gcry_ecc_mul_point which is making my life a lot easier (for me as a programmer at least!). Now what I want to know is: when does this function go into production releases? I've been programming similar functions myself and did not get it working using testdata. And please more functions like this. They are so powerful and easy to use. Thanks, Stef Bon From wk at gnupg.org Mon Dec 14 13:20:45 2020 From: wk at gnupg.org (Werner Koch) Date: Mon, 14 Dec 2020 13:20:45 +0100 Subject: New functions like gcry_ecc_mul_point. In-Reply-To: (Stef Bon via Gcrypt-devel's message of "Mon, 14 Dec 2020 08:13:19 +0100") References: Message-ID: <87lfe037fm.fsf@wheatstone.g10code.de> On Mon, 14 Dec 2020 08:13, Stef Bon said: > Hi, > > I;m using libgrypt for my ssh library for all crypto: hashing, > publickey, key-agreement (Diffie-Hellman dh and ecdh), encryption etc. > > Doing ecdh is hard since the way to get from buffers holding keys to > ecc multiplication is hard. > But here is this new function gcry_ecc_mul_point which is making my > life a lot easier (for me as a programmer at least!). > > Now what I want to know is: when does this function go into production > releases? I've been programming similar functions myself and did not You are right, releasing Libgcrypt 1.9 is long uverdue. See https://dev.gnupg.org/T4294 We also want to get GnuPG 2.3 out and this requires Libgcrypt 1.9. Thus a Libgcrypt 1.9 is definitely on our short list ... but I better don't promise a concrete date :-(. First quarter 2021 for 1.9 maybe. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From stefbon at gmail.com Mon Dec 14 14:20:12 2020 From: stefbon at gmail.com (Stef Bon) Date: Mon, 14 Dec 2020 14:20:12 +0100 Subject: New functions like gcry_ecc_mul_point. In-Reply-To: <87lfe037fm.fsf@wheatstone.g10code.de> References: <87lfe037fm.fsf@wheatstone.g10code.de> Message-ID: Op ma 14 dec. 2020 om 13:50 schreef Werner Koch : > > > Now what I want to know is: when does this function go into production > > releases? I've been programming similar functions myself and did not > > You are right, releasing Libgcrypt 1.9 is long uverdue. See > https://dev.gnupg.org/T4294 > > We also want to get GnuPG 2.3 out and this requires Libgcrypt 1.9. Thus > a Libgcrypt 1.9 is definitely on our short list ... but I better don't > promise a concrete date :-(. > > First quarter 2021 for 1.9 maybe. > Great! I'm looking forward to release my super fuse filesystem by then. See: https://github.com/stefbon/fs-workspace Keep up the good work, Stef Bon Stef Bon From gniibe at fsij.org Wed Dec 16 04:19:23 2020 From: gniibe at fsij.org (NIIBE Yutaka) Date: Wed, 16 Dec 2020 12:19:23 +0900 Subject: Refactor HMAC selftest into MAC selftest Message-ID: <87czzatp38.fsf@iwagami.gniibe.org> Hello, For FIPS 140 things, I created a branch to review works from Red Hat: gniibe/fips-from-redhat https://dev.gnupg.org/source/libgcrypt/history/gniibe%252Ffips-from-redhat/ Reviewing libgcrypt-1.8.3-cmac-selftest.patch, before actually working for that, I think that we need some improvement in our selftest. Here is my proposal #1 to refactor HMAC selftest into MAC selftest, so that we can add CMAC selftest (and GMAC) easily. (Proposal #2 is merging hmac-tests.c into mac-hmac.c (and removing hmac-tests.c).) This patch does: Add new member 'selftest' in gcry_mac_spec_ops_t. Add an internal function _gcry_mac_selftest. Rename run_hmac_selftests in fips.c to run_mac_selftests. Remove the function _gcry_hmac_selftest in hmac-tests.c. Any comments will be appriciated. -------------------------- diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 4798d456..eca87d1a 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -26,7 +26,7 @@ AM_CFLAGS = $(GPG_ERROR_CFLAGS) AM_CCASFLAGS = $(NOEXECSTACK_FLAGS) -EXTRA_DIST = gost-s-box.c +EXTRA_DIST = gost-s-box.c hmac-tests.c CLEANFILES = gost-s-box DISTCLEANFILES = gost-sb.h @@ -61,7 +61,6 @@ libcipher_la_SOURCES = \ mac-hmac.c mac-cmac.c mac-gmac.c mac-poly1305.c \ poly1305.c poly1305-internal.h \ kdf.c kdf-internal.h \ - hmac-tests.c \ bithelp.h \ bufhelp.h \ primegen.c \ diff --git a/cipher/gost28147.c b/cipher/gost28147.c index df16c3c6..1bafe317 100644 --- a/cipher/gost28147.c +++ b/cipher/gost28147.c @@ -542,6 +542,7 @@ static gcry_mac_spec_ops_t gost_imit_ops = { gost_imit_get_maclen, gost_imit_get_keylen, gost_imit_set_extra_info, + NULL }; gcry_mac_spec_t _gcry_mac_type_spec_gost28147_imit = diff --git a/cipher/hmac-tests.c b/cipher/hmac-tests.c index 78d260a1..f5bac69c 100644 --- a/cipher/hmac-tests.c +++ b/cipher/hmac-tests.c @@ -1098,6 +1098,7 @@ selftests_sha3 (int hashalgo, int extended, selftest_report_func_t report) } +#if 0 /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t run_selftests (int algo, int extended, selftest_report_func_t report) @@ -1138,7 +1139,6 @@ run_selftests (int algo, int extended, selftest_report_func_t report) - /* Run the selftests for HMAC with digest algorithm ALGO with optional reporting function REPORT. */ gpg_error_t @@ -1158,3 +1158,4 @@ _gcry_hmac_selftest (int algo, int extended, selftest_report_func_t report) } return gpg_error (ec); } +#endif diff --git a/cipher/mac-cmac.c b/cipher/mac-cmac.c index 120fa3df..f4d0ce59 100644 --- a/cipher/mac-cmac.c +++ b/cipher/mac-cmac.c @@ -157,6 +157,7 @@ static gcry_mac_spec_ops_t cmac_ops = { cmac_verify, cmac_get_maclen, cmac_get_keylen, + NULL, NULL }; diff --git a/cipher/mac-gmac.c b/cipher/mac-gmac.c index aa78c7e3..b9805eea 100644 --- a/cipher/mac-gmac.c +++ b/cipher/mac-gmac.c @@ -150,6 +150,7 @@ static gcry_mac_spec_ops_t gmac_ops = { gmac_verify, gmac_get_maclen, gmac_get_keylen, + NULL, NULL }; diff --git a/cipher/mac-hmac.c b/cipher/mac-hmac.c index d0cc5775..2dca4253 100644 --- a/cipher/mac-hmac.c +++ b/cipher/mac-hmac.c @@ -222,6 +222,49 @@ hmac_get_keylen (int algo) } } +#include "hmac-tests.c" + +static gpg_err_code_t +hmac_selftest (int algo, int extended, selftest_report_func_t report) +{ + gpg_err_code_t ec; + + switch (algo) + { + case GCRY_MAC_HMAC_SHA1: + ec = selftests_sha1 (extended, report); + break; + case GCRY_MAC_HMAC_SHA224: + ec = selftests_sha224 (extended, report); + break; + case GCRY_MAC_HMAC_SHA256: + ec = selftests_sha256 (extended, report); + break; + case GCRY_MAC_HMAC_SHA384: + ec = selftests_sha384 (extended, report); + break; + case GCRY_MAC_HMAC_SHA512: + ec = selftests_sha512 (extended, report); + break; + + case GCRY_MAC_HMAC_SHA3_224: + case GCRY_MAC_HMAC_SHA3_256: + case GCRY_MAC_HMAC_SHA3_384: + case GCRY_MAC_HMAC_SHA3_512: + { + int md_algo = map_mac_algo_to_md (algo); + ec = selftests_sha3 (md_algo, extended, report); + } + break; + + default: + ec = GPG_ERR_MAC_ALGO; + break; + } + + return ec; +} + static const gcry_mac_spec_ops_t hmac_ops = { hmac_open, @@ -234,7 +277,8 @@ static const gcry_mac_spec_ops_t hmac_ops = { hmac_verify, hmac_get_maclen, hmac_get_keylen, - NULL + NULL, + hmac_selftest }; diff --git a/cipher/mac-internal.h b/cipher/mac-internal.h index 8c13520b..d907a46f 100644 --- a/cipher/mac-internal.h +++ b/cipher/mac-internal.h @@ -20,6 +20,7 @@ #include #include "g10lib.h" +#include "cipher-proto.h" #include "gost.h" @@ -81,6 +82,7 @@ typedef struct gcry_mac_spec_ops gcry_mac_get_maclen_func_t get_maclen; gcry_mac_get_keylen_func_t get_keylen; gcry_mac_set_extra_info_t set_extra_info; + selftest_func_t selftest; } gcry_mac_spec_ops_t; diff --git a/cipher/mac-poly1305.c b/cipher/mac-poly1305.c index 39ba790f..d27a31c6 100644 --- a/cipher/mac-poly1305.c +++ b/cipher/mac-poly1305.c @@ -323,7 +323,8 @@ static gcry_mac_spec_ops_t poly1305mac_ops = { poly1305mac_verify, poly1305mac_get_maclen, poly1305mac_get_keylen, - NULL + NULL, + NULL, }; diff --git a/cipher/mac.c b/cipher/mac.c index 933be74c..e274b356 100644 --- a/cipher/mac.c +++ b/cipher/mac.c @@ -781,3 +781,28 @@ _gcry_mac_algo_info (int algo, int what, void *buffer, size_t * nbytes) return rc; } + + +/* Run the self-tests for the MAC. */ +gpg_error_t +_gcry_mac_selftest (int algo, int extended, selftest_report_func_t report) +{ + gcry_err_code_t ec; + gcry_mac_spec_t *spec; + + spec = spec_from_algo (algo); + if (spec && !spec->flags.disabled && spec->ops && spec->ops->selftest) + ec = spec->ops->selftest (algo, extended, report); + else + { + ec = GPG_ERR_MAC_ALGO; + if (report) + report ("mac", algo, "module", + spec && !spec->flags.disabled? + "no selftest available" : + spec? "algorithm disabled" : + "algorithm not found"); + } + + return gpg_error (ec); +} diff --git a/src/fips.c b/src/fips.c index 1ac7f477..94ffbd20 100644 --- a/src/fips.c +++ b/src/fips.c @@ -493,21 +493,21 @@ run_digest_selftests (int extended) } -/* Run self-tests for all HMAC algorithms. Return 0 on success. */ +/* Run self-tests for MAC algorithms. Return 0 on success. */ static int -run_hmac_selftests (int extended) +run_mac_selftests (int extended) { static int algos[] = { - GCRY_MD_SHA1, - GCRY_MD_SHA224, - GCRY_MD_SHA256, - GCRY_MD_SHA384, - GCRY_MD_SHA512, - GCRY_MD_SHA3_224, - GCRY_MD_SHA3_256, - GCRY_MD_SHA3_384, - GCRY_MD_SHA3_512, + GCRY_MAC_HMAC_SHA1, + GCRY_MAC_HMAC_SHA224, + GCRY_MAC_HMAC_SHA256, + GCRY_MAC_HMAC_SHA384, + GCRY_MAC_HMAC_SHA512, + GCRY_MAC_HMAC_SHA3_224, + GCRY_MAC_HMAC_SHA3_256, + GCRY_MAC_HMAC_SHA3_384, + GCRY_MAC_HMAC_SHA3_512, 0 }; int idx; @@ -516,8 +516,8 @@ run_hmac_selftests (int extended) for (idx=0; algos[idx]; idx++) { - err = _gcry_hmac_selftest (algos[idx], extended, reporter); - reporter ("hmac", algos[idx], NULL, + err = _gcry_mac_selftest (algos[idx], extended, reporter); + reporter ("mac", algos[idx], NULL, err? gpg_strerror (err):NULL); if (err) anyerr = 1; @@ -678,7 +678,7 @@ _gcry_fips_run_selftests (int extended) if (run_digest_selftests (extended)) goto leave; - if (run_hmac_selftests (extended)) + if (run_mac_selftests (extended)) goto leave; /* Run random tests before the pubkey tests because the latter -- From wk at gnupg.org Thu Dec 17 08:42:15 2020 From: wk at gnupg.org (Werner Koch) Date: Thu, 17 Dec 2020 08:42:15 +0100 Subject: Refactor HMAC selftest into MAC selftest In-Reply-To: <87czzatp38.fsf@iwagami.gniibe.org> (NIIBE Yutaka's message of "Wed, 16 Dec 2020 12:19:23 +0900") References: <87czzatp38.fsf@iwagami.gniibe.org> Message-ID: <87a6uczxns.fsf@wheatstone.g10code.de> On Wed, 16 Dec 2020 12:19, NIIBE Yutaka said: > This patch does: > > Add new member 'selftest' in gcry_mac_spec_ops_t. > Add an internal function _gcry_mac_selftest. > Rename run_hmac_selftests in fips.c to run_mac_selftests. > Remove the function _gcry_hmac_selftest in hmac-tests.c. Okay with me. FWIW: Actually it would be better if we could factor out the hmac code from the md functions and divert hmac requests in gcry_md_* directly to gcry_mac_* functions. However, that is a too intrusive change for now and thus we need to stick to the structure we have. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 227 bytes Desc: not available URL: From jussi.kivilinna at iki.fi Tue Dec 22 19:37:44 2020 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 22 Dec 2020 20:37:44 +0200 Subject: [PATCH 2/2] hwf-arm: fix incorrect HWCAP2 for SHA1 and SHA2 on AArch32 In-Reply-To: <20201222183744.2676977-1-jussi.kivilinna@iki.fi> References: <20201222183744.2676977-1-jussi.kivilinna@iki.fi> Message-ID: <20201222183744.2676977-2-jussi.kivilinna@iki.fi> * src/hwf-arm.c (HWCAP2_SHA1, HWCAP2_SHA2): Change from bit indexes to flags. -- GnuPG-bug-id: 5195 Signed-off-by: Jussi Kivilinna --- src/hwf-arm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hwf-arm.c b/src/hwf-arm.c index 1d19ea86..41188583 100644 --- a/src/hwf-arm.c +++ b/src/hwf-arm.c @@ -93,10 +93,10 @@ struct feature_map_s { # define HWCAP2_PMULL 2 #endif #ifndef HWCAP2_SHA1 -# define HWCAP2_SHA1 3 +# define HWCAP2_SHA1 4 #endif #ifndef HWCAP2_SHA2 -# define HWCAP2_SHA2 4 +# define HWCAP2_SHA2 8 #endif static const struct feature_map_s arm_features[] = -- 2.27.0 From jussi.kivilinna at iki.fi Tue Dec 22 19:37:43 2020 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Tue, 22 Dec 2020 20:37:43 +0200 Subject: [PATCH 1/2] Add missing prototype for _gcry_mac_selftest Message-ID: <20201222183744.2676977-1-jussi.kivilinna@iki.fi> * src/cipher-proto.h (_gcry_hmac_selftest): Rename to... (_gcry_mac_selftest): ... this. -- It appears that '_gcry_hmac_selftest' has been renamed to '_gcry_mac_selftest' but renaming prototype was missed. Signed-off-by: Jussi Kivilinna --- src/cipher-proto.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cipher-proto.h b/src/cipher-proto.h index d87559ed..ece5322d 100644 --- a/src/cipher-proto.h +++ b/src/cipher-proto.h @@ -267,8 +267,8 @@ gcry_error_t _gcry_md_selftest (int algo, int extended, selftest_report_func_t report); gcry_error_t _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report); -gcry_error_t _gcry_hmac_selftest (int algo, int extended, - selftest_report_func_t report); +gcry_error_t _gcry_mac_selftest (int algo, int extended, + selftest_report_func_t report); gcry_error_t _gcry_random_selftest (selftest_report_func_t report); -- 2.27.0 From gniibe at fsij.org Wed Dec 23 09:03:38 2020 From: gniibe at fsij.org (Niibe Yutaka) Date: Wed, 23 Dec 2020 17:03:38 +0900 Subject: [PATCH 1/2] Add missing prototype for _gcry_mac_selftest In-Reply-To: <20201222183744.2676977-1-jussi.kivilinna@iki.fi> References: <20201222183744.2676977-1-jussi.kivilinna@iki.fi> Message-ID: <87pn316jad.fsf@jumper.gniibe.org> Jussi Kivilinna wrote: > It appears that '_gcry_hmac_selftest' has been renamed to > '_gcry_mac_selftest' but renaming prototype was missed. Thank you. --