Use u64 for CCM data lengths
authorJussi Kivilinna <jussi.kivilinna@iki.fi>
Sun, 15 Dec 2013 18:07:54 +0000 (20:07 +0200)
committerJussi Kivilinna <jussi.kivilinna@iki.fi>
Sun, 15 Dec 2013 18:07:54 +0000 (20:07 +0200)
* cipher/cipher-ccm.c: Move code inside [HAVE_U64_TYPEDEF].
[HAVE_U64_TYPEDEF] (_gcry_cipher_ccm_set_lengths): Use 'u64' for
data lengths.
[!HAVE_U64_TYPEDEF] (_gcry_cipher_ccm_encrypt)
(_gcry_cipher_ccm_decrypt, _gcry_cipher_ccm_set_nonce)
(_gcry_cipher_ccm_authenticate, _gcry_cipher_ccm_get_tag)
(_gcry_cipher_ccm_check_tag): Dummy functions returning
GPG_ERROR_NOT_SUPPORTED.
* cipher/cipher-internal.h (gcry_cipher_handle.u_mode.ccm)
(_gcry_cipher_ccm_set_lengths): Move inside [HAVE_U64_TYPEDEF] and use
u64 instead of size_t for CCM data lengths.
* cipher/cipher.c (_gcry_cipher_open_internal, cipher_reset)
(_gcry_cipher_ctl) [!HAVE_U64_TYPEDEF]: Return GPG_ERR_NOT_SUPPORTED
for CCM.
(_gcry_cipher_ctl) [HAVE_U64_TYPEDEF]: Use u64 for
GCRYCTL_SET_CCM_LENGTHS length parameters.
* tests/basic.c: Do not use CCM if !HAVE_U64_TYPEDEF.
* tests/bench-slope.c: Ditto.
* tests/benchmark.c: Ditto.
--

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
cipher/cipher-ccm.c
cipher/cipher-internal.h
cipher/cipher.c
tests/basic.c
tests/bench-slope.c
tests/benchmark.c

index d2b8841..47f2162 100644 (file)
@@ -29,6 +29,9 @@
 #include "bufhelp.h"
 #include "./cipher-internal.h"
 
+/* We need a 64 bit type for this code.  */
+#ifdef HAVE_U64_TYPEDEF
+
 
 #define set_burn(burn, nburn) do { \
   unsigned int __nburn = (nburn); \
