Hi Bruno,

Bruno Haible <[email protected]> writes:

> Collin Funk wrote:
>> +Link:
>> +$(LIB_CRYPTO)
>> +
>
> Due to the added dependency on 'xalloc-die', which depends on 'gettext-h',
> we also need this line:
> $(LTLIBINTL) when linking with libtool, $(LIBINTL) otherwise
>
>> @@ -24,7 +24,15 @@ check_PROGRAMS += test-sha3-224-buffer 
>> test-sha3-256-buffer
>>  check_PROGRAMS += test-sha3-384-buffer test-sha3-512-buffer
>>  noinst_PROGRAMS += bench-sha3-224 bench-sha3-256
>>  noinst_PROGRAMS += bench-sha3-384 bench-sha3-512
>> +test_sha3_224_buffer_LDADD = $(LDADD) @LIB_CRYPTO@
>> +test_sha3_256_buffer_LDADD = $(LDADD) @LIB_CRYPTO@
>> +test_sha3_384_buffer_LDADD = $(LDADD) @LIB_CRYPTO@
>> +test_sha3_512_buffer_LDADD = $(LDADD) @LIB_CRYPTO@
>>  bench_sha3_224_CPPFLAGS = $(AM_CPPFLAGS) -DNDEBUG
>> +bench_sha3_224_LDADD = $(LDADD) @LIB_CRYPTO@
>>  bench_sha3_256_CPPFLAGS = $(AM_CPPFLAGS) -DNDEBUG
>> +bench_sha3_256_LDADD = $(LDADD) @LIB_CRYPTO@
>>  bench_sha3_384_CPPFLAGS = $(AM_CPPFLAGS) -DNDEBUG
>> +bench_sha3_384_LDADD = $(LDADD) @LIB_CRYPTO@
>>  bench_sha3_512_CPPFLAGS = $(AM_CPPFLAGS) -DNDEBUG
>> +bench_sha3_512_LDADD = $(LDADD) @LIB_CRYPTO@
>
> All of these programs need to be linked also with $(LIBINTL), due to the use 
> of
> xalloc_die().

Thanks for checking. But now I realize that we cannot use xalloc_die
here. I just noticed the following:

    $ gnulib-tool --create-testdir --dir testdir1 crypto/sha3
    gnulib-tool: warning: module crypto/sha3 depends on a module with an 
incompatible license: xalloc-die

I rather keep the module LGPL like the rest of the crypto modules.
Therefore, a call to abort will have to do. I don't think it is worth
the effort for a seperate *-lgpl module.

Pushed the attached which also fixes the memory leak that others noticed.

Collin

>From a351f5c211db7197bf48fd4b87c71338d7ab6a1f Mon Sep 17 00:00:00 2001
Message-ID: <a351f5c211db7197bf48fd4b87c71338d7ab6a1f.1756861721.git.collin.fu...@gmail.com>
From: Collin Funk <[email protected]>
Date: Mon, 1 Sep 2025 22:57:22 -0700
Subject: [PATCH v2] crypto/sha3-buffer: Add support for OpenSSL.

* lib/sha3.c (DEFINE_SHA3_INIT_CTX, sha3_read_ctx, sha3_finish_ctx)
(DEFINE_SHA3_BUFFER, sha3_process_bytes, sha3_process_block)
[HAVE_OPENSSL_SHA3]: Define these functions/macros using the OpenSSL EVP
API.
* lib/sha3.h [HAVE_OPENSSL_SHA3]: Include <openssl/evp.h>.
(struct sha3_ctx) [HAVE_OPENSSL_SHA3]: Only store a pointer to an
EVP_MD_CTX in the structure.
* m4/gl-openssl.m4 (gl_CRYPTO_CHECK): If the argument is SHA3 check for
EVP_sha3_224.
* m4/sha3.m4 (gl_SHA3): New file, based on m4/sha512.m4.
* modules/crypto/sha3-buffer (Files): Add m4/gl-openssl.m4 and
m4/sha3.m4.
(configure.ac): Invoke gl_SHA3. Remove gl_BIGENDIAN.
* modules/crypto/sha3-buffer-tests (Makefile.am): Link to @LIB_CRYPTO@.
---
 ChangeLog                        | 18 ++++++++
 lib/sha3.c                       | 71 ++++++++++++++++++++++++++++++++
 lib/sha3.h                       | 12 ++++++
 m4/gl-openssl.m4                 | 15 ++++---
 m4/sha3.m4                       | 16 +++++++
 modules/crypto/sha3-buffer       |  7 +++-
 modules/crypto/sha3-buffer-tests |  8 ++++
 7 files changed, 141 insertions(+), 6 deletions(-)
 create mode 100644 m4/sha3.m4

