ni...@lysator.liu.se (Niels Möller) writes:

> Owen Kirby is working on an implementation of the CCM mode. I'm
> forwarding my comments here (with permission).

Ooops, I got bitten by the bad mailman configuration regarding
attachments. New attempt below. /Niels

Owen Kirby <o...@exegin.com> writes:

> I've been looking at trying to add some of the AES-CCM mode cipher suites to 
> GnuTLS.
> It seemed like the best way to start would be to add support for them to 
> nettle, and
> this is what I've come up with so far.

Makes sense to me.

> These cipher modes are a combination of a CTR encryption with a CBC-MAC, they 
> are
> technically an AEAD cipher mode, but there are some weird parameters that 
> need to be
> passed to the nonce function that make it unlikely to work well with the 
> nettle_aead 
> API.

I haven't looked carefully at CCM, I've only read the critique in the
eax paper (eax is also CTR-mode + CBC-mac, but in a better way,
according to the eax authors).

> Let me know if you think these might be suitable for inclusion to nettle, or 
> if there
> is anything that you think needs to be changed.

I think it looks pretty good. Thanks!

Some initial comments below. I think it would make sense to discuss it
on the public nettle mailing list, in particular any interface issues.
Feel free to reply on-list. And if you don't object, I'd like to forward
this reply to the list.

If you make another revision of these patches, GNU-style ChangeLog
entries are also appreciated. And documentation, but it's probably good
to wait with that until any interface issues are sorted out.

> --- /dev/null
> +++ b/ccm-aes.c
> @@ -0,0 +1,65 @@
> +/* ccm-aes.c
> + *
> + * Counter with CBC-MAC mode, specified by NIST,
> + */
> +
> +/* nettle, low-level cryptographics library
> + *
> + * Copyright (C) 2011 Niels Möller
> + *
> + * The nettle library is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU Lesser General Public License as published 
> by
> + * the Free Software Foundation; either version 2.1 of the License, or (at 
> your
> + * option) any later version.
> + * 
> + * The nettle library is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
> + * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
> + * License for more details.
> + * 
> + * You should have received a copy of the GNU Lesser General Public License
> + * along with the nettle library; see the file COPYING.LIB.  If not, write to
> + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 
> Boston,
> + * MA 02111-1301, USA.
> + */
> +
> +#if HAVE_CONFIG_H
> +# include "config.h"
> +#endif
> +
> +#include "ccm.h"
> +
> +void
> +ccm_aes_set_nonce(struct ccm_aes_ctx *ctx,
> +        size_t length, const uint8_t *nonce,
> +        size_t authlen, size_t msglen, size_t taglen)
> +{
> +  CCM_SET_NONCE(ctx, length, nonce, authlen, msglen, taglen);
> +}

I don't think the ccm_aes family of functions are needed. ccm_aes128 etc
should be sufficient, and since it's a new feature, there's nothing to
be backwards compatible with.

> --- /dev/null
> +++ b/ccm.c
> @@ -0,0 +1,210 @@
> +/* ccm.h
> + *
> + * Counter with CBC-MAC mode, specified by NIST,
> + * 
> http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf
> + *
> + */
> +
> +/* nettle, low-level cryptographics library
> + *
> + * Copyright (C) 2011 Niels Möller
> + * Copyright (C) 2011 Katholieke Universiteit Leuven
> + * 
> + * Contributed by Owen Kirby

I think we need to be a bit clearer about the copyright. We currently
don't do any copyright assignments for Nettle. I take it you wrote the
ccm implementation, so you own the copyright. Unless it's owned by your
employer or client? 

(BTW, I've been very sloppy with copyright headers in the test programs,
but it would be good with an accurate header also for ccm-test.c).

> +/*
> + * Because of the encoding of L(a), we have to handle input data that might
> + * not be a multiple of the block size anyways, as such, we don't have the
> + * input constraint of most AEAD modes that the intermediate calls to 
> update()
> + * must be in multiples of the block size.
> + */
> +void
> +ccm_update(struct ccm_ctx *ctx, void *cipher, nettle_crypt_func *f,
> +        size_t length, const uint8_t *data)

In nettle, the update functions usually accept arbitrary size, just like
you do. Complete blocks are only required for crypt functions.

> +/*
> + * Because of the underlying CTR mode encryption, when called multiple times
> + * the data in intermediate calls must be provided in multiples of the block
> + * size.
> + */
> +void
> +ccm_encrypt(struct ccm_ctx *ctx, void *cipher, nettle_crypt_func *f,
> +         size_t length, uint8_t *dst, const uint8_t *src)
> +{
> +  ccm_pad(ctx, cipher, f);
> +  ccm_update(ctx, cipher, f, length, src);
> +  ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, dst, src);
> +}
> +
> +/*
> + * Because of the underlying CTR mode decryption, when called multiple times
> + * the data in intermediate calls must be provided in multiples of the block
> + * size.
> + */
> +void
> +ccm_decrypt(struct ccm_ctx *ctx, void *cipher, nettle_crypt_func *f,
> +         size_t length, uint8_t *dst, const uint8_t *src)
> +{
> +  ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, dst, src);
> +  ccm_pad(ctx, cipher, f);
> +  ccm_update(ctx, cipher, f, length, dst);
> +}
> +void
> +ccm_digest(struct ccm_ctx *ctx, void *cipher, nettle_crypt_func *f,
> +        size_t length, uint8_t *digest)
> +{
> +  int i = CCM_BLOCK_SIZE - CCM_FLAG_GET_L(ctx->ctr.b[CCM_OFFSET_FLAGS]);
> +  while (i < CCM_BLOCK_SIZE)  ctx->ctr.b[i++] = 0;
> +  ccm_pad(ctx, cipher, f);
> +  ctr_crypt(cipher, f, CCM_BLOCK_SIZE, ctx->ctr.b, length, digest, 
> ctx->tag.b);
> +}

Are there any sanity checks that the lengths match the ones specified
with set_nonce?

> --- /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.

The general aead interface should include some easy-to-use functions for
"all-in-one" processing of messages. It would be nice if ccm could be
made to fit into that framework sufficiently well to make such functions
work.

> --- /dev/null
> +++ b/testsuite/ccm-test.c

Thanks for including thorough tests. 

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
Internet email is subject to wholesale government surveillance.
_______________________________________________
nettle-bugs mailing list
nettle-bugs@lists.lysator.liu.se
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs

Reply via email to