* encode.c (encode_simple): Fix problem with using compression algo 2 and
authorDavid Shaw <dshaw@jabberwocky.com>
Tue, 13 Aug 2002 19:00:23 +0000 (19:00 +0000)
committerDavid Shaw <dshaw@jabberwocky.com>
Tue, 13 Aug 2002 19:00:23 +0000 (19:00 +0000)
symmetric compressed files.

* encode.c (encode_simple, encode_crypt): If we are not using a MDC,
compress even if a file is already compressed.  This is to help against
the chosen ciphertext attack.

* pkclist.c (select_algo_from_prefs): Fix requested algorithm bug so the
request succeeds even if the requested algorithm is not the first found.

* cipher.c (write_header), encode.c (use_mdc, encode_simple, encode_crypt,
encrypt_filter), g10.c (main): Be more eager to use a MDC.  We use a MDC
if the keys directly support it, if the keys list AES (any) or TWOFISH
anywhere in the prefs, or if the cipher chosen does not have a 64 bit
blocksize.

g10/ChangeLog
g10/cipher.c
g10/encode.c
g10/g10.c
g10/pkclist.c

index 6fd61f3..708bd12 100644 (file)
@@ -1,3 +1,22 @@
+2002-08-13  David Shaw  <dshaw@jabberwocky.com>
+
+       * encode.c (encode_simple): Fix problem with using compression
+       algo 2 and symmetric compressed files.
+
+       * encode.c (encode_simple, encode_crypt): If we are not using a
+       MDC, compress even if a file is already compressed.  This is to
+       help against the chosen ciphertext attack.
+
+       * pkclist.c (select_algo_from_prefs): Fix requested algorithm bug
+       so the request succeeds even if the requested algorithm is not the
+       first found.
+
+       * cipher.c (write_header), encode.c (use_mdc, encode_simple,
+       encode_crypt, encrypt_filter), g10.c (main): Be more eager to use
+       a MDC.  We use a MDC if the keys directly support it, if the keys
+       list AES (any) or TWOFISH anywhere in the prefs, or if the cipher
+       chosen does not have a 64 bit blocksize.
+
 2002-08-08  David Shaw  <dshaw@jabberwocky.com>
 
        * options.skel: Some language tweaks, and remove the
index 2af8750..cb9f149 100644 (file)
@@ -47,31 +47,16 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
     byte temp[18];
     unsigned blocksize;
     unsigned nprefix;
-    int use_mdc;
 
     blocksize = cipher_get_blocksize( cfx->dek->algo );
     if( blocksize < 8 || blocksize > 16 )
        log_fatal("unsupported blocksize %u\n", blocksize );
 
-    use_mdc = cfx->dek->use_mdc;
-
-    if( blocksize != 8 )
-       use_mdc = 1;  /* Hack: enable it for all modern ciphers */
-    /* Note: We should remove this hack as soon as a reasonable number of keys
-       are carrying the MDC flag.  But always keep the hack for conventional
-       encryption */
-
-    if (opt.force_mdc)
-        use_mdc = 1;
-        
-    if( opt.rfc2440 || opt.rfc1991 || opt.disable_mdc )
-       use_mdc = 0;  /* override - rfc2440 does not know about MDC */
-
     memset( &ed, 0, sizeof ed );
     ed.len = cfx->datalen;
     ed.extralen = blocksize+2;
     ed.new_ctb = !ed.len && !opt.rfc1991;
