Import gcrypt public-key cryptography and implement signature checking.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-01-11 21:32:42 +01:00
parent 535714bdcf
commit 5e3b8dcbb5
238 changed files with 40500 additions and 417 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,143 @@
# Makefile.am - for gcrypt/src
# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
# 2006, 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 General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
## 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
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 \
cipher.h cipher-proto.h gcrypt-module.h \
misc.c global.c sexp.c hwfeatures.c \
stdmem.c stdmem.h secmem.c secmem.h \
mpi.h missing-string.c module.c fips.c \
hmac256.c hmac256.h \
ath.h ath.c
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) $(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 = \
../cipher/libcipher.la \
../random/librandom.la \
../mpi/libmpi.la \
../compat/libcompat.la \
$(srcdir)/libgcrypt.vers $(gcrypt_deps)
libgcrypt_la_LIBADD = $(gcrypt_res) \
../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

View file

@ -0,0 +1,58 @@
# Manifest - checksums of the src directory
# Copyright 2004 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
# Checksums for all source files in this directory. Format is
# filename, blanks, base-64 part of an OpenPGP detached signature
# without the header lines. Blank lines and lines beginning with a
# hash mark are ignored. A tool to process this file is available by
# cvs -d :pserver:anoncvs@cvs.gnupg.org:/cvs/wk co misc-scripts/manifest-tool
#
# The special entry "$names$" holds a signature over all sorted
# filenames excluding itself.
gcrypt.h iQCVAwUAQH5RsTEAnp832S/7AQK7xgP+Kc3NY9lipZkaAMrnHDkQVLdHYwTbZWuGOYdTLp8Xy7Auh9wtWV9hrWVUqs+kxDzT/2iF6XkO3WT3rf/PmQ/Q0TIGfOyjE3c/qvB/jVippaxoGda3tnGpODytdI3XPhfPS0Ss8nDzfCStPBGAEq0OVU7imnExrFzhRXt+Gljr0o0==Yagz
gcrypt-module.h iQCVAwUAQH5UXzEAnp832S/7AQJMQgQAzumz9aaZelhw+FxTCeVadphBxt1bbNQvMrnddYYblyJv+AcxZ9ZxGz2oPeusN58Qg54DQcaW3lYhTgnWfXultsi+Ruxlz7400OUrzSXOl3At7KssdODAoscFzZIgh94G9lzQxEBr9lTXI9R3LsPFJP6muNG4frcNBAA42yckK7w==BBp5
ath.c iQCVAwUAQH5E+DEAnp832S/7AQKFpgP+KSZHtVcnh9FFggIyHKbALUljW2FXauasZvFyN8Sk/mIMgKxyXFOG1THBAUzWLaKWIEWU+WkYU7uThqBtpnEImM5AenWzbQuJjftPC3gVHO8yjjmBWD4zmJj28htoKDoa/xDsoqumrHxae3FYcaCWtYGVjM/Pbl+OMRMOFAhp0ho==lQZ3
ath.h iQCVAwUAQH5FODEAnp832S/7AQKiuQQAg4K+KOAn1LWBZN32MAhms4FeZKoce0fAuZW7BpyY4cCxIVgxqrtUC90CDykw8XegFfOyyYrgd0NmaMVdY7HZDncNOvIPxpgFQPCZrycsMOoAtoVwjK704RDeNo3zmeyxTKeDH+3M1J7JmLiafaEdSbOC8flX/W0icaV0Ol4dmBc==Ll6w
cipher.h iQCVAwUAQH5FUzEAnp832S/7AQJKLgP9GSSk9f7EINIRqSQH1XKX+dYzt3phDHdqFTUGIfYNh7YzGdy0drvgFhG4k15nqDouKRuFVM/hKY3ZVY7JccmKXKGAH6+ZYShoG6LMFfIGgDX8zne0dNxc72PLfns3fVxNn/RlHmHBkrQ+ppjR9HnSthFmOqzbQaW1BKmc3Z2x5GU==lIeW
g10lib.h iQCVAwUAQH5FejEAnp832S/7AQJ75wP/ZjOybwRix5eoXdfVeXPjoPygejzpYJJdMUGN3Y5UtkfBu9mPREsKfvZ6tH+Evjx+3xfeAb4bU/k2mRMp0tiWnk2koToS08vI9uxnioKQr9oulZH6r28S+NLSgMQuEGN1JNUky6RQ9TTNRndeTjKKSrEjZ7V6bv+rb8A1bYCKChs==P5mk
mpi.h iQCVAwUAQH5FwzEAnp832S/7AQJJ4wP9E3jVkcO9M0YtSBHIbjG3hDWKWXzi86AlUh51qiE8/2XP0FfjA4TosyvmicZs7j48HitAByr9tHOSxnbeo7NBf17ICwAo6Eqty+wKDg+eyLeEGUy7VpVK3RJRQAA4H+kl3S2l3YMTKf3WJlbc7qkWSXZspdy5c9sAxeodCKrAubU==oALf
global.c iQCVAwUAQH5HFzEAnp832S/7AQJc+QQAvi53ZkMCzLnVULHvhI6W+EX537zi9n8cplYguvIJqUhAZrP68yGAIyqyCONbZVDyB7wqeXdUMLzMk7W8fg+xuk5JSDpppAQf2m/bdQyze6XVqJso682eYBM8+b9z/IVEvLaFwhZcOKO1bcXudBlBCcJgVDpupfTtAWgPnewil9Q==Xwy1
misc.c iQCVAwUAQH5IIjEAnp832S/7AQKNJAQAkEpyY3fCG7tvADJFAW9xA7DEQwLCa8YmiUhHvrEsWOI4YgvS7LUbWWc7VqK+ryORvXLKRAVieznbnHAuy0TKtqdnmA/kUmiurS0ah5SWqR/iuAeJtt0RGsmZaZ6oa2m4PZ2Y2GCHSTZqcclvwsetS9eq5AipxHxYFUltu5wGZNI==twM2
missing-string.c iQCVAwUAQH5JfjEAnp832S/7AQI3ZQQAg55eEJbGQQHyBEJGxvt/FXpQiXcoDit3ZHzvdaQn/NUgdLjCHiWVzhyCXACGivLWMNModDaSaZk073NXxVkWfPcX9vkF//Wugwzidd5P3Bfu5k35o+Xxz82fsk5KuFGGq1mBUZ07xUYQ8KkKkhADUkr0QiQAuypp079Yq0uUC7Q==zvKn
module.c iQCVAwUAQH5JvjEAnp832S/7AQKlMgQAjZYTXMpWb5kHxCMXzRi069Ku/4/xnWsD+S0dje1LiKzCnRpwTTxARzc/y10Y8OcygkMuR4unEaWedO+9syjjty3fBCcue/j7YlLitq5EC9UE4o23poWvWCuX9Tadm2DK5qf4p7smMJ22O22cLTYTVCyAoYTQ2xC8ajzBsBRkX80==yRRD
secmem.c iQCVAwUAQH5LLDEAnp832S/7AQKtFwQAwY2wBr6WJC1cwqp/1DQoKzHx9C3plONxbZMazwR7VMI83NUbBAbv1mcxpeZWXmb2dRrnsR1VBbNPDSbJLN5T6czLQ2nIb6mnq9u8Ip4SAa+GCWfDV4AUtAJ4hN/yvWo8iEKu+KD5iJ6xJh31NdXjt5yk6vnk46SA6R4FkHdIEXc==UKVr
secmem.h iQCVAwUAQH5LTDEAnp832S/7AQIsJwQAkZUu4hvmh9NXCLNm98+tGZFzWYvZO/NffC2wdPE8Q/OTa/m3g+oBbEhaV1ze3oY4t1F/p7ZHFx5CsIp4zVjyPkxlni8AAVMUOQr/LopyxouHn2OjKO+dVqecWQf01+nPWjklbL2FZ3mQ99k2qeWZlVSkz0nm8u39F3v7z3OTCss==AJqE
sexp.c iQCVAwUAQH5LojEAnp832S/7AQKCTQQArlrj1KGwR2x93fcyN3M0iXuGkBq5R9KNu+1Bq04G4SLlpZ1RRY0OjV3L9To1BHTd01lXlO8MNz7NpRxWlG1Sw5FohbBlhWZQRcW8GdAawJPcfIY2Y8Ek6Yx8quZKbk9uD3bcBmStmg0P+TIA0nr20bmtfB3uX2KQVHQqWZQT5qU==P8FE
stdmem.c iQCVAwUAQH5LzjEAnp832S/7AQLOUAP9FU16itXBBrkfRDGmhUjAOeEEKdd+brQ3XdT8xoLvP/IH/6U1Kq3ampP2/xcL4kwVdz2rw6NRzP7jlL/yM3tW722lSS/JPJkH+2+qUkcb0fYNoql/WYPMYp1/Mzu6ttXnjag1cQGlKIyYAD+G6h3FtpLwQy0hEJopnF9+Ovd8U7A==CkiZ
stdmem.h iQCVAwUAQH5L8jEAnp832S/7AQIH0wP+Lyqh0tj++s2L79Tmf/gqgCK+HLMxTddcewF3XbsYf9T5FmLez1gz6Ggti4Ss9VjozOA3ti3trCiA/YNRmV9AYw4zLUPm+MsjJuveL/AgB9HdoD2v+RfJm0WwgSKiysp+8iyjg3Plopmhba4cGuOP5MJ3CWTqYwPmJVscUKC6g38==02MN
types.h iQCVAwUAQH5MKTEAnp832S/7AQLqTAP6A3mUMD5MMkBkebq4bRY6Bq0KsgdKfZ8TLhc2o87gFay8YD0Uom3YJNG2LF/rAIct2ih4jYJaIb5dRfJ0KJoPi2ETd462J8OFCL4fjq9TaSjB2pXcB+kWoxzPasGNg2Ukk0dQ6lvF1tSYrtt32PVI7q/UaPsjTylgRmzLfX/VxrU==OMu3
# Configuration
Makefile.am iQCVAwUAQH5WVjEAnp832S/7AQLmsQP/bbI8/UWAC5yITVhGcCOCbN/FaMqXVKjxESzo6GTs02jxK1y3RuuaoNU1ssQZGAxpFiMJW8u933V3yTHFMxWpwHemDnEyv/a8YACxJBQ0tQgpgHS716BjMbHOfcuOis2WlCOOm0ErjhAYNa4NQ1q3jwkOvTDLFpdnqaWI2wWn08U==Yjun
libgcrypt.m4 iQCVAwUAQH5MbTEAnp832S/7AQJ1uAQA1C6xI7qXiKVtUeXawhPytAldosrzcXmqz34xi7JklQqw83d68WtWHFMBEUa7MKfi4WCbuQb7FjGUvMRw5z/T9ez7CoDekHc63+cIIZLQ23weUK8GaA1uQLoD0scmT41J5RkBlJbH7ck1zRd3d04o75rWNEUNit6KBvrQ4Pd8oQ8==uMgB
libgcrypt-config.in iQCVAwUAQH5UbzEAnp832S/7AQJISgP+Nbd2AQnDM/k8sQLbvz8YZjwX3LigZM+AkF1VAwyAm6YOU3nrXnz5t+cXkQD2dkz4L2F0AAsIkFiJsrgmZgCp2h1L6LeFnH+hoId9RhbYw4NkDaHb+MC9JcalpcfFvvxq6vM/W37bSFimM78P+5RLKypXCytVQNAAaIRgZjVfXY8==IGDS
libgcrypt.vers iQCVAwUAQH5MjTEAnp832S/7AQKCdQQAotG6Z3zdcePI0V33YY2sh91uYkLBNhQw+PzyE3BRRAVhMGLOBD1nSWJHJvE3eyCVOqFY0ZmvpVex51Fa0D/TwsJOO4RVxf1L9bbAncu9OuEXaGXKytLZp54TliDTAWGDq0lvtx1TvDDgtM8TbbaXvMbjfQ4wXBxdLvaenFCTlR4==kgHq
$names$ iQCVAwUAQH5UhDEAnp832S/7AQK/jwP9H7A3mI99M1NGuhD+16C+2gJIITB8GJeYeUd3vm8kWQ5n76WyMCdeA62qn0JUddIBjAbagtfvTL5aesnD9MlhEGaNlHauU7SINTIJ8njKf87EAAfDZrhS/tGDziC2nakMPweRxXQCLDWHkBPjYfrspSLLohjdegqBvTNyVM76+KE==3p9Z

View file

@ -0,0 +1,323 @@
/* ath.c - A Thread-safeness library.
* Copyright (C) 2002, 2003, 2004, 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 <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#if USE_POSIX_THREADS_WEAK
# include <pthread.h>
#endif
#include "ath.h"
/* On an ELF system it is easy to use pthreads using weak references.
Take care not to test the address of a weak referenced function we
actually use; some GCC versions have a bug were &foo != NULL is
always evaluated to true in PIC mode. USING_PTHREAD_AS_DEFAULT is
used by ath_install to detect the default usage of pthread. */
#if USE_POSIX_THREADS_WEAK
# pragma weak pthread_cancel
# pragma weak pthread_mutex_init
# pragma weak pthread_mutex_lock
# pragma weak pthread_mutex_unlock
# pragma weak pthread_mutex_destroy
#endif
/* For the dummy interface. The MUTEX_NOTINIT value is used to check
that a mutex has been initialized. Because its value is there is
no need to explicit initialized a mutex variable because it is
anyway static and we store a pointer to allocated memory there
after initialization. The same thing works with other thread
models. */
#define MUTEX_NOTINIT ((ath_mutex_t) 0)
#define MUTEX_UNLOCKED ((ath_mutex_t) 1)
#define MUTEX_LOCKED ((ath_mutex_t) 2)
#define MUTEX_DESTROYED ((ath_mutex_t) 3)
/* Return the thread type from the option field. */
#define GET_OPTION(a) ((a) & 0xff)
enum ath_thread_model {
ath_model_undefined = 0,
ath_model_none, /* No thread support. */
ath_model_pthreads_weak, /* POSIX threads using weak symbols. */
ath_model_pthreads, /* POSIX threads directly linked. */
ath_model_w32 /* Microsoft Windows threads. */
};
/* The thread model in use. */
static enum ath_thread_model thread_model;
/* Initialize the ath subsystem. This is called as part of the
Libgcrypt initialization. It's purpose is to initialize the
locking system. It returns 0 on sucess or an ERRNO value on error.
In the latter case it is not defined whether ERRNO was changed.
Note: This should be called as early as possible because it is not
always possible to detect the thread model to use while already
running multi threaded. */
int
ath_init (void)
{
int err = 0;
if (thread_model)
return 0; /* Already initialized - no error. */
if (0)
;
#if USE_POSIX_THREADS_WEAK
else if (pthread_cancel)
{
thread_model = ath_model_pthreads_weak;
}
#endif
else
{
/* Assume a single threaded application. */
thread_model = ath_model_none;
}
return err;
}
/* Return the used thread model as string for display purposes an if
R_MODEL is not null store its internal number at R_MODEL. */
const char *
ath_get_model (int *r_model)
{
if (r_model)
*r_model = thread_model;
switch (thread_model)
{
case ath_model_undefined: return "undefined";
case ath_model_none: return "none";
case ath_model_pthreads_weak: return "pthread(weak)";
case ath_model_pthreads: return "pthread";
case ath_model_w32: return "w32";
default: return "?";
}
}
/* This function was used in old Libgcrypt versions (via
GCRYCTL_SET_THREAD_CBS) to register the thread callback functions.
It is not anymore required. However to allow existing code to
continue to work, we keep this function and check that no user
defined callbacks are used and that the requested thread system
matches the one Libgcrypt is using. */
gpg_err_code_t
ath_install (struct ath_ops *ath_ops)
{
unsigned int thread_option;
/* Check if the requested thread option is compatible to the
thread option we are already committed to. */
thread_option = ath_ops? GET_OPTION (ath_ops->option) : 0;
/* Return an error if the requested thread model does not match the
configured one. */
if (0)
;
#if USE_POSIX_THREADS_WEAK
else if (thread_model == ath_model_pthreads_weak)
{
if (thread_option == ATH_THREAD_OPTION_PTHREAD)
return 0; /* Okay - compatible. */
}
#endif /*USE_POSIX_THREADS_WEAK*/
else if (thread_option == ATH_THREAD_OPTION_DEFAULT)
return 0; /* No thread support requested. */
return GPG_ERR_NOT_SUPPORTED;
}
/* Initialize a new mutex. This function returns 0 on success or an
system error code (i.e. an ERRNO value). ERRNO may or may not be
changed on error. */
int
ath_mutex_init (ath_mutex_t *lock)
{
int err;
switch (thread_model)
{
case ath_model_none:
*lock = MUTEX_UNLOCKED;
err = 0;
break;
#if USE_POSIX_THREADS_WEAK
case ath_model_pthreads_weak:
{
pthread_mutex_t *plck;
plck = malloc (sizeof *plck);
if (!plck)
err = errno? errno : ENOMEM;
else
{
err = pthread_mutex_init (plck, NULL);
if (err)
free (plck);
else
*lock = (void*)plck;
}
}
break;
#endif /*USE_POSIX_THREADS_WEAK*/
default:
err = EINVAL;
break;
}
return err;
}
/* Destroy a mutex. This function is a NOP if LOCK is NULL. If the
mutex is still locked it can't be destroyed and the function
returns EBUSY. ERRNO may or may not be changed on error. */
int
ath_mutex_destroy (ath_mutex_t *lock)
{
int err;
if (!*lock)
return 0;
switch (thread_model)
{
case ath_model_none:
if (*lock != MUTEX_UNLOCKED)
err = EBUSY;
else
{
*lock = MUTEX_DESTROYED;
err = 0;
}
break;
#if USE_POSIX_THREADS_WEAK
case ath_model_pthreads_weak:
{
pthread_mutex_t *plck = (pthread_mutex_t*)lock;
err = pthread_mutex_destroy (plck);
if (!err)
{
free (plck);
lock = NULL;
}
}
break;
#endif /*USE_POSIX_THREADS_WEAK*/
default:
err = EINVAL;
break;
}
return err;
}
/* Lock the mutex LOCK. On success the function returns 0; on error
an error code. ERRNO may or may not be changed on error. */
int
ath_mutex_lock (ath_mutex_t *lock)
{
int err;
switch (thread_model)
{
case ath_model_none:
if (*lock == MUTEX_NOTINIT)
err = EINVAL;
else if (*lock == MUTEX_UNLOCKED)
{
*lock = MUTEX_LOCKED;
err = 0;
}
else
err = EDEADLK;
break;
#if USE_POSIX_THREADS_WEAK
case ath_model_pthreads_weak:
err = pthread_mutex_lock ((pthread_mutex_t*)lock);
break;
#endif /*USE_POSIX_THREADS_WEAK*/
default:
err = EINVAL;
break;
}
return err;
}
/* Unlock the mutex LOCK. On success the function returns 0; on error
an error code. ERRNO may or may not be changed on error. */
int
ath_mutex_unlock (ath_mutex_t *lock)
{
int err;
switch (thread_model)
{
case ath_model_none:
if (*lock == MUTEX_NOTINIT)
err = EINVAL;
else if (*lock == MUTEX_LOCKED)
{
*lock = MUTEX_UNLOCKED;
err = 0;
}
else
err = EPERM;
break;
#if USE_POSIX_THREADS_WEAK
case ath_model_pthreads_weak:
err = pthread_mutex_unlock ((pthread_mutex_t*)lock);
break;
#endif /*USE_POSIX_THREADS_WEAK*/
default:
err = EINVAL;
break;
}
return err;
}

View file

@ -0,0 +1,92 @@
/* ath.h - Thread-safeness library.
* Copyright (C) 2002, 2003, 2004, 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 <http://www.gnu.org/licenses/>.
*/
#ifndef ATH_H
#define ATH_H
#include <config.h>
#ifdef _WIN32
# include <windows.h>
#else /* !_WIN32 */
# ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
# else
# include <sys/time.h>
# endif
# include <sys/types.h>
# ifdef HAVE_SYS_MSG_H
# include <sys/msg.h> /* (e.g. for zOS) */
# endif
# include <sys/socket.h>
#endif /* !_WIN32 */
#include <gpg-error.h>
/* Define _ATH_EXT_SYM_PREFIX if you want to give all external symbols
a prefix. */
#define _ATH_EXT_SYM_PREFIX _gcry_
#ifdef _ATH_EXT_SYM_PREFIX
#define _ATH_PREFIX1(x,y) x ## y
#define _ATH_PREFIX2(x,y) _ATH_PREFIX1(x,y)
#define _ATH_PREFIX(x) _ATH_PREFIX2(_ATH_EXT_SYM_PREFIX,x)
#define ath_install _ATH_PREFIX(ath_install)
#define ath_init _ATH_PREFIX(ath_init)
#define ath_get_model _ATH_PREFIX(ath_get_model)
#define ath_mutex_init _ATH_PREFIX(ath_mutex_init)
#define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy)
#define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock)
#define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock)
#endif
enum ath_thread_option
{
ATH_THREAD_OPTION_DEFAULT = 0,
ATH_THREAD_OPTION_USER = 1,
ATH_THREAD_OPTION_PTH = 2,
ATH_THREAD_OPTION_PTHREAD = 3
};
struct ath_ops
{
/* The OPTION field encodes the thread model and the version number
of this structure.
Bits 7 - 0 are used for the thread model
Bits 15 - 8 are used for the version number.
*/
unsigned int option;
};
gpg_err_code_t ath_install (struct ath_ops *ath_ops);
int ath_init (void);
const char *ath_get_model (int *r_model);
/* Functions for mutual exclusion. */
typedef void *ath_mutex_t;
int ath_mutex_init (ath_mutex_t *mutex);
int ath_mutex_destroy (ath_mutex_t *mutex);
int ath_mutex_lock (ath_mutex_t *mutex);
int ath_mutex_unlock (ath_mutex_t *mutex);
#endif /* ATH_H */

View file

@ -0,0 +1,124 @@
/* cipher-proto.h - Internal declarations
* Copyright (C) 2008, 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 <http://www.gnu.org/licenses/>.
*/
/* This file has been factored out from cipher.h so that it can be
used standalone in visibility.c . */
#ifndef G10_CIPHER_PROTO_H
#define G10_CIPHER_PROTO_H
/* Definition of a function used to report selftest failures.
DOMAIN is a string describing the function block:
"cipher", "digest", "pubkey or "random",
ALGO is the algorithm under test,
WHAT is a string describing what has been tested,
DESC is a string describing the error. */
typedef void (*selftest_report_func_t)(const char *domain,
int algo,
const char *what,
const char *errdesc);
/* Definition of the selftest functions. */
typedef gpg_err_code_t (*selftest_func_t)
(int algo, int extended, selftest_report_func_t report);
/* An extended type of the generate function. */
typedef gcry_err_code_t (*pk_ext_generate_t)
(int algo,
unsigned int nbits,
unsigned long evalue,
gcry_sexp_t genparms,
gcry_mpi_t *skey,
gcry_mpi_t **retfactors,
gcry_sexp_t *extrainfo);
/* The type used to compute the keygrip. */
typedef gpg_err_code_t (*pk_comp_keygrip_t)
(gcry_md_hd_t md, gcry_sexp_t keyparm);
/* The type used to query ECC curve parameters. */
typedef gcry_err_code_t (*pk_get_param_t)
(const char *name, gcry_mpi_t *pkey);
/* The type used to query an ECC curve name. */
typedef const char *(*pk_get_curve_t)(gcry_mpi_t *pkey, int iterator,
unsigned int *r_nbits);
/* The type used to query ECC curve parameters by name. */
typedef gcry_sexp_t (*pk_get_curve_param_t)(const char *name);
/* The type used to convey additional information to a cipher. */
typedef gpg_err_code_t (*cipher_set_extra_info_t)
(void *c, int what, const void *buffer, size_t buflen);
/* Extra module specification structures. These are used for internal
modules which provide more functions than available through the
public algorithm register APIs. */
typedef struct cipher_extra_spec
{
selftest_func_t selftest;
cipher_set_extra_info_t set_extra_info;
} cipher_extra_spec_t;
typedef struct md_extra_spec
{
selftest_func_t selftest;
} md_extra_spec_t;
typedef struct pk_extra_spec
{
selftest_func_t selftest;
pk_ext_generate_t ext_generate;
pk_comp_keygrip_t comp_keygrip;
pk_get_param_t get_param;
pk_get_curve_t get_curve;
pk_get_curve_param_t get_curve_param;
} pk_extra_spec_t;
/* The private register functions. */
gcry_error_t _gcry_cipher_register (gcry_cipher_spec_t *cipher,
cipher_extra_spec_t *extraspec,
int *algorithm_id,
gcry_module_t *module);
gcry_error_t _gcry_md_register (gcry_md_spec_t *cipher,
md_extra_spec_t *extraspec,
unsigned int *algorithm_id,
gcry_module_t *module);
gcry_error_t _gcry_pk_register (gcry_pk_spec_t *cipher,
pk_extra_spec_t *extraspec,
unsigned int *algorithm_id,
gcry_module_t *module);
/* The selftest functions. */
gcry_error_t _gcry_cipher_selftest (int algo, int extended,
selftest_report_func_t report);
gcry_error_t _gcry_md_selftest (int algo, int extended,
selftest_report_func_t report);
gcry_error_t _gcry_pk_selftest (int algo, int extended,
selftest_report_func_t report);
gcry_error_t _gcry_hmac_selftest (int algo, int extended,
selftest_report_func_t report);
gcry_error_t _gcry_random_selftest (selftest_report_func_t report);
#endif /*G10_CIPHER_PROTO_H*/

View file

@ -0,0 +1,181 @@
/* 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 <gcrypt.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);
/*-- 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 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*/

View file

@ -0,0 +1,766 @@
/* dumpsexp.c - Dump S-expressions.
* Copyright (C) 2007, 2010 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 3 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, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdarg.h>
#include <errno.h>
/* For a native WindowsCE binary we need to include gpg-error.h to
provide a replacement for strerror. */
#ifdef __MINGW32CE__
# include <gpg-error.h>
#endif
#define PGM "dumpsexp"
#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
static int verbose; /* Verbose mode. */
static int decimal; /* Print addresses in decimal. */
static int assume_hex; /* Assume input is hexencoded. */
static int advanced; /* Advanced format output. */
static void
print_version (int with_help)
{
fputs (MYVERSION_LINE "\n"
"Copyright (C) 2010 Free Software Foundation, Inc.\n"
"License GPLv3+: GNU GPL version 3 or later "
"<http://gnu.org/licenses/gpl.html>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n",
stdout);
if (with_help)
fputs ("\n"
"Usage: " PGM " [OPTIONS] [file]\n"
"Debug tool for S-expressions\n"
"\n"
" --decimal Print offsets using decimal notation\n"
" --assume-hex Assume input is a hex dump\n"
" --advanced Print file in advanced format\n"
" --verbose Show what we are doing\n"
" --version Print version of the program and exit\n"
" --help Display this help and exit\n"
BUGREPORT_LINE, stdout );
exit (0);
}
static int
print_usage (void)
{
fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr);
fputs (" (use --help to display options)\n", stderr);
exit (1);
}
#define space_p(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t')
#define digit_p(a) ((a) >= '0' && (a) <= '9')
#define octdigit_p(a) ((a) >= '0' && (a) <= '7')
#define alpha_p(a) ( ((a) >= 'A' && (a) <= 'Z') \
|| ((a) >= 'a' && (a) <= 'z'))
#define hexdigit_p(a) (digit_p (a) \
|| ((a) >= 'A' && (a) <= 'F') \
|| ((a) >= 'a' && (a) <= 'f'))
#define xtoi_1(a) ((a) <= '9'? ((a)- '0'): \
(a) <= 'F'? ((a)-'A'+10):((a)-'a'+10))
/* Return true if P points to a byte containing a whitespace according
to the S-expressions definition. */
static inline int
whitespace_p (int c)
{
switch (c)
{
case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1;
default: return 0;
}
}
static void
logit (const char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format) ;
fputs (PGM ": ", stderr);
vfprintf (stderr, format, arg_ptr);
putc ('\n', stderr);
va_end (arg_ptr);
}
/* The raw data buffer and its current length */
static unsigned char databuffer[16];
static int databufferlen;
/* The number of bytes in databuffer which should be skipped at a flush. */
static int skipdatabufferlen;
/* The number of raw bytes printed on the last line. */
static int nbytesprinted;
/* The file offset of the current data buffer . */
static unsigned long databufferoffset;
static int
my_getc (FILE *fp)
{
int c1, c2;
if (!assume_hex)
return getc (fp);
while ( (c1=getc (fp)) != EOF && space_p (c1) )
;
if (c1 == EOF)
return EOF;
if (!hexdigit_p (c1))
{
logit ("non hex-digit encountered\n");
return EOF;
}
while ( (c2=getc (fp)) != EOF && space_p (c2) )
;
if (c2 == EOF)
{
logit ("error reading second hex nibble\n");
return EOF;
}
if (!hexdigit_p (c2))
{
logit ("second hex nibble is not a hex-digit\n");
return EOF;
}
return xtoi_1 (c1) * 16 + xtoi_1 (c2);
}
/* Flush the raw data buffer. */
static void
flushdatabuffer (void)
{
int i;
if (!databufferlen)
return;
nbytesprinted = 0;
if (decimal)
printf ("%08lu ", databufferoffset);
else
printf ("%08lx ", databufferoffset);
for (i=0; i < databufferlen; i++)
{
if (i == 8)
putchar (' ');
if (i < skipdatabufferlen)
fputs (" ", stdout);
else
{
printf (" %02x", databuffer[i]);
databufferoffset++;
}
nbytesprinted++;
}
for (; i < sizeof (databuffer); i++)
{
if (i == 8)
putchar (' ');
fputs (" ", stdout);
}
fputs (" |", stdout);
for (i=0; i < databufferlen; i++)
{
if (i < skipdatabufferlen)
putchar (' ');
else if (databuffer[i] >= ' ' && databuffer[i] <= '~'
&& databuffer[i] != '|')
putchar (databuffer[i]);
else
putchar ('.');
}
putchar ('|');
putchar ('\n');
databufferlen = 0;
skipdatabufferlen = 0;
}
/* Add C to the raw data buffer and flush as needed. */
static void
addrawdata (int c)
{
if ( databufferlen >= sizeof databuffer )
flushdatabuffer ();
databuffer[databufferlen++] = c;
}
static void
printcursor (int both)
{
int i;
flushdatabuffer ();
printf ("%8s ", "");
for (i=0; i < sizeof (databuffer); i++)
{
if (i == 8)
putchar (' ');
if (i+1 == nbytesprinted)
{
fputs (" ^ ", stdout);
if (!both)
break;
}
else
fputs (" ", stdout);
}
if (both)
{
fputs (" ", stdout);
for (i=0; i < nbytesprinted-1; i++)
putchar (' ');
putchar ('^');
}
databufferlen = skipdatabufferlen = nbytesprinted;
}
static void
printerr (const char *text)
{
printcursor (1);
printf ("\n Error: %s\n", text);
}
static void
printctl (const char *text)
{
if (verbose && !advanced)
{
printcursor (0);
printf ("%s\n", text);
}
}
static void
printchr (int c)
{
putchar (c);
}
/* static void */
/* printhex (int c) */
/* { */
/* printf ("\\x%02x", c); */
/* } */
#if 0
/****************
* Print SEXP to buffer using the MODE. Returns the length of the
* SEXP in buffer or 0 if the buffer is too short (We have at least an
* empty list consisting of 2 bytes). If a buffer of NULL is provided,
* the required length is returned.
*/
size_t
gcry_sexp_sprint (const gcry_sexp_t list,
void *buffer, size_t maxlength )
{
static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
const unsigned char *s;
char *d;
DATALEN n;
char numbuf[20];
int i, indent = 0;
s = list? list->d : empty;
d = buffer;
while ( *s != ST_STOP )
{
switch ( *s )
{
case ST_OPEN:
s++;
if (indent)
putchar ('\n');
for (i=0; i < indent; i++)
putchar (' ');
putchar ('(');
indent++;
break;
case ST_CLOSE:
s++;
putchar (')');
indent--;
if (*s != ST_OPEN && *s != ST_STOP)
{
putchar ('\n');
for (i=0; i < indent; i++)
putchar (' ');
}
break;
case ST_DATA:
s++;
memcpy (&n, s, sizeof n);
s += sizeof n;
{
int type;
size_t nn;
switch ( (type=suitable_encoding (s, n)))
{
case 1: nn = convert_to_string (s, n, NULL); break;
case 2: nn = convert_to_token (s, n, NULL); break;
default: nn = convert_to_hex (s, n, NULL); break;
}
switch (type)
{
case 1: convert_to_string (s, n, d); break;
case 2: convert_to_token (s, n, d); break;
default: convert_to_hex (s, n, d); break;
}
d += nn;
if (s[n] != ST_CLOSE)
putchar (' ');
}
else
{
snprintf (numbuf, sizeof numbuf, "%u:", (unsigned int)n );
d = stpcpy (d, numbuf);
memcpy (d, s, n);
d += n;
}
s += n;
break;
default:
BUG ();
}
}
putchar ('\n');
return len;
}
#endif
/* Prepare for saving a chunk of data. */
static void
init_data (void)
{
}
/* Push C on the current data chunk. */
static void
push_data (int c)
{
(void)c;
}
/* Flush and thus print the current data chunk. */
static void
flush_data (void)
{
}
/* Returns 0 on success. */
static int
parse_and_print (FILE *fp)
{
static const char tokenchars[] =
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789-./_:*+=";
int c;
int level = 0;
int tokenc = 0;
int hexcount = 0;
int disphint = 0;
unsigned long datalen = 0;
char quote_buf[10];
int quote_idx = 0;
enum
{
INIT_STATE = 0, IN_NUMBER, PRE_DATA, IN_DATA, IN_STRING,
IN_ESCAPE, IN_OCT_ESC, IN_HEX_ESC,
CR_ESC, LF_ESC, IN_HEXFMT, IN_BASE64
}
state = INIT_STATE;
while ((c = my_getc (fp)) != EOF )
{
addrawdata (c);
switch (state)
{
case INIT_STATE:
if (tokenc)
{
if (strchr (tokenchars, c))
{
printchr (c);
continue;
}
tokenc = 0;
}
parse_init_state:
if (c == '(')
{
if (disphint)
{
printerr ("unmatched display hint");
disphint = 0;
}
printctl ("open");
level++;
}
else if (c == ')')
{
if (disphint)
{
printerr ("unmatched display hint");
disphint = 0;
}
printctl ("close");
level--;
}
else if (c == '\"')
{
state = IN_STRING;
printctl ("beginstring");
init_data ();
}
else if (c == '#')
{
state = IN_HEXFMT;
hexcount = 0;
printctl ("beginhex");
init_data ();
}
else if (c == '|')
{
state = IN_BASE64;
printctl ("beginbase64");
init_data ();
}
else if (c == '[')
{
if (disphint)
printerr ("nested display hint");
disphint = c;
}
else if (c == ']')
{
if (!disphint)
printerr ("no open display hint");
disphint = 0;
}
else if (c >= '0' && c <= '9')
{
if (c == '0')
printerr ("zero prefixed length");
state = IN_NUMBER;
datalen = (c - '0');
}
else if (strchr (tokenchars, c))
{
printchr (c);
tokenc = c;
}
else if (whitespace_p (c))
;
else if (c == '{')
{
printerr ("rescanning is not supported");
}
else if (c == '&' || c == '\\')
{
printerr ("reserved punctuation detected");
}
else
{
printerr ("bad character detected");
}
break;
case IN_NUMBER:
if (digit_p (c))
{
unsigned long tmp = datalen * 10 + (c - '0');
if (tmp < datalen)
{
printerr ("overflow in data length");
state = INIT_STATE;
datalen = 0;
}
else
datalen = tmp;
}
else if (c == ':')
{
if (!datalen)
{
printerr ("no data length");
state = INIT_STATE;
}
else
state = PRE_DATA;
}
else if (c == '\"' || c == '#' || c == '|' )
{
/* We ignore the optional length and divert to the init
state parser code. */
goto parse_init_state;
}
else
printerr ("invalid length specification");
break;
case PRE_DATA:
state = IN_DATA;
printctl ("begindata");
init_data ();
case IN_DATA:
if (datalen)
{
push_data (c);
datalen--;
}
if (!datalen)
{
state = INIT_STATE;
printctl ("enddata");
flush_data ();
}
break;
case IN_STRING:
if (c == '\"')
{
printctl ("endstring");
flush_data ();
state = INIT_STATE;
}
else if (c == '\\')
state = IN_ESCAPE;
else
push_data (c);
break;
case IN_ESCAPE:
switch (c)
{
case 'b': push_data ('\b'); state = IN_STRING; break;
case 't': push_data ('\t'); state = IN_STRING; break;
case 'v': push_data ('\v'); state = IN_STRING; break;
case 'n': push_data ('\n'); state = IN_STRING; break;
case 'f': push_data ('\f'); state = IN_STRING; break;
case 'r': push_data ('\r'); state = IN_STRING; break;
case '"': push_data ('"'); state = IN_STRING; break;
case '\'': push_data ('\''); state = IN_STRING; break;
case '\\': push_data ('\\'); state = IN_STRING; break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
state = IN_OCT_ESC;
quote_idx = 0;
quote_buf[quote_idx++] = c;
break;
case 'x':
state = IN_HEX_ESC;
quote_idx = 0;
break;
case '\r':
state = CR_ESC;
break;
case '\n':
state = LF_ESC;
break;
default:
printerr ("invalid escape sequence");
state = IN_STRING;
break;
}
break;
case IN_OCT_ESC:
if (quote_idx < 3 && strchr ("01234567", c))
{
quote_buf[quote_idx++] = c;
if (quote_idx == 3)
{
push_data ((unsigned int)quote_buf[0] * 8 * 8
+ (unsigned int)quote_buf[1] * 8
+ (unsigned int)quote_buf[2]);
state = IN_STRING;
}
}
else
state = IN_STRING;
break;
case IN_HEX_ESC:
if (quote_idx < 2 && strchr ("0123456789abcdefABCDEF", c))
{
quote_buf[quote_idx++] = c;
if (quote_idx == 2)
{
push_data (xtoi_1 (quote_buf[0]) * 16
+ xtoi_1 (quote_buf[1]));
state = IN_STRING;
}
}
else
state = IN_STRING;
break;
case CR_ESC:
state = IN_STRING;
break;
case LF_ESC:
state = IN_STRING;
break;
case IN_HEXFMT:
if (hexdigit_p (c))
{
push_data (c);
hexcount++;
}
else if (c == '#')
{
if ((hexcount & 1))
printerr ("odd number of hex digits");
printctl ("endhex");
flush_data ();
state = INIT_STATE;
}
else if (!whitespace_p (c))
printerr ("bad hex character");
break;
case IN_BASE64:
if (c == '|')
{
printctl ("endbase64");
flush_data ();
state = INIT_STATE;
}
else
push_data (c);
break;
default:
logit ("invalid state %d detected", state);
exit (1);
}
}
flushdatabuffer ();
if (ferror (fp))
{
logit ("error reading input: %s\n", strerror (errno));
return -1;
}
return 0;
}
int
main (int argc, char **argv)
{
int rc;
if (argc)
{
argc--; argv++;
}
while (argc && **argv == '-' && (*argv)[1] == '-')
{
if (!(*argv)[2])
{
argc--; argv++;
break;
}
else if (!strcmp (*argv, "--version"))
print_version (0);
else if (!strcmp (*argv, "--help"))
print_version (1);
else if (!strcmp (*argv, "--verbose"))
{
argc--; argv++;
verbose = 1;
}
else if (!strcmp (*argv, "--decimal"))
{
argc--; argv++;
decimal = 1;
}
else if (!strcmp (*argv, "--assume-hex"))
{
argc--; argv++;
assume_hex = 1;
}
else if (!strcmp (*argv, "--advanced"))
{
argc--; argv++;
advanced = 1;
}
else
print_usage ();
}
if (!argc)
{
rc = parse_and_print (stdin);
}
else
{
rc = 0;
for (; argc; argv++, argc--)
{
FILE *fp = fopen (*argv, "rb");
if (!fp)
{
logit ("can't open `%s': %s\n", *argv, strerror (errno));
rc = 1;
}
else
{
if (parse_and_print (fp))
rc = 1;
fclose (fp);
}
}
}
return !!rc;
}

