diff options
author | Niels Möller <nisse@lysator.liu.se> | 2019-06-05 22:25:20 +0200 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2019-06-05 22:25:20 +0200 |
commit | 81af7f9cdec3c8a19c4b725527959fe310ae3c97 (patch) | |
tree | 52c73f67c389933b16b8c19133152db516d5d751 | |
parent | d2da7945b49f056db674827d671dbb2c56e34e27 (diff) | |
download | nettle-cmac-layout.tar.gz |
Further separation of CMAC per-message state from subkeys.cmac-layout
-rw-r--r-- | ChangeLog | 17 | ||||
-rw-r--r-- | cmac.c | 41 | ||||
-rw-r--r-- | cmac.h | 37 |
3 files changed, 60 insertions, 35 deletions
@@ -1,3 +1,20 @@ +2019-06-05 Niels Möller <nisse@lysator.liu.se> + + Further separation of CMAC per-message state from the + message-independent subkeys, analogous to the gcm implementation. + * cmac.h (struct cmac128_ctx): Remove key, instead a struct + cmac128_key should be passed separately to functions that need it. + (CMAC128_CTX): Include both a struct cmac128_key and a struct + cmac128_ctx. + (CMAC128_SET_KEY, CMAC128_DIGEST): Updated accordingly. + + * cmac.c (cmac128_set_key): Change argument type from cmac128_ctx + to cmac128_key. Use a nettle_block16 for the constant zero block. + (cmac128_init): New function, to initialize a cmac128_ctx. + (cmac128_digest): Add cmac128_key argument. Move padding memset + into the block handling a partial block. Call cmac128_init to + reset state. + 2019-06-01 Niels Möller <nisse@lysator.liu.se> * cmac.h (struct cmac128_key): New struct. @@ -70,21 +70,24 @@ block_mulx(union nettle_block16 *dst, #endif /* !WORDS_BIGENDIAN */ void -cmac128_set_key(struct cmac128_ctx *ctx, const void *cipher, +cmac128_set_key(struct cmac128_key *key, const void *cipher, nettle_cipher_func *encrypt) { - static const uint8_t const_zero[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - union nettle_block16 *L = &ctx->block; - memset(ctx, 0, sizeof(*ctx)); + static const union nettle_block16 zero_block; + union nettle_block16 L; /* step 1 - generate subkeys k1 and k2 */ - encrypt(cipher, 16, L->b, const_zero); + encrypt(cipher, 16, L.b, zero_block.b); - block_mulx(&ctx->key.K1, L); - block_mulx(&ctx->key.K2, &ctx->key.K1); + block_mulx(&key->K1, &L); + block_mulx(&key->K2, &key->K1); +} + +void +cmac128_init(struct cmac128_ctx *ctx) +{ + memset(&ctx->X, 0, sizeof(ctx->X)); + ctx->index = 0; } #define MIN(x,y) ((x)<(y)?(x):(y)) @@ -135,24 +138,23 @@ cmac128_update(struct cmac128_ctx *ctx, const void *cipher, } void -cmac128_digest(struct cmac128_ctx *ctx, const void *cipher, - nettle_cipher_func *encrypt, - unsigned length, - uint8_t *dst) +cmac128_digest(struct cmac128_ctx *ctx, const struct cmac128_key *key, + const void *cipher, nettle_cipher_func *encrypt, + unsigned length, uint8_t *dst) { union nettle_block16 Y; - memset(ctx->block.b+ctx->index, 0, sizeof(ctx->block.b)-ctx->index); - /* re-use ctx->block for memxor output */ if (ctx->index < 16) { ctx->block.b[ctx->index] = 0x80; - memxor(ctx->block.b, ctx->key.K2.b, 16); + memset(ctx->block.b + ctx->index + 1, 0, 16 - 1 - ctx->index); + + memxor(ctx->block.b, key->K2.b, 16); } else { - memxor(ctx->block.b, ctx->key.K1.b, 16); + memxor(ctx->block.b, key->K1.b, 16); } memxor3(Y.b, ctx->block.b, ctx->X.b, 16); @@ -169,6 +171,5 @@ cmac128_digest(struct cmac128_ctx *ctx, const void *cipher, } /* reset state for re-use */ - memset(&ctx->X, 0, sizeof(ctx->X)); - ctx->index = 0; + cmac128_init(ctx); } @@ -46,6 +46,7 @@ extern "C" { #define CMAC128_DIGEST_SIZE 16 #define cmac128_set_key nettle_cmac128_set_key +#define cmac128_init nettle_cmac128_init #define cmac128_update nettle_cmac128_update #define cmac128_digest nettle_cmac128_digest #define cmac_aes128_set_key nettle_cmac_aes128_set_key @@ -63,8 +64,6 @@ struct cmac128_key struct cmac128_ctx { - struct cmac128_key key; - /* MAC state */ union nettle_block16 X; @@ -74,21 +73,24 @@ struct cmac128_ctx }; void -cmac128_set_key(struct cmac128_ctx *ctx, const void *cipher, +cmac128_set_key(struct cmac128_key *key, const void *cipher, nettle_cipher_func *encrypt); + +void +cmac128_init(struct cmac128_ctx *ctx); + void cmac128_update(struct cmac128_ctx *ctx, const void *cipher, nettle_cipher_func *encrypt, size_t msg_len, const uint8_t *msg); void -cmac128_digest(struct cmac128_ctx *ctx, const void *cipher, - nettle_cipher_func *encrypt, - unsigned length, - uint8_t *digest); +cmac128_digest(struct cmac128_ctx *ctx, const struct cmac128_key *key, + const void *cipher, nettle_cipher_func *encrypt, + unsigned length, uint8_t *digest); #define CMAC128_CTX(type) \ - { struct cmac128_ctx ctx; type cipher; } + { struct cmac128_key key; struct cmac128_ctx ctx; type cipher; } /* NOTE: Avoid using NULL, as we don't include anything defining it. */ #define CMAC128_SET_KEY(self, set_key, encrypt, cmac_key) \ @@ -96,20 +98,25 @@ cmac128_digest(struct cmac128_ctx *ctx, const void *cipher, (set_key)(&(self)->cipher, (cmac_key)); \ if (0) (encrypt)(&(self)->cipher, ~(size_t) 0, \ (uint8_t *) 0, (const uint8_t *) 0); \ - cmac128_set_key(&(self)->ctx, &(self)->cipher, \ - (nettle_cipher_func *) (encrypt)); \ + cmac128_set_key(&(self)->key, &(self)->cipher, \ + (nettle_cipher_func *) (encrypt)); \ + cmac128_init(&(self)->ctx); \ } while (0) #define CMAC128_UPDATE(self, encrypt, length, src) \ - cmac128_update(&(self)->ctx, &(self)->cipher, \ - (nettle_cipher_func *)encrypt, (length), (src)) + (0 ? (encrypt)(&(self)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0) \ + : cmac128_update(&(self)->ctx, &(self)->cipher, \ + (nettle_cipher_func *)encrypt, \ + (length), (src))) #define CMAC128_DIGEST(self, encrypt, length, digest) \ (0 ? (encrypt)(&(self)->cipher, ~(size_t) 0, \ (uint8_t *) 0, (const uint8_t *) 0) \ - : cmac128_digest(&(self)->ctx, &(self)->cipher, \ - (nettle_cipher_func *) (encrypt), \ - (length), (digest))) + : cmac128_digest(&(self)->ctx, &(self)->key, \ + &(self)->cipher, \ + (nettle_cipher_func *) (encrypt), \ + (length), (digest))) struct cmac_aes128_ctx CMAC128_CTX(struct aes128_ctx); |