]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
* gcm.c (gcm_hash_sizes): New function.
authorNiels Möller <nisse@lysator.liu.se>
Wed, 9 Feb 2011 21:57:05 +0000 (22:57 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Wed, 9 Feb 2011 21:57:05 +0000 (22:57 +0100)
(gcm_set_iv): Added support for IVs of arbitrary size. Needed
another argument, for the hash subkey.
(gcm_digest): Use gcm_hash_sizes.

Rev: nettle/gcm.c:1.13
Rev: nettle/gcm.h:1.8

gcm.c
gcm.h

diff --git a/gcm.c b/gcm.c
index 2fb0bd9bd06fafec0eb7dbf31fe69ccc81931c3b..b83bb00fd5217278cd30ddf718505f431a9b52a8 100644 (file)
--- a/gcm.c
+++ b/gcm.c
@@ -347,30 +347,6 @@ gcm_set_key(struct gcm_key *key,
 #endif
 }
 
-/*
- * @length: The size of the iv (fixed for now to GCM_NONCE_SIZE)
- * @iv: The iv
- */
-void
-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.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.b, ctx->iv.b, GCM_BLOCK_SIZE);
-  INC32 (ctx->ctr);
-
-  /* Reset the rest of the message-dependent state. */
-  memset(ctx->x.b, 0, sizeof(ctx->x));
-  ctx->auth_size = ctx->data_size = 0;
-}
-
 static void
 gcm_hash(const struct gcm_key *key, union gcm_block *x,
         unsigned length, const uint8_t *data)
@@ -388,6 +364,52 @@ gcm_hash(const struct gcm_key *key, union gcm_block *x,
     }
 }
 
+static void
+gcm_hash_sizes(const struct gcm_key *key, union gcm_block *x,
+                uint64_t auth_size, uint64_t data_size)
+{
+  uint8_t buffer[GCM_BLOCK_SIZE];
+
+  data_size *= 8;
+  auth_size *= 8;
+
+  WRITE_UINT64 (buffer, auth_size);
+  WRITE_UINT64 (buffer + 8, data_size);
+
+  gcm_hash(key, x, GCM_BLOCK_SIZE, buffer);
+}
+
+/*
+ * @length: The size of the iv (fixed for now to GCM_NONCE_SIZE)
+ * @iv: The iv
+ */
+void
+gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key,
+          unsigned length, const uint8_t *iv)
+{
+  if (length == GCM_IV_SIZE)
+    {
+      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;
+    }
+  else
+    {
+      memset(ctx->iv.b, 0, GCM_BLOCK_SIZE);
+      gcm_hash(key, &ctx->iv, length, iv);
+      gcm_hash_sizes(key, &ctx->iv, 0, length);
+    }
+
+  memcpy (ctx->ctr.b, ctx->iv.b, GCM_BLOCK_SIZE);
+  INC32 (ctx->ctr);
+
+  /* Reset the rest of the message-dependent state. */
+  memset(ctx->x.b, 0, sizeof(ctx->x));
+  ctx->auth_size = ctx->data_size = 0;
+}
+
 void
 gcm_auth(struct gcm_ctx *ctx, const struct gcm_key *key,
         unsigned length, const uint8_t *data)
@@ -472,13 +494,7 @@ gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
 
   assert (length <= GCM_BLOCK_SIZE);
 
-  ctx->data_size *= 8;
-  ctx->auth_size *= 8;
-
-  WRITE_UINT64 (buffer, ctx->auth_size);
-  WRITE_UINT64 (buffer + 8, ctx->data_size);
-
-  gcm_hash(key, &ctx->x, GCM_BLOCK_SIZE, buffer);
+  gcm_hash_sizes(key, &ctx->x, ctx->auth_size, ctx->data_size);
 
   f (cipher, GCM_BLOCK_SIZE, buffer, ctx->iv.b);
   memxor3 (digest, ctx->x.b, buffer, length);
diff --git a/gcm.h b/gcm.h
index c71ebaabbce49bf823b8594a02d51f4a4513abb6..4366bd86af3daced472cb1f9e14d6e46369ebc38 100644 (file)
--- a/gcm.h
+++ b/gcm.h
@@ -93,7 +93,8 @@ gcm_set_key(struct gcm_key *key,
            void *cipher, nettle_crypt_func *f);
 
 void
-gcm_set_iv(struct gcm_ctx *ctx, unsigned length, const uint8_t *iv);
+gcm_set_iv(struct gcm_ctx *ctx, const struct gcm_key *key,
+          unsigned length, const uint8_t *iv);
 
 void
 gcm_auth(struct gcm_ctx *ctx, const struct gcm_key *key,