View file

@ -0,0 +1,852 @@
/* fips.c - FIPS mode management
* 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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#ifdef ENABLE_HMAC_BINARY_CHECK
# include <dlfcn.h>
#endif
#ifdef HAVE_SYSLOG
# include <syslog.h>
#endif /*HAVE_SYSLOG*/
#include "g10lib.h"
#include "ath.h"
#include "cipher-proto.h"
#include "hmac256.h"
/* The name of the file used to foce libgcrypt into fips mode. */
#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled"
/* The states of the finite state machine used in fips mode. */
enum module_states
{
/* POWEROFF cannot be represented. */
STATE_POWERON = 0,
STATE_INIT,
STATE_SELFTEST,
STATE_OPERATIONAL,
STATE_ERROR,
STATE_FATALERROR,
STATE_SHUTDOWN
};
/* Flag telling whether we are in fips mode. It uses inverse logic so
that fips mode is the default unless changed by the initialization
code. To check whether fips mode is enabled, use the function
fips_mode()! */
static int no_fips_mode_required;
/* Flag to indicate that we are in the enforced FIPS mode. */
static int enforced_fips_mode;
/* If this flag is set, the application may no longer assume that the
process is running in FIPS mode. This flag is protected by the
FSM_LOCK. */
static int inactive_fips_mode;
/* This is the lock we use to protect the FSM. */
static ath_mutex_t fsm_lock;
/* The current state of the FSM. The whole state machinery is only
used while in fips mode. Change this only while holding fsm_lock. */
static enum module_states current_state;
static void fips_new_state (enum module_states new_state);
/* Convert lowercase hex digits; assumes valid hex digits. */
#define loxtoi_1(p) (*(p) <= '9'? (*(p)- '0'): (*(p)-'a'+10))
#define loxtoi_2(p) ((loxtoi_1(p) * 16) + loxtoi_1((p)+1))
/* Returns true if P points to a lowercase hex digit. */
#define loxdigit_p(p) !!strchr ("01234567890abcdef", *(p))
/* Check whether the OS is in FIPS mode and record that in a module
local variable. If FORCE is passed as true, fips mode will be
enabled anyway. Note: This function is not thread-safe and should
be called before any threads are created. This function may only
be called once. */
void
_gcry_initialize_fips_mode (int force)
{
static int done;
gpg_error_t err;
/* Make sure we are not accidently called twice. */
if (done)
{
if ( fips_mode () )
{
fips_new_state (STATE_FATALERROR);
fips_noreturn ();
}
/* If not in fips mode an assert is sufficient. */
gcry_assert (!done);
}
done = 1;
/* If the calling application explicitly requested fipsmode, do so. */
if (force)
{
gcry_assert (!no_fips_mode_required);
goto leave;
}
/* For testing the system it is useful to override the system
provided detection of the FIPS mode and force FIPS mode using a
file. The filename is hardwired so that there won't be any
confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is
actually used. The file itself may be empty. */
if ( !access (FIPS_FORCE_FILE, F_OK) )
{
gcry_assert (!no_fips_mode_required);
goto leave;
}
/* Checking based on /proc file properties. */
{
static const char procfname[] = "/proc/sys/crypto/fips_enabled";
FILE *fp;
int saved_errno;
fp = fopen (procfname, "r");
if (fp)
{
char line[256];
if (fgets (line, sizeof line, fp) && atoi (line))
{
/* System is in fips mode. */
fclose (fp);
gcry_assert (!no_fips_mode_required);
goto leave;
}
fclose (fp);
}
else if ((saved_errno = errno) != ENOENT
&& saved_errno != EACCES
&& !access ("/proc/version", F_OK) )
{
/* Problem reading the fips file despite that we have the proc
file system. We better stop right away. */
log_info ("FATAL: error reading `%s' in libgcrypt: %s\n",
procfname, strerror (saved_errno));
#ifdef HAVE_SYSLOG
syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
"reading `%s' failed: %s - abort",
procfname, strerror (saved_errno));
#endif /*HAVE_SYSLOG*/
abort ();
}
}
/* Fips not not requested, set flag. */
no_fips_mode_required = 1;
leave:
if (!no_fips_mode_required)
{
/* Yes, we are in FIPS mode. */
FILE *fp;
/* Intitialize the lock to protect the FSM. */
err = ath_mutex_init (&fsm_lock);
if (err)
{
/* If that fails we can't do anything but abort the
process. We need to use log_info so that the FSM won't
get involved. */
log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n",
strerror (err));
#ifdef HAVE_SYSLOG
syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
"creating FSM lock failed: %s - abort",
strerror (err));
#endif /*HAVE_SYSLOG*/
abort ();
}
/* If the FIPS force files exists, is readable and has a number
!= 0 on its first line, we enable the enforced fips mode. */
fp = fopen (FIPS_FORCE_FILE, "r");
if (fp)
{
char line[256];
if (fgets (line, sizeof line, fp) && atoi (line))
enforced_fips_mode = 1;
fclose (fp);
}
/* Now get us into the INIT state. */
fips_new_state (STATE_INIT);
}
return;
}
static void
lock_fsm (void)
{
gpg_error_t err;
err = ath_mutex_lock (&fsm_lock);
if (err)
{
log_info ("FATAL: failed to acquire the FSM lock in libgrypt: %s\n",
strerror (err));
#ifdef HAVE_SYSLOG
syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
"acquiring FSM lock failed: %s - abort",
strerror (err));
#endif /*HAVE_SYSLOG*/
abort ();
}
}
static void
unlock_fsm (void)
{
gpg_error_t err;
err = ath_mutex_unlock (&fsm_lock);
if (err)
{
log_info ("FATAL: failed to release the FSM lock in libgrypt: %s\n",
strerror (err));
#ifdef HAVE_SYSLOG
syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
"releasing FSM lock failed: %s - abort",
strerror (err));
#endif /*HAVE_SYSLOG*/
abort ();
}
}
/* This function returns true if fips mode is enabled. This is
independent of the fips required finite state machine and only used
to enable fips specific code. Please use the fips_mode macro
instead of calling this function directly. */
int
_gcry_fips_mode (void)
{
/* No locking is required because we have the requirement that this
variable is only initialized once with no other threads
existing. */
return !no_fips_mode_required;
}
/* Return a flag telling whether we are in the enforced fips mode. */
int
_gcry_enforced_fips_mode (void)
{
return enforced_fips_mode;
}
/* If we do not want to enforce the fips mode, we can set a flag so
that the application may check whether it is still in fips mode.
TEXT will be printed as part of a syslog message. This function
may only be be called if in fips mode. */
void
_gcry_inactivate_fips_mode (const char *text)
{
gcry_assert (_gcry_fips_mode ());
if (_gcry_enforced_fips_mode () )
{
/* Get us into the error state. */
fips_signal_error (text);
return;
}
lock_fsm ();
if (!inactive_fips_mode)
{
inactive_fips_mode = 1;
unlock_fsm ();
#ifdef HAVE_SYSLOG
syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
"%s - FIPS mode inactivated", text);
#endif /*HAVE_SYSLOG*/
}
else
unlock_fsm ();
}
/* Return the FIPS mode inactive flag. If it is true the FIPS mode is
not anymore active. */
int
_gcry_is_fips_mode_inactive (void)
{
int flag;
if (!_gcry_fips_mode ())
return 0;
lock_fsm ();
flag = inactive_fips_mode;
unlock_fsm ();
return flag;
}
static const char *
state2str (enum module_states state)
{
const char *s;
switch (state)
{
case STATE_POWERON: s = "Power-On"; break;
case STATE_INIT: s = "Init"; break;
case STATE_SELFTEST: s = "Self-Test"; break;
case STATE_OPERATIONAL: s = "Operational"; break;
case STATE_ERROR: s = "Error"; break;
case STATE_FATALERROR: s = "Fatal-Error"; break;
case STATE_SHUTDOWN: s = "Shutdown"; break;
default: s = "?"; break;
}
return s;
}
/* Return true if the library is in the operational state. */
int
_gcry_fips_is_operational (void)
{
int result;
if (!fips_mode ())
result = 1;
else
{
lock_fsm ();
if (current_state == STATE_INIT)
{
/* If we are still in the INIT state, we need to run the
selftests so that the FSM can eventually get into
operational state. Given that we would need a 2-phase
initialization of libgcrypt, but that has traditionally
not been enforced, we use this on demand self-test
checking. Note that Proper applications would do the
application specific libgcrypt initialization between a
gcry_check_version() and gcry_control
(GCRYCTL_INITIALIZATION_FINISHED) where the latter will
run the selftests. The drawback of these on-demand
self-tests are a small chance that self-tests are
performed by severeal threads; that is no problem because
our FSM make sure that we won't oversee any error. */
unlock_fsm ();
_gcry_fips_run_selftests (0);
lock_fsm ();
}
result = (current_state == STATE_OPERATIONAL);
unlock_fsm ();
}
return result;
}
/* This is test on whether the library is in the operational state. In
contrast to _gcry_fips_is_operational this function won't do a
state transition on the fly. */
int
_gcry_fips_test_operational (void)
{
int result;
if (!fips_mode ())
result = 1;
else
{
lock_fsm ();
result = (current_state == STATE_OPERATIONAL);
unlock_fsm ();
}
return result;
}
/* This is a test on whether the library is in the error or
operational state. */
int
_gcry_fips_test_error_or_operational (void)
{
int result;
if (!fips_mode ())
result = 1;
else
{
lock_fsm ();
result = (current_state == STATE_OPERATIONAL
|| current_state == STATE_ERROR);
unlock_fsm ();
}
return result;
}
static void
reporter (const char *domain, int algo, const char *what, const char *errtxt)
{
if (!errtxt && !_gcry_log_verbosity (2))
return;
log_info ("libgcrypt selftest: %s %s%s (%d): %s%s%s%s\n",
!strcmp (domain, "hmac")? "digest":domain,
!strcmp (domain, "hmac")? "HMAC-":"",
!strcmp (domain, "cipher")? _gcry_cipher_algo_name (algo) :
!strcmp (domain, "digest")? _gcry_md_algo_name (algo) :
!strcmp (domain, "hmac")? _gcry_md_algo_name (algo) :
!strcmp (domain, "pubkey")? _gcry_pk_algo_name (algo) : "",
algo, errtxt? errtxt:"Okay",
what?" (":"", what? what:"", what?")":"");
}
/* Run self-tests for all required cipher algorithms. Return 0 on
success. */
static int
run_cipher_selftests (int extended)
{
static int algos[] =
{
GCRY_CIPHER_3DES,
GCRY_CIPHER_AES128,
GCRY_CIPHER_AES192,
GCRY_CIPHER_AES256,
0
};
int idx;
gpg_error_t err;
int anyerr = 0;
for (idx=0; algos[idx]; idx++)
{
err = _gcry_cipher_selftest (algos[idx], extended, reporter);
reporter ("cipher", algos[idx], NULL,
err? gpg_strerror (err):NULL);
if (err)
anyerr = 1;
}
return anyerr;
}
/* Run self-tests for all required hash algorithms. Return 0 on
success. */
static int
run_digest_selftests (int extended)
{
static int algos[] =
{
GCRY_MD_SHA1,
GCRY_MD_SHA224,
GCRY_MD_SHA256,
GCRY_MD_SHA384,
GCRY_MD_SHA512,
0
};
int idx;
gpg_error_t err;
int anyerr = 0;
for (idx=0; algos[idx]; idx++)
{
err = _gcry_md_selftest (algos[idx], extended, reporter);
reporter ("digest", algos[idx], NULL,
err? gpg_strerror (err):NULL);
if (err)
anyerr = 1;
}
return anyerr;
}
/* Run self-tests for all HMAC algorithms. Return 0 on success. */
static int
run_hmac_selftests (int extended)
{
static int algos[] =
{
GCRY_MD_SHA1,
GCRY_MD_SHA224,
GCRY_MD_SHA256,
GCRY_MD_SHA384,
GCRY_MD_SHA512,
0
};
int idx;
gpg_error_t err;
int anyerr = 0;
for (idx=0; algos[idx]; idx++)
{
err = _gcry_hmac_selftest (algos[idx], extended, reporter);
reporter ("hmac", algos[idx], NULL,
err? gpg_strerror (err):NULL);
if (err)
anyerr = 1;
}
return anyerr;
}
/* Run self-tests for all required public key algorithms. Return 0 on
success. */
static int
run_pubkey_selftests (int extended)
{
static int algos[] =
{
GCRY_PK_RSA,
GCRY_PK_DSA,
/* GCRY_PK_ECDSA is not enabled in fips mode. */
0
};
int idx;
gpg_error_t err;
int anyerr = 0;
for (idx=0; algos[idx]; idx++)
{
err = _gcry_pk_selftest (algos[idx], extended, reporter);
reporter ("pubkey", algos[idx], NULL,
err? gpg_strerror (err):NULL);
if (err)
anyerr = 1;
}
return anyerr;
}
/* Run self-tests for the random number generator. Returns 0 on
success. */
static int
run_random_selftests (void)
{
gpg_error_t err;
err = _gcry_random_selftest (reporter);
reporter ("random", 0, NULL, err? gpg_strerror (err):NULL);
return !!err;
}
/* Run an integrity check on the binary. Returns 0 on success. */
static int
check_binary_integrity (void)
{
#ifdef ENABLE_HMAC_BINARY_CHECK
gpg_error_t err;
Dl_info info;
unsigned char digest[32];
int dlen;
char *fname = NULL;
const char key[] = "What am I, a doctor or a moonshuttle conductor?";
if (!dladdr ("gcry_check_version", &info))
err = gpg_error_from_syserror ();
else
{
dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname,
key, strlen (key));
if (dlen < 0)
err = gpg_error_from_syserror ();
else if (dlen != 32)
err = gpg_error (GPG_ERR_INTERNAL);
else
{
fname = gcry_malloc (strlen (info.dli_fname) + 1 + 5 + 1 );
if (!fname)
err = gpg_error_from_syserror ();
else
{
FILE *fp;
char *p;
/* Prefix the basename with a dot. */
strcpy (fname, info.dli_fname);
p = strrchr (fname, '/');
if (p)
p++;
else
p = fname;
memmove (p+1, p, strlen (p)+1);
*p = '.';
strcat (fname, ".hmac");
/* Open the file. */
fp = fopen (fname, "r");
if (!fp)
err = gpg_error_from_syserror ();
else
{
/* A buffer of 64 bytes plus one for a LF and one to
detect garbage. */
unsigned char buffer[64+1+1];
const unsigned char *s;
int n;
/* The HMAC files consists of lowercase hex digits
only with an optional trailing linefeed. Fail if
there is any garbage. */
err = gpg_error (GPG_ERR_SELFTEST_FAILED);
n = fread (buffer, 1, sizeof buffer, fp);
if (n == 64 || (n == 65 && buffer[64] == '\n'))
{
buffer[64] = 0;
for (n=0, s= buffer;
n < 32 && loxdigit_p (s) && loxdigit_p (s+1);
n++, s += 2)
buffer[n] = loxtoi_2 (s);
if ( n == 32 && !memcmp (digest, buffer, 32) )
err = 0;
}
fclose (fp);
}
}
}
}
reporter ("binary", 0, fname, err? gpg_strerror (err):NULL);
#ifdef HAVE_SYSLOG
if (err)
syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
"integrity check using `%s' failed: %s",
fname? fname:"[?]", gpg_strerror (err));
#endif /*HAVE_SYSLOG*/
gcry_free (fname);
return !!err;
#else
return 0;
#endif
}
/* Run the self-tests. If EXTENDED is true, extended versions of the
selftest are run, that is more tests than required by FIPS. */
gpg_err_code_t
_gcry_fips_run_selftests (int extended)
{
enum module_states result = STATE_ERROR;
gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED;
if (fips_mode ())
fips_new_state (STATE_SELFTEST);
if (run_cipher_selftests (extended))
goto leave;
if (run_digest_selftests (extended))
goto leave;
if (run_hmac_selftests (extended))
goto leave;
/* Run random tests before the pubkey tests because the latter
require random. */
if (run_random_selftests ())
goto leave;
if (run_pubkey_selftests (extended))
goto leave;
/* Now check the integrity of the binary. We do this this after
having checked the HMAC code. */
if (check_binary_integrity ())
goto leave;
/* All selftests passed. */
result = STATE_OPERATIONAL;
ec = 0;
leave:
if (fips_mode ())
fips_new_state (result);
return ec;
}
/* This function is used to tell the FSM about errors in the library.
The FSM will be put into an error state. This function should not
be called directly but by one of the macros
fips_signal_error (description)
fips_signal_fatal_error (description)
where DESCRIPTION is a string describing the error. */
void
_gcry_fips_signal_error (const char *srcfile, int srcline, const char *srcfunc,
int is_fatal, const char *description)
{
if (!fips_mode ())
return; /* Not required. */
/* Set new state before printing an error. */
fips_new_state (is_fatal? STATE_FATALERROR : STATE_ERROR);
/* Print error. */
log_info ("%serror in libgcrypt, file %s, line %d%s%s: %s\n",
is_fatal? "fatal ":"",
srcfile, srcline,
srcfunc? ", function ":"", srcfunc? srcfunc:"",
description? description : "no description available");
#ifdef HAVE_SYSLOG
syslog (LOG_USER|LOG_ERR, "Libgcrypt error: "
"%serror in file %s, line %d%s%s: %s",
is_fatal? "fatal ":"",
srcfile, srcline,
srcfunc? ", function ":"", srcfunc? srcfunc:"",
description? description : "no description available");
#endif /*HAVE_SYSLOG*/
}
/* Perform a state transition to NEW_STATE. If this is an invalid
transition, the module will go into a fatal error state. */
static void
fips_new_state (enum module_states new_state)
{
int ok = 0;
enum module_states last_state;
lock_fsm ();
last_state = current_state;
switch (current_state)
{
case STATE_POWERON:
if (new_state == STATE_INIT
|| new_state == STATE_ERROR
|| new_state == STATE_FATALERROR)
ok = 1;
break;
case STATE_INIT:
if (new_state == STATE_SELFTEST
|| new_state == STATE_ERROR
|| new_state == STATE_FATALERROR)
ok = 1;
break;
case STATE_SELFTEST:
if (new_state == STATE_OPERATIONAL
|| new_state == STATE_ERROR
|| new_state == STATE_FATALERROR)
ok = 1;
break;
case STATE_OPERATIONAL:
if (new_state == STATE_SHUTDOWN
|| new_state == STATE_SELFTEST
|| new_state == STATE_ERROR
|| new_state == STATE_FATALERROR)
ok = 1;
break;
case STATE_ERROR:
if (new_state == STATE_SHUTDOWN
|| new_state == STATE_ERROR
|| new_state == STATE_FATALERROR
|| new_state == STATE_SELFTEST)
ok = 1;
break;
case STATE_FATALERROR:
if (new_state == STATE_SHUTDOWN )
ok = 1;
break;
case STATE_SHUTDOWN:
/* We won't see any transition *from* Shutdown because the only
allowed new state is Power-Off and that one can't be
represented. */
break;
}
if (ok)
{
current_state = new_state;
}
unlock_fsm ();
if (!ok || _gcry_log_verbosity (2))
log_info ("libgcrypt state transition %s => %s %s\n",
state2str (last_state), state2str (new_state),
ok? "granted":"denied");
if (!ok)
{
/* Invalid state transition. Halting library. */
#ifdef HAVE_SYSLOG
syslog (LOG_USER|LOG_ERR,
"Libgcrypt error: invalid state transition %s => %s",
state2str (last_state), state2str (new_state));
#endif /*HAVE_SYSLOG*/
fips_noreturn ();
}
else if (new_state == STATE_ERROR || new_state == STATE_FATALERROR)
{
#ifdef HAVE_SYSLOG
syslog (LOG_USER|LOG_WARNING,
"Libgcrypt notice: state transition %s => %s",
state2str (last_state), state2str (new_state));
#endif /*HAVE_SYSLOG*/
}
}
/* This function should be called to ensure that the execution shall
not continue. */
void
_gcry_fips_noreturn (void)
{
#ifdef HAVE_SYSLOG
syslog (LOG_USER|LOG_ERR, "Libgcrypt terminated the application");
#endif /*HAVE_SYSLOG*/
fflush (NULL);
abort ();
/*NOTREACHED*/
}

