[PATCH 1/3] Use hash transform function return type for passing burn stack depth

Jussi Kivilinna jussi.kivilinna at iki.fi
Thu Sep 19 13:47:54 CEST 2013


* cipher/gostr4311-94.c (transform): Return stack burn depth.
* cipher/hash-common.c (_gcry_md_block_write): Use stack burn depth
returned by 'hd->bwrite'.
* cipher/hash-common.h (_gcry_md_block_write_t): Change return type to
'unsigned int'.
(gry_md_block_ctx_t): Remove 'stack_burn'.
* cipher/md4.c (transform): Return stack burn depth.
(md4_final): Use stack burn depth from transform.
* cipher/md5.c (transform): Return stack burn depth.
(md5_final): Use stack burn depth from transform.
* cipher/rmd160.c (transform): Return stack burn depth.
(rmd160_final): Use stack burn depth from transform.
* cipher/sha1.c (transform): Return stack burn depth.
(sha1_final): Use stack burn depth from transform.
* cipher/sha256.c (transform): Return stack burn depth.
(sha256_final): Use stack burn depth from transform.
* cipher/sha512.c (__transform, transform): Return stack burn depth.
(sha512_final): Use stack burn depth from transform.
* cipher/stribog.c (transform64): Return stack burn depth.
* cipher/tiger.c (transform): Return stack burn depth.
(tiger_final): Use stack burn depth from transform.
--

Transform function might want different depth of stack burn depending on
detected CPU features (like in SHA-512 on ARM with NEON). So return
stack burn depth from transform functions as a request or a hint to
calling function.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
 cipher/gostr3411-94.c |    9 +++++----
 cipher/hash-common.c  |   10 ++++++----
 cipher/hash-common.h  |    4 ++--
 cipher/md4.c          |   12 +++++++-----
 cipher/md5.c          |   12 +++++++-----
 cipher/rmd160.c       |   13 ++++++++-----
 cipher/sha1.c         |   16 +++++++++-------
 cipher/sha256.c       |   14 ++++++++------
 cipher/sha512.c       |   27 +++++++++++----------------
 cipher/stribog.c      |    7 ++++---
 cipher/tiger.c        |   13 ++++++++-----
 11 files changed, 75 insertions(+), 62 deletions(-)

diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c
index 93bf597..bfd52bd 100644
--- a/cipher/gostr3411-94.c
+++ b/cipher/gostr3411-94.c
@@ -38,7 +38,7 @@ typedef struct {
   u32 len;
 } GOSTR3411_CONTEXT;
 
-static void
+static unsigned int
 transform (void *c, const unsigned char *data);
 
 static void
@@ -53,8 +53,6 @@ gost3411_init (void *context)
   hd->bctx.nblocks = 0;
   hd->bctx.count = 0;
   hd->bctx.blocksize = 32;
-  /* FIXME: Fix this arbitrary value for the stack_burn size.  -wk */
-  hd->bctx.stack_burn = 200;
   hd->bctx.bwrite = transform;
 }
 
@@ -203,7 +201,7 @@ do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m)
 }
 
 
-static void
+static unsigned int
 transform (void *ctx, const unsigned char *data)
 {
   GOSTR3411_CONTEXT *hd = ctx;
@@ -212,6 +210,9 @@ transform (void *ctx, const unsigned char *data)
   memcpy (m, data, 32);
   do_hash_step (&hd->hd, hd->h, m);
   do_add (hd->sigma, m);
+
+/* FIXME: Fix this arbitrary value for the stack_burn size.  -wk */
+  return /* stack_burn */ 200;
 }
 
 /*
diff --git a/cipher/hash-common.c b/cipher/hash-common.c
index 1a6e8e9..bec699f 100644
--- a/cipher/hash-common.c
+++ b/cipher/hash-common.c
@@ -101,6 +101,7 @@ _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen)
 {
   const unsigned char *inbuf = inbuf_arg;
   gcry_md_block_ctx_t *hd = context;
+  unsigned int stack_burn = 0;
 
   if (sizeof(hd->buf) < hd->blocksize)
     BUG();
@@ -110,8 +111,8 @@ _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen)
 
   if (hd->count == hd->blocksize)  /* Flush the buffer. */
     {
-      hd->bwrite (hd, hd->buf);
-      _gcry_burn_stack (hd->stack_burn);
+      stack_burn = hd->bwrite (hd, hd->buf);
+      _gcry_burn_stack (stack_burn);
       hd->count = 0;
       hd->nblocks++;
     }
