Commit 98bc9191 authored by Niels Möller's avatar Niels Möller

Merge branch 'siv-mode' into master-updates

parents ee5d6289 83296eb6
2019-06-06 Niels Möller <nisse@lysator.liu.se>
Update for cmac changes, enabling const for the _message functions.
* siv-cmac.c (_siv_s2v): Take a const struct cmac128_key as argument,
and use a local struct cmac128_ctx for message-specific state.
(siv_cmac_set_key): Take a struct cmac128_key as argument. Updated
callers.
(siv_cmac_encrypt_message, siv_cmac_decrypt_message): Take a const
struct cmac128_key as argument. Updated callers.
* siv-cmac.h (SIV_CMAC_CTX): Changed to use struct cmac128_key
rather than struct cmac128_ctx.
* siv-cmac-aes256.c (siv_cmac_aes256_encrypt_message)
(siv_cmac_aes256_decrypt_message): Likewise.
* siv-cmac-aes128.c (siv_cmac_aes128_encrypt_message)
(siv_cmac_aes128_decrypt_message): The ctx argument made const.
2019-05-15 Niels Möller <nisse@lysator.liu.se>
* siv-cmac.h (SIV_CMAC_AES128_KEY_SIZE, SIV_CMAC_AES256_KEY_SIZE):
New constants.
* testsuite/siv-test.c: Simplify tests a little.
* siv-cmac.h (SIV_MIN_NONCE_SIZE): New constant, 1.
* siv-cmac.c (_siv_s2v): Require non-empty nonce.
* nettle.texinfo (SIV-CMAC): Update documentation.
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.
* cmac.c (_cmac128_block_mulx): Renamed function...
(block_mulx): ... from old name.
* cmac-internal.h (_cmac128_block_mulx): New file, declare function.
* Makefile.in (DISTFILES): Added cmac-internal.h.
2019-06-26 Niels Möller <nisse@lysator.liu.se>
* Released nettle-3.5.1.
......
......@@ -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 \
......@@ -229,7 +230,7 @@ DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \
INSTALL NEWS ChangeLog \
nettle.pc.in hogweed.pc.in \
$(des_headers) descore.README desdata.stamp \
aes-internal.h camellia-internal.h serpent-internal.h \
aes-internal.h camellia-internal.h cmac-internal.h serpent-internal.h \
cast128_sboxes.h desinfo.h desCode.h \
ripemd160-internal.h sha2-internal.h \
memxor-internal.h nettle-internal.h nettle-write.h \
......
/* cmac-internal.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 "cmac.h"
#ifdef __cplusplus
extern "C" {
#endif
#define _cmac128_block_mulx _nettle_cmac128_block_mulx
void _cmac128_block_mulx(union nettle_block16 *out,
const union nettle_block16 *in);
#ifdef __cplusplus
}
#endif
#endif /* CMAC_INTERNAL_H_INCLUDED */
......@@ -44,13 +44,14 @@
#include "memxor.h"
#include "nettle-internal.h"
#include "cmac-internal.h"
#include "macros.h"
/* shift one and XOR with 0x87. */
#if WORDS_BIGENDIAN
static void
block_mulx(union nettle_block16 *dst,
const union nettle_block16 *src)
void
_cmac128_block_mulx(union nettle_block16 *dst,
const union nettle_block16 *src)
{
uint64_t carry = src->u64[0] >> 63;
dst->u64[0] = (src->u64[0] << 1) | (src->u64[1] >> 63);
......@@ -59,9 +60,9 @@ block_mulx(union nettle_block16 *dst,
#else /* !WORDS_BIGENDIAN */
#define LE_SHIFT(x) ((((x) & 0x7f7f7f7f7f7f7f7f) << 1) | \
(((x) & 0x8080808080808080) >> 15))
static void
block_mulx(union nettle_block16 *dst,
const union nettle_block16 *src)
void
_cmac128_block_mulx(union nettle_block16 *dst,
const union nettle_block16 *src)
{
uint64_t carry = (src->u64[0] & 0x80) >> 7;
dst->u64[0] = LE_SHIFT(src->u64[0]) | ((src->u64[1] & 0x80) << 49);
......@@ -79,8 +80,8 @@ cmac128_set_key(struct cmac128_key *key, const void *cipher,
/* step 1 - generate subkeys k1 and k2 */
encrypt(cipher, 16, L.b, zero_block.b);
block_mulx(&key->K1, &L);
block_mulx(&key->K2, &key->K1);
_cmac128_block_mulx(&key->K1, &L);
_cmac128_block_mulx(&key->K2, &key->K1);
}
void
......
......@@ -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,101 @@ 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 do not allow access to this
feature and also require the use of a non-empty nonce. 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.
@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
@defvr Constant SIV_MIN_NONCE_SIZE
The the minimum size for an @acronym{SIV-CMAC} nonce, 1.
@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->cmac_key, &ctx->cmac_cipher, &ctx->ctr_cipher, &nettle_aes128, key);
}
void
siv_cmac_aes128_encrypt_message(const 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->cmac_key, &ctx->cmac_cipher,
&nettle_aes128, &ctx->ctr_cipher,
nlength, nonce, alength, adata,
clength, dst, src);
}
int
siv_cmac_aes128_decrypt_message(const 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->cmac_key, &ctx->cmac_cipher,
&nettle_aes128, &ctx->ctr_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->cmac_key, &ctx->cmac_cipher, &ctx->ctr_cipher, &nettle_aes256, key);
}
void
siv_cmac_aes256_encrypt_message(const 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->cmac_key, &ctx->cmac_cipher,
&nettle_aes256, &ctx->ctr_cipher,
nlength, nonce, alength, adata,
clength, dst, src);
}
int
siv_cmac_aes256_decrypt_message(const 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->cmac_key, &ctx->cmac_cipher,
&nettle_aes256, &ctx->ctr_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,
const struct cmac128_key *cmac_key,
const void *cmac_cipher,
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 };
struct cmac128_ctx cmac_ctx;
assert (nlength >= SIV_MIN_NONCE_SIZE);
cmac128_init(&cmac_ctx);
cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, 16, const_zero.b);
cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, D.b);
_cmac128_block_mulx (&D, &D);
cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, alength, adata);
cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b);
memxor (D.b, S.b, 16);
_cmac128_block_mulx (&D, &D);
cmac128_update (&cmac_ctx, cmac_cipher, nc->encrypt, nlength, nonce);
cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, S.b);
memxor (D.b, S.b, 16);
/* Sn */
if (plength >= 16)
{
cmac128_update (&cmac_ctx, cmac_cipher, 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 (&cmac_ctx, cmac_cipher, nc->encrypt, 16, T.b);
cmac128_digest (&cmac_ctx, cmac_key, cmac_cipher, nc->encrypt, 16, v);
}
void
siv_cmac_set_key (struct cmac128_key *cmac_key, void *cmac_cipher, void *siv_cipher,
const struct nettle_cipher *nc, const uint8_t * key)
{
nc->set_encrypt_key (cmac_cipher, key);
cmac128_set_key (cmac_key, cmac_cipher, nc->encrypt);
nc->set_encrypt_key (siv_cipher, key + nc->key_size);
}
void
siv_cmac_encrypt_message (const struct cmac128_key *cmac_key,
const void *cmac_cipher,
const struct nettle_cipher *nc,
const void *ctr_cipher,
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, cmac_key, cmac_cipher, 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 (ctr_cipher, nc->encrypt, AES_BLOCK_SIZE, siv.b, slength,
dst + SIV_DIGEST_SIZE, src);
}
int
siv_cmac_decrypt_message (const struct cmac128_key *cmac_key,
const void *cmac_cipher,
const struct nettle_cipher *nc,
const void *ctr_cipher,
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 (ctr_cipher, nc->encrypt, AES_BLOCK_SIZE, ctr.b,
mlength, dst, src + SIV_DIGEST_SIZE);
/* create CTR nonce */
_siv_s2v (nc,
cmac_key, cmac_cipher, 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
#define SIV_MIN_NONCE_SIZE 1
void
siv_cmac_set_key(struct cmac128_key *cmac_key, void *cmac_cipher, void *ctr_cipher,
const struct nettle_cipher *nc,
const uint8_t *key);
void
siv_cmac_encrypt_message(const struct cmac128_key *cmac_key, const void *cmac_cipher_ctx,
const struct nettle_cipher *nc,
const void *ctr_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(const struct cmac128_key *cmac_key, const void *cmac_cipher,
const struct nettle_cipher *nc,
const void *ctr_cipher,
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_key cmac_key; type cmac_cipher; type ctr_cipher; }
/* SIV_CMAC_AES128 */
#define SIV_CMAC_AES128_KEY_SIZE 32
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(const 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(const 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 */
#define SIV_CMAC_AES256_KEY_SIZE 64
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(const 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(const 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
}