gpg: Rename cipher.c to cipher-cfb.c
[gnupg.git] / g10 / cipher-aead.c
index 1d72634..cc306f9 100644 (file)
 #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).  */
@@ -90,7 +86,8 @@ set_additional_data (cipher_filter_context_t *cfx, int final)
       ad[19] = cfx->total >>  8;
       ad[20] = cfx->total;
     }
-  log_printhex (ad, final? 21 : 13, "authdata:");
+  if (DBG_CRYPTO)
+    log_printhex (ad, final? 21 : 13, "authdata:");
   return gcry_cipher_authenticate (cfx->cipher_hd, ad, final? 21 : 13);
 }
 
@@ -128,7 +125,8 @@ set_nonce (cipher_filter_context_t *cfx)
   nonce[i++] ^= cfx->chunkindex >>  8;
   nonce[i++] ^= cfx->chunkindex;
 
-  log_printhex (nonce, 15, "nonce:");
+  if (DBG_CRYPTO)
+    log_printhex (nonce, 15, "nonce:");
   return gcry_cipher_setiv (cfx->cipher_hd, nonce, i);
 }
 
@@ -149,25 +147,12 @@ 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;
+  log_assert (opt.chunk_size >= 6 && opt.chunk_size <= 62);
+  cfx->chunkbyte = opt.chunk_size - 6;
   cfx->chunksize = (uint64_t)1 << (cfx->chunkbyte + 6);
   cfx->chunklen = 0;
   cfx->bufsize = AEAD_ENC_BUFFER_SIZE;
@@ -188,8 +173,9 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a)
   pkt.pkttype = PKT_ENCRYPTED_AEAD;
   pkt.pkt.encrypted = &ed;
 
-  log_debug ("aead packet: len=%lu extralen=%d\n",
-             (unsigned long)ed.len, ed.extralen);
+  if (DBG_FILTER)
+    log_debug ("aead packet: len=%lu extralen=%d\n",
+               (unsigned long)ed.len, ed.extralen);
 
   write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d",
                        cfx->dek->algo, ed.aead_algo);
@@ -211,7 +197,8 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a)
   if (err)
     goto leave;
 
-  log_printhex (cfx->dek->key, cfx->dek->keylen, "thekey:");
+  if (DBG_CRYPTO)
+    log_printhex (cfx->dek->key, cfx->dek->keylen, "thekey:");
   err = gcry_cipher_setkey (cfx->cipher_hd, cfx->dek->key, cfx->dek->keylen);
   if (err)
     return err;
@@ -244,7 +231,6 @@ write_auth_tag (cipher_filter_context_t *cfx, iobuf_t a)
   err = my_iobuf_write (a, tag, 16);
   if (err)
     goto leave;
-  log_printhex (tag, 16, "wrote tag:");
 
  leave:
   return err;
@@ -258,7 +244,8 @@ write_final_chunk (cipher_filter_context_t *cfx, iobuf_t a)
   gpg_error_t err;
   char dummy[1];
 
-  cfx->chunkindex++;
+  if (cfx->chunklen)
+    cfx->chunkindex++;
 
   err = set_nonce (cfx);
   if (err)
