From cvs at cvs.gnupg.org Mon Sep 1 10:18:49 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 01 Sep 2008 10:18:49 +0200 Subject: [svn] gcry - r1311 - in trunk: . random src Message-ID: Author: wk Date: 2008-09-01 10:18:46 +0200 (Mon, 01 Sep 2008) New Revision: 1311 Modified: trunk/ChangeLog trunk/README trunk/configure.ac trunk/random/ChangeLog trunk/random/random-fips.c trunk/src/ChangeLog trunk/src/secmem.c trunk/src/stdmem.c trunk/src/versioninfo.rc.in Log: Prepare a release candidate Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-08-29 15:40:24 UTC (rev 1310) +++ trunk/ChangeLog 2008-09-01 08:18:46 UTC (rev 1311) @@ -1,3 +1,9 @@ +2008-09-01 Werner Koch + + Release 1.4.2rc2. + + * configure.ac: Update svn_revision macro. + 2008-08-22 Werner Koch * configure.ac: Add option --enable-hmac-binary-check. Modified: trunk/random/ChangeLog =================================================================== --- trunk/random/ChangeLog 2008-08-29 15:40:24 UTC (rev 1310) +++ trunk/random/ChangeLog 2008-09-01 08:18:46 UTC (rev 1311) @@ -1,3 +1,11 @@ +2008-09-01 Werner Koch + + * random-fips.c (x931_get_dt) [W32]: Do not use getppid. + (get_entropy): Prepare for use under Windows. + (_gcry_rngfips_selftest): Ditto. + (entropy_collect_cb): Make sure that the gatherer never overflows + the buffers. + 2008-08-29 Werner Koch * random-fips.c (SEED_TTL): New. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-08-29 15:40:24 UTC (rev 1310) +++ trunk/src/ChangeLog 2008-09-01 08:18:46 UTC (rev 1311) @@ -1,3 +1,7 @@ +2008-09-01 Werner Koch + + * stdmem.c: Re-indented. + 2008-08-29 Werner Koch * fips.c (_gcry_initialize_fips_mode): Changed /proc file to test Modified: trunk/README =================================================================== --- trunk/README 2008-08-29 15:40:24 UTC (rev 1310) +++ trunk/README 2008-09-01 08:18:46 UTC (rev 1311) @@ -1,8 +1,7 @@ libgcrypt - The GNU crypto library ------------------------------------ - Version 1.4.2rc1 + Version 1.4.2rc2 - *** Warning: RELEASE CANDIDATE *** Copyright 2000, 2002, 2003, 2004, 2007, 2008 Free Software Foundation, Inc. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-08-29 15:40:24 UTC (rev 1310) +++ trunk/configure.ac 2008-09-01 08:18:46 UTC (rev 1311) @@ -26,11 +26,11 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.4.2]) -m4_define([my_issvn], [yes]) +m4_define([my_version], [1.4.2rc2]) +m4_define([my_issvn], [no]) -m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ - || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) +m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ + | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) AC_INIT([libgcrypt], [my_version[]m4_if(my_issvn,[yes],[-svn[]svn_revision])], [bug-libgcrypt at gnupg.org]) Modified: trunk/random/random-fips.c =================================================================== --- trunk/random/random-fips.c 2008-08-29 15:40:24 UTC (rev 1310) +++ trunk/random/random-fips.c 2008-09-01 08:18:46 UTC (rev 1311) @@ -304,7 +304,9 @@ to an not so easy predictable value to avoid always starting at 0. Not really needed but it doesn't harm. */ counter1 = (u32)getpid (); +#ifndef HAVE_W32_SYSTEM counter0 = (u32)getppid (); +#endif } @@ -513,10 +515,11 @@ gcry_assert (fips_rng_is_locked); gcry_assert (entropy_collect_buffer); - - while (length--) + + /* Note that we need to protect against gatherers returning more + than the requested bytes (e.g. rndw32). */ + while (length-- && entropy_collect_buffer_len < entropy_collect_buffer_size) { - gcry_assert (entropy_collect_buffer_len < entropy_collect_buffer_size); entropy_collect_buffer[entropy_collect_buffer_len++] ^= *p++; } } @@ -528,18 +531,32 @@ static void * get_entropy (size_t nbytes) { -#if USE_RNDLINUX void *result; + int rc; gcry_assert (!entropy_collect_buffer); entropy_collect_buffer = gcry_xmalloc_secure (nbytes); entropy_collect_buffer_size = nbytes; entropy_collect_buffer_len = 0; - if (_gcry_rndlinux_gather_random (entropy_collect_cb, 0, - X931_AES_KEYLEN, - GCRY_VERY_STRONG_RANDOM) < 0 - || entropy_collect_buffer_len != entropy_collect_buffer_size) + +#if USE_RNDLINUX + rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0, + X931_AES_KEYLEN, + GCRY_VERY_STRONG_RANDOM); +#elif USE_RNDW32 + do { + rc = _gcry_rndw32_gather_random (entropy_collect_cb, 0, + X931_AES_KEYLEN, + GCRY_VERY_STRONG_RANDOM); + } + while (rc >= 0 && entropy_collect_buffer_len < entropy_collect_buffer_size); +#else + rc = -1; +#endif + + if (rc < 0 || entropy_collect_buffer_len != entropy_collect_buffer_size) + { gcry_free (entropy_collect_buffer); entropy_collect_buffer = NULL; log_fatal ("error getting entropy data\n"); @@ -547,10 +564,6 @@ result = entropy_collect_buffer; entropy_collect_buffer = NULL; return result; -#else - log_fatal ("/dev/random support is not compiled in\n"); - return NULL; /* NOTREACHED */ -#endif } @@ -953,7 +966,7 @@ { gcry_err_code_t ec; -#if USE_RNDLINUX +#if defined(USE_RNDLINUX) || defined(USE_RNDW32) { char buffer[8]; @@ -966,8 +979,8 @@ ec = selftest_kat (report); -#else /*!USE_RNDLINUX*/ - report ("random", 0, "setup", "no support for /dev/random"); +#else /*!(USE_RNDLINUX||USE_RNDW32)*/ + report ("random", 0, "setup", "no entropy gathering module"); ec = GPG_ERR_SELFTEST_FAILED; #endif return gpg_error (ec); Modified: trunk/src/secmem.c =================================================================== --- trunk/src/secmem.c 2008-08-29 15:40:24 UTC (rev 1310) +++ trunk/src/secmem.c 2008-09-01 08:18:46 UTC (rev 1311) @@ -15,8 +15,7 @@ * 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 + * License along with this program; if not, see . */ #include Modified: trunk/src/stdmem.c =================================================================== --- trunk/src/stdmem.c 2008-08-29 15:40:24 UTC (rev 1310) +++ trunk/src/stdmem.c 2008-09-01 08:18:46 UTC (rev 1311) @@ -1,5 +1,5 @@ /* stdmem.c - private memory allocator - * Copyright (C) 1998, 2000, 2002, 2005 Free Software Foundation, Inc. + * Copyright (C) 1998, 2000, 2002, 2005, 2008 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -14,21 +14,20 @@ * 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 + * License along with this program; if not, see . */ /* * Description of the layered memory management in Libgcrypt: * - * [User] - * | - * | - * \ / - * global.c: [MM entrance points] -----> [user callbacks] - * | | - * | | - * \ / \ / + * [User] + * | + * | + * \ / + * global.c: [MM entrance points] -----> [user callbacks] + * | | + * | | + * \ / \ / * * stdmem.c: [non-secure handlers] [secure handlers] * @@ -75,149 +74,162 @@ * here have been used. */ void -_gcry_private_enable_m_guard(void) +_gcry_private_enable_m_guard (void) { - use_m_guard = 1; + use_m_guard = 1; } -/**************** + +/* * Allocate memory of size n. * Return NULL if we are out of memory. */ void * -_gcry_private_malloc( size_t n) +_gcry_private_malloc (size_t n) { - if(!n) - return NULL; /* allocating 0 bytes is undefined - better return - an error */ - if( use_m_guard ) { - char *p; - - if( !(p = malloc( n + EXTRA_ALIGN+5 )) ) - return NULL; - ((byte*)p)[EXTRA_ALIGN+0] = n; - ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; - ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; - ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_NOR_BYTE; - p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE; - return p+EXTRA_ALIGN+4; + if (!n) + return NULL; /* Allocating 0 bytes is undefined - we better return + an error to detect such coding errors. */ + if (use_m_guard) + { + char *p; + + if ( !(p = malloc (n + EXTRA_ALIGN+5)) ) + return NULL; + ((byte*)p)[EXTRA_ALIGN+0] = n; + ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; + ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; + ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_NOR_BYTE; + p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE; + return p+EXTRA_ALIGN+4; } - else { - return malloc( n ); + else + { + return malloc( n ); } } -/**************** - * Allocate memory of size n from the secure memory pool. - * Return NULL if we are out of memory. + +/* + * Allocate memory of size N from the secure memory pool. Return NULL + * if we are out of memory. */ void * -_gcry_private_malloc_secure( size_t n) +_gcry_private_malloc_secure (size_t n) { - if(!n) - return NULL; /* allocating 0 bytes is undefined - better return - an error */ - if( use_m_guard ) { - char *p; - - if( !(p = _gcry_secmem_malloc( n +EXTRA_ALIGN+ 5 )) ) - return NULL; - ((byte*)p)[EXTRA_ALIGN+0] = n; - ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; - ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; - ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_SEC_BYTE; - p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE; - return p+EXTRA_ALIGN+4; + if (!n) + return NULL; /* Allocating 0 bytes is undefined - better return an + error to detect such coding errors. */ + if (use_m_guard) + { + char *p; + + if ( !(p = _gcry_secmem_malloc (n +EXTRA_ALIGN+ 5)) ) + return NULL; + ((byte*)p)[EXTRA_ALIGN+0] = n; + ((byte*)p)[EXTRA_ALIGN+1] = n >> 8 ; + ((byte*)p)[EXTRA_ALIGN+2] = n >> 16 ; + ((byte*)p)[EXTRA_ALIGN+3] = MAGIC_SEC_BYTE; + p[4+EXTRA_ALIGN+n] = MAGIC_END_BYTE; + return p+EXTRA_ALIGN+4; } - else { - return _gcry_secmem_malloc( n ); + else + { + return _gcry_secmem_malloc( n ); } } -/**************** +/* * Realloc and clear the old space * Return NULL if there is not enough memory. */ void * -_gcry_private_realloc( void *a, size_t n ) +_gcry_private_realloc ( void *a, size_t n ) { - if( use_m_guard ) { - unsigned char *p = a; - char *b; - size_t len; - - if (!a) - return _gcry_private_malloc(n); + if (use_m_guard) + { + unsigned char *p = a; + char *b; + size_t len; + + if (!a) + return _gcry_private_malloc(n); - _gcry_private_check_heap(p); - len = p[-4]; - len |= p[-3] << 8; - len |= p[-2] << 16; - if( len >= n ) /* we don't shrink for now */ - return a; - if( p[-1] == MAGIC_SEC_BYTE ) - b = _gcry_private_malloc_secure(n); - else - b = _gcry_private_malloc(n); - if( !b ) - return NULL; - memcpy(b, a, len ); - memset(b+len, 0, n-len ); - _gcry_private_free( p ); - return b; + _gcry_private_check_heap(p); + len = p[-4]; + len |= p[-3] << 8; + len |= p[-2] << 16; + if( len >= n ) /* We don't shrink for now. */ + return a; + if (p[-1] == MAGIC_SEC_BYTE) + b = _gcry_private_malloc_secure(n); + else + b = _gcry_private_malloc(n); + if (!b) + return NULL; + memcpy (b, a, len); + memset (b+len, 0, n-len); + _gcry_private_free (p); + return b; } - else if( _gcry_private_is_secure(a) ) { - return _gcry_secmem_realloc( a, n ); + else if ( _gcry_private_is_secure(a) ) + { + return _gcry_secmem_realloc( a, n ); } - else { - return realloc( a, n ); + else + { + return realloc( a, n ); } } void -_gcry_private_check_heap( const void *a ) +_gcry_private_check_heap (const void *a) { - if( use_m_guard ) { - const byte *p = a; - size_t len; - - if( !p ) - return; - - if( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) ) - _gcry_log_fatal("memory at %p corrupted (underflow=%02x)\n", p, p[-1] ); - len = p[-4]; - len |= p[-3] << 8; - len |= p[-2] << 16; - if( p[len] != MAGIC_END_BYTE ) - _gcry_log_fatal("memory at %p corrupted (overflow=%02x)\n", p, p[-1] ); + if (use_m_guard) + { + const byte *p = a; + size_t len; + + if (!p) + return; + + if ( !(p[-1] == MAGIC_NOR_BYTE || p[-1] == MAGIC_SEC_BYTE) ) + _gcry_log_fatal ("memory at %p corrupted (underflow=%02x)\n", p, p[-1]); + len = p[-4]; + len |= p[-3] << 8; + len |= p[-2] << 16; + if ( p[len] != MAGIC_END_BYTE ) + _gcry_log_fatal ("memory at %p corrupted (overflow=%02x)\n", p, p[-1]); } } -/**************** + +/* * Free a memory block allocated by this opr the secmem module */ void -_gcry_private_free( void *a ) +_gcry_private_free (void *a) { - byte *p = a; + byte *p = a; - if( !p ) - return; - if( use_m_guard ) { - _gcry_private_check_heap(p); - if( _gcry_private_is_secure(a) ) - _gcry_secmem_free(p-EXTRA_ALIGN-4); - else { - free(p-EXTRA_ALIGN-4); + if (!p) + return; + if (use_m_guard ) + { + _gcry_private_check_heap(p); + if ( _gcry_private_is_secure(a) ) + _gcry_secmem_free(p-EXTRA_ALIGN-4); + else + { + free(p-EXTRA_ALIGN-4); } } - else if( _gcry_private_is_secure(a) ) - _gcry_secmem_free(p); - else - free(p); + else if ( _gcry_private_is_secure(a) ) + _gcry_secmem_free(p); + else + free(p); } Modified: trunk/src/versioninfo.rc.in =================================================================== --- trunk/src/versioninfo.rc.in 2008-08-29 15:40:24 UTC (rev 1310) +++ trunk/src/versioninfo.rc.in 2008-09-01 08:18:46 UTC (rev 1311) @@ -39,7 +39,7 @@ VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0" VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT at .@LIBGCRYPT_LT_AGE at .@LIBGCRYPT_LT_REVISION at .@BUILD_REVISION@\0" VALUE "InternalName", "libgcrypt\0" - VALUE "LegalCopyright", "Copyright ? 2007 Free Software Foundation, Inc.\0" + VALUE "LegalCopyright", "Copyright ? 2008 Free Software Foundation, Inc.\0" VALUE "LegalTrademarks", "\0" VALUE "OriginalFilename", "libgcrypt.dll\0" VALUE "PrivateBuild", "\0" From cvs at cvs.gnupg.org Mon Sep 1 10:40:39 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 01 Sep 2008 10:40:39 +0200 Subject: [svn] gcry - r1312 - tags Message-ID: Author: wk Date: 2008-09-01 10:40:39 +0200 (Mon, 01 Sep 2008) New Revision: 1312 Added: tags/libgcrypt-1.4.2rc2/ Log: Add release tag. From cvs at cvs.gnupg.org Mon Sep 1 12:39:25 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 01 Sep 2008 12:39:25 +0200 Subject: [svn] assuan - r288 - trunk/src Message-ID: Author: wk Date: 2008-09-01 12:39:24 +0200 (Mon, 01 Sep 2008) New Revision: 288 Modified: trunk/src/ChangeLog trunk/src/assuan-io.c Log: Support sustems without nanosleep() Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-05-27 11:45:44 UTC (rev 287) +++ trunk/src/ChangeLog 2008-09-01 10:39:24 UTC (rev 288) @@ -1,3 +1,8 @@ +2008-09-01 Werner Koch + + * assuan-io.c: Include time.h. Fixes bug#951. + (_assuan_usleep): Use nanosleep only is available. + 2008-03-25 Marcus Brinkmann * assuan-inquire.c (assuan_inquire): Loop over _assuan_read_line Modified: trunk/src/assuan-io.c =================================================================== --- trunk/src/assuan-io.c 2008-05-27 11:45:44 UTC (rev 287) +++ trunk/src/assuan-io.c 2008-09-01 10:39:24 UTC (rev 288) @@ -21,6 +21,7 @@ #include #endif +#include #include #include #ifdef HAVE_SYS_SOCKET_H @@ -218,20 +219,27 @@ void _assuan_usleep (unsigned int usec) { -#ifdef HAVE_W32_SYSTEM - /* FIXME. */ - Sleep (usec / 1000); + if (usec) + { +#ifdef HAVE_NANOSLEEP + struct timespec req; + struct timespec rem; + + req.tv_sec = 0; + req.tv_nsec = usec * 1000; + + while (nanosleep (&req, &rem) < 0 && errno == EINTR) + req = rem; + +#elif defined(HAVE_W32_SYSTEM) + Sleep (usec / 1000); #else - struct timespec req; - struct timespec rem; + struct timeval tv; - if (usec == 0) - return; - - req.tv_sec = 0; - req.tv_nsec = usec * 1000; - - while (nanosleep (&req, &rem) < 0 && errno == EINTR) - req = rem; + tv.tv_sec = usec / 1000000; + tv.tv_usec = usec % 1000000; + select (0, NULL, NULL, NULL, &tv); #endif + } } + From cvs at cvs.gnupg.org Mon Sep 1 12:39:45 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 01 Sep 2008 12:39:45 +0200 Subject: [svn] assuan - r289 - trunk Message-ID: Author: wk Date: 2008-09-01 12:39:44 +0200 (Mon, 01 Sep 2008) New Revision: 289 Modified: trunk/configure.ac Log: check for nanosleep Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-09-01 10:39:24 UTC (rev 288) +++ trunk/configure.ac 2008-09-01 10:39:44 UTC (rev 289) @@ -210,7 +210,7 @@ # Checks for library functions. -AC_CHECK_FUNCS(flockfile funlockfile) +AC_CHECK_FUNCS([flockfile funlockfile nanosleep]) # Check for funopen AC_CHECK_FUNCS(funopen) From cvs at cvs.gnupg.org Mon Sep 1 13:56:07 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 01 Sep 2008 13:56:07 +0200 Subject: [svn] GpgEX - r59 - trunk/src Message-ID: Author: marcus Date: 2008-09-01 13:56:06 +0200 (Mon, 01 Sep 2008) New Revision: 59 Modified: trunk/src/ChangeLog Log: 2008-09-01 Marcus Brinkmann * gpgex.cc (Initialize): Also pay attention to endings pem, p7m and p7s. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-08-01 12:04:30 UTC (rev 58) +++ trunk/src/ChangeLog 2008-09-01 11:56:06 UTC (rev 59) @@ -1,3 +1,8 @@ +2008-09-01 Marcus Brinkmann + + * gpgex.cc (Initialize): Also pay attention to endings pem, p7m + and p7s. + 2008-03-26 Marcus Brinkmann * client.cc (default_uiserver_cmdline): Fall back to GPA if From cvs at cvs.gnupg.org Wed Sep 3 11:37:38 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 03 Sep 2008 11:37:38 +0200 Subject: [svn] GnuPG - r4822 - in trunk: . agent common doc keyserver po sm tools Message-ID: Author: wk Date: 2008-09-03 11:37:32 +0200 (Wed, 03 Sep 2008) New Revision: 4822 Modified: trunk/NEWS trunk/THANKS trunk/TODO trunk/agent/ChangeLog trunk/agent/command.c trunk/agent/preset-passphrase.c trunk/common/ChangeLog trunk/common/convert.c trunk/common/t-convert.c trunk/common/util.h trunk/doc/ChangeLog trunk/doc/yat2m.c trunk/keyserver/ChangeLog trunk/keyserver/gpgkeys_kdns.c trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po trunk/sm/ChangeLog trunk/sm/sign.c trunk/tools/mk-tdata.c Log: Fix gpg-preset-passphrase bug. Cleanups [The diff below has been truncated] Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/agent/ChangeLog 2008-09-03 09:37:32 UTC (rev 4822) @@ -1,3 +1,11 @@ +2008-09-03 Werner Koch + + * command.c (parse_keygrip): Use hex2bin. + (cmd_preset_passphrase): Decode the passphrase. Reported by Kiss + Gabor. Fixes #679 again. + * preset-passphrase.c (make_hexstring): Remove. + (preset_passphrase): Use bin2hex. + 2008-05-27 Werner Koch * trustlist.c (insert_colons): Fix stupidly wrong allocation size @@ -12,7 +20,7 @@ * gpg-agent.c (main, agent_deinit_default_ctrl): Always use xfree because our asprintf is mapped to an xmalloc style function in - util.h. Replace xtrdup by xtrystrdup. + util.h. Replace xstrdup by xtrystrdup. * w32main.c (build_argv): Ditto. * preset-passphrase.c (preset_passphrase): Ditto. * divert-scd.c (ask_for_card): Ditto. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/common/ChangeLog 2008-09-03 09:37:32 UTC (rev 4822) @@ -1,3 +1,9 @@ +2008-09-03 Werner Koch + + * convert.c (hex2str): New. + (hex2str_alloc): New. + * t-convert.c (test_hex2str): New. + 2008-08-19 Werner Koch * iobuf.c: Avoid passing a NULL (iobuf_t)->desc to the log Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/doc/ChangeLog 2008-09-03 09:37:32 UTC (rev 4822) @@ -1,3 +1,8 @@ +2008-08-30 Werner Koch + + * yat2m.c (write_th): Print a not ethat this is generated source. + (VERSION): Bump up to 1.0. + 2008-07-30 Werner Koch * gpgsm.texi (GPGSM Configuration): Mention com-cert.pem. Modified: trunk/keyserver/ChangeLog =================================================================== --- trunk/keyserver/ChangeLog 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/keyserver/ChangeLog 2008-09-03 09:37:32 UTC (rev 4822) @@ -1,3 +1,7 @@ +2008-08-29 Werner Koch + + * gpgkeys_kdns.c: Changed copyright notice to the FSF. + 2008-04-21 Werner Koch * ksutil.c (w32_init_sockets) [HAVE_W32_SYSTEM]: New. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/sm/ChangeLog 2008-09-03 09:37:32 UTC (rev 4822) @@ -1,3 +1,8 @@ +2008-09-03 Werner Koch + + * sign.c (MY_GCRY_MD_SHA224): New, so that we don't need libgcrypt + 1.2. + 2008-08-13 Werner Koch * keylist.c (list_cert_colon): Print 'f' for validated certs. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/NEWS 2008-09-03 09:37:32 UTC (rev 4822) @@ -27,7 +27,9 @@ * gpgsm now uses AES by default. + * gpg-preset-passphrase works again. + Noteworthy changes in version 2.0.9 (2008-03-26) ------------------------------------------------ Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/THANKS 2008-09-03 09:37:32 UTC (rev 4822) @@ -140,6 +140,7 @@ Keith Clayton keith at claytons.org Ken Takusagawa ken.takusagawa.2 at gmail.com Kevin Ryde user42 at zip.com.au +Kiss Gabor kissg at ssg.ki.iif.hu Klaus Singvogel ks at caldera.de Kurt Garloff garloff at suse.de Lars Kellogg-Stedman lars at bu.edu Modified: trunk/TODO =================================================================== --- trunk/TODO 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/TODO 2008-09-03 09:37:32 UTC (rev 4822) @@ -104,7 +104,10 @@ Remove these definitions. ** MY_GCRY_PK_ECDSA Remove this. +** MY_GCRY_MD_SHA224 + Remove this. + * Extend selinux support to other modules * Remove -sat PGP2 compatibility hack Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/agent/command.c 2008-09-03 09:37:32 UTC (rev 4822) @@ -271,7 +271,6 @@ { int rc; size_t n; - const unsigned char *p; rc = parse_hexstring (ctx, string, &n); if (rc) @@ -280,8 +279,8 @@ if (n != 20) return set_error (GPG_ERR_ASS_PARAMETER, "invalid length of keygrip"); - for (p=(const unsigned char*)string, n=0; n < 20; p += 2, n++) - buf[n] = xtoi_2 (p); + if (hex2bin (string, buf, 20) < 0) + return set_error (GPG_ERR_BUG, "hex2bin"); return 0; } @@ -1100,7 +1099,7 @@ size_t len; if (!opt.allow_preset_passphrase) - return gpg_error (GPG_ERR_NOT_SUPPORTED); + return set_error (GPG_ERR_NOT_SUPPORTED, "no --allow-preset-passphrase"); rc = parse_keygrip (ctx, line, grip); if (rc) @@ -1135,11 +1134,17 @@ /* If there is a passphrase, use it. Currently, a passphrase is required. */ if (*line) - passphrase = line; + { + /* Do in-place conversion. */ + passphrase = line; + if (!hex2str (passphrase, passphrase, strlen (passphrase)+1, NULL)) + rc = set_error (GPG_ERR_ASS_PARAMETER, "invalid hexstring"); + } else - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + rc = set_error (GPG_ERR_NOT_IMPLEMENTED, "passphrase is required"); - rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl); + if (!rc) + rc = agent_put_cache (grip_clear, CACHE_MODE_ANY, passphrase, ttl); if (rc) log_error ("command preset_passwd failed: %s\n", gpg_strerror (rc)); Modified: trunk/agent/preset-passphrase.c =================================================================== --- trunk/agent/preset-passphrase.c 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/agent/preset-passphrase.c 2008-09-03 09:37:32 UTC (rev 4822) @@ -113,38 +113,7 @@ /* Include the implementation of map_spwq_error. */ MAP_SPWQ_ERROR_IMPL -/* Convert the string SRC into HEX encoding. Caller needs to xfree - the returned string. */ -static char * -make_hexstring (const char *src) -{ - int len = 2 * strlen (src) + 1; - char *dst; - char *res; - res = dst = xtrymalloc (len); - if (!dst) - { - log_error ("can not escape string: %s\n", - gpg_strerror (gpg_error_from_syserror ())); - return NULL; - } - -#define _tohex(nr) ((nr) < 10 ? ((nr) + '0') : (((nr) - 10) + 'A')) -#define tohex1(p) _tohex (*((unsigned char *) p) & 15) -#define tohex2(p) _tohex ((*((unsigned char *) p) >> 4) & 15) - - while (*src) - { - *(dst++) = tohex2 (src); - *(dst++) = tohex1 (src); - src++; - } - *dst = '\0'; - return res; -} - - static void preset_passphrase (const char *keygrip) { @@ -175,11 +144,14 @@ /* FIXME: How to handle empty passwords? */ } - passphrase_esc = make_hexstring (opt_passphrase - ? opt_passphrase : passphrase); + { + const char *s = opt_passphrase ? opt_passphrase : passphrase; + passphrase_esc = bin2hex (s, strlen (s), NULL); + } if (!passphrase_esc) { - /* Error message printed by callee. */ + log_error ("can not escape string: %s\n", + gpg_strerror (gpg_error_from_syserror ())); return; } Modified: trunk/common/convert.c =================================================================== --- trunk/common/convert.c 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/common/convert.c 2008-09-03 09:37:32 UTC (rev 4822) @@ -1,5 +1,5 @@ /* convert.c - Hex conversion functions. - * Copyright (C) 2006 Free Software Foundation, Inc. + * Copyright (C) 2006, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -30,7 +30,7 @@ /* Convert STRING consisting of hex characters into its binary representation and store that at BUFFER. BUFFER needs to be of - LENGTH bytes. The function check that the STRING will convert + LENGTH bytes. The function checks that the STRING will convert exactly to LENGTH bytes. The string is delimited by either end of string or a white space character. The function returns -1 on error or the length of the parsed string. */ @@ -100,6 +100,7 @@ } + static char * do_bin2hex (const void *buffer, size_t length, char *stringbuf, int with_colon) { @@ -160,3 +161,87 @@ } + +/* Convert HEXSTRING consisting of hex characters into string and + store that at BUFFER. HEXSTRING is either delimited by end of + string or a white space character. The function makes sure that + the resulting string in BUFFER is terminated by a Nul character. + BUFSIZE is the availabe length of BUFFER; if the converted result + plus a possible required Nul character does not fit into this + buffer, the function returns NULL and won't change the existing + conent of buffer. In-place conversion is possible as long as + BUFFER points to HEXSTRING. + + If BUFFER is NULL and bufsize is 0 the function scans HEXSTRING but + does not store anything. This may be used to find the end of + hexstring. + + On sucess the function returns a pointer to the next character + after HEXSTRING (which is either end-of-string or a the next white + space). If BUFLEN is not NULL the strlen of buffer is stored + there; this will even be done if BUFFER has been passed as NULL. */ +const char * +hex2str (const char *hexstring, char *buffer, size_t bufsize, size_t *buflen) +{ + const char *s = hexstring; + int idx, count; + int need_nul = 0; + + if (buflen) + *buflen = 0; + + for (s=hexstring, count=0; hexdigitp (s) && hexdigitp (s+1); s += 2, count++) + ; + if (*s && (!isascii (*s) || !isspace (*s)) ) + return NULL; /* Not followed by Nul or white space. */ + need_nul = !(s[-2] == '0' && s[-1] == '0'); + if (need_nul) + count++; + + if (buffer) + { + if (count > bufsize) + return NULL; /* Too long. */ + + for (s=hexstring, idx=0; hexdigitp (s) && hexdigitp (s+1); s += 2) + ((unsigned char*)buffer)[idx++] = xtoi_2 (s); + if (need_nul) + buffer[idx] = 0; + } + + if (buflen) + *buflen = count - 1; + return s; +} + + +/* Same as hex2str but this function allocated a new string. Returns + NULL on error. If R_COUNT is not NULL, the number of scanned bytes + will be stored there. ERRNO is set on error. */ +char * +hex2str_alloc (const char *hexstring, size_t *r_count) +{ + const char *tail; + size_t nbytes; + char *result; + + tail = hex2str (hexstring, NULL, 0, &nbytes); + if (!tail) + { + if (r_count) + *r_count = 0; + errno = EINVAL; + return NULL; + } + if (r_count) + *r_count = tail - hexstring; + result = xtrymalloc (nbytes+1); + if (!result) + return NULL; + if (!hex2str (hexstring, result, nbytes+1, NULL)) + BUG (); + return result; +} + + + Modified: trunk/common/t-convert.c =================================================================== --- trunk/common/t-convert.c 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/common/t-convert.c 2008-09-03 09:37:32 UTC (rev 4822) @@ -1,5 +1,5 @@ /* t-convert.c - Module test for convert.c - * Copyright (C) 2006 Free Software Foundation, Inc. + * Copyright (C) 2006, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -20,6 +20,7 @@ #include #include #include +#include #include "util.h" @@ -275,7 +276,174 @@ +static void +test_hex2str (void) +{ + static struct { + const char *hex; + const char *str; + int off; + int no_alloc_test; + } tests[] = { + /* Simple tests. */ + { "112233445566778899aabbccddeeff1122", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + { "112233445566778899aabbccddeeff1122 blah", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + { "112233445566778899aabbccddeeff1122\tblah", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + { "112233445566778899aabbccddeeff1122\nblah", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 34 }, + /* Valid tests yielding an empty string. */ + { "00", + "", + 2 }, + { "00 x", + "", + 2 }, + { "", + "", + 0 }, + { " ", + "", + 0 }, + /* Test trailing Nul feature. */ + { "112233445566778899aabbccddeeff112200", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 36 }, + { "112233445566778899aabbccddeeff112200 ", + "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22", + 36 }, + /* Test buffer size. (buffer is of length 20) */ + { "6162636465666768696A6b6c6D6e6f70717273", + "abcdefghijklmnopqrs", + 38 }, + { "6162636465666768696A6b6c6D6e6f7071727300", + "abcdefghijklmnopqrs", + 40 }, + { "6162636465666768696A6b6c6D6e6f7071727374", + NULL, + 0, 1 }, + { "6162636465666768696A6b6c6D6e6f707172737400", + NULL, + 0, 1 }, + { "6162636465666768696A6b6c6D6e6f707172737475", + NULL, + 0, 1 }, + /* Invalid tests. */ + { "112233445566778899aabbccddeeff1122334", NULL, 0 }, + { "112233445566778899AABBCCDDEEFF1122334", NULL, 0 }, + { "112233445566778899AABBCCDDEEFG11223344", NULL, 0 }, + { "0:0112233445566778899aabbccddeeff11223344", NULL, 0 }, + { "112233445566778899aabbccddeeff11223344:", NULL, 0 }, + { "112233445566778899aabbccddeeff112233445", NULL, 0 }, + { "112233445566778899aabbccddeeff1122334455", NULL, 0, 1 }, + { "112233445566778899aabbccddeeff11223344blah", NULL, 0 }, + { "0", NULL, 0 }, + { "00:", NULL, 0 }, + { "00x", NULL, 0 }, + + { NULL, NULL, 0 } + }; + + int idx; + char buffer[20]; + const char *tail; + size_t count; + char *result; + + for (idx=0; tests[idx].hex; idx++) + { + tail = hex2str (tests[idx].hex, buffer, sizeof buffer, &count); + if (tests[idx].str) + { + /* Good case test. */ + if (!tail) + fail (idx); + else if (strcmp (tests[idx].str, buffer)) + fail (idx); + else if (tail - tests[idx].hex != tests[idx].off) + fail (idx); + else if (strlen (buffer) != count) + fail (idx); + } + else + { + /* Bad case test. */ + if (tail) + fail (idx); + } + } + + /* Same tests again using in-place conversion. */ + for (idx=0; tests[idx].hex; idx++) + { + char tmpbuf[100]; + + assert (strlen (tests[idx].hex)+1 < sizeof tmpbuf); + strcpy (tmpbuf, tests[idx].hex); + + /* Note: we still need to use 20 as buffer length because our + tests assume that. */ + tail = hex2str (tmpbuf, tmpbuf, 20, &count); + if (tests[idx].str) + { + /* Good case test. */ + if (!tail) + fail (idx); + else if (strcmp (tests[idx].str, tmpbuf)) + fail (idx); + else if (tail - tmpbuf != tests[idx].off) + fail (idx); + else if (strlen (tmpbuf) != count) + fail (idx); + } + else + { + /* Bad case test. */ + if (tail) + fail (idx); + if (strcmp (tmpbuf, tests[idx].hex)) + fail (idx); /* Buffer was modified. */ + } + } + + /* Test the allocation variant. */ + for (idx=0; tests[idx].hex; idx++) + { + if (tests[idx].no_alloc_test) + continue; + + result = hex2str_alloc (tests[idx].hex, &count); + if (tests[idx].str) + { + /* Good case test. */ + if (!result) + fail (idx); + else if (strcmp (tests[idx].str, result)) + fail (idx); + else if (count != tests[idx].off) + fail (idx); + } + else + { + /* Bad case test. */ + if (result) + fail (idx); + } + xfree (result); + } +} + + + + + int main (int argc, char **argv) { @@ -284,6 +452,7 @@ test_hexcolon2bin (); test_bin2hex (); test_bin2hexcolon (); + test_hex2str (); return 0; } Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/common/util.h 2008-09-03 09:37:32 UTC (rev 4822) @@ -189,6 +189,9 @@ int hexcolon2bin (const char *string, void *buffer, size_t length); char *bin2hex (const void *buffer, size_t length, char *stringbuf); char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf); +const char *hex2str (const char *hexstring, + char *buffer, size_t bufsize, size_t *buflen); +char *hex2str_alloc (const char *hexstring, size_t *r_count); /*-- homedir.c --*/ Modified: trunk/doc/yat2m.c =================================================================== --- trunk/doc/yat2m.c 2008-08-31 11:55:09 UTC (rev 4821) +++ trunk/doc/yat2m.c 2008-09-03 09:37:32 UTC (rev 4822) @@ -1,6 +1,6 @@ From cvs at cvs.gnupg.org Wed Sep 3 12:42:11 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 03 Sep 2008 12:42:11 +0200 Subject: [svn] gcry - r1313 - in trunk: . doc Message-ID: Author: wk Date: 2008-09-03 12:42:11 +0200 (Wed, 03 Sep 2008) New Revision: 1313 Modified: trunk/NEWS trunk/configure.ac trunk/doc/gcrypt.texi Log: Updated the NEWS file. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-09-01 08:40:39 UTC (rev 1312) +++ trunk/NEWS 2008-09-03 10:42:11 UTC (rev 1313) @@ -1,19 +1,22 @@ Noteworthy changes in version 1.4.2 (unreleased) ------------------------------------------------ - * The library may now be switched into a FIPS mode. + * The long missing gcry_mpi_lshift function has been added. - * More runtime selftests. + * RSA key generation now supports a "transient-key" flag. + * The keygrip computation for ECDSA has been implemented thus ECDSA + is now fully supported. + * A few macros have been replaced by functions for better type checking. * The thread initialization structure now carries version information. - * The long missing gcry_mpi_lshift function has been added. + * The manual describes more clearly how to initialize Libgcrypt. - * RSA key generation now supports a "transient-key" flag. + * The library may now be switched into a FIPS mode. * Interface changes relative to the 1.3.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-09-01 08:40:39 UTC (rev 1312) +++ trunk/configure.ac 2008-09-03 10:42:11 UTC (rev 1313) @@ -26,8 +26,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.4.2rc2]) -m4_define([my_issvn], [no]) +m4_define([my_version], [1.4.2]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-01 08:40:39 UTC (rev 1312) +++ trunk/doc/gcrypt.texi 2008-09-03 10:42:11 UTC (rev 1313) @@ -2634,7 +2634,7 @@ This is only meaningful for RSA keys. This is a flag with no value. If given the RSA key is created using a faster and a somewhat less secure random number generator. This flag may be used for keys which are only -used for a short time and do not require full cryptograohic strength. +used for a short time and do not require full cryptographic strength. @end table @@ -4338,6 +4338,12 @@ result in @var{x}. @end deftypefun + at deftypefun void gcry_mpi_lshift (@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 left and store the +result in @var{x}. + at end deftypefun + @node Miscellaneous @section Miscellaneous From cvs at cvs.gnupg.org Thu Sep 4 11:52:37 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 04 Sep 2008 11:52:37 +0200 Subject: [svn] ksba - r292 - trunk/src Message-ID: Author: wk Date: 2008-09-04 11:52:37 +0200 (Thu, 04 Sep 2008) New Revision: 292 Modified: trunk/src/ChangeLog trunk/src/asn1-func.c trunk/src/asn1-func.h trunk/src/asn1-func2.c trunk/src/cms.c trunk/src/visibility.c trunk/src/visibility.h Log: Fix a visibility problem. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-03-17 09:55:50 UTC (rev 291) +++ trunk/src/ChangeLog 2008-09-04 09:52:37 UTC (rev 292) @@ -1,3 +1,14 @@ +2008-09-04 Werner Koch + + * asn1-func.h (ksba_asn_create_structure): Remove unused prototype + (ksba_asn1_create_tree): Ditto. + (ksba_asn_read_value, ksba_asn_write_value): Ditto. + + * asn1-func.c (ksba_asn_delete_structure): Prefix name with underscore. + * visibility.h (ksba_asn_delete_structure): Remove macros. + (MARK_VISIBLEX): New. + (ksba_asn_delete_structure): New. + 2008-03-17 Werner Koch * cert.c (ksba_cert_get_image): Fix size_t/int format mismatch. @@ -23,7 +34,7 @@ * keyinfo.c (pkalgo_t): New. (algo_table_s): Add fields PARMELEM_STRING and - PARMCTRL_STRING. repalce IS-ECC by PKALGO. Adjust all tables and + PARMCTRL_STRING. Replace IS_ECC by PKALGO. Adjust all tables and users of IS_ECC. Add DSA parameter description. (TLV_LENGTH): Add PREFIX arg and change all callers. (_ksba_keyinfo_to_sexp): Parse parameters. Modified: trunk/src/asn1-func.c =================================================================== --- trunk/src/asn1-func.c 2008-03-17 09:55:50 UTC (rev 291) +++ trunk/src/asn1-func.c 2008-09-04 09:52:37 UTC (rev 292) @@ -637,7 +637,7 @@ } int -ksba_asn_delete_structure (AsnNode root) +_ksba_asn_delete_structure (AsnNode root) { AsnNode p, p2, p3; Modified: trunk/src/asn1-func.h =================================================================== --- trunk/src/asn1-func.h 2008-03-17 09:55:50 UTC (rev 291) +++ trunk/src/asn1-func.h 2008-09-04 09:52:37 UTC (rev 292) @@ -201,12 +201,7 @@ const void *oidbuf, size_t oidlen); -int ksba_asn_create_structure (AsnNode root, char *source_name, - AsnNode*pointer , char *dest_name); -int ksba_asn_delete_structure (AsnNode root); -int ksba_asn1_create_tree (const static_asn *root,AsnNode*pointer); -int ksba_asn_read_value(AsnNode root,const char *name,unsigned char *value,int *len); -int ksba_asn_write_value(AsnNode root,char *name,unsigned char *value,int len); +int _ksba_asn_delete_structure (AsnNode root); /*-- asn2-func.c --*/ Modified: trunk/src/asn1-func2.c =================================================================== --- trunk/src/asn1-func2.c 2008-03-17 09:55:50 UTC (rev 291) +++ trunk/src/asn1-func2.c 2008-09-04 09:52:37 UTC (rev 292) @@ -208,7 +208,7 @@ rc = gpg_error (GPG_ERR_GENERAL); if (rc) - ksba_asn_delete_structure (pointer); + _ksba_asn_delete_structure (pointer); return rc; } Modified: trunk/src/cms.c =================================================================== --- trunk/src/cms.c 2008-03-17 09:55:50 UTC (rev 291) +++ trunk/src/cms.c 2008-09-04 09:52:37 UTC (rev 292) @@ -1329,7 +1329,7 @@ * Set the algorithm to be used for creating the hash. Note, that we * currently can't do a per-signer hash. * - * Return value: o on success or an error code + * Return value: 0 on success or an error code **/ gpg_error_t ksba_cms_add_digest_algo (ksba_cms_t cms, const char *oid) Modified: trunk/src/visibility.c =================================================================== --- trunk/src/visibility.c 2008-03-17 09:55:50 UTC (rev 291) +++ trunk/src/visibility.c 2008-09-04 09:52:37 UTC (rev 292) @@ -1096,7 +1096,6 @@ } - /*-- asn1-func.c --*/ void ksba_asn_tree_dump (ksba_asn_tree_t tree, const char *name, FILE *fp) @@ -1112,6 +1111,17 @@ } +/* This is a dummy function which we only include because it was + accidently put into the public interface. */ +int +ksba_asn_delete_structure (void *dummy) +{ + (void)dummy; + fprintf (stderr, "BUG: ksba_asn_delete_structure called\n"); + return -1; +} + + /*-- oid.c --*/ char * ksba_oid_to_str (const char *buffer, size_t length) Modified: trunk/src/visibility.h =================================================================== --- trunk/src/visibility.h 2008-03-17 09:55:50 UTC (rev 291) +++ trunk/src/visibility.h 2008-09-04 09:52:37 UTC (rev 292) @@ -30,7 +30,6 @@ #define ksba_realloc _ksba_realloc #define ksba_strdup _ksba_strdup #define ksba_asn_create_tree _ksba_asn_create_tree -#define ksba_asn_delete_structure _ksba_asn_delete_structure #define ksba_asn_parse_file _ksba_asn_parse_file #define ksba_asn_tree_dump _ksba_asn_tree_dump #define ksba_asn_tree_release _ksba_asn_tree_release @@ -199,23 +198,18 @@ # ifdef KSBA_USE_VISIBILITY # define MARK_VISIBLE(name) \ extern __typeof__ (_##name) name _KSBA_VISIBILITY_DEFAULT; +# define MARK_VISIBLEX(name) \ + extern __typeof__ (name) name _KSBA_VISIBILITY_DEFAULT; # else -# define MARK_VISIBLE(name) /* */ +# define MARK_VISIBLE(name) /* */ +# define MARK_VISIBLEX(name) /* */ # endif -/* Prototypes of functions though exported not yet officially known or - only accidently put into the public interface. */ -struct asn_node_struct; -#ifndef HAVE_TYPEDEFD_ASNNODE - typedef struct asn_node_struct *AsnNode; - typedef struct asn_node_struct *asn_node_t; -# define HAVE_TYPEDEFD_ASNNODE -#endif -int ksba_asn_delete_structure (asn_node_t root); +/* Prototype for a dummy function we once exported accidently. */ +int ksba_asn_delete_structure (void *dummy); - /* Undef all redefined symbols so that we set the attribute on the exported name of the symbol. */ #undef ksba_check_version @@ -227,7 +221,6 @@ #undef ksba_realloc #undef ksba_strdup #undef ksba_asn_create_tree -#undef ksba_asn_delete_structure #undef ksba_asn_parse_file #undef ksba_asn_tree_dump #undef ksba_asn_tree_release @@ -386,10 +379,10 @@ MARK_VISIBLE (ksba_realloc) MARK_VISIBLE (ksba_strdup) MARK_VISIBLE (ksba_asn_create_tree) -MARK_VISIBLE (ksba_asn_delete_structure) MARK_VISIBLE (ksba_asn_parse_file) MARK_VISIBLE (ksba_asn_tree_dump) MARK_VISIBLE (ksba_asn_tree_release) +MARK_VISIBLEX (ksba_asn_delete_structure) /* Dummy for ABI compatibility. */ MARK_VISIBLE (ksba_cert_get_auth_key_id) MARK_VISIBLE (ksba_cert_get_cert_policies) From cvs at cvs.gnupg.org Thu Sep 4 12:35:42 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 04 Sep 2008 12:35:42 +0200 Subject: [svn] GnuPG - r4823 - in trunk: doc sm Message-ID: Author: wk Date: 2008-09-04 12:35:41 +0200 (Thu, 04 Sep 2008) New Revision: 4823 Modified: trunk/doc/a-decade-of-gnupg.txt trunk/sm/ChangeLog trunk/sm/certdump.c Log: Workaround for a mingw runtime bug. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-09-03 09:37:32 UTC (rev 4822) +++ trunk/sm/ChangeLog 2008-09-04 10:35:41 UTC (rev 4823) @@ -1,3 +1,7 @@ +2008-09-04 Werner Koch + + * certdump.c (gpgsm_format_keydesc): Work around a mingw32 bug. + 2008-09-03 Werner Koch * sign.c (MY_GCRY_MD_SHA224): New, so that we don't need libgcrypt Modified: trunk/doc/a-decade-of-gnupg.txt =================================================================== --- trunk/doc/a-decade-of-gnupg.txt 2008-09-03 09:37:32 UTC (rev 4822) +++ trunk/doc/a-decade-of-gnupg.txt 2008-09-04 10:35:41 UTC (rev 4823) @@ -198,7 +198,7 @@ === Remarks === -In a reply to this mail Alan Olsen remakrked on the ML: +In a reply to this mail Alan Olsen remarked on the ML: MIT was forced to use the RSAREF library which had a non free license. At first they used the RSAREF2 library, but then they were Modified: trunk/sm/certdump.c =================================================================== --- trunk/sm/certdump.c 2008-09-03 09:37:32 UTC (rev 4822) +++ trunk/sm/certdump.c 2008-09-04 10:35:41 UTC (rev 4823) @@ -979,7 +979,13 @@ buffer = p = xtrymalloc (strlen (name) * 3 + 1); for (s=name; *s; s++) { - if (*s < ' ' || *s == '+') + /* We also escape the quote character to work around a bug in + the mingw32 runtime which does not correcty handle command + line quoting. We correctly double the quote mark when + calling a program (i.e. gpg-protec-tool), but the pre-main + code does not notice the double quote as an escaped + quote. */ + if (*s < ' ' || *s == '+' || *s == '\"') { sprintf (p, "%%%02X", *(unsigned char *)s); p += 3; From cvs at cvs.gnupg.org Thu Sep 4 18:47:35 2008 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 04 Sep 2008 18:47:35 +0200 Subject: [svn] GnuPG - r4824 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: dshaw Date: 2008-09-04 18:47:34 +0200 (Thu, 04 Sep 2008) New Revision: 4824 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/keyserver.c Log: * keyserver.c (keyserver_import_cert): Allow keyserver URLs in addition to full URLs in CERT records. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-09-04 10:35:41 UTC (rev 4823) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-09-04 16:47:34 UTC (rev 4824) @@ -1,3 +1,8 @@ +2008-09-04 David Shaw + + * keyserver.c (keyserver_import_cert): Allow keyserver URLs in + addition to full URLs in CERT records. + 2008-08-11 Werner Koch * keygen.c (ask_expire_interval): Check for time overflow of an Modified: branches/STABLE-BRANCH-1-4/g10/keyserver.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keyserver.c 2008-09-04 10:35:41 UTC (rev 4823) +++ branches/STABLE-BRANCH-1-4/g10/keyserver.c 2008-09-04 16:47:34 UTC (rev 4824) @@ -2018,13 +2018,7 @@ spec=parse_keyserver_uri(url,1,NULL,0); if(spec) { - STRLIST list=NULL; - - add_to_strlist(&list,url); - - rc=keyserver_fetch(list); - - free_strlist(list); + rc=keyserver_import_fprint(*fpr,*fpr_len,spec); free_keyserver_spec(spec); } } From cvs at cvs.gnupg.org Thu Sep 4 18:54:59 2008 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 04 Sep 2008 18:54:59 +0200 Subject: [svn] GnuPG - r4825 - trunk/g10 Message-ID: Author: dshaw Date: 2008-09-04 18:54:58 +0200 (Thu, 04 Sep 2008) New Revision: 4825 Modified: trunk/g10/ChangeLog trunk/g10/keyserver.c Log: * keyserver.c (keyserver_import_cert): Allow keyserver URLs in addition to full URLs in CERT records. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-09-04 16:47:34 UTC (rev 4824) +++ trunk/g10/ChangeLog 2008-09-04 16:54:58 UTC (rev 4825) @@ -1,3 +1,8 @@ +2008-09-04 David Shaw + + * keyserver.c (keyserver_import_cert): Allow keyserver URLs in + addition to full URLs in CERT records. + 2008-08-11 Werner Koch * keygen.c (ask_expire_interval): Check for time overflow of an Modified: trunk/g10/keyserver.c =================================================================== --- trunk/g10/keyserver.c 2008-09-04 16:47:34 UTC (rev 4824) +++ trunk/g10/keyserver.c 2008-09-04 16:54:58 UTC (rev 4825) @@ -2041,13 +2041,7 @@ spec=parse_keyserver_uri(url,1,NULL,0); if(spec) { - strlist_t list=NULL; - - add_to_strlist(&list,url); - - rc=keyserver_fetch(list); - - free_strlist(list); + rc=keyserver_import_fprint(*fpr,*fpr_len,spec); free_keyserver_spec(spec); } } From cvs at cvs.gnupg.org Fri Sep 5 18:00:52 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 05 Sep 2008 18:00:52 +0200 Subject: [svn] gcry - r1314 - in trunk: random src tests Message-ID: Author: wk Date: 2008-09-05 18:00:51 +0200 (Fri, 05 Sep 2008) New Revision: 1314 Modified: trunk/random/ChangeLog trunk/random/random-fips.c trunk/random/random.c trunk/src/ChangeLog trunk/src/fips.c trunk/src/g10lib.h trunk/src/gcrypt.h.in trunk/src/global.c trunk/tests/basic.c Log: Let the test suite run the selftests even in non-fips mode. Modified: trunk/random/ChangeLog =================================================================== --- trunk/random/ChangeLog 2008-09-03 10:42:11 UTC (rev 1313) +++ trunk/random/ChangeLog 2008-09-05 16:00:51 UTC (rev 1314) @@ -1,3 +1,8 @@ +2008-09-05 Werner Koch + + * random.c (_gcry_random_selftest): Return success if not in fips + mode. + 2008-09-01 Werner Koch * random-fips.c (x931_get_dt) [W32]: Do not use getppid. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-03 10:42:11 UTC (rev 1313) +++ trunk/src/ChangeLog 2008-09-05 16:00:51 UTC (rev 1314) @@ -1,3 +1,10 @@ +2008-09-05 Werner Koch + + * gcrypt.h.in (GCYRCTL_SELFTEST): New. + * global.c (_gcry_vcontrol): Implement. + * fips.c (_gcry_fips_run_selftests): Do state transitions only if + in fips mode. Return an error code. + 2008-09-01 Werner Koch * stdmem.c: Re-indented. Modified: trunk/random/random-fips.c =================================================================== --- trunk/random/random-fips.c 2008-09-03 10:42:11 UTC (rev 1313) +++ trunk/random/random-fips.c 2008-09-05 16:00:51 UTC (rev 1314) @@ -783,6 +783,9 @@ gcry_error_t _gcry_rngfips_add_bytes (const void *buf, size_t buflen, int quality) { + (void)buf; + (void)buflen; + (void)quality; return 0; /* Not implemented. */ } Modified: trunk/random/random.c =================================================================== --- trunk/random/random.c 2008-09-03 10:42:11 UTC (rev 1313) +++ trunk/random/random.c 2008-09-05 16:00:51 UTC (rev 1314) @@ -280,6 +280,6 @@ if (fips_mode ()) return _gcry_rngfips_selftest (report); else - return gpg_error (GPG_ERR_NOT_SUPPORTED); + return 0; /* No selftests yet. */ } Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2008-09-03 10:42:11 UTC (rev 1313) +++ trunk/src/fips.c 2008-09-05 16:00:51 UTC (rev 1314) @@ -200,8 +200,8 @@ /* This function returns true if fips mode is enabled. This is independent of the fips required finite state machine and only used - to enable run fips specific code. Please use the fips_mode macro - instead of calling this fucntion directly. */ + to enable fips specific code. Please use the fips_mode macro + instead of calling this function directly. */ int _gcry_fips_mode (void) { @@ -520,12 +520,14 @@ /* Run the self-tests. */ -void +gpg_err_code_t _gcry_fips_run_selftests (void) { enum module_states result = STATE_ERROR; + gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED; - fips_new_state (STATE_SELFTEST); + if (fips_mode ()) + fips_new_state (STATE_SELFTEST); if (run_cipher_selftests ()) goto leave; @@ -549,9 +551,13 @@ /* All selftests passed. */ result = STATE_OPERATIONAL; + ec = 0; leave: - fips_new_state (result); + if (fips_mode ()) + fips_new_state (result); + + return ec; } Modified: trunk/src/g10lib.h =================================================================== --- trunk/src/g10lib.h 2008-09-03 10:42:11 UTC (rev 1313) +++ trunk/src/g10lib.h 2008-09-05 16:00:51 UTC (rev 1314) @@ -316,7 +316,7 @@ int _gcry_fips_test_operational (void); int _gcry_fips_test_error_or_operational (void); -void _gcry_fips_run_selftests (void); +gpg_err_code_t _gcry_fips_run_selftests (void); void _gcry_fips_noreturn (void); #define fips_noreturn() (_gcry_fips_noreturn ()) Modified: trunk/src/gcrypt.h.in =================================================================== --- trunk/src/gcrypt.h.in 2008-09-03 10:42:11 UTC (rev 1313) +++ trunk/src/gcrypt.h.in 2008-09-05 16:00:51 UTC (rev 1314) @@ -408,7 +408,8 @@ GCRYCTL_PRINT_CONFIG = 53, GCRYCTL_OPERATIONAL_P = 54, GCRYCTL_FIPS_MODE_P = 55, - GCRYCTL_FORCE_FIPS_MODE = 56 + GCRYCTL_FORCE_FIPS_MODE = 56, + GCRYCTL_SELFTEST = 57 }; /* Perform various operations defined by CMD. */ Modified: trunk/src/global.c =================================================================== --- trunk/src/global.c 2008-09-03 10:42:11 UTC (rev 1313) +++ trunk/src/global.c 2008-09-05 16:00:51 UTC (rev 1314) @@ -475,6 +475,13 @@ } break; + case GCRYCTL_SELFTEST: + /* Run a selftest. This works in fips mode as weel as in + standard mode. Returns 0 on success or an error code. */ + global_init (); + err = _gcry_fips_run_selftests (); + break; + default: err = GPG_ERR_INV_OP; } Modified: trunk/tests/basic.c =================================================================== --- trunk/tests/basic.c 2008-09-03 10:42:11 UTC (rev 1313) +++ trunk/tests/basic.c 2008-09-05 16:00:51 UTC (rev 1314) @@ -2105,9 +2105,9 @@ check_hmac (); check_pubkey (); - /* If we are in fips mode do some more tests. */ if (in_fips_mode) { + /* If we are in fips mode do some more tests. */ gcry_md_hd_t md; /* First trigger a self-test. */ @@ -2130,6 +2130,8 @@ /* gcry_md_get_algo is only defined for a context with just one digest algorithm. With our setup it should put the oibrary intoerror state. */ + fputs ("Note: Two lines with error messages follow " + "- this is expected\n", stderr); gcry_md_get_algo (md); gcry_md_close (md); if (gcry_control (GCRYCTL_OPERATIONAL_P, 0)) @@ -2147,7 +2149,11 @@ } } - + else + { + /* If in standard mode, run selftests. */ + gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + } if (verbose) fprintf (stderr, "\nAll tests completed. Errors: %i\n", error_count); From cvs at cvs.gnupg.org Fri Sep 5 20:06:09 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 05 Sep 2008 20:06:09 +0200 Subject: [svn] gcry - r1315 - in trunk: . doc Message-ID: Author: wk Date: 2008-09-05 20:06:09 +0200 (Fri, 05 Sep 2008) New Revision: 1315 Modified: trunk/README trunk/doc/gcrypt.texi Log: Updated the architecture chapter Modified: trunk/README =================================================================== --- trunk/README 2008-09-05 16:00:51 UTC (rev 1314) +++ trunk/README 2008-09-05 18:06:09 UTC (rev 1315) @@ -176,9 +176,9 @@ The library is distributed under the terms of the GNU Lesser General Public License (LGPL); see the file COPYING.LIB for the - actual terms. The helper programs (gcryptrnd and getrandom) as - well as the documentation are distributed under the terms of the - GNU General Public License (GPL); see the file COPYING for teh + actual terms. The helper programs (e.g. gcryptrnd and getrandom) + as well as the documentation are distributed under the terms of + the GNU General Public License (GPL); see the file COPYING for the actual terms. This library used to be available under the GPL - this was changed Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-05 16:00:51 UTC (rev 1314) +++ trunk/doc/gcrypt.texi 2008-09-05 18:06:09 UTC (rev 1315) @@ -772,7 +772,12 @@ application switch the library into FIPS mode. Note that Libgcrypt will reject an attempt to switch to fips mode during or after the intialization. + at item GCRYCTL_SELFTEST; Arguments: none +This may be used at anytime to have the library run all implemented +selftests. It works in standard and in FIPS mode. Returns 0 on +success or an error code. + @end table @end deftypefun @@ -4033,14 +4038,7 @@ 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 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. - - at noindent +library, its interface is exposed by Libgcrypt. In the context of Libgcrypt and in most other applications, these large numbers are called MPIs (multi-precision-integers). @@ -4508,7 +4506,7 @@ Provisions have been take so that the library can be directly used from C++ applications; however building with a C++ compiler is not supported. -Building libgcrypt is done by using the common @code{./configure && make} +Building Libgcrypt is done by using the common @code{./configure && make} approach. The configure command is included in the source distribution and as a portable shell script it works on any Unix-alike system. The result of running the configure script are a C header file @@ -4539,18 +4537,18 @@ all these subsystems provide a public API; this includes the helper subsystems like the one for S-expression. The API style depends on the subsystem; in general an open, use, close approach is implemented. The -open returns a handle to a context used for all futher operations on +open returns a handle to a context used for all further operations on this handle, several functions may then be used on this handle and a final close function releases all resources associated with the handle. @menu -* Public-Key Subsystem Architecture:: All about public keys. -* Symmetric Encryption Subsystem Architecture:: All about standard ciphers. -* Hashing and MACing Subsystem Architecture:: All about hashing. -* Multi-Precision-Integer Subsystem Architecture:: All about big integers. -* Prime-Number-Generator Subsystem Architecture:: All about prime numbers. -* Random-Number Subsystem Architecture:: All about random stuff. -* Helper Subsystems Architecture:: All about other stuff. +* Public-Key Subsystem Architecture:: About public keys. +* Symmetric Encryption Subsystem Architecture:: About standard ciphers. +* Hashing and MACing Subsystem Architecture:: About hashing. +* Multi-Precision-Integer Subsystem Architecture:: About big integers. +* Prime-Number-Generator Subsystem Architecture:: About prime numbers. +* Random-Number Subsystem Architecture:: About random stuff. + at c * Helper Subsystems Architecture:: About other stuff. @end menu @@ -4558,68 +4556,424 @@ @node Public-Key Subsystem Architecture @section Public-Key Architecture -TBD. +Libgcrypt implements two interfaces for public key cryptography: The +standard interface is PK interface using functions in the + at code{gcry_pk_} name space. The AC interface in an alternative one +which is now deprecated and will not be further described. The AC +interface is also disabled in FIPS mode. +Because public key cryptography is almost always used to process small +amounts of data (hash values or session keys), the interface is not +implemented using the open-use-close paradigm, but with single +self-contained functions. Due to the wide variety of parameters +required by different algorithms S-expressions, as flexible way to +convey these parameters, are used. There is a set of helper functions +to work with these S-expressions. + at c see @xref{S-expression Subsystem Architecture}. + +Aside of functions to register new algorithms, map algorithms names to +algorithms identifiers and to lookup properties of a key, the +following main functions are available: + + at table @code + + at item gcry_pk_encrypt +Encrypt data using a public key. + + at item gcry_pk_decrypt +Decrypt data using a private key. + + at item gcry_pk_sign +Sign data using a private key. + + at item gcry_pk_verify +Verify that a signature matches the data. + + at item gcry_pk_testkey +Perform a consistency over a public or private key. + + at item gcry_pk_genkey +Create a new public/private key pair. + + at end table + +With the help of the module registration system all these functions +lookup the module implementing the algorithm and pass the actual work +to that module. The parsing of the S-expression input and the +construction of S-expression for the return values is done by the high +level code (@file{cipher/pubkey.c}). Thus the internal interface +between the algorithm modules and the high level functions passes data +in a custom format. The interface to the modules is published +(@file{gcrypt-modules.h}) so that it can used to register external +implementations of algorithms with Libgcrypt. However, for some algorithms this +module interface is to limited and thus for the internal modules an +extra interface is sometimes used to convey more information. + + @node Symmetric Encryption Subsystem Architecture - at section Symmetric Encryption Subsystem Architecturen + at section Symmetric Encryption Subsystem Architecture -TBD. +The interface to work with symmetric encryption algorithms is made up +of functions from the @code{gcry_cipher_} name space. The +implementation follows the open-use-close paradigm and uses registered +algorithm modules for the actual work. Unless a module implements +optimized cipher mode implementations, the high level code +(@file{cipher/cipher.c}) implements the modes and calls the core +algorithm functions to process each block. +The most important functions are: + + at table @code + + at item gcry_cipher_open +Create a new instance to encrypt or decrypt using a specified +algorithm and mode. + + at item gcry_cipher_close +Release an instance. + + at item gcry_cipher_setkey +Set a key to be used for encryption or decryption. + + at item gcry_cipher_setiv +Set an initialization vector to be used for encryption or decryption. + + at item gcry_cipher_encrypt + at itemx gcry_cipher_decrypt +Encrypt or decrypt data. These functions may be called with arbitrary +amounts of data and as often as needed to encrypt or decrypt all data. + + at end table + +There are also functions to query properties of algorithms or context, +like block length, key length, map names or to enable features like +padding methods. + + + @node Hashing and MACing Subsystem Architecture @section Hashing and MACing Subsystem Architecture -TBD. +The interface to work with message digests and CRC algorithms is made +up of functions from the @code{gcry_md_} name space. The +implementation follows the open-use-close paradigm and uses registered +algorithm modules for the actual work. Although CRC algorithms are +not considered cryptographic hash algorithms, they share enough +properties so that it makes sense to handle them in the same way. +It is possible to use several algorithms at once with one context and +thus compute them all on the same data. +The most important functions are: + at table @code + at item gcry_md_open +Create a new message digest instance and optionally enable one +algorithm. A flag may be used to turn the message digest algorithm +into a HMAC algorithm. + + at item gcry_md_enable +Enable an additional algorithm for the instance. + + at item gcry_md_setkey +Set the key for the MAC. + + at item gcry_md_write +Pass more data for computing the message digest to an instance. + + at item gcry_md_putc +Buffered version of @code{gcry_md_write} implemented as a macro. + + at item gcry_md_read +Finalize the computation of the message digest or HMAC and return the +result. + + at item gcry_md_close +Release an instance + + at item gcry_md_hash_buffer +Convenience function to directly compute a message digest over a +memory buffer without the need to create an instance first. + + at end table + +There are also functions to query properties of algorithms or the +instance, like enabled algorithms, digest length, map algorithm names. +it is also possible to reset an instance or to copy the current state +of an instance at any time. Debug functions to write the hashed data +to files are available as well. + + + @node Multi-Precision-Integer Subsystem Architecture @section Multi-Precision-Integer Subsystem Architecture -TBD. +The implementation of Libgcrypt's big integer computation code is +based on an old release of GNU Multi-Precision Library (GMP). The +decision not to use the GMP library directly was due to stalled +development at that time and due to security requirements which could +not be provided by the code in GMP. As GMP does, Libgcrypt provides +high performance assembler implementations of low level code for +several CPUS to gain much better performance than with a generic C +implementation. + at noindent +Major features of Libgcrypt's multi-precision-integer code compared to +GMP are: + + at itemize + at item +Avoidance of stack based allocations to allow protection against +swapping out of sensitive data and for easy zeroing of sensitive +intermediate results. + + at item +Optional use of secure memory and tracking of its use so that results +are also put into secure memory. + + at item +MPIs are identified by a handle (implemented as a pointer) to give +better control over allocations and to augment them with extra +properties like opaque data. + + at item +Removal of unnecessary code to reduce complexity. + + at item +Functions specialized for public key cryptography. + + at end itemize + + + @node Prime-Number-Generator Subsystem Architecture @section Prime-Number-Generator Subsystem Architecture -TBD. +Libgcrypt provides an interface to its prime number generator. These +functions make use of the internal prime number generator which is +required for the generation for public key key pairs. The plain prime +checking function is exported as well. +The generation of random prime numbers is based on the Lim and Lee +algorithm to create practically save primes. at footnote{Chae Hoon Lim +and Pil Joong Lee. A key recovery attack on discrete log-based shemes +using a prime order subgroup. In Burton S. Kaliski Jr., editor, +Advances in Cryptology: Crypto '97, pages 249?-263, Berlin / +Heidelberg / New York, 1997. Springer-Verlag. Described on page 260.} +This algorithm creates a pool of smaller primes, select a few of them +to create candidate primes of the form @math{2 * p_0 * p_1 * ... * p_n ++ 1}, tests the candidate for primality and permutates the pool until +a prime has been found. It is possible to clamp one of the small +primes to a certain size to help DSA style algorithms. Because most +of the small primes in the pool are not used for the resulting prime +number, they are saved for later use (see @code{save_pool_prime} and + at code{get_pool_prime} in @file{cipher/primegen.c}). The prime +generator optionally supports the finding of an appropriate generator. + + at noindent +The primality test works in three steps: + + at enumerate + at item +The standard sieve algorithm using the primes up to 4999 is used as a +quick first check. + + at item +A Fermat test filters out almost all non-primes. + + at item +A 5 round Rabin-Miller test is finally used. The first round uses a +witness of 2, whereas the next rounds use a random witness. + + at end enumerate + @node Random-Number Subsystem Architecture @section Random-Number Subsystem Architecture -TBD. +Libgcrypt provides 3 levels or random quality: The level + at code{GCRY_VERY_STRONG_RANDOM} usually used for key generation, the +level @code{GCRY_STRONG_RANDOM} for all other strong random +requirements and the function @code{gcry_create_nonce} which is used +for weaker usages like nonces. There is also a level + at code{GCRY_WEAK_RANDOM} which in general maps to + at code{GCRY_STRONG_RANDOM} except when used with the function + at code{gcry_mpi_randomize}, where it randomizes an +multi-precision-integer using the @code{gcry_create_nonce} function. + at noindent +There are two distinct random generators available: - at node Helper Subsystems Architecture - at section Helper Subsystems Architecture + at itemize + at item +The Continuously Seeded Pseudo Random Number Generator (CSPRNG), which +is based on the classic GnuPG derived big pool implementation. +Implemented in @code{random/random-csprng.c} and used by default. + at item +A FIPS approved ANSI X9.31 PRNG using AES with a 128 bit key. Implemented in + at code{random/random-fips.c} and used if Libgcrypt is in FIPS mode. + at end itemize -There are a few smaller subsystems which are mainly used internally by -Libgcrypt but also available to applications. + at noindent +Both generators make use of so-called entropy gathering modules: + at table @asis + at item rndlinux +Uses the operating system provided + at file{/dev/random} and @file{/dev/urandom} devices. + + at item rndunix +Runs several operating system commands to collect entropy from sources +like virtual machine and process statistics. It is a kind of +poor-man's @code{/dev/random} implementation. It is not available in +FIPS mode. + + at item rndegd +Uses the operating system provided Entropy Gathering Daemon (EGD). +The EGD basically uses the same algorithms as rndunix does. However +as a system daemon it keeps on running and thus can serve several +processes requiring entropy input and does not waste collected entropy +if the application does not need all the collected entropy. It is not +available in FIPS mode. + + at item rndw32 +Targeted for the Microsoft Windows OS. It uses certain properties of +that system and is the only gathering module available for that OS. + + at item rndhw +Extra module to collect additional entropy by utilizing a hardware +random number generator. As of now the only supported hardware RNG is +the Padlock engine of VIA (Centaur) CPUs. It is not available in FIPS +mode. + + at end table + + @menu -* S-expression Subsystem Architecture:: Details about the S-expression architecture. -* Memory Subsystem Architecture:: Details about the memory allocation architecture. -* Miscellaneous Subsystems Architecture:: Details about other subsystems. +* CSPRNG Description:: Description of the CSPRNG. +* FIPS PRNG Description:: Description of the FIPS X9.31 PRNG. @end menu - at node S-expression Subsystem Architecture - at subsection S-expression Subsystem Architecture -TBD. + at node CSPRNG Description + at subsection Description of the CSPRNG +This random number generator is loosely modelled after the one +described in Peter Gutmann's paper: "Software Generation of +Practically Strong Random Numbers". at footnote{Also described in chapter +6 of his book "Cryptographic Security Architecture", New York, 2004, +ISBN 0-387-95387-6.} - at node Memory Subsystem Architecture - at subsection Memory Subsystem Architecture +A pool of 600 bytes is used and mixed using the core RIPE-MD160 hash +transform function. Several extra features are used to make the +robust against a wide variety of attacks and to protect against +failures of subsystems. The state of the generator may be saved to a +file and initially seed form a file. -TBD. +Depending on how Libgcrypt was build the generator is able to select +the best working entropy gathering module. It makes use of the slow +and fast collection methods and requires the pool to initially seeded +form the slow gatherer or a seed file. An entropy estimation is used +to mix in enough data from the gather modules before returning the +actual random output. Process fork detection and protection is +implemented. + at c FIXME: The design and implementaion needs a more verbose description. - at node Miscellaneous Subsystems Architecture - at subsection Miscellaneous Subsystems Architecture +The implementation of the nonce generator (for + at code{gcry_create_nonce}) is a straightforward repeated hash design: A +28 byte buffer is initially seeded with the PID and the time in +seconds in the first 20 bytes and with 8 bytes of random taken from +the @code{GCRY_STRONG_RANDOM} generator. Random numbers are then +created by hashing all the 28 bytes with SHA-1 and saving that again +in the first 20 bytes. The hash is also returned as result. -TBD. + at node FIPS PRNG Description + at subsection Description of the FIPS X9.31 PRNG +The core of this deterministic random number generator is implemented +according to the document ``NIST-Recommended Random Number Generator +Based on ANSI X9.31 Appendix A.2.4 Using the 3-Key Triple DES and AES +Algorithms'', dated 2005-01-31. This implementation uses the AES +variant. +The generator is based on contexts to utilize the same core functions +for all random levels as required by the high-level interface. All +random generators return their data in 128 bit blocks. If the caller +requests less bits, the extra bits are not used. The key for each +generator is only set once at the first time a generator context is +used. The seed value is set along with the key and again after 1000 +output blocks. +On Unix like systems the @code{GCRY_VERY_STRONG_RANDOM} and + at code{GCRY_STRONG_RANDOM} generators are keyed and seeded using the +rndlinux module with the @file{/dev/radnom} device. Thus these +generators may block until the OS kernel has collected enough entropy. +When used with Microsoft Windows the rndw32 module is used instead. +The generator used for @code{gcry_create_nonce} is keyed and seeded +from the @code{GCRY_STRONG_RANDOM} generator. Thus is may also block +if the @code{GCRY_STRONG_RANDOM} generator has not yet been used +before and thus gets initialized on the first use by + at code{gcry_create_nonce}. This special treatment is justified by the +weaker requirements for a nonce generator and to save precious kernel +entropy for use by the ``real'' random generators. + +A self test facility uses a separate context to check the +functionality of the core X9.31 functions using a known answers test. +During runtime each output block is compared to the previous one to +detect a stucked generator. + +The DT value for the generator is made up of the current time down to +microseconds (if available) and a free running 64 bit counter. When +used with the test context the DT value is taken from the context and +incremented on each use. + + + + at c @node Helper Subsystems Architecture + at c @section Helper Subsystems Architecture + at c + at c There are a few smaller subsystems which are mainly used internally by + at c Libgcrypt but also available to applications. + at c + at c @menu + at c * S-expression Subsystem Architecture:: Details about the S-expression architecture. + at c * Memory Subsystem Architecture:: Details about the memory allocation architecture. + at c * Miscellaneous Subsystems Architecture:: Details about other subsystems. + at c @end menu + at c + at c @node S-expression Subsystem Architecture + at c @subsection S-expression Subsystem Architecture + at c + at c Libgcrypt provides an interface to S-expression to create and parse + at c them. To use an S-expression with Libgcrypt it needs first be + at c converted into the internal representation used by Libgcrypt (the type + at c @code{gcry_sexp_t}). The conversion functions support a large subset + at c of the S-expression specification and further fature a printf like + at c function to convert a list of big integers or other binary data into + at c an S-expression. + at c + at c Libgcrypt currently implements S-expressions using a tagged linked + at c list. However this is not exposed to an application and may be + at c changed in future releases to reduce overhead when already working + at c with canonically encoded S-expressions. Secure memory is supported by + at c this S-expressions implementation. + at c + at c @node Memory Subsystem Architecture + at c @subsection Memory Subsystem Architecture + at c + at c TBD. + at c + at c + at c @node Miscellaneous Subsystems Architecture + at c @subsection Miscellaneous Subsystems Architecture + at c + at c TBD. + at c + at c + + + @c ********************************************************** @c ******************* Appendices ************************* @c ********************************************************** @@ -4890,7 +5244,7 @@ GCRYCTL_SET_RANDOM_DAEMON_SOCKET GCRYCTL_USE_RANDOM_DAEMON The random damon is still a bit experimental, thus we do not document -them. Not ethat they should be used during initialization and that +them. Note that they should be used during initialization and that these functions are not really thread safe. From cvs at cvs.gnupg.org Fri Sep 5 23:01:17 2008 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Fri, 05 Sep 2008 23:01:17 +0200 Subject: [svn] GnuPG - r4826 - branches/STABLE-BRANCH-1-4/util Message-ID: Author: dshaw Date: 2008-09-05 23:01:17 +0200 (Fri, 05 Sep 2008) New Revision: 4826 Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/Makefile.am Log: * Makefile.am: Use $(CC) instead of "cc" to compile, as the user might be overriding the compiler. Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2008-09-04 16:54:58 UTC (rev 4825) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2008-09-05 21:01:17 UTC (rev 4826) @@ -1,3 +1,8 @@ +2008-09-05 David Shaw + + * Makefile.am: Use $(CC) instead of "cc" to compile, as the user + might be overriding the compiler. + 2008-08-19 Werner Koch * iobuf.c: Avoid passing a NULL (iobuf_t)->desc to the log Modified: branches/STABLE-BRANCH-1-4/util/Makefile.am =================================================================== --- branches/STABLE-BRANCH-1-4/util/Makefile.am 2008-09-04 16:54:58 UTC (rev 4825) +++ branches/STABLE-BRANCH-1-4/util/Makefile.am 2008-09-05 21:01:17 UTC (rev 4826) @@ -64,17 +64,17 @@ libcompat_a_LIBADD = @LIBOBJS@ http-test: http.c - cc -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \ + $(CC) -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \ -DTEST -o http-test http.c libutil.a @LIBINTL@ @DNSLIBS@ @CAPLIBS@ srv-test: srv.c - cc -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \ + $(CC) -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \ -DTEST -o srv-test srv.c libutil.a @LIBINTL@ @DNSLIBS@ @CAPLIBS@ pka-test: pka.c - cc -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \ + $(CC) -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \ -DTEST -o pka-test pka.c libutil.a @LIBINTL@ @DNSLIBS@ @CAPLIBS@ cert-test: cert.c - cc -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \ + $(CC) -DHAVE_CONFIG_H -I. -I. -I.. $(INCLUDES) $(LDFLAGS) -g -Wall \ -DTEST -o cert-test cert.c libutil.a @LIBINTL@ @DNSLIBS@ @CAPLIBS@ From cvs at cvs.gnupg.org Mon Sep 8 18:56:37 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 08 Sep 2008 18:56:37 +0200 Subject: [svn] gcry - r1316 - in trunk: . doc Message-ID: Author: wk Date: 2008-09-08 18:56:37 +0200 (Mon, 08 Sep 2008) New Revision: 1316 Modified: trunk/AUTHORS trunk/ChangeLog trunk/NEWS trunk/README trunk/configure.ac trunk/doc/ChangeLog trunk/doc/gcrypt.texi trunk/doc/gpl.texi trunk/doc/lgpl.texi Log: doc cleanups Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-09-05 18:06:09 UTC (rev 1315) +++ trunk/ChangeLog 2008-09-08 16:56:37 UTC (rev 1316) @@ -1,3 +1,7 @@ +2008-09-08 Werner Koch + + Release 1.4.2. + 2008-09-01 Werner Koch Release 1.4.2rc2. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-09-05 18:06:09 UTC (rev 1315) +++ trunk/doc/ChangeLog 2008-09-08 16:56:37 UTC (rev 1316) @@ -1,3 +1,9 @@ +2008-09-08 Werner Koch + + * gcrypt.texi: Formatting cleanups. + * lgpl.texi (Library Copying): Replace @appendix by @unnumbered. + * gpl.texi (Copying): Ditto. + 2008-08-27 Werner Koch * Makefile.am (online): Take care of development versions. Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2008-09-05 18:06:09 UTC (rev 1315) +++ trunk/AUTHORS 2008-09-08 16:56:37 UTC (rev 1316) @@ -59,7 +59,7 @@ GNUTLS Nikolaos Mavrogiannopoulos 2003-11-22 nmav at gnutls.org -Orginal code for cipher/rfc2268.c. +Original code for cipher/rfc2268.c. LIBGCRYPT The Written Word 2005-04-15 Assigns past and future changes. (new: src/libgcrypt.pc.in, Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-09-05 18:06:09 UTC (rev 1315) +++ trunk/NEWS 2008-09-08 16:56:37 UTC (rev 1316) @@ -1,4 +1,4 @@ -Noteworthy changes in version 1.4.2 (unreleased) +Noteworthy changes in version 1.4.2 (2008-09-08) ------------------------------------------------ * The long missing gcry_mpi_lshift function has been added. Modified: trunk/README =================================================================== --- trunk/README 2008-09-05 18:06:09 UTC (rev 1315) +++ trunk/README 2008-09-08 16:56:37 UTC (rev 1316) @@ -1,6 +1,6 @@ - libgcrypt - The GNU crypto library + Libgcrypt - The GNU Crypto Library ------------------------------------ - Version 1.4.2rc2 + Version 1.4.2 Copyright 2000, 2002, 2003, 2004, 2007, Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-09-05 18:06:09 UTC (rev 1315) +++ trunk/configure.ac 2008-09-08 16:56:37 UTC (rev 1316) @@ -27,7 +27,7 @@ # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. m4_define([my_version], [1.4.2]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-05 18:06:09 UTC (rev 1315) +++ trunk/doc/gcrypt.texi 2008-09-08 16:56:37 UTC (rev 1316) @@ -19,7 +19,7 @@ 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''. +section entitled ``GNU General Public License''. @end quotation @end copying @@ -316,7 +316,7 @@ be used. So you may want to check that the version is okay right after program startup. - at deftypefun const char *gcry_check_version (const char *@var{req_version}) + at deftypefun {const char *} gcry_check_version (const char *@var{req_version}) The function @code{gcry_check_version} initializes some subsystems used by Libgcrypt and must be invoked before any other function in the @@ -475,10 +475,10 @@ strict rules may apply.}. @item - Just like the function @code{gpg_strerror}, the function @code{gcry_strerror} is not thread safe. You have to use @code{gpg_strerror_r} instead. + @end itemize @@ -517,8 +517,8 @@ @node FIPS mode @section FIPS Mode -Libgcrypt may be used in a FIPS 140 mode. Note, that this does not -necessary mean that Libcgrypt is n appoved FIPS 140-2 module. Check the +Libgcrypt may be used in a FIPS 140-2 mode. Note, that this does not +necessary mean that Libcgrypt is an appoved FIPS 140-2 module. Check the NIST database at @url{http://csrc.nist.gov/groups/STM/cmvp/} to see what versions of Libgcrypt are approved. @@ -532,7 +532,7 @@ If the file @file{/proc/sys/crypto/fips_enabled} exists and contains a numeric value other than @code{0}, Libgcrypt is put into FIPS mode at initialization time. Obviously this works only on systems with a - at code{proc} file system (ie.e GNU/Linux). + at code{proc} file system (i.e. GNU/Linux). @item If the file @file{/etc/gcrypt/fips140.force} exists, Libgcrypt is put @@ -540,16 +540,16 @@ hardwired and does not depend on any configuration options. @item -If the applications requests FIPS mode using the control command +If the application requests FIPS mode using the control command @code{GCRYCTL_FORCE_FIPS_MODE}. This must be done prior to any initialization (i.e. before @code{gcry_check_version}). @end itemize -Note that once Libgcrypt has been put into FIPS mode, it is not possible -to switch back to standard mode without terminating the process first. -If the log verbosity level of Libgcrypt has been set to at least 2, the -state transitions and the selftests are logged. +Once Libgcrypt has been put into FIPS mode, it is not possible to +switch back to standard mode without terminating the process first. +If the logging verbosity level of Libgcrypt has been set to at least +2, the state transitions and the selftests are logged. @@ -775,7 +775,7 @@ @item GCRYCTL_SELFTEST; Arguments: none This may be used at anytime to have the library run all implemented selftests. It works in standard and in FIPS mode. Returns 0 on -success or an error code. +success or an error code on failure. @end table @@ -1593,10 +1593,11 @@ @xref{Available cipher modes}, for a list of supported cipher modes 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. +(@code{GCRY_CIPHER_MODE_STREAM}) only works with stream ciphers. Any +block cipher mode (@code{GCRY_CIPHER_MODE_ECB}, + at code{GCRY_CIPHER_MODE_CBC}, @code{GCRY_CIPHER_MODE_CFB}, + at code{GCRY_CIPHER_MODE_OFB} or @code{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. @@ -1789,7 +1790,7 @@ @end deftypefun @c end gcry_cipher_algo_info - at deftypefun const char *gcry_cipher_algo_name (int @var{algo}) + at 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 @@ -1851,9 +1852,10 @@ @uref{http://people.csail.mit.edu/@/rivest/@/sexp.html}) and does not work with contexts as most of the other building blocks of Libgcrypt do. + at noindent The following information are stored in S-expressions: - at table @asis + at itemize @asis @item keys @item plain text data @@ -1862,7 +1864,7 @@ @item signatures - at end table + at end itemize @noindent To describe how Libgcrypt expect keys, we use examples. Note that @@ -2785,7 +2787,7 @@ @var{data_cp}. FIXME: exact semantics undefined. @end deftypefun - at deftypefun unsigned int gcry_ac_data_length (gcry_ac_data_t @var{data}) + at 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 @@ -3541,7 +3543,7 @@ The way to read out the calculated message digest is by using the function: - at deftypefun unsigned char *gcry_md_read (gcry_md_hd_t @var{h}, int @var{algo}) + at 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 @@ -3580,7 +3582,7 @@ used by names, so two functions are available to map between string representations and hash algorithm identifiers. - at deftypefun const char *gcry_md_algo_name (int @var{algo}) + at 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 function returns the @@ -3624,7 +3626,7 @@ If the length of a message digest is not known, it can be retrieved using the following function: - at deftypefun unsigned int gcry_md_get_algo_dlen (int @var{algo}) + at 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 @@ -3715,19 +3717,19 @@ @acronym{Libgcypt} offers random numbers of different quality levels: - at deftp {Data type} enum gcry_random_level -The constants for the random quality levels are of this type. + at deftp {Data type} gcry_random_level_t +The constants for the random quality levels are of this enum type. @end deftp @table @code @item GCRY_WEAK_RANDOM For all functions, except for @code{gcry_mpi_randomize}, this level maps -to GCRY_STRONG_RANDOM. IF you do not want this, consider using +to GCRY_STRONG_RANDOM. If you do not want this, consider using @code{gcry_create_nonce}. @item GCRY_STRONG_RANDOM -Use this level for e.g. session keys and similar purposes. +Use this level for session keys and similar purposes. @item GCRY_VERY_STRONG_RANDOM -Use this level for e.g. key material. +Use this level for long term key material. @end table @node Retrieving random numbers @@ -3739,14 +3741,14 @@ as defined by @var{level}. @end deftypefun - at deftypefun void * gcry_random_bytes (size_t @var{nbytes}, enum gcry_random_level @var{level}) + at deftypefun {void *} gcry_random_bytes (size_t @var{nbytes}, enum gcry_random_level @var{level}) Convenience function to allocate a memory block consisting of @var{nbytes} fresh random bytes using a random quality as defined by @var{level}. @end deftypefun - at deftypefun void * gcry_random_bytes_secure (size_t @var{nbytes}, enum gcry_random_level @var{level}) + at deftypefun {void *} gcry_random_bytes_secure (size_t @var{nbytes}, enum gcry_random_level @var{level}) Convenience function to allocate a memory block consisting of @var{nbytes} fresh random bytes using a random quality as defined by @@ -3999,7 +4001,7 @@ @end example @end deftypefun - at deftypefun char *gcry_sexp_nth_string (@w{gcry_sexp_t @var{list}}, @w{int @var{number}}) + at deftypefun {char *} gcry_sexp_nth_string (@w{gcry_sexp_t @var{list}}, @w{int @var{number}}) This function is used to get and convert data from a @var{list}. The data is assumed to be a Nul terminated string. The caller must @@ -4045,8 +4047,8 @@ @node Data types @section Data types - at deftp {Data type} gcry_mpi_t -The @code{gcry_mpi_t} type represents an object to hold an MPI. + at deftp {Data type} {gcry_mpi_t} +This type represents an object to hold an MPI. @end deftp @node Basic functions @@ -4418,7 +4420,7 @@ might be used to influence the prime number generation process. @end deftypefun - at deftypefun gcry_prime_group_generator (gcry_mpi_t *@var{r_g}, + at deftypefun gcry_error_t 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 @@ -4456,18 +4458,18 @@ @node Memory allocation @section Memory allocation - at deftypefun void *gcry_malloc (size_t @var{n}) + at 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 - at deftypefun void *gcry_malloc_secure (size_t @var{n}) + at deftypefun {void *} gcry_malloc_secure (size_t @var{n}) Like @code{gcry_malloc}, but uses secure memory. @end deftypefun - at deftypefun void *gcry_calloc (size_t @var{n}) + at 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 @@ -4475,11 +4477,11 @@ returns NULL. @end deftypefun - at deftypefun void *gcry_calloc_secure (size_t @var{n}) + at deftypefun {void *} gcry_calloc_secure (size_t @var{n}) Like @code{gcry_calloc}, but uses secure memory. @end deftypefun - at deftypefun void *gcry_realloc (void *@var{p}, size_t @var{n}) + at 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 @@ -4535,8 +4537,8 @@ Libgcrypt consists of several subsystems (@pxref{fig:subsystems}) and all these subsystems provide a public API; this includes the helper -subsystems like the one for S-expression. The API style depends on the -subsystem; in general an open, use, close approach is implemented. The +subsystems like the one for S-expressions. The API style depends on the +subsystem; in general an open-use-close approach is implemented. The open returns a handle to a context used for all further operations on this handle, several functions may then be used on this handle and a final close function releases all resources associated with the handle. Modified: trunk/doc/gpl.texi =================================================================== --- trunk/doc/gpl.texi 2008-09-05 18:06:09 UTC (rev 1315) +++ trunk/doc/gpl.texi 2008-09-08 16:56:37 UTC (rev 1316) @@ -1,5 +1,5 @@ @node Copying - at appendix GNU GENERAL PUBLIC LICENSE + at unnumbered GNU General Public License @cindex GPL, GNU General Public License @center Version 2, June 1991 @@ -12,7 +12,7 @@ of this license document, but changing it is not allowed. @end display - at appendixsubsec Preamble + at heading Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -63,7 +63,7 @@ modification follow. @iftex - at appendixsubsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + at heading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @end iftex @ifinfo @center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @@ -325,7 +325,7 @@ @end ifinfo @page - at unnumberedsec How to Apply These Terms to Your New Programs + at heading How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it Modified: trunk/doc/lgpl.texi =================================================================== --- trunk/doc/lgpl.texi 2008-09-05 18:06:09 UTC (rev 1315) +++ trunk/doc/lgpl.texi 2008-09-08 16:56:37 UTC (rev 1316) @@ -1,5 +1,5 @@ @node Library Copying - at appendix GNU LESSER GENERAL PUBLIC LICENSE + at unnumbered Lesser General Public License @cindex LGPL, Lesser General Public License @center Version 2.1, February 1999 @@ -16,7 +16,7 @@ version number 2.1.] @end display - at appendixsubsec Preamble + at heading Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -119,7 +119,7 @@ be combined with the library in order to run. @iftex - at appendixsubsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + at heading TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION @end iftex @ifinfo @center GNU LESSER GENERAL PUBLIC LICENSE @@ -515,7 +515,7 @@ @end ifinfo @page - at appendixsubsec How to Apply These Terms to Your New Libraries + at heading How to Apply These Terms to Your New Libraries If you develop a new library, and you want it to be of the greatest possible use to the public, we recommend making it free software that From cvs at cvs.gnupg.org Mon Sep 8 19:22:25 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 08 Sep 2008 19:22:25 +0200 Subject: [svn] gcry - r1317 - trunk/doc Message-ID: Author: marcus Date: 2008-09-08 19:22:24 +0200 (Mon, 08 Sep 2008) New Revision: 1317 Modified: trunk/doc/ChangeLog trunk/doc/gcrypt.texi Log: 2008-09-08 Marcus Brinkmann * gcrypt.texi: Some typos fixed. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-09-08 16:56:37 UTC (rev 1316) +++ trunk/doc/ChangeLog 2008-09-08 17:22:24 UTC (rev 1317) @@ -1,3 +1,7 @@ +2008-09-08 Marcus Brinkmann + + * gcrypt.texi: Some typos fixed. + 2008-09-08 Werner Koch * gcrypt.texi: Formatting cleanups. Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-08 16:56:37 UTC (rev 1316) +++ trunk/doc/gcrypt.texi 2008-09-08 17:22:24 UTC (rev 1317) @@ -332,7 +332,7 @@ Libgcrypt uses a concept known as secure memory, which is a region of memory set aside for storing sensitive data. Because such memory is a -scare resource, it needs to be setup in advanced to a fixed size. +scarce resource, it needs to be setup in advanced to a fixed size. Further, most operating systems have special requirements on how that secure memory can be used. For example, it might be required to install an application as ``setuid(root)'' to allow allocating such memory. @@ -500,8 +500,9 @@ @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. +gcry_pthread_mutex_init, gcry_pthread_mutex_destroy, +gcry_pthread_mutex_lock, gcry_pthread_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 @@ -632,11 +633,12 @@ @item GCRYCTL_TERM_SECMEM; Arguments: none This command zeroises the secure memory and destroys the handler. The secure memory pool may not be used anymore after running this command. -If the secure memory pool as already been destroyed, this command has no -effect. Applications might want to run this command from their exit -handler to make sure that the secure memory gets properly destroyed. -This command is not necessary thread-safe but that should not be needed -in cleanup code. It may be called from a signal handler. +If the secure memory pool as already been destroyed, this command has +no effect. Applications might want to run this command from their +exit handler to make sure that the secure memory gets properly +destroyed. This command is not necessarily thread-safe but that +should not be needed in cleanup code. It may be called from a signal +handler. @item GCRYCTL_DISABLE_SECMEM_WARN; Arguments: none Disable warning messages about problems with the secure memory @@ -686,30 +688,30 @@ requested as in this case enough extra entropy gets mixed. It is also not an issue when using Linux (rndlinux driver), because this one guarantees to read full 16 bytes from /dev/urandom and thus there is no -way for an attacker without kernel access to conrol these 16 bytes. +way for an attacker without kernel access to control these 16 bytes. @item GCRYCTL_SET_VERBOSITY; Arguments: int level This command sets the verbosity of the logging. A level of 0 disables all extra logging whereas positive numbers enable more verbose logging. The level may be changed at any time but be aware that no memory -syncronization is done so the effect of this command might not +synchronization is done so the effect of this command might not immediately show up in other threads. This command may even be used -prioe to @code{gcry_check_version}. +prior to @code{gcry_check_version}. @item GCRYCTL_SET_DEBUG_FLAGS; Arguments: unsigned int flags Set the debug flag bits as given by the argument. Be aware that that no -memory syncronization is done so the effect of this command might not +memory synchronization is done so the effect of this command might not immediately show up in other threads. The debug flags are not considered part of the API and thus may change without notice. As of now bit 0 enables debugging of cipher functions and bit 1 debugging of -multi-precision-integers. This command may even be used prioe to +multi-precision-integers. This command may even be used prior to @code{gcry_check_version}. @item GCRYCTL_CLEAR_DEBUG_FLAGS; Arguments: unsigned int flags Set the debug flag bits as given by the argument. Be aware that that no -memory syncronization is done so the effect of this command might not +memory synchronization is done so the effect of this command might not immediately show up in other threads. This command may even be used -prioe to @code{gcry_check_version}. +prior to @code{gcry_check_version}. @item GCRYCTL_DISABLE_INTERNAL_LOCKING; Arguments: none This command does nothing. It exists only for backward compatibility. From cvs at cvs.gnupg.org Mon Sep 8 19:37:15 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 08 Sep 2008 19:37:15 +0200 Subject: [svn] gcry - r1318 - trunk/doc Message-ID: Author: wk Date: 2008-09-08 19:37:15 +0200 (Mon, 08 Sep 2008) New Revision: 1318 Modified: trunk/doc/gcrypt.texi Log: Fix line wrapping Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-08 17:22:24 UTC (rev 1317) +++ trunk/doc/gcrypt.texi 2008-09-08 17:37:15 UTC (rev 1318) @@ -4422,8 +4422,7 @@ might be used to influence the prime number generation process. @end deftypefun - at deftypefun gcry_error_t 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}) + at deftypefun gcry_error_t 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}. From cvs at cvs.gnupg.org Mon Sep 8 20:03:43 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 08 Sep 2008 20:03:43 +0200 Subject: [svn] gcry - r1319 - tags Message-ID: Author: wk Date: 2008-09-08 20:03:43 +0200 (Mon, 08 Sep 2008) New Revision: 1319 Added: tags/libgcrypt-1.4.2/ Log: Release! From cvs at cvs.gnupg.org Mon Sep 8 20:04:35 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 08 Sep 2008 20:04:35 +0200 Subject: [svn] gcry - r1320 - branches Message-ID: Author: wk Date: 2008-09-08 20:04:35 +0200 (Mon, 08 Sep 2008) New Revision: 1320 Added: branches/padlock-test/ Log: New branch vor VIA padlock tests. From cvs at cvs.gnupg.org Tue Sep 9 11:52:58 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 09 Sep 2008 11:52:58 +0200 Subject: [svn] GpgEX - r60 - in trunk: . doc src Message-ID: Author: wk Date: 2008-09-09 11:52:58 +0200 (Tue, 09 Sep 2008) New Revision: 60 Modified: trunk/AUTHORS trunk/NEWS trunk/configure.ac trunk/doc/gpgex.texi trunk/src/gpgex.cc Log: Fix forgotten commit. Prepare release. Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2008-09-01 11:56:06 UTC (rev 59) +++ trunk/AUTHORS 2008-09-09 09:52:58 UTC (rev 60) @@ -1,8 +1,8 @@ Package: gpgex Contact: info-gpgex at g10code.com Bugs: bug-gpgex at g10code.com +License: LGPLv2.1 - g10 Code GmbH New code and package maintainer. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-09-01 11:56:06 UTC (rev 59) +++ trunk/NEWS 2008-09-09 09:52:58 UTC (rev 60) @@ -1,5 +1,11 @@ +Noteworthy changes for version 0.9.1 (2008-09-09) +------------------------------------------------- + +* Take care of CMS file suffixes. + + Noteworthy changes for version 0.9.0 (2008-03-26) ------------------------------------------------- +------------------------------------------------- * Initial release. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-09-01 11:56:06 UTC (rev 59) +++ trunk/configure.ac 2008-09-09 09:52:58 UTC (rev 60) @@ -17,7 +17,7 @@ # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. m4_define([my_version], [0.9.1]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) Modified: trunk/doc/gpgex.texi =================================================================== --- trunk/doc/gpgex.texi 2008-09-01 11:56:06 UTC (rev 59) +++ trunk/doc/gpgex.texi 2008-09-09 09:52:58 UTC (rev 60) @@ -111,7 +111,7 @@ @node Assuan Protocol @chapter Description of the UI Server Protocol -All cryptographic operations are done by this server and the server is +All cryptographic operations are done by a server and the server is responsible for all dialogs. If a a server is not available, @acronym{GpgEX} does not work. Modified: trunk/src/gpgex.cc =================================================================== --- trunk/src/gpgex.cc 2008-09-01 11:56:06 UTC (rev 59) +++ trunk/src/gpgex.cc 2008-09-09 09:52:58 UTC (rev 60) @@ -203,7 +203,11 @@ if (! strcasecmp (ending, "gpg") || ! strcasecmp (ending, "pgp") || ! strcasecmp (ending, "asc") - || ! strcasecmp (ending, "sig")) + || ! strcasecmp (ending, "sig") + || ! strcasecmp (ending, "pem") + || ! strcasecmp (ending, "p7m") + || ! strcasecmp (ending, "p7s") + ) gpg = true; if (gpg == false) From cvs at cvs.gnupg.org Tue Sep 9 12:09:39 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 09 Sep 2008 12:09:39 +0200 Subject: [svn] GpgEX - r61 - tags Message-ID: Author: wk Date: 2008-09-09 12:09:39 +0200 (Tue, 09 Sep 2008) New Revision: 61 Added: tags/gpgex-0.9.1/ Log: Release. From cvs at cvs.gnupg.org Tue Sep 9 20:06:39 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 09 Sep 2008 20:06:39 +0200 Subject: [svn] gcry - r1321 - in trunk: . cipher doc tests Message-ID: Author: wk Date: 2008-09-09 20:06:38 +0200 (Tue, 09 Sep 2008) New Revision: 1321 Modified: trunk/NEWS trunk/cipher/ChangeLog trunk/cipher/Makefile.am trunk/cipher/des.c trunk/cipher/hmac-tests.c trunk/cipher/sha1.c trunk/cipher/sha256.c trunk/cipher/sha512.c trunk/configure.ac trunk/doc/announce.txt trunk/tests/ChangeLog trunk/tests/basic.c Log: Add more selftests. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/cipher/ChangeLog 2008-09-09 18:06:38 UTC (rev 1321) @@ -1,3 +1,13 @@ +2008-09-09 Werner Koch + + * hmac-tests.c (selftests_sha1): Add tests. + (selftests_sha224, selftests_sha384, selftests_sha512): Make up tests. + + * hash-common.c, hash-common.h: New. + * sha1.c (selftests_sha1): Add 3 tests. + * sha256.c (selftests_sha256, selftests_sha224): Ditto. + * sha512.c (selftests_sha512, selftests_sha384): Ditto. + 2008-08-29 Werner Koch * pubkey.c (gcry_pk_get_keygrip): Remove the special case for RSA Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/tests/ChangeLog 2008-09-09 18:06:38 UTC (rev 1321) @@ -1,3 +1,7 @@ +2008-09-09 Werner Koch + + * basic.c (main): New option --selftest. + 2008-08-29 Werner Koch * keygrip.c: Update to also check ECDSA. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/NEWS 2008-09-09 18:06:38 UTC (rev 1321) @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.4.3 +------------------------------------------------ + + Noteworthy changes in version 1.4.2 (2008-09-08) ------------------------------------------------ Modified: trunk/cipher/Makefile.am =================================================================== --- trunk/cipher/Makefile.am 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/cipher/Makefile.am 2008-09-09 18:06:38 UTC (rev 1321) @@ -39,6 +39,7 @@ hmac-tests.c \ bithelp.h \ primegen.c \ +hash-common.c hash-common.h \ rmd.h EXTRA_libcipher_la_SOURCES = \ Modified: trunk/cipher/des.c =================================================================== --- trunk/cipher/des.c 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/cipher/des.c 2008-09-09 18:06:38 UTC (rev 1321) @@ -1087,7 +1087,7 @@ */ -/* Complete selftest for TripleDES with all modes and driver code. */ +/* Selftest for TripleDES. */ static gpg_err_code_t selftest_fips (selftest_report_func_t report) { @@ -1099,7 +1099,10 @@ if (errtxt) goto failed; - /* FIXME: need more tests. */ + /* The low-level self-tests are quite extensive and thus we can do + without high level tests. This is also justified because we have + no custom block code implementation for 3des but always use the + standard high level block code. */ return 0; /* Succeeded. */ Modified: trunk/cipher/hmac-tests.c =================================================================== --- trunk/cipher/hmac-tests.c 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/cipher/hmac-tests.c 2008-09-09 18:06:38 UTC (rev 1321) @@ -25,8 +25,8 @@ digest algorithm modules, but that would blow up the code too much and spread the hmac tests over several modules. - Thus we implement all HMAC tests in this test module and provide a - function to run the tests. + Thus we implement all HMAC tests in this test module and provide a + function to run the tests. */ #include @@ -54,6 +54,7 @@ gcry_md_hd_t hd; const unsigned char *digest; +/* printf ("HMAC algo %d\n", algo); */ if (_gcry_md_get_algo_dlen (algo) != expectlen) return "invalid tests data"; if (_gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC)) @@ -72,6 +73,17 @@ } if (memcmp (digest, expect, expectlen)) { +/* int i; */ + +/* fputs (" {", stdout); */ +/* for (i=0; i < expectlen-1; i++) */ +/* { */ +/* if (i && !(i % 8)) */ +/* fputs ("\n ", stdout); */ +/* printf (" 0x%02x,", digest[i]); */ +/* } */ +/* printf (" 0x%02x } },\n", digest[i]); */ + _gcry_md_close (hd); return "does not match"; } @@ -83,31 +95,56 @@ static gpg_err_code_t selftests_sha1 (selftest_report_func_t report) { - static struct - { - const char * const desc; - const char * const data; - const char * const key; - const char expect[20]; - } tv[] = - { - { NULL } - }; const char *what; const char *errtxt; - int tvidx; - - for (tvidx=0; tv[tvidx].desc; tvidx++) - { - what = tv[tvidx].desc; - errtxt = check_one (GCRY_MD_SHA1, - tv[tvidx].data, strlen (tv[tvidx].data), - tv[tvidx].key, strlen (tv[tvidx].key), - tv[tvidx].expect, DIM (tv[tvidx].expect) ); - if (errtxt) - goto failed; - } + unsigned char key[128]; + int i, j; + what = "FIPS-198a, A.1"; + for (i=0; i < 64; i++) + key[i] = i; + errtxt = check_one (GCRY_MD_SHA1, + "Sample #1", 9, + key, 64, + "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12" + "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a", 20); + if (errtxt) + goto failed; + + what = "FIPS-198a, A.2"; + for (i=0, j=0x30; i < 20; i++) + key[i] = j++; + errtxt = check_one (GCRY_MD_SHA1, + "Sample #2", 9, + key, 20, + "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82" + "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24", 20); + if (errtxt) + goto failed; + + what = "FIPS-198a, A.3"; + for (i=0, j=0x50; i < 100; i++) + key[i] = j++; + errtxt = check_one (GCRY_MD_SHA1, + "Sample #3", 9, + key, 100, + "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0" + "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa", 20 ); + if (errtxt) + goto failed; + + what = "FIPS-198a, A.4"; + for (i=0, j=0x70; i < 49; i++) + key[i] = j++; + errtxt = check_one (GCRY_MD_SHA1, + "Sample #4", 9, + key, 49, + "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42" + "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26", 20 ); + if (errtxt) + goto failed; + + return 0; /* Succeeded. */ failed: @@ -129,6 +166,81 @@ const char expect[28]; } tv[] = { + { "data-28 key-4", + "what do ya want for nothing?", + "Jefe", + { 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf, + 0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f, + 0x8b, 0xbe, 0xa2, 0xa3, 0x9e, 0x61, 0x48, 0x00, + 0x8f, 0xd0, 0x5e, 0x44 } }, + + { "data-9 key-20", + "Hi There", + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b\x0b", + { 0x89, 0x6f, 0xb1, 0x12, 0x8a, 0xbb, 0xdf, 0x19, + 0x68, 0x32, 0x10, 0x7c, 0xd4, 0x9d, 0xf3, 0x3f, + 0x47, 0xb4, 0xb1, 0x16, 0x99, 0x12, 0xba, 0x4f, + 0x53, 0x68, 0x4b, 0x22 } }, + + { "data-50 key-20", + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa", + { 0x7f, 0xb3, 0xcb, 0x35, 0x88, 0xc6, 0xc1, 0xf6, + 0xff, 0xa9, 0x69, 0x4d, 0x7d, 0x6a, 0xd2, 0x64, + 0x93, 0x65, 0xb0, 0xc1, 0xf6, 0x5d, 0x69, 0xd1, + 0xec, 0x83, 0x33, 0xea } }, + + { "data-50 key-26", + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd", + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19", + { 0x6c, 0x11, 0x50, 0x68, 0x74, 0x01, 0x3c, 0xac, + 0x6a, 0x2a, 0xbc, 0x1b, 0xb3, 0x82, 0x62, 0x7c, + 0xec, 0x6a, 0x90, 0xd8, 0x6e, 0xfc, 0x01, 0x2d, + 0xe7, 0xaf, 0xec, 0x5a } }, + + { "data-54 key-131", + "Test Using Larger Than Block-Size Key - Hash Key First", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + { 0x95, 0xe9, 0xa0, 0xdb, 0x96, 0x20, 0x95, 0xad, + 0xae, 0xbe, 0x9b, 0x2d, 0x6f, 0x0d, 0xbc, 0xe2, + 0xd4, 0x99, 0xf1, 0x12, 0xf2, 0xd2, 0xb7, 0x27, + 0x3f, 0xa6, 0x87, 0x0e } }, + + { "data-152 key-131", + "This is a test using a larger than block-size key and a larger " + "than block-size data. The key needs to be hashed before being " + "used by the HMAC algorithm.", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + { 0x3a, 0x85, 0x41, 0x66, 0xac, 0x5d, 0x9f, 0x02, + 0x3f, 0x54, 0xd5, 0x17, 0xd0, 0xb3, 0x9d, 0xbd, + 0x94, 0x67, 0x70, 0xdb, 0x9c, 0x2b, 0x95, 0xc9, + 0xf6, 0xf5, 0x65, 0xd1 } }, + { NULL } }; const char *what; @@ -305,6 +417,93 @@ const char expect[48]; } tv[] = { + { "data-28 key-4", + "what do ya want for nothing?", + "Jefe", + { 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31, + 0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b, + 0x9c, 0x7e, 0xf4, 0x64, 0xf5, 0xa0, 0x1b, 0x47, + 0xe4, 0x2e, 0xc3, 0x73, 0x63, 0x22, 0x44, 0x5e, + 0x8e, 0x22, 0x40, 0xca, 0x5e, 0x69, 0xe2, 0xc7, + 0x8b, 0x32, 0x39, 0xec, 0xfa, 0xb2, 0x16, 0x49 } }, + + { "data-9 key-20", + "Hi There", + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b\x0b", + { 0xaf, 0xd0, 0x39, 0x44, 0xd8, 0x48, 0x95, 0x62, + 0x6b, 0x08, 0x25, 0xf4, 0xab, 0x46, 0x90, 0x7f, + 0x15, 0xf9, 0xda, 0xdb, 0xe4, 0x10, 0x1e, 0xc6, + 0x82, 0xaa, 0x03, 0x4c, 0x7c, 0xeb, 0xc5, 0x9c, + 0xfa, 0xea, 0x9e, 0xa9, 0x07, 0x6e, 0xde, 0x7f, + 0x4a, 0xf1, 0x52, 0xe8, 0xb2, 0xfa, 0x9c, 0xb6 } }, + + { "data-50 key-20", + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa", + { 0x88, 0x06, 0x26, 0x08, 0xd3, 0xe6, 0xad, 0x8a, + 0x0a, 0xa2, 0xac, 0xe0, 0x14, 0xc8, 0xa8, 0x6f, + 0x0a, 0xa6, 0x35, 0xd9, 0x47, 0xac, 0x9f, 0xeb, + 0xe8, 0x3e, 0xf4, 0xe5, 0x59, 0x66, 0x14, 0x4b, + 0x2a, 0x5a, 0xb3, 0x9d, 0xc1, 0x38, 0x14, 0xb9, + 0x4e, 0x3a, 0xb6, 0xe1, 0x01, 0xa3, 0x4f, 0x27 } }, + + { "data-50 key-26", + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd", + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19", + { 0x3e, 0x8a, 0x69, 0xb7, 0x78, 0x3c, 0x25, 0x85, + 0x19, 0x33, 0xab, 0x62, 0x90, 0xaf, 0x6c, 0xa7, + 0x7a, 0x99, 0x81, 0x48, 0x08, 0x50, 0x00, 0x9c, + 0xc5, 0x57, 0x7c, 0x6e, 0x1f, 0x57, 0x3b, 0x4e, + 0x68, 0x01, 0xdd, 0x23, 0xc4, 0xa7, 0xd6, 0x79, + 0xcc, 0xf8, 0xa3, 0x86, 0xc6, 0x74, 0xcf, 0xfb } }, + + { "data-54 key-131", + "Test Using Larger Than Block-Size Key - Hash Key First", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + { 0x4e, 0xce, 0x08, 0x44, 0x85, 0x81, 0x3e, 0x90, + 0x88, 0xd2, 0xc6, 0x3a, 0x04, 0x1b, 0xc5, 0xb4, + 0x4f, 0x9e, 0xf1, 0x01, 0x2a, 0x2b, 0x58, 0x8f, + 0x3c, 0xd1, 0x1f, 0x05, 0x03, 0x3a, 0xc4, 0xc6, + 0x0c, 0x2e, 0xf6, 0xab, 0x40, 0x30, 0xfe, 0x82, + 0x96, 0x24, 0x8d, 0xf1, 0x63, 0xf4, 0x49, 0x52 } }, + + { "data-152 key-131", + "This is a test using a larger than block-size key and a larger " + "than block-size data. The key needs to be hashed before being " + "used by the HMAC algorithm.", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + { 0x66, 0x17, 0x17, 0x8e, 0x94, 0x1f, 0x02, 0x0d, + 0x35, 0x1e, 0x2f, 0x25, 0x4e, 0x8f, 0xd3, 0x2c, + 0x60, 0x24, 0x20, 0xfe, 0xb0, 0xb8, 0xfb, 0x9a, + 0xdc, 0xce, 0xbb, 0x82, 0x46, 0x1e, 0x99, 0xc5, + 0xa6, 0x78, 0xcc, 0x31, 0xe7, 0x99, 0x17, 0x6d, + 0x38, 0x60, 0xe6, 0x11, 0x0c, 0x46, 0x52, 0x3e } }, + { NULL } }; const char *what; @@ -342,6 +541,105 @@ const char expect[64]; } tv[] = { + { "data-28 key-4", + "what do ya want for nothing?", + "Jefe", + { 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2, + 0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3, + 0x87, 0xbd, 0x64, 0x22, 0x2e, 0x83, 0x1f, 0xd6, + 0x10, 0x27, 0x0c, 0xd7, 0xea, 0x25, 0x05, 0x54, + 0x97, 0x58, 0xbf, 0x75, 0xc0, 0x5a, 0x99, 0x4a, + 0x6d, 0x03, 0x4f, 0x65, 0xf8, 0xf0, 0xe6, 0xfd, + 0xca, 0xea, 0xb1, 0xa3, 0x4d, 0x4a, 0x6b, 0x4b, + 0x63, 0x6e, 0x07, 0x0a, 0x38, 0xbc, 0xe7, 0x37 } }, + + { "data-9 key-20", + "Hi There", + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b\x0b", + { 0x87, 0xaa, 0x7c, 0xde, 0xa5, 0xef, 0x61, 0x9d, + 0x4f, 0xf0, 0xb4, 0x24, 0x1a, 0x1d, 0x6c, 0xb0, + 0x23, 0x79, 0xf4, 0xe2, 0xce, 0x4e, 0xc2, 0x78, + 0x7a, 0xd0, 0xb3, 0x05, 0x45, 0xe1, 0x7c, 0xde, + 0xda, 0xa8, 0x33, 0xb7, 0xd6, 0xb8, 0xa7, 0x02, + 0x03, 0x8b, 0x27, 0x4e, 0xae, 0xa3, 0xf4, 0xe4, + 0xbe, 0x9d, 0x91, 0x4e, 0xeb, 0x61, 0xf1, 0x70, + 0x2e, 0x69, 0x6c, 0x20, 0x3a, 0x12, 0x68, 0x54 } }, + + { "data-50 key-20", + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa", + { 0xfa, 0x73, 0xb0, 0x08, 0x9d, 0x56, 0xa2, 0x84, + 0xef, 0xb0, 0xf0, 0x75, 0x6c, 0x89, 0x0b, 0xe9, + 0xb1, 0xb5, 0xdb, 0xdd, 0x8e, 0xe8, 0x1a, 0x36, + 0x55, 0xf8, 0x3e, 0x33, 0xb2, 0x27, 0x9d, 0x39, + 0xbf, 0x3e, 0x84, 0x82, 0x79, 0xa7, 0x22, 0xc8, + 0x06, 0xb4, 0x85, 0xa4, 0x7e, 0x67, 0xc8, 0x07, + 0xb9, 0x46, 0xa3, 0x37, 0xbe, 0xe8, 0x94, 0x26, + 0x74, 0x27, 0x88, 0x59, 0xe1, 0x32, 0x92, 0xfb } }, + + { "data-50 key-26", + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd", + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10" + "\x11\x12\x13\x14\x15\x16\x17\x18\x19", + { 0xb0, 0xba, 0x46, 0x56, 0x37, 0x45, 0x8c, 0x69, + 0x90, 0xe5, 0xa8, 0xc5, 0xf6, 0x1d, 0x4a, 0xf7, + 0xe5, 0x76, 0xd9, 0x7f, 0xf9, 0x4b, 0x87, 0x2d, + 0xe7, 0x6f, 0x80, 0x50, 0x36, 0x1e, 0xe3, 0xdb, + 0xa9, 0x1c, 0xa5, 0xc1, 0x1a, 0xa2, 0x5e, 0xb4, + 0xd6, 0x79, 0x27, 0x5c, 0xc5, 0x78, 0x80, 0x63, + 0xa5, 0xf1, 0x97, 0x41, 0x12, 0x0c, 0x4f, 0x2d, + 0xe2, 0xad, 0xeb, 0xeb, 0x10, 0xa2, 0x98, 0xdd } }, + + { "data-54 key-131", + "Test Using Larger Than Block-Size Key - Hash Key First", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + { 0x80, 0xb2, 0x42, 0x63, 0xc7, 0xc1, 0xa3, 0xeb, + 0xb7, 0x14, 0x93, 0xc1, 0xdd, 0x7b, 0xe8, 0xb4, + 0x9b, 0x46, 0xd1, 0xf4, 0x1b, 0x4a, 0xee, 0xc1, + 0x12, 0x1b, 0x01, 0x37, 0x83, 0xf8, 0xf3, 0x52, + 0x6b, 0x56, 0xd0, 0x37, 0xe0, 0x5f, 0x25, 0x98, + 0xbd, 0x0f, 0xd2, 0x21, 0x5d, 0x6a, 0x1e, 0x52, + 0x95, 0xe6, 0x4f, 0x73, 0xf6, 0x3f, 0x0a, 0xec, + 0x8b, 0x91, 0x5a, 0x98, 0x5d, 0x78, 0x65, 0x98 } }, + + { "data-152 key-131", + "This is a test using a larger than block-size key and a larger " + "than block-size data. The key needs to be hashed before being " + "used by the HMAC algorithm.", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + { 0xe3, 0x7b, 0x6a, 0x77, 0x5d, 0xc8, 0x7d, 0xba, + 0xa4, 0xdf, 0xa9, 0xf9, 0x6e, 0x5e, 0x3f, 0xfd, + 0xde, 0xbd, 0x71, 0xf8, 0x86, 0x72, 0x89, 0x86, + 0x5d, 0xf5, 0xa3, 0x2d, 0x20, 0xcd, 0xc9, 0x44, + 0xb6, 0x02, 0x2c, 0xac, 0x3c, 0x49, 0x82, 0xb1, + 0x0d, 0x5e, 0xeb, 0x55, 0xc3, 0xe4, 0xde, 0x15, + 0x13, 0x46, 0x76, 0xfb, 0x6d, 0xe0, 0x44, 0x60, + 0x65, 0xc9, 0x74, 0x40, 0xfa, 0x8c, 0x6a, 0x58 } }, + { NULL } }; const char *what; Modified: trunk/cipher/sha1.c =================================================================== --- trunk/cipher/sha1.c 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/cipher/sha1.c 2008-09-09 18:06:38 UTC (rev 1321) @@ -40,6 +40,7 @@ #include "memory.h" #include "bithelp.h" #include "cipher.h" +#include "hash-common.h" /* A macro to test whether P is properly aligned for an u32 type. @@ -385,13 +386,33 @@ const char *what; const char *errtxt; - what = "low-level"; - errtxt = NULL; /*selftest ();*/ + what = "short string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA1, 0, + "abc", 3, + "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E" + "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D", 20); if (errtxt) goto failed; - /* FIXME: need more tests. */ + what = "long string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA1, 0, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE" + "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1", 20); + if (errtxt) + goto failed; + what = "one million \"a\""; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA1, 1, + NULL, 0, + "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E" + "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F", 20); + if (errtxt) + goto failed; + return 0; /* Succeeded. */ failed: Modified: trunk/cipher/sha256.c =================================================================== --- trunk/cipher/sha256.c 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/cipher/sha256.c 2008-09-09 18:06:38 UTC (rev 1321) @@ -44,6 +44,7 @@ #include "memory.h" #include "bithelp.h" #include "cipher.h" +#include "hash-common.h" typedef struct { u32 h0,h1,h2,h3,h4,h5,h6,h7; @@ -325,13 +326,33 @@ const char *what; const char *errtxt; - what = "low-level"; - errtxt = NULL; /*selftest ();*/ + what = "short string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA224, 0, + "abc", 3, + "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3" + "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7", 28); if (errtxt) goto failed; - /* FIXME: need more tests. */ + what = "long string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA224, 0, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50" + "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28); + if (errtxt) + goto failed; + what = "one million \"a\""; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA224, 1, + NULL, 0, + "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b" + "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67", 28); + if (errtxt) + goto failed; + return 0; /* Succeeded. */ failed: @@ -346,13 +367,33 @@ const char *what; const char *errtxt; - what = "low-level"; - errtxt = NULL; /*selftest ();*/ + what = "short string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA256, 0, + "abc", 3, + "\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", 32); if (errtxt) goto failed; - /* FIXME: need more tests. */ + what = "long string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA256, 0, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\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", 32); + if (errtxt) + goto failed; + what = "one million \"a\""; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA256, 1, + NULL, 0, + "\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", 32); + if (errtxt) + goto failed; + return 0; /* Succeeded. */ failed: Modified: trunk/cipher/sha512.c =================================================================== --- trunk/cipher/sha512.c 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/cipher/sha512.c 2008-09-09 18:06:38 UTC (rev 1321) @@ -51,6 +51,7 @@ #include "g10lib.h" #include "bithelp.h" #include "cipher.h" +#include "hash-common.h" typedef struct { @@ -372,13 +373,37 @@ const char *what; const char *errtxt; - what = "low-level"; - errtxt = NULL; /*selftest ();*/ + what = "short string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA384, 0, + "abc", 3, + "\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", 48); if (errtxt) goto failed; - /* FIXME: need more tests. */ + what = "long string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA384, 0, + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47" + "\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12" + "\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39", 48); + if (errtxt) + goto failed; + what = "one million \"a\""; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA384, 1, + NULL, 0, + "\x9D\x0E\x18\x09\x71\x64\x74\xCB\x08\x6E\x83\x4E\x31\x0A\x4A\x1C" + "\xED\x14\x9E\x9C\x00\xF2\x48\x52\x79\x72\xCE\xC5\x70\x4C\x2A\x5B" + "\x07\xB8\xB3\xDC\x38\xEC\xC4\xEB\xAE\x97\xDD\xD8\x7F\x3D\x89\x85", 48); + if (errtxt) + goto failed; + return 0; /* Succeeded. */ failed: @@ -393,13 +418,40 @@ const char *what; const char *errtxt; - what = "low-level"; - errtxt = NULL; /*selftest ();*/ + what = "short string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA512, 0, + "abc", 3, + "\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", 64); if (errtxt) goto failed; - /* FIXME: need more tests. */ + what = "long string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA512, 0, + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F" + "\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18" + "\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A" + "\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09", 64); + if (errtxt) + goto failed; + what = "one million \"a\""; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA512, 1, + NULL, 0, + "\xE7\x18\x48\x3D\x0C\xE7\x69\x64\x4E\x2E\x42\xC7\xBC\x15\xB4\x63" + "\x8E\x1F\x98\xB1\x3B\x20\x44\x28\x56\x32\xA8\x03\xAF\xA9\x73\xEB" + "\xDE\x0F\xF2\x44\x87\x7E\xA6\x0A\x4C\xB0\x43\x2C\xE5\x77\xC3\x1B" + "\xEB\x00\x9C\x5C\x2C\x49\xAA\x2E\x4E\xAD\xB2\x17\xAD\x8C\xC0\x9B", 64); + if (errtxt) + goto failed; + return 0; /* Succeeded. */ failed: Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/configure.ac 2008-09-09 18:06:38 UTC (rev 1321) @@ -26,8 +26,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.4.2]) -m4_define([my_issvn], [no]) +m4_define([my_version], [1.4.3]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) Modified: trunk/doc/announce.txt =================================================================== --- trunk/doc/announce.txt 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/doc/announce.txt 2008-09-09 18:06:38 UTC (rev 1321) @@ -5,46 +5,66 @@ Hello! The GNU project is pleased to announce the availability of Libgcrypt -version 1.4.1. This is a maintenance release to fix a few problems. +version 1.4.2. Libgcrypt is a general purpose library of cryptographic building blocks. It is originally based on code used by GnuPG. It does not provide any implementation of OpenPGP or other protocols. Thorough understanding of applied cryptography is required to use Libgcrypt. -Noteworthy changes in version 1.4.1 (2008-04-25) ------------------------------------------------- +Noteworthy changes in version 1.4.2: - * Fixed a bug introduced by 1.3.1 which led to the comsumption of far - too much entropy for the intial seeding. + * The long missing gcry_mpi_lshift function has been added. - * Improved AES performance for CFB and CBC modes. + * RSA key generation now supports a "transient-key" flag. - * Removed build problems for the Padlock support. + * The keygrip computation for ECDSA has been implemented thus ECDSA + is now fully supported. + * A few macros have been replaced by functions for better type + checking. + * The thread initialization structure now carries version + information. + + * The manual describes more clearly how to initialize Libgcrypt. + + * The library may now be switched into a FIPS mode. + + * Interface changes relative to the 1.3.0 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + GCRYCTL_OPERATIONAL_P NEW. + GCRYCTL_FIPS_MODE_P NEW. + GCRYCTL_FORCE_FIPS_MODE NEW. + gcry_cipher_setkey NEW: Replaces macro. + gcry_cipher_setiv NEW: Replaces macro. + gcry_cipher_setctr NEW: Replaces macro. + gcry_mpi_lshift NEW. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Source code is hosted at the GnuPG FTP server and its mirrors as listed at http://www.gnupg.org/download/mirrors.html . On the primary server the source file and its digital signatures is: - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.1.tar.bz2 (946k) - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.1.tar.bz2.sig + ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.2.tar.bz2 (1049k) + ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.2.tar.bz2.sig This file is bzip2 compressed. A gzip compressed version is also available: - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.1.tar.gz (1179k) + ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.1.tar.gz (1301k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.1.tar.gz.sig -Alternativley you may upgrade version 1.4.0 using this patch file: +Alternativley you may upgrade version 1.4.1 using this patch file: - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.0-1.4.1.diff.bz2 (49k) + ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.1-1.4.2.diff.bz2 (171k) The SHA-1 checksums are: -367fe7fecd2ed4ab743849279dbc2f7e148f9956 libgcrypt-1.4.1.tar.bz2 -36f1c6632fa06a6d3c92f83c3cdca8c7731a4220 libgcrypt-1.4.1.tar.gz -458fa5939df46da383df64b27ed8f8f580931618 libgcrypt-1.4.0-1.4.1.diff.bz2 +f4eda0d4a63905aef3bcdf24bb3dad787ef4b918 libgcrypt-1.4.2.tar.gz +e9c65688e3191c4cad2910bda2f6c69fc05997a2 libgcrypt-1.4.2.tar.bz2 +e0e5e4192f144ae0fc093d08aff50b725f46c0f9 libgcrypt-1.4.1-1.4.2.diff.bz2 For help on developing with Libgcrypt you should read the included @@ -64,6 +84,7 @@ Many thanks to all who contributed to Libgcrypt development, be it bug fixes, code, documentation, testing or helping users. + Happy hacking, Werner @@ -73,6 +94,6 @@ [1] See http://www.gnupg.org/documentation/mailing-lists.html . [2] Note that copyright assignments to the FSF are required. -[3] For example http://www.fsfeurope.org/help/donate.en.html . +[3] For example see http://donate.fsf.org . [4] See the service directory at http://www.gnupg.org/service.html . Modified: trunk/tests/basic.c =================================================================== --- trunk/tests/basic.c 2008-09-08 18:04:35 UTC (rev 1320) +++ trunk/tests/basic.c 2008-09-09 18:06:38 UTC (rev 1321) @@ -2045,6 +2045,7 @@ int last_argc = -1; int debug = 0; int use_fips = 0; + int selftest_only = 0; if (argc) { argc--; argv++; } @@ -2072,6 +2073,12 @@ use_fips = 1; argc--; argv++; } + else if (!strcmp (*argv, "--selftest")) + { + selftest_only = 1; + verbose += 2; + argc--; argv++; + } } gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); @@ -2095,17 +2102,20 @@ if ( gcry_control (GCRYCTL_FIPS_MODE_P, 0) ) in_fips_mode = 1; - check_ciphers (); - check_aes128_cbc_cts_cipher (); - check_cbc_mac_cipher (); - check_ctr_cipher (); - check_cfb_cipher (); - check_ofb_cipher (); - check_digests (); - check_hmac (); - check_pubkey (); + if (!selftest_only) + { + check_ciphers (); + check_aes128_cbc_cts_cipher (); + check_cbc_mac_cipher (); + check_ctr_cipher (); + check_cfb_cipher (); + check_ofb_cipher (); + check_digests (); + check_hmac (); + check_pubkey (); + } - if (in_fips_mode) + if (in_fips_mode && !selftest_only) { /* If we are in fips mode do some more tests. */ gcry_md_hd_t md; @@ -2152,7 +2162,7 @@ else { /* If in standard mode, run selftests. */ - gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + gcry_control (GCRYCTL_SELFTEST, 0); } if (verbose) From cvs at cvs.gnupg.org Thu Sep 11 12:38:05 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 11 Sep 2008 12:38:05 +0200 Subject: [svn] gcry - r1322 - in trunk: cipher doc src tests Message-ID: Author: wk Date: 2008-09-11 12:38:04 +0200 (Thu, 11 Sep 2008) New Revision: 1322 Modified: trunk/cipher/ChangeLog trunk/cipher/dsa.c trunk/cipher/rsa.c trunk/doc/ChangeLog trunk/doc/Makefile.am trunk/doc/gcrypt.texi trunk/src/ChangeLog trunk/src/fips.c trunk/tests/basic.c Log: Implemented more self-tests. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-09-09 18:06:38 UTC (rev 1321) +++ trunk/cipher/ChangeLog 2008-09-11 10:38:04 UTC (rev 1322) @@ -1,3 +1,14 @@ +2008-09-11 Werner Koch + + * rsa.c (_gcry_rsa_decrypt): Return an error instead of calling + BUG in case of a practically impossible condition. + (sample_secret_key, sample_public_key): New. + (selftest_sign_1024, selftest_encr_1024): New. + (selftests_rsa): Implement tests. + * dsa.c (sample_secret_key, sample_public_key): New. + (selftest_sign_1024): New. + (selftests_dsa): Implement tests. + 2008-09-09 Werner Koch * hmac-tests.c (selftests_sha1): Add tests. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-09-09 18:06:38 UTC (rev 1321) +++ trunk/doc/ChangeLog 2008-09-11 10:38:04 UTC (rev 1322) @@ -1,3 +1,8 @@ +2008-09-11 Werner Koch + + * gcrypt.texi (Public-Key Subsystem Architecture): Explain RSA + blinding. + 2008-09-08 Marcus Brinkmann * gcrypt.texi: Some typos fixed. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-09 18:06:38 UTC (rev 1321) +++ trunk/src/ChangeLog 2008-09-11 10:38:04 UTC (rev 1322) @@ -1,3 +1,8 @@ +2008-09-11 Werner Koch + + * fips.c (_gcry_fips_run_selftests): Run random tests before the + pubkey tests. + 2008-09-05 Werner Koch * gcrypt.h.in (GCYRCTL_SELFTEST): New. Modified: trunk/cipher/dsa.c =================================================================== --- trunk/cipher/dsa.c 2008-09-09 18:06:38 UTC (rev 1321) +++ trunk/cipher/dsa.c 2008-09-11 10:38:04 UTC (rev 1322) @@ -1,4 +1,4 @@ -/* dsa.c - DSA signature scheme +/* dsa.c - DSA signature scheme * Copyright (C) 1998, 2000, 2001, 2002, 2003, * 2006, 2008 Free Software Foundation, Inc. * @@ -47,6 +47,45 @@ } DSA_secret_key; +/* A sample 1024 bit DSA key used for the selftests. */ +static const char sample_secret_key[] = +"(private-key" +" (dsa" +" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" +" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" +" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" +" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)" +" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)" +" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" +" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" +" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" +" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)" +" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" +" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" +" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" +" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)" +" (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))"; +/* A sample 1024 bit DSA key used for the selftests (public only). */ +static const char sample_public_key[] = +"(public-key" +" (dsa" +" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" +" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" +" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" +" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)" +" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)" +" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" +" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" +" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" +" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)" +" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" +" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" +" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" +" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))"; + + + + static gcry_mpi_t gen_k (gcry_mpi_t q); static void test_keys (DSA_secret_key *sk, unsigned qbits); static int check_secret_key (DSA_secret_key *sk); @@ -539,23 +578,103 @@ Self-test section. */ +static const char * +selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) +{ + static const char sample_data[] = + "(data (flags pkcs1)" + " (hash sha1 #a0b1c2d3e4f500102030405060708090a1b2c3d4#))"; + static const char sample_data_bad[] = + "(data (flags pkcs1)" + " (hash sha1 #a0b1c2d3e4f510102030405060708090a1b2c3d4#))"; + const char *errtxt = NULL; + gcry_error_t err; + gcry_sexp_t data = NULL; + gcry_sexp_t data_bad = NULL; + gcry_sexp_t sig = NULL; + + err = gcry_sexp_sscan (&data, NULL, + sample_data, strlen (sample_data)); + if (!err) + err = gcry_sexp_sscan (&data_bad, NULL, + sample_data_bad, strlen (sample_data_bad)); + if (err) + { + errtxt = "converting data failed"; + goto leave; + } + + err = gcry_pk_sign (&sig, data, skey); + if (err) + { + errtxt = "signing failed"; + goto leave; + } + err = gcry_pk_verify (sig, data, pkey); + if (err) + { + errtxt = "verify failed"; + goto leave; + } + err = gcry_pk_verify (sig, data_bad, pkey); + if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE) + { + errtxt = "bad signature not detected"; + goto leave; + } + + + leave: + gcry_sexp_release (sig); + gcry_sexp_release (data_bad); + gcry_sexp_release (data); + return errtxt; +} + + static gpg_err_code_t selftests_dsa (selftest_report_func_t report) { const char *what; const char *errtxt; - - what = "low-level"; - errtxt = NULL; /*selftest ();*/ + gcry_error_t err; + gcry_sexp_t skey = NULL; + gcry_sexp_t pkey = NULL; + + /* Convert the S-expressions into the internal representation. */ + what = "convert"; + err = gcry_sexp_sscan (&skey, NULL, + sample_secret_key, strlen (sample_secret_key)); + if (!err) + err = gcry_sexp_sscan (&pkey, NULL, + sample_public_key, strlen (sample_public_key)); + if (err) + { + errtxt = gcry_strerror (err); + goto failed; + } + + what = "key consistency"; + err = gcry_pk_testkey (skey); + if (err) + { + errtxt = gcry_strerror (err); + goto failed; + } + + what = "sign"; + errtxt = selftest_sign_1024 (pkey, skey); if (errtxt) goto failed; - /* FIXME: need more tests. */ - + gcry_sexp_release (pkey); + gcry_sexp_release (skey); return 0; /* Succeeded. */ failed: + gcry_sexp_release (pkey); + gcry_sexp_release (skey); if (report) report ("pubkey", GCRY_PK_DSA, what, errtxt); return GPG_ERR_SELFTEST_FAILED; Modified: trunk/cipher/rsa.c =================================================================== --- trunk/cipher/rsa.c 2008-09-09 18:06:38 UTC (rev 1321) +++ trunk/cipher/rsa.c 2008-09-11 10:38:04 UTC (rev 1322) @@ -1,4 +1,4 @@ -/* rsa.c - RSA function +/* rsa.c - RSA implementation * Copyright (C) 1997, 1998, 1999 by Werner Koch (dd9jn) * Copyright (C) 2000, 2001, 2002, 2003, 2008 Free Software Foundation, Inc. * @@ -52,6 +52,38 @@ } RSA_secret_key; +/* A sample 1024 bit RSA key used for the selftests. */ +static const char sample_secret_key[] = +"(private-key" +" (rsa" +" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" +" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" +" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" +" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)" +" (e #010001#)" +" (d #046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b11" +" 7d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bd" +" c543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21" +" c3ee47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781#)" +" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" +" fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)" +" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" +" 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)" +" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" +" ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))"; +/* A sample 1024 bit RSA key used for the selftests (public only). */ +static const char sample_public_key[] = +"(public-key" +" (rsa" +" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" +" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" +" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" +" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)" +" (e #010001#)))"; + + + + static void test_keys (RSA_secret_key *sk, unsigned nbits); static gpg_err_code_t generate (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, @@ -585,12 +617,11 @@ GCRY_STRONG_RANDOM); gcry_mpi_mod (r, r, sk.n); - /* Actually it should be okay to skip the check for equality - with either p or q here. */ - - /* Calculate inverse of r. */ - if (! gcry_mpi_invm (ri, r, sk.n)) - BUG (); + /* Calculate inverse of r. It practically impossible that the + follwing test fails, thus we do not add code to release + allocated resources. */ + if (!gcry_mpi_invm (ri, r, sk.n)) + return GPG_ERR_INTERNAL; } if (! (flags & PUBKEY_FLAG_NO_BLINDING)) @@ -730,23 +761,179 @@ Self-test section. */ +static const char * +selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) +{ + static const char sample_data[] = + "(data (flags pkcs1)" + " (hash sha1 #11223344556677889900aabbccddeeff10203040#))"; + static const char sample_data_bad[] = + "(data (flags pkcs1)" + " (hash sha1 #11223344556677889900aabbccddeeff80203040#))"; + const char *errtxt = NULL; + gcry_error_t err; + gcry_sexp_t data = NULL; + gcry_sexp_t data_bad = NULL; + gcry_sexp_t sig = NULL; + + err = gcry_sexp_sscan (&data, NULL, + sample_data, strlen (sample_data)); + if (!err) + err = gcry_sexp_sscan (&data_bad, NULL, + sample_data_bad, strlen (sample_data_bad)); + if (err) + { + errtxt = "converting data failed"; + goto leave; + } + + err = gcry_pk_sign (&sig, data, skey); + if (err) + { + errtxt = "signing failed"; + goto leave; + } + err = gcry_pk_verify (sig, data, pkey); + if (err) + { + errtxt = "verify failed"; + goto leave; + } + err = gcry_pk_verify (sig, data_bad, pkey); + if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE) + { + errtxt = "bad signature not detected"; + goto leave; + } + + + leave: + gcry_sexp_release (sig); + gcry_sexp_release (data_bad); + gcry_sexp_release (data); + return errtxt; +} + + +static const char * +selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) +{ + const char *errtxt = NULL; + gcry_error_t err; + const unsigned int nbits = 1000; /* Encrypt 1000 random bits. */ + gcry_mpi_t value = NULL; + gcry_sexp_t plain = NULL; + gcry_sexp_t encr = NULL; + gcry_sexp_t decr = NULL; + gcry_mpi_t decr_value = NULL; + gcry_sexp_t tmplist = NULL; + + /* Create plain text. */ + value = gcry_mpi_new (nbits); + gcry_mpi_randomize (value, nbits, GCRY_WEAK_RANDOM); + + err = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", value); + if (err) + { + errtxt = "converting data failed"; + goto leave; + } + + /* Encrypt and decrypt. */ + err = gcry_pk_encrypt (&encr, plain, pkey); + if (err) + { + errtxt = "encrypt failed"; + goto leave; + } + err = gcry_pk_decrypt (&decr, encr, skey); + if (err) + { + errtxt = "decrypt failed"; + goto leave; + } + + /* Extract decrypted data. The output of gcry_pk_decrypt depends on + whether a flags lists occurs in its input data. Because we + passed the output of gcry_pk_encrypt directly to gcry_pk_decrypt, + such a flag value won't be there as of today. To be prepared for + future changes we take care of it anyway. */ + tmplist = gcry_sexp_find_token (decr, "value", 0); + if (tmplist) + decr_value = gcry_sexp_nth_mpi (tmplist, 1, GCRYMPI_FMT_USG); + else + decr_value = gcry_sexp_nth_mpi (decr, 0, GCRYMPI_FMT_USG); + if (!decr_value) + { + errtxt = "decrypt returned no value"; + goto leave; + } + + if (gcry_mpi_cmp (value, decr_value)) + { + errtxt = "mismatch"; + goto leave; + } + + leave: + gcry_sexp_release (tmplist); + gcry_mpi_release (decr_value); + gcry_sexp_release (decr); + gcry_sexp_release (encr); + gcry_sexp_release (plain); + gcry_mpi_release (value); + return errtxt; +} + + static gpg_err_code_t selftests_rsa (selftest_report_func_t report) { const char *what; const char *errtxt; + gcry_error_t err; + gcry_sexp_t skey = NULL; + gcry_sexp_t pkey = NULL; - what = "low-level"; - errtxt = NULL; /*selftest ();*/ + /* Convert the S-expressions into the internal representation. */ + what = "convert"; + err = gcry_sexp_sscan (&skey, NULL, + sample_secret_key, strlen (sample_secret_key)); + if (!err) + err = gcry_sexp_sscan (&pkey, NULL, + sample_public_key, strlen (sample_public_key)); + if (err) + { + errtxt = gcry_strerror (err); + goto failed; + } + + what = "key consistency"; + err = gcry_pk_testkey (skey); + if (err) + { + errtxt = gcry_strerror (err); + goto failed; + } + + what = "sign"; + errtxt = selftest_sign_1024 (pkey, skey); if (errtxt) goto failed; - /* FIXME: need more tests. */ + what = "encrypt"; + errtxt = selftest_encr_1024 (pkey, skey); + if (errtxt) + goto failed; + gcry_sexp_release (pkey); + gcry_sexp_release (skey); return 0; /* Succeeded. */ failed: + gcry_sexp_release (pkey); + gcry_sexp_release (skey); if (report) report ("pubkey", GCRY_PK_RSA, what, errtxt); return GPG_ERR_SELFTEST_FAILED; Modified: trunk/doc/Makefile.am =================================================================== --- trunk/doc/Makefile.am 2008-09-09 18:06:38 UTC (rev 1321) +++ trunk/doc/Makefile.am 2008-09-11 10:38:04 UTC (rev 1322) @@ -63,9 +63,9 @@ cp gcrypt.info gcrypt.html/; \ else \ rsync -v gcrypt.pdf gcrypt.info \ - $${user}@cvs.gnupg.org:webspace/manuals/ ; \ + $${user}@trithemius.gnupg.org:webspace/manuals/ ; \ fi ; \ cd gcrypt.html ; \ rsync -vr --exclude='.svn' . \ - $${user}@cvs.gnupg.org:webspace/manuals/gcrypt$${dashdevel}/ + $${user}@trithemius.gnupg.org:webspace/manuals/gcrypt$${dashdevel}/ Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-09 18:06:38 UTC (rev 1321) +++ trunk/doc/gcrypt.texi 2008-09-11 10:38:04 UTC (rev 1322) @@ -2273,7 +2273,7 @@ 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 +value will be 0 and a new S-expression with the encrypted result is allocated and assigned 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 @@ -4608,11 +4608,22 @@ between the algorithm modules and the high level functions passes data in a custom format. The interface to the modules is published (@file{gcrypt-modules.h}) so that it can used to register external -implementations of algorithms with Libgcrypt. However, for some algorithms this -module interface is to limited and thus for the internal modules an -extra interface is sometimes used to convey more information. +implementations of algorithms with Libgcrypt. However, for some +algorithms this module interface is to limited and thus for the +internal modules an extra interface is sometimes used to convey more +information. +By default Libgcrypt uses a blinding technique for RSA decryption to +mitigate real world timing attacks over a network: Instead of using +the RSA decryption directly, a blinded value @math{y = x r^{e} \bmod n} +is decrypted and the unblinded value @math{x' = y' r^{-1} \bmod n} +returned. The blinding value @math{r} is a random value with the size +of the modulus @math{n} and generated with @code{GCRY_STRONG_RANDOM} +random level. + + + @node Symmetric Encryption Subsystem Architecture @section Symmetric Encryption Subsystem Architecture Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2008-09-09 18:06:38 UTC (rev 1321) +++ trunk/src/fips.c 2008-09-11 10:38:04 UTC (rev 1322) @@ -538,10 +538,12 @@ if (run_hmac_selftests ()) goto leave; - if (run_pubkey_selftests ()) + /* Run random tests before the pubkey tests because the latter + require random. */ + if (run_random_selftests ()) goto leave; - if (run_random_selftests ()) + if (run_pubkey_selftests ()) goto leave; /* Now check the integrity of the binary. We do this this after Modified: trunk/tests/basic.c =================================================================== --- trunk/tests/basic.c 2008-09-09 18:06:38 UTC (rev 1321) +++ trunk/tests/basic.c 2008-09-11 10:38:04 UTC (rev 1322) @@ -1375,7 +1375,7 @@ gcry_md_close (hd); p = gcry_md_read (hd2, algo); - if (0 == p) + if (!p) fail("algo %d, hmac gcry_md_read failed\n", algo); if (memcmp (p, expect, mdlen)) From cvs at cvs.gnupg.org Thu Sep 11 17:11:00 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 11 Sep 2008 17:11:00 +0200 Subject: [svn] gcry - r1323 - trunk/src Message-ID: Author: wk Date: 2008-09-11 17:11:00 +0200 (Thu, 11 Sep 2008) New Revision: 1323 Modified: trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/fips.c Log: Changed the HMAC binary check file format. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-11 10:38:04 UTC (rev 1322) +++ trunk/src/ChangeLog 2008-09-11 15:11:00 UTC (rev 1323) @@ -1,5 +1,9 @@ 2008-09-11 Werner Koch + * fips.c: Include string.h. + (loxtoi_1, loxtoi_2, loxdigit_p): New. + (check_binary_integrity): Change the format of the expected file. + * fips.c (_gcry_fips_run_selftests): Run random tests before the pubkey tests. Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2008-09-11 10:38:04 UTC (rev 1322) +++ trunk/src/Makefile.am 2008-09-11 15:11:00 UTC (rev 1323) @@ -126,7 +126,7 @@ # libgcrypt.la?) and how to create the hmac file already at link time # so that it can be used without installing libgcrypt first. #install-exec-hook: -# ./hmac256 --binary "What am I, a doctor or a moonshuttle conductor?" \ -# $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \ -# >$(DESTDIR)$(libdir)/libgcrypt.so.11.5.0.hmac +# ./hmac256 "What am I, a doctor or a moonshuttle conductor?" \ +# < $(DESTDIR)$(libdir)/libgcrypt.so.11.5.0 \ +# > $(DESTDIR)$(libdir)/.libgcrypt.so.11.5.0.hmac Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2008-09-11 10:38:04 UTC (rev 1322) +++ trunk/src/fips.c 2008-09-11 15:11:00 UTC (rev 1323) @@ -22,6 +22,7 @@ #include #include #include +#include #ifdef ENABLE_HMAC_BINARY_CHECK # include #endif @@ -60,11 +61,20 @@ + static void fips_new_state (enum module_states new_state); + +/* Convert lowercase hex digits; assumes valid hex digits. */ +#define loxtoi_1(p) (*(p) <= '9'? (*(p)- '0'): (*(p)-'a'+10)) +#define loxtoi_2(p) ((loxtoi_1(p) * 16) + loxtoi_1((p)+1)) +/* Returns true if P points to a lowercase hex digit. */ +#define loxdigit_p(p) !!strchr ("01234567890abcdef", *(p)) + + /* Check whether the OS is in FIPS mode and record that in a module local variable. If FORCE is passed as true, fips mode will be @@ -480,31 +490,52 @@ err = gpg_error (GPG_ERR_INTERNAL); else { - FILE *fp; - - fname = gcry_malloc (strlen (info.dli_fname) + 5 + 1 ); + fname = gcry_malloc (strlen (info.dli_fname) + 1 + 5 + 1 ); if (!fname) err = gpg_error_from_syserror (); else { - strcpy (stpcpy (fname, info.dli_fname), ".hmac"); - fp = fopen (fname, "rb"); + FILE *fp; + char *p; + + /* Prefix the basename with a dot. */ + strcpy (fname, info.dli_fname); + p = strrchr (fname, '/'); + if (p) + p++; + else + p = fname; + memmove (p+1, p, strlen (p)+1); + *p = '.'; + strcat (fname, ".hmac"); + + /* Open the file. */ + fp = fopen (fname, "r"); if (!fp) err = gpg_error_from_syserror (); else { - char buffer[33]; + /* A buffer of 64 bytes plus one for a LF and one to + detect garbage. */ + unsigned char buffer[64+1+1]; + const unsigned char *s; int n; - /* We expect a file of exactly 32 bytes. Consider - the self-test failed if this is not the case or - if it does not match the just computed HMAC. */ - if ((n=fread (buffer, 1, 33, fp)) != 32 - || memcmp (digest, buffer, 32) ) - err = gpg_error (GPG_ERR_SELFTEST_FAILED); - else - err = 0; - + /* The HMAC files consists of lowercase hex digits + only with an optional trailing linefeed. Fail if + there is any garbage. */ + err = gpg_error (GPG_ERR_SELFTEST_FAILED); + n = fread (buffer, 1, sizeof buffer, fp); + if (n == 64 || (n == 65 && buffer[64] == '\n')) + { + buffer[64] = 0; + for (n=0, s= buffer; + n < 32 && loxdigit_p (s) && loxdigit_p (s+1); + n++, s += 2) + buffer[n] = loxtoi_2 (s); + if ( n == 32 && !memcmp (digest, buffer, 32) ) + err = 0; + } fclose (fp); } } From cvs at cvs.gnupg.org Fri Sep 12 11:48:05 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 12 Sep 2008 11:48:05 +0200 Subject: [svn] gcry - r1324 - trunk/cipher Message-ID: Author: wk Date: 2008-09-12 11:48:04 +0200 (Fri, 12 Sep 2008) New Revision: 1324 Modified: trunk/cipher/ChangeLog trunk/cipher/rsa.c Log: Improved the encryption test. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-09-11 15:11:00 UTC (rev 1323) +++ trunk/cipher/ChangeLog 2008-09-12 09:48:04 UTC (rev 1324) @@ -1,3 +1,9 @@ +2008-09-12 Werner Koch + + * rsa.c (extract_a_from_sexp): New. + (selftest_encr_1024): Check that the ciphertext does not match the + plaintext. + 2008-09-11 Werner Koch * rsa.c (_gcry_rsa_decrypt): Return an error instead of calling Modified: trunk/cipher/rsa.c =================================================================== --- trunk/cipher/rsa.c 2008-09-11 15:11:00 UTC (rev 1323) +++ trunk/cipher/rsa.c 2008-09-12 09:48:04 UTC (rev 1324) @@ -816,37 +816,93 @@ } + +/* Given an S-expression ENCR_DATA of the form: + + (enc-val + (rsa + (a a-value))) + + as returned by gcry_pk_decrypt, return the the A-VALUE. On error, + return NULL. */ +static gcry_mpi_t +extract_a_from_sexp (gcry_sexp_t encr_data) +{ + gcry_sexp_t l1, l2, l3; + gcry_mpi_t a_value; + + l1 = gcry_sexp_find_token (encr_data, "enc-val", 0); + if (!l1) + return NULL; + l2 = gcry_sexp_find_token (l1, "rsa", 0); + gcry_sexp_release (l1); + if (!l2) + return NULL; + l3 = gcry_sexp_find_token (l2, "a", 0); + gcry_sexp_release (l2); + if (!l3) + return NULL; + a_value = gcry_sexp_nth_mpi (l3, 1, 0); + gcry_sexp_release (l3); + + return a_value; +} + + static const char * selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) { const char *errtxt = NULL; gcry_error_t err; const unsigned int nbits = 1000; /* Encrypt 1000 random bits. */ - gcry_mpi_t value = NULL; + gcry_mpi_t plaintext = NULL; gcry_sexp_t plain = NULL; gcry_sexp_t encr = NULL; + gcry_mpi_t ciphertext = NULL; gcry_sexp_t decr = NULL; - gcry_mpi_t decr_value = NULL; + gcry_mpi_t decr_plaintext = NULL; gcry_sexp_t tmplist = NULL; - /* Create plain text. */ - value = gcry_mpi_new (nbits); - gcry_mpi_randomize (value, nbits, GCRY_WEAK_RANDOM); + /* Create plaintext. The plaintext is actually a big integer number. */ + plaintext = gcry_mpi_new (nbits); + gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM); - err = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", value); + /* Put the plaintext into an S-expression. */ + err = gcry_sexp_build (&plain, NULL, + "(data (flags raw) (value %m))", plaintext); if (err) { errtxt = "converting data failed"; goto leave; } - /* Encrypt and decrypt. */ + /* Encrypt. */ err = gcry_pk_encrypt (&encr, plain, pkey); if (err) { errtxt = "encrypt failed"; goto leave; } + + /* Extraxt the ciphertext from the returned S-expression. */ + /*gcry_sexp_dump (encr);*/ + ciphertext = extract_a_from_sexp (encr); + if (!ciphertext) + { + errtxt = "gcry_pk_decrypt returned garbage"; + goto leave; + } + + /* Check that the ciphertext does no match the plaintext. */ + /* _gcry_log_mpidump ("plaintext", plaintext); */ + /* _gcry_log_mpidump ("ciphertxt", ciphertext); */ + if (!gcry_mpi_cmp (plaintext, ciphertext)) + { + errtxt = "ciphertext matches plaintext"; + goto leave; + } + + /* Decrypt. */ err = gcry_pk_decrypt (&decr, encr, skey); if (err) { @@ -854,23 +910,25 @@ goto leave; } - /* Extract decrypted data. The output of gcry_pk_decrypt depends on - whether a flags lists occurs in its input data. Because we - passed the output of gcry_pk_encrypt directly to gcry_pk_decrypt, - such a flag value won't be there as of today. To be prepared for - future changes we take care of it anyway. */ + /* Extract the decrypted data from the S-expression. Note that the + output of gcry_pk_decrypt depends on whether a flags lists occurs + in its input data. Because we passed the output of + gcry_pk_encrypt directly to gcry_pk_decrypt, such a flag value + won't be there as of today. To be prepared for future changes we + take care of it anyway. */ tmplist = gcry_sexp_find_token (decr, "value", 0); if (tmplist) - decr_value = gcry_sexp_nth_mpi (tmplist, 1, GCRYMPI_FMT_USG); + decr_plaintext = gcry_sexp_nth_mpi (tmplist, 1, GCRYMPI_FMT_USG); else - decr_value = gcry_sexp_nth_mpi (decr, 0, GCRYMPI_FMT_USG); - if (!decr_value) + decr_plaintext = gcry_sexp_nth_mpi (decr, 0, GCRYMPI_FMT_USG); + if (!decr_plaintext) { - errtxt = "decrypt returned no value"; + errtxt = "decrypt returned no plaintext"; goto leave; } - - if (gcry_mpi_cmp (value, decr_value)) + + /* Check that the decrypted plaintext matches the original plaintext. */ + if (gcry_mpi_cmp (plaintext, decr_plaintext)) { errtxt = "mismatch"; goto leave; @@ -878,11 +936,12 @@ leave: gcry_sexp_release (tmplist); - gcry_mpi_release (decr_value); + gcry_mpi_release (decr_plaintext); gcry_sexp_release (decr); + gcry_mpi_release (ciphertext); gcry_sexp_release (encr); gcry_sexp_release (plain); - gcry_mpi_release (value); + gcry_mpi_release (plaintext); return errtxt; } From cvs at cvs.gnupg.org Fri Sep 12 13:40:22 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 12 Sep 2008 13:40:22 +0200 Subject: [svn] gcry - r1325 - trunk/cipher Message-ID: Author: wk Date: 2008-09-12 13:40:22 +0200 (Fri, 12 Sep 2008) New Revision: 1325 Modified: trunk/cipher/ChangeLog trunk/cipher/dsa.c trunk/cipher/rsa.c Log: Improve selftest done after key generation. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-09-12 09:48:04 UTC (rev 1324) +++ trunk/cipher/ChangeLog 2008-09-12 11:40:22 UTC (rev 1325) @@ -3,6 +3,10 @@ * rsa.c (extract_a_from_sexp): New. (selftest_encr_1024): Check that the ciphertext does not match the plaintext. + (test_keys): Improve tests and return an error status. + (generate): Return an error if test_keys fails. + * dsa.c (test_keys): Add comments and return an error status. + (generate): Return an error if test_keys failed. 2008-09-11 Werner Koch Modified: trunk/cipher/dsa.c =================================================================== --- trunk/cipher/dsa.c 2008-09-12 09:48:04 UTC (rev 1324) +++ trunk/cipher/dsa.c 2008-09-12 11:40:22 UTC (rev 1325) @@ -87,7 +87,7 @@ static gcry_mpi_t gen_k (gcry_mpi_t q); -static void test_keys (DSA_secret_key *sk, unsigned qbits); +static int test_keys (DSA_secret_key *sk, unsigned int qbits); static int check_secret_key (DSA_secret_key *sk); static gpg_err_code_t generate (DSA_secret_key *sk, unsigned int nbits, @@ -183,27 +183,39 @@ } -static void -test_keys( DSA_secret_key *sk, unsigned qbits ) +/* Check that a freshly generated key actually works. Returns 0 on success. */ +static int +test_keys (DSA_secret_key *sk, unsigned int qbits) { + int result = -1; /* Default to failure. */ DSA_public_key pk; - gcry_mpi_t test = gcry_mpi_new ( qbits ); - gcry_mpi_t out1_a = gcry_mpi_new ( qbits ); - gcry_mpi_t out1_b = gcry_mpi_new ( qbits ); + gcry_mpi_t data = gcry_mpi_new (qbits); + gcry_mpi_t sig_a = gcry_mpi_new (qbits); + gcry_mpi_t sig_b = gcry_mpi_new (qbits); + /* Put the relevant parameters into a public key structure. */ pk.p = sk->p; pk.q = sk->q; pk.g = sk->g; pk.y = sk->y; - gcry_mpi_randomize( test, qbits, GCRY_WEAK_RANDOM ); - sign( out1_a, out1_b, test, sk ); - if( !verify( out1_a, out1_b, test, &pk ) ) - log_fatal("DSA:: sign, verify failed\n"); + /* Create a random plaintext. */ + gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM); - gcry_mpi_release ( test ); - gcry_mpi_release ( out1_a ); - gcry_mpi_release ( out1_b ); + /* Sign DATA using the secret key. */ + sign (sig_a, sig_b, data, sk); + + /* Verify the signature using the public key. */ + if ( !verify (sig_a, sig_b, data, &pk) ) + goto leave; /* Signature does not match. */ + + result = 0; /* The test succeeded. */ + + leave: + gcry_mpi_release (sig_b); + gcry_mpi_release (sig_a); + gcry_mpi_release (data); + return result; } @@ -323,7 +335,15 @@ sk->x = x; /* Now we can test our keys (this should never fail!). */ - test_keys( sk, qbits ); + if ( test_keys (sk, qbits) ) + { + gcry_mpi_release (sk->p); sk->p = NULL; + gcry_mpi_release (sk->q); sk->q = NULL; + gcry_mpi_release (sk->g); sk->g = NULL; + gcry_mpi_release (sk->y); sk->y = NULL; + gcry_mpi_release (sk->x); sk->x = NULL; + return GPG_ERR_SELFTEST_FAILED; + } return 0; } Modified: trunk/cipher/rsa.c =================================================================== --- trunk/cipher/rsa.c 2008-09-12 09:48:04 UTC (rev 1324) +++ trunk/cipher/rsa.c 2008-09-12 11:40:22 UTC (rev 1325) @@ -84,7 +84,7 @@ -static void test_keys (RSA_secret_key *sk, unsigned nbits); +static int test_keys (RSA_secret_key *sk, unsigned nbits); static gpg_err_code_t generate (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, int transient_key); @@ -93,29 +93,57 @@ static void secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey); -static void -test_keys( RSA_secret_key *sk, unsigned nbits ) +/* Check that a freshly generated key actually works. Returns 0 on success. */ +static int +test_keys (RSA_secret_key *sk, unsigned int nbits) { + int result = -1; /* Default to failure. */ RSA_public_key pk; - gcry_mpi_t test = gcry_mpi_new ( nbits ); - gcry_mpi_t out1 = gcry_mpi_new ( nbits ); - gcry_mpi_t out2 = gcry_mpi_new ( nbits ); + gcry_mpi_t plaintext = gcry_mpi_new (nbits); + gcry_mpi_t ciphertext = gcry_mpi_new (nbits); + gcry_mpi_t decr_plaintext = gcry_mpi_new (nbits); + gcry_mpi_t signature = gcry_mpi_new (nbits); + /* Put the relevant parameters into a public key structure. */ pk.n = sk->n; pk.e = sk->e; - gcry_mpi_randomize( test, nbits, GCRY_WEAK_RANDOM ); - public( out1, test, &pk ); - secret( out2, out1, sk ); - if( mpi_cmp( test, out2 ) ) - log_fatal("RSA operation: public, secret failed\n"); - secret( out1, test, sk ); - public( out2, out1, &pk ); - if( mpi_cmp( test, out2 ) ) - log_fatal("RSA operation: secret, public failed\n"); - gcry_mpi_release ( test ); - gcry_mpi_release ( out1 ); - gcry_mpi_release ( out2 ); + /* Create a random plaintext. */ + gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM); + + /* Encrypt using the public key. */ + public (ciphertext, plaintext, &pk); + + /* Check that the cipher text does not match the plaintext. */ + if (!gcry_mpi_cmp (ciphertext, plaintext)) + goto leave; /* Ciphertext is identical to the plaintext. */ + + /* Decrypt using the secret key. */ + secret (decr_plaintext, ciphertext, sk); + + /* Check that the decrypted plaintext matches the original plaintext. */ + if (gcry_mpi_cmp (decr_plaintext, plaintext)) + goto leave; /* Plaintext does not match. */ + + /* Create another random plaintext as data for signature checking. */ + gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM); + + /* Use the RSA secret function to create a signature of the plaintext. */ + secret (signature, plaintext, sk); + + /* Use the RSA public function to verify this signature. */ + public (decr_plaintext, signature, &pk); + if (gcry_mpi_cmp (decr_plaintext, plaintext)) + goto leave; /* Signature does not match. */ + + result = 0; /* All tests succeeded. */ + + leave: + gcry_mpi_release (signature); + gcry_mpi_release (decr_plaintext); + gcry_mpi_release (ciphertext); + gcry_mpi_release (plaintext); + return result; } @@ -279,8 +307,17 @@ sk->d = d; sk->u = u; - /* now we can test our keys (this should never fail!) */ - test_keys( sk, nbits - 64 ); + /* Now we can test our keys. */ + if (test_keys (sk, nbits - 64)) + { + gcry_mpi_release (sk->n); sk->n = NULL; + gcry_mpi_release (sk->e); sk->e = NULL; + gcry_mpi_release (sk->p); sk->p = NULL; + gcry_mpi_release (sk->q); sk->q = NULL; + gcry_mpi_release (sk->d); sk->d = NULL; + gcry_mpi_release (sk->u); sk->u = NULL; + return GPG_ERR_SELFTEST_FAILED; + } return 0; } From cvs at cvs.gnupg.org Fri Sep 12 14:33:28 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 12 Sep 2008 14:33:28 +0200 Subject: [svn] gcry - r1326 - trunk/cipher Message-ID: Author: wk Date: 2008-09-12 14:33:28 +0200 (Fri, 12 Sep 2008) New Revision: 1326 Added: trunk/cipher/hash-common.c trunk/cipher/hash-common.h Log: Add files. From cvs at cvs.gnupg.org Fri Sep 12 16:47:29 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 12 Sep 2008 16:47:29 +0200 Subject: [svn] gcry - r1327 - in trunk: cipher src Message-ID: Author: wk Date: 2008-09-12 16:47:28 +0200 (Fri, 12 Sep 2008) New Revision: 1327 Modified: trunk/cipher/ChangeLog trunk/cipher/cipher.c trunk/cipher/des.c trunk/cipher/dsa.c trunk/cipher/hmac-tests.c trunk/cipher/md.c trunk/cipher/pubkey.c trunk/cipher/rijndael.c trunk/cipher/rsa.c trunk/cipher/sha1.c trunk/cipher/sha256.c trunk/cipher/sha512.c trunk/src/ChangeLog trunk/src/cipher-proto.h trunk/src/fips.c trunk/src/g10lib.h trunk/src/global.c Log: Only run required tests during power-up self-test. Enter error state after a failed key generation tests. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/ChangeLog 2008-09-12 14:47:28 UTC (rev 1327) @@ -1,5 +1,41 @@ 2008-09-12 Werner Koch + * cipher.c (_gcry_cipher_selftest): Add arg EXTENDED and pass it + to the called tests. + * md.c (_gcry_md_selftest): Ditto. + * pubkey.c (_gcry_pk_selftest): Ditto. + * rijndael.c (run_selftests): Add arg EXTENDED and pass it to the + called tests. + (selftest_fips_128): Add arg EXTENDED and run only one test + non-extended mode. + (selftest_fips_192): Add dummy arg EXTENDED. + (selftest_fips_256): Ditto. + * hmac-tests.c (_gcry_hmac_selftest): Ditto. + (run_selftests): Ditto. + (selftests_sha1): Add arg EXTENDED and run only one test + non-extended mode. + (selftests_sha224, selftests_sha256): Ditto. + (selftests_sha384, selftests_sha512): Ditto. + * sha1.c (run_selftests): Add arg EXTENDED and pass it to the + called test. + (selftests_sha1): Add arg EXTENDED and run only one test + non-extended mode. + * sha256.c (run_selftests): Add arg EXTENDED and pass it to the + called tests. + (selftests_sha224): Add arg EXTENDED and run only one test + non-extended mode. + (selftests_sha256): Ditto. + * sha512.c (run_selftests): Add arg EXTENDED and pass it to the + called tests. + (selftests_sha384): Add arg EXTENDED and run only one test + non-extended mode. + (selftests_sha512): Ditto. + * des.c (run_selftests): Add arg EXTENDED and pass it to the + called test. + (selftest_fips): Add dummy arg EXTENDED. + * rsa.c (run_selftests): Add dummy arg EXTENDED. + * dsa.c (run_selftests): Add dummy arg EXTENDED. + * rsa.c (extract_a_from_sexp): New. (selftest_encr_1024): Check that the ciphertext does not match the plaintext. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/src/ChangeLog 2008-09-12 14:47:28 UTC (rev 1327) @@ -1,3 +1,10 @@ +2008-09-12 Werner Koch + + * fips.c (_gcry_fips_run_selftests): Add arg EXTENDED. + (run_cipher_selftests, run_digest_selftests, run_hmac_selftests) + (run_pubkey_selftests): Ditto. + * cipher-proto.h (selftest_func_t): Add arg EXTENDED + 2008-09-11 Werner Koch * fips.c: Include string.h. Modified: trunk/cipher/cipher.c =================================================================== --- trunk/cipher/cipher.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/cipher.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -1859,7 +1859,7 @@ /* Run the selftests for cipher algorithm ALGO with optional reporting function REPORT. */ gpg_error_t -_gcry_cipher_selftest (int algo, selftest_report_func_t report) +_gcry_cipher_selftest (int algo, int extended, selftest_report_func_t report) { gcry_module_t module = NULL; cipher_extra_spec_t *extraspec = NULL; @@ -1873,7 +1873,7 @@ extraspec = module->extraspec; ath_mutex_unlock (&ciphers_registered_lock); if (extraspec && extraspec->selftest) - ec = extraspec->selftest (algo, report); + ec = extraspec->selftest (algo, extended, report); else { ec = GPG_ERR_CIPHER_ALGO; Modified: trunk/cipher/des.c =================================================================== --- trunk/cipher/des.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/des.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -1089,11 +1089,13 @@ /* Selftest for TripleDES. */ static gpg_err_code_t -selftest_fips (selftest_report_func_t report) +selftest_fips (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; + (void)extended; /* No extended tests available. */ + what = "low-level"; errtxt = selftest (); if (errtxt) @@ -1116,14 +1118,14 @@ /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t -run_selftests (int algo, selftest_report_func_t report) +run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_CIPHER_3DES: - ec = selftest_fips (report); + ec = selftest_fips (extended, report); break; default: ec = GPG_ERR_CIPHER_ALGO; Modified: trunk/cipher/dsa.c =================================================================== --- trunk/cipher/dsa.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/dsa.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -342,6 +342,7 @@ gcry_mpi_release (sk->g); sk->g = NULL; gcry_mpi_release (sk->y); sk->y = NULL; gcry_mpi_release (sk->x); sk->x = NULL; + fips_signal_error ("self-test after key generation failed"); return GPG_ERR_SELFTEST_FAILED; } return 0; @@ -703,10 +704,12 @@ /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t -run_selftests (int algo, selftest_report_func_t report) +run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; + (void)extended; + switch (algo) { case GCRY_PK_DSA: Modified: trunk/cipher/hmac-tests.c =================================================================== --- trunk/cipher/hmac-tests.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/hmac-tests.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -93,7 +93,7 @@ static gpg_err_code_t -selftests_sha1 (selftest_report_func_t report) +selftests_sha1 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; @@ -111,40 +111,42 @@ if (errtxt) goto failed; - what = "FIPS-198a, A.2"; - for (i=0, j=0x30; i < 20; i++) - key[i] = j++; - errtxt = check_one (GCRY_MD_SHA1, - "Sample #2", 9, - key, 20, - "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82" - "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24", 20); - if (errtxt) - goto failed; + if (extended) + { + what = "FIPS-198a, A.2"; + for (i=0, j=0x30; i < 20; i++) + key[i] = j++; + errtxt = check_one (GCRY_MD_SHA1, + "Sample #2", 9, + key, 20, + "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82" + "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24", 20); + if (errtxt) + goto failed; + + what = "FIPS-198a, A.3"; + for (i=0, j=0x50; i < 100; i++) + key[i] = j++; + errtxt = check_one (GCRY_MD_SHA1, + "Sample #3", 9, + key, 100, + "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0" + "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa", 20 ); + if (errtxt) + goto failed; + + what = "FIPS-198a, A.4"; + for (i=0, j=0x70; i < 49; i++) + key[i] = j++; + errtxt = check_one (GCRY_MD_SHA1, + "Sample #4", 9, + key, 49, + "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42" + "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26", 20 ); + if (errtxt) + goto failed; + } - what = "FIPS-198a, A.3"; - for (i=0, j=0x50; i < 100; i++) - key[i] = j++; - errtxt = check_one (GCRY_MD_SHA1, - "Sample #3", 9, - key, 100, - "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0" - "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa", 20 ); - if (errtxt) - goto failed; - - what = "FIPS-198a, A.4"; - for (i=0, j=0x70; i < 49; i++) - key[i] = j++; - errtxt = check_one (GCRY_MD_SHA1, - "Sample #4", 9, - key, 49, - "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42" - "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26", 20 ); - if (errtxt) - goto failed; - - return 0; /* Succeeded. */ failed: @@ -156,7 +158,7 @@ static gpg_err_code_t -selftests_sha224 (selftest_report_func_t report) +selftests_sha224 (int extended, selftest_report_func_t report) { static struct { @@ -256,6 +258,8 @@ tv[tvidx].expect, DIM (tv[tvidx].expect) ); if (errtxt) goto failed; + if (!extended) + break; } return 0; /* Succeeded. */ @@ -268,7 +272,7 @@ static gpg_err_code_t -selftests_sha256 (selftest_report_func_t report) +selftests_sha256 (int extended, selftest_report_func_t report) { static struct { @@ -395,6 +399,9 @@ goto failed; } _gcry_hmac256_release (hmachd); + + if (!extended) + break; } return 0; /* Succeeded. */ @@ -407,7 +414,7 @@ static gpg_err_code_t -selftests_sha384 (selftest_report_func_t report) +selftests_sha384 (int extended, selftest_report_func_t report) { static struct { @@ -519,6 +526,8 @@ tv[tvidx].expect, DIM (tv[tvidx].expect) ); if (errtxt) goto failed; + if (!extended) + break; } return 0; /* Succeeded. */ @@ -531,7 +540,7 @@ static gpg_err_code_t -selftests_sha512 (selftest_report_func_t report) +selftests_sha512 (int extended, selftest_report_func_t report) { static struct { @@ -655,6 +664,8 @@ tv[tvidx].expect, DIM (tv[tvidx].expect) ); if (errtxt) goto failed; + if (!extended) + break; } return 0; /* Succeeded. */ @@ -669,26 +680,26 @@ /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t -run_selftests (int algo, selftest_report_func_t report) +run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_MD_SHA1: - ec = selftests_sha1 (report); + ec = selftests_sha1 (extended, report); break; case GCRY_MD_SHA224: - ec = selftests_sha224 (report); + ec = selftests_sha224 (extended, report); break; case GCRY_MD_SHA256: - ec = selftests_sha256 (report); + ec = selftests_sha256 (extended, report); break; case GCRY_MD_SHA384: - ec = selftests_sha384 (report); + ec = selftests_sha384 (extended, report); break; case GCRY_MD_SHA512: - ec = selftests_sha512 (report); + ec = selftests_sha512 (extended, report); break; default: ec = GPG_ERR_DIGEST_ALGO; @@ -703,13 +714,13 @@ /* Run the selftests for HMAC with digest algorithm ALGO with optional reporting function REPORT. */ gpg_error_t -_gcry_hmac_selftest (int algo, selftest_report_func_t report) +_gcry_hmac_selftest (int algo, int extended, selftest_report_func_t report) { gcry_err_code_t ec = 0; if (!gcry_md_test_algo (algo)) { - ec = run_selftests (algo, report); + ec = run_selftests (algo, extended, report); } else { Modified: trunk/cipher/md.c =================================================================== --- trunk/cipher/md.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/md.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -1305,7 +1305,7 @@ /* Run the selftests for digest algorithm ALGO with optional reporting function REPORT. */ gpg_error_t -_gcry_md_selftest (int algo, selftest_report_func_t report) +_gcry_md_selftest (int algo, int extended, selftest_report_func_t report) { gcry_module_t module = NULL; cipher_extra_spec_t *extraspec = NULL; @@ -1319,7 +1319,7 @@ extraspec = module->extraspec; ath_mutex_unlock (&digests_registered_lock); if (extraspec && extraspec->selftest) - ec = extraspec->selftest (algo, report); + ec = extraspec->selftest (algo, extended, report); else { ec = GPG_ERR_DIGEST_ALGO; Modified: trunk/cipher/pubkey.c =================================================================== --- trunk/cipher/pubkey.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/pubkey.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -2714,7 +2714,7 @@ /* Run the selftests for pubkey algorithm ALGO with optional reporting function REPORT. */ gpg_error_t -_gcry_pk_selftest (int algo, selftest_report_func_t report) +_gcry_pk_selftest (int algo, int extended, selftest_report_func_t report) { gcry_module_t module = NULL; pk_extra_spec_t *extraspec = NULL; @@ -2728,7 +2728,7 @@ extraspec = module->extraspec; ath_mutex_unlock (&pubkeys_registered_lock); if (extraspec && extraspec->selftest) - ec = extraspec->selftest (algo, report); + ec = extraspec->selftest (algo, extended, report); else { ec = GPG_ERR_PUBKEY_ALGO; Modified: trunk/cipher/rijndael.c =================================================================== --- trunk/cipher/rijndael.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/rijndael.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -1046,7 +1046,7 @@ /* Complete selftest for AES-128 with all modes and driver code. */ static gpg_err_code_t -selftest_fips_128 (selftest_report_func_t report) +selftest_fips_128 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; @@ -1056,17 +1056,19 @@ if (errtxt) goto failed; - what = "cfb"; - errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_CFB); - if (errtxt) - goto failed; + if (extended) + { + what = "cfb"; + errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_CFB); + if (errtxt) + goto failed; + + what = "ofb"; + errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_OFB); + if (errtxt) + goto failed; + } - what = "ofb"; - errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_OFB); - if (errtxt) - goto failed; - - return 0; /* Succeeded. */ failed: @@ -1075,21 +1077,21 @@ return GPG_ERR_SELFTEST_FAILED; } -/* Complete selftest for AES-192 with all modes and driver code. */ +/* Complete selftest for AES-192. */ static gpg_err_code_t -selftest_fips_192 (selftest_report_func_t report) +selftest_fips_192 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; + (void)extended; /* No extended tests available. */ + what = "low-level"; errtxt = selftest_basic_192 (); if (errtxt) goto failed; - - return 0; /* Succeeded. */ failed: @@ -1099,13 +1101,15 @@ } -/* Complete selftest for AES-256 with all modes and driver code. */ +/* Complete selftest for AES-256. */ static gpg_err_code_t -selftest_fips_256 (selftest_report_func_t report) +selftest_fips_256 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; + (void)extended; /* No extended tests available. */ + what = "low-level"; errtxt = selftest_basic_256 (); if (errtxt) @@ -1123,20 +1127,20 @@ /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t -run_selftests (int algo, selftest_report_func_t report) +run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_CIPHER_AES128: - ec = selftest_fips_128 (report); + ec = selftest_fips_128 (extended, report); break; case GCRY_CIPHER_AES192: - ec = selftest_fips_192 (report); + ec = selftest_fips_192 (extended, report); break; case GCRY_CIPHER_AES256: - ec = selftest_fips_256 (report); + ec = selftest_fips_256 (extended, report); break; default: ec = GPG_ERR_CIPHER_ALGO; Modified: trunk/cipher/rsa.c =================================================================== --- trunk/cipher/rsa.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/rsa.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -316,6 +316,7 @@ gcry_mpi_release (sk->q); sk->q = NULL; gcry_mpi_release (sk->d); sk->d = NULL; gcry_mpi_release (sk->u); sk->u = NULL; + fips_signal_error ("self-test after key generation failed"); return GPG_ERR_SELFTEST_FAILED; } @@ -1038,10 +1039,12 @@ /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t -run_selftests (int algo, selftest_report_func_t report) +run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; + (void)extended; + switch (algo) { case GCRY_PK_RSA: Modified: trunk/cipher/sha1.c =================================================================== --- trunk/cipher/sha1.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/sha1.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -381,7 +381,7 @@ static gpg_err_code_t -selftests_sha1 (selftest_report_func_t report) +selftests_sha1 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; @@ -395,24 +395,27 @@ if (errtxt) goto failed; - what = "long string"; - errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA1, 0, - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, - "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE" - "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1", 20); - if (errtxt) - goto failed; + if (extended) + { + what = "long string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA1, 0, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE" + "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1", 20); + if (errtxt) + goto failed; + + what = "one million \"a\""; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA1, 1, + NULL, 0, + "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E" + "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F", 20); + if (errtxt) + goto failed; + } - what = "one million \"a\""; - errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA1, 1, - NULL, 0, - "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E" - "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F", 20); - if (errtxt) - goto failed; - return 0; /* Succeeded. */ failed: @@ -424,14 +427,14 @@ /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t -run_selftests (int algo, selftest_report_func_t report) +run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_MD_SHA1: - ec = selftests_sha1 (report); + ec = selftests_sha1 (extended, report); break; default: ec = GPG_ERR_DIGEST_ALGO; Modified: trunk/cipher/sha256.c =================================================================== --- trunk/cipher/sha256.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/sha256.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -321,7 +321,7 @@ static gpg_err_code_t -selftests_sha224 (selftest_report_func_t report) +selftests_sha224 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; @@ -335,24 +335,27 @@ if (errtxt) goto failed; - what = "long string"; - errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA224, 0, - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, - "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50" - "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28); - if (errtxt) - goto failed; + if (extended) + { + what = "long string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA224, 0, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50" + "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25", 28); + if (errtxt) + goto failed; + + what = "one million \"a\""; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA224, 1, + NULL, 0, + "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b" + "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67", 28); + if (errtxt) + goto failed; + } - what = "one million \"a\""; - errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA224, 1, - NULL, 0, - "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b" - "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67", 28); - if (errtxt) - goto failed; - return 0; /* Succeeded. */ failed: @@ -362,7 +365,7 @@ } static gpg_err_code_t -selftests_sha256 (selftest_report_func_t report) +selftests_sha256 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; @@ -376,24 +379,29 @@ if (errtxt) goto failed; - what = "long string"; - errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA256, 0, - "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, - "\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", 32); - if (errtxt) - goto failed; + if (extended) + { + what = "long string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA256, 0, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56, + "\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", + 32); + if (errtxt) + goto failed; + + what = "one million \"a\""; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA256, 1, + NULL, 0, + "\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", + 32); + if (errtxt) + goto failed; + } - what = "one million \"a\""; - errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA256, 1, - NULL, 0, - "\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", 32); - if (errtxt) - goto failed; - return 0; /* Succeeded. */ failed: @@ -405,17 +413,17 @@ /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t -run_selftests (int algo, selftest_report_func_t report) +run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_MD_SHA224: - ec = selftests_sha224 (report); + ec = selftests_sha224 (extended, report); break; case GCRY_MD_SHA256: - ec = selftests_sha256 (report); + ec = selftests_sha256 (extended, report); break; default: ec = GPG_ERR_DIGEST_ALGO; Modified: trunk/cipher/sha512.c =================================================================== --- trunk/cipher/sha512.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/cipher/sha512.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -368,7 +368,7 @@ static gpg_err_code_t -selftests_sha384 (selftest_report_func_t report) +selftests_sha384 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; @@ -383,26 +383,31 @@ if (errtxt) goto failed; - what = "long string"; - errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA384, 0, - "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, - "\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47" - "\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12" - "\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39", 48); - if (errtxt) - goto failed; + if (extended) + { + what = "long string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA384, 0, + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47" + "\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12" + "\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39", + 48); + if (errtxt) + goto failed; - what = "one million \"a\""; - errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA384, 1, - NULL, 0, - "\x9D\x0E\x18\x09\x71\x64\x74\xCB\x08\x6E\x83\x4E\x31\x0A\x4A\x1C" - "\xED\x14\x9E\x9C\x00\xF2\x48\x52\x79\x72\xCE\xC5\x70\x4C\x2A\x5B" - "\x07\xB8\xB3\xDC\x38\xEC\xC4\xEB\xAE\x97\xDD\xD8\x7F\x3D\x89\x85", 48); - if (errtxt) - goto failed; + what = "one million \"a\""; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA384, 1, + NULL, 0, + "\x9D\x0E\x18\x09\x71\x64\x74\xCB\x08\x6E\x83\x4E\x31\x0A\x4A\x1C" + "\xED\x14\x9E\x9C\x00\xF2\x48\x52\x79\x72\xCE\xC5\x70\x4C\x2A\x5B" + "\x07\xB8\xB3\xDC\x38\xEC\xC4\xEB\xAE\x97\xDD\xD8\x7F\x3D\x89\x85", + 48); + if (errtxt) + goto failed; + } return 0; /* Succeeded. */ @@ -413,7 +418,7 @@ } static gpg_err_code_t -selftests_sha512 (selftest_report_func_t report) +selftests_sha512 (int extended, selftest_report_func_t report) { const char *what; const char *errtxt; @@ -429,29 +434,34 @@ if (errtxt) goto failed; - what = "long string"; - errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA512, 0, - "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" - "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, - "\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F" - "\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18" - "\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A" - "\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09", 64); - if (errtxt) - goto failed; + if (extended) + { + what = "long string"; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA512, 0, + "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112, + "\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F" + "\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18" + "\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A" + "\xC7\xD3\x29\xEE\xB6\xDD\x26\x54\x5E\x96\xE5\x5B\x87\x4B\xE9\x09", + 64); + if (errtxt) + goto failed; + + what = "one million \"a\""; + errtxt = _gcry_hash_selftest_check_one + (GCRY_MD_SHA512, 1, + NULL, 0, + "\xE7\x18\x48\x3D\x0C\xE7\x69\x64\x4E\x2E\x42\xC7\xBC\x15\xB4\x63" + "\x8E\x1F\x98\xB1\x3B\x20\x44\x28\x56\x32\xA8\x03\xAF\xA9\x73\xEB" + "\xDE\x0F\xF2\x44\x87\x7E\xA6\x0A\x4C\xB0\x43\x2C\xE5\x77\xC3\x1B" + "\xEB\x00\x9C\x5C\x2C\x49\xAA\x2E\x4E\xAD\xB2\x17\xAD\x8C\xC0\x9B", + 64); + if (errtxt) + goto failed; + } - what = "one million \"a\""; - errtxt = _gcry_hash_selftest_check_one - (GCRY_MD_SHA512, 1, - NULL, 0, - "\xE7\x18\x48\x3D\x0C\xE7\x69\x64\x4E\x2E\x42\xC7\xBC\x15\xB4\x63" - "\x8E\x1F\x98\xB1\x3B\x20\x44\x28\x56\x32\xA8\x03\xAF\xA9\x73\xEB" - "\xDE\x0F\xF2\x44\x87\x7E\xA6\x0A\x4C\xB0\x43\x2C\xE5\x77\xC3\x1B" - "\xEB\x00\x9C\x5C\x2C\x49\xAA\x2E\x4E\xAD\xB2\x17\xAD\x8C\xC0\x9B", 64); - if (errtxt) - goto failed; - return 0; /* Succeeded. */ failed: @@ -463,17 +473,17 @@ /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t -run_selftests (int algo, selftest_report_func_t report) +run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; switch (algo) { case GCRY_MD_SHA384: - ec = selftests_sha384 (report); + ec = selftests_sha384 (extended, report); break; case GCRY_MD_SHA512: - ec = selftests_sha512 (report); + ec = selftests_sha512 (extended, report); break; default: ec = GPG_ERR_DIGEST_ALGO; Modified: trunk/src/cipher-proto.h =================================================================== --- trunk/src/cipher-proto.h 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/src/cipher-proto.h 2008-09-12 14:47:28 UTC (rev 1327) @@ -36,7 +36,7 @@ /* Definition of the selftest functions. */ typedef gpg_err_code_t (*selftest_func_t) - (int algo, selftest_report_func_t report); + (int algo, int extended, selftest_report_func_t report); /* An extended type of the generate function. */ @@ -90,10 +90,14 @@ gcry_module_t *module); /* The selftest functions. */ -gcry_error_t _gcry_cipher_selftest (int algo, selftest_report_func_t report); -gcry_error_t _gcry_md_selftest (int algo, selftest_report_func_t report); -gcry_error_t _gcry_pk_selftest (int algo, selftest_report_func_t report); -gcry_error_t _gcry_hmac_selftest (int algo, selftest_report_func_t report); +gcry_error_t _gcry_cipher_selftest (int algo, int extended, + selftest_report_func_t report); +gcry_error_t _gcry_md_selftest (int algo, int extended, + selftest_report_func_t report); +gcry_error_t _gcry_pk_selftest (int algo, int extended, + selftest_report_func_t report); +gcry_error_t _gcry_hmac_selftest (int algo, int extended, + selftest_report_func_t report); gcry_error_t _gcry_random_selftest (selftest_report_func_t report); Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/src/fips.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -269,7 +269,7 @@ performed by severeal threads; that is no problem because our FSM make sure that we won't oversee any error. */ unlock_fsm (); - _gcry_fips_run_selftests (); + _gcry_fips_run_selftests (0); lock_fsm (); } @@ -340,7 +340,7 @@ /* Run self-tests for all required cipher algorithms. Return 0 on success. */ static int -run_cipher_selftests (void) +run_cipher_selftests (int extended) { static int algos[] = { @@ -356,7 +356,7 @@ for (idx=0; algos[idx]; idx++) { - err = _gcry_cipher_selftest (algos[idx], reporter); + err = _gcry_cipher_selftest (algos[idx], extended, reporter); reporter ("cipher", algos[idx], NULL, err? gpg_strerror (err):NULL); if (err) @@ -369,7 +369,7 @@ /* Run self-tests for all required hash algorithms. Return 0 on success. */ static int -run_digest_selftests (void) +run_digest_selftests (int extended) { static int algos[] = { @@ -386,7 +386,7 @@ for (idx=0; algos[idx]; idx++) { - err = _gcry_md_selftest (algos[idx], reporter); + err = _gcry_md_selftest (algos[idx], extended, reporter); reporter ("digest", algos[idx], NULL, err? gpg_strerror (err):NULL); if (err) @@ -398,7 +398,7 @@ /* Run self-tests for all HMAC algorithms. Return 0 on success. */ static int -run_hmac_selftests (void) +run_hmac_selftests (int extended) { static int algos[] = { @@ -415,7 +415,7 @@ for (idx=0; algos[idx]; idx++) { - err = _gcry_hmac_selftest (algos[idx], reporter); + err = _gcry_hmac_selftest (algos[idx], extended, reporter); reporter ("hmac", algos[idx], NULL, err? gpg_strerror (err):NULL); if (err) @@ -428,7 +428,7 @@ /* Run self-tests for all required public key algorithms. Return 0 on success. */ static int -run_pubkey_selftests (void) +run_pubkey_selftests (int extended) { static int algos[] = { @@ -443,7 +443,7 @@ for (idx=0; algos[idx]; idx++) { - err = _gcry_pk_selftest (algos[idx], reporter); + err = _gcry_pk_selftest (algos[idx], extended, reporter); reporter ("pubkey", algos[idx], NULL, err? gpg_strerror (err):NULL); if (err) @@ -550,9 +550,10 @@ } -/* Run the self-tests. */ +/* Run the self-tests. If EXTENDED is true, extended versions of the + selftest are run, that is more tests than required by FIPS. */ gpg_err_code_t -_gcry_fips_run_selftests (void) +_gcry_fips_run_selftests (int extended) { enum module_states result = STATE_ERROR; gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED; @@ -560,13 +561,13 @@ if (fips_mode ()) fips_new_state (STATE_SELFTEST); - if (run_cipher_selftests ()) + if (run_cipher_selftests (extended)) goto leave; - if (run_digest_selftests ()) + if (run_digest_selftests (extended)) goto leave; - if (run_hmac_selftests ()) + if (run_hmac_selftests (extended)) goto leave; /* Run random tests before the pubkey tests because the latter @@ -574,7 +575,7 @@ if (run_random_selftests ()) goto leave; - if (run_pubkey_selftests ()) + if (run_pubkey_selftests (extended)) goto leave; /* Now check the integrity of the binary. We do this this after Modified: trunk/src/g10lib.h =================================================================== --- trunk/src/g10lib.h 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/src/g10lib.h 2008-09-12 14:47:28 UTC (rev 1327) @@ -316,7 +316,7 @@ int _gcry_fips_test_operational (void); int _gcry_fips_test_error_or_operational (void); -gpg_err_code_t _gcry_fips_run_selftests (void); +gpg_err_code_t _gcry_fips_run_selftests (int extended); void _gcry_fips_noreturn (void); #define fips_noreturn() (_gcry_fips_noreturn ()) Modified: trunk/src/global.c =================================================================== --- trunk/src/global.c 2008-09-12 12:33:28 UTC (rev 1326) +++ trunk/src/global.c 2008-09-12 14:47:28 UTC (rev 1327) @@ -469,17 +469,19 @@ run a selftest. If not we use the is_operational call to force us into operational state if possible. */ if (_gcry_fips_test_error_or_operational ()) - _gcry_fips_run_selftests (); + _gcry_fips_run_selftests (1); if (_gcry_fips_is_operational ()) err = GPG_ERR_GENERAL; /* Used as TRUE value */ } break; case GCRYCTL_SELFTEST: - /* Run a selftest. This works in fips mode as weel as in - standard mode. Returns 0 on success or an error code. */ + /* Run a selftest. This works in fips mode as well as in + standard mode. In contrast to the power-up tests, we use an + extended version ofthe selftests. Returns 0 on success or an + error code. */ global_init (); - err = _gcry_fips_run_selftests (); + err = _gcry_fips_run_selftests (1); break; default: From cvs at cvs.gnupg.org Fri Sep 12 21:00:03 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 12 Sep 2008 21:00:03 +0200 Subject: [svn] gcry - r1328 - trunk/cipher Message-ID: Author: wk Date: 2008-09-12 21:00:03 +0200 (Fri, 12 Sep 2008) New Revision: 1328 Modified: trunk/cipher/ChangeLog trunk/cipher/dsa.c trunk/cipher/rsa.c Log: Add a bad-case test for the key generation. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-09-12 14:47:28 UTC (rev 1327) +++ trunk/cipher/ChangeLog 2008-09-12 19:00:03 UTC (rev 1328) @@ -1,5 +1,8 @@ 2008-09-12 Werner Koch + * rsa.c (test_keys): Do a bad case signature check. + * dsa.c (test_keys): Do a bad case check. + * cipher.c (_gcry_cipher_selftest): Add arg EXTENDED and pass it to the called tests. * md.c (_gcry_md_selftest): Ditto. @@ -34,6 +37,7 @@ called test. (selftest_fips): Add dummy arg EXTENDED. * rsa.c (run_selftests): Add dummy arg EXTENDED. + * dsa.c (run_selftests): Add dummy arg EXTENDED. * rsa.c (extract_a_from_sexp): New. Modified: trunk/cipher/dsa.c =================================================================== --- trunk/cipher/dsa.c 2008-09-12 14:47:28 UTC (rev 1327) +++ trunk/cipher/dsa.c 2008-09-12 19:00:03 UTC (rev 1328) @@ -209,6 +209,11 @@ if ( !verify (sig_a, sig_b, data, &pk) ) goto leave; /* Signature does not match. */ + /* Modify the data and check that the signing fails. */ + gcry_mpi_add_ui (data, data, 1); + if ( verify (sig_a, sig_b, data, &pk) ) + goto leave; /* Signature matches but should not. */ + result = 0; /* The test succeeded. */ leave: Modified: trunk/cipher/rsa.c =================================================================== --- trunk/cipher/rsa.c 2008-09-12 14:47:28 UTC (rev 1327) +++ trunk/cipher/rsa.c 2008-09-12 19:00:03 UTC (rev 1328) @@ -136,6 +136,12 @@ if (gcry_mpi_cmp (decr_plaintext, plaintext)) goto leave; /* Signature does not match. */ + /* Modify the signature and check that the signing fails. */ + gcry_mpi_add_ui (signature, signature, 1); + public (decr_plaintext, signature, &pk); + if (!gcry_mpi_cmp (decr_plaintext, plaintext)) + goto leave; /* Signature matches but should not. */ + result = 0; /* All tests succeeded. */ leave: From cvs at cvs.gnupg.org Fri Sep 12 21:11:10 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 12 Sep 2008 21:11:10 +0200 Subject: [svn] gcry - r1329 - trunk/doc Message-ID: Author: wk Date: 2008-09-12 21:11:10 +0200 (Fri, 12 Sep 2008) New Revision: 1329 Modified: trunk/doc/gcrypt.texi Log: Add a new appendix with the description of the self-tests. Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-12 19:00:03 UTC (rev 1328) +++ trunk/doc/gcrypt.texi 2008-09-12 19:11:10 UTC (rev 1329) @@ -77,6 +77,7 @@ Appendices +* Self-Tests:: Description of self-tests. * FIPS Restrictions:: Restrictions in FIPS mode. * FIPS Finite State Machine:: Description of the FIPS FSM. * Library Copying:: The GNU Lesser General Public License @@ -550,7 +551,7 @@ Once Libgcrypt has been put into FIPS mode, it is not possible to switch back to standard mode without terminating the process first. If the logging verbosity level of Libgcrypt has been set to at least -2, the state transitions and the selftests are logged. +2, the state transitions and the self-tests are logged. @@ -768,7 +769,7 @@ @item GCRYCTL_FORCE_FIPS_MODE; Arguments: none Running this command puts the library into FIPS mode. If the library is -already in FIPS mode, a selftest is triggered and thus the library will +already in FIPS mode, a self-test is triggered and thus the library will be put into operational state. This command may be used before a call to gcry_check_version and that is actually the recommended way to let an application switch the library into FIPS mode. Note that Libgcrypt will @@ -776,7 +777,7 @@ @item GCRYCTL_SELFTEST; Arguments: none This may be used at anytime to have the library run all implemented -selftests. It works in standard and in FIPS mode. Returns 0 on +self-tests. It works in standard and in FIPS mode. Returns 0 on success or an error code on failure. @@ -4932,7 +4933,7 @@ weaker requirements for a nonce generator and to save precious kernel entropy for use by the ``real'' random generators. -A self test facility uses a separate context to check the +A self-test facility uses a separate context to check the functionality of the core X9.31 functions using a known answers test. During runtime each output block is compared to the previous one to detect a stucked generator. @@ -4993,9 +4994,343 @@ @c ********************************************************** @c ******************************************** + at node Self-Tests + at appendix Description of Self-Tests + +In addition to the build time regression test suite, Libgcrypt +implements self-tests to be performed at runtime. Which self-tests +are actually used depends on the mode Libgcrypt is used in. In +standard mode a limited set of self-tests is run at the time an +algorithm is first used. Note that not all algorithms feature a +self-test in standard mode. The @code{GCRYCTL_SELFTEST} control +command may be used to run all implemented self-tests at any time; +this will even run more tests than those run in FIPS mode. + +If any of the self-tests fails, the library immediately returns an +error code to the caller. If Libgcrypt is in FIPS mode the self-tests +will be performed within the ``Self-Test'' state and any failure puts +the library into the ``Error'' state. + + at c -------------------------------- + at section Power-Up Tests + +Power-up tests are only performed if Libgcrypt is in FIPS mode. + + at subsection Symmetric Cipher Algorithm Power-Up Tests + +The following symmetric encryption algorithm tests are run during +power-up: + + at table @asis + at item 3DES +To test the 3DES 3-key EDE encryption in ECB mode these tests are +run: + at enumerate + at item +A known answer test is run on a 64 bit test vector processed by 64 +rounds of Single-DES block encryption and decryption using a key +changed with each round. + at item +A known answer test is run on a 64 bit test vector processed by 16 +rounds of 2-key and 3-key Triple-DES block encryption and decryptions +using a key changed with each round. + at item +10 known answer tests using 3-key Triple-DES EDE encryption, comparing +the ciphertext to the known value, then running a decryption and +comparing it to the initial plaintext. + at end enumerate +(@code{cipher/des.c:selftest}) + + at item AES-128 +A known answer tests is run using one test vector and one test +key with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_128}) + + at item AES-192 +A known answer tests is run using one test vector and one test +key with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_192}) + + at item AES-256 +A known answer tests is run using one test vector and one test key +with AES in ECB mode. (@code{cipher/rijndael.c:selftest_basic_256}) + at end table + + at subsection Hash Algorithm Power-Up Tests + +The following hash algorithm tests are run during power-up: + + at table @asis + at item SHA-1 +A known answer test using the string @code{"abc"} is run. +(@code{cipher/@/sha1.c:@/selftests_sha1}) + at item SHA-224 +A known answer test using the string @code{"abc"} is run. +(@code{cipher/@/sha256.c:@/selftests_sha224}) + at item SHA-256 +A known answer test using the string @code{"abc"} is run. +(@code{cipher/@/sha256.c:@/selftests_sha256}) + at item SHA-384 +A known answer test using the string @code{"abc"} is run. +(@code{cipher/@/sha512.c:@/selftests_sha384}) + at item SHA-512 +A known answer test using the string @code{"abc"} is run. +(@code{cipher/@/sha512.c:@/selftests_sha512}) + at end table + + at subsection MAC Algorithm Power-Up Tests + +The following MAC algorithm tests are run during power-up: + + at table @asis + at item HMAC SHA-1 +A known answer test using 9 byte of data and a 64 byte key is run. +(@code{cipher/hmac-tests.c:selftests_sha1}) + at item HMAC SHA-224 +A known answer test using 28 byte of data and a 4 byte key is run. +(@code{cipher/hmac-tests.c:selftests_sha224}) + at item HMAC SHA-256 +A known answer test using 28 byte of data and a 4 byte key is run. +(@code{cipher/hmac-tests.c:selftests_sha256}) + at item HMAC SHA-384 +A known answer test using 28 byte of data and a 4 byte key is run. +(@code{cipher/hmac-tests.c:selftests_sha384}) + at item HMAC SHA-512 +A known answer test using 28 byte of data and a 4 byte key is run. +(@code{cipher/hmac-tests.c:selftests_sha512}) + at end table + + at subsection Random Number Power-Up Test + +The DRNG is tested during power-up this way: + + at enumerate + at item +Requesting one block of random using the public interface to check +general working and the duplicated block detection. + at item +3 know answer tests using pre-defined keys, seed and initial DT +values. For each test 3 blocks of 16 bytes are requested and compared +to the expected result. The DT value is incremented for each block. + at end enumerate + + at subsection Public Key Algorithm Power-Up Tests + +The public key algorithms are tested during power-up: + + at table @asis + at item RSA +A pre-defined 1024 bit RSA key is used and these tests are run +in turn: + at enumerate + at item +Conversion of S-expression to internal format. +(@code{cipher/@/rsa.c:@/selftests_rsa}) + at item +Private key consistency check. +(@code{cipher/@/rsa.c:@/selftests_rsa}) + at item +A pre-defined 20 byte value is signed with PKCS#1 padding for SHA-1. +The result is verified using the public key against the original data +and against modified data. (@code{cipher/@/rsa.c:@/selftest_sign_1024}) + at item +A 1000 bit random value is encrypted and checked that it does not +match the orginal random value. The encrtypted result is then +decrypted and checked that it macthes the original random value. +(@code{cipher/@/rsa.c:@/selftest_encr_1024}) + at end enumerate + + at item DSA +A pre-defined 1024 bit DSA key is used and these tests are run in turn: + at enumerate + at item +Conversion of S-expression to internal format. +(@code{cipher/@/dsa.c:@/selftests_dsa}) + at item +Private key consistency check. +(@code{cipher/@/dsa.c:@/selftests_dsa}) + at item +A pre-defined 20 byte value is signed with PKCS#1 padding for +SHA-1. The result is verified using the public key against the +original data and against modified data. +(@code{cipher/@/dsa.c:@/selftest_sign_1024}) + at end enumerate + at end table + + at subsection Integrity Power-Up Tests + +The integrity of the Libgcrypt is tested during power-up but only if +checking has been enabled at build time. The check works by computing +a HMAC SHA-256 checksum over the file used to load Libgcrypt into +memory. That checksum is compared against a checksum stored in a file +of the same name but with a single dot as a prefix and a suffix of + at file{.hmac}. + + + at subsection Critical Functions Power-Up Tests + +The 3DES weak key detection is tested during power-up by calling the +detection function with keys taken from a table listening all weak +keys. The table itself is protected using a SHA-1 hash. +(@code{cipher/@/des.c:@/selftest}) + + + + at c -------------------------------- + at section Conditional Tests + +The conditional tests are performed if a certain contidion is met. +This may occur at any time; the library does not necessary enter the +``Self-Test'' state to run these tests but will transit to the +``Error'' state if a test failed. + + at subsection Key-Pair Generation Tests + +After an asymmetric key-pair has been generated, Libgcrypt runs a +pair-wise consistency tests on the generated key. On failure the +generated key is not used, an error code is returned and, if in FIPS +mode, the library is put into the ``Error'' state. + + at table @asis + at item RSA +The test uses a random number 64 bits less the size of the modulus to +test the encryption and decryption operation. A new random number of +the same size is then generated to test the signing operation. The +signature is then modified and then checked to test that a modified +signature is correcty detected. (@code{cipher/@/dsa.c:@/test_keys}) + at item DSA +The test uses a random number of the size of the Q parameter to create +a signature and then checked that the signature verifies. The data is +then modified and then checked that the signature does not verify. +(@code{cipher/@/dsa.c:@/test_keys}) + at end table + + + at subsection Software Load Tests + +Loading of extra modules into libgcrypt is disabled in FIPS mode and +thus no tests are +implemented. (@code{cipher/@/cipher.c:@/gcry_cipher_register}, + at code{cipher/@/md.c:@/gcry_md_register}, + at code{cipher/@/md.c:@/gcry_pk_register}) + + + at subsection Manual Key Entry Tests + +A manual key entry feature is not implemented in Libgcrypt. + + + at subsection Continuous RNG Tests + +The continuous random number test is only used in FIPS mode. The RNG +generates blocks of 128 bit size; the first block generated per +context is saved in the context and another block is generated to be +returned to the caller. Each block is compared against the saved +block and then stored in the context. If a duplicated block is +detected an error is signaled and the libray is put into the +``Fatal-Error'' state. +(@code{random/@/random-fips.c:@/x931_aes_driver}) + + + + at c -------------------------------- + at section Application Requested Tests + +The application may requests tests at any time by means of the + at code{GCRYCTL_SELFTEST} control command. Note that using these tests +is not FIPS conform: Although Libgcrypt rejects all application +requests for services while running self-tests, it does not ensure +that no other operations of Libgcrypt are still being executed. Thus +in FIPS mode an application requesting self-tests needs to be +power-cycle Libgcrypt instead. + +When self-tests are requested, Libgcrypt runs all the tests it does +during power-up as well as a few extra checks as described below. + + at subsection Symmetric Cipher Algorithm Tests + +The following symmetric encryption algorithm tests are run in addition +to the power-up tests: + + at table @asis + at item AES-128 +A known answer tests with test vectors taken from NIST SP800-38a and +using the high level functions is run for block modes CFB and OFB. + + at end table + + at subsection Hash Algorithm Tests + +The following hash algorithm tests are run in addition to the +power-up tests: + + at table @asis + at item SHA-1 + at itemx SHA-224 + at itemx SHA-256 + at enumerate + at item +A known answer test using a 56 byte string is run. + at item +A known answer test using a string of one million letters "a" is run. + at end enumerate +(@code{cipher/@/sha1.c:@/selftests_sha1}, + at code{cipher/@/sha256.c:@/selftests_sha224}, + at code{cipher/@/sha256.c:@/selftests_sha256}) + at item SHA-384 + at item SHA-512 + at enumerate + at item +A known answer test using a 112 byte string is run. + at item +A known answer test using a string of one million letters "a" is run. + at end enumerate +(@code{cipher/@/sha512.c:@/selftests_sha384}, + at code{cipher/@/sha512.c:@/selftests_sha512}) + at end table + + at subsection MAC Algorithm Tests + +The following MAC algorithm tests are run in addition to the power-up +tests: + + at table @asis + at item HMAC SHA-1 + at enumerate + at item +A known answer test using 9 byte of data and a 20 byte key is run. + at item +A known answer test using 9 byte of data and a 100 byte key is run. + at item +A known answer test using 9 byte of data and a 49 byte key is run. + at end enumerate +(@code{cipher/hmac-tests.c:selftests_sha1}) + at item HMAC SHA-224 + at itemx HMAC SHA-256 + at itemx HMAC SHA-384 + at itemx HMAC SHA-512 + at enumerate + at item +A known answer test using 9 byte of data and a 20 byte key is run. + at item +A known answer test using 50 byte of data and a 20 byte key is run. + at item +A known answer test using 50 byte of data and a 26 byte key is run. + at item +A known answer test using 54 byte of data and a 131 byte key is run. + at item +A known answer test using 152 byte of data and a 131 byte key is run. + at end enumerate +(@code{cipher/@/hmac-tests.c:@/selftests_sha224}, + at code{cipher/@/hmac-tests.c:@/selftests_sha256}, + at code{cipher/@/hmac-tests.c:@/selftests_sha384}, + at code{cipher/@/hmac-tests.c:@/selftests_sha512}) + at end table + + + at c ******************************************** @node FIPS Restrictions @appendix Restrictions in FIPS mode + at noindent If Libgcrypt is used in FIPS mode these restrictions are effective: @itemize From cvs at cvs.gnupg.org Mon Sep 15 12:19:15 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 15 Sep 2008 12:19:15 +0200 Subject: [svn] gcry - r1330 - in trunk: . doc Message-ID: Author: wk Date: 2008-09-15 12:19:15 +0200 (Mon, 15 Sep 2008) New Revision: 1330 Modified: trunk/NEWS trunk/doc/ChangeLog trunk/doc/gcrypt.texi trunk/doc/lgpl.texi Log: doc cleanups. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-09-12 19:11:10 UTC (rev 1329) +++ trunk/doc/ChangeLog 2008-09-15 10:19:15 UTC (rev 1330) @@ -1,3 +1,7 @@ +2008-09-15 Werner Koch + + * gcrypt.texi: Fold the two FIPS appendices into one. + 2008-09-11 Werner Koch * gcrypt.texi (Public-Key Subsystem Architecture): Explain RSA Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-09-12 19:11:10 UTC (rev 1329) +++ trunk/NEWS 2008-09-15 10:19:15 UTC (rev 1330) @@ -1,7 +1,11 @@ Noteworthy changes in version 1.4.3 ------------------------------------------------ + * More self-tests. + * Documentation cleanups. + + Noteworthy changes in version 1.4.2 (2008-09-08) ------------------------------------------------ Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-12 19:11:10 UTC (rev 1329) +++ trunk/doc/gcrypt.texi 2008-09-15 10:19:15 UTC (rev 1330) @@ -77,9 +77,8 @@ Appendices -* Self-Tests:: Description of self-tests. -* FIPS Restrictions:: Restrictions in FIPS mode. -* FIPS Finite State Machine:: Description of the FIPS FSM. +* Self-Tests:: Description of the self-tests. +* FIPS Mode:: Description of the FIPS mode. * 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 @@ -188,7 +187,7 @@ * Building sources using Automake:: How to build sources with the help of Automake. * Initializing the library:: How to initialize the library. * Multi-Threading:: How Libgcrypt can be used in a MT environment. -* FIPS mode:: How to enable the FIPS mode. +* Enabling FIPS mode:: How to enable the FIPS mode. @end menu @@ -392,8 +391,8 @@ gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); @anchor{sample-use-resume-secmem} - /* It is now okay to let Libgcrypt complain when there was/is a problem - with the secure memory. */ + /* It is now okay to let Libgcrypt complain when there was/is + a problem with the secure memory. */ gcry_control (GCRYCTL_RESUME_SECMEM_WARN); /* ... If required, other initialization goes here. */ @@ -489,25 +488,28 @@ @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. +This macro defines the following (static) symbols: + at code{gcry_pth_init}, @code{gcry_pth_mutex_init}, + at code{gcry_pth_mutex_destroy}, @code{gcry_pth_mutex_lock}, + at code{gcry_pth_mutex_unlock}, @code{gcry_pth_read}, + at code{gcry_pth_write}, @code{gcry_pth_select}, + at code{gcry_pth_waitpid}, @code{gcry_pth_accept}, + at code{gcry_pth_connect}, @code{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''. +After including this macro, @code{gcry_control()} shall be used with a +command of @code{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_pthread_mutex_lock, gcry_pthread_mutex_unlock, -gcry_threads_pthread. + at code{gcry_pthread_mutex_init}, @code{gcry_pthread_mutex_destroy}, + at code{gcry_pthread_mutex_lock}, @code{gcry_pthread_mutex_unlock}, + at code{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''. +After including this macro, @code{gcry_control()} shall be used with a +command of @code{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 @@ -515,10 +517,9 @@ programmers might have to wrap these macros in an ``extern C'' body. + at node Enabling FIPS mode + at section How to enable the FIPS mode - at node FIPS mode - at section FIPS Mode - Libgcrypt may be used in a FIPS 140-2 mode. Note, that this does not necessary mean that Libcgrypt is an appoved FIPS 140-2 module. Check the NIST database at @url{http://csrc.nist.gov/groups/STM/cmvp/} to see what @@ -1168,7 +1169,8 @@ gcry_cipher_hd_t handle; gcry_error_t err = 0; - err = gcry_cipher_open (&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0); + err = gcry_cipher_open (&handle, GCRY_CIPHER_AES, + GCRY_CIPHER_MODE_CBC, 0); if (err) @{ fprintf (stderr, "Failure: %s/%s\n", @@ -1510,13 +1512,13 @@ @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 +(*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 +(*gcry_@/cipher_@/stdecrypt_@/t) (void *c, const unsigned char *outbuf, const unsigned char *, unsigned int n) @end deftp @@ -3011,7 +3013,8 @@ err = gcry_ac_open (&handle, GCRY_AC_RSA, 0); assert (! err); - err = gcry_ac_key_pair_generate (handle, 1024, &rsa_spec, &key_pair, NULL); + err = gcry_ac_key_pair_generate (handle, 1024, &rsa_spec, + &key_pair, NULL); assert (! err); @} @end example @@ -4995,7 +4998,7 @@ @c ******************************************** @node Self-Tests - at appendix Description of Self-Tests + at appendix Description of the Self-Tests In addition to the build time regression test suite, Libgcrypt implements self-tests to be performed at runtime. Which self-tests @@ -5191,16 +5194,22 @@ @table @asis @item RSA -The test uses a random number 64 bits less the size of the modulus to -test the encryption and decryption operation. A new random number of -the same size is then generated to test the signing operation. The -signature is then modified and then checked to test that a modified -signature is correcty detected. (@code{cipher/@/dsa.c:@/test_keys}) +The test uses a random number 64 bits less the size of the modulus as +plaintext and runs an encryption and decryption operation in turn. The +encrypted value is checked to not match the plaintext and the result +of the decryption is checked to match the plaintext. + +A new random number of the same size is generated, signed and verified +to test the correctness of the signing operation. As a second signing +test, the signature is modified by incrementing its value and then +verified with the expected result that the verification fails. +(@code{cipher/@/dsa.c:@/test_keys}) @item DSA The test uses a random number of the size of the Q parameter to create -a signature and then checked that the signature verifies. The data is -then modified and then checked that the signature does not verify. -(@code{cipher/@/dsa.c:@/test_keys}) +a signature and then checks that the signature verifies. As a second +signing test, the data is modified by incrementing its value and then +verified against the signature with the expected result that the +verification fails. (@code{cipher/@/dsa.c:@/test_keys}) @end table @@ -5327,9 +5336,17 @@ @c ******************************************** - at node FIPS Restrictions - at appendix Restrictions in FIPS mode + at node FIPS Mode + at appendix Description of the FIPS Mode +This appendix gives detailed information pertaining to the FIPS mode. +In particular, the changes to the standard mode and the finite state +machine are described. The self-tests required in this mode are +described in the appendix on self-tests. + + at c ------------------------------- + at section Restrictions in FIPS Mode + @noindent If Libgcrypt is used in FIPS mode these restrictions are effective: @@ -5426,8 +5443,7 @@ @c ******************************************** - at node FIPS Finite State Machine - at appendix FIPS Finite State Machine + at section FIPS Finite State Machine The FIPS mode of libgcrypt implements a finite state machine (FSM) using 8 states (@pxref{tbl:fips-states}) and checks at runtime that only valid Modified: trunk/doc/lgpl.texi =================================================================== --- trunk/doc/lgpl.texi 2008-09-12 19:11:10 UTC (rev 1329) +++ trunk/doc/lgpl.texi 2008-09-15 10:19:15 UTC (rev 1330) @@ -1,7 +1,7 @@ @node Library Copying - at unnumbered Lesser General Public License + at unnumbered GNU Lesser General Public License - at cindex LGPL, Lesser General Public License + at cindex LGPL, GNU Lesser General Public License @center Version 2.1, February 1999 @display From cvs at cvs.gnupg.org Mon Sep 15 12:37:39 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 15 Sep 2008 12:37:39 +0200 Subject: [svn] gcry - r1331 - trunk/doc Message-ID: Author: wk Date: 2008-09-15 12:37:39 +0200 (Mon, 15 Sep 2008) New Revision: 1331 Modified: trunk/doc/gcrypt.texi Log: Typo fix. Document the CFB shift size. Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-15 10:19:15 UTC (rev 1330) +++ trunk/doc/gcrypt.texi 2008-09-15 10:37:39 UTC (rev 1331) @@ -1558,7 +1558,8 @@ Electronic Codebook mode. @item GCRY_CIPHER_MODE_CFB -Cipher Feedback mode. +Cipher Feedback mode. The shift size equals the block size of the +cipher (e.g. for AES it is CFB-128). @item GCRY_CIPHER_MODE_CBC Cipher Block Chaining mode. @@ -5203,7 +5204,7 @@ to test the correctness of the signing operation. As a second signing test, the signature is modified by incrementing its value and then verified with the expected result that the verification fails. -(@code{cipher/@/dsa.c:@/test_keys}) +(@code{cipher/@/rsa.c:@/test_keys}) @item DSA The test uses a random number of the size of the Q parameter to create a signature and then checks that the signature verifies. As a second From cvs at cvs.gnupg.org Mon Sep 15 21:21:57 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 15 Sep 2008 21:21:57 +0200 Subject: [svn] gcry - r1332 - in trunk: . random src tests Message-ID: Author: wk Date: 2008-09-15 21:21:57 +0200 (Mon, 15 Sep 2008) New Revision: 1332 Added: trunk/tests/fipsrngdrv.c Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/random/ChangeLog trunk/random/rand-internal.h trunk/random/random-fips.c trunk/random/random.c trunk/random/random.h trunk/src/ChangeLog trunk/src/fips.c trunk/src/g10lib.h trunk/src/gcrypt.h.in trunk/src/global.c trunk/tests/ChangeLog trunk/tests/Makefile.am Log: Use syslog to log important messages. Add an external RNG test hook. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/ChangeLog 2008-09-15 19:21:57 UTC (rev 1332) @@ -1,3 +1,7 @@ +2008-09-15 Werner Koch + + * configure.ac: Cehck for syslog. + 2008-09-08 Werner Koch Release 1.4.2. Modified: trunk/random/ChangeLog =================================================================== --- trunk/random/ChangeLog 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/random/ChangeLog 2008-09-15 19:21:57 UTC (rev 1332) @@ -1,3 +1,16 @@ +2008-09-15 Werner Koch + + * random.c (_gcry_random_init_external_test): New. + (_gcry_random_run_external_test): New. + (_gcry_random_deinit_external_test): New. + * random-fips.c (struct rng_context): Turn TEST_DT_COUNTER into a + 32 bit integer. + (x931_get_dt): Ditto. + (selftest_kat): Intialize it accordingly. + (_gcry_rngfips_init_external_test): New. + (_gcry_rngfips_run_external_test): New. + (_gcry_rngfips_deinit_external_test): New. + 2008-09-05 Werner Koch * random.c (_gcry_random_selftest): Return success if not in fips Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/src/ChangeLog 2008-09-15 19:21:57 UTC (rev 1332) @@ -1,3 +1,18 @@ +2008-09-15 Werner Koch + + * fips.c [HAVE_SYSLOG]: Include syslog.h. + (_gcry_initialize_fips_mode, lock_fsm, unlock_fsm) + (_gcry_fips_signal_error, fips_new_state) + (_gcry_fips_noreturn) [HAVE_SYSLOG]: Also log via syslog. + * global.h [HAVE_SYSLOG]: Include syslog.h. + (_gcry_global_is_operational) [HAVE_SYSLOG]: Print warning. + + * global.c (_gcry_vcontrol): Use GCRYCTL_INITIALIZATION_FINISHED + to run power-up tests. Add unpublished control commands 58-60. + + * global.c (_gcry_global_is_operational): New. + * g10lib.h (fips_is_operational): Change to call this function. + 2008-09-12 Werner Koch * fips.c (_gcry_fips_run_selftests): Add arg EXTENDED. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/tests/ChangeLog 2008-09-15 19:21:57 UTC (rev 1332) @@ -1,3 +1,7 @@ +2008-09-15 Werner Koch + + * fipsrngdrv.c: New. + 2008-09-09 Werner Koch * basic.c (main): New option --selftest. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/NEWS 2008-09-15 19:21:57 UTC (rev 1332) @@ -1,6 +1,15 @@ Noteworthy changes in version 1.4.3 ------------------------------------------------ + * Try to auto-initialize Libgcrypt to minimize the effect of + applications not doing that correctly. This is not a perfect + solution but given that many applicationion would totally fail + without such a hack, we try to help at least with the most common + cases. Folks, please read the manual to learn how to properly + initialize Libgcrypt! + + * Log fatal error via syslog. + * More self-tests. * Documentation cleanups. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/configure.ac 2008-09-15 19:21:57 UTC (rev 1332) @@ -700,7 +700,7 @@ AC_CHECK_FUNCS(strtoul memmove stricmp atexit raise) # Other checks AC_CHECK_FUNCS(strerror rand mmap getpagesize sysconf waitpid wait4) -AC_CHECK_FUNCS(gettimeofday getrusage gethrtime clock_gettime) +AC_CHECK_FUNCS(gettimeofday getrusage gethrtime clock_gettime syslog) AC_CHECK_FUNCS(fcntl ftruncate) GNUPG_CHECK_MLOCK Modified: trunk/random/rand-internal.h =================================================================== --- trunk/random/rand-internal.h 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/random/rand-internal.h 2008-09-15 19:21:57 UTC (rev 1332) @@ -79,6 +79,16 @@ gcry_error_t _gcry_rngfips_selftest (selftest_report_func_t report); +gcry_err_code_t _gcry_rngfips_init_external_test (void **r_context, + const void *key, + size_t keylen, + const void *seed, + size_t seedlen, + const void *dt, + size_t dtlen); +gcry_err_code_t _gcry_rngfips_run_external_test (void *context, + char *buffer, size_t buflen); +void _gcry_rngfips_deinit_external_test (void *context); Modified: trunk/random/random-fips.c =================================================================== --- trunk/random/random-fips.c 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/random/random-fips.c 2008-09-15 19:21:57 UTC (rev 1332) @@ -144,12 +144,12 @@ /* To implement a KAT we need to provide a know DT value. To accomplish this the x931_get_dt function checks whether this field is not NULL and then uses the 16 bytes at this address for - the DT value. However the last byte is will be replaced by the - value of field TEST_DT_COUNTER which will be incremented with + the DT value. However the last 4 bytes are replaced by the + value of field TEST_DT_COUNTER which will be incremented after each invocation of x931_get_dt. We use a pointer and not a buffer because there is no need to put this value into secure memory. */ const unsigned char *test_dt_ptr; - unsigned char test_dt_counter; + u32 test_dt_counter; /* We need to keep track of the process which did the initialization so that we can detect a fork. The volatile modifier is required @@ -283,8 +283,12 @@ && rng_ctx != std_rng_context && rng_ctx != strong_rng_context) { - memcpy (buffer, rng_ctx->test_dt_ptr, 15); - buffer[15] = rng_ctx->test_dt_counter++; + memcpy (buffer, rng_ctx->test_dt_ptr, 16); + buffer[12] = (rng_ctx->test_dt_counter >> 24); + buffer[13] = (rng_ctx->test_dt_counter >> 16); + buffer[14] = (rng_ctx->test_dt_counter >> 8); + buffer[15] = rng_ctx->test_dt_counter; + rng_ctx->test_dt_counter++; return; } @@ -792,7 +796,7 @@ /* Public function to fill the buffer with LENGTH bytes of cryptographically strong random bytes. Level GCRY_WEAK_RANDOM is - here mapped to GCRY_STRING_RANDOM, GCRY_STRONG_RANDOM is strong + here mapped to GCRY_STRONG_RANDOM, GCRY_STRONG_RANDOM is strong enough for most usage, GCRY_VERY_STRONG_RANDOM is good for key generation stuff but may be very slow. */ void @@ -915,9 +919,12 @@ /* Setup a DT value. */ test_ctx->test_dt_ptr = tv[tvidx].dt; - test_ctx->test_dt_counter = tv[tvidx].dt[15]; + test_ctx->test_dt_counter = ( (tv[tvidx].dt[12] << 24) + |(tv[tvidx].dt[13] << 16) + |(tv[tvidx].dt[14] << 8) + |(tv[tvidx].dt[15]) ); - /* Get ant compare the first three results. */ + /* Get and compare the first three results. */ for (ridx=0; ridx < 3; ridx++) { /* Compute the next value. */ @@ -989,3 +996,104 @@ return gpg_error (ec); } + +/* Create a new test context for an external RNG test driver. On + success the test context is stored at R_CONTEXT; on failure NULL is + stored at R_CONTEXT and an error code is returned. */ +gcry_err_code_t +_gcry_rngfips_init_external_test (void **r_context, + const void *key, size_t keylen, + const void *seed, size_t seedlen, + const void *dt, size_t dtlen) +{ + gpg_error_t err; + rng_context_t test_ctx; + + _gcry_rngfips_initialize (1); /* Auto-initialize if needed. */ + + if (!r_context + || !key || keylen != 16 + || !seed || seedlen != 16 + || !dt || dtlen != 16 ) + return GPG_ERR_INV_ARG; + + test_ctx = gcry_calloc (1, sizeof *test_ctx + dtlen); + if (!test_ctx) + return gpg_err_code_from_syserror (); + setup_guards (test_ctx); + + /* Setup the key. */ + err = gcry_cipher_open (&test_ctx->cipher_hd, + GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, + GCRY_CIPHER_SECURE); + if (err) + goto leave; + + err = gcry_cipher_setkey (test_ctx->cipher_hd, key, keylen); + if (err) + goto leave; + + test_ctx->key_init_pid = getpid (); + + /* Setup the seed. */ + memcpy (test_ctx->seed_V, seed, seedlen); + test_ctx->is_seeded = 1; + test_ctx->seed_init_pid = getpid (); + + /* Setup a DT value. Because our context structure only stores a + pointer we copy the DT value to the extra space we allocated in + the test_ctx and set the pointer to tehre. */ + memcpy ((char*)test_ctx + sizeof *test_ctx, dt, dtlen); + test_ctx->test_dt_ptr = (unsigned char*)test_ctx + sizeof test_ctx; + test_ctx->test_dt_counter = ( (test_ctx->test_dt_ptr[12] << 24) + |(test_ctx->test_dt_ptr[13] << 16) + |(test_ctx->test_dt_ptr[14] << 8) + |(test_ctx->test_dt_ptr[15]) ); + + check_guards (test_ctx); + /* All fine. */ + err = 0; + + leave: + if (err) + { + gcry_cipher_close (test_ctx->cipher_hd); + gcry_free (test_ctx); + *r_context = NULL; + } + else + *r_context = test_ctx; + return gcry_err_code (err); +} + + +/* Get BUFLEN bytes from the RNG using the test CONTEXT and store them + at BUFFER. Return 0 on success or an error code. */ +gcry_err_code_t +_gcry_rngfips_run_external_test (void *context, char *buffer, size_t buflen) +{ + rng_context_t test_ctx = context; + + if (!test_ctx || !buffer || buflen != 16) + return GPG_ERR_INV_ARG; + + lock_rng (); + get_random (buffer, buflen, test_ctx); + unlock_rng (); + return 0; +} + +/* Release the test CONTEXT. */ +void +_gcry_rngfips_deinit_external_test (void *context) +{ + rng_context_t test_ctx = context; + + if (test_ctx) + { + gcry_cipher_close (test_ctx->cipher_hd); + gcry_free (test_ctx); + } +} + + Modified: trunk/random/random.c =================================================================== --- trunk/random/random.c 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/random/random.c 2008-09-15 19:21:57 UTC (rev 1332) @@ -283,3 +283,41 @@ return 0; /* No selftests yet. */ } + +/* Create a new test context for an external RNG test driver. On + success the test context is stored at R_CONTEXT; on failure NULL is + stored at R_CONTEXT and an error code is returned. */ +gcry_err_code_t +_gcry_random_init_external_test (void **r_context, + unsigned int flags, + const void *key, size_t keylen, + const void *seed, size_t seedlen, + const void *dt, size_t dtlen) +{ + (void)flags; + if (fips_mode ()) + return _gcry_rngfips_init_external_test (r_context, key, keylen, + seed, seedlen, + dt, dtlen); + else + return GPG_ERR_NOT_SUPPORTED; +} + +/* Get BUFLEN bytes from the RNG using the test CONTEXT and store them + at BUFFER. Return 0 on success or an error code. */ +gcry_err_code_t +_gcry_random_run_external_test (void *context, char *buffer, size_t buflen) +{ + if (fips_mode ()) + return _gcry_rngfips_run_external_test (context, buffer, buflen); + else + return GPG_ERR_NOT_SUPPORTED; +} + +/* Release the test CONTEXT. */ +void +_gcry_random_deinit_external_test (void *context) +{ + if (fips_mode ()) + return _gcry_rngfips_deinit_external_test (context); +} Modified: trunk/random/random.h =================================================================== --- trunk/random/random.h 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/random/random.h 2008-09-15 19:21:57 UTC (rev 1332) @@ -39,7 +39,19 @@ byte *_gcry_get_random_bits( size_t nbits, int level, int secure ); void _gcry_fast_random_poll( void ); +gcry_err_code_t _gcry_random_init_external_test (void **r_context, + unsigned int flags, + const void *key, + size_t keylen, + const void *seed, + size_t seedlen, + const void *dt, + size_t dtlen); +gcry_err_code_t _gcry_random_run_external_test (void *context, + char *buffer, size_t buflen); +void _gcry_random_deinit_external_test (void *context); + /*-- rndegd.c --*/ gpg_error_t _gcry_rndegd_set_socket_name (const char *name); Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/src/fips.c 2008-09-15 19:21:57 UTC (rev 1332) @@ -26,6 +26,9 @@ #ifdef ENABLE_HMAC_BINARY_CHECK # include #endif +#ifdef HAVE_SYSLOG +# include +#endif /*HAVE_SYSLOG*/ #include "g10lib.h" #include "ath.h" @@ -148,6 +151,11 @@ file system. We better stop right away. */ log_info ("FATAL: error reading `%s' in libgcrypt: %s\n", procfname, strerror (saved_errno)); +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " + "reading `%s' failed: %s - abort", + procfname, strerror (saved_errno)); +#endif /*HAVE_SYSLOG*/ abort (); } } @@ -169,6 +177,11 @@ get involved. */ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", strerror (err)); +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " + "creating FSM lock failed: %s - abort", + strerror (err)); +#endif /*HAVE_SYSLOG*/ abort (); } @@ -189,6 +202,11 @@ { log_info ("FATAL: failed to acquire the FSM lock in libgrypt: %s\n", strerror (err)); +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " + "acquiring FSM lock failed: %s - abort", + strerror (err)); +#endif /*HAVE_SYSLOG*/ abort (); } } @@ -203,6 +221,11 @@ { log_info ("FATAL: failed to release the FSM lock in libgrypt: %s\n", strerror (err)); +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " + "releasing FSM lock failed: %s - abort", + strerror (err)); +#endif /*HAVE_SYSLOG*/ abort (); } } @@ -619,6 +642,14 @@ srcfile, srcline, srcfunc? ", function ":"", srcfunc? srcfunc:"", description? description : "no description available"); +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " + "%serror in file %s, line %d%s%s: %s", + is_fatal? "fatal ":"", + srcfile, srcline, + srcfunc? ", function ":"", srcfunc? srcfunc:"", + description? description : "no description available"); +#endif /*HAVE_SYSLOG*/ } @@ -697,8 +728,21 @@ if (!ok) { /* Invalid state transition. Halting library. */ +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_ERR, + "Libgcrypt error: invalid state transition %s => %s", + state2str (last_state), state2str (new_state)); +#endif /*HAVE_SYSLOG*/ fips_noreturn (); } + else if (new_state == STATE_ERROR || new_state == STATE_FATALERROR) + { +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_WARNING, + "Libgcrypt notice: state transition %s => %s", + state2str (last_state), state2str (new_state)); +#endif /*HAVE_SYSLOG*/ + } } @@ -709,6 +753,9 @@ void _gcry_fips_noreturn (void) { +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_ERR, "Libgcrypt terminated the application"); +#endif /*HAVE_SYSLOG*/ fflush (NULL); abort (); /*NOTREACHED*/ Modified: trunk/src/g10lib.h =================================================================== --- trunk/src/g10lib.h 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/src/g10lib.h 2008-09-15 19:21:57 UTC (rev 1332) @@ -74,6 +74,7 @@ /*-- src/global.c -*/ +int _gcry_global_is_operational (void); gcry_error_t _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr); void _gcry_check_heap (const void *a); int _gcry_get_debug_flag (unsigned int mask); @@ -310,7 +311,7 @@ #endif int _gcry_fips_is_operational (void); -#define fips_is_operational() (_gcry_fips_is_operational ()) +#define fips_is_operational() (_gcry_global_is_operational ()) #define fips_not_operational() (GCRY_GPG_ERR_NOT_OPERATIONAL) int _gcry_fips_test_operational (void); Modified: trunk/src/gcrypt.h.in =================================================================== --- trunk/src/gcrypt.h.in 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/src/gcrypt.h.in 2008-09-15 19:21:57 UTC (rev 1332) @@ -410,6 +410,7 @@ GCRYCTL_FIPS_MODE_P = 55, GCRYCTL_FORCE_FIPS_MODE = 56, GCRYCTL_SELFTEST = 57 + /* Note: 58, 59 and 60 are used internally. */ }; /* Perform various operations defined by CMD. */ Modified: trunk/src/global.c =================================================================== --- trunk/src/global.c 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/src/global.c 2008-09-15 19:21:57 UTC (rev 1332) @@ -28,6 +28,9 @@ #include #include #include +#ifdef HAVE_SYSLOG +# include +#endif /*HAVE_SYSLOG*/ #include "g10lib.h" #include "cipher.h" @@ -80,7 +83,7 @@ return; any_init_done = 1; - /* Initialize our portable theead/mutex wrapper. */ + /* Initialize our portable thread/mutex wrapper. */ err = ath_init (); if (err) goto fail; @@ -119,6 +122,39 @@ } +/* This function is called by the macro fips_is_operational and makes + sure that the minimal initialization has been done. This is far + from a perfect solution and hides problems with an improper + initialization but at least in single-threaded mode it should work + reliable. + + The reason we need this is that a lot of applications don't use + Libgcrypt properly by not running any initialization code at all. + They just call a Libgcrypt function and that is all what they want. + Now with the FIPS mode, that has the side effect of entering FIPS + mode (for security reasons, FIPS mode is the default if no + initialization has been done) and bailing out immediately because + the FSM is in the wrong state. If we always run the init code, + Libgcrypt can test for FIPS mode and at least if not in FIPS mode, + it will behave as before. Note that this on-the-fly initialization + is only done for the cryptographic functions subject to FIPS mode + and thus not all API calls will do such an initialization. */ +int +_gcry_global_is_operational (void) +{ + if (!any_init_done) + { +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " + "missing initialization - please fix the application"); +#endif /*HAVE_SYSLOG*/ + global_init (); + } + return _gcry_fips_is_operational (); +} + + + /* Version number parsing. */ @@ -392,6 +428,8 @@ mutexes. */ _gcry_random_initialize (0); init_finished = 1; + /* Force us into operational state if in FIPS mode. */ + (void)fips_is_operational (); } break; @@ -478,12 +516,48 @@ case GCRYCTL_SELFTEST: /* Run a selftest. This works in fips mode as well as in standard mode. In contrast to the power-up tests, we use an - extended version ofthe selftests. Returns 0 on success or an + extended version of the selftests. Returns 0 on success or an error code. */ global_init (); err = _gcry_fips_run_selftests (1); break; + case 58: + { + void **rctx = va_arg (arg_ptr, void **); + unsigned int flags = va_arg (arg_ptr, unsigned int); + const void *key = va_arg (arg_ptr, const void *); + size_t keylen = va_arg (arg_ptr, size_t); + const void *seed = va_arg (arg_ptr, const void *); + size_t seedlen = va_arg (arg_ptr, size_t); + const void *dt = va_arg (arg_ptr, const void *); + size_t dtlen = va_arg (arg_ptr, size_t); + if (!fips_is_operational ()) + err = fips_not_operational (); + else + err = _gcry_random_init_external_test (rctx, flags, key, keylen, + seed, seedlen, dt, dtlen); + } + break; + case 59: + { + void *ctx = va_arg (arg_ptr, void *); + void *buffer = va_arg (arg_ptr, void *); + size_t buflen = va_arg (arg_ptr, size_t); + if (!fips_is_operational ()) + err = fips_not_operational (); + else + err = _gcry_random_run_external_test (ctx, buffer, buflen); + } + break; + case 60: + { + void *ctx = va_arg (arg_ptr, void *); + _gcry_random_deinit_external_test (ctx); + } + break; + + default: err = GPG_ERR_INV_OP; } Modified: trunk/tests/Makefile.am =================================================================== --- trunk/tests/Makefile.am 2008-09-15 10:37:39 UTC (rev 1331) +++ trunk/tests/Makefile.am 2008-09-15 19:21:57 UTC (rev 1332) @@ -39,7 +39,7 @@ LDADD = ../src/libgcrypt.la $(DL_LIBS) EXTRA_PROGRAMS = testapi pkbench -noinst_PROGRAMS = $(TESTS) +noinst_PROGRAMS = $(TESTS) fipsrngdrv EXTRA_DIST = README rsa-16k.key Added: trunk/tests/fipsrngdrv.c =================================================================== --- trunk/tests/fipsrngdrv.c (rev 0) +++ trunk/tests/fipsrngdrv.c 2008-09-15 19:21:57 UTC (rev 1332) @@ -0,0 +1,119 @@ +/* fipsrngdrv.c - A driver to test the FIPS RNG. + Copyright (C) 2008 Free Software Foundation, Inc. + + This file is part of Libgcrypt. + + Libgcrypt is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + Libgcrypt is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, see . + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include + +#include "../src/gcrypt.h" + +#define PGM "fipsrngdrv" + + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + fputs (PGM ": ", stderr); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + +static gcry_error_t +init_external_test (void **r_context, + unsigned int flags, + const void *key, size_t keylen, + const void *seed, size_t seedlen, + const void *dt, size_t dtlen) +{ + return gcry_control (58, + r_context, flags, + key, keylen, + seed, seedlen, + dt, dtlen); +} + +static gcry_error_t +run_external_test (void *context, void *buffer, size_t buflen) +{ + return gcry_control (59, context, buffer, buflen); +} + +static void +deinit_external_test (void *context) +{ + gcry_control (60, context); +} + + +static void +print_buffer (const unsigned char *buffer, size_t length) +{ + while (length--) + printf ("%02X", *buffer++); +} + + +int +main (int argc, char **argv) +{ + void *context; + gpg_error_t err; + int block; + unsigned char buffer[16]; + + (void)argc; + (void)argv; + + gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_SET_VERBOSITY, 2); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + err = init_external_test (&context, 0, + "1234567890123456", 16, + "abcdefghijklmnop", 16, + "XXXXXXXXXXXXXXXX", 16); + if (err) + die ("init external test failed: %s\n", gpg_strerror (err)); + + for (block=0; block < 10; block++) + { + err = run_external_test (context, buffer, sizeof buffer); + if (err) + die ("run external test failed: %s\n", gpg_strerror (err)); + print_buffer (buffer, sizeof buffer); + putchar ('\n'); + } + + deinit_external_test (context); + + return 0; +} + From cvs at cvs.gnupg.org Mon Sep 15 21:36:07 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 15 Sep 2008 21:36:07 +0200 Subject: [svn] gcry - r1333 - trunk/src Message-ID: Author: wk Date: 2008-09-15 21:36:07 +0200 (Mon, 15 Sep 2008) New Revision: 1333 Modified: trunk/src/ChangeLog trunk/src/fips.c Log: Log a failed intgetrity check with filename. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-15 19:21:57 UTC (rev 1332) +++ trunk/src/ChangeLog 2008-09-15 19:36:07 UTC (rev 1333) @@ -4,6 +4,7 @@ (_gcry_initialize_fips_mode, lock_fsm, unlock_fsm) (_gcry_fips_signal_error, fips_new_state) (_gcry_fips_noreturn) [HAVE_SYSLOG]: Also log via syslog. + (check_binary_integrity) [HAVE_SYSLOG]: Log failure. * global.h [HAVE_SYSLOG]: Include syslog.h. (_gcry_global_is_operational) [HAVE_SYSLOG]: Print warning. Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2008-09-15 19:21:57 UTC (rev 1332) +++ trunk/src/fips.c 2008-09-15 19:36:07 UTC (rev 1333) @@ -565,6 +565,12 @@ } } reporter ("binary", 0, fname, err? gpg_strerror (err):NULL); +#ifdef HAVE_SYSLOG + if (err) + syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " + "integrity check on `%s' failed: %s", + fname? fname:"[?]", gpg_strerror (err)); +#endif /*HAVE_SYSLOG*/ gcry_free (fname); return !!err; #else From cvs at cvs.gnupg.org Mon Sep 15 21:43:23 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 15 Sep 2008 21:43:23 +0200 Subject: [svn] gcry - r1334 - trunk/src Message-ID: Author: wk Date: 2008-09-15 21:43:22 +0200 (Mon, 15 Sep 2008) New Revision: 1334 Modified: trunk/src/fips.c Log: Changed error text. Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2008-09-15 19:36:07 UTC (rev 1333) +++ trunk/src/fips.c 2008-09-15 19:43:22 UTC (rev 1334) @@ -568,7 +568,7 @@ #ifdef HAVE_SYSLOG if (err) syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " - "integrity check on `%s' failed: %s", + "integrity check using `%s' failed: %s", fname? fname:"[?]", gpg_strerror (err)); #endif /*HAVE_SYSLOG*/ gcry_free (fname); From cvs at cvs.gnupg.org Tue Sep 16 09:48:25 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 16 Sep 2008 09:48:25 +0200 Subject: [svn] gcry - r1335 - in trunk: random tests Message-ID: Author: wk Date: 2008-09-16 09:48:25 +0200 (Tue, 16 Sep 2008) New Revision: 1335 Modified: trunk/random/ChangeLog trunk/random/random-fips.c trunk/tests/ChangeLog trunk/tests/fipsrngdrv.c Log: Finish FIPS random test driver. Disable re-seeding if in test mode. Modified: trunk/random/ChangeLog =================================================================== --- trunk/random/ChangeLog 2008-09-15 19:43:22 UTC (rev 1334) +++ trunk/random/ChangeLog 2008-09-16 07:48:25 UTC (rev 1335) @@ -1,3 +1,7 @@ +2008-09-16 Werner Koch + + * random-fips.c (x931_aes_driver): No re-seeding with test contexts. + 2008-09-15 Werner Koch * random.c (_gcry_random_init_external_test): New. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-09-15 19:43:22 UTC (rev 1334) +++ trunk/tests/ChangeLog 2008-09-16 07:48:25 UTC (rev 1335) @@ -1,3 +1,7 @@ +2008-09-16 Werner Koch + + * fipsrngdrv.c: Bail out on write error. + 2008-09-15 Werner Koch * fipsrngdrv.c: New. Modified: trunk/random/random-fips.c =================================================================== --- trunk/random/random-fips.c 2008-09-15 19:43:22 UTC (rev 1334) +++ trunk/random/random-fips.c 2008-09-16 07:48:25 UTC (rev 1335) @@ -455,8 +455,9 @@ while (length) { - /* We require a new seed after some time. */ - if (rng_ctx->use_counter > SEED_TTL) + /* Unless we are running with a test context, we require a new + seed after some time. */ + if (!rng_ctx->test_dt_ptr && rng_ctx->use_counter > SEED_TTL) { x931_reseed (rng_ctx); rng_ctx->use_counter = 0; Modified: trunk/tests/fipsrngdrv.c =================================================================== --- trunk/tests/fipsrngdrv.c 2008-09-15 19:43:22 UTC (rev 1334) +++ trunk/tests/fipsrngdrv.c 2008-09-16 07:48:25 UTC (rev 1335) @@ -24,12 +24,26 @@ #include #include #include +#include +#include +#ifndef HAVE_W32_SYSTEM +# include +#endif -#include "../src/gcrypt.h" +#include #define PGM "fipsrngdrv" +#define my_isascii(c) (!((c) & 0x80)) +#define digitp(p) (*(p) >= '0' && *(p) <= '9') +#define hexdigitp(a) (digitp (a) \ + || (*(a) >= 'A' && *(a) <= 'F') \ + || (*(a) >= 'a' && *(a) <= 'f')) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) + static void die (const char *format, ...) { @@ -43,6 +57,37 @@ } +/* Convert STRING consisting of hex characters into its binary + representation and store that at BUFFER. BUFFER needs to be of + LENGTH bytes. The function checks that the STRING will convert + exactly to LENGTH bytes. The string is delimited by either end of + string or a white space character. The function returns -1 on + error or the length of the parsed string. */ +int +hex2bin (const char *string, void *buffer, size_t length) +{ + int i; + const char *s = string; + + for (i=0; i < length; ) + { + if (!hexdigitp (s) || !hexdigitp (s+1)) + return -1; /* Invalid hex digits. */ + ((unsigned char*)buffer)[i++] = xtoi_2 (s); + s += 2; + } + if (*s && (!my_isascii (*s) || !isspace (*s)) ) + return -1; /* Not followed by Nul or white space. */ + if (i != length) + return -1; /* Not of expected length. */ + if (*s) + s++; /* Skip the delimiter. */ + return s - string; +} + + + + static gcry_error_t init_external_test (void **r_context, unsigned int flags, @@ -81,37 +126,116 @@ int main (int argc, char **argv) { + int last_argc = -1; + int verbose = 0; + int binary = 0; + int loop = 0; + int progress = 0; + unsigned char key[16]; + unsigned char seed[16]; + unsigned char dt[16]; void *context; gpg_error_t err; - int block; unsigned char buffer[16]; - (void)argc; - (void)argv; + if (argc) + { argc--; argv++; } + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--verbose")) + { + verbose = 2; + argc--; argv++; + } + else if (!strcmp (*argv, "--binary")) + { + binary = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--loop")) + { + loop = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--progress")) + { + progress = 1; + argc--; argv++; + } + } + + if (!argc) + { + memcpy (key, "1234567890123456", 16); + memcpy (seed, "abcdefghijklmnop", 16); + memcpy (dt, "XXXXXXXXXXXXXXXX", 16); + } + else if (argc == 3) + { + if ( hex2bin (argv[0], key, 16) < 0 + || hex2bin (argv[1], seed, 16) < 0 + || hex2bin (argv[2], dt, 16) < 0 ) + die ("args are not 32 hex digits each\n"); + } + else + die ("invalid usage\n"); + +#ifndef HAVE_W32_SYSTEM + if (loop) + signal (SIGPIPE, SIG_IGN); +#endif + + gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); - if (!gcry_check_version (GCRYPT_VERSION)) + if (!gcry_check_version ("1.4.3")) die ("version mismatch\n"); gcry_control (GCRYCTL_DISABLE_SECMEM, 0); - gcry_control (GCRYCTL_SET_VERBOSITY, 2); gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); - err = init_external_test (&context, 0, - "1234567890123456", 16, - "abcdefghijklmnop", 16, - "XXXXXXXXXXXXXXXX", 16); + err = init_external_test (&context, 0, key, 16, seed, 16, dt, 16); if (err) die ("init external test failed: %s\n", gpg_strerror (err)); - for (block=0; block < 10; block++) + do { err = run_external_test (context, buffer, sizeof buffer); if (err) die ("run external test failed: %s\n", gpg_strerror (err)); - print_buffer (buffer, sizeof buffer); - putchar ('\n'); + if (binary) + { + if (fwrite (buffer, 16, 1, stdout) != 1) + { +#ifndef HAVE_W32_SYSTEM + if (loop && errno == EPIPE) + break; +#endif + die ("writing output failed: %s\n", strerror (errno)); + } + fflush (stdout); + } + else + { + print_buffer (buffer, sizeof buffer); + putchar ('\n'); + } + if (progress) + { + putc ('.', stderr); + fflush (stderr); + } } + while (loop); + if (progress) + putc ('\n', stderr); + deinit_external_test (context); return 0; From cvs at cvs.gnupg.org Tue Sep 16 16:28:17 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 16 Sep 2008 16:28:17 +0200 Subject: [svn] gcry - r1336 - in trunk: doc random tests Message-ID: Author: wk Date: 2008-09-16 16:28:17 +0200 (Tue, 16 Sep 2008) New Revision: 1336 Modified: trunk/doc/gcrypt.texi trunk/random/ChangeLog trunk/random/random-fips.c trunk/tests/ChangeLog trunk/tests/fipsrngdrv.c Log: Make fipsrngdriv more pretty. Fix a problem in the RNG test code. Minor doc update. Modified: trunk/random/ChangeLog =================================================================== --- trunk/random/ChangeLog 2008-09-16 07:48:25 UTC (rev 1335) +++ trunk/random/ChangeLog 2008-09-16 14:28:17 UTC (rev 1336) @@ -1,6 +1,7 @@ 2008-09-16 Werner Koch * random-fips.c (x931_aes_driver): No re-seeding with test contexts. + (_gcry_rngfips_init_external_test): Fix setting of test_dt_ptr. 2008-09-15 Werner Koch Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-09-16 07:48:25 UTC (rev 1335) +++ trunk/tests/ChangeLog 2008-09-16 14:28:17 UTC (rev 1336) @@ -1,6 +1,7 @@ 2008-09-16 Werner Koch - * fipsrngdrv.c: Bail out on write error. + * fipsrngdrv.c (main): Bail out on write error. Implement verbose + option. 2008-09-15 Werner Koch Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-16 07:48:25 UTC (rev 1335) +++ trunk/doc/gcrypt.texi 2008-09-16 14:28:17 UTC (rev 1336) @@ -3442,10 +3442,11 @@ @item GCRY_MD_FLAG_HMAC Turn the algorithm into a HMAC message authentication algorithm. This -only works if just one algorithm is enabled for the handle. Note that the function - at 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}. +only works if just one algorithm is enabled for the handle. Note that +the function @code{gcry_md_setkey} must be used to set the MAC key. +The size of the MAC is equal to the message digest of the underlying +hash algorithm. 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 @@ -3472,7 +3473,7 @@ @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}. +of length @var{keylen}. There is no restriction on the length of the key. @end deftypefun Modified: trunk/random/random-fips.c =================================================================== --- trunk/random/random-fips.c 2008-09-16 07:48:25 UTC (rev 1335) +++ trunk/random/random-fips.c 2008-09-16 14:28:17 UTC (rev 1336) @@ -37,7 +37,7 @@ caller requested less bits, the extra bits are not used. The key for each generator is only set once at the first time a generator is used. The seed value is set with the key and again after 1000 - (SEED_TTL) output blocks. + (SEED_TTL) output blocks; the re-seeding is disabled in test mode. The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are keyed and seeded from the /dev/random device. Thus these @@ -1043,9 +1043,9 @@ /* Setup a DT value. Because our context structure only stores a pointer we copy the DT value to the extra space we allocated in - the test_ctx and set the pointer to tehre. */ - memcpy ((char*)test_ctx + sizeof *test_ctx, dt, dtlen); - test_ctx->test_dt_ptr = (unsigned char*)test_ctx + sizeof test_ctx; + the test_ctx and set the pointer to that address. */ + memcpy ((unsigned char*)test_ctx + sizeof *test_ctx, dt, dtlen); + test_ctx->test_dt_ptr = (unsigned char*)test_ctx + sizeof *test_ctx; test_ctx->test_dt_counter = ( (test_ctx->test_dt_ptr[12] << 24) |(test_ctx->test_dt_ptr[13] << 16) |(test_ctx->test_dt_ptr[14] << 8) Modified: trunk/tests/fipsrngdrv.c =================================================================== --- trunk/tests/fipsrngdrv.c 2008-09-16 07:48:25 UTC (rev 1335) +++ trunk/tests/fipsrngdrv.c 2008-09-16 14:28:17 UTC (rev 1336) @@ -63,7 +63,7 @@ exactly to LENGTH bytes. The string is delimited by either end of string or a white space character. The function returns -1 on error or the length of the parsed string. */ -int +static int hex2bin (const char *string, void *buffer, size_t length) { int i; @@ -149,9 +149,16 @@ argc--; argv++; break; } + else if (!strcmp (*argv, "--help")) + { + fputs ("usage: " PGM + " [--verbose] [--binary] [--loop] [--progress] KEY V DT\n", + stdout); + exit (0); + } else if (!strcmp (*argv, "--verbose")) { - verbose = 2; + verbose++; argc--; argv++; } else if (!strcmp (*argv, "--binary")) @@ -185,13 +192,16 @@ die ("args are not 32 hex digits each\n"); } else - die ("invalid usage\n"); + die ("invalid usage (try --help)\n"); #ifndef HAVE_W32_SYSTEM if (loop) signal (SIGPIPE, SIG_IGN); #endif + if (verbose) + fputs (PGM ": started\n", stderr); + gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); if (!gcry_check_version ("1.4.3")) @@ -205,26 +215,33 @@ do { + int writerr = 0; + err = run_external_test (context, buffer, sizeof buffer); if (err) die ("run external test failed: %s\n", gpg_strerror (err)); if (binary) { if (fwrite (buffer, 16, 1, stdout) != 1) - { -#ifndef HAVE_W32_SYSTEM - if (loop && errno == EPIPE) - break; -#endif - die ("writing output failed: %s\n", strerror (errno)); - } - fflush (stdout); + writerr = 1; + else + fflush (stdout); } else { print_buffer (buffer, sizeof buffer); - putchar ('\n'); + if (putchar ('\n') == EOF) + writerr = 1; } + if (writerr) + { +#ifndef HAVE_W32_SYSTEM + if (loop && errno == EPIPE) + break; +#endif + die ("writing output failed: %s\n", strerror (errno)); + } + if (progress) { putc ('.', stderr); @@ -238,6 +255,9 @@ deinit_external_test (context); + if (verbose) + fputs (PGM ": ready\n", stderr); + return 0; } From cvs at cvs.gnupg.org Tue Sep 16 17:23:24 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 16 Sep 2008 17:23:24 +0200 Subject: [svn] gpgme - r1331 - trunk/gpgme Message-ID: Author: marcus Date: 2008-09-16 17:23:23 +0200 (Tue, 16 Sep 2008) New Revision: 1331 Modified: trunk/gpgme/ChangeLog trunk/gpgme/rungpg.c Log: 2008-09-16 Marcus Brinkmann * rungpg.c (gpg_new): Don't use errno with ttyname_r. Modified: trunk/gpgme/ChangeLog =================================================================== --- trunk/gpgme/ChangeLog 2008-08-11 17:23:45 UTC (rev 1330) +++ trunk/gpgme/ChangeLog 2008-09-16 15:23:23 UTC (rev 1331) @@ -1,3 +1,7 @@ +2008-09-16 Marcus Brinkmann + + * rungpg.c (gpg_new): Don't use errno with ttyname_r. + 2008-08-11 Marcus Brinkmann * rungpg.c (gpg_cancel): Remove cmd fd before status fd. @@ -12,7 +16,7 @@ * rungpg.c (command_handler): Remove I/O callback on error, too. -2008-06-29 Marcus Brinkmann +2008-06-29 Marcus Brinkmann * gpgme.c (gpgme_cancel_async): Remove unused variable. Modified: trunk/gpgme/rungpg.c =================================================================== --- trunk/gpgme/rungpg.c 2008-08-11 17:23:45 UTC (rev 1330) +++ trunk/gpgme/rungpg.c 2008-09-16 15:23:23 UTC (rev 1331) @@ -516,7 +516,7 @@ err = ttyname_r (1, dft_ttyname, sizeof (dft_ttyname)); if (err) - rc = gpg_error_from_errno (errno); + rc = gpg_error_from_errno (err); else { if (*dft_ttyname) From cvs at cvs.gnupg.org Tue Sep 16 17:30:44 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 16 Sep 2008 17:30:44 +0200 Subject: [svn] gpgme - r1332 - trunk Message-ID: Author: marcus Date: 2008-09-16 17:30:44 +0200 (Tue, 16 Sep 2008) New Revision: 1332 Modified: trunk/ChangeLog trunk/configure.ac Log: 2008-09-16 Marcus Brinkmann * configure.ac (_XOPEN_SOURCE) [apple-darwin]: Define it. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-09-16 15:23:23 UTC (rev 1331) +++ trunk/ChangeLog 2008-09-16 15:30:44 UTC (rev 1332) @@ -1,3 +1,7 @@ +2008-09-16 Marcus Brinkmann + + * configure.ac (_XOPEN_SOURCE) [apple-darwin]: Define it. + 2008-07-04 Werner Koch * config.guess, config.sub: Update to 2007-11-19. Also update Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-09-16 15:23:23 UTC (rev 1331) +++ trunk/configure.ac 2008-09-16 15:30:44 UTC (rev 1332) @@ -110,7 +110,12 @@ *-*-gnu*) have_ld_version_script=yes ;; + *-apple-darwin*) + AC_DEFINE(_XOPEN_SOURCE, 500, Activate POSIX interface on MacOS X) + ;; esac + +esac AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes") GPG_DEFAULT=no From cvs at cvs.gnupg.org Tue Sep 16 18:53:43 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 16 Sep 2008 18:53:43 +0200 Subject: [svn] gcry - r1337 - in trunk: doc src Message-ID: Author: wk Date: 2008-09-16 18:53:43 +0200 (Tue, 16 Sep 2008) New Revision: 1337 Modified: trunk/doc/ChangeLog trunk/doc/fips-fsm.fig trunk/doc/gcrypt.texi trunk/src/ChangeLog trunk/src/fips.c Log: Allow transition to Error states from thye Init state. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-09-16 14:28:17 UTC (rev 1336) +++ trunk/doc/ChangeLog 2008-09-16 16:53:43 UTC (rev 1337) @@ -1,3 +1,8 @@ +2008-09-16 Werner Koch + + * gcrypt.texi (FIPS Mode): Describe new transitions 18 and 19. + * fips-fsm.fig: Add new transitions. + 2008-09-15 Werner Koch * gcrypt.texi: Fold the two FIPS appendices into one. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-16 14:28:17 UTC (rev 1336) +++ trunk/src/ChangeLog 2008-09-16 16:53:43 UTC (rev 1337) @@ -1,3 +1,8 @@ +2008-09-16 Werner Koch + + * fips.c (fips_new_state): Allow transition to Error and + Fatal-error from Init. + 2008-09-15 Werner Koch * fips.c [HAVE_SYSLOG]: Include syslog.h. Modified: trunk/doc/fips-fsm.fig =================================================================== --- trunk/doc/fips-fsm.fig 2008-09-16 14:28:17 UTC (rev 1336) +++ trunk/doc/fips-fsm.fig 2008-09-16 16:53:43 UTC (rev 1337) @@ -1,4 +1,4 @@ -#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +#FIG 3.2 Portrait Center Metric @@ -20,51 +20,128 @@ 0 42 #8c8c8c 0 43 #424242 6 900 270 8775 9450 -6 900 270 8775 9450 5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 4837.500 16740.000 6750 6705 4725 6525 2925 6705 1 1 2.00 120.00 240.00 5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 3026.138 8399.825 4185 8370 3870 7605 2925 7245 1 1 2.00 120.00 240.00 +5 1 0 2 0 7 50 -1 -1 0.000 1 1 1 0 7708.125 -2028.750 2925 5175 4815 6120 6795 6570 + 1 1 2.00 120.00 240.00 +6 3096 1593 3380 1877 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3238 1735 142 142 3238 1735 3103 1690 +4 0 0 50 -1 13 12 0.0000 4 105 105 3157 1805 1\001 +-6 +6 2266 3607 2550 3891 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2408 3749 142 142 2408 3749 2273 3704 +4 0 0 50 -1 13 12 0.0000 4 105 105 2327 3819 2\001 +-6 +6 1566 5667 1850 5951 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 1708 5809 142 142 1708 5809 1573 5764 +4 0 0 50 -1 13 12 0.0000 4 105 105 1627 5879 3\001 +-6 +6 5706 1543 5990 1827 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5848 1685 142 142 5848 1685 5713 1640 +4 0 0 50 -1 13 12 0.0000 4 105 105 5767 1755 6\001 +-6 +6 5986 7757 6270 8041 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6128 7899 142 142 6128 7899 5993 7854 +4 0 0 50 -1 13 12 0.0000 4 105 105 6047 7969 7\001 +-6 +6 7426 4747 7710 5031 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 7568 4889 142 142 7568 4889 7433 4844 +4 0 0 50 -1 13 12 0.0000 4 105 105 7487 4959 8\001 +-6 +6 5866 3737 6150 4021 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6008 3879 142 142 6008 3879 5873 3834 +4 0 0 50 -1 13 12 0.0000 4 105 210 5882 3940 10\001 +-6 +6 5276 2517 5560 2801 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5418 2659 142 142 5418 2659 5283 2614 +4 0 0 50 -1 13 12 0.0000 4 105 210 5292 2720 11\001 +-6 +6 4126 3573 4410 3857 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4268 3715 142 142 4268 3715 4133 3670 +4 0 0 50 -1 13 12 0.0000 4 105 210 4142 3776 12\001 +-6 +6 3066 5723 3350 6007 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3208 5865 142 142 3208 5865 3073 5820 +4 0 0 50 -1 13 12 0.0000 4 105 210 3082 5926 13\001 +-6 +6 4036 6623 4320 6907 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4178 6765 142 142 4178 6765 4043 6720 +4 0 0 50 -1 13 12 0.0000 4 105 210 4052 6826 14\001 +-6 +6 4416 7213 4700 7497 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4558 7355 142 142 4558 7355 4423 7310 +4 0 0 50 -1 13 12 0.0000 4 105 210 4432 7416 15\001 +-6 +6 5066 7223 5350 7507 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5208 7365 142 142 5208 7365 5073 7320 +4 0 0 50 -1 13 12 0.0000 4 105 105 5127 7435 5\001 +-6 +6 3566 7573 3850 7857 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3708 7715 142 142 3708 7715 3573 7670 +4 0 0 50 -1 13 12 0.0000 4 105 210 3582 7776 16\001 +-6 +6 2896 7783 3180 8067 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3038 7925 142 142 3038 7925 2903 7880 +4 0 0 50 -1 13 12 0.0000 4 105 105 2957 7995 4\001 +-6 +6 6426 5753 6710 6037 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6568 5895 142 142 6568 5895 6433 5850 +4 0 0 50 -1 13 12 0.0000 4 105 105 6487 5965 9\001 +-6 6 3600 8370 5985 9450 2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5 5970 9450 3600 9450 3600 8370 5970 8370 5970 9450 -4 0 0 50 -1 0 24 0.0000 4 360 1965 3870 9000 Operational\001 +4 0 0 50 -1 0 24 0.0000 4 330 1725 3870 9000 Operational\001 -6 6 900 4320 2970 5445 2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5 2940 5445 915 5445 915 4335 2940 4335 2940 5445 -4 0 0 50 -1 0 24 0.0000 4 270 585 1620 4995 Init\001 +4 0 0 50 -1 0 24 0.0000 4 240 510 1620 4995 Init\001 -6 6 900 6345 2970 7470 2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5 2955 7455 930 7455 930 6345 2955 6345 2955 7455 -4 0 0 50 -1 0 24 0.0000 4 270 1515 1215 7020 Self-Test\001 +4 0 0 50 -1 0 24 0.0000 4 255 1335 1215 7020 Self-Test\001 -6 6 6750 6345 8775 7470 2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5 8775 7470 6750 7470 6750 6360 8775 6360 8775 7470 -4 0 0 50 -1 0 24 0.0000 4 270 870 7335 7020 Error\001 +4 0 0 50 -1 0 24 0.0000 4 240 765 7335 7020 Error\001 -6 6 3825 4320 5850 5445 2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5 5850 5445 3825 5445 3825 4335 5850 4335 5850 5445 -4 0 0 50 -1 0 24 0.0000 4 270 1830 3915 4995 Fatal-Error\001 +4 0 0 50 -1 0 24 0.0000 4 255 1620 3915 4995 Fatal-Error\001 -6 6 6750 2295 8775 3420 2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5 8775 3420 6750 3420 6750 2310 8775 2310 8775 3420 -4 0 0 50 -1 0 24 0.0000 4 270 1695 6930 2970 Shutdown\001 +4 0 0 50 -1 0 24 0.0000 4 240 1455 6930 2970 Shutdown\001 -6 6 2475 2295 4500 3420 2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5 4500 3405 2475 3405 2475 2295 4500 2295 4500 3405 -4 0 0 50 -1 0 24 0.0000 4 270 1695 2655 2970 Power-On\001 +4 0 0 50 -1 0 24 0.0000 4 240 1470 2655 2970 Power-On\001 -6 6 2475 270 4500 1395 2 4 0 1 0 7 50 -1 -1 0.000 0 0 20 0 0 5 4500 1395 2475 1395 2475 285 4500 285 4500 1395 -4 0 0 50 -1 0 24 0.0000 4 270 1755 2565 945 Power-Off\001 +4 0 0 50 -1 0 24 0.0000 4 240 1530 2565 945 Power-Off\001 -6 +6 4050 6196 4334 6480 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4192 6338 142 142 4192 6338 4057 6293 +4 0 0 50 -1 13 12 0.0000 4 105 210 4066 6399 17\001 +-6 +6 3188 5033 3486 5331 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3337 5182 142 142 3337 5182 3202 5137 +4 0 0 50 -1 13 12 0.0000 4 105 210 3211 5243 18\001 +-6 +6 3053 4358 3351 4656 +1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3202 4507 142 142 3202 4507 3067 4462 +4 0 0 50 -1 13 12 0.0000 4 105 210 3076 4568 19\001 +-6 2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2 1 1 2.00 120.00 240.00 3420 1395 3420 2295 @@ -110,73 +187,7 @@ 2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2 1 1 2.00 120.00 240.00 5895 8460 6840 7380 +2 1 0 2 0 7 50 -1 -1 0.000 0 1 -1 1 0 2 + 1 1 2.00 120.00 240.00 + 2925 4680 3825 4680 -6 -6 3096 1593 3380 1877 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3238 1735 142 142 3238 1735 3103 1690 -4 0 0 50 -1 13 12 0.0000 4 105 120 3157 1805 1\001 --6 -6 2266 3607 2550 3891 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 2408 3749 142 142 2408 3749 2273 3704 -4 0 0 50 -1 13 12 0.0000 4 105 120 2327 3819 2\001 --6 -6 1566 5667 1850 5951 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 1708 5809 142 142 1708 5809 1573 5764 -4 0 0 50 -1 13 12 0.0000 4 105 120 1627 5879 3\001 --6 -6 5706 1543 5990 1827 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5848 1685 142 142 5848 1685 5713 1640 -4 0 0 50 -1 13 12 0.0000 4 105 120 5767 1755 6\001 --6 -6 5986 7757 6270 8041 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6128 7899 142 142 6128 7899 5993 7854 -4 0 0 50 -1 13 12 0.0000 4 105 120 6047 7969 7\001 --6 -6 7426 4747 7710 5031 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 7568 4889 142 142 7568 4889 7433 4844 -4 0 0 50 -1 13 12 0.0000 4 105 120 7487 4959 8\001 --6 -6 5866 3737 6150 4021 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6008 3879 142 142 6008 3879 5873 3834 -4 0 0 50 -1 13 12 0.0000 4 105 240 5882 3940 10\001 --6 -6 5276 2517 5560 2801 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5418 2659 142 142 5418 2659 5283 2614 -4 0 0 50 -1 13 12 0.0000 4 105 240 5292 2720 11\001 --6 -6 4126 3573 4410 3857 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4268 3715 142 142 4268 3715 4133 3670 -4 0 0 50 -1 13 12 0.0000 4 105 240 4142 3776 12\001 --6 -6 3066 5723 3350 6007 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3208 5865 142 142 3208 5865 3073 5820 -4 0 0 50 -1 13 12 0.0000 4 105 240 3082 5926 13\001 --6 -6 4036 6623 4320 6907 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4178 6765 142 142 4178 6765 4043 6720 -4 0 0 50 -1 13 12 0.0000 4 105 240 4052 6826 14\001 --6 -6 4416 7213 4700 7497 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 4558 7355 142 142 4558 7355 4423 7310 -4 0 0 50 -1 13 12 0.0000 4 105 240 4432 7416 15\001 --6 -6 5066 7223 5350 7507 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5208 7365 142 142 5208 7365 5073 7320 -4 0 0 50 -1 13 12 0.0000 4 105 120 5127 7435 5\001 --6 -6 3566 7573 3850 7857 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3708 7715 142 142 3708 7715 3573 7670 -4 0 0 50 -1 13 12 0.0000 4 105 240 3582 7776 16\001 --6 -6 4996 6193 5280 6477 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 5138 6335 142 142 5138 6335 5003 6290 -4 0 0 50 -1 13 12 0.0000 4 105 240 5012 6396 17\001 --6 -6 2896 7783 3180 8067 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 3038 7925 142 142 3038 7925 2903 7880 -4 0 0 50 -1 13 12 0.0000 4 105 120 2957 7995 4\001 --6 -6 6426 5753 6710 6037 -1 3 0 1 0 7 50 -1 -1 0.000 1 0.0000 6568 5895 142 142 6568 5895 6433 5850 -4 0 0 50 -1 13 12 0.0000 4 105 120 6487 5965 9\001 --6 --6 Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-16 14:28:17 UTC (rev 1336) +++ trunk/doc/gcrypt.texi 2008-09-16 16:53:43 UTC (rev 1337) @@ -5566,7 +5566,7 @@ Self-Test to Error is triggred by a failed self-test. @item 15 -Operational to Fatal-Error is triggred if Libcrypt encountered a +Operational to Fatal-Error is triggered if Libcrypt encountered a non-recoverable error. @item 16 @@ -5577,6 +5577,13 @@ Error to Self-Test is triggered if the application has requested to run self-tests to get to get back into operational state after an error. + at item 18 +Init to Error is triggered by errors in the initialization code. + + at item 19 +Init to Fatal-Error is triggered by non-recoverable errors in the +initialization code. + @end table @end float Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2008-09-16 14:28:17 UTC (rev 1336) +++ trunk/src/fips.c 2008-09-16 16:53:43 UTC (rev 1337) @@ -680,7 +680,9 @@ break; case STATE_INIT: - if (new_state == STATE_SELFTEST ) + if (new_state == STATE_SELFTEST + || new_state == STATE_ERROR + || new_state == STATE_FATALERROR) ok = 1; break; From cvs at cvs.gnupg.org Tue Sep 16 21:22:11 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 16 Sep 2008 21:22:11 +0200 Subject: [svn] gcry - r1338 - in trunk: cipher doc random src tests Message-ID: Author: wk Date: 2008-09-16 21:22:10 +0200 (Tue, 16 Sep 2008) New Revision: 1338 Added: trunk/tests/cavs_driver.pl Modified: trunk/cipher/ChangeLog trunk/cipher/ecc.c trunk/doc/gcrypt.texi trunk/random/ChangeLog trunk/random/rand-internal.h trunk/random/random-fips.c trunk/random/random.c trunk/src/ChangeLog trunk/src/global.c trunk/tests/ChangeLog trunk/tests/Makefile.am trunk/tests/fipsrngdrv.c Log: Another tweak for the RNG test code. [The diff below has been truncated] Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/cipher/ChangeLog 2008-09-16 19:22:10 UTC (rev 1338) @@ -1,3 +1,7 @@ +2008-09-16 Werner Koch + + * ecc.c (run_selftests): Add arg EXTENDED. + 2008-09-12 Werner Koch * rsa.c (test_keys): Do a bad case signature check. Modified: trunk/random/ChangeLog =================================================================== --- trunk/random/ChangeLog 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/random/ChangeLog 2008-09-16 19:22:10 UTC (rev 1338) @@ -2,6 +2,11 @@ * random-fips.c (x931_aes_driver): No re-seeding with test contexts. (_gcry_rngfips_init_external_test): Fix setting of test_dt_ptr. + (struct rng_context): Add flag TEST_NO_DUP_CHECK. + (x931_aes_driver): Use that flag. + (_gcry_rngfips_init_external_test): Add arg FLAGS and use it to + modify the test. + * random.c (_gcry_random_init_external_test): Pass FLAGS. 2008-09-15 Werner Koch Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/src/ChangeLog 2008-09-16 19:22:10 UTC (rev 1338) @@ -1,5 +1,7 @@ 2008-09-16 Werner Koch + * global.c (print_config): Use y/n for fips mode. + * fips.c (fips_new_state): Allow transition to Error and Fatal-error from Init. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/tests/ChangeLog 2008-09-16 19:22:10 UTC (rev 1338) @@ -2,6 +2,7 @@ * fipsrngdrv.c (main): Bail out on write error. Implement verbose option. + (main): Use flag to disable dup block checks. 2008-09-15 Werner Koch Modified: trunk/cipher/ecc.c =================================================================== --- trunk/cipher/ecc.c 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/cipher/ecc.c 2008-09-16 19:22:10 UTC (rev 1338) @@ -1316,10 +1316,12 @@ /* Run a full self-test for ALGO and return 0 on success. */ static gpg_err_code_t -run_selftests (int algo, selftest_report_func_t report) +run_selftests (int algo, int extended, selftest_report_func_t report) { gpg_err_code_t ec; + (void)extended; + switch (algo) { case GCRY_PK_ECDSA: Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/doc/gcrypt.texi 2008-09-16 19:22:10 UTC (rev 1338) @@ -5249,9 +5249,9 @@ @code{GCRYCTL_SELFTEST} control command. Note that using these tests is not FIPS conform: Although Libgcrypt rejects all application requests for services while running self-tests, it does not ensure -that no other operations of Libgcrypt are still being executed. Thus -in FIPS mode an application requesting self-tests needs to be -power-cycle Libgcrypt instead. +that no other operations of Libgcrypt are still being executed. Thus, +in FIPS mode an application requesting self-tests needs to power-cycle +Libgcrypt instead. When self-tests are requested, Libgcrypt runs all the tests it does during power-up as well as a few extra checks as described below. Modified: trunk/random/rand-internal.h =================================================================== --- trunk/random/rand-internal.h 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/random/rand-internal.h 2008-09-16 19:22:10 UTC (rev 1338) @@ -79,7 +79,8 @@ gcry_error_t _gcry_rngfips_selftest (selftest_report_func_t report); -gcry_err_code_t _gcry_rngfips_init_external_test (void **r_context, +gcry_err_code_t _gcry_rngfips_init_external_test (void **r_context, + unsigned int flags, const void *key, size_t keylen, const void *seed, Modified: trunk/random/random-fips.c =================================================================== --- trunk/random/random-fips.c 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/random/random-fips.c 2008-09-16 19:22:10 UTC (rev 1338) @@ -141,13 +141,16 @@ unsigned char guard_3[1]; + /* The external test may want to suppress the duplicate bock check. + This is done if the this flag is set. */ + unsigned char test_no_dup_check; /* To implement a KAT we need to provide a know DT value. To accomplish this the x931_get_dt function checks whether this field is not NULL and then uses the 16 bytes at this address for the DT value. However the last 4 bytes are replaced by the value of field TEST_DT_COUNTER which will be incremented after each invocation of x931_get_dt. We use a pointer and not a buffer - because there is no need to put this value into secure memory. */ + because there is no need to put this value into secure memory. */ const unsigned char *test_dt_ptr; u32 test_dt_counter; @@ -476,24 +479,36 @@ intermediate_I, temp_buffer); rng_ctx->use_counter++; - /* Do a basic check on the output to avoid a stuck generator. */ - if (!rng_ctx->compare_value_valid) + if (rng_ctx->test_no_dup_check + && rng_ctx->test_dt_ptr + && rng_ctx != nonce_context + && rng_ctx != std_rng_context + && rng_ctx != strong_rng_context) { - /* First time used, only save the result. */ - memcpy (rng_ctx->compare_value, result_buffer, 16); - rng_ctx->compare_value_valid = 1; - continue; + /* This is a test context which does not want the duplicate + block check. */ } - if (!memcmp (rng_ctx->compare_value, result_buffer, 16)) + else { - /* Ooops, we received the same 128 bit block - that should - in theory never happen. The FIPS requirement says that - we need to put ourself into the error state in such - case. */ - fips_signal_error ("duplicate 128 bit block returned by RNG"); - return -1; + /* Do a basic check on the output to avoid a stuck generator. */ + if (!rng_ctx->compare_value_valid) + { + /* First time used, only save the result. */ + memcpy (rng_ctx->compare_value, result_buffer, 16); + rng_ctx->compare_value_valid = 1; + continue; + } + if (!memcmp (rng_ctx->compare_value, result_buffer, 16)) + { + /* Ooops, we received the same 128 bit block - that should + in theory never happen. The FIPS requirement says that + we need to put ourself into the error state in such + case. */ + fips_signal_error ("duplicate 128 bit block returned by RNG"); + return -1; + } + memcpy (rng_ctx->compare_value, result_buffer, 16); } - memcpy (rng_ctx->compare_value, result_buffer, 16); /* Append to outbut. */ memcpy (output, result_buffer, nbytes); @@ -1002,7 +1017,7 @@ success the test context is stored at R_CONTEXT; on failure NULL is stored at R_CONTEXT and an error code is returned. */ gcry_err_code_t -_gcry_rngfips_init_external_test (void **r_context, +_gcry_rngfips_init_external_test (void **r_context, unsigned int flags, const void *key, size_t keylen, const void *seed, size_t seedlen, const void *dt, size_t dtlen) @@ -1051,6 +1066,9 @@ |(test_ctx->test_dt_ptr[14] << 8) |(test_ctx->test_dt_ptr[15]) ); + if ( (flags & 1) ) + test_ctx->test_no_dup_check = 1; + check_guards (test_ctx); /* All fine. */ err = 0; Modified: trunk/random/random.c =================================================================== --- trunk/random/random.c 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/random/random.c 2008-09-16 19:22:10 UTC (rev 1338) @@ -296,7 +296,7 @@ { (void)flags; if (fips_mode ()) - return _gcry_rngfips_init_external_test (r_context, key, keylen, + return _gcry_rngfips_init_external_test (r_context, flags, key, keylen, seed, seedlen, dt, dtlen); else Modified: trunk/src/global.c =================================================================== --- trunk/src/global.c 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/src/global.c 2008-09-16 19:22:10 UTC (rev 1338) @@ -294,7 +294,10 @@ if ( (hwf & hwflist[i].flag) ) fnc (fp, "%s:", hwflist[i].desc); fnc (fp, "\n"); - fnc (fp, "fips-mode:%d:\n", fips_mode () ); + /* We use y/n instead of 1/0 for the simple reason that Emacsen's + compile error parser would accidently flag that line when printed + during "make check" as an error. */ + fnc (fp, "fips-mode:%c:\n", fips_mode ()? 'y':'n' ); } Modified: trunk/tests/Makefile.am =================================================================== --- trunk/tests/Makefile.am 2008-09-16 16:53:43 UTC (rev 1337) +++ trunk/tests/Makefile.am 2008-09-16 19:22:10 UTC (rev 1338) @@ -43,3 +43,6 @@ EXTRA_DIST = README rsa-16k.key +# Note: There is a file cavs-driver.pl in the SVN but we do not +# distribute it because we have no configure tests for Perl and thus +# we can expect that people get it from the SVN instead. Added: trunk/tests/cavs_driver.pl =================================================================== --- trunk/tests/cavs_driver.pl (rev 0) +++ trunk/tests/cavs_driver.pl 2008-09-16 19:22:10 UTC (rev 1338) @@ -0,0 +1,1498 @@ +#!/usr/bin/env perl +# +# CAVS test driver (based on the OpenSSL driver) +# Written by: Stephan M?ller +# Copyright (c) atsec information security corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# NO WARRANTY +# +# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +# REPAIR OR CORRECTION. +# +# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGES. +# +# +# test execution instruction: +# 1. get the request files from the lab +# 2. call each request file from 1. with this program: +# $0 .rep +# 3. send the resulting file .rsp to the lab +# +# +# Test should be easily adoptable to other implementations +# See the first functions for this task +# +# Following tests are covered (others may also be covered +# but have not been tested) +# +# AES +# CBCGFSbox[128|192|256] +# CBCMCT[128|192|256] +# CBCVarKey[128|192|256] +# CBCKeySbox[128|192|256] +# CBCMMT[128|192|256] +# CBCVarTxt[128|192|256] +# +# RSA +# SigGen[15|RSA] +# SigVer15 +# (SigVerRSA is not applicable for OpenSSL as X9.31 padding +# is not done through openssl dgst) +# +# SHA +# SHA1ShortMsg +# SHA1LongMsg +# SHA1Monte +# +# TDES +# TCBCMonte[1|2|3] +# TCBCpermop +# TCBCMMT[1|2|3] +# TCBCsubtab +# TCBCvarkey +# TCBCinvperm +# TCBCvartext +# +# ANSI X9.31 RNG +# ANSI931_AES128MCT +# ANSI931_AES128VST +# +# RC4 (atsec developed tests) +# RC4KeyBD +# RC4MCT +# RC4PltBD +# RC4REGT +# + +use strict; +use warnings; +use IPC::Open2; +use Getopt::Std; +use MIME::Base64; + +# Contains the command line options +my %opt; + + +################################################################# +##### Central interface functions to the external ciphers ####### +################################################################# +# Only these interface routines should be changed in case of +# porting to a new cipher library +# +# For porting to a new library, create implementation of these functions +# and then add pointers to the respective implementation of each +# function to the given variables. + +# common encryption/decryption routine +# $1 key in hex form +# $2 iv in hex form +# $3 cipher +# $4 encrypt=1/decrypt=0 +# $5 de/encrypted data in hex form +# return en/decrypted data in hex form +my $encdec; + +# Sign a message with RSA +# $1: data to be signed in hex form +# $2: Hash algo +# $3: Key file in PEM format with the private key +# return: digest in hex format +my $rsa_sign; + +# Verify a message with RSA +# $1: data to be verified in hex form +# $2: hash algo +# $3: file holding the public RSA key in PEM format +# $4: file holding the signature in binary form +# return: 1 == verfied / 0 == not verified +my $rsa_verify; + +# generate a new private RSA key in PEM format +# $1 key size in bit +# $2 keyfile name +# return: nothing, but file created +my $gen_rsakey; + +# Creating a hash +# $1: Plaintext +# $2: hash type +# return: hash in hex form +my $hash; + +# supplying the call to the external cipher implementation +# that is being used to keep STDIN and STDOUT open +# to maintain the state of the block chaining +# $1: cipher +# $2: 1=encryption, 0=decryption +# $3: buffersize needed for openssl +# $4: encryption key in binary form +# $5: IV in binary form +# return: command line to execute the application +my $state_cipher; + +# supplying the call to the external cipher implementation +# that is being used to keep STDIN and STDOUT open +# to maintain the state of the RNG with its seed +# +# input holds seed values +# $1: cipher key in hex format +# $2: DT value in hex format +# $3: V value in hex format +# +# return: command line to execute the application +# +# the application is expected to deliver random values on STDOUT - the script +# reads 128 bits repeatedly where the state of the RNG must be retained +# between the reads. The output of the RNG on STDOUT is assumed to be binary. +my $state_rng; + +################################################################ +##### OpenSSL interface functions +################################################################ +sub openssl_encdec($$$$$) { + my $key=shift; + my $iv=shift; + my $cipher=shift; + my $enc = (shift) ? "-e" : "-d"; + my $data=shift; + + $data=hex2bin($data); + my $program="openssl enc -$cipher -nopad -nosalt -K $key $enc -iv $iv"; + $program = "rc4 -k $key" if $opt{'R'}; #for ARCFOUR, no IV must be given + $data=pipe_through_program($data,$program); + return bin2hex($data); +} + +sub openssl_rsa_sign($$$) { + my $data = shift; + my $cipher = shift; + my $keyfile = shift; + + $data=hex2bin($data); + die "ARCFOUR not available for RSA" if $opt{'R'}; + $data=pipe_through_program($data, + "openssl dgst -$cipher -binary -sign $keyfile"); + return bin2hex($data); +} + +sub openssl_rsa_verify($$$$) { + my $data = shift; + my $cipher = shift; + my $keyfile = shift; + my $sigfile = shift; + + $data = hex2bin($data); + die "ARCFOUR not available for RSA" if $opt{'R'}; + $data = pipe_through_program($data, + "openssl dgst -$cipher -binary -verify $keyfile -signature $sigfile"); + + # Parse through the OpenSSL output information + return ($data =~ /OK/); +} + +sub openssl_gen_rsakey($$) { + my $keylen = shift; + my $file = shift; + + die "ARCFOUR not available for RSA" if $opt{'R'}; + # generating of a key with exponent 0x10001 + my @args = ("openssl", "genrsa", "-F4", "-out", "$file", "$keylen"); + system(@args) == 0 + or die "system @args failed: $?"; + die "system @args failed: file $file not created" if (! -f $file); +} + +sub openssl_hash($$) { + my $pt = shift; + my $cipher = shift; + + die "ARCFOUR not available for hashes" if $opt{'R'}; + my $hash = hex2bin($pt); + #bin2hex not needed as the '-hex' already converts it + return pipe_through_program($hash, "openssl dgst -$cipher -hex"); +} + +sub openssl_state_cipher($$$$$) { + my $cipher = shift; + my $encdec = shift; + my $bufsize = shift; + my $key = shift; + my $iv = shift; + + my $enc = $encdec ? "-e": "-d"; + + my $out = "openssl enc -'$cipher' $enc -nopad -nosalt -bufsize $bufsize -K ".bin2hex($key)." -iv ".bin2hex($iv); + #for ARCFOUR, no IV must be given + $out = "rc4 -k " . bin2hex($key) if $opt{'R'}; + return $out; +} + +###### End of OpenSSL interface implementation ############ + +########################################################### +###### libgcrypt implementation +########################################################### +sub libgcrypt_state_rng($$$) { + my $key = shift; + my $dt = shift; + my $v = shift; + + return "fipsrngdrv --binary --loop $key $v $dt"; +} + +######### End of libgcrypt implementation ################ + +##### No other interface functions below this point ###### +########################################################## + +########################################################## +# General helper routines + +# Executing a program by feeding STDIN and retrieving +# STDOUT +# $1: data string to be piped to the app on STDIN +# rest: program and args +# returns: STDOUT of program as string +sub pipe_through_program($@) { + my $in = shift; + my @args = @_; + + my ($CO, $CI); + my $pid = open2($CO, $CI, @args); + + my $out = ""; + my $len = length($in); + my $first = 1; + while (1) { + my $rin = ""; + my $win = ""; + # Output of prog is FD that we read + vec($rin,fileno($CO),1) = 1; + # Input of prog is FD that we write + # check for $first is needed because we can have NULL input + # that is to be written to the app + if ( $len > 0 || $first) { + (vec($win,fileno($CI),1) = 1); + $first=0; + } + # Let us wait for 100ms + my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1); + if ( $wout ) { + my $written = syswrite($CI, $in, $len); + die "broken pipe" if !defined $written; + $len -= $written; + substr($in, 0, $written) = ""; + if ($len <= 0) { + close $CI or die "broken pipe: $!"; + } + } + if ( $rout ) { + my $tmp_out = ""; + my $bytes_read = sysread($CO, $tmp_out, 4096); + $out .= $tmp_out; + last if ($bytes_read == 0); + } + } + close $CO or die "broken pipe: $!"; + waitpid $pid, 0; + + return $out; +} + +# +# convert ASCII hex to binary input +# $1 ASCII hex +# return binary representation +sub hex2bin($) { + my $in = shift; + my $len = length($in); + $len = 0 if ($in eq "00"); + return pack("H$len", "$in"); +} + +# +# convert binary input to ASCII hex +# $1 binary value +# return ASCII hex representation +sub bin2hex($) { + my $in = shift; + my $len = length($in)*2; + return unpack("H$len", "$in"); +} + +# $1: binary byte (character) +# returns: binary byte with odd parity using low bit as parity bit +sub odd_par($) { + my $in = ord(shift); + my $odd_count=0; + for(my $i=1; $i<8; $i++) { + $odd_count++ if ($in & (1<<$i)); + } + + my $out = $in; + if ($odd_count & 1) { # check if parity is already odd + $out &= ~1; # clear the low bit + } else { + $out |= 1; # set the low bit + } + + return chr($out); +} + +# DES keys uses only the 7 high bits of a byte, the 8th low bit +# is the parity bit +# as the new key is calculated from oldkey XOR cipher in the MCT test, +# the parity is not really checked and needs to be set to match +# expectation (OpenSSL does not really care, but the FIPS +# test result is expected that the key has the appropriate parity) +# $1: arbitrary binary string +# returns: string with odd parity set in low bit of each byte +sub fix_key_parity($) { + my $in = shift; + my $out = ""; + for (my $i = 0; $i < length($in); $i++) { + $out .= odd_par(substr($in, $i, 1)); + } + + return $out; +} + +#################################################### +# Encrypt/Decrypt routines + +# encryption +# $1 key in hex form +# $2 iv in hex form +# $3 cipher +# $4 data in hex form +# return encrypted data +sub encrypt($$$$) { + my $key=shift; + my $iv=shift; + my $cipher=shift; + my $data=shift; + + return &$encdec($key, $iv, $cipher, 1, $data); +} + +# decryption +# $1 key in hex form +# $2 iv in hex form +# $3 cipher +# $4 data in hex form +# return encrypted data +sub decrypt($$$$) { + my $key=shift; + my $iv=shift; + my $cipher=shift; + my $data=shift; + + return &$encdec($key, $iv, $cipher, 0, $data); +} + +#################################################### +# DER/PEM utility functions +# Cf. http://www.columbia.edu/~ariel/ssleay/layman.html + +# Convert unsigned integer to base256 bigint bytes +# $1 integer +# returns base256 octet string +sub int_base256_unsigned($) { + my $n = shift; + + my $out = chr($n & 255); + while ($n>>=8) { + $out = chr($n & 255) . $out; + } + + return $out; +} + +# Convert signed integer to base256 bigint bytes +# $1 integer +# returns base256 octet string +sub int_base256_signed($) { + my $n = shift; + my $negative = ($n < 0); + + if ($negative) { + $n = -$n-1; + } + + my $out = int_base256_unsigned($n); + + if (ord(substr($out, 0, 1)) & 128) { + # it's supposed to be positive but has sign bit set, + # add a leading zero + $out = chr(0) . $out; + } + + if ($negative) { + my $neg = chr(255) x length($out); + $out ^= $neg; + } + + return $out; +} + +# Length header for specified DER object length +# $1 length as integer +# return octet encoding for length +sub der_len($) { + my $len = shift; + + if ($len <= 127) { + return chr($len); + } else { + my $blen = int_base256_unsigned($len); + + return chr(128 | length($blen)) . $blen; + } +} + +# Prepend length header to object +# $1 object as octet sequence +# return length header for object followed by object as octets +sub der_len_obj($) { + my $x = shift; + + return der_len(length($x)) . $x; +} + +# DER sequence +# $* objects +# returns DER sequence consisting of the objects passed as arguments +sub der_seq { + my $seq = join("", @_); + return chr(0x30) . der_len_obj($seq); +} + +# DER bitstring +# $1 input octets (must be full octets, fractional octets not supported) +# returns input encapsulated as bitstring +sub der_bitstring($) { + my $x = shift; + + $x = chr(0) . $x; + + return chr(0x03) . der_len_obj($x); +} + +# base-128-encoded integer, used for object numbers. +# $1 integer +# returns octet sequence +sub der_base128($) { + my $n = shift; + + my $out = chr($n & 127); + + while ($n>>=7) { + $out = chr(128 | ($n & 127)) . $out; + } + + return $out; +} + +# Generating the PEM certificate string +# (base-64-encoded DER string) +# $1 DER string +# returns octet sequence +sub pem_cert($) { + my $n = shift; + + my $out = "-----BEGIN PUBLIC KEY-----\n"; + $out .= encode_base64($n); + $out .= "-----END PUBLIC KEY-----\n"; + + return $out; +} + +# DER object identifier +# $* sequence of id numbers +# returns octets +sub der_objectid { + my $v1 = shift; + my $v2 = shift; + + my $out = chr(40*$v1 + $v2) . join("", map { der_base128($_) } @_); + + return chr(0x06) . der_len_obj($out); +} + +# DER signed integer +# $1 number as octet string (base 256 representation, high byte first) +# returns number in DER integer encoding +sub der_bigint($) { + my $x = shift; + + return chr(0x02) . der_len_obj($x); +} + +# DER positive integer with leading zeroes stripped +# $1 number as octet string (base 256 representation, high byte first) +# returns number in DER integer encoding +sub der_pos_bigint($) { + my $x = shift; + + # strip leading zero digits + $x =~ s/^[\0]+//; + + # need to prepend a zero if high bit set, since it would otherwise be + # interpreted as a negative number. Also needed for number 0. + if (!length($x) || ord(substr($x, 0, 1)) >= 128) { + $x = chr(0) . $x; + } + + return der_bigint($x); +} + +# $1 number as signed integer +# returns number as signed DER integer encoding +sub der_int($) { + my $n = shift; + + return der_bigint(int_base256_signed($n)); +} + +# the NULL object constant +sub der_null() { + return chr(0x05) . chr(0x00); +} + +# Unit test helper +# $1 calculated result +# $2 expected result +# no return value, dies if results differ, showing caller's line number +sub der_test($$) { + my $actual = bin2hex(shift); + my $expected = shift; + + my @caller = caller; + $actual eq $expected or die "Error:line $caller[2]:assertion failed: " + ."$actual != $expected\n"; +} + +# Unit testing for the DER encoding functions +# Examples from http://www.columbia.edu/~ariel/ssleay/layman.html +# No input, no output. Dies if unit tests fail. +sub der_unit_test { + ## uncomment these if you want to test the test framework + #print STDERR "Unit test running\n"; + #der_test chr(0), "42"; + + der_test der_null, "0500"; + + # length bytes + der_test der_len(1), "01"; + der_test der_len(127), "7f"; + der_test der_len(128), "8180"; + der_test der_len(256), "820100"; + der_test der_len(65536), "83010000"; + + # bigint + der_test der_bigint(chr(0)), "020100"; + der_test der_bigint(chr(128)), "020180"; # -128 + der_test der_pos_bigint(chr(128)), "02020080"; # +128 + der_test der_pos_bigint(chr(0).chr(0).chr(1)), "020101"; + der_test der_pos_bigint(chr(0)), "020100"; + + # integers (tests base256 conversion) + der_test der_int( 0), "020100"; + der_test der_int( 127), "02017f"; + der_test der_int( 128), "02020080"; + der_test der_int( 256), "02020100"; + der_test der_int( -1), "0201ff"; + der_test der_int( -128), "020180"; + der_test der_int( -129), "0202ff7f"; + der_test der_int(-65536), "0203ff0000"; + der_test der_int(-65537), "0203feffff"; + + # object encoding, "RSA Security" + der_test der_base128(840), "8648"; + der_test der_objectid(1, 2, 840, 113549), "06062a864886f70d"; + + # Combinations + der_test der_bitstring("ABCD"), "03050041424344"; + der_test der_bitstring(der_null), "0303000500"; + der_test der_seq(der_int(0), der_null), "30050201000500"; + + # The big picture + der_test der_seq(der_seq(der_objectid(1, 2, 840, 113549), der_null), + der_bitstring(der_seq(der_pos_bigint(chr(5)), + der_pos_bigint(chr(3))))), + "3017300a06062a864886f70d05000309003006020105020103"; +} + +#################################################### +# OpenSSL missing functionality workarounds + +## Format of an RSA public key: +# 0:d=0 hl=3 l= 159 cons: SEQUENCE +# 3:d=1 hl=2 l= 13 cons: SEQUENCE +# 5:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption +# 16:d=2 hl=2 l= 0 prim: NULL +# 18:d=1 hl=3 l= 141 prim: BIT STRING +# [ sequence: INTEGER (n), INTEGER (e) ] + +# generate RSA pub key in PEM format +# $1: filename where PEM key is to be stored +# $2: n of the RSA key in hex +# $3: e of the RSA key in hex +# return: nothing, but file created +sub gen_pubrsakey($$$) { + my $filename=shift; + my $n = shift; + my $e = shift; + + # make sure the DER encoder works ;-) + der_unit_test(); + + # generate DER encoding of the public key + + my $rsaEncryption = der_objectid(1, 2, 840, 113549, 1, 1, 1); + + my $der = der_seq(der_seq($rsaEncryption, der_null), + der_bitstring(der_seq(der_pos_bigint(hex2bin($n)), + der_pos_bigint(hex2bin($e))))); + + open(FH, ">", $filename) or die; + print FH pem_cert($der); + close FH; + +} + +# generate RSA pub key in PEM format +# +# This implementation uses "openssl asn1parse -genconf" which was added +# in openssl 0.9.8. It is not available in older openssl versions. +# +# $1: filename where PEM key is to be stored +# $2: n of the RSA key in hex +# $3: e of the RSA key in hex +# return: nothing, but file created +sub gen_pubrsakey_using_openssl($$$) { + my $filename=shift; + my $n = shift; + my $e = shift; + + my $asn1 = "asn1=SEQUENCE:pubkeyinfo + +[pubkeyinfo] +algorithm=SEQUENCE:rsa_alg +pubkey=BITWRAP,SEQUENCE:rsapubkey + +[rsa_alg] +algorithm=OID:rsaEncryption +parameter=NULL + +[rsapubkey] +n=INTEGER:0x$n + +e=INTEGER:0x$e"; + + open(FH, ">$filename.cnf") or die "Cannot create file $filename.cnf: $?"; + print FH $asn1; + close FH; + my @args = ("openssl", "asn1parse", "-genconf", "$filename.cnf", "-noout", "-out", "$filename.der"); + system(@args) == 0 or die "system @args failed: $?"; + @args = ("openssl", "rsa", "-inform", "DER", "-in", "$filename.der", + "-outform", "PEM", "-pubin", "-pubout", "-out", "$filename"); + system(@args) == 0 or die "system @args failed: $?"; + die "RSA PEM formatted key file $filename was not created" + if (! -f $filename); + + unlink("$filename.cnf"); + unlink("$filename.der"); +} + +############################################ +# Test cases + +# This is the Known Answer Test +# $1: the string that we have to put in front of the key +# when printing the key +# $2: crypto key1 in hex form +# $3: crypto key2 in hex form (TDES, undef otherwise) +# $4: crypto key3 in hex form (TDES, undef otherwise) +# $5: IV in hex form +# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form +# $7: cipher +# $8: encrypt=1/decrypt=0 +# return: string formatted as expected by CAVS +sub kat($$$$$$$$) { + my $keytype = shift; + my $key1 = shift; + my $key2 = shift; + my $key3 = shift; + my $iv = shift; + my $pt = shift; + my $cipher = shift; + my $enc = shift; + + my $out = ""; + + # this is the concardination of the keys for 3DES + # as used in OpenSSL + if (defined($key2)) { + $out .= "$keytype = $key1\n"; + $out .= "KEY2 = $key2\n"; + $key1 = $key1 . $key2; + } else { + $out .= "$keytype = $key1\n"; + } + if (defined($key3)) { + $out .= "KEY3 = $key3\n"; + $key1= $key1 . $key3; + } + + $out .= "IV = $iv\n"; + if ($enc) { + $out .= "PLAINTEXT = $pt\n"; + $out .= "CIPHERTEXT = " . encrypt($key1, $iv, $cipher, $pt) . "\n"; + } else { + $out .= "CIPHERTEXT = $pt\n"; + $out .= "PLAINTEXT = " . decrypt($key1, $iv, $cipher, $pt) . "\n"; + } + + return $out; +} + +# This is the Known Answer Test for Hashes +# $1: Plaintext in hex form +# $2: hash +# $3: hash length (undef if not applicable) +# return: string formatted as expected by CAVS +sub hash_kat($$$) { + my $pt = shift; + my $cipher = shift; + my $len = shift; + + my $out = ""; + $out .= "Len = $len\n" if (defined($len)); + $out .= "Msg = $pt\n"; + $out .= "MD = " . &$hash($pt, $cipher); + return $out; +} + +# Cipher Monte Carlo Testing +# $1: the string that we have to put in front of the key +# when printing the key +# $2: crypto key1 in hex form +# $3: crypto key2 in hex form (TDES, undef otherwise) +# $4: crypto key3 in hex form (TDES, undef otherwise) +# $5: IV in hex form +# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form +# $7: cipher +# $8: encrypt=1/decrypt=0 +# return: string formatted as expected by CAVS +sub crypto_mct($$$$$$$$) { + my $keytype = shift; + my $key1 = hex2bin(shift); + my $key2 = shift; + my $key3 = shift; + my $iv = hex2bin(shift); + my $source_data = hex2bin(shift); + my $cipher = shift; + my $enc = shift; + + my $out = ""; + + $key2 = hex2bin($key2) if (defined($key2)); + $key3 = hex2bin($key3) if (defined($key3)); + my $bufsize = length($source_data); + + # for AES: outer loop 0-99, inner 0-999 based on FIPS compliance tests + # for RC4: outer loop 0-99, inner 0-999 based on atsec compliance tests + # for DES: outer loop 0-399, inner 0-9999 based on FIPS compliance tests + my $ciph = substr($cipher,0,3); + my $oloop=100; + my $iloop=1000; + if ($ciph =~ /des/) {$oloop=400;$iloop=10000;} + + for (my $i=0; $i<$oloop; ++$i) { + $out .= "COUNT = $i\n"; + if (defined($key2)) { + $out .= "$keytype = ". bin2hex($key1). "\n"; + $out .= "KEY2 = ". bin2hex($key2). "\n"; + $key1 = $key1 . $key2; + } else { + $out .= "$keytype = ". bin2hex($key1). "\n"; + } + if(defined($key3)) { + $out .= "KEY3 = ". bin2hex($key3). "\n"; + $key1 = $key1 . $key3; + } + my $keylen = length($key1); + + $out .= "IV = ". bin2hex($iv). "\n"; + + if ($enc) { + $out .= "PLAINTEXT = ". bin2hex($source_data). "\n"; + } else { + $out .= "CIPHERTEXT = ". bin2hex($source_data). "\n"; + } + my ($CO, $CI); + my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); + my $pid = open2($CO, $CI, $cipher_imp); + + my $calc_data = $iv; # CT[j] + my $old_calc_data; # CT[j-1] + my $old_old_calc_data; # CT[j-2] + for (my $j = 0; $j < $iloop; ++$j) { + $old_old_calc_data = $old_calc_data; + $old_calc_data = $calc_data; + + # $calc_data = AES($key, $calc_data); + #print STDERR "source_data=", bin2hex($source_data), "\n"; + syswrite $CI, $source_data or die; + my $len = sysread $CO, $calc_data, $bufsize; + #print STDERR "len=$len, bufsize=$bufsize\n"; + die if $len ne $bufsize; + #print STDERR "calc_data=", bin2hex($calc_data), "\n"; + + if ( (!$enc && $ciph =~ /des/) || + $ciph =~ /rc4/ ) { + #TDES in decryption mode and RC4 have a special rule + $source_data = $calc_data; + } else { + $source_data = $old_calc_data; + } + } + close $CO; + close $CI; + waitpid $pid, 0; + + if ($enc) { + $out .= "CIPHERTEXT = ". bin2hex($calc_data). "\n\n"; + } else { + $out .= "PLAINTEXT = ". bin2hex($calc_data). "\n\n"; + } + + if ( $ciph =~ /aes/ ) { + $key1 ^= substr($old_calc_data . $calc_data, -$keylen); + #print STDERR bin2hex($key1)."\n"; + } elsif ( $ciph =~ /des/ ) { + die "Wrong keylen $keylen" if ($keylen != 24); + + # $nkey needed as $key holds the concatenation of the + # old key atm + my $nkey = fix_key_parity(substr($key1,0,8) ^ $calc_data); + #print STDERR "KEY1 = ". bin2hex($nkey)."\n"; + if (substr($key1,0,8) ne substr($key1,8,8)) { + #print STDERR "KEY2 recalc: KEY1==KEY3, KEY2 indep. or all KEYs are indep.\n"; + $key2 = fix_key_parity((substr($key1,8,8) ^ $old_calc_data)); + } else { + #print STDERR "KEY2 recalc: KEY1==KEY2==KEY3\n"; + $key2 = fix_key_parity((substr($key1,8,8) ^ $calc_data)); + } + #print STDERR "KEY2 = ". bin2hex($key2)."\n"; + if ( substr($key1,0,8) eq substr($key1,16)) { + #print STDERR "KEY3 recalc: KEY1==KEY2==KEY3 or KEY1==KEY3, KEY2 indep.\n"; + $key3 = fix_key_parity((substr($key1,16) ^ $calc_data)); + } else { + #print STDERR "KEY3 recalc: all KEYs are independent\n"; + $key3 = fix_key_parity((substr($key1,16) ^ $old_old_calc_data)); + } + #print STDERR "KEY3 = ". bin2hex($key3)."\n"; + + # reset the first key - concardination happens at + # beginning of loop + $key1=$nkey; + } elsif ($ciph =~ /rc4/ ) { + $key1 ^= substr($calc_data, 0, 16); + #print STDERR bin2hex($key1)."\n"; + } else { + die "Test limitation: cipher '$cipher' not supported in Monte Carlo testing"; + } + + if (! $enc && $ciph =~ /des/ ) { + #TDES in decryption mode has a special rule + $iv = $old_calc_data; + $source_data = $calc_data; + } elsif ( $ciph =~ /rc4/ ) { + #No resetting of IV as the IV is all zero set initially (i.e. no IV) + $source_data = $calc_data; + } else { + $iv = $calc_data; + $source_data = $old_calc_data; + } + } + + return $out; +} + +# Hash Monte Carlo Testing +# $1: Plaintext in hex form +# $2: hash +# return: string formatted as expected by CAVS +sub hash_mct($$) { + my $pt = shift; + my $cipher = shift; + + my $out = ""; + + $out .= "Seed = $pt\n\n"; + + for (my $j=0; $j<100; ++$j) { + $out .= "COUNT = $j\n"; + my $md0=$pt; + my $md1=$pt; + my $md2=$pt; + for (my $i=0; $i<1000; ++$i) { + my $mi= $md0 . $md1 . $md2; + $md0=$md1; + $md1=$md2; + $md2 = &$hash($mi, $cipher); + $md2 =~ s/\n//; + } + $out .= "MD = $md2\n\n"; + $pt=$md2; + } + + return $out; +} + +# RSA SigGen test +# $1: Message to be signed in hex form +# $2: Hash algorithm +# $3: file name with RSA key in PEM form +# return: string formatted as expected by CAVS +sub rsa_siggen($$$) { + my $data = shift; + my $cipher = shift; + my $keyfile = shift; + + my $out = ""; + + $out .= "SHAAlg = $cipher\n"; + $out .= "Msg = $data\n"; + $out .= "S = " . &$rsa_sign($data, $cipher, $keyfile) . "\n"; + + return $out; +} + +# RSA SigVer test +# $1: Message to be verified in hex form +# $2: Hash algoritm +# $3: Signature of message in hex form +# $4: n of the RSA key in hex in hex form +# $5: e of the RSA key in hex in hex form +# return: string formatted as expected by CAVS +sub rsa_sigver($$$$$) { + my $data = shift; + my $cipher = shift; + my $signature = shift; + my $n = shift; + my $e = shift; + + my $out = ""; + + $out .= "SHAAlg = $cipher\n"; + $out .= "e = $e\n"; + $out .= "Msg = $data\n"; + $out .= "S = $signature\n"; + + # XXX maybe a secure temp file name is better here + # but since it is not run on a security sensitive + # system, I hope that this is fine + my $keyfile = "rsa_sigver.tmp.$$"; + gen_pubrsakey($keyfile, $n, $e); + + my $sigfile = "$keyfile.sig"; + open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?"; + print FH hex2bin($signature); + close FH; + + $out .= "Result = " . (&$rsa_verify($data, $cipher, $keyfile, $sigfile) ? "P\n" : "F\n"); + + unlink($keyfile); + unlink($sigfile); + + return $out; +} + +# X9.31 RNG test +# $1 key for the AES cipher +# $2 DT value +# $3 V value +# $4 type ("VST", "MCT") +# return: string formatted as expected by CAVS +sub rngx931($$$$) { + my $key=shift; + my $dt=shift; + my $v=shift; + my $type=shift; + + my $out = "Key = $key\n"; + $out .= "DT = $dt\n"; + $out .= "V = $v\n"; + + my $count = 1; + $count = 10000 if ($type eq "MCT"); + + my $rnd_val = ""; + + # we read 16 bytes from RNG + my $bufsize = 16; + + my ($CO, $CI); + my $rng_imp = &$state_rng($key, $dt, $v); + my $pid = open2($CO, $CI, $rng_imp); + for (my $i = 0; $i < $count; ++$i) { + my $len = sysread $CO, $rnd_val, $bufsize; + #print STDERR "len=$len, bufsize=$bufsize\n"; + die "len=$len != bufsize=$bufsize" if $len ne $bufsize; + #print STDERR "calc_data=", bin2hex($rnd_val), "\n"; + } + close $CO; + close $CI; + waitpid $pid, 0; + + $out .= "R = " . bin2hex($rnd_val) . "\n\n"; + + return $out; +} + +############################################################## +# Parser of input file and generator of result file +# + +sub usage() { + + print STDERR "Usage: +$0 [-R] + +-R execution of ARCFOUR instead of OpenSSL"; + +} + +# Parser of CAVS test vector file +# $1: Test vector file +# $2: Output file for test results +# return: nothing +sub parse($$) { + my $infile = shift; + my $outfile = shift; + + my $out = ""; + + # Do I need to generate the key? + my $rsa_keygen = 0; + + # this is my cipher/hash type + my $cipher = ""; + + # Test type + # 1 - cipher known answer test + # 2 - cipher Monte Carlo test + # 3 - hash known answer test + # 4 - hash Monte Carlo test + # 5 - RSA signature generation + # 6 - RSA signature verification + my $tt = 0; + + # Variables for tests + my $keytype = ""; # we can have "KEY", "KEYs", "KEY1" + my $key1 = ""; + my $key2 = undef; #undef needed for allowing + my $key3 = undef; #the use of them as input variables + my $pt = ""; + my $enc = 1; + my $iv = ""; + my $len = undef; #see key2|3 + my $n = ""; + my $e = ""; + my $signature = ""; + my $rsa_keyfile = ""; + my $dt = ""; + my $v = ""; + + my $mode = ""; + + open(IN, "<$infile"); + while() { + + my $line = $_; + chomp($line); + $line =~ s/\r//; + + my $keylen = ""; + + # Mode and type check + # consider the following parsed line + # '# AESVS MCT test data for CBC' + # '# TDES Multi block Message Test for CBC' + # '# INVERSE PERMUTATION - KAT for CBC' + # '# SUBSTITUTION TABLE - KAT for CBC' + # '# TDES Monte Carlo (Modes) Test for CBC' + # '# "SHA-1 Monte" information for "IBMRHEL5"' + # '# "SigVer PKCS#1 Ver 1.5" information for "IBMRHEL5"' + # '# "SigGen PKCS#1 Ver 1.5" information for "IBMRHEL5"' + # '#RC4VS MCT test data' + + # avoid false positives from user specified 'for "PRODUCT"' strings + my $tmpline = $line; + $tmpline =~ s/ for ".*"//; + + ##### Extract cipher + # XXX there may be more - to be added + if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-1|SigGen|SigVer|RC4VS|ANSI X9\.31)/) { + if ($tmpline =~ /CBC/) { $mode="cbc"; } + elsif ($tmpline =~ /ECB/) { $mode="ecb"; } + elsif ($tmpline =~ /OFB/) { $mode="ofb"; } + elsif ($tmpline =~ /CFB/) { $mode="cfb"; } + #we do not need mode as the cipher is already clear + elsif ($tmpline =~ /SHA-1/) { $cipher="sha1"; } + #we do not need mode as the cipher is already clear + elsif ($tmpline =~ /RC4VS/) { $cipher="rc4"; } + elsif ($tmpline =~ /SigGen|SigVer/) { + die "Error: X9.31 is not supported" + if ($tmpline =~ /X9/); + $cipher="sha1"; #place holder - might be overwritten later + } + + # RSA Key Generation test + if ($tmpline =~ /SigGen/) { + $rsa_keygen = 1; + } + if ($tmpline =~ /^#.*AESVS/) { + # AES cipher (part of it) + $cipher="aes"; + } + if ($tmpline =~ /^#.*(TDES|KAT)/) { + # TDES cipher (full definition) + # the FIPS-140 test generator tool does not produce + # machine readable output! + if ($mode eq "cbc") { $cipher="des-ede3-cbc"; } + if ($mode eq "ecb") { $cipher="des-ede3"; } + if ($mode eq "ofb") { $cipher="des-ede3-ofb"; } + if ($mode eq "cfb") { $cipher="des-ede3-cfb"; } + } + + # check for RNG + if ($tmpline =~ /ANSI X9\.31/) { + # change the tmpline to add the type of the + # test which is ONLY visible from the file + # name :-( + if ($infile =~ /MCT\.req/) { + $tmpline .= " MCT"; + } elsif ($infile =~ /VST\.req/) { + $tmpline .= " VST"; + } else { + die "Unexpected cipher type with $infile"; + } + } + + + ##### Identify the test type + if ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /MCT/) { + $tt = 8; + die "Interface function state_rng for RNG MCT not defined for tested library" + if (!defined($state_rng)); + } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /VST/) { + $tt = 7; + die "Interface function state_rng for RNG KAT not defined for tested library" + if (!defined($state_rng)); + } elsif ($tmpline =~ /SigVer/ ) { + $tt = 6; + die "Interface function rsa_verify or gen_rsakey for RSA verification not defined for tested library" + if (!defined($rsa_verify) || !defined($gen_rsakey)); + } elsif ($tmpline =~ /SigGen/ ) { + $tt = 5; + die "Interface function rsa_sign or gen_rsakey for RSA sign not defined for tested library" + if (!defined($rsa_sign) || !defined($gen_rsakey)); + } elsif ($tmpline =~ /Monte|MCT|Carlo/ && $cipher eq "sha1") { + $tt = 4; + die "Interface function hash for Hashing not defined for tested library" + if (!defined($hash)); + } elsif ($tmpline =~ /Monte|MCT|Carlo/) { + $tt = 2; + die "Interface function state_cipher for Stateful Cipher operation defined for tested library" + if (!defined($state_cipher)); + } elsif ($cipher eq "sha1" && $tt!=5 && $tt!=6) { + $tt = 3; + die "Interface function hash for Hashing not defined for tested library" + if (!defined($hash)); + } else { + $tt = 1; + die "Interface function encdec for Encryption/Decryption not defined for tested library" + if (!defined($encdec)); + } + } + + # This is needed as ARCFOUR does not operate with an IV + $iv = "00000000000000000000000000000000" if ($cipher eq "rc4" + && $iv eq "" ); + + # we are now looking for the string + # '# Key Length : 256' + # found in AES + if ($tmpline =~ /^# Key Length.*?(128|192|256)/) { + if ($cipher eq "aes") { + $cipher="$cipher-$1-$mode"; + } else { + die "Error: Key length $1 given for cipher $cipher which is unexpected"; + } + } + + # Get the test data + if ($line =~ /^(KEY|KEYs|KEY1|Key)\s*=\s*(.*)/) { # found in ciphers and RNG + die "KEY seen twice - input file crap" if ($key1 ne ""); + $keytype=$1; + $key1=$2; + $key1 =~ s/\s//g; #replace potential white spaces + } + elsif ($line =~ /^KEY2\s*=\s*(.*)/) { # found in TDES + die "First key not set, but got already second key - input file crap" if ($key1 eq ""); + die "KEY2 seen twice - input file crap" if (defined($key2)); + $key2=$1; + $key2 =~ s/\s//g; #replace potential white spaces + } + elsif ($line =~ /^KEY3\s*=\s*(.*)/) { # found in TDES + die "Second key not set, but got already third key - input file crap" if ($key2 eq ""); + die "KEY2 seen twice - input file crap" if (defined($key3)); + $key3=$1; + $key3 =~ s/\s//g; #replace potential white spaces + } + elsif ($line =~ /^IV\s*=\s*(.*)/) { # found in ciphers + die "IV seen twice - input file crap" if ($iv ne ""); + $iv=$1; + $iv =~ s/\s//g; #replace potential white spaces + } + elsif ($line =~ /^PLAINTEXT\s*=\s*(.*)/) { # found in ciphers + if ( $1 !~ /\?/ ) { #only use it if there is valid hex data + die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne ""); + $pt=$1; + $pt =~ s/\s//g; #replace potential white spaces + $enc=1; + } + } + elsif ($line =~ /^CIPHERTEXT\s*=\s*(.*)/) { # found in ciphers + if ( $1 !~ /\?/ ) { #only use it if there is valid hex data + die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne ""); + $pt=$1; + $pt =~ s/\s//g; #replace potential white spaces + $enc=0; + } + } + elsif ($line =~ /^Len\s*=\s*(.*)/) { # found in hashs + $len=$1; + } + elsif ($line =~ /^(Msg|Seed)\s*=\s*(.*)/) { # found in hashs From cvs at cvs.gnupg.org Thu Sep 18 14:14:09 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 18 Sep 2008 14:14:09 +0200 Subject: [svn] gcry - r1339 - in trunk: . doc src tests Message-ID: Author: wk Date: 2008-09-18 14:14:09 +0200 (Thu, 18 Sep 2008) New Revision: 1339 Modified: trunk/NEWS trunk/TODO trunk/doc/ChangeLog trunk/doc/gcrypt.texi trunk/src/ChangeLog trunk/src/fips.c trunk/src/g10lib.h trunk/src/global.c trunk/src/secmem.c trunk/tests/ChangeLog trunk/tests/basic.c trunk/tests/cavs_driver.pl Log: Implemented an Enforced FIPS mode. Documentation updates. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/doc/ChangeLog 2008-09-18 12:14:09 UTC (rev 1339) @@ -1,3 +1,8 @@ +2008-09-18 Werner Koch + + * gcrypt.texi: Add a couple of index items. + (FIPS Mode): Reflect recent changes. + 2008-09-16 Werner Koch * gcrypt.texi (FIPS Mode): Describe new transitions 18 and 19. @@ -407,7 +412,7 @@ * FAQ: Ditto. * DETAILS: Ditto. - Copyright 1999, 2000, 2002, 2003 Free Software Foundation, Inc. + Copyright 1999, 2000, 2002, 2003, 2008 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 Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/src/ChangeLog 2008-09-18 12:14:09 UTC (rev 1339) @@ -1,3 +1,26 @@ +2008-09-18 Werner Koch + + * secmem.c (_gcry_secmem_init): Factor most code out to .. + (secmem_init): .. new. + (DEFAULT_POOL_SIZE): Rename to MINIMUM_POOL_SIZE. + (STANDARD_POOL_SIZE): New. + (_gcry_secmem_malloc_internal): Don't abort if the pool is not + initialized but try to out intialize it first and only then print + an error message and return NULL. If the pool is not locked while + in FIPS mode, return NULL. + + * fips.c (FIPS_FORCE_FILE): New constant. Change the file name to + "/etc/gcrypt/fips_enabled". + (enforced_fips_mode): New. + (_gcry_initialize_fips_mode): Set that flag. + (_gcry_enforced_fips_mode): New. + * global.c (inactive_fips_mode): New. + (_gcry_vcontrol): Take that flag in account for GCRYCTL_FIPS_MODE_P. + (gcry_set_allocation_handler): Take care of the enforced fips mdoe + flag. + (get_no_secure_memory): New. + (do_malloc, gcry_is_secure): Use it. + 2008-09-16 Werner Koch * global.c (print_config): Use y/n for fips mode. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/tests/ChangeLog 2008-09-18 12:14:09 UTC (rev 1339) @@ -1,3 +1,7 @@ +2008-09-18 Werner Koch + + * basic.c (main): Do not disable secure memory in FIPS mode. + 2008-09-16 Werner Koch * fipsrngdrv.c (main): Bail out on write error. Implement verbose Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/NEWS 2008-09-18 12:14:09 UTC (rev 1339) @@ -8,8 +8,13 @@ cases. Folks, please read the manual to learn how to properly initialize Libgcrypt! - * Log fatal error via syslog. + * Log fatal errors via syslog. + * Auto-initialize the secure memory to 32k instead of aborting the + process. + + * Changed the name and the semantics of the fips mode config file. + * More self-tests. * Documentation cleanups. Modified: trunk/TODO =================================================================== --- trunk/TODO 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/TODO 2008-09-18 12:14:09 UTC (rev 1339) @@ -22,32 +22,6 @@ 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 -** Init requirements for random - The documentation says in "Controlling the library" that some - functions can only be used at initialization time, but it does not - explain what that means. Initialization is a multi-step procedure: - First the thread callbacks have to be set up (optional), then the - gcry_check_version() function must be called (mandatory), then - further functions can be used. - - The manual also says that something happens when the seed file is - registered berfore the PRNG is initialized, but it does not say how - one can guarantee to call it early enough. - - Suggested fix: Specify initialization time as the time after - gcry_check_version and before calling any other function except - gcry_control(). - - All functions which modify global state without a lock must be - documented as "can only be called during initialization time" (but - see item 1). Then the extraneous calls to _gcry_random_initialize - in gcry_control() can be removed, and the comments "not thread - safe" in various initialization-time-only functions like - _gcry_use_random_daemon become superfluous. - * Use builtin bit functions of gcc 3.4 * Consider using a daemon to maintain the random pool Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/doc/gcrypt.texi 2008-09-18 12:14:09 UTC (rev 1339) @@ -519,6 +519,7 @@ @node Enabling FIPS mode @section How to enable the FIPS mode + at cindex FIPS mode Libgcrypt may be used in a FIPS 140-2 mode. Note, that this does not necessary mean that Libcgrypt is an appoved FIPS 140-2 module. Check the @@ -538,7 +539,7 @@ @code{proc} file system (i.e. GNU/Linux). @item -If the file @file{/etc/gcrypt/fips140.force} exists, Libgcrypt is put +If the file @file{/etc/gcrypt/fips_enabled} exists, Libgcrypt is put into FIPS mode at initialization time. Note that this filename is hardwired and does not depend on any configuration options. @@ -549,6 +550,14 @@ @end itemize + at cindex Enforced FIPS mode + +In addition to the standard FIPS mode, Libgcrypt may also be put into +an Enforced FIPS mode by writing a non-zero value into the file + at file{/etc/gcrypt/fips_enabled}. The Enforced FIPS mode helps to +detect applications which don't fulfill all requirements for using +Libgcrypt in FIPS mode (@pxref{FIPS Mode}). + Once Libgcrypt has been put into FIPS mode, it is not possible to switch back to standard mode without terminating the process first. If the logging verbosity level of Libgcrypt has been set to at least @@ -616,13 +625,14 @@ after initialization. @item GCRYCTL_DISABLE_SECMEM; Arguments: none -This command disables the use of secure memory. +This command disables the use of secure memory. If this command is +used in FIPS mode, FIPS mode will be disabled and the command + at code{GCRYCTL_FIPS_MODE_P} returns false. However, in Enforced FIPS +mode this command has no effect at all. Many applications do not require secure memory, so they should disable -it right away. There won't be a problem if not disabling it unless one -makes use of a feature which requires secure memory - in that case the -process will abort because the secmem is not initialized. This command -should be executed right after @code{gcry_check_version}. +it right away. This command should be executed right after + at code{gcry_check_version}. @item GCRYCTL_INIT_SECMEM; Arguments: int nbytes This command is used to allocate a pool of secure memory and thus @@ -766,7 +776,8 @@ This command returns true if the library is in FIPS mode. Note, that this is no indication about the current state of the library. This command may be used before the intialization has been finished but not -before a gcry_version_check. +before a gcry_version_check. An application may use this function to +check whether FIPS mode is still active. @item GCRYCTL_FORCE_FIPS_MODE; Arguments: none Running this command puts the library into FIPS mode. If the library is @@ -1360,18 +1371,25 @@ The value always evaluates to false. @item GCRY_CIPHER_IDEA + at cindex 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 + at cindex 3DES + at cindex Triple-DES + at cindex DES-EDE + at cindex Digital Encryption Standard 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 + at cindex CAST5 CAST128-5 block cipher algorithm. The key size is 128 bits. @item GCRY_CIPHER_BLOWFISH + at cindex Blowfish The blowfish algorithm. The current implementation allows only for a key size of 128 bits. @@ -1385,6 +1403,9 @@ @itemx GCRY_CIPHER_AES128 @itemx GCRY_CIPHER_RIJNDAEL @itemx GCRY_CIPHER_RIJNDAEL128 + at cindex Rijndael + at cindex AES + at cindex Advanced Encryption Standard AES (Rijndael) with a 128 bit key. @item GCRY_CIPHER_AES192 @@ -1396,17 +1417,21 @@ AES (Rijndael) with a 256 bit key. @item GCRY_CIPHER_TWOFISH + at cindex 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 + at cindex Arcfour + at cindex RC4 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. - at item GCRY_CIPHER_DES + at item GCRY_CIPHER_DES + at cindex 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. @@ -1414,20 +1439,25 @@ @item GCRY_CIPHER_SERPENT128 @itemx GCRY_CIPHER_SERPENT192 @itemx GCRY_CIPHER_SERPENT256 + at cindex Serpent The Serpent cipher from the AES contest. @item GCRY_CIPHER_RFC2268_40 @itemx GCRY_CIPHER_RFC2268_128 + at cindex rfc-2268 + at cindex RC2 Ron's Cipher 2 in the 40 and 128 bit variants. Note, that we currently only support the 40 bit variant. The identifier for 128 is reserved for future use. @item GCRY_CIPHER_SEED + at cindex Seed (cipher) A 128 bit cipher as described by RFC4269. @item GCRY_CIPHER_CAMELLIA128 @itemx GCRY_CIPHER_CAMELLIA192 @itemx GCRY_CIPHER_CAMELLIA256 + at cindex Camellia The Camellia cipher by NTT. See @uref{http://info.isl.ntt.co.jp/@/crypt/@/eng/@/camellia/@/specifications.html}. @@ -1555,22 +1585,27 @@ set, this mode may be used to bypass the actual encryption. @item GCRY_CIPHER_MODE_ECB + at cindex ECB, Electronic Codebook mode Electronic Codebook mode. @item GCRY_CIPHER_MODE_CFB + at cindex CFB, Cipher Feedback mode Cipher Feedback mode. The shift size equals the block size of the cipher (e.g. for AES it is CFB-128). @item GCRY_CIPHER_MODE_CBC + at cindex CBC, Cipher Block Chaining mode Cipher Block Chaining mode. @item GCRY_CIPHER_MODE_STREAM Stream mode, only to be used with stream cipher algorithms. @item GCRY_CIPHER_MODE_OFB + at cindex OFB, Output Feedback mode Output Feedback mode. @item GCRY_CIPHER_MODE_CTR + at cindex CTR, Counter mode Counter mode. @end table @@ -1613,15 +1648,18 @@ 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 + at cindex sync mode (OpenPGP) This flag enables the CFB sync mode, which is a special feature of Libgcrypt's CFB mode implementation to allow for OpenPGP's CFB variant. See @code{gcry_cipher_sync}. @item GCRY_CIPHER_CBC_CTS + at cindex cipher text stealing 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 + at cindex 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. @@ -3250,6 +3288,14 @@ @section Available hash algorithms @c begin table of hash algorithms + at cindex SHA-1 + at cindex SHA-224, SHA-256, SHA-384, SHA-512 + at cindex RIPE-MD-160 + at cindex MD2, MD4, MD5 + at cindex TIGER + at cindex HAVAL + at cindex Whirlpool + at cindex CRC32 @table @code @item GCRY_MD_NONE This is not a real algorithm but used by some functions as an error @@ -3441,6 +3487,7 @@ this is the hashed data is highly confidential. @item GCRY_MD_FLAG_HMAC + at cindex HMAC Turn the algorithm into a HMAC message authentication algorithm. This only works if just one algorithm is enabled for the handle. Note that the function @code{gcry_md_setkey} must be used to set the MAC key. @@ -5409,17 +5456,21 @@ Switching into FIPS mode on other systems will fail at runtime. @item -Saving and loading a random seed file is not ignored. +Saving and loading a random seed file is ignored. @item An X9.31 style random number generator is used in place of the large-pool-CSPRNG generator. @item +The command @code{GCRYCTL_ENABLE_QUICK_RANDOM} is ignored. + + at item The Alternative Public Key Interface (@code{gcry_ac_xxx}) is not supported and all API calls return an error. - at item Registration of external modules is not supported. + at item +Registration of external modules is not supported. @item Message digest debugging is disabled. @@ -5428,22 +5479,30 @@ All debug output related to cryptographic data is suppressed. @item -On-the-fly self-tests are not performed, instead of this self-tests are -run before entering operational state. +On-the-fly self-tests are not performed, instead self-tests are run +before entering operational state. @item -The function @code{gcry_set_allocation_handler} may not be used. If it -is used Libgcrypt will enter the error state. +The function @code{gcry_set_allocation_handler} may not be used. If +it is used Libgcrypt disables FIPS mode unless Enforced FIPS mode is +enabled, in which case Libgcrypt will enter the error state. + at item +In Enforced FIPS mode the command @code{GCRYCTL_DISABLE_SECMEM} is +ignored. In standard FIPS mode it disables FIPS mode. + @item A handler set by @code{gcry_set_outofcore_handler} is ignored. @item A handler set by @code{gcry_set_fatalerror_handler} is ignored. - @end itemize +Note that when we speak about disabling FIPS mode, it merely means +that the command @code{GCRYCTL_FIPS_MODE_P} returns false; it does not +mean that any non FIPS algorithms are allowed. + @c ******************************************** @section FIPS Finite State Machine Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/src/fips.c 2008-09-18 12:14:09 UTC (rev 1339) @@ -35,6 +35,11 @@ #include "cipher-proto.h" #include "hmac256.h" + +/* The name of the file used to foce libgcrypt into fips mode. */ +#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled" + + /* The states of the finite state machine used in fips mode. */ enum module_states { @@ -55,6 +60,9 @@ fips_mode()! */ static int no_fips_mode_required; +/* Flag to indicate that we are in the enforced FIPS mode. */ +static int enforced_fips_mode; + /* This is the lock we use to protect the FSM. */ static ath_mutex_t fsm_lock = ATH_MUTEX_INITIALIZER; @@ -103,7 +111,7 @@ } done = 1; - /* If the calling applicatione explicitly requested fipsmode, do so. */ + /* If the calling application explicitly requested fipsmode, do so. */ if (force) { gcry_assert (!no_fips_mode_required); @@ -114,11 +122,8 @@ provided detection of the FIPS mode and force FIPS mode using a file. The filename is hardwired so that there won't be any confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is - actually used. The file itself may be empty. A comment may be - included in the file, but comment lines need to be prefixed with - a hash mark; only such comment lines and empty lines are - allowed. */ - if ( !access ("/etc/gcrypt/fips140.force", F_OK) ) + actually used. The file itself may be empty. */ + if ( !access (FIPS_FORCE_FILE, F_OK) ) { gcry_assert (!no_fips_mode_required); goto leave; @@ -167,6 +172,7 @@ if (!no_fips_mode_required) { /* Yes, we are in FIPS mode. */ + FILE *fp; /* Intitialize the lock to protect the FSM. */ err = ath_mutex_init (&fsm_lock); @@ -184,7 +190,20 @@ #endif /*HAVE_SYSLOG*/ abort (); } + + /* If the FIPS force files exists, is readable and has a number + != 0 on its first line, we enable the enforced fips mode. */ + fp = fopen (FIPS_FORCE_FILE, "r"); + if (fp) + { + char line[256]; + + if (fgets (line, sizeof line, fp) && atoi (line)) + enforced_fips_mode = 1; + fclose (fp); + } + /* Now get us into the INIT state. */ fips_new_state (STATE_INIT); @@ -245,6 +264,14 @@ } +/* Return a flag telling whether we are in the enforced fips mode. */ +int +_gcry_enforced_fips_mode (void) +{ + return enforced_fips_mode; +} + + static const char * state2str (enum module_states state) { Modified: trunk/src/g10lib.h =================================================================== --- trunk/src/g10lib.h 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/src/g10lib.h 2008-09-18 12:14:09 UTC (rev 1339) @@ -293,6 +293,8 @@ int _gcry_fips_mode (void); #define fips_mode() _gcry_fips_mode () +int _gcry_enforced_fips_mode (void); + void _gcry_fips_signal_error (const char *srcfile, int srcline, const char *srcfunc, Modified: trunk/src/global.c =================================================================== --- trunk/src/global.c 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/src/global.c 2008-09-18 12:14:09 UTC (rev 1339) @@ -50,6 +50,10 @@ intialization code swicthed fips mode on. */ static int force_fips_mode; +/* If this flag is set, the application may no longer assume that the + process is running in FIPS mode. */ +static int inactive_fips_mode; + /* Controlled by global_init(). */ static int any_init_done; @@ -297,7 +301,9 @@ /* We use y/n instead of 1/0 for the simple reason that Emacsen's compile error parser would accidently flag that line when printed during "make check" as an error. */ - fnc (fp, "fips-mode:%c:\n", fips_mode ()? 'y':'n' ); + fnc (fp, "fips-mode:%c:%c:\n", + fips_mode ()? 'y':'n'; + _gcry_enforced_fips_mode ()? 'y':'n' ); } @@ -489,7 +495,7 @@ break; case GCRYCTL_FIPS_MODE_P: - if (fips_mode ()) + if (fips_mode () && !inactive_fips_mode && !no_secure_memory) err = GPG_ERR_GENERAL; /* Used as TRUE value */ break; @@ -636,7 +642,10 @@ return gcry_error (gpg_err_code_from_errno (err)); } -/**************** + +/* Set custom allocation handlers. This is in general not useful + * because the libgcrypt allocation functions are guaranteed to + * provide proper allocation handlers which zeroize memory if needed. * NOTE: All 5 functions should be set. */ void gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func, @@ -647,10 +656,22 @@ { global_init (); - if (fips_mode () ) + if (fips_mode ()) { - fips_signal_error ("custom allocation handler used"); - return; + if (_gcry_enforced_fips_mode () ) + { + /* Get us into the error state. */ + fips_signal_error ("custom allocation handler used"); + return; + } + /* We do not want to enforce the fips mode, but merely set a + flag so that the application may check wheter it is still in + fips mode. */ + inactive_fips_mode = 1; +#ifdef HAVE_SYSLOG + syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: " + "custom allocation handler used - FIPS mode disabled"); +#endif /*HAVE_SYSLOG*/ } alloc_func = new_alloc_func; @@ -692,13 +713,28 @@ outofcore_handler_value = value; } +/* Return the no_secure_memory flag. */ +static int +get_no_secure_memory (void) +{ + if (!no_secure_memory) + return 0; + if (_gcry_enforced_fips_mode ()) + { + no_secure_memory = 0; + return 0; + } + return no_secure_memory; +} + + static gcry_err_code_t do_malloc (size_t n, unsigned int flags, void **mem) { gcry_err_code_t err = 0; void *m; - if ((flags & GCRY_ALLOC_FLAG_SECURE) && !no_secure_memory) + if ((flags & GCRY_ALLOC_FLAG_SECURE) && !get_no_secure_memory ()) { if (alloc_secure_func) m = (*alloc_secure_func) (n); @@ -750,7 +786,7 @@ int gcry_is_secure (const void *a) { - if (no_secure_memory) + if (get_no_secure_memory ()) return 0; if (is_secure_func) return is_secure_func (a) ; Modified: trunk/src/secmem.c =================================================================== --- trunk/src/secmem.c 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/src/secmem.c 2008-09-18 12:14:09 UTC (rev 1339) @@ -44,7 +44,8 @@ #define MAP_ANONYMOUS MAP_ANON #endif -#define DEFAULT_POOL_SIZE 16384 +#define MINIMUM_POOL_SIZE 16384 +#define STANDARD_POOL_SIZE 32768 #define DEFAULT_PAGE_SIZE 4096 typedef struct memblock @@ -442,15 +443,12 @@ return flags; } -/* Initialize the secure memory system. If running with the necessary - privileges, the secure memory pool will be locked into the core in - order to prevent page-outs of the data. Furthermore allocated - secure memory will be wiped out when released. */ -void -_gcry_secmem_init (size_t n) + +/* See _gcry_secmem_init. This function is expected to be called with + the secmem lock held. */ +static void +secmem_init (size_t n) { - SECMEM_LOCK; - if (!n) { #ifdef USE_CAPABILITIES @@ -471,8 +469,8 @@ } else { - if (n < DEFAULT_POOL_SIZE) - n = DEFAULT_POOL_SIZE; + if (n < MINIMUM_POOL_SIZE) + n = MINIMUM_POOL_SIZE; if (! pool_okay) { init_pool (n); @@ -481,7 +479,21 @@ else log_error ("Oops, secure memory pool already initialized\n"); } +} + + +/* Initialize the secure memory system. If running with the necessary + privileges, the secure memory pool will be locked into the core in + order to prevent page-outs of the data. Furthermore allocated + secure memory will be wiped out when released. */ +void +_gcry_secmem_init (size_t n) +{ + SECMEM_LOCK; + + secmem_init (n); + SECMEM_UNLOCK; } @@ -493,9 +505,20 @@ if (!pool_okay) { - log_bug (_ - ("operation is not possible without initialized secure memory\n")); + /* Try to initialize the pool if the user forgot about it. */ + secmem_init (STANDARD_POOL_SIZE); + if (!pool_okay) + { + log_info (_("operation is not possible without " + "initialized secure memory\n")); + return NULL; + } } + if (not_locked && fips_mode ()) + { + log_info (_("secure memory pool is not locked while in FIPS mode\n")); + return NULL; + } if (show_warning && !suspend_warning) { show_warning = 0; Modified: trunk/tests/basic.c =================================================================== --- trunk/tests/basic.c 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/tests/basic.c 2008-09-18 12:14:09 UTC (rev 1339) @@ -2089,19 +2089,21 @@ if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); + if ( gcry_control (GCRYCTL_FIPS_MODE_P, 0) ) + in_fips_mode = 1; + + if (!in_fips_mode) + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (verbose) gcry_set_progress_handler (progress_handler, NULL); - - gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); /* No valuable keys are create, so we can speed up our RNG. */ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); - if ( gcry_control (GCRYCTL_FIPS_MODE_P, 0) ) - in_fips_mode = 1; - if (!selftest_only) { check_ciphers (); Modified: trunk/tests/cavs_driver.pl =================================================================== --- trunk/tests/cavs_driver.pl 2008-09-16 19:22:10 UTC (rev 1338) +++ trunk/tests/cavs_driver.pl 2008-09-18 12:14:09 UTC (rev 1339) @@ -1,5 +1,7 @@ #!/usr/bin/env perl # +# $Id: cavs_driver.pl 1236 2008-09-17 13:00:06Z smueller $ +# # CAVS test driver (based on the OpenSSL driver) # Written by: Stephan M?ller # Copyright (c) atsec information security corporation @@ -51,12 +53,12 @@ # but have not been tested) # # AES -# CBCGFSbox[128|192|256] -# CBCMCT[128|192|256] -# CBCVarKey[128|192|256] -# CBCKeySbox[128|192|256] -# CBCMMT[128|192|256] -# CBCVarTxt[128|192|256] +# [CBC|CFB128|ECB|OFB]GFSbox[128|192|256] +# [CBC|CFB128|ECB|OFB]MCT[128|192|256] +# [CBC|CFB128|ECB|OFB]VarKey[128|192|256] +# [CBC|CFB128|ECB|OFB]KeySbox[128|192|256] +# [CBC|CFB128|ECB|OFB]MMT[128|192|256] +# [CBC|CFB128|ECB|OFB]VarTxt[128|192|256] # # RSA # SigGen[15|RSA] @@ -65,18 +67,23 @@ # is not done through openssl dgst) # # SHA -# SHA1ShortMsg -# SHA1LongMsg -# SHA1Monte +# SHA[1|224|256|384|512]ShortMsg +# SHA[1|224|256|384|512]LongMsg +# SHA[1|224|256|384|512]Monte # +# HMAC (SHA - caveat: we only support hash output equal to the block size of +# of the hash - we do not support truncation of the hash; to support +# that, we first need to decipher the HMAC.req file - see hmac_kat() ) +# HMAC +# # TDES -# TCBCMonte[1|2|3] -# TCBCpermop -# TCBCMMT[1|2|3] -# TCBCsubtab -# TCBCvarkey -# TCBCinvperm -# TCBCvartext +# T[CBC|CFB??|ECB|OFB]Monte[1|2|3] +# T[CBC|CFB??|ECB|OFB]permop +# T[CBC|CFB??|ECB|OFB]MMT[1|2|3] +# T[CBC|CFB??|ECB|OFB]subtab +# T[CBC|CFB??|ECB|OFB]varkey +# T[CBC|CFB??|ECB|OFB]invperm +# T[CBC|CFB??|ECB|OFB]vartext # # ANSI X9.31 RNG # ANSI931_AES128MCT @@ -110,9 +117,15 @@ # function to the given variables. # common encryption/decryption routine -# $1 key in hex form +# $1 key in hex form (please note for 3DES: even when ede3 for three +# independent ciphers is given with the cipher specification, we hand in +# either one key for k1 = k2 = k3, two keys which are concatinated for +# k1 = k3, k2 independent, or three keys which are concatinated for +# k1, k2, k3 independent) # $2 iv in hex form -# $3 cipher +# $3 cipher - the cipher string is defined as specified in the openssl +# enc(1ssl) specification for the option "-ciphername" +# (e.g. aes-128-cbc or des-ede3-cbc) # $4 encrypt=1/decrypt=0 # $5 de/encrypted data in hex form # return en/decrypted data in hex form @@ -133,15 +146,18 @@ # return: 1 == verfied / 0 == not verified my $rsa_verify; -# generate a new private RSA key in PEM format +# generate a new private RSA key with the following properties: +# exponent is 65537 +# PEM format # $1 key size in bit # $2 keyfile name # return: nothing, but file created my $gen_rsakey; # Creating a hash -# $1: Plaintext -# $2: hash type +# $1: Plaintext in hex form +# $2: hash type in the form documented in openssl's dgst(1ssl) - e.g. +# sha1, sha224, sha256, sha384, sha512 # return: hash in hex form my $hash; @@ -172,6 +188,14 @@ # between the reads. The output of the RNG on STDOUT is assumed to be binary. my $state_rng; +# Generate an HMAC based on SHAx +# $1: Key to be used for the HMAC in hex format +# $2: length of the hash to be calculated in bits +# $3: Message for which the HMAC shall be calculated in hex format +# $4: hash type (1 - SHA1, 224 - SHA224, and so on) +# return: calculated HMAC in hex format +my $hmac; + ################################################################ ##### OpenSSL interface functions ################################################################ @@ -266,6 +290,16 @@ return "fipsrngdrv --binary --loop $key $v $dt"; } +sub libgcrypt_hmac($$$$) { + my $key = shift; + my $maclen = shift; + my $msg = shift; + my $hashtype = shift; + + die "libgcrypt HMAC test not yet implemented: key $key, maclen $maclen, msg $msg, hashtype $hashtype"; + +} + ######### End of libgcrypt implementation ################ ##### No other interface functions below this point ###### @@ -757,14 +791,12 @@ my $out = ""; + $out .= "$keytype = $key1\n"; + # this is the concardination of the keys for 3DES - # as used in OpenSSL if (defined($key2)) { - $out .= "$keytype = $key1\n"; $out .= "KEY2 = $key2\n"; $key1 = $key1 . $key2; - } else { - $out .= "$keytype = $key1\n"; } if (defined($key3)) { $out .= "KEY3 = $key3\n"; @@ -800,6 +832,46 @@ return $out; } +# Known Answer Test for HMAC hash +# $1: key length in bytes +# $2: MAC length in bytes +# $3: key for HMAC in hex form +# $4: message to be hashed +# return: string formatted as expected by CAVS +sub hmac_kat($$$$) { + my $klen = shift; + my $tlen = shift; + my $key = shift; + my $msg = shift; + + # XXX this is a hack - we need to decipher the HMAC REQ files in a more + # sane way + # + # This is a conversion table from the expected hash output size + # to the assumed hash type - we only define here the block size of + # the underlying hashes and do not allow any truncation + my %hashtype = ( + 20 => 1, + 28 => 224, + 32 => 256, + 48 => 384, + 64 => 512 + ); + + die "Hash output size $tlen is not supported!" + if(!defined($hashtype{$tlen})); + + my $out = ""; + $out .= "Klen = $klen\n"; + $out .= "Tlen = $tlen\n"; + $out .= "Key = $key\n"; + $out .= "Msg = $msg\n"; + $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n\n"; + + return $out; +} + + # Cipher Monte Carlo Testing # $1: the string that we have to put in front of the key # when printing the key @@ -1132,6 +1204,8 @@ my $rsa_keyfile = ""; my $dt = ""; my $v = ""; + my $klen = ""; + my $tlen = ""; my $mode = ""; @@ -1162,13 +1236,17 @@ ##### Extract cipher # XXX there may be more - to be added - if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-1|SigGen|SigVer|RC4VS|ANSI X9\.31)/) { + if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested)/) { if ($tmpline =~ /CBC/) { $mode="cbc"; } elsif ($tmpline =~ /ECB/) { $mode="ecb"; } elsif ($tmpline =~ /OFB/) { $mode="ofb"; } elsif ($tmpline =~ /CFB/) { $mode="cfb"; } #we do not need mode as the cipher is already clear elsif ($tmpline =~ /SHA-1/) { $cipher="sha1"; } + elsif ($tmpline =~ /SHA-224/) { $cipher="sha224"; } + elsif ($tmpline =~ /SHA-256/) { $cipher="sha256"; } + elsif ($tmpline =~ /SHA-384/) { $cipher="sha384"; } + elsif ($tmpline =~ /SHA-512/) { $cipher="sha512"; } #we do not need mode as the cipher is already clear elsif ($tmpline =~ /RC4VS/) { $cipher="rc4"; } elsif ($tmpline =~ /SigGen|SigVer/) { @@ -1211,7 +1289,11 @@ ##### Identify the test type - if ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /MCT/) { + if ($tmpline =~ /Hash sizes tested/) { + $tt = 9; + die "Interface function hmac for HMAC testing not defined for tested library" + if (!defined($hmac)); + } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /MCT/) { $tt = 8; die "Interface function state_rng for RNG MCT not defined for tested library" if (!defined($state_rng)); @@ -1227,7 +1309,7 @@ $tt = 5; die "Interface function rsa_sign or gen_rsakey for RSA sign not defined for tested library" if (!defined($rsa_sign) || !defined($gen_rsakey)); - } elsif ($tmpline =~ /Monte|MCT|Carlo/ && $cipher eq "sha1") { + } elsif ($tmpline =~ /Monte|MCT|Carlo/ && $cipher eq "sha") { $tt = 4; die "Interface function hash for Hashing not defined for tested library" if (!defined($hash)); @@ -1235,7 +1317,7 @@ $tt = 2; die "Interface function state_cipher for Stateful Cipher operation defined for tested library" if (!defined($state_cipher)); - } elsif ($cipher eq "sha1" && $tt!=5 && $tt!=6) { + } elsif ($cipher eq "sha" && $tt!=5 && $tt!=6) { $tt = 3; die "Interface function hash for Hashing not defined for tested library" if (!defined($hash)); @@ -1276,7 +1358,7 @@ } elsif ($line =~ /^KEY3\s*=\s*(.*)/) { # found in TDES die "Second key not set, but got already third key - input file crap" if ($key2 eq ""); - die "KEY2 seen twice - input file crap" if (defined($key3)); + die "KEY3 seen twice - input file crap" if (defined($key3)); $key3=$1; $key3 =~ s/\s//g; #replace potential white spaces } @@ -1348,6 +1430,16 @@ if ($v ne ""); $v=$1; } + elsif ($line =~ /^Klen\s*=\s*(.*)/) { # HMAC requests + die "Klen seen twice - check input file" + if ($klen ne ""); + $klen=$1; + } + elsif ($line =~ /^Tlen\s*=\s*(.*)/) { # HMAC RNG requests + die "Tlen seen twice - check input file" + if ($tlen ne ""); + $tlen=$1; + } else { $out .= $line . "\n"; } @@ -1417,6 +1509,15 @@ $v = ""; } } + elsif ($tt == 9) { + if ($klen ne "" && $tlen ne "" && $key1 ne "" && $pt ne "") { + $out .= hmac_kat($klen, $tlen, $key1, $pt); + $key1 = ""; + $tlen = ""; + $klen = ""; + $pt = ""; + } + } elsif ($tt > 0) { die "Test case $tt not defined"; } @@ -1452,15 +1553,16 @@ ##### Set library #print STDERR "Using OpenSSL interface functions\n"; - #$encdec=\&openssl_encdec; - #$rsa_sign=\&openssl_rsa_sign; - #$rsa_verify=\&openssl_rsa_verify; - #$gen_rsakey=\&openssl_gen_rsakey; - #$hash=\&openssl_hash; - #$state_cipher=\&openssl_state_cipher; + #$encdec = \&openssl_encdec; + #$rsa_sign = \&openssl_rsa_sign; + #$rsa_verify = \&openssl_rsa_verify; + #$gen_rsakey = \&openssl_gen_rsakey; + #$hash = \&openssl_hash; + #$state_cipher = \&openssl_state_cipher; print STDERR "Using libgcrypt interface functions\n"; - $state_rng=\&libgcrypt_state_rng; + $state_rng = \&libgcrypt_state_rng; + $hmac = \&libgcrypt_hmac; my $infile=$ARGV[0]; die "Error: Test vector file $infile not found" if (! -f $infile); From cvs at cvs.gnupg.org Thu Sep 18 14:35:07 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 18 Sep 2008 14:35:07 +0200 Subject: [svn] gcry - r1340 - trunk/src Message-ID: Author: wk Date: 2008-09-18 14:35:06 +0200 (Thu, 18 Sep 2008) New Revision: 1340 Modified: trunk/src/global.c Log: Syntax fix. Modified: trunk/src/global.c =================================================================== --- trunk/src/global.c 2008-09-18 12:14:09 UTC (rev 1339) +++ trunk/src/global.c 2008-09-18 12:35:06 UTC (rev 1340) @@ -302,7 +302,7 @@ compile error parser would accidently flag that line when printed during "make check" as an error. */ fnc (fp, "fips-mode:%c:%c:\n", - fips_mode ()? 'y':'n'; + fips_mode ()? 'y':'n', _gcry_enforced_fips_mode ()? 'y':'n' ); } From cvs at cvs.gnupg.org Thu Sep 18 17:25:50 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 18 Sep 2008 17:25:50 +0200 Subject: [svn] gcry - r1341 - in trunk: . doc src tests Message-ID: Author: wk Date: 2008-09-18 17:25:49 +0200 (Thu, 18 Sep 2008) New Revision: 1341 Modified: trunk/ChangeLog trunk/NEWS trunk/README trunk/TODO trunk/configure.ac trunk/doc/ChangeLog trunk/doc/announce.txt trunk/doc/gcrypt.texi trunk/src/ChangeLog trunk/src/gcrypt.h.in trunk/tests/basic.c Log: Preparing a release Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/ChangeLog 2008-09-18 15:25:49 UTC (rev 1341) @@ -1,3 +1,9 @@ +2008-09-18 Werner Koch + + Release 1.4.3. + + * configure.ac: Bump LT version to C16/A5/R1. + 2008-09-15 Werner Koch * configure.ac: Cehck for syslog. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/doc/ChangeLog 2008-09-18 15:25:49 UTC (rev 1341) @@ -2,6 +2,7 @@ * gcrypt.texi: Add a couple of index items. (FIPS Mode): Reflect recent changes. + (Controlling the library): Describe gcry_fips_mode_active. 2008-09-16 Werner Koch Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/src/ChangeLog 2008-09-18 15:25:49 UTC (rev 1341) @@ -1,5 +1,7 @@ 2008-09-18 Werner Koch + * gcrypt.h.in (gcry_fips_mode_active): New. + * secmem.c (_gcry_secmem_init): Factor most code out to .. (secmem_init): .. new. (DEFAULT_POOL_SIZE): Rename to MINIMUM_POOL_SIZE. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/NEWS 2008-09-18 15:25:49 UTC (rev 1341) @@ -1,4 +1,4 @@ -Noteworthy changes in version 1.4.3 +Noteworthy changes in version 1.4.3 (2008-09-18) ------------------------------------------------ * Try to auto-initialize Libgcrypt to minimize the effect of @@ -8,13 +8,15 @@ cases. Folks, please read the manual to learn how to properly initialize Libgcrypt! - * Log fatal errors via syslog. - * Auto-initialize the secure memory to 32k instead of aborting the process. + * Log fatal errors via syslog. + * Changed the name and the semantics of the fips mode config file. + * Add convenience macro gcry_fips_mode_active. + * More self-tests. * Documentation cleanups. Modified: trunk/README =================================================================== --- trunk/README 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/README 2008-09-18 15:25:49 UTC (rev 1341) @@ -1,6 +1,6 @@ Libgcrypt - The GNU Crypto Library ------------------------------------ - Version 1.4.2 + Version 1.4.4 Copyright 2000, 2002, 2003, 2004, 2007, Modified: trunk/TODO =================================================================== --- trunk/TODO 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/TODO 2008-09-18 15:25:49 UTC (rev 1341) @@ -36,11 +36,6 @@ collectros need to run that bunch of Unix utilities we don't waste their precious results. -* Out of memory handler for secure memory should do proper logging - - There is no shortage of standard memory, so logging is most likely - possible. - * mpi_print does not use secure memory for internal variables. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/configure.ac 2008-09-18 15:25:49 UTC (rev 1341) @@ -27,7 +27,7 @@ # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. m4_define([my_version], [1.4.3]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) @@ -40,7 +40,7 @@ # (No interfaces changed: REVISION++) LIBGCRYPT_LT_CURRENT=16 LIBGCRYPT_LT_AGE=5 -LIBGCRYPT_LT_REVISION=0 +LIBGCRYPT_LT_REVISION=1 # If the API is changed in an incompatible way: increment the next counter. Modified: trunk/doc/announce.txt =================================================================== --- trunk/doc/announce.txt 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/doc/announce.txt 2008-09-18 15:25:49 UTC (rev 1341) @@ -5,68 +5,56 @@ Hello! The GNU project is pleased to announce the availability of Libgcrypt -version 1.4.2. +version 1.4.3. Libgcrypt is a general purpose library of cryptographic building blocks. It is originally based on code used by GnuPG. It does not provide any implementation of OpenPGP or other protocols. Thorough understanding of applied cryptography is required to use Libgcrypt. -Noteworthy changes in version 1.4.2: +Noteworthy changes in version 1.4.3: - * The long missing gcry_mpi_lshift function has been added. + * Try to auto-initialize Libgcrypt to minimize the effect of + applications not doing that correctly. This is not a perfect + solution but given that many applicationion would totally fail + without such a hack, we try to help at least with the most common + cases. Folks, please read the manual to learn how to properly + initialize Libgcrypt! - * RSA key generation now supports a "transient-key" flag. + * Auto-initialize the secure memory to 32k instead of aborting the + process. - * The keygrip computation for ECDSA has been implemented thus ECDSA - is now fully supported. + * Log fatal errors via syslog. - * A few macros have been replaced by functions for better type - checking. + * Changed the name and the semantics of the fips mode config file. - * The thread initialization structure now carries version - information. + * Add convenience macro gcry_fips_mode_active. - * The manual describes more clearly how to initialize Libgcrypt. + * More self-tests. - * The library may now be switched into a FIPS mode. + * Documentation cleanups. - * Interface changes relative to the 1.3.0 release: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - GCRYCTL_OPERATIONAL_P NEW. - GCRYCTL_FIPS_MODE_P NEW. - GCRYCTL_FORCE_FIPS_MODE NEW. - gcry_cipher_setkey NEW: Replaces macro. - gcry_cipher_setiv NEW: Replaces macro. - gcry_cipher_setctr NEW: Replaces macro. - gcry_mpi_lshift NEW. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Source code is hosted at the GnuPG FTP server and its mirrors as listed at http://www.gnupg.org/download/mirrors.html . On the primary server the source file and its digital signatures is: - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.2.tar.bz2 (1049k) - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.2.tar.bz2.sig + ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.3.tar.bz2 (k) + ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.3.tar.bz2.sig This file is bzip2 compressed. A gzip compressed version is also available: - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.1.tar.gz (1301k) - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.1.tar.gz.sig + ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.3.tar.gz (k) + ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.3.tar.gz.sig -Alternativley you may upgrade version 1.4.1 using this patch file: +Alternativley you may upgrade version 1.4.2 using this patch file: - ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.1-1.4.2.diff.bz2 (171k) + ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.4.2-1.4.3.diff.bz2 (k) The SHA-1 checksums are: -f4eda0d4a63905aef3bcdf24bb3dad787ef4b918 libgcrypt-1.4.2.tar.gz -e9c65688e3191c4cad2910bda2f6c69fc05997a2 libgcrypt-1.4.2.tar.bz2 -e0e5e4192f144ae0fc093d08aff50b725f46c0f9 libgcrypt-1.4.1-1.4.2.diff.bz2 - For help on developing with Libgcrypt you should read the included manual and optional ask on the gcrypt-devel mailing list [1]. Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/doc/gcrypt.texi 2008-09-18 15:25:49 UTC (rev 1341) @@ -626,8 +626,8 @@ @item GCRYCTL_DISABLE_SECMEM; Arguments: none This command disables the use of secure memory. If this command is -used in FIPS mode, FIPS mode will be disabled and the command - at code{GCRYCTL_FIPS_MODE_P} returns false. However, in Enforced FIPS +used in FIPS mode, FIPS mode will be disabled and the fucntion + at code{gcry_fips_mode_active} returns false. However, in Enforced FIPS mode this command has no effect at all. Many applications do not require secure memory, so they should disable @@ -776,9 +776,18 @@ This command returns true if the library is in FIPS mode. Note, that this is no indication about the current state of the library. This command may be used before the intialization has been finished but not -before a gcry_version_check. An application may use this function to -check whether FIPS mode is still active. +before a gcry_version_check. An application may use this command or +the convenience macro below to check whether FIPS mode is actually +active. + at deftypefun int gcry_fips_mode_active (void) + +Returns true if the FIPS mode is active. Note that this is +implemented as a macro. + at end deftypefun + + + @item GCRYCTL_FORCE_FIPS_MODE; Arguments: none Running this command puts the library into FIPS mode. If the library is already in FIPS mode, a self-test is triggered and thus the library will @@ -5499,8 +5508,8 @@ @end itemize Note that when we speak about disabling FIPS mode, it merely means -that the command @code{GCRYCTL_FIPS_MODE_P} returns false; it does not -mean that any non FIPS algorithms are allowed. +that the fucntion @code{gcry_fips_mode_active} returns false; it does +not mean that any non FIPS algorithms are allowed. @c ******************************************** Modified: trunk/src/gcrypt.h.in =================================================================== --- trunk/src/gcrypt.h.in 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/src/gcrypt.h.in 2008-09-18 15:25:49 UTC (rev 1341) @@ -1815,6 +1815,10 @@ /* Return true if A is allocated in "secure" memory. */ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE; +/* Return true if Libgcrypt is in FIPS mode. */ +#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) + + /* Include support for Libgcrypt modules. */ #include Modified: trunk/tests/basic.c =================================================================== --- trunk/tests/basic.c 2008-09-18 12:35:06 UTC (rev 1340) +++ trunk/tests/basic.c 2008-09-18 15:25:49 UTC (rev 1341) @@ -2089,7 +2089,7 @@ if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); - if ( gcry_control (GCRYCTL_FIPS_MODE_P, 0) ) + if ( gcry_fips_mode_active () ) in_fips_mode = 1; if (!in_fips_mode) From cvs at cvs.gnupg.org Thu Sep 18 17:50:42 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 18 Sep 2008 17:50:42 +0200 Subject: [svn] gcry - r1342 - trunk/tests Message-ID: Author: wk Date: 2008-09-18 17:50:42 +0200 (Thu, 18 Sep 2008) New Revision: 1342 Modified: trunk/tests/benchmark.c Log: Windows fix. Modified: trunk/tests/benchmark.c =================================================================== --- trunk/tests/benchmark.c 2008-09-18 15:25:49 UTC (rev 1341) +++ trunk/tests/benchmark.c 2008-09-18 15:50:42 UTC (rev 1342) @@ -321,7 +321,7 @@ t2 += (((unsigned long long)stopped_at.user_time.dwHighDateTime << 32) + stopped_at.user_time.dwLowDateTime); t = (t2 - t1)/10000; - snprintf (buf, sizeof buf, "%5lums", (unsigned long)t ); + snprintf (buf, sizeof buf, "%5.0fms", (double)t ); #else snprintf (buf, sizeof buf, "%5.0fms", (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000); From cvs at cvs.gnupg.org Thu Sep 18 17:56:54 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 18 Sep 2008 17:56:54 +0200 Subject: [svn] gcry - r1343 - tags Message-ID: Author: wk Date: 2008-09-18 17:56:54 +0200 (Thu, 18 Sep 2008) New Revision: 1343 Added: tags/libgcrypt-1.4.3/ Log: Release. From cvs at cvs.gnupg.org Fri Sep 19 16:15:52 2008 From: cvs at cvs.gnupg.org (svn author mo) Date: Fri, 19 Sep 2008 16:15:52 +0200 Subject: [svn] gpgme - r1333 - trunk Message-ID: Author: mo Date: 2008-09-19 16:15:51 +0200 (Fri, 19 Sep 2008) New Revision: 1333 Modified: trunk/ChangeLog trunk/configure.ac Log: 2008-09-19 Moritz * configure.ac: Remove bogus "esac". Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-09-16 15:30:44 UTC (rev 1332) +++ trunk/ChangeLog 2008-09-19 14:15:51 UTC (rev 1333) @@ -1,3 +1,7 @@ +2008-09-19 Moritz + + * configure.ac: Remove bogus "esac". + 2008-09-16 Marcus Brinkmann * configure.ac (_XOPEN_SOURCE) [apple-darwin]: Define it. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-09-16 15:30:44 UTC (rev 1332) +++ trunk/configure.ac 2008-09-19 14:15:51 UTC (rev 1333) @@ -115,7 +115,6 @@ ;; esac -esac AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes") GPG_DEFAULT=no From cvs at cvs.gnupg.org Sat Sep 20 12:00:36 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Sat, 20 Sep 2008 12:00:36 +0200 Subject: [svn] gcry - r1344 - trunk/src Message-ID: Author: wk Date: 2008-09-20 12:00:36 +0200 (Sat, 20 Sep 2008) New Revision: 1344 Modified: trunk/src/hmac256.c Log: fix sigbus Modified: trunk/src/hmac256.c =================================================================== --- trunk/src/hmac256.c 2008-09-18 15:56:54 UTC (rev 1343) +++ trunk/src/hmac256.c 2008-09-20 10:00:36 UTC (rev 1344) @@ -271,10 +271,12 @@ /* Store the digest into hd->buf. */ p = hd->buf; #ifdef WORDS_BIGENDIAN -#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0) +#define X(a) do { *p++ = hd->h##a; *p++ = hd->h##a >> 8; \ + *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0) #else /* little endian */ #define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \ *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0) + #endif X(0); X(1); From cvs at cvs.gnupg.org Tue Sep 23 11:57:46 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 23 Sep 2008 11:57:46 +0200 Subject: [svn] GnuPG - r4827 - in trunk: agent doc g10 scd sm Message-ID: Author: wk Date: 2008-09-23 11:57:45 +0200 (Tue, 23 Sep 2008) New Revision: 4827 Modified: trunk/agent/pksign.c trunk/doc/gpg.texi trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/g10/call-agent.h trunk/g10/card-util.c trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/apdu.h trunk/scd/app-common.h trunk/scd/app-openpgp.c trunk/scd/app.c trunk/scd/atr.c trunk/scd/ccid-driver.c trunk/scd/command.c trunk/scd/iso7816.c trunk/scd/iso7816.h trunk/sm/certdump.c Log: Support the Certifciate DO of the v2 OpenPGP cards. [The diff below has been truncated] Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/g10/ChangeLog 2008-09-23 09:57:45 UTC (rev 4827) @@ -1,3 +1,14 @@ +2008-09-16 Werner Koch + + * card-util.c (fpr_is_ff): New. + (card_status): Do not print general key info for an all-ff fpr. + (change_login, change_private_do): Factor common code out to ... + (get_data_from_file): .. new. + (change_cert): New. + (card_edit): Add command "writecert". + * call-agent.c (writecert_parm_s): New. + (inq_writecert_parms, agent_scd_writecert): New. + 2008-09-04 David Shaw * keyserver.c (keyserver_import_cert): Allow keyserver URLs in Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/scd/ChangeLog 2008-09-23 09:57:45 UTC (rev 4827) @@ -1,3 +1,29 @@ +2008-09-23 Werner Koch + + * app-openpgp.c (do_setattr): Use command chaining for long + values. + * iso7816.c (iso7816_put_data): Add arg EXTENDED_MODE. Change all + callers. + * apdu.c (apdu_send_simple): Add arg EXTENDED_MODE. Change all + callers. + (send_le): Implement command chaining. + * ccid-driver.c (ccid_transceive_apdu_level): Increase allowed + APDU size. + * apdu.h: Add new SW_ codes. + +2008-09-16 Werner Koch + + * command.c (cmd_writecert): New. + (register_commands): Register it. + * app-common.h (app_ctx_s): Add member WRITECERT. + * app.c (app_writecert): New. + * app-openpgp.c (do_writecert): New. + (parse_historical): New. + (show_extcap): New. + (dump_all_do): Print only the length of longs DOs. + * command.c (cmd_writekey, cmd_apdu, cmd_pksign) + (cmd_passwd): Replace open coding by skip_options. + 2008-08-30 Moritz * scdaemon.c (main): Use estream_asprintf instead of asprintf. Modified: trunk/agent/pksign.c =================================================================== --- trunk/agent/pksign.c 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/agent/pksign.c 2008-09-23 09:57:45 UTC (rev 4827) @@ -75,7 +75,7 @@ } -/* Special version of do_encode_md to take care of pckcs#1 padding. +/* Special version of do_encode_md to take care of pkcs#1 padding. For TLS-MD5SHA1 we need to do the padding ourself as Libgrypt does not know about this special scheme. Fixme: We should have a pkcs1-only-padding flag for Libgcrypt. */ Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/doc/gpg.texi 2008-09-23 09:57:45 UTC (rev 4827) @@ -2709,6 +2709,9 @@ @item gpg -sb @code{file} make a detached signature + at item gpg -u 0x12345678 -sb @code{file} +make a detached signature with the key 0x12345678 + @item gpg --list-keys @code{user_ID} show keys Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/g10/call-agent.c 2008-09-23 09:57:45 UTC (rev 4827) @@ -53,6 +53,13 @@ size_t ciphertextlen; }; +struct writecert_parm_s +{ + assuan_context_t ctx; + const unsigned char *certdata; + size_t certdatalen; +}; + struct writekey_parm_s { assuan_context_t ctx; @@ -445,6 +452,56 @@ +/* Handle a CERTDATA inquiry. Note, we only send the data, + assuan_transact takes care of flushing and writing the END + command. */ +static int +inq_writecert_parms (void *opaque, const char *line) +{ + int rc; + struct writecert_parm_s *parm = opaque; + + if (!strncmp (line, "CERTDATA", 8) && (line[8]==' '||!line[8])) + { + rc = assuan_send_data (parm->ctx, parm->certdata, parm->certdatalen); + } + else + rc = default_inq_cb (opaque, line); + + return rc; +} + + +/* Send a WRITECERT command to the SCdaemon. */ +int +agent_scd_writecert (const char *certidstr, + const unsigned char *certdata, size_t certdatalen) +{ + int rc; + char line[ASSUAN_LINELENGTH]; + struct writecert_parm_s parms; + + rc = start_agent (); + if (rc) + return rc; + + memset (&parms, 0, sizeof parms); + + snprintf (line, DIM(line)-1, "SCD WRITECERT %s", certidstr); + line[DIM(line)-1] = 0; + parms.ctx = agent_ctx; + parms.certdata = certdata; + parms.certdatalen = certdatalen; + + rc = assuan_transact (agent_ctx, line, NULL, NULL, + inq_writecert_parms, &parms, NULL, NULL); + + return rc; +} + + + + /* Handle a KEYDATA inquiry. Note, we only send the data, assuan_transact takes care of flushing and writing the end */ static int Modified: trunk/g10/call-agent.h =================================================================== --- trunk/g10/call-agent.h 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/g10/call-agent.h 2008-09-23 09:57:45 UTC (rev 4827) @@ -76,6 +76,10 @@ const unsigned char *value, size_t valuelen, const char *serialno); +/* Send a WRITECERT command to the SCdaemon. */ +int agent_scd_writecert (const char *certidstr, + const unsigned char *certdata, size_t certdatalen); + /* Send a WRITEKEY command to the SCdaemon. */ int agent_scd_writekey (int keyno, const char *serialno, const unsigned char *keydata, size_t keydatalen); Modified: trunk/g10/card-util.c =================================================================== --- trunk/g10/card-util.c 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/g10/card-util.c 2008-09-23 09:57:45 UTC (rev 4827) @@ -288,6 +288,18 @@ } +/* Return true if the SHA1 fingerprint FPR consists only of 0xFF. */ +static int +fpr_is_ff (const char *fpr) +{ + int i; + + for (i=0; i < 20 && fpr[i] == '\xff'; i++) + ; + return (i == 20); +} + + /* Print all available information about the current card. */ void card_status (FILE *fp, char *serialno, size_t serialnobuflen) @@ -467,7 +479,10 @@ thefpr = (info.fpr1valid? info.fpr1 : info.fpr2valid? info.fpr2 : info.fpr3valid? info.fpr3 : NULL); - if ( thefpr && !get_pubkey_byfprint (pk, thefpr, 20)) + /* If the fingerprint is all 0xff, the key has no asssociated + OpenPGP certificate. */ + if ( thefpr && !fpr_is_ff (thefpr) + && !get_pubkey_byfprint (pk, thefpr, 20)) { KBNODE keyblock = NULL; @@ -655,7 +670,59 @@ } +/* Read data from file FNAME up to MAXLEN characters. On error return + -1 and store NULl at R_BUFFER; on success return the number of + bytes read and store the address of a newly allocated buffer at + R_BUFFER. */ static int +get_data_from_file (const char *fname, size_t maxlen, char **r_buffer) +{ + FILE *fp; + char *data; + int n; + + *r_buffer = NULL; + + fp = fopen (fname, "rb"); +#if GNUPG_MAJOR_VERSION == 1 + if (fp && is_secured_file (fileno (fp))) + { + fclose (fp); + fp = NULL; + errno = EPERM; + } +#endif + if (!fp) + { + tty_printf (_("can't open `%s': %s\n"), fname, strerror (errno)); + return -1; + } + + data = xtrymalloc (maxlen? maxlen:1); + if (!data) + { + tty_printf (_("error allocating enough memory: %s\n"), strerror (errno)); + fclose (fp); + return -1; + } + + if (maxlen) + n = fread (data, 1, maxlen, fp); + else + n = 0; + fclose (fp); + if (n < 0) + { + tty_printf (_("error reading `%s': %s\n"), fname, strerror (errno)); + xfree (data); + return -1; + } + *r_buffer = data; + return n; +} + + +static int change_login (const char *args) { char *data; @@ -664,34 +731,11 @@ if (args && *args == '<') /* Read it from a file */ { - FILE *fp; - for (args++; spacep (args); args++) ; - fp = fopen (args, "rb"); -#if GNUPG_MAJOR_VERSION == 1 - if (fp && is_secured_file (fileno (fp))) - { - fclose (fp); - fp = NULL; - errno = EPERM; - } -#endif - if (!fp) - { - tty_printf (_("can't open `%s': %s\n"), args, strerror (errno)); - return -1; - } - - data = xmalloc (254); - n = fread (data, 1, 254, fp); - fclose (fp); + n = get_data_from_file (args, 254, &data); if (n < 0) - { - tty_printf (_("error reading `%s': %s\n"), args, strerror (errno)); - xfree (data); - return -1; - } + return -1; } else { @@ -732,35 +776,11 @@ if (args && (args = strchr (args, '<'))) /* Read it from a file */ { - FILE *fp; - - /* Fixme: Factor this duplicated code out. */ for (args++; spacep (args); args++) ; - fp = fopen (args, "rb"); -#if GNUPG_MAJOR_VERSION == 1 - if (fp && is_secured_file (fileno (fp))) - { - fclose (fp); - fp = NULL; - errno = EPERM; - } -#endif - if (!fp) - { - tty_printf (_("can't open `%s': %s\n"), args, strerror (errno)); - return -1; - } - - data = xmalloc (254); - n = fread (data, 1, 254, fp); - fclose (fp); + n = get_data_from_file (args, 254, &data); if (n < 0) - { - tty_printf (_("error reading `%s': %s\n"), args, strerror (errno)); - xfree (data); - return -1; - } + return -1; } else { @@ -788,7 +808,37 @@ return rc; } + static int +change_cert (const char *args) +{ + char *data; + int n; + int rc; + + if (args && *args == '<') /* Read it from a file */ + { + for (args++; spacep (args); args++) + ; + n = get_data_from_file (args, 16384, &data); + if (n < 0) + return -1; + } + else + { + tty_printf ("usage error: redirectrion to file required\n"); + return -1; + } + + rc = agent_scd_writecert ("OPENPGP.3", data, n); + if (rc) + log_error ("error writing certificate to card: %s\n", gpg_strerror (rc)); + xfree (data); + return rc; +} + + +static int change_lang (void) { char *data, *p; @@ -1294,7 +1344,7 @@ cmdNOP = 0, cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY, cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR, - cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, + cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT, cmdINVCMD }; @@ -1325,8 +1375,9 @@ { "generate", cmdGENERATE, 1, N_("generate new keys")}, { "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")}, { "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")}, - /* Note, that we do not announce this command yet. */ + /* Note, that we do not announce these command yet. */ { "privatedo", cmdPRIVATEDO, 0, NULL }, + { "writecert", cmdWRITECERT, 1, NULL }, { NULL, cmdINVCMD, 0, NULL } }; @@ -1401,6 +1452,7 @@ { int arg_number; const char *arg_string = ""; + const char *arg_rest = ""; char *p; int i; int cmd_admin_only; @@ -1469,6 +1521,11 @@ trim_spaces (p); arg_number = atoi(p); arg_string = p; + arg_rest = p; + while (digitp (arg_rest)) + arg_rest++; + while (spacep (arg_rest)) + arg_rest++; } for (i=0; cmds[i].name; i++ ) @@ -1567,6 +1624,13 @@ change_private_do (arg_string, arg_number); break; + case cmdWRITECERT: + if ( arg_number != 3 ) + tty_printf ("usage: writecert 3 < FILE\n"); + else + change_cert (arg_rest); + break; + case cmdFORCESIG: toggle_forcesig (); break; Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/scd/apdu.c 2008-09-23 09:57:45 UTC (rev 4827) @@ -1,5 +1,5 @@ /* apdu.c - ISO 7816 APDU functions and low level I/O - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2003, 2004, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1182,7 +1182,7 @@ err = SW_HOST_INV_VALUE; } /* We need to read any rest of the response, to keep the - protocol runnng. */ + protocol running. */ while (full_len) { unsigned char dummybuf[128]; @@ -2587,20 +2587,29 @@ if (reader_table[slot].send_apdu_reader) return reader_table[slot].send_apdu_reader (slot, apdu, apdulen, - buffer, buflen, pininfo); + buffer, buflen, + pininfo); else return SW_HOST_NOT_SUPPORTED; } -/* Core APDU trabceiver function. Parameters are described at +/* Core APDU tranceiver function. Parameters are described at apdu_send_le with the exception of PININFO which indicates keypad - related operations if not NULL. */ + related operations if not NULL. If EXTENDED_MODE is not NULL + command chaining or extended length will be used according to these + values: + n < 0 := Use command chaining without the data part limited to -n + in each chunk. If -1 is used a default value is used. + n == 1 := Use extended length for input and output with out a + length limit. + n > 1 := Use extended length with up to N bytes. +*/ static int send_le (int slot, int class, int ins, int p0, int p1, int lc, const char *data, int le, unsigned char **retbuf, size_t *retbuflen, - struct pininfo_s *pininfo) + struct pininfo_s *pininfo, int extended_mode) { #define RESULTLEN 258 unsigned char result[RESULTLEN+10]; /* 10 extra in case of bugs in @@ -2611,16 +2620,37 @@ int sw; long rc; /* We need a long here due to PC/SC. */ int did_exact_length_hack = 0; + int use_chaining = 0; + int lc_chunk; if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; if (DBG_CARD_IO) - log_debug ("send apdu: c=%02X i=%02X p0=%02X p1=%02X lc=%d le=%d\n", - class, ins, p0, p1, lc, le); + log_debug ("send apdu: c=%02X i=%02X p0=%02X p1=%02X lc=%d le=%d em=%d\n", + class, ins, p0, p1, lc, le, extended_mode); if (lc != -1 && (lc > 255 || lc < 0)) - return SW_WRONG_LENGTH; + { + /* Data does not fit into an APDU. What we do now dependes on + the EXTENDED_MODE parameter. */ + if (!extended_mode) + return SW_WRONG_LENGTH; /* No way. to send such an APDU. */ + else if (extended_mode > 0) + return SW_HOST_NOT_SUPPORTED; /* FIXME. */ + else if (extended_mode < 0) + { + /* Send APDU using chaining mode. */ + if (lc > 16384) + return SW_WRONG_LENGTH; /* Sanity check. */ + if ((class&0xf0) != 0) + return SW_HOST_INV_VALUE; /* Upper 4 bits need to be 0. */ + use_chaining = extended_mode == -1? 255 : -extended_mode; + use_chaining &= 0xff; + } + else + return SW_HOST_INV_VALUE; + } if (le != -1 && (le > 256 || le < 0)) return SW_WRONG_LENGTH; if ((!data && lc != -1) || (data && lc == -1)) @@ -2629,43 +2659,61 @@ if ((sw = lock_slot (slot))) return sw; - apdulen = 0; - apdu[apdulen++] = class; - apdu[apdulen++] = ins; - apdu[apdulen++] = p0; - apdu[apdulen++] = p1; - if (lc != -1) + do { - apdu[apdulen++] = lc; - memcpy (apdu+apdulen, data, lc); - apdulen += lc; - /* T=0 does not allow the use of Lc together with Le; thus - disable Le in this case. */ - if (reader_table[slot].is_t0) - le = -1; + apdulen = 0; + apdu[apdulen] = class; + if (use_chaining && lc > 255) + { + apdu[apdulen] |= 0x10; + assert (use_chaining < 256); + lc_chunk = use_chaining; + lc -= use_chaining; + } + else + { + use_chaining = 0; + lc_chunk = lc; + } + apdulen++; + apdu[apdulen++] = ins; + apdu[apdulen++] = p0; + apdu[apdulen++] = p1; + if (lc_chunk != -1) + { + apdu[apdulen++] = lc_chunk; + memcpy (apdu+apdulen, data, lc_chunk); + data += lc_chunk; + apdulen += lc_chunk; + /* T=0 does not allow the use of Lc together with Le; thus + disable Le in this case. */ + if (reader_table[slot].is_t0) + le = -1; + } + if (le != -1) + apdu[apdulen++] = le; /* Truncation is okay because 0 means 256. */ + /* As safeguard don't pass any garbage from the stack to the driver. */ + assert (sizeof (apdu) >= apdulen); + memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); + exact_length_hack: + resultlen = RESULTLEN; + rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo); + if (rc || resultlen < 2) + { + log_error ("apdu_send_simple(%d) failed: %s\n", + slot, apdu_strerror (rc)); + unlock_slot (slot); + return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE; + } + sw = (result[resultlen-2] << 8) | result[resultlen-1]; + if (!did_exact_length_hack && SW_EXACT_LENGTH_P (sw)) + { + apdu[apdulen-1] = (sw & 0x00ff); + did_exact_length_hack = 1; + goto exact_length_hack; + } } - if (le != -1) - apdu[apdulen++] = le; /* Truncation is okay because 0 means 256. */ - assert (sizeof (apdu) >= apdulen); - /* As safeguard don't pass any garbage from the stack to the driver. */ - memset (apdu+apdulen, 0, sizeof (apdu) - apdulen); - exact_length_hack: - resultlen = RESULTLEN; - rc = send_apdu (slot, apdu, apdulen, result, &resultlen, pininfo); - if (rc || resultlen < 2) - { - log_error ("apdu_send_simple(%d) failed: %s\n", - slot, apdu_strerror (rc)); - unlock_slot (slot); - return rc? rc : SW_HOST_INCOMPLETE_CARD_RESPONSE; - } - sw = (result[resultlen-2] << 8) | result[resultlen-1]; - if (!did_exact_length_hack && SW_EXACT_LENGTH_P (sw)) - { - apdu[apdulen-1] = (sw & 0x00ff); - did_exact_length_hack = 1; - goto exact_length_hack; - } + while (use_chaining && sw == SW_SUCCESS); /* Store away the returned data but strip the statusword. */ resultlen -= 2; @@ -2808,7 +2856,7 @@ return send_le (slot, class, ins, p0, p1, lc, data, le, retbuf, retbuflen, - NULL); + NULL, 0); } @@ -2826,7 +2874,7 @@ int lc, const char *data, unsigned char **retbuf, size_t *retbuflen) { return send_le (slot, class, ins, p0, p1, lc, data, 256, - retbuf, retbuflen, NULL); + retbuf, retbuflen, NULL, 0); } /* Send an APDU to the card in SLOT. The APDU is created from all @@ -2836,10 +2884,12 @@ for an invalid SLOT or other non card related error. No data will be returned. */ int -apdu_send_simple (int slot, int class, int ins, int p0, int p1, +apdu_send_simple (int slot, int extended_mode, + int class, int ins, int p0, int p1, int lc, const char *data) { - return send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL, NULL); + return send_le (slot, class, ins, p0, p1, lc, data, -1, NULL, NULL, NULL, + extended_mode); } @@ -2857,13 +2907,13 @@ pininfo.maxlen = pinlen_max; pininfo.padlen = pin_padlen; return send_le (slot, class, ins, p0, p1, lc, data, -1, - NULL, NULL, &pininfo); + NULL, NULL, &pininfo, 0); } /* This is a more generic version of the apdu sending routine. It takes an already formatted APDU in APDUDATA or length APDUDATALEN - and returns the with the APDU including the status word. With + and returns the with an APDU including the status word. With HANDLE_MORE set to true this function will handle the MORE DATA status and return all APDUs concatenated with one status word at the end. The function does not return a regular status word but 0 Modified: trunk/scd/apdu.h =================================================================== --- trunk/scd/apdu.h 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/scd/apdu.h 2008-09-23 09:57:45 UTC (rev 4827) @@ -1,5 +1,5 @@ /* apdu.h - ISO 7816 APDU functions and low level I/O - * Copyright (C) 2003 Free Software Foundation, Inc. + * Copyright (C) 2003, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -29,8 +29,11 @@ SW_MORE_DATA = 0x6100, /* Note: that the low byte must be masked of.*/ SW_EOF_REACHED = 0x6282, + SW_TERM_STATE = 0x6285, /* Selected file is in termination state. */ SW_EEPROM_FAILURE = 0x6581, SW_WRONG_LENGTH = 0x6700, + SW_SM_NOT_SUP = 0x6882, /* Secure Messaging is not supported. */ + SW_CC_NOT_SUP = 0x6884, /* Command Chaining is not supported. */ SW_CHV_WRONG = 0x6982, SW_CHV_BLOCKED = 0x6983, SW_USE_CONDITIONS = 0x6985, @@ -97,7 +100,8 @@ unsigned int *status, unsigned int *changed); int apdu_check_keypad (int slot, int command, int pin_mode, int pinlen_min, int pinlen_max, int pin_padlen); -int apdu_send_simple (int slot, int class, int ins, int p0, int p1, +int apdu_send_simple (int slot, int extended_mode, + int class, int ins, int p0, int p1, int lc, const char *data); int apdu_send_simple_kp (int slot, int class, int ins, int p0, int p1, int lc, const char *data, Modified: trunk/scd/app-common.h =================================================================== --- trunk/scd/app-common.h 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/scd/app-common.h 2008-09-23 09:57:45 UTC (rev 4827) @@ -1,5 +1,5 @@ /* app-common.h - Common declarations for all card applications - * Copyright (C) 2003, 2005 Free Software Foundation, Inc. + * Copyright (C) 2003, 2005, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -94,8 +94,13 @@ void *pincb_arg, const void *indata, size_t indatalen, unsigned char **outdata, size_t *outdatalen); + gpg_error_t (*writecert) (app_t app, ctrl_t ctrl, + const char *certid, + gpg_error_t (*pincb)(void*,const char *,char **), + void *pincb_arg, + const unsigned char *data, size_t datalen); gpg_error_t (*writekey) (app_t app, ctrl_t ctrl, - const char *certid, unsigned int flags, + const char *keyid, unsigned int flags, gpg_error_t (*pincb)(void*,const char *,char **), void *pincb_arg, const unsigned char *pk, size_t pklen); @@ -165,6 +170,11 @@ void *pincb_arg, const void *indata, size_t indatalen, unsigned char **outdata, size_t *outdatalen ); +gpg_error_t app_writecert (app_t app, ctrl_t ctrl, + const char *certidstr, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg, + const unsigned char *keydata, size_t keydatalen); gpg_error_t app_writekey (app_t app, ctrl_t ctrl, const char *keyidstr, unsigned int flags, gpg_error_t (*pincb)(void*, const char *, char **), Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/scd/app-openpgp.c 2008-09-23 09:57:45 UTC (rev 4827) @@ -63,6 +63,7 @@ } data_objects[] = { { 0x005E, 0, 0, 1, 0, 0, 0, "Login Data" }, { 0x5F50, 0, 0, 0, 0, 0, 0, "URL" }, + { 0x5F52, 0, 0, 1, 0, 0, 0, "Historical Bytes" }, { 0x0065, 1, 0, 1, 0, 0, 0, "Cardholder Related Data"}, { 0x005B, 0, 0x65, 0, 0, 0, 0, "Name" }, { 0x5F2D, 0, 0x65, 0, 0, 0, 0, "Language preferences" }, @@ -118,7 +119,16 @@ implicitly available. */ } pk[3]; - /* Keep track of card capabilities. */ + unsigned char status_indicator; /* The card status indicator. */ + + /* Keep track of the ISO card capabilities. */ + struct + { + unsigned int cmd_chaining:1; /* Command chaining is supported. */ + unsigned int ext_lc_le:1; /* Extended Lc and Le are supported. */ + } cardcap; + + /* Keep track of extended card capabilities. */ struct { unsigned int is_v2:1; /* This is a v2.0 compatible card. */ @@ -126,7 +136,12 @@ unsigned int key_import:1; unsigned int change_force_chv:1; unsigned int private_dos:1; + unsigned int sm_supported:1; /* Secure Messaging is supported. */ + unsigned int sm_aes128:1; /* Use AES-128 for SM. */ unsigned int max_certlen_3:16; + unsigned int max_get_challenge:16; /* Maximum size for get_challenge. */ + unsigned int max_cmd_data:16; /* Maximum data size for a command. */ + unsigned int max_rsp_data:16; /* Maximum size of a response. */ } extcap; /* Flags used to control the application. */ @@ -451,7 +466,10 @@ if (data_objects[j].binary) { log_info ("DO `%s': ", data_objects[j].desc); - log_printhex ("", value, valuelen); + if (valuelen > 200) + log_info ("[%u]\n", (unsigned int)valuelen); + else + log_printhex ("", value, valuelen); } else log_info ("DO `%s': `%.*s'\n", @@ -596,8 +614,9 @@ xfree (buffer); - rc = iso7816_put_data (slot, (card_version > 0x0007? 0xC7 : 0xC6) - + keynumber, fpr, 20); + rc = iso7816_put_data (slot, 0, + (card_version > 0x0007? 0xC7 : 0xC6) + + keynumber, fpr, 20); if (rc) log_error (_("failed to store the fingerprint: %s\n"),gpg_strerror (rc)); @@ -610,7 +629,7 @@ buf[2] = timestamp >> 8; buf[3] = timestamp; - rc = iso7816_put_data (slot, 0xCE + keynumber, buf, 4); + rc = iso7816_put_data (slot, 0, 0xCE + keynumber, buf, 4); if (rc) log_error (_("failed to store the creation date: %s\n"), gpg_strerror (rc)); @@ -1278,10 +1297,10 @@ #endif } -/* Read the statdard certificate of an OpenPGP v2 card. It is +/* Read the standard certificate of an OpenPGP v2 card. It is returned in a freshly allocated buffer with that address stored at CERT and the length of the certificate stored at CERTLEN. CERTID - needs to be set to "OpenPGP.3". */ + needs to be set to "OPENPGP.3". */ static gpg_error_t do_readcert (app_t app, const char *certid, unsigned char **cert, size_t *certlen) @@ -1296,10 +1315,10 @@ *certlen = 0; if (strcmp (certid, "OPENPGP.3")) return gpg_error (GPG_ERR_INV_ID); - if (app->app_local->extcap.is_v2) + if (!app->app_local->extcap.is_v2) return gpg_error (GPG_ERR_NOT_FOUND); - relptr = get_one_do (app, 0x00C4, &buffer, &buflen, NULL); + relptr = get_one_do (app, 0x7F21, &buffer, &buflen, NULL); if (!relptr) return gpg_error (GPG_ERR_NOT_FOUND); @@ -1649,15 +1668,18 @@ { "PRIVATE-DO-3", 0x0103, 2 }, { "PRIVATE-DO-4", 0x0104, 3 }, { "CERT-3", 0x7F21, 3, 0, 1 }, + { "SM-KEY-ENC", 0x00D1, 3, 0, 1 }, + { "SM-KEY-MAC", 0x00D2, 3, 0, 1 }, + { "PW-RESET-CODE",0x00D3, 3, 0, 1 }, { NULL, 0 } }; + int exmode; - for (idx=0; table[idx].name && strcmp (table[idx].name, name); idx++) ; if (!table[idx].name) return gpg_error (GPG_ERR_INV_NAME); - if (table[idx].need_v2) + if (table[idx].need_v2 && !app->app_local->extcap.is_v2) return gpg_error (GPG_ERR_NOT_SUPPORTED); /* Not yet supported. */ switch (table[idx].need_chv) @@ -1678,7 +1700,12 @@ will reread the data from the card and thus get synced in case of errors (e.g. data truncated by the card). */ flush_cache_item (app, table[idx].tag); - rc = iso7816_put_data (app->slot, table[idx].tag, value, valuelen); + /* For command chaining we use a value of 254 for this card. */ + if (app->app_local->cardcap.cmd_chaining && valuelen > 254) + exmode = -254; + else + exmode = 0; + rc = iso7816_put_data (app->slot, exmode, table[idx].tag, value, valuelen); if (rc) log_error ("failed to set `%s': %s\n", table[idx].name, gpg_strerror (rc)); @@ -1691,6 +1718,34 @@ } +/* Handle the WRITECERT command for OpenPGP. This rites the standard + certifciate to the card; CERTID needs to be set to "OPENPGP.3". + PINCB and PINCB_ARG are the usual arguments for the pinentry + callback. */ +static gpg_error_t +do_writecert (app_t app, ctrl_t ctrl, + const char *certidstr, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg, + const unsigned char *certdata, size_t certdatalen) +{ +#if GNUPG_MAJOR_VERSION > 1 + if (strcmp (certidstr, "OPENPGP.3")) + return gpg_error (GPG_ERR_INV_ID); + if (!certdata || !certdatalen) + return gpg_error (GPG_ERR_INV_ARG); + if (!app->app_local->extcap.is_v2) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + if (certdatalen > app->app_local->extcap.max_certlen_3) + return gpg_error (GPG_ERR_TOO_LARGE); + return do_setattr (app, "CERT-3", pincb, pincb_arg, certdata, certdatalen); +#else + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +#endif +} + + + /* Handle the PASSWD command. */ static gpg_error_t do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, @@ -2074,7 +2129,7 @@ goto leave; /* Store the key. */ - err = iso7816_put_data (app->slot, + err = iso7816_put_data (app->slot, 0, (app->card_version > 0x0007? 0xE0 : 0xE9) + keyno, template, template_len); if (err) @@ -2711,8 +2766,82 @@ } +/* Show information about card capabilities. */ +static void +show_caps (struct app_local_s *s) +{ + log_info ("Version-2 ......: %s\n", s->extcap.is_v2? "yes":"no"); + log_info ("Get-Challenge ..: %s", s->extcap.get_challenge? "yes":"no"); + if (s->extcap.get_challenge) + log_printf (" (%u bytes max)", s->extcap.max_get_challenge); + log_info ("Key-Import .....: %s\n", s->extcap.key_import? "yes":"no"); + log_info ("Change-Force-PW1: %s\n", s->extcap.change_force_chv? "yes":"no"); + log_info ("Private-DOs ....: %s\n", s->extcap.private_dos? "yes":"no"); + log_info ("SM-Support .....: %s", s->extcap.sm_supported? "yes":"no"); + if (s->extcap.sm_supported) + log_printf (" (%s)", s->extcap.sm_aes128? "AES-128":"3DES"); + log_info ("Max-Cert3-Len ..: %u\n", s->extcap.max_certlen_3); + log_info ("Max-Cmd-Data ...: %u\n", s->extcap.max_cmd_data); + log_info ("Max-Rsp-Data ...: %u\n", s->extcap.max_rsp_data); + log_info ("Cmd-Chaining ...: %s\n", s->cardcap.cmd_chaining?"yes":"no"); + log_info ("Ext-Lc-Le ......: %s\n", s->cardcap.ext_lc_le?"yes":"no"); + log_info ("Status Indicator: %02X\n", s->status_indicator); + log_info ("GnuPG-No-Sync ..: %s\n", s->flags.no_sync? "yes":"no"); + log_info ("GnuPG-Def-PW2 ..: %s\n", s->flags.def_chv2? "yes":"no"); +} + +/* Parse the historical bytes in BUFFER of BUFLEN and store them in + APPLOC. */ +static void +parse_historical (struct app_local_s *apploc, + const unsigned char * buffer, size_t buflen) +{ + /* Example buffer: 00 31 C5 73 C0 01 80 00 90 00 */ + if (buflen < 4) + { + log_error ("warning: historical bytes are too short\n"); + return; /* Too short. */ + } + if (*buffer) + { + log_error ("warning: bad category indicator in historical bytes\n"); + return; + } + + /* Skip category indicator. */ + buffer++; + buflen--; + + /* Get the status indicator. */ + apploc->status_indicator = buffer[buflen-3]; + buflen -= 3; + + /* Parse the compact TLV. */ + while (buflen) + { + unsigned int tag = (*buffer & 0xf0) >> 4; + unsigned int len = (*buffer & 0x0f); + if (len+1 > buflen) + { + log_error ("warning: bad Compact-TLV in historical bytes\n"); + return; /* Error. */ + } + buffer++; + buflen--; + if (tag == 7 && len == 3) + { + /* Card capabilities. */ + apploc->cardcap.cmd_chaining = !!(buffer[2] & 0x80); + apploc->cardcap.ext_lc_le = !!(buffer[2] & 0x40); + } + buffer += len; + buflen -= len; + } +} + + /* Select the OpenPGP application on the card in SLOT. This function must be used before any other OpenPGP application functions. */ gpg_error_t @@ -2771,6 +2900,22 @@ if (app->card_version >= 0x0200) app->app_local->extcap.is_v2 = 1; + + /* Read the historical bytes. */ + relptr = get_one_do (app, 0x5f52, &buffer, &buflen, NULL); + if (relptr) + { + if (opt.verbose) + { + log_info ("Historical Bytes: "); + log_printhex ("", buffer, buflen); + } + parse_historical (app->app_local, buffer, buflen); + xfree (relptr); + } + + + /* Read the force-chv1 flag. */ relptr = get_one_do (app, 0x00C4, &buffer, &buflen, NULL); if (!relptr) { @@ -2781,6 +2926,7 @@ app->force_chv1 = (buflen && *buffer == 0); xfree (relptr); + /* Read the extended capabilities. */ relptr = get_one_do (app, 0x00C0, &buffer, &buflen, NULL); if (!relptr) { @@ -2790,6 +2936,7 @@ } if (buflen) { + app->app_local->extcap.sm_supported = !!(*buffer & 0x80); app->app_local->extcap.get_challenge = !!(*buffer & 0x40); app->app_local->extcap.key_import = !!(*buffer & 0x20); app->app_local->extcap.change_force_chv = !!(*buffer & 0x10); @@ -2798,7 +2945,12 @@ if (buflen >= 10) { /* Available with v2 cards. */ + app->app_local->extcap.sm_aes128 = (buffer[1] == 1); + app->app_local->extcap.max_get_challenge + = (buffer[2] << 8 | buffer[3]); app->app_local->extcap.max_certlen_3 = (buffer[4] << 8 | buffer[5]); + app->app_local->extcap.max_cmd_data = (buffer[6] << 8 | buffer[7]); + app->app_local->extcap.max_rsp_data = (buffer[8] << 8 | buffer[9]); } xfree (relptr); @@ -2809,6 +2961,9 @@ parse_login_data (app); + if (opt.verbose) + show_caps (app->app_local); + if (opt.verbose > 1) dump_all_do (slot); @@ -2818,6 +2973,7 @@ app->fnc.readkey = do_readkey; app->fnc.getattr = do_getattr; app->fnc.setattr = do_setattr; + app->fnc.writecert = do_writecert; app->fnc.writekey = do_writekey; app->fnc.genkey = do_genkey; app->fnc.sign = do_sign; Modified: trunk/scd/app.c =================================================================== --- trunk/scd/app.c 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/scd/app.c 2008-09-23 09:57:45 UTC (rev 4827) @@ -240,8 +240,8 @@ /* If we don't have an app, check whether we have a saved application for that slot. This is useful so that a card does - not get reset even if only one session is using the card - so the - PIN cache and other cached data are preserved. */ + not get reset even if only one session is using the card - this + way the PIN cache and other cached data are preserved. */ if (!app && lock_table[slot].initialized && lock_table[slot].last_app) { app = lock_table[slot].last_app; @@ -734,6 +734,34 @@ } +/* Perform the WRITECERT operation. */ +gpg_error_t +app_writecert (app_t app, ctrl_t ctrl, + const char *certidstr, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg, + const unsigned char *data, size_t datalen) +{ + gpg_error_t err; + + if (!app || !certidstr || !*certidstr || !pincb) + return gpg_error (GPG_ERR_INV_VALUE); + if (!app->initialized) + return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); + if (!app->fnc.writecert) + return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); + err = lock_reader (app->slot); + if (err) + return err; + err = app->fnc.writecert (app, ctrl, certidstr, + pincb, pincb_arg, data, datalen); + unlock_reader (app->slot); + if (opt.verbose) + log_info ("operation writecert result: %s\n", gpg_strerror (err)); + return err; +} + + /* Perform the WRITEKEY operation. */ gpg_error_t app_writekey (app_t app, ctrl_t ctrl, @@ -759,7 +787,6 @@ if (opt.verbose) log_info ("operation writekey result: %s\n", gpg_strerror (err)); return err; - } Modified: trunk/scd/atr.c =================================================================== --- trunk/scd/atr.c 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/scd/atr.c 2008-09-23 09:57:45 UTC (rev 4827) @@ -277,10 +277,121 @@ } +/* Note: This code has not yet been tested! It shall return -1 on + error or the nu,ber of hiostroical bytes and store them at + HISTORICAL. */ +int +atr_get_historical (int slot, unsigned char historical[]) +{ + int result = -1; + unsigned char *atrbuffer = NULL; + unsigned char *atr; + size_t atrlen; + int have_ta, have_tb, have_tc, have_td; + int n_historical; + int idx; + unsigned char chksum; + atr = atrbuffer = apdu_get_atr (slot, &atrlen); + if (!atr || atrlen < 2) + goto leave; + atrlen--; + atr++; + chksum = *atr; + for (idx=1; idx < atrlen-1; idx++) + chksum ^= atr[idx]; + have_ta = !!(*atr & 0x10); + have_tb = !!(*atr & 0x20); + have_tc = !!(*atr & 0x40); + have_td = !!(*atr & 0x80); + n_historical = (*atr & 0x0f); + if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen) + goto leave; /* ATR shorter than indicated by format character. */ + atrlen--; + atr++; + if (have_ta + have_tb + have_tc >= atrlen) + goto leave; + atrlen -= have_ta + have_tb + have_tc; + atr += have_ta + have_tb + have_tc; + if (have_td) + { + have_ta = !!(*atr & 0x10); + have_tb = !!(*atr & 0x20); + have_tc = !!(*atr & 0x40); + have_td = !!(*atr & 0x80); + if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen) + goto leave; /* ATR shorter than indicated by format character. */ + atrlen--; + atr++; + } + else + have_ta = have_tb = have_tc = have_td = 0; + if (have_ta + have_tb + have_tc >= atrlen) + goto leave; + atrlen -= have_ta + have_tb + have_tc; + atr += have_ta + have_tb + have_tc; + + if (have_td) + { + have_ta = !!(*atr & 0x10); + have_tb = !!(*atr & 0x20); + have_tc = !!(*atr & 0x40); + have_td = !!(*atr & 0x80); + if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen) + goto leave; /* ATR shorter than indicated by format character. */ + atrlen--; + atr++; + } + else + have_ta = have_tb = have_tc = have_td = 0; + + for (idx = 3; have_ta || have_tb || have_tc || have_td; idx++) + { + if (have_ta + have_tb + have_tc >= atrlen) + goto leave; + atrlen -= have_ta + have_tb + have_tc; + atr += have_ta + have_tb + have_tc; + + if (have_td) + { + have_ta = !!(*atr & 0x10); + have_tb = !!(*atr & 0x20); + have_tc = !!(*atr & 0x40); + have_td = !!(*atr & 0x80); + if (have_ta + have_tb + have_tc + have_td + n_historical >= atrlen) + goto leave; /* ATR shorter than indicated by format character. */ + atrlen--; + atr++; + } + else + have_ta = have_tb = have_tc = have_td = 0; + } + + if (n_historical >= atrlen) + goto leave; /* ATR shorter than required for historical bytes. */ + + if (n_historical) + { + for (idx=0; n_historical && atrlen; n_historical--, atrlen--, atr++) + historical[idx] = *atr; + } + + if (!atrlen || *atr != chksum) + goto leave; + + /* Don't care about garbage at the end of the ATR. */ + + result = n_historical; + + leave: + xfree (atrbuffer); + + return result; +} + Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/scd/ccid-driver.c 2008-09-23 09:57:45 UTC (rev 4827) @@ -1957,7 +1957,7 @@ size_t *nresp) { int rc; - unsigned char send_buffer[10+259], recv_buffer[10+259]; + unsigned char send_buffer[10+261], recv_buffer[10+261]; const unsigned char *apdu; size_t apdulen; unsigned char *msg; @@ -1971,7 +1971,9 @@ apdulen = apdu_buflen; assert (apdulen); - if (apdulen > 254) + /* The maximum length for a short APDU T=1 block is 261, for an + extra APDU T=1 block is 65544. */ + if (apdulen > 261) return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */ msg[0] = PC_to_RDR_XfrBlock; @@ -2117,6 +2119,7 @@ assert (apdulen); /* Construct an I-Block. */ +#warning fixme: APDULEN may be larger if (apdulen > 254) return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */ Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/scd/command.c 2008-09-23 09:57:45 UTC (rev 4827) @@ -47,7 +47,10 @@ /* Maximum allowed size of key data as used in inquiries. */ #define MAXLEN_KEYDATA 4096 +/* Maximum allowed size of certificate data as used in inquiries. */ +#define MAXLEN_CERTDATA 16384 + #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) @@ -851,15 +854,9 @@ hash_algo = GCRY_MD_SHA1; else return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm"); - /* Skip over options. */ - while ( *line == '-' && line[1] == '-' ) - { - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - } + line = skip_options (line); + if ( IS_LOCKED (ctrl) ) return gpg_error (GPG_ERR_LOCKED); @@ -1036,8 +1033,8 @@ names and values are depend on the currently selected smartcard application. NAME and VALUE must be percent and '+' escaped. - However, the curent implementation assumes that Name is not escaped; - this works as long as noone uses arbitrary escaping. + However, the current implementation assumes that NAME is not + escaped; this works as long as noone uses arbitrary escaping. A PIN will be requested for most NAMEs. See the corresponding setattr function of the actually used application (app-*.c) for @@ -1083,12 +1080,74 @@ +/* WRITECERT + + This command is used to store a certifciate on a smartcard. The + allowed certids depend on the currently selected smartcard + application. The actual certifciate is requested using the inquiry + "CERTDATA" and needs to be provided in its raw (e.g. DER) form. + + In almost all cases a a PIN will be requested. See the related + writecert function of the actually used application (app-*.c) for + details. */ +static int +cmd_writecert (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + int rc; + char *certid; + unsigned char *certdata; + size_t certdatalen; + + if ( IS_LOCKED (ctrl) ) + return gpg_error (GPG_ERR_LOCKED); + + line = skip_options (line); + + if (!*line) + return set_error (GPG_ERR_ASS_PARAMETER, "no certid given"); + certid = line; + while (*line && !spacep (line)) + line++; + *line = 0; + + if ((rc = open_card (ctrl, NULL))) + return rc; + + if (!ctrl->app_ctx) + return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); + + certid = xtrystrdup (certid); + if (!certid) + return out_of_core (); + + /* Now get the actual keydata. */ + rc = assuan_inquire (ctx, "CERTDATA", + &certdata, &certdatalen, MAXLEN_CERTDATA); + if (rc) + { + xfree (certid); + return rc; + } + + /* Write the certificate to the card. */ + rc = app_writecert (ctrl->app_ctx, ctrl, certid, + pin_cb, ctx, certdata, certdatalen); + xfree (certid); + xfree (certdata); + + TEST_CARD_REMOVAL (ctrl, rc); + return rc; +} + + + /* WRITEKEY [--force] This command is used to store a secret key on a a smartcard. The allowed keyids depend on the currently selected smartcard application. The actual keydata is requested using the inquiry - "KETDATA" and need to be provided without any protection. With + "KEYDATA" and need to be provided without any protection. With --force set an existing key under this KEYID will get overwritten. The keydata is expected to be the usual canonical encoded S-expression. @@ -1109,14 +1168,8 @@ if ( IS_LOCKED (ctrl) ) return gpg_error (GPG_ERR_LOCKED); - /* Skip over options. */ - while ( *line == '-' && line[1] == '-' ) - { - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - } + line = skip_options (line); + if (!*line) return set_error (GPG_ERR_ASS_PARAMETER, "no keyid given"); keyid = line; @@ -1294,14 +1347,8 @@ if ( IS_LOCKED (ctrl) ) return gpg_error (GPG_ERR_LOCKED); - /* Skip over options. */ - while (*line == '-' && line[1] == '-') - { - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - } + line = skip_options (line); + if (!*line) return set_error (GPG_ERR_ASS_PARAMETER, "no CHV number given"); chvnostr = line; @@ -1601,14 +1648,7 @@ with_atr = has_option (line, "--atr"); handle_more = has_option (line, "--more"); - /* Skip over options. */ - while ( *line == '-' && line[1] == '-' ) - { - while (*line && !spacep (line)) - line++; - while (spacep (line)) - line++; - } + line = skip_options (line); if ( IS_LOCKED (ctrl) ) return gpg_error (GPG_ERR_LOCKED); @@ -1687,6 +1727,7 @@ { "OUTPUT", NULL }, { "GETATTR", cmd_getattr }, { "SETATTR", cmd_setattr }, + { "WRITECERT", cmd_writecert }, { "WRITEKEY", cmd_writekey }, { "GENKEY", cmd_genkey }, { "RANDOM", cmd_random }, Modified: trunk/scd/iso7816.c =================================================================== --- trunk/scd/iso7816.c 2008-09-05 21:01:17 UTC (rev 4826) +++ trunk/scd/iso7816.c 2008-09-23 09:57:45 UTC (rev 4827) @@ -66,7 +66,10 @@ switch (sw) { case SW_EEPROM_FAILURE: ec = GPG_ERR_HARDWARE; break; + case SW_TERM_STATE: ec = GPG_ERR_CARD; break; case SW_WRONG_LENGTH: ec = GPG_ERR_INV_VALUE; break; + case SW_SM_NOT_SUP: ec = GPG_ERR_NOT_SUPPORTED; break; + case SW_CC_NOT_SUP: ec = GPG_ERR_NOT_SUPPORTED; break; case SW_CHV_WRONG: ec = GPG_ERR_BAD_PIN; break; case SW_CHV_BLOCKED: ec = GPG_ERR_PIN_BLOCKED; break; case SW_USE_CONDITIONS: ec = GPG_ERR_USE_CONDITIONS; break; @@ -130,7 +133,7 @@ unsigned int flags) { int sw; - sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, 4, + sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE, 4, (flags&1)? 0 :0x0c, aidlen, aid); return map_sw (sw); } @@ -156,7 +159,7 @@ { p0 = (tag == 0x3F00)? 0: is_dir? 1:2; p1 = 0x0c; /* No FC return. */ - sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, + sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE, p0, p1, 2, (char*)tagbuf ); return map_sw (sw); } @@ -192,7 +195,7 @@ p0 = 0x08; p1 = 0x0c; /* No FC return. */ - sw = apdu_send_simple (slot, 0x00, CMD_SELECT_FILE, + sw = apdu_send_simple (slot, 0, 0x00, CMD_SELECT_FILE, p0, p1, buflen, (char*)buffer ); return map_sw (sw); } @@ -253,7 +256,7 @@ pininfo->maxlen, pininfo->padlen); else - sw = apdu_send_simple (slot, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv); + sw = apdu_send_simple (slot, 0, 0x00, CMD_VERIFY, 0, chvno, chvlen, chv); return map_sw (sw); } @@ -300,7 +303,7 @@ pininfo->maxlen, pininfo->padlen); else - sw = apdu_send_simple (slot, 0x00, CMD_CHANGE_REFERENCE_DATA, + sw = apdu_send_simple (slot, 0, 0x00, CMD_CHANGE_REFERENCE_DATA, oldchvlen? 0 : 1, chvno, oldchvlen+newchvlen, buf); xfree (buf); return map_sw (sw); @@ -340,7 +343,7 @@ pininfo->maxlen, pininfo->padlen); else - sw = apdu_send_simple (slot, 0x00, CMD_RESET_RETRY_COUNTER, + sw = apdu_send_simple (slot, 0, 0x00, CMD_RESET_RETRY_COUNTER, 2, chvno, newchvlen, newchv); return map_sw (sw); From cvs at cvs.gnupg.org Tue Sep 23 12:36:09 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 23 Sep 2008 12:36:09 +0200 Subject: [svn] GnuPG - r4828 - trunk/scd Message-ID: Author: wk Date: 2008-09-23 12:36:09 +0200 (Tue, 23 Sep 2008) New Revision: 4828 Modified: trunk/scd/ChangeLog trunk/scd/ccid-driver.c Log: Untested fix for TPDU level exchange of large data (command chaining) Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-09-23 09:57:45 UTC (rev 4827) +++ trunk/scd/ChangeLog 2008-09-23 10:36:09 UTC (rev 4828) @@ -9,6 +9,7 @@ (send_le): Implement command chaining. * ccid-driver.c (ccid_transceive_apdu_level): Increase allowed APDU size. + (ccid_transceive): Alow for APDUS of up to 259 bytes. * apdu.h: Add new SW_ codes. 2008-09-16 Werner Koch Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2008-09-23 09:57:45 UTC (rev 4827) +++ trunk/scd/ccid-driver.c 2008-09-23 10:36:09 UTC (rev 4828) @@ -1971,8 +1971,9 @@ apdulen = apdu_buflen; assert (apdulen); - /* The maximum length for a short APDU T=1 block is 261, for an - extra APDU T=1 block is 65544. */ + /* The maximum length for a short APDU T=1 block is 261. For an + extended APDU T=1 block the maximum length 65544; however + extended APDU exchange levele is not yet supported. */ if (apdulen > 261) return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */ @@ -2119,8 +2120,11 @@ assert (apdulen); /* Construct an I-Block. */ -#warning fixme: APDULEN may be larger - if (apdulen > 254) + /* Fixme: I am not sure whether limiting the length to 259 + as per CCID spec is required. The code blow chops the + APDU anyway into 128 byte blocks. Needs to be addressed + when supporting extended length APDUs. */ + if (apdulen > 259) return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */ tpdu = msg+10; From cvs at cvs.gnupg.org Tue Sep 23 12:52:10 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 23 Sep 2008 12:52:10 +0200 Subject: [svn] gpgme - r1334 - in trunk: . gpgme Message-ID: Author: marcus Date: 2008-09-23 12:52:09 +0200 (Tue, 23 Sep 2008) New Revision: 1334 Modified: trunk/THANKS trunk/gpgme/ChangeLog trunk/gpgme/gpgme.c Log: 2008-09-23 Marcus Brinkmann * gpgme.c (gpgme_sig_notation_clear): Clear CTX->sig_notations. Submitted by "Daniel Mueller" Modified: trunk/gpgme/ChangeLog =================================================================== --- trunk/gpgme/ChangeLog 2008-09-19 14:15:51 UTC (rev 1333) +++ trunk/gpgme/ChangeLog 2008-09-23 10:52:09 UTC (rev 1334) @@ -1,3 +1,8 @@ +2008-09-23 Marcus Brinkmann + + * gpgme.c (gpgme_sig_notation_clear): Clear CTX->sig_notations. + Submitted by "Daniel Mueller" + 2008-09-16 Marcus Brinkmann * rungpg.c (gpg_new): Don't use errno with ttyname_r. Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2008-09-19 14:15:51 UTC (rev 1333) +++ trunk/THANKS 2008-09-23 10:52:09 UTC (rev 1334) @@ -7,6 +7,7 @@ Adriaan de Groot adridg at cs.kun.nl Albrecht Dre? albrecht.dress at arcor.de Alfons Hoogervorst alfons at proteus.demon.nl +Daniel Mueller daniel at danm.de Enno Cramer uebergeek at web.de Frank Heckenbach frank at g-n-u.de Igor Belyi gpgme at katehok.ac93.org Modified: trunk/gpgme/gpgme.c =================================================================== --- trunk/gpgme/gpgme.c 2008-09-19 14:15:51 UTC (rev 1333) +++ trunk/gpgme/gpgme.c 2008-09-23 10:52:09 UTC (rev 1334) @@ -554,6 +554,7 @@ _gpgme_sig_notation_free (notation); notation = next_notation; } + ctx->sig_notations = NULL; } From cvs at cvs.gnupg.org Tue Sep 23 15:04:42 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 23 Sep 2008 15:04:42 +0200 Subject: [svn] GnuPG - r4829 - trunk/scd Message-ID: Author: marcus Date: 2008-09-23 15:04:42 +0200 (Tue, 23 Sep 2008) New Revision: 4829 Modified: trunk/scd/ChangeLog trunk/scd/apdu.c Log: Marcus Brinkmann * apdu.c (pcsc_get_status): Be more relaxed with the usable flag under Windows. M scd/ChangeLog M scd/apdu.c Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-09-23 10:36:09 UTC (rev 4828) +++ trunk/scd/ChangeLog 2008-09-23 13:04:42 UTC (rev 4829) @@ -1,3 +1,8 @@ +2008-09-23 Marcus Brinkmann + + * apdu.c (pcsc_get_status): Be more relaxed with the usable flag + under Windows. + 2008-09-23 Werner Koch * app-openpgp.c (do_setattr): Use command chaining for long Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2008-09-23 10:36:09 UTC (rev 4828) +++ trunk/scd/apdu.c 2008-09-23 13:04:42 UTC (rev 4829) @@ -1082,12 +1082,19 @@ *status |= 2; if ( !(rdrstates[0].event_state & PCSC_STATE_MUTE) ) *status |= 4; +#ifndef HAVE_W32_SYSTEM /* We indicate a useful card if it is not in use by another application. This is because we only use exclusive access mode. */ if ( (*status & 6) == 6 && !(rdrstates[0].event_state & PCSC_STATE_INUSE) ) *status |= 1; +#else + /* Some winscard drivers may set EXCLUSIVE and INUSE at the same + time when we are the only user (SCM SCR335) under Windows. */ + if ((status & 6) == 6) + status |= 1; +#endif return 0; #endif /*!NEED_PCSC_WRAPPER*/ From cvs at cvs.gnupg.org Tue Sep 23 17:42:11 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 23 Sep 2008 17:42:11 +0200 Subject: [svn] GnuPG - r4830 - trunk/scd Message-ID: Author: wk Date: 2008-09-23 17:42:11 +0200 (Tue, 23 Sep 2008) New Revision: 4830 Modified: trunk/scd/ChangeLog trunk/scd/app-openpgp.c Log: Improvements for 2k keys. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-09-23 13:04:42 UTC (rev 4829) +++ trunk/scd/ChangeLog 2008-09-23 15:42:11 UTC (rev 4830) @@ -1,3 +1,10 @@ +2008-09-23 Werner Koch + + * app-openpgp.c (do_sign): Support SHA-2 digests. + (verify_chv2): No CHV auto-sync for v2 cards. + (do_auth): Allow 2048 bit keys. + (parse_algorithm_attribute): New. + 2008-09-23 Marcus Brinkmann * apdu.c (pcsc_get_status): Be more relaxed with the usable flag Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2008-09-23 13:04:42 UTC (rev 4829) +++ trunk/scd/app-openpgp.c 2008-09-23 15:42:11 UTC (rev 4830) @@ -887,7 +887,7 @@ size_t e_new_n = 0; /* Loop over all records until we have found the subkey - corresponsing to the fingerprint. Inm general the first record + corresponding to the fingerprint. Inm general the first record should be the pub record, but we don't rely on that. Given that we only need to look at one key, it is sufficient to compare the keyid so that we don't need to look at "fpr" records. */ @@ -1249,6 +1249,8 @@ send_keypair_info (app, ctrl, 1); send_keypair_info (app, ctrl, 2); send_keypair_info (app, ctrl, 3); + /* Note: We do not send the Cardholder Certificate, because that is + relativly long and for OpenPGP applications not really needed. */ return 0; } @@ -1493,7 +1495,8 @@ app->did_chv2 = 1; - if (!app->did_chv1 && !app->force_chv1 && pinvalue) + if (!app->did_chv1 && !app->force_chv1 && pinvalue + && !app->app_local->extcap.is_v2) { /* For convenience we verify CHV1 here too. We do this only if the card is not configured to require a verification before @@ -2373,15 +2376,32 @@ const void *indata, size_t indatalen, unsigned char **outdata, size_t *outdatalen ) { - static unsigned char sha1_prefix[15] = /* Object ID is 1.3.14.3.2.26 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, - 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */ - { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, - 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; + { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, + 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; + static unsigned char sha1_prefix[15] = /* (1.3.14.3.2.26) */ + { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, + 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 }; + static unsigned char sha224_prefix[19] = /* (2.16.840.1.101.3.4.2.4) */ + { 0x30, 0x2D, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, + 0x1C }; + static unsigned char sha256_prefix[19] = /* (2.16.840.1.101.3.4.2.1) */ + { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, + 0x00, 0x04, 0x20 }; + static unsigned char sha384_prefix[19] = /* (2.16.840.1.101.3.4.2.2) */ + { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, + 0x00, 0x04, 0x30 }; + static unsigned char sha512_prefix[19] = /* (2.16.840.1.101.3.4.2.3) */ + { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, + 0x00, 0x04, 0x40 }; int rc; - unsigned char data[35]; - unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */ + unsigned char data[19+64]; + size_t datalen; + unsigned char tmp_sn[20]; /* Actually 16 bytes but also for the fpr. */ const char *s; int n; const char *fpr = NULL; @@ -2390,26 +2410,38 @@ if (!keyidstr || !*keyidstr) return gpg_error (GPG_ERR_INV_VALUE); + + /* Strip off known prefixes. */ +#define X(a,b,c,d) \ + if (hashalgo == GCRY_MD_ ## a \ + && (d) \ + && indatalen == sizeof b ## _prefix + (c) \ + && !memcmp (indata, b ## _prefix, sizeof b ## _prefix)) \ + { \ + indata = (const char*)indata + sizeof b ## _prefix; \ + indatalen -= sizeof b ## _prefix; \ + } + if (indatalen == 20) - ; - else if (indatalen == (15 + 20) && hashalgo == GCRY_MD_SHA1 - && !memcmp (indata, sha1_prefix, 15)) - { - indata = (const char*)indata + 15; - indatalen -= 15; - } - else if (indatalen == (15 + 20) && hashalgo == GCRY_MD_RMD160 - && !memcmp (indata, rmd160_prefix, 15)) - { - indata = (const char*)indata + 15; - indatalen -= 15; - } + ; /* Assume a plain SHA-1 or RMD160 digest has been given. */ + else X(SHA1, sha1, 20, 1) + else X(RMD160, rmd160, 20, 1) + else X(SHA224, sha224, 28, app->app_local->extcap.is_v2) + else X(SHA256, sha256, 32, app->app_local->extcap.is_v2) + else X(SHA384, sha384, 48, app->app_local->extcap.is_v2) + else X(SHA512, sha512, 64, app->app_local->extcap.is_v2) + else if ((indatalen == 28 || indatalen == 32 + || indatalen == 48 || indatalen ==64) + && app->app_local->extcap.is_v2) + ; /* Assume a plain SHA-3 digest has been given. */ else { log_error (_("card does not support digest algorithm %s\n"), gcry_md_algo_name (hashalgo)); + /* Or the supplied digest length does not match an algorithm. */ return gpg_error (GPG_ERR_INV_VALUE); } +#undef X /* Check whether an OpenPGP card of any version has been requested. */ if (!strcmp (keyidstr, "OPENPGP.1")) @@ -2450,25 +2482,39 @@ if (rc) return rc; - if (hashalgo == GCRY_MD_SHA1) - memcpy (data, sha1_prefix, 15); - else if (hashalgo == GCRY_MD_RMD160) - memcpy (data, rmd160_prefix, 15); + /* Concatenate prefix and digest. */ +#define X(a,b,d) \ + if (hashalgo == GCRY_MD_ ## a && (d) ) \ + { \ + datalen = sizeof b ## _prefix + indatalen; \ + assert (datalen <= sizeof data); \ + memcpy (data, b ## _prefix, sizeof b ## _prefix); \ + memcpy (data + sizeof b ## _prefix, indata, indatalen); \ + } + + X(SHA1, sha1, 1) + else X(RMD160, rmd160, 1) + else X(SHA224, sha224, app->app_local->extcap.is_v2) + else X(SHA256, sha256, app->app_local->extcap.is_v2) + else X(SHA384, sha384, app->app_local->extcap.is_v2) + else X(SHA512, sha512, app->app_local->extcap.is_v2) else return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data+15, indata, indatalen); +#undef X + /* Redirect to the AUTH command if asked to. */ if (use_auth) { - /* This is a hack to redirect to the internal authenticate command. */ return do_auth (app, "OPENPGP.3", pincb, pincb_arg, - data, 35, + data, datalen, outdata, outdatalen); } + /* Show the number of signature done using this key. */ sigcount = get_sig_counter (app); log_info (_("signatures created so far: %lu\n"), sigcount); + /* Check CHV if needed. */ if (!app->did_chv1 || app->force_chv1 ) { char *pinvalue; @@ -2479,10 +2525,13 @@ app->did_chv1 = 1; - if (!app->did_chv2 && pinvalue) + /* For cards with versions < 2 we want to keep CHV1 and CHV2 in + sync, thus we verify CHV2 here using the given PIN. Cards + with version2 to not have the need for a separate CHV2 and + internally use just one. Obviously we can't do that if the + keypad has been used. */ + if (!app->did_chv2 && pinvalue && !app->app_local->extcap.is_v2) { - /* We should also verify CHV2. Note, that we can't do that - if the keypad has been used. */ rc = iso7816_verify (app->slot, 0x82, pinvalue, strlen (pinvalue)); if (gpg_err_code (rc) == GPG_ERR_BAD_PIN) rc = gpg_error (GPG_ERR_PIN_NOT_SYNCED); @@ -2498,7 +2547,7 @@ xfree (pinvalue); } - rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen); + rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen); return rc; } @@ -2520,14 +2569,14 @@ unsigned char **outdata, size_t *outdatalen ) { int rc; - unsigned char tmp_sn[20]; /* actually 16 but we use it also for the fpr. */ + unsigned char tmp_sn[20]; /* Actually 16 but we use it also for the fpr. */ const char *s; int n; const char *fpr = NULL; if (!keyidstr || !*keyidstr) return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen > 50) /* For a 1024 bit key. */ + if (indatalen > 101) /* For a 2048 bit key. */ return gpg_error (GPG_ERR_INV_VALUE); /* Check whether an OpenPGP card of any version has been requested. */ @@ -2842,6 +2891,51 @@ } +/* Read and parse the algorithm attributes for KEYNO. KEYNO must be + in the range 0..2. */ +static void +parse_algorithm_attribute (app_t app, int keyno) +{ + unsigned char *buffer; + size_t buflen; + void *relptr; + const char const desc[3][5] = {"sign", "encr", "auth"}; + + assert (keyno >=0 && keyno <= 2); + + relptr = get_one_do (app, 0xC1+keyno, &buffer, &buflen, NULL); + if (!relptr) + { + log_error ("error reading DO 0x%02X\n", 0xc1+keyno); + return; + } + if (buflen < 1) + { + log_error ("error reading DO 0x%02X\n", 0xc1+keyno); + xfree (relptr); + return; + } + + log_info ("Key-Attr-%s ..: ", desc[keyno]); + if (*buffer == 1 && (buflen == 5 || buflen == 6)) + { + log_printf ("RSA, n=%d, e=%d", + (buffer[1]<<8 | buffer[2]), + (buffer[3]<<8 | buffer[4])); + if (buflen == 6) + log_printf (", format=%s", + buffer[5] == 0? "std" : + buffer[5] == 1? "std+n" : + buffer[5] == 2? "crt" : + buffer[5] == 2? "crt+n" : "?"); + log_printf ("\n"); + } + else + log_printhex ("", buffer, buflen); + + xfree (relptr); +} + /* Select the OpenPGP application on the card in SLOT. This function must be used before any other OpenPGP application functions. */ gpg_error_t @@ -2914,7 +3008,6 @@ xfree (relptr); } - /* Read the force-chv1 flag. */ relptr = get_one_do (app, 0x00C4, &buffer, &buflen, NULL); if (!relptr) @@ -2953,7 +3046,7 @@ app->app_local->extcap.max_rsp_data = (buffer[8] << 8 | buffer[9]); } xfree (relptr); - + /* Some of the first cards accidently don't set the CHANGE_FORCE_CHV bit but allow it anyway. */ if (app->card_version <= 0x0100 && manufacturer == 1) @@ -2964,6 +3057,13 @@ if (opt.verbose) show_caps (app->app_local); + if (opt.verbose) + { + parse_algorithm_attribute (app, 0); + parse_algorithm_attribute (app, 1); + parse_algorithm_attribute (app, 2); + } + if (opt.verbose > 1) dump_all_do (slot); From cvs at cvs.gnupg.org Tue Sep 23 21:18:53 2008 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Tue, 23 Sep 2008 21:18:53 +0200 Subject: [svn] GnuPG - r4831 - trunk/doc Message-ID: Author: dshaw Date: 2008-09-23 21:18:52 +0200 (Tue, 23 Sep 2008) New Revision: 4831 Modified: trunk/doc/ChangeLog trunk/doc/gpg.texi Log: * gpg.texi (OpenPGP Key Management): Clarify setpref a bit. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-09-23 15:42:11 UTC (rev 4830) +++ trunk/doc/ChangeLog 2008-09-23 19:18:52 UTC (rev 4831) @@ -1,3 +1,7 @@ +2008-09-23 David Shaw + + * gpg.texi (OpenPGP Key Management): Clarify setpref a bit. + 2008-08-30 Werner Koch * yat2m.c (write_th): Print a not ethat this is generated source. Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2008-09-23 15:42:11 UTC (rev 4830) +++ trunk/doc/gpg.texi 2008-09-23 19:18:52 UTC (rev 4831) @@ -754,13 +754,24 @@ Set the list of user ID preferences to @code{string} for all (or just the selected) user IDs. Calling setpref with no arguments sets the preference list to the default (either built-in or set via - at option{--default-preference-list}), and calling setpref with "none" as -the argument sets an empty preference list. Use @command{@gpgname + at option{--default-preference-list}), and calling setpref with "none" +as the argument sets an empty preference list. Use @command{@gpgname --version} to get a list of available algorithms. Note that while you can change the preferences on an attribute user ID (aka "photo ID"), GnuPG does not select keys via attribute user IDs so these preferences will not be used by GnuPG. +When setting preferences, you should list the algorithms in the order +which you'd like to see them used by someone else when encrypting a +message to your key. If you don't include 3DES, it will be +automatically added at the end. Note that there are many factors that +go into choosing an algorithm (for example, your key may not be the +only recipient), and so the remote OpenPGP application being used to +send to you may or may not follow your exact chosen order for a given +message. It will, however, only choose an algorithm that is present +on the preference list of every recipient key. See also the +INTEROPERABILITY WITH OTHER OPENPGP PROGRAMS section below. + @item keyserver @opindex keyedit:keyserver Set a preferred keyserver for the specified user ID(s). This allows From cvs at cvs.gnupg.org Tue Sep 23 23:10:11 2008 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Tue, 23 Sep 2008 23:10:11 +0200 Subject: [svn] GnuPG - r4832 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: dshaw Date: 2008-09-23 23:10:10 +0200 (Tue, 23 Sep 2008) New Revision: 4832 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/pkclist.c Log: * pkclist.c (select_algo_from_prefs): Redo function to rank prefs and pick a consensus winner across all keys. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-09-23 19:18:52 UTC (rev 4831) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-09-23 21:10:10 UTC (rev 4832) @@ -1,3 +1,8 @@ +2008-09-23 David Shaw + + * pkclist.c (select_algo_from_prefs): Redo function to rank prefs + and pick a consensus winner across all keys. + 2008-09-04 David Shaw * keyserver.c (keyserver_import_cert): Allow keyserver URLs in Modified: branches/STABLE-BRANCH-1-4/g10/pkclist.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/pkclist.c 2008-09-23 19:18:52 UTC (rev 4831) +++ branches/STABLE-BRANCH-1-4/g10/pkclist.c 2008-09-23 21:10:10 UTC (rev 4832) @@ -1,6 +1,6 @@ /* pkclist.c - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - * 2007 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, + * 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1254,8 +1254,6 @@ return 0; } - - /**************** * Return -1 if we could not find an algorithm. */ @@ -1263,164 +1261,177 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype, int request, const union pref_hint *hint) { - PK_LIST pkr; - u32 bits[8]; - const prefitem_t *prefs; - int i, j; - int compr_hack=0; - int any; + PK_LIST pkr; + u32 bits[8]; + const prefitem_t *prefs; + int result=-1,i; + unsigned int best=-1; + byte scores[256]; + + if( !pk_list ) + return -1; - if( !pk_list ) - return -1; + memset(bits,0xFF,sizeof(bits)); + memset(scores,0,sizeof(scores)); - memset( bits, ~0, 8 * sizeof *bits ); - for( pkr = pk_list; pkr; pkr = pkr->next ) { - u32 mask[8]; + for( pkr = pk_list; pkr; pkr = pkr->next ) + { + u32 mask[8]; + int rank=1,implicit=-1; - memset( mask, 0, 8 * sizeof *mask ); - if( preftype == PREFTYPE_SYM ) { - if( PGP2 && - pkr->pk->version < 4 && - pkr->pk->selfsigversion < 4 ) - mask[0] |= (1<<1); /* IDEA is implicitly there for v3 keys - with v3 selfsigs (rfc2440:12.1) if - --pgp2 mode is on. This doesn't - mean it's actually available, of - course. */ + memset(mask,0,sizeof(mask)); + + switch(preftype) + { + case PREFTYPE_SYM: + /* IDEA is implicitly there for v3 keys with v3 selfsigs if + --pgp2 mode is on. This was a 2440 thing that was + dropped from 4880 but is still relevant to GPG's 1991 + support. All this doesn't mean IDEA is actually + available, of course. */ + if(PGP2 && pkr->pk->version<4 && pkr->pk->selfsigversion<4) + implicit=CIPHER_ALGO_IDEA; else - mask[0] |= (1<<2); /* 3DES is implicitly there for everyone else */ - } - else if( preftype == PREFTYPE_HASH ) { + implicit=CIPHER_ALGO_3DES; + + break; + + case PREFTYPE_HASH: /* While I am including this code for completeness, note that currently --pgp2 mode locks the hash at MD5, so this - function will never even be called. Even if the hash - wasn't locked at MD5, we don't support sign+encrypt in - --pgp2 mode, and that's the only time PREFTYPE_HASH is - used anyway. -dms */ - if( PGP2 && - pkr->pk->version < 4 && - pkr->pk->selfsigversion < 4 ) - mask[0] |= (1<<1); /* MD5 is there for v3 keys with v3 - selfsigs when --pgp2 is on. */ + code will never even be called. Even if the hash wasn't + locked at MD5, we don't support sign+encrypt in --pgp2 + mode, and that's the only time PREFTYPE_HASH is used + anyway. -dms */ + + /* MD5 is there for v3 keys with v3 selfsigs when --pgp2 is + on. */ + if(PGP2 && pkr->pk->version<4 && pkr->pk->selfsigversion<4) + implicit=DIGEST_ALGO_MD5; else - mask[0] |= (1<<2); /* SHA1 is there for everyone else */ - } - else if( preftype == PREFTYPE_ZIP ) - mask[0] |= (1<<0); /* Uncompressed is implicit */ + implicit=DIGEST_ALGO_SHA1; - if (pkr->pk->user_id) /* selected by user ID */ - prefs = pkr->pk->user_id->prefs; - else - prefs = pkr->pk->prefs; + break; - any = 0; - if( prefs ) { - for (i=0; prefs[i].type; i++ ) { - if( prefs[i].type == preftype ) { - mask[prefs[i].value/32] |= 1 << (prefs[i].value%32); - any = 1; - } - } + case PREFTYPE_ZIP: + /* Uncompressed is always an option. */ + implicit=COMPRESS_ALGO_NONE; } - if( (!prefs || !any) && preftype == PREFTYPE_ZIP ) { - mask[0] |= 3; /* asume no_compression and old pgp */ - compr_hack = 1; - } + if (pkr->pk->user_id) /* selected by user ID */ + prefs = pkr->pk->user_id->prefs; + else + prefs = pkr->pk->prefs; -#if 0 - log_debug("pref mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n", - (ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4], - (ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0]); -#endif - for(i=0; i < 8; i++ ) - bits[i] &= mask[i]; -#if 0 - log_debug("pref bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n", - (ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4], - (ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]); -#endif - } - /* usable algorithms are now in bits - * We now use the last key from pk_list to select - * the algorithm we want to use. there are no - * preferences for the last key, we select the one - * corresponding to first set bit. - */ - i = -1; - any = 0; + if( prefs ) + { + for (i=0; prefs[i].type; i++ ) + { + if( prefs[i].type == preftype ) + { + scores[prefs[i].value]+=rank; + mask[prefs[i].value/32] |= 1<<(prefs[i].value%32); - /* Can we use the requested algorithm? */ - if(request>-1 && (bits[request/32] & (1<<(request%32))) && - algo_available(preftype,request,hint)) - return request; + rank++; - /* If we have personal prefs set, use them instead of the last key */ - if(preftype==PREFTYPE_SYM && opt.personal_cipher_prefs) - prefs=opt.personal_cipher_prefs; - else if(preftype==PREFTYPE_HASH && opt.personal_digest_prefs) - prefs=opt.personal_digest_prefs; - else if(preftype==PREFTYPE_ZIP && opt.personal_compress_prefs) - prefs=opt.personal_compress_prefs; - - if( prefs ) { - for(j=0; prefs[j].type; j++ ) { - if( prefs[j].type == preftype ) { - if( (bits[prefs[j].value/32] & (1<<(prefs[j].value%32))) ) { - if( algo_available( preftype, prefs[j].value, hint ) ) { - any = 1; - i = prefs[j].value; - break; - } + /* We saw the implicit algorithm, so we don't need + tack it on the end ourselves. */ + if(implicit==prefs[i].value) + implicit=-1; } } } - } - if( !prefs || !any ) { - for(j=0; j < 256; j++ ) - if( (bits[j/32] & (1<<(j%32))) ) { - if( algo_available( preftype, j, hint ) ) { - i = j; - break; - } - } - } -#if 0 - log_debug("prefs of type %d: selected %d\n", preftype, i ); -#endif - if( compr_hack && !i ) { - /* selected no compression, but we should check whether - * algorithm 1 is also available (the ordering is not relevant - * in this case). */ - if( bits[0] & (1<<1) ) - i = 1; /* yep; we can use compression algo 1 */ + if(rank==1 && preftype==PREFTYPE_ZIP) + { + /* If the compression preferences are not present, they are + assumed to be ZIP, Uncompressed (RFC4880:13.3.1) */ + scores[1]=1; /* ZIP is first choice */ + scores[0]=2; /* Uncompressed is second choice */ + mask[0]|=3; + } + + /* If the key didn't have the implicit algorithm listed + explicitly, add it here at the tail of the list. */ + if(implicit>-1) + { + scores[implicit]+=rank; + mask[implicit/32] |= 1<<(implicit%32); + } + + for(i=0;i<8;i++) + bits[i]&=mask[i]; } - /* "If you are building an authentication system, the recipient - may specify a preferred signing algorithm. However, the signer - would be foolish to use a weak algorithm simply because the - recipient requests it." RFC2440:13. If we settle on MD5, and - SHA1 is also available, use SHA1 instead. Of course, if the - user intentionally chose MD5 (by putting it in their personal - prefs), then we should do what they say. */ + /* We've now scored all of the algorithms, and the usable ones have + bits set. Let's pick the winner. */ - if(preftype==PREFTYPE_HASH && - i==DIGEST_ALGO_MD5 && (bits[0] & (1<-1 && (bits[request/32] & (1<<(request%32))) && + algo_available(preftype,request,hint)) + result=request; - if(opt.personal_digest_prefs) - for(j=0; prefs[j].type; j++ ) - if(opt.personal_digest_prefs[j].type==PREFTYPE_HASH && - opt.personal_digest_prefs[j].value==DIGEST_ALGO_MD5) + if(result==-1) + { + /* If we have personal prefs set, use them. */ + prefs=NULL; + if(preftype==PREFTYPE_SYM && opt.personal_cipher_prefs) + prefs=opt.personal_cipher_prefs; + else if(preftype==PREFTYPE_HASH && opt.personal_digest_prefs) + prefs=opt.personal_digest_prefs; + else if(preftype==PREFTYPE_ZIP && opt.personal_compress_prefs) + prefs=opt.personal_compress_prefs; + + if( prefs ) + for(i=0; prefs[i].type; i++ ) + { + if(bits[prefs[i].value/32] & (1<<(prefs[i].value%32)) + && algo_available( preftype, prefs[i].value, hint)) { - i=DIGEST_ALGO_MD5; + result = prefs[i].value; break; } - } + } + } - return i; + if(result==-1) + { + /* At this point, we have not selected an algorithm due to a + special request or via personal prefs. Pick the highest + ranked algorithm (i.e. the one with the lowest score). */ + + for(i=0;i<256;i++) + { + /* Note the '<' here. This means in case of a tie, we will + favor the lower algorithm number. We have a choice + between the lower number (probably an older algorithm + with more time in use), or the higher number (probably a + newer algorithm with less time in use). Older is + probably safer here, even though the newer algorithms + tend to be "stronger". */ + if(scores[i] && scores[i] Author: dshaw Date: 2008-09-23 23:52:18 +0200 (Tue, 23 Sep 2008) New Revision: 4833 Modified: trunk/g10/ChangeLog trunk/g10/pkclist.c Log: * pkclist.c (select_algo_from_prefs): Redo function to rank prefs and pick a consensus winner across all keys. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-09-23 21:10:10 UTC (rev 4832) +++ trunk/g10/ChangeLog 2008-09-23 21:52:18 UTC (rev 4833) @@ -1,3 +1,8 @@ +2008-09-23 David Shaw + + * pkclist.c (select_algo_from_prefs): Redo function to rank prefs + and pick a consensus winner across all keys. + 2008-09-16 Werner Koch * card-util.c (fpr_is_ff): New. Modified: trunk/g10/pkclist.c =================================================================== --- trunk/g10/pkclist.c 2008-09-23 21:10:10 UTC (rev 4832) +++ trunk/g10/pkclist.c 2008-09-23 21:52:18 UTC (rev 4833) @@ -1,6 +1,6 @@ /* pkclist.c - create a list of public keys - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, + * 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1263,174 +1263,184 @@ return 0; } - - /**************** * Return -1 if we could not find an algorithm. */ int -select_algo_from_prefs(PK_LIST pk_list, int preftype, int request, - const union pref_hint *hint) +select_algo_from_prefs(PK_LIST pk_list, int preftype, + int request, const union pref_hint *hint) { - PK_LIST pkr; - u32 bits[8]; - const prefitem_t *prefs; - int i, j; - int compr_hack=0; - int any; + PK_LIST pkr; + u32 bits[8]; + const prefitem_t *prefs; + int result=-1,i; + unsigned int best=-1; + byte scores[256]; + + if( !pk_list ) + return -1; - if( !pk_list ) - return -1; + memset(bits,0xFF,sizeof(bits)); + memset(scores,0,sizeof(scores)); - memset( bits, ~0, 8 * sizeof *bits ); - for( pkr = pk_list; pkr; pkr = pkr->next ) { - u32 mask[8]; + for( pkr = pk_list; pkr; pkr = pkr->next ) + { + u32 mask[8]; + int rank=1,implicit=-1; - memset( mask, 0, 8 * sizeof *mask ); - if( preftype == PREFTYPE_SYM ) { - if( PGP2 && - pkr->pk->version < 4 && - pkr->pk->selfsigversion < 4 ) - mask[0] |= (1<<1); /* IDEA is implicitly there for v3 keys - with v3 selfsigs (rfc2440:12.1) if - --pgp2 mode is on. This doesn't - mean it's actually available, of - course. */ + memset(mask,0,sizeof(mask)); + + switch(preftype) + { + case PREFTYPE_SYM: + /* IDEA is implicitly there for v3 keys with v3 selfsigs if + --pgp2 mode is on. This was a 2440 thing that was + dropped from 4880 but is still relevant to GPG's 1991 + support. All this doesn't mean IDEA is actually + available, of course. */ + if(PGP2 && pkr->pk->version<4 && pkr->pk->selfsigversion<4) + implicit=CIPHER_ALGO_IDEA; else - mask[0] |= (1<<2); /* 3DES is implicitly there for everyone else */ - } - else if( preftype == PREFTYPE_HASH ) { + implicit=CIPHER_ALGO_3DES; + + break; + + case PREFTYPE_HASH: /* While I am including this code for completeness, note that currently --pgp2 mode locks the hash at MD5, so this - function will never even be called. Even if the hash - wasn't locked at MD5, we don't support sign+encrypt in - --pgp2 mode, and that's the only time PREFTYPE_HASH is - used anyway. -dms */ - if( PGP2 && - pkr->pk->version < 4 && - pkr->pk->selfsigversion < 4 ) - mask[0] |= (1<<1); /* MD5 is there for v3 keys with v3 - selfsigs when --pgp2 is on. */ + code will never even be called. Even if the hash wasn't + locked at MD5, we don't support sign+encrypt in --pgp2 + mode, and that's the only time PREFTYPE_HASH is used + anyway. -dms */ + + /* MD5 is there for v3 keys with v3 selfsigs when --pgp2 is + on. */ + if(PGP2 && pkr->pk->version<4 && pkr->pk->selfsigversion<4) + implicit=DIGEST_ALGO_MD5; else - mask[0] |= (1<<2); /* SHA1 is there for everyone else */ - } - else if( preftype == PREFTYPE_ZIP ) - mask[0] |= (1<<0); /* Uncompressed is implicit */ + implicit=DIGEST_ALGO_SHA1; - if (pkr->pk->user_id) /* selected by user ID */ - prefs = pkr->pk->user_id->prefs; - else - prefs = pkr->pk->prefs; + break; - any = 0; - if( prefs ) { - for (i=0; prefs[i].type; i++ ) { - if( prefs[i].type == preftype ) { - mask[prefs[i].value/32] |= 1 << (prefs[i].value%32); - any = 1; - } - } + case PREFTYPE_ZIP: + /* Uncompressed is always an option. */ + implicit=COMPRESS_ALGO_NONE; } - if( (!prefs || !any) && preftype == PREFTYPE_ZIP ) { - mask[0] |= 3; /* asume no_compression and old pgp */ - compr_hack = 1; - } + if (pkr->pk->user_id) /* selected by user ID */ + prefs = pkr->pk->user_id->prefs; + else + prefs = pkr->pk->prefs; -#if 0 - log_debug("pref mask=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX (%s)\n", - (ulong)mask[7], (ulong)mask[6], (ulong)mask[5], (ulong)mask[4], - (ulong)mask[3], (ulong)mask[2], (ulong)mask[1], (ulong)mask[0], - keystr_from_pk (pkr->pk)); -#endif - for(i=0; i < 8; i++ ) - bits[i] &= mask[i]; -#if 0 - log_debug("pref bits=%08lX%08lX%08lX%08lX%08lX%08lX%08lX%08lX\n", - (ulong)bits[7], (ulong)bits[6], (ulong)bits[5], (ulong)bits[4], - (ulong)bits[3], (ulong)bits[2], (ulong)bits[1], (ulong)bits[0]); -#endif - } - /* usable algorithms are now in bits - * We now use the last key from pk_list to select - * the algorithm we want to use. there are no - * preferences for the last key, we select the one - * corresponding to first set bit. - */ - i = -1; - any = 0; + if( prefs ) + { + for (i=0; prefs[i].type; i++ ) + { + if( prefs[i].type == preftype ) + { + scores[prefs[i].value]+=rank; + mask[prefs[i].value/32] |= 1<<(prefs[i].value%32); - /* Can we use the requested algorithm? */ - if(request>-1 && (bits[request/32] & (1<<(request%32))) && - algo_available(preftype,request,hint)) - return request; + rank++; - /* If we have personal prefs set, use them instead of the last key */ - if(preftype==PREFTYPE_SYM && opt.personal_cipher_prefs) - prefs=opt.personal_cipher_prefs; - else if(preftype==PREFTYPE_HASH && opt.personal_digest_prefs) - prefs=opt.personal_digest_prefs; - else if(preftype==PREFTYPE_ZIP && opt.personal_compress_prefs) - prefs=opt.personal_compress_prefs; - - if( prefs ) { - for(j=0; prefs[j].type; j++ ) { - if( prefs[j].type == preftype ) { - if( (bits[prefs[j].value/32] & (1<<(prefs[j].value%32))) ) { - if( algo_available( preftype, prefs[j].value, hint ) ) { - any = 1; - i = prefs[j].value; - break; - } + /* We saw the implicit algorithm, so we don't need + tack it on the end ourselves. */ + if(implicit==prefs[i].value) + implicit=-1; } } } - } - if( !prefs || !any ) { - for(j=0; j < 256; j++ ) - if( (bits[j/32] & (1<<(j%32))) ) { - if( algo_available( preftype, j, hint ) ) { - i = j; - break; - } - } - } -#if 0 - log_debug("prefs of type %d: selected %d\n", preftype, i ); -#endif - if( compr_hack && !i ) { - /* selected no compression, but we should check whether - * algorithm 1 is also available (the ordering is not relevant - * in this case). */ - if( bits[0] & (1<<1) ) - i = 1; /* yep; we can use compression algo 1 */ + if(rank==1 && preftype==PREFTYPE_ZIP) + { + /* If the compression preferences are not present, they are + assumed to be ZIP, Uncompressed (RFC4880:13.3.1) */ + scores[1]=1; /* ZIP is first choice */ + scores[0]=2; /* Uncompressed is second choice */ + mask[0]|=3; + } + + /* If the key didn't have the implicit algorithm listed + explicitly, add it here at the tail of the list. */ + if(implicit>-1) + { + scores[implicit]+=rank; + mask[implicit/32] |= 1<<(implicit%32); + } + + for(i=0;i<8;i++) + bits[i]&=mask[i]; } - /* "If you are building an authentication system, the recipient - may specify a preferred signing algorithm. However, the signer - would be foolish to use a weak algorithm simply because the - recipient requests it." RFC2440:13. If we settle on MD5, and - SHA1 is also available, use SHA1 instead. Of course, if the - user intentionally chose MD5 (by putting it in their personal - prefs), then we should do what they say. */ + /* We've now scored all of the algorithms, and the usable ones have + bits set. Let's pick the winner. */ - if(preftype==PREFTYPE_HASH && - i==DIGEST_ALGO_MD5 && (bits[0] & (1<-1 && (bits[request/32] & (1<<(request%32))) && + algo_available(preftype,request,hint)) + result=request; - if(opt.personal_digest_prefs) - for(j=0; prefs[j].type; j++ ) - if(opt.personal_digest_prefs[j].type==PREFTYPE_HASH && - opt.personal_digest_prefs[j].value==DIGEST_ALGO_MD5) + if(result==-1) + { + /* If we have personal prefs set, use them. */ + prefs=NULL; + if(preftype==PREFTYPE_SYM && opt.personal_cipher_prefs) + prefs=opt.personal_cipher_prefs; + else if(preftype==PREFTYPE_HASH && opt.personal_digest_prefs) + prefs=opt.personal_digest_prefs; + else if(preftype==PREFTYPE_ZIP && opt.personal_compress_prefs) + prefs=opt.personal_compress_prefs; + + if( prefs ) + for(i=0; prefs[i].type; i++ ) + { + if(bits[prefs[i].value/32] & (1<<(prefs[i].value%32)) + && algo_available( preftype, prefs[i].value, hint)) { - i=DIGEST_ALGO_MD5; + result = prefs[i].value; break; } - } + } + } - return i; + if(result==-1) + { + /* At this point, we have not selected an algorithm due to a + special request or via personal prefs. Pick the highest + ranked algorithm (i.e. the one with the lowest score). */ + + for(i=0;i<256;i++) + { + /* Note the '<' here. This means in case of a tie, we will + favor the lower algorithm number. We have a choice + between the lower number (probably an older algorithm + with more time in use), or the higher number (probably a + newer algorithm with less time in use). Older is + probably safer here, even though the newer algorithms + tend to be "stronger". */ + if(scores[i] && scores[i] Author: dshaw Date: 2008-09-25 06:00:36 +0200 (Thu, 25 Sep 2008) New Revision: 4834 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/keyedit.c Log: * keyedit.c (keyedit_menu): Fix bug where a modified keyring loses its modified status after a "clean" or "minimize" that doesn't need to do anything. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-09-23 21:52:18 UTC (rev 4833) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2008-09-25 04:00:36 UTC (rev 4834) @@ -1,3 +1,9 @@ +2008-09-24 David Shaw + + * keyedit.c (keyedit_menu): Fix bug where a modified keyring loses + its modified status after a "clean" or "minimize" that doesn't + need to do anything. + 2008-09-23 David Shaw * pkclist.c (select_algo_from_prefs): Redo function to rank prefs Modified: branches/STABLE-BRANCH-1-4/g10/keyedit.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keyedit.c 2008-09-23 21:52:18 UTC (rev 4833) +++ branches/STABLE-BRANCH-1-4/g10/keyedit.c 2008-09-25 04:00:36 UTC (rev 4834) @@ -2185,11 +2185,13 @@ break; case cmdCLEAN: - redisplay=modified=menu_clean(keyblock,0); + if(menu_clean(keyblock,0)) + redisplay=modified=1; break; case cmdMINIMIZE: - redisplay=modified=menu_clean(keyblock,1); + if(menu_clean(keyblock,1)) + redisplay=modified=1; break; case cmdQUIT: From cvs at cvs.gnupg.org Thu Sep 25 12:06:03 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 25 Sep 2008 12:06:03 +0200 Subject: [svn] GnuPG - r4835 - in trunk: . agent g10 scd Message-ID: Author: wk Date: 2008-09-25 12:06:02 +0200 (Thu, 25 Sep 2008) New Revision: 4835 Modified: trunk/NEWS trunk/agent/ChangeLog trunk/agent/divert-scd.c trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/g10/call-agent.h trunk/g10/card-util.c trunk/scd/ChangeLog trunk/scd/app-openpgp.c trunk/scd/iso7816.c trunk/scd/iso7816.h Log: Finished support for v2 cards with the exception of secure messaging. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/agent/ChangeLog 2008-09-25 10:06:02 UTC (rev 4835) @@ -1,3 +1,7 @@ +2008-09-25 Werner Koch + + * divert-scd.c (getpin_cb): Support a Reset Code style PINs.. + 2008-09-03 Werner Koch * command.c (parse_keygrip): Use hex2bin. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/g10/ChangeLog 2008-09-25 10:06:02 UTC (rev 4835) @@ -1,3 +1,16 @@ +2008-09-25 Werner Koch + + * card-util.c (change_pin): Support setting of the reset code. + +2008-09-24 Werner Koch + + * call-agent.h (struct agent_card_info_s): Add field IS_V2. + * call-agent.c (learn_status_cb): That that field. + + * card-util.c (change_pin): Rename first arg to UNBLOCK_v2 and use + it this way. + (card_edit): Add new command UNBLOCK. + 2008-09-23 David Shaw * pkclist.c (select_algo_from_prefs): Redo function to rank prefs Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/scd/ChangeLog 2008-09-25 10:06:02 UTC (rev 4835) @@ -1,3 +1,22 @@ +2008-09-25 Werner Koch + + * app-openpgp.c (do_setattr): Do not allow setting of the reset + code. + (do_change_pin): Allow setting of the reset code. + +2008-09-24 Werner Koch + + * app-openpgp.c (verify_chv3): Set the did_chv3 flag which was + accidently removed on 2008-03-26. + (verify_chv2): Revert last change. + (do_change_pin): Do not change CHV2. Add reset code logic for v2 + cards. + * iso7816.c (iso7816_reset_retry_counter_with_rc): New. + + * app-openpgp.c (add_tlv, build_privkey_template): New. + (do_writekey): Support v2 keys and other key lengths than 1024. + * iso7816.c (iso7816_put_data_odd): New. + 2008-09-23 Werner Koch * app-openpgp.c (do_sign): Support SHA-2 digests. @@ -4,6 +23,8 @@ (verify_chv2): No CHV auto-sync for v2 cards. (do_auth): Allow 2048 bit keys. (parse_algorithm_attribute): New. + (rsa_key_format_t): New. + (struct app_local_s): Add struct KEYATTR. 2008-09-23 Marcus Brinkmann @@ -1815,7 +1836,7 @@ the gpg-agent. - Copyright 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + Copyright 2002, 2003, 2004, 2005, 2007, 2008 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 Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/NEWS 2008-09-25 10:06:02 UTC (rev 4835) @@ -4,32 +4,36 @@ * New keyserver helper gpg2keys_kdns as generic DNS CERT lookup. Run with --help for a short description. Requires the ADNS library. - * New mechanisms "local" and "nodefault" for --auto-key-locate [gpg]. + * [gpg] New mechanisms "local" and "nodefault" for --auto-key-locate. Fixed a few problems with this option. - * [W32] Initialized the socket subsystem for all keyserver helpers. + * [w32] Initialized the socket subsystem for all keyserver helpers. - * [W32] The sysconf directory has been moved from a subdirectory of + * [w32] The sysconf directory has been moved from a subdirectory of the installation directory to %CSIDL_COMMON_APPDATA%/GNU/etc/gnupg. - * New gpg2 command --locate-keys. + * [gpg] New command --locate-keys. - * New gpg2 options --with-sig-list and --with-sig-check. + * [gpg] New options --with-sig-list and --with-sig-check. - * Made gpgsm's --output option work with --export-secret-key-p12. + * [gpgsm] Made --output option work with --export-secret-key-p12. * gpg-connect-agent accepts commands given as command line arguments. - * The gpg2 option --fixed-list-mode is now implicitly used and obsolete. + * [gpg] The option --fixed-list-mode is now implicitly used and obsolete. - * New control statement %ask-passphrase for the unattended key - generation of gpg2. + * [gpg] New control statement %ask-passphrase for the unattended key + generation. * gpgsm now uses AES by default. * gpg-preset-passphrase works again. + * Admin PINs are cached again (bug in 2.0.9). + * Support for version 2 OpenPGP cards. + + Noteworthy changes in version 2.0.9 (2008-03-26) ------------------------------------------------ Modified: trunk/agent/divert-scd.c =================================================================== --- trunk/agent/divert-scd.c 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/agent/divert-scd.c 2008-09-25 10:06:02 UTC (rev 4835) @@ -185,6 +185,7 @@ PIN. If the PIN is not correctly repeated it starts from all over. 'A' = The PIN is an Admin PIN, SO-PIN, PUK or alike. + 'R' = The PIN is a Reset Code. Example: @@ -202,6 +203,7 @@ const char *ends, *s; int any_flags = 0; int newpin = 0; + int resetcode = 0; const char *again_text = NULL; const char *prompt = "PIN"; @@ -217,6 +219,11 @@ prompt = _("Admin PIN"); else if (*s == 'N') newpin = 1; + else if (*s == 'R') + { + prompt = _("Reset Code"); + resetcode = 1; + } } info = ends+1; any_flags = 1; @@ -272,10 +279,16 @@ pi2->min_digits = 0; pi2->max_digits = 8; pi2->max_tries = 1; - rc = agent_askpin (ctrl, _("Repeat this PIN"), prompt, NULL, pi2); + rc = agent_askpin (ctrl, + (resetcode? + _("Repeat this Reset Code"): + _("Repeat this PIN")), + prompt, NULL, pi2); if (!rc && strcmp (pi->pin, pi2->pin)) { - again_text = N_("PIN not correctly repeated; try again"); + again_text = (resetcode? + N_("Reset Code not correctly repeated; try again"): + N_("PIN not correctly repeated; try again")); xfree (pi2); xfree (pi); goto again; Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/g10/call-agent.c 2008-09-25 10:06:02 UTC (rev 4835) @@ -264,6 +264,8 @@ { xfree (parm->serialno); parm->serialno = store_serialno (line); + parm->is_v2 = (strlen (parm->serialno) >= 16 + && xtoi_2 (parm->serialno+12) >= 2 ); } else if (keywordlen == 9 && !memcmp (keyword, "DISP-NAME", keywordlen)) { @@ -758,10 +760,12 @@ /* Change the PIN of an OpenPGP card or reset the retry counter. CHVNO 1: Change the PIN - 2: Same as 1 + 2: For v1 cards: Same as 1. + For v2 cards: Reset the PIN using the Reset Code. 3: Change the admin PIN 101: Set a new PIN and reset the retry counter - 102: Same as 101 + 102: For v1 cars: Same as 101. + For v2 cards: Set a new Reset Code. SERIALNO is not used. */ int Modified: trunk/g10/call-agent.h =================================================================== --- trunk/g10/call-agent.h 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/g10/call-agent.h 2008-09-25 10:06:02 UTC (rev 4835) @@ -49,6 +49,7 @@ int chv1_cached; /* True if a PIN is not required for each signing. Note that the gpg-agent might cache it anyway. */ + int is_v2; /* True if this is a v2 card. */ int chvmaxlen[3]; /* Maximum allowed length of a CHV. */ int chvretry[3]; /* Allowed retries for the CHV; 0 = blocked. */ }; Modified: trunk/g10/card-util.c =================================================================== --- trunk/g10/card-util.c 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/g10/card-util.c 2008-09-25 10:06:02 UTC (rev 4835) @@ -51,7 +51,7 @@ /* Change the PIN of a an OpenPGP card. This is an interactive function. */ void -change_pin (int chvno, int allow_admin) +change_pin (int unblock_v2, int allow_admin) { struct agent_card_info_s info; int rc; @@ -76,8 +76,27 @@ return; } - if(!allow_admin) + + if (unblock_v2) { + if (!info.is_v2) + log_error (_("This command is only available for version 2 cards\n")); + else if (!info.chvretry[1]) + log_error (_("Reset Code not or not anymore available\n")); + else + { + rc = agent_scd_change_pin (2, info.serialno); + if (rc) + tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); + else + { + write_status (STATUS_SC_OP_SUCCESS); + tty_printf ("PIN changed.\n"); + } + } + } + else if (!allow_admin) + { rc = agent_scd_change_pin (1, info.serialno); if (rc) tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); @@ -96,6 +115,7 @@ tty_printf ("1 - change PIN\n" "2 - unblock PIN\n" "3 - change Admin PIN\n" + "4 - set the Reset Code\n" "Q - quit\n"); tty_printf ("\n"); @@ -107,6 +127,7 @@ rc = 0; if (*answer == '1') { + /* Change PIN. */ rc = agent_scd_change_pin (1, info.serialno); if (rc) tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); @@ -118,6 +139,7 @@ } else if (*answer == '2') { + /* Unblock PIN. */ rc = agent_scd_change_pin (101, info.serialno); if (rc) tty_printf ("Error unblocking the PIN: %s\n", gpg_strerror (rc)); @@ -129,6 +151,7 @@ } else if (*answer == '3') { + /* Change Admin PIN. */ rc = agent_scd_change_pin (3, info.serialno); if (rc) tty_printf ("Error changing the PIN: %s\n", gpg_strerror (rc)); @@ -138,6 +161,19 @@ tty_printf ("PIN changed.\n"); } } + else if (*answer == '4') + { + /* Set a new Reset Code. */ + rc = agent_scd_change_pin (102, info.serialno); + if (rc) + tty_printf ("Error setting the Reset Code: %s\n", + gpg_strerror (rc)); + else + { + write_status (STATUS_SC_OP_SUCCESS); + tty_printf ("Reset Code set.\n"); + } + } else if (*answer == 'q' || *answer == 'Q') { break; @@ -1345,6 +1381,7 @@ cmdQUIT, cmdADMIN, cmdHELP, cmdLIST, cmdDEBUG, cmdVERIFY, cmdNAME, cmdURL, cmdFETCH, cmdLOGIN, cmdLANG, cmdSEX, cmdCAFPR, cmdFORCESIG, cmdGENERATE, cmdPASSWD, cmdPRIVATEDO, cmdWRITECERT, + cmdUNBLOCK, cmdINVCMD }; @@ -1375,6 +1412,7 @@ { "generate", cmdGENERATE, 1, N_("generate new keys")}, { "passwd" , cmdPASSWD, 0, N_("menu to change or unblock the PIN")}, { "verify" , cmdVERIFY, 0, N_("verify the PIN and list all data")}, + { "unblock" , cmdUNBLOCK,0, N_("unblock the PIN using a Reset Code") }, /* Note, that we do not announce these command yet. */ { "privatedo", cmdPRIVATEDO, 0, NULL }, { "writecert", cmdWRITECERT, 1, NULL }, @@ -1644,6 +1682,11 @@ did_checkpin = 0; /* Need to reset it of course. */ break; + case cmdUNBLOCK: + change_pin (1, allow_admin); + did_checkpin = 0; /* Need to reset it of course. */ + break; + case cmdQUIT: goto leave; Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/scd/app-openpgp.c 2008-09-25 10:06:02 UTC (rev 4835) @@ -19,6 +19,29 @@ * $Id$ */ +/* Some notes: + + CHV means Card Holder Verification and is nothing else than a PIN + or password. That term seems to have been used originally with GSM + cards. Version v2 of the specs changes the term to the clearer + term PW for password. We use the terms here interchangeable + because we do not want to change existing strings i18n wise. + + Version 2 of the specs also drops the separate PW2 which was + required in v1 due to ISO requirements. It is now possible to have + one physical PW but two reference to it so that they can be + individually be verified (e.g. to implement a forced verification + for one key). Thus you will noticed the use of PW2 with the verify + command but not with change_reference_data because the latter + operates directly on the physical PW. + + The Reset Code (RC) as implemented by v2 cards uses the same error + counter as the PW2 of v1 cards. By default no RC is set and thus + that error counter is set to 0. After setting the RC the error + counter will be initialized to 3. + + */ + #include #include #include @@ -46,6 +69,7 @@ #include "tlv.h" +/* A table describing the DOs of the card. */ static struct { int tag; int constructed; @@ -91,6 +115,18 @@ }; +/* The format of RSA private keys. */ +typedef enum + { + RSA_UNKNOWN_FMT, + RSA_STD, + RSA_STD_N, + RSA_CRT, + RSA_CRT_N + } +rsa_key_format_t; + + /* One cache item for DOs. */ struct cache_s { struct cache_s *next; @@ -150,6 +186,16 @@ unsigned int no_sync:1; /* Do not sync CHV1 and CHV2 */ unsigned int def_chv2:1; /* Use 123456 for CHV2. */ } flags; + + struct + { + unsigned int n_bits; /* Size of the modulus in bits. The rest + of this strucuire is only valid if + this is not 0. */ + unsigned int e_bits; /* Size of the public exponent in bits. */ + rsa_key_format_t format; + } keyattr[3]; + }; @@ -1495,8 +1541,7 @@ app->did_chv2 = 1; - if (!app->did_chv1 && !app->force_chv1 && pinvalue - && !app->app_local->extcap.is_v2) + if (!app->did_chv1 && !app->force_chv1 && pinvalue) { /* For convenience we verify CHV1 here too. We do this only if the card is not configured to require a verification before @@ -1635,6 +1680,7 @@ flush_cache_after_error (app); return rc; } + app->did_chv3 = 1; } return rc; } @@ -1673,7 +1719,6 @@ { "CERT-3", 0x7F21, 3, 0, 1 }, { "SM-KEY-ENC", 0x00D1, 3, 0, 1 }, { "SM-KEY-MAC", 0x00D2, 3, 0, 1 }, - { "PW-RESET-CODE",0x00D3, 3, 0, 1 }, { NULL, 0 } }; int exmode; @@ -1758,8 +1803,10 @@ { int rc = 0; int chvno = atoi (chvnostr); + char *resetcode = NULL; char *pinvalue; int reset_mode = !!(flags & APP_CHANGE_FLAG_RESET); + int set_resetcode = 0; if (reset_mode && chvno == 3) { @@ -1768,12 +1815,55 @@ } else if (reset_mode || chvno == 3) { - /* we always require that the PIN is entered. */ + /* We always require that the PIN is entered. */ app->did_chv3 = 0; rc = verify_chv3 (app, pincb, pincb_arg); if (rc) goto leave; + + if (chvno == 2 && app->app_local->extcap.is_v2) + set_resetcode = 1; } + else if (chvno == 2 && app->app_local->extcap.is_v2) + { + /* There is no PW2 for v2 cards. We use this condition to allow + a PW reset using the Reset Code. */ + void *relptr; + unsigned char *value; + size_t valuelen; + int remaining; + + relptr = get_one_do (app, 0x00C4, &value, &valuelen, NULL); + if (!relptr || valuelen < 7) + { + log_error (_("error retrieving CHV status from card\n")); + xfree (relptr); + rc = gpg_error (GPG_ERR_CARD); + goto leave; + } + remaining = value[5]; + xfree (relptr); + if (!remaining) + { + log_error (_("Reset Code not or not anymore available\n")); + rc = gpg_error (GPG_ERR_BAD_PIN); + goto leave; + } + + rc = pincb (pincb_arg, _("||Please enter the Reset Code for the card"), + &resetcode); + if (rc) + { + log_info (_("PIN callback returned error: %s\n"), gpg_strerror (rc)); + goto leave; + } + if (strlen (resetcode) < 8) + { + log_error (_("Reset Code is too short; minimum length is %d\n"), 8); + rc = gpg_error (GPG_ERR_BAD_PIN); + goto leave; + } + } else if (chvno == 1 || chvno == 2) { /* CHV1 and CVH2 should always have the same value, thus we @@ -1802,7 +1892,9 @@ /* TRANSLATORS: Do not translate the "|*|" prefixes but keep it at the start of the string. We need this elsewhere to get some infos on the string. */ - rc = pincb (pincb_arg, chvno == 3? _("|AN|New Admin PIN") : _("|N|New PIN"), + rc = pincb (pincb_arg, + set_resetcode? _("|RN|New Reset Code") : + chvno == 3? _("|AN|New Admin PIN") : _("|N|New PIN"), &pinvalue); if (rc) { @@ -1810,11 +1902,38 @@ goto leave; } - if (reset_mode) + if (resetcode) { + char *buffer; + + buffer = xtrymalloc (strlen (resetcode) + strlen (pinvalue) + 1); + if (!buffer) + rc = gpg_error_from_syserror (); + else + { + strcpy (stpcpy (buffer, resetcode), pinvalue); + rc = iso7816_reset_retry_counter_with_rc (app->slot, 0x81, + buffer, strlen (buffer)); + wipememory (buffer, strlen (buffer)); + xfree (buffer); + } + } + else if (set_resetcode) + { + if (strlen (pinvalue) < 8) + { + log_error (_("Reset Code is too short; minimum length is %d\n"), 8); + rc = gpg_error (GPG_ERR_BAD_PIN); + } + else + rc = iso7816_put_data (app->slot, 0, 0xD3, + pinvalue, strlen (pinvalue)); + } + else if (reset_mode) + { rc = iso7816_reset_retry_counter (app->slot, 0x81, pinvalue, strlen (pinvalue)); - if (!rc) + if (!rc && !app->app_local->extcap.is_v2) rc = iso7816_reset_retry_counter (app->slot, 0x82, pinvalue, strlen (pinvalue)); } @@ -1824,7 +1943,7 @@ { rc = iso7816_change_reference_data (app->slot, 0x81, NULL, 0, pinvalue, strlen (pinvalue)); - if (!rc) + if (!rc && !app->app_local->extcap.is_v2) rc = iso7816_change_reference_data (app->slot, 0x82, NULL, 0, pinvalue, strlen (pinvalue)); } @@ -1832,11 +1951,20 @@ rc = iso7816_change_reference_data (app->slot, 0x80 + chvno, NULL, 0, pinvalue, strlen (pinvalue)); } - xfree (pinvalue); + if (pinvalue) + { + wipememory (pinvalue, strlen (pinvalue)); + xfree (pinvalue); + } if (rc) flush_cache_after_error (app); leave: + if (resetcode) + { + wipememory (resetcode, strlen (resetcode)); + xfree (resetcode); + } return rc; } @@ -1883,7 +2011,163 @@ } +/* Create a TLV tag and value and store it at BUFFER. Return the length + of tag and length. A LENGTH greater than 65535 is truncated. */ +static size_t +add_tlv (unsigned char *buffer, unsigned int tag, size_t length) +{ + unsigned char *p = buffer; + assert (tag <= 0xffff); + if ( tag > 0xff ) + *p++ = tag >> 8; + *p++ = tag; + if (length < 128) + *p++ = length; + else if (length < 256) + { + *p++ = 0x81; + *p++ = length; + } + else + { + if (length > 0xffff) + length = 0xffff; + *p++ = 0x82; + *p++ = length >> 8; + *p++ = length; + } + + return p - buffer; +} + + +/* Build the private key template as specified in the OpenPGP specs + v2.0 section 4.3.3.7. */ +static gpg_error_t +build_privkey_template (app_t app, int keyno, + const unsigned char *rsa_n, size_t rsa_n_len, + const unsigned char *rsa_e, size_t rsa_e_len, + const unsigned char *rsa_p, size_t rsa_p_len, + const unsigned char *rsa_q, size_t rsa_q_len, + unsigned char **result, size_t *resultlen) +{ + size_t rsa_e_reqlen; + unsigned char privkey[7*(1+3)]; + size_t privkey_len; + unsigned char exthdr[2+2+3]; + size_t exthdr_len; + unsigned char suffix[2+3]; + size_t suffix_len; + unsigned char *tp; + size_t datalen; + unsigned char *template; + size_t template_size; + + *result = NULL; + *resultlen = 0; + + switch (app->app_local->keyattr[keyno].format) + { + case RSA_STD: + case RSA_STD_N: + break; + case RSA_CRT: + case RSA_CRT_N: + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + default: + return gpg_error (GPG_ERR_INV_VALUE); + } + + /* Get the required length for E. */ + rsa_e_reqlen = app->app_local->keyattr[keyno].e_bits/8; + assert (rsa_e_len <= rsa_e_reqlen); + + /* Build the 7f48 cardholder private key template. */ + datalen = 0; + tp = privkey; + + tp += add_tlv (tp, 0x91, rsa_e_reqlen); + datalen += rsa_e_reqlen; + + tp += add_tlv (tp, 0x92, rsa_p_len); + datalen += rsa_p_len; + + tp += add_tlv (tp, 0x93, rsa_q_len); + datalen += rsa_q_len; + + if (app->app_local->keyattr[keyno].format == RSA_STD_N + || app->app_local->keyattr[keyno].format == RSA_CRT_N) + { + tp += add_tlv (tp, 0x97, rsa_n_len); + datalen += rsa_n_len; + } + privkey_len = tp - privkey; + + /* Build the extended header list without the private key template. */ + tp = exthdr; + *tp++ = keyno ==0 ? 0xb6 : keyno == 1? 0xb8 : 0xa4; + *tp++ = 0; + tp += add_tlv (tp, 0x7f48, privkey_len); + exthdr_len = tp - exthdr; + + /* Build the 5f48 suffix of the data. */ + tp = suffix; + tp += add_tlv (tp, 0x5f48, datalen); + suffix_len = tp - suffix; + + /* Now concatenate everything. */ + template_size = (1 + 3 /* 0x4d and len. */ + + exthdr_len + + privkey_len + + suffix_len + + datalen); + tp = template = xtrymalloc_secure (template_size); + if (!template) + return gpg_error_from_syserror (); + + tp += add_tlv (tp, 0x4d, exthdr_len + privkey_len + suffix_len + datalen); + memcpy (tp, exthdr, exthdr_len); + tp += exthdr_len; + memcpy (tp, privkey, privkey_len); + tp += privkey_len; + memcpy (tp, suffix, suffix_len); + tp += suffix_len; + + memcpy (tp, rsa_e, rsa_e_len); + if (rsa_e_len < rsa_e_reqlen) + { + /* Right justify E. */ + memmove (tp + rsa_e_reqlen - rsa_e_len, tp, rsa_e_len); + memset (tp, 0, rsa_e_reqlen - rsa_e_len); + } + tp += rsa_e_reqlen; + + memcpy (tp, rsa_p, rsa_p_len); + tp += rsa_p_len; + + memcpy (tp, rsa_q, rsa_q_len); + tp += rsa_q_len; + + if (app->app_local->keyattr[keyno].format == RSA_STD_N + || app->app_local->keyattr[keyno].format == RSA_CRT_N) + { + memcpy (tp, rsa_n, rsa_n_len); + tp += rsa_n_len; + } + + /* Sanity check. We don't know the exact length because we + allocated 3 bytes for the first length header. */ + assert (tp - template <= template_size); + + *result = template; + *resultlen = tp - template; + return 0; +} + + + /* Handle the WRITEKEY command for OpenPGP. This function expects a canonical encoded S-expression with the secret key in KEYDATA and its length (for assertions) in KEYDATALEN. KEYID needs to be the @@ -1910,6 +2194,7 @@ const unsigned char *rsa_q = NULL; size_t rsa_n_len, rsa_e_len, rsa_p_len, rsa_q_len; unsigned int nbits; + unsigned int maxbits; unsigned char *template = NULL; unsigned char *tp; size_t template_len; @@ -2049,92 +2334,133 @@ err = gpg_error (GPG_ERR_INV_VALUE); goto leave; } + + maxbits = app->app_local->keyattr[keyno].n_bits; nbits = rsa_n? count_bits (rsa_n, rsa_n_len) : 0; - if (nbits != 1024) + if (nbits != maxbits) { - log_error (_("RSA modulus missing or not of size %d bits\n"), 1024); + log_error (_("RSA modulus missing or not of size %d bits\n"), + (int)maxbits); err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; } + + maxbits = app->app_local->keyattr[keyno].e_bits; + if (maxbits > 32 && !app->app_local->extcap.is_v2) + maxbits = 32; /* Our code for v1 does only support 32 bits. */ nbits = rsa_e? count_bits (rsa_e, rsa_e_len) : 0; - if (nbits < 2 || nbits > 32) + if (nbits < 2 || nbits > maxbits) { log_error (_("RSA public exponent missing or larger than %d bits\n"), - 32); + (int)maxbits); err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; } + + maxbits = app->app_local->keyattr[keyno].n_bits/2; nbits = rsa_p? count_bits (rsa_p, rsa_p_len) : 0; - if (nbits != 512) + if (nbits != maxbits) { - log_error (_("RSA prime %s missing or not of size %d bits\n"), "P", 512); + log_error (_("RSA prime %s missing or not of size %d bits\n"), + "P", (int)maxbits); err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; } nbits = rsa_q? count_bits (rsa_q, rsa_q_len) : 0; - if (nbits != 512) + if (nbits != maxbits) { - log_error (_("RSA prime %s missing or not of size %d bits\n"), "Q", 512); + log_error (_("RSA prime %s missing or not of size %d bits\n"), + "Q", (int)maxbits); err = gpg_error (GPG_ERR_BAD_SECKEY); goto leave; } - - /* Build the private key template as described in section 4.3.3.6 of - the OpenPGP card specs: - 0xC0 public exponent - 0xC1 prime p - 0xC2 prime q - */ - assert (rsa_e_len <= 4); - template_len = (1 + 1 + 4 - + 1 + 1 + rsa_p_len - + 1 + 1 + rsa_q_len); - template = tp = xtrymalloc_secure (template_len); - if (!template) - { - err = gpg_error_from_syserror (); - goto leave; - } - *tp++ = 0xC0; - *tp++ = 4; - memcpy (tp, rsa_e, rsa_e_len); - if (rsa_e_len < 4) - { - /* Right justify E. */ - memmove (tp+4-rsa_e_len, tp, rsa_e_len); - memset (tp, 0, 4-rsa_e_len); - } - tp += 4; - - *tp++ = 0xC1; - *tp++ = rsa_p_len; - memcpy (tp, rsa_p, rsa_p_len); - tp += rsa_p_len; - - *tp++ = 0xC2; - *tp++ = rsa_q_len; - memcpy (tp, rsa_q, rsa_q_len); - tp += rsa_q_len; - - assert (tp - template == template_len); - - - /* Obviously we need to remove the cached public key. */ + /* We need to remove the cached public key. */ xfree (app->app_local->pk[keyno].key); app->app_local->pk[keyno].key = NULL; app->app_local->pk[keyno].keylen = 0; app->app_local->pk[keyno].read_done = 0; - /* Prepare for storing the key. */ - err = verify_chv3 (app, pincb, pincb_arg); - if (err) - goto leave; - /* Store the key. */ - err = iso7816_put_data (app->slot, 0, - (app->card_version > 0x0007? 0xE0 : 0xE9) + keyno, - template, template_len); + if (app->app_local->extcap.is_v2) + { + /* Build the private key template as described in section 4.3.3.7 of + the OpenPGP card specs version 2.0. */ + int exmode; + + err = build_privkey_template (app, keyno, + rsa_n, rsa_n_len, + rsa_e, rsa_e_len, + rsa_p, rsa_p_len, + rsa_q, rsa_q_len, + &template, &template_len); + if (err) + goto leave; + + /* Prepare for storing the key. */ + err = verify_chv3 (app, pincb, pincb_arg); + if (err) + goto leave; + + /* Store the key. */ + if (app->app_local->cardcap.cmd_chaining && template_len > 254) + exmode = -254; + else + exmode = 0; + err = iso7816_put_data_odd (app->slot, exmode, 0x3fff, + template, template_len); + } + else + { + /* Build the private key template as described in section 4.3.3.6 of + the OpenPGP card specs version 1.1: + 0xC0 public exponent + 0xC1 prime p + 0xC2 prime q + */ + assert (rsa_e_len <= 4); + template_len = (1 + 1 + 4 + + 1 + 1 + rsa_p_len + + 1 + 1 + rsa_q_len); + template = tp = xtrymalloc_secure (template_len); + if (!template) + { + err = gpg_error_from_syserror (); + goto leave; + } + *tp++ = 0xC0; + *tp++ = 4; + memcpy (tp, rsa_e, rsa_e_len); + if (rsa_e_len < 4) + { + /* Right justify E. */ + memmove (tp+4-rsa_e_len, tp, rsa_e_len); + memset (tp, 0, 4-rsa_e_len); + } + tp += 4; + + *tp++ = 0xC1; + *tp++ = rsa_p_len; + memcpy (tp, rsa_p, rsa_p_len); + tp += rsa_p_len; + + *tp++ = 0xC2; + *tp++ = rsa_q_len; + memcpy (tp, rsa_q, rsa_q_len); + tp += rsa_q_len; + + assert (tp - template == template_len); + + /* Prepare for storing the key. */ + err = verify_chv3 (app, pincb, pincb_arg); + if (err) + goto leave; + + /* Store the key. */ + err = iso7816_put_data (app->slot, 0, + (app->card_version > 0x0007? 0xE0:0xE9)+keyno, + template, template_len); + } if (err) { log_error (_("failed to store the key: %s\n"), gpg_strerror (err)); @@ -2891,8 +3217,8 @@ } -/* Read and parse the algorithm attributes for KEYNO. KEYNO must be - in the range 0..2. */ +/* Parse and optionally show the algorithm attributes for KEYNO. + KEYNO must be in the range 0..2. */ static void parse_algorithm_attribute (app_t app, int keyno) { @@ -2903,6 +3229,8 @@ assert (keyno >=0 && keyno <= 2); + app->app_local->keyattr[keyno].n_bits = 0; + relptr = get_one_do (app, 0xC1+keyno, &buffer, &buflen, NULL); if (!relptr) { @@ -2916,21 +3244,33 @@ return; } - log_info ("Key-Attr-%s ..: ", desc[keyno]); + if (opt.verbose) + log_info ("Key-Attr-%s ..: ", desc[keyno]); if (*buffer == 1 && (buflen == 5 || buflen == 6)) { - log_printf ("RSA, n=%d, e=%d", - (buffer[1]<<8 | buffer[2]), - (buffer[3]<<8 | buffer[4])); - if (buflen == 6) - log_printf (", format=%s", - buffer[5] == 0? "std" : - buffer[5] == 1? "std+n" : - buffer[5] == 2? "crt" : - buffer[5] == 2? "crt+n" : "?"); - log_printf ("\n"); + app->app_local->keyattr[keyno].n_bits = (buffer[1]<<8 | buffer[2]); + app->app_local->keyattr[keyno].e_bits = (buffer[3]<<8 | buffer[4]); + app->app_local->keyattr[keyno].format = 0; + if (buflen < 6) + app->app_local->keyattr[keyno].format = RSA_STD; + else + app->app_local->keyattr[keyno].format = (buffer[5] == 0? RSA_STD : + buffer[5] == 1? RSA_STD_N : + buffer[5] == 2? RSA_CRT : + buffer[5] == 3? RSA_CRT_N : + RSA_UNKNOWN_FMT); + + if (opt.verbose) + log_printf + ("RSA, n=%u, e=%u, fmt=%s\n", + app->app_local->keyattr[keyno].n_bits, + app->app_local->keyattr[keyno].e_bits, + app->app_local->keyattr[keyno].format == RSA_STD? "std" : + app->app_local->keyattr[keyno].format == RSA_STD_N?"std+n": + app->app_local->keyattr[keyno].format == RSA_CRT? "crt" : + app->app_local->keyattr[keyno].format == RSA_CRT_N?"crt+n":"?"); } - else + else if (opt.verbose) log_printhex ("", buffer, buflen); xfree (relptr); @@ -3057,12 +3397,9 @@ if (opt.verbose) show_caps (app->app_local); - if (opt.verbose) - { - parse_algorithm_attribute (app, 0); - parse_algorithm_attribute (app, 1); - parse_algorithm_attribute (app, 2); - } + parse_algorithm_attribute (app, 0); + parse_algorithm_attribute (app, 1); + parse_algorithm_attribute (app, 2); if (opt.verbose > 1) dump_all_do (slot); Modified: trunk/scd/iso7816.c =================================================================== --- trunk/scd/iso7816.c 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/scd/iso7816.c 2008-09-25 10:06:02 UTC (rev 4835) @@ -1,5 +1,5 @@ /* iso7816.c - ISO 7816 commands - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2003, 2004, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -335,6 +335,7 @@ if (!newchv || !newchvlen ) return gpg_error (GPG_ERR_INV_VALUE); + /* FIXME: The keypad mode has not yet been tested. */ if (pininfo && pininfo->mode) sw = apdu_send_simple_kp (slot, 0x00, CMD_RESET_RETRY_COUNTER, 2, chvno, newchvlen, newchv, @@ -350,6 +351,21 @@ gpg_error_t +iso7816_reset_retry_counter_with_rc (int slot, int chvno, + const char *data, size_t datalen) +{ + int sw; + + if (!data || !datalen ) + return gpg_error (GPG_ERR_INV_VALUE); + + sw = apdu_send_simple (slot, 0, 0x00, CMD_RESET_RETRY_COUNTER, + 0, chvno, datalen, data); + return map_sw (sw); +} + + +gpg_error_t iso7816_reset_retry_counter (int slot, int chvno, const char *newchv, size_t newchvlen) { @@ -404,6 +420,19 @@ return map_sw (sw); } +/* Same as iso7816_put_data but uses an odd instrcution byte. */ +gpg_error_t +iso7816_put_data_odd (int slot, int extended_mode, int tag, + const unsigned char *data, size_t datalen) +{ + int sw; + + sw = apdu_send_simple (slot, extended_mode, 0x00, CMD_PUT_DATA+1, + ((tag >> 8) & 0xff), (tag & 0xff), + datalen, (const char*)data); + return map_sw (sw); +} + /* Manage Security Environment. This is a weird operation and there is no easy abstraction for it. Furthermore, some card seem to have a different interpreation of 7816-8 and thus we resort to let the Modified: trunk/scd/iso7816.h =================================================================== --- trunk/scd/iso7816.h 2008-09-25 04:00:36 UTC (rev 4834) +++ trunk/scd/iso7816.h 2008-09-25 10:06:02 UTC (rev 4835) @@ -77,10 +77,15 @@ const char *newchv, size_t newchvlen, iso7816_pininfo_t *pininfo); +gpg_error_t iso7816_reset_retry_counter_with_rc (int slot, int chvno, + const char *data, + size_t datalen); gpg_error_t iso7816_get_data (int slot, int tag, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_put_data (int slot, int extended_mode, int tag, const unsigned char *data, size_t datalen); +gpg_error_t iso7816_put_data_odd (int slot, int extended_mode, int tag, + const unsigned char *data, size_t datalen); gpg_error_t iso7816_manage_security_env (int slot, int p1, int p2, const unsigned char *data, size_t datalen); From cvs at cvs.gnupg.org Thu Sep 25 14:55:51 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 25 Sep 2008 14:55:51 +0200 Subject: [svn] GnuPG - r4836 - trunk/g10 Message-ID: Author: wk Date: 2008-09-25 14:55:50 +0200 (Thu, 25 Sep 2008) New Revision: 4836 Modified: trunk/g10/ChangeLog trunk/g10/parse-packet.c Log: Fix bug #931 Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-09-25 10:06:02 UTC (rev 4835) +++ trunk/g10/ChangeLog 2008-09-25 12:55:50 UTC (rev 4836) @@ -1,5 +1,8 @@ 2008-09-25 Werner Koch + * parse-packet.c (parse): Remove special treatment for compressed + new style packets. Fixes bug#931. + * card-util.c (change_pin): Support setting of the reset code. 2008-09-24 Werner Koch Modified: trunk/g10/parse-packet.c =================================================================== --- trunk/g10/parse-packet.c 2008-09-25 10:06:02 UTC (rev 4835) +++ trunk/g10/parse-packet.c 2008-09-25 12:55:50 UTC (rev 4836) @@ -395,12 +395,20 @@ rc = gpg_error (GPG_ERR_INV_PACKET); goto leave; } - if (pkttype == PKT_COMPRESSED) { - iobuf_set_partial_block_mode(inp, c & 0xff); - pktlen = 0;/* to indicate partial length */ - partial=1; - } - else { + +/* The follwing code has been here for ages (2002-08-30) but it is + clearly wrong: For example passing a 0 as second argument to + iobuf_set_partial_block_mode stops the partial block mode which we + definitely do not want. Also all values < 224 or 255 are not + valid. Let's disable it and put PKT_COMPRESSED into the list of + allowed packets with partial header until someone complains. */ +/* if (pkttype == PKT_COMPRESSED) { */ +/* iobuf_set_partial_block_mode(inp, c & 0xff); */ +/* pktlen = 0; /\* to indicate partial length *\/ */ +/* partial=1; */ +/* } */ +/* else */ + { hdr[hdrlen++] = c; if( c < 192 ) pktlen = c; @@ -433,19 +441,21 @@ } else { - /* Partial body length. Note that we handled - PKT_COMPRESSED earlier. */ - if(pkttype==PKT_PLAINTEXT || pkttype==PKT_ENCRYPTED - || pkttype==PKT_ENCRYPTED_MDC) - { + /* Partial body length. */ + switch (pkttype) + { + case PKT_PLAINTEXT: + case PKT_ENCRYPTED: + case PKT_ENCRYPTED_MDC: + case PKT_COMPRESSED: iobuf_set_partial_block_mode(inp, c & 0xff); - pktlen = 0;/* to indicate partial length */ + pktlen = 0;/* To indicate partial length. */ partial=1; - } - else - { + break; + + default: log_error("%s: partial length for invalid" - " packet type %d\n",iobuf_where(inp),pkttype); + " packet type %d\n", iobuf_where(inp),pkttype); rc = gpg_error (GPG_ERR_INV_PACKET); goto leave; } From cvs at cvs.gnupg.org Thu Sep 25 20:12:39 2008 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 25 Sep 2008 20:12:39 +0200 Subject: [svn] GnuPG - r4837 - trunk/g10 Message-ID: Author: dshaw Date: 2008-09-25 20:12:39 +0200 (Thu, 25 Sep 2008) New Revision: 4837 Modified: trunk/g10/ChangeLog trunk/g10/keyedit.c Log: * keyedit.c (keyedit_menu): Fix bug where a modified keyring loses its modified status after a "clean" or "minimize" that doesn't need to do anything. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-09-25 12:55:50 UTC (rev 4836) +++ trunk/g10/ChangeLog 2008-09-25 18:12:39 UTC (rev 4837) @@ -1,3 +1,9 @@ +2008-09-25 David Shaw + + * keyedit.c (keyedit_menu): Fix bug where a modified keyring loses + its modified status after a "clean" or "minimize" that doesn't + need to do anything. + 2008-09-25 Werner Koch * parse-packet.c (parse): Remove special treatment for compressed Modified: trunk/g10/keyedit.c =================================================================== --- trunk/g10/keyedit.c 2008-09-25 12:55:50 UTC (rev 4836) +++ trunk/g10/keyedit.c 2008-09-25 18:12:39 UTC (rev 4837) @@ -2200,11 +2200,13 @@ break; case cmdCLEAN: - redisplay=modified=menu_clean(keyblock,0); + if(menu_clean(keyblock,0)) + redisplay=modified=1; break; case cmdMINIMIZE: - redisplay=modified=menu_clean(keyblock,1); + if(menu_clean(keyblock,1)) + redisplay=modified=1; break; case cmdQUIT: From cvs at cvs.gnupg.org Thu Sep 25 22:38:00 2008 From: cvs at cvs.gnupg.org (cvs user werner) Date: Thu, 25 Sep 2008 22:38:00 +0200 Subject: misc-scripts (ChangeLog mkdiff sks-stats.sh) Message-ID: Date: Thursday, September 25, 2008 @ 22:38:00 Author: werner Path: /cvs/wk/misc-scripts Added: sks-stats.sh Modified: ChangeLog mkdiff Add SKS server stat tool From cvs at cvs.gnupg.org Sun Sep 28 14:48:42 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Sun, 28 Sep 2008 14:48:42 +0200 Subject: [svn] GnuPG - r4838 - trunk/scd Message-ID: Author: marcus Date: 2008-09-28 14:48:41 +0200 (Sun, 28 Sep 2008) New Revision: 4838 Modified: trunk/scd/ChangeLog trunk/scd/apdu.c Log: 2008-09-28 Marcus Brinkmann * apdu.c (pcsc_get_status): Fix last change. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-09-25 18:12:39 UTC (rev 4837) +++ trunk/scd/ChangeLog 2008-09-28 12:48:41 UTC (rev 4838) @@ -1,3 +1,7 @@ +2008-09-28 Marcus Brinkmann + + * apdu.c (pcsc_get_status): Fix last change. + 2008-09-25 Werner Koch * app-openpgp.c (do_setattr): Do not allow setting of the reset Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2008-09-25 18:12:39 UTC (rev 4837) +++ trunk/scd/apdu.c 2008-09-28 12:48:41 UTC (rev 4838) @@ -1092,8 +1092,8 @@ #else /* Some winscard drivers may set EXCLUSIVE and INUSE at the same time when we are the only user (SCM SCR335) under Windows. */ - if ((status & 6) == 6) - status |= 1; + if ((*status & 6) == 6) + *status |= 1; #endif return 0; From cvs at cvs.gnupg.org Mon Sep 29 17:02:56 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 29 Sep 2008 17:02:56 +0200 Subject: [svn] GnuPG - r4839 - in trunk: . agent g10 jnlib scd sm Message-ID: Author: wk Date: 2008-09-29 17:02:55 +0200 (Mon, 29 Sep 2008) New Revision: 4839 Modified: trunk/ChangeLog trunk/NEWS trunk/TODO trunk/agent/ChangeLog trunk/agent/agent.h trunk/agent/command.c trunk/agent/divert-scd.c trunk/agent/pksign.c trunk/configure.ac trunk/g10/ChangeLog trunk/g10/gpg.c trunk/g10/options.skel trunk/g10/seskey.c trunk/g10/sign.c trunk/g10/skclist.c trunk/jnlib/ChangeLog trunk/jnlib/argparse.c trunk/jnlib/argparse.h trunk/jnlib/libjnlib-config.h trunk/scd/ChangeLog trunk/scd/app-p15.c trunk/scd/scdaemon.h trunk/sm/ChangeLog trunk/sm/certcheck.c trunk/sm/certreqgen-ui.c trunk/sm/gpgsm.c trunk/sm/sign.c Log: Remove hacks which are not anymore needed since we now require Libgcrypt 1.4 Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/ChangeLog 2008-09-29 15:02:55 UTC (rev 4839) @@ -1,3 +1,7 @@ +2008-09-29 Werner Koch + + * configure.ac: Require libgcrypt 1.4. + 2008-08-27 David Shaw * configure.ac: Use printf for the most portable SVN version Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/agent/ChangeLog 2008-09-29 15:02:55 UTC (rev 4839) @@ -1,3 +1,9 @@ +2008-09-29 Werner Koch + + * agent.h (GCRY_MD_USER): Rename to GCRY_MODULE_ID_USER. + (GCRY_MD_USER_TLS_MD5SHA1): Rename to MD_USER_TLS_MD5SHA1 and + change all users. + 2008-09-25 Werner Koch * divert-scd.c (getpin_cb): Support a Reset Code style PINs.. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/g10/ChangeLog 2008-09-29 15:02:55 UTC (rev 4839) @@ -1,3 +1,14 @@ +2008-09-29 Werner Koch + + * gpg.c (main): Remove -sat kludge. Note that we printed a + warning for two years. + + * seskey.c (encode_md_value): Remove extra gcry_md_test_algo since + it is not needed with Libgcrypt 1.4. + * skclist.c (random_is_faked): Simplify. + * sign.c (match_dsa_hash): Remove runtime check for SHA224. + * gpg.c (print_mds): Use GCRY_MD_SHA224 constant. + 2008-09-25 David Shaw * keyedit.c (keyedit_menu): Fix bug where a modified keyring loses Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/jnlib/ChangeLog 2008-09-29 15:02:55 UTC (rev 4839) @@ -1,3 +1,10 @@ +2008-09-29 Werner Koch + + * argparse.c (ARGERR_): Use constants for error values. + (optfile_parse): Prettify. Replace xmalloc and xrealloc by malloc + and realloc. + * libjnlib-config.h (jnlib_strdup, jnlib_realloc): New. + 2008-06-26 Werner Koch * stringhelp.c (print_sanitized_buffer2): Loose check for control Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/scd/ChangeLog 2008-09-29 15:02:55 UTC (rev 4839) @@ -1,3 +1,9 @@ +2008-09-29 Werner Koch + + * scdaemon.h (GCRY_MD_USER): Rename to GCRY_MODULE_ID_USER. + (GCRY_MD_USER_TLS_MD5SHA1): Rename to MD_USER_TLS_MD5SHA1 and + change all users. + 2008-09-28 Marcus Brinkmann * apdu.c (pcsc_get_status): Fix last change. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/sm/ChangeLog 2008-09-29 15:02:55 UTC (rev 4839) @@ -1,3 +1,10 @@ +2008-09-29 Werner Koch + + * certcheck.c (MY_GCRY_PK_ECDSA): Remove. Change users to + GCRY_PK_ECDSA. + * gpgsm.c (MY_GCRY_PK_ECDSA): Ditto. + * sign.c (MY_GCRY_MD_SHA224): Remove change users to GCRY_MD_SHA224. + 2008-09-04 Werner Koch * certdump.c (gpgsm_format_keydesc): Work around a mingw32 bug. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/NEWS 2008-09-29 15:02:55 UTC (rev 4839) @@ -16,6 +16,8 @@ * [gpg] New options --with-sig-list and --with-sig-check. + * [gpg] The option "-sat" is no longer an alias for --clearsign. + * [gpgsm] Made --output option work with --export-secret-key-p12. * gpg-connect-agent accepts commands given as command line arguments. @@ -33,7 +35,9 @@ * Support for version 2 OpenPGP cards. + * Libgcrypt 1.4 is now required. + Noteworthy changes in version 2.0.9 (2008-03-26) ------------------------------------------------ Modified: trunk/TODO =================================================================== --- trunk/TODO 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/TODO 2008-09-29 15:02:55 UTC (rev 4839) @@ -51,7 +51,7 @@ * sm/export.c ** Return an error code or a status info per user ID. -* scd/tlv.c +* common/tlv.c The parse_sexp function should not go into this file. Check whether we can change all S-expression handling code to make use of this function. @@ -85,33 +85,13 @@ Replace by an estream based implementation. * jnlib/ -** provide jnlib_malloc and try to remove all jnlib_xmalloc. +** Try to remove all jnlib_xmalloc. * g10/ ** issue a NO_SECKEY xxxx if a -u key was not found. - -* When switching to libgcrypt 1.4 -** scd#encode_md_for_card, g10#encode_md_value, sm at do_encode_md - Remove the extra test for a valid algorithm as libgcrypt will do it - then in gcry_md_algo_info. -** skclist.c - Remove the hard coded constant in random_is_faked. -** g10/ Replace DIGEST_ALGO_SHA224 - We can't do that right now because it is only defined by newer - versions of libgcrypt. -** GCRY_MD_USER - Remove these definitions. -** MY_GCRY_PK_ECDSA - Remove this. -** MY_GCRY_MD_SHA224 - Remove this. - - * Extend selinux support to other modules -* Remove -sat PGP2 compatibility hack - * UTF-8 specific TODOs None. Modified: trunk/agent/agent.h =================================================================== --- trunk/agent/agent.h 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/agent/agent.h 2008-09-29 15:02:55 UTC (rev 4839) @@ -36,10 +36,10 @@ /* To convey some special hash algorithms we use algorithm numbers reserved for application use. */ -#ifndef GCRY_MD_USER -#define GCRY_MD_USER 1024 +#ifndef GCRY_MODULE_ID_USER +#define GCRY_MODULE_ID_USER 1024 #endif -#define GCRY_MD_USER_TLS_MD5SHA1 (GCRY_MD_USER+1) +#define MD_USER_TLS_MD5SHA1 (GCRY_MODULE_ID_USER+1) /* Maximum length of a digest. */ #define MAX_DIGEST_LEN 36 Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/agent/command.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -597,7 +597,7 @@ else if (has_option (line, "--hash=md5")) algo = GCRY_MD_MD5; else if (has_option (line, "--hash=tls-md5sha1")) - algo = GCRY_MD_USER_TLS_MD5SHA1; + algo = MD_USER_TLS_MD5SHA1; else return set_error (GPG_ERR_ASS_PARAMETER, "invalid hash algorithm"); } @@ -622,7 +622,7 @@ if (rc) return rc; n /= 2; - if (algo == GCRY_MD_USER_TLS_MD5SHA1 && n == 36) + if (algo == MD_USER_TLS_MD5SHA1 && n == 36) ; else if (n != 16 && n != 20 && n != 24 && n != 32) return set_error (GPG_ERR_ASS_PARAMETER, "unsupported length of hash"); Modified: trunk/agent/divert-scd.c =================================================================== --- trunk/agent/divert-scd.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/agent/divert-scd.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -335,7 +335,7 @@ if (rc) return rc; - if (algo == GCRY_MD_USER_TLS_MD5SHA1) + if (algo == MD_USER_TLS_MD5SHA1) { int save = ctrl->use_auth_call; ctrl->use_auth_call = 1; Modified: trunk/agent/pksign.c =================================================================== --- trunk/agent/pksign.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/agent/pksign.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -181,7 +181,7 @@ gcry_sexp_t s_hash = NULL; /* Put the hash into a sexp */ - if (ctrl->digest.algo == GCRY_MD_USER_TLS_MD5SHA1) + if (ctrl->digest.algo == MD_USER_TLS_MD5SHA1) rc = do_encode_raw_pkcs1 (ctrl->digest.value, ctrl->digest.valuelen, gcry_pk_get_nbits (s_skey), Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/configure.ac 2008-09-29 15:02:55 UTC (rev 4839) @@ -39,7 +39,7 @@ NEED_GPG_ERROR_VERSION=1.4 NEED_LIBGCRYPT_API=1 -NEED_LIBGCRYPT_VERSION=1.2.2 +NEED_LIBGCRYPT_VERSION=1.4.0 NEED_LIBASSUAN_API=1 NEED_LIBASSUAN_VERSION=1.0.4 Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/g10/gpg.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -1,6 +1,6 @@ /* gpg.c - The GnuPG utility (main for gpg) * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006, 2007 Free Software Foundation, Inc. + * 2006, 2007, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -3285,15 +3285,6 @@ set_cmd( &cmd, aListKeys); } - /* kludge to let -sat generate a clear text signature */ - if( opt.textmode == 2 && !detached_sig && opt.armor && cmd == aSign ) - { - log_info ("compatibility note:\n"); - log_info ("\"-sat\" won't generate clear signed messages in " - "future versions\n"); - log_info ("Use \"--clearsign\" instead of \"-sat\"\n"); - cmd = aClearsign; - } if( opt.verbose > 1 ) set_packet_list_mode(1); @@ -4155,8 +4146,8 @@ gcry_md_enable (md, GCRY_MD_MD5); gcry_md_enable (md, GCRY_MD_SHA1); gcry_md_enable (md, GCRY_MD_RMD160); - if (!openpgp_md_test_algo (DIGEST_ALGO_SHA224)) - gcry_md_enable (md, DIGEST_ALGO_SHA224); + if (!openpgp_md_test_algo (GCRY_MD_SHA224)) + gcry_md_enable (md, GCRY_MD_SHA224); if (!openpgp_md_test_algo (GCRY_MD_SHA256)) gcry_md_enable (md, GCRY_MD_SHA256); if (!openpgp_md_test_algo (GCRY_MD_SHA384)) @@ -4178,8 +4169,8 @@ print_hashline( md, GCRY_MD_MD5, fname ); print_hashline( md, GCRY_MD_SHA1, fname ); print_hashline( md, GCRY_MD_RMD160, fname ); - if (!gcry_md_test_algo (DIGEST_ALGO_SHA224)) - print_hashline (md, DIGEST_ALGO_SHA224, fname); + if (!gcry_md_test_algo (GCRY_MD_SHA224)) + print_hashline (md, GCRY_MD_SHA224, fname); if (!gcry_md_test_algo (GCRY_MD_SHA256)) print_hashline( md, GCRY_MD_SHA256, fname ); if (!gcry_md_test_algo (GCRY_MD_SHA384)) @@ -4195,8 +4186,8 @@ print_hex( md, GCRY_MD_MD5, fname ); print_hex( md, GCRY_MD_SHA1, fname ); print_hex( md, GCRY_MD_RMD160, fname ); - if (!gcry_md_test_algo (DIGEST_ALGO_SHA224)) - print_hex (md, DIGEST_ALGO_SHA224, fname); + if (!gcry_md_test_algo (GCRY_MD_SHA224)) + print_hex (md, GCRY_MD_SHA224, fname); if (!gcry_md_test_algo (GCRY_MD_SHA256)) print_hex( md, GCRY_MD_SHA256, fname ); if (!gcry_md_test_algo (GCRY_MD_SHA384)) Modified: trunk/g10/options.skel =================================================================== --- trunk/g10/options.skel 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/g10/options.skel 2008-09-29 15:02:55 UTC (rev 4839) @@ -128,6 +128,7 @@ # the "--keyserver-options debug". keyserver hkp://keys.gnupg.net +#keyserver http://http-keys.gnupg.net #keyserver mailto:pgp-public-keys at keys.nl.pgp.net #keyserver ldap://pgp.surfnet.nl:11370 #keyserver ldap://keyserver.pgp.com Modified: trunk/g10/seskey.c =================================================================== --- trunk/g10/seskey.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/g10/seskey.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -265,11 +265,9 @@ byte *asn; size_t asnlen; - rc = gcry_md_test_algo (hash_algo); - if (!rc) - rc = gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, NULL, &asnlen); + rc = gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, NULL, &asnlen); if (rc) - log_fatal ("can't get OID of algo %d: %s\n", + log_fatal ("can't get OID of digest algorithm %d: %s\n", hash_algo, gpg_strerror (rc)); asn = xmalloc (asnlen); if ( gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, asn, &asnlen) ) Modified: trunk/g10/sign.c =================================================================== --- trunk/g10/sign.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/g10/sign.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -346,9 +346,7 @@ if (qbytes <= 20) return DIGEST_ALGO_SHA1; - /* SHA244 is only available with libgcrypt 1.4 - thus do a runtime - test. */ - if (qbytes <= 28 && !gcry_md_test_algo (DIGEST_ALGO_SHA224)) + if (qbytes <= 28) return DIGEST_ALGO_SHA224; if (qbytes <= 32) Modified: trunk/g10/skclist.c =================================================================== --- trunk/g10/skclist.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/g10/skclist.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -41,18 +41,7 @@ int random_is_faked (void) { - /* We use a runtime check to allow for slow migrattion of libgcrypt. - We can't use the constant becuase that one is actually an enum - value. */ - gpg_error_t err = gcry_control ( 51 /*GCRYCTL_FAKED_RANDOM_P*/, 0); - - if (!err) - return 0; - if (gpg_err_code (err) != GPG_ERR_INV_OP) - return 1; - log_info ("WARNING: libgcrypt too old.\n"); - log_info (" can't check whether we are in faked RNG mode\n"); - return 0; /* Need to return false. */ + return !!gcry_control ( GCRYCTL_FAKED_RANDOM_P, 0); } Modified: trunk/jnlib/argparse.c =================================================================== --- trunk/jnlib/argparse.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/jnlib/argparse.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -34,6 +34,7 @@ #include "argparse.h" + /********************************* * @Summary arg_parse * #include @@ -172,18 +173,20 @@ if (filename) { - if ( arg->r_opt == -6 ) + if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG ) s = _("argument not expected"); - else if ( arg->r_opt == -5 ) + else if ( arg->r_opt == ARGPARSE_READ_ERROR ) s = _("read error"); - else if ( arg->r_opt == -4 ) + else if ( arg->r_opt == ARGPARSE_KEYWORD_TOO_LONG ) s = _("keyword too long"); - else if ( arg->r_opt == -3 ) + else if ( arg->r_opt == ARGPARSE_MISSING_ARG ) s = _("missing argument"); - else if ( arg->r_opt == -7 ) + else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND ) s = _("invalid command"); - else if ( arg->r_opt == -10 ) + else if ( arg->r_opt == ARGPARSE_INVALID_ALIAS ) s = _("invalid alias definition"); + else if ( arg->r_opt == ARGPARSE_OUT_OF_CORE ) + s = _("out of core"); else s = _("invalid option"); jnlib_log_error ("%s:%u: %s\n", filename, *lineno, s); @@ -192,17 +195,19 @@ { s = arg->internal.last? arg->internal.last:"[??]"; - if ( arg->r_opt == -3 ) + if ( arg->r_opt == ARGPARSE_MISSING_ARG ) jnlib_log_error (_("missing argument for option \"%.50s\"\n"), s); - else if ( arg->r_opt == -6 ) + else if ( arg->r_opt == ARGPARSE_UNEXPECTED_ARG ) jnlib_log_error (_("option \"%.50s\" does not expect an " "argument\n"), s ); - else if ( arg->r_opt == -7 ) + else if ( arg->r_opt == ARGPARSE_INVALID_COMMAND ) jnlib_log_error (_("invalid command \"%.50s\"\n"), s); - else if ( arg->r_opt == -8 ) + else if ( arg->r_opt == ARGPARSE_AMBIGUOUS_OPTION ) jnlib_log_error (_("option \"%.50s\" is ambiguous\n"), s); - else if ( arg->r_opt == -9 ) + else if ( arg->r_opt == ARGPARSE_AMBIGUOUS_OPTION ) jnlib_log_error (_("command \"%.50s\" is ambiguous\n"),s ); + else if ( arg->r_opt == ARGPARSE_OUT_OF_CORE ) + jnlib_log_error ("%s\n", _("out of core\n")); else jnlib_log_error (_("invalid option \"%.50s\"\n"), s); } @@ -251,181 +256,246 @@ * Note: Abbreviation of options is here not allowed. */ int -optfile_parse( FILE *fp, const char *filename, unsigned *lineno, +optfile_parse (FILE *fp, const char *filename, unsigned *lineno, ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) { - int state, i, c; - int idx=0; - char keyword[100]; - char *buffer = NULL; - size_t buflen = 0; - int inverse=0; - int in_alias=0; + int state, i, c; + int idx=0; + char keyword[100]; + char *buffer = NULL; + size_t buflen = 0; + int in_alias=0; + + if (!fp) /* Divert to to arg_parse() in this case. */ + return arg_parse (arg, opts); + + initialize (arg, filename, lineno); - if( !fp ) /* same as arg_parse() in this case */ - return arg_parse( arg, opts ); + /* Find the next keyword. */ + state = i = 0; + for (;;) + { + c = getc (fp); + if (c == '\n' || c== EOF ) + { + if ( c != EOF ) + ++*lineno; + if (state == -1) + break; + else if (state == 2) + { + keyword[i] = 0; + for (i=0; opts[i].short_opt; i++ ) + { + if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword)) + break; + } + idx = i; + arg->r_opt = opts[idx].short_opt; + if (!opts[idx].short_opt ) + arg->r_opt = ((opts[idx].flags & 256) + ? ARGPARSE_INVALID_COMMAND + : ARGPARSE_INVALID_OPTION); + else if (!(opts[idx].flags & 7)) + arg->r_type = 0; /* Does not take an arg. */ + else if ((opts[idx].flags & 8) ) + arg->r_type = 0; /* Arg is optional. */ + else + arg->r_opt = ARGPARSE_MISSING_ARG; - initialize( arg, filename, lineno ); + break; + } + else if (state == 3) + { + /* No argument found. */ + if (in_alias) + arg->r_opt = ARGPARSE_MISSING_ARG; + else if (!(opts[idx].flags & 7)) + arg->r_type = 0; /* Does not take an arg. */ + else if ((opts[idx].flags & 8)) + arg->r_type = 0; /* No optional argument. */ + else + arg->r_opt = ARGPARSE_MISSING_ARG; - /* find the next keyword */ - state = i = 0; - for(;;) { - c=getc(fp); - if( c == '\n' || c== EOF ) { - if( c != EOF ) - ++*lineno; - if( state == -1 ) - break; - else if( state == 2 ) { - keyword[i] = 0; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - break; - idx = i; - arg->r_opt = opts[idx].short_opt; - if( inverse ) /* this does not have an effect, hmmm */ - arg->r_opt = -arg->r_opt; - if( !opts[idx].short_opt ) /* unknown command/option */ - arg->r_opt = (opts[idx].flags & 256)? -7:-2; - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_type = 0; /* okay */ - else if( (opts[idx].flags & 8) ) /* argument is optional */ - arg->r_type = 0; /* okay */ - else /* required argument */ - arg->r_opt = -3; /* error */ - break; + break; } - else if( state == 3 ) { /* no argument found */ - if( in_alias ) - arg->r_opt = -3; /* error */ - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_type = 0; /* okay */ - else if( (opts[idx].flags & 8) ) /* no optional argument */ - arg->r_type = 0; /* okay */ - else /* no required argument */ - arg->r_opt = -3; /* error */ - break; - } - else if( state == 4 ) { /* have an argument */ - if( in_alias ) { - if( !buffer ) - arg->r_opt = -6; - else { - char *p; - - buffer[i] = 0; - p = strpbrk( buffer, " \t" ); - if( p ) { - *p++ = 0; - trim_spaces( p ); + else if (state == 4) + { + /* Has an argument. */ + if (in_alias) + { + if (!buffer) + arg->r_opt = ARGPARSE_UNEXPECTED_ARG; + else + { + char *p; + + buffer[i] = 0; + p = strpbrk (buffer, " \t"); + if (p) + { + *p++ = 0; + trim_spaces (p); } - if( !p || !*p ) { - jnlib_free( buffer ); - arg->r_opt = -10; - } - else { - store_alias( arg, buffer, p ); - } + if (!p || !*p) + { + jnlib_free (buffer); + arg->r_opt = ARGPARSE_INVALID_ALIAS; + } + else + { + store_alias (arg, buffer, p); + } } } - else if( !(opts[idx].flags & 7) ) /* does not take an arg */ - arg->r_opt = -6; /* error */ - else { - char *p; - if( !buffer ) { - keyword[i] = 0; - buffer = jnlib_xstrdup(keyword); - } - else - buffer[i] = 0; + else if (!(opts[idx].flags & 7)) + arg->r_opt = ARGPARSE_UNEXPECTED_ARG; + else + { + char *p; - trim_spaces( buffer ); - p = buffer; - if( *p == '"' ) { /* remove quotes */ - p++; - if( *p && p[strlen(p)-1] == '"' ) - p[strlen(p)-1] = 0; + if (!buffer) + { + keyword[i] = 0; + buffer = jnlib_strdup (keyword); + if (!buffer) + arg->r_opt = ARGPARSE_OUT_OF_CORE; } - if( !set_opt_arg(arg, opts[idx].flags, p) ) + else + buffer[i] = 0; + + if (buffer) + { + trim_spaces (buffer); + p = buffer; + if (*p == '"') + { + /* Remove quotes. */ + p++; + if (*p && p[strlen(p)-1] == '\"' ) + p[strlen(p)-1] = 0; + } + if (!set_opt_arg (arg, opts[idx].flags, p)) jnlib_free(buffer); - } - break; - } - else if( c == EOF ) { - if( ferror(fp) ) - arg->r_opt = -5; /* read error */ - else - arg->r_opt = 0; /* eof */ - break; - } - state = 0; - i = 0; - } - else if( state == -1 ) - ; /* skip */ - else if( !state && isspace(c) ) - ; /* skip leading white space */ - else if( !state && c == '#' ) - state = 1; /* start of a comment */ - else if( state == 1 ) - ; /* skip comments */ - else if( state == 2 && isspace(c) ) { - keyword[i] = 0; - for(i=0; opts[i].short_opt; i++ ) - if( opts[i].long_opt && !strcmp( opts[i].long_opt, keyword) ) - break; - idx = i; - arg->r_opt = opts[idx].short_opt; - if( !opts[idx].short_opt ) { - if( !strcmp( keyword, "alias" ) ) { - in_alias = 1; - state = 3; - } - else { - arg->r_opt = (opts[idx].flags & 256)? -7:-2; - state = -1; /* skip rest of line and leave */ - } - } - else - state = 3; - } - else if( state == 3 ) { /* skip leading spaces of the argument */ - if( !isspace(c) ) { - i = 0; - keyword[i++] = c; - state = 4; - } - } - else if( state == 4 ) { /* collect the argument */ - if( buffer ) { - if( i < buflen-1 ) - buffer[i++] = c; - else { - buflen += 50; - buffer = jnlib_xrealloc(buffer, buflen); - buffer[i++] = c; - } - } - else if( i < DIM(keyword)-1 ) - keyword[i++] = c; - else { - buflen = DIM(keyword)+50; - buffer = jnlib_xmalloc(buflen); - memcpy(buffer, keyword, i); - buffer[i++] = c; - } - } - else if( i >= DIM(keyword)-1 ) { - arg->r_opt = -4; /* keyword to long */ - state = -1; /* skip rest of line and leave */ - } - else { - keyword[i++] = c; - state = 2; - } + } + } + break; + } + else if (c == EOF) + { + if (ferror (fp)) + arg->r_opt = ARGPARSE_READ_ERROR; + else + arg->r_opt = 0; /* EOF. */ + break; + } + state = 0; + i = 0; + } + else if (state == -1) + ; /* Skip. */ + else if (state == 0 && isascii (c) && isspace(c)) + ; /* Skip leading white space. */ + else if (state == 0 && c == '#' ) + state = 1; /* Start of a comment. */ + else if (state == 1) + ; /* Skip comments. */ + else if (state == 2 && isascii (c) && isspace(c)) + { + /* Check keyword. */ + keyword[i] = 0; + for (i=0; opts[i].short_opt; i++ ) + if (opts[i].long_opt && !strcmp (opts[i].long_opt, keyword)) + break; + idx = i; + arg->r_opt = opts[idx].short_opt; + if (!opts[idx].short_opt) + { + if (!strcmp (keyword, "alias")) + { + in_alias = 1; + state = 3; + } + else + { + arg->r_opt = ((opts[idx].flags & 256) + ? ARGPARSE_INVALID_COMMAND + : ARGPARSE_INVALID_OPTION); + state = -1; /* Skip rest of line and leave. */ + } + } + else + state = 3; + } + else if (state == 3) + { + /* Skip leading spaces of the argument. */ + if (!isascii (c) || !isspace(c)) + { + i = 0; + keyword[i++] = c; + state = 4; + } + } + else if (state == 4) + { + /* Collect the argument. */ + if (buffer) + { + if (i < buflen-1) + buffer[i++] = c; + else + { + char *tmp; + size_t tmplen = buflen + 50; + + tmp = jnlib_realloc (buffer, tmplen); + if (tmp) + { + buflen = tmplen; + buffer = tmp; + buffer[i++] = c; + } + else + { + jnlib_free (buffer); + arg->r_opt = ARGPARSE_OUT_OF_CORE; + break; + } + } + } + else if (i < DIM(keyword)-1) + keyword[i++] = c; + else + { + size_t tmplen = DIM(keyword) + 50; + buffer = jnlib_malloc (tmplen); + if (buffer) + { + buflen = tmplen; + memcpy(buffer, keyword, i); + buffer[i++] = c; + } + else + { + arg->r_opt = ARGPARSE_OUT_OF_CORE; + break; + } + } + } + else if (i >= DIM(keyword)-1) + { + arg->r_opt = ARGPARSE_KEYWORD_TOO_LONG; + state = -1; /* Skip rest of line and leave. */ + } + else + { + keyword[i++] = c; + state = 2; + } } - - return arg->r_opt; + + return arg->r_opt; } @@ -504,7 +574,7 @@ arg->internal.last = s; if( arg->internal.stopped && (arg->flags & (1<<1)) ) { - arg->r_opt = -1; /* not an option but a argument */ + arg->r_opt = ARGPARSE_IS_ARG; /* Not an option but an argument. */ arg->r_type = 2; arg->r.ret_str = s; argc--; argv++; idx++; /* set to next one */ @@ -551,10 +621,10 @@ exit(0); } - if( i == -2 ) /* ambiguous option */ - arg->r_opt = -8; + if( i == -2 ) + arg->r_opt = ARGPARSE_AMBIGUOUS_OPTION; else if( i == -1 ) { - arg->r_opt = -2; + arg->r_opt = ARGPARSE_INVALID_OPTION; arg->r.ret_str = s+2; } else @@ -573,7 +643,7 @@ arg->r_type = 0; /* because it is optional */ } else if( !s2 ) { - arg->r_opt = -3; /* missing argument */ + arg->r_opt = ARGPARSE_MISSING_ARG; } else if( !argpos && *s2 == '-' && (opts[i].flags & 8) ) { /* the argument is optional and the next seems to be @@ -622,7 +692,8 @@ arg->r_opt = opts[i].short_opt; if( !opts[i].short_opt ) { - arg->r_opt = (opts[i].flags & 256)? -7:-2; + arg->r_opt = (opts[i].flags & 256)? + ARGPARSE_INVALID_COMMAND:ARGPARSE_INVALID_OPTION; arg->internal.inarg++; /* point to the next arg */ arg->r.ret_str = s; } @@ -637,7 +708,7 @@ arg->r_type = 0; /* because it is optional */ } else if( !s2 ) { - arg->r_opt = -3; /* missing argument */ + arg->r_opt = ARGPARSE_MISSING_ARG; } else if( *s2 == '-' && s2[1] && (opts[i].flags & 8) ) { /* the argument is optional and the next seems to be @@ -662,7 +733,7 @@ } } else if( arg->flags & (1<<2) ) { - arg->r_opt = -1; /* not an option but a argument */ + arg->r_opt = ARGPARSE_IS_ARG; arg->r_type = 2; arg->r.ret_str = s; argc--; argv++; idx++; /* set to next one */ Modified: trunk/jnlib/argparse.h =================================================================== --- trunk/jnlib/argparse.h 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/jnlib/argparse.h 2008-09-29 15:02:55 UTC (rev 4839) @@ -55,7 +55,20 @@ } ARGPARSE_OPTS; +/* Error values. */ +#define ARGPARSE_IS_ARG (-1) +#define ARGPARSE_INVALID_OPTION (-2) +#define ARGPARSE_MISSING_ARG (-3) +#define ARGPARSE_KEYWORD_TOO_LONG (-4) +#define ARGPARSE_READ_ERROR (-5) +#define ARGPARSE_UNEXPECTED_ARG (-6) +#define ARGPARSE_INVALID_COMMAND (-7) +#define ARGPARSE_AMBIGUOUS_OPTION (-8) +#define ARGPARSE_AMBIGUOUS_COMMAND (-9) +#define ARGPARSE_INVALID_ALIAS (-10) +#define ARGPARSE_OUT_OF_CORE (-11) + int arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); int optfile_parse( FILE *fp, const char *filename, unsigned *lineno, ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts); Modified: trunk/jnlib/libjnlib-config.h =================================================================== --- trunk/jnlib/libjnlib-config.h 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/jnlib/libjnlib-config.h 2008-09-29 15:02:55 UTC (rev 4839) @@ -65,13 +65,15 @@ /* Malloc functions to be used by jnlib. */ #define jnlib_malloc(a) gcry_malloc( (a) ) #define jnlib_calloc(a,b) gcry_calloc( (a), (b) ) +#define jnlib_realloc(a,b) gcry_realloc( (a), (b) ) +#define jnlib_strdup(a) gcry_strdup( (a) ) #define jnlib_xmalloc(a) gcry_xmalloc( (a) ) #define jnlib_xcalloc(a,b) gcry_xcalloc( (a), (b) ) #define jnlib_xrealloc(a,n) gcry_xrealloc( (a), (n) ) #define jnlib_xstrdup(a) gcry_xstrdup( (a) ) #define jnlib_free(a) gcry_free( (a) ) -/* Logging functions to be jused by jnlib. */ +/* Logging functions to be used by jnlib. */ #define jnlib_log_debug log_debug #define jnlib_log_info log_info #define jnlib_log_error log_error Modified: trunk/scd/app-p15.c =================================================================== --- trunk/scd/app-p15.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/scd/app-p15.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -2948,7 +2948,7 @@ mse[0] = 4; /* Length of the template. */ mse[1] = 0x80; /* Algorithm reference tag. */ - if (hashalgo == GCRY_MD_USER_TLS_MD5SHA1) + if (hashalgo == MD_USER_TLS_MD5SHA1) mse[2] = 0x01; /* Let card do pkcs#1 0xFF padding. */ else mse[2] = 0x02; /* RSASSA-PKCS1-v1.5 using SHA1. */ @@ -3124,7 +3124,7 @@ if (indatalen == 36) { /* No ASN.1 container used. */ - if (hashalgo != GCRY_MD_USER_TLS_MD5SHA1) + if (hashalgo != MD_USER_TLS_MD5SHA1) return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); memcpy (data, indata, indatalen); } @@ -3187,7 +3187,7 @@ return err; } - if (hashalgo == GCRY_MD_USER_TLS_MD5SHA1) + if (hashalgo == MD_USER_TLS_MD5SHA1) err = iso7816_compute_ds (app->slot, data, 36, outdata, outdatalen); else if (no_data_padding) err = iso7816_compute_ds (app->slot, data+15, 20, outdata, outdatalen); @@ -3226,7 +3226,7 @@ return gpg_error (GPG_ERR_WRONG_KEY_USAGE); } - algo = indatalen == 36? GCRY_MD_USER_TLS_MD5SHA1 : GCRY_MD_SHA1; + algo = indatalen == 36? MD_USER_TLS_MD5SHA1 : GCRY_MD_SHA1; return do_sign (app, keyidstr, algo, pincb, pincb_arg, indata, indatalen, outdata, outdatalen); } Modified: trunk/scd/scdaemon.h =================================================================== --- trunk/scd/scdaemon.h 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/scd/scdaemon.h 2008-09-29 15:02:55 UTC (rev 4839) @@ -33,10 +33,10 @@ /* To convey some special hash algorithms we use algorithm numbers reserved for application use. */ -#ifndef GCRY_MD_USER -#define GCRY_MD_USER 1024 +#ifndef GCRY_MODULE_ID_USER +#define GCRY_MODULE_ID_USER 1024 #endif -#define GCRY_MD_USER_TLS_MD5SHA1 (GCRY_MD_USER+1) +#define MD_USER_TLS_MD5SHA1 (GCRY_MODULE_ID_USER+1) /* Maximum length of a digest. */ #define MAX_DIGEST_LEN 36 Modified: trunk/sm/certcheck.c =================================================================== --- trunk/sm/certcheck.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/sm/certcheck.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -34,10 +34,6 @@ #include "i18n.h" -/* Remove this if libgcrypt 1.3.0 is required. */ -#define MY_GCRY_PK_ECDSA 301 - - /* Return the number of bits of the Q parameter from the DSA key KEY. */ static unsigned int @@ -75,11 +71,11 @@ size_t nframe; unsigned char *frame; - if (pkalgo == GCRY_PK_DSA || pkalgo == MY_GCRY_PK_ECDSA) + if (pkalgo == GCRY_PK_DSA || pkalgo == GCRY_PK_ECDSA) { unsigned int qbits; - if ( pkalgo == MY_GCRY_PK_ECDSA ) + if ( pkalgo == GCRY_PK_ECDSA ) qbits = gcry_pk_get_nbits (pkey); else qbits = get_dsa_qbits (pkey); @@ -214,7 +210,7 @@ /* Because this function is called only for verification we can assume that ECC actually means ECDSA. */ else if (n==3 && !memcmp (name, "ecc", 3)) - algo = MY_GCRY_PK_ECDSA; + algo = GCRY_PK_ECDSA; else if (n==13 && !memcmp (name, "ambiguous-rsa", 13)) algo = GCRY_PK_RSA; else Modified: trunk/sm/certreqgen-ui.c =================================================================== --- trunk/sm/certreqgen-ui.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/sm/certreqgen-ui.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -300,7 +300,7 @@ goto leave; mem_error: - log_error (_("resource problem: out or core\n")); + log_error (_("resource problem: out of core\n")); leave: es_fclose (fp); xfree (keytype); Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/sm/gpgsm.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -500,17 +500,13 @@ static estream_t open_es_fwrite (const char *filename); static void run_protect_tool (int argc, char **argv); -/* Remove this if libgcrypt 1.3.0 is required. */ -#define MY_GCRY_PK_ECDSA 301 - - static int our_pk_test_algo (int algo) { switch (algo) { case GCRY_PK_RSA: - case MY_GCRY_PK_ECDSA: + case GCRY_PK_ECDSA: return gcry_pk_test_algo (algo); default: return 1; Modified: trunk/sm/sign.c =================================================================== --- trunk/sm/sign.c 2008-09-28 12:48:41 UTC (rev 4838) +++ trunk/sm/sign.c 2008-09-29 15:02:55 UTC (rev 4839) @@ -33,10 +33,7 @@ #include "keydb.h" #include "i18n.h" -/* Remove this if libgcrypt 1.4 is required. */ -#define MY_GCRY_MD_SHA224 11 - static void hash_data (int fd, gcry_md_hd_t md) { @@ -411,7 +408,7 @@ { case GCRY_MD_SHA1: oid = "1.3.14.3.2.26"; break; case GCRY_MD_RMD160: oid = "1.3.36.3.2.1"; break; - case MY_GCRY_MD_SHA224: oid = "2.16.840.1.101.3.4.2.4"; break; + case GCRY_MD_SHA224: oid = "2.16.840.1.101.3.4.2.4"; break; case GCRY_MD_SHA256: oid = "2.16.840.1.101.3.4.2.1"; break; case GCRY_MD_SHA384: oid = "2.16.840.1.101.3.4.2.2"; break; case GCRY_MD_SHA512: oid = "2.16.840.1.101.3.4.2.3"; break; From cvs at cvs.gnupg.org Tue Sep 30 12:30:21 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 30 Sep 2008 12:30:21 +0200 Subject: [svn] GnuPG - r4840 - in trunk: sm tests tests/openpgp Message-ID: Author: wk Date: 2008-09-30 12:30:20 +0200 (Tue, 30 Sep 2008) New Revision: 4840 Modified: trunk/sm/ChangeLog trunk/sm/call-agent.c trunk/sm/gpgsm.h trunk/sm/server.c trunk/tests/ChangeLog trunk/tests/Makefile.am trunk/tests/openpgp/ChangeLog trunk/tests/openpgp/clearsig.test Log: Add gpgsm server command GETINFO agent-check. Fix tests. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-09-29 15:02:55 UTC (rev 4839) +++ trunk/sm/ChangeLog 2008-09-30 10:30:20 UTC (rev 4840) @@ -1,3 +1,8 @@ +2008-09-30 Werner Koch + + * server.c (cmd_getinfo): New subcommand agent-check. + * call-agent.c (gpgsm_agent_send_nop): New. + 2008-09-29 Werner Koch * certcheck.c (MY_GCRY_PK_ECDSA): Remove. Change users to Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2008-09-29 15:02:55 UTC (rev 4839) +++ trunk/tests/ChangeLog 2008-09-30 10:30:20 UTC (rev 4840) @@ -1,3 +1,7 @@ +2008-09-29 Werner Koch + + * Makefile.am (TESTS): Remove tests. + 2008-02-19 Werner Koch * Makefile.am: Always run pkits tests. Modified: trunk/tests/openpgp/ChangeLog =================================================================== --- trunk/tests/openpgp/ChangeLog 2008-09-29 15:02:55 UTC (rev 4839) +++ trunk/tests/openpgp/ChangeLog 2008-09-30 10:30:20 UTC (rev 4840) @@ -1,3 +1,7 @@ +2008-09-29 Werner Koch + + * clearsig.test: Replace -sat by --clearsign. + 2008-03-19 Werner Koch * import.test, bug894-test.asc: New. Modified: trunk/sm/call-agent.c =================================================================== --- trunk/sm/call-agent.c 2008-09-29 15:02:55 UTC (rev 4839) +++ trunk/sm/call-agent.c 2008-09-30 10:30:20 UTC (rev 4840) @@ -328,7 +328,7 @@ { int rc; char line[ASSUAN_LINELENGTH]; - membuf_t data; + membuf_t data; struct cipher_parm_s cipher_parm; size_t n, len; char *p, *buf, *endp; @@ -802,3 +802,21 @@ default_inq_cb, ctrl, NULL, NULL); return rc; } + + + +/* Return 0 if the agent is alive. This is useful to make sure that + an agent has been started. */ +gpg_error_t +gpgsm_agent_send_nop (ctrl_t ctrl) +{ + int rc; + + rc = start_agent (ctrl); + if (!rc) + rc = assuan_transact (agent_ctx, "NOP", + NULL, NULL, NULL, NULL, NULL, NULL); + return rc; +} + + Modified: trunk/sm/gpgsm.h =================================================================== --- trunk/sm/gpgsm.h 2008-09-29 15:02:55 UTC (rev 4839) +++ trunk/sm/gpgsm.h 2008-09-30 10:30:20 UTC (rev 4840) @@ -393,6 +393,7 @@ int gpgsm_agent_learn (ctrl_t ctrl); int gpgsm_agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc); gpg_error_t gpgsm_agent_get_confirmation (ctrl_t ctrl, const char *desc); +gpg_error_t gpgsm_agent_send_nop (ctrl_t ctrl); /*-- call-dirmngr.c --*/ int gpgsm_dirmngr_isvalid (ctrl_t ctrl, Modified: trunk/sm/server.c =================================================================== --- trunk/sm/server.c 2008-09-29 15:02:55 UTC (rev 4839) +++ trunk/sm/server.c 2008-09-30 10:30:20 UTC (rev 4840) @@ -1016,6 +1016,7 @@ version - Return the version of the program. pid - Return the process id of the server. + agent-check - Return success if the agent is running. */ static int @@ -1035,6 +1036,11 @@ snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ()); rc = assuan_send_data (ctx, numbuf, strlen (numbuf)); } + else if (!strcmp (line, "agent-check")) + { + ctrl_t ctrl = assuan_get_pointer (ctx); + rc = gpgsm_agent_send_nop (ctrl); + } else rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); return rc; Modified: trunk/tests/Makefile.am =================================================================== --- trunk/tests/Makefile.am 2008-09-29 15:02:55 UTC (rev 4839) +++ trunk/tests/Makefile.am 2008-09-30 10:30:20 UTC (rev 4840) @@ -44,7 +44,13 @@ samplekeys/cert_g10code_test1.pem \ samplekeys/cert_g10code_theo1.pem -TESTS = $(testscripts) +# We used to run $(testscripts) here but tehse asschk scripts ares not +# completely reliable in all enviromnets and thus we better disable +# them. The tests are anyway way to minimal. We will eventually +# write new tests based on gpg-connect-agent which has a full fledged +# script language and thus makes it far easier to write tests than to +# use the low--level asschk stuff. +TESTS = CLEANFILES = inittests.stamp x y y z out err \ *.lock .\#lk* Modified: trunk/tests/openpgp/clearsig.test =================================================================== --- trunk/tests/openpgp/clearsig.test 2008-09-29 15:02:55 UTC (rev 4839) +++ trunk/tests/openpgp/clearsig.test 2008-09-30 10:30:20 UTC (rev 4840) @@ -18,7 +18,7 @@ # it is clear text and not binary text. # ====================================== for i in $plain_files plain-large ; do - echo "$usrpass1" | $GPG --passphrase-fd 0 -sat -o x --yes $i + echo "$usrpass1" | $GPG --passphrase-fd 0 --clearsign -o x --yes $i $GPG --verify x done @@ -29,7 +29,7 @@ if have_pubkey_algo "RSA"; then for i in $plain_files plain-large ; do - $GPG -u $usrname3 --rfc1991 --digest-algo md5 -sat -o x --yes $i + $GPG -u $usrname3 --rfc1991 --digest-algo md5 --clearsign -o x --yes $i $GPG --verify x done fi From cvs at cvs.gnupg.org Tue Sep 30 14:45:44 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 30 Sep 2008 14:45:44 +0200 Subject: [svn] GnuPG - r4841 - trunk/tools Message-ID: Author: wk Date: 2008-09-30 14:45:44 +0200 (Tue, 30 Sep 2008) New Revision: 4841 Modified: trunk/tools/ChangeLog trunk/tools/gpgconf.c Log: Extend --list-dirs to print the bindir. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2008-09-30 10:30:20 UTC (rev 4840) +++ trunk/tools/ChangeLog 2008-09-30 12:45:44 UTC (rev 4841) @@ -1,3 +1,7 @@ +2008-09-30 Werner Koch + + * gpgconf.c (main) : Print the bindir. + 2008-08-06 Marcus Brinkmann * gpgconf-comp.c (gc_options_gpgsm): Change type of keyserver Modified: trunk/tools/gpgconf.c =================================================================== --- trunk/tools/gpgconf.c 2008-09-30 10:30:20 UTC (rev 4840) +++ trunk/tools/gpgconf.c 2008-09-30 12:45:44 UTC (rev 4841) @@ -263,6 +263,8 @@ get_outfp (&outfp); fprintf (outfp, "sysconfdir:%s\n", gc_percent_escape (gnupg_sysconfdir ())); + fprintf (outfp, "bindir:%s\n", + gc_percent_escape (gnupg_bindir ())); break; } From cvs at cvs.gnupg.org Tue Sep 30 15:09:32 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 30 Sep 2008 15:09:32 +0200 Subject: [svn] dirmngr - r308 - trunk/src Message-ID: Author: marcus Date: 2008-09-30 15:09:32 +0200 (Tue, 30 Sep 2008) New Revision: 308 Modified: trunk/src/ChangeLog trunk/src/get-path.c Log: 2008-09-30 Marcus Brinkmann * get-path.c (dirmngr_cachedir): Make COMP a pointer to const to silence gcc warning. (get_dirmngr_ldap_path): Look for dirmngr_ldap in the installation directory. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-08-06 11:46:39 UTC (rev 307) +++ trunk/src/ChangeLog 2008-09-30 13:09:32 UTC (rev 308) @@ -1,3 +1,10 @@ +2008-09-30 Marcus Brinkmann + + * get-path.c (dirmngr_cachedir): Make COMP a pointer to const to + silence gcc warning. + (get_dirmngr_ldap_path): Look for dirmngr_ldap in the installation + directory. + 2008-08-06 Marcus Brinkmann * dirmngr.c (main): Mark the ldapserverlist-file option as Modified: trunk/src/get-path.c =================================================================== --- trunk/src/get-path.c 2008-08-06 11:46:39 UTC (rev 307) +++ trunk/src/get-path.c 2008-09-30 13:09:32 UTC (rev 308) @@ -236,7 +236,39 @@ return -1; } + static char * +find_program_in_inst_dir (const char *name) +{ + char *result = NULL; + char *tmp; + + tmp = read_w32_registry_string ("HKEY_LOCAL_MACHINE", + "Software\\GNU\\GnuPG", + "Install Directory"); + if (!tmp) + return NULL; + + result = malloc (strlen (tmp) + 1 + strlen (name) + 1); + if (!result) + { + free (tmp); + return NULL; + } + + strcpy (stpcpy (stpcpy (result, tmp), "\\"), name); + free (tmp); + if (access (result, F_OK)) + { + free (result); + return NULL; + } + + return result; +} + + +static char * find_program_at_standard_place (const char *name) { char path[MAX_PATH]; @@ -267,6 +299,8 @@ #ifdef HAVE_W32_SYSTEM if (!pgmname) + pgmname = find_program_in_inst_dir ("dirmngr_ldap.exe"); + if (!pgmname) pgmname = find_program_at_standard_place ("GNU\\GnuPG\\dirmngr_ldap.exe"); #endif if (!pgmname) @@ -512,7 +546,7 @@ char path[MAX_PATH]; const char *s1[] = { "GNU", "cache", "dirmngr", NULL }; int s1_len; - char **comp; + const char **comp; s1_len = 0; for (comp = s1; *comp; comp++) From cvs at cvs.gnupg.org Tue Sep 30 15:33:45 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 30 Sep 2008 15:33:45 +0200 Subject: [svn] GpgOL - r268 - trunk/src Message-ID: Author: wk Date: 2008-09-30 15:33:44 +0200 (Tue, 30 Sep 2008) New Revision: 268 Modified: trunk/src/ChangeLog trunk/src/mapihelp.cpp Log: Detect pgp signed mails with S/MIME disabled. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-08-06 06:49:09 UTC (rev 267) +++ trunk/src/ChangeLog 2008-09-30 13:33:44 UTC (rev 268) @@ -1,3 +1,8 @@ +2008-09-30 Werner Koch + + * mapihelp.cpp (mapi_change_message_class): Special handling for + MultipartSigned if S/MIME support is disabled. + 2008-08-06 Werner Koch * olflange-dlgs.cpp (GPGOptionsDlgProc): Disable S/MIME notice. Modified: trunk/src/mapihelp.cpp =================================================================== --- trunk/src/mapihelp.cpp 2008-08-06 06:49:09 UTC (rev 267) +++ trunk/src/mapihelp.cpp 2008-09-30 13:33:44 UTC (rev 268) @@ -791,13 +791,14 @@ xfree (ct); } } - else if (opt.enable_smime && !strcmp (s, "IPM.Note.SMIME")) + else if (!strcmp (s, "IPM.Note.SMIME")) { /* This is an S/MIME opaque encrypted or signed message. - Check what it really is. */ - char *ct, *smtype; + Check what it really is. Notee that this might even be a + PGP/MIME mail. */ + char *ct, *proto, *smtype; - ct = mapi_get_message_content_type (message, NULL, &smtype); + ct = mapi_get_message_content_type (message, &proto, &smtype); if (!ct) log_debug ("%s:%s: message has no content type", SRCNAME, __func__); @@ -805,8 +806,16 @@ { log_debug ("%s:%s: content type is '%s'", SRCNAME, __func__, ct); - if (smtype) + if (proto + && !strcmp (ct, "multipart/signed") + && !strcmp (proto, "application/pgp-signature")) { + newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned"); + } + else if (!opt.enable_smime) + ; /* S/MIME not enabled; thus no further checks. */ + else if (smtype) + { log_debug ("%s:%s: smime-type is '%s'", SRCNAME, __func__, smtype); @@ -818,7 +827,6 @@ else if (!strcmp (smtype, "enveloped-data")) newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueEncrypted"); } - xfree (smtype); } else { @@ -831,10 +839,11 @@ else newvalue = xstrdup ("IPM.Note.GpgOL.OpaqueSigned"); } - + xfree (smtype); + xfree (proto); xfree (ct); } - if (!newvalue) + if (!newvalue && opt.enable_smime) newvalue = xstrdup ("IPM.Note.GpgOL"); } else if (opt.enable_smime @@ -849,6 +858,31 @@ newvalue = (char*)xmalloc (strlen (s) + 1); strcpy (stpcpy (newvalue, "IPM.Note.GpgOL"), s+14); } + else if (!strcmp (s, "IPM.Note.SMIME.MultipartSigned")) + { + /* This is an S/MIME message class but smime support is not + enabled. We need to check whetehr this is actually a + PGP/MIME message. */ + char *ct, *proto; + + ct = mapi_get_message_content_type (message, &proto, NULL); + if (!ct) + log_debug ("%s:%s: message has no content type", + SRCNAME, __func__); + else + { + log_debug ("%s:%s: content type is '%s'", + SRCNAME, __func__, ct); + if (proto + && !strcmp (ct, "multipart/signed") + && !strcmp (proto, "application/pgp-signature")) + { + newvalue = xstrdup ("IPM.Note.GpgOL.MultipartSigned"); + } + xfree (proto); + xfree (ct); + } + } else if (opt.enable_smime && sync_override && have_override && !strncmp (s, "IPM.Note.GpgOL", 14) && (!s[14]||s[14] =='.')) { From cvs at cvs.gnupg.org Tue Sep 30 16:41:40 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 30 Sep 2008 16:41:40 +0200 Subject: [svn] dirmngr - r309 - trunk/src Message-ID: Author: marcus Date: 2008-09-30 16:41:40 +0200 (Tue, 30 Sep 2008) New Revision: 309 Modified: trunk/src/ChangeLog trunk/src/get-path.c Log: 2008-09-30 Marcus Brinkmann * get-path.c (get_dirmngr_ldap_path): Revert last change. Instead, use dirmngr_libexecdir(). (find_program_at_standard_place): Don't define for now. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-09-30 13:09:32 UTC (rev 308) +++ trunk/src/ChangeLog 2008-09-30 14:41:40 UTC (rev 309) @@ -1,5 +1,11 @@ 2008-09-30 Marcus Brinkmann + * get-path.c (get_dirmngr_ldap_path): Revert last change. + Instead, use dirmngr_libexecdir(). + (find_program_at_standard_place): Don't define for now. + +2008-09-30 Marcus Brinkmann + * get-path.c (dirmngr_cachedir): Make COMP a pointer to const to silence gcc warning. (get_dirmngr_ldap_path): Look for dirmngr_ldap in the installation Modified: trunk/src/get-path.c =================================================================== --- trunk/src/get-path.c 2008-09-30 13:09:32 UTC (rev 308) +++ trunk/src/get-path.c 2008-09-30 14:41:40 UTC (rev 309) @@ -237,6 +237,7 @@ } +#if 0 static char * find_program_in_inst_dir (const char *name) { @@ -290,18 +291,23 @@ return result; } #endif +#endif const char * get_dirmngr_ldap_path (void) { - static const char *pgmname; + static char *pgmname; #ifdef HAVE_W32_SYSTEM - if (!pgmname) - pgmname = find_program_in_inst_dir ("dirmngr_ldap.exe"); - if (!pgmname) - pgmname = find_program_at_standard_place ("GNU\\GnuPG\\dirmngr_ldap.exe"); + if (! pgmname) + { + const char *dir = dirmngr_libexecdir (); + const char *exe = "\\dirmngr_ldap.exe"; + pgmname = malloc (strlen (dir) + strlen (exe) + 1); + if (pgmname) + strcpy (stpcpy (pgmname, dir), exe); + } #endif if (!pgmname) pgmname = DIRMNGR_LIBEXECDIR "/dirmngr_ldap"; From cvs at cvs.gnupg.org Tue Sep 30 19:58:23 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 30 Sep 2008 19:58:23 +0200 Subject: [svn] gcry - r1345 - trunk/cipher Message-ID: Author: wk Date: 2008-09-30 19:58:22 +0200 (Tue, 30 Sep 2008) New Revision: 1345 Modified: trunk/cipher/ChangeLog trunk/cipher/dsa.c trunk/cipher/pubkey.c trunk/cipher/rijndael.c trunk/cipher/rsa.c Log: Fix bug #936. cleaned up internal symbol usage. Add domain parameter. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-09-20 10:00:36 UTC (rev 1344) +++ trunk/cipher/ChangeLog 2008-09-30 17:58:22 UTC (rev 1345) @@ -1,3 +1,29 @@ +2008-09-30 Werner Koch + + * rijndael.c (do_setkey): Properly align "t" and "tk". + (prepare_decryption): Properly align "w". Fixes bug #936. + +2008-09-18 Werner Koch + + + * pubkey.c (gcry_pk_genkey): Parse domain parameter. + (pubkey_generate): Add new arg DOMAIN and remove special case for + DSA with qbits. + * rsa.c (rsa_generate): Add dummy args QBITS, NAME and DOMAIN and + rename to rsa_generate_ext. Change caller. + (_gcry_rsa_generate, _gcry_rsa_check_secret_key) + (_gcry_rsa_encrypt, _gcry_rsa_decrypt, _gcry_rsa_sign) + (_gcry_rsa_verify, _gcry_rsa_get_nbits): Make static and remove + _gcry_ prefix. + (_gcry_pubkey_spec_rsa, _gcry_pubkey_extraspec_rsa): Adjust names. + * dsa.c (dsa_generate_ext): New. + (_gcry_dsa_generate): Replace code by a call to dsa_generate. + (_gcry_dsa_check_secret_key, _gcry_dsa_sign, _gcry_dsa_verify) + (_gcry_dsa_get_nbits): Make static and remove _gcry prefix. + (_gcry_dsa_generate2): Remove. + (_gcry_pubkey_spec_dsa): Adjust to name changes. + (_gcry_pubkey_extraspec_rsa): Add dsa_generate_ext. + 2008-09-16 Werner Koch * ecc.c (run_selftests): Add arg EXTENDED. Modified: trunk/cipher/dsa.c =================================================================== --- trunk/cipher/dsa.c 2008-09-20 10:00:36 UTC (rev 1344) +++ trunk/cipher/dsa.c 2008-09-30 17:58:22 UTC (rev 1345) @@ -1,4 +1,4 @@ -/* dsa.c - DSA signature scheme +/* dsa.c - DSA signature algorithm * Copyright (C) 1998, 2000, 2001, 2002, 2003, * 2006, 2008 Free Software Foundation, Inc. * @@ -458,18 +458,24 @@ ************** interface ****************** *********************************************/ -gcry_err_code_t -_gcry_dsa_generate (int algo, unsigned int nbits, unsigned long dummy, - gcry_mpi_t *skey, gcry_mpi_t **retfactors) +static gcry_err_code_t +dsa_generate_ext (int algo, unsigned int nbits, unsigned int qbits, + unsigned long use_e, + const char *name, const gcry_sexp_t domain, + unsigned int keygen_flags, + gcry_mpi_t *skey, gcry_mpi_t **retfactors) { - gpg_err_code_t err; + gpg_err_code_t ec; DSA_secret_key sk; (void)algo; - (void)dummy; + (void)use_e; + (void)name; + (void)domain; + (void)keygen_flags; - err = generate (&sk, nbits, 0, retfactors); - if (!err) + ec = generate (&sk, nbits, qbits, retfactors); + if (!ec) { skey[0] = sk.p; skey[1] = sk.q; @@ -478,42 +484,22 @@ skey[4] = sk.x; } - return err; + return ec; } -/* We don't want to break our API. Thus we use a hack in pubkey.c to - link directly to this function. Note that we can't reuse the dummy - parameter because we can't be sure that applicaions accidently pass - a USE_E (that is for what dummy is used with RSA) to a DSA - generation. */ -gcry_err_code_t -_gcry_dsa_generate2 (int algo, unsigned int nbits, unsigned int qbits, - unsigned long dummy, - gcry_mpi_t *skey, gcry_mpi_t **retfactors) +static gcry_err_code_t +dsa_generate (int algo, unsigned int nbits, unsigned long dummy, + gcry_mpi_t *skey, gcry_mpi_t **retfactors) { - gpg_err_code_t err; - DSA_secret_key sk; - - (void)algo; (void)dummy; - - err = generate (&sk, nbits, qbits, retfactors); - if (!err) - { - skey[0] = sk.p; - skey[1] = sk.q; - skey[2] = sk.g; - skey[3] = sk.y; - skey[4] = sk.x; - } - - return err; + return dsa_generate_ext (algo, nbits, 0, 0, NULL, NULL, 0, skey, retfactors); } -gcry_err_code_t -_gcry_dsa_check_secret_key (int algo, gcry_mpi_t *skey) + +static gcry_err_code_t +dsa_check_secret_key (int algo, gcry_mpi_t *skey) { gcry_err_code_t err = GPG_ERR_NO_ERROR; DSA_secret_key sk; @@ -537,8 +523,8 @@ } -gcry_err_code_t -_gcry_dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey) +static gcry_err_code_t +dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey) { gcry_err_code_t err = GPG_ERR_NO_ERROR; DSA_secret_key sk; @@ -563,9 +549,9 @@ return err; } -gcry_err_code_t -_gcry_dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey, - int (*cmp) (void *, gcry_mpi_t), void *opaquev) +static gcry_err_code_t +dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey, + int (*cmp) (void *, gcry_mpi_t), void *opaquev) { gcry_err_code_t err = GPG_ERR_NO_ERROR; DSA_public_key pk; @@ -590,8 +576,8 @@ } -unsigned int -_gcry_dsa_get_nbits (int algo, gcry_mpi_t *pkey) +static unsigned int +dsa_get_nbits (int algo, gcry_mpi_t *pkey) { (void)algo; @@ -743,16 +729,17 @@ "DSA", dsa_names, "pqgy", "pqgyx", "", "rs", "pqgy", GCRY_PK_USAGE_SIGN, - _gcry_dsa_generate, - _gcry_dsa_check_secret_key, + dsa_generate, + dsa_check_secret_key, NULL, NULL, - _gcry_dsa_sign, - _gcry_dsa_verify, - _gcry_dsa_get_nbits, + dsa_sign, + dsa_verify, + dsa_get_nbits }; pk_extra_spec_t _gcry_pubkey_extraspec_dsa = { - run_selftests + run_selftests, + dsa_generate_ext }; Modified: trunk/cipher/pubkey.c =================================================================== --- trunk/cipher/pubkey.c 2008-09-20 10:00:36 UTC (rev 1344) +++ trunk/cipher/pubkey.c 2008-09-30 17:58:22 UTC (rev 1345) @@ -531,15 +531,16 @@ /* Generate a new public key with algorithm ALGORITHM of size NBITS and return it at SKEY. The use of the arguments QBITS, USE_E, - XVALUE and CURVE_NAME depend on the ALGORITHM. RETFACTOR is used - by some algorithms to return certain additional information which - are in general not required. + XVALUE, CURVE_NAME and DOMAIN depend on the ALGORITHM. RETFACTOR + is used by some algorithms to return certain additional information + which are in general not required. The function returns the error code number or 0 on success. */ static gcry_err_code_t pubkey_generate (int algorithm, unsigned int nbits, unsigned int qbits, unsigned long use_e, gcry_mpi_t xvalue, - const char *curve_name, unsigned int keygen_flags, + const char *curve_name, gcry_sexp_t domain, + unsigned int keygen_flags, gcry_mpi_t *skey, gcry_mpi_t **retfactors) { gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO; @@ -561,13 +562,6 @@ security sensitive.. */ ec = GPG_ERR_INV_FLAG; } - else if (qbits && pubkey->spec == &_gcry_pubkey_spec_dsa) - { - /* Hack to pass QBITS to the DSA generation. fixme: We - should merge this into an ext_generate fucntion. */ - ec = _gcry_dsa_generate2 - (algorithm, nbits, qbits, 0, skey, retfactors); - } #ifdef USE_ELGAMAL else if (xvalue && pubkey->spec == &_gcry_pubkey_spec_elg) { @@ -587,10 +581,17 @@ else if (extraspec && extraspec->ext_generate) { /* Use the extended generate function if available. */ - ec = extraspec->ext_generate (algorithm, nbits, use_e, - keygen_flags, + ec = extraspec->ext_generate (algorithm, nbits, qbits, use_e, + NULL, domain, keygen_flags, skey, retfactors); } + else if (qbits || domain) + { + /* A qbits or domain parameter is specified but the + algorithm does not feature an extended generation + function. */ + ec = GPG_ERR_INV_PARAMETER; + } else { /* Use the standard generate function. */ @@ -2258,8 +2259,11 @@ else nbits = 0; + /* Extract the optional domain parameter and call the key generation. */ + l2 = gcry_sexp_find_token (list, "domain", 0); rc = pubkey_generate (module->mod_id, nbits, qbits, use_e, xvalue, - curve, keygen_flags, skey, &factors); + curve, l2, keygen_flags, skey, &factors); + gcry_sexp_release (l2); if (rc) goto leave; Modified: trunk/cipher/rijndael.c =================================================================== --- trunk/cipher/rijndael.c 2008-09-20 10:00:36 UTC (rev 1344) +++ trunk/cipher/rijndael.c 2008-09-30 17:58:22 UTC (rev 1345) @@ -97,11 +97,21 @@ static int initialized = 0; static const char *selftest_failed=0; int ROUNDS; - byte k[MAXKC][4]; int i,j, r, t, rconpointer = 0; - byte tk[MAXKC][4]; int KC; - + union + { + PROPERLY_ALIGNED_TYPE dummy; + byte k[MAXKC][4]; + } k; +#define k k.k + union + { + PROPERLY_ALIGNED_TYPE dummy; + byte tk[MAXKC][4]; + } tk; +#define tk tk.tk + /* The on-the-fly self tests are only run in non-fips mode. In fips mode explicit self-tests are required. Actually the on-the-fly self-tests are not fully thread-safe and it might happen that a @@ -237,6 +247,8 @@ } return 0; +#undef tk +#undef k } @@ -256,7 +268,12 @@ prepare_decryption( RIJNDAEL_context *ctx ) { int r; - byte *w; + union + { + PROPERLY_ALIGNED_TYPE dummy; + byte *w; + } w; +#define w w.w for (r=0; r < MAXROUNDS+1; r++ ) { @@ -285,6 +302,7 @@ ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]); } #undef W +#undef w } Modified: trunk/cipher/rsa.c =================================================================== --- trunk/cipher/rsa.c 2008-09-20 10:00:36 UTC (rev 1344) +++ trunk/cipher/rsa.c 2008-09-30 17:58:22 UTC (rev 1345) @@ -532,15 +532,20 @@ *********************************************/ static gcry_err_code_t -rsa_generate (int algo, unsigned int nbits, unsigned long use_e, - unsigned int keygen_flags, - gcry_mpi_t *skey, gcry_mpi_t **retfactors) +rsa_generate_ext (int algo, unsigned int nbits, unsigned int qbits, + unsigned long use_e, + const char *name, const gcry_sexp_t domain, + unsigned int keygen_flags, + gcry_mpi_t *skey, gcry_mpi_t **retfactors) { RSA_secret_key sk; gpg_err_code_t ec; int i; (void)algo; + (void)qbits; + (void)name; + (void)domain; ec = generate (&sk, nbits, use_e, !!(keygen_flags & PUBKEY_FLAG_TRANSIENT_KEY) ); @@ -572,16 +577,17 @@ } -gcry_err_code_t -_gcry_rsa_generate (int algo, unsigned int nbits, unsigned long use_e, - gcry_mpi_t *skey, gcry_mpi_t **retfactors) +static gcry_err_code_t +rsa_generate (int algo, unsigned int nbits, unsigned long use_e, + gcry_mpi_t *skey, gcry_mpi_t **retfactors) { - return rsa_generate (algo, nbits, use_e, 0, skey, retfactors); + return rsa_generate_ext (algo, nbits, 0, use_e, NULL, NULL, 0, + skey, retfactors); } -gcry_err_code_t -_gcry_rsa_check_secret_key( int algo, gcry_mpi_t *skey ) +static gcry_err_code_t +rsa_check_secret_key (int algo, gcry_mpi_t *skey) { gcry_err_code_t err = GPG_ERR_NO_ERROR; RSA_secret_key sk; @@ -605,9 +611,9 @@ } -gcry_err_code_t -_gcry_rsa_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, - gcry_mpi_t *pkey, int flags) +static gcry_err_code_t +rsa_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, + gcry_mpi_t *pkey, int flags) { RSA_public_key pk; @@ -622,9 +628,10 @@ return GPG_ERR_NO_ERROR; } -gcry_err_code_t -_gcry_rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data, - gcry_mpi_t *skey, int flags) + +static gcry_err_code_t +rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data, + gcry_mpi_t *skey, int flags) { RSA_secret_key sk; gcry_mpi_t r = MPI_NULL; /* Random number needed for blinding. */ @@ -701,8 +708,9 @@ return GPG_ERR_NO_ERROR; } -gcry_err_code_t -_gcry_rsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey) + +static gcry_err_code_t +rsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey) { RSA_secret_key sk; @@ -720,8 +728,9 @@ return GPG_ERR_NO_ERROR; } -gcry_err_code_t -_gcry_rsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey, + +static gcry_err_code_t +rsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey, int (*cmp) (void *opaque, gcry_mpi_t tmp), void *opaquev) { @@ -752,8 +761,8 @@ } -unsigned int -_gcry_rsa_get_nbits (int algo, gcry_mpi_t *pkey) +static unsigned int +rsa_get_nbits (int algo, gcry_mpi_t *pkey) { (void)algo; @@ -1080,18 +1089,18 @@ "RSA", rsa_names, "ne", "nedpqu", "a", "s", "n", GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR, - _gcry_rsa_generate, - _gcry_rsa_check_secret_key, - _gcry_rsa_encrypt, - _gcry_rsa_decrypt, - _gcry_rsa_sign, - _gcry_rsa_verify, - _gcry_rsa_get_nbits, + rsa_generate, + rsa_check_secret_key, + rsa_encrypt, + rsa_decrypt, + rsa_sign, + rsa_verify, + rsa_get_nbits, }; pk_extra_spec_t _gcry_pubkey_extraspec_rsa = { run_selftests, - rsa_generate, + rsa_generate_ext, compute_keygrip }; From cvs at cvs.gnupg.org Tue Sep 30 20:23:35 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 30 Sep 2008 20:23:35 +0200 Subject: [svn] GnuPG - r4842 - branches/STABLE-BRANCH-1-4/po Message-ID: Author: wk Date: 2008-09-30 20:23:35 +0200 (Tue, 30 Sep 2008) New Revision: 4842 Modified: branches/STABLE-BRANCH-1-4/po/ChangeLog branches/STABLE-BRANCH-1-4/po/fr.po Log: fix bug #922 Modified: branches/STABLE-BRANCH-1-4/po/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/po/ChangeLog 2008-09-30 12:45:44 UTC (rev 4841) +++ branches/STABLE-BRANCH-1-4/po/ChangeLog 2008-09-30 18:23:35 UTC (rev 4842) @@ -1,3 +1,7 @@ +2008-09-30 David Ammouial (wk) + + * fr.po: Fix bug #922. + 2008-07-21 Daniel Nylander (wk) * sv.po: Update. Modified: branches/STABLE-BRANCH-1-4/po/fr.po [not shown] From cvs at cvs.gnupg.org Tue Sep 30 20:24:11 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 30 Sep 2008 20:24:11 +0200 Subject: [svn] GnuPG - r4843 - trunk/po Message-ID: Author: wk Date: 2008-09-30 20:24:10 +0200 (Tue, 30 Sep 2008) New Revision: 4843 Modified: trunk/po/ChangeLog trunk/po/fr.po Log: Fix bug #922 Modified: trunk/po/ChangeLog =================================================================== --- trunk/po/ChangeLog 2008-09-30 18:23:35 UTC (rev 4842) +++ trunk/po/ChangeLog 2008-09-30 18:24:10 UTC (rev 4843) @@ -1,3 +1,7 @@ +2008-09-30 David Ammouial (wk) + + * fr.po: Fix bug #922. + 2008-07-21 Werner Koch * sv.po: Adjust special size entry. Modified: trunk/po/fr.po [not shown]