diff --git a/ChangeLog b/ChangeLog
index a7a4355f065984988f8a4724f891979411d0ecba..900a7e83096d1fdd0cb5dd71e54f54fa0588d88c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/cmac.c b/cmac.c
index 07d805f380e8ebaf8e7643a60dd16d1e075676c3..c5a59b18e572732730f956c82d4c57d36d1e62cf 100644
--- a/cmac.c
+++ b/cmac.c
@@ -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);
 }
diff --git a/cmac.h b/cmac.h
index 9bff537d7748ea11497f8ea8628d71d305d946e0..3c5b7bea3e5537f2e2efedf8341bbb53394c255a 100644
--- a/cmac.h
+++ b/cmac.h
@@ -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);