Here's a first stab at assembling some documentation about CCM mode and its API. It's probably still in need some some good proofreading for grammar and consistency.
Some minor nits that I noticed about the API while writing it: - ccm_decrypt_message uses const void * for the cipher context, but all the other interfaces use void * for this. - passing the clength rather mlength to ccm_decrypt_message could be a little confusing when compared to the rest of the API. In retrospect, I think Neils's initial suggestion on this API was probably the better way to go.
Cheers, Owen
From 0b0651a6e754652d9ce1aa7c2f6f7cbc3fc498bc Mon Sep 17 00:00:00 2001
From: Owen Kirby osk@exegin.com Date: Sat, 12 Apr 2014 21:31:39 -0700 Subject: [PATCH] Added CCM mode to the documentation.
--- nettle.texinfo | 225 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 224 insertions(+), 1 deletion(-)
diff --git a/nettle.texinfo b/nettle.texinfo index 68883a5..c988eb6 100644 --- a/nettle.texinfo +++ b/nettle.texinfo @@ -88,6 +88,7 @@ Cipher modes * CBC:: * CTR:: * GCM:: +* CCM::
Public-key algorithms
@@ -1788,6 +1789,7 @@ signature to authenticate the message. * CBC:: * CTR:: * GCM:: +* CCM:: @end menu
@@ -1960,7 +1962,7 @@ last three arguments define the source and destination area for the operation. @end deffn
-@node GCM, , CTR, Cipher modes +@node GCM, CCM, CTR, Cipher modes @comment node-name, next, previous, up @subsection Galois counter mode
@@ -2153,7 +2155,228 @@ equal to @code{GCM_BLOCK_SIZE}, but if you provide a smaller value, only the first @var{length} octets of the digest are written. @end deftypefun
+@node CCM, , GCM, Cipher modes +@comment node-name, next, previous, up +@subsection Counter with CBC-MAC mode + +@cindex Counter with CBC-MAC Mode +@cindex CCM Mode + +CCM mode is the combination of counter mode with message authentication based on +cipher block chaining. It is constructed on top of a block cipher which must +have a block size of 128 bits. @acronym{CCM} mode is recommended by NIST in +@uref{http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_..., +NIST Special Publication 800-38C}. Nettle's support for CCM consists of a +low-level general interface, a message encryption and authentication interface, +and specific functions for CCM using AES as the underlying block cipher. These +interfaces are defined in @file{<nettle/ccm.h>} + +The inputs to @acronym{CCM} are: +@itemize +@item +A key, which can be used for many messages. +@item +A parameter @var{L} which determines the size of the nonce and the maximum +length of message data which can be processed by @acronym{CCM}. +@item +A tag length, which must be a multiple of 4 bytes up to a maximum of one block. +@item +A nonce which @emph{must} be unique for each message. +@item +Optional authenticated data, which is to be included in the message +authentication, but not encrypted. +@item +The plaintext. May be empty. +@end itemize + +The outputs from @acronym{CCM} are: +@itemize +@item +The ciphertext of the same length as the plaintext. +@item +An encrypted authentication tag, up to one block on length. +@end itemize + +The parameter @var{L} determines the size of the counter that is used for the +message length, such that the maximum message length in bytes is given by +@code{maxlength = (1 << L) - 1}. However increasing @var{L} also restricts the +size of the nonce such that @code{noncelength = CCM_BLOCK_SIZE - 1 - L}, and +throughout this interface the parameter @var{L} is provided implicitly by the +nonce length. + +@acronym{CCM} mode encryption operates as follows: +@itemize +@item The nonce and message length are concatenated to create + @code{B_0 = flags | nonce | mlength} +@item The authenticated data and plaintext is formatted into the string + @code{B = L(adata) | adata | padding | plaintext | padding} with @code{padding} + being the shortest string of zero bytes such that the length of the string is + a multiple of the block size, and @code{L(adata)} is an encoding of the + length of @code{adata}. +@item The string @code{B} is separated into blocks @code{B_1} ... @code{B_n} +@item The authentication tag @code{T} is calculated as + @code{T=0, for i=0 to n, do T = E_k(B_i XOR T)} + +@item An initial counter is then initialized from the nonce to create + @code{IC = flags | nonce | padding}, where @code{padding} is the shortest + string of zero bytes such that @code{IC} is exactly one block in length. +@item The authentication tag is encrypted using using @acronym{CTR} mode: + @code{MAC = E_k(IC) XOR T} +@item The plaintext is then encrypted using @acronym{CTR} mode with an initial + counter of @code{IC+1}. +@end itemize + +@acronym{CCM} mode decryption operates similarly, except that the ciphertext +and @acronym{MAC} are first decrypted using CTR mode to retreive the plaintext +and authentication tag. The authentication tag can then be recalucated from the +authenticated data and plantext, and compared to the value in the message to +check for authenticity. + +@subsubsection General @acronym{CCM} interface + +For all of the functions in the @acronym{CCM} interface, @var{cipher} is the +context struct for the underlying cipher and @var{f} is the encryption function. +The cipher's encryption key must be set before calling any of the @acronym{CCM} +functions. The cipher's decryption function and key are never used. + +@deftp {Context struct} {struct ccm_ctx} +Holds state corresponding to a particular message. +@end deftp + +@defvr Constant CCM_BLOCK_SIZE +@acronym{CCM}'s block size, 16. +@end defvr + +@deftypefun void ccm_set_nonce (struct ccm_ctx *@var{ctx}, void *@var{cipher}, nettle_crypt_func *@var{f}, size_t @var{noncelen}, const uint8_t *@var{nonce}, size_t @var{authlen}, size_t @var{msglen}, size_t @var{taglen}) +Initializes @var{ctx} using the given nonce and the sizes of the authenticated +data, message, and @acronym{MAC} to be processed. +@end deftypefun + +@deftypefun void ccm_update (struct ccm_ctx *@var{ctx}, void *@var{cipher}, nettle_crypt_func *@var{f}, size_t @var{length}, const uint8_t *@var{data}) +Provides associated data to be authenticated. Must be called after +@code{ccm_set_nonce}, and before @code{ccm_encrypt}, @code{ccm_decrypt}, or +@code{ccm_digest}. +@end deftypefun + +@deftypefun void ccm_encrypt (struct ccm_ctx *@var{ctx}, void *@var{cipher}, nettle_crypt_func *@var{f}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx void ccm_decrypt (struct ccm_ctx *@var{ctx}, void *@var{cipher}, nettle_crypt_func *@var{f}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +Encrypts or decrypts the message data. Must be called after @code{ccm_set_nonce} +and before @code{ccm_digest}. All but the last call for each message @emph{must} +use a length that is a multiple of the block size. +@end deftypefun + +@deftypefun void ccm_digest (struct ccm_ctx *@var{ctx}, void *@var{cipher}, nettle_crypt_func *@var{f}, size_t @var{length}, uint8_t *@var{digest}) +Extracts the message digest (also known ``authentication tag''). This is +the final operation when processing a message. @var{length} is usually +equal to the @var{taglen} parameter supplied to @code{ccm_set_nonce}, but if you +provide a smaller value, only the first @var{length} octets of the digest are +written. +@end deftypefun + +To encrypt a message using the general @acronym{CCM} interface, set the message +nonce and length using @code{ccm_set_nonce} and then call @code{ccm_update} to +generate the digest of any authenticated data. After all of the authenticated +data has been digested use @code{ccm_encrypt} to encrypt the plaintext. Finally, +use @code{ccm_digest} to return the encrypted @acronym{MAC}. + +To decrypt a message, use @code{ccm_set_nonce} and @code{ccm_update} the same as +you would for encryption, and then call @code{ccm_decrypt} to decrypt the +ciphertext. After decrypting the ciphertext @code{ccm_digest} will return the +encrypted @acronym{MAC} which should be identical to the @acronym{MAC} in the +received message. + +@subsubsection @acronym{CCM} message interface + +The @acronym{CCM} message fuctions provides a simple interface that will +perform authentication and message encryption in a single function call. The +length of the ciphertext is given by @var{clength}, and it is always exactly +@var{tlength} bytes longer than the corresponding plaintext. The length of the +plaintext is not provided explicitly in this interface, as it would always have +a value of @var{mlength} = @var{clength} - @var{tlength}. + +@deftypefun void ccm_encrypt_message (void *@var{cipher}, nettle_crypt_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_crypt_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}) +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 @var{src}. If the values of the received +and calculated @acronym{MAC}s are equal, this will return 1 indicating a valid +and authenticated message. Otherwise, this function will return zero. +@end deftypefun + +@subsubsection @acronym{CCM}-@acronym{AES} interface + +The @acronym{AES} @acronym{CCM} functions provide an API for using @acronym{CCM} +mode with the @acronym{AES} block ciphers. The parameters all have the same +meaning as the general and message interfaces, except that the @var{cipher}, +@var{f}, and @var{ctx} parameters are replaced with an @acronym{AES} context +structure, and a set-key function must be called before using any of the other +functions in this interface.
+@deftp {Context struct} {struct ccm_aes128_ctx} +Holds state corresponding to a particular message encrypted using the AES-128 block cipher. +@end deftp + +@deftp {Context struct} {struct ccm_aes192_ctx} +Holds state corresponding to a particular message encrypted using the AES-192 block cipher. +@end deftp + +@deftp {Context struct} {struct ccm_aes256_ctx} +Holds state corresponding to a particular message encrypted using the AES-256 block cipher. +@end deftp + +@deftypefun void ccm_aes128_set_key (struct ccm_aes128_ctx *@var{ctx}, const void *@var{key}) +@deftypefunx void ccm_aes192_set_key (struct ccm_aes192_ctx *@var{ctx}, const void *@var{key}) +@deftypefunx void ccm_aes256_set_key (struct ccm_aes256_ctx *@var{ctx}, const void *@var{key}) +Initializes the encryption key for the AES block cipher. One of these functions +must be called before any of the other functions in the @acronym{AES} +@acronym{CCM} interface. +@end deftypefun + +@deftypefun void ccm_aes128_set_nonce (struct ccm_aes128_ctx *@var{ctx}, size_t @var{noncelen}, const uint8_t *@var{nonce}, size_t @var{authlen}, size_t @var{msglen}, size_t @var{taglen}) +@deftypefunx void ccm_aes192_set_nonce (struct ccm_aes192_ctx *@var{ctx}, size_t @var{noncelen}, const uint8_t *@var{nonce}, size_t @var{authlen}, size_t @var{msglen}, size_t @var{taglen}) +@deftypefunx void ccm_aes256_set_nonce (struct ccm_aes256_ctx *@var{ctx}, size_t @var{noncelen}, const uint8_t *@var{nonce}, size_t @var{authlen}, size_t @var{msglen}, size_t @var{taglen}) +These are identical to @code{ccm_set_nonce}, except that @var{cipher}, +@var{f}, and @var{ctx} are replaced with a context structure. +@end deftypefun + +@deftypefun void ccm_aes128_update (struct ccm_aes128_ctx *@var{ctx}, size_t @var{length}, const uint8_t *@var{data}) +@deftypefunx void ccm_aes192_update (struct ccm_aes192_ctx *@var{ctx}, size_t @var{length}, const uint8_t *@var{data}) +@deftypefunx void ccm_aes256_update (struct ccm_aes256_ctx *@var{ctx}, size_t @var{length}, const uint8_t *@var{data}) +These are identical to @code{ccm_set_update}, except that @var{cipher}, +@var{f}, and @var{ctx} are replaced with a context structure. +@end deftypefun + +@deftypefun void ccm_aes128_encrypt (struct ccm_aes128_ctx *@var{ctx}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx void ccm_aes192_encrypt (struct ccm_aes192_ctx *@var{ctx}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx void ccm_aes256_encrypt (struct ccm_aes256_ctx *@var{ctx}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx void ccm_aes128_decrypt (struct ccm_aes128_ctx *@var{ctx}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx void ccm_aes192_decrypt (struct ccm_aes192_ctx *@var{ctx}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx void ccm_aes256_decrypt (struct ccm_aes256_ctx *@var{ctx}, size_t @var{length}, uint8_t *@var{dst}, const uint8_t *@var{src}) +These are identical to @code{ccm_set_encrypt} and @code{ccm_set_decrypt}, except +that @var{cipher}, @var{f}, and @var{ctx} are replaced with a context structure. +@end deftypefun + +@deftypefun void ccm_aes128_digest (struct ccm_aes128_ctx *@var{ctx}, size_t @var{length}, uint8_t *@var{digest}) +@deftypefunx void ccm_aes192_digest (struct ccm_aes192_ctx *@var{ctx}, size_t @var{length}, uint8_t *@var{digest}) +@deftypefunx void ccm_aes256_digest (struct ccm_aes256_ctx *@var{ctx}, size_t @var{length}, uint8_t *@var{digest}) +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{clength}, 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{clength}, uint8_t *@var{dst}, const uint8_t *@var{src}) +@deftypefunx int ccm_aes192_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{clength}, 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. +@end deftypefun
@node Keyed hash functions, Key derivation functions, Cipher modes, Reference @comment node-name, next, previous, up
Owen Kirby osk@exegin.com writes:
Here's a first stab at assembling some documentation about CCM mode and its API.
Thanks! You are aware that the manual is licensed as public domain, is that ok with you?
Some minor nits that I noticed about the API while writing it:
- ccm_decrypt_message uses const void * for the cipher context, but all the other interfaces use void * for this.
Can you be more specific? I think it should be const void * everywhere, and I see no void * in the version of ccm.h which is in the repo. That's one of the things I changed when integrating it.
- passing the clength rather mlength to ccm_decrypt_message could be a little confusing when compared to the rest of the API. In retrospect, I think Neils's initial suggestion on this API was probably the better way to go.
If I remember correctly, we agreed that when we pass the triple (length, dst, src), and the src and destination areas are of diferent sizes, then it's best to adopt the convention that length always is the size of the destination area?
Which then means that ccm_encrypt_message should take clength (length of ciphertext) and ccm_decrypt_message should be changed to take mlength (length of cleartext).
+The inputs to @acronym{CCM} are: +@itemize +@item +A key, which can be used for many messages. +@item +A parameter @var{L} which determines the size of the nonce and the maximum +length of message data which can be processed by @acronym{CCM}. +@item +A tag length, which must be a multiple of 4 bytes up to a maximum of one block. +@item +A nonce which @emph{must} be unique for each message. +@item +Optional authenticated data, which is to be included in the message +authentication, but not encrypted. +@item +The plaintext. May be empty. +@end itemize
+The outputs from @acronym{CCM} are: +@itemize +@item +The ciphertext of the same length as the plaintext. +@item +An encrypted authentication tag, up to one block on length. +@end itemize
+The parameter @var{L} determines the size of the counter that is used for the +message length, such that the maximum message length in bytes is given by +@code{maxlength = (1 << L) - 1}. However increasing @var{L} also restricts the +size of the nonce such that @code{noncelength = CCM_BLOCK_SIZE - 1 - L}, and +throughout this interface the parameter @var{L} is provided implicitly by the +nonce length.
I think it would be good with a bit more focus on how the caller should select the nonce size. I'd expect that 12 bytes nonce (and the corresponding limit on message size) is the most widely used, following RFC 5116.
What happens if the caller specifies an invalid combination of nonce size and message size? Will it trigger some assert, or will the counter wrap around silently?
Regards, /Niels
On 14-04-13 12:51 AM, Niels Möller wrote:
Owen Kirby osk@exegin.com writes:
Here's a first stab at assembling some documentation about CCM mode and its API.
Thanks! You are aware that the manual is licensed as public domain, is that ok with you?
That is ok with me.
Some minor nits that I noticed about the API while writing it:
- ccm_decrypt_message uses const void * for the cipher context, but all the other interfaces use void * for this.
Can you be more specific? I think it should be const void * everywhere, and I see no void * in the version of ccm.h which is in the repo. That's one of the things I changed when integrating it.
Ah, you are right. The I must have copy-pasted the non-const versions from the GCM section of the docs, which hasn't been updated yet to agree with the const void* used in the source. I'll make sure to change them back to const void*
- passing the clength rather mlength to ccm_decrypt_message could be a little confusing when compared to the rest of the API. In retrospect, I think Neils's initial suggestion on this API was probably the better way to go.
If I remember correctly, we agreed that when we pass the triple (length, dst, src), and the src and destination areas are of diferent sizes, then it's best to adopt the convention that length always is the size of the destination area?
Which then means that ccm_encrypt_message should take clength (length of ciphertext) and ccm_decrypt_message should be changed to take mlength (length of cleartext).
Noted, I'll make an update accordingly.
+The inputs to @acronym{CCM} are: +@itemize +@item +A key, which can be used for many messages. +@item +A parameter @var{L} which determines the size of the nonce and the maximum +length of message data which can be processed by @acronym{CCM}. +@item +A tag length, which must be a multiple of 4 bytes up to a maximum of one block. +@item +A nonce which @emph{must} be unique for each message. +@item +Optional authenticated data, which is to be included in the message +authentication, but not encrypted. +@item +The plaintext. May be empty. +@end itemize
+The outputs from @acronym{CCM} are: +@itemize +@item +The ciphertext of the same length as the plaintext. +@item +An encrypted authentication tag, up to one block on length. +@end itemize
+The parameter @var{L} determines the size of the counter that is used for the +message length, such that the maximum message length in bytes is given by +@code{maxlength = (1 << L) - 1}. However increasing @var{L} also restricts the +size of the nonce such that @code{noncelength = CCM_BLOCK_SIZE - 1 - L}, and +throughout this interface the parameter @var{L} is provided implicitly by the +nonce length.
I think it would be good with a bit more focus on how the caller should select the nonce size. I'd expect that 12 bytes nonce (and the corresponding limit on message size) is the most widely used, following RFC 5116.
What happens if the caller specifies an invalid combination of nonce size and message size? Will it trigger some assert, or will the counter wrap around silently?
The last line in ccm_build_iv will assert if the counter rolls over when forming the IV. There are no checks for rollovers when incrementing the CTR, but to do that one would have to encrypt more than (1 << (L*8)) blocks of data, and at least 16 times the amount of data that was specified in the callto ccm_set_nonce
It also occurs to me that the my formula for calculating the maximum message size from L is completely wrong. L basically specifies the size of the counter field (in bytes), so it should really be maxlength = (1 << (L*8)) - 1.
Most protocols focus on maximizing the length of the nonce, since messages seldomly exceed a few kilobytes and you want to get as much entropy into the IV as possible. Off the top of my head, I think most IETF protocols use a nonce of 12 bytes while the IEEE 802.15.4 and ZigBee use a nonce of 13 bytes. I'll try to put together a few official-sounding words on the topic.
Cheers, Owen
Owen Kirby osk@exegin.com writes:
It also occurs to me that the my formula for calculating the maximum message size from L is completely wrong. L basically specifies the size of the counter field (in bytes), so it should really be maxlength = (1 << (L*8)) - 1.
I think it would be nice with some public macro in ccm.h which gives the maximum message size for a given nonce size, together with constants CCM_MIN_NONCE_SIZE and CCM_MAX_NONCE_SIZE. There should be some reasonably easy way for an application to check if potential ccm parameters are valid.
If I read ccm.c correctly, nonce size is in the range 7...14 bytes, inclusive.
Regards, /Niels
Owen Kirby osk@exegin.com writes:
It also occurs to me that the my formula for calculating the maximum message size from L is completely wrong. L basically specifies the size of the counter field (in bytes), so it should really be maxlength = (1 << (L*8)) - 1.
Is the following correct? Intended for ccm.h:
/* Maximum cleartext message size, as a function of the nonce size N. The length field is L octets, with L = 15 - N, and then the maximum size M = 2^{8L} - 1. */ #define CCM_MAX_MSG_SIZE(N) \ ((sizeof(size_t) + (N) <= 15) \ ? ~(size_t) 0 \ : ((size_t) 1 << (8*(15 - N))) - 1)
Regards, /Niels
Niels,
Yep, that looks good.
Thanks, Owen
On 14-04-29 10:16 AM, Niels Möller wrote:
Owen Kirby osk@exegin.com writes:
It also occurs to me that the my formula for calculating the maximum message size from L is completely wrong. L basically specifies the size of the counter field (in bytes), so it should really be maxlength = (1 << (L*8)) - 1.
Is the following correct? Intended for ccm.h:
/* Maximum cleartext message size, as a function of the nonce size N. The length field is L octets, with L = 15 - N, and then the maximum size M = 2^{8L} - 1. */ #define CCM_MAX_MSG_SIZE(N) \ ((sizeof(size_t) + (N) <= 15) \ ? ~(size_t) 0 \ : ((size_t) 1 << (8*(15 - N))) - 1)
Regards, /Niels
Owen Kirby osk@exegin.com writes:
Yep, that looks good.
I've now added CCM_MAX_MSG_SIZE() and constants CCM_MIN_NONCE_SIZE, CC_MAX_NONCE_SIZE, CCM_DIGEST_SIZE, and updated the docs a bit.
Regards, /Niels
Owen Kirby osk@exegin.com writes:
Here's a first stab at assembling some documentation about CCM mode and its API. It's probably still in need some some good proofreading for grammar and consistency.
I've checked in these docs now, with fixes as below. Thanks!
Some minor nits that I noticed about the API while writing it:
- ccm_decrypt_message uses const void * for the cipher context, but all the other interfaces use void * for this.
Fixed to document const void *.
- passing the clength rather mlength to ccm_decrypt_message could be a little confusing when compared to the rest of the API. In retrospect, I think Neils's initial suggestion on this API was probably the better way to go.
Fixed, both in the docs and the code.
Not yet done: Fixing the logic for deriving the maxumum mesage size from the nocne size. Public macros for computing maximum message size for a given nonce, and documentation of these and general nonce size issues.
Do you think you can have a look at that soon?
Regards, /Niels
nettle-bugs@lists.lysator.liu.se