[svn] gcry - r1354 - in trunk: . cipher src tests

svn author wk cvs at cvs.gnupg.org
Wed Nov 5 18:21:58 CET 2008


Author: wk
Date: 2008-11-05 18:21:57 +0100 (Wed, 05 Nov 2008)
New Revision: 1354

Modified:
   trunk/NEWS
   trunk/cipher/ChangeLog
   trunk/cipher/cipher.c
   trunk/cipher/des.c
   trunk/src/ChangeLog
   trunk/src/cipher-proto.h
   trunk/src/cipher.h
   trunk/src/fips.c
   trunk/src/gcrypt.h.in
   trunk/src/global.c
   trunk/tests/ChangeLog
   trunk/tests/fipsdrv.c
Log:
Add a method to disable the weak key detection.
Add a method to return the current input block.
Use this in the FIPS driver.


Modified: trunk/cipher/ChangeLog
===================================================================
--- trunk/cipher/ChangeLog	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/cipher/ChangeLog	2008-11-05 17:21:57 UTC (rev 1354)
@@ -1,3 +1,14 @@
+2008-11-05  Werner Koch  <wk at g10code.com>
+
+	* cipher.c (gcry_cipher_handle): Add field EXTRASPEC.
+	(gcry_cipher_open): Set it.
+	(gcry_cipher_ctl): Add private control code to disable weak key
+	detection and to return the current input block.
+	* des.c (_tripledes_ctx): Add field FLAGS.
+	(do_tripledes_set_extra_info): New.
+	(_gcry_cipher_extraspec_tripledes): Add new function.
+	(do_tripledes_setkey): Disable weak key detection.
+
 2008-10-24  Werner Koch  <wk at g10code.com>
 
 	* md.c (digest_table): Allow MD5 in fips mode.

Modified: trunk/src/ChangeLog
===================================================================
--- trunk/src/ChangeLog	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/src/ChangeLog	2008-11-05 17:21:57 UTC (rev 1354)
@@ -1,3 +1,10 @@
+2008-11-05  Werner Koch  <wk at g10code.com>
+
+	* cipher.h (CIPHER_INFO_NO_WEAK_KEY): New.
+
+	* cipher-proto.h (cipher_set_extra_info_t): New.
+	(cipher_extra_spec): Add field SET_EXTRA_INFO.
+
 2008-10-30  Werner Koch  <wk at g10code.com>
 
 	* g10lib.h (GCC_ATTR_FORMAT_ARG): New.

Modified: trunk/tests/ChangeLog
===================================================================
--- trunk/tests/ChangeLog	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/tests/ChangeLog	2008-11-05 17:21:57 UTC (rev 1354)
@@ -1,3 +1,7 @@
+2008-11-05  Werner Koch  <wk at g10code.com>
+
+	* fipsdrv.c (run_encrypt_decrypt): Disable weak key detection.
+
 2008-10-31  Werner Koch  <wk at g10code.com>
 
 	* fipsdrv.c (run_rsa_sign): Buffer needs to be larger for SHA512.

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/NEWS	2008-11-05 17:21:57 UTC (rev 1354)
@@ -2,7 +2,7 @@
 ------------------------------------------------
 
  * Publish GCRY_MODULE_ID_USER and GCRY_MODULE_ID_USER_LAST constants.
-   This functionality is in Libgcrypt since 1.3.0. 
+   This functionality has been in Libgcrypt since 1.3.0. 
 
  * MD5 may now be used in non-enforced fips mode.
 

Modified: trunk/cipher/cipher.c
===================================================================
--- trunk/cipher/cipher.c	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/cipher/cipher.c	2008-11-05 17:21:57 UTC (rev 1354)
@@ -161,6 +161,7 @@
   size_t actual_handle_size;     /* Allocated size of this handle. */
   size_t handle_offset;          /* Offset to the malloced block.  */
   gcry_cipher_spec_t *cipher;
