On Wed, 2018-01-24 at 09:46 +0100, Niels Möller wrote:
>
> > > So then we'de have something similar to the ccm_*_message
> > > functions.
> > > Should the nonce length and tag length be variable per message?
> >
> > The tag is fixed since it is used as the IV. On the branch I'm
> > working
> > on I have the following interface:
> >
> > struct siv_aes128_cmac_ctx {
> > struct aes128_ctx cipher;
> > uint8_t s2vk[AES128_KEY_SIZE];
> > };
> >
> > void
> > siv_aes128_cmac_set_key(struct siv_aes128_cmac_ctx *ctx, const
> > uint8_t *key);
> >
> > void
> > siv_aes128_cmac_encrypt_message(struct siv_aes128_cmac_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
> > siv_aes128_cmac_decrypt_message(struct siv_aes128_cmac_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);
>
> I think this is the right level for most applications. But I'm a bit
> confused with regards to my questions. Are the tlength and nlength
> arguments useful (for siv, and and for aead in general)?
The tag length is not. There is an assert in my current code to ensure
its value is right. I've keeped this interface compatible with the CCM
version (assuming that this will be the generic AEAD interface).
The nlength is variable (0 or more) on SIV so it makes sense to have it
there.
> Or should at least tag length be considered parameter of the aead
> algorithm, not something which can vary from message to message?
In CCM removing the tag length will require to introduce a new
interface for CCM-8 vs CCM-16. Other modes like GCM can also use
shorter auth tags, thus fixing the tag to the interface would require a
handful of new functions for each tag length possibility.
> For hashes and macs, use of truncated outputs seemed fairly common,
> which is why the current interfaces includes a digest length
> argument.
Right, RFC5116's text for AEAD ciphers says about tags:
"Each AEAD algorithm MUST provide a description relating the length of
the plaintext to that of the ciphertext. This relation MUST NOT
depend on external parameters, such as an authentication strength
parameter (e.g., authentication tag length). That sort of
dependence
would complicate the use of the algorithm by creating a situation in
which the information from the AEAD registry was not sufficient to
ensure interoperability."
(from https://tools.ietf.org/html/rfc5116#section-4 )
So I think that when implementing that API, the tag should be indeed
implicit per AEAD cipher, meaning that CCM-8 should be treated
differently to CCM-16, as well as any GCM variants. The current nettle
interface allows more flexibility in that aspect at the cost of another
function parameter.
> But aeads are a bit different. For SIV, would a shortened tag just
> reduce the strength of authentication, or would it make it impossible
> to decrypt the message?
It is not possible in the sense that the IV should be 128-bits and
having a shortened tag to be used as IV wouldn't be possible by
following the protocol.
> > I think the expectation is to prepend the tag/IV to the message. As
> > the message interface above doesn't distinguish between tag and
> > ciphertext, I think it quite conveniently fits it.
>
> For authenticated decryption one needs three pieces of data:
>
> 1. The nonce.
>
> 2. The ciphertext.
>
> 3. The tag.
>
> The nonce should most likely be a separate argument, it might not be
> attached at all to the data on the wire. E.g., it could be derived
> from an implicit message number.
>
> The current ccm_*_ message functions represents ciphertext and tag as
> a single blob,
>
> +--------------+-------+
> | ciphertext | tag |
> +--------------+-------+
>
> It seems you're saying that for siv, you put them together in the
> opposite order,
>
> +-------+--------------+
> | tag | ciphertext |
> +-------+--------------+
>
> Should we treat the encrypted message as a single blob, with any
> internal structure being an internal detail of the aead? That seems
> to be the RFC 5116 view.
I think that's reasonable expectation.
> In case there are protocols or applications that specify that
> ciphertext
> and tag are sent/stored as separately byte strings, we would need to
> expose that distinction in the api. E.g., say we do in-place
> block-by-block encryption on disk, and treat nonce and tag for each
> block as metadata, stored elsewhere.
I'm not sure whether that's a possibility. A protocol which would use
an AEAD cipher (e.g., like NTP), would use the formatting required by
the AEAD cipher.
> > A possible interface could be:
> > void siv_aes128_cmac_set_key(struct siv_aes128_cmac_ctx *ctx, const
> > uint8_t *key)
> > void siv_aes128_cmac_s2v(struct siv_aes128_cmac_ctx *ctx, size_t
> > nlength, const uint8_t *nonce,
> > size_t adatalen, size_t *alength, const
> > uint8_t **adata,
> > size_t plength, size_t pdata);
> >
> > (notice the pointer to pointer for adata)
>
> I think I'd prefer something like
>
> void
> siv_aes128_cmac_extra_adata(struct siv_aes128_cmac_ctx *ctx,
> size_t length, const uint8_t *data);
>
> to be called zero or more times between _set_key and the call with
> the
> body of the message. (Probably need a separate set_nonce function
> too,
> if nonce must be known before processing and associated data).
But then when would generate the actual IV? When data are added
gradually, one would have to require order in the calling of functions,
to ensure that one would generate the IV to be used by the encryption
functions. For example require
siv_aes128_cmac_set_key
siv_aes128_cmac_extra_adata
siv_aes128_cmac_extra_adata
siv_aes_128_cmac_set_nonce (must be last and must be called even if
there is no nonce, and will generate and save the IV)
siv_aes128_cmac_decrypt (which will use the saved in ctx IV)
or
siv_aes128_cmac_set_key
siv_aes128_cmac_extra_adata
siv_aes128_cmac_extra
_adata
siv_aes_128_cmac_set_nonce
siv_aes_128_cmac_get_iv
siv_aes128_cmac_
decrypt (which will use the provided in param IV)
I'm also not sure how to check the tag? Make siv_aes128_cmac_decrypt()
check it and return an int, or provide a digest function which will
return the generated IV and let the caller do something with it?
Shouldn't the siv_aes128_cmac_extra_adata be named
siv_aes128_cmac_update? (though its semantics would be different from
other AEAD ciphers as updating with "ab" is different than two calls
with "a" and "b").
Overall, the more I look how a low level API for SIV would look like,
the more I think having only a high level one.
regards,
Nikos
_______________________________________________
nettle-bugs mailing list
[email protected]
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs