diff options
Diffstat (limited to 'plugins/MirOTR/Libgcrypt/src')
33 files changed, 16304 insertions, 0 deletions
diff --git a/plugins/MirOTR/Libgcrypt/src/ath.c b/plugins/MirOTR/Libgcrypt/src/ath.c new file mode 100644 index 0000000000..a3d300c1b9 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/ath.c @@ -0,0 +1,345 @@ +/* ath.c - Thread-safeness library. + Copyright (C) 2002, 2003, 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 + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Libgcrypt; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <assert.h> /* Right: We need to use assert and not gcry_assert. */ +#include <unistd.h> +#ifdef HAVE_SYS_SELECT_H +# include <sys/select.h> +#else +# include <sys/time.h> +#endif +#include <sys/types.h> +#ifndef _WIN32 +#include <sys/wait.h> +#endif +#include <errno.h> + +#include "ath.h" + + + +/* The interface table. */ +static struct ath_ops ops; + +/* True if we should use the external callbacks. */ +static int ops_set; + + +/* For the dummy interface. */ +#define MUTEX_UNLOCKED ((ath_mutex_t) 0) +#define MUTEX_LOCKED ((ath_mutex_t) 1) +#define MUTEX_DESTROYED ((ath_mutex_t) 2) + + +/* Return the thread type from the option field. */ +#define GET_OPTION(a) ((a) & 0xff) +/* Return the version number from the option field. */ +#define GET_VERSION(a) (((a) >> 8)& 0xff) + + + +/* The lock we take while checking for lazy lock initialization. */ +static ath_mutex_t check_init_lock = ATH_MUTEX_INITIALIZER; + +int +ath_init (void) +{ + int err = 0; + + if (ops_set) + { + if (ops.init) + err = (*ops.init) (); + if (err) + return err; + err = (*ops.mutex_init) (&check_init_lock); + } + return err; +} + + +/* Initialize the locking library. Returns 0 if the operation was + successful, EINVAL if the operation table was invalid and EBUSY if + we already were initialized. */ +gpg_err_code_t +ath_install (struct ath_ops *ath_ops, int check_only) +{ + if (check_only) + { + unsigned int option = 0; + + /* Check if the requested thread option is compatible to the + thread option we are already committed to. */ + if (ath_ops) + option = ath_ops->option; + + if (!ops_set && GET_OPTION (option)) + return GPG_ERR_NOT_SUPPORTED; + + if (GET_OPTION (ops.option) == ATH_THREAD_OPTION_USER + || GET_OPTION (option) == ATH_THREAD_OPTION_USER + || GET_OPTION (ops.option) != GET_OPTION (option) + || GET_VERSION (ops.option) != GET_VERSION (option)) + return GPG_ERR_NOT_SUPPORTED; + + return 0; + } + + if (ath_ops) + { + /* It is convenient to not require DESTROY. */ + if (!ath_ops->mutex_init || !ath_ops->mutex_lock + || !ath_ops->mutex_unlock) + return GPG_ERR_INV_ARG; + + ops = *ath_ops; + ops_set = 1; + } + else + ops_set = 0; + + return 0; +} + + +static int +mutex_init (ath_mutex_t *lock, int just_check) +{ + int err = 0; + + if (just_check) + (*ops.mutex_lock) (&check_init_lock); + if (*lock == ATH_MUTEX_INITIALIZER || !just_check) + err = (*ops.mutex_init) (lock); + if (just_check) + (*ops.mutex_unlock) (&check_init_lock); + return err; +} + + +int +ath_mutex_init (ath_mutex_t *lock) +{ + if (ops_set) + return mutex_init (lock, 0); + +#ifndef NDEBUG + *lock = MUTEX_UNLOCKED; +#endif + return 0; +} + + +int +ath_mutex_destroy (ath_mutex_t *lock) +{ + if (ops_set) + { + if (!ops.mutex_destroy) + return 0; + + (*ops.mutex_lock) (&check_init_lock); + if (*lock == ATH_MUTEX_INITIALIZER) + { + (*ops.mutex_unlock) (&check_init_lock); + return 0; + } + (*ops.mutex_unlock) (&check_init_lock); + return (*ops.mutex_destroy) (lock); + } + +#ifndef NDEBUG + assert (*lock == MUTEX_UNLOCKED); + + *lock = MUTEX_DESTROYED; +#endif + return 0; +} + + +int +ath_mutex_lock (ath_mutex_t *lock) +{ + if (ops_set) + { + int ret = mutex_init (lock, 1); + if (ret) + return ret; + return (*ops.mutex_lock) (lock); + } + +#ifndef NDEBUG + assert (*lock == MUTEX_UNLOCKED); + + *lock = MUTEX_LOCKED; +#endif + return 0; +} + + +int +ath_mutex_unlock (ath_mutex_t *lock) +{ + if (ops_set) + { + int ret = mutex_init (lock, 1); + if (ret) + return ret; + return (*ops.mutex_unlock) (lock); + } + +#ifndef NDEBUG + assert (*lock == MUTEX_LOCKED); + + *lock = MUTEX_UNLOCKED; +#endif + return 0; +} + + +ssize_t +ath_read (int fd, void *buf, size_t nbytes) +{ + if (ops_set && ops.read) + return (*ops.read) (fd, buf, nbytes); + else + return _read (fd, buf, nbytes); +} + + +ssize_t +ath_write (int fd, const void *buf, size_t nbytes) +{ + if (ops_set && ops.write) + return (*ops.write) (fd, buf, nbytes); + else + return _write (fd, buf, nbytes); +} + + +ssize_t +#ifdef _WIN32 +ath_select (int nfd, void *rset, void *wset, void *eset, + struct timeval *timeout) +#else +ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, + struct timeval *timeout) +#endif +{ + if (ops_set && ops.select) + return (*ops.select) (nfd, rset, wset, eset, timeout); + else +#ifdef _WIN32 + return -1; +#else + return select (nfd, rset, wset, eset, timeout); +#endif +} + + +ssize_t +ath_waitpid (pid_t pid, int *status, int options) +{ + if (ops_set && ops.waitpid) + return (*ops.waitpid) (pid, status, options); + else +#ifdef _WIN32 + return -1; +#else + return waitpid (pid, status, options); +#endif +} + + +int +#ifdef _WIN32 +ath_accept (int s, void *addr, int *length_ptr) +#else +ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr) +#endif +{ + if (ops_set && ops.accept) + return (*ops.accept) (s, addr, length_ptr); + else +#ifdef _WIN32 + return -1; +#else + return accept (s, addr, length_ptr); +#endif +} + + +int +#ifdef _WIN32 +ath_connect (int s, void *addr, int length) +#else +ath_connect (int s, struct sockaddr *addr, socklen_t length) +#endif +{ + if (ops_set && ops.connect) + return (*ops.connect) (s, addr, length); + else +#ifdef _WIN32 + return -1; +#else + return connect (s, addr, length); +#endif +} + + +int +#ifdef _WIN32 +ath_sendmsg (int s, const void *msg, int flags) +#else +ath_sendmsg (int s, const struct msghdr *msg, int flags) +#endif +{ + if (ops_set && ops.sendmsg) + return (*ops.sendmsg) (s, msg, flags); + else +#ifdef _WIN32 + return -1; +#else + return sendmsg (s, msg, flags); +#endif +} + + +int +#ifdef _WIN32 +ath_recvmsg (int s, void *msg, int flags) +#else +ath_recvmsg (int s, struct msghdr *msg, int flags) +#endif +{ + if (ops_set && ops.recvmsg) + return (*ops.recvmsg) (s, msg, flags); + else +#ifdef _WIN32 + return -1; +#else + return recvmsg (s, msg, flags); +#endif +} + diff --git a/plugins/MirOTR/Libgcrypt/src/ath.h b/plugins/MirOTR/Libgcrypt/src/ath.h new file mode 100644 index 0000000000..aba5e78359 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/ath.h @@ -0,0 +1,141 @@ +/* ath.h - Thread-safeness library. + Copyright (C) 2002, 2003, 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 + General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with Libgcrypt; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. */ + +#ifndef ATH_H +#define ATH_H + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#else +#include <sys/types.h> +#include <sys/socket.h> +#endif +#include <gpg-error.h> + +#include <sys/time.h> /* Required by Interix. */ + +#include <config.h> +#include <io.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_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) +#define ath_read _ATH_PREFIX(ath_read) +#define ath_write _ATH_PREFIX(ath_write) +#define ath_select _ATH_PREFIX(ath_select) +#define ath_waitpid _ATH_PREFIX(ath_waitpid) +#define ath_connect _ATH_PREFIX(ath_connect) +#define ath_accept _ATH_PREFIX(ath_accept) +#define ath_sendmsg _ATH_PREFIX(ath_sendmsg) +#define ath_recvmsg _ATH_PREFIX(ath_recvmsg) +#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; + + int (*init) (void); + int (*mutex_init) (void **priv); + int (*mutex_destroy) (void *priv); + int (*mutex_lock) (void *priv); + int (*mutex_unlock) (void *priv); + ssize_t (*read) (int fd, void *buf, size_t nbytes); + ssize_t (*write) (int fd, const void *buf, size_t nbytes); +#ifdef _WIN32 + ssize_t (*select) (int nfd, void *rset, void *wset, void *eset, + struct timeval *timeout); + ssize_t (*waitpid) (pid_t pid, int *status, int options); + int (*accept) (int s, void *addr, int *length_ptr); + int (*connect) (int s, void *addr, int length); + int (*sendmsg) (int s, const void *msg, int flags); + int (*recvmsg) (int s, void *msg, int flags); +#else + ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, + struct timeval *timeout); + ssize_t (*waitpid) (pid_t pid, int *status, int options); + int (*accept) (int s, struct sockaddr *addr, socklen_t *length_ptr); + int (*connect) (int s, struct sockaddr *addr, socklen_t length); + int (*sendmsg) (int s, const struct msghdr *msg, int flags); + int (*recvmsg) (int s, struct msghdr *msg, int flags); +#endif +}; + +gpg_err_code_t ath_install (struct ath_ops *ath_ops, int check_only); +int ath_init (void); + + +/* Functions for mutual exclusion. */ +typedef void *ath_mutex_t; +#define ATH_MUTEX_INITIALIZER 0 + +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); + +/* Replacement for the POSIX functions, which can be used to allow + other (user-level) threads to run. */ +ssize_t ath_read (int fd, void *buf, size_t nbytes); +ssize_t ath_write (int fd, const void *buf, size_t nbytes); +#ifdef _WIN32 +ssize_t ath_select (int nfd, void *rset, void *wset, void *eset, + struct timeval *timeout); +ssize_t ath_waitpid (pid_t pid, int *status, int options); +int ath_accept (int s, void *addr, int *length_ptr); +int ath_connect (int s, void *addr, int length); +int ath_sendmsg (int s, const void *msg, int flags); +int ath_recvmsg (int s, void *msg, int flags); +#else +ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, + struct timeval *timeout); +ssize_t ath_waitpid (pid_t pid, int *status, int options); +int ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr); +int ath_connect (int s, struct sockaddr *addr, socklen_t length); +int ath_sendmsg (int s, const struct msghdr *msg, int flags); +int ath_recvmsg (int s, struct msghdr *msg, int flags); +#endif + +#endif /* ATH_H */ diff --git a/plugins/MirOTR/Libgcrypt/src/cipher-proto.h b/plugins/MirOTR/Libgcrypt/src/cipher-proto.h new file mode 100644 index 0000000000..215323671e --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/cipher-proto.h @@ -0,0 +1,115 @@ +/* cipher-proto.h - Internal declarations + * 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/>. + */ + +/* 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 quert ECC curve parameters. */ +typedef gcry_err_code_t (*pk_get_param_t) + (const char *name, gcry_mpi_t *pkey); + +/* 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_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*/ diff --git a/plugins/MirOTR/Libgcrypt/src/cipher.h b/plugins/MirOTR/Libgcrypt/src/cipher.h new file mode 100644 index 0000000000..48baab4225 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/cipher.h @@ -0,0 +1,139 @@ +/* cipher.h + * Copyright (C) 1998, 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_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) + +#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); + + +/*-- 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 pk_extra_spec_t _gcry_pubkey_extraspec_rsa; +extern pk_extra_spec_t _gcry_pubkey_extraspec_dsa; +extern pk_extra_spec_t _gcry_pubkey_extraspec_elg; +extern pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa; + + +#endif /*G10_CIPHER_H*/ diff --git a/plugins/MirOTR/Libgcrypt/src/dumpsexp.c b/plugins/MirOTR/Libgcrypt/src/dumpsexp.c new file mode 100644 index 0000000000..8f5c0d30be --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/dumpsexp.c @@ -0,0 +1,613 @@ +/* dumpsexp.c - Dump S-expressions. + * Copyright (C) 2007 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, 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> + +#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 void +print_version (int with_help) +{ + fputs (MYVERSION_LINE "\n" + "Copyright (C) 2007 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] [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" + " --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) + { + printcursor (0); + printf ("%s\n", text); + } +} + +static void +printchr (int c) +{ + (void)c; +} + +static void +printhex (int c) +{ + (void)c; +} + + + + + + +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"); + } + else if (c == '#') + { + state = IN_HEXFMT; + hexcount = 0; + printctl ("beginhex"); + } + else if (c == '|') + { + state = IN_BASE64; + printctl ("beginbase64"); + } + 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"); + case IN_DATA: + if (datalen) + { + printhex (c); + datalen--; + } + if (!datalen) + { + state = INIT_STATE; + printctl ("enddata"); + } + break; + + case IN_STRING: + if (c == '\"') + { + printctl ("endstring"); + state = INIT_STATE; + } + else if (c == '\\') + state = IN_ESCAPE; + else + printchr (c); + break; + + case IN_ESCAPE: + switch (c) + { + case 'b': case 't': case 'v': case 'n': case 'f': + case 'r': case '"': case '\'': case '\\': + printhex (c); + 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; + } + + case IN_OCT_ESC: + state = IN_STRING; + break; + case IN_HEX_ESC: + 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)) + { + printchr (c); + hexcount++; + } + else if (c == '#') + { + if ((hexcount & 1)) + printerr ("odd number of hex digits"); + printctl ("endhex"); + state = INIT_STATE; + } + else if (!whitespace_p (c)) + printerr ("bad hex character"); + break; + + case IN_BASE64: + if (c == '|') + { + printctl ("endbase64"); + state = INIT_STATE; + } + else + printchr (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 + print_usage (); + } + + if (!argc) + { + rc = parse_and_print (stdin); + } + else + { + for (; argc; 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; +} + diff --git a/plugins/MirOTR/Libgcrypt/src/fips.c b/plugins/MirOTR/Libgcrypt/src/fips.c new file mode 100644 index 0000000000..8709dae96d --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/fips.c @@ -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 intialization + 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 = ATH_MUTEX_INITIALIZER; + +/* 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 wether 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*/ +} diff --git a/plugins/MirOTR/Libgcrypt/src/g10lib.h b/plugins/MirOTR/Libgcrypt/src/g10lib.h new file mode 100644 index 0000000000..7deb90c419 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/g10lib.h @@ -0,0 +1,358 @@ +/* g10lib.h - Internal definitions for libgcrypt + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005 + * 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 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) +#define N_(a) (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 ); + +#ifdef JNLIB_GCC_M_FUNCTION +#define BUG() _gcry_bug( __FILE__ , __LINE__, __FUNCTION__ ) +#define gcry_assert(expr) ((expr)? (void)0 \ + : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __FUNCTION__)) +#elif __STDC_VERSION__ >= 199901L +#define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ ) +#define gcry_assert(expr) ((expr)? (void)0 \ + : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__)) +#else +#define BUG() _gcry_bug( __FILE__ , __LINE__ ) +#define gcry_assert(expr) ((expr)? (void)0 \ + : _gcry_assert_failed (STR(expr), __FILE__, __LINE__)) +#endif + + +#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 + +unsigned int _gcry_get_hw_features (void); +void _gcry_detect_hw_features (void); + + +/*-- 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_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. */ +}; + +/* 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 successfull + 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_ac_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_fips_mode (void); +#define fips_mode() _gcry_fips_mode () + +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 */ diff --git a/plugins/MirOTR/Libgcrypt/src/gcrypt-module.h b/plugins/MirOTR/Libgcrypt/src/gcrypt-module.h new file mode 100644 index 0000000000..e717b70c97 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/gcrypt-module.h @@ -0,0 +1,233 @@ +/* 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. + */ + +#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; + +/* Register a new cipher module whose specification can be found in + CIPHER. On success, a new algorithm ID is stored in ALGORITHM_ID + and a pointer representing this module is stored in MODULE. */ +gcry_error_t gcry_cipher_register (gcry_cipher_spec_t *cipher, + int *algorithm_id, + gcry_module_t *module); + +/* Unregister the cipher identified by MODULE, which must have been + registered with gcry_cipher_register. */ +void gcry_cipher_unregister (gcry_module_t module); + +/* ********************** */ + +/* 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; + +/* Register a new pubkey module whose specification can be found in + PUBKEY. On success, a new algorithm ID is stored in ALGORITHM_ID + and a pointer representhing this module is stored in MODULE. */ +gcry_error_t gcry_pk_register (gcry_pk_spec_t *pubkey, + unsigned int *algorithm_id, + gcry_module_t *module); + +/* Unregister the pubkey identified by ID, which must have been + registered with gcry_pk_register. */ +void gcry_pk_unregister (gcry_module_t module); + +/* ********************** */ + +/* 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; + +/* Register a new digest module whose specification can be found in + DIGEST. On success, a new algorithm ID is stored in ALGORITHM_ID + and a pointer representhing this module is stored in MODULE. */ +gcry_error_t gcry_md_register (gcry_md_spec_t *digest, + unsigned int *algorithm_id, + gcry_module_t *module); + +/* Unregister the digest identified by ID, which must have been + registered with gcry_digest_register. */ +void gcry_md_unregister (gcry_module_t module); + +#if 0 /* keep Emacsens's auto-indent happy */ +{ +#endif +#ifdef __cplusplus +} +#endif +#endif diff --git a/plugins/MirOTR/Libgcrypt/src/gcrypt.h b/plugins/MirOTR/Libgcrypt/src/gcrypt.h new file mode 100644 index 0000000000..ef4196c266 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/gcrypt.h @@ -0,0 +1,1843 @@ +/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*- + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 + 2007, 2008, 2009, 2010 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/>. + + File: src/gcrypt.h. Generated from gcrypt.h.in by configure. */ + +#ifndef _GCRYPT_H +#define _GCRYPT_H + +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <tchar.h> + +#include <gpg-error.h> + +#include <sys/types.h> + +#if defined _WIN32 || defined __WIN32__ +#ifdef socklen_t + #undef socklen_t +#endif +# include <winsock2.h> +# include <ws2tcpip.h> +# include <time.h> +# ifndef __GNUC__ + typedef signed int ssize_t; + typedef int pid_t; +# endif /*!__GNUC__*/ +#else +# include <sys/socket.h> +# include <sys/time.h> +#endif /*!_WIN32*/ + +typedef socklen_t gcry_socklen_t; + + +/* This is required for error code compatibility. */ +#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT + +#ifdef __cplusplus +extern "C" { +#if 0 /* (Keep Emacsens' auto-indent happy.) */ +} +#endif +#endif + +/* The version of this header should match the one of the library. It + should not be used by a program because gcry_check_version() should + return the same version. The purpose of this macro is to let + autoconf (using the AM_PATH_GCRYPT macro) check that this header + matches the installed library. */ +#define GCRYPT_VERSION "1.4.6" + +/* Internal: We can't use the convenience macros for the multi + precision integer functions when building this library. */ +#ifdef _GCRYPT_IN_LIBGCRYPT +#ifndef GCRYPT_NO_MPI_MACROS +#define GCRYPT_NO_MPI_MACROS 1 +#endif +#endif + +/* We want to use gcc attributes when possible. Warning: Don't use + these macros in your programs: As indicated by the leading + underscore they are subject to change without notice. */ +#ifdef __GNUC__ + +#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +#if _GCRY_GCC_VERSION >= 30100 +#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) +#endif + +#if _GCRY_GCC_VERSION >= 29600 +#define _GCRY_GCC_ATTR_PURE __attribute__ ((__pure__)) +#endif + +#if _GCRY_GCC_VERSION >= 30200 +#define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__)) +#endif + +#endif /*__GNUC__*/ + +#ifndef _GCRY_GCC_ATTR_DEPRECATED +#define _GCRY_GCC_ATTR_DEPRECATED +#endif +#ifndef _GCRY_GCC_ATTR_PURE +#define _GCRY_GCC_ATTR_PURE +#endif +#ifndef _GCRY_GCC_ATTR_MALLOC +#define _GCRY_GCC_ATTR_MALLOC +#endif + +/* Some members in a public type should only be used internally. + There is no "internal" attribute, so we abuse the deprecated + attribute to discourage external use. */ +#ifdef _GCRYPT_IN_LIBGCRYPT +#define _GCRY_ATTR_INTERNAL +#else +#define _GCRY_ATTR_INTERNAL _GCRY_GCC_ATTR_DEPRECATED +#endif + +/* Wrappers for the libgpg-error library. */ + +typedef gpg_error_t gcry_error_t; +typedef gpg_err_code_t gcry_err_code_t; +typedef gpg_err_source_t gcry_err_source_t; + +static GPG_ERR_INLINE gcry_error_t +gcry_err_make (gcry_err_source_t source, gcry_err_code_t code) +{ + return gpg_err_make (source, code); +} + +/* The user can define GPG_ERR_SOURCE_DEFAULT before including this + file to specify a default source for gpg_error. */ +#ifndef GCRY_ERR_SOURCE_DEFAULT +#define GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_USER_1 +#endif + +static GPG_ERR_INLINE gcry_error_t +gcry_error (gcry_err_code_t code) +{ + return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code); +} + +static GPG_ERR_INLINE gcry_err_code_t +gcry_err_code (gcry_error_t err) +{ + return gpg_err_code (err); +} + + +static GPG_ERR_INLINE gcry_err_source_t +gcry_err_source (gcry_error_t err) +{ + return gpg_err_source (err); +} + +/* Return a pointer to a string containing a description of the error + code in the error value ERR. */ +const char *gcry_strerror (gcry_error_t err); + +/* Return a pointer to a string containing a description of the error + source in the error value ERR. */ +const char *gcry_strsource (gcry_error_t err); + +/* Retrieve the error code for the system error ERR. This returns + GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report + this). */ +gcry_err_code_t gcry_err_code_from_errno (int err); + +/* Retrieve the system error for the error code CODE. This returns 0 + if CODE is not a system error code. */ +int gcry_err_code_to_errno (gcry_err_code_t code); + +/* Return an error value with the error source SOURCE and the system + error ERR. */ +gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err); + +/* Return an error value with the system error ERR. */ +gcry_err_code_t gcry_error_from_errno (int err); + + +/* This enum is deprecated; it is only declared for the sake of + complete API compatibility. */ +enum gcry_thread_option + { + _GCRY_THREAD_OPTION_DUMMY + } _GCRY_GCC_ATTR_DEPRECATED; + + +/* Constants defining the thread model to use. Used with the OPTION + field of the struct gcry_thread_cbs. */ +#define GCRY_THREAD_OPTION_DEFAULT 0 +#define GCRY_THREAD_OPTION_USER 1 +#define GCRY_THREAD_OPTION_PTH 2 +#define GCRY_THREAD_OPTION_PTHREAD 3 + +/* The version number encoded in the OPTION field of the struct + gcry_thread_cbs. */ +#define GCRY_THREAD_OPTION_VERSION 0 + +/* Wrapper for struct ath_ops. */ +struct gcry_thread_cbs +{ + /* 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; + + int (*init) (void); + int (*mutex_init) (void **priv); + int (*mutex_destroy) (void **priv); + int (*mutex_lock) (void **priv); + int (*mutex_unlock) (void **priv); + ssize_t (*read) (int fd, void *buf, size_t nbytes); + ssize_t (*write) (int fd, const void *buf, size_t nbytes); +#ifdef _WIN32 + ssize_t (*select) (int nfd, void *rset, void *wset, void *eset, + struct timeval *timeout); + ssize_t (*waitpid) (pid_t pid, int *status, int options); + int (*accept) (int s, void *addr, int *length_ptr); + int (*connect) (int s, void *addr, gcry_socklen_t length); + int (*sendmsg) (int s, const void *msg, int flags); + int (*recvmsg) (int s, void *msg, int flags); +#else + ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, + struct timeval *timeout); + ssize_t (*waitpid) (pid_t pid, int *status, int options); + int (*accept) (int s, struct sockaddr *addr, gcry_socklen_t *length_ptr); + int (*connect) (int s, struct sockaddr *addr, gcry_socklen_t length); + int (*sendmsg) (int s, const struct msghdr *msg, int flags); + int (*recvmsg) (int s, struct msghdr *msg, int flags); +#endif +}; + +#ifdef _WIN32 +# define _GCRY_THREAD_OPTION_PTH_IMPL_NET \ +static ssize_t gcry_pth_select (int nfd, void *rset, void *wset, \ + void *eset, struct timeval *timeout) \ + { return pth_select (nfd, rset, wset, eset, timeout); } \ +static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \ + { return pth_waitpid (pid, status, options); } \ +static int gcry_pth_accept (int s, void *addr, \ + gcry_socklen_t *length_ptr) \ + { return pth_accept (s, addr, length_ptr); } \ +static int gcry_pth_connect (int s, void *addr, \ + gcry_socklen_t length) \ + { return pth_connect (s, addr, length); } +#else /*!_WIN32*/ +# define _GCRY_THREAD_OPTION_PTH_IMPL_NET \ +static ssize_t gcry_pth_select (int nfd, fd_set *rset, fd_set *wset, \ + fd_set *eset, struct timeval *timeout) \ + { return pth_select (nfd, rset, wset, eset, timeout); } \ +static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \ + { return pth_waitpid (pid, status, options); } \ +static int gcry_pth_accept (int s, struct sockaddr *addr, \ + gcry_socklen_t *length_ptr) \ + { return pth_accept (s, addr, length_ptr); } \ +static int gcry_pth_connect (int s, struct sockaddr *addr, \ + gcry_socklen_t length) \ + { return pth_connect (s, addr, length); } +#endif /*!_WIN32*/ + + + +#define GCRY_THREAD_OPTION_PTH_IMPL \ +static int gcry_pth_init (void) \ +{ return (pth_init () == FALSE) ? errno : 0; } \ +static int gcry_pth_mutex_init (void **priv) \ +{ \ + int err = 0; \ + pth_mutex_t *lock = malloc (sizeof (pth_mutex_t)); \ + \ + if (!lock) \ + err = ENOMEM; \ + if (!err) \ + { \ + err = pth_mutex_init (lock); \ + if (err == FALSE) \ + err = errno; \ + else \ + err = 0; \ + if (err) \ + free (lock); \ + else \ + *priv = lock; \ + } \ + return err; \ +} \ +static int gcry_pth_mutex_destroy (void **lock) \ + { /* GNU Pth has no destructor function. */ free (*lock); return 0; } \ +static int gcry_pth_mutex_lock (void **lock) \ + { return ((pth_mutex_acquire (*lock, 0, NULL)) == FALSE) \ + ? errno : 0; } \ +static int gcry_pth_mutex_unlock (void **lock) \ + { return ((pth_mutex_release (*lock)) == FALSE) \ + ? errno : 0; } \ +static ssize_t gcry_pth_read (int fd, void *buf, size_t nbytes) \ + { return pth_read (fd, buf, nbytes); } \ +static ssize_t gcry_pth_write (int fd, const void *buf, size_t nbytes) \ + { return pth_write (fd, buf, nbytes); } \ +_GCRY_THREAD_OPTION_PTH_IMPL_NET \ + \ +/* Note: GNU Pth is missing pth_sendmsg and pth_recvmsg. */ \ +static struct gcry_thread_cbs gcry_threads_pth = { \ + (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8)), \ + gcry_pth_init, gcry_pth_mutex_init, gcry_pth_mutex_destroy, \ + gcry_pth_mutex_lock, gcry_pth_mutex_unlock, gcry_pth_read, gcry_pth_write, \ + gcry_pth_select, gcry_pth_waitpid, gcry_pth_accept, gcry_pth_connect, \ + NULL, NULL } + + +#define GCRY_THREAD_OPTION_PTHREAD_IMPL \ +static int gcry_pthread_mutex_init (void **priv) \ +{ \ + int err = 0; \ + pthread_mutex_t *lock = (pthread_mutex_t*)malloc (sizeof (pthread_mutex_t));\ + \ + if (!lock) \ + err = ENOMEM; \ + if (!err) \ + { \ + err = pthread_mutex_init (lock, NULL); \ + if (err) \ + free (lock); \ + else \ + *priv = lock; \ + } \ + return err; \ +} \ +static int gcry_pthread_mutex_destroy (void **lock) \ + { int err = pthread_mutex_destroy ((pthread_mutex_t*)*lock); \ + free (*lock); return err; } \ +static int gcry_pthread_mutex_lock (void **lock) \ + { return pthread_mutex_lock ((pthread_mutex_t*)*lock); } \ +static int gcry_pthread_mutex_unlock (void **lock) \ + { return pthread_mutex_unlock ((pthread_mutex_t*)*lock); } \ + \ +static struct gcry_thread_cbs gcry_threads_pthread = { \ + (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)), \ + NULL, gcry_pthread_mutex_init, gcry_pthread_mutex_destroy, \ + gcry_pthread_mutex_lock, gcry_pthread_mutex_unlock, \ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } + + +/* The data object used to hold a multi precision integer. */ +struct gcry_mpi; +typedef struct gcry_mpi *gcry_mpi_t; + +#ifndef GCRYPT_NO_DEPRECATED +typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED; +typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED; +#endif + + + +/* Check that the library fulfills the version requirement. */ +const char *gcry_check_version (const char *req_version); + +/* Codes for function dispatchers. */ + +/* Codes used with the gcry_control function. */ +enum gcry_ctl_cmds + { + GCRYCTL_SET_KEY = 1, + GCRYCTL_SET_IV = 2, + GCRYCTL_CFB_SYNC = 3, + GCRYCTL_RESET = 4, /* e.g. for MDs */ + GCRYCTL_FINALIZE = 5, + GCRYCTL_GET_KEYLEN = 6, + GCRYCTL_GET_BLKLEN = 7, + GCRYCTL_TEST_ALGO = 8, + GCRYCTL_IS_SECURE = 9, + GCRYCTL_GET_ASNOID = 10, + GCRYCTL_ENABLE_ALGO = 11, + GCRYCTL_DISABLE_ALGO = 12, + GCRYCTL_DUMP_RANDOM_STATS = 13, + GCRYCTL_DUMP_SECMEM_STATS = 14, + GCRYCTL_GET_ALGO_NPKEY = 15, + GCRYCTL_GET_ALGO_NSKEY = 16, + GCRYCTL_GET_ALGO_NSIGN = 17, + GCRYCTL_GET_ALGO_NENCR = 18, + GCRYCTL_SET_VERBOSITY = 19, + GCRYCTL_SET_DEBUG_FLAGS = 20, + GCRYCTL_CLEAR_DEBUG_FLAGS = 21, + GCRYCTL_USE_SECURE_RNDPOOL= 22, + GCRYCTL_DUMP_MEMORY_STATS = 23, + GCRYCTL_INIT_SECMEM = 24, + GCRYCTL_TERM_SECMEM = 25, + GCRYCTL_DISABLE_SECMEM_WARN = 27, + GCRYCTL_SUSPEND_SECMEM_WARN = 28, + GCRYCTL_RESUME_SECMEM_WARN = 29, + GCRYCTL_DROP_PRIVS = 30, + GCRYCTL_ENABLE_M_GUARD = 31, + GCRYCTL_START_DUMP = 32, + GCRYCTL_STOP_DUMP = 33, + GCRYCTL_GET_ALGO_USAGE = 34, + GCRYCTL_IS_ALGO_ENABLED = 35, + GCRYCTL_DISABLE_INTERNAL_LOCKING = 36, + GCRYCTL_DISABLE_SECMEM = 37, + GCRYCTL_INITIALIZATION_FINISHED = 38, + GCRYCTL_INITIALIZATION_FINISHED_P = 39, + GCRYCTL_ANY_INITIALIZATION_P = 40, + GCRYCTL_SET_CBC_CTS = 41, + GCRYCTL_SET_CBC_MAC = 42, + GCRYCTL_SET_CTR = 43, + GCRYCTL_ENABLE_QUICK_RANDOM = 44, + GCRYCTL_SET_RANDOM_SEED_FILE = 45, + GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46, + GCRYCTL_SET_THREAD_CBS = 47, + GCRYCTL_FAST_POLL = 48, + GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49, + GCRYCTL_USE_RANDOM_DAEMON = 50, + GCRYCTL_FAKED_RANDOM_P = 51, + GCRYCTL_SET_RNDEGD_SOCKET = 52, + GCRYCTL_PRINT_CONFIG = 53, + GCRYCTL_OPERATIONAL_P = 54, + GCRYCTL_FIPS_MODE_P = 55, + GCRYCTL_FORCE_FIPS_MODE = 56, + GCRYCTL_SELFTEST = 57 + /* Note: 58 .. 62 are used internally. */ + }; + +/* Perform various operations defined by CMD. */ +gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...); + + +/* S-expression management. */ + +/* The object to represent an S-expression as used with the public key + functions. */ +struct gcry_sexp; +typedef struct gcry_sexp *gcry_sexp_t; + +#ifndef GCRYPT_NO_DEPRECATED +typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED; +typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED; +#endif + +/* The possible values for the S-expression format. */ +enum gcry_sexp_format + { + GCRYSEXP_FMT_DEFAULT = 0, + GCRYSEXP_FMT_CANON = 1, + GCRYSEXP_FMT_BASE64 = 2, + GCRYSEXP_FMT_ADVANCED = 3 + }; + +/* Create an new S-expression object from BUFFER of size LENGTH and + return it in RETSEXP. With AUTODETECT set to 0 the data in BUFFER + is expected to be in canonized format. */ +gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp, + const void *buffer, size_t length, + int autodetect); + + /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the + effect to transfer ownership of BUFFER to the created object. */ +gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp, + void *buffer, size_t length, + int autodetect, void (*freefnc) (void *)); + +/* Scan BUFFER and return a new S-expression object in RETSEXP. This + function expects a printf like string in BUFFER. */ +gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, + const char *buffer, size_t length); + +/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus + only be used for certain encodings. */ +gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, + const char *format, ...); + +/* Like gcry_sexp_build, but uses an array instead of variable + function arguments. */ +gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, + const char *format, void **arg_list); + +/* Release the S-expression object SEXP */ +void gcry_sexp_release (gcry_sexp_t sexp); + +/* Calculate the length of an canonized S-expresion in BUFFER and + check for a valid encoding. */ +size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, + size_t *erroff, gcry_error_t *errcode); + +/* Copies the S-expression object SEXP into BUFFER using the format + specified in MODE. */ +size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, + size_t maxlength); + +/* Dumps the S-expression object A in a format suitable for debugging + to Libgcrypt's logging stream. */ +void gcry_sexp_dump (const gcry_sexp_t a); + +gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b); +gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array); +gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...); +gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n); +gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n); + +/* Scan the S-expression for a sublist with a type (the car of the + list) matching the string TOKEN. If TOKLEN is not 0, the token is + assumed to be raw memory of this length. The function returns a + newly allocated S-expression consisting of the found sublist or + `NULL' when not found. */ +gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list, + const char *tok, size_t toklen); +/* Return the length of the LIST. For a valid S-expression this + should be at least 1. */ +int gcry_sexp_length (const gcry_sexp_t list); + +/* Create and return a new S-expression from the element with index + NUMBER in LIST. Note that the first element has the index 0. If + there is no such element, `NULL' is returned. */ +gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number); + +/* Create and return a new S-expression from the first element in + LIST; this called the "type" and should always exist and be a + string. `NULL' is returned in case of a problem. */ +gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list); + +/* Create and return a new list form all elements except for the first + one. Note, that this function may return an invalid S-expression + because it is not guaranteed, that the type exists and is a string. + However, for parsing a complex S-expression it might be useful for + intermediate lists. Returns `NULL' on error. */ +gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list); + +gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list); + + +/* This function is used to get data from a LIST. A pointer to the + actual data with index NUMBER is returned and the length of this + data will be stored to DATALEN. If there is no data at the given + index or the index represents another list, `NULL' is returned. + *Note:* The returned pointer is valid as long as LIST is not + modified or released. */ +const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number, + size_t *datalen); + +/* This function is used to get and convert data from a LIST. The + data is assumed to be a Nul terminated string. The caller must + release the returned value using `gcry_free'. If there is no data + at the given index, the index represents a list or the value can't + be converted to a string, `NULL' is returned. */ +char *gcry_sexp_nth_string (gcry_sexp_t list, int number); + +/* This function is used to get and convert data from a LIST. This + data is assumed to be an MPI stored in the format described by + MPIFMT and returned as a standard Libgcrypt MPI. The caller must + release this returned value using `gcry_mpi_release'. If there is + no data at the given index, the index represents a list or the + value can't be converted to an MPI, `NULL' is returned. */ +gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt); + + + +/******************************************* + * * + * Multi Precision Integer Functions * + * * + *******************************************/ + +/* Different formats of external big integer representation. */ +enum gcry_mpi_format + { + GCRYMPI_FMT_NONE= 0, + GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */ + GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */ + GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */ + GCRYMPI_FMT_HEX = 4, /* Hex format. */ + GCRYMPI_FMT_USG = 5 /* Like STD but unsigned. */ + }; + +/* Flags used for creating big integers. */ +enum gcry_mpi_flag + { + GCRYMPI_FLAG_SECURE = 1, /* Allocate the number in "secure" memory. */ + GCRYMPI_FLAG_OPAQUE = 2 /* The number is not a real one but just + a way to store some bytes. This is + useful for encrypted big integers. */ + }; + + +/* Allocate a new big integer object, initialize it with 0 and + initially allocate memory for a number of at least NBITS. */ +gcry_mpi_t gcry_mpi_new (unsigned int nbits); + +/* Same as gcry_mpi_new() but allocate in "secure" memory. */ +gcry_mpi_t gcry_mpi_snew (unsigned int nbits); + +/* Release the number A and free all associated resources. */ +void gcry_mpi_release (gcry_mpi_t a); + +/* Create a new number with the same value as A. */ +gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a); + +/* Store the big integer value U in W. */ +gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u); + +/* Store the unsigned integer value U in W. */ +gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u); + +/* Swap the values of A and B. */ +void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b); + +/* Compare the big integer number U and V returning 0 for equality, a + positive value for U > V and a negative for U < V. */ +int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v); + +/* Compare the big integer number U with the unsigned integer V + returning 0 for equality, a positive value for U > V and a negative + for U < V. */ +int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v); + +/* Convert the external representation of an integer stored in BUFFER + with a length of BUFLEN into a newly create MPI returned in + RET_MPI. If NSCANNED is not NULL, it will receive the number of + bytes actually scanned after a successful operation. */ +gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, + const void *buffer, size_t buflen, + size_t *nscanned); + +/* Convert the big integer A into the external representation + described by FORMAT and store it in the provided BUFFER which has + been allocated by the user with a size of BUFLEN bytes. NWRITTEN + receives the actual length of the external representation unless it + has been passed as NULL. */ +gcry_error_t gcry_mpi_print (enum gcry_mpi_format format, + unsigned char *buffer, size_t buflen, + size_t *nwritten, + const gcry_mpi_t a); + +/* Convert the big integer A int the external representation described + by FORMAT and store it in a newly allocated buffer which address + will be put into BUFFER. NWRITTEN receives the actual lengths of the + external representation. */ +gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format, + unsigned char **buffer, size_t *nwritten, + const gcry_mpi_t a); + +/* Dump the value of A in a format suitable for debugging to + Libgcrypt's logging stream. Note that one leading space but no + trailing space or linefeed will be printed. It is okay to pass + NULL for A. */ +void gcry_mpi_dump (const gcry_mpi_t a); + + +/* W = U + V. */ +void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); + +/* W = U + V. V is an unsigned integer. */ +void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v); + +/* W = U + V mod M. */ +void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); + +/* W = U - V. */ +void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); + +/* W = U - V. V is an unsigned integer. */ +void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); + +/* W = U - V mod M */ +void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); + +/* W = U * V. */ +void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); + +/* W = U * V. V is an unsigned integer. */ +void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); + +/* W = U * V mod M. */ +void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); + +/* W = U * (2 ^ CNT). */ +void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt); + +/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR, + Q or R may be passed as NULL. ROUND should be negative or 0. */ +void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, + gcry_mpi_t dividend, gcry_mpi_t divisor, int round); + +/* R = DIVIDEND % DIVISOR */ +void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor); + +/* W = B ^ E mod M. */ +void gcry_mpi_powm (gcry_mpi_t w, + const gcry_mpi_t b, const gcry_mpi_t e, + const gcry_mpi_t m); + +/* Set G to the greatest common divisor of A and B. + Return true if the G is 1. */ +int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b); + +/* Set X to the multiplicative inverse of A mod M. + Return true if the value exists. */ +int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m); + + +/* Return the number of bits required to represent A. */ +unsigned int gcry_mpi_get_nbits (gcry_mpi_t a); + +/* Return true when bit number N (counting from 0) is set in A. */ +int gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n); + +/* Set bit number N in A. */ +void gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n); + +/* Clear bit number N in A. */ +void gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n); + +/* Set bit number N in A and clear all bits greater than N. */ +void gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n); + +/* Clear bit number N in A and all bits greater than N. */ +void gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n); + +/* Shift the value of A by N bits to the right and store the result in X. */ +void gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); + +/* Shift the value of A by N bits to the left and store the result in X. */ +void gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); + +/* Store NBITS of the value P points to in A and mark A as an opaque + value. WARNING: Never use an opaque MPI for anything thing else then + gcry_mpi_release, gcry_mpi_get_opaque. */ +gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits); + +/* Return a pointer to an opaque value stored in A and return its size + in NBITS. Note that the returned pointer is still owned by A and + that the function should never be used for an non-opaque MPI. */ +void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits); + +/* Set the FLAG for the big integer A. Currently only the flag + GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger + stored in "secure" memory. */ +void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); + +/* Clear FLAG for the big integer A. Note that this function is + currently useless as no flags are allowed. */ +void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); + +/* Return true when the FLAG is set for A. */ +int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); + +/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of + convenience macros for the big integer functions. */ +#ifndef GCRYPT_NO_MPI_MACROS +#define mpi_new(n) gcry_mpi_new( (n) ) +#define mpi_secure_new( n ) gcry_mpi_snew( (n) ) +#define mpi_release(a) \ + do \ + { \ + gcry_mpi_release ((a)); \ + (a) = NULL; \ + } \ + while (0) + +#define mpi_copy( a ) gcry_mpi_copy( (a) ) +#define mpi_set( w, u) gcry_mpi_set( (w), (u) ) +#define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) ) +#define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) ) +#define mpi_cmp_ui( u, v ) gcry_mpi_cmp_ui( (u), (v) ) + +#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)) +#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)) +#define mpi_powm(w,b,e,m) gcry_mpi_powm ( (w), (b), (e), (m) ) +#define mpi_tdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), 0) +#define mpi_fdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), -1) +#define mpi_mod(r,a,m) gcry_mpi_mod ((r), (a), (m)) +#define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) ) +#define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) ) + +#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)) + +#define mpi_set_opaque(a,b,c) gcry_mpi_set_opaque( (a), (b), (c) ) +#define mpi_get_opaque(a,b) gcry_mpi_get_opaque( (a), (b) ) +#endif /* GCRYPT_NO_MPI_MACROS */ + + + +/************************************ + * * + * Symmetric Cipher Functions * + * * + ************************************/ + +/* The data object used to hold a handle to an encryption object. */ +struct gcry_cipher_handle; +typedef struct gcry_cipher_handle *gcry_cipher_hd_t; + +#ifndef GCRYPT_NO_DEPRECATED +typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED; +typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED; +#endif + +/* All symmetric encryption algorithms are identified by their IDs. + More IDs may be registered at runtime. */ +enum gcry_cipher_algos + { + GCRY_CIPHER_NONE = 0, + GCRY_CIPHER_IDEA = 1, + GCRY_CIPHER_3DES = 2, + GCRY_CIPHER_CAST5 = 3, + GCRY_CIPHER_BLOWFISH = 4, + GCRY_CIPHER_SAFER_SK128 = 5, + GCRY_CIPHER_DES_SK = 6, + GCRY_CIPHER_AES = 7, + GCRY_CIPHER_AES192 = 8, + GCRY_CIPHER_AES256 = 9, + GCRY_CIPHER_TWOFISH = 10, + + /* Other cipher numbers are above 300 for OpenPGP reasons. */ + GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */ + GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */ + GCRY_CIPHER_TWOFISH128 = 303, + GCRY_CIPHER_SERPENT128 = 304, + GCRY_CIPHER_SERPENT192 = 305, + GCRY_CIPHER_SERPENT256 = 306, + GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */ + GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */ + GCRY_CIPHER_SEED = 309, /* 128 bit cipher described in RFC4269. */ + GCRY_CIPHER_CAMELLIA128 = 310, + GCRY_CIPHER_CAMELLIA192 = 311, + GCRY_CIPHER_CAMELLIA256 = 312 + }; + +/* The Rijndael algorithm is basically AES, so provide some macros. */ +#define GCRY_CIPHER_AES128 GCRY_CIPHER_AES +#define GCRY_CIPHER_RIJNDAEL GCRY_CIPHER_AES +#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128 +#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192 +#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256 + +/* The supported encryption modes. Note that not all of them are + supported for each algorithm. */ +enum gcry_cipher_modes + { + GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */ + GCRY_CIPHER_MODE_ECB = 1, /* Electronic codebook. */ + GCRY_CIPHER_MODE_CFB = 2, /* Cipher feedback. */ + GCRY_CIPHER_MODE_CBC = 3, /* Cipher block chaining. */ + GCRY_CIPHER_MODE_STREAM = 4, /* Used with stream ciphers. */ + GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */ + GCRY_CIPHER_MODE_CTR = 6, /* Counter. */ + GCRY_CIPHER_MODE_AESWRAP= 7 /* AES-WRAP algorithm. */ + }; + +/* Flags used with the open function. */ +enum gcry_cipher_flags + { + GCRY_CIPHER_SECURE = 1, /* Allocate in secure memory. */ + GCRY_CIPHER_ENABLE_SYNC = 2, /* Enable CFB sync mode. */ + GCRY_CIPHER_CBC_CTS = 4, /* Enable CBC cipher text stealing (CTS). */ + GCRY_CIPHER_CBC_MAC = 8 /* Enable CBC message auth. code (MAC). */ + }; + + +/* Create a handle for algorithm ALGO to be used in MODE. FLAGS may + be given as an bitwise OR of the gcry_cipher_flags values. */ +gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle, + int algo, int mode, unsigned int flags); + +/* Close the cioher handle H and release all resource. */ +void gcry_cipher_close (gcry_cipher_hd_t h); + +/* Perform various operations on the cipher object H. */ +gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, + size_t buflen); + +/* Retrieve various information about the cipher object H. */ +gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, + size_t *nbytes); + +/* Retrieve various information about the cipher algorithm ALGO. */ +gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer, + size_t *nbytes); + +/* Map the cipher algorithm whose ID is contained in ALGORITHM to a + string representation of the algorithm name. For unknown algorithm + IDs this function returns "?". */ +const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; + +/* Map the algorithm name NAME to an cipher algorithm ID. Return 0 if + the algorithm name is not known. */ +int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE; + +/* Given an ASN.1 object identifier in standard IETF dotted decimal + format in STRING, return the encryption mode associated with that + OID or 0 if not known or applicable. */ +int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE; + +/* Encrypt the plaintext of size INLEN in IN using the cipher handle H + into the buffer OUT which has an allocated length of OUTSIZE. For + most algorithms it is possible to pass NULL for in and 0 for INLEN + and do a in-place decryption of the data provided in OUT. */ +gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h, + void *out, size_t outsize, + const void *in, size_t inlen); + +/* The counterpart to gcry_cipher_encrypt. */ +gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h, + void *out, size_t outsize, + const void *in, size_t inlen); + +/* Set KEY of length KEYLEN bytes for the cipher handle HD. */ +gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd, + const void *key, size_t keylen); + + +/* Set initialization vector IV of length IVLEN for the cipher handle HD. */ +gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd, + const void *iv, size_t ivlen); + + +/* Reset the handle to the state after open. */ +#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0) + +/* Perform the OpenPGP sync operation if this is enabled for the + cipher handle H. */ +#define gcry_cipher_sync(h) gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0) + +/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */ +#define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \ + NULL, on ) + +/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of + block size length, or (NULL,0) to set the CTR to the all-zero block. */ +gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd, + const void *ctr, size_t ctrlen); + +/* Retrieved the key length in bytes used with algorithm A. */ +size_t gcry_cipher_get_algo_keylen (int algo); + +/* Retrieve the block length in bytes used with algorithm A. */ +size_t gcry_cipher_get_algo_blklen (int algo); + +/* Return 0 if the algorithm A is available for use. */ +#define gcry_cipher_test_algo(a) \ + gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) + +/* Get a list consisting of the IDs of the loaded cipher modules. If + LIST is zero, write the number of loaded cipher 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_error_t gcry_cipher_list (int *list, int *list_length); + + +/************************************ + * * + * Asymmetric Cipher Functions * + * * + ************************************/ + +/* The algorithms and their IDs we support. */ +enum gcry_pk_algos + { + GCRY_PK_RSA = 1, + GCRY_PK_RSA_E = 2, /* (deprecated) */ + GCRY_PK_RSA_S = 3, /* (deprecated) */ + GCRY_PK_ELG_E = 16, + GCRY_PK_DSA = 17, + GCRY_PK_ELG = 20, + GCRY_PK_ECDSA = 301 + }; + +/* Flags describing usage capabilities of a PK algorithm. */ +#define GCRY_PK_USAGE_SIGN 1 /* Good for signatures. */ +#define GCRY_PK_USAGE_ENCR 2 /* Good for encryption. */ +#define GCRY_PK_USAGE_CERT 4 /* Good to certify other keys. */ +#define GCRY_PK_USAGE_AUTH 8 /* Good for authentication. */ +#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */ + +/* Encrypt the DATA using the public key PKEY and store the result as + a newly created S-expression at RESULT. */ +gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result, + gcry_sexp_t data, gcry_sexp_t pkey); + +/* Decrypt the DATA using the private key SKEY and store the result as + a newly created S-expression at RESULT. */ +gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result, + gcry_sexp_t data, gcry_sexp_t skey); + +/* Sign the DATA using the private key SKEY and store the result as + a newly created S-expression at RESULT. */ +gcry_error_t gcry_pk_sign (gcry_sexp_t *result, + gcry_sexp_t data, gcry_sexp_t skey); + +/* Check the signature SIGVAL on DATA using the public key PKEY. */ +gcry_error_t gcry_pk_verify (gcry_sexp_t sigval, + gcry_sexp_t data, gcry_sexp_t pkey); + +/* Check that private KEY is sane. */ +gcry_error_t gcry_pk_testkey (gcry_sexp_t key); + +/* Generate a new key pair according to the parameters given in + S_PARMS. The new key pair is returned in as an S-expression in + R_KEY. */ +gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms); + +/* Catch all function for miscellaneous operations. */ +gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen); + +/* Retrieve information about the public key algorithm ALGO. */ +gcry_error_t gcry_pk_algo_info (int algo, int what, + void *buffer, size_t *nbytes); + +/* Map the public key algorithm whose ID is contained in ALGORITHM to + a string representation of the algorithm name. For unknown + algorithm IDs this functions returns "?". */ +const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; + +/* Map the algorithm NAME to a public key algorithm Id. Return 0 if + the algorithm name is not known. */ +int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE; + +/* Return what is commonly referred as the key length for the given + public or private KEY. */ +unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE; + +/* Please note that keygrip is still experimental and should not be + used without contacting the author. */ +unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array); + +/* Return 0 if the public key algorithm A is available for use. */ +#define gcry_pk_test_algo(a) \ + gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) + +/* Get a list consisting of the IDs of the loaded pubkey modules. If + LIST is zero, write the number of loaded pubkey 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 pubkey modules than + *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */ +gcry_error_t gcry_pk_list (int *list, int *list_length); + + + +/************************************ + * * + * Cryptograhic Hash Functions * + * * + ************************************/ + +/* Algorithm IDs for the hash functions we know about. Not all of them + are implemnted. */ +enum gcry_md_algos + { + GCRY_MD_NONE = 0, + GCRY_MD_MD5 = 1, + GCRY_MD_SHA1 = 2, + GCRY_MD_RMD160 = 3, + GCRY_MD_MD2 = 5, + GCRY_MD_TIGER = 6, /* TIGER/192 as used by GnuPG <= 1.3.2. */ + GCRY_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */ + GCRY_MD_SHA256 = 8, + GCRY_MD_SHA384 = 9, + GCRY_MD_SHA512 = 10, + GCRY_MD_SHA224 = 11, + GCRY_MD_MD4 = 301, + GCRY_MD_CRC32 = 302, + GCRY_MD_CRC32_RFC1510 = 303, + GCRY_MD_CRC24_RFC2440 = 304, + GCRY_MD_WHIRLPOOL = 305, + GCRY_MD_TIGER1 = 306, /* TIGER (fixed). */ + GCRY_MD_TIGER2 = 307 /* TIGER2 variant. */ + }; + +/* Flags used with the open function. */ +enum gcry_md_flags + { + GCRY_MD_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */ + GCRY_MD_FLAG_HMAC = 2 /* Make an HMAC out of this algorithm. */ + }; + +/* (Forward declaration.) */ +struct gcry_md_context; + +/* This object is used to hold a handle to a message digest object. + This structure is private - only to be used by the public gcry_md_* + macros. */ +typedef struct gcry_md_handle +{ + /* Actual context. */ + struct gcry_md_context *ctx; + + /* Buffer management. */ + int bufpos; + int bufsize; + unsigned char buf[1]; +} *gcry_md_hd_t; + +/* Compatibility types, do not use them. */ +#ifndef GCRYPT_NO_DEPRECATED +typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED; +typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED; +#endif + +/* Create a message digest object for algorithm ALGO. FLAGS may be + given as an bitwise OR of the gcry_md_flags values. ALGO may be + given as 0 if the algorithms to be used are later set using + gcry_md_enable. */ +gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags); + +/* Release the message digest object HD. */ +void gcry_md_close (gcry_md_hd_t hd); + +/* Add the message digest algorithm ALGO to the digest object HD. */ +gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo); + +/* Create a new digest object as an exact copy of the object HD. */ +gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd); + +/* Reset the digest object HD to its initial state. */ +void gcry_md_reset (gcry_md_hd_t hd); + +/* Perform various operations on the digest object HD. */ +gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd, + void *buffer, size_t buflen); + +/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that + it can update the digest values. This is the actual hash + function. */ +void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length); + +/* Read out the final digest from HD return the digest value for + algorithm ALGO. */ +unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo); + +/* Convenience function to calculate the hash from the data in BUFFER + of size LENGTH using the algorithm ALGO avoiding the creating of a + hash object. The hash is returned in the caller provided buffer + DIGEST which must be large enough to hold the digest of the given + algorithm. */ +void gcry_md_hash_buffer (int algo, void *digest, + const void *buffer, size_t length); + +/* Retrieve the algorithm used with HD. This does not work reliable + if more than one algorithm is enabled in HD. */ +int gcry_md_get_algo (gcry_md_hd_t hd); + +/* Retrieve the length in bytes of the digest yielded by algorithm + ALGO. */ +unsigned int gcry_md_get_algo_dlen (int algo); + +/* Return true if the the algorithm ALGO is enabled in the digest + object A. */ +int gcry_md_is_enabled (gcry_md_hd_t a, int algo); + +/* Return true if the digest object A is allocated in "secure" memory. */ +int gcry_md_is_secure (gcry_md_hd_t a); + +/* Retrieve various information about the object H. */ +gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer, + size_t *nbytes); + +/* Retrieve various information about the algorithm ALGO. */ +gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer, + size_t *nbytes); + +/* Map the digest algorithm id ALGO to a string representation of the + algorithm name. For unknown algorithms this function returns + "?". */ +const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE; + +/* Map the algorithm NAME to a digest algorithm Id. Return 0 if + the algorithm name is not known. */ +int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE; + +/* For use with the HMAC feature, the set MAC key to the KEY of + KEYLEN bytes. */ +gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen); + +/* Start or stop debugging for digest handle HD; i.e. create a file + named dbgmd-<n>.<suffix> while hashing. If SUFFIX is NULL, + debugging stops and the file will be closed. */ +void gcry_md_debug (gcry_md_hd_t hd, const char *suffix); + + +/* Update the hash(s) of H with the character C. This is a buffered + version of the gcry_md_write function. */ +#define gcry_md_putc(h,c) \ + do { \ + gcry_md_hd_t h__ = (h); \ + if( (h__)->bufpos == (h__)->bufsize ) \ + gcry_md_write( (h__), NULL, 0 ); \ + (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \ + } while(0) + +/* Finalize the digest calculation. This is not really needed because + gcry_md_read() does this implicitly. */ +#define gcry_md_final(a) \ + gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0) + +/* Return 0 if the algorithm A is available for use. */ +#define gcry_md_test_algo(a) \ + gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) + +/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N + must point to size_t variable with the available size of buffer B. + After return it will receive the actual size of the returned + OID. */ +#define gcry_md_get_asnoid(a,b,n) \ + gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n)) + +/* Enable debugging for digest object A; i.e. create files named + dbgmd-<n>.<string> while hashing. B is a string used as the suffix + for the filename. This macro is deprecated, use gcry_md_debug. */ +#ifndef GCRYPT_NO_DEPRECATED +#define gcry_md_start_debug(a,b) \ + gcry_md_ctl( (a), GCRYCTL_START_DUMP, (b), 0 ) + +/* Disable the debugging of A. This macro is deprecated, use + gcry_md_debug. */ +#define gcry_md_stop_debug(a,b) \ + gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 ) +#endif + +/* Get a list consisting of the IDs of the loaded message digest + modules. If LIST is zero, write the number of loaded message + digest 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 message digest modules + than *LIST_LENGTH, *LIST_LENGTH is updated to the correct + number. */ +gcry_error_t gcry_md_list (int *list, int *list_length); + + + +/* Alternative interface for asymmetric cryptography. This interface + is deprecated. */ + +/* The algorithm IDs. */ +typedef enum gcry_ac_id + { + GCRY_AC_RSA = 1, + GCRY_AC_DSA = 17, + GCRY_AC_ELG = 20, + GCRY_AC_ELG_E = 16 + } +gcry_ac_id_t; + +/* Key types. */ +typedef enum gcry_ac_key_type + { + GCRY_AC_KEY_SECRET, + GCRY_AC_KEY_PUBLIC + } +gcry_ac_key_type_t; + +/* Encoding methods. */ +typedef enum gcry_ac_em + { + GCRY_AC_EME_PKCS_V1_5, + GCRY_AC_EMSA_PKCS_V1_5 + } +gcry_ac_em_t; + +/* Encryption and Signature schemes. */ +typedef enum gcry_ac_scheme + { + GCRY_AC_ES_PKCS_V1_5, + GCRY_AC_SSA_PKCS_V1_5 + } +gcry_ac_scheme_t; + +/* AC data. */ +#define GCRY_AC_FLAG_DEALLOC (1 << 0) +#define GCRY_AC_FLAG_COPY (1 << 1) +#define GCRY_AC_FLAG_NO_BLINDING (1 << 2) + +/* This type represents a `data set'. */ +typedef struct gcry_ac_data *gcry_ac_data_t; + +/* This type represents a single `key', either a secret one or a + public one. */ +typedef struct gcry_ac_key *gcry_ac_key_t; + +/* This type represents a `key pair' containing a secret and a public + key. */ +typedef struct gcry_ac_key_pair *gcry_ac_key_pair_t; + +/* This type represents a `handle' that is needed by functions + performing cryptographic operations. */ +typedef struct gcry_ac_handle *gcry_ac_handle_t; + +typedef gpg_error_t (*gcry_ac_data_read_cb_t) (void *opaque, + unsigned char *buffer, + size_t *buffer_n); + +typedef gpg_error_t (*gcry_ac_data_write_cb_t) (void *opaque, + unsigned char *buffer, + size_t buffer_n); + +typedef enum + { + GCRY_AC_IO_READABLE, + GCRY_AC_IO_WRITABLE + } +gcry_ac_io_mode_t; + +typedef enum + { + GCRY_AC_IO_STRING, + GCRY_AC_IO_CALLBACK + } +gcry_ac_io_type_t; + +typedef struct gcry_ac_io +{ + /* This is an INTERNAL structure, do NOT use manually. */ + gcry_ac_io_mode_t mode _GCRY_ATTR_INTERNAL; + gcry_ac_io_type_t type _GCRY_ATTR_INTERNAL; + union + { + union + { + struct + { + gcry_ac_data_read_cb_t cb; + void *opaque; + } callback; + struct + { + unsigned char *data; + size_t data_n; + } string; + void *opaque; + } readable; + union + { + struct + { + gcry_ac_data_write_cb_t cb; + void *opaque; + } callback; + struct + { + unsigned char **data; + size_t *data_n; + } string; + void *opaque; + } writable; + } io _GCRY_ATTR_INTERNAL; +} +gcry_ac_io_t; + +/* The caller of gcry_ac_key_pair_generate can provide one of these + structures in order to influence the key generation process in an + algorithm-specific way. */ +typedef struct gcry_ac_key_spec_rsa +{ + gcry_mpi_t e; /* E to use. */ +} gcry_ac_key_spec_rsa_t; + +/* Structure used for passing data to the implementation of the + `EME-PKCS-V1_5' encoding method. */ +typedef struct gcry_ac_eme_pkcs_v1_5 +{ + size_t key_size; +} gcry_ac_eme_pkcs_v1_5_t; + +typedef enum gcry_md_algos gcry_md_algo_t; + +/* Structure used for passing data to the implementation of the + `EMSA-PKCS-V1_5' encoding method. */ +typedef struct gcry_ac_emsa_pkcs_v1_5 +{ + gcry_md_algo_t md; + size_t em_n; +} gcry_ac_emsa_pkcs_v1_5_t; + +/* Structure used for passing data to the implementation of the + `SSA-PKCS-V1_5' signature scheme. */ +typedef struct gcry_ac_ssa_pkcs_v1_5 +{ + gcry_md_algo_t md; +} gcry_ac_ssa_pkcs_v1_5_t; + +/* Returns a new, empty data set in DATA. */ +gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data); + +/* Destroy the data set DATA. */ +void gcry_ac_data_destroy (gcry_ac_data_t data); + +/* Create a copy of the data set DATA and store it in DATA_CP. */ +gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp, + gcry_ac_data_t data); + +/* Return the number of named MPI values inside of the data set + DATA. */ +unsigned int gcry_ac_data_length (gcry_ac_data_t data); + +/* Destroy any values contained in the data set DATA. */ +void gcry_ac_data_clear (gcry_ac_data_t data); + +/* Add the value MPI to DATA with the label NAME. If FLAGS contains + GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of NAME + and MPI. If FLAGS contains GCRY_AC_FLAG_DATA_DEALLOC or + GCRY_AC_FLAG_DATA_COPY, the values contained in the data set will + be deallocated when they are to be removed from the data set. */ +gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags, + const char *name, gcry_mpi_t mpi); + +/* Store the value labelled with NAME found in DATA in MPI. If FLAGS + contains GCRY_AC_FLAG_COPY, store a copy of the MPI value contained + in the data set. MPI may be NULL. */ +gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags, + const char *name, gcry_mpi_t *mpi); + +/* Stores in NAME and MPI the named MPI value contained in the data + set DATA with the index IDX. If FLAGS contains GCRY_AC_FLAG_COPY, + store copies of the values contained in the data set. NAME or MPI + may be NULL. */ +gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags, + unsigned int idx, + const char **name, gcry_mpi_t *mpi); + +/* Convert the data set DATA into a new S-Expression, which is to be + stored in SEXP, according to the identifiers contained in + IDENTIFIERS. */ +gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, + const char **identifiers); + +/* Create a new data set, which is to be stored in DATA_SET, from the + S-Expression SEXP, according to the identifiers contained in + IDENTIFIERS. */ +gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp, + const char **identifiers); + +/* Initialize AC_IO according to MODE, TYPE and the variable list of + arguments. The list of variable arguments to specify depends on + the given TYPE. */ +void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode, + gcry_ac_io_type_t type, ...); + +/* Initialize AC_IO according to MODE, TYPE and the variable list of + arguments AP. The list of variable arguments to specify depends on + the given TYPE. */ +void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode, + gcry_ac_io_type_t type, va_list ap); + +/* Create a new ac handle. */ +gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle, + gcry_ac_id_t algorithm, unsigned int flags); + +/* Destroy an ac handle. */ +void gcry_ac_close (gcry_ac_handle_t handle); + +/* Initialize a key from a given data set. */ +gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle, + gcry_ac_key_type_t type, gcry_ac_data_t data); + +/* Generates a new key pair via the handle HANDLE of NBITS bits and + stores it in KEY_PAIR. In case non-standard settings are wanted, a + pointer to a structure of type gcry_ac_key_spec_<algorithm>_t, + matching the selected algorithm, can be given as KEY_SPEC. + MISC_DATA is not used yet. */ +gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle, + unsigned int nbits, void *spec, + gcry_ac_key_pair_t *key_pair, + gcry_mpi_t **misc_data); + +/* Returns the key of type WHICH out of the key pair KEY_PAIR. */ +gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, + gcry_ac_key_type_t which); + +/* Returns the data set contained in the key KEY. */ +gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key); + +/* Verifies that the key KEY is sane via HANDLE. */ +gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key); + +/* Stores the number of bits of the key KEY in NBITS via HANDLE. */ +gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle, + gcry_ac_key_t key, unsigned int *nbits); + +/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via + HANDLE. */ +gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key, + unsigned char *key_grip); + +/* Destroy a key. */ +void gcry_ac_key_destroy (gcry_ac_key_t key); + +/* Destroy a key pair. */ +void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair); + +/* Encodes a message according to the encoding method METHOD. OPTIONS + must be a pointer to a method-specific structure + (gcry_ac_em*_t). */ +gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method, + unsigned int flags, void *options, + gcry_ac_io_t *io_read, + gcry_ac_io_t *io_write); + +/* Decodes a message according to the encoding method METHOD. OPTIONS + must be a pointer to a method-specific structure + (gcry_ac_em*_t). */ +gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method, + unsigned int flags, void *options, + gcry_ac_io_t *io_read, + gcry_ac_io_t *io_write); + +/* Encrypt the plain text MPI value DATA_PLAIN with the key KEY under + the control of the flags FLAGS and store the resulting data set + into DATA_ENCRYPTED. */ +gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle, + unsigned int flags, + gcry_ac_key_t key, + gcry_mpi_t data_plain, + gcry_ac_data_t *data_encrypted); + +/* Decrypt the decrypted data contained in the data set DATA_ENCRYPTED + with the key KEY under the control of the flags FLAGS and store the + resulting plain text MPI value in DATA_PLAIN. */ +gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle, + unsigned int flags, + gcry_ac_key_t key, + gcry_mpi_t *data_plain, + gcry_ac_data_t data_encrypted); + +/* Sign the data contained in DATA with the key KEY and store the + resulting signature in the data set DATA_SIGNATURE. */ +gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle, + gcry_ac_key_t key, + gcry_mpi_t data, + gcry_ac_data_t *data_signature); + +/* Verify that the signature contained in the data set DATA_SIGNATURE + is indeed the result of signing the data contained in DATA with the + secret key belonging to the public key KEY. */ +gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle, + gcry_ac_key_t key, + gcry_mpi_t data, + gcry_ac_data_t data_signature); + +/* Encrypts the plain text readable from IO_MESSAGE through HANDLE + with the public key KEY according to SCHEME, FLAGS and OPTS. If + OPTS is not NULL, it has to be a pointer to a structure specific to + the chosen scheme (gcry_ac_es_*_t). The encrypted message is + written to IO_CIPHER. */ +gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_message, + gcry_ac_io_t *io_cipher); + +/* Decrypts the cipher text readable from IO_CIPHER through HANDLE + with the secret key KEY according to SCHEME, @var{flags} and OPTS. + If OPTS is not NULL, it has to be a pointer to a structure specific + to the chosen scheme (gcry_ac_es_*_t). The decrypted message is + written to IO_MESSAGE. */ +gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_cipher, + gcry_ac_io_t *io_message); + +/* Signs the message readable from IO_MESSAGE through HANDLE with the + secret key KEY according to SCHEME, FLAGS and OPTS. If OPTS is not + NULL, it has to be a pointer to a structure specific to the chosen + scheme (gcry_ac_ssa_*_t). The signature is written to + IO_SIGNATURE. */ +gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_message, + gcry_ac_io_t *io_signature); + +/* Verifies through HANDLE that the signature readable from + IO_SIGNATURE is indeed the result of signing the message readable + from IO_MESSAGE with the secret key belonging to the public key KEY + according to SCHEME and OPTS. If OPTS is not NULL, it has to be an + anonymous structure (gcry_ac_ssa_*_t) specific to the chosen + scheme. */ +gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_message, + gcry_ac_io_t *io_signature); + +/* Store the textual representation of the algorithm whose id is given + in ALGORITHM in NAME. This function is deprecated; use + gcry_pk_algo_name. */ +#ifndef GCRYPT_NO_DEPRECATED +gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm, + const char **name) + /* */ _GCRY_GCC_ATTR_DEPRECATED; +/* Store the numeric ID of the algorithm whose textual representation + is contained in NAME in ALGORITHM. This function is deprecated; + use gcry_pk_map_name. */ +gcry_error_t gcry_ac_name_to_id (const char *name, + gcry_ac_id_t *algorithm) + /* */ _GCRY_GCC_ATTR_DEPRECATED; +#endif + + +/************************************ + * * + * Random Generating Functions * + * * + ************************************/ + +/* The possible values for the random quality. The rule of thumb is + to use STRONG for session keys and VERY_STRONG for key material. + WEAK is usually an alias for STRONG and should not be used anymore + (except with gcry_mpi_randomize); use gcry_create_nonce instead. */ +typedef enum gcry_random_level + { + GCRY_WEAK_RANDOM = 0, + GCRY_STRONG_RANDOM = 1, + GCRY_VERY_STRONG_RANDOM = 2 + } +gcry_random_level_t; + +/* Fill BUFFER with LENGTH bytes of random, using random numbers of + quality LEVEL. */ +void gcry_randomize (void *buffer, size_t length, + enum gcry_random_level level); + +/* Add the external random from BUFFER with LENGTH bytes into the + pool. QUALITY should either be -1 for unknown or in the range of 0 + to 100 */ +gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length, + int quality); + +/* If random numbers are used in an application, this macro should be + called from time to time so that new stuff gets added to the + internal pool of the RNG. */ +#define gcry_fast_random_poll() gcry_control (GCRYCTL_FAST_POLL, NULL) + + +/* Return NBYTES of allocated random using a random numbers of quality + LEVEL. */ +void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level) + _GCRY_GCC_ATTR_MALLOC; + +/* Return NBYTES of allocated random using a random numbers of quality + LEVEL. The random numbers are created returned in "secure" + memory. */ +void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) + _GCRY_GCC_ATTR_MALLOC; + + +/* Set the big integer W to a random value of NBITS using a random + generator with quality LEVEL. Note that by using a level of + GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */ +void gcry_mpi_randomize (gcry_mpi_t w, + unsigned int nbits, enum gcry_random_level level); + + +/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ +void gcry_create_nonce (void *buffer, size_t length); + + + + + +/*******************************/ +/* */ +/* Prime Number Functions */ +/* */ +/*******************************/ + +/* Mode values passed to a gcry_prime_check_func_t. */ +#define GCRY_PRIME_CHECK_AT_FINISH 0 +#define GCRY_PRIME_CHECK_AT_GOT_PRIME 1 +#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2 + +/* The function should return 1 if the operation shall continue, 0 to + reject the prime candidate. */ +typedef int (*gcry_prime_check_func_t) (void *arg, int mode, + gcry_mpi_t candidate); + +/* Flags for gcry_prime_generate(): */ + +/* Allocate prime numbers and factors in secure memory. */ +#define GCRY_PRIME_FLAG_SECRET (1 << 0) + +/* Make sure that at least one prime factor is of size + `FACTOR_BITS'. */ +#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1) + +/* Generate a new prime number of PRIME_BITS bits and store it in + PRIME. If FACTOR_BITS is non-zero, one of the prime factors of + (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is + non-zero, allocate a new, NULL-terminated array holding the prime + factors and store it in FACTORS. FLAGS might be used to influence + the prime number generation process. */ +gcry_error_t gcry_prime_generate (gcry_mpi_t *prime, + unsigned int prime_bits, + unsigned int factor_bits, + gcry_mpi_t **factors, + gcry_prime_check_func_t cb_func, + void *cb_arg, + gcry_random_level_t random_level, + unsigned int flags); + +/* Find a generator for PRIME where the factorization of (prime-1) is + in the NULL terminated array FACTORS. Return the generator as a + newly allocated MPI in R_G. If START_G is not NULL, use this as + teh start for the search. */ +gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g, + gcry_mpi_t prime, + gcry_mpi_t *factors, + gcry_mpi_t start_g); + + +/* Convenience function to release the FACTORS array. */ +void gcry_prime_release_factors (gcry_mpi_t *factors); + + +/* Check wether the number X is prime. */ +gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); + + + +/************************************ + * * + * Miscellaneous Stuff * + * * + ************************************/ + +/* Log levels used by the internal logging facility. */ +enum gcry_log_levels + { + GCRY_LOG_CONT = 0, /* (Continue the last log line.) */ + GCRY_LOG_INFO = 10, + GCRY_LOG_WARN = 20, + GCRY_LOG_ERROR = 30, + GCRY_LOG_FATAL = 40, + GCRY_LOG_BUG = 50, + GCRY_LOG_DEBUG = 100 + }; + +/* Type for progress handlers. */ +typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int); + +/* Type for memory allocation handlers. */ +typedef void *(*gcry_handler_alloc_t) (size_t n); + +/* Type for secure memory check handlers. */ +typedef int (*gcry_handler_secure_check_t) (const void *); + +/* Type for memory reallocation handlers. */ +typedef void *(*gcry_handler_realloc_t) (void *p, size_t n); + +/* Type for memory free handlers. */ +typedef void (*gcry_handler_free_t) (void *); + +/* Type for out-of-memory handlers. */ +typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int); + +/* Type for fatal error handlers. */ +typedef void (*gcry_handler_error_t) (void *, int, const char *); + +/* Type for logging handlers. */ +typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list); + +/* Certain operations can provide progress information. This function + is used to register a handler for retrieving these information. */ +void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data); + + +/* Register a custom memory allocation functions. */ +void gcry_set_allocation_handler ( + gcry_handler_alloc_t func_alloc, + gcry_handler_alloc_t func_alloc_secure, + gcry_handler_secure_check_t func_secure_check, + gcry_handler_realloc_t func_realloc, + gcry_handler_free_t func_free); + +/* Register a function used instead of the internal out of memory + handler. */ +void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque); + +/* Register a function used instead of the internal fatal error + handler. */ +void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque); + +/* Register a function used instead of the internal logging + facility. */ +void gcry_set_log_handler (gcry_handler_log_t f, void *opaque); + +/* Reserved for future use. */ +void gcry_set_gettext_handler (const char *(*f)(const char*)); + +/* Libgcrypt uses its own memory allocation. It is important to use + gcry_free () to release memory allocated by libgcrypt. */ +void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC; +void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; +void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +void *gcry_realloc (void *a, size_t n); +char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC; +void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC; +void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; +void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +void *gcry_xrealloc (void *a, size_t n); +char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC; +void gcry_free (void *a); + +/* Return true if A is allocated in "secure" memory. */ +int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; + +/* Return true if Libgcrypt is in FIPS mode. */ +#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) + + +/* Include support for Libgcrypt modules. */ +#include <gcrypt-module.h> + +#if 0 /* (Keep Emacsens' auto-indent happy.) */ +{ +#endif +#ifdef __cplusplus +} +#endif +#endif /* _GCRYPT_H */ diff --git a/plugins/MirOTR/Libgcrypt/src/gcrypt.h.in b/plugins/MirOTR/Libgcrypt/src/gcrypt.h.in new file mode 100644 index 0000000000..3d1cb4cb3d --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/gcrypt.h.in @@ -0,0 +1,1839 @@ +/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*- + Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006 + 2007, 2008, 2009, 2010 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/>. + + File: @configure_input@ */ + +#ifndef _GCRYPT_H +#define _GCRYPT_H + +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> + +#include <gpg-error.h> + +#include <sys/types.h> + +#if defined _WIN32 || defined __WIN32__ +# include <winsock2.h> +# include <ws2tcpip.h> +# include <time.h> +# ifndef __GNUC__ + typedef long ssize_t; + typedef int pid_t; +# endif /*!__GNUC__*/ +#else +# include <sys/socket.h> +# include <sys/time.h> +#endif /*!_WIN32*/ + +@FALLBACK_SOCKLEN_T@ + + +/* This is required for error code compatibility. */ +#define _GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_GCRYPT + +#ifdef __cplusplus +extern "C" { +#if 0 /* (Keep Emacsens' auto-indent happy.) */ +} +#endif +#endif + +/* The version of this header should match the one of the library. It + should not be used by a program because gcry_check_version() should + return the same version. The purpose of this macro is to let + autoconf (using the AM_PATH_GCRYPT macro) check that this header + matches the installed library. */ +#define GCRYPT_VERSION "@VERSION@" + +/* Internal: We can't use the convenience macros for the multi + precision integer functions when building this library. */ +#ifdef _GCRYPT_IN_LIBGCRYPT +#ifndef GCRYPT_NO_MPI_MACROS +#define GCRYPT_NO_MPI_MACROS 1 +#endif +#endif + +/* We want to use gcc attributes when possible. Warning: Don't use + these macros in your programs: As indicated by the leading + underscore they are subject to change without notice. */ +#ifdef __GNUC__ + +#define _GCRY_GCC_VERSION (__GNUC__ * 10000 \ + + __GNUC_MINOR__ * 100 \ + + __GNUC_PATCHLEVEL__) + +#if _GCRY_GCC_VERSION >= 30100 +#define _GCRY_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) +#endif + +#if _GCRY_GCC_VERSION >= 29600 +#define _GCRY_GCC_ATTR_PURE __attribute__ ((__pure__)) +#endif + +#if _GCRY_GCC_VERSION >= 30200 +#define _GCRY_GCC_ATTR_MALLOC __attribute__ ((__malloc__)) +#endif + +#endif /*__GNUC__*/ + +#ifndef _GCRY_GCC_ATTR_DEPRECATED +#define _GCRY_GCC_ATTR_DEPRECATED +#endif +#ifndef _GCRY_GCC_ATTR_PURE +#define _GCRY_GCC_ATTR_PURE +#endif +#ifndef _GCRY_GCC_ATTR_MALLOC +#define _GCRY_GCC_ATTR_MALLOC +#endif + +/* Some members in a public type should only be used internally. + There is no "internal" attribute, so we abuse the deprecated + attribute to discourage external use. */ +#ifdef _GCRYPT_IN_LIBGCRYPT +#define _GCRY_ATTR_INTERNAL +#else +#define _GCRY_ATTR_INTERNAL _GCRY_GCC_ATTR_DEPRECATED +#endif + +/* Wrappers for the libgpg-error library. */ + +typedef gpg_error_t gcry_error_t; +typedef gpg_err_code_t gcry_err_code_t; +typedef gpg_err_source_t gcry_err_source_t; + +static GPG_ERR_INLINE gcry_error_t +gcry_err_make (gcry_err_source_t source, gcry_err_code_t code) +{ + return gpg_err_make (source, code); +} + +/* The user can define GPG_ERR_SOURCE_DEFAULT before including this + file to specify a default source for gpg_error. */ +#ifndef GCRY_ERR_SOURCE_DEFAULT +#define GCRY_ERR_SOURCE_DEFAULT GPG_ERR_SOURCE_USER_1 +#endif + +static GPG_ERR_INLINE gcry_error_t +gcry_error (gcry_err_code_t code) +{ + return gcry_err_make (GCRY_ERR_SOURCE_DEFAULT, code); +} + +static GPG_ERR_INLINE gcry_err_code_t +gcry_err_code (gcry_error_t err) +{ + return gpg_err_code (err); +} + + +static GPG_ERR_INLINE gcry_err_source_t +gcry_err_source (gcry_error_t err) +{ + return gpg_err_source (err); +} + +/* Return a pointer to a string containing a description of the error + code in the error value ERR. */ +const char *gcry_strerror (gcry_error_t err); + +/* Return a pointer to a string containing a description of the error + source in the error value ERR. */ +const char *gcry_strsource (gcry_error_t err); + +/* Retrieve the error code for the system error ERR. This returns + GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report + this). */ +gcry_err_code_t gcry_err_code_from_errno (int err); + +/* Retrieve the system error for the error code CODE. This returns 0 + if CODE is not a system error code. */ +int gcry_err_code_to_errno (gcry_err_code_t code); + +/* Return an error value with the error source SOURCE and the system + error ERR. */ +gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err); + +/* Return an error value with the system error ERR. */ +gcry_err_code_t gcry_error_from_errno (int err); + + +/* This enum is deprecated; it is only declared for the sake of + complete API compatibility. */ +enum gcry_thread_option + { + _GCRY_THREAD_OPTION_DUMMY + } _GCRY_GCC_ATTR_DEPRECATED; + + +/* Constants defining the thread model to use. Used with the OPTION + field of the struct gcry_thread_cbs. */ +#define GCRY_THREAD_OPTION_DEFAULT 0 +#define GCRY_THREAD_OPTION_USER 1 +#define GCRY_THREAD_OPTION_PTH 2 +#define GCRY_THREAD_OPTION_PTHREAD 3 + +/* The version number encoded in the OPTION field of the struct + gcry_thread_cbs. */ +#define GCRY_THREAD_OPTION_VERSION 0 + +/* Wrapper for struct ath_ops. */ +struct gcry_thread_cbs +{ + /* 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; + + int (*init) (void); + int (*mutex_init) (void **priv); + int (*mutex_destroy) (void **priv); + int (*mutex_lock) (void **priv); + int (*mutex_unlock) (void **priv); + ssize_t (*read) (int fd, void *buf, size_t nbytes); + ssize_t (*write) (int fd, const void *buf, size_t nbytes); +#ifdef _WIN32 + ssize_t (*select) (int nfd, void *rset, void *wset, void *eset, + struct timeval *timeout); + ssize_t (*waitpid) (pid_t pid, int *status, int options); + int (*accept) (int s, void *addr, int *length_ptr); + int (*connect) (int s, void *addr, gcry_socklen_t length); + int (*sendmsg) (int s, const void *msg, int flags); + int (*recvmsg) (int s, void *msg, int flags); +#else + ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, + struct timeval *timeout); + ssize_t (*waitpid) (pid_t pid, int *status, int options); + int (*accept) (int s, struct sockaddr *addr, gcry_socklen_t *length_ptr); + int (*connect) (int s, struct sockaddr *addr, gcry_socklen_t length); + int (*sendmsg) (int s, const struct msghdr *msg, int flags); + int (*recvmsg) (int s, struct msghdr *msg, int flags); +#endif +}; + +#ifdef _WIN32 +# define _GCRY_THREAD_OPTION_PTH_IMPL_NET \ +static ssize_t gcry_pth_select (int nfd, void *rset, void *wset, \ + void *eset, struct timeval *timeout) \ + { return pth_select (nfd, rset, wset, eset, timeout); } \ +static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \ + { return pth_waitpid (pid, status, options); } \ +static int gcry_pth_accept (int s, void *addr, \ + gcry_socklen_t *length_ptr) \ + { return pth_accept (s, addr, length_ptr); } \ +static int gcry_pth_connect (int s, void *addr, \ + gcry_socklen_t length) \ + { return pth_connect (s, addr, length); } +#else /*!_WIN32*/ +# define _GCRY_THREAD_OPTION_PTH_IMPL_NET \ +static ssize_t gcry_pth_select (int nfd, fd_set *rset, fd_set *wset, \ + fd_set *eset, struct timeval *timeout) \ + { return pth_select (nfd, rset, wset, eset, timeout); } \ +static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \ + { return pth_waitpid (pid, status, options); } \ +static int gcry_pth_accept (int s, struct sockaddr *addr, \ + gcry_socklen_t *length_ptr) \ + { return pth_accept (s, addr, length_ptr); } \ +static int gcry_pth_connect (int s, struct sockaddr *addr, \ + gcry_socklen_t length) \ + { return pth_connect (s, addr, length); } +#endif /*!_WIN32*/ + + + +#define GCRY_THREAD_OPTION_PTH_IMPL \ +static int gcry_pth_init (void) \ +{ return (pth_init () == FALSE) ? errno : 0; } \ +static int gcry_pth_mutex_init (void **priv) \ +{ \ + int err = 0; \ + pth_mutex_t *lock = malloc (sizeof (pth_mutex_t)); \ + \ + if (!lock) \ + err = ENOMEM; \ + if (!err) \ + { \ + err = pth_mutex_init (lock); \ + if (err == FALSE) \ + err = errno; \ + else \ + err = 0; \ + if (err) \ + free (lock); \ + else \ + *priv = lock; \ + } \ + return err; \ +} \ +static int gcry_pth_mutex_destroy (void **lock) \ + { /* GNU Pth has no destructor function. */ free (*lock); return 0; } \ +static int gcry_pth_mutex_lock (void **lock) \ + { return ((pth_mutex_acquire (*lock, 0, NULL)) == FALSE) \ + ? errno : 0; } \ +static int gcry_pth_mutex_unlock (void **lock) \ + { return ((pth_mutex_release (*lock)) == FALSE) \ + ? errno : 0; } \ +static ssize_t gcry_pth_read (int fd, void *buf, size_t nbytes) \ + { return pth_read (fd, buf, nbytes); } \ +static ssize_t gcry_pth_write (int fd, const void *buf, size_t nbytes) \ + { return pth_write (fd, buf, nbytes); } \ +_GCRY_THREAD_OPTION_PTH_IMPL_NET \ + \ +/* Note: GNU Pth is missing pth_sendmsg and pth_recvmsg. */ \ +static struct gcry_thread_cbs gcry_threads_pth = { \ + (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8)), \ + gcry_pth_init, gcry_pth_mutex_init, gcry_pth_mutex_destroy, \ + gcry_pth_mutex_lock, gcry_pth_mutex_unlock, gcry_pth_read, gcry_pth_write, \ + gcry_pth_select, gcry_pth_waitpid, gcry_pth_accept, gcry_pth_connect, \ + NULL, NULL } + + +#define GCRY_THREAD_OPTION_PTHREAD_IMPL \ +static int gcry_pthread_mutex_init (void **priv) \ +{ \ + int err = 0; \ + pthread_mutex_t *lock = (pthread_mutex_t*)malloc (sizeof (pthread_mutex_t));\ + \ + if (!lock) \ + err = ENOMEM; \ + if (!err) \ + { \ + err = pthread_mutex_init (lock, NULL); \ + if (err) \ + free (lock); \ + else \ + *priv = lock; \ + } \ + return err; \ +} \ +static int gcry_pthread_mutex_destroy (void **lock) \ + { int err = pthread_mutex_destroy ((pthread_mutex_t*)*lock); \ + free (*lock); return err; } \ +static int gcry_pthread_mutex_lock (void **lock) \ + { return pthread_mutex_lock ((pthread_mutex_t*)*lock); } \ +static int gcry_pthread_mutex_unlock (void **lock) \ + { return pthread_mutex_unlock ((pthread_mutex_t*)*lock); } \ + \ +static struct gcry_thread_cbs gcry_threads_pthread = { \ + (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)), \ + NULL, gcry_pthread_mutex_init, gcry_pthread_mutex_destroy, \ + gcry_pthread_mutex_lock, gcry_pthread_mutex_unlock, \ + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } + + +/* The data object used to hold a multi precision integer. */ +struct gcry_mpi; +typedef struct gcry_mpi *gcry_mpi_t; + +#ifndef GCRYPT_NO_DEPRECATED +typedef struct gcry_mpi *GCRY_MPI _GCRY_GCC_ATTR_DEPRECATED; +typedef struct gcry_mpi *GcryMPI _GCRY_GCC_ATTR_DEPRECATED; +#endif + + + +/* Check that the library fulfills the version requirement. */ +const char *gcry_check_version (const char *req_version); + +/* Codes for function dispatchers. */ + +/* Codes used with the gcry_control function. */ +enum gcry_ctl_cmds + { + GCRYCTL_SET_KEY = 1, + GCRYCTL_SET_IV = 2, + GCRYCTL_CFB_SYNC = 3, + GCRYCTL_RESET = 4, /* e.g. for MDs */ + GCRYCTL_FINALIZE = 5, + GCRYCTL_GET_KEYLEN = 6, + GCRYCTL_GET_BLKLEN = 7, + GCRYCTL_TEST_ALGO = 8, + GCRYCTL_IS_SECURE = 9, + GCRYCTL_GET_ASNOID = 10, + GCRYCTL_ENABLE_ALGO = 11, + GCRYCTL_DISABLE_ALGO = 12, + GCRYCTL_DUMP_RANDOM_STATS = 13, + GCRYCTL_DUMP_SECMEM_STATS = 14, + GCRYCTL_GET_ALGO_NPKEY = 15, + GCRYCTL_GET_ALGO_NSKEY = 16, + GCRYCTL_GET_ALGO_NSIGN = 17, + GCRYCTL_GET_ALGO_NENCR = 18, + GCRYCTL_SET_VERBOSITY = 19, + GCRYCTL_SET_DEBUG_FLAGS = 20, + GCRYCTL_CLEAR_DEBUG_FLAGS = 21, + GCRYCTL_USE_SECURE_RNDPOOL= 22, + GCRYCTL_DUMP_MEMORY_STATS = 23, + GCRYCTL_INIT_SECMEM = 24, + GCRYCTL_TERM_SECMEM = 25, + GCRYCTL_DISABLE_SECMEM_WARN = 27, + GCRYCTL_SUSPEND_SECMEM_WARN = 28, + GCRYCTL_RESUME_SECMEM_WARN = 29, + GCRYCTL_DROP_PRIVS = 30, + GCRYCTL_ENABLE_M_GUARD = 31, + GCRYCTL_START_DUMP = 32, + GCRYCTL_STOP_DUMP = 33, + GCRYCTL_GET_ALGO_USAGE = 34, + GCRYCTL_IS_ALGO_ENABLED = 35, + GCRYCTL_DISABLE_INTERNAL_LOCKING = 36, + GCRYCTL_DISABLE_SECMEM = 37, + GCRYCTL_INITIALIZATION_FINISHED = 38, + GCRYCTL_INITIALIZATION_FINISHED_P = 39, + GCRYCTL_ANY_INITIALIZATION_P = 40, + GCRYCTL_SET_CBC_CTS = 41, + GCRYCTL_SET_CBC_MAC = 42, + GCRYCTL_SET_CTR = 43, + GCRYCTL_ENABLE_QUICK_RANDOM = 44, + GCRYCTL_SET_RANDOM_SEED_FILE = 45, + GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46, + GCRYCTL_SET_THREAD_CBS = 47, + GCRYCTL_FAST_POLL = 48, + GCRYCTL_SET_RANDOM_DAEMON_SOCKET = 49, + GCRYCTL_USE_RANDOM_DAEMON = 50, + GCRYCTL_FAKED_RANDOM_P = 51, + GCRYCTL_SET_RNDEGD_SOCKET = 52, + GCRYCTL_PRINT_CONFIG = 53, + GCRYCTL_OPERATIONAL_P = 54, + GCRYCTL_FIPS_MODE_P = 55, + GCRYCTL_FORCE_FIPS_MODE = 56, + GCRYCTL_SELFTEST = 57 + /* Note: 58 .. 62 are used internally. */ + }; + +/* Perform various operations defined by CMD. */ +gcry_error_t gcry_control (enum gcry_ctl_cmds CMD, ...); + + +/* S-expression management. */ + +/* The object to represent an S-expression as used with the public key + functions. */ +struct gcry_sexp; +typedef struct gcry_sexp *gcry_sexp_t; + +#ifndef GCRYPT_NO_DEPRECATED +typedef struct gcry_sexp *GCRY_SEXP _GCRY_GCC_ATTR_DEPRECATED; +typedef struct gcry_sexp *GcrySexp _GCRY_GCC_ATTR_DEPRECATED; +#endif + +/* The possible values for the S-expression format. */ +enum gcry_sexp_format + { + GCRYSEXP_FMT_DEFAULT = 0, + GCRYSEXP_FMT_CANON = 1, + GCRYSEXP_FMT_BASE64 = 2, + GCRYSEXP_FMT_ADVANCED = 3 + }; + +/* Create an new S-expression object from BUFFER of size LENGTH and + return it in RETSEXP. With AUTODETECT set to 0 the data in BUFFER + is expected to be in canonized format. */ +gcry_error_t gcry_sexp_new (gcry_sexp_t *retsexp, + const void *buffer, size_t length, + int autodetect); + + /* Same as gcry_sexp_new but allows to pass a FREEFNC which has the + effect to transfer ownership of BUFFER to the created object. */ +gcry_error_t gcry_sexp_create (gcry_sexp_t *retsexp, + void *buffer, size_t length, + int autodetect, void (*freefnc) (void *)); + +/* Scan BUFFER and return a new S-expression object in RETSEXP. This + function expects a printf like string in BUFFER. */ +gcry_error_t gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, + const char *buffer, size_t length); + +/* Same as gcry_sexp_sscan but expects a string in FORMAT and can thus + only be used for certain encodings. */ +gcry_error_t gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, + const char *format, ...); + +/* Like gcry_sexp_build, but uses an array instead of variable + function arguments. */ +gcry_error_t gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, + const char *format, void **arg_list); + +/* Release the S-expression object SEXP */ +void gcry_sexp_release (gcry_sexp_t sexp); + +/* Calculate the length of an canonized S-expresion in BUFFER and + check for a valid encoding. */ +size_t gcry_sexp_canon_len (const unsigned char *buffer, size_t length, + size_t *erroff, gcry_error_t *errcode); + +/* Copies the S-expression object SEXP into BUFFER using the format + specified in MODE. */ +size_t gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, + size_t maxlength); + +/* Dumps the S-expression object A in a format suitable for debugging + to Libgcrypt's logging stream. */ +void gcry_sexp_dump (const gcry_sexp_t a); + +gcry_sexp_t gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b); +gcry_sexp_t gcry_sexp_alist (const gcry_sexp_t *array); +gcry_sexp_t gcry_sexp_vlist (const gcry_sexp_t a, ...); +gcry_sexp_t gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n); +gcry_sexp_t gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n); + +/* Scan the S-expression for a sublist with a type (the car of the + list) matching the string TOKEN. If TOKLEN is not 0, the token is + assumed to be raw memory of this length. The function returns a + newly allocated S-expression consisting of the found sublist or + `NULL' when not found. */ +gcry_sexp_t gcry_sexp_find_token (gcry_sexp_t list, + const char *tok, size_t toklen); +/* Return the length of the LIST. For a valid S-expression this + should be at least 1. */ +int gcry_sexp_length (const gcry_sexp_t list); + +/* Create and return a new S-expression from the element with index + NUMBER in LIST. Note that the first element has the index 0. If + there is no such element, `NULL' is returned. */ +gcry_sexp_t gcry_sexp_nth (const gcry_sexp_t list, int number); + +/* Create and return a new S-expression from the first element in + LIST; this called the "type" and should always exist and be a + string. `NULL' is returned in case of a problem. */ +gcry_sexp_t gcry_sexp_car (const gcry_sexp_t list); + +/* Create and return a new list form all elements except for the first + one. Note, that this function may return an invalid S-expression + because it is not guaranteed, that the type exists and is a string. + However, for parsing a complex S-expression it might be useful for + intermediate lists. Returns `NULL' on error. */ +gcry_sexp_t gcry_sexp_cdr (const gcry_sexp_t list); + +gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list); + + +/* This function is used to get data from a LIST. A pointer to the + actual data with index NUMBER is returned and the length of this + data will be stored to DATALEN. If there is no data at the given + index or the index represents another list, `NULL' is returned. + *Note:* The returned pointer is valid as long as LIST is not + modified or released. */ +const char *gcry_sexp_nth_data (const gcry_sexp_t list, int number, + size_t *datalen); + +/* This function is used to get and convert data from a LIST. The + data is assumed to be a Nul terminated string. The caller must + release the returned value using `gcry_free'. If there is no data + at the given index, the index represents a list or the value can't + be converted to a string, `NULL' is returned. */ +char *gcry_sexp_nth_string (gcry_sexp_t list, int number); + +/* This function is used to get and convert data from a LIST. This + data is assumed to be an MPI stored in the format described by + MPIFMT and returned as a standard Libgcrypt MPI. The caller must + release this returned value using `gcry_mpi_release'. If there is + no data at the given index, the index represents a list or the + value can't be converted to an MPI, `NULL' is returned. */ +gcry_mpi_t gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt); + + + +/******************************************* + * * + * Multi Precision Integer Functions * + * * + *******************************************/ + +/* Different formats of external big integer representation. */ +enum gcry_mpi_format + { + GCRYMPI_FMT_NONE= 0, + GCRYMPI_FMT_STD = 1, /* Twos complement stored without length. */ + GCRYMPI_FMT_PGP = 2, /* As used by OpenPGP (unsigned only). */ + GCRYMPI_FMT_SSH = 3, /* As used by SSH (like STD but with length). */ + GCRYMPI_FMT_HEX = 4, /* Hex format. */ + GCRYMPI_FMT_USG = 5 /* Like STD but unsigned. */ + }; + +/* Flags used for creating big integers. */ +enum gcry_mpi_flag + { + GCRYMPI_FLAG_SECURE = 1, /* Allocate the number in "secure" memory. */ + GCRYMPI_FLAG_OPAQUE = 2 /* The number is not a real one but just + a way to store some bytes. This is + useful for encrypted big integers. */ + }; + + +/* Allocate a new big integer object, initialize it with 0 and + initially allocate memory for a number of at least NBITS. */ +gcry_mpi_t gcry_mpi_new (unsigned int nbits); + +/* Same as gcry_mpi_new() but allocate in "secure" memory. */ +gcry_mpi_t gcry_mpi_snew (unsigned int nbits); + +/* Release the number A and free all associated resources. */ +void gcry_mpi_release (gcry_mpi_t a); + +/* Create a new number with the same value as A. */ +gcry_mpi_t gcry_mpi_copy (const gcry_mpi_t a); + +/* Store the big integer value U in W. */ +gcry_mpi_t gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u); + +/* Store the unsigned integer value U in W. */ +gcry_mpi_t gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u); + +/* Swap the values of A and B. */ +void gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b); + +/* Compare the big integer number U and V returning 0 for equality, a + positive value for U > V and a negative for U < V. */ +int gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v); + +/* Compare the big integer number U with the unsigned integer V + returning 0 for equality, a positive value for U > V and a negative + for U < V. */ +int gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v); + +/* Convert the external representation of an integer stored in BUFFER + with a length of BUFLEN into a newly create MPI returned in + RET_MPI. If NSCANNED is not NULL, it will receive the number of + bytes actually scanned after a successful operation. */ +gcry_error_t gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, + const void *buffer, size_t buflen, + size_t *nscanned); + +/* Convert the big integer A into the external representation + described by FORMAT and store it in the provided BUFFER which has + been allocated by the user with a size of BUFLEN bytes. NWRITTEN + receives the actual length of the external representation unless it + has been passed as NULL. */ +gcry_error_t gcry_mpi_print (enum gcry_mpi_format format, + unsigned char *buffer, size_t buflen, + size_t *nwritten, + const gcry_mpi_t a); + +/* Convert the big integer A int the external representation described + by FORMAT and store it in a newly allocated buffer which address + will be put into BUFFER. NWRITTEN receives the actual lengths of the + external representation. */ +gcry_error_t gcry_mpi_aprint (enum gcry_mpi_format format, + unsigned char **buffer, size_t *nwritten, + const gcry_mpi_t a); + +/* Dump the value of A in a format suitable for debugging to + Libgcrypt's logging stream. Note that one leading space but no + trailing space or linefeed will be printed. It is okay to pass + NULL for A. */ +void gcry_mpi_dump (const gcry_mpi_t a); + + +/* W = U + V. */ +void gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); + +/* W = U + V. V is an unsigned integer. */ +void gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v); + +/* W = U + V mod M. */ +void gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); + +/* W = U - V. */ +void gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); + +/* W = U - V. V is an unsigned integer. */ +void gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); + +/* W = U - V mod M */ +void gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); + +/* W = U * V. */ +void gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); + +/* W = U * V. V is an unsigned integer. */ +void gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); + +/* W = U * V mod M. */ +void gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); + +/* W = U * (2 ^ CNT). */ +void gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt); + +/* Q = DIVIDEND / DIVISOR, R = DIVIDEND % DIVISOR, + Q or R may be passed as NULL. ROUND should be negative or 0. */ +void gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, + gcry_mpi_t dividend, gcry_mpi_t divisor, int round); + +/* R = DIVIDEND % DIVISOR */ +void gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor); + +/* W = B ^ E mod M. */ +void gcry_mpi_powm (gcry_mpi_t w, + const gcry_mpi_t b, const gcry_mpi_t e, + const gcry_mpi_t m); + +/* Set G to the greatest common divisor of A and B. + Return true if the G is 1. */ +int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b); + +/* Set X to the multiplicative inverse of A mod M. + Return true if the value exists. */ +int gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m); + + +/* Return the number of bits required to represent A. */ +unsigned int gcry_mpi_get_nbits (gcry_mpi_t a); + +/* Return true when bit number N (counting from 0) is set in A. */ +int gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n); + +/* Set bit number N in A. */ +void gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n); + +/* Clear bit number N in A. */ +void gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n); + +/* Set bit number N in A and clear all bits greater than N. */ +void gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n); + +/* Clear bit number N in A and all bits greater than N. */ +void gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n); + +/* Shift the value of A by N bits to the right and store the result in X. */ +void gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); + +/* Shift the value of A by N bits to the left and store the result in X. */ +void gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n); + +/* Store NBITS of the value P points to in A and mark A as an opaque + value. WARNING: Never use an opaque MPI for anything thing else then + gcry_mpi_release, gcry_mpi_get_opaque. */ +gcry_mpi_t gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits); + +/* Return a pointer to an opaque value stored in A and return its size + in NBITS. Note that the returned pointer is still owned by A and + that the function should never be used for an non-opaque MPI. */ +void *gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits); + +/* Set the FLAG for the big integer A. Currently only the flag + GCRYMPI_FLAG_SECURE is allowed to convert A into an big intger + stored in "secure" memory. */ +void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); + +/* Clear FLAG for the big integer A. Note that this function is + currently useless as no flags are allowed. */ +void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); + +/* Return true when the FLAG is set for A. */ +int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); + +/* Unless the GCRYPT_NO_MPI_MACROS is used, provide a couple of + convenience macros for the big integer functions. */ +#ifndef GCRYPT_NO_MPI_MACROS +#define mpi_new(n) gcry_mpi_new( (n) ) +#define mpi_secure_new( n ) gcry_mpi_snew( (n) ) +#define mpi_release(a) \ + do \ + { \ + gcry_mpi_release ((a)); \ + (a) = NULL; \ + } \ + while (0) + +#define mpi_copy( a ) gcry_mpi_copy( (a) ) +#define mpi_set( w, u) gcry_mpi_set( (w), (u) ) +#define mpi_set_ui( w, u) gcry_mpi_set_ui( (w), (u) ) +#define mpi_cmp( u, v ) gcry_mpi_cmp( (u), (v) ) +#define mpi_cmp_ui( u, v ) gcry_mpi_cmp_ui( (u), (v) ) + +#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)) +#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)) +#define mpi_powm(w,b,e,m) gcry_mpi_powm ( (w), (b), (e), (m) ) +#define mpi_tdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), 0) +#define mpi_fdiv(q,r,a,m) gcry_mpi_div ( (q), (r), (a), (m), -1) +#define mpi_mod(r,a,m) gcry_mpi_mod ((r), (a), (m)) +#define mpi_gcd(g,a,b) gcry_mpi_gcd ( (g), (a), (b) ) +#define mpi_invm(g,a,b) gcry_mpi_invm ( (g), (a), (b) ) + +#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)) + +#define mpi_set_opaque(a,b,c) gcry_mpi_set_opaque( (a), (b), (c) ) +#define mpi_get_opaque(a,b) gcry_mpi_get_opaque( (a), (b) ) +#endif /* GCRYPT_NO_MPI_MACROS */ + + + +/************************************ + * * + * Symmetric Cipher Functions * + * * + ************************************/ + +/* The data object used to hold a handle to an encryption object. */ +struct gcry_cipher_handle; +typedef struct gcry_cipher_handle *gcry_cipher_hd_t; + +#ifndef GCRYPT_NO_DEPRECATED +typedef struct gcry_cipher_handle *GCRY_CIPHER_HD _GCRY_GCC_ATTR_DEPRECATED; +typedef struct gcry_cipher_handle *GcryCipherHd _GCRY_GCC_ATTR_DEPRECATED; +#endif + +/* All symmetric encryption algorithms are identified by their IDs. + More IDs may be registered at runtime. */ +enum gcry_cipher_algos + { + GCRY_CIPHER_NONE = 0, + GCRY_CIPHER_IDEA = 1, + GCRY_CIPHER_3DES = 2, + GCRY_CIPHER_CAST5 = 3, + GCRY_CIPHER_BLOWFISH = 4, + GCRY_CIPHER_SAFER_SK128 = 5, + GCRY_CIPHER_DES_SK = 6, + GCRY_CIPHER_AES = 7, + GCRY_CIPHER_AES192 = 8, + GCRY_CIPHER_AES256 = 9, + GCRY_CIPHER_TWOFISH = 10, + + /* Other cipher numbers are above 300 for OpenPGP reasons. */ + GCRY_CIPHER_ARCFOUR = 301, /* Fully compatible with RSA's RC4 (tm). */ + GCRY_CIPHER_DES = 302, /* Yes, this is single key 56 bit DES. */ + GCRY_CIPHER_TWOFISH128 = 303, + GCRY_CIPHER_SERPENT128 = 304, + GCRY_CIPHER_SERPENT192 = 305, + GCRY_CIPHER_SERPENT256 = 306, + GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */ + GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */ + GCRY_CIPHER_SEED = 309, /* 128 bit cipher described in RFC4269. */ + GCRY_CIPHER_CAMELLIA128 = 310, + GCRY_CIPHER_CAMELLIA192 = 311, + GCRY_CIPHER_CAMELLIA256 = 312 + }; + +/* The Rijndael algorithm is basically AES, so provide some macros. */ +#define GCRY_CIPHER_AES128 GCRY_CIPHER_AES +#define GCRY_CIPHER_RIJNDAEL GCRY_CIPHER_AES +#define GCRY_CIPHER_RIJNDAEL128 GCRY_CIPHER_AES128 +#define GCRY_CIPHER_RIJNDAEL192 GCRY_CIPHER_AES192 +#define GCRY_CIPHER_RIJNDAEL256 GCRY_CIPHER_AES256 + +/* The supported encryption modes. Note that not all of them are + supported for each algorithm. */ +enum gcry_cipher_modes + { + GCRY_CIPHER_MODE_NONE = 0, /* Not yet specified. */ + GCRY_CIPHER_MODE_ECB = 1, /* Electronic codebook. */ + GCRY_CIPHER_MODE_CFB = 2, /* Cipher feedback. */ + GCRY_CIPHER_MODE_CBC = 3, /* Cipher block chaining. */ + GCRY_CIPHER_MODE_STREAM = 4, /* Used with stream ciphers. */ + GCRY_CIPHER_MODE_OFB = 5, /* Outer feedback. */ + GCRY_CIPHER_MODE_CTR = 6, /* Counter. */ + GCRY_CIPHER_MODE_AESWRAP= 7 /* AES-WRAP algorithm. */ + }; + +/* Flags used with the open function. */ +enum gcry_cipher_flags + { + GCRY_CIPHER_SECURE = 1, /* Allocate in secure memory. */ + GCRY_CIPHER_ENABLE_SYNC = 2, /* Enable CFB sync mode. */ + GCRY_CIPHER_CBC_CTS = 4, /* Enable CBC cipher text stealing (CTS). */ + GCRY_CIPHER_CBC_MAC = 8 /* Enable CBC message auth. code (MAC). */ + }; + + +/* Create a handle for algorithm ALGO to be used in MODE. FLAGS may + be given as an bitwise OR of the gcry_cipher_flags values. */ +gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *handle, + int algo, int mode, unsigned int flags); + +/* Close the cioher handle H and release all resource. */ +void gcry_cipher_close (gcry_cipher_hd_t h); + +/* Perform various operations on the cipher object H. */ +gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, + size_t buflen); + +/* Retrieve various information about the cipher object H. */ +gcry_error_t gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, + size_t *nbytes); + +/* Retrieve various information about the cipher algorithm ALGO. */ +gcry_error_t gcry_cipher_algo_info (int algo, int what, void *buffer, + size_t *nbytes); + +/* Map the cipher algorithm whose ID is contained in ALGORITHM to a + string representation of the algorithm name. For unknown algorithm + IDs this function returns "?". */ +const char *gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; + +/* Map the algorithm name NAME to an cipher algorithm ID. Return 0 if + the algorithm name is not known. */ +int gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE; + +/* Given an ASN.1 object identifier in standard IETF dotted decimal + format in STRING, return the encryption mode associated with that + OID or 0 if not known or applicable. */ +int gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE; + +/* Encrypt the plaintext of size INLEN in IN using the cipher handle H + into the buffer OUT which has an allocated length of OUTSIZE. For + most algorithms it is possible to pass NULL for in and 0 for INLEN + and do a in-place decryption of the data provided in OUT. */ +gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h, + void *out, size_t outsize, + const void *in, size_t inlen); + +/* The counterpart to gcry_cipher_encrypt. */ +gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t h, + void *out, size_t outsize, + const void *in, size_t inlen); + +/* Set KEY of length KEYLEN bytes for the cipher handle HD. */ +gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t hd, + const void *key, size_t keylen); + + +/* Set initialization vector IV of length IVLEN for the cipher handle HD. */ +gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd, + const void *iv, size_t ivlen); + + +/* Reset the handle to the state after open. */ +#define gcry_cipher_reset(h) gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0) + +/* Perform the OpenPGP sync operation if this is enabled for the + cipher handle H. */ +#define gcry_cipher_sync(h) gcry_cipher_ctl( (h), GCRYCTL_CFB_SYNC, NULL, 0) + +/* Enable or disable CTS in future calls to gcry_encrypt(). CBC mode only. */ +#define gcry_cipher_cts(h,on) gcry_cipher_ctl( (h), GCRYCTL_SET_CBC_CTS, \ + NULL, on ) + +/* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of + block size length, or (NULL,0) to set the CTR to the all-zero block. */ +gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd, + const void *ctr, size_t ctrlen); + +/* Retrieved the key length in bytes used with algorithm A. */ +size_t gcry_cipher_get_algo_keylen (int algo); + +/* Retrieve the block length in bytes used with algorithm A. */ +size_t gcry_cipher_get_algo_blklen (int algo); + +/* Return 0 if the algorithm A is available for use. */ +#define gcry_cipher_test_algo(a) \ + gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) + +/* Get a list consisting of the IDs of the loaded cipher modules. If + LIST is zero, write the number of loaded cipher 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_error_t gcry_cipher_list (int *list, int *list_length); + + +/************************************ + * * + * Asymmetric Cipher Functions * + * * + ************************************/ + +/* The algorithms and their IDs we support. */ +enum gcry_pk_algos + { + GCRY_PK_RSA = 1, + GCRY_PK_RSA_E = 2, /* (deprecated) */ + GCRY_PK_RSA_S = 3, /* (deprecated) */ + GCRY_PK_ELG_E = 16, + GCRY_PK_DSA = 17, + GCRY_PK_ELG = 20, + GCRY_PK_ECDSA = 301 + }; + +/* Flags describing usage capabilities of a PK algorithm. */ +#define GCRY_PK_USAGE_SIGN 1 /* Good for signatures. */ +#define GCRY_PK_USAGE_ENCR 2 /* Good for encryption. */ +#define GCRY_PK_USAGE_CERT 4 /* Good to certify other keys. */ +#define GCRY_PK_USAGE_AUTH 8 /* Good for authentication. */ +#define GCRY_PK_USAGE_UNKN 128 /* Unknown usage flag. */ + +/* Encrypt the DATA using the public key PKEY and store the result as + a newly created S-expression at RESULT. */ +gcry_error_t gcry_pk_encrypt (gcry_sexp_t *result, + gcry_sexp_t data, gcry_sexp_t pkey); + +/* Decrypt the DATA using the private key SKEY and store the result as + a newly created S-expression at RESULT. */ +gcry_error_t gcry_pk_decrypt (gcry_sexp_t *result, + gcry_sexp_t data, gcry_sexp_t skey); + +/* Sign the DATA using the private key SKEY and store the result as + a newly created S-expression at RESULT. */ +gcry_error_t gcry_pk_sign (gcry_sexp_t *result, + gcry_sexp_t data, gcry_sexp_t skey); + +/* Check the signature SIGVAL on DATA using the public key PKEY. */ +gcry_error_t gcry_pk_verify (gcry_sexp_t sigval, + gcry_sexp_t data, gcry_sexp_t pkey); + +/* Check that private KEY is sane. */ +gcry_error_t gcry_pk_testkey (gcry_sexp_t key); + +/* Generate a new key pair according to the parameters given in + S_PARMS. The new key pair is returned in as an S-expression in + R_KEY. */ +gcry_error_t gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms); + +/* Catch all function for miscellaneous operations. */ +gcry_error_t gcry_pk_ctl (int cmd, void *buffer, size_t buflen); + +/* Retrieve information about the public key algorithm ALGO. */ +gcry_error_t gcry_pk_algo_info (int algo, int what, + void *buffer, size_t *nbytes); + +/* Map the public key algorithm whose ID is contained in ALGORITHM to + a string representation of the algorithm name. For unknown + algorithm IDs this functions returns "?". */ +const char *gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE; + +/* Map the algorithm NAME to a public key algorithm Id. Return 0 if + the algorithm name is not known. */ +int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE; + +/* Return what is commonly referred as the key length for the given + public or private KEY. */ +unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE; + +/* Please note that keygrip is still experimental and should not be + used without contacting the author. */ +unsigned char *gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array); + +/* Return 0 if the public key algorithm A is available for use. */ +#define gcry_pk_test_algo(a) \ + gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) + +/* Get a list consisting of the IDs of the loaded pubkey modules. If + LIST is zero, write the number of loaded pubkey 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 pubkey modules than + *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */ +gcry_error_t gcry_pk_list (int *list, int *list_length); + + + +/************************************ + * * + * Cryptograhic Hash Functions * + * * + ************************************/ + +/* Algorithm IDs for the hash functions we know about. Not all of them + are implemnted. */ +enum gcry_md_algos + { + GCRY_MD_NONE = 0, + GCRY_MD_MD5 = 1, + GCRY_MD_SHA1 = 2, + GCRY_MD_RMD160 = 3, + GCRY_MD_MD2 = 5, + GCRY_MD_TIGER = 6, /* TIGER/192 as used by GnuPG <= 1.3.2. */ + GCRY_MD_HAVAL = 7, /* HAVAL, 5 pass, 160 bit. */ + GCRY_MD_SHA256 = 8, + GCRY_MD_SHA384 = 9, + GCRY_MD_SHA512 = 10, + GCRY_MD_SHA224 = 11, + GCRY_MD_MD4 = 301, + GCRY_MD_CRC32 = 302, + GCRY_MD_CRC32_RFC1510 = 303, + GCRY_MD_CRC24_RFC2440 = 304, + GCRY_MD_WHIRLPOOL = 305, + GCRY_MD_TIGER1 = 306, /* TIGER (fixed). */ + GCRY_MD_TIGER2 = 307 /* TIGER2 variant. */ + }; + +/* Flags used with the open function. */ +enum gcry_md_flags + { + GCRY_MD_FLAG_SECURE = 1, /* Allocate all buffers in "secure" memory. */ + GCRY_MD_FLAG_HMAC = 2 /* Make an HMAC out of this algorithm. */ + }; + +/* (Forward declaration.) */ +struct gcry_md_context; + +/* This object is used to hold a handle to a message digest object. + This structure is private - only to be used by the public gcry_md_* + macros. */ +typedef struct gcry_md_handle +{ + /* Actual context. */ + struct gcry_md_context *ctx; + + /* Buffer management. */ + int bufpos; + int bufsize; + unsigned char buf[1]; +} *gcry_md_hd_t; + +/* Compatibility types, do not use them. */ +#ifndef GCRYPT_NO_DEPRECATED +typedef struct gcry_md_handle *GCRY_MD_HD _GCRY_GCC_ATTR_DEPRECATED; +typedef struct gcry_md_handle *GcryMDHd _GCRY_GCC_ATTR_DEPRECATED; +#endif + +/* Create a message digest object for algorithm ALGO. FLAGS may be + given as an bitwise OR of the gcry_md_flags values. ALGO may be + given as 0 if the algorithms to be used are later set using + gcry_md_enable. */ +gcry_error_t gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags); + +/* Release the message digest object HD. */ +void gcry_md_close (gcry_md_hd_t hd); + +/* Add the message digest algorithm ALGO to the digest object HD. */ +gcry_error_t gcry_md_enable (gcry_md_hd_t hd, int algo); + +/* Create a new digest object as an exact copy of the object HD. */ +gcry_error_t gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd); + +/* Reset the digest object HD to its initial state. */ +void gcry_md_reset (gcry_md_hd_t hd); + +/* Perform various operations on the digest object HD. */ +gcry_error_t gcry_md_ctl (gcry_md_hd_t hd, int cmd, + void *buffer, size_t buflen); + +/* Pass LENGTH bytes of data in BUFFER to the digest object HD so that + it can update the digest values. This is the actual hash + function. */ +void gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length); + +/* Read out the final digest from HD return the digest value for + algorithm ALGO. */ +unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo); + +/* Convenience function to calculate the hash from the data in BUFFER + of size LENGTH using the algorithm ALGO avoiding the creating of a + hash object. The hash is returned in the caller provided buffer + DIGEST which must be large enough to hold the digest of the given + algorithm. */ +void gcry_md_hash_buffer (int algo, void *digest, + const void *buffer, size_t length); + +/* Retrieve the algorithm used with HD. This does not work reliable + if more than one algorithm is enabled in HD. */ +int gcry_md_get_algo (gcry_md_hd_t hd); + +/* Retrieve the length in bytes of the digest yielded by algorithm + ALGO. */ +unsigned int gcry_md_get_algo_dlen (int algo); + +/* Return true if the the algorithm ALGO is enabled in the digest + object A. */ +int gcry_md_is_enabled (gcry_md_hd_t a, int algo); + +/* Return true if the digest object A is allocated in "secure" memory. */ +int gcry_md_is_secure (gcry_md_hd_t a); + +/* Retrieve various information about the object H. */ +gcry_error_t gcry_md_info (gcry_md_hd_t h, int what, void *buffer, + size_t *nbytes); + +/* Retrieve various information about the algorithm ALGO. */ +gcry_error_t gcry_md_algo_info (int algo, int what, void *buffer, + size_t *nbytes); + +/* Map the digest algorithm id ALGO to a string representation of the + algorithm name. For unknown algorithms this function returns + "?". */ +const char *gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE; + +/* Map the algorithm NAME to a digest algorithm Id. Return 0 if + the algorithm name is not known. */ +int gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE; + +/* For use with the HMAC feature, the set MAC key to the KEY of + KEYLEN bytes. */ +gcry_error_t gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen); + +/* Start or stop debugging for digest handle HD; i.e. create a file + named dbgmd-<n>.<suffix> while hashing. If SUFFIX is NULL, + debugging stops and the file will be closed. */ +void gcry_md_debug (gcry_md_hd_t hd, const char *suffix); + + +/* Update the hash(s) of H with the character C. This is a buffered + version of the gcry_md_write function. */ +#define gcry_md_putc(h,c) \ + do { \ + gcry_md_hd_t h__ = (h); \ + if( (h__)->bufpos == (h__)->bufsize ) \ + gcry_md_write( (h__), NULL, 0 ); \ + (h__)->buf[(h__)->bufpos++] = (c) & 0xff; \ + } while(0) + +/* Finalize the digest calculation. This is not really needed because + gcry_md_read() does this implicitly. */ +#define gcry_md_final(a) \ + gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0) + +/* Return 0 if the algorithm A is available for use. */ +#define gcry_md_test_algo(a) \ + gcry_md_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL ) + +/* Return an DER encoded ASN.1 OID for the algorithm A in buffer B. N + must point to size_t variable with the available size of buffer B. + After return it will receive the actual size of the returned + OID. */ +#define gcry_md_get_asnoid(a,b,n) \ + gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n)) + +/* Enable debugging for digest object A; i.e. create files named + dbgmd-<n>.<string> while hashing. B is a string used as the suffix + for the filename. This macro is deprecated, use gcry_md_debug. */ +#ifndef GCRYPT_NO_DEPRECATED +#define gcry_md_start_debug(a,b) \ + gcry_md_ctl( (a), GCRYCTL_START_DUMP, (b), 0 ) + +/* Disable the debugging of A. This macro is deprecated, use + gcry_md_debug. */ +#define gcry_md_stop_debug(a,b) \ + gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 ) +#endif + +/* Get a list consisting of the IDs of the loaded message digest + modules. If LIST is zero, write the number of loaded message + digest 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 message digest modules + than *LIST_LENGTH, *LIST_LENGTH is updated to the correct + number. */ +gcry_error_t gcry_md_list (int *list, int *list_length); + + + +/* Alternative interface for asymmetric cryptography. This interface + is deprecated. */ + +/* The algorithm IDs. */ +typedef enum gcry_ac_id + { + GCRY_AC_RSA = 1, + GCRY_AC_DSA = 17, + GCRY_AC_ELG = 20, + GCRY_AC_ELG_E = 16 + } +gcry_ac_id_t; + +/* Key types. */ +typedef enum gcry_ac_key_type + { + GCRY_AC_KEY_SECRET, + GCRY_AC_KEY_PUBLIC + } +gcry_ac_key_type_t; + +/* Encoding methods. */ +typedef enum gcry_ac_em + { + GCRY_AC_EME_PKCS_V1_5, + GCRY_AC_EMSA_PKCS_V1_5 + } +gcry_ac_em_t; + +/* Encryption and Signature schemes. */ +typedef enum gcry_ac_scheme + { + GCRY_AC_ES_PKCS_V1_5, + GCRY_AC_SSA_PKCS_V1_5 + } +gcry_ac_scheme_t; + +/* AC data. */ +#define GCRY_AC_FLAG_DEALLOC (1 << 0) +#define GCRY_AC_FLAG_COPY (1 << 1) +#define GCRY_AC_FLAG_NO_BLINDING (1 << 2) + +/* This type represents a `data set'. */ +typedef struct gcry_ac_data *gcry_ac_data_t; + +/* This type represents a single `key', either a secret one or a + public one. */ +typedef struct gcry_ac_key *gcry_ac_key_t; + +/* This type represents a `key pair' containing a secret and a public + key. */ +typedef struct gcry_ac_key_pair *gcry_ac_key_pair_t; + +/* This type represents a `handle' that is needed by functions + performing cryptographic operations. */ +typedef struct gcry_ac_handle *gcry_ac_handle_t; + +typedef gpg_error_t (*gcry_ac_data_read_cb_t) (void *opaque, + unsigned char *buffer, + size_t *buffer_n); + +typedef gpg_error_t (*gcry_ac_data_write_cb_t) (void *opaque, + unsigned char *buffer, + size_t buffer_n); + +typedef enum + { + GCRY_AC_IO_READABLE, + GCRY_AC_IO_WRITABLE + } +gcry_ac_io_mode_t; + +typedef enum + { + GCRY_AC_IO_STRING, + GCRY_AC_IO_CALLBACK + } +gcry_ac_io_type_t; + +typedef struct gcry_ac_io +{ + /* This is an INTERNAL structure, do NOT use manually. */ + gcry_ac_io_mode_t mode _GCRY_ATTR_INTERNAL; + gcry_ac_io_type_t type _GCRY_ATTR_INTERNAL; + union + { + union + { + struct + { + gcry_ac_data_read_cb_t cb; + void *opaque; + } callback; + struct + { + unsigned char *data; + size_t data_n; + } string; + void *opaque; + } readable; + union + { + struct + { + gcry_ac_data_write_cb_t cb; + void *opaque; + } callback; + struct + { + unsigned char **data; + size_t *data_n; + } string; + void *opaque; + } writable; + } io _GCRY_ATTR_INTERNAL; +} +gcry_ac_io_t; + +/* The caller of gcry_ac_key_pair_generate can provide one of these + structures in order to influence the key generation process in an + algorithm-specific way. */ +typedef struct gcry_ac_key_spec_rsa +{ + gcry_mpi_t e; /* E to use. */ +} gcry_ac_key_spec_rsa_t; + +/* Structure used for passing data to the implementation of the + `EME-PKCS-V1_5' encoding method. */ +typedef struct gcry_ac_eme_pkcs_v1_5 +{ + size_t key_size; +} gcry_ac_eme_pkcs_v1_5_t; + +typedef enum gcry_md_algos gcry_md_algo_t; + +/* Structure used for passing data to the implementation of the + `EMSA-PKCS-V1_5' encoding method. */ +typedef struct gcry_ac_emsa_pkcs_v1_5 +{ + gcry_md_algo_t md; + size_t em_n; +} gcry_ac_emsa_pkcs_v1_5_t; + +/* Structure used for passing data to the implementation of the + `SSA-PKCS-V1_5' signature scheme. */ +typedef struct gcry_ac_ssa_pkcs_v1_5 +{ + gcry_md_algo_t md; +} gcry_ac_ssa_pkcs_v1_5_t; + +/* Returns a new, empty data set in DATA. */ +gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data); + +/* Destroy the data set DATA. */ +void gcry_ac_data_destroy (gcry_ac_data_t data); + +/* Create a copy of the data set DATA and store it in DATA_CP. */ +gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp, + gcry_ac_data_t data); + +/* Return the number of named MPI values inside of the data set + DATA. */ +unsigned int gcry_ac_data_length (gcry_ac_data_t data); + +/* Destroy any values contained in the data set DATA. */ +void gcry_ac_data_clear (gcry_ac_data_t data); + +/* Add the value MPI to DATA with the label NAME. If FLAGS contains + GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of NAME + and MPI. If FLAGS contains GCRY_AC_FLAG_DATA_DEALLOC or + GCRY_AC_FLAG_DATA_COPY, the values contained in the data set will + be deallocated when they are to be removed from the data set. */ +gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags, + const char *name, gcry_mpi_t mpi); + +/* Store the value labelled with NAME found in DATA in MPI. If FLAGS + contains GCRY_AC_FLAG_COPY, store a copy of the MPI value contained + in the data set. MPI may be NULL. */ +gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags, + const char *name, gcry_mpi_t *mpi); + +/* Stores in NAME and MPI the named MPI value contained in the data + set DATA with the index IDX. If FLAGS contains GCRY_AC_FLAG_COPY, + store copies of the values contained in the data set. NAME or MPI + may be NULL. */ +gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags, + unsigned int idx, + const char **name, gcry_mpi_t *mpi); + +/* Convert the data set DATA into a new S-Expression, which is to be + stored in SEXP, according to the identifiers contained in + IDENTIFIERS. */ +gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, + const char **identifiers); + +/* Create a new data set, which is to be stored in DATA_SET, from the + S-Expression SEXP, according to the identifiers contained in + IDENTIFIERS. */ +gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp, + const char **identifiers); + +/* Initialize AC_IO according to MODE, TYPE and the variable list of + arguments. The list of variable arguments to specify depends on + the given TYPE. */ +void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode, + gcry_ac_io_type_t type, ...); + +/* Initialize AC_IO according to MODE, TYPE and the variable list of + arguments AP. The list of variable arguments to specify depends on + the given TYPE. */ +void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode, + gcry_ac_io_type_t type, va_list ap); + +/* Create a new ac handle. */ +gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle, + gcry_ac_id_t algorithm, unsigned int flags); + +/* Destroy an ac handle. */ +void gcry_ac_close (gcry_ac_handle_t handle); + +/* Initialize a key from a given data set. */ +gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle, + gcry_ac_key_type_t type, gcry_ac_data_t data); + +/* Generates a new key pair via the handle HANDLE of NBITS bits and + stores it in KEY_PAIR. In case non-standard settings are wanted, a + pointer to a structure of type gcry_ac_key_spec_<algorithm>_t, + matching the selected algorithm, can be given as KEY_SPEC. + MISC_DATA is not used yet. */ +gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle, + unsigned int nbits, void *spec, + gcry_ac_key_pair_t *key_pair, + gcry_mpi_t **misc_data); + +/* Returns the key of type WHICH out of the key pair KEY_PAIR. */ +gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, + gcry_ac_key_type_t which); + +/* Returns the data set contained in the key KEY. */ +gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key); + +/* Verifies that the key KEY is sane via HANDLE. */ +gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key); + +/* Stores the number of bits of the key KEY in NBITS via HANDLE. */ +gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle, + gcry_ac_key_t key, unsigned int *nbits); + +/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via + HANDLE. */ +gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key, + unsigned char *key_grip); + +/* Destroy a key. */ +void gcry_ac_key_destroy (gcry_ac_key_t key); + +/* Destroy a key pair. */ +void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair); + +/* Encodes a message according to the encoding method METHOD. OPTIONS + must be a pointer to a method-specific structure + (gcry_ac_em*_t). */ +gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method, + unsigned int flags, void *options, + gcry_ac_io_t *io_read, + gcry_ac_io_t *io_write); + +/* Decodes a message according to the encoding method METHOD. OPTIONS + must be a pointer to a method-specific structure + (gcry_ac_em*_t). */ +gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method, + unsigned int flags, void *options, + gcry_ac_io_t *io_read, + gcry_ac_io_t *io_write); + +/* Encrypt the plain text MPI value DATA_PLAIN with the key KEY under + the control of the flags FLAGS and store the resulting data set + into DATA_ENCRYPTED. */ +gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle, + unsigned int flags, + gcry_ac_key_t key, + gcry_mpi_t data_plain, + gcry_ac_data_t *data_encrypted); + +/* Decrypt the decrypted data contained in the data set DATA_ENCRYPTED + with the key KEY under the control of the flags FLAGS and store the + resulting plain text MPI value in DATA_PLAIN. */ +gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle, + unsigned int flags, + gcry_ac_key_t key, + gcry_mpi_t *data_plain, + gcry_ac_data_t data_encrypted); + +/* Sign the data contained in DATA with the key KEY and store the + resulting signature in the data set DATA_SIGNATURE. */ +gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle, + gcry_ac_key_t key, + gcry_mpi_t data, + gcry_ac_data_t *data_signature); + +/* Verify that the signature contained in the data set DATA_SIGNATURE + is indeed the result of signing the data contained in DATA with the + secret key belonging to the public key KEY. */ +gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle, + gcry_ac_key_t key, + gcry_mpi_t data, + gcry_ac_data_t data_signature); + +/* Encrypts the plain text readable from IO_MESSAGE through HANDLE + with the public key KEY according to SCHEME, FLAGS and OPTS. If + OPTS is not NULL, it has to be a pointer to a structure specific to + the chosen scheme (gcry_ac_es_*_t). The encrypted message is + written to IO_CIPHER. */ +gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_message, + gcry_ac_io_t *io_cipher); + +/* Decrypts the cipher text readable from IO_CIPHER through HANDLE + with the secret key KEY according to SCHEME, @var{flags} and OPTS. + If OPTS is not NULL, it has to be a pointer to a structure specific + to the chosen scheme (gcry_ac_es_*_t). The decrypted message is + written to IO_MESSAGE. */ +gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_cipher, + gcry_ac_io_t *io_message); + +/* Signs the message readable from IO_MESSAGE through HANDLE with the + secret key KEY according to SCHEME, FLAGS and OPTS. If OPTS is not + NULL, it has to be a pointer to a structure specific to the chosen + scheme (gcry_ac_ssa_*_t). The signature is written to + IO_SIGNATURE. */ +gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_message, + gcry_ac_io_t *io_signature); + +/* Verifies through HANDLE that the signature readable from + IO_SIGNATURE is indeed the result of signing the message readable + from IO_MESSAGE with the secret key belonging to the public key KEY + according to SCHEME and OPTS. If OPTS is not NULL, it has to be an + anonymous structure (gcry_ac_ssa_*_t) specific to the chosen + scheme. */ +gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_message, + gcry_ac_io_t *io_signature); + +/* Store the textual representation of the algorithm whose id is given + in ALGORITHM in NAME. This function is deprecated; use + gcry_pk_algo_name. */ +#ifndef GCRYPT_NO_DEPRECATED +gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm, + const char **name) + /* */ _GCRY_GCC_ATTR_DEPRECATED; +/* Store the numeric ID of the algorithm whose textual representation + is contained in NAME in ALGORITHM. This function is deprecated; + use gcry_pk_map_name. */ +gcry_error_t gcry_ac_name_to_id (const char *name, + gcry_ac_id_t *algorithm) + /* */ _GCRY_GCC_ATTR_DEPRECATED; +#endif + + +/************************************ + * * + * Random Generating Functions * + * * + ************************************/ + +/* The possible values for the random quality. The rule of thumb is + to use STRONG for session keys and VERY_STRONG for key material. + WEAK is usually an alias for STRONG and should not be used anymore + (except with gcry_mpi_randomize); use gcry_create_nonce instead. */ +typedef enum gcry_random_level + { + GCRY_WEAK_RANDOM = 0, + GCRY_STRONG_RANDOM = 1, + GCRY_VERY_STRONG_RANDOM = 2 + } +gcry_random_level_t; + +/* Fill BUFFER with LENGTH bytes of random, using random numbers of + quality LEVEL. */ +void gcry_randomize (void *buffer, size_t length, + enum gcry_random_level level); + +/* Add the external random from BUFFER with LENGTH bytes into the + pool. QUALITY should either be -1 for unknown or in the range of 0 + to 100 */ +gcry_error_t gcry_random_add_bytes (const void *buffer, size_t length, + int quality); + +/* If random numbers are used in an application, this macro should be + called from time to time so that new stuff gets added to the + internal pool of the RNG. */ +#define gcry_fast_random_poll() gcry_control (GCRYCTL_FAST_POLL, NULL) + + +/* Return NBYTES of allocated random using a random numbers of quality + LEVEL. */ +void *gcry_random_bytes (size_t nbytes, enum gcry_random_level level) + _GCRY_GCC_ATTR_MALLOC; + +/* Return NBYTES of allocated random using a random numbers of quality + LEVEL. The random numbers are created returned in "secure" + memory. */ +void *gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) + _GCRY_GCC_ATTR_MALLOC; + + +/* Set the big integer W to a random value of NBITS using a random + generator with quality LEVEL. Note that by using a level of + GCRY_WEAK_RANDOM gcry_create_nonce is used internally. */ +void gcry_mpi_randomize (gcry_mpi_t w, + unsigned int nbits, enum gcry_random_level level); + + +/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */ +void gcry_create_nonce (void *buffer, size_t length); + + + + + +/*******************************/ +/* */ +/* Prime Number Functions */ +/* */ +/*******************************/ + +/* Mode values passed to a gcry_prime_check_func_t. */ +#define GCRY_PRIME_CHECK_AT_FINISH 0 +#define GCRY_PRIME_CHECK_AT_GOT_PRIME 1 +#define GCRY_PRIME_CHECK_AT_MAYBE_PRIME 2 + +/* The function should return 1 if the operation shall continue, 0 to + reject the prime candidate. */ +typedef int (*gcry_prime_check_func_t) (void *arg, int mode, + gcry_mpi_t candidate); + +/* Flags for gcry_prime_generate(): */ + +/* Allocate prime numbers and factors in secure memory. */ +#define GCRY_PRIME_FLAG_SECRET (1 << 0) + +/* Make sure that at least one prime factor is of size + `FACTOR_BITS'. */ +#define GCRY_PRIME_FLAG_SPECIAL_FACTOR (1 << 1) + +/* Generate a new prime number of PRIME_BITS bits and store it in + PRIME. If FACTOR_BITS is non-zero, one of the prime factors of + (prime - 1) / 2 must be FACTOR_BITS bits long. If FACTORS is + non-zero, allocate a new, NULL-terminated array holding the prime + factors and store it in FACTORS. FLAGS might be used to influence + the prime number generation process. */ +gcry_error_t gcry_prime_generate (gcry_mpi_t *prime, + unsigned int prime_bits, + unsigned int factor_bits, + gcry_mpi_t **factors, + gcry_prime_check_func_t cb_func, + void *cb_arg, + gcry_random_level_t random_level, + unsigned int flags); + +/* Find a generator for PRIME where the factorization of (prime-1) is + in the NULL terminated array FACTORS. Return the generator as a + newly allocated MPI in R_G. If START_G is not NULL, use this as + teh start for the search. */ +gcry_error_t gcry_prime_group_generator (gcry_mpi_t *r_g, + gcry_mpi_t prime, + gcry_mpi_t *factors, + gcry_mpi_t start_g); + + +/* Convenience function to release the FACTORS array. */ +void gcry_prime_release_factors (gcry_mpi_t *factors); + + +/* Check wether the number X is prime. */ +gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags); + + + +/************************************ + * * + * Miscellaneous Stuff * + * * + ************************************/ + +/* Log levels used by the internal logging facility. */ +enum gcry_log_levels + { + GCRY_LOG_CONT = 0, /* (Continue the last log line.) */ + GCRY_LOG_INFO = 10, + GCRY_LOG_WARN = 20, + GCRY_LOG_ERROR = 30, + GCRY_LOG_FATAL = 40, + GCRY_LOG_BUG = 50, + GCRY_LOG_DEBUG = 100 + }; + +/* Type for progress handlers. */ +typedef void (*gcry_handler_progress_t) (void *, const char *, int, int, int); + +/* Type for memory allocation handlers. */ +typedef void *(*gcry_handler_alloc_t) (size_t n); + +/* Type for secure memory check handlers. */ +typedef int (*gcry_handler_secure_check_t) (const void *); + +/* Type for memory reallocation handlers. */ +typedef void *(*gcry_handler_realloc_t) (void *p, size_t n); + +/* Type for memory free handlers. */ +typedef void (*gcry_handler_free_t) (void *); + +/* Type for out-of-memory handlers. */ +typedef int (*gcry_handler_no_mem_t) (void *, size_t, unsigned int); + +/* Type for fatal error handlers. */ +typedef void (*gcry_handler_error_t) (void *, int, const char *); + +/* Type for logging handlers. */ +typedef void (*gcry_handler_log_t) (void *, int, const char *, va_list); + +/* Certain operations can provide progress information. This function + is used to register a handler for retrieving these information. */ +void gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data); + + +/* Register a custom memory allocation functions. */ +void gcry_set_allocation_handler ( + gcry_handler_alloc_t func_alloc, + gcry_handler_alloc_t func_alloc_secure, + gcry_handler_secure_check_t func_secure_check, + gcry_handler_realloc_t func_realloc, + gcry_handler_free_t func_free); + +/* Register a function used instead of the internal out of memory + handler. */ +void gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque); + +/* Register a function used instead of the internal fatal error + handler. */ +void gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque); + +/* Register a function used instead of the internal logging + facility. */ +void gcry_set_log_handler (gcry_handler_log_t f, void *opaque); + +/* Reserved for future use. */ +void gcry_set_gettext_handler (const char *(*f)(const char*)); + +/* Libgcrypt uses its own memory allocation. It is important to use + gcry_free () to release memory allocated by libgcrypt. */ +void *gcry_malloc (size_t n) _GCRY_GCC_ATTR_MALLOC; +void *gcry_calloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +void *gcry_malloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; +void *gcry_calloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +void *gcry_realloc (void *a, size_t n); +char *gcry_strdup (const char *string) _GCRY_GCC_ATTR_MALLOC; +void *gcry_xmalloc (size_t n) _GCRY_GCC_ATTR_MALLOC; +void *gcry_xcalloc (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +void *gcry_xmalloc_secure (size_t n) _GCRY_GCC_ATTR_MALLOC; +void *gcry_xcalloc_secure (size_t n, size_t m) _GCRY_GCC_ATTR_MALLOC; +void *gcry_xrealloc (void *a, size_t n); +char *gcry_xstrdup (const char * a) _GCRY_GCC_ATTR_MALLOC; +void gcry_free (void *a); + +/* Return true if A is allocated in "secure" memory. */ +int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; + +/* Return true if Libgcrypt is in FIPS mode. */ +#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) + + +/* Include support for Libgcrypt modules. */ +#include <gcrypt-module.h> + +#if 0 /* (Keep Emacsens' auto-indent happy.) */ +{ +#endif +#ifdef __cplusplus +} +#endif +#endif /* _GCRYPT_H */ diff --git a/plugins/MirOTR/Libgcrypt/src/gcryptrnd.c b/plugins/MirOTR/Libgcrypt/src/gcryptrnd.c new file mode 100644 index 0000000000..e15fecaf35 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/gcryptrnd.c @@ -0,0 +1,681 @@ +/* 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 fucntions prints to the stderro 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 occured 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); +} + diff --git a/plugins/MirOTR/Libgcrypt/src/getrandom.c b/plugins/MirOTR/Libgcrypt/src/getrandom.c new file mode 100644 index 0000000000..f4c9b4b2d3 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/getrandom.c @@ -0,0 +1,327 @@ +/* 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; +} + diff --git a/plugins/MirOTR/Libgcrypt/src/global.c b/plugins/MirOTR/Libgcrypt/src/global.c new file mode 100644 index 0000000000..a69513e7d5 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/global.c @@ -0,0 +1,1069 @@ +/* global.c - global control functions + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 + * 2004, 2005, 2006, 2008 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser general Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <ctype.h> +#include <limits.h> +#include <errno.h> +#include <unistd.h> +#ifdef HAVE_SYSLOG +# include <syslog.h> +#endif /*HAVE_SYSLOG*/ + +#include "g10lib.h" +#include "cipher.h" +#include "stdmem.h" /* our own memory allocator */ +#include "secmem.h" /* our own secmem allocator */ +#include "ath.h" + + + +/**************** + * flag bits: 0 : general cipher debug + * 1 : general MPI debug + */ +static unsigned int debug_flags; + +/* gcry_control (GCRYCTL_SET_FIPS_MODE), sets this flag so that the + intialization code swicthed fips mode on. */ +static int force_fips_mode; + +/* Controlled by global_init(). */ +static int any_init_done; + + + +/* Memory management. */ + +static gcry_handler_alloc_t alloc_func; +static gcry_handler_alloc_t alloc_secure_func; +static gcry_handler_secure_check_t is_secure_func; +static gcry_handler_realloc_t realloc_func; +static gcry_handler_free_t free_func; +static gcry_handler_no_mem_t outofcore_handler; +static void *outofcore_handler_value; +static int no_secure_memory; + + + + + +/* This is our handmade constructor. It gets called by any function + likely to be called at startup. The suggested way for an + application to make sure that this has been called is by using + gcry_check_version. */ +static void +global_init (void) +{ + gcry_error_t err = 0; + + if (any_init_done) + return; + any_init_done = 1; + + /* Initialize our portable thread/mutex wrapper. */ + err = ath_init (); + if (err) + goto fail; + + /* See whether the system is in FIPS mode. This needs to come as + early as possible put after the ATH has been initialized. */ + _gcry_initialize_fips_mode (force_fips_mode); + + /* Before we do any other initialization we need to test available + hardware features. */ + _gcry_detect_hw_features (); + + err = _gcry_cipher_init (); + if (err) + goto fail; + err = _gcry_md_init (); + if (err) + goto fail; + err = _gcry_pk_init (); + if (err) + goto fail; +#if 0 + /* Hmmm, as of now ac_init does nothing. */ + if ( !fips_mode () ) + { + err = _gcry_ac_init (); + if (err) + goto fail; + } +#endif + + return; + + fail: + BUG (); +} + + +/* This function is called by the macro fips_is_operational and makes + sure that the minimal initialization has been done. This is far + from a perfect solution and hides problems with an improper + initialization but at least in single-threaded mode it should work + reliable. + + The reason we need this is that a lot of applications don't use + Libgcrypt properly by not running any initialization code at all. + They just call a Libgcrypt function and that is all what they want. + Now with the FIPS mode, that has the side effect of entering FIPS + mode (for security reasons, FIPS mode is the default if no + initialization has been done) and bailing out immediately because + the FSM is in the wrong state. If we always run the init code, + Libgcrypt can test for FIPS mode and at least if not in FIPS mode, + it will behave as before. Note that this on-the-fly initialization + is only done for the cryptographic functions subject to FIPS mode + and thus not all API calls will do such an initialization. */ +int +_gcry_global_is_operational (void) +{ + if (!any_init_done) + { +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " + "missing initialization - please fix the application"); +#endif /*HAVE_SYSLOG*/ + global_init (); + } + return _gcry_fips_is_operational (); +} + + + + +/* Version number parsing. */ + +/* This function parses the first portion of the version number S and + stores it in *NUMBER. On sucess, this function returns a pointer + into S starting with the first character, which is not part of the + initial number portion; on failure, NULL is returned. */ +static const char* +parse_version_number( const char *s, int *number ) +{ + int val = 0; + + if( *s == '0' && isdigit(s[1]) ) + return NULL; /* leading zeros are not allowed */ + for ( ; isdigit(*s); s++ ) { + val *= 10; + val += *s - '0'; + } + *number = val; + return val < 0? NULL : s; +} + +/* This function breaks up the complete string-representation of the + version number S, which is of the following struture: <major + number>.<minor number>.<micro number><patch level>. The major, + minor and micro number components will be stored in *MAJOR, *MINOR + and *MICRO. + + On success, the last component, the patch level, will be returned; + in failure, NULL will be returned. */ + +static const char * +parse_version_string( const char *s, int *major, int *minor, int *micro ) +{ + s = parse_version_number( s, major ); + if( !s || *s != '.' ) + return NULL; + s++; + s = parse_version_number( s, minor ); + if( !s || *s != '.' ) + return NULL; + s++; + s = parse_version_number( s, micro ); + if( !s ) + return NULL; + return s; /* patchlevel */ +} + +/* If REQ_VERSION is non-NULL, check that the version of the library + is at minimum the requested one. Returns the string representation + of the library version if the condition is satisfied; return NULL + if the requested version is newer than that of the library. + + If a NULL is passed to this function, no check is done, but the + string representation of the library is simply returned. */ +const char * +gcry_check_version( const char *req_version ) +{ + const char *ver = VERSION; + int my_major, my_minor, my_micro; + int rq_major, rq_minor, rq_micro; + const char *my_plvl, *rq_plvl; + + /* Initialize library. */ + global_init (); + + if ( !req_version ) + /* Caller wants our version number. */ + return ver; + + /* Parse own version number. */ + my_plvl = parse_version_string( ver, &my_major, &my_minor, &my_micro ); + if ( !my_plvl ) + /* very strange our own version is bogus. Shouldn't we use + assert() here and bail out in case this happens? -mo. */ + return NULL; + + /* Parse requested version number. */ + rq_plvl = parse_version_string( req_version, &rq_major, &rq_minor, + &rq_micro ); + if ( !rq_plvl ) + /* req version string is invalid, this can happen. */ + return NULL; + + /* Compare version numbers. */ + if ( my_major > rq_major + || (my_major == rq_major && my_minor > rq_minor) + || (my_major == rq_major && my_minor == rq_minor + && my_micro > rq_micro) + || (my_major == rq_major && my_minor == rq_minor + && my_micro == rq_micro + && strcmp( my_plvl, rq_plvl ) >= 0) ) { + return ver; + } + + return NULL; +} + + +static void +print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp) +{ + unsigned int hwf; + struct { + unsigned int flag; + const char *desc; + } hwflist[] = { + { HWF_PADLOCK_RNG, "padlock-rng" }, + { HWF_PADLOCK_AES, "padlock-aes" }, + { HWF_PADLOCK_SHA, "padlock-sha" }, + { 0, NULL} + }; + int i; + + fnc (fp, "version:%s:\n", VERSION); + fnc (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS); + fnc (fp, "pubkeys:%s:\n", LIBGCRYPT_PUBKEY_CIPHERS); + fnc (fp, "digests:%s:\n", LIBGCRYPT_DIGESTS); + fnc (fp, "rnd-mod:" +#if USE_RNDEGD + "egd:" +#endif +#if USE_RNDLINUX + "linux:" +#endif +#if USE_RNDUNIX + "unix:" +#endif +#if USE_RNDW32 + "w32:" +#endif + "\n"); + fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ()); + hwf = _gcry_get_hw_features (); + fnc (fp, "hwflist:"); + for (i=0; hwflist[i].desc; i++) + if ( (hwf & hwflist[i].flag) ) + fnc (fp, "%s:", hwflist[i].desc); + fnc (fp, "\n"); + /* We use y/n instead of 1/0 for the simple reason that Emacsen's + compile error parser would accidently flag that line when printed + during "make check" as an error. */ + fnc (fp, "fips-mode:%c:%c:\n", + fips_mode ()? 'y':'n', + _gcry_enforced_fips_mode ()? 'y':'n' ); +} + + + + +/* Command dispatcher function, acting as general control + function. */ +gcry_error_t +_gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr) +{ + static int init_finished = 0; + gcry_err_code_t err = 0; + + switch (cmd) + { + case GCRYCTL_ENABLE_M_GUARD: + _gcry_private_enable_m_guard (); + break; + + case GCRYCTL_ENABLE_QUICK_RANDOM: + _gcry_enable_quick_random_gen (); + break; + + case GCRYCTL_FAKED_RANDOM_P: + /* Return an error if the RNG is faked one (e.g. enabled by + ENABLE_QUICK_RANDOM. */ + if (_gcry_random_is_faked ()) + err = GPG_ERR_GENERAL; /* Use as TRUE value. */ + break; + + case GCRYCTL_DUMP_RANDOM_STATS: + _gcry_random_dump_stats (); + break; + + case GCRYCTL_DUMP_MEMORY_STATS: + /*m_print_stats("[fixme: prefix]");*/ + break; + + case GCRYCTL_DUMP_SECMEM_STATS: + _gcry_secmem_dump_stats (); + break; + + case GCRYCTL_DROP_PRIVS: + global_init (); + _gcry_secmem_init (0); + break; + + case GCRYCTL_DISABLE_SECMEM: + global_init (); + no_secure_memory = 1; + break; + + case GCRYCTL_INIT_SECMEM: + global_init (); + _gcry_secmem_init (va_arg (arg_ptr, unsigned int)); + if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED)) + err = GPG_ERR_GENERAL; + break; + + case GCRYCTL_TERM_SECMEM: + global_init (); + _gcry_secmem_term (); + break; + + case GCRYCTL_DISABLE_SECMEM_WARN: + _gcry_secmem_set_flags ((_gcry_secmem_get_flags () + | GCRY_SECMEM_FLAG_NO_WARNING)); + break; + + case GCRYCTL_SUSPEND_SECMEM_WARN: + _gcry_secmem_set_flags ((_gcry_secmem_get_flags () + | GCRY_SECMEM_FLAG_SUSPEND_WARNING)); + break; + + case GCRYCTL_RESUME_SECMEM_WARN: + _gcry_secmem_set_flags ((_gcry_secmem_get_flags () + & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING)); + break; + + case GCRYCTL_USE_SECURE_RNDPOOL: + global_init (); + _gcry_secure_random_alloc (); /* Put random number into secure memory. */ + break; + + case GCRYCTL_SET_RANDOM_SEED_FILE: + _gcry_set_random_seed_file (va_arg (arg_ptr, const char *)); + break; + + case GCRYCTL_UPDATE_RANDOM_SEED_FILE: + if ( fips_is_operational () ) + _gcry_update_random_seed_file (); + break; + + case GCRYCTL_SET_VERBOSITY: + _gcry_set_log_verbosity (va_arg (arg_ptr, int)); + break; + + case GCRYCTL_SET_DEBUG_FLAGS: + debug_flags |= va_arg (arg_ptr, unsigned int); + break; + + case GCRYCTL_CLEAR_DEBUG_FLAGS: + debug_flags &= ~va_arg (arg_ptr, unsigned int); + break; + + case GCRYCTL_DISABLE_INTERNAL_LOCKING: + /* Not used anymore. */ + global_init (); + break; + + case GCRYCTL_ANY_INITIALIZATION_P: + if (any_init_done) + err = GPG_ERR_GENERAL; + break; + + case GCRYCTL_INITIALIZATION_FINISHED_P: + if (init_finished) + err = GPG_ERR_GENERAL; /* Yes. */ + break; + + case GCRYCTL_INITIALIZATION_FINISHED: + /* This is a hook which should be used by an application after + all initialization has been done and right before any threads + are started. It is not really needed but the only way to be + really sure that all initialization for thread-safety has + been done. */ + if (! init_finished) + { + global_init (); + /* Do only a basic random initialization, i.e. init the + mutexes. */ + _gcry_random_initialize (0); + init_finished = 1; + /* Force us into operational state if in FIPS mode. */ + (void)fips_is_operational (); + } + break; + + case GCRYCTL_SET_THREAD_CBS: + err = ath_install (va_arg (arg_ptr, void *), any_init_done); + if (! err) + global_init (); + break; + + case GCRYCTL_FAST_POLL: + /* We need to do make sure that the random pool is really + initialized so that the poll function is not a NOP. */ + _gcry_random_initialize (1); + + if ( fips_is_operational () ) + _gcry_fast_random_poll (); + break; + + case GCRYCTL_SET_RNDEGD_SOCKET: +#if USE_RNDEGD + err = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *)); +#else + err = gpg_error (GPG_ERR_NOT_SUPPORTED); +#endif + break; + + case GCRYCTL_SET_RANDOM_DAEMON_SOCKET: + _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *)); + break; + + case GCRYCTL_USE_RANDOM_DAEMON: + /* We need to do make sure that the random pool is really + initialized so that the poll function is not a NOP. */ + _gcry_random_initialize (1); + _gcry_use_random_daemon (!! va_arg (arg_ptr, int)); + break; + + /* This command dumps information pertaining to the + configuration of libgcrypt to the given stream. It may be + used before the intialization has been finished but not + before a gcry_version_check. */ + case GCRYCTL_PRINT_CONFIG: + { + FILE *fp = va_arg (arg_ptr, FILE *); + print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp); + } + break; + + case GCRYCTL_OPERATIONAL_P: + /* Returns true if the library is in an operational state. This + is always true for non-fips mode. */ + if (_gcry_fips_test_operational ()) + err = GPG_ERR_GENERAL; /* Used as TRUE value */ + break; + + case GCRYCTL_FIPS_MODE_P: + if (fips_mode () + && !_gcry_is_fips_mode_inactive () + && !no_secure_memory) + err = GPG_ERR_GENERAL; /* Used as TRUE value */ + break; + + case GCRYCTL_FORCE_FIPS_MODE: + /* Performing this command puts the library into fips mode. If + the library has already been initialized into fips mode, a + selftest is triggered. it is not possible to put the libraty + into fips mode after having passed the initialization. */ + if (!any_init_done) + { + /* Not yet intialized at all. Set a flag so that we are put + into fips mode during initialization. */ + force_fips_mode = 1; + } + else + { + /* Already initialized. If we are already operational we + run a selftest. If not we use the is_operational call to + force us into operational state if possible. */ + if (_gcry_fips_test_error_or_operational ()) + _gcry_fips_run_selftests (1); + if (_gcry_fips_is_operational ()) + err = GPG_ERR_GENERAL; /* Used as TRUE value */ + } + break; + + case GCRYCTL_SELFTEST: + /* Run a selftest. This works in fips mode as well as in + standard mode. In contrast to the power-up tests, we use an + extended version of the selftests. Returns 0 on success or an + error code. */ + global_init (); + err = _gcry_fips_run_selftests (1); + break; + + case 58: /* Init external random test. */ + { + void **rctx = va_arg (arg_ptr, void **); + unsigned int flags = va_arg (arg_ptr, unsigned int); + const void *key = va_arg (arg_ptr, const void *); + size_t keylen = va_arg (arg_ptr, size_t); + const void *seed = va_arg (arg_ptr, const void *); + size_t seedlen = va_arg (arg_ptr, size_t); + const void *dt = va_arg (arg_ptr, const void *); + size_t dtlen = va_arg (arg_ptr, size_t); + if (!fips_is_operational ()) + err = fips_not_operational (); + else + err = _gcry_random_init_external_test (rctx, flags, key, keylen, + seed, seedlen, dt, dtlen); + } + break; + case 59: /* Run external random test. */ + { + void *ctx = va_arg (arg_ptr, void *); + void *buffer = va_arg (arg_ptr, void *); + size_t buflen = va_arg (arg_ptr, size_t); + if (!fips_is_operational ()) + err = fips_not_operational (); + else + err = _gcry_random_run_external_test (ctx, buffer, buflen); + } + break; + case 60: /* Deinit external random test. */ + { + void *ctx = va_arg (arg_ptr, void *); + _gcry_random_deinit_external_test (ctx); + } + break; + + + default: + err = GPG_ERR_INV_OP; + } + + return gcry_error (err); +} + + +/* Command dispatcher function, acting as general control + function. */ +gcry_error_t +gcry_control (enum gcry_ctl_cmds cmd, ...) +{ + gcry_error_t err; + va_list arg_ptr; + + va_start (arg_ptr, cmd); + err = _gcry_vcontrol (cmd, arg_ptr); + va_end(arg_ptr); + return err; +} + + + +/* Return a pointer to a string containing a description of the error + code in the error value ERR. */ +const char * +gcry_strerror (gcry_error_t err) +{ + return gpg_strerror (err); +} + +/* Return a pointer to a string containing a description of the error + source in the error value ERR. */ +const char * +gcry_strsource (gcry_error_t err) +{ + return gpg_strsource (err); +} + +/* Retrieve the error code for the system error ERR. This returns + GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report + this). */ +gcry_err_code_t +gcry_err_code_from_errno (int err) +{ + return gpg_err_code_from_errno (err); +} + + +/* Retrieve the system error for the error code CODE. This returns 0 + if CODE is not a system error code. */ +int +gcry_err_code_to_errno (gcry_err_code_t code) +{ + return gpg_err_code_from_errno (code); +} + + +/* Return an error value with the error source SOURCE and the system + error ERR. */ +gcry_error_t +gcry_err_make_from_errno (gpg_err_source_t source, int err) +{ + return gpg_err_make_from_errno (source, err); +} + + +/* Return an error value with the system error ERR. */ +gcry_err_code_t +gcry_error_from_errno (int err) +{ + return gcry_error (gpg_err_code_from_errno (err)); +} + + +/* Set custom allocation handlers. This is in general not useful + * because the libgcrypt allocation functions are guaranteed to + * provide proper allocation handlers which zeroize memory if needed. + * NOTE: All 5 functions should be set. */ +void +gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func, + gcry_handler_alloc_t new_alloc_secure_func, + gcry_handler_secure_check_t new_is_secure_func, + gcry_handler_realloc_t new_realloc_func, + gcry_handler_free_t new_free_func) +{ + global_init (); + + if (fips_mode ()) + { + /* We do not want to enforce the fips mode, but merely set a + flag so that the application may check whether it is still in + fips mode. */ + _gcry_inactivate_fips_mode ("custom allocation handler"); + } + + alloc_func = new_alloc_func; + alloc_secure_func = new_alloc_secure_func; + is_secure_func = new_is_secure_func; + realloc_func = new_realloc_func; + free_func = new_free_func; +} + + + +/**************** + * Set an optional handler which is called in case the xmalloc functions + * ran out of memory. This handler may do one of these things: + * o free some memory and return true, so that the xmalloc function + * tries again. + * o Do whatever it like and return false, so that the xmalloc functions + * use the default fatal error handler. + * o Terminate the program and don't return. + * + * The handler function is called with 3 arguments: The opaque value set with + * this function, the requested memory size, and a flag with these bits + * currently defined: + * bit 0 set = secure memory has been requested. + */ +void +gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ), + void *value ) +{ + global_init (); + + if (fips_mode () ) + { + log_info ("out of core handler ignored in FIPS mode\n"); + return; + } + + outofcore_handler = f; + outofcore_handler_value = value; +} + +/* Return the no_secure_memory flag. */ +static int +get_no_secure_memory (void) +{ + if (!no_secure_memory) + return 0; + if (_gcry_enforced_fips_mode ()) + { + no_secure_memory = 0; + return 0; + } + return no_secure_memory; +} + + +static gcry_err_code_t +do_malloc (size_t n, unsigned int flags, void **mem) +{ + gcry_err_code_t err = 0; + void *m; + + if ((flags & GCRY_ALLOC_FLAG_SECURE) && !get_no_secure_memory ()) + { + if (alloc_secure_func) + m = (*alloc_secure_func) (n); + else + m = _gcry_private_malloc_secure (n); + } + else + { + if (alloc_func) + m = (*alloc_func) (n); + else + m = _gcry_private_malloc (n); + } + + if (!m) + { + /* Make sure that ERRNO has been set in case a user supplied + memory handler didn't it correctly. */ + if (!errno) + errno = ENOMEM; + err = gpg_err_code_from_errno (errno); + } + else + *mem = m; + + return err; +} + +void * +gcry_malloc (size_t n) +{ + void *mem = NULL; + + do_malloc (n, 0, &mem); + + return mem; +} + +void * +gcry_malloc_secure (size_t n) +{ + void *mem = NULL; + + do_malloc (n, GCRY_ALLOC_FLAG_SECURE, &mem); + + return mem; +} + +int +gcry_is_secure (const void *a) +{ + if (get_no_secure_memory ()) + return 0; + if (is_secure_func) + return is_secure_func (a) ; + return _gcry_private_is_secure (a); +} + +void +_gcry_check_heap( const void *a ) +{ + (void)a; + + /* FIXME: implement this*/ +#if 0 + if( some_handler ) + some_handler(a) + else + _gcry_private_check_heap(a) +#endif +} + +void * +gcry_realloc (void *a, size_t n) +{ + void *p; + + if (realloc_func) + p = realloc_func (a, n); + else + p = _gcry_private_realloc (a, n); + if (!p && !errno) + errno = ENOMEM; + return p; +} + +void +gcry_free (void *p) +{ + int save_errno; + + if (!p) + return; + + /* In case ERRNO is set we better save it so that the free machinery + may not accidently change ERRNO. We restore it only if it was + already set to comply with the usual C semantic for ERRNO. */ + save_errno = errno; + if (free_func) + free_func (p); + else + _gcry_private_free (p); + + if (save_errno) + errno = save_errno; +} + +void * +gcry_calloc (size_t n, size_t m) +{ + size_t bytes; + void *p; + + bytes = n * m; /* size_t is unsigned so the behavior on overflow is + defined. */ + if (m && bytes / m != n) + { + errno = ENOMEM; + return NULL; + } + + p = gcry_malloc (bytes); + if (p) + memset (p, 0, bytes); + return p; +} + +void * +gcry_calloc_secure (size_t n, size_t m) +{ + size_t bytes; + void *p; + + bytes = n * m; /* size_t is unsigned so the behavior on overflow is + defined. */ + if (m && bytes / m != n) + { + errno = ENOMEM; + return NULL; + } + + p = gcry_malloc_secure (bytes); + if (p) + memset (p, 0, bytes); + return p; +} + + +/* Create and return a copy of the null-terminated string STRING. If + it is contained in secure memory, the copy will be contained in + secure memory as well. In an out-of-memory condition, NULL is + returned. */ +char * +gcry_strdup (const char *string) +{ + char *string_cp = NULL; + size_t string_n = 0; + + string_n = strlen (string); + + if (gcry_is_secure (string)) + string_cp = gcry_malloc_secure (string_n + 1); + else + string_cp = gcry_malloc (string_n + 1); + + if (string_cp) + strcpy (string_cp, string); + + return string_cp; +} + + +void * +gcry_xmalloc( size_t n ) +{ + void *p; + + while ( !(p = gcry_malloc( n )) ) + { + if ( fips_mode () + || !outofcore_handler + || !outofcore_handler (outofcore_handler_value, n, 0) ) + { + _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL); + } + } + return p; +} + +void * +gcry_xrealloc( void *a, size_t n ) +{ + void *p; + + while ( !(p = gcry_realloc( a, n )) ) + { + if ( fips_mode () + || !outofcore_handler + || !outofcore_handler (outofcore_handler_value, n, + gcry_is_secure(a)? 3:2 ) ) + { + _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL ); + } + } + return p; +} + +void * +gcry_xmalloc_secure( size_t n ) +{ + void *p; + + while ( !(p = gcry_malloc_secure( n )) ) + { + if ( fips_mode () + || !outofcore_handler + || !outofcore_handler (outofcore_handler_value, n, 1) ) + { + _gcry_fatal_error (gpg_err_code_from_errno (errno), + _("out of core in secure memory")); + } + } + return p; +} + + +void * +gcry_xcalloc( size_t n, size_t m ) +{ + size_t nbytes; + void *p; + + nbytes = n * m; + if (m && nbytes / m != n) + { + errno = ENOMEM; + _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL ); + } + + p = gcry_xmalloc ( nbytes ); + memset ( p, 0, nbytes ); + return p; +} + +void * +gcry_xcalloc_secure( size_t n, size_t m ) +{ + size_t nbytes; + void *p; + + nbytes = n * m; + if (m && nbytes / m != n) + { + errno = ENOMEM; + _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL ); + } + + p = gcry_xmalloc_secure ( nbytes ); + memset ( p, 0, nbytes ); + return p; +} + +char * +gcry_xstrdup (const char *string) +{ + char *p; + + while ( !(p = gcry_strdup (string)) ) + { + size_t n = strlen (string); + int is_sec = !!gcry_is_secure (string); + + if (fips_mode () + || !outofcore_handler + || !outofcore_handler (outofcore_handler_value, n, is_sec) ) + { + _gcry_fatal_error (gpg_err_code_from_errno (errno), + is_sec? _("out of core in secure memory"):NULL); + } + } + + return p; +} + + +int +_gcry_get_debug_flag (unsigned int mask) +{ + if ( fips_mode () ) + return 0; + return (debug_flags & mask); +} + + + +/* It is often useful to get some feedback of long running operations. + This function may be used to register a handler for this. + The callback function CB is used as: + + void cb (void *opaque, const char *what, int printchar, + int current, int total); + + Where WHAT is a string identifying the the type of the progress + output, PRINTCHAR the character usually printed, CURRENT the amount + of progress currently done and TOTAL the expected amount of + progress. A value of 0 for TOTAL indicates that there is no + estimation available. + + Defined values for WHAT: + + "need_entropy" X 0 number-of-bytes-required + When running low on entropy + "primegen" '\n' 0 0 + Prime generated + '!' + Need to refresh the prime pool + '<','>' + Number of bits adjusted + '^' + Looking for a generator + '.' + Fermat tests on 10 candidates failed + ':' + Restart with a new random value + '+' + Rabin Miller test passed + "pk_elg" '+','-','.','\n' 0 0 + Only used in debugging mode. + "pk_dsa" + Only used in debugging mode. +*/ +void +gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int), + void *cb_data) +{ +#if USE_DSA + _gcry_register_pk_dsa_progress (cb, cb_data); +#endif +#if USE_ELGAMAL + _gcry_register_pk_elg_progress (cb, cb_data); +#endif + _gcry_register_primegen_progress (cb, cb_data); + _gcry_register_random_progress (cb, cb_data); +} diff --git a/plugins/MirOTR/Libgcrypt/src/hmac256.c b/plugins/MirOTR/Libgcrypt/src/hmac256.c new file mode 100644 index 0000000000..b2f83dd0e7 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/hmac256.c @@ -0,0 +1,784 @@ +/* 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 + +#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 fucntion 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); + 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); + } + } + 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: +*/ diff --git a/plugins/MirOTR/Libgcrypt/src/hmac256.h b/plugins/MirOTR/Libgcrypt/src/hmac256.h new file mode 100644 index 0000000000..df28e72721 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/hmac256.h @@ -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*/ diff --git a/plugins/MirOTR/Libgcrypt/src/hwfeatures.c b/plugins/MirOTR/Libgcrypt/src/hwfeatures.c new file mode 100644 index 0000000000..97442dbad4 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/hwfeatures.c @@ -0,0 +1,167 @@ +/* hwfeatures.c - Detect hardware features. + * 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/>. + */ + +#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) +{ +#ifdef ENABLE_PADLOCK_SUPPORT + /* 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; + + /* Check whether this is a VIA CPU and what PadLock features we + have. */ + if (!strcmp (vendor_id, "CentaurHauls")) + { + 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*/ +} +#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 (void) +{ + 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 +} diff --git a/plugins/MirOTR/Libgcrypt/src/libgcrypt-config.in b/plugins/MirOTR/Libgcrypt/src/libgcrypt-config.in new file mode 100644 index 0000000000..be6df8aceb --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/libgcrypt-config.in @@ -0,0 +1,177 @@ +#!/bin/sh +# Copyright (C) 1999, 2002, 2003, 2004 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@" + +# 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 + +# Prints usage information. +usage() +{ + cat <<EOF +Usage: $0 [OPTIONS] +Options: + [--prefix] + [--exec-prefix] + [--version] + [--api-version] + [--libs] + [--cflags] + [--algorithms] +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 + ;; + *) + 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_algorithms" = "yes"; then + echo "Symmetric cipher algorithms: $symmetric_ciphers" + echo "Public-key cipher algorithms: $asymmetric_ciphers" + echo "Message digest algorithms: $digests" +fi diff --git a/plugins/MirOTR/Libgcrypt/src/libgcrypt.def b/plugins/MirOTR/Libgcrypt/src/libgcrypt.def new file mode 100644 index 0000000000..8fc4d329aa --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/libgcrypt.def @@ -0,0 +1,237 @@ +;; 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 + gcry_cipher_list @104 + + 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 + gcry_pk_list @117 + + gcry_ac_data_new @118 + gcry_ac_data_destroy @119 + gcry_ac_data_set @120 + gcry_ac_data_copy @121 + gcry_ac_data_length @122 + gcry_ac_data_get_name @123 + gcry_ac_data_get_index @124 + gcry_ac_data_clear @125 + gcry_ac_open @126 + gcry_ac_close @127 + gcry_ac_key_init @128 + gcry_ac_key_pair_generate @129 + gcry_ac_key_pair_extract @130 + gcry_ac_key_data_get @131 + gcry_ac_key_test @132 + gcry_ac_key_get_nbits @133 + gcry_ac_key_get_grip @134 + gcry_ac_key_destroy @135 + gcry_ac_key_pair_destroy @136 + gcry_ac_data_encrypt @137 + gcry_ac_data_decrypt @138 + gcry_ac_data_sign @139 + gcry_ac_data_verify @140 + gcry_ac_id_to_name @141 + gcry_ac_name_to_id @142 + + 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 + gcry_md_list @161 + + 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 + + gcry_cipher_register @173 + gcry_cipher_unregister @174 + gcry_md_register @175 + gcry_md_unregister @176 + gcry_pk_register @177 + gcry_pk_unregister @178 + + gcry_ac_data_from_sexp @179 + gcry_ac_data_to_sexp @180 + gcry_ac_io_init @181 + gcry_ac_io_init_va @182 + gcry_ac_data_encrypt_scheme @183 + gcry_ac_data_decrypt_scheme @184 + gcry_ac_data_sign_scheme @185 + gcry_ac_data_verify_scheme @186 + + gcry_sexp_nth_string @187 + + gcry_cipher_setkey @188 + gcry_cipher_setiv @189 + gcry_cipher_setctr @190 + + gcry_mpi_lshift @191 + + + diff --git a/plugins/MirOTR/Libgcrypt/src/libgcrypt.m4 b/plugins/MirOTR/Libgcrypt/src/libgcrypt.m4 new file mode 100644 index 0000000000..854eaaa8cc --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/libgcrypt.m4 @@ -0,0 +1,108 @@ +dnl Autoconf macros for libgcrypt +dnl Copyright (C) 2002, 2004 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_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_PROG(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]) + else + LIBGCRYPT_CFLAGS="" + LIBGCRYPT_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(LIBGCRYPT_CFLAGS) + AC_SUBST(LIBGCRYPT_LIBS) +]) diff --git a/plugins/MirOTR/Libgcrypt/src/libgcrypt.vers b/plugins/MirOTR/Libgcrypt/src/libgcrypt.vers new file mode 100644 index 0000000000..ef9fcee12e --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/libgcrypt.vers @@ -0,0 +1,109 @@ +# libgcrypt.vers - What symbols to export -*- std -*- +# Copyright (C) 2002, 2004, 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, 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.2 { + 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_list; gcry_md_map_name; gcry_md_open; gcry_md_read; + gcry_md_register; gcry_md_reset; gcry_md_setkey; + gcry_md_unregister; 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_list; gcry_cipher_map_name; + gcry_cipher_mode_from_oid; gcry_cipher_open; + gcry_cipher_register; gcry_cipher_unregister; + 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_list; + gcry_pk_map_name; gcry_pk_register; gcry_pk_sign; + gcry_pk_testkey; gcry_pk_unregister; gcry_pk_verify; + + gcry_ac_data_new; gcry_ac_data_destroy; gcry_ac_data_copy; + gcry_ac_data_length; gcry_ac_data_clear; gcry_ac_data_set; + gcry_ac_data_get_name; gcry_ac_data_get_index; gcry_ac_open; + gcry_ac_close; gcry_ac_key_init; gcry_ac_key_pair_generate; + gcry_ac_key_pair_extract; gcry_ac_key_data_get; gcry_ac_key_test; + gcry_ac_key_get_nbits; gcry_ac_key_get_grip; gcry_ac_key_destroy; + gcry_ac_key_pair_destroy; gcry_ac_data_encrypt; gcry_ac_data_decrypt; + gcry_ac_data_sign; gcry_ac_data_verify; gcry_ac_id_to_name; + gcry_ac_name_to_id; gcry_ac_list; gcry_ac_data_encode; + gcry_ac_data_decode; gcry_ac_mpi_to_os; gcry_ac_mpi_to_os_alloc; + gcry_ac_os_to_mpi; gcry_ac_data_encrypt_scheme; + gcry_ac_data_decrypt_scheme; + gcry_ac_data_sign_scheme; gcry_ac_data_verify_scheme; + gcry_ac_data_to_sexp; gcry_ac_data_from_sexp; + gcry_ac_io_init; gcry_ac_io_init_va; + + 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: + *; + +}; + diff --git a/plugins/MirOTR/Libgcrypt/src/misc.c b/plugins/MirOTR/Libgcrypt/src/misc.c new file mode 100644 index 0000000000..fcad8d4e3b --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/misc.c @@ -0,0 +1,297 @@ +/* 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 <io.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 ) +{ + write( 2, s, strlen(s) ); +} + +/* + * 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); +} diff --git a/plugins/MirOTR/Libgcrypt/src/missing-string.c b/plugins/MirOTR/Libgcrypt/src/missing-string.c new file mode 100644 index 0000000000..a5e56c3f76 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/missing-string.c @@ -0,0 +1,55 @@ +/* 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 + diff --git a/plugins/MirOTR/Libgcrypt/src/module.c b/plugins/MirOTR/Libgcrypt/src/module.c new file mode 100644 index 0000000000..c70a44c08a --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/module.c @@ -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 successfull + 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 successfull 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; +} diff --git a/plugins/MirOTR/Libgcrypt/src/mpi.h b/plugins/MirOTR/Libgcrypt/src/mpi.h new file mode 100644 index 0000000000..f630c3f6f3 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/mpi.h @@ -0,0 +1,262 @@ +/* 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 "types.h" +#include "memory.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 fucntions. */ +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*/ diff --git a/plugins/MirOTR/Libgcrypt/src/secmem.c b/plugins/MirOTR/Libgcrypt/src/secmem.c new file mode 100644 index 0000000000..a12af58a22 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/secmem.c @@ -0,0 +1,686 @@ +/* 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 preceeding 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 preceeding 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)) + 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 + */ +#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 + */ +#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. + */ +#else + 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")); + return NULL; + } + } + if (not_locked && fips_mode ()) + { + log_info (_("secure memory pool is not locked while in FIPS mode\n")); + 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 +} diff --git a/plugins/MirOTR/Libgcrypt/src/secmem.h b/plugins/MirOTR/Libgcrypt/src/secmem.h new file mode 100644 index 0000000000..29e151af43 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/secmem.h @@ -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 */ diff --git a/plugins/MirOTR/Libgcrypt/src/sexp.c b/plugins/MirOTR/Libgcrypt/src/sexp.c new file mode 100644 index 0000000000..e11f86ec0a --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/sexp.c @@ -0,0 +1,1976 @@ +/* sexp.c - S-Expression handling
+ * Copyright (C) 1999, 2000, 2001, 2002, 2003,
+ * 2004, 2006, 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, 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 <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+
+#define GCRYPT_NO_MPI_MACROS 1
+#include "g10lib.h"
+
+typedef struct gcry_sexp *NODE;
+typedef unsigned short DATALEN;
+
+struct gcry_sexp
+{
+ byte d[1];
+};
+
+#define ST_STOP 0
+#define ST_DATA 1 /* datalen follows */
+#define ST_HINT 2 /* datalen follows */
+#define ST_OPEN 3
+#define ST_CLOSE 4
+
+/* the atoi macros assume that the buffer has only valid digits */
+#define atoi_1(p) (*(p) - '0' )
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+
+#define TOKEN_SPECIALS "-./_:*+="
+
+static gcry_error_t
+vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, va_list arg_ptr);
+
+static gcry_error_t
+sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, ...);
+
+/* Return true if P points to a byte containing a whitespace according
+ to the S-expressions definition. */
+#undef whitespacep
+static GPG_ERR_INLINE int
+whitespacep (const char *p)
+{
+ switch (*p)
+ {
+ case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1;
+ default: return 0;
+ }
+}
+
+
+#if 0
+static void
+dump_mpi( gcry_mpi_t a )
+{
+ char buffer[1000];
+ size_t n = 1000;
+
+ if( !a )
+ fputs("[no MPI]", stderr );
+ else if( gcry_mpi_print( GCRYMPI_FMT_HEX, buffer, &n, a ) )
+ fputs("[MPI too large to print]", stderr );
+ else
+ fputs( buffer, stderr );
+}
+#endif
+
+static void
+dump_string (const byte *p, size_t n, int delim )
+{
+ for (; n; n--, p++ )
+ {
+ if ((*p & 0x80) || iscntrl( *p ) || *p == delim )
+ {
+ if( *p == '\n' )
+ log_printf ("\\n");
+ else if( *p == '\r' )
+ log_printf ("\\r");
+ else if( *p == '\f' )
+ log_printf ("\\f");
+ else if( *p == '\v' )
+ log_printf ("\\v");
+ else if( *p == '\b' )
+ log_printf ("\\b");
+ else if( !*p )
+ log_printf ("\\0");
+ else
+ log_printf ("\\x%02x", *p );
+ }
+ else
+ log_printf ("%c", *p);
+ }
+}
+
+
+void
+gcry_sexp_dump (const gcry_sexp_t a)
+{
+ const byte *p;
+ int indent = 0;
+ int type;
+
+ if (!a)
+ {
+ log_printf ( "[nil]\n");
+ return;
+ }
+
+ p = a->d;
+ while ( (type = *p) != ST_STOP )
+ {
+ p++;
+ switch ( type )
+ {
+ case ST_OPEN:
+ log_printf ("%*s[open]\n", 2*indent, "");
+ indent++;
+ break;
+ case ST_CLOSE:
+ if( indent )
+ indent--;
+ log_printf ("%*s[close]\n", 2*indent, "");
+ break;
+ case ST_DATA: {
+ DATALEN n;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ log_printf ("%*s[data=\"", 2*indent, "" );
+ dump_string (p, n, '\"' );
+ log_printf ("\"]\n");
+ p += n;
+ }
+ break;
+ default:
+ log_printf ("%*s[unknown tag %d]\n", 2*indent, "", type);
+ break;
+ }
+ }
+}
+
+/****************
+ * Pass list through except when it is an empty list - in that case
+ * return NULL and release the passed list.
+ */
+static gcry_sexp_t
+normalize ( gcry_sexp_t list )
+{
+ unsigned char *p;
+
+ if ( !list )
+ return NULL;
+ p = list->d;
+ if ( *p == ST_STOP )
+ {
+ /* this is "" */
+ gcry_sexp_release ( list );
+ return NULL;
+ }
+ if ( *p == ST_OPEN && p[1] == ST_CLOSE )
+ {
+ /* this is "()" */
+ gcry_sexp_release ( list );
+ return NULL;
+ }
+
+ return list;
+}
+
+/* Create a new S-expression object by reading LENGTH bytes from
+ BUFFER, assuming it is canonical encoded or autodetected encoding
+ when AUTODETECT is set to 1. With FREEFNC not NULL, ownership of
+ the buffer is transferred to the newly created object. FREEFNC
+ should be the freefnc used to release BUFFER; there is no guarantee
+ at which point this function is called; most likey you want to use
+ free() or gcry_free().
+
+ Passing LENGTH and AUTODETECT as 0 is allowed to indicate that
+ BUFFER points to a valid canonical encoded S-expression. A LENGTH
+ of 0 and AUTODETECT 1 indicates that buffer points to a
+ null-terminated string.
+
+ This function returns 0 and and the pointer to the new object in
+ RETSEXP or an error code in which case RETSEXP is set to NULL. */
+gcry_error_t
+gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
+ int autodetect, void (*freefnc)(void*) )
+{
+ gcry_error_t errcode;
+ gcry_sexp_t se;
+
+ if (!retsexp)
+ return gcry_error (GPG_ERR_INV_ARG);
+ *retsexp = NULL;
+ if (autodetect < 0 || autodetect > 1 || !buffer)
+ return gcry_error (GPG_ERR_INV_ARG);
+
+ if (!length && !autodetect)
+ { /* What a brave caller to assume that there is really a canonical
+ encoded S-expression in buffer */
+ length = gcry_sexp_canon_len (buffer, 0, NULL, &errcode);
+ if (!length)
+ return errcode;
+ }
+ else if (!length && autodetect)
+ { /* buffer is a string */
+ length = strlen ((char *)buffer);
+ }
+
+ errcode = sexp_sscan (&se, NULL, buffer, length, 0, NULL);
+ if (errcode)
+ return errcode;
+
+ *retsexp = se;
+ if (freefnc)
+ {
+ /* For now we release the buffer immediately. As soon as we
+ have changed the internal represenation of S-expression to
+ the canoncial format - which has the advantage of faster
+ parsing - we will use this function as a closure in our
+ GCRYSEXP object and use the BUFFER directly. */
+ freefnc (buffer);
+ }
+ return gcry_error (GPG_ERR_NO_ERROR);
+}
+
+/* Same as gcry_sexp_create but don't transfer ownership */
+gcry_error_t
+gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length,
+ int autodetect)
+{
+ return gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL);
+}
+
+
+/****************
+ * Release resource of the given SEXP object.
+ */
+void
+gcry_sexp_release( gcry_sexp_t sexp )
+{
+ if (sexp)
+ {
+ if (gcry_is_secure (sexp))
+ {
+ /* Extra paranoid wiping. */
+ const byte *p = sexp->d;
+ int type;
+
+ while ( (type = *p) != ST_STOP )
+ {
+ p++;
+ switch ( type )
+ {
+ case ST_OPEN:
+ break;
+ case ST_CLOSE:
+ break;
+ case ST_DATA:
+ {
+ DATALEN n;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ p += n;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ wipememory (sexp->d, p - sexp->d);
+ }
+ gcry_free ( sexp );
+ }
+}
+
+
+/****************
+ * Make a pair from lists a and b, don't use a or b later on.
+ * Special behaviour: If one is a single element list we put the
+ * element straight into the new pair.
+ */
+gcry_sexp_t
+gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b )
+{
+ (void)a;
+ (void)b;
+
+ /* NYI: Implementation should be quite easy with our new data
+ representation */
+ BUG ();
+ return NULL;
+}
+
+
+/****************
+ * Make a list from all items in the array the end of the array is marked
+ * with a NULL.
+ */
+gcry_sexp_t
+gcry_sexp_alist( const gcry_sexp_t *array )
+{
+ (void)array;
+
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+/****************
+ * Make a list from all items, the end of list is indicated by a NULL
+ */
+gcry_sexp_t
+gcry_sexp_vlist( const gcry_sexp_t a, ... )
+{
+ (void)a;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+
+/****************
+ * Append n to the list a
+ * Returns: a new ist (which maybe a)
+ */
+gcry_sexp_t
+gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n )
+{
+ (void)a;
+ (void)n;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+gcry_sexp_t
+gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n )
+{
+ (void)a;
+ (void)n;
+ /* NYI: Implementation should be quite easy with our new data
+ representation. */
+ BUG ();
+ return NULL;
+}
+
+
+
+/****************
+ * Locate token in a list. The token must be the car of a sublist.
+ * Returns: A new list with this sublist or NULL if not found.
+ */
+gcry_sexp_t
+gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
+{
+ const byte *p;
+ DATALEN n;
+
+ if ( !list )
+ return NULL;
+
+ if ( !toklen )
+ toklen = strlen(tok);
+
+ p = list->d;
+ while ( *p != ST_STOP )
+ {
+ if ( *p == ST_OPEN && p[1] == ST_DATA )
+ {
+ const byte *head = p;
+
+ p += 2;
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ if ( n == toklen && !memcmp( p, tok, toklen ) )
+ { /* found it */
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 1;
+
+ /* Look for the end of the list. */
+ for ( p += n; level; p++ )
+ {
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--; /* Compensate for later increment. */
+ }
+ else if ( *p == ST_OPEN )
+ {
+ level++;
+ }
+ else if ( *p == ST_CLOSE )
+ {
+ level--;
+ }
+ else if ( *p == ST_STOP )
+ {
+ BUG ();
+ }
+ }
+ n = p - head;
+
+ newlist = gcry_malloc ( sizeof *newlist + n );
+ if (!newlist)
+ {
+ /* No way to return an error code, so we can only
+ return Not Found. */
+ return NULL;
+ }
+ d = newlist->d;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_STOP;
+ return normalize ( newlist );
+ }
+ p += n;
+ }
+ else if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n ); p += sizeof n;
+ p += n;
+ }
+ else
+ p++;
+ }
+ return NULL;
+}
+
+/****************
+ * Return the length of the given list
+ */
+int
+gcry_sexp_length( const gcry_sexp_t list )
+{
+ const byte *p;
+ DATALEN n;
+ int type;
+ int length = 0;
+ int level = 0;
+
+ if ( !list )
+ return 0;
+
+ p = list->d;
+ while ( (type=*p) != ST_STOP ) {
+ p++;
+ if ( type == ST_DATA ) {
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n + n;
+ if ( level == 1 )
+ length++;
+ }
+ else if ( type == ST_OPEN ) {
+ if ( level == 1 )
+ length++;
+ level++;
+ }
+ else if ( type == ST_CLOSE ) {
+ level--;
+ }
+ }
+ return length;
+}
+
+
+/* Return the internal lengths offset of LIST. That is the size of
+ the buffer from the first ST_OPEN, which is retruned at R_OFF, to
+ the corresponding ST_CLOSE inclusive. */
+static size_t
+get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
+{
+ const unsigned char *p;
+ DATALEN n;
+ int type;
+ int level = 0;
+
+ *r_off = 0;
+ if (list)
+ {
+ p = list->d;
+ while ( (type=*p) != ST_STOP )
+ {
+ p++;
+ if (type == ST_DATA)
+ {
+ memcpy (&n, p, sizeof n);
+ p += sizeof n + n;
+ }
+ else if (type == ST_OPEN)
+ {
+ if (!level)
+ *r_off = (p-1) - list->d;
+ level++;
+ }
+ else if ( type == ST_CLOSE )
+ {
+ level--;
+ if (!level)
+ return p - list->d;
+ }
+ }
+ }
+ return 0; /* Not a proper list. */
+}
+
+
+
+/* Extract the CAR of the given list. May return NULL for bad lists
+ or memory failure. */
+gcry_sexp_t
+gcry_sexp_nth( const gcry_sexp_t list, int number )
+{
+ const byte *p;
+ DATALEN n;
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 0;
+
+ if ( !list || list->d[0] != ST_OPEN )
+ return NULL;
+ p = list->d;
+
+ while ( number > 0 ) {
+ p++;
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_STOP ) {
+ return NULL;
+ }
+ }
+ p++;
+
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, p, sizeof n ); p += sizeof n;
+ newlist = gcry_malloc ( sizeof *newlist + n + 1 );
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ memcpy ( d, p, n ); d += n;
+ *d++ = ST_STOP;
+ }
+ else if ( *p == ST_OPEN ) {
+ const byte *head = p;
+
+ level = 1;
+ do {
+ p++;
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ }
+ else if ( *p == ST_STOP ) {
+ BUG ();
+ }
+ } while ( level );
+ n = p + 1 - head;
+
+ newlist = gcry_malloc ( sizeof *newlist + n );
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_STOP;
+ }
+ else
+ newlist = NULL;
+
+ return normalize (newlist);
+}
+
+gcry_sexp_t
+gcry_sexp_car( const gcry_sexp_t list )
+{
+ return gcry_sexp_nth ( list, 0 );
+}
+
+
+/* Helper to get data from the car. The returned value is valid as
+ long as the list is not modified. */
+static const char *
+sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
+{
+ const byte *p;
+ DATALEN n;
+ int level = 0;
+
+ *datalen = 0;
+ if ( !list )
+ return NULL;
+
+ p = list->d;
+ if ( *p == ST_OPEN )
+ p++; /* Yep, a list. */
+ else if (number)
+ return NULL; /* Not a list but N > 0 requested. */
+
+ /* Skip over N elements. */
+ while ( number > 0 )
+ {
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_OPEN )
+ {
+ level++;
+ }
+ else if ( *p == ST_CLOSE )
+ {
+ level--;
+ if ( !level )
+ number--;
+ }
+ else if ( *p == ST_STOP )
+ {
+ return NULL;
+ }
+ p++;
+ }
+
+ /* If this is data, return it. */
+ if ( *p == ST_DATA )
+ {
+ memcpy ( &n, ++p, sizeof n );
+ *datalen = n;
+ return (const char*)p + sizeof n;
+ }
+
+ return NULL;
+}
+
+
+/* Get data from the car. The returned value is valid as long as the
+ list is not modified. */
+const char *
+gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
+{
+ return sexp_nth_data (list, number, datalen);
+}
+
+
+/* Get a string from the car. The returned value is a malloced string
+ and needs to be freed by the caller. */
+char *
+gcry_sexp_nth_string (const gcry_sexp_t list, int number)
+{
+ const char *s;
+ size_t n;
+ char *buf;
+
+ s = sexp_nth_data (list, number, &n);
+ if (!s || n < 1 || (n+1) < 1)
+ return NULL;
+ buf = gcry_malloc (n+1);
+ if (!buf)
+ return NULL;
+ memcpy (buf, s, n);
+ buf[n] = 0;
+ return buf;
+}
+
+/*
+ * Get a MPI from the car
+ */
+gcry_mpi_t
+gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt )
+{
+ const char *s;
+ size_t n;
+ gcry_mpi_t a;
+
+ if ( !mpifmt )
+ mpifmt = GCRYMPI_FMT_STD;
+
+ s = sexp_nth_data (list, number, &n);
+ if (!s)
+ return NULL;
+
+ if ( gcry_mpi_scan ( &a, mpifmt, s, n, NULL ) )
+ return NULL;
+
+ return a;
+}
+
+
+/****************
+ * Get the CDR
+ */
+gcry_sexp_t
+gcry_sexp_cdr( const gcry_sexp_t list )
+{
+ const byte *p;
+ const byte *head;
+ DATALEN n;
+ gcry_sexp_t newlist;
+ byte *d;
+ int level = 0;
+ int skip = 1;
+
+ if ( !list || list->d[0] != ST_OPEN )
+ return NULL;
+ p = list->d;
+
+ while ( skip > 0 ) {
+ p++;
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ if ( !level )
+ skip--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ if ( !level )
+ skip--;
+ }
+ else if ( *p == ST_STOP ) {
+ return NULL;
+ }
+ }
+ p++;
+
+ head = p;
+ level = 0;
+ do {
+ if ( *p == ST_DATA ) {
+ memcpy ( &n, ++p, sizeof n );
+ p += sizeof n + n;
+ p--;
+ }
+ else if ( *p == ST_OPEN ) {
+ level++;
+ }
+ else if ( *p == ST_CLOSE ) {
+ level--;
+ }
+ else if ( *p == ST_STOP ) {
+ return NULL;
+ }
+ p++;
+ } while ( level );
+ n = p - head;
+
+ newlist = gcry_malloc ( sizeof *newlist + n + 2 );
+ if (!newlist)
+ return NULL;
+ d = newlist->d;
+ *d++ = ST_OPEN;
+ memcpy ( d, head, n ); d += n;
+ *d++ = ST_CLOSE;
+ *d++ = ST_STOP;
+
+ return normalize (newlist);
+}
+
+gcry_sexp_t
+gcry_sexp_cadr ( const gcry_sexp_t list )
+{
+ gcry_sexp_t a, b;
+
+ a = gcry_sexp_cdr ( list );
+ b = gcry_sexp_car ( a );
+ gcry_sexp_release ( a );
+ return b;
+}
+
+
+
+static int
+hextobyte( const byte *s )
+{
+ int c=0;
+
+ if( *s >= '0' && *s <= '9' )
+ c = 16 * (*s - '0');
+ else if( *s >= 'A' && *s <= 'F' )
+ c = 16 * (10 + *s - 'A');
+ else if( *s >= 'a' && *s <= 'f' ) {
+ c = 16 * (10 + *s - 'a');
+ }
+ s++;
+ if( *s >= '0' && *s <= '9' )
+ c += *s - '0';
+ else if( *s >= 'A' && *s <= 'F' )
+ c += 10 + *s - 'A';
+ else if( *s >= 'a' && *s <= 'f' ) {
+ c += 10 + *s - 'a';
+ }
+ return c;
+}
+
+struct make_space_ctx {
+ gcry_sexp_t sexp;
+ size_t allocated;
+ byte *pos;
+};
+
+static gpg_err_code_t
+make_space ( struct make_space_ctx *c, size_t n )
+{
+ size_t used = c->pos - c->sexp->d;
+
+ if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
+ {
+ gcry_sexp_t newsexp;
+ byte *newhead;
+ size_t newsize;
+
+ newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
+ if (newsize <= c->allocated)
+ return GPG_ERR_TOO_LARGE;
+ newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1);
+ if (!newsexp)
+ return gpg_err_code_from_errno (errno);
+ c->allocated = newsize;
+ newhead = newsexp->d;
+ c->pos = newhead + used;
+ c->sexp = newsexp;
+ }
+ return 0;
+}
+
+
+/* Unquote STRING of LENGTH and store it into BUF. The surrounding
+ quotes are must already be removed from STRING. We assume that the
+ quoted string is syntacillay correct. */
+static size_t
+unquote_string (const char *string, size_t length, unsigned char *buf)
+{
+ int esc = 0;
+ const unsigned char *s = (const unsigned char*)string;
+ unsigned char *d = buf;
+ size_t n = length;
+
+ for (; n; n--, s++)
+ {
+ if (esc)
+ {
+ switch (*s)
+ {
+ case 'b': *d++ = '\b'; break;
+ case 't': *d++ = '\t'; break;
+ case 'v': *d++ = '\v'; break;
+ case 'n': *d++ = '\n'; break;
+ case 'f': *d++ = '\f'; break;
+ case 'r': *d++ = '\r'; break;
+ case '"': *d++ = '\"'; break;
+ case '\'': *d++ = '\''; break;
+ case '\\': *d++ = '\\'; break;
+
+ case '\r': /* ignore CR[,LF] */
+ if (n>1 && s[1] == '\n')
+ {
+ s++; n--;
+ }
+ break;
+
+ case '\n': /* ignore LF[,CR] */
+ if (n>1 && s[1] == '\r')
+ {
+ s++; n--;
+ }
+ break;
+
+ case 'x': /* hex value */
+ if (n>2 && hexdigitp (s+1) && hexdigitp (s+2))
+ {
+ s++; n--;
+ *d++ = xtoi_2 (s);
+ s++; n--;
+ }
+ break;
+
+ default:
+ if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
+ {
+ *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
+ s += 2;
+ n -= 2;
+ }
+ break;
+ }
+ esc = 0;
+ }
+ else if( *s == '\\' )
+ esc = 1;
+ else
+ *d++ = *s;
+ }
+
+ return d - buf;
+}
+
+/****************
+ * Scan the provided buffer and return the S expression in our internal
+ * format. Returns a newly allocated expression. If erroff is not NULL and
+ * a parsing error has occurred, the offset into buffer will be returned.
+ * If ARGFLAG is true, the function supports some printf like
+ * expressions.
+ * These are:
+ * %m - MPI
+ * %s - string (no autoswitch to secure allocation)
+ * %d - integer stored as string (no autoswitch to secure allocation)
+ * %b - memory buffer; this takes _two_ arguments: an integer with the
+ * length of the buffer and a pointer to the buffer.
+ * %S - Copy an gcry_sexp_t here. The S-expression needs to be a
+ * regular one, starting with a parenthesis.
+ * (no autoswitch to secure allocation)
+ * all other format elements are currently not defined and return an error.
+ * this includes the "%%" sequence becauce the percent sign is not an
+ * allowed character.
+ * FIXME: We should find a way to store the secure-MPIs not in the string
+ * but as reference to somewhere - this can help us to save huge amounts
+ * of secure memory. The problem is, that if only one element is secure, all
+ * other elements are automagicaly copied to secure memory too, so the most
+ * common operation gcry_sexp_cdr_mpi() will always return a secure MPI
+ * regardless whether it is needed or not.
+ */
+static gcry_error_t
+vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, va_list arg_ptr)
+{
+ gcry_err_code_t err = 0;
+ static const char tokenchars[] =
+ "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789-./_:*+=";
+ const char *p;
+ size_t n;
+ const char *digptr = NULL;
+ const char *quoted = NULL;
+ const char *tokenp = NULL;
+ const char *hexfmt = NULL;
+ const char *base64 = NULL;
+ const char *disphint = NULL;
+ const char *percent = NULL;
+ int hexcount = 0;
+ int quoted_esc = 0;
+ int datalen = 0;
+ size_t dummy_erroff;
+ struct make_space_ctx c;
+ int arg_counter = 0;
+ int level = 0;
+
+ if (!erroff)
+ erroff = &dummy_erroff;
+
+ /* Depending on whether ARG_LIST is non-zero or not, this macro gives
+ us the next argument, either from the variable argument list as
+ specified by ARG_PTR or from the argument array ARG_LIST. */
+#define ARG_NEXT(storage, type) \
+ do \
+ { \
+ if (!arg_list) \
+ storage = va_arg (arg_ptr, type); \
+ else \
+ storage = *((type *) (arg_list[arg_counter++])); \
+ } \
+ while (0)
+
+ /* The MAKE_SPACE macro is used before each store operation to
+ ensure that the buffer is large enough. It requires a global
+ context named C and jumps out to the label LEAVE on error! It
+ also sets ERROFF using the variables BUFFER and P. */
+#define MAKE_SPACE(n) do { \
+ gpg_err_code_t _ms_err = make_space (&c, (n)); \
+ if (_ms_err) \
+ { \
+ err = _ms_err; \
+ *erroff = p - buffer; \
+ goto leave; \
+ } \
+ } while (0)
+
+ /* The STORE_LEN macro is used to store the length N at buffer P. */
+#define STORE_LEN(p,n) do { \
+ DATALEN ashort = (n); \
+ memcpy ( (p), &ashort, sizeof(ashort) ); \
+ (p) += sizeof (ashort); \
+ } while (0)
+
+ /* We assume that the internal representation takes less memory than
+ the provided one. However, we add space for one extra datalen so
+ that the code which does the ST_CLOSE can use MAKE_SPACE */
+ c.allocated = length + sizeof(DATALEN);
+ if (buffer && length && gcry_is_secure (buffer))
+ c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1);
+ else
+ c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1);
+ if (!c.sexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ *erroff = 0;
+ goto leave;
+ }
+ c.pos = c.sexp->d;
+
+ for (p = buffer, n = length; n; p++, n--)
+ {
+ if (tokenp && !hexfmt)
+ {
+ if (strchr (tokenchars, *p))
+ continue;
+ else
+ {
+ datalen = p - tokenp;
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ memcpy (c.pos, tokenp, datalen);
+ c.pos += datalen;
+ tokenp = NULL;
+ }
+ }
+
+ if (quoted)
+ {
+ if (quoted_esc)
+ {
+ switch (*p)
+ {
+ case 'b': case 't': case 'v': case 'n': case 'f':
+ case 'r': case '"': case '\'': case '\\':
+ quoted_esc = 0;
+ break;
+
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7':
+ if (!((n > 2)
+ && (p[1] >= '0') && (p[1] <= '7')
+ && (p[2] >= '0') && (p[2] <= '7')))
+ {
+ *erroff = p - buffer;
+ /* Invalid octal value. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ p += 2;
+ n -= 2;
+ quoted_esc = 0;
+ break;
+
+ case 'x':
+ if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
+ {
+ *erroff = p - buffer;
+ /* Invalid hex value. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ p += 2;
+ n -= 2;
+ quoted_esc = 0;
+ break;
+
+ case '\r':
+ /* ignore CR[,LF] */
+ if (n && (p[1] == '\n'))
+ {
+ p++;
+ n--;
+ }
+ quoted_esc = 0;
+ break;
+
+ case '\n':
+ /* ignore LF[,CR] */
+ if (n && (p[1] == '\r'))
+ {
+ p++;
+ n--;
+ }
+ quoted_esc = 0;
+ break;
+
+ default:
+ *erroff = p - buffer;
+ /* Invalid quoted string escape. */
+ err = GPG_ERR_SEXP_BAD_QUOTATION;
+ goto leave;
+ }
+ }
+ else if (*p == '\\')
+ quoted_esc = 1;
+ else if (*p == '\"')
+ {
+ /* Keep it easy - we know that the unquoted string will
+ never be larger. */
+ unsigned char *save;
+ size_t len;
+
+ quoted++; /* Skip leading quote. */
+ MAKE_SPACE (p - quoted);
+ *c.pos++ = ST_DATA;
+ save = c.pos;
+ STORE_LEN (c.pos, 0); /* Will be fixed up later. */
+ len = unquote_string (quoted, p - quoted, c.pos);
+ c.pos += len;
+ STORE_LEN (save, len);
+ quoted = NULL;
+ }
+ }
+ else if (hexfmt)
+ {
+ if (isxdigit (*p))
+ hexcount++;
+ else if (*p == '#')
+ {
+ if ((hexcount & 1))
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
+ goto leave;
+ }
+
+ datalen = hexcount / 2;
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ for (hexfmt++; hexfmt < p; hexfmt++)
+ {
+ if (whitespacep (hexfmt))
+ continue;
+ *c.pos++ = hextobyte ((const unsigned char*)hexfmt);
+ hexfmt++;
+ }
+ hexfmt = NULL;
+ }
+ else if (!whitespacep (p))
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_BAD_HEX_CHAR;
+ goto leave;
+ }
+ }
+ else if (base64)
+ {
+ if (*p == '|')
+ base64 = NULL;
+ }
+ else if (digptr)
+ {
+ if (digitp (p))
+ ;
+ else if (*p == ':')
+ {
+ datalen = atoi (digptr); /* FIXME: check for overflow. */
+ digptr = NULL;
+ if (datalen > n - 1)
+ {
+ *erroff = p - buffer;
+ /* Buffer too short. */
+ err = GPG_ERR_SEXP_STRING_TOO_LONG;
+ goto leave;
+ }
+ /* Make a new list entry. */
+ MAKE_SPACE (datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ memcpy (c.pos, p + 1, datalen);
+ c.pos += datalen;
+ n -= datalen;
+ p += datalen;
+ }
+ else if (*p == '\"')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ quoted = p;
+ quoted_esc = 0;
+ }
+ else if (*p == '#')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ hexfmt = p;
+ hexcount = 0;
+ }
+ else if (*p == '|')
+ {
+ digptr = NULL; /* We ignore the optional length. */
+ base64 = p;
+ }
+ else
+ {
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_INV_LEN_SPEC;
+ goto leave;
+ }
+ }
+ else if (percent)
+ {
+ if (*p == 'm')
+ {
+ /* Insert an MPI. */
+ gcry_mpi_t m;
+ size_t nm = 0;
+
+ ARG_NEXT (m, gcry_mpi_t);
+
+ if (gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &nm, m))
+ BUG ();
+
+ MAKE_SPACE (nm);
+ if (!gcry_is_secure (c.sexp->d)
+ && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = gcry_malloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ gcry_free (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, nm);
+ if (gcry_mpi_print (GCRYMPI_FMT_STD, c.pos, nm, &nm, m))
+ BUG ();
+ c.pos += nm;
+ }
+ else if (*p == 's')
+ {
+ /* Insert an string. */
+ const char *astr;
+ size_t alen;
+
+ ARG_NEXT (astr, const char *);
+ alen = strlen (astr);
+
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, astr, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'b')
+ {
+ /* Insert a memory buffer. */
+ const char *astr;
+ int alen;
+
+ ARG_NEXT (alen, int);
+ ARG_NEXT (astr, const char *);
+
+ MAKE_SPACE (alen);
+ if (alen
+ && !gcry_is_secure (c.sexp->d)
+ && gcry_is_secure (astr))
+ {
+ /* We have to switch to secure allocation. */
+ gcry_sexp_t newsexp;
+ byte *newhead;
+
+ newsexp = gcry_malloc_secure (sizeof *newsexp
+ + c.allocated - 1);
+ if (!newsexp)
+ {
+ err = gpg_err_code_from_errno (errno);
+ goto leave;
+ }
+ newhead = newsexp->d;
+ memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
+ c.pos = newhead + (c.pos - c.sexp->d);
+ gcry_free (c.sexp);
+ c.sexp = newsexp;
+ }
+
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, astr, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'd')
+ {
+ /* Insert an integer as string. */
+ int aint;
+ size_t alen;
+ char buf[20];
+
+ ARG_NEXT (aint, int);
+ sprintf (buf, "%d", aint);
+ alen = strlen (buf);
+ MAKE_SPACE (alen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy (c.pos, buf, alen);
+ c.pos += alen;
+ }
+ else if (*p == 'S')
+ {
+ /* Insert a gcry_sexp_t. */
+ gcry_sexp_t asexp;
+ size_t alen, aoff;
+
+ ARG_NEXT (asexp, gcry_sexp_t);
+ alen = get_internal_buffer (asexp, &aoff);
+ if (alen)
+ {
+ MAKE_SPACE (alen);
+ memcpy (c.pos, asexp->d + aoff, alen);
+ c.pos += alen;
+ }
+ }
+ else
+ {
+ *erroff = p - buffer;
+ /* Invalid format specifier. */
+ err = GPG_ERR_SEXP_INV_LEN_SPEC;
+ goto leave;
+ }
+ percent = NULL;
+ }
+ else if (*p == '(')
+ {
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_OPEN;
+ level++;
+ }
+ else if (*p == ')')
+ {
+ /* Walk up. */
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_CLOSE;
+ level--;
+ }
+ else if (*p == '\"')
+ {
+ quoted = p;
+ quoted_esc = 0;
+ }
+ else if (*p == '#')
+ {
+ hexfmt = p;
+ hexcount = 0;
+ }
+ else if (*p == '|')
+ base64 = p;
+ else if (*p == '[')
+ {
+ if (disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_NESTED_DH;
+ goto leave;
+ }
+ disphint = p;
+ }
+ else if (*p == ']')
+ {
+ if (!disphint)
+ {
+ *erroff = p - buffer;
+ /* Open display hint. */
+ err = GPG_ERR_SEXP_UNMATCHED_DH;
+ goto leave;
+ }
+ disphint = NULL;
+ }
+ else if (digitp (p))
+ {
+ if (*p == '0')
+ {
+ /* A length may not begin with zero. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_ZERO_PREFIX;
+ goto leave;
+ }
+ digptr = p;
+ }
+ else if (strchr (tokenchars, *p))
+ tokenp = p;
+ else if (whitespacep (p))
+ ;
+ else if (*p == '{')
+ {
+ /* fixme: handle rescanning: we can do this by saving our
+ current state and start over at p+1 -- Hmmm. At this
+ point here we are in a well defined state, so we don't
+ need to save it. Great. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+ goto leave;
+ }
+ else if (strchr ("&\\", *p))
+ {
+ /* Reserved punctuation. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
+ goto leave;
+ }
+ else if (argflag && (*p == '%'))
+ percent = p;
+ else
+ {
+ /* Bad or unavailable. */
+ *erroff = p - buffer;
+ err = GPG_ERR_SEXP_BAD_CHARACTER;
+ goto leave;
+ }
+ }
+ MAKE_SPACE (0);
+ *c.pos++ = ST_STOP;
+
+ if (level && !err)
+ err = GPG_ERR_SEXP_UNMATCHED_PAREN;
+
+ leave:
+ if (err)
+ {
+ /* Error -> deallocate. */
+ if (c.sexp)
+ {
+ /* Extra paranoid wipe on error. */
+ if (gcry_is_secure (c.sexp))
+ wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
+ gcry_free (c.sexp);
+ }
+ /* This might be expected by existing code... */
+ *retsexp = NULL;
+ }
+ else
+ *retsexp = normalize (c.sexp);
+
+ return gcry_error (err);
+#undef MAKE_SPACE
+#undef STORE_LEN
+}
+
+
+static gcry_error_t
+sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length, int argflag,
+ void **arg_list, ...)
+{
+ gcry_error_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, arg_list);
+ rc = vsexp_sscan (retsexp, erroff, buffer, length, argflag,
+ arg_list, arg_ptr);
+ va_end (arg_ptr);
+
+ return rc;
+}
+
+
+gcry_error_t
+gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
+{
+ gcry_error_t rc;
+ va_list arg_ptr;
+
+ va_start (arg_ptr, format);
+ rc = vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
+ NULL, arg_ptr);
+ va_end (arg_ptr);
+
+ return rc;
+}
+
+
+gcry_error_t
+_gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, va_list arg_ptr)
+{
+ return vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
+ NULL, arg_ptr);
+}
+
+
+/* Like gcry_sexp_build, but uses an array instead of variable
+ function arguments. */
+gcry_error_t
+gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *format, void **arg_list)
+{
+ return sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
+}
+
+
+gcry_error_t
+gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+ const char *buffer, size_t length)
+{
+ return sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
+}
+
+
+/* Figure out a suitable encoding for BUFFER of LENGTH.
+ Returns: 0 = Binary
+ 1 = String possible
+ 2 = Token possible
+*/
+static int
+suitable_encoding (const unsigned char *buffer, size_t length)
+{
+ const unsigned char *s;
+ int maybe_token = 1;
+
+ if (!length)
+ return 1;
+
+ for (s=buffer; length; s++, length--)
+ {
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
+ && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
+ return 0; /*binary*/
+ if ( maybe_token
+ && !alphap (s) && !digitp (s) && !strchr (TOKEN_SPECIALS, *s))
+ maybe_token = 0;
+ }
+ s = buffer;
+ if ( maybe_token && !digitp (s) )
+ return 2;
+ return 1;
+}
+
+
+static int
+convert_to_hex (const unsigned char *src, size_t len, char *dest)
+{
+ int i;
+
+ if (dest)
+ {
+ *dest++ = '#';
+ for (i=0; i < len; i++, dest += 2 )
+ sprintf (dest, "%02X", src[i]);
+ *dest++ = '#';
+ }
+ return len*2+2;
+}
+
+static int
+convert_to_string (const unsigned char *s, size_t len, char *dest)
+{
+ if (dest)
+ {
+ char *p = dest;
+ *p++ = '\"';
+ for (; len; len--, s++ )
+ {
+ switch (*s)
+ {
+ case '\b': *p++ = '\\'; *p++ = 'b'; break;
+ case '\t': *p++ = '\\'; *p++ = 't'; break;
+ case '\v': *p++ = '\\'; *p++ = 'v'; break;
+ case '\n': *p++ = '\\'; *p++ = 'n'; break;
+ case '\f': *p++ = '\\'; *p++ = 'f'; break;
+ case '\r': *p++ = '\\'; *p++ = 'r'; break;
+ case '\"': *p++ = '\\'; *p++ = '\"'; break;
+ case '\'': *p++ = '\\'; *p++ = '\''; break;
+ case '\\': *p++ = '\\'; *p++ = '\\'; break;
+ default:
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
+ {
+ sprintf (p, "\\x%02x", *s);
+ p += 4;
+ }
+ else
+ *p++ = *s;
+ }
+ }
+ *p++ = '\"';
+ return p - dest;
+ }
+ else
+ {
+ int count = 2;
+ for (; len; len--, s++ )
+ {
+ switch (*s)
+ {
+ case '\b':
+ case '\t':
+ case '\v':
+ case '\n':
+ case '\f':
+ case '\r':
+ case '\"':
+ case '\'':
+ case '\\': count += 2; break;
+ default:
+ if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
+ count += 4;
+ else
+ count++;
+ }
+ }
+ return count;
+ }
+}
+
+
+
+static int
+convert_to_token (const unsigned char *src, size_t len, char *dest)
+{
+ if (dest)
+ memcpy (dest, src, len);
+ return len;
+}
+
+
+/****************
+ * 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, int mode,
+ 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];
+ size_t len = 0;
+ int i, indent = 0;
+
+ s = list? list->d : empty;
+ d = buffer;
+ while ( *s != ST_STOP )
+ {
+ switch ( *s )
+ {
+ case ST_OPEN:
+ s++;
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ if (indent)
+ len++;
+ len += indent;
+ }
+ len++;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ if (indent)
+ *d++ = '\n';
+ for (i=0; i < indent; i++)
+ *d++ = ' ';
+ }
+ *d++ = '(';
+ }
+ indent++;
+ break;
+ case ST_CLOSE:
+ s++;
+ len++;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = ')';
+ }
+ indent--;
+ if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
+ {
+ len++;
+ len += indent;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ *d++ = '\n';
+ for (i=0; i < indent; i++)
+ *d++ = ' ';
+ }
+ }
+ break;
+ case ST_DATA:
+ s++;
+ memcpy ( &n, s, sizeof n ); s += sizeof n;
+ if (mode == GCRYSEXP_FMT_ADVANCED)
+ {
+ 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;
+ }
+ len += nn;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ 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)
+ {
+ len++;
+ if (buffer)
+ {
+ if (len >= maxlength)
+ return 0;
+ *d++ = ' ';
+ }
+ }
+ }
+ else
+ {
+ sprintf (numbuf, "%u:", (unsigned int)n );
+ len += strlen (numbuf) + n;
+ if ( buffer )
+ {
+ if ( len >= maxlength )
+ return 0;
+ d = stpcpy ( d, numbuf );
+ memcpy ( d, s, n ); d += n;
+ }
+ }
+ s += n;
+ break;
+ default:
+ BUG ();
+ }
+ }
+ if ( mode != GCRYSEXP_FMT_CANON )
+ {
+ len++;
+ if (buffer)
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = '\n';
+ }
+ }
+ if (buffer)
+ {
+ if ( len >= maxlength )
+ return 0;
+ *d++ = 0; /* for convenience we make a C string */
+ }
+ else
+ len++; /* we need one byte more for this */
+
+ return len;
+}
+
+
+/* Scan a canonical encoded buffer with implicit length values and
+ return the actual length this S-expression uses. For a valid S-Exp
+ it should never return 0. If LENGTH is not zero, the maximum
+ length to scan is given - this can be used for syntax checks of
+ data passed from outside. errorcode and erroff may both be passed as
+ NULL. */
+size_t
+gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+ size_t *erroff, gcry_error_t *errcode)
+{
+ const unsigned char *p;
+ const unsigned char *disphint = NULL;
+ unsigned int datalen = 0;
+ size_t dummy_erroff;
+ gcry_error_t dummy_errcode;
+ size_t count = 0;
+ int level = 0;
+
+ if (!erroff)
+ erroff = &dummy_erroff;
+ if (!errcode)
+ errcode = &dummy_errcode;
+
+ *errcode = gcry_error (GPG_ERR_NO_ERROR);
+ *erroff = 0;
+ if (!buffer)
+ return 0;
+ if (*buffer != '(')
+ {
+ *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL);
+ return 0;
+ }
+
+ for (p=buffer; ; p++, count++ )
+ {
+ if (length && count >= length)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
+ return 0;
+ }
+
+ if (datalen)
+ {
+ if (*p == ':')
+ {
+ if (length && (count+datalen) >= length)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
+ return 0;
+ }
+ count += datalen;
+ p += datalen;
+ datalen = 0;
+ }
+ else if (digitp(p))
+ datalen = datalen*10 + atoi_1(p);
+ else
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC);
+ return 0;
+ }
+ }
+ else if (*p == '(')
+ {
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+ return 0;
+ }
+ level++;
+ }
+ else if (*p == ')')
+ { /* walk up */
+ if (!level)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN);
+ return 0;
+ }
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+ return 0;
+ }
+ if (!--level)
+ return ++count; /* ready */
+ }
+ else if (*p == '[')
+ {
+ if (disphint)
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH);
+ return 0;
+ }
+ disphint = p;
+ }
+ else if (*p == ']')
+ {
+ if ( !disphint )
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+ return 0;
+ }
+ disphint = NULL;
+ }
+ else if (digitp (p) )
+ {
+ if (*p == '0')
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX);
+ return 0;
+ }
+ datalen = atoi_1 (p);
+ }
+ else if (*p == '&' || *p == '\\')
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC);
+ return 0;
+ }
+ else
+ {
+ *erroff = count;
+ *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER);
+ return 0;
+ }
+ }
+}
diff --git a/plugins/MirOTR/Libgcrypt/src/stdmem.c b/plugins/MirOTR/Libgcrypt/src/stdmem.c new file mode 100644 index 0000000000..bb8adeabec --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/stdmem.c @@ -0,0 +1,235 @@ +/* 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 "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) + 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) + 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); +} + + diff --git a/plugins/MirOTR/Libgcrypt/src/stdmem.h b/plugins/MirOTR/Libgcrypt/src/stdmem.h new file mode 100644 index 0000000000..b476e7e501 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/stdmem.h @@ -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 */ diff --git a/plugins/MirOTR/Libgcrypt/src/types.h b/plugins/MirOTR/Libgcrypt/src/types.h new file mode 100644 index 0000000000..ee0a62bb91 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/types.h @@ -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*/ diff --git a/plugins/MirOTR/Libgcrypt/src/versioninfo.rc.in b/plugins/MirOTR/Libgcrypt/src/versioninfo.rc.in new file mode 100644 index 0000000000..e5e87e0b82 --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/versioninfo.rc.in @@ -0,0 +1,52 @@ +/* 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 © 2008 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 + diff --git a/plugins/MirOTR/Libgcrypt/src/visibility.c b/plugins/MirOTR/Libgcrypt/src/visibility.c new file mode 100644 index 0000000000..f187a65e7a --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/visibility.c @@ -0,0 +1,1453 @@ +/* visibility.c - Wrapper for all public functions. + * Copyright (C) 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 <stdarg.h> + +#define _GCRY_INCLUDED_BY_VISIBILITY_C +#include "g10lib.h" +#include "cipher-proto.h" + + + +const char * +gcry_strerror (gcry_error_t err) +{ + return _gcry_strerror (err); +} + +const char * +gcry_strsource (gcry_error_t err) +{ + return _gcry_strsource (err); +} + +gcry_err_code_t +gcry_err_code_from_errno (int err) +{ + return _gcry_err_code_from_errno (err); +} + +int +gcry_err_code_to_errno (gcry_err_code_t code) +{ + return _gcry_err_code_to_errno (code); +} + +gcry_error_t +gcry_err_make_from_errno (gcry_err_source_t source, int err) +{ + return _gcry_err_make_from_errno (source, err); +} + +gcry_err_code_t +gcry_error_from_errno (int err) +{ + return _gcry_error_from_errno (err); +} + +const char * +gcry_check_version (const char *req_version) +{ + return _gcry_check_version (req_version); +} + +gcry_error_t +gcry_control (enum gcry_ctl_cmds cmd, ...) +{ + gcry_error_t err; + va_list arg_ptr; + + va_start (arg_ptr, cmd); + err = _gcry_vcontrol (cmd, arg_ptr); + va_end(arg_ptr); + return err; +} + +gcry_error_t +gcry_sexp_new (gcry_sexp_t *retsexp, + const void *buffer, size_t length, + int autodetect) +{ + return _gcry_sexp_new (retsexp, buffer, length, autodetect); +} + +gcry_error_t +gcry_sexp_create (gcry_sexp_t *retsexp, + void *buffer, size_t length, + int autodetect, void (*freefnc) (void *)) +{ + return _gcry_sexp_create (retsexp, buffer, length, + autodetect, freefnc); +} + +gcry_error_t +gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, + const char *buffer, size_t length) +{ + return _gcry_sexp_sscan (retsexp, erroff, buffer, length); +} + +gcry_error_t +gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, + const char *format, ...) +{ + gcry_error_t err; + va_list arg_ptr; + + va_start (arg_ptr, format); + err = _gcry_sexp_vbuild (retsexp, erroff, format, arg_ptr); + va_end (arg_ptr); + return err; +} + +gcry_error_t +gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff, + const char *format, void **arg_list) +{ + return _gcry_sexp_build_array (retsexp, erroff, format, arg_list); +} + +void +gcry_sexp_release (gcry_sexp_t sexp) +{ + _gcry_sexp_release (sexp); +} + +size_t +gcry_sexp_canon_len (const unsigned char *buffer, size_t length, + size_t *erroff, gcry_error_t *errcode) +{ + return _gcry_sexp_canon_len (buffer, length, erroff, errcode); +} + +size_t +gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer, size_t maxlength) +{ + return _gcry_sexp_sprint (sexp, mode, buffer, maxlength); +} + +void +gcry_sexp_dump (const gcry_sexp_t a) +{ + _gcry_sexp_dump (a); +} + +gcry_sexp_t +gcry_sexp_cons (const gcry_sexp_t a, const gcry_sexp_t b) +{ + return _gcry_sexp_cons (a, b); +} + +gcry_sexp_t +gcry_sexp_alist (const gcry_sexp_t *array) +{ + return _gcry_sexp_alist (array); +} + +gcry_sexp_t +gcry_sexp_vlist (const gcry_sexp_t a, ...) +{ + /* This is not yet implemented in sexp.c. */ + (void)a; + BUG (); + return NULL; +} + +gcry_sexp_t +gcry_sexp_append (const gcry_sexp_t a, const gcry_sexp_t n) +{ + return _gcry_sexp_append (a, n); +} + +gcry_sexp_t +gcry_sexp_prepend (const gcry_sexp_t a, const gcry_sexp_t n) +{ + return _gcry_sexp_prepend (a, n); +} + + +gcry_sexp_t +gcry_sexp_find_token (gcry_sexp_t list, const char *tok, size_t toklen) +{ + return _gcry_sexp_find_token (list, tok, toklen); +} + +int +gcry_sexp_length (const gcry_sexp_t list) +{ + return _gcry_sexp_length (list); +} + +gcry_sexp_t +gcry_sexp_nth (const gcry_sexp_t list, int number) +{ + return _gcry_sexp_nth (list, number); +} + +gcry_sexp_t +gcry_sexp_car (const gcry_sexp_t list) +{ + return _gcry_sexp_car (list); +} + +gcry_sexp_t +gcry_sexp_cdr (const gcry_sexp_t list) +{ + return _gcry_sexp_cdr (list); +} + +gcry_sexp_t +gcry_sexp_cadr (const gcry_sexp_t list) +{ + return _gcry_sexp_cadr (list); +} + +const char * +gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen) +{ + return _gcry_sexp_nth_data (list, number, datalen); +} + +char * +gcry_sexp_nth_string (gcry_sexp_t list, int number) +{ + return _gcry_sexp_nth_string (list, number); +} + +gcry_mpi_t +gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt) +{ + return _gcry_sexp_nth_mpi (list, number, mpifmt); +} + +gcry_mpi_t +gcry_mpi_new (unsigned int nbits) +{ + return _gcry_mpi_new (nbits); +} + +gcry_mpi_t +gcry_mpi_snew (unsigned int nbits) +{ + return _gcry_mpi_snew (nbits); +} + +void +gcry_mpi_release (gcry_mpi_t a) +{ + _gcry_mpi_release (a); +} + +gcry_mpi_t +gcry_mpi_copy (const gcry_mpi_t a) +{ + return _gcry_mpi_copy (a); +} + +gcry_mpi_t +gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u) +{ + return _gcry_mpi_set (w, u); +} + +gcry_mpi_t +gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u) +{ + return _gcry_mpi_set_ui (w, u); +} + +void +gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b) +{ + _gcry_mpi_swap (a, b); +} + +int +gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v) +{ + return _gcry_mpi_cmp (u, v); +} + +int +gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v) +{ + return _gcry_mpi_cmp_ui (u, v); +} + +gcry_error_t +gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format, + const void *buffer, size_t buflen, + size_t *nscanned) +{ + return _gcry_mpi_scan (ret_mpi, format, buffer, buflen, nscanned); +} + +gcry_error_t +gcry_mpi_print (enum gcry_mpi_format format, + unsigned char *buffer, size_t buflen, + size_t *nwritten, + const gcry_mpi_t a) +{ + return _gcry_mpi_print (format, buffer, buflen, nwritten, a); +} + +gcry_error_t +gcry_mpi_aprint (enum gcry_mpi_format format, + unsigned char **buffer, size_t *nwritten, + const gcry_mpi_t a) +{ + return _gcry_mpi_aprint (format, buffer, nwritten, a); +} + +void +gcry_mpi_dump (const gcry_mpi_t a) +{ + _gcry_mpi_dump (a); +} + +void +gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) +{ + _gcry_mpi_add (w, u, v); +} + +void +gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v) +{ + _gcry_mpi_add_ui (w, u, v); +} + +void +gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) +{ + _gcry_mpi_addm (w, u, v, m); +} + +void +gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) +{ + _gcry_mpi_sub (w, u, v); +} + +void +gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) +{ + _gcry_mpi_sub_ui (w, u, v); +} + +void +gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) +{ + _gcry_mpi_subm (w, u, v, m); +} + +void +gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v) +{ + _gcry_mpi_mul (w, u, v); +} + +void +gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ) +{ + _gcry_mpi_mul_ui (w, u, v); +} + +void +gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) +{ + _gcry_mpi_mulm (w, u, v, m); +} + +void +gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt) +{ + _gcry_mpi_mul_2exp (w, u, cnt); +} + +void +gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, + gcry_mpi_t dividend, gcry_mpi_t divisor, int round) +{ + _gcry_mpi_div (q, r, dividend, divisor, round); +} + +void +gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor) +{ + _gcry_mpi_mod (r, dividend, divisor); +} + +void +gcry_mpi_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e, + const gcry_mpi_t m) +{ + _gcry_mpi_powm (w, b, e, m); +} + +int +gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b) +{ + return _gcry_mpi_gcd (g, a, b); +} + +int +gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m) +{ + return _gcry_mpi_invm (x, a, m); +} + + +unsigned int +gcry_mpi_get_nbits (gcry_mpi_t a) +{ + return _gcry_mpi_get_nbits (a); +} + +int +gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n) +{ + return _gcry_mpi_test_bit (a, n); +} + +void +gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n) +{ + _gcry_mpi_set_bit (a, n); +} + +void +gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n) +{ + _gcry_mpi_clear_bit (a, n); +} + +void +gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n) +{ + _gcry_mpi_set_highbit (a, n); +} + +void +gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n) +{ + _gcry_mpi_clear_highbit (a, n); +} + +void +gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n) +{ + _gcry_mpi_rshift (x, a, n); +} + +void +gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n) +{ + _gcry_mpi_lshift (x, a, n); +} + +gcry_mpi_t +gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits) +{ + return _gcry_mpi_set_opaque (a, p, nbits); +} + +void * +gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits) +{ + return _gcry_mpi_get_opaque (a, nbits); +} + +void +gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) +{ + _gcry_mpi_set_flag (a, flag); +} + +void +gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) +{ + _gcry_mpi_clear_flag (a, flag); +} + +int +gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag) +{ + return _gcry_mpi_get_flag (a, flag); +} + +gcry_error_t +gcry_cipher_open (gcry_cipher_hd_t *handle, + int algo, int mode, unsigned int flags) +{ + if (!fips_is_operational ()) + { + *handle = NULL; + return gpg_error (fips_not_operational ()); + } + + return _gcry_cipher_open (handle, algo, mode, flags); +} + +void +gcry_cipher_close (gcry_cipher_hd_t h) +{ + _gcry_cipher_close (h); +} + +gcry_error_t +gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + + return _gcry_cipher_setkey (hd, key, keylen); +} + +gcry_error_t +gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + + return _gcry_cipher_setiv (hd, iv, ivlen); +} + +gpg_error_t +gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + + return _gcry_cipher_setctr (hd, ctr, ctrlen); +} + + +gcry_error_t +gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + + return _gcry_cipher_ctl (h, cmd, buffer, buflen); +} + +gcry_error_t +gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, size_t *nbytes) +{ + return _gcry_cipher_info (h, what, buffer, nbytes); +} + +gcry_error_t +gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + + return _gcry_cipher_algo_info (algo, what, buffer, nbytes); +} + +const char * +gcry_cipher_algo_name (int algorithm) +{ + return _gcry_cipher_algo_name (algorithm); +} + +int +gcry_cipher_map_name (const char *name) +{ + return _gcry_cipher_map_name (name); +} + +int +gcry_cipher_mode_from_oid (const char *string) +{ + return _gcry_cipher_mode_from_oid (string); +} + +gcry_error_t +gcry_cipher_encrypt (gcry_cipher_hd_t h, + void *out, size_t outsize, + const void *in, size_t inlen) +{ + if (!fips_is_operational ()) + { + /* Make sure that the plaintext will never make it to OUT. */ + if (out) + memset (out, 0x42, outsize); + return gpg_error (fips_not_operational ()); + } + + return _gcry_cipher_encrypt (h, out, outsize, in, inlen); +} + +gcry_error_t +gcry_cipher_decrypt (gcry_cipher_hd_t h, + void *out, size_t outsize, + const void *in, size_t inlen) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + + return _gcry_cipher_decrypt (h, out, outsize, in, inlen); +} + +size_t +gcry_cipher_get_algo_keylen (int algo) +{ + return _gcry_cipher_get_algo_keylen (algo); +} + +size_t +gcry_cipher_get_algo_blklen (int algo) +{ + return _gcry_cipher_get_algo_blklen (algo); +} + +gcry_error_t +gcry_cipher_list (int *list, int *list_length) +{ + return _gcry_cipher_list (list, list_length); +} + +gcry_error_t +gcry_pk_encrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t pkey) +{ + if (!fips_is_operational ()) + { + *result = NULL; + return gpg_error (fips_not_operational ()); + } + return _gcry_pk_encrypt (result, data, pkey); +} + +gcry_error_t +gcry_pk_decrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey) +{ + if (!fips_is_operational ()) + { + *result = NULL; + return gpg_error (fips_not_operational ()); + } + return _gcry_pk_decrypt (result, data, skey); +} + +gcry_error_t +gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey) +{ + if (!fips_is_operational ()) + { + *result = NULL; + return gpg_error (fips_not_operational ()); + } + return _gcry_pk_sign (result, data, skey); +} + +gcry_error_t +gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + return _gcry_pk_verify (sigval, data, pkey); +} + +gcry_error_t +gcry_pk_testkey (gcry_sexp_t key) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + return _gcry_pk_testkey (key); +} + +gcry_error_t +gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms) +{ + if (!fips_is_operational ()) + { + *r_key = NULL; + return gpg_error (fips_not_operational ()); + } + return _gcry_pk_genkey (r_key, s_parms); +} + +gcry_error_t +gcry_pk_ctl (int cmd, void *buffer, size_t buflen) +{ + return _gcry_pk_ctl (cmd, buffer, buflen); +} + +gcry_error_t +gcry_pk_algo_info (int algo, int what, void *buffer, size_t *nbytes) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + + return _gcry_pk_algo_info (algo, what, buffer, nbytes); +} + +const char * +gcry_pk_algo_name (int algorithm) +{ + return _gcry_pk_algo_name (algorithm); +} + +int +gcry_pk_map_name (const char *name) +{ + return _gcry_pk_map_name (name); +} + +unsigned int +gcry_pk_get_nbits (gcry_sexp_t key) +{ + if (!fips_is_operational ()) + { + (void)fips_not_operational (); + return 0; + } + + return _gcry_pk_get_nbits (key); +} + +unsigned char * +gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array) +{ + if (!fips_is_operational ()) + { + (void)fips_not_operational (); + return NULL; + } + return _gcry_pk_get_keygrip (key, array); +} + +gcry_error_t +gcry_pk_list (int *list, int *list_length) +{ + return _gcry_pk_list (list, list_length); +} + +gcry_error_t +gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags) +{ + if (!fips_is_operational ()) + { + *h = NULL; + return gpg_error (fips_not_operational ()); + } + + return _gcry_md_open (h, algo, flags); +} + +void +gcry_md_close (gcry_md_hd_t hd) +{ + _gcry_md_close (hd); +} + +gcry_error_t +gcry_md_enable (gcry_md_hd_t hd, int algo) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + return _gcry_md_enable (hd, algo); +} + +gcry_error_t +gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd) +{ + if (!fips_is_operational ()) + { + *bhd = NULL; + return gpg_error (fips_not_operational ()); + } + return _gcry_md_copy (bhd, ahd); +} + +void +gcry_md_reset (gcry_md_hd_t hd) +{ + _gcry_md_reset (hd); +} + +gcry_error_t +gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + return _gcry_md_ctl (hd, cmd, buffer, buflen); +} + +void +gcry_md_write (gcry_md_hd_t hd, const void *buffer, size_t length) +{ + if (!fips_is_operational ()) + { + (void)fips_not_operational (); + return; + } + _gcry_md_write (hd, buffer, length); +} + +unsigned char * +gcry_md_read (gcry_md_hd_t hd, int algo) +{ + return _gcry_md_read (hd, algo); +} + +void +gcry_md_hash_buffer (int algo, void *digest, + const void *buffer, size_t length) +{ + if (!fips_is_operational ()) + { + (void)fips_not_operational (); + fips_signal_error ("called in non-operational state"); + } + _gcry_md_hash_buffer (algo, digest, buffer, length); +} + +int +gcry_md_get_algo (gcry_md_hd_t hd) +{ + if (!fips_is_operational ()) + { + (void)fips_not_operational (); + fips_signal_error ("used in non-operational state"); + return 0; + } + return _gcry_md_get_algo (hd); +} + +unsigned int +gcry_md_get_algo_dlen (int algo) +{ + return _gcry_md_get_algo_dlen (algo); +} + +int +gcry_md_is_enabled (gcry_md_hd_t a, int algo) +{ + if (!fips_is_operational ()) + { + (void)fips_not_operational (); + return 0; + } + + return _gcry_md_is_enabled (a, algo); +} + +int +gcry_md_is_secure (gcry_md_hd_t a) +{ + return _gcry_md_is_secure (a); +} + +gcry_error_t +gcry_md_info (gcry_md_hd_t h, int what, void *buffer, size_t *nbytes) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + + return _gcry_md_info (h, what, buffer, nbytes); +} + +gcry_error_t +gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes) +{ + return _gcry_md_algo_info (algo, what, buffer, nbytes); +} + +const char * +gcry_md_algo_name (int algo) +{ + return _gcry_md_algo_name (algo); +} + +int +gcry_md_map_name (const char* name) +{ + return _gcry_md_map_name (name); +} + +gcry_error_t +gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + return _gcry_md_setkey (hd, key, keylen); +} + +void +gcry_md_debug (gcry_md_hd_t hd, const char *suffix) +{ + _gcry_md_debug (hd, suffix); +} + +gcry_error_t +gcry_md_list (int *list, int *list_length) +{ + return _gcry_md_list (list, list_length); +} + +gcry_error_t +gcry_ac_data_new (gcry_ac_data_t *data) +{ + return _gcry_ac_data_new (data); +} + +void +gcry_ac_data_destroy (gcry_ac_data_t data) +{ + _gcry_ac_data_destroy (data); +} + +gcry_error_t +gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data) +{ + return _gcry_ac_data_copy (data_cp, data); +} + +unsigned int +gcry_ac_data_length (gcry_ac_data_t data) +{ + return _gcry_ac_data_length (data); +} + +void +gcry_ac_data_clear (gcry_ac_data_t data) +{ + _gcry_ac_data_clear (data); +} + +gcry_error_t +gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags, + const char *name, gcry_mpi_t mpi) +{ + return _gcry_ac_data_set (data, flags, name, mpi); +} + +gcry_error_t +gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags, + const char *name, gcry_mpi_t *mpi) +{ + return _gcry_ac_data_get_name (data, flags, name, mpi); +} + +gcry_error_t +gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags, + unsigned int idx, const char **name, gcry_mpi_t *mpi) +{ + return _gcry_ac_data_get_index (data, flags, idx, name, mpi); +} + +gcry_error_t +gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, + const char **identifiers) +{ + return _gcry_ac_data_to_sexp (data, sexp, identifiers); +} + +gcry_error_t +gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp, + const char **identifiers) +{ + return _gcry_ac_data_from_sexp (data, sexp, identifiers); +} + +void +gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode, + gcry_ac_io_type_t type, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, type); + _gcry_ac_io_init_va (ac_io, mode, type, arg_ptr); + va_end (arg_ptr); +} + +void +gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode, + gcry_ac_io_type_t type, va_list ap) +{ + _gcry_ac_io_init_va (ac_io, mode, type, ap); +} + +gcry_error_t +gcry_ac_open (gcry_ac_handle_t *handle, + gcry_ac_id_t algorithm, unsigned int flags) +{ + return _gcry_ac_open (handle, algorithm, flags); +} + +void +gcry_ac_close (gcry_ac_handle_t handle) +{ + _gcry_ac_close (handle); +} + +gcry_error_t +gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle, + gcry_ac_key_type_t type, gcry_ac_data_t data) +{ + return _gcry_ac_key_init (key, handle, type, data); +} + +gcry_error_t +gcry_ac_key_pair_generate (gcry_ac_handle_t handle, + unsigned int nbits, void *spec, + gcry_ac_key_pair_t *key_pair, + gcry_mpi_t **miscdata) +{ + return _gcry_ac_key_pair_generate ( handle, nbits, spec, key_pair, miscdata); +} + +gcry_ac_key_t +gcry_ac_key_pair_extract (gcry_ac_key_pair_t keypair, gcry_ac_key_type_t which) +{ + return _gcry_ac_key_pair_extract (keypair, which); +} + +gcry_ac_data_t +gcry_ac_key_data_get (gcry_ac_key_t key) +{ + return _gcry_ac_key_data_get (key); +} + +gcry_error_t +gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key) +{ + return _gcry_ac_key_test (handle, key); +} + +gcry_error_t +gcry_ac_key_get_nbits (gcry_ac_handle_t handle, + gcry_ac_key_t key, unsigned int *nbits) +{ + return _gcry_ac_key_get_nbits (handle, key, nbits); +} + +gcry_error_t +gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key, + unsigned char *key_grip) +{ + return _gcry_ac_key_get_grip (handle, key, key_grip); +} + +void +gcry_ac_key_destroy (gcry_ac_key_t key) +{ + _gcry_ac_key_destroy (key); +} + +void +gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair) +{ + _gcry_ac_key_pair_destroy (key_pair); +} + +gcry_error_t +gcry_ac_data_encode (gcry_ac_em_t method, unsigned int flags, void *options, + gcry_ac_io_t *io_read, gcry_ac_io_t *io_write) +{ + return _gcry_ac_data_encode (method, flags, options, io_read, io_write); +} + +gcry_error_t +gcry_ac_data_decode (gcry_ac_em_t method, unsigned int flags, void *options, + gcry_ac_io_t *io_read, gcry_ac_io_t *io_write) +{ + return _gcry_ac_data_decode (method, flags, options, io_read, io_write); +} + +gcry_error_t +gcry_ac_data_encrypt (gcry_ac_handle_t handle, + unsigned int flags, + gcry_ac_key_t key, + gcry_mpi_t data_plain, + gcry_ac_data_t *data_encrypted) +{ + return _gcry_ac_data_encrypt (handle, flags, key, + data_plain, data_encrypted); +} + +gcry_error_t +gcry_ac_data_decrypt (gcry_ac_handle_t handle, + unsigned int flags, + gcry_ac_key_t key, + gcry_mpi_t *data_plain, + gcry_ac_data_t data_encrypted) +{ + return _gcry_ac_data_decrypt (handle, flags, key, + data_plain, data_encrypted); +} + +gcry_error_t +gcry_ac_data_sign (gcry_ac_handle_t handle, + gcry_ac_key_t key, + gcry_mpi_t data, + gcry_ac_data_t *data_signature) +{ + return _gcry_ac_data_sign (handle, key, data, data_signature); +} + +gcry_error_t +gcry_ac_data_verify (gcry_ac_handle_t handle, + gcry_ac_key_t key, + gcry_mpi_t data, + gcry_ac_data_t data_signature) +{ + return _gcry_ac_data_verify (handle, key, data, data_signature); +} + +gcry_error_t +gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_message, + gcry_ac_io_t *io_cipher) +{ + return _gcry_ac_data_encrypt_scheme (handle, scheme, flags, opts, key, + io_message, io_cipher); +} + +gcry_error_t +gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_cipher, + gcry_ac_io_t *io_message) +{ + return _gcry_ac_data_decrypt_scheme (handle, scheme, flags, opts, key, + io_cipher, io_message); +} + +gcry_error_t +gcry_ac_data_sign_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_message, + gcry_ac_io_t *io_signature) +{ + return _gcry_ac_data_sign_scheme (handle, scheme, flags, opts, key, + io_message, io_signature); +} + +gcry_error_t +gcry_ac_data_verify_scheme (gcry_ac_handle_t handle, + gcry_ac_scheme_t scheme, + unsigned int flags, void *opts, + gcry_ac_key_t key, + gcry_ac_io_t *io_message, + gcry_ac_io_t *io_signature) +{ + return _gcry_ac_data_verify_scheme (handle, scheme, flags, opts, key, + io_message, io_signature); +} + +gcry_error_t +gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name) +{ + /* This function is deprecated. We implement it in terms of the + suggested replacement. */ + const char *tmp = _gcry_pk_algo_name (algorithm); + if (!*tmp) + return gcry_error (GPG_ERR_PUBKEY_ALGO); + *name = tmp; + return 0; +} + +gcry_error_t +gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm) +{ + /* This function is deprecated. We implement it in terms of the + suggested replacement. */ + int algo = _gcry_pk_map_name (name); + if (!algo) + return gcry_error (GPG_ERR_PUBKEY_ALGO); + *algorithm = algo; + return 0; +} + +void +gcry_randomize (void *buffer, size_t length, enum gcry_random_level level) +{ + if (!fips_is_operational ()) + { + (void)fips_not_operational (); + fips_signal_fatal_error ("called in non-operational state"); + fips_noreturn (); + } + _gcry_randomize (buffer, length, level); +} + +gcry_error_t +gcry_random_add_bytes (const void *buffer, size_t length, int quality) +{ + if (!fips_is_operational ()) + return gpg_error (fips_not_operational ()); + return _gcry_random_add_bytes (buffer, length, quality); +} + +void * +gcry_random_bytes (size_t nbytes, enum gcry_random_level level) +{ + if (!fips_is_operational ()) + { + (void)fips_not_operational (); + fips_signal_fatal_error ("called in non-operational state"); + fips_noreturn (); + } + + return _gcry_random_bytes (nbytes,level); +} + +void * +gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level) +{ + if (!fips_is_operational ()) + { + (void)fips_not_operational (); + fips_signal_fatal_error ("called in non-operational state"); + fips_noreturn (); + } + + return _gcry_random_bytes_secure (nbytes, level); +} + +void +gcry_mpi_randomize (gcry_mpi_t w, + unsigned int nbits, enum gcry_random_level level) +{ + _gcry_mpi_randomize (w, nbits, level); +} + +void +gcry_create_nonce (void *buffer, size_t length) +{ + if (!fips_is_operational ()) + { + (void)fips_not_operational (); + fips_signal_fatal_error ("called in non-operational state"); + fips_noreturn (); + } + _gcry_create_nonce (buffer, length); +} + +gcry_error_t +gcry_prime_generate (gcry_mpi_t *prime, + unsigned int prime_bits, + unsigned int factor_bits, + gcry_mpi_t **factors, + gcry_prime_check_func_t cb_func, + void *cb_arg, + gcry_random_level_t random_level, + unsigned int flags) +{ + return _gcry_prime_generate (prime, prime_bits, factor_bits, factors, + cb_func, cb_arg, random_level, flags); +} + +gcry_error_t +gcry_prime_group_generator (gcry_mpi_t *r_g, + gcry_mpi_t prime, gcry_mpi_t *factors, + gcry_mpi_t start_g) +{ + return _gcry_prime_group_generator (r_g, prime, factors, start_g); +} + +void +gcry_prime_release_factors (gcry_mpi_t *factors) +{ + _gcry_prime_release_factors (factors); +} + +gcry_error_t +gcry_prime_check (gcry_mpi_t x, unsigned int flags) +{ + return _gcry_prime_check (x, flags); +} + +void +gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data) +{ + _gcry_set_progress_handler (cb, cb_data); +} + +void +gcry_set_allocation_handler (gcry_handler_alloc_t func_alloc, + gcry_handler_alloc_t func_alloc_secure, + gcry_handler_secure_check_t func_secure_check, + gcry_handler_realloc_t func_realloc, + gcry_handler_free_t func_free) +{ + _gcry_set_allocation_handler (func_alloc, func_alloc_secure, + func_secure_check, func_realloc, func_free); +} + +void +gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque) +{ + _gcry_set_outofcore_handler (h, opaque); +} + +void +gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque) +{ + _gcry_set_fatalerror_handler (fnc, opaque); +} + +void +gcry_set_log_handler (gcry_handler_log_t f, void *opaque) +{ + _gcry_set_log_handler (f, opaque); +} + +void +gcry_set_gettext_handler (const char *(*f)(const char*)) +{ + _gcry_set_gettext_handler (f); +} + +void * +gcry_malloc (size_t n) +{ + return _gcry_malloc (n); +} + +void * +gcry_calloc (size_t n, size_t m) +{ + return _gcry_calloc (n, m); +} + +void * +gcry_malloc_secure (size_t n) +{ + return _gcry_malloc_secure (n); +} + +void * +gcry_calloc_secure (size_t n, size_t m) +{ + return _gcry_calloc_secure (n,m); +} + +void * +gcry_realloc (void *a, size_t n) +{ + return _gcry_realloc (a, n); +} + +char * +gcry_strdup (const char *string) +{ + return _gcry_strdup (string); +} + +void * +gcry_xmalloc (size_t n) +{ + return _gcry_xmalloc (n); +} + +void * +gcry_xcalloc (size_t n, size_t m) +{ + return _gcry_xcalloc (n, m); +} + +void * +gcry_xmalloc_secure (size_t n) +{ + return _gcry_xmalloc_secure (n); +} + +void * +gcry_xcalloc_secure (size_t n, size_t m) +{ + return _gcry_xcalloc_secure (n, m); +} + +void * +gcry_xrealloc (void *a, size_t n) +{ + return _gcry_xrealloc (a, n); +} + +char * +gcry_xstrdup (const char *a) +{ + return _gcry_xstrdup (a); +} + +void +gcry_free (void *a) +{ + _gcry_free (a); +} + +int +gcry_is_secure (const void *a) +{ + return _gcry_is_secure (a); +} + + +gcry_error_t +gcry_cipher_register (gcry_cipher_spec_t *cipher, int *algorithm_id, + gcry_module_t *module) +{ + return _gcry_cipher_register (cipher, NULL, algorithm_id, module); +} + +void +gcry_cipher_unregister (gcry_module_t module) +{ + _gcry_cipher_unregister (module); +} + +gcry_error_t +gcry_pk_register (gcry_pk_spec_t *pubkey, unsigned int *algorithm_id, + gcry_module_t *module) +{ + return _gcry_pk_register (pubkey, NULL, algorithm_id, module); +} + +void +gcry_pk_unregister (gcry_module_t module) +{ + _gcry_pk_unregister (module); +} + +gcry_error_t +gcry_md_register (gcry_md_spec_t *digest, unsigned int *algorithm_id, + gcry_module_t *module) +{ + return _gcry_md_register (digest, NULL, algorithm_id, module); +} + +void +gcry_md_unregister (gcry_module_t module) +{ + _gcry_md_unregister (module); +} diff --git a/plugins/MirOTR/Libgcrypt/src/visibility.h b/plugins/MirOTR/Libgcrypt/src/visibility.h new file mode 100644 index 0000000000..a11e5474fd --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/src/visibility.h @@ -0,0 +1,704 @@ +/* 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_list _gcry_md_list +#define gcry_md_map_name _gcry_md_map_name +#define gcry_md_open _gcry_md_open +#define gcry_md_read _gcry_md_read +/* gcry_md_register and _gcry_md_register differ. */ +#define gcry_md_unregister _gcry_md_unregister +#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_list _gcry_cipher_list +#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 +/* gcry_cipher_register and _gcry_cipher_register differ. */ +#define gcry_cipher_unregister _gcry_cipher_unregister + +#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_nbits _gcry_pk_get_nbits +#define gcry_pk_list _gcry_pk_list +#define gcry_pk_map_name _gcry_pk_map_name +/* gcry_pk_register and _gcry_pk_register differ. */ +#define gcry_pk_unregister _gcry_pk_unregister +#define gcry_pk_sign _gcry_pk_sign +#define gcry_pk_testkey _gcry_pk_testkey +#define gcry_pk_verify _gcry_pk_verify + +#define gcry_ac_data_new _gcry_ac_data_new +#define gcry_ac_data_destroy _gcry_ac_data_destroy +#define gcry_ac_data_copy _gcry_ac_data_copy +#define gcry_ac_data_length _gcry_ac_data_length +#define gcry_ac_data_clear _gcry_ac_data_clear +#define gcry_ac_data_set _gcry_ac_data_set +#define gcry_ac_data_get_name _gcry_ac_data_get_name +#define gcry_ac_data_get_index _gcry_ac_data_get_index +#define gcry_ac_open _gcry_ac_open +#define gcry_ac_close _gcry_ac_close +#define gcry_ac_key_init _gcry_ac_key_init +#define gcry_ac_key_pair_generate _gcry_ac_key_pair_generate +#define gcry_ac_key_pair_extract _gcry_ac_key_pair_extract +#define gcry_ac_key_data_get _gcry_ac_key_data_get +#define gcry_ac_key_test _gcry_ac_key_test +#define gcry_ac_key_get_nbits _gcry_ac_key_get_nbits +#define gcry_ac_key_get_grip _gcry_ac_key_get_grip +#define gcry_ac_key_destroy _gcry_ac_key_destroy +#define gcry_ac_key_pair_destroy _gcry_ac_key_pair_destroy +#define gcry_ac_data_encrypt _gcry_ac_data_encrypt +#define gcry_ac_data_decrypt _gcry_ac_data_decrypt +#define gcry_ac_data_sign _gcry_ac_data_sign +#define gcry_ac_data_verify _gcry_ac_data_verify +#define gcry_ac_id_to_name _gcry_ac_id_to_name +#define gcry_ac_name_to_id _gcry_ac_name_to_id +#define gcry_ac_data_encode _gcry_ac_data_encode +#define gcry_ac_data_decode _gcry_ac_data_decode +#define gcry_ac_mpi_to_os _gcry_ac_mpi_to_os +#define gcry_ac_mpi_to_os_alloc _gcry_ac_mpi_to_os_alloc +#define gcry_ac_os_to_mpi _gcry_ac_os_to_mpi +#define gcry_ac_data_encrypt_scheme _gcry_ac_data_encrypt_scheme +#define gcry_ac_data_decrypt_scheme _gcry_ac_data_decrypt_scheme +#define gcry_ac_data_sign_scheme _gcry_ac_data_sign_scheme +#define gcry_ac_data_verify_scheme _gcry_ac_data_verify_scheme +#define gcry_ac_data_to_sexp _gcry_ac_data_to_sexp +#define gcry_ac_data_from_sexp _gcry_ac_data_from_sexp +#define gcry_ac_io_init _gcry_ac_io_init +#define gcry_ac_io_init_va _gcry_ac_io_init_va + +#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" + gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name); + gcry_error_t gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm); +#else +# include "gcrypt.h" +#endif + +/* 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); +void gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n); +gcry_error_t gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, + size_t *os_n); +void gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n); + + + +/* 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_list +#undef gcry_md_map_name +#undef gcry_md_open +#undef gcry_md_read +/* gcry_md_register is not anymore a macro. */ +#undef gcry_md_unregister +#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_list +#undef gcry_cipher_map_name +#undef gcry_cipher_mode_from_oid +#undef gcry_cipher_open +/* gcry_cipher_register is not anymore a macro. */ +#undef gcry_cipher_unregister + +#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_nbits +#undef gcry_pk_list +#undef gcry_pk_map_name +/* gcry_pk_register is not anymore a macro. */ +#undef gcry_pk_unregister +#undef gcry_pk_sign +#undef gcry_pk_testkey +#undef gcry_pk_verify + +#undef gcry_ac_data_new +#undef gcry_ac_data_destroy +#undef gcry_ac_data_copy +#undef gcry_ac_data_length +#undef gcry_ac_data_clear +#undef gcry_ac_data_set +#undef gcry_ac_data_get_name +#undef gcry_ac_data_get_index +#undef gcry_ac_open +#undef gcry_ac_close +#undef gcry_ac_key_init +#undef gcry_ac_key_pair_generate +#undef gcry_ac_key_pair_extract +#undef gcry_ac_key_data_get +#undef gcry_ac_key_test +#undef gcry_ac_key_get_nbits +#undef gcry_ac_key_get_grip +#undef gcry_ac_key_destroy +#undef gcry_ac_key_pair_destroy +#undef gcry_ac_data_encrypt +#undef gcry_ac_data_decrypt +#undef gcry_ac_data_sign +#undef gcry_ac_data_verify +#undef gcry_ac_id_to_name +#undef gcry_ac_name_to_id +#undef gcry_ac_data_encode +#undef gcry_ac_data_decode +#undef gcry_ac_mpi_to_os +#undef gcry_ac_mpi_to_os_alloc +#undef gcry_ac_os_to_mpi +#undef gcry_ac_data_encrypt_scheme +#undef gcry_ac_data_decrypt_scheme +#undef gcry_ac_data_sign_scheme +#undef gcry_ac_data_verify_scheme +#undef gcry_ac_data_to_sexp +#undef gcry_ac_data_from_sexp +#undef gcry_ac_io_init +#undef gcry_ac_io_init_va + +#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_list) +MARK_VISIBLE (gcry_md_map_name) +MARK_VISIBLE (gcry_md_open) +MARK_VISIBLE (gcry_md_read) +MARK_VISIBLEX(gcry_md_register) +MARK_VISIBLE (gcry_md_reset) +MARK_VISIBLE (gcry_md_setkey) +MARK_VISIBLE (gcry_md_unregister) +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_list) +MARK_VISIBLE (gcry_cipher_map_name) +MARK_VISIBLE (gcry_cipher_mode_from_oid) +MARK_VISIBLE (gcry_cipher_open) +MARK_VISIBLEX(gcry_cipher_register) +MARK_VISIBLE (gcry_cipher_unregister) + +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_nbits) +MARK_VISIBLE (gcry_pk_list) +MARK_VISIBLE (gcry_pk_map_name) +MARK_VISIBLEX(gcry_pk_register) +MARK_VISIBLE (gcry_pk_sign) +MARK_VISIBLE (gcry_pk_testkey) +MARK_VISIBLE (gcry_pk_unregister) +MARK_VISIBLE (gcry_pk_verify) + +MARK_VISIBLE (gcry_ac_data_new) +MARK_VISIBLE (gcry_ac_data_destroy) +MARK_VISIBLE (gcry_ac_data_copy) +MARK_VISIBLE (gcry_ac_data_length) +MARK_VISIBLE (gcry_ac_data_clear) +MARK_VISIBLE (gcry_ac_data_set) +MARK_VISIBLE (gcry_ac_data_get_name) +MARK_VISIBLE (gcry_ac_data_get_index) +MARK_VISIBLE (gcry_ac_open) +MARK_VISIBLE (gcry_ac_close) +MARK_VISIBLE (gcry_ac_key_init) +MARK_VISIBLE (gcry_ac_key_pair_generate) +MARK_VISIBLE (gcry_ac_key_pair_extract) +MARK_VISIBLE (gcry_ac_key_data_get) +MARK_VISIBLE (gcry_ac_key_test) +MARK_VISIBLE (gcry_ac_key_get_nbits) +MARK_VISIBLE (gcry_ac_key_get_grip) +MARK_VISIBLE (gcry_ac_key_destroy) +MARK_VISIBLE (gcry_ac_key_pair_destroy) +MARK_VISIBLE (gcry_ac_data_encrypt) +MARK_VISIBLE (gcry_ac_data_decrypt) +MARK_VISIBLE (gcry_ac_data_sign) +MARK_VISIBLE (gcry_ac_data_verify) +MARK_VISIBLE (gcry_ac_id_to_name) +MARK_VISIBLE (gcry_ac_name_to_id) +/* MARK_VISIBLE (gcry_ac_list) Not defined although it is in + libgcrypt.vers. */ +MARK_VISIBLE (gcry_ac_data_encode) +MARK_VISIBLE (gcry_ac_data_decode) +MARK_VISIBLE (gcry_ac_mpi_to_os) +MARK_VISIBLE (gcry_ac_mpi_to_os_alloc) +MARK_VISIBLE (gcry_ac_os_to_mpi) +MARK_VISIBLE (gcry_ac_data_encrypt_scheme) +MARK_VISIBLE (gcry_ac_data_decrypt_scheme) +MARK_VISIBLE (gcry_ac_data_sign_scheme) +MARK_VISIBLE (gcry_ac_data_verify_scheme) +MARK_VISIBLE (gcry_ac_data_to_sexp) +MARK_VISIBLE (gcry_ac_data_from_sexp) +MARK_VISIBLE (gcry_ac_io_init) +MARK_VISIBLE (gcry_ac_io_init_va) + +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*/ |