]> git.ipfire.org Git - thirdparty/nettle.git/commitdiff
Add tag_length to ccm_ctx, and drop length argument to ccm_digest.
authorNiels Möller <nisse@lysator.liu.se>
Wed, 14 Jan 2026 10:50:34 +0000 (11:50 +0100)
committerNiels Möller <nisse@lysator.liu.se>
Wed, 14 Jan 2026 15:13:52 +0000 (16:13 +0100)
ChangeLog
ccm-aes128.c
ccm-aes192.c
ccm-aes256.c
ccm.c
ccm.h
testsuite/ccm-test.c

index ca91c5b466825f798c6da032f94be041793f0acf..82e4b82df16452482cf816d452d8a67dc9d6c06a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2026-01-14  Niels Möller  <nisse@lysator.liu.se>
+
+       * ccm.h (CCM_MIN_DIGEST_SIZE): New constant.
+       (struct ccm_ctx): New field tag_length, storing the size used for
+       constructing the IV in ccm_set_nonce.
+       * ccm.c (ccm_set_nonce): Check that tag length is according to
+       spec, and store in context.
+       (ccm_digest): Delete length argument. Size of digest was stored in
+       the context by ccm_set_nonce. Updated all callers.
+       * ccm-aes128.c (ccm_aes128_digest): Delete length argument.
+       * ccm-aes192.c (ccm_aes192_digest): Likewise.
+       * ccm-aes256.c: Likewise.
+       * testsuite/ccm-test.c (test_main): Delete test from IEEE
+       802.15.4-2011, C.2.2, since it uses an invalid zero tag length.
+
 2026-01-08  Niels Möller  <nisse@lysator.liu.se>
 
        * ocb.c (update_offset): Deleted function, replaced with...
index cf61407347c1d7eef04a9dac2f1feb2c55069894..39045f6b8178d08cd0e86b884818cb500d73f5bf 100644 (file)
@@ -81,11 +81,9 @@ ccm_aes128_decrypt(struct ccm_aes128_ctx *ctx,
 }
 
 void
-ccm_aes128_digest(struct ccm_aes128_ctx *ctx,
-                 size_t length, uint8_t *digest)
+ccm_aes128_digest(struct ccm_aes128_ctx *ctx, uint8_t *digest)
 {
-  ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt,
-            length, digest);
+  ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes128_encrypt, digest);
 }
 
 void
index f0064162ed7141b1e3c849b1b494117b1c516720..392c60269dbe52b16bfaac8ed5b56e5184cdabe0 100644 (file)
@@ -81,11 +81,9 @@ ccm_aes192_decrypt(struct ccm_aes192_ctx *ctx,
 }
 
 void
-ccm_aes192_digest(struct ccm_aes192_ctx *ctx,
-                 size_t length, uint8_t *digest)
+ccm_aes192_digest(struct ccm_aes192_ctx *ctx, uint8_t *digest)
 {
-  ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt,
-            length, digest);
+  ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes192_encrypt, digest);
 }
 
 void
index a5562c7b932a4540b3d31456129bf9118162c3ad..96ccb54672483362feef539810cfb3d03d8a5d3e 100644 (file)
@@ -82,11 +82,9 @@ ccm_aes256_decrypt(struct ccm_aes256_ctx *ctx,
 }
 
 void
-ccm_aes256_digest(struct ccm_aes256_ctx *ctx,
-                 size_t length, uint8_t *digest)
+ccm_aes256_digest(struct ccm_aes256_ctx *ctx, uint8_t *digest)
 {
-  ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt,
-            length, digest);
+  ccm_digest(&ctx->ccm, &ctx->cipher, (nettle_cipher_func *) aes256_encrypt, digest);
 }
 
 void
diff --git a/ccm.c b/ccm.c
index bdbd595c60474f68024be120c6a3cd1d5e4ebcf3..442753e011cab02d7bfddc3f53abc20595fad154 100644 (file)
--- a/ccm.c
+++ b/ccm.c
@@ -121,6 +121,9 @@ ccm_set_nonce(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
              size_t length, const uint8_t *nonce,
              size_t authlen, size_t msglen, size_t taglen)
 {
+  assert (taglen >= 4 && taglen <= 16 && !(taglen & 1));
+  ctx->tag_length = taglen;
+
   /* Generate the IV for the CTR and CBC-MAC */
   ctx->blength = 0;
   ccm_build_iv(ctx->tag.b, length, nonce, CCM_FLAG_SET_M(taglen), msglen);
@@ -222,13 +225,13 @@ ccm_decrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
 
 void
 ccm_digest(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
-          size_t length, uint8_t *digest)
+          uint8_t *digest)
 {
   int i = CCM_BLOCK_SIZE - CCM_FLAG_GET_L(ctx->ctr.b[CCM_OFFSET_FLAGS]);
-  assert(length <= CCM_BLOCK_SIZE);
   while (i < CCM_BLOCK_SIZE)  ctx->ctr.b[i++] = 0;
   ccm_pad(ctx, cipher, f);
-  ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, digest, ctx->tag.b);
+  assert (ctx->tag_length <= CCM_BLOCK_SIZE);
+  ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, ctx->tag_length, digest, ctx->tag.b);
 }
 
 void
