Re: SIV-CMAC

2019-07-04 Thread Miroslav Lichvar
On Wed, Jul 03, 2019 at 06:26:07AM +0200, Nikos Mavrogiannopoulos wrote:
> Looks good to me, but I'm adding Mirek in CC who is using SIV-AES-CMAC
> for NTS/NTP implementation to verify that the final code is sufficient
> for this implementation.

I've updated my code to use the Nettle's SIV-CMAC and it seems to be
working fine. It interoperates with the previous version of itself
(using Nikos' original SIV-CMAC implementation with slightly different
API) and two other NTS implementations (one based on openssl, not sure
about the other).

Thank you both!

-- 
Miroslav Lichvar
___
nettle-bugs mailing list
nettle-bugs@lists.lysator.liu.se
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs


Re: SIV-CMAC

2019-07-02 Thread Nikos Mavrogiannopoulos
Looks good to me, but I'm adding Mirek in CC who is using SIV-AES-CMAC
for NTS/NTP implementation to verify that the final code is sufficient
for this implementation.

regards,
Nikos

On Tue, Jul 2, 2019 at 4:25 PM Niels Möller  wrote:
>
> Nikos Mavrogiannopoulos  writes:
>
> > I prefer the second option because I think the zero nonce variant
> > requires a disproportionate, to its usefullness and use, discussion to
> > define the "right" semantics.
>
> Merged siv-mode to the master branch now. Does it look right to you?
>
> Regards,
> /Niels
>
> --
> Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
> 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


Re: SIV-CMAC

2019-07-02 Thread Niels Möller
Nikos Mavrogiannopoulos  writes:

> I prefer the second option because I think the zero nonce variant
> requires a disproportionate, to its usefullness and use, discussion to
> define the "right" semantics.

Merged siv-mode to the master branch now. Does it look right to you?

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
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


Re: SIV-CMAC

2019-05-11 Thread Niels Möller
Nikos Mavrogiannopoulos  writes:

> Thanks. If you added the zero-nonce method, maybe it would be better
> to add test vectors for it as well. I'm copying from my last patch
> with it:

I was about to add the miscreant.js examples (and with nettle's output,
which is different), to illustrate interop issue. Unfortunately, the RFC
5297 testvectors appear useless if one wants to test the RFC 5116 mode
of operation.

And on second thought, maybe it makes more sense to change nettle to be
interoperable with miscreant here? I think that's how you did it
originally, and I found it confusing. RFC 5297 (SIV mode) says that for
use according to RFC5116 (AEAD interface), N_MIN = 1.

Another option, which you've also tried, is to to require non-empty
nonce, i.e., add back the assert (nlength > 0), and define
SIV_MIN_NONCE_SIZE as one, not zero. That's perhaps the most
conservative approach: support for empty nonce, however that should
behave, can be added later.

Opinions? 

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
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


Re: SIV-CMAC

2019-05-08 Thread Nikos Mavrogiannopoulos
Thanks. If you added the zero-nonce method, maybe it would be better
to add test vectors for it as well. I'm copying from my last patch
with it:

+  /*
+   * Example with no nonce, no AD and no plaintext; taken from
+   * https://github.com/miscreant/miscreant/blob/master/vectors/aes_siv.tjson
+   * however we don't interoperate.
+   */
+  test_siv_aes128("AES_SIV_CMAC256", sizeof(struct siv_aes128_cmac_ctx),
+  _aes128,
+  SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0"
+   "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"),
+  SHEX(""),
+  SHEX(""),
+  SHEX(""),
+  SHEX("949f99cb cc3eb5da6 d3c45d0 f59aa9c7"));
+
+  /*
+   * Example with no nonce, no AD and plaintext; taken from
+   * https://github.com/miscreant/miscreant/blob/master/vectors/aes_siv.tjson
+   */
+  test_siv_aes128("AES_SIV_CMAC256", sizeof(struct siv_aes128_cmac_ctx),
+  _aes128,
+  SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0"
+   "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"),
+  SHEX(""),
+  SHEX(""),
+  SHEX("00112233 44556677 8899aabb ccddeeff"),
+  SHEX("f304f912 863e303d 5b540e50 57c7010c"
+   "942ffaf4 5b0e5ca5 fb9a56a5 263bb065"));
+  /*
+   * Example without nonce length < 16 (RFC5297)
+   */
+  test_siv_aes128("AES_SIV_CMAC256", sizeof(struct siv_aes128_cmac_ctx),
+  _aes128,
+  SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0"
+   "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"),
+  SHEX(""),
+  SHEX("10111213 14151617 18191a1b 1c1d1e1f"
+   "20212223 24252627"),
+  SHEX("11223344 55667788 99aabbcc ddee"),
+  SHEX("85632d07 c6e8f37f 950acd32 0a2ecc93"
+   "40c02b96 90c4dc04 daef7f6a fe5c"));
+
+  /*
+   * Example without nonce length > 16
+   */
+  test_siv_aes128("AES_SIV_CMAC256", sizeof(struct siv_aes128_cmac_ctx),
+  _aes128,
+  SHEX("7f7e7d7c 7b7a7978 77767574 73727170"
+   "40414243 44454647 48494a4b 4c4d4e4f"),
+  SHEX(""),
+  SHEX("00112233 44556677 8899aabb ccddeeff"
+   "deaddada deaddada ffeeddcc bbaa9988"
+   "77665544 33221100"),
+  SHEX("74686973 20697320 736f6d65 20706c61"
+   "696e7465 78742074 6f20656e 63727970"
+   "74207573 696e6720 5349562d 414553"),
+  SHEX("c12ccaa7 54e1b3fa 4f416c18 415625ca"
+   "472fbee de5bc03f 34934819 a9abb20b5"
+   "8cd019c 470ac832 f6eb9ddf 0656c5dce"
+   "ffe611a 5a5ca3e1 c3c12da5 6e4bb87"));
+  /* AES-SIV-CMAC-512 (AES-256)
+   */
+  test_siv_aes256("AES_SIV_CMAC512", sizeof(struct siv_aes256_cmac_ctx),
+  _aes256,
+  SHEX("c27df2fd aec35d4a 2a412a50 c3e8c47d"
+   "2d568e91 a38e5414 8abdc0b6 e86caf87"
+   "695c0a8a df4c5f8e b2c6c8b1 36529864"
+   "f3b84b3a e8e3676c e760c461 f3a13e83"),
+  SHEX(""),
+  SHEX("10111213 14151617 18191a1b 1c1d1e1f"
+   "20212223 24252627"),
+  SHEX("11223344 55667788 99aabbcc ddee"),
+  SHEX("ae2b1bd1 ba7fcd6a 4f9f7eb2 4b40f766"
+   "86053ffd c384cb19 76031f46 3013"));
+
+  /*
+   * Example without nonce length > 16
+   */
+  test_siv_aes256("AES_SIV_CMAC512", sizeof(struct siv_aes256_cmac_ctx),
+  _aes256,
+  SHEX("c27df2fd aec35d4a 2a412a50 c3e8c47d"
+   "2d568e91 a38e5414 8abdc0b6 e86caf87"
+   "695c0a8a df4c5f8e b2c6c8b1 36529864"
+   "f3b84b3a e8e3676c e760c461 f3a13e83"),
+  SHEX(""),
+  SHEX("00112233 44556677 8899aabb ccddeeff"
+   "deaddada deaddada ffeeddcc bbaa9988"
+   "77665544 33221100"),
+  SHEX("74686973 20697320 736f6d65 20706c61"
+   "696e7465 78742074 6f20656e 63727970"
+   "74207573 696e6720 5349562d 414553"),
+  SHEX("79476aaa 388374fe 97d0db51 596cb5ee"
+   "a933e001 412026c7 956c82dd b753b1af"
+   "3d7d49ac 474a800a c14b4bab a4542067"
+   "83647ef9 51315dab b7a2c05b 288ba8"));

