Commit 9924966a authored by Niels Möller's avatar Niels Möller
Browse files

* gcm.c (gcm_hash_sizes): New function.

(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
parent 1fb0a70b
...@@ -347,21 +347,60 @@ gcm_set_key(struct gcm_key *key, ...@@ -347,21 +347,60 @@ gcm_set_key(struct gcm_key *key,
#endif #endif
} }
static void
gcm_hash(const struct gcm_key *key, union gcm_block *x,
unsigned length, const uint8_t *data)
{
for (; length >= GCM_BLOCK_SIZE;
length -= GCM_BLOCK_SIZE, data += GCM_BLOCK_SIZE)
{
memxor (x->b, data, GCM_BLOCK_SIZE);
gcm_gf_mul (x, key->h);
}
if (length > 0)
{
memxor (x->b, data, length);
gcm_gf_mul (x, key->h);
}
}
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) * @length: The size of the iv (fixed for now to GCM_NONCE_SIZE)
* @iv: The iv * @iv: The iv
*/ */
void 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)
{ {
/* FIXME: remove the iv size limitation */ if (length == GCM_IV_SIZE)
assert (length == GCM_IV_SIZE); {
memcpy (ctx->iv.b, iv, GCM_BLOCK_SIZE - 4); memcpy (ctx->iv.b, iv, GCM_BLOCK_SIZE - 4);
ctx->iv.b[GCM_BLOCK_SIZE - 4] = 0; ctx->iv.b[GCM_BLOCK_SIZE - 4] = 0;
ctx->iv.b[GCM_BLOCK_SIZE - 3] = 0; ctx->iv.b[GCM_BLOCK_SIZE - 3] = 0;
ctx->iv.b[GCM_BLOCK_SIZE - 2] = 0; ctx->iv.b[GCM_BLOCK_SIZE - 2] = 0;
ctx->iv.b[GCM_BLOCK_SIZE - 1] = 1; 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); memcpy (ctx->ctr.b, ctx->iv.b, GCM_BLOCK_SIZE);
INC32 (ctx->ctr); INC32 (ctx->ctr);
...@@ -371,23 +410,6 @@ gcm_set_iv(struct gcm_ctx *ctx, unsigned length, const uint8_t* iv) ...@@ -371,23 +410,6 @@ gcm_set_iv(struct gcm_ctx *ctx, unsigned length, const uint8_t* iv)
ctx->auth_size = ctx->data_size = 0; 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)
{
for (; length >= GCM_BLOCK_SIZE;
length -= GCM_BLOCK_SIZE, data += GCM_BLOCK_SIZE)
{
memxor (x->b, data, GCM_BLOCK_SIZE);
gcm_gf_mul (x, key->h);
}
if (length > 0)
{
memxor (x->b, data, length);
gcm_gf_mul (x, key->h);
}
}
void void
gcm_auth(struct gcm_ctx *ctx, const struct gcm_key *key, gcm_auth(struct gcm_ctx *ctx, const struct gcm_key *key,
unsigned length, const uint8_t *data) unsigned length, const uint8_t *data)
...@@ -472,13 +494,7 @@ gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key, ...@@ -472,13 +494,7 @@ gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
assert (length <= GCM_BLOCK_SIZE); assert (length <= GCM_BLOCK_SIZE);
ctx->data_size *= 8; gcm_hash_sizes(key, &ctx->x, ctx->auth_size, ctx->data_size);
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);
f (cipher, GCM_BLOCK_SIZE, buffer, ctx->iv.b); f (cipher, GCM_BLOCK_SIZE, buffer, ctx->iv.b);
memxor3 (digest, ctx->x.b, buffer, length); memxor3 (digest, ctx->x.b, buffer, length);
......
...@@ -93,7 +93,8 @@ gcm_set_key(struct gcm_key *key, ...@@ -93,7 +93,8 @@ gcm_set_key(struct gcm_key *key,
void *cipher, nettle_crypt_func *f); void *cipher, nettle_crypt_func *f);
void 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 void
gcm_auth(struct gcm_ctx *ctx, const struct gcm_key *key, gcm_auth(struct gcm_ctx *ctx, const struct gcm_key *key,
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment