Implement CMAC using TrippleDES as underlying cipher.
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- Makefile.in | 2 +- cmac-des3.c | 61 +++++++++++++++++++++++++++++++++++++++++++ cmac.h | 17 ++++++++++++ testsuite/cmac-test.c | 32 +++++++++++++++++++++++ 4 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 cmac-des3.c
diff --git a/Makefile.in b/Makefile.in index a6b8ffd6693e..8ade1834499d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -101,7 +101,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 cmac-aes256.c \ + cmac.c cmac-aes128.c cmac-aes256.c cmac-des3.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 \ diff --git a/cmac-des3.c b/cmac-des3.c new file mode 100644 index 000000000000..d2d55ca43e75 --- /dev/null +++ b/cmac-des3.c @@ -0,0 +1,61 @@ +/* cmac-des3.c + + CMAC using TrippleDES as the underlying cipher. + + Copyright (C) 2019 Dmitry Eremin-Solenikov + + 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_des3_set_key (struct cmac_des3_ctx *ctx, const uint8_t *key) +{ + CMAC64_SET_KEY (ctx, des3_set_key, des3_encrypt, key); +} + +void +cmac_des3_update (struct cmac_des3_ctx *ctx, + size_t length, const uint8_t *data) +{ + CMAC64_UPDATE (ctx, des3_encrypt, length, data); +} + +void +cmac_des3_digest (struct cmac_des3_ctx *ctx, + size_t length, uint8_t *digest) +{ + CMAC64_DIGEST (ctx, des3_encrypt, length, digest); +} + diff --git a/cmac.h b/cmac.h index 0cf9462d2120..ecad3778f71e 100644 --- a/cmac.h +++ b/cmac.h @@ -37,6 +37,7 @@ #define NETTLE_CMAC_H_INCLUDED
#include "aes.h" +#include "des.h" #include "nettle-types.h"
#ifdef __cplusplus @@ -61,6 +62,9 @@ extern "C" { #define cmac64_init nettle_cmac64_init #define cmac64_update nettle_cmac64_update #define cmac64_digest nettle_cmac64_digest +#define cmac_des3_set_key nettle_cmac_des3_set_key +#define cmac_des3_update nettle_cmac_des3_update +#define cmac_des3_digest nettle_cmac_des3_digest
struct cmac128_key { @@ -213,6 +217,19 @@ void cmac_aes256_digest(struct cmac_aes256_ctx *ctx, size_t length, uint8_t *digest);
+struct cmac_des3_ctx CMAC64_CTX(struct des3_ctx); + +void +cmac_des3_set_key(struct cmac_des3_ctx *ctx, const uint8_t *key); + +void +cmac_des3_update(struct cmac_des3_ctx *ctx, + size_t length, const uint8_t *data); + +void +cmac_des3_digest(struct cmac_des3_ctx *ctx, + size_t length, uint8_t *digest); + #ifdef __cplusplus } #endif diff --git a/testsuite/cmac-test.c b/testsuite/cmac-test.c index b1d4aa30dfbe..9d6682777dcf 100644 --- a/testsuite/cmac-test.c +++ b/testsuite/cmac-test.c @@ -26,12 +26,27 @@ const struct nettle_mac nettle_cmac_aes256 = (nettle_hash_digest_func*) cmac_aes256_digest };
+const struct nettle_mac nettle_cmac_des3 = +{ + "CMAC-3DES", + sizeof(struct cmac_des3_ctx), + CMAC64_DIGEST_SIZE, + DES3_KEY_SIZE, + + (nettle_set_key_func*) cmac_des3_set_key, + (nettle_hash_update_func*) cmac_des3_update, + (nettle_hash_digest_func*) cmac_des3_digest +}; + #define test_cmac_aes128(key, msg, ref) \ test_mac(&nettle_cmac_aes128, key, msg, ref)
#define test_cmac_aes256(key, msg, ref) \ test_mac(&nettle_cmac_aes256, key, msg, ref)
+#define test_cmac_des3(key, msg, ref) \ + test_mac(&nettle_cmac_des3, key, msg, ref) + void test_main(void) { @@ -96,4 +111,21 @@ test_main(void) SHEX("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17ad2b417be66c3710"), SHEX("e1992190549f6ed5696a2c056c315410"));
+ /* CMAC-3DES vectors from NIST SP800-38B examples */ + test_cmac_des3 (SHEX("0123456789abcdef23456789abcdef01456789abcdef0123"), + SDATA(""), + SHEX("7db0d37df936c550")); + + test_cmac_des3 (SHEX("0123456789abcdef23456789abcdef01456789abcdef0123"), + SHEX("6bc1bee22e409f96e93d7e117393172a"), + SHEX("30239cf1f52e6609")); + + test_cmac_des3 (SHEX("0123456789abcdef23456789abcdef01456789abcdef0123"), + SHEX("6bc1bee22e409f96e93d7e117393172aae2d8a57"), + SHEX("6c9f3ee4923f6be2")); + + + test_cmac_des3 (SHEX("0123456789abcdef23456789abcdef01456789abcdef0123"), + SHEX("6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e51"), + SHEX("99429bd0bf7904e5")); }