diff --git a/configure.ac b/configure.ac index d9b16392..13541bbc 100644 --- a/configure.ac +++ b/configure.ac @@ -1,1629 +1,1622 @@ # Configure.ac script for Libgcrypt # Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006, # 2007, 2008, 2009, 2011 Free Software Foundation, Inc. # Copyright (C) 2012, 2013 g10 Code GmbH # # This file is part of Libgcrypt. # # Libgcrypt is free software; you can redistribute it and/or modify # it under the terms of the GNU Lesser General Public License as # published by the Free Software Foundation; either version 2.1 of # the License, or (at your option) any later version. # # Libgcrypt is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with this program; if not, see . # (Process this file with autoconf to produce a configure script.) AC_REVISION($Revision$) AC_PREREQ(2.60) min_automake_version="1.10" # To build a release you need to create a tag with the version number # (git tag -s libgcrypt-n.m.k) and run "./autogen.sh --force". Please # bump the version number immediately after the release and do another # commit and push so that the git magic is able to work. See below # for the LT versions. m4_define(mym4_version_major, [1]) m4_define(mym4_version_minor, [6]) m4_define(mym4_version_micro, [0]) # Below is m4 magic to extract and compute the revision number, the # decimalized short revision number, a beta version string, and a flag # indicating a development version (mym4_isgit). Note that the m4 # processing is done by autoconf and not during the configure run. m4_define(mym4_version, [mym4_version_major.mym4_version_minor.mym4_version_micro]) m4_define([mym4_revision], m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r'])) m4_define([mym4_revision_dec], m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))])) m4_define([mym4_betastring], m4_esyscmd_s([git describe --match 'libgcrypt-[0-9].*[0-9]' --long|\ awk -F- '$3!=0{print"-beta"$3}'])) m4_define([mym4_isgit],m4_if(mym4_betastring,[],[no],[yes])) m4_define([mym4_full_version],[mym4_version[]mym4_betastring]) AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org]) # LT Version numbers, remember to change them just *before* a release. # (Interfaces removed: CURRENT++, AGE=0, REVISION=0) # (Interfaces added: CURRENT++, AGE++, REVISION=0) # (No interfaces changed: REVISION++) # CAUTION: Due to the ABI change in 1.6 the LT version numbers below have # already been set for the next release. Thus don't update them for # the 1.6.0 release. LIBGCRYPT_LT_CURRENT=20 LIBGCRYPT_LT_AGE=0 LIBGCRYPT_LT_REVISION=0 # If the API is changed in an incompatible way: increment the next counter. LIBGCRYPT_CONFIG_API_VERSION=1 +# If you change the required gpg-error version, please remove +# unnecessary error code defines in src/gcrypt-int.h. NEED_GPG_ERROR_VERSION=1.11 PACKAGE=$PACKAGE_NAME VERSION=$PACKAGE_VERSION AC_CONFIG_SRCDIR([src/libgcrypt.vers]) AM_INIT_AUTOMAKE AC_CONFIG_HEADER(config.h) AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_LIBOBJ_DIR([compat]) AC_CANONICAL_HOST AM_MAINTAINER_MODE AH_TOP([ #ifndef _GCRYPT_CONFIG_H_INCLUDED #define _GCRYPT_CONFIG_H_INCLUDED /* Enable gpg-error's strerror macro for W32CE. */ #define GPG_ERR_ENABLE_ERRNO_MACROS 1 ]) AH_BOTTOM([ #define _GCRYPT_IN_LIBGCRYPT 1 /* If the configure check for endianness has been disabled, get it from OS macros. This is intended for making fat binary builds on OS X. */ #ifdef DISABLED_ENDIAN_CHECK # if defined(__BIG_ENDIAN__) # define WORDS_BIGENDIAN 1 # elif defined(__LITTLE_ENDIAN__) # undef WORDS_BIGENDIAN # else # error "No endianness found" # endif #endif /*DISABLED_ENDIAN_CHECK*/ /* We basically use the original Camellia source. Make sure the symbols properly prefixed. */ #define CAMELLIA_EXT_SYM_PREFIX _gcry_ -/* These error codes are used but not defined in the required - libgpg-error 1.11. Define them here. */ -#define GPG_ERR_NO_CRYPT_CTX 191 -#define GPG_ERR_WRONG_CRYPT_CTX 192 -#define GPG_ERR_BAD_CRYPT_CTX 193 -#define GPG_ERR_CRYPT_CTX_CONFLICT 194 -#define GPG_ERR_BROKEN_PUBKEY 195 -#define GPG_ERR_BROKEN_SECKEY 196 - #endif /*_GCRYPT_CONFIG_H_INCLUDED*/ ]) AH_VERBATIM([_REENTRANT], [/* To allow the use of Libgcrypt in multithreaded programs we have to use special features from the library. */ #ifndef _REENTRANT # define _REENTRANT 1 #endif ]) AC_SUBST(LIBGCRYPT_LT_CURRENT) AC_SUBST(LIBGCRYPT_LT_AGE) AC_SUBST(LIBGCRYPT_LT_REVISION) AC_SUBST(PACKAGE) AC_SUBST(VERSION) AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package]) VERSION_NUMBER=m4_esyscmd(printf "0x%02x%02x%02x" mym4_version_major \ mym4_version_minor mym4_version_micro) AC_SUBST(VERSION_NUMBER) ###################### ## Basic checks. ### (we need some results later on (e.g. $GCC) ###################### AC_PROG_MAKE_SET missing_dir=`cd $ac_aux_dir && pwd` AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) # AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) AC_PROG_CC AC_PROG_CPP AM_PROG_CC_C_O AM_PROG_AS AC_ISC_POSIX AC_PROG_INSTALL AC_PROG_AWK AC_GNU_SOURCE # We need to compile and run a program on the build machine. A # comment in libgpg-error says that the AC_PROG_CC_FOR_BUILD macro in # the AC archive is broken for autoconf 2.57. Given that there is no # newer version of that macro, we assume that it is also broken for # autoconf 2.61 and thus we use a simple but usually sufficient # approach. AC_MSG_CHECKING(for cc for build) if test "$cross_compiling" = "yes"; then CC_FOR_BUILD="${CC_FOR_BUILD-cc}" else CC_FOR_BUILD="${CC_FOR_BUILD-$CC}" fi AC_MSG_RESULT($CC_FOR_BUILD) AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler]) LT_PREREQ([2.2.6]) LT_INIT([win32-dll disable-static]) LT_LANG([Windows Resource]) ########################## ## General definitions. ## ########################## # Used by libgcrypt-config LIBGCRYPT_CONFIG_LIBS="-lgcrypt" LIBGCRYPT_CONFIG_CFLAGS="" LIBGCRYPT_CONFIG_HOST="$host" # Definitions for symmetric ciphers. available_ciphers="arcfour blowfish cast5 des aes twofish serpent rfc2268 seed" available_ciphers="$available_ciphers camellia idea" enabled_ciphers="" # Definitions for public-key ciphers. available_pubkey_ciphers="dsa elgamal rsa ecc" enabled_pubkey_ciphers="" # Definitions for message digests. available_digests="crc md4 md5 rmd160 sha1 sha256" available_digests_64="sha512 tiger whirlpool" enabled_digests="" # Definitions for kdfs (optional ones) available_kdfs="s2k pkdf2" available_kdfs_64="scrypt" enabled_kdfs="" # Definitions for random modules. available_random_modules="linux egd unix" auto_random_modules="$available_random_modules" # Supported thread backends. LIBGCRYPT_THREAD_MODULES="" # Other definitions. print_egd_notice=no have_w32_system=no have_w32ce_system=no have_pthread=no # Setup some stuff depending on host. case "${host}" in *-*-mingw32*) ac_cv_have_dev_random=no have_w32_system=yes case "${host}" in *-mingw32ce*) have_w32ce_system=yes available_random_modules="w32ce" ;; *) available_random_modules="w32" ;; esac AC_DEFINE(USE_ONLY_8DOT3,1, [set this to limit filenames to the 8.3 format]) AC_DEFINE(HAVE_DRIVE_LETTERS,1, [defined if we must run on a stupid file system]) AC_DEFINE(HAVE_DOSISH_SYSTEM,1, [defined if we run on some of the PCDOS like systems (DOS, Windoze. OS/2) with special properties like no file modes]) ;; i?86-emx-os2 | i?86-*-os2*emx) # OS/2 with the EMX environment ac_cv_have_dev_random=no AC_DEFINE(HAVE_DRIVE_LETTERS) AC_DEFINE(HAVE_DOSISH_SYSTEM) ;; i?86-*-msdosdjgpp*) # DOS with the DJGPP environment ac_cv_have_dev_random=no AC_DEFINE(HAVE_DRIVE_LETTERS) AC_DEFINE(HAVE_DOSISH_SYSTEM) ;; *-*-hpux*) if test -z "$GCC" ; then CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE" fi ;; *-dec-osf4*) if test -z "$GCC" ; then # Suppress all warnings # to get rid of the unsigned/signed char mismatch warnings. CFLAGS="$CFLAGS -w" fi ;; m68k-atari-mint) ;; *) ;; esac if test "$have_w32_system" = yes; then AC_DEFINE(HAVE_W32_SYSTEM,1, [Defined if we run on a W32 API based system]) if test "$have_w32ce_system" = yes; then AC_DEFINE(HAVE_W32CE_SYSTEM,1,[Defined if we run on WindowsCE]) fi fi AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) AM_CONDITIONAL(HAVE_W32CE_SYSTEM, test "$have_w32ce_system" = yes) # A printable OS Name is sometimes useful. case "${host}" in *-*-mingw32ce*) PRINTABLE_OS_NAME="W32CE" ;; *-*-mingw32*) PRINTABLE_OS_NAME="W32" ;; i?86-emx-os2 | i?86-*-os2*emx ) PRINTABLE_OS_NAME="OS/2" ;; i?86-*-msdosdjgpp*) PRINTABLE_OS_NAME="MSDOS/DJGPP" ;; *-linux*) PRINTABLE_OS_NAME="GNU/Linux" ;; *) PRINTABLE_OS_NAME=`uname -s || echo "Unknown"` ;; esac # # Figure out the name of the random device # case "${host}" in *-openbsd*) NAME_OF_DEV_RANDOM="/dev/srandom" NAME_OF_DEV_URANDOM="/dev/urandom" ;; *) NAME_OF_DEV_RANDOM="/dev/random" NAME_OF_DEV_URANDOM="/dev/urandom" ;; esac AC_ARG_ENABLE(endian-check, AC_HELP_STRING([--disable-endian-check], [disable the endian check and trust the OS provided macros]), endiancheck=$enableval,endiancheck=yes) if test x"$endiancheck" = xyes ; then AC_C_BIGENDIAN else AC_DEFINE(DISABLED_ENDIAN_CHECK,1,[configure did not test for endianess]) fi AC_CHECK_SIZEOF(unsigned short, 2) AC_CHECK_SIZEOF(unsigned int, 4) AC_CHECK_SIZEOF(unsigned long, 4) AC_CHECK_SIZEOF(unsigned long long, 0) AC_TYPE_UINTPTR_T if test "$ac_cv_sizeof_unsigned_short" = "0" \ || test "$ac_cv_sizeof_unsigned_int" = "0" \ || test "$ac_cv_sizeof_unsigned_long" = "0"; then AC_MSG_WARN([Hmmm, something is wrong with the sizes - using defaults]); fi # Do we have any 64-bit data types? if test "$ac_cv_sizeof_unsigned_int" != "8" \ && test "$ac_cv_sizeof_unsigned_long" != "8" \ && test "$ac_cv_sizeof_unsigned_long_long" != "8" \ && test "$ac_cv_sizeof_uint64_t" != "8"; then AC_MSG_WARN([No 64-bit types. Disabling TIGER/192, SCRYPT, SHA-384, \ and SHA-512]) else available_digests="$available_digests $available_digests_64" available_kdfs="$available_kdfs $available_kdfs_64" fi # If not specified otherwise, all available algorithms will be # included. default_ciphers="$available_ciphers" default_pubkey_ciphers="$available_pubkey_ciphers" default_digests="$available_digests" default_kdfs="$available_kdfs" # Substitutions to set generated files in a Emacs buffer to read-only. AC_SUBST(emacs_local_vars_begin, ['Local Variables:']) AC_SUBST(emacs_local_vars_read_only, ['buffer-read-only: t']) AC_SUBST(emacs_local_vars_end, ['End:']) ############################ ## Command line switches. ## ############################ # Implementation of the --enable-ciphers switch. AC_ARG_ENABLE(ciphers, AC_HELP_STRING([--enable-ciphers=ciphers], [select the symmetric ciphers to include]), [enabled_ciphers=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`], [enabled_ciphers=""]) if test "x$enabled_ciphers" = "x" \ -o "$enabled_ciphers" = "yes" \ -o "$enabled_ciphers" = "no"; then enabled_ciphers=$default_ciphers fi AC_MSG_CHECKING([which symmetric ciphers to include]) for cipher in $enabled_ciphers; do LIST_MEMBER($cipher, $available_ciphers) if test "$found" = "0"; then AC_MSG_ERROR([unsupported cipher "$cipher" specified]) fi done AC_MSG_RESULT([$enabled_ciphers]) # Implementation of the --enable-pubkey-ciphers switch. AC_ARG_ENABLE(pubkey-ciphers, AC_HELP_STRING([--enable-pubkey-ciphers=ciphers], [select the public-key ciphers to include]), [enabled_pubkey_ciphers=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`], [enabled_pubkey_ciphers=""]) if test "x$enabled_pubkey_ciphers" = "x" \ -o "$enabled_pubkey_ciphers" = "yes" \ -o "$enabled_pubkey_ciphers" = "no"; then enabled_pubkey_ciphers=$default_pubkey_ciphers fi AC_MSG_CHECKING([which public-key ciphers to include]) for cipher in $enabled_pubkey_ciphers; do LIST_MEMBER($cipher, $available_pubkey_ciphers) if test "$found" = "0"; then AC_MSG_ERROR([unsupported public-key cipher specified]) fi done AC_MSG_RESULT([$enabled_pubkey_ciphers]) # Implementation of the --enable-digests switch. AC_ARG_ENABLE(digests, AC_HELP_STRING([--enable-digests=digests], [select the message digests to include]), [enabled_digests=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`], [enabled_digests=""]) if test "x$enabled_digests" = "x" \ -o "$enabled_digests" = "yes" \ -o "$enabled_digests" = "no"; then enabled_digests=$default_digests fi AC_MSG_CHECKING([which message digests to include]) for digest in $enabled_digests; do LIST_MEMBER($digest, $available_digests) if test "$found" = "0"; then AC_MSG_ERROR([unsupported message digest specified]) fi done AC_MSG_RESULT([$enabled_digests]) # Implementation of the --enable-kdfs switch. AC_ARG_ENABLE(kdfs, AC_HELP_STRING([--enable-kfds=kdfs], [select the KDFs to include]), [enabled_kdfs=`echo $enableval | tr ',:' ' ' | tr '[A-Z]' '[a-z]'`], [enabled_kdfs=""]) if test "x$enabled_kdfs" = "x" \ -o "$enabled_kdfs" = "yes" \ -o "$enabled_kdfs" = "no"; then enabled_kdfs=$default_kdfs fi AC_MSG_CHECKING([which key derivation functions to include]) for kdf in $enabled_kdfs; do LIST_MEMBER($kdf, $available_kdfs) if test "$found" = "0"; then AC_MSG_ERROR([unsupported key derivation function specified]) fi done AC_MSG_RESULT([$enabled_kdfs]) # Implementation of the --enable-random switch. AC_ARG_ENABLE(random, AC_HELP_STRING([--enable-random=name], [select which random number generator to use]), [random=`echo $enableval | tr '[A-Z]' '[a-z]'`], []) if test "x$random" = "x" -o "$random" = "yes" -o "$random" = "no"; then random=default fi AC_MSG_CHECKING([which random module to use]) if test "$random" != "default" -a "$random" != "auto"; then LIST_MEMBER($random, $available_random_modules) if test "$found" = "0"; then AC_MSG_ERROR([unsupported random module specified]) fi fi AC_MSG_RESULT($random) # Implementation of the --disable-dev-random switch. AC_MSG_CHECKING([whether use of /dev/random is requested]) AC_ARG_ENABLE(dev-random, [ --disable-dev-random disable the use of dev random], try_dev_random=$enableval, try_dev_random=yes) AC_MSG_RESULT($try_dev_random) # Implementation of the --with-egd-socket switch. AC_ARG_WITH(egd-socket, [ --with-egd-socket=NAME Use NAME for the EGD socket)], egd_socket_name="$withval", egd_socket_name="" ) AC_DEFINE_UNQUOTED(EGD_SOCKET_NAME, "$egd_socket_name", [Define if you don't want the default EGD socket name. For details see cipher/rndegd.c]) # Implementation of the --enable-random-daemon AC_MSG_CHECKING([whether the experimental random daemon is requested]) AC_ARG_ENABLE([random-daemon], AC_HELP_STRING([--enable-random-daemon], [Build and support the experimental gcryptrnd]), [use_random_daemon=$enableval], [use_random_daemon=no]) AC_MSG_RESULT($use_random_daemon) if test x$use_random_daemon = xyes ; then AC_DEFINE(USE_RANDOM_DAEMON,1, [Define to support the experimental random daemon]) fi AM_CONDITIONAL(USE_RANDOM_DAEMON, test x$use_random_daemon = xyes) # Implementation of --disable-asm. AC_MSG_CHECKING([whether MPI assembler modules are requested]) AC_ARG_ENABLE([asm], AC_HELP_STRING([--disable-asm], [Disable MPI assembler modules]), [try_asm_modules=$enableval], [try_asm_modules=yes]) AC_MSG_RESULT($try_asm_modules) # Implementation of the --enable-m-guard switch. AC_MSG_CHECKING([whether memory guard is requested]) AC_ARG_ENABLE(m-guard, AC_HELP_STRING([--enable-m-guard], [Enable memory guard facility]), [use_m_guard=$enableval], [use_m_guard=no]) AC_MSG_RESULT($use_m_guard) if test "$use_m_guard" = yes ; then AC_DEFINE(M_GUARD,1,[Define to use the (obsolete) malloc guarding feature]) fi # Implementation of the --with-capabilities switch. # Check whether we want to use Linux capabilities AC_MSG_CHECKING([whether use of capabilities is requested]) AC_ARG_WITH(capabilities, AC_HELP_STRING([--with-capabilities], [Use linux capabilities [default=no]]), [use_capabilities="$withval"],[use_capabilities=no]) AC_MSG_RESULT($use_capabilities) # Implementation of the --enable-hmac-binary-check. AC_MSG_CHECKING([whether a HMAC binary check is requested]) AC_ARG_ENABLE(hmac-binary-check, AC_HELP_STRING([--enable-hmac-binary-check], [Enable library integrity check]), [use_hmac_binary_check=$enableval], [use_hmac_binary_check=no]) AC_MSG_RESULT($use_hmac_binary_check) if test "$use_hmac_binary_check" = yes ; then AC_DEFINE(ENABLE_HMAC_BINARY_CHECK,1, [Define to support an HMAC based integrity check]) fi # Implementation of the --disable-padlock-support switch. AC_MSG_CHECKING([whether padlock support is requested]) AC_ARG_ENABLE(padlock-support, AC_HELP_STRING([--disable-padlock-support], [Disable support for the PadLock Engine of VIA processors]), padlocksupport=$enableval,padlocksupport=yes) AC_MSG_RESULT($padlocksupport) if test x"$padlocksupport" = xyes ; then AC_DEFINE(ENABLE_PADLOCK_SUPPORT, 1, [Enable support for the PadLock engine.]) fi # Implementation of the --disable-aesni-support switch. AC_MSG_CHECKING([whether AESNI support is requested]) AC_ARG_ENABLE(aesni-support, AC_HELP_STRING([--disable-aesni-support], [Disable support for the Intel AES-NI instructions]), aesnisupport=$enableval,aesnisupport=yes) AC_MSG_RESULT($aesnisupport) # Implementation of the --disable-drng-support switch. AC_MSG_CHECKING([whether DRNG support is requested]) AC_ARG_ENABLE(drng-support, AC_HELP_STRING([--disable-drng-support], [Disable support for the Intel DRNG (RDRAND instruction)]), drngsupport=$enableval,drngsupport=yes) AC_MSG_RESULT($drngsupport) if test x"$drngsupport" = xyes ; then AC_DEFINE(ENABLE_DRNG_SUPPORT, 1, [Enable support for Intel DRNG (RDRAND instruction).]) fi # Implementation of the --disable-avx-support switch. AC_MSG_CHECKING([whether AVX support is requested]) AC_ARG_ENABLE(avx-support, AC_HELP_STRING([--disable-avx-support], [Disable support for the Intel AVX instructions]), avxsupport=$enableval,avxsupport=yes) AC_MSG_RESULT($avxsupport) # Implementation of the --disable-avx2-support switch. AC_MSG_CHECKING([whether AVX2 support is requested]) AC_ARG_ENABLE(avx2-support, AC_HELP_STRING([--disable-avx2-support], [Disable support for the Intel AVX2 instructions]), avx2support=$enableval,avx2support=yes) AC_MSG_RESULT($avx2support) # Implementation of the --disable-O-flag-munging switch. AC_MSG_CHECKING([whether a -O flag munging is requested]) AC_ARG_ENABLE([O-flag-munging], AC_HELP_STRING([--disable-O-flag-munging], [Disable modification of the cc -O flag]), [enable_o_flag_munging=$enableval], [enable_o_flag_munging=yes]) AC_MSG_RESULT($enable_o_flag_munging) AM_CONDITIONAL(ENABLE_O_FLAG_MUNGING, test "$enable_o_flag_munging" = "yes") AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME", [A human readable text with the name of the OS]) # For some systems we know that we have ld_version scripts. # Use it then as default. have_ld_version_script=no case "${host}" in *-*-linux*) have_ld_version_script=yes ;; *-*-gnu*) have_ld_version_script=yes ;; esac AC_ARG_ENABLE([ld-version-script], AC_HELP_STRING([--enable-ld-version-script], [enable/disable use of linker version script. (default is system dependent)]), [have_ld_version_script=$enableval], [ : ] ) AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes") AC_DEFINE_UNQUOTED(NAME_OF_DEV_RANDOM, "$NAME_OF_DEV_RANDOM", [defined to the name of the strong random device]) AC_DEFINE_UNQUOTED(NAME_OF_DEV_URANDOM, "$NAME_OF_DEV_URANDOM", [defined to the name of the weaker random device]) ############################### #### Checks for libraries. #### ############################### # # gpg-error is required. # AM_PATH_GPG_ERROR("$NEED_GPG_ERROR_VERSION") if test "x$GPG_ERROR_LIBS" = "x"; then AC_MSG_ERROR([libgpg-error is needed. See ftp://ftp.gnupg.org/gcrypt/libgpg-error/ .]) fi AC_DEFINE(GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_GCRYPT, [The default error source for libgcrypt.]) # # Check whether the GNU Pth library is available. We require this # to build the optional gcryptrnd program. # AC_ARG_WITH(pth-prefix, AC_HELP_STRING([--with-pth-prefix=PFX], [prefix where GNU Pth is installed (optional)]), pth_config_prefix="$withval", pth_config_prefix="") if test x$pth_config_prefix != x ; then PTH_CONFIG="$pth_config_prefix/bin/pth-config" fi if test "$use_random_daemon" = "yes"; then AC_PATH_PROG(PTH_CONFIG, pth-config, no) if test "$PTH_CONFIG" = "no"; then AC_MSG_WARN([[ *** *** To build the Libgcrypt's random number daemon *** we need the support of the GNU Portable Threads Library. *** Download it from ftp://ftp.gnu.org/gnu/pth/ *** On a Debian GNU/Linux system you might want to try *** apt-get install libpth-dev ***]]) else GNUPG_PTH_VERSION_CHECK([1.3.7]) if test $have_pth = yes; then PTH_CFLAGS=`$PTH_CONFIG --cflags` PTH_LIBS=`$PTH_CONFIG --ldflags` PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs --all`" AC_DEFINE(USE_GNU_PTH, 1, [Defined if the GNU Portable Thread Library should be used]) AC_DEFINE(HAVE_PTH, 1, [Defined if the GNU Pth is available]) fi fi fi AC_SUBST(PTH_CFLAGS) AC_SUBST(PTH_LIBS) # # Check whether pthreads is available # AC_CHECK_LIB(pthread,pthread_create,have_pthread=yes) if test "$have_pthread" = yes; then AC_DEFINE(HAVE_PTHREAD, ,[Define if we have pthread.]) fi # # See which thread system we have # FIXME: Thus duplicates the above check. # gl_LOCK # Solaris needs -lsocket and -lnsl. Unisys system includes # gethostbyname in libsocket but needs libnsl for socket. AC_SEARCH_LIBS(setsockopt, [socket], , [AC_SEARCH_LIBS(setsockopt, [socket], , , [-lnsl])]) AC_SEARCH_LIBS(setsockopt, [nsl]) ################################## #### Checks for header files. #### ################################## AC_HEADER_STDC AC_CHECK_HEADERS(unistd.h sys/select.h sys/msg.h) INSERT_SYS_SELECT_H= if test x"$ac_cv_header_sys_select_h" = xyes; then INSERT_SYS_SELECT_H=" include " fi AC_SUBST(INSERT_SYS_SELECT_H) ########################################## #### Checks for typedefs, structures, #### #### and compiler characteristics. #### ########################################## AC_C_CONST AC_C_INLINE AC_TYPE_SIZE_T AC_TYPE_SIGNAL AC_DECL_SYS_SIGLIST AC_TYPE_PID_T GNUPG_CHECK_TYPEDEF(byte, HAVE_BYTE_TYPEDEF) GNUPG_CHECK_TYPEDEF(ushort, HAVE_USHORT_TYPEDEF) GNUPG_CHECK_TYPEDEF(ulong, HAVE_ULONG_TYPEDEF) GNUPG_CHECK_TYPEDEF(u16, HAVE_U16_TYPEDEF) GNUPG_CHECK_TYPEDEF(u32, HAVE_U32_TYPEDEF) gl_TYPE_SOCKLEN_T case "${host}" in *-*-mingw32*) # socklen_t may or may not be defined depending on what headers # are included. To be safe we use int as this is the actual type. FALLBACK_SOCKLEN_T="typedef int gcry_socklen_t;" ;; *) if test ".$gl_cv_socklen_t_equiv" = "."; then FALLBACK_SOCKLEN_T="typedef socklen_t gcry_socklen_t;" else FALLBACK_SOCKLEN_T="typedef ${gl_cv_socklen_t_equiv} gcry_socklen_t;" fi esac AC_SUBST(FALLBACK_SOCKLEN_T) # # Check for ELF visibility support. # AC_CACHE_CHECK(whether the visibility attribute is supported, gcry_cv_visibility_attribute, [gcry_cv_visibility_attribute=no AC_LANG_CONFTEST([AC_LANG_SOURCE( [[int foo __attribute__ ((visibility ("hidden"))) = 1; int bar __attribute__ ((visibility ("protected"))) = 1; ]])]) if ${CC-cc} -Werror -S conftest.c -o conftest.s \ 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then if grep '\.hidden.*foo' conftest.s >/dev/null 2>&1 ; then if grep '\.protected.*bar' conftest.s >/dev/null 2>&1; then gcry_cv_visibility_attribute=yes fi fi fi ]) if test "$gcry_cv_visibility_attribute" = "yes"; then AC_CACHE_CHECK(for broken visibility attribute, gcry_cv_broken_visibility_attribute, [gcry_cv_broken_visibility_attribute=yes AC_LANG_CONFTEST([AC_LANG_SOURCE( [[int foo (int x); int bar (int x) __asm__ ("foo") __attribute__ ((visibility ("hidden"))); int bar (int x) { return x; } ]])]) if ${CC-cc} -Werror -S conftest.c -o conftest.s \ 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then if grep '\.hidden@<:@ _@:>@foo' conftest.s >/dev/null 2>&1; then gcry_cv_broken_visibility_attribute=no fi fi ]) fi if test "$gcry_cv_visibility_attribute" = "yes"; then AC_CACHE_CHECK(for broken alias attribute, gcry_cv_broken_alias_attribute, [gcry_cv_broken_alias_attribute=yes AC_LANG_CONFTEST([AC_LANG_SOURCE( [[extern int foo (int x) __asm ("xyzzy"); int bar (int x) { return x; } extern __typeof (bar) foo __attribute ((weak, alias ("bar"))); extern int dfoo; extern __typeof (dfoo) dfoo __asm ("abccb"); int dfoo = 1; ]])]) if ${CC-cc} -Werror -S conftest.c -o conftest.s \ 1>&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ; then if grep 'xyzzy' conftest.s >/dev/null 2>&1 && \ grep 'abccb' conftest.s >/dev/null 2>&1; then gcry_cv_broken_alias_attribute=no fi fi ]) fi if test "$gcry_cv_visibility_attribute" = "yes"; then AC_CACHE_CHECK(if gcc supports -fvisibility=hidden, gcry_cv_gcc_has_f_visibility, [gcry_cv_gcc_has_f_visibility=no _gcc_cflags_save=$CFLAGS CFLAGS="-fvisibility=hidden" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])], gcry_cv_gcc_has_f_visibility=yes) CFLAGS=$_gcc_cflags_save; ]) fi if test "$gcry_cv_visibility_attribute" = "yes" \ && test "$gcry_cv_broken_visibility_attribute" != "yes" \ && test "$gcry_cv_broken_alias_attribute" != "yes" \ && test "$gcry_cv_gcc_has_f_visibility" = "yes" then AC_DEFINE(GCRY_USE_VISIBILITY, 1, [Define to use the GNU C visibility attribute.]) CFLAGS="$CFLAGS -fvisibility=hidden" fi # # Check whether the compiler supports the GCC style aligned attribute # AC_CACHE_CHECK([whether the GCC style aligned attribute is supported], [gcry_cv_gcc_attribute_aligned], [gcry_cv_gcc_attribute_aligned=no AC_COMPILE_IFELSE([AC_LANG_SOURCE( [[struct { int a; } foo __attribute__ ((aligned (16)));]])], [gcry_cv_gcc_attribute_aligned=yes])]) if test "$gcry_cv_gcc_attribute_aligned" = "yes" ; then AC_DEFINE(HAVE_GCC_ATTRIBUTE_ALIGNED,1, [Defined if a GCC style "__attribute__ ((aligned (n))" is supported]) fi # # Check whether the compiler supports 'asm' or '__asm__' keyword for # assembler blocks # AC_CACHE_CHECK([whether 'asm' assembler keyword is supported], [gcry_cv_have_asm], [gcry_cv_have_asm=no AC_COMPILE_IFELSE([AC_LANG_SOURCE( [[void a(void) { asm("":::"memory"); }]])], [gcry_cv_have_asm=yes])]) AC_CACHE_CHECK([whether '__asm__' assembler keyword is supported], [gcry_cv_have___asm__], [gcry_cv_have___asm__=no AC_COMPILE_IFELSE([AC_LANG_SOURCE( [[void a(void) { __asm__("":::"memory"); }]])], [gcry_cv_have___asm__=yes])]) if test "$gcry_cv_have_asm" = "no" ; then if test "$gcry_cv_have___asm__" = "yes" ; then AC_DEFINE(asm,__asm__, [Define to supported assembler block keyword, if plain 'asm' was not supported]) fi fi # # Check whether GCC inline assembler supports SSSE3 instructions # This is required for the AES-NI instructions. # AC_CACHE_CHECK([whether GCC inline assembler supports SSSE3 instructions], [gcry_cv_gcc_inline_asm_ssse3], [gcry_cv_gcc_inline_asm_ssse3=no AC_COMPILE_IFELSE([AC_LANG_SOURCE( [[static unsigned char be_mask[16] __attribute__ ((aligned (16))) = { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; void a(void) { __asm__("pshufb %[mask], %%xmm2\n\t"::[mask]"m"(*be_mask):); }]])], [gcry_cv_gcc_inline_asm_ssse3=yes])]) if test "$gcry_cv_gcc_inline_asm_ssse3" = "yes" ; then AC_DEFINE(HAVE_GCC_INLINE_ASM_SSSE3,1, [Defined if inline assembler supports SSSE3 instructions]) fi # # Check whether GCC inline assembler supports AVX instructions # AC_CACHE_CHECK([whether GCC inline assembler supports AVX instructions], [gcry_cv_gcc_inline_asm_avx], [gcry_cv_gcc_inline_asm_avx=no AC_COMPILE_IFELSE([AC_LANG_SOURCE( [[void a(void) { __asm__("vaesdeclast (%[mem]),%%xmm0,%%xmm7\n\t"::[mem]"r"(0):); }]])], [gcry_cv_gcc_inline_asm_avx=yes])]) if test "$gcry_cv_gcc_inline_asm_avx" = "yes" ; then AC_DEFINE(HAVE_GCC_INLINE_ASM_AVX,1, [Defined if inline assembler supports AVX instructions]) fi # # Check whether GCC inline assembler supports AVX2 instructions # AC_CACHE_CHECK([whether GCC inline assembler supports AVX2 instructions], [gcry_cv_gcc_inline_asm_avx2], [gcry_cv_gcc_inline_asm_avx2=no AC_COMPILE_IFELSE([AC_LANG_SOURCE( [[void a(void) { __asm__("vpbroadcastb %%xmm7,%%ymm1\n\t":::); }]])], [gcry_cv_gcc_inline_asm_avx2=yes])]) if test "$gcry_cv_gcc_inline_asm_avx2" = "yes" ; then AC_DEFINE(HAVE_GCC_INLINE_ASM_AVX2,1, [Defined if inline assembler supports AVX2 instructions]) fi # # Check whether GCC assembler supports features needed for our amd64 # implementations # AC_CACHE_CHECK([whether GCC assembler is compatible for amd64 assembly implementations], [gcry_cv_gcc_amd64_platform_as_ok], [gcry_cv_gcc_amd64_platform_as_ok=no AC_COMPILE_IFELSE([AC_LANG_SOURCE( [[__asm__( /* Test if '.set' is supported by underlying assembler. */ ".set a0, %rax\n\t" ".set b0, %rdx\n\t" "asmfunc:\n\t" "movq a0, b0;\n\t" /* Fails here if .set ignored by as. */ /* Test if '.type' and '.size' are supported. */ /* These work only on ELF targets. */ /* TODO: add COFF (mingw64, cygwin64) support to assembly * implementations. Mingw64/cygwin64 also require additional * work because they use different calling convention. */ ".size asmfunc,.-asmfunc;\n\t" ".type asmfunc,@function;\n\t" );]])], [gcry_cv_gcc_amd64_platform_as_ok=yes])]) if test "$gcry_cv_gcc_amd64_platform_as_ok" = "yes" ; then AC_DEFINE(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS,1, [Defined if underlying assembler is compatible with amd64 assembly implementations]) fi ####################################### #### Checks for library functions. #### ####################################### AC_FUNC_VPRINTF # We have replacements for these in src/missing-string.c AC_CHECK_FUNCS(stpcpy strcasecmp) # We have replacements for these in src/g10lib.h AC_CHECK_FUNCS(strtoul memmove stricmp atexit raise) # Other checks AC_CHECK_FUNCS(strerror rand mmap getpagesize sysconf waitpid wait4) AC_CHECK_FUNCS(gettimeofday getrusage gethrtime clock_gettime syslog) AC_CHECK_FUNCS(fcntl ftruncate) GNUPG_CHECK_MLOCK # # Replacement functions. # AC_REPLACE_FUNCS([getpid clock]) # # Check wether it is necessary to link against libdl. # DL_LIBS="" if test "$use_hmac_binary_check" = yes ; then _gcry_save_libs="$LIBS" LIBS="" AC_SEARCH_LIBS(dlopen, c dl,,,) DL_LIBS=$LIBS LIBS="$_gcry_save_libs" LIBGCRYPT_CONFIG_LIBS="${LIBGCRYPT_CONFIG_LIBS} ${DL_LIBS}" fi AC_SUBST(DL_LIBS) # # Check whether we can use Linux capabilities as requested. # if test "$use_capabilities" = "yes" ; then use_capabilities=no AC_CHECK_HEADERS(sys/capability.h) if test "$ac_cv_header_sys_capability_h" = "yes" ; then AC_CHECK_LIB(cap, cap_init, ac_need_libcap=1) if test "$ac_cv_lib_cap_cap_init" = "yes"; then AC_DEFINE(USE_CAPABILITIES,1, [define if capabilities should be used]) LIBS="$LIBS -lcap" use_capabilities=yes fi fi if test "$use_capabilities" = "no" ; then AC_MSG_WARN([[ *** *** The use of capabilities on this system is not possible. *** You need a recent Linux kernel and some patches: *** fcaps-2.2.9-990610.patch (kernel patch for 2.2.9) *** fcap-module-990613.tar.gz (kernel module) *** libcap-1.92.tar.gz (user mode library and utilities) *** And you have to configure the kernel with CONFIG_VFS_CAP_PLUGIN *** set (filesystems menu). Be warned: This code is *really* ALPHA. ***]]) fi fi # Check whether a random device is available. if test "$try_dev_random" = yes ; then AC_CACHE_CHECK(for random device, ac_cv_have_dev_random, [if test -r "$NAME_OF_DEV_RANDOM" && test -r "$NAME_OF_DEV_URANDOM" ; then ac_cv_have_dev_random=yes; else ac_cv_have_dev_random=no; fi]) if test "$ac_cv_have_dev_random" = yes; then AC_DEFINE(HAVE_DEV_RANDOM,1, [defined if the system supports a random device] ) fi else AC_MSG_CHECKING(for random device) ac_cv_have_dev_random=no AC_MSG_RESULT(has been disabled) fi # Figure out the random modules for this configuration. if test "$random" = "default"; then # Select default value. if test "$ac_cv_have_dev_random" = yes; then # Try Linuxish random device. random_modules="linux" else case "${host}" in *-*-mingw32ce*) # WindowsCE random device. random_modules="w32ce" ;; *-*-mingw32*|*-*-cygwin*) # Windows random device. random_modules="w32" ;; *) # Build everything, allow to select at runtime. random_modules="$auto_random_modules" ;; esac fi else if test "$random" = "auto"; then # Build everything, allow to select at runtime. random_modules="$auto_random_modules" else random_modules="$random" fi fi # # Setup assembler stuff. # # Note that config.links also defines mpi_cpu_arch, which is required # later on. # GNUPG_SYS_SYMBOL_UNDERSCORE() AC_ARG_ENABLE(mpi-path, AC_HELP_STRING([--enable-mpi-path=EXTRA_PATH], [prepend EXTRA_PATH to list of CPU specific optimizations]), mpi_extra_path="$enableval",mpi_extra_path="") AC_MSG_CHECKING(for mpi assembler functions) if test -f $srcdir/mpi/config.links ; then . $srcdir/mpi/config.links AC_CONFIG_LINKS("$mpi_ln_list") ac_cv_mpi_sflags="$mpi_sflags" AC_MSG_RESULT(done) else AC_MSG_RESULT(failed) AC_MSG_ERROR([mpi/config.links missing!]) fi MPI_SFLAGS="$ac_cv_mpi_sflags" AC_SUBST(MPI_SFLAGS) AM_CONDITIONAL(MPI_MOD_ASM_MPIH_ADD1, test "$mpi_mod_asm_mpih_add1" = yes) AM_CONDITIONAL(MPI_MOD_ASM_MPIH_SUB1, test "$mpi_mod_asm_mpih_sub1" = yes) AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL1, test "$mpi_mod_asm_mpih_mul1" = yes) AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL2, test "$mpi_mod_asm_mpih_mul2" = yes) AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL3, test "$mpi_mod_asm_mpih_mul3" = yes) AM_CONDITIONAL(MPI_MOD_ASM_MPIH_LSHIFT, test "$mpi_mod_asm_mpih_lshift" = yes) AM_CONDITIONAL(MPI_MOD_ASM_MPIH_RSHIFT, test "$mpi_mod_asm_mpih_rshift" = yes) AM_CONDITIONAL(MPI_MOD_ASM_UDIV, test "$mpi_mod_asm_udiv" = yes) AM_CONDITIONAL(MPI_MOD_ASM_UDIV_QRNND, test "$mpi_mod_asm_udiv_qrnnd" = yes) AM_CONDITIONAL(MPI_MOD_C_MPIH_ADD1, test "$mpi_mod_c_mpih_add1" = yes) AM_CONDITIONAL(MPI_MOD_C_MPIH_SUB1, test "$mpi_mod_c_mpih_sub1" = yes) AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL1, test "$mpi_mod_c_mpih_mul1" = yes) AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL2, test "$mpi_mod_c_mpih_mul2" = yes) AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL3, test "$mpi_mod_c_mpih_mul3" = yes) AM_CONDITIONAL(MPI_MOD_C_MPIH_LSHIFT, test "$mpi_mod_c_mpih_lshift" = yes) AM_CONDITIONAL(MPI_MOD_C_MPIH_RSHIFT, test "$mpi_mod_c_mpih_rshift" = yes) AM_CONDITIONAL(MPI_MOD_C_UDIV, test "$mpi_mod_c_udiv" = yes) AM_CONDITIONAL(MPI_MOD_C_UDIV_QRNND, test "$mpi_mod_c_udiv_qrnnd" = yes) if test mym4_isgit = "yes"; then AC_DEFINE(IS_DEVELOPMENT_VERSION,1, [Defined if this is not a regular release]) fi AM_CONDITIONAL(CROSS_COMPILING, test x$cross_compiling = xyes) # This is handy for debugging so the compiler doesn't rearrange # things and eliminate variables. AC_ARG_ENABLE(optimization, AC_HELP_STRING([--disable-optimization], [disable compiler optimization]), [if test $enableval = no ; then CFLAGS=`echo $CFLAGS | sed 's/-O[[0-9]]//'` fi]) # CFLAGS mangling when using gcc. if test "$GCC" = yes; then CFLAGS="$CFLAGS -Wall" if test "$USE_MAINTAINER_MODE" = "yes"; then CFLAGS="$CFLAGS -Wcast-align -Wshadow -Wstrict-prototypes" CFLAGS="$CFLAGS -Wformat -Wno-format-y2k -Wformat-security" # If -Wno-missing-field-initializers is supported we can enable a # a bunch of really useful warnings. AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers]) _gcc_cflags_save=$CFLAGS CFLAGS="-Wno-missing-field-initializers" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no) AC_MSG_RESULT($_gcc_wopt) CFLAGS=$_gcc_cflags_save; if test x"$_gcc_wopt" = xyes ; then CFLAGS="$CFLAGS -W -Wextra -Wbad-function-cast" CFLAGS="$CFLAGS -Wwrite-strings" CFLAGS="$CFLAGS -Wdeclaration-after-statement" CFLAGS="$CFLAGS -Wno-missing-field-initializers" CFLAGS="$CFLAGS -Wno-sign-compare" fi AC_MSG_CHECKING([if gcc supports -Wpointer-arith]) _gcc_cflags_save=$CFLAGS CFLAGS="-Wpointer-arith" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no) AC_MSG_RESULT($_gcc_wopt) CFLAGS=$_gcc_cflags_save; if test x"$_gcc_wopt" = xyes ; then CFLAGS="$CFLAGS -Wpointer-arith" fi fi fi # Check whether as(1) supports a noeexecstack feature. This test # includes an override option. CL_AS_NOEXECSTACK AC_SUBST(LIBGCRYPT_CONFIG_API_VERSION) AC_SUBST(LIBGCRYPT_CONFIG_LIBS) AC_SUBST(LIBGCRYPT_CONFIG_CFLAGS) AC_SUBST(LIBGCRYPT_CONFIG_HOST) AC_SUBST(LIBGCRYPT_THREAD_MODULES) AC_CONFIG_COMMANDS([gcrypt-conf],[[ chmod +x src/libgcrypt-config ]],[[ prefix=$prefix exec_prefix=$exec_prefix libdir=$libdir datadir=$datadir DATADIRNAME=$DATADIRNAME ]]) ##################### #### Conclusion. #### ##################### # Check that requested feature can actually be used and define # ENABLE_foo_SUPPORT macros. if test x"$aesnisupport" = xyes ; then if test "$gcry_cv_gcc_inline_asm_ssse3" != "yes" ; then aesnisupport="no (unsupported by compiler)" fi fi if test x"$avxsupport" = xyes ; then if test "$gcry_cv_gcc_inline_asm_avx" != "yes" ; then avxsupport="no (unsupported by compiler)" fi fi if test x"$avx2support" = xyes ; then if test "$gcry_cv_gcc_inline_asm_avx2" != "yes" ; then avx2support="no (unsupported by compiler)" fi fi if test x"$aesnisupport" = xyes ; then AC_DEFINE(ENABLE_AESNI_SUPPORT, 1, [Enable support for Intel AES-NI instructions.]) fi if test x"$avxsupport" = xyes ; then AC_DEFINE(ENABLE_AVX_SUPPORT,1, [Enable support for Intel AVX instructions.]) fi if test x"$avx2support" = xyes ; then AC_DEFINE(ENABLE_AVX2_SUPPORT,1, [Enable support for Intel AVX2 instructions.]) fi # Define conditional sources and config.h symbols depending on the # selected ciphers, pubkey-ciphers, digests, kdfs, and random modules. LIST_MEMBER(arcfour, $enabled_ciphers) if test "$found" = "1"; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS arcfour.lo" AC_DEFINE(USE_ARCFOUR, 1, [Defined if this module should be included]) fi LIST_MEMBER(blowfish, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish.lo" AC_DEFINE(USE_BLOWFISH, 1, [Defined if this module should be included]) case "${host}" in x86_64-*-*) # Build with the assembly implementation GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish-amd64.lo" ;; esac fi LIST_MEMBER(cast5, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5.lo" AC_DEFINE(USE_CAST5, 1, [Defined if this module should be included]) case "${host}" in x86_64-*-*) # Build with the assembly implementation GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5-amd64.lo" ;; esac fi LIST_MEMBER(des, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS des.lo" AC_DEFINE(USE_DES, 1, [Defined if this module should be included]) fi LIST_MEMBER(aes, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael.lo" AC_DEFINE(USE_AES, 1, [Defined if this module should be included]) case "${host}" in x86_64-*-*) # Build with the assembly implementation GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-amd64.lo" ;; esac fi LIST_MEMBER(twofish, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish.lo" AC_DEFINE(USE_TWOFISH, 1, [Defined if this module should be included]) case "${host}" in x86_64-*-*) # Build with the assembly implementation GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-amd64.lo" ;; esac fi LIST_MEMBER(serpent, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent.lo" AC_DEFINE(USE_SERPENT, 1, [Defined if this module should be included]) case "${host}" in x86_64-*-*) # Build with the SSE2 implementation GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-sse2-amd64.lo" ;; esac if test x"$avx2support" = xyes ; then # Build with the AVX2 implementation GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-avx2-amd64.lo" fi fi LIST_MEMBER(rfc2268, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS rfc2268.lo" AC_DEFINE(USE_RFC2268, 1, [Defined if this module should be included]) fi LIST_MEMBER(seed, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS seed.lo" AC_DEFINE(USE_SEED, 1, [Defined if this module should be included]) fi LIST_MEMBER(camellia, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia.lo camellia-glue.lo" AC_DEFINE(USE_CAMELLIA, 1, [Defined if this module should be included]) if test x"$avxsupport" = xyes ; then if test x"$aesnisupport" = xyes ; then # Build with the AES-NI/AVX implementation GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aesni-avx-amd64.lo" fi fi if test x"$avx2support" = xyes ; then if test x"$aesnisupport" = xyes ; then # Build with the AES-NI/AVX2 implementation GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aesni-avx2-amd64.lo" fi fi fi LIST_MEMBER(idea, $enabled_ciphers) if test "$found" = "1" ; then GCRYPT_CIPHERS="$GCRYPT_CIPHERS idea.lo" AC_DEFINE(USE_IDEA, 1, [Defined if this module should be included]) fi LIST_MEMBER(dsa, $enabled_pubkey_ciphers) if test "$found" = "1" ; then GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS dsa.lo" AC_DEFINE(USE_DSA, 1, [Defined if this module should be included]) fi LIST_MEMBER(rsa, $enabled_pubkey_ciphers) if test "$found" = "1" ; then GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS rsa.lo" AC_DEFINE(USE_RSA, 1, [Defined if this module should be included]) fi LIST_MEMBER(elgamal, $enabled_pubkey_ciphers) if test "$found" = "1" ; then GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS elgamal.lo" AC_DEFINE(USE_ELGAMAL, 1, [Defined if this module should be included]) fi LIST_MEMBER(ecc, $enabled_pubkey_ciphers) if test "$found" = "1" ; then GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS ecc.lo" AC_DEFINE(USE_ECC, 1, [Defined if this module should be included]) fi LIST_MEMBER(crc, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS crc.lo" AC_DEFINE(USE_CRC, 1, [Defined if this module should be included]) fi LIST_MEMBER(md4, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS md4.lo" AC_DEFINE(USE_MD4, 1, [Defined if this module should be included]) fi LIST_MEMBER(md5, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS md5.lo" AC_DEFINE(USE_MD5, 1, [Defined if this module should be included]) fi LIST_MEMBER(sha256, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256.lo" AC_DEFINE(USE_SHA256, 1, [Defined if this module should be included]) fi LIST_MEMBER(sha512, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512.lo" AC_DEFINE(USE_SHA512, 1, [Defined if this module should be included]) fi LIST_MEMBER(tiger, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS tiger.lo" AC_DEFINE(USE_TIGER, 1, [Defined if this module should be included]) fi LIST_MEMBER(whirlpool, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool.lo" AC_DEFINE(USE_WHIRLPOOL, 1, [Defined if this module should be included]) fi # rmd160 and sha1 should be included always. GCRYPT_DIGESTS="$GCRYPT_DIGESTS rmd160.lo sha1.lo" AC_DEFINE(USE_RMD160, 1, [Defined if this module should be included]) AC_DEFINE(USE_SHA1, 1, [Defined if this module should be included]) LIST_MEMBER(scrypt, $enabled_kdfs) if test "$found" = "1" ; then GCRYPT_KDFS="$GCRYPT_KDFS scrypt.lo" AC_DEFINE(USE_SCRYPT, 1, [Defined if this module should be included]) fi LIST_MEMBER(linux, $random_modules) if test "$found" = "1" ; then GCRYPT_RANDOM="$GCRYPT_RANDOM rndlinux.lo" AC_DEFINE(USE_RNDLINUX, 1, [Defined if the /dev/random RNG should be used.]) fi LIST_MEMBER(unix, $random_modules) if test "$found" = "1" ; then GCRYPT_RANDOM="$GCRYPT_RANDOM rndunix.lo" AC_DEFINE(USE_RNDUNIX, 1, [Defined if the default Unix RNG should be used.]) print_egd_notice=yes fi LIST_MEMBER(egd, $random_modules) if test "$found" = "1" ; then GCRYPT_RANDOM="$GCRYPT_RANDOM rndegd.lo" AC_DEFINE(USE_RNDEGD, 1, [Defined if the EGD based RNG should be used.]) fi LIST_MEMBER(w32, $random_modules) if test "$found" = "1" ; then GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32.lo" AC_DEFINE(USE_RNDW32, 1, [Defined if the Windows specific RNG should be used.]) fi LIST_MEMBER(w32ce, $random_modules) if test "$found" = "1" ; then GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32ce.lo" AC_DEFINE(USE_RNDW32CE, 1, [Defined if the WindowsCE specific RNG should be used.]) fi AC_SUBST([GCRYPT_CIPHERS]) AC_SUBST([GCRYPT_PUBKEY_CIPHERS]) AC_SUBST([GCRYPT_DIGESTS]) AC_SUBST([GCRYPT_KDFS]) AC_SUBST([GCRYPT_RANDOM]) AC_SUBST(LIBGCRYPT_CIPHERS, $enabled_ciphers) AC_SUBST(LIBGCRYPT_PUBKEY_CIPHERS, $enabled_pubkey_ciphers) AC_SUBST(LIBGCRYPT_DIGESTS, $enabled_digests) # For printing the configuration we need a colon separated list of # algorithm names. tmp=`echo "$enabled_ciphers" | tr ' ' : ` AC_DEFINE_UNQUOTED(LIBGCRYPT_CIPHERS, "$tmp", [List of available cipher algorithms]) tmp=`echo "$enabled_pubkey_ciphers" | tr ' ' : ` AC_DEFINE_UNQUOTED(LIBGCRYPT_PUBKEY_CIPHERS, "$tmp", [List of available public key cipher algorithms]) tmp=`echo "$enabled_digests" | tr ' ' : ` AC_DEFINE_UNQUOTED(LIBGCRYPT_DIGESTS, "$tmp", [List of available digest algorithms]) tmp=`echo "$enabled_kdfs" | tr ' ' : ` AC_DEFINE_UNQUOTED(LIBGCRYPT_KDFS, "$tmp", [List of available KDF algorithms]) # # Define conditional sources depending on the used hardware platform. # Note that all possible modules must also be listed in # src/Makefile.am (EXTRA_libgcrypt_la_SOURCES). # GCRYPT_HWF_MODULES= case "$mpi_cpu_arch" in x86) AC_DEFINE(HAVE_CPU_ARCH_X86, 1, [Defined for the x86 platforms]) GCRYPT_HWF_MODULES="hwf-x86.lo" ;; alpha) AC_DEFINE(HAVE_CPU_ARCH_ALPHA, 1, [Defined for Alpha platforms]) ;; sparc) AC_DEFINE(HAVE_CPU_ARCH_SPARC, 1, [Defined for SPARC platforms]) ;; mips) AC_DEFINE(HAVE_CPU_ARCH_MIPS, 1, [Defined for MIPS platforms]) ;; m68k) AC_DEFINE(HAVE_CPU_ARCH_M68K, 1, [Defined for M68k platforms]) ;; ppc) AC_DEFINE(HAVE_CPU_ARCH_PPC, 1, [Defined for PPC platforms]) ;; arm) AC_DEFINE(HAVE_CPU_ARCH_ARM, 1, [Defined for ARM platforms]) ;; esac AC_SUBST([GCRYPT_HWF_MODULES]) # # Provide information about the build. # BUILD_REVISION="mym4_revision" AC_SUBST(BUILD_REVISION) AC_DEFINE_UNQUOTED(BUILD_REVISION, "$BUILD_REVISION", [GIT commit id revision used to build this package]) changequote(,)dnl BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'` changequote([,])dnl BUILD_FILEVERSION="${BUILD_FILEVERSION}mym4_revision_dec" AC_SUBST(BUILD_FILEVERSION) BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date` AC_SUBST(BUILD_TIMESTAMP) AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP", [The time this package was configured for a build]) # And create the files. AC_CONFIG_FILES([ Makefile m4/Makefile compat/Makefile mpi/Makefile cipher/Makefile random/Makefile doc/Makefile src/Makefile src/gcrypt.h src/libgcrypt-config src/versioninfo.rc tests/Makefile ]) AC_OUTPUT detection_module="${GCRYPT_HWF_MODULES%.lo}" test -n "$detection_module" || detection_module="none" # Give some feedback GCRY_MSG_SHOW([],[]) GCRY_MSG_SHOW([Libgcrypt],[v${VERSION} has been configured as follows:]) GCRY_MSG_SHOW([],[]) GCRY_MSG_SHOW([Platform: ],[$PRINTABLE_OS_NAME ($host)]) GCRY_MSG_SHOW([Hardware detection module:],[$detection_module]) GCRY_MSG_WRAP([Enabled cipher algorithms:],[$enabled_ciphers]) GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests]) GCRY_MSG_WRAP([Enabled kdf algorithms: ],[$enabled_kdfs]) GCRY_MSG_WRAP([Enabled pubkey algorithms:],[$enabled_pubkey_ciphers]) GCRY_MSG_SHOW([Random number generator: ],[$random]) GCRY_MSG_SHOW([Using linux capabilities: ],[$use_capabilities]) GCRY_MSG_SHOW([Try using Padlock crypto: ],[$padlocksupport]) GCRY_MSG_SHOW([Try using AES-NI crypto: ],[$aesnisupport]) GCRY_MSG_SHOW([Try using DRNG (RDRAND): ],[$drngsupport]) GCRY_MSG_SHOW([Try using Intel AVX: ],[$avxsupport]) GCRY_MSG_SHOW([Try using Intel AVX2: ],[$avx2support]) GCRY_MSG_SHOW([],[]) if test "$print_egd_notice" = "yes"; then cat <. ## Process this file with automake to produce Makefile.in EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \ gcrypt.h.in libgcrypt.def bin_SCRIPTS = libgcrypt-config m4datadir = $(datadir)/aclocal m4data_DATA = libgcrypt.m4 include_HEADERS = gcrypt.h lib_LTLIBRARIES = libgcrypt.la bin_PROGRAMS = dumpsexp hmac256 if USE_RANDOM_DAEMON sbin_PROGRAMS = gcryptrnd bin_PROGRAMS += getrandom endif USE_RANDOM_DAEMON # Depending on the architecture some targets require libgpg-error. if HAVE_W32CE_SYSTEM arch_gpg_error_cflags = $(GPG_ERROR_CFLAGS) arch_gpg_error_libs = $(GPG_ERROR_LIBS) else arch_gpg_error_cflags = arch_gpg_error_libs = endif AM_CFLAGS = $(GPG_ERROR_CFLAGS) AM_CCASFLAGS = $(NOEXECSTACK_FLAGS) if HAVE_LD_VERSION_SCRIPT libgcrypt_version_script_cmd = -Wl,--version-script=$(srcdir)/libgcrypt.vers else libgcrypt_version_script_cmd = endif libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS) -libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \ +libgcrypt_la_SOURCES = \ + gcrypt-int.h g10lib.h visibility.c visibility.h types.h \ cipher.h cipher-proto.h gcrypt-module.h \ misc.c global.c sexp.c hwfeatures.c hwf-common.h \ stdmem.c stdmem.h secmem.c secmem.h \ mpi.h missing-string.c module.c fips.c \ hmac256.c hmac256.h context.c context.h \ ec-context.h \ ath.h ath.c EXTRA_libgcrypt_la_SOURCES = hwf-x86.c gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@ if HAVE_W32_SYSTEM RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(libgcrypt_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) LTRCCOMPILE = $(LIBTOOL) --mode=compile --tag=RC $(RCCOMPILE) SUFFIXES = .rc .lo .rc.lo: $(LTRCCOMPILE) -i "$<" -o "$@" gcrypt_res = versioninfo.lo no_undefined = -no-undefined export_symbols = -export-symbols $(srcdir)/libgcrypt.def install-def-file: -$(INSTALL) -d $(DESTDIR)$(libdir) $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def uninstall-def-file: -rm $(DESTDIR)$(libdir)/libgcrypt.def gcrypt_deps = $(gcrypt_res) libgcrypt.def else !HAVE_W32_SYSTEM gcrypt_res = gcrypt_res_ldflag = no_undefined = export_symbols = install-def-file: uninstall-def-file: gcrypt_deps = endif !HAVE_W32_SYSTEM libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \ $(libgcrypt_version_script_cmd) -version-info \ @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@ libgcrypt_la_DEPENDENCIES = \ $(gcrypt_hwf_modules) \ ../cipher/libcipher.la \ ../random/librandom.la \ ../mpi/libmpi.la \ ../compat/libcompat.la \ $(srcdir)/libgcrypt.vers $(gcrypt_deps) libgcrypt_la_LIBADD = $(gcrypt_res) \ $(gcrypt_hwf_modules) \ ../cipher/libcipher.la \ ../random/librandom.la \ ../mpi/libmpi.la \ ../compat/libcompat.la $(GPG_ERROR_LIBS) dumpsexp_SOURCES = dumpsexp.c dumpsexp_CFLAGS = $(arch_gpg_error_cflags) dumpsexp_LDADD = $(arch_gpg_error_libs) hmac256_SOURCES = hmac256.c hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags) hmac256_LDADD = $(arch_gpg_error_libs) if USE_RANDOM_DAEMON gcryptrnd_SOURCES = gcryptrnd.c gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS) gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS) getrandom_SOURCES = getrandom.c endif USE_RANDOM_DAEMON install-data-local: install-def-file uninstall-local: uninstall-def-file # FIXME: We need to figure out how to get the actual name (parsing # libgcrypt.la?) and how to create the hmac file already at link time # so that it can be used without installing libgcrypt first. #install-exec-hook: # ./hmac256 "What am I, a doctor or a moonshuttle conductor?" \ # < $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \ # > $(DESTDIR)$(libdir)/.libgcrypt.so.11.5.0.hmac diff --git a/src/cipher.h b/src/cipher.h index 80c88392..26206135 100644 --- a/src/cipher.h +++ b/src/cipher.h @@ -1,240 +1,240 @@ /* cipher.h * Copyright (C) 1998, 2002, 2003, 2009 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser general Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifndef G10_CIPHER_H #define G10_CIPHER_H -#include +#include "gcrypt-int.h" #define DBG_CIPHER _gcry_get_debug_flag( 1 ) #include "../random/random.h" #define PUBKEY_FLAG_NO_BLINDING (1 << 0) enum pk_operation { PUBKEY_OP_ENCRYPT, PUBKEY_OP_DECRYPT, PUBKEY_OP_SIGN, PUBKEY_OP_VERIFY }; enum pk_encoding { PUBKEY_ENC_RAW, PUBKEY_ENC_PKCS1, PUBKEY_ENC_OAEP, PUBKEY_ENC_PSS, PUBKEY_ENC_UNKNOWN }; struct pk_encoding_ctx { enum pk_operation op; unsigned int nbits; enum pk_encoding encoding; int flags; int hash_algo; /* for OAEP */ unsigned char *label; size_t labellen; /* for PSS */ size_t saltlen; int (* verify_cmp) (void *opaque, gcry_mpi_t tmp); void *verify_arg; }; #define CIPHER_INFO_NO_WEAK_KEY 1 #include "cipher-proto.h" /*-- rmd160.c --*/ void _gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length); /*-- sha1.c --*/ void _gcry_sha1_hash_buffer (void *outbuf, const void *buffer, size_t length); /*-- rijndael.c --*/ void _gcry_aes_cfb_enc (void *context, unsigned char *iv, void *outbuf, const void *inbuf, unsigned int nblocks); void _gcry_aes_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_aes_cbc_enc (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks, int cbc_mac); void _gcry_aes_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_aes_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); /*-- blowfish.c --*/ void _gcry_blowfish_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_blowfish_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_blowfish_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); /*-- cast5.c --*/ void _gcry_cast5_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_cast5_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_cast5_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); /*-- camellia-glue.c --*/ void _gcry_camellia_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_camellia_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_camellia_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); /*-- serpent.c --*/ void _gcry_serpent_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_serpent_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_serpent_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); /*-- twofish.c --*/ void _gcry_twofish_ctr_enc (void *context, unsigned char *ctr, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_twofish_cbc_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); void _gcry_twofish_cfb_dec (void *context, unsigned char *iv, void *outbuf_arg, const void *inbuf_arg, unsigned int nblocks); /*-- dsa.c --*/ void _gcry_register_pk_dsa_progress (gcry_handler_progress_t cbc, void *cb_data); /*-- elgamal.c --*/ void _gcry_register_pk_elg_progress (gcry_handler_progress_t cb, void *cb_data); /*-- ecc.c --*/ void _gcry_register_pk_ecc_progress (gcry_handler_progress_t cbc, void *cb_data); /*-- primegen.c --*/ void _gcry_register_primegen_progress (gcry_handler_progress_t cb, void *cb_data); /*-- pubkey.c --*/ const char * _gcry_pk_aliased_algo_name (int algorithm); /* Declarations for the cipher specifications. */ extern gcry_cipher_spec_t _gcry_cipher_spec_blowfish; extern gcry_cipher_spec_t _gcry_cipher_spec_des; extern gcry_cipher_spec_t _gcry_cipher_spec_tripledes; extern gcry_cipher_spec_t _gcry_cipher_spec_arcfour; extern gcry_cipher_spec_t _gcry_cipher_spec_cast5; extern gcry_cipher_spec_t _gcry_cipher_spec_aes; extern gcry_cipher_spec_t _gcry_cipher_spec_aes192; extern gcry_cipher_spec_t _gcry_cipher_spec_aes256; extern gcry_cipher_spec_t _gcry_cipher_spec_twofish; extern gcry_cipher_spec_t _gcry_cipher_spec_twofish128; extern gcry_cipher_spec_t _gcry_cipher_spec_serpent128; extern gcry_cipher_spec_t _gcry_cipher_spec_serpent192; extern gcry_cipher_spec_t _gcry_cipher_spec_serpent256; extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40; extern gcry_cipher_spec_t _gcry_cipher_spec_seed; extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128; extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192; extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256; extern gcry_cipher_spec_t _gcry_cipher_spec_idea; extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes; extern cipher_extra_spec_t _gcry_cipher_extraspec_aes; extern cipher_extra_spec_t _gcry_cipher_extraspec_aes192; extern cipher_extra_spec_t _gcry_cipher_extraspec_aes256; /* Declarations for the digest specifications. */ extern gcry_md_spec_t _gcry_digest_spec_crc32; extern gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510; extern gcry_md_spec_t _gcry_digest_spec_crc24_rfc2440; extern gcry_md_spec_t _gcry_digest_spec_md4; extern gcry_md_spec_t _gcry_digest_spec_md5; extern gcry_md_spec_t _gcry_digest_spec_rmd160; extern gcry_md_spec_t _gcry_digest_spec_sha1; extern gcry_md_spec_t _gcry_digest_spec_sha224; extern gcry_md_spec_t _gcry_digest_spec_sha256; extern gcry_md_spec_t _gcry_digest_spec_sha512; extern gcry_md_spec_t _gcry_digest_spec_sha384; extern gcry_md_spec_t _gcry_digest_spec_tiger; extern gcry_md_spec_t _gcry_digest_spec_tiger1; extern gcry_md_spec_t _gcry_digest_spec_tiger2; extern gcry_md_spec_t _gcry_digest_spec_whirlpool; extern md_extra_spec_t _gcry_digest_extraspec_sha1; extern md_extra_spec_t _gcry_digest_extraspec_sha224; extern md_extra_spec_t _gcry_digest_extraspec_sha256; extern md_extra_spec_t _gcry_digest_extraspec_sha384; extern md_extra_spec_t _gcry_digest_extraspec_sha512; /* Declarations for the pubkey cipher specifications. */ extern gcry_pk_spec_t _gcry_pubkey_spec_rsa; extern gcry_pk_spec_t _gcry_pubkey_spec_elg; extern gcry_pk_spec_t _gcry_pubkey_spec_dsa; extern gcry_pk_spec_t _gcry_pubkey_spec_ecdsa; extern gcry_pk_spec_t _gcry_pubkey_spec_ecdh; extern pk_extra_spec_t _gcry_pubkey_extraspec_rsa; extern pk_extra_spec_t _gcry_pubkey_extraspec_dsa; extern pk_extra_spec_t _gcry_pubkey_extraspec_elg; extern pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa; #endif /*G10_CIPHER_H*/ diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h new file mode 100644 index 00000000..33969fe0 --- /dev/null +++ b/src/gcrypt-int.h @@ -0,0 +1,40 @@ +/* gcrypt-int.h - Internal version of gcrypt.h + * Copyright (C) 2013 g10 Code GmbH + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifndef GCRY_GCRYPT_INT_H +#define GCRY_GCRYPT_INT_H + +#ifdef _GCRYPT_H +#error gcrypt.h already included +#endif + +#include "gcrypt.h" + +/* These error codes are used but not defined in the required + libgpg-error 1.11. Define them here. */ +#ifndef GPG_ERR_NO_CRYPT_CTX +# define GPG_ERR_NO_CRYPT_CTX 191 +# define GPG_ERR_WRONG_CRYPT_CTX 192 +# define GPG_ERR_BAD_CRYPT_CTX 193 +# define GPG_ERR_CRYPT_CTX_CONFLICT 194 +# define GPG_ERR_BROKEN_PUBKEY 195 +# define GPG_ERR_BROKEN_SECKEY 196 +#endif + +#endif /*GCRY_GCRYPT_INT_H*/ diff --git a/src/visibility.h b/src/visibility.h index 6887f37b..4837ed65 100644 --- a/src/visibility.h +++ b/src/visibility.h @@ -1,605 +1,605 @@ /* visibility.h - Set visibility attribute * Copyright (C) 2007 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifndef GCRY_VISIBILITY_H #define GCRY_VISIBILITY_H /* Redefine all public symbols with an underscore unless we already use the underscore prefixed version internally. */ #define gcry_check_version _gcry_check_version #define gcry_control _gcry_control #define gcry_set_allocation_handler _gcry_set_allocation_handler #define gcry_set_fatalerror_handler _gcry_set_fatalerror_handler #define gcry_set_gettext_handler _gcry_set_gettext_handler #define gcry_set_log_handler _gcry_set_log_handler #define gcry_set_outofcore_handler _gcry_set_outofcore_handler #define gcry_set_progress_handler _gcry_set_progress_handler #define gcry_err_code_from_errno _gcry_err_code_from_errno #define gcry_err_code_to_errno _gcry_err_code_to_errno #define gcry_err_make_from_errno _gcry_err_make_from_errno #define gcry_error_from_errno _gcry_error_from_errno #define gcry_strerror _gcry_strerror #define gcry_strsource _gcry_strsource #define gcry_free _gcry_free #define gcry_malloc _gcry_malloc #define gcry_malloc_secure _gcry_malloc_secure #define gcry_calloc _gcry_calloc #define gcry_calloc_secure _gcry_calloc_secure #define gcry_realloc _gcry_realloc #define gcry_strdup _gcry_strdup #define gcry_is_secure _gcry_is_secure #define gcry_xcalloc _gcry_xcalloc #define gcry_xcalloc_secure _gcry_xcalloc_secure #define gcry_xmalloc _gcry_xmalloc #define gcry_xmalloc_secure _gcry_xmalloc_secure #define gcry_xrealloc _gcry_xrealloc #define gcry_xstrdup _gcry_xstrdup #define gcry_md_algo_info _gcry_md_algo_info #define gcry_md_algo_name _gcry_md_algo_name #define gcry_md_close _gcry_md_close #define gcry_md_copy _gcry_md_copy #define gcry_md_ctl _gcry_md_ctl #define gcry_md_enable _gcry_md_enable #define gcry_md_get _gcry_md_get #define gcry_md_get_algo _gcry_md_get_algo #define gcry_md_get_algo_dlen _gcry_md_get_algo_dlen #define gcry_md_hash_buffer _gcry_md_hash_buffer #define gcry_md_info _gcry_md_info #define gcry_md_is_enabled _gcry_md_is_enabled #define gcry_md_is_secure _gcry_md_is_secure #define gcry_md_map_name _gcry_md_map_name #define gcry_md_open _gcry_md_open #define gcry_md_read _gcry_md_read #define gcry_md_reset _gcry_md_reset #define gcry_md_setkey _gcry_md_setkey #define gcry_md_write _gcry_md_write #define gcry_md_debug _gcry_md_debug #define gcry_cipher_algo_info _gcry_cipher_algo_info #define gcry_cipher_algo_name _gcry_cipher_algo_name #define gcry_cipher_close _gcry_cipher_close #define gcry_cipher_setkey _gcry_cipher_setkey #define gcry_cipher_setiv _gcry_cipher_setiv #define gcry_cipher_setctr _gcry_cipher_setctr #define gcry_cipher_ctl _gcry_cipher_ctl #define gcry_cipher_decrypt _gcry_cipher_decrypt #define gcry_cipher_encrypt _gcry_cipher_encrypt #define gcry_cipher_get_algo_blklen _gcry_cipher_get_algo_blklen #define gcry_cipher_get_algo_keylen _gcry_cipher_get_algo_keylen #define gcry_cipher_info _gcry_cipher_info #define gcry_cipher_map_name _gcry_cipher_map_name #define gcry_cipher_mode_from_oid _gcry_cipher_mode_from_oid #define gcry_cipher_open _gcry_cipher_open #define gcry_pk_algo_info _gcry_pk_algo_info #define gcry_pk_algo_name _gcry_pk_algo_name #define gcry_pk_ctl _gcry_pk_ctl #define gcry_pk_decrypt _gcry_pk_decrypt #define gcry_pk_encrypt _gcry_pk_encrypt #define gcry_pk_genkey _gcry_pk_genkey #define gcry_pk_get_keygrip _gcry_pk_get_keygrip #define gcry_pk_get_curve _gcry_pk_get_curve #define gcry_pk_get_param _gcry_pk_get_param #define gcry_pk_get_nbits _gcry_pk_get_nbits #define gcry_pk_map_name _gcry_pk_map_name #define gcry_pk_sign _gcry_pk_sign #define gcry_pk_testkey _gcry_pk_testkey #define gcry_pk_verify _gcry_pk_verify #define gcry_kdf_derive _gcry_kdf_derive #define gcry_prime_check _gcry_prime_check #define gcry_prime_generate _gcry_prime_generate #define gcry_prime_group_generator _gcry_prime_group_generator #define gcry_prime_release_factors _gcry_prime_release_factors #define gcry_random_add_bytes _gcry_random_add_bytes #define gcry_random_bytes _gcry_random_bytes #define gcry_random_bytes_secure _gcry_random_bytes_secure #define gcry_randomize _gcry_randomize #define gcry_create_nonce _gcry_create_nonce #define gcry_sexp_alist _gcry_sexp_alist #define gcry_sexp_append _gcry_sexp_append #define gcry_sexp_build _gcry_sexp_build #define gcry_sexp_build_array _gcry_sexp_build_array #define gcry_sexp_cadr _gcry_sexp_cadr #define gcry_sexp_canon_len _gcry_sexp_canon_len #define gcry_sexp_car _gcry_sexp_car #define gcry_sexp_cdr _gcry_sexp_cdr #define gcry_sexp_cons _gcry_sexp_cons #define gcry_sexp_create _gcry_sexp_create #define gcry_sexp_dump _gcry_sexp_dump #define gcry_sexp_find_token _gcry_sexp_find_token #define gcry_sexp_length _gcry_sexp_length #define gcry_sexp_new _gcry_sexp_new #define gcry_sexp_nth _gcry_sexp_nth #define gcry_sexp_nth_data _gcry_sexp_nth_data #define gcry_sexp_nth_mpi _gcry_sexp_nth_mpi #define gcry_sexp_prepend _gcry_sexp_prepend #define gcry_sexp_release _gcry_sexp_release #define gcry_sexp_sprint _gcry_sexp_sprint #define gcry_sexp_sscan _gcry_sexp_sscan #define gcry_sexp_vlist _gcry_sexp_vlist #define gcry_sexp_nth_string _gcry_sexp_nth_string #define gcry_mpi_add _gcry_mpi_add #define gcry_mpi_add_ui _gcry_mpi_add_ui #define gcry_mpi_addm _gcry_mpi_addm #define gcry_mpi_aprint _gcry_mpi_aprint #define gcry_mpi_clear_bit _gcry_mpi_clear_bit #define gcry_mpi_clear_flag _gcry_mpi_clear_flag #define gcry_mpi_clear_highbit _gcry_mpi_clear_highbit #define gcry_mpi_cmp _gcry_mpi_cmp #define gcry_mpi_cmp_ui _gcry_mpi_cmp_ui #define gcry_mpi_copy _gcry_mpi_copy #define gcry_mpi_div _gcry_mpi_div #define gcry_mpi_dump _gcry_mpi_dump #define gcry_mpi_gcd _gcry_mpi_gcd #define gcry_mpi_get_flag _gcry_mpi_get_flag #define gcry_mpi_get_nbits _gcry_mpi_get_nbits #define gcry_mpi_get_opaque _gcry_mpi_get_opaque #define gcry_mpi_invm _gcry_mpi_invm #define gcry_mpi_mod _gcry_mpi_mod #define gcry_mpi_mul _gcry_mpi_mul #define gcry_mpi_mul_2exp _gcry_mpi_mul_2exp #define gcry_mpi_mul_ui _gcry_mpi_mul_ui #define gcry_mpi_mulm _gcry_mpi_mulm #define gcry_mpi_new _gcry_mpi_new #define gcry_mpi_point_get _gcry_mpi_point_get #define gcry_mpi_point_new _gcry_mpi_point_new #define gcry_mpi_point_release _gcry_mpi_point_release #define gcry_mpi_point_set _gcry_mpi_point_set #define gcry_mpi_point_snatch_get _gcry_mpi_point_snatch_get #define gcry_mpi_point_snatch_set _gcry_mpi_point_snatch_set #define gcry_mpi_powm _gcry_mpi_powm #define gcry_mpi_print _gcry_mpi_print #define gcry_mpi_randomize _gcry_mpi_randomize #define gcry_mpi_release _gcry_mpi_release #define gcry_mpi_rshift _gcry_mpi_rshift #define gcry_mpi_lshift _gcry_mpi_lshift #define gcry_mpi_scan _gcry_mpi_scan #define gcry_mpi_set _gcry_mpi_set #define gcry_mpi_set_bit _gcry_mpi_set_bit #define gcry_mpi_set_flag _gcry_mpi_set_flag #define gcry_mpi_set_highbit _gcry_mpi_set_highbit #define gcry_mpi_set_opaque _gcry_mpi_set_opaque #define gcry_mpi_set_ui _gcry_mpi_set_ui #define gcry_mpi_snatch _gcry_mpi_snatch #define gcry_mpi_snew _gcry_mpi_snew #define gcry_mpi_sub _gcry_mpi_sub #define gcry_mpi_sub_ui _gcry_mpi_sub_ui #define gcry_mpi_subm _gcry_mpi_subm #define gcry_mpi_swap _gcry_mpi_swap #define gcry_mpi_test_bit _gcry_mpi_test_bit #define gcry_ctx_release _gcry_ctx_release /* Include the main header here so that public symbols are mapped to the internal underscored ones. */ #ifdef _GCRY_INCLUDED_BY_VISIBILITY_C /* We need to redeclare the deprecated functions without the deprecated attribute. */ # define GCRYPT_NO_DEPRECATED -# include "gcrypt.h" +# include "gcrypt-int.h" /* None in this version. */ #else -# include "gcrypt.h" +# include "gcrypt-int.h" #endif #include "gcrypt-module.h" /* Prototypes of functions exported but not ready for use. */ gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo, unsigned char *buffer, int buflen); /* Our use of the ELF visibility feature works by passing -fvisibiliy=hidden on the command line and by explicitly marking all exported functions as visible. NOTE: When adding new functions, please make sure to add them to libgcrypt.vers and libgcrypt.def as well. */ #ifdef _GCRY_INCLUDED_BY_VISIBILITY_C /* A macro to flag a function as visible. Note that we take the definition from the mapped name. */ #ifdef GCRY_USE_VISIBILITY # define MARK_VISIBLE(name) \ extern __typeof__ (_##name) name __attribute__ ((visibility("default"))); # define MARK_VISIBLEX(name) \ extern __typeof__ (name) name __attribute__ ((visibility("default"))); #else # define MARK_VISIBLE(name) /* */ # define MARK_VISIBLEX(name) /* */ #endif /* First undef all redefined symbols so that we set the attribute on the correct version name. */ #undef gcry_check_version #undef gcry_control #undef gcry_set_allocation_handler #undef gcry_set_fatalerror_handler #undef gcry_set_gettext_handler #undef gcry_set_log_handler #undef gcry_set_outofcore_handler #undef gcry_set_progress_handler #undef gcry_err_code_from_errno #undef gcry_err_code_to_errno #undef gcry_err_make_from_errno #undef gcry_error_from_errno #undef gcry_strerror #undef gcry_strsource #undef gcry_free #undef gcry_malloc #undef gcry_malloc_secure #undef gcry_calloc #undef gcry_calloc_secure #undef gcry_realloc #undef gcry_strdup #undef gcry_is_secure #undef gcry_xcalloc #undef gcry_xcalloc_secure #undef gcry_xmalloc #undef gcry_xmalloc_secure #undef gcry_xrealloc #undef gcry_xstrdup #undef gcry_md_algo_info #undef gcry_md_algo_name #undef gcry_md_close #undef gcry_md_copy #undef gcry_md_ctl #undef gcry_md_enable #undef gcry_md_get #undef gcry_md_get_algo #undef gcry_md_get_algo_dlen #undef gcry_md_hash_buffer #undef gcry_md_info #undef gcry_md_is_enabled #undef gcry_md_is_secure #undef gcry_md_map_name #undef gcry_md_open #undef gcry_md_read #undef gcry_md_reset #undef gcry_md_setkey #undef gcry_md_write #undef gcry_md_debug #undef gcry_cipher_algo_info #undef gcry_cipher_algo_name #undef gcry_cipher_close #undef gcry_cipher_setkey #undef gcry_cipher_setiv #undef gcry_cipher_setctr #undef gcry_cipher_ctl #undef gcry_cipher_decrypt #undef gcry_cipher_encrypt #undef gcry_cipher_get_algo_blklen #undef gcry_cipher_get_algo_keylen #undef gcry_cipher_info #undef gcry_cipher_map_name #undef gcry_cipher_mode_from_oid #undef gcry_cipher_open #undef gcry_pk_algo_info #undef gcry_pk_algo_name #undef gcry_pk_ctl #undef gcry_pk_decrypt #undef gcry_pk_encrypt #undef gcry_pk_genkey #undef gcry_pk_get_keygrip #undef gcry_pk_get_curve #undef gcry_pk_get_param #undef gcry_pk_get_nbits #undef gcry_pk_map_name #undef gcry_pk_sign #undef gcry_pk_testkey #undef gcry_pk_verify #undef gcry_kdf_derive #undef gcry_prime_check #undef gcry_prime_generate #undef gcry_prime_group_generator #undef gcry_prime_release_factors #undef gcry_random_add_bytes #undef gcry_random_bytes #undef gcry_random_bytes_secure #undef gcry_randomize #undef gcry_create_nonce #undef gcry_sexp_alist #undef gcry_sexp_append #undef gcry_sexp_build #undef gcry_sexp_build_array #undef gcry_sexp_cadr #undef gcry_sexp_canon_len #undef gcry_sexp_car #undef gcry_sexp_cdr #undef gcry_sexp_cons #undef gcry_sexp_create #undef gcry_sexp_dump #undef gcry_sexp_find_token #undef gcry_sexp_length #undef gcry_sexp_new #undef gcry_sexp_nth #undef gcry_sexp_nth_data #undef gcry_sexp_nth_mpi #undef gcry_sexp_prepend #undef gcry_sexp_release #undef gcry_sexp_sprint #undef gcry_sexp_sscan #undef gcry_sexp_vlist #undef gcry_sexp_nth_string #undef gcry_mpi_add #undef gcry_mpi_add_ui #undef gcry_mpi_addm #undef gcry_mpi_aprint #undef gcry_mpi_clear_bit #undef gcry_mpi_clear_flag #undef gcry_mpi_clear_highbit #undef gcry_mpi_cmp #undef gcry_mpi_cmp_ui #undef gcry_mpi_copy #undef gcry_mpi_div #undef gcry_mpi_dump #undef gcry_mpi_gcd #undef gcry_mpi_get_flag #undef gcry_mpi_get_nbits #undef gcry_mpi_get_opaque #undef gcry_mpi_invm #undef gcry_mpi_mod #undef gcry_mpi_mul #undef gcry_mpi_mul_2exp #undef gcry_mpi_mul_ui #undef gcry_mpi_mulm #undef gcry_mpi_new #undef gcry_mpi_point_get #undef gcry_mpi_point_new #undef gcry_mpi_point_release #undef gcry_mpi_point_set #undef gcry_mpi_point_snatch_get #undef gcry_mpi_point_snatch_set #undef gcry_mpi_powm #undef gcry_mpi_print #undef gcry_mpi_randomize #undef gcry_mpi_release #undef gcry_mpi_rshift #undef gcry_mpi_lshift #undef gcry_mpi_scan #undef gcry_mpi_snatch #undef gcry_mpi_set #undef gcry_mpi_set_bit #undef gcry_mpi_set_flag #undef gcry_mpi_set_highbit #undef gcry_mpi_set_opaque #undef gcry_mpi_set_ui #undef gcry_mpi_snew #undef gcry_mpi_sub #undef gcry_mpi_sub_ui #undef gcry_mpi_subm #undef gcry_mpi_swap #undef gcry_mpi_test_bit #undef gcry_ctx_release /* Now mark all symbols. */ MARK_VISIBLE (gcry_check_version) MARK_VISIBLE (gcry_control) MARK_VISIBLE (gcry_set_allocation_handler) MARK_VISIBLE (gcry_set_fatalerror_handler) MARK_VISIBLE (gcry_set_gettext_handler) MARK_VISIBLE (gcry_set_log_handler) MARK_VISIBLE (gcry_set_outofcore_handler) MARK_VISIBLE (gcry_set_progress_handler) MARK_VISIBLE (gcry_err_code_from_errno) MARK_VISIBLE (gcry_err_code_to_errno) MARK_VISIBLE (gcry_err_make_from_errno) MARK_VISIBLE (gcry_error_from_errno) MARK_VISIBLE (gcry_strerror) MARK_VISIBLE (gcry_strsource) MARK_VISIBLE (gcry_free) MARK_VISIBLE (gcry_malloc) MARK_VISIBLE (gcry_malloc_secure) MARK_VISIBLE (gcry_calloc) MARK_VISIBLE (gcry_calloc_secure) MARK_VISIBLE (gcry_realloc) MARK_VISIBLE (gcry_strdup) MARK_VISIBLE (gcry_is_secure) MARK_VISIBLE (gcry_xcalloc) MARK_VISIBLE (gcry_xcalloc_secure) MARK_VISIBLE (gcry_xmalloc) MARK_VISIBLE (gcry_xmalloc_secure) MARK_VISIBLE (gcry_xrealloc) MARK_VISIBLE (gcry_xstrdup) MARK_VISIBLE (gcry_md_algo_info) MARK_VISIBLE (gcry_md_algo_name) MARK_VISIBLE (gcry_md_close) MARK_VISIBLE (gcry_md_copy) MARK_VISIBLE (gcry_md_ctl) MARK_VISIBLE (gcry_md_enable) MARK_VISIBLE (gcry_md_get) MARK_VISIBLE (gcry_md_get_algo) MARK_VISIBLE (gcry_md_get_algo_dlen) MARK_VISIBLE (gcry_md_hash_buffer) MARK_VISIBLE (gcry_md_info) MARK_VISIBLE (gcry_md_is_enabled) MARK_VISIBLE (gcry_md_is_secure) MARK_VISIBLE (gcry_md_map_name) MARK_VISIBLE (gcry_md_open) MARK_VISIBLE (gcry_md_read) MARK_VISIBLE (gcry_md_reset) MARK_VISIBLE (gcry_md_setkey) MARK_VISIBLE (gcry_md_write) MARK_VISIBLE (gcry_md_debug) MARK_VISIBLE (gcry_cipher_algo_info) MARK_VISIBLE (gcry_cipher_algo_name) MARK_VISIBLE (gcry_cipher_close) MARK_VISIBLE (gcry_cipher_setkey) MARK_VISIBLE (gcry_cipher_setiv) MARK_VISIBLE (gcry_cipher_setctr) MARK_VISIBLE (gcry_cipher_ctl) MARK_VISIBLE (gcry_cipher_decrypt) MARK_VISIBLE (gcry_cipher_encrypt) MARK_VISIBLE (gcry_cipher_get_algo_blklen) MARK_VISIBLE (gcry_cipher_get_algo_keylen) MARK_VISIBLE (gcry_cipher_info) MARK_VISIBLE (gcry_cipher_map_name) MARK_VISIBLE (gcry_cipher_mode_from_oid) MARK_VISIBLE (gcry_cipher_open) MARK_VISIBLE (gcry_pk_algo_info) MARK_VISIBLE (gcry_pk_algo_name) MARK_VISIBLE (gcry_pk_ctl) MARK_VISIBLE (gcry_pk_decrypt) MARK_VISIBLE (gcry_pk_encrypt) MARK_VISIBLE (gcry_pk_genkey) MARK_VISIBLE (gcry_pk_get_keygrip) MARK_VISIBLE (gcry_pk_get_curve) MARK_VISIBLE (gcry_pk_get_param) MARK_VISIBLE (gcry_pk_get_nbits) MARK_VISIBLE (gcry_pk_map_name) MARK_VISIBLE (gcry_pk_sign) MARK_VISIBLE (gcry_pk_testkey) MARK_VISIBLE (gcry_pk_verify) MARK_VISIBLEX(gcry_pubkey_get_sexp) MARK_VISIBLE (gcry_kdf_derive) MARK_VISIBLE (gcry_prime_check) MARK_VISIBLE (gcry_prime_generate) MARK_VISIBLE (gcry_prime_group_generator) MARK_VISIBLE (gcry_prime_release_factors) MARK_VISIBLE (gcry_random_add_bytes) MARK_VISIBLE (gcry_random_bytes) MARK_VISIBLE (gcry_random_bytes_secure) MARK_VISIBLE (gcry_randomize) MARK_VISIBLE (gcry_create_nonce) MARK_VISIBLE (gcry_sexp_alist) MARK_VISIBLE (gcry_sexp_append) MARK_VISIBLE (gcry_sexp_build) MARK_VISIBLE (gcry_sexp_build_array) MARK_VISIBLE (gcry_sexp_cadr) MARK_VISIBLE (gcry_sexp_canon_len) MARK_VISIBLE (gcry_sexp_car) MARK_VISIBLE (gcry_sexp_cdr) MARK_VISIBLE (gcry_sexp_cons) MARK_VISIBLE (gcry_sexp_create) MARK_VISIBLE (gcry_sexp_dump) MARK_VISIBLE (gcry_sexp_find_token) MARK_VISIBLE (gcry_sexp_length) MARK_VISIBLE (gcry_sexp_new) MARK_VISIBLE (gcry_sexp_nth) MARK_VISIBLE (gcry_sexp_nth_data) MARK_VISIBLE (gcry_sexp_nth_mpi) MARK_VISIBLE (gcry_sexp_prepend) MARK_VISIBLE (gcry_sexp_release) MARK_VISIBLE (gcry_sexp_sprint) MARK_VISIBLE (gcry_sexp_sscan) MARK_VISIBLE (gcry_sexp_vlist) MARK_VISIBLE (gcry_sexp_nth_string) MARK_VISIBLE (gcry_mpi_add) MARK_VISIBLE (gcry_mpi_add_ui) MARK_VISIBLE (gcry_mpi_addm) MARK_VISIBLE (gcry_mpi_aprint) MARK_VISIBLE (gcry_mpi_clear_bit) MARK_VISIBLE (gcry_mpi_clear_flag) MARK_VISIBLE (gcry_mpi_clear_highbit) MARK_VISIBLE (gcry_mpi_cmp) MARK_VISIBLE (gcry_mpi_cmp_ui) MARK_VISIBLE (gcry_mpi_copy) MARK_VISIBLE (gcry_mpi_div) MARK_VISIBLE (gcry_mpi_dump) MARK_VISIBLEX(gcry_mpi_ec_add) MARK_VISIBLEX(gcry_mpi_ec_dup) MARK_VISIBLEX(gcry_mpi_ec_get_affine) MARK_VISIBLEX(gcry_mpi_ec_mul) MARK_VISIBLEX(gcry_mpi_ec_new) MARK_VISIBLEX(gcry_mpi_ec_get_mpi) MARK_VISIBLEX(gcry_mpi_ec_get_point) MARK_VISIBLEX(gcry_mpi_ec_set_mpi) MARK_VISIBLEX(gcry_mpi_ec_set_point) MARK_VISIBLE (gcry_mpi_gcd) MARK_VISIBLE (gcry_mpi_get_flag) MARK_VISIBLE (gcry_mpi_get_nbits) MARK_VISIBLE (gcry_mpi_get_opaque) MARK_VISIBLE (gcry_mpi_invm) MARK_VISIBLE (gcry_mpi_mod) MARK_VISIBLE (gcry_mpi_mul) MARK_VISIBLE (gcry_mpi_mul_2exp) MARK_VISIBLE (gcry_mpi_mul_ui) MARK_VISIBLE (gcry_mpi_mulm) MARK_VISIBLE (gcry_mpi_new) MARK_VISIBLE (gcry_mpi_point_get) MARK_VISIBLE (gcry_mpi_point_new) MARK_VISIBLE (gcry_mpi_point_release) MARK_VISIBLE (gcry_mpi_point_set) MARK_VISIBLE (gcry_mpi_point_snatch_get) MARK_VISIBLE (gcry_mpi_point_snatch_set) MARK_VISIBLE (gcry_mpi_powm) MARK_VISIBLE (gcry_mpi_print) MARK_VISIBLE (gcry_mpi_randomize) MARK_VISIBLE (gcry_mpi_release) MARK_VISIBLE (gcry_mpi_rshift) MARK_VISIBLE (gcry_mpi_lshift) MARK_VISIBLE (gcry_mpi_scan) MARK_VISIBLE (gcry_mpi_snatch) MARK_VISIBLE (gcry_mpi_set) MARK_VISIBLE (gcry_mpi_set_bit) MARK_VISIBLE (gcry_mpi_set_flag) MARK_VISIBLE (gcry_mpi_set_highbit) MARK_VISIBLE (gcry_mpi_set_opaque) MARK_VISIBLE (gcry_mpi_set_ui) MARK_VISIBLE (gcry_mpi_snew) MARK_VISIBLE (gcry_mpi_sub) MARK_VISIBLE (gcry_mpi_sub_ui) MARK_VISIBLE (gcry_mpi_subm) MARK_VISIBLE (gcry_mpi_swap) MARK_VISIBLE (gcry_mpi_test_bit) MARK_VISIBLE (gcry_ctx_release) /* Functions used to implement macros. */ MARK_VISIBLEX(_gcry_mpi_get_const) #undef MARK_VISIBLE #endif /*_GCRY_INCLUDED_BY_VISIBILITY_C*/ #endif /*GCRY_VISIBILITY_H*/ diff --git a/tests/aeswrap.c b/tests/aeswrap.c index bb52fc90..16b576d3 100644 --- a/tests/aeswrap.c +++ b/tests/aeswrap.c @@ -1,259 +1,259 @@ /* aeswrap.c - AESWRAP mode regression tests * Copyright (C) 2009 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" static int verbose; static int error_count; static void fail (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); error_count++; } static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void check (int algo, const void *kek, size_t keklen, const void *data, size_t datalen, const void *expected, size_t expectedlen) { gcry_error_t err; gcry_cipher_hd_t hd; unsigned char outbuf[32+8]; size_t outbuflen; err = gcry_cipher_open (&hd, algo, GCRY_CIPHER_MODE_AESWRAP, 0); if (err) { fail ("gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } err = gcry_cipher_setkey (hd, kek, keklen); if (err) { fail ("gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); return; } outbuflen = datalen + 8; if (outbuflen > sizeof outbuf) err = gpg_error (GPG_ERR_INTERNAL); else err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, datalen); if (err) { fail ("gcry_cipher_encrypt failed: %s\n", gpg_strerror (err)); return; } if (outbuflen != expectedlen || memcmp (outbuf, expected, expectedlen)) { const unsigned char *s; int i; fail ("mismatch at encryption!\n"); fprintf (stderr, "computed: "); for (i = 0; i < outbuflen; i++) fprintf (stderr, "%02x ", outbuf[i]); fprintf (stderr, "\nexpected: "); for (s = expected, i = 0; i < expectedlen; s++, i++) fprintf (stderr, "%02x ", *s); putc ('\n', stderr); } outbuflen = expectedlen - 8; if (outbuflen > sizeof outbuf) err = gpg_error (GPG_ERR_INTERNAL); else err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); if (err) { fail ("gcry_cipher_decrypt failed: %s\n", gpg_strerror (err)); return; } if (outbuflen != datalen || memcmp (outbuf, data, datalen)) { const unsigned char *s; int i; fail ("mismatch at decryption!\n"); fprintf (stderr, "computed: "); for (i = 0; i < outbuflen; i++) fprintf (stderr, "%02x ", outbuf[i]); fprintf (stderr, "\nexpected: "); for (s = data, i = 0; i < datalen; s++, i++) fprintf (stderr, "%02x ", *s); putc ('\n', stderr); } /* Now the last step again with a key reset. */ gcry_cipher_reset (hd); outbuflen = expectedlen - 8; if (outbuflen > sizeof outbuf) err = gpg_error (GPG_ERR_INTERNAL); else err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); if (err) { fail ("gcry_cipher_decrypt(2) failed: %s\n", gpg_strerror (err)); return; } if (outbuflen != datalen || memcmp (outbuf, data, datalen)) fail ("mismatch at decryption(2)!\n"); /* And once ore without a key reset. */ outbuflen = expectedlen - 8; if (outbuflen > sizeof outbuf) err = gpg_error (GPG_ERR_INTERNAL); else err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); if (err) { fail ("gcry_cipher_decrypt(3) failed: %s\n", gpg_strerror (err)); return; } if (outbuflen != datalen || memcmp (outbuf, data, datalen)) fail ("mismatch at decryption(3)!\n"); gcry_cipher_close (hd); } static void check_all (void) { if (verbose) fprintf (stderr, "4.1 Wrap 128 bits of Key Data with a 128-bit KEK\n"); check (GCRY_CIPHER_AES128, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16, "\x1F\xA6\x8B\x0A\x81\x12\xB4\x47\xAE\xF3\x4B\xD8\xFB\x5A\x7B\x82" "\x9D\x3E\x86\x23\x71\xD2\xCF\xE5", 24); if (verbose) fprintf (stderr, "4.2 Wrap 128 bits of Key Data with a 192-bit KEK\n"); check (GCRY_CIPHER_AES192, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14\x15\x16\x17", 24, "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16, "\x96\x77\x8B\x25\xAE\x6C\xA4\x35\xF9\x2B\x5B\x97\xC0\x50\xAE\xD2" "\x46\x8A\xB8\xA1\x7A\xD8\x4E\x5D", 24); if (verbose) fprintf (stderr, "4.3 Wrap 128 bits of Key Data with a 256-bit KEK\n"); check (GCRY_CIPHER_AES256, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16, "\x64\xE8\xC3\xF9\xCE\x0F\x5B\xA2\x63\xE9\x77\x79\x05\x81\x8A\x2A" "\x93\xC8\x19\x1E\x7D\x6E\x8A\xE7", 24); if (verbose) fprintf (stderr, "4.4 Wrap 192 bits of Key Data with a 192-bit KEK\n"); check (GCRY_CIPHER_AES192, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14\x15\x16\x17", 24, "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" "\x00\x01\x02\x03\x04\x05\x06\x07", 24, "\x03\x1D\x33\x26\x4E\x15\xD3\x32\x68\xF2\x4E\xC2\x60\x74\x3E\xDC" "\xE1\xC6\xC7\xDD\xEE\x72\x5A\x93\x6B\xA8\x14\x91\x5C\x67\x62\xD2", 32); if (verbose) fprintf (stderr, "4.5 Wrap 192 bits of Key Data with a 256-bit KEK\n"); check (GCRY_CIPHER_AES256, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" "\x00\x01\x02\x03\x04\x05\x06\x07", 24, "\xA8\xF9\xBC\x16\x12\xC6\x8B\x3F\xF6\xE6\xF4\xFB\xE3\x0E\x71\xE4" "\x76\x9C\x8B\x80\xA3\x2C\xB8\x95\x8C\xD5\xD1\x7D\x6B\x25\x4D\xA1", 32); if (verbose) fprintf (stderr, "4.6 Wrap 256 bits of Key Data with a 256-bit KEK\n"); check (GCRY_CIPHER_AES, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 32, "\x28\xC9\xF4\x04\xC4\xB8\x10\xF4\xCB\xCC\xB3\x5C\xFB\x87\xF8\x26" "\x3F\x57\x86\xE2\xD8\x0E\xD3\x26\xCB\xC7\xF0\xE7\x1A\x99\xF4\x3B" "\xFB\x98\x8B\x9B\x7A\x02\xDD\x21", 40); } int main (int argc, char **argv) { int debug = 0; if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) verbose = debug = 1; if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); check_all (); return error_count ? 1 : 0; } diff --git a/tests/basic.c b/tests/basic.c index c92750cd..d1b4002a 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -1,3278 +1,3278 @@ /* basic.c - basic regression tests * Copyright (C) 2001, 2002, 2003, 2005, 2008, * 2009 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" #ifndef DIM # define DIM(v) (sizeof(v)/sizeof((v)[0])) #endif typedef struct test_spec_pubkey_key { const char *secret; const char *public; const char *grip; } test_spec_pubkey_key_t; typedef struct test_spec_pubkey { int id; int flags; test_spec_pubkey_key_t key; } test_spec_pubkey_t; #define FLAG_CRYPT (1 << 0) #define FLAG_SIGN (1 << 1) #define FLAG_GRIP (1 << 2) static int verbose; static int error_count; static int in_fips_mode; static int die_on_error; static void fail (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); error_count++; if (die_on_error) exit (1); } static void mismatch (const void *expected, size_t expectedlen, const void *computed, size_t computedlen) { const unsigned char *p; fprintf (stderr, "expected:"); for (p = expected; expectedlen; p++, expectedlen--) fprintf (stderr, " %02x", *p); fprintf (stderr, "\ncomputed:"); for (p = computed; computedlen; p++, computedlen--) fprintf (stderr, " %02x", *p); fprintf (stderr, "\n"); } static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void show_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; if (prefix) fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = gcry_xmalloc (size); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); gcry_free (buf); } #define MAX_DATA_LEN 100 void progress_handler (void *cb_data, const char *what, int printchar, int current, int total) { (void)cb_data; (void)what; (void)current; (void)total; if (printchar == '\n') fputs ( "", stdout); else putchar (printchar); fflush (stdout); } static void check_cbc_mac_cipher (void) { struct tv { int algo; char key[MAX_DATA_LEN]; unsigned char plaintext[MAX_DATA_LEN]; size_t plaintextlen; char mac[MAX_DATA_LEN]; } tv[] = { { GCRY_CIPHER_AES, "chicken teriyaki", "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0, "\x23\x8f\x6d\xc7\x53\x6a\x62\x97\x11\xc4\xa5\x16\x43\xea\xb0\xb6" }, { GCRY_CIPHER_3DES, "abcdefghABCDEFGH01234567", "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0, "\x5c\x11\xf0\x01\x47\xbd\x3d\x3a" }, { GCRY_CIPHER_DES, "abcdefgh", "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", 0, "\xfa\x4b\xdf\x9d\xfa\xab\x01\x70" } }; gcry_cipher_hd_t hd; unsigned char out[MAX_DATA_LEN]; int i, blklen, keylen; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting CBC MAC checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", tv[i].algo); continue; } err = gcry_cipher_open (&hd, tv[i].algo, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC); if (!hd) { fail ("cbc-mac algo %d, gcry_cipher_open failed: %s\n", tv[i].algo, gpg_strerror (err)); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("cbc-mac algo %d, gcry_cipher_get_algo_blklen failed\n", tv[i].algo); gcry_cipher_close (hd); return; } keylen = gcry_cipher_get_algo_keylen (tv[i].algo); if (!keylen) { fail ("cbc-mac algo %d, gcry_cipher_get_algo_keylen failed\n", tv[i].algo); return; } err = gcry_cipher_setkey (hd, tv[i].key, keylen); if (err) { fail ("cbc-mac algo %d, gcry_cipher_setkey failed: %s\n", tv[i].algo, gpg_strerror (err)); gcry_cipher_close (hd); return; } err = gcry_cipher_setiv (hd, NULL, 0); if (err) { fail ("cbc-mac algo %d, gcry_cipher_setiv failed: %s\n", tv[i].algo, gpg_strerror (err)); gcry_cipher_close (hd); return; } if (verbose) fprintf (stderr, " checking CBC MAC for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_encrypt (hd, out, blklen, tv[i].plaintext, tv[i].plaintextlen ? tv[i].plaintextlen : strlen ((char*)tv[i].plaintext)); if (err) { fail ("cbc-mac algo %d, gcry_cipher_encrypt failed: %s\n", tv[i].algo, gpg_strerror (err)); gcry_cipher_close (hd); return; } #if 0 { int j; for (j = 0; j < gcry_cipher_get_algo_blklen (tv[i].algo); j++) printf ("\\x%02x", out[j] & 0xFF); printf ("\n"); } #endif if (memcmp (tv[i].mac, out, blklen)) fail ("cbc-mac algo %d, encrypt mismatch entry %d\n", tv[i].algo, i); gcry_cipher_close (hd); } if (verbose) fprintf (stderr, " Completed CBC MAC checks.\n"); } static void check_aes128_cbc_cts_cipher (void) { char key[128 / 8] = "chicken teriyaki"; unsigned char plaintext[] = "I would like the General Gau's Chicken, please, and wonton soup."; struct tv { unsigned char out[MAX_DATA_LEN]; int inlen; } tv[] = { { "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f" "\x97", 17 }, { "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22" "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5", 31 }, { "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84", 32 }, { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e" "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5", 47 }, { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8" "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8", 48 }, { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" "\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40" "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8", 64 }, }; gcry_cipher_hd_t hd; unsigned char out[MAX_DATA_LEN]; int i; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting AES128 CBC CTS checks.\n"); err = gcry_cipher_open (&hd, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS); if (err) { fail ("aes-cbc-cts, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } err = gcry_cipher_setkey (hd, key, 128 / 8); if (err) { fail ("aes-cbc-cts, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); return; } for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { err = gcry_cipher_setiv (hd, NULL, 0); if (err) { fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); return; } if (verbose) fprintf (stderr, " checking encryption for length %i\n", tv[i].inlen); err = gcry_cipher_encrypt (hd, out, MAX_DATA_LEN, plaintext, tv[i].inlen); if (err) { fail ("aes-cbc-cts, gcry_cipher_encrypt failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); return; } if (memcmp (tv[i].out, out, tv[i].inlen)) fail ("aes-cbc-cts, encrypt mismatch entry %d\n", i); err = gcry_cipher_setiv (hd, NULL, 0); if (err) { fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); return; } if (verbose) fprintf (stderr, " checking decryption for length %i\n", tv[i].inlen); err = gcry_cipher_decrypt (hd, out, tv[i].inlen, NULL, 0); if (err) { fail ("aes-cbc-cts, gcry_cipher_decrypt failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); return; } if (memcmp (plaintext, out, tv[i].inlen)) fail ("aes-cbc-cts, decrypt mismatch entry %d\n", i); } gcry_cipher_close (hd); if (verbose) fprintf (stderr, " Completed AES128 CBC CTS checks.\n"); } static void check_ctr_cipher (void) { struct tv { int algo; char key[MAX_DATA_LEN]; char ctr[MAX_DATA_LEN]; struct data { unsigned char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; } data[8]; } tv[] = { /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" }, { "", 0, "" } } }, { GCRY_CIPHER_AES192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b" "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" }, { "", 0, "" } } }, { GCRY_CIPHER_AES256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" }, { "", 0, "" } } }, /* Some truncation tests. With a truncated second block and also with a single truncated block. */ { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e", 15, "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" }, {"", 0, "" } } }, { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, {"\xae", 1, "\x98" }, {"", 0, "" } } }, { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17", 15, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6" }, {"", 0, "" } } }, { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b", 1, "\x87" }, {"", 0, "" } } }, /* Tests to see whether it works correctly as a stream cipher. */ { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e", 15, "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" }, {"\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 17, "\xff\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" }, {"\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" }, { "", 0, "" } } }, { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", {{"\x6b", 1, "\x87" }, {"\xc1\xbe", 2, "\x4d\x61" }, {"\xe2\x2e\x40", 3, "\x91\xb6\x20" }, {"\x9f", 1, "\xe3" }, {"\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 9, "\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e", 15, "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd" }, {"\x51\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 9, "\xff\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e" }, { "", 0, "" } } }, #if USE_CAST5 /* A selfmade test vector using an 64 bit block cipher. */ { GCRY_CIPHER_CAST5, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8", {{"\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\xe8\xa7\xac\x68\xca\xca\xa0\x20\x10\xcb\x1b\xcc\x79\x2c\xc4\x48" }, {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c", 8, "\x16\xe8\x72\x77\xb0\x98\x29\x68" }, {"\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 8, "\x9a\xb3\xa8\x03\x3b\xb4\x14\xba" }, {"\xae\x2d\x8a\x57\x1e\x03\xac\x9c\xa1\x00", 10, "\x31\x5e\xd3\xfb\x1b\x8d\xd1\xf9\xb0\x83" }, { "", 0, "" } } }, #endif /*USE_CAST5*/ { 0, "", "", { {"", 0, "" } } } }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; int i, j, keylen, blklen; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting CTR cipher checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (!tv[i].algo) continue; err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); if (err) { fail ("aes-ctr, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("aes-ctr, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-ctr, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("aes-ctr, gcry_cipher_get_algo_blklen failed\n"); return; } err = gcry_cipher_setctr (hde, tv[i].ctr, blklen); if (!err) err = gcry_cipher_setctr (hdd, tv[i].ctr, blklen); if (err) { fail ("aes-ctr, gcry_cipher_setctr failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (verbose) fprintf (stderr, " checking CTR mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); for (j = 0; tv[i].data[j].inlen; j++) { err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].data[j].plaintext, tv[i].data[j].inlen == -1 ? strlen ((char*)tv[i].data[j].plaintext) : tv[i].data[j].inlen); if (err) { fail ("aes-ctr, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) { fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j); mismatch (tv[i].data[j].out, tv[i].data[j].inlen, out, tv[i].data[j].inlen); } err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); if (err) { fail ("aes-ctr, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) { fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j); mismatch (tv[i].data[j].plaintext, tv[i].data[j].inlen, out, tv[i].data[j].inlen); } } /* Now check that we get valid return codes back for good and bad inputs. */ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, "1234567890123456", 16); if (err) fail ("aes-ctr, encryption failed for valid input"); err = gcry_cipher_encrypt (hde, out, 15, "1234567890123456", 16); if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT) fail ("aes-ctr, too short output buffer returned wrong error: %s\n", gpg_strerror (err)); err = gcry_cipher_encrypt (hde, out, 0, "1234567890123456", 16); if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT) fail ("aes-ctr, 0 length output buffer returned wrong error: %s\n", gpg_strerror (err)); err = gcry_cipher_encrypt (hde, out, 16, "1234567890123456", 16); if (err) fail ("aes-ctr, correct length output buffer returned error: %s\n", gpg_strerror (err)); /* Again, now for decryption. */ err = gcry_cipher_decrypt (hde, out, MAX_DATA_LEN, "1234567890123456", 16); if (err) fail ("aes-ctr, decryption failed for valid input"); err = gcry_cipher_decrypt (hde, out, 15, "1234567890123456", 16); if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT) fail ("aes-ctr, too short output buffer returned wrong error: %s\n", gpg_strerror (err)); err = gcry_cipher_decrypt (hde, out, 0, "1234567890123456", 16); if (gpg_err_code (err) != GPG_ERR_BUFFER_TOO_SHORT) fail ("aes-ctr, 0 length output buffer returned wrong error: %s\n", gpg_strerror (err)); err = gcry_cipher_decrypt (hde, out, 16, "1234567890123456", 16); if (err) fail ("aes-ctr, correct length output buffer returned error: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed CTR cipher checks.\n"); } static void check_cfb_cipher (void) { struct tv { int algo; char key[MAX_DATA_LEN]; char iv[MAX_DATA_LEN]; struct data { unsigned char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; } data[MAX_DATA_LEN]; } tv[] = { /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\xc8\xa6\x45\x37\xa0\xb3\xa9\x3f\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b"}, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x26\x75\x1f\x67\xa3\xcb\xb1\x40\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6" }, } }, { GCRY_CIPHER_AES192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b" "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x67\xce\x7f\x7f\x81\x17\x36\x21\x96\x1a\x2b\x70\x17\x1d\x3d\x7a" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0\x42\xae\x8f\xba\x58\x4b\x09\xff" }, } }, { GCRY_CIPHER_AES256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x39\xff\xed\x14\x3b\x28\xb1\xc8\x32\x11\x3c\x63\x31\xe5\x40\x7b" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\xdf\x10\x13\x24\x15\xe5\x4b\x92\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x75\xa3\x85\x74\x1a\xb9\xce\xf8\x20\x31\x62\x3d\x55\xb1\xe4\x71" } } } }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; int i, j, keylen, blklen; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting CFB checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (verbose) fprintf (stderr, " checking CFB mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CFB, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CFB, 0); if (err) { fail ("aes-cfb, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("aes-cfb, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-cfb, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("aes-cfb, gcry_cipher_get_algo_blklen failed\n"); return; } err = gcry_cipher_setiv (hde, tv[i].iv, blklen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, blklen); if (err) { fail ("aes-cfb, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } for (j = 0; tv[i].data[j].inlen; j++) { err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].data[j].plaintext, tv[i].data[j].inlen); if (err) { fail ("aes-cfb, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) { fail ("aes-cfb, encrypt mismatch entry %d:%d\n", i, j); } err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); if (err) { fail ("aes-cfb, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) fail ("aes-cfb, decrypt mismatch entry %d:%d\n", i, j); } gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed CFB checks.\n"); } static void check_ofb_cipher (void) { struct tv { int algo; char key[MAX_DATA_LEN]; char iv[MAX_DATA_LEN]; struct data { unsigned char plaintext[MAX_DATA_LEN]; int inlen; char out[MAX_DATA_LEN]; } data[MAX_DATA_LEN]; } tv[] = { /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ { GCRY_CIPHER_AES, "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5\x3c\x52\xda\xc5\x4e\xd8\x25"}, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43\x44\xf7\xa8\x22\x60\xed\xcc" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x30\x4c\x65\x28\xf6\x59\xc7\x78\x66\xa5\x10\xd9\xc1\xd6\xae\x5e" }, } }, { GCRY_CIPHER_AES192, "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b" "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\xfc\xc2\x8b\x8d\x4c\x63\x83\x7c\x09\xe8\x17\x00\xc1\x10\x04\x01" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x8d\x9a\x9a\xea\xc0\xf6\x59\x6f\x55\x9c\x6d\x4d\xaf\x59\xa5\xf2" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x6d\x9f\x20\x08\x57\xca\x6c\x3e\x9c\xac\x52\x4b\xd9\xac\xc9\x2a" }, } }, { GCRY_CIPHER_AES256, "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" }, { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 16, "\x4f\xeb\xdc\x67\x40\xd2\x0b\x3a\xc8\x8f\x6a\xd8\x2a\x4f\xb0\x8d" }, { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", 16, "\x71\xab\x47\xa0\x86\xe8\x6e\xed\xf3\x9d\x1c\x5b\xba\x97\xc4\x08" }, { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 16, "\x01\x26\x14\x1d\x67\xf3\x7b\xe8\x53\x8f\x5a\x8b\xe7\x40\xe4\x84" } } } }; gcry_cipher_hd_t hde, hdd; unsigned char out[MAX_DATA_LEN]; int i, j, keylen, blklen; gcry_error_t err = 0; if (verbose) fprintf (stderr, " Starting OFB checks.\n"); for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) { if (verbose) fprintf (stderr, " checking OFB mode for %s [%i]\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo); err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0); if (err) { fail ("aes-ofb, gcry_cipher_open failed: %s\n", gpg_strerror (err)); return; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("aes-ofb, gcry_cipher_get_algo_keylen failed\n"); return; } err = gcry_cipher_setkey (hde, tv[i].key, keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, keylen); if (err) { fail ("aes-ofb, gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("aes-ofb, gcry_cipher_get_algo_blklen failed\n"); return; } err = gcry_cipher_setiv (hde, tv[i].iv, blklen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, blklen); if (err) { fail ("aes-ofb, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } for (j = 0; tv[i].data[j].inlen; j++) { err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, tv[i].data[j].plaintext, tv[i].data[j].inlen); if (err) { fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j); err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); if (err) { fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j); } err = gcry_cipher_reset(hde); if (!err) err = gcry_cipher_reset(hdd); if (err) { fail ("aes-ofb, gcry_cipher_reset (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* gcry_cipher_reset clears the IV */ err = gcry_cipher_setiv (hde, tv[i].iv, blklen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, blklen); if (err) { fail ("aes-ofb, gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } /* this time we encrypt and decrypt one byte at a time */ for (j = 0; tv[i].data[j].inlen; j++) { int byteNum; for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum) { err = gcry_cipher_encrypt (hde, out+byteNum, 1, (tv[i].data[j].plaintext) + byteNum, 1); if (err) { fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j); for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum) { err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0); if (err) { fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n", i, j, gpg_strerror (err)); gcry_cipher_close (hde); gcry_cipher_close (hdd); return; } } if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j); } gcry_cipher_close (hde); gcry_cipher_close (hdd); } if (verbose) fprintf (stderr, " Completed OFB checks.\n"); } /* Check that our bulk encryption fucntions work properly. */ static void check_bulk_cipher_modes (void) { struct { int algo; int mode; const char *key; int keylen; const char *iv; int ivlen; char t1_hash[20]; } tv[] = { { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[0]*/ { 0x53, 0xda, 0x27, 0x3c, 0x78, 0x3d, 0x54, 0x66, 0x19, 0x63, 0xd7, 0xe6, 0x20, 0x10, 0xcd, 0xc0, 0x5a, 0x0b, 0x06, 0xcc } }, { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB, "abcdefghijklmnopABCDEFG", 24, "1234567890123456", 16, /*[1]*/ { 0xc7, 0xb1, 0xd0, 0x09, 0x95, 0x04, 0x34, 0x61, 0x2b, 0xd9, 0xcb, 0xb3, 0xc7, 0xcb, 0xef, 0xea, 0x16, 0x19, 0x9b, 0x3e } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[2]*/ { 0x31, 0xe1, 0x1f, 0x63, 0x65, 0x47, 0x8c, 0x3f, 0x53, 0xdb, 0xd9, 0x4d, 0x91, 0x1d, 0x02, 0x9c, 0x05, 0x25, 0x58, 0x29 } }, { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[3]*/ { 0xdc, 0x0c, 0xc2, 0xd9, 0x6b, 0x47, 0xf9, 0xeb, 0x06, 0xb4, 0x2f, 0x6e, 0xec, 0x72, 0xbf, 0x55, 0x26, 0x7f, 0xa9, 0x97 } }, { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC, "abcdefghijklmnopABCDEFG", 24, "1234567890123456", 16, /*[4]*/ { 0x2b, 0x90, 0x9b, 0xe6, 0x40, 0xab, 0x6e, 0xc2, 0xc5, 0xb1, 0x87, 0xf5, 0x43, 0x84, 0x7b, 0x04, 0x06, 0x47, 0xd1, 0x8f } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[5]*/ { 0xaa, 0xa8, 0xdf, 0x03, 0xb0, 0xba, 0xc4, 0xe3, 0xc1, 0x02, 0x38, 0x31, 0x8d, 0x86, 0xcb, 0x49, 0x6d, 0xad, 0xae, 0x01 } }, { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OFB, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[6]*/ { 0x65, 0xfe, 0xde, 0x48, 0xd0, 0xa1, 0xa6, 0xf9, 0x24, 0x6b, 0x52, 0x5f, 0x21, 0x8a, 0x6f, 0xc7, 0x70, 0x3b, 0xd8, 0x4a } }, { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB, "abcdefghijklmnopABCDEFG", 24, "1234567890123456", 16, /*[7]*/ { 0x59, 0x5b, 0x02, 0xa2, 0x88, 0xc0, 0xbe, 0x94, 0x43, 0xaa, 0x39, 0xf6, 0xbd, 0xcc, 0x83, 0x99, 0xee, 0x00, 0xa1, 0x91 } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[8]*/ { 0x38, 0x8c, 0xe1, 0xe2, 0xbe, 0x67, 0x60, 0xe8, 0xeb, 0xce, 0xd0, 0xc6, 0xaa, 0xd6, 0xf6, 0x26, 0x15, 0x56, 0xd0, 0x2b } }, { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[9]*/ { 0x9a, 0x48, 0x94, 0xd6, 0x50, 0x46, 0x81, 0xdb, 0x68, 0x34, 0x3b, 0xc5, 0x9e, 0x66, 0x94, 0x81, 0x98, 0xa0, 0xf9, 0xff } }, { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR, "abcdefghijklmnopABCDEFG", 24, "1234567890123456", 16, /*[10]*/ { 0x2c, 0x2c, 0xd3, 0x75, 0x81, 0x2a, 0x59, 0x07, 0xeb, 0x08, 0xce, 0x28, 0x4c, 0x0c, 0x6a, 0xa8, 0x8f, 0xa3, 0x98, 0x7e } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[11]*/ { 0x64, 0xce, 0x73, 0x03, 0xc7, 0x89, 0x99, 0x1f, 0xf1, 0xce, 0xfe, 0xfb, 0xb9, 0x42, 0x30, 0xdf, 0xbb, 0x68, 0x6f, 0xd3 } }, { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, "abcdefghijklmnop", 16, "1234567890123456", 16, /*[12]*/ { 0x51, 0xae, 0xf5, 0xac, 0x22, 0xa0, 0xba, 0x11, 0xc5, 0xaa, 0xb4, 0x70, 0x99, 0xce, 0x18, 0x08, 0x12, 0x9b, 0xb1, 0xc5 } }, { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB, "abcdefghijklmnopABCDEFG", 24, "1234567890123456", 16, /*[13]*/ { 0x57, 0x91, 0xea, 0x48, 0xd8, 0xbf, 0x9e, 0xc1, 0xae, 0x33, 0xb3, 0xfd, 0xf7, 0x7a, 0xeb, 0x30, 0xb1, 0x62, 0x0d, 0x82 } }, { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB, "abcdefghijklmnopABCDEFGHIJKLMNOP", 32, "1234567890123456", 16, /*[14]*/ { 0x2d, 0x71, 0x54, 0xb9, 0xc5, 0x28, 0x76, 0xff, 0x76, 0xb5, 0x99, 0x37, 0x99, 0x9d, 0xf7, 0x10, 0x6d, 0x86, 0x4f, 0x3f } } }; gcry_cipher_hd_t hde = NULL; gcry_cipher_hd_t hdd = NULL; unsigned char *buffer_base, *outbuf_base; /* Allocated buffers. */ unsigned char *buffer, *outbuf; /* Aligned buffers. */ size_t buflen; unsigned char hash[20]; int i, j, keylen, blklen; gcry_error_t err = 0; if (verbose) fprintf (stderr, "Starting bulk cipher checks.\n"); buflen = 16*100; /* We check a 1600 byte buffer. */ buffer_base = gcry_xmalloc (buflen+16); buffer = buffer_base + (16 - ((size_t)buffer_base & 0x0f)); outbuf_base = gcry_xmalloc (buflen+16); outbuf = outbuf_base + (16 - ((size_t)outbuf_base & 0x0f)); for (i = 0; i < DIM (tv); i++) { if (verbose) fprintf (stderr, " checking bulk encryption for %s [%i], mode %d\n", gcry_cipher_algo_name (tv[i].algo), tv[i].algo, tv[i].mode); err = gcry_cipher_open (&hde, tv[i].algo, tv[i].mode, 0); if (!err) err = gcry_cipher_open (&hdd, tv[i].algo, tv[i].mode, 0); if (err) { fail ("gcry_cipher_open failed: %s\n", gpg_strerror (err)); goto leave; } keylen = gcry_cipher_get_algo_keylen(tv[i].algo); if (!keylen) { fail ("gcry_cipher_get_algo_keylen failed\n"); goto leave; } err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen); if (!err) err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen); if (err) { fail ("gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); goto leave; } blklen = gcry_cipher_get_algo_blklen(tv[i].algo); if (!blklen) { fail ("gcry_cipher_get_algo_blklen failed\n"); goto leave; } err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen); if (!err) err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen); if (err) { fail ("gcry_cipher_setiv failed: %s\n", gpg_strerror (err)); goto leave; } /* Fill the buffer with our test pattern. */ for (j=0; j < buflen; j++) buffer[j] = ((j & 0xff) ^ ((j >> 8) & 0xff)); err = gcry_cipher_encrypt (hde, outbuf, buflen, buffer, buflen); if (err) { fail ("gcry_cipher_encrypt (algo %d, mode %d) failed: %s\n", tv[i].algo, tv[i].mode, gpg_strerror (err)); goto leave; } gcry_md_hash_buffer (GCRY_MD_SHA1, hash, outbuf, buflen); #if 0 printf ("/*[%d]*/\n", i); fputs (" {", stdout); for (j=0; j < 20; j++) printf (" 0x%02x%c%s", hash[j], j==19? ' ':',', j == 9? "\n ":""); puts ("}"); #endif if (memcmp (hash, tv[i].t1_hash, 20)) fail ("encrypt mismatch (algo %d, mode %d)\n", tv[i].algo, tv[i].mode); err = gcry_cipher_decrypt (hdd, outbuf, buflen, NULL, 0); if (err) { fail ("gcry_cipher_decrypt (algo %d, mode %d) failed: %s\n", tv[i].algo, tv[i].mode, gpg_strerror (err)); goto leave; } if (memcmp (buffer, outbuf, buflen)) fail ("decrypt mismatch (algo %d, mode %d)\n", tv[i].algo, tv[i].mode); gcry_cipher_close (hde); hde = NULL; gcry_cipher_close (hdd); hdd = NULL; } if (verbose) fprintf (stderr, "Completed bulk cipher checks.\n"); leave: gcry_cipher_close (hde); gcry_cipher_close (hdd); gcry_free (buffer_base); gcry_free (outbuf_base); } /* The core of the cipher check. In addition to the parameters passed to check_one_cipher it also receives the KEY and the plain data. PASS is printed with error messages. The function returns 0 on success. */ static int check_one_cipher_core (int algo, int mode, int flags, const char *key, size_t nkey, const unsigned char *plain, size_t nplain, int bufshift, int pass) { gcry_cipher_hd_t hd; unsigned char in_buffer[1040+1], out_buffer[1040+1]; unsigned char *in, *out; int keylen; gcry_error_t err = 0; assert (nkey == 32); assert (nplain == 1040); assert (sizeof(in_buffer) == nplain + 1); assert (sizeof(out_buffer) == sizeof(in_buffer)); if (!bufshift) { in = in_buffer; out = out_buffer; } else if (bufshift == 1) { in = in_buffer+1; out = out_buffer; } else if (bufshift == 2) { in = in_buffer+1; out = out_buffer+1; } else { in = in_buffer; out = out_buffer+1; } keylen = gcry_cipher_get_algo_keylen (algo); if (!keylen) { fail ("pass %d, algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n", pass, algo, mode); return -1; } if (keylen < 40 / 8 || keylen > 32) { fail ("pass %d, algo %d, mode %d, keylength problem (%d)\n", pass, algo, mode, keylen); return -1; } err = gcry_cipher_open (&hd, algo, mode, flags); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_open failed: %s\n", pass, algo, mode, gpg_strerror (err)); return -1; } err = gcry_cipher_setkey (hd, key, keylen); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_setkey failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } gcry_cipher_reset (hd); err = gcry_cipher_decrypt (hd, in, nplain, out, nplain); if (err) { fail ("pass %d, algo %d, mode %d, gcry_cipher_decrypt failed: %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } if (memcmp (plain, in, nplain)) fail ("pass %d, algo %d, mode %d, encrypt-decrypt mismatch\n", pass, algo, mode); /* Again, using in-place encryption. */ gcry_cipher_reset (hd); memcpy (out, plain, nplain); err = gcry_cipher_encrypt (hd, out, nplain, NULL, 0); if (err) { fail ("pass %d, algo %d, mode %d, in-place, gcry_cipher_encrypt failed:" " %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } gcry_cipher_reset (hd); err = gcry_cipher_decrypt (hd, out, nplain, NULL, 0); if (err) { fail ("pass %d, algo %d, mode %d, in-place, gcry_cipher_decrypt failed:" " %s\n", pass, algo, mode, gpg_strerror (err)); gcry_cipher_close (hd); return -1; } if (memcmp (plain, out, nplain)) fail ("pass %d, algo %d, mode %d, in-place, encrypt-decrypt mismatch\n", pass, algo, mode); gcry_cipher_close (hd); return 0; } static void check_one_cipher (int algo, int mode, int flags) { char key[32+1]; unsigned char plain[1040+1]; int bufshift, i; for (bufshift=0; bufshift < 4; bufshift++) { /* Pass 0: Standard test. */ memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32); memcpy (plain, "foobar42FOOBAR17", 16); for (i = 16; i < 1040; i += 16) { memcpy (&plain[i], &plain[i-16], 16); if (!++plain[i+7]) plain[i+6]++; if (!++plain[i+15]) plain[i+14]++; } if (check_one_cipher_core (algo, mode, flags, key, 32, plain, 1040, bufshift, 0+10*bufshift)) return; /* Pass 1: Key not aligned. */ memmove (key+1, key, 32); if (check_one_cipher_core (algo, mode, flags, key+1, 32, plain, 1040, bufshift, 1+10*bufshift)) return; /* Pass 2: Key not aligned and data not aligned. */ memmove (plain+1, plain, 1024); if (check_one_cipher_core (algo, mode, flags, key+1, 32, plain+1, 1040, bufshift, 2+10*bufshift)) return; /* Pass 3: Key aligned and data not aligned. */ memmove (key, key+1, 32); if (check_one_cipher_core (algo, mode, flags, key, 32, plain+1, 1040, bufshift, 3+10*bufshift)) return; } return; } static void check_ciphers (void) { static int algos[] = { #if USE_BLOWFISH GCRY_CIPHER_BLOWFISH, #endif #if USE_DES GCRY_CIPHER_DES, GCRY_CIPHER_3DES, #endif #if USE_CAST5 GCRY_CIPHER_CAST5, #endif #if USE_AES GCRY_CIPHER_AES, GCRY_CIPHER_AES192, GCRY_CIPHER_AES256, #endif #if USE_TWOFISH GCRY_CIPHER_TWOFISH, GCRY_CIPHER_TWOFISH128, #endif #if USE_SERPENT GCRY_CIPHER_SERPENT128, GCRY_CIPHER_SERPENT192, GCRY_CIPHER_SERPENT256, #endif #if USE_RFC2268 GCRY_CIPHER_RFC2268_40, #endif #if USE_SEED GCRY_CIPHER_SEED, #endif #if USE_CAMELLIA GCRY_CIPHER_CAMELLIA128, GCRY_CIPHER_CAMELLIA192, GCRY_CIPHER_CAMELLIA256, #endif #if USE_IDEA GCRY_CIPHER_IDEA, #endif 0 }; static int algos2[] = { #if USE_ARCFOUR GCRY_CIPHER_ARCFOUR, #endif 0 }; int i; if (verbose) fprintf (stderr, "Starting Cipher checks.\n"); for (i = 0; algos[i]; i++) { if (gcry_cipher_test_algo (algos[i]) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i]); continue; } if (verbose) fprintf (stderr, " checking %s [%i]\n", gcry_cipher_algo_name (algos[i]), gcry_cipher_map_name (gcry_cipher_algo_name (algos[i]))); check_one_cipher (algos[i], GCRY_CIPHER_MODE_ECB, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_OFB, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS); check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0); } for (i = 0; algos2[i]; i++) { if (gcry_cipher_test_algo (algos[i]) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i]); continue; } if (verbose) fprintf (stderr, " checking `%s'\n", gcry_cipher_algo_name (algos2[i])); check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0); } /* we have now run all cipher's selftests */ if (verbose) fprintf (stderr, "Completed Cipher checks.\n"); /* TODO: add some extra encryption to test the higher level functions */ } static void check_cipher_modes(void) { if (verbose) fprintf (stderr, "Starting Cipher Mode checks.\n"); check_aes128_cbc_cts_cipher (); check_cbc_mac_cipher (); check_ctr_cipher (); check_cfb_cipher (); check_ofb_cipher (); if (verbose) fprintf (stderr, "Completed Cipher Mode checks.\n"); } static void check_one_md (int algo, const char *data, int len, const char *expect) { gcry_md_hd_t hd, hd2; unsigned char *p; int mdlen; int i; gcry_error_t err = 0; err = gcry_md_open (&hd, algo, 0); if (err) { fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); return; } mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 500) { fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); return; } if (*data == '!' && !data[1]) { /* hash one million times a "a" */ char aaa[1000]; /* Write in odd size chunks so that we test the buffering. */ memset (aaa, 'a', 1000); for (i = 0; i < 1000; i++) gcry_md_write (hd, aaa, 1000); } else gcry_md_write (hd, data, len); err = gcry_md_copy (&hd2, hd); if (err) { fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); } gcry_md_close (hd); p = gcry_md_read (hd2, algo); if (memcmp (p, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } gcry_md_close (hd2); } static void check_digests (void) { static struct algos { int md; const char *data; const char *expect; } algos[] = { { GCRY_MD_MD4, "", "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" }, { GCRY_MD_MD4, "a", "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb\x24" }, { GCRY_MD_MD4, "message digest", "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01\x4b" }, { GCRY_MD_MD5, "", "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E" }, { GCRY_MD_MD5, "a", "\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61" }, { GCRY_MD_MD5, "abc", "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72" }, { GCRY_MD_MD5, "message digest", "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0" }, { GCRY_MD_SHA1, "abc", "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E" "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" }, { GCRY_MD_SHA1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE" "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1" }, { GCRY_MD_SHA1, "!" /* kludge for "a"*1000000 */ , "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E" "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" }, /* From RFC3874 */ { GCRY_MD_SHA224, "abc", "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3" "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7" }, { GCRY_MD_SHA224, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50" "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25" }, { GCRY_MD_SHA224, "!", "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b" "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67" }, { GCRY_MD_SHA256, "abc", "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23" "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" }, { GCRY_MD_SHA256, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39" "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" }, { GCRY_MD_SHA256, "!", "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67" "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0" }, { GCRY_MD_SHA384, "abc", "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07" "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed" "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7" }, { GCRY_MD_SHA512, "abc", "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31" "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A" "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD" "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F" }, { GCRY_MD_RMD160, "", "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28" "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" }, { GCRY_MD_RMD160, "a", "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae" "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe" }, { GCRY_MD_RMD160, "abc", "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04" "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc" }, { GCRY_MD_RMD160, "message digest", "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8" "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" }, { GCRY_MD_CRC32, "", "\x00\x00\x00\x00" }, { GCRY_MD_CRC32, "foo", "\x8c\x73\x65\x21" }, { GCRY_MD_CRC32_RFC1510, "", "\x00\x00\x00\x00" }, { GCRY_MD_CRC32_RFC1510, "foo", "\x73\x32\xbc\x33" }, { GCRY_MD_CRC32_RFC1510, "test0123456789", "\xb8\x3e\x88\xd6" }, { GCRY_MD_CRC32_RFC1510, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY", "\xe3\x41\x80\xf7" }, #if 0 { GCRY_MD_CRC32_RFC1510, "\x80\x00", "\x3b\x83\x98\x4b" }, { GCRY_MD_CRC32_RFC1510, "\x00\x08", "\x0e\xdb\x88\x32" }, { GCRY_MD_CRC32_RFC1510, "\x00\x80", "\xed\xb8\x83\x20" }, #endif { GCRY_MD_CRC32_RFC1510, "\x80", "\xed\xb8\x83\x20" }, #if 0 { GCRY_MD_CRC32_RFC1510, "\x80\x00\x00\x00", "\xed\x59\xb6\x3b" }, { GCRY_MD_CRC32_RFC1510, "\x00\x00\x00\x01", "\x77\x07\x30\x96" }, #endif { GCRY_MD_CRC24_RFC2440, "", "\xb7\x04\xce" }, { GCRY_MD_CRC24_RFC2440, "foo", "\x4f\xc2\x55" }, { GCRY_MD_TIGER, "", "\x24\xF0\x13\x0C\x63\xAC\x93\x32\x16\x16\x6E\x76" "\xB1\xBB\x92\x5F\xF3\x73\xDE\x2D\x49\x58\x4E\x7A" }, { GCRY_MD_TIGER, "abc", "\xF2\x58\xC1\xE8\x84\x14\xAB\x2A\x52\x7A\xB5\x41" "\xFF\xC5\xB8\xBF\x93\x5F\x7B\x95\x1C\x13\x29\x51" }, { GCRY_MD_TIGER, "Tiger", "\x9F\x00\xF5\x99\x07\x23\x00\xDD\x27\x6A\xBB\x38" "\xC8\xEB\x6D\xEC\x37\x79\x0C\x11\x6F\x9D\x2B\xDF" }, { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg" "hijklmnopqrstuvwxyz0123456789+-", "\x87\xFB\x2A\x90\x83\x85\x1C\xF7\x47\x0D\x2C\xF8" "\x10\xE6\xDF\x9E\xB5\x86\x44\x50\x34\xA5\xA3\x86" }, { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdef" "ghijklmnopqrstuvwxyz+0123456789", "\x46\x7D\xB8\x08\x63\xEB\xCE\x48\x8D\xF1\xCD\x12" "\x61\x65\x5D\xE9\x57\x89\x65\x65\x97\x5F\x91\x97" }, { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " "by Ross Anderson and Eli Biham", "\x0C\x41\x0A\x04\x29\x68\x86\x8A\x16\x71\xDA\x5A" "\x3F\xD2\x9A\x72\x5E\xC1\xE4\x57\xD3\xCD\xB3\x03" }, { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " "by Ross Anderson and Eli Biham, proceedings of Fa" "st Software Encryption 3, Cambridge.", "\xEB\xF5\x91\xD5\xAF\xA6\x55\xCE\x7F\x22\x89\x4F" "\xF8\x7F\x54\xAC\x89\xC8\x11\xB6\xB0\xDA\x31\x93" }, { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " "by Ross Anderson and Eli Biham, proceedings of Fa" "st Software Encryption 3, Cambridge, 1996.", "\x3D\x9A\xEB\x03\xD1\xBD\x1A\x63\x57\xB2\x77\x4D" "\xFD\x6D\x5B\x24\xDD\x68\x15\x1D\x50\x39\x74\xFC" }, { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh" "ijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRS" "TUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", "\x00\xB8\x3E\xB4\xE5\x34\x40\xC5\x76\xAC\x6A\xAE" "\xE0\xA7\x48\x58\x25\xFD\x15\xE7\x0A\x59\xFF\xE4" }, { GCRY_MD_TIGER1, "", "\x32\x93\xAC\x63\x0C\x13\xF0\x24\x5F\x92\xBB\xB1" "\x76\x6E\x16\x16\x7A\x4E\x58\x49\x2D\xDE\x73\xF3" }, { GCRY_MD_TIGER1, "a", "\x77\xBE\xFB\xEF\x2E\x7E\xF8\xAB\x2E\xC8\xF9\x3B" "\xF5\x87\xA7\xFC\x61\x3E\x24\x7F\x5F\x24\x78\x09" }, { GCRY_MD_TIGER1, "abc", "\x2A\xAB\x14\x84\xE8\xC1\x58\xF2\xBF\xB8\xC5\xFF" "\x41\xB5\x7A\x52\x51\x29\x13\x1C\x95\x7B\x5F\x93" }, { GCRY_MD_TIGER1, "message digest", "\xD9\x81\xF8\xCB\x78\x20\x1A\x95\x0D\xCF\x30\x48" "\x75\x1E\x44\x1C\x51\x7F\xCA\x1A\xA5\x5A\x29\xF6" }, { GCRY_MD_TIGER1, "abcdefghijklmnopqrstuvwxyz", "\x17\x14\xA4\x72\xEE\xE5\x7D\x30\x04\x04\x12\xBF" "\xCC\x55\x03\x2A\x0B\x11\x60\x2F\xF3\x7B\xEE\xE9" }, { GCRY_MD_TIGER1, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\x0F\x7B\xF9\xA1\x9B\x9C\x58\xF2\xB7\x61\x0D\xF7" "\xE8\x4F\x0A\xC3\xA7\x1C\x63\x1E\x7B\x53\xF7\x8E" }, { GCRY_MD_TIGER1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789", "\x8D\xCE\xA6\x80\xA1\x75\x83\xEE\x50\x2B\xA3\x8A" "\x3C\x36\x86\x51\x89\x0F\xFB\xCC\xDC\x49\xA8\xCC" }, { GCRY_MD_TIGER1, "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890", "\x1C\x14\x79\x55\x29\xFD\x9F\x20\x7A\x95\x8F\x84" "\xC5\x2F\x11\xE8\x87\xFA\x0C\xAB\xDF\xD9\x1B\xFD" }, { GCRY_MD_TIGER1, "!", "\x6D\xB0\xE2\x72\x9C\xBE\xAD\x93\xD7\x15\xC6\xA7" "\xD3\x63\x02\xE9\xB3\xCE\xE0\xD2\xBC\x31\x4B\x41" }, { GCRY_MD_TIGER2, "", "\x44\x41\xBE\x75\xF6\x01\x87\x73\xC2\x06\xC2\x27" "\x45\x37\x4B\x92\x4A\xA8\x31\x3F\xEF\x91\x9F\x41" }, { GCRY_MD_TIGER2, "a", "\x67\xE6\xAE\x8E\x9E\x96\x89\x99\xF7\x0A\x23\xE7" "\x2A\xEA\xA9\x25\x1C\xBC\x7C\x78\xA7\x91\x66\x36" }, { GCRY_MD_TIGER2, "abc", "\xF6\x8D\x7B\xC5\xAF\x4B\x43\xA0\x6E\x04\x8D\x78" "\x29\x56\x0D\x4A\x94\x15\x65\x8B\xB0\xB1\xF3\xBF" }, { GCRY_MD_TIGER2, "message digest", "\xE2\x94\x19\xA1\xB5\xFA\x25\x9D\xE8\x00\x5E\x7D" "\xE7\x50\x78\xEA\x81\xA5\x42\xEF\x25\x52\x46\x2D" }, { GCRY_MD_TIGER2, "abcdefghijklmnopqrstuvwxyz", "\xF5\xB6\xB6\xA7\x8C\x40\x5C\x85\x47\xE9\x1C\xD8" "\x62\x4C\xB8\xBE\x83\xFC\x80\x4A\x47\x44\x88\xFD" }, { GCRY_MD_TIGER2, "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "\xA6\x73\x7F\x39\x97\xE8\xFB\xB6\x3D\x20\xD2\xDF" "\x88\xF8\x63\x76\xB5\xFE\x2D\x5C\xE3\x66\x46\xA9" }, { GCRY_MD_TIGER2, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789", "\xEA\x9A\xB6\x22\x8C\xEE\x7B\x51\xB7\x75\x44\xFC" "\xA6\x06\x6C\x8C\xBB\x5B\xBA\xE6\x31\x95\x05\xCD" }, { GCRY_MD_TIGER2, "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890" "1234567890", "\xD8\x52\x78\x11\x53\x29\xEB\xAA\x0E\xEC\x85\xEC" "\xDC\x53\x96\xFD\xA8\xAA\x3A\x58\x20\x94\x2F\xFF" }, { GCRY_MD_TIGER2, "!", "\xE0\x68\x28\x1F\x06\x0F\x55\x16\x28\xCC\x57\x15" "\xB9\xD0\x22\x67\x96\x91\x4D\x45\xF7\x71\x7C\xF4" }, { GCRY_MD_WHIRLPOOL, "", "\x19\xFA\x61\xD7\x55\x22\xA4\x66\x9B\x44\xE3\x9C\x1D\x2E\x17\x26" "\xC5\x30\x23\x21\x30\xD4\x07\xF8\x9A\xFE\xE0\x96\x49\x97\xF7\xA7" "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB\xCF\x88\xE3\xE0\x3C\x4F\x07\x57" "\xEA\x89\x64\xE5\x9B\x63\xD9\x37\x08\xB1\x38\xCC\x42\xA6\x6E\xB3" }, { GCRY_MD_WHIRLPOOL, "a", "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7" "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42" "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59" "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" }, { GCRY_MD_WHIRLPOOL, "a", "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7" "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42" "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59" "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" }, { GCRY_MD_WHIRLPOOL, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B\xF1\x1F\x00\xED\x9A\xBA\x26\x90" "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E" "\x08\xEB\xA2\x66\x29\x12\x9D\x8F\xB7\xCB\x57\x21\x1B\x92\x81\xA6" "\x55\x17\xCC\x87\x9D\x7B\x96\x21\x42\xC6\x5F\x5A\x7A\xF0\x14\x67" }, { GCRY_MD_WHIRLPOOL, "!", "\x0C\x99\x00\x5B\xEB\x57\xEF\xF5\x0A\x7C\xF0\x05\x56\x0D\xDF\x5D" "\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5" "\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD" "\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" }, { 0 }, }; int i; if (verbose) fprintf (stderr, "Starting hash checks.\n"); for (i = 0; algos[i].md; i++) { if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].md); continue; } if (verbose) fprintf (stderr, " checking %s [%i] for length %zi\n", gcry_md_algo_name (algos[i].md), algos[i].md, !strcmp (algos[i].data, "!")? 1000000 : strlen(algos[i].data)); check_one_md (algos[i].md, algos[i].data, strlen (algos[i].data), algos[i].expect); } if (verbose) fprintf (stderr, "Completed hash checks.\n"); } static void check_one_hmac (int algo, const char *data, int datalen, const char *key, int keylen, const char *expect) { gcry_md_hd_t hd, hd2; unsigned char *p; int mdlen; int i; gcry_error_t err = 0; err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC); if (err) { fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); return; } mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 500) { fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); return; } gcry_md_setkey( hd, key, keylen ); gcry_md_write (hd, data, datalen); err = gcry_md_copy (&hd2, hd); if (err) { fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); } gcry_md_close (hd); p = gcry_md_read (hd2, algo); if (!p) fail("algo %d, hmac gcry_md_read failed\n", algo); if (memcmp (p, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, digest mismatch\n", algo); } gcry_md_close (hd2); } static void check_hmac (void) { static struct algos { int md; const char *data; const char *key; const char *expect; } algos[] = { { GCRY_MD_MD5, "what do ya want for nothing?", "Jefe", "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38" }, { GCRY_MD_MD5, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d" }, { GCRY_MD_MD5, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6" }, { GCRY_MD_MD5, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79" }, { GCRY_MD_MD5, "Test With Truncation", "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c" }, { GCRY_MD_MD5, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa", "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd" }, { GCRY_MD_MD5, "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa", "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e", }, { GCRY_MD_SHA256, "what do ya want for nothing?", "Jefe", "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a" "\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43" }, { GCRY_MD_SHA256, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88" "\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7" }, { GCRY_MD_SHA256, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7" "\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe" }, { GCRY_MD_SHA256, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08" "\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b" }, { GCRY_MD_SHA256, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f" "\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54" }, { GCRY_MD_SHA256, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44" "\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2" }, { GCRY_MD_SHA224, "what do ya want for nothing?", "Jefe", "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f" "\x8b\xbe\xa2\xa3\x9e\x61\x48\x00\x8f\xd0\x5e\x44" }, { GCRY_MD_SHA224, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3\x3f\x47" "\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22" }, { GCRY_MD_SHA224, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\x7f\xb3\xcb\x35\x88\xc6\xc1\xf6\xff\xa9\x69\x4d\x7d\x6a\xd2\x64" "\x93\x65\xb0\xc1\xf6\x5d\x69\xd1\xec\x83\x33\xea" }, { GCRY_MD_SHA224, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x6c\x11\x50\x68\x74\x01\x3c\xac\x6a\x2a\xbc\x1b\xb3\x82\x62" "\x7c\xec\x6a\x90\xd8\x6e\xfc\x01\x2d\xe7\xaf\xec\x5a" }, { GCRY_MD_SHA224, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x95\xe9\xa0\xdb\x96\x20\x95\xad\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2" "\xd4\x99\xf1\x12\xf2\xd2\xb7\x27\x3f\xa6\x87\x0e" }, { GCRY_MD_SHA224, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x3a\x85\x41\x66\xac\x5d\x9f\x02\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd" "\x94\x67\x70\xdb\x9c\x2b\x95\xc9\xf6\xf5\x65\xd1" }, { GCRY_MD_SHA384, "what do ya want for nothing?", "Jefe", "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b" "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22\x44\x5e" "\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa\xb2\x16\x49" }, { GCRY_MD_SHA384, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90\x7f\x15" "\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c\xfa\xea" "\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6" }, { GCRY_MD_SHA384, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\x88\x06\x26\x08\xd3\xe6\xad\x8a\x0a\xa2\xac\xe0\x14\xc8\xa8\x6f" "\x0a\xa6\x35\xd9\x47\xac\x9f\xeb\xe8\x3e\xf4\xe5\x59\x66\x14\x4b" "\x2a\x5a\xb3\x9d\xc1\x38\x14\xb9\x4e\x3a\xb6\xe1\x01\xa3\x4f\x27" }, { GCRY_MD_SHA384, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\x3e\x8a\x69\xb7\x78\x3c\x25\x85\x19\x33\xab\x62\x90\xaf\x6c\xa7" "\x7a\x99\x81\x48\x08\x50\x00\x9c\xc5\x57\x7c\x6e\x1f\x57\x3b\x4e" "\x68\x01\xdd\x23\xc4\xa7\xd6\x79\xcc\xf8\xa3\x86\xc6\x74\xcf\xfb" }, { GCRY_MD_SHA384, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x4e\xce\x08\x44\x85\x81\x3e\x90\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4" "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6" "\x0c\x2e\xf6\xab\x40\x30\xfe\x82\x96\x24\x8d\xf1\x63\xf4\x49\x52" }, { GCRY_MD_SHA384, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x66\x17\x17\x8e\x94\x1f\x02\x0d\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c" "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a\xdc\xce\xbb\x82\x46\x1e\x99\xc5" "\xa6\x78\xcc\x31\xe7\x99\x17\x6d\x38\x60\xe6\x11\x0c\x46\x52\x3e" }, { GCRY_MD_SHA512, "what do ya want for nothing?", "Jefe", "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3" "\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54" "\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd" "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37" }, { GCRY_MD_SHA512, "Hi There", "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" "\x0b\x0b\x0b", "\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0" "\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde" "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4" "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54" }, { GCRY_MD_SHA512, "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" "\xdd\xdd\xdd\xdd\xdd", "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" "\xAA\xAA\xAA\xAA", "\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b\xe9" "\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27\x9d\x39" "\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e\x67\xc8\x07" "\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59\xe1\x32\x92\xfb" }, { GCRY_MD_SHA512, "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" "\xcd\xcd\xcd\xcd\xcd", "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", "\xb0\xba\x46\x56\x37\x45\x8c\x69\x90\xe5\xa8\xc5\xf6\x1d\x4a\xf7" "\xe5\x76\xd9\x7f\xf9\x4b\x87\x2d\xe7\x6f\x80\x50\x36\x1e\xe3\xdb" "\xa9\x1c\xa5\xc1\x1a\xa2\x5e\xb4\xd6\x79\x27\x5c\xc5\x78\x80\x63" "\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd" }, { GCRY_MD_SHA512, "Test Using Larger Than Block-Size Key - Hash Key First", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4" "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1\x12\x1b\x01\x37\x83\xf8\xf3\x52" "\x6b\x56\xd0\x37\xe0\x5f\x25\x98\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52" "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98" }, { GCRY_MD_SHA512, "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" "\xaa\xaa\xaa", "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd" "\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44" "\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15" "\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58" }, { 0 }, }; int i; if (verbose) fprintf (stderr, "Starting hashed MAC checks.\n"); for (i = 0; algos[i].md; i++) { if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", algos[i].md); continue; } if (verbose) fprintf (stderr, " checking %s [%i] for %zi byte key and %zi byte data\n", gcry_md_algo_name (algos[i].md), algos[i].md, strlen(algos[i].key), strlen(algos[i].data)); check_one_hmac (algos[i].md, algos[i].data, strlen (algos[i].data), algos[i].key, strlen(algos[i].key), algos[i].expect); } if (verbose) fprintf (stderr, "Completed hashed MAC checks.\n"); } /* Check that the signature SIG matches the hash HASH. PKEY is the public key used for the verification. BADHASH is a hash value which should result in a bad signature status. */ static void verify_one_signature (gcry_sexp_t pkey, gcry_sexp_t hash, gcry_sexp_t badhash, gcry_sexp_t sig) { gcry_error_t rc; rc = gcry_pk_verify (sig, hash, pkey); if (rc) fail ("gcry_pk_verify failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_verify (sig, badhash, pkey); if (gcry_err_code (rc) != GPG_ERR_BAD_SIGNATURE) fail ("gcry_pk_verify failed to detect a bad signature: %s\n", gpg_strerror (rc)); } /* Test the public key sign function using the private ket SKEY. PKEY is used for verification. */ static void check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) { gcry_error_t rc; gcry_sexp_t sig, badhash, hash; int dataidx; static const char baddata[] = "(data\n (flags pkcs1)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n"; static struct { const char *data; int algo; int expected_rc; } datas[] = { { "(data\n (flags pkcs1)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags oaep)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", 0, GPG_ERR_CONFLICT }, /* This test is to see whether hash algorithms not hard wired in pubkey.c are detected: */ { "(data\n (flags pkcs1)\n" " (hash oid.1.3.14.3.2.29 " " #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags )\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", 0, GPG_ERR_CONFLICT }, { "(data\n (flags pkcs1)\n" " (hash foo #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, GPG_ERR_DIGEST_ALGO }, { "(data\n (flags )\n" " (value #11223344556677889900AA#))\n", 0, 0 }, { "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n", 0, 0 }, { "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n", 0, 0 }, { "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", GCRY_PK_RSA, GPG_ERR_CONFLICT }, { "(data\n (flags raw foo)\n" " (value #11223344556677889900AA#))\n", 0, GPG_ERR_INV_FLAG }, { "(data\n (flags pss)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", GCRY_PK_RSA, 0 }, { "(data\n (flags pss)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#)\n" " (random-override #4253647587980912233445566778899019283747#))\n", GCRY_PK_RSA, 0 }, { NULL } }; rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); for (dataidx = 0; datas[dataidx].data; dataidx++) { if (datas[dataidx].algo && datas[dataidx].algo != algo) continue; if (verbose) fprintf (stderr, " test %d, signature test %d\n", n, dataidx); rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data, strlen (datas[dataidx].data)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_sign (&sig, hash, skey); if (gcry_err_code (rc) != datas[dataidx].expected_rc) fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc)); if (!rc) verify_one_signature (pkey, hash, badhash, sig); gcry_sexp_release (sig); sig = NULL; gcry_sexp_release (hash); hash = NULL; } gcry_sexp_release (badhash); } /* Test the public key sign function using the private ket SKEY. PKEY is used for verification. This variant is only used for ECDSA. */ static void check_pubkey_sign_ecdsa (int n, gcry_sexp_t skey, gcry_sexp_t pkey) { gcry_error_t rc; gcry_sexp_t sig, badhash, hash; unsigned int nbits; int dataidx; static struct { unsigned int nbits; const char *data; int expected_rc; const char *baddata; int dummy; } datas[] = { { 256, "(data (flags raw)\n" " (value #00112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))", 0, "(data (flags raw)\n" " (value #80112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))", 0 }, { 192, "(data (flags raw)\n" " (value #00112233445566778899AABBCCDDEEFF0001020304050607#))", 0, "(data (flags raw)\n" " (value #80112233445566778899AABBCCDDEEFF0001020304050607#))", 0 }, { 0, NULL } }; nbits = gcry_pk_get_nbits (skey); for (dataidx = 0; datas[dataidx].data; dataidx++) { if (datas[dataidx].nbits != nbits) continue; if (verbose) fprintf (stderr, " test %d, signature test %d (%u bit ecdsa)\n", n, dataidx, nbits); rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data, strlen (datas[dataidx].data)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); rc = gcry_sexp_sscan (&badhash, NULL, datas[dataidx].baddata, strlen (datas[dataidx].baddata)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_sign (&sig, hash, skey); if (gcry_err_code (rc) != datas[dataidx].expected_rc) fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc)); if (!rc && verbose > 1) show_sexp ("ECDSA signature:\n", sig); if (!rc) verify_one_signature (pkey, hash, badhash, sig); gcry_sexp_release (sig); sig = NULL; gcry_sexp_release (badhash); badhash = NULL; gcry_sexp_release (hash); hash = NULL; } } static void check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) { gcry_error_t rc; gcry_sexp_t plain, ciph, data; int dataidx; static struct { int algo; /* If not 0 run test only if ALGO matches. */ const char *data; const char *hint; int unpadded; int encrypt_expected_rc; int decrypt_expected_rc; } datas[] = { { GCRY_PK_RSA, "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", NULL, 0, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags pkcs1)\n" " (value #11223344556677889900AA#))\n", "(flags pkcs1)", 1, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags oaep)\n" " (value #11223344556677889900AA#))\n", "(flags oaep)", 1, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags oaep)\n (hash-algo sha1)\n" " (value #11223344556677889900AA#))\n", "(flags oaep)(hash-algo sha1)", 1, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n" " (value #11223344556677889900AA#))\n", "(flags oaep)(hash-algo sha1)(label \"test\")", 1, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags oaep)\n (hash-algo sha1)\n (label \"test\")\n" " (value #11223344556677889900AA#)\n" " (random-override #4253647587980912233445566778899019283747#))\n", "(flags oaep)(hash-algo sha1)(label \"test\")", 1, 0, 0 }, { 0, "(data\n (flags )\n" " (value #11223344556677889900AA#))\n", NULL, 1, 0, 0 }, { 0, "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n", NULL, 1, 0, 0 }, { 0, "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n", NULL, 1, 0, 0 }, { GCRY_PK_RSA, "(data\n (flags pkcs1)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", NULL, 0, GPG_ERR_CONFLICT, 0}, { 0, "(data\n (flags raw foo)\n" " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", NULL, 0, GPG_ERR_INV_FLAG, 0}, { 0, "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n", "(flags oaep)", 1, 0, GPG_ERR_ENCODING_PROBLEM }, { GCRY_PK_RSA, "(data\n (flags oaep)\n" " (value #11223344556677889900AA#))\n", "(flags pkcs1)", 1, 0, GPG_ERR_ENCODING_PROBLEM }, { 0, "(data\n (flags pss)\n" " (value #11223344556677889900AA#))\n", NULL, 0, GPG_ERR_CONFLICT }, { 0, NULL } }; (void)n; for (dataidx = 0; datas[dataidx].data; dataidx++) { if (datas[dataidx].algo && datas[dataidx].algo != algo) continue; if (verbose) fprintf (stderr, " encryption/decryption test %d (algo %d)\n", dataidx, algo); rc = gcry_sexp_sscan (&data, NULL, datas[dataidx].data, strlen (datas[dataidx].data)); if (rc) die ("converting data failed: %s\n", gpg_strerror (rc)); rc = gcry_pk_encrypt (&ciph, data, pkey); if (gcry_err_code (rc) != datas[dataidx].encrypt_expected_rc) fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (rc)); if (!rc) { /* Insert decoding hint to CIPH. */ if (datas[dataidx].hint) { size_t hint_len, len; char *hint, *buf; gcry_sexp_t list; /* Convert decoding hint into canonical sexp. */ hint_len = gcry_sexp_new (&list, datas[dataidx].hint, strlen (datas[dataidx].hint), 1); hint_len = gcry_sexp_sprint (list, GCRYSEXP_FMT_CANON, NULL, 0); hint = gcry_malloc (hint_len); if (!hint) die ("can't allocate memory\n"); hint_len = gcry_sexp_sprint (list, GCRYSEXP_FMT_CANON, hint, hint_len); gcry_sexp_release (list); /* Convert CIPH into canonical sexp. */ len = gcry_sexp_sprint (ciph, GCRYSEXP_FMT_CANON, NULL, 0); buf = gcry_malloc (len + hint_len); if (!buf) die ("can't allocate memory\n"); len = gcry_sexp_sprint (ciph, GCRYSEXP_FMT_CANON, buf, len); /* assert (!strcmp (buf, "(7:enc-val", 10)); */ /* Copy decoding hint into CIPH. */ memmove (buf + 10 + hint_len, buf + 10, len - 10); memcpy (buf + 10, hint, hint_len); gcry_free (hint); gcry_sexp_new (&list, buf, len + hint_len, 1); gcry_free (buf); gcry_sexp_release (ciph); ciph = list; } rc = gcry_pk_decrypt (&plain, ciph, skey); if (gcry_err_code (rc) != datas[dataidx].decrypt_expected_rc) fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (rc)); if (!rc && datas[dataidx].unpadded) { gcry_sexp_t p1, p2; p1 = gcry_sexp_find_token (data, "value", 0); p2 = gcry_sexp_find_token (plain, "value", 0); if (p1 && p2) { const char *s1, *s2; size_t n1, n2; s1 = gcry_sexp_nth_data (p1, 1, &n1); s2 = gcry_sexp_nth_data (p2, 1, &n2); if (n1 != n2 || memcmp (s1, s2, n1)) fail ("gcry_pk_encrypt/gcry_pk_decrypt do not roundtrip\n"); } gcry_sexp_release (p1); gcry_sexp_release (p2); } } gcry_sexp_release (plain); plain = NULL; gcry_sexp_release (ciph); ciph = NULL; gcry_sexp_release (data); data = NULL; } } static void check_pubkey_grip (int n, const unsigned char *grip, gcry_sexp_t skey, gcry_sexp_t pkey, int algo) { unsigned char sgrip[20], pgrip[20]; (void)algo; if (!gcry_pk_get_keygrip (skey, sgrip)) die ("get keygrip for private RSA key failed\n"); if (!gcry_pk_get_keygrip (pkey, pgrip)) die ("[%i] get keygrip for public RSA key failed\n", n); if (memcmp (sgrip, pgrip, 20)) fail ("[%i] keygrips don't match\n", n); if (memcmp (sgrip, grip, 20)) fail ("wrong keygrip for RSA key\n"); } static void do_check_one_pubkey (int n, gcry_sexp_t skey, gcry_sexp_t pkey, const unsigned char *grip, int algo, int flags) { if (flags & FLAG_SIGN) { if (algo == GCRY_PK_ECDSA) check_pubkey_sign_ecdsa (n, skey, pkey); else check_pubkey_sign (n, skey, pkey, algo); } if (flags & FLAG_CRYPT) check_pubkey_crypt (n, skey, pkey, algo); if (grip && (flags & FLAG_GRIP)) check_pubkey_grip (n, grip, skey, pkey, algo); } static void check_one_pubkey (int n, test_spec_pubkey_t spec) { gcry_error_t err = GPG_ERR_NO_ERROR; gcry_sexp_t skey, pkey; err = gcry_sexp_sscan (&skey, NULL, spec.key.secret, strlen (spec.key.secret)); if (!err) err = gcry_sexp_sscan (&pkey, NULL, spec.key.public, strlen (spec.key.public)); if (err) die ("converting sample key failed: %s\n", gpg_strerror (err)); do_check_one_pubkey (n, skey, pkey, (const unsigned char*)spec.key.grip, spec.id, spec.flags); gcry_sexp_release (skey); gcry_sexp_release (pkey); } static void get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; if (verbose) fprintf (stderr, " generating RSA key:"); rc = gcry_sexp_new (&key_spec, in_fips_mode ? "(genkey (rsa (nbits 4:1024)))" : "(genkey (rsa (nbits 4:1024)(transient-key)))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gpg_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (rc) die ("error generating RSA key: %s\n", gpg_strerror (rc)); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (! pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (! sec_key) die ("private part missing in key\n"); gcry_sexp_release (key); *pkey = pub_key; *skey = sec_key; } static void check_one_pubkey_new (int n) { gcry_sexp_t skey, pkey; get_keys_new (&pkey, &skey); do_check_one_pubkey (n, skey, pkey, NULL, GCRY_PK_RSA, FLAG_SIGN | FLAG_CRYPT); gcry_sexp_release (pkey); gcry_sexp_release (skey); } /* Run all tests for the public key functions. */ static void check_pubkey (void) { test_spec_pubkey_t pubkeys[] = { { GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN, { "(private-key\n" " (rsa\n" " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" " 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" " ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" " 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea2" " 51#)\n" " (e #010001#)\n" " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" " 7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" " C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" " C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781" " #)\n" " (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" " fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424" " f1#)\n" " (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" " 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad3" " 61#)\n" " (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" " ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b" " #)))\n", "(public-key\n" " (rsa\n" " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" " 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" " ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" " 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea2" " 51#)\n" " (e #010001#)))\n", "\x32\x10\x0c\x27\x17\x3e\xf6\xe9\xc4\xe9" "\xa2\x5d\x3d\x69\xf8\x6d\x37\xa4\xf9\x39"} }, { GCRY_PK_DSA, FLAG_SIGN, { "(private-key\n" " (DSA\n" " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" " 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" " CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" " 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D877" " 7B#)\n" " (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n" " (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" " AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" " B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" " 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15" " #)\n" " (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" " A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB" " #)\n" " (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))\n", "(public-key\n" " (DSA\n" " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" " 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" " CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" " 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D877" " 7B#)\n" " (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n" " (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" " AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" " B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" " 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15" " #)\n" " (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" " A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB" " #)))\n", "\xc6\x39\x83\x1a\x43\xe5\x05\x5d\xc6\xd8" "\x4a\xa6\xf9\xeb\x23\xbf\xa9\x12\x2d\x5b" } }, { GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT, { "(private-key\n" " (ELG\n" " (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D" " F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517" " B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797" " 6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2" " A7#)\n" " (g #05#)\n" " (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B" " E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B" " D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675" " 56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4" " #)\n" " (x #03C28900087B38DABF4A0AB98ACEA39BB674D6557096C01D72E31C16BDD32214" " #)))\n", "(public-key\n" " (ELG\n" " (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D" " F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517" " B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797" " 6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2" " A7#)\n" " (g #05#)\n" " (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B" " E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B" " D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675" " 56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4" " #)))\n", "\xa7\x99\x61\xeb\x88\x83\xd2\xf4\x05\xc8" "\x4f\xba\x06\xf8\x78\x09\xbc\x1e\x20\xe5" } }, { /* ECDSA test. */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecdsa\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n" " (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n", "(public-key\n" " (ecdsa\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* ECDSA test with the public key algorithm given as "ecc". */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecdsa\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n" " (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n", "(public-key\n" " (ecc\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* ECDSA test with the private key algorithm given as "ecc". */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecc\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n" " (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n", "(public-key\n" " (ecdsa\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* ECDSA test with the key algorithms given as "ecc". */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecc\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n" " (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n", "(public-key\n" " (ecc\n" " (curve nistp192)\n" " (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE" " C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n", "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } }, { /* ECDSA test 256 bit. */ GCRY_PK_ECDSA, FLAG_SIGN, { "(private-key\n" " (ecc\n" " (curve nistp256)\n" " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2B" " EB6644D3609FC781B71F9A8072F58CB66AE2F89BB1245187" " 3ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n" " (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F74" " 4715E1D5BBE70378#)))\n", "(public-key\n" " (ecc\n" " (curve nistp256)\n" " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2B" " EB6644D3609FC781B71F9A8072F58CB66AE2F89BB1245187" " 3ABF7D91F9E1FBF96BF2F70E73AAC9A283#)))\n" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } } }; int i; if (verbose) fprintf (stderr, "Starting public key checks.\n"); for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++) if (pubkeys[i].id) { if (gcry_pk_test_algo (pubkeys[i].id) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", pubkeys[i].id); continue; } check_one_pubkey (i, pubkeys[i]); } if (verbose) fprintf (stderr, "Completed public key checks.\n"); if (verbose) fprintf (stderr, "Starting additional public key checks.\n"); for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++) if (pubkeys[i].id) { if (gcry_pk_test_algo (pubkeys[i].id) && in_fips_mode) { if (verbose) fprintf (stderr, " algorithm %d not available in fips mode\n", pubkeys[i].id); continue; } check_one_pubkey_new (i); } if (verbose) fprintf (stderr, "Completed additional public key checks.\n"); } int main (int argc, char **argv) { gpg_error_t err; int last_argc = -1; int debug = 0; int use_fips = 0; int selftest_only = 0; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--verbose")) { verbose++; argc--; argv++; } else if (!strcmp (*argv, "--debug")) { verbose = debug = 1; argc--; argv++; } else if (!strcmp (*argv, "--fips")) { use_fips = 1; argc--; argv++; } else if (!strcmp (*argv, "--selftest")) { selftest_only = 1; verbose += 2; argc--; argv++; } else if (!strcmp (*argv, "--die")) { die_on_error = 1; argc--; argv++; } } gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); if (use_fips) gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); /* Check that we test exactly our version - including the patchlevel. */ if (strcmp (GCRYPT_VERSION, gcry_check_version (NULL))) die ("version mismatch; pgm=%s, library=%s\n", GCRYPT_VERSION,gcry_check_version (NULL)); if ( gcry_fips_mode_active () ) in_fips_mode = 1; if (!in_fips_mode) gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (verbose) gcry_set_progress_handler (progress_handler, NULL); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); /* No valuable keys are create, so we can speed up our RNG. */ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); if (!selftest_only) { check_ciphers (); check_cipher_modes (); check_bulk_cipher_modes (); check_digests (); check_hmac (); check_pubkey (); } if (in_fips_mode && !selftest_only) { /* If we are in fips mode do some more tests. */ gcry_md_hd_t md; /* First trigger a self-test. */ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("not in operational state after self-test\n"); /* Get us into the error state. */ err = gcry_md_open (&md, GCRY_MD_SHA1, 0); if (err) fail ("failed to open SHA-1 hash context: %s\n", gpg_strerror (err)); else { err = gcry_md_enable (md, GCRY_MD_SHA256); if (err) fail ("failed to add SHA-256 hash context: %s\n", gpg_strerror (err)); else { /* gcry_md_get_algo is only defined for a context with just one digest algorithm. With our setup it should put the oibrary intoerror state. */ fputs ("Note: Two lines with error messages follow " "- this is expected\n", stderr); gcry_md_get_algo (md); gcry_md_close (md); if (gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("expected error state but still in operational state\n"); else { /* Now run a self-test and to get back into operational state. */ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("did not reach operational after error " "and self-test\n"); } } } } else { /* If in standard mode, run selftests. */ if (gcry_control (GCRYCTL_SELFTEST, 0)) fail ("running self-test failed\n"); } if (verbose) fprintf (stderr, "\nAll tests completed. Errors: %i\n", error_count); if (in_fips_mode && !gcry_fips_mode_active ()) fprintf (stderr, "FIPS mode is not anymore active\n"); return error_count ? 1 : 0; } diff --git a/tests/benchmark.c b/tests/benchmark.c index 61badd5d..c4b52589 100644 --- a/tests/benchmark.c +++ b/tests/benchmark.c @@ -1,1341 +1,1341 @@ /* benchmark.c - for libgcrypt * Copyright (C) 2002, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser general Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #ifdef _WIN32 #include #else #include #endif #ifdef _GCRYPT_IN_LIBGCRYPT -# include "../src/gcrypt.h" +# include "../src/gcrypt-int.h" # include "../compat/libcompat.h" #else # include #endif #define PGM "benchmark" static int verbose; /* Do encryption tests with large buffers. */ static int large_buffers; /* Number of cipher repetitions. */ static int cipher_repetitions; /* Number of hash repetitions. */ static int hash_repetitions; /* Alignment of the buffers. */ static int buffer_alignment; /* Whether to include the keysetup in the cipher timings. */ static int cipher_with_keysetup; /* Whether fips mode was active at startup. */ static int in_fips_mode; static const char sample_private_dsa_key_1024[] = "(private-key\n" " (dsa\n" " (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685" "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A" "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF" "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n" " (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n" " (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622" "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312" "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3" "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n" " (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4" "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6" "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155" "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n" " (x #4186F8A58C5DF46C5BCFC7006BEEBF05E93C0CA7#)\n" "))\n"; static const char sample_public_dsa_key_1024[] = "(public-key\n" " (dsa\n" " (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685" "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A" "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF" "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n" " (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n" " (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622" "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312" "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3" "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n" " (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4" "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6" "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155" "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n" "))\n"; static const char sample_private_dsa_key_2048[] = "(private-key\n" " (dsa\n" " (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365" "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C" "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150" "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970" "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405" "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179" "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4" "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n" " (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n" " (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78" "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3" "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F" "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508" "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F" "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44" "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3" "6EE4425A553AF8885FEA15A88135BE133520#)\n" " (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C" "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB" "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79" "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F" "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3" "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923" "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7" "14A264330AECCB24DE2A1107847B23490897#)\n" " (x #477BD14676E22563C5ABA68025CEBA2A48D485F5B2D4AD4C0EBBD6D0#)\n" "))\n"; static const char sample_public_dsa_key_2048[] = "(public-key\n" " (dsa\n" " (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365" "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C" "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150" "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970" "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405" "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179" "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4" "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n" " (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n" " (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78" "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3" "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F" "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508" "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F" "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44" "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3" "6EE4425A553AF8885FEA15A88135BE133520#)\n" " (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C" "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB" "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79" "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F" "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3" "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923" "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7" "14A264330AECCB24DE2A1107847B23490897#)\n" "))\n"; static const char sample_private_dsa_key_3072[] = "(private-key\n" " (dsa\n" " (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938" "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5" "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83" "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988" "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46" "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2" "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902" "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60" "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E" "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7" "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33" "8015353D3778B02B892AF7#)\n" " (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n" " (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4" "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474" "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98" "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC" "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C" "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89" "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB" "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6" "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0" "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F" "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC" "4997AF9EB55C6660B01A#)\n" " (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE" "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053" "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492" "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15" "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71" "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997" "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026" "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B" "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD" "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765" "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561" "2703D518D8D49FF0EBE6#)\n" " (x #00A9FFFC88E67D6F7B810E291C050BAFEA7FC4A75E8D2F16CFED3416FD77607232#)\n" "))\n"; static const char sample_public_dsa_key_3072[] = "(public-key\n" " (dsa\n" " (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938" "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5" "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83" "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988" "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46" "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2" "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902" "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60" "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E" "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7" "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33" "8015353D3778B02B892AF7#)\n" " (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n" " (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4" "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474" "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98" "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC" "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C" "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89" "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB" "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6" "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0" "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F" "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC" "4997AF9EB55C6660B01A#)\n" " (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE" "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053" "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492" "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15" "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71" "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997" "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026" "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B" "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD" "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765" "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561" "2703D518D8D49FF0EBE6#)\n" "))\n"; #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) #define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\ exit(2);} while(0) /* Helper for the start and stop timer. */ #ifdef _WIN32 struct { FILETIME creation_time, exit_time, kernel_time, user_time; } started_at, stopped_at; #else static clock_t started_at, stopped_at; #endif static void die (const char *format, ...) { va_list arg_ptr ; va_start( arg_ptr, format ) ; putchar ('\n'); fputs ( PGM ": ", stderr); vfprintf (stderr, format, arg_ptr ); va_end(arg_ptr); exit (1); } static void show_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = malloc (size); if (!buf) die ("out of core\n"); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); } static void start_timer (void) { #ifdef _WIN32 #ifdef __MINGW32CE__ GetThreadTimes (GetCurrentThread (), &started_at.creation_time, &started_at.exit_time, &started_at.kernel_time, &started_at.user_time); #else GetProcessTimes (GetCurrentProcess (), &started_at.creation_time, &started_at.exit_time, &started_at.kernel_time, &started_at.user_time); #endif stopped_at = started_at; #else struct tms tmp; times (&tmp); started_at = stopped_at = tmp.tms_utime; #endif } static void stop_timer (void) { #ifdef _WIN32 #ifdef __MINGW32CE__ GetThreadTimes (GetCurrentThread (), &stopped_at.creation_time, &stopped_at.exit_time, &stopped_at.kernel_time, &stopped_at.user_time); #else GetProcessTimes (GetCurrentProcess (), &stopped_at.creation_time, &stopped_at.exit_time, &stopped_at.kernel_time, &stopped_at.user_time); #endif #else struct tms tmp; times (&tmp); stopped_at = tmp.tms_utime; #endif } static const char * elapsed_time (void) { static char buf[50]; #if _WIN32 unsigned long long t1, t2, t; t1 = (((unsigned long long)started_at.kernel_time.dwHighDateTime << 32) + started_at.kernel_time.dwLowDateTime); t1 += (((unsigned long long)started_at.user_time.dwHighDateTime << 32) + started_at.user_time.dwLowDateTime); t2 = (((unsigned long long)stopped_at.kernel_time.dwHighDateTime << 32) + stopped_at.kernel_time.dwLowDateTime); t2 += (((unsigned long long)stopped_at.user_time.dwHighDateTime << 32) + stopped_at.user_time.dwLowDateTime); t = (t2 - t1)/10000; snprintf (buf, sizeof buf, "%5.0fms", (double)t ); #else snprintf (buf, sizeof buf, "%5.0fms", (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000); #endif return buf; } static void progress_cb (void *cb_data, const char *what, int printchar, int current, int total) { (void)cb_data; fprintf (stderr, PGM ": progress (%s %c %d %d)\n", what, printchar, current, total); fflush (stderr); } static void random_bench (int very_strong) { char buf[128]; int i; printf ("%-10s", "random"); if (!very_strong) { start_timer (); for (i=0; i < 100; i++) gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM); stop_timer (); printf (" %s", elapsed_time ()); } start_timer (); for (i=0; i < 100; i++) gcry_randomize (buf, 8, very_strong? GCRY_VERY_STRONG_RANDOM:GCRY_STRONG_RANDOM); stop_timer (); printf (" %s", elapsed_time ()); putchar ('\n'); if (verbose) gcry_control (GCRYCTL_DUMP_RANDOM_STATS); } static void md_bench ( const char *algoname ) { int algo; gcry_md_hd_t hd; int i, j, repcount; char buf_base[1000+15]; size_t bufsize = 1000; char *buf; char *largebuf_base; char *largebuf; char digest[512/8]; gcry_error_t err = GPG_ERR_NO_ERROR; if (!algoname) { for (i=1; i < 400; i++) if (in_fips_mode && i == GCRY_MD_MD5) ; /* Don't use MD5 in fips mode. */ else if ( !gcry_md_test_algo (i) ) md_bench (gcry_md_algo_name (i)); return; } buf = buf_base + ((16 - ((size_t)buf_base & 0x0f)) % buffer_alignment); algo = gcry_md_map_name (algoname); if (!algo) { fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname); exit (1); } err = gcry_md_open (&hd, algo, 0); if (err) { fprintf (stderr, PGM ": error opening hash algorithm `%s'\n", algoname); exit (1); } for (i=0; i < bufsize; i++) buf[i] = i; printf ("%-12s", gcry_md_algo_name (algo)); start_timer (); for (repcount=0; repcount < hash_repetitions; repcount++) for (i=0; i < 1000; i++) gcry_md_write (hd, buf, bufsize); gcry_md_final (hd); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); gcry_md_reset (hd); start_timer (); for (repcount=0; repcount < hash_repetitions; repcount++) for (i=0; i < 10000; i++) gcry_md_write (hd, buf, bufsize/10); gcry_md_final (hd); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); gcry_md_reset (hd); start_timer (); for (repcount=0; repcount < hash_repetitions; repcount++) for (i=0; i < 1000000; i++) gcry_md_write (hd, buf, 1); gcry_md_final (hd); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); start_timer (); for (repcount=0; repcount < hash_repetitions; repcount++) for (i=0; i < 1000; i++) for (j=0; j < bufsize; j++) gcry_md_putc (hd, buf[j]); gcry_md_final (hd); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); gcry_md_close (hd); /* Now 100 hash operations on 10000 bytes using the fast function. We initialize the buffer so that all memory pages are committed and we have repeatable values. */ if (gcry_md_get_algo_dlen (algo) > sizeof digest) die ("digest buffer too short\n"); largebuf_base = malloc (10000+15); if (!largebuf_base) die ("out of core\n"); largebuf = (largebuf_base + ((16 - ((size_t)largebuf_base & 0x0f)) % buffer_alignment)); for (i=0; i < 10000; i++) largebuf[i] = i; start_timer (); for (repcount=0; repcount < hash_repetitions; repcount++) for (i=0; i < 100; i++) gcry_md_hash_buffer (algo, digest, largebuf, 10000); stop_timer (); printf (" %s", elapsed_time ()); free (largebuf_base); putchar ('\n'); fflush (stdout); } static void cipher_bench ( const char *algoname ) { static int header_printed; int algo; gcry_cipher_hd_t hd; int i; int keylen, blklen; char key[128]; char *outbuf, *buf; char *raw_outbuf, *raw_buf; size_t allocated_buflen, buflen; int repetitions; static struct { int mode; const char *name; int blocked; } modes[] = { { GCRY_CIPHER_MODE_ECB, " ECB/Stream", 1 }, { GCRY_CIPHER_MODE_CBC, " CBC", 1 }, { GCRY_CIPHER_MODE_CFB, " CFB", 0 }, { GCRY_CIPHER_MODE_OFB, " OFB", 0 }, { GCRY_CIPHER_MODE_CTR, " CTR", 0 }, { GCRY_CIPHER_MODE_STREAM, "", 0 }, {0} }; int modeidx; gcry_error_t err = GPG_ERR_NO_ERROR; if (!algoname) { for (i=1; i < 400; i++) if ( !gcry_cipher_test_algo (i) ) cipher_bench (gcry_cipher_algo_name (i)); return; } if (large_buffers) { allocated_buflen = 1024 * 100; repetitions = 10; } else { allocated_buflen = 1024; repetitions = 1000; } repetitions *= cipher_repetitions; raw_buf = gcry_xmalloc (allocated_buflen+15); buf = (raw_buf + ((16 - ((size_t)raw_buf & 0x0f)) % buffer_alignment)); outbuf = raw_outbuf = gcry_xmalloc (allocated_buflen+15); outbuf = (raw_outbuf + ((16 - ((size_t)raw_outbuf & 0x0f)) % buffer_alignment)); if (!header_printed) { if (cipher_repetitions != 1) printf ("Running each test %d times.\n", cipher_repetitions); printf ("%-12s", ""); for (modeidx=0; modes[modeidx].mode; modeidx++) if (*modes[modeidx].name) printf (" %-15s", modes[modeidx].name ); putchar ('\n'); printf ("%-12s", ""); for (modeidx=0; modes[modeidx].mode; modeidx++) if (*modes[modeidx].name) printf (" ---------------" ); putchar ('\n'); header_printed = 1; } algo = gcry_cipher_map_name (algoname); if (!algo) { fprintf (stderr, PGM ": invalid cipher algorithm `%s'\n", algoname); exit (1); } keylen = gcry_cipher_get_algo_keylen (algo); if (!keylen) { fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n", algoname); exit (1); } if ( keylen > sizeof key ) { fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n", algo, keylen ); exit (1); } for (i=0; i < keylen; i++) key[i] = i + (clock () & 0xff); blklen = gcry_cipher_get_algo_blklen (algo); if (!blklen) { fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n", algoname); exit (1); } printf ("%-12s", gcry_cipher_algo_name (algo)); fflush (stdout); for (modeidx=0; modes[modeidx].mode; modeidx++) { if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM) | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM)) continue; for (i=0; i < sizeof buf; i++) buf[i] = i; err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0); if (err) { fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname); exit (1); } if (!cipher_with_keysetup) { err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, "gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } } buflen = allocated_buflen; if (modes[modeidx].blocked) buflen = (buflen / blklen) * blklen; start_timer (); for (i=err=0; !err && i < repetitions; i++) { if (cipher_with_keysetup) { err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, "gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } } err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen); } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); gcry_cipher_close (hd); if (err) { fprintf (stderr, "gcry_cipher_encrypt failed: %s\n", gpg_strerror (err) ); exit (1); } err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0); if (err) { fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname); exit (1); } if (!cipher_with_keysetup) { err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, "gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } } start_timer (); for (i=err=0; !err && i < repetitions; i++) { if (cipher_with_keysetup) { err = gcry_cipher_setkey (hd, key, keylen); if (err) { fprintf (stderr, "gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); gcry_cipher_close (hd); exit (1); } } err = gcry_cipher_decrypt ( hd, outbuf, buflen, buf, buflen); } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); gcry_cipher_close (hd); if (err) { fprintf (stderr, "gcry_cipher_decrypt failed: %s\n", gpg_strerror (err) ); exit (1); } } putchar ('\n'); gcry_free (raw_buf); gcry_free (raw_outbuf); } static void rsa_bench (int iterations, int print_header, int no_blinding) { gpg_error_t err; int p_sizes[] = { 1024, 2048, 3072, 4096 }; int testno; if (print_header) printf ("Algorithm generate %4d*sign %4d*verify\n" "------------------------------------------------\n", iterations, iterations ); for (testno=0; testno < DIM (p_sizes); testno++) { gcry_sexp_t key_spec, key_pair, pub_key, sec_key; gcry_mpi_t x; gcry_sexp_t data; gcry_sexp_t sig = NULL; int count; printf ("RSA %3d bit ", p_sizes[testno]); fflush (stdout); err = gcry_sexp_build (&key_spec, NULL, gcry_fips_mode_active () ? "(genkey (RSA (nbits %d)))" : "(genkey (RSA (nbits %d)(transient-key)))", p_sizes[testno]); if (err) die ("creating S-expression failed: %s\n", gcry_strerror (err)); start_timer (); err = gcry_pk_genkey (&key_pair, key_spec); if (err) die ("creating %d bit RSA key failed: %s\n", p_sizes[testno], gcry_strerror (err)); pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); if (! pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); if (! sec_key) die ("private part missing in key\n"); gcry_sexp_release (key_pair); gcry_sexp_release (key_spec); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); x = gcry_mpi_new (p_sizes[testno]); gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM); err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); gcry_mpi_release (x); if (err) die ("converting data failed: %s\n", gcry_strerror (err)); start_timer (); for (count=0; count < iterations; count++) { gcry_sexp_release (sig); err = gcry_pk_sign (&sig, data, sec_key); if (err) die ("signing failed (%d): %s\n", count, gpg_strerror (err)); } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); start_timer (); for (count=0; count < iterations; count++) { err = gcry_pk_verify (sig, data, pub_key); if (err) { putchar ('\n'); show_sexp ("seckey:\n", sec_key); show_sexp ("data:\n", data); show_sexp ("sig:\n", sig); die ("verify failed (%d): %s\n", count, gpg_strerror (err)); } } stop_timer (); printf (" %s", elapsed_time ()); if (no_blinding) { fflush (stdout); x = gcry_mpi_new (p_sizes[testno]); gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM); err = gcry_sexp_build (&data, NULL, "(data (flags no-blinding) (value %m))", x); gcry_mpi_release (x); if (err) die ("converting data failed: %s\n", gcry_strerror (err)); start_timer (); for (count=0; count < iterations; count++) { gcry_sexp_release (sig); err = gcry_pk_sign (&sig, data, sec_key); if (err) die ("signing failed (%d): %s\n", count, gpg_strerror (err)); } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); } putchar ('\n'); fflush (stdout); gcry_sexp_release (sig); gcry_sexp_release (data); gcry_sexp_release (sec_key); gcry_sexp_release (pub_key); } } static void dsa_bench (int iterations, int print_header) { gpg_error_t err; gcry_sexp_t pub_key[3], sec_key[3]; int p_sizes[3] = { 1024, 2048, 3072 }; int q_sizes[3] = { 160, 224, 256 }; gcry_sexp_t data; gcry_sexp_t sig; int i, j; err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024, strlen (sample_public_dsa_key_1024)); if (!err) err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_dsa_key_1024, strlen (sample_private_dsa_key_1024)); if (!err) err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_dsa_key_2048, strlen (sample_public_dsa_key_2048)); if (!err) err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_dsa_key_2048, strlen (sample_private_dsa_key_2048)); if (!err) err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_dsa_key_3072, strlen (sample_public_dsa_key_3072)); if (!err) err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_dsa_key_3072, strlen (sample_private_dsa_key_3072)); if (err) { fprintf (stderr, PGM ": converting sample keys failed: %s\n", gcry_strerror (err)); exit (1); } if (print_header) printf ("Algorithm generate %4d*sign %4d*verify\n" "------------------------------------------------\n", iterations, iterations ); for (i=0; i < DIM (q_sizes); i++) { gcry_mpi_t x; x = gcry_mpi_new (q_sizes[i]); gcry_mpi_randomize (x, q_sizes[i], GCRY_WEAK_RANDOM); err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); gcry_mpi_release (x); if (err) { fprintf (stderr, PGM ": converting data failed: %s\n", gcry_strerror (err)); exit (1); } printf ("DSA %d/%d -", p_sizes[i], q_sizes[i]); fflush (stdout); start_timer (); for (j=0; j < iterations; j++) { err = gcry_pk_sign (&sig, data, sec_key[i]); if (err) { putchar ('\n'); fprintf (stderr, PGM ": signing failed: %s\n", gpg_strerror (err)); exit (1); } } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); start_timer (); for (j=0; j < iterations; j++) { err = gcry_pk_verify (sig, data, pub_key[i]); if (err) { putchar ('\n'); fprintf (stderr, PGM ": verify failed: %s\n", gpg_strerror (err)); exit (1); } } stop_timer (); printf (" %s\n", elapsed_time ()); fflush (stdout); gcry_sexp_release (sig); gcry_sexp_release (data); } for (i=0; i < DIM (q_sizes); i++) { gcry_sexp_release (sec_key[i]); gcry_sexp_release (pub_key[i]); } } static void ecc_bench (int iterations, int print_header) { #if USE_ECC gpg_error_t err; int p_sizes[] = { 192, 224, 256, 384, 521 }; int testno; if (print_header) printf ("Algorithm generate %4d*sign %4d*verify\n" "------------------------------------------------\n", iterations, iterations ); for (testno=0; testno < DIM (p_sizes); testno++) { gcry_sexp_t key_spec, key_pair, pub_key, sec_key; gcry_mpi_t x; gcry_sexp_t data; gcry_sexp_t sig = NULL; int count; printf ("ECDSA %3d bit ", p_sizes[testno]); fflush (stdout); err = gcry_sexp_build (&key_spec, NULL, "(genkey (ECDSA (nbits %d)))", p_sizes[testno]); if (err) die ("creating S-expression failed: %s\n", gcry_strerror (err)); start_timer (); err = gcry_pk_genkey (&key_pair, key_spec); if (err) die ("creating %d bit ECC key failed: %s\n", p_sizes[testno], gcry_strerror (err)); pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); if (! pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); if (! sec_key) die ("private part missing in key\n"); gcry_sexp_release (key_pair); gcry_sexp_release (key_spec); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); x = gcry_mpi_new (p_sizes[testno]); gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM); err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); gcry_mpi_release (x); if (err) die ("converting data failed: %s\n", gcry_strerror (err)); start_timer (); for (count=0; count < iterations; count++) { gcry_sexp_release (sig); err = gcry_pk_sign (&sig, data, sec_key); if (err) die ("signing failed: %s\n", gpg_strerror (err)); } stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); start_timer (); for (count=0; count < iterations; count++) { err = gcry_pk_verify (sig, data, pub_key); if (err) { putchar ('\n'); show_sexp ("seckey:\n", sec_key); show_sexp ("data:\n", data); show_sexp ("sig:\n", sig); die ("verify failed: %s\n", gpg_strerror (err)); } } stop_timer (); printf (" %s\n", elapsed_time ()); fflush (stdout); gcry_sexp_release (sig); gcry_sexp_release (data); gcry_sexp_release (sec_key); gcry_sexp_release (pub_key); } #endif /*USE_ECC*/ } static void do_powm ( const char *n_str, const char *e_str, const char *m_str) { gcry_mpi_t e, n, msg, cip; gcry_error_t err; int i; err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, n_str, 0, 0); if (err) BUG (); err = gcry_mpi_scan (&e, GCRYMPI_FMT_HEX, e_str, 0, 0); if (err) BUG (); err = gcry_mpi_scan (&msg, GCRYMPI_FMT_HEX, m_str, 0, 0); if (err) BUG (); cip = gcry_mpi_new (0); start_timer (); for (i=0; i < 1000; i++) gcry_mpi_powm (cip, msg, e, n); stop_timer (); printf (" %s", elapsed_time ()); fflush (stdout); /* { */ /* char *buf; */ /* if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */ /* BUG (); */ /* printf ("result: %s\n", buf); */ /* gcry_free (buf); */ /* } */ gcry_mpi_release (cip); gcry_mpi_release (msg); gcry_mpi_release (n); gcry_mpi_release (e); } static void mpi_bench (void) { printf ("%-10s", "powm"); fflush (stdout); do_powm ( "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E4", "29", "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8" ); do_powm ( "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716", "29", "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847" ); do_powm ( "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA4071620A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716", "29", "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847" ); putchar ('\n'); } int main( int argc, char **argv ) { int last_argc = -1; int no_blinding = 0; int use_random_daemon = 0; int with_progress = 0; buffer_alignment = 1; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--help")) { fputs ("usage: benchmark " "[md|cipher|random|mpi|rsa|dsa|ecc [algonames]]\n", stdout); exit (0); } else if (!strcmp (*argv, "--verbose")) { verbose++; argc--; argv++; } else if (!strcmp (*argv, "--use-random-daemon")) { use_random_daemon = 1; argc--; argv++; } else if (!strcmp (*argv, "--prefer-standard-rng")) { /* This is anyway the default, but we may want to use it for debugging. */ gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD); argc--; argv++; } else if (!strcmp (*argv, "--prefer-fips-rng")) { gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS); argc--; argv++; } else if (!strcmp (*argv, "--prefer-system-rng")) { gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM); argc--; argv++; } else if (!strcmp (*argv, "--no-blinding")) { no_blinding = 1; argc--; argv++; } else if (!strcmp (*argv, "--large-buffers")) { large_buffers = 1; argc--; argv++; } else if (!strcmp (*argv, "--cipher-repetitions")) { argc--; argv++; if (argc) { cipher_repetitions = atoi(*argv); argc--; argv++; } } else if (!strcmp (*argv, "--cipher-with-keysetup")) { cipher_with_keysetup = 1; argc--; argv++; } else if (!strcmp (*argv, "--hash-repetitions")) { argc--; argv++; if (argc) { hash_repetitions = atoi(*argv); argc--; argv++; } } else if (!strcmp (*argv, "--alignment")) { argc--; argv++; if (argc) { buffer_alignment = atoi(*argv); argc--; argv++; } } else if (!strcmp (*argv, "--disable-hwf")) { argc--; argv++; if (argc) { if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL)) fprintf (stderr, PGM ": unknown hardware feature `%s'" " - option ignored\n", *argv); argc--; argv++; } } else if (!strcmp (*argv, "--fips")) { argc--; argv++; /* This command needs to be called before gcry_check_version. */ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); } else if (!strcmp (*argv, "--progress")) { argc--; argv++; with_progress = 1; } } if (buffer_alignment < 1 || buffer_alignment > 16) die ("value for --alignment must be in the range 1 to 16\n"); gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); if (!gcry_check_version (GCRYPT_VERSION)) { fprintf (stderr, PGM ": version mismatch; pgm=%s, library=%s\n", GCRYPT_VERSION, gcry_check_version (NULL)); exit (1); } if (gcry_fips_mode_active ()) in_fips_mode = 1; else gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (use_random_daemon) gcry_control (GCRYCTL_USE_RANDOM_DAEMON, 1); if (with_progress) gcry_set_progress_handler (progress_cb, NULL); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (cipher_repetitions < 1) cipher_repetitions = 1; if (hash_repetitions < 1) hash_repetitions = 1; if ( !argc ) { gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); md_bench (NULL); putchar ('\n'); cipher_bench (NULL); putchar ('\n'); rsa_bench (100, 1, no_blinding); dsa_bench (100, 0); ecc_bench (100, 0); putchar ('\n'); mpi_bench (); putchar ('\n'); random_bench (0); } else if ( !strcmp (*argv, "random") || !strcmp (*argv, "strongrandom")) { if (argc == 1) random_bench ((**argv == 's')); else if (argc == 2) { gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, argv[1]); random_bench ((**argv == 's')); gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); } else fputs ("usage: benchmark [strong]random [seedfile]\n", stdout); } else if ( !strcmp (*argv, "md")) { if (argc == 1) md_bench (NULL); else for (argc--, argv++; argc; argc--, argv++) md_bench ( *argv ); } else if ( !strcmp (*argv, "cipher")) { if (argc == 1) cipher_bench (NULL); else for (argc--, argv++; argc; argc--, argv++) cipher_bench ( *argv ); } else if ( !strcmp (*argv, "mpi")) { mpi_bench (); } else if ( !strcmp (*argv, "rsa")) { gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); rsa_bench (100, 1, no_blinding); } else if ( !strcmp (*argv, "dsa")) { gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); dsa_bench (100, 1); } else if ( !strcmp (*argv, "ecc")) { gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); ecc_bench (100, 1); } else { fprintf (stderr, PGM ": bad arguments\n"); return 1; } if (in_fips_mode && !gcry_fips_mode_active ()) fprintf (stderr, PGM ": FIPS mode is not anymore active\n"); return 0; } diff --git a/tests/curves.c b/tests/curves.c index 6cfcd4f4..664e8753 100644 --- a/tests/curves.c +++ b/tests/curves.c @@ -1,210 +1,210 @@ /* curves.c - ECC curves regression tests * Copyright (C) 2011 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" /* Number of curves defined in ../cipger/ecc.c */ #define N_CURVES 12 /* A real world sample public key. */ static char const sample_key_1[] = "(public-key\n" " (ecdsa\n" " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)\n" " (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)\n" " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)\n" " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)\n" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)\n" " (q #0442B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146EE" "86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E#)\n" " ))"; static char const sample_key_1_curve[] = "NIST P-256"; static unsigned int sample_key_1_nbits = 256; /* A made up sample public key. */ static char const sample_key_2[] = "(public-key\n" " (ecdh\n" " (p #e95e4a5f737059dc60dfc7ad95b3d8139515620f#)\n" " (a #340e7be2a280eb74e2be61bada745d97e8f7c300#)\n" " (b #1e589a8595423412134faa2dbdec95c8d8675e58#)\n" " (g #04bed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3" "1667cb477a1a8ec338f94741669c976316da6321#)\n" " (n #e95e4a5f737059dc60df5991d45029409e60fc09#)\n" " (q #041111111111111111111111111111111111111111" "2222222222222222222222222222222222222222#)\n" " ))"; static char const sample_key_2_curve[] = "brainpoolP160r1"; static unsigned int sample_key_2_nbits = 160; /* Program option flags. */ static int verbose; static int error_count; static void fail (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); error_count++; } static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void list_curves (void) { int idx; const char *name; unsigned int nbits; for (idx=0; (name = gcry_pk_get_curve (NULL, idx, &nbits)); idx++) { if (verbose) printf ("%s - %u bits\n", name, nbits); } if (idx != N_CURVES) fail ("expected %d curves but got %d\n", N_CURVES, idx); if (gcry_pk_get_curve (NULL, -1, NULL)) fail ("curve iteration failed\n"); } static void check_matching (void) { gpg_error_t err; gcry_sexp_t key; const char *name; unsigned int nbits; err = gcry_sexp_new (&key, sample_key_1, 0, 1); if (err) die ("parsing s-expression string failed: %s\n", gpg_strerror (err)); name = gcry_pk_get_curve (key, 0, &nbits); if (!name) fail ("curve name not found for sample_key_1\n"); else if (strcmp (name, sample_key_1_curve)) fail ("expected curve name %s but got %s for sample_key_1\n", sample_key_1_curve, name); else if (nbits != sample_key_1_nbits) fail ("expected curve size %u but got %u for sample_key_1\n", sample_key_1_nbits, nbits); gcry_sexp_release (key); err = gcry_sexp_new (&key, sample_key_2, 0, 1); if (err) die ("parsing s-expression string failed: %s\n", gpg_strerror (err)); name = gcry_pk_get_curve (key, 0, &nbits); if (!name) fail ("curve name not found for sample_key_2\n"); else if (strcmp (name, sample_key_2_curve)) fail ("expected curve name %s but got %s for sample_key_2\n", sample_key_2_curve, name); else if (nbits != sample_key_2_nbits) fail ("expected curve size %u but got %u for sample_key_2\n", sample_key_2_nbits, nbits); gcry_sexp_release (key); } static void check_get_params (void) { gcry_sexp_t param; const char *name; param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_1_curve); if (!param) fail ("error gerring parameters for `%s'\n", sample_key_1_curve); name = gcry_pk_get_curve (param, 0, NULL); if (!name) fail ("get_param: curve name not found for sample_key_1\n"); else if (strcmp (name, sample_key_1_curve)) fail ("get_param: expected curve name %s but got %s for sample_key_1\n", sample_key_1_curve, name); gcry_sexp_release (param); param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_2_curve); if (!param) fail ("error gerring parameters for `%s'\n", sample_key_2_curve); name = gcry_pk_get_curve (param, 0, NULL); if (!name) fail ("get_param: curve name not found for sample_key_2\n"); else if (strcmp (name, sample_key_2_curve)) fail ("get_param: expected curve name %s but got %s for sample_key_2\n", sample_key_2_curve, name); gcry_sexp_release (param); } int main (int argc, char **argv) { int debug = 0; if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) verbose = debug = 1; if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); list_curves (); check_matching (); check_get_params (); return error_count ? 1 : 0; } diff --git a/tests/fips186-dsa.c b/tests/fips186-dsa.c index 401acff0..10b18abb 100644 --- a/tests/fips186-dsa.c +++ b/tests/fips186-dsa.c @@ -1,465 +1,465 @@ /* fips186-dsa.c - FIPS 186 DSA tests * Copyright (C) 2008 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #ifdef _GCRYPT_IN_LIBGCRYPT -# include "../src/gcrypt.h" +# include "../src/gcrypt-int.h" #else # include #endif #define my_isascii(c) (!((c) & 0x80)) #define digitp(p) (*(p) >= '0' && *(p) <= '9') #define hexdigitp(a) (digitp (a) \ || (*(a) >= 'A' && *(a) <= 'F') \ || (*(a) >= 'a' && *(a) <= 'f')) #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) static int verbose; static int error_count; static void info (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); } static void fail (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); error_count++; } static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void show_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; if (prefix) fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = gcry_xmalloc (size); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); gcry_free (buf); } static gcry_mpi_t mpi_from_string (const char *string) { gpg_error_t err; gcry_mpi_t a; err = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, string, 0, NULL); if (err) die ("error converting string to mpi: %s\n", gpg_strerror (err)); return a; } /* Convert STRING consisting of hex characters into its binary representation and return it as an allocated buffer. The valid length of the buffer is returned at R_LENGTH. The string is delimited by end of string. The function returns NULL on error. */ static void * data_from_hex (const char *string, size_t *r_length) { const char *s; unsigned char *buffer; size_t length; buffer = gcry_xmalloc (strlen(string)/2+1); length = 0; for (s=string; *s; s +=2 ) { if (!hexdigitp (s) || !hexdigitp (s+1)) die ("error parsing hex string `%s'\n", string); ((unsigned char*)buffer)[length++] = xtoi_2 (s); } *r_length = length; return buffer; } static void extract_cmp_mpi (gcry_sexp_t sexp, const char *name, const char *expected) { gcry_sexp_t l1; gcry_mpi_t a, b; l1 = gcry_sexp_find_token (sexp, name, 0); a = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); b = mpi_from_string (expected); if (!a) fail ("parameter \"%s\" missing in key\n", name); else if ( gcry_mpi_cmp (a, b) ) fail ("parameter \"%s\" does not match expected value\n", name); gcry_mpi_release (b); gcry_mpi_release (a); gcry_sexp_release (l1); } static void extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected) { gcry_sexp_t l1; const void *a; size_t alen; void *b; size_t blen; l1 = gcry_sexp_find_token (sexp, name, 0); a = gcry_sexp_nth_data (l1, 1, &alen); b = data_from_hex (expected, &blen); if (!a) fail ("parameter \"%s\" missing in key\n", name); else if ( alen != blen || memcmp (a, b, alen) ) fail ("parameter \"%s\" does not match expected value\n", name); gcry_free (b); gcry_sexp_release (l1); } static void extract_cmp_int (gcry_sexp_t sexp, const char *name, int expected) { gcry_sexp_t l1; char *a; l1 = gcry_sexp_find_token (sexp, name, 0); a = gcry_sexp_nth_string (l1, 1); if (!a) fail ("parameter \"%s\" missing in key\n", name); else if ( strtoul (a, NULL, 10) != expected ) fail ("parameter \"%s\" does not match expected value\n", name); gcry_free (a); gcry_sexp_release (l1); } static void check_dsa_gen_186_2 (void) { static struct { int nbits; const char *p, *q, *g; const char *seed; int counter; const char *h; } tbl[] = { /* These tests are from FIPS 186-2, B.3.1. */ { 1024, "d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69", "9c916d121de9a03f71fb21bc2e1c0d116f065a4f", "8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44", "0cb1990c1fd3626055d7a0096f8fa99807399871", 98, "00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000002" }, { 1024, "f5c73304080353357de1b5967597c27d65f70aa2fe9b6aed1d0afc2b499adf22f" "8e37937096d88548ac36c4a067f8353c7fed73f96f0d688b19b0624aedbae5dbb" "0ee8835a4c269288c0e1d69479e701ee266bb767af39d748fe7d6afc73fdf44be" "3eb6e661e599670061203e75fc8b3dbd59e40b54f358d0097013a0f3867f9", "f8751166cf4f6f3b07c081fd2a9071f23ca1988d", "1e288a442e02461c418ed67a66d24cacbeb8936fbde62ff995f5fd569dee6be62" "4e4f0f9f8c8093f5d192ab3b3f9ae3f2665d95d27fb10e382f45cd356e7f4eb7a" "665db432113ed06478f93b7cf188ec7a1ee97aec8f91ea7bfceaf8b6e7e5a349c" "4ad3225362ef440c57cbc6e69df15b6699caac85f733555075f04781b2b33", "34b3520d45d240a8861b82c8b61ffa16e67b5cce", 622, "00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000002", }, { 1024, "c6c6f4f4eed927fb1c3b0c81010967e530658e6f9698ebe058b4f47b2dc8fcbc7" "b69296b9e8b6cf55681181fe72492668061b262b0046a0d409902e269b0cb69a4" "55ed1a086caf41927f5912bf0e0cbc45ee81a4f98bf6146f6168a228aec80e9cc" "1162d6f6aa412efe82d4f18b95e34ab790daac5bd7aef0b22fa08ba5dbaad", "d32b29f065c1394a30490b6fcbf812a32a8634ab", "06f973c879e2e89345d0ac04f9c34ad69b9eff1680f18d1c8f3e1596c2e8fa8e1" "ecef6830409e9012d4788bef6ec7414d09c981b47c941b77f39dfc49caff5e714" "c97abe25a7a8b5d1fe88700bb96eff91cca64d53700a28b1146d81bad1212d231" "80154c95a01f5aeebb553a8365c38a5ebe05539b51734233776ce9aff98b2", "b6ec750da2f824cb42c5f7e28c81350d97f75125", 185, "00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000002", }, { 1024, "b827a9dc9221a6ed1bec7b64d61232aacb2812f888b0a0b3a95033d7a22e77d0b" "ff23bfeed0fb1281b21b8ff7421f0c727d1fb8aa2b843d6885f067e763f83d41f" "d800ab15a7e2b12f71ec2058ee7bd62cd72c26989b272e519785da57bfa1f974b" "c652e1a2d6cfb68477de5635fd019b37add656cff0b802558b31b6d2851e5", "de822c03445b77cec4ad3a6fb0ca39ff97059ddf", "65a9e2d43a378d7063813104586868cacf2fccd51aec1e0b6af8ba3e66dee6371" "681254c3fb5e3929d65e3c4bcd20abd4ddc7cf815623e17b9fc92f02b8d44278b" "848480ffd193104cf5612639511e45bd247708ff6028bd3824f8844c263b46c69" "1f2076f8cd13c5d0be95f1f2a1a17ab1f7e5bc73500bac27d57b473ba9748", "cd2221dd73815a75224e9fde7faf52829b81ac7a", 62, "00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000002", }, { 1024, "898a8d93e295c8ef2ffd46976225a1543640640d155a576fafa0be32136165803" "ba2eff2782a2be75cc9ec65db6bd3238cca695b3a5a14726a2a314775c377d891" "354b3de6c89e714a05599ca04132c987f889f72c4fe298ccb31f711c03b07e1d9" "8d72af590754cf3847398b60cecd55a4611692b308809560a83880404c227", "c6d786643d2acfc6b8d576863fda8cfbfbd5e03f", "2fd38b8d21c58e8fb5315a177b8d5dc4c450d574e69348b7b9da367c26e72438d" "af8372e7f0bee84ef5dcbbc3727194a2228431192f1779be24837f22a0e14d10d" "5344da1b8b403df9f9b2655095b3d0f67418ed6cd989f35aa4232e4b7001764fb" "e85d6b2c716980f13272fc4271ac1e234f7e24c023cfc2d2dc0aa1e9af2fb", "73483e697599871af983a281e3afa22e0ed86b68", 272, "00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000" "00000000000000000000000000000000000000000000000000000000000000000" "0000000000000000000000000000000000000000000000000000000000002", }, /* These tests are generated by the OpenSSL FIPS version. */ { 1024, "A404363903FDCE86839BCFD953AAD2DA2B0E70CAED3B5FF5D68F15A1C4BB0A793C" "A9D58FC956804C5901DE0AF99F345ED1A8617C687864BAC044B7C3C3E732A2B255" "EC986AA76EA8CB0E0815B3E0E605650AF7D8058EE7E8EBCDEFFDAB8100D3FC1033" "11BA3AB232EF06BB74BA9A949EC0C7ED324C19B202F4AB725BBB4080C9", "C643946CEA8748E12D430C48DB038F9165814389", "59B7E7BA0033CCE8E6837173420FBB382A784D4154A3C166043F5A68CB92945D16" "892D4CC5585F2D28C780E75A6C20A379E2B58304C1E5FC0D8C15E4E89C4498C8BC" "B90FB36ED8DC0489B9D0BC09EC4411FB0BFADF25485EEAB6700BE0ACF5C44A6ED7" "44A015382FF9B8DA7EAA00DEA135FADC59212DBBFFC1537336FA4B7225", "02708ab36e3f0bfd67ec3b8bd8829d03b84f56bd", 50, "02" }, { 1024, "9C664033DB8B203D826F896D2293C62EF9351D5CFD0F4C0AD7EFDA4DDC7F15987" "6A3C68CAB2586B44FD1BD4DEF7A17905D88D321DD77C4E1720D848CA21D79F9B3" "D8F537338E09B44E9F481E8DA3C56569F63146596A050EF8FAEE8ACA32C666450" "04F675C8806EB4025B0A5ECC39CE89983EA40A183A7CF5208BA958045ABD5", "AD0D8CBA369AF6CD0D2BAC0B4CFCAF0A1F9BCDF7", "74D717F7092A2AF725FDD6C2561D1DBE5AEE40203C638BA8B9F49003857873701" "95A44E515C4E8B344F5CDC7F4A6D38097CD57675E7643AB9700692C69F0A99B0E" "039FDDDFCA8CEB607BDB4ADF2834DE1690F5823FC8199FB8F6F29E5A583B6786A" "C14C7E67106C3B30568CBB9383F89287D578159778EB18216799D16D46498", "6481a12a50384888ee84b61024f7c9c685d6ac96", 289, "02" }, { 1024, "B0DFB602EB8462B1DC8C2214A52B587D3E6842CCF1C38D0F7C7F967ED30CF6828" "1E2675B3BAB594755FB1634E66B4C23936F0725A358F8DFF3C307E2601FD66D63" "5B17270450C50BD2BEC29E0E9A471DF1C15B0191517952268A2763D4BD28B8503" "B3399686272B76B11227F693D7833105EF70C2289C3194CF4527024B272DF", "EA649C04911FAB5A41440287A517EF752A40354B", "88C5A4563ECB949763E0B696CD04B21321360F54C0EE7B23E2CEDC30E9E486162" "01BFB1619E7C54B653D1F890C50E04B29205F5E3E2F93A13B0751AF25491C5194" "93C09DDF6B9C173B3846DFB0E7A5C870BBFC78419260C90E20315410691C8326C" "858D7063E7921F3F601158E912C7EE487FF259202BEEB10F6D9E99190F696", "5bf9d17bc62fbbf3d569c92bd4505586b2e5ef1a", 626, "02" }, { 1024, "F783C08D7F9463E48BA87893805C4B34B63C85DF7EBDD9EBEE94DB4AF4E4A415C" "F0F3793AE55096BA1199598798FA8403B28DED7F7C7AFD54FD535861A0150EF4D" "5871465B13837CCF46BEB0A22F8D38DC7D6AE0E14A3845FD0C027CFA97791B977" "CE2808BAD9B43CE69390C0F40016056722D82C0D7B1B27413D026A39D7DAD", "A40D9EE456AED4C8A653FDB47B6629C0B843FE8F", "DF876263E21F263AE6DA57409BD517DCEADB9216048F066D6B58867F8E59A5EEE" "700283A946C1455534618979BE6C227673C1B803910262BD93BC94D5089850614" "F3E29AB64E8C989A7E3E28FE670FFA3EE21DEEEC1AB0B60E1D8E2AA39663BADD7" "2C9F957D7F3D4F17D9FDAD050EB373A6DEFD09F5DA752EAFE046836E14B67", "8a9a57706f69f4f566252cdf6d5cbfdf2020150b", 397, "02" }, { 1024, "D40E4F6461E145859CCF60FD57962840BD75FFF12C22F76626F566842252AD068" "29745F0147056354F6C016CF12762B0E331787925B8128CF5AF81F9B176A51934" "96D792430FF83C7B79BD595BDA10787B34600787FA552EFE3662F37B99AAD3F3A" "093732680A01345192A19BECCE6BF5D498E44ED6BED5B0BA72AAD49E8276B", "D12F1BD0AA78B99247FD9F18EAFEE5C136686EA5", "468EBD20C99449C1E440E6F8E452C6A6BC7551C555FE5E94996E20CFD4DA3B9CC" "58499D6CC2374CCF9C392715A537DE10CFCA8A6A37AFBD187CF6B88D26881E5F5" "7521D9D2C9BBA51E7B87B070BBE73F5C5FE31E752CAF88183516D8503BAAC1159" "928EF50DEE52D96F396B93FB4138D786464C315401A853E57C9A0F9D25839", "30b3599944a914a330a3f49d11ec88f555422aef", 678, "02" } }; gpg_error_t err; int tno; gcry_sexp_t key_spec, key, pub_key, sec_key, seed_values; gcry_sexp_t l1; for (tno = 0; tno < DIM (tbl); tno++) { if (verbose) info ("generating FIPS 186-2 test key %d\n", tno); { void *data; size_t datalen; data = data_from_hex (tbl[tno].seed, &datalen); err = gcry_sexp_build (&key_spec, NULL, "(genkey (dsa (nbits %d)(use-fips186-2)" "(derive-parms(seed %b))))", tbl[tno].nbits, (int)datalen, data); gcry_free (data); } if (err) die ("error creating S-expression %d: %s\n", tno, gpg_strerror (err)); err = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (err) { fail ("error generating key %d: %s\n", tno, gpg_strerror (err)); continue; } if (verbose > 1) show_sexp ("generated key:\n", key); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (!pub_key) fail ("public part missing in key %d\n", tno); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (!sec_key) fail ("private part missing in key %d\n", tno); l1 = gcry_sexp_find_token (key, "misc-key-info", 0); if (!l1) fail ("misc_key_info part missing in key %d\n", tno); seed_values = gcry_sexp_find_token (l1, "seed-values", 0); if (!seed_values) fail ("seed-values part missing in key %d\n", tno); gcry_sexp_release (l1); extract_cmp_mpi (sec_key, "p", tbl[tno].p); extract_cmp_mpi (sec_key, "q", tbl[tno].q); extract_cmp_mpi (sec_key, "g", tbl[tno].g); extract_cmp_data (seed_values, "seed", tbl[tno].seed); extract_cmp_int (seed_values, "counter", tbl[tno].counter); extract_cmp_mpi (seed_values, "h", tbl[tno].h); gcry_sexp_release (seed_values); gcry_sexp_release (sec_key); gcry_sexp_release (pub_key); gcry_sexp_release (key); } } int main (int argc, char **argv) { int debug = 0; if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) { verbose = 2; debug = 1; } gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (!gcry_check_version ("1.4.4")) die ("version mismatch\n"); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); /* No valuable keys are create, so we can speed up our RNG. */ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); check_dsa_gen_186_2 (); return error_count ? 1 : 0; } diff --git a/tests/fipsdrv.c b/tests/fipsdrv.c index 2d4c3624..eef2ddd1 100644 --- a/tests/fipsdrv.c +++ b/tests/fipsdrv.c @@ -1,2525 +1,2525 @@ /* fipsdrv.c - A driver to help with FIPS CAVS tests. Copyright (C) 2008 Free Software Foundation, Inc. This file is part of Libgcrypt. Libgcrypt is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Libgcrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #ifdef HAVE_W32_SYSTEM # include /* We need setmode(). */ #else # include #endif #include #include #ifdef _GCRYPT_IN_LIBGCRYPT -# include "../src/gcrypt.h" +# include "../src/gcrypt-int.h" #else # include # define PACKAGE_BUGREPORT "devnull@example.org" # define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]" #endif #define PGM "fipsdrv" #define my_isascii(c) (!((c) & 0x80)) #define digitp(p) (*(p) >= '0' && *(p) <= '9') #define hexdigitp(a) (digitp (a) \ || (*(a) >= 'A' && *(a) <= 'F') \ || (*(a) >= 'a' && *(a) <= 'f')) #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) #define PRIV_CTL_INIT_EXTRNG_TEST 58 #define PRIV_CTL_RUN_EXTRNG_TEST 59 #define PRIV_CTL_DEINIT_EXTRNG_TEST 60 #define PRIV_CTL_DISABLE_WEAK_KEY 61 #define PRIV_CTL_GET_INPUT_VECTOR 62 /* Verbose mode flag. */ static int verbose; /* Binary input flag. */ static int binary_input; /* Binary output flag. */ static int binary_output; /* Base64 output flag. */ static int base64_output; /* We need to know whether we are in loop_mode. */ static int loop_mode; /* If true some functions are modified to print the output in the CAVS response file format. */ static int standalone_mode; /* ASN.1 classes. */ enum { UNIVERSAL = 0, APPLICATION = 1, ASNCONTEXT = 2, PRIVATE = 3 }; /* ASN.1 tags. */ enum { TAG_NONE = 0, TAG_BOOLEAN = 1, TAG_INTEGER = 2, TAG_BIT_STRING = 3, TAG_OCTET_STRING = 4, TAG_NULL = 5, TAG_OBJECT_ID = 6, TAG_OBJECT_DESCRIPTOR = 7, TAG_EXTERNAL = 8, TAG_REAL = 9, TAG_ENUMERATED = 10, TAG_EMBEDDED_PDV = 11, TAG_UTF8_STRING = 12, TAG_REALTIVE_OID = 13, TAG_SEQUENCE = 16, TAG_SET = 17, TAG_NUMERIC_STRING = 18, TAG_PRINTABLE_STRING = 19, TAG_TELETEX_STRING = 20, TAG_VIDEOTEX_STRING = 21, TAG_IA5_STRING = 22, TAG_UTC_TIME = 23, TAG_GENERALIZED_TIME = 24, TAG_GRAPHIC_STRING = 25, TAG_VISIBLE_STRING = 26, TAG_GENERAL_STRING = 27, TAG_UNIVERSAL_STRING = 28, TAG_CHARACTER_STRING = 29, TAG_BMP_STRING = 30 }; /* ASN.1 Parser object. */ struct tag_info { int class; /* Object class. */ unsigned long tag; /* The tag of the object. */ unsigned long length; /* Length of the values. */ int nhdr; /* Length of the header (TL). */ unsigned int ndef:1; /* The object has an indefinite length. */ unsigned int cons:1; /* This is a constructed object. */ }; /* Print a error message and exit the process with an error code. */ static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); fputs (PGM ": ", stderr); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void showhex (const char *prefix, const void *buffer, size_t length) { const unsigned char *p = buffer; if (prefix) fprintf (stderr, PGM ": %s: ", prefix); while (length-- ) fprintf (stderr, "%02X", *p++); if (prefix) putc ('\n', stderr); } /* static void */ /* show_sexp (const char *prefix, gcry_sexp_t a) */ /* { */ /* char *buf; */ /* size_t size; */ /* if (prefix) */ /* fputs (prefix, stderr); */ /* size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); */ /* buf = gcry_xmalloc (size); */ /* gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); */ /* fprintf (stderr, "%.*s", (int)size, buf); */ /* gcry_free (buf); */ /* } */ /* Convert STRING consisting of hex characters into its binary representation and store that at BUFFER. BUFFER needs to be of LENGTH bytes. The function checks that the STRING will convert exactly to LENGTH bytes. The string is delimited by either end of string or a white space character. The function returns -1 on error or the length of the parsed string. */ static int hex2bin (const char *string, void *buffer, size_t length) { int i; const char *s = string; for (i=0; i < length; ) { if (!hexdigitp (s) || !hexdigitp (s+1)) return -1; /* Invalid hex digits. */ ((unsigned char*)buffer)[i++] = xtoi_2 (s); s += 2; } if (*s && (!my_isascii (*s) || !isspace (*s)) ) return -1; /* Not followed by Nul or white space. */ if (i != length) return -1; /* Not of expected length. */ if (*s) s++; /* Skip the delimiter. */ return s - string; } /* Convert STRING consisting of hex characters into its binary representation and return it as an allocated buffer. The valid length of the buffer is returned at R_LENGTH. The string is delimited by end of string. The function returns NULL on error. */ static void * hex2buffer (const char *string, size_t *r_length) { const char *s; unsigned char *buffer; size_t length; buffer = gcry_xmalloc (strlen(string)/2+1); length = 0; for (s=string; *s; s +=2 ) { if (!hexdigitp (s) || !hexdigitp (s+1)) return NULL; /* Invalid hex digits. */ ((unsigned char*)buffer)[length++] = xtoi_2 (s); } *r_length = length; return buffer; } static char * read_textline (FILE *fp) { char line[256]; char *p; int any = 0; /* Read line but skip over initial empty lines. */ do { do { if (!fgets (line, sizeof line, fp)) { if (feof (fp)) return NULL; die ("error reading input line: %s\n", strerror (errno)); } p = strchr (line, '\n'); if (p) *p = 0; p = line + (*line? (strlen (line)-1):0); for ( ;p > line; p--) if (my_isascii (*p) && isspace (*p)) *p = 0; } while (!any && !*line); any = 1; } while (*line == '#'); /* Always skip comment lines. */ if (verbose > 1) fprintf (stderr, PGM ": received line: %s\n", line); return gcry_xstrdup (line); } static char * read_hexline (FILE *fp, size_t *retlen) { char *line, *p; line = read_textline (fp); if (!line) return NULL; p = hex2buffer (line, retlen); if (!p) die ("error decoding hex string on input\n"); gcry_free (line); return p; } static void skip_to_empty_line (FILE *fp) { char line[256]; char *p; do { if (!fgets (line, sizeof line, fp)) { if (feof (fp)) return; die ("error reading input line: %s\n", strerror (errno)); } p = strchr (line, '\n'); if (p) *p =0; } while (*line); } /* Read a file from stream FP into a newly allocated buffer and return that buffer. The valid length of the buffer is stored at R_LENGTH. Returns NULL on failure. If decode is set, the file is assumed to be hex encoded and the decoded content is returned. */ static void * read_file (FILE *fp, int decode, size_t *r_length) { char *buffer; size_t buflen; size_t nread, bufsize = 0; *r_length = 0; #define NCHUNK 8192 #ifdef HAVE_DOSISH_SYSTEM setmode (fileno(fp), O_BINARY); #endif buffer = NULL; buflen = 0; do { bufsize += NCHUNK; if (!buffer) buffer = gcry_xmalloc (bufsize); else buffer = gcry_xrealloc (buffer, bufsize); nread = fread (buffer + buflen, 1, NCHUNK, fp); if (nread < NCHUNK && ferror (fp)) { gcry_free (buffer); return NULL; } buflen += nread; } while (nread == NCHUNK); #undef NCHUNK if (decode) { const char *s; char *p; for (s=buffer,p=buffer,nread=0; nread+1 < buflen; s += 2, nread +=2 ) { if (!hexdigitp (s) || !hexdigitp (s+1)) { gcry_free (buffer); return NULL; /* Invalid hex digits. */ } *(unsigned char*)p++ = xtoi_2 (s); } if (nread != buflen) { gcry_free (buffer); return NULL; /* Odd number of hex digits. */ } buflen = p - buffer; } *r_length = buflen; return buffer; } /* Do in-place decoding of base-64 data of LENGTH in BUFFER. Returns the new length of the buffer. Dies on error. */ static size_t base64_decode (char *buffer, size_t length) { static unsigned char const asctobin[128] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff }; int idx = 0; unsigned char val = 0; int c = 0; char *d, *s; int lfseen = 1; /* Find BEGIN line. */ for (s=buffer; length; length--, s++) { if (lfseen && *s == '-' && length > 11 && !memcmp (s, "-----BEGIN ", 11)) { for (; length && *s != '\n'; length--, s++) ; break; } lfseen = (*s == '\n'); } /* Decode until pad character or END line. */ for (d=buffer; length; length--, s++) { if (lfseen && *s == '-' && length > 9 && !memcmp (s, "-----END ", 9)) break; if ((lfseen = (*s == '\n')) || *s == ' ' || *s == '\r' || *s == '\t') continue; if (*s == '=') { /* Pad character: stop */ if (idx == 1) *d++ = val; break; } if ( (*s & 0x80) || (c = asctobin[*(unsigned char *)s]) == 0xff) die ("invalid base64 character %02X at pos %d detected\n", *(unsigned char*)s, (int)(s-buffer)); switch (idx) { case 0: val = c << 2; break; case 1: val |= (c>>4)&3; *d++ = val; val = (c<<4)&0xf0; break; case 2: val |= (c>>2)&15; *d++ = val; val = (c<<6)&0xc0; break; case 3: val |= c&0x3f; *d++ = val; break; } idx = (idx+1) % 4; } return d - buffer; } /* Parse the buffer at the address BUFFER which consists of the number of octets as stored at BUFLEN. Return the tag and the length part from the TLV triplet. Update BUFFER and BUFLEN on success. Checks that the encoded length does not exhaust the length of the provided buffer. */ static int parse_tag (unsigned char const **buffer, size_t *buflen, struct tag_info *ti) { int c; unsigned long tag; const unsigned char *buf = *buffer; size_t length = *buflen; ti->length = 0; ti->ndef = 0; ti->nhdr = 0; /* Get the tag */ if (!length) return -1; /* Premature EOF. */ c = *buf++; length--; ti->nhdr++; ti->class = (c & 0xc0) >> 6; ti->cons = !!(c & 0x20); tag = (c & 0x1f); if (tag == 0x1f) { tag = 0; do { tag <<= 7; if (!length) return -1; /* Premature EOF. */ c = *buf++; length--; ti->nhdr++; tag |= (c & 0x7f); } while ( (c & 0x80) ); } ti->tag = tag; /* Get the length */ if (!length) return -1; /* Premature EOF. */ c = *buf++; length--; ti->nhdr++; if ( !(c & 0x80) ) ti->length = c; else if (c == 0x80) ti->ndef = 1; else if (c == 0xff) return -1; /* Forbidden length value. */ else { unsigned long len = 0; int count = c & 0x7f; for (; count; count--) { len <<= 8; if (!length) return -1; /* Premature EOF. */ c = *buf++; length--; ti->nhdr++; len |= (c & 0xff); } ti->length = len; } if (ti->class == UNIVERSAL && !ti->tag) ti->length = 0; if (ti->length > length) return -1; /* Data larger than buffer. */ *buffer = buf; *buflen = length; return 0; } /* Read the file FNAME assuming it is a PEM encoded private key file and return an S-expression. With SHOW set, the key parameters are printed. */ static gcry_sexp_t read_private_key_file (const char *fname, int show) { gcry_error_t err; FILE *fp; char *buffer; size_t buflen; const unsigned char *der; size_t derlen; struct tag_info ti; gcry_mpi_t keyparms[8]; int n_keyparms = 8; int idx; gcry_sexp_t s_key; fp = fopen (fname, binary_input?"rb":"r"); if (!fp) die ("can't open `%s': %s\n", fname, strerror (errno)); buffer = read_file (fp, 0, &buflen); if (!buffer) die ("error reading `%s'\n", fname); fclose (fp); buflen = base64_decode (buffer, buflen); /* Parse the ASN.1 structure. */ der = (const unsigned char*)buffer; derlen = buflen; if ( parse_tag (&der, &derlen, &ti) || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) goto bad_asn1; if ( parse_tag (&der, &derlen, &ti) || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef) goto bad_asn1; if (ti.length != 1 || *der) goto bad_asn1; /* The value of the first integer is no 0. */ der += ti.length; derlen -= ti.length; for (idx=0; idx < n_keyparms; idx++) { if ( parse_tag (&der, &derlen, &ti) || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef) goto bad_asn1; if (show) { char prefix[2]; prefix[0] = idx < 8? "nedpq12u"[idx] : '?'; prefix[1] = 0; showhex (prefix, der, ti.length); } err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL); if (err) die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err)); der += ti.length; derlen -= ti.length; } if (idx != n_keyparms) die ("not enough RSA key parameters\n"); gcry_free (buffer); /* Convert from OpenSSL parameter ordering to the OpenPGP order. */ /* First check that p < q; if not swap p and q and recompute u. */ if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0) { gcry_mpi_swap (keyparms[3], keyparms[4]); gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]); } /* Build the S-expression. */ err = gcry_sexp_build (&s_key, NULL, "(private-key(rsa(n%m)(e%m)" /**/ "(d%m)(p%m)(q%m)(u%m)))", keyparms[0], keyparms[1], keyparms[2], keyparms[3], keyparms[4], keyparms[7] ); if (err) die ("error building S-expression: %s\n", gpg_strerror (err)); for (idx=0; idx < n_keyparms; idx++) gcry_mpi_release (keyparms[idx]); return s_key; bad_asn1: die ("invalid ASN.1 structure in `%s'\n", fname); return NULL; /*NOTREACHED*/ } /* Read the file FNAME assuming it is a PEM encoded public key file and return an S-expression. With SHOW set, the key parameters are printed. */ static gcry_sexp_t read_public_key_file (const char *fname, int show) { gcry_error_t err; FILE *fp; char *buffer; size_t buflen; const unsigned char *der; size_t derlen; struct tag_info ti; gcry_mpi_t keyparms[2]; int n_keyparms = 2; int idx; gcry_sexp_t s_key; fp = fopen (fname, binary_input?"rb":"r"); if (!fp) die ("can't open `%s': %s\n", fname, strerror (errno)); buffer = read_file (fp, 0, &buflen); if (!buffer) die ("error reading `%s'\n", fname); fclose (fp); buflen = base64_decode (buffer, buflen); /* Parse the ASN.1 structure. */ der = (const unsigned char*)buffer; derlen = buflen; if ( parse_tag (&der, &derlen, &ti) || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) goto bad_asn1; if ( parse_tag (&der, &derlen, &ti) || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) goto bad_asn1; /* We skip the description of the key parameters and assume it is RSA. */ der += ti.length; derlen -= ti.length; if ( parse_tag (&der, &derlen, &ti) || ti.tag != TAG_BIT_STRING || ti.class || ti.cons || ti.ndef) goto bad_asn1; if (ti.length < 1 || *der) goto bad_asn1; /* The number of unused bits needs to be 0. */ der += 1; derlen -= 1; /* Parse the BIT string. */ if ( parse_tag (&der, &derlen, &ti) || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) goto bad_asn1; for (idx=0; idx < n_keyparms; idx++) { if ( parse_tag (&der, &derlen, &ti) || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef) goto bad_asn1; if (show) { char prefix[2]; prefix[0] = idx < 2? "ne"[idx] : '?'; prefix[1] = 0; showhex (prefix, der, ti.length); } err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL); if (err) die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err)); der += ti.length; derlen -= ti.length; } if (idx != n_keyparms) die ("not enough RSA key parameters\n"); gcry_free (buffer); /* Build the S-expression. */ err = gcry_sexp_build (&s_key, NULL, "(public-key(rsa(n%m)(e%m)))", keyparms[0], keyparms[1] ); if (err) die ("error building S-expression: %s\n", gpg_strerror (err)); for (idx=0; idx < n_keyparms; idx++) gcry_mpi_release (keyparms[idx]); return s_key; bad_asn1: die ("invalid ASN.1 structure in `%s'\n", fname); return NULL; /*NOTREACHED*/ } /* Read the file FNAME assuming it is a binary signature result and return an an S-expression suitable for gcry_pk_verify. */ static gcry_sexp_t read_sig_file (const char *fname) { gcry_error_t err; FILE *fp; char *buffer; size_t buflen; gcry_mpi_t tmpmpi; gcry_sexp_t s_sig; fp = fopen (fname, "rb"); if (!fp) die ("can't open `%s': %s\n", fname, strerror (errno)); buffer = read_file (fp, 0, &buflen); if (!buffer) die ("error reading `%s'\n", fname); fclose (fp); err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, buffer, buflen, NULL); if (!err) err = gcry_sexp_build (&s_sig, NULL, "(sig-val(rsa(s %m)))", tmpmpi); if (err) die ("error building S-expression: %s\n", gpg_strerror (err)); gcry_mpi_release (tmpmpi); gcry_free (buffer); return s_sig; } /* Read an S-expression from FNAME. */ static gcry_sexp_t read_sexp_from_file (const char *fname) { gcry_error_t err; FILE *fp; char *buffer; size_t buflen; gcry_sexp_t sexp; fp = fopen (fname, "rb"); if (!fp) die ("can't open `%s': %s\n", fname, strerror (errno)); buffer = read_file (fp, 0, &buflen); if (!buffer) die ("error reading `%s'\n", fname); fclose (fp); if (!buflen) die ("error: file `%s' is empty\n", fname); err = gcry_sexp_create (&sexp, buffer, buflen, 1, gcry_free); if (err) die ("error parsing `%s': %s\n", fname, gpg_strerror (err)); return sexp; } static void print_buffer (const void *buffer, size_t length) { int writerr = 0; if (base64_output) { static const unsigned char bintoasc[64+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; const unsigned char *p; unsigned char inbuf[4]; char outbuf[4]; int idx, quads; idx = quads = 0; for (p = buffer; length; p++, length--) { inbuf[idx++] = *p; if (idx > 2) { outbuf[0] = bintoasc[(*inbuf>>2)&077]; outbuf[1] = bintoasc[(((*inbuf<<4)&060) |((inbuf[1] >> 4)&017))&077]; outbuf[2] = bintoasc[(((inbuf[1]<<2)&074) |((inbuf[2]>>6)&03))&077]; outbuf[3] = bintoasc[inbuf[2]&077]; if (fwrite (outbuf, 4, 1, stdout) != 1) writerr = 1; idx = 0; if (++quads >= (64/4)) { if (fwrite ("\n", 1, 1, stdout) != 1) writerr = 1; quads = 0; } } } if (idx) { outbuf[0] = bintoasc[(*inbuf>>2)&077]; if (idx == 1) { outbuf[1] = bintoasc[((*inbuf<<4)&060)&077]; outbuf[2] = outbuf[3] = '='; } else { outbuf[1] = bintoasc[(((*inbuf<<4)&060) |((inbuf[1]>>4)&017))&077]; outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077]; outbuf[3] = '='; } if (fwrite (outbuf, 4, 1, stdout) != 1) writerr = 1; quads++; } if (quads && fwrite ("\n", 1, 1, stdout) != 1) writerr = 1; } else if (binary_output) { if (fwrite (buffer, length, 1, stdout) != 1) writerr++; } else { const unsigned char *p = buffer; if (verbose > 1) showhex ("sent line", buffer, length); while (length-- && !ferror (stdout) ) printf ("%02X", *p++); if (ferror (stdout)) writerr++; } if (!writerr && fflush (stdout) == EOF) writerr++; if (writerr) { #ifndef HAVE_W32_SYSTEM if (loop_mode && errno == EPIPE) loop_mode = 0; else #endif die ("writing output failed: %s\n", strerror (errno)); } } /* Print an MPI on a line. */ static void print_mpi_line (gcry_mpi_t a, int no_lz) { unsigned char *buf, *p; gcry_error_t err; int writerr = 0; err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a); if (err) die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); p = buf; if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) p += 2; printf ("%s\n", p); if (ferror (stdout)) writerr++; if (!writerr && fflush (stdout) == EOF) writerr++; if (writerr) die ("writing output failed: %s\n", strerror (errno)); gcry_free (buf); } /* Print some data on hex format on a line. */ static void print_data_line (const void *data, size_t datalen) { const unsigned char *p = data; int writerr = 0; while (data && datalen-- && !ferror (stdout) ) printf ("%02X", *p++); putchar ('\n'); if (ferror (stdout)) writerr++; if (!writerr && fflush (stdout) == EOF) writerr++; if (writerr) die ("writing output failed: %s\n", strerror (errno)); } /* Print the S-expression A to the stream FP. */ static void print_sexp (gcry_sexp_t a, FILE *fp) { char *buf; size_t size; size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = gcry_xmalloc (size); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); if (fwrite (buf, size, 1, fp) != 1) die ("error writing to stream: %s\n", strerror (errno)); gcry_free (buf); } static gcry_error_t init_external_rng_test (void **r_context, unsigned int flags, const void *key, size_t keylen, const void *seed, size_t seedlen, const void *dt, size_t dtlen) { return gcry_control (PRIV_CTL_INIT_EXTRNG_TEST, r_context, flags, key, keylen, seed, seedlen, dt, dtlen); } static gcry_error_t run_external_rng_test (void *context, void *buffer, size_t buflen) { return gcry_control (PRIV_CTL_RUN_EXTRNG_TEST, context, buffer, buflen); } static void deinit_external_rng_test (void *context) { gcry_control (PRIV_CTL_DEINIT_EXTRNG_TEST, context); } /* Given an OpenSSL cipher name NAME, return the Libgcrypt algirithm identified and store the libgcrypt mode at R_MODE. Returns 0 on error. */ static int map_openssl_cipher_name (const char *name, int *r_mode) { static struct { const char *name; int algo; int mode; } table[] = { { "bf-cbc", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC }, { "bf", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC }, { "bf-cfb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB }, { "bf-ecb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB }, { "bf-ofb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB }, { "cast-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC }, { "cast", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC }, { "cast5-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC }, { "cast5-cfb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB }, { "cast5-ecb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB }, { "cast5-ofb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB }, { "des-cbc", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC }, { "des", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC }, { "des-cfb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB }, { "des-ofb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB }, { "des-ecb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB }, { "des-ede3-cbc", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC }, { "des-ede3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB }, { "des3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC }, { "des-ede3-cfb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB }, { "des-ede3-ofb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB }, { "rc4", GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM }, { "aes-128-cbc", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC }, { "aes-128", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC }, { "aes-128-cfb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB }, { "aes-128-ecb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB }, { "aes-128-ofb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB }, { "aes-192-cbc", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC }, { "aes-192", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC }, { "aes-192-cfb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB }, { "aes-192-ecb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB }, { "aes-192-ofb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB }, { "aes-256-cbc", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC }, { "aes-256", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC }, { "aes-256-cfb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB }, { "aes-256-ecb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB }, { "aes-256-ofb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB }, { NULL, 0 , 0 } }; int idx; for (idx=0; table[idx].name; idx++) if (!strcmp (name, table[idx].name)) { *r_mode = table[idx].mode; return table[idx].algo; } *r_mode = 0; return 0; } /* Run an encrypt or decryption operations. If DATA is NULL the function reads its input in chunks of size DATALEN from fp and processes it and writes it out until EOF. */ static void run_encrypt_decrypt (int encrypt_mode, int cipher_algo, int cipher_mode, const void *iv_buffer, size_t iv_buflen, const void *key_buffer, size_t key_buflen, const void *data, size_t datalen, FILE *fp) { gpg_error_t err; gcry_cipher_hd_t hd; void *outbuf; size_t outbuflen; void *inbuf; size_t inbuflen; size_t blocklen; err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0); if (err) die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", cipher_algo, cipher_mode, gpg_strerror (err)); blocklen = gcry_cipher_get_algo_blklen (cipher_algo); assert (blocklen); gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0); err = gcry_cipher_setkey (hd, key_buffer, key_buflen); if (err) die ("gcry_cipher_setkey failed with keylen %u: %s\n", (unsigned int)key_buflen, gpg_strerror (err)); if (iv_buffer) { err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen); if (err) die ("gcry_cipher_setiv failed with ivlen %u: %s\n", (unsigned int)iv_buflen, gpg_strerror (err)); } inbuf = data? NULL : gcry_xmalloc (datalen); outbuflen = datalen; outbuf = gcry_xmalloc (outbuflen < blocklen? blocklen:outbuflen); do { if (inbuf) { int nread = fread (inbuf, 1, datalen, fp); if (nread < (int)datalen && ferror (fp)) die ("error reading input\n"); data = inbuf; inbuflen = nread; } else inbuflen = datalen; if (encrypt_mode) err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen); else err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen); if (err) die ("gcry_cipher_%scrypt failed: %s\n", encrypt_mode? "en":"de", gpg_strerror (err)); print_buffer (outbuf, outbuflen); } while (inbuf); gcry_cipher_close (hd); gcry_free (outbuf); gcry_free (inbuf); } static void get_current_iv (gcry_cipher_hd_t hd, void *buffer, size_t buflen) { unsigned char tmp[17]; if (gcry_cipher_ctl (hd, PRIV_CTL_GET_INPUT_VECTOR, tmp, sizeof tmp)) die ("error getting current input vector\n"); if (buflen > *tmp) die ("buffer too short to store the current input vector\n"); memcpy (buffer, tmp+1, *tmp); } /* Run the inner loop of the CAVS monte carlo test. */ static void run_cipher_mct_loop (int encrypt_mode, int cipher_algo, int cipher_mode, const void *iv_buffer, size_t iv_buflen, const void *key_buffer, size_t key_buflen, const void *data, size_t datalen, int iterations) { gpg_error_t err; gcry_cipher_hd_t hd; size_t blocklen; int count; char input[16]; char output[16]; char last_output[16]; char last_last_output[16]; char last_iv[16]; err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0); if (err) die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", cipher_algo, cipher_mode, gpg_strerror (err)); blocklen = gcry_cipher_get_algo_blklen (cipher_algo); if (!blocklen || blocklen > sizeof output) die ("invalid block length %d\n", blocklen); gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0); err = gcry_cipher_setkey (hd, key_buffer, key_buflen); if (err) die ("gcry_cipher_setkey failed with keylen %u: %s\n", (unsigned int)key_buflen, gpg_strerror (err)); if (iv_buffer) { err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen); if (err) die ("gcry_cipher_setiv failed with ivlen %u: %s\n", (unsigned int)iv_buflen, gpg_strerror (err)); } if (datalen != blocklen) die ("length of input (%u) does not match block length (%u)\n", (unsigned int)datalen, (unsigned int)blocklen); memcpy (input, data, datalen); memset (output, 0, sizeof output); for (count=0; count < iterations; count++) { memcpy (last_last_output, last_output, sizeof last_output); memcpy (last_output, output, sizeof output); get_current_iv (hd, last_iv, blocklen); if (encrypt_mode) err = gcry_cipher_encrypt (hd, output, blocklen, input, blocklen); else err = gcry_cipher_decrypt (hd, output, blocklen, input, blocklen); if (err) die ("gcry_cipher_%scrypt failed: %s\n", encrypt_mode? "en":"de", gpg_strerror (err)); if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB || cipher_mode == GCRY_CIPHER_MODE_CBC)) memcpy (input, last_iv, blocklen); else if (cipher_mode == GCRY_CIPHER_MODE_OFB) memcpy (input, last_iv, blocklen); else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) { /* Reconstruct the output vector. */ int i; for (i=0; i < blocklen; i++) input[i] ^= output[i]; } else memcpy (input, output, blocklen); } print_buffer (output, blocklen); putchar ('\n'); print_buffer (last_output, blocklen); putchar ('\n'); print_buffer (last_last_output, blocklen); putchar ('\n'); get_current_iv (hd, last_iv, blocklen); print_buffer (last_iv, blocklen); /* Last output vector. */ putchar ('\n'); print_buffer (input, blocklen); /* Next input text. */ putchar ('\n'); if (verbose > 1) showhex ("sent line", "", 0); putchar ('\n'); fflush (stdout); gcry_cipher_close (hd); } /* Run a digest operation. */ static void run_digest (int digest_algo, const void *data, size_t datalen) { gpg_error_t err; gcry_md_hd_t hd; const unsigned char *digest; unsigned int digestlen; err = gcry_md_open (&hd, digest_algo, 0); if (err) die ("gcry_md_open failed for algo %d: %s\n", digest_algo, gpg_strerror (err)); gcry_md_write (hd, data, datalen); digest = gcry_md_read (hd, digest_algo); digestlen = gcry_md_get_algo_dlen (digest_algo); print_buffer (digest, digestlen); gcry_md_close (hd); } /* Run a HMAC operation. */ static void run_hmac (int digest_algo, const void *key, size_t keylen, const void *data, size_t datalen) { gpg_error_t err; gcry_md_hd_t hd; const unsigned char *digest; unsigned int digestlen; err = gcry_md_open (&hd, digest_algo, GCRY_MD_FLAG_HMAC); if (err) die ("gcry_md_open failed for HMAC algo %d: %s\n", digest_algo, gpg_strerror (err)); gcry_md_setkey (hd, key, keylen); if (err) die ("gcry_md_setkey failed for HMAC algo %d: %s\n", digest_algo, gpg_strerror (err)); gcry_md_write (hd, data, datalen); digest = gcry_md_read (hd, digest_algo); digestlen = gcry_md_get_algo_dlen (digest_algo); print_buffer (digest, digestlen); gcry_md_close (hd); } /* Derive an RSA key using the S-expression in (DATA,DATALEN). This S-expression is used directly as input to gcry_pk_genkey. The result is printed to stdout with one parameter per line in hex format and in this order: p, q, n, d. */ static void run_rsa_derive (const void *data, size_t datalen) { gpg_error_t err; gcry_sexp_t s_keyspec, s_key, s_top, l1; gcry_mpi_t mpi; const char *parmlist; int idx; if (!datalen) err = gpg_error (GPG_ERR_NO_DATA); else err = gcry_sexp_new (&s_keyspec, data, datalen, 1); if (err) die ("gcry_sexp_new failed for RSA key derive: %s\n", gpg_strerror (err)); err = gcry_pk_genkey (&s_key, s_keyspec); if (err) die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); gcry_sexp_release (s_keyspec); /* P and Q might have been swapped but we need to to return them in the proper order. Build the parameter list accordingly. */ parmlist = "pqnd"; s_top = gcry_sexp_find_token (s_key, "misc-key-info", 0); if (s_top) { l1 = gcry_sexp_find_token (s_top, "p-q-swapped", 0); if (l1) parmlist = "qpnd"; gcry_sexp_release (l1); gcry_sexp_release (s_top); } /* Parse and print the parameters. */ l1 = gcry_sexp_find_token (s_key, "private-key", 0); s_top = gcry_sexp_find_token (l1, "rsa", 0); gcry_sexp_release (l1); if (!s_top) die ("private-key part not found in result\n"); for (idx=0; parmlist[idx]; idx++) { l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1); mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); gcry_sexp_release (l1); if (!mpi) die ("parameter %c missing in private-key\n", parmlist[idx]); print_mpi_line (mpi, 1); gcry_mpi_release (mpi); } gcry_sexp_release (s_top); gcry_sexp_release (s_key); } static size_t compute_tag_length (size_t n) { int needed = 0; if (n < 128) needed += 2; /* Tag and one length byte. */ else if (n < 256) needed += 3; /* Tag, number of length bytes, 1 length byte. */ else if (n < 65536) needed += 4; /* Tag, number of length bytes, 2 length bytes. */ else die ("DER object too long to encode\n"); return needed; } static unsigned char * store_tag_length (unsigned char *p, int tag, size_t n) { if (tag == TAG_SEQUENCE) tag |= 0x20; /* constructed */ *p++ = tag; if (n < 128) *p++ = n; else if (n < 256) { *p++ = 0x81; *p++ = n; } else if (n < 65536) { *p++ = 0x82; *p++ = n >> 8; *p++ = n; } return p; } /* Generate an RSA key of size KEYSIZE using the public exponent PUBEXP and print it to stdout in the OpenSSL format. The format is: SEQUENCE { INTEGER (0) -- Unknown constant. INTEGER -- n INTEGER -- e INTEGER -- d INTEGER -- p INTEGER -- q (with p < q) INTEGER -- dmp1 = d mod (p-1) INTEGER -- dmq1 = d mod (q-1) INTEGER -- u = p^{-1} mod q } */ static void run_rsa_gen (int keysize, int pubexp) { gpg_error_t err; gcry_sexp_t keyspec, key, l1; const char keyelems[] = "nedpq..u"; gcry_mpi_t keyparms[8]; size_t keyparmslen[8]; int idx; size_t derlen, needed, n; unsigned char *derbuf, *der; err = gcry_sexp_build (&keyspec, NULL, "(genkey (rsa (nbits %d)(rsa-use-e %d)))", keysize, pubexp); if (err) die ("gcry_sexp_build failed for RSA key generation: %s\n", gpg_strerror (err)); err = gcry_pk_genkey (&key, keyspec); if (err) die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); gcry_sexp_release (keyspec); l1 = gcry_sexp_find_token (key, "private-key", 0); if (!l1) die ("private key not found in genkey result\n"); gcry_sexp_release (key); key = l1; l1 = gcry_sexp_find_token (key, "rsa", 0); if (!l1) die ("returned private key not formed as expected\n"); gcry_sexp_release (key); key = l1; /* Extract the parameters from the S-expression and store them in a well defined order in KEYPARMS. */ for (idx=0; idx < DIM(keyparms); idx++) { if (keyelems[idx] == '.') { keyparms[idx] = gcry_mpi_new (0); continue; } l1 = gcry_sexp_find_token (key, keyelems+idx, 1); if (!l1) die ("no %c parameter in returned private key\n", keyelems[idx]); keyparms[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); if (!keyparms[idx]) die ("no value for %c parameter in returned private key\n", keyelems[idx]); gcry_sexp_release (l1); } gcry_sexp_release (key); /* Check that p < q; if not swap p and q and recompute u. */ if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0) { gcry_mpi_swap (keyparms[3], keyparms[4]); gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]); } /* Compute the additional parameters. */ gcry_mpi_sub_ui (keyparms[5], keyparms[3], 1); gcry_mpi_mod (keyparms[5], keyparms[2], keyparms[5]); gcry_mpi_sub_ui (keyparms[6], keyparms[4], 1); gcry_mpi_mod (keyparms[6], keyparms[2], keyparms[6]); /* Compute the length of the DER encoding. */ needed = compute_tag_length (1) + 1; for (idx=0; idx < DIM(keyparms); idx++) { err = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, keyparms[idx]); if (err) die ("error formatting parameter: %s\n", gpg_strerror (err)); keyparmslen[idx] = n; needed += compute_tag_length (n) + n; } /* Store the key parameters. */ derlen = compute_tag_length (needed) + needed; der = derbuf = gcry_xmalloc (derlen); der = store_tag_length (der, TAG_SEQUENCE, needed); der = store_tag_length (der, TAG_INTEGER, 1); *der++ = 0; for (idx=0; idx < DIM(keyparms); idx++) { der = store_tag_length (der, TAG_INTEGER, keyparmslen[idx]); err = gcry_mpi_print (GCRYMPI_FMT_STD, der, keyparmslen[idx], NULL, keyparms[idx]); if (err) die ("error formatting parameter: %s\n", gpg_strerror (err)); der += keyparmslen[idx]; } /* Print the stuff. */ for (idx=0; idx < DIM(keyparms); idx++) gcry_mpi_release (keyparms[idx]); assert (der - derbuf == derlen); if (base64_output) puts ("-----BEGIN RSA PRIVATE KEY-----"); print_buffer (derbuf, derlen); if (base64_output) puts ("-----END RSA PRIVATE KEY-----"); gcry_free (derbuf); } /* Sign DATA of length DATALEN using the key taken from the PEM encoded KEYFILE and the hash algorithm HASHALGO. */ static void run_rsa_sign (const void *data, size_t datalen, int hashalgo, int pkcs1, const char *keyfile) { gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig, s_tmp; gcry_mpi_t sig_mpi = NULL; unsigned char *outbuf; size_t outlen; /* showhex ("D", data, datalen); */ if (pkcs1) { unsigned char hash[64]; unsigned int hashsize; hashsize = gcry_md_get_algo_dlen (hashalgo); if (!hashsize || hashsize > sizeof hash) die ("digest too long for buffer or unknown hash algorithm\n"); gcry_md_hash_buffer (hashalgo, hash, data, datalen); err = gcry_sexp_build (&s_data, NULL, "(data (flags pkcs1)(hash %s %b))", gcry_md_algo_name (hashalgo), (int)hashsize, hash); } else { gcry_mpi_t tmp; err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL); if (!err) { err = gcry_sexp_build (&s_data, NULL, "(data (flags raw)(value %m))", tmp); gcry_mpi_release (tmp); } } if (err) die ("gcry_sexp_build failed for RSA data input: %s\n", gpg_strerror (err)); s_key = read_private_key_file (keyfile, 0); err = gcry_pk_sign (&s_sig, s_data, s_key); if (err) { gcry_sexp_release (read_private_key_file (keyfile, 1)); die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n", (int)datalen, keyfile, gpg_strerror (err)); } gcry_sexp_release (s_key); gcry_sexp_release (s_data); s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0); if (s_tmp) { gcry_sexp_release (s_sig); s_sig = s_tmp; s_tmp = gcry_sexp_find_token (s_sig, "rsa", 0); if (s_tmp) { gcry_sexp_release (s_sig); s_sig = s_tmp; s_tmp = gcry_sexp_find_token (s_sig, "s", 0); if (s_tmp) { gcry_sexp_release (s_sig); s_sig = s_tmp; sig_mpi = gcry_sexp_nth_mpi (s_sig, 1, GCRYMPI_FMT_USG); } } } gcry_sexp_release (s_sig); if (!sig_mpi) die ("no value in returned S-expression\n"); err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &outbuf, &outlen, sig_mpi); if (err) die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); gcry_mpi_release (sig_mpi); print_buffer (outbuf, outlen); gcry_free (outbuf); } /* Verify DATA of length DATALEN using the public key taken from the PEM encoded KEYFILE and the hash algorithm HASHALGO against the binary signature in SIGFILE. */ static void run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1, const char *keyfile, const char *sigfile) { gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig; if (pkcs1) { unsigned char hash[64]; unsigned int hashsize; hashsize = gcry_md_get_algo_dlen (hashalgo); if (!hashsize || hashsize > sizeof hash) die ("digest too long for buffer or unknown hash algorithm\n"); gcry_md_hash_buffer (hashalgo, hash, data, datalen); err = gcry_sexp_build (&s_data, NULL, "(data (flags pkcs1)(hash %s %b))", gcry_md_algo_name (hashalgo), (int)hashsize, hash); } else { gcry_mpi_t tmp; err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL); if (!err) { err = gcry_sexp_build (&s_data, NULL, "(data (flags raw)(value %m))", tmp); gcry_mpi_release (tmp); } } if (err) die ("gcry_sexp_build failed for RSA data input: %s\n", gpg_strerror (err)); s_key = read_public_key_file (keyfile, 0); s_sig = read_sig_file (sigfile); err = gcry_pk_verify (s_sig, s_data, s_key); if (!err) puts ("GOOD signature"); else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE) puts ("BAD signature"); else printf ("ERROR (%s)\n", gpg_strerror (err)); gcry_sexp_release (s_sig); gcry_sexp_release (s_key); gcry_sexp_release (s_data); } /* Generate a DSA key of size KEYSIZE and return the complete S-expression. */ static gcry_sexp_t dsa_gen (int keysize) { gpg_error_t err; gcry_sexp_t keyspec, key; err = gcry_sexp_build (&keyspec, NULL, "(genkey (dsa (nbits %d)(use-fips186-2)))", keysize); if (err) die ("gcry_sexp_build failed for DSA key generation: %s\n", gpg_strerror (err)); err = gcry_pk_genkey (&key, keyspec); if (err) die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); gcry_sexp_release (keyspec); return key; } /* Generate a DSA key of size KEYSIZE and return the complete S-expression. */ static gcry_sexp_t dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) { gpg_error_t err; gcry_sexp_t keyspec, key; err = gcry_sexp_build (&keyspec, NULL, "(genkey" " (dsa" " (nbits %d)" " (use-fips186-2)" " (derive-parms" " (seed %b))))", keysize, (int)seedlen, seed); if (err) die ("gcry_sexp_build failed for DSA key generation: %s\n", gpg_strerror (err)); err = gcry_pk_genkey (&key, keyspec); if (err) die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); gcry_sexp_release (keyspec); return key; } /* Print the domain parameter as well as the derive information. KEY is the complete key as returned by dsa_gen. We print to stdout with one parameter per line in hex format using this order: p, q, g, seed, counter, h. */ static void print_dsa_domain_parameters (gcry_sexp_t key) { gcry_sexp_t l1, l2; gcry_mpi_t mpi; int idx; const void *data; size_t datalen; char *string; l1 = gcry_sexp_find_token (key, "public-key", 0); if (!l1) die ("public key not found in genkey result\n"); l2 = gcry_sexp_find_token (l1, "dsa", 0); if (!l2) die ("returned public key not formed as expected\n"); gcry_sexp_release (l1); l1 = l2; /* Extract the parameters from the S-expression and print them to stdout. */ for (idx=0; "pqg"[idx]; idx++) { l2 = gcry_sexp_find_token (l1, "pqg"+idx, 1); if (!l2) die ("no %c parameter in returned public key\n", "pqg"[idx]); mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); if (!mpi) die ("no value for %c parameter in returned public key\n","pqg"[idx]); gcry_sexp_release (l2); if (standalone_mode) printf ("%c = ", "PQG"[idx]); print_mpi_line (mpi, 1); gcry_mpi_release (mpi); } gcry_sexp_release (l1); /* Extract the seed values. */ l1 = gcry_sexp_find_token (key, "misc-key-info", 0); if (!l1) die ("misc-key-info not found in genkey result\n"); l2 = gcry_sexp_find_token (l1, "seed-values", 0); if (!l2) die ("no seed-values in returned key\n"); gcry_sexp_release (l1); l1 = l2; l2 = gcry_sexp_find_token (l1, "seed", 0); if (!l2) die ("no seed value in returned key\n"); data = gcry_sexp_nth_data (l2, 1, &datalen); if (!data) die ("no seed value in returned key\n"); if (standalone_mode) printf ("Seed = "); print_data_line (data, datalen); gcry_sexp_release (l2); l2 = gcry_sexp_find_token (l1, "counter", 0); if (!l2) die ("no counter value in returned key\n"); string = gcry_sexp_nth_string (l2, 1); if (!string) die ("no counter value in returned key\n"); if (standalone_mode) printf ("c = %ld\n", strtoul (string, NULL, 10)); else printf ("%lX\n", strtoul (string, NULL, 10)); gcry_free (string); gcry_sexp_release (l2); l2 = gcry_sexp_find_token (l1, "h", 0); if (!l2) die ("no n value in returned key\n"); mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); if (!mpi) die ("no h value in returned key\n"); if (standalone_mode) printf ("H = "); print_mpi_line (mpi, 1); gcry_mpi_release (mpi); gcry_sexp_release (l2); gcry_sexp_release (l1); } /* Generate DSA domain parameters for a modulus size of KEYSIZE. The result is printed to stdout with one parameter per line in hex format and in this order: p, q, g, seed, counter, h. If SEED is not NULL this seed value will be used for the generation. */ static void run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) { gcry_sexp_t key; if (seed) key = dsa_gen_with_seed (keysize, seed, seedlen); else key = dsa_gen (keysize); print_dsa_domain_parameters (key); gcry_sexp_release (key); } /* Generate a DSA key of size of KEYSIZE and write the private key to FILENAME. Also write the parameters to stdout in the same way as run_dsa_pqg_gen. */ static void run_dsa_gen (int keysize, const char *filename) { gcry_sexp_t key, private_key; FILE *fp; key = dsa_gen (keysize); private_key = gcry_sexp_find_token (key, "private-key", 0); if (!private_key) die ("private key not found in genkey result\n"); print_dsa_domain_parameters (key); fp = fopen (filename, "wb"); if (!fp) die ("can't create `%s': %s\n", filename, strerror (errno)); print_sexp (private_key, fp); fclose (fp); gcry_sexp_release (private_key); gcry_sexp_release (key); } /* Sign DATA of length DATALEN using the key taken from the S-expression encoded KEYFILE. */ static void run_dsa_sign (const void *data, size_t datalen, const char *keyfile) { gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; char hash[20]; gcry_mpi_t tmpmpi; gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); if (!err) { err = gcry_sexp_build (&s_data, NULL, "(data (flags raw)(value %m))", tmpmpi); gcry_mpi_release (tmpmpi); } if (err) die ("gcry_sexp_build failed for DSA data input: %s\n", gpg_strerror (err)); s_key = read_sexp_from_file (keyfile); err = gcry_pk_sign (&s_sig, s_data, s_key); if (err) { gcry_sexp_release (read_private_key_file (keyfile, 1)); die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n", (int)datalen, keyfile, gpg_strerror (err)); } gcry_sexp_release (s_data); /* We need to return the Y parameter first. */ s_tmp = gcry_sexp_find_token (s_key, "private-key", 0); if (!s_tmp) die ("private key part not found in provided key\n"); s_tmp2 = gcry_sexp_find_token (s_tmp, "dsa", 0); if (!s_tmp2) die ("private key part is not a DSA key\n"); gcry_sexp_release (s_tmp); s_tmp = gcry_sexp_find_token (s_tmp2, "y", 0); tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); if (!tmpmpi) die ("no y parameter in DSA key\n"); print_mpi_line (tmpmpi, 1); gcry_mpi_release (tmpmpi); gcry_sexp_release (s_tmp); gcry_sexp_release (s_key); /* Now return the actual signature. */ s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0); if (!s_tmp) die ("no sig-val element in returned S-expression\n"); gcry_sexp_release (s_sig); s_sig = s_tmp; s_tmp = gcry_sexp_find_token (s_sig, "dsa", 0); if (!s_tmp) die ("no dsa element in returned S-expression\n"); gcry_sexp_release (s_sig); s_sig = s_tmp; s_tmp = gcry_sexp_find_token (s_sig, "r", 0); tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); if (!tmpmpi) die ("no r parameter in returned S-expression\n"); print_mpi_line (tmpmpi, 1); gcry_mpi_release (tmpmpi); gcry_sexp_release (s_tmp); s_tmp = gcry_sexp_find_token (s_sig, "s", 0); tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); if (!tmpmpi) die ("no s parameter in returned S-expression\n"); print_mpi_line (tmpmpi, 1); gcry_mpi_release (tmpmpi); gcry_sexp_release (s_tmp); gcry_sexp_release (s_sig); } /* Verify DATA of length DATALEN using the public key taken from the S-expression in KEYFILE against the S-expression formatted signature in SIGFILE. */ static void run_dsa_verify (const void *data, size_t datalen, const char *keyfile, const char *sigfile) { gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig; char hash[20]; gcry_mpi_t tmpmpi; gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); /* Note that we can't simply use %b with HASH to build the S-expression, because that might yield a negative value. */ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); if (!err) { err = gcry_sexp_build (&s_data, NULL, "(data (flags raw)(value %m))", tmpmpi); gcry_mpi_release (tmpmpi); } if (err) die ("gcry_sexp_build failed for DSA data input: %s\n", gpg_strerror (err)); s_key = read_sexp_from_file (keyfile); s_sig = read_sexp_from_file (sigfile); err = gcry_pk_verify (s_sig, s_data, s_key); if (!err) puts ("GOOD signature"); else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE) puts ("BAD signature"); else printf ("ERROR (%s)\n", gpg_strerror (err)); gcry_sexp_release (s_sig); gcry_sexp_release (s_key); gcry_sexp_release (s_data); } static void usage (int show_help) { if (!show_help) { fputs ("usage: " PGM " [OPTION] [FILE] (try --help for more information)\n", stderr); exit (2); } fputs ("Usage: " PGM " [OPTIONS] MODE [FILE]\n" "Run a crypto operation using hex encoded input and output.\n" "MODE:\n" " encrypt, decrypt, digest, random, hmac-sha,\n" " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n" "OPTIONS:\n" " --verbose Print additional information\n" " --binary Input and output is in binary form\n" " --no-fips Do not force FIPS mode\n" " --key KEY Use the hex encoded KEY\n" " --iv IV Use the hex encoded IV\n" " --dt DT Use the hex encoded DT for the RNG\n" " --algo NAME Use algorithm NAME\n" " --keysize N Use a keysize of N bits\n" " --signature NAME Take signature from file NAME\n" " --chunk N Read in chunks of N bytes (implies --binary)\n" " --pkcs1 Use PKCS#1 encoding\n" " --mct-server Run a monte carlo test server\n" " --loop Enable random loop mode\n" " --progress Print pogress indicators\n" " --help Print this text\n" "With no FILE, or when FILE is -, read standard input.\n" "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout); exit (0); } int main (int argc, char **argv) { int last_argc = -1; gpg_error_t err; int no_fips = 0; int progress = 0; int use_pkcs1 = 0; const char *mode_string; const char *key_string = NULL; const char *iv_string = NULL; const char *dt_string = NULL; const char *algo_string = NULL; const char *keysize_string = NULL; const char *signature_string = NULL; FILE *input; void *data; size_t datalen; size_t chunksize = 0; int mct_server = 0; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--help")) { usage (1); } else if (!strcmp (*argv, "--version")) { fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout); exit (0); } else if (!strcmp (*argv, "--verbose")) { verbose++; argc--; argv++; } else if (!strcmp (*argv, "--binary")) { binary_input = binary_output = 1; argc--; argv++; } else if (!strcmp (*argv, "--no-fips")) { no_fips++; argc--; argv++; } else if (!strcmp (*argv, "--loop")) { loop_mode = 1; argc--; argv++; } else if (!strcmp (*argv, "--progress")) { progress = 1; argc--; argv++; } else if (!strcmp (*argv, "--key")) { argc--; argv++; if (!argc) usage (0); key_string = *argv; argc--; argv++; } else if (!strcmp (*argv, "--iv")) { argc--; argv++; if (!argc) usage (0); iv_string = *argv; argc--; argv++; } else if (!strcmp (*argv, "--dt")) { argc--; argv++; if (!argc) usage (0); dt_string = *argv; argc--; argv++; } else if (!strcmp (*argv, "--algo")) { argc--; argv++; if (!argc) usage (0); algo_string = *argv; argc--; argv++; } else if (!strcmp (*argv, "--keysize")) { argc--; argv++; if (!argc) usage (0); keysize_string = *argv; argc--; argv++; } else if (!strcmp (*argv, "--signature")) { argc--; argv++; if (!argc) usage (0); signature_string = *argv; argc--; argv++; } else if (!strcmp (*argv, "--chunk")) { argc--; argv++; if (!argc) usage (0); chunksize = atoi (*argv); binary_input = binary_output = 1; argc--; argv++; } else if (!strcmp (*argv, "--pkcs1")) { use_pkcs1 = 1; argc--; argv++; } else if (!strcmp (*argv, "--mct-server")) { mct_server = 1; argc--; argv++; } else if (!strcmp (*argv, "--standalone")) { standalone_mode = 1; argc--; argv++; } } if (!argc || argc > 2) usage (0); mode_string = *argv; if (!strcmp (mode_string, "rsa-derive")) binary_input = 1; if (argc == 2 && strcmp (argv[1], "-")) { input = fopen (argv[1], binary_input? "rb":"r"); if (!input) die ("can't open `%s': %s\n", argv[1], strerror (errno)); } else input = stdin; #ifndef HAVE_W32_SYSTEM if (loop_mode) signal (SIGPIPE, SIG_IGN); #endif if (verbose) fprintf (stderr, PGM ": started (mode=%s)\n", mode_string); gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); if (!no_fips) gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); if (!gcry_check_version ("1.4.3")) die ("Libgcrypt is not sufficient enough\n"); if (verbose) fprintf (stderr, PGM ": using Libgcrypt %s\n", gcry_check_version (NULL)); if (no_fips) gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); /* Most operations need some input data. */ if (!chunksize && !mct_server && strcmp (mode_string, "random") && strcmp (mode_string, "rsa-gen") && strcmp (mode_string, "dsa-gen") ) { data = read_file (input, !binary_input, &datalen); if (!data) die ("error reading%s input\n", binary_input?"":" and decoding"); if (verbose) fprintf (stderr, PGM ": %u bytes of input data\n", (unsigned int)datalen); } else { data = NULL; datalen = 0; } if (!strcmp (mode_string, "encrypt") || !strcmp (mode_string, "decrypt")) { int cipher_algo, cipher_mode; void *iv_buffer = NULL; void *key_buffer = NULL; size_t iv_buflen, key_buflen; if (!algo_string) die ("option --algo is required in this mode\n"); cipher_algo = map_openssl_cipher_name (algo_string, &cipher_mode); if (!cipher_algo) die ("cipher algorithm `%s' is not supported\n", algo_string); if (mct_server) { int iterations; for (;;) { gcry_free (key_buffer); key_buffer = NULL; gcry_free (iv_buffer); iv_buffer = NULL; gcry_free (data); data = NULL; if (!(key_buffer = read_textline (input))) { if (feof (input)) break; die ("no version info in input\n"); } if (atoi (key_buffer) != 1) die ("unsupported input version %s\n", key_buffer); gcry_free (key_buffer); if (!(key_buffer = read_textline (input))) die ("no iteration count in input\n"); iterations = atoi (key_buffer); gcry_free (key_buffer); if (!(key_buffer = read_hexline (input, &key_buflen))) die ("no key in input\n"); if (!(iv_buffer = read_hexline (input, &iv_buflen))) die ("no IV in input\n"); if (!(data = read_hexline (input, &datalen))) die ("no data in input\n"); skip_to_empty_line (input); run_cipher_mct_loop ((*mode_string == 'e'), cipher_algo, cipher_mode, iv_buffer, iv_buflen, key_buffer, key_buflen, data, datalen, iterations); } } else { if (cipher_mode != GCRY_CIPHER_MODE_ECB) { if (!iv_string) die ("option --iv is required in this mode\n"); iv_buffer = hex2buffer (iv_string, &iv_buflen); if (!iv_buffer) die ("invalid value for IV\n"); } else { iv_buffer = NULL; iv_buflen = 0; } if (!key_string) die ("option --key is required in this mode\n"); key_buffer = hex2buffer (key_string, &key_buflen); if (!key_buffer) die ("invalid value for KEY\n"); run_encrypt_decrypt ((*mode_string == 'e'), cipher_algo, cipher_mode, iv_buffer, iv_buflen, key_buffer, key_buflen, data, data? datalen:chunksize, input); } gcry_free (key_buffer); gcry_free (iv_buffer); } else if (!strcmp (mode_string, "digest")) { int algo; if (!algo_string) die ("option --algo is required in this mode\n"); algo = gcry_md_map_name (algo_string); if (!algo) die ("digest algorithm `%s' is not supported\n", algo_string); if (!data) die ("no data available (do not use --chunk)\n"); run_digest (algo, data, datalen); } else if (!strcmp (mode_string, "random")) { void *context; unsigned char key[16]; unsigned char seed[16]; unsigned char dt[16]; unsigned char buffer[16]; size_t count = 0; if (hex2bin (key_string, key, 16) < 0 ) die ("value for --key are not 32 hex digits\n"); if (hex2bin (iv_string, seed, 16) < 0 ) die ("value for --iv are not 32 hex digits\n"); if (hex2bin (dt_string, dt, 16) < 0 ) die ("value for --dt are not 32 hex digits\n"); /* The flag value 1 disables the dup check, so that the RNG returns all generated data. */ err = init_external_rng_test (&context, 1, key, 16, seed, 16, dt, 16); if (err) die ("init external RNG test failed: %s\n", gpg_strerror (err)); do { err = run_external_rng_test (context, buffer, sizeof buffer); if (err) die ("running external RNG test failed: %s\n", gpg_strerror (err)); print_buffer (buffer, sizeof buffer); if (progress) { if (!(++count % 1000)) fprintf (stderr, PGM ": %lu random bytes so far\n", (unsigned long int)count * sizeof buffer); } } while (loop_mode); if (progress) fprintf (stderr, PGM ": %lu random bytes\n", (unsigned long int)count * sizeof buffer); deinit_external_rng_test (context); } else if (!strcmp (mode_string, "hmac-sha")) { int algo; void *key_buffer; size_t key_buflen; if (!data) die ("no data available (do not use --chunk)\n"); if (!algo_string) die ("option --algo is required in this mode\n"); switch (atoi (algo_string)) { case 1: algo = GCRY_MD_SHA1; break; case 224: algo = GCRY_MD_SHA224; break; case 256: algo = GCRY_MD_SHA256; break; case 384: algo = GCRY_MD_SHA384; break; case 512: algo = GCRY_MD_SHA512; break; default: algo = 0; break; } if (!algo) die ("no digest algorithm found for hmac type `%s'\n", algo_string); if (!key_string) die ("option --key is required in this mode\n"); key_buffer = hex2buffer (key_string, &key_buflen); if (!key_buffer) die ("invalid value for KEY\n"); run_hmac (algo, key_buffer, key_buflen, data, datalen); gcry_free (key_buffer); } else if (!strcmp (mode_string, "rsa-derive")) { if (!data) die ("no data available (do not use --chunk)\n"); run_rsa_derive (data, datalen); } else if (!strcmp (mode_string, "rsa-gen")) { int keysize; if (!binary_output) base64_output = 1; keysize = keysize_string? atoi (keysize_string) : 0; if (keysize < 128 || keysize > 16384) die ("invalid keysize specified; needs to be 128 .. 16384\n"); run_rsa_gen (keysize, 65537); } else if (!strcmp (mode_string, "rsa-sign")) { int algo; if (!key_string) die ("option --key is required in this mode\n"); if (access (key_string, R_OK)) die ("option --key needs to specify an existing keyfile\n"); if (!algo_string) die ("option --algo is required in this mode\n"); algo = gcry_md_map_name (algo_string); if (!algo) die ("digest algorithm `%s' is not supported\n", algo_string); if (!data) die ("no data available (do not use --chunk)\n"); run_rsa_sign (data, datalen, algo, use_pkcs1, key_string); } else if (!strcmp (mode_string, "rsa-verify")) { int algo; if (!key_string) die ("option --key is required in this mode\n"); if (access (key_string, R_OK)) die ("option --key needs to specify an existing keyfile\n"); if (!algo_string) die ("option --algo is required in this mode\n"); algo = gcry_md_map_name (algo_string); if (!algo) die ("digest algorithm `%s' is not supported\n", algo_string); if (!data) die ("no data available (do not use --chunk)\n"); if (!signature_string) die ("option --signature is required in this mode\n"); if (access (signature_string, R_OK)) die ("option --signature needs to specify an existing file\n"); run_rsa_verify (data, datalen, algo, use_pkcs1, key_string, signature_string); } else if (!strcmp (mode_string, "dsa-pqg-gen")) { int keysize; keysize = keysize_string? atoi (keysize_string) : 0; if (keysize < 1024 || keysize > 3072) die ("invalid keysize specified; needs to be 1024 .. 3072\n"); run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); } else if (!strcmp (mode_string, "dsa-gen")) { int keysize; keysize = keysize_string? atoi (keysize_string) : 0; if (keysize < 1024 || keysize > 3072) die ("invalid keysize specified; needs to be 1024 .. 3072\n"); if (!key_string) die ("option --key is required in this mode\n"); run_dsa_gen (keysize, key_string); } else if (!strcmp (mode_string, "dsa-sign")) { if (!key_string) die ("option --key is required in this mode\n"); if (access (key_string, R_OK)) die ("option --key needs to specify an existing keyfile\n"); if (!data) die ("no data available (do not use --chunk)\n"); run_dsa_sign (data, datalen, key_string); } else if (!strcmp (mode_string, "dsa-verify")) { if (!key_string) die ("option --key is required in this mode\n"); if (access (key_string, R_OK)) die ("option --key needs to specify an existing keyfile\n"); if (!data) die ("no data available (do not use --chunk)\n"); if (!signature_string) die ("option --signature is required in this mode\n"); if (access (signature_string, R_OK)) die ("option --signature needs to specify an existing file\n"); run_dsa_verify (data, datalen, key_string, signature_string); } else usage (0); gcry_free (data); /* Because Libgcrypt does not enforce FIPS mode in all cases we let the process die if Libgcrypt is not anymore in FIPS mode after the actual operation. */ if (!no_fips && !gcry_fips_mode_active ()) die ("FIPS mode is not anymore active\n"); if (verbose) fputs (PGM ": ready\n", stderr); return 0; } diff --git a/tests/hmac.c b/tests/hmac.c index 292a2fa3..5d695ea0 100644 --- a/tests/hmac.c +++ b/tests/hmac.c @@ -1,171 +1,171 @@ /* hmac.c - HMAC regression tests * Copyright (C) 2005 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" static int verbose; static int error_count; static void fail (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); error_count++; } static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void check_one_mac (int algo, const void *key, size_t keylen, const void *data, size_t datalen, const char *expect) { gcry_md_hd_t hd; unsigned char *p; int mdlen; int i; gcry_error_t err = 0; err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC); if (err) { fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err)); return; } mdlen = gcry_md_get_algo_dlen (algo); if (mdlen < 1 || mdlen > 500) { fail ("algo %d, gcry_md_get_algo_dlen failed: %d\n", algo, mdlen); return; } err = gcry_md_setkey (hd, key, keylen); if (err) { fail ("algo %d, gcry_md_setkey failed: %s\n", algo, gpg_strerror (err)); return; } gcry_md_write (hd, data, datalen); p = gcry_md_read (hd, 0); if (memcmp (p, expect, mdlen)) { printf ("computed: "); for (i = 0; i < mdlen; i++) printf ("%02x ", p[i] & 0xFF); printf ("\nexpected: "); for (i = 0; i < mdlen; i++) printf ("%02x ", expect[i] & 0xFF); printf ("\n"); fail ("algo %d, MAC does not match\n", algo); } gcry_md_close (hd); } static void check_hmac (void) { unsigned char key[128]; int i, j; if (verbose) fprintf (stderr, "checking FIPS-198a, A.1\n"); for (i=0; i < 64; i++) key[i] = i; check_one_mac (GCRY_MD_SHA1, key, 64, "Sample #1", 9, "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12" "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a"); if (verbose) fprintf (stderr, "checking FIPS-198a, A.2\n"); for (i=0, j=0x30; i < 20; i++) key[i] = j++; check_one_mac (GCRY_MD_SHA1, key, 20, "Sample #2", 9, "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82" "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24"); if (verbose) fprintf (stderr, "checking FIPS-198a, A.3\n"); for (i=0, j=0x50; i < 100; i++) key[i] = j++; check_one_mac (GCRY_MD_SHA1, key, 100, "Sample #3", 9, "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0" "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa"); if (verbose) fprintf (stderr, "checking FIPS-198a, A.4\n"); for (i=0, j=0x70; i < 49; i++) key[i] = j++; check_one_mac (GCRY_MD_SHA1, key, 49, "Sample #4", 9, "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42" "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26"); } int main (int argc, char **argv) { int debug = 0; if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) verbose = debug = 1; if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); check_hmac (); return error_count ? 1 : 0; } diff --git a/tests/keygen.c b/tests/keygen.c index 05593c39..1d1b43ea 100644 --- a/tests/keygen.c +++ b/tests/keygen.c @@ -1,374 +1,374 @@ /* keygen.c - key generation regression tests * Copyright (C) 2003, 2005, 2012 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" static int verbose; static int debug; static int error_count; static void fail ( const char *format, ... ) { va_list arg_ptr ; va_start( arg_ptr, format ) ; vfprintf (stderr, format, arg_ptr ); va_end(arg_ptr); error_count++; } static void die ( const char *format, ... ) { va_list arg_ptr ; va_start( arg_ptr, format ) ; vfprintf (stderr, format, arg_ptr ); va_end(arg_ptr); exit (1); } static void print_mpi (const char *text, gcry_mpi_t a) { char *buf; void *bufaddr = &buf; gcry_error_t rc; rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); if (rc) fprintf (stderr, "%s=[error printing number: %s]\n", text, gpg_strerror (rc)); else { fprintf (stderr, "%s=0x%s\n", text, buf); gcry_free (buf); } } static void check_generated_rsa_key (gcry_sexp_t key, unsigned long expected_e) { gcry_sexp_t skey, pkey, list; pkey = gcry_sexp_find_token (key, "public-key", 0); if (!pkey) fail ("public part missing in return value\n"); else { gcry_mpi_t e = NULL; list = gcry_sexp_find_token (pkey, "e", 0); if (!list || !(e=gcry_sexp_nth_mpi (list, 1, 0)) ) fail ("public exponent not found\n"); else if (!expected_e) { if (verbose) print_mpi ("e", e); } else if ( gcry_mpi_cmp_ui (e, expected_e)) { print_mpi ("e", e); fail ("public exponent is not %lu\n", expected_e); } gcry_sexp_release (list); gcry_mpi_release (e); gcry_sexp_release (pkey); } skey = gcry_sexp_find_token (key, "private-key", 0); if (!skey) fail ("private part missing in return value\n"); else { int rc = gcry_pk_testkey (skey); if (rc) fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc)); gcry_sexp_release (skey); } } static void check_rsa_keys (void) { gcry_sexp_t keyparm, key; int rc; int i; /* Check that DSA generation works and that it can grok the qbits argument. */ if (verbose) fprintf (stderr, "creating 5 1024 bit DSA keys\n"); for (i=0; i < 5; i++) { rc = gcry_sexp_new (&keyparm, "(genkey\n" " (dsa\n" " (nbits 4:1024)\n" " ))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gpg_strerror (rc)); rc = gcry_pk_genkey (&key, keyparm); gcry_sexp_release (keyparm); if (rc) die ("error generating DSA key: %s\n", gpg_strerror (rc)); gcry_sexp_release (key); if (verbose) fprintf (stderr, " done\n"); } if (verbose) fprintf (stderr, "creating 1536 bit DSA key\n"); rc = gcry_sexp_new (&keyparm, "(genkey\n" " (dsa\n" " (nbits 4:1536)\n" " (qbits 3:224)\n" " ))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gpg_strerror (rc)); rc = gcry_pk_genkey (&key, keyparm); gcry_sexp_release (keyparm); if (rc) die ("error generating DSA key: %s\n", gpg_strerror (rc)); if (debug) { char buffer[20000]; gcry_sexp_sprint (key, GCRYSEXP_FMT_ADVANCED, buffer, sizeof buffer); if (verbose) printf ("=============================\n%s\n" "=============================\n", buffer); } gcry_sexp_release (key); if (verbose) fprintf (stderr, "creating 1024 bit RSA key\n"); rc = gcry_sexp_new (&keyparm, "(genkey\n" " (rsa\n" " (nbits 4:1024)\n" " ))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gpg_strerror (rc)); rc = gcry_pk_genkey (&key, keyparm); gcry_sexp_release (keyparm); if (rc) die ("error generating RSA key: %s\n", gpg_strerror (rc)); check_generated_rsa_key (key, 65537); gcry_sexp_release (key); if (verbose) fprintf (stderr, "creating 512 bit RSA key with e=257\n"); rc = gcry_sexp_new (&keyparm, "(genkey\n" " (rsa\n" " (nbits 3:512)\n" " (rsa-use-e 3:257)\n" " ))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gpg_strerror (rc)); rc = gcry_pk_genkey (&key, keyparm); gcry_sexp_release (keyparm); if (rc) die ("error generating RSA key: %s\n", gpg_strerror (rc)); check_generated_rsa_key (key, 257); gcry_sexp_release (key); if (verbose) fprintf (stderr, "creating 512 bit RSA key with default e\n"); rc = gcry_sexp_new (&keyparm, "(genkey\n" " (rsa\n" " (nbits 3:512)\n" " (rsa-use-e 1:0)\n" " ))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gpg_strerror (rc)); rc = gcry_pk_genkey (&key, keyparm); gcry_sexp_release (keyparm); if (rc) die ("error generating RSA key: %s\n", gpg_strerror (rc)); check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */ gcry_sexp_release (key); } static void check_generated_ecc_key (gcry_sexp_t key) { gcry_sexp_t skey, pkey; pkey = gcry_sexp_find_token (key, "public-key", 0); if (!pkey) fail ("public part missing in return value\n"); else { /* Fixme: Check more stuff. */ gcry_sexp_release (pkey); } skey = gcry_sexp_find_token (key, "private-key", 0); if (!skey) fail ("private part missing in return value\n"); else { int rc = gcry_pk_testkey (skey); if (rc) fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc)); gcry_sexp_release (skey); } /* Finally check that gcry_pk_testkey also works on the entire S-expression. */ { int rc = gcry_pk_testkey (key); if (rc) fail ("gcry_pk_testkey failed on key pair: %s\n", gpg_strerror (rc)); } } static void check_ecc_keys (void) { const char *curves[] = { "NIST P-521", "NIST P-384", "NIST P-256", NULL }; int testno; gcry_sexp_t keyparm, key; int rc; for (testno=0; curves[testno]; testno++) { if (verbose) fprintf (stderr, "creating ECC key using curve %s\n", curves[testno]); rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve %s)))", curves[testno]); if (rc) die ("error creating S-expression: %s\n", gpg_strerror (rc)); rc = gcry_pk_genkey (&key, keyparm); gcry_sexp_release (keyparm); if (rc) die ("error generating ECC key using curve %s: %s\n", curves[testno], gpg_strerror (rc)); check_generated_ecc_key (key); gcry_sexp_release (key); } } static void check_nonce (void) { char a[32], b[32]; int i,j; int oops=0; if (verbose) fprintf (stderr, "checking gcry_create_nonce\n"); gcry_create_nonce (a, sizeof a); for (i=0; i < 10; i++) { gcry_create_nonce (b, sizeof b); if (!memcmp (a, b, sizeof a)) die ("identical nounce found\n"); } for (i=0; i < 10; i++) { gcry_create_nonce (a, sizeof a); if (!memcmp (a, b, sizeof a)) die ("identical nounce found\n"); } again: for (i=1,j=0; i < sizeof a; i++) if (a[0] == a[i]) j++; if (j+1 == sizeof (a)) { if (oops) die ("impossible nonce found\n"); oops++; gcry_create_nonce (a, sizeof a); goto again; } } static void progress_cb (void *cb_data, const char *what, int printchar, int current, int total) { (void)cb_data; (void)what; (void)current; (void)total; if (printchar == '\n') fputs ( "", stdout); else putchar (printchar); fflush (stdout); } int main (int argc, char **argv) { if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) verbose = debug = 1; if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); /* No valuable keys are create, so we can speed up our RNG. */ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); if (verbose) gcry_set_progress_handler ( progress_cb, NULL ); check_rsa_keys (); check_ecc_keys (); check_nonce (); return error_count? 1:0; } diff --git a/tests/keygrip.c b/tests/keygrip.c index a496ca2c..a89bba87 100644 --- a/tests/keygrip.c +++ b/tests/keygrip.c @@ -1,249 +1,249 @@ /* keygrip.c - verifies that keygrips are calculated as expected * Copyright (C) 2005 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" static int verbose; static int repetitions; static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void print_hex (const char *text, const void *buf, size_t n) { const unsigned char *p = buf; fputs (text, stdout); for (; n; n--, p++) printf ("%02X", *p); putchar ('\n'); } static struct { int algo; const char *key; const unsigned char grip[20]; } key_grips[] = { { GCRY_PK_RSA, "(private-key" " (rsa" " (n #00B6B509596A9ECABC939212F891E656A626BA07DA8521A9CAD4C08E640C04052FBB87F424EF1A0275A48A9299AC9DB69ABE3D0124E6C756B1F7DFB9B842D6251AEA6EE85390495CADA73D671537FCE5850A932F32BAB60AB1AC1F852C1F83C625E7A7D70CDA9EF16D5C8E47739D77DF59261ABE8454807FF441E143FBD37F8545#)" " (e #010001#)" " (d #077AD3DE284245F4806A1B82B79E616FBDE821C82D691A65665E57B5FAD3F34E67F401E7BD2E28699E89D9C496CF821945AE83AC7A1231176A196BA6027E77D85789055D50404A7A2A95B1512F91F190BBAEF730ED550D227D512F89C0CDB31AC06FA9A19503DDF6B66D0B42B9691BFD6140EC1720FFC48AE00C34796DC899E5#)" " (p #00D586C78E5F1B4BF2E7CD7A04CA091911706F19788B93E44EE20AAF462E8363E98A72253ED845CCBF2481BB351E8557C85BCFFF0DABDBFF8E26A79A0938096F27#)" " (q #00DB0CDF60F26F2A296C88D6BF9F8E5BE45C0DDD713C96CC73EBCB48B061740943F21D2A93D6E42A7211E7F02A95DCED6C390A67AD21ECF739AE8A0CA46FF2EBB3#)" " (u #33149195F16912DB20A48D020DBC3B9E3881B39D722BF79378F6340F43148A6E9FC5F53E2853B7387BA4443BA53A52FCA8173DE6E85B42F9783D4A7817D0680B#)))", "\x32\xCF\xFA\x85\xB1\x79\x1F\xBB\x26\x14\xE9\x1A\xFD\xF3\xAF\xE3\x32\x08\x2E\x25" }, { GCRY_PK_DSA, " (public-key" " (dsa" " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)))", "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" }, { GCRY_PK_DSA, "(private-key" " (dsa" " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)" " (x #0087F9E91BFBCC1163DE71ED86D557708E32F8ADDE#)))", "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" }, { GCRY_PK_ECDSA, "(public-key" " (ecdsa" " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" " (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)" " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" }, { GCRY_PK_ECDSA, "(public-key" " (ecdsa" " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" " (curve \"NIST P-256\")" " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" }, { GCRY_PK_ECDSA, "(public-key" " (ecdsa" " (curve secp256r1)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" } }; static void check (void) { unsigned char buf[20]; unsigned char *ret; gcry_error_t err; gcry_sexp_t sexp; unsigned int i; int repn; for (i = 0; i < (sizeof (key_grips) / sizeof (*key_grips)); i++) { if (gcry_pk_test_algo (key_grips[i].algo)) { if (verbose) fprintf (stderr, "algo %d not available; test skipped\n", key_grips[i].algo); continue; } err = gcry_sexp_sscan (&sexp, NULL, key_grips[i].key, strlen (key_grips[i].key)); if (err) die ("scanning data %d failed: %s\n", i, gpg_strerror (err)); for (repn=0; repn < repetitions; repn++) { ret = gcry_pk_get_keygrip (sexp, buf); if (!ret) die ("gcry_pk_get_keygrip failed for %d\n", i); if ( memcmp (key_grips[i].grip, buf, sizeof (buf)) ) { print_hex ("keygrip: ", buf, sizeof buf); die ("keygrip for %d does not match\n", i); } } gcry_sexp_release (sexp); } } static void progress_handler (void *cb_data, const char *what, int printchar, int current, int total) { (void)cb_data; (void)what; (void)current; (void)total; putchar (printchar); } int main (int argc, char **argv) { int last_argc = -1; int debug = 0; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--verbose")) { verbose = 1; argc--; argv++; } else if (!strcmp (*argv, "--debug")) { verbose = 1; debug = 1; argc--; argv++; } else if (!strcmp (*argv, "--repetitions")) { argc--; argv++; if (argc) { repetitions = atoi(*argv); argc--; argv++; } } } if (repetitions < 1) repetitions = 1; if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_set_progress_handler (progress_handler, NULL); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); check (); return 0; } diff --git a/tests/mpitests.c b/tests/mpitests.c index 3b75ea79..5643c1be 100644 --- a/tests/mpitests.c +++ b/tests/mpitests.c @@ -1,363 +1,363 @@ /* mpitests.c - basic mpi tests * Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #ifdef _GCRYPT_IN_LIBGCRYPT -# include "../src/gcrypt.h" +# include "../src/gcrypt-int.h" #else # include #endif static int verbose; static int debug; static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } /* Set up some test patterns */ /* 48 bytes with value 1: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ unsigned char ones[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }; /* 48 bytes with value 2: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ unsigned char twos[] = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 }; /* 48 bytes with value 3: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ unsigned char threes[] = { 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; /* 48 bytes with value 0x80: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ unsigned char eighties[] = { 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 }; /* 48 bytes with value 0xff: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ unsigned char manyff[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; static int test_const_and_immutable (void) { gcry_mpi_t one, second_one; one = gcry_mpi_set_ui (NULL, 1); if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE) || gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST)) die ("immutable or const flag initially set\n"); second_one = gcry_mpi_copy (one); if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE)) die ("immutable flag set after copy\n"); if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST)) die ("const flag set after copy\n"); gcry_mpi_release (second_one); gcry_mpi_set_flag (one, GCRYMPI_FLAG_IMMUTABLE); if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)) die ("failed to set immutable flag\n"); if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST)) die ("const flag unexpectly set\n"); second_one = gcry_mpi_copy (one); if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE)) die ("immutable flag not cleared after copy\n"); if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST)) die ("const flag unexpectly set after copy\n"); gcry_mpi_release (second_one); gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE); if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)) die ("failed to clear immutable flag\n"); if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST)) die ("const flag unexpectly set\n"); gcry_mpi_set_flag (one, GCRYMPI_FLAG_CONST); if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST)) die ("failed to set const flag\n"); if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)) die ("failed to set immutable flag with const flag\n"); second_one = gcry_mpi_copy (one); if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE)) die ("immutable flag not cleared after copy\n"); if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST)) die ("const flag not cleared after copy\n"); gcry_mpi_release (second_one); gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE); if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)) die ("clearing immutable flag not ignored for a constant MPI\n"); if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST)) die ("const flag unexpectly cleared\n"); /* Due to the the constant flag the release below should be a NOP and will leak memory. */ gcry_mpi_release (one); return 1; } static int test_add (void) { gcry_mpi_t one; gcry_mpi_t two; gcry_mpi_t ff; gcry_mpi_t result; unsigned char* pc; gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL); result = gcry_mpi_new(0); gcry_mpi_add(result, one, two); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); if (verbose) printf("Result of one plus two:\n%s\n", pc); gcry_free(pc); gcry_mpi_add(result, ff, one); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); if (verbose) printf("Result of ff plus one:\n%s\n", pc); gcry_free(pc); gcry_mpi_release(one); gcry_mpi_release(two); gcry_mpi_release(ff); gcry_mpi_release(result); return 1; } static int test_sub (void) { gcry_mpi_t one; gcry_mpi_t two; gcry_mpi_t result; unsigned char* pc; gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); result = gcry_mpi_new(0); gcry_mpi_sub(result, two, one); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); if (verbose) printf("Result of two minus one:\n%s\n", pc); gcry_free(pc); gcry_mpi_release(one); gcry_mpi_release(two); gcry_mpi_release(result); return 1; } static int test_mul (void) { gcry_mpi_t two; gcry_mpi_t three; gcry_mpi_t result; unsigned char* pc; gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL); result = gcry_mpi_new(0); gcry_mpi_mul(result, two, three); gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); if (verbose) printf("Result of two mul three:\n%s\n", pc); gcry_free(pc); gcry_mpi_release(two); gcry_mpi_release(three); gcry_mpi_release(result); return 1; } /* What we test here is that we don't overwrite our args and that using thne same mpi for several args works. */ static int test_powm (void) { int b_int = 17; int e_int = 3; int m_int = 19; gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int); gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int); gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int); gcry_mpi_t res = gcry_mpi_new (0); gcry_mpi_powm (res, base, exp, mod); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); if (gcry_mpi_cmp_ui (exp, e_int)) die ("test_powm_ui failed for exp at %d\n", __LINE__); if (gcry_mpi_cmp_ui (mod, m_int)) die ("test_powm failed for mod at %d\n", __LINE__); /* Check using base for the result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui (exp, e_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (base, base, exp, mod); if (gcry_mpi_cmp (res, base)) die ("test_powm failed at %d\n", __LINE__); if (gcry_mpi_cmp_ui (exp, e_int)) die ("test_powm_ui failed for exp at %d\n", __LINE__); if (gcry_mpi_cmp_ui (mod, m_int)) die ("test_powm failed for mod at %d\n", __LINE__); /* Check using exp for the result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui (exp, e_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (exp, base, exp, mod); if (gcry_mpi_cmp (res, exp)) die ("test_powm failed at %d\n", __LINE__); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); if (gcry_mpi_cmp_ui (mod, m_int)) die ("test_powm failed for mod at %d\n", __LINE__); /* Check using mod for the result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui (exp, e_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (mod, base, exp, mod); if (gcry_mpi_cmp (res, mod)) die ("test_powm failed at %d\n", __LINE__); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); if (gcry_mpi_cmp_ui (exp, e_int)) die ("test_powm_ui failed for exp at %d\n", __LINE__); /* Now check base ^ base mod mod. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (res, base, base, mod); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); if (gcry_mpi_cmp_ui (mod, m_int)) die ("test_powm failed for mod at %d\n", __LINE__); /* Check base ^ base mod mod with base as result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (base, base, base, mod); if (gcry_mpi_cmp (res, base)) die ("test_powm failed at %d\n", __LINE__); if (gcry_mpi_cmp_ui (mod, m_int)) die ("test_powm failed for mod at %d\n", __LINE__); /* Check base ^ base mod mod with mod as result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_set_ui(mod, m_int); gcry_mpi_powm (mod, base, base, mod); if (gcry_mpi_cmp (res, mod)) die ("test_powm failed at %d\n", __LINE__); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); /* Now check base ^ base mod base. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_powm (res, base, base, base); if (gcry_mpi_cmp_ui (base, b_int)) die ("test_powm failed for base at %d\n", __LINE__); /* Check base ^ base mod base with base as result. */ gcry_mpi_set_ui (base, b_int); gcry_mpi_powm (base, base, base, base); if (gcry_mpi_cmp (res, base)) die ("test_powm failed at %d\n", __LINE__); /* Fixme: We should add the rest of the cases of course. */ return 1; } int main (int argc, char* argv[]) { if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) verbose = debug = 1; if (!gcry_check_version (GCRYPT_VERSION)) { fputs ("version mismatch\n", stderr); exit (1); } gcry_control(GCRYCTL_DISABLE_SECMEM); test_const_and_immutable (); test_add (); test_sub (); test_mul (); test_powm (); return 0; } diff --git a/tests/pkcs1v2.c b/tests/pkcs1v2.c index bb062924..20f1b642 100644 --- a/tests/pkcs1v2.c +++ b/tests/pkcs1v2.c @@ -1,723 +1,723 @@ /* pkcs1v2.c - Test OAEP and PSS padding * Copyright (C) 2011 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #ifdef _GCRYPT_IN_LIBGCRYPT -# include "../src/gcrypt.h" +# include "../src/gcrypt-int.h" #else # include #endif #define my_isascii(c) (!((c) & 0x80)) #define digitp(p) (*(p) >= '0' && *(p) <= '9') #define hexdigitp(a) (digitp (a) \ || (*(a) >= 'A' && *(a) <= 'F') \ || (*(a) >= 'a' && *(a) <= 'f')) #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) static int verbose; static int die_on_error; static int error_count; static void info (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); } static void fail (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); error_count++; if (die_on_error) exit (1); } static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void show_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; if (prefix) fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = gcry_xmalloc (size); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); gcry_free (buf); } /* Convert STRING consisting of hex characters into its binary representation and return it as an allocated buffer. The valid length of the buffer is returned at R_LENGTH. The string is delimited by end of string. The function returns NULL on error. */ static void * data_from_hex (const char *string, size_t *r_length) { const char *s; unsigned char *buffer; size_t length; buffer = gcry_xmalloc (strlen(string)/2+1); length = 0; for (s=string; *s; s +=2 ) { if (!hexdigitp (s) || !hexdigitp (s+1)) die ("error parsing hex string `%s'\n", string); ((unsigned char*)buffer)[length++] = xtoi_2 (s); } *r_length = length; return buffer; } static int extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected, const char *description) { gcry_sexp_t l1; const void *a; size_t alen; void *b; size_t blen; int rc = 0; l1 = gcry_sexp_find_token (sexp, name, 0); a = gcry_sexp_nth_data (l1, 1, &alen); b = data_from_hex (expected, &blen); if (!a) { info ("%s: parameter \"%s\" missing in key\n", description, name); rc = 1; } else if ( alen != blen || memcmp (a, b, alen) ) { info ("%s: parameter \"%s\" does not match expected value\n", description, name); rc = 1; } gcry_free (b); gcry_sexp_release (l1); return rc; } /* Check against the OAEP test vectors from ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip . */ static void check_oaep (void) { #include "pkcs1v2-oaep.h" gpg_error_t err; int tno, mno; for (tno = 0; tno < DIM (tbl); tno++) { void *rsa_n, *rsa_e, *rsa_d; size_t rsa_n_len, rsa_e_len, rsa_d_len; gcry_sexp_t sec_key, pub_key; if (verbose > 1) info ("(%s)\n", tbl[tno].desc); rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len); rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len); rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len); err = gcry_sexp_build (&sec_key, NULL, "(private-key (rsa (n %b)(e %b)(d %b)))", (int)rsa_n_len, rsa_n, (int)rsa_e_len, rsa_e, (int)rsa_d_len, rsa_d); if (err) die ("constructing private key failed: %s\n", gpg_strerror (err)); err = gcry_sexp_build (&pub_key, NULL, "(public-key (rsa (n %b)(e %b)))", (int)rsa_n_len, rsa_n, (int)rsa_e_len, rsa_e); if (err) die ("constructing public key failed: %s\n", gpg_strerror (err)); gcry_free (rsa_n); gcry_free (rsa_e); gcry_free (rsa_d); for (mno = 0; mno < DIM (tbl[0].m); mno++) { void *mesg, *seed, *encr; size_t mesg_len, seed_len, encr_len; gcry_sexp_t plain, ciph; if (verbose) info ("running test: %s\n", tbl[tno].m[mno].desc); mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len); seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); err = gcry_sexp_build (&plain, NULL, "(data (flags oaep)(hash-algo sha1)" "(value %b)(random-override %b))", (int)mesg_len, mesg, (int)seed_len, seed); if (err) die ("constructing plain data failed: %s\n", gpg_strerror (err)); gcry_free (mesg); gcry_free (seed); err = gcry_pk_encrypt (&ciph, plain, pub_key); if (err) { show_sexp ("plain:\n", ciph); fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err)); } else { if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr, tbl[tno].m[mno].desc)) { show_sexp ("encrypt result:\n", ciph); fail ("mismatch in gcry_pk_encrypt\n"); } gcry_sexp_release (ciph); ciph = NULL; } gcry_sexp_release (plain); plain = NULL; /* Now test the decryption. */ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len); err = gcry_sexp_build (&ciph, NULL, "(enc-val (flags oaep)(hash-algo sha1)" "(random-override %b)" "(rsa (a %b)))", (int)seed_len, seed, (int)encr_len, encr); if (err) die ("constructing cipher data failed: %s\n", gpg_strerror (err)); gcry_free (encr); gcry_free (seed); err = gcry_pk_decrypt (&plain, ciph, sec_key); if (err) { show_sexp ("ciph:\n", ciph); fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err)); } else { if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg, tbl[tno].m[mno].desc)) { show_sexp ("decrypt result:\n", plain); fail ("mismatch in gcry_pk_decrypt\n"); } gcry_sexp_release (plain); plain = NULL; } gcry_sexp_release (ciph); ciph = NULL; } gcry_sexp_release (sec_key); gcry_sexp_release (pub_key); } } /* Check against the PSS test vectors from ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2-vec.zip . */ static void check_pss (void) { #include "pkcs1v2-pss.h" gpg_error_t err; int tno, mno; for (tno = 0; tno < DIM (tbl); tno++) { void *rsa_n, *rsa_e, *rsa_d; size_t rsa_n_len, rsa_e_len, rsa_d_len; gcry_sexp_t sec_key, pub_key; if (verbose > 1) info ("(%s)\n", tbl[tno].desc); rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len); rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len); rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len); err = gcry_sexp_build (&sec_key, NULL, "(private-key (rsa (n %b)(e %b)(d %b)))", (int)rsa_n_len, rsa_n, (int)rsa_e_len, rsa_e, (int)rsa_d_len, rsa_d); if (err) die ("constructing private key failed: %s\n", gpg_strerror (err)); err = gcry_sexp_build (&pub_key, NULL, "(public-key (rsa (n %b)(e %b)))", (int)rsa_n_len, rsa_n, (int)rsa_e_len, rsa_e); if (err) die ("constructing public key failed: %s\n", gpg_strerror (err)); gcry_free (rsa_n); gcry_free (rsa_e); gcry_free (rsa_d); for (mno = 0; mno < DIM (tbl[0].m); mno++) { void *mesg, *salt, *sign; size_t mesg_len, salt_len, sign_len; gcry_sexp_t sigtmpl, sig; char mhash[20]; if (verbose) info ("running test: %s\n", tbl[tno].m[mno].desc); mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len); salt = data_from_hex (tbl[tno].m[mno].salt, &salt_len); gcry_md_hash_buffer (GCRY_MD_SHA1, mhash, mesg, mesg_len); err = gcry_sexp_build (&sigtmpl, NULL, "(data (flags pss)" "(hash sha1 %b)" "(random-override %b))", 20, mhash, (int)salt_len, salt); if (err) die ("constructing sig template failed: %s\n", gpg_strerror (err)); gcry_free (mesg); gcry_free (salt); err = gcry_pk_sign (&sig, sigtmpl, sec_key); if (err) { show_sexp ("sigtmpl:\n", sigtmpl); fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err)); } else { if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign, tbl[tno].m[mno].desc)) { show_sexp ("sign result:\n", sig); fail ("mismatch in gcry_pk_sign\n"); } gcry_sexp_release (sig); sig = NULL; } gcry_sexp_release (sigtmpl); sigtmpl = NULL; /* Now test the verification. */ salt = data_from_hex (tbl[tno].m[mno].salt, &salt_len); sign = data_from_hex (tbl[tno].m[mno].sign, &sign_len); err = gcry_sexp_build (&sig, NULL, "(sig-val(rsa(s %b)))", (int)sign_len, sign); if (err) die ("constructing verify data failed: %s\n", gpg_strerror (err)); err = gcry_sexp_build (&sigtmpl, NULL, "(data (flags pss)" "(hash sha1 %b)" "(random-override %b))", 20, mhash, (int)salt_len, salt); if (err) die ("constructing verify tmpl failed: %s\n", gpg_strerror (err)); gcry_free (sign); gcry_free (salt); err = gcry_pk_verify (sig, sigtmpl, pub_key); if (err) { show_sexp ("sig:\n", sig); show_sexp ("sigtmpl:\n", sigtmpl); fail ("gcry_pk_verify failed: %s\n", gpg_strerror (err)); } gcry_sexp_release (sig); sig = NULL; gcry_sexp_release (sigtmpl); sigtmpl = NULL; } gcry_sexp_release (sec_key); gcry_sexp_release (pub_key); } } /* Check against PKCS#1 v1.5 encryption test vectors as found at ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt . */ static void check_v15crypt (void) { #include "pkcs1v2-v15c.h" gpg_error_t err; int tno, mno; for (tno = 0; tno < DIM (tbl); tno++) { void *rsa_n, *rsa_e, *rsa_d; size_t rsa_n_len, rsa_e_len, rsa_d_len; gcry_sexp_t sec_key, pub_key; if (verbose > 1) info ("(%s)\n", tbl[tno].desc); rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len); rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len); rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len); err = gcry_sexp_build (&sec_key, NULL, "(private-key (rsa (n %b)(e %b)(d %b)))", (int)rsa_n_len, rsa_n, (int)rsa_e_len, rsa_e, (int)rsa_d_len, rsa_d); if (err) die ("constructing private key failed: %s\n", gpg_strerror (err)); err = gcry_sexp_build (&pub_key, NULL, "(public-key (rsa (n %b)(e %b)))", (int)rsa_n_len, rsa_n, (int)rsa_e_len, rsa_e); if (err) die ("constructing public key failed: %s\n", gpg_strerror (err)); gcry_free (rsa_n); gcry_free (rsa_e); gcry_free (rsa_d); for (mno = 0; mno < DIM (tbl[0].m); mno++) { void *mesg, *seed, *encr; size_t mesg_len, seed_len, encr_len; gcry_sexp_t plain, ciph; if (verbose) info ("running test: %s\n", tbl[tno].m[mno].desc); mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len); seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); err = gcry_sexp_build (&plain, NULL, "(data (flags pkcs1)(hash-algo sha1)" "(value %b)(random-override %b))", (int)mesg_len, mesg, (int)seed_len, seed); if (err) die ("constructing plain data failed: %s\n", gpg_strerror (err)); gcry_free (mesg); gcry_free (seed); err = gcry_pk_encrypt (&ciph, plain, pub_key); if (err) { show_sexp ("plain:\n", ciph); fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err)); } else { if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr, tbl[tno].m[mno].desc)) { show_sexp ("encrypt result:\n", ciph); fail ("mismatch in gcry_pk_encrypt\n"); } gcry_sexp_release (ciph); ciph = NULL; } gcry_sexp_release (plain); plain = NULL; /* Now test the decryption. */ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len); err = gcry_sexp_build (&ciph, NULL, "(enc-val (flags pkcs1)(hash-algo sha1)" "(random-override %b)" "(rsa (a %b)))", (int)seed_len, seed, (int)encr_len, encr); if (err) die ("constructing cipher data failed: %s\n", gpg_strerror (err)); gcry_free (encr); gcry_free (seed); err = gcry_pk_decrypt (&plain, ciph, sec_key); if (err) { show_sexp ("ciph:\n", ciph); fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err)); } else { if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg, tbl[tno].m[mno].desc)) { show_sexp ("decrypt result:\n", plain); fail ("mismatch in gcry_pk_decrypt\n"); } gcry_sexp_release (plain); plain = NULL; } gcry_sexp_release (ciph); ciph = NULL; } gcry_sexp_release (sec_key); gcry_sexp_release (pub_key); } } /* Check against PKCS#1 v1.5 signature test vectors as found at ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15sign-vectors.txt . */ static void check_v15sign (void) { #include "pkcs1v2-v15s.h" gpg_error_t err; int tno, mno; for (tno = 0; tno < DIM (tbl); tno++) { void *rsa_n, *rsa_e, *rsa_d; size_t rsa_n_len, rsa_e_len, rsa_d_len; gcry_sexp_t sec_key, pub_key; if (verbose > 1) info ("(%s)\n", tbl[tno].desc); rsa_n = data_from_hex (tbl[tno].n, &rsa_n_len); rsa_e = data_from_hex (tbl[tno].e, &rsa_e_len); rsa_d = data_from_hex (tbl[tno].d, &rsa_d_len); err = gcry_sexp_build (&sec_key, NULL, "(private-key (rsa (n %b)(e %b)(d %b)))", (int)rsa_n_len, rsa_n, (int)rsa_e_len, rsa_e, (int)rsa_d_len, rsa_d); if (err) die ("constructing private key failed: %s\n", gpg_strerror (err)); err = gcry_sexp_build (&pub_key, NULL, "(public-key (rsa (n %b)(e %b)))", (int)rsa_n_len, rsa_n, (int)rsa_e_len, rsa_e); if (err) die ("constructing public key failed: %s\n", gpg_strerror (err)); gcry_free (rsa_n); gcry_free (rsa_e); gcry_free (rsa_d); for (mno = 0; mno < DIM (tbl[0].m); mno++) { void *mesg, *sign; size_t mesg_len, sign_len; gcry_sexp_t sigtmpl, sig; char mhash[20]; if (verbose) info ("running test: %s\n", tbl[tno].m[mno].desc); mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len); gcry_md_hash_buffer (GCRY_MD_SHA1, mhash, mesg, mesg_len); err = gcry_sexp_build (&sigtmpl, NULL, "(data (flags pkcs1)" "(hash sha1 %b))", 20, mhash); if (err) die ("constructing sig template failed: %s\n", gpg_strerror (err)); gcry_free (mesg); err = gcry_pk_sign (&sig, sigtmpl, sec_key); if (err) { show_sexp ("sigtmpl:\n", sigtmpl); fail ("gcry_pk_sign failed: %s\n", gpg_strerror (err)); } else { if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign, tbl[tno].m[mno].desc)) { show_sexp ("sign result:\n", sig); fail ("mismatch in gcry_pk_sign\n"); } gcry_sexp_release (sig); sig = NULL; } gcry_sexp_release (sigtmpl); sigtmpl = NULL; /* Now test the verification. */ sign = data_from_hex (tbl[tno].m[mno].sign, &sign_len); err = gcry_sexp_build (&sig, NULL, "(sig-val(rsa(s %b)))", (int)sign_len, sign); if (err) die ("constructing verify data failed: %s\n", gpg_strerror (err)); err = gcry_sexp_build (&sigtmpl, NULL, "(data (flags pkcs1)" "(hash sha1 %b))", 20, mhash); if (err) die ("constructing verify tmpl failed: %s\n", gpg_strerror (err)); gcry_free (sign); err = gcry_pk_verify (sig, sigtmpl, pub_key); if (err) { show_sexp ("sig:\n", sig); show_sexp ("sigtmpl:\n", sigtmpl); fail ("gcry_pk_verify failed: %s\n", gpg_strerror (err)); } gcry_sexp_release (sig); sig = NULL; gcry_sexp_release (sigtmpl); sigtmpl = NULL; } gcry_sexp_release (sec_key); gcry_sexp_release (pub_key); } } int main (int argc, char **argv) { int last_argc = -1; int debug = 0; int run_oaep = 0; int run_pss = 0; int run_v15c = 0; int run_v15s = 0; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--verbose")) { verbose++; argc--; argv++; } else if (!strcmp (*argv, "--debug")) { verbose = 2; debug = 1; argc--; argv++; } else if (!strcmp (*argv, "--die")) { die_on_error = 1; argc--; argv++; } else if (!strcmp (*argv, "--oaep")) { run_oaep = 1; argc--; argv++; } else if (!strcmp (*argv, "--pss")) { run_pss = 1; argc--; argv++; } else if (!strcmp (*argv, "--v15c")) { run_v15c = 1; argc--; argv++; } else if (!strcmp (*argv, "--v15s")) { run_v15s = 1; argc--; argv++; } } if (!run_oaep && !run_pss && !run_v15c && !run_v15s) run_oaep = run_pss = run_v15c = run_v15s = 1; gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (!gcry_check_version ("1.5.0")) die ("version mismatch\n"); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); /* No valuable keys are create, so we can speed up our RNG. */ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); if (run_oaep) check_oaep (); if (run_pss) check_pss (); if (run_v15c) check_v15crypt (); if (run_v15s) check_v15sign (); if (verbose) fprintf (stderr, "\nAll tests completed. Errors: %i\n", error_count); return error_count ? 1 : 0; } diff --git a/tests/prime.c b/tests/prime.c index 5d928bdb..6e825aeb 100644 --- a/tests/prime.c +++ b/tests/prime.c @@ -1,253 +1,253 @@ /* prime.c - part of the Libgcrypt test suite. Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" static int verbose; static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void check_primes (void) { gcry_error_t err = GPG_ERR_NO_ERROR; gcry_mpi_t *factors = NULL; gcry_mpi_t prime = NULL; gcry_mpi_t g; unsigned int i = 0; struct prime_spec { unsigned int prime_bits; unsigned int factor_bits; unsigned int flags; } prime_specs[] = { { 1024, 100, GCRY_PRIME_FLAG_SPECIAL_FACTOR }, { 128, 0, 0 }, { 0 }, }; for (i = 0; prime_specs[i].prime_bits; i++) { err = gcry_prime_generate (&prime, prime_specs[i].prime_bits, prime_specs[i].factor_bits, &factors, NULL, NULL, GCRY_WEAK_RANDOM, prime_specs[i].flags); assert (! err); if (verbose) { fprintf (stderr, "test %d: p = ", i); gcry_mpi_dump (prime); putc ('\n', stderr); } err = gcry_prime_check (prime, 0); assert (! err); err = gcry_prime_group_generator (&g, prime, factors, NULL); assert (!err); gcry_prime_release_factors (factors); factors = NULL; if (verbose) { fprintf (stderr, " %d: g = ", i); gcry_mpi_dump (g); putc ('\n', stderr); } gcry_mpi_release (g); gcry_mpi_add_ui (prime, prime, 1); err = gcry_prime_check (prime, 0); assert (err); } } /* Print an MPI S-expression. */ static void print_mpi (const char *name, gcry_mpi_t a) { gcry_error_t err; unsigned char *buf; int writerr = 0; err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a); if (err) die ("gcry_mpi_aprint failed: %s\n", gcry_strerror (err)); printf (" (%s #%s#)\n", name, buf); if (ferror (stdout)) writerr++; if (!writerr && fflush (stdout) == EOF) writerr++; if (writerr) die ("writing output failed\n"); gcry_free (buf); } /* Create the key for our public standard dummy CA. */ static void create_42prime (void) { gcry_error_t err; char string[128*2+1]; int i; gcry_mpi_t start = NULL; gcry_mpi_t p, q, n, t1, t2, phi, f, g, e, d, u; /* Our start value is a string of 0x42 values, with the exception that the two high order bits are set. This is to resemble the way Lingcrypt generates RSA primes. */ for (i=0; i < 128;) { string[i++] = '4'; string[i++] = '2'; } string[i] = 0; string[0] = 'C'; err = gcry_mpi_scan (&start, GCRYMPI_FMT_HEX, string, 0, NULL); if (err) die ("gcry_mpi_scan failed: %s\n", gcry_strerror (err)); fputs ("start:", stderr); gcry_mpi_dump (start); putc ('\n', stderr); /* Generate two primes with p < q. We take the first primes below and above a start value. */ p = gcry_mpi_copy (start); gcry_mpi_sub_ui (p, p, 1); while (gcry_prime_check (p, 0)) gcry_mpi_sub_ui (p, p, 2); fputs (" p:", stderr); gcry_mpi_dump (p); putc ('\n', stderr); q = gcry_mpi_copy (start); gcry_mpi_add_ui (q, q, 1); while (gcry_prime_check (q, 0)) gcry_mpi_add_ui (q, q, 2); fputs (" q:", stderr); gcry_mpi_dump (q); putc ('\n', stderr); /* Compute the modulus. */ n = gcry_mpi_new (1024); gcry_mpi_mul (n, p, q); fputs (" n:", stderr); gcry_mpi_dump (n); putc ('\n', stderr); if (gcry_mpi_get_nbits (n) != 1024) die ("Oops: the size of N is not 1024 but %u\n", gcry_mpi_get_nbits (n)); /* Calculate Euler totient: phi = (p-1)(q-1) */ t1 = gcry_mpi_new (0); t2 = gcry_mpi_new (0); phi = gcry_mpi_new (0); g = gcry_mpi_new (0); f = gcry_mpi_new (0); gcry_mpi_sub_ui (t1, p, 1); gcry_mpi_sub_ui (t2, q, 1); gcry_mpi_mul (phi, t1, t2); gcry_mpi_gcd (g, t1, t2); gcry_mpi_div (f, NULL, phi, g, -1); /* Check the public exponent. */ e = gcry_mpi_set_ui (NULL, 65537); if (!gcry_mpi_gcd (t1, e, phi)) die ("Oops: E is not a generator\n"); fputs (" e:", stderr); gcry_mpi_dump (e); putc ('\n', stderr); /* Compute the secret key: d = e^-1 mod phi */ d = gcry_mpi_new (0); gcry_mpi_invm (d, e, f ); fputs (" d:", stderr); gcry_mpi_dump (d); putc ('\n', stderr); /* Compute the inverse of p and q. */ u = gcry_mpi_new (0); gcry_mpi_invm (u, p, q); fputs (" u:", stderr); gcry_mpi_dump (u); putc ('\n', stderr); /* Print the S-expression. */ fputs ("(private-key\n (rsa\n", stdout); print_mpi ("n", n); print_mpi ("e", e); print_mpi ("d", d); print_mpi ("p", p); print_mpi ("q", q); print_mpi ("u", u); fputs ("))\n", stdout); gcry_mpi_release (p); gcry_mpi_release (q); gcry_mpi_release (n); gcry_mpi_release (t1); gcry_mpi_release (t2); gcry_mpi_release (phi); gcry_mpi_release (f); gcry_mpi_release (g); gcry_mpi_release (e); gcry_mpi_release (d); gcry_mpi_release (u); } int main (int argc, char **argv) { int debug = 0; int mode42 = 0; if ((argc > 1) && (! strcmp (argv[1], "--verbose"))) verbose = 1; else if ((argc > 1) && (! strcmp (argv[1], "--debug"))) verbose = debug = 1; else if ((argc > 1) && (! strcmp (argv[1], "--42"))) verbose = debug = mode42 = 1; gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (! gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); if (mode42) create_42prime (); else check_primes (); return 0; } diff --git a/tests/pubkey.c b/tests/pubkey.c index 45341750..ffaecb37 100644 --- a/tests/pubkey.c +++ b/tests/pubkey.c @@ -1,967 +1,967 @@ /* pubkey.c - Public key encryption/decryption tests * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" /* Sample RSA keys, taken from basic.c. */ static const char sample_private_key_1[] = "(private-key\n" " (openpgp-rsa\n" " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" " (e #010001#)\n" " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" " (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n" " (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n" " (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n" " )\n" ")\n"; /* The same key as above but without p, q and u to test the non CRT case. */ static const char sample_private_key_1_1[] = "(private-key\n" " (openpgp-rsa\n" " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" " (e #010001#)\n" " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" " )\n" ")\n"; /* The same key as above but just without q to test the non CRT case. This should fail. */ static const char sample_private_key_1_2[] = "(private-key\n" " (openpgp-rsa\n" " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" " (e #010001#)\n" " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" " (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n" " (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n" " )\n" ")\n"; static const char sample_public_key_1[] = "(public-key\n" " (rsa\n" " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" " (e #010001#)\n" " )\n" ")\n"; static int verbose; static void die (const char *format, ...) { va_list arg_ptr ; va_start( arg_ptr, format ) ; vfprintf (stderr, format, arg_ptr ); va_end(arg_ptr); if (*format && format[strlen(format)-1] != '\n') putc ('\n', stderr); exit (1); } static void show_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; if (prefix) fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = gcry_xmalloc (size); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); gcry_free (buf); } static void check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey, gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code) { gcry_sexp_t plain1, cipher, l; gcry_mpi_t x0, x1; int rc; int have_flags; /* Extract data from plaintext. */ l = gcry_sexp_find_token (plain0, "value", 0); x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG); /* Encrypt data. */ rc = gcry_pk_encrypt (&cipher, plain0, pkey); if (rc) die ("encryption failed: %s\n", gcry_strerror (rc)); l = gcry_sexp_find_token (cipher, "flags", 0); have_flags = !!l; gcry_sexp_release (l); /* Decrypt data. */ rc = gcry_pk_decrypt (&plain1, cipher, skey); gcry_sexp_release (cipher); if (rc) { if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code) return; /* This is the expected failure code. */ die ("decryption failed: %s\n", gcry_strerror (rc)); } /* Extract decrypted data. Note that for compatibility reasons, the output of gcry_pk_decrypt depends on whether a flags lists (even if empty) occurs in its input data. Because we passed the output of encrypt directly to decrypt, such a flag value won't be there as of today. We check it anyway. */ l = gcry_sexp_find_token (plain1, "value", 0); if (l) { if (!have_flags) die ("compatibility mode of pk_decrypt broken\n"); gcry_sexp_release (plain1); x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG); gcry_sexp_release (l); } else { if (have_flags) die ("compatibility mode of pk_decrypt broken\n"); x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG); gcry_sexp_release (plain1); } /* Compare. */ if (gcry_mpi_cmp (x0, x1)) die ("data corrupted\n"); } static void check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data, gpg_err_code_t decrypt_fail_code) { gcry_sexp_t plain; gcry_mpi_t x; int rc; /* Create plain text. */ x = gcry_mpi_new (nbits_data); gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM); rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x); if (rc) die ("converting data for encryption failed: %s\n", gcry_strerror (rc)); check_keys_crypt (pkey, skey, plain, decrypt_fail_code); gcry_sexp_release (plain); gcry_mpi_release (x); /* Create plain text. */ x = gcry_mpi_new (nbits_data); gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM); rc = gcry_sexp_build (&plain, NULL, "(data (flags raw no-blinding) (value %m))", x); if (rc) die ("converting data for encryption failed: %s\n", gcry_strerror (rc)); check_keys_crypt (pkey, skey, plain, decrypt_fail_code); gcry_sexp_release (plain); } static void get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant) { gcry_sexp_t pub_key, sec_key; int rc; static const char *secret; switch (secret_variant) { case 0: secret = sample_private_key_1; break; case 1: secret = sample_private_key_1_1; break; case 2: secret = sample_private_key_1_2; break; default: die ("BUG\n"); } rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1, strlen (sample_public_key_1)); if (!rc) rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret)); if (rc) die ("converting sample keys failed: %s\n", gcry_strerror (rc)); *pkey = pub_key; *skey = sec_key; } static void get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; rc = gcry_sexp_new (&key_spec, "(genkey (rsa (nbits 4:1024)))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (rc) die ("error generating RSA key: %s\n", gcry_strerror (rc)); if (verbose > 1) show_sexp ("generated RSA key:\n", key); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (! pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (! sec_key) die ("private part missing in key\n"); gcry_sexp_release (key); *pkey = pub_key; *skey = sec_key; } static void get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; rc = gcry_sexp_new (&key_spec, "(genkey (rsa (nbits 4:1024)(use-x931)))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (rc) die ("error generating RSA key: %s\n", gcry_strerror (rc)); if (verbose > 1) show_sexp ("generated RSA (X9.31) key:\n", key); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (!pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (!sec_key) die ("private part missing in key\n"); gcry_sexp_release (key); *pkey = pub_key; *skey = sec_key; } static void get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; rc = gcry_sexp_new (&key_spec, (fixed_x ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))" : "(genkey (elg (nbits 3:512)))"), 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (rc) die ("error generating Elgamal key: %s\n", gcry_strerror (rc)); if (verbose > 1) show_sexp ("generated ELG key:\n", key); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (!pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (!sec_key) die ("private part missing in key\n"); gcry_sexp_release (key); *pkey = pub_key; *skey = sec_key; } static void get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; rc = gcry_sexp_new (&key_spec, transient_key ? "(genkey (dsa (nbits 4:1024)(transient-key)))" : "(genkey (dsa (nbits 4:1024)))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (rc) die ("error generating DSA key: %s\n", gcry_strerror (rc)); if (verbose > 1) show_sexp ("generated DSA key:\n", key); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (!pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (!sec_key) die ("private part missing in key\n"); gcry_sexp_release (key); *pkey = pub_key; *skey = sec_key; } static void get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; rc = gcry_sexp_new (&key_spec, "(genkey (dsa (nbits 4:1024)(use-fips186)))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (rc) die ("error generating DSA key: %s\n", gcry_strerror (rc)); if (verbose > 1) show_sexp ("generated DSA key (fips 186):\n", key); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (!pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (!sec_key) die ("private part missing in key\n"); gcry_sexp_release (key); *pkey = pub_key; *skey = sec_key; } static void get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; rc = gcry_sexp_new (&key_spec, "(genkey (dsa (transient-key)(domain" "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" ")))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (rc) die ("error generating DSA key: %s\n", gcry_strerror (rc)); if (verbose > 1) show_sexp ("generated DSA key:\n", key); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (!pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (!sec_key) die ("private part missing in key\n"); gcry_sexp_release (key); *pkey = pub_key; *skey = sec_key; } static void get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; rc = gcry_sexp_new (&key_spec, "(genkey (dsa (transient-key)(use-fips186)(domain" "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" ")))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (rc) die ("error generating DSA key: %s\n", gcry_strerror (rc)); if (verbose > 1) show_sexp ("generated DSA key:\n", key); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (!pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (!sec_key) die ("private part missing in key\n"); gcry_sexp_release (key); *pkey = pub_key; *skey = sec_key; } static void get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) { gcry_sexp_t key_spec, key, pub_key, sec_key; int rc; rc = gcry_sexp_new (&key_spec, "(genkey" " (dsa" " (nbits 4:1024)" " (use-fips186)" " (transient-key)" " (derive-parms" " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gcry_strerror (rc)); rc = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (rc) die ("error generating DSA key: %s\n", gcry_strerror (rc)); if (verbose > 1) show_sexp ("generated DSA key (fips 186 with seed):\n", key); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (!pub_key) die ("public part missing in key\n"); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (!sec_key) die ("private part missing in key\n"); gcry_sexp_release (key); *pkey = pub_key; *skey = sec_key; } static void check_run (void) { gpg_error_t err; gcry_sexp_t pkey, skey; int variant; for (variant=0; variant < 3; variant++) { if (verbose) fprintf (stderr, "Checking sample key (%d).\n", variant); get_keys_sample (&pkey, &skey, variant); /* Check gcry_pk_testkey which requires all elements. */ err = gcry_pk_testkey (skey); if ((variant == 0 && err) || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ)) die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err)); /* Run the usual check but expect an error from variant 2. */ check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0); gcry_sexp_release (pkey); gcry_sexp_release (skey); } if (verbose) fprintf (stderr, "Checking generated RSA key.\n"); get_keys_new (&pkey, &skey); check_keys (pkey, skey, 800, 0); gcry_sexp_release (pkey); gcry_sexp_release (skey); if (verbose) fprintf (stderr, "Checking generated RSA key (X9.31).\n"); get_keys_x931_new (&pkey, &skey); check_keys (pkey, skey, 800, 0); gcry_sexp_release (pkey); gcry_sexp_release (skey); if (verbose) fprintf (stderr, "Checking generated Elgamal key.\n"); get_elg_key_new (&pkey, &skey, 0); check_keys (pkey, skey, 400, 0); gcry_sexp_release (pkey); gcry_sexp_release (skey); if (verbose) fprintf (stderr, "Checking passphrase generated Elgamal key.\n"); get_elg_key_new (&pkey, &skey, 1); check_keys (pkey, skey, 800, 0); gcry_sexp_release (pkey); gcry_sexp_release (skey); if (verbose) fprintf (stderr, "Generating DSA key.\n"); get_dsa_key_new (&pkey, &skey, 0); /* Fixme: Add a check function for DSA keys. */ gcry_sexp_release (pkey); gcry_sexp_release (skey); if (!gcry_fips_mode_active ()) { if (verbose) fprintf (stderr, "Generating transient DSA key.\n"); get_dsa_key_new (&pkey, &skey, 1); /* Fixme: Add a check function for DSA keys. */ gcry_sexp_release (pkey); gcry_sexp_release (skey); } if (verbose) fprintf (stderr, "Generating DSA key (FIPS 186).\n"); get_dsa_key_fips186_new (&pkey, &skey); /* Fixme: Add a check function for DSA keys. */ gcry_sexp_release (pkey); gcry_sexp_release (skey); if (verbose) fprintf (stderr, "Generating DSA key with given domain.\n"); get_dsa_key_with_domain_new (&pkey, &skey); /* Fixme: Add a check function for DSA keys. */ gcry_sexp_release (pkey); gcry_sexp_release (skey); if (verbose) fprintf (stderr, "Generating DSA key with given domain (FIPS 186).\n"); get_dsa_key_fips186_with_domain_new (&pkey, &skey); /* Fixme: Add a check function for DSA keys. */ gcry_sexp_release (pkey); gcry_sexp_release (skey); if (verbose) fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n"); get_dsa_key_fips186_with_seed_new (&pkey, &skey); /* Fixme: Add a check function for DSA keys. */ gcry_sexp_release (pkey); gcry_sexp_release (skey); } static gcry_mpi_t key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name) { gcry_sexp_t l1, l2; gcry_mpi_t result; l1 = gcry_sexp_find_token (sexp, topname, 0); if (!l1) return NULL; l2 = gcry_sexp_find_token (l1, name, 0); if (!l2) { gcry_sexp_release (l1); return NULL; } result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); gcry_sexp_release (l2); gcry_sexp_release (l1); return result; } static void check_x931_derived_key (int what) { static struct { const char *param; const char *expected_d; } testtable[] = { { /* First example from X9.31 (D.1.1). */ "(genkey\n" " (rsa\n" " (nbits 4:1024)\n" " (rsa-use-e 1:3)\n" " (derive-parms\n" " (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n" " (Xp2 #192E8AAC41C576C822D93EA433#)\n" " (Xp #D8CD81F035EC57EFE822955149D3BFF70C53520D\n" " 769D6D76646C7A792E16EBD89FE6FC5B605A6493\n" " 39DFC925A86A4C6D150B71B9EEA02D68885F5009\n" " B98BD984#)\n" " (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n" " (Xq2 #134E4CAA16D2350A21D775C404#)\n" " (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n" " 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n" " 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n" " 321DE34A#))))\n", "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173" "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961" "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE" "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13" "241D3C4B" }, { /* Second example from X9.31 (D.2.1). */ "(genkey\n" " (rsa\n" " (nbits 4:1536)\n" " (rsa-use-e 1:3)\n" " (derive-parms\n" " (Xp1 #18272558B61316348297EACA74#)\n" " (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n" " (Xp #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n" " 0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n" " 60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n" " 318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n" " EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n" " (Xq1 #11FDDA6E8128DC1629F75192BA#)\n" " (Xq2 #18AB178ECA907D72472F65E480#)\n" " (Xq #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n" " CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n" " B734E3FBD15862EBC59FA0425DFA131E549136E8\n" " E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n" " EA14B9D5F2A263DC65626E4D6CEAC767#))))\n", "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1" "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2" "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383" "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9" "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C" "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0" "BBCCB9F65C83" /* Note that this example in X9.31 gives this value for D: "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44" "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8" "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E" "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7" "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270" "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342" "EF32E7D9720B" This is a bug in X9.31, obviously introduced by using d = e^{-1} mod (p-1)(q-1) instead of using the universal exponent as required by 4.1.3: d = e^{-1} mod lcm(p-1,q-1) The examples in X9.31 seem to be pretty buggy, see cipher/primegen.c for another bug. Not only that I had to spend 100 USD for the 66 pages of the document, it also took me several hours to figure out that the bugs are in the document and not in my code. */ }, { /* First example from NIST RSAVS (B.1.1). */ "(genkey\n" " (rsa\n" " (nbits 4:1024)\n" " (rsa-use-e 1:3)\n" " (derive-parms\n" " (Xp1 #1ed3d6368e101dab9124c92ac8#)\n" " (Xp2 #16e5457b8844967ce83cab8c11#)\n" " (Xp #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n" " ab262da1dcda8194720672a4e02229a0c71f60ae\n" " c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n" " cab44595#)\n" " (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n" " (Xq2 #1f9cca85f185341516d92e82fd#)\n" " (Xq #c8387fd38fa33ddcea6a9de1b2d55410663502db\n" " c225655a9310cceac9f4cf1bce653ec916d45788\n" " f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n" " 2f389eda#))))\n", "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b" "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd" "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a" "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0" "dc7e8feb" }, { /* Second example from NIST RSAVS (B.1.1). */ "(genkey\n" " (rsa\n" " (nbits 4:1536)\n" " (rsa-use-e 1:3)\n" " (derive-parms\n" " (Xp1 #1e64c1af460dff8842c22b64d0#)\n" " (Xp2 #1e948edcedba84039c81f2ac0c#)\n" " (Xp #c8c67df894c882045ede26a9008ab09ea0672077\n" " d7bc71d412511cd93981ddde8f91b967da404056\n" " c39f105f7f239abdaff92923859920f6299e82b9\n" " 5bd5b8c959948f4a034d81613d6235a3953b49ce\n" " 26974eb7bb1f14843841281b363b9cdb#)\n" " (Xq1 #1f3df0f017ddd05611a97b6adb#)\n" " (Xq2 #143edd7b22d828913abf24ca4d#)\n" " (Xq #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n" " b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n" " 7552195fae8b061077e03920814d8b9cfb5a3958\n" " b3a82c2a7fc97e55db543948d3396289245336ec\n" " 9e3cb308cc655aebd766340da8921383#))))\n", "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184" "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536" "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461" "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a" "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2" "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4" "2ccf8a84835b" } }; gpg_error_t err; gcry_sexp_t key_spec, key, pub_key, sec_key; gcry_mpi_t d_expected, d_have; if (what < 0 && what >= sizeof testtable) die ("invalid WHAT value\n"); err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1); if (err) die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err)); err = gcry_pk_genkey (&key, key_spec); gcry_sexp_release (key_spec); if (err) die ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err)); pub_key = gcry_sexp_find_token (key, "public-key", 0); if (!pub_key) die ("public part missing in key [%d]\n", what); sec_key = gcry_sexp_find_token (key, "private-key", 0); if (!sec_key) die ("private part missing in key [%d]\n", what); err = gcry_mpi_scan (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL); if (err) die ("error converting string [%d]\n", what); if (verbose > 1) show_sexp ("generated key:\n", key); d_have = key_param_from_sexp (sec_key, "rsa", "d"); if (!d_have) die ("parameter d not found in RSA secret key [%d]\n", what); if (gcry_mpi_cmp (d_expected, d_have)) { show_sexp (NULL, sec_key); die ("parameter d does match expected value [%d]\n", what); } gcry_mpi_release (d_expected); gcry_mpi_release (d_have); gcry_sexp_release (key); gcry_sexp_release (pub_key); gcry_sexp_release (sec_key); } static void check_ecc_sample_key (void) { static const char ecc_private_key[] = "(private-key\n" " (ecdsa\n" " (curve \"NIST P-256\")\n" " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781" "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n" " (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)" "))"; static const char ecc_private_key_wo_q[] = "(private-key\n" " (ecdsa\n" " (curve \"NIST P-256\")\n" " (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)" "))"; static const char ecc_public_key[] = "(public-key\n" " (ecdsa\n" " (curve \"NIST P-256\")\n" " (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781" "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)" "))"; static const char hash_string[] = "(data (flags raw)\n" " (value #00112233445566778899AABBCCDDEEFF" /* */ "000102030405060708090A0B0C0D0E0F#))"; gpg_error_t err; gcry_sexp_t key, hash, sig; if (verbose) fprintf (stderr, "Checking sample ECC key.\n"); if ((err = gcry_sexp_new (&hash, hash_string, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_sign (&sig, hash, key))) die ("gcry_pk_sign failed: %s", gpg_strerror (err)); gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_verify (sig, hash, key))) die ("gcry_pk_verify failed: %s", gpg_strerror (err)); /* Now try signing without the Q parameter. */ gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); gcry_sexp_release (sig); if ((err = gcry_pk_sign (&sig, hash, key))) die ("gcry_pk_sign without Q failed: %s", gpg_strerror (err)); gcry_sexp_release (key); if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1))) die ("line %d: %s", __LINE__, gpg_strerror (err)); if ((err = gcry_pk_verify (sig, hash, key))) die ("gcry_pk_verify signed without Q failed: %s", gpg_strerror (err)); gcry_sexp_release (sig); gcry_sexp_release (key); gcry_sexp_release (hash); } int main (int argc, char **argv) { int debug = 0; int i; if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) { verbose = 2; debug = 1; } gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); /* No valuable keys are create, so we can speed up our RNG. */ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); for (i=0; i < 2; i++) check_run (); for (i=0; i < 4; i++) check_x931_derived_key (i); check_ecc_sample_key (); return 0; } diff --git a/tests/random.c b/tests/random.c index a46d754d..ccaa3f92 100644 --- a/tests/random.c +++ b/tests/random.c @@ -1,539 +1,539 @@ /* random.c - part of the Libgcrypt test suite. Copyright (C) 2005 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #ifndef HAVE_W32_SYSTEM # include # include # include #endif -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" #define PGM "random" static int verbose; static int debug; static int with_progress; static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); fputs ( PGM ": ", stderr); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void inf (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); fputs ( PGM ": ", stderr); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); } static void print_hex (const char *text, const void *buf, size_t n) { const unsigned char *p = buf; inf ("%s", text); for (; n; n--, p++) fprintf (stderr, "%02X", *p); putc ('\n', stderr); } static void progress_cb (void *cb_data, const char *what, int printchar, int current, int total) { (void)cb_data; inf ("progress (%s %c %d %d)\n", what, printchar, current, total); fflush (stderr); } static int writen (int fd, const void *buf, size_t nbytes) { size_t nleft = nbytes; int nwritten; while (nleft > 0) { nwritten = write (fd, buf, nleft); if (nwritten < 0) { if (errno == EINTR) nwritten = 0; else return -1; } nleft -= nwritten; buf = (const char*)buf + nwritten; } return 0; } static int readn (int fd, void *buf, size_t buflen, size_t *ret_nread) { size_t nleft = buflen; int nread; while ( nleft > 0 ) { nread = read ( fd, buf, nleft ); if (nread < 0) { if (nread == EINTR) nread = 0; else return -1; } else if (!nread) break; /* EOF */ nleft -= nread; buf = (char*)buf + nread; } if (ret_nread) *ret_nread = buflen - nleft; return 0; } /* Check that forking won't return the same random. */ static void check_forking (void) { #ifdef HAVE_W32_SYSTEM if (verbose) inf ("check_forking skipped: not applicable on Windows\n"); #else /*!HAVE_W32_SYSTEM*/ pid_t pid; int rp[2]; int i, status; size_t nread; char tmp1[16], tmp1c[16], tmp1p[16]; if (verbose) inf ("checking that a fork won't cause the same random output\n"); /* We better make sure that the RNG has been initialzied. */ gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); if (verbose) print_hex ("initial random: ", tmp1, sizeof tmp1); if (pipe (rp) == -1) die ("pipe failed: %s\n", strerror (errno)); pid = fork (); if (pid == (pid_t)(-1)) die ("fork failed: %s\n", strerror (errno)); if (!pid) { gcry_randomize (tmp1c, sizeof tmp1c, GCRY_STRONG_RANDOM); if (writen (rp[1], tmp1c, sizeof tmp1c)) die ("write failed: %s\n", strerror (errno)); if (verbose) { print_hex (" child random: ", tmp1c, sizeof tmp1c); fflush (stdout); } _exit (0); } gcry_randomize (tmp1p, sizeof tmp1p, GCRY_STRONG_RANDOM); if (verbose) print_hex (" parent random: ", tmp1p, sizeof tmp1p); close (rp[1]); if (readn (rp[0], tmp1c, sizeof tmp1c, &nread)) die ("read failed: %s\n", strerror (errno)); if (nread != sizeof tmp1c) die ("read too short\n"); while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR) ; if (i != (pid_t)(-1) && WIFEXITED (status) && !WEXITSTATUS (status)) ; else die ("child failed\n"); if (!memcmp (tmp1p, tmp1c, sizeof tmp1c)) die ("parent and child got the same random number\n"); #endif /*!HAVE_W32_SYSTEM*/ } /* Check that forking won't return the same nonce. */ static void check_nonce_forking (void) { #ifdef HAVE_W32_SYSTEM if (verbose) inf ("check_nonce_forking skipped: not applicable on Windows\n"); #else /*!HAVE_W32_SYSTEM*/ pid_t pid; int rp[2]; int i, status; size_t nread; char nonce1[10], nonce1c[10], nonce1p[10]; if (verbose) inf ("checking that a fork won't cause the same nonce output\n"); /* We won't get the same nonce back if we never initialized the nonce subsystem, thus we get one nonce here and forget about it. */ gcry_create_nonce (nonce1, sizeof nonce1); if (verbose) print_hex ("initial nonce: ", nonce1, sizeof nonce1); if (pipe (rp) == -1) die ("pipe failed: %s\n", strerror (errno)); pid = fork (); if (pid == (pid_t)(-1)) die ("fork failed: %s\n", strerror (errno)); if (!pid) { gcry_create_nonce (nonce1c, sizeof nonce1c); if (writen (rp[1], nonce1c, sizeof nonce1c)) die ("write failed: %s\n", strerror (errno)); if (verbose) { print_hex (" child nonce: ", nonce1c, sizeof nonce1c); fflush (stdout); } _exit (0); } gcry_create_nonce (nonce1p, sizeof nonce1p); if (verbose) print_hex (" parent nonce: ", nonce1p, sizeof nonce1p); close (rp[1]); if (readn (rp[0], nonce1c, sizeof nonce1c, &nread)) die ("read failed: %s\n", strerror (errno)); if (nread != sizeof nonce1c) die ("read too short\n"); while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR) ; if (i != (pid_t)(-1) && WIFEXITED (status) && !WEXITSTATUS (status)) ; else die ("child failed\n"); if (!memcmp (nonce1p, nonce1c, sizeof nonce1c)) die ("parent and child got the same nonce\n"); #endif /*!HAVE_W32_SYSTEM*/ } static int rng_type (void) { int rngtype; if (gcry_control (GCRYCTL_GET_CURRENT_RNG_TYPE, &rngtype)) die ("retrieving RNG type failed\n"); return rngtype; } static void check_rng_type_switching (void) { int rngtype, initial; char tmp1[4]; if (verbose) inf ("checking whether RNG type switching works\n"); rngtype = rng_type (); if (debug) inf ("rng type: %d\n", rngtype); initial = rngtype; gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); if (debug) print_hex (" sample: ", tmp1, sizeof tmp1); if (rngtype != rng_type ()) die ("RNG type unexpectedly changed\n"); gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM); rngtype = rng_type (); if (debug) inf ("rng type: %d\n", rngtype); if (rngtype != initial) die ("switching to System RNG unexpectedly succeeded\n"); gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); if (debug) print_hex (" sample: ", tmp1, sizeof tmp1); if (rngtype != rng_type ()) die ("RNG type unexpectedly changed\n"); gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS); rngtype = rng_type (); if (debug) inf ("rng type: %d\n", rngtype); if (rngtype != initial) die ("switching to FIPS RNG unexpectedly succeeded\n"); gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); if (debug) print_hex (" sample: ", tmp1, sizeof tmp1); if (rngtype != rng_type ()) die ("RNG type unexpectedly changed\n"); gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD); rngtype = rng_type (); if (debug) inf ("rng type: %d\n", rngtype); if (rngtype != GCRY_RNG_TYPE_STANDARD) die ("switching to standard RNG failed\n"); gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); if (debug) print_hex (" sample: ", tmp1, sizeof tmp1); if (rngtype != rng_type ()) die ("RNG type unexpectedly changed\n"); } static void check_early_rng_type_switching (void) { int rngtype, initial; if (verbose) inf ("checking whether RNG type switching works in the early stage\n"); rngtype = rng_type (); if (debug) inf ("rng type: %d\n", rngtype); initial = rngtype; gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM); rngtype = rng_type (); if (debug) inf ("rng type: %d\n", rngtype); if (initial >= GCRY_RNG_TYPE_SYSTEM && rngtype != GCRY_RNG_TYPE_SYSTEM) die ("switching to System RNG failed\n"); gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS); rngtype = rng_type (); if (debug) inf ("rng type: %d\n", rngtype); if (initial >= GCRY_RNG_TYPE_FIPS && rngtype != GCRY_RNG_TYPE_FIPS) die ("switching to FIPS RNG failed\n"); gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD); rngtype = rng_type (); if (debug) inf ("rng type: %d\n", rngtype); if (rngtype != GCRY_RNG_TYPE_STANDARD) die ("switching to standard RNG failed\n"); } /* Because we want to check initialization behaviour, we need to fork/exec this program with several command line arguments. We use system, so that these tests work also on Windows. */ static void run_all_rng_tests (const char *program) { static const char *options[] = { "--early-rng-check", "--early-rng-check --prefer-standard-rng", "--early-rng-check --prefer-fips-rng", "--early-rng-check --prefer-system-rng", "--prefer-standard-rng", "--prefer-fips-rng", "--prefer-system-rng", NULL }; int idx; size_t len, maxlen; char *cmdline; maxlen = 0; for (idx=0; options[idx]; idx++) { len = strlen (options[idx]); if (len > maxlen) maxlen = len; } maxlen += strlen (program); maxlen += strlen (" --in-recursion --verbose --debug --progress"); maxlen++; cmdline = malloc (maxlen + 1); if (!cmdline) die ("out of core\n"); for (idx=0; options[idx]; idx++) { if (verbose) inf ("now running with options '%s'\n", options[idx]); strcpy (cmdline, program); strcat (cmdline, " --in-recursion"); if (verbose) strcat (cmdline, " --verbose"); if (debug) strcat (cmdline, " --debug"); if (with_progress) strcat (cmdline, " --progress"); strcat (cmdline, " "); strcat (cmdline, options[idx]); if (system (cmdline)) die ("running '%s' failed\n", cmdline); } free (cmdline); } int main (int argc, char **argv) { int last_argc = -1; int early_rng = 0; int in_recursion = 0; const char *program = NULL; if (argc) { program = *argv; argc--; argv++; } else die ("argv[0] missing\n"); while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--help")) { fputs ("usage: random [options]\n", stdout); exit (0); } else if (!strcmp (*argv, "--verbose")) { verbose = 1; argc--; argv++; } else if (!strcmp (*argv, "--debug")) { debug = verbose = 1; argc--; argv++; } else if (!strcmp (*argv, "--progress")) { argc--; argv++; with_progress = 1; } else if (!strcmp (*argv, "--in-recursion")) { in_recursion = 1; argc--; argv++; } else if (!strcmp (*argv, "--early-rng-check")) { early_rng = 1; argc--; argv++; } else if (!strcmp (*argv, "--prefer-standard-rng")) { /* This is anyway the default, but we may want to use it for debugging. */ gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD); argc--; argv++; } else if (!strcmp (*argv, "--prefer-fips-rng")) { gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS); argc--; argv++; } else if (!strcmp (*argv, "--prefer-system-rng")) { gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM); argc--; argv++; } } #ifndef HAVE_W32_SYSTEM signal (SIGPIPE, SIG_IGN); #endif if (early_rng) check_early_rng_type_switching (); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); if (with_progress) gcry_set_progress_handler (progress_cb, NULL); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); if (!in_recursion) { check_forking (); check_nonce_forking (); } check_rng_type_switching (); if (!in_recursion) run_all_rng_tests (program); return 0; } diff --git a/tests/rsacvt.c b/tests/rsacvt.c index 014cd2a3..6fb5c76f 100644 --- a/tests/rsacvt.c +++ b/tests/rsacvt.c @@ -1,426 +1,426 @@ /* rsacvt.c - A debug tool to convert RSA formats. Copyright (C) 2009 Free Software Foundation, Inc. This file is part of Libgcrypt. Libgcrypt is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Libgcrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ /* Input data format: ======= # A hash denotes a comment line e861b700e17e8afe68[...]f1 f7a7ca5367c661f8e6[...]61 10001 # After an empty line another input block may follow. 7861b700e17e8afe68[...]f3 e7a7ca5367c661f8e6[...]71 3 ========= */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #ifdef HAVE_W32_SYSTEM # include /* We need setmode(). */ #else # include #endif #include #include #ifdef _GCRYPT_IN_LIBGCRYPT -# include "../src/gcrypt.h" +# include "../src/gcrypt-int.h" #else # include # define PACKAGE_BUGREPORT "devnull@example.org" # define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]" #endif #define PGM "rsacvt" #define my_isascii(c) (!((c) & 0x80)) #define digitp(p) (*(p) >= '0' && *(p) <= '9') #define hexdigitp(a) (digitp (a) \ || (*(a) >= 'A' && *(a) <= 'F') \ || (*(a) >= 'a' && *(a) <= 'f')) #define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) #define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) /* Verbose mode flag. */ static int verbose; /* Prefix output with labels. */ static int with_labels; /* Do not suppress leading zeroes. */ static int keep_lz; /* Create parameters as specified by OpenPGP (rfc4880). That is we don't store dmp1 and dmp1 but d and make sure that p is less than q. */ static int openpgp_mode; /* Print a error message and exit the process with an error code. */ static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); fputs (PGM ": ", stderr); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static char * read_textline (FILE *fp) { char line[4096]; char *p; int any = 0; /* Read line but skip over initial empty lines. */ do { do { if (!fgets (line, sizeof line, fp)) { if (feof (fp)) return NULL; die ("error reading input line: %s\n", strerror (errno)); } p = strchr (line, '\n'); if (p) *p = 0; p = line + (*line? (strlen (line)-1):0); for ( ;p > line; p--) if (my_isascii (*p) && isspace (*p)) *p = 0; } while (!any && !*line); any = 1; } while (*line == '#'); /* Always skip comment lines. */ if (verbose > 1) fprintf (stderr, PGM ": received line: %s\n", line); return gcry_xstrdup (line); } static gcry_mpi_t read_hexmpi_line (FILE *fp, int *got_eof) { gpg_error_t err; gcry_mpi_t a; char *line; *got_eof = 0; line = read_textline (fp); if (!line) { *got_eof = 1; return NULL; } err = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL); gcry_free (line); if (err) a = NULL; return a; } static int skip_to_empty_line (FILE *fp) { char line[256]; char *p; do { if (!fgets (line, sizeof line, fp)) { if (feof (fp)) return -1; die ("error reading input line: %s\n", strerror (errno)); } p = strchr (line, '\n'); if (p) *p =0; } while (*line); return 0; } /* Print an MPI on a line. */ static void print_mpi_line (const char *label, gcry_mpi_t a) { unsigned char *buf, *p; gcry_error_t err; int writerr = 0; if (with_labels && label) printf ("%s = ", label); err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a); if (err) die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); p = buf; if (!keep_lz && p[0] == '0' && p[1] == '0' && p[2]) p += 2; printf ("%s\n", p); if (ferror (stdout)) writerr++; if (!writerr && fflush (stdout) == EOF) writerr++; if (writerr) die ("writing output failed: %s\n", strerror (errno)); gcry_free (buf); } /* Compute and print missing RSA parameters. */ static void compute_missing (gcry_mpi_t rsa_p, gcry_mpi_t rsa_q, gcry_mpi_t rsa_e) { gcry_mpi_t rsa_n, rsa_d, rsa_pm1, rsa_qm1, rsa_u; gcry_mpi_t phi, tmp_g, tmp_f; rsa_n = gcry_mpi_new (0); rsa_d = gcry_mpi_new (0); rsa_pm1 = gcry_mpi_new (0); rsa_qm1 = gcry_mpi_new (0); rsa_u = gcry_mpi_new (0); phi = gcry_mpi_new (0); tmp_f = gcry_mpi_new (0); tmp_g = gcry_mpi_new (0); /* Check that p < q; if not swap p and q. */ if (openpgp_mode && gcry_mpi_cmp (rsa_p, rsa_q) > 0) { fprintf (stderr, PGM ": swapping p and q\n"); gcry_mpi_swap (rsa_p, rsa_q); } gcry_mpi_mul (rsa_n, rsa_p, rsa_q); /* Compute the Euler totient: phi = (p-1)(q-1) */ gcry_mpi_sub_ui (rsa_pm1, rsa_p, 1); gcry_mpi_sub_ui (rsa_qm1, rsa_q, 1); gcry_mpi_mul (phi, rsa_pm1, rsa_qm1); if (!gcry_mpi_gcd (tmp_g, rsa_e, phi)) die ("parameter 'e' does match 'p' and 'q'\n"); /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */ gcry_mpi_gcd (tmp_g, rsa_pm1, rsa_qm1); gcry_mpi_div (tmp_f, NULL, phi, tmp_g, -1); /* Compute the secret key: d = e^{-1} mod lcm(p-1,q-1) */ gcry_mpi_invm (rsa_d, rsa_e, tmp_f); /* Compute the CRT helpers: d mod (p-1), d mod (q-1) */ gcry_mpi_mod (rsa_pm1, rsa_d, rsa_pm1); gcry_mpi_mod (rsa_qm1, rsa_d, rsa_qm1); /* Compute the CRT value: OpenPGP: u = p^{-1} mod q Standard: iqmp = q^{-1} mod p */ if (openpgp_mode) gcry_mpi_invm (rsa_u, rsa_p, rsa_q); else gcry_mpi_invm (rsa_u, rsa_q, rsa_p); gcry_mpi_release (phi); gcry_mpi_release (tmp_f); gcry_mpi_release (tmp_g); /* Print everything. */ print_mpi_line ("n", rsa_n); print_mpi_line ("e", rsa_e); if (openpgp_mode) print_mpi_line ("d", rsa_d); print_mpi_line ("p", rsa_p); print_mpi_line ("q", rsa_q); if (openpgp_mode) print_mpi_line ("u", rsa_u); else { print_mpi_line ("dmp1", rsa_pm1); print_mpi_line ("dmq1", rsa_qm1); print_mpi_line ("iqmp", rsa_u); } gcry_mpi_release (rsa_n); gcry_mpi_release (rsa_d); gcry_mpi_release (rsa_pm1); gcry_mpi_release (rsa_qm1); gcry_mpi_release (rsa_u); } static void usage (int show_help) { if (!show_help) { fputs ("usage: " PGM " [OPTION] [FILE] (try --help for more information)\n", stderr); exit (2); } fputs ("Usage: " PGM " [OPTIONS] [FILE]\n" "Take RSA parameters p, n, e and compute missing parameters.\n" "OPTIONS:\n" " --openpgp Compute as specified by RFC4880\n" " --labels Prefix output with labels\n" " --keep-lz Keep all leading zeroes in the output\n" " --verbose Print additional information\n" " --version Print version information\n" " --help Print this text\n" "With no FILE, or if FILE is -, read standard input.\n" "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout); exit (0); } int main (int argc, char **argv) { int last_argc = -1; FILE *input; gcry_mpi_t rsa_p, rsa_q, rsa_e; int got_eof; int any = 0; if (argc) { argc--; argv++; } while (argc && last_argc != argc ) { last_argc = argc; if (!strcmp (*argv, "--")) { argc--; argv++; break; } else if (!strcmp (*argv, "--help")) { usage (1); } else if (!strcmp (*argv, "--version")) { fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout); printf ("libgcrypt %s\n", gcry_check_version (NULL)); exit (0); } else if (!strcmp (*argv, "--verbose")) { verbose++; argc--; argv++; } else if (!strcmp (*argv, "--labels")) { with_labels = 1; argc--; argv++; } else if (!strcmp (*argv, "--keep-lz")) { keep_lz = 1; argc--; argv++; } else if (!strcmp (*argv, "--openpgp")) { openpgp_mode = 1; argc--; argv++; } } if (argc > 1) usage (0); #if !defined (HAVE_W32_SYSTEM) && !defined (_WIN32) signal (SIGPIPE, SIG_IGN); #endif if (argc == 1 && strcmp (argv[0], "-")) { input = fopen (argv[0], "r"); if (!input) die ("can't open `%s': %s\n", argv[0], strerror (errno)); } else input = stdin; gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); if (!gcry_check_version ("1.4.0")) die ("Libgcrypt is not sufficient enough\n"); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); do { rsa_p = read_hexmpi_line (input, &got_eof); if (!rsa_p && got_eof) break; if (!rsa_p) die ("RSA parameter 'p' missing or not properly hex encoded\n"); rsa_q = read_hexmpi_line (input, &got_eof); if (!rsa_q) die ("RSA parameter 'q' missing or not properly hex encoded\n"); rsa_e = read_hexmpi_line (input, &got_eof); if (!rsa_e) die ("RSA parameter 'e' missing or not properly hex encoded\n"); got_eof = skip_to_empty_line (input); if (any) putchar ('\n'); compute_missing (rsa_p, rsa_q, rsa_e); gcry_mpi_release (rsa_p); gcry_mpi_release (rsa_q); gcry_mpi_release (rsa_e); any = 1; } while (!got_eof); return 0; } diff --git a/tests/t-kdf.c b/tests/t-kdf.c index 50deba08..adbe6cc0 100644 --- a/tests/t-kdf.c +++ b/tests/t-kdf.c @@ -1,1079 +1,1079 @@ /* t-kdf.c - KDF regression tests * Copyright (C) 2011 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" #ifndef DIM # define DIM(v) (sizeof(v)/sizeof((v)[0])) #endif /* Program option flags. */ static int verbose; static int debug; static int error_count; static void fail (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); error_count++; } static void die (const char *format, ...) { va_list arg_ptr; va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void check_openpgp (void) { /* Test vectors manually created with gpg 1.4 derived code: In passphrase.c:hash_passpharse, add this code to the end of the function: ===8<=== printf ("{\n" " \""); for (i=0; i < pwlen; i++) { if (i && !(i%16)) printf ("\"\n \""); printf ("\\x%02x", ((const unsigned char *)pw)[i]); } printf ("\", %d,\n", pwlen); printf (" %s, %s,\n", s2k->mode == 0? "GCRY_KDF_SIMPLE_S2K": s2k->mode == 1? "GCRY_KDF_SALTED_S2K": s2k->mode == 3? "GCRY_KDF_ITERSALTED_S2K":"?", s2k->hash_algo == DIGEST_ALGO_MD5 ? "GCRY_MD_MD5" : s2k->hash_algo == DIGEST_ALGO_SHA1 ? "GCRY_MD_SHA1" : s2k->hash_algo == DIGEST_ALGO_RMD160? "GCRY_MD_RMD160" : s2k->hash_algo == DIGEST_ALGO_SHA256? "GCRY_MD_SHA256" : s2k->hash_algo == DIGEST_ALGO_SHA384? "GCRY_MD_SHA384" : s2k->hash_algo == DIGEST_ALGO_SHA512? "GCRY_MD_SHA512" : s2k->hash_algo == DIGEST_ALGO_SHA224? "GCRY_MD_SHA224" : "?"); if (s2k->mode == 0) printf (" NULL, 0,\n"); else { printf (" \""); for (i=0; i < 8; i++) printf ("\\x%02x", (unsigned int)s2k->salt[i]); printf ("\", %d,\n", 8); } if (s2k->mode == 3) printf (" %lu,\n", (unsigned long)S2K_DECODE_COUNT(s2k->count)); else printf (" 0,\n"); printf (" %d,\n", (int)dek->keylen); printf (" \""); for (i=0; i < dek->keylen; i++) { if (i && !(i%16)) printf ("\"\n \""); printf ("\\x%02x", ((unsigned char *)dek->key)[i]); } printf ("\"\n},\n"); ===>8=== Then prepare a file x.inp with utf8 encoding: ===8<=== 0 aes md5 1024 a 0 aes md5 1024 ab 0 aes md5 1024 abc 0 aes md5 1024 abcd 0 aes md5 1024 abcde 0 aes md5 1024 abcdef 0 aes md5 1024 abcdefg 0 aes md5 1024 abcdefgh 0 aes md5 1024 abcdefghi 0 aes md5 1024 abcdefghijklmno 0 aes md5 1024 abcdefghijklmnop 0 aes md5 1024 abcdefghijklmnopq 0 aes md5 1024 Long_sentence_used_as_passphrase 0 aes md5 1024 With_utf8_umlauts:äüÖß 0 aes sha1 1024 a 0 aes sha1 1024 ab 0 aes sha1 1024 abc 0 aes sha1 1024 abcd 0 aes sha1 1024 abcde 0 aes sha1 1024 abcdef 0 aes sha1 1024 abcdefg 0 aes sha1 1024 abcdefgh 0 aes sha1 1024 abcdefghi 0 aes sha1 1024 abcdefghijklmno 0 aes sha1 1024 abcdefghijklmnop 0 aes sha1 1024 abcdefghijklmnopq 0 aes sha1 1024 abcdefghijklmnopqr 0 aes sha1 1024 abcdefghijklmnopqrs 0 aes sha1 1024 abcdefghijklmnopqrst 0 aes sha1 1024 abcdefghijklmnopqrstu 0 aes sha1 1024 Long_sentence_used_as_passphrase 0 aes256 sha1 1024 Long_sentence_used_as_passphrase 0 aes sha1 1024 With_utf8_umlauts:äüÖß 3 aes sha1 1024 a 3 aes sha1 1024 ab 3 aes sha1 1024 abc 3 aes sha1 1024 abcd 3 aes sha1 1024 abcde 3 aes sha1 1024 abcdef 3 aes sha1 1024 abcdefg 3 aes sha1 1024 abcdefgh 3 aes sha1 1024 abcdefghi 3 aes sha1 1024 abcdefghijklmno 3 aes sha1 1024 abcdefghijklmnop 3 aes sha1 1024 abcdefghijklmnopq 3 aes sha1 1024 abcdefghijklmnopqr 3 aes sha1 1024 abcdefghijklmnopqrs 3 aes sha1 1024 abcdefghijklmnopqrst 3 aes sha1 1024 abcdefghijklmnopqrstu 3 aes sha1 1024 With_utf8_umlauts:äüÖß 3 aes sha1 1024 Long_sentence_used_as_passphrase 3 aes sha1 10240 Long_sentence_used_as_passphrase 3 aes sha1 102400 Long_sentence_used_as_passphrase 3 aes192 sha1 1024 a 3 aes192 sha1 1024 abcdefg 3 aes192 sha1 1024 abcdefghi 3 aes192 sha1 1024 abcdefghi 3 aes192 sha1 1024 Long_sentence_used_as_passphrase 3 aes256 sha1 1024 a 3 aes256 sha1 1024 abcdefg 3 aes256 sha1 1024 abcdefghi 3 aes256 sha1 1024 abcdefghi 3 aes256 sha1 1024 Long_sentence_used_as_passphrase 0 aes sha256 1024 Long_sentence_used_as_passphrase 1 aes sha256 1024 Long_sentence_used_as_passphrase 3 aes sha256 1024 Long_sentence_used_as_passphrase 3 aes sha256 10240 Long_sentence_used_as_passphrase 3 aes sha384 1024 Long_sentence_used_as_passphrase 3 aes sha512 1024 Long_sentence_used_as_passphrase 3 aes256 sha512 1024 Long_sentence_used_as_passphrase 3 3des sha512 1024 Long_sentence_used_as_passphrase ===>8=== and finally using a proper utf-8 enabled shell, run: cat x.inp | while read mode cipher digest count pass dummy; do \ ./gpg x.out */ static struct { const char *p; /* Passphrase. */ size_t plen; /* Length of P. */ int algo; int hashalgo; const char *salt; size_t saltlen; unsigned long c; /* Iterations. */ int dklen; /* Requested key length. */ const char *dk; /* Derived key. */ int disabled; } tv[] = { { "\x61", 1, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\x0c\xc1\x75\xb9\xc0\xf1\xb6\xa8\x31\xc3\x99\xe2\x69\x77\x26\x61" }, { "\x61\x62", 2, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\x18\x7e\xf4\x43\x61\x22\xd1\xcc\x2f\x40\xdc\x2b\x92\xf0\xeb\xa0" }, { "\x61\x62\x63", 3, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\x90\x01\x50\x98\x3c\xd2\x4f\xb0\xd6\x96\x3f\x7d\x28\xe1\x7f\x72" }, { "\x61\x62\x63\x64", 4, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\xe2\xfc\x71\x4c\x47\x27\xee\x93\x95\xf3\x24\xcd\x2e\x7f\x33\x1f" }, { "\x61\x62\x63\x64\x65", 5, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\xab\x56\xb4\xd9\x2b\x40\x71\x3a\xcc\x5a\xf8\x99\x85\xd4\xb7\x86" }, { "\x61\x62\x63\x64\x65\x66", 6, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\xe8\x0b\x50\x17\x09\x89\x50\xfc\x58\xaa\xd8\x3c\x8c\x14\x97\x8e" }, { "\x61\x62\x63\x64\x65\x66\x67", 7, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\x7a\xc6\x6c\x0f\x14\x8d\xe9\x51\x9b\x8b\xd2\x64\x31\x2c\x4d\x64" }, { "\x61\x62\x63\x64\x65\x66\x67\x68", 8, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\xe8\xdc\x40\x81\xb1\x34\x34\xb4\x51\x89\xa7\x20\xb7\x7b\x68\x18" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\x8a\xa9\x9b\x1f\x43\x9f\xf7\x12\x93\xe9\x53\x57\xba\xc6\xfd\x94" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\x8a\x73\x19\xdb\xf6\x54\x4a\x74\x22\xc9\xe2\x54\x52\x58\x0e\xa5" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\x1d\x64\xdc\xe2\x39\xc4\x43\x7b\x77\x36\x04\x1d\xb0\x89\xe1\xb9" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71", 17, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\x9a\x8d\x98\x45\xa6\xb4\xd8\x2d\xfc\xb2\xc2\xe3\x51\x62\xc8\x30" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\x35\x2a\xf0\xfc\xdf\xe9\xbb\x62\x16\xfc\x99\x9d\x8d\x58\x05\xcb" }, { "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74" "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26, GCRY_KDF_SIMPLE_S2K, GCRY_MD_MD5, NULL, 0, 0, 16, "\x21\xa4\xeb\xd8\xfd\xf0\x59\x25\xd1\x32\x31\xdb\xe7\xf2\x13\x5d" }, { "\x61", 1, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x86\xf7\xe4\x37\xfa\xa5\xa7\xfc\xe1\x5d\x1d\xdc\xb9\xea\xea\xea" }, { "\x61\x62", 2, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\xda\x23\x61\x4e\x02\x46\x9a\x0d\x7c\x7b\xd1\xbd\xab\x5c\x9c\x47" }, { "\x61\x62\x63", 3, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\xa9\x99\x3e\x36\x47\x06\x81\x6a\xba\x3e\x25\x71\x78\x50\xc2\x6c" }, { "\x61\x62\x63\x64", 4, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x81\xfe\x8b\xfe\x87\x57\x6c\x3e\xcb\x22\x42\x6f\x8e\x57\x84\x73" }, { "\x61\x62\x63\x64\x65", 5, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x03\xde\x6c\x57\x0b\xfe\x24\xbf\xc3\x28\xcc\xd7\xca\x46\xb7\x6e" }, { "\x61\x62\x63\x64\x65\x66", 6, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x1f\x8a\xc1\x0f\x23\xc5\xb5\xbc\x11\x67\xbd\xa8\x4b\x83\x3e\x5c" }, { "\x61\x62\x63\x64\x65\x66\x67", 7, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x2f\xb5\xe1\x34\x19\xfc\x89\x24\x68\x65\xe7\xa3\x24\xf4\x76\xec" }, { "\x61\x62\x63\x64\x65\x66\x67\x68", 8, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x42\x5a\xf1\x2a\x07\x43\x50\x2b\x32\x2e\x93\xa0\x15\xbc\xf8\x68" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\xc6\x3b\x19\xf1\xe4\xc8\xb5\xf7\x6b\x25\xc4\x9b\x8b\x87\xf5\x7d" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x29\x38\xdc\xc2\xe3\xaa\x77\x98\x7c\x7e\x5d\x4a\x0f\x26\x96\x67" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x14\xf3\x99\x52\x88\xac\xd1\x89\xe6\xe5\x0a\x7a\xf4\x7e\xe7\x09" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71", 17, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\xd8\x3d\x62\x1f\xcd\x2d\x4d\x29\x85\x54\x70\x43\xa7\xa5\xfd\x4d" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71\x72", 18, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\xe3\x81\xfe\x42\xc5\x7e\x48\xa0\x82\x17\x86\x41\xef\xfd\x1c\xb9" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71\x72\x73", 19, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x89\x3e\x69\xff\x01\x09\xf3\x45\x9c\x42\x43\x01\x3b\x3d\xe8\xb1" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71\x72\x73\x74", 20, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x14\xa2\x3a\xd7\x0f\x2a\x5d\xd7\x25\x57\x5d\xe6\xc4\x3e\x1c\xdd" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71\x72\x73\x74\x75", 21, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\xec\xa9\x86\xb9\x5d\x58\x7f\x34\xd7\x1c\xa7\x75\x2a\x4e\x00\x10" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\x3e\x1b\x9a\x50\x7d\x6e\x9a\xd8\x93\x64\x96\x7a\x3f\xcb\x27\x3f" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 32, "\x3e\x1b\x9a\x50\x7d\x6e\x9a\xd8\x93\x64\x96\x7a\x3f\xcb\x27\x3f" "\xc3\x7b\x3a\xb2\xef\x4d\x68\xaa\x9c\xd7\xe4\x88\xee\xd1\x5e\x70" }, { "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74" "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA1, NULL, 0, 0, 16, "\xe0\x4e\x1e\xe3\xad\x0b\x49\x7c\x7a\x5f\x37\x3b\x4d\x90\x3c\x2e" }, { "\x61", 1, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x6d\x47\xe3\x68\x5d\x2c\x36\x16", 8, 1024, 16, "\x41\x9f\x48\x6e\xbf\xe6\xdd\x05\x9a\x72\x23\x17\x44\xd8\xd3\xf3" }, { "\x61\x62", 2, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x7c\x34\x78\xfb\x28\x2d\x25\xc7", 8, 1024, 16, "\x0a\x9d\x09\x06\x43\x3d\x4f\xf9\x87\xd6\xf7\x48\x90\xde\xd1\x1c" }, { "\x61\x62\x63", 3, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xc3\x16\x37\x2e\x27\xf6\x9f\x6f", 8, 1024, 16, "\xf8\x27\xa0\x07\xc6\xcb\xdd\xf1\xfe\x5c\x88\x3a\xfc\xcd\x84\x4d" }, { "\x61\x62\x63\x64", 4, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xf0\x0c\x73\x38\xb7\xc3\xd5\x14", 8, 1024, 16, "\x9b\x5f\x26\xba\x52\x3b\xcd\xd9\xa5\x2a\xef\x3c\x03\x4d\xd1\x52" }, { "\x61\x62\x63\x64\x65", 5, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xe1\x7d\xa2\x36\x09\x59\xee\xc5", 8, 1024, 16, "\x94\x9d\x5b\x1a\x5a\x66\x8c\xfa\x8f\x6f\x22\xaf\x8b\x60\x9f\xaf" }, { "\x61\x62\x63\x64\x65\x66", 6, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xaf\xa7\x0c\x68\xdf\x7e\xaa\x27", 8, 1024, 16, "\xe5\x38\xf4\x39\x62\x27\xcd\xcc\x91\x37\x7f\x1b\xdc\x58\x64\x27" }, { "\x61\x62\x63\x64\x65\x66\x67", 7, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x40\x57\xb2\x9d\x5f\xbb\x11\x4f", 8, 1024, 16, "\xad\xa2\x33\xd9\xdd\xe0\xfb\x94\x8e\xcc\xec\xcc\xb3\xa8\x3a\x9e" }, { "\x61\x62\x63\x64\x65\x66\x67\x68", 8, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x38\xf5\x65\xc5\x0f\x8c\x19\x61", 8, 1024, 16, "\xa0\xb0\x3e\x29\x76\xe6\x8f\xa0\xd8\x34\x8f\xa4\x2d\xfd\x65\xee" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xc3\xb7\x99\xcc\xda\x2d\x05\x7b", 8, 1024, 16, "\x27\x21\xc8\x99\x5f\xcf\x20\xeb\xf2\xd9\xff\x6a\x69\xff\xad\xe8" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f", 15, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x7d\xd8\x68\x8a\x1c\xc5\x47\x22", 8, 1024, 16, "\x0f\x96\x7a\x12\x23\x54\xf6\x92\x61\x67\x07\xb4\x68\x17\xb8\xaa" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70", 16, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x8a\x95\xd4\x88\x0b\xb8\xe9\x9d", 8, 1024, 16, "\xcc\xe4\xc8\x82\x53\x32\xf1\x93\x5a\x00\xd4\x7f\xd4\x46\xfa\x07" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71", 17, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xb5\x22\x48\xa6\xc4\xad\x74\x67", 8, 1024, 16, "\x0c\xe3\xe0\xee\x3d\x8f\x35\xd2\x35\x14\x14\x29\x0c\xf1\xe3\x34" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71\x72", 18, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xac\x9f\x04\x63\x83\x0e\x3c\x95", 8, 1024, 16, "\x49\x0a\x04\x68\xa8\x2a\x43\x6f\xb9\x73\x94\xb4\x85\x9a\xaa\x0e" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71\x72\x73", 19, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x03\x6f\x60\x30\x3a\x19\x61\x0d", 8, 1024, 16, "\x15\xe5\x9b\xbf\x1c\xf0\xbe\x74\x95\x1a\xb2\xc4\xda\x09\xcd\x99" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71\x72\x73\x74", 20, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x51\x40\xa5\x57\xf5\x28\xfd\x03", 8, 1024, 16, "\xa6\xf2\x7e\x6b\x30\x4d\x8d\x67\xd4\xa2\x7f\xa2\x57\x27\xab\x96" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70" "\x71\x72\x73\x74\x75", 21, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x4c\xf1\x10\x11\x04\x70\xd3\x6e", 8, 1024, 16, "\x2c\x50\x79\x8d\x83\x23\xac\xd6\x22\x29\x37\xaf\x15\x0d\xdd\x8f" }, { "\x57\x69\x74\x68\x5f\x75\x74\x66\x38\x5f\x75\x6d\x6c\x61\x75\x74" "\x73\x3a\xc3\xa4\xc3\xbc\xc3\x96\xc3\x9f", 26, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xfe\x3a\x25\xcb\x78\xef\xe1\x21", 8, 1024, 16, "\x2a\xb0\x53\x08\xf3\x2f\xd4\x6e\xeb\x01\x49\x5d\x87\xf6\x27\xf6" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x04\x97\xd0\x02\x6a\x44\x2d\xde", 8, 1024, 16, "\x57\xf5\x70\x41\xa0\x9b\x8c\x09\xca\x74\xa9\x22\xa5\x82\x2d\x17" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xdd\xf3\x31\x7c\xce\xf4\x81\x26", 8, 10240, 16, "\xc3\xdd\x01\x6d\xaf\xf6\x58\xc8\xd7\x79\xb4\x40\x00\xb5\xe8\x0b" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x95\xd6\x72\x4e\xfb\xe1\xc3\x1a", 8, 102400, 16, "\xf2\x3f\x36\x7f\xb4\x6a\xd0\x3a\x31\x9e\x65\x11\x8e\x2b\x99\x9b" }, { "\x61", 1, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x6d\x69\x15\x18\xe4\x13\x42\x82", 8, 1024, 24, "\x28\x0c\x7e\xf2\x31\xf6\x1c\x6b\x5c\xef\x6a\xd5\x22\x64\x97\x91" "\xe3\x5e\x37\xfd\x50\xe2\xfc\x6c" }, { "\x61\x62\x63\x64\x65\x66\x67", 7, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x9b\x76\x5e\x81\xde\x13\xdf\x15", 8, 1024, 24, "\x91\x1b\xa1\xc1\x7b\x4f\xc3\xb1\x80\x61\x26\x08\xbe\x53\xe6\x50" "\x40\x6f\x28\xed\xc6\xe6\x67\x55" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x7a\xac\xcc\x6e\x15\x56\xbd\xa1", 8, 1024, 24, "\xfa\x7e\x20\x07\xb6\x47\xb0\x09\x46\xb8\x38\xfb\xa1\xaf\xf7\x75" "\x2a\xfa\x77\x14\x06\x54\xcb\x34" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x1c\x68\xf8\xfb\x98\xf7\x8c\x39", 8, 1024, 24, "\xcb\x1e\x86\xf5\xe0\xe4\xfb\xbf\x71\x34\x99\x24\xf4\x39\x8c\xc2" "\x8e\x25\x1c\x4c\x96\x47\x22\xe8" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x10\xa9\x4e\xc1\xa5\xec\x17\x52", 8, 1024, 24, "\x0f\x83\xa2\x77\x92\xbb\xe4\x58\x68\xc5\xf2\x14\x6e\x6e\x2e\x6b" "\x98\x17\x70\x92\x07\x44\xe0\x51" }, { "\x61", 1, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xef\x8f\x37\x61\x8f\xab\xae\x4f", 8, 1024, 32, "\x6d\x65\xae\x86\x23\x91\x39\x98\xec\x1c\x23\x44\xb6\x0d\xad\x32" "\x54\x46\xc7\x23\x26\xbb\xdf\x4b\x54\x6e\xd4\xc2\xfa\xc6\x17\x17" }, { "\x61\x62\x63\x64\x65\x66\x67", 7, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xaa\xfb\xd9\x06\x7d\x7c\x40\xaf", 8, 1024, 32, "\x7d\x10\x54\x13\x3c\x43\x7a\xb3\x54\x1f\x38\xd4\x8f\x70\x0a\x09" "\xe2\xfa\xab\x97\x9a\x70\x16\xef\x66\x68\xca\x34\x2e\xce\xfa\x1f" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x58\x03\x4f\x56\x8b\x97\xd4\x98", 8, 1024, 32, "\xf7\x40\xb1\x25\x86\x0d\x35\x8f\x9f\x91\x2d\xce\x04\xee\x5a\x04" "\x9d\xbd\x44\x23\x4c\xa6\xbb\xab\xb0\xd0\x56\x82\xa9\xda\x47\x16" }, { "\x61\x62\x63\x64\x65\x66\x67\x68\x69", 9, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\x5d\x41\x3d\xa3\xa7\xfc\x5d\x0c", 8, 1024, 32, "\x4c\x7a\x86\xed\x81\x8a\x94\x99\x7d\x4a\xc4\xf7\x1c\xf8\x08\xdb" "\x09\x35\xd9\xa3\x2d\x22\xde\x32\x2d\x74\x38\xe5\xc8\xf2\x50\x6e" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA1, "\xca\xa7\xdc\x59\xce\x31\xe7\x49", 8, 1024, 32, "\x67\xe9\xd6\x29\x49\x1c\xb6\xa0\x85\xe8\xf9\x8b\x85\x47\x3a\x7e" "\xa7\xee\x89\x52\x6f\x19\x00\x53\x93\x07\x0a\x8b\xb9\xa8\x86\x94" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_SIMPLE_S2K, GCRY_MD_SHA256, NULL, 0, 0, 16, "\x88\x36\x78\x6b\xd9\x5a\x62\xff\x47\xd3\xfb\x79\xc9\x08\x70\x56" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_SALTED_S2K, GCRY_MD_SHA256, "\x05\x8b\xfe\x31\xaa\xf3\x29\x11", 8, 0, 16, "\xb2\x42\xfe\x5e\x09\x02\xd9\x62\xb9\x35\xf3\xa8\x43\x80\x9f\xb1" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA256, "\xd3\x4a\xea\xc9\x97\x1b\xcc\x83", 8, 1024, 16, "\x35\x37\x99\x62\x07\x26\x68\x23\x05\x47\xb2\xa0\x0b\x2b\x2b\x8d" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA256, "\x5e\x71\xbd\x00\x5f\x96\xc4\x23", 8, 10240, 16, "\xa1\x6a\xee\xba\xde\x73\x25\x25\xd1\xab\xa0\xc5\x7e\xc6\x39\xa7" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA384, "\xc3\x08\xeb\x17\x62\x08\x89\xef", 8, 1024, 16, "\x9b\x7f\x0c\x81\x6f\x71\x59\x9b\xd5\xf6\xbf\x3a\x86\x20\x16\x33" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512, "\xe6\x7d\x13\x6b\x39\xe3\x44\x05", 8, 1024, 16, "\xc8\xcd\x4b\xa4\xf3\xf1\xd5\xb0\x59\x06\xf0\xbb\x89\x34\x6a\xad" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512, "\xed\x7d\x30\x47\xe4\xc3\xf8\xb6", 8, 1024, 32, "\x89\x7a\xef\x70\x97\xe7\x10\xdb\x75\xcc\x20\x22\xab\x7b\xf3\x05" "\x4b\xb6\x2e\x17\x11\x9f\xd6\xeb\xbf\xdf\x4d\x70\x59\xf0\xf9\xe5" }, { "\x4c\x6f\x6e\x67\x5f\x73\x65\x6e\x74\x65\x6e\x63\x65\x5f\x75\x73" "\x65\x64\x5f\x61\x73\x5f\x70\x61\x73\x73\x70\x68\x72\x61\x73\x65", 32, GCRY_KDF_ITERSALTED_S2K, GCRY_MD_SHA512, "\xbb\x1a\x45\x30\x68\x62\x6d\x63", 8, 1024, 24, "\xde\x5c\xb8\xd5\x75\xf6\xad\x69\x5b\xc9\xf6\x2f\xba\xeb\xfb\x36" "\x34\xf2\xb8\xee\x3b\x37\x21\xb7" } }; int tvidx; gpg_error_t err; unsigned char outbuf[32]; int i; for (tvidx=0; tvidx < DIM(tv); tvidx++) { if (tv[tvidx].disabled) continue; if (verbose) fprintf (stderr, "checking S2K test vector %d\n", tvidx); assert (tv[tvidx].dklen <= sizeof outbuf); err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen, tv[tvidx].algo, tv[tvidx].hashalgo, tv[tvidx].salt, tv[tvidx].saltlen, tv[tvidx].c, tv[tvidx].dklen, outbuf); if (err) fail ("s2k test %d failed: %s\n", tvidx, gpg_strerror (err)); else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) { fail ("s2k test %d failed: mismatch\n", tvidx); fputs ("got:", stderr); for (i=0; i < tv[tvidx].dklen; i++) fprintf (stderr, " %02x", outbuf[i]); putc ('\n', stderr); } } } static void check_pbkdf2 (void) { /* Test vectors are from RFC-6070. */ static struct { const char *p; /* Passphrase. */ size_t plen; /* Length of P. */ const char *salt; size_t saltlen; unsigned long c; /* Iterations. */ int dklen; /* Requested key length. */ const char *dk; /* Derived key. */ int disabled; } tv[] = { { "password", 8, "salt", 4, 1, 20, "\x0c\x60\xc8\x0f\x96\x1f\x0e\x71\xf3\xa9" "\xb5\x24\xaf\x60\x12\x06\x2f\xe0\x37\xa6" }, { "password", 8, "salt", 4, 2, 20, "\xea\x6c\x01\x4d\xc7\x2d\x6f\x8c\xcd\x1e" "\xd9\x2a\xce\x1d\x41\xf0\xd8\xde\x89\x57" }, { "password", 8, "salt", 4, 4096, 20, "\x4b\x00\x79\x01\xb7\x65\x48\x9a\xbe\xad" "\x49\xd9\x26\xf7\x21\xd0\x65\xa4\x29\xc1" }, { "password", 8, "salt", 4, 16777216, 20, "\xee\xfe\x3d\x61\xcd\x4d\xa4\xe4\xe9\x94" "\x5b\x3d\x6b\xa2\x15\x8c\x26\x34\xe9\x84", 1 /* This test takes too long. */ }, { "passwordPASSWORDpassword", 24, "saltSALTsaltSALTsaltSALTsaltSALTsalt", 36, 4096, 25, "\x3d\x2e\xec\x4f\xe4\x1c\x84\x9b\x80\xc8" "\xd8\x36\x62\xc0\xe4\x4a\x8b\x29\x1a\x96" "\x4c\xf2\xf0\x70\x38" }, { "pass\0word", 9, "sa\0lt", 5, 4096, 16, "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37" "\xd7\xf0\x34\x25\xe0\xc3" }, { /* empty password test, not in RFC-6070 */ "", 0, "salt", 4, 2, 20, "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2" "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97" } }; int tvidx; gpg_error_t err; unsigned char outbuf[32]; int i; for (tvidx=0; tvidx < DIM(tv); tvidx++) { if (tv[tvidx].disabled) continue; if (verbose) fprintf (stderr, "checking PBKDF2 test vector %d\n", tvidx); assert (tv[tvidx].dklen <= sizeof outbuf); err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen, GCRY_KDF_PBKDF2, GCRY_MD_SHA1, tv[tvidx].salt, tv[tvidx].saltlen, tv[tvidx].c, tv[tvidx].dklen, outbuf); if (err) fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err)); else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) { fail ("pbkdf2 test %d failed: mismatch\n", tvidx); fputs ("got:", stderr); for (i=0; i < tv[tvidx].dklen; i++) fprintf (stderr, " %02x", outbuf[i]); putc ('\n', stderr); } } } static void check_scrypt (void) { /* Test vectors are from draft-josefsson-scrypt-kdf-01. */ static struct { const char *p; /* Passphrase. */ size_t plen; /* Length of P. */ const char *salt; size_t saltlen; int parm_n; /* CPU/memory cost. */ int parm_r; /* blocksize */ unsigned long parm_p; /* parallelization. */ int dklen; /* Requested key length. */ const char *dk; /* Derived key. */ int disabled; } tv[] = { { "", 0, "", 0, 16, 1, 1, 64, "\x77\xd6\x57\x62\x38\x65\x7b\x20\x3b\x19\xca\x42\xc1\x8a\x04\x97" "\xf1\x6b\x48\x44\xe3\x07\x4a\xe8\xdf\xdf\xfa\x3f\xed\xe2\x14\x42" "\xfc\xd0\x06\x9d\xed\x09\x48\xf8\x32\x6a\x75\x3a\x0f\xc8\x1f\x17" "\xe8\xd3\xe0\xfb\x2e\x0d\x36\x28\xcf\x35\xe2\x0c\x38\xd1\x89\x06" }, { "password", 8, "NaCl", 4, 1024, 8, 16, 64, "\xfd\xba\xbe\x1c\x9d\x34\x72\x00\x78\x56\xe7\x19\x0d\x01\xe9\xfe" "\x7c\x6a\xd7\xcb\xc8\x23\x78\x30\xe7\x73\x76\x63\x4b\x37\x31\x62" "\x2e\xaf\x30\xd9\x2e\x22\xa3\x88\x6f\xf1\x09\x27\x9d\x98\x30\xda" "\xc7\x27\xaf\xb9\x4a\x83\xee\x6d\x83\x60\xcb\xdf\xa2\xcc\x06\x40" }, { "pleaseletmein", 13, "SodiumChloride", 14, 16384, 8, 1, 64, "\x70\x23\xbd\xcb\x3a\xfd\x73\x48\x46\x1c\x06\xcd\x81\xfd\x38\xeb" "\xfd\xa8\xfb\xba\x90\x4f\x8e\x3e\xa9\xb5\x43\xf6\x54\x5d\xa1\xf2" "\xd5\x43\x29\x55\x61\x3f\x0f\xcf\x62\xd4\x97\x05\x24\x2a\x9a\xf9" "\xe6\x1e\x85\xdc\x0d\x65\x1e\x40\xdf\xcf\x01\x7b\x45\x57\x58\x87" }, { "pleaseletmein", 13, "SodiumChloride", 14, 1048576, 8, 1, 64, "\x21\x01\xcb\x9b\x6a\x51\x1a\xae\xad\xdb\xbe\x09\xcf\x70\xf8\x81" "\xec\x56\x8d\x57\x4a\x2f\xfd\x4d\xab\xe5\xee\x98\x20\xad\xaa\x47" "\x8e\x56\xfd\x8f\x4b\xa5\xd0\x9f\xfa\x1c\x6d\x92\x7c\x40\xf4\xc3" "\x37\x30\x40\x49\xe8\xa9\x52\xfb\xcb\xf4\x5c\x6f\xa7\x7a\x41\xa4", 2 /* Only in debug mode. */ } }; int tvidx; gpg_error_t err; unsigned char outbuf[64]; int i; for (tvidx=0; tvidx < DIM(tv); tvidx++) { if (tv[tvidx].disabled && !(tv[tvidx].disabled == 2 && debug)) continue; if (verbose) fprintf (stderr, "checking SCRYPT test vector %d\n", tvidx); assert (tv[tvidx].dklen <= sizeof outbuf); err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen, tv[tvidx].parm_r == 1 ? 41 : GCRY_KDF_SCRYPT, tv[tvidx].parm_n, tv[tvidx].salt, tv[tvidx].saltlen, tv[tvidx].parm_p, tv[tvidx].dklen, outbuf); if (err) fail ("scrypt test %d failed: %s\n", tvidx, gpg_strerror (err)); else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) { fail ("scrypt test %d failed: mismatch\n", tvidx); fputs ("got:", stderr); for (i=0; i < tv[tvidx].dklen; i++) fprintf (stderr, " %02x", outbuf[i]); putc ('\n', stderr); } } } int main (int argc, char **argv) { if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) verbose = debug = 1; if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); check_openpgp (); check_pbkdf2 (); check_scrypt (); return error_count ? 1 : 0; } diff --git a/tests/t-mpi-bit.c b/tests/t-mpi-bit.c index 85bd32e9..b1c999e4 100644 --- a/tests/t-mpi-bit.c +++ b/tests/t-mpi-bit.c @@ -1,361 +1,361 @@ /* t-mpi-bit.c - Tests for bit level functions * Copyright (C) 2006 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" #define PGM "t-mpi-bit" static const char *wherestr; static int verbose; static int error_count; #define xmalloc(a) gcry_xmalloc ((a)) #define xcalloc(a,b) gcry_xcalloc ((a),(b)) #define xfree(a) gcry_free ((a)) #define pass() do { ; } while (0) static void show (const char *format, ...) { va_list arg_ptr; if (!verbose) return; fprintf (stderr, "%s: ", PGM); va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); } static void fail (const char *format, ...) { va_list arg_ptr; fflush (stdout); fprintf (stderr, "%s: ", PGM); if (wherestr) fprintf (stderr, "%s: ", wherestr); va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); error_count++; } static void die (const char *format, ...) { va_list arg_ptr; fflush (stdout); fprintf (stderr, "%s: ", PGM); if (wherestr) fprintf (stderr, "%s: ", wherestr); va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } /* Allocate a bit string consisting of '0' and '1' from the MPI A. Return the LENGTH least significant bits. Caller needs to xfree the result. */ static char * mpi2bitstr (gcry_mpi_t a, size_t length) { char *p, *buf; buf = p = xmalloc (length+1); while (length--) *p++ = gcry_mpi_test_bit (a, length) ? '1':'0'; *p = 0; return buf; } /* Allocate a bit string consisting of '0' and '1' from the MPI A. Do not return any leading zero bits. Caller needs to xfree the result. */ static char * mpi2bitstr_nlz (gcry_mpi_t a) { char *p, *buf; size_t length = gcry_mpi_get_nbits (a); if (!length) { buf = p = xmalloc (2); *p++ = '0'; } else { buf = p = xmalloc (length + 1); while (length-- > 1) *p++ = gcry_mpi_test_bit (a, length) ? '1':'0'; *p++ = gcry_mpi_test_bit (a, 0) ? '1':'0'; } *p = 0; return buf; } /* Shift a bit string to the right. */ static void rshiftbitstring (char *string, size_t n) { size_t len = strlen (string); if (n > len) n = len; memmove (string+n, string, len-n); memset (string, '0', n); } /* Shift a bit string to the left. Caller needs to free the result. */ static char * lshiftbitstring (const char *string, size_t n) { size_t len = strlen (string); char *result; if (len+n+1 < len) die ("internal overflow\n"); /* Allocate enough space. */ result = xmalloc (len+n+1); for (; *string == '0' && string[1]; string++, len--) ; memcpy (result, string, len); if (*string == '0' && !string[1]) n = 0; /* Avoid extra nulls for an only 0 string. */ else memset (result+len, '0', n); result[len+n] = 0; return result; } /* This is to check a bug reported by bpgcrypt at itaparica.org on 2006-07-31 against libgcrypt 1.2.2. */ static void one_bit_only (int highbit) { gcry_mpi_t a; char *result; int i; wherestr = "one_bit_only"; show ("checking that set_%sbit does only set one bit\n", highbit?"high":""); a = gcry_mpi_new (0); gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); gcry_mpi_set_ui (a, 0); if (highbit) gcry_mpi_set_highbit (a, 42); else gcry_mpi_set_bit (a, 42); if (!gcry_mpi_test_bit (a, 42)) fail ("failed to set a bit\n"); gcry_mpi_clear_bit (a, 42); if (gcry_mpi_test_bit (a, 42)) fail ("failed to clear a bit\n"); result = mpi2bitstr (a, 70); assert (strlen (result) == 70); for (i=0; result[i]; i++) if ( result[i] != '0' ) break; if (result[i]) fail ("spurious bits detected\n"); xfree (result); gcry_mpi_release (a); } /* Check that right shifting actually works for an amount larger than the number of bits per limb. */ static void test_rshift (int pass) { gcry_mpi_t a, b; char *result, *result2; int i; wherestr = "test_rshift"; show ("checking that rshift works as expected (pass %d)\n", pass); a = gcry_mpi_new (0); b = gcry_mpi_new (0); gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); for (i=0; i < 75; i++) { gcry_mpi_rshift (b, a, i); result = mpi2bitstr (b, 72); result2 = mpi2bitstr (a, 72); rshiftbitstring (result2, i); if (strcmp (result, result2)) { show ("got =%s\n", result); show ("want=%s\n", result2); fail ("rshift by %d failed\n", i); } xfree (result); xfree (result2); } /* Again. This time using in-place operation. */ gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); for (i=0; i < 75; i++) { gcry_mpi_release (b); b = gcry_mpi_copy (a); gcry_mpi_rshift (b, b, i); result = mpi2bitstr (b, 72); result2 = mpi2bitstr (a, 72); rshiftbitstring (result2, i); if (strcmp (result, result2)) { show ("got =%s\n", result); show ("want=%s\n", result2); fail ("in-place rshift by %d failed\n", i); } xfree (result2); xfree (result); } gcry_mpi_release (b); gcry_mpi_release (a); } /* Check that left shifting works correctly. */ static void test_lshift (int pass) { static int size_list[] = {1, 31, 32, 63, 64, 65, 70, 0}; int size_idx; gcry_mpi_t a, b; char *tmpstr, *result, *result2; int i; wherestr = "test_lshift"; show ("checking that lshift works as expected (pass %d)\n", pass); for (size_idx=0; size_list[size_idx]; size_idx++) { a = gcry_mpi_new (0); b = gcry_mpi_new (0); /* gcry_mpi_randomize rounds up to full bytes, thus we need to use gcry_mpi_clear_highbit to fix that. */ gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM); gcry_mpi_clear_highbit (a, size_list[size_idx]); for (i=0; i < 75; i++) { gcry_mpi_lshift (b, a, i); result = mpi2bitstr_nlz (b); tmpstr = mpi2bitstr_nlz (a); result2 = lshiftbitstring (tmpstr, i); xfree (tmpstr); if (strcmp (result, result2)) { show ("got =%s\n", result); show ("want=%s\n", result2); fail ("lshift by %d failed\n", i); } xfree (result); xfree (result2); } /* Again. This time using in-place operation. */ gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM); gcry_mpi_clear_highbit (a, size_list[size_idx]); for (i=0; i < 75; i++) { gcry_mpi_release (b); b = gcry_mpi_copy (a); gcry_mpi_lshift (b, b, i); result = mpi2bitstr_nlz (b); tmpstr = mpi2bitstr_nlz (a); result2 = lshiftbitstring (tmpstr, i); xfree (tmpstr); if (strcmp (result, result2)) { show ("got =%s\n", result); show ("want=%s\n", result2); fail ("in-place lshift by %d failed\n", i); } xfree (result2); xfree (result); } gcry_mpi_release (b); gcry_mpi_release (a); } } int main (int argc, char **argv) { int debug = 0; int i; if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) verbose = debug = 1; if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); one_bit_only (0); one_bit_only (1); for (i=0; i < 5; i++) test_rshift (i); /* Run several times due to random initializations. */ for (i=0; i < 5; i++) test_lshift (i); /* Run several times due to random initializations. */ show ("All tests completed. Errors: %d\n", error_count); return error_count ? 1 : 0; } diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 98236e78..2631a113 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -1,793 +1,793 @@ /* t-mpi-point.c - Tests for mpi point functions * Copyright (C) 2013 g10 Code GmbH * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" #define PGM "t-mpi-point" static const char *wherestr; static int verbose; static int debug; static int error_count; #define xmalloc(a) gcry_xmalloc ((a)) #define xcalloc(a,b) gcry_xcalloc ((a),(b)) #define xfree(a) gcry_free ((a)) #define pass() do { ; } while (0) static struct { const char *desc; /* Description of the curve. */ const char *p; /* Order of the prime field. */ const char *a, *b; /* The coefficients. */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ } test_curve[] = { { "NIST P-192", "0xfffffffffffffffffffffffffffffffeffffffffffffffff", "0xfffffffffffffffffffffffffffffffefffffffffffffffc", "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811" }, { "NIST P-224", "0xffffffffffffffffffffffffffffffff000000000000000000000001", "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe", "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34" }, { "NIST P-256", "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" }, { "NIST P-384", "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" "ffffffff0000000000000000ffffffff", "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" "ffffffff0000000000000000fffffffc", "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a" "c656398d8a2ed19d2a85c8edd3ec2aef", "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf" "581a0db248b0a77aecec196accc52973", "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" "5502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" "0a60b1ce1d7e819d7a431d7c90ea0e5f" }, { "NIST P-521", "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" }, { NULL, NULL, NULL, NULL, NULL } }; /* A sample public key for NIST P-256. */ static const char sample_p256_q[] = "04" "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E" "E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E"; static const char sample_p256_q_x[] = "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E"; static const char sample_p256_q_y[] = "00E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E"; static void show (const char *format, ...) { va_list arg_ptr; if (!verbose) return; fprintf (stderr, "%s: ", PGM); va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); } static void fail (const char *format, ...) { va_list arg_ptr; fflush (stdout); fprintf (stderr, "%s: ", PGM); if (wherestr) fprintf (stderr, "%s: ", wherestr); va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); error_count++; } static void die (const char *format, ...) { va_list arg_ptr; fflush (stdout); fprintf (stderr, "%s: ", PGM); if (wherestr) fprintf (stderr, "%s: ", wherestr); va_start (arg_ptr, format); vfprintf (stderr, format, arg_ptr); va_end (arg_ptr); exit (1); } static void print_mpi_2 (const char *text, const char *text2, gcry_mpi_t a) { gcry_error_t err; char *buf; void *bufaddr = &buf; err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); if (err) fprintf (stderr, "%s%s: [error printing number: %s]\n", text, text2? text2:"", gpg_strerror (err)); else { fprintf (stderr, "%s%s: %s\n", text, text2? text2:"", buf); gcry_free (buf); } } static void print_mpi (const char *text, gcry_mpi_t a) { print_mpi_2 (text, NULL, a); } static void print_point (const char *text, gcry_mpi_point_t a) { gcry_mpi_t x, y, z; x = gcry_mpi_new (0); y = gcry_mpi_new (0); z = gcry_mpi_new (0); gcry_mpi_point_get (x, y, z, a); print_mpi_2 (text, ".x", x); print_mpi_2 (text, ".y", y); print_mpi_2 (text, ".z", z); gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (z); } static void print_sexp (const char *prefix, gcry_sexp_t a) { char *buf; size_t size; if (prefix) fputs (prefix, stderr); size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); buf = gcry_xmalloc (size); gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); fprintf (stderr, "%.*s", (int)size, buf); gcry_free (buf); } static gcry_mpi_t hex2mpi (const char *string) { gpg_error_t err; gcry_mpi_t val; err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); if (err) die ("hex2mpi '%s' failed: %s\n", gpg_strerror (err)); return val; } /* Compare A to B, where B is given as a hex string. */ static int cmp_mpihex (gcry_mpi_t a, const char *b) { gcry_mpi_t bval; int res; bval = hex2mpi (b); res = gcry_mpi_cmp (a, bval); gcry_mpi_release (bval); return res; } /* Wrapper to emulate the libgcrypt internal EC context allocation function. */ static gpg_error_t ec_p_new (gcry_ctx_t *r_ctx, gcry_mpi_t p, gcry_mpi_t a) { gpg_error_t err; gcry_sexp_t sexp; if (p && a) err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m)(a %m))", p, a); else if (p) err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m))", p); else if (a) err = gcry_sexp_build (&sexp, NULL, "(ecdsa (a %m))", a); else err = gcry_sexp_build (&sexp, NULL, "(ecdsa)"); if (err) return err; err = gcry_mpi_ec_new (r_ctx, sexp, NULL); gcry_sexp_release (sexp); return err; } static void set_get_point (void) { gcry_mpi_point_t point; gcry_mpi_t x, y, z; wherestr = "set_get_point"; show ("checking point setting functions\n"); point = gcry_mpi_point_new (0); x = gcry_mpi_set_ui (NULL, 17); y = gcry_mpi_set_ui (NULL, 42); z = gcry_mpi_set_ui (NULL, 11371); gcry_mpi_point_get (x, y, z, point); if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) fail ("new point not initialized to (0,0,0)\n"); gcry_mpi_point_snatch_get (x, y, z, point); point = NULL; if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) fail ("snatch_get failed\n"); gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (z); point = gcry_mpi_point_new (0); x = gcry_mpi_set_ui (NULL, 17); y = gcry_mpi_set_ui (NULL, 42); z = gcry_mpi_set_ui (NULL, 11371); gcry_mpi_point_set (point, x, y, z); gcry_mpi_set_ui (x, 23); gcry_mpi_set_ui (y, 24); gcry_mpi_set_ui (z, 25); gcry_mpi_point_get (x, y, z, point); if (gcry_mpi_cmp_ui (x, 17) || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) fail ("point_set/point_get failed\n"); gcry_mpi_point_snatch_set (point, x, y, z); x = gcry_mpi_new (0); y = gcry_mpi_new (0); z = gcry_mpi_new (0); gcry_mpi_point_get (x, y, z, point); if (gcry_mpi_cmp_ui (x, 17) || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) fail ("point_snatch_set/point_get failed\n"); gcry_mpi_point_release (point); gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (z); } static void context_alloc (void) { gpg_error_t err; gcry_ctx_t ctx; gcry_mpi_t p, a; wherestr = "context_alloc"; show ("checking context functions\n"); p = gcry_mpi_set_ui (NULL, 1); a = gcry_mpi_set_ui (NULL, 1); err = ec_p_new (&ctx, p, a); if (err) die ("ec_p_new returned an error: %s\n", gpg_strerror (err)); gcry_mpi_release (p); gcry_mpi_release (a); gcry_ctx_release (ctx); p = gcry_mpi_set_ui (NULL, 0); a = gcry_mpi_set_ui (NULL, 0); err = ec_p_new (&ctx, p, a); if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) fail ("ec_p_new: bad parameter detection failed (1)\n"); gcry_mpi_set_ui (p, 1); err = ec_p_new (&ctx, p, a); if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) fail ("ec_p_new: bad parameter detection failed (2)\n"); gcry_mpi_release (p); p = NULL; err = ec_p_new (&ctx, p, a); if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) fail ("ec_p_new: bad parameter detection failed (3)\n"); gcry_mpi_release (a); a = NULL; err = ec_p_new (&ctx, p, a); if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) fail ("ec_p_new: bad parameter detection failed (4)\n"); } static int get_and_cmp_mpi (const char *name, const char *mpistring, const char *desc, gcry_ctx_t ctx) { gcry_mpi_t mpi; mpi = gcry_mpi_ec_get_mpi (name, ctx, 1); if (!mpi) { fail ("error getting parameter '%s' of curve '%s'\n", name, desc); return 1; } if (debug) print_mpi (name, mpi); if (cmp_mpihex (mpi, mpistring)) { fail ("parameter '%s' of curve '%s' does not match\n", name, desc); gcry_mpi_release (mpi); return 1; } gcry_mpi_release (mpi); return 0; } static int get_and_cmp_point (const char *name, const char *mpi_x_string, const char *mpi_y_string, const char *desc, gcry_ctx_t ctx) { gcry_mpi_point_t point; gcry_mpi_t x, y, z; int result = 0; point = gcry_mpi_ec_get_point (name, ctx, 1); if (!point) { fail ("error getting point parameter '%s' of curve '%s'\n", name, desc); return 1; } if (debug) print_point (name, point); x = gcry_mpi_new (0); y = gcry_mpi_new (0); z = gcry_mpi_new (0); gcry_mpi_point_snatch_get (x, y, z, point); if (cmp_mpihex (x, mpi_x_string)) { fail ("x coordinate of '%s' of curve '%s' does not match\n", name, desc); result = 1; } if (cmp_mpihex (y, mpi_y_string)) { fail ("y coordinate of '%s' of curve '%s' does not match\n", name, desc); result = 1; } if (cmp_mpihex (z, "01")) { fail ("z coordinate of '%s' of curve '%s' is not 1\n", name, desc); result = 1; } gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (z); return result; } static void context_param (void) { gpg_error_t err; int idx; gcry_ctx_t ctx = NULL; gcry_mpi_t q; gcry_sexp_t keyparam; wherestr = "context_param"; show ("checking standard curves\n"); for (idx=0; test_curve[idx].desc; idx++) { gcry_ctx_release (ctx); err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc); if (err) { fail ("can't create context for curve '%s': %s\n", test_curve[idx].desc, gpg_strerror (err)); continue; } if (get_and_cmp_mpi ("p", test_curve[idx].p, test_curve[idx].desc, ctx)) continue; if (get_and_cmp_mpi ("a", test_curve[idx].a, test_curve[idx].desc, ctx)) continue; if (get_and_cmp_mpi ("b", test_curve[idx].b, test_curve[idx].desc, ctx)) continue; if (get_and_cmp_mpi ("g.x",test_curve[idx].g_x, test_curve[idx].desc,ctx)) continue; if (get_and_cmp_mpi ("g.y",test_curve[idx].g_y, test_curve[idx].desc,ctx)) continue; if (get_and_cmp_mpi ("n", test_curve[idx].n, test_curve[idx].desc, ctx)) continue; if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y, test_curve[idx].desc, ctx)) continue; } gcry_ctx_release (ctx); show ("checking sample public key\n"); q = hex2mpi (sample_p256_q); err = gcry_sexp_build (&keyparam, NULL, "(public-key(ecdsa(curve %s)(q %m)))", "NIST P-256", q); if (err) die ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); gcry_mpi_release (q); /* We can't call gcry_pk_testkey because it is only implemented for private keys. */ /* err = gcry_pk_testkey (keyparam); */ /* if (err) */ /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */ /* gpg_strerror (err)); */ err = gcry_mpi_ec_new (&ctx, keyparam, NULL); if (err) fail ("gcry_mpi_ec_new failed for sample public key: %s\n", gpg_strerror (err)); else { gcry_sexp_t sexp; get_and_cmp_mpi ("q", sample_p256_q, "NIST P-256", ctx); get_and_cmp_point ("q", sample_p256_q_x, sample_p256_q_y, "NIST P-256", ctx); err = gcry_pubkey_get_sexp (&sexp, 0, ctx); if (err) fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err)); else if (debug) print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp); gcry_sexp_release (sexp); err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx); if (err) fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", gpg_strerror (err)); else if (debug) print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp); gcry_sexp_release (sexp); err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx); if (gpg_err_code (err) != GPG_ERR_NO_SECKEY) fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n", gpg_strerror (err)); gcry_sexp_release (sexp); gcry_ctx_release (ctx); } gcry_sexp_release (keyparam); } /* Create a new point from (X,Y,Z) given as hex strings. */ gcry_mpi_point_t make_point (const char *x, const char *y, const char *z) { gcry_mpi_point_t point; point = gcry_mpi_point_new (0); gcry_mpi_point_snatch_set (point, hex2mpi (x), hex2mpi (y), hex2mpi (z)); return point; } /* This tests checks that the low-level EC API yields the same result as using the high level API. The values have been taken from a test run using the high level API. */ static void basic_ec_math (void) { gpg_error_t err; gcry_ctx_t ctx; gcry_mpi_t P, A; gcry_mpi_point_t G, Q; gcry_mpi_t d; gcry_mpi_t x, y, z; wherestr = "basic_ec_math"; show ("checking basic math functions for EC\n"); P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff"); A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc"); G = make_point ("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", "1"); d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D"); Q = gcry_mpi_point_new (0); err = ec_p_new (&ctx, P, A); if (err) die ("ec_p_new failed: %s\n", gpg_strerror (err)); x = gcry_mpi_new (0); y = gcry_mpi_new (0); z = gcry_mpi_new (0); { /* A quick check that multiply by zero works. */ gcry_mpi_t tmp; tmp = gcry_mpi_new (0); gcry_mpi_ec_mul (Q, tmp, G, ctx); gcry_mpi_release (tmp); gcry_mpi_point_get (x, y, z, Q); if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) fail ("multiply a point by zero failed\n"); } gcry_mpi_ec_mul (Q, d, G, ctx); gcry_mpi_point_get (x, y, z, Q); if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66") || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8") || cmp_mpihex (z, "00B06B519071BC536999AC8F2D3934B3C1FC9EACCD0A31F88F")) fail ("computed public key does not match\n"); if (debug) { print_mpi ("Q.x", x); print_mpi ("Q.y", y); print_mpi ("Q.z", z); } if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) fail ("failed to get affine coordinates\n"); if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE") || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966")) fail ("computed affine coordinates of public key do not match\n"); if (debug) { print_mpi ("q.x", x); print_mpi ("q.y", y); } gcry_mpi_release (z); gcry_mpi_release (y); gcry_mpi_release (x); gcry_mpi_point_release (Q); gcry_mpi_release (d); gcry_mpi_point_release (G); gcry_mpi_release (A); gcry_mpi_release (P); } /* This is the same as basic_ec_math but uses more advanced features. */ static void basic_ec_math_simplified (void) { gpg_error_t err; gcry_ctx_t ctx; gcry_mpi_point_t G, Q; gcry_mpi_t d; gcry_mpi_t x, y, z; gcry_sexp_t sexp; wherestr = "basic_ec_math_simplified"; show ("checking basic math functions for EC (variant)\n"); d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D"); Q = gcry_mpi_point_new (0); err = gcry_mpi_ec_new (&ctx, NULL, "NIST P-192"); if (err) die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err)); G = gcry_mpi_ec_get_point ("g", ctx, 1); if (!G) die ("gcry_mpi_ec_get_point(G) failed\n"); gcry_mpi_ec_mul (Q, d, G, ctx); x = gcry_mpi_new (0); y = gcry_mpi_new (0); z = gcry_mpi_new (0); gcry_mpi_point_get (x, y, z, Q); if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66") || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8") || cmp_mpihex (z, "00B06B519071BC536999AC8F2D3934B3C1FC9EACCD0A31F88F")) fail ("computed public key does not match\n"); if (debug) { print_mpi ("Q.x", x); print_mpi ("Q.y", y); print_mpi ("Q.z", z); } if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) fail ("failed to get affine coordinates\n"); if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE") || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966")) fail ("computed affine coordinates of public key do not match\n"); if (debug) { print_mpi ("q.x", x); print_mpi ("q.y", y); } gcry_mpi_release (z); gcry_mpi_release (y); gcry_mpi_release (x); /* Let us also check wheer we can update the context. */ err = gcry_mpi_ec_set_point ("g", G, ctx); if (err) die ("gcry_mpi_ec_set_point(G) failed\n"); err = gcry_mpi_ec_set_mpi ("d", d, ctx); if (err) die ("gcry_mpi_ec_set_mpi(d) failed\n"); /* FIXME: Below we need to check that the returned S-expression is as requested. For now we use manual inspection using --debug. */ /* Does get_sexp return the private key? */ err = gcry_pubkey_get_sexp (&sexp, 0, ctx); if (err) fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err)); else if (verbose) print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp); gcry_sexp_release (sexp); /* Does get_sexp return the public key if requested? */ err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx); if (err) fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", gpg_strerror (err)); else if (verbose) print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp); gcry_sexp_release (sexp); /* Does get_sexp return the public key if after d has been deleted? */ err = gcry_mpi_ec_set_mpi ("d", NULL, ctx); if (err) die ("gcry_mpi_ec_set_mpi(d=NULL) failed\n"); err = gcry_pubkey_get_sexp (&sexp, 0, ctx); if (err) fail ("gcry_pubkey_get_sexp(0 w/o d) failed: %s\n", gpg_strerror (err)); else if (verbose) print_sexp ("Result of gcry_pubkey_get_sexp (0 w/o d):\n", sexp); gcry_sexp_release (sexp); /* Does get_sexp return an error after d has been deleted? */ err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx); if (gpg_err_code (err) != GPG_ERR_NO_SECKEY) fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n", gpg_strerror (err)); gcry_sexp_release (sexp); /* Does get_sexp return an error after d and Q have been deleted? */ err = gcry_mpi_ec_set_point ("q", NULL, ctx); if (err) die ("gcry_mpi_ec_set_point(q=NULL) failed\n"); err = gcry_pubkey_get_sexp (&sexp, 0, ctx); if (gpg_err_code (err) != GPG_ERR_BAD_CRYPT_CTX) fail ("gcry_pubkey_get_sexp(0 w/o Q,d) returned wrong error: %s\n", gpg_strerror (err)); gcry_sexp_release (sexp); gcry_mpi_point_release (Q); gcry_mpi_release (d); gcry_mpi_point_release (G); } int main (int argc, char **argv) { if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) verbose = debug = 1; if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); set_get_point (); context_alloc (); context_param (); basic_ec_math (); basic_ec_math_simplified (); show ("All tests completed. Errors: %d\n", error_count); return error_count ? 1 : 0; } diff --git a/tests/tsexp.c b/tests/tsexp.c index 73d3d6ed..cef3ed13 100644 --- a/tests/tsexp.c +++ b/tests/tsexp.c @@ -1,456 +1,456 @@ /* tsexp.c - S-expression regression tests * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * * Libgcrypt is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * Libgcrypt is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" #define PGMNAME "tsexp" static int verbose; static int error_count; static void info (const char *format, ...) { va_list arg_ptr; if (verbose) { va_start( arg_ptr, format ) ; vfprintf (stderr, format, arg_ptr ); va_end(arg_ptr); } } static void fail ( const char *format, ... ) { va_list arg_ptr ; fputs (PGMNAME ": ", stderr); va_start( arg_ptr, format ) ; vfprintf (stderr, format, arg_ptr ); va_end(arg_ptr); error_count++; } /* fixme: we need better tests */ static void basic (void) { int pass; gcry_sexp_t sexp; int idx; char *secure_buffer; size_t secure_buffer_len; const char *string; static struct { const char *token; const char *parm; } values[] = { { "public-key", NULL }, { "dsa", NULL }, { "dsa", "p" }, { "dsa", "y" }, { "dsa", "q" }, { "dsa", "g" }, { NULL } }; info ("doing some pretty pointless tests\n"); secure_buffer_len = 99; secure_buffer = gcry_xmalloc_secure (secure_buffer_len); memset (secure_buffer, 'G', secure_buffer_len); for (pass=0;;pass++) { switch (pass) { case 0: string = ("(public-key (dsa (p #41424344#) (y this_is_y) " "(q #61626364656667#) (g %m)))"); if ( gcry_sexp_build (&sexp, NULL, string, gcry_mpi_set_ui (NULL, 42)) ) { fail (" scanning `%s' failed\n", string); return; } break; case 1: string = ("(public-key (dsa (p #41424344#) (y this_is_y) " "(q %b) (g %m)))"); if ( gcry_sexp_build (&sexp, NULL, string, 15, "foo\0\x01\0x02789012345", gcry_mpi_set_ui (NULL, 42)) ) { fail (" scanning `%s' failed\n", string); return; } break; case 2: string = ("(public-key (dsa (p #41424344#) (y silly_y_value) " "(q %b) (g %m)))"); if ( gcry_sexp_build (&sexp, NULL, string, secure_buffer_len, secure_buffer, gcry_mpi_set_ui (NULL, 17)) ) { fail (" scanning `%s' failed\n", string); return; } if (!gcry_is_secure (sexp)) fail ("gcry_sexp_build did not switch to secure memory\n"); break; case 3: { gcry_sexp_t help_sexp; if (gcry_sexp_new (&help_sexp, "(foobar-parms (xp #1234#)(xq #03#))", 0, 1)) { fail (" scanning fixed string failed\n"); return; } string = ("(public-key (dsa (p #41424344#) (parm %S) " "(y dummy)(q %b) (g %m)))"); if ( gcry_sexp_build (&sexp, NULL, string, help_sexp, secure_buffer_len, secure_buffer, gcry_mpi_set_ui (NULL, 17)) ) { fail (" scanning `%s' failed\n", string); return; } gcry_sexp_release (help_sexp); } break; default: return; /* Ready. */ } /* now find something */ for (idx=0; values[idx].token; idx++) { const char *token = values[idx].token; const char *parm = values[idx].parm; gcry_sexp_t s1, s2; gcry_mpi_t a; const char *p; size_t n; s1 = gcry_sexp_find_token (sexp, token, strlen(token) ); if (!s1) { fail ("didn't found `%s'\n", token); continue; } p = gcry_sexp_nth_data (s1, 0, &n); if (!p) { fail ("no car for `%s'\n", token); continue; } info ("car=`%.*s'\n", (int)n, p); s2 = gcry_sexp_cdr (s1); if (!s2) { fail ("no cdr for `%s'\n", token); continue; } p = gcry_sexp_nth_data (s2, 0, &n); if (p) { fail ("data at car of `%s'\n", token); continue; } if (parm) { s2 = gcry_sexp_find_token (s1, parm, strlen (parm)); if (!s2) { fail ("didn't found `%s'\n", parm); continue; } p = gcry_sexp_nth_data (s2, 0, &n); if (!p) { fail("no car for `%s'\n", parm ); continue; } info ("car=`%.*s'\n", (int)n, p); p = gcry_sexp_nth_data (s2, 1, &n); if (!p) { fail("no cdr for `%s'\n", parm ); continue; } info ("cdr=`%.*s'\n", (int)n, p); a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG); if (!a) { fail("failed to cdr the mpi for `%s'\n", parm); continue; } } } gcry_sexp_release (sexp); sexp = NULL; } gcry_free (secure_buffer); } static void canon_len (void) { static struct { size_t textlen; /* length of the buffer */ size_t expected;/* expected length or 0 on error and then ... */ size_t erroff; /* ... and at this offset */ gcry_error_t errcode; /* ... with this error code */ const char *text; } values[] = { { 14, 13, 0, GPG_ERR_NO_ERROR, "(9:abcdefghi) " }, { 16, 15, 0, GPG_ERR_NO_ERROR, "(10:abcdefghix)" }, { 14, 0,14, GPG_ERR_SEXP_STRING_TOO_LONG, "(10:abcdefghi)" }, { 15, 0, 1, GPG_ERR_SEXP_ZERO_PREFIX, "(010:abcdefghi)" }, { 2, 0, 0, GPG_ERR_SEXP_NOT_CANONICAL, "1:"}, { 4, 0, 4, GPG_ERR_SEXP_STRING_TOO_LONG, "(1:)"}, { 5, 5, 0, GPG_ERR_NO_ERROR, "(1:x)"}, { 2, 2, 0, GPG_ERR_NO_ERROR, "()"}, { 4, 2, 0, GPG_ERR_NO_ERROR, "()()"}, { 4, 4, 0, GPG_ERR_NO_ERROR, "(())"}, { 3, 0, 3, GPG_ERR_SEXP_STRING_TOO_LONG, "(()"}, { 3, 0, 1, GPG_ERR_SEXP_BAD_CHARACTER, "( )"}, { 9, 9, 0, GPG_ERR_NO_ERROR, "(3:abc())"}, { 10, 0, 6, GPG_ERR_SEXP_BAD_CHARACTER, "(3:abc ())"}, /* fixme: we need much more cases */ { 0 }, }; int idx; gcry_error_t errcode; size_t n, erroff; info ("checking canoncial length test function\n"); for (idx=0; values[idx].text; idx++) { n = gcry_sexp_canon_len ((const unsigned char*)values[idx].text, values[idx].textlen, &erroff, &errcode); if (n && n == values[idx].expected) ; /* success */ else if (!n && !values[idx].expected) { /* we expected an error - check that this is the right one */ if (values[idx].erroff != erroff) fail ("canonical length test %d - wrong error offset %u\n", idx, (unsigned int)erroff); if (gcry_err_code (errcode) != values[idx].errcode) fail ("canonical length test %d - wrong error code %d\n", idx, errcode); } else fail ("canonical length test %d failed - n=%u, off=%u, err=%d\n", idx, (unsigned int)n, (unsigned int)erroff, errcode); } } static void back_and_forth_one (int testno, const char *buffer, size_t length) { gcry_error_t rc; gcry_sexp_t se, se1; size_t n, n1; char *p1; rc = gcry_sexp_new (&se, buffer, length, 1); if (rc) { fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc)); return; } n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0); if (!n1) { fail ("baf %d: get required length for canon failed\n", testno); return; } p1 = gcry_xmalloc (n1); n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1); if (n1 != n+1) /* sprints adds an extra 0 but dies not return it */ { fail ("baf %d: length mismatch for canon\n", testno); return; } rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free); if (rc) { fail ("baf %d: gcry_sexp_create failed: %s\n", testno, gpg_strerror (rc)); return; } gcry_sexp_release (se1); /* Again but with memory checking. */ p1 = gcry_xmalloc (n1+2); *p1 = '\x55'; p1[n1+1] = '\xaa'; n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1); if (n1 != n+1) /* sprints adds an extra 0 but does not return it */ { fail ("baf %d: length mismatch for canon\n", testno); return; } if (*p1 != '\x55' || p1[n1+1] != '\xaa') fail ("baf %d: memory corrupted (1)\n", testno); rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL); if (rc) { fail ("baf %d: gcry_sexp_create failed: %s\n", testno, gpg_strerror (rc)); return; } if (*p1 != '\x55' || p1[n1+1] != '\xaa') fail ("baf %d: memory corrupted (2)\n", testno); gcry_sexp_release (se1); if (*p1 != '\x55' || p1[n1+1] != '\xaa') fail ("baf %d: memory corrupted (3)\n", testno); gcry_free (p1); /* FIXME: we need a lot more tests */ gcry_sexp_release (se); } static void back_and_forth (void) { static struct { const char *buf; int len; } tests[] = { { "(7:g34:fgh1::2:())", 0 }, { "(7:g34:fgh1::2:())", 18 }, { "(protected-private-key \n" " (rsa \n" " (n #00BE8A536204687149A48FF9F1715FF3530AD9A836D62102BF4065E5CF5953236DB94F1DF2FF4D525CD4CE7966DDC3C839968E8BAC2948934DF047CC65287CD79F6C23C93E55D7F9231E3942BD496DE383469977635A51ADF4AF747DB958CA02E9940DFC1DC0FC7FC755E7EB6618FEE6DA54B8A06E0CBF9D9257443F9992261435#)\n" " (e #010001#)\n" " (protected openpgp-s2k3-sha1-aes-cbc \n" " (\n" " (sha1 #C2A5673BD3882405# \"96\")\n" " #8D08AAF6A9209ED69D71EB7E64D78715#)\n" " #F7B0B535F8F8E22F4F3DA031224070303F82F9207D42952F1ACF21A4AB1C50304EBB25527992C7B265A9E9FF702826FB88759BDD55E4759E9FCA6C879538C9D043A9C60A326CB6681090BAA731289BD880A7D5774D9999F026E5E7963BFC8C0BDC9F061393CB734B4F259725C0A0A0B15BA39C39146EF6A1B3DC4DF30A22EBE09FD05AE6CB0C8C6532951A925F354F4E26A51964F5BBA50081690C421C8385C4074E9BAB9297D081B857756607EAE652415275A741C89E815558A50AC638EDC5F5030210B4395E3E1A40FF38DCCCB333A19EA88EFE7E4D51B54128C6DF27395646836679AC21B1B25C1DA6F0A7CE9F9BE078EFC7934FA9AE202CBB0AA06C20DFAF9A66FAB7E9073FBE96B9A7F25C3BA45EC3EECA65796AEE313BA148DE5314F30345B452B50B17C4D841A7F27397126E8C10BD0CE3B50A82C0425AAEE7798031671407B681F52916256F78CAF92A477AC27BCBE26DAFD1BCE386A853E2A036F8314BB2E8E5BB1F196434232EFB0288331C2AB16DBC5457CC295EB966CAC5CE73D5DA5D566E469F0EFA82F9A12B8693E0#)\n" " )\n" " )\n", 0 }, { NULL, 0 } }; int idx; for (idx=0; tests[idx].buf; idx++) back_and_forth_one (idx, tests[idx].buf, tests[idx].len); } static void check_sscan (void) { static struct { const char *text; gcry_error_t expected_err; } values[] = { /* Bug reported by Olivier L'Heureux 2003-10-07 */ { "(7:sig-val(3:dsa" "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64" "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)" "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d" "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e)))", GPG_ERR_NO_ERROR }, { "(7:sig-val(3:dsa" "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64" "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)" "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d" "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))", GPG_ERR_SEXP_UNMATCHED_PAREN }, { "(7:sig-val(3:dsa" "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64" "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)" "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d" "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))))", GPG_ERR_SEXP_UNMATCHED_PAREN }, { NULL, 0 } }; int idx; gcry_error_t err; gcry_sexp_t s; info ("checking gcry_sexp_sscan\n"); for (idx=0; values[idx].text; idx++) { err = gcry_sexp_sscan (&s, NULL, values[idx].text, strlen (values[idx].text)); if (gpg_err_code (err) != values[idx].expected_err) fail ("gcry_sexp_sscan test %d failed: %s\n", idx, gpg_strerror (err)); gcry_sexp_release (s); } } int main (int argc, char **argv) { if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); basic (); canon_len (); back_and_forth (); check_sscan (); return error_count? 1:0; } diff --git a/tests/version.c b/tests/version.c index af3c4c38..1332c7c7 100644 --- a/tests/version.c +++ b/tests/version.c @@ -1,60 +1,60 @@ /* version.c - This version test should be run first. Copyright (C) 2007 Free Software Foundation, Inc. This file is part of Libgcrypt. Libgcrypt is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. Libgcrypt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* This test should be run first because due to a failing config.links script or bad configure parameters the just build libgcrypt may crash in case MPI function for specific CPU revisions have been enabled. Running this test first will print out information so to make it easier to figure out the problem. */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" #define PGM "version" int main (int argc, char **argv) { (void)argc; (void)argv; gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (strcmp (GCRYPT_VERSION, gcry_check_version (NULL))) { int oops = !gcry_check_version (GCRYPT_VERSION); fprintf (stderr, PGM ": %sversion mismatch; pgm=%s, library=%s\n", oops? "":"warning: ", GCRYPT_VERSION, gcry_check_version (NULL)); if (oops) exit (1); } gcry_control (GCRYCTL_PRINT_CONFIG, NULL); return 0; }