Commit 5f07c78b authored by Niels Möller's avatar Niels Möller

* gcm.c (gcm_set_key): Replaced context argument by a struct

gcm_key *.
(gcm_hash): Replaced context argument by a struct gcm_key * and a
pointer to the hashing state block.
(gcm_auth): Added struct gcm_key * argument.
(gcm_encrypt): Likewise.
(gcm_decrypt): Likewise.
(gcm_digest): Likewise.

* gcm.h (struct gcm_key): Moved the key-dependent and
message-independent state to its own struct.
(struct gcm_ctx): ... and removed it here.
(GCM_CTX): New macro.
(GCM_SET_KEY): Likewise.
(GCM_AUTH): Likewise.
(GCM_ENCRYPT): Likewise.
(GCM_DECRYPT): Likewise.
(GCM_DIGEST): Likewise.
(struct gcm_aes_ctx): New struct.

Rev: nettle/ChangeLog:1.142
Rev: nettle/gcm.c:1.12
Rev: nettle/gcm.h:1.7
parent 8b753af5
2011-02-09 Niels Mller <nisse@lysator.liu.se>
* gcm.c (gcm_set_key): Replaced context argument by a struct
gcm_key *.
(gcm_hash): Replaced context argument by a struct gcm_key * and a
pointer to the hashing state block.
(gcm_auth): Added struct gcm_key * argument.
(gcm_encrypt): Likewise.
(gcm_decrypt): Likewise.
(gcm_digest): Likewise.
* gcm-aes.c: New file.
(gcm_aes_set_key): New function.
(gcm_aes_set_iv): Likewise.
(gcm_aes_auth): Likewise.
(gcm_aes_encrypt): Likewise.
(gcm_aes_decrypt): Likewise.
(gcm_aes_digest): Likewise.
* gcm.h (struct gcm_key): Moved the key-dependent and
message-independent state to its own struct.
(struct gcm_ctx): ... and removed it here.
(GCM_CTX): New macro.
(GCM_SET_KEY): Likewise.
(GCM_AUTH): Likewise.
(GCM_ENCRYPT): Likewise.
(GCM_DECRYPT): Likewise.
(GCM_DIGEST): Likewise.
(struct gcm_aes_ctx): New struct.
2011-02-08 Niels Mller <nisse@lysator.liu.se>
* gcm.h (struct gcm_ctx): The hash key is now always an array,
......
......@@ -322,7 +322,7 @@ gcm_gf_mul (union gcm_block *x, const union gcm_block *table)
* @f: The underlying cipher encryption function
*/
void
gcm_set_key(struct gcm_ctx *ctx,
gcm_set_key(struct gcm_key *key,
void *cipher, nettle_crypt_func f)
{
/* Middle element if GCM_TABLE_BITS > 0, otherwise the first
......@@ -330,19 +330,19 @@ gcm_set_key(struct gcm_ctx *ctx,
unsigned i = (1<<GCM_TABLE_BITS)/2;
/* H */
memset(ctx->h[0].b, 0, GCM_BLOCK_SIZE);
f (cipher, GCM_BLOCK_SIZE, ctx->h[i].b, ctx->h[0].b);
memset(key->h[0].b, 0, GCM_BLOCK_SIZE);
f (cipher, GCM_BLOCK_SIZE, key->h[i].b, key->h[0].b);
#if GCM_TABLE_BITS
/* Algorithm 3 from the gcm paper. First do powers of two, then do
the rest by adding. */
while (i /= 2)
gcm_gf_shift(&ctx->h[i], &ctx->h[2*i]);
gcm_gf_shift(&key->h[i], &key->h[2*i]);
for (i = 2; i < 1<<GCM_TABLE_BITS; i *= 2)
{
unsigned j;
for (j = 1; j < i; j++)
gcm_gf_add(&ctx->h[i+j], &ctx->h[i],&ctx->h[j]);
gcm_gf_add(&key->h[i+j], &key->h[i],&key->h[j]);
}
#endif
}
......@@ -372,37 +372,37 @@ gcm_set_iv(struct gcm_ctx *ctx, unsigned length, const uint8_t* iv)
}
static void
gcm_hash(struct gcm_ctx *ctx, unsigned length, const uint8_t *data)
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 (ctx->x.b, data, GCM_BLOCK_SIZE);
gcm_gf_mul (&ctx->x, ctx->h);
memxor (x->b, data, GCM_BLOCK_SIZE);
gcm_gf_mul (x, key->h);
}
if (length > 0)
{
memxor (ctx->x.b, data, length);
gcm_gf_mul (&ctx->x, ctx->h);
memxor (x->b, data, length);
gcm_gf_mul (x, key->h);
}
}
void
gcm_auth(struct gcm_ctx *ctx,
gcm_auth(struct gcm_ctx *ctx, const struct gcm_key *key,
unsigned length, const uint8_t *data)
{
assert(ctx->auth_size % GCM_BLOCK_SIZE == 0);
assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
gcm_hash(ctx, length, data);
gcm_hash(key, &ctx->x, length, data);
ctx->auth_size += length;
}
static void
gcm_crypt(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f,
unsigned length,
uint8_t *dst, const uint8_t *src)
unsigned length, uint8_t *dst, const uint8_t *src)
{
uint8_t buffer[GCM_BLOCK_SIZE];
......@@ -438,32 +438,34 @@ gcm_crypt(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f,
}
void
gcm_encrypt (struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f,
unsigned length,
uint8_t *dst, const uint8_t *src)
gcm_encrypt (struct gcm_ctx *ctx, const struct gcm_key *key,
void *cipher, nettle_crypt_func *f,
unsigned length, uint8_t *dst, const uint8_t *src)
{
assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
gcm_crypt(ctx, cipher, f, length, dst, src);
gcm_hash(ctx, length, dst);
gcm_hash(key, &ctx->x, length, dst);
ctx->data_size += length;
}
void
gcm_decrypt(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f,
gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
void *cipher, nettle_crypt_func *f,
unsigned length, uint8_t *dst, const uint8_t *src)
{
assert(ctx->data_size % GCM_BLOCK_SIZE == 0);
gcm_hash(ctx, length, src);
gcm_hash(key, &ctx->x, length, src);
gcm_crypt(ctx, cipher, f, length, dst, src);
ctx->data_size += length;
}
void
gcm_digest(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f,
gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
void *cipher, nettle_crypt_func *f,
unsigned length, uint8_t *digest)
{
uint8_t buffer[GCM_BLOCK_SIZE];
......@@ -476,7 +478,7 @@ gcm_digest(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f,
WRITE_UINT64 (buffer, ctx->auth_size);
WRITE_UINT64 (buffer + 8, ctx->data_size);
gcm_hash(ctx, GCM_BLOCK_SIZE, buffer);
gcm_hash(key, &ctx->x, GCM_BLOCK_SIZE, buffer);
f (cipher, GCM_BLOCK_SIZE, buffer, ctx->iv.b);
memxor3 (digest, ctx->x.b, buffer, length);
......
......@@ -34,7 +34,7 @@
#ifndef NETTLE_GCM_H_INCLUDED
#define NETTLE_GCM_H_INCLUDED
#include "nettle-types.h"
#include "aes.h"
#ifdef __cplusplus
extern "C" {
......@@ -48,6 +48,13 @@ extern "C" {
#define gcm_decrypt nettle_gcm_decrypt
#define gcm_digest nettle_gcm_digest
#define gcm_aes_set_key nettle_gcm_aes_set_key
#define gcm_aes_set_iv nettle_gcm_aes_set_iv
#define gcm_aes_auth nettle_gcm_aes_auth
#define gcm_aes_encrypt nettle_gcm_aes_encrypt
#define gcm_aes_decrypt nettle_gcm_aes_decrypt
#define gcm_aes_digest nettle_gcm_aes_digest
#define GCM_BLOCK_SIZE 16
#define GCM_IV_SIZE (GCM_BLOCK_SIZE - 4)
......@@ -60,11 +67,14 @@ union gcm_block
unsigned long w[1];
};
struct gcm_ctx {
/* Key-dependent state. */
/* Hashing subkey */
/* Hashing subkey */
struct gcm_key
{
union gcm_block h[1 << GCM_TABLE_BITS];
/* Per-message state, depending on the iv */
};
/* Per-message state, depending on the iv */
struct gcm_ctx {
/* Original counter block */
union gcm_block iv;
/* Updated for each block. */
......@@ -79,52 +89,56 @@ struct gcm_ctx {
nettle_crypt_func, which also rules out using that abstraction for
arcfour. */
void
gcm_set_key(struct gcm_ctx *ctx,
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);
void
gcm_auth(struct gcm_ctx *ctx, unsigned length, const uint8_t *data);
gcm_auth(struct gcm_ctx *ctx, const struct gcm_key *key,
unsigned length, const uint8_t *data);
void
gcm_encrypt(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f,
gcm_encrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
void *cipher, nettle_crypt_func *f,
unsigned length, uint8_t *dst, const uint8_t *src);
void
gcm_decrypt(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f,
gcm_decrypt(struct gcm_ctx *ctx, const struct gcm_key *key,
void *cipher, nettle_crypt_func *f,
unsigned length, uint8_t *dst, const uint8_t *src);
void
gcm_digest(struct gcm_ctx *ctx, void *cipher, nettle_crypt_func *f,
gcm_digest(struct gcm_ctx *ctx, const struct gcm_key *key,
void *cipher, nettle_crypt_func *f,
unsigned length, uint8_t *digest);
#if 0
/* FIXME: Is this macrology useful? */
#define GCM_KEY(type) \
{ type cipher; struct gcm_ctx gcm; }
/* Convenience macrology (not sure how useful it is) */
/* All-in-one context, with cipher, hash subkey, and message state. */
#define GCM_CTX(type) \
{ type cipher; struct gcm_key key; struct gcm_ctx gcm; }
#define GCM_SET_KEY(ctx, set_key, encrypt, length, data) \
do { \
(set_key)(&(ctx)->cipher, (length), (data)); \
gcm_set_key(&(ctx)->gcm, &(ctx)->cipher, (encrypt)); \
gcm_set_key(&(ctx)->key, &(ctx)->cipher, (encrypt)); \
} while (0)
#define GCM_AUTH(ctx, encrypt, length, data) \
gcm_auth((ctx)->gcm, &(ctx)->cipher, (encrypt), \
(length), (data))
gcm_auth(&(ctx)->gcm, &(ctx)->key, (length), (data))
#define GCM_ENCRYPT(ctx, encrypt, length, dst, src) \
gcm_encrypt((ctx)->gcm, &(ctx)->cipher, (encrypt), \
gcm_encrypt(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher, (encrypt), \
(length), (dst), (src))
#define GCM_DECRYPT(ctx, key, encrypt, length, dst, src) \
gcm_decrypt((ctx)->gcm, &(ctx)->cipher, (encrypt), \
#define GCM_DECRYPT(ctx, encrypt, length, dst, src) \
gcm_decrypt(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher, (encrypt), \
(length), (dst), (src))
#define GCM_DIGEST(ctx, key, encrypt, length, digest) \
gcm_digest((ctx)->gcm, &(ctx)->cipher, (encrypt), \
#define GCM_DIGEST(ctx, encrypt, length, digest) \
gcm_digest(&(ctx)->gcm, &(ctx)->key, &(ctx)->cipher, (encrypt), \
(length), (digest))
struct gcm_aes_ctx GCM_CTX(struct aes_ctx);
......@@ -137,6 +151,8 @@ void
gcm_aes_set_iv(struct gcm_aes_ctx *ctx,
unsigned length, const uint8_t *iv);
/* FIXME: Rename to gcm_aes_update, for consistency with other hash
and mac functions? */
void
gcm_aes_auth(struct gcm_aes_ctx *ctx,
unsigned length, const uint8_t *data);
......@@ -150,9 +166,7 @@ gcm_aes_decrypt(struct gcm_aes_ctx *ctx,
unsigned length, uint8_t *dst, const uint8_t *src);
void
gcm_aes_digest(struct gcm_aes_ctx *ctx,
unsigned length, uint8_t *digest);
#endif
gcm_aes_digest(struct gcm_aes_ctx *ctx, unsigned length, uint8_t *digest);
#ifdef __cplusplus
}
......
Markdown is supported
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