+  cipher_extra_spec_t *extraspec;
   gcry_module_t module;
 
   /* The algorithm id.  This is a hack required because the module
@@ -669,6 +670,7 @@
 {
   int secure = (flags & GCRY_CIPHER_SECURE);
   gcry_cipher_spec_t *cipher = NULL;
+  cipher_extra_spec_t *extraspec = NULL;
   gcry_module_t module = NULL;
   gcry_cipher_hd_t h = NULL;
   gcry_err_code_t err = 0;
@@ -694,7 +696,10 @@
 	  _gcry_module_release (module);
 	}
       else
-	cipher = (gcry_cipher_spec_t *) module->spec;
+        {
+          cipher = (gcry_cipher_spec_t *) module->spec;
+          extraspec = module->extraspec;
+        }
     }
   else
     err = GPG_ERR_CIPHER_ALGO;
@@ -731,7 +736,7 @@
 	break;
 
       case GCRY_CIPHER_MODE_NONE:
-        /* This mode may be used for debbuging.  It copies the main
+        /* This mode may be used for debugging.  It copies the main
            text verbatim to the ciphertext.  We do not allow this in
            fips mode or if no debug flag has been set.  */
 	if (fips_mode () || !_gcry_get_debug_flag (0))
@@ -783,6 +788,7 @@
           h->actual_handle_size = size - off;
           h->handle_offset = off;
 	  h->cipher = cipher;
+	  h->extraspec = extraspec;
 	  h->module = module;
           h->algo = algo;
 	  h->mode = mode;
@@ -1681,6 +1687,38 @@
 	rc = GPG_ERR_INV_ARG;
       break;
 
+    case 61:  /* Disable weak key detection (private).  */
+      if (h->extraspec->set_extra_info)
+        rc = h->extraspec->set_extra_info 
+          (&h->context.c, CIPHER_INFO_NO_WEAK_KEY, NULL, 0);
+      else
+        rc = GPG_ERR_NOT_SUPPORTED;
+      break;
+
+    case 62: /* Return current input vector (private).  */
+      /* This is the input block as used in CFB and OFB mode which has
+         initially been set as IV.  The returned format is: 
+           1 byte  Actual length of the block in bytes.
+           n byte  The block.
+         If the provided buffer is too short, an error is returned. */
+      if (buflen < (1 + h->cipher->blocksize))
+        rc = GPG_ERR_TOO_SHORT;
+      else
+        {
+          unsigned char *ivp;
+          unsigned char *dst = buffer;
+          int n = h->unused;
+          
+          if (!n)
+            n = h->cipher->blocksize;
+          gcry_assert (n <= h->cipher->blocksize);
+          *dst++ = n;
+          ivp = h->u_iv.iv + h->cipher->blocksize - n;
+          while (n--)
+            *dst++ = *ivp++;
+        }
+      break;
+
     default:
       rc = GPG_ERR_INV_OP;
     }

Modified: trunk/cipher/des.c
===================================================================
--- trunk/cipher/des.c	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/cipher/des.c	2008-11-05 17:21:57 UTC (rev 1354)
@@ -1,5 +1,6 @@
 /* des.c - DES and Triple-DES encryption/decryption Algorithm
- * Copyright (C) 1998, 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2001, 2002, 2003,
+ *               2008  Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
@@ -152,6 +153,9 @@
   {
     u32 encrypt_subkeys[96];
     u32 decrypt_subkeys[96];
+    struct {
+      int no_weak_key;
+    } flags;
   }
 tripledes_ctx[1];
 
@@ -1013,7 +1017,9 @@
 
   tripledes_set3keys ( ctx, key, key+8, key+16);
 
-  if( is_weak_key( key ) || is_weak_key( key+8 ) || is_weak_key( key+16 ) )
+  if (ctx->flags.no_weak_key)
+    ; /* Detection has been disabled.  */
+  else if (is_weak_key (key) || is_weak_key (key+8) || is_weak_key (key+16))
     {
       _gcry_burn_stack (64);
       return GPG_ERR_WEAK_KEY;
@@ -1024,6 +1030,30 @@
 }
 
 