diff --git a/ChangeLog b/ChangeLog
index b84aa6a86d..0e489bd482 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2025-09-02  Collin Funk  <[email protected]>
+
+	crypto/sha3-buffer: Add support for OpenSSL.
+	* lib/sha3.c (DEFINE_SHA3_INIT_CTX, sha3_read_ctx, sha3_finish_ctx)
+	(DEFINE_SHA3_BUFFER, sha3_process_bytes, sha3_process_block)
+	[HAVE_OPENSSL_SHA3]: Define these functions/macros using the OpenSSL EVP
+	API.
+	* lib/sha3.h [HAVE_OPENSSL_SHA3]: Include <openssl/evp.h>.
+	(struct sha3_ctx) [HAVE_OPENSSL_SHA3]: Only store a pointer to an
+	EVP_MD_CTX in the structure.
+	* m4/gl-openssl.m4 (gl_CRYPTO_CHECK): If the argument is SHA3 check for
+	EVP_sha3_224.
+	* m4/sha3.m4 (gl_SHA3): New file, based on m4/sha512.m4.
+	* modules/crypto/sha3-buffer (Files): Add m4/gl-openssl.m4 and
+	m4/sha3.m4.
+	(configure.ac): Invoke gl_SHA3. Remove gl_BIGENDIAN.
+	* modules/crypto/sha3-buffer-tests (Makefile.am): Link to @LIB_CRYPTO@.
+
 2025-09-02  Bruno Haible  <[email protected]>
 
 	tests: Fix potential link errors.
diff --git a/lib/sha3.c b/lib/sha3.c
index f4e56ab3a1..5da85db5f2 100644
--- a/lib/sha3.c
+++ b/lib/sha3.c
@@ -32,6 +32,8 @@
 # define SWAP(n) (n)
 #endif
 
+#if ! HAVE_OPENSSL_SHA3
+
 static const u64 rc[] = {
   u64init (0x00000000, 0x00000001), u64init (0x00000000, 0x00008082),
   u64init (0x80000000, 0x0000808A), u64init (0x80000000, 0x80008000),
@@ -314,3 +316,72 @@ sha3_process_block (const void *buffer, size_t len, struct sha3_ctx *ctx)
         }
     }
 }