@@ -129,13 +130,14 @@ _gcry_md_block_write (void *context, const void *inbuf_arg, size_t inlen)
 
   while (inlen >= hd->blocksize)
     {
-      hd->bwrite (hd, inbuf);
+      stack_burn = hd->bwrite (hd, inbuf);
       hd->count = 0;
       hd->nblocks++;
       inlen -= hd->blocksize;
       inbuf += hd->blocksize;
     }
-  _gcry_burn_stack (hd->stack_burn);
   for (; inlen && hd->count < hd->blocksize; inlen--)
     hd->buf[hd->count++] = *inbuf++;
+
+  _gcry_burn_stack (stack_burn);
 }
diff --git a/cipher/hash-common.h b/cipher/hash-common.h
index 4dd5441..3caf0a7 100644
--- a/cipher/hash-common.h
+++ b/cipher/hash-common.h
@@ -29,7 +29,8 @@ const char * _gcry_hash_selftest_check_one
               const void *expect, size_t expectlen);
 
 /* Type for the md_write helper function.  */
-typedef void (*_gcry_md_block_write_t) (void *c, const unsigned char *buf);
+typedef unsigned int (*_gcry_md_block_write_t) (void *c,
+						const unsigned char *buf);
 
 #if defined(HAVE_U64_TYPEDEF) && defined(USE_SHA512)
 /* SHA-512 needs u64 and larger buffer. */
@@ -47,7 +48,6 @@ typedef struct gcry_md_block_ctx
     int count;
     size_t blocksize;
     _gcry_md_block_write_t bwrite;
-    size_t stack_burn;
 } gcry_md_block_ctx_t;
 
 
diff --git a/cipher/md4.c b/cipher/md4.c
index 9e75fbc..2de530c 100644
--- a/cipher/md4.c
+++ b/cipher/md4.c
@@ -64,7 +64,7 @@ typedef struct {
     u32 A,B,C,D;	  /* chaining variables */
 } MD4_CONTEXT;
 
-static void
+static unsigned int
 transform ( void *c, const unsigned char *data );
 
 static void
@@ -80,7 +80,6 @@ md4_init( void *context )
   ctx->bctx.nblocks = 0;
   ctx->bctx.count = 0;
   ctx->bctx.blocksize = 64;
-  ctx->bctx.stack_burn = 80+6*sizeof(void*);
   ctx->bctx.bwrite = transform;
 }
 
@@ -92,7 +91,7 @@ md4_init( void *context )
 /****************
  * transform 64 bytes
  */
-static void
+static unsigned int
 transform ( void *c, const unsigned char *data )
 {
   MD4_CONTEXT *ctx = c;
@@ -188,6 +187,8 @@ transform ( void *c, const unsigned char *data )
   ctx->B += B;
   ctx->C += C;
   ctx->D += D;
+
+  return /*burn_stack*/ 80+6*sizeof(void*);
 }
 
 
@@ -204,6 +205,7 @@ md4_final( void *context )
   MD4_CONTEXT *hd = context;
   u32 t, msb, lsb;
   byte *p;
+  unsigned int burn;
 
   _gcry_md_block_write(hd, NULL, 0); /* flush */;
 
@@ -244,8 +246,8 @@ md4_final( void *context )
   hd->bctx.buf[61] = msb >>  8;
   hd->bctx.buf[62] = msb >> 16;
   hd->bctx.buf[63] = msb >> 24;
