[PATCH 2/5] Separate common md block code
Dmitry Eremin-Solenikov
dbaryshkov at gmail.com
Mon Sep 2 11:28:49 CEST 2013
* cipher/hash-common.c, cipher/hash-common.h: add _gcry_md_block_write()
a new function to handle block md operations. Currently implementation
is limited to 64 bytes buffer and u32 blocks counter.
* cipher/md4.c, cipher/md5.c, cipher/rmd.h, cipher/rmd160.c,
cipher/sha1.c, cipher/sha256.c, cipher/tiger.c: convert to use
_gcry_md_block_write().
whirpool and sha512 are left as before, as sha512 uses 128 bytes buffer
and u64 blocks counter and whirpool does not have trivial block handling
structure.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov at gmail.com>
---
cipher/hash-common.c | 42 ++++++++++++++++++
cipher/hash-common.h | 19 ++++++--
cipher/md4.c | 109 +++++++++++++++-------------------------------
cipher/md5.c | 110 +++++++++++++++-------------------------------
cipher/rmd.h | 5 +--
cipher/rmd160.c | 104 +++++++++++++++----------------------------
cipher/sha1.c | 121 +++++++++++++++------------------------------------
cipher/sha256.c | 113 +++++++++++++++++------------------------------
cipher/tiger.c | 112 ++++++++++++++++-------------------------------
9 files changed, 279 insertions(+), 456 deletions(-)
diff --git a/cipher/hash-common.c b/cipher/hash-common.c
index 8c413bc..e267da1 100644
--- a/cipher/hash-common.c
+++ b/cipher/hash-common.c
@@ -91,3 +91,45 @@ _gcry_hash_selftest_check_one (int algo,
return result;
}
+
+void
+_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;
+
+ if ( hd->buf == NULL || hd->bwrite == NULL)
+ return;
+
+ if( hd->count == hd->blocksize ) /* flush the buffer */
+ {
+ hd->bwrite( hd, hd->buf );
+ _gcry_burn_stack (hd->stack_burn);
+ hd->count = 0;
+ hd->nblocks++;
+ }
+ if( !inbuf )
+ return;
+
+ if( hd->count )
+ {
+ for( ; inlen && hd->count < hd->blocksize; inlen-- )
+ hd->buf[hd->count++] = *inbuf++;
+ _gcry_md_block_write( hd, NULL, 0 );
+ if( !inlen )
+ return;
+ }
+
+ while( inlen >= hd->blocksize)
+ {
+ 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++;
+
+}
diff --git a/cipher/hash-common.h b/cipher/hash-common.h
index fdebef4..9553dcf 100644
--- a/cipher/hash-common.h
+++ b/cipher/hash-common.h
@@ -26,8 +26,21 @@ const char * _gcry_hash_selftest_check_one
int datamode, const void *data, size_t datalen,
const void *expect, size_t expectlen);
-
-
-
+/* Type for the md_write helper function for block MD. */
+typedef void (*_gcry_md_block_write_t) (void *c, const unsigned char *buf);
+
+typedef struct gcry_md_block_ctx
+{
+ u32 nblocks;
+ int count;
+ byte buf[64];
+ size_t blocksize;
+ _gcry_md_block_write_t bwrite;
+ size_t stack_burn;
+} gcry_md_block_ctx_t;
+
+
+void
+_gcry_md_block_write( void *context, const void *inbuf_arg, size_t inlen);
#endif /*GCRY_HASH_COMMON_H*/
diff --git a/cipher/md4.c b/cipher/md4.c
index 22fbf8d..9e75fbc 100644
--- a/cipher/md4.c
+++ b/cipher/md4.c
@@ -56,15 +56,16 @@
#include "cipher.h"
#include "bithelp.h"
+#include "hash-common.h"
typedef struct {
+ gcry_md_block_ctx_t bctx;
u32 A,B,C,D; /* chaining variables */
- u32 nblocks;
- byte buf[64];
- int count;
} MD4_CONTEXT;
+static void
+transform ( void *c, const unsigned char *data );
static void
md4_init( void *context )
@@ -76,8 +77,11 @@ md4_init( void *context )
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
- ctx->nblocks = 0;
- ctx->count = 0;
+ ctx->bctx.nblocks = 0;
+ ctx->bctx.count = 0;
+ ctx->bctx.blocksize = 64;
+ ctx->bctx.stack_burn = 80+6*sizeof(void*);
+ ctx->bctx.bwrite = transform;
}
#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
@@ -89,8 +93,9 @@ md4_init( void *context )
* transform 64 bytes
*/
static void
-transform ( MD4_CONTEXT *ctx, const unsigned char *data )
+transform ( void *c, const unsigned char *data )
{
+ MD4_CONTEXT *ctx = c;
u32 in[16];
register u32 A = ctx->A;
register u32 B = ctx->B;
@@ -187,50 +192,6 @@ transform ( MD4_CONTEXT *ctx, const unsigned char *data )
-/* The routine updates the message-digest context to
- * account for the presence of each of the characters inBuf[0..inLen-1]
- * in the message whose digest is being computed.
- */
-static void
-md4_write ( void *context, const void *inbuf_arg, size_t inlen)
-{
- const unsigned char *inbuf = inbuf_arg;
- MD4_CONTEXT *hd = context;
-
- if( hd->count == 64 ) /* flush the buffer */
- {
- transform( hd, hd->buf );
- _gcry_burn_stack (80+6*sizeof(void*));
- hd->count = 0;
- hd->nblocks++;
- }
- if( !inbuf )
- return;
-
- if( hd->count )
- {
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
- md4_write( hd, NULL, 0 );
- if( !inlen )
- return;
- }
- _gcry_burn_stack (80+6*sizeof(void*));
-
- while( inlen >= 64 )
- {
- transform( hd, inbuf );
- hd->count = 0;
- hd->nblocks++;
- inlen -= 64;
- inbuf += 64;
- }
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
-}
-
-
-
/* The routine final terminates the message-digest computation and
* ends with the desired message digest in mdContext->digest[0...15].
* The handle is prepared for a new MD4 cycle.
@@ -244,15 +205,15 @@ md4_final( void *context )
u32 t, msb, lsb;
byte *p;
- md4_write(hd, NULL, 0); /* flush */;
+ _gcry_md_block_write(hd, NULL, 0); /* flush */;
- t = hd->nblocks;
+ t = hd->bctx.nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
- if( (lsb += hd->count) < t )
+ if( (lsb += hd->bctx.count) < t )
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
@@ -260,33 +221,33 @@ md4_final( void *context )
msb <<= 3;
msb |= t >> 29;
- if( hd->count < 56 ) /* enough room */
+ if( hd->bctx.count < 56 ) /* enough room */
{
- hd->buf[hd->count++] = 0x80; /* pad */
- while( hd->count < 56 )
- hd->buf[hd->count++] = 0; /* pad */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ while( hd->bctx.count < 56 )
+ hd->bctx.buf[hd->bctx.count++] = 0; /* pad */
}
else /* need one extra block */
{
- hd->buf[hd->count++] = 0x80; /* pad character */
- while( hd->count < 64 )
- hd->buf[hd->count++] = 0;
- md4_write(hd, NULL, 0); /* flush */;
- memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ while( hd->bctx.count < 64 )
+ hd->bctx.buf[hd->bctx.count++] = 0;
+ _gcry_md_block_write(hd, NULL, 0); /* flush */;
+ memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
}
/* append the 64 bit count */
- hd->buf[56] = lsb ;
- hd->buf[57] = lsb >> 8;
- hd->buf[58] = lsb >> 16;
- hd->buf[59] = lsb >> 24;
- hd->buf[60] = msb ;
- hd->buf[61] = msb >> 8;
- hd->buf[62] = msb >> 16;
- hd->buf[63] = msb >> 24;
- transform( hd, hd->buf );
+ hd->bctx.buf[56] = lsb ;
+ hd->bctx.buf[57] = lsb >> 8;
+ hd->bctx.buf[58] = lsb >> 16;
+ hd->bctx.buf[59] = lsb >> 24;
+ hd->bctx.buf[60] = msb ;
+ 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*));
- p = hd->buf;
+ p = hd->bctx.buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
*p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
@@ -305,7 +266,7 @@ static byte *
md4_read (void *context)
{
MD4_CONTEXT *hd = context;
- return hd->buf;
+ return hd->bctx.buf;
}
static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
@@ -322,6 +283,6 @@ static gcry_md_oid_spec_t oid_spec_md4[] =
gcry_md_spec_t _gcry_digest_spec_md4 =
{
"MD4", asn, DIM (asn), oid_spec_md4,16,
- md4_init, md4_write, md4_final, md4_read,
+ md4_init, _gcry_md_block_write, md4_final, md4_read,
sizeof (MD4_CONTEXT)
};
diff --git a/cipher/md5.c b/cipher/md5.c
index a98678a..9857f2c 100644
--- a/cipher/md5.c
+++ b/cipher/md5.c
@@ -40,15 +40,16 @@
#include "cipher.h"
#include "bithelp.h"
+#include "hash-common.h"
typedef struct {
+ gcry_md_block_ctx_t bctx;
u32 A,B,C,D; /* chaining variables */
- u32 nblocks;
- byte buf[64];
- int count;
} MD5_CONTEXT;
+static void
+transform ( void *ctx, const unsigned char *data );
static void
md5_init( void *context )
@@ -60,8 +61,11 @@ md5_init( void *context )
ctx->C = 0x98badcfe;
ctx->D = 0x10325476;
- ctx->nblocks = 0;
- ctx->count = 0;
+ ctx->bctx.nblocks = 0;
+ ctx->bctx.count = 0;
+ ctx->bctx.blocksize = 64;
+ ctx->bctx.stack_burn = 80+6*sizeof(void*);
+ ctx->bctx.bwrite = transform;
}
@@ -79,8 +83,9 @@ md5_init( void *context )
* transform n*64 bytes
*/
static void
-transform ( MD5_CONTEXT *ctx, const unsigned char *data )
+transform ( void *c, const unsigned char *data )
{
+ MD5_CONTEXT *ctx = c;
u32 correct_words[16];
register u32 A = ctx->A;
register u32 B = ctx->B;
@@ -212,51 +217,6 @@ transform ( MD5_CONTEXT *ctx, const unsigned char *data )
-/* The routine updates the message-digest context to
- * account for the presence of each of the characters inBuf[0..inLen-1]
- * in the message whose digest is being computed.
- */
-static void
-md5_write( void *context, const void *inbuf_arg , size_t inlen)
-{
- const unsigned char *inbuf = inbuf_arg;
- MD5_CONTEXT *hd = context;
-
- if( hd->count == 64 ) /* flush the buffer */
- {
- transform( hd, hd->buf );
- _gcry_burn_stack (80+6*sizeof(void*));
- hd->count = 0;
- hd->nblocks++;
- }
- if( !inbuf )
- return;
-
- if( hd->count )
- {
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
- md5_write( hd, NULL, 0 );
- if( !inlen )
- return;
- }
- _gcry_burn_stack (80+6*sizeof(void*));
-
- while( inlen >= 64 )
- {
- transform( hd, inbuf );
- hd->count = 0;
- hd->nblocks++;
- inlen -= 64;
- inbuf += 64;
- }
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
-
-}
-
-
-
/* The routine final terminates the message-digest computation and
* ends with the desired message digest in mdContext->digest[0...15].
* The handle is prepared for a new MD5 cycle.
@@ -270,15 +230,15 @@ md5_final( void *context)
u32 t, msb, lsb;
byte *p;
- md5_write(hd, NULL, 0); /* flush */;
+ _gcry_md_block_write(hd, NULL, 0); /* flush */;
- t = hd->nblocks;
+ t = hd->bctx.nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
- if( (lsb += hd->count) < t )
+ if( (lsb += hd->bctx.count) < t )
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
@@ -286,33 +246,33 @@ md5_final( void *context)
msb <<= 3;
msb |= t >> 29;
- if( hd->count < 56 ) /* enough room */
+ if( hd->bctx.count < 56 ) /* enough room */
{
- hd->buf[hd->count++] = 0x80; /* pad */
- while( hd->count < 56 )
- hd->buf[hd->count++] = 0; /* pad */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ while( hd->bctx.count < 56 )
+ hd->bctx.buf[hd->bctx.count++] = 0; /* pad */
}
else /* need one extra block */
{
- hd->buf[hd->count++] = 0x80; /* pad character */
- while( hd->count < 64 )
- hd->buf[hd->count++] = 0;
- md5_write(hd, NULL, 0); /* flush */;
- memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ while( hd->bctx.count < 64 )
+ hd->bctx.buf[hd->bctx.count++] = 0;
+ _gcry_md_block_write(hd, NULL, 0); /* flush */;
+ memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
}
/* append the 64 bit count */
- hd->buf[56] = lsb ;
- hd->buf[57] = lsb >> 8;
- hd->buf[58] = lsb >> 16;
- hd->buf[59] = lsb >> 24;
- hd->buf[60] = msb ;
- hd->buf[61] = msb >> 8;
- hd->buf[62] = msb >> 16;
- hd->buf[63] = msb >> 24;
- transform( hd, hd->buf );
+ hd->bctx.buf[56] = lsb ;
+ hd->bctx.buf[57] = lsb >> 8;
+ hd->bctx.buf[58] = lsb >> 16;
+ hd->bctx.buf[59] = lsb >> 24;
+ hd->bctx.buf[60] = msb ;
+ 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*));
- p = hd->buf;
+ p = hd->bctx.buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *p++ = hd->a ; *p++ = hd->a >> 8; \
*p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
@@ -331,7 +291,7 @@ static byte *
md5_read( void *context )
{
MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
- return hd->buf;
+ return hd->bctx.buf;
}
static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */
@@ -350,6 +310,6 @@ static gcry_md_oid_spec_t oid_spec_md5[] =
gcry_md_spec_t _gcry_digest_spec_md5 =
{
"MD5", asn, DIM (asn), oid_spec_md5, 16,
- md5_init, md5_write, md5_final, md5_read,
+ md5_init, _gcry_md_block_write, md5_final, md5_read,
sizeof (MD5_CONTEXT)
};
diff --git a/cipher/rmd.h b/cipher/rmd.h
index 6a9fe31..a56ee49 100644
--- a/cipher/rmd.h
+++ b/cipher/rmd.h
@@ -20,14 +20,13 @@
#ifndef G10_RMD_H
#define G10_RMD_H
+#include "hash-common.h"
/* We need this here because random.c must have direct access. */
typedef struct
{
+ gcry_md_block_ctx_t bctx;
u32 h0,h1,h2,h3,h4;
- u32 nblocks;
- byte buf[64];
- int count;
} RMD160_CONTEXT;
void _gcry_rmd160_init ( void *context );
diff --git a/cipher/rmd160.c b/cipher/rmd160.c
index 179a4d9..5bb32a6 100644
--- a/cipher/rmd160.c
+++ b/cipher/rmd160.c
@@ -139,6 +139,8 @@
* 1 million times "a" 52783243c1697bdbe16d37f97f68f08325dc1528
*/
+static void
+transform ( void *ctx, const unsigned char *data );
void
_gcry_rmd160_init (void *context)
@@ -150,8 +152,11 @@ _gcry_rmd160_init (void *context)
hd->h2 = 0x98BADCFE;
hd->h3 = 0x10325476;
hd->h4 = 0xC3D2E1F0;
- hd->nblocks = 0;
- hd->count = 0;
+ hd->bctx.nblocks = 0;
+ hd->bctx.count = 0;
+ hd->bctx.blocksize = 64;
+ hd->bctx.stack_burn = 108+5*sizeof(void*);
+ hd->bctx.bwrite = transform;
}
@@ -160,8 +165,9 @@ _gcry_rmd160_init (void *context)
* Transform the message X which consists of 16 32-bit-words
*/
static void
-transform ( RMD160_CONTEXT *hd, const unsigned char *data )
+transform ( void *ctx, const unsigned char *data )
{
+ RMD160_CONTEXT *hd = ctx;
register u32 a,b,c,d,e;
u32 aa,bb,cc,dd,ee,t;
#ifdef WORDS_BIGENDIAN
@@ -397,46 +403,6 @@ transform ( RMD160_CONTEXT *hd, const unsigned char *data )
}
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-rmd160_write ( void *context, const void *inbuf_arg, size_t inlen)
-{
- const unsigned char *inbuf = inbuf_arg;
- RMD160_CONTEXT *hd = context;
-
- if( hd->count == 64 ) /* flush the buffer */
- {
- transform( hd, hd->buf );
- _gcry_burn_stack (108+5*sizeof(void*));
- hd->count = 0;
- hd->nblocks++;
- }
- if( !inbuf )
- return;
- if( hd->count )
- {
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
- rmd160_write( hd, NULL, 0 );
- if( !inlen )
- return;
- }
-
- while( inlen >= 64 )
- {
- transform( hd, inbuf );
- hd->count = 0;
- hd->nblocks++;
- inlen -= 64;
- inbuf += 64;
- }
- _gcry_burn_stack (108+5*sizeof(void*));
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
-}
-
/****************
* Apply the rmd160 transform function on the buffer which must have
* a length 64 bytes. Do not use this function together with the
@@ -469,15 +435,15 @@ rmd160_final( void *context )
u32 t, msb, lsb;
byte *p;
- rmd160_write(hd, NULL, 0); /* flush */;
+ _gcry_md_block_write(hd, NULL, 0); /* flush */;
- t = hd->nblocks;
+ t = hd->bctx.nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
- if( (lsb += hd->count) < t )
+ if( (lsb += hd->bctx.count) < t )
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
@@ -485,33 +451,33 @@ rmd160_final( void *context )
msb <<= 3;
msb |= t >> 29;
- if( hd->count < 56 ) /* enough room */
+ if( hd->bctx.count < 56 ) /* enough room */
{
- hd->buf[hd->count++] = 0x80; /* pad */
- while( hd->count < 56 )
- hd->buf[hd->count++] = 0; /* pad */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ while( hd->bctx.count < 56 )
+ hd->bctx.buf[hd->bctx.count++] = 0; /* pad */
}
else /* need one extra block */
{
- hd->buf[hd->count++] = 0x80; /* pad character */
- while( hd->count < 64 )
- hd->buf[hd->count++] = 0;
- rmd160_write(hd, NULL, 0); /* flush */;
- memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ while( hd->bctx.count < 64 )
+ hd->bctx.buf[hd->bctx.count++] = 0;
+ _gcry_md_block_write(hd, NULL, 0); /* flush */;
+ memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
}
/* append the 64 bit count */
- hd->buf[56] = lsb ;
- hd->buf[57] = lsb >> 8;
- hd->buf[58] = lsb >> 16;
- hd->buf[59] = lsb >> 24;
- hd->buf[60] = msb ;
- hd->buf[61] = msb >> 8;
- hd->buf[62] = msb >> 16;
- hd->buf[63] = msb >> 24;
- transform( hd, hd->buf );
+ hd->bctx.buf[56] = lsb ;
+ hd->bctx.buf[57] = lsb >> 8;
+ hd->bctx.buf[58] = lsb >> 16;
+ hd->bctx.buf[59] = lsb >> 24;
+ hd->bctx.buf[60] = msb ;
+ 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*));
- p = hd->buf;
+ p = hd->bctx.buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *p++ = hd->h##a ; *p++ = hd->h##a >> 8; \
*p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
@@ -531,7 +497,7 @@ rmd160_read( void *context )
{
RMD160_CONTEXT *hd = context;
- return hd->buf;
+ return hd->bctx.buf;
}
@@ -546,9 +512,9 @@ _gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length )
RMD160_CONTEXT hd;
_gcry_rmd160_init ( &hd );
- rmd160_write ( &hd, buffer, length );
+ _gcry_md_block_write ( &hd, buffer, length );
rmd160_final ( &hd );
- memcpy ( outbuf, hd.buf, 20 );
+ memcpy ( outbuf, hd.bctx.buf, 20 );
}
static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
@@ -567,6 +533,6 @@ static gcry_md_oid_spec_t oid_spec_rmd160[] =
gcry_md_spec_t _gcry_digest_spec_rmd160 =
{
"RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
- _gcry_rmd160_init, rmd160_write, rmd160_final, rmd160_read,
+ _gcry_rmd160_init, _gcry_md_block_write, rmd160_final, rmd160_read,
sizeof (RMD160_CONTEXT)
};
diff --git a/cipher/sha1.c b/cipher/sha1.c
index 4b784ac..6777348 100644
--- a/cipher/sha1.c
+++ b/cipher/sha1.c
@@ -51,18 +51,15 @@
/* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % sizeof (u32))) */
/* #endif */
-#define TRANSFORM(x,d,n) transform ((x), (d), (n))
-
-
typedef struct
{
+ gcry_md_block_ctx_t bctx;
u32 h0,h1,h2,h3,h4;
- u32 nblocks;
- unsigned char buf[64];
- int count;
} SHA1_CONTEXT;
+static void
+transform (void *c, const unsigned char *data);
static void
sha1_init (void *context)
@@ -74,8 +71,11 @@ sha1_init (void *context)
hd->h2 = 0x98badcfe;
hd->h3 = 0x10325476;
hd->h4 = 0xc3d2e1f0;
- hd->nblocks = 0;
- hd->count = 0;
+ hd->bctx.nblocks = 0;
+ hd->bctx.count = 0;
+ hd->bctx.blocksize = 64;
+ hd->bctx.stack_burn = 88+4*sizeof(void*);
+ hd->bctx.bwrite = transform;
}
@@ -105,15 +105,13 @@ sha1_init (void *context)
* Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA.
*/
static void
-transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
+transform (void *ctx, const unsigned char *data)
{
+ SHA1_CONTEXT *hd = ctx;
register u32 a, b, c, d, e; /* Local copies of the chaining variables. */
register u32 tm; /* Helper. */
u32 x[16]; /* The array we work on. */
- /* Loop over all blocks. */
- for ( ;nblocks; nblocks--)
- {
#ifdef WORDS_BIGENDIAN
memcpy (x, data, 64);
data += 64;
@@ -226,53 +224,6 @@ transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
hd->h2 += c;
hd->h3 += d;
hd->h4 += e;
- }
-}
-
-
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-sha1_write( void *context, const void *inbuf_arg, size_t inlen)
-{
- const unsigned char *inbuf = inbuf_arg;
- SHA1_CONTEXT *hd = context;
- size_t nblocks;
-
- if (hd->count == 64) /* Flush the buffer. */
- {
- TRANSFORM( hd, hd->buf, 1 );
- _gcry_burn_stack (88+4*sizeof(void*));
- hd->count = 0;
- hd->nblocks++;
- }
- if (!inbuf)
- return;
-
- if (hd->count)
- {
- for (; inlen && hd->count < 64; inlen--)
- hd->buf[hd->count++] = *inbuf++;
- sha1_write (hd, NULL, 0);
- if (!inlen)
- return;
- }
-
- nblocks = inlen / 64;
- if (nblocks)
- {
- TRANSFORM (hd, inbuf, nblocks);
- hd->count = 0;
- hd->nblocks += nblocks;
- inlen -= nblocks * 64;
- inbuf += nblocks * 64;
- }
- _gcry_burn_stack (88+4*sizeof(void*));
-
- /* Save remaining bytes. */
- for (; inlen && hd->count < 64; inlen--)
- hd->buf[hd->count++] = *inbuf++;
}
@@ -291,15 +242,15 @@ sha1_final(void *context)
u32 t, msb, lsb;
unsigned char *p;
- sha1_write(hd, NULL, 0); /* flush */;
+ _gcry_md_block_write (hd, NULL, 0); /* flush */;
- t = hd->nblocks;
+ t = hd->bctx.nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
- if( (lsb += hd->count) < t )
+ if( (lsb += hd->bctx.count) < t )
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
@@ -307,33 +258,33 @@ sha1_final(void *context)
msb <<= 3;
msb |= t >> 29;
- if( hd->count < 56 ) /* enough room */
+ if( hd->bctx.count < 56 ) /* enough room */
{
- hd->buf[hd->count++] = 0x80; /* pad */
- while( hd->count < 56 )
- hd->buf[hd->count++] = 0; /* pad */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ while( hd->bctx.count < 56 )
+ hd->bctx.buf[hd->bctx.count++] = 0; /* pad */
}
else /* need one extra block */
{
- hd->buf[hd->count++] = 0x80; /* pad character */
- while( hd->count < 64 )
- hd->buf[hd->count++] = 0;
- sha1_write(hd, NULL, 0); /* flush */;
- memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ while( hd->bctx.count < 64 )
+ hd->bctx.buf[hd->bctx.count++] = 0;
+ _gcry_md_block_write(hd, NULL, 0); /* flush */;
+ memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
}
/* append the 64 bit count */
- hd->buf[56] = msb >> 24;
- hd->buf[57] = msb >> 16;
- hd->buf[58] = msb >> 8;
- hd->buf[59] = msb ;
- hd->buf[60] = lsb >> 24;
- hd->buf[61] = lsb >> 16;
- hd->buf[62] = lsb >> 8;
- hd->buf[63] = lsb ;
- TRANSFORM( hd, hd->buf, 1 );
+ hd->bctx.buf[56] = msb >> 24;
+ hd->bctx.buf[57] = msb >> 16;
+ hd->bctx.buf[58] = msb >> 8;
+ hd->bctx.buf[59] = msb ;
+ hd->bctx.buf[60] = lsb >> 24;
+ 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*));
- p = hd->buf;
+ p = hd->bctx.buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
#else /* little endian */
@@ -354,7 +305,7 @@ sha1_read( void *context )
{
SHA1_CONTEXT *hd = context;
- return hd->buf;
+ return hd->bctx.buf;
}
/****************
@@ -367,9 +318,9 @@ _gcry_sha1_hash_buffer (void *outbuf, const void *buffer, size_t length)
SHA1_CONTEXT hd;
sha1_init (&hd);
- sha1_write (&hd, buffer, length);
+ _gcry_md_block_write (&hd, buffer, length);
sha1_final (&hd);
- memcpy (outbuf, hd.buf, 20);
+ memcpy (outbuf, hd.bctx.buf, 20);
}
@@ -468,7 +419,7 @@ static gcry_md_oid_spec_t oid_spec_sha1[] =
gcry_md_spec_t _gcry_digest_spec_sha1 =
{
"SHA1", asn, DIM (asn), oid_spec_sha1, 20,
- sha1_init, sha1_write, sha1_final, sha1_read,
+ sha1_init, _gcry_md_block_write, sha1_final, sha1_read,
sizeof (SHA1_CONTEXT)
};
md_extra_spec_t _gcry_digest_extraspec_sha1 =
diff --git a/cipher/sha256.c b/cipher/sha256.c
index 309fa3b..1785699 100644
--- a/cipher/sha256.c
+++ b/cipher/sha256.c
@@ -46,12 +46,12 @@
#include "hash-common.h"
typedef struct {
+ gcry_md_block_ctx_t bctx;
u32 h0,h1,h2,h3,h4,h5,h6,h7;
- u32 nblocks;
- byte buf[64];
- int count;
} SHA256_CONTEXT;
+static void
+transform (void *c, const unsigned char *data);
static void
sha256_init (void *context)
@@ -67,8 +67,11 @@ sha256_init (void *context)
hd->h6 = 0x1f83d9ab;
hd->h7 = 0x5be0cd19;
- hd->nblocks = 0;
- hd->count = 0;
+ hd->bctx.nblocks = 0;
+ hd->bctx.count = 0;
+ hd->bctx.blocksize = 64;
+ hd->bctx.stack_burn = 74*4+32;
+ hd->bctx.bwrite = transform;
}
@@ -86,8 +89,11 @@ sha224_init (void *context)
hd->h6 = 0x64f98fa7;
hd->h7 = 0xbefa4fa4;
- hd->nblocks = 0;
- hd->count = 0;
+ hd->bctx.nblocks = 0;
+ hd->bctx.count = 0;
+ hd->bctx.blocksize = 64;
+ hd->bctx.stack_burn = 74*4+32;
+ hd->bctx.bwrite = transform;
}
@@ -140,8 +146,9 @@ Sum1 (u32 x)
static void
-transform (SHA256_CONTEXT *hd, const unsigned char *data)
+transform (void *ctx, const unsigned char *data)
{
+ SHA256_CONTEXT *hd = ctx;
static const u32 K[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
@@ -260,46 +267,6 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data)
#undef R
-/* Update the message digest with the contents of INBUF with length
- INLEN. */
-static void
-sha256_write (void *context, const void *inbuf_arg, size_t inlen)
-{
- const unsigned char *inbuf = inbuf_arg;
- SHA256_CONTEXT *hd = context;
-
- if (hd->count == 64)
- { /* flush the buffer */
- transform (hd, hd->buf);
- _gcry_burn_stack (74*4+32);
- hd->count = 0;
- hd->nblocks++;
- }
- if (!inbuf)
- return;
- if (hd->count)
- {
- for (; inlen && hd->count < 64; inlen--)
- hd->buf[hd->count++] = *inbuf++;
- sha256_write (hd, NULL, 0);
- if (!inlen)
- return;
- }
-
- while (inlen >= 64)
- {
- transform (hd, inbuf);
- hd->count = 0;
- hd->nblocks++;
- inlen -= 64;
- inbuf += 64;
- }
- _gcry_burn_stack (74*4+32);
- for (; inlen && hd->count < 64; inlen--)
- hd->buf[hd->count++] = *inbuf++;
-}
-
-
/*
The routine finally terminates the computation and returns the
digest. The handle is prepared for a new cycle, but adding bytes
@@ -312,15 +279,15 @@ sha256_final(void *context)
u32 t, msb, lsb;
byte *p;
- sha256_write (hd, NULL, 0); /* flush */;
+ _gcry_md_block_write (hd, NULL, 0); /* flush */;
- t = hd->nblocks;
+ t = hd->bctx.nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
- if ((lsb += hd->count) < t)
+ if ((lsb += hd->bctx.count) < t)
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
@@ -328,33 +295,33 @@ sha256_final(void *context)
msb <<= 3;
msb |= t >> 29;
- if (hd->count < 56)
+ if (hd->bctx.count < 56)
{ /* enough room */
- hd->buf[hd->count++] = 0x80; /* pad */
- while (hd->count < 56)
- hd->buf[hd->count++] = 0; /* pad */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+ while (hd->bctx.count < 56)
+ hd->bctx.buf[hd->bctx.count++] = 0; /* pad */
}
else
{ /* need one extra block */
- hd->buf[hd->count++] = 0x80; /* pad character */
- while (hd->count < 64)
- hd->buf[hd->count++] = 0;
- sha256_write (hd, NULL, 0); /* flush */;
- memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
+ hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+ while (hd->bctx.count < 64)
+ hd->bctx.buf[hd->bctx.count++] = 0;
+ _gcry_md_block_write (hd, NULL, 0); /* flush */;
+ memset (hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
}
/* append the 64 bit count */
- hd->buf[56] = msb >> 24;
- hd->buf[57] = msb >> 16;
- hd->buf[58] = msb >> 8;
- hd->buf[59] = msb;
- hd->buf[60] = lsb >> 24;
- hd->buf[61] = lsb >> 16;
- hd->buf[62] = lsb >> 8;
- hd->buf[63] = lsb;
- transform (hd, hd->buf);
+ hd->bctx.buf[56] = msb >> 24;
+ hd->bctx.buf[57] = msb >> 16;
+ hd->bctx.buf[58] = msb >> 8;
+ hd->bctx.buf[59] = msb;
+ hd->bctx.buf[60] = lsb >> 24;
+ 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);
- p = hd->buf;
+ p = hd->bctx.buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
#else /* little endian */
@@ -377,7 +344,7 @@ sha256_read (void *context)
{
SHA256_CONTEXT *hd = context;
- return hd->buf;
+ return hd->bctx.buf;
}
@@ -534,7 +501,7 @@ static gcry_md_oid_spec_t oid_spec_sha256[] =
gcry_md_spec_t _gcry_digest_spec_sha224 =
{
"SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
- sha224_init, sha256_write, sha256_final, sha256_read,
+ sha224_init, _gcry_md_block_write, sha256_final, sha256_read,
sizeof (SHA256_CONTEXT)
};
md_extra_spec_t _gcry_digest_extraspec_sha224 =
@@ -545,7 +512,7 @@ md_extra_spec_t _gcry_digest_extraspec_sha224 =
gcry_md_spec_t _gcry_digest_spec_sha256 =
{
"SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
- sha256_init, sha256_write, sha256_final, sha256_read,
+ sha256_init, _gcry_md_block_write, sha256_final, sha256_read,
sizeof (SHA256_CONTEXT)
};
md_extra_spec_t _gcry_digest_extraspec_sha256 =
diff --git a/cipher/tiger.c b/cipher/tiger.c
index d4ad514..49d3919 100644
--- a/cipher/tiger.c
+++ b/cipher/tiger.c
@@ -27,16 +27,15 @@
#include "g10lib.h"
#include "cipher.h"
+#include "hash-common.h"
/* We really need a 64 bit type for this code. */
#ifdef HAVE_U64_TYPEDEF
typedef struct
{
+ gcry_md_block_ctx_t bctx;
u64 a, b, c;
- byte buf[64];
- int count;
- u32 nblocks;
int variant; /* 0 = old code, 1 = fixed code, 2 - TIGER2. */
} TIGER_CONTEXT;
@@ -589,6 +588,9 @@ static u64 sbox4[256] = {
};
static void
+transform ( void *ctx, const unsigned char *data );
+
+static void
do_init (void *context, int variant)
{
TIGER_CONTEXT *hd = context;
@@ -596,8 +598,11 @@ do_init (void *context, int variant)
hd->a = 0x0123456789abcdefLL;
hd->b = 0xfedcba9876543210LL;
hd->c = 0xf096a5b4c3b2e187LL;
- hd->nblocks = 0;
- hd->count = 0;
+ 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;
}
@@ -687,8 +692,9 @@ key_schedule( u64 *x )
* Transform the message DATA which consists of 512 bytes (8 words)
*/
static void
-transform ( TIGER_CONTEXT *hd, const unsigned char *data )
+transform ( void *ctx, const unsigned char *data )
{
+ TIGER_CONTEXT *hd = ctx;
u64 a,b,c,aa,bb,cc;
u64 x[8];
#ifdef WORDS_BIGENDIAN
@@ -733,48 +739,6 @@ transform ( TIGER_CONTEXT *hd, const unsigned char *data )
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-tiger_write ( void *context, const void *inbuf_arg, size_t inlen)
-{
- const unsigned char *inbuf = inbuf_arg;
- TIGER_CONTEXT *hd = context;
-
- if( hd->count == 64 ) /* flush the buffer */
- {
- transform( hd, hd->buf );
- _gcry_burn_stack (21*8+11*sizeof(void*));
- hd->count = 0;
- hd->nblocks++;
- }
- if( !inbuf )
- return;
- if( hd->count )
- {
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
- tiger_write( hd, NULL, 0 );
- if( !inlen )
- return;
- }
-
- while( inlen >= 64 )
- {
- transform( hd, inbuf );
- hd->count = 0;
- hd->nblocks++;
- inlen -= 64;
- inbuf += 64;
- }
- _gcry_burn_stack (21*8+11*sizeof(void*));
- for( ; inlen && hd->count < 64; inlen-- )
- hd->buf[hd->count++] = *inbuf++;
-}
-
-
-
/* The routine terminates the computation
*/
static void
@@ -785,15 +749,15 @@ tiger_final( void *context )
byte *p;
byte pad = hd->variant == 2? 0x80 : 0x01;
- tiger_write(hd, NULL, 0); /* flush */;
+ _gcry_md_block_write(hd, NULL, 0); /* flush */;
- t = hd->nblocks;
+ t = hd->bctx.nblocks;
/* multiply by 64 to make a byte count */
lsb = t << 6;
msb = t >> 26;
/* add the count */
t = lsb;
- if( (lsb += hd->count) < t )
+ if( (lsb += hd->bctx.count) < t )
msb++;
/* multiply by 8 to make a bit count */
t = lsb;
@@ -801,33 +765,33 @@ tiger_final( void *context )
msb <<= 3;
msb |= t >> 29;
- if( hd->count < 56 ) /* enough room */
+ if( hd->bctx.count < 56 ) /* enough room */
{
- hd->buf[hd->count++] = pad;
- while( hd->count < 56 )
- hd->buf[hd->count++] = 0; /* pad */
+ hd->bctx.buf[hd->bctx.count++] = pad;
+ while( hd->bctx.count < 56 )
+ hd->bctx.buf[hd->bctx.count++] = 0; /* pad */
}
else /* need one extra block */
{
- hd->buf[hd->count++] = pad; /* pad character */
- while( hd->count < 64 )
- hd->buf[hd->count++] = 0;
- tiger_write(hd, NULL, 0); /* flush */;
- memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+ hd->bctx.buf[hd->bctx.count++] = pad; /* pad character */
+ while( hd->bctx.count < 64 )
+ hd->bctx.buf[hd->bctx.count++] = 0;
+ _gcry_md_block_write(hd, NULL, 0); /* flush */;
+ memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
}
/* append the 64 bit count */
- hd->buf[56] = lsb ;
- hd->buf[57] = lsb >> 8;
- hd->buf[58] = lsb >> 16;
- hd->buf[59] = lsb >> 24;
- hd->buf[60] = msb ;
- hd->buf[61] = msb >> 8;
- hd->buf[62] = msb >> 16;
- hd->buf[63] = msb >> 24;
- transform( hd, hd->buf );
+ hd->bctx.buf[56] = lsb ;
+ hd->bctx.buf[57] = lsb >> 8;
+ hd->bctx.buf[58] = lsb >> 16;
+ hd->bctx.buf[59] = lsb >> 24;
+ hd->bctx.buf[60] = msb ;
+ 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*));
- p = hd->buf;
+ p = hd->bctx.buf;
#ifdef WORDS_BIGENDIAN
#define X(a) do { *(u64*)p = hd->a ; p += 8; } while(0)
#else /* little endian */
@@ -861,7 +825,7 @@ tiger_read( void *context )
{
TIGER_CONTEXT *hd = context;
- return hd->buf;
+ return hd->bctx.buf;
}
@@ -872,7 +836,7 @@ tiger_read( void *context )
gcry_md_spec_t _gcry_digest_spec_tiger =
{
"TIGER192", NULL, 0, NULL, 24,
- tiger_init, tiger_write, tiger_final, tiger_read,
+ tiger_init, _gcry_md_block_write, tiger_final, tiger_read,
sizeof (TIGER_CONTEXT)
};
@@ -894,7 +858,7 @@ static gcry_md_oid_spec_t oid_spec_tiger1[] =
gcry_md_spec_t _gcry_digest_spec_tiger1 =
{
"TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24,
- tiger1_init, tiger_write, tiger_final, tiger_read,
+ tiger1_init, _gcry_md_block_write, tiger_final, tiger_read,
sizeof (TIGER_CONTEXT)
};
@@ -904,7 +868,7 @@ gcry_md_spec_t _gcry_digest_spec_tiger1 =
gcry_md_spec_t _gcry_digest_spec_tiger2 =
{
"TIGER2", NULL, 0, NULL, 24,
- tiger2_init, tiger_write, tiger_final, tiger_read,
+ tiger2_init, _gcry_md_block_write, tiger_final, tiger_read,
sizeof (TIGER_CONTEXT)
};
--
1.8.4.rc3
More information about the Gcrypt-devel
mailing list