Commit ef82f228 authored by Niels Möller's avatar Niels Möller

SIV-CMAC mode, based on patch by Nikos Mavrogiannopoulos

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.
parent 9adb998c
2019-05-06 Niels Möller <nisse@lysator.liu.se>
SIV-CMAC mode, based on patch by Nikos Mavrogiannopoulos:
* siv-cmac.h (SIV_BLOCK_SIZE, SIV_DIGEST_SIZE): New constants.
(SIV_CMAC_CTX): New macro.
(struct siv_cmac_aes128_ctx, struct siv_cmac_aes256_ctx): New
context structs.
* siv-cmac.c (_siv_s2v, siv_cmac_set_key)
(siv_cmac_encrypt_message)
(siv_cmac_decrypt_message): New file, new functions.
* siv-cmac-aes128.c (siv_cmac_aes128_set_key)
(siv_cmac_aes128_encrypt_message)
(siv_cmac_aes128_decrypt_message): New file, new functions.
* siv-cmac-aes256.c (siv_cmac_aes256_set_key)
(siv_cmac_aes256_encrypt_message)
(siv_cmac_aes256_decrypt_message): New file, new functions.
* Makefile.in (nettle_SOURCES): Add siv-cmac source files.
(HEADERS): Add siv-cmac.h.
* testsuite/siv-test.c: New file.
* testsuite/Makefile.in (TS_NETTLE_SOURCES): Added siv-test.c
* nettle.texinfo (SIV-CMAC): Documentation.
2019-04-30 Niels Möller <nisse@lysator.liu.se>
Based on a patch contributed by Nikos Mavrogiannopoulos.
......
......@@ -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-cmac-aes128.c siv-cmac-aes256.c \
cnd-memcpy.c \
chacha-crypt.c chacha-core-internal.c \
chacha-poly1305.c chacha-poly1305-meta.c \
......@@ -198,7 +199,7 @@ 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 siv-cmac.h \
md2.h md4.h \
md5.h md5-compat.h \
memops.h memxor.h \
......
......@@ -97,6 +97,7 @@ Cipher modes
* CFB and CFB8::
* GCM::
* CCM::
* SIV-CMAC::
Keyed Hash Functions
......@@ -2565,6 +2566,7 @@ more adventurous alternative, in particular if performance is important.
* GCM::
* CCM::
* ChaCha-Poly1305::
* SIV-CMAC::
* nettle_aead abstraction::
@end menu
......@@ -3212,7 +3214,7 @@ These are identical to @code{ccm_encrypt_message} and @code{ccm_decrypt_message}
except that @var{cipher} and @var{f} are replaced with a context structure.
@end deftypefun
@node ChaCha-Poly1305, nettle_aead abstraction, CCM, Authenticated encryption
@node ChaCha-Poly1305, SIV-CMAC, CCM, Authenticated encryption
@comment node-name, next, previous, up
@subsection ChaCha-Poly1305
......@@ -3295,6 +3297,107 @@ smaller than @code{CHACHA_POLY1305_DIGEST_SIZE}, only the first
@var{length} octets of the digest are written.
@end deftypefun
@node SIV-CMAC, nettle_aead abstraction, ChaCha-Poly1305, Authenticated encryption
@comment node-name, next, previous, up
@subsection Synthetic Initialization Vector AEAD
@cindex SIV mode
@cindex SIV-CMAC mode
@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.
It is constructed on top of a block cipher which must have a block size of
128 bits. Nettle's support for @acronym{SIV-CMAC} consists of
a message encryption and authentication interface, for
@acronym{SIV-CMAC} using AES as the underlying block cipher.
When a nonce is re-used with this mode, message authenticity is retained
however an attacker can determine whether the same plaintext was protected
with the two messages sharing the nonce.
These interfaces are defined in @file{<nettle/siv-cmac.h>}.
Unlike other @acronym{AEAD} mode in @acronym{SIV-CMAC} the initialization
vector serves as the tag. That means that in the generated ciphertext
the tag precedes the ciphertext.
Note also, that the @acronym{SIV-CMAC} algorithm, as specified in
@cite{RFC 5297}, introduces the notion of authenticated data which
consist of multiple components. For example with @acronym{SIV-CMAC} the
authentication tag of data @code{X} followed by @code{Y}, is different
than the concatenated data @code{X || Y}. The interfaces described below
follow the @acronym{AEAD} paradigm and uses a fix structure with single
string of authenticated data, a nonce, and the plaintext message itself.
In the terminology of the RFC, the input to the S2V function is always a
vector of three elements, where S1 is the authenticated data, S2 is the
nonce, and S3 is the plaintext.
@emph{Empty nonce should be considered experimental:} The specification
also discusses nonce-less mode of operation, where the nonce is omitted
in the S2V input vector; this leads to some confusion on how to do
SIV-CMAC when the nonce is an empty string: Should S2 be an empty
string, or should this mean nonce-less mode? Nettle's implementation
currently uses an empty S2, but this may have interoperability issues.
If standards emerge, Nettle's implementation may be changed to follow.
In principle, we have the same ambiguity with empty associated data, but
at the time of writing, Nettle authors are not aware of any
interoperability problems with this.
@subsubsection General interface
@defvr Constant SIV_BLOCK_SIZE
@acronym{SIV-CMAC}'s block size, 16.
@end defvr
@defvr Constant SIV_DIGEST_SIZE
Size of the @acronym{SIV-CMAC} digest or initialization vector, 16.
@end defvr
@subsubsection @acronym{SIV-CMAC}-@acronym{AES} interface
The @acronym{AES} @acronym{SIV-CMAC} functions provide an API for using
@acronym{SIV-CMAC} mode with the @acronym{AES} block ciphers. The parameters
all have the same meaning as the general and message interfaces, except
that the @var{cipher}, @var{f}, and @var{ctx} parameters are replaced
with an @acronym{AES} context structure, and a set-key function must be
called before using any of the other functions in this interface.
@deftp {Context struct} {struct siv_cmac_aes128_ctx}
Holds state corresponding to a particular message encrypted using the
AES-128 block cipher.
@end deftp
@deftp {Context struct} {struct siv_cmac_aes256_ctx}
Holds state corresponding to a particular message encrypted using the
AES-256 block cipher.
@end deftp
@deftypefun void siv_cmac_aes128_set_key (struct siv_cmac_aes128_ctx *@var{ctx}, const uint8_t *@var{key})
@deftypefunx void siv_cmac_aes256_set_key (struct siv_cmac_aes256_ctx *@var{ctx}, const uint8_t *@var{key})
Initializes the encryption key for the AES block cipher. One of these
functions must be called before any of the other functions in the
@acronym{AES} @acronym{SIV-CMAC} interface.
@end deftypefun
@deftypefun void siv_cmac_aes128_encrypt_message (struct siv_cmac_aes128_ctx *@var{ctx}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{clength}, uint8_t *@var{dst}, const uint8_t *@var{src})
@deftypefunx void siv_cmac_aes256_encrypt_message (struct siv_cmac_aes256_ctx *@var{ctx}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{clength}, uint8_t *@var{dst}, const uint8_t *@var{src})
Computes the message digest from the @var{adata} and @var{src}
parameters, encrypts the plaintext from @var{src}, prepends the
initialization vector to the ciphertext and outputs it to @var{dst}.
The @var{clength} variable must be equal to the length of @var{src}
plus @code{SIV_DIGEST_SIZE}.
@end deftypefun
@deftypefun int siv_cmac_aes128_decrypt_message (struct siv_cmac_aes128_ctx *@var{ctx}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{mlength}, uint8_t *@var{dst}, const uint8_t *@var{src})
@deftypefunx int siv_cmac_aes256_decrypt_message (struct siv_cmac_aes128_ctx *@var{ctx}, size_t @var{nlength}, const uint8_t *@var{nonce}, size_t @var{alength}, const uint8_t *@var{adata}, size_t @var{mlength}, uint8_t *@var{dst}, const uint8_t *@var{src})
Decrypts the ciphertext from @var{src}, outputs the plaintext to
@var{dst}, recalculates the initialization vector from @var{adata} and the
plaintext. If the values of the received and calculated initialization vector
are equal, this will return 1 indicating a valid and authenticated
message. Otherwise, this function will return zero.
@end deftypefun
@node nettle_aead abstraction, , ChaCha-Poly1305, Authenticated encryption
@comment node-name, next, previous, up
@subsection The @code{struct nettle_aead} abstraction
......
/* siv-cmac-aes128.c
AES-SIV, RFC5297
Copyright (C) 2017 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/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <string.h>
#include "aes.h"
#include "siv-cmac.h"
#include "cmac.h"
#include "ctr.h"
#include "memxor.h"
#include "memops.h"
#include "cmac-internal.h"
void
siv_cmac_aes128_set_key(struct siv_cmac_aes128_ctx *ctx, const uint8_t *key)
{
siv_cmac_set_key(&ctx->siv_cmac.ctx, &ctx->siv_cmac.cipher, &ctx->siv_cipher, &nettle_aes128, key);
}
void
siv_cmac_aes128_encrypt_message(struct siv_cmac_aes128_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t clength, uint8_t *dst, const uint8_t *src)
{
siv_cmac_encrypt_message(&ctx->siv_cmac.ctx, &ctx->siv_cmac.cipher,
&nettle_aes128, &ctx->siv_cipher,
nlength, nonce, alength, adata,
clength, dst, src);
}
int
siv_cmac_aes128_decrypt_message(struct siv_cmac_aes128_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t mlength, uint8_t *dst, const uint8_t *src)
{
return siv_cmac_decrypt_message(&ctx->siv_cmac.ctx, &ctx->siv_cmac.cipher,
&nettle_aes128, &ctx->siv_cipher,
nlength, nonce, alength, adata,
mlength, dst, src);
}
/* siv-cmac-aes256.c
AES-SIV, RFC5297
Copyright (C) 2017 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/.
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <assert.h>
#include <string.h>
#include "aes.h"
#include "siv-cmac.h"
#include "cmac.h"
#include "ctr.h"
#include "memxor.h"
#include "memops.h"
#include "cmac-internal.h"
void
siv_cmac_aes256_set_key(struct siv_cmac_aes256_ctx *ctx, const uint8_t *key)
{
siv_cmac_set_key(&ctx->siv_cmac.ctx, &ctx->siv_cmac.cipher, &ctx->siv_cipher, &nettle_aes256, key);
}
void
siv_cmac_aes256_encrypt_message(struct siv_cmac_aes256_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t clength, uint8_t *dst, const uint8_t *src)
{
siv_cmac_encrypt_message(&ctx->siv_cmac.ctx, &ctx->siv_cmac.cipher,
&nettle_aes256, &ctx->siv_cipher,
nlength, nonce, alength, adata,
clength, dst, src);
}
int
siv_cmac_aes256_decrypt_message(struct siv_cmac_aes256_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t mlength, uint8_t *dst, const uint8_t *src)
{
return siv_cmac_decrypt_message(&ctx->siv_cmac.ctx, &ctx->siv_cmac.cipher,
&nettle_aes256, &ctx->siv_cipher,
nlength, nonce, alength, adata,
mlength, dst, src);
}
/* siv-cmac.c
SIV-CMAC, RFC5297
Copyright (C) 2017 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/.
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <assert.h>
#include <string.h>
#include "aes.h"
#include "siv-cmac.h"
#include "cmac.h"
#include "ctr.h"
#include "memxor.h"
#include "memops.h"
#include "cmac-internal.h"
#include "nettle-internal.h"
/* This is an implementation of S2V for the AEAD case where
* vectors if zero, are considered as S empty components */
static void
_siv_s2v (const struct nettle_cipher *nc,
struct cmac128_ctx *siv_cmac_ctx,
const void *cmac_cipher_ctx,
size_t alength, const uint8_t * adata,
size_t nlength, const uint8_t * nonce,
size_t plength, const uint8_t * pdata, uint8_t * v)
{
union nettle_block16 D, S, T;
static const union nettle_block16 const_zero = {.b = 0 };
cmac128_update (siv_cmac_ctx, cmac_cipher_ctx, nc->encrypt, 16, const_zero.b);
cmac128_digest (siv_cmac_ctx, cmac_cipher_ctx, nc->encrypt, 16, D.b);
_cmac128_block_mulx (&D, &D);
cmac128_update (siv_cmac_ctx, cmac_cipher_ctx, nc->encrypt, alength, adata);
cmac128_digest (siv_cmac_ctx, cmac_cipher_ctx, nc->encrypt, 16, S.b);
memxor (D.b, S.b, 16);
_cmac128_block_mulx (&D, &D);
cmac128_update (siv_cmac_ctx, cmac_cipher_ctx, nc->encrypt, nlength, nonce);
cmac128_digest (siv_cmac_ctx, cmac_cipher_ctx, nc->encrypt, 16, S.b);
memxor (D.b, S.b, 16);
/* Sn */
if (plength >= 16)
{
cmac128_update (siv_cmac_ctx, cmac_cipher_ctx, nc->encrypt, plength - 16, pdata);
pdata += plength - 16;
memxor3 (T.b, pdata, D.b, 16);
}
else
{
union nettle_block16 pad;
_cmac128_block_mulx (&T, &D);
memcpy (pad.b, pdata, plength);
pad.b[plength] = 0x80;
if (plength + 1 < 16)
memset (&pad.b[plength + 1], 0, 16 - plength - 1);
memxor (T.b, pad.b, 16);
}
cmac128_update (siv_cmac_ctx, cmac_cipher_ctx, nc->encrypt, 16, T.b);
cmac128_digest (siv_cmac_ctx, cmac_cipher_ctx, nc->encrypt, 16, v);
}
void
siv_cmac_set_key (struct cmac128_ctx *siv_cmac_ctx, void *cmac_cipher_ctx, void *cipher_ctx,
const struct nettle_cipher *nc, const uint8_t * key)
{
nc->set_encrypt_key (cmac_cipher_ctx, key);
cmac128_set_key (siv_cmac_ctx, cmac_cipher_ctx, nc->encrypt);
nc->set_encrypt_key (cipher_ctx, key + nc->key_size);
}
void
siv_cmac_encrypt_message (struct cmac128_ctx *siv_cmac_ctx,
const void *cmac_cipher_ctx,
const struct nettle_cipher *nc,
const void *cipher_ctx,
size_t nlength, const uint8_t * nonce,
size_t alength, const uint8_t * adata,
size_t clength, uint8_t * dst, const uint8_t * src)
{
union nettle_block16 siv;
size_t slength;
assert (clength >= SIV_DIGEST_SIZE);
slength = clength - SIV_DIGEST_SIZE;
/* create CTR nonce */
_siv_s2v (nc, siv_cmac_ctx, cmac_cipher_ctx, alength, adata, nlength, nonce, slength, src, siv.b);
memcpy (dst, siv.b, SIV_DIGEST_SIZE);
siv.b[8] &= ~0x80;
siv.b[12] &= ~0x80;
ctr_crypt (cipher_ctx, nc->encrypt, AES_BLOCK_SIZE, siv.b, slength,
dst + SIV_DIGEST_SIZE, src);
}
int
siv_cmac_decrypt_message (struct cmac128_ctx *siv_cmac_ctx,
const void *cmac_cipher_ctx,
const struct nettle_cipher *nc,
const void *cipher_ctx,
size_t nlength, const uint8_t * nonce,
size_t alength, const uint8_t * adata,
size_t mlength, uint8_t * dst, const uint8_t * src)
{
union nettle_block16 siv;
union nettle_block16 ctr;
memcpy (ctr.b, src, SIV_DIGEST_SIZE);
ctr.b[8] &= ~0x80;
ctr.b[12] &= ~0x80;
ctr_crypt (cipher_ctx, nc->encrypt, AES_BLOCK_SIZE, ctr.b,
mlength, dst, src + SIV_DIGEST_SIZE);
/* create CTR nonce */
_siv_s2v (nc,
siv_cmac_ctx, cmac_cipher_ctx, alength, adata,
nlength, nonce, mlength, dst, siv.b);
return memeql_sec (siv.b, src, SIV_DIGEST_SIZE);
}
/* siv-cmac.h
AES-SIV, RFC5297
Copyright (C) 2017 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_SIV_H_INCLUDED
#define NETTLE_SIV_H_INCLUDED
#include "nettle-types.h"
#include "nettle-meta.h"
#include "cmac.h"
#include "aes.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Name mangling */
#define siv_cmac_set_key nettle_siv_cmac_set_key
#define siv_cmac_encrypt_message nettle_siv_cmac_encrypt_message
#define siv_cmac_decrypt_message nettle_siv_cmac_decrypt_message
#define siv_cmac_aes128_set_key nettle_siv_cmac_aes128_set_key
#define siv_cmac_aes128_encrypt_message nettle_siv_cmac_aes128_encrypt_message
#define siv_cmac_aes128_decrypt_message nettle_siv_cmac_aes128_decrypt_message
#define siv_cmac_aes256_set_key nettle_siv_cmac_aes256_set_key
#define siv_cmac_aes256_encrypt_message nettle_siv_cmac_aes256_encrypt_message
#define siv_cmac_aes256_decrypt_message nettle_siv_cmac_aes256_decrypt_message
/* For SIV, the block size of the underlying cipher shall be 128 bits. */
#define SIV_BLOCK_SIZE 16
#define SIV_DIGEST_SIZE 16
void
siv_cmac_set_key(struct cmac128_ctx *siv_cmac_ctx, void *cmac_cipher_ctx, void *cipher_ctx,
const struct nettle_cipher *nc,
const uint8_t *key);
void
siv_cmac_encrypt_message(struct cmac128_ctx *siv_cmac_ctx, const void *cmac_cipher_ctx,
const struct nettle_cipher *nc,
const void *cipher_ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t clength, uint8_t *dst, const uint8_t *src);
int
siv_cmac_decrypt_message(struct cmac128_ctx *siv_cmac_ctx, const void *cmac_cipher_ctx,
const struct nettle_cipher *nc,
const void *cipher_ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t mlength, uint8_t *dst, const uint8_t *src);
/*
* SIV mode requires the aad and plaintext when building the IV, which
* prevents streaming processing and it incompatible with the AEAD API.
*/
#define SIV_CMAC_CTX(type) { struct CMAC128_CTX(type) siv_cmac; type siv_cipher; }
/* SIV_CMAC_AES128 */
struct siv_cmac_aes128_ctx SIV_CMAC_CTX(struct aes128_ctx);
void
siv_cmac_aes128_set_key(struct siv_cmac_aes128_ctx *ctx, const uint8_t *key);
void
siv_cmac_aes128_encrypt_message(struct siv_cmac_aes128_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t clength, uint8_t *dst, const uint8_t *src);
int
siv_cmac_aes128_decrypt_message(struct siv_cmac_aes128_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t mlength, uint8_t *dst, const uint8_t *src);
/* SIV_CMAC_AES256 */
struct siv_cmac_aes256_ctx SIV_CMAC_CTX(struct aes256_ctx);
void
siv_cmac_aes256_set_key(struct siv_cmac_aes256_ctx *ctx, const uint8_t *key);
void
siv_cmac_aes256_encrypt_message(struct siv_cmac_aes256_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t clength, uint8_t *dst, const uint8_t *src);
int
siv_cmac_aes256_decrypt_message(struct siv_cmac_aes256_ctx *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t mlength, uint8_t *dst, const uint8_t *src);
#ifdef __cplusplus
}
#endif
#endif /* NETTLE_SIV_H_INCLUDED */
......@@ -96,6 +96,8 @@
/version-test
/yarrow-test
/xts-test
/cmac-test
/siv-test
/test.in
/test1.out
......
......@@ -136,6 +136,9 @@ ccm-test$(EXEEXT): ccm-test.$(OBJEXT)
cmac-test$(EXEEXT): cmac-test.$(OBJEXT)
$(LINK) cmac-test.$(OBJEXT) $(TEST_OBJS) -o cmac-test$(EXEEXT)
siv-test$(EXEEXT): siv-test.$(OBJEXT)
$(LINK) siv-test.$(OBJEXT) $(TEST_OBJS) -o siv-test$(EXEEXT)
poly1305-test$(EXEEXT): poly1305-test.$(OBJEXT)
$(LINK) poly1305-test.$(OBJEXT) $(TEST_OBJS) -o poly1305-test$(EXEEXT)
......
......@@ -27,7 +27,7 @@ TS_NETTLE_SOURCES = aes-test.c arcfour-test.c arctwo-test.c \
serpent-test.c twofish-test.c version-test.c \
knuth-lfib-test.c \
cbc-test.c cfb-test.c ctr-test.c gcm-test.c eax-test.c ccm-test.c \
cmac-test.c \
cmac-test.c siv-test.c \
poly1305-test.c chacha-poly1305-test.c \
hmac-test.c umac-test.c \
meta-hash-test.c meta-cipher-test.c\
......
/* siv-test.c
Self-test and vectors for AES-SIV mode ciphers
Copyright (C) 2018 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/.
*/
/* The
* test vectors have been collected from the following standards:
* RFC5297
*/
#include "testutils.h"
#include "aes.h"
#include "nettle-types.h"
#include "siv-cmac.h"
#include "knuth-lfib.h"
/* AEAD ciphers */
typedef void
nettle_encrypt_message_func(void *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t clength, uint8_t *dst, const uint8_t *src);
typedef int
nettle_decrypt_message_func(void *ctx,
size_t nlength, const uint8_t *nonce,
size_t alength, const uint8_t *adata,
size_t mlength, uint8_t *dst, const uint8_t *src);
static void
test_compare_results(const char *name,
const struct tstring *adata,
/* Expected results. */
const struct tstring *e_clear,
const struct tstring *e_cipher,
/* Actual results. */
const void *clear,
const void *cipher,
const void *digest) /* digest optional. */
{
if (digest && !MEMEQ(SIV_DIGEST_SIZE, e_cipher->data, digest))
{
fprintf(stderr, "%s digest failed:\nAdata:", name);
tstring_print_hex(adata);
fprintf(stderr, "\nInput: ");
tstring_print_hex(e_clear);
fprintf(stderr, "\nOutput: ");
print_hex(SIV_DIGEST_SIZE, digest);
fprintf(stderr, "\nExpected:");
print_hex(SIV_DIGEST_SIZE, e_cipher->data);
fprintf(stderr, "\n");
FAIL();
}
if (!MEMEQ(e_cipher->length, e_cipher->data, cipher))
{
fprintf(stderr, "%s: encryption failed\nAdata: ", name);
tstring_print_hex(adata);
fprintf(stderr, "\nInput: ");
tstring_print_hex(e_clear);
fprintf(stderr, "\nOutput: ");