+static gcry_err_code_t
+do_tripledes_set_extra_info (void *context, int what,
+                             const void *buffer, size_t buflen)
+{
+  struct _tripledes_ctx *ctx = (struct _tripledes_ctx *)context;
+  gpg_err_code_t ec = 0;
+
+  (void)buffer;
+  (void)buflen;
+
+  switch (what)
+    {
+    case CIPHER_INFO_NO_WEAK_KEY:
+      ctx->flags.no_weak_key = 1;
+      break;
+
+    default:
+      ec = GPG_ERR_INV_OP; 
+      break;
+    }
+  return ec;
+}
+
+
 static void
 do_tripledes_encrypt( void *context, byte *outbuf, const byte *inbuf )
 {
@@ -1161,5 +1191,6 @@
 
 cipher_extra_spec_t _gcry_cipher_extraspec_tripledes = 
   {
-    run_selftests
+    run_selftests,
+    do_tripledes_set_extra_info
   };

Modified: trunk/src/cipher-proto.h
===================================================================
--- trunk/src/cipher-proto.h	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/src/cipher-proto.h	2008-11-05 17:21:57 UTC (rev 1354)
@@ -55,13 +55,18 @@
 typedef gpg_err_code_t (*pk_comp_keygrip_t)
      (gcry_md_hd_t md, gcry_sexp_t keyparm);
 
+/* The type used to convey additional information to a cipher.  */
+typedef gpg_err_code_t (*cipher_set_extra_info_t)
+     (void *c, int what, const void *buffer, size_t buflen);
 
+
 /* Extra module specification structures.  These are used for internal
    modules which provide more functions than available through the
    public algorithm register APIs.  */
 typedef struct cipher_extra_spec
 {
   selftest_func_t selftest;
+  cipher_set_extra_info_t set_extra_info;
 } cipher_extra_spec_t;
 
 typedef struct md_extra_spec

Modified: trunk/src/cipher.h
===================================================================
--- trunk/src/cipher.h	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/src/cipher.h	2008-11-05 17:21:57 UTC (rev 1354)
@@ -29,6 +29,8 @@
 #define PUBKEY_FLAG_NO_BLINDING    (1 << 0)
 #define PUBKEY_FLAG_TRANSIENT_KEY  (1 << 1)
 
+#define CIPHER_INFO_NO_WEAK_KEY    1
+
 #include "cipher-proto.h"
 
 

Modified: trunk/src/fips.c
===================================================================
--- trunk/src/fips.c	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/src/fips.c	2008-11-05 17:21:57 UTC (rev 1354)
@@ -262,8 +262,8 @@
 int
 _gcry_fips_mode (void)
 {
-  /* No locking is required becuase we have the requirement that this
-     variable is only intialized once with no other threads
+  /* No locking is required because we have the requirement that this
+     variable is only initialized once with no other threads
      existing.  */
   return !no_fips_mode_required;
 }

Modified: trunk/src/gcrypt.h.in
===================================================================
--- trunk/src/gcrypt.h.in	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/src/gcrypt.h.in	2008-11-05 17:21:57 UTC (rev 1354)
@@ -410,7 +410,7 @@
     GCRYCTL_FIPS_MODE_P = 55,
     GCRYCTL_FORCE_FIPS_MODE = 56,
     GCRYCTL_SELFTEST = 57
-    /* Note: 58, 59 and 60 are used internally.  */
+    /* Note: 58 .. 62 are used internally.  */
   };
 
 /* Perform various operations defined by CMD. */

Modified: trunk/src/global.c
===================================================================
--- trunk/src/global.c	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/src/global.c	2008-11-05 17:21:57 UTC (rev 1354)
@@ -529,7 +529,7 @@
       err = _gcry_fips_run_selftests (1);
       break;
 