@@ -243,7 +246,7 @@ ccm_encrypt_message(const void *cipher, nettle_cipher_func *f,
   ccm_set_nonce(&ctx, cipher, f, nlength, nonce, alength, clength-tlength, tlength);
   ccm_update(&ctx, cipher, f, alength, adata);
   ccm_encrypt(&ctx, cipher, f, clength-tlength, dst, src);
-  ccm_digest(&ctx, cipher, f, tlength, tag);
+  ccm_digest(&ctx, cipher, f, tag);
 }
 
 int
@@ -257,6 +260,6 @@ ccm_decrypt_message(const void *cipher, nettle_cipher_func *f,
   ccm_set_nonce(&ctx, cipher, f, nlength, nonce, alength, mlength, tlength);
   ccm_update(&ctx, cipher, f, alength, adata);
   ccm_decrypt(&ctx, cipher, f, mlength, dst, src);
-  ccm_digest(&ctx, cipher, f, tlength, tag);
+  ccm_digest(&ctx, cipher, f, tag);
   return memeql_sec(tag, src + mlength, tlength);
 }
diff --git a/ccm.h b/ccm.h
index 95d3bfe16bb603d8d387e049cbace31cbf98d507..391e0da9033bf5556e4714601c2f7ce7050cae68 100644 (file)
--- a/ccm.h
+++ b/ccm.h
@@ -90,6 +90,8 @@ extern "C" {
 /* For CCM, the block size of the block cipher shall be 128 bits. */
 #define CCM_BLOCK_SIZE  16
 #define CCM_DIGEST_SIZE 16
+/* Digest size must be even, valid values 4, 6, 8, 10, 12, 14, 16 */
+#define CCM_MIN_DIGEST_SIZE 4
 #define CCM_MIN_NONCE_SIZE 7
 #define CCM_MAX_NONCE_SIZE 14
 
@@ -106,7 +108,8 @@ struct ccm_ctx {
   union nettle_block16 ctr;     /* Counter for CTR encryption. */
   union nettle_block16 tag;     /* CBC-MAC message tag. */
   /* Length of data processed by the CBC-MAC modulus the block size */
-  unsigned int blength;
+  unsigned short blength;
+  unsigned short tag_length;
 };
 
 /*
@@ -132,7 +135,7 @@ ccm_decrypt(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
 
 void
 ccm_digest(struct ccm_ctx *ctx, const void *cipher, nettle_cipher_func *f,
-          size_t length, uint8_t *digest);
+          uint8_t *digest);
 
 /*
  * All-in-one encryption and decryption API:
@@ -190,8 +193,7 @@ ccm_aes128_decrypt(struct ccm_aes128_ctx *ctx,
                   size_t length, uint8_t *dst, const uint8_t *src);
 
 void
-ccm_aes128_digest(struct ccm_aes128_ctx *ctx,
-                 size_t length, uint8_t *digest);
+ccm_aes128_digest(struct ccm_aes128_ctx *ctx, uint8_t *digest);
 
 void
 ccm_aes128_encrypt_message(const struct aes128_ctx *ctx,
@@ -234,8 +236,7 @@ ccm_aes192_decrypt(struct ccm_aes192_ctx *ctx,
                   size_t length, uint8_t *dst, const uint8_t *src);
 
 void
-ccm_aes192_digest(struct ccm_aes192_ctx *ctx,
-                 size_t length, uint8_t *digest);
+ccm_aes192_digest(struct ccm_aes192_ctx *ctx, uint8_t *digest);
 
 void
 ccm_aes192_encrypt_message(const struct aes192_ctx *ctx,
@@ -278,8 +279,7 @@ ccm_aes256_decrypt(struct ccm_aes256_ctx *ctx,
                   size_t length, uint8_t *dst, const uint8_t *src);
 
 void
-ccm_aes256_digest(struct ccm_aes256_ctx *ctx,
-                 size_t length, uint8_t *digest);
+ccm_aes256_digest(struct ccm_aes256_ctx *ctx, uint8_t *digest);
 
 void
 ccm_aes256_encrypt_message(const struct aes256_ctx *ctx,
index 3401b1d45b3171ded271fa8686d17e521d7acb02..e50293e9a7415d0e356c7a54cad7e9e2bcf7de29 100644 (file)
@@ -133,7 +133,7 @@ test_cipher_ccm(const struct nettle_cipher *cipher,
     ccm_update(&ccm, ctx, cipher->encrypt, authdata->length, authdata->data);
   }
   ccm_encrypt(&ccm, ctx, cipher->encrypt, cleartext->length, en_data, cleartext->data);
-  ccm_digest(&ccm, ctx, cipher->encrypt, tlength, en_digest);
+  ccm_digest(&ccm, ctx, cipher->encrypt, en_digest);
 
   /* Decrypt using the incremental API. */
   ccm_set_nonce(&ccm, ctx, cipher->encrypt, nonce->length, nonce->data,
@@ -142,7 +142,7 @@ test_cipher_ccm(const struct nettle_cipher *cipher,
     ccm_update(&ccm, ctx, cipher->encrypt, authdata->length, authdata->data);
   }
   ccm_decrypt(&ccm, ctx, cipher->encrypt, cleartext->length, de_data, ciphertext->data);
-  ccm_digest(&ccm, ctx, cipher->encrypt, tlength, de_digest);
+  ccm_digest(&ccm, ctx, cipher->encrypt, de_digest);
 
   /* Compare results using the generic API. */
   test_compare_results("CCM", authdata,
@@ -205,7 +205,7 @@ test_cipher_ccm(const struct nettle_cipher *cipher,
       ccm_aes128_update(&aes, authdata->length, authdata->data);
     }
     ccm_aes128_encrypt(&aes, cleartext->length, en_data, cleartext->data);
-    ccm_aes128_digest(&aes, tlength, en_digest);
+    ccm_aes128_digest(&aes, en_digest);
 
     /* AES-128 decrypt. */
     ccm_aes128_set_nonce(&aes, nonce->length, nonce->data,
@@ -214,7 +214,7 @@ test_cipher_ccm(const struct nettle_cipher *cipher,
       ccm_aes128_update(&aes, authdata->length, authdata->data);
     }
     ccm_aes128_decrypt(&aes, cleartext->length, de_data, ciphertext->data);
-    ccm_aes128_digest(&aes, tlength, de_digest);
+    ccm_aes128_digest(&aes, de_digest);
 
     test_compare_results("CCM_AES_128", authdata,
                         cleartext, ciphertext, de_data, en_data, de_digest);
@@ -251,7 +251,7 @@ test_cipher_ccm(const struct nettle_cipher *cipher,
       ccm_aes256_update(&aes, authdata->length, authdata->data);
     }
     ccm_aes256_encrypt(&aes, cleartext->length, en_data, cleartext->data);
-    ccm_aes256_digest(&aes, tlength, en_digest);
+    ccm_aes256_digest(&aes, en_digest);
 
     /* AES-256 decrypt. */
     ccm_aes256_set_nonce(&aes, nonce->length, nonce->data,
@@ -260,7 +260,7 @@ test_cipher_ccm(const struct nettle_cipher *cipher,
       ccm_aes256_update(&aes, authdata->length, authdata->data);
     }
     ccm_aes256_decrypt(&aes, cleartext->length, de_data, ciphertext->data);
-    ccm_aes256_digest(&aes, tlength, de_digest);
+    ccm_aes256_digest(&aes, de_digest);
 
     test_compare_results("CCM_AES_256", authdata,
                         cleartext, ciphertext, de_data, en_data, de_digest);
@@ -633,16 +633,6 @@ test_main(void)
                  SHEX(""),
                  SHEX("22 3B C1 EC 84 1A B5 53"));
 
-  /*
-   * C.2.2 MAC data frame
-   */
-  test_cipher_ccm(&nettle_aes128,
-                 SHEX("C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF"),
-                 SHEX("AC DE 48 00 00 00 00 01 00 00 00 05 04"),
-                 SHEX("69 DC 84 21 43 02 00 00 00 00 48 DE AC 01 00 00 00 00 48 DE AC 04 05 00 00 00"), 1,
-                 SHEX("61 62 63 64"),
-                 SHEX("D4 3E 02 2B"));
-
   /*
    * C.2.3 MAC command frame
    */