From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>

I created a test file via
        dd if=/dev/zero bs=1024k count=1024 | xz -v -0 -Csha256

and compared the in-tree sha256 implementation on a Ryzen (CPU
acceleration available):

| Performance counter stats for 'xz --test sha256.xz' (5 runs):
|
|    20.748.708.638      cycles                    #    4,174 GHz               
       ( +-  1,23% )  (83,29%)
|    63.371.432.190      instructions              #    3,05  insn per cycle
|                                                  #    0,23  stalled cycles 
per insn  ( +-  0,01% )  (83,37%)
|            4,9778 +- 0,0488 seconds time elapsed  ( +-  0,98% )

vs OpenSSL's:

| Performance counter stats for './src/xz/xz --test sha256.xz' (5 runs):
|
|    10.037.180.776      cycles                    #    4,230 GHz               
       ( +-  0,03% )  (83,18%)
|    16.126.619.033      instructions              #    1,61  insn per cycle
|                                                  #    0,50  stalled cycles 
per insn  ( +-  0,01% )  (83,43%)
|           2,37200 +- 0,00621 seconds time elapsed  ( +-  0,26% )

worse insn/cycle ratio, much less instructions half run time. It is
even slightly better compared to crc64:

| Performance counter stats for './src/xz/xz --test crc64.xz' (5 runs):
|
|    10.989.495.452      cycles                    #    4,250 GHz               
       ( +-  0,04% )  (83,22%)
|    17.829.100.301      instructions              #    1,62  insn per cycle
|                                                  #    0,43  stalled cycles 
per insn  ( +-  0,02% )  (83,42%)
|            2,5850 +- 0,0103 seconds time elapsed  ( +-  0,40% )

For the protocol, compared to no checksum:

| Performance counter stats for './src/xz/xz --test none.xz' (5 runs):
|
|     7.857.471.590      cycles                    #    4,237 GHz               
       ( +-  0,03% )  (83,08%)
|    13.257.837.157      instructions              #    1,69  insn per cycle
|
|           1,85337 +- 0,00440 seconds time elapsed  ( +-  0,24% )

Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
---

I learned here that rpm is using sha256 based checksums. So that might
be a good thing.

 configure.ac              | 24 +++++++++++++++++++++++-
 src/liblzma/Makefile.am   |  1 +
 src/liblzma/check/check.h | 33 ++++++++++++++++++++++++++++++++-
 src/lzmainfo/Makefile.am  |  2 +-
 src/xz/Makefile.am        |  2 +-
 src/xzdec/Makefile.am     |  2 +-
 6 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/configure.ac b/configure.ac
index 2418e4b039e61..5e0eaefc99c92 100644
--- a/configure.ac
+++ b/configure.ac
@@ -289,6 +289,19 @@ else
        AC_MSG_RESULT([no])
 fi
 
+AC_MSG_CHECKING([if openssl should be used])
+AC_ARG_ENABLE([openssl], AS_HELP_STRING([--enable-openssl],
+               [Use openssl from the operating system.
+               See INSTALL for possible subtle problems.]),
+               [], [enable_openssl=no])
+if test "x$enable_openssl" != "xyes"; then
+       enable_openssl=no
+fi
+if test "x$enable_openssl" = xyes; then
+       AC_MSG_RESULT([yes])
+else
+       AC_MSG_RESULT([no])
+fi
 
 ###########################
 # Assembler optimizations #
@@ -740,6 +753,7 @@ TUKLIB_MBSTR
 sha256_header_found=no
 sha256_type_found=no
 sha256_func_found=no
+openssl_found=no
 if test "x$enable_external_sha256" = "xyes"; then
        # Test for Common Crypto before others, because Darwin has sha256.h
        # too and we don't want to use that, because on older versions it
@@ -770,11 +784,19 @@ if test "x$enable_external_sha256" = "xyes"; then
                                [sha256_func_found=yes ; break])
                fi
        fi
+elif test "x$enable_openssl" = "xyes"; then
+       PKG_CHECK_MODULES([OPENSSL_CRYPTO], [libcrypto],
+                         [AC_DEFINE([HAVE_OPENSSL_CRYPTO], [1], [Use SHA256 
from openssl])
+                         openssl_found=yes])
 fi
-AM_CONDITIONAL([COND_INTERNAL_SHA256], [test "x$sha256_func_found" = xno])
+
+AM_CONDITIONAL([COND_INTERNAL_SHA256], [test "x$sha256_func_found" = xno -a 
"x$openssl_found" = xno])
 if test "x$enable_external_sha256$sha256_func_found" = xyesno; then
        AC_MSG_ERROR([--enable-external-sha256 was specified but no supported 
external SHA-256 implementation was found])
 fi