-    case 58:
+    case 58:  /* Init external random test.  */
       {
         void **rctx        = va_arg (arg_ptr, void **);
         unsigned int flags = va_arg (arg_ptr, unsigned int);
@@ -546,7 +546,7 @@
                                                  seed, seedlen, dt, dtlen);
       }
       break;
-    case 59:
+    case 59:  /* Run external random test.  */
       {
         void *ctx     = va_arg (arg_ptr, void *);
         void *buffer  = va_arg (arg_ptr, void *);
@@ -557,7 +557,7 @@
           err = _gcry_random_run_external_test (ctx, buffer, buflen);
       }
       break;
-    case 60:
+    case 60:  /* Deinit external random test.  */
       {
         void *ctx = va_arg (arg_ptr, void *);
         _gcry_random_deinit_external_test (ctx);

Modified: trunk/tests/fipsdrv.c
===================================================================
--- trunk/tests/fipsdrv.c	2008-10-31 13:57:39 UTC (rev 1353)
+++ trunk/tests/fipsdrv.c	2008-11-05 17:21:57 UTC (rev 1354)
@@ -48,6 +48,13 @@
 #define DIMof(type,member)   DIM(((type *)0)->member)
 
 
+#define PRIV_CTL_INIT_EXTRNG_TEST   58
+#define PRIV_CTL_RUN_EXTRNG_TEST    59
+#define PRIV_CTL_DEINIT_EXTRNG_TEST 60
+#define PRIV_CTL_DISABLE_WEAK_KEY   61
+#define PRIV_CTL_GET_INPUT_VECTOR   62
+
+
 /* Verbose mode flag.  */
 static int verbose;
 
@@ -63,6 +70,10 @@
 /* We need to know whetehr we are in loop_mode.  */
 static int loop_mode;
 
+/* If true the input vectors are printed before and after encryption
+   and decryption.  */
+static int print_ivs;
+
 /* ASN.1 classes.  */
 enum
 {
@@ -747,7 +758,7 @@
                     const void *seed, size_t seedlen,
                     const void *dt, size_t dtlen)
 {
-  return gcry_control (58, 
+  return gcry_control (PRIV_CTL_INIT_EXTRNG_TEST, 
                        r_context, flags,
                        key, keylen,
                        seed, seedlen,
@@ -757,13 +768,13 @@
 static gcry_error_t
 run_external_rng_test (void *context, void *buffer, size_t buflen)
 {
-  return gcry_control (59, context, buffer, buflen);
+  return gcry_control (PRIV_CTL_RUN_EXTRNG_TEST, context, buffer, buflen);
 }
 
 static void
 deinit_external_rng_test (void *context)
 {
-  gcry_control (60, context);
+  gcry_control (PRIV_CTL_DEINIT_EXTRNG_TEST, context);
 }
 
 
@@ -856,12 +867,18 @@
   size_t outbuflen;
   void *inbuf;
   size_t inbuflen;
+  size_t blocklen;
 
   err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0);
   if (err)
     die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", 
          cipher_algo, cipher_mode, gpg_strerror (err));
 
+  blocklen = gcry_cipher_get_algo_blklen (cipher_algo);
+  assert (blocklen);
+
+  gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0);
+
   err = gcry_cipher_setkey (hd, key_buffer, key_buflen);
   if (err)
     die ("gcry_cipher_setkey failed with keylen %u: %s\n",
@@ -877,7 +894,7 @@
 
   inbuf = data? NULL : gcry_xmalloc (datalen);
   outbuflen = datalen;
-  outbuf = gcry_xmalloc (outbuflen);
+  outbuf = gcry_xmalloc (outbuflen < blocklen? blocklen:outbuflen);
 
   do
     {
@@ -892,14 +909,52 @@
       else
         inbuflen = datalen;
 
-      if (encrypt_mode)
-        err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen);
+      if (print_ivs)
+        {
+          /* If we want to print the input vectors we need to pass the
+             data block by block to the encryption function.  */
+          unsigned char tmp[17];
+          const unsigned char *iptr = data;
+          size_t ilen;
+          
+          do
+            {
+              ilen = inbuflen > blocklen? blocklen : inbuflen;
+              
+              if (gcry_cipher_ctl (hd, PRIV_CTL_GET_INPUT_VECTOR,
+                                   tmp, sizeof tmp))
+                die ("error getting input block\n");
+              print_buffer (tmp+1, *tmp);
+              putchar ('\n');
+
+              if (encrypt_mode)
+                err = gcry_cipher_encrypt (hd, outbuf, blocklen, iptr, ilen);
+              else
+                err = gcry_cipher_decrypt (hd, outbuf, blocklen, iptr, ilen);
+              if (err)
+                die ("gcry_cipher_%scrypt failed: %s\n",
+                     encrypt_mode? "en":"de", gpg_strerror (err));
+              
+              print_buffer (outbuf, blocklen);
+              putchar ('\n');
+
+              iptr += ilen;
+              inbuflen -= ilen;
+             }
+          while (inbuflen);
+        }
       else
-        err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen);
-      if (err)
-        die ("gcry_cipher_%scrypt failed: %s\n",
-             encrypt_mode? "en":"de", gpg_strerror (err));
-      print_buffer (outbuf, outbuflen);
+        {
+          if (encrypt_mode)
+            err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen);
+          else
+            err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen);
+          if (err)
+            die ("gcry_cipher_%scrypt failed: %s\n",
+                 encrypt_mode? "en":"de", gpg_strerror (err));
+          
+          print_buffer (outbuf, outbuflen);
+        }
     }
   while (inbuf);
 