View file

@ -0,0 +1,349 @@
/* g10lib.h - Internal definitions for libgcrypt
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
* 2007, 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 <http://www.gnu.org/licenses/>.
*/
/* This header is to be used inside of libgcrypt in place of gcrypt.h.
This way we can better distinguish between internal and external
usage of gcrypt.h. */
#ifndef G10LIB_H
#define G10LIB_H 1
#ifdef _GCRYPT_H
#error gcrypt.h already included
#endif
#ifndef _GCRYPT_IN_LIBGCRYPT
#error something is wrong with config.h
#endif
#include <stdio.h>
#include <stdarg.h>
#include "visibility.h"
#include "types.h"
/* Attribute handling macros. */
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 )
#define JNLIB_GCC_M_FUNCTION 1
#define JNLIB_GCC_A_NR __attribute__ ((noreturn))
#define JNLIB_GCC_A_PRINTF( f, a ) __attribute__ ((format (printf,f,a)))
#define JNLIB_GCC_A_NR_PRINTF( f, a ) \
__attribute__ ((noreturn, format (printf,f,a)))
#define GCC_ATTR_NORETURN __attribute__ ((__noreturn__))
#else
#define JNLIB_GCC_A_NR
#define JNLIB_GCC_A_PRINTF( f, a )
#define JNLIB_GCC_A_NR_PRINTF( f, a )
#define GCC_ATTR_NORETURN
#endif
#if __GNUC__ >= 3
/* According to glibc this attribute is available since 2.8 however we
better play safe and use it only with gcc 3 or newer. */
#define GCC_ATTR_FORMAT_ARG(a) __attribute__ ((format_arg (a)))
#else
#define GCC_ATTR_FORMAT_ARG(a)
#endif
/* Gettext macros. */
#define _(a) _gcry_gettext(a)
/* Some handy macros */
#ifndef STR
#define STR(v) #v
#endif
#define STR2(v) STR(v)
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
#define DIMof(type,member) DIM(((type *)0)->member)
/*-- src/global.c -*/
int _gcry_global_is_operational (void);
gcry_error_t _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr);
void _gcry_check_heap (const void *a);
int _gcry_get_debug_flag (unsigned int mask);
/*-- src/misc.c --*/
#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L
void _gcry_bug (const char *file, int line,
const char *func) GCC_ATTR_NORETURN;
void _gcry_assert_failed (const char *expr, const char *file, int line,
const char *func) GCC_ATTR_NORETURN;
#else
void _gcry_bug (const char *file, int line);
void _gcry_assert_failed (const char *expr, const char *file, int line);
#endif
const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1);
void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR;
void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3);
void _gcry_log_bug( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
void _gcry_log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
void _gcry_log_error( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
void _gcry_log_info( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
int _gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
JNLIB_GCC_A_PRINTF(2,3);
void _gcry_log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
void _gcry_log_printf ( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
void _gcry_log_printhex (const char *text, const void *buffer, size_t length);
void _gcry_set_log_verbosity( int level );
int _gcry_log_verbosity( int level );
#define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ )
#define gcry_assert(expr) ((expr)? (void)0 \
: _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__))
#define log_bug _gcry_log_bug
#define log_fatal _gcry_log_fatal
#define log_error _gcry_log_error
#define log_info _gcry_log_info
#define log_debug _gcry_log_debug
#define log_printf _gcry_log_printf
#define log_printhex _gcry_log_printhex
/*-- src/hwfeatures.c --*/
/* (Do not change these values unless synced with the asm code.) */
#define HWF_PADLOCK_RNG 1
#define HWF_PADLOCK_AES 2
#define HWF_PADLOCK_SHA 4
#define HWF_PADLOCK_MMUL 8
#define HWF_INTEL_AESNI 256
unsigned int _gcry_get_hw_features (void);
void _gcry_detect_hw_features (unsigned int);
/*-- mpi/mpiutil.c --*/
const char *_gcry_mpi_get_hw_config (void);
/*-- cipher/pubkey.c --*/
/* FIXME: shouldn't this go into mpi.h? */
#ifndef mpi_powm
#define mpi_powm(w,b,e,m) gcry_mpi_powm( (w), (b), (e), (m) )
#endif
/*-- primegen.c --*/
gcry_err_code_t _gcry_primegen_init (void);
gcry_mpi_t _gcry_generate_secret_prime (unsigned int nbits,
gcry_random_level_t random_level,
int (*extra_check)(void*, gcry_mpi_t),
void *extra_check_arg);
gcry_mpi_t _gcry_generate_public_prime (unsigned int nbits,
gcry_random_level_t random_level,
int (*extra_check)(void*, gcry_mpi_t),
void *extra_check_arg);
gcry_mpi_t _gcry_generate_elg_prime (int mode,
unsigned int pbits, unsigned int qbits,
gcry_mpi_t g, gcry_mpi_t **factors);
gcry_mpi_t _gcry_derive_x931_prime (const gcry_mpi_t xp,
const gcry_mpi_t xp1, const gcry_mpi_t xp2,
const gcry_mpi_t e,
gcry_mpi_t *r_p1, gcry_mpi_t *r_p2);
gpg_err_code_t _gcry_generate_fips186_2_prime
(unsigned int pbits, unsigned int qbits,
const void *seed, size_t seedlen,
gcry_mpi_t *r_q, gcry_mpi_t *r_p,
int *r_counter,
void **r_seed, size_t *r_seedlen);
gpg_err_code_t _gcry_generate_fips186_3_prime
(unsigned int pbits, unsigned int qbits,
const void *seed, size_t seedlen,
gcry_mpi_t *r_q, gcry_mpi_t *r_p,
int *r_counter,
void **r_seed, size_t *r_seedlen, int *r_hashalgo);
/* Replacements of missing functions (missing-string.c). */
#ifndef HAVE_STPCPY
char *stpcpy (char *a, const char *b);
#endif
#ifndef HAVE_STRCASECMP
int strcasecmp (const char *a, const char *b) _GCRY_GCC_ATTR_PURE;
#endif
/* Macros used to rename missing functions. */
#ifndef HAVE_STRTOUL
#define strtoul(a,b,c) ((unsigned long)strtol((a),(b),(c)))
#endif
#ifndef HAVE_MEMMOVE
#define memmove(d, s, n) bcopy((s), (d), (n))
#endif
#ifndef HAVE_STRICMP
#define stricmp(a,b) strcasecmp( (a), (b) )
#endif
#ifndef HAVE_ATEXIT
#define atexit(a) (on_exit((a),0))
#endif
#ifndef HAVE_RAISE
#define raise(a) kill(getpid(), (a))
#endif
/* Stack burning. */
void _gcry_burn_stack (int bytes);
/* To avoid that a compiler optimizes certain memset calls away, these
macros may be used instead. */
#define wipememory2(_ptr,_set,_len) do { \
volatile char *_vptr=(volatile char *)(_ptr); \
size_t _vlen=(_len); \
while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
} while(0)
#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
/* Digit predicates. */
#define digitp(p) (*(p) >= '0' && *(p) <= '9')
#define octdigitp(p) (*(p) >= '0' && *(p) <= '7')
#define alphap(a) ( (*(a) >= 'A' && *(a) <= 'Z') \
|| (*(a) >= 'a' && *(a) <= 'z'))
#define hexdigitp(a) (digitp (a) \
|| (*(a) >= 'A' && *(a) <= 'F') \
|| (*(a) >= 'a' && *(a) <= 'f'))
/* Management for ciphers/digests/pubkey-ciphers. */
/* Structure for each registered `module'. */
struct gcry_module
{
struct gcry_module *next; /* List pointers. */
struct gcry_module **prevp;
void *spec; /* Pointer to the subsystem-specific
specification structure. */
void *extraspec; /* Pointer to the subsystem-specific
extra specification structure. */
int flags; /* Associated flags. */
int counter; /* Use counter. */
unsigned int mod_id; /* ID of this module. */
};
typedef struct gcry_module gcry_module_t;
/* Flags for the `flags' member of gcry_module_t. */
#define FLAG_MODULE_DISABLED (1 << 0)
gcry_err_code_t _gcry_module_add (gcry_module_t *entries,
unsigned int id,
void *spec,
void *extraspec,
gcry_module_t *module);
typedef int (*gcry_module_lookup_t) (void *spec, void *data);
/* Lookup a module specification by it's ID. After a successful
lookup, the module has it's resource counter incremented. */
gcry_module_t _gcry_module_lookup_id (gcry_module_t entries,
unsigned int id);
/* Internal function. Lookup a module specification. */
gcry_module_t _gcry_module_lookup (gcry_module_t entries, void *data,
gcry_module_lookup_t func);
/* Release a module. In case the use-counter reaches zero, destroy
the module. */
void _gcry_module_release (gcry_module_t entry);
/* Add a reference to a module. */
void _gcry_module_use (gcry_module_t module);
/* Return a list of module IDs. */
gcry_err_code_t _gcry_module_list (gcry_module_t modules,
int *list, int *list_length);
gcry_err_code_t _gcry_cipher_init (void);
gcry_err_code_t _gcry_md_init (void);
gcry_err_code_t _gcry_pk_init (void);
gcry_err_code_t _gcry_pk_module_lookup (int id, gcry_module_t *module);
void _gcry_pk_module_release (gcry_module_t module);
gcry_err_code_t _gcry_pk_get_elements (int algo, char **enc, char **sig);
/* Memory management. */
#define GCRY_ALLOC_FLAG_SECURE (1 << 0)
/*-- sexp.c --*/
gcry_error_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
const char *format, va_list arg_ptr);
char *_gcry_sexp_nth_string (const gcry_sexp_t list, int number);
/*-- fips.c --*/
void _gcry_initialize_fips_mode (int force);
int _gcry_enforced_fips_mode (void);
void _gcry_inactivate_fips_mode (const char *text);
int _gcry_is_fips_mode_inactive (void);
void _gcry_fips_signal_error (const char *srcfile,
int srcline,
const char *srcfunc,
int is_fatal,
const char *description);
#ifdef JNLIB_GCC_M_FUNCTION
# define fips_signal_error(a) \
_gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 0, (a))
# define fips_signal_fatal_error(a) \
_gcry_fips_signal_error (__FILE__, __LINE__, __FUNCTION__, 1, (a))
#else
# define fips_signal_error(a) \
_gcry_fips_signal_error (__FILE__, __LINE__, NULL, 0, (a))
# define fips_signal_fatal_error(a) \
_gcry_fips_signal_error (__FILE__, __LINE__, NULL, 1, (a))
#endif
int _gcry_fips_is_operational (void);
#define fips_is_operational() (_gcry_global_is_operational ())
#define fips_not_operational() (GCRY_GPG_ERR_NOT_OPERATIONAL)
int _gcry_fips_test_operational (void);
int _gcry_fips_test_error_or_operational (void);
gpg_err_code_t _gcry_fips_run_selftests (int extended);
void _gcry_fips_noreturn (void);
#define fips_noreturn() (_gcry_fips_noreturn ())
#endif /* G10LIB_H */

View file

