diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-09-21 13:54:38 +0300 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-09-21 13:54:38 +0300 |
commit | cce7449efe471b076c5a97929ac8907162011394 (patch) | |
tree | 094b7a1184a139576f4443f0e1c373064a295aa2 /cipher/sha512.c | |
parent | 3e5cfa20acfeccb9df2c3fae2730344b40b36104 (diff) | |
download | libgcrypt-cce7449efe471b076c5a97929ac8907162011394.tar.gz |
Make SHA-512 use the new _gcry_md_block_write helper
* cipher/hash-common.c (_gcry_md_block_write): Check that hd->buf is
large enough.
* cipher/hash-common.h (MD_BLOCK_MAX_BLOCKSIZE, MD_NBLOCKS_TYPE): New
macros.
(gcry_md_block_ctx_t): Use above macros for 'nblocks' and 'buf'.
* cipher/sha512.c (SHA512_STATE): New struct.
(SHA512_CONTEXT): Add 'bctx' and 'state'.
(sha512_init, sha384_init): Initialize 'bctx'.
(__transform, _gcry_sha512_transform_armv7_neon): Use SHA512_STATE for
'hd'.
(transform): For now, do not return burn stack.
(sha512_write): Remove.
(sha512_final): Use _gcry_md_block_write and bctx.
(_gcry_digest_spec_sha512, _gcry_digest_spec_sha384): Use
_gcry_md_block_write.
--
Patch changes 'nblocks' counter to 64-bits when SHA-512 is enabled. This does
not cause problems with other algorithms; they are already casting 'nblocks'
to u32 variable in their finalization functions. Also move 'buf' member to
head of 'gcry_md_block_ctx_t' to ensure proper alignment; this is because some
algorithms cast buffer pointer to (u64*) in final endian conversion.
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'cipher/sha512.c')
-rw-r--r-- | cipher/sha512.c | 179 |
1 files changed, 79 insertions, 100 deletions
diff --git a/cipher/sha512.c b/cipher/sha512.c index fee3e713..ed63ae61 100644 --- a/cipher/sha512.c +++ b/cipher/sha512.c @@ -67,18 +67,25 @@ typedef struct { u64 h0, h1, h2, h3, h4, h5, h6, h7; - u64 nblocks; - byte buf[128]; - int count; +} SHA512_STATE; + +typedef struct +{ + gcry_md_block_ctx_t bctx; + SHA512_STATE state; #ifdef USE_ARM_NEON_ASM int use_neon; #endif } SHA512_CONTEXT; static void +transform (void *context, const unsigned char *data); + +static void sha512_init (void *context) { - SHA512_CONTEXT *hd = context; + SHA512_CONTEXT *ctx = context; + SHA512_STATE *hd = &ctx->state; hd->h0 = U64_C(0x6a09e667f3bcc908); hd->h1 = U64_C(0xbb67ae8584caa73b); @@ -89,17 +96,22 @@ sha512_init (void *context) hd->h6 = U64_C(0x1f83d9abfb41bd6b); hd->h7 = U64_C(0x5be0cd19137e2179); - hd->nblocks = 0; - hd->count = 0; + ctx->bctx.nblocks = 0; + ctx->bctx.count = 0; + ctx->bctx.blocksize = 128; + ctx->bctx.bwrite = transform; + ctx->bctx.stack_burn = 256; + #ifdef USE_ARM_NEON_ASM - hd->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0; + ctx->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0; #endif } static void sha384_init (void *context) { - SHA512_CONTEXT *hd = context; + SHA512_CONTEXT *ctx = context; + SHA512_STATE *hd = &ctx->state; hd->h0 = U64_C(0xcbbb9d5dc1059ed8); hd->h1 = U64_C(0x629a292a367cd507); @@ -110,10 +122,14 @@ sha384_init (void *context) hd->h6 = U64_C(0xdb0c2e0d64f98fa7); hd->h7 = U64_C(0x47b5481dbefa4fa4); - hd->nblocks = 0; - hd->count = 0; + ctx->bctx.nblocks = 0; + ctx->bctx.count = 0; + ctx->bctx.blocksize = 128; + ctx->bctx.bwrite = transform; + ctx->bctx.stack_burn = 256; + #ifdef USE_ARM_NEON_ASM - hd->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0; + ctx->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0; #endif } @@ -196,7 +212,7 @@ static const u64 k[] = * Transform the message W which consists of 16 64-bit-words */ static void -__transform (SHA512_CONTEXT *hd, const unsigned char *data) +__transform (SHA512_STATE *hd, const unsigned char *data) { u64 a, b, c, d, e, f, g, h; u64 w[16]; @@ -477,71 +493,33 @@ __transform (SHA512_CONTEXT *hd, const unsigned char *data) #ifdef USE_ARM_NEON_ASM -void _gcry_sha512_transform_armv7_neon (SHA512_CONTEXT *hd, +void _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd, const unsigned char *data, const u64 k[]); #endif -static unsigned int -transform (SHA512_CONTEXT *hd, const unsigned char *data) +static void +transform (void *context, const unsigned char *data) { + SHA512_CONTEXT *ctx = context; + #ifdef USE_ARM_NEON_ASM if (hd->use_neon) { - _gcry_sha512_transform_armv7_neon(hd, data, k); + _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); + return /*(sizeof(void *) * 3)*/; } #endif - __transform (hd, data); + __transform (&ctx->state, data); + /* TODO: return burn stack to md_block_write */ /* return stack burn depth */ - return 256; -} - - -/* Update the message digest with the contents - * of INBUF with length INLEN. - */ -static void -sha512_write (void *context, const void *inbuf_arg, size_t inlen) -{ - const unsigned char *inbuf = inbuf_arg; - SHA512_CONTEXT *hd = context; - unsigned int stack_burn_depth = 0; - - if (hd->count == 128) - { /* flush the buffer */ - stack_burn_depth = transform (hd, hd->buf); - _gcry_burn_stack (stack_burn_depth); - hd->count = 0; - hd->nblocks++; - } - if (!inbuf) - return; - if (hd->count) - { - for (; inlen && hd->count < 128; inlen--) - hd->buf[hd->count++] = *inbuf++; - sha512_write (context, NULL, 0); - if (!inlen) - return; - } - - while (inlen >= 128) - { - stack_burn_depth = transform (hd, inbuf); - hd->count = 0; - hd->nblocks++; - inlen -= 128; - inbuf += 128; - } - _gcry_burn_stack (stack_burn_depth); - for (; inlen && hd->count < 128; inlen--) - hd->buf[hd->count++] = *inbuf++; + return /*256*/; } @@ -561,15 +539,15 @@ sha512_final (void *context) u64 t, msb, lsb; byte *p; - sha512_write (context, NULL, 0); /* flush */ ; + _gcry_md_block_write (context, NULL, 0); /* flush */ ; - t = hd->nblocks; + t = hd->bctx.nblocks; /* multiply by 128 to make a byte count */ lsb = t << 7; msb = t >> 57; /* 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; @@ -577,49 +555,50 @@ sha512_final (void *context) msb <<= 3; msb |= t >> 61; - if (hd->count < 112) + if (hd->bctx.count < 112) { /* enough room */ - hd->buf[hd->count++] = 0x80; /* pad */ - while (hd->count < 112) - hd->buf[hd->count++] = 0; /* pad */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */ + while (hd->bctx.count < 112) + hd->bctx.buf[hd->bctx.count++] = 0; /* pad */ } else { /* need one extra block */ - hd->buf[hd->count++] = 0x80; /* pad character */ - while (hd->count < 128) - hd->buf[hd->count++] = 0; - sha512_write (context, NULL, 0); /* flush */ ; - memset (hd->buf, 0, 112); /* fill next block with zeroes */ + hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */ + while (hd->bctx.count < 128) + hd->bctx.buf[hd->bctx.count++] = 0; + _gcry_md_block_write (context, NULL, 0); /* flush */ ; + memset (hd->bctx.buf, 0, 112); /* fill next block with zeroes */ } /* append the 128 bit count */ - hd->buf[112] = msb >> 56; - hd->buf[113] = msb >> 48; - hd->buf[114] = msb >> 40; - hd->buf[115] = msb >> 32; - hd->buf[116] = msb >> 24; - hd->buf[117] = msb >> 16; - hd->buf[118] = msb >> 8; - hd->buf[119] = msb; - - hd->buf[120] = lsb >> 56; - hd->buf[121] = lsb >> 48; - hd->buf[122] = lsb >> 40; - hd->buf[123] = lsb >> 32; - hd->buf[124] = lsb >> 24; - hd->buf[125] = lsb >> 16; - hd->buf[126] = lsb >> 8; - hd->buf[127] = lsb; - stack_burn_depth = transform (hd, hd->buf); + hd->bctx.buf[112] = msb >> 56; + hd->bctx.buf[113] = msb >> 48; + hd->bctx.buf[114] = msb >> 40; + hd->bctx.buf[115] = msb >> 32; + hd->bctx.buf[116] = msb >> 24; + hd->bctx.buf[117] = msb >> 16; + hd->bctx.buf[118] = msb >> 8; + hd->bctx.buf[119] = msb; + + hd->bctx.buf[120] = lsb >> 56; + hd->bctx.buf[121] = lsb >> 48; + hd->bctx.buf[122] = lsb >> 40; + hd->bctx.buf[123] = lsb >> 32; + hd->bctx.buf[124] = lsb >> 24; + 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; _gcry_burn_stack (stack_burn_depth); - p = hd->buf; + p = hd->bctx.buf; #ifdef WORDS_BIGENDIAN -#define X(a) do { *(u64*)p = hd->h##a ; p += 8; } while (0) +#define X(a) do { *(u64*)p = hd->state.h##a ; p += 8; } while (0) #else /* little endian */ -#define X(a) do { *p++ = hd->h##a >> 56; *p++ = hd->h##a >> 48; \ - *p++ = hd->h##a >> 40; *p++ = hd->h##a >> 32; \ - *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16; \ - *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while (0) +#define X(a) do { *p++ = hd->state.h##a >> 56; *p++ = hd->state.h##a >> 48; \ + *p++ = hd->state.h##a >> 40; *p++ = hd->state.h##a >> 32; \ + *p++ = hd->state.h##a >> 24; *p++ = hd->state.h##a >> 16; \ + *p++ = hd->state.h##a >> 8; *p++ = hd->state.h##a; } while(0) #endif X (0); X (1); @@ -638,7 +617,7 @@ static byte * sha512_read (void *context) { SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context; - return hd->buf; + return hd->bctx.buf; } @@ -797,7 +776,7 @@ static gcry_md_oid_spec_t oid_spec_sha512[] = gcry_md_spec_t _gcry_digest_spec_sha512 = { "SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64, - sha512_init, sha512_write, sha512_final, sha512_read, + sha512_init, _gcry_md_block_write, sha512_final, sha512_read, sizeof (SHA512_CONTEXT), }; md_extra_spec_t _gcry_digest_extraspec_sha512 = @@ -825,7 +804,7 @@ static gcry_md_oid_spec_t oid_spec_sha384[] = gcry_md_spec_t _gcry_digest_spec_sha384 = { "SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48, - sha384_init, sha512_write, sha512_final, sha512_read, + sha384_init, _gcry_md_block_write, sha512_final, sha512_read, sizeof (SHA512_CONTEXT), }; md_extra_spec_t _gcry_digest_extraspec_sha384 = |