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;
}