Page MenuHome GnuPG

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/AUTHORS b/AUTHORS
index 45499ff4..b3b398da 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,98 +1,103 @@
Library: Libgcrypt
Maintainer: Moritz Schulte <moritz@g10code.com>
Bug reports: <bug-libgcrypt@gnupg.org>
Security related bug reports: <security@gnupg.org>
Libgcrypt used to be part of GnuPG but has been taken out into its own
package on 2000-12-21.
Authors of Libgcrypt
====================
GNUPG Werner Koch 1998-02-23
Assigns GNU Privacy Guard and future changes.
wk@gnupg.org
Designed and implemented GnuPG.
GNUPG Matthew Skala 1998-08-10
Disclaims changes.
mskala@ansuz.sooke.bc.ca
Wrote cipher/twofish.c.
GNUPG Natural Resources Canada 1998-08-11
Disclaims changes by Matthew Skala.
-
GNUPG Michael Roth Germany 1998-09-17
Assigns changes.
mroth@nessie.de
Wrote cipher/des.c.
Changes and bug fixes all over the place.
-
GNUPG Niklas Hernaeus 1998-09-18
Disclaims changes.
nh@df.lth.se
Weak key patches.
-
GNUPG Rémi Guyomarch 1999-05-25
Assigns past and future changes. (g10/compress.c, g10/encr-data.c,
g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c)
rguyom@mail.dotcom.fr
ANY g10 Code GmbH 2001-06-07
Code marked with ChangeLog entries of g10 Code employees.
LIBGCRYPT Timo Schulz 2001-08-31
Assigns past and future changes.
twoaday@freakmail.de
LIBGCRYPT Simon Josefsson 2002-10-25
Assigns past and future changes to FSF (cipher/{md4,crc}.c, CTR mode,
CTS/MAC flags, self test improvements)
simon@josefsson.org
LIBGCRYPT Moritz Schulte 2003-04-17
Assigns past and future changes.
moritz@g10code.com
GNUTLS Nikolaos Mavrogiannopoulos 2003-11-22
nmav@gnutls.org
Orginal code for cipher/rfc2268.c.
LIBGCRYPT The Written Word 2005-04-15
Assigns past and future changes. (new: src/libgcrypt.pc.in,
src/Makefile.am, src/secmem.c, mpi/hppa1.1/mpih-mul3.S,
mpi/hppa1.1/udiv-qrnnd.S, mpi/hppa1.1/mpih-mul2.S,
mpi/hppa1.1/mpih-mul1.S, mpi/Makefile.am, tests/prime.c,
tests/register.c, tests/ac.c, tests/basic.c, tests/tsexp.c,
tests/keygen.c, tests/pubkey.c, configure.ac, acinclude.m4)
+LIBGCRYPT Brad Hards 2006-02-09
+Assigns Past and Future Changes
+bradh@frogmouth.net
+(Added OFB mode. Changed cipher/cipher.c, test/basic.c doc/gcrypt.tex)
+
+
+
More credits
============
The ATH implementation (src/ath*) has been taken from GPGME and
relicensed to the LGPL by the copyright holder of GPGME (g10 Code
GmbH); it is now considered to be a part of Libgcrypt.
Most of the stuff in mpi has been taken from an old GMP library
version by Torbjorn Granlund <tege@noisy.tmg.se>.
The files cipher/rndunix.c and cipher/rndw32.c are based on those
files from Cryptlib. Copyright Peter Gutmann, Paul Kendall, and Chris
Wedgwood 1996-1999.
- Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003,
+ 2006 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.
diff --git a/TODO b/TODO
index 43a432b4..6d6355ff 100644
--- a/TODO
+++ b/TODO
@@ -1,38 +1,41 @@
What's left to do -*- outline -*-
* Add more tests. Even basic is very minimal.
* udiv-qrnbd.o should get build as *.lo [HPUX]
* Allow operation using RSA keys consisting of the OpenSSL list of
parameters and allow for a third form where the private Exponent
is not given (saves space).
* Add a warning to the manual, to check that libgcrypt actually has
been compiled with thread support when used by a threaded
application.
* write an autoconf test to check whether the linker supports a
version script.
* Make use of the forthcoming visibility attribute.
* Add attributes to the MPI functions.
* Write tests for the progress function
* In case the ac interface will be more popular than the pk interface,
the asymmetric ciphers could be changed for convenient interaction
with the ac interface (i.e. by using ac's `data sets') and the pk
interface could be changed to be a wrapper for the ac interface.
* HMAC won't work with sha-512 due to the different block size. OTOH,
I can imagine no cryptographic reason to use it.
* cipher/pubkey.c and pubkey implementaions.
Don't rely on the secure memory based wiping function but add an
extra wiping.
* update/improve documentation
- it's outdated for e.g. gcry_pk_algo_info.
- document algorithm capabilities
+
+* Use builtin bit functions of gcc 3.4
+
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index c70ebcab..792bd82a 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -1,2960 +1,2965 @@
+2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07)
+
+ * cipher.c (cipher_encrypt, cipher_decrypt, do_ofb_encrypt)
+ (do_ofb_decrypt, gcry_cipher_open): Implement Output Feedback Mode.
+
2005-11-02 Moritz Schulte <moritz@g10code.com>
* pubkey.c (gcry_pk_algo_name): Return "?" instead of NULL for
unknown algorithm IDs.
* cipher.c (cipher_algo_to_string): Likewise.
2005-11-01 Moritz Schulte <moritz@g10code.com>
* pubkey.c (gcry_pk_algo_info): Don't forget to break after switch
case.
2005-09-19 Werner Koch <wk@g10code.com>
* dsa.c (generate): Add preliminary support for 2 and 4 keys.
Return an error code if the key size is not supported.
(_gcry_dsa_generate): Return an error.
2005-08-22 Werner Koch <wk@g10code.com>
* primegen.c (check_prime): New arg RM_ROUNDS.
(prime_generate_internal): Call it here with 5 rounds as used
before.
(gcry_prime_check): But here with 64 rounds.
(is_prime): Make sure never to use less than 5 rounds.
2005-04-16 Moritz Schulte <moritz@g10code.com>
* ac.c (_gcry_ac_init): New function.
2005-04-12 Moritz Schulte <moritz@g10code.com>
* ac.c (_gcry_ac_io_write, _gcry_ac_io_read): Initialize err to
make the compiler happy.
Always use errno, now that gcry_malloc() is guaranteed to set
errno on failure.
(_gcry_ac_data_to_sexp): Don't forget to goto out after error in
loop.
(_gcry_ac_data_to_sexp): Remove unused variable: mpi_list;
(_gcry_ac_data_to_sexp): Always deallocate sexp_buffer.
(_gcry_ac_data_from_sexp): Don't forget to initialize data_set_new.
(_gcry_ac_data_from_sexp): Handle special case, which is
necessary, since gcry_sexp_nth() does not distinguish between
"element does not exist" and "element is the empty list".
(_gcry_ac_io_init_va): Use assert to make sure that mode and type
are correct.
Use gcry_error_t types where gcry_err_code_t types have been used
before.
2005-04-11 Moritz Schulte <moritz@g10code.com>
* ac.c (_gcry_ac_data_sign_scheme): Don't forget to initialize
buffer.
* whirlpool.c: New file.
* md.c (digest_table): Add whirlpool.
* Makefile.am (EXTRA_libcipher_la_SOURCES): Added: whirlpool.c.
2005-03-30 Moritz Schulte <moritz@g10code.com>
* ac.c (_gcry_ac_data_from_sexp): Use length of SEXP_CUR, not
length of SEXP; do not forget to set SEXP_TMP to NULL after it has
been released.
(struct gcry_ac_mpi): New member: name_provided.
(_gcry_ac_data_set): Rename variable `name_final' to `name_cp';
remove const qualifier; change code to not cast away const
qualifiers; use name_provided member as well.
(_gcry_ac_data_set, _gcry_ac_data_get_name): Use name_provided
member of named mpi structure.
(gcry_ac_name_to_id): Do not forget to initialize err.
(_gcry_ac_data_get_index): Do not forget to initialize mpi_return;
use gcry_free() instead of free(); remove unnecessary cast; rename
mpi_return and name_return to mpi_cp and name_cp; adjust code.
(ac_data_mpi_copy): Do not cast away const qualifier.
(ac_data_values_destroy): Likewise.
(ac_data_construct): Likewise.
(ac_data_mpi_copy): Initialize flags to GCRY_AC_FLAG_DEALLOC.
(ac_data_extract): Use GCRY_AC_FLAG_DEALLOC instead of
GCRY_AC_FLAG_COPY.
(_gcry_ac_io_init_va, _gcry_ac_io_init, gcry_ac_io_init)
(gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read)
(_gcry_ac_io_read_all, _gcry_ac_io_process): New functions.
(gry_ac_em_dencode_t): Use gcry_ac_io_t in prototype instead of
memroy strings directly; adjust encode/decode functions to use io
objects.
(emsa_pkcs_v1_5_encode_data_cb): New function ...
(emsa_pkcs_v1_5_encode): ... use it here.
(ac_data_dencode): Use io objects.
(_gcry_ac_data_encode, _gcry_ac_data_decode, gcry_ac_data_encode)
(gcry_ac_data_decode): Likewise.
(_gcry_ac_data_encrypt_scheme, gcry_ac_data_encrypt_scheme)
(_gcry_ac_data_decrypt_scheme, gcry_ac_data_decrypt_scheme)
(_gcry_ac_data_sign_scheme, gcry_ac_data_sign_scheme)
(_gcry_ac_data_verify_scheme, gcry_ac_data_verify_scheme):
Likewise.
2005-03-23 Werner Koch <wk@g10code.com>
* rndw32.c (_gcry_rndw32_gather_random_fast): While adding data
use the size of the object and not the one of its address. Bug
reported by Sascha Kiefer.
2005-03-19 Moritz Schulte <moritz@g10code.com>
* cipher.c (do_cbc_encrypt): Be careful to not overwrite data,
which is to be used later on. This happend, in case CTS is
enabled and OUTBUF is equal to INBUF.
2005-02-25 Werner Koch <wk@g10code.com>
* pubkey.c (gcry_pk_get_keygrip): Allow for shadowed-private-key.
2005-02-13 Moritz Schulte <moritz@g10code.com>
* serpent.c: Updated from 1.2 branch:
s/u32_t/u32/ and s/byte_t/byte/. Too match what we have always
used and are using in all other files too
(serpent_test): Moved prototype out of a fucntion.
2005-02-07 Moritz Schulte <moritz@g10code.com>
* ac.c: Major parts rewritten.
* pubkey.c (_gcry_pk_get_elements): New function.
2004-12-09 Werner Koch <wk@g10code.com>
* serpent.c (serpent_setkey): Moved prototype of serpent_test to
outer scope.
2004-09-11 Moritz Schulte <moritz@g10code.com>
* pubkey.c (pubkey_table): Added an alias entry for GCRY_PK_ELG_E.
2004-08-23 Moritz Schulte <moritz@g10code.com>
* ac.c: Do not include <assert.h>.
* rndegd.c: Likewise.
* sha1.c: Likewise.
* rndunix.c: Likewise.
* rndlinux.c: Likewise.
* rmd160.c: Likewise.
* md5.c: Likewise.
* md4.c: Likewise.
* cipher.c: Likewise.
* crc.c: Likewise.
* blowfish.c: Likewise.
* pubkey.c (dummy_generate, dummy_check_secret_key)
(dummy_encrypt, dummy_decrypt, dummy_sign, dummy_verify): Return
err code GPG_ERR_NOT_IMPLEMENTED instead of aborting through
log_bug().
(dummy_get_nbits): Return 0 instead of aborting though log_bug().
2004-08-19 Werner Koch <wk@g10code.de>
* pubkey.c (sexp_data_to_mpi): Changed the zero random byte
substituting code to actually do clever things. Thanks to
Matthias Urlichs for noting the implementation problem.
2004-08-09 Moritz Schulte <moritz@g10code.com>
* pubkey.c (gcry_pk_sign): Fixed memory leak; fix provided by
Modestas Vainius.
2004-07-16 Werner Koch <wk@gnupg.org>
* rijndael.c (do_encrypt): Fix alignment problem. Bugs found by
Matthias Urlichs.
(do_decrypt): Ditto.
(keySched, keySched2): Use 2 macros along with unions in the key
schedule context.
2004-07-14 Moritz Schulte <moritz@g10code.com>
* rsa.c (_gcry_rsa_decrypt): Don't forget to free "a". Thanks to
Nikos Mavroyanopoulos.
2004-05-09 Werner Koch <wk@gnupg.org>
* random.c (read_pool): Mix the PID in to better protect after a
fork.
2004-07-04 Moritz Schulte <moritz@g10code.com>
* serpent.c: Use "u32_t" instead of "unsigned long", do not
declare S-Box variables as "register". Fixes failure on
OpenBSD/sparc64, reported by Nikolay Sturm.
2004-05-07 Werner Koch <wk@gnupg.org>
* random.c (initialize): Factored out some code to ..
(initialize_basics): .. new function.
(_gcry_random_initialize): Just call initialize_basics unless the
new arg FULL is set to TRUE.
(_gcry_fast_random_poll): Don't do anything unless the random
system has been really initialized.
2004-05-07 Moritz Schulte <moritz@g10code.de>
* ac.c (gcry_ac_open): Do not dereference NULL pointer. Reported
by Umberto Salsi.
2004-02-20 Werner Koch <wk@gnupg.org>
* primegen.c (check_prime): New args CB_FUNC and CB_ARG; call them
at different stages. Pass these arguments through all callers.
2004-02-06 Werner Koch <wk@gnupg.org>
* des.c: Add a new OID as used by pkcs#12.
* rfc2268.c: New. Taken from libgcrypt.
* cipher.c: Setup the rfc2268 algorithm.
2004-01-25 Moritz Schulte <mo@g10code.com>
* primegen.c (prime_generate_internal): Do not forget to free
`q_factor'; fixed by Brieuc Jeunhomme.
(prime_generate_internal): Do not forget to free `prime'.
2004-01-14 Moritz Schulte <mo@g10code.com>
* ac.c (gcry_ac_data_set): New argument: flags; slightly
rewritten.
(gcry_ac_data_get_name, gcry_ac_data_get_index): Likewise.
(gcry_ac_key_pair_generate): New argument: misc_data; modified
order of arguments.
(gcry_ac_key_test): New argument: handle.
(gcry_ac_key_get_nbits, gcry_ac_key_get_grip): Likewise.
Use GCRY_AC_FLAG_NO_BLINDING instead of
GCRY_AC_DATA_FLAG_NO_BLINDING.
(gcry_ac_mpi): New member: flags.
(gcry_ac_data_search, gcry_ac_data_add): Removed functions.
2003-12-22 Werner Koch <wk@gnupg.org>
* primegen.c (is_prime): Release A2.
2003-12-19 Werner Koch <wk@gnupg.org>
* md.c: Moved a couple of functions down below the data structure
definitions.
(struct gcry_md_context): New field ACTUAL_HANDLE_SIZE.
(md_open): Set it here.
(strcut gcry_md_list): New field ACTUAL_STRUCT_SIZE.
(md_enable): Set it here.
(md_close): Wipe the context memory.
secure memory.
* cipher.c (struct gcry_cipher_handle): New field ACTUAL_HANDLE_SIZE.
(gcry_cipher_open): Set it here.
(gcry_cipher_close): Use it to always wipe out the handle data.
* ac.c (gcry_ac_open): Make sure HANDLE gets initialized even when
the function is not successful.
(gcry_ac_close): Allow a NULL handle.
(gcry_ac_key_destroy, gcry_ac_key_pair_destroy): Ditto.
(gcry_ac_key_get_grip): Return INV_OBJ on error.
* primegen.c (prime_generate_internal): Fixed error code for
failed malloc. Replaced the !err if chain by gotos.
(gcry_prime_group_generator): Remove the extra sanity check.
* md.c: Minor code and comment cleanups.
2003-12-16 Werner Koch <wk@gnupg.org>
* primegen.c (gen_prime): Doc fix. Thanks to Newton Hammet.
2003-12-11 Werner Koch <wk@gnupg.org>
* rndunix.c (slow_poll): Don't use #warning but #error.
* rndegd.c: Changed indentation.
(my_make_filename): Removd the var_arg cruft becuase we
don't need it here. Changed caller.
* rndlinux.c: Changed indentation.
(open_device): Remove the superfluous stat call and clarify
comment.
* rsa.c: Changed indentation.
(secret): Use the standard algorithm if p, q and u are not
available.
(rsa_blind, rsa_unblind): Renamed from _gcry_rsa_blind,
_gcry_rsa_unblind and moved more to the top.
* md4.c: Changed indentation. Removed unnecessary casts.
* md5.c, rmd160.c, sha1.c, tiger.c: Ditto.
* rijndael.c, twofish.c: Ditto.
* serpent.c: Removed unnecessary casts.
* sha256.c, sha512.c: Ditto.
2003-12-09 Werner Koch <wk@gnupg.org>
* dsa.c: Unified indentation style.
* elgamal.c: Ditto.
* des.c (des_key_schedule): Code beautifications.
* blowfish.c: Changed indentation style.
* cast5.c (do_cast_setkey): Ditto.
* pubkey.c (gcry_pk_encrypt): Replaced the chain of if(!err) tests
by straightforward gotos. Other cleanups.
(gcry_pk_decrypt): Ditto.
(gcry_pk_sign): Ditto.
(gcry_pk_verify): Ditto.
(gcry_pk_genkey): Ditto. Use strtoul instead of strtol.
(gcry_pk_ctl): Use GPG_ERR_INV_ARG to indicate bad arguments.
2003-12-07 Werner Koch <wk@gnupg.org>
* pubkey.c (gcry_pk_register_default): Undef the helper macro.
(gcry_pk_map_name): Allow NULL for string.
(sexp_to_key): Use memcpy and not strncpy. Use gcry_free and not
free.
(sexp_to_sig): Ditto.
(sexp_to_enc): Ditto. Replaced the chain of if(!err) tests by
straightforward gotos.
2003-12-05 Werner Koch <wk@gnupg.org>
* cipher.c: Documentation cleanups.
(gcry_cipher_mode_from_oid): Allow NULL for STRING.
2003-12-03 Werner Koch <wk@gnupg.org>
* elgamal.c (sign, do_encrypt, gen_k): Make sure that a small K is
only used for encryption.
2003-11-18 Werner Koch <wk@gnupg.org>
* random.h (rndw32_set_dll_name): Removed unused prototype.
* Makefile.am (EXTRA_DIST): Added Manifest.
2003-11-11 Werner Koch <wk@gnupg.org>
* Manifest: New.
2003-11-04 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_hash_buffer): Use shortcut for SHA1
* sha1.c (_gcry_sha1_hash_buffer): New.
* random.c: Reformatted most functions.
(mix_pool): Moved the failsafe_digest from global
scope to here.
(do_fast_random_poll): Use the generic fucntions even if a fast
gathering function has been used.
(read_pool): Detect a fork and retry.
(gcry_randomize, get_random_bytes): Don't distinguish anymore
between weak and strong random.
(gcry_create_nonce): New.
2003-10-31 Werner Koch <wk@gnupg.org>
* rndw32.c (slow_gatherer_windowsNT): Use a plain buffer for the
disk performance values and not the W32 API structure.
* dsa.c (verify): s/exp/ex/ due to shadowing of a builtin.
* elgamal.c (verify): Ditto.
* ac.c (gcry_ac_data_get_index): s/index/idx/
(gcry_ac_data_copy_internal): Remove the cast in _gcry_malloc.
(gcry_ac_data_add): Must use gcry_realloc instead of realloc.
* pubkey.c (sexp_elements_extract): s/index/idx/ as tribute to the
forehackers.
(gcry_pk_encrypt): Removed shadowed definition of I. Reordered
arguments to malloc for clarity.
(gcry_pk_sign, gcry_pk_genkey): Ditto.
* primegen.c (prime_generate_internal): s/random/randomlevel/.
2003-10-27 Moritz Schulte <mo@g10code.com>
* pubkey.c (gcry_pk_encrypt): Don't forget to deallocate pkey.
2003-10-27 Werner Koch <wk@gnupg.org>
* random.c (gcry_random_add_bytes): Return if buflen is zero to
avoid gcc warning about unsed parameter.
(MASK_LEVEL): Simplified; does now work for signed and unsigned
w/o warnings.
* md.c (md_start_debug): Removed the const from SUFFIX, because
this function is called from the control fucntion which does not
require const.
Prefixed all (pubkey,digest,cipher}_spec_* globale variables with
_gcry_.
* ac.c (ac_key_identifiers): Made static.
* random.c (getfnc_gather_random,getfnc_fast_random_poll): Move
prototypes to ..
* rand-internal.h: .. here
* random.c (getfnc_gather_random): Include rndw32 gatherer.
* rndunix.c, rndw32.c, rndegd.c: Include them here.
* rndlinux.c (_gcry_rndlinux_gather_random): Prepend the _gcry_
prefix. Changed all callers.
* rndegd.c (_gcry_rndegd_gather_random): Likewise.
(_gcry_rndegd_connect_socket): Likewise.
* rndunix.c (_gcry_rndunix_gather_random): Likewise.
(waitpid): Made static.
* rndw32.c: Removed the old and unused winseed.dll cruft.
(_gcry_rndw32_gather_random_fast): Renamed from
gather_random_fast.
(_gcry_rndw32_gather_random): Renamed from gather_random. Note,
that the changes 2003-04-08 somehow got lost.
* sha512.c (sha512_init, sha384_init): Made static.
* cipher.c (do_ctr_decrypt): Removed "return" from this void
function.
2003-10-24 Moritz Schulte <mo@g10code.com>
* serpent.c: Fix an issue on big-endian systems.
* rndw32.c: Removed IS_MODULE -cruft.
* rndlinux.c (rndlinux_gather_random): Likewise.
2003-10-10 Werner Koch <wk@gnupg.org>
* primegen.c (gen_prime): Bail out if NBITS is less than 16.
(prime_generate_internal): Initialize prime variable to suppress
compiler warning. Check pbits, initialize qbits when passed as
zero.
* primegen.c (prime_generate_internal): New arg
ALL_FACTORS. Changed all callers.
(gcry_prime_generate): Make the factors arg optional. Request
all_factors. Make sure PRIME is set to NULL even on error.
(gcry_prime_group_generator): New.
(gcry_prime_release_factors): New.
2003-10-06 Werner Koch <wk@gnupg.org>
* primegen.c (gen_prime): Assert that NBITS is never zero, it
would cause a segv.
2003-09-28 Moritz Schulte <mo@g10code.com>
* ac.c: Include "cipher.h".
2003-09-27 Moritz Schulte <mo@g10code.com>
* rndegd.c (do_read): Return nread instead of nbytes; thanks to
Michael Caerwyn.
2003-09-04 Werner Koch <wk@gnupg.org>
* pubkey.c (_gcry_pk_aliased_algo_name): New.
* ac.c (gcry_ac_open): Use it here.
* Makefile.am (EXTRA_libcipher_la_SOURCES): Add serpent.c
2003-09-02 Moritz Schulte <mo@g10code.com>
* primegen.c (gcry_prime_check, gcry_prime_generate): New
functions.
(prime_generate_internal): New function, based on
_gcry_generate_elg_prime.
(_gcry_generate_elg_prime): Rewritten as a wrapper for
prime_generate_internal.
2003-08-28 Werner Koch <wk@gnupg.org>
* pubkey.c (gcry_pk_encrypt): Don't include the flags list in the
return value. This does not make sense and breaks any programs
parsing the output strictly (e.g. current gpgsm).
(gcry_pk_encrypt): If aliases for the algorithm name exists, take
the first one instead of the regular name to adhere to SPKI
conventions.
(gcry_pk_genkey): Ditto.
(gcry_pk_sign): Ditto. Removed unused KEY_ALGO_NAME.
2003-08-19 Moritz Schulte <mo@g10code.com>
* cipher.c: Add support for Serpent
* serpent.c: New file.
2003-08-10 Moritz Schulte <moritz@g10code.com>
* rsa.c (_gcry_rsa_blind, _gcry_rsa_unblind): Declare static.
2003-08-09 Timo Schulz <twoaday@freakmail.de>
* random.c (getfnc_gather_random): Don't check NAME_OF_DEV_RANDOM
two times, but also the NAME_OF_DEV_URANDOM device.
2003-08-08 Moritz Schulte <moritz@g10code.com>
* pubkey.c (sexp_to_enc): Fixed extraction of S-Expression: do not
fail if no `flags' sub S-Expression is found.
2003-07-27 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_lookup_func_oid): Allow for empty OID lists.
2003-07-23 Moritz Schulte <moritz@g10code.com>
* ac.c (gcry_ac_data_construct): New argument: include_flags, only
include `flags' S-expression, if include_flags is true. Adjust
callers. Thanks for triggering a bug caused by `flags'
sub-S-expression where they are not expected to Ralf Schneider.
2003-07-21 Moritz Schulte <moritz@g10code.com>
* pubkey.c (gcry_pk_lookup_func_name): Use new member name
`aliases' instead of `sexp_names'.
* ac.c (gcry_ac_key_data_get): New function.
* cipher.c (gcry_cipher_lookup_func_name): Fix return value.
2003-07-20 Moritz Schulte <moritz@g10code.com>
* blowfish.c: Adjusted for new gcry_cipher_spec_t structure.
* cast5.c: Likewise.
* twofish.c: Likewise.
* arcfour.c: Likewise.
* rijndael.c (rijndael_oids, rijndael192_oids, rijndael256_oids):
New variables, adjust for new gcry_cipher_spec_t structure.
* des.c (oids_tripledes): New variable, adjust for new
gcry_cipher_spec_t structure.
* md.c (oid_table): Removed.
* tiger.c (oid_spec_tiger): New variable.
(digest_spec_tiger): Adjusted for new gry_md_spec_t structure.
* sha512.c (oid_spec_sha512): New variable.
(digest_spec_sha512): Adjusted for new gry_md_spec_t structure.
* sha512.c (oid_spec_sha384): New variable.
(digest_spec_sha384): Adjusted for new gry_md_spec_t structure.
* sha256.c (oid_spec_sha256): New variable.
(digest_spec_sha256): Adjusted for new gry_md_spec_t structure.
* sha1.c (oid_spec_sha1): New variable.
(digest_spec_sha1): Adjusted for new gry_md_spec_t structure.
* rmd160.c (oid_spec_rmd160): New variable.
(digest_spec_rnd160): Adjusted for new gry_md_spec_t structure.
* md5.c (oid_spec_md5): New variable.
(digest_spec_md5): Adjusted for new gry_md_spec_t structure.
* md4.c (oid_spec_md4): New variable.
(digest_spec_md4): Adjusted for new gry_md_spec_t structure.
* crc.c (digest_spec_crc32, digest_spec_crc32_rfc1510,
digest_spec_crc32_rfc2440): Adjusted for new gry_md_spec_t
structure.
2003-07-19 Moritz Schulte <moritz@g10code.com>
* md.c (gcry_md_lookup_func_oid): New function.
(search_oid): New function, copied from cipher.c.
(gcry_md_map_name): Adjust for new search_oid_interface.
* cipher.c (oid_table): Removed table.
(gcry_cipher_lookup_func_oid): New function.
(search_oid): Rewritten to use the module functions.
(gcry_cipher_map_name): Adjust for new search_oid interface.
(gcry_cipher_mode_from_oid): Likewise.
2003-07-18 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_hash_buffer): Convert ERR to gpg_error_t in
gpg_strerror.
2003-07-14 Moritz Schulte <moritz@g10code.com>
* cipher.c (gcry_cipher_lookup_func_name): Also check the cipher
name aliases, not just the primary name.
(gcry_cipher_map_name): Remove kludge for aliasing Rijndael to
AES.
* arcfour.c, blowfish.c, cast5.c, des.c, twofish.c: Adjust cipher
specification structures.
* rijndael.c (rijndael_names, rijndael192_names,
rijndael256_names): New variables, use them in the cipher
specifications.
* rmd160test.c: Removed file.
* ac.c, arcfour.c, blowfish.c, cast5.c, cipher.c, des.c, dsa.c,
elgamal.c, md.c, pubkey.c, random.c, rijndael.c, rsa.c, twofish.c:
Used gcry_err* wrappers for libgpg symbols.
* primegen.c (gen_prime): Correct the order arguments to
extra_check.
2003-07-12 Moritz Schulte <moritz@g10code.com>
* ac.c: Replaced all public occurences of gpg_error_t with
gcry_error_t.
* cipher.c: Likewise.
* md.c: Likewise.
* pubkey.c: Likewise.
* random.c: Likewise.
* cipher.c: Added support for TWOFISH128.
2003-07-08 Moritz Schulte <moritz@g10code.com>
* ac.c (gcry_ac_data_copy_internal): New function, based on
gcry_ac_data_copy.
(gcry_ac_data_copy): Made public, use gcry_ac_data_copy_internal.
(gcry_ac_key_init): Use gcry_ac_data_copy_internal.
2003-07-07 Moritz Schulte <moritz@g10code.com>
* ac.c (gcry_ac_data_set): Only release old MPI value if it is
different from the new value. Bug reported by Simon Josefsson
<jas@extundo.com>.
* pubkey.c (gcry_pk_list): New function.
* md.c (gcry_md_list): New function.
* ac.c (gcry_ac_key_pair_generate): Fix calculation of format
string size.
2003-07-05 Moritz Schulte <moritz@g10code.com>
* md.c: Named struct of digest_table `digest_table_entry'.
(digest_table_entry): New member: algorithm; filled in.
(digest_table_entry): Removed unused member: flags.
(gcry_md_register): New argument: algorithm_id, filled in.
(gcry_md_register_default): Used algorithm ID from module
structure.
(gcry_md_map_name): Likewise.
(md_enable): Likewise.
(md_read): Likewise.
(gcry_md_info): Likewise.
* pubkey.c: Named truct for pubkey_table `pubkey_table_entry'.
(pubkey_table_entry): New member: algorithm; filled in.
(gcry_pk_register_default): Used algorithm ID from pubkey_table.
(gcry_pk_register): New argument: algorithm_id, filled in.
(gcry_pk_map_name): Used algorithm ID from module structure.
(gcry_pk_decrypt): Likewise.
(gcry_pk_encrypt): Likewise.
(gcry_pk_verify): Likewise.
(gcry_pk_sign): Likewise.
(gcry_pk_testkey): Likewise.
(gcry_pk_genkey): Likewise.
(gcry_pk_get_nbits): Likewise.
(sexp_to_key): Removed unused variable: algo.
(sexp_to_sig): Likewise.
* cipher.c: Named struct for cipher_table `cipher_table_entry'.
(cipher_table_entry): New member: algorithm; filled in.
(gcry_cipher_register_default): Used algorithm ID from
cipher_table.
(gcry_cipher_register): New argument: algorithm_id, filled in.
(gcry_cipher_map_name): Used algorithm ID from module structure.
* arcfour.c (cipher_spec_arcfour): Removed algorithm ID.
* blowfish.c (cipher_spec_blowfish): Likewise.
* cast5.c (cipher_spec_cast5): Likewise.
* crc.c (digest_spec_crc32): Likewise.
* crc.c (digest_spec_crc32_rfc1510): Likewise.
* crc.c (digest_spec_crc32_rfc2440): Likewise.
* des.c (cipher_spec_des): Likewise.
* des.c (cipher_spec_tripledes): Likewise.
* dsa.c (pubkey_spec_dsa): Likewise.
* elgamal.c (pubkey_spec_elg): Likewise.
* md4.c (digest_spec_md4): Likewise.
* md5.c (digest_spec_md5): Likewise.
* aes.c (cipher_spec_aes): Likewise.
* aes.c (cipher_spec_aes192): Likewise.
* aes.c (cipher_spec_aes256): Likewise.
* rsa.c (pubkey_spec_rsa): Likewise.
* sha1.c (digest_spec_sha1): Likewise.
* sha256.c (digest_spec_sha256): Likewise.
* sha512.c (digest_spec_sha512): Likewise.
* tiger.c (digest_spec_tiger): Likewise.
* twofish.c (cipher_spec_twofish): Likewise.
* twofish.c (cipher_spec_twofish128): Likewise.
* Makefile.am (EXTRA_libcipher_la_SOURCES): Fix list of source
files; reported by Simon Josefsson <jas@extundo.com>.
* pubkey.c: Replaced all occurences of `id' with `algorithm',
since `id' is a keyword in obj-c.
* md.c: Likewise.
* cipher.c: Likewise.
* crc.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, tiger.c:
Replaced all occurences of gcry_digest_spec_t with gcry_md_spec_t.
* dsa.c, rsa.c, elgamal.c: Replaced all occurencens of
gcry_pubkey_spec_t with gcry_pk_spec_t.
* md.c: Replaced all occurences of gcry_digest_spec_t with
gcry_md_spec_t.
(gcry_digest_register_default): Renamed to ...
(gcry_md_register_default): ... this; adjusted callers.
(gcry_digest_lookup_func_name): Renamed to ...
(gcry_md_lookup_func_name): ... this; adjusted callers.
(gcry_digest_lookup_name): Renamed to ...
(gcry_md_lookup_name): ... this; adjusted callers.
(gcry_digest_register): Renamed to ...
(gcry_md_register): ... this.
(gcry_digest_unregister): Renamed to ...
(gcry_md_unregister): ... this.
* pubkey.c (gcry_pubkey_register): Renamed to ...
(gcry_pk_register): ... this.
(gcry_pubkey_unregister): Renamed to ...
(gcry_pk_unregister): ... this.
Replaced all occurences of gcry_pubkey_spec_t with gcry_pk_spec_t.
(gcry_pubkey_register_default): Renamed to ...
(gcry_pk_register_default): ... this; adjusted callers.
(gcry_pubkey_lookup_func_name): Renamed to ...
(gcry_pk_lookup_func_name): ... this; adjusted callers.
(gcry_pubkey_lookup_name): Renamed to ...
(gcry_pk_lookup_name): ... this; adjusted callers.
* md.c (gcry_md_hash_buffer): Fix error checking. Thanks to Simon
Josefsson <jas@extunde.com>.
2003-07-04 Moritz Schulte <moritz@g10code.com>
* cipher.c (gcry_cipher_list): New function.
2003-07-01 Moritz Schulte <moritz@g10code.com>
* pubkey.c (sexp_to_sig): Accept a `flags' S-expression to be more
consistent with sexp_to_enc.
2003-06-30 Moritz Schulte <moritz@g10code.com>
* Makefile.am (libcipher_la_SOURCES): Added: ac.c.
* pubkey.c (_gcry_pk_module_lookup): New function.
(_gcry_pk_module_release): New function.
2003-06-29 Moritz Schulte <moritz@g10code.com>
* ac.c: New file.
2003-06-26 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_hash_buffer): Trigger BUG correcly with new API.
2003-06-19 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_is_enabled): Fixed.
2003-06-18 Werner Koch <wk@gnupg.org>
* cipher.c (gcry_cipher_get_algo_keylen): New.
(gcry_cipher_get_algo_blklen): New.
2003-06-18 Moritz Schulte <moritz@g10code.com>
* arcfour.c, cipher.c, blowfish.c, md.c, cast5.c, pubkey.c, crc.c,
des.c, dsa.c, elgamal.c, md4.c, md5.c, random.c, rijndael.c,
rmd160.c, rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c:
Replaced older types GcryDigestSpec, GcryCipherSpec and
GcryPubkeySpec with newer types: gcry_digest_spec_t,
gcry_cipher_spec_t and gcry_pubkey_spec_t.
* md.c (gcry_digest_id_new): Removed function.
(gcry_digest_register): Removed code for generating a new module
ID.
* pubkey.c (gcry_pubkey_id_new): Removed function.
(gcry_pubkey_register): Removed code for generating a new module
ID.
* cipher.c, md.c, pubkey.c: Replace old type GcryModule with newer
one: gcry_module_t.
(gcry_cipher_id_new): Removed function.
(gcry_cipher_register): Removed code for generating a new module
ID.
* cipher.c (gcry_cipher_register): Adjust call to
_gcry_module_add.
(gcry_cipher_register_default): Likewise.
* pubkey.c (gcry_pubkey_register_default): Likewise.
(gcry_pubkey_register): Likewise.
* md.c (gcry_digest_register_default): Likewise.
(gcry_digest_register): Likewise.
* md.c (gcry_digest_lookup_func_id): Removed function.
(gcry_digest_lookup_id): Likewise.
(gcry_digest_id_new): Use _gcry_module_lookup_id instead of
gcry_digest_lookup_id.
(digest_algo_to_string): Likewise.
(check_digest_algo): Likewise.
(md_enable): Likewise.
(md_digest_length): Likewise.
(md_asn_oid): Likewise.
* pubkey.c (gcry_pubkey_lookup_id): Removed function.
(gcry_pubkey_lookup_func_id): Likewise.
(gcry_pubkey_id_new): Use _gcry_module_lookup_id instead of
gcry_pubkey_id_new.
(gcry_pk_algo_name): Likewise.
(disable_pubkey_algo): Likewise.
(check_pubkey_algo): Likewise.
(pubkey_get_npkey): Likewise.
(pubkey_get_nskey): Likewise.
(pubkey_get_nsig): Likewise.
(pubkey_get_nenc): Likewise.
(pubkey_generate): Likewise.
(pubkey_check_secret_key): Likewise.
(pubkey_encrypt): Likewise.
(pubkey_decrypt): Likewise.
(pubkey_sign): Likewise.
(pubkey_verify): Likewise.
(gcry_pk_algo_info): Likewise.
* cipher.c (gcry_cipher_lookup_func_id): Removed function.
(gcry_cipher_lookup_id): Likewise.
(cipher_algo_to_string): use _gcry_module_lookup_id instead of
gcry_cipher_lookup_id.
(disable_cipher_algo): Likewise.
(check_cipher_algo): Likewise.
(cipher_get_blocksize): Likewise.
(gcry_cipher_open): Likewise.
(gcry_cipher_id_new): Likewise.
2003-06-17 Moritz Schulte <moritz@g10code.com>
* Makefile.am (GCRYPT_MODULES): Set to @GCRYPT_CIPHERS@,
@GCRYPT_PUBKEY_CIPHERS@, @GCRYPT_DIGESTS@ and @GCRYPT_RANDOM@.
(libcipher_la_DEPENDENCIES): Set to $(GCRYPT_MODULES).
(libcipher_la_LIBADD): Likewise.
(AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
(EXTRA_libcipher_la_SOURCES): Added all conditional sources.
* md.c (md_open): Use _gcry_fast_random_poll instead of
fast_random_poll.
* cipher.c (gcry_cipher_open): Likewise.
* random.h (fast_random_poll): Removed macro.
* blowfish.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, sha512.c,
tiger.c: Use Autoconf's WORDS_BIGENDIAN instead of our own
BIG_ENDIAN_HOST.
2003-06-16 Moritz Schulte <moritz@g10code.com>
* random.c (getfnc_gather_random): Do not special-case
USE_ALL_RANDOM_MODULES, make it the default.
* dsa.c: Replace last occurences of old type names with newer
names (i.e. replace MPI with gcry_mpi_t).
* elgamal.c: Likewise.
* primegen.c: Likewise.
* pubkey.c: Likewise.
* rsa.c: Likewise.
2003-06-14 Moritz Schulte <moritz@g10code.com>
* des.c (des_setkey): Add selftest check.
(tripledes_set3keys): Likewise.
(do_tripledes_setkey): Remove selftest check.
(do_des_setkey): Likewise.
2003-06-11 Moritz Schulte <moritz@g10code.com>
* md.c (_gcry_md_init): New function.
* cipher.c (_gcry_cipher_init): New function.
* pubkey.c (_gcry_pk_init): New function.
2003-06-13 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_get_algo): Reverted to old API. This is a
convenience function anyway and error checking is not approriate.
(gcry_md_is_secure): New.
(gcry_md_is_enabled): New.
2003-06-12 Werner Koch <wk@gnupg.org>
* cipher.c (gcry_cipher_open): Make sure HANDLE is set to NULL on
error.
2003-06-11 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_open): Make sure H receives either NULL or an
valid handle.
(gcry_md_copy): Swapped arguments so that it is more in lione with
md_open and most other API fucntions like memcpy (destination
comes first). Make sure HANDLE is set to NULL on error.
* rijndael.c (do_encrypt): Hack to force correct alignment. It
seems not to be not sufficient, though. We should rework this
fucntions and remove all these ugly casts. Let the compiler
optimize or have an assembler implementation.
2003-06-09 Moritz Schulte <moritz@g10code.com>
* Makefile.am: Removed rules serpent, since that is not commited
yet.
2003-06-08 Moritz Schulte <moritz@g10code.com>
* pubkey.c (gcry_pk_encrypt): Improve calculation for size of the
format string.
2003-06-07 Moritz Schulte <moritz@g10code.com>
* arcfour.c, bithelp.h, blowfish.c, cast5.c, cipher.c, crc.c,
des.c, dsa.c, elgamal.c, md4.c, md5.c, md.c, primegen.c, pubkey.c,
rand-internal.h, random.c, random.h, rijndael.c, rmd160.c,
rmd160test.c, rmd.h, rndeged.c, rndlinux.c, rndunix.c, rndw32.c,
rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c: Edited all
preprocessor instructions to remove whitespace before the '#'.
This is not required by C89, but there are some compilers out
there that don't like it. Replaced any occurence of the now
deprecated type names with the new ones.
2003-06-04 Moritz Schulte <moritz@g10code.com>
* pubkey.c (gcry_pk_encrypt): Construct an arg_list and use
gcry_sexp_build_array instead of gcry_sexp_build.
(gcry_pk_sign): Likewise.
(gcry_pk_genkey): Likewise.
2003-06-01 Moritz Schulte <moritz@g10code.com>
* dsa.c (_gcry_dsa_generate): Do not check wether the algorithm ID
does indeed belong to DSA.
(_gcry_dsa_sign): Likewise.
(_gcry_dsa_verify): Likewise.
(_gcry_dsa_get_nbits): Likewise.
* elgamal.c (_gcry_elg_check_secret_key): Do not check wether the
algorithm ID does indeed belong to ElGamal.
(_gcry_elg_encrypt): Likewise.
(_gcry_elg_decrypt): Likewise.
(_gcry_elg_sign): Likewise.
(_gcry_elg_verify): Likewise.
(_gcry_elg_get_nbits): Likewise.
(_gcry_elg_generate): Likewise.
* rsa.c (_gcry_rsa_generate): Do not check wether the algorithm ID
does indeed belong to RSA.
(_gcry_rsa_encrypt): Likewise.
(_gcry_rsa_decrypt): Likewise.
(_gcry_rsa_sign): Likewise.
(_gcry_rsa_verify): Likewise.
(_gcry_rsa_get_nbits): Likewise.
2003-05-30 Moritz Schulte <moritz@g10code.com>
* md.c (md_get_algo): Return zero in case to algorithm is enabled.
* md.c (gcry_md_info): Adjusted for new no-errno-API.
(md_final): Likewise.
(gcry_md_get_algo): Likewise.
* pubkey.c (gcry_pk_get_keygrip): Likewise.
(gcry_pk_ctl): Likewise.
(gcry_pk_algo_info): Likewise.
* des.c (selftest): Likewise.
2003-05-29 Moritz Schulte <moritz@g10code.com>
* md.c (md_enable): Do not forget to release module on error.
(gcry_md_open): Adjusted for new no-errno-API.
(md_open): Likewise.
(md_copy): Likewise.
(gcry_md_copy): Likewise.
(gcry_md_setkey): Likewise.
(gcry_md_algo_info): Likewise.
* cipher.c (gcry_cipher_open): Adjusted for new no-errno-API and
also fixed a locking bug.
(gcry_cipher_encrypt): Adjusted for new no-errno-API.
(gcry_cipher_decrypt): Likewise.
(gcry_cipher_ctl): Likewise.
(gcry_cipher_info): Likewise.
(gcry_cipher_algo_info): Likewise.
2003-05-28 Moritz Schulte <moritz@g10code.com>
* md.c (md_enable): Adjusted for libgpg-error.
(gcry_md_enable): Likewise.
(gcry_digest_register_default): Likewise.
(gcry_digest_register): Likewise.
(check_digest_algo): Likewise.
(prepare_macpads): Likewise.
(gcry_md_setkey): Likewise.
(gcry_md_ctl): Likewise.
(gcry_md_get): Likewise.
(gcry_md_algo_info): Likewise.
(gcry_md_info): Likewise.
* dsa.c (_gcry_dsa_generate): Likewise.
(_gcry_dsa_check_secret_key): Likewise.
(_gcry_dsa_sign): Likewie.
(_gcry_dsa_verify): Likewise.
* twofish.c (do_twofish_setkey): Likewise.
(twofish_setkey): Likewise.
* cipher.c (gcry_cipher_register): Likewise.
2003-05-25 Moritz Schulte <moritz@g10code.com>
* rijndael.c (do_setkey): Adjusted for libgpg-error.
(rijndael_setkey): Likewise.
* random.c (gcry_random_add_bytes): Likewise.
* elgamal.c (_gcry_elg_generate): Likewise.
(_gcry_elg_check_secret_key): Likewise.
(_gcry_elg_encrypt): Likewise.
(_gcry_elg_decrypt): Likewise.
(_gcry_elg_sign): Likewise.
(_gcry_elg_verify): Likewise.
* rsa.c (_gcry_rsa_generate): Likewise.
(_gcry_rsa_check_secret_key): Likewise.
(_gcry_rsa_encrypt): Likewise.
(_gcry_rsa_decrypt): Likewise.
(_gcry_rsa_sign): Likewise.
(_gcry_rsa_verify): Likewise.
* pubkey.c (dummy_generate, dummy_check_secret_key, dummy_encrypt,
dummy_decrypt, dummy_sign, dummy_verify): Likewise.
(gcry_pubkey_register): Likewise.
(check_pubkey_algo): Likewise.
(pubkey_generate): Likewise.
(pubkey_check_secret_key): Likewise.
(pubkey_encrypt): Likewise.
(pubkey_decrypt): Likewise.
(pubkey_sign): Likewise.
(pubkey_verify): Likewise.
(sexp_elements_extract): Likewise.
(sexp_to_key): Likewise.
(sexp_to_sig): Likewise.
(sexp_to_enc): Likewise.
(sexp_data_to_mpi): Likewise.
(gcry_pk_encrypt): Likewise.
(gcry_pk_decrypt): Likewise.
(gcry_pk_sign): Likewise.
(gcry_pk_verify): Likewise.
(gcry_pk_testkey): Likewise.
(gcry_pk_genkey): Likewise.
(gcry_pk_ctl): Likewise.
* cipher.c (dummy_setkey): Likewise.
(check_cipher_algo): Likewise.
(gcry_cipher_open): Likewise.
(cipher_setkey): Likewise.
(gcry_cipher_ctl): Likewise.
(cipher_encrypt): Likewise.
(gcry_cipher_encrypt): Likewise.
(cipher_decrypt): Likewise.
(gcry_cipher_decrypt): Likewise.
(gcry_cipher_info): Likewise.
(gcry_cipher_algo_info): Likewise.
* cast5.c (cast_setkey): Likewise.
(do_cast_setkey): Likewise.
* arcfour.c (arcfour_setkey): Likewise.
(do_arcfour_setkey): Likewise.
* blowfish.c (do_bf_setkey): Likewise.
(bf_setkey): Likewise.
* des.c (do_des_setkey): Likewise.
(do_tripledes_setkey): Likewise.
2003-05-22 Moritz Schulte <moritz@g10code.com>
* tiger.c: Merged code ussing the U64_C macro from GnuPG.
* sha512.c: Likewise.
2003-05-17 Moritz Schulte <moritz@g10code.com>
* pubkey.c (gcry_pk_genkey): Fix type: acquire a lock, instead of
releasing it.
2003-05-11 Moritz Schulte <moritz@g10code.com>
* pubkey.c (gcry_pk_testkey): Call REGISTER_DEFAULT_CIPHERS.
(gcry_pk_ctl): Likewise.
2003-04-27 Moritz Schulte <moritz@g10code.com>
* pubkey.c (gcry_pk_genkey): Release sexp after extracted data has
been used.
* md.c (gcry_md_get_algo_dlen): Simplified, simply call
md_digest_length to do the job.
* des.c (do_des_setkey): Check for selftest failure not only
during initialization.
(do_tripledes_setkey): Include check for selftest failure.
* pubkey.c (gcry_pubkey_register_default): New macro
`pubkey_use_dummy', use it.
* elgamal.c (elg_names): New variable.
(pubkey_spec_elg): Include elg_names.
* dsa.c (dsa_names): New variable.
(pubkey_spec_dsa): Include dsa_names.
* rsa.c (rsa_names): New variable.
(pubkey_spec_rsa): Include rsa_names.
* pubkey.c (gcry_pubkey_lookup_func_name): Compare name also with
the names listed in `sexp_names'.
2003-04-24 Moritz Schulte <moritz@g10code.com>
* pubkey.c (sexp_to_key): New variables: module, pubkey. Adjusted
to new module interface.
(sexp_to_key): Changend type of argument `retalgo' from `int *' to
`GcryModule **'. Adjusted all callers. Removed argument:
r_algotblidx.
(sexp_to_sig): Changend type of argument `retalgo' from `int *' to
`GcryModule **'. Adjusted all callers.
(sexp_to_enc): Likewise.
(pubkey_get_npkey, pubkey_get_nskey, pubkey_get_nsig,
pubkey_get_nenc): Use strlen to find out the number.
* rsa.c: Adjust pubkey_spec_rsa to new internal interface.
* dsa.c: Likewise.
* elgamal.c: Likewise.
2003-04-17 Moritz Schulte <moritz@g10code.com>
* pubkey.c (sexp_elements_extract): New function.
* pubkey.c (sexp_to_key): Removed variable `idx', added `err', use
sexp_elements_extract.
(sexp_to_sig): Likewise.
(sexp_to_enc): Likewise.
* pubkey.c: Terminate list correctly.
* md.c: Include sha512/sha384 in digest_table.
2003-04-16 Moritz Schulte <moritz@g10code.com>
* Makefile.am: Include support for sha512.c.
* sha512.c: New file, merged from GnuPG, with few modifications
for libgcrypt.
* rand-internal.h: Removed declarations for constructor functions.
* md.c (md_copy): Call _gcry_module_use for incrementing the usage
counter of the digest modules.
* rsa.c: Do not include "rsa.h".
* dsa.c: Do not include "dsa.h".
* elgamal.c: Do not include "elgamal.h".
* des.c: Do not include "des.h".
* cast5.c: Do not include "cast5.h".
* blowfish.c: Do not include "blowfish.h".
* arcfour.c: Do not include "arcfour.h".
* Makefile.am (libcipher_la_DEPENDENCIES): Removed.
(libcipher_la_LIBADD): Removed.
Use Automake conditionals for conditional compilation.
2003-04-13 Moritz Schulte <moritz@g10code.com>
* cipher.c (gcry_cipher_open): Call REGISTER_DEFAULT_CIPHERS.
* md.c (gcry_md_list): New member: module.
(md_enable): New variable: module, changed use of module and
digest.
(md_enable): Initialize member: module.
(md_close): Call _gcry_module_release.
* cipher.c (gcry_cipher_open): New variable: module, changed use of
module and cipher.
(struct gcry_cipher_handle): New member: module.
(gcry_cipher_open): Initialize member: module.
(gcry_cipher_close): Call _gcry_module_release.
2003-04-09 Moritz Schulte <moritz@g10code.com>
* cipher.c: Include "ath.h".
* md.c: Likewise.
* pubkey.c: Likewise.
* cipher.c (ciphers_registered_lock): New variable.
* md.c (digests_registered_lock): New variable.
* pubkey.c (pubkeys_registered_lock): New variable.
* rndlinux.c (gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func): Removed function.
(_gcry_rndlinux_constructor): Removed function.
* rndegd.c (gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func): Removed function.
(_gcry_rndegd_constructor): Removed function.
* rndunix.c (gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func): Removed function.
(_gcry_rndunix_constructor): Removed function.
* rndw32.c (gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func): Removed function.
(_gcry_rndw32_constructor): Removed function.
* rndegd.c (rndegd_connect_socket): Simplify code for creating the
egd socket address.
(rndegd_connect_socket): Call log_fatal use instead of
g10_log_fatal.
(egd_gather_random): Renamed to ...
(rndegd_gather_random): ... here.
2003-04-08 Moritz Schulte <moritz@g10code.com>
* rndlinux.c: Do not include "dynload.h".
* rndunix.c: Likewise.
* rndw32.c: Likewise.
* rndegd.c (rndegd_connect_socket): Factored out from ...
(egd_gather_random): here; call it.
(egd_socket): New variable.
(egd_gather_random): Initialize fd with egd_socket, do not declare
fd static.
(do_read): Merged few changes from GnuPG. FIXME - not finished?
Do not include "dynload.h".
* rndw32.c (gather_random): Renamed to rndw32_gather_random, do
not declare static.
(gather_random_fast): Renamed to rndw32_gather_random_fast, do not
declare static.
* rndunix.c (gather_random): Renamed to rndunix_gather_random, do
not declare static.
* rndegd.c (gather_random): Renamed to rndegd_gather_random, do
not declare static.
* rndlinux.c (gather_random): Renamed to rndlinux_gather_random,
do not declare static.
2003-04-07 Moritz Schulte <moritz@g10code.com>
* Makefile.am (libcipher_la_SOURCES): Removed construct.c.
(libcipher_la_SOURCES): Added sha1.c, sha256.c, rmd160.c, md4.c,
md5.c, tiger.c and crc.c
(EXTRA_PROGRAMS): Removed sha1, sha256, rmd160, md4, md5, tiger
and crc. Removed definitions: EXTRA_md4_SOURCES,
EXTRA_md5_SOURCES, EXTRA_rmd160_SOURCES, EXTRA_sha1_SOURCES,
EXTRA_sha256_SOURCES, EXTRA_tiger_SOURCES and EXTRA_crc_SOURCES,
BUILT_SOURCES, DISTCLEANFILES.
* pubkey.c: Do not include "elgamal.h", "dsa.h" and "rsa.h".
* Makefile.am (libcipher_la_SOURCES): Removed rsa.h, elgamal.h,
dsa.h, des.h, cast5.h, arcfour.h and blowfish.h.
* rsa.h: Removed file.
* elgamal.h: Removed file.
* dsa.h: Removed file.
* des.h: Removed file.
* cast5.h: Removed file.
* arcfour.h: Removed file.
* blowfish.h: Removed file.
* Makefile.am (libcipher_la_SOURCES): Removed dynload.c and
dynload.h.
* rsa.c (pubkey_spec_rsa): New variable.
* dsa.c (pubkey_spec_rsa): New variable.
* elgamal.c (pubkey_spec_elg): New variable.
* rsa.c (_gcry_rsa_get_info): Removed function.
* elgamal.c (_gcry_elg_get_info): Removed function.
* dsa.c (_gcry_dsa_get_info): Removed function.
* tiger.c (tiger_get_info): Removed function.
(gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func): Removed function.
(_gcry_tiger_constructor): Removed function.
* sha1.c (sha1_get_info): Removed function.
(gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func): Removed function.
(_gcry_sha1_constructor): Removed function.
* sha256.c (sha256_get_info): Removed function.
(gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func): Removed function.
(_gcry_sha256_constructor): Removed function.
* rmd160.c (rmd160_get_info): Removed function.
(gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func): Removed function.
(_gcry_rmd160_constructor): Removed function.
* md5.c (md5_get_info): Removed function.
(gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func): Removed function.
(_gcry_md5_constructor): Removed function.
* md4.c (md4_get_info): Removed function.
(gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func): Removed function.
(_gcry_md4_constructor): Removed function.
* crc.c (crc_get_info): Removed function.
* arcfour.c (do_arcfour_setkey): Changed type of context argument
to `void *', added local variable for cast, adjusted callers.
(arcfour_setkey): Likewise.
(encrypt_stream): Likewise.
* cast5.c (cast_setkey): Likewise.
(encrypt_block): Likewise.
* rijndael.c (rijndael_setkey): Likewise.
(rijndael_encrypt): Likewise.
(rijndael_decrypt): Likewise.
* twofish.c (twofish_setkey): Likewise.
(twofish_encrypt): Likewise.
(twofish_decrypt): Likewise.
* des.c (do_des_setkey): Likewise.
(do_des_encrypt): Likewise.
(do_des_encrypt): Likewise.
(do_tripledes_encrypt): Likewise.
(do_tripledes_encrypt): Likewise.
* blowfish.c (bf_setkey: Likewise.
(encrypt_block): Likewise.
(decrypt_block): Likewise.
* arcfour.c (encrypt_stream): Likewise.
* rijndael.c (gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func) Removed function.
* twofish.c (gnupgext_version, func_table): Removed definitions.
(gnupgext_enum_func) Removed function.
* cast5.c (CIPHER_ALGO_CAST5): Removed.
* blowfish.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
(CIPHER_ALGO_BLOWFISH): Removed symbol.
* cast5.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Likewise.
* des.c (selftest_failed): Removed.
(initialized): New variable.
(do_des_setkey): Run selftest, if not yet done.
(FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
* arcfour.c (_gcry_arcfour_get_info): Removed function.
* blowfish.c (_gcry_blowfish_get_info): Removed function.
* cast5.c (_gcry_cast5_get_info): Removed function.
* des.c (_gcry_des_get_info): Removed function.
* rijndael.c (_gcry_rijndael_get_info): Removed function.
* twofish.c (_gcry_twofish_get_info): Removed function.
* arcfour.c (cipher_spec_arcfour): New variable.
* twofish.c (cipher_spec_twofish, cipher_spec_twofish128): New
variables.
* rijndael.c (cipher_spec_aes, cipher_spec_aes192,
cipher_spec256): New variables.
* des.c (cipher_spec_des, cipher_spec_tripledes): New variables.
* cast5.c (cipher_spec_cast5): New variable.
* blowfish.c (cipher_spec_blowfish): Likewise.
* twofish.c: Do not include "dynload.h".
* rijndael.c: Likewise.
* des.c: Likewise.
* cast5.c: Likewise.
* blowfish.c: Likewise.
* cipher.c: Likewise.
* crc.c: Likewise.
* md4.c: Likewise.
* md5.c: Likewise.
* md.c: Likewise.
* pubkey.c: Likewise.
* rijndael.c: Likewise.
* sha1.c: Likewise.
* sha256.c: Likewise.
* arcfour.c: Include "cipher.h".
* twofish.c: Likewise.
* rijndael.c: Likewise.
* des.c: Likewise.
* cast5.c: Likewise.
* blowfish.c: Likewise.
* twofish.c (twofish_setkey): Declared argument `key' const.
(twofish_encrypt): Declared argument `inbuf' const.
(twofish_decrypt): Likewise.
* rijndael.c (rijndael_setkey): Declared argument `key' const.
(rijndael_encrypt): Declared argument `inbuf' const.
(rijndael_decrypt): Likewise.
* des.c (do_des_setkey): Declared argument `key' const.
(do_tripledes_setkey): Likewise.
(do_des_encrypt): Declared argument `inbuf' const.
(do_des_decrypt): Likewise.
(do_tripledes_encrypt): Likewise.
(do_tripledes_decrypt): Likewise.
* cast5.c (encrypt_block): Declared argument `inbuf' const.
(decrypt_block): Likewise.
(cast_setkey): Declared argument `key' const.
* blowfish.c (do_bf_setkey): Declared argument `key' const.
(encrypt_block): Declared argument `inbuf' const.
(encrypt_block): Likewise.
* cipher.c: Remove CIPHER_ALGO_DUMMY related code.
Removed struct cipher_table_s.
Changed definition of cipher_table.
Removed definition of disabled_algos.
(ciphers_registered, default_ciphers_registered): New variables.
(REGISTER_DEFAULT_CIPHERS): New macro.
(dummy_setkey): Declared argument `key' const.
(dummy_encrypt_block): Declared argument `inbuf' const.
(dummy_encrypt_block): Likewise.
(dummy_encrypt_stream): Likewise.
(dummy_encrypt_stream): Likewise.
(dummy_setkey): Use `unsigned char' instead of `byte'.
(dummy_encrypt_block): Likewise.
(dummy_decrypt_block): Likewise.
(dummy_encrypt_stream): Likewise.
(dummy_decrypt_stream): Likewise.
(gcry_cipher_register_default): New function.
(gcry_cipher_lookup_func_id): New function.
(gcry_cipher_lookup_func_name): New function.
(gcry_cipher_lookup_id): New function.
(gcry_cipher_lookup_name): New function.
(gcry_cipher_id_new): New function.
(gcry_cipher_register): New function.
(gcry_cipher_unregister): New function.
(setup_cipher_table): Removed function.
(load_cipher_modules): Removed function.
(gcry_cipher_map_name): Adjusted to use new module management.
(cipher_algo_to_string): Likewise.
(disable_cipher_algo): Likewise.
(check_cipher_algo): Likewise.
(cipher_get_keylen): Likewise.
(cipher_get_blocksize): Likewise.
(gcry_cipher_open): Likewise.
(struct gcry_cipher_handle): Replaced members algo, algo_index,
blocksize, setkey, encrypt, decrypt, stencrypt, stdecrypt with one
member: cipher.
(gcry_cipher_open): Adjusted code for new handle structure.
(cipher_setkey): Likewise.
(cipher_setiv): Likewise.
(cipher_reset): Likewise.
(do_ecb_encrypt): Likewise.
(do_ecb_decrypt): Likewise.
(do_cbc_encrypt): Likewise.
(do_cbc_decrypt): Likewise.
(do_cfb_encrypt): Likewise.
(do_cfb_decrypt): Likewise.
(do_ctr_encrypt): Likewise.
(cipher_encrypt): Likewise.
(gcry_cipher_encrypt): Likewise.
(cipher_decrypt): Likewise.
(gcry_cipher_decrypt): Likewise.
(cipher_sync): Likewise.
(gcry_cipher_ctl): Likewise.
* pubkey.c: Removed struct pubkey_table_s.
Changed definition of pubkey_table.
Removed definition of disabled_algos.
(pubkeys_registered, default_pubkeys_registered): New variables.
(REGISTER_DEFAULT_PUBKEYS): New macro.
(setup_pubkey_table): Removed function.
(load_pubkey_modules): Removed function.
(gcry_pubkey_register_default): New function.
(gcry_pubkey_lookup_func_id): New function.
(gcry_pubkey_lookup_func_name): New function.
(gcry_pubkey_lookup_id): New function.
(gcry_pubkey_lookup_name): New function.
(gcry_pubkey_id_new): New function.
(gcry_pubkey_register): New function.
(gcry_pubkey_unregister): New function.
(gcry_pk_map_name): Adjusted to use new module management.
(gcry_pk_algo_name): Likewise.
(disable_pubkey_algo): Likewise.
(check_pubkey_algo): Likewise.
(pubkey_get_npkey): Likewise.
(pubkey_get_nskey): Likewise.
(pubkey_get_nsig): Likewise.
(pubkey_get_nenc): Likewise.
(pubkey_generate): Likewise.
(pubkey_check_secret_key): Likewise.
(pubkey_encrypt): Likewise.
(pubkey_decrypt): Likewise.
(pubkey_sign): Likewise.
(pubkey_verify): Likewise.
(gcry_pk_get_nbits): Likewise.
(gcry_pk_algo_info): Likewise.
* md.c: Removed struct md_digest_list_s.
(digest_list): Changed definition.
(digests_registered, default_digests_registered): New variables.
(REGISTER_DEFAULT_DIGESTS): New macro.
(new_list_item): Removed function.
(setup_md_table): Removed function.
(load_digest_module): Removed function.
(gcry_digest_register_default): New function.
(gcry_digest_lookup_func_id): New function.
(gcry_digest_lookup_func_name): New function.
(gcry_digest_lookup_id): New function.
(gcry_digest_lookup_name): New function.
(gcry_digest_id_new): New function.
(gcry_digest_register): New function.
(gcry_digest_unregister): New function.
(GcryDigestEntry): New type.
(struct gcry_md_context): Adjusted type of `list'.
(gcry_md_map_name): Adjusted to use new module management.
(digest_algo_to_string): Likewise.
(check_digest_algo): Likewise.
(md_enable): Likewise.
(md_digest_length): Likewise.
(md_asn_oid): Likewise.
2003-04-07 Moritz Schulte <moritz@g10code.com>
* pubkey.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA,
PUBKEY_ALGO_RSA with GCRY_PK_RSA and PUBKEY_ALGO_ELGAMAL with
GCRY_PK_ELG.
* dsa.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA.
2003-04-01 Moritz Schulte <moritz@g10code.com>
* des.c: Removed checks for GCRY_CIPHER_3DES and GCRY_CIPHER_DES.
2003-03-31 Moritz Schulte <moritz@g10code.com>
* tiger.c (tiger_get_info): Do not declare static.
* sha256.c (sha256_get_info): Likewise.
* sha1.c (sha1_get_info): Likewise.
* rmd160.c (rmd160_get_info): Likewise.
* md5.c (md5_get_info): Likewise.
* md4.c (md4_get_info): Likewise.
* crc.c (crc_get_info): Likewise.
* md.c (load_digest_module): Call setup_md_table during
initialization.
(new_list_item): Link new element into digest_list.
* cipher.c (do_ctr_decrypt): Made do_ctr_encrypt act as a wrapper
for do_ctr_encrypt, since these functions are identical.
2003-03-30 Simon Josefsson <jas@extundo.com>
* cipher.c (struct gcry_cipher_handle): Add counter field.
(gcry_cipher_open): Add CTR.
(cipher_reset): Clear counter field.
(do_ctr_encrypt, do_ctr_decrypt): New functions.
(cipher_encrypt, cipher_decrypt): Call CTR functions.
(gcry_cipher_ctl): Add SET_CTR to set counter.
2003-03-30 Moritz Schulte <moritz@g10code.com>
* rsa.c (_gcry_rsa_blind): New function.
(_gcry_rsa_unblind): New function.
(_gcry_rsa_decrypt): Use _gcry_rsa_blind and _gcry_rsa_decrypt.
2003-03-26 Moritz Schulte <moritz@g10code.com>
* dynload.c (_gcry_enum_gnupgext_pubkeys): Adjust `encrypt' and
`decrypt' function arguments.
(_gcry_enum_gnupgext_pubkeys): Likewise.
* dynload.h: Likewise.
* pubkey.c (dummy_decrypt): Add argument: int flags.
(dummy_encrypt): Likewise.
* elgamal.c (_gcry_elg_encrypt): Add argument: int flags.
(_gcry_elg_decrypt): Likewise.
* rsa.c (_gcry_rsa_encrypt): Add argument: int flags.
(_gcry_rsa_decrypt): Likewise.
* pubkey.c: Add `flags' argument to members `encrypt' and
`decrypt' of struct `pubkey_table_s'.
* rsa.h: Add `flags' argument to function declarations.
* elgamal.h: Likewise.
* pubkey.c (sexp_data_to_mpi): New variable: int parsed_flags.
(sexp_data_to_mpi): Set `parsed_flags'.
(sexp_data_to_mpi): New argument: int *flags.
(gcry_pk_encrypt): New variable: int flags.
(gcry_pk_encrypt): Pass `flags' to pubkey_encrypt.
(pubkey_encrypt): New variable: int flags.
(pubkey_encrypt): Pass `flags' to pubkey encrypt function.
(pubkey_decrypt): Likewise.
(pubkey_decrypt): Pass `flags' to pubkey encrypt function.
(gcry_pk_encrypt): Include `flags' s-exp in return list.
(sexp_to_enc): New argument: int *flags.
(gcry_pk_decrypt): New variable: int flags.
(gcry_pk_decrypt): Pass `flags' to pubkey_decrypt.
(sexp_to_enc): New variable: int parsed_flags.
(sexp_to_enc): Set `parsed_flags'.
2003-03-22 Simon Josefsson <jas@extundo.com>
* cipher.c (gcry_cipher_open, do_cbc_encrypt)
(gcry_cipher_encrypt): Support GCRY_CIPHER_CBC_MAC.
(gcry_cipher_ctl): Support GCRYCTL_SET_CBC_MAC.
2003-03-19 Werner Koch <wk@gnupg.org>
* primegen.c (gen_prime): New args EXTRA_CHECK and EXTRA_CHECK_ARG
to allow for a user callback. Changed all callers.
(_gcry_generate_secret_prime)
(_gcry_generate_public_prime): Ditto, pass them to gen_prime.
* rsa.c (check_exponent): New.
(generate): Use a callback to ensure that a given exponent is
actually generated.
2003-03-12 Moritz Schulte <moritz@g10code.com>
* primegen.c: Initialize `no_of_small_prime_numbers' statically.
(gen_prime): Remove calculation of `no_of_small_prime_numbers'.
2003-03-03 Moritz Schulte <moritz@g10code.com>
* md.c (gcry_md_ctl): Rewritten to use same style like the other
functions dispatchers.
2003-03-02 Moritz Schulte <moritz@g10code.com>
* cipher.c (struct gcry_cipher_handle): New member: algo_index.
(gcry_cipher_open): Allocate memory for two cipher contexts.
Initialize algo_index.
(cipher_setkey): Duplicate context into reserved memory.
(cipher_reset): New function, which resets the context and clear
the IV.
(gcry_cipher_ctl): Call cipher_reset.
2003-02-23 Moritz Schulte <moritz@g10code.com>
* cipher.c: Remove (bogus) `digitp' macro definition.
* md.c: Likewise.
* blowfish.c (burn_stack): Removed.
* arcfour.c (burn_stack): Likewise.
* cast5.c (burn_stack): Likewise.
* des.c (burn_stack): Likewise.
* md4.c (burn_stack): Likewise.
* md5.c (burn_stack): Likewise.
* random.c (burn_stack): Likewise.
* rijndael.c (burn_stack): Likewise.
* rmd160.c (burn_stack): Likewise.
* sha1.c (burn_stack): Likewise.
* sha256.c (burn_stack): Likewise.
* tiger.c (burn_stack): Likewise.
* twofish.c (burn_stack): Likewise.
* blowfish.c: Changed all occurences of burn_stack to
_gcry_burn_stack.
* arcfour.c: Likewise.
* cast5.c: Likewise.
* des.c: Likewise.
* md4.c: Likewise.
* md5.c: Likewise.
* random.c: Likewise.
* rijndael.c: Likewise.
* rmd160.c: Likewise.
* sha1.c: Likewise.
* sha256.c: Likewise.
* tiger.c: Likewise.
* twofish.c: Likewise.
* arcfour.c (_gcry_arcfour_get_info): Use GCRY_CIPHER_ARCFOUR
instead of hard-coded value `301'.
2003-01-24 Werner Koch <wk@gnupg.org>
* random.c (_gcry_register_random_progress): New.
(_gcry_random_progress): New.
* rndlinux.c (gather_random): Call the random progress function.
2003-01-23 Werner Koch <wk@gnupg.org>
* rsa.c (generate): New arg USE_E to request a specific public
exponent.
(_gcry_rsa_generate): Ditto.
* elgamal.c (_gcry_elg_generate): Must add an dummy argument
instead of USE_E.
* dsa.c (_gcry_dsa_generate): Ditto.
* pubkey.c (dummy_generate): Ditto.
(pubkey_generate): Add USE_E arg and pass it down.
(gcry_pk_genkey): Detect "rsa-use-e" parameter and pass it to generate.
* pubkey.c (sexp_to_enc): New arg RET_MODERN.
(gcry_pk_decrypt): Make use of it to return a real S-expression.
Return better error codes.
(gcry_pk_verify): Return better error codes.
2003-01-21 Werner Koch <wk@gnupg.org>
* random.c (gcry_random_add_bytes): Add QUALITY argument, let
function return an error code and disable its core for now.
2003-01-21 Timo Schulz <twoaday@freakmail.de>
* random.c (gcry_random_add_bytes): New. Function to add external
random to the pool.
2003-01-20 Simon Josefsson <jas@extundo.com>
* crc.c: New.
* Makefile.am (EXTRA_PROGRAMS, EXTRA_crc_SOURCES): Add crc.c.
* md.c (gcry_md_get_algo_dlen): Add values for CRC.
2003-01-20 Werner Koch <wk@gnupg.org>
* sha256.c: New.
* bithelp.h (ror): New.
* Makfile.am: Add sha256.c.
* md.c (oid_table): Add values for SHA256 et al.
(gcry_md_get_algo_dlen): Likewise
2003-01-20 Werner Koch <wk@gnupg.org>
* pubkey.c (gcry_pk_get_keygrip): Implemented keygrips for DSA
and ElGamal.
2003-01-17 Werner Koch <wk@gnupg.org>
* cipher.c (gcry_cipher_encrypt): Reworked so that the output will
never contain the plaintext even if the caller did not checked the
return value.
* md.c (gcry_md_get_algo): Changed error code to GCRYERR_GENERAL
because we don't have an invalid md algo but no algorithm enabled.
* pubkey.c (gcry_pk_genkey): Changed error code for bounds check
of table parameters to GCRYERR_INTERNAL.
* md.c (gcry_md_open): Partly reverted Timo's change from
2002-10-10 by removing the check for the algorithm. An algorithm
of 0 is allowed and anyway we should not double check it or check
it using a different function. Also fixed the flags check.
* pubkey.c (gcry_pk_encrypt): Make sure that R_CIPH points to NULL
on error.
(gcry_pk_decrypt): Ditto for R_PLAIN.
(gcry_pk_sign): Ditto for R_SIG.
(gcry_pk_genkey): Ditto for R_KEY.
2003-01-16 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_write): Changed 2nd argument type to void*.
(gcry_md_hash_buffer): Changed type of boths buffers to void*.
(gcry_md_setkey): Changed 2nd argument type to void*.
2003-01-15 Werner Koch <wk@gnupg.org>
* pubkey.c (sexp_data_to_mpi): New. This handles pkcs1 padding.
(gcry_pk_sign, gcry_pk_verify): Use it here.
(gcry_pk_encrypt): And here.
(pubkey_verify): Add debug code.
(sexp_to_enc): Handle flags in the input and return the pkcs1 flag
in a new parameter.
(gcry_pk_decrypt): Prepare for future pkcs1 handling.
2002-12-19 Werner Koch <wk@gnupg.org>
* random.c (_gcry_random_initialize): New.
2002-12-16 Werner Koch <wk@gnupg.org>
* cipher.c: Added a Teletrust specific OID for 3DES.
2002-12-12 Werner Koch <wk@gnupg.org>
* md.c: Added another oddball OIW OID (sha-1WithRSAEncryption).
2002-11-23 Werner Koch <wk@gnupg.org>
* md.c (load_digest_module): Enlarged checked_algos bitmap.
* md4.c (func_table): Fixed entry for md4.
Both by Simon Josephson.
(transform): Copy data to get the alignment straight. Tested only
on i386.
2002-11-10 Simon Josefsson <jas@extundo.com>
* cipher.c (gcry_cipher_open): Don't reject CTS flag.
(do_cbc_encrypt, do_cbc_decrypt, cipher_encrypt)
(gcry_cipher_encrypt, cipher_decrypt)
(gcry_cipher_decrypt): Support CTS flag.
(gcry_cipher_ctl): Toggle CTS flag.
2002-11-10 Werner Koch <wk@gnupg.org>
* md4.c: New. By Simon Josefsson.
* Makefile.am (EXTRA_PROGRAMS): Add md4.c.
* md.c (oid_table,gcry_md_get_algo_dlen): MD4 support.
2002-10-14 Werner Koch <wk@gnupg.org>
* arcfour.c (do_encrypt_stream): Don't use increment op when
assigning to the same variable.
2002-10-10 Timo Schulz <ts@winpt.org>
* pubkey.c (gcry_pk_genkey): Check boundaries.
* md.c (gcry_md_open): Check that algo is available and only
valid flag values are used.
(gcry_md_get_algo): Add error handling.
2002-09-26 Werner Koch <wk@gnupg.org>
* md.c: Include an OID for TIGER.
* tiger.c (tiger_get_info): Use a regular OID.
2002-09-17 Werner Koch <wk@gnupg.org>
* random.c: Replaced mutex.h by the new ath.h. Changed all calls.
2002-09-16 Werner Koch <wk@gnupg.org>
* arcfour.c (do_encrypt_stream): Use register modifier and modulo.
According to Nikos Mavroyanopoulos this increases perfromace on
i386 system noticable. And I always tought gcc is clever enough.
* md5.c (transform): Use register modifier.
* rmd160.c (transform): Ditto.
* sha1.c (transform): Ditto. We hope that there are 6 free registers.
* random.c (gcry_randomize): Rewrote to avoid malloc calls.
* rndlinux.c (gather_random): Replaced remaining fprintfs by log_*.
* arcfour.c (do_arcfour_setkey): Ditto.
* twofish.c (do_twofish_setkey): Ditto.
* rndegd.c (gather_random): Ditto.
* rijndael.c (do_setkey): Ditto.
* random.c (_gcry_random_dump_stats): Ditto.
* primegen.c (_gcry_generate_elg_prime): Ditto.
* des.c (_gcry_des_get_info): Ditto.
* cast5.c (do_cast_setkey): Ditto.
* blowfish.c (do_bf_setkey): Ditto.
2002-08-26 Werner Koch <wk@gnupg.org>
* des.c (weak_keys): Fixed one entry in the table and compared
all entries against the literature.
(selftest): Checksum the weak key table.
2002-08-21 Werner Koch <wk@gnupg.org>
* pubkey.c: Enable keygrip calculation for "openpgp-rsa".
2002-08-17 Werner Koch <wk@gnupg.org>
* cipher.c (setup_cipher_table): Don't overwrite the DES entry
with the entry for DUMMY.
2002-08-14 Werner Koch <wk@gnupg.org>
* des.c (do_des_setkey,do_des_encrypt, do_des_decrypt): New.
(_gcry_des_get_info): Support plain old DES.
* cipher.c (setup_cipher_table): Put DES into the table.
2002-07-25 Werner Koch <wk@gnupg.org>
* rndunix.c (_gcry_rndunix_constructor): Prefixed with _gcry_.
Noted by Stephan Austermuehle.
2002-07-08 Timo Schulz <ts@winpt.org>
* rndw32.c: Replaced the m_ memory functions with the real
gcry_ functions. Renamed all g10_ prefixed functions to log_.
2002-06-12 Werner Koch <wk@gnupg.org>
* rsa.c (generate): Use e = 65537 for now.
2002-06-11 Werner Koch <wk@gnupg.org>
* pubkey.c (gcry_pk_get_keygrip): Allow a "protected-private-key".
2002-06-05 Timo Schulz <ts@winpt.org>
* cipher.c (gcry_cipher_encrypt, gcry_cipher_decrypt):
Check that the input size is a multiple of the blocksize.
2002-05-23 Werner Koch <wk@gnupg.org>
* md.c (oid_table): Add an rsadsi OID for MD5.
2002-05-21 Werner Koch <wk@gnupg.org>
* primegen.c, elgamal.c, dsa.c (progress): Do not print anything
by default. Pass an extra identifying string to the callback and
reserved 2 argumenst for current and total counters. Changed the
register function prototype.
2002-05-17 Werner Koch <wk@gnupg.org>
* rndegd.c (rndegd_constructor): Fixed name of register function
and prefixed the function name with _gcry_.
* rndw32.c (rndw32_constructor): Ditto.
* tiger.c (tiger_constructor): Ditto.
* Makefile.am: Removed all dynamic loading stuff.
* dynload.c: Ditto. Now only used for the constructor system.
2002-05-15 Werner Koch <wk@gnupg.org>
* random.c (gcry_random_bytes,gcry_random_bytes_secure)
(gcry_randomize): Make sure we are initialized.
2002-05-14 Werner Koch <wk@gnupg.org>
Changed license of most files to the LGPL.
2002-05-02 Werner Koch <wk@gnupg.org>
* random.c (_gcry_fast_random_poll): Initialize the module so the
mutex can be used.
* primegen.c (small_prime_numbers): Moved table from smallprime.c
* smallprime.c: File removed.
* des.c (leftkey_swap, rightkey_swap, working_memcmp): Made static.
* cipher.c (gcry_cipher_map_name): Map "RIJNDAEL" to "AES".
* rijndael.c (rijndael_get_info): We do only support a 128 bit
blocksize so it makes sense to change the algorithm strings to
AES.
* tiger.c (tiger_final): Removed superfluous token pasting operators.
* md5.c (md5_final): Ditto.
2002-04-30 Werner Koch <wk@gnupg.org>
* cipher.c: Fixed list of copyright years.
2002-03-18 Werner Koch <wk@gnupg.org>
* random.c (initialize): Initialize the new pool lock mutex.
(_gcry_fast_random_poll): Add locking and moved main
code out to...
(do_fast_random_poll): new function.
(read_pool): Use the new function here.
(get_random_bytes): Add locking.
(_gcry_update_random_seed_file): Ditto.
2002-03-11 Werner Koch <wk@gnupg.org>
* md.c: Add rsaSignatureWithripemd160 to OID table.
2002-02-20 Werner Koch <wk@gnupg.org>
* sha1.c: Removed a left over comment note. The code has been
rewritten from scratch in 1998. Thanks to Niels Möller for
reporting this misleading comment.
2002-02-18 Werner Koch <wk@gnupg.org>
* rndunix.c (rndunix_constructor): Use the the new prefixed
function name. Reported by Jordi Mallach.
2002-02-10 Werner Koch <wk@gnupg.org>
* random.c (mix_pool): Carry an extra failsafe_digest buffer
around to make the function more robust.
2002-02-08 Werner Koch <wk@gnupg.org>
* random.c (add_randomness): Xor new data into the pool and not
just copy it. This avoids any choosen input attacks which are not
serious in our setting because an outsider won't be able to mix
data in and even then we keep going with a PRNG. Thanks to Stefan
Keller for pointing this out.
2002-01-04 Werner Koch <wk@gnupg.org>
* pubkey.c (gcry_pk_genkey): Do not release skey - it is static.
* primegen.c (gen_prime): Of course we should use set_bit
and not set_highbit to set the second high bit.
2001-12-18 Werner Koch <wk@gnupg.org>
* rsa.c (generate): Loop until we find the exact modulus size.
Changed the exponent to 41.
(rsa_get_info): s/usage/r_usage/ to avoid shadow warnings.
* primegen.c (gen_prime): Set 2 high order bits for secret primes.
* Makefile.am (DISTCLEANFILES): Include construct.c.
2001-12-17 Werner Koch <wk@gnupg.org>
* pubkey.c (gcry_pk_get_keygrip): New - experimental.
2001-12-11 Werner Koch <wk@gnupg.org>
* cipher.c: Added OIDs for AES.
(gcry_cipher_mode_from_oid): New.
(gcry_cipher_map_name): Moved OID search code to ..
(search_oid): .. new function.
2001-12-10 Werner Koch <wk@gnupg.org>
* pubkey.c (gcry_pk_encrypt): Find the signature algorithm by name
and not by number.
* pubkey.c (gcry_pk_encrypt,gcry_pk_decrypt,gcry_pk_sign)
(gcry_pk_verify,gcry_pk_testkey, gcry_pk_genkey)
(gcry_pk_get_nbits): Release the arrays. Noted by Nikos
Mavroyanopoulos.
2001-12-06 Werner Koch <wk@gnupg.org>
* cipher.c (gcry_cipher_map_name): Look also for OIDs prefixed
with "oid." or "OID.".
2001-12-05 Werner Koch <wk@gnupg.org>
* pubkey.c (algo_info_table): Fixed entry for openpgp-rsa.
2001-11-24 Werner Koch <wk@gnupg.org>
* pubkey.c: Added the rsaEncryption OID to the tables.
(sexp_to_key): Add an arg to return the index of the algorithm,
changed all callers.
(gcry_pk_sign): Find the signature algorithm by name and not by
number.
(gcry_pk_get_nbits): Fixed so that we can now really pass a secret
key to get the result.
* md.c (gcry_md_map_name): Look also for OIDs prefixed with "oid."
or "OID." so that an OID string can be used as an S-Exp token.
2001-11-20 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_map_name): Lookup by OID if the the name begins
with a digit.
(oid_table): New.
2001-11-16 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_info): New operator GCRYCTL_IS_ALGO_ENABLED.
2001-11-07 Werner Koch <wk@gnupg.org>
* md.c (gcry_md_hash_buffer): Close the handle which was left open
for algorithms other than rmd160.
2001-08-08 Werner Koch <wk@gnupg.org>
* rndw32.c (gather_random): Use toolhelp in addition to the NT
gatherer for Windows2000. Suggested by Sami Tolvanen.
* random.c (read_pool): Fixed length check, this used to be one
byte to strict. Made an assert out of it because the caller has
already made sure that only poolsize bytes are requested.
Reported by Marcus Brinkmann.
2001-08-03 Werner Koch <wk@gnupg.org>
* cipher.c (cipher_encrypt, cipher_decrypt): Prepare to return
errors. We have to change the interface to all ciphers to make
this really work but we should do so to prepare for hardware
encryption modules.
(gcry_cipher_encrypt, gcry_cipher_decrypt): Return the error and
set lasterr.
(gcry_cipher_ctl): Make sure that errors from setkey are returned.
2001-08-02 Werner Koch <wk@gnupg.org>
* rndlinux.c (gather_random): casted a size_t arg to int so that
the format string is correct. Casting is okay here and avoids
translation changes.
* random.c (fast_random_poll): Do not check the return code of
getrusage.
* rndunix.c: Add a signal.h header to avoid warnings on Solaris 7
and 8.
* tiger.c (print_abc,print_data): Removed.
* rijndael.c, des.c, blowfish.c, twofish.c, cast5.c, arcfour.c
(burn_stack): New. Add wrappers for most functions to be able to
call burn_stack after the function invocation. This methods seems
to be the most portable way to zeroise the stack used. It does
only work on stack frame based machines but it is highly portable
and has no side effects. Just setting the automatic variables at
the end of a function to zero does not work well because the
compiler will optimize them away - marking them as volatile would
be bad for performance.
* md5.c, sha1.c, rmd160.c, tiger.c (burn_stack): Likewise.
* random.c (burn_stack): New.
(mix_pool): Use it here to burn the stack of the mixblock function.
* primegen.c (_gcry_generate_elg_prime): Freed q at 3 places.
Thanks to Tommi Komulainen.
* arcfour.c (arcfour_setkey): Check the minimim keylength against
bytes and not bits.
(selftest): Must reset the key before decryption.
2001-05-31 Werner Koch <wk@gnupg.org>
* sha1.c (sha1_init): Made static.
Changed all g10_ prefixed function names as well as some mpi_
function names to cope with the introduced naming changes.
* md.c (prepare_macpads): Made key const.
2001-05-28 Werner Koch <wk@gnupg.org>
* rndegd.c (gather_random): Removed the use of tty_printf.
2001-03-29 Werner Koch <wk@gnupg.org>
* md5.c (md5_final): Fixed calculation of hashed length. Thanks
to disastry@saiknes.lv for pointing out that it was horrible wrong
for more than 512MB of input.
* sha1.c (sha1_final): Ditto.
* rmd160.c (rmd160_final): Ditto.
* tiger.c (tiger_final): Ditto.
* blowfish.c (encrypt,do_encrypt): Changed name to do_encrypt to
avoid name clashes with an encrypt function in stdlib.h of
Dynix/PIX. Thanks to Gene Carter.
* elgamal.c (encrypt,do_encrypt): Ditto.
* twofish.c (gnupgext_enum_func): Use only when when compiled as a
module.
* rijndael.c (gnupgext_enum_func): Ditto.
* tiger.c (tiger_get_info): Return "TIGER192" and not just
"TIGER". By Edwin Woudt.
* random.c: Always include time.h - standard requirement. Thanks
to James Troup.
* rndw32.c: Fixes to the macros.
2001-01-11 Werner Koch <wk@gnupg.org>
* cipher.c (cipher_encrypt,gcry_cipher_encrypt): Use blocksize and
not 8.
2000-12-19 Werner Koch <wk@gnupg.org>
Major change:
Removed all GnuPG stuff and renamed this piece of software
to gcrypt.
2000-11-14 Werner Koch <wk@gnupg.org>
* dsa.c (test_keys): Replaced mpi_alloc by gcry_mpi_new and
mpi_free by gcry_mpi_release.
* elgamal.c (test_keys,generate): Ditto, also for mpi_alloc_secure.
* rsa.c (test_keys,generate,rsa_verify): Ditto.
* primegen.c (generate_elg_prime): Ditto.
(gen_prime): Ditto and removed nlimbs.
* rsa.c (generate): Allocate 2 more vars in secure memory.
* Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
problems.
2000-10-09 Werner Koch <wk@gnupg.org>
* arcfour.c, arcfour.h: New.
* cipher.c (cipher_encrypt, cipher_decrypt): Add stream mode.
(setup_cipher_table): Add Arcfour.
(gcry_cipher_open): Kludge to allow stream mode.
Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
* sha1.c (transform): Use rol() macro. Actually this is not needed
for a newer gcc but there are still aoter compilers.
* rsa.c (test_keys): Use new random function.
* md.c (gcry_md_setkey): New function to overcome problems with
const conflics.
(gcry_md_ctl): Pass set key to the new functions.
* rijndael.c: New.
* cipher.c: Add Rijndael support.
Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
* rndlinux.c (open_device): Loose random device checking.
By Nils Ellmenreich.
* random.c (fast_random_poll): Check ENOSYS for getrusage.
* rndunix.c: Add 2 sources for QNX. By Sam Roberts.
* pubkey.c (gcry_pk_algo_info): Add GCRYCTL_GET_ALGO_USAGE.
* rsa.c: Changed the comment about the patent.
(secret): Speed up by using the CRT. For a 2k keys this
is about 3 times faster.
(stronger_key_check): New but unused code to check the secret key.
* Makefile.am: Included rsa.[ch].
* pubkey.c: Enabled RSA support.
(pubkey_get_npkey): Removed RSA workaround.
Mon Jul 31 10:04:47 CEST 2000 Werner Koch <wk@openit.de>
* pubkey.c: Replaced all gcry_sexp_{car,cdr}_{data,mpi} by the new
gcry_sexp_nth_{data,mpi} functions.
Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
* pubkey.c (exp_to_key,sexp_to_sig,sexp_to_enc,gcry_pk_encrypt,
gcry_pk_decrypt,gcry_pk_sign,gcry_pk_genkey): Changed to work with
the new S-Exp interface.
Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
* random.c (gather_faked): Replaced make_timestamp by time(2) again.
Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
* md.c (gcry_md_ctl): Support GCRYCTL_{START,STOP}_DUMP.
* Makefile.am: Never compile mingw32 as module.
* Makefile.am: Tweaked module build and removed libtool
* Makefile.am: Replaced -O1 by -O. Suggested by Alec Habig.
* elgamal.c (sign): Removed inactive code.
* rsa.c, rsa.h: New based on the old module version (only in CVS for now).
* pubkey.c (setup_pubkey_table): Added commented support for RSA.
* rndunix.c (waitpid): New. For UTS 2.1. All by Dave Dykstra.
(my_popen): Do the FD_CLOEXEC only if it is available
(start_gatherer): Cope with missing _SC_OPEN_MAX
* rndunix.c: Add some more headers for QNX. By Sam Roberts.
* rndegd.c (gather_random): Shortcut level 0.
* rndunix.c (gather_random): Ditto.
* rndw32.c (gather_random): Ditto.
* rndw32.c: Replaced with code from Cryptlib and commented the old stuff.
* rndw32.c: Add some debuging code enabled by an environment variable.
* random.c (read_seed_file): Binary open for DOSish system
(update_random_seed_file): Ditto.
* random.c [MINGW32]: Include process.h for getpid.
* random.c (fast_random_poll): Add clock_gettime() as fallback for
system which support this POSIX.4 fucntion. By Sam Roberts.
* random.c (read_seed_file): Removed the S_ISLNK test becuase it
is already covered by !S_ISREG and is not defined in Unixware.
Reported by Dave Dykstra.
(update_random_seed_file): Silently ignore update request when pool
is not filled.
* random.c (read_seed_file): New.
(set_random_seed_file): New.
(read_pool): Try to read the seeding file.
(update_random_seed_file): New.
(read_pool): Do an initial extra seeding when level 2 quality random
is requested the first time. This requestes at least POOLSIZE/2 bytes
of entropy. Compined with the seeding file this should make normal
random bytes cheaper and increase the quality of the random bytes
used for key generation.
* random.c (read_pool): Print a more friendly error message in
cases when too much random is requested in one call.
* random.c (fast_random_poll): Check whether RUSAGE_SELF is defined;
this is not the case for some ESIX and Unixware, although they have
getrusage().
* primegen.c (generate_elg_prime): All primes are now generated with
the lowest random quality level. Because they are public anyway we
don't need stronger random and by this we do not drain the systems
entropy so much.
* primegen.c (register_primegen_progress): New.
* dsa.c (register_pk_dsa_progress): New.
* elgamal.c (register_pk_elg_progress): New.
* elgamal.c (wiener_map): New.
(gen_k): Use a much smaller k.
(generate): Calculate the qbits using the wiener map and
choose an x at a size comparable to the one choosen in gen_k
* rmd160.c (rmd160_get_info): Moved casting to the left side due to a
problem with UTS4.3. Suggested by Dave Dykstra.
* sha1.c (sha1_get_info): Ditto.
* tiger.c (tiger_get_info): Ditto.
* md5.c (md5_get_info): Ditto
* des.c (des_get_info): Ditto.
* blowfish.c (blowfish_get_info): Ditto.
* cast5.c (cast5_get_info): Ditto.
* twofish.c (twofish_get_info): Ditto.
Fri Mar 24 11:25:45 CET 2000 Werner Koch <wk@openit.de>
* md.c (md_open): Add hmac arg and allocate space for the pads.
(md_finalize): Add HMAC support.
(md_copy): Ditto.
(md_close): Ditto.
(gcry_md_reset): Ditto.
(gcry_md_ctl): Ditto.
(prepare_macpdas): New.
Mon Mar 13 19:22:46 CET 2000 Werner Koch <wk@openit.de>
* md.c (gcry_md_hash_buffer): Add support for the other algorithms.
Mon Jan 31 16:37:34 CET 2000 Werner Koch <wk@gnupg.de>
* genprime.c (generate_elg_prime): Fixed returned factors which never
worked for non-DSA keys.
Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
* pubkey.c (sexp_to_key): Fixed mem leaks in case of errors.
Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
* pubkey.c (gcry_pk_decrypt): Implemented.
(gcry_pk_encrypt): Implemented.
(gcry_pk_testkey): New.
(gcry_pk_genkey): New.
(pubkey_decrypt): Made static.
(pubkey_encrypt): Ditto.
(pubkey_check_secret_key): Ditto.
(pubkey_generate): Ditto.
Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
* pubkey.c (pubkey_nbits): Removed and replaced by ...
(gcry_pk_get_nbits): this new one.
Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
* dsa.c: s/mpi_powm/gcry_mpi_powm/g
* elgamal.c: Ditto.
* primegen.c: Ditto.
* : Replaced g10_opt_verbose by g10_log_verbosity().
* Makefile.am (INCLUDES): removed intl, add ../gcrypt
Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
* dynload.c (cmp_filenames): New to replaced compare_filename() in
module.
(register_cipher_extension): Removed the tilde expansion stuff.
* rndeg.c (my_make_filename): New.
* : Replaced header util.h by g10lib.h
* random.c (gather_faked): Replaced make_timestamp by time(2).
Disabled wrning printed with tty_printf.
* rndlinux.c (gather_random): Always use fprintf instead of tty_xxx;
this should be replaced by a callback function.
* primegen.c (gen_prime): Use gcry_mpi_randomize.
(is_prime): Ditto.
* elgamal.c (test_keys): Ditto.
* dsa.c (test_keys): Ditto.
* cipher.c (gcry_cipher_close): Die on invalid handle.
Mon Nov 15 21:36:02 CET 1999 Werner Koch <wk@gnupg.de>
* elgamal.c (gen_k): Use the new random API.
(generate): Ditto.
* dsa.c (gen_k): Ditto.
(generate): Ditto.
Sat Nov 13 17:44:23 CET 1999 Werner Koch <wk@gnupg.de>
* pubkey.c (disable_pubkey_algo): Made static.
(gcry_pk_ctl): New.
* random.c (get_random_bits): Renamed to ...
(get_random_bytes): ... this and made static.
(gcry_random_bytes): New.
(gcry_random_bytes_secure): New.
(randomize_buffer): Renamed to ...
(gcry_randomize): ...this.
* md.c (gcry_md_hash_buffer): New.
* pubkey.c (gcry_pk_algo_info): 4 new commands.
(pubkey_get_npkey): Made static.
(pubkey_get_nskey): Made static.
(pubkey_get_nsig): Made static.
(pubkey_get_nenc): Made static.
* pubkey.c: Removed all G10ERR_xxx.
* cipher.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_CIPHER_ALGO.
* md.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_MD_ALGO.
* cast5.c (cast_setkey): Changed errocodes to GCRYERR_xxx.
* blowfish.c: Ditto.
* des.c: Ditto.
* twofish.c: Ditto.
* dsa.c: Ditto.
* elgamal.c: Ditto.
* g10c.c: Removed
* cipher.c (gcry_cipher_open): Replaced alloc functions and return NULL
if we are out of core.
* dynload.c: Replaced all memory allocation functions.
* md.c: Ditto.
* primegen.c: Ditto.
* pubkey.c: Ditto.
* random.c: Ditto.
* rndw32.c: Ditto.
* elgamal.c: Ditto.
* dsa.c: Ditto.
Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
* elgamal.c (sign): Hugh found strange code here. Replaced by BUG().
* cipher.c: Merged with gcrypt/symapi.c.
* pubkey.c (string_to_pubkey_algo): Renamed function to ...
(gcry_pk_map_name): ... this.
(pubkey_algo_to_string): Renamed function to ...
(gcry_pk_algo_name): ... this.
(gcry_pk_algo_info): New.
* pubkey.c: Merged with gcrypt/pkapi.c.
* md.c (md_reset): Clear finalized; thanks to Ulf Moeller for
fixing this bug.
* md.c: Merged with gcrypt/mdapi.c
Wed Sep 15 14:39:59 CEST 1999 Michael Roth <mroth@nessie.de>
* des.c: Various speed improvements: One bit pre rotation
trick after initial permutation (Richard Outerbridge).
Finished test of SSLeay Tripple-DES patterns.
Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* rndw32.c: New.
Mon Sep 13 10:51:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* bithelp.h: New.
* rmd160.h, sha1.h, md5.h: Use the rol macro from bithelp.h
Tue Sep 7 16:23:36 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am: Fixed seds for latest egcc. By Ollivier Robert.
Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* des.c (selftest): Add some testpattern
Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* cipher.c (do_cbc_encrypt): Fixed serious bug occuring when not using
in place encryption. Pointed out by Frank Stajano.
Mon Jul 26 09:34:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* md5.c (md5_final): Fix for a SCO cpp bug.
Thu Jul 15 10:15:35 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* elgamal.c (elg_check_secret_key,elg_encrypt
elg_decrypt,elg_sign,elg_verify): Sanity check on the args.
* dsa.c (dsa_check_secret_key,dsa_sign,dsa_verify): Ditto.
* pubkey.c (disable_pubkey_algo): New.
(check_pubkey_algo2): Look at disabled algo table.
* cipher.c (disable_cipher_algo): New.
(check_cipher_algo): Look at disabled algo table.
Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am: Support for libtool.
Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* dsa.c (gen_k): Changed algorithm to consume less random bytes
* elgamal.c (gen_k): Ditto.
* random.c (random_dump_stats): New.
Thu Jul 1 12:47:31 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* primegen.c, elgamal.c, dsa.c (progess): New and replaced all
fputc with a call to this function.
Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* rndegd.c (do_write): s/ssize_t/int/ due to SunOS 4.1 probs.
* cipher.c (do_cbc_encrypt, do_cbc_decrypt): New.
* dynload.c (HAVE_DL_SHL_LOAD): Map hpux API to dlopen (Dave Dykstra).
* Makefile.am (install-exec-hook): Removed.
Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* cipher.c (setup_cipher_table): Enable Twofish
* random.c (fast_random_poll): Disable use of times() for mingw32.
Mon May 17 21:54:43 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* dynload.c (register_internal_cipher_extension): Minor init fix.
Tue May 4 15:47:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* primegen.c (gen_prime): Readded the Fermat test. Fixed the bug
that we didn't correct for step when passing the prime to the
Rabin-Miller test which led to bad performance (Stefan Keller).
(check_prime): Add a first Fermat test.
Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* cipher.c (cipher_setiv): Add ivlen arg, changed all callers.
* random.c (randomize_buffer): alway use secure memory because
we can't use m_is_secure() on a statically allocated buffer.
* twofish.c: Replaced some macros by a loop to reduce text size.
* Makefile.am (twofish): No more need for sed editing.
Fri Apr 9 12:26:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* cipher.c (cipher_open): Reversed the changes for AUTO_CFB.
* blowfish.c: Dropped the Blowfish 160 mode.
* cipher.c (cipher_open): Ditto.
(setup_cipher_table): Ditto. And removed support of twofish128
Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* random.c (get_random_bits): Can now handle requests > POOLSIZE
* cipher.c (cipher_open): Now uses standard CFB for automode if
the blocksize is gt 8 (according to rfc2440).
* twofish.c: Applied Matthew Skala's patches for 256 bit key.
Tue Apr 6 19:58:12 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* random.c (get_random_bits): Can now handle requests > POOLSIZE
* cipher.c (cipher_open): Now uses standard CFB for automode if
the blocksize is gt 8 (according to rfc2440).
Sat Mar 20 11:44:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* rndlinux.c (tty_printf) [IS_MODULE]: Removed.
* rndegd.c (gather_random): Some fixes.
Wed Mar 17 13:09:03 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* rndegd.c (do_read): New.
(gather_random): Changed the implementation.
Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* dynload.c (DLSYM_NEEDS_UNDERSCORE): Renamed.
Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* md.c: Nearly a total rewrote.
Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* cipher.c (context): Fixed alignment
* md.c: Ditto.
* rndegd.c: New
Mon Feb 22 20:04:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* rndegd.c: New.
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am: Modules are now figured out by configure
* construct.c: New. Generated by configure. Changed all modules
to work with that.
* sha1.h: Removed.
* md5.h: Removed.
* twofish.c: Changed interface to allow Twofish/256
* rndunix.c (start_gatherer): Die on SIGPIPE.
Wed Jan 20 18:59:49 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* rndunix.c (gather_random): Fix to avoid infinite loop.
Sun Jan 17 11:04:33 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* des.c (is_weak_key): Replace system memcmp due to bugs
in SunOS's memcmp.
(des_get_info): Return error on failed selftest.
* twofish.c (twofish_setkey): Return error on failed selftest or
invalid keylength.
* cast5.c (cast_setkey): Ditto.
* blowfish.c (bf_setkey): Return error on failed selftest.
Tue Jan 12 11:17:18 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* random.c (random_is_faked): New.
* tiger.c: Only compile if we have the u64 type
Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* rndunix.c (gather_random): check for setuid.
* Makefile.am: Add a way to staically link random modules
Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* md.c (md_stop_debug): Do a flush first.
(md_open): size of buffer now depends on the secure parameter
Sun Jan 3 15:28:44 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* rndunix.c (start_gatherer): Fixed stupid ==/= bug
1998-12-31 Geoff Keating <geoffk@ozemail.com.au>
* des.c (is_weak_key): Rewrite loop end condition.
Tue Dec 29 14:41:47 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* random.c: add unistd.h for getpid().
(RAND_MAX): Fallback value for Sun.
Wed Dec 23 17:12:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* md.c (md_copy): Reset debug.
Mon Dec 14 21:18:49 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* random.c (read_random_source): Changed the interface to the
random gathering function.
(gather_faked): Use new interface.
* dynload.c (dynload_getfnc_fast_random_poll): Ditto.
(dynload_getfnc_gather_random): Ditto.
* rndlinux.c (gather_random): Ditto.
* rndunix.c (gather_random): Ditto.
Sat Dec 12 18:40:32 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* dynload.c (SYMBOL_VERSION): New to cope with system which needs
underscores.
* rndunix.c: Rewrote large parts
Thu Dec 10 20:15:36 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
* dynload.c (load_extension): increased needed verbosity level.
* random.c (fast_random_poll): Fallback to a default fast random
poll function.
(read_random_source): Always use the faked entroy gatherer if no
gather module is available.
* rndlinux.c (fast_poll): Removed.
* rndunix.c (fast_poll): Removed.
Wed Nov 25 12:33:41 1998 Werner Koch (wk@isil.d.shuttle.de)
* rand-*.c: Removed.
* rndlinux.c : New.
* rndunix.c : New.
* random.c : Restructured the interface to the gather modules.
(intialize): Call constructor functions
(read_radnom_source): Moved to here.
* dynload.c (dynload_getfnc_gather_random): New.
(dynload_getfnc_fast_random_poll): New.
(register_internal_cipher_extension): New.
(register_cipher_extension): Support of internal modules.
Sun Nov 8 17:44:36 1998 Werner Koch (wk@isil.d.shuttle.de)
* rand-unix.c (read_random_source): Removed the assert.
Mon Oct 19 18:34:30 1998 me,,, (wk@tobold)
* pubkey.c: Hack to allow us to give some info about RSA keys back.
Thu Oct 15 11:47:57 1998 Werner Koch (wk@isil.d.shuttle.de)
* dynload.c: Support for DLD
Wed Oct 14 12:13:07 1998 Werner Koch (wk@isil.d.shuttle.de)
* rand-unix.c: Now uses names from configure for /dev/random.
1998-10-10 SL Baur <steve@altair.xemacs.org>
* Makefile.am: fix sed -O substitutions to catch -O6, etc.
Tue Oct 6 10:06:32 1998 Werner Koch (wk@isil.d.shuttle.de)
* rand-unix.c (HAVE_GETTIMEOFDAY): Fixed (was ..GETTIMEOFTIME :-)
* rand-dummy.c (HAVE_GETTIMEOFDAY): Ditto.
Mon Sep 28 13:23:09 1998 Werner Koch (wk@isil.d.shuttle.de)
* md.c (md_digest): New.
(md_reset): New.
Wed Sep 23 12:27:02 1998 Werner Koch (wk@isil.d.shuttle.de)
* tiger.c (TIGER_CONTEXT): moved "buf", so that it is 64 bit aligned.
Mon Sep 21 06:22:53 1998 Werner Koch (wk@(none))
* des.c: Some patches from Michael.
Thu Sep 17 19:00:06 1998 Werner Koch (wk@(none))
* des.c : New file from Michael Roth <mroth@nessie.de>
Mon Sep 14 11:10:55 1998 Werner Koch (wk@(none))
* blowfish.c (bf_setkey): Niklas Hernaeus patch to detect weak keys.
Mon Sep 14 09:19:25 1998 Werner Koch (wk@(none))
* dynload.c (RTLD_NOW): Now defined to 1 if it is undefined.
Mon Sep 7 17:04:33 1998 Werner Koch (wk@(none))
* Makefile.am: Fixes to allow a different build directory
Thu Aug 6 17:25:38 1998 Werner Koch,mobil,,, (wk@tobold)
* random.c (get_random_byte): Removed and changed all callers
to use get_random_bits()
Mon Jul 27 10:30:22 1998 Werner Koch (wk@(none))
* cipher.c : Support for other blocksizes
(cipher_get_blocksize): New.
* twofish.c: New.
* Makefile.am: Add twofish module.
Mon Jul 13 21:30:52 1998 Werner Koch (wk@isil.d.shuttle.de)
* random.c (read_pool): Simple alloc if secure_alloc is not set.
(get_random_bits): Ditto.
Thu Jul 9 13:01:14 1998 Werner Koch (wk@isil.d.shuttle.de)
* dynload.c (load_extension): Function now nbails out if
the program is run setuid.
Wed Jul 8 18:58:23 1998 Werner Koch (wk@isil.d.shuttle.de)
* rmd160.c (rmd160_hash_buffer): New.
Thu Jul 2 10:50:30 1998 Werner Koch (wk@isil.d.shuttle.de)
* cipher.c (cipher_open): algos >=100 use standard CFB
Thu Jun 25 11:18:25 1998 Werner Koch (wk@isil.d.shuttle.de)
* Makefile.am: Support for extensions
Thu Jun 18 12:09:38 1998 Werner Koch (wk@isil.d.shuttle.de)
* random.c (mix_pool): simpler handling for level 0
Mon Jun 15 14:40:48 1998 Werner Koch (wk@isil.d.shuttle.de)
* tiger.c: Removed from dist, will reappear as dynload module
Sat Jun 13 14:16:57 1998 Werner Koch (wk@isil.d.shuttle.de)
* pubkey.c: Major changes to allow extensions. Changed the inteface
of all public key ciphers and added the ability to load extensions
on demand.
* misc.c: Removed.
Wed Jun 10 07:52:08 1998 Werner Koch,mobil,,, (wk@tobold)
* dynload.c: New.
* cipher.c: Major changes to allow extensions.
Mon Jun 8 22:43:00 1998 Werner Koch (wk@isil.d.shuttle.de)
* cipher.c: Major internal chnages to support extensions.
* blowfish.c (blowfish_get_info): New and made all internal
functions static, changed heder.
* cast5.c (cast5_get_info): Likewise.
Mon Jun 8 12:27:52 1998 Werner Koch (wk@isil.d.shuttle.de)
* tiger.c (transform): Fix for big endian
* cipher.c (do_cfb_decrypt): Big endian fix.
Fri May 22 07:30:39 1998 Werner Koch (wk@isil.d.shuttle.de)
* md.c (md_get_oid): Add a new one for TIGER.
Thu May 21 13:24:52 1998 Werner Koch (wk@isil.d.shuttle.de)
* cipher.c: Add support for a dummy cipher
Thu May 14 15:40:36 1998 Werner Koch (wk@isil.d.shuttle.de)
* rmd160.c (transform): fixed sigbus - I should better
add Christian von Roques's new implemenation of rmd160_write.
Fri May 8 18:07:44 1998 Werner Koch (wk@isil.d.shuttle.de)
* rand-internal.h, rand-unix.c, rand-w32.c, rand_dummy.c: New
* random.c: Moved system specific functions to rand-****.c
Fri May 8 14:01:17 1998 Werner Koch (wk@isil.d.shuttle.de)
* random.c (fast_random_poll): add call to gethrtime.
Tue May 5 21:28:55 1998 Werner Koch (wk@isil.d.shuttle.de)
* elgamal.c (elg_generate): choosing x was not correct, could
yield 6 bytes which are not from the random pool, tsss, tsss..
Tue May 5 14:09:06 1998 Werner Koch (wk@isil.d.shuttle.de)
* primegen.c (generate_elg_prime): Add arg mode, changed all
callers and implemented mode 1.
Mon Apr 27 14:41:58 1998 Werner Koch (wk@isil.d.shuttle.de)
* cipher.c (cipher_get_keylen): New.
Sun Apr 26 14:44:52 1998 Werner Koch (wk@isil.d.shuttle.de)
* tiger.c, tiger.h: New.
Wed Apr 8 14:57:11 1998 Werner Koch (wk@isil.d.shuttle.de)
* misc.c (check_pubkey_algo2): New.
Tue Apr 7 18:46:49 1998 Werner Koch (wk@isil.d.shuttle.de)
* cipher.c: New
* misc.c (check_cipher_algo): Moved to cipher.c
* cast5.c: Moved many functions to cipher.c
* blowfish.c: Likewise.
Sat Apr 4 19:52:08 1998 Werner Koch (wk@isil.d.shuttle.de)
* cast5.c: Implemented and tested.
Wed Apr 1 16:38:27 1998 Werner Koch (wk@isil.d.shuttle.de)
* elgamal.c (elg_generate): Faster generation of x in some cases.
Thu Mar 19 13:54:48 1998 Werner Koch (wk@isil.d.shuttle.de)
* blowfish.c (blowfish_decode_cfb): changed XOR operation
(blowfish_encode_cfb): Ditto.
Thu Mar 12 14:04:05 1998 Werner Koch (wk@isil.d.shuttle.de)
* sha1.c (transform): Rewrote
* blowfish.c (encrypt): Unrolled for rounds == 16
(decrypt): Ditto.
Tue Mar 10 16:32:08 1998 Werner Koch (wk@isil.d.shuttle.de)
* rmd160.c (transform): Unrolled the loop.
Tue Mar 10 13:05:14 1998 Werner Koch (wk@isil.d.shuttle.de)
* random.c (read_pool): Add pool_balance stuff.
(get_random_bits): New.
* elgamal.c (elg_generate): Now uses get_random_bits to generate x.
Tue Mar 10 11:33:51 1998 Werner Koch (wk@isil.d.shuttle.de)
* md.c (md_digest_length): New.
Tue Mar 10 11:27:41 1998 Werner Koch (wk@isil.d.shuttle.de)
* dsa.c (dsa_verify): Works.
Mon Mar 9 12:59:08 1998 Werner Koch (wk@isil.d.shuttle.de)
* dsa.c, dsa.h: Removed some unused code.
Wed Mar 4 10:39:22 1998 Werner Koch (wk@isil.d.shuttle.de)
* md.c (md_open): Add call to fast_random_poll.
blowfish.c (blowfish_setkey): Ditto.
Tue Mar 3 13:32:54 1998 Werner Koch (wk@isil.d.shuttle.de)
* rmd160.c (rmd160_mixblock): New.
* random.c: Restructured to start with a new RNG implementation.
* random.h: New.
Mon Mar 2 19:21:46 1998 Werner Koch (wk@isil.d.shuttle.de)
* gost.c, gost.h: Removed because they did only conatin trash.
Sun Mar 1 16:42:29 1998 Werner Koch (wk@isil.d.shuttle.de)
* random.c (fill_buffer): removed error message if n == -1.
Fri Feb 27 16:39:34 1998 Werner Koch (wk@isil.d.shuttle.de)
* md.c (md_enable): No init if called twice.
Thu Feb 26 07:57:02 1998 Werner Koch (wk@isil.d.shuttle.de)
* primegen.c (generate_elg_prime): Changed the progress printing.
(gen_prime): Ditto.
Tue Feb 24 12:28:42 1998 Werner Koch (wk@isil.d.shuttle.de)
* md5.c, md.5 : Replaced by a modified version of md5.c from
GNU textutils 1.22.
Wed Feb 18 14:08:30 1998 Werner Koch (wk@isil.d.shuttle.de)
* md.c, md.h : New debugging support
Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de)
* misc.c (cipher_algo_to_string): New
(pubkey_algo_to_string): New.
(digest_algo_to_string): New.
Copyright 1998,1999,2000,2001,2002,2003 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.
diff --git a/cipher/cipher.c b/cipher/cipher.c
index 087a3478..03b17525 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -1,1399 +1,1500 @@
/* cipher.c - cipher dispatcher
* Copyright (C) 1998, 1999, 2000, 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
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "g10lib.h"
#include "cipher.h"
#include "ath.h"
#define MAX_BLOCKSIZE 16
#define TABLE_SIZE 14
#define CTX_MAGIC_NORMAL 0x24091964
#define CTX_MAGIC_SECURE 0x46919042
/* This is the list of the default ciphers, which are included in
libgcrypt. */
static struct cipher_table_entry
{
gcry_cipher_spec_t *cipher;
unsigned int algorithm;
} cipher_table[] =
{
#if USE_BLOWFISH
{ &_gcry_cipher_spec_blowfish, GCRY_CIPHER_BLOWFISH },
#endif
#if USE_DES
{ &_gcry_cipher_spec_des, GCRY_CIPHER_DES },
{ &_gcry_cipher_spec_tripledes, GCRY_CIPHER_3DES },
#endif
#if USE_ARCFOUR
{ &_gcry_cipher_spec_arcfour, GCRY_CIPHER_ARCFOUR },
#endif
#if USE_CAST5
{ &_gcry_cipher_spec_cast5, GCRY_CIPHER_CAST5 },
#endif
#if USE_AES
{ &_gcry_cipher_spec_aes, GCRY_CIPHER_AES },
{ &_gcry_cipher_spec_aes192, GCRY_CIPHER_AES192 },
{ &_gcry_cipher_spec_aes256, GCRY_CIPHER_AES256 },
#endif
#if USE_TWOFISH
{ &_gcry_cipher_spec_twofish, GCRY_CIPHER_TWOFISH },
{ &_gcry_cipher_spec_twofish128, GCRY_CIPHER_TWOFISH128 },
#endif
#if USE_SERPENT
{ &_gcry_cipher_spec_serpent128, GCRY_CIPHER_SERPENT128 },
{ &_gcry_cipher_spec_serpent192, GCRY_CIPHER_SERPENT192 },
{ &_gcry_cipher_spec_serpent256, GCRY_CIPHER_SERPENT256 },
#endif
#ifdef USE_RFC2268
{ &_gcry_cipher_spec_rfc2268_40, GCRY_CIPHER_RFC2268_40 },
#endif
{ NULL },
};
/* List of registered ciphers. */
static gcry_module_t ciphers_registered;
/* This is the lock protecting CIPHERS_REGISTERED. */
static ath_mutex_t ciphers_registered_lock = ATH_MUTEX_INITIALIZER;
/* Flag to check wether the default ciphers have already been
registered. */
static int default_ciphers_registered;
/* Convenient macro for registering the default ciphers. */
#define REGISTER_DEFAULT_CIPHERS \
do \
{ \
ath_mutex_lock (&ciphers_registered_lock); \
if (! default_ciphers_registered) \
{ \
gcry_cipher_register_default (); \
default_ciphers_registered = 1; \
} \
ath_mutex_unlock (&ciphers_registered_lock); \
} \
while (0)
/* The handle structure. */
struct gcry_cipher_handle
{
int magic;
size_t actual_handle_size; /* Allocated size of this handle. */
gcry_cipher_spec_t *cipher;
gcry_module_t module;
int mode;
unsigned int flags;
unsigned char iv[MAX_BLOCKSIZE]; /* (this should be ulong aligned) */
unsigned char lastiv[MAX_BLOCKSIZE];
int unused; /* in IV */
unsigned char ctr[MAX_BLOCKSIZE]; /* For Counter (CTR) mode. */
PROPERLY_ALIGNED_TYPE context;
};
/* These dummy functions are used in case a cipher implementation
refuses to provide it's own functions. */
static gcry_err_code_t
dummy_setkey (void *c, const unsigned char *key, unsigned keylen)
{
return GPG_ERR_NO_ERROR;
}
static void
dummy_encrypt_block (void *c,
unsigned char *outbuf, const unsigned char *inbuf)
{
BUG();
}
static void
dummy_decrypt_block (void *c,
unsigned char *outbuf, const unsigned char *inbuf)
{
BUG();
}
static void
dummy_encrypt_stream (void *c,
unsigned char *outbuf, const unsigned char *inbuf,
unsigned int n)
{
BUG();
}
static void
dummy_decrypt_stream (void *c,
unsigned char *outbuf, const unsigned char *inbuf,
unsigned int n)
{
BUG();
}
/* Internal function. Register all the ciphers included in
CIPHER_TABLE. Note, that this function gets only used by the macro
REGISTER_DEFAULT_CIPHERS which protects it using a mutex. */
static void
gcry_cipher_register_default (void)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
int i;
for (i = 0; !err && cipher_table[i].cipher; i++)
{
if (! cipher_table[i].cipher->setkey)
cipher_table[i].cipher->setkey = dummy_setkey;
if (! cipher_table[i].cipher->encrypt)
cipher_table[i].cipher->encrypt = dummy_encrypt_block;
if (! cipher_table[i].cipher->decrypt)
cipher_table[i].cipher->decrypt = dummy_decrypt_block;
if (! cipher_table[i].cipher->stencrypt)
cipher_table[i].cipher->stencrypt = dummy_encrypt_stream;
if (! cipher_table[i].cipher->stdecrypt)
cipher_table[i].cipher->stdecrypt = dummy_decrypt_stream;
err = _gcry_module_add (&ciphers_registered,
cipher_table[i].algorithm,
(void *) cipher_table[i].cipher,
NULL);
}
if (err)
BUG ();
}
/* Internal callback function. Used via _gcry_module_lookup. */
static int
gcry_cipher_lookup_func_name (void *spec, void *data)
{
gcry_cipher_spec_t *cipher = (gcry_cipher_spec_t *) spec;
char *name = (char *) data;
const char **aliases = cipher->aliases;
int i, ret = ! stricmp (name, cipher->name);
if (aliases)
for (i = 0; aliases[i] && (! ret); i++)
ret = ! stricmp (name, aliases[i]);
return ret;
}
/* Internal callback function. Used via _gcry_module_lookup. */
static int
gcry_cipher_lookup_func_oid (void *spec, void *data)
{
gcry_cipher_spec_t *cipher = (gcry_cipher_spec_t *) spec;
char *oid = (char *) data;
gcry_cipher_oid_spec_t *oid_specs = cipher->oids;
int ret = 0, i;
if (oid_specs)
for (i = 0; oid_specs[i].oid && (! ret); i++)
if (! stricmp (oid, oid_specs[i].oid))
ret = 1;
return ret;
}
/* Internal function. Lookup a cipher entry by it's name. */
static gcry_module_t
gcry_cipher_lookup_name (const char *name)
{
gcry_module_t cipher;
cipher = _gcry_module_lookup (ciphers_registered, (void *) name,
gcry_cipher_lookup_func_name);
return cipher;
}
/* Internal function. Lookup a cipher entry by it's oid. */
static gcry_module_t
gcry_cipher_lookup_oid (const char *oid)
{
gcry_module_t cipher;
cipher = _gcry_module_lookup (ciphers_registered, (void *) oid,
gcry_cipher_lookup_func_oid);
return cipher;
}
/* 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 representhing this module is stored in MODULE. */
gcry_error_t
gcry_cipher_register (gcry_cipher_spec_t *cipher,
unsigned int *algorithm_id,
gcry_module_t *module)
{
gcry_err_code_t err = 0;
gcry_module_t mod;
ath_mutex_lock (&ciphers_registered_lock);
err = _gcry_module_add (&ciphers_registered, 0,
(void *) cipher, &mod);
ath_mutex_unlock (&ciphers_registered_lock);
if (! err)
{
*module = mod;
*algorithm_id = mod->mod_id;
}
return gcry_error (err);
}
/* Unregister the cipher identified by MODULE, which must have been
registered with gcry_cipher_register. */
void
gcry_cipher_unregister (gcry_module_t module)
{
ath_mutex_lock (&ciphers_registered_lock);
_gcry_module_release (module);
ath_mutex_unlock (&ciphers_registered_lock);
}
/* Locate the OID in the oid table and return the index or -1 when not
found. An opitonal "oid." or "OID." prefix in OID is ignored, the
OID is expected to be in standard IETF dotted notation. The
internal algorithm number is returned in ALGORITHM unless it
ispassed as NULL. A pointer to the specification of the module
implementing this algorithm is return in OID_SPEC unless passed as
NULL.*/
static int
search_oid (const char *oid, int *algorithm, gcry_cipher_oid_spec_t *oid_spec)
{
gcry_module_t module;
int ret = 0;
if (oid && ((! strncmp (oid, "oid.", 4))
|| (! strncmp (oid, "OID.", 4))))
oid += 4;
module = gcry_cipher_lookup_oid (oid);
if (module)
{
gcry_cipher_spec_t *cipher = module->spec;
int i;
for (i = 0; cipher->oids[i].oid && !ret; i++)
if (! stricmp (oid, cipher->oids[i].oid))
{
if (algorithm)
*algorithm = module->mod_id;
if (oid_spec)
*oid_spec = cipher->oids[i];
ret = 1;
}
_gcry_module_release (module);
}
return ret;
}
/* Map STRING to the cipher algorithm identifier. Returns the
algorithm ID of the cipher for the given name or 0 if the name is
not known. It is valid to pass NULL for STRING which results in a
return value of 0. */
int
gcry_cipher_map_name (const char *string)
{
gcry_module_t cipher;
int ret, algorithm = 0;
if (! string)
return 0;
REGISTER_DEFAULT_CIPHERS;
/* If the string starts with a digit (optionally prefixed with
either "OID." or "oid."), we first look into our table of ASN.1
object identifiers to figure out the algorithm */
ath_mutex_lock (&ciphers_registered_lock);
ret = search_oid (string, &algorithm, NULL);
if (! ret)
{
cipher = gcry_cipher_lookup_name (string);
if (cipher)
{
algorithm = cipher->mod_id;
_gcry_module_release (cipher);
}
}
ath_mutex_unlock (&ciphers_registered_lock);
return algorithm;
}
/* Given a STRING with an OID in dotted decimal notation, this
function returns the cipher mode (GCRY_CIPHER_MODE_*) associated
with that OID or 0 if no mode is known. Passing NULL for string
yields a return value of 0. */
int
gcry_cipher_mode_from_oid (const char *string)
{
gcry_cipher_oid_spec_t oid_spec;
int ret = 0, mode = 0;
if (!string)
return 0;
ath_mutex_lock (&ciphers_registered_lock);
ret = search_oid (string, NULL, &oid_spec);
if (ret)
mode = oid_spec.mode;
ath_mutex_unlock (&ciphers_registered_lock);
return mode;
}
/* 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 "?". */
static const char *
cipher_algo_to_string (int algorithm)
{
gcry_module_t cipher;
const char *name;
REGISTER_DEFAULT_CIPHERS;
ath_mutex_lock (&ciphers_registered_lock);
cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
if (cipher)
{
name = ((gcry_cipher_spec_t *) cipher->spec)->name;
_gcry_module_release (cipher);
}
else
name = "?";
ath_mutex_unlock (&ciphers_registered_lock);
return name;
}
/* Map the cipher algorithm identifier ALGORITHM to a string
representing this algorithm. This string is the default name as
used by Libgcrypt. An pointer to an empty string is returned for
an unknown algorithm. NULL is never returned. */
const char *
gcry_cipher_algo_name (int algorithm)
{
const char *s = cipher_algo_to_string (algorithm);
return s ? s : "";
}
/* Flag the cipher algorithm with the identifier ALGORITHM as
disabled. There is no error return, the function does nothing for
unknown algorithms. Disabled algorithms are vitually not available
in Libgcrypt. */
static void
disable_cipher_algo (int algorithm)
{
gcry_module_t cipher;
REGISTER_DEFAULT_CIPHERS;
ath_mutex_lock (&ciphers_registered_lock);
cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
if (cipher)
{
if (! (cipher->flags & FLAG_MODULE_DISABLED))
cipher->flags |= FLAG_MODULE_DISABLED;
_gcry_module_release (cipher);
}
ath_mutex_unlock (&ciphers_registered_lock);
}
/* Return 0 if the cipher algorithm with indentifier ALGORITHM is
available. Returns a basic error code value if it is not available. */
static gcry_err_code_t
check_cipher_algo (int algorithm)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
gcry_module_t cipher;
REGISTER_DEFAULT_CIPHERS;
ath_mutex_lock (&ciphers_registered_lock);
cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
if (cipher)
{
if (cipher->flags & FLAG_MODULE_DISABLED)
err = GPG_ERR_CIPHER_ALGO;
_gcry_module_release (cipher);
}
else
err = GPG_ERR_CIPHER_ALGO;
ath_mutex_unlock (&ciphers_registered_lock);
return err;
}
/* Return the standard length of the key for the cipher algorithm with
the identifier ALGORITHM. This function expects a valid algorithm
and will abort if the algorithm is not available or the length of
the key is not known. */
static unsigned int
cipher_get_keylen (int algorithm)
{
gcry_module_t cipher;
unsigned len = 0;
REGISTER_DEFAULT_CIPHERS;
ath_mutex_lock (&ciphers_registered_lock);
cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
if (cipher)
{
len = ((gcry_cipher_spec_t *) cipher->spec)->keylen;
if (! len)
log_bug ("cipher %d w/o key length\n", algorithm);
_gcry_module_release (cipher);
}
else
log_bug ("cipher %d not found\n", algorithm);
ath_mutex_unlock (&ciphers_registered_lock);
return len;
}
/* Return the block length of the cipher algorithm with the identifier
ALGORITHM. This function expects a valid algorithm and will abort
if the algorithm is not available or the length of the key is not
known. */
static unsigned int
cipher_get_blocksize (int algorithm)
{
gcry_module_t cipher;
unsigned len = 0;
REGISTER_DEFAULT_CIPHERS;
ath_mutex_lock (&ciphers_registered_lock);
cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
if (cipher)
{
len = ((gcry_cipher_spec_t *) cipher->spec)->blocksize;
if (! len)
log_bug ("cipher %d w/o blocksize\n", algorithm);
_gcry_module_release (cipher);
}
else
log_bug ("cipher %d not found\n", algorithm);
ath_mutex_unlock (&ciphers_registered_lock);
return len;
}
/*
Open a cipher handle for use with cipher algorithm ALGORITHM, using
the cipher mode MODE (one of the GCRY_CIPHER_MODE_*) and return a
handle in HANDLE. Put NULL into HANDLE and return an error code if
something goes wrong. FLAGS may be used to modify the
operation. The defined flags are:
GCRY_CIPHER_SECURE: allocate all internal buffers in secure memory.
GCRY_CIPHER_ENABLE_SYNC: Enable the sync operation as used in OpenPGP.
GCRY_CIPHER_CBC_CTS: Enable CTS mode.
GCRY_CIPHER_CBC_MAC: Enable MAC mode.
Values for these flags may be combined using OR.
*/
gcry_error_t
gcry_cipher_open (gcry_cipher_hd_t *handle,
int algo, int mode, unsigned int flags)
{
int secure = (flags & GCRY_CIPHER_SECURE);
gcry_cipher_spec_t *cipher = NULL;
gcry_module_t module = NULL;
gcry_cipher_hd_t h = NULL;
gcry_err_code_t err = 0;
/* If the application missed to call the random poll function, we do
it here to ensure that it is used once in a while. */
_gcry_fast_random_poll ();
REGISTER_DEFAULT_CIPHERS;
/* Fetch the according module and check wether the cipher is marked
available for use. */
ath_mutex_lock (&ciphers_registered_lock);
module = _gcry_module_lookup_id (ciphers_registered, algo);
if (module)
{
/* Found module. */
if (module->flags & FLAG_MODULE_DISABLED)
{
/* Not available for use. */
err = GPG_ERR_CIPHER_ALGO;
_gcry_module_release (module);
}
else
cipher = (gcry_cipher_spec_t *) module->spec;
}
else
err = GPG_ERR_CIPHER_ALGO;
ath_mutex_unlock (&ciphers_registered_lock);
/* check flags */
if ((! err)
&& ((flags & ~(0
| GCRY_CIPHER_SECURE
| GCRY_CIPHER_ENABLE_SYNC
| GCRY_CIPHER_CBC_CTS
| GCRY_CIPHER_CBC_MAC))
|| (flags & GCRY_CIPHER_CBC_CTS & GCRY_CIPHER_CBC_MAC)))
err = GPG_ERR_CIPHER_ALGO;
/* check that a valid mode has been requested */
if (! err)
switch (mode)
{
case GCRY_CIPHER_MODE_ECB:
case GCRY_CIPHER_MODE_CBC:
case GCRY_CIPHER_MODE_CFB:
+ case GCRY_CIPHER_MODE_OFB:
case GCRY_CIPHER_MODE_CTR:
if ((cipher->encrypt == dummy_encrypt_block)
|| (cipher->decrypt == dummy_decrypt_block))
err = GPG_ERR_INV_CIPHER_MODE;
break;
case GCRY_CIPHER_MODE_STREAM:
if ((cipher->stencrypt == dummy_encrypt_stream)
|| (cipher->stdecrypt == dummy_decrypt_stream))
err = GPG_ERR_INV_CIPHER_MODE;
break;
case GCRY_CIPHER_MODE_NONE:
/* FIXME: issue a warning when this mode is used */
break;
default:
err = GPG_ERR_INV_CIPHER_MODE;
}
/* ? FIXME: perform selftest here and mark this with a flag in
cipher_table ? */
if (! err)
{
size_t size = (sizeof (*h)
+ 2 * cipher->contextsize
- sizeof (PROPERLY_ALIGNED_TYPE));
if (secure)
h = gcry_calloc_secure (1, size);
else
h = gcry_calloc (1, size);
if (! h)
err = gpg_err_code_from_errno (errno);
else
{
h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
h->actual_handle_size = size;
h->cipher = cipher;
h->module = module;
h->mode = mode;
h->flags = flags;
}
}
/* Done. */
if (err)
{
if (module)
{
/* Release module. */
ath_mutex_lock (&ciphers_registered_lock);
_gcry_module_release (module);
ath_mutex_unlock (&ciphers_registered_lock);
}
}
*handle = err ? NULL : h;
return gcry_error (err);
}
/* Release all resources associated with the cipher handle H. H may be
NULL in which case this is a no-operation. */
void
gcry_cipher_close (gcry_cipher_hd_t h)
{
if (! h)
return;
if ((h->magic != CTX_MAGIC_SECURE)
&& (h->magic != CTX_MAGIC_NORMAL))
_gcry_fatal_error(GPG_ERR_INTERNAL,
"gcry_cipher_close: already closed/invalid handle");
else
h->magic = 0;
/* Release module. */
ath_mutex_lock (&ciphers_registered_lock);
_gcry_module_release (h->module);
ath_mutex_unlock (&ciphers_registered_lock);
/* We always want to wipe out the memory even when the context has
been allocated in secure memory. The user might have disabled
secure memory or is using his own implementation which does not
do the wiping. To accomplish this we need to keep track of the
actual size of this structure because we have no way to known
how large the allocated area was when using a standard malloc. */
wipememory (h, h->actual_handle_size);
gcry_free (h);
}
/* Set the key to be used for the encryption context C to KEY with
length KEYLEN. The length should match the required length. */
static gcry_error_t
cipher_setkey (gcry_cipher_hd_t c, byte *key, unsigned keylen)
{
gcry_err_code_t ret;
ret = (*c->cipher->setkey) (&c->context.c, key, keylen);
if (! ret)
/* Duplicate initial context. */
memcpy ((void *) ((char *) &c->context.c + c->cipher->contextsize),
(void *) &c->context.c,
c->cipher->contextsize);
return gcry_error (ret);
}
/* Set the IV to be used for the encryption context C to IV with
length IVLEN. The length should match the required length. */
static void
cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen )
{
memset( c->iv, 0, c->cipher->blocksize );
if( iv ) {
if( ivlen != c->cipher->blocksize )
log_info("WARNING: cipher_setiv: ivlen=%u blklen=%u\n",
ivlen, (unsigned) c->cipher->blocksize );
if (ivlen > c->cipher->blocksize)
ivlen = c->cipher->blocksize;
memcpy( c->iv, iv, ivlen );
}
c->unused = 0;
}
/* Reset the cipher context to the initial contex. This is basically
the same as an release followed by a new. */
static void
cipher_reset (gcry_cipher_hd_t c)
{
memcpy (&c->context.c,
(char *) &c->context.c + c->cipher->contextsize,
c->cipher->contextsize);
memset (c->iv, 0, c->cipher->blocksize);
memset (c->lastiv, 0, c->cipher->blocksize);
memset (c->ctr, 0, c->cipher->blocksize);
}
static void
do_ecb_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
unsigned int nblocks )
{
unsigned int n;
for(n=0; n < nblocks; n++ ) {
c->cipher->encrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
inbuf += c->cipher->blocksize;
outbuf += c->cipher->blocksize;
}
}
static void
do_ecb_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
unsigned int nblocks )
{
unsigned n;
for(n=0; n < nblocks; n++ ) {
c->cipher->decrypt ( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
inbuf += c->cipher->blocksize;
outbuf += c->cipher->blocksize;
}
}
static void
do_cbc_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
unsigned int nbytes )
{
unsigned int n;
byte *ivp;
int i;
size_t blocksize = c->cipher->blocksize;
unsigned nblocks = nbytes / blocksize;
if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) {
if ((nbytes % blocksize) == 0)
nblocks--;
}
for(n=0; n < nblocks; n++ ) {
/* fixme: the xor should work on words and not on
* bytes. Maybe it is a good idea to enhance the cipher backend
* API to allow for CBC handling direct in the backend */
for(ivp=c->iv,i=0; i < blocksize; i++ )
outbuf[i] = inbuf[i] ^ *ivp++;
c->cipher->encrypt ( &c->context.c, outbuf, outbuf );
memcpy(c->iv, outbuf, blocksize );
inbuf += blocksize;
if (!(c->flags & GCRY_CIPHER_CBC_MAC))
outbuf += blocksize;
}
if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize)
{
/* We have to be careful here, since outbuf might be equal to
inbuf. */
int restbytes;
byte b;
if ((nbytes % blocksize) == 0)
restbytes = blocksize;
else
restbytes = nbytes % blocksize;
outbuf -= blocksize;
for (ivp = c->iv, i = 0; i < restbytes; i++)
{
b = inbuf[i];
outbuf[blocksize + i] = outbuf[i];
outbuf[i] = b ^ *ivp++;
}
for (; i < blocksize; i++)
outbuf[i] = 0 ^ *ivp++;
c->cipher->encrypt (&c->context.c, outbuf, outbuf);
memcpy (c->iv, outbuf, blocksize);
}
}
static void
do_cbc_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
unsigned int nbytes )
{
unsigned int n;
byte *ivp;
int i;
size_t blocksize = c->cipher->blocksize;
unsigned int nblocks = nbytes / blocksize;
if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) {
nblocks--;
if ((nbytes % blocksize) == 0)
nblocks--;
memcpy(c->lastiv, c->iv, blocksize );
}
for(n=0; n < nblocks; n++ ) {
/* Because outbuf and inbuf might be the same, we have
* to save the original ciphertext block. We use lastiv
* for this here because it is not used otherwise. */
memcpy(c->lastiv, inbuf, blocksize );
c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
for(ivp=c->iv,i=0; i < blocksize; i++ )
outbuf[i] ^= *ivp++;
memcpy(c->iv, c->lastiv, blocksize );
inbuf += c->cipher->blocksize;
outbuf += c->cipher->blocksize;
}
if ((c->flags & GCRY_CIPHER_CBC_CTS) && nbytes > blocksize) {
int restbytes;
if ((nbytes % blocksize) == 0)
restbytes = blocksize;
else
restbytes = nbytes % blocksize;
memcpy(c->lastiv, c->iv, blocksize ); /* save Cn-2 */
memcpy(c->iv, inbuf + blocksize, restbytes ); /* save Cn */
c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
for(ivp=c->iv,i=0; i < restbytes; i++ )
outbuf[i] ^= *ivp++;
memcpy(outbuf + blocksize, outbuf, restbytes);
for(i=restbytes; i < blocksize; i++)
c->iv[i] = outbuf[i];
c->cipher->decrypt ( &c->context.c, outbuf, c->iv );
for(ivp=c->lastiv,i=0; i < blocksize; i++ )
outbuf[i] ^= *ivp++;
/* c->lastiv is now really lastlastiv, does this matter? */
}
}
static void
do_cfb_encrypt( gcry_cipher_hd_t c,
byte *outbuf, const byte *inbuf, unsigned nbytes )
{
byte *ivp;
size_t blocksize = c->cipher->blocksize;
if( nbytes <= c->unused ) {
/* Short enough to be encoded by the remaining XOR mask. */
/* XOR the input with the IV and store input into IV. */
for (ivp=c->iv+c->cipher->blocksize - c->unused;
nbytes;
nbytes--, c->unused-- )
*outbuf++ = (*ivp++ ^= *inbuf++);
return;
}
if( c->unused ) {
/* XOR the input with the IV and store input into IV */
nbytes -= c->unused;
for(ivp=c->iv+blocksize - c->unused; c->unused; c->unused-- )
*outbuf++ = (*ivp++ ^= *inbuf++);
}
/* Now we can process complete blocks. */
while( nbytes >= blocksize ) {
int i;
/* Encrypt the IV (and save the current one). */
memcpy( c->lastiv, c->iv, blocksize );
c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
/* XOR the input with the IV and store input into IV */
for(ivp=c->iv,i=0; i < blocksize; i++ )
*outbuf++ = (*ivp++ ^= *inbuf++);
nbytes -= blocksize;
}
if( nbytes ) { /* process the remaining bytes */
/* encrypt the IV (and save the current one) */
memcpy( c->lastiv, c->iv, blocksize );
c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
c->unused = blocksize;
/* and apply the xor */
c->unused -= nbytes;
for(ivp=c->iv; nbytes; nbytes-- )
*outbuf++ = (*ivp++ ^= *inbuf++);
}
}
static void
do_cfb_decrypt( gcry_cipher_hd_t c,
byte *outbuf, const byte *inbuf, unsigned int nbytes )
{
byte *ivp;
ulong temp;
size_t blocksize = c->cipher->blocksize;
if( nbytes <= c->unused ) {
/* Short enough to be encoded by the remaining XOR mask. */
/* XOR the input with the IV and store input into IV. */
for(ivp=c->iv+blocksize - c->unused; nbytes; nbytes--,c->unused--) {
temp = *inbuf++;
*outbuf++ = *ivp ^ temp;
*ivp++ = temp;
}
return;
}
if( c->unused ) {
/* XOR the input with the IV and store input into IV. */
nbytes -= c->unused;
for(ivp=c->iv+blocksize - c->unused; c->unused; c->unused-- ) {
temp = *inbuf++;
*outbuf++ = *ivp ^ temp;
*ivp++ = temp;
}
}
/* now we can process complete blocks */
while( nbytes >= blocksize ) {
int i;
/* encrypt the IV (and save the current one) */
memcpy( c->lastiv, c->iv, blocksize );
c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
/* XOR the input with the IV and store input into IV */
for(ivp=c->iv,i=0; i < blocksize; i++ ) {
temp = *inbuf++;
*outbuf++ = *ivp ^ temp;
*ivp++ = temp;
}
nbytes -= blocksize;
}
if( nbytes ) { /* process the remaining bytes */
/* encrypt the IV (and save the current one) */
memcpy( c->lastiv, c->iv, blocksize );
c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
c->unused = blocksize;
/* and apply the xor */
c->unused -= nbytes;
for(ivp=c->iv; nbytes; nbytes-- ) {
temp = *inbuf++;
*outbuf++ = *ivp ^ temp;
*ivp++ = temp;
}
}
}
+static void
+do_ofb_encrypt( gcry_cipher_hd_t c,
+ byte *outbuf, const byte *inbuf, unsigned nbytes )
+{
+ byte *ivp;
+ size_t blocksize = c->cipher->blocksize;
+
+ if ( nbytes <= c->unused )
+ {
+ /* Short enough to be encoded by the remaining XOR mask. */
+ /* XOR the input with the IV */
+ for (ivp=c->iv+c->cipher->blocksize - c->unused;
+ nbytes;
+ nbytes--, c->unused-- )
+ *outbuf++ = (*ivp++ ^ *inbuf++);
+ return;
+ }
+
+ if( c->unused )
+ {
+ nbytes -= c->unused;
+ for(ivp=c->iv+blocksize - c->unused; c->unused; c->unused-- )
+ *outbuf++ = (*ivp++ ^ *inbuf++);
+ }
+
+ /* Now we can process complete blocks. */
+ while ( nbytes >= blocksize )
+ {
+ int i;
+ /* Encrypt the IV (and save the current one). */
+ memcpy( c->lastiv, c->iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
+
+ for (ivp=c->iv,i=0; i < blocksize; i++ )
+ *outbuf++ = (*ivp++ ^ *inbuf++);
+ nbytes -= blocksize;
+ }
+ if ( nbytes )
+ { /* process the remaining bytes */
+ memcpy( c->lastiv, c->iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
+ c->unused = blocksize;
+ c->unused -= nbytes;
+ for(ivp=c->iv; nbytes; nbytes-- )
+ *outbuf++ = (*ivp++ ^ *inbuf++);
+ }
+}
+
+static void
+do_ofb_decrypt( gcry_cipher_hd_t c,
+ byte *outbuf, const byte *inbuf, unsigned int nbytes )
+{
+ byte *ivp;
+ size_t blocksize = c->cipher->blocksize;
+
+ if( nbytes <= c->unused )
+ {
+ /* Short enough to be encoded by the remaining XOR mask. */
+ for (ivp=c->iv+blocksize - c->unused; nbytes; nbytes--,c->unused--)
+ *outbuf++ = *ivp++ ^ *inbuf++;
+ return;
+ }
+
+ if ( c->unused )
+ {
+ nbytes -= c->unused;
+ for (ivp=c->iv+blocksize - c->unused; c->unused; c->unused-- )
+ *outbuf++ = *ivp++ ^ *inbuf++;
+ }
+
+ /* Now we can process complete blocks. */
+ while ( nbytes >= blocksize )
+ {
+ int i;
+ /* Encrypt the IV (and save the current one). */
+ memcpy( c->lastiv, c->iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
+ for (ivp=c->iv,i=0; i < blocksize; i++ )
+ *outbuf++ = *ivp++ ^ *inbuf++;
+ nbytes -= blocksize;
+ }
+ if ( nbytes )
+ { /* Process the remaining bytes. */
+ /* Encrypt the IV (and save the current one). */
+ memcpy( c->lastiv, c->iv, blocksize );
+ c->cipher->encrypt ( &c->context.c, c->iv, c->iv );
+ c->unused = blocksize;
+ c->unused -= nbytes;
+ for (ivp=c->iv; nbytes; nbytes-- )
+ *outbuf++ = *ivp++ ^ *inbuf++;
+ }
+}
+
+
static void
do_ctr_encrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
unsigned int nbytes )
{
unsigned int n;
byte tmp[MAX_BLOCKSIZE];
int i;
for(n=0; n < nbytes; n++)
{
if ((n % c->cipher->blocksize) == 0)
{
c->cipher->encrypt (&c->context.c, tmp, c->ctr);
for (i = c->cipher->blocksize; i > 0; i--)
{
c->ctr[i-1]++;
if (c->ctr[i-1] != 0)
break;
}
}
/* XOR input with encrypted counter and store in output. */
outbuf[n] = inbuf[n] ^ tmp[n % c->cipher->blocksize];
}
}
static void
do_ctr_decrypt( gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
unsigned int nbytes )
{
do_ctr_encrypt (c, outbuf, inbuf, nbytes);
}
/****************
* Encrypt INBUF to OUTBUF with the mode selected at open.
* inbuf and outbuf may overlap or be the same.
* Depending on the mode some contraints apply to NBYTES.
*/
static gcry_err_code_t
cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf,
const byte *inbuf, unsigned int nbytes)
{
gcry_err_code_t rc = GPG_ERR_NO_ERROR;
switch( c->mode ) {
case GCRY_CIPHER_MODE_ECB:
if (!(nbytes%c->cipher->blocksize))
do_ecb_encrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize );
else
rc = GPG_ERR_INV_ARG;
break;
case GCRY_CIPHER_MODE_CBC:
if (!(nbytes%c->cipher->blocksize)
|| (nbytes > c->cipher->blocksize
&& (c->flags & GCRY_CIPHER_CBC_CTS)))
do_cbc_encrypt(c, outbuf, inbuf, nbytes );
else
rc = GPG_ERR_INV_ARG;
break;
case GCRY_CIPHER_MODE_CFB:
do_cfb_encrypt(c, outbuf, inbuf, nbytes );
break;
+ case GCRY_CIPHER_MODE_OFB:
+ do_ofb_encrypt(c, outbuf, inbuf, nbytes );
+ break;
case GCRY_CIPHER_MODE_CTR:
do_ctr_encrypt(c, outbuf, inbuf, nbytes );
break;
case GCRY_CIPHER_MODE_STREAM:
c->cipher->stencrypt ( &c->context.c,
outbuf, (byte*)/*arggg*/inbuf, nbytes );
break;
case GCRY_CIPHER_MODE_NONE:
if( inbuf != outbuf )
memmove( outbuf, inbuf, nbytes );
break;
default:
log_fatal("cipher_encrypt: invalid mode %d\n", c->mode );
rc = GPG_ERR_INV_CIPHER_MODE;
break;
}
return rc;
}
/****************
* Encrypt IN and write it to OUT. If IN is NULL, in-place encryption has
* been requested.
*/
gcry_error_t
gcry_cipher_encrypt (gcry_cipher_hd_t h, byte *out, size_t outsize,
const byte *in, size_t inlen)
{
gcry_err_code_t err;
if (!in)
/* Caller requested in-place encryption. */
/* Actullay cipher_encrypt() does not need to know about it, but
* we may change this to get better performance. */
err = cipher_encrypt (h, out, out, outsize);
else if (outsize < ((h->flags & GCRY_CIPHER_CBC_MAC) ?
h->cipher->blocksize : inlen))
err = GPG_ERR_TOO_SHORT;
else if ((h->mode == GCRY_CIPHER_MODE_ECB
|| (h->mode == GCRY_CIPHER_MODE_CBC
&& (! ((h->flags & GCRY_CIPHER_CBC_CTS)
&& (inlen > h->cipher->blocksize)))))
&& (inlen % h->cipher->blocksize))
err = GPG_ERR_INV_ARG;
else
err = cipher_encrypt (h, out, in, inlen);
if (err && out)
memset (out, 0x42, outsize); /* Failsafe: Make sure that the
plaintext will never make it into
OUT. */
return gcry_error (err);
}
/****************
* Decrypt INBUF to OUTBUF with the mode selected at open.
* inbuf and outbuf may overlap or be the same.
* Depending on the mode some some contraints apply to NBYTES.
*/
static gcry_err_code_t
cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, const byte *inbuf,
unsigned int nbytes)
{
gcry_err_code_t rc = GPG_ERR_NO_ERROR;
switch( c->mode ) {
case GCRY_CIPHER_MODE_ECB:
if (!(nbytes%c->cipher->blocksize))
do_ecb_decrypt(c, outbuf, inbuf, nbytes/c->cipher->blocksize );
else
rc = GPG_ERR_INV_ARG;
break;
case GCRY_CIPHER_MODE_CBC:
if (!(nbytes%c->cipher->blocksize)
|| (nbytes > c->cipher->blocksize
&& (c->flags & GCRY_CIPHER_CBC_CTS)))
do_cbc_decrypt(c, outbuf, inbuf, nbytes );
else
rc = GPG_ERR_INV_ARG;
break;
case GCRY_CIPHER_MODE_CFB:
do_cfb_decrypt(c, outbuf, inbuf, nbytes );
break;
+ case GCRY_CIPHER_MODE_OFB:
+ do_ofb_decrypt(c, outbuf, inbuf, nbytes );
+ break;
case GCRY_CIPHER_MODE_CTR:
do_ctr_decrypt(c, outbuf, inbuf, nbytes );
break;
case GCRY_CIPHER_MODE_STREAM:
c->cipher->stdecrypt ( &c->context.c,
outbuf, (byte*)/*arggg*/inbuf, nbytes );
break;
case GCRY_CIPHER_MODE_NONE:
if( inbuf != outbuf )
memmove( outbuf, inbuf, nbytes );
break;
default:
log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode );
rc = GPG_ERR_INV_CIPHER_MODE;
break;
}
return rc;
}
gcry_error_t
gcry_cipher_decrypt (gcry_cipher_hd_t h, byte *out, size_t outsize,
const byte *in, size_t inlen)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
if (! in)
/* Caller requested in-place encryption. */
/* Actullay cipher_encrypt() does not need to know about it, but
* we may chnage this to get better performance. */
err = cipher_decrypt (h, out, out, outsize);
else if (outsize < inlen)
err = GPG_ERR_TOO_SHORT;
else if (((h->mode == GCRY_CIPHER_MODE_ECB)
|| ((h->mode == GCRY_CIPHER_MODE_CBC)
&& (! ((h->flags & GCRY_CIPHER_CBC_CTS)
&& (inlen > h->cipher->blocksize)))))
&& (inlen % h->cipher->blocksize) != 0)
err = GPG_ERR_INV_ARG;
else
err = cipher_decrypt (h, out, in, inlen);
return gcry_error (err);
}
/****************
* Used for PGP's somewhat strange CFB mode. Only works if
* the corresponding flag is set.
*/
static void
cipher_sync( gcry_cipher_hd_t c )
{
if( (c->flags & GCRY_CIPHER_ENABLE_SYNC) && c->unused ) {
memmove(c->iv + c->unused, c->iv, c->cipher->blocksize - c->unused );
memcpy(c->iv, c->lastiv + c->cipher->blocksize - c->unused, c->unused);
c->unused = 0;
}
}
gcry_error_t
gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
{
gcry_err_code_t rc = GPG_ERR_NO_ERROR;
switch (cmd)
{
case GCRYCTL_SET_KEY:
rc = cipher_setkey( h, buffer, buflen );
break;
case GCRYCTL_SET_IV:
cipher_setiv( h, buffer, buflen );
break;
case GCRYCTL_RESET:
cipher_reset (h);
break;
case GCRYCTL_CFB_SYNC:
cipher_sync( h );
break;
case GCRYCTL_SET_CBC_CTS:
if (buflen)
if (h->flags & GCRY_CIPHER_CBC_MAC)
rc = GPG_ERR_INV_FLAG;
else
h->flags |= GCRY_CIPHER_CBC_CTS;
else
h->flags &= ~GCRY_CIPHER_CBC_CTS;
break;
case GCRYCTL_SET_CBC_MAC:
if (buflen)
if (h->flags & GCRY_CIPHER_CBC_CTS)
rc = GPG_ERR_INV_FLAG;
else
h->flags |= GCRY_CIPHER_CBC_MAC;
else
h->flags &= ~GCRY_CIPHER_CBC_MAC;
break;
case GCRYCTL_DISABLE_ALGO:
/* this one expects a NULL handle and buffer pointing to an
* integer with the algo number.
*/
if( h || !buffer || buflen != sizeof(int) )
return gcry_error (GPG_ERR_CIPHER_ALGO);
disable_cipher_algo( *(int*)buffer );
break;
case GCRYCTL_SET_CTR:
if (buffer && buflen == h->cipher->blocksize)
memcpy (h->ctr, buffer, h->cipher->blocksize);
else if (buffer == NULL || buflen == 0)
memset (h->ctr, 0, h->cipher->blocksize);
else
rc = GPG_ERR_INV_ARG;
break;
default:
rc = GPG_ERR_INV_OP;
}
return gcry_error (rc);
}
/****************
* Return information about the cipher handle.
*/
gcry_error_t
gcry_cipher_info( gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
switch (cmd)
{
default:
err = GPG_ERR_INV_OP;
}
return gcry_error (err);
}
/****************
* Return information about the given cipher algorithm
* WHAT select the kind of information returned:
* GCRYCTL_GET_KEYLEN:
* Return the length of the key, if the algorithm
* supports multiple key length, the maximum supported value
* is returnd. The length is return as number of octets.
* buffer and nbytes must be zero.
* The keylength is returned in _bytes_.
* GCRYCTL_GET_BLKLEN:
* Return the blocklength of the algorithm counted in octets.
* buffer and nbytes must be zero.
* GCRYCTL_TEST_ALGO:
* Returns 0 when the specified algorithm is available for use.
* buffer and nbytes must be zero.
*
* Note: Because this function is in most cases used to return an
* integer value, we can make it easier for the caller to just look at
* the return value. The caller will in all cases consult the value
* and thereby detecting whether a error occured or not (i.e. while checking
* the block size)
*/
gcry_error_t
gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
unsigned int ui;
switch (what)
{
case GCRYCTL_GET_KEYLEN:
if (buffer || (! nbytes))
err = GPG_ERR_CIPHER_ALGO;
else
{
ui = cipher_get_keylen (algo);
if ((ui > 0) && (ui <= 512))
*nbytes = (size_t) ui / 8;
else
/* The only reason is an invalid algo or a strange
blocksize. */
err = GPG_ERR_CIPHER_ALGO;
}
break;
case GCRYCTL_GET_BLKLEN:
if (buffer || (! nbytes))
err = GPG_ERR_CIPHER_ALGO;
else
{
ui = cipher_get_blocksize (algo);
if ((ui > 0) && (ui < 10000))
*nbytes = ui;
else
/* The only reason is an invalid algo or a strange
blocksize. */
err = GPG_ERR_CIPHER_ALGO;
}
break;
case GCRYCTL_TEST_ALGO:
if (buffer || nbytes)
err = GPG_ERR_INV_ARG;
else
err = check_cipher_algo (algo);
break;
default:
err = GPG_ERR_INV_OP;
}
return gcry_error (err);
}
size_t
gcry_cipher_get_algo_keylen (int algo)
{
size_t n;
if (gcry_cipher_algo_info( algo, GCRYCTL_GET_KEYLEN, NULL, &n))
n = 0;
return n;
}
size_t
gcry_cipher_get_algo_blklen (int algo)
{
size_t n;
if (gcry_cipher_algo_info( algo, GCRYCTL_GET_BLKLEN, NULL, &n))
n = 0;
return n;
}
gcry_err_code_t
_gcry_cipher_init (void)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
REGISTER_DEFAULT_CIPHERS;
return err;
}
/* 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)
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
ath_mutex_lock (&ciphers_registered_lock);
err = _gcry_module_list (ciphers_registered, list, list_length);
ath_mutex_unlock (&ciphers_registered_lock);
return err;
}
diff --git a/doc/ChangeLog b/doc/ChangeLog
index 797396d0..e0b54115 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,326 +1,331 @@
+2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07)
+
+ * gcrypt.texi (Available cipher modes): Typo fix, add a little
+ more detail on cipher modes vs cipher algorithms.
+
2006-01-08 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi: Added documentation for more gcry_control commands.
* gcrypt.texi: Fixed several typos; thanks to Tommi Vainikainen.
2005-12-16 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (MPI formats): Fix return types of functions:
gcry_mpi_scan, gcry_mpi_print, gcry_mpi_aprint.
2005-11-26 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi: New chapter: Prime numbers.
2005-11-12 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (MPI formats): Document that for gcry_mpi_scan and
in the case of GCRYMPI_FMT_HEX, BUFLEN must be zero.
2005-10-31 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi: Added more gcry_control related descriptions.
2005-10-16 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Controlling the library): Start documenting the
existing control commands.
2005-04-11 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Available hash algorithms): Add entry for Whirlpool.
2005-03-30 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Working with IO objects): Document ac io objects;
adjust ac scheme functions, which do now use io objects.
2005-03-19 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Working with cipher handles): Clarify CTS mode.
2005-02-08 Werner Koch <wk@g10code.com>
* gcrypt.texi: Fixed direntry.
2005-02-13 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Using cryptographic functions): Document new
encoding and scheme crypto functionality.
2005-02-03 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi: Fixed several typos; thanks to Michele Baldessari.
2005-01-04 Werner Koch <wk@g10code.com>
* gcrypt.texi: Updated to use @copying. Fixed list of copyright
years; we had real changes in 2004. Fixed some formatting issues.
2004-08-24 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Miscellaneous): Document gcry_mpi_randomize.
2004-08-18 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Multi Threading): Document
GCRY_THREAD_OPTION_PTH_IMPL, GCRY_THREAD_OPTION_PTHREAD_IMPL.
2004-05-07 Moritz Schulte <moritz@g10code.de>
* gcrypt.texi: Merged several fixes reported by Umberto Salsi.
2004-04-08 Moritz Schulte <moritz@g10code.de>
* gcrypt.texi (Multi Threading): Typo fix.
2004-03-11 Marcus Brinkmann <marcus@g10code.de>
* gcrypt.texi (Multi Threading): Partially document new thread
support.
2004-02-24 Werner Koch <wk@gnupg.org>
* gcrypt.texi (Calculations): Typo fix.
2004-01-25 Moritz Schulte <mo@g10code.com>
* gcrypt.texi (General cipher functions): Fixed descriptions of
the arguments for GCRYCTL_GET_KEYLEN, GCRYCTL_GET_BLKLEN; reported
by Randy.
2004-01-14 Moritz Schulte <mo@g10code.com>
* gcrypt.texi (Public Key cryptography II): Adjusted to new
gcry_ac_* API; document flags.
2003-12-04 Werner Koch <wk@gnupg.org>
* Makefile.am (gcrypt_TEXINFOS): Removed fdl.texi.
2003-12-03 Werner Koch <wk@gnupg.org>
* gcrypt.texi: Changed license from FDL to GPL because this is a
reference manual only useful along with actual code.
* fdl.texi: Removed.
* gcrypt.texi: Minor cleanups
(Working with keys): Clarified generation of RSA's E parameter.
(Multi Threading): Clarified.
2003-11-11 Werner Koch <wk@gnupg.org>
* gcrypt.texi (Working with S-expressions): Added "%b".
2003-11-04 Werner Koch <wk@gnupg.org>
* gcrypt.texi (Retrieving random numbers): Add gcry_create_nonce.
2003-08-30 Werner Koch <wk@gnupg.org>
* gcrypt.texi (Working with hash algorithms): Clarified that HMAC
does not work with all algorithms.
2003-07-30 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Available asymmetric algorithms): Mention
GCRY_AC_ELG_E.
2003-07-28 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Working with keys): Mention that gcry_pk_testkey
and gcry_ac_key_test only verify private keys.
(Working with keys): Fix typo.
(General public-key related Functions): Fixed some sentences,
thanks to Neil Spring.
2003-07-27 Werner Koch <wk@gnupg.org>
* gcrypt.texi: Adjusted description of gcry_mpi_scan and
gcry_mpi_dump. Add gcry_mpi_dump.
2003-07-22 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi: Added more documentation for the register
mechanism.
2003-07-18 Werner Koch <wk@gnupg.org>
* gcrypt.texi (Misc): Add a warning on the use of opaque values.
2003-07-14 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Overview): Mention the non-thread-safe-nature of
functions modifying context stored in handles.
2003-07-12 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Available ciphers): Added: TWOFISH128.
(Error Handling): Merged a lot of documentation taken from GPGME.
2003-07-08 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Working with sets of data): Documented:
gcry_ac_data_copy.
2003-07-07 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi: Documented module system.
2003-07-05 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Working with cipher handles): Small fix by Simon
Josefsson <jas@extundo.com>.
2003-07-02 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi: Documented ac interface.
2003-06-18 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi: Small fixes.
2003-06-16 Moritz Schulte <moritz@g10code.com>
* cipher-ref.sgml: Removed file.
* digest-ref.sgml: Likewise.
* misc-ref.sgml: Likewise.
* pubkey-ref.sgml: Likewise.
* reference.sgml: Likewise.
* version.sgml.in: Likewise.
2003-06-15 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi: Documented several parts of the library, merged
some documentation from GPGME's manual, re-structured the whole
manual, added more menus.
2003-06-14 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Hash Functions): Adjusteded description of
gcry_md_copy.
2003-06-12 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Public Key Functions): Fix example S-Exp, i.e.:
added the number of following digits as prefix to the number of
bits.
(Public Key Functions): Document the general usage of `flags',
including the no-blinding flag.
2003-06-11 Werner Koch <wk@gnupg.org>
* gcrypt.texi (Hash Functions): Document possible values of HD.
2003-06-09 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Version Check): Changed description of
gcry_check_version; the user now *must* call the function to
initialize the library.
2003-06-08 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi: Change for libgpg-error.
2003-05-22 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Public Key Functions): Fixed typo.
2003-05-17 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Public Key Functions): Mention that only the
checking of secret keys is supported currently.
2003-03-30 Simon Josefsson <jas@extundo.com>
* gcrypt.texi: Add CTR.
2003-03-22 Simon Josefsson <jas@extundo.com>
* gcrypt.texi: Add CBC-MAC.
2003-03-04 Moritz Schulte <moritz@g10code.com>
* gcrypt.texi (Cipher Functions): Added gcry_cipher_reset.
2003-01-23 Werner Koch <wk@gnupg.org>
* gcrypt.texi (gcry_pk_decrypt): Described use of FLAGS
2003-01-20 Simon Josefsson <jas@extundo.com>
* gcrypt.texi (Hash Functions): Add CRC.
2003-01-19 Werner Koch <wk@gnupg.org>
* gcrypt.texi: Most functions are now documented. Still need to
fine tune the menu structure, document some utility functions,
mark up indices and references and add examples.
2002-08-14 Werner Koch <wk@gnupg.org>
* gcrypt.texi: Typo fixes.
2002-05-14 Werner Koch <wk@gnupg.org>
* lgpl.texi: New.
* gcrypt.texi: Included lgpl and commented not yet converted text.
2002-04-16 Werner Koch <wk@gnupg.org>
* version.sgml.in, cipher-ref.sgml, digest-ref.sgml, misc-ref.sgml
* pubkey-ref.sgml, reference.sgml: Removed.
* gcrypt.texi: New. Based on the old sgml version.
* gpl.texi, fdl.texi: New.
* Makefile.am: Adjusted for use with texinfo.
2000-12-21 Werner Koch <wk@gnupg.org>
Renamed the gcryptref.sgml files and removed the GnuPG stuff.
Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
* Makefile.am (SUBDIRS): Removed gph from this development series
Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am (SUBDIRS): New subdir gph for the manual.
Thu Jul 22 20:03:03 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* gpg.sgml (--always-trust): Added.
Wed Jul 14 19:42:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.am: Create a dummy man page if docbook-to-man is missing.
Wed Jun 16 20:16:21 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* gpg1.pod: Removed.
* gpg.sgml: New. Replaces the pod file
* Makefile.am: Add rule to make a man file from sgml
Tue Jun 15 12:21:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* Makefile.in.in: Use DESTDIR.
Mon May 31 19:41:10 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
* gpg.1pod: Enhanced the Bugs section (Michael).
Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
* gpg.1pod: Spelling and grammar corrections (John A. Martin)
* FAQ: Ditto.
* DETAILS: Ditto.
Copyright 1999, 2000, 2002, 2003 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.
diff --git a/doc/gcrypt.texi b/doc/gcrypt.texi
index 907f7bb2..fa32a3ab 100644
--- a/doc/gcrypt.texi
+++ b/doc/gcrypt.texi
@@ -1,4120 +1,4124 @@
\input texinfo @c -*- Texinfo -*-
@c %**start of header
@setfilename gcrypt.info
@include version.texi
@settitle The Libgcrypt Reference Manual
@c Unify some of the indices.
@syncodeindex tp fn
@syncodeindex pg fn
@c %**end of header
@copying
This manual is for Libgcrypt
(version @value{VERSION}, @value{UPDATED}),
which is GNU's library of cryptographic building blocks.
-Copyright @copyright{} 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
+Copyright @copyright{} 2000, 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
@quotation
Permission is granted to copy, distribute and/or modify this document
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. The text of the license can be found in the
section entitled ``Copying''.
@end quotation
@end copying
@dircategory GNU Libraries
@direntry
* libgcrypt: (gcrypt). Cryptographic function library.
@end direntry
@c
@c Titlepage
@c
@setchapternewpage odd
@titlepage
@title The Libgcrypt Reference Manual
@subtitle Version @value{VERSION}
@subtitle @value{UPDATED}
@author Werner Koch (@email{wk@@gnupg.org})
@author Moritz Schulte (@email{mo@@g10code.com})
@page
@vskip 0pt plus 1filll
@insertcopying
@end titlepage
@summarycontents
@contents
@page
@ifnottex
@node Top
@top The Libgcrypt Library
@insertcopying
@end ifnottex
@menu
* Introduction:: What is @acronym{Libgcrypt}.
* Preparation:: What you should do before using the library.
* Generalities:: General library functions and data types.
* Handler Functions:: Working with handler functions.
* Symmetric cryptography:: How to use symmetric cryptography.
* Hashing:: How to use hashing.
* Public Key cryptography (I):: How to use public key cryptography.
* Public Key cryptography (II):: How to use public key cryptography, alternatively.
* Random Numbers:: How to work with random numbers.
* S-expressions:: How to manage S-expressions.
* MPI library:: How to work with multi-precision-integers.
* Prime numbers:: How to use the Prime number related functions.
* Utilities:: Utility functions.
Appendices
* Library Copying:: The GNU Lesser General Public License
says how you can copy and share `Libgcrypt'.
* Copying:: The GNU General Public License says how you
can copy and share some parts of `Libgcrypt'.
Indices
* Concept Index:: Index of concepts and programs.
* Function and Data Index:: Index of functions, variables and data types.
@detailmenu
--- The Detailed Node Listing ---
Introduction
* Getting Started:: How to use this manual.
* Features:: A glance at @acronym{Libgcrypt}'s features.
* Overview:: Overview about the library.
Preparation
* Header:: What header file you need to include.
* Building sources:: How to build sources using the library.
* Building sources using Automake:: How to build sources with the help of Automake.
* Initializing the library:: How to initialize the library.
* Multi Threading:: How @acronym{Libgcrypt} can be used in a MT environment.
Generalities
* Controlling the library:: Controlling @acronym{Libgcrypt}'s behavior.
* Modules:: Description of extension modules.
* Error Handling:: Error codes and such.
Handler Functions
* Progress handler:: Using a progress handler function.
* Allocation handler:: Using special memory allocation functions.
* Error handler:: Using error handler functions.
* Logging handler:: Using a special logging function.
Symmetric cryptography
* Available ciphers:: List of ciphers supported by the library.
* Cipher modules:: How to work with cipher modules.
* Available cipher modes:: List of cipher modes supported by the library.
* Working with cipher handles:: How to perform operations related to cipher handles.
* General cipher functions:: General cipher functions independent of cipher handles.
Hashing
* Available hash algorithms:: List of hash algorithms supported by the library.
* Hash algorithm modules:: How to work with hash algorithm modules.
* Working with hash algorithms:: List of functions related to hashing.
Public Key cryptography (I)
* Used S-expressions:: Introduction into the used S-expression.
* Available algorithms:: Algorithms supported by the library.
* Public key modules:: How to work with public key modules.
* Cryptographic Functions:: Functions for performing the cryptographic actions.
* General public-key related Functions:: General functions, not implementing any cryptography.
Public Key cryptography (II)
* Available asymmetric algorithms:: List of algorithms supported by the library.
* Working with sets of data:: How to work with sets of data.
* Working with handles:: How to use handles.
* Working with keys:: How to work with keys.
* Using cryptographic functions:: How to perform cryptographic operations.
* Handle-independent functions:: General functions independent of handles.
Random Numbers
* Quality of random numbers:: @acronym{Libgcrypt} uses different quality levels.
* Retrieving random numbers:: How to retrieve random numbers.
S-expressions
* Data types for S-expressions:: Data types related with S-expressions.
* Working with S-expressions:: How to work with S-expressions.
MPI library
* Data types:: MPI related data types.
* Basic functions:: First steps with MPI numbers.
* MPI formats:: External representation of MPIs.
* Calculations:: Performing MPI calculations.
* Comparisons:: How to compare MPI values.
* Bit manipulations:: How to access single bits of MPI values.
* Miscellaneous:: Miscellaneous MPI functions.
Prime numbers
* Generation:: Generation of new prime numbers.
* Checking:: Checking if a given number is prime.
Utilities
* Memory allocation:: Functions related with memory allocation.
@end detailmenu
@end menu
@c **********************************************************
@c ******************* Introduction ***********************
@c **********************************************************
@node Introduction
@chapter Introduction
`@acronym{Libgcrypt}' is a library providing cryptographic building blocks.
@menu
* Getting Started:: How to use this manual.
* Features:: A glance at @acronym{Libgcrypt}'s features.
* Overview:: Overview about the library.
@end menu
@node Getting Started
@section Getting Started
This manual documents the `@acronym{Libgcrypt}' library application programming
interface (API). All functions and data types provided by the library
are explained.
@noindent
The reader is assumed to possess basic knowledge about applied
cryptography.
This manual can be used in several ways. If read from the beginning
to the end, it gives a good introduction into the library and how it
can be used in an application. Forward references are included where
necessary. Later on, the manual can be used as a reference manual to
get just the information needed about any particular interface of the
library. Experienced programmers might want to start looking at the
examples at the end of the manual, and then only read up those parts
of the interface which are unclear.
@node Features
@section Features
`Libgcrypt' might have a couple of advantages over other libraries doing
a similar job.
@table @asis
@item It's Free Software
Anybody can use, modify, and redistribute it under the terms of the GNU
Lesser General Public License (@pxref{Library Copying}). Note, that
some parts (which are not needed on a GNU or GNU/Linux system) are
subject to the terms of the GNU General Public License
(@pxref{Copying}); please see the README file of the distribution for of
list of these parts.
@item It encapsulates the low level cryptography
`@acronym{Libgcrypt}' provides a high level interface to cryptographic building
blocks using an extendable and flexible API.
@end table
@node Overview
@section Overview
@noindent
The `@acronym{Libgcrypt}' library is fully thread-safe, where it makes
sense to be thread-safe. An exception for thread-safety are some
cryptographic functions that modify a certain context stored in
handles. If the user really intents to use such functions from
different threads on the same handle, he has to take care of the
serialization of such functions himself. If not described otherwise,
every function is thread-safe.
@acronym{Libgcrypt} depends on the library `libgpg-error', which
contains common error handling related code for GnuPG components.
@c **********************************************************
@c ******************* Preparation ************************
@c **********************************************************
@node Preparation
@chapter Preparation
To use `@acronym{Libgcrypt}', you have to perform some changes to your
sources and the build system. The necessary changes are small and
explained in the following sections. At the end of this chapter, it
is described how the library is initialized, and how the requirements
of the library are verified.
@menu
* Header:: What header file you need to include.
* Building sources:: How to build sources using the library.
* Building sources using Automake:: How to build sources with the help of Automake.
* Initializing the library:: How to initialize the library.
* Multi Threading:: How @acronym{Libgcrypt} can be used in a MT environment.
@end menu
@node Header
@section Header
All interfaces (data types and functions) of the library are defined
in the header file `gcrypt.h'. You must include this in all source
files using the library, either directly or through some other header
file, like this:
@example
#include <gcrypt.h>
@end example
The name space of `@acronym{Libgcrypt}' is @code{gcry_*} for function
and type names and @code{GCRY*} for other symbols. In addition the
same name prefixes with one prepended underscore are reserved for
internal use and should never be used by an application. Furthermore
`libgpg-error' defines functions prefixed with `gpg_' and preprocessor
symbols prefixed with `GPG_'. Note that @acronym{Libgcrypt} uses
libgpg-error, which uses @code{gpg_err_*} as name space for function
and type names and @code{GPG_ERR_*} for other symbols, including all
the error codes.
@node Building sources
@section Building sources
If you want to compile a source file including the `gcrypt.h' header
file, you must make sure that the compiler can find it in the
directory hierarchy. This is accomplished by adding the path to the
directory in which the header file is located to the compilers include
file search path (via the @option{-I} option).
However, the path to the include file is determined at the time the
source is configured. To solve this problem, `@acronym{Libgcrypt}' ships with a small
helper program @command{libgcrypt-config} that knows the path to the
include file and other configuration options. The options that need
to be added to the compiler invocation at compile time are output by
the @option{--cflags} option to @command{libgcrypt-config}. The following
example shows how it can be used at the command line:
@example
gcc -c foo.c `libgcrypt-config --cflags`
@end example
Adding the output of @samp{libgcrypt-config --cflags} to the compilers
command line will ensure that the compiler can find the `@acronym{Libgcrypt}' header
file.
A similar problem occurs when linking the program with the library.
Again, the compiler has to find the library files. For this to work,
the path to the library files has to be added to the library search path
(via the @option{-L} option). For this, the option @option{--libs} to
@command{libgcrypt-config} can be used. For convenience, this option
also outputs all other options that are required to link the program
with the `@acronym{Libgcrypt}' libraries (in particular, the @samp{-lgcrypt}
option). The example shows how to link @file{foo.o} with the `@acronym{Libgcrypt}'
library to a program @command{foo}.
@example
gcc -o foo foo.o `libgcrypt-config --libs`
@end example
Of course you can also combine both examples to a single command by
specifying both options to @command{libgcrypt-config}:
@example
gcc -o foo foo.c `libgcrypt-config --cflags --libs`
@end example
@node Building sources using Automake
@section Building sources using Automake
It is much easier if you use GNU Automake instead of writing your own
Makefiles. If you do that you do not have to worry about finding and
invoking the @command{libgcrypt-config} script at all.
@acronym{Libgcrypt} provides an extension to Automake that does all
the work for you.
@c A simple macro for optional variables.
@macro ovar{varname}
@r{[}@var{\varname\}@r{]}
@end macro
@defmac AM_PATH_LIBGCRYPT (@ovar{minimum-version}, @ovar{action-if-found}, @ovar{action-if-not-found})
Check whether @acronym{Libgcrypt} (at least version
@var{minimum-version}, if given) exists on the host system. If it is
found, execute @var{action-if-found}, otherwise do
@var{action-if-not-found}, if given.
Additionally, the function defines @code{LIBGCRYPT_CFLAGS} to the
flags needed for compilation of the program to find the
@file{gcrypt.h} header file, and @code{LIBGCRYPT_LIBS} to the linker
flags needed to link the program to the @acronym{Libgcrypt} library.
@end defmac
You can use the defined Autoconf variables like this in your
@file{Makefile.am}:
@example
AM_CPPFLAGS = $(LIBGCRYPT_CFLAGS)
LDADD = $(LIBGCRYPT_LIBS)
@end example
@node Initializing the library
@section Initializing the library
It is often desirable to check that the version of `@acronym{Libgcrypt}' used is
indeed one which fits all requirements. Even with binary compatibility
new features may have been introduced but due to problem with the
dynamic linker an old version is actually used. So you may want to
check that the version is okay right after program startup.
@deftypefun const char *gcry_check_version (const char *@var{req_version})
The function @code{gcry_check_version} has three purposes. It can be
used to retrieve the version number of the library. In addition it
can verify that the version number is higher than a certain required
version number.
In either case, the function initializes some sub-systems, and for
this reason alone it must be invoked early in your program, before you
make use of the other functions of @acronym{Libgcrypt}.
@end deftypefun
@node Multi Threading
@section Multi Threading
As mentioned earlier, the `@acronym{Libgcrypt}' library is
thread-safe if you adhere to the following requirements:
@itemize @bullet
@item
If your application is multi-threaded, you must set the thread support
callbacks with the @code{GCRYCTL_SET_THREAD_CBS} command
@strong{before} any other function in the library.
This is easy enough if you are indeed writing an application using
Libgcrypt. It is rather problematic if you are writing a library
instead. Here are some tips what to do if you are writing a library:
If your library requires a certain thread package, just initialize
Libgcrypt to use this thread package. If your library supports multiple
thread packages, but needs to be configured, you will have to
implement a way to determine which thread package the application
wants to use with your library anyway. Then configure Libgcrypt to use
this thread package.
If your library is fully reentrant without any special support by a
thread package, then you are lucky indeed. Unfortunately, this does
not relieve you from doing either of the two above, or use a third
option. The third option is to let the application initialize Libgcrypt
for you. Then you are not using Libgcrypt transparently, though.
As if this was not difficult enough, a conflict may arise if two
libraries try to initialize Libgcrypt independently of each others, and
both such libraries are then linked into the same application. To
make it a bit simpler for you, this will probably work, but only if
both libraries have the same requirement for the thread package. This
is currently only supported for the non-threaded case, GNU Pth and
pthread. Support for more thread packages is easy to add, so contact
us if you require it.
@item
The function @code{gcry_check_version} must be called before any other
function in the library, except the @code{GCRYCTL_SET_THREAD_CBS}
command (called via the @code{gcry_control} function), because it
initializes the thread support subsystem in @acronym{Libgcrypt}. To
achieve this in multi-threaded programs, you must synchronize the
memory with respect to other threads that also want to use
@acronym{Libgcrypt}. For this, it is sufficient to call
@code{gcry_check_version} before creating the other threads using
@acronym{Libgcrypt}@footnote{At least this is true for POSIX threads,
as @code{pthread_create} is a function that synchronizes memory with
respects to other threads. There are many functions which have this
property, a complete list can be found in POSIX, IEEE Std 1003.1-2003,
Base Definitions, Issue 6, in the definition of the term ``Memory
Synchronization''. For other thread packages, more relaxed or more
strict rules may apply.}.
@item
As with the function @code{gpg_strerror}, @code{gcry_strerror} is not
thread safe. You have to use @code{gpg_strerror_r} instead.
@end itemize
@acronym{Libgcrypt} contains convenient macros, which define the
necessary thread callbacks for PThread and for GNU Pth:
@table @code
@item GCRY_THREAD_OPTION_PTH_IMPL
This macro defines the following (static) symbols: 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, gcry_threads_pth.
After including this macro, gcry_control() shall be used with a
command of GCRYCTL_SET_THREAD_CBS in order to register the thread
callback structure named ``gcry_threads_pth''.
@item GCRY_THREAD_OPTION_PTHREAD_IMPL
This macro defines the following (static) symbols:
gcry_pthread_mutex_init, gcry_pthread_mutex_destroy, gcry_mutex_lock,
gcry_mutex_unlock, gcry_threads_pthread.
After including this macro, gcry_control() shall be used with a
command of GCRYCTL_SET_THREAD_CBS in order to register the thread
callback structure named ``gcry_threads_pthread''.
@end table
Note that these macros need to be terminated with a semicolon. Keep
in mind that these are convenient macros for C programmers; C++
programmers might have to wrap these macros in an ``extern C'' body.
@c **********************************************************
@c ******************* General ****************************
@c **********************************************************
@node Generalities
@chapter Generalities
@menu
* Controlling the library:: Controlling @acronym{Libgcrypt}'s behavior.
* Modules:: Description of extension modules.
* Error Handling:: Error codes and such.
@end menu
@node Controlling the library
@section Controlling the library
@deftypefun gcry_error_t gcry_control (enum gcry_ctl_cmds @var{cmd}, ...)
This function can be used to influence the general behavior of
@acronym{Libgcrypt} in several ways. Depending on @var{cmd}, more
arguments can or have to be provided.
@table @code
@item GCRYCTL_ENABLE_M_GUARD; Arguments: none
This command enables the built-in memory guard. It must not be used to
activate the memory guard after the memory management has already been
used; therefore it can ONLY be used at initialization time. Note that
the memory guard is NOT used when the user of the library has set his
own memory management callbacks.
@item GCRYCTL_ENABLE_QUICK_RANDOM; Arguments: none
This command activates the use of a highly-insecure, but fast PRNG. It
can only be used at initialization time - FIXME: is this correct?
@item GCRYCTL_DUMP_RANDOM_STATS
This command dumps PRNG related statistics to the librarys logging
stream.
@item GCRYCTL_DUMP_MEMORY_STATS
This command dumps memory manamgent related statistics to the librarys
logging stream.
@item GCRYCTL_DUMP_SECMEM_STATS
This command dumps secure memory manamgent related statistics to the
librarys logging stream.
@item GCRYCTL_DROP_PRIVS
This command disables the use of secure memory and drops the priviliges
of the current process. FIXME.
@item GCRYCTL_DISABLE_SECMEM
This command disables the use of secure memory. FIXME.
@item GCRYCTL_INIT_SECMEM
@item GCRYCTL_TERM_SECMEM
@item GCRYCTL_DISABLE_SECMEM_WARN
@item GCRYCTL_SUSPEND_SECMEM_WARN
@item GCRYCTL_RESUME_SECMEM_WARN
@item GCRYCTL_USE_SECURE_RNDPOOL; Arguments: none
This command tells the PRNG to store random numbers in secure memory.
FIXME: what about initialization time?
@item GCRYCTL_SET_RANDOM_SEED_FILE; Arguments: const char *filename
This command specifies the file, which is to be used as seed file for
the PRNG. If the seed file is registered prior to initialization of the
PRNG, the seed file's content (if it exists and seems to be valid) is
feed into the PRNG pool. After the seed file has been registered, the
PRNG can be signalled to write out the PRNG pool's content into the seed
file with the following command.
@item GCRYCTL_UPDATE_RANDOM_SEED_FILE; Arguments: none
Write out the PRNG pool's content into the registered seed file.
@item GCRYCTL_SET_VERBOSITY
@item GCRYCTL_SET_DEBUG_FLAGS
@item GCRYCTL_CLEAR_DEBUG_FLAGS
@item GCRYCTL_DISABLE_INTERNAL_LOCKING
@item GCRYCTL_ANY_INITIALIZATION_P
@item GCRYCTL_INITIALIZATION_FINISHED_P
@item GCRYCTL_INITIALIZATION_FINISHED
@item GCRYCTL_SET_THREAD_CBS; Arguments: struct ath_ops *ath_ops
This command registers a thread-callback structure. See section ``multi
threading'' for more information on this command.
@item GCRYCTL_FAST_POOL
@end table
@end deftypefun
@node Modules
@section Modules
@acronym{Libgcrypt} supports the use of `extension modules', which
implement algorithms in addition to those already built into the library
directly.
@deftp {Data type} gcry_module_t
This data type represents a `module'.
@end deftp
Functions registering modules provided by the user take a `module
specification structure' as input and return a value of
@code{gcry_module_t} and an ID that is unique in the modules'
category. This ID can be used to reference the newly registered
module. After registering a module successfully, the new functionality
should be able to be used through the normal functions provided by
@acronym{Libgcrypt} until it is unregistered again.
@c **********************************************************
@c ******************* Errors ****************************
@c **********************************************************
@node Error Handling
@section Error Handling
Many functions in @acronym{Libgcrypt} can return an error if they
fail. For this reason, the application should always catch the error
condition and take appropriate measures, for example by releasing the
resources and passing the error up to the caller, or by displaying a
descriptive message to the user and cancelling the operation.
Some error values do not indicate a system error or an error in the
operation, but the result of an operation that failed properly. For
example, if you try to decrypt a tempered message, the decryption will
fail. Another error value actually means that the end of a data
buffer or list has been reached. The following descriptions explain
for many error codes what they mean usually. Some error values have
specific meanings if returned by a certain functions. Such cases are
described in the documentation of those functions.
@acronym{Libgcrypt} uses the @code{libgpg-error} library. This allows
to share the error codes with other components of the GnuPG system,
and thus pass error values transparently from the crypto engine, or
some helper application of the crypto engine, to the user. This way
no information is lost. As a consequence, @acronym{Libgcrypt} does
not use its own identifiers for error codes, but uses those provided
by @code{libgpg-error}. They usually start with @code{GPG_ERR_}.
However, @acronym{Libgcrypt} does provide aliases for the functions
defined in libgpg-error, which might be preferred for name space
consistency.
Most functions in @acronym{Libgcrypt} return an error code in the case
of failure. For this reason, the application should always catch the
error condition and take appropriate measures, for example by
releasing the resources and passing the error up to the caller, or by
displaying a descriptive message to the user and canceling the
operation.
Some error values do not indicate a system error or an error in the
operation, but the result of an operation that failed properly.
GnuPG components, including Libgcrypt, use an extra library named
libgpg-error to provide a common error handling scheme. For more
information on libgpg-error, see the according manual.
@menu
* Error Values:: The error value and what it means.
* Error Sources:: A list of important error sources.
* Error Codes:: A list of important error codes.
* Error Strings:: How to get a descriptive string from a value.
@end menu
@node Error Values
@subsection Error Values
@cindex error values
@cindex error codes
@cindex error sources
@deftp {Data type} {gcry_err_code_t}
The @code{gcry_err_code_t} type is an alias for the
@code{libgpg-error} type @code{gpg_err_code_t}. The error code
indicates the type of an error, or the reason why an operation failed.
A list of important error codes can be found in the next section.
@end deftp
@deftp {Data type} {gcry_err_source_t}
The @code{gcry_err_source_t} type is an alias for the
@code{libgpg-error} type @code{gpg_err_source_t}. The error source
has not a precisely defined meaning. Sometimes it is the place where
the error happened, sometimes it is the place where an error was
encoded into an error value. Usually the error source will give an
indication to where to look for the problem. This is not always true,
but it is attempted to achieve this goal.
A list of important error sources can be found in the next section.
@end deftp
@deftp {Data type} {gcry_error_t}
The @code{gcry_error_t} type is an alias for the @code{libgpg-error}
type @code{gpg_error_t}. An error value like this has always two
components, an error code and an error source. Both together form the
error value.
Thus, the error value can not be directly compared against an error
code, but the accessor functions described below must be used.
However, it is guaranteed that only 0 is used to indicate success
(@code{GPG_ERR_NO_ERROR}), and that in this case all other parts of
the error value are set to 0, too.
Note that in @acronym{Libgcrypt}, the error source is used purely for
diagnostic purposes. Only the error code should be checked to test
for a certain outcome of a function. The manual only documents the
error code part of an error value. The error source is left
unspecified and might be anything.
@end deftp
@deftypefun {gcry_err_code_t} gcry_err_code (@w{gcry_error_t @var{err}})
The static inline function @code{gcry_err_code} returns the
@code{gcry_err_code_t} component of the error value @var{err}. This
function must be used to extract the error code from an error value in
order to compare it with the @code{GPG_ERR_*} error code macros.
@end deftypefun
@deftypefun {gcry_err_source_t} gcry_err_source (@w{gcry_error_t @var{err}})
The static inline function @code{gcry_err_source} returns the
@code{gcry_err_source_t} component of the error value @var{err}. This
function must be used to extract the error source from an error value in
order to compare it with the @code{GPG_ERR_SOURCE_*} error source macros.
@end deftypefun
@deftypefun {gcry_error_t} gcry_err_make (@w{gcry_err_source_t @var{source}}, @w{gcry_err_code_t @var{code}})
The static inline function @code{gcry_err_make} returns the error
value consisting of the error source @var{source} and the error code
@var{code}.
This function can be used in callback functions to construct an error
value to return it to the library.
@end deftypefun
@deftypefun {gcry_error_t} gcry_error (@w{gcry_err_code_t @var{code}})
The static inline function @code{gcry_error} returns the error value
consisting of the default error source and the error code @var{code}.
For @acronym{GCRY} applications, the default error source is
@code{GPG_ERR_SOURCE_USER_1}. You can define
@code{GCRY_ERR_SOURCE_DEFAULT} before including @file{gcrypt.h} to
change this default.
This function can be used in callback functions to construct an error
value to return it to the library.
@end deftypefun
The @code{libgpg-error} library provides error codes for all system
error numbers it knows about. If @var{err} is an unknown error
number, the error code @code{GPG_ERR_UNKNOWN_ERRNO} is used. The
following functions can be used to construct error values from system
errno numbers.
@deftypefun {gcry_error_t} gcry_err_make_from_errno (@w{gcry_err_source_t @var{source}}, @w{int @var{err}})
The function @code{gcry_err_make_from_errno} is like
@code{gcry_err_make}, but it takes a system error like @code{errno}
instead of a @code{gcry_err_code_t} error code.
@end deftypefun
@deftypefun {gcry_error_t} gcry_error_from_errno (@w{int @var{err}})
The function @code{gcry_error_from_errno} is like @code{gcry_error},
but it takes a system error like @code{errno} instead of a
@code{gcry_err_code_t} error code.
@end deftypefun
Sometimes you might want to map system error numbers to error codes
directly, or map an error code representing a system error back to the
system error number. The following functions can be used to do that.
@deftypefun {gcry_err_code_t} gcry_err_code_from_errno (@w{int @var{err}})
The function @code{gcry_err_code_from_errno} returns the error code
for the system error @var{err}. If @var{err} is not a known system
error, the function returns @code{GPG_ERR_UNKNOWN_ERRNO}.
@end deftypefun
@deftypefun {int} gcry_err_code_to_errno (@w{gcry_err_code_t @var{err}})
The function @code{gcry_err_code_to_errno} returns the system error
for the error code @var{err}. If @var{err} is not an error code
representing a system error, or if this system error is not defined on
this system, the function returns @code{0}.
@end deftypefun
@node Error Sources
@subsection Error Sources
@cindex error codes, list of
The library @code{libgpg-error} defines an error source for every
component of the GnuPG system. The error source part of an error
value is not well defined. As such it is mainly useful to improve the
diagnostic error message for the user.
If the error code part of an error value is @code{0}, the whole error
value will be @code{0}. In this case the error source part is of
course @code{GPG_ERR_SOURCE_UNKNOWN}.
The list of error sources that might occur in applications using
@acronym{Libgctypt} is:
@table @code
@item GPG_ERR_SOURCE_UNKNOWN
The error source is not known. The value of this error source is
@code{0}.
@item GPG_ERR_SOURCE_GPGME
The error source is @acronym{GPGME} itself.
@item GPG_ERR_SOURCE_GPG
The error source is GnuPG, which is the crypto engine used for the
OpenPGP protocol.
@item GPG_ERR_SOURCE_GPGSM
The error source is GPGSM, which is the crypto engine used for the
OpenPGP protocol.
@item GPG_ERR_SOURCE_GCRYPT
The error source is @code{libgcrypt}, which is used by crypto engines
to perform cryptographic operations.
@item GPG_ERR_SOURCE_GPGAGENT
The error source is @command{gpg-agent}, which is used by crypto
engines to perform operations with the secret key.
@item GPG_ERR_SOURCE_PINENTRY
The error source is @command{pinentry}, which is used by
@command{gpg-agent} to query the passphrase to unlock a secret key.
@item GPG_ERR_SOURCE_SCD
The error source is the SmartCard Daemon, which is used by
@command{gpg-agent} to delegate operations with the secret key to a
SmartCard.
@item GPG_ERR_SOURCE_KEYBOX
The error source is @code{libkbx}, a library used by the crypto
engines to manage local keyrings.
@item GPG_ERR_SOURCE_USER_1
@item GPG_ERR_SOURCE_USER_2
@item GPG_ERR_SOURCE_USER_3
@item GPG_ERR_SOURCE_USER_4
These error sources are not used by any GnuPG component and can be
used by other software. For example, applications using
@acronym{Libgcrypt} can use them to mark error values coming from callback
handlers. Thus @code{GPG_ERR_SOURCE_USER_1} is the default for errors
created with @code{gcry_error} and @code{gcry_error_from_errno},
unless you define @code{GCRY_ERR_SOURCE_DEFAULT} before including
@file{gcrypt.h}.
@end table
@node Error Codes
@subsection Error Codes
@cindex error codes, list of
The library @code{libgpg-error} defines many error values. The
following list includes the most important error codes.
@table @code
@item GPG_ERR_EOF
This value indicates the end of a list, buffer or file.
@item GPG_ERR_NO_ERROR
This value indicates success. The value of this error code is
@code{0}. Also, it is guaranteed that an error value made from the
error code @code{0} will be @code{0} itself (as a whole). This means
that the error source information is lost for this error code,
however, as this error code indicates that no error occured, this is
generally not a problem.
@item GPG_ERR_GENERAL
This value means that something went wrong, but either there is not
enough information about the problem to return a more useful error
value, or there is no separate error value for this type of problem.
@item GPG_ERR_ENOMEM
This value means that an out-of-memory condition occurred.
@item GPG_ERR_E...
System errors are mapped to GPG_ERR_EFOO where FOO is the symbol for
the system error.
@item GPG_ERR_INV_VALUE
This value means that some user provided data was out of range.
@item GPG_ERR_UNUSABLE_PUBKEY
This value means that some recipients for a message were invalid.
@item GPG_ERR_UNUSABLE_SECKEY
This value means that some signers were invalid.
@item GPG_ERR_NO_DATA
This value means that data was expected where no data was found.
@item GPG_ERR_CONFLICT
This value means that a conflict of some sort occurred.
@item GPG_ERR_NOT_IMPLEMENTED
This value indicates that the specific function (or operation) is not
implemented. This error should never happen. It can only occur if
you use certain values or configuration options which do not work,
but for which we think that they should work at some later time.
@item GPG_ERR_DECRYPT_FAILED
This value indicates that a decryption operation was unsuccessful.
@item GPG_ERR_WRONG_KEY_USAGE
This value indicates that a key is not used appropriately.
@item GPG_ERR_NO_SECKEY
This value indicates that no secret key for the user ID is available.
@item GPG_ERR_UNSUPPORTED_ALGORITHM
This value means a verification failed because the cryptographic
algorithm is not supported by the crypto backend.
@item GPG_ERR_BAD_SIGNATURE
This value means a verification failed because the signature is bad.
@item GPG_ERR_NO_PUBKEY
This value means a verification failed because the public key is not
available.
@item GPG_ERR_USER_1
@item GPG_ERR_USER_2
@item ...
@item GPG_ERR_USER_16
These error codes are not used by any GnuPG component and can be
freely used by other software. Applications using @acronym{Libgcrypt}
might use them to mark specific errors returned by callback handlers
if no suitable error codes (including the system errors) for these
errors exist already.
@end table
@node Error Strings
@subsection Error Strings
@cindex error values, printing of
@cindex error codes, printing of
@cindex error sources, printing of
@cindex error strings
@deftypefun {const char *} gcry_strerror (@w{gcry_error_t @var{err}})
The function @code{gcry_strerror} returns a pointer to a statically
allocated string containing a description of the error code contained
in the error value @var{err}. This string can be used to output a
diagnostic message to the user.
@end deftypefun
@deftypefun {const char *} gcry_strsource (@w{gcry_error_t @var{err}})
The function @code{gcry_strerror} returns a pointer to a statically
allocated string containing a description of the error source
contained in the error value @var{err}. This string can be used to
output a diagnostic message to the user.
@end deftypefun
The following example illustrates the use of the functions described
above:
@example
@{
gcry_cipher_hd_t handle;
gcry_error_t err = 0;
err = gcry_cipher_open (&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
if (err)
@{
fprintf (stderr, "Failure: %s/%s\n",
gcry_strsource (err),
gcry_strerror (err));
@}
@}
@end example
@c **********************************************************
@c ******************* General ****************************
@c **********************************************************
@node Handler Functions
@chapter Handler Functions
@acronym{Libgcrypt} makes it possible to install so called `handler functions',
which get called by @acronym{Libgcrypt} in case of certain events.
@menu
* Progress handler:: Using a progress handler function.
* Allocation handler:: Using special memory allocation functions.
* Error handler:: Using error handler functions.
* Logging handler:: Using a special logging function.
@end menu
@node Progress handler
@section Progress handler
It is often useful to retrieve some feedback while long running
operations are performed.
@deftp {Data type} gcry_handler_progress_t
Progress handler functions have to be of the type
@code{gcry_handler_progress_t}, which is defined as:
@code{void (*gcry_handler_progress_t) (void *, const char *, int, int, int)}
@end deftp
The following function may be used to register a handler function for
this purpose.
@deftypefun void gcry_set_progress_handler (gcry_handler_progress_t @var{cb}, void *@var{cb_data})
This function installs @var{cb} as the `Progress handler' function.
@var{cb} must be defined as follows:
@example
void
my_progress_handler (void *@var{cb_data}, const char *@var{what},
int @var{printchar}, int @var{current}, int @var{total})
@{
/* Do something. */
@}
@end example
A description of the arguments of the progress handler function follows.
@table @var
@item cb_data
The argument provided in the call to @code{gcry_set_progress_handler}.
@item what
A string identifying the type of the progress output. The following
values for @var{what} are defined:
@table @code
@item need_entropy
Not enough entropy is available. @var{total} holds the number of
required bytes.
@item primegen
Values for @var{printchar}:
@table @code
@item \n
Prime generated.
@item !
Need to refresh the pool of prime numbers.
@item <, >
Number of bits adjusted.
@item ^
Searching for a generator.
@item .
Fermat test on 10 candidates failed.
@item :
Restart with a new random value.
@item +
Rabin Miller test passed.
@end table
@end table
@end table
@end deftypefun
@node Allocation handler
@section Allocation handler
It is possible to make @acronym{Libgcrypt} use special memory
allocation functions instead of the built-in ones.
Memory allocation functions are of the following types:
@deftp {Data type} gcry_handler_alloc_t
This type is defined as: @code{void *(*gcry_handler_alloc_t) (size_t n)}.
@end deftp
@deftp {Data type} gcry_handler_secure_check_t
This type is defined as: @code{int *(*gcry_handler_secure_check_t) (const void *)}.
@end deftp
@deftp {Data type} gcry_handler_realloc_t
This type is defined as: @code{void *(*gcry_handler_realloc_t) (void *p, size_t n)}.
@end deftp
@deftp {Data type} gcry_handler_free_t
This type is defined as: @code{void *(*gcry_handler_free_t) (void *)}.
@end deftp
Special memory allocation functions can be installed with the
following function:
@deftypefun void gcry_set_allocation_handler (gcry_handler_alloc_t @var{func_alloc}, gcry_handler_alloc_t @var{func_alloc_secure}, gcry_handler_secure_check_t @var{func_secure_check}, gcry_handler_realloc_t @var{func_realloc}, gcry_handler_free_t @var{func_free})
Install the provided functions and use them instead of the built-in
functions for doing memory allocation.
@end deftypefun
@node Error handler
@section Error handler
The following functions may be used to register handler functions that
are called by @acronym{Libgcrypt} in case certain error conditions
occur.
@deftp {Data type} gcry_handler_no_mem_t
This type is defined as: @code{void (*gcry_handler_no_mem_t) (void *, size_t, unsigned int)}
@end deftp
@deftypefun void gcry_set_outofcore_handler (gcry_handler_no_mem_t @var{func_no_mem}, void *@var{cb_data})
This function registers @var{func_no_mem} as `out-of-core handler',
which means that it will be called in the case of not having enough
memory available.
@end deftypefun
@deftp {Data type} gcry_handler_error_t
This type is defined as: @code{void (*gcry_handler_error_t) (void *, int, const char *)}
@end deftp
@deftypefun void gcry_set_fatalerror_handler (gcry_handler_error_t @var{func_error}, void *@var{cb_data})
This function registers @var{func_error} as `error handler',
which means that it will be called in error conditions.
@end deftypefun
@node Logging handler
@section Logging handler
@deftp {Data type} gcry_handler_log_t
This type is defined as: @code{void (*gcry_handler_log_t) (void *, int, const char *, va_list)}
@end deftp
@deftypefun void gcry_set_log_handler (gcry_handler_log_t @var{func_log}, void *@var{cb_data})
This function registers @var{func_log} as `logging handler', which
means that it will be called in case @acronym{Libgcrypt} wants to log
a message.
@end deftypefun
@c **********************************************************
@c ******************* Ciphers ****************************
@c **********************************************************
@c @include cipher-ref.texi
@node Symmetric cryptography
@chapter Symmetric cryptography
The cipher functions are used for symmetrical cryptography,
i.e. cryptography using a shared key. The programming model follows
an open/process/close paradigm and is in that similar to other
building blocks provided by @acronym{Libgcrypt}.
@menu
* Available ciphers:: List of ciphers supported by the library.
* Cipher modules:: How to work with cipher modules.
* Available cipher modes:: List of cipher modes supported by the library.
* Working with cipher handles:: How to perform operations related to cipher handles.
* General cipher functions:: General cipher functions independent of cipher handles.
@end menu
@node Available ciphers
@section Available ciphers
@table @code
@item GCRY_CIPHER_NONE
This is not a real algorithm but used by some functions as error return.
The value always evaluates to false.
@item GCRY_CIPHER_IDEA
This is the IDEA algorithm. The constant is provided but there is
currently no implementation for it because the algorithm is patented.
@item GCRY_CIPHER_3DES
Triple-DES with 3 Keys as EDE. The key size of this algorithm is 168 but
you have to pass 192 bits because the most significant bits of each byte
are ignored.
@item GCRY_CIPHER_CAST5
CAST128-5 block cipher algorithm. The key size is 128 bits.
@item GCRY_CIPHER_BLOWFISH
The blowfish algorithm. The current implementation allows only for a key
size of 128 bits.
@item GCRY_CIPHER_SAFER_SK128
Reserved and not currently implemented.
@item GCRY_CIPHER_DES_SK
Reserved and not currently implemented.
@item GCRY_CIPHER_AES
@itemx GCRY_CIPHER_AES128
@itemx GCRY_CIPHER_RIJNDAEL
@itemx GCRY_CIPHER_RIJNDAEL128
AES (Rijndael) with a 128 bit key.
@item GCRY_CIPHER_AES192
@itemx GCRY_CIPHER_RIJNDAEL192
AES (Rijndael) with a 192 bit key.
@item GCRY_CIPHER_AES256
@itemx GCRY_CIPHER_RIJNDAEL256
AES (Rijndael) with a 256 bit key.
@item GCRY_CIPHER_TWOFISH
The Twofish algorithm with a 256 bit key.
@item GCRY_CIPHER_TWOFISH128
The Twofish algorithm with a 128 bit key.
@item GCRY_CIPHER_ARCFOUR
An algorithm which is 100% compatible with RSA Inc.'s RC4 algorithm.
Note that this is a stream cipher and must be used very carefully to
avoid a couple of weaknesses.
@item GCRY_CIPHER_DES
Standard DES with a 56 bit key. You need to pass 64 bit but the high
bits of each byte are ignored. Note, that this is a weak algorithm
which can be broken in reasonable time using a brute force approach.
@end table
@node Cipher modules
@section Cipher modules
@acronym{Libgcrypt} makes it possible to load additional `cipher
modules'; these cipher can be used just like the cipher algorithms
that are built into the library directly. For an introduction into
extension modules, see @xref{Modules}.
@deftp {Data type} gcry_cipher_spec_t
This is the `module specification structure' needed for registering
cipher modules, which has to be filled in by the user before it can be
used to register a module. It contains the following members:
@table @code
@item const char *name
The primary name of the algorithm.
@item const char **aliases
A list of strings that are `aliases' for the algorithm. The list must
be terminated with a NULL element.
@item gcry_cipher_oid_spec_t *oids
A list of OIDs that are to be associated with the algorithm. The
list's last element must have it's `oid' member set to NULL. See
below for an explanation of this type.
@item size_t blocksize
The block size of the algorithm, in bytes.
@item size_t keylen
The length of the key, in bits.
@item size_t contextsize
The size of the algorithm-specific `context', that should be allocated
for each handle.
@item gcry_cipher_setkey_t setkey
The function responsible for initializing a handle with a provided
key. See below for a description of this type.
@item gcry_cipher_encrypt_t encrypt
The function responsible for encrypting a single block. See below for
a description of this type.
@item gcry_cipher_decrypt_t decrypt
The function responsible for decrypting a single block. See below for
a description of this type.
@item gcry_cipher_stencrypt_t stencrypt
Like `encrypt', for stream ciphers. See below for a description of
this type.
@item gcry_cipher_stdecrypt_t stdecrypt
Like `decrypt', for stream ciphers. See below for a description of
this type.
@end table
@end deftp
@deftp {Data type} gcry_cipher_oid_spec_t
This type is used for associating a user-provided algorithm
implementation with certain OIDs. It contains the following members:
@table @code
@item const char *oid
Textual representation of the OID.
@item int mode
Cipher mode for which this OID is valid.
@end table
@end deftp
@deftp {Data type} gcry_cipher_setkey_t
Type for the `setkey' function, defined as: gcry_err_code_t
(*gcry_cipher_setkey_t) (void *c, const unsigned char *key, unsigned
keylen)
@end deftp
@deftp {Data type} gcry_cipher_encrypt_t
Type for the `encrypt' function, defined as: gcry_err_code_t
(*gcry_cipher_encrypt_t) (void *c, const unsigned char *outbuf, const
unsigned char *inbuf)
@end deftp
@deftp {Data type} gcry_cipher_decrypt_t
Type for the `decrypt' function, defined as: gcry_err_code_t
(*gcry_cipher_decrypt_t) (void *c, const unsigned char *outbuf, const
unsigned char *inbuf)
@end deftp
@deftp {Data type} gcry_cipher_stencrypt_t
Type for the `stencrypt' function, defined as: gcry_err_code_t
(*gcry_cipher_stencrypt_t) (void *c, const unsigned char *outbuf, const
unsigned char *, unsigned int n)
@end deftp
@deftp {Data type} gcry_cipher_stdecrypt_t
Type for the `stdecrypt' function, defined as: gcry_err_code_t
(*gcry_cipher_stdecrypt_t) (void *c, const unsigned char *outbuf, const
unsigned char *, unsigned int n)
@end deftp
@deftypefun gcry_error_t gcry_cipher_register (gcry_cipher_spec_t *@var{cipher}, unsigned int *algorithm_id, gcry_module_t *@var{module})
Register a new cipher module whose specification can be found in
@var{cipher}. On success, a new algorithm ID is stored in
@var{algorithm_id} and a pointer representing this module is stored
in @var{module}.
@end deftypefun
@deftypefun void gcry_cipher_unregister (gcry_module_t @var{module})
Unregister the cipher identified by @var{module}, which must have been
registered with gcry_cipher_register.
@end deftypefun
@deftypefun gcry_error_t gcry_cipher_list (int *@var{list}, int *@var{list_length})
Get a list consisting of the IDs of the loaded cipher modules. If
@var{list} is zero, write the number of loaded cipher modules to
@var{list_length} and return. If @var{list} is non-zero, the first
*@var{list_length} algorithm IDs are stored in @var{list}, which must
be of according size. In case there are less cipher modules than
*@var{list_length}, *@var{list_length} is updated to the correct
number.
@end deftypefun
@node Available cipher modes
@section Available cipher modes
@table @code
@item GCRY_CIPHER_MODE_NONE
No mode specified, may be set later using other functions. The value
of this constant is always 0.
@item GCRY_CIPHER_MODE_ECB
Electronic Codebook mode.
@item GCRY_CIPHER_MODE_CFB
Cipher Feedback mode.
@item GCRY_CIPHER_MODE_CBC
Cipher Block Chaining mode.
@item GCRY_CIPHER_MODE_STREAM
Stream mode, only to be used with stream cipher algorithms.
@item GCRY_CIPHER_MODE_OFB
-Outer Feedback mode.
+Output Feedback mode.
@item GCRY_CIPHER_MODE_CTR
Counter mode.
@end table
@node Working with cipher handles
@section Working with cipher handles
To use a cipher algorithm, you must first allocate an according
handle. This is to be done using the open function:
@deftypefun gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *@var{hd}, int @var{algo}, int @var{mode}, unsigned int @var{flags})
This function creates the context handle required for most of the
other cipher functions and returns a handle to it in `hd'. In case of
an error, an according error code is returned.
The ID of algorithm to use must be specified via @var{algo}. See
@xref{Available ciphers}, for a list of supported ciphers and the
according constants.
Besides using the constants directly, the function
@code{gcry_cipher_map_name} may be used to convert the textual name of
an algorithm into the according numeric ID.
The cipher mode to use must be specified via @var{mode}. See
@xref{Available cipher modes}, for a list of supported cipher modes
-and the according constants. Note, that some modes do not work
-together with all algorithms.
+and the according constants. Note that some modes are incompatible
+with some algorithms - in particular, stream mode
+(GCRY_CIPHER_MODE_STREAM) only works with stream ciphers. Any block
+cipher mode (GCRY_CIPHER_MODE_ECB, GCRY_CIPHER_MODE_CBC,
+GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_MODE_OFB or GCRY_CIPHER_MODE_CTR)
+will work with any block cipher algorithm.
The third argument @var{flags} can either be passed as @code{0} or as
the bit-wise OR of the following constants.
@table @code
@item GCRY_CIPHER_SECURE
Make sure that all operations are allocated in secure memory. This is
useful, when the key material is highly confidential.
@item GCRY_CIPHER_ENABLE_SYNC
This flag enables the CFB sync mode, which is a special feature of
@acronym{Libgcrypt}'s CFB mode implementation to allow for OpenPGP's CFB variant.
See @code{gcry_cipher_sync}.
@item GCRY_CIPHER_CBC_CTS
Enable cipher text stealing (CTS) for the CBC mode. Cannot be used
simultaneous as GCRY_CIPHER_CBC_MAC. CTS mode makes it possible to
transform data of almost arbitrary size (only limitation is that it
must be greater than the algorithm's block size).
@item GCRY_CIPHER_CBC_MAC
Compute CBC-MAC keyed checksums. This is the same as CBC mode, but
only output the last block. Cannot be used simultaneous as
GCRY_CIPHER_CBC_CTS.
@end table
@end deftypefun
Use the following function to release an existing handle:
@deftypefun void gcry_cipher_close (gcry_cipher_hd_t @var{h})
This function releases the context created by @code{gcry_cipher_open}.
@end deftypefun
In order to use a handle for performing cryptographic operations, a
`key' has to be set first:
@deftypefun gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t @var{h}, void *@var{k}, size_t @var{l})
Set the key @var{k} used for encryption or decryption in the context
denoted by the handle @var{h}. The length @var{l} of the key @var{k}
must match the required length of the algorithm set for this context or
be in the allowed range for algorithms with variable key size. The
function checks this and returns an error if there is a problem. A
caller should always check for an error.
Note, this is currently implemented as a macro but may be changed to a
function in the future.
@end deftypefun
Most crypto modes requires an initialization vector (IV), which
usually is a non-secret random string acting as a kind of salt value.
The CTR mode requires a counter, which is also similar to a salt
value. To set the IV or CTR, use these functions:
@deftypefun gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t @var{h}, void *@var{k}, size_t @var{l})
Set the initialization vector used for encryption or decryption. The
vector is passed as the buffer @var{K} of length @var{l} and copied to
internal data structures. The function checks that the IV matches the
requirement of the selected algorithm and mode. Note, that this is
implemented as a macro.
@end deftypefun
@deftypefun gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t @var{h}, void *@var{c}, size_t @var{l})
Set the counter vector used for encryption or decryption. The counter
is passed as the buffer @var{c} of length @var{l} and copied to
internal data structures. The function checks that the counter
matches the requirement of the selected algorithm (i.e., it must be
the same size as the block size). Note, that this is implemented as a
macro.
@end deftypefun
@deftypefun gcry_error_t gcry_cipher_reset (gcry_cipher_hd_t @var{h})
Set the given handle's context back to the state it had after the last
call to gcry_cipher_setkey and clear the initialization vector.
Note, that gcry_cipher_reset is implemented as a macro.
@end deftypefun
The actual encryption and decryption is done by using one of the
following functions. They may be used as often as required to process
all the data.
@deftypefun gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t @var{h}, unsigned char *{out}, size_t @var{outsize}, const unsigned char *@var{in}, size_t @var{inlen})
@code{gcry_cipher_encrypt} is used to encrypt the data. This function
can either work in place or with two buffers. It uses the cipher
context already setup and described by the handle @var{h}. There are 2
ways to use the function: If @var{in} is passed as @code{NULL} and
@var{inlen} is @code{0}, in-place encryption of the data in @var{out} or
length @var{outsize} takes place. With @var{in} being not @code{NULL},
@var{inlen} bytes are encrypted to the buffer @var{out} which must have
at least a size of @var{inlen}. @var{outsize} must be set to the
allocated size of @var{out}, so that the function can check that there
is sufficient space. Note, that overlapping buffers are not allowed.
Depending on the selected algorithms and encryption mode, the length of
the buffers must be a multiple of the block size.
The function returns @code{0} on success or an error code.
@end deftypefun
@deftypefun gcry_error_t gcry_cipher_decrypt (gcry_cipher_hd_t @var{h}, unsigned char *{out}, size_t @var{outsize}, const unsigned char *@var{in}, size_t @var{inlen})
@code{gcry_cipher_decrypt} is used to decrypt the data. This function
can either work in place or with two buffers. It uses the cipher
context already setup and described by the handle @var{h}. There are 2
ways to use the function: If @var{in} is passed as @code{NULL} and
@var{inlen} is @code{0}, in-place decryption of the data in @var{out} or
length @var{outsize} takes place. With @var{in} being not @code{NULL},
@var{inlen} bytes are decrypted to the buffer @var{out} which must have
at least a size of @var{inlen}. @var{outsize} must be set to the
allocated size of @var{out}, so that the function can check that there
is sufficient space. Note, that overlapping buffers are not allowed.
Depending on the selected algorithms and encryption mode, the length of
the buffers must be a multiple of the block size.
The function returns @code{0} on success or an error code.
@end deftypefun
OpenPGP (as defined in RFC-2440) requires a special sync operation in
some places, the following function is used for this:
@deftypefun gcry_error_t gcry_cipher_sync (gcry_cipher_hd_t @var{h})
Perform the OpenPGP sync operation on context @var{h}. Note, that this
is a no-op unless the context was created with the flag
@code{GCRY_CIPHER_ENABLE_SYNC}
@end deftypefun
Some of the described functions are implemented as macros utilizing a
catch-all control function. This control function is rarely used
directly but there is nothing which would inhibit it:
@deftypefun gcry_error_t gcry_cipher_ctl (gcry_cipher_hd_t @var{h}, int @var{cmd}, void *@var{buffer}, size_t @var{buflen})
@code{gcry_cipher_ctl} controls various aspects of the cipher module and
specific cipher contexts. Usually some more specialized functions or
macros are used for this purpose. The semantics of the function and its
parameters depends on the the command @var{cmd} and the passed context
handle @var{h}. Please see the comments in the source code
(@code{src/global.c}) for details.
@end deftypefun
@deftypefun gcry_error_t gcry_cipher_info (gcry_cipher_hd_t @var{h}, int @var{what}, void *@var{buffer}, size_t *@var{nbytes})
@code{gcry_cipher_info} is used to retrieve various
information about a cipher context or the cipher module in general.
Currently no information is available.
@end deftypefun
@node General cipher functions
@section General cipher functions
To work with the algorithms, several functions are available to map
algorithm names to the internal identifiers, as well as ways to
retrieve information about an algorithm or the current cipher context.
@deftypefun gcry_error_t gcry_cipher_algo_info (int @var{algo}, int @var{what}, void *@var{buffer}, size_t *@var{nbytes})
This function is used to retrieve information on a specific algorithm.
You pass the cipher algorithm ID as @var{algo} and the type of
information requested as @var{what}. The result is either returned as
the return code of the function or copied to the provided @var{buffer}
whose allocated length must be available in an integer variable with the
address passed in @var{nbytes}. This variable will also receive the
actual used length of the buffer.
Here is a list of supported codes for @var{what}:
@c begin constants for gcry_cipher_algo_info
@table @code
@item GCRYCTL_GET_KEYLEN:
Return the length of the key. If the algorithm supports multiple key
lengths, the maximum supported value is returned. The length is
returned as number of octets (bytes) and not as number of bits in
@var{nbytes}; @var{buffer} must be zero.
@item GCRYCTL_GET_BLKLEN:
Return the block length of the algorithm. The length is returned as a
number of octets in @var{nbytes}; @var{buffer} must be zero.
@item GCRYCTL_TEST_ALGO:
Returns @code{0} when the specified algorithm is available for use.
@var{buffer} and @var{nbytes} must be zero.
@end table
@c end constants for gcry_cipher_algo_info
@end deftypefun
@c end gcry_cipher_algo_info
@deftypefun const char *gcry_cipher_algo_name (int @var{algo})
@code{gcry_cipher_algo_name} returns a string with the name of the
cipher algorithm @var{algo}. If the algorithm is not known or another
error occurred, an empty string is returned. This function will never
return @code{NULL}.
@end deftypefun
@deftypefun int gcry_cipher_map_name (const char *@var{name})
@code{gcry_cipher_map_name} returns the algorithm identifier for the
cipher algorithm described by the string @var{name}. If this algorithm
is not available @code{0} is returned.
@end deftypefun
@deftypefun int gcry_cipher_mode_from_oid (const char *@var{string})
Return the cipher mode associated with an @acronym{ASN.1} object
identifier. The object identifier is expected to be in the
@acronym{IETF}-style dotted decimal notation. The function returns
@code{0} for an unknown object identifier or when no mode is associated
with it.
@end deftypefun
@c **********************************************************
@c ******************* Hash Functions *********************
@c **********************************************************
@node Hashing
@chapter Hashing
@acronym{Libgcrypt} provides an easy and consistent to use interface
for hashing. Hashing is buffered and several hash algorithms can be
updated at once. It is possible to calculate a MAC using the same
routines. The programming model follows an open/process/close
paradigm and is in that similar to other building blocks provided by
@acronym{Libgcrypt}.
For convenience reasons, a few cyclic redundancy check value operations
are also supported.
@menu
* Available hash algorithms:: List of hash algorithms supported by the library.
* Hash algorithm modules:: How to work with hash algorithm modules.
* Working with hash algorithms:: List of functions related to hashing.
@end menu
@node Available hash algorithms
@section Available hash algorithms
@c begin table of hash algorithms
@table @code
@item GCRY_MD_NONE
This is not a real algorithm but used by some functions as an error
return value. This constant is guaranteed to have the value @code{0}.
@item GCRY_MD_SHA1
This is the SHA-1 algorithm which yields a message digest of 20 bytes.
@item GCRY_MD_RMD160
This is the 160 bit version of the RIPE message digest (RIPE-MD-160).
Like SHA-1 it also yields a digest of 20 bytes.
@item GCRY_MD_MD5
This is the well known MD5 algorithm, which yields a message digest of
16 bytes.
@item GCRY_MD_MD4
This is the MD4 algorithm, which yields a message digest of 16 bytes.
@item GCRY_MD_MD2
This is an reserved identifier for MD-2; there is no implementation yet.
@item GCRY_MD_TIGER
This is the TIGER/192 algorithm which yields a message digest of 24 bytes.
@item GCRY_MD_HAVAL
This is an reserved for the HAVAL algorithm with 5 passes and 160
bit. It yields a message digest of 20 bytes. Note that there is no
implementation yet available.
@item GCRY_MD_SHA256
This is the SHA-256 algorithm which yields a message digest of 32 bytes.
See FIPS 180-2 for the specification.
@item GCRY_MD_SHA384
This is reserved for SHA-2 with 384 bits. It yields a message digest of
48 bytes. Note that there is no implementation yet available.
@item GCRY_MD_SHA512
This is reserved for SHA-2 with 512 bits. It yields a message digest of
64 bytes. Note that there is no implementation yet available.
@item GCRY_MD_CRC32
This is the ISO 3309 and ITU-T V.42 cyclic redundancy check. It
yields an output of 4 bytes.
@item GCRY_MD_CRC32_RFC1510
This is the above cyclic redundancy check function, as modified by RFC
1510. It yields an output of 4 bytes.
@item GCRY_MD_CRC24_RFC2440
This is the OpenPGP cyclic redundancy check function. It yields an
output of 3 bytes.
@item GCRY_MD_WHIRLPOOL
This is the Whirlpool algorithm which yields a message digest of 64
bytes.
@end table
@c end table of hash algorithms
@node Hash algorithm modules
@section Hash algorithm modules
@acronym{Libgcrypt} makes it possible to load additional `message
digest modules'; these cipher can be used just like the message digest
algorithms that are built into the library directly. For an
introduction into extension modules, see @xref{Modules}.
@deftp {Data type} gcry_md_spec_t
This is the `module specification structure' needed for registering
message digest modules, which has to be filled in by the user before
it can be used to register a module. It contains the following
members:
@table @code
@item const char *name
The primary name of this algorithm.
@item unsigned char *asnoid
Array of bytes that form the ASN OID.
@item int asnlen
Length of bytes in `asnoid'.
@item gcry_md_oid_spec_t *oids
A list of OIDs that are to be associated with the algorithm. The
list's last element must have it's `oid' member set to NULL. See
below for an explanation of this type. See below for an explanation
of this type.
@item int mdlen
Length of the message digest algorithm. See below for an explanation
of this type.
@item gcry_md_init_t init
The function responsible for initializing a handle. See below for an
explanation of this type.
@item gcry_md_write_t write
The function responsible for writing data into a message digest
context. See below for an explanation of this type.
@item gcry_md_final_t final
The function responsible for `finalizing' a message digest context.
See below for an explanation of this type.
@item gcry_md_read_t read
The function responsible for reading out a message digest result. See
below for an explanation of this type.
@item size_t contextsize
The size of the algorithm-specific `context', that should be
allocated for each handle.
@end table
@end deftp
@deftp {Data type} gcry_md_oid_spec_t
This type is used for associating a user-provided algorithm
implementation with certain OIDs. It contains the following members:
@table @code
@item const char *oidstring
Textual representation of the OID.
@end table
@end deftp
@deftp {Data type} gcry_md_init_t
Type for the `init' function, defined as: void (*gcry_md_init_t) (void
*c)
@end deftp
@deftp {Data type} gcry_md_write_t
Type for the `write' function, defined as: void (*gcry_md_write_t)
(void *c, unsigned char *buf, size_t nbytes)
@end deftp
@deftp {Data type} gcry_md_final_t
Type for the `final' function, defined as: void (*gcry_md_final_t)
(void *c)
@end deftp
@deftp {Data type} gcry_md_read_t
Type for the `read' function, defined as: unsigned char
*(*gcry_md_read_t) (void *c)
@end deftp
@deftypefun gcry_error_t gcry_md_register (gcry_md_spec_t *@var{digest}, unsigned int *algorithm_id, gcry_module_t *@var{module})
Register a new digest module whose specification can be found in
@var{digest}. On success, a new algorithm ID is stored in
@var{algorithm_id} and a pointer representing this module is stored
in @var{module}.
@end deftypefun
@deftypefun void gcry_md_unregister (gcry_module_t @var{module})
Unregister the digest identified by @var{module}, which must have been
registered with gcry_md_register.
@end deftypefun
@deftypefun gcry_error_t gcry_md_list (int *@var{list}, int *@var{list_length})
Get a list consisting of the IDs of the loaded message digest modules.
If @var{list} is zero, write the number of loaded message digest
modules to @var{list_length} and return. If @var{list} is non-zero,
the first *@var{list_length} algorithm IDs are stored in @var{list},
which must be of according size. In case there are less message
digests modules than *@var{list_length}, *@var{list_length} is updated
to the correct number.
@end deftypefun
@node Working with hash algorithms
@section Working with hash algorithms
To use most of these function it is necessary to create a context;
this is done using:
@deftypefun gcry_error_t gcry_md_open (gcry_md_hd_t *@var{hd}, int @var{algo}, unsigned int @var{flags})
Create a message digest object for algorithm @var{algo}. @var{flags}
may be given as an bitwise OR of constants described below. @var{algo}
may be given as @code{0} if the algorithms to use are later set using
@code{gcry_md_enable}. @var{hd} is guaranteed to either receive a valid
handle or NULL.
For a list of supported algorithms, see @xref{Available hash
algorithms}.
The flags allowed for @var{mode} are:
@c begin table of hash flags
@table @code
@item GCRY_MD_FLAG_SECURE
Allocate all buffers and the resulting digest in "secure memory". Use
this is the hashed data is highly confidential.
@item GCRY_MD_FLAG_HMAC
Turn the algorithm into a HMAC message authentication algorithm. This
does only work if just one algorithm is enabled for the handle and
SHA-384 and SHA512 is not used. Note that the function
@code{gcry_md_setkey} must be used to set the MAC key. If you want CBC
message authentication codes based on a cipher, see @xref{Working with
cipher handles}.
@end table
@c begin table of hash flags
You may use the function @code{gcry_md_is_enabled} to later check
whether an algorithm has been enabled.
@end deftypefun
@c end function gcry_md_open
If you want to calculate several hash algorithms at the same time, you
have to use the following function right after the @code{gcry_md_open}:
@deftypefun gcry_error_t gcry_md_enable (gcry_md_hd_t @var{h}, int @var{algo})
Add the message digest algorithm @var{algo} to the digest object
described by handle @var{h}. Duplicated enabling of algorithms is
detected and ignored.
@end deftypefun
If the flag @code{GCRY_MD_FLAG_HMAC} was used, the key for the MAC must
be set using the function:
@deftypefun gcry_error_t gcry_md_setkey (gcry_md_hd_t @var{h}, const void *@var{key}, size_t @var{keylen})
For use with the HMAC feature, set the MAC key to the value of @var{key}
of length @var{keylen}.
@end deftypefun
After you are done with the hash calculation, you should release the
resources by using:
@deftypefun void gcry_md_close (gcry_md_hd_t @var{h})
Release all resources of hash context @var{h}. @var{h} should not be
used after a call to this function. A @code{NULL} passed as @var{h} is
ignored.
@end deftypefun
Often you have to do several hash operations using the same algorithm.
To avoid the overhead of creating and releasing context, a reset function
is provided:
@deftypefun void gcry_md_reset (gcry_md_hd_t @var{h})
Reset the current context to its initial state. This is effectively
identical to a close followed by an open and enabling all currently
active algorithms.
@end deftypefun
Often it is necessary to start hashing some data and than continue to
hash different data. To avoid hashing the same data several times (which
might not even be possible if the data is received from a pipe), a
snapshot of the current hash context can be taken and turned into a new
context:
@deftypefun gcry_error_t gcry_md_copy (gcry_md_hd_t *@var{handle_dst}, gcry_md_hd_t @var{handle_src})
Create a new digest object as an exact copy of the object described by
handle @var{handle_src} and store it in @var{handle_dst}. The context
is not reset and you can continue to hash data using this context and
independently using the original context.
@end deftypefun
Now that we have prepared everything to calculate hashes, its time to
see how it is actually done. There are 2 ways for this, one to
update the hash with a block of memory and one macro to update the hash
by just one character. Both may be used intermixed.
@deftypefun void gcry_md_write (gcry_md_hd_t @var{h}, const void *@var{buffer}, size_t @var{length})
Pass @var{length} bytes of the data in @var{buffer} to the digest object
with handle @var{h} to update the digest values. This
function should be used for large blocks of data.
@end deftypefun
@deftypefun void gcry_md_putc (gcry_md_hd_t @var{h}, int @var{c})
Pass the byte in @var{c} to the digest object with handle @var{h} to
update the digest value. This is an efficient function, implemented as
a macro to buffer the data before an actual update.
@end deftypefun
The semantics of the hash functions don't allow to read out intermediate
message digests because the calculation must be finalized fist. This
finalization may for example include the number of bytes hashed in the
message digest.
@deftypefun void gcry_md_final (gcry_md_hd_t @var{h})
Finalize the message digest calculation. This is not really needed
because @code{gcry_md_read} does this implicitly. After this has been
done no further updates (by means of @code{gcry_md_write} or
@code{gcry_md_putc} are allowed. Only the first call to this function
has an effect. It is implemented as a macro.
@end deftypefun
The way to read out the calculated message digest is by using the
function:
@deftypefun unsigned char *gcry_md_read (gcry_md_hd_t @var{h}, int @var{algo})
@code{gcry_md_read} returns the message digest after finalizing the
calculation. This function may be used as often as required but it will
always return the same value for one handle. The returned message digest
is allocated within the message context and therefore valid until the
handle is released or reseted (using @code{gcry_md_close} or
@code{gcry_md_reset}. @var{algo} may be given as 0 to return the only
enabled message digest or it may specify one of the enabled algorithms.
The function does return @code{NULL} if the requested algorithm has not
been enabled.
@end deftypefun
Because it is often necessary to get the message digest of one block of
memory, a fast convenience function is available for this task:
@deftypefun void gcry_md_hash_buffer (int @var{algo}, void *@var{digest}, const cvoid *@var{buffer}, size_t @var{length});
@code{gcry_md_hash_buffer} is a shortcut function to calculate a message
digest of a buffer. This function does not require a context and
immediately returns the message digest of the @var{length} bytes at
@var{buffer}. @var{digest} must be allocated by the caller, large
enough to hold the message digest yielded by the the specified algorithm
@var{algo}. This required size may be obtained by using the function
@code{gcry_md_get_algo_dlen}.
Note, that this function will abort the process if an unavailable
algorithm is used.
@end deftypefun
@c ***********************************
@c ***** MD info functions ***********
@c ***********************************
Hash algorithms are identified by internal algorithm numbers (see
@code{gcry_md_open} for a list. However, in most applications they are
used by names, so 2 functions are available to map between string
representations and hash algorithm identifiers.
@deftypefun const char *gcry_md_algo_name (int @var{algo})
Map the digest algorithm id @var{algo} to a string representation of the
algorithm name. For unknown algorithms this functions returns an
empty string. This function should not be used to test for the
availability of an algorithm.
@end deftypefun
@deftypefun int gcry_md_map_name (const char *@var{name})
Map the algorithm with @var{name} to a digest algorithm identifier.
Returns 0 if the algorithm name is not known. Names representing
@acronym{ASN.1} object identifiers are recognized if the @acronym{IETF}
dotted format is used and the OID is prefixed with either "@code{oid.}"
or "@code{OID.}". For a list of supported OIDs, see the source code at
@file{cipher/md.c}. This function should not be used to test for the
availability of an algorithm.
@end deftypefun
@deftypefun gcry_error_t gcry_md_get_asnoid (int @var{algo}, void *@var{buffer}, size_t *@var{length})
Return an DER encoded ASN.1 OID for the algorithm @var{algo} in the
user allocated @var{buffer}. @var{length} must point to variable with
the available size of @var{buffer} and receives after return the
actual size of the returned OID. The returned error code may be
@code{GPG_ERR_TOO_SHORT} if the provided buffer is to short to receive
the OID; it is possible to call the function with @code{NULL} for
@var{buffer} to have it only return the required size. The function
returns 0 on success.
@end deftypefun
To test whether an algorithm is actually available for use, the
following macro should be used:
@deftypefun gcry_error_t gcry_md_test_algo (int @var{algo})
The macro returns 0 if the algorithm @var{algo} is available for use.
@end deftypefun
If the length of a message digest is not known, it can be retrieved
using the following function:
@deftypefun unsigned int gcry_md_get_algo_dlen (int @var{algo})
Retrieve the length in bytes of the digest yielded by algorithm
@var{algo}. This is often used prior to @code{gcry_md_read} to allocate
sufficient memory for the digest.
@end deftypefun
In some situations it might be hard to remember the algorithm used for
the ongoing hashing. The following function might be used to get that
information:
@deftypefun int gcry_md_get_algo (gcry_md_hd_t @var{h})
Retrieve the algorithm used with the handle @var{h}. Note, that this
does not work reliable if more than one algorithm is enabled in @var{h}.
@end deftypefun
The following macro might also be useful:
@deftypefun int gcry_md_is_secure (gcry_md_hd_t @var{h})
This function returns true when the digest object @var{h} is allocated
in "secure memory"; i.e. @var{h} was created with the
@code{GCRY_MD_FLAG_SECURE}.
@end deftypefun
@deftypefun int gcry_md_is_enabled (gcry_md_hd_t @var{h}, int @var{algo})
This function returns true when the algorithm @var{algo} has been
enabled for the digest object @var{h}.
@end deftypefun
Tracking bugs related to hashing is often a cumbersome task which
requires to add a lot of printf statements into the code. @acronym{Libgcrypt}
provides an easy way to avoid this. The actual data hashed can be
written to files on request. The following 2 macros should be used to
implement such a debugging facility:
@deftypefun void gcry_md_start_debug (gcry_md_hd_t @var{h}, const char *@var{suffix})
Enable debugging for the digest object with handle @var{h}. This
creates create files named @file{dbgmd-<n>.<string>} while doing the
actual hashing. @var{suffix} is the string part in the filename. The
number is a counter incremented for each new hashing. The data in the
file is the raw data as passed to @code{gcry_md_write} or
@code{gcry_md_putc}.
@end deftypefun
@deftypefun void gcry_md_stop_debug (gcry_md_hd_t @var{h}, int @var{reserved})
Stop debugging on handle @var{h}. @var{reserved} should be specified as
0. This function is usually not required because @code{gcry_md_close}
does implicitly stop debugging.
@end deftypefun
@c **********************************************************
@c ******************* Public Key *************************
@c **********************************************************
@node Public Key cryptography (I)
@chapter Public Key cryptography (I)
Public key cryptography, also known as asymmetric cryptography, is an
easy way for key management and to provide digital signatures.
@acronym{Libgcrypt} provides two completely different interfaces to
public key cryptography, this chapter explains the one based on
S-expressions.
@menu
* Available algorithms:: Algorithms supported by the library.
* Used S-expressions:: Introduction into the used S-expression.
* Public key modules:: How to work with public key modules.
* Cryptographic Functions:: Functions for performing the cryptographic actions.
* General public-key related Functions:: General functions, not implementing any cryptography.
@end menu
@node Available algorithms
@section Available algorithms
@acronym{Libgcrypt} supports the RSA (Rivest-Shamir-Adleman) algorithms as well
as DSA (Digital Signature Algorithm) and ElGamal. The versatile
interface allows to add more algorithms in the future.
@node Used S-expressions
@section Used S-expressions
@acronym{Libgcrypt}'s API for asymmetric cryptography is based on data
structures called S-expressions (see XXXX) and does not work with
contexts as most of the other building blocks of @acronym{Libgcrypt}
do.
The following information are stored in S-expressions:
@table @asis
@item keys
@item plain text data
@item encrypted data
@item signatures
@end table
@noindent
To describe how @acronym{Libgcrypt} expect keys, we use some examples. Note that
words in
@ifnottex
uppercase
@end ifnottex
@iftex
italics
@end iftex
indicate parameters whereas lowercase words are literals.
@example
(private-key
(dsa
(p @var{p-mpi})
(q @var{q-mpi})
(g @var{g-mpi})
(y @var{y-mpi})
(x @var{x-mpi})))
@end example
@noindent
This specifies a DSA private key with the following parameters:
@table @var
@item p-mpi
DSA prime @math{p}.
@item q-mpi
DSA group order @math{q} (which is a prime divisor of @math{p-1}).
@item g-mpi
DSA group generator @math{g}.
@item y-mpi
DSA public key value @math{y = g^x \bmod p}.
@item x-mpi
DSA secret exponent x.
@end table
All the MPI values are expected to be in @code{GCRYMPI_FMT_USG} format.
The public key is similar with "private-key" replaced by "public-key"
and no @var{x-mpi}.
An easy way to create such an S-expressions is by using
@code{gcry_sexp_build} which allows to pass a string with printf-like
escapes to insert MPI values.
@noindent
Here is an example for an RSA key:
@example
(private-key
(rsa
(n @var{n-mpi})
(e @var{e-mpi})
(d @var{d-mpi})
(p @var{p-mpi})
(q @var{q-mpi})
(u @var{u-mpi})
@end example
@noindent
with
@table @var
@item n-mpi
RSA public modulus @math{n}.
@item e-mpi
RSA public exponent @math{e}.
@item d-mpi
RSA secret exponent @math{d = e^{-1} \bmod (p-1)(q-1)}.
@item p-mpi
RSA secret prime @math{p}.
@item q-mpi
RSA secret prime @math{q} with @math{q > p}.
@item u-mpi
multiplicative inverse @math{u = p^{-1} \bmod q}.
@end table
@node Public key modules
@section Public key modules
@acronym{Libgcrypt} makes it possible to load additional `public key
modules'; these public key algorithms can be used just like the
algorithms that are built into the library directly. For an
introduction into extension modules, see @xref{Modules}.
@deftp {Data type} gcry_pk_spec_t
This is the `module specification structure' needed for registering
public key modules, which has to be filled in by the user before it
can be used to register a module. It contains the following members:
@table @code
@item const char *name
The primary name of this algorithm.
@item char **aliases
A list of strings that are `aliases' for the algorithm. The list
must be terminated with a NULL element.
@item const char *elements_pkey
String containing the one-letter names of the MPI values contained in
a public key.
@item const char *element_skey
String containing the one-letter names of the MPI values contained in
a secret key.
@item const char *elements_enc
String containing the one-letter names of the MPI values that are the
result of an encryption operation using this algorithm.
@item const char *elements_sig
String containing the one-letter names of the MPI values that are the
result of a sign operation using this algorithm.
@item const char *elements_grip
String containing the one-letter names of the MPI values that are to
be included in the `key grip'.
@item int use
The bitwise-OR of the following flags, depending on the abilities of
the algorithm:
@table @code
@item GCRY_PK_USAGE_SIGN
The algorithm supports signing and verifying of data.
@item GCRY_PK_USAGE_ENCR
The algorithm supports the encryption and decryption of data.
@end table
@item gcry_pk_generate_t generate
The function responsible for generating a new key pair. See below for
a description of this type.
@item gcry_pk_check_secret_key_t check_secret_key
The function responsible for checking the sanity of a provided secret
key. See below for a description of this type.
@item gcry_pk_encrypt_t encrypt
The function responsible for encrypting data. See below for a
description of this type.
@item gcry_pk_decrypt_t decrypt
The function responsible for decrypting data. See below for a
description of this type.
@item gcry_pk_sign_t sign
The function responsible for signing data. See below for a description
of this type.
@item gcry_pk_verify_t verify
The function responsible for verifying that the provided signature
matches the provided data. See below for a description of this type.
@item gcry_pk_get_nbits_t get_nbits
The function responsible for returning the number of bits of a provided
key. See below for a description of this type.
@end table
@end deftp
@deftp {Data type} gcry_pk_generate_t
Type for the `generate' function, defined as: 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)
@end deftp
@deftp {Data type} gcry_pk_check_secret_key_t
Type for the `check_secret_key' function, defined as: gcry_err_code_t
(*gcry_pk_check_secret_key_t) (int algo, gcry_mpi_t *skey)
@end deftp
@deftp {Data type} gcry_pk_encrypt_t
Type for the `encrypt' function, defined as: gcry_err_code_t
(*gcry_pk_encrypt_t) (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
gcry_mpi_t *pkey, int flags)
@end deftp
@deftp {Data type} gcry_pk_decrypt_t
Type for the `decrypt' function, defined as: gcry_err_code_t
(*gcry_pk_decrypt_t) (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
gcry_mpi_t *skey, int flags)
@end deftp
@deftp {Data type} gcry_pk_sign_t
Type for the `sign' function, defined as: gcry_err_code_t
(*gcry_pk_sign_t) (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
gcry_mpi_t *skey)
@end deftp
@deftp {Data type} gcry_pk_verify_t
Type for the `verify' function, defined as: 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)
@end deftp
@deftp {Data type} gcry_pk_get_nbits_t
Type for the `get_nbits' function, defined as: unsigned
(*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey)
@end deftp
@deftypefun gcry_error_t gcry_pk_register (gcry_pk_spec_t *@var{pubkey}, unsigned int *algorithm_id, gcry_module_t *@var{module})
Register a new public key module whose specification can be found in
@var{pubkey}. On success, a new algorithm ID is stored in
@var{algorithm_id} and a pointer representing this module is stored
in @var{module}.
@end deftypefun
@deftypefun void gcry_pk_unregister (gcry_module_t @var{module})
Unregister the public key module identified by @var{module}, which
must have been registered with gcry_pk_register.
@end deftypefun
@deftypefun gcry_error_t gcry_pk_list (int *@var{list}, int *@var{list_length})
Get a list consisting of the IDs of the loaded pubkey modules. If
@var{list} is zero, write the number of loaded pubkey modules to
@var{list_length} and return. If @var{list} is non-zero, the first
*@var{list_length} algorithm IDs are stored in @var{list}, which must
be of according size. In case there are less pubkey modules than
*@var{list_length}, *@var{list_length} is updated to the correct
number.
@end deftypefun
@node Cryptographic Functions
@section Cryptographic Functions
@noindent
Note, that we will in future allow to use keys without p,q and u
specified and may also support other parameters for performance
reasons.
@noindent
Some functions operating on S-expressions support `flags', that
influence the operation. These flags have to be listed in a
sub-S-expression named `flags'; the following flags are known:
@table @var
@item pkcs1
Use PKCS#1 block type 2 padding.
@item no-blinding
Do not use a technique called `blinding', which is used by default in
order to prevent leaking of secret information. Blinding is only
implemented by RSA, but it might be implemented by other algorithms in
the future as well, when necessary.
@end table
@noindent
Now that we know the key basics, we can carry on and explain how to
encrypt and decrypt data. In almost all cases the data is a random
session key which is in turn used for the actual encryption of the real
data. There are 2 functions to do this:
@deftypefun gcry_error_t gcry_pk_encrypt (@w{gcry_sexp_t *@var{r_ciph},} @w{gcry_sexp_t @var{data},} @w{gcry_sexp_t @var{pkey}})
Obviously a public key must be provided for encryption. It is
expected as an appropriate S-expression (see above) in @var{pkey}.
The data to be encrypted can either be in the simple old format, which
is a very simple S-expression consisting only of one MPI, or it may be
a more complex S-expression which also allows to specify flags for
operation, like e.g. padding rules.
@noindent
If you don't want to let @acronym{Libgcrypt} handle the padding, you must pass an
appropriate MPI using this expression for @var{data}:
@example
(data
(flags raw)
(value @var{mpi}))
@end example
@noindent
This has the same semantics as the old style MPI only way. @var{MPI} is
the actual data, already padded appropriate for your protocol. Most
systems however use PKCS#1 padding and so you can use this S-expression
for @var{data}:
@example
(data
(flags pkcs1)
(value @var{block}))
@end example
@noindent
Here, the "flags" list has the "pkcs1" flag which let the function know
that it should provide PKCS#1 block type 2 padding. The actual data to
be encrypted is passed as a string of octets in @var{block}. The
function checks that this data actually can be used with the given key,
does the padding and encrypts it.
If the function could successfully perform the encryption, the return
value will be 0 and a a new S-expression with the encrypted result is
allocated and assign to the variable at the address of @var{r_ciph}.
The caller is responsible to release this value using
@code{gcry_sexp_release}. In case of an error, an error code is
returned and @var{r_ciph} will be set to @code{NULL}.
@noindent
The returned S-expression has this format when used with RSA:
@example
(enc-val
(rsa
(a @var{a-mpi})))
@end example
@noindent
Where @var{a-mpi} is an MPI with the result of the RSA operation. When
using the ElGamal algorithm, the return value will have this format:
@example
(enc-val
(elg
(a @var{a-mpi})
(b @var{b-mpi})))
@end example
@noindent
Where @var{a-mpi} and @var{b-mpi} are MPIs with the result of the
ElGamal encryption operation.
@end deftypefun
@c end gcry_pk_encrypt
@deftypefun gcry_error_t gcry_pk_decrypt (@w{gcry_sexp_t *@var{r_plain},} @w{gcry_sexp_t @var{data},} @w{gcry_sexp_t @var{skey}})
Obviously a private key must be provided for decryption. It is expected
as an appropriate S-expression (see above) in @var{skey}. The data to
be decrypted must match the format of the result as returned by
@code{gcry_pk_encrypt}, but should be enlarged with a @code{flags}
element:
@example
(enc-val
(flags)
(elg
(a @var{a-mpi})
(b @var{b-mpi})))
@end example
@noindent
Note, that this function currently does not know of any padding
methods and the caller must do any un-padding on his own.
@noindent
The function returns 0 on success or an error code. The variable at the
address of @var{r_plain} will be set to NULL on error or receive the
decrypted value on success. The format of @var{r_plain} is a
simple S-expression part (i.e. not a valid one) with just one MPI if
there was no @code{flags} element in @var{data}; if at least an empty
@code{flags} is passed in @var{data}, the format is:
@example
(value @var{plaintext})
@end example
@end deftypefun
@c end gcry_pk_decrypt
Another operation commonly performed using public key cryptography is
signing data. In some sense this is even more important than
encryption because digital signatures are an important instrument for
key management. @acronym{Libgcrypt} supports digital signatures using
2 functions, similar to the encryption functions:
@deftypefun gcry_error_t gcry_pk_sign (@w{gcry_sexp_t *@var{r_sig},} @w{gcry_sexp_t @var{data},} @w{gcry_sexp_t @var{skey}})
This function creates a digital signature for @var{data} using the
private key @var{skey} and place it into the variable at the address of
@var{r_sig}. @var{data} may either be the simple old style S-expression
with just one MPI or a modern and more versatile S-expression which
allows to let @acronym{Libgcrypt} handle padding:
@example
(data
(flags pkcs1)
(hash @var{hash-algo} @var{block}))
@end example
@noindent
This example requests to sign the data in @var{block} after applying
PKCS#1 block type 1 style padding. @var{hash-algo} is a string with the
hash algorithm to be encoded into the signature, this may be any hash
algorithm name as supported by @acronym{Libgcrypt}. Most likely, this will be
"sha1", "rmd160" or "md5". It is obvious that the length of @var{block}
must match the size of that message digests; the function checks that
this and other constraints are valid.
@noindent
If PKCS#1 padding is not required (because the caller does already
provide a padded value), either the old format or better the following
format should be used:
@example
(data
(flags raw)
(value @var{mpi}))
@end example
@noindent
Here, the data to be signed is directly given as an @var{MPI}.
@noindent
The signature is returned as a newly allocated S-expression in
@var{r_sig} using this format for RSA:
@example
(sig-val
(rsa
(s @var{s-mpi})))
@end example
Where @var{s-mpi} is the result of the RSA sign operation. For DSA the
S-expression returned is:
@example
(sig-val
(dsa
(r @var{r-mpi})
(s @var{s-mpi})))
@end example
Where @var{r-mpi} and @var{s-mpi} are the result of the DSA sign
operation. For ElGamal signing (which is slow, yields large numbers
and probably is not as secure as the other algorithms), the same format is
used with "elg" replacing "dsa".
@end deftypefun
@c end gcry_pk_sign
@noindent
The operation most commonly used is definitely the verification of a
signature. @acronym{Libgcrypt} provides this function:
@deftypefun gcry_error_t gcry_pk_verify (@w{gcry_sexp_t @var{sig}}, @w{gcry_sexp_t @var{data}}, @w{gcry_sexp_t @var{pkey}})
This is used to check whether the signature @var{sig} matches the
@var{data}. The public key @var{pkey} must be provided to perform this
verification. This function is similar in its parameters to
@code{gcry_pk_sign} with the exceptions that the public key is used
instead of the private key and that no signature is created but a
signature, in a format as created by @code{gcry_pk_sign}, is passed to
the function in @var{sig}.
@noindent
The result is 0 for success (i.e. the data matches the signature), or an
error code where the most relevant code is @code{GCRYERR_BAD_SIGNATURE}
to indicate that the signature does not match the provided data.
@end deftypefun
@c end gcry_pk_verify
@node General public-key related Functions
@section General public-key related Functions
@noindent
A couple of utility functions are available to retrieve the length of
the key, map algorithm identifiers and perform sanity checks:
@deftypefun {const char *} gcry_pk_algo_name (int @var{algo})
Map the public key algorithm id @var{algo} to a string representation of
the algorithm name. For unknown algorithms this functions returns an
empty string.
@end deftypefun
@deftypefun int gcry_pk_map_name (const char *@var{name})
Map the algorithm @var{name} to a public key algorithm Id. Returns 0 if
the algorithm name is not known.
@end deftypefun
@deftypefun int gcry_pk_test_algo (int @var{algo})
Return 0 if the public key algorithm @var{algo} is available for use.
Note, that this is implemented as a macro.
@end deftypefun
@deftypefun {unsigned int} gcry_pk_get_nbits (gcry_sexp_t @var{key})
Return what is commonly referred as the key length for the given
public or private in @var{key}.
@end deftypefun
@deftypefun {unsigned char *} gcry_pk_get_keygrip (@w{gcry_sexp_t @var{key}}, @w{unsigned char *@var{array}})
Return the so called "keygrip" which is the SHA-1 hash of the public key
parameters expressed in a way depended on the algorithm. @var{array}
must either provide space for 20 bytes or @code{NULL;}. In the latter
case a newly allocated array of that size is returned. On success a
pointer to the newly allocated space or to @var{array} is returned.
@code{NULL} is returned to indicate an error which is most likely an unknown
algorithm or one where a "keygrip" has not yet been defined.
The function accepts public or secret keys in @var{key}.
@end deftypefun
@deftypefun gcry_error_t gcry_pk_testkey (gcry_sexp_t @var{key})
Return zero if the private key @var{key} is `sane', an error code otherwise.
Note, that it is not possible to chek the `saneness' of a public key.
@end deftypefun
@deftypefun gcry_error_t gcry_pk_algo_info (@w{int @var{algo}}, @w{int @var{what}}, @w{void *@var{buffer}}, @w{size_t *@var{nbytes}})
Depending on the value of @var{what} return various information about
the public key algorithm with the id @var{algo}. Note, that the
function returns @code{-1} on error and the actual error code must be
retrieved using the function @code{gcry_errno}. The currently defined
values for @var{what} are:
@table @code
@item GCRYCTL_TEST_ALGO:
Return 0 when the specified algorithm is available for use.
@var{buffer} must be @code{NULL}, @var{nbytes} may be passed as
@code{NULL} or point to a variable with the required usage of the
algorithm. This may be 0 for "don't care" or the bit-wise OR of these
flags:
@table @code
@item GCRY_PK_USAGE_SIGN
Algorithm is usable for signing.
@item GCRY_PK_USAGE_ENCR
Algorithm is usable for encryption.
@end table
@item GCRYCTL_GET_ALGO_USAGE:
Return the usage flags for the given algorithm. An invalid algorithm
return 0. Disabled algorithms are ignored here because we
want to know whether the algorithm is at all capable of a certain usage.
@item GCRYCTL_GET_ALGO_NPKEY
Return the number of elements the public key for algorithm @var{algo}
consist of. Return 0 for an unknown algorithm.
@item GCRYCTL_GET_ALGO_NSKEY
Return the number of elements the private key for algorithm @var{algo}
consist of. Note that this value is always larger than that of the
public key. Return 0 for an unknown algorithm.
@item GCRYCTL_GET_ALGO_NSIGN
Return the number of elements a signature created with the algorithm
@var{algo} consists of. Return 0 for an unknown algorithm or for an
algorithm not capable of creating signatures.
@item GCRYCTL_GET_ALGO_NENC
Return the number of elements a encrypted message created with the algorithm
@var{algo} consists of. Return 0 for an unknown algorithm or for an
algorithm not capable of encryption.
@end table
@noindent
Please note that parameters not required should be passed as @code{NULL}.
@end deftypefun
@c end gcry_pk_algo_info
@deftypefun gcry_error_t gcry_pk_ctl (@w{int @var{cmd}}, @w{void *@var{buffer}}, @w{size_t @var{buflen}})
This is a general purpose function to perform certain control
operations. @var{cmd} controls what is to be done. The return value is
0 for success or an error code. Currently supported values for
@var{cmd} are:
@table @code
@item GCRYCTL_DISABLE_ALGO
Disable the algorithm given as an algorithm id in @var{buffer}.
@var{buffer} must point to an @code{int} variable with the algorithm id
and @var{buflen} must have the value @code{sizeof (int)}.
@end table
@end deftypefun
@c end gcry_pk_ctl
@noindent
@acronym{Libgcrypt} also provides a function for generating public key
pairs:
@deftypefun gcry_error_t gcry_pk_genkey (@w{gcry_sexp_t *@var{r_key}}, @w{gcry_sexp_t @var{parms}})
This function create a new public key pair using information given in
the S-expression @var{parms} and stores the private and the public key
in one new S-expression at the address given by @var{r_key}. In case of
an error, @var{r_key} is set to @code{NULL}. The return code is 0 for
success or an error code otherwise.
@noindent
Here is an example for @var{parms} for creating a 1024 bit RSA key:
@example
(genkey
(rsa
(nbits 4:1024)))
@end example
@noindent
To create an ElGamal key, substitute "elg" for "rsa" and to create a DSA
key use "dsa". Valid ranges for the key length depend on the
algorithms; all commonly used key lengths are supported. Currently
supported parameters are:
@table @code
@item nbits
This is always required to specify the length of the key. The argument
is a string with a number in C-notation.
@item rsa-use-e
This is only used with RSA to give a hint for the public exponent. The
value will be used as a base to test for a usable exponent. Some values
are special:
@table @samp
@item 0
Use a secure and fast value. This is currently the number 41.
@item 1
Use a secure value as required by some specification. This is currently
the number 65537.
@item 2
Reserved
@end table
@noindent
If this parameter is not used, @acronym{Libgcrypt} uses for historic reasons
65537.
@end table
@c end table of parameters
@noindent
The key pair is returned in a format depending on the algorithm. Both
private and public keys are returned in one container and may be
accompanied by some miscellaneous information.
@noindent
As an example, here is what the ElGamal key generation returns:
@example
(key-data
(public-key
(elg
(p @var{p-mpi})
(g @var{g-mpi})
(y @var{y-mpi})))
(private-key
(elg
(p @var{p-mpi})
(g @var{g-mpi})
(y @var{y-mpi})
(x @var{x-mpi})))
(misc-key-info
(pm1-factors @var{n1 n2 ... nn})))
@end example
@noindent
As you can see, some of the information is duplicated, but this provides
an easy way to extract either the public or the private key. Note that
the order of the elements is not defined, e.g. the private key may be
stored before the public key. @var{n1 n2 ... nn} is a list of prime
numbers used to composite @var{p-mpi}; this is in general not a very
useful information.
@end deftypefun
@c end gcry_pk_genkey
@node Public Key cryptography (II)
@chapter Public Key cryptography (II)
This chapter documents the alternative interface to asymmetric
cryptography (ac) that is not based on S-expressions, but on native C
data structures. As opposed to the pk interface described in the
former chapter, this one follows an open/use/close paradigm like other
building blocks of the library.
@menu
* Available asymmetric algorithms:: List of algorithms supported by the library.
* Working with sets of data:: How to work with sets of data.
* Working with IO objects:: How to work with IO objects.
* Working with handles:: How to use handles.
* Working with keys:: How to work with keys.
* Using cryptographic functions:: How to perform cryptographic operations.
* Handle-independent functions:: General functions independent of handles.
@end menu
@node Available asymmetric algorithms
@section Available asymmetric algorithms
@acronym{Libgcrypt} supports the RSA (Rivest-Shamir-Adleman)
algorithms as well as DSA (Digital Signature Algorithm) and ElGamal.
The versatile interface allows to add more algorithms in the future.
@deftp {Data type} gcry_ac_id_t
The following constants are defined for this type:
@table @code
@item GCRY_AC_RSA
Riven-Shamir-Adleman
@item GCRY_AC_DSA
Digital Signature Algorithm
@item GCRY_AC_ELG
ElGamal
@item GCRY_AC_ELG_E
ElGamal, encryption only.
@end table
@end deftp
@node Working with sets of data
@section Working with sets of data
In the context of this interface the term `data set' refers to a list
of `named MPI values' that is used by functions performing
cryptographic operations; a named MPI value is a an MPI value,
associated with a label.
Such data sets are used for representing keys, since keys simply
consist of a variable amount of numbers. Furthermore some functions
return data sets to the caller that are to be provided to other
functions.
This section documents the data types, symbols and functions that are
relevant for working with data sets.
@deftp {Data type} gcry_ac_data_t
A single data set.
@end deftp
The following flags are supported:
@table @code
@item GCRY_AC_FLAG_DEALLOC
Used for storing data in a data set. If given, the data will be
released by the library. Note that whenever one of the ac functions
is about to release objects because of this flag, the objects are
expected to be stored in memory allocated through the Libgcrypt memory
management. In other words: gcry_free() is used instead of free().
@item GCRY_AC_FLAG_COPY
Used for storing/retrieving data in/from a data set. If given, the
library will create copies of the provided/contained data, which will
then be given to the user/associated with the data set.
@end table
@deftypefun gcry_error_t gcry_ac_data_new (gcry_ac_data_t *@var{data})
Creates a new, empty data set and stores it in @var{data}.
@end deftypefun
@deftypefun void gcry_ac_data_destroy (gcry_ac_data_t @var{data})
Destroys the data set @var{data}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_set (gcry_ac_data_t @var{data}, unsigned int @var{flags}, char *@var{name}, gcry_mpi_t @var{mpi})
Add the value @var{mpi} to @var{data} with the label @var{name}. If
@var{flags} contains GCRY_AC_FLAG_DATA_COPY, the data set will contain
copies of @var{name} and @var{mpi}. If @var{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.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *@var{data_cp}, gcry_ac_data_t @var{data})
Create a copy of the data set @var{data} and store it in
@var{data_cp}. FIXME: exact semantics undefined.
@end deftypefun
@deftypefun unsigned int gcry_ac_data_length (gcry_ac_data_t @var{data})
Returns the number of named MPI values inside of the data set
@var{data}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t @var{data}, unsigned int @var{flags}, char *@var{name}, gcry_mpi_t *@var{mpi})
Store the value labelled with @var{name} found in @var{data} in
@var{mpi}. If @var{flags} contains GCRY_AC_FLAG_COPY, store a copy of
the @var{mpi} value contained in the data set. @var{mpi} may be NULL
(this might be useful for checking the existence of an MPI with
extracting it).
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t @var{data}, unsigned int flags, unsigned int @var{index}, const char **@var{name}, gcry_mpi_t *@var{mpi})
Stores in @var{name} and @var{mpi} the named @var{mpi} value contained
in the data set @var{data} with the index @var{idx}. If @var{flags}
contains GCRY_AC_FLAG_COPY, store copies of the values contained in
the data set. @var{name} or @var{mpi} may be NULL.
@end deftypefun
@deftypefun void gcry_ac_data_clear (gcry_ac_data_t @var{data})
Destroys any values contained in the data set @var{data}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t @var{data}, gcry_sexp_t *@var{sexp}, const char **@var{identifiers})
This function converts the data set @var{data} into a newly created
S-Expression, which is to be stored in @var{sexp}; @var{identifiers}
is a NULL terminated list of C strings, which specifies the structure
of the S-Expression.
Example:
If @var{identifiers} is a list of pointers to the strings ``foo'' and
``bar'' and if @var{data} is a data set containing the values ``val1 =
0x01'' and ``val2 = 0x02'', then the resulting S-Expression will look
like this: (foo (bar ((val1 0x01) (val2 0x02))).
@end deftypefun
@deftypefun gcry_error gcry_ac_data_from_sexp (gcry_ac_data_t *@var{data}, gcry_sexp_t @var{sexp}, const char **@var{identifiers})
This function converts the S-Expression @var{sexp} into a newly
created data set, which is to be stored in @var{data};
@var{identifiers} is a NULL terminated list of C strings, which
specifies the structure of the S-Expression. If the list of
identifiers does not match the structure of the S-Expression, the
function fails.
@end deftypefun
@node Working with IO objects
@section Working with IO objects
Note: IO objects are currently only used in the context of message
encoding/decoding and encryption/signature schemes.
@deftp {Data type} {gcry_ac_io_t}
@code{gcry_ac_io_t} is the type to be used for IO objects.
@end deftp
IO objects provide an uniform IO layer on top of different underlying
IO mechanisms; either they can be used for providing data to the
library (mode is GCRY_AC_IO_READABLE) or they can be used for
retrieving data from the library (mode is GCRY_AC_IO_WRITABLE).
IO object need to be initialized by calling on of the following
functions:
@deftypefun void gcry_ac_io_init (gcry_ac_io_t *@var{ac_io}, gcry_ac_io_mode_t @var{mode}, gcry_ac_io_type_t @var{type}, ...);
Initialize @var{ac_io} according to @var{mode}, @var{type} and the
variable list of arguments. The list of variable arguments to specify
depends on the given @var{type}.
@end deftypefun
@deftypefun void gcry_ac_io_init_va (gcry_ac_io_t *@var{ac_io}, gcry_ac_io_mode_t @var{mode}, gcry_ac_io_type_t @var{type}, va_list @var{ap});
Initialize @var{ac_io} according to @var{mode}, @var{type} and the
variable list of arguments @var{ap}. The list of variable arguments
to specify depends on the given @var{type}.
@end deftypefun
The following types of IO objects exist:
@table @code
@item GCRY_AC_IO_STRING
In case of GCRY_AC_IO_READABLE the IO object will provide data from a
memory string. Arguments to specify at initialization time:
@table @code
@item unsigned char *
Pointer to the beginning of the memory string
@item size_t
Size of the memory string
@end table
In case of GCRY_AC_IO_WRITABLE the object will store retrieved data in
a newly allocated memory string. Arguments to specify at
initialization time:
@table @code
@item unsigned char **
Pointer to address, at which the pointer to the newly created memory
string is to be stored
@item size_t *
Pointer to address, at which the size of the newly created memory
string is to be stored
@end table
@item GCRY_AC_IO_CALLBACK
In case of GCRY_AC_IO_READABLE the object will forward read requests
to a provided callback function. Arguments to specify at
initialization time:
@table @code
@item gcry_ac_data_read_cb_t
Callback function to use
@item void *
Opaque argument to provide to the callback function
@end table
In case of GCRY_AC_IO_WRITABLE the object will forward write requests
to a provided callback function. Arguments to specify at
initialization time:
@table @code
@item gcry_ac_data_write_cb_t
Callback function to use
@item void *
Opaque argument to provide to the callback function
@end table
@end table
@node Working with handles
@section Working with handles
In order to use an algorithm, an according handle must be created.
This is done using the following function:
@deftypefun gcry_error_t gcry_ac_open (gcry_ac_handle_t *@var{handle}, int @var{algorithm}, int @var{flags})
Creates a new handle for the algorithm @var{algorithm} and stores it
in @var{handle}. @var{flags} is not used currently.
@var{algorithm} must be a valid algorithm ID, see @xref{Available
algorithms}, for a list of supported algorithms and the according
constants. Besides using the listed constants directly, the functions
@code{gcry_ac_name_to_id} may be used to convert the textual name of
an algorithm into the according numeric ID.
@end deftypefun
@deftypefun void gcry_ac_close (gcry_ac_handle_t @var{handle})
Destroys the handle @var{handle}.
@end deftypefun
@node Working with keys
@section Working with keys
@deftp {Data type} gcry_ac_key_type_t
Defined constants:
@table @code
@item GCRY_AC_KEY_TYPE_SECRET
Specifies a secret key.
@item GCRY_AC_KEY_TYPE_PUBLIC
Specifies a public key.
@end table
@end deftp
@deftp {Data type} gcry_ac_key_t
This type represents a single `key', either a secret one or a public
one.
@end deftp
@deftp {Data type} gcry_ac_key_pair_t
This type represents a `key pair' containing a secret and a public key.
@end deftp
Key data structures can be created in two different ways; a new key
pair can be generated, resulting in ready-to-use key. Alternatively a
key can be initialized from a given data set.
@deftypefun gcry_error_t gcry_ac_key_init (gcry_ac_key_t *@var{key}, gcry_ac_handle_t @var{handle}, gcry_ac_key_type_t @var{type}, gcry_ac_data_t @var{data})
Creates a new key of type @var{type}, consisting of the MPI values
contained in the data set @var{data} and stores it in @var{key}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t @var{handle}, unsigned int @var{nbits}, void *@var{key_spec}, gcry_ac_key_pair_t *@var{key_pair}, gcry_mpi_t **@var{misc_data})
Generates a new key pair via the handle @var{handle} of @var{NBITS}
bits and stores it in @var{key_pair}.
In case non-standard settings are wanted, a pointer to a structure of
type @code{gcry_ac_key_spec_<algorithm>_t}, matching the selected
algorithm, can be given as @var{key_spec}. @var{misc_data} is not
used yet. Such a structure does only exist for RSA. A descriptions
of the members of the supported structures follows.
@table @code
@item gcry_ac_key_spec_rsa_t
@table @code
@item gcry_mpi_t e
Generate the key pair using a special @code{e}. The value of @code{e}
has the following meanings:
@table @code
@item = 0
Let @acronym{Libgcrypt} decide what exponent should be used.
@item = 1
Request the use of a ``secure'' exponent; this is required by some
specification to be 65537.
@item > 2
Try starting at this value until a working exponent is found. Note,
that the current implementation leaks some information about the
private key because the incrementation used is not randomized. Thus,
this function will be changed in the future to return a random
exponent of the given size.
@end table
@end table
@end table
Example code:
@example
@{
gcry_ac_key_pair_t key_pair;
gcry_ac_key_spec_rsa_t rsa_spec;
rsa_spec.e = gcry_mpi_new (0);
gcry_mpi_set_ui (rsa_spec.e, 1)
err = gcry_ac_open (&handle, GCRY_AC_RSA, 0);
assert (! err);
err = gcry_ac_key_pair_generate (handle, &key_pair, 1024, (void *) &rsa_spec);
assert (! err);
@}
@end example
@end deftypefun
@deftypefun gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t @var{key_pair}, gcry_ac_key_type_t @var{which})
Returns the key of type @var{which} out of the key pair
@var{key_pair}.
@end deftypefun
@deftypefun void gcry_ac_key_destroy (gcry_ac_key_t @var{key})
Destroys the key @var{key}.
@end deftypefun
@deftypefun void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t @var{key_pair})
Destroys the key pair @var{key_pair}.
@end deftypefun
@deftypefun gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t @var{key})
Returns the data set contained in the key @var{key}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_key_test (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key})
Verifies that the private key @var{key} is sane via @var{handle}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, unsigned int *@var{nbits})
Stores the number of bits of the key @var{key} in @var{nbits} via @var{handle}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, unsigned char *@var{key_grip})
Writes the 20 byte long key grip of the key @var{key} to
@var{key_grip} via @var{handle}.
@end deftypefun
@node Using cryptographic functions
@section Using cryptographic functions
The following flags might be relevant:
@table @code
@item GCRY_AC_FLAG_NO_BLINDING
Disable any blinding, which might be supported by the chosen
algorithm; blinding is the default.
@end table
There exist two kinds of cryptographic functions available through the
ac interface: primitives, and high-level functions.
Primitives deal with MPIs (data sets) directly; what they provide is
direct access to the cryptographic operations provided by an algorithm
implementation.
High-level functions deal with octet strings, according to a specified
``scheme''. Schemes make use of ``encoding methods'', which are
responsible for converting the provided octet strings into MPIs, which
are then forwared to the cryptographic primitives. Since schemes are
to be used for a special purpose in order to achieve a particular
security goal, there exist ``encryption schemes'' and ``signature
schemes''. Encoding methods can be used seperately or implicitly
through schemes.
What follows is a description of the cryptographic primitives.
@deftypefun gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t @var{handle}, unsigned int @var{flags}, gcry_ac_key_t @var{key}, gcry_mpi_t @var{data_plain}, gcry_ac_data_t **@var{data_encrypted})
Encrypts the plain text MPI value @var{data_plain} with the key public
@var{key} under the control of the flags @var{flags} and stores the
resulting data set into @var{data_encrypted}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t @var{handle}, unsigned int @var{flags}, gcry_ac_key_t @var{key}, gcry_mpi_t *@var{data_plain}, gcry_ac_data_t @var{data_encrypted})
Decrypts the encrypted data contained in the data set
@var{data_encrypted} with the secret key KEY under the control of the
flags @var{flags} and stores the resulting plain text MPI value in
@var{DATA_PLAIN}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, gcry_mpi_t @var{data}, gcry_ac_data_t *@var{data_signature})
Signs the data contained in @var{data} with the secret key @var{key}
and stores the resulting signature in the data set
@var{data_signature}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, gcry_mpi_t @var{data}, gcry_ac_data_t @var{data_signature})
Verifies that the signature contained in the data set
@var{data_signature} is indeed the result of signing the data
contained in @var{data} with the secret key belonging to the public
key @var{key}.
@end deftypefun
What follows is a description of the high-level functions.
The type ``gcry_ac_em_t'' is used for specifying encoding methods; the
following methods are supported:
@table @code
@item GCRY_AC_EME_PKCS_V1_5
PKCS-V1_5 Encoding Method for Encryption. Options must be provided
through a pointer to a correctly initialized object of type
gcry_ac_eme_pkcs_v1_5_t.
@item GCRY_AC_EMSA_PKCS_V1_5
PKCS-V1_5 Encoding Method for Signatures with Appendix. Options must
be provided through a pointer to a correctly initialized object of
type gcry_ac_emsa_pkcs_v1_5_t.
@end table
Option structure types:
@table @code
@item gcry_ac_eme_pkcs_v1_5_t
@table @code
@item gcry_ac_key_t key
@item gcry_ac_handle_t handle
@end table
@item gcry_ac_emsa_pkcs_v1_5_t
@table @code
@item gcry_md_algo_t md
@item size_t em_n
@end table
@end table
Encoding methods can be used directly through the following functions:
@deftypefun gcry_error_t gcry_ac_data_encode (gcry_ac_em_t @var{method}, unsigned int @var{flags}, void *@var{options}, unsigned char *@var{m}, size_t @var{m_n}, unsigned char **@var{em}, size_t *@var{em_n})
Encodes the message contained in @var{m} of size @var{m_n} according
to @var{method}, @var{flags} and @var{options}. The newly created
encoded message is stored in @var{em} and @var{em_n}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_decode (gcry_ac_em_t @var{method}, unsigned int @var{flags}, void *@var{options}, unsigned char *@var{em}, size_t @var{em_n}, unsigned char **@var{m}, size_t *@var{m_n})
Decodes the message contained in @var{em} of size @var{em_n} according
to @var{method}, @var{flags} and @var{options}. The newly created
decoded message is stored in @var{m} and @var{m_n}.
@end deftypefun
The type ``gcry_ac_scheme_t'' is used for specifying schemes; the
following schemes are supported:
@table @code
@item GCRY_AC_ES_PKCS_V1_5
PKCS-V1_5 Encryption Scheme. No options can be provided.
@item GCRY_AC_SSA_PKCS_V1_5
PKCS-V1_5 Signature Scheme (with Appendix). Options can be provided
through a pointer to a correctly initialized object of type
gcry_ac_ssa_pkcs_v1_5_t.
@end table
Option structure types:
@table @code
@item gcry_ac_ssa_pkcs_v1_5_t
@table @code
@item gcry_md_algo_t md
@end table
@end table
The functions implementing schemes:
@deftypefun gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_message}, gcry_ac_io_t *@var{io_cipher})
Encrypts the plain text readable from @var{io_message} through
@var{handle} with the public key @var{key} according to @var{scheme},
@var{flags} and @var{opts}. If @var{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 @var{io_cipher}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_cipher}, gcry_ac_io_t *@var{io_message})
Decrypts the cipher text readable from @var{io_cipher} through
@var{handle} with the secret key @var{key} according to @var{scheme},
@var{flags} and @var{opts}. If @var{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 @var{io_message}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_message}, gcry_ac_io_t *@var{io_signature})
Signs the message readable from @var{io_message} through @var{handle}
with the secret key @var{key} according to @var{scheme}, @var{flags}
and @var{opts}. If @var{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 @var{io_signature}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_message}, gcry_ac_io_t *@var{io_signature})
Verifies through @var{handle} that the signature readable from
@var{io_signature} is indeed the result of signing the message
readable from @var{io_message} with the secret key belonging to the
public key @var{key} according to @var{scheme} and @var{opts}. If
@var{opts} is not NULL, it has to be an anonymous structure
(gcry_ac_ssa_*_t) specific to the chosen scheme.
@end deftypefun
@node Handle-independent functions
@section Handle-independent functions
@deftypefun gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t @var{algorithm}, const char **@var{name})
Stores the textual representation of the algorithm whose id is given
in @var{algorithm} in @var{name}.
@end deftypefun
@deftypefun gcry_error_t gcry_ac_name_to_id (const char *@var{name}, gcry_ac_id_t *@var{algorithm})
Stores the numeric ID of the algorithm whose textual representation is
contained in @var{name} in @var{algorithm}.
@end deftypefun
@c **********************************************************
@c ******************* Random *****************************
@c **********************************************************
@node Random Numbers
@chapter Random Numbers
@menu
* Quality of random numbers:: @acronym{Libgcrypt} uses different quality levels.
* Retrieving random numbers:: How to retrieve random numbers.
@end menu
@node Quality of random numbers
@section Quality of random numbers
@acronym{Libgcypt} offers random numbers of different quality levels:
@deftp {Data type} enum gcry_random_level
The constants for the random quality levels are of this type.
@end deftp
@table @code
@item GCRY_WEAK_RANDOM
This should not anymore be used. It has recently been changed to an
alias of GCRY_STRONG_RANDOM. Use @code{gcry_create_nonce} instead.
@item GCRY_STRONG_RANDOM
Use this level for e.g. session keys and similar purposes.
@item GCRY_VERY_STRONG_RANDOM
Use this level for e.g. key material.
@end table
@node Retrieving random numbers
@section Retrieving random numbers
@deftypefun void gcry_randomize (unsigned char *@var{buffer}, size_t @var{length}, enum gcry_random_level @var{level})
Fill @var{buffer} with @var{length} random bytes using a random quality
as defined by @var{level}.
@end deftypefun
@deftypefun void * gcry_random_bytes (size_t @var{nbytes}, enum gcry_random_level @var{level})
Allocate a memory block consisting of @var{nbytes} fresh random bytes
using a random quality as defined by @var{level}.
@end deftypefun
@deftypefun void * gcry_random_bytes_secure (size_t @var{nbytes}, enum gcry_random_level @var{level})
Allocate a memory block consisting of @var{nbytes} fresh random bytes
using a random quality as defined by @var{level}. This function
differs from @code{gcry_random_bytes} in that the returned buffer is
allocated in a ``secure'' area of the memory.
@end deftypefun
@deftypefun void gcry_create_nonce (unsigned char *@var{buffer}, size_t @var{length})
Fill @var{buffer} with @var{length} unpredictable bytes. This is
commonly called a nonce and may also be used for initialization
vectors and padding. This is an extra function nearly independent of
the other random function for 3 reasons: It better protects the
regular random generator's internal state, provides better performance
and does not drain the precious entropy pool.
@end deftypefun
@c **********************************************************
@c ******************* S-Expressions ***********************
@c **********************************************************
@node S-expressions
@chapter S-expressions
S-expressions are used by the public key functions to pass complex data
structures around. These LISP like objects are used by some
cryptographic protocols (cf. RFC-2692) and @acronym{Libgcrypt} provides functions
to parse and construct them. For detailed information, see
@cite{Ron Rivest, code and description of S-expressions,
@uref{http://theory.lcs.mit.edu/~rivest/sexp.html}}.
@menu
* Data types for S-expressions:: Data types related with S-expressions.
* Working with S-expressions:: How to work with S-expressions.
@end menu
@node Data types for S-expressions
@section Data types for S-expressions
@deftp {Data type} gcry_sexp_t
The @code{gcry_sexp_t} type describes an object with the @acronym{Libgcrypt} internal
representation of an S-expression.
@end deftp
@node Working with S-expressions
@section Working with S-expressions
@noindent
There are several functions to create an @acronym{Libgcrypt} S-expression object
from its external representation or from a string template. There is
also a function to convert the internal representation back into one of
the external formats:
@deftypefun gcry_error_t gcry_sexp_new (@w{gcry_sexp_t *@var{r_sexp}}, @w{const void *@var{buffer}}, @w{size_t @var{length}}, @w{int @var{autodetect}})
This is the generic function to create an new S-expression object from
its external representation in @var{buffer} of @var{length} bytes. On
success the result is stored at the address given by @var{r_sexp}.
With @var{autodetect} set to 0, the data in @var{buffer} is expected to
be in canonized format, with @var{autodetect} set to 1 the parses any of
the defined external formats. If @var{buffer} does not hold a valid
S-expression an error code is returned and @var{r_sexp} set to
@code{NULL}.
Note, that the caller is responsible for releasing the newly allocated
S-expression using @code{gcry_sexp_release}.
@end deftypefun
@deftypefun gcry_error_t gcry_sexp_create (@w{gcry_sexp_t *@var{r_sexp}}, @w{void *@var{buffer}}, @w{size_t @var{length}}, @w{int @var{autodetect}}, @w{void (*@var{freefnc})(void*)})
This function is identical to @code{gcry_sexp_new} but has an extra
argument @var{freefnc}, which, when not set to @code{NULL}, is expected
to be a function to release the @var{buffer}; most likely the standard
@code{free} function is used for this argument. This has the effect of
transferring the ownership of @var{buffer} to the created object in
@var{r_sexp}. The advantage of using this function is that @acronym{Libgcrypt}
might decide to directly use the provided buffer and thus avoid extra
copying.
@end deftypefun
@deftypefun gcry_error_t gcry_sexp_sscan (@w{gcry_sexp_t *@var{r_sexp}}, @w{size_t *@var{erroff}}, @w{const char *@var{buffer}}, @w{size_t @var{length}})
This is another variant of the above functions. It behaves nearly
identical but provides an @var{erroff} argument which will receive the
offset into the buffer where the parsing stopped on error.
@end deftypefun
@deftypefun gcry_error_t gcry_sexp_build (@w{gcry_sexp_t *@var{r_sexp}}, @w{size_t *@var{erroff}}, @w{const char *@var{format}, ...})
This function creates an internal S-expression from the string template
@var{format} and stores it at the address of @var{r_sexp}. If there is a
parsing error, the function returns an appropriate error code and stores
the offset into @var{format} where the parsing stopped in @var{erroff}.
The function supports a couple of printf-like formatting characters and
expects arguments for some of these escape sequences right after
@var{format}. The following format characters are defined:
@table @samp
@item %m
The next argument is expected to be of type @code{gcry_mpi_t} and a copy of
its value is inserted into the resulting S-expression.
@item %s
The next argument is expected to be of type @code{char *} and that
string is inserted into the resulting S-expression.
@item %d
The next argument is expected to be of type @code{int} and its value is
inserted into the resulting S-expression.
@item %b
The next argument is expected to be of type @code{int} directly
followed by an argument of type @code{char *}. This represents a
buffer of given length to be inserted into the resulting regular
expression.
@end table
@noindent
No other format characters are defined and would return an error. Note,
that the format character @samp{%%} does not exists, because a percent
sign is not a valid character in an S-expression.
@end deftypefun
@deftypefun void gcry_sexp_release (@w{gcry_sexp_t @var{sexp}})
Release the S-expression object @var{sexp}.
@end deftypefun
@noindent
The next 2 functions are used to convert the internal representation
back into a regular external S-expression format and to show the
structure for debugging.
@deftypefun size_t gcry_sexp_sprint (@w{gcry_sexp_t @var{sexp}}, @w{int @var{mode}}, @w{char *@var{buffer}}, @w{size_t @var{maxlength}})
Copies the S-expression object @var{sexp} into @var{buffer} using the
format specified in @var{mode}. @var{maxlength} must be set to the
allocated length of @var{buffer}. The function returns the actual
length of valid bytes put into @var{buffer} or 0 if the provided buffer
is too short. Passing @code{NULL} for @var{buffer} returns the required
length for @var{buffer}. For convenience reasons an extra byte with
value 0 is appended to the buffer.
@noindent
The following formats are supported:
@table @code
@item GCRYSEXP_FMT_DEFAULT
Returns a convenient external S-expression representation.
@item GCRYSEXP_FMT_CANON
Return the S-expression in canonical format.
@item GCRYSEXP_FMT_BASE64
Not currently supported.
@item GCRYSEXP_FMT_ADVANCED
Returns the S-expression in advanced format.
@end table
@end deftypefun
@deftypefun void gcry_sexp_dump (@w{gcry_sexp_t @var{sexp}})
Dumps @var{sexp} in a format suitable for debugging to @acronym{Libgcrypt}'s
logging stream.
@end deftypefun
@noindent
Often canonical encoding is used in the external representation. The
following function can be used to check for valid encoding and to learn
the length of the S-expression"
@deftypefun size_t gcry_sexp_canon_len (@w{const unsigned char *@var{buffer}}, @w{size_t @var{length}}, @w{size_t *@var{erroff}}, @w{int *@var{errcode}})
Scan the canonical encoded @var{buffer} with implicit length values and
return the actual length this S-expression uses. For a valid S-expression
it should never return 0. If @var{length} is not 0, the maximum
length to scan is given; this can be used for syntax checks of
data passed from outside. @var{errcode} and @var{erroff} may both be
passed as @code{NULL}.
@end deftypefun
@noindent
There are a couple of functions to parse S-expressions and retrieve
elements:
@deftypefun gcry_sexp_t gcry_sexp_find_token (@w{const gcry_sexp_t @var{list}}, @w{const char *@var{token}}, @w{size_t @var{toklen}})
Scan the S-expression for a sublist with a type (the car of the list)
matching the string @var{token}. If @var{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 @code{NULL}
when not found.
@end deftypefun
@deftypefun int gcry_sexp_length (@w{const gcry_sexp_t @var{list}})
Return the length of the @var{list}. For a valid S-expression this
should be at least 1.
@end deftypefun
@deftypefun gcry_sexp_t gcry_sexp_nth (@w{const gcry_sexp_t @var{list}}, @w{int @var{number}})
Create and return a new S-expression from the element with index @var{number} in
@var{list}. Note that the first element has the index 0. If there is
no such element, @code{NULL} is returned.
@end deftypefun
@deftypefun gcry_sexp_t gcry_sexp_car (@w{const gcry_sexp_t @var{list}})
Create and return a new S-expression from the first element in
@var{list}; this called the "type" and should always exist and be a
string. @code{NULL} is returned in case of a problem.
@end deftypefun
@deftypefun gcry_sexp_t gcry_sexp_cdr (@w{const gcry_sexp_t @var{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 @code{NULL} on error.
@end deftypefun
@deftypefun {const char *} gcry_sexp_nth_data (@w{const gcry_sexp_t @var{list}}, @w{int @var{number}}, @w{size_t *@var{datalen}})
This function is used to get data from a @var{list}. A pointer to the
actual data with index @var{number} is returned and the length of this
data will be stored to @var{datalen}. If there is no data at the given
index or the index represents another list, @code{NULL} is returned.
@strong{Note:} The returned pointer is valid as long as @var{list} is
not modified or released.
@noindent
Here is an example on how to extract and print the surname (Meier) from
the S-expression @samp{(Name Otto Meier (address Burgplatz 3))}:
@example
size_t len;
const char *name;
name = gcry_sexp_nth_data (list, 2, &len);
printf ("my name is %.*s\n", (int)len, name);
@end example
@end deftypefun
@deftypefun gcry_mpi_t gcry_sexp_nth_mpi (@w{gcry_sexp_t @var{list}}, @w{int @var{number}}, @w{int @var{mpifmt}})
This function is used to get and convert data from a @var{list}. This
data is assumed to be an MPI stored in the format described by
@var{mpifmt} and returned as a standard @acronym{Libgcrypt} MPI. The caller must
release this returned value using @code{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, @code{NULL} is returned.
@end deftypefun
@c **********************************************************
@c ******************* MPIs ******** ***********************
@c **********************************************************
@node MPI library
@chapter MPI library
@menu
* Data types:: MPI related data types.
* Basic functions:: First steps with MPI numbers.
* MPI formats:: External representation of MPIs.
* Calculations:: Performing MPI calculations.
* Comparisons:: How to compare MPI values.
* Bit manipulations:: How to access single bits of MPI values.
* Miscellaneous:: Miscellaneous MPI functions.
@end menu
Public key cryptography is based on mathematics with large numbers. To
implement the public key functions, a library for handling these large
numbers is required. Because of the general usefulness of such a
library, its interface is exposed by @acronym{Libgcrypt}. The implementation is
based on an old release of GNU Multi-Precision Library (GMP) but in the
meantime heavily modified and stripped down to what is required for
cryptography. For a lot of CPUs, high performance assembler
implementations of some very low level functions are used to gain much
better performance than with the standard C implementation.
@noindent
In the context of @acronym{Libgcrypt} and in most other applications, these large
numbers are called MPIs (multi-precision-integers).
@node Data types
@section Data types
@deftp {Data type} gcry_mpi_t
The @code{gcry_mpi_t} type represents an object to hold an MPI.
@end deftp
@node Basic functions
@section Basic functions
@noindent
To work with MPIs, storage must be allocated and released for the
numbers. This can be done with one of these functions:
@deftypefun gcry_mpi_t gcry_mpi_new (@w{unsigned int @var{nbits}})
Allocate a new MPI object, initialize it to 0 and initially allocate
enough memory for a number of at least @var{nbits}. This pre-allocation is
only a small performance issue and not actually necessary because
@acronym{Libgcrypt} automatically re-allocates the required memory.
@end deftypefun
@deftypefun gcry_mpi_t gcry_mpi_snew (@w{unsigned int @var{nbits}})
This is identical to @code{gcry_mpi_new} but allocates the MPI in the so
called "secure memory" which in turn will take care that all derived
values will also be stored in this "secure memory". Use this for highly
confidential data like private key parameters.
@end deftypefun
@deftypefun gcry_mpi_t gcry_mpi_copy (@w{const gcry_mpi_t @var{a}})
Create a new MPI as the exact copy of @var{a}.
@end deftypefun
@deftypefun void gcry_mpi_release (@w{gcry_mpi_t @var{a}})
Release the MPI @var{a} and free all associated resources. Passing
@code{NULL} is allowed and ignored. When a MPI stored in the "secure
memory" is released, that memory gets wiped out immediately.
@end deftypefun
@noindent
The simplest operations are used to assign a new value to an MPI:
@deftypefun gcry_mpi_t gcry_mpi_set (@w{gcry_mpi_t @var{w}}, @w{const gcry_mpi_t @var{u}})
Assign the value of @var{u} to @var{w} and return @var{w}. If
@code{NULL} is passed for @var{w}, a new MPI is allocated, set to the
value of @var{u} and returned.
@end deftypefun
@deftypefun gcry_mpi_t gcry_mpi_set_ui (@w{gcry_mpi_t @var{w}}, @w{unsigned long @var{u}})
Assign the value of @var{u} to @var{w} and return @var{w}. If
@code{NULL} is passed for @var{w}, a new MPI is allocated, set to the
value of @var{u} and returned. This function takes an @code{unsigned
int} as type for @var{u} and thus it is only possible to set @var{w} to
small values (usually up to the word size of the CPU).
@end deftypefun
@deftypefun void gcry_mpi_swap (@w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{b}})
Swap the values of @var{a} and @var{b}.
@end deftypefun
@node MPI formats
@section MPI formats
@noindent
The following functions are used to convert between an external
representation of an MPI and the internal one of @acronym{Libgcrypt}.
@deftypefun gcry_error_t gcry_mpi_scan (@w{gcry_mpi_t *@var{r_mpi}}, @w{enum gcry_mpi_format @var{format}}, @w{const unsigned char *@var{buffer}}, @w{size_t @var{buflen}}, @w{size_t *@var{nscanned}})
Convert the external representation of an integer stored in @var{buffer}
with a length of @var{buflen} into a newly created MPI returned which
will be stored at the address of @var{r_mpi}. For certain formats the
length argument is not required and may be passed as @code{0}. After a
successful operation the variable @var{nscanned} receives the number of
bytes actually scanned unless @var{nscanned} was given as
@code{NULL}. @var{format} describes the format of the MPI as stored in
@var{buffer}:
@table @code
@item GCRYMPI_FMT_STD
2-complement stored without a length header.
@item GCRYMPI_FMT_PGP
As used by OpenPGP (only defined as unsigned). This is basically
@code{GCRYMPI_FMT_STD} with a 2 byte big endian length header.
@item GCRYMPI_FMT_SSH
As used in the Secure Shell protocol. This is @code{GCRYMPI_FMT_STD}
with a 4 byte big endian header.
@item GCRYMPI_FMT_HEX
Stored as a C style string with each byte of the MPI encoded as 2 hex
digits. When using this format, @var{buflen} must be zero.
@item GCRYMPI_FMT_USG
Simple unsigned integer.
@end table
@noindent
Note, that all of the above formats store the integer in big-endian
format (MSB first).
@end deftypefun
@deftypefun gcry_error_t gcry_mpi_print (@w{enum gcry_mpi_format @var{format}}, @w{unsigned char *@var{buffer}}, @w{size_t @var{buflen}}, @w{size_t *@var{nwritten}}, @w{const gcry_mpi_t @var{a}})
Convert the MPI @var{a} into an external representation described by
@var{format} (see above) and store it in the provided @var{buffer}
which has a usable length of at least the @var{buflen} bytes. If
@var{nwritten} is not NULL, it will receive the number of bytes
actually stored in @var{buffer} after a successful operation.
@end deftypefun
@deftypefun gcry_error_t gcry_mpi_aprint (@w{enum gcry_mpi_format @var{format}}, @w{unsigned char **@var{buffer}}, @w{size_t *@var{nbytes}}, @w{const gcry_mpi_t @var{a}})
Convert the MPI @var{a} into an external representation described by
@var{format} (see above) and store it in a newly allocated buffer which
address will be stored in the variable @var{buffer} points to. The
number of bytes stored in this buffer will be stored in the variable
@var{nbytes} points to, unless @var{nbytes} is @code{NULL}.
@end deftypefun
@deftypefun void gcry_mpi_dump (@w{const gcry_mpi_t @var{a}})
Dump the value of @var{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 @code{NULL} for
@var{a}.
@end deftypefun
@node Calculations
@section Calculations
@noindent
Basic arithmetic operations:
@deftypefun void gcry_mpi_add (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}})
@math{@var{w} = @var{u} + @var{v}}.
@end deftypefun
@deftypefun void gcry_mpi_add_ui (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
@math{@var{w} = @var{u} + @var{v}}. Note, that @var{v} is an unsigned integer.
@end deftypefun
@deftypefun void gcry_mpi_addm (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}}, @w{gcry_mpi_t @var{m}})
@math{@var{w} = @var{u} + @var{v} \bmod @var{m}}.
@end deftypefun
@deftypefun void gcry_mpi_sub (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}})
@math{@var{w} = @var{u} - @var{v}}.
@end deftypefun
@deftypefun void gcry_mpi_sub_ui (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
@math{@var{w} = @var{u} - @var{v}}. @var{v} is an unsigned integer.
@end deftypefun
@deftypefun void gcry_mpi_subm (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}}, @w{gcry_mpi_t @var{m}})
@math{@var{w} = @var{u} - @var{v} \bmod @var{m}}.
@end deftypefun
@deftypefun void gcry_mpi_mul (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}})
@math{@var{w} = @var{u} * @var{v}}.
@end deftypefun
@deftypefun void gcry_mpi_mul_ui (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
@math{@var{w} = @var{u} * @var{v}}. @var{v} is an unsigned integer.
@end deftypefun
@deftypefun void gcry_mpi_mulm (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{gcry_mpi_t @var{v}}, @w{gcry_mpi_t @var{m}})
@math{@var{w} = @var{u} * @var{v} \bmod @var{m}}.
@end deftypefun
@deftypefun void gcry_mpi_mul_2exp (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}}, @w{unsigned long @var{e}})
@c FIXME: I am in need for a real TeX{info} guru:
@c I don't know why TeX can grok @var{e} here.
@math{@var{w} = @var{u} * 2^e}.
@end deftypefun
@deftypefun void gcry_mpi_div (@w{gcry_mpi_t @var{q}}, @w{gcry_mpi_t @var{r}}, @w{gcry_mpi_t @var{dividend}}, @w{gcry_mpi_t @var{divisor}}, @w{int @var{round}})
@math{@var{q} = @var{dividend} / @var{divisor}}, @math{@var{r} =
@var{dividend} \bmod @var{divisor}}. @var{q} and @var{r} may be passed
as @code{NULL}. @var{round} should be negative or 0.
@end deftypefun
@deftypefun void gcry_mpi_mod (@w{gcry_mpi_t @var{r}}, @w{gcry_mpi_t @var{dividend}}, @w{gcry_mpi_t @var{divisor}})
@math{@var{r} = @var{dividend} \bmod @var{divisor}}.
@end deftypefun
@deftypefun void gcry_mpi_powm (@w{gcry_mpi_t @var{w}}, @w{const gcry_mpi_t @var{b}}, @w{const gcry_mpi_t @var{e}}, @w{const gcry_mpi_t @var{m}})
@c I don't know why TeX can grok @var{e} here.
@math{@var{w} = @var{b}^e \bmod @var{m}}.
@end deftypefun
@deftypefun int gcry_mpi_gcd (@w{gcry_mpi_t @var{g}}, @w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{b}})
Set @var{g} to the greatest common divisor of @var{a} and @var{b}.
Return true if the @var{g} is 1.
@end deftypefun
@deftypefun int gcry_mpi_invm (@w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{a}}, @w{gcry_mpi_t @var{m}})
Set @var{x} to the multiplicative inverse of @math{@var{a} \bmod @var{m}}.
Return true if the inverse exists.
@end deftypefun
@node Comparisons
@section Comparisons
@noindent
The next 2 functions are used to compare MPIs:
@deftypefun int gcry_mpi_cmp (@w{const gcry_mpi_t @var{u}}, @w{const gcry_mpi_t @var{v}})
Compare the big integer number @var{u} and @var{v} returning 0 for
equality, a positive value for @var{u} > @var{v} and a negative for
@var{u} < @var{v}.
@end deftypefun
@deftypefun int gcry_mpi_cmp_ui (@w{const gcry_mpi_t @var{u}}, @w{unsigned long @var{v}})
Compare the big integer number @var{u} with the unsigned integer @var{v}
returning 0 for equality, a positive value for @var{u} > @var{v} and a
negative for @var{u} < @var{v}.
@end deftypefun
@node Bit manipulations
@section Bit manipulations
@noindent
There are a couple of functions to get information on arbitrary bits
in an MPI and to set or clear them:
@deftypefun {unsigned int} gcry_mpi_get_nbits (@w{gcry_mpi_t @var{a}})
Return the number of bits required to represent @var{a}.
@end deftypefun
@deftypefun int gcry_mpi_test_bit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
Return true if bit number @var{n} (counting from 0) is set in @var{a}.
@end deftypefun
@deftypefun void gcry_mpi_set_bit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
Set bit number @var{n} in @var{a}.
@end deftypefun
@deftypefun void gcry_mpi_clear_bit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
Clear bit number @var{n} in @var{a}.
@end deftypefun
@deftypefun void gcry_mpi_set_highbit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
Set bit number @var{n} in @var{a} and clear all bits greater than @var{n}.
@end deftypefun
@deftypefun void gcry_mpi_clear_highbit (@w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
Clear bit number @var{n} in @var{a} and all bits greater than @var{n}.
@end deftypefun
@deftypefun void gcry_mpi_rshift (@w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{a}}, @w{unsigned int @var{n}})
Shift the value of @var{a} by @var{n} bits to the right and store the
result in @var{x}.
@end deftypefun
@node Miscellaneous
@section Miscellanous
@deftypefun gcry_mpi_t gcry_mpi_set_opaque (@w{gcry_mpi_t @var{a}}, @w{void *@var{p}}, @w{unsigned int @var{nbits}})
Store @var{nbits} of the value @var{p} points to in @var{a} and mark
@var{a} as an opaque value (i.e. an value that can't be used for any
math calculation and is only used to store an arbitrary bit pattern in
@var{a}).
WARNING: Never use an opaque MPI for actual math operations. The only
valid functions are gcry_mpi_get_opaque and gcry_mpi_release. Use
gcry_mpi_scan to convert a string of arbitrary bytes into an MPI.
@end deftypefun
@deftypefun {void *} gcry_mpi_get_opaque (@w{gcry_mpi_t @var{a}}, @w{unsigned int *@var{nbits}})
Return a pointer to an opaque value stored in @var{a} and return its
size in @var{nbits}. Note, that the returned pointer is still owned by
@var{a} and that the function should never be used for an non-opaque
MPI.
@end deftypefun
@deftypefun void gcry_mpi_set_flag (@w{gcry_mpi_t @var{a}}, @w{enum gcry_mpi_flag @var{flag}})
Set the @var{flag} for the MPI @var{a}. Currently only the flag
@code{GCRYMPI_FLAG_SECURE} is allowed to convert @var{a} into an MPI
stored in "secure memory".
@end deftypefun
@deftypefun void gcry_mpi_clear_flag (@w{gcry_mpi_t @var{a}}, @w{enum gcry_mpi_flag @var{flag}})
Clear @var{flag} for the big integer @var{a}. Note, that this function is
currently useless as no flags are allowed.
@end deftypefun
@deftypefun int gcry_mpi_get_flag (@w{gcry_mpi_t @var{a}}, @w{enum gcry_mpi_flag @var{flag}})
Return true when the @var{flag} is set for @var{a}.
@end deftypefun
@deftypefun void gcry_mpi_randomize (@w{gcry_mpi_t @var{w}}, @w{unsigned int @var{nbits}}, @w{enum gcry_random_level @var{level}})
Set the big integer @var{w} to a random value of @var{nbits}, using
random data quality of level @var{level}. In case @var{nbits} is not
a multiple of a byte, @var{nbits} is rounded up to the next byte
boundary.
@end deftypefun
@c **********************************************************
@c ******************** Prime numbers ***********************
@c **********************************************************
@node Prime numbers
@chapter Prime numbers
@menu
* Generation:: Generation of new prime numbers.
* Checking:: Checking if a given number is prime.
@end menu
@node Generation
@section Generation
@deftypefun gcry_error_t gcry_prime_generate (gcry_mpi_t *@var{prime},
unsigned int @var{prime_bits}, unsigned int @var{factor_bits},
gcry_mpi_t **@var{factors}, gcry_prime_check_func_t @var{cb_func},
void *@var{cb_arg}, gcry_random_level_t @var{random_level},
unsigned int @var{flags})
Generate a new prime number of @var{prime_bits} bits and store it in
@var{prime}. If @var{factor_bits} is non-zero, one of the prime factors
of (@var{prime} - 1) / 2 must be @var{factor_bits} bits long. If
@var{factors} is non-zero, allocate a new, @code{NULL}-terminated array
holding the prime factors and store it in @var{factors}. @var{flags}
might be used to influence the prime number generation process.
@end deftypefun
@deftypefun gcry_prime_group_generator (gcry_mpi_t *@var{r_g},
gcry_mpi_t @var{prime}, gcry_mpi_t *@var{factors}, gcry_mpi_t @var{start_g})
Find a generator for @var{prime} where the factorization of (@var{prime}
- 1) is in the @code{NULL} terminated array @var{factors}. Return the
generator as a newly allocated MPI in @var{r_g}. If @var{start_g} is
not NULL, use this as the start for the search.
@end deftypefun
@deftypefun void gcry_prime_release_factors (gcry_mpi_t *@var{factors})
Convenience function to release the @var{factors} array.
@end deftypefun
@node Checking
@section Checking
@deftypefun gcry_error_t gcry_prime_check (gcry_mpi_t @var{p},
unsigned int @var{flags})
Check wether the number @var{p} is prime. Returns zero in case @var{p}
is indeed a prime, returns @code{GPG_ERR_NO_PRIME} in case @var{p} is
not a prime and a different error code in case something went horribly
wrong.
@end deftypefun
@node Utilities
@chapter Utilities
@menu
* Memory allocation:: Functions related with memory allocation.
@end menu
@node Memory allocation
@section Memory allocation
@deftypefun void *gcry_malloc (size_t @var{n})
This function tries to allocate @var{n} bytes of memory. On success
it returns a pointer to the memory area, in an out-of-core condition,
it returns NULL.
@end deftypefun
@deftypefun void *gcry_malloc_secure (size_t @var{n})
Like @code{gcry_malloc}, but uses secure memory.
@end deftypefun
@deftypefun void *gcry_calloc (size_t @var{n})
This function tries to allocate @var{n} bytes of cleared memory
(i.e. memory that is initialized with zero bytes). On success it
returns a pointer to the memory area, in an out-of-core condition, it
returns NULL.
@end deftypefun
@deftypefun void *gcry_calloc_secure (size_t @var{n})
Like @code{gcry_calloc}, but uses secure memory.
@end deftypefun
@deftypefun void *gcry_realloc (void *@var{p}, size_t @var{n})
This function tries to resize the memory area pointed to by @var{p} to
@var{n} bytes. On success it returns a pointer to the new memory
area, in an out-of-core condition, it returns NULL. Depending on
whether the memory pointed to by @var{p} is secure memory or not,
gcry_realloc tries to use secure memory as well.
@end deftypefun
@deftypefun void gcry_free (void *@var{p})
Release the memory area pointed to by @var{p}.
@end deftypefun
@c **********************************************************
@c ******************* Appendices *************************
@c **********************************************************
@include lgpl.texi
@include gpl.texi
@node Concept Index
@unnumbered Concept Index
@printindex cp
@node Function and Data Index
@unnumbered Function and Data Index
@printindex fn
@bye
/* Version check should be the very first gcry call because it
makes sure that constructor functions are run. */
if (!gcry_check_version (GCRYPT_VERSION))
die ("version mismatch\n");
/* Many applications don't require secure memory, so they should
disable it right away. There won't be a problem unless one makes
use of a feature which requires secure memory - in that case the
process would abort because the secmem is not initialized. */
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
/* .. add whatever initialization you want, but better don't make calls
to libgcrypt from more than one thread ... */
/* Tell Libgcrypt that initialization has completed. */
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
If you require secure memory, this code should be used:
if (!gcry_check_version (GCRYPT_VERSION))
die ("version mismatch\n");
/* We don't want to see any warnings, e.g. because we have not yet
parsed options which might be used to suppress such warnings */
gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
/* ... */
/* Allocate a pool of 16k secure memory. This also drops priviliges
on some systems. */
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
/* It is now okay to let Libgcrypt complain when there was/is a problem
with the secure memory. */
gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
/* Tell Libgcrypt that initialization has completed. */
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
This sounds a bit complicated but has the advantage that the caller
must decide whether he wants secure memory or not - there is no
default.
It is important that this initialization is not done by a library but
in the application. The library might want to check for finished
initialization using:
if (!gcry_control (GCRYCTL_INITIALIZATION_FINISHED_P))
return MYLIB_ERROR_LIBGCRYPT_NOT_INITIALIZED;
@c LocalWords: int HD
diff --git a/tests/ChangeLog b/tests/ChangeLog
index bd86b5f4..4d78663e 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,369 +1,378 @@
+2006-03-07 Werner Koch <wk@g10code.com>
+
+ * benchmark.c (cipher_bench): Add OFB mode.
+
+2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07)
+
+ * basic.c: Added test cases for OFB and CFB modes. Fixed some
+ compiler warnings for signedness.
+
2005-11-12 Moritz Schulte <moritz@g10code.com>
* ac-data.c: Added way more test cases.
2005-09-15 Moritz Schulte <moritz@g10code.com>
* Makefile.am (TESTS): Added keygrip.
* keygrip.c: New.
2005-09-19 Werner Koch <wk@g10code.com>
* benchmark.c (dsa_bench): New.
2005-08-19 Werner Koch <wk@g10code.com>
* hmac.c (main): Added all FIPS tests.
2005-08-18 Werner Koch <wk@g10code.com>
* hmac.c: New.
2005-04-22 Moritz Schulte <moritz@g10code.com>
* tsexp.c: Include <config.h> in case HAVE_CONFIG_H is defined;
thanks to Albert Chin.
* testapi.c: Likewise.
* register.c: Likewise.
* pubkey.c: Likewise.
* prime.c: Likewise.
* pkbench.c: Likewise.
* keygen.c: Likewise.
* benchmark.c: Likewise.
* basic.c: Likewise.
* ac-schemes.c: Likewise.
* ac-data.c: Likewise.
* ac.c: Likewise.
2005-04-16 Moritz Schulte <moritz@g10code.com>
* ac-data.c (check_run): Include new test.
2005-04-11 Moritz Schulte <moritz@g10code.com>
* basic.c (check_digests): Add tests for Whirlpool.
2005-03-30 Moritz Schulte <moritz@g10code.com>
* ac-schemes.c: New file.
* ac-data.c: New file.
* Makefile.am (TESTS): Added ac-schemes and ac-data.
2004-09-15 Moritz Schulte <moritz@g10code.com>
* pkbench.c: Include <time.h>.
2004-08-24 Moritz Schulte <moritz@g10code.com>
* pkbench.c (context_init): Improve generation of test data.
2004-08-23 Moritz Schulte <moritz@g10code.com>
* Makefile.am (TESTS): Added: pkbench.
* pkbench.c: New file.
2004-02-25 Werner Koch <wk@gnupg.org>
* Makefile.am (TEST): Add benchmark.
* benchmark.c (md_bench, cipher_bench): Allow NULL arg to to run
tests for all algorithms.
(main): Run all tests by default.
2004-02-03 Werner Koch <wk@gnupg.org>
* tsexp.c (basic): New pass to check secure memory switching.
2004-01-12 Moritz Schulte <mo@g10code.com>
* ac.c (check_one): Adjust to new ac API.
2003-11-22 Werner Koch <wk@gnupg.org>
* pubkey.c (check_keys_crypt): Fixed my last patch.
2003-11-11 Werner Koch <wk@gnupg.org>
* tsexp.c (basic): Add pass structure and a test for the %b
format.
2003-11-04 Werner Koch <wk@gnupg.org>
* Makefile.am (noinst_PROGRAMS): Use this so that test programs
get always build.
* keygen.c (check_nonce): New.
(main): Add a basic check for the nocen function.
2003-10-31 Werner Koch <wk@gnupg.org>
* basic.c (check_aes128_cbc_cts_cipher): Make it a prototype
* ac.c (check_run): Comment unused variable.
2003-10-10 Werner Koch <wk@gnupg.org>
* prime.c (check_primes): Generate a generator and avoid printing
unless in verbose mode.
2003-10-07 Werner Koch <wk@gnupg.org>
* tsexp.c (check_sscan): New.
2003-09-04 Werner Koch <wk@gnupg.org>
* pubkey.c (check_keys_crypt): Fix for compatibility mode.
2003-09-02 Moritz Schulte <mo@g10code.com>
* Makefile.am (TESTS): Added: prime.
* prime.c: New file.
2003-08-27 Moritz Schulte <mo@g10code.com>
* basic.c (check_ciphers): Added: Serpent.
Write braces around flags.
2003-08-04 Moritz Schulte <moritz@g10code.com>
* benchmark.c (do_powm): Adjust for new gcry_mpi_scan interface.
2003-07-23 Moritz Schulte <moritz@g10code.com>
* ac.c (key_copy): New function...
(check_one): ... use it.
2003-07-22 Moritz Schulte <moritz@g10code.com>
* basic.c (check_ciphers): Use gcry_cipher_map_name.
2003-07-18 Moritz Schulte <moritz@g10code.com>
* ac.c (check_run): Renamed to ...
(check_one): ... this, changed calling interface.
(check_run): New function.
* register.c: Adjust gcry_cipher_spec_t structure.
2003-07-14 Moritz Schulte <moritz@g10code.com>
* register.c: Adjust cipher specification structure.
* benchmark.c: New file.
* testapi.c: New file.
* Makefile.am (EXTRA_PROGRAMS): Set to: benchmark testapi.
(check_PROGRAMS): Set to: $(TESTS).
2003-07-12 Moritz Schulte <moritz@g10code.com>
* ac.c, basic.c, keygen.c, register.c, sexp.c, tsexp.c: Used
gcry_err* wrappers for libgpg symbols.
* basic.c (check_ciphers): Added: GCRY_CIPHER_TWOFISH128.
2003-07-08 Moritz Schulte <moritz@g10code.com>
* Makefile.am (LIBS): Remove: -lpthread.
* basic.c (check_one_cipher): Fix variable initialization. Thanks
to Simon Joseffson <jas@extundo.com>.
2003-07-07 Moritz Schulte <moritz@g10code.com>
* Makefile.am (TESTS): Added: register.
2003-07-05 Moritz Schulte <moritz@g10code.com>
* register.c (check_run): Adjusted for new gcry_cipher_register API.
2003-07-02 Moritz Schulte <moritz@g10code.com>
* Makefile.am (TESTS): Added: ac.
* ac.c: New file.
2003-06-18 Werner Koch <wk@gnupg.org>
* basic.c (check_cbc_mac_cipher): Adjusted for new API of get_blklen
and get_keylen.
(check_ctr_cipher): Ditto.
(check_one_cipher): Ditto.
(check_one_md): Adjusted for new API of gcry_md_copy.
2003-06-18 Moritz Schulte <moritz@g10code.com>
* register.c: Replace old type GcryModule with newer one:
gcry_module_t.
Adjusted for new API.
* Makefile.am (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
2003-06-15 Moritz Schulte <moritz@g10code.com>
* basic.c (get_keys_new): New function.
(do_check_one_pubkey): New function ...
(check_one_pubkey): ... use it.
(progress_handler): New function.
(main): Use gcry_set_progress_handler.
2003-06-14 Moritz Schulte <moritz@g10code.com>
* basic.c: Replaced calls to gcry_strerror with calls to
gpg_strerror.
(check_one_md): Adjust for new gcry_md_copy API.
* tsexp.c: Likewise.
* keygen.c: Likewise.
2003-06-12 Moritz Schulte <moritz@g10code.com>
* basic.c: Changed here and there, reorganized pubkey checks,
added DSA and ELG keys.
2003-06-09 Moritz Schulte <moritz@g10code.com>
* basic.c, keygen.c, pubkey.c, register.c, tsexp.c: Changed to use
new API.
2003-06-01 Moritz Schulte <moritz@g10code.com>
* tsexp.c (canon_len): Adjust for new gcry_sexp_canon_len API.
2003-05-26 Moritz Schulte <moritz@g10code.com>
* basic.c (verify_one_signature): Adjust for libgpg-error.
(check_pubkey_sign): Likewise.
(check_pubkey): Likewise.
* basic.c (check_pubkey_sign): Likewise.
* tsexp.c (canon_len): Likewise.
(back_and_forth_one): Likewise.
2003-04-27 Moritz Schulte <moritz@g10code.com>
* pubkey.c: Changed the sample private key to contain the
identifier `openpgp-rsa' instead of `rsa'.
* basic.c (check_digests): Enabled/fixed some tests for TIGER.
2003-04-17 Moritz Schulte <moritz@g10code.com>
* Makefile.am (TESTS): Removed `register' for now.
2003-04-17 Moritz Schulte <moritz@g10code.com>
* basic.c (check_digests): Include checks for SHA512 and SHA384.
2003-04-16 Moritz Schulte <moritz@g10code.com>
* basic.c (check_one_md): Also test md_copy.
2003-04-07 Moritz Schulte <moritz@g10code.com>
* Makefile.am (TESTS): Added register.
* register.c: New file.
2003-03-30 Simon Josefsson <jas@extundo.com>
* basic.c (check_one_cipher): New. Test CTR.
(main): Call it.
(check_ciphers): Check CTR mode.
2003-03-26 Moritz Schulte <moritz@g10code.com>
* Makefile.am (TESTS): Added pubkey.
* pubkey.c: New file.
2003-03-22 Simon Josefsson <jas@extundo.com>
* basic.c (check_cbc_mac_cipher): New.
(main): Use it.
2003-03-19 Werner Koch <wk@gnupg.org>
* keygen.c (check_rsa_keys): Don't expect an exponent when asking
for e=0.
(check_generated_rsa_key): Just print exponent if EXPECTED_E is 0.
2003-03-02 Moritz Schulte <moritz@g10code.com>
* basic.c (check_one_cipher): Use gcry_cipher_reset() instead of
gcry_cipher_close(), gcry_cipher_open and gcry_cipher_setkey().
2003-01-23 Werner Koch <wk@gnupg.org>
* keygen.c: New.
2003-01-20 Simon Josefsson <jas@extundo.com>
* basic.c (check_digests): Add CRC.
(check_one_md): Print computed and expected values on error.
2003-01-20 Werner Koch <wk@gnupg.org>
* basic.c (check_one_md): Kludge to check a one million "a".
(check_digests): Add checks for SHA-256.
2003-01-20 Werner Koch <wk@gnupg.org>
* basic.c (check_pubkey): Check the keygrip for the sample key.
2003-01-15 Werner Koch <wk@gnupg.org>
* basic.c (verify_one_signature,check_pubkey_sign)
(check_pubkey): New.
(main): Check public key functions. Add a --debug option.
2002-11-23 Werner Koch <wk@gnupg.org>
* basic.c (check_digests): Add another test for MD4. By Simon
Josefsson.
2002-11-10 Simon Josefsson <jas@extundo.com>
* basic.c (check_aes128_cbc_cts_cipher): New function.
(check_one_cipher): Add flags parameter.
(check_ciphers): Support flags parameter.
(main): Check CTS.
2002-11-10 Werner Koch <wk@gnupg.org>
* basic.c (check_one_md): New. By Simon Josefsson.
(check_digests): New tests for MD4. By Simon.
2002-08-26 Werner Koch <wk@gnupg.org>
* basic.c (check_ciphers): Check simple DES.
2002-05-16 Werner Koch <wk@gnupg.org>
* tsexp.c (back_and_forth): Very minimal test of the new functions.
2002-05-14 Werner Koch <wk@gnupg.org>
Changed license of all files to the LGPL.
2002-05-02 Werner Koch <wk@gnupg.org>
* basic.c: Add option --verbose.
2002-01-11 Werner Koch <wk@gnupg.org>
* tsexp.c (canon_len): Fixed tests.
2001-12-18 Werner Koch <wk@gnupg.org>
* tsexp.c: New.
Copyright 2001, 2002, 2003 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.
diff --git a/tests/basic.c b/tests/basic.c
index f5444dc2..29e0054e 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -1,1124 +1,1516 @@
/* basic.c - basic regression tests
* Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "../src/gcrypt.h"
typedef struct test_spec_pubkey_key
{
const char *secret;
const char *public;
const char *grip;
}
test_spec_pubkey_key_t;
typedef struct test_spec_pubkey
{
int id;
int flags;
test_spec_pubkey_key_t key;
}
test_spec_pubkey_t;
#define FLAG_CRYPT (1 << 0)
#define FLAG_SIGN (1 << 1)
#define FLAG_GRIP (1 << 2)
static int verbose;
static int error_count;
static void
fail (const char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format);
vfprintf (stderr, format, arg_ptr);
va_end (arg_ptr);
error_count++;
}
static void
die (const char *format, ...)
{
va_list arg_ptr;
va_start (arg_ptr, format);
vfprintf (stderr, format, arg_ptr);
va_end (arg_ptr);
exit (1);
}
#define MAX_DATA_LEN 100
void
progress_handler (void *cb_data, const char *what, int printchar,
int current, int total)
{
putchar (printchar);
}
static void
check_cbc_mac_cipher (void)
{
struct tv
{
int algo;
char key[MAX_DATA_LEN];
- char plaintext[MAX_DATA_LEN];
+ unsigned char plaintext[MAX_DATA_LEN];
size_t plaintextlen;
char mac[MAX_DATA_LEN];
}
tv[] =
{
{ GCRY_CIPHER_AES,
"chicken teriyaki",
"This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
0, "\x23\x8f\x6d\xc7\x53\x6a\x62\x97\x11\xc4\xa5\x16\x43\xea\xb0\xb6" },
{ GCRY_CIPHER_3DES,
"abcdefghABCDEFGH01234567",
"This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
0, "\x5c\x11\xf0\x01\x47\xbd\x3d\x3a" },
{ GCRY_CIPHER_DES,
"abcdefgh",
"This is a sample plaintext for CBC MAC of sixtyfour bytes.......",
0, "\xfa\x4b\xdf\x9d\xfa\xab\x01\x70" }
};
gcry_cipher_hd_t hd;
- char out[MAX_DATA_LEN];
+ unsigned char out[MAX_DATA_LEN];
int i, blklen, keylen;
gcry_error_t err = 0;
for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
{
err = gcry_cipher_open (&hd,
tv[i].algo,
GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC);
if (!hd)
{
fail ("cbc-mac algo %d, grcy_open_cipher failed: %s\n",
tv[i].algo, gpg_strerror (err));
return;
}
blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
if (!blklen)
{
fail ("cbc-mac algo %d, gcry_cipher_get_algo_blklen failed\n",
tv[i].algo);
gcry_cipher_close (hd);
return;
}
keylen = gcry_cipher_get_algo_keylen (tv[i].algo);
if (!keylen)
{
fail ("cbc-mac algo %d, gcry_cipher_get_algo_keylen failed\n",
tv[i].algo);
return;
}
err = gcry_cipher_setkey (hd, tv[i].key, keylen);
if (err)
{
fail ("cbc-mac algo %d, gcry_cipher_setkey failed: %s\n",
tv[i].algo, gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
err = gcry_cipher_setiv (hd, NULL, 0);
if (err)
{
fail ("cbc-mac algo %d, gcry_cipher_setiv failed: %s\n",
tv[i].algo, gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
err = gcry_cipher_encrypt (hd,
out, blklen,
tv[i].plaintext,
tv[i].plaintextlen ?
tv[i].plaintextlen :
- strlen (tv[i].plaintext));
+ strlen ((char*)tv[i].plaintext));
if (err)
{
fail ("cbc-mac algo %d, gcry_cipher_encrypt failed: %s\n",
tv[i].algo, gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
#if 0
{
int j;
for (j = 0; j < gcry_cipher_get_algo_blklen (tv[i].algo); j++)
printf ("\\x%02x", out[j] & 0xFF);
printf ("\n");
}
#endif
if (memcmp (tv[i].mac, out, blklen))
fail ("cbc-mac algo %d, encrypt mismatch entry %d\n", tv[i].algo, i);
gcry_cipher_close (hd);
}
}
static void
check_aes128_cbc_cts_cipher (void)
{
char key[128 / 8] = "chicken teriyaki";
- char plaintext[] =
+ unsigned char plaintext[] =
"I would like the General Gau's Chicken, please, and wonton soup.";
struct tv
{
- char out[MAX_DATA_LEN];
+ unsigned char out[MAX_DATA_LEN];
int inlen;
} tv[] =
{
{ "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f"
"\x97",
17 },
{ "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22"
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5",
31 },
{ "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
"\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84",
32 },
{ "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
"\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e"
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5",
47 },
{ "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
"\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8"
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8",
48 },
{ "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84"
"\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8"
"\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40"
"\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8",
64 },
};
gcry_cipher_hd_t hd;
- char out[MAX_DATA_LEN];
+ unsigned char out[MAX_DATA_LEN];
int i;
gcry_error_t err = 0;
err = gcry_cipher_open (&hd,
GCRY_CIPHER_AES,
GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
if (err)
{
fail ("aes-cbc-cts, grcy_open_cipher failed: %s\n", gpg_strerror (err));
return;
}
err = gcry_cipher_setkey (hd, key, 128 / 8);
if (err)
{
fail ("aes-cbc-cts, gcry_cipher_setkey failed: %s\n",
gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
{
err = gcry_cipher_setiv (hd, NULL, 0);
if (err)
{
fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
err = gcry_cipher_encrypt (hd, out, MAX_DATA_LEN,
plaintext, tv[i].inlen);
if (err)
{
fail ("aes-cbc-cts, gcry_cipher_encrypt failed: %s\n",
gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
if (memcmp (tv[i].out, out, tv[i].inlen))
fail ("aes-cbc-cts, encrypt mismatch entry %d\n", i);
err = gcry_cipher_setiv (hd, NULL, 0);
if (err)
{
fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n",
gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
err = gcry_cipher_decrypt (hd, out, tv[i].inlen, NULL, 0);
if (err)
{
fail ("aes-cbc-cts, gcry_cipher_decrypt failed: %s\n",
gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
if (memcmp (plaintext, out, tv[i].inlen))
fail ("aes-cbc-cts, decrypt mismatch entry %d\n", i);
}
gcry_cipher_close (hd);
}
static void
check_ctr_cipher (void)
{
struct tv
{
int algo;
char key[MAX_DATA_LEN];
char ctr[MAX_DATA_LEN];
struct data
{
- char plaintext[MAX_DATA_LEN];
+ unsigned char plaintext[MAX_DATA_LEN];
int inlen;
char out[MAX_DATA_LEN];
}
data[MAX_DATA_LEN];
} tv[] =
{
/* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
{ GCRY_CIPHER_AES,
"\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
{ { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
16,
"\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" },
{ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
16,
"\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff" },
{ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
16,
"\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" },
{ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
16,
"\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" },
}
},
{ GCRY_CIPHER_AES192,
"\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
"\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
{ { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
16,
"\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b" },
{ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
16,
"\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94" },
{ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
16,
"\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7" },
{ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
16,
"\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" },
}
},
{ GCRY_CIPHER_AES256,
"\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
"\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
{ { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
16,
"\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28" },
{ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
16,
"\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5" },
{ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
16,
"\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" },
{ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
16,
"\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" }
}
}
};
gcry_cipher_hd_t hde, hdd;
- char out[MAX_DATA_LEN];
+ unsigned char out[MAX_DATA_LEN];
int i, j, keylen, blklen;
gcry_error_t err = 0;
for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
{
err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
if (!err)
err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
if (err)
{
fail ("aes-ctr, grcy_open_cipher failed: %s\n", gpg_strerror (err));
return;
}
keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
if (!keylen)
{
fail ("aes-ctr, gcry_cipher_get_algo_keylen failed\n");
return;
}
err = gcry_cipher_setkey (hde, tv[i].key, keylen);
if (!err)
err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
if (err)
{
fail ("aes-ctr, gcry_cipher_setkey failed: %s\n",
gpg_strerror (err));
gcry_cipher_close (hde);
gcry_cipher_close (hdd);
return;
}
blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
if (!blklen)
{
fail ("aes-ctr, gcry_cipher_get_algo_blklen failed\n");
return;
}
err = gcry_cipher_setctr (hde, tv[i].ctr, blklen);
if (!err)
err = gcry_cipher_setctr (hdd, tv[i].ctr, blklen);
if (err)
{
fail ("aes-ctr, gcry_cipher_setctr failed: %s\n",
gpg_strerror (err));
gcry_cipher_close (hde);
gcry_cipher_close (hdd);
return;
}
for (j = 0; tv[i].data[j].inlen; j++)
{
err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
tv[i].data[j].plaintext,
tv[i].data[j].inlen == -1 ?
- strlen (tv[i].data[j].plaintext) :
+ strlen ((char*)tv[i].data[j].plaintext) :
tv[i].data[j].inlen);
if (err)
{
fail ("aes-ctr, gcry_cipher_encrypt (%d, %d) failed: %s\n",
i, j, gpg_strerror (err));
gcry_cipher_close (hde);
gcry_cipher_close (hdd);
return;
}
if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j);
err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
if (err)
{
fail ("aes-ctr, gcry_cipher_decrypt (%d, %d) failed: %s\n",
i, j, gpg_strerror (err));
gcry_cipher_close (hde);
gcry_cipher_close (hdd);
return;
}
if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j);
}
gcry_cipher_close (hde);
gcry_cipher_close (hdd);
}
}
+static void
+check_cfb_cipher (void)
+{
+ struct tv
+ {
+ int algo;
+ char key[MAX_DATA_LEN];
+ char iv[MAX_DATA_LEN];
+ struct data
+ {
+ unsigned char plaintext[MAX_DATA_LEN];
+ int inlen;
+ char out[MAX_DATA_LEN];
+ }
+ data[MAX_DATA_LEN];
+ } tv[] =
+ {
+ /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\xc8\xa6\x45\x37\xa0\xb3\xa9\x3f\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b"},
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x26\x75\x1f\x67\xa3\xcb\xb1\x40\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6" },
+ }
+ },
+ { GCRY_CIPHER_AES192,
+ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
+ "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x67\xce\x7f\x7f\x81\x17\x36\x21\x96\x1a\x2b\x70\x17\x1d\x3d\x7a" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0\x42\xae\x8f\xba\x58\x4b\x09\xff" },
+ }
+ },
+ { GCRY_CIPHER_AES256,
+ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x39\xff\xed\x14\x3b\x28\xb1\xc8\x32\x11\x3c\x63\x31\xe5\x40\x7b" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\xdf\x10\x13\x24\x15\xe5\x4b\x92\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x75\xa3\x85\x74\x1a\xb9\xce\xf8\x20\x31\x62\x3d\x55\xb1\xe4\x71" }
+ }
+ }
+ };
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_DATA_LEN];
+ int i, j, keylen, blklen;
+ gcry_error_t err = 0;
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CFB, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CFB, 0);
+ if (err)
+ {
+ fail ("aes-cfb, grcy_open_cipher failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("aes-cfb, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("aes-cfb, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("aes-cfb, gcry_cipher_get_algo_blklen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, blklen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, blklen);
+ if (err)
+ {
+ fail ("aes-cfb, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+ tv[i].data[j].plaintext,
+ tv[i].data[j].inlen);
+ if (err)
+ {
+ fail ("aes-cfb, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) {
+ fail ("aes-cfb, encrypt mismatch entry %d:%d\n", i, j);
+ }
+ err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
+ if (err)
+ {
+ fail ("aes-cfb, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ fail ("aes-cfb, decrypt mismatch entry %d:%d\n", i, j);
+ }
+
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+}
+
+static void
+check_ofb_cipher (void)
+{
+ struct tv
+ {
+ int algo;
+ char key[MAX_DATA_LEN];
+ char iv[MAX_DATA_LEN];
+ struct data
+ {
+ unsigned char plaintext[MAX_DATA_LEN];
+ int inlen;
+ char out[MAX_DATA_LEN];
+ }
+ data[MAX_DATA_LEN];
+ } tv[] =
+ {
+ /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */
+ { GCRY_CIPHER_AES,
+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5\x3c\x52\xda\xc5\x4e\xd8\x25"},
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43\x44\xf7\xa8\x22\x60\xed\xcc" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x30\x4c\x65\x28\xf6\x59\xc7\x78\x66\xa5\x10\xd9\xc1\xd6\xae\x5e" },
+ }
+ },
+ { GCRY_CIPHER_AES192,
+ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b"
+ "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\xfc\xc2\x8b\x8d\x4c\x63\x83\x7c\x09\xe8\x17\x00\xc1\x10\x04\x01" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x8d\x9a\x9a\xea\xc0\xf6\x59\x6f\x55\x9c\x6d\x4d\xaf\x59\xa5\xf2" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x6d\x9f\x20\x08\x57\xca\x6c\x3e\x9c\xac\x52\x4b\xd9\xac\xc9\x2a" },
+ }
+ },
+ { GCRY_CIPHER_AES256,
+ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81"
+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4",
+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+ 16,
+ "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" },
+ { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+ 16,
+ "\x4f\xeb\xdc\x67\x40\xd2\x0b\x3a\xc8\x8f\x6a\xd8\x2a\x4f\xb0\x8d" },
+ { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef",
+ 16,
+ "\x71\xab\x47\xa0\x86\xe8\x6e\xed\xf3\x9d\x1c\x5b\xba\x97\xc4\x08" },
+ { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+ 16,
+ "\x01\x26\x14\x1d\x67\xf3\x7b\xe8\x53\x8f\x5a\x8b\xe7\x40\xe4\x84" }
+ }
+ }
+ };
+ gcry_cipher_hd_t hde, hdd;
+ unsigned char out[MAX_DATA_LEN];
+ int i, j, keylen, blklen;
+ gcry_error_t err = 0;
+
+ for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+ {
+ err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0);
+ if (!err)
+ err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0);
+ if (err)
+ {
+ fail ("aes-ofb, grcy_open_cipher failed: %s\n", gpg_strerror (err));
+ return;
+ }
+
+ keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+ if (!keylen)
+ {
+ fail ("aes-ofb, gcry_cipher_get_algo_keylen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setkey (hde, tv[i].key, keylen);
+ if (!err)
+ err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_setkey failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+ if (!blklen)
+ {
+ fail ("aes-ofb, gcry_cipher_get_algo_blklen failed\n");
+ return;
+ }
+
+ err = gcry_cipher_setiv (hde, tv[i].iv, blklen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, blklen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+ tv[i].data[j].plaintext,
+ tv[i].data[j].inlen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j);
+
+ err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j);
+ }
+
+ err = gcry_cipher_reset(hde);
+ if (!err)
+ err = gcry_cipher_reset(hdd);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_reset (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* gcry_cipher_reset clears the IV */
+ err = gcry_cipher_setiv (hde, tv[i].iv, blklen);
+ if (!err)
+ err = gcry_cipher_setiv (hdd, tv[i].iv, blklen);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_setiv failed: %s\n",
+ gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+
+ /* this time we encrypt and decrypt one byte at a time */
+ for (j = 0; tv[i].data[j].inlen; j++)
+ {
+ int byteNum;
+ for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum)
+ {
+ err = gcry_cipher_encrypt (hde, out+byteNum, 1,
+ (tv[i].data[j].plaintext) + byteNum,
+ 1);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j);
+
+ for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum)
+ {
+ err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0);
+ if (err)
+ {
+ fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+ i, j, gpg_strerror (err));
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ return;
+ }
+ }
+
+ if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+ fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j);
+ }
+
+ gcry_cipher_close (hde);
+ gcry_cipher_close (hdd);
+ }
+}
+
static void
check_one_cipher (int algo, int mode, int flags)
{
gcry_cipher_hd_t hd;
- char key[32], plain[16], in[16], out[16];
+ char key[32];
+ unsigned char plain[16], in[16], out[16];
int keylen;
gcry_error_t err = 0;
memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32);
memcpy (plain, "foobar42FOOBAR17", 16);
keylen = gcry_cipher_get_algo_keylen (algo);
if (!keylen)
{
fail ("algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n",
algo, mode);
return;
}
if (keylen < 40 / 8 || keylen > 32)
{
fail ("algo %d, mode %d, keylength problem (%d)\n", algo, mode, keylen);
return;
}
err = gcry_cipher_open (&hd, algo, mode, flags);
if (err)
{
fail ("algo %d, mode %d, grcy_open_cipher failed: %s\n",
algo, mode, gpg_strerror (err));
return;
}
err = gcry_cipher_setkey (hd, key, keylen);
if (err)
{
fail ("algo %d, mode %d, gcry_cipher_setkey failed: %s\n",
algo, mode, gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
err = gcry_cipher_encrypt (hd, out, 16, plain, 16);
if (err)
{
fail ("algo %d, mode %d, gcry_cipher_encrypt failed: %s\n",
algo, mode, gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
gcry_cipher_reset (hd);
err = gcry_cipher_decrypt (hd, in, 16, out, 16);
if (err)
{
fail ("algo %d, mode %d, gcry_cipher_decrypt failed: %s\n",
algo, mode, gpg_strerror (err));
gcry_cipher_close (hd);
return;
}
gcry_cipher_close (hd);
if (memcmp (plain, in, 16))
fail ("algo %d, mode %d, encrypt-decrypt mismatch\n", algo, mode);
}
static void
check_ciphers (void)
{
static int algos[] = {
GCRY_CIPHER_3DES,
GCRY_CIPHER_CAST5,
GCRY_CIPHER_BLOWFISH,
GCRY_CIPHER_AES,
GCRY_CIPHER_AES192,
GCRY_CIPHER_AES256,
GCRY_CIPHER_TWOFISH,
GCRY_CIPHER_TWOFISH128,
GCRY_CIPHER_DES,
GCRY_CIPHER_SERPENT128,
GCRY_CIPHER_SERPENT192,
GCRY_CIPHER_SERPENT256,
0
};
static int algos2[] = {
GCRY_CIPHER_ARCFOUR,
0
};
int i;
for (i = 0; algos[i]; i++)
{
if (verbose)
fprintf (stderr, "checking `%s' [%i]\n",
gcry_cipher_algo_name (algos[i]),
gcry_cipher_map_name (gcry_cipher_algo_name (algos[i])));
check_one_cipher (algos[i], GCRY_CIPHER_MODE_ECB, 0);
check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB, 0);
+ check_one_cipher (algos[i], GCRY_CIPHER_MODE_OFB, 0);
check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0);
check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS);
check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0);
}
for (i = 0; algos2[i]; i++)
{
if (verbose)
fprintf (stderr, "checking `%s'\n",
gcry_cipher_algo_name (algos2[i]));
check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0);
}
/* we have now run all cipher's selftests */
/* TODO: add some extra encryption to test the higher level functions */
}
static void
check_one_md (int algo, char *data, int len, char *expect)
{
gcry_md_hd_t hd, hd2;
- char *p;
+ unsigned char *p;
int mdlen;
int i;
gcry_error_t err = 0;
err = gcry_md_open (&hd, algo, 0);
if (err)
{
fail ("algo %d, grcy_md_open failed: %s\n", algo, gpg_strerror (err));
return;
}
mdlen = gcry_md_get_algo_dlen (algo);
if (mdlen < 1 || mdlen > 500)
{
fail ("algo %d, grcy_md_get_algo_dlen failed: %d\n", algo, mdlen);
return;
}
if (*data == '!' && !data[1])
{ /* hash one million times a "a" */
char aaa[1000];
memset (aaa, 'a', 1000);
for (i = 0; i < 1000; i++)
gcry_md_write (hd, aaa, 1000);
}
else
gcry_md_write (hd, data, len);
err = gcry_md_copy (&hd2, hd);
if (err)
{
fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err));
}
gcry_md_close (hd);
p = gcry_md_read (hd2, algo);
if (memcmp (p, expect, mdlen))
{
printf ("computed: ");
for (i = 0; i < mdlen; i++)
printf ("%02x ", p[i] & 0xFF);
printf ("\nexpected: ");
for (i = 0; i < mdlen; i++)
printf ("%02x ", expect[i] & 0xFF);
printf ("\n");
fail ("algo %d, digest mismatch\n", algo);
}
gcry_md_close (hd2);
}
static void
check_digests (void)
{
static struct algos
{
int md;
char *data;
char *expect;
} algos[] =
{
{ GCRY_MD_MD4, "",
"\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" },
{ GCRY_MD_MD4, "a",
"\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb\x24" },
{ GCRY_MD_MD4, "message digest",
"\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01\x4b" },
{ GCRY_MD_MD5, "",
"\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E" },
{ GCRY_MD_MD5, "a",
"\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61" },
{ GCRY_MD_MD5, "abc",
"\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72" },
{ GCRY_MD_MD5, "message digest",
"\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0" },
{ GCRY_MD_SHA1, "abc",
"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
"\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" },
{ GCRY_MD_SHA1,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE"
"\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1" },
{ GCRY_MD_SHA1, "!" /* kludge for "a"*1000000 */ ,
"\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E"
"\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" },
{ GCRY_MD_SHA256, "abc",
"\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
"\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" },
{ GCRY_MD_SHA256,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
"\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
"\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
{ GCRY_MD_SHA256, "!",
"\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
"\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0" },
{ GCRY_MD_SHA384, "abc",
"\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07"
"\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed"
"\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7" },
{ GCRY_MD_SHA512, "abc",
"\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31"
"\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A"
"\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD"
"\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F" },
{ GCRY_MD_RMD160, "",
"\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28"
"\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" },
{ GCRY_MD_RMD160, "a",
"\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae"
"\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe" },
{ GCRY_MD_RMD160, "abc",
"\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04"
"\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc" },
{ GCRY_MD_RMD160, "message digest",
"\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8"
"\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" },
{ GCRY_MD_CRC32, "", "\x00\x00\x00\x00" },
{ GCRY_MD_CRC32, "foo", "\x8c\x73\x65\x21" },
{ GCRY_MD_CRC32_RFC1510, "", "\x00\x00\x00\x00" },
{ GCRY_MD_CRC32_RFC1510, "foo", "\x73\x32\xbc\x33" },
{ GCRY_MD_CRC32_RFC1510, "test0123456789", "\xb8\x3e\x88\xd6" },
{ GCRY_MD_CRC32_RFC1510, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY",
"\xe3\x41\x80\xf7" },
#if 0
{ GCRY_MD_CRC32_RFC1510, "\x80\x00", "\x3b\x83\x98\x4b" },
{ GCRY_MD_CRC32_RFC1510, "\x00\x08", "\x0e\xdb\x88\x32" },
{ GCRY_MD_CRC32_RFC1510, "\x00\x80", "\xed\xb8\x83\x20" },
#endif
{ GCRY_MD_CRC32_RFC1510, "\x80", "\xed\xb8\x83\x20" },
#if 0
{ GCRY_MD_CRC32_RFC1510, "\x80\x00\x00\x00", "\xed\x59\xb6\x3b" },
{ GCRY_MD_CRC32_RFC1510, "\x00\x00\x00\x01", "\x77\x07\x30\x96" },
#endif
{ GCRY_MD_CRC24_RFC2440, "", "\xb7\x04\xce" },
{ GCRY_MD_CRC24_RFC2440, "foo", "\x4f\xc2\x55" },
{ GCRY_MD_TIGER, "",
"\x24\xF0\x13\x0C\x63\xAC\x93\x32\x16\x16\x6E\x76"
"\xB1\xBB\x92\x5F\xF3\x73\xDE\x2D\x49\x58\x4E\x7A" },
{ GCRY_MD_TIGER, "abc",
"\xF2\x58\xC1\xE8\x84\x14\xAB\x2A\x52\x7A\xB5\x41"
"\xFF\xC5\xB8\xBF\x93\x5F\x7B\x95\x1C\x13\x29\x51" },
{ GCRY_MD_TIGER, "Tiger",
"\x9F\x00\xF5\x99\x07\x23\x00\xDD\x27\x6A\xBB\x38"
"\xC8\xEB\x6D\xEC\x37\x79\x0C\x11\x6F\x9D\x2B\xDF" },
{ GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg"
"hijklmnopqrstuvwxyz0123456789+-",
"\x87\xFB\x2A\x90\x83\x85\x1C\xF7\x47\x0D\x2C\xF8"
"\x10\xE6\xDF\x9E\xB5\x86\x44\x50\x34\xA5\xA3\x86" },
{ GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdef"
"ghijklmnopqrstuvwxyz+0123456789",
"\x46\x7D\xB8\x08\x63\xEB\xCE\x48\x8D\xF1\xCD\x12"
"\x61\x65\x5D\xE9\x57\x89\x65\x65\x97\x5F\x91\x97" },
#if 0
{ GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
"by Ross Anderson and Eli Biham",
"0C410A042968868A1671DA5A3FD29A725EC1E457D3CDB303" },
{ GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
"by Ross Anderson and Eli Biham, proceedings of Fa"
"st Software Encryption 3, Cambridge.",
"EBF591D5AFA655CE7F22894FF87F54AC89C811B6B0DA3193" },
{ GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, "
"by Ross Anderson and Eli Biham, proceedings of Fa"
"st Software Encryption 3, Cambridge, 1996.",
"3D9AEB03D1BD1A6357B2774DFD6D5B24DD68151D503974FC" },
{ GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh"
"ijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRS"
"TUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-",
"00B83EB4E53440C5 76AC6AAEE0A74858 25FD15E70A59FFE4" },
#endif
{ GCRY_MD_WHIRLPOOL, "",
"\x19\xFA\x61\xD7\x55\x22\xA4\x66\x9B\x44\xE3\x9C\x1D\x2E\x17\x26"
"\xC5\x30\x23\x21\x30\xD4\x07\xF8\x9A\xFE\xE0\x96\x49\x97\xF7\xA7"
"\x3E\x83\xBE\x69\x8B\x28\x8F\xEB\xCF\x88\xE3\xE0\x3C\x4F\x07\x57"
"\xEA\x89\x64\xE5\x9B\x63\xD9\x37\x08\xB1\x38\xCC\x42\xA6\x6E\xB3" },
{ GCRY_MD_WHIRLPOOL, "a",
"\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
"\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42"
"\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59"
"\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" },
{ GCRY_MD_WHIRLPOOL, "a",
"\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7"
"\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42"
"\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59"
"\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" },
{ GCRY_MD_WHIRLPOOL,
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B\xF1\x1F\x00\xED\x9A\xBA\x26\x90"
"\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E"
"\x08\xEB\xA2\x66\x29\x12\x9D\x8F\xB7\xCB\x57\x21\x1B\x92\x81\xA6"
"\x55\x17\xCC\x87\x9D\x7B\x96\x21\x42\xC6\x5F\x5A\x7A\xF0\x14\x67" },
{ GCRY_MD_WHIRLPOOL,
"!",
"\x0C\x99\x00\x5B\xEB\x57\xEF\xF5\x0A\x7C\xF0\x05\x56\x0D\xDF\x5D"
"\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5"
"\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD"
"\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" },
{ 0 },
};
int i;
for (i = 0; algos[i].md; i++)
{
if (verbose)
fprintf (stderr, "checking `%s'\n", gcry_md_algo_name (algos[i].md));
check_one_md (algos[i].md, algos[i].data, strlen (algos[i].data),
algos[i].expect);
}
/* TODO: test HMAC mode */
}
/* Check that the signature SIG matches the hash HASH. PKEY is the
public key used for the verification. BADHASH is a hasvalue which
should; result in a bad signature status. */
static void
verify_one_signature (gcry_sexp_t pkey, gcry_sexp_t hash,
gcry_sexp_t badhash, gcry_sexp_t sig)
{
gcry_error_t rc;
rc = gcry_pk_verify (sig, hash, pkey);
if (rc)
fail ("gcry_pk_verify failed: %s\n", gpg_strerror (rc));
rc = gcry_pk_verify (sig, badhash, pkey);
if (gcry_err_code (rc) != GPG_ERR_BAD_SIGNATURE)
fail ("gcry_pk_verify failed to detect a bad signature: %s\n",
gpg_strerror (rc));
}
/* Test the public key sign function using the private ket SKEY. PKEY
is used for verification. */
static void
check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey)
{
gcry_error_t rc;
gcry_sexp_t sig, badhash, hash;
int dataidx;
static const char baddata[] =
"(data\n (flags pkcs1)\n"
" (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n";
static struct
{
const char *data;
int expected_rc;
} datas[] =
{
{ "(data\n (flags pkcs1)\n"
" (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
0 },
{ "(data\n (flags )\n"
" (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n",
GPG_ERR_CONFLICT },
{ "(data\n (flags pkcs1)\n"
" (hash foo #11223344556677889900AABBCCDDEEFF10203040#))\n",
GPG_ERR_DIGEST_ALGO },
{ "(data\n (flags )\n" " (value #11223344556677889900AA#))\n",
0 },
{ "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n",
0 },
{ "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n",
0 },
{ "(data\n (flags pkcs1)\n"
" (value #11223344556677889900AA#))\n",
GPG_ERR_CONFLICT },
{ "(data\n (flags raw foo)\n"
" (value #11223344556677889900AA#))\n",
GPG_ERR_INV_FLAG },
{ NULL }
};
rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata));
if (rc)
die ("converting data failed: %s\n", gpg_strerror (rc));
for (dataidx = 0; datas[dataidx].data; dataidx++)
{
if (verbose)
fprintf (stderr, "signature test %d\n", dataidx);
rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data,
strlen (datas[dataidx].data));
if (rc)
die ("converting data failed: %s\n", gpg_strerror (rc));
rc = gcry_pk_sign (&sig, hash, skey);
if (gcry_err_code (rc) != datas[dataidx].expected_rc)
fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc));
if (!rc)
verify_one_signature (pkey, hash, badhash, sig);
gcry_sexp_release (sig);
sig = NULL;
gcry_sexp_release (hash);
hash = NULL;
}
gcry_sexp_release (badhash);
}
static void
check_pubkey_grip (int n, const unsigned char *grip,
gcry_sexp_t skey, gcry_sexp_t pkey)
{
unsigned char sgrip[20], pgrip[20];
if (!gcry_pk_get_keygrip (skey, sgrip))
die ("get keygrip for private RSA key failed\n");
if (!gcry_pk_get_keygrip (pkey, pgrip))
die ("[%i] get keygrip for public RSA key failed\n", n);
if (memcmp (sgrip, pgrip, 20))
fail ("[%i] keygrips don't match\n", n);
if (memcmp (sgrip, grip, 20))
fail ("wrong keygrip for RSA key\n");
}
static void
do_check_one_pubkey (int n, gcry_sexp_t skey, gcry_sexp_t pkey,
const unsigned char *grip, int flags)
{
if (flags & FLAG_SIGN)
check_pubkey_sign (n, skey, pkey);
if (grip && (flags & FLAG_GRIP))
check_pubkey_grip (n, grip, skey, pkey);
}
static void
check_one_pubkey (int n, test_spec_pubkey_t spec)
{
gcry_error_t err = GPG_ERR_NO_ERROR;
gcry_sexp_t skey, pkey;
err = gcry_sexp_sscan (&skey, NULL, spec.key.secret,
strlen (spec.key.secret));
if (!err)
err = gcry_sexp_sscan (&pkey, NULL, spec.key.public,
strlen (spec.key.public));
if (err)
die ("converting sample key failed: %s\n", gpg_strerror (err));
do_check_one_pubkey (n, skey, pkey, spec.key.grip, spec.flags);
gcry_sexp_release (skey);
gcry_sexp_release (pkey);
}
static void
get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
{
gcry_sexp_t key_spec, key, pub_key, sec_key;
int rc;
rc = gcry_sexp_new (&key_spec,
"(genkey (rsa (nbits 4:1024)))", 0, 1);
if (rc)
die ("error creating S-expression: %s\n", gpg_strerror (rc));
rc = gcry_pk_genkey (&key, key_spec);
gcry_sexp_release (key_spec);
if (rc)
die ("error generating RSA key: %s\n", gpg_strerror (rc));
pub_key = gcry_sexp_find_token (key, "public-key", 0);
if (! pub_key)
die ("public part missing in key\n");
sec_key = gcry_sexp_find_token (key, "private-key", 0);
if (! sec_key)
die ("private part missing in key\n");
gcry_sexp_release (key);
*pkey = pub_key;
*skey = sec_key;
}
static void
check_one_pubkey_new (int n)
{
gcry_sexp_t skey, pkey;
get_keys_new (&pkey, &skey);
do_check_one_pubkey (n, skey, pkey, NULL, FLAG_SIGN | FLAG_CRYPT);
}
/* Run all tests for the public key fucntions. */
static void
check_pubkey (void)
{
test_spec_pubkey_t pubkeys[] =
{
{
GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN,
{ "(private-key\n"
" (rsa\n"
" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
" (e #010001#)\n"
" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
" 7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
" C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
" C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
" fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
" 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
" ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))\n",
"(public-key\n"
" (rsa\n"
" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
" (e #010001#)))\n",
"\x32\x10\x0c\x27\x17\x3e\xf6\xe9\xc4\xe9"
"\xa2\x5d\x3d\x69\xf8\x6d\x37\xa4\xf9\x39"}
},
{
GCRY_PK_DSA, FLAG_SIGN,
{ "(private-key\n"
" (DSA\n"
" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)\n"
" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n"
" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)\n"
" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)\n"
" (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))\n",
"(public-key\n"
" (DSA\n"
" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)\n"
" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n"
" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)\n"
" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))\n",
"\xc6\x39\x83\x1a\x43\xe5\x05\x5d\xc6\xd8"
"\x4a\xa6\xf9\xeb\x23\xbf\xa9\x12\x2d\x5b" }
},
{
GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT,
{ "(private-key\n"
" (ELG\n"
" (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D"
" F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517"
" B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797"
" 6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2A7#)\n"
" (g #05#)\n"
" (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B"
" E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B"
" D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675"
" 56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4#)\n"
" (x #03C28900087B38DABF4A0AB98ACEA39BB674D6557096C01D72E31C16BDD32214#)))\n",
"(public-key\n"
" (ELG\n"
" (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D"
" F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517"
" B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797"
" 6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2A7#)\n"
" (g #05#)\n"
" (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B"
" E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B"
" D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675"
" 56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4#)))\n",
"\xa7\x99\x61\xeb\x88\x83\xd2\xf4\x05\xc8"
"\x4f\xba\x06\xf8\x78\x09\xbc\x1e\x20\xe5" }
},
};
int i;
for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++)
if (pubkeys[i].id)
check_one_pubkey (i, pubkeys[i]);
check_one_pubkey_new (i);
}
int
main (int argc, char **argv)
{
int debug = 0;
if (argc > 1 && !strcmp (argv[1], "--verbose"))
verbose = 1;
else if (argc > 1 && !strcmp (argv[1], "--debug"))
verbose = debug = 1;
if (!gcry_check_version (GCRYPT_VERSION))
die ("version mismatch\n");
gcry_set_progress_handler (progress_handler, NULL);
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
if (debug)
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
check_ciphers ();
check_aes128_cbc_cts_cipher ();
check_cbc_mac_cipher ();
check_ctr_cipher ();
+ check_cfb_cipher ();
+ check_ofb_cipher ();
check_digests ();
check_pubkey ();
return error_count ? 1 : 0;
}
diff --git a/tests/benchmark.c b/tests/benchmark.c
index 04cfedc9..1d82c5d8 100644
--- a/tests/benchmark.c
+++ b/tests/benchmark.c
@@ -1,732 +1,733 @@
/* benchmark.c - for libgcrypt
* Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser general Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/times.h>
#include <gcrypt.h>
#define PGM "benchmark"
static const char sample_private_dsa_key_1024[] =
"(private-key\n"
" (dsa\n"
" (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685"
"03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A"
"853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF"
"C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n"
" (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n"
" (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622"
"B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312"
"FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3"
"85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n"
" (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4"
"ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6"
"66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155"
"D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n"
" (x #4186F8A58C5DF46C5BCFC7006BEEBF05E93C0CA7#)\n"
"))\n";
static const char sample_public_dsa_key_1024[] =
"(public-key\n"
" (dsa\n"
" (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685"
"03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A"
"853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF"
"C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n"
" (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n"
" (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622"
"B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312"
"FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3"
"85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n"
" (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4"
"ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6"
"66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155"
"D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n"
"))\n";
static const char sample_private_dsa_key_2048[] =
"(private-key\n"
" (dsa\n"
" (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365"
"A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C"
"308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150"
"C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970"
"71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405"
"D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179"
"0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4"
"2F9C9F315ED409171EC35CA04CC06B275577B3#)\n"
" (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n"
" (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78"
"98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3"
"5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F"
"B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508"
"4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F"
"0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44"
"2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3"
"6EE4425A553AF8885FEA15A88135BE133520#)\n"
" (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C"
"2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB"
"4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79"
"328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F"
"8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3"
"E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923"
"79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7"
"14A264330AECCB24DE2A1107847B23490897#)\n"
" (x #477BD14676E22563C5ABA68025CEBA2A48D485F5B2D4AD4C0EBBD6D0#)\n"
"))\n";
static const char sample_public_dsa_key_2048[] =
"(public-key\n"
" (dsa\n"
" (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365"
"A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C"
"308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150"
"C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970"
"71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405"
"D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179"
"0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4"
"2F9C9F315ED409171EC35CA04CC06B275577B3#)\n"
" (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n"
" (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78"
"98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3"
"5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F"
"B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508"
"4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F"
"0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44"
"2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3"
"6EE4425A553AF8885FEA15A88135BE133520#)\n"
" (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C"
"2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB"
"4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79"
"328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F"
"8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3"
"E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923"
"79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7"
"14A264330AECCB24DE2A1107847B23490897#)\n"
"))\n";
static const char sample_private_dsa_key_3072[] =
"(private-key\n"
" (dsa\n"
" (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938"
"877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5"
"62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83"
"B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988"
"AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46"
"0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2"
"AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902"
"D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60"
"B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E"
"95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7"
"62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33"
"8015353D3778B02B892AF7#)\n"
" (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n"
" (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4"
"DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474"
"7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98"
"9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC"
"134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C"
"7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89"
"F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB"
"120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6"
"374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0"
"21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F"
"D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC"
"4997AF9EB55C6660B01A#)\n"
" (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE"
"4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053"
"A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492"
"8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15"
"DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71"
"CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997"
"437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026"
"73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B"
"FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD"
"F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765"
"3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561"
"2703D518D8D49FF0EBE6#)\n"
" (x #00A9FFFC88E67D6F7B810E291C050BAFEA7FC4A75E8D2F16CFED3416FD77607232#)\n"
"))\n";
static const char sample_public_dsa_key_3072[] =
"(public-key\n"
" (dsa\n"
" (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938"
"877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5"
"62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83"
"B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988"
"AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46"
"0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2"
"AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902"
"D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60"
"B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E"
"95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7"
"62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33"
"8015353D3778B02B892AF7#)\n"
" (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n"
" (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4"
"DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474"
"7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98"
"9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC"
"134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C"
"7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89"
"F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB"
"120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6"
"374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0"
"21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F"
"D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC"
"4997AF9EB55C6660B01A#)\n"
" (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE"
"4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053"
"A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492"
"8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15"
"DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71"
"CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997"
"437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026"
"73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B"
"FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD"
"F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765"
"3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561"
"2703D518D8D49FF0EBE6#)\n"
"))\n";
#define DIM(v) (sizeof(v)/sizeof((v)[0]))
#define DIMof(type,member) DIM(((type *)0)->member)
#define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\
exit(2);} while(0)
/* Helper for the start and stop timer. */
static clock_t started_at, stopped_at;
static void
start_timer (void)
{
struct tms tmp;
times (&tmp);
started_at = stopped_at = tmp.tms_utime;
}
static void
stop_timer (void)
{
struct tms tmp;
times (&tmp);
stopped_at = tmp.tms_utime;
}
static const char *
elapsed_time (void)
{
static char buf[50];
sprintf (buf, "%5.0fms",
(((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000);
return buf;
}
static void
random_bench (void)
{
char buf[128];
int i;
printf ("%-10s", "random");
start_timer ();
for (i=0; i < 100; i++)
gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
stop_timer ();
printf (" %s", elapsed_time ());
start_timer ();
for (i=0; i < 100; i++)
gcry_randomize (buf, 8, GCRY_STRONG_RANDOM);
stop_timer ();
printf (" %s", elapsed_time ());
putchar ('\n');
}
static void
md_bench ( const char *algoname )
{
int algo;
gcry_md_hd_t hd;
int i;
char buf[1000];
gcry_error_t err = GPG_ERR_NO_ERROR;
if (!algoname)
{
for (i=1; i < 400; i++)
if ( !gcry_md_test_algo (i) )
md_bench (gcry_md_algo_name (i));
return;
}
algo = gcry_md_map_name (algoname);
if (!algo)
{
fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname);
exit (1);
}
err = gcry_md_open (&hd, algo, 0);
if (err)
{
fprintf (stderr, PGM ": error opening hash algorithm `%s'\n", algoname);
exit (1);
}
for (i=0; i < sizeof buf; i++)
buf[i] = i;
printf ("%-12s", gcry_md_algo_name (algo));
start_timer ();
for (i=0; i < 1000; i++)
gcry_md_write (hd, buf, sizeof buf);
gcry_md_final (hd);
stop_timer ();
printf (" %s", elapsed_time ());
gcry_md_reset (hd);
start_timer ();
for (i=0; i < 10000; i++)
gcry_md_write (hd, buf, sizeof buf/10);
gcry_md_final (hd);
stop_timer ();
printf (" %s", elapsed_time ());
gcry_md_reset (hd);
start_timer ();
for (i=0; i < 1000000; i++)
gcry_md_write (hd, "", 1);
gcry_md_final (hd);
stop_timer ();
printf (" %s", elapsed_time ());
gcry_md_close (hd);
putchar ('\n');
}
static void
cipher_bench ( const char *algoname )
{
static int header_printed;
int algo;
gcry_cipher_hd_t hd;
int i;
int keylen, blklen;
char key[128];
char outbuf[1000], buf[1000];
size_t buflen;
static struct { int mode; const char *name; int blocked; } modes[] = {
{ GCRY_CIPHER_MODE_ECB, "ECB", 1 },
{ GCRY_CIPHER_MODE_CBC, "CBC", 1 },
{ GCRY_CIPHER_MODE_CFB, "CFB", 0 },
+ { GCRY_CIPHER_MODE_OFB, "OFB", 0 },
{ GCRY_CIPHER_MODE_CTR, "CTR", 0 },
{ GCRY_CIPHER_MODE_STREAM, "STREAM", 0 },
{0}
};
int modeidx;
gcry_error_t err = GPG_ERR_NO_ERROR;
if (!algoname)
{
for (i=1; i < 400; i++)
if ( !gcry_cipher_test_algo (i) )
cipher_bench (gcry_cipher_algo_name (i));
return;
}
if (!header_printed)
{
printf ("%-10s", "");
for (modeidx=0; modes[modeidx].mode; modeidx++)
printf (" %-15s", modes[modeidx].name );
putchar ('\n');
printf ("%-10s", "");
for (modeidx=0; modes[modeidx].mode; modeidx++)
printf (" ---------------" );
putchar ('\n');
header_printed = 1;
}
algo = gcry_cipher_map_name (algoname);
if (!algo)
{
fprintf (stderr, PGM ": invalid cipher algorithm `%s'\n", algoname);
exit (1);
}
keylen = gcry_cipher_get_algo_keylen (algo);
if (!keylen)
{
fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
algoname);
exit (1);
}
if ( keylen > sizeof key )
{
fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n",
algo, keylen );
exit (1);
}
for (i=0; i < keylen; i++)
key[i] = i + (clock () & 0xff);
blklen = gcry_cipher_get_algo_blklen (algo);
if (!blklen)
{
fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n",
algoname);
exit (1);
}
printf ("%-10s", gcry_cipher_algo_name (algo));
fflush (stdout);
for (modeidx=0; modes[modeidx].mode; modeidx++)
{
if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM)
| (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM))
{
printf (" " );
continue;
}
for (i=0; i < sizeof buf; i++)
buf[i] = i;
err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
if (err)
{
fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname);
exit (1);
}
err = gcry_cipher_setkey (hd, key, keylen);
if (err)
{
fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
gpg_strerror (err));
gcry_cipher_close (hd);
exit (1);
}
buflen = sizeof buf;
if (modes[modeidx].blocked)
buflen = (buflen / blklen) * blklen;
start_timer ();
for (i=err=0; !err && i < 1000; i++)
err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen);
stop_timer ();
printf (" %s", elapsed_time ());
fflush (stdout);
gcry_cipher_close (hd);
if (err)
{
fprintf (stderr, "gcry_cipher_encrypt failed: %s\n",
gpg_strerror (err) );
exit (1);
}
err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0);
if (err)
{
fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname);
exit (1);
}
err = gcry_cipher_setkey (hd, key, keylen);
if (err)
{
fprintf (stderr, "gcry_cipher_setkey failed: %s\n",
gpg_strerror (err));
gcry_cipher_close (hd);
exit (1);
}
start_timer ();
for (i=err=0; !err && i < 1000; i++)
err = gcry_cipher_decrypt ( hd, outbuf, buflen, buf, buflen);
stop_timer ();
printf (" %s", elapsed_time ());
fflush (stdout);
gcry_cipher_close (hd);
if (err)
{
fprintf (stderr, "gcry_cipher_decrypt failed: %s\n",
gpg_strerror (err) );
exit (1);
}
}
putchar ('\n');
}
static void
dsa_bench (void)
{
gpg_error_t err;
gcry_sexp_t pub_key[3], sec_key[3];
int p_sizes[3] = { 1024, 2048, 3072 };
int q_sizes[3] = { 160, 224, 256 };
gcry_sexp_t data;
gcry_sexp_t sig;
int i, j;
err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024,
strlen (sample_public_dsa_key_1024));
if (!err)
err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_dsa_key_1024,
strlen (sample_private_dsa_key_1024));
if (!err)
err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_dsa_key_2048,
strlen (sample_public_dsa_key_2048));
if (!err)
err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_dsa_key_2048,
strlen (sample_private_dsa_key_2048));
if (!err)
err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_dsa_key_3072,
strlen (sample_public_dsa_key_3072));
if (!err)
err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_dsa_key_3072,
strlen (sample_private_dsa_key_3072));
if (err)
{
fprintf (stderr, PGM ": converting sample keys failed: %s\n",
gcry_strerror (err));
exit (1);
}
fputs ("DSA 100 times sign verify\n"
"-----------------------------\n", stdout);
for (i=0; i < DIM (q_sizes); i++)
{
gcry_mpi_t x;
x = gcry_mpi_new (q_sizes[i]);
gcry_mpi_randomize (x, q_sizes[i], GCRY_WEAK_RANDOM);
err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
gcry_mpi_release (x);
if (err)
{
fprintf (stderr, PGM ": converting data failed: %s\n",
gcry_strerror (err));
exit (1);
}
printf ("DSA %d/%d ", p_sizes[i], q_sizes[i]);
start_timer ();
for (j=0; j < 100; j++)
{
err = gcry_pk_sign (&sig, data, sec_key[i]);
if (err)
{
putchar ('\n');
fprintf (stderr, PGM ": signing failed: %s\n",
gpg_strerror (err));
exit (1);
}
}
stop_timer ();
printf (" %s", elapsed_time ());
start_timer ();
for (j=0; j < 100; j++)
{
err = gcry_pk_verify (sig, data, pub_key[i]);
if (err)
{
putchar ('\n');
fprintf (stderr, PGM ": verify failed: %s\n",
gpg_strerror (err));
exit (1);
}
}
stop_timer ();
printf (" %s\n", elapsed_time ());
gcry_sexp_release (sig);
gcry_sexp_release (data);
}
for (i=0; i < DIM (q_sizes); i++)
{
gcry_sexp_release (sec_key[i]);
gcry_sexp_release (pub_key[i]);
}
}
static void
do_powm ( const char *n_str, const char *e_str, const char *m_str)
{
gcry_mpi_t e, n, msg, cip;
gcry_error_t err;
int i;
err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, n_str, 0, 0);
if (err) BUG ();
err = gcry_mpi_scan (&e, GCRYMPI_FMT_HEX, e_str, 0, 0);
if (err) BUG ();
err = gcry_mpi_scan (&msg, GCRYMPI_FMT_HEX, m_str, 0, 0);
if (err) BUG ();
cip = gcry_mpi_new (0);
start_timer ();
for (i=0; i < 1000; i++)
gcry_mpi_powm (cip, msg, e, n);
stop_timer ();
printf (" %s", elapsed_time ()); fflush (stdout);
/* { */
/* char *buf; */
/* if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */
/* BUG (); */
/* printf ("result: %s\n", buf); */
/* gcry_free (buf); */
/* } */
gcry_mpi_release (cip);
gcry_mpi_release (msg);
gcry_mpi_release (n);
gcry_mpi_release (e);
}
static void
mpi_bench (void)
{
printf ("%-10s", "powm"); fflush (stdout);
do_powm (
"20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E4",
"29",
"B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8"
);
do_powm (
"20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
"29",
"B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847"
);
do_powm (
"20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA4071620A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716",
"29",
"B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847"
);
putchar ('\n');
}
int
main( int argc, char **argv )
{
if (argc)
{ argc--; argv++; }
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
if (!gcry_check_version (GCRYPT_VERSION))
{
fprintf (stderr, PGM ": version mismatch\n");
exit (1);
}
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
if ( !argc )
{
md_bench (NULL);
putchar ('\n');
cipher_bench (NULL);
putchar ('\n');
mpi_bench ();
putchar ('\n');
random_bench ();
}
else if ( !strcmp (*argv, "--help"))
fputs ("usage: benchmark [md|cipher|random|mpi|dsa [algonames]]\n",
stdout);
else if ( !strcmp (*argv, "random"))
{
random_bench ();
}
else if ( !strcmp (*argv, "md"))
{
if (argc == 1)
md_bench (NULL);
else
for (argc--, argv++; argc; argc--, argv++)
md_bench ( *argv );
}
else if ( !strcmp (*argv, "cipher"))
{
if (argc == 1)
cipher_bench (NULL);
else
for (argc--, argv++; argc; argc--, argv++)
cipher_bench ( *argv );
}
else if ( !strcmp (*argv, "mpi"))
{
mpi_bench ();
}
else if ( !strcmp (*argv, "dsa"))
{
dsa_bench ();
}
else
{
fprintf (stderr, PGM ": bad arguments\n");
return 1;
}
return 0;
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Jul 17, 12:36 AM (1 d, 7 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
97/5a/deab5b3e0c37f7ddb3d3c20e6106

Event Timeline