-    if( use_mdc ) {
+    if( cfx->dek->use_mdc ) {
        ed.mdc_method = DIGEST_ALGO_SHA1;
        cfx->mdc_hash = md_open( DIGEST_ALGO_SHA1, 0 );
        if ( DBG_HASHING )
@@ -86,7 +71,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
     }
 
     init_packet( &pkt );
-    pkt.pkttype = use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED;
+    pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED;
     pkt.pkt.encrypted = &ed;
     if( build_packet( a, &pkt ))
        log_bug("build_packet(ENCR_DATA) failed\n");
@@ -96,7 +81,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a )
     temp[nprefix+1] = temp[nprefix-1];
     print_cipher_algo_note( cfx->dek->algo );
     cfx->cipher_hd = cipher_open( cfx->dek->algo,
-                                 use_mdc? CIPHER_MODE_CFB
+                                 cfx->dek->use_mdc? CIPHER_MODE_CFB
                                         : CIPHER_MODE_AUTO_CFB, 1 );
 /*   log_hexdump( "thekey", cfx->dek->key, cfx->dek->keylen );*/
     cipher_setkey( cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen );
index 87289cf..417685f 100644 (file)
@@ -102,6 +102,52 @@ encode_sesskey( DEK *dek, DEK **ret_dek, byte *enckey )
     *ret_dek = c;
 }
 