@@ -1301,20 +1356,21 @@
      "MODE:\n"
      "  encrypt, decrypt, digest, random, hmac-sha, rsa-{gen,sign,verify}\n"
      "OPTIONS:\n"
-     "  --verbose        print additional information\n"
-     "  --binary         input and output is in binary form\n"
-     "  --no-fips        do not force FIPS mode\n"
-     "  --key KEY        use the hex encoded KEY\n"
-     "  --iv IV          use the hex encoded IV\n"
-     "  --dt DT          use the hex encoded DT for the RNG\n"
-     "  --algo NAME      use algorithm NAME\n"
-     "  --keysize N      use a keysize of N bits\n"
-     "  --signature NAME take signature from file NAME\n"
-     "  --chunk N        read in chunks of N bytes (implies --binary)\n"
-     "  --pkcs1          use PKCS#1 encoding\n"
-     "  --loop           enable random loop mode\n"
-     "  --progress       print pogress indicators\n"
-     "  --help           print this text\n"
+     "  --verbose        Print additional information\n"
+     "  --binary         Input and output is in binary form\n"
+     "  --no-fips        Do not force FIPS mode\n"
+     "  --key KEY        Use the hex encoded KEY\n"
+     "  --iv IV          Use the hex encoded IV\n"
+     "  --dt DT          Use the hex encoded DT for the RNG\n"
+     "  --algo NAME      Use algorithm NAME\n"
+     "  --keysize N      Use a keysize of N bits\n"
+     "  --signature NAME Take signature from file NAME\n"
+     "  --chunk N        Read in chunks of N bytes (implies --binary)\n"
+     "  --pkcs1          Use PKCS#1 encoding\n"
+     "  --print-ivs      Print input vectors\n"
+     "  --loop           Enable random loop mode\n"
+     "  --progress       Print pogress indicators\n"
+     "  --help           Print this text\n"
      "With no FILE, or when FILE is -, read standard input.\n"
      "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout);
   exit (0);
@@ -1448,6 +1504,11 @@
           use_pkcs1 = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--print-ivs"))
+        {
+          print_ivs = 1;
+          argc--; argv++;
+        }
     }          
 
   if (!argc || argc > 2)




More information about the Gnupg-commits mailing list