@@ -285,12 +272,13 @@ write_final_chunk (cipher_filter_context_t *cfx, iobuf_t a)
 static gpg_error_t
 do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
 {
-  gpg_error_t err;
+  gpg_error_t err = 0;
   int newchunk = 0;
   size_t n;
 
   /* Put the data into a buffer, flush and encrypt as needed.  */
-  log_debug ("flushing %zu bytes (cur buflen=%zu)\n", size, cfx->buflen);
+  if (DBG_FILTER)
+    log_debug ("flushing %zu bytes (cur buflen=%zu)\n", size, cfx->buflen);
   do
     {
       if (cfx->buflen + size < cfx->bufsize)
@@ -298,14 +286,15 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
       else
         n = cfx->bufsize - cfx->buflen;
 
-      if (cfx->chunklen + n >= cfx->chunksize)
+      if (cfx->chunklen + cfx->buflen + n >= cfx->chunksize)
         {
-          size_t n1 = cfx->chunksize - cfx->chunklen;
+          size_t n1 = cfx->chunksize - (cfx->chunklen + cfx->buflen);
           newchunk = 1;
-          log_debug ("chunksize %ju reached;"
-                     " cur buflen=%zu using %zu of %zu\n",
-                     (uintmax_t)cfx->chunksize, (uintmax_t)cfx->buflen,
-                     n1, n);
+          if (DBG_FILTER)
+            log_debug ("chunksize %ju reached;"
+                       " cur buflen=%zu using %zu of %zu\n",
+                       (uintmax_t)cfx->chunksize, (uintmax_t)cfx->buflen,
+                       n1, n);
           n = n1;
         }
 
@@ -316,11 +305,14 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
 
       if (cfx->buflen == cfx->bufsize || newchunk)
         {
-          log_debug ("encrypting: buflen=%zu %s %p\n",
-                     cfx->buflen, newchunk?"(newchunk)":"", cfx->cipher_hd);
+          if (DBG_FILTER)
+            log_debug ("encrypting: buflen=%zu %s n=%zu\n",
+                       cfx->buflen, newchunk?"(newchunk)":"", n);
           if (newchunk)
             gcry_cipher_final (cfx->cipher_hd);
-          if (newchunk)
+          if (!DBG_FILTER)
+            ;
+          else if (newchunk)
             log_printhex (cfx->buffer, cfx->buflen, "plain(1):");
           else if (cfx->buflen > 32)
             log_printhex (cfx->buffer + cfx->buflen - 32, 32,
@@ -332,7 +324,7 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
            * mode.  */
           gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen,
                                NULL, 0);
-          if (newchunk)
+          if (newchunk && DBG_FILTER)
             log_printhex (cfx->buffer, cfx->buflen, "ciphr(1):");
           err = my_iobuf_write (a, cfx->buffer, cfx->buflen);
           if (err)
@@ -343,18 +335,19 @@ do_flush (cipher_filter_context_t *cfx, iobuf_t a, byte *buf, size_t size)
 
           if (newchunk)
             {
-              log_debug ("chunklen=%ju  total=%ju\n",
-                         (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
+              if (DBG_FILTER)
+                log_debug ("chunklen=%ju  total=%ju\n",
+                           (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
               err = write_auth_tag (cfx, a);
               if (err)
                 {
-                  log_debug ("gcry_cipher_gettag failed: %s\n",
+                  log_error ("gcry_cipher_gettag failed: %s\n",
                              gpg_strerror (err));
                   goto leave;
                 }
 
-              log_debug ("starting a new chunk (cur size=%zu)\n", size);
-              log_printhex (buf, size, "cur buf:");
+              if (DBG_FILTER)
+                log_debug ("starting a new chunk (cur size=%zu)\n", size);
               cfx->chunkindex++;
               cfx->chunklen = 0;
               err = set_nonce (cfx);
@@ -380,6 +373,9 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a)
 {
   gpg_error_t err = 0;
 
+  if (DBG_FILTER)
+    log_debug ("do_free: buflen=%zu\n", cfx->buflen);
+
   /* FIXME: Check what happens if we just wrote the last chunk and no
    * more bytes were to encrypt.  We should then not call finalize and
    * write the auth tag again, right?  May this at all happen?  */
@@ -391,10 +387,10 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a)
   /* Encrypt any remaining bytes.  */
   if (cfx->buflen)
     {
-      log_debug ("processing last %zu bytes of the last chunk\n", cfx->buflen);
-      log_printhex (cfx->buffer, cfx->buflen, "plain(2):");
+      if (DBG_FILTER)
+        log_debug ("processing last %zu bytes of the last chunk\n",
+                   cfx->buflen);
       gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, cfx->buflen, NULL, 0);
-      log_printhex (cfx->buffer, cfx->buflen, "ciphr(2):");
       err = my_iobuf_write (a, cfx->buffer, cfx->buflen);
       if (err)
         goto leave;
@@ -402,23 +398,27 @@ do_free (cipher_filter_context_t *cfx, iobuf_t a)
       cfx->chunklen += cfx->buflen;
       cfx->total += cfx->buflen;
     }
+  else /* Dummy encryption.  */
+    gcry_cipher_encrypt (cfx->cipher_hd, cfx->buffer, 0, NULL, 0);
 
   /* Get and write the authentication tag.  */
-  log_debug ("chunklen=%ju  total=%ju\n",
-             (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
+  if (DBG_FILTER)
+    log_debug ("chunklen=%ju  total=%ju\n",
+               (uintmax_t)cfx->chunklen, (uintmax_t)cfx->total);
   err = write_auth_tag (cfx, a);
   if (err)
     goto leave;
 
   /* Write the final chunk.  */
-  log_debug ("creating final chunk\n");
+  if (DBG_FILTER)
+    log_debug ("creating final chunk\n");
   err = write_final_chunk (cfx, a);
 
  leave:
   xfree (cfx->buffer);
   cfx->buffer = NULL;
-  /* gcry_cipher_close (cfx->cipher_hd); */
-  /* cfx->cipher_hd = NULL; */
+  gcry_cipher_close (cfx->cipher_hd);
+  cfx->cipher_hd = NULL;
   return err;
 }