From 0631293ac4d6a3e081a00da754ce50bcdf39c2a8 Mon Sep 17 00:00:00 2001 From: Gregor Pintar Date: Tue, 24 Dec 2013 11:36:52 +0100 Subject: [PATCH] XCBC mac added --- README | 2 +- include/kripto/mac/xcbc.h | 9 ++ lib/mac/xcbc.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++ test/mac/xcbc.c | 65 ++++++++++++++ 4 files changed, 288 insertions(+), 1 deletion(-) create mode 100644 include/kripto/mac/xcbc.h create mode 100644 lib/mac/xcbc.c create mode 100644 test/mac/xcbc.c diff --git a/README b/README index c997b78..c64d84a 100644 --- a/README +++ b/README @@ -117,7 +117,7 @@ MAC's: - HMAC - OMAC (CMAC1) - CMAC2*? - - XCBC* + - XCBC - CBC*? - Keccak1600 - Keccak800 diff --git a/include/kripto/mac/xcbc.h b/include/kripto/mac/xcbc.h new file mode 100644 index 0000000..099726c --- /dev/null +++ b/include/kripto/mac/xcbc.h @@ -0,0 +1,9 @@ +#ifndef KRIPTO_MAC_XCBC_H +#define KRIPTO_MAC_XCBC_H + +#include +#include + +extern kripto_mac_desc *kripto_mac_xcbc(const kripto_block_desc *block); + +#endif diff --git a/lib/mac/xcbc.c b/lib/mac/xcbc.c new file mode 100644 index 0000000..1e42a34 --- /dev/null +++ b/lib/mac/xcbc.c @@ -0,0 +1,213 @@ +/* + * Written in 2013 by Gregor Pintar + * + * To the extent possible under law, the author(s) have dedicated + * all copyright and related and neighboring rights to this software + * to the public domain worldwide. + * + * This software is distributed without any warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication. + * If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +struct kripto_mac +{ + struct kripto_mac_object obj; + kripto_block *block; + uint8_t *buf; + uint8_t *k2; + uint8_t *k3; + unsigned int len; + unsigned int i; + int f; +}; + +static int xcbc_init(kripto_mac *s, unsigned int r) +{ + unsigned int i; + + /* key 1 */ + for(i = 0; i < s->len; i++) s->buf[i] = 1; + kripto_block_encrypt(s->block, s->buf, s->buf); + + /* key 2 */ + for(i = 0; i < s->len; i++) s->k2[i] = 2; + kripto_block_encrypt(s->block, s->k2, s->k2); + + /* key 3 */ + for(i = 0; i < s->len; i++) s->k3[i] = 3; + kripto_block_encrypt(s->block, s->k3, s->k3); + + s->block = kripto_block_recreate(s->block, r, s->buf, s->len); + if(!s->block) return -1; + + memset(s->buf, 0, s->len); + s->i = 0; + s->f = 0; + + return 0; +} + +static void xcbc_input(kripto_mac *s, const void *in, size_t len) +{ + size_t i; + + for(i = 0; i < len; i++) + { + s->buf[s->i++] ^= CU8(in)[i]; + + if(s->i == s->len) + { + kripto_block_encrypt(s->block, s->buf, s->buf); + s->i = 0; + } + } +} + +static void xcbc_tag(kripto_mac *s, void *tag, unsigned int len) +{ + unsigned int i; + + if(!s->f) + { + /* finish */ + if(s->i) + { + /* pad */ + s->buf[s->i] ^= 0x80; + + /* key 3 */ + for(i = 0; i < s->len; i++) + s->buf[i] ^= s->k3[i]; + } + else + { + /* key 2 */ + for(i = 0; i < s->len; i++) + s->buf[i] ^= s->k2[i]; + } + + kripto_block_encrypt(s->block, s->buf, s->buf); + s->i = 0; + s->f = -1; + } + + /* output */ + for(i = 0; i < len; i++) + { + assert(s->i < s->len); + U8(tag)[i] = s->buf[s->i++]; + } +} + +static void xcbc_destroy(kripto_mac *s) +{ + kripto_block_destroy(s->block); + + kripto_memwipe(s, sizeof(kripto_mac) + s->len * 3); + free(s); +} + +struct ext +{ + kripto_mac_desc desc; + const kripto_block_desc *block; +}; + +#define EXT(X) ((const struct ext *)(X)) + +static kripto_mac *xcbc_create +( + const kripto_mac_desc *desc, + unsigned int r, + const void *key, + unsigned int key_len, + unsigned int tag_len +) +{ + kripto_mac *s; + + (void)tag_len; + + s = malloc(sizeof(kripto_mac) + desc->maxtag * 3); + if(!s) return 0; + + s->obj.desc = desc; + s->len = desc->maxtag; + s->buf = (uint8_t *)s + sizeof(kripto_mac); + s->k2 = s->buf + s->len; + s->k3 = s->k2 + s->len; + s->block = kripto_block_create(EXT(desc)->block, r, key, key_len); + if(!s->block) + { + free(s); + return 0; + } + + if(xcbc_init(s, r)) + { + free(s); + return 0; + } + + return s; +} + +static kripto_mac *xcbc_recreate +( + kripto_mac *s, + unsigned int r, + const void *key, + unsigned int key_len, + unsigned int tag_len +) +{ + (void)tag_len; + + s->block = kripto_block_recreate(s->block, r, key, key_len); + if(!s->block) goto err; + + if(xcbc_init(s, r)) goto err; + + return s; + +err: + kripto_memwipe(s, sizeof(kripto_mac) + s->obj.desc->maxtag * 3); + free(s); + return 0; +} + +kripto_mac_desc *kripto_mac_xcbc(const kripto_block_desc *block) +{ + struct ext *s; + + s = malloc(sizeof(struct ext)); + if(!s) return 0; + + s->block = block; + + s->desc.create = &xcbc_create; + s->desc.recreate = &xcbc_recreate; + s->desc.input = &xcbc_input; + s->desc.tag = &xcbc_tag; + s->desc.destroy = &xcbc_destroy; + s->desc.maxtag = kripto_block_size(block); + s->desc.maxkey = kripto_block_maxkey(block); + + return (kripto_mac_desc *)s; +} diff --git a/test/mac/xcbc.c b/test/mac/xcbc.c new file mode 100644 index 0000000..0fd6551 --- /dev/null +++ b/test/mac/xcbc.c @@ -0,0 +1,65 @@ +/* + * Written in 2013 by Gregor Pintar + * + * To the extent possible under law, the author(s) have dedicated + * all copyright and related and neighboring rights to this software + * to the public domain worldwide. + * + * This software is distributed without any warranty. + * + * You should have received a copy of the CC0 Public Domain Dedication. + * If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include + +static const uint8_t key[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const uint8_t msg[34] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21 +}; + +static const uint8_t tag[16] = +{ + 0xBE, 0xCB, 0xB3, 0xBC, 0xCD, 0xB5, 0x18, 0xA3, + 0x06, 0x77, 0xD5, 0x48, 0x1F, 0xB6, 0xB4, 0xD8 +}; + +int main(void) +{ + kripto_mac_desc *desc; + uint8_t t[16]; + + desc = kripto_mac_xcbc(kripto_block_rijndael128); + if(!desc) return -1; + + kripto_mac_all( + desc, 0, + key, 16, + msg, 34, + t, 16 + ); + + if(memcmp(tag, t, 16)) puts("xcbc rijndael128: FAIL"); + else puts("xcbc rijndael128: OK"); + + free(desc); + + return 0; +} -- 2.11.4.GIT