+/* We try very hard to use a MDC */
+static int
+use_mdc(PK_LIST pk_list,int algo)
+{
+  /* --force-mdc overrides --disable-mdc */
+  if(opt.force_mdc)
+    return 1;
+
+  if(opt.disable_mdc)
+    return 0;
+
+  /* Do the keys really support MDC? */
+
+  if(select_mdc_from_pklist(pk_list))
+    return 1;
+  
+  /* The keys don't support MDC, so now we do a bit of a hack - if any
+     of the AESes or TWOFISH are in the prefs, we assume that the user
+     can handle a MDC.  This is valid for PGP 7, which can handle MDCs
+     though it will not generate them.  2440bis allows this, by the
+     way. */
+
+  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
+                           CIPHER_ALGO_AES,NULL)==CIPHER_ALGO_AES)
+    return 1;
+
+  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
+                           CIPHER_ALGO_AES192,NULL)==CIPHER_ALGO_AES192)
+    return 1;
+
+  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
+                           CIPHER_ALGO_AES256,NULL)==CIPHER_ALGO_AES256)
+    return 1;
+
+  if(select_algo_from_prefs(pk_list,PREFTYPE_SYM,
+                           CIPHER_ALGO_TWOFISH,NULL)==CIPHER_ALGO_TWOFISH)
+    return 1;
+
+  /* Last try.  Use MDC for the modern ciphers. */
+
+  if(cipher_get_blocksize(algo)!=8)
+    return 1;
+
+  return 0; /* No MDC */
+}
+
 static int
 encode_simple( const char *filename, int mode, int compat )
 {
@@ -126,15 +172,6 @@ encode_simple( const char *filename, int mode, int compat )
     memset( &tfx, 0, sizeof tfx);
     init_packet(&pkt);
     
-    if (opt.compress == -1 && is_file_compressed(filename, &rc))
-      {
-        if (opt.verbose)
-          log_info(_("`%s' already compressed\n"), filename);
-        do_compress = 0;        
-      }
-    if (rc)
-        return rc;
-
     /* prepare iobufs */
     if( !(inp = iobuf_open(filename)) ) {
        log_error(_("%s: can't open: %s\n"), filename? filename: "[stdin]",
@@ -175,9 +212,19 @@ encode_simple( const char *filename, int mode, int compat )
             encode_sesskey( cfx.dek, &dek, enckey );
             m_free( cfx.dek ); cfx.dek = dek;
         }
+
+       cfx.dek->use_mdc=use_mdc(NULL,cfx.dek->algo);
     }
 
-    if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
+    if (opt.compress == -1 && cfx.dek && cfx.dek->use_mdc &&
+       is_file_compressed(filename, &rc))
+      {
+        if (opt.verbose)
+          log_info(_("`%s' already compressed\n"), filename);
+        do_compress = 0;        
+      }
+
+    if( rc || (rc = open_outfile( filename, opt.armor? 1:0, &out )) ) {
        iobuf_cancel(inp);
        m_free(cfx.dek);
        m_free(s2k);
@@ -271,7 +318,12 @@ encode_simple( const char *filename, int mode, int compat )
        iobuf_push_filter( out, cipher_filter, &cfx );
     /* register the compress filter */
     if( do_compress )
+      {
+       zfx.algo=opt.def_compress_algo;
+       if(zfx.algo==-1)
+         zfx.algo=DEFAULT_COMPRESS_ALGO;
        iobuf_push_filter( out, compress_filter, &zfx );
+      }
 
     /* do the work */
     if (!opt.no_literal) {
@@ -351,18 +403,6 @@ encode_crypt( const char *filename, STRLIST remusr )
          }
     }
 
-    if (opt.compress == -1 && is_file_compressed(filename, &rc2))
-      {
-        if (opt.verbose)
-          log_info(_("`%s' already compressed\n"), filename);
-        do_compress = 0;        
-      }
-    if (rc2)
-      {
-        rc = rc2;
-        goto leave;
-      }
-    
     /* prepare iobufs */
     if( !(inp = iobuf_open(filename)) ) {
        log_error(_("can't open %s: %s\n"), filename? filename: "[stdin]",
@@ -423,7 +463,26 @@ encode_crypt( const char *filename, STRLIST remusr )
 
       cfx.dek->algo = opt.def_cipher_algo;
     }
-    cfx.dek->use_mdc = select_mdc_from_pklist (pk_list);
+
+    cfx.dek->use_mdc=use_mdc(pk_list,cfx.dek->algo);
+
+    /* Only do the is-file-already-compressed check if we are using a
+       MDC.  This forces compressed files to be re-compressed if we do
+       not have a MDC to give some protection against chosen
+       ciphertext attacks. */
+
+    if (opt.compress == -1 && cfx.dek->use_mdc &&
+       is_file_compressed(filename, &rc2) )
+      {
+        if (opt.verbose)
+          log_info(_("`%s' already compressed\n"), filename);
+        do_compress = 0;        
+      }
+    if (rc2)
+      {
+        rc = rc2;
+        goto leave;
+      }
 
     make_session_key( cfx.dek );
     if( DBG_CIPHER )
@@ -578,7 +637,7 @@ encrypt_filter( void *opaque, int control,
              efx->cfx.dek->algo = opt.def_cipher_algo;
            }
 
-            efx->cfx.dek->use_mdc = select_mdc_from_pklist (efx->pk_list);
+            efx->cfx.dek->use_mdc = use_mdc(efx->pk_list,efx->cfx.dek->algo);
 
            make_session_key( efx->cfx.dek );
            if( DBG_CIPHER )
index 545c5b8..70c609c 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -1400,12 +1400,15 @@ main( int argc, char **argv )
            opt.rfc1991 = 1;
            opt.rfc2440 = 0;
            opt.force_v4_certs = 0;
-           opt.sk_comments = 0;
+           opt.disable_mdc = 1;
            opt.escape_from = 1;
            break;
          case oOpenPGP:
+           /* TODO: When 2440bis becomes a RFC, these may need
+               changing. */
            opt.rfc1991 = 0;
            opt.rfc2440 = 1;
+           opt.disable_mdc = 1;
            opt.allow_non_selfsigned_uid = 1;
            opt.allow_freeform_uid = 1;
            opt.pgp2_workarounds = 0;
index 671b568..cf6eca6 100644 (file)
@@ -1159,6 +1159,11 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype, int request, void *hint)
     i = -1;
     any = 0;
 
+    /* Can we use the requested algorithm? */
+    if(request>-1 && (bits[request/32] & (1<<(request%32))) &&
+       algo_available(preftype,request,hint))
+      return request;
+
     /* 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;
@@ -1190,10 +1195,6 @@ select_algo_from_prefs(PK_LIST pk_list, int preftype, int request, void *hint)
            }
     }
 
-    /* Can we use the requested algorithm? */
-    if(request>-1 && request==i)
-      return i;
-
   #if 0
     log_debug("prefs of type %d: selected %d\n", preftype, i );
   #endif