+
+#else /* OpenSSL implementation.  */
+
+#define DEFINE_SHA3_INIT_CTX(SIZE)                                      \
+  void                                                                  \
+  sha3_##SIZE##_init_ctx (struct sha3_ctx *ctx)                         \
+  {                                                                     \
+    int rc;                                                             \
+    ctx->evp_ctx = EVP_MD_CTX_create ();                                \
+    if (ctx->evp_ctx == NULL)                                           \
+      abort ();                                                         \
+    rc = EVP_DigestInit_ex (ctx->evp_ctx, EVP_sha3_##SIZE (), NULL);    \
+    if (rc == 0)                                                        \
+      abort ();                                                         \
+  }
+
+DEFINE_SHA3_INIT_CTX (224)
+DEFINE_SHA3_INIT_CTX (256)
+DEFINE_SHA3_INIT_CTX (384)
+DEFINE_SHA3_INIT_CTX (512)
+
+void *
+sha3_read_ctx (const struct sha3_ctx *ctx, void *resbuf)
+{
+  /* Assume any unprocessed bytes in ctx are not to be ignored.  */
+  int result = EVP_DigestFinal_ex (ctx->evp_ctx, resbuf, NULL);
+  if (result == 0)
+    abort ();
+  return resbuf;
+}
+
+void *
+sha3_finish_ctx (struct sha3_ctx *ctx, void *resbuf)
+{
+  void *result = sha3_read_ctx (ctx, resbuf);
+  EVP_MD_CTX_free (ctx->evp_ctx);
+  return resbuf;
+}
+
+#define DEFINE_SHA3_BUFFER(SIZE)                                        \
+  void *                                                                \
+  sha3_##SIZE##_buffer (const char *buffer, size_t len, void *resblock) \
+  {                                                                     \
+    struct sha3_ctx ctx;                                                \
+    sha3_##SIZE##_init_ctx (&ctx);                                      \
+    sha3_process_bytes (buffer, len, &ctx);                             \
+    return sha3_finish_ctx (&ctx, resblock);                            \
+  }
+
+DEFINE_SHA3_BUFFER (224)
+DEFINE_SHA3_BUFFER (256)
+DEFINE_SHA3_BUFFER (384)
+DEFINE_SHA3_BUFFER (512)
+
+void
+sha3_process_bytes (const void *buffer, size_t len, struct sha3_ctx *ctx)
+{
+  int result = EVP_DigestUpdate (ctx->evp_ctx, buffer, len);
+  if (result == 0)
+    abort ();
+}
+
+void
+sha3_process_block (const void *buffer, size_t len, struct sha3_ctx *ctx)
+{
+  sha3_process_bytes (buffer, len, ctx);
+}
+
+#endif
diff --git a/lib/sha3.h b/lib/sha3.h
index 8e0a7a7fdf..7de1216fda 100644
--- a/lib/sha3.h
+++ b/lib/sha3.h
@@ -28,6 +28,12 @@
 extern "C" {
 # endif
 
+/* OpenSSL does not have the Init, Update, Final API for SHA-3.  We must use
+   the EVP API.  */
+# if HAVE_OPENSSL_SHA3
+#  include <openssl/evp.h>
+# endif
+
 /* Digest sizes in bytes.  */
 enum { SHA3_224_DIGEST_SIZE = 224 / 8 };
 enum { SHA3_256_DIGEST_SIZE = 256 / 8 };
@@ -43,11 +49,17 @@ enum { SHA3_512_BLOCK_SIZE = 576 / 8 };
 /* Structure to save state of computation between the single steps.  */
 struct sha3_ctx
 {
+# if HAVE_OPENSSL_SHA3
+  /* This is an incomplete type, so we can only place a pointer in the
+     struct.  */
+  EVP_MD_CTX *evp_ctx;
+# else
   u64 state[25];
   uint8_t buffer[144]; /* Up to BLOCKLEN in use.  */
   size_t buflen;       /* ≥ 0, ≤ BLOCKLEN  */
   size_t digestlen;    /* One of SHA3_{224,256,384,512}_DIGEST_SIZE.  */
   size_t blocklen;     /* One of SHA3_{224,256,384,512}_BLOCK_SIZE.  */
+# endif
 };
 
 /* Initialize structure containing state of computation.  */
diff --git a/m4/gl-openssl.m4 b/m4/gl-openssl.m4
index 3cfea50fe5..e91be782f9 100644
--- a/m4/gl-openssl.m4
+++ b/m4/gl-openssl.m4
@@ -1,5 +1,5 @@
 # gl-openssl.m4
-# serial 7
+# serial 8
 dnl Copyright (C) 2013-2025 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -58,12 +58,17 @@ AC_DEFUN([gl_CRYPTO_CHECK]
     fi
     if test "x$with_openssl" != xauto-gpl-compat ||
        test "x$gl_cv_openssl_gpl_compat" = xyes; then
-      AC_CHECK_LIB([crypto], [$1],
-        [AC_CHECK_HEADERS(
-           m4_if([$1], [MD5], [openssl/md5.h], [openssl/sha.h]),
+      m4_if([$1], [SHA3],
+        [AC_CHECK_LIB([crypto], [EVP_sha3_224],
            [LIB_CRYPTO=-lcrypto
             AC_DEFINE([HAVE_OPENSSL_$1], [1],
-              [Define to 1 if libcrypto is used for $1.])])])
+              [Define to 1 if libcrypto is used for $1.])])],
+        [AC_CHECK_LIB([crypto], [$1],
+           [AC_CHECK_HEADERS(
+              m4_if([$1], [MD5], [openssl/md5.h], [openssl/sha.h]),
+              [LIB_CRYPTO=-lcrypto
+               AC_DEFINE([HAVE_OPENSSL_$1], [1],
+                 [Define to 1 if libcrypto is used for $1.])])])])
     fi
     if test "x$LIB_CRYPTO" = x; then
       message='openssl development library not found for $1.
diff --git a/m4/sha3.m4 b/m4/sha3.m4
new file mode 100644
index 0000000000..773f420ff9
--- /dev/null
+++ b/m4/sha3.m4
@@ -0,0 +1,16 @@
+# sha3.m4
+# serial 1
+dnl Copyright (C) 2025 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+dnl This file is offered as-is, without any warranty.
+
+AC_DEFUN([gl_SHA3],
+[
+  dnl Prerequisites of lib/sha3.c.
+  AC_REQUIRE([gl_BIGENDIAN])
+
+  dnl Determine HAVE_OPENSSL_SHA3 and LIB_CRYPTO
+  gl_CRYPTO_CHECK([SHA3])
+])
diff --git a/modules/crypto/sha3-buffer b/modules/crypto/sha3-buffer
index 375e7ba6a2..83b3a090ff 100644
--- a/modules/crypto/sha3-buffer
+++ b/modules/crypto/sha3-buffer
@@ -4,6 +4,8 @@ Compute SHA-3 checksums.
 Files:
 lib/sha3.h
 lib/sha3.c
+m4/gl-openssl.m4
+m4/sha3.m4
 
 Depends-on:
 byteswap
@@ -13,7 +15,7 @@ u64
 
 configure.ac:
 AC_REQUIRE([AC_C_RESTRICT])
-AC_REQUIRE([gl_BIGENDIAN])
+gl_SHA3
 
 Makefile.am:
 lib_SOURCES += sha3.c
@@ -21,6 +23,9 @@ lib_SOURCES += sha3.c
 Include:
 "sha3.h"
 
+Link:
+$(LIB_CRYPTO)
+
 License:
 LGPLv2+
 
diff --git a/modules/crypto/sha3-buffer-tests b/modules/crypto/sha3-buffer-tests
index 0f9e57318a..ebb293381b 100644
--- a/modules/crypto/sha3-buffer-tests
+++ b/modules/crypto/sha3-buffer-tests
@@ -24,7 +24,15 @@ check_PROGRAMS += test-sha3-224-buffer test-sha3-256-buffer
 check_PROGRAMS += test-sha3-384-buffer test-sha3-512-buffer
 noinst_PROGRAMS += bench-sha3-224 bench-sha3-256
 noinst_PROGRAMS += bench-sha3-384 bench-sha3-512
+test_sha3_224_buffer_LDADD = $(LDADD) @LIB_CRYPTO@
+test_sha3_256_buffer_LDADD = $(LDADD) @LIB_CRYPTO@
+test_sha3_384_buffer_LDADD = $(LDADD) @LIB_CRYPTO@
+test_sha3_512_buffer_LDADD = $(LDADD) @LIB_CRYPTO@
 bench_sha3_224_CPPFLAGS = $(AM_CPPFLAGS) -DNDEBUG
+bench_sha3_224_LDADD = $(LDADD) @LIB_CRYPTO@
 bench_sha3_256_CPPFLAGS = $(AM_CPPFLAGS) -DNDEBUG
+bench_sha3_256_LDADD = $(LDADD) @LIB_CRYPTO@
 bench_sha3_384_CPPFLAGS = $(AM_CPPFLAGS) -DNDEBUG
+bench_sha3_384_LDADD = $(LDADD) @LIB_CRYPTO@
 bench_sha3_512_CPPFLAGS = $(AM_CPPFLAGS) -DNDEBUG
+bench_sha3_512_LDADD = $(LDADD) @LIB_CRYPTO@
-- 
2.51.0

Reply via email to