[git] GnuPG - branch, master, updated. gnupg-2.2.3-123-g112e02e

by Werner Koch cvs at cvs.gnupg.org
Tue Jan 23 12:58:13 CET 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Guard".

The branch, master has been updated
       via  112e02ee89b78369c1c50e672873e726cbfeb994 (commit)
       via  278d87465685e0aa415e0333de1d27e79d1608f0 (commit)
       via  9aab9167bca38323973e853845ca95ae8e9b6871 (commit)
       via  da3015e3c05030fe709c8f922486e73d06d1d16a (commit)
      from  0131d4369a81a51bf7bb328cc81a3bb082ed1a94 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 112e02ee89b78369c1c50e672873e726cbfeb994
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jan 23 12:50:11 2018 +0100

    gpg: Copy the AEAD prefs to the user ID struct.
    
    * g10/getkey.c (fixup_uidnode): Copy the AEAD prefs.
    --
    
    With this patch AEAD preferences are now properly created and
    displayed.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/getkey.c b/g10/getkey.c
index 497dace..a838c3c 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -2443,8 +2443,8 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated)
 {
   PKT_user_id *uid = uidnode->pkt->pkt.user_id;
   PKT_signature *sig = signode->pkt->pkt.signature;
-  const byte *p, *sym, *hash, *zip;
-  size_t n, nsym, nhash, nzip;
+  const byte *p, *sym, *aead, *hash, *zip;
+  size_t n, nsym, naead, nhash, nzip;
 
   sig->flags.chosen_selfsig = 1;/* We chose this one. */
   uid->created = 0;		/* Not created == invalid. */
@@ -2499,6 +2499,9 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated)
   p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_SYM, &n);
   sym = p;
   nsym = p ? n : 0;
+  p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_AEAD, &n);
+  aead = p;
+  naead = p ? n : 0;
   p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_HASH, &n);
   hash = p;
   nhash = p ? n : 0;
@@ -2507,7 +2510,7 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated)
   nzip = p ? n : 0;
   if (uid->prefs)
     xfree (uid->prefs);
-  n = nsym + nhash + nzip;
+  n = nsym + naead + nhash + nzip;
   if (!n)
     uid->prefs = NULL;
   else
@@ -2519,6 +2522,11 @@ fixup_uidnode (KBNODE uidnode, KBNODE signode, u32 keycreated)
 	  uid->prefs[n].type = PREFTYPE_SYM;
 	  uid->prefs[n].value = *sym++;
 	}
