]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
* gcm.c: Use the new union gcm_block for all gf operations.
authorNiels Möller <nisse@lysator.liu.se>
Tue, 8 Feb 2011 10:42:54 +0000 (11:42 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Tue, 8 Feb 2011 10:42:54 +0000 (11:42 +0100)
* 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
gcm.c
gcm.h

index a8ecc958eb387a0c324db160e150b7d19c8edec2..64825426c98485b4ec9d106c7f716a414ace768e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2011-02-08  Niels Möller  <nisse@lysator.liu.se>
+
+       * 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  <nisse@lysator.liu.se>
 
        * gcm.c (gcm_gf_shift_chunk) : Bug fix for little-endian 8-bit
diff --git a/gcm.c b/gcm.c
index 70598d44a7c90f7cb776f952eb4f3d782629e903..a44746510f662a67609c9be06d74651fb51a7ee3 100644 (file)
--- a/gcm.c
+++ b/gcm.c
 
 #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 c6d1c2c6b214d618d7484ed1dbe0a40bc5918870..aa17c34eb168c077979a921638ba46b6a1394f8d 100644 (file)
--- 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;
 };