releases-comm-central/third_party/libgcrypt/cipher/mac-cmac.c

227 строки
5.2 KiB
C

/* mac-cmac.c - CMAC 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_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