@@ -149,14 +152,14 @@ _gcry_cipher_ccm_set_nonce (gcry_cipher_hd_t c, const unsigned char *nonce,
 
 
 gcry_err_code_t
-_gcry_cipher_ccm_set_lengths (gcry_cipher_hd_t c, size_t encryptlen,
-                              size_t aadlen, size_t taglen)
+_gcry_cipher_ccm_set_lengths (gcry_cipher_hd_t c, u64 encryptlen, u64 aadlen,
+                              u64 taglen)
 {
   unsigned int burn = 0;
   unsigned char b0[16];
   size_t noncelen = 15 - (c->u_iv.iv[0] + 1);
-  size_t M = taglen;
-  size_t M_;
+  u64 M = taglen;
+  u64 M_;
   int i;
 
   M_ = (M - 2) / 2;
@@ -203,7 +206,6 @@ _gcry_cipher_ccm_set_lengths (gcry_cipher_hd_t c, size_t encryptlen,
       buf_put_be32(&b0[2], aadlen);
       set_burn (burn, do_cbc_mac (c, b0, 6, 0));
     }
-#ifdef HAVE_U64_TYPEDEF
   else if (aadlen > (unsigned int)0xffffffff)
     {
       b0[0] = 0xff;
@@ -211,7 +213,6 @@ _gcry_cipher_ccm_set_lengths (gcry_cipher_hd_t c, size_t encryptlen,
       buf_put_be64(&b0[2], aadlen);
       set_burn (burn, do_cbc_mac (c, b0, 10, 0));
     }
-#endif
 
   /* Generate S_0 and increase counter.  */
   set_burn (burn, c->spec->encrypt ( &c->context.c, c->u_mode.ccm.s0,
@@ -364,3 +365,78 @@ _gcry_cipher_ccm_decrypt (gcry_cipher_hd_t c, unsigned char *outbuf,
 
   return err;
 }
+
+#else
+
+/*
+ * Provide dummy functions so that we avoid adding too much #ifdefs in
+ * cipher.c.
+ */
+
+gcry_err_code_t
+_gcry_cipher_ccm_encrypt(gcry_cipher_hd_t c, unsigned char *outbuf,
+                        size_t outbuflen, const unsigned char *inbuf,
+                        size_t inbuflen)
+{
+  (void)c;
+  (void)outbuf;
+  (void)outbuflen;
+  (void)inbuf;
+  (void)inbuflen;
+  return GPG_ERR_NOT_SUPPORTED;
+}
+
+gcry_err_code_t
+_gcry_cipher_ccm_decrypt(gcry_cipher_hd_t c, unsigned char *outbuf,
+                        size_t outbuflen, const unsigned char *inbuf,
+                        size_t inbuflen)
+{
+  (void)c;
+  (void)outbuf;
+  (void)outbuflen;
+  (void)inbuf;
+  (void)inbuflen;
+  return GPG_ERR_NOT_SUPPORTED;
+}
+
+gcry_err_code_t
+_gcry_cipher_ccm_set_nonce(gcry_cipher_hd_t c, const unsigned char *nonce,
+                          size_t noncelen)
+{
+  (void)c;
+  (void)nonce;
+  (void)noncelen;
+  return GPG_ERR_NOT_SUPPORTED;
+}
+
+gcry_err_code_t
+_gcry_cipher_ccm_authenticate(gcry_cipher_hd_t c, const unsigned char *abuf,
+                             size_t abuflen)
+{
+  (void)c;
+  (void)abuf;
+  (void)abuflen;
+  return GPG_ERR_NOT_SUPPORTED;
+}
+
+gcry_err_code_t
+_gcry_cipher_ccm_get_tag(gcry_cipher_hd_t c, unsigned char *outtag,
+                        size_t taglen)
+{
+  (void)c;
+  (void)outtag;
+  (void)taglen;
+  return GPG_ERR_NOT_SUPPORTED;
+}
+
+gcry_err_code_t
+_gcry_cipher_ccm_check_tag(gcry_cipher_hd_t c, const unsigned char *intag,
+                          size_t taglen)
+{
+  (void)c;
+  (void)intag;
+  (void)taglen;
+  return GPG_ERR_NOT_SUPPORTED;
+}
+
+#endif /*HAVE_U64_TYPEDEF*/
index 6fb3bac..cdac445 100644 (file)
@@ -135,10 +135,11 @@ struct gcry_cipher_handle
   int unused;  /* Number of unused bytes in LASTIV. */
 
   union {
+#ifdef HAVE_U64_TYPEDEF
     /* Mode specific storage for CCM mode. */
     struct {
-      size_t encryptlen;
-      size_t aadlen;
+      u64 encryptlen;
+      u64 aadlen;
       unsigned int authlen;
 
       /* Space to save partial input lengths for MAC. */
@@ -151,6 +152,7 @@ struct gcry_cipher_handle
       unsigned int lengths:1; /* Set to 1 if CCM length parameters has been
                                  processed.  */
     } ccm;
+#endif
 
     /* Mode specific storage for CMAC mode. */
     struct {
@@ -280,9 +282,10 @@ gcry_err_code_t _gcry_cipher_ccm_set_nonce
                  size_t noncelen);
 gcry_err_code_t _gcry_cipher_ccm_authenticate
 /*           */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen);
+#ifdef HAVE_U64_TYPEDEF
 gcry_err_code_t _gcry_cipher_ccm_set_lengths
-/*           */ (gcry_cipher_hd_t c, size_t encryptedlen, size_t aadlen,
-                 size_t taglen);
+/*           */ (gcry_cipher_hd_t c, u64 encryptedlen, u64 aadlen, u64 taglen);
+#endif
 gcry_err_code_t _gcry_cipher_ccm_get_tag
 /*           */ (gcry_cipher_hd_t c,
                  unsigned char *outtag, size_t taglen);
index 8b47abc..8c5a0b4 100644 (file)
@@ -394,11 +394,15 @@ _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
     switch (mode)
       {
       case GCRY_CIPHER_MODE_CCM:
+#ifdef HAVE_U64_TYPEDEF
        if (spec->blocksize != GCRY_CCM_BLOCK_LEN)
          err = GPG_ERR_INV_CIPHER_MODE;
        if (!spec->encrypt || !spec->decrypt)
          err = GPG_ERR_INV_CIPHER_MODE;
        break;
+#else
+        err = GPG_ERR_NOT_SUPPORTED;
+#endif
 
       case GCRY_CIPHER_MODE_ECB:
       case GCRY_CIPHER_MODE_CBC:
@@ -686,9 +690,11 @@ cipher_reset (gcry_cipher_hd_t c)
       }
       break;
 
+#ifdef HAVE_U64_TYPEDEF
     case GCRY_CIPHER_MODE_CCM:
       memset (&c->u_mode.ccm, 0, sizeof c->u_mode.ccm);
       break;
+#endif
 
     default:
       break; /* u_mode unused by other modes. */
@@ -1139,8 +1145,9 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
       break;
 
     case GCRYCTL_SET_CCM_LENGTHS:
+#ifdef HAVE_U64_TYPEDEF
       {
-        size_t params[3];
+        u64 params[3];
         size_t encryptedlen;
         size_t aadlen;
         size_t authtaglen;
@@ -1148,7 +1155,7 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
         if (h->mode != GCRY_CIPHER_MODE_CCM)
           return gcry_error (GPG_ERR_INV_CIPHER_MODE);
 
-        if (!buffer || buflen != 3 * sizeof(size_t))
+        if (!buffer || buflen != 3 * sizeof(u64))
           return gcry_error (GPG_ERR_INV_ARG);
 
         /* This command is used to pass additional length parameters needed
@@ -1160,6 +1167,9 @@ _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
 
         rc = _gcry_cipher_ccm_set_lengths (h, encryptedlen, aadlen, authtaglen);
       }
+#else
+      rc = GPG_ERR_NOT_SUPPORTED;
+#endif
       break;
 
     case GCRYCTL_DISABLE_ALGO:
index 6ffc3f5..0eb8215 100644 (file)
@@ -1545,6 +1545,7 @@ check_gcm_cipher (void)
 static void
 check_ccm_cipher (void)
 {
+#ifdef HAVE_U64_TYPEDEF
   static const struct tv
   {
     int algo;
@@ -1950,7 +1951,7 @@ check_ccm_cipher (void)
   static const int cut[] = { 0, 1, 8, 10, 16, 19, -1 };
   gcry_cipher_hd_t hde, hdd;
   unsigned char out[MAX_DATA_LEN];
-  size_t ctl_params[3];
+  u64 ctl_params[3];
   int split, aadsplit;
   size_t j, i, keylen, blklen, authlen;
   gcry_error_t err = 0;
@@ -2305,10 +2306,11 @@ check_ccm_cipher (void)
     if (memcmp (buf, tag, taglen) != 0)
       fail ("cipher-ccm-huge, encrypt mismatch entry\n");
   }
-#endif
 
   if (verbose)
     fprintf (stderr, "  Completed CCM checks.\n");
+#endif
+#endif /*HAVE_U64_TYPEDEF*/
 }
 
 
index 219e0dd..bd05064 100644 (file)
@@ -740,7 +740,7 @@ static struct bench_ops decrypt_ops = {
 };
 
 
-
+#ifdef HAVE_U64_TYPEDEF
 static void
 bench_ccm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
 {
@@ -748,7 +748,7 @@ bench_ccm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
   int err;
   char tag[8];
   char nonce[11] = { 0x80, 0x01, };
-  size_t params[3];
+  u64 params[3];
 
   gcry_cipher_setiv (hd, nonce, sizeof (nonce));
 
@@ -792,7 +792,7 @@ bench_ccm_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
   int err;
   char tag[8] = { 0, };
   char nonce[11] = { 0x80, 0x01, };
-  size_t params[3];
+  u64 params[3];
 
   gcry_cipher_setiv (hd, nonce, sizeof (nonce));
 
@@ -839,7 +839,7 @@ bench_ccm_authenticate_do_bench (struct bench_obj *obj, void *buf,
   int err;
   char tag[8] = { 0, };
   char nonce[11] = { 0x80, 0x01, };
-  size_t params[3];
+  u64 params[3];
   char data = 0xff;
 
   gcry_cipher_setiv (hd, nonce, sizeof (nonce));
@@ -903,6 +903,8 @@ static struct bench_ops ccm_authenticate_ops = {
   &bench_encrypt_free,
   &bench_ccm_authenticate_do_bench
 };
+#endif /*HAVE_U64_TYPEDEF*/
+
 
 static void
 bench_gcm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
@@ -1037,9 +1039,11 @@ static struct bench_cipher_mode cipher_modes[] = {
   {GCRY_CIPHER_MODE_OFB, "OFB dec", &decrypt_ops},
   {GCRY_CIPHER_MODE_CTR, "CTR enc", &encrypt_ops},
   {GCRY_CIPHER_MODE_CTR, "CTR dec", &decrypt_ops},
+#ifdef HAVE_U64_TYPEDEF
   {GCRY_CIPHER_MODE_CCM, "CCM enc", &ccm_encrypt_ops},
   {GCRY_CIPHER_MODE_CCM, "CCM dec", &ccm_decrypt_ops},
   {GCRY_CIPHER_MODE_CCM, "CCM auth", &ccm_authenticate_ops},
+#endif
   {GCRY_CIPHER_MODE_GCM, "GCM enc", &gcm_encrypt_ops},
   {GCRY_CIPHER_MODE_GCM, "GCM dec", &gcm_decrypt_ops},
   {GCRY_CIPHER_MODE_GCM, "GCM auth", &gcm_authenticate_ops},
index 62dfc22..e009c22 100644 (file)
@@ -562,13 +562,13 @@ mac_bench ( const char *algoname )
 }
 
 
-
+#ifdef HAVE_U64_TYPEDEF
 static void ccm_aead_init(gcry_cipher_hd_t hd, size_t buflen, int authlen)
 {
   const int _L = 4;
   const int noncelen = 15 - _L;
   char nonce[noncelen];
-  size_t params[3];
+  u64 params[3];
   gcry_error_t err = GPG_ERR_NO_ERROR;
 
   memset (nonce, 0x33, noncelen);
@@ -594,6 +594,7 @@ static void ccm_aead_init(gcry_cipher_hd_t hd, size_t buflen, int authlen)
       exit (1);
     }
 }
+#endif
 
 
 static void
@@ -622,8 +623,10 @@ cipher_bench ( const char *algoname )
     { GCRY_CIPHER_MODE_CFB, "      CFB", 0 },
     { GCRY_CIPHER_MODE_OFB, "      OFB", 0 },
     { GCRY_CIPHER_MODE_CTR, "      CTR", 0 },
+#ifdef HAVE_U64_TYPEDEF
     { GCRY_CIPHER_MODE_CCM, "      CCM", 0,
       ccm_aead_init, GCRY_CCM_BLOCK_LEN, 8 },
+#endif
     { GCRY_CIPHER_MODE_GCM, "      GCM", 0,
       NULL, GCRY_GCM_BLOCK_LEN, GCRY_GCM_BLOCK_LEN },
     { GCRY_CIPHER_MODE_STREAM, "", 0 },