@ -0,0 +1,204 @@
/* gcrypt-module.h - GNU Cryptographic Library Interface
Copyright (C) 2003, 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 <http://www.gnu.org/licenses/>.
*/
/*
This file contains the necessary declarations/definitions for
working with Libgcrypt modules. Since 1.6 this is an internal
interface and will eventually be merged into another header or
entirely removed.
*/
#ifndef GCRYPT_MODULE_H
#define GCRYPT_MODULE_H
#ifdef __cplusplus
extern "C" {
#if 0 /* keep Emacsens's auto-indent happy */
}
#endif
#endif
/* The interfaces using the module system reserve a certain range of
IDs for application use. These IDs are not valid within Libgcrypt
but Libgcrypt makes sure never to allocate such a module ID. */
#define GCRY_MODULE_ID_USER 1024
#define GCRY_MODULE_ID_USER_LAST 4095
/* This type represents a `module'. */
typedef struct gcry_module *gcry_module_t;
/* Check that the library fulfills the version requirement. */
/* Type for the cipher_setkey function. */
typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
const unsigned char *key,
unsigned keylen);
/* Type for the cipher_encrypt function. */
typedef void (*gcry_cipher_encrypt_t) (void *c,
unsigned char *outbuf,
const unsigned char *inbuf);
/* Type for the cipher_decrypt function. */
typedef void (*gcry_cipher_decrypt_t) (void *c,
unsigned char *outbuf,
const unsigned char *inbuf);
/* Type for the cipher_stencrypt function. */
typedef void (*gcry_cipher_stencrypt_t) (void *c,
unsigned char *outbuf,
const unsigned char *inbuf,
unsigned int n);
/* Type for the cipher_stdecrypt function. */
typedef void (*gcry_cipher_stdecrypt_t) (void *c,
unsigned char *outbuf,
const unsigned char *inbuf,
unsigned int n);
typedef struct gcry_cipher_oid_spec
{
const char *oid;
int mode;
} gcry_cipher_oid_spec_t;
/* Module specification structure for ciphers. */
typedef struct gcry_cipher_spec
{
const char *name;
const char **aliases;
gcry_cipher_oid_spec_t *oids;
size_t blocksize;
size_t keylen;
size_t contextsize;
gcry_cipher_setkey_t setkey;
gcry_cipher_encrypt_t encrypt;
gcry_cipher_decrypt_t decrypt;
gcry_cipher_stencrypt_t stencrypt;
gcry_cipher_stdecrypt_t stdecrypt;
} gcry_cipher_spec_t;
/* ********************** */
/* Type for the pk_generate function. */
typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo,
unsigned int nbits,
unsigned long use_e,
gcry_mpi_t *skey,
gcry_mpi_t **retfactors);
/* Type for the pk_check_secret_key function. */
typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
gcry_mpi_t *skey);
/* Type for the pk_encrypt function. */
typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo,
gcry_mpi_t *resarr,
gcry_mpi_t data,
gcry_mpi_t *pkey,
int flags);
/* Type for the pk_decrypt function. */
typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo,
gcry_mpi_t *result,
gcry_mpi_t *data,
gcry_mpi_t *skey,
int flags);
/* Type for the pk_sign function. */
typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo,
gcry_mpi_t *resarr,
gcry_mpi_t data,
gcry_mpi_t *skey);
/* Type for the pk_verify function. */
typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo,
gcry_mpi_t hash,
gcry_mpi_t *data,
gcry_mpi_t *pkey,
int (*cmp) (void *, gcry_mpi_t),
void *opaquev);
/* Type for the pk_get_nbits function. */
typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey);
/* Module specification structure for message digests. */
typedef struct gcry_pk_spec
{
const char *name;
const char **aliases;
const char *elements_pkey;
const char *elements_skey;
const char *elements_enc;
const char *elements_sig;
const char *elements_grip;
int use;
gcry_pk_generate_t generate;
gcry_pk_check_secret_key_t check_secret_key;
gcry_pk_encrypt_t encrypt;
gcry_pk_decrypt_t decrypt;
gcry_pk_sign_t sign;
gcry_pk_verify_t verify;
gcry_pk_get_nbits_t get_nbits;
} gcry_pk_spec_t;
/* ********************** */
/* Type for the md_init function. */
typedef void (*gcry_md_init_t) (void *c);
/* Type for the md_write function. */
typedef void (*gcry_md_write_t) (void *c, const void *buf, size_t nbytes);
/* Type for the md_final function. */
typedef void (*gcry_md_final_t) (void *c);
/* Type for the md_read function. */
typedef unsigned char *(*gcry_md_read_t) (void *c);
typedef struct gcry_md_oid_spec
{
const char *oidstring;
} gcry_md_oid_spec_t;
/* Module specification structure for message digests. */
typedef struct gcry_md_spec
{
const char *name;
unsigned char *asnoid;
int asnlen;
gcry_md_oid_spec_t *oids;
int mdlen;
gcry_md_init_t init;
gcry_md_write_t write;
gcry_md_final_t final;
gcry_md_read_t read;
size_t contextsize; /* allocate this amount of context */
} gcry_md_spec_t;
#if 0 /* keep Emacsens's auto-indent happy */
{
#endif
#ifdef __cplusplus
}
#endif
#endif /*GCRYPT_MODULE_H*/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,680 @@
/* gcryptrnd.c - Libgcrypt Random Number Daemon
* Copyright (C) 2006 Free Software Foundation, Inc.
*
* Gcryptend 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.
*
* Gcryptrnd 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/* We require vsyslog pth
We need to test for: setrlimit
We should also prioritize requests. This is best done by putting
the requests into queues and have a main thread processing these
queues.
*/
#include <config.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>
#include <sys/times.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <syslog.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
#include <pth.h>
#include <gcrypt.h>
#define PGM "gcryptrnd"
#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
/* Pth wrapper function definitions. */
GCRY_THREAD_OPTION_PTH_IMPL;
/* Flag set to true if we have been daemonized. */
static int running_detached;
/* Flag indicating that a shutdown has been requested. */
static int shutdown_pending;
/* Counter for active connections. */
static int active_connections;
/* Local prototypes. */
static void serve (int listen_fd);
/* To avoid that a compiler optimizes certain memset calls away, these
macros may be used instead. */
#define wipememory2(_ptr,_set,_len) do { \
volatile char *_vptr=(volatile char *)(_ptr); \
size_t _vlen=(_len); \
while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
} while(0)
#define wipememory(_ptr,_len) wipememory2(_ptr,0,_len)
/* Error printing utility. PRIORITY should be one of syslog's
priority levels. This functions prints to the stderr or syslog
depending on whether we are already daemonized. */
static void
logit (int priority, const char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format) ;
if (running_detached)
{
vsyslog (priority, format, arg_ptr);
}
else
{
fputs (PGM ": ", stderr);
vfprintf (stderr, format, arg_ptr);
putc ('\n', stderr);
}
va_end (arg_ptr);
}
/* Callback used by libgcrypt for logging. */
static void
my_gcry_logger (void *dummy, int level, const char *format, va_list arg_ptr)
{
(void)dummy;
/* Map the log levels. */
switch (level)
{
case GCRY_LOG_CONT: level = LOG_INFO /* FIXME */; break;
case GCRY_LOG_INFO: level = LOG_INFO; break;
case GCRY_LOG_WARN: level = LOG_WARNING; break;
case GCRY_LOG_ERROR:level = LOG_ERR; break;
case GCRY_LOG_FATAL:level = LOG_CRIT; break;
case GCRY_LOG_BUG: level = LOG_CRIT; break;
case GCRY_LOG_DEBUG:level = LOG_DEBUG; break;
default: level = LOG_ERR; break;
}
if (running_detached)
{
vsyslog (level, format, arg_ptr);
}
else
{
fputs (PGM ": ", stderr);
vfprintf (stderr, format, arg_ptr);
if (!*format || format[strlen (format)-1] != '\n')
putc ('\n', stderr);
}
}
/* The cleanup handler - used to wipe out the secure memory. */
static void
cleanup (void)
{
gcry_control (GCRYCTL_TERM_SECMEM );
}
/* Make us a daemon and open the syslog. */
static void
daemonize (void)
{
int i;
pid_t pid;
fflush (NULL);
pid = fork ();
if (pid == (pid_t)-1)
{
logit (LOG_CRIT, "fork failed: %s", strerror (errno));
exit (1);
}
if (pid)
exit (0);
if (setsid() == -1)
{
logit (LOG_CRIT, "setsid() failed: %s", strerror(errno));
exit (1);
}
signal (SIGHUP, SIG_IGN);
pid = fork ();
if (pid == (pid_t)-1)
{
logit (LOG_CRIT, PGM ": second fork failed: %s", strerror (errno));
exit (1);
}
if (pid)
exit (0); /* First child exits. */
running_detached = 1;
if (chdir("/"))
{
logit (LOG_CRIT, "chdir(\"/\") failed: %s", strerror (errno));
exit (1);
}
umask (0);
for (i=0; i <= 2; i++)
close (i);
openlog (PGM, LOG_PID, LOG_DAEMON);
}
static void
disable_core_dumps (void)
{
#ifdef HAVE_SETRLIMIT
struct rlimit limit;
if (getrlimit (RLIMIT_CORE, &limit))
limit.rlim_max = 0;
limit.rlim_cur = 0;
if( !setrlimit (RLIMIT_CORE, &limit) )
return 0;
if (errno != EINVAL && errno != ENOSYS)
logit (LOG_ERR, "can't disable core dumps: %s\n", strerror (errno));
#endif /* HAVE_SETRLIMIT */
}
static void
print_version (int with_help)
{
fputs (MYVERSION_LINE "\n"
"Copyright (C) 2006 Free Software Foundation, Inc.\n"
"License GPLv2+: GNU GPL version 2 or later "
"<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n",
stdout);
if (with_help)
fputs ("\n"
"Usage: " PGM " [OPTIONS] [SOCKETNAME]\n"
"Start Libgcrypt's random number daemon listening"
" on socket SOCKETNAME\n"
"SOCKETNAME defaults to XXX\n"
"\n"
" --no-detach do not deatach from the console\n"
" --version print version of the program and exit\n"
" --help display this help and exit\n"
BUGREPORT_LINE, stdout );
exit (0);
}
static int
print_usage (void)
{
fputs ("usage: " PGM " [OPTIONS] [SOCKETNAME]\n", stderr);
fputs (" (use --help to display options)\n", stderr);
exit (1);
}
int
main (int argc, char **argv)
{
int no_detach = 0;
gpg_error_t err;
struct sockaddr_un *srvr_addr;
socklen_t addrlen;
int fd;
int rc;
const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
if (argc)
{
argc--; argv++;
}
while (argc && **argv == '-' && (*argv)[1] == '-')
{
if (!(*argv)[2])
{
argc--; argv++;
break;
}
else if (!strcmp (*argv, "--version"))
print_version (0);
else if (!strcmp (*argv, "--help"))
print_version (1);
else if (!strcmp (*argv, "--no-detach"))
{
no_detach = 1;
argc--; argv++;
}
else
print_usage ();
}
if (argc == 1)
socketname = argv[0];
else if (argc > 1)
print_usage ();
if (!no_detach)
daemonize ();
signal (SIGPIPE, SIG_IGN);
logit (LOG_NOTICE, "started version " VERSION );
/* Libgcrypt requires us to register the threading model before we
do anything else with it. Note that this also calls pth_init. We
do the initialization while already running as a daemon to avoid
overhead with double initialization of Libgcrypt. */
err = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
if (err)
{
logit (LOG_CRIT, "can't register GNU Pth with Libgcrypt: %s",
gpg_strerror (err));
exit (1);
}
/* Check that the libgcrypt version is sufficient. */
if (!gcry_check_version (VERSION) )
{
logit (LOG_CRIT, "libgcrypt is too old (need %s, have %s)",
VERSION, gcry_check_version (NULL) );
exit (1);
}
/* Register the logging callback and tell Libcgrypt to put the
random pool into secure memory. */
gcry_set_log_handler (my_gcry_logger, NULL);
gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);
/* Obviously we don't want to allow any core dumps. */
disable_core_dumps ();
/* Initialize the secure memory stuff which will also drop any extra
privileges we have. */
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
/* Register a cleanup handler. */
atexit (cleanup);
/* Create and listen on the socket. */
fd = socket (AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
{
logit (LOG_CRIT, "can't create socket: %s", strerror (errno));
exit (1);
}
srvr_addr = gcry_xmalloc (sizeof *srvr_addr);
memset (srvr_addr, 0, sizeof *srvr_addr);
srvr_addr->sun_family = AF_UNIX;
if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
{
logit (LOG_CRIT, "socket name `%s' too long", socketname);
exit (1);
}
strcpy (srvr_addr->sun_path, socketname);
addrlen = (offsetof (struct sockaddr_un, sun_path)
+ strlen (srvr_addr->sun_path) + 1);
rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
if (rc == -1 && errno == EADDRINUSE)
{
remove (socketname);
rc = bind (fd, (struct sockaddr*) srvr_addr, addrlen);
}
if (rc == -1)
{
logit (LOG_CRIT, "error binding socket to `%s': %s",
srvr_addr->sun_path, strerror (errno));
close (fd);
exit (1);
}
if (listen (fd, 5 ) == -1)
{
logit (LOG_CRIT, "listen() failed: %s", strerror (errno));
close (fd);
exit (1);
}
logit (LOG_INFO, "listening on socket `%s', fd=%d",
srvr_addr->sun_path, fd);
serve (fd);
close (fd);
logit (LOG_NOTICE, "stopped version " VERSION );
return 0;
}
/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
success or another value on write error. */
static int
writen (int fd, const void *buffer, size_t length)
{
while (length)
{
ssize_t n = pth_write (fd, buffer, length);
if (n < 0)
{
logit (LOG_ERR, "connection %d: write error: %s",
fd, strerror (errno));
return -1; /* write error */
}
length -= n;
buffer = (const char*)buffer + n;
}
return 0; /* Okay */
}
/* Send an error response back. Returns 0 on success. */
static int
send_error (int fd, int errcode)
{
unsigned char buf[2];
buf[0] = errcode;
buf[1] = 0;
return writen (fd, buf, 2 );
}
/* Send a pong response back. Returns 0 on success or another value
on write error. */
static int
send_pong (int fd)
{
return writen (fd, "\x00\x04pong", 6);
}
/* Send a nonce of size LENGTH back. Return 0 on success. */
static int
send_nonce (int fd, int length)
{
unsigned char buf[2+255];
int rc;
assert (length >= 0 && length <= 255);
buf[0] = 0;
buf[1] = length;
gcry_create_nonce (buf+2, length);
rc = writen (fd, buf, 2+length );
wipememory (buf+2, length);
return rc;
}
/* Send a random of size LENGTH with quality LEVEL back. Return 0 on
success. */
static int
send_random (int fd, int length, int level)
{
unsigned char buf[2+255];
int rc;
assert (length >= 0 && length <= 255);
assert (level == GCRY_STRONG_RANDOM || level == GCRY_VERY_STRONG_RANDOM);
buf[0] = 0;
buf[1] = length;
/* Note that we don't bother putting the random stuff into secure
memory because this daemon is anyway intended to be run under
root and it is questionable whether the kernel buffers etc. are
equally well protected. */
gcry_randomize (buf+2, length, level);
rc = writen (fd, buf, 2+length );
wipememory (buf+2, length);
return rc;
}
/* Main processing loop for a connection.
A request is made up of:
1 byte Total length of request; must be 3
1 byte Command
0 = Ping
10 = GetNonce
11 = GetStrongRandom
12 = GetVeryStrongRandom
(all other values are reserved)
1 byte Number of requested bytes.
This is ignored for command Ping.
A response is made up of:
1 byte Error Code
0 = Everything is fine
1 = Bad Command
0xff = Other error.
(For a bad request the connection will simply be closed)
1 byte Length of data
n byte data
The requests are read as long as the connection is open.
*/
static void
connection_loop (int fd)
{
unsigned char request[3];
unsigned char *p;
int nleft, n;
int rc;
for (;;)
{
for (nleft=3, p=request; nleft > 0; )
{
n = pth_read (fd, p, nleft);
if (!n && p == request)
return; /* Client terminated connection. */
if (n <= 0)
{
logit (LOG_ERR, "connection %d: read error: %s",
fd, n? strerror (errno) : "Unexpected EOF");
return;
}
p += n;
nleft -= n;
}
if (request[0] != 3)
{
logit (LOG_ERR, "connection %d: invalid length (%d) of request",
fd, request[0]);
return;
}
switch (request[1])
{
case 0: /* Ping */
rc = send_pong (fd);
break;
case 10: /* GetNonce */
rc = send_nonce (fd, request[2]);
break;
case 11: /* GetStrongRandom */
rc = send_random (fd, request[2], GCRY_STRONG_RANDOM);
break;
case 12: /* GetVeryStrongRandom */
rc = send_random (fd, request[2], GCRY_VERY_STRONG_RANDOM);
break;
default: /* Invalid command */
rc = send_error (fd, 1);
break;
}
if (rc)
break; /* A write error occurred while sending the response. */
}
}
/* Entry point for a connection's thread. */
static void *
connection_thread (void *arg)
{
int fd = (int)arg;
active_connections++;
logit (LOG_INFO, "connection handler for fd %d started", fd);
connection_loop (fd);
close (fd);
logit (LOG_INFO, "connection handler for fd %d terminated", fd);
active_connections--;
return NULL;
}
/* This signal handler is called from the main loop between acepting
connections. It is called on the regular stack, thus no special
caution needs to be taken. It returns true to indicate that the
process should terminate. */
static int
handle_signal (int signo)
{
switch (signo)
{
case SIGHUP:
logit (LOG_NOTICE, "SIGHUP received - re-reading configuration");
break;
case SIGUSR1:
logit (LOG_NOTICE, "SIGUSR1 received - no action defined");
break;
case SIGUSR2:
logit (LOG_NOTICE, "SIGUSR2 received - no action defined");
break;
case SIGTERM:
if (!shutdown_pending)
logit (LOG_NOTICE, "SIGTERM received - shutting down ...");
else
logit (LOG_NOTICE, "SIGTERM received - still %d active connections",
active_connections);
shutdown_pending++;
if (shutdown_pending > 2)
{
logit (LOG_NOTICE, "shutdown forced");
return 1;
}
break;
case SIGINT:
logit (LOG_NOTICE, "SIGINT received - immediate shutdown");
return 1;
default:
logit (LOG_NOTICE, "signal %d received - no action defined\n", signo);
}
return 0;
}
/* Main server loop. This is called with the FD of the listening
socket. */
static void
serve (int listen_fd)
{
pth_attr_t tattr;
pth_event_t ev;
sigset_t sigs;
int signo;
struct sockaddr_un paddr;
socklen_t plen = sizeof (paddr);
int fd;
tattr = pth_attr_new();
pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0);
pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024);
pth_attr_set (tattr, PTH_ATTR_NAME, "connection");
sigemptyset (&sigs);
sigaddset (&sigs, SIGHUP);
sigaddset (&sigs, SIGUSR1);
sigaddset (&sigs, SIGUSR2);
sigaddset (&sigs, SIGINT);
sigaddset (&sigs, SIGTERM);
ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo);
for (;;)
{
if (shutdown_pending)
{
if (!active_connections)
break; /* Ready. */
/* Do not accept anymore connections but wait for existing
connections to terminate. */
signo = 0;
pth_wait (ev);
if (pth_event_occurred (ev) && signo)
if (handle_signal (signo))
break; /* Stop the loop. */
continue;
}
gcry_fast_random_poll ();
fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev);
if (fd == -1)
{
if (pth_event_occurred (ev))
{
if (handle_signal (signo))
break; /* Stop the loop. */
continue;
}
logit (LOG_WARNING, "accept failed: %s - waiting 1s\n",
strerror (errno));
gcry_fast_random_poll ();
pth_sleep (1);
continue;
}
if (!pth_spawn (tattr, connection_thread, (void*)fd))
{
logit (LOG_ERR, "error spawning connection handler: %s\n",
strerror (errno) );
close (fd);
}
}
pth_event_free (ev, PTH_FREE_ALL);
}

View file

