[git] GnuPG - branch, master, updated. gnupg-2.2.3-119-g0131d43

by Werner Koch cvs at cvs.gnupg.org
Mon Jan 22 15:58:38 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  0131d4369a81a51bf7bb328cc81a3bb082ed1a94 (commit)
      from  7356d6ec50ea24bc9449187e1c2b3ecd717b789f (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 0131d4369a81a51bf7bb328cc81a3bb082ed1a94
Author: Werner Koch <wk at gnupg.org>
Date:   Mon Jan 22 15:50:24 2018 +0100

    gpg: Refactor function encrypt_seskey.
    
    * g10/encrypt.c (encrypt_seskey): Allocate the buffer for the
    encrypted key and returns that buffer and its length.
    (encrypt_simple): Adjust for above change.
    (write_symkey_enc): Ditto.
    
    Signed-off-by: Werner Koch <wk at gnupg.org>

diff --git a/g10/encrypt.c b/g10/encrypt.c
index 8568497..ab745ce 100644
--- a/g10/encrypt.c
+++ b/g10/encrypt.c
@@ -67,45 +67,75 @@ encrypt_store (const char *filename)
 }
 
 
-/* *SESKEY contains the unencrypted session key ((*SESKEY)->KEY) and
-   the algorithm that will be used to encrypt the contents of the SED
-   packet ((*SESKEY)->ALGO).  If *SESKEY is NULL, then a random
-   session key that is appropriate for DEK->ALGO is generated and
-   stored there.
-
-   Encrypt that session key using DEK and store the result in ENCKEY,
-   which must be large enough to hold (*SESKEY)->KEYLEN + 1 bytes.  */
-void
-encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey)
+/* 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
+ * 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.
+ */
+gpg_error_t
+encrypt_seskey (DEK *dek, DEK **r_seskey, void **r_enckey, size_t *r_enckeylen)
 {
-  gcry_cipher_hd_t hd;
-  byte buf[33];
+  gpg_error_t err;
+  gcry_cipher_hd_t hd = NULL;
+  byte *buf = NULL;
+  DEK *seskey;
+
+  *r_enckey = NULL;
+  *r_enckeylen = 0;
 
-  log_assert ( dek->keylen <= 32 );
-  if (!*seskey)
+  if (*r_seskey)
+    seskey = *r_seskey;
+  else
     {
-      *seskey=xmalloc_clear(sizeof(DEK));
-      (*seskey)->algo=dek->algo;
-      make_session_key(*seskey);
+      seskey = xtrycalloc (1, sizeof(DEK));
+      if (!seskey)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+      seskey->algo = dek->algo;
+      make_session_key (seskey);
       /*log_hexdump( "thekey", c->key, c->keylen );*/
     }
 
+  buf = xtrymalloc_secure (1 + seskey->keylen);
+  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 );
-
-  /* We only pass already checked values to the following function,
-     thus we consider any failure as fatal.  */
-  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_encrypt (hd, buf, (*seskey)->keylen + 1, NULL, 0);
-  gcry_cipher_close (hd);
+  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_enckey = buf;
+  buf = NULL;
+  *r_enckeylen = seskey->keylen + 1;
+  /* Return the session key in case we allocated it.  */
+  *r_seskey = seskey;
+  seskey = NULL;
 
-  memcpy( enckey, buf, (*seskey)->keylen + 1 );
-  wipememory( buf, sizeof buf ); /* burn key */
+ leave:
+  gcry_cipher_close (hd);
+  if (seskey != *r_seskey)
+    xfree (seskey);
+  xfree (buf);
+  return err;
 }
 
 
@@ -218,9 +248,9 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
   PACKET pkt;
   PKT_plaintext *pt = NULL;
   STRING2KEY *s2k = NULL;
-  byte enckey[33];
+  void *enckey = NULL;
+  size_t enckeylen = 0;
   int rc = 0;
-  int seskeylen = 0;
   u32 filesize;
   cipher_filter_context_t cfx;
   armor_filter_context_t  *afx = NULL;
@@ -273,6 +303,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
   if ( mode )
     {
       int canceled;
+      aead_algo_t aead_algo;
 
       s2k = xmalloc_clear( sizeof *s2k );
       s2k->mode = opt.s2k_mode;
@@ -296,21 +327,33 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
                       "due to the S2K mode\n"));
         }
 
+      /* See whether we want to use AEAD.  */
+      aead_algo = use_aead (NULL, cfx.dek->algo)? default_aead_algo () : 0;
+
       if ( use_seskey )
         {
           DEK *dek = NULL;
 
-          seskeylen = openpgp_cipher_get_algo_keylen (default_cipher_algo ());
-          encrypt_seskey( cfx.dek, &dek, enckey );
-          xfree( cfx.dek ); cfx.dek = dek;
+          rc = encrypt_seskey (cfx.dek, &dek, &enckey, &enckeylen);
+          if (rc)
+            {
+              xfree (cfx.dek);
+              xfree (s2k);
+              iobuf_close (inp);
+              release_progress_context (pfx);
+              return rc;
+            }
+          /* Replace key in DEK.  */
+          xfree (cfx.dek);
+          cfx.dek = dek;
         }
 
       if (opt.verbose)
         log_info(_("using cipher %s\n"),
                  openpgp_cipher_algo_name (cfx.dek->algo));
 
