[RFC PATCH 2/3] Add API for initializing AEAD modes
jussi.kivilinna at iki.fi
Wed Oct 16 11:05:06 CEST 2013
On 15.10.2013 16:46, Werner Koch wrote:
> On Mon, 14 Oct 2013 13:20, jussi.kivilinna at iki.fi said:
>> I based CCM patchset on the AEAD API patch Dmitry sent earlier for
>> GCM. Since CCM has more restrictions (need to know data lengths in
>> advance) than GCM, I added gcry_cipher_aead_init.
> I forgot about this because I delayed that far too long. Sorry.
>> With this patchset to encrypt a buffer using CCM, you'd first need to
>> initialize/reset CCM state with:
>> gcry_cipher_aead_init (hd, nonce_buf, nonce_len, authtag_len, plaintext_len)
>> CCM needs tag and plaintext lengths for MAC initialization. CCM also
> Up until now we use separate functions to set key, IV, and counter.
> This function changes this pattern. Why not reusing setiv for the
> nonce and adding a function for the authentication tag?
Sure, setiv can be reused.
> Is the plaintext length really required in advance? That is
> embarrassing in particular because the authenticated data is appended to
> the ciphertext.
Yes, this is really the case with CCM. The first block to CBC-MAC contains
length of encrypted message.. from RFC:
The first block B_0 is formatted as follows, where l(m) is encoded in
most-significant-byte first order:
Octet Number Contents
1 ... 15-L Nonce N
16-L ... 15 l(m)
Flags encodes the length of length field (L), tag length and an AAD flag.
>> gcry_cipher_authenticate (hd, aadbuf, aadbuflen)
>> which does the actual MAC initialization. If aadbuflen == 0, then
>> above call can be omitted and gcry_cipher_(en|de)crypt will call
>> gcry_cipher_authenticate with zero length.
> What about extending this fucntion to also take the authentication tag
> and, if the plaintext length is required for the MAC setup, also that
> length? That would group the information together.
Ok, so we'd have
gcry_cipher_authenticate (hd, const void *aadbuf, size_t aadbuflen,
count void *tag, size_t taglen, size_t crypt_len)
For encryption, tag is NULL pointer and taglen is zero and after encryption
authentication tag can be read with 'gcry_cipher_tag'. For decryption, tag
is given for authentication check with above function.
Also (at least) for CCM, encrypt_len needs to be given.
>> NIST paper and RFC 3610 define CCM ciphertext as [ctr-enc(plaintext)
>> || authtag] and that decryption must not reveal any information
>> (plaintext or authtag) if authtag is not correct. Therefore full
>> buffers, matching with length of plaintext_len and authtag_len given
>> in gcry_cipher_aead_init, have to be used. If authentication check
> I don't see that. That is an implementaion detail and the requirement
> could also be achieved by putting it into the security policy.
>> Would it be better to add functions to do AEAD encrypt/decrypt in
>> single go and use gcry_buffer_t? This would avoid having internal
>> state machines in AEAD modes and having to call different functions in
>> correct order.
> And it also means that you can't use that mode with large amounts of
> data. Not a good idea; there are still lots of platforms with a quite
> limited amount of memory but in need to encrypt large data take from
> somewhere. Yes, the need for the plaintext length makes it hard to use
> but I can image systems which know that length on advance even if the
> data does not fit into memory.
Agreed and not all AEAD modes require plaintext length in advance.
> I mentioned gcry_buffer_t having the AAD in mind; a scatter/gather style
> operation may be useful here.
> We should also keep in mind that adding support for OCB is desirable. I
> had in mind to require the use of a new GCRYCTL_ENABLE_GPL_CODE to state
> that Libgcrypt is used under the terms of the GPL. However, meanwhile
> Phil Rogaway relaxed the requirement for royalty free patent licensing
> to all free software licenses and thus we could simply got forth and
> implement OCB. Any new API should make it easy to do just that.
More information about the Gcrypt-devel