@ -0,0 +1,326 @@
/* getrandom.c - Libgcrypt Random Number client
* Copyright (C) 2006 Free Software Foundation, Inc.
*
* Getrandom 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.
*
* Getrandom 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., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <config.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <errno.h>
#define PGM "getrandom"
#define MYVERSION_LINE PGM " (Libgcrypt) " VERSION
#define BUGREPORT_LINE "\nReport bugs to <bug-libgcrypt@gnupg.org>.\n"
static void
logit (const char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format) ;
fputs (PGM ": ", stderr);
vfprintf (stderr, format, arg_ptr);
putc ('\n', stderr);
va_end (arg_ptr);
}
/* Send LENGTH bytes of BUFFER to file descriptor FD. Returns 0 on
success or another value on write error. */
static int
writen (int fd, const void *buffer, size_t length)
{
while (length)
{
ssize_t n;
do
n = write (fd, buffer, length);
while (n < 0 && errno == EINTR);
if (n < 0)
{
logit ("write error: %s", strerror (errno));
return -1; /* write error */
}
length -= n;
buffer = (const char *)buffer + n;
}
return 0; /* Okay */
}
static void
print_version (int with_help)
{
fputs (MYVERSION_LINE "\n"
"Copyright (C) 2006 Free Software Foundation, Inc.\n"
"License GPLv2+: GNU GPL version 2 or later "
"<http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>\n"
"This is free software: you are free to change and redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n",
stdout);
if (with_help)
fputs ("\n"
"Usage: " PGM " [OPTIONS] NBYTES\n"
"Connect to libgcrypt's random number daemon and "
"return random numbers"
"\n"
" --nonce Return weak random suitable for a nonce\n"
" --very-strong Return very strong random\n"
" --ping Send a ping\n"
" --socket NAME Name of sockket to connect to\n"
" --hex Return result as a hex dump\n"
" --verbose Show what we are doing\n"
" --version Print version of the program and exit\n"
" --help Display this help and exit\n"
BUGREPORT_LINE, stdout );
exit (0);
}
static int
print_usage (void)
{
fputs ("usage: " PGM " [OPTIONS] NBYTES\n", stderr);
fputs (" (use --help to display options)\n", stderr);
exit (1);
}
int
main (int argc, char **argv)
{
struct sockaddr_un *srvr_addr;
socklen_t addrlen;
int fd;
int rc;
unsigned char buffer[300];
int nleft, nread;
const char *socketname = "/var/run/libgcrypt/S.gcryptrnd";
int do_ping = 0;
int get_nonce = 0;
int get_very_strong = 0;
int req_nbytes, nbytes, n;
int verbose = 0;
int fail = 0;
int do_hex = 0;
if (argc)
{
argc--; argv++;
}
while (argc && **argv == '-' && (*argv)[1] == '-')
{
if (!(*argv)[2])
{
argc--; argv++;
break;
}
else if (!strcmp (*argv, "--version"))
print_version (0);
else if (!strcmp (*argv, "--help"))
print_version (1);
else if (!strcmp (*argv, "--socket") && argc > 1 )
{
argc--; argv++;
socketname = *argv;
argc--; argv++;
}
else if (!strcmp (*argv, "--nonce"))
{
argc--; argv++;
get_nonce = 1;
}
else if (!strcmp (*argv, "--very-strong"))
{
argc--; argv++;
get_very_strong = 1;
}
else if (!strcmp (*argv, "--ping"))
{
argc--; argv++;
do_ping = 1;
}
else if (!strcmp (*argv, "--hex"))
{
argc--; argv++;
do_hex = 1;
}
else if (!strcmp (*argv, "--verbose"))
{
argc--; argv++;
verbose = 1;
}
else
print_usage ();
}
if (!argc && do_ping)
; /* This is allowed. */
else if (argc != 1)
print_usage ();
req_nbytes = argc? atoi (*argv) : 0;
if (req_nbytes < 0)
print_usage ();
/* Create a socket. */
fd = socket (AF_UNIX, SOCK_STREAM, 0);
if (fd == -1)
{
logit ("can't create socket: %s", strerror (errno));
exit (1);
}
srvr_addr = malloc (sizeof *srvr_addr);
if (!srvr_addr)
{
logit ("malloc failed: %s", strerror (errno));
exit (1);
}
memset (srvr_addr, 0, sizeof *srvr_addr);
srvr_addr->sun_family = AF_UNIX;
if (strlen (socketname) + 1 >= sizeof (srvr_addr->sun_path))
{
logit ("socket name `%s' too long", socketname);
exit (1);
}
strcpy (srvr_addr->sun_path, socketname);
addrlen = (offsetof (struct sockaddr_un, sun_path)
+ strlen (srvr_addr->sun_path) + 1);
rc = connect (fd, (struct sockaddr*) srvr_addr, addrlen);
if (rc == -1)
{
logit ("error connecting socket `%s': %s",
srvr_addr->sun_path, strerror (errno));
close (fd);
exit (1);
}
do
{
nbytes = req_nbytes > 255? 255 : req_nbytes;
req_nbytes -= nbytes;
buffer[0] = 3;
if (do_ping)
buffer[1] = 0;
else if (get_nonce)
buffer[1] = 10;
else if (get_very_strong)
buffer[1] = 12;
else
buffer[1] = 11;
buffer[2] = nbytes;
if (writen (fd, buffer, 3))
fail = 1;
else
{
for (nleft=2, nread=0; nleft > 0; )
{
do
n = read (fd, buffer+nread, nleft);
while (n < 0 && errno == EINTR);
if (n < 0)
{
logit ("read error: %s", strerror (errno));
exit (1);
}
nleft -= n;
nread += n;
if (nread && buffer[0])
{
logit ("server returned error code %d", buffer[0]);
exit (1);
}
}
if (verbose)
logit ("received response with %d bytes of data", buffer[1]);
if (buffer[1] < nbytes)
{
logit ("warning: server returned less bytes than requested");
fail = 1;
}
else if (buffer[1] > nbytes && !do_ping)
{
logit ("warning: server returned more bytes than requested");
fail = 1;
}
nbytes = buffer[1];
if (nbytes > sizeof buffer)
{
logit ("buffer too short to receive data");
exit (1);
}
for (nleft=nbytes, nread=0; nleft > 0; )
{
do
n = read (fd, buffer+nread, nleft);
while (n < 0 && errno == EINTR);
if (n < 0)
{
logit ("read error: %s", strerror (errno));
exit (1);
}
nleft -= n;
nread += n;
}
if (do_hex)
{
for (n=0; n < nbytes; n++)
{
if (!n)
;
else if (!(n % 16))
putchar ('\n');
else
putchar (' ');
printf ("%02X", buffer[n]);
}
if (nbytes)
putchar ('\n');
}
else
{
if (fwrite (buffer, nbytes, 1, stdout) != 1)
{
logit ("error writing to stdout: %s", strerror (errno));
fail = 1;
}
}
}
}
while (!fail && req_nbytes);
close (fd);
free (srvr_addr);
return fail? 1 : 0;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,795 @@
/* hmac256.c - Standalone HMAC implementation
* Copyright (C) 2003, 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 <http://www.gnu.org/licenses/>.
*/
/*
This is a standalone HMAC-SHA-256 implementation based on the code
from ../cipher/sha256.c. It is a second implementation to allow
comparing against the standard implementations and to be used for
internal consistency checks. It should not be used for sensitive
data because no mechanisms to clear the stack etc are used.
This module may be used standalone and requires only a few
standard definitions to be provided in a config.h file.
Types:
u32 - unsigned 32 bit type.
Constants:
WORDS_BIGENDIAN Defined to 1 on big endian systems.
inline If defined, it should yield the keyword used
to inline a function.
HAVE_U32_TYPEDEF Defined if the u32 type is available.
SIZEOF_UNSIGNED_INT Defined to the size in bytes of an unsigned int.
SIZEOF_UNSIGNED_LONG Defined to the size in bytes of an unsigned long.
STANDALONE Compile a test driver similar to the
sha1sum tool. This driver uses a self-test
identically to the one used by Libcgrypt
for testing this included module.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#if defined(__WIN32) && defined(STANDALONE)
# include <fcntl.h> /* We need setmode(). */
#endif
/* For a native WindowsCE binary we need to include gpg-error.h to
provide a replacement for strerror. In other cases we need a
replacement macro for gpg_err_set_errno. */
#ifdef __MINGW32CE__
# include <gpg-error.h>
#else
# define gpg_err_set_errno(a) (errno = (a))
#endif
#include "hmac256.h"
#ifndef HAVE_U32_TYPEDEF
# undef u32 /* Undef a possible macro with that name. */
# if SIZEOF_UNSIGNED_INT == 4
typedef unsigned int u32;
# elif SIZEOF_UNSIGNED_LONG == 4
typedef unsigned long u32;
# else
# error no typedef for u32
# endif
# define HAVE_U32_TYPEDEF
#endif
/* The context used by this module. */
struct hmac256_context
{
u32 h0, h1, h2, h3, h4, h5, h6, h7;
u32 nblocks;
int count;
int finalized:1;
int use_hmac:1;
unsigned char buf[64];
unsigned char opad[64];
};
/* Rotate a 32 bit word. */
#if defined(__GNUC__) && defined(__i386__)
static inline u32
ror(u32 x, int n)
{
__asm__("rorl %%cl,%0"
:"=r" (x)
:"0" (x),"c" (n));
return x;
}
#else
#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
#endif
#define my_wipememory2(_ptr,_set,_len) do { \
volatile char *_vptr=(volatile char *)(_ptr); \
size_t _vlen=(_len); \
while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
} while(0)
#define my_wipememory(_ptr,_len) my_wipememory2(_ptr,0,_len)
/*
The SHA-256 core: Transform the message X which consists of 16
32-bit-words. See FIPS 180-2 for details.
*/
static void
transform (hmac256_context_t hd, const void *data_arg)
{
const unsigned char *data = data_arg;
#define Cho(x,y,z) (z ^ (x & (y ^ z))) /* (4.2) same as SHA-1's F1 */
#define Maj(x,y,z) ((x & y) | (z & (x|y))) /* (4.3) same as SHA-1's F3 */
#define Sum0(x) (ror ((x), 2) ^ ror ((x), 13) ^ ror ((x), 22)) /* (4.4) */
#define Sum1(x) (ror ((x), 6) ^ ror ((x), 11) ^ ror ((x), 25)) /* (4.5) */
#define S0(x) (ror ((x), 7) ^ ror ((x), 18) ^ ((x) >> 3)) /* (4.6) */
#define S1(x) (ror ((x), 17) ^ ror ((x), 19) ^ ((x) >> 10)) /* (4.7) */
#define R(a,b,c,d,e,f,g,h,k,w) do \
{ \
t1 = (h) + Sum1((e)) + Cho((e),(f),(g)) + (k) + (w); \
t2 = Sum0((a)) + Maj((a),(b),(c)); \
h = g; \
g = f; \
f = e; \
e = d + t1; \
d = c; \
c = b; \
b = a; \
a = t1 + t2; \
} while (0)
static const u32 K[64] =
{
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
u32 a, b, c, d, e, f, g, h, t1, t2;
u32 x[16];
u32 w[64];
int i;
a = hd->h0;
b = hd->h1;
c = hd->h2;
d = hd->h3;
e = hd->h4;
f = hd->h5;
g = hd->h6;
h = hd->h7;
#ifdef WORDS_BIGENDIAN
memcpy (x, data, 64);
#else /*!WORDS_BIGENDIAN*/
{
unsigned char *p2;
for (i=0, p2=(unsigned char*)x; i < 16; i++, p2 += 4 )
{
p2[3] = *data++;
p2[2] = *data++;
p2[1] = *data++;
p2[0] = *data++;
}
}
#endif /*!WORDS_BIGENDIAN*/
for (i=0; i < 16; i++)
w[i] = x[i];
for (; i < 64; i++)
w[i] = S1(w[i-2]) + w[i-7] + S0(w[i-15]) + w[i-16];
for (i=0; i < 64; i++)
R(a,b,c,d,e,f,g,h,K[i],w[i]);
hd->h0 += a;
hd->h1 += b;
hd->h2 += c;
hd->h3 += d;
hd->h4 += e;
hd->h5 += f;
hd->h6 += g;
hd->h7 += h;
}
#undef Cho
#undef Maj
#undef Sum0
#undef Sum1
#undef S0
#undef S1
#undef R
/* Finalize the current SHA256 calculation. */
static void
finalize (hmac256_context_t hd)
{
u32 t, msb, lsb;
unsigned char *p;
if (hd->finalized)
return; /* Silently ignore a finalized context. */
_gcry_hmac256_update (hd, NULL, 0); /* Flush. */
t = hd->nblocks;
/* Multiply by 64 to make a byte count. */
lsb = t << 6;
msb = t >> 26;
/* Add the count. */
t = lsb;
if ((lsb += hd->count) < t)
msb++;
/* Multiply by 8 to make a bit count. */
t = lsb;
lsb <<= 3;
msb <<= 3;
msb |= t >> 29;
if (hd->count < 56)
{ /* Enough room. */
hd->buf[hd->count++] = 0x80; /* pad */
while (hd->count < 56)
hd->buf[hd->count++] = 0; /* pad */
}
else
{ /* Need one extra block. */
hd->buf[hd->count++] = 0x80; /* pad character */
while (hd->count < 64)
hd->buf[hd->count++] = 0;
_gcry_hmac256_update (hd, NULL, 0); /* Flush. */;
memset (hd->buf, 0, 56 ); /* Zero out next next block. */
}
/* Append the 64 bit count. */
hd->buf[56] = msb >> 24;
hd->buf[57] = msb >> 16;
hd->buf[58] = msb >> 8;
hd->buf[59] = msb;
hd->buf[60] = lsb >> 24;
hd->buf[61] = lsb >> 16;
hd->buf[62] = lsb >> 8;
hd->buf[63] = lsb;
transform (hd, hd->buf);
/* Store the digest into hd->buf. */
p = hd->buf;
#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \
*p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
X(0);
X(1);
X(2);
X(3);
X(4);
X(5);
X(6);
X(7);
#undef X
hd->finalized = 1;
}
/* Create a new context. On error NULL is returned and errno is set
appropriately. If KEY is given the function computes HMAC using
this key; with KEY given as NULL, a plain SHA-256 digest is
computed. */
hmac256_context_t
_gcry_hmac256_new (const void *key, size_t keylen)
{
hmac256_context_t hd;
hd = malloc (sizeof *hd);
if (!hd)
return NULL;
hd->h0 = 0x6a09e667;
hd->h1 = 0xbb67ae85;
hd->h2 = 0x3c6ef372;
hd->h3 = 0xa54ff53a;
hd->h4 = 0x510e527f;
hd->h5 = 0x9b05688c;
hd->h6 = 0x1f83d9ab;
hd->h7 = 0x5be0cd19;
hd->nblocks = 0;
hd->count = 0;
hd->finalized = 0;
hd->use_hmac = 0;
if (key)
{
int i;
unsigned char ipad[64];
memset (ipad, 0, 64);
memset (hd->opad, 0, 64);
if (keylen <= 64)
{
memcpy (ipad, key, keylen);
memcpy (hd->opad, key, keylen);
}
else
{
hmac256_context_t tmphd;
tmphd = _gcry_hmac256_new (NULL, 0);
if (!tmphd)
{
free (hd);
return NULL;
}
_gcry_hmac256_update (tmphd, key, keylen);
finalize (tmphd);
memcpy (ipad, tmphd->buf, 32);
memcpy (hd->opad, tmphd->buf, 32);
_gcry_hmac256_release (tmphd);
}
for (i=0; i < 64; i++)
{
ipad[i] ^= 0x36;
hd->opad[i] ^= 0x5c;
}
hd->use_hmac = 1;
_gcry_hmac256_update (hd, ipad, 64);
my_wipememory (ipad, 64);
}
return hd;
}
/* Release a context created by _gcry_hmac256_new. CTX may be NULL
in which case the function does nothing. */
void
_gcry_hmac256_release (hmac256_context_t ctx)
{
if (ctx)
{
/* Note: We need to take care not to modify errno. */
if (ctx->use_hmac)
my_wipememory (ctx->opad, 64);
free (ctx);
}
}
/* Update the message digest with the contents of BUFFER containing
LENGTH bytes. */
void
_gcry_hmac256_update (hmac256_context_t hd,
const void *buffer, size_t length)
{
const unsigned char *inbuf = buffer;
if (hd->finalized)
return; /* Silently ignore a finalized context. */
if (hd->count == 64)
{
/* Flush the buffer. */
transform (hd, hd->buf);
hd->count = 0;
hd->nblocks++;
}
if (!inbuf)
return; /* Only flushing was requested. */
if (hd->count)
{
for (; length && hd->count < 64; length--)
hd->buf[hd->count++] = *inbuf++;
_gcry_hmac256_update (hd, NULL, 0); /* Flush. */
if (!length)
return;
}
while (length >= 64)
{
transform (hd, inbuf);
hd->count = 0;
hd->nblocks++;
length -= 64;
inbuf += 64;
}
for (; length && hd->count < 64; length--)
hd->buf[hd->count++] = *inbuf++;
}
/* Finalize an operation and return the digest. If R_DLEN is not NULL
the length of the digest will be stored at that address. The
returned value is valid as long as the context exists. On error
NULL is returned. */
const void *
_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen)
{
finalize (hd);
if (hd->use_hmac)
{
hmac256_context_t tmphd;
tmphd = _gcry_hmac256_new (NULL, 0);
if (!tmphd)
{
free (hd);
return NULL;
}
_gcry_hmac256_update (tmphd, hd->opad, 64);
_gcry_hmac256_update (tmphd, hd->buf, 32);
finalize (tmphd);
memcpy (hd->buf, tmphd->buf, 32);
_gcry_hmac256_release (tmphd);
}
if (r_dlen)
*r_dlen = 32;
return (void*)hd->buf;
}
/* Convenience function to compute the HMAC-SHA256 of one file. The
user needs to provide a buffer RESULT of at least 32 bytes, he
needs to put the size of the buffer into RESULTSIZE and the
FILENAME. KEY and KEYLEN are as described for _gcry_hmac256_new.
On success the function returns the valid length of the result
buffer (which will be 32) or -1 on error. On error ERRNO is set
appropriate. */
int
_gcry_hmac256_file (void *result, size_t resultsize, const char *filename,
const void *key, size_t keylen)
{
FILE *fp;
hmac256_context_t hd;
size_t buffer_size, nread, digestlen;
char *buffer;
const unsigned char *digest;
fp = fopen (filename, "rb");
if (!fp)
return -1;
hd = _gcry_hmac256_new (key, keylen);
if (!hd)
{
fclose (fp);
return -1;
}
buffer_size = 32768;
buffer = malloc (buffer_size);
if (!buffer)
{
fclose (fp);
_gcry_hmac256_release (hd);
return -1;
}
while ( (nread = fread (buffer, 1, buffer_size, fp)))
_gcry_hmac256_update (hd, buffer, nread);
free (buffer);
if (ferror (fp))
{
fclose (fp);
_gcry_hmac256_release (hd);
return -1;
}
fclose (fp);
digest = _gcry_hmac256_finalize (hd, &digestlen);
if (!digest)
{
_gcry_hmac256_release (hd);
return -1;
}
if (digestlen > resultsize)
{
_gcry_hmac256_release (hd);
gpg_err_set_errno (EINVAL);
return -1;
}
memcpy (result, digest, digestlen);
_gcry_hmac256_release (hd);
return digestlen;
}
#ifdef STANDALONE
static int
selftest (void)
{
static struct
{
const char * const desc;
const char * const data;
const char * const key;
const unsigned char expect[32];
} tv[] =
{
{ "data-28 key-4",
"what do ya want for nothing?",
"Jefe",
{ 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
0x5a, 0x00, 0x3f, 0x08, 0x9d, 0x27, 0x39, 0x83,
0x9d, 0xec, 0x58, 0xb9, 0x64, 0xec, 0x38, 0x43 } },
{ "data-9 key-20",
"Hi There",
"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
"\x0b\x0b\x0b\x0b",
{ 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53,
0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b,
0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7,
0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 } },
{ "data-50 key-20",
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
"\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\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",
{ 0x77, 0x3e, 0xa9, 0x1e, 0x36, 0x80, 0x0e, 0x46,
0x85, 0x4d, 0xb8, 0xeb, 0xd0, 0x91, 0x81, 0xa7,
0x29, 0x59, 0x09, 0x8b, 0x3e, 0xf8, 0xc1, 0x22,
0xd9, 0x63, 0x55, 0x14, 0xce, 0xd5, 0x65, 0xfe } },
{ "data-50 key-26",
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
"\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\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",
{ 0x82, 0x55, 0x8a, 0x38, 0x9a, 0x44, 0x3c, 0x0e,
0xa4, 0xcc, 0x81, 0x98, 0x99, 0xf2, 0x08, 0x3a,
0x85, 0xf0, 0xfa, 0xa3, 0xe5, 0x78, 0xf8, 0x07,
0x7a, 0x2e, 0x3f, 0xf4, 0x67, 0x29, 0x66, 0x5b } },
{ "data-54 key-131",
"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",
{ 0x60, 0xe4, 0x31, 0x59, 0x1e, 0xe0, 0xb6, 0x7f,
0x0d, 0x8a, 0x26, 0xaa, 0xcb, 0xf5, 0xb7, 0x7f,
0x8e, 0x0b, 0xc6, 0x21, 0x37, 0x28, 0xc5, 0x14,
0x05, 0x46, 0x04, 0x0f, 0x0e, 0xe3, 0x7f, 0x54 } },
{ "data-152 key-131",
"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",
{ 0x9b, 0x09, 0xff, 0xa7, 0x1b, 0x94, 0x2f, 0xcb,
0x27, 0x63, 0x5f, 0xbc, 0xd5, 0xb0, 0xe9, 0x44,
0xbf, 0xdc, 0x63, 0x64, 0x4f, 0x07, 0x13, 0x93,
0x8a, 0x7f, 0x51, 0x53, 0x5c, 0x3a, 0x35, 0xe2 } },
{ NULL }
};
int tvidx;
for (tvidx=0; tv[tvidx].desc; tvidx++)
{
hmac256_context_t hmachd;
const unsigned char *digest;
size_t dlen;
hmachd = _gcry_hmac256_new (tv[tvidx].key, strlen (tv[tvidx].key));
if (!hmachd)
return -1;
_gcry_hmac256_update (hmachd, tv[tvidx].data, strlen (tv[tvidx].data));
digest = _gcry_hmac256_finalize (hmachd, &dlen);
if (!digest)
{
_gcry_hmac256_release (hmachd);
return -1;
}
if (dlen != sizeof (tv[tvidx].expect)
|| memcmp (digest, tv[tvidx].expect, sizeof (tv[tvidx].expect)))
{
_gcry_hmac256_release (hmachd);
return -1;
}
_gcry_hmac256_release (hmachd);
}
return 0; /* Succeeded. */
}
int
main (int argc, char **argv)
{
const char *pgm;
int last_argc = -1;
const char *key;
size_t keylen;
FILE *fp;
hmac256_context_t hd;
const unsigned char *digest;
char buffer[4096];
size_t n, dlen, idx;
int use_stdin = 0;
int use_binary = 0;
assert (sizeof (u32) == 4);
#ifdef __WIN32
setmode (fileno (stdin), O_BINARY);
#endif
if (argc)
{
pgm = strrchr (*argv, '/');
if (pgm)
pgm++;
else
pgm = *argv;
argc--; argv++;
}
else
pgm = "?";
while (argc && last_argc != argc )
{
last_argc = argc;
if (!strcmp (*argv, "--"))
{
argc--; argv++;
break;
}
else if (!strcmp (*argv, "--version"))
{
fputs ("hmac256 (Libgcrypt) " VERSION "\n"
"Copyright (C) 2008 Free Software Foundation, Inc.\n"
"License LGPLv2.1+: GNU LGPL version 2.1 or later "
"<http://gnu.org/licenses/old-licenses/lgpl-2.1.html>\n"
"This is free software: you are free to change and "
"redistribute it.\n"
"There is NO WARRANTY, to the extent permitted by law.\n",
stdout);
exit (0);
}
else if (!strcmp (*argv, "--binary"))
{
argc--; argv++;
use_binary = 1;
}
}
if (argc < 1)
{
fprintf (stderr, "usage: %s [--binary] key [filename]\n", pgm);
exit (1);
}
#ifdef __WIN32
if (use_binary)
setmode (fileno (stdout), O_BINARY);
#endif
key = *argv;
argc--, argv++;
keylen = strlen (key);
use_stdin = !argc;
if (selftest ())
{
fprintf (stderr, "%s: fatal error: self-test failed\n", pgm);
exit (2);
}
for (; argc || use_stdin; argv++, argc--)
{
const char *fname = use_stdin? "-" : *argv;
fp = use_stdin? stdin : fopen (fname, "rb");
if (!fp)
{
fprintf (stderr, "%s: can't open `%s': %s\n",
pgm, fname, strerror (errno));
exit (1);
}
hd = _gcry_hmac256_new (key, keylen);
if (!hd)
{
fprintf (stderr, "%s: can't allocate context: %s\n",
pgm, strerror (errno));
exit (1);
}
while ( (n = fread (buffer, 1, sizeof buffer, fp)))
_gcry_hmac256_update (hd, buffer, n);
if (ferror (fp))
{
fprintf (stderr, "%s: error reading `%s': %s\n",
pgm, fname, strerror (errno));
exit (1);
}
if (!use_stdin)
fclose (fp);
digest = _gcry_hmac256_finalize (hd, &dlen);
if (!digest)
{
fprintf (stderr, "%s: error computing HMAC: %s\n",
pgm, strerror (errno));
exit (1);
}
if (use_binary)
{
if (fwrite (digest, dlen, 1, stdout) != 1)
{
fprintf (stderr, "%s: error writing output: %s\n",
pgm, strerror (errno));
exit (1);
}
if (use_stdin)
break;
}
else
{
for (idx=0; idx < dlen; idx++)
printf ("%02x", digest[idx]);
_gcry_hmac256_release (hd);
if (use_stdin)
{
putchar ('\n');
break;
}
printf (" %s\n", fname);
}
}
return 0;
}
#endif /*STANDALONE*/
/*
Local Variables:
compile-command: "cc -Wall -g -I.. -DSTANDALONE -o hmac256 hmac256.c"
End:
*/

View file

@ -0,0 +1,36 @@
/* hmac256.h - Declarations for _gcry_hmac256
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef HMAC256_H
#define HMAC256_H
struct hmac256_context;
typedef struct hmac256_context *hmac256_context_t;
hmac256_context_t _gcry_hmac256_new (const void *key, size_t keylen);
void _gcry_hmac256_update (hmac256_context_t hd, const void *buf, size_t len);
const void *_gcry_hmac256_finalize (hmac256_context_t hd, size_t *r_dlen);
void _gcry_hmac256_release (hmac256_context_t hd);
int _gcry_hmac256_file (void *result, size_t resultsize, const char *filename,
const void *key, size_t keylen);
#endif /*HMAC256_H*/

View file

