Commit 81af7f9c authored by Niels Möller's avatar Niels Möller

Further separation of CMAC per-message state from subkeys.

parent d2da7945
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> 2019-06-01 Niels Möller <nisse@lysator.liu.se>
* cmac.h (struct cmac128_key): New struct. * cmac.h (struct cmac128_key): New struct.
......
...@@ -70,21 +70,24 @@ block_mulx(union nettle_block16 *dst, ...@@ -70,21 +70,24 @@ block_mulx(union nettle_block16 *dst,
#endif /* !WORDS_BIGENDIAN */ #endif /* !WORDS_BIGENDIAN */
void 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) nettle_cipher_func *encrypt)
{ {
static const uint8_t const_zero[] = { static const union nettle_block16 zero_block;
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, union nettle_block16 L;
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
union nettle_block16 *L = &ctx->block;
memset(ctx, 0, sizeof(*ctx));
/* step 1 - generate subkeys k1 and k2 */ /* 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(&key->K1, &L);
block_mulx(&ctx->key.K2, &ctx->key.K1); 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)) #define MIN(x,y) ((x)<(y)?(x):(y))
...@@ -135,24 +138,23 @@ cmac128_update(struct cmac128_ctx *ctx, const void *cipher, ...@@ -135,24 +138,23 @@ cmac128_update(struct cmac128_ctx *ctx, const void *cipher,
} }
void void
cmac128_digest(struct cmac128_ctx *ctx, const void *cipher, cmac128_digest(struct cmac128_ctx *ctx, const struct cmac128_key *key,
nettle_cipher_func *encrypt, const void *cipher, nettle_cipher_func *encrypt,
unsigned length, unsigned length, uint8_t *dst)
uint8_t *dst)
{ {
union nettle_block16 Y; union nettle_block16 Y;
memset(ctx->block.b+ctx->index, 0, sizeof(ctx->block.b)-ctx->index);
/* re-use ctx->block for memxor output */ /* re-use ctx->block for memxor output */
if (ctx->index < 16) if (ctx->index < 16)
{ {
ctx->block.b[ctx->index] = 0x80; 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 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); memxor3(Y.b, ctx->block.b, ctx->X.b, 16);
...@@ -169,6 +171,5 @@ cmac128_digest(struct cmac128_ctx *ctx, const void *cipher, ...@@ -169,6 +171,5 @@ cmac128_digest(struct cmac128_ctx *ctx, const void *cipher,
} }
/* reset state for re-use */ /* reset state for re-use */
memset(&ctx->X, 0, sizeof(ctx->X)); cmac128_init(ctx);
ctx->index = 0;
} }
...@@ -46,6 +46,7 @@ extern "C" { ...@@ -46,6 +46,7 @@ extern "C" {
#define CMAC128_DIGEST_SIZE 16 #define CMAC128_DIGEST_SIZE 16
#define cmac128_set_key nettle_cmac128_set_key #define cmac128_set_key nettle_cmac128_set_key
#define cmac128_init nettle_cmac128_init
#define cmac128_update nettle_cmac128_update #define cmac128_update nettle_cmac128_update
#define cmac128_digest nettle_cmac128_digest #define cmac128_digest nettle_cmac128_digest
#define cmac_aes128_set_key nettle_cmac_aes128_set_key #define cmac_aes128_set_key nettle_cmac_aes128_set_key
...@@ -63,8 +64,6 @@ struct cmac128_key ...@@ -63,8 +64,6 @@ struct cmac128_key
struct cmac128_ctx struct cmac128_ctx
{ {
struct cmac128_key key;
/* MAC state */ /* MAC state */
union nettle_block16 X; union nettle_block16 X;
...@@ -74,21 +73,24 @@ struct cmac128_ctx ...@@ -74,21 +73,24 @@ struct cmac128_ctx
}; };
void 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); nettle_cipher_func *encrypt);
void
cmac128_init(struct cmac128_ctx *ctx);
void void
cmac128_update(struct cmac128_ctx *ctx, const void *cipher, cmac128_update(struct cmac128_ctx *ctx, const void *cipher,
nettle_cipher_func *encrypt, nettle_cipher_func *encrypt,
size_t msg_len, const uint8_t *msg); size_t msg_len, const uint8_t *msg);
void void
cmac128_digest(struct cmac128_ctx *ctx, const void *cipher, cmac128_digest(struct cmac128_ctx *ctx, const struct cmac128_key *key,
nettle_cipher_func *encrypt, const void *cipher, nettle_cipher_func *encrypt,
unsigned length, unsigned length, uint8_t *digest);
uint8_t *digest);
#define CMAC128_CTX(type) \ #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. */ /* NOTE: Avoid using NULL, as we don't include anything defining it. */
#define CMAC128_SET_KEY(self, set_key, encrypt, cmac_key) \ #define CMAC128_SET_KEY(self, set_key, encrypt, cmac_key) \
...@@ -96,20 +98,25 @@ cmac128_digest(struct cmac128_ctx *ctx, const void *cipher, ...@@ -96,20 +98,25 @@ cmac128_digest(struct cmac128_ctx *ctx, const void *cipher,
(set_key)(&(self)->cipher, (cmac_key)); \ (set_key)(&(self)->cipher, (cmac_key)); \
if (0) (encrypt)(&(self)->cipher, ~(size_t) 0, \ if (0) (encrypt)(&(self)->cipher, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0); \ (uint8_t *) 0, (const uint8_t *) 0); \
cmac128_set_key(&(self)->ctx, &(self)->cipher, \ cmac128_set_key(&(self)->key, &(self)->cipher, \
(nettle_cipher_func *) (encrypt)); \ (nettle_cipher_func *) (encrypt)); \
cmac128_init(&(self)->ctx); \
} while (0) } while (0)
#define CMAC128_UPDATE(self, encrypt, length, src) \ #define CMAC128_UPDATE(self, encrypt, length, src) \
cmac128_update(&(self)->ctx, &(self)->cipher, \ (0 ? (encrypt)(&(self)->cipher, ~(size_t) 0, \
(nettle_cipher_func *)encrypt, (length), (src)) (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) \ #define CMAC128_DIGEST(self, encrypt, length, digest) \
(0 ? (encrypt)(&(self)->cipher, ~(size_t) 0, \ (0 ? (encrypt)(&(self)->cipher, ~(size_t) 0, \
(uint8_t *) 0, (const uint8_t *) 0) \ (uint8_t *) 0, (const uint8_t *) 0) \
: cmac128_digest(&(self)->ctx, &(self)->cipher, \ : cmac128_digest(&(self)->ctx, &(self)->key, \
(nettle_cipher_func *) (encrypt), \ &(self)->cipher, \
(length), (digest))) (nettle_cipher_func *) (encrypt), \
(length), (digest)))
struct cmac_aes128_ctx CMAC128_CTX(struct aes128_ctx); struct cmac_aes128_ctx CMAC128_CTX(struct aes128_ctx);
......
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