On Mon, May 6, 2019 at 7:45 PM Niels Möller  wrote:
>
> Nikos Mavrogiannopoulos  writes:
>
> > https://gitlab.com/nmav/nettle/merge_requests/4/
>
> I've integrated this onto a branch siv-mode, with some changes (renamed
> functions to all have the siv_cmac prefix, document that empty nonce may
> have interop issues and should be considered experimental (but still
> allow it), and dropped some macros and unrelated changes (which would
> belong on a different branch). Please have a look, and say if I've
> messed up something.
>
> Regards,
> /Niels
>
> --
> Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
> 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

Re: SIV-CMAC

2019-05-06 Thread Niels Möller
Nikos Mavrogiannopoulos  writes:

> https://gitlab.com/nmav/nettle/merge_requests/4/

I've integrated this onto a branch siv-mode, with some changes (renamed
functions to all have the siv_cmac prefix, document that empty nonce may
have interop issues and should be considered experimental (but still
allow it), and dropped some macros and unrelated changes (which would
belong on a different branch). Please have a look, and say if I've
messed up something.

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
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


Re: SIV-CMAC

2019-04-18 Thread Nikos Mavrogiannopoulos
Simo informed me that I didn't update the CMAC file with the new
initializer. Instead of spamming the list with numerous patches, my
latest version is at:

https://gitlab.com/nmav/nettle/merge_requests/4/

Can be downloaded as patches at:
https://gitlab.com/nmav/nettle/merge_requests/4.patch

On Thu, Apr 18, 2019 at 9:00 AM Nikos Mavrogiannopoulos  wrote:
>
> On Wed, 2019-04-17 at 20:41 +0200, Niels Möller wrote:
> >
> > > > To me, this sounds like a likely source of interop problems.
> > > > Since
> > > > RFC
> > > > 5297 is general and allows the application to decide on the
> > > > number of
> > > > elements and meaning of the input vector, it doesn't give much
> > > > guidance on this, as far as I see. The crucial case is when an
> > > > application specifies that SIV is used with associated data
> > > > and/or a
> > > > nonce, but allows an empty string for either of those.
> > >
> > > I agree on that. That's one of the reasons I stuck on the higher
> > > level
> > > AEAD API (expressed by the message APIs in nettle). I added two
> > > sentences in the documentation about it.
> >
> > The thing is, the AEAD api should allow inputs to be zero-length
> > strings. Then the question is how to treat zero-length inputs in
> > _siv_s2v, and I don't find RFC 5297 crystal clear on this point.
> >
> > To me, it would make most sense for the AEAD construction to always
> > use
> > the S2V function in the spec with S1 = associated data (possibly zero
> > length), S2 = nonce (possibly zero length), S3 = plaintext (possibly
> > zero length). But we need to do what's needed to make it easy to
> > interoperate with applicatinos and protocols using SIV; if everyone
> > else
> > does this differently, we should probably follow.
>
> I agree. The patch I sent yesterday is towards that. I have verified
> that this approach interoperates with two implementations. The
> difference from what you write above is that we don't support at all
> the case where nonce=empty. That has interop issues (two
> interpretations, skip the field, or use it as empty), and I think it
> makes sense to leave it out. It has no use for our interface.
>
> Today's patch adds two more vectors from another implementation and
> includes Simo's suggestion.
>
> >
> > If we do it this way, then the nonce-less "key wrapping" usecase
> > mentioned in RFC5297, with the example in A1, is *not* a special case
> > of
> > the AEAD construction, since this mode uses S1 = associated data, S2
> > =
> > plaintext.
> >
> > If we need to support several modes, maybe we should have a context
> > struct that lets us do S2V incrementally, one element at a time,
>
> Let's see if that is needed. For key wrapping I know no practical
> applications. I'd treat it as a separate algorithm, and we can add it
> later if needed.
>
> > > Done. It needed some reorganization, and cmac128_syn is still
> > > needed in
> > > an ugly simulation of the CMAC structure setup to use the macros. I
> > > have kept the union
> >
> > Maybe it would be easier without using the CMAC macros. They're
> > intended
> > for convenience, so there's little point in using them where it
> > doesn't
> > bring any convenience.
>
> I do not think that avoiding them would change this part.
>
> regards,
> Nikos
>
___
nettle-bugs mailing list
nettle-bugs@lists.lysator.liu.se
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs


