diff options
Diffstat (limited to 'libotr/libgcrypt-1.8.7/cipher/mac-gmac.c')
-rw-r--r-- | libotr/libgcrypt-1.8.7/cipher/mac-gmac.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/libotr/libgcrypt-1.8.7/cipher/mac-gmac.c b/libotr/libgcrypt-1.8.7/cipher/mac-gmac.c new file mode 100644 index 0000000..9bc86d9 --- /dev/null +++ b/libotr/libgcrypt-1.8.7/cipher/mac-gmac.c @@ -0,0 +1,185 @@ +/* mac-gmac.c - GMAC glue for MAC API + * Copyright (C) 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_GMAC_AES: + return GCRY_CIPHER_AES; + case GCRY_MAC_GMAC_CAMELLIA: + return GCRY_CIPHER_CAMELLIA128; + case GCRY_MAC_GMAC_TWOFISH: + return GCRY_CIPHER_TWOFISH; + case GCRY_MAC_GMAC_SERPENT: + return GCRY_CIPHER_SERPENT128; + case GCRY_MAC_GMAC_SEED: + return GCRY_CIPHER_SEED; + } +} + + +static gcry_err_code_t +gmac_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_GCM, + flags); + if (err) + return err; + + h->u.gmac.cipher_algo = cipher_algo; + h->u.gmac.ctx = hd; + return 0; +} + + +static void +gmac_close (gcry_mac_hd_t h) +{ + _gcry_cipher_close (h->u.gmac.ctx); + h->u.gmac.ctx = NULL; +} + + +static gcry_err_code_t +gmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen) +{ + return _gcry_cipher_setkey (h->u.gmac.ctx, key, keylen); +} + + +static gcry_err_code_t +gmac_setiv (gcry_mac_hd_t h, const unsigned char *iv, size_t ivlen) +{ + return _gcry_cipher_setiv (h->u.gmac.ctx, iv, ivlen); +} + + +static gcry_err_code_t +gmac_reset (gcry_mac_hd_t h) +{ + return _gcry_cipher_reset (h->u.gmac.ctx); +} + + +static gcry_err_code_t +gmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen) +{ + return _gcry_cipher_authenticate (h->u.gmac.ctx, buf, buflen); +} + + +static gcry_err_code_t +gmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen) +{ + if (*outlen > GCRY_GCM_BLOCK_LEN) + *outlen = GCRY_GCM_BLOCK_LEN; + return _gcry_cipher_gettag (h->u.gmac.ctx, outbuf, *outlen); +} + + +static gcry_err_code_t +gmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen) +{ + return _gcry_cipher_checktag (h->u.gmac.ctx, buf, buflen); +} + + +static unsigned int +gmac_get_maclen (int algo) +{ + (void)algo; + return GCRY_GCM_BLOCK_LEN; +} + + +static unsigned int +gmac_get_keylen (int algo) +{ + return _gcry_cipher_get_algo_keylen (map_mac_algo_to_cipher (algo)); +} + + +static gcry_mac_spec_ops_t gmac_ops = { + gmac_open, + gmac_close, + gmac_setkey, + gmac_setiv, + gmac_reset, + gmac_write, + gmac_read, + gmac_verify, + gmac_get_maclen, + gmac_get_keylen +}; + + +#if USE_AES +gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = { + GCRY_MAC_GMAC_AES, {0, 1}, "GMAC_AES", + &gmac_ops +}; +#endif +#if USE_TWOFISH +gcry_mac_spec_t _gcry_mac_type_spec_gmac_twofish = { + GCRY_MAC_GMAC_TWOFISH, {0, 0}, "GMAC_TWOFISH", + &gmac_ops +}; +#endif +#if USE_SERPENT +gcry_mac_spec_t _gcry_mac_type_spec_gmac_serpent = { + GCRY_MAC_GMAC_SERPENT, {0, 0}, "GMAC_SERPENT", + &gmac_ops +}; +#endif +#if USE_SEED +gcry_mac_spec_t _gcry_mac_type_spec_gmac_seed = { + GCRY_MAC_GMAC_SEED, {0, 0}, "GMAC_SEED", + &gmac_ops +}; +#endif +#if USE_CAMELLIA +gcry_mac_spec_t _gcry_mac_type_spec_gmac_camellia = { + GCRY_MAC_GMAC_CAMELLIA, {0, 0}, "GMAC_CAMELLIA", + &gmac_ops +}; +#endif |