diff --git a/.gitignore b/.gitignore index 7964e136..f73526b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,59 +1,57 @@ *.o *.a *.la *.lo *.pc *.tar.* *.sha256* stamp-h1 Makefile.in Makefile .deps .libs .version .dirstamp # build-aux/release.mk related litter /.tarball-version /tag-* aclocal.m4 autoconf autoheader autom4te.cache automake compile config.* configure* debian/changelog debian/kronosnetd.postinst debian/patches depcomp install-sh libtoolize ltmain.sh m4/libtool.m4 m4/lt~obsolete.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 missing libtool autoscan.log init/kronosnetd init/kronosnetd.service kronosnetd/kronosnetd kronosnetd/knet-keygen kronosnetd/kronosnetd.logrotate kronosnet.spec -libknet/compress_canary -libknet/crypto_canary *.swp *_test *_bench test-driver *.trs *.log Doxyfile doxyfile.stamp xml/ diff --git a/configure.ac b/configure.ac index 5e8db12b..13b02c3e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,520 +1,502 @@ # # Copyright (C) 2010-2017 Red Hat, Inc. All rights reserved. # # Authors: Fabio M. Di Nitto # Federico Simoncelli # # This software licensed under GPL-2.0+, LGPL-2.0+ # # -*- Autoconf -*- # Process this file with autoconf to produce a configure script. # AC_PREREQ([2.63]) AC_INIT([kronosnet], m4_esyscmd([build-aux/git-version-gen .tarball-version]), [devel@lists.kronosnet.org]) AC_USE_SYSTEM_EXTENSIONS AM_INIT_AUTOMAKE([1.13 dist-bzip2 dist-xz color-tests -Wno-portability subdir-objects]) LT_PREREQ([2.2.6]) LT_INIT AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_SRCDIR([kronosnetd/main.c]) AC_CONFIG_HEADERS([config.h]) AC_CANONICAL_HOST AC_PROG_LIBTOOL AC_LANG([C]) systemddir=${prefix}/lib/systemd/system if test "$prefix" = "NONE"; then prefix="/usr" if test "$localstatedir" = "\${prefix}/var"; then localstatedir="/var" fi if test "$sysconfdir" = "\${prefix}/etc"; then sysconfdir="/etc" fi if test "$systemddir" = "NONE/lib/systemd/system"; then systemddir=/lib/systemd/system fi if test "$libdir" = "\${exec_prefix}/lib"; then if test -e /usr/lib64; then libdir="/usr/lib64" else libdir="/usr/lib" fi fi fi AC_PROG_AWK AC_PROG_GREP AC_PROG_SED AC_PROG_CPP AC_PROG_CC AC_PROG_CC_C99 if test "x$ac_cv_prog_cc_c99" = "xno"; then AC_MSG_ERROR(["C99 support is required"]) fi AC_PROG_LN_S AC_PROG_INSTALL AC_PROG_MAKE_SET PKG_PROG_PKG_CONFIG AC_CHECK_PROGS([DOXYGEN], [doxygen]) AC_CHECK_PROGS([DOXY2MAN], [doxy2man]) manpageupdates=1 if test "x$DOXYGEN" = "x" || test "x$DOXY2MAN" = "x"; then manpageupdates=0; fi AM_CONDITIONAL([MANPAGEUPDATES], [test $manpageupdates -gt 0]) AC_CHECK_PROGS([VALGRIND_EXEC], [valgrind]) AM_CONDITIONAL([HAS_VALGRIND], [test x$VALGRIND_EXEC != "x"]) AC_ARG_ENABLE([libknet-sctp], [ --disable-libknet-sctp : disable libknet SCTP support ],, [ enable_libknet_sctp="yes" ]) AM_CONDITIONAL([BUILDSCTP], [test x$enable_libknet_sctp = xyes]) AC_ARG_ENABLE([crypto-all], [ --disable-crypto-all : disable libknet all crypto modules support ],, [ enable_crypto_all="yes" ]) AC_ARG_ENABLE([crypto-nss], [ --disable-crypto-nss : disable libknet nss support ],, [ enable_crypto_nss="$enable_crypto_all" ]) AM_CONDITIONAL([BUILDCRYPTONSS], [test x$enable_crypto_nss = xyes]) AC_ARG_ENABLE([crypto-openssl], [ --disable-crypto-openssl : disable libknet openssl support ],, [ enable_crypto_openssl="$enable_crypto_all" ]) AM_CONDITIONAL([BUILDCRYPTOOPENSSL], [test x$enable_crypto_openssl = xyes]) AC_ARG_ENABLE([compress-all], [ --disable-compress-all : disable libknet all compress modules support ],, [ enable_compress_all="yes" ]) AC_ARG_ENABLE([compress-zlib], [ --disable-compress-zlib : disable libknet zlib support ],, [ enable_compress_zlib="$enable_compress_all" ]) AM_CONDITIONAL([BUILDCOMPZLIB], [test x$enable_compress_zlib = xyes]) AC_ARG_ENABLE([compress-lz4], [ --disable-compress-lz4 : disable libknet lz4 support ],, [ enable_compress_lz4="$enable_compress_all" ]) AM_CONDITIONAL([BUILDCOMPLZ4], [test x$enable_compress_lz4 = xyes]) AC_ARG_ENABLE([compress-lzo2], [ --disable-compress-lzo2 : disable libknet lzo2 support ],, [ enable_compress_lzo2="$enable_compress_all" ]) AM_CONDITIONAL([BUILDCOMPLZO2], [test x$enable_compress_lzo2 = xyes]) AC_ARG_ENABLE([compress-lzma], [ --disable-compress-lzma : disable libknet lzma support ],, [ enable_compress_lzma="$enable_compress_all" ]) AM_CONDITIONAL([BUILDCOMPLZMA], [test x$enable_compress_lzma = xyes]) AC_ARG_ENABLE([compress-bzip2], [ --disable-compress-bzip2 : disable libknet bzip2 support ],, [ enable_compress_bzip2="$enable_compress_all" ]) AM_CONDITIONAL([BUILDCOMPBZIP2], [test x$enable_compress_bzip2 = xyes]) AC_ARG_ENABLE([poc], [ --enable-poc : enable building poc code ],, [ enable_poc="no" ]) AM_CONDITIONAL([BUILD_POC], [test x$enable_poc = xyes]) AC_ARG_ENABLE([kronosnetd], [ --enable-kronosnetd : Kronosnetd support ],, [ enable_kronosnetd="no" ]) AM_CONDITIONAL([BUILD_KRONOSNETD], [test x$enable_kronosnetd = xyes]) AC_ARG_ENABLE([runautogen], [ --enable-runautogen : run autogen.sh ],, [ enable_runautogen="no" ]) AM_CONDITIONAL([BUILD_RUNAUTOGEN], [test x$enable_runautogen = xyes]) AC_ARG_ENABLE([libtap], [ --enable-libtap : libtap support ],, [ enable_libtap="no" ]) if test "x$enable_kronosnetd" = xyes; then enable_libtap=yes fi AM_CONDITIONAL([BUILD_LIBTAP], [test x$enable_libtap = xyes]) ## local helper functions # this function checks if CC support options passed as # args. Global CFLAGS are ignored during this test. cc_supports_flag() { saveCPPFLAGS="$CPPFLAGS" CPPFLAGS="$@" if echo $CC | grep -q clang; then CPPFLAGS="-Werror $CPPFLAGS" fi AC_MSG_CHECKING([whether $CC supports "$@"]) AC_PREPROC_IFELSE([AC_LANG_PROGRAM([])], [RC=0; AC_MSG_RESULT([yes])], [RC=1; AC_MSG_RESULT([no])]) CPPFLAGS="$saveCPPFLAGS" return $RC } # Checks for C features AC_C_INLINE # Checks for libraries. AX_PTHREAD(,[AC_MSG_ERROR([POSIX threads support is required])]) AC_CHECK_LIB([m], [ceil], [AC_SUBST([m_LIBS], [-lm])], [AC_MSG_ERROR([kronosnet requires m library])]) saved_LIBS="$LIBS" LIBS= AC_SEARCH_LIBS([clock_gettime], [rt], , [AC_MSG_ERROR([clock_gettime not found])]) AC_SUBST([rt_LIBS], [$LIBS]) LIBS= AC_SEARCH_LIBS([dlopen], [dl dld], , [AC_MSG_ERROR([dlopen not found])]) AC_SUBST([dl_LIBS], [$LIBS]) LIBS="$saved_LIBS" # OS detection AC_MSG_CHECKING([for os in ${host_os}]) case "$host_os" in *linux*) AC_DEFINE_UNQUOTED([KNET_LINUX], [1], [Compiling for Linux platform]) AC_MSG_RESULT([Linux]) ;; *bsd*) AC_DEFINE_UNQUOTED([KNET_BSD], [1], [Compiling for BSD platform]) AC_MSG_RESULT([BSD]) if test "x$enable_libtap" = xyes; then AC_MSG_ERROR([libtap is not currently supported on BSD platforms]) fi ;; *) AC_MSG_ERROR([Unsupported OS? hmmmm]) ;; esac -AC_DEFUN([KNET_PKG_SONAME],[ -AC_MSG_CHECKING([for soname of $1]) -$CC -shared -nostdlib -o dummy.so -Wl,--no-as-needed $$1_LIBS -# Choosing the first SONAME is a best guess here: -knet_pkg_soname=`$OBJDUMP -p dummy.so | $SED -n '/^Dynamic Section:$/,/^[^ ]/{s/ *NEEDED *//p;}' | head -n1` -rm dummy.so -AC_DEFINE_UNQUOTED([$2],["$knet_pkg_soname"],[SONAME of the $1 library]) -AS_IF([test "x$knet_pkg_soname" = x], - [AC_MSG_FAILURE([failed to extract SONAME])], - [AC_MSG_RESULT([$knet_pkg_soname])]) -]) - # crypto libraries checks if test "x$enable_crypto_nss" = xyes; then PKG_CHECK_MODULES([nss],[nss]) AC_DEFINE_UNQUOTED([BUILDCRYPTONSS], [1], [Enable nss crypto]) - KNET_PKG_SONAME([nss],[LIBNSS3]) fi if test "x$enable_crypto_openssl" = xyes; then PKG_CHECK_MODULES([openssl],[libcrypto < 1.1], [AC_DEFINE_UNQUOTED([BUILDCRYPTOOPENSSL10], [1], [openssl 1.0 crypto])], [PKG_CHECK_MODULES([openssl],[libcrypto >= 1.1], [AC_DEFINE_UNQUOTED([BUILDCRYPTOOPENSSL11], [1], [openssl 1.1 crypto])])]) AC_DEFINE_UNQUOTED([BUILDCRYPTOOPENSSL], [1], [Enable openssl crypto]) - KNET_PKG_SONAME([openssl],[LIBOPENSSL]) fi # compress libraries checks if test "x$enable_compress_zlib" = xyes; then PKG_CHECK_MODULES([zlib], [zlib]) AC_DEFINE_UNQUOTED([BUILDCOMPZLIB], [1], [Enable zlib compression]) - KNET_PKG_SONAME([zlib],[LIBZ_1]) fi if test "x$enable_compress_lz4" = xyes; then PKG_CHECK_MODULES([liblz4], [liblz4]) AC_DEFINE_UNQUOTED([BUILDCOMPLZ4], [1], [Enable lz4 compress]) - KNET_PKG_SONAME([liblz4],[LIBLZ4_1]) fi if test "x$enable_compress_lzo2" = xyes; then PKG_CHECK_MODULES([lzo2], [lzo2],, [AC_CHECK_HEADERS([lzo/lzo1x.h], [AC_CHECK_LIB([lzo2], [lzo1x_decompress_safe], [AC_SUBST([lzo2_LIBS], [-llzo2])])], [AC_MSG_ERROR(["missing required lzo/lzo1x.h header"])])]) AC_DEFINE_UNQUOTED([BUILDCOMPLZO2], [1], [Enable lzo2 compress]) - KNET_PKG_SONAME([lzo2],[LIBLZO2_2]) fi if test "x$enable_compress_lzma" = xyes; then PKG_CHECK_MODULES([liblzma], [liblzma]) AC_DEFINE_UNQUOTED([BUILDCOMPLZMA], [1], [Enable lzma compress]) - KNET_PKG_SONAME([liblzma],[LIBLZMA_5]) fi if test "x$enable_compress_bzip2" = xyes; then PKG_CHECK_MODULES([bzip2], [bzip2],, [AC_CHECK_HEADERS([bzlib.h], [AC_CHECK_LIB([bz2], [BZ2_bzBuffToBuffCompress], [AC_SUBST([bzip2_LIBS], [-lbz2])])], [AC_MSG_ERROR(["missing required bzlib.h"])])]) AC_DEFINE_UNQUOTED([BUILDCOMPBZIP2], [1], [Enable bzip2 compress]) fi # Checks for header files. AC_CHECK_HEADERS([fcntl.h]) AC_CHECK_HEADERS([stdlib.h]) AC_CHECK_HEADERS([string.h]) AC_CHECK_HEADERS([strings.h]) AC_CHECK_HEADERS([sys/ioctl.h]) AC_CHECK_HEADERS([syslog.h]) AC_CHECK_HEADERS([unistd.h]) AC_CHECK_HEADERS([netinet/in.h]) AC_CHECK_HEADERS([sys/socket.h]) AC_CHECK_HEADERS([arpa/inet.h]) AC_CHECK_HEADERS([netdb.h]) AC_CHECK_HEADERS([limits.h]) AC_CHECK_HEADERS([stdint.h]) AC_CHECK_HEADERS([sys/epoll.h]) if test "x$enable_libknet_sctp" = xyes; then AC_CHECK_HEADERS([netinet/sctp.h],, [AC_MSG_ERROR(["missing required SCTP headers"])]) fi # Checks for typedefs, structures, and compiler characteristics. AC_C_INLINE AC_TYPE_SIZE_T AC_TYPE_PID_T AC_TYPE_SSIZE_T AC_TYPE_UINT8_T AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_INT32_T # Checks for library functions. AC_FUNC_ALLOCA AC_FUNC_FORK AC_FUNC_MALLOC AC_FUNC_REALLOC AC_CHECK_FUNCS([kevent]) # if neither sys/epoll.h nor kevent are present, we should fail. if test "x$ac_cv_header_sys_epoll_h" = xno && test "x$ac_cv_func_kevent" = xno; then AC_MSG_ERROR([Both epoll and kevent unavailable on this OS]) fi if test "x$ac_cv_header_sys_epoll_h" = xyes && test "x$ac_cv_func_kevent" = xyes; then AC_MSG_ERROR([Both epoll and kevent available on this OS, please contact the maintainers to fix the code]) fi # checks (for kronosnetd) if test "x$enable_kronosnetd" = xyes; then AC_CHECK_HEADERS([security/pam_appl.h], [AC_CHECK_LIB([pam], [pam_start], [AC_SUBST([pam_LIBS], [-lpam])], [AC_MSG_ERROR([Unable to find LinuxPAM devel files])])]) AC_CHECK_HEADERS([security/pam_misc.h], [AC_CHECK_LIB([pam_misc], [misc_conv], [AC_SUBST([pam_misc_LIBS], [-lpam_misc])], [AC_MSG_ERROR([Unable to find LinuxPAM MISC devel files])])]) PKG_CHECK_MODULES([libqb], [libqb]) AC_CHECK_LIB([qb], [qb_log_thread_priority_set], [have_qb_log_thread_priority_set="yes"], [have_qb_log_thread_priority_set="no"]) if test "x${have_qb_log_thread_priority_set}" = xyes; then AC_DEFINE_UNQUOTED([HAVE_QB_LOG_THREAD_PRIORITY_SET], [1], [have qb_log_thread_priority_set]) fi fi # local options AC_ARG_ENABLE([debug], [ --enable-debug enable debug build. ], [ default="no" ]) AC_ARG_WITH([initdefaultdir], [ --with-initdefaultdir : path to /etc/sysconfig/.. or /etc/default dir. ], [ INITDEFAULTDIR="$withval" ], [ INITDEFAULTDIR="$sysconfdir/default" ]) AC_ARG_WITH([initddir], [ --with-initddir=DIR : path to init script directory. ], [ INITDDIR="$withval" ], [ INITDDIR="$sysconfdir/init.d" ]) AC_ARG_WITH([systemddir], [ --with-systemddir=DIR : path to systemd unit files directory. ], [ SYSTEMDDIR="$withval" ], [ SYSTEMDDIR="$systemddir" ]) AC_ARG_WITH([syslogfacility], [ --with-syslogfacility=FACILITY default syslog facility. ], [ SYSLOGFACILITY="$withval" ], [ SYSLOGFACILITY="LOG_DAEMON" ]) AC_ARG_WITH([sysloglevel], [ --with-sysloglevel=LEVEL default syslog level. ], [ SYSLOGLEVEL="$withval" ], [ SYSLOGLEVEL="LOG_INFO" ]) AC_ARG_WITH([defaultadmgroup], [ --with-defaultadmgroup=GROUP define PAM group. Users part of this group will be allowed to configure kronosnet. Others will only receive read-only rights. ], [ DEFAULTADMGROUP="$withval" ], [ DEFAULTADMGROUP="kronosnetadm" ]) ## random vars LOGDIR=${localstatedir}/log/ RUNDIR=${localstatedir}/run/ DEFAULT_CONFIG_DIR=${sysconfdir}/kronosnet ## do subst AM_CONDITIONAL([DEBUG], [test "x${enable_debug}" = xyes]) AC_SUBST([DEFAULT_CONFIG_DIR]) AC_SUBST([INITDEFAULTDIR]) AC_SUBST([INITDDIR]) AC_SUBST([SYSTEMDDIR]) AC_SUBST([LOGDIR]) AC_SUBST([DEFAULTADMGROUP]) AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_DIR], ["$(eval echo ${DEFAULT_CONFIG_DIR})"], [Default config directory]) AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_FILE], ["$(eval echo ${DEFAULT_CONFIG_DIR}/kronosnetd.conf)"], [Default config file]) AC_DEFINE_UNQUOTED([LOGDIR], ["$(eval echo ${LOGDIR})"], [Default logging directory]) AC_DEFINE_UNQUOTED([DEFAULT_LOG_FILE], ["$(eval echo ${LOGDIR}/kronosnetd.log)"], [Default log file]) AC_DEFINE_UNQUOTED([RUNDIR], ["$(eval echo ${RUNDIR})"], [Default run directory]) AC_DEFINE_UNQUOTED([SYSLOGFACILITY], [$(eval echo ${SYSLOGFACILITY})], [Default syslog facility]) AC_DEFINE_UNQUOTED([SYSLOGLEVEL], [$(eval echo ${SYSLOGLEVEL})], [Default syslog level]) AC_DEFINE_UNQUOTED([DEFAULTADMGROUP], ["$(eval echo ${DEFAULTADMGROUP})"], [Default admin group]) ## *FLAGS handling ENV_CFLAGS="$CFLAGS" ENV_CPPFLAGS="$CPPFLAGS" ENV_LDFLAGS="$LDFLAGS" # debug build stuff if test "x${enable_debug}" = xyes; then AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code]) OPT_CFLAGS="-O0" else OPT_CFLAGS="-O3" fi # gdb flags if test "x${GCC}" = xyes; then GDB_FLAGS="-ggdb3" else GDB_FLAGS="-g" fi # extra warnings EXTRA_WARNINGS="" WARNLIST=" all extra unused shadow missing-prototypes missing-declarations suggest-attribute=noreturn suggest-attribute=format strict-prototypes declaration-after-statement pointer-arith write-strings cast-align bad-function-cast missing-format-attribute float-equal format=2 format-signedness format-security format-nonliteral no-long-long unsigned-char gnu89-inline no-strict-aliasing error address cpp overflow parentheses sequence-point switch shift-overflow=2 overlength-strings retundent-decls init-self uninitialized unused-but-set-variable unused-function unused-result unused-value unused-variable unknown-pragmas no-unused-parameter " for j in $WARNLIST; do if cc_supports_flag -W$j; then EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j"; fi done CFLAGS="$ENV_CFLAGS $lt_prog_compiler_pic $OPT_CFLAGS $GDB_FLAGS \ $EXTRA_WARNINGS $WERROR_CFLAGS" CPPFLAGS="$ENV_CPPFLAGS" LDFLAGS="$ENV_LDFLAGS $lt_prog_compiler_pic" AC_CONFIG_FILES([ Makefile init/Makefile libtap/Makefile libtap/libtap.pc kronosnetd/Makefile kronosnetd/kronosnetd.logrotate libknet/Makefile libknet/libknet.pc libknet/tests/Makefile libknet/man/Doxyfile libknet/man/Makefile poc-code/Makefile poc-code/iov-hash/Makefile poc-code/access-list/Makefile ]) AC_OUTPUT diff --git a/libknet/Makefile.am b/libknet/Makefile.am index 1a04c6fc..cc5cebce 100644 --- a/libknet/Makefile.am +++ b/libknet/Makefile.am @@ -1,145 +1,162 @@ # # Copyright (C) 2010-2017 Red Hat, Inc. All rights reserved. # # Authors: Fabio M. Di Nitto # Federico Simoncelli # # This software licensed under GPL-2.0+, LGPL-2.0+ # MAINTAINERCLEANFILES = Makefile.in include $(top_srcdir)/build-aux/check.mk SYMFILE = libknet_exported_syms EXTRA_DIST = $(SYMFILE) SUBDIRS = . tests man libversion = 1:0:0 # override global LIBS that pulls in lots of craft we don't need here LIBS = sources = \ common.c \ compat.c \ compress.c \ - compress_zlib.c \ - compress_lz4.c \ - compress_lzo2.c \ - compress_lzma.c \ crypto.c \ - crypto_nss.c \ - crypto_openssl.c \ handle.c \ host.c \ links.c \ logging.c \ netutils.c \ threads_common.c \ threads_dsthandler.c \ threads_heartbeat.c \ threads_pmtud.c \ threads_rx.c \ threads_tx.c \ transports.c \ transport_common.c \ transport_loopback.c \ transport_udp.c \ transport_sctp.c include_HEADERS = libknet.h pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libknet.pc noinst_HEADERS = \ common.h \ compat.h \ compress.h \ compress_model.h \ - compress_lz4.h \ - compress_lz4_remap.h \ - compress_lzma.h \ - compress_lzma_remap.h \ - compress_lzo2.h \ - compress_lzo2_remap.h \ - compress_zlib.h \ - compress_zlib_remap.h \ crypto.h \ - crypto_nss.h \ - crypto_nss_remap.h \ - crypto_openssl.h \ - crypto_openssl_remap.h \ + crypto_model.h \ host.h \ internals.h \ links.h \ logging.h \ netutils.h \ onwire.h \ - remap.h \ threads_common.h \ threads_dsthandler.h \ threads_heartbeat.h \ threads_pmtud.h \ threads_rx.h \ threads_tx.h \ transports.h \ transport_common.h \ transport_loopback.h \ transport_udp.h \ transport_sctp.h lib_LTLIBRARIES = libknet.la libknet_la_SOURCES = $(sources) -libknet_la_CFLAGS = $(PTHREAD_CFLAGS) \ - $(nss_CFLAGS) $(openssl_CFLAGS) \ - $(zlib_CFLAGS) $(liblz4_CFLAGS) $(lzo2_CFLAGS) $(liblzma_CFLAGS) +libknet_la_CFLAGS = $(PTHREAD_CFLAGS) EXTRA_libknet_la_DEPENDENCIES = $(SYMFILE) libknet_la_LDFLAGS = -Wl,--version-script=$(srcdir)/$(SYMFILE) \ --export-dynamic \ -Wl,-rpath=$(pkglibdir) \ -version-number $(libversion) libknet_la_LIBADD = $(PTHREAD_LIBS) $(dl_LIBS) $(rt_LIBS) $(m_LIBS) # Prepare empty value for appending pkglib_LTLIBRARIES = +if BUILDCOMPZLIB +pkglib_LTLIBRARIES += compress_zlib.la +compress_zlib_la_LDFLAGS = -module -avoid-version +compress_zlib_la_CFLAGS = $(zlib_CFLAGS) +compress_zlib_la_LIBADD = $(zlib_LIBS) +endif + +if BUILDCOMPLZ4 +pkglib_LTLIBRARIES += compress_lz4.la compress_lz4hc.la +compress_lz4_la_LDFLAGS = -module -avoid-version +compress_lz4_la_CFLAGS = $(liblz4_CFLAGS) +compress_lz4_la_LIBADD = $(liblz4_LIBS) +compress_lz4hc_la_LDFLAGS = -module -avoid-version +compress_lz4hc_la_CFLAGS = $(liblz4_CFLAGS) +compress_lz4hc_la_LIBADD = $(liblz4_LIBS) +endif + +if BUILDCOMPLZO2 +pkglib_LTLIBRARIES += compress_lzo2.la +compress_lzo2_la_LDFLAGS = -module -avoid-version +compress_lzo2_la_CFLAGS = $(lzo2_CFLAGS) +compress_lzo2_la_LIBADD = $(lzo2_LIBS) +endif + +if BUILDCOMPLZMA +pkglib_LTLIBRARIES += compress_lzma.la +compress_lzma_la_LDFLAGS = -module -avoid-version +compress_lzma_la_CFLAGS = $(liblzma_CFLAGS) +compress_lzma_la_LIBADD = $(liblzma_LIBS) +endif + if BUILDCOMPBZIP2 pkglib_LTLIBRARIES += compress_bzip2.la compress_bzip2_la_LDFLAGS = -module -avoid-version compress_bzip2_la_CFLAGS = $(bzip2_CFLAGS) compress_bzip2_la_LIBADD = $(bzip2_LIBS) endif -noinst_PROGRAMS = crypto_canary compress_canary -crypto_canary_SOURCES = crypto_canary.c -crypto_canary_CFLAGS = $(nss_CFLAGS) $(openssl_CFLAGS) -crypto_canary_LDADD = $(nss_LIBS) $(openssl_LIBS) -compress_canary_SOURCES = compress_canary.c -compress_canary_CFLAGS = $(zlib_CFLAGS) $(liblz4_CFLAGS) $(lzo2_CFLAGS) $(liblzma_CFLAGS) -compress_canary_LDADD = $(zlib_LIBS) $(liblz4_LIBS) $(lzo2_LIBS) $(liblzma_LIBS) +if BUILDCRYPTONSS +pkglib_LTLIBRARIES += crypto_nss.la +crypto_nss_la_LDFLAGS = -module -avoid-version +crypto_nss_la_CFLAGS = $(nss_CFLAGS) +crypto_nss_la_LIBADD = $(nss_LIBS) +endif + +if BUILDCRYPTOOPENSSL +pkglib_LTLIBRARIES += crypto_openssl.la +crypto_openssl_la_LDFLAGS = -module -avoid-version +crypto_openssl_la_CFLAGS = $(openssl_CFLAGS) +crypto_openssl_la_LIBADD = $(openssl_LIBS) +endif dist_man_MANS = man update-man-pages: doxyfile.stamp doxyfile.stamp: Doxyfile if MANPAGEUPDATES $(DOXYGEN) Doxyfile $(DOXY2MAN) -o $(abs_srcdir)/man -s 3 --short-pkg @PACKAGE_NAME@ --pkg "Kronosnet Programmer's Manual" $(builddir)/xml/libknet_8h.xml else @echo this system does not have doxy2man or doxygen installed. Unable to update man pages automatically. endif touch doxyfile.stamp clean-local: rm -rf doxyfile.stamp xml diff --git a/libknet/common.c b/libknet/common.c index 6feda1e1..1ddf31c9 100644 --- a/libknet/common.c +++ b/libknet/common.c @@ -1,161 +1,185 @@ /* * Copyright (C) 2010-2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "logging.h" #include "common.h" int _fdset_cloexec(int fd) { int fdflags; fdflags = fcntl(fd, F_GETFD, 0); if (fdflags < 0) return -1; fdflags |= FD_CLOEXEC; if (fcntl(fd, F_SETFD, fdflags) < 0) return -1; return 0; } int _fdset_nonblock(int fd) { int fdflags; fdflags = fcntl(fd, F_GETFL, 0); if (fdflags < 0) return -1; fdflags |= O_NONBLOCK; if (fcntl(fd, F_SETFL, fdflags) < 0) return -1; return 0; } void *open_lib(knet_handle_t knet_h, const char *libname, int extra_flags) { void *ret = NULL; char *error = NULL; char dir[MAXPATHLEN], path[MAXPATHLEN], link[MAXPATHLEN]; struct stat sb; /* * clear any pending error */ dlerror(); ret = dlopen(libname, RTLD_NOW | RTLD_GLOBAL | extra_flags); error = dlerror(); if (error != NULL) { log_err(knet_h, KNET_SUB_COMMON, "unable to dlopen %s: %s", libname, error); errno = EAGAIN; return NULL; } memset(dir, 0, sizeof(dir)); memset(link, 0, sizeof(link)); memset(path, 0, sizeof(path)); if (dlinfo(ret, RTLD_DI_ORIGIN, &dir) < 0) { /* * should we dlclose and return error? */ log_warn(knet_h, KNET_SUB_COMMON, "unable to dlinfo %s: %s", libname, error); } else { snprintf(path, sizeof(path), "%s/%s", dir, libname); log_info(knet_h, KNET_SUB_COMMON, "%s has been loaded from %s", libname, path); /* * try to resolve the library and check if it is a symlink and to where. * we can't prevent symlink attacks but at least we can log where the library * has been loaded from */ if (lstat(path, &sb) < 0) { log_debug(knet_h, KNET_SUB_COMMON, "Unable to stat %s: %s", path, strerror(errno)); goto out; } if (S_ISLNK(sb.st_mode)) { if (readlink(path, link, sizeof(link)) < 0) { log_debug(knet_h, KNET_SUB_COMMON, "Unable to readlink %s: %s", path, strerror(errno)); goto out; } /* * symlink is relative to the directory */ if (link[0] != '/') { snprintf(path, sizeof(path), "%s/%s", dir, link); log_info(knet_h, KNET_SUB_COMMON, "%s/%s is a symlink to %s", dir, libname, path); } else { log_info(knet_h, KNET_SUB_COMMON, "%s/%s is a symlink to %s", dir, libname, link); } } } out: return ret; } -void *remap_symbol(knet_handle_t knet_h, uint8_t subsystem, - void *lib_handle, const char *symbol_name) -{ - void *symbol = dlsym (lib_handle, symbol_name); - if (!symbol) { - log_err (knet_h, subsystem, "unable to map %s: %s", symbol_name, dlerror ()); - } - return symbol; -} - +/* Separate these into compress.c and crypto.c or keep them together? */ int load_compress_lib(knet_handle_t knet_h, compress_model_t *model) { void *module; compress_model_t *module_cmds; char soname[MAXPATHLEN]; const char model_sym[] = "compress_model"; if (model->loaded) { return 0; } snprintf (soname, sizeof soname, "compress_%s.so", model->model_name); module = open_lib(knet_h, soname, 0); if (!module) { return -1; } module_cmds = dlsym (module, model_sym); if (!module_cmds) { log_err (knet_h, KNET_SUB_COMPRESS, "unable to map symbol %s in module %s: %s", model_sym, soname, dlerror ()); errno = EINVAL; return -1; } model->is_init = module_cmds->is_init; model->init = module_cmds->init; model->fini = module_cmds->fini; model->val_level = module_cmds->val_level; model->compress = module_cmds->compress; model->decompress = module_cmds->decompress; return 0; } + +int load_crypto_lib(knet_handle_t knet_h, crypto_model_t *model) +{ + void *module; + crypto_model_t *module_cmds; + char soname[MAXPATHLEN]; + const char model_sym[] = "crypto_model"; + + if (model->loaded) { + return 0; + } + snprintf (soname, sizeof soname, "crypto_%s.so", model->model_name); + module = open_lib(knet_h, soname, 0); + if (!module) { + return -1; + } + module_cmds = dlsym (module, model_sym); + if (!module_cmds) { + log_err (knet_h, KNET_SUB_CRYPTO, "unable to map symbol %s in module %s: %s", + model_sym, soname, dlerror ()); + errno = EINVAL; + return -1; + } + if (module_cmds->load_lib && (*module_cmds->load_lib)(knet_h)) { + return -1; + } + model->init = module_cmds->init; + model->fini = module_cmds->fini; + model->crypt = module_cmds->crypt; + model->cryptv = module_cmds->cryptv; + model->decrypt = module_cmds->decrypt; + return 0; +} diff --git a/libknet/common.h b/libknet/common.h index d7c3501e..d21a80d9 100644 --- a/libknet/common.h +++ b/libknet/common.h @@ -1,23 +1,23 @@ /* * Copyright (C) 2012-2017 Red Hat, Inc. All rights reserved. * * Authors: Fabio M. Di Nitto * Federico Simoncelli * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "internals.h" #include "compress_model.h" +#include "crypto_model.h" #ifndef __KNET_COMMON_H__ #define __KNET_COMMON_H__ int _fdset_cloexec(int fd); int _fdset_nonblock(int fd); void *open_lib(knet_handle_t knet_h, const char *libname, int extra_flags); -void *remap_symbol(knet_handle_t knet_h, uint8_t subsystem, - void *lib_handle, const char *symbol_name); int load_compress_lib(knet_handle_t knet_h, compress_model_t *model); +int load_crypto_lib(knet_handle_t knet_h, crypto_model_t *model); #endif diff --git a/libknet/compress.c b/libknet/compress.c index 66466f80..daf057f3 100644 --- a/libknet/compress.c +++ b/libknet/compress.c @@ -1,466 +1,453 @@ /* * Copyright (C) 2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "config.h" #include #include #include #include #include #include "internals.h" #include "compress.h" #include "compress_model.h" #include "logging.h" #include "threads_common.h" #include "common.h" -#ifdef BUILDCOMPZLIB -#include "compress_zlib.h" -#endif -#ifdef BUILDCOMPLZ4 -#include "compress_lz4.h" -#endif -#ifdef BUILDCOMPLZO2 -#include "compress_lzo2.h" -#endif -#ifdef BUILDCOMPLZMA -#include "compress_lzma.h" -#endif - /* * internal module switch data */ /* * DO NOT CHANGE MODEL_ID HERE OR ONWIRE COMPATIBILITY * WILL BREAK! * * always add before the last NULL/NULL/NULL. */ #define empty_module 0, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL }, compress_model_t compress_modules_cmds[] = { { "none", 0, empty_module { "zlib", 1, #ifdef BUILDCOMPZLIB - 1, zlib_load_lib, 0, NULL, NULL, NULL, zlib_val_level, zlib_compress, zlib_decompress }, + 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL }, #else empty_module #endif { "lz4", 2, #ifdef BUILDCOMPLZ4 - 1, lz4_load_lib, 0, NULL, NULL, NULL, lz4_val_level, lz4_compress, lz4_decompress }, + 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL }, #else empty_module #endif { "lz4hc", 3, #ifdef BUILDCOMPLZ4 - 1, lz4_load_lib, 0, NULL, NULL, NULL, lz4hc_val_level, lz4hc_compress, lz4_decompress }, + 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL }, #else empty_module #endif { "lzo2", 4, #ifdef BUILDCOMPLZO2 - 1, lzo2_load_lib, 0, lzo2_is_init, lzo2_init, lzo2_fini, lzo2_val_level, lzo2_compress, lzo2_decompress }, + 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL }, #else empty_module #endif { "lzma", 5, #ifdef BUILDCOMPLZMA - 1, lzma_load_lib, 0, NULL, NULL, NULL, lzma_val_level, lzma_compress, lzma_decompress }, + 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL }, #else empty_module #endif { "bzip2", 6, #ifdef BUILDCOMPBZIP2 - 1, load_compress_lib, 0, NULL, NULL, NULL, NULL, NULL, NULL }, + 1, NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL }, #else empty_module #endif { NULL, 255, empty_module }; static int max_model = 0; static struct timespec last_load_failure; static int compress_get_model(const char *model) { int idx = 0; while (compress_modules_cmds[idx].model_name != NULL) { if (!strcmp(compress_modules_cmds[idx].model_name, model)) { return compress_modules_cmds[idx].model_id; } idx++; } return -1; } static int compress_get_max_model(void) { int idx = 0; while (compress_modules_cmds[idx].model_name != NULL) { idx++; } return idx - 1; } static int compress_is_valid_model(int compress_model) { int idx = 0; while (compress_modules_cmds[idx].model_name != NULL) { if ((compress_model == compress_modules_cmds[idx].model_id) && (compress_modules_cmds[idx].built_in == 1)) { return 0; } idx++; } return -1; } static int val_level( knet_handle_t knet_h, int compress_model, int compress_level) { return compress_modules_cmds[compress_model].val_level(knet_h, compress_level); } /* * compress_check_lib_is_init needs to be invoked in a locked context! */ static int compress_check_lib_is_init(knet_handle_t knet_h, int cmp_model) { /* * lack of a .is_init function means that the module does not require * init per handle so we use a fake reference in the compress_int_data * to identify that we already increased the libref for this handle */ if (compress_modules_cmds[cmp_model].loaded == 1) { if (compress_modules_cmds[cmp_model].is_init == NULL) { if (knet_h->compress_int_data[cmp_model] != NULL) { return 1; } } else { if (compress_modules_cmds[cmp_model].is_init(knet_h, cmp_model) == 1) { return 1; } } } return 0; } /* * compress_load_lib should _always_ be invoked in write lock context */ static int compress_load_lib(knet_handle_t knet_h, int cmp_model, int rate_limit) { struct timespec clock_now; unsigned long long timediff; /* * checking again for paranoia and because * compress_check_lib_is_init is usually invoked in read context * and we need to switch from read to write locking in between. * another thread might have init the library in the meantime */ if (compress_check_lib_is_init(knet_h, cmp_model)) { return 0; } /* * due to the fact that decompress can load libraries * on demand, depending on the compress model selected * on other nodes, it is possible for an attacker * to send crafted packets to attempt to load libraries * at random in a DoS fashion. * If there is an error loading a library, then we want * to rate_limit a retry to reload the library every X * seconds to avoid a lock DoS that could greatly slow * down libknet. */ if (rate_limit) { if ((last_load_failure.tv_sec != 0) || (last_load_failure.tv_nsec != 0)) { clock_gettime(CLOCK_MONOTONIC, &clock_now); timespec_diff(last_load_failure, clock_now, &timediff); if (timediff < 10000000000) { errno = EAGAIN; return -1; } } } if (compress_modules_cmds[cmp_model].loaded == 0) { - if (compress_modules_cmds[cmp_model].load_lib(knet_h, compress_modules_cmds+cmp_model) < 0) { + if (load_compress_lib(knet_h, compress_modules_cmds+cmp_model) < 0) { clock_gettime(CLOCK_MONOTONIC, &last_load_failure); return -1; } compress_modules_cmds[cmp_model].loaded = 1; } if (compress_modules_cmds[cmp_model].init != NULL) { if (compress_modules_cmds[cmp_model].init(knet_h, cmp_model) < 0) { return -1; } } else { knet_h->compress_int_data[cmp_model] = (void *)&"1"; } return 0; } int compress_init( knet_handle_t knet_h) { max_model = compress_get_max_model(); if (max_model > KNET_MAX_COMPRESS_METHODS) { log_err(knet_h, KNET_SUB_COMPRESS, "Too many compress methods defined in compress.c."); errno = EINVAL; return -1; } memset(&last_load_failure, 0, sizeof(struct timespec)); return 0; } int compress_cfg( knet_handle_t knet_h, struct knet_handle_compress_cfg *knet_handle_compress_cfg) { int savederrno = 0, err = 0; int cmp_model; cmp_model = compress_get_model(knet_handle_compress_cfg->compress_model); if (cmp_model < 0) { log_err(knet_h, KNET_SUB_COMPRESS, "compress model %s not supported", knet_handle_compress_cfg->compress_model); errno = EINVAL; return -1; } log_debug(knet_h, KNET_SUB_COMPRESS, "Initizializing compress module [%s/%d/%u]", knet_handle_compress_cfg->compress_model, knet_handle_compress_cfg->compress_level, knet_handle_compress_cfg->compress_threshold); if (cmp_model > 0) { if (compress_modules_cmds[cmp_model].built_in == 0) { log_err(knet_h, KNET_SUB_COMPRESS, "compress model %s support has not been built in. Please contact your vendor or fix the build", knet_handle_compress_cfg->compress_model); errno = EINVAL; return -1; } if (knet_handle_compress_cfg->compress_threshold > KNET_MAX_PACKET_SIZE) { log_err(knet_h, KNET_SUB_COMPRESS, "compress threshold cannot be higher than KNET_MAX_PACKET_SIZE (%d).", KNET_MAX_PACKET_SIZE); errno = EINVAL; return -1; } if (knet_handle_compress_cfg->compress_threshold == 0) { knet_h->compress_threshold = KNET_COMPRESS_THRESHOLD; log_debug(knet_h, KNET_SUB_COMPRESS, "resetting compression threshold to default (%d)", KNET_COMPRESS_THRESHOLD); } else { knet_h->compress_threshold = knet_handle_compress_cfg->compress_threshold; } savederrno = pthread_rwlock_rdlock(&shlib_rwlock); if (savederrno) { log_err(knet_h, KNET_SUB_COMPRESS, "Unable to get read lock: %s", strerror(savederrno)); errno = savederrno; return -1; } if (!compress_check_lib_is_init(knet_h, cmp_model)) { /* * need to switch to write lock, load the lib, and return with a write lock * this is not racy because compress_load_lib is written idempotent. */ pthread_rwlock_unlock(&shlib_rwlock); savederrno = pthread_rwlock_wrlock(&shlib_rwlock); if (savederrno) { log_err(knet_h, KNET_SUB_COMPRESS, "Unable to get write lock: %s", strerror(savederrno)); errno = savederrno; return -1; } if (compress_load_lib(knet_h, cmp_model, 0) < 0) { savederrno = errno; log_err(knet_h, KNET_SUB_COMPRESS, "Unable to load library: %s", strerror(savederrno)); err = -1; goto out_unlock; } } if (val_level(knet_h, cmp_model, knet_handle_compress_cfg->compress_level) < 0) { log_err(knet_h, KNET_SUB_COMPRESS, "compress level %d not supported for model %s", knet_handle_compress_cfg->compress_level, knet_handle_compress_cfg->compress_model); savederrno = EINVAL; err = -1; goto out_unlock; } out_unlock: pthread_rwlock_unlock(&shlib_rwlock); } if (!err) { knet_h->compress_model = cmp_model; knet_h->compress_level = knet_handle_compress_cfg->compress_level; } else { knet_h->compress_model = 0; } errno = savederrno; return err; } void compress_fini( knet_handle_t knet_h, int all) { int savederrno = 0; int idx = 0; savederrno = pthread_rwlock_wrlock(&shlib_rwlock); if (savederrno) { log_err(knet_h, KNET_SUB_COMPRESS, "Unable to get write lock: %s", strerror(savederrno)); return; } while (compress_modules_cmds[idx].model_name != NULL) { if ((compress_modules_cmds[idx].built_in == 1) && (compress_modules_cmds[idx].loaded == 1) && (compress_modules_cmds[idx].model_id > 0) && (knet_h->compress_int_data[idx] != NULL) && (idx < KNET_MAX_COMPRESS_METHODS)) { if ((all) || (compress_modules_cmds[idx].model_id == knet_h->compress_model)) { if (compress_modules_cmds[idx].fini != NULL) { compress_modules_cmds[idx].fini(knet_h, idx); } else { knet_h->compress_int_data[idx] = NULL; } } } idx++; } pthread_rwlock_unlock(&shlib_rwlock); return; } /* * compress does not require compress_check_lib_is_init * because it's protected by compress_cfg */ int compress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { return compress_modules_cmds[knet_h->compress_model].compress(knet_h, buf_in, buf_in_len, buf_out, buf_out_len); } int decompress( knet_handle_t knet_h, int compress_model, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int savederrno = 0, err = 0; if (compress_model > max_model) { log_err(knet_h, KNET_SUB_COMPRESS, "Received packet with unknown compress model %d", compress_model); errno = EINVAL; return -1; } if (compress_is_valid_model(compress_model) < 0) { log_err(knet_h, KNET_SUB_COMPRESS, "Received packet compressed with %s but support is not built in this version of libknet. Please contact your distribution vendor or fix the build.", compress_modules_cmds[compress_model].model_name); errno = EINVAL; return -1; } savederrno = pthread_rwlock_rdlock(&shlib_rwlock); if (savederrno) { log_err(knet_h, KNET_SUB_COMPRESS, "Unable to get read lock: %s", strerror(savederrno)); errno = savederrno; return -1; } if (!compress_check_lib_is_init(knet_h, compress_model)) { /* * need to switch to write lock, load the lib, and return with a write lock * this is not racy because compress_load_lib is written idempotent. */ pthread_rwlock_unlock(&shlib_rwlock); savederrno = pthread_rwlock_wrlock(&shlib_rwlock); if (savederrno) { log_err(knet_h, KNET_SUB_COMPRESS, "Unable to get write lock: %s", strerror(savederrno)); errno = savederrno; return -1; } if (compress_load_lib(knet_h, compress_model, 1) < 0) { savederrno = errno; err = -1; log_err(knet_h, KNET_SUB_COMPRESS, "Unable to load library: %s", strerror(savederrno)); goto out_unlock; } } err = compress_modules_cmds[compress_model].decompress(knet_h, buf_in, buf_in_len, buf_out, buf_out_len); savederrno = errno; out_unlock: pthread_rwlock_unlock(&shlib_rwlock); errno = savederrno; return err; } int knet_get_compress_list(struct knet_compress_info *compress_list, size_t *compress_list_entries) { int err = 0; int idx = 0; int outidx = 0; if (!compress_list_entries) { errno = EINVAL; return -1; } while (compress_modules_cmds[idx].model_name != NULL) { if (compress_modules_cmds[idx].built_in) { if (compress_list) { compress_list[outidx].name = compress_modules_cmds[idx].model_name; } outidx++; } idx++; } *compress_list_entries = outidx; return err; } diff --git a/libknet/compress_bzip2.c b/libknet/compress_bzip2.c index 90a8f290..79d1f66f 100644 --- a/libknet/compress_bzip2.c +++ b/libknet/compress_bzip2.c @@ -1,117 +1,117 @@ /* * Copyright (C) 2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "config.h" #include #include #include "logging.h" #include "compress_model.h" static int bzip2_val_level( knet_handle_t knet_h, int compress_level) { if ((compress_level < 1) || (compress_level > 9)) { log_err(knet_h, KNET_SUB_BZIP2COMP, "bzip2 unsupported compression level %d (accepted values from 1 to 9)", compress_level); errno = EINVAL; return -1; } return 0; } static int bzip2_compress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int err = 0; int savederrno = 0; unsigned int destLen = KNET_DATABUFSIZE_COMPRESS; err = BZ2_bzBuffToBuffCompress((char *)buf_out, &destLen, (char *)buf_in, buf_in_len, knet_h->compress_level, 0, 0); switch(err) { case BZ_OK: *buf_out_len = destLen; break; case BZ_MEM_ERROR: log_err(knet_h, KNET_SUB_BZIP2COMP, "bzip2 compress has not enough memory"); savederrno = ENOMEM; err = -1; break; case BZ_OUTBUFF_FULL: log_err(knet_h, KNET_SUB_BZIP2COMP, "bzip2 unable to compress source in destination buffer"); savederrno = E2BIG; err = -1; break; default: log_err(knet_h, KNET_SUB_BZIP2COMP, "bzip2 compress unknown error %d", err); savederrno = EINVAL; err = -1; break; } errno = savederrno; return err; } static int bzip2_decompress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int err = 0; int savederrno = 0; unsigned int destLen = KNET_DATABUFSIZE_COMPRESS; err = BZ2_bzBuffToBuffDecompress((char *)buf_out, &destLen, (char *)buf_in, buf_in_len, 0, 0); switch(err) { case BZ_OK: *buf_out_len = destLen; break; case BZ_MEM_ERROR: log_err(knet_h, KNET_SUB_BZIP2COMP, "bzip2 decompress has not enough memory"); savederrno = ENOMEM; err = -1; break; case BZ_OUTBUFF_FULL: log_err(knet_h, KNET_SUB_BZIP2COMP, "bzip2 unable to decompress source in destination buffer"); savederrno = E2BIG; err = -1; break; case BZ_DATA_ERROR: case BZ_DATA_ERROR_MAGIC: case BZ_UNEXPECTED_EOF: log_err(knet_h, KNET_SUB_BZIP2COMP, "bzip2 decompress detected input data corruption"); savederrno = EINVAL; err = -1; break; default: log_err(knet_h, KNET_SUB_BZIP2COMP, "bzip2 decompress unknown error %d", err); savederrno = EINVAL; err = -1; break; } errno = savederrno; return err; } -compress_model_t compress_model = { "bzip2", 0, 1, NULL, 1, NULL, NULL, NULL, bzip2_val_level, bzip2_compress, bzip2_decompress }; +compress_model_t compress_model = { "", 0, 0, NULL, 0, NULL, NULL, NULL, bzip2_val_level, bzip2_compress, bzip2_decompress }; diff --git a/libknet/compress_canary.c b/libknet/compress_canary.c deleted file mode 100644 index a46413d0..00000000 --- a/libknet/compress_canary.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Transform the binary into dependencies like: - * dpkg-shlibdeps -pcompress -dSuggests -xlibc6 -elibknet/compress_canary - */ - -#include "config.h" - -#define CANARY - -#include "compress_lz4_remap.h" -#include "compress_lzma_remap.h" -#include "compress_lzo2_remap.h" -#include "compress_zlib_remap.h" - -#define CANARY_CALL - -int main (void) -{ - return -#ifdef BUILDCOMPLZ4 -#include "compress_lz4_remap.h" -#endif -#ifdef BUILDCOMPLZMA -#include "compress_lzma_remap.h" -#endif -#ifdef BUILDCOMPLZO2 -#include "compress_lzo2_remap.h" -#endif -#ifdef BUILDCOMPZLIB -#include "compress_zlib_remap.h" -#endif - 0; -} diff --git a/libknet/compress_lz4.c b/libknet/compress_lz4.c index aa00fc02..02c96643 100644 --- a/libknet/compress_lz4.c +++ b/libknet/compress_lz4.c @@ -1,205 +1,93 @@ /* * Copyright (C) 2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "config.h" -#include -#include #include -#include -#ifdef BUILDCOMPLZ4 #include -#include "internals.h" -#include "compress_lz4.h" #include "logging.h" -#include "common.h" +#include "compress_model.h" -/* - * global vars for dlopen - */ -static void *lz4_lib; - -#include "compress_lz4_remap.h" - -static int lz4_remap_symbols(knet_handle_t knet_h) -{ -#define REMAP_WITH(name) remap_symbol (knet_h, KNET_SUB_LZ4COMP, lz4_lib, name) -#include "compress_lz4_remap.h" - return 0; - - fail: -#define REMAP_FAIL -#include "compress_lz4_remap.h" - errno = EINVAL; - return -1; -} - -int lz4_load_lib( - knet_handle_t knet_h) -{ - int err = 0, savederrno = 0; - - if (!lz4_lib) { - lz4_lib = open_lib(knet_h, LIBLZ4_1, 0); - if (!lz4_lib) { - savederrno = EAGAIN; - err = -1; - goto out; - } - } - - if (lz4_remap_symbols(knet_h) < 0) { - savederrno = errno; - err = -1; - } -out: - errno = savederrno; - return err; -} - -int lz4_val_level( +static int lz4_val_level( knet_handle_t knet_h, int compress_level) { if (compress_level <= 0) { - log_info(knet_h, KNET_SUB_LZ4COMP, "lz4 acceleration level 0 (or negatives) are automatically remapped to 1 by %s", LIBLZ4_1); + log_info(knet_h, KNET_SUB_LZ4COMP, "lz4 acceleration level 0 (or negatives) are automatically remapped to 1"); } return 0; } -int lz4_compress( +static int lz4_compress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int lzerr = 0, err = 0; int savederrno = 0; - lzerr = (*_int_LZ4_compress_fast)((const char *)buf_in, (char *)buf_out, buf_in_len, KNET_DATABUFSIZE_COMPRESS, knet_h->compress_level); + lzerr = LZ4_compress_fast((const char *)buf_in, (char *)buf_out, buf_in_len, KNET_DATABUFSIZE_COMPRESS, knet_h->compress_level); /* * data compressed */ if (lzerr > 0) { *buf_out_len = lzerr; } /* * unable to compress */ if (lzerr == 0) { *buf_out_len = buf_in_len; } /* * lz4 internal error */ if (lzerr < 0) { log_err(knet_h, KNET_SUB_LZ4COMP, "lz4 compression error: %d", lzerr); savederrno = EINVAL; err = -1; } errno = savederrno; return err; } -#ifdef LZ4HC_CLEVEL_MAX -#define KNET_LZ4HC_MAX LZ4HC_CLEVEL_MAX -#endif -#ifdef LZ4HC_MAX_CLEVEL -#define KNET_LZ4HC_MAX LZ4HC_MAX_CLEVEL -#endif -#ifndef KNET_LZ4HC_MAX -#define KNET_LZ4HC_MAX 0 -#error Please check lz4hc.h for missing LZ4HC_CLEVEL_MAX or LZ4HC_MAX_CLEVEL variants -#endif - -int lz4hc_val_level( - knet_handle_t knet_h, - int compress_level) -{ - if (compress_level < 1) { - log_err(knet_h, KNET_SUB_LZ4HCCOMP, "lz4hc supports only 1+ values for compression level"); - errno = EINVAL; - return -1; - } - - if (compress_level < 4) { - log_info(knet_h, KNET_SUB_LZ4HCCOMP, "lz4hc recommends 4+ compression level for better results"); - } - - if (compress_level > KNET_LZ4HC_MAX) { - log_warn(knet_h, KNET_SUB_LZ4HCCOMP, "lz4hc installed on this system supports up to compression level %d. Higher values behaves as %d", KNET_LZ4HC_MAX, KNET_LZ4HC_MAX); - } - - return 0; -} - -int lz4hc_compress( +static int lz4_decompress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int lzerr = 0, err = 0; int savederrno = 0; - lzerr = (*_int_LZ4_compress_HC)((const char *)buf_in, (char *)buf_out, buf_in_len, KNET_DATABUFSIZE_COMPRESS, knet_h->compress_level); - - /* - * data compressed - */ - if (lzerr > 0) { - *buf_out_len = lzerr; - } - - /* - * unable to compress - */ - if (lzerr <= 0) { - log_err(knet_h, KNET_SUB_LZ4HCCOMP, "lz4hc compression error: %d", lzerr); - savederrno = EINVAL; - err = -1; - } - - errno = savederrno; - return err; -} - -int lz4_decompress( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len) -{ - int lzerr = 0, err = 0; - int savederrno = 0; - - lzerr = (*_int_LZ4_decompress_safe)((const char *)buf_in, (char *)buf_out, buf_in_len, KNET_DATABUFSIZE); + lzerr = LZ4_decompress_safe((const char *)buf_in, (char *)buf_out, buf_in_len, KNET_DATABUFSIZE); if (lzerr < 0) { log_err(knet_h, KNET_SUB_LZ4COMP, "lz4 decompression error: %d", lzerr); savederrno = EINVAL; err = -1; } if (lzerr > 0) { *buf_out_len = lzerr; } errno = savederrno; return err; } -#endif + +compress_model_t compress_model = { "", 0, 0, NULL, 0, NULL, NULL, NULL, lz4_val_level, lz4_compress, lz4_decompress }; diff --git a/libknet/compress_lz4.h b/libknet/compress_lz4.h deleted file mode 100644 index 093136e0..00000000 --- a/libknet/compress_lz4.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2017 Red Hat, Inc. All rights reserved. - * - * Author: Fabio M. Di Nitto - * - * This software licensed under GPL-2.0+, LGPL-2.0+ - */ - -#ifndef __KNET_COMPRESS_LZ4_H__ -#define __KNET_COMPRESS_LZ4_H__ - -#include "internals.h" - -int lz4_load_lib( - knet_handle_t knet_h); - -int lz4_val_level( - knet_handle_t knet_h, - int compress_level); - -int lz4_compress( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int lz4hc_val_level( - knet_handle_t knet_h, - int compress_level); - -int lz4hc_compress( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int lz4_decompress( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -#endif diff --git a/libknet/compress_lz4_remap.h b/libknet/compress_lz4_remap.h deleted file mode 100644 index 039cc9ad..00000000 --- a/libknet/compress_lz4_remap.h +++ /dev/null @@ -1,13 +0,0 @@ -#include "remap.h" - -REMAP_PROTO(int,LZ4_compress_HC, - (const char* src, char* dst, - int srcSize, int dstCapacity, - int compressionLevel)) -REMAP_PROTO(int,LZ4_compress_fast, - (const char* source, char* dest, - int sourceSize, int maxDestSize, - int acceleration)) -REMAP_PROTO(int,LZ4_decompress_safe, - (const char* source, char* dest, - int compressedSize, int maxDecompressedSize)) diff --git a/libknet/compress_lz4hc.c b/libknet/compress_lz4hc.c new file mode 100644 index 00000000..c496b8da --- /dev/null +++ b/libknet/compress_lz4hc.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2017 Red Hat, Inc. All rights reserved. + * + * Author: Fabio M. Di Nitto + * + * This software licensed under GPL-2.0+, LGPL-2.0+ + */ + +#include "config.h" + +#include +#include + +#include "logging.h" +#include "compress_model.h" + +#ifdef LZ4HC_CLEVEL_MAX +#define KNET_LZ4HC_MAX LZ4HC_CLEVEL_MAX +#endif +#ifdef LZ4HC_MAX_CLEVEL +#define KNET_LZ4HC_MAX LZ4HC_MAX_CLEVEL +#endif +#ifndef KNET_LZ4HC_MAX +#define KNET_LZ4HC_MAX 0 +#error Please check lz4hc.h for missing LZ4HC_CLEVEL_MAX or LZ4HC_MAX_CLEVEL variants +#endif + +static int lz4hc_val_level( + knet_handle_t knet_h, + int compress_level) +{ + if (compress_level < 1) { + log_err(knet_h, KNET_SUB_LZ4HCCOMP, "lz4hc supports only 1+ values for compression level"); + errno = EINVAL; + return -1; + } + + if (compress_level < 4) { + log_info(knet_h, KNET_SUB_LZ4HCCOMP, "lz4hc recommends 4+ compression level for better results"); + } + + if (compress_level > KNET_LZ4HC_MAX) { + log_warn(knet_h, KNET_SUB_LZ4HCCOMP, "lz4hc installed on this system supports up to compression level %d. Higher values behaves as %d", KNET_LZ4HC_MAX, KNET_LZ4HC_MAX); + } + + return 0; +} + +static int lz4hc_compress( + knet_handle_t knet_h, + const unsigned char *buf_in, + const ssize_t buf_in_len, + unsigned char *buf_out, + ssize_t *buf_out_len) +{ + int lzerr = 0, err = 0; + int savederrno = 0; + + lzerr = LZ4_compress_HC((const char *)buf_in, (char *)buf_out, buf_in_len, KNET_DATABUFSIZE_COMPRESS, knet_h->compress_level); + + /* + * data compressed + */ + if (lzerr > 0) { + *buf_out_len = lzerr; + } + + /* + * unable to compress + */ + if (lzerr <= 0) { + log_err(knet_h, KNET_SUB_LZ4HCCOMP, "lz4hc compression error: %d", lzerr); + savederrno = EINVAL; + err = -1; + } + + errno = savederrno; + return err; +} + +/* This is a straight copy from compress_lz4.c */ +static int lz4_decompress( + knet_handle_t knet_h, + const unsigned char *buf_in, + const ssize_t buf_in_len, + unsigned char *buf_out, + ssize_t *buf_out_len) +{ + int lzerr = 0, err = 0; + int savederrno = 0; + + lzerr = LZ4_decompress_safe((const char *)buf_in, (char *)buf_out, buf_in_len, KNET_DATABUFSIZE); + + if (lzerr < 0) { + log_err(knet_h, KNET_SUB_LZ4COMP, "lz4 decompression error: %d", lzerr); + savederrno = EINVAL; + err = -1; + } + + if (lzerr > 0) { + *buf_out_len = lzerr; + } + + errno = savederrno; + return err; +} + +compress_model_t compress_model = { "", 0, 0, NULL, 0, NULL, NULL, NULL, lz4hc_val_level, lz4hc_compress, lz4_decompress }; diff --git a/libknet/compress_lzma.c b/libknet/compress_lzma.c index 3ace3d07..f719e23f 100644 --- a/libknet/compress_lzma.c +++ b/libknet/compress_lzma.c @@ -1,177 +1,129 @@ /* * Copyright (C) 2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "config.h" -#include -#include #include -#include -#ifdef BUILDCOMPLZMA #include -#include "internals.h" -#include "compress_lzma.h" #include "logging.h" -#include "common.h" +#include "compress_model.h" -/* - * global vars for dlopen - */ -static void *lzma_lib; - -#include "compress_lzma_remap.h" - -static int lzma_remap_symbols(knet_handle_t knet_h) -{ -#define REMAP_WITH(name) remap_symbol (knet_h, KNET_SUB_LZMACOMP, lzma_lib, name) -#include "compress_lzma_remap.h" - return 0; - - fail: -#define REMAP_FAIL -#include "compress_lzma_remap.h" - errno = EINVAL; - return -1; -} - -int lzma_load_lib( - knet_handle_t knet_h) -{ - int err = 0, savederrno = 0; - - if (!lzma_lib) { - lzma_lib = open_lib(knet_h, LIBLZMA_5, 0); - if (!lzma_lib) { - savederrno = EAGAIN; - err = -1; - goto out; - } - } - - if (lzma_remap_symbols(knet_h) < 0) { - savederrno = errno; - err = -1; - } -out: - errno = savederrno; - return err; -} - -int lzma_val_level( +static int lzma_val_level( knet_handle_t knet_h, int compress_level) { if ((compress_level < 0) || (compress_level > 9)) { log_err(knet_h, KNET_SUB_LZMACOMP, "lzma unsupported compression preset %d (accepted values from 0 to 9)", compress_level); errno = EINVAL; return -1; } return 0; } -int lzma_compress( +static int lzma_compress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int err = 0; int savederrno = 0; size_t out_pos = 0; lzma_ret ret = 0; - ret = (*_int_lzma_easy_buffer_encode)(knet_h->compress_level, LZMA_CHECK_NONE, NULL, - (const uint8_t *)buf_in, buf_in_len, - (uint8_t *)buf_out, &out_pos, KNET_DATABUFSIZE_COMPRESS); + ret = lzma_easy_buffer_encode(knet_h->compress_level, LZMA_CHECK_NONE, NULL, + (const uint8_t *)buf_in, buf_in_len, + (uint8_t *)buf_out, &out_pos, KNET_DATABUFSIZE_COMPRESS); switch(ret) { case LZMA_OK: *buf_out_len = out_pos; break; case LZMA_MEM_ERROR: log_err(knet_h, KNET_SUB_LZMACOMP, "lzma compress memory allocation failed"); savederrno = ENOMEM; err = -1; break; case LZMA_MEMLIMIT_ERROR: log_err(knet_h, KNET_SUB_LZMACOMP, "lzma compress requires higher memory boundaries (see lzma_memlimit_set)"); savederrno = ENOMEM; err = -1; break; case LZMA_PROG_ERROR: log_err(knet_h, KNET_SUB_LZMACOMP, "lzma compress has been called with incorrect options"); savederrno = EINVAL; err = -1; break; default: log_err(knet_h, KNET_SUB_LZMACOMP, "lzma compress unknown error %u", ret); savederrno = EINVAL; err = -1; break; } errno = savederrno; return err; } -int lzma_decompress( +static int lzma_decompress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int err = 0; int savederrno = 0; uint64_t memlimit = UINT64_MAX; /* disable lzma internal memlimit check */ size_t out_pos = 0, in_pos = 0; lzma_ret ret = 0; - ret = (*_int_lzma_stream_buffer_decode)(&memlimit, 0, NULL, - (const uint8_t *)buf_in, &in_pos, buf_in_len, - (uint8_t *)buf_out, &out_pos, KNET_DATABUFSIZE_COMPRESS); + ret = lzma_stream_buffer_decode(&memlimit, 0, NULL, + (const uint8_t *)buf_in, &in_pos, buf_in_len, + (uint8_t *)buf_out, &out_pos, KNET_DATABUFSIZE_COMPRESS); switch(ret) { case LZMA_OK: *buf_out_len = out_pos; break; case LZMA_MEM_ERROR: log_err(knet_h, KNET_SUB_LZMACOMP, "lzma decompress memory allocation failed"); savederrno = ENOMEM; err = -1; break; case LZMA_MEMLIMIT_ERROR: log_err(knet_h, KNET_SUB_LZMACOMP, "lzma decompress requires higher memory boundaries (see lzma_memlimit_set)"); savederrno = ENOMEM; err = -1; break; case LZMA_DATA_ERROR: case LZMA_FORMAT_ERROR: log_err(knet_h, KNET_SUB_LZMACOMP, "lzma decompress invalid data received"); savederrno = EINVAL; err = -1; break; case LZMA_PROG_ERROR: log_err(knet_h, KNET_SUB_LZMACOMP, "lzma decompress has been called with incorrect options"); savederrno = EINVAL; err = -1; break; default: log_err(knet_h, KNET_SUB_LZMACOMP, "lzma decompress unknown error %u", ret); savederrno = EINVAL; err = -1; break; } errno = savederrno; return err; } -#endif + +compress_model_t compress_model = { "", 0, 0, NULL, 0, NULL, NULL, NULL, lzma_val_level, lzma_compress, lzma_decompress }; diff --git a/libknet/compress_lzma.h b/libknet/compress_lzma.h deleted file mode 100644 index f5f155d9..00000000 --- a/libknet/compress_lzma.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 Red Hat, Inc. All rights reserved. - * - * Author: Fabio M. Di Nitto - * - * This software licensed under GPL-2.0+, LGPL-2.0+ - */ - -#ifndef __KNET_COMPRESS_LZMA_H__ -#define __KNET_COMPRESS_LZMA_H__ - -#include "internals.h" - -int lzma_load_lib( - knet_handle_t knet_h); - -int lzma_val_level( - knet_handle_t knet_h, - int compress_level); - -int lzma_compress( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int lzma_decompress( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -#endif diff --git a/libknet/compress_lzma_remap.h b/libknet/compress_lzma_remap.h deleted file mode 100644 index 780ebd53..00000000 --- a/libknet/compress_lzma_remap.h +++ /dev/null @@ -1,12 +0,0 @@ -#include "remap.h" - -REMAP_PROTO(LZMA_API(lzma_ret),lzma_easy_buffer_encode, - (uint32_t preset, lzma_check check, - const lzma_allocator *allocator, - const uint8_t *in, size_t in_size, - uint8_t *out, size_t *out_pos, size_t out_size)) -REMAP_PROTO(LZMA_API(lzma_ret),lzma_stream_buffer_decode, - (uint64_t *memlimit, uint32_t flags, - const lzma_allocator *allocator, - const uint8_t *in, size_t *in_pos, size_t in_size, - uint8_t *out, size_t *out_pos, size_t out_size)) diff --git a/libknet/compress_lzo2.c b/libknet/compress_lzo2.c index e3476519..d1405dec 100644 --- a/libknet/compress_lzo2.c +++ b/libknet/compress_lzo2.c @@ -1,202 +1,156 @@ /* * Copyright (C) 2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "config.h" -#include #include +#include #include -#include -#ifdef BUILDCOMPLZO2 #include -#include "internals.h" -#include "compress_lzo2.h" #include "logging.h" -#include "common.h" - -/* - * global vars for dlopen - */ -static void *lzo2_lib; - -#include "compress_lzo2_remap.h" - -static int lzo2_remap_symbols(knet_handle_t knet_h) -{ -#define REMAP_WITH(name) remap_symbol (knet_h, KNET_SUB_LZO2COMP, lzo2_lib, name) -#include "compress_lzo2_remap.h" - return 0; - - fail: -#define REMAP_FAIL -#include "compress_lzo2_remap.h" - errno = EINVAL; - return -1; -} +#include "compress_model.h" -int lzo2_load_lib( - knet_handle_t knet_h) -{ - int err = 0, savederrno = 0; - - if (!lzo2_lib) { - lzo2_lib = open_lib(knet_h, LIBLZO2_2, 0); - if (!lzo2_lib) { - savederrno = EAGAIN; - err = -1; - goto out; - } - } - - if (lzo2_remap_symbols(knet_h) < 0) { - savederrno = errno; - err = -1; - } -out: - errno = savederrno; - return err; -} - -int lzo2_is_init( +static int lzo2_is_init( knet_handle_t knet_h, int method_idx) { if (knet_h->compress_int_data[method_idx]) { return 1; } return 0; } -int lzo2_init( +static int lzo2_init( knet_handle_t knet_h, int method_idx) { /* * LZO1X_999_MEM_COMPRESS is the highest amount of memory lzo2 can use */ if (!knet_h->compress_int_data[method_idx]) { knet_h->compress_int_data[method_idx] = malloc(LZO1X_999_MEM_COMPRESS); if (!knet_h->compress_int_data[method_idx]) { log_err(knet_h, KNET_SUB_LZO2COMP, "lzo2 unable to allocate work memory"); errno = ENOMEM; return -1; } memset(knet_h->compress_int_data[method_idx], 0, LZO1X_999_MEM_COMPRESS); } return 0; } -void lzo2_fini( +static void lzo2_fini( knet_handle_t knet_h, int method_idx) { if (knet_h->compress_int_data[method_idx]) { free(knet_h->compress_int_data[method_idx]); knet_h->compress_int_data[method_idx] = NULL; } return; } -int lzo2_val_level( +static int lzo2_val_level( knet_handle_t knet_h, int compress_level) { switch(compress_level) { case 1: log_debug(knet_h, KNET_SUB_LZO2COMP, "lzo2 will use lzo1x_1_compress internal compress method"); break; case 11: log_debug(knet_h, KNET_SUB_LZO2COMP, "lzo2 will use lzo1x_1_11_compress internal compress method"); break; case 12: log_debug(knet_h, KNET_SUB_LZO2COMP, "lzo2 will use lzo1x_1_12_compress internal compress method"); break; case 15: log_debug(knet_h, KNET_SUB_LZO2COMP, "lzo2 will use lzo1x_1_15_compress internal compress method"); break; case 999: log_debug(knet_h, KNET_SUB_LZO2COMP, "lzo2 will use lzo1x_999_compress internal compress method"); break; default: log_warn(knet_h, KNET_SUB_LZO2COMP, "Unknown lzo2 internal compress method. lzo1x_1_compress will be used as default fallback"); break; } return 0; } -int lzo2_compress( +static int lzo2_compress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int savederrno = 0, lzerr = 0, err = 0; lzo_uint cmp_len; switch(knet_h->compress_level) { case 1: - lzerr = (*_int_lzo1x_1_compress)(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); + lzerr = lzo1x_1_compress(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); break; case 11: - lzerr = (*_int_lzo1x_1_11_compress)(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); + lzerr = lzo1x_1_11_compress(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); break; case 12: - lzerr = (*_int_lzo1x_1_12_compress)(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); + lzerr = lzo1x_1_12_compress(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); break; case 15: - lzerr = (*_int_lzo1x_1_15_compress)(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); + lzerr = lzo1x_1_15_compress(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); break; case 999: - lzerr = (*_int_lzo1x_999_compress)(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); + lzerr = lzo1x_999_compress(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); break; default: - lzerr = (*_int_lzo1x_1_compress)(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); + lzerr = lzo1x_1_compress(buf_in, buf_in_len, buf_out, &cmp_len, knet_h->compress_int_data[knet_h->compress_model]); break; } if (lzerr != LZO_E_OK) { log_err(knet_h, KNET_SUB_LZO2COMP, "lzo2 internal compression error"); savederrno = EAGAIN; err = -1; } else { *buf_out_len = cmp_len; } errno = savederrno; return err; } -int lzo2_decompress( +static int lzo2_decompress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int lzerr = 0, err = 0; int savederrno = 0; lzo_uint decmp_len; - lzerr = (*_int_lzo1x_decompress)(buf_in, buf_in_len, buf_out, &decmp_len, NULL); + lzerr = lzo1x_decompress(buf_in, buf_in_len, buf_out, &decmp_len, NULL); if (lzerr != LZO_E_OK) { log_err(knet_h, KNET_SUB_LZO2COMP, "lzo2 internal decompression error"); savederrno = EAGAIN; err = -1; } else { *buf_out_len = decmp_len; } errno = savederrno; return err; } -#endif + +compress_model_t compress_model = { "", 0, 0, NULL, 0, lzo2_is_init, lzo2_init, lzo2_fini, lzo2_val_level, lzo2_compress, lzo2_decompress }; diff --git a/libknet/compress_lzo2.h b/libknet/compress_lzo2.h deleted file mode 100644 index 990e63bf..00000000 --- a/libknet/compress_lzo2.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2017 Red Hat, Inc. All rights reserved. - * - * Author: Fabio M. Di Nitto - * - * This software licensed under GPL-2.0+, LGPL-2.0+ - */ - -#ifndef __KNET_COMPRESS_LZO2_H__ -#define __KNET_COMPRESS_LZO2_H__ - -#include "internals.h" - -int lzo2_load_lib( - knet_handle_t knet_h); - -int lzo2_is_init( - knet_handle_t knet_h, - int method_idx); - -int lzo2_init( - knet_handle_t knet_h, - int method_idx); - -void lzo2_fini( - knet_handle_t knet_h, - int method_idx); - -int lzo2_val_level( - knet_handle_t knet_h, - int compress_level); - -int lzo2_compress( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int lzo2_decompress( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -#endif diff --git a/libknet/compress_lzo2_remap.h b/libknet/compress_lzo2_remap.h deleted file mode 100644 index c0c7d2b7..00000000 --- a/libknet/compress_lzo2_remap.h +++ /dev/null @@ -1,26 +0,0 @@ -#include "remap.h" - -REMAP_PROTO(int,lzo1x_decompress, - (const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem /* NOT USED */ )) -REMAP_PROTO(int,lzo1x_1_compress, - (const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem)) -REMAP_PROTO(int,lzo1x_1_11_compress, - (const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem)) -REMAP_PROTO(int,lzo1x_1_12_compress, - (const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem)) -REMAP_PROTO(int,lzo1x_1_15_compress, - (const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem)) -REMAP_PROTO(int,lzo1x_999_compress, - (const lzo_bytep src, lzo_uint src_len, - lzo_bytep dst, lzo_uintp dst_len, - lzo_voidp wrkmem)) diff --git a/libknet/compress_model.h b/libknet/compress_model.h index 2d040d8f..cc8ba8d3 100644 --- a/libknet/compress_model.h +++ b/libknet/compress_model.h @@ -1,95 +1,92 @@ /* * Copyright (C) 2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #ifndef __KNET_COMPRESS_MODEL_H__ #define __KNET_COMPRESS_MODEL_H__ #include "internals.h" -/* This separate typedef can be removed again when the load_lib field disappears */ -typedef struct compress_model_t compress_model_t; - -struct compress_model_t { +typedef struct { const char *model_name; uint8_t model_id; /* sequencial unique identifier */ uint8_t built_in; /* set at configure/build time to 1 if available */ /* * shared lib load functions * * both are called in shlib_rwlock write context and should * update the loaded status below. */ - int (*load_lib) (knet_handle_t knet_h, compress_model_t *self); + int (*load_lib) (knet_handle_t knet_h); /* * library is loaded */ uint8_t loaded; /* * runtime bits */ /* * some libs need special init and handling of buffers etc. * is_init is called in shlib_rwlock read only context to see if * the module has been initialized within this knet_handle. * Providing is_init is optional. A module that does not export * an is_init and if the associated shared library is already loaded * is treated as "does not require init". */ int (*is_init) (knet_handle_t knet_h, int method_idx); /* * init is called when the library requires special init handling, * such as memory allocation and such. * init is invoked in shlib_rwlock write only context when * the module exports this function. * It is optional to provide an init function if the module * does not require any init. */ int (*init) (knet_handle_t knet_h, int method_idx); /* * fini is invoked only on knet_handle_free in a write only context. * It is optional to provide this function if the module * does not require any finalization */ void (*fini) (knet_handle_t knet_h, int method_idx); /* * runtime config validation and compress/decompress */ /* * required functions * * val_level is called upon compress configuration changes * to make sure that the requested compress_level is valid * within the context of a given module. */ int (*val_level)(knet_handle_t knet_h, int compress_level); /* * hopefully those 2 don't require any explanation.... */ int (*compress) (knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len); int (*decompress)(knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len); -}; +} compress_model_t; #endif diff --git a/libknet/compress_zlib.c b/libknet/compress_zlib.c index 76a7d04e..e319d9c3 100644 --- a/libknet/compress_zlib.c +++ b/libknet/compress_zlib.c @@ -1,175 +1,127 @@ /* * Copyright (C) 2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "config.h" -#include -#include #include -#include -#ifdef BUILDCOMPZLIB #include -#include "internals.h" -#include "compress_zlib.h" #include "logging.h" -#include "common.h" +#include "compress_model.h" -/* - * global vars for dlopen - */ -static void *zlib_lib; - -#include "compress_zlib_remap.h" - -static int zlib_remap_symbols(knet_handle_t knet_h) -{ -#define REMAP_WITH(name) remap_symbol (knet_h, KNET_SUB_ZLIBCOMP, zlib_lib, name) -#include "compress_zlib_remap.h" - return 0; - - fail: -#define REMAP_FAIL -#include "compress_zlib_remap.h" - errno = EINVAL; - return -1; -} - -int zlib_load_lib( - knet_handle_t knet_h) -{ - int err = 0, savederrno = 0; - - if (!zlib_lib) { - zlib_lib = open_lib(knet_h, LIBZ_1, 0); - if (!zlib_lib) { - savederrno = EAGAIN; - err = -1; - goto out; - } - } - - if (zlib_remap_symbols(knet_h) < 0) { - savederrno = errno; - err = -1; - } -out: - errno = savederrno; - return err; -} - -int zlib_val_level( +static int zlib_val_level( knet_handle_t knet_h, int compress_level) { if (compress_level < 0) { log_err(knet_h, KNET_SUB_ZLIBCOMP, "zlib does not support negative compression level %d", compress_level); return -1; } if (compress_level > 9) { log_err(knet_h, KNET_SUB_ZLIBCOMP, "zlib does not support compression level higher than 9"); return -1; } if (compress_level == 0) { log_warn(knet_h, KNET_SUB_ZLIBCOMP, "zlib compress level 0 does NOT perform any compression"); } return 0; } -int zlib_compress( +static int zlib_compress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int zerr = 0, err = 0; int savederrno = 0; uLongf destLen = *buf_out_len; - zerr = (*_int_compress2)(buf_out, &destLen, - buf_in, buf_in_len, - knet_h->compress_level); + zerr = compress2(buf_out, &destLen, + buf_in, buf_in_len, + knet_h->compress_level); *buf_out_len = destLen; switch(zerr) { case Z_OK: err = 0; savederrno = 0; break; case Z_MEM_ERROR: log_err(knet_h, KNET_SUB_ZLIBCOMP, "zlib compress mem error"); err = -1; savederrno = ENOMEM; break; case Z_BUF_ERROR: log_err(knet_h, KNET_SUB_ZLIBCOMP, "zlib compress buf error"); err = -1; savederrno = ENOBUFS; break; case Z_STREAM_ERROR: log_err(knet_h, KNET_SUB_ZLIBCOMP, "zlib compress stream error"); err = -1; savederrno = EINVAL; break; default: log_err(knet_h, KNET_SUB_ZLIBCOMP, "zlib unknown compress error: %d", zerr); break; } errno = savederrno; return err; } -int zlib_decompress( +static int zlib_decompress( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { int zerr = 0, err = 0; int savederrno = 0; uLongf destLen = *buf_out_len; - zerr = (*_int_uncompress)(buf_out, &destLen, - buf_in, buf_in_len); + zerr = uncompress(buf_out, &destLen, + buf_in, buf_in_len); *buf_out_len = destLen; switch(zerr) { case Z_OK: err = 0; savederrno = 0; break; case Z_MEM_ERROR: log_err(knet_h, KNET_SUB_ZLIBCOMP, "zlib decompress mem error"); err = -1; savederrno = ENOMEM; break; case Z_BUF_ERROR: log_err(knet_h, KNET_SUB_ZLIBCOMP, "zlib decompress buf error"); err = -1; savederrno = ENOBUFS; break; case Z_DATA_ERROR: log_err(knet_h, KNET_SUB_ZLIBCOMP, "zlib decompress data error"); err = -1; savederrno = EINVAL; break; default: log_err(knet_h, KNET_SUB_ZLIBCOMP, "zlib unknown decompress error: %d", zerr); break; } errno = savederrno; return err; } -#endif + +compress_model_t compress_model = { "", 0, 0, NULL, 0, NULL, NULL, NULL, zlib_val_level, zlib_compress, zlib_decompress }; diff --git a/libknet/compress_zlib.h b/libknet/compress_zlib.h deleted file mode 100644 index 26791633..00000000 --- a/libknet/compress_zlib.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2017 Red Hat, Inc. All rights reserved. - * - * Author: Fabio M. Di Nitto - * - * This software licensed under GPL-2.0+, LGPL-2.0+ - */ - -#ifndef __KNET_COMPRESS_ZLIB_H__ -#define __KNET_COMPRESS_ZLIB_H__ - -#include "internals.h" - -int zlib_load_lib( - knet_handle_t knet_h); - -int zlib_val_level( - knet_handle_t knet_h, - int compress_level); - -int zlib_compress( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int zlib_decompress( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -#endif diff --git a/libknet/compress_zlib_remap.h b/libknet/compress_zlib_remap.h deleted file mode 100644 index 7ff16e67..00000000 --- a/libknet/compress_zlib_remap.h +++ /dev/null @@ -1,9 +0,0 @@ -#include "remap.h" - -REMAP_PROTO(int,uncompress, - (Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)) -REMAP_PROTO(int,compress2, - (Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)) diff --git a/libknet/crypto.c b/libknet/crypto.c index 1d429dea..23a43fa3 100644 --- a/libknet/crypto.c +++ b/libknet/crypto.c @@ -1,210 +1,210 @@ /* * Copyright (C) 2012-2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "config.h" #include #include #include #include #include #include "crypto.h" -#include "crypto_nss.h" -#include "crypto_openssl.h" +#include "crypto_model.h" #include "internals.h" #include "logging.h" +#include "common.h" /* * internal module switch data */ #define empty_module NULL, 0, NULL, NULL, NULL, NULL, NULL }, crypto_model_t crypto_modules_cmds[] = { { "nss", #ifdef BUILDCRYPTONSS - 1, nsscrypto_load_lib, 0, nsscrypto_init, nsscrypto_fini, nsscrypto_encrypt_and_sign, nsscrypto_encrypt_and_signv, nsscrypto_authenticate_and_decrypt }, + 1, NULL, 0, NULL, NULL, NULL, NULL, NULL }, #else 0,empty_module #endif { "openssl", #ifdef BUILDCRYPTOOPENSSL - 1, opensslcrypto_load_lib, 0, opensslcrypto_init, opensslcrypto_fini, opensslcrypto_encrypt_and_sign, opensslcrypto_encrypt_and_signv, opensslcrypto_authenticate_and_decrypt }, + 1, NULL, 0, NULL, NULL, NULL, NULL, NULL }, #else 0,empty_module #endif { NULL, 0, empty_module }; static int crypto_get_model(const char *model) { int idx = 0; while (crypto_modules_cmds[idx].model_name != NULL) { if (!strcmp(crypto_modules_cmds[idx].model_name, model)) return idx; idx++; } return -1; } /* * exported API */ int crypto_encrypt_and_sign ( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { return crypto_modules_cmds[knet_h->crypto_instance->model].crypt(knet_h, buf_in, buf_in_len, buf_out, buf_out_len); } int crypto_encrypt_and_signv ( knet_handle_t knet_h, const struct iovec *iov_in, int iovcnt_in, unsigned char *buf_out, ssize_t *buf_out_len) { return crypto_modules_cmds[knet_h->crypto_instance->model].cryptv(knet_h, iov_in, iovcnt_in, buf_out, buf_out_len); } int crypto_authenticate_and_decrypt ( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { return crypto_modules_cmds[knet_h->crypto_instance->model].decrypt(knet_h, buf_in, buf_in_len, buf_out, buf_out_len); } int crypto_init( knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg) { int savederrno = 0; int model = 0; model = crypto_get_model(knet_handle_crypto_cfg->crypto_model); if (model < 0) { log_err(knet_h, KNET_SUB_CRYPTO, "model %s not supported", knet_handle_crypto_cfg->crypto_model); return -1; } if (crypto_modules_cmds[model].built_in == 0) { log_err(knet_h, KNET_SUB_CRYPTO, "this version of libknet was built without %s support. Please contact your vendor or fix the build.", knet_handle_crypto_cfg->crypto_model); return -1; } savederrno = pthread_rwlock_wrlock(&shlib_rwlock); if (savederrno) { log_err(knet_h, KNET_SUB_CRYPTO, "Unable to get write lock: %s", strerror(savederrno)); return -1; } if (!crypto_modules_cmds[model].loaded) { - if (crypto_modules_cmds[model].load_lib(knet_h) < 0) { + if (load_crypto_lib(knet_h, crypto_modules_cmds+model) < 0) { log_err(knet_h, KNET_SUB_CRYPTO, "Unable to load %s lib", crypto_modules_cmds[model].model_name); goto out_err; } crypto_modules_cmds[model].loaded = 1; } log_debug(knet_h, KNET_SUB_CRYPTO, "Initizializing crypto module [%s/%s/%s]", knet_handle_crypto_cfg->crypto_model, knet_handle_crypto_cfg->crypto_cipher_type, knet_handle_crypto_cfg->crypto_hash_type); knet_h->crypto_instance = malloc(sizeof(struct crypto_instance)); if (!knet_h->crypto_instance) { log_err(knet_h, KNET_SUB_CRYPTO, "Unable to allocate memory for crypto instance"); pthread_rwlock_unlock(&shlib_rwlock); goto out_err; } /* * if crypto_modules_cmds.init fails, it is expected that * it will clean everything by itself. * crypto_modules_cmds.fini is not invoked on error. */ knet_h->crypto_instance->model = model; if (crypto_modules_cmds[knet_h->crypto_instance->model].init(knet_h, knet_handle_crypto_cfg)) goto out_err; log_debug(knet_h, KNET_SUB_CRYPTO, "security network overhead: %zu", knet_h->sec_header_size); pthread_rwlock_unlock(&shlib_rwlock); return 0; out_err: if (knet_h->crypto_instance) { free(knet_h->crypto_instance); knet_h->crypto_instance = NULL; } pthread_rwlock_unlock(&shlib_rwlock); return -1; } void crypto_fini( knet_handle_t knet_h) { int savederrno = 0; int model = 0; savederrno = pthread_rwlock_wrlock(&shlib_rwlock); if (savederrno) { log_err(knet_h, KNET_SUB_CRYPTO, "Unable to get write lock: %s", strerror(savederrno)); return; } if (knet_h->crypto_instance) { model = knet_h->crypto_instance->model; if (crypto_modules_cmds[model].fini != NULL) { crypto_modules_cmds[model].fini(knet_h); } free(knet_h->crypto_instance); knet_h->crypto_instance = NULL; } pthread_rwlock_unlock(&shlib_rwlock); return; } int knet_get_crypto_list(struct knet_crypto_info *crypto_list, size_t *crypto_list_entries) { int err = 0; int idx = 0; int outidx = 0; if (!crypto_list_entries) { errno = EINVAL; return -1; } while (crypto_modules_cmds[idx].model_name != NULL) { if (crypto_modules_cmds[idx].built_in) { if (crypto_list) { crypto_list[outidx].name = crypto_modules_cmds[idx].model_name; } outidx++; } idx++; } *crypto_list_entries = outidx; return err; } diff --git a/libknet/crypto.h b/libknet/crypto.h index 2208de84..fbc5d0e1 100644 --- a/libknet/crypto.h +++ b/libknet/crypto.h @@ -1,77 +1,42 @@ /* * Copyright (C) 2012-2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #ifndef __KNET_CRYPTO_H__ #define __KNET_CRYPTO_H__ #include "internals.h" -struct crypto_instance { - int model; - void *model_instance; -}; - -typedef struct { - const char *model_name; - uint8_t built_in; - - /* - * see compress.h for explanation of the various lib related functions - */ - int (*load_lib) (knet_handle_t knet_h); - uint8_t loaded; - - int (*init) (knet_handle_t knet_h, - struct knet_handle_crypto_cfg *knet_handle_crypto_cfg); - void (*fini) (knet_handle_t knet_h); - int (*crypt) (knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - int (*cryptv) (knet_handle_t knet_h, - const struct iovec *iov_in, - int iovcnt_in, - unsigned char *buf_out, - ssize_t *buf_out_len); - int (*decrypt) (knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); -} crypto_model_t; - int crypto_authenticate_and_decrypt ( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len); int crypto_encrypt_and_sign ( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len); int crypto_encrypt_and_signv ( knet_handle_t knet_h, const struct iovec *iov_in, int iovcnt_in, unsigned char *buf_out, ssize_t *buf_out_len); int crypto_init( knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg); void crypto_fini( knet_handle_t knet_h); #endif diff --git a/libknet/crypto_canary.c b/libknet/crypto_canary.c deleted file mode 100644 index 1555694c..00000000 --- a/libknet/crypto_canary.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Transform the binary into dependencies like: - * dpkg-shlibdeps -pcrypto -dRecommends -xlibc6 -elibknet/crypto_canary -O | sed 's/,/ |/g' >>debian/substvars - */ - -#include "config.h" - -#define CANARY - -#include "crypto_nss_remap.h" -#include "crypto_openssl_remap.h" - -#define CANARY_CALL - -int main (void) -{ - return -#ifdef BUILDCRYPTONSS -#include "crypto_nss_remap.h" -#endif -#ifdef BUILDCRYPTOOPENSSL -#include "crypto_openssl_remap.h" -#endif - 0; -} diff --git a/libknet/crypto.h b/libknet/crypto_model.h similarity index 57% copy from libknet/crypto.h copy to libknet/crypto_model.h index 2208de84..3833ce1c 100644 --- a/libknet/crypto.h +++ b/libknet/crypto_model.h @@ -1,77 +1,49 @@ /* * Copyright (C) 2012-2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ -#ifndef __KNET_CRYPTO_H__ -#define __KNET_CRYPTO_H__ +#ifndef __KNET_CRYPTO_MODEL_H__ +#define __KNET_CRYPTO_MODEL_H__ #include "internals.h" struct crypto_instance { int model; void *model_instance; }; typedef struct { const char *model_name; uint8_t built_in; /* - * see compress.h for explanation of the various lib related functions + * see compress_model.h for explanation of the various lib related functions */ int (*load_lib) (knet_handle_t knet_h); uint8_t loaded; int (*init) (knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg); void (*fini) (knet_handle_t knet_h); int (*crypt) (knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len); int (*cryptv) (knet_handle_t knet_h, const struct iovec *iov_in, int iovcnt_in, unsigned char *buf_out, ssize_t *buf_out_len); int (*decrypt) (knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len); } crypto_model_t; -int crypto_authenticate_and_decrypt ( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int crypto_encrypt_and_sign ( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int crypto_encrypt_and_signv ( - knet_handle_t knet_h, - const struct iovec *iov_in, - int iovcnt_in, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int crypto_init( - knet_handle_t knet_h, - struct knet_handle_crypto_cfg *knet_handle_crypto_cfg); - -void crypto_fini( - knet_handle_t knet_h); - #endif diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c index 2b5a7314..548eaf0b 100644 --- a/libknet/crypto_nss.c +++ b/libknet/crypto_nss.c @@ -1,856 +1,806 @@ /* * Copyright (C) 2012-2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "config.h" #include -#include #include -#ifdef BUILDCRYPTONSS #include #include #include #include #include #include #include #include #include #include -#include "common.h" -#include "crypto.h" -#include "crypto_nss.h" +#include "crypto_model.h" #include "logging.h" -/* - * global vars for dlopen - */ -static void *nss_lib; - -#include "crypto_nss_remap.h" - -static int nsscrypto_remap_symbols(knet_handle_t knet_h) -{ -#define REMAP_WITH(name) remap_symbol (knet_h, KNET_SUB_NSSCRYPTO, nss_lib, name) -#include "crypto_nss_remap.h" - return 0; - - fail: -#define REMAP_FAIL -#include "crypto_nss_remap.h" - errno = EINVAL; - return -1; -} - static int nss_db_is_init = 0; static int at_exit_registered = 0; static void nss_atexit_handler(void) { if (nss_db_is_init) { - if (_int_NSS_Shutdown) { - (*_int_NSS_Shutdown)(); - } - if ((_int_PR_Initialized) && ((*_int_PR_Initialized)())) { - if (_int_PL_ArenaFinish) { - (*_int_PL_ArenaFinish)(); - } - if (_int_PR_Cleanup) { - (*_int_PR_Cleanup)(); - } + NSS_Shutdown(); + if (PR_Initialized()) { + PL_ArenaFinish(); + PR_Cleanup(); } } return; } -int nsscrypto_load_lib( +static int nsscrypto_load_lib( knet_handle_t knet_h) { - int err = 0, savederrno = 0; - - if (!nss_lib) { - nss_lib = open_lib(knet_h, LIBNSS3, 0); - if (!nss_lib) { - savederrno = errno; - err = -1; - goto out; - } - } - - if (nsscrypto_remap_symbols(knet_h) < 0) { - savederrno = errno; - err = -1; - goto out; - } - if (!at_exit_registered) { if (atexit(nss_atexit_handler)) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to register NSS atexit handler"); - savederrno = EAGAIN; - err = -1; - goto out; + errno = EAGAIN; + return -1; } at_exit_registered = 1; } - if ((nss_lib) && (_int_NSS_NoDB_Init) && (!nss_db_is_init)) { - if ((*_int_NSS_NoDB_Init)(".") != SECSuccess) { + if (!nss_db_is_init) { + if (NSS_NoDB_Init(".") != SECSuccess) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "NSS DB initialization failed (err %d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); - savederrno = EAGAIN; - err = -1; - goto out; + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); + errno = EAGAIN; + return -1; } nss_db_is_init = 1; } -out: - errno = savederrno; - return err; + return 0; } /* * crypto definitions and conversion tables */ #define SALT_SIZE 16 /* * This are defined in new NSS. For older one, we will define our own */ #ifndef AES_256_KEY_LENGTH #define AES_256_KEY_LENGTH 32 #endif #ifndef AES_192_KEY_LENGTH #define AES_192_KEY_LENGTH 24 #endif #ifndef AES_128_KEY_LENGTH #define AES_128_KEY_LENGTH 16 #endif enum nsscrypto_crypt_t { CRYPTO_CIPHER_TYPE_NONE = 0, CRYPTO_CIPHER_TYPE_AES256 = 1, CRYPTO_CIPHER_TYPE_AES192 = 2, CRYPTO_CIPHER_TYPE_AES128 = 3, CRYPTO_CIPHER_TYPE_3DES = 4 }; CK_MECHANISM_TYPE cipher_to_nss[] = { 0, /* CRYPTO_CIPHER_TYPE_NONE */ CKM_AES_CBC_PAD, /* CRYPTO_CIPHER_TYPE_AES256 */ CKM_AES_CBC_PAD, /* CRYPTO_CIPHER_TYPE_AES192 */ CKM_AES_CBC_PAD, /* CRYPTO_CIPHER_TYPE_AES128 */ CKM_DES3_CBC_PAD /* CRYPTO_CIPHER_TYPE_3DES */ }; size_t nsscipher_key_len[] = { 0, /* CRYPTO_CIPHER_TYPE_NONE */ AES_256_KEY_LENGTH, /* CRYPTO_CIPHER_TYPE_AES256 */ AES_192_KEY_LENGTH, /* CRYPTO_CIPHER_TYPE_AES192 */ AES_128_KEY_LENGTH, /* CRYPTO_CIPHER_TYPE_AES128 */ 24 /* CRYPTO_CIPHER_TYPE_3DES */ }; size_t nsscypher_block_len[] = { 0, /* CRYPTO_CIPHER_TYPE_NONE */ AES_BLOCK_SIZE, /* CRYPTO_CIPHER_TYPE_AES256 */ AES_BLOCK_SIZE, /* CRYPTO_CIPHER_TYPE_AES192 */ AES_BLOCK_SIZE, /* CRYPTO_CIPHER_TYPE_AES128 */ 0 /* CRYPTO_CIPHER_TYPE_3DES */ }; /* * hash definitions and conversion tables */ enum nsscrypto_hash_t { CRYPTO_HASH_TYPE_NONE = 0, CRYPTO_HASH_TYPE_MD5 = 1, CRYPTO_HASH_TYPE_SHA1 = 2, CRYPTO_HASH_TYPE_SHA256 = 3, CRYPTO_HASH_TYPE_SHA384 = 4, CRYPTO_HASH_TYPE_SHA512 = 5 }; CK_MECHANISM_TYPE hash_to_nss[] = { 0, /* CRYPTO_HASH_TYPE_NONE */ CKM_MD5_HMAC, /* CRYPTO_HASH_TYPE_MD5 */ CKM_SHA_1_HMAC, /* CRYPTO_HASH_TYPE_SHA1 */ CKM_SHA256_HMAC, /* CRYPTO_HASH_TYPE_SHA256 */ CKM_SHA384_HMAC, /* CRYPTO_HASH_TYPE_SHA384 */ CKM_SHA512_HMAC /* CRYPTO_HASH_TYPE_SHA512 */ }; size_t nsshash_len[] = { 0, /* CRYPTO_HASH_TYPE_NONE */ MD5_LENGTH, /* CRYPTO_HASH_TYPE_MD5 */ SHA1_LENGTH, /* CRYPTO_HASH_TYPE_SHA1 */ SHA256_LENGTH, /* CRYPTO_HASH_TYPE_SHA256 */ SHA384_LENGTH, /* CRYPTO_HASH_TYPE_SHA384 */ SHA512_LENGTH /* CRYPTO_HASH_TYPE_SHA512 */ }; enum sym_key_type { SYM_KEY_TYPE_CRYPT, SYM_KEY_TYPE_HASH }; struct nsscrypto_instance { PK11SymKey *nss_sym_key; PK11SymKey *nss_sym_key_sign; unsigned char *private_key; unsigned int private_key_len; int crypto_cipher_type; int crypto_hash_type; }; /* * crypt/decrypt functions */ static int nssstring_to_crypto_cipher_type(const char* crypto_cipher_type) { if (strcmp(crypto_cipher_type, "none") == 0) { return CRYPTO_CIPHER_TYPE_NONE; } else if (strcmp(crypto_cipher_type, "aes256") == 0) { return CRYPTO_CIPHER_TYPE_AES256; } else if (strcmp(crypto_cipher_type, "aes192") == 0) { return CRYPTO_CIPHER_TYPE_AES192; } else if (strcmp(crypto_cipher_type, "aes128") == 0) { return CRYPTO_CIPHER_TYPE_AES128; } else if (strcmp(crypto_cipher_type, "3des") == 0) { return CRYPTO_CIPHER_TYPE_3DES; } return -1; } static PK11SymKey *nssimport_symmetric_key(knet_handle_t knet_h, enum sym_key_type key_type) { struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance; SECItem key_item; PK11SlotInfo *slot; PK11SymKey *res_key; CK_MECHANISM_TYPE cipher; CK_ATTRIBUTE_TYPE operation; CK_MECHANISM_TYPE wrap_mechanism; int wrap_key_len; PK11SymKey *wrap_key; PK11Context *wrap_key_crypt_context; SECItem tmp_sec_item; SECItem wrapped_key; int wrapped_key_len; unsigned char wrapped_key_data[KNET_MAX_KEY_LEN]; memset(&key_item, 0, sizeof(key_item)); slot = NULL; wrap_key = NULL; res_key = NULL; wrap_key_crypt_context = NULL; key_item.type = siBuffer; key_item.data = instance->private_key; switch (key_type) { case SYM_KEY_TYPE_CRYPT: key_item.len = nsscipher_key_len[instance->crypto_cipher_type]; cipher = cipher_to_nss[instance->crypto_cipher_type]; operation = CKA_ENCRYPT|CKA_DECRYPT; break; case SYM_KEY_TYPE_HASH: key_item.len = instance->private_key_len; cipher = hash_to_nss[instance->crypto_hash_type]; operation = CKA_SIGN; break; default: log_err(knet_h, KNET_SUB_NSSCRYPTO, "Import symmetric key failed. Unknown keyimport request"); goto exit_res_key; break; } - slot = (*_int_PK11_GetBestSlot)(cipher, NULL); + slot = PK11_GetBestSlot(cipher, NULL); if (slot == NULL) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to find security slot (%d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto exit_res_key; } /* * Without FIPS it would be possible to just use * res_key = PK11_ImportSymKey(slot, cipher, PK11_OriginUnwrap, operation, &key_item, NULL); * with FIPS NSS Level 2 certification has to be "workarounded" (so it becomes Level 1) by using * following method: * 1. Generate wrap key * 2. Encrypt authkey with wrap key * 3. Unwrap encrypted authkey using wrap key */ /* * Generate wrapping key */ - wrap_mechanism = (*_int_PK11_GetBestWrapMechanism)(slot); - wrap_key_len = (*_int_PK11_GetBestKeyLength)(slot, wrap_mechanism); - wrap_key = (*_int_PK11_KeyGen)(slot, wrap_mechanism, NULL, wrap_key_len, NULL); + wrap_mechanism = PK11_GetBestWrapMechanism(slot); + wrap_key_len = PK11_GetBestKeyLength(slot, wrap_mechanism); + wrap_key = PK11_KeyGen(slot, wrap_mechanism, NULL, wrap_key_len, NULL); if (wrap_key == NULL) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to generate wrapping key (%d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto exit_res_key; } /* * Encrypt authkey with wrapping key */ /* * Initialization of IV is not needed because PK11_GetBestWrapMechanism should return ECB mode */ memset(&tmp_sec_item, 0, sizeof(tmp_sec_item)); - wrap_key_crypt_context = (*_int_PK11_CreateContextBySymKey)(wrap_mechanism, CKA_ENCRYPT, - wrap_key, &tmp_sec_item); + wrap_key_crypt_context = PK11_CreateContextBySymKey(wrap_mechanism, CKA_ENCRYPT, + wrap_key, &tmp_sec_item); if (wrap_key_crypt_context == NULL) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to create encrypt context (%d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto exit_res_key; } wrapped_key_len = (int)sizeof(wrapped_key_data); - if ((*_int_PK11_CipherOp)(wrap_key_crypt_context, wrapped_key_data, &wrapped_key_len, - sizeof(wrapped_key_data), key_item.data, key_item.len) != SECSuccess) { + if (PK11_CipherOp(wrap_key_crypt_context, wrapped_key_data, &wrapped_key_len, + sizeof(wrapped_key_data), key_item.data, key_item.len) != SECSuccess) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to encrypt authkey (%d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto exit_res_key; } - if ((*_int_PK11_Finalize)(wrap_key_crypt_context) != SECSuccess) { + if (PK11_Finalize(wrap_key_crypt_context) != SECSuccess) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to finalize encryption of authkey (%d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto exit_res_key; } /* * Finally unwrap sym key */ memset(&tmp_sec_item, 0, sizeof(tmp_sec_item)); wrapped_key.data = wrapped_key_data; wrapped_key.len = wrapped_key_len; - res_key = (*_int_PK11_UnwrapSymKey)(wrap_key, wrap_mechanism, &tmp_sec_item, &wrapped_key, - cipher, operation, key_item.len); + res_key = PK11_UnwrapSymKey(wrap_key, wrap_mechanism, &tmp_sec_item, &wrapped_key, + cipher, operation, key_item.len); if (res_key == NULL) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Failure to import key into NSS (%d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); - if ((*_int_PR_GetError)() == SEC_ERROR_BAD_DATA) { + if (PR_GetError() == SEC_ERROR_BAD_DATA) { /* * Maximum key length for FIPS enabled softtoken is limited to * MAX_KEY_LEN (pkcs11i.h - 256) and checked in NSC_UnwrapKey. Returned * error is CKR_TEMPLATE_INCONSISTENT which is mapped to SEC_ERROR_BAD_DATA. */ log_err(knet_h, KNET_SUB_NSSCRYPTO, "Secret key is probably too long. " "Try reduce it to 256 bytes"); } goto exit_res_key; } exit_res_key: if (wrap_key_crypt_context != NULL) { - (*_int_PK11_DestroyContext)(wrap_key_crypt_context, PR_TRUE); + PK11_DestroyContext(wrap_key_crypt_context, PR_TRUE); } if (wrap_key != NULL) { - (*_int_PK11_FreeSymKey)(wrap_key); + PK11_FreeSymKey(wrap_key); } if (slot != NULL) { - (*_int_PK11_FreeSlot)(slot); + PK11_FreeSlot(slot); } return (res_key); } static int init_nss_crypto(knet_handle_t knet_h) { struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance; if (!cipher_to_nss[instance->crypto_cipher_type]) { return 0; } instance->nss_sym_key = nssimport_symmetric_key(knet_h, SYM_KEY_TYPE_CRYPT); if (instance->nss_sym_key == NULL) { return -1; } return 0; } static int encrypt_nss( knet_handle_t knet_h, const struct iovec *iov, int iovcnt, unsigned char *buf_out, ssize_t *buf_out_len) { struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance; PK11Context* crypt_context = NULL; SECItem crypt_param; SECItem *nss_sec_param = NULL; int tmp_outlen = 0, tmp1_outlen = 0; unsigned int tmp2_outlen = 0; unsigned char *salt = buf_out; unsigned char *data = buf_out + SALT_SIZE; int err = -1; int i; - if ((*_int_PK11_GenerateRandom)(salt, SALT_SIZE) != SECSuccess) { + if (PK11_GenerateRandom(salt, SALT_SIZE) != SECSuccess) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Failure to generate a random number (err %d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } crypt_param.type = siBuffer; crypt_param.data = salt; crypt_param.len = SALT_SIZE; - nss_sec_param = (*_int_PK11_ParamFromIV)(cipher_to_nss[instance->crypto_cipher_type], - &crypt_param); + nss_sec_param = PK11_ParamFromIV(cipher_to_nss[instance->crypto_cipher_type], + &crypt_param); if (nss_sec_param == NULL) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Failure to set up PKCS11 param (err %d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } /* * Create cipher context for encryption */ - crypt_context = (*_int_PK11_CreateContextBySymKey)(cipher_to_nss[instance->crypto_cipher_type], - CKA_ENCRYPT, - instance->nss_sym_key, - nss_sec_param); + crypt_context = PK11_CreateContextBySymKey(cipher_to_nss[instance->crypto_cipher_type], + CKA_ENCRYPT, + instance->nss_sym_key, + nss_sec_param); if (!crypt_context) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CreateContext failed (encrypt) crypt_type=%d (err %d): %s", (int)cipher_to_nss[instance->crypto_cipher_type], - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } for (i=0; icrypto_cipher_type], - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } tmp1_outlen = tmp1_outlen + tmp_outlen; } - if ((*_int_PK11_DigestFinal)(crypt_context, data + tmp1_outlen, + if (PK11_DigestFinal(crypt_context, data + tmp1_outlen, &tmp2_outlen, KNET_DATABUFSIZE_CRYPT - tmp1_outlen) != SECSuccess) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinal failed (encrypt) crypt_type=%d (err %d): %s", (int)cipher_to_nss[instance->crypto_cipher_type], - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } *buf_out_len = tmp1_outlen + tmp2_outlen + SALT_SIZE; err = 0; out: if (crypt_context) { - (*_int_PK11_DestroyContext)(crypt_context, PR_TRUE); + PK11_DestroyContext(crypt_context, PR_TRUE); } if (nss_sec_param) { - (*_int_SECITEM_FreeItem)(nss_sec_param, PR_TRUE); + SECITEM_FreeItem(nss_sec_param, PR_TRUE); } return err; } static int decrypt_nss ( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance; PK11Context* decrypt_context = NULL; SECItem decrypt_param; int tmp1_outlen = 0; unsigned int tmp2_outlen = 0; unsigned char *salt = (unsigned char *)buf_in; unsigned char *data = salt + SALT_SIZE; int datalen = buf_in_len - SALT_SIZE; int err = -1; /* Create cipher context for decryption */ decrypt_param.type = siBuffer; decrypt_param.data = salt; decrypt_param.len = SALT_SIZE; - decrypt_context = (*_int_PK11_CreateContextBySymKey)(cipher_to_nss[instance->crypto_cipher_type], - CKA_DECRYPT, - instance->nss_sym_key, &decrypt_param); + decrypt_context = PK11_CreateContextBySymKey(cipher_to_nss[instance->crypto_cipher_type], + CKA_DECRYPT, + instance->nss_sym_key, &decrypt_param); if (!decrypt_context) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CreateContext (decrypt) failed (err %d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } - if ((*_int_PK11_CipherOp)(decrypt_context, buf_out, &tmp1_outlen, - KNET_DATABUFSIZE_CRYPT, data, datalen) != SECSuccess) { + if (PK11_CipherOp(decrypt_context, buf_out, &tmp1_outlen, + KNET_DATABUFSIZE_CRYPT, data, datalen) != SECSuccess) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CipherOp (decrypt) failed (err %d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } - if ((*_int_PK11_DigestFinal)(decrypt_context, buf_out + tmp1_outlen, &tmp2_outlen, - KNET_DATABUFSIZE_CRYPT - tmp1_outlen) != SECSuccess) { + if (PK11_DigestFinal(decrypt_context, buf_out + tmp1_outlen, &tmp2_outlen, + KNET_DATABUFSIZE_CRYPT - tmp1_outlen) != SECSuccess) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinal (decrypt) failed (err %d): %s", - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } *buf_out_len = tmp1_outlen + tmp2_outlen; err = 0; out: if (decrypt_context) { - (*_int_PK11_DestroyContext)(decrypt_context, PR_TRUE); + PK11_DestroyContext(decrypt_context, PR_TRUE); } return err; } /* * hash/hmac/digest functions */ static int nssstring_to_crypto_hash_type(const char* crypto_hash_type) { if (strcmp(crypto_hash_type, "none") == 0) { return CRYPTO_HASH_TYPE_NONE; } else if (strcmp(crypto_hash_type, "md5") == 0) { return CRYPTO_HASH_TYPE_MD5; } else if (strcmp(crypto_hash_type, "sha1") == 0) { return CRYPTO_HASH_TYPE_SHA1; } else if (strcmp(crypto_hash_type, "sha256") == 0) { return CRYPTO_HASH_TYPE_SHA256; } else if (strcmp(crypto_hash_type, "sha384") == 0) { return CRYPTO_HASH_TYPE_SHA384; } else if (strcmp(crypto_hash_type, "sha512") == 0) { return CRYPTO_HASH_TYPE_SHA512; } return -1; } static int init_nss_hash(knet_handle_t knet_h) { struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance; if (!hash_to_nss[instance->crypto_hash_type]) { return 0; } instance->nss_sym_key_sign = nssimport_symmetric_key(knet_h, SYM_KEY_TYPE_HASH); if (instance->nss_sym_key_sign == NULL) { return -1; } return 0; } static int calculate_nss_hash( knet_handle_t knet_h, const unsigned char *buf, const size_t buf_len, unsigned char *hash) { struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance; PK11Context* hash_context = NULL; SECItem hash_param; unsigned int hash_tmp_outlen = 0; int err = -1; /* Now do the digest */ hash_param.type = siBuffer; hash_param.data = 0; hash_param.len = 0; - hash_context = (*_int_PK11_CreateContextBySymKey)(hash_to_nss[instance->crypto_hash_type], - CKA_SIGN, - instance->nss_sym_key_sign, - &hash_param); + hash_context = PK11_CreateContextBySymKey(hash_to_nss[instance->crypto_hash_type], + CKA_SIGN, + instance->nss_sym_key_sign, + &hash_param); if (!hash_context) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CreateContext failed (hash) hash_type=%d (err %d): %s", (int)hash_to_nss[instance->crypto_hash_type], - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } - if ((*_int_PK11_DigestBegin)(hash_context) != SECSuccess) { + if (PK11_DigestBegin(hash_context) != SECSuccess) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestBegin failed (hash) hash_type=%d (err %d): %s", (int)hash_to_nss[instance->crypto_hash_type], - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } - if ((*_int_PK11_DigestOp)(hash_context, buf, buf_len) != SECSuccess) { + if (PK11_DigestOp(hash_context, buf, buf_len) != SECSuccess) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestOp failed (hash) hash_type=%d (err %d): %s", (int)hash_to_nss[instance->crypto_hash_type], - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } - if ((*_int_PK11_DigestFinal)(hash_context, hash, - &hash_tmp_outlen, nsshash_len[instance->crypto_hash_type]) != SECSuccess) { + if (PK11_DigestFinal(hash_context, hash, + &hash_tmp_outlen, nsshash_len[instance->crypto_hash_type]) != SECSuccess) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinale failed (hash) hash_type=%d (err %d): %s", (int)hash_to_nss[instance->crypto_hash_type], - (*_int_PR_GetError)(), (*_int_PR_ErrorToString)((*_int_PR_GetError)(), PR_LANGUAGE_I_DEFAULT)); + PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT)); goto out; } err = 0; out: if (hash_context) { - (*_int_PK11_DestroyContext)(hash_context, PR_TRUE); + PK11_DestroyContext(hash_context, PR_TRUE); } return err; } /* * global/glue nss functions */ static int init_nss(knet_handle_t knet_h) { if (init_nss_crypto(knet_h) < 0) { return -1; } if (init_nss_hash(knet_h) < 0) { return -1; } return 0; } /* * exported API */ -int nsscrypto_encrypt_and_sign ( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len) -{ - struct iovec iov_in; - - memset(&iov_in, 0, sizeof(iov_in)); - iov_in.iov_base = (unsigned char *)buf_in; - iov_in.iov_len = buf_in_len; - - return nsscrypto_encrypt_and_signv(knet_h, &iov_in, 1, buf_out, buf_out_len); -} - -int nsscrypto_encrypt_and_signv ( +static int nsscrypto_encrypt_and_signv ( knet_handle_t knet_h, const struct iovec *iov_in, int iovcnt_in, unsigned char *buf_out, ssize_t *buf_out_len) { struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance; int i; if (cipher_to_nss[instance->crypto_cipher_type]) { if (encrypt_nss(knet_h, iov_in, iovcnt_in, buf_out, buf_out_len) < 0) { return -1; } } else { *buf_out_len = 0; for (i=0; icrypto_hash_type]) { if (calculate_nss_hash(knet_h, buf_out, *buf_out_len, buf_out + *buf_out_len) < 0) { return -1; } *buf_out_len = *buf_out_len + nsshash_len[instance->crypto_hash_type]; } return 0; } -int nsscrypto_authenticate_and_decrypt ( +static int nsscrypto_encrypt_and_sign ( + knet_handle_t knet_h, + const unsigned char *buf_in, + const ssize_t buf_in_len, + unsigned char *buf_out, + ssize_t *buf_out_len) +{ + struct iovec iov_in; + + memset(&iov_in, 0, sizeof(iov_in)); + iov_in.iov_base = (unsigned char *)buf_in; + iov_in.iov_len = buf_in_len; + + return nsscrypto_encrypt_and_signv(knet_h, &iov_in, 1, buf_out, buf_out_len); +} + +static int nsscrypto_authenticate_and_decrypt ( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance; ssize_t temp_len = buf_in_len; if (hash_to_nss[instance->crypto_hash_type]) { unsigned char tmp_hash[nsshash_len[instance->crypto_hash_type]]; ssize_t temp_buf_len = buf_in_len - nsshash_len[instance->crypto_hash_type]; if ((temp_buf_len < 0) || (temp_buf_len > KNET_MAX_PACKET_SIZE)) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Incorrect packet size."); return -1; } if (calculate_nss_hash(knet_h, buf_in, temp_buf_len, tmp_hash) < 0) { return -1; } if (memcmp(tmp_hash, buf_in + temp_buf_len, nsshash_len[instance->crypto_hash_type]) != 0) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Digest does not match"); return -1; } temp_len = temp_len - nsshash_len[instance->crypto_hash_type]; *buf_out_len = temp_len; } if (cipher_to_nss[instance->crypto_cipher_type]) { if (decrypt_nss(knet_h, buf_in, temp_len, buf_out, buf_out_len) < 0) { return -1; } } else { memmove(buf_out, buf_in, temp_len); *buf_out_len = temp_len; } return 0; } -int nsscrypto_init( +static void nsscrypto_fini( + knet_handle_t knet_h) +{ + struct nsscrypto_instance *nsscrypto_instance = knet_h->crypto_instance->model_instance; + + if (nsscrypto_instance) { + if (nsscrypto_instance->nss_sym_key) { + PK11_FreeSymKey(nsscrypto_instance->nss_sym_key); + nsscrypto_instance->nss_sym_key = NULL; + } + if (nsscrypto_instance->nss_sym_key_sign) { + PK11_FreeSymKey(nsscrypto_instance->nss_sym_key_sign); + nsscrypto_instance->nss_sym_key_sign = NULL; + } + free(nsscrypto_instance); + knet_h->crypto_instance->model_instance = NULL; + knet_h->sec_header_size = 0; + } + + return; +} + +static int nsscrypto_init( knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg) { struct nsscrypto_instance *nsscrypto_instance = NULL; log_debug(knet_h, KNET_SUB_NSSCRYPTO, "Initizializing nss crypto module [%s/%s]", knet_handle_crypto_cfg->crypto_cipher_type, knet_handle_crypto_cfg->crypto_hash_type); knet_h->crypto_instance->model_instance = malloc(sizeof(struct nsscrypto_instance)); if (!knet_h->crypto_instance->model_instance) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to allocate memory for nss model instance"); return -1; } nsscrypto_instance = knet_h->crypto_instance->model_instance; memset(nsscrypto_instance, 0, sizeof(struct nsscrypto_instance)); nsscrypto_instance->crypto_cipher_type = nssstring_to_crypto_cipher_type(knet_handle_crypto_cfg->crypto_cipher_type); if (nsscrypto_instance->crypto_cipher_type < 0) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "unknown crypto cipher type requested"); goto out_err; } nsscrypto_instance->crypto_hash_type = nssstring_to_crypto_hash_type(knet_handle_crypto_cfg->crypto_hash_type); if (nsscrypto_instance->crypto_hash_type < 0) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "unknown crypto hash type requested"); goto out_err; } if ((nsscrypto_instance->crypto_cipher_type > 0) && (nsscrypto_instance->crypto_hash_type == 0)) { log_err(knet_h, KNET_SUB_NSSCRYPTO, "crypto communication requires hash specified"); goto out_err; } nsscrypto_instance->private_key = knet_handle_crypto_cfg->private_key; nsscrypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len; if (init_nss(knet_h) < 0) { goto out_err; } knet_h->sec_header_size = 0; if (nsscrypto_instance->crypto_hash_type > 0) { knet_h->sec_header_size += nsshash_len[nsscrypto_instance->crypto_hash_type]; knet_h->sec_hash_size = nsshash_len[nsscrypto_instance->crypto_hash_type]; } if (nsscrypto_instance->crypto_cipher_type > 0) { int block_size; if (nsscypher_block_len[nsscrypto_instance->crypto_cipher_type]) { block_size = nsscypher_block_len[nsscrypto_instance->crypto_cipher_type]; } else { - block_size = (*_int_PK11_GetBlockSize)(nsscrypto_instance->crypto_cipher_type, NULL); + block_size = PK11_GetBlockSize(nsscrypto_instance->crypto_cipher_type, NULL); if (block_size < 0) { goto out_err; } } knet_h->sec_header_size += (block_size * 2); knet_h->sec_header_size += SALT_SIZE; knet_h->sec_salt_size = SALT_SIZE; knet_h->sec_block_size = block_size; } return 0; out_err: nsscrypto_fini(knet_h); return -1; } -void nsscrypto_fini( - knet_handle_t knet_h) -{ - struct nsscrypto_instance *nsscrypto_instance = knet_h->crypto_instance->model_instance; - - if (nsscrypto_instance) { - if (nsscrypto_instance->nss_sym_key) { - (*_int_PK11_FreeSymKey)(nsscrypto_instance->nss_sym_key); - nsscrypto_instance->nss_sym_key = NULL; - } - if (nsscrypto_instance->nss_sym_key_sign) { - (*_int_PK11_FreeSymKey)(nsscrypto_instance->nss_sym_key_sign); - nsscrypto_instance->nss_sym_key_sign = NULL; - } - free(nsscrypto_instance); - knet_h->crypto_instance->model_instance = NULL; - knet_h->sec_header_size = 0; - } - - return; -} -#endif +crypto_model_t crypto_model = { "", 0, nsscrypto_load_lib, 0, nsscrypto_init, nsscrypto_fini, nsscrypto_encrypt_and_sign, nsscrypto_encrypt_and_signv, nsscrypto_authenticate_and_decrypt }; diff --git a/libknet/crypto_nss.h b/libknet/crypto_nss.h deleted file mode 100644 index d77a8d8b..00000000 --- a/libknet/crypto_nss.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2012-2017 Red Hat, Inc. All rights reserved. - * - * Author: Fabio M. Di Nitto - * - * This software licensed under GPL-2.0+, LGPL-2.0+ - */ - -#ifndef __KNET_NSSCRYPTO_H__ -#define __KNET_NSSCRYPTO_H__ - -#include "internals.h" - -struct nsscrypto_instance; - -int nsscrypto_load_lib( - knet_handle_t knet_h); - -int nsscrypto_init( - knet_handle_t knet_h, - struct knet_handle_crypto_cfg *knet_handle_crypto_cfg); - -void nsscrypto_fini( - knet_handle_t knet_h); - -int nsscrypto_authenticate_and_decrypt ( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int nsscrypto_encrypt_and_sign ( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int nsscrypto_encrypt_and_signv ( - knet_handle_t knet_h, - const struct iovec *iov_in, - int iovcnt_in, - unsigned char *buf_out, - ssize_t *buf_out_len); - -#endif diff --git a/libknet/crypto_nss_remap.h b/libknet/crypto_nss_remap.h deleted file mode 100644 index 572aecda..00000000 --- a/libknet/crypto_nss_remap.h +++ /dev/null @@ -1,54 +0,0 @@ -#include "remap.h" - -/* - * nss3 - */ -REMAP_PROTO(CK_MECHANISM_TYPE,PK11_GetBestWrapMechanism,(PK11SlotInfo *slot)) -REMAP_PROTO(PK11SlotInfo *,PK11_GetBestSlot, - (CK_MECHANISM_TYPE type, void *wincx)) -REMAP_PROTO(int,PK11_GetBestKeyLength, - (PK11SlotInfo *slot, CK_MECHANISM_TYPE type)) -REMAP_PROTO(SECStatus,PK11_DigestFinal, - (PK11Context *context, unsigned char *data, - unsigned int *outLen, unsigned int length)) -REMAP_PROTO(void,SECITEM_FreeItem,(SECItem *zap, PRBool freeit)) -REMAP_PROTO(SECStatus,NSS_NoDB_Init,(const char *configdir)) -REMAP_PROTO(SECStatus,NSS_Shutdown,(void)) -REMAP_PROTO(SECStatus,PK11_DigestBegin,(PK11Context *cx)) -REMAP_PROTO(SECStatus,PK11_DigestOp, - (PK11Context *context, const unsigned char *in, unsigned len)) -REMAP_PROTO(void,PK11_DestroyContext,(PK11Context *context, PRBool freeit)) -REMAP_PROTO(SECStatus,PK11_Finalize,(PK11Context *context)) -REMAP_PROTO(SECStatus,PK11_CipherOp, - (PK11Context *context, unsigned char *out, int *outlen, - int maxout, const unsigned char *in, int inlen)) -REMAP_PROTO(PK11SymKey *,PK11_UnwrapSymKey, - (PK11SymKey *key, CK_MECHANISM_TYPE wraptype, SECItem *param, - SECItem *wrapppedKey, CK_MECHANISM_TYPE target, - CK_ATTRIBUTE_TYPE operation, int keySize)) -REMAP_PROTO(void,PK11_FreeSymKey,(PK11SymKey *key)) -REMAP_PROTO(PK11Context *,PK11_CreateContextBySymKey, - (CK_MECHANISM_TYPE type, - CK_ATTRIBUTE_TYPE operation, - PK11SymKey *symKey, SECItem *param)) -REMAP_PROTO(SECStatus,PK11_GenerateRandom,(unsigned char *data, int len)) -REMAP_PROTO(SECItem *,PK11_ParamFromIV,(CK_MECHANISM_TYPE type, SECItem *iv)) -REMAP_PROTO(void,PK11_FreeSlot,(PK11SlotInfo *slot)) -REMAP_PROTO(int,PK11_GetBlockSize,(CK_MECHANISM_TYPE type, SECItem *params)) -REMAP_PROTO(PK11SymKey *,PK11_KeyGen, - (PK11SlotInfo *slot, CK_MECHANISM_TYPE type, - SECItem *param, int keySize, void *wincx)) - -/* - * nspr4 - */ -REMAP_PROTO(PRStatus,PR_Cleanup,(void)) -REMAP_PROTO(const char *,PR_ErrorToString, - (PRErrorCode code, PRLanguageCode language)) -REMAP_PROTO(PRErrorCode,PR_GetError,(void)) -REMAP_PROTO(PRBool,PR_Initialized,(void)) - -/* - * plds4 - */ -REMAP_PROTO(void,PL_ArenaFinish,(void)) diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c index c44760f7..130a9c8f 100644 --- a/libknet/crypto_openssl.c +++ b/libknet/crypto_openssl.c @@ -1,565 +1,522 @@ /* * Copyright (C) 2017 Red Hat, Inc. All rights reserved. * * Author: Fabio M. Di Nitto * * This software licensed under GPL-2.0+, LGPL-2.0+ */ #include "config.h" +#include #include #include -#include -#ifdef BUILDCRYPTOOPENSSL #include #include #include #include #include -#include "common.h" -#include "crypto.h" -#include "crypto_openssl.h" #include "logging.h" +#include "crypto_model.h" /* * 1.0.2 requires at least 120 bytes * 1.1.0 requires at least 256 bytes */ #define SSLERR_BUF_SIZE 512 -/* - * global vars for dlopen - */ -static void *openssl_lib; - -#include "crypto_openssl_remap.h" - -static int opensslcrypto_remap_symbols(knet_handle_t knet_h) -{ -#define REMAP_WITH(name) remap_symbol (knet_h, KNET_SUB_OPENSSLCRYPTO, openssl_lib, name) -#include "crypto_openssl_remap.h" - return 0; - - fail: -#define REMAP_FAIL -#include "crypto_openssl_remap.h" - errno = EINVAL; - return -1; -} - static int openssl_is_init = 0; -int opensslcrypto_load_lib( +static int opensslcrypto_load_lib( knet_handle_t knet_h) { - int err = 0, savederrno = 0; - - if (!openssl_lib) { - openssl_lib = open_lib(knet_h, LIBOPENSSL, 0); - if (!openssl_lib) { - savederrno = errno; - err = -1; - goto out; - } - } - - if (opensslcrypto_remap_symbols(knet_h) < 0) { - savederrno = errno; - err = -1; - goto out; - } - if (!openssl_is_init) { #ifdef BUILDCRYPTOOPENSSL10 - (*_int_ERR_load_crypto_strings)(); - (*_int_OPENSSL_add_all_algorithms_noconf)(); + ERR_load_crypto_strings(); + OPENSSL_add_all_algorithms_noconf(); #endif #ifdef BUILDCRYPTOOPENSSL11 - if (!(*_int_OPENSSL_init_crypto)(OPENSSL_INIT_ADD_ALL_CIPHERS \ - | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)) { + if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \ + | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)) { log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to init openssl"); - err = -1; - savederrno = EAGAIN; - goto out; + errno = EAGAIN; + return -1; } #endif openssl_is_init = 1; } - -out: - errno = savederrno; - return err; + return 0; } /* * crypto definitions and conversion tables */ #define SALT_SIZE 16 struct opensslcrypto_instance { void *private_key; int private_key_len; const EVP_CIPHER *crypto_cipher_type; const EVP_MD *crypto_hash_type; }; /* * crypt/decrypt functions openssl1.0 */ #ifdef BUILDCRYPTOOPENSSL10 static int encrypt_openssl( knet_handle_t knet_h, const struct iovec *iov, int iovcnt, unsigned char *buf_out, ssize_t *buf_out_len) { struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance; EVP_CIPHER_CTX ctx; int tmplen = 0, offset = 0; unsigned char *salt = buf_out; unsigned char *data = buf_out + SALT_SIZE; int err = 0; int i; char sslerr[SSLERR_BUF_SIZE]; - (*_int_EVP_CIPHER_CTX_init)(&ctx); + EVP_CIPHER_CTX_init(&ctx); /* * contribute to PRNG for each packet we send/receive */ - (*_int_RAND_seed)((unsigned char *)iov[iovcnt - 1].iov_base, iov[iovcnt - 1].iov_len); + RAND_seed((unsigned char *)iov[iovcnt - 1].iov_base, iov[iovcnt - 1].iov_len); - if (!(*_int_RAND_bytes)(salt, SALT_SIZE)) { - (*_int_ERR_error_string_n)((*_int_ERR_get_error)(), sslerr, sizeof(sslerr)); + if (!RAND_bytes(salt, SALT_SIZE)) { + ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr)); log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to get random salt data: %s", sslerr); err = -1; goto out; } /* * add warning re keylength */ - (*_int_EVP_EncryptInit_ex)(&ctx, instance->crypto_cipher_type, NULL, instance->private_key, salt); + EVP_EncryptInit_ex(&ctx, instance->crypto_cipher_type, NULL, instance->private_key, salt); for (i=0; icrypto_instance->model_instance; EVP_CIPHER_CTX ctx; int tmplen1 = 0, tmplen2 = 0; unsigned char *salt = (unsigned char *)buf_in; unsigned char *data = salt + SALT_SIZE; int datalen = buf_in_len - SALT_SIZE; int err = 0; char sslerr[SSLERR_BUF_SIZE]; - (*_int_EVP_CIPHER_CTX_init)(&ctx); + EVP_CIPHER_CTX_init(&ctx); /* * contribute to PRNG for each packet we send/receive */ - (*_int_RAND_seed)(buf_in, buf_in_len); + RAND_seed(buf_in, buf_in_len); /* * add warning re keylength */ - (*_int_EVP_DecryptInit_ex)(&ctx, instance->crypto_cipher_type, NULL, instance->private_key, salt); + EVP_DecryptInit_ex(&ctx, instance->crypto_cipher_type, NULL, instance->private_key, salt); - if (!(*_int_EVP_DecryptUpdate)(&ctx, buf_out, &tmplen1, data, datalen)) { - (*_int_ERR_error_string_n)((*_int_ERR_get_error)(), sslerr, sizeof(sslerr)); + if (!EVP_DecryptUpdate(&ctx, buf_out, &tmplen1, data, datalen)) { + ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr)); log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to decrypt: %s", sslerr); err = -1; goto out; } - if (!(*_int_EVP_DecryptFinal_ex)(&ctx, buf_out + tmplen1, &tmplen2)) { - (*_int_ERR_error_string_n)((*_int_ERR_get_error)(), sslerr, sizeof(sslerr)); + if (!EVP_DecryptFinal_ex(&ctx, buf_out + tmplen1, &tmplen2)) { + ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr)); log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to finalize decrypt: %s", sslerr); err = -1; goto out; } *buf_out_len = tmplen1 + tmplen2; out: - (*_int_EVP_CIPHER_CTX_cleanup)(&ctx); + EVP_CIPHER_CTX_cleanup(&ctx); return err; } #endif #ifdef BUILDCRYPTOOPENSSL11 static int encrypt_openssl( knet_handle_t knet_h, const struct iovec *iov, int iovcnt, unsigned char *buf_out, ssize_t *buf_out_len) { struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance; EVP_CIPHER_CTX *ctx; int tmplen = 0, offset = 0; unsigned char *salt = buf_out; unsigned char *data = buf_out + SALT_SIZE; int err = 0; int i; char sslerr[SSLERR_BUF_SIZE]; - ctx = (*_int_EVP_CIPHER_CTX_new)(); + ctx = EVP_CIPHER_CTX_new(); /* * contribute to PRNG for each packet we send/receive */ - (*_int_RAND_seed)((unsigned char *)iov[iovcnt - 1].iov_base, iov[iovcnt - 1].iov_len); + RAND_seed((unsigned char *)iov[iovcnt - 1].iov_base, iov[iovcnt - 1].iov_len); - if (!(*_int_RAND_bytes)(salt, SALT_SIZE)) { - (*_int_ERR_error_string_n)((*_int_ERR_get_error)(), sslerr, sizeof(sslerr)); + if (!RAND_bytes(salt, SALT_SIZE)) { + ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr)); log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to get random salt data: %s", sslerr); err = -1; goto out; } /* * add warning re keylength */ - (*_int_EVP_EncryptInit_ex)(ctx, instance->crypto_cipher_type, NULL, instance->private_key, salt); + EVP_EncryptInit_ex(ctx, instance->crypto_cipher_type, NULL, instance->private_key, salt); for (i=0; icrypto_instance->model_instance; EVP_CIPHER_CTX *ctx; int tmplen1 = 0, tmplen2 = 0; unsigned char *salt = (unsigned char *)buf_in; unsigned char *data = salt + SALT_SIZE; int datalen = buf_in_len - SALT_SIZE; int err = 0; char sslerr[SSLERR_BUF_SIZE]; - ctx = (*_int_EVP_CIPHER_CTX_new)(); + ctx = EVP_CIPHER_CTX_new(); /* * contribute to PRNG for each packet we send/receive */ - (*_int_RAND_seed)(buf_in, buf_in_len); + RAND_seed(buf_in, buf_in_len); /* * add warning re keylength */ - (*_int_EVP_DecryptInit_ex)(ctx, instance->crypto_cipher_type, NULL, instance->private_key, salt); + EVP_DecryptInit_ex(ctx, instance->crypto_cipher_type, NULL, instance->private_key, salt); - if (!(*_int_EVP_DecryptUpdate)(ctx, buf_out, &tmplen1, data, datalen)) { - (*_int_ERR_error_string_n)((*_int_ERR_get_error)(), sslerr, sizeof(sslerr)); + if (!EVP_DecryptUpdate(ctx, buf_out, &tmplen1, data, datalen)) { + ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr)); log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to decrypt: %s", sslerr); err = -1; goto out; } - if (!(*_int_EVP_DecryptFinal_ex)(ctx, buf_out + tmplen1, &tmplen2)) { - (*_int_ERR_error_string_n)((*_int_ERR_get_error)(), sslerr, sizeof(sslerr)); + if (!EVP_DecryptFinal_ex(ctx, buf_out + tmplen1, &tmplen2)) { + ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr)); log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to finalize decrypt: %s", sslerr); err = -1; goto out; } *buf_out_len = tmplen1 + tmplen2; out: - (*_int_EVP_CIPHER_CTX_free)(ctx); + EVP_CIPHER_CTX_free(ctx); return err; } #endif /* * hash/hmac/digest functions */ static int calculate_openssl_hash( knet_handle_t knet_h, const unsigned char *buf, const size_t buf_len, unsigned char *hash) { struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance; unsigned int hash_len = 0; unsigned char *hash_out = NULL; char sslerr[SSLERR_BUF_SIZE]; - hash_out = (*_int_HMAC)(instance->crypto_hash_type, - instance->private_key, instance->private_key_len, - buf, buf_len, - hash, &hash_len); + hash_out = HMAC(instance->crypto_hash_type, + instance->private_key, instance->private_key_len, + buf, buf_len, + hash, &hash_len); if ((!hash_out) || (hash_len != knet_h->sec_hash_size)) { - (*_int_ERR_error_string_n)((*_int_ERR_get_error)(), sslerr, sizeof(sslerr)); + ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr)); log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to calculate hash: %s", sslerr); return -1; } return 0; } /* * exported API */ -int opensslcrypto_encrypt_and_sign ( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len) -{ - struct iovec iov_in; - - memset(&iov_in, 0, sizeof(iov_in)); - iov_in.iov_base = (unsigned char *)buf_in; - iov_in.iov_len = buf_in_len; - - return opensslcrypto_encrypt_and_signv(knet_h, &iov_in, 1, buf_out, buf_out_len); -} - -int opensslcrypto_encrypt_and_signv ( +static int opensslcrypto_encrypt_and_signv ( knet_handle_t knet_h, const struct iovec *iov_in, int iovcnt_in, unsigned char *buf_out, ssize_t *buf_out_len) { struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance; int i; if (instance->crypto_cipher_type) { if (encrypt_openssl(knet_h, iov_in, iovcnt_in, buf_out, buf_out_len) < 0) { return -1; } } else { *buf_out_len = 0; for (i=0; icrypto_hash_type) { if (calculate_openssl_hash(knet_h, buf_out, *buf_out_len, buf_out + *buf_out_len) < 0) { return -1; } *buf_out_len = *buf_out_len + knet_h->sec_hash_size; } return 0; } -int opensslcrypto_authenticate_and_decrypt ( +static int opensslcrypto_encrypt_and_sign ( + knet_handle_t knet_h, + const unsigned char *buf_in, + const ssize_t buf_in_len, + unsigned char *buf_out, + ssize_t *buf_out_len) +{ + struct iovec iov_in; + + memset(&iov_in, 0, sizeof(iov_in)); + iov_in.iov_base = (unsigned char *)buf_in; + iov_in.iov_len = buf_in_len; + + return opensslcrypto_encrypt_and_signv(knet_h, &iov_in, 1, buf_out, buf_out_len); +} + +static int opensslcrypto_authenticate_and_decrypt ( knet_handle_t knet_h, const unsigned char *buf_in, const ssize_t buf_in_len, unsigned char *buf_out, ssize_t *buf_out_len) { struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance; ssize_t temp_len = buf_in_len; if (instance->crypto_hash_type) { unsigned char tmp_hash[knet_h->sec_hash_size]; ssize_t temp_buf_len = buf_in_len - knet_h->sec_hash_size; if ((temp_buf_len < 0) || (temp_buf_len > KNET_MAX_PACKET_SIZE)) { log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Incorrect packet size."); return -1; } if (calculate_openssl_hash(knet_h, buf_in, temp_buf_len, tmp_hash) < 0) { return -1; } if (memcmp(tmp_hash, buf_in + temp_buf_len, knet_h->sec_hash_size) != 0) { log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Digest does not match"); return -1; } temp_len = temp_len - knet_h->sec_hash_size; *buf_out_len = temp_len; } if (instance->crypto_cipher_type) { if (decrypt_openssl(knet_h, buf_in, temp_len, buf_out, buf_out_len) < 0) { return -1; } } else { memmove(buf_out, buf_in, temp_len); *buf_out_len = temp_len; } return 0; } -int opensslcrypto_init( +static void opensslcrypto_fini( + knet_handle_t knet_h) +{ + struct opensslcrypto_instance *opensslcrypto_instance = knet_h->crypto_instance->model_instance; + + if (opensslcrypto_instance) { + if (opensslcrypto_instance->private_key) { + free(opensslcrypto_instance->private_key); + opensslcrypto_instance->private_key = NULL; + } + free(opensslcrypto_instance); + knet_h->crypto_instance->model_instance = NULL; + knet_h->sec_header_size = 0; + } + + return; +} + +static int opensslcrypto_init( knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg) { struct opensslcrypto_instance *opensslcrypto_instance = NULL; log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO, "Initizializing openssl crypto module [%s/%s]", knet_handle_crypto_cfg->crypto_cipher_type, knet_handle_crypto_cfg->crypto_hash_type); knet_h->crypto_instance->model_instance = malloc(sizeof(struct opensslcrypto_instance)); if (!knet_h->crypto_instance->model_instance) { log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to allocate memory for openssl model instance"); return -1; } opensslcrypto_instance = knet_h->crypto_instance->model_instance; memset(opensslcrypto_instance, 0, sizeof(struct opensslcrypto_instance)); if (strcmp(knet_handle_crypto_cfg->crypto_cipher_type, "none") == 0) { opensslcrypto_instance->crypto_cipher_type = NULL; } else { - opensslcrypto_instance->crypto_cipher_type = (*_int_EVP_get_cipherbyname)(knet_handle_crypto_cfg->crypto_cipher_type); + opensslcrypto_instance->crypto_cipher_type = EVP_get_cipherbyname(knet_handle_crypto_cfg->crypto_cipher_type); if (!opensslcrypto_instance->crypto_cipher_type) { log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "unknown crypto cipher type requested"); goto out_err; } } if (strcmp(knet_handle_crypto_cfg->crypto_hash_type, "none") == 0) { opensslcrypto_instance->crypto_hash_type = NULL; } else { - opensslcrypto_instance->crypto_hash_type = (*_int_EVP_get_digestbyname)(knet_handle_crypto_cfg->crypto_hash_type); + opensslcrypto_instance->crypto_hash_type = EVP_get_digestbyname(knet_handle_crypto_cfg->crypto_hash_type); if (!opensslcrypto_instance->crypto_hash_type) { log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "unknown crypto hash type requested"); goto out_err; } } if ((opensslcrypto_instance->crypto_cipher_type) && (!opensslcrypto_instance->crypto_hash_type)) { log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "crypto communication requires hash specified"); goto out_err; } opensslcrypto_instance->private_key = malloc(knet_handle_crypto_cfg->private_key_len); if (!opensslcrypto_instance->private_key) { log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to allocate memory for openssl private key"); goto out_err; } memmove(opensslcrypto_instance->private_key, knet_handle_crypto_cfg->private_key, knet_handle_crypto_cfg->private_key_len); opensslcrypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len; knet_h->sec_header_size = 0; if (opensslcrypto_instance->crypto_hash_type) { - knet_h->sec_hash_size = (*_int_EVP_MD_size)(opensslcrypto_instance->crypto_hash_type); + knet_h->sec_hash_size = EVP_MD_size(opensslcrypto_instance->crypto_hash_type); knet_h->sec_header_size += knet_h->sec_hash_size; } if (opensslcrypto_instance->crypto_cipher_type) { int block_size; - block_size = (*_int_EVP_CIPHER_block_size)(opensslcrypto_instance->crypto_cipher_type); + block_size = EVP_CIPHER_block_size(opensslcrypto_instance->crypto_cipher_type); if (block_size < 0) { goto out_err; } knet_h->sec_header_size += (block_size * 2); knet_h->sec_header_size += SALT_SIZE; knet_h->sec_salt_size = SALT_SIZE; knet_h->sec_block_size = block_size; } return 0; out_err: opensslcrypto_fini(knet_h); return -1; } -void opensslcrypto_fini( - knet_handle_t knet_h) -{ - struct opensslcrypto_instance *opensslcrypto_instance = knet_h->crypto_instance->model_instance; - - if (opensslcrypto_instance) { - if (opensslcrypto_instance->private_key) { - free(opensslcrypto_instance->private_key); - opensslcrypto_instance->private_key = NULL; - } - free(opensslcrypto_instance); - knet_h->crypto_instance->model_instance = NULL; - knet_h->sec_header_size = 0; - } - - return; -} -#endif +crypto_model_t crypto_model = { "", 0, opensslcrypto_load_lib, 0, opensslcrypto_init, opensslcrypto_fini, opensslcrypto_encrypt_and_sign, opensslcrypto_encrypt_and_signv, opensslcrypto_authenticate_and_decrypt }; diff --git a/libknet/crypto_openssl.h b/libknet/crypto_openssl.h deleted file mode 100644 index cdb2fd44..00000000 --- a/libknet/crypto_openssl.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2012-2017 Red Hat, Inc. All rights reserved. - * - * Author: Fabio M. Di Nitto - * - * This software licensed under GPL-2.0+, LGPL-2.0+ - */ - -#ifndef __KNET_OPENSSLCRYPTO_H__ -#define __KNET_OPENSSLCRYPTO_H__ - -#include "internals.h" - -struct opensslcrypto_instance; - -int opensslcrypto_load_lib( - knet_handle_t knet_h); - -int opensslcrypto_init( - knet_handle_t knet_h, - struct knet_handle_crypto_cfg *knet_handle_crypto_cfg); - -void opensslcrypto_fini( - knet_handle_t knet_h); - -int opensslcrypto_authenticate_and_decrypt ( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int opensslcrypto_encrypt_and_sign ( - knet_handle_t knet_h, - const unsigned char *buf_in, - const ssize_t buf_in_len, - unsigned char *buf_out, - ssize_t *buf_out_len); - -int opensslcrypto_encrypt_and_signv ( - knet_handle_t knet_h, - const struct iovec *iov_in, - int iovcnt_in, - unsigned char *buf_out, - ssize_t *buf_out_len); - -#endif diff --git a/libknet/crypto_openssl_remap.h b/libknet/crypto_openssl_remap.h deleted file mode 100644 index 6d2d609e..00000000 --- a/libknet/crypto_openssl_remap.h +++ /dev/null @@ -1,58 +0,0 @@ -#include "remap.h" - -#ifdef BUILDCRYPTOOPENSSL10 -REMAP_PROTO(void,OPENSSL_add_all_algorithms_noconf,(void)) -#endif -#ifdef BUILDCRYPTOOPENSSL11 -REMAP_PROTO(int,OPENSSL_init_crypto, - (uint64_t opts, const OPENSSL_INIT_SETTINGS *settings)) -#endif - -#ifdef BUILDCRYPTOOPENSSL10 -REMAP_PROTO(void,ERR_load_crypto_strings,(void)) -#endif -REMAP_PROTO(unsigned long,ERR_get_error,(void)) -REMAP_PROTO(void,ERR_error_string_n, - (unsigned long e, char *buf, size_t len)) - -REMAP_PROTO(void,RAND_seed,(const void *buf, int num)) -REMAP_PROTO(int,RAND_bytes,(unsigned char *buf, int num)) - -REMAP_PROTO(const EVP_MD *,EVP_get_digestbyname,(const char *name)) -REMAP_PROTO(int,EVP_MD_size,(const EVP_MD *md)) -REMAP_PROTO(unsigned char *,HMAC, - (const EVP_MD *evp_md, const void *key, int key_len, - const unsigned char *d, size_t n, unsigned char *md, - unsigned int *md_len)) - -REMAP_PROTO(const EVP_CIPHER *,EVP_get_cipherbyname,(const char *name)) -REMAP_PROTO(int,EVP_CIPHER_block_size,(const EVP_CIPHER *cipher)) - -#ifdef BUILDCRYPTOOPENSSL10 -REMAP_PROTO(void,EVP_CIPHER_CTX_init,(EVP_CIPHER_CTX *a)) -REMAP_PROTO(int,EVP_CIPHER_CTX_cleanup,(EVP_CIPHER_CTX *a)) -#endif -#ifdef BUILDCRYPTOOPENSSL11 -REMAP_PROTO(EVP_CIPHER_CTX *,EVP_CIPHER_CTX_new,(void)) -REMAP_PROTO(void,EVP_CIPHER_CTX_free,(EVP_CIPHER_CTX *c)) -#endif - -REMAP_PROTO(int,EVP_EncryptInit_ex, - (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - ENGINE *impl, const unsigned char *key, - const unsigned char *iv)) -REMAP_PROTO(int,EVP_EncryptUpdate, - (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl)) -REMAP_PROTO(int,EVP_EncryptFinal_ex, - (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)) - -REMAP_PROTO(int,EVP_DecryptInit_ex, - (EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, - ENGINE *impl, const unsigned char *key, - const unsigned char *iv)) -REMAP_PROTO(int,EVP_DecryptUpdate, - (EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, - const unsigned char *in, int inl)) -REMAP_PROTO(int,EVP_DecryptFinal_ex, - (EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl)) diff --git a/libknet/remap.h b/libknet/remap.h deleted file mode 100644 index 87c1e679..00000000 --- a/libknet/remap.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Repeated inclusions define this differently */ -#undef REMAP_PROTO - -#ifdef CANARY - -/* Canary uses fake prototype to make "calls" uniform */ -#ifdef CANARY_CALL -#define REMAP_PROTO(ret,name,args) name() + -#else -#define REMAP_PROTO(ret,name,args) char name(void); -#endif /* CANARY_CALL */ - -#else - -#ifdef REMAP_FAIL -#define REMAP_PROTO(ret,name,args) _int_ ## name = NULL; -#else -#ifdef REMAP_WITH -#define REMAP_PROTO(ret,name,args) if (!(_int_ ## name = REMAP_WITH(#name))) goto fail; -#else -/* Provide the plain prototype as well for validation */ -#define REMAP_PROTO(ret,name,args) ret (*_int_ ## name)args; \ - ret name args; -#endif /* REMAP_WITH */ -#endif /* REMAP_FAIL */ - -#endif /* CANARY */ diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am index 85fed2cf..8c5fab51 100644 --- a/libknet/tests/Makefile.am +++ b/libknet/tests/Makefile.am @@ -1,91 +1,87 @@ # # Copyright (C) 2016-2017 Red Hat, Inc. All rights reserved. # # Authors: Fabio M. Di Nitto # # This software licensed under GPL-2.0+, LGPL-2.0+ # MAINTAINERCLEANFILES = Makefile.in include $(top_srcdir)/build-aux/check.mk include $(top_srcdir)/libknet/tests/api-check.mk EXTRA_DIST = \ api-test-coverage \ api-check.mk AM_CPPFLAGS = -I$(top_srcdir)/libknet AM_CFLAGS = $(PTHREAD_CFLAGS) LIBS = $(top_builddir)/libknet/libknet.la \ $(PTHREAD_LIBS) $(dl_LIBS) noinst_HEADERS = \ test-common.h # the order of those tests is NOT random. # some functions can only be tested properly after some dependents # API have been validated upfront. check_PROGRAMS = \ $(api_checks) \ $(int_checks) \ $(fun_checks) int_checks = \ int_crypto_test \ int_timediff_test fun_checks = benchmarks = \ crypto_bench_test \ knet_bench_test noinst_PROGRAMS = \ api_knet_handle_new_limit_test \ pckt_test \ $(benchmarks) \ $(check_PROGRAMS) noinst_SCRIPTS = \ api-test-coverage TESTS = $(check_PROGRAMS) check-local: check-api-test-coverage check-api-test-coverage: chmod u+x $(top_srcdir)/libknet/tests/api-test-coverage $(top_srcdir)/libknet/tests/api-test-coverage $(top_srcdir) $(top_builddir) pckt_test_SOURCES = pckt_test.c int_crypto_test_SOURCES = int_crypto.c \ ../common.c \ ../crypto.c \ - ../crypto_nss.c \ - ../crypto_openssl.c \ ../logging.c \ test-common.c int_crypto_test_CFLAGS = $(nss_CFLAGS) $(openssl_CFLAGS) int_timediff_test_SOURCES = int_timediff.c crypto_bench_test_SOURCES = crypto_bench.c \ ../common.c \ ../crypto.c \ - ../crypto_nss.c \ - ../crypto_openssl.c \ ../logging.c \ test-common.c crypto_bench_test_CFLAGS = $(nss_CFLAGS) $(openssl_CFLAGS) knet_bench_test_SOURCES = knet_bench.c \ test-common.c \ ../common.c \ ../logging.c \ ../compat.c \ ../transport_common.c