From 6b34ff5a164ca4cb0524e4e6e0718726d8fa69ee Mon Sep 17 00:00:00 2001 From: =?utf8?q?Niels=20M=C3=B6ller?= Date: Tue, 8 Feb 2011 11:42:54 +0100 Subject: [PATCH] * gcm.c: Use the new union gcm_block for all gf operations. * gcm.h (union gcm_block): New union, used to enforce alignment. Rev: nettle/ChangeLog:1.138 Rev: nettle/gcm.c:1.9 Rev: nettle/gcm.h:1.5 --- ChangeLog | 6 +++ gcm.c | 125 ++++++++++++++++++++++++++---------------------------- gcm.h | 17 +++++--- 3 files changed, 77 insertions(+), 71 deletions(-) diff --git a/ChangeLog b/ChangeLog index a8ecc958..64825426 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2011-02-08 Niels Möller + + * gcm.c: Use the new union gcm_block for all gf operations. + + * gcm.h (union gcm_block): New union, used to enforce alignment. + 2011-02-07 Niels Möller * gcm.c (gcm_gf_shift_chunk) : Bug fix for little-endian 8-bit diff --git a/gcm.c b/gcm.c index 70598d44..a4474651 100644 --- a/gcm.c +++ b/gcm.c @@ -47,28 +47,23 @@ #define GHASH_POLYNOMIAL 0xE1 -/* Like memxor, but for fixed length and aligned operands. */ static void -gcm_gf_add (uint8_t *r, const uint8_t *x, const uint8_t *y) +gcm_gf_add (union gcm_block *r, const union gcm_block *x, const union gcm_block *y) { - unsigned long *rw = (unsigned long *) r; - unsigned long *xw = (unsigned long *) x; - unsigned long *yw = (unsigned long *) y; - - rw[0] = xw[0] ^ yw[0]; - rw[1] = xw[1] ^ yw[1]; + r->w[0] = x->w[0] ^ y->w[0]; + r->w[1] = x->w[1] ^ y->w[1]; #if SIZEOF_LONG == 4 - rw[2] = xw[2] ^ yw[2]; - rw[3] = xw[3] ^ yw[3]; + r->w[2] = x->w[2] ^ y->w[2]; + r->w[3] = x->w[3] ^ y->w[3]; #endif } /* Multiplication by 010...0; a big-endian shift right. If the bit shifted out is one, the defining polynomial is added to cancel it - out. The argument must be properly aligned for word accesses. */ + out. */ static void -gcm_gf_shift (uint8_t *x) +gcm_gf_shift (union gcm_block *x) { - unsigned long *w = (unsigned long *) x; + unsigned long *w = x->w; long mask; /* Shift uses big-endian representation. */ #if WORDS_BIGENDIAN @@ -113,14 +108,14 @@ gcm_gf_shift (uint8_t *x) specification. y may be shorter than a full block, missing bytes are assumed zero. */ static void -gcm_gf_mul (uint8_t *r, const uint8_t *x, unsigned yn, const uint8_t *y) +gcm_gf_mul (union gcm_block *r, const union gcm_block *x, unsigned yn, const uint8_t *y) { - uint8_t V[GCM_BLOCK_SIZE]; - uint8_t Z[GCM_BLOCK_SIZE]; + union gcm_block V; + union gcm_block Z; unsigned i; - memcpy(V, x, sizeof(V)); - memset(Z, 0, sizeof(Z)); + memcpy(V.b, x, sizeof(V)); + memset(Z.b, 0, sizeof(Z)); for (i = 0; i < yn; i++) { @@ -129,12 +124,12 @@ gcm_gf_mul (uint8_t *r, const uint8_t *x, unsigned yn, const uint8_t *y) for (j = 0; j < 8; j++, b <<= 1) { if (b & 0x80) - gcm_gf_add(Z, Z, V); + gcm_gf_add(&Z, &Z, &V); - gcm_gf_shift(V); + gcm_gf_shift(&V); } } - memcpy (r, Z, sizeof(Z)); + memcpy (r->b, Z.b, sizeof(Z)); } #if GCM_TABLE_BITS @@ -195,9 +190,9 @@ shift_table[0x100] = { #if GCM_TABLE_BITS == 4 static void -gcm_gf_shift_chunk(uint8_t *x) +gcm_gf_shift_chunk(union gcm_block *x) { - unsigned long *w = (unsigned long *) x; + unsigned long *w = x->w; unsigned long reduce; /* Shift uses big-endian representation. */ @@ -239,31 +234,30 @@ gcm_gf_shift_chunk(uint8_t *x) #endif /* ! WORDS_BIGENDIAN */ } -/* FIXME: Table should be const. */ static void -gcm_gf_mul_chunk (uint8_t *x, const uint8_t *h, uint8_t table[16][16]) +gcm_gf_mul_chunk (union gcm_block *x, const union gcm_block *h, const union gcm_block *table) { - uint8_t Z[GCM_BLOCK_SIZE]; + union gcm_block Z; unsigned i; - memset(Z, 0, sizeof(Z)); + memset(Z.b, 0, sizeof(Z)); for (i = GCM_BLOCK_SIZE; i-- > 0;) { - uint8_t b = x[i]; + uint8_t b = x->b[i]; - gcm_gf_shift_chunk(Z); - gcm_gf_add(Z, Z, table[b & 0xf]); - gcm_gf_shift_chunk(Z); - gcm_gf_add(Z, Z, table[b >> 4]); + gcm_gf_shift_chunk(&Z); + gcm_gf_add(&Z, &Z, &table[b & 0xf]); + gcm_gf_shift_chunk(&Z); + gcm_gf_add(&Z, &Z, &table[b >> 4]); } - memcpy (x, Z, sizeof(Z)); + memcpy (x->b, Z.b, sizeof(Z)); } #elif GCM_TABLE_BITS == 8 static void -gcm_gf_shift_chunk(uint8_t *x) +gcm_gf_shift_chunk(union gcm_block *x) { - unsigned long *w = (unsigned long *) x; + unsigned long *w = x->w; unsigned long reduce; /* Shift uses big-endian representation. */ @@ -298,22 +292,21 @@ gcm_gf_shift_chunk(uint8_t *x) #endif /* ! WORDS_BIGENDIAN */ } -/* FIXME: Table should be const. */ static void -gcm_gf_mul_chunk (uint8_t *x, const uint8_t *h, uint8_t table[16][16]) +gcm_gf_mul_chunk (union gcm_block *x, const union gcm_block *h, const union gcm_block *table) { - uint8_t Z[GCM_BLOCK_SIZE]; + union gcm_block Z; unsigned i; - memcpy(Z, table[x[GCM_BLOCK_SIZE-1]], GCM_BLOCK_SIZE); + memcpy(Z.b, table[x->b[GCM_BLOCK_SIZE-1]].b, GCM_BLOCK_SIZE); for (i = GCM_BLOCK_SIZE-2; i > 0; i--) { - gcm_gf_shift_chunk(Z); - gcm_gf_add(Z, Z, table[x[i]]); + gcm_gf_shift_chunk(&Z); + gcm_gf_add(&Z, &Z, &table[x->b[i]]); } - gcm_gf_shift_chunk(Z); - gcm_gf_add(x, Z, table[x[0]]); + gcm_gf_shift_chunk(&Z); + gcm_gf_add(x, &Z, &table[x->b[0]]); } #else /* GCM_TABLE_BITS != 8 */ @@ -322,7 +315,7 @@ gcm_gf_mul_chunk (uint8_t *x, const uint8_t *h, uint8_t table[16][16]) #endif /* GCM_TABLE_BITS */ /* Increment the rightmost 32 bits. */ -#define INC32(block) INCREMENT(4, (block) + GCM_BLOCK_SIZE - 4) +#define INC32(block) INCREMENT(4, (block.b) + GCM_BLOCK_SIZE - 4) /* Initialization of GCM. * @ctx: The context of GCM @@ -333,8 +326,8 @@ void gcm_set_key(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func f) { - memset (ctx->h, 0, sizeof (ctx->h)); - f (cipher, GCM_BLOCK_SIZE, ctx->h, ctx->h); /* H */ + memset (ctx->h.b, 0, sizeof (ctx->h)); + f (cipher, GCM_BLOCK_SIZE, ctx->h.b, ctx->h.b); /* H */ #if GCM_TABLE_BITS #if GCM_TABLE_BITS == 4 { @@ -342,7 +335,7 @@ gcm_set_key(struct gcm_ctx *ctx, for (i = 0; i < 0x10; i++) { uint8_t x = i << 4; - gcm_gf_mul(ctx->h_table[i], ctx->h, 1, &x); + gcm_gf_mul(&ctx->h_table[i], &ctx->h, 1, &x); } } #elif GCM_TABLE_BITS == 8 @@ -351,7 +344,7 @@ gcm_set_key(struct gcm_ctx *ctx, for (i = 0; i < 0x100; i++) { uint8_t x = i; - gcm_gf_mul(ctx->h_table[i], ctx->h, 1, &x); + gcm_gf_mul(&ctx->h_table[i], &ctx->h, 1, &x); } } #else @@ -370,17 +363,17 @@ gcm_set_iv(struct gcm_ctx *ctx, unsigned length, const uint8_t* iv) /* FIXME: remove the iv size limitation */ assert (length == GCM_IV_SIZE); - memcpy (ctx->iv, iv, GCM_BLOCK_SIZE - 4); - ctx->iv[GCM_BLOCK_SIZE - 4] = 0; - ctx->iv[GCM_BLOCK_SIZE - 3] = 0; - ctx->iv[GCM_BLOCK_SIZE - 2] = 0; - ctx->iv[GCM_BLOCK_SIZE - 1] = 1; + memcpy (ctx->iv.b, iv, GCM_BLOCK_SIZE - 4); + ctx->iv.b[GCM_BLOCK_SIZE - 4] = 0; + ctx->iv.b[GCM_BLOCK_SIZE - 3] = 0; + ctx->iv.b[GCM_BLOCK_SIZE - 2] = 0; + ctx->iv.b[GCM_BLOCK_SIZE - 1] = 1; - memcpy (ctx->ctr, ctx->iv, GCM_BLOCK_SIZE); + memcpy (ctx->ctr.b, ctx->iv.b, GCM_BLOCK_SIZE); INC32 (ctx->ctr); /* Reset the rest of the message-dependent state. */ - memset(ctx->x, 0, sizeof(ctx->x)); + memset(ctx->x.b, 0, sizeof(ctx->x)); ctx->auth_size = ctx->data_size = 0; } @@ -390,20 +383,20 @@ gcm_hash(struct gcm_ctx *ctx, unsigned length, const uint8_t *data) for (; length >= GCM_BLOCK_SIZE; length -= GCM_BLOCK_SIZE, data += GCM_BLOCK_SIZE) { - memxor (ctx->x, data, GCM_BLOCK_SIZE); + memxor (ctx->x.b, data, GCM_BLOCK_SIZE); #if GCM_TABLE_BITS - gcm_gf_mul_chunk (ctx->x, ctx->h, ctx->h_table); + gcm_gf_mul_chunk (&ctx->x, &ctx->h, ctx->h_table); #else - gcm_gf_mul (ctx->x, ctx->x, GCM_BLOCK_SIZE, ctx->h); + gcm_gf_mul (&ctx->x, &ctx->x, GCM_BLOCK_SIZE, ctx->h.b); #endif } if (length > 0) { - memxor (ctx->x, data, length); + memxor (ctx->x.b, data, length); #if GCM_TABLE_BITS - gcm_gf_mul_chunk (ctx->x, ctx->h, ctx->h_table); + gcm_gf_mul_chunk (&ctx->x, &ctx->h, ctx->h_table); #else - gcm_gf_mul (ctx->x, ctx->x, GCM_BLOCK_SIZE, ctx->h); + gcm_gf_mul (&ctx->x, &ctx->x, GCM_BLOCK_SIZE, ctx->h.b); #endif } } @@ -433,7 +426,7 @@ gcm_crypt(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f, (length -= GCM_BLOCK_SIZE, src += GCM_BLOCK_SIZE, dst += GCM_BLOCK_SIZE)) { - f (cipher, GCM_BLOCK_SIZE, dst, ctx->ctr); + f (cipher, GCM_BLOCK_SIZE, dst, ctx->ctr.b); memxor (dst, src, GCM_BLOCK_SIZE); INC32 (ctx->ctr); } @@ -444,7 +437,7 @@ gcm_crypt(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f, (length -= GCM_BLOCK_SIZE, src += GCM_BLOCK_SIZE, dst += GCM_BLOCK_SIZE)) { - f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr); + f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr.b); memxor3 (dst, src, buffer, GCM_BLOCK_SIZE); INC32 (ctx->ctr); } @@ -452,7 +445,7 @@ gcm_crypt(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f, if (length > 0) { /* A final partial block */ - f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr); + f (cipher, GCM_BLOCK_SIZE, buffer, ctx->ctr.b); memxor3 (dst, src, buffer, length); INC32 (ctx->ctr); } @@ -499,8 +492,8 @@ gcm_digest(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f, gcm_hash(ctx, GCM_BLOCK_SIZE, buffer); - f (cipher, GCM_BLOCK_SIZE, buffer, ctx->iv); - memxor3 (digest, ctx->x, buffer, length); + f (cipher, GCM_BLOCK_SIZE, buffer, ctx->iv.b); + memxor3 (digest, ctx->x.b, buffer, length); return; } diff --git a/gcm.h b/gcm.h index c6d1c2c6..aa17c34e 100644 --- a/gcm.h +++ b/gcm.h @@ -53,20 +53,27 @@ extern "C" { #define GCM_TABLE_BITS 4 +/* To make sure that we have proper alignment. */ +union gcm_block +{ + uint8_t b[GCM_BLOCK_SIZE]; + unsigned long w[1]; +}; + struct gcm_ctx { /* Key-dependent state. */ /* Hashing subkey */ - uint8_t h[GCM_BLOCK_SIZE]; + union gcm_block h; #if GCM_TABLE_BITS - uint8_t h_table[1 << GCM_TABLE_BITS][GCM_BLOCK_SIZE]; + union gcm_block h_table[1 << GCM_TABLE_BITS]; #endif /* Per-message state, depending on the iv */ /* Original counter block */ - uint8_t iv[GCM_BLOCK_SIZE]; + union gcm_block iv; /* Updated for each block. */ - uint8_t ctr[GCM_BLOCK_SIZE]; + union gcm_block ctr; /* Hashing state */ - uint8_t x[GCM_BLOCK_SIZE]; + union gcm_block x; uint64_t auth_size; uint64_t data_size; }; -- 2.47.3