-      if (use_aead (NULL, cfx.dek->algo))
-        cfx.dek->use_aead = default_aead_algo ();
+      if (aead_algo)
+        cfx.dek->use_aead = aead_algo;
       else
         cfx.dek->use_mdc = !!use_mdc (NULL, cfx.dek->algo);
     }
@@ -342,20 +385,23 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
 
   if ( s2k )
     {
-      PKT_symkey_enc *enc = xmalloc_clear( sizeof *enc + seskeylen + 1 );
+      /* Fixme: This is quite similar to write_symkey_enc.  */
+      PKT_symkey_enc *enc = xmalloc_clear (sizeof *enc + enckeylen);
       enc->version = 4;
       enc->cipher_algo = cfx.dek->algo;
       enc->s2k = *s2k;
-      if ( use_seskey && seskeylen )
+      if (enckeylen)
         {
-          enc->seskeylen = seskeylen + 1; /* algo id */
-          memcpy (enc->seskey, enckey, seskeylen + 1 );
+          enc->seskeylen = enckeylen;
+          memcpy (enc->seskey, enckey, enckeylen);
         }
       pkt.pkttype = PKT_SYMKEY_ENC;
       pkt.pkt.symkey_enc = enc;
       if ((rc = build_packet( out, &pkt )))
         log_error("build symkey packet failed: %s\n", gpg_strerror (rc) );
       xfree (enc);
+      xfree (enckey);
+      enckey = NULL;
     }
 
   if (!opt.no_literal)
@@ -459,6 +505,7 @@ encrypt_simple (const char *filename, int mode, int use_seskey)
   if (pt)
     pt->buf = NULL;
   free_packet (&pkt, NULL);
+  xfree (enckey);
   xfree (cfx.dek);
   xfree (s2k);
   release_armor_context (afx);
@@ -493,20 +540,29 @@ static int
 write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
                   iobuf_t out)
 {
-  int rc, seskeylen = openpgp_cipher_get_algo_keylen (dek->algo);
-
+  int rc;
+  void *enckey;
+  size_t enckeylen;
   PKT_symkey_enc *enc;
-  byte enckey[33];
   PACKET pkt;
 
-  enc=xmalloc_clear(sizeof(PKT_symkey_enc)+seskeylen+1);
-  encrypt_seskey(symkey_dek,&dek,enckey);
+  rc = encrypt_seskey (symkey_dek, &dek, &enckey, &enckeylen);
+  if (rc)
+    return rc;
+  enc = xtrycalloc (1, sizeof (PKT_symkey_enc) + enckeylen);
+  if (!enc)
+    {
+      rc = gpg_error_from_syserror ();
+      xfree (enckey);
+      return rc;
+    }
 
   enc->version = 4;
   enc->cipher_algo = opt.s2k_cipher_algo;
   enc->s2k = *symkey_s2k;
-  enc->seskeylen = seskeylen + 1; /* algo id */
-  memcpy( enc->seskey, enckey, seskeylen + 1 );
+  enc->seskeylen = enckeylen;
+  memcpy (enc->seskey, enckey, enckeylen);
+  xfree (enckey);
 
   pkt.pkttype = PKT_SYMKEY_ENC;
   pkt.pkt.symkey_enc = enc;
@@ -514,7 +570,7 @@ write_symkey_enc (STRING2KEY *symkey_s2k, DEK *symkey_dek, DEK *dek,
   if ((rc=build_packet(out,&pkt)))
     log_error("build symkey_enc packet failed: %s\n",gpg_strerror (rc));
 
-  xfree(enc);
+  xfree (enc);
   return rc;
 }
 
diff --git a/g10/gpgcompose.c b/g10/gpgcompose.c
index f879838..f22c7c2 100644
--- a/g10/gpgcompose.c
+++ b/g10/gpgcompose.c
@@ -2283,9 +2283,11 @@ sk_esk (const char *option, int argc, char *argv[], void *cookie)
       DEK *sesdekp = &sesdek;
 
       /* Now encrypt the session key (or rather, the algorithm used to
-         encrypt the SED plus the session key) using ENCKEY.  */
-      ske->seskeylen = 1 + sesdek.keylen;
-      encrypt_seskey (&s2kdek, &sesdekp, ske->seskey);
+         encrypt the SKESK plus the session key) using ENCKEY.  */
+      err = encrypt_seskey (&s2kdek, &sesdekp,
+                            (void**)&ske->seskey, (size_t *)&ske->seskeylen);
+      if (err)
+        log_fatal ("encrypt_seskey failed: %s\n", gpg_strerror (err));
 
       /* Save the session key for later.  */
       session_key = sesdek;
diff --git a/g10/main.h b/g10/main.h
index 393a1b0..509126c 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -232,7 +232,8 @@ void display_online_help( const char *keyword );
 
 /*-- encode.c --*/
 int setup_symkey (STRING2KEY **symkey_s2k,DEK **symkey_dek);
-void encrypt_seskey (DEK *dek, DEK **seskey, byte *enckey);
+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);
 int use_mdc (pk_list_t pk_list,int algo);
 int encrypt_symmetric (const char *filename );

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

Summary of changes:
 g10/encrypt.c    | 156 +++++++++++++++++++++++++++++++++++++------------------
 g10/gpgcompose.c |   8 +--
 g10/main.h       |   3 +-
 3 files changed, 113 insertions(+), 54 deletions(-)


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




More information about the Gnupg-commits mailing list