[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