+if test "x$enable_openssl$openssl_found" = xyesno; then
+       AC_MSG_ERROR([--enable-openssl was specified but openssl was not 
found.])
+fi
 
 # Check for SSE2 intrinsics.
 AC_CHECK_DECL([_mm_movemask_epi8],
diff --git a/src/liblzma/Makefile.am b/src/liblzma/Makefile.am
index 6323e26aade10..3afb08169840c 100644
--- a/src/liblzma/Makefile.am
+++ b/src/liblzma/Makefile.am
@@ -25,6 +25,7 @@ liblzma_la_CPPFLAGS = \
        -I$(top_srcdir)/src/common \
        -DTUKLIB_SYMBOL_PREFIX=lzma_
 liblzma_la_LDFLAGS = -no-undefined -version-info 8:99:3
+liblzma_la_LDFLAGS += $(OPENSSL_CRYPTO_LIBS)
 
 EXTRA_DIST += liblzma.map validate_map.sh
 if COND_SYMVERS
diff --git a/src/liblzma/check/check.h b/src/liblzma/check/check.h
index 3007d889b0f3a..0249025ec179a 100644
--- a/src/liblzma/check/check.h
+++ b/src/liblzma/check/check.h
@@ -20,6 +20,7 @@
 // both a usable header and a type have already been found.
 #if !(defined(HAVE_CC_SHA256_INIT) \
                || defined(HAVE_SHA256_INIT) \
+               || defined(HAVE_OPENSSL_CRYPTO) \
                || defined(HAVE_SHA256INIT))
 #      define HAVE_INTERNAL_SHA256 1
 #endif
@@ -34,6 +35,8 @@
 #elif defined(HAVE_SHA2_H)
 #      include <sys/types.h>
 #      include <sha2.h>
+#elif defined(HAVE_OPENSSL_CRYPTO)
+#      include <openssl/evp.h>
 #endif
 
 #if defined(HAVE_INTERNAL_SHA256)
@@ -51,6 +54,11 @@ typedef CC_SHA256_CTX lzma_sha256_state;
 typedef SHA256_CTX lzma_sha256_state;
 #elif defined(HAVE_SHA2_CTX)
 typedef SHA2_CTX lzma_sha256_state;
+#elif defined(HAVE_OPENSSL_CRYPTO)
+typedef struct {
+       EVP_MD_CTX *ctx;
+
+} lzma_sha256_state;
 #endif
 
 #if defined(HAVE_INTERNAL_SHA256)
@@ -121,8 +129,31 @@ extern void lzma_check_update(lzma_check_state *check, 
lzma_check type,
 /// Finish the check calculation and store the result to check->buffer.u8.
 extern void lzma_check_finish(lzma_check_state *check, lzma_check type);
 
+#ifdef HAVE_OPENSSL_CRYPTO
 
-#ifndef LZMA_SHA256FUNC
+/// Prepare SHA-256 state for new input.
+static inline void lzma_sha256_init(lzma_check_state *check)
+{
+       check->state.sha256.ctx = EVP_MD_CTX_new();
+       EVP_DigestInit_ex(check->state.sha256.ctx,
+                        EVP_get_digestbyname("sha256"), NULL);
+}
+
+/// Update the SHA-256 hash state
+static inline void lzma_sha256_update(
+               const uint8_t *buf, size_t size, lzma_check_state *check)
+{
+       EVP_DigestUpdate(check->state.sha256.ctx, buf, size);
+}
+
+/// Finish the SHA-256 calculation and store the result to check->buffer.u8.
+static inline void lzma_sha256_finish(lzma_check_state *check)
+{
+       EVP_DigestFinal_ex(check->state.sha256.ctx, check->buffer.u8, NULL);
+       EVP_MD_CTX_free(check->state.sha256.ctx);
+}
+
+#elif !defined(LZMA_SHA256FUNC)
 
 /// Prepare SHA-256 state for new input.
 extern void lzma_sha256_init(lzma_check_state *check);
diff --git a/src/lzmainfo/Makefile.am b/src/lzmainfo/Makefile.am
index ff7172b50f380..51424effb750a 100644
--- a/src/lzmainfo/Makefile.am
+++ b/src/lzmainfo/Makefile.am
@@ -28,7 +28,7 @@ if COND_GNULIB
 lzmainfo_LDADD += $(top_builddir)/lib/libgnu.a
 endif
 
-lzmainfo_LDADD += $(LTLIBINTL)
+lzmainfo_LDADD += $(LTLIBINTL) $(OPENSSL_CRYPTO_LIBS)
 
 
 dist_man_MANS = lzmainfo.1
diff --git a/src/xz/Makefile.am b/src/xz/Makefile.am
index 4bc64f360ada5..8d6604c8ffb22 100644
--- a/src/xz/Makefile.am
+++ b/src/xz/Makefile.am
@@ -60,7 +60,7 @@ xz_LDADD += $(top_builddir)/lib/libgnu.a
 endif
 
 # libgnu.a may need these libs, so this must be after libgnu.a.
-xz_LDADD += $(LTLIBINTL)
+xz_LDADD += $(LTLIBINTL) $(OPENSSL_CRYPTO_LIBS)
 
 
 # Windows resource compiler support
diff --git a/src/xzdec/Makefile.am b/src/xzdec/Makefile.am
index 90f1e922a07c6..59ad965eb1678 100644
--- a/src/xzdec/Makefile.am
+++ b/src/xzdec/Makefile.am
@@ -32,7 +32,7 @@ if COND_GNULIB
 xzdec_LDADD += $(top_builddir)/lib/libgnu.a
 endif
 
-xzdec_LDADD += $(LTLIBINTL)
+xzdec_LDADD += $(LTLIBINTL) $(OPENSSL_CRYPTO_LIBS)
 
 
 lzmadec_SOURCES = \
-- 
2.30.0


Reply via email to