@ -0,0 +1,192 @@
/* hwfeatures.c - Detect hardware features.
* Copyright (C) 2007, 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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include "g10lib.h"
/* A bit vector describing the hardware features currently
available. */
static unsigned int hw_features;
/* Return a bit vector describing the available hardware features.
The HWF_ constants are used to test for them. */
unsigned int
_gcry_get_hw_features (void)
{
return hw_features;
}
#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
static void
detect_ia32_gnuc (void)
{
/* The code here is only useful for the PadLock engine thus we don't
build it if that support has been disabled. */
int has_cpuid = 0;
char vendor_id[12+1];
/* Detect the CPUID feature by testing some undefined behaviour (16
vs 32 bit pushf/popf). */
asm volatile
("pushf\n\t" /* Copy flags to EAX. */
"popl %%eax\n\t"
"movl %%eax, %%ecx\n\t" /* Save flags into ECX. */
"xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags. */
"pushl %%eax\n\t"
"popf\n\t"
"pushf\n\t" /* Copy changed flags again to EAX. */
"popl %%eax\n\t"
"pushl %%ecx\n\t" /* Restore flags from ECX. */
"popf\n\t"
"xorl %%eax, %%ecx\n\t" /* Compare flags against saved flags. */
"jz .Lno_cpuid%=\n\t" /* Toggling did not work, thus no CPUID. */
"movl $1, %0\n" /* Worked. true -> HAS_CPUID. */
".Lno_cpuid%=:\n\t"
: "+r" (has_cpuid)
:
: "%eax", "%ecx", "cc"
);
if (!has_cpuid)
return; /* No way. */
asm volatile
("pushl %%ebx\n\t" /* Save GOT register. */
"xorl %%eax, %%eax\n\t" /* 0 -> EAX. */
"cpuid\n\t" /* Get vendor ID. */
"movl %%ebx, (%0)\n\t" /* EBX,EDX,ECX -> VENDOR_ID. */
"movl %%edx, 4(%0)\n\t"
"movl %%ecx, 8(%0)\n\t"
"popl %%ebx\n"
:
: "S" (&vendor_id[0])
: "%eax", "%ecx", "%edx", "cc"
);
vendor_id[12] = 0;
if (0)
; /* Just to make "else if" and ifdef macros look pretty. */
#ifdef ENABLE_PADLOCK_SUPPORT
else if (!strcmp (vendor_id, "CentaurHauls"))
{
/* This is a VIA CPU. Check what PadLock features we have. */
asm volatile
("pushl %%ebx\n\t" /* Save GOT register. */
"movl $0xC0000000, %%eax\n\t" /* Check for extended centaur */
"cpuid\n\t" /* feature flags. */
"popl %%ebx\n\t" /* Restore GOT register. */
"cmpl $0xC0000001, %%eax\n\t"
"jb .Lready%=\n\t" /* EAX < 0xC0000000 => no padlock. */
"pushl %%ebx\n\t" /* Save GOT register. */
"movl $0xC0000001, %%eax\n\t" /* Ask for the extended */
"cpuid\n\t" /* feature flags. */
"popl %%ebx\n\t" /* Restore GOT register. */
"movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
"andl $0x0C, %%eax\n\t" /* Test bits 2 and 3 to see whether */
"cmpl $0x0C, %%eax\n\t" /* the RNG exists and is enabled. */
"jnz .Lno_rng%=\n\t"
"orl $1, %0\n" /* Set our HWF_PADLOCK_RNG bit. */
".Lno_rng%=:\n\t"
"movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
"andl $0xC0, %%eax\n\t" /* Test bits 6 and 7 to see whether */
"cmpl $0xC0, %%eax\n\t" /* the ACE exists and is enabled. */
"jnz .Lno_ace%=\n\t"
"orl $2, %0\n" /* Set our HWF_PADLOCK_AES bit. */
".Lno_ace%=:\n\t"
"movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
"andl $0xC00, %%eax\n\t" /* Test bits 10, 11 to see whether */
"cmpl $0xC00, %%eax\n\t" /* the PHE exists and is enabled. */
"jnz .Lno_phe%=\n\t"
"orl $4, %0\n" /* Set our HWF_PADLOCK_SHA bit. */
".Lno_phe%=:\n\t"
"movl %%edx, %%eax\n\t" /* Take copy of feature flags. */
"andl $0x3000, %%eax\n\t" /* Test bits 12, 13 to see whether */
"cmpl $0x3000, %%eax\n\t" /* MONTMUL exists and is enabled. */
"jnz .Lready%=\n\t"
"orl $8, %0\n" /* Set our HWF_PADLOCK_MMUL bit. */
".Lready%=:\n"
: "+r" (hw_features)
:
: "%eax", "%edx", "cc"
);
}
#endif /*ENABLE_PADLOCK_SUPPORT*/
else if (!strcmp (vendor_id, "GenuineIntel"))
{
/* This is an Intel CPU. */
asm volatile
("pushl %%ebx\n\t" /* Save GOT register. */
"movl $1, %%eax\n\t" /* Get CPU info and feature flags. */
"cpuid\n"
"popl %%ebx\n\t" /* Restore GOT register. */
"testl $0x02000000, %%ecx\n\t" /* Test bit 25. */
"jz .Lno_aes%=\n\t" /* No AES support. */
"orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */
".Lno_aes%=:\n"
: "+r" (hw_features)
:
: "%eax", "%ecx", "%edx", "cc"
);
}
else if (!strcmp (vendor_id, "AuthenticAMD"))
{
/* This is an AMD CPU. */
}
}
#endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */
/* Detect the available hardware features. This function is called
once right at startup and we assume that no other threads are
running. */
void
_gcry_detect_hw_features (unsigned int disabled_features)
{
hw_features = 0;
if (fips_mode ())
return; /* Hardware support is not to be evaluated. */
#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4
#ifdef __GNUC__
detect_ia32_gnuc ();
#endif
#elif defined (__i386__) && SIZEOF_UNSIGNED_LONG == 8
#ifdef __GNUC__
#endif
#endif
hw_features &= ~disabled_features;
}

View file

@ -0,0 +1,189 @@
#!/bin/sh
# Copyright (C) 1999, 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# File: @configure_input@
# General.
prefix="@prefix@"
exec_prefix="@exec_prefix@"
version="@VERSION@"
includedir="@includedir@"
libdir="@libdir@"
gpg_error_libs="@GPG_ERROR_LIBS@"
gpg_error_cflags="@GPG_ERROR_CFLAGS@"
# libgcrypt values.
libs="@LIBGCRYPT_CONFIG_LIBS@"
cflags="@LIBGCRYPT_CONFIG_CFLAGS@"
# API info
api_version="@LIBGCRYPT_CONFIG_API_VERSION@"
# Configured for host
my_host="@LIBGCRYPT_CONFIG_HOST@"
# Misc information.
symmetric_ciphers="@LIBGCRYPT_CIPHERS@"
asymmetric_ciphers="@LIBGCRYPT_PUBKEY_CIPHERS@"
digests="@LIBGCRYPT_DIGESTS@"
# State variables.
echo_libs=no
echo_cflags=no
echo_prefix=no
echo_algorithms=no
echo_exec_prefix=no
echo_version=no
echo_api_version=no
echo_host=no
# Prints usage information.
usage()
{
cat <<EOF
Usage: $0 [OPTIONS]
Options:
[--prefix]
[--exec-prefix]
[--version]
[--api-version]
[--libs]
[--cflags]
[--algorithms]
[--host]
EOF
exit $1
}
if test $# -eq 0; then
# Nothing to do.
usage 1 1>&2
fi
while test $# -gt 0; do
case "$1" in
# Set up `optarg'.
--*=*)
optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
;;
*)
optarg=""
;;
esac
case $1 in
--thread=*)
echo "$0: --thread option obsolete: use the thread callback interface" 1>&2
exit 1
;;
--prefix=*)
# For compatibility reasons with old M4 macros, we ignore
# setting of prefix.
;;
--prefix)
echo_prefix=yes
;;
--exec-prefix=*)
;;
--exec-prefix)
echo_exec_prefix=yes
;;
--version)
echo_version=yes
;;
--api-version)
echo_api_version=yes
;;
--cflags)
echo_cflags=yes
;;
--libs)
echo_libs=yes
;;
--algorithms)
echo_algorithms=yes
;;
--host)
echo_host=yes
;;
*)
usage 1 1>&2
;;
esac
shift
done
if test "$echo_prefix" = "yes"; then
echo "$prefix"
fi
if test "$echo_exec_prefix" = "yes"; then
echo "$exec_prefix"
fi
if test "$echo_cflags" = "yes"; then
includes=""
cflags_final="$cflags"
# Set up `includes'.
if test "x$includedir" != "x/usr/include" -a "x$includedir" != "x/include"; then
includes="-I$includedir"
fi
# Set up `cflags_final'.
cflags_final="$cflags_final $gpg_error_cflags"
tmp=""
for i in $includes $cflags_final; do
if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then
tmp="$tmp $i"
fi
done
echo $tmp
fi
if test "$echo_libs" = "yes"; then
libdirs=""
libs_final="$libs"
# Set up `libdirs'.
if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib"; then
libdirs="-L$libdir"
fi
# Set up `libs_final'.
libs_final="$libs_final $gpg_error_libs"
tmp=""
for i in $libdirs $libs_final; do
if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then
tmp="$tmp $i"
fi
done
echo $tmp
fi
if test "$echo_version" = "yes"; then
echo "$version"
fi
if test "$echo_api_version" = "yes"; then
echo "$api_version"
fi
if test "$echo_host" = "yes"; then
echo "$my_host"
fi
if test "$echo_algorithms" = "yes"; then
echo "Symmetric cipher algorithms: $symmetric_ciphers"
echo "Public-key cipher algorithms: $asymmetric_ciphers"
echo "Message digest algorithms: $digests"
fi

View file

@ -0,0 +1,213 @@
;; libgcrypt.defs - Exported symbols for W32
;; Copyright (C) 2003, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
;;
;; Note: This file should be updated manually and the ordinals shall
;; never be changed. Also check libgcrypt.vers and visibility.h.
EXPORTS
gcry_check_version @1
gcry_control @2
gcry_malloc @3
gcry_calloc @4
gcry_malloc_secure @5
gcry_calloc_secure @6
gcry_realloc @7
gcry_strdup @8
gcry_xmalloc @9
gcry_xcalloc @10
gcry_xmalloc_secure @11
gcry_xcalloc_secure @12
gcry_xrealloc @13
gcry_xstrdup @14
gcry_is_secure @15
gcry_free @16
gcry_set_progress_handler @17
gcry_set_allocation_handler @18
gcry_set_outofcore_handler @19
gcry_set_fatalerror_handler @20
gcry_set_log_handler @21
gcry_set_gettext_handler @22
gcry_strerror @23
gcry_strsource @24
gcry_err_code_from_errno @25
gcry_err_code_to_errno @26
gcry_err_make_from_errno @27
gcry_error_from_errno @28
gcry_sexp_new @29
gcry_sexp_create @30
gcry_sexp_sscan @31
gcry_sexp_build @32
gcry_sexp_build_array @33
gcry_sexp_release @34
gcry_sexp_canon_len @35
gcry_sexp_sprint @36
gcry_sexp_dump @37
gcry_sexp_cons @38
gcry_sexp_alist @39
gcry_sexp_vlist @40
gcry_sexp_append @41
gcry_sexp_prepend @42
gcry_sexp_find_token @43
gcry_sexp_length @44
gcry_sexp_nth @45
gcry_sexp_car @46
gcry_sexp_cdr @47
gcry_sexp_cadr @48
gcry_sexp_nth_data @49
gcry_sexp_nth_mpi @50
gcry_mpi_new @51
gcry_mpi_snew @52
gcry_mpi_release @53
gcry_mpi_copy @54
gcry_mpi_set @55
gcry_mpi_set_ui @56
gcry_mpi_swap @57
gcry_mpi_cmp @58
gcry_mpi_cmp_ui @59
gcry_mpi_scan @60
gcry_mpi_print @61
gcry_mpi_aprint @62
gcry_mpi_dump @63
gcry_mpi_add @64
gcry_mpi_add_ui @65
gcry_mpi_addm @66
gcry_mpi_sub @67
gcry_mpi_sub_ui @68
gcry_mpi_subm @69
gcry_mpi_mul @70
gcry_mpi_mul_ui @71
gcry_mpi_mulm @72
gcry_mpi_mul_2exp @73
gcry_mpi_div @74
gcry_mpi_mod @75
gcry_mpi_powm @76
gcry_mpi_gcd @77
gcry_mpi_invm @78
gcry_mpi_get_nbits @79
gcry_mpi_test_bit @80
gcry_mpi_set_bit @81
gcry_mpi_clear_bit @82
gcry_mpi_set_highbit @83
gcry_mpi_clear_highbit @84
gcry_mpi_rshift @85
gcry_mpi_set_opaque @86
gcry_mpi_get_opaque @87
gcry_mpi_set_flag @88
gcry_mpi_clear_flag @89
gcry_mpi_get_flag @90
gcry_cipher_open @92
gcry_cipher_close @93
gcry_cipher_ctl @94
gcry_cipher_info @95
gcry_cipher_algo_info @96
gcry_cipher_algo_name @97
gcry_cipher_map_name @98
gcry_cipher_mode_from_oid @99
gcry_cipher_encrypt @100
gcry_cipher_decrypt @101
gcry_cipher_get_algo_keylen @102
gcry_cipher_get_algo_blklen @103
;; @104 used to be part of the module register interface
gcry_pk_encrypt @105
gcry_pk_decrypt @106
gcry_pk_sign @107
gcry_pk_verify @108
gcry_pk_testkey @109
gcry_pk_genkey @110
gcry_pk_ctl @111
gcry_pk_algo_info @112
gcry_pk_algo_name @113
gcry_pk_map_name @114
gcry_pk_get_nbits @115
gcry_pk_get_keygrip @116
;; @117 used to be part of the module register interface
;;
;; 118 to 142 were used in previous Libgcrypt versions for the gcry_ac
;; interface
;;
gcry_md_open @143
gcry_md_close @144
gcry_md_enable @145
gcry_md_copy @146
gcry_md_reset @147
gcry_md_ctl @148
gcry_md_write @149
gcry_md_read @150
gcry_md_hash_buffer @151
gcry_md_get_algo @152
gcry_md_get_algo_dlen @153
gcry_md_is_enabled @154
gcry_md_is_secure @155
gcry_md_info @156
gcry_md_algo_info @157
gcry_md_algo_name @158
gcry_md_map_name @159
gcry_md_setkey @160
;; @161 used to be part of the module register interface
gcry_randomize @162
gcry_random_add_bytes @163
gcry_random_bytes @164
gcry_random_bytes_secure @165
gcry_mpi_randomize @166
gcry_prime_generate @167
gcry_prime_group_generator @168
gcry_prime_release_factors @169
gcry_prime_check @170
gcry_create_nonce @171
gcry_md_debug @172
;; @173 used to be part of the module register interface
;; @174 used to be part of the module register interface
;; @175 used to be part of the module register interface
;; @176 used to be part of the module register interface
;; @177 used to be part of the module register interface
;; @178 used to be part of the module register interface
;;
;; @179 to @186 used to be part of the removed gcry_ac interface
;;
gcry_sexp_nth_string @187
gcry_cipher_setkey @188
gcry_cipher_setiv @189
gcry_cipher_setctr @190
gcry_mpi_lshift @191
gcry_pk_get_curve @192
gcry_pk_get_param @193
gcry_kdf_derive @194

View file

@ -0,0 +1,122 @@
dnl Autoconf macros for libgcrypt
dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc.
dnl
dnl This file is free software; as a special exception the author gives
dnl unlimited permission to copy and/or distribute it, with or without
dnl modifications, as long as this notice is preserved.
dnl
dnl This file is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
dnl implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
dnl [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
dnl Test for libgcrypt and define LIBGCRYPT_CFLAGS and LIBGCRYPT_LIBS.
dnl MINIMUN-VERSION is a string with the version number optionalliy prefixed
dnl with the API version to also check the API compatibility. Example:
dnl a MINIMUN-VERSION of 1:1.2.5 won't pass the test unless the installed
dnl version of libgcrypt is at least 1.2.5 *and* the API number is 1. Using
dnl this features allows to prevent build against newer versions of libgcrypt
dnl with a changed API.
dnl
AC_DEFUN([AM_PATH_LIBGCRYPT],
[ AC_REQUIRE([AC_CANONICAL_HOST])
AC_ARG_WITH(libgcrypt-prefix,
AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
[prefix where LIBGCRYPT is installed (optional)]),
libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
if test x$libgcrypt_config_prefix != x ; then
if test x${LIBGCRYPT_CONFIG+set} != xset ; then
LIBGCRYPT_CONFIG=$libgcrypt_config_prefix/bin/libgcrypt-config
fi
fi
AC_PATH_TOOL(LIBGCRYPT_CONFIG, libgcrypt-config, no)
tmp=ifelse([$1], ,1:1.2.0,$1)
if echo "$tmp" | grep ':' >/dev/null 2>/dev/null ; then
req_libgcrypt_api=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\1/'`
min_libgcrypt_version=`echo "$tmp" | sed 's/\(.*\):\(.*\)/\2/'`
else
req_libgcrypt_api=0
min_libgcrypt_version="$tmp"
fi
AC_MSG_CHECKING(for LIBGCRYPT - version >= $min_libgcrypt_version)
ok=no
if test "$LIBGCRYPT_CONFIG" != "no" ; then
req_major=`echo $min_libgcrypt_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\1/'`
req_minor=`echo $min_libgcrypt_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\2/'`
req_micro=`echo $min_libgcrypt_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\)/\3/'`
libgcrypt_config_version=`$LIBGCRYPT_CONFIG --version`
major=`echo $libgcrypt_config_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\1/'`
minor=`echo $libgcrypt_config_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\2/'`
micro=`echo $libgcrypt_config_version | \
sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\.\([[0-9]]*\).*/\3/'`
if test "$major" -gt "$req_major"; then
ok=yes
else
if test "$major" -eq "$req_major"; then
if test "$minor" -gt "$req_minor"; then
ok=yes
else
if test "$minor" -eq "$req_minor"; then
if test "$micro" -ge "$req_micro"; then
ok=yes
fi
fi
fi
fi
fi
fi
if test $ok = yes; then
AC_MSG_RESULT([yes ($libgcrypt_config_version)])
else
AC_MSG_RESULT(no)
fi
if test $ok = yes; then
# If we have a recent libgcrypt, we should also check that the
# API is compatible
if test "$req_libgcrypt_api" -gt 0 ; then
tmp=`$LIBGCRYPT_CONFIG --api-version 2>/dev/null || echo 0`
if test "$tmp" -gt 0 ; then
AC_MSG_CHECKING([LIBGCRYPT API version])
if test "$req_libgcrypt_api" -eq "$tmp" ; then
AC_MSG_RESULT([okay])
else
ok=no
AC_MSG_RESULT([does not match. want=$req_libgcrypt_api got=$tmp])
fi
fi
fi
fi
if test $ok = yes; then
LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
ifelse([$2], , :, [$2])
libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
if test x"$libgcrypt_config_host" != xnone ; then
if test x"$libgcrypt_config_host" != x"$host" ; then
AC_MSG_WARN([[
***
*** The config script $LIBGCRYPT_CONFIG was
*** built for $libgcrypt_config_host and thus may not match the
*** used host $host.
*** You may want to use the configure option --with-libgcrypt-prefix
*** to specify a matching config script.
***]])
fi
fi
else
LIBGCRYPT_CFLAGS=""
LIBGCRYPT_LIBS=""
ifelse([$3], , :, [$3])
fi
AC_SUBST(LIBGCRYPT_CFLAGS)
AC_SUBST(LIBGCRYPT_LIBS)
])

View file

@ -0,0 +1,94 @@
# libgcrypt.vers - What symbols to export -*- std -*-
# Copyright (C) 2002, 2004, 2008, 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
# NOTE: When adding new functions, please make sure to add them to
# visibility.h and libgcrypt.def as well.
GCRYPT_1.6 {
global:
gcry_check_version; gcry_control;
gcry_set_allocation_handler; gcry_set_fatalerror_handler;
gcry_set_gettext_handler; gcry_set_log_handler;
gcry_set_outofcore_handler; gcry_set_progress_handler;
gcry_err_code_from_errno; gcry_err_code_to_errno;
gcry_err_make_from_errno; gcry_error_from_errno;
gcry_strerror; gcry_strsource;
gcry_free; gcry_malloc; gcry_malloc_secure; gcry_calloc;
gcry_calloc_secure; gcry_realloc; gcry_strdup; gcry_is_secure;
gcry_xcalloc; gcry_xcalloc_secure; gcry_xmalloc;
gcry_xmalloc_secure; gcry_xrealloc; gcry_xstrdup;
gcry_md_algo_info; gcry_md_algo_name; gcry_md_close;
gcry_md_copy; gcry_md_ctl; gcry_md_enable; gcry_md_get;
gcry_md_get_algo; gcry_md_get_algo_dlen; gcry_md_hash_buffer;
gcry_md_info; gcry_md_is_enabled; gcry_md_is_secure;
gcry_md_map_name; gcry_md_open; gcry_md_read;
gcry_md_reset; gcry_md_setkey;
gcry_md_write; gcry_md_debug;
gcry_cipher_algo_info; gcry_cipher_algo_name; gcry_cipher_close;
gcry_cipher_ctl; gcry_cipher_decrypt; gcry_cipher_encrypt;
gcry_cipher_get_algo_blklen; gcry_cipher_get_algo_keylen;
gcry_cipher_info; gcry_cipher_map_name;
gcry_cipher_mode_from_oid; gcry_cipher_open;
gcry_cipher_setkey; gcry_cipher_setiv; gcry_cipher_setctr;
gcry_pk_algo_info; gcry_pk_algo_name; gcry_pk_ctl;
gcry_pk_decrypt; gcry_pk_encrypt; gcry_pk_genkey;
gcry_pk_get_keygrip; gcry_pk_get_nbits;
gcry_pk_map_name; gcry_pk_register; gcry_pk_sign;
gcry_pk_testkey; gcry_pk_verify;
gcry_pk_get_curve; gcry_pk_get_param;
gcry_kdf_derive;
gcry_prime_check; gcry_prime_generate;
gcry_prime_group_generator; gcry_prime_release_factors;
gcry_random_add_bytes; gcry_random_bytes; gcry_random_bytes_secure;
gcry_randomize; gcry_create_nonce;
gcry_sexp_alist; gcry_sexp_append; gcry_sexp_build;
gcry_sexp_build_array; gcry_sexp_cadr; gcry_sexp_canon_len;
gcry_sexp_car; gcry_sexp_cdr; gcry_sexp_cons; gcry_sexp_create;
gcry_sexp_dump; gcry_sexp_find_token; gcry_sexp_length;
gcry_sexp_new; gcry_sexp_nth; gcry_sexp_nth_data;
gcry_sexp_nth_mpi; gcry_sexp_prepend; gcry_sexp_release;
gcry_sexp_sprint; gcry_sexp_sscan; gcry_sexp_vlist;
gcry_sexp_nth_string;
gcry_mpi_add; gcry_mpi_add_ui; gcry_mpi_addm; gcry_mpi_aprint;
gcry_mpi_clear_bit; gcry_mpi_clear_flag; gcry_mpi_clear_highbit;
gcry_mpi_cmp; gcry_mpi_cmp_ui; gcry_mpi_copy; gcry_mpi_div;
gcry_mpi_dump; gcry_mpi_gcd; gcry_mpi_get_flag; gcry_mpi_get_nbits;
gcry_mpi_get_opaque; gcry_mpi_invm; gcry_mpi_mod; gcry_mpi_mul;
gcry_mpi_mul_2exp; gcry_mpi_mul_ui; gcry_mpi_mulm; gcry_mpi_new;
gcry_mpi_powm; gcry_mpi_print; gcry_mpi_randomize; gcry_mpi_release;
gcry_mpi_rshift; gcry_mpi_scan; gcry_mpi_set; gcry_mpi_set_bit;
gcry_mpi_set_flag; gcry_mpi_set_highbit; gcry_mpi_set_opaque;
gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui;
gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit;
gcry_mpi_lshift;
local:
*;
};

View file

@ -0,0 +1,298 @@
/* misc.c
* Copyright (C) 1999, 2001, 2002, 2003, 2007,
* 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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include "g10lib.h"
#include "secmem.h"
static int verbosity_level = 0;
static void (*fatal_error_handler)(void*,int, const char*) = NULL;
static void *fatal_error_handler_value = 0;
static void (*log_handler)(void*,int, const char*, va_list) = NULL;
static void *log_handler_value = 0;
static const char *(*user_gettext_handler)( const char * ) = NULL;
void
gcry_set_gettext_handler( const char *(*f)(const char*) )
{
user_gettext_handler = f;
}
const char *
_gcry_gettext( const char *key )
{
if( user_gettext_handler )
return user_gettext_handler( key );
/* FIXME: switch the domain to gnupg and restore later */
return key;
}
void
gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value)
{
fatal_error_handler_value = value;
fatal_error_handler = fnc;
}
static void
write2stderr( const char *s )
{
/* Dummy variable to silence gcc warning. */
int res = write( 2, s, strlen(s) );
(void) res;
}
/*
* This function is called for fatal errors. A caller might want to
* set his own handler because this function simply calls abort().
*/
void
_gcry_fatal_error (int rc, const char *text)
{
if ( !text ) /* get a default text */
text = gpg_strerror (rc);
if (fatal_error_handler && !fips_mode () )
fatal_error_handler (fatal_error_handler_value, rc, text);
fips_signal_fatal_error (text);
write2stderr("\nFatal error: ");
write2stderr(text);
write2stderr("\n");
_gcry_secmem_term ();
abort ();
}
void
gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ),
void *opaque )
{
log_handler = f;
log_handler_value = opaque;
}
void
_gcry_set_log_verbosity( int level )
{
verbosity_level = level;
}
int
_gcry_log_verbosity( int level )
{
return verbosity_level >= level;
}
/****************
* This is our log function which prints all log messages to stderr or
* using the function defined with gcry_set_log_handler().
*/
static void
_gcry_logv( int level, const char *fmt, va_list arg_ptr )
{
if (log_handler)
log_handler (log_handler_value, level, fmt, arg_ptr);
else
{
switch (level)
{
case GCRY_LOG_CONT: break;
case GCRY_LOG_INFO: break;
case GCRY_LOG_WARN: break;
case GCRY_LOG_ERROR: break;
case GCRY_LOG_FATAL: fputs("Fatal: ",stderr ); break;
case GCRY_LOG_BUG: fputs("Ohhhh jeeee: ", stderr); break;
case GCRY_LOG_DEBUG: fputs("DBG: ", stderr ); break;
default: fprintf(stderr,"[Unknown log level %d]: ", level ); break;
}
vfprintf(stderr,fmt,arg_ptr) ;
}
if ( level == GCRY_LOG_FATAL || level == GCRY_LOG_BUG )
{
fips_signal_fatal_error ("internal error (fatal or bug)");
_gcry_secmem_term ();
abort ();
}
}
void
_gcry_log( int level, const char *fmt, ... )
{
va_list arg_ptr ;
va_start( arg_ptr, fmt ) ;
_gcry_logv( level, fmt, arg_ptr );
va_end(arg_ptr);
}
#if defined(JNLIB_GCC_M_FUNCTION) || __STDC_VERSION__ >= 199901L
void
_gcry_bug( const char *file, int line, const char *func )
{
_gcry_log( GCRY_LOG_BUG,
("... this is a bug (%s:%d:%s)\n"), file, line, func );
abort(); /* never called, but it makes the compiler happy */
}
void
_gcry_assert_failed (const char *expr, const char *file, int line,
const char *func)
{
_gcry_log (GCRY_LOG_BUG,
("Assertion `%s' failed (%s:%d:%s)\n"), expr, file, line, func );
abort(); /* Never called, but it makes the compiler happy. */
}
#else
void
_gcry_bug( const char *file, int line )
{
_gcry_log( GCRY_LOG_BUG,
_("you found a bug ... (%s:%d)\n"), file, line);
abort(); /* never called, but it makes the compiler happy */
}
void
_gcry_assert_failed (const char *expr, const char *file, int line)
{
_gcry_log (GCRY_LOG_BUG,
("Assertion `%s' failed (%s:%d)\n"), expr, file, line);
abort(); /* Never called, but it makes the compiler happy. */
}
#endif
void
_gcry_log_info( const char *fmt, ... )
{
va_list arg_ptr ;
va_start( arg_ptr, fmt ) ;
_gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
va_end(arg_ptr);
}
int
_gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
{
va_list arg_ptr;
(void)fp;
va_start( arg_ptr, fmt ) ;
_gcry_logv( GCRY_LOG_INFO, fmt, arg_ptr );
va_end(arg_ptr);
return 0;
}
void
_gcry_log_error( const char *fmt, ... )
{
va_list arg_ptr ;
va_start( arg_ptr, fmt ) ;
_gcry_logv( GCRY_LOG_ERROR, fmt, arg_ptr );
va_end(arg_ptr);
}
void
_gcry_log_fatal( const char *fmt, ... )
{
va_list arg_ptr ;
va_start( arg_ptr, fmt ) ;
_gcry_logv( GCRY_LOG_FATAL, fmt, arg_ptr );
va_end(arg_ptr);
abort(); /* never called, but it makes the compiler happy */
}
void
_gcry_log_bug( const char *fmt, ... )
{
va_list arg_ptr ;
va_start( arg_ptr, fmt ) ;
_gcry_logv( GCRY_LOG_BUG, fmt, arg_ptr );
va_end(arg_ptr);
abort(); /* never called, but it makes the compiler happy */
}
void
_gcry_log_debug( const char *fmt, ... )
{
va_list arg_ptr ;
va_start( arg_ptr, fmt ) ;
_gcry_logv( GCRY_LOG_DEBUG, fmt, arg_ptr );
va_end(arg_ptr);
}
void
_gcry_log_printf (const char *fmt, ...)
{
va_list arg_ptr;
if (fmt)
{
va_start( arg_ptr, fmt ) ;
_gcry_logv (GCRY_LOG_CONT, fmt, arg_ptr);
va_end(arg_ptr);
}
}
/* Print a hexdump of BUFFER. With TEXT of NULL print just the raw
dump, with TEXT an empty string, print a trailing linefeed,
otherwise print an entire debug line. */
void
_gcry_log_printhex (const char *text, const void *buffer, size_t length)
{
if (text && *text)
log_debug ("%s ", text);
if (length)
{
const unsigned char *p = buffer;
log_printf ("%02X", *p);
for (length--, p++; length--; p++)
log_printf (" %02X", *p);
}
if (text)
log_printf ("\n");
}
void
_gcry_burn_stack (int bytes)
{
char buf[64];
wipememory (buf, sizeof buf);
bytes -= sizeof buf;
if (bytes > 0)
_gcry_burn_stack (bytes);
}

