From: Niels Möller Date: Wed, 9 Feb 2011 21:31:07 +0000 (+0100) Subject: * gcm.c (gcm_set_key): Replaced context argument by a struct X-Git-Tag: nettle_2.2_release_20110711~163 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5f07c78bbbf2dd5156f56085263f1245a2080cc0;p=thirdparty%2Fnettle.git * 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 --- diff --git a/ChangeLog b/ChangeLog index e4178436..a8235b95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,33 @@ +2011-02-09 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-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 Möller * gcm.h (struct gcm_ctx): The hash key is now always an array, diff --git a/gcm.c b/gcm.c index e1d81f42..2fb0bd9b 100644 --- a/gcm.c +++ b/gcm.c @@ -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<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<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); diff --git a/gcm.h b/gcm.h index 7f3c8ae1..c71ebaab 100644 --- a/gcm.h +++ b/gcm.h @@ -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 }