Re: SIV-CMAC

2019-04-18 Thread Nikos Mavrogiannopoulos
On Wed, 2019-04-17 at 20:41 +0200, Niels Möller wrote:
> 
> > > To me, this sounds like a likely source of interop problems.
> > > Since
> > > RFC
> > > 5297 is general and allows the application to decide on the
> > > number of
> > > elements and meaning of the input vector, it doesn't give much
> > > guidance on this, as far as I see. The crucial case is when an
> > > application specifies that SIV is used with associated data
> > > and/or a
> > > nonce, but allows an empty string for either of those.
> > 
> > I agree on that. That's one of the reasons I stuck on the higher
> > level
> > AEAD API (expressed by the message APIs in nettle). I added two
> > sentences in the documentation about it.
> 
> The thing is, the AEAD api should allow inputs to be zero-length
> strings. Then the question is how to treat zero-length inputs in
> _siv_s2v, and I don't find RFC 5297 crystal clear on this point.
> 
> To me, it would make most sense for the AEAD construction to always
> use
> the S2V function in the spec with S1 = associated data (possibly zero
> length), S2 = nonce (possibly zero length), S3 = plaintext (possibly
> zero length). But we need to do what's needed to make it easy to
> interoperate with applicatinos and protocols using SIV; if everyone
> else
> does this differently, we should probably follow.

I agree. The patch I sent yesterday is towards that. I have verified
that this approach interoperates with two implementations. The
difference from what you write above is that we don't support at all
the case where nonce=empty. That has interop issues (two
interpretations, skip the field, or use it as empty), and I think it
makes sense to leave it out. It has no use for our interface.

Today's patch adds two more vectors from another implementation and
includes Simo's suggestion.

> 
> If we do it this way, then the nonce-less "key wrapping" usecase
> mentioned in RFC5297, with the example in A1, is *not* a special case
> of
> the AEAD construction, since this mode uses S1 = associated data, S2
> =
> plaintext.
> 
> If we need to support several modes, maybe we should have a context
> struct that lets us do S2V incrementally, one element at a time,

Let's see if that is needed. For key wrapping I know no practical
applications. I'd treat it as a separate algorithm, and we can add it
later if needed. 

> > Done. It needed some reorganization, and cmac128_syn is still
> > needed in
> > an ugly simulation of the CMAC structure setup to use the macros. I
> > have kept the union 
> 
> Maybe it would be easier without using the CMAC macros. They're
> intended
> for convenience, so there's little point in using them where it
> doesn't
> bring any convenience.

I do not think that avoiding them would change this part.

regards,
Nikos

From a0ceb52e7bef137226ec5a1013d154e5516d2ba4 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos 
Date: Tue, 16 Apr 2019 20:19:17 +0200
Subject: [PATCH 1/3] cmac: use nettle_block16 for const variable

Signed-off-by: Nikos Mavrogiannopoulos 
---
 cmac.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/cmac.c b/cmac.c