View file

@ -0,0 +1,54 @@
/* missing-string.c - missing string utilities
* Copyright (C) 1994, 1998, 1999, 2000, 2001,
* 2003 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "g10lib.h"
#ifndef HAVE_STPCPY
char *
stpcpy(char *a,const char *b)
{
while( *b )
*a++ = *b++;
*a = 0;
return (char*)a;
}
#endif
#ifndef HAVE_STRCASECMP
int
strcasecmp( const char *a, const char *b )
{
for( ; *a && *b; a++, b++ ) {
if( *a != *b && toupper(*a) != toupper(*b) )
break;
}
return *(const byte*)a - *(const byte*)b;
}
#endif

View file

@ -0,0 +1,212 @@
/* module.c - Module management for libgcrypt.
* Copyright (C) 2003, 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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <errno.h>
#include "g10lib.h"
/* Please match these numbers with the allocated algorithm
numbers. */
#define MODULE_ID_MIN 600
#define MODULE_ID_LAST 65500
#define MODULE_ID_USER GCRY_MODULE_ID_USER
#define MODULE_ID_USER_LAST GCRY_MODULE_ID_USER_LAST
#if MODULE_ID_MIN >= MODULE_ID_USER
#error Need to implement a different search strategy
#endif
/* Internal function. Generate a new, unique module ID for a module
that should be inserted into the module chain starting at
MODULES. */
static gcry_err_code_t
_gcry_module_id_new (gcry_module_t modules, unsigned int *id_new)
{
unsigned int mod_id;
gcry_err_code_t err = GPG_ERR_NO_ERROR;
gcry_module_t module;
/* Search for unused ID. */
for (mod_id = MODULE_ID_MIN; mod_id < MODULE_ID_LAST; mod_id++)
{
if (mod_id == MODULE_ID_USER)
{
mod_id = MODULE_ID_USER_LAST;
continue;
}
/* Search for a module with the current ID. */
for (module = modules; module; module = module->next)
if (mod_id == module->mod_id)
break;
if (! module)
/* None found -> the ID is available for use. */
break;
}
if (mod_id < MODULE_ID_LAST)
/* Done. */
*id_new = mod_id;
else
/* No free ID found. */
err = GPG_ERR_INTERNAL;
return err;
}
/* Add a module specification to the list ENTRIES. The new module has
it's use-counter set to one. */
gcry_err_code_t
_gcry_module_add (gcry_module_t *entries, unsigned int mod_id,
void *spec, void *extraspec, gcry_module_t *module)
{
gcry_err_code_t err = 0;
gcry_module_t entry;
if (! mod_id)
err = _gcry_module_id_new (*entries, &mod_id);
if (! err)
{
entry = gcry_malloc (sizeof (struct gcry_module));
if (! entry)
err = gpg_err_code_from_errno (errno);
}
if (! err)
{
/* Fill new module entry. */
entry->flags = 0;
entry->counter = 1;
entry->spec = spec;
entry->extraspec = extraspec;
entry->mod_id = mod_id;
/* Link it into the list. */
entry->next = *entries;
entry->prevp = entries;
if (*entries)
(*entries)->prevp = &entry->next;
*entries = entry;
/* And give it to the caller. */
if (module)
*module = entry;
}
return err;
}
/* Internal function. Unlink CIPHER_ENTRY from the list of registered
ciphers and destroy it. */
static void
_gcry_module_drop (gcry_module_t entry)
{
*entry->prevp = entry->next;
if (entry->next)
entry->next->prevp = entry->prevp;
gcry_free (entry);
}
/* Lookup a module specification by it's ID. After a successful
lookup, the module has it's resource counter incremented. */
gcry_module_t
_gcry_module_lookup_id (gcry_module_t entries, unsigned int mod_id)
{
gcry_module_t entry;
for (entry = entries; entry; entry = entry->next)
if (entry->mod_id == mod_id)
{
entry->counter++;
break;
}
return entry;
}
/* Lookup a module specification. After a successful lookup, the
module has it's resource counter incremented. FUNC is a function
provided by the caller, which is responsible for identifying the
wanted module. */
gcry_module_t
_gcry_module_lookup (gcry_module_t entries, void *data,
gcry_module_lookup_t func)
{
gcry_module_t entry;
for (entry = entries; entry; entry = entry->next)
if ((*func) (entry->spec, data))
{
entry->counter++;
break;
}
return entry;
}
/* Release a module. In case the use-counter reaches zero, destroy
the module. Passing MODULE as NULL is a dummy operation (similar
to free()). */
void
_gcry_module_release (gcry_module_t module)
{
if (module && ! --module->counter)
_gcry_module_drop (module);
}
/* Add a reference to a module. */
void
_gcry_module_use (gcry_module_t module)
{
++module->counter;
}
/* If LIST is zero, write the number of modules identified by MODULES
to LIST_LENGTH and return. If LIST is non-zero, the first
*LIST_LENGTH algorithm IDs are stored in LIST, which must be of
according size. In case there are less cipher modules than
*LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
gcry_err_code_t
_gcry_module_list (gcry_module_t modules,
int *list, int *list_length)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
gcry_module_t module;
int length, i;
for (module = modules, length = 0; module; module = module->next, length++);
if (list)
{
if (length > *list_length)
length = *list_length;
for (module = modules, i = 0; i < length; module = module->next, i++)
list[i] = module->mod_id;
if (length < *list_length)
*list_length = length;
}
else
*list_length = length;
return err;
}

View file

@ -0,0 +1,263 @@
/* mpi.h - Multi Precision Integers
* Copyright (C) 1994, 1996, 1998,
* 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
*
* Note: This code is heavily based on the GNU MP Library.
* Actually it's the same code with only minor changes in the
* way the data is stored; this is to support the abstraction
* of an optional secure memory allocation which may be used
* to avoid revealing of sensitive data due to paging etc.
*/
#ifndef G10_MPI_H
#define G10_MPI_H
#include <config.h>
#include <stdio.h>
#include <string.h>
#include "types.h"
#include "../mpi/mpi-asm-defs.h"
#include "g10lib.h"
#ifndef _GCRYPT_IN_LIBGCRYPT
#error this file should only be used inside libgcrypt
#endif
#ifndef BITS_PER_MPI_LIMB
#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_INT
typedef unsigned int mpi_limb_t;
typedef signed int mpi_limb_signed_t;
#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG
typedef unsigned long int mpi_limb_t;
typedef signed long int mpi_limb_signed_t;
#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG
typedef unsigned long long int mpi_limb_t;
typedef signed long long int mpi_limb_signed_t;
#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_SHORT
typedef unsigned short int mpi_limb_t;
typedef signed short int mpi_limb_signed_t;
#else
#error BYTES_PER_MPI_LIMB does not match any C type
#endif
#define BITS_PER_MPI_LIMB (8*BYTES_PER_MPI_LIMB)
#endif /*BITS_PER_MPI_LIMB*/
#define DBG_MPI _gcry_get_debug_flag( 2 );
struct gcry_mpi
{
int alloced; /* Array size (# of allocated limbs). */
int nlimbs; /* Number of valid limbs. */
int sign; /* Indicates a negative number and is also used
for opaque MPIs to store the length. */
unsigned int flags; /* Bit 0: Array to be allocated in secure memory space.*/
/* Bit 2: the limb is a pointer to some m_alloced data.*/
mpi_limb_t *d; /* Array with the limbs */
};
#define MPI_NULL NULL
#define mpi_get_nlimbs(a) ((a)->nlimbs)
#define mpi_is_neg(a) ((a)->sign)
/*-- mpiutil.c --*/
#ifdef M_DEBUG
# define mpi_alloc(n) _gcry_mpi_debug_alloc((n), M_DBGINFO( __LINE__ ) )
# define mpi_alloc_secure(n) _gcry_mpi_debug_alloc_secure((n), M_DBGINFO( __LINE__ ) )
# define mpi_free(a) _gcry_mpi_debug_free((a), M_DBGINFO(__LINE__) )
# define mpi_resize(a,b) _gcry_mpi_debug_resize((a),(b), M_DBGINFO(__LINE__) )
# define mpi_copy(a) _gcry_mpi_debug_copy((a), M_DBGINFO(__LINE__) )
gcry_mpi_t _gcry_mpi_debug_alloc( unsigned nlimbs, const char *info );
gcry_mpi_t _gcry_mpi_debug_alloc_secure( unsigned nlimbs, const char *info );
void _gcry_mpi_debug_free( gcry_mpi_t a, const char *info );
void _gcry_mpi_debug_resize( gcry_mpi_t a, unsigned nlimbs, const char *info );
gcry_mpi_t _gcry_mpi_debug_copy( gcry_mpi_t a, const char *info );
#else
# define mpi_alloc(n) _gcry_mpi_alloc((n) )
# define mpi_alloc_secure(n) _gcry_mpi_alloc_secure((n) )
# define mpi_free(a) _gcry_mpi_free((a) )
# define mpi_resize(a,b) _gcry_mpi_resize((a),(b))
# define mpi_copy(a) gcry_mpi_copy((a))
gcry_mpi_t _gcry_mpi_alloc( unsigned nlimbs );
gcry_mpi_t _gcry_mpi_alloc_secure( unsigned nlimbs );
void _gcry_mpi_free( gcry_mpi_t a );
void _gcry_mpi_resize( gcry_mpi_t a, unsigned nlimbs );
gcry_mpi_t _gcry_mpi_copy( gcry_mpi_t a );
#endif
#define mpi_is_opaque(a) ((a) && ((a)->flags&4))
#define mpi_is_secure(a) ((a) && ((a)->flags&1))
#define mpi_clear(a) _gcry_mpi_clear ((a))
#define mpi_alloc_like(a) _gcry_mpi_alloc_like((a))
#define mpi_set(a,b) gcry_mpi_set ((a),(b))
#define mpi_set_ui(a,b) gcry_mpi_set_ui ((a),(b))
#define mpi_get_ui(a,b) _gcry_mpi_get_ui ((a),(b))
#define mpi_alloc_set_ui(a) _gcry_mpi_alloc_set_ui ((a))
#define mpi_m_check(a) _gcry_mpi_m_check ((a))
#define mpi_swap(a,b) _gcry_mpi_swap ((a),(b))
#define mpi_new(n) gcry_mpi_new ((n))
#define mpi_snew(n) _gcry_mpi_snew ((n))
void _gcry_mpi_clear( gcry_mpi_t a );
gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a );
gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u);
gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
void _gcry_mpi_m_check( gcry_mpi_t a );
void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b);
gcry_mpi_t _gcry_mpi_new (unsigned int nbits);
gcry_mpi_t _gcry_mpi_snew (unsigned int nbits);
/*-- mpicoder.c --*/
void _gcry_log_mpidump( const char *text, gcry_mpi_t a );
u32 _gcry_mpi_get_keyid( gcry_mpi_t a, u32 *keyid );
byte *_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
byte *_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
void _gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer,
unsigned int nbytes, int sign );
#define log_mpidump _gcry_log_mpidump
/*-- mpi-add.c --*/
#define mpi_add_ui(w,u,v) gcry_mpi_add_ui((w),(u),(v))
#define mpi_add(w,u,v) gcry_mpi_add ((w),(u),(v))
#define mpi_addm(w,u,v,m) gcry_mpi_addm ((w),(u),(v),(m))
#define mpi_sub_ui(w,u,v) gcry_mpi_sub_ui ((w),(u),(v))
#define mpi_sub(w,u,v) gcry_mpi_sub ((w),(u),(v))
#define mpi_subm(w,u,v,m) gcry_mpi_subm ((w),(u),(v),(m))
/*-- mpi-mul.c --*/
#define mpi_mul_ui(w,u,v) gcry_mpi_mul_ui ((w),(u),(v))
#define mpi_mul_2exp(w,u,v) gcry_mpi_mul_2exp ((w),(u),(v))
#define mpi_mul(w,u,v) gcry_mpi_mul ((w),(u),(v))
#define mpi_mulm(w,u,v,m) gcry_mpi_mulm ((w),(u),(v),(m))
/*-- mpi-div.c --*/
#define mpi_fdiv_r_ui(a,b,c) _gcry_mpi_fdiv_r_ui((a),(b),(c))
#define mpi_fdiv_r(a,b,c) _gcry_mpi_fdiv_r((a),(b),(c))
#define mpi_fdiv_q(a,b,c) _gcry_mpi_fdiv_q((a),(b),(c))
#define mpi_fdiv_qr(a,b,c,d) _gcry_mpi_fdiv_qr((a),(b),(c),(d))
#define mpi_tdiv_r(a,b,c) _gcry_mpi_tdiv_r((a),(b),(c))
#define mpi_tdiv_qr(a,b,c,d) _gcry_mpi_tdiv_qr((a),(b),(c),(d))
#define mpi_tdiv_q_2exp(a,b,c) _gcry_mpi_tdiv_q_2exp((a),(b),(c))
#define mpi_divisible_ui(a,b) _gcry_mpi_divisible_ui((a),(b))
ulong _gcry_mpi_fdiv_r_ui( gcry_mpi_t rem, gcry_mpi_t dividend, ulong divisor );
void _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
void _gcry_mpi_fdiv_q( gcry_mpi_t quot, gcry_mpi_t dividend, gcry_mpi_t divisor );
void _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor );
void _gcry_mpi_tdiv_r( gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
void _gcry_mpi_tdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t num, gcry_mpi_t den);
void _gcry_mpi_tdiv_q_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned count );
int _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor );
/*-- mpi-mod.c --*/
#define mpi_mod(r,a,m) _gcry_mpi_mod ((r), (a), (m))
#define mpi_barrett_init(m,f) _gcry_mpi_barrett_init ((m),(f))
#define mpi_barrett_free(c) _gcry_mpi_barrett_free ((c))
#define mpi_mod_barrett(r,a,c) _gcry_mpi_mod_barrett ((r), (a), (c))
#define mpi_mul_barrett(r,u,v,c) _gcry_mpi_mul_barrett ((r), (u), (v), (c))
void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
/* Context used with Barrett reduction. */
struct barrett_ctx_s;
typedef struct barrett_ctx_s *mpi_barrett_t;
mpi_barrett_t _gcry_mpi_barrett_init (gcry_mpi_t m, int copy);
void _gcry_mpi_barrett_free (mpi_barrett_t ctx);
void _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx);
void _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
mpi_barrett_t ctx);
/*-- mpi-gcd.c --*/
/*-- mpi-mpow.c --*/
#define mpi_mulpowm(a,b,c,d) _gcry_mpi_mulpowm ((a),(b),(c),(d))
void _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t mod);
/*-- mpi-cmp.c --*/
#define mpi_cmp_ui(a,b) gcry_mpi_cmp_ui ((a),(b))
#define mpi_cmp(a,b) gcry_mpi_cmp ((a),(b))
int gcry_mpi_cmp_ui( gcry_mpi_t u, ulong v );
int gcry_mpi_cmp( gcry_mpi_t u, gcry_mpi_t v );
/*-- mpi-scan.c --*/
#define mpi_trailing_zeros(a) _gcry_mpi_trailing_zeros ((a))
int _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx );
void _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int value );
unsigned _gcry_mpi_trailing_zeros( gcry_mpi_t a );
/*-- mpi-bit.c --*/
#define mpi_normalize(a) _gcry_mpi_normalize ((a))
#define mpi_get_nbits(a) gcry_mpi_get_nbits ((a))
#define mpi_test_bit(a,b) gcry_mpi_test_bit ((a),(b))
#define mpi_set_bit(a,b) gcry_mpi_set_bit ((a),(b))
#define mpi_set_highbit(a,b) gcry_mpi_set_highbit ((a),(b))
#define mpi_clear_bit(a,b) gcry_mpi_clear_bit ((a),(b))
#define mpi_clear_highbit(a,b) gcry_mpi_clear_highbit ((a),(b))
#define mpi_rshift(a,b,c) gcry_mpi_rshift ((a),(b),(c))
#define mpi_lshift(a,b,c) gcry_mpi_lshift ((a),(b),(c))
void _gcry_mpi_normalize( gcry_mpi_t a );
/*-- mpi-inv.c --*/
#define mpi_invm(a,b,c) gcry_mpi_invm ((a),(b),(c))
/*-- ec.c --*/
/* Object to represent a point in projective coordinates. */
struct mpi_point_s;
typedef struct mpi_point_s mpi_point_t;
struct mpi_point_s
{
gcry_mpi_t x;
gcry_mpi_t y;
gcry_mpi_t z;
};
/* Context used with elliptic curve functions. */
struct mpi_ec_ctx_s;
typedef struct mpi_ec_ctx_s *mpi_ec_t;
void _gcry_mpi_ec_point_init (mpi_point_t *p);
void _gcry_mpi_ec_point_free (mpi_point_t *p);
mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a);
void _gcry_mpi_ec_free (mpi_ec_t ctx);
int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
mpi_ec_t ctx);
void _gcry_mpi_ec_dup_point (mpi_point_t *result,
mpi_point_t *point, mpi_ec_t ctx);
void _gcry_mpi_ec_add_points (mpi_point_t *result,
mpi_point_t *p1, mpi_point_t *p2,
mpi_ec_t ctx);
void _gcry_mpi_ec_mul_point (mpi_point_t *result,
gcry_mpi_t scalar, mpi_point_t *point,
mpi_ec_t ctx);
#endif /*G10_MPI_H*/

View file

