diff options
author | Werner Koch <wk@gnupg.org> | 2000-10-04 11:16:18 +0000 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2000-10-04 11:16:18 +0000 |
commit | 03998985fc9c3375a52a0e7c336da5bee951310f (patch) | |
tree | d63f3f0431f1f84ba0fd49c3c8c650fd29016f56 | |
parent | c6b6080aabd9cbaf5dbc77e9d23536a7c2de37ed (diff) | |
download | libgcrypt-03998985fc9c3375a52a0e7c336da5bee951310f.tar.gz |
See ChangeLog: Wed Oct 4 13:16:18 CEST 2000 Werner Koch
-rw-r--r-- | cipher/ChangeLog | 14 | ||||
-rw-r--r-- | cipher/Makefile.am | 1 | ||||
-rw-r--r-- | cipher/cipher.c | 50 | ||||
-rw-r--r-- | cipher/md.c | 19 | ||||
-rw-r--r-- | cipher/random.h | 2 | ||||
-rw-r--r-- | cipher/rsa.c | 5 | ||||
-rw-r--r-- | cipher/sha1.c | 2 | ||||
-rw-r--r-- | doc/digest-ref.sgml | 7 | ||||
-rw-r--r-- | doc/misc-ref.sgml | 289 | ||||
-rw-r--r-- | src/ChangeLog | 4 | ||||
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/gcrypt.h | 7 | ||||
-rw-r--r-- | src/global.c | 4 |
13 files changed, 368 insertions, 42 deletions
diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 2e4ebe53..1d793ec3 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,17 @@ +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. diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 26de9252..6feea156 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -36,6 +36,7 @@ libcipher_la_SOURCES = cipher.c \ bithelp.h \ des.c \ des.h \ + rijndael.c \ twofish.c \ blowfish.c \ blowfish.h \ diff --git a/cipher/cipher.c b/cipher/cipher.c index 7808d876..d36db665 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -33,7 +33,7 @@ #include "dynload.h" #define MAX_BLOCKSIZE 16 -#define TABLE_SIZE 10 +#define TABLE_SIZE 12 #define CTX_MAGIC_NORMAL 0x24091964 #define CTX_MAGIC_SECURE 0x46919042 @@ -82,11 +82,43 @@ dummy_decrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); } static void setup_cipher_table(void) { - int i; i = 0; - cipher_table[i].algo = CIPHER_ALGO_TWOFISH; + cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL; + cipher_table[i].name = rijndael_get_info( cipher_table[i].algo, + &cipher_table[i].keylen, + &cipher_table[i].blocksize, + &cipher_table[i].contextsize, + &cipher_table[i].setkey, + &cipher_table[i].encrypt, + &cipher_table[i].decrypt ); + if( !cipher_table[i].name ) + BUG(); + i++; + cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL192; + cipher_table[i].name = rijndael_get_info( cipher_table[i].algo, + &cipher_table[i].keylen, + &cipher_table[i].blocksize, + &cipher_table[i].contextsize, + &cipher_table[i].setkey, + &cipher_table[i].encrypt, + &cipher_table[i].decrypt ); + if( !cipher_table[i].name ) + BUG(); + i++; + cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL256; + cipher_table[i].name = rijndael_get_info( cipher_table[i].algo, + &cipher_table[i].keylen, + &cipher_table[i].blocksize, + &cipher_table[i].contextsize, + &cipher_table[i].setkey, + &cipher_table[i].encrypt, + &cipher_table[i].decrypt ); + if( !cipher_table[i].name ) + BUG(); + i++; + cipher_table[i].algo = GCRY_CIPHER_TWOFISH; cipher_table[i].name = twofish_get_info( cipher_table[i].algo, &cipher_table[i].keylen, &cipher_table[i].blocksize, @@ -97,7 +129,7 @@ setup_cipher_table(void) if( !cipher_table[i].name ) BUG(); i++; - cipher_table[i].algo = CIPHER_ALGO_BLOWFISH; + cipher_table[i].algo = GCRY_CIPHER_BLOWFISH; cipher_table[i].name = blowfish_get_info( cipher_table[i].algo, &cipher_table[i].keylen, &cipher_table[i].blocksize, @@ -108,7 +140,7 @@ setup_cipher_table(void) if( !cipher_table[i].name ) BUG(); i++; - cipher_table[i].algo = CIPHER_ALGO_CAST5; + cipher_table[i].algo = GCRY_CIPHER_CAST5; cipher_table[i].name = cast5_get_info( cipher_table[i].algo, &cipher_table[i].keylen, &cipher_table[i].blocksize, @@ -119,7 +151,7 @@ setup_cipher_table(void) if( !cipher_table[i].name ) BUG(); i++; - cipher_table[i].algo = CIPHER_ALGO_3DES; + cipher_table[i].algo = GCRY_CIPHER_3DES; cipher_table[i].name = des_get_info( cipher_table[i].algo, &cipher_table[i].keylen, &cipher_table[i].blocksize, @@ -455,7 +487,7 @@ do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo unsigned n; for(n=0; n < nblocks; n++ ) { - (*c->encrypt)( &c->context.c, outbuf, inbuf ); + (*c->encrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf ); inbuf += c->blocksize; outbuf += c->blocksize; } @@ -467,7 +499,7 @@ do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo unsigned n; for(n=0; n < nblocks; n++ ) { - (*c->decrypt)( &c->context.c, outbuf, inbuf ); + (*c->decrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf ); inbuf += c->blocksize; outbuf += c->blocksize; } @@ -507,7 +539,7 @@ do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo * to save the original ciphertext block. We use lastiv * for this here because it is not used otherwise */ memcpy(c->lastiv, inbuf, blocksize ); - (*c->decrypt)( &c->context.c, outbuf, inbuf ); + (*c->decrypt)( &c->context.c, outbuf, (char*)/*argggg*/inbuf ); for(ivp=c->iv,i=0; i < blocksize; i++ ) outbuf[i] ^= *ivp++; memcpy(c->iv, c->lastiv, blocksize ); diff --git a/cipher/md.c b/cipher/md.c index e8ac8ac2..29d6afed 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -557,10 +557,7 @@ gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen) if( cmd == GCRYCTL_FINALIZE ) md_final( hd ); else if( cmd == GCRYCTL_SET_KEY ) { - if( !(hd->ctx->macpads ) ) - rc = GCRYERR_CONFLICT; - else if ( !(rc = prepare_macpads( hd, buffer, buflen )) ) - gcry_md_reset( hd ); + rc = gcry_md_setkey ( hd, buffer, buflen ); } else if( cmd == GCRYCTL_START_DUMP ) { md_start_debug( hd, buffer ); @@ -574,6 +571,20 @@ gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen) } +int +gcry_md_setkey( GCRY_MD_HD hd, const char *key, size_t keylen ) +{ + int rc = 0; + + if( !(hd->ctx->macpads ) ) + rc = GCRYERR_CONFLICT; + else if ( !(rc = prepare_macpads( hd, key, keylen )) ) + gcry_md_reset( hd ); + + return rc; +} + + /**************** * if ALGO is null get the digest for the used algo (which should be only one) */ diff --git a/cipher/random.h b/cipher/random.h index 9a7dd8f6..d96cea7f 100644 --- a/cipher/random.h +++ b/cipher/random.h @@ -27,6 +27,8 @@ void random_dump_stats(void); void secure_random_alloc(void); int quick_random_gen( int onoff ); int random_is_faked(void); +void secure_random_alloc(void); +void random_dump_stats(void); byte *get_random_bits( size_t nbits, int level, int secure ); void fast_random_poll( void ); diff --git a/cipher/rsa.c b/cipher/rsa.c index 2bb45100..f342e3c3 100644 --- a/cipher/rsa.c +++ b/cipher/rsa.c @@ -67,10 +67,7 @@ test_keys( RSA_secret_key *sk, unsigned nbits ) pk.n = sk->n; pk.e = sk->e; - { char *p = get_random_bits( nbits, 0, 0 ); - mpi_set_buffer( test, p, (nbits+7)/8, 0 ); - g10_free(p); - } + gcry_mpi_randomize( test, nbits, GCRY_WEAK_RANDOM ); public( out1, test, &pk ); secret( out2, out1, sk ); diff --git a/cipher/sha1.c b/cipher/sha1.c index aa3ac092..a0438dbd 100644 --- a/cipher/sha1.c +++ b/cipher/sha1.c @@ -108,7 +108,7 @@ transform( SHA1_CONTEXT *hd, byte *data ) #define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] \ ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \ - , (x[i&0x0f] = (tm << 1) | (tm >> 31)) ) + , (x[i&0x0f] = rol(tm, 1)) ) #define R(a,b,c,d,e,f,k,m) do { e += rol( a, 5 ) \ + f( b, c, d ) \ diff --git a/doc/digest-ref.sgml b/doc/digest-ref.sgml index a123c9b2..3b4dcd7e 100644 --- a/doc/digest-ref.sgml +++ b/doc/digest-ref.sgml @@ -68,7 +68,8 @@ specified. It is possible to use these functions as MAC functons; therefore the flag <literal/GCRY_MD_FLAG_HMAC/ must be given along with the hash functions. Other MAC algorithms than HMAC are currently not - supported. The key for the MAC must be set using the gcry_md_setkey macro. + supported. The key for the MAC must be set using + the <function>gcry_md_setkey</> function. <function>gcry_md_close</function> releases all resources associated with the context. <function>gcry_md_enable</function> may be used to enable hash @@ -194,6 +195,7 @@ hash functions into MAC functions. The key may be any string of the speicified length. The type of the MAC is determined by special flags set with the open function. + NEW: There is now a function to do this </para> </refentry> @@ -479,3 +481,6 @@ </para> </refentry> + +<!-- FIXME: doc gcry_md_setkey */ + diff --git a/doc/misc-ref.sgml b/doc/misc-ref.sgml index 31032d64..8b93ee79 100644 --- a/doc/misc-ref.sgml +++ b/doc/misc-ref.sgml @@ -18,28 +18,238 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA --> -<!-- -const char *gcry_check_version( const char *req_version ); +<refentry> + <refnamediv> + <refname>gcry_check_version</refname> + <refpurpose>get or check the version of libgcrypt</refpurpose> + </refnamediv> -int gcry_errno(void); -const char *gcry_strerror( int ec ); -int gcry_control( enum gcry_ctl_cmds, ... ); + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo> + #include <gcrypt.h> + </funcsynopsisinfo> + <funcprototype> + <funcdef>const char *<function>gcry_check_version</function></funcdef> + <paramdef>const char *<parameter>req_version</parameter></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1><title>Description</title> + <para> + <indexterm><primary>gcry_check_version</primary> + </indexterm> + <function>gcry_check_version</function> checks +that the version of the library is at minimum the requested one +and return the version string; NULL is returned if the condition is +not met. You may pass NULL as reqy_version to simply get the version +string back without any checking. + </para> +</refentry> + +<refentry> + <refnamediv> + <refname>gcry_errno</refname> + <refname>gcry_strerror</refname> + <refpurpose>Get the last error</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo> + #include <gcrypt.h> + </funcsynopsisinfo> + <funcprototype> + <funcdef>int <function>gcry_errno</function></funcdef> + </funcprototype> + <funcprototype> + <funcdef>const char *<function>gcry_strerror</function></funcdef> + <paramdef>int<parameter>no</parameter></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1><title>Description</title> + <para> + <indexterm><primary>gcry_errno</primary></indexterm> + <indexterm><primary>gcry_strerror</primary></indexterm> + Both function are to be used like there Standard-C + counterparts. However <function>gcry_errno</function> is a function + and not just a global variable. If -1 is passed to + <function>gcry_strerror</>, <function>gcry_errno</> is implictly used. + </para> +</refentry> + + +<refentry> + <refnamediv> + <refname>gcry_control</refname> + <refpurpose>Multi purpose control function</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo> + #include <gcrypt.h> + </funcsynopsisinfo> + <funcprototype> + <funcdef>int <function>gcry_control</function></funcdef> + <paramdef>enum gcry_ctl_cmds<parameter>cmd</parameter></paramdef> + <paramdef><parameter>...</parameter></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1><title>Description</title> + <para> + <indexterm><primary>gcry_control</primary></indexterm> + This function is used to control various aspects of &libgcrypt; + FIXME: Explain all commands here. + </para> +</refentry> + + + + + +<refentry> + <refnamediv> + <refname>gcry_set_allocation_handler</refname> + <refname>gcry_set_outofcore_handler</refname> + <refpurpose>Use application defined malloc functions</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo> + #include <gcrypt.h> + </funcsynopsisinfo> + <funcprototype> + <funcdef>void <function>gcry_set_allocation_handler</></funcdef> + <paramdef>void *(*<parameter>alloc_func</>)(size_t n)</paramdef> + <paramdef>void *(*<parameter>alloc_secure_func</>)(size_t n)</paramdef> + <paramdef>int (*<parameter>is_secure_func</>)(const void *p)</paramdef> + <paramdef>void *(*<parameter>realloc_func</>)(void *p, size_t n)</paramdef> + <paramdef>void (*<parameter>free_func</>)(void *p)</paramdef> + </funcprototype> + <funcprototype> + <funcdef>void <function>gcry_set_outofcore_handler</></funcdef> + + <paramdef>int (*<parameter>h</>)( void*, size_t, unsigned int ), + void *opaque )</paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1><title>Description</title> + <para> + <indexterm><primary>gcry_set_allocation_handler</primary></indexterm> + <indexterm><primary>gcry_set_outofcore_handler</primary></indexterm> + + FIXME + </para> +</refentry> + + +<refentry> + <refnamediv> + <refname>gcry_set_fatalerror_handler</refname> + <refpurpose>change the default fatal error handler</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo> + #include <gcrypt.h> + </funcsynopsisinfo> + <funcprototype> + <funcdef>void <function>gcry_set_fatalerror_handler</></funcdef> + <paramdef>void (*<parameter>func</>)( + void *, int, const char*)</paramdef> + <paramdef>void *<parameter>opaque</></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1><title>Description</title> + <para> + <indexterm><primary>gcry_set_fatalerror_handler</primary></indexterm> + At certain places the &libgcrypt; may need to call a fatal error fucntion + which does terminate the process. To allow an application to do + some emergency cleanup, it may register a fatal error handler with + the library. This handler is assumed to terminate the application; + however if it returns &libgcrypt; will abort anyway. + </para> + <para> +The handler is called with the opaque value registered here, an +errorcode from &libgcrypt; and some descriptive text string. + </para> +</refentry> + + +<refentry> + <refnamediv> + <refname>gcry_set_gettext_handler</refname> + <refpurpose>Change the default gettext function</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo> + #include <gcrypt.h> + </funcsynopsisinfo> + <funcprototype> + <funcdef>void <function>gcry_set_gettext_handler</></funcdef> + <paramdef>const char *(*<parameter>func</>)(const char*)</paramdef> + <paramdef>void *<parameter>opaque</></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1><title>Description</title> + <para> + <indexterm><primary>gcry_set_log_handler</primary></indexterm> + FIXME!! + </para> +</refentry> -void gcry_set_allocation_handler( void *(*new_alloc_func)(size_t n), - void *(*new_alloc_secure_func)(size_t n), - int (*new_is_secure_func)(const void*), - void *(*new_realloc_func)(void *p, size_t n), - void (*new_free_func)(void*) ); -void gcry_set_outofcore_handler( int (*h)( void*, size_t, unsigned int ), - void *opaque ); -void gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), - void *opaque ); -void gcry_set_gettext_handler( const char *(*f)(const char*) ); void gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ), void *opaque ); +<refentry> + <refnamediv> + <refname>gcry_set_log_handler</refname> + <refpurpose>Change the default logging function</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo> + #include <gcrypt.h> + </funcsynopsisinfo> + <funcprototype> + <funcdef>void <function>gcry_set_log_handler</></funcdef> + <paramdef>void (*<parameter>func</>) + (void*, int, const char*, va_list)</paramdef> + <paramdef>void *<parameter>opaque</></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1><title>Description</title> + <para> + <indexterm><primary>gcry_set_log_handler</primary></indexterm> + &libgcrypt; has it;s own logging functions. Applications which + need to use their own, should provide a log function to &libgcrypt; +so that it will use this function instead. + +Fixme: Describe how this is intended to work. + </para> +</refentry> + void *gcry_malloc( size_t n ); void *gcry_calloc( size_t n, size_t m ); @@ -55,6 +265,53 @@ char *gcry_xstrdup( const char * a); void gcry_free( void *a ); int gcry_is_secure( const void *a ); +<refentry> + <refnamediv> + <refname>gcry_malloc</refname> + <refname>gcry_calloc</refname> + <refname>gcry_malloc_secure</refname> + <refname>gcry_calloc_secure</refname> + <refname>gcry_realloc</refname> + <refname>gcry_xmalloc</refname> + <refname>gcry_xcalloc</refname> + <refname>gcry_xmalloc_secure</refname> + <refname>gcry_xcalloc_secure</refname> + <refname>gcry_xrealloc</refname> + <refname>gcry_xstrdup</refname> + + WORk WORK + <refname>gcry_malloc</refname> + <refname>gcry_malloc</refname> + + <refpurpose>Change the default logging function</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <funcsynopsis> + <funcsynopsisinfo> + #include <gcrypt.h> + </funcsynopsisinfo> + <funcprototype> + <funcdef>void <function>gcry_set_log_handler</></funcdef> + <paramdef>void (*<parameter>func</>) + (void*, int, const char*, va_list)</paramdef> + <paramdef>void *<parameter>opaque</></paramdef> + </funcprototype> + </funcsynopsis> + </refsynopsisdiv> + + <refsect1><title>Description</title> + <para> + <indexterm><primary>gcry_set_log_handler</primary></indexterm> + &libgcrypt; has it;s own logging functions. Applications which + need to use their own, should provide a log function to &libgcrypt; +so that it will use this function instead. + +Fixme: Describe how this is intended to work. + </para> +</refentry> + + void gcry_randomize( byte *buffer, size_t length, enum gcry_random_level level ); @@ -65,3 +322,5 @@ void *gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level ); --> + + diff --git a/src/ChangeLog b/src/ChangeLog index 01798140..fd384644 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,7 @@ +Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de> + + * gcrypt.h (gcry_md_setkey): Replaced macro by function prototype. + Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de> * gcrypt.h (GCRYCTL_GET_ALGO_USAGE): New. diff --git a/src/Makefile.am b/src/Makefile.am index 5396781a..07329a94 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -13,9 +13,9 @@ # Rember to change this just before a release. -LIBGRYPT_LT_CURRENT = 1 -LIBGRYPT_LT_REVISION = 0 -LIBGRYPT_LT_AGE = 0 +LIBGCRYPT_LT_CURRENT = 1 +LIBGCRYPT_LT_REVISION = 0 +LIBGCRYPT_LT_AGE = 0 diff --git a/src/gcrypt.h b/src/gcrypt.h index edfbaa3f..5593b59d 100644 --- a/src/gcrypt.h +++ b/src/gcrypt.h @@ -259,6 +259,9 @@ enum gcry_cipher_algos { GCRY_CIPHER_BLOWFISH = 4, GCRY_CIPHER_SAFER_SK128 = 5, GCRY_CIPHER_DES_SK = 6, + GCRY_CIPHER_RIJNDAEL = 7, + GCRY_CIPHER_RIJNDAEL192 = 8, + GCRY_CIPHER_RIJNDAEL256 = 9, GCRY_CIPHER_TWOFISH = 10, }; @@ -386,9 +389,7 @@ int gcry_md_info( GCRY_MD_HD h, int what, void *buffer, size_t *nbytes); int gcry_md_algo_info( int algo, int what, void *buffer, size_t *nbytes); const char *gcry_md_algo_name( int algo ); int gcry_md_map_name( const char* name ); - - -#define gcry_md_setkey(h,k,l) gcry_md_ctl( (h), GCRYCTL_SET_KEY, (k), (l) ) +int gcry_md_setkey( GCRY_MD_HD hd, const char *key, size_t keylen ); #define gcry_md_putc(h,c) \ do { \ diff --git a/src/global.c b/src/global.c index 4835b525..63b46a77 100644 --- a/src/global.c +++ b/src/global.c @@ -81,8 +81,8 @@ parse_version_string( const char *s, int *major, int *minor, int *micro ) /**************** * Check that the the version of the library is at minimum the requested one * and return the version string; return NULL if the condition is not - * satisfied. If a NULL is passed to thsi function, no check is done, - * but the version string is simpley returned. + * satisfied. If a NULL is passed to this function, no check is done, + * but the version string is simply returned. */ const char * gcry_check_version( const char *req_version ) |