On Tue, 2018-01-16 at 14:25 +0100, Niels Möller wrote: > Nikos Mavrogiannopoulos <n.mavrogiannopou...@gmail.com> writes: > > > On Mon, Jan 15, 2018 at 9:37 PM Niels Möller <ni...@lysator.liu.se> > > wrote: > > > > > > + unsigned overflow = b2 & 0x8000000000000000; > > > > + > > > > + b1 <<= 1; > > > > + b2 <<= 1; > > > > + > > > > + if (overflow) > > > > + b1 |= 0x01; > > > > > > I'd write the shift as > > > > > > b1 = (b1 << 1) | (b2 >> 63); > > > b2 <<= 1; > > > > > > > I have bad experience with shifts over 31. I could switch it to > > that, but > > my understanding is that they don't universally work especially in > > 32-bit > > systems offerring 64-bit quantities. Given that this code is being > > used > > unconditionally and is not performance critical, I'd stay with the > > safe > > version, unless you have strong opinion about it. > > What problems have you seen? I've not heard of any C compilers which > have uint64_t but doesn't support shift properly (and this is the > simplest case, with unsigned values and constant shift count). The > idiom > I proposed is used all over the place in gmp, but there I guess we > don't > use 64-bit types on 32-bit platforms.
I do not seem to find any references for similar issues. Out of memory it was a report on the failure of a longer than 32-bit shift on an mips64 system. It's been long time ago and it may have been a compiler issue. I attach a patch to switch to the 63-bit switch on top of the previous one in case you prefer that version (seems simpler). > On the other hand, I think > > unsigned overflow = b2 & 0x8000000000000000; > is incorrect if int is 32 bit, won't the result be always zero? Thank you for the catch. Hopefully the x86 run on our CI would have caught it but I never run it there. I've now sent a build with the 0001 patch at: https://gitlab.com/nmav/nettle/pipelines/16256301 regards, Nikos
From 396f2ba4f3f238073e88364c7a6635d17505687e Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos <n...@redhat.com> Date: Wed, 10 Jan 2018 09:29:17 +0100 Subject: [PATCH 1/2] Added support for CMAC That adds support for CMAC as a generic framework for 128-bit block and key ciphers, as well as API for AES-128-CMAC. Signed-off-by: Nikos Mavrogiannopoulos <n...@redhat.com> --- Makefile.in | 2 + cmac-aes128.c | 60 ++++++++++++++++ cmac.c | 162 ++++++++++++++++++++++++++++++++++++++++++++ cmac.h | 118 ++++++++++++++++++++++++++++++++ examples/nettle-benchmark.c | 24 ++++++- nettle.texinfo | 47 ++++++++++++- testsuite/.test-rules.make | 3 + testsuite/Makefile.in | 1 + testsuite/cmac-test.c | 111 ++++++++++++++++++++++++++++++ 9 files changed, 526 insertions(+), 2 deletions(-) create mode 100644 cmac-aes128.c create mode 100644 cmac.c create mode 100644 cmac.h create mode 100644 testsuite/cmac-test.c diff --git a/Makefile.in b/Makefile.in index 6a0c13ec..a25c0f99 100644 --- a/Makefile.in +++ b/Makefile.in @@ -103,6 +103,7 @@ nettle_SOURCES = aes-decrypt-internal.c aes-decrypt.c \ gcm-aes256.c gcm-aes256-meta.c \ gcm-camellia128.c gcm-camellia128-meta.c \ gcm-camellia256.c gcm-camellia256-meta.c \ + cmac.c cmac-aes128.c \ gosthash94.c gosthash94-meta.c \ hmac.c hmac-md5.c hmac-ripemd160.c hmac-sha1.c \ hmac-sha224.c hmac-sha256.c hmac-sha384.c hmac-sha512.c \ @@ -195,6 +196,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 \ md2.h md4.h \ md5.h md5-compat.h \ memops.h memxor.h \ diff --git a/cmac-aes128.c b/cmac-aes128.c new file mode 100644 index 00000000..e53e114e --- /dev/null +++ b/cmac-aes128.c @@ -0,0 +1,60 @@ +/* cmac-aes128.c + + CMAC using AES128 as the underlying cipher. + + Copyright (C) 2017 Red Hat, Inc. + + 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 "cmac.h" + +void +cmac_aes128_set_key(struct cmac_aes128_ctx *ctx, const uint8_t *key) +{ + CMAC128_SET_KEY(ctx, aes128_set_encrypt_key, aes128_encrypt, key); +} + +void +cmac_aes128_update (struct cmac_aes128_ctx *ctx, + size_t length, const uint8_t *data) +{ + CMAC128_UPDATE (ctx, aes128_encrypt, length, data); +} + +void +cmac_aes128_digest(struct cmac_aes128_ctx *ctx, + size_t length, uint8_t *digest) +{ + CMAC128_DIGEST(ctx, aes128_encrypt, length, digest); +} diff --git a/cmac.c b/cmac.c new file mode 100644 index 00000000..a4d2468a --- /dev/null +++ b/cmac.c @@ -0,0 +1,162 @@ +/* + AES-CMAC-128 (rfc 4493) + Copyright (C) Stefan Metzmacher 2012 + Copyright (C) Jeremy Allison 2012 + Copyright (C) Michael Adam 2012 + Copyright (C) 2017, Red Hat Inc. + + 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 <stdlib.h> +#include <string.h> + +#include "cmac.h" + +#include "memxor.h" +#include "nettle-internal.h" +#include "macros.h" + +static const uint8_t const_zero[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +/* shift one and XOR with 0x87. */ +static inline void block_mulx(union nettle_block16 *out, + const union nettle_block16 *in) +{ + uint64_t b1 = READ_UINT64(in->b); + uint64_t b2 = READ_UINT64(in->b+8); + unsigned overflow = (b2 & UINT64_C(0x8000000000000000))?1:0; + + b1 <<= 1; + b2 <<= 1; + + if (overflow) + b1 |= 0x01; + + if (in->b[0] & 0x80) + b2 ^= 0x87; + + WRITE_UINT64(out->b, b1); + WRITE_UINT64(out->b+8, b2); +} + +void cmac128_set_key(struct cmac128 *ctx, void *key, + nettle_cipher_func *encrypt) +{ + union nettle_block16 *L = &ctx->block; + memset(ctx, 0, sizeof(*ctx)); + + /* step 1 - generate subkeys k1 and k2 */ + encrypt(key, 16, L->b, const_zero); + + block_mulx(&ctx->K1, L); + block_mulx(&ctx->K2, &ctx->K1); +} + +#define MIN(x,y) ((x)<(y)?(x):(y)) + +void cmac128_update(struct cmac128 *ctx, void *key, + nettle_cipher_func *encrypt, + size_t msg_len, const uint8_t *msg) +{ + union nettle_block16 Y; + /* + * check if we expand the block + */ + if (ctx->index < 16) { + size_t len = MIN(16 - ctx->index, msg_len); + memcpy(&ctx->block.b[ctx->index], msg, len); + msg += len; + msg_len -= len; + ctx->index += len; + } + + if (msg_len == 0) { + /* if it is still the last block, we are done */ + return; + } + + /* + * now checksum everything but the last block + */ + memxor3(Y.b, ctx->X.b, ctx->block.b, 16); + encrypt(key, 16, ctx->X.b, Y.b); + + while (msg_len > 16) { + memxor3(Y.b, ctx->X.b, msg, 16); + encrypt(key, 16, ctx->X.b, Y.b); + msg += 16; + msg_len -= 16; + } + + /* + * copy the last block, it will be processed in + * cmac128_digest(). + */ + memcpy(ctx->block.b, msg, msg_len); + ctx->index = msg_len; +} + +void cmac128_digest(struct cmac128 *ctx, void *key, + nettle_cipher_func *encrypt, + unsigned length, + uint8_t *out) +{ + union nettle_block16 Y; + + memset(ctx->block.b+ctx->index, 0, sizeof(ctx->block.b)-ctx->index); + + /* re-use ctx->block for memxor output */ + if (ctx->index < 16) { + ctx->block.b[ctx->index] = 0x80; + memxor(ctx->block.b, ctx->K2.b, 16); + } else { + memxor(ctx->block.b, ctx->K1.b, 16); + } + + memxor3(Y.b, ctx->block.b, ctx->X.b, 16); + + assert(length <= 16); + if (length == 16) { + encrypt(key, 16, out, Y.b); + } else { + encrypt(key, 16, ctx->block.b, Y.b); + memcpy(out, ctx->block.b, length); + } + + /* reset state for re-use */ + memset(&ctx->X, 0, sizeof(ctx->X)); + ctx->index = 0; +} diff --git a/cmac.h b/cmac.h new file mode 100644 index 00000000..168ca95a --- /dev/null +++ b/cmac.h @@ -0,0 +1,118 @@ +/* cmac.h + + CMAC mode, as specified in RFC4493 + + 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_H_INCLUDED +#define NETTLE_CMAC_H_INCLUDED + +#include "aes.h" +#include "nettle-types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CMAC128_KEY_SIZE 16 +#define CMAC128_DIGEST_SIZE 16 + +#define cmac128_set_key nettle_cmac128_set_key +#define cmac128_update nettle_cmac128_update +#define cmac128_digest nettle_cmac128_digest +#define cmac_aes128_set_key nettle_cmac_aes128_set_key +#define cmac_aes128_update nettle_cmac_aes128_update +#define cmac_aes128_digest nettle_cmac_aes128_digest + +struct cmac128 { + union nettle_block16 K1; + union nettle_block16 K2; + + union nettle_block16 X; + + union nettle_block16 block; + size_t index; +}; + +void cmac128_set_key(struct cmac128 *ctx, void *key, + nettle_cipher_func *encrypt); +void cmac128_update(struct cmac128 *ctx, void *key, + nettle_cipher_func *encrypt, + size_t msg_len, const uint8_t *msg); +void cmac128_digest(struct cmac128 *ctx, void *key, + nettle_cipher_func *encrypt, + unsigned length, + uint8_t *out); + + +#define CMAC128_CTX(type) \ + { struct cmac128 data; type cipher; } + +/* NOTE: Avoid using NULL, as we don't include anything defining it. */ +#define CMAC128_SET_KEY(ctx, set_key, encrypt, cmac_key) \ + do { \ + (set_key)(&(ctx)->cipher, (cmac_key)); \ + if (0) (encrypt)(&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0); \ + cmac128_set_key(&(ctx)->data, &(ctx)->cipher, \ + (nettle_cipher_func *) (encrypt)); \ + } while (0) + +#define CMAC128_UPDATE(ctx, encrypt, length, data) \ + cmac128_update(&(ctx)->data, &(ctx)->cipher, \ + (nettle_cipher_func *)encrypt, (length), (data)) + +#define CMAC128_DIGEST(ctx, encrypt, length, digest) \ + (0 ? (encrypt)(&(ctx)->cipher, ~(size_t) 0, \ + (uint8_t *) 0, (const uint8_t *) 0) \ + : cmac128_digest(&(ctx)->data, &(ctx)->cipher, \ + (nettle_cipher_func *) (encrypt), \ + (length), (digest))) + +struct cmac_aes128_ctx CMAC128_CTX(struct aes128_ctx); + +void +cmac_aes128_set_key(struct cmac_aes128_ctx *ctx, const uint8_t *key); + +void +cmac_aes128_update(struct cmac_aes128_ctx *ctx, + size_t length, const uint8_t *data); + +void +cmac_aes128_digest(struct cmac_aes128_ctx *ctx, + size_t length, uint8_t *digest); + +#ifdef __cplusplus +} +#endif + +#endif /* CMAC_H_INCLUDED */ diff --git a/examples/nettle-benchmark.c b/examples/nettle-benchmark.c index 9327881b..9ecc095e 100644 --- a/examples/nettle-benchmark.c +++ b/examples/nettle-benchmark.c @@ -64,6 +64,7 @@ #include "sha3.h" #include "twofish.h" #include "umac.h" +#include "cmac.h" #include "poly1305.h" #include "nettle-meta.h" @@ -403,7 +404,7 @@ time_umac(void) struct umac64_ctx ctx64; struct umac96_ctx ctx96; struct umac128_ctx ctx128; - + uint8_t key[16]; umac32_set_key (&ctx32, key); @@ -439,6 +440,24 @@ time_umac(void) time_function(bench_hash, &info)); } +static void +time_cmac(void) +{ + static uint8_t data[BENCH_BLOCK]; + struct bench_hash_info info; + struct cmac_aes128_ctx ctx; + + uint8_t key[16]; + + cmac_aes128_set_key (&ctx, key); + info.ctx = &ctx; + info.update = (nettle_hash_update_func *) cmac_aes128_update; + info.data = data; + + display("cmac-aes128", "update", AES_BLOCK_SIZE, + time_function(bench_hash, &info)); +} + static void time_poly1305_aes(void) { @@ -845,6 +864,9 @@ main(int argc, char **argv) if (!alg || strstr ("umac", alg)) time_umac(); + if (!alg || strstr ("cmac", alg)) + time_cmac(); + if (!alg || strstr ("poly1305-aes", alg)) time_poly1305_aes(); diff --git a/nettle.texinfo b/nettle.texinfo index aa374449..4a2d286f 100644 --- a/nettle.texinfo +++ b/nettle.texinfo @@ -101,6 +101,7 @@ Keyed Hash Functions * HMAC:: * UMAC:: +* CMAC:: Public-key algorithms @@ -271,6 +272,9 @@ The implementation of the TWOFISH cipher is written by Ruud de Rooij. @item UMAC Written by @value{AUTHOR}. +@item CMAC +Written by Nikos Mavrogiannopoulos, @value{AUTHOR}, Jeremy Allison, Michael Adam and Stefan Metzmacher. + @item RSA Written by @value{AUTHOR}. Uses the GMP library for bignum operations. @@ -3066,6 +3070,7 @@ as well. @menu * HMAC:: * UMAC:: +* CMAC:: * Poly1305:: @end menu @@ -3408,7 +3413,47 @@ as described above, the new value is used unless you call the @code{_set_nonce} function explicitly for each message. @end deftypefun -@node Poly1305,, UMAC, Keyed hash functions +@node CMAC,, UMAC, Keyed hash functions +@subsection @acronym{CMAC} +@cindex CMAC + +@acronym{CMAC} is a message authentication code based on CBC encryption +mode. It is suitable for systems where block ciphers are preferrable +and perform better than hash functions. @acronym{CMAC} is specified in +@cite{RFC4493}. The secret key is always 128 bits (16 octets). + +Nettle provides helper functions for @acronym{CMAC } with +the @acronym{AES} block cipher. + +Nettle defines @acronym{CMAC} in @file{<nettle/cmac.h>}. + +@deftp {Context struct} {struct cmac128_ctx} +@end deftp + +@defvr Constant CMAC128_KEY_SIZE +The CMAC key size, 16. +@end defvr +@defvr Constant CMAC128_DIGEST_SIZE +The size of an CMAC digest, 16. +@end defvr + +@deftypefun void cmac_aes128_set_key (struct cmac_aes128_ctx *@var{ctx}, const uint8_t *@var{key}) +This function initializes the @acronym{CMAC} context struct. +@end deftypefun + +@deftypefun void cmac_aes128_update (struct cmac_aes128_ctx *@var{ctx}, size_t @var{length}, const uint8_t *@var{data}) +This function is called zero or more times to process the message. +@end deftypefun + +@deftypefun void cmac_aes128_digest (struct cmac_aes128_ctx *@var{ctx}, size_t @var{length}, uint8_t *@var{digest}) +Extracts the @acronym{MAC} of the message, writing it to @var{digest}. +@var{length} is usually equal to the specified output size, but if you +provide a smaller value, only the first @var{length} octets of the +@acronym{MAC} are written. This function resets the context for +processing of a new message with the same key. +@end deftypefun + +@node Poly1305,, CMAC, Keyed hash functions @comment node-name, next, previous, up @subsection Poly1305 diff --git a/testsuite/.test-rules.make b/testsuite/.test-rules.make index 1f780310..c7e04cb4 100644 --- a/testsuite/.test-rules.make +++ b/testsuite/.test-rules.make @@ -130,6 +130,9 @@ eax-test$(EXEEXT): eax-test.$(OBJEXT) ccm-test$(EXEEXT): ccm-test.$(OBJEXT) $(LINK) ccm-test.$(OBJEXT) $(TEST_OBJS) -o ccm-test$(EXEEXT) +cmac-test$(EXEEXT): cmac-test.$(OBJEXT) + $(LINK) cmac-test.$(OBJEXT) $(TEST_OBJS) -o cmac-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 3117d66d..dd1ecf41 100644 --- a/testsuite/Makefile.in +++ b/testsuite/Makefile.in @@ -26,6 +26,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 \ 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/cmac-test.c b/testsuite/cmac-test.c new file mode 100644 index 00000000..983c5127 --- /dev/null +++ b/testsuite/cmac-test.c @@ -0,0 +1,111 @@ +#include "testutils.h" +#include "nettle-internal.h" +#include "cmac.h" + +static void +test_cmac_hash (const struct tstring *key, const struct tstring *msg, const struct tstring *ref) +{ + struct cmac_aes128_ctx ctx; + uint8_t digest[16]; + unsigned i; + + ASSERT (ref->length == sizeof(digest)); + ASSERT (key->length == 16); + cmac_aes128_set_key (&ctx, key->data); + cmac_aes128_update (&ctx, msg->length, msg->data); + cmac_aes128_digest (&ctx, sizeof(digest), digest); + if (!MEMEQ (ref->length, ref->data, digest)) + { + fprintf (stderr, "cmac_hash failed, msg: "); + print_hex (msg->length, msg->data); + fprintf(stderr, "Output:"); + print_hex (16, digest); + fprintf(stderr, "Expected:"); + tstring_print_hex(ref); + fprintf(stderr, "\n"); + FAIL(); + } + + /* attempt to re-use the structure */ + cmac_aes128_update (&ctx, msg->length, msg->data); + cmac_aes128_digest (&ctx, sizeof(digest), digest); + if (!MEMEQ (ref->length, ref->data, digest)) + { + fprintf (stderr, "cmac_hash failed on re-use, msg: "); + print_hex (msg->length, msg->data); + fprintf(stderr, "Output:"); + print_hex (16, digest); + fprintf(stderr, "Expected:"); + tstring_print_hex(ref); + fprintf(stderr, "\n"); + FAIL(); + } + + /* attempt byte-by-byte hashing */ + cmac_aes128_set_key (&ctx, key->data); + for (i=0;i<msg->length;i++) + cmac_aes128_update (&ctx, 1, msg->data+i); + cmac_aes128_digest (&ctx, sizeof(digest), digest); + if (!MEMEQ (ref->length, ref->data, digest)) + { + fprintf (stderr, "cmac_hash failed on byte-by-byte, msg: "); + print_hex (msg->length, msg->data); + fprintf(stderr, "Output:"); + print_hex (16, digest); + fprintf(stderr, "Expected:"); + tstring_print_hex(ref); + fprintf(stderr, "\n"); + FAIL(); + } +} + +void +test_main(void) +{ + /* + * CMAC-AES Test Vectors from RFC4493. + */ + + test_cmac_hash (SHEX("2b7e151628aed2a6abf7158809cf4f3c"), + SDATA(""), + SHEX("bb1d6929e95937287fa37d129b756746")); + + test_cmac_hash (SHEX("2b7e151628aed2a6abf7158809cf4f3c"), + SHEX("6bc1bee22e409f96e93d7e117393172a"), + SHEX("070a16b46b4d4144f79bdd9dd04a287c")); + + test_cmac_hash (SHEX("2b7e151628aed2a6abf7158809cf4f3c"), + SHEX("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411"), + SHEX("dfa66747de9ae63030ca32611497c827")); + + test_cmac_hash (SHEX("2b7e151628aed2a6abf7158809cf4f3c"), + SHEX("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411e5fbc1191a0a52ef" + "f69f2445df4f9b17ad2b417be66c3710"), + SHEX("51f0bebf7e3b9d92fc49741779363cfe")); + + /* Additional tests with different keys (same plaintext) + * to check all variants of set_key() */ + test_cmac_hash (SHEX("2b7e151628aed2a8abf7158809cf4f3c"), + SHEX("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411"), + SHEX("87dd33c2945a4e228028690ae8954945")); + + test_cmac_hash (SHEX("2b7e1ab628aed2a8abf7158809cf4f3c"), + SHEX("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411"), + SHEX("f0dc613a88886c7ed76eeb51f1c5e8d3")); + + test_cmac_hash (SHEX("2b7e1ab628aed2a8abf7158809cf4f3d"), + SHEX("6bc1bee22e409f96e93d7e117393172a" + "ae2d8a571e03ac9c9eb76fac45af8e51" + "30c81c46a35ce411"), + SHEX("b9d092dc387a9e42cdfeb9f9930cf567")); + +} + -- 2.14.3
From ace3ada217319019663b4dec92b6e2980324c077 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos <n...@redhat.com> Date: Wed, 17 Jan 2018 10:47:23 +0100 Subject: [PATCH 2/2] cmac: block_mulx: simplify shifts Signed-off-by: Nikos Mavrogiannopoulos <n...@redhat.com> --- cmac.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cmac.c b/cmac.c index a4d2468a..27df917e 100644 --- a/cmac.c +++ b/cmac.c @@ -57,14 +57,10 @@ static inline void block_mulx(union nettle_block16 *out, { uint64_t b1 = READ_UINT64(in->b); uint64_t b2 = READ_UINT64(in->b+8); - unsigned overflow = (b2 & UINT64_C(0x8000000000000000))?1:0; - b1 <<= 1; + b1 = (b1 << 1) | (b2 >> 63); b2 <<= 1; - if (overflow) - b1 |= 0x01; - if (in->b[0] & 0x80) b2 ^= 0x87; -- 2.14.3
_______________________________________________ nettle-bugs mailing list nettle-bugs@lists.lysator.liu.se http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs