[RFC PATCH 2/3] Add API for initializing AEAD modes

Jussi Kivilinna 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
      ------------   ---------
      0              Flags
      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.
> Shalom-Salam,
>    Werner

More information about the Gcrypt-devel mailing list