diff options
author | Niels Möller <nisse@lysator.liu.se> | 2019-07-02 14:28:04 +0200 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2019-07-02 14:28:04 +0200 |
commit | 98bc919114f2272a8b2537467213de4a0fb776e4 (patch) | |
tree | 7ba0d138ad75a2604717cf6e2c4c861c2b3479c8 | |
parent | ee5d62898cf070f08beedc410a8d7c418588bd95 (diff) | |
parent | 83296eb6a45f7dba125372a2ce3c8f4d6c8b9934 (diff) | |
download | nettle-98bc919114f2272a8b2537467213de4a0fb776e4.tar.gz |
Merge branch 'siv-mode' into master-updates
-rw-r--r-- | ChangeLog | 58 | ||||
-rw-r--r-- | Makefile.in | 5 | ||||
-rw-r--r-- | cmac-internal.h | 54 | ||||
-rw-r--r-- | cmac.c | 17 | ||||
-rw-r--r-- | nettle.texinfo | 99 | ||||
-rw-r--r-- | siv-cmac-aes128.c | 77 | ||||
-rw-r--r-- | siv-cmac-aes256.c | 77 | ||||
-rw-r--r-- | siv-cmac.c | 165 | ||||
-rw-r--r-- | siv-cmac.h | 134 | ||||
-rw-r--r-- | testsuite/.gitignore | 2 | ||||
-rw-r--r-- | testsuite/.test-rules.make | 3 | ||||
-rw-r--r-- | testsuite/Makefile.in | 2 | ||||
-rw-r--r-- | testsuite/siv-test.c | 382 |
13 files changed, 1063 insertions, 12 deletions
@@ -1,3 +1,61 @@ +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. diff --git a/Makefile.in b/Makefile.in index 537e97d1..b54e64b0 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-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 \ diff --git a/cmac-internal.h b/cmac-internal.h new file mode 100644 index 00000000..80db7fcc --- /dev/null +++ b/cmac-internal.h @@ -0,0 +1,54 @@ +/* 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 diff --git a/nettle.texinfo b/nettle.texinfo index b8579a6e..9cdec480 100644 --- a/nettle.texinfo +++ b/nettle.texinfo @@ -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 diff --git a/siv-cmac-aes128.c b/siv-cmac-aes128.c new file mode 100644 index 00000000..82ac16e9 --- /dev/null +++ b/siv-cmac-aes128.c @@ -0,0 +1,77 @@ +/* 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); +} diff --git a/siv-cmac-aes256.c b/siv-cmac-aes256.c new file mode 100644 index 00000000..9401bbf1 --- /dev/null +++ b/siv-cmac-aes256.c @@ -0,0 +1,77 @@ +/* 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); +} diff --git a/siv-cmac.c b/siv-cmac.c new file mode 100644 index 00000000..f498cb86 --- /dev/null +++ b/siv-cmac.c @@ -0,0 +1,165 @@ +/* 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); +} diff --git a/siv-cmac.h b/siv-cmac.h new file mode 100644 index 00000000..c631a41e --- /dev/null +++ b/siv-cmac.h @@ -0,0 +1,134 @@ +/* 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 +} +#endif + +#endif /* NETTLE_SIV_H_INCLUDED */ diff --git a/testsuite/.gitignore b/testsuite/.gitignore index 4d680cd1..066bcee2 100644 --- a/testsuite/.gitignore +++ b/testsuite/.gitignore @@ -95,6 +95,8 @@ /version-test /yarrow-test /xts-test +/cmac-test +/siv-test /test.in /test1.out diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make index ab22da23..efb7df3c 100644 --- a/testsuite/.test-rules.make +++ b/testsuite/.test-rules.make @@ -133,6 +133,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) diff --git a/testsuite/Makefile.in b/testsuite/Makefile.in index 9a1fe209..f8f85701 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -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\ diff --git a/testsuite/siv-test.c b/testsuite/siv-test.c new file mode 100644 index 00000000..627e3844 --- /dev/null +++ b/testsuite/siv-test.c @@ -0,0 +1,382 @@ +/* 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: "); + print_hex(e_cipher->length, cipher); + fprintf(stderr, "\nExpected:"); + tstring_print_hex(e_cipher); + fprintf(stderr, "\n"); + FAIL(); + } + if (!MEMEQ(e_clear->length, e_clear->data, clear)) + { + fprintf(stderr, "%s decrypt failed:\nAdata:", name); + tstring_print_hex(adata); + fprintf(stderr, "\nInput: "); + tstring_print_hex(e_cipher); + fprintf(stderr, "\nOutput: "); + print_hex(e_clear->length, clear); + fprintf(stderr, "\nExpected:"); + tstring_print_hex(e_clear); + fprintf(stderr, "\n"); + FAIL(); + } +} /* test_compare_results */ + +static void +test_cipher_siv(const char *name, + nettle_set_key_func *siv_set_key, + nettle_encrypt_message_func *siv_encrypt, + nettle_decrypt_message_func *siv_decrypt, + size_t context_size, size_t key_size, + const struct tstring *key, + const struct tstring *nonce, + const struct tstring *authdata, + const struct tstring *cleartext, + const struct tstring *ciphertext) +{ + void *ctx = xalloc(context_size); + uint8_t *en_data; + uint8_t *de_data; + int ret; + + ASSERT (key->length == key_size); + ASSERT (cleartext->length + SIV_DIGEST_SIZE == ciphertext->length); + + de_data = xalloc(cleartext->length+SIV_DIGEST_SIZE); + en_data = xalloc(ciphertext->length); + + /* Ensure we get the same answers using the all-in-one API. */ + memset(de_data, 0, cleartext->length); + memset(en_data, 0, ciphertext->length); + + siv_set_key(ctx, key->data); + siv_encrypt(ctx, nonce->length, nonce->data, + authdata->length, authdata->data, + cleartext->length+SIV_DIGEST_SIZE, en_data, cleartext->data); + + ret = siv_decrypt(ctx, nonce->length, nonce->data, + authdata->length, authdata->data, + cleartext->length, de_data, ciphertext->data); + + if (ret != 1) fprintf(stderr, "siv_decrypt_message failed to validate message\n"); + test_compare_results(name, authdata, + cleartext, ciphertext, de_data, en_data, NULL); + + test_compare_results(name, authdata, + cleartext, ciphertext, de_data, en_data, en_data); + + + /* Ensure that we can detect corrupted message or tag data. */ + en_data[0] ^= 1; + ret = siv_decrypt(ctx, nonce->length, nonce->data, + authdata->length, authdata->data, + ciphertext->length, de_data, en_data); + if (ret != 0) fprintf(stderr, "siv_decrypt_message failed to detect corrupted message\n"); + + /* Ensure we can detect corrupted adata. */ + if (authdata->length) { + en_data[0] ^= 1; + ret = siv_decrypt(ctx, nonce->length, nonce->data, + authdata->length-1, authdata->data, + ciphertext->length, de_data, en_data); + if (ret != 0) fprintf(stderr, "siv_decrypt_message failed to detect corrupted message\n"); + } + + + free(ctx); + free(en_data); + free(de_data); +} + +#define test_siv_aes128(name, key, nonce, authdata, cleartext, ciphertext) \ + test_cipher_siv(name, (nettle_set_key_func*)siv_cmac_aes128_set_key, \ + (nettle_encrypt_message_func*)siv_cmac_aes128_encrypt_message, \ + (nettle_decrypt_message_func*)siv_cmac_aes128_decrypt_message, \ + sizeof(struct siv_cmac_aes128_ctx), SIV_CMAC_AES128_KEY_SIZE, \ + key, nonce, authdata, cleartext, ciphertext) + +#define test_siv_aes256(name, key, nonce, authdata, cleartext, ciphertext) \ + test_cipher_siv(name, (nettle_set_key_func*)siv_cmac_aes256_set_key, \ + (nettle_encrypt_message_func*)siv_cmac_aes256_encrypt_message, \ + (nettle_decrypt_message_func*)siv_cmac_aes256_decrypt_message, \ + sizeof(struct siv_cmac_aes256_ctx), SIV_CMAC_AES256_KEY_SIZE, \ + key, nonce, authdata, cleartext, ciphertext) + +void +test_main(void) +{ + /* The following tests were checked for interoperability against libaes_siv */ + + /* + * Example with small nonce, no AD and no plaintext + */ + test_siv_aes128("SIV_CMAC_AES128", + SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0" + "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"), + SHEX("01"), + SHEX(""), + SHEX(""), + SHEX("c696f84f df92aba3 c31c23d5 f2087513")); + /* + * Example with small nonce, no AD and plaintext + */ + test_siv_aes128("SIV_CMAC_AES128", + SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0" + "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"), + SHEX("02"), + SHEX(""), + SHEX("00112233 44556677 8899aabb ccddeeff"), + SHEX("5027b101 589747b8 865a9790 d3fd51d7" + "1f259d40 5bfa260b 9ba1d60a a287fd0b")); + + /* + * Example with length < 16 + */ + test_siv_aes128("SIV_CMAC_AES128", + SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0" + "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"), + SHEX("02"), + SHEX("10111213 14151617 18191a1b 1c1d1e1f" + "20212223 24252627"), + SHEX("11223344 55667788 99aabbcc ddee"), + SHEX("7300cd9b 3f514a44 ed660db6 14157f59" + "f0382e23 ae0e6e62 27a03dd3 2619")); + + /* + * Example with length > 16 + */ + test_siv_aes128("SIV_CMAC_AES128", + SHEX("7f7e7d7c 7b7a7978 77767574 73727170" + "40414243 44454647 48494a4b 4c4d4e4f"), + SHEX("020304"), + 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("f1dba33d e5b3369e 883f67b6 fc823cee" + "a4ffb87f dba97c89 44a62325 f133b4e0" + "1ca55276 e2261c1a 1d1d4248 d1da30ba" + "52b9c8d7 955d65c8 d2ce6eb7 e367d0")); + + /* + * Example with single AAD, length > 16 + */ + test_siv_aes128("SIV_CMAC_AES128", + SHEX("7f7e7d7c 7b7a7978 77767574 73727170" + "40414243 44454647 48494a4b 4c4d4e4f"), + SHEX("09f91102 9d74e35b d84156c5 635688c0"), + 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("85825e22 e90cf2dd da2c548d c7c1b631" + "0dcdaca0 cebf9dc6 cb90583f 5bf1506e" + "02cd4883 2b00e4e5 98b2b22a 53e6199d" + "4df0c166 6a35a043 3b250dc1 34d776")); + + /* + * Example with single AAD, length < 16 + */ + test_siv_aes128("SIV_CMAC_AES128", + SHEX("7f7e7d7c 7b7a7978 77767574 73727170" + "40414243 44454647 48494a4b 4c4d4e4f"), + SHEX("09f91102 9d74e35b d84156c5 635688c0"), + SHEX("00112233 44556677 8899aabb ccddeeff" + "deaddada deaddada ffeeddcc bbaa9988" + "77665544 33221100"), + SHEX("11223344 55667788 99aabbcc ddee"), + SHEX("15f83882 14bdc94e 3ec4c7c3 69863746" + "cd72d317 4b20a1e4 a0894fb7 cd78")); + + /* AES-SIV-CMAC-512 (AES-256) from dchest/siv repo + */ + test_siv_aes256("SIV_CMAC_AES256", + SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0" + "6f6e6d6c 6b6a6968 67666564 63626160" + "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff" + "00010203 04050607 08090a0b 0c0d0e0f"), + SHEX("02"), + SHEX("10111213 14151617 18191a1b 1c1d1e1f" + "20212223 24252627"), + SHEX("11223344 55667788 99aabbcc ddee"), + SHEX("6f740b42 1e2972d8 5e76189e 99842843" + "ad9e6ff1 4ea97c32 ab315e67 464c")); + + + /* AES-SIV-CMAC-512 (AES-256) + */ + test_siv_aes256("SIV_CMAC_AES256", + SHEX("c27df2fd aec35d4a 2a412a50 c3e8c47d" + "2d568e91 a38e5414 8abdc0b6 e86caf87" + "695c0a8a df4c5f8e b2c6c8b1 36529864" + "f3b84b3a e8e3676c e760c461 f3a13e83"), + SHEX("02"), + SHEX("10111213 14151617 18191a1b 1c1d1e1f" + "20212223 24252627"), + SHEX("11223344 55667788 99aabbcc ddee"), + SHEX("c3366ef8 92911eac 3d17f29a 37d4ebad" + "ddc1219e bbde06d1 ee893e55 a39f")); + + /* + * Example with length > 16 + */ + test_siv_aes256("SIV_CMAC_AES256", + SHEX("c27df2fd aec35d4a 2a412a50 c3e8c47d" + "2d568e91 a38e5414 8abdc0b6 e86caf87" + "695c0a8a df4c5f8e b2c6c8b1 36529864" + "f3b84b3a e8e3676c e760c461 f3a13e83"), + SHEX("02"), + 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("bbe4751a 549d2fce 410c2efd e0df4d13" + "1a6eac0d 030028f8 dc16b6c4 3a557d4e" + "3e846ad7 52c5a030 c75a85ff 8b07ff10" + "71b133f5 edac3c60 8bb6eb13 dd1fd9")); + + /* + * Example with single AAD, length > 16 + */ + test_siv_aes256("SIV_CMAC_AES256", + SHEX("c27df2fd aec35d4a 2a412a50 c3e8c47d" + "2d568e91 a38e5414 8abdc0b6 e86caf87" + "695c0a8a df4c5f8e b2c6c8b1 36529864" + "f3b84b3a e8e3676c e760c461 f3a13e83"), + SHEX("09f91102 9d74e35b d84156c5 635688c0"), + 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("5a979b0d a58fde80 51621ae6 bf96feda" + "50933da8 047bc306 fabaf0c3 d9fa8471" + "c70a7def 39a2f91d 68a2021c 99ac7e2a" + "24535a13 4ba23ec1 5787cebe 5c53cc")); + + /* The following tests were checked for interoperability against miscreant.js */ + + /* + * Example from miscreant.js with no AD + * https://github.com/miscreant/miscreant.js/blob/master/vectors/aes_siv_aead.tjson + */ + test_siv_aes128("SIV_CMAC_AES128", + SHEX("fffefdfc fbfaf9f8 f7f6f5f4 f3f2f1f0" + "f0f1f2f3 f4f5f6f7 f8f9fafb fcfdfeff"), + SHEX("10111213 1415161718191a1b1 c1d1e1f2" + "02122232 4252627"), + SHEX(""), + SHEX("11223344 55667788 99aabbcc ddee"), + SHEX("4b3d0f15 ae9ffa9e 65b94942 1582ef70" + "e410910d 6446c775 9ebff9b5 385a")); + + /* + * Example from miscreant.js with AD + */ + test_siv_aes128("SIV_CMAC_AES128", + SHEX("7f7e7d7c 7b7a7978 77767574 73727170" + "40414243 44454647 48494a4b 4c4d4e4f"), + SHEX("09f91102 9d74e35b d84156c5 635688c0"), + 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("85825e22 e90cf2dd da2c548d c7c1b631" + "0dcdaca0 cebf9dc6 cb90583f 5bf1506e" + "02cd4883 2b00e4e5 98b2b22a 53e6199d" + "4df0c166 6a35a043 3b250dc1 34d776")); +} |