@ -0,0 +1,696 @@
/* secmem.c - memory allocation from a secure heap
* Copyright (C) 1998, 1999, 2000, 2001, 2002,
* 2003, 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 <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <unistd.h>
#include <stddef.h>
#if defined(HAVE_MLOCK) || defined(HAVE_MMAP)
#include <sys/mman.h>
#include <sys/types.h>
#include <fcntl.h>
#ifdef USE_CAPABILITIES
#include <sys/capability.h>
#endif
#endif
#include "ath.h"
#include "g10lib.h"
#include "secmem.h"
#if defined (MAP_ANON) && ! defined (MAP_ANONYMOUS)
#define MAP_ANONYMOUS MAP_ANON
#endif
#define MINIMUM_POOL_SIZE 16384
#define STANDARD_POOL_SIZE 32768
#define DEFAULT_PAGE_SIZE 4096
typedef struct memblock
{
unsigned size; /* Size of the memory available to the
user. */
int flags; /* See below. */
PROPERLY_ALIGNED_TYPE aligned;
} memblock_t;
/* This flag specifies that the memory block is in use. */
#define MB_FLAG_ACTIVE (1 << 0)
/* The pool of secure memory. */
static void *pool;
/* Size of POOL in bytes. */
static size_t pool_size;
/* True, if the memory pool is ready for use. May be checked in an
atexit function. */
static volatile int pool_okay;
/* True, if the memory pool is mmapped. */
static volatile int pool_is_mmapped;
/* FIXME? */
static int disable_secmem;
static int show_warning;
static int not_locked;
static int no_warning;
static int suspend_warning;
/* Stats. */
static unsigned int cur_alloced, cur_blocks;
/* Lock protecting accesses to the memory pool. */
static ath_mutex_t secmem_lock;
/* Convenient macros. */
#define SECMEM_LOCK ath_mutex_lock (&secmem_lock)
#define SECMEM_UNLOCK ath_mutex_unlock (&secmem_lock)
/* The size of the memblock structure; this does not include the
memory that is available to the user. */
#define BLOCK_HEAD_SIZE \
offsetof (memblock_t, aligned)
/* Convert an address into the according memory block structure. */
#define ADDR_TO_BLOCK(addr) \
(memblock_t *) ((char *) addr - BLOCK_HEAD_SIZE)
/* Check whether P points into the pool. */
static int
ptr_into_pool_p (const void *p)
{
/* We need to convert pointers to addresses. This is required by
C-99 6.5.8 to avoid undefined behaviour. Using size_t is at
least only implementation defined. See also
http://lists.gnupg.org/pipermail/gcrypt-devel/2007-February/001102.html
*/
size_t p_addr = (size_t)p;
size_t pool_addr = (size_t)pool;
return p_addr >= pool_addr && p_addr < pool_addr+pool_size;
}
/* Update the stats. */
static void
stats_update (size_t add, size_t sub)
{
if (add)
{
cur_alloced += add;
cur_blocks++;
}
if (sub)
{
cur_alloced -= sub;
cur_blocks--;
}
}
/* Return the block following MB or NULL, if MB is the last block. */
static memblock_t *
mb_get_next (memblock_t *mb)
{
memblock_t *mb_next;
mb_next = (memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE + mb->size);
if (! ptr_into_pool_p (mb_next))
mb_next = NULL;
return mb_next;
}
/* Return the block preceding MB or NULL, if MB is the first
block. */
static memblock_t *
mb_get_prev (memblock_t *mb)
{
memblock_t *mb_prev, *mb_next;
if (mb == pool)
mb_prev = NULL;
else
{
mb_prev = (memblock_t *) pool;
while (1)
{
mb_next = mb_get_next (mb_prev);
if (mb_next == mb)
break;
else
mb_prev = mb_next;
}
}
return mb_prev;
}
/* If the preceding block of MB and/or the following block of MB
exist and are not active, merge them to form a bigger block. */
static void
mb_merge (memblock_t *mb)
{
memblock_t *mb_prev, *mb_next;
mb_prev = mb_get_prev (mb);
mb_next = mb_get_next (mb);
if (mb_prev && (! (mb_prev->flags & MB_FLAG_ACTIVE)))
{
mb_prev->size += BLOCK_HEAD_SIZE + mb->size;
mb = mb_prev;
}
if (mb_next && (! (mb_next->flags & MB_FLAG_ACTIVE)))
mb->size += BLOCK_HEAD_SIZE + mb_next->size;
}
/* Return a new block, which can hold SIZE bytes. */
static memblock_t *
mb_get_new (memblock_t *block, size_t size)
{
memblock_t *mb, *mb_split;
for (mb = block; ptr_into_pool_p (mb); mb = mb_get_next (mb))
if (! (mb->flags & MB_FLAG_ACTIVE) && mb->size >= size)
{
/* Found a free block. */
mb->flags |= MB_FLAG_ACTIVE;
if (mb->size - size > BLOCK_HEAD_SIZE)
{
/* Split block. */
mb_split = (memblock_t *) (((char *) mb) + BLOCK_HEAD_SIZE + size);
mb_split->size = mb->size - size - BLOCK_HEAD_SIZE;
mb_split->flags = 0;
mb->size = size;
mb_merge (mb_split);
}
break;
}
if (! ptr_into_pool_p (mb))
{
gpg_err_set_errno (ENOMEM);
mb = NULL;
}
return mb;
}
/* Print a warning message. */
static void
print_warn (void)
{
if (!no_warning)
log_info (_("Warning: using insecure memory!\n"));
}
/* Lock the memory pages into core and drop privileges. */
static void
lock_pool (void *p, size_t n)
{
#if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
int err;
cap_set_proc (cap_from_text ("cap_ipc_lock+ep"));
err = mlock (p, n);
if (err && errno)
err = errno;
cap_set_proc (cap_from_text ("cap_ipc_lock+p"));
if (err)
{
if (errno != EPERM
#ifdef EAGAIN /* OpenBSD returns this */
&& errno != EAGAIN
#endif
#ifdef ENOSYS /* Some SCOs return this (function not implemented) */
&& errno != ENOSYS
#endif
#ifdef ENOMEM /* Linux might return this. */
&& errno != ENOMEM
#endif
)
log_error ("can't lock memory: %s\n", strerror (err));
show_warning = 1;
not_locked = 1;
}
#elif defined(HAVE_MLOCK)
uid_t uid;
int err;
uid = getuid ();
#ifdef HAVE_BROKEN_MLOCK
/* Under HP/UX mlock segfaults if called by non-root. Note, we have
noch checked whether mlock does really work under AIX where we
also detected a broken nlock. Note further, that using plock ()
is not a good idea under AIX. */
if (uid)
{
errno = EPERM;
err = errno;
}
else
{
err = mlock (p, n);
if (err && errno)
err = errno;
}
#else /* !HAVE_BROKEN_MLOCK */
err = mlock (p, n);
if (err && errno)
err = errno;
#endif /* !HAVE_BROKEN_MLOCK */
if (uid && ! geteuid ())
{
/* check that we really dropped the privs.
* Note: setuid(0) should always fail */
if (setuid (uid) || getuid () != geteuid () || !setuid (0))
log_fatal ("failed to reset uid: %s\n", strerror (errno));
}
if (err)
{
if (errno != EPERM
#ifdef EAGAIN /* OpenBSD returns this. */
&& errno != EAGAIN
#endif
#ifdef ENOSYS /* Some SCOs return this (function not implemented). */
&& errno != ENOSYS
#endif
#ifdef ENOMEM /* Linux might return this. */
&& errno != ENOMEM
#endif
)
log_error ("can't lock memory: %s\n", strerror (err));
show_warning = 1;
not_locked = 1;
}
#elif defined ( __QNX__ )
/* QNX does not page at all, so the whole secure memory stuff does
* not make much sense. However it is still of use because it
* wipes out the memory on a free().
* Therefore it is sufficient to suppress the warning. */
(void)p;
(void)n;
#elif defined (HAVE_DOSISH_SYSTEM) || defined (__CYGWIN__)
/* It does not make sense to print such a warning, given the fact that
* this whole Windows !@#$% and their user base are inherently insecure. */
(void)p;
(void)n;
#elif defined (__riscos__)
/* No virtual memory on RISC OS, so no pages are swapped to disc,
* besides we don't have mmap, so we don't use it! ;-)
* But don't complain, as explained above. */
(void)p;
(void)n;
#else
(void)p;
(void)n;
log_info ("Please note that you don't have secure memory on this system\n");
#endif
}
/* Initialize POOL. */
static void
init_pool (size_t n)
{
size_t pgsize;
long int pgsize_val;
memblock_t *mb;
pool_size = n;
if (disable_secmem)
log_bug ("secure memory is disabled");
#if defined(HAVE_SYSCONF) && defined(_SC_PAGESIZE)
pgsize_val = sysconf (_SC_PAGESIZE);
#elif defined(HAVE_GETPAGESIZE)
pgsize_val = getpagesize ();
#else
pgsize_val = -1;
#endif
pgsize = (pgsize_val != -1 && pgsize_val > 0)? pgsize_val:DEFAULT_PAGE_SIZE;
#if HAVE_MMAP
pool_size = (pool_size + pgsize - 1) & ~(pgsize - 1);
#ifdef MAP_ANONYMOUS
pool = mmap (0, pool_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
#else /* map /dev/zero instead */
{
int fd;
fd = open ("/dev/zero", O_RDWR);
if (fd == -1)
{
log_error ("can't open /dev/zero: %s\n", strerror (errno));
pool = (void *) -1;
}
else
{
pool = mmap (0, pool_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
close (fd);
}
}
#endif
if (pool == (void *) -1)
log_info ("can't mmap pool of %u bytes: %s - using malloc\n",
(unsigned) pool_size, strerror (errno));
else
{
pool_is_mmapped = 1;
pool_okay = 1;
}
#endif
if (!pool_okay)
{
pool = malloc (pool_size);
if (!pool)
log_fatal ("can't allocate memory pool of %u bytes\n",
(unsigned) pool_size);
else
pool_okay = 1;
}
/* Initialize first memory block. */
mb = (memblock_t *) pool;
mb->size = pool_size;
mb->flags = 0;
}
void
_gcry_secmem_set_flags (unsigned flags)
{
int was_susp;
SECMEM_LOCK;
was_susp = suspend_warning;
no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING;
suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING;
/* and now issue the warning if it is not longer suspended */
if (was_susp && !suspend_warning && show_warning)
{
show_warning = 0;
print_warn ();
}
SECMEM_UNLOCK;
}
unsigned int
_gcry_secmem_get_flags (void)
{
unsigned flags;
SECMEM_LOCK;
flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0;
flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0;
flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0;
SECMEM_UNLOCK;
return flags;
}
/* See _gcry_secmem_init. This function is expected to be called with
the secmem lock held. */
static void
secmem_init (size_t n)
{
if (!n)
{
#ifdef USE_CAPABILITIES
/* drop all capabilities */
cap_set_proc (cap_from_text ("all-eip"));
#elif !defined(HAVE_DOSISH_SYSTEM)
uid_t uid;
disable_secmem = 1;
uid = getuid ();
if (uid != geteuid ())
{
if (setuid (uid) || getuid () != geteuid () || !setuid (0))
log_fatal ("failed to drop setuid\n");
}
#endif
}
else
{
if (n < MINIMUM_POOL_SIZE)
n = MINIMUM_POOL_SIZE;
if (! pool_okay)
{
init_pool (n);
lock_pool (pool, n);
}
else
log_error ("Oops, secure memory pool already initialized\n");
}
}
/* Initialize the secure memory system. If running with the necessary
privileges, the secure memory pool will be locked into the core in
order to prevent page-outs of the data. Furthermore allocated
secure memory will be wiped out when released. */
void
_gcry_secmem_init (size_t n)
{
SECMEM_LOCK;
secmem_init (n);
SECMEM_UNLOCK;
}
static void *
_gcry_secmem_malloc_internal (size_t size)
{
memblock_t *mb;
if (!pool_okay)
{
/* Try to initialize the pool if the user forgot about it. */
secmem_init (STANDARD_POOL_SIZE);
if (!pool_okay)
{
log_info (_("operation is not possible without "
"initialized secure memory\n"));
gpg_err_set_errno (ENOMEM);
return NULL;
}
}
if (not_locked && fips_mode ())
{
log_info (_("secure memory pool is not locked while in FIPS mode\n"));
gpg_err_set_errno (ENOMEM);
return NULL;
}
if (show_warning && !suspend_warning)
{
show_warning = 0;
print_warn ();
}
/* Blocks are always a multiple of 32. */
size = ((size + 31) / 32) * 32;
mb = mb_get_new ((memblock_t *) pool, size);
if (mb)
stats_update (size, 0);
return mb ? &mb->aligned.c : NULL;
}
void *
_gcry_secmem_malloc (size_t size)
{
void *p;
SECMEM_LOCK;
p = _gcry_secmem_malloc_internal (size);
SECMEM_UNLOCK;
return p;
}
static void
_gcry_secmem_free_internal (void *a)
{
memblock_t *mb;
int size;
if (!a)
return;
mb = ADDR_TO_BLOCK (a);
size = mb->size;
/* This does not make much sense: probably this memory is held in the
* cache. We do it anyway: */
#define MB_WIPE_OUT(byte) \
wipememory2 ((memblock_t *) ((char *) mb + BLOCK_HEAD_SIZE), (byte), size);
MB_WIPE_OUT (0xff);
MB_WIPE_OUT (0xaa);
MB_WIPE_OUT (0x55);
MB_WIPE_OUT (0x00);
stats_update (0, size);
mb->flags &= ~MB_FLAG_ACTIVE;
/* Update stats. */
mb_merge (mb);
}
/* Wipe out and release memory. */
void
_gcry_secmem_free (void *a)
{
SECMEM_LOCK;
_gcry_secmem_free_internal (a);
SECMEM_UNLOCK;
}
/* Realloc memory. */
void *
_gcry_secmem_realloc (void *p, size_t newsize)
{
memblock_t *mb;
size_t size;
void *a;
SECMEM_LOCK;
mb = (memblock_t *) ((char *) p - ((size_t) &((memblock_t *) 0)->aligned.c));
size = mb->size;
if (newsize < size)
{
/* It is easier to not shrink the memory. */
a = p;
}
else
{
a = _gcry_secmem_malloc_internal (newsize);
if (a)
{
memcpy (a, p, size);
memset ((char *) a + size, 0, newsize - size);
_gcry_secmem_free_internal (p);
}
}
SECMEM_UNLOCK;
return a;
}
/* Return true if P points into the secure memory area. */
int
_gcry_private_is_secure (const void *p)
{
return pool_okay && ptr_into_pool_p (p);
}
/****************
* Warning: This code might be called by an interrupt handler
* and frankly, there should really be such a handler,
* to make sure that the memory is wiped out.
* We hope that the OS wipes out mlocked memory after
* receiving a SIGKILL - it really should do so, otherwise
* there is no chance to get the secure memory cleaned.
*/
void
_gcry_secmem_term ()
{
if (!pool_okay)
return;
wipememory2 (pool, 0xff, pool_size);
wipememory2 (pool, 0xaa, pool_size);
wipememory2 (pool, 0x55, pool_size);
wipememory2 (pool, 0x00, pool_size);
#if HAVE_MMAP
if (pool_is_mmapped)
munmap (pool, pool_size);
#endif
pool = NULL;
pool_okay = 0;
pool_size = 0;
not_locked = 0;
}
void
_gcry_secmem_dump_stats ()
{
#if 1
SECMEM_LOCK;
if (pool_okay)
log_info ("secmem usage: %u/%lu bytes in %u blocks\n",
cur_alloced, (unsigned long)pool_size, cur_blocks);
SECMEM_UNLOCK;
#else
memblock_t *mb;
int i;
SECMEM_LOCK;
for (i = 0, mb = (memblock_t *) pool;
ptr_into_pool_p (mb);
mb = mb_get_next (mb), i++)
log_info ("SECMEM: [%s] block: %i; size: %i\n",
(mb->flags & MB_FLAG_ACTIVE) ? "used" : "free",
i,
mb->size);
SECMEM_UNLOCK;
#endif
}

View file

@ -0,0 +1,39 @@
/* secmem.h - internal definitions for secmem
* Copyright (C) 2000, 2001, 2002, 2003 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_SECMEM_H
#define G10_SECMEM_H 1
void _gcry_secmem_init (size_t npool);
void _gcry_secmem_term (void);
void *_gcry_secmem_malloc (size_t size) _GCRY_GCC_ATTR_MALLOC;
void *_gcry_secmem_realloc (void *a, size_t newsize);
void _gcry_secmem_free (void *a);
void _gcry_secmem_dump_stats (void);
void _gcry_secmem_set_flags (unsigned flags);
unsigned _gcry_secmem_get_flags(void);
int _gcry_private_is_secure (const void *p);
/* Flags for _gcry_secmem_{set,get}_flags. */
#define GCRY_SECMEM_FLAG_NO_WARNING (1 << 0)
#define GCRY_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
#define GCRY_SECMEM_FLAG_NOT_LOCKED (1 << 2)
#endif /* G10_SECMEM_H */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,242 @@
/* stdmem.c - private memory allocator
* Copyright (C) 1998, 2000, 2002, 2005, 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 <http://www.gnu.org/licenses/>.
*/
/*
* Description of the layered memory management in Libgcrypt:
*
* [User]
* |
* |
* \ /
* global.c: [MM entrance points] -----> [user callbacks]
* | |
* | |
* \ / \ /
*
* stdmem.c: [non-secure handlers] [secure handlers]
*
* | |
* | |
* \ / \ /
*
* stdmem.c: [ memory guard ]
*
* | |
* | |
* \ / \ /
*
* libc: [ MM functions ] secmem.c: [ secure MM functions]
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include "g10lib.h"
#include "stdmem.h"
#include "secmem.h"
#define MAGIC_NOR_BYTE 0x55
#define MAGIC_SEC_BYTE 0xcc
#define MAGIC_END_BYTE 0xaa
#if SIZEOF_UNSIGNED_LONG == 8
#define EXTRA_ALIGN 4
#else
#define EXTRA_ALIGN 0
#endif
static int use_m_guard = 0;
/****************
* Warning: Never use this function after any of the functions
* here have been used.
*/
void
_gcry_private_enable_m_guard (void)
{
use_m_guard = 1;
}
/*
* Allocate memory of size n.
* Return NULL if we are out of memory.
*/
void *
_gcry_private_malloc (size_t n)
{
if (!n)
{
gpg_err_set_errno (EINVAL);
return NULL; /* Allocating 0 bytes is undefined - we better return
an error to detect such coding errors. */
}
if (use_m_guard)
{
char *p;
if ( !(p = malloc (n + EXTRA_ALIGN+5)) )
return NULL;
((byte*)p)[EXTRA_ALIGN+0] = n;
((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
((byte*)p)[EXTRA_ALIGN+3] = MAGIC_NOR_BYTE;
p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
return p+EXTRA_ALIGN+4;
}
else
{
return malloc( n );
}
}
/*
* Allocate memory of size N from the secure memory pool. Return NULL
* if we are out of memory.
*/
void *
_gcry_private_malloc_secure (size_t n)
{
if (!n)
{
gpg_err_set_errno (EINVAL);
return NULL; /* Allocating 0 bytes is undefined - better return an
error to detect such coding errors. */
}
if (use_m_guard)
{
char *p;
if ( !(p = _gcry_secmem_malloc (n +EXTRA_ALIGN+ 5)) )
return NULL;
((byte*)p)[EXTRA_ALIGN+0] = n;
((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ;
((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ;
((byte*)p)[EXTRA_ALIGN+3] = MAGIC_SEC_BYTE;
p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE;
return p+EXTRA_ALIGN+4;
}
else
{
return _gcry_secmem_malloc( n );
}
}
/*
* Realloc and clear the old space
* Return NULL if there is not enough memory.
*/
void *
_gcry_private_realloc ( void *a, size_t n )
{
if (use_m_guard)
{
unsigned char *p = a;
char *b;
size_t len;
if (!a)
return _gcry_private_malloc(n);
_gcry_private_check_heap(p);
len = p[-4];
len |= p[-3] << 8;
len |= p[-2] << 16;
if( len >= n ) /* We don't shrink for now. */
return a;
if (p[-1] == MAGIC_SEC_BYTE)
b = _gcry_private_malloc_secure(n);
else
b = _gcry_private_malloc(n);
if (!b)
return NULL;
memcpy (b, a, len);
memset (b+len, 0, n-len);
_gcry_private_free (p);
return b;
}
else if ( _gcry_private_is_secure(a) )
{
return _gcry_secmem_realloc( a, n );
}
else
{
return realloc( a, n );
}
}
void
_gcry_private_check_heap (const void *a)
{
if (use_m_guard)
{
const byte *p = a;
size_t len;
if (!p)
return;
if ( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) )
_gcry_log_fatal ("memory at %p corrupted (underflow=%02x)\n", p, p[-1]);
len = p[-4];
len |= p[-3] << 8;
len |= p[-2] << 16;
if ( p[len] != MAGIC_END_BYTE )
_gcry_log_fatal ("memory at %p corrupted (overflow=%02x)\n", p, p[-1]);
}
}
/*
* Free a memory block allocated by this or the secmem module
*/
void
_gcry_private_free (void *a)
{
unsigned char *p = a;
if (!p)
return;
if (use_m_guard )
{
_gcry_private_check_heap(p);
if ( _gcry_private_is_secure(a) )
_gcry_secmem_free(p-EXTRA_ALIGN-4);
else
{
free(p-EXTRA_ALIGN-4);
}
}
else if ( _gcry_private_is_secure(a) )
_gcry_secmem_free(p);
else
free(p);
}

View file

@ -0,0 +1,32 @@
/* stdmem.h - internal definitions for stdmem
* Copyright (C) 2000, 2002, 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
*/
#ifndef G10_STDMEM_H
#define G10_STDMEM_H 1
void _gcry_private_enable_m_guard(void);
void *_gcry_private_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC;
void *_gcry_private_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC;
void *_gcry_private_realloc (void *a, size_t n);
void _gcry_private_check_heap (const void *a);
void _gcry_private_free (void *a);
#endif /* G10_STDMEM_H */

View file

@ -0,0 +1,128 @@
/* types.h - some common typedefs
* Copyright (C) 1998, 2000, 2002, 2003 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 GCRYPT_TYPES_H
#define GCRYPT_TYPES_H
/* The AC_CHECK_SIZEOF() in configure fails for some machines.
* we provide some fallback values here */
#if !SIZEOF_UNSIGNED_SHORT
#undef SIZEOF_UNSIGNED_SHORT
#define SIZEOF_UNSIGNED_SHORT 2
#endif
#if !SIZEOF_UNSIGNED_INT
#undef SIZEOF_UNSIGNED_INT
#define SIZEOF_UNSIGNED_INT 4
#endif
#if !SIZEOF_UNSIGNED_LONG
#undef SIZEOF_UNSIGNED_LONG
#define SIZEOF_UNSIGNED_LONG 4
#endif
#include <sys/types.h>
#ifndef HAVE_BYTE_TYPEDEF
#undef byte /* maybe there is a macro with this name */
/* Windows typedefs byte in the rpc headers. Avoid warning about
double definition. */
#if !(defined(_WIN32) && defined(cbNDRContext))
typedef unsigned char byte;
#endif
#define HAVE_BYTE_TYPEDEF
#endif
#ifndef HAVE_USHORT_TYPEDEF
#undef ushort /* maybe there is a macro with this name */
typedef unsigned short ushort;
#define HAVE_USHORT_TYPEDEF
#endif
#ifndef HAVE_ULONG_TYPEDEF
#undef ulong /* maybe there is a macro with this name */
typedef unsigned long ulong;
#define HAVE_ULONG_TYPEDEF
#endif
#ifndef HAVE_U16_TYPEDEF
#undef u16 /* maybe there is a macro with this name */
#if SIZEOF_UNSIGNED_INT == 2
typedef unsigned int u16;
#elif SIZEOF_UNSIGNED_SHORT == 2
typedef unsigned short u16;
#else
#error no typedef for u16
#endif
#define HAVE_U16_TYPEDEF
#endif
#ifndef HAVE_U32_TYPEDEF
#undef u32 /* maybe there is a macro with this name */
#if SIZEOF_UNSIGNED_INT == 4
typedef unsigned int u32;
#elif SIZEOF_UNSIGNED_LONG == 4
typedef unsigned long u32;
#else
#error no typedef for u32
#endif
#define HAVE_U32_TYPEDEF
#endif
/****************
* Warning: Some systems segfault when this u64 typedef and
* the dummy code in cipher/md.c is not available. Examples are
* Solaris and IRIX.
*/
#ifndef HAVE_U64_TYPEDEF
#undef u64 /* maybe there is a macro with this name */
#if SIZEOF_UNSIGNED_INT == 8
typedef unsigned int u64;
#define U64_C(c) (c ## U)
#define HAVE_U64_TYPEDEF
#elif SIZEOF_UNSIGNED_LONG == 8
typedef unsigned long u64;
#define U64_C(c) (c ## UL)
#define HAVE_U64_TYPEDEF
#elif SIZEOF_UNSIGNED_LONG_LONG == 8
typedef unsigned long long u64;
#define U64_C(c) (c ## ULL)
#define HAVE_U64_TYPEDEF
#elif SIZEOF_UINT64_T == 8
typedef uint64_t u64;
#define U64_C(c) (UINT64_C(c))
#define HAVE_U64_TYPEDEF
#endif
#endif
typedef union {
int a;
short b;
char c[1];
long d;
#ifdef HAVE_U64_TYPEDEF
u64 e;
#endif
float f;
double g;
} PROPERLY_ALIGNED_TYPE;
#endif /*GCRYPT_TYPES_H*/

View file

@ -0,0 +1,51 @@
/* versioninfo.rc.in - for libgcrypt
* Copyright (C) 2005, 2006 g10 Code GmbH
*
* This file is free software; as a special exception the author gives
* unlimited permission to copy and/or distribute it, with or without
* modifications, as long as this notice is preserved.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* This file is processed by configure to create versioninfo.rc */
#line __LINE__ "versioninfo.rc.in"
#include <afxres.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION @LIBGCRYPT_LT_CURRENT@,@LIBGCRYPT_LT_AGE@,@LIBGCRYPT_LT_REVISION@,@BUILD_REVISION@
PRODUCTVERSION @BUILD_FILEVERSION@
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x21L
#else
FILEFLAGS 0x20L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "Comments", "Provided under the terms of the GNU Lesser General Public License (LGPLv2.1+).\0"
VALUE "CompanyName", "g10 Code GmbH\0"
VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0"
VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT@.@LIBGCRYPT_LT_AGE@.@LIBGCRYPT_LT_REVISION@.@BUILD_REVISION@\0"
VALUE "InternalName", "libgcrypt\0"
VALUE "LegalCopyright", "Copyright © 2011 Free Software Foundation, Inc.\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "libgcrypt.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "libgcrypt\0"
VALUE "ProductVersion", "@VERSION@\0"
VALUE "SpecialBuild", "@BUILD_TIMESTAMP@\0"
END
END
END

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,565 @@
/* 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 <http://www.gnu.org/licenses/>.
*/
#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_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_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
/* 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"
/* None in this version. */
#else
# include "gcrypt.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_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_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
/* 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_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_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_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_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)
#undef MARK_VISIBLE
#endif /*_GCRY_INCLUDED_BY_VISIBILITY_C*/
#endif /*GCRY_VISIBILITY_H*/