-  transform( hd, hd->bctx.buf );
-  _gcry_burn_stack (80+6*sizeof(void*));
+  burn = transform( hd, hd->bctx.buf );
+  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #ifdef WORDS_BIGENDIAN
diff --git a/cipher/md5.c b/cipher/md5.c
index 9857f2c..88745a8 100644
--- a/cipher/md5.c
+++ b/cipher/md5.c
@@ -48,7 +48,7 @@ typedef struct {
     u32 A,B,C,D;	  /* chaining variables */
 } MD5_CONTEXT;
 
-static void
+static unsigned int
 transform ( void *ctx, const unsigned char *data );
 
 static void
@@ -64,7 +64,6 @@ md5_init( void *context )
   ctx->bctx.nblocks = 0;
   ctx->bctx.count = 0;
   ctx->bctx.blocksize = 64;
-  ctx->bctx.stack_burn = 80+6*sizeof(void*);
   ctx->bctx.bwrite = transform;
 }
 
@@ -82,7 +81,7 @@ md5_init( void *context )
 /****************
  * transform n*64 bytes
  */
-static void
+static unsigned int
 transform ( void *c, const unsigned char *data )
 {
   MD5_CONTEXT *ctx = c;
@@ -213,6 +212,8 @@ transform ( void *c, const unsigned char *data )
   ctx->B += B;
   ctx->C += C;
   ctx->D += D;
+
+  return /*burn_stack*/ 80+6*sizeof(void*);
 }
 
 
@@ -229,6 +230,7 @@ md5_final( void *context)
   MD5_CONTEXT *hd = context;
   u32 t, msb, lsb;
   byte *p;
+  unsigned int burn;
 
   _gcry_md_block_write(hd, NULL, 0); /* flush */;
 
@@ -269,8 +271,8 @@ md5_final( void *context)
   hd->bctx.buf[61] = msb >>  8;
   hd->bctx.buf[62] = msb >> 16;
   hd->bctx.buf[63] = msb >> 24;
-  transform( hd, hd->bctx.buf );
-  _gcry_burn_stack (80+6*sizeof(void*));
+  burn = transform( hd, hd->bctx.buf );
+  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #ifdef WORDS_BIGENDIAN
diff --git a/cipher/rmd160.c b/cipher/rmd160.c
index 5bb32a6..7f143df 100644
--- a/cipher/rmd160.c
+++ b/cipher/rmd160.c
@@ -139,7 +139,7 @@
  * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
  */
 
-static void
+static unsigned int
 transform ( void *ctx, const unsigned char *data );
 
 void
@@ -152,10 +152,10 @@ _gcry_rmd160_init (void *context)
   hd->h2 = 0x98BADCFE;
   hd->h3 = 0x10325476;
   hd->h4 = 0xC3D2E1F0;
+
   hd->bctx.nblocks = 0;
   hd->bctx.count = 0;
   hd->bctx.blocksize = 64;
-  hd->bctx.stack_burn = 108+5*sizeof(void*);
   hd->bctx.bwrite = transform;
 }
 
@@ -164,7 +164,7 @@ _gcry_rmd160_init (void *context)
 /****************
  * Transform the message X which consists of 16 32-bit-words
  */
-static void
+static unsigned int
 transform ( void *ctx, const unsigned char *data )
 {
   RMD160_CONTEXT *hd = ctx;
@@ -400,6 +400,8 @@ transform ( void *ctx, const unsigned char *data )
   hd->h3 = hd->h4 + b + aa;
   hd->h4 = hd->h0 + c + bb;
   hd->h0 = t;
+
+  return /*burn_stack*/ 108+5*sizeof(void*);
 }
 
 
@@ -434,6 +436,7 @@ rmd160_final( void *context )
   RMD160_CONTEXT *hd = context;
   u32 t, msb, lsb;
   byte *p;
+  unsigned int burn;
 
   _gcry_md_block_write(hd, NULL, 0); /* flush */;
 