+      for (; naead; naead--, n++)
+	{
+	  uid->prefs[n].type = PREFTYPE_AEAD;
+	  uid->prefs[n].value = *aead++;
+	}
       for (; nhash; nhash--, n++)
 	{
 	  uid->prefs[n].type = PREFTYPE_HASH;

commit 278d87465685e0aa415e0333de1d27e79d1608f0
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jan 23 11:54:02 2018 +0100

    gpg: Clear the symmetric passphrase cache for encrypted session keys.
    
    * g10/mainproc.c (proc_symkey_enc): Clear the symmetric key cache on
    error.
    (proc_encrypted): Need to take are of the checksum error.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/mainproc.c b/g10/mainproc.c
index d1d44d7..accf25e 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -252,7 +252,6 @@ symkey_decrypt_seskey (DEK *dek, byte *seskey, size_t slen)
   gcry_cipher_hd_t hd;
   unsigned int noncelen, keylen;
   enum gcry_cipher_modes ciphermode;
-  byte ad[4];
 
   if (dek->use_aead)
     {
@@ -410,9 +409,17 @@ proc_symkey_enc (CTX c, PACKET *pkt)
                       log_info ("decryption of the symmetrically encrypted"
                                  " session key failed: %s\n",
                                  gpg_strerror (err));
-                      if (gpg_err_code (err) != GPG_ERR_BAD_KEY)
+                      if (gpg_err_code (err) != GPG_ERR_BAD_KEY
+                          && gpg_err_code (err) != GPG_ERR_CHECKSUM)
                         log_fatal ("process terminated to be bug compatible"
                                    " with GnuPG <= 2.2\n");
+                      if (c->dek->s2k_cacheid[0])
+                        {
+                          if (opt.debug)
+                            log_debug ("cleared passphrase cached with ID:"
+                                       " %s\n", c->dek->s2k_cacheid);
+                          passphrase_clear_cache (c->dek->s2k_cacheid);
+                        }
                       xfree (c->dek);
                       c->dek = NULL;
                     }
@@ -757,6 +764,7 @@ proc_encrypted (CTX c, PACKET *pkt)
   else
     {
       if ((gpg_err_code (result) == GPG_ERR_BAD_KEY
+	   || gpg_err_code (result) == GPG_ERR_CHECKSUM
 	   || gpg_err_code (result) == GPG_ERR_CIPHER_ALGO)
           && *c->dek->s2k_cacheid != '\0')
         {

commit 9aab9167bca38323973e853845ca95ae8e9b6871
Author: Werner Koch <wk at gnupg.org>
Date:   Tue Jan 23 12:07:25 2018 +0100

    gpg: Implement AEAD for SKESK packets.
    
    * g10/packet.h (PKT_symkey_enc): Add field aead_algo.
    * g10/build-packet.c (do_symkey_enc): Support version 5 packets.
    * g10/parse-packet.c (parse_symkeyenc): Ditto.
    * g10/encrypt.c (encrypt_symmetric): Force using a random session
    key in AEAD mode.
    (encrypt_seskey): Add and support arg aead_algo.
    (write_symkey_enc): Ditto.
    (encrypt_simple): Adjust accordingly.
    (encrypt_filter): Ditto.
    * g10/gpgcompose.c (sk_esk): For now call encrypt_seskey without AEAD
    support.
    * g10/mainproc.c (symkey_decrypt_seskey): Support AEAD.  Nver call BUG
    but return an error.
    (proc_symkey_enc): Call symkey_decrypt_seskey in a bug compatible way.
    
    * g10/import.c (check_prefs): Check AEAD preferences.
    * g10/keyedit.c (show_prefs): Print AEAD preferences.
    --
    
    For easier debugging this patch also changes some diagnostics to also
    print the encryption mode with the cipher algorithm.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/build-packet.c b/g10/build-packet.c
index fc64c9c..b4e03d0 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -617,11 +617,8 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
   IOBUF a = iobuf_temp();
 
   log_assert (ctb_pkttype (ctb) == PKT_SYMKEY_ENC);
+  log_assert (enc->version == 4 || enc->version == 5);
 
-  /* The only acceptable version.  */
-  log_assert( enc->version == 4 );
-
-  /* RFC 4880, Section 3.7.  */
   switch (enc->s2k.mode)
     {
     case 0: /* Simple S2K.  */
@@ -632,23 +629,26 @@ do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc )
     default:
       log_bug ("do_symkey_enc: s2k=%d\n", enc->s2k.mode);
     }
-    iobuf_put( a, enc->version );
-    iobuf_put( a, enc->cipher_algo );
-    iobuf_put( a, enc->s2k.mode );
-    iobuf_put( a, enc->s2k.hash_algo );
-    if( enc->s2k.mode == 1 || enc->s2k.mode == 3 ) {
-	iobuf_write(a, enc->s2k.salt, 8 );
-	if( enc->s2k.mode == 3 )
-	    iobuf_put(a, enc->s2k.count);
+  iobuf_put (a, enc->version);
+  iobuf_put (a, enc->cipher_algo);
+  if (enc->version == 5)
+    iobuf_put (a, enc->aead_algo);
+  iobuf_put (a, enc->s2k.mode);
+  iobuf_put (a, enc->s2k.hash_algo);
+  if (enc->s2k.mode == 1 || enc->s2k.mode == 3)
+    {
+      iobuf_write (a, enc->s2k.salt, 8);
+      if (enc->s2k.mode == 3)
+        iobuf_put (a, enc->s2k.count);
     }
-    if( enc->seskeylen )
-	iobuf_write(a, enc->seskey, enc->seskeylen );
+  if (enc->seskeylen)
+    iobuf_write (a, enc->seskey, enc->seskeylen);
 
-    write_header(out, ctb, iobuf_get_temp_length(a) );
-    rc = iobuf_write_temp( out, a );
+  write_header (out, ctb, iobuf_get_temp_length(a));
+  rc = iobuf_write_temp (out, a);
 
-    iobuf_close(a);
-    return rc;
+  iobuf_close (a);
+  return rc;
 }
 
 
diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c
index 7ed0bf0..46650f2 100644
--- a/g10/decrypt-data.c
+++ b/g10/decrypt-data.c
@@ -212,8 +212,10 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
   if ( opt.verbose && !dek->algo_info_printed )
     {
       if (!openpgp_cipher_test_algo (dek->algo))
-        log_info (_("%s encrypted data\n"),
-                  openpgp_cipher_algo_name (dek->algo));
+        log_info (_("%s.%s encrypted data\n"),
+                  openpgp_cipher_algo_name (dek->algo),
+                  ed->aead_algo? openpgp_aead_algo_name (ed->aead_algo)
+                  /**/         : "CFB");
       else
         log_info (_("encrypted with unknown algorithm %d\n"), dek->algo );
       dek->algo_info_printed = 1;
diff --git a/g10/encrypt.c b/g10/encrypt.c
index 4cc4b1a..c6c9e3a 100644
--- a/g10/encrypt.c
+++ b/g10/encrypt.c
@@ -47,12 +47,12 @@ static int write_pubkey_enc_from_list (ctrl_t ctrl,
 
 /****************
  * Encrypt FILENAME with only the symmetric cipher.  Take input from
- * stdin if FILENAME is NULL.
+ * stdin if FILENAME is NULL.  If --force-aead is used we use an SKESK.
  */
 int
 encrypt_symmetric (const char *filename)
 {
-  return encrypt_simple( filename, 1, 0 );
+  return encrypt_simple( filename, 1, opt.force_aead);
 }
 
 
@@ -70,14 +70,16 @@ encrypt_store (const char *filename)
 /* Encrypt a session key using DEK and store a pointer to the result
  * at R_ENCKEY and its length at R_ENCKEYLEN.
  *
- * R_SESKEY points to the unencrypted session key (.KEY, >KEYLEN) and
+ * R_SESKEY points to the unencrypted session key (.KEY, .KEYLEN) and
  * the algorithm that will be used to encrypt the contents of the
  * SKESK packet (.ALGO).  If R_SESKEY points to NULL, then a random
  * session key that is appropriate for DEK->ALGO is generated and
- * stored at R_SESKEY.
+ * stored at R_SESKEY.  If AEAD_ALGO is not 0 the given AEAD algorithm
+ * is used for encryption.
  */
 gpg_error_t
-encrypt_seskey (DEK *dek, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen)
+encrypt_seskey (DEK *dek, aead_algo_t aead_algo,
+                DEK **r_seskey, void **r_enckey, size_t *r_enckeylen)
 {
   gpg_error_t err;
   gcry_cipher_hd_t hd = NULL;
@@ -102,30 +104,84 @@ encrypt_seskey (DEK *dek, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen)
       /*log_hexdump( "thekey", c->key, c->keylen );*/
     }
 
-  buf = xtrymalloc_secure (1 + seskey->keylen);
-  if (!buf)
+
+  if (aead_algo)
     {
-      err = gpg_error_from_syserror ();
-      goto leave;
-    }
+      unsigned int noncelen;
+      enum gcry_cipher_modes ciphermode;
+      byte ad[4];
+
+      err = openpgp_aead_algo_info (aead_algo, &ciphermode, &noncelen);
+      if (err)
+        goto leave;
+
+      /* Allocate space for the nonce, the key, and the authentication
+       * tag (16).  */
+      buf = xtrymalloc_secure (noncelen + seskey->keylen + 16);
+      if (!buf)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
 
-  /* The encrypted session key is prefixed with a one-octet algorithm id.  */
-  buf[0] = seskey->algo;
-  memcpy (buf + 1, seskey->key, seskey->keylen);
-
-  err = openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1);
-  if (!err)
-    err =  gcry_cipher_setkey (hd, dek->key, dek->keylen);
-  if (!err)
-    err = gcry_cipher_setiv (hd, NULL, 0);
-  if (!err)
-    err = gcry_cipher_encrypt (hd, buf, seskey->keylen + 1, NULL, 0);
-  if (err)
-    goto leave;
+      gcry_randomize (buf, noncelen, GCRY_STRONG_RANDOM);
+
+      err = openpgp_cipher_open (&hd, dek->algo,
+                                 ciphermode, GCRY_CIPHER_SECURE);
+      if (!err)
+        err = gcry_cipher_setkey (hd, dek->key, dek->keylen);
+      if (!err)
+        err = gcry_cipher_setiv (hd, buf, noncelen);
+      if (err)
+        goto leave;
+
+      ad[0] = (0xc0 | PKT_SYMKEY_ENC);
+      ad[1] = 5;
+      ad[2] = dek->algo;
+      ad[3] = aead_algo;
+      err = gcry_cipher_authenticate (hd, ad, 4);
+      if (err)
+        goto leave;
+
+      memcpy (buf + noncelen, seskey->key, seskey->keylen);
+      gcry_cipher_final (hd);
+      err = gcry_cipher_encrypt (hd, buf + noncelen, seskey->keylen, NULL,0);
+      if (err)
+        goto leave;
+      err = gcry_cipher_gettag (hd, buf + noncelen + seskey->keylen, 16);
+      if (err)
+        goto leave;
+      *r_enckeylen = noncelen + seskey->keylen + 16;
+      *r_enckey = buf;
+      buf = NULL;
+    }
+  else
+    {
+      /* In the old version 4 SKESK the encrypted session key is
+       * prefixed with a one-octet algorithm id.  */
+      buf = xtrymalloc_secure (1 + seskey->keylen);
+      if (!buf)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      buf[0] = seskey->algo;
+      memcpy (buf + 1, seskey->key, seskey->keylen);
+
+      err = openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1);
+      if (!err)
+        err = gcry_cipher_setkey (hd, dek->key, dek->keylen);
+      if (!err)
+        err = gcry_cipher_setiv (hd, NULL, 0);
+      if (!err)
+        err = gcry_cipher_encrypt (hd, buf, seskey->keylen + 1, NULL, 0);
+      if (err)
+        goto leave;
+      *r_enckeylen = seskey->keylen + 1;
+      *r_enckey = buf;
+      buf = NULL;
+    }
 
-  *r_enckey = buf;
-  buf = NULL;
-  *r_enckeylen = seskey->keylen + 1;
   /* Return the session key in case we allocated it.  */
   *r_seskey = seskey;
   seskey = NULL;
@@ -332,7 +388,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
         {
           DEK *dek = NULL;
 
-          rc = encrypt_seskey (cfx.dek, &dek, &enckey, &enckeylen);
+          rc = encrypt_seskey (cfx.dek, aead_algo, &dek, &enckey, &enckeylen);
           if (rc)
             {
               xfree (cfx.dek);
@@ -346,14 +402,16 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
           cfx.dek = dek;
         }
 
-      if (opt.verbose)
-        log_info(_("using cipher %s\n"),
-                 openpgp_cipher_algo_name (cfx.dek->algo));
-
       if (aead_algo)
         cfx.dek->use_aead = aead_algo;
       else
         cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo);
+
+      if (opt.verbose)
+        log_info(_("using cipher %s.%s\n"),
+                 openpgp_cipher_algo_name (cfx.dek->algo),
+                 cfx.dek->use_aead? openpgp_aead_algo_name (cfx.dek->use_aead)
+                 /**/             : "CFB");
     }
 
   if (do_compress
@@ -385,8 +443,9 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
     {
       /* Fixme: This is quite similar to write_symkey_enc.  */
       PKT_symkey_enc *enc = xmalloc_clear (sizeof *enc + enckeylen);
-      enc->version = 4;
+      enc->version = cfx.dek->use_aead ? 5 : 4;
       enc->cipher_algo = cfx.dek->algo;
+      enc->aead_algo = cfx.dek->use_aead;
       enc->s2k = *s2k;
       if (enckeylen)
         {
@@ -535,8 +594,8 @@ setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek)
 
 
 static int
-write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
-                  iobuf_t out)
+write_symkey_enc (STRING2KEY *symkey_s2k, aead_algo_t aead_algo,
+                  DEK *symkey_dek, DEK *dek, iobuf_t out)
 {
   int rc;
   void *enckey;
@@ -544,7 +603,7 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
   PKT_symkey_enc *enc;
   PACKET pkt;
 
-  rc = encrypt_seskey (symkey_dek, &dek, &enckey, &enckeylen);
+  rc = encrypt_seskey (symkey_dek, aead_algo, &dek, &enckey, &enckeylen);
   if (rc)
     return rc;
   enc = xtrycalloc (1, sizeof (PKT_symkey_enc) + enckeylen);
@@ -555,8 +614,9 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
       return rc;
     }
 
-  enc->version = 4;
+  enc->version = aead_algo? 5 : 4;
   enc->cipher_algo = opt.s2k_cipher_algo;
+  enc->aead_algo = aead_algo;
   enc->s2k = *symkey_s2k;
   enc->seskeylen = enckeylen;
   memcpy (enc->seskey, enckey, enckeylen);
@@ -813,10 +873,11 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
     goto leave;
 
   /* We put the passphrase (if any) after any public keys as this
-     seems to be the most useful on the recipient side - there is no
-     point in prompting a user for a passphrase if they have the
-     secret key needed to decrypt.  */
-  if(use_symkey && (rc = write_symkey_enc(symkey_s2k,symkey_dek,cfx.dek,out)))
+   * seems to be the most useful on the recipient side - there is no
+   * point in prompting a user for a passphrase if they have the
+   * secret key needed to decrypt.  */
+  if (use_symkey && (rc = write_symkey_enc (symkey_s2k, cfx.dek->use_aead,
+                                            symkey_dek, cfx.dek, out)))
     goto leave;
 
   if (!opt.no_literal)
@@ -1014,9 +1075,9 @@ encrypt_filter (void *opaque, int control,
 
           if(efx->symkey_s2k && efx->symkey_dek)
             {
-              rc=write_symkey_enc(efx->symkey_s2k,efx->symkey_dek,
-                                  efx->cfx.dek,a);
-              if(rc)
+              rc = write_symkey_enc (efx->symkey_s2k, efx->cfx.dek->use_aead,
+                                     efx->symkey_dek, efx->cfx.dek, a);
+              if (rc)
                 return rc;
             }
 
@@ -1084,9 +1145,11 @@ write_pubkey_enc (ctrl_t ctrl,
       if ( opt.verbose )
         {
           char *ustr = get_user_id_string_native (ctrl, enc->keyid);
-          log_info (_("%s/%s encrypted for: \"%s\"\n"),
+          log_info (_("%s/%s.%s encrypted for: \"%s\"\n"),
                     openpgp_pk_algo_name (enc->pubkey_algo),
                     openpgp_cipher_algo_name (dek->algo),
+                    dek->use_aead? openpgp_aead_algo_name (dek->use_aead)
+                    /**/         : "CFB",
                     ustr );
           xfree (ustr);
         }
diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c
index f22c7c2..094bc76 100644
--- a/g10/gpgcompose.c
+++ b/g10/gpgcompose.c
@@ -2284,7 +2284,7 @@ sk_esk (const char *option, int argc, char *argv[], void *cookie)
 
       /* Now encrypt the session key (or rather, the algorithm used to
          encrypt the SKESK plus the session key) using ENCKEY.  */
-      err = encrypt_seskey (&s2kdek, &sesdekp,
+      err = encrypt_seskey (&s2kdek, 0, &sesdekp,
                             (void**)&ske->seskey, (size_t *)&ske->seskeylen);
       if (err)
         log_fatal ("encrypt_seskey failed: %s\n", gpg_strerror (err));
diff --git a/g10/import.c b/g10/import.c
index 71e3955..ed679d5 100644
--- a/g10/import.c
+++ b/g10/import.c
@@ -1113,6 +1113,24 @@ check_prefs (ctrl_t ctrl, kbnode_t keyblock)
 		      problem=1;
 		    }
 		}
+	      else if(prefs->type==PREFTYPE_AEAD)
+		{
+		  if (openpgp_aead_test_algo (prefs->value))
+		    {
+                      /* FIXME: The test below is wrong.  We should
+                       * check if ...algo_name yields a "?" and
+                       * only in that case use NUM.  */
+		      const char *algo =
+                        (openpgp_aead_test_algo (prefs->value)
+                         ? num
+                         : openpgp_aead_algo_name (prefs->value));
+		      if(!problem)
+			check_prefs_warning(pk);
+		      log_info(_("         \"%s\": preference for AEAD"
+				 " algorithm %s\n"), user, algo);
+		      problem=1;
+		    }
+		}
 	      else if(prefs->type==PREFTYPE_HASH)
 		{
 		  if(openpgp_md_test_algo(prefs->value))
@@ -2255,6 +2273,7 @@ transfer_secret_keys (ctrl_t ctrl, struct import_stats_s *stats,
         {
           char countbuf[35];
 
+          /* FIXME: Support AEAD */
           /* Note that the IVLEN may be zero if we are working on a
              dummy key.  We can't express that in an S-expression and
              thus we send dummy data for the IV.  */
diff --git a/g10/keyedit.c b/g10/keyedit.c
index 81344eb..3ae96a3 100644
--- a/g10/keyedit.c
+++ b/g10/keyedit.c
@@ -3064,6 +3064,23 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
 	  tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
 	}
       tty_printf ("\n     ");
+      tty_printf (_("AEAD: "));
+      for (i = any = 0; prefs[i].type; i++)
+	{
+	  if (prefs[i].type == PREFTYPE_AEAD)
+	    {
+	      if (any)
+		tty_printf (", ");
+	      any = 1;
+	      /* We don't want to display strings for experimental algos */
+	      if (!openpgp_aead_test_algo (prefs[i].value)
+		  && prefs[i].value < 100)
+		tty_printf ("%s", openpgp_aead_algo_name (prefs[i].value));
+	      else
+		tty_printf ("[%d]", prefs[i].value);
+	    }
+	}
+      tty_printf ("\n     ");
       tty_printf (_("Digest: "));
       for (i = any = 0; prefs[i].type; i++)
 	{
@@ -3172,6 +3189,7 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
       for (i = 0; prefs[i].type; i++)
 	{
 	  tty_printf (" %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
+		      prefs[i].type == PREFTYPE_AEAD ? 'A' :
 		      prefs[i].type == PREFTYPE_HASH ? 'H' :
 		      prefs[i].type == PREFTYPE_ZIP ? 'Z' : '?',
 		      prefs[i].value);
diff --git a/g10/main.h b/g10/main.h
index 96899ac..a02c574 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -235,7 +235,7 @@ void display_online_help( const char *keyword );
 
 /*-- encode.c --*/
 int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
-gpg_error_t encrypt_seskey (DEK *dek, DEK **r_seskey,
+gpg_error_t encrypt_seskey (DEK *dek, aead_algo_t aead_algo, DEK **r_seskey,
                             void **r_enckey, size_t *r_enckeylen);
 aead_algo_t use_aead (pk_list_t pk_list, int algo);
 int use_mdc (pk_list_t pk_list,int algo);
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 92da982..d1d44d7 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -245,46 +245,102 @@ add_signature (CTX c, PACKET *pkt)
   return 1;
 }
 
-static int
+static gpg_error_t
 symkey_decrypt_seskey (DEK *dek, byte *seskey, size_t slen)
 {
+  gpg_error_t err;
   gcry_cipher_hd_t hd;
+  unsigned int noncelen, keylen;
+  enum gcry_cipher_modes ciphermode;
+  byte ad[4];
+
+  if (dek->use_aead)
+    {
+      err = openpgp_aead_algo_info (dek->use_aead, &ciphermode, &noncelen);
+      if (err)
+        return err;
+    }
+  else
+    {
+      ciphermode = GCRY_CIPHER_MODE_CFB;
+      noncelen = 0;
+    }
 
-  if(slen < 17 || slen > 33)
+  /* Check that the session key has a size of 16 to 32 bytes.  */
+  if ((dek->use_aead && (slen < (noncelen + 16 + 16)
+                         || slen > (noncelen + 32 + 16)))
+      || (!dek->use_aead && (slen < 17 || slen > 33)))
     {
       log_error ( _("weird size for an encrypted session key (%d)\n"),
 		  (int)slen);
-      return GPG_ERR_BAD_KEY;
+      return gpg_error (GPG_ERR_BAD_KEY);
     }
 
-  if (openpgp_cipher_open (&hd, dek->algo, GCRY_CIPHER_MODE_CFB, 1))
-      BUG ();
-  if (gcry_cipher_setkey ( hd, dek->key, dek->keylen ))
-    BUG ();
-  gcry_cipher_setiv ( hd, NULL, 0 );
-  gcry_cipher_decrypt ( hd, seskey, slen, NULL, 0 );
-  gcry_cipher_close ( hd );
-
-  /* Now we replace the dek components with the real session key to
-     decrypt the contents of the sequencing packet. */
-
-  dek->keylen=slen-1;
-  dek->algo=seskey[0];
+  err = openpgp_cipher_open (&hd, dek->algo, ciphermode, GCRY_CIPHER_SECURE);
+  if (!err)
+    err = gcry_cipher_setkey (hd, dek->key, dek->keylen);
+  if (!err)
+    err = gcry_cipher_setiv (hd, noncelen? seskey : NULL, noncelen);
+  if (err)
+    goto leave;
 
-  if(dek->keylen > DIM(dek->key))
-    BUG ();
-
-  memcpy(dek->key, seskey + 1, dek->keylen);
+  if (dek->use_aead)
+    {
+      byte ad[4];
+
+      ad[0] = (0xc0 | PKT_SYMKEY_ENC);
+      ad[1] = 5;
+      ad[2] = dek->algo;
+      ad[3] = dek->use_aead;
+      err = gcry_cipher_authenticate (hd, ad, 4);
+      if (err)
+        goto leave;
+      gcry_cipher_final (hd);
+      keylen = slen - noncelen - 16;
+      err = gcry_cipher_decrypt (hd, seskey+noncelen, keylen, NULL, 0);
+      if (err)
+        goto leave;
+      err = gcry_cipher_checktag (hd, seskey+noncelen+keylen, 16);
+      if (err)
+        goto leave;
+      /* Now we replace the dek components with the real session key to
+       * decrypt the contents of the sequencing packet. */
+      if (keylen > DIM(dek->key))
+        {
+          err = gpg_error (GPG_ERR_TOO_LARGE);
+          goto leave;
+        }
+      dek->keylen = keylen;
+      memcpy (dek->key, seskey + noncelen, dek->keylen);
+    }
+  else
+    {
+      gcry_cipher_decrypt (hd, seskey, slen, NULL, 0 );
+      /* Now we replace the dek components with the real session key to
+       * decrypt the contents of the sequencing packet. */
+      keylen = slen-1;
+      if (keylen > DIM(dek->key))
+        {
+          err = gpg_error (GPG_ERR_TOO_LARGE);
+          goto leave;
+        }
+      dek->algo = seskey[0];
+      dek->keylen = keylen;
+      memcpy (dek->key, seskey + 1, dek->keylen);
+    }
 
   /*log_hexdump( "thekey", dek->key, dek->keylen );*/
 
-  return 0;
+ leave:
+  gcry_cipher_close (hd);
+  return err;
 }
 
 
 static void
 proc_symkey_enc (CTX c, PACKET *pkt)
 {
+  gpg_error_t err;
   PKT_symkey_enc *enc;
 
   enc = pkt->pkt.symkey_enc;
@@ -294,19 +350,21 @@ proc_symkey_enc (CTX c, PACKET *pkt)
     {
       int algo = enc->cipher_algo;
       const char *s = openpgp_cipher_algo_name (algo);
+      const char *a = (enc->aead_algo ? openpgp_aead_algo_name (enc->aead_algo)
+                       /**/           : "CFB");
 
       if (!openpgp_cipher_test_algo (algo))
         {
           if (!opt.quiet)
             {
               if (enc->seskeylen)
-                log_info (_("%s encrypted session key\n"), s );
+                log_info (_("%s.%s encrypted session key\n"), s, a );
               else
-                log_info (_("%s encrypted data\n"), s );
+                log_info (_("%s.%s encrypted data\n"), s, a );
             }
         }
       else
-        log_error (_("encrypted with unknown algorithm %d\n"), algo);
+        log_error (_("encrypted with unknown algorithm %d.%s\n"), algo, a);
 
       if (openpgp_md_test_algo (enc->s2k.hash_algo))
         {
@@ -334,6 +392,7 @@ proc_symkey_enc (CTX c, PACKET *pkt)
           if (c->dek)
             {
               c->dek->symmetric = 1;
+              c->dek->use_aead = enc->aead_algo;
 
               /* FIXME: This doesn't work perfectly if a symmetric key
                  comes before a public key in the message - if the
@@ -344,9 +403,16 @@ proc_symkey_enc (CTX c, PACKET *pkt)
                  come later. */
               if (enc->seskeylen)
                 {
-                  if (symkey_decrypt_seskey (c->dek,
-                                             enc->seskey, enc->seskeylen))
+                  err = symkey_decrypt_seskey (c->dek,
+                                               enc->seskey, enc->seskeylen);
+                  if (err)
                     {
+                      log_info ("decryption of the symmetrically encrypted"
+                                 " session key failed: %s\n",
+                                 gpg_strerror (err));
+                      if (gpg_err_code (err) != GPG_ERR_BAD_KEY)
+                        log_fatal ("process terminated to be bug compatible"
+                                   " with GnuPG <= 2.2\n");
                       xfree (c->dek);
                       c->dek = NULL;
                     }
diff --git a/g10/packet.h b/g10/packet.h
index 4d15574..4f4569f 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -94,12 +94,14 @@ typedef struct
 /* A symmetric-key encrypted session key packet as defined in RFC
    4880, Section 5.3.  All fields are serialized.  */
 typedef struct {
-  /* RFC 4880: this must be 4.  */
+  /* We support version 4 (rfc4880) and 5 (rfc4880bis).  */
   byte version;
-  /* The cipher algorithm used to encrypt the session key.  (This may
-     be different from the algorithm that is used to encrypt the SED
-     packet.)  */
+  /* The cipher algorithm used to encrypt the session key.  Note that
+   * this may be different from the algorithm that is used to encrypt
+   * bulk data.  */
   byte cipher_algo;
+  /* The AEAD algorithm or 0 for CFB encryption.  */
+  byte aead_algo;
   /* The string-to-key specifier.  */
   STRING2KEY s2k;
   /* The length of SESKEY in bytes or 0 if this packet does not
@@ -107,7 +109,8 @@ typedef struct {
      S2K function on the password is the session key. See RFC 4880,
      Section 5.3.)  */
   byte seskeylen;
-  /* The session key as encrypted by the S2K specifier.  */
+  /* The session key as encrypted by the S2K specifier.  For AEAD this
+   * includes the nonce and the authentication tag.  */
   byte seskey[1];
 } PKT_symkey_enc;
 
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index de51770..5c6d364 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -1105,7 +1105,7 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
 {
   PKT_symkey_enc *k;
   int rc = 0;
-  int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen;
+  int i, version, s2kmode, cipher_algo, aead_algo, hash_algo, seskeylen, minlen;
 
   if (pktlen < 4)
     {
@@ -1117,7 +1117,11 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
     }
   version = iobuf_get_noeof (inp);
   pktlen--;
-  if (version != 4)
+  if (version == 4)
+    ;
+  else if (version == 5)
+    ;
+  else
     {
       log_error ("packet(%d) with unknown version %d\n", pkttype, version);
       if (list_mode)
@@ -1135,6 +1139,13 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
     }
   cipher_algo = iobuf_get_noeof (inp);
   pktlen--;
+  if (version == 5)
+    {
+      aead_algo = iobuf_get_noeof (inp);
+      pktlen--;
+    }
+  else
+    aead_algo = 0;
   s2kmode = iobuf_get_noeof (inp);
   pktlen--;
   hash_algo = iobuf_get_noeof (inp);
@@ -1169,6 +1180,7 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
 					      + seskeylen - 1);
   k->version = version;
   k->cipher_algo = cipher_algo;
+  k->aead_algo = aead_algo;
   k->s2k.mode = s2kmode;
   k->s2k.hash_algo = hash_algo;
   if (s2kmode == 1 || s2kmode == 3)
@@ -1199,10 +1211,20 @@ parse_symkeyenc (IOBUF inp, int pkttype, unsigned long pktlen,
   if (list_mode)
     {
       es_fprintf (listfp,
-                  ":symkey enc packet: version %d, cipher %d, s2k %d, hash %d",
-                  version, cipher_algo, s2kmode, hash_algo);
+                  ":symkey enc packet: version %d, cipher %d, aead %d,"
+                  " s2k %d, hash %d",
+                  version, cipher_algo, aead_algo, s2kmode, hash_algo);
       if (seskeylen)
-	es_fprintf (listfp, ", seskey %d bits", (seskeylen - 1) * 8);
+        {
+          /* To compute the size of the session key we need to know
+           * the size of the AEAD nonce which we may not know.  Thus
+           * we show only the seize of the entire encrypted session
+           * key.  */
+          if (aead_algo)
+            es_fprintf (listfp, ", encrypted seskey %d bytes", seskeylen);
+          else
+            es_fprintf (listfp, ", seskey %d bits", (seskeylen - 1) * 8);
+        }
       es_fprintf (listfp, "\n");
       if (s2kmode == 1 || s2kmode == 3)
 	{
diff --git a/g10/sign.c b/g10/sign.c
index 7045e8c..df71ccc 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -1326,9 +1326,6 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr)
     s2k->hash_algo = S2K_DIGEST_ALGO;
 
     algo = default_cipher_algo();
-    if (!opt.quiet || !opt.batch)
-        log_info (_("%s encryption will be used\n"),
-                  openpgp_cipher_algo_name (algo) );
     cfx.dek = passphrase_to_dek (algo, s2k, 1, 1, NULL, &canceled);
 
     if (!cfx.dek || !cfx.dek->keylen) {
@@ -1341,6 +1338,12 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr)
     if (!cfx.dek->use_aead)
       cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo);
 
+    if (!opt.quiet || !opt.batch)
+        log_info (_("%s.%s encryption will be used\n"),
+                  openpgp_cipher_algo_name (algo),
+                  cfx.dek->use_aead? openpgp_aead_algo_name (cfx.dek->use_aead)
+                  /**/             : "CFB");
+
     /* now create the outfile */
     rc = open_outfile (-1, fname, opt.armor? 1:0, 0, &out);
     if (rc)

commit da3015e3c05030fe709c8f922486e73d06d1d16a
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Jan 22 16:23:02 2018 +0100

    gpg: Unify AEAD parameter retrieval.
    
    * g10/pkclist.c (select_aead_from_pklist): Return the AEAD_algo.
    * g10/encrypt.c (use_aead): Return the AEAD algo.
    (encrypt_simple): Adjust for this change.
    (encrypt_crypt): Ditto.
    (encrypt_filter): Ditto.
    * g10/sign.c (sign_symencrypt_file): Ditto.
    
    * g10/misc.c (MY_GCRY_CIPHER_MODE_EAX): New.
    (openpgp_aead_algo_info): New.
    * g10/cipher-aead.c (MY_GCRY_CIPHER_MODE_EAX): Remove.
    (write_header): Use new fucntion.
    * g10/decrypt-data.c (MY_GCRY_CIPHER_MODE_EAX): Remove.
    (decrypt_data): Use new function.  Also allow for chunkbytes other
    than 10.
    --
    
    Note that other chunk bytes than 10 and in particular 0 (64 byte
    chunks) have not yet been tested.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/cipher-aead.c b/g10/cipher-aead.c
index 1d72634..637bd71 100644
--- a/g10/cipher-aead.c
+++ b/g10/cipher-aead.c
@@ -33,10 +33,6 @@
 #include "options.h"
 #include "main.h"
 
-/* FIXME: Libgcrypt 1.9 will support EAX.  Until we kame this a
- * requirement we hardwire the enum used for EAX.  */
-#define MY_GCRY_CIPHER_MODE_EAX 14
-
 
 /* The size of the buffer we allocate to encrypt the data.  This must
  * be a multiple of the OCB blocksize (16 byte).  */
@@ -149,23 +145,9 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a)
   if (blocksize != 16 )
     log_fatal ("unsupported blocksize %u for AEAD\n", blocksize);
 
-  switch (cfx->dek->use_aead)
-    {
-    case AEAD_ALGO_OCB:
-      ciphermode = GCRY_CIPHER_MODE_OCB;
-      startivlen = 15;
-      break;
-
-    case AEAD_ALGO_EAX:
-      ciphermode = MY_GCRY_CIPHER_MODE_EAX;
-      startivlen = 16;
-      break;
-
-    default:
-      log_error ("unsupported AEAD algo %d\n", cfx->dek->use_aead);
-      err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
-      goto leave;
-    }
+  err = openpgp_aead_algo_info (cfx->dek->use_aead, &ciphermode, &startivlen);
+  if (err)
+    goto leave;
 
   cfx->chunkbyte = 10;
   cfx->chunksize = (uint64_t)1 << (cfx->chunkbyte + 6);
diff --git a/g10/decrypt-data.c b/g10/decrypt-data.c
index 79e2554..7ed0bf0 100644
--- a/g10/decrypt-data.c
+++ b/g10/decrypt-data.c
@@ -31,10 +31,6 @@
 #include "../common/status.h"
 #include "../common/compliance.h"
 
-/* FIXME: Libgcrypt 1.9 will support EAX.  Until we kame this a
- * requirement we hardwire the enum used for EAX.  */
-#define MY_GCRY_CIPHER_MODE_EAX 14
-
 
 static int aead_decode_filter (void *opaque, int control, iobuf_t a,
                                byte *buf, size_t *ret_len);
@@ -274,28 +270,15 @@ decrypt_data (ctrl_t ctrl, void *procctx, PKT_encrypted *ed, DEK *dek)
           goto leave;
         }
 
-      switch (ed->aead_algo)
-        {
-        case AEAD_ALGO_OCB:
-          startivlen = 15;
-          ciphermode = GCRY_CIPHER_MODE_OCB;
-          break;
-        case AEAD_ALGO_EAX:
-          startivlen = 16;
-          ciphermode = MY_GCRY_CIPHER_MODE_EAX;
-          break;
-        default:
-          log_error ("unknown AEAD algo %d\n", ed->aead_algo);
-          rc = gpg_error (GPG_ERR_INV_CIPHER_MODE);
-          goto leave;
-        }
+      rc = openpgp_aead_algo_info (ed->aead_algo, &ciphermode, &startivlen);
+      if (rc)
+        goto leave;
       log_assert (startivlen <= sizeof dfx->startiv);
 
-      if (ed->chunkbyte != 10)
+      if (ed->chunkbyte > 56)
         {
-          /* FIXME */
-          log_error ("unsupported chunkbyte %u\n", ed->chunkbyte);
-          rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+          log_error ("invalid AEAD chunkbyte %u\n", ed->chunkbyte);
+          rc = gpg_error (GPG_ERR_INV_PACKET);
           goto leave;
         }
 
diff --git a/g10/encrypt.c b/g10/encrypt.c
index ab745ce..4cc4b1a 100644
--- a/g10/encrypt.c
+++ b/g10/encrypt.c
@@ -139,8 +139,9 @@ encrypt_seskey (DEK *dek, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen)
 }
 
 
-/* Return true if we shall use AEAD mode.  */
-int
+/* Return the AEAD algo if we shall use AEAD mode.  Returns 0 if AEAD
+ * shall not be used.  */
+aead_algo_t
 use_aead (pk_list_t pk_list, int algo)
 {
   int can_use;
@@ -168,7 +169,7 @@ use_aead (pk_list_t pk_list, int algo)
                     openpgp_cipher_algo_name (algo));
           return 0;
         }
-      return 1;
+      return default_aead_algo ();
     }
 
   /* AEAD does only work with 128 bit cipher blocklength.  */
@@ -176,10 +177,7 @@ use_aead (pk_list_t pk_list, int algo)
     return 0;
 
   /* If all keys support AEAD we can use it.  */
-  if (select_aead_from_pklist (pk_list))
-    return 1;
-
-  return 0; /* No AEAD. */
+  return select_aead_from_pklist (pk_list);
 }
 
 
@@ -328,7 +326,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
         }
 
       /* See whether we want to use AEAD.  */
-      aead_algo = use_aead (NULL, cfx.dek->algo)? default_aead_algo () : 0;
+      aead_algo = use_aead (NULL, cfx.dek->algo);
 
       if ( use_seskey )
         {
@@ -784,9 +782,8 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename,
                           gnupg_status_compliance_flag (CO_DE_VS),
                           NULL);
 
-  if (use_aead (pk_list, cfx.dek->algo))
-    cfx.dek->use_aead = 1;
-  else
+  cfx.dek->use_aead = use_aead (pk_list, cfx.dek->algo);
+  if (!cfx.dek->use_aead)
     cfx.dek->use_mdc = !!use_mdc (pk_list, cfx.dek->algo);
 
   /* Only do the is-file-already-compressed check if we are using a
@@ -1002,9 +999,8 @@ encrypt_filter (void *opaque, int control,
 	      efx->cfx.dek->algo = opt.def_cipher_algo;
 	    }
 
-          if (use_aead (efx->pk_list, efx->cfx.dek->algo))
-            efx->cfx.dek->use_aead = 1;
-          else
+          efx->cfx.dek->use_aead = use_aead (efx->pk_list, efx->cfx.dek->algo);
+          if (!efx->cfx.dek->use_aead)
             efx->cfx.dek->use_mdc = !!use_mdc (efx->pk_list,efx->cfx.dek->algo);
 
           make_session_key ( efx->cfx.dek );
diff --git a/g10/keydb.h b/g10/keydb.h
index 9f6064b..f2ea8a7 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -232,7 +232,7 @@ int  algo_available( preftype_t preftype, int algo,
 int  select_algo_from_prefs( PK_LIST pk_list, int preftype,
 			     int request, const union pref_hint *hint);
 int  select_mdc_from_pklist (PK_LIST pk_list);
-int  select_aead_from_pklist (pk_list_t pk_list);
+aead_algo_t select_aead_from_pklist (pk_list_t pk_list);
 void warn_missing_mdc_from_pklist (PK_LIST pk_list);
 void warn_missing_aes_from_pklist (PK_LIST pk_list);
 
diff --git a/g10/main.h b/g10/main.h
index 509126c..96899ac 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -127,6 +127,9 @@ const char *openpgp_cipher_algo_name (cipher_algo_t algo);
 
 gpg_error_t openpgp_aead_test_algo (aead_algo_t algo);
 const char *openpgp_aead_algo_name (aead_algo_t algo);
+gpg_error_t openpgp_aead_algo_info (aead_algo_t algo,
+                                    enum gcry_cipher_modes *r_mode,
+                                    unsigned int *r_noncelen);
 
 pubkey_algo_t map_pk_gcry_to_openpgp (enum gcry_pk_algos algo);
 int openpgp_pk_test_algo (pubkey_algo_t algo);
@@ -234,7 +237,7 @@ void display_online_help( const char *keyword );
 int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
 gpg_error_t encrypt_seskey (DEK *dek, DEK **r_seskey,
                             void **r_enckey, size_t *r_enckeylen);
-int use_aead (pk_list_t pk_list, int algo);
+aead_algo_t use_aead (pk_list_t pk_list, int algo);
 int use_mdc (pk_list_t pk_list,int algo);
 int encrypt_symmetric (const char *filename );
 int encrypt_store (const char *filename );
diff --git a/g10/misc.c b/g10/misc.c
index f7ac3c7..36d3bdc 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -70,6 +70,11 @@
 #include "../common/zb32.h"
 
 
+/* FIXME: Libgcrypt 1.9 will support EAX.  Until we kame this a
+ * requirement we hardwire the enum used for EAX.  */
+#define MY_GCRY_CIPHER_MODE_EAX 14
+
+
 #ifdef ENABLE_SELINUX_HACKS
 /* A object and a global variable to keep track of files marked as
    secured. */
@@ -616,6 +621,34 @@ openpgp_aead_algo_name (aead_algo_t algo)
 }
 
 
+/* Return information for the AEAD algorithm ALGO.  The corresponding
+ * Libgcrypt ciphermode is stored at R_MODE and the required number of
+ * octets for the nonce at R_NONCELEN.  On error and error code is
+ * returned.  Note that the taglen is always 128 bits.  */
+gpg_error_t
+openpgp_aead_algo_info (aead_algo_t algo, enum gcry_cipher_modes *r_mode,
+                        unsigned int *r_noncelen)
+{
+  switch (algo)
+    {
+    case AEAD_ALGO_OCB:
+      *r_mode = GCRY_CIPHER_MODE_OCB;
+      *r_noncelen = 15;
+      break;
+
+    case AEAD_ALGO_EAX:
+      *r_mode = MY_GCRY_CIPHER_MODE_EAX;
+      *r_noncelen = 16;
+      break;
+
+    default:
+      log_error ("unsupported AEAD algo %d\n", algo);
+      return gpg_error (GPG_ERR_INV_CIPHER_MODE);
+    }
+  return 0;
+}
+
+
 /* Return 0 if ALGO is a supported OpenPGP public key algorithm.  */
 int
 openpgp_pk_test_algo (pubkey_algo_t algo)
diff --git a/g10/pkclist.c b/g10/pkclist.c
index b85efa4..6ec5537 100644
--- a/g10/pkclist.c
+++ b/g10/pkclist.c
@@ -1652,8 +1652,9 @@ select_mdc_from_pklist (PK_LIST pk_list)
 
 
 /* Select the AEAD flag from the pk_list.  We can only use AEAD if all
- * recipients support this feature.  Returns true if AEAD can be used.  */
-int
+ * recipients support this feature.  Returns the AEAD to be used or 0
+ * if AEAD shall not be used.  */
+aead_algo_t
 select_aead_from_pklist (PK_LIST pk_list)
 {
   pk_list_t pkr;
@@ -1672,7 +1673,7 @@ select_aead_from_pklist (PK_LIST pk_list)
         return 0;  /* At least one recipient does not support it. */
     }
 
-  return 1; /* Can be used. */
+  return default_aead_algo (); /* Yes, AEAD can be used. */
 }
 
 
diff --git a/g10/sign.c b/g10/sign.c
index 051ab59..7045e8c 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -1337,9 +1337,8 @@ sign_symencrypt_file (ctrl_t ctrl, const char *fname, strlist_t locusr)
         goto leave;
     }
 
-    if (use_aead (NULL, cfx.dek->algo))
-      cfx.dek->use_aead = 1;
-    else
+    cfx.dek->use_aead = use_aead (NULL, cfx.dek->algo);
+    if (!cfx.dek->use_aead)
       cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo);
 
     /* now create the outfile */

-----------------------------------------------------------------------

Summary of changes:
 g10/build-packet.c |  36 +++++------
 g10/cipher-aead.c  |  24 +-------
 g10/decrypt-data.c |  35 +++--------
 g10/encrypt.c      | 175 +++++++++++++++++++++++++++++++++++------------------
 g10/getkey.c       |  14 ++++-
 g10/gpgcompose.c   |   2 +-
 g10/import.c       |  19 ++++++
 g10/keydb.h        |   2 +-
 g10/keyedit.c      |  18 ++++++
 g10/main.h         |   7 ++-
 g10/mainproc.c     | 126 ++++++++++++++++++++++++++++++--------
 g10/misc.c         |  33 ++++++++++
 g10/packet.h       |  13 ++--
 g10/parse-packet.c |  32 ++++++++--
 g10/pkclist.c      |   7 ++-
 g10/sign.c         |  14 +++--
 16 files changed, 383 insertions(+), 174 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Guard
http://git.gnupg.org




More information about the Gnupg-commits mailing list