diff options
Diffstat (limited to 'plugins/MirOTR/Libgcrypt/cipher/mac-cmac.c')
-rw-r--r-- | plugins/MirOTR/Libgcrypt/cipher/mac-cmac.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/plugins/MirOTR/Libgcrypt/cipher/mac-cmac.c b/plugins/MirOTR/Libgcrypt/cipher/mac-cmac.c new file mode 100644 index 0000000000..69a2f174db --- /dev/null +++ b/plugins/MirOTR/Libgcrypt/cipher/mac-cmac.c @@ -0,0 +1,226 @@ +/* mac-cmac.c - CMAC glue for MAC API + * Copyright © 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi> + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser general Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> + +#include "g10lib.h" +#include "cipher.h" +#include "./mac-internal.h" + + +static int +map_mac_algo_to_cipher (int mac_algo) +{ + switch (mac_algo) + { + default: + return GCRY_CIPHER_NONE; + case GCRY_MAC_CMAC_AES: + return GCRY_CIPHER_AES; + case GCRY_MAC_CMAC_3DES: + return GCRY_CIPHER_3DES; + case GCRY_MAC_CMAC_CAMELLIA: + return GCRY_CIPHER_CAMELLIA128; + case GCRY_MAC_CMAC_IDEA: + return GCRY_CIPHER_IDEA; + case GCRY_MAC_CMAC_CAST5: + return GCRY_CIPHER_CAST5; + case GCRY_MAC_CMAC_BLOWFISH: + return GCRY_CIPHER_BLOWFISH; + case GCRY_MAC_CMAC_TWOFISH: + return GCRY_CIPHER_TWOFISH; + case GCRY_MAC_CMAC_SERPENT: + return GCRY_CIPHER_SERPENT128; + case GCRY_MAC_CMAC_SEED: + return GCRY_CIPHER_SEED; + case GCRY_MAC_CMAC_RFC2268: + return GCRY_CIPHER_RFC2268_128; + case GCRY_MAC_CMAC_GOST28147: + return GCRY_CIPHER_GOST28147; + } +} + + +static gcry_err_code_t +cmac_open (gcry_mac_hd_t h) +{ + gcry_err_code_t err; + gcry_cipher_hd_t hd; + int secure = (h->magic == CTX_MAGIC_SECURE); + int cipher_algo; + unsigned int flags; + + cipher_algo = map_mac_algo_to_cipher (h->spec->algo); + flags = (secure ? GCRY_CIPHER_SECURE : 0); + + err = _gcry_cipher_open_internal (&hd, cipher_algo, GCRY_CIPHER_MODE_CMAC, + flags); + if (err) + return err; + + h->u.cmac.cipher_algo = cipher_algo; + h->u.cmac.ctx = hd; + h->u.cmac.blklen = _gcry_cipher_get_algo_blklen (cipher_algo); + return 0; +} + + +static void +cmac_close (gcry_mac_hd_t h) +{ + _gcry_cipher_close (h->u.cmac.ctx); + h->u.cmac.ctx = NULL; +} + + +static gcry_err_code_t +cmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen) +{ + return _gcry_cipher_setkey (h->u.cmac.ctx, key, keylen); +} + + +static gcry_err_code_t +cmac_reset (gcry_mac_hd_t h) +{ + return _gcry_cipher_reset (h->u.cmac.ctx); +} + + +static gcry_err_code_t +cmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen) +{ + return _gcry_cipher_cmac_authenticate (h->u.cmac.ctx, buf, buflen); +} + + +static gcry_err_code_t +cmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen) +{ + if (*outlen > h->u.cmac.blklen) + *outlen = h->u.cmac.blklen; + return _gcry_cipher_cmac_get_tag (h->u.cmac.ctx, outbuf, *outlen); +} + + +static gcry_err_code_t +cmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen) +{ + return _gcry_cipher_cmac_check_tag (h->u.cmac.ctx, buf, buflen); +} + + +static unsigned int +cmac_get_maclen (int algo) +{ + return _gcry_cipher_get_algo_blklen (map_mac_algo_to_cipher (algo)); +} + + +static unsigned int +cmac_get_keylen (int algo) +{ + return _gcry_cipher_get_algo_keylen (map_mac_algo_to_cipher (algo)); +} + + +static gcry_mac_spec_ops_t cmac_ops = { + cmac_open, + cmac_close, + cmac_setkey, + NULL, + cmac_reset, + cmac_write, + cmac_read, + cmac_verify, + cmac_get_maclen, + cmac_get_keylen +}; + + +#if USE_BLOWFISH +gcry_mac_spec_t _gcry_mac_type_spec_cmac_blowfish = { + GCRY_MAC_CMAC_BLOWFISH, {0, 0}, "CMAC_BLOWFISH", + &cmac_ops +}; +#endif +#if USE_DES +gcry_mac_spec_t _gcry_mac_type_spec_cmac_tripledes = { + GCRY_MAC_CMAC_3DES, {0, 1}, "CMAC_3DES", + &cmac_ops +}; +#endif +#if USE_CAST5 +gcry_mac_spec_t _gcry_mac_type_spec_cmac_cast5 = { + GCRY_MAC_CMAC_CAST5, {0, 0}, "CMAC_CAST5", + &cmac_ops +}; +#endif +#if USE_AES +gcry_mac_spec_t _gcry_mac_type_spec_cmac_aes = { + GCRY_MAC_CMAC_AES, {0, 1}, "CMAC_AES", + &cmac_ops +}; +#endif +#if USE_TWOFISH +gcry_mac_spec_t _gcry_mac_type_spec_cmac_twofish = { + GCRY_MAC_CMAC_TWOFISH, {0, 0}, "CMAC_TWOFISH", + &cmac_ops +}; +#endif +#if USE_SERPENT +gcry_mac_spec_t _gcry_mac_type_spec_cmac_serpent = { + GCRY_MAC_CMAC_SERPENT, {0, 0}, "CMAC_SERPENT", + &cmac_ops +}; +#endif +#if USE_RFC2268 +gcry_mac_spec_t _gcry_mac_type_spec_cmac_rfc2268 = { + GCRY_MAC_CMAC_RFC2268, {0, 0}, "CMAC_RFC2268", + &cmac_ops +}; +#endif +#if USE_SEED +gcry_mac_spec_t _gcry_mac_type_spec_cmac_seed = { + GCRY_MAC_CMAC_SEED, {0, 0}, "CMAC_SEED", + &cmac_ops +}; +#endif +#if USE_CAMELLIA +gcry_mac_spec_t _gcry_mac_type_spec_cmac_camellia = { + GCRY_MAC_CMAC_CAMELLIA, {0, 0}, "CMAC_CAMELLIA", + &cmac_ops +}; +#endif +#ifdef USE_IDEA +gcry_mac_spec_t _gcry_mac_type_spec_cmac_idea = { + GCRY_MAC_CMAC_IDEA, {0, 0}, "CMAC_IDEA", + &cmac_ops +}; +#endif +#if USE_GOST28147 +gcry_mac_spec_t _gcry_mac_type_spec_cmac_gost28147 = { + GCRY_MAC_CMAC_GOST28147, {0, 0}, "CMAC_GOST28147", + &cmac_ops +}; +#endif |