From cb20517cb25a24420ee8e7edcc877bbb6c705d52 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Niels=20M=C3=B6ller?= Date: Sun, 9 Mar 2025 09:06:24 +0100 Subject: [PATCH] Change type of the context argument for ccm_aes*_message. Used to be a struct ccm_aes{128,192,256}_ctx * most of which was unused. Changed to instead take just a const struct aes{128,192,256}_ctx * --- ChangeLog | 15 +++++++++ ccm-aes128.c | 9 +++--- ccm-aes192.c | 9 +++--- ccm-aes256.c | 8 ++--- ccm.h | 15 ++++----- nettle.texinfo | 19 ++++++------ testsuite/ccm-test.c | 72 ++++++++++++++++++++++++++++++++++---------- 7 files changed, 99 insertions(+), 48 deletions(-) diff --git a/ChangeLog b/ChangeLog index 954c3b08..6278a939 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2025-03-09 Niels Möller + + * ccm-aes128.c (ccm_aes128_encrypt_message) + (ccm_aes128_decrypt_message): Change type of ctx argument to const + struct aes128_ctx *. + * ccm-aes192.c (ccm_aes192_encrypt_message) + (ccm_aes192_decrypt_message): Change type of ctx argument to const + struct aes192_ctx *. + * ccm-aes256.c (ccm_aes256_encrypt_message) + (ccm_aes256_decrypt_message): Change type of ctx argument to const + struct aes256_ctx *. + * testsuite/ccm-test.c (test_cipher_ccm): Add tests for + ccm_aes*_message functions, + * nettle.texinfo (CCM): Update documentation. + 2025-03-06 Niels Möller * nettle-types.h (union nettle_block16): Delete deprecated diff --git a/ccm-aes128.c b/ccm-aes128.c index 74ae51f4..cf614073 100644 --- a/ccm-aes128.c +++ b/ccm-aes128.c @@ -89,26 +89,25 @@ ccm_aes128_digest(struct ccm_aes128_ctx *ctx, } void -ccm_aes128_encrypt_message(struct ccm_aes128_ctx *ctx, +ccm_aes128_encrypt_message(const struct aes128_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t clength, uint8_t *dst, const uint8_t *src) { - ccm_encrypt_message(&ctx->cipher, (nettle_cipher_func *) aes128_encrypt, + ccm_encrypt_message(ctx, (nettle_cipher_func *) aes128_encrypt, nlength, nonce, alength, adata, tlength, clength, dst, src); } int -ccm_aes128_decrypt_message(struct ccm_aes128_ctx *ctx, +ccm_aes128_decrypt_message(const struct aes128_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t mlength, uint8_t *dst, const uint8_t *src) { - return ccm_decrypt_message(&ctx->cipher, - (nettle_cipher_func *) aes128_encrypt, + return ccm_decrypt_message(ctx, (nettle_cipher_func *) aes128_encrypt, nlength, nonce, alength, adata, tlength, mlength, dst, src); } diff --git a/ccm-aes192.c b/ccm-aes192.c index 6b6ebed9..f0064162 100644 --- a/ccm-aes192.c +++ b/ccm-aes192.c @@ -89,26 +89,25 @@ ccm_aes192_digest(struct ccm_aes192_ctx *ctx, } void -ccm_aes192_encrypt_message(struct ccm_aes192_ctx *ctx, +ccm_aes192_encrypt_message(const struct aes192_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t clength, uint8_t *dst, const uint8_t *src) { - ccm_encrypt_message(&ctx->cipher, (nettle_cipher_func *) aes192_encrypt, + ccm_encrypt_message(ctx, (nettle_cipher_func *) aes192_encrypt, nlength, nonce, alength, adata, tlength, clength, dst, src); } int -ccm_aes192_decrypt_message(struct ccm_aes192_ctx *ctx, +ccm_aes192_decrypt_message(const struct aes192_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t mlength, uint8_t *dst, const uint8_t *src) { - return ccm_decrypt_message(&ctx->cipher, - (nettle_cipher_func *) aes192_encrypt, + return ccm_decrypt_message(ctx, (nettle_cipher_func *) aes192_encrypt, nlength, nonce, alength, adata, tlength, mlength, dst, src); } diff --git a/ccm-aes256.c b/ccm-aes256.c index 211c411b..a5562c7b 100644 --- a/ccm-aes256.c +++ b/ccm-aes256.c @@ -90,25 +90,25 @@ ccm_aes256_digest(struct ccm_aes256_ctx *ctx, } void -ccm_aes256_encrypt_message(struct ccm_aes256_ctx *ctx, +ccm_aes256_encrypt_message(const struct aes256_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t clength, uint8_t *dst, const uint8_t *src) { - ccm_encrypt_message(&ctx->cipher, (nettle_cipher_func *) aes256_encrypt, + ccm_encrypt_message(ctx, (nettle_cipher_func *) aes256_encrypt, nlength, nonce, alength, adata, tlength, clength, dst, src); } int -ccm_aes256_decrypt_message(struct ccm_aes256_ctx *ctx, +ccm_aes256_decrypt_message(const struct aes256_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t mlength, uint8_t *dst, const uint8_t *src) { - return ccm_decrypt_message(&ctx->cipher, (nettle_cipher_func *) aes256_encrypt, + return ccm_decrypt_message(ctx, (nettle_cipher_func *) aes256_encrypt, nlength, nonce, alength, adata, tlength, mlength, dst, src); } diff --git a/ccm.h b/ccm.h index edab268a..3bde665e 100644 --- a/ccm.h +++ b/ccm.h @@ -193,18 +193,15 @@ void ccm_aes128_digest(struct ccm_aes128_ctx *ctx, size_t length, uint8_t *digest); -/* FIXME: For next API/ABI break: first argument should be const - struct aes128_ctx *, and similarly for other ccm_*_message - functions below. */ void -ccm_aes128_encrypt_message(struct ccm_aes128_ctx *ctx, +ccm_aes128_encrypt_message(const struct aes128_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t clength, uint8_t *dst, const uint8_t *src); int -ccm_aes128_decrypt_message(struct ccm_aes128_ctx *ctx, +ccm_aes128_decrypt_message(const struct aes128_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, @@ -241,14 +238,14 @@ ccm_aes192_digest(struct ccm_aes192_ctx *ctx, size_t length, uint8_t *digest); void -ccm_aes192_encrypt_message(struct ccm_aes192_ctx *ctx, +ccm_aes192_encrypt_message(const struct aes192_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t clength, uint8_t *dst, const uint8_t *src); int -ccm_aes192_decrypt_message(struct ccm_aes192_ctx *ctx, +ccm_aes192_decrypt_message(const struct aes192_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, @@ -285,14 +282,14 @@ ccm_aes256_digest(struct ccm_aes256_ctx *ctx, size_t length, uint8_t *digest); void -ccm_aes256_encrypt_message(struct ccm_aes256_ctx *ctx, +ccm_aes256_encrypt_message(const struct aes256_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, size_t clength, uint8_t *dst, const uint8_t *src); int -ccm_aes256_decrypt_message(struct ccm_aes256_ctx *ctx, +ccm_aes256_decrypt_message(const struct aes256_ctx *ctx, size_t nlength, const uint8_t *nonce, size_t alength, const uint8_t *adata, size_t tlength, diff --git a/nettle.texinfo b/nettle.texinfo index 3c021bc2..0037f743 100644 --- a/nettle.texinfo +++ b/nettle.texinfo @@ -3496,13 +3496,13 @@ passed to a function is always the size for the result, @var{clength} for the encryption functions, and @var{mlength} for the decryption functions. -@deftypefun void ccm_encrypt_message (void *@var{cipher}, nettle_cipher_func *@var{f}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{clength}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefun void ccm_encrypt_message (const void *@var{cipher}, nettle_cipher_func *@var{f}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{clength}, uint8_t *@var{dst}, const uint8_t *@var{src}) Computes the message digest from the @var{adata} and @var{src} parameters, encrypts the plaintext from @var{src}, appends the encrypted @acronym{MAC} to ciphertext and outputs it to @var{dst}. @end deftypefun -@deftypefun int ccm_decrypt_message (void *@var{cipher}, nettle_cipher_func *@var{f}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{mlength}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefun int ccm_decrypt_message (const void *@var{cipher}, nettle_cipher_func *@var{f}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{mlength}, uint8_t *@var{dst}, const uint8_t *@var{src}) Decrypts the ciphertext from @var{src}, outputs the plaintext to @var{dst}, recalculates the @acronym{MAC} from @var{adata} and the plaintext, and compares it to the final @var{tlength} bytes of @@ -3574,14 +3574,15 @@ These are identical to @code{ccm_set_digest}, except that @var{cipher}, @var{f}, and @var{ctx} are replaced with a context structure. @end deftypefun -@deftypefun void ccm_aes128_encrypt_message (struct ccm_aes128_ctx *@var{ctx}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{clength}, uint8_t *@var{dst}, const uint8_t *@var{src}) -@deftypefunx void ccm_aes192_encrypt_message (struct ccm_aes192_ctx *@var{ctx}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{clength}, uint8_t *@var{dst}, const uint8_t *@var{src}) -@deftypefunx void ccm_aes256_encrypt_message (struct ccm_aes256_ctx *@var{ctx}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{clength}, uint8_t *@var{dst}, const uint8_t *@var{src}) -@deftypefunx int ccm_aes128_decrypt_message (struct ccm_aes128_ctx *@var{ctx}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{mlength}, uint8_t *@var{dst}, const uint8_t *@var{src}) -@deftypefunx int ccm_aes192_decrypt_message (struct ccm_aes192_ctx *@var{ctx}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{mlength}, uint8_t *@var{dst}, const uint8_t *@var{src}) -@deftypefunx int ccm_aes256_decrypt_message (struct ccm_aes256_ctx *@var{ctx}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{mlength}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefun void ccm_aes128_encrypt_message (const struct aes128_ctx *@var{cipher}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{clength}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx void ccm_aes192_encrypt_message (const struct aes192_ctx *@var{cipher}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{clength}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx void ccm_aes256_encrypt_message (const struct aes256_ctx *@var{cipher}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{clength}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx int ccm_aes128_decrypt_message (const struct aes128_ctx *@var{cipher}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{mlength}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx int ccm_aes192_decrypt_message (const struct aes192_ctx *@var{cipher}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{mlength}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx int ccm_aes256_decrypt_message (const struct aes256_ctx *@var{cipher}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{tlength}, size_t @var{mlength}, uint8_t *@var{dst}, const uint8_t *@var{src}) These are identical to @code{ccm_encrypt_message} and @code{ccm_decrypt_message} -except that @var{cipher} and @var{f} are replaced with a context structure. +except that @var{cipher} is an AES context and the encryption function +@var{f} is implied. @end deftypefun @node ChaCha-Poly1305 diff --git a/testsuite/ccm-test.c b/testsuite/ccm-test.c index 4176cc7f..3401b1d4 100644 --- a/testsuite/ccm-test.c +++ b/testsuite/ccm-test.c @@ -50,7 +50,7 @@ test_compare_results(const char *name, const struct tstring *adata, /* Expected results. */ const struct tstring *e_clear, - const struct tstring *e_cipher, + const struct tstring *e_cipher, /* Actual results. */ const void *clear, const void *cipher, @@ -150,37 +150,43 @@ test_cipher_ccm(const struct nettle_cipher *cipher, /* Ensure we get the same answers using the all-in-one API. */ if (repeat <= 1) { - int ret; memset(de_data, 0, cleartext->length); memset(en_data, 0, ciphertext->length); - memset(de_digest, 0, sizeof(de_digest)); ccm_encrypt_message(ctx, cipher->encrypt, nonce->length, nonce->data, authdata->length, authdata->data, tlength, ciphertext->length, en_data, cleartext->data); - ret = ccm_decrypt_message(ctx, cipher->encrypt, nonce->length, nonce->data, - authdata->length, authdata->data, tlength, - cleartext->length, de_data, ciphertext->data); - - if (ret != 1) fprintf(stderr, "ccm_decrypt_message failed to validate message\n"); + if (!ccm_decrypt_message(ctx, cipher->encrypt, nonce->length, nonce->data, + authdata->length, authdata->data, tlength, + cleartext->length, de_data, ciphertext->data)) + { + fprintf(stderr, "ccm_decrypt_message failed to validate message\n"); + FAIL(); + } test_compare_results("CCM_MSG", authdata, cleartext, ciphertext, de_data, en_data, NULL); /* Ensure that we can detect corrupted message or tag data. */ if (tlength) { en_data[0] ^= 1; - ret = ccm_decrypt_message(ctx, cipher->encrypt, nonce->length, nonce->data, - authdata->length, authdata->data, tlength, - cleartext->length, de_data, en_data); - if (ret != 0) fprintf(stderr, "ccm_decrypt_message failed to detect corrupted message\n"); + if (ccm_decrypt_message(ctx, cipher->encrypt, nonce->length, nonce->data, + authdata->length, authdata->data, tlength, + cleartext->length, de_data, en_data)) + { + fprintf(stderr, "ccm_decrypt_message failed to detect corrupted message\n"); + FAIL(); + } } /* Ensure we can detect corrupted adata. */ if (tlength && authdata->length) { - ret = ccm_decrypt_message(ctx, cipher->encrypt, nonce->length, nonce->data, - authdata->length-1, authdata->data, tlength, - cleartext->length, de_data, ciphertext->data); - if (ret != 0) fprintf(stderr, "ccm_decrypt_message failed to detect corrupted message\n"); + if (ccm_decrypt_message(ctx, cipher->encrypt, nonce->length, nonce->data, + authdata->length-1, authdata->data, tlength, + cleartext->length, de_data, ciphertext->data)) + { + fprintf(stderr, "ccm_decrypt_message failed to detect corrupted message\n"); + FAIL(); + } } } @@ -212,6 +218,23 @@ test_cipher_ccm(const struct nettle_cipher *cipher, test_compare_results("CCM_AES_128", authdata, cleartext, ciphertext, de_data, en_data, de_digest); + if (repeat <= 1) + { + memset(de_data, 0, cleartext->length); + memset(en_data, 0, ciphertext->length); + ccm_aes128_encrypt_message (ctx, nonce->length, nonce->data, + authdata->length, authdata->data, tlength, + ciphertext->length, en_data, cleartext->data); + if (!ccm_aes128_decrypt_message(ctx, nonce->length, nonce->data, + authdata->length, authdata->data, tlength, + cleartext->length, de_data, ciphertext->data)) + { + fprintf(stderr, "ccm_aes128_decrypt_message failed to validate message\n"); + FAIL(); + } + test_compare_results("CCM_AES_128_MSG", authdata, + cleartext, ciphertext, de_data, en_data, NULL); + } } /* TODO: I couldn't find any test cases for CCM-AES-192 */ if (cipher == &nettle_aes256) { @@ -241,6 +264,23 @@ test_cipher_ccm(const struct nettle_cipher *cipher, test_compare_results("CCM_AES_256", authdata, cleartext, ciphertext, de_data, en_data, de_digest); + if (repeat <= 1) + { + memset(de_data, 0, cleartext->length); + memset(en_data, 0, ciphertext->length); + ccm_aes256_encrypt_message (ctx, nonce->length, nonce->data, + authdata->length, authdata->data, tlength, + ciphertext->length, en_data, cleartext->data); + if (!ccm_aes256_decrypt_message(ctx, nonce->length, nonce->data, + authdata->length, authdata->data, tlength, + cleartext->length, de_data, ciphertext->data)) + { + fprintf(stderr, "ccm_aes256_decrypt_message failed to validate message\n"); + FAIL(); + } + test_compare_results("CCM_AES_256_MSG", authdata, + cleartext, ciphertext, de_data, en_data, NULL); + } } free(ctx); -- 2.47.3