index ed3b5eb8..01fee79e 100644
--- a/cmac.c
+++ b/cmac.c
@@ -73,15 +73,15 @@ void
 cmac128_set_key(struct cmac128_ctx *ctx, const void *cipher,
 		nettle_cipher_func *encrypt)
 {
-  static const uint8_t const_zero[] = {
-0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00
+  static const union nettle_block16 const_zero = { .b = {
+	0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00 }
   };
   union nettle_block16 *L = >block;
   memset(ctx, 0, sizeof(*ctx));
 
   /* step 1 - generate subkeys k1 and k2 */
-  encrypt(cipher, 16, L->b, const_zero);
+  encrypt(cipher, 16, L->b, const_zero.b);
 
   block_mulx(>K1, L);
   block_mulx(>K2, >K1);
-- 
2.20.1

From 1030249c1ac8be816b3d2bf1863d325bc3fe8827 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos 
Date: Wed, 17 Apr 2019 15:17:47 +0200
Subject: [PATCH 2/3] .gitlab-ci.yml: added make distcheck target

This checks whether the distributed tarball misses files
and result to a functioning library.

Signed-off-by: Nikos Mavrogiannopoulos 
---
 .gitlab-ci.yml | 9 +
 1 file changed, 9 insertions(+)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index ecd95ad3..e7101c64 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -50,6 +50,15 @@ build/ndebug:
   - shared
   except:
   - tags
+distcheck:
+  image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
+  script:
+  - ./.bootstrap &&
+./configure --disable-static --disable-assembler && make distcheck
+  tags:
+  - shared
+  except:
+  - tags
 build/ubsan:
   image: $CI_REGISTRY/$BUILD_IMAGES_PROJECT:$FEDORA_BUILD
   script:
-- 
2.20.1

From efeb8451efa6e68b995830f19005354785aba2ba Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos 
Date: Sat, 20 Jan 2018 10:36:05 +0100
Subject: [PATCH 3/3] Added support for AES_SIV_CMAC_256 and 

Re: SIV-CMAC

2019-04-17 Thread Niels Möller
Nikos Mavrogiannopoulos  writes:

>> In this function, you treat empty associated data or nonce as those
>> elements missing in the input vector to S2V. E.g., if both adata and
>> nonce are empty, the input vector is { plaintext }, one single
>> element.
>> But it could also be { "", "", plaintext }, with three elements, the
>> first two being empty strings.
>
> While the low level function could handle it, it is not exposed to be
> called directly (mainly intentionally as this cipher introduces a very
> new paradigm which I do not quite see much of practical uses).
>
> This patch only adds the higher level AEAD API only, so this case
> cannot happen as we don't have the notion of empty string
> in nettle. We can introduce it of course, though we may be opening a
> can of worms as not only empty strings are undefined in terms of AEAD
> API [0], but what would these mean in the other implementations?
>
> [0]. https://tools.ietf.org/html/rfc5116#section-2

By empty string I simply meant a string of length 0. As I read RFC 5116,
it requires that the key is between 1 and 255 octets (inclusive), but
all of nonce, plaintext and associated data may consist of zero octets.

>> To me, this sounds like a likely source of interop problems. Since
>> RFC
>> 5297 is general and allows the application to decide on the number of
>> elements and meaning of the input vector, it doesn't give much
>> guidance on this, as far as I see. The crucial case is when an
>> application specifies that SIV is used with associated data and/or a
>> nonce, but allows an empty string for either of those.
>
> I agree on that. That's one of the reasons I stuck on the higher level
> AEAD API (expressed by the message APIs in nettle). I added two
> sentences in the documentation about it.

The thing is, the AEAD api should allow inputs to be zero-length
strings. Then the question is how to treat zero-length inputs in
_siv_s2v, and I don't find RFC 5297 crystal clear on this point.

To me, it would make most sense for the AEAD construction to always use
the S2V function in the spec with S1 = associated data (possibly zero
length), S2 = nonce (possibly zero length), S3 = plaintext (possibly
zero length). But we need to do what's needed to make it easy to
interoperate with applicatinos and protocols using SIV; if everyone else
does this differently, we should probably follow.

If we do it this way, then the nonce-less "key wrapping" usecase
mentioned in RFC5297, with the example in A1, is *not* a special case of
the AEAD construction, since this mode uses S1 = associated data, S2 =
plaintext.

If we need to support several modes, maybe we should have a context
struct that lets us do S2V incrementally, one element at a time,

  siv_add_adata(struct siv_ctx *ctx, size_t length, const uint8_t *data);

called zero or more times, followed by

  siv_encrypt(struct siv_ctx *ctx, size_t clength, uint8_t *dst, const uint8_t 
*src);

which does the CMAC of the plaintext (the final S2V element), extracts
V, and does the encryption. (S2V is defined also for n == 0, but that's
not very useful and we don't need to support it).

But I think we should start with the AEAD-style api with both adata and
nonce mandatory (but possibly empty), before worrying too much about
generalizations.

> Done. It needed some reorganization, and cmac128_syn is still needed in
> an ugly simulation of the CMAC structure setup to use the macros. I
> have kept the union 

Maybe it would be easier without using the CMAC macros. They're intended
for convenience, so there's little point in using them where it doesn't
bring any convenience.

> The attached version should address the comments so far and also
> changes cmac128_set_key to use nettle_block16 as well.

Thanks! I hope to read through the new patch during the weekend.

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
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


Re: SIV-CMAC

2019-04-17 Thread Simo Sorce
On Wed, 2019-04-17 at 20:27 +0200, Nikos Mavrogiannopoulos wrote:
> +  static const union nettle_block16 const_zero = { .b = {
> + 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
> + 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00 }

You could save some space/eyes by using .b = 0 (assuming we can depend
on modern C99 semantics) or also just via .u64 = { 0, 0 }

Simo.

-- 
Simo Sorce
Sr. Principal Software Engineer
Red Hat, Inc


___
nettle-bugs mailing list
nettle-bugs@lists.lysator.liu.se
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs


Re: SIV-CMAC

2019-04-17 Thread Nikos Mavrogiannopoulos
On Wed, 2019-04-17 at 11:37 +0200, Nikos Mavrogiannopoulos wrote:
> On Sun, 2019-04-14 at 09:33 +0200, Niels Möller wrote:
> > +  assert(nc->context_size <= NETTLE_MAX_CIPHER16_CONTEXT_SIZE);
> > > +
> > > +  /* ensure we have enough size of context plus any padding size
> > > */
> > > +  CMAC128_SET_KEY(, nc->set_encrypt_key, nc->encrypt, s2vk);
> > > +
> > > +  if (nlength == 0 && alength == 0) {
> > > +CMAC128_UPDATE(, nc->encrypt, 16, const_one);
> > > +CMAC128_DIGEST(, nc->encrypt, 16, v);
> > > +return;
> > > +  }
> > 
> > Shouldn't the plaintext, plength, pdata, still be processed in this
> > case?
> 
> Right, there should be an and plength == 0 as well. I've added an two
> additional test cases to check these cases, and the case where
> everything is zero, doesn't seem to interoperate with two libs I
> tried.
> 
> Hopefully it is issue of this code.
> 
> https://github.com/miscreant/miscreant/issues/194
> https://github.com/dfoxfranke/libaes_siv/issues/14

Based on the discussions on these bugs, I think it makes sense to
strictly restrict the implementation to the common interoperable
conventions (AEAD). That is, always assume (aad, nonce, plaintext),
even if empty. As such I've updated the test vectors to include non
empty nonce and tested them against libaes_siv.

The attached bugs update this implementation, and an additional patch
adds a "make distcheck" check to CI. That ensures that any missing or
incorrectly added in Makefile files are caught by the CI.

regards,
Nikos

From 8dfd9653109844dc7253b45af1815a0492b25c2a Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos 
Date: Sat, 20 Jan 2018 10:36:05 +0100
Subject: [PATCH 3/3] Added support for AES_SIV_CMAC_256 and AES_SIV_CMAC_512

This AEAD algorithm provides a way to make nonce-reuse a not critical
issue. That is particular useful to stateless servers that cannot ensure
that the nonce will not repeat. This cipher is used by
draft-ietf-ntp-using-nts-for-ntp-17.

Signed-off-by: Nikos Mavrogiannopoulos 
---
 Makefile.in|   4 +-
 cmac-internal.h|  54 ++
 cmac.c |  15 +-
 nettle-internal.h  |   2 +
 nettle.texinfo |  94 +-
 siv-aes128-cmac.c  |  75 
 siv-aes256-cmac.c  |  75 
 siv-cmac.c | 186 
 siv-cmac.h | 131 ++
 testsuite/.gitignore   |   2 +
 testsuite/.test-rules.make |   3 +
 testsuite/Makefile.in  |   2 +-
 testsuite/siv-test.c   | 347 +
 testsuite/testutils.h  |  13 ++
 14 files changed, 992 insertions(+), 11 deletions(-)
 create mode 100644 cmac-internal.h
 create mode 100644 siv-aes128-cmac.c
 create mode 100644 siv-aes256-cmac.c
 create mode 100644 siv-cmac.c
 create mode 100644 siv-cmac.h
 create mode 100644 testsuite/siv-test.c

diff --git a/Makefile.in b/Makefile.in
index 440de9f7..962a6b73 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -89,6 +89,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \
 		 camellia256-meta.c \
 		 cast128.c cast128-meta.c cbc.c \
 		 ccm.c ccm-aes128.c ccm-aes192.c ccm-aes256.c cfb.c \
+		 siv-cmac.c siv-aes128-cmac.c siv-aes256-cmac.c \
 		 cnd-memcpy.c \
 		 chacha-crypt.c chacha-core-internal.c \
 		 chacha-poly1305.c chacha-poly1305-meta.c \
@@ -198,7 +199,8 @@ HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \
 	  gcm.h gosthash94.h hmac.h \
 	  knuth-lfib.h hkdf.h \
 	  macros.h \
-	  cmac.h \
+	  cmac.h cmac-internal.h \
+	  siv-cmac.h \
 	  md2.h md4.h \
 	  md5.h md5-compat.h \
 	  memops.h memxor.h \
diff --git a/cmac-internal.h b/cmac-internal.h
new file mode 100644
index ..789588e6
--- /dev/null
+++ b/cmac-internal.h
@@ -0,0 +1,54 @@
+/* cmac.h
+
+   CMAC mode internal functions
+
+   Copyright (C) 2017 Red Hat, Inc.
+
+   Contributed by Nikos Mavrogiannopoulos
+
+   This file is part of GNU Nettle.
+
+   GNU Nettle is free software: you can redistribute it and/or
+   modify it under the terms of either:
+
+ * the GNU Lesser General Public License as published by the Free
+   Software Foundation; either version 3 of the License, or (at your
+   option) any later version.
+
+   or
+
+ * the GNU General Public License as published by the Free
+   Software Foundation; either version 2 of the License, or (at your
+   option) any later version.
+
+   or both in parallel, as here.
+
+   GNU Nettle 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
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see http://www.gnu.org/licenses/.
+*/
+
+#ifndef NETTLE_CMAC_INTERNAL_H_INCLUDED
+#define NETTLE_CMAC_INTERNAL_H_INCLUDED
+
+#include 

Re: SIV-CMAC

2019-04-17 Thread Nikos Mavrogiannopoulos
On Sun, 2019-04-14 at 09:33 +0200, Niels Möller wrote:
> +  assert(nc->context_size <= NETTLE_MAX_CIPHER16_CONTEXT_SIZE);
> > +
> > +  /* ensure we have enough size of context plus any padding size
> > */
> > +  CMAC128_SET_KEY(, nc->set_encrypt_key, nc->encrypt, s2vk);
> > +
> > +  if (nlength == 0 && alength == 0) {
> > +CMAC128_UPDATE(, nc->encrypt, 16, const_one);
> > +CMAC128_DIGEST(, nc->encrypt, 16, v);
> > +return;
> > +  }
> 
> Shouldn't the plaintext, plength, pdata, still be processed in this
> case?

Right, there should be an and plength == 0 as well. I've added an two
additional test cases to check these cases, and the case where
everything is zero, doesn't seem to interoperate with two libs I tried.

Hopefully it is issue of this code.

https://github.com/miscreant/miscreant/issues/194
https://github.com/dfoxfranke/libaes_siv/issues/14

> In this function, you treat empty associated data or nonce as those
> elements missing in the input vector to S2V. E.g., if both adata and
> nonce are empty, the input vector is { plaintext }, one single
> element.
> But it could also be { "", "", plaintext }, with three elements, the
> first two being empty strings.

While the low level function could handle it, it is not exposed to be
called directly (mainly intentionally as this cipher introduces a very
new paradigm which I do not quite see much of practical uses).

This patch only adds the higher level AEAD API only, so this case
cannot happen as we don't have the notion of empty string
in nettle. We can introduce it of course, though we may be opening a
can of worms as not only empty strings are undefined in terms of AEAD
API [0], but what would these mean in the other implementations?

[0]. https://tools.ietf.org/html/rfc5116#section-2

> To me, this sounds like a likely source of interop problems. Since
> RFC
> 5297 is general and allows the application to decide on the number of
> elements and meaning of the input vector, it doesn't give much
> guidance on this, as far as I see. The crucial case is when an
> application specifies that SIV is used with associated data and/or a
> nonce, but allows an empty string for either of those.

I agree on that. That's one of the reasons I stuck on the higher level
AEAD API (expressed by the message APIs in nettle). I added two
sentences in the documentation about it.

> >> I think this function should do the underlying key setup also for
> the
> >> cipher instance used for s2v, not just store the key for later. So
> >> then the function would be
> >> 
> >>   void
> >>   siv_cmac_set_key(void *cmac_cipher, void *ctr_cipher,
> The idea of the set_key function is to do all preparations that don't
> depend on the actual message, so they don't have to be repeated. And
> I
> think it's a bit odd to handle the keying of the two involved cipher
> contexts so differently.

Done. It needed some reorganization, and cmac128_syn is still needed in
an ugly simulation of the CMAC structure setup to use the macros. I
have kept the union 

The attached version should address the comments so far and also
changes cmac128_set_key to use nettle_block16 as well.

regards,
Nikos

From a0ceb52e7bef137226ec5a1013d154e5516d2ba4 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos 
Date: Tue, 16 Apr 2019 20:19:17 +0200
Subject: [PATCH 1/2] cmac: use nettle_block16 for const variable

Signed-off-by: Nikos Mavrogiannopoulos 
---
 cmac.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/cmac.c b/cmac.c
index ed3b5eb8..01fee79e 100644
--- a/cmac.c
+++ b/cmac.c
@@ -73,15 +73,15 @@ void
 cmac128_set_key(struct cmac128_ctx *ctx, const void *cipher,
 		nettle_cipher_func *encrypt)
 {
-  static const uint8_t const_zero[] = {
-0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
-0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00
+  static const union nettle_block16 const_zero = { .b = {
+	0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00 }
   };
   union nettle_block16 *L = >block;
   memset(ctx, 0, sizeof(*ctx));
 
   /* step 1 - generate subkeys k1 and k2 */
-  encrypt(cipher, 16, L->b, const_zero);
+  encrypt(cipher, 16, L->b, const_zero.b);
 
   block_mulx(>K1, L);
   block_mulx(>K2, >K1);
-- 
2.20.1

From c85011ce5fd60cd4c941319b78cd567d14b2ec85 Mon Sep 17 00:00:00 2001
From: Nikos Mavrogiannopoulos 
Date: Sat, 20 Jan 2018 10:36:05 +0100
Subject: [PATCH 2/2] Added support for AES_SIV_CMAC_256 and AES_SIV_CMAC_512

This AEAD algorithm provides a way to make nonce-reuse a not critical
issue. That is particular useful to stateless servers that cannot ensure
that the nonce will not repeat. This cipher is used by
draft-ietf-ntp-using-nts-for-ntp-17.

Signed-off-by: Nikos Mavrogiannopoulos 
---
 Makefile.in|   4 +-
 cmac-internal.h|  54 ++
 cmac.c |  15 +-
 nettle-internal.h  |   2 +
 nettle.texinfo |  94 +-
 siv-aes128-cmac.c 

Re: SIV-CMAC

2019-04-15 Thread Niels Möller
Nikos Mavrogiannopoulos  writes:

> On Sun, 2019-04-14 at 09:33 +0200, Niels Möller wrote:

>> > +typedef int
>> > +nettle_decrypt_message(void *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);
>> > +
>> 
>> In this patch, these types used in tests only. But I imagine you'd
>> like something in nettle-meta to represent a message-oriented aead?
>
> I have never used the nettle-meta interface for ciphers, so I'm not
> sure about whether that's needed or not. CCM for example is not
> represented there. Would it make sense to separate the meta interface
> from the addition of the cipher, or should I avoid adding the type
> completely?

Put these typedefs in testutils.h for now, if you find them useful for
the tests.

>> Some detail on the nonce-reuse would be helpful. As I understood RFC
>> 5297, the nonce used in SIV is only to make the ciphertexts of
>> otherwise identical messages look different to the attacker.

> My understanding of this RFC is that a primary goal as in 1.3.2, is to
> be resistant to nonce misuse (e.g., if you re-use the nonce). I can add
> more information but I am not sure I understand which direction of
> detail you mean. What are you missing or think is unclear in the text?

Something brief on what the consequences are if one accidentally or
deliberately uses the same nonce twice. You could even quote the rtc, if
it expresses it well and concisely.

>
>> > --- /dev/null
>> > +++ b/siv-aes128-cmac.c
>> > @@ -0,0 +1,79 @@
>> [...]
>> > +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 slength, uint8_t *dst, const
>> > uint8_t *src)
>> > +{
>> > +  assert(tlength == SIV_DIGEST_SIZE);
>> 
>> The tlength argument doesn't look that useful, do we need it?.
>
> If we remove the tlength then it would not implement the
> nettle_encrypt_message_func(). My goal in keeping tlength was to have a
> consistent interface across the message oriented ciphers.

I'd prefer to not have the tlength argument. If we do a
nettle-meta-style interface for messge-oriented aead, we may use a fix
tlength, so that, e.g., CCM with full tag length (16 bytes) nd truncated
tag (say, 4 bytes) would be considered distinct aead algorithms.

>> Also, I
>> think we agreed that the message length argument should be the size
>> of
>> the *destination* area, i.e., ciphertext size for encrypt_message
>> (see
>> ccm_*_encrypt_message):
>
> I can name it clength, but there is the implicit assumption that
> clength = slength right? Otherwise if a larger buffer is provided for
> destination, I do not see how it figure the source size.

clength == tlength + slength. This is what the docs for the
corresponding ccm functions say (which do have tlength argument, since
ccm supports truncated tag) say:

  The CCM message fuctions provides a simple interface that will perform
  authentication and message encryption in a single function call.  The
  length of the cleartext is given by MLENGTH and the length of the
  ciphertext is given by CLENGTH, always exactly TLENGTH bytes longer than
  the corresponding plaintext.  The length argument passed to a function
  is always the size for the result, CLENGTH for the encryption functions,
  and MLENGTH for the decryption functions.

>> > --- /dev/null
>> > +++ b/siv-cmac.c
>> > @@ -0,0 +1,194 @@
>> > +/* This is a common structure for AES-128 and AES-256 thus
>> > + * for the cipher part we simply pad to the maximum structure
>> > + * size plus 16 bytes to account for any alignment difference in
>> > + * the original structures */
>> > +struct cmac128_syn {
>> > +  struct cmac128_ctx ctx;
>> > +  struct {
>> > +uint8_t pad[NETTLE_MAX_CIPHER16_CONTEXT_SIZE+16];
>> > +  } cipher;
>> > +};
>> 
>> I don't think this guarantees any alignment. You would either need
>> soemthing like
>> 
>>   struct cipher_storage {
>> union {
>>   uint64_t u64;
>>   char c[NETTLE_MAX_CIPHER16_CONTEXT_SIZE];
>> } storage;
>>   };
>>   ...
>>   CMAC128_CTX(cipher_storage) ctx;
>
> The goal here was not to make c aligned, but to have enough pad so that
> when this structure is read as cmac_aes128_ctx, to account for any
> alignment in the latter. Maybe actually I should do just that, and add
> the real types as union.

I think it's important that the context struct gets the alignment it
needs. Now, since cmac128_ctx has aligned contents, uint8_t pad will
likely get sufficient alignment anyway, but I think it's a bit brittle
to depend on that; an uint8_t[...] inside a struct usually doesn't get
larger alignment than a single byte.

>> or use TMP_ALLOC_ALIGN 

Re: SIV-CMAC

2019-04-14 Thread Nikos Mavrogiannopoulos
On Sun, 2019-04-14 at 09:33 +0200, Niels Möller wrote:
> Nikos Mavrogiannopoulos  writes:
> 
> > This patch adds the SIV-CMAC algorithm to nettle (an update of the
> > previous attempt). It is an atypical cipher which fits into the
> > encrypt_message interface.
> 
> Thanks. Some comments below:
> 
> > --- a/nettle-types.h
> > +++ b/nettle-types.h
> > @@ -78,6 +78,21 @@ typedef void *nettle_realloc_func(void *ctx,
> > void *p, size_t length);
> >  /* Ciphers */
> >  typedef void nettle_set_key_func(void *ctx, const uint8_t *key);
> >  
> > +/* AEAD ciphers */
> > +typedef void
> > +nettle_encrypt_message(void *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);
> > +
> > +typedef int
> > +nettle_decrypt_message(void *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);
> > +
> 
> In this patch, these types used in tests only. But I imagine you'd
> like something in nettle-meta to represent a message-oriented aead?

I have never used the nettle-meta interface for ciphers, so I'm not
sure about whether that's needed or not. CCM for example is not
represented there. Would it make sense to separate the meta interface
from the addition of the cipher, or should I avoid adding the type
completely?


> 
> > +@acronym{SIV-CMAC} mode is a combination of counter mode with
> > message
> > +authentication based on @acronym{CMAC}. Unlike other counter
> > @acronym{AEAD}
> > +modes, it provides protection against accidental nonce misuse,
> > making it
> > +a good choice for stateless-servers that cannot ensure nonce
> > uniqueness.
> 
> Some detail on the nonce-reuse would be helpful. As I understood RFC
> 5297, the nonce used in SIV is only to make the ciphertexts of
> otherwise identical messages look different to the attacker.

My understanding of this RFC is that a primary goal as in 1.3.2, is to
be resistant to nonce misuse (e.g., if you re-use the nonce). I can add
more information but I am not sure I understand which direction of
detail you mean. What are you missing or think is unclear in the text?

> > --- /dev/null
> > +++ b/siv-aes128-cmac.c
> > @@ -0,0 +1,79 @@
> [...]
> > +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 slength, uint8_t *dst, const
> > uint8_t *src)
> > +{
> > +  assert(tlength == SIV_DIGEST_SIZE);
> 
> The tlength argument doesn't look that useful, do we need it?.

If we remove the tlength then it would not implement the
nettle_encrypt_message_func(). My goal in keeping tlength was to have a
consistent interface across the message oriented ciphers.

> Also, I
> think we agreed that the message length argument should be the size
> of
> the *destination* area, i.e., ciphertext size for encrypt_message
> (see
> ccm_*_encrypt_message):

I can name it clength, but there is the implicit assumption that
clength = slength right? Otherwise if a larger buffer is provided for
destination, I do not see how it figure the source size.

> > --- /dev/null
> > +++ b/siv-cmac.c
> > @@ -0,0 +1,194 @@
> > +/* This is a common structure for AES-128 and AES-256 thus
> > + * for the cipher part we simply pad to the maximum structure
> > + * size plus 16 bytes to account for any alignment difference in
> > + * the original structures */
> > +struct cmac128_syn {
> > +  struct cmac128_ctx ctx;
> > +  struct {
> > +uint8_t pad[NETTLE_MAX_CIPHER16_CONTEXT_SIZE+16];
> > +  } cipher;
> > +};
> 
> I don't think this guarantees any alignment. You would either need
> soemthing like
> 
>   struct cipher_storage {
> union {
>   uint64_t u64;
>   char c[NETTLE_MAX_CIPHER16_CONTEXT_SIZE];
> } storage;
>   };
>   ...
>   CMAC128_CTX(cipher_storage) ctx;

The goal here was not to make c aligned, but to have enough pad so that
when this structure is read as cmac_aes128_ctx, to account for any
alignment in the latter. Maybe actually I should do just that, and add
the real types as union.

> or use TMP_ALLOC_ALIGN (but in the latter case, you can't use the
> CMAC128_* macros). Or let caller pass in the cipher context (see last
> comment in this mail)
> 
> > +static
> > +void _siv_s2v(const struct nettle_cipher *nc,
> > + const uint8_t *s2vk, size_t alength, const uint8_t
> > *adata,
> > +  size_t nlength, const uint8_t *nonce,
> > +  size_t plength, const uint8_t *pdata,
> > +  uint8_t *v)
> > +{
> > +  struct cmac128_syn ctx;
> > +  union 

Re: SIV-CMAC

2019-04-14 Thread Niels Möller
Nikos Mavrogiannopoulos  writes:

> This patch adds the SIV-CMAC algorithm to nettle (an update of the
> previous attempt). It is an atypical cipher which fits into the
> encrypt_message interface.

Thanks. Some comments below:

> --- a/nettle-types.h
> +++ b/nettle-types.h
> @@ -78,6 +78,21 @@ typedef void *nettle_realloc_func(void *ctx, void *p, 
> size_t length);
>  /* Ciphers */
>  typedef void nettle_set_key_func(void *ctx, const uint8_t *key);
>  
> +/* AEAD ciphers */
> +typedef void
> +nettle_encrypt_message(void *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);
> +
> +typedef int
> +nettle_decrypt_message(void *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);
> +

In this patch, these types used in tests only. But I imagine you'd like
something in nettle-meta to represent a message-oriented aead?

> +@acronym{SIV-CMAC} mode is a combination of counter mode with message
> +authentication based on @acronym{CMAC}. Unlike other counter @acronym{AEAD}
> +modes, it provides protection against accidental nonce misuse, making it
> +a good choice for stateless-servers that cannot ensure nonce
> uniqueness.

Some detail on the nonce-reuse would be helpful. As I understood RFC
5297, the nonce used in SIV is only to make the ciphertexts of otherwise
identical messages look different to the attacker.

> --- /dev/null
> +++ b/siv-aes128-cmac.c
> @@ -0,0 +1,79 @@
[...]
> +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 slength, uint8_t *dst, const uint8_t 
> *src)
> +{
> +  assert(tlength == SIV_DIGEST_SIZE);

The tlength argument doesn't look that useful, do we need it?. Also, I
think we agreed that the message length argument should be the size of
the *destination* area, i.e., ciphertext size for encrypt_message (see
ccm_*_encrypt_message):

> --- /dev/null
> +++ b/siv-cmac.c
> @@ -0,0 +1,194 @@

> +/* This is a common structure for AES-128 and AES-256 thus
> + * for the cipher part we simply pad to the maximum structure
> + * size plus 16 bytes to account for any alignment difference in
> + * the original structures */
> +struct cmac128_syn {
> +  struct cmac128_ctx ctx;
> +  struct {
> +uint8_t pad[NETTLE_MAX_CIPHER16_CONTEXT_SIZE+16];
> +  } cipher;
> +};

I don't think this guarantees any alignment. You would either need
soemthing like

  struct cipher_storage {
union {
  uint64_t u64;
  char c[NETTLE_MAX_CIPHER16_CONTEXT_SIZE];
} storage;
  };
  ...
  CMAC128_CTX(cipher_storage) ctx;

or use TMP_ALLOC_ALIGN (but in the latter case, you can't use the
CMAC128_* macros). Or let caller pass in the cipher context (see last
comment in this mail)

> +static
> +void _siv_s2v(const struct nettle_cipher *nc,
> +   const uint8_t *s2vk, size_t alength, const uint8_t *adata,
> +  size_t nlength, const uint8_t *nonce,
> +  size_t plength, const uint8_t *pdata,
> +  uint8_t *v)
> +{
> +  struct cmac128_syn ctx;
> +  union nettle_block16 D, S, T;
> +  const uint8_t const_one[16] = {
> + 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
> + 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x01
> +  };
> +  const uint8_t const_zero[16] = {
> + 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00,
> + 0x00, 0x00, 0x00, 0x00,  0x00, 0x00, 0x00, 0x00
> +  };

Use static const.

> +  assert(nc->context_size <= NETTLE_MAX_CIPHER16_CONTEXT_SIZE);
> +
> +  /* ensure we have enough size of context plus any padding size */
> +  CMAC128_SET_KEY(, nc->set_encrypt_key, nc->encrypt, s2vk);
> +
> +  if (nlength == 0 && alength == 0) {
> +CMAC128_UPDATE(, nc->encrypt, 16, const_one);
> +CMAC128_DIGEST(, nc->encrypt, 16, v);
> +return;
> +  }

Shouldn't the plaintext, plength, pdata, still be processed in this
case?

In this function, you treat empty associated data or nonce as those
elements missing in the input vector to S2V. E.g., if both adata and
nonce are empty, the input vector is { plaintext }, one single element.
But it could also be { "", "", plaintext }, with three elements, the
first two being empty strings.

To me, this sounds like a likely source of interop problems. Since RFC
5297 is general and allows the application to decide on the number of
elements and meaning of the input vector, it doesn't give much
guidance on this, as far as I see. The crucial case is when an
application specifies that SIV is used with associated