123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835 |
- /* mac.c - message authentication code dispatcher
- * 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 "mac-internal.h"
- /* This is the list of the digest implementations included in
- libgcrypt. */
- static const gcry_mac_spec_t * const mac_list[] = {
- #if USE_SHA1
- &_gcry_mac_type_spec_hmac_sha1,
- #endif
- #if USE_SHA256
- &_gcry_mac_type_spec_hmac_sha256,
- &_gcry_mac_type_spec_hmac_sha224,
- #endif
- #if USE_SHA512
- &_gcry_mac_type_spec_hmac_sha512,
- &_gcry_mac_type_spec_hmac_sha384,
- &_gcry_mac_type_spec_hmac_sha512_256,
- &_gcry_mac_type_spec_hmac_sha512_224,
- #endif
- #if USE_SHA3
- &_gcry_mac_type_spec_hmac_sha3_224,
- &_gcry_mac_type_spec_hmac_sha3_256,
- &_gcry_mac_type_spec_hmac_sha3_384,
- &_gcry_mac_type_spec_hmac_sha3_512,
- #endif
- #if USE_GOST_R_3411_94
- &_gcry_mac_type_spec_hmac_gost3411_94,
- &_gcry_mac_type_spec_hmac_gost3411_cp,
- #endif
- #if USE_GOST_R_3411_12
- &_gcry_mac_type_spec_hmac_stribog256,
- &_gcry_mac_type_spec_hmac_stribog512,
- #endif
- #if USE_WHIRLPOOL
- &_gcry_mac_type_spec_hmac_whirlpool,
- #endif
- #if USE_RMD160
- &_gcry_mac_type_spec_hmac_rmd160,
- #endif
- #if USE_TIGER
- &_gcry_mac_type_spec_hmac_tiger1,
- #endif
- #if USE_MD5
- &_gcry_mac_type_spec_hmac_md5,
- #endif
- #if USE_MD4
- &_gcry_mac_type_spec_hmac_md4,
- #endif
- #if USE_BLAKE2
- &_gcry_mac_type_spec_hmac_blake2b_512,
- &_gcry_mac_type_spec_hmac_blake2b_384,
- &_gcry_mac_type_spec_hmac_blake2b_256,
- &_gcry_mac_type_spec_hmac_blake2b_160,
- &_gcry_mac_type_spec_hmac_blake2s_256,
- &_gcry_mac_type_spec_hmac_blake2s_224,
- &_gcry_mac_type_spec_hmac_blake2s_160,
- &_gcry_mac_type_spec_hmac_blake2s_128,
- #endif
- #if USE_SM3
- &_gcry_mac_type_spec_hmac_sm3,
- #endif
- #if USE_BLOWFISH
- &_gcry_mac_type_spec_cmac_blowfish,
- #endif
- #if USE_DES
- &_gcry_mac_type_spec_cmac_tripledes,
- #endif
- #if USE_CAST5
- &_gcry_mac_type_spec_cmac_cast5,
- #endif
- #if USE_AES
- &_gcry_mac_type_spec_cmac_aes,
- &_gcry_mac_type_spec_gmac_aes,
- &_gcry_mac_type_spec_poly1305mac_aes,
- #endif
- #if USE_TWOFISH
- &_gcry_mac_type_spec_cmac_twofish,
- &_gcry_mac_type_spec_gmac_twofish,
- &_gcry_mac_type_spec_poly1305mac_twofish,
- #endif
- #if USE_SERPENT
- &_gcry_mac_type_spec_cmac_serpent,
- &_gcry_mac_type_spec_gmac_serpent,
- &_gcry_mac_type_spec_poly1305mac_serpent,
- #endif
- #if USE_RFC2268
- &_gcry_mac_type_spec_cmac_rfc2268,
- #endif
- #if USE_SEED
- &_gcry_mac_type_spec_cmac_seed,
- &_gcry_mac_type_spec_gmac_seed,
- &_gcry_mac_type_spec_poly1305mac_seed,
- #endif
- #if USE_CAMELLIA
- &_gcry_mac_type_spec_cmac_camellia,
- &_gcry_mac_type_spec_gmac_camellia,
- &_gcry_mac_type_spec_poly1305mac_camellia,
- #endif
- #if USE_IDEA
- &_gcry_mac_type_spec_cmac_idea,
- #endif
- #if USE_GOST28147
- &_gcry_mac_type_spec_cmac_gost28147,
- &_gcry_mac_type_spec_gost28147_imit,
- #endif
- &_gcry_mac_type_spec_poly1305mac,
- #if USE_SM4
- &_gcry_mac_type_spec_cmac_sm4,
- &_gcry_mac_type_spec_gmac_sm4,
- &_gcry_mac_type_spec_poly1305mac_sm4,
- #endif
- #if USE_ARIA
- &_gcry_mac_type_spec_cmac_aria,
- &_gcry_mac_type_spec_gmac_aria,
- &_gcry_mac_type_spec_poly1305mac_aria,
- #endif
- NULL
- };
- /* HMAC implementations start with index 101 (enum gcry_mac_algos) */
- static const gcry_mac_spec_t * const mac_list_algo101[] =
- {
- #if USE_SHA256
- &_gcry_mac_type_spec_hmac_sha256,
- &_gcry_mac_type_spec_hmac_sha224,
- #else
- NULL,
- NULL,
- #endif
- #if USE_SHA512
- &_gcry_mac_type_spec_hmac_sha512,
- &_gcry_mac_type_spec_hmac_sha384,
- #else
- NULL,
- NULL,
- #endif
- #if USE_SHA1
- &_gcry_mac_type_spec_hmac_sha1,
- #else
- NULL,
- #endif
- #if USE_MD5
- &_gcry_mac_type_spec_hmac_md5,
- #else
- NULL,
- #endif
- #if USE_MD4
- &_gcry_mac_type_spec_hmac_md4,
- #else
- NULL,
- #endif
- #if USE_RMD160
- &_gcry_mac_type_spec_hmac_rmd160,
- #else
- NULL,
- #endif
- #if USE_TIGER
- &_gcry_mac_type_spec_hmac_tiger1,
- #else
- NULL,
- #endif
- #if USE_WHIRLPOOL
- &_gcry_mac_type_spec_hmac_whirlpool,
- #else
- NULL,
- #endif
- #if USE_GOST_R_3411_94
- &_gcry_mac_type_spec_hmac_gost3411_94,
- #else
- NULL,
- #endif
- #if USE_GOST_R_3411_12
- &_gcry_mac_type_spec_hmac_stribog256,
- &_gcry_mac_type_spec_hmac_stribog512,
- #else
- NULL,
- NULL,
- #endif
- #if USE_MD2
- &_gcry_mac_type_spec_hmac_md2,
- #else
- NULL,
- #endif
- #if USE_SHA3
- &_gcry_mac_type_spec_hmac_sha3_224,
- &_gcry_mac_type_spec_hmac_sha3_256,
- &_gcry_mac_type_spec_hmac_sha3_384,
- &_gcry_mac_type_spec_hmac_sha3_512,
- #else
- NULL,
- NULL,
- NULL,
- NULL,
- #endif
- #if USE_GOST_R_3411_94
- &_gcry_mac_type_spec_hmac_gost3411_cp,
- #else
- NULL,
- #endif
- #if USE_BLAKE2
- &_gcry_mac_type_spec_hmac_blake2b_512,
- &_gcry_mac_type_spec_hmac_blake2b_384,
- &_gcry_mac_type_spec_hmac_blake2b_256,
- &_gcry_mac_type_spec_hmac_blake2b_160,
- &_gcry_mac_type_spec_hmac_blake2s_256,
- &_gcry_mac_type_spec_hmac_blake2s_224,
- &_gcry_mac_type_spec_hmac_blake2s_160,
- &_gcry_mac_type_spec_hmac_blake2s_128,
- #else
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- #endif
- #if USE_SM3
- &_gcry_mac_type_spec_hmac_sm3,
- #else
- NULL,
- #endif
- #if USE_SHA512
- &_gcry_mac_type_spec_hmac_sha512_256,
- &_gcry_mac_type_spec_hmac_sha512_224
- #else
- NULL,
- NULL
- #endif
- };
- /* CMAC implementations start with index 201 (enum gcry_mac_algos) */
- static const gcry_mac_spec_t * const mac_list_algo201[] =
- {
- #if USE_AES
- &_gcry_mac_type_spec_cmac_aes,
- #else
- NULL,
- #endif
- #if USE_DES
- &_gcry_mac_type_spec_cmac_tripledes,
- #else
- NULL,
- #endif
- #if USE_CAMELLIA
- &_gcry_mac_type_spec_cmac_camellia,
- #else
- NULL,
- #endif
- #if USE_CAST5
- &_gcry_mac_type_spec_cmac_cast5,
- #else
- NULL,
- #endif
- #if USE_BLOWFISH
- &_gcry_mac_type_spec_cmac_blowfish,
- #else
- NULL,
- #endif
- #if USE_TWOFISH
- &_gcry_mac_type_spec_cmac_twofish,
- #else
- NULL,
- #endif
- #if USE_SERPENT
- &_gcry_mac_type_spec_cmac_serpent,
- #else
- NULL,
- #endif
- #if USE_SEED
- &_gcry_mac_type_spec_cmac_seed,
- #else
- NULL,
- #endif
- #if USE_RFC2268
- &_gcry_mac_type_spec_cmac_rfc2268,
- #else
- NULL,
- #endif
- #if USE_IDEA
- &_gcry_mac_type_spec_cmac_idea,
- #else
- NULL,
- #endif
- #if USE_GOST28147
- &_gcry_mac_type_spec_cmac_gost28147,
- #else
- NULL,
- #endif
- #if USE_SM4
- &_gcry_mac_type_spec_cmac_sm4,
- #else
- NULL,
- #endif
- #if USE_ARIA
- &_gcry_mac_type_spec_cmac_aria
- #else
- NULL
- #endif
- };
- /* GMAC implementations start with index 401 (enum gcry_mac_algos) */
- static const gcry_mac_spec_t * const mac_list_algo401[] =
- {
- #if USE_AES
- &_gcry_mac_type_spec_gmac_aes,
- #else
- NULL,
- #endif
- #if USE_CAMELLIA
- &_gcry_mac_type_spec_gmac_camellia,
- #else
- NULL,
- #endif
- #if USE_TWOFISH
- &_gcry_mac_type_spec_gmac_twofish,
- #else
- NULL,
- #endif
- #if USE_SERPENT
- &_gcry_mac_type_spec_gmac_serpent,
- #else
- NULL,
- #endif
- #if USE_SEED
- &_gcry_mac_type_spec_gmac_seed,
- #else
- NULL,
- #endif
- #if USE_SM4
- &_gcry_mac_type_spec_gmac_sm4,
- #else
- NULL,
- #endif
- #if USE_ARIA
- &_gcry_mac_type_spec_gmac_aria
- #else
- NULL
- #endif
- };
- /* Poly1305-MAC implementations start with index 501 (enum gcry_mac_algos) */
- static const gcry_mac_spec_t * const mac_list_algo501[] =
- {
- &_gcry_mac_type_spec_poly1305mac,
- #if USE_AES
- &_gcry_mac_type_spec_poly1305mac_aes,
- #else
- NULL,
- #endif
- #if USE_CAMELLIA
- &_gcry_mac_type_spec_poly1305mac_camellia,
- #else
- NULL,
- #endif
- #if USE_TWOFISH
- &_gcry_mac_type_spec_poly1305mac_twofish,
- #else
- NULL,
- #endif
- #if USE_SERPENT
- &_gcry_mac_type_spec_poly1305mac_serpent,
- #else
- NULL,
- #endif
- #if USE_SEED
- &_gcry_mac_type_spec_poly1305mac_seed,
- #else
- NULL,
- #endif
- #if USE_SM4
- &_gcry_mac_type_spec_poly1305mac_sm4,
- #else
- NULL,
- #endif
- #if USE_ARIA
- &_gcry_mac_type_spec_poly1305mac_aria
- #else
- NULL
- #endif
- };
- /* Explicitly initialize this module. */
- gcry_err_code_t
- _gcry_mac_init (void)
- {
- return 0;
- }
- /* Return the spec structure for the MAC algorithm ALGO. For an
- unknown algorithm NULL is returned. */
- static const gcry_mac_spec_t *
- spec_from_algo (int algo)
- {
- const gcry_mac_spec_t *spec = NULL;
- if (algo >= 101 && algo < 101 + DIM(mac_list_algo101))
- spec = mac_list_algo101[algo - 101];
- else if (algo >= 201 && algo < 201 + DIM(mac_list_algo201))
- spec = mac_list_algo201[algo - 201];
- else if (algo >= 401 && algo < 401 + DIM(mac_list_algo401))
- spec = mac_list_algo401[algo - 401];
- else if (algo >= 501 && algo < 501 + DIM(mac_list_algo501))
- spec = mac_list_algo501[algo - 501];
- #if USE_GOST28147
- else if (algo == GCRY_MAC_GOST28147_IMIT)
- spec = &_gcry_mac_type_spec_gost28147_imit;
- #endif
- if (spec)
- gcry_assert (spec->algo == algo);
- return spec;
- }
- /* Lookup a mac's spec by its name. */
- static const gcry_mac_spec_t *
- spec_from_name (const char *name)
- {
- const gcry_mac_spec_t *spec;
- int idx;
- for (idx = 0; (spec = mac_list[idx]); idx++)
- if (!stricmp (name, spec->name))
- return spec;
- return NULL;
- }
- /****************
- * Map a string to the mac algo
- */
- int
- _gcry_mac_map_name (const char *string)
- {
- const gcry_mac_spec_t *spec;
- if (!string)
- return 0;
- /* Not found, search a matching mac name. */
- spec = spec_from_name (string);
- if (spec)
- return spec->algo;
- return 0;
- }
- /****************
- * This function simply returns the name of the algorithm or some constant
- * string when there is no algo. It will never return NULL.
- * Use the macro gcry_mac_test_algo() to check whether the algorithm
- * is valid.
- */
- const char *
- _gcry_mac_algo_name (int algorithm)
- {
- const gcry_mac_spec_t *spec;
- spec = spec_from_algo (algorithm);
- return spec ? spec->name : "?";
- }
- static gcry_err_code_t
- check_mac_algo (int algorithm)
- {
- const gcry_mac_spec_t *spec;
- spec = spec_from_algo (algorithm);
- if (spec && !spec->flags.disabled && (spec->flags.fips || !fips_mode ()))
- return 0;
- return GPG_ERR_MAC_ALGO;
- }
- /****************
- * Open a message digest handle for use with algorithm ALGO.
- */
- static gcry_err_code_t
- mac_open (gcry_mac_hd_t * hd, int algo, int secure, gcry_ctx_t ctx)
- {
- const gcry_mac_spec_t *spec;
- gcry_err_code_t err;
- gcry_mac_hd_t h;
- spec = spec_from_algo (algo);
- if (!spec)
- return GPG_ERR_MAC_ALGO;
- else if (spec->flags.disabled)
- return GPG_ERR_MAC_ALGO;
- else if (!spec->flags.fips && fips_mode ())
- return GPG_ERR_MAC_ALGO;
- else if (!spec->ops)
- return GPG_ERR_MAC_ALGO;
- else if (!spec->ops->open || !spec->ops->write || !spec->ops->setkey ||
- !spec->ops->read || !spec->ops->verify || !spec->ops->reset)
- return GPG_ERR_MAC_ALGO;
- if (secure)
- h = xtrycalloc_secure (1, sizeof (*h));
- else
- h = xtrycalloc (1, sizeof (*h));
- if (!h)
- return gpg_err_code_from_syserror ();
- h->magic = secure ? CTX_MAC_MAGIC_SECURE : CTX_MAC_MAGIC_NORMAL;
- h->spec = spec;
- h->algo = algo;
- h->gcry_ctx = ctx;
- err = h->spec->ops->open (h);
- if (err)
- xfree (h);
- else
- *hd = h;
- return err;
- }
- static gcry_err_code_t
- mac_reset (gcry_mac_hd_t hd)
- {
- if (hd->spec->ops->reset)
- return hd->spec->ops->reset (hd);
- return 0;
- }
- static void
- mac_close (gcry_mac_hd_t hd)
- {
- if (hd->spec->ops->close)
- hd->spec->ops->close (hd);
- wipememory (hd, sizeof (*hd));
- xfree (hd);
- }
- static gcry_err_code_t
- mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
- {
- if (!hd->spec->ops->setkey)
- return GPG_ERR_INV_ARG;
- if (keylen > 0 && !key)
- return GPG_ERR_INV_ARG;
- return hd->spec->ops->setkey (hd, key, keylen);
- }
- static gcry_err_code_t
- mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
- {
- if (!hd->spec->ops->setiv)
- return GPG_ERR_INV_ARG;
- if (ivlen > 0 && !iv)
- return GPG_ERR_INV_ARG;
- return hd->spec->ops->setiv (hd, iv, ivlen);
- }
- static gcry_err_code_t
- mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
- {
- if (!hd->spec->ops->write)
- return GPG_ERR_INV_ARG;
- if (inlen > 0 && !inbuf)
- return GPG_ERR_INV_ARG;
- return hd->spec->ops->write (hd, inbuf, inlen);
- }
- static gcry_err_code_t
- mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
- {
- if (!outbuf || !outlen || *outlen == 0 || !hd->spec->ops->read)
- return GPG_ERR_INV_ARG;
- return hd->spec->ops->read (hd, outbuf, outlen);
- }
- static gcry_err_code_t
- mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
- {
- if (!buf || buflen == 0 || !hd->spec->ops->verify)
- return GPG_ERR_INV_ARG;
- return hd->spec->ops->verify (hd, buf, buflen);
- }
- /* Create a MAC object for algorithm ALGO. FLAGS may be
- given as an bitwise OR of the gcry_mac_flags values.
- H is guaranteed to be a valid handle or NULL on error. */
- gpg_err_code_t
- _gcry_mac_open (gcry_mac_hd_t * h, int algo, unsigned int flags,
- gcry_ctx_t ctx)
- {
- gcry_err_code_t rc;
- gcry_mac_hd_t hd = NULL;
- if ((flags & ~GCRY_MAC_FLAG_SECURE))
- rc = GPG_ERR_INV_ARG;
- else
- rc = mac_open (&hd, algo, !!(flags & GCRY_MAC_FLAG_SECURE), ctx);
- *h = rc ? NULL : hd;
- return rc;
- }
- void
- _gcry_mac_close (gcry_mac_hd_t hd)
- {
- if (hd)
- mac_close (hd);
- }
- gcry_err_code_t
- _gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
- {
- return mac_setkey (hd, key, keylen);
- }
- gcry_err_code_t
- _gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
- {
- return mac_setiv (hd, iv, ivlen);
- }
- gcry_err_code_t
- _gcry_mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
- {
- return mac_write (hd, inbuf, inlen);
- }
- gcry_err_code_t
- _gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
- {
- return mac_read (hd, outbuf, outlen);
- }
- gcry_err_code_t
- _gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
- {
- return mac_verify (hd, buf, buflen);
- }
- int
- _gcry_mac_get_algo (gcry_mac_hd_t hd)
- {
- return hd->algo;
- }
- unsigned int
- _gcry_mac_get_algo_maclen (int algo)
- {
- const gcry_mac_spec_t *spec;
- spec = spec_from_algo (algo);
- if (!spec || !spec->ops || !spec->ops->get_maclen)
- return 0;
- return spec->ops->get_maclen (algo);
- }
- unsigned int
- _gcry_mac_get_algo_keylen (int algo)
- {
- const gcry_mac_spec_t *spec;
- spec = spec_from_algo (algo);
- if (!spec || !spec->ops || !spec->ops->get_keylen)
- return 0;
- return spec->ops->get_keylen (algo);
- }
- gcry_err_code_t
- _gcry_mac_ctl (gcry_mac_hd_t hd, int cmd, void *buffer, size_t buflen)
- {
- gcry_err_code_t rc;
- /* Currently not used. */
- (void) hd;
- (void) buffer;
- (void) buflen;
- switch (cmd)
- {
- case GCRYCTL_RESET:
- rc = mac_reset (hd);
- break;
- case GCRYCTL_SET_SBOX:
- if (hd->spec->ops->set_extra_info)
- rc = hd->spec->ops->set_extra_info
- (hd, GCRYCTL_SET_SBOX, buffer, buflen);
- else
- rc = GPG_ERR_NOT_SUPPORTED;
- break;
- default:
- rc = GPG_ERR_INV_OP;
- }
- return rc;
- }
- /* Return information about the given MAC algorithm ALGO.
- GCRYCTL_TEST_ALGO:
- Returns 0 if the specified algorithm ALGO is available for use.
- BUFFER and NBYTES must be zero.
- Note: Because this function is in most cases used to return an
- integer value, we can make it easier for the caller to just look at
- the return value. The caller will in all cases consult the value
- and thereby detecting whether a error occurred or not (i.e. while
- checking the block size)
- */
- gcry_err_code_t
- _gcry_mac_algo_info (int algo, int what, void *buffer, size_t * nbytes)
- {
- gcry_err_code_t rc = 0;
- unsigned int ui;
- switch (what)
- {
- case GCRYCTL_GET_KEYLEN:
- if (buffer || (!nbytes))
- rc = GPG_ERR_INV_ARG;
- else
- {
- ui = _gcry_mac_get_algo_keylen (algo);
- if (ui > 0)
- *nbytes = (size_t) ui;
- else
- /* The only reason for an error is an invalid algo. */
- rc = GPG_ERR_MAC_ALGO;
- }
- break;
- case GCRYCTL_TEST_ALGO:
- if (buffer || nbytes)
- rc = GPG_ERR_INV_ARG;
- else
- rc = check_mac_algo (algo);
- break;
- default:
- rc = GPG_ERR_INV_OP;
- }
- return rc;
- }
- /* Run the self-tests for the MAC. */
- gpg_error_t
- _gcry_mac_selftest (int algo, int extended, selftest_report_func_t report)
- {
- gcry_err_code_t ec;
- const gcry_mac_spec_t *spec;
- spec = spec_from_algo (algo);
- if (spec && !spec->flags.disabled
- && (spec->flags.fips || !fips_mode ())
- && spec->ops && spec->ops->selftest)
- ec = spec->ops->selftest (algo, extended, report);
- else
- {
- ec = GPG_ERR_MAC_ALGO;
- if (report)
- report ("mac", algo, "module",
- spec && !spec->flags.disabled
- && (spec->flags.fips || !fips_mode ())?
- "no selftest available" :
- spec? "algorithm disabled" :
- "algorithm not found");
- }
- return gpg_error (ec);
- }
|