[git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-365-gf2260e3

by Jussi Kivilinna cvs at cvs.gnupg.org
Sun Mar 27 10:18:30 CEST 2016


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  f2260e3a2e962ac80124ef938e54041bbea08561 (commit)
      from  4a064e2a06fe737f344d1dfd8a45cc4c2abbe4c9 (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 f2260e3a2e962ac80124ef938e54041bbea08561
Author: Jussi Kivilinna <jussi.kivilinna at iki.fi>
Date:   Sun Mar 27 11:17:39 2016 +0300

    cipher: GCM: check that length of supplied tag is one of valid lengths
    
    * cipher/cipher-gcm.c (is_tag_length_valid): New.
    (_gcry_cipher_gcm_tag): Check that 'outbuflen' has valid tag length.
    * tests/basic.c (_check_gcm_cipher): Add test-vectors with different
    valid tag lengths and negative test vectors with invalid lengths.
    --
    
    NIST SP 800-38D allows following tag lengths:
     128, 120, 112, 104, 96, 64 and 32 bits.
    
    [v2: allow larger buffer when outputting tag. 128-bit tag is written
         to target buffer in this case]
    Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>

diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c
index 712641e..6e0959a 100644
--- a/cipher/cipher-gcm.c
+++ b/cipher/cipher-gcm.c
@@ -769,12 +769,32 @@ _gcry_cipher_gcm_geniv (gcry_cipher_hd_t c,
 #endif
 
 
+static int
+is_tag_length_valid(size_t taglen)
+{
+  switch (taglen)
+    {
+    /* Allowed tag lengths from NIST SP 800-38D.  */
+    case 128 / 8: /* GCRY_GCM_BLOCK_LEN */
+    case 120 / 8:
+    case 112 / 8:
+    case 104 / 8:
+    case 96 / 8:
+    case 64 / 8:
+    case 32 / 8:
+      return 1;
+
+    default:
+      return 0;
+    }
+}
+
 static gcry_err_code_t
 _gcry_cipher_gcm_tag (gcry_cipher_hd_t c,
                       byte * outbuf, size_t outbuflen, int check)
 {
-  if (outbuflen < GCRY_GCM_BLOCK_LEN)
-    return GPG_ERR_BUFFER_TOO_SHORT;
+  if (!(is_tag_length_valid (outbuflen) || outbuflen >= GCRY_GCM_BLOCK_LEN))
+    return GPG_ERR_INV_LENGTH;
   if (c->u_mode.gcm.datalen_over_limits)
     return GPG_ERR_INV_LENGTH;
 
@@ -815,17 +835,19 @@ _gcry_cipher_gcm_tag (gcry_cipher_hd_t c,
 
   if (!check)
     {
+      if (outbuflen > GCRY_GCM_BLOCK_LEN)
+        outbuflen = GCRY_GCM_BLOCK_LEN;
+
       /* NB: We already checked that OUTBUF is large enough to hold
-         the result.  */
-      memcpy (outbuf, c->u_mode.gcm.u_tag.tag, GCRY_GCM_BLOCK_LEN);
+       * the result or has valid truncated length.  */
+      memcpy (outbuf, c->u_mode.gcm.u_tag.tag, outbuflen);
     }
   else
     {
       /* OUTBUFLEN gives the length of the user supplied tag in OUTBUF
        * and thus we need to compare its length first.  */
-      if (outbuflen != GCRY_GCM_BLOCK_LEN
-          || !buf_eq_const (outbuf, c->u_mode.gcm.u_tag.tag,
-                            GCRY_GCM_BLOCK_LEN))
+      if (!is_tag_length_valid (outbuflen)
+          || !buf_eq_const (outbuf, c->u_mode.gcm.u_tag.tag, outbuflen))
         return GPG_ERR_CHECKSUM;
     }
 
diff --git a/tests/basic.c b/tests/basic.c
index 36a83d0..25d31ee 100644
--- a/tests/basic.c
+++ b/tests/basic.c
@@ -1304,6 +1304,8 @@ _check_gcm_cipher (unsigned int step)
     int inlen;
     char out[MAX_DATA_LEN];
     char tag[MAX_DATA_LEN];
+    int taglen;
+    int should_fail;
   } tv[] =
     {
       /* http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf */
@@ -1319,6 +1321,78 @@ _check_gcm_cipher (unsigned int step)
         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
         "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7\x45",
+        15 },
+      { GCRY_CIPHER_AES,
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4\xe7",
+        14 },
+      { GCRY_CIPHER_AES,
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57\xa4",
+        13 },
+      { GCRY_CIPHER_AES,
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d\x57",
+        12 },
+      { GCRY_CIPHER_AES,
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61\x36\x7f\x1d",
+        11, 1 },
+      { GCRY_CIPHER_AES,
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce\xfa\x7e\x30\x61",
+        8 },
+      { GCRY_CIPHER_AES,
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58\xe2\xfc\xce",
+        4 },
+      { GCRY_CIPHER_AES,
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+        "", 0,
+        "",
+        0,
+        "",
+        "\x58",
+        1, 1 },
+      { GCRY_CIPHER_AES,
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+        "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12,
+        "", 0,
         "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
         16,
         "\x03\x88\xda\xce\x60\xb6\xa3\x92\xf3\x28\xc2\xb9\x71\xb2\xfe\x78",
@@ -1570,9 +1644,14 @@ _check_gcm_cipher (unsigned int step)
       if (memcmp (tv[i].plaintext, out, tv[i].inlen))
         fail ("aes-gcm, decrypt mismatch entry %d (step %d)\n", i, step);
 
-      err = gcry_cipher_gettag (hde, out, GCRY_GCM_BLOCK_LEN);
+      taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN;
+
+      err = gcry_cipher_gettag (hde, out, taglen2);
       if (err)
         {
+          if (tv[i].should_fail)
+            goto next_tv;
+
           fail ("aes-gcm, gcry_cipher_gettag(%d) failed: %s\n",
                 i, gpg_strerror (err));
           gcry_cipher_close (hde);
@@ -1580,11 +1659,10 @@ _check_gcm_cipher (unsigned int step)
           return;
         }
 
-      if (memcmp (tv[i].tag, out, GCRY_GCM_BLOCK_LEN))
+      if (memcmp (tv[i].tag, out, taglen2))
         fail ("aes-gcm, encrypt tag mismatch entry %d\n", i);
 
-
-      err = gcry_cipher_checktag (hdd, out, GCRY_GCM_BLOCK_LEN);
+      err = gcry_cipher_checktag (hdd, out, taglen2);
       if (err)
         {
           fail ("aes-gcm, gcry_cipher_checktag(%d) failed: %s\n",
@@ -1660,17 +1738,25 @@ _check_gcm_cipher (unsigned int step)
       if (memcmp (tv[i].out, out, tv[i].inlen))
         fail ("aes-gcm, encrypt mismatch entry %d, (byte-buf)\n", i);
 
-      err = gcry_cipher_gettag (hde, tag, GCRY_GCM_BLOCK_LEN);
+      /* Test output to larger than 16-byte buffer. */
+      taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN + 1;
+
+      err = gcry_cipher_gettag (hde, tag, taglen2);
       if (err)
         {
-          fail ("aes-gcm, gcry_cipher_gettag(%d) (byte-buf) failed: %s\n",
-                i, gpg_strerror (err));
+          if (tv[i].should_fail)
+            goto next_tv;
+
+          fail ("aes-gcm, gcry_cipher_gettag(%d, %d) (byte-buf) failed: %s\n",
+                i, taglen2, gpg_strerror (err));
           gcry_cipher_close (hde);
           gcry_cipher_close (hdd);
           return;
         }
 
-      if (memcmp (tv[i].tag, tag, GCRY_GCM_BLOCK_LEN))
+      taglen2 = tv[i].taglen ? tv[i].taglen : GCRY_GCM_BLOCK_LEN;
+
+      if (memcmp (tv[i].tag, tag, taglen2))
         fail ("aes-gcm, encrypt tag mismatch entry %d, (byte-buf)\n", i);
 
       for (byteNum = 0; byteNum < tv[i].inlen; ++byteNum)
@@ -1689,7 +1775,7 @@ _check_gcm_cipher (unsigned int step)
       if (memcmp (tv[i].plaintext, out, tv[i].inlen))
         fail ("aes-gcm, decrypt mismatch entry %d\n", i);
 
-      err = gcry_cipher_checktag (hdd, tag, GCRY_GCM_BLOCK_LEN);
+      err = gcry_cipher_checktag (hdd, tag, taglen2);
       if (err)
         {
           fail ("aes-gcm, gcry_cipher_checktag(%d) (byte-buf) failed: %s\n",
@@ -1699,6 +1785,34 @@ _check_gcm_cipher (unsigned int step)
           return;
         }
 
+      err = gcry_cipher_checktag (hdd, tag, 1);
+      if (!err)
+        {
+          fail ("aes-gcm, gcry_cipher_checktag(%d) did not fail for invalid "
+	        " tag length of '%d'\n", i, 1);
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+      err = gcry_cipher_checktag (hdd, tag, 17);
+      if (!err)
+        {
+          fail ("aes-gcm, gcry_cipher_checktag(%d) did not fail for invalid "
+	        " tag length of '%d'\n", i, 17);
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+      if (tv[i].should_fail)
+        {
+          fail ("aes-gcm, negative test succeeded %d\n", i);
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
+        }
+
+next_tv:
       gcry_cipher_close (hde);
       gcry_cipher_close (hdd);
     }

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

Summary of changes:
 cipher/cipher-gcm.c |  36 +++++++++++---
 tests/basic.c       | 132 ++++++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 152 insertions(+), 16 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