nisse@lysator.liu.se (Niels Möller) writes:
Owen Kirby osk@exegin.com writes:
--- /dev/null +++ b/ccm.h +/* Obnoxiously, CCM mode requires the adata and message lengths when
- building the IV. This prevents any sort of streaming type API to
- the cipher mode. We chose to put all of that cruft in the set_nonce()
- function, so that the update/encrypt/decrypt and digest functions will
- remain compatible with the nettle AEAD API.
- */
+void +ccm_set_nonce(struct ccm_ctx *ctx, size_t noncelen, const uint8_t *nonce,
size_t authlen, size_t msglen, size_t taglen);
Are there any alternative ways to design this interface? E.g., one could specify that for ccm, the update and encrypt/decrypt functions may be called at most once for each message, with no possibility for streaming or incremental processing. But that won't help if one needs *both* lengths before processing either the message data or the associated data.
It looks like that isn't possible. Reading the code (I haven't read the spec yet), it seems like the message length must be known before processing of the associated data.
However we decide to do the incremental interface for CCM, I think it would be good to also provide an all-in-one function, something like
void ccm_encrypt_message (void *cipher_ctx, nettle_crypt_func *f, size_t nonce_length, const uint8_t *nonce, size_t adata_length, const uint8_t *adata, size_t tag_length, size_t msg_length, uint8_t *dst, const uint8_t *src);
/* Return 1 on success, 0 on authentication failure */ int ccm_decrypt_message (void *cipher_ctx, nettle_crypt_func *f, size_t nonce_length, const uint8_t *nonce, size_t adata_length, const uint8_t *adata, size_t tag_length, size_t msg_length, uint8_t *dst, const uint8_t *src);
(since CCM doesn't quite fit in Nettle's aead framework, it can't easily use any general construction on top of that framework). But there are usecases where incremental processing is desired. E.g, processing a large file (size limited to 16 MB - 1 byte with RFC 5116 parameters for CCM, so maybe not *extremely* large), where you could know the size in advance, e.g., from stat(2), but still might want to do the processing with an i/o buffer in memory limited to, say, 64 KB.
Regards, /Niels