[git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-172-g5e66a4f

by Jussi Kivilinna cvs at cvs.gnupg.org
Sat Feb 28 18:25:58 CET 2015


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 crypto library".

The branch, master has been updated
       via  5e66a4f8d5a63f58caeee367433dd8dd32346083 (commit)
      from  505decf5369970219ddc9e78a20f97c623957b78 (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 5e66a4f8d5a63f58caeee367433dd8dd32346083
Author: Jussi Kivilinna <jussi.kivilinna at iki.fi>
Date:   Sat Feb 28 18:04:34 2015 +0200

    Fix in-place encryption for OCB mode
    
    * cipher/cipher-ocb.c (ocb_checksum): New.
    (ocb_crypt): Move checksum calculation outside main crypt loop, do
    checksum calculation for encryption before inbuf is overwritten.
    * tests/basic.c (check_ocb_cipher): Rename to ...
    (do_check_ocb_cipher): ... to this and add argument for testing
    in-place encryption/decryption.
    (check_ocb_cipher): New.
    --
    
    Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>

diff --git a/cipher/cipher-ocb.c b/cipher/cipher-ocb.c
index 25466f0..652683c 100644
--- a/cipher/cipher-ocb.c
+++ b/cipher/cipher-ocb.c
@@ -299,6 +299,21 @@ _gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf,
 }
 
 
+/* Checksumming for encrypt and decrypt.  */
+static void ocb_checksum(unsigned char *chksum, const unsigned char *plainbuf,
+                         size_t nblks)
+{
+  while (nblks > 0)
+    {
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      buf_xor_1(chksum, plainbuf, OCB_BLOCK_LEN);
+
+      plainbuf += OCB_BLOCK_LEN;
+      nblks--;
+    }
+}
+
+
 /* Common code for encrypt and decrypt.  */
 static gcry_err_code_t
 ocb_crypt (gcry_cipher_hd_t c, int encrypt,
@@ -308,6 +323,7 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt,
   unsigned char l_tmp[OCB_BLOCK_LEN];
   unsigned int burn = 0;
   unsigned int nburn;
+  size_t nblks = inbuflen / OCB_BLOCK_LEN;
 
   /* Check that a nonce and thus a key has been set and that we are
      not yet in end of data state. */
@@ -324,6 +340,12 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt,
   else if ((inbuflen % OCB_BLOCK_LEN))
     return GPG_ERR_INV_LENGTH;  /* We support only full blocks for now.  */
 
+  if (encrypt)
+    {
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      ocb_checksum (c->u_ctr.ctr, inbuf, nblks);
+    }
+
   /* Encrypt all full blocks.  */
   while (inbuflen >= OCB_BLOCK_LEN)
     {
@@ -341,15 +363,18 @@ ocb_crypt (gcry_cipher_hd_t c, int encrypt,
       burn = nburn > burn ? nburn : burn;
       buf_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN);
 
-      /* Checksum_i = Checksum_{i-1} xor P_i  */
-      buf_xor_1 (c->u_ctr.ctr, encrypt? inbuf : outbuf, OCB_BLOCK_LEN);
-
       inbuf += OCB_BLOCK_LEN;
       inbuflen -= OCB_BLOCK_LEN;
       outbuf += OCB_BLOCK_LEN;
       outbuflen =- OCB_BLOCK_LEN;
     }
 
+  if (!encrypt)
+    {
+      /* Checksum_i = Checksum_{i-1} xor P_i  */
+      ocb_checksum (c->u_ctr.ctr, outbuf - nblks * OCB_BLOCK_LEN, nblks);
+     }
+
   /* Encrypt final partial block.  Note that we expect INBUFLEN to be
      shorter than OCB_BLOCK_LEN (see above).  */
   if (inbuflen)
diff --git a/tests/basic.c b/tests/basic.c
index 869b381..6ebc056 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -2781,7 +2781,7 @@ check_ccm_cipher (void)
 
 
 static void
-check_ocb_cipher (void)
+do_check_ocb_cipher (int inplace)
 {
   /* Note that we use hex strings and not binary strings in TV.  That
      makes it easier to maintain the test vectors.  */
@@ -3028,7 +3028,18 @@ check_ocb_cipher (void)
 
       err = gcry_cipher_final (hde);
       if (!err)
-        err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, plain, plainlen);
+        {
+          if (inplace)
+            {
+              memcpy(out, plain, plainlen);
+              err = gcry_cipher_encrypt (hde, out, plainlen, NULL, 0);
+            }
+          else
+            {
+              err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+                                         plain, plainlen);
+            }
+        }
       if (err)
         {
           fail ("cipher-ocb, gcry_cipher_encrypt failed (tv %d): %s\n",
@@ -3075,7 +3086,19 @@ check_ocb_cipher (void)
       /* Now for the decryption.  */
       err = gcry_cipher_final (hdd);
       if (!err)
-        err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0);
+        {
+          if (inplace)
+            {
+              err = gcry_cipher_decrypt (hdd, out, plainlen, NULL, 0);
+            }
+          else
+            {
+              unsigned char tmp[MAX_DATA_LEN];
+
+              memcpy(tmp, out, plainlen);
+              err = gcry_cipher_decrypt (hdd, out, plainlen, tmp, plainlen);
+            }
+        }
       if (err)
         {
           fail ("cipher-ocb, gcry_cipher_decrypt (tv %d) failed: %s\n",
@@ -3130,6 +3153,18 @@ check_ocb_cipher (void)
 
 
 static void
+check_ocb_cipher (void)
+{
+  /* Check OCB cipher with separate destination and source buffers for
+   * encryption/decryption. */
+  do_check_ocb_cipher(0);
+
+  /* Check OCB cipher with inplace encrypt/decrypt. */
+  do_check_ocb_cipher(1);
+}
+
+
+static void
 check_stream_cipher (void)
 {
   static const struct tv

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

Summary of changes:
 cipher/cipher-ocb.c | 31 ++++++++++++++++++++++++++++---
 tests/basic.c       | 41 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 66 insertions(+), 6 deletions(-)


hooks/post-receive
-- 
The GNU crypto library
http://git.gnupg.org


_______________________________________________
Gnupg-commits mailing list
Gnupg-commits at gnupg.org
http://lists.gnupg.org/mailman/listinfo/gnupg-commits




More information about the Gcrypt-devel mailing list