summaryrefslogtreecommitdiff
path: root/cipher/sha512.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2013-09-21 13:54:38 +0300
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2013-09-21 13:54:38 +0300
commitcce7449efe471b076c5a97929ac8907162011394 (patch)
tree094b7a1184a139576f4443f0e1c373064a295aa2 /cipher/sha512.c
parent3e5cfa20acfeccb9df2c3fae2730344b40b36104 (diff)
downloadlibgcrypt-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.c179
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 =