From: Sebastian Andrzej Siewior <[email protected]>
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 <[email protected]>
---
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