@@ -474,8 +477,8 @@ rmd160_final( void *context )
   hd->bctx.buf[61] = msb >>  8;
   hd->bctx.buf[62] = msb >> 16;
   hd->bctx.buf[63] = msb >> 24;
-  transform( hd, hd->bctx.buf );
-  _gcry_burn_stack (108+5*sizeof(void*));
+  burn = transform( hd, hd->bctx.buf );
+  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #ifdef WORDS_BIGENDIAN
diff --git a/cipher/sha1.c b/cipher/sha1.c
index 9e4e9c6..382bce8 100644
--- a/cipher/sha1.c
+++ b/cipher/sha1.c
@@ -57,10 +57,10 @@ typedef struct
   u32           h0,h1,h2,h3,h4;
 } SHA1_CONTEXT;
 
-
-static void
+static unsigned int
 transform (void *c, const unsigned char *data);
 
+
 static void
 sha1_init (void *context)
 {
@@ -71,10 +71,10 @@ sha1_init (void *context)
   hd->h2 = 0x98badcfe;
   hd->h3 = 0x10325476;
   hd->h4 = 0xc3d2e1f0;
+
   hd->bctx.nblocks = 0;
   hd->bctx.count = 0;
   hd->bctx.blocksize = 64;
-  hd->bctx.stack_burn = 88+4*sizeof(void*);
   hd->bctx.bwrite = transform;
 }
 
@@ -104,7 +104,7 @@ sha1_init (void *context)
 /*
  * Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA.
  */
-static void
+static unsigned int
 transform (void *ctx, const unsigned char *data)
 {
   SHA1_CONTEXT *hd = ctx;
@@ -224,6 +224,8 @@ transform (void *ctx, const unsigned char *data)
       hd->h2 += c;
       hd->h3 += d;
       hd->h4 += e;
+
+  return /* burn_stack */ 88+4*sizeof(void*);
 }
 
 
@@ -238,9 +240,9 @@ static void
 sha1_final(void *context)
 {
   SHA1_CONTEXT *hd = context;
-
   u32 t, msb, lsb;
   unsigned char *p;
+  unsigned int burn;
 
   _gcry_md_block_write (hd, NULL, 0); /* flush */;
 
@@ -281,8 +283,8 @@ sha1_final(void *context)
   hd->bctx.buf[61] = lsb >> 16;
   hd->bctx.buf[62] = lsb >>  8;
   hd->bctx.buf[63] = lsb	   ;
-  transform( hd, hd->bctx.buf );
-  _gcry_burn_stack (88+4*sizeof(void*));
+  burn = transform( hd, hd->bctx.buf );
+  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #ifdef WORDS_BIGENDIAN
diff --git a/cipher/sha256.c b/cipher/sha256.c
index 1785699..cf23f2f 100644
--- a/cipher/sha256.c
+++ b/cipher/sha256.c
@@ -50,9 +50,10 @@ typedef struct {
   u32  h0,h1,h2,h3,h4,h5,h6,h7;
 } SHA256_CONTEXT;
 
-static void
+static unsigned int
 transform (void *c, const unsigned char *data);
 
+
 static void
 sha256_init (void *context)
 {
@@ -70,7 +71,6 @@ sha256_init (void *context)
   hd->bctx.nblocks = 0;
   hd->bctx.count = 0;
   hd->bctx.blocksize = 64;
-  hd->bctx.stack_burn = 74*4+32;
   hd->bctx.bwrite = transform;
 }
 
@@ -92,7 +92,6 @@ sha224_init (void *context)
   hd->bctx.nblocks = 0;
   hd->bctx.count = 0;
   hd->bctx.blocksize = 64;
-  hd->bctx.stack_burn = 74*4+32;
   hd->bctx.bwrite = transform;
 }
 
@@ -145,7 +144,7 @@ Sum1 (u32 x)
 }
 
 
