summaryrefslogtreecommitdiff
path: root/cipher/whirlpool.c
diff options
context:
space:
mode:
Diffstat (limited to 'cipher/whirlpool.c')
-rw-r--r--cipher/whirlpool.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/cipher/whirlpool.c b/cipher/whirlpool.c
index 954640ac..1ee89162 100644
--- a/cipher/whirlpool.c
+++ b/cipher/whirlpool.c
@@ -54,7 +54,7 @@ typedef struct {
whirlpool_block_t hash_state;
unsigned char buffer[BLOCK_SIZE];
size_t count;
- unsigned char length[32];
+ u64 nblocks;
} whirlpool_context_t;
@@ -1274,11 +1274,6 @@ whirlpool_add (whirlpool_context_t *context,
const void *buffer_arg, size_t buffer_n)
{
const unsigned char *buffer = buffer_arg;
- u64 buffer_size;
- unsigned int carry;
- unsigned int i;
-
- buffer_size = buffer_n;
if (context->count == BLOCK_SIZE)
{
@@ -1286,6 +1281,7 @@ whirlpool_add (whirlpool_context_t *context,
whirlpool_transform (context, context->buffer);
/*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
context->count = 0;
+ context->nblocks++;
}
if (! buffer)
return; /* Nothing to add. */
@@ -1298,6 +1294,9 @@ whirlpool_add (whirlpool_context_t *context,
buffer_n--;
}
whirlpool_add (context, NULL, 0);
+ /* Can return early now that bit counter calculation is done in final. */
+ if (!buffer_n)
+ return;
}
/*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
@@ -1305,6 +1304,7 @@ whirlpool_add (whirlpool_context_t *context,
{
whirlpool_transform (context, buffer);
context->count = 0;
+ context->nblocks++;
buffer_n -= BLOCK_SIZE;
buffer += BLOCK_SIZE;
}
@@ -1313,29 +1313,17 @@ whirlpool_add (whirlpool_context_t *context,
context->buffer[context->count++] = *buffer++;
buffer_n--;
}
-
- /* Update bit counter. */
- carry = 0;
- buffer_size <<= 3;
- for (i = 1; i <= 32; i++)
- {
- if (! (buffer_size || carry))
- break;
-
- carry += context->length[32 - i] + (buffer_size & 0xFF);
- context->length[32 - i] = carry;
- buffer_size >>= 8;
- carry >>= 8;
- }
- gcry_assert (! (buffer_size || carry));
}
static void
whirlpool_write (void *ctx, const void *buffer, size_t buffer_n)
{
whirlpool_context_t *context = ctx;
+ u64 old_nblocks = context->nblocks;
whirlpool_add (context, buffer, buffer_n);
+
+ gcry_assert (old_nblocks <= context->nblocks);
}
static void
@@ -1343,9 +1331,25 @@ whirlpool_final (void *ctx)
{
whirlpool_context_t *context = ctx;
unsigned int i;
+ u64 t, lsb, msb;
+ unsigned char *length;
+
+ t = context->nblocks;
+ /* multiply by 64 to make a byte count */
+ lsb = t << 6;
+ msb = t >> 58;
+ /* add the count */
+ t = lsb;
+ if ((lsb += context->count) < t)
+ msb++;
+ /* multiply by 8 to make a bit count */
+ t = lsb;
+ lsb <<= 3;
+ msb <<= 3;
+ msb |= t >> 61;
/* Flush. */
- whirlpool_add (context, NULL, 0);
+ whirlpool_write (context, NULL, 0);
/* Pad. */
context->buffer[context->count++] = 0x80;
@@ -1355,15 +1359,19 @@ whirlpool_final (void *ctx)
/* An extra block is necessary. */
while (context->count < 64)
context->buffer[context->count++] = 0;
- whirlpool_add (context, NULL, 0);
+ whirlpool_write (context, NULL, 0);
}
while (context->count < 32)
context->buffer[context->count++] = 0;
/* Add length of message. */
- memcpy (context->buffer + context->count, context->length, 32);
+ length = context->buffer + context->count;
+ buf_put_be64(&length[0 * 8], 0);
+ buf_put_be64(&length[1 * 8], 0);
+ buf_put_be64(&length[2 * 8], msb);
+ buf_put_be64(&length[3 * 8], lsb);
context->count += 32;
- whirlpool_add (context, NULL, 0);
+ whirlpool_write (context, NULL, 0);
block_to_buffer (context->buffer, context->hash_state, i);
}