[PATCH 2/3] Use buf_cpy instead of copying buffers byte by byte

Jussi Kivilinna jussi.kivilinna at iki.fi
Thu Mar 21 20:36:25 CET 2019


* cipher/bufhelp.h (buf_cpy): Skip memcpy if length is zero.
* cipher/cipher-ccm.c (do_cbc_mac): Replace buffer copy loops with buf_cpy call.
* cipher/cipher-cmac.c (_gcry_cmac_write): Ditto.
* cipher/cipher-ocb.c (_gcry_cipher_ocb_authenticate): Ditto.
--

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 0 files changed

diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h
index 0e8f5991c..5043d8b04 100644
--- a/cipher/bufhelp.h
+++ b/cipher/bufhelp.h
@@ -207,6 +207,8 @@ buf_cpy(void *_dst, const void *_src, size_t len)
 #if __GNUC__ >= 4
   if (!__builtin_constant_p (len))
     {
+      if (len == 0)
+	return;
       memcpy(_dst, _src, len);
       return;
     }
diff --git a/cipher/cipher-ccm.c b/cipher/cipher-ccm.c
index fd284caa5..3bacb6b16 100644
--- a/cipher/cipher-ccm.c
+++ b/cipher/cipher-ccm.c
@@ -44,6 +44,7 @@ do_cbc_mac (gcry_cipher_hd_t c, const unsigned char *inbuf, size_t inlen,
   unsigned int burn = 0;
   unsigned int unused = c->u_mode.ccm.mac_unused;
   size_t nblocks;
+  size_t n;
 
   if (inlen == 0 && (unused == 0 || !do_padding))
     return 0;
@@ -52,8 +53,12 @@ do_cbc_mac (gcry_cipher_hd_t c, const unsigned char *inbuf, size_t inlen,
     {
       if (inlen + unused < blocksize || unused > 0)
         {
-          for (; inlen && unused < blocksize; inlen--)
-            c->u_mode.ccm.macbuf[unused++] = *inbuf++;
+	  n = (inlen > blocksize - unused) ? blocksize - unused : inlen;
+
+	  buf_cpy (&c->u_mode.ccm.macbuf[unused], inbuf, n);
+	  unused += n;
+	  inlen -= n;
+	  inbuf += n;
         }
       if (!inlen)
         {
diff --git a/cipher/cipher-cmac.c b/cipher/cipher-cmac.c
index da550c372..4efd1e19b 100644
--- a/cipher/cipher-cmac.c
+++ b/cipher/cipher-cmac.c
@@ -43,6 +43,7 @@ _gcry_cmac_write (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx,
   byte outbuf[MAX_BLOCKSIZE];
   unsigned int burn = 0;
   unsigned int nblocks;
+  size_t n;
 
   if (ctx->tag)
     return GPG_ERR_INV_STATE;
@@ -56,15 +57,24 @@ _gcry_cmac_write (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx,
   /* Last block is needed for cmac_final.  */
   if (ctx->mac_unused + inlen <= blocksize)
     {
-      for (; inlen && ctx->mac_unused < blocksize; inlen--)
-        ctx->macbuf[ctx->mac_unused++] = *inbuf++;
+      buf_cpy (&ctx->macbuf[ctx->mac_unused], inbuf, inlen);
+      ctx->mac_unused += inlen;
+      inbuf += inlen;
+      inlen -= inlen;
+
       return 0;
     }
 
   if (ctx->mac_unused)
     {
-      for (; inlen && ctx->mac_unused < blocksize; inlen--)
-        ctx->macbuf[ctx->mac_unused++] = *inbuf++;
+      n = inlen;
+      if (n > blocksize - ctx->mac_unused)
+	n = blocksize - ctx->mac_unused;
+
+      buf_cpy (&ctx->macbuf[ctx->mac_unused], inbuf, n);
+      ctx->mac_unused += n;
+      inbuf += n;
+      inlen -= n;
 
       cipher_block_xor (ctx->u_iv.iv, ctx->u_iv.iv, ctx->macbuf, blocksize);
       set_burn (burn, enc_fn (&c->context.c, ctx->u_iv.iv, ctx->u_iv.iv));
@@ -96,8 +106,14 @@ _gcry_cmac_write (gcry_cipher_hd_t c, gcry_cmac_context_t *ctx,
   if (inlen == 0)
     BUG ();
 
-  for (; inlen && ctx->mac_unused < blocksize; inlen--)
-    ctx->macbuf[ctx->mac_unused++] = *inbuf++;
+  n = inlen;
+  if (n > blocksize - ctx->mac_unused)
+    n = blocksize - ctx->mac_unused;
+
+  buf_cpy (&ctx->macbuf[ctx->mac_unused], inbuf, n);
+  ctx->mac_unused += n;
+  inbuf += n;
+  inlen -= n;
 
   if (burn)
     _gcry_burn_stack (burn + 4 * sizeof (void *));
diff --git a/cipher/cipher-ocb.c b/cipher/cipher-ocb.c
index 308b04952..f1c94db0c 100644
--- a/cipher/cipher-ocb.c
+++ b/cipher/cipher-ocb.c
@@ -254,6 +254,7 @@ _gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf,
   unsigned char l_tmp[OCB_BLOCK_LEN];
   unsigned int burn = 0;
   unsigned int nburn;
+  size_t n;
 
   /* Check that a nonce and thus a key has been set and that we have
      not yet computed the tag.  We also return an error if the aad has
@@ -268,9 +269,15 @@ _gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf,
   /* Process remaining data from the last call first.  */
   if (c->u_mode.ocb.aad_nleftover)
     {
-      for (; abuflen && c->u_mode.ocb.aad_nleftover < OCB_BLOCK_LEN;
-           abuf++, abuflen--)
-        c->u_mode.ocb.aad_leftover[c->u_mode.ocb.aad_nleftover++] = *abuf;
+      n = abuflen;
+      if (n > OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover)
+	n = OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover;
+
+      buf_cpy (&c->u_mode.ocb.aad_leftover[c->u_mode.ocb.aad_nleftover],
+	       abuf, n);
+      c->u_mode.ocb.aad_nleftover += n;
+      abuf += n;
+      abuflen -= n;
 
       if (c->u_mode.ocb.aad_nleftover == OCB_BLOCK_LEN)
         {
@@ -383,9 +390,19 @@ _gcry_cipher_ocb_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf,
     }
 
   /* Store away the remaining data.  */
-  for (; abuflen && c->u_mode.ocb.aad_nleftover < OCB_BLOCK_LEN;
-       abuf++, abuflen--)
-    c->u_mode.ocb.aad_leftover[c->u_mode.ocb.aad_nleftover++] = *abuf;
+  if (abuflen)
+    {
+      n = abuflen;
+      if (n > OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover)
+	n = OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover;
+
+      buf_cpy (&c->u_mode.ocb.aad_leftover[c->u_mode.ocb.aad_nleftover],
+	       abuf, n);
+      c->u_mode.ocb.aad_nleftover += n;
+      abuf += n;
+      abuflen -= n;
+    }
+
   gcry_assert (!abuflen);
 
   if (burn > 0)




More information about the Gcrypt-devel mailing list