-static void
+static unsigned int
 transform (void *ctx, const unsigned char *data)
 {
   SHA256_CONTEXT *hd = ctx;
@@ -261,6 +260,8 @@ transform (void *ctx, const unsigned char *data)
   hd->h5 += f;
   hd->h6 += g;
   hd->h7 += h;
+
+  return /*burn_stack*/ 74*4+32;
 }
 #undef S0
 #undef S1
@@ -278,6 +279,7 @@ sha256_final(void *context)
   SHA256_CONTEXT *hd = context;
   u32 t, msb, lsb;
   byte *p;
+  unsigned int burn;
 
   _gcry_md_block_write (hd, NULL, 0); /* flush */;
 
@@ -318,8 +320,8 @@ sha256_final(void *context)
   hd->bctx.buf[61] = lsb >> 16;
   hd->bctx.buf[62] = lsb >>  8;
   hd->bctx.buf[63] = lsb;
-  transform (hd, hd->bctx.buf);
-  _gcry_burn_stack (74*4+32);
+  burn = transform (hd, hd->bctx.buf);
+  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #ifdef WORDS_BIGENDIAN
diff --git a/cipher/sha512.c b/cipher/sha512.c
index ed63ae6..26cbe14 100644
--- a/cipher/sha512.c
+++ b/cipher/sha512.c
@@ -63,7 +63,6 @@
 # endif
 #endif
 
-
 typedef struct
 {
   u64 h0, h1, h2, h3, h4, h5, h6, h7;
@@ -78,7 +77,7 @@ typedef struct
 #endif
 } SHA512_CONTEXT;
 
-static void
+static unsigned int
 transform (void *context, const unsigned char *data);
 
 static void
@@ -100,7 +99,6 @@ sha512_init (void *context)
   ctx->bctx.count = 0;
   ctx->bctx.blocksize = 128;
   ctx->bctx.bwrite = transform;
-  ctx->bctx.stack_burn = 256;
 
 #ifdef USE_ARM_NEON_ASM
   ctx->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0;
@@ -126,7 +124,6 @@ sha384_init (void *context)
   ctx->bctx.count = 0;
   ctx->bctx.blocksize = 128;
   ctx->bctx.bwrite = transform;
-  ctx->bctx.stack_burn = 256;
 
 #ifdef USE_ARM_NEON_ASM
   ctx->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0;
@@ -211,7 +208,7 @@ static const u64 k[] =
 /****************
  * Transform the message W which consists of 16 64-bit-words
  */
-static void
+static unsigned int
 __transform (SHA512_STATE *hd, const unsigned char *data)
 {
   u64 a, b, c, d, e, f, g, h;
@@ -489,6 +486,9 @@ __transform (SHA512_STATE *hd, const unsigned char *data)
   hd->h5 += f;
   hd->h6 += g;
   hd->h7 += h;
+
+  return /* burn_stack */ (8 + 16) * sizeof(u64) + sizeof(u32) +
+                          3 * sizeof(void*);
 }
 
 
@@ -499,7 +499,7 @@ void _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd,
 #endif
 
 
-static void
+static unsigned int
 transform (void *context, const unsigned char *data)
 {
   SHA512_CONTEXT *ctx = context;
@@ -509,17 +509,13 @@ transform (void *context, const unsigned char *data)
     {
       _gcry_sha512_transform_armv7_neon(&ctx->state, data, k);
 
-      /* TODO: return burn stack to md_block_write */
-      /* return stack burn depth */
-      return /*(sizeof(void *) * 3)*/;
+      /* _gcry_sha512_transform_armv7_neon does not store sensitive data
+       * to stack.  */
+      return /* no burn_stack */ 0;
     }
 #endif
 
-  __transform (&ctx->state, data);
-
-  /* TODO: return burn stack to md_block_write */
-  /* return stack burn depth */
-  return /*256*/;
+  return __transform (&ctx->state, data) + 3 * sizeof(void*);
 }
 
 
@@ -587,8 +583,7 @@ sha512_final (void *context)
   hd->bctx.buf[125] = lsb >> 16;
   hd->bctx.buf[126] = lsb >> 8;
   hd->bctx.buf[127] = lsb;
-  transform (hd, hd->bctx.buf);
-  stack_burn_depth = hd->bctx.stack_burn;
+  stack_burn_depth = transform (hd, hd->bctx.buf);
   _gcry_burn_stack (stack_burn_depth);
 
   p = hd->bctx.buf;
diff --git a/cipher/stribog.c b/cipher/stribog.c
index 234a17e..1f79882 100644
--- a/cipher/stribog.c
+++ b/cipher/stribog.c
@@ -1274,7 +1274,7 @@ static void g (u64 *h, u64 *m, u64 *N)
 }
 
 
-static void
+static unsigned int
 transform64 (void *context, const unsigned char *inbuf_arg);
 
 
@@ -1287,7 +1287,6 @@ stribog_init_512 (void *context)
 
   hd->bctx.blocksize = 64;
   hd->bctx.bwrite = transform64;
-  hd->bctx.stack_burn = 768;
 }
 
 static void
@@ -1346,12 +1345,14 @@ transform (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count)
       hd->Sigma[i] += M[i];
 }
 
-static void
+static unsigned int
 transform64 (void *context, const unsigned char *inbuf_arg)
 {
   STRIBOG_CONTEXT *hd = context;
 
   transform (hd, inbuf_arg, 64 * 8);
+
+  return /* burn_stack */ 768;
 }
 
 /*
diff --git a/cipher/tiger.c b/cipher/tiger.c
index 49d3919..8f5959b 100644
--- a/cipher/tiger.c
+++ b/cipher/tiger.c
@@ -587,7 +587,7 @@ static u64 sbox4[256] = {
   U64_C(0xc83223f1720aef96) /* 1022 */, U64_C(0xc3a0396f7363a51f) /* 1023 */
 };
 
-static void
+static unsigned int
 transform ( void *ctx, const unsigned char *data );
 
 static void
@@ -598,10 +598,10 @@ do_init (void *context, int variant)
   hd->a = 0x0123456789abcdefLL;
   hd->b = 0xfedcba9876543210LL;
   hd->c = 0xf096a5b4c3b2e187LL;
+
   hd->bctx.nblocks = 0;
   hd->bctx.count = 0;
   hd->bctx.blocksize = 64;
-  hd->bctx.stack_burn = 21*8+11*sizeof(void*);
   hd->bctx.bwrite = transform;
   hd->variant = variant;
 }
@@ -691,7 +691,7 @@ key_schedule( u64 *x )
 /****************
  * Transform the message DATA which consists of 512 bytes (8 words)
  */
-static void
+static unsigned int
 transform ( void *ctx, const unsigned char *data )
 {
   TIGER_CONTEXT *hd = ctx;
@@ -735,6 +735,8 @@ transform ( void *ctx, const unsigned char *data )
   hd->a = a;
   hd->b = b;
   hd->c = c;
+
+  return /*burn_stack*/ 21*8+11*sizeof(void*);
 }
 
 
@@ -747,6 +749,7 @@ tiger_final( void *context )
   TIGER_CONTEXT *hd = context;
   u32 t, msb, lsb;
   byte *p;
+  unsigned int burn;
   byte pad = hd->variant == 2? 0x80 : 0x01;
 
   _gcry_md_block_write(hd, NULL, 0); /* flush */;
@@ -788,8 +791,8 @@ tiger_final( void *context )
   hd->bctx.buf[61] = msb >>  8;
   hd->bctx.buf[62] = msb >> 16;
   hd->bctx.buf[63] = msb >> 24;
-  transform( hd, hd->bctx.buf );
-  _gcry_burn_stack (21*8+11*sizeof(void*));
+  burn = transform( hd, hd->bctx.buf );
+  _gcry_burn_stack (burn);
 
   p = hd->bctx.buf;
 #ifdef WORDS_BIGENDIAN




More information about the Gcrypt-devel mailing list