Coverage Report

Created: 2024-11-21 07:03

/src/libgcrypt/cipher/mac.c
Line
Count
Source (jump to first uncovered line)
1
/* mac.c  -  message authentication code dispatcher
2
 * Copyright (C) 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
3
 *
4
 * This file is part of Libgcrypt.
5
 *
6
 * Libgcrypt is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser General Public License as
8
 * published by the Free Software Foundation; either version 2.1 of
9
 * the License, or (at your option) any later version.
10
 *
11
 * Libgcrypt is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
#include <config.h>
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <errno.h>
25
26
#include "g10lib.h"
27
#include "mac-internal.h"
28
29
30
/* This is the list of the digest implementations included in
31
   libgcrypt.  */
32
static const gcry_mac_spec_t * const mac_list[] = {
33
#if USE_SHA1
34
  &_gcry_mac_type_spec_hmac_sha1,
35
#endif
36
#if USE_SHA256
37
  &_gcry_mac_type_spec_hmac_sha256,
38
  &_gcry_mac_type_spec_hmac_sha224,
39
#endif
40
#if USE_SHA512
41
  &_gcry_mac_type_spec_hmac_sha512,
42
  &_gcry_mac_type_spec_hmac_sha384,
43
  &_gcry_mac_type_spec_hmac_sha512_256,
44
  &_gcry_mac_type_spec_hmac_sha512_224,
45
#endif
46
#if USE_SHA3
47
  &_gcry_mac_type_spec_hmac_sha3_224,
48
  &_gcry_mac_type_spec_hmac_sha3_256,
49
  &_gcry_mac_type_spec_hmac_sha3_384,
50
  &_gcry_mac_type_spec_hmac_sha3_512,
51
#endif
52
#if USE_GOST_R_3411_94
53
  &_gcry_mac_type_spec_hmac_gost3411_94,
54
  &_gcry_mac_type_spec_hmac_gost3411_cp,
55
#endif
56
#if USE_GOST_R_3411_12
57
  &_gcry_mac_type_spec_hmac_stribog256,
58
  &_gcry_mac_type_spec_hmac_stribog512,
59
#endif
60
#if USE_WHIRLPOOL
61
  &_gcry_mac_type_spec_hmac_whirlpool,
62
#endif
63
#if USE_RMD160
64
  &_gcry_mac_type_spec_hmac_rmd160,
65
#endif
66
#if USE_TIGER
67
  &_gcry_mac_type_spec_hmac_tiger1,
68
#endif
69
#if USE_MD5
70
  &_gcry_mac_type_spec_hmac_md5,
71
#endif
72
#if USE_MD4
73
  &_gcry_mac_type_spec_hmac_md4,
74
#endif
75
#if USE_BLAKE2
76
  &_gcry_mac_type_spec_hmac_blake2b_512,
77
  &_gcry_mac_type_spec_hmac_blake2b_384,
78
  &_gcry_mac_type_spec_hmac_blake2b_256,
79
  &_gcry_mac_type_spec_hmac_blake2b_160,
80
  &_gcry_mac_type_spec_hmac_blake2s_256,
81
  &_gcry_mac_type_spec_hmac_blake2s_224,
82
  &_gcry_mac_type_spec_hmac_blake2s_160,
83
  &_gcry_mac_type_spec_hmac_blake2s_128,
84
#endif
85
#if USE_SM3
86
  &_gcry_mac_type_spec_hmac_sm3,
87
#endif
88
#if USE_BLOWFISH
89
  &_gcry_mac_type_spec_cmac_blowfish,
90
#endif
91
#if USE_DES
92
  &_gcry_mac_type_spec_cmac_tripledes,
93
#endif
94
#if USE_CAST5
95
  &_gcry_mac_type_spec_cmac_cast5,
96
#endif
97
#if USE_AES
98
  &_gcry_mac_type_spec_cmac_aes,
99
  &_gcry_mac_type_spec_gmac_aes,
100
  &_gcry_mac_type_spec_poly1305mac_aes,
101
#endif
102
#if USE_TWOFISH
103
  &_gcry_mac_type_spec_cmac_twofish,
104
  &_gcry_mac_type_spec_gmac_twofish,
105
  &_gcry_mac_type_spec_poly1305mac_twofish,
106
#endif
107
#if USE_SERPENT
108
  &_gcry_mac_type_spec_cmac_serpent,
109
  &_gcry_mac_type_spec_gmac_serpent,
110
  &_gcry_mac_type_spec_poly1305mac_serpent,
111
#endif
112
#if USE_RFC2268
113
  &_gcry_mac_type_spec_cmac_rfc2268,
114
#endif
115
#if USE_SEED
116
  &_gcry_mac_type_spec_cmac_seed,
117
  &_gcry_mac_type_spec_gmac_seed,
118
  &_gcry_mac_type_spec_poly1305mac_seed,
119
#endif
120
#if USE_CAMELLIA
121
  &_gcry_mac_type_spec_cmac_camellia,
122
  &_gcry_mac_type_spec_gmac_camellia,
123
  &_gcry_mac_type_spec_poly1305mac_camellia,
124
#endif
125
#if USE_IDEA
126
  &_gcry_mac_type_spec_cmac_idea,
127
#endif
128
#if USE_GOST28147
129
  &_gcry_mac_type_spec_cmac_gost28147,
130
  &_gcry_mac_type_spec_gost28147_imit,
131
#endif
132
  &_gcry_mac_type_spec_poly1305mac,
133
#if USE_SM4
134
  &_gcry_mac_type_spec_cmac_sm4,
135
  &_gcry_mac_type_spec_gmac_sm4,
136
  &_gcry_mac_type_spec_poly1305mac_sm4,
137
#endif
138
#if USE_ARIA
139
  &_gcry_mac_type_spec_cmac_aria,
140
  &_gcry_mac_type_spec_gmac_aria,
141
  &_gcry_mac_type_spec_poly1305mac_aria,
142
#endif
143
  NULL
144
};
145
146
/* HMAC implementations start with index 101 (enum gcry_mac_algos) */
147
static const gcry_mac_spec_t * const mac_list_algo101[] =
148
  {
149
#if USE_SHA256
150
    &_gcry_mac_type_spec_hmac_sha256,
151
    &_gcry_mac_type_spec_hmac_sha224,
152
#else
153
    NULL,
154
    NULL,
155
#endif
156
#if USE_SHA512
157
    &_gcry_mac_type_spec_hmac_sha512,
158
    &_gcry_mac_type_spec_hmac_sha384,
159
#else
160
    NULL,
161
    NULL,
162
#endif
163
#if USE_SHA1
164
    &_gcry_mac_type_spec_hmac_sha1,
165
#else
166
    NULL,
167
#endif
168
#if USE_MD5
169
    &_gcry_mac_type_spec_hmac_md5,
170
#else
171
    NULL,
172
#endif
173
#if USE_MD4
174
    &_gcry_mac_type_spec_hmac_md4,
175
#else
176
    NULL,
177
#endif
178
#if USE_RMD160
179
    &_gcry_mac_type_spec_hmac_rmd160,
180
#else
181
    NULL,
182
#endif
183
#if USE_TIGER
184
    &_gcry_mac_type_spec_hmac_tiger1,
185
#else
186
    NULL,
187
#endif
188
#if USE_WHIRLPOOL
189
    &_gcry_mac_type_spec_hmac_whirlpool,
190
#else
191
    NULL,
192
#endif
193
#if USE_GOST_R_3411_94
194
    &_gcry_mac_type_spec_hmac_gost3411_94,
195
#else
196
    NULL,
197
#endif
198
#if USE_GOST_R_3411_12
199
    &_gcry_mac_type_spec_hmac_stribog256,
200
    &_gcry_mac_type_spec_hmac_stribog512,
201
#else
202
    NULL,
203
    NULL,
204
#endif
205
#if USE_MD2
206
    &_gcry_mac_type_spec_hmac_md2,
207
#else
208
    NULL,
209
#endif
210
#if USE_SHA3
211
    &_gcry_mac_type_spec_hmac_sha3_224,
212
    &_gcry_mac_type_spec_hmac_sha3_256,
213
    &_gcry_mac_type_spec_hmac_sha3_384,
214
    &_gcry_mac_type_spec_hmac_sha3_512,
215
#else
216
    NULL,
217
    NULL,
218
    NULL,
219
    NULL,
220
#endif
221
#if USE_GOST_R_3411_94
222
    &_gcry_mac_type_spec_hmac_gost3411_cp,
223
#else
224
    NULL,
225
#endif
226
#if USE_BLAKE2
227
    &_gcry_mac_type_spec_hmac_blake2b_512,
228
    &_gcry_mac_type_spec_hmac_blake2b_384,
229
    &_gcry_mac_type_spec_hmac_blake2b_256,
230
    &_gcry_mac_type_spec_hmac_blake2b_160,
231
    &_gcry_mac_type_spec_hmac_blake2s_256,
232
    &_gcry_mac_type_spec_hmac_blake2s_224,
233
    &_gcry_mac_type_spec_hmac_blake2s_160,
234
    &_gcry_mac_type_spec_hmac_blake2s_128,
235
#else
236
    NULL,
237
    NULL,
238
    NULL,
239
    NULL,
240
    NULL,
241
    NULL,
242
    NULL,
243
    NULL,
244
#endif
245
#if USE_SM3
246
    &_gcry_mac_type_spec_hmac_sm3,
247
#else
248
    NULL,
249
#endif
250
#if USE_SHA512
251
    &_gcry_mac_type_spec_hmac_sha512_256,
252
    &_gcry_mac_type_spec_hmac_sha512_224
253
#else
254
    NULL,
255
    NULL
256
#endif
257
  };
258
259
/* CMAC implementations start with index 201 (enum gcry_mac_algos) */
260
static const gcry_mac_spec_t * const mac_list_algo201[] =
261
  {
262
#if USE_AES
263
    &_gcry_mac_type_spec_cmac_aes,
264
#else
265
    NULL,
266
#endif
267
#if USE_DES
268
    &_gcry_mac_type_spec_cmac_tripledes,
269
#else
270
    NULL,
271
#endif
272
#if USE_CAMELLIA
273
    &_gcry_mac_type_spec_cmac_camellia,
274
#else
275
    NULL,
276
#endif
277
#if USE_CAST5
278
    &_gcry_mac_type_spec_cmac_cast5,
279
#else
280
    NULL,
281
#endif
282
#if USE_BLOWFISH
283
    &_gcry_mac_type_spec_cmac_blowfish,
284
#else
285
    NULL,
286
#endif
287
#if USE_TWOFISH
288
    &_gcry_mac_type_spec_cmac_twofish,
289
#else
290
    NULL,
291
#endif
292
#if USE_SERPENT
293
    &_gcry_mac_type_spec_cmac_serpent,
294
#else
295
    NULL,
296
#endif
297
#if USE_SEED
298
    &_gcry_mac_type_spec_cmac_seed,
299
#else
300
    NULL,
301
#endif
302
#if USE_RFC2268
303
    &_gcry_mac_type_spec_cmac_rfc2268,
304
#else
305
    NULL,
306
#endif
307
#if USE_IDEA
308
    &_gcry_mac_type_spec_cmac_idea,
309
#else
310
    NULL,
311
#endif
312
#if USE_GOST28147
313
    &_gcry_mac_type_spec_cmac_gost28147,
314
#else
315
    NULL,
316
#endif
317
#if USE_SM4
318
    &_gcry_mac_type_spec_cmac_sm4,
319
#else
320
    NULL,
321
#endif
322
#if USE_ARIA
323
    &_gcry_mac_type_spec_cmac_aria
324
#else
325
    NULL
326
#endif
327
  };
328
329
/* GMAC implementations start with index 401 (enum gcry_mac_algos) */
330
static const gcry_mac_spec_t * const mac_list_algo401[] =
331
  {
332
#if USE_AES
333
    &_gcry_mac_type_spec_gmac_aes,
334
#else
335
    NULL,
336
#endif
337
#if USE_CAMELLIA
338
    &_gcry_mac_type_spec_gmac_camellia,
339
#else
340
    NULL,
341
#endif
342
#if USE_TWOFISH
343
    &_gcry_mac_type_spec_gmac_twofish,
344
#else
345
    NULL,
346
#endif
347
#if USE_SERPENT
348
    &_gcry_mac_type_spec_gmac_serpent,
349
#else
350
    NULL,
351
#endif
352
#if USE_SEED
353
    &_gcry_mac_type_spec_gmac_seed,
354
#else
355
    NULL,
356
#endif
357
#if USE_SM4
358
    &_gcry_mac_type_spec_gmac_sm4,
359
#else
360
    NULL,
361
#endif
362
#if USE_ARIA
363
    &_gcry_mac_type_spec_gmac_aria
364
#else
365
    NULL
366
#endif
367
  };
368
369
/* Poly1305-MAC implementations start with index 501 (enum gcry_mac_algos) */
370
static const gcry_mac_spec_t * const mac_list_algo501[] =
371
  {
372
    &_gcry_mac_type_spec_poly1305mac,
373
#if USE_AES
374
    &_gcry_mac_type_spec_poly1305mac_aes,
375
#else
376
    NULL,
377
#endif
378
#if USE_CAMELLIA
379
    &_gcry_mac_type_spec_poly1305mac_camellia,
380
#else
381
    NULL,
382
#endif
383
#if USE_TWOFISH
384
    &_gcry_mac_type_spec_poly1305mac_twofish,
385
#else
386
    NULL,
387
#endif
388
#if USE_SERPENT
389
    &_gcry_mac_type_spec_poly1305mac_serpent,
390
#else
391
    NULL,
392
#endif
393
#if USE_SEED
394
    &_gcry_mac_type_spec_poly1305mac_seed,
395
#else
396
    NULL,
397
#endif
398
#if USE_SM4
399
    &_gcry_mac_type_spec_poly1305mac_sm4,
400
#else
401
    NULL,
402
#endif
403
#if USE_ARIA
404
    &_gcry_mac_type_spec_poly1305mac_aria
405
#else
406
    NULL
407
#endif
408
  };
409
410
411
412
413
/* Explicitly initialize this module.  */
414
gcry_err_code_t
415
_gcry_mac_init (void)
416
10
{
417
10
  return 0;
418
10
}
419
420

421
/* Return the spec structure for the MAC algorithm ALGO.  For an
422
   unknown algorithm NULL is returned.  */
423
static const gcry_mac_spec_t *
424
spec_from_algo (int algo)
425
4.49k
{
426
4.49k
  const gcry_mac_spec_t *spec = NULL;
427
428
4.49k
  if (algo >= 101 && algo < 101 + DIM(mac_list_algo101))
429
3.93k
    spec = mac_list_algo101[algo - 101];
430
555
  else if (algo >= 201 && algo < 201 + DIM(mac_list_algo201))
431
555
    spec = mac_list_algo201[algo - 201];
432
0
  else if (algo >= 401 && algo < 401 + DIM(mac_list_algo401))
433
0
    spec = mac_list_algo401[algo - 401];
434
0
  else if (algo >= 501 && algo < 501 + DIM(mac_list_algo501))
435
0
    spec = mac_list_algo501[algo - 501];
436
0
#if USE_GOST28147
437
0
  else if (algo == GCRY_MAC_GOST28147_IMIT)
438
0
    spec = &_gcry_mac_type_spec_gost28147_imit;
439
4.49k
#endif
440
441
4.49k
  if (spec)
442
4.49k
    gcry_assert (spec->algo == algo);
443
444
0
  return spec;
445
4.49k
}
446
447
448
/* Lookup a mac's spec by its name.  */
449
static const gcry_mac_spec_t *
450
spec_from_name (const char *name)
451
0
{
452
0
  const gcry_mac_spec_t *spec;
453
0
  int idx;
454
455
0
  for (idx = 0; (spec = mac_list[idx]); idx++)
456
0
    if (!stricmp (name, spec->name))
457
0
      return spec;
458
459
0
  return NULL;
460
0
}
461
462
463
/****************
464
 * Map a string to the mac algo
465
 */
466
int
467
_gcry_mac_map_name (const char *string)
468
0
{
469
0
  const gcry_mac_spec_t *spec;
470
471
0
  if (!string)
472
0
    return 0;
473
474
  /* Not found, search a matching mac name.  */
475
0
  spec = spec_from_name (string);
476
0
  if (spec)
477
0
    return spec->algo;
478
479
0
  return 0;
480
0
}
481
482
483
/****************
484
 * This function simply returns the name of the algorithm or some constant
485
 * string when there is no algo.  It will never return NULL.
486
 * Use the macro gcry_mac_test_algo() to check whether the algorithm
487
 * is valid.
488
 */
489
const char *
490
_gcry_mac_algo_name (int algorithm)
491
0
{
492
0
  const gcry_mac_spec_t *spec;
493
494
0
  spec = spec_from_algo (algorithm);
495
0
  return spec ? spec->name : "?";
496
0
}
497
498
499
static gcry_err_code_t
500
check_mac_algo (int algorithm)
501
0
{
502
0
  const gcry_mac_spec_t *spec;
503
504
0
  spec = spec_from_algo (algorithm);
505
0
  if (spec && !spec->flags.disabled && (spec->flags.fips || !fips_mode ()))
506
0
    return 0;
507
508
0
  return GPG_ERR_MAC_ALGO;
509
0
}
510
511
512
/****************
513
 * Open a message digest handle for use with algorithm ALGO.
514
 */
515
static gcry_err_code_t
516
mac_open (gcry_mac_hd_t * hd, int algo, int secure, gcry_ctx_t ctx)
517
2.26k
{
518
2.26k
  const gcry_mac_spec_t *spec;
519
2.26k
  gcry_err_code_t err;
520
2.26k
  gcry_mac_hd_t h;
521
522
2.26k
  spec = spec_from_algo (algo);
523
2.26k
  if (!spec)
524
0
    return GPG_ERR_MAC_ALGO;
525
2.26k
  else if (spec->flags.disabled)
526
0
    return GPG_ERR_MAC_ALGO;
527
2.26k
  else if (!spec->flags.fips && fips_mode ())
528
0
    return GPG_ERR_MAC_ALGO;
529
2.26k
  else if (!spec->ops)
530
0
    return GPG_ERR_MAC_ALGO;
531
2.26k
  else if (!spec->ops->open || !spec->ops->write || !spec->ops->setkey ||
532
2.26k
           !spec->ops->read || !spec->ops->verify || !spec->ops->reset)
533
0
    return GPG_ERR_MAC_ALGO;
534
535
2.26k
  if (secure)
536
552
    h = xtrycalloc_secure (1, sizeof (*h));
537
1.71k
  else
538
1.71k
    h = xtrycalloc (1, sizeof (*h));
539
540
2.26k
  if (!h)
541
0
    return gpg_err_code_from_syserror ();
542
543
2.26k
  h->magic = secure ? CTX_MAC_MAGIC_SECURE : CTX_MAC_MAGIC_NORMAL;
544
2.26k
  h->spec = spec;
545
2.26k
  h->algo = algo;
546
2.26k
  h->gcry_ctx = ctx;
547
548
2.26k
  err = h->spec->ops->open (h);
549
2.26k
  if (err)
550
0
    xfree (h);
551
2.26k
  else
552
2.26k
    *hd = h;
553
554
2.26k
  return err;
555
2.26k
}
556
557
558
static gcry_err_code_t
559
mac_reset (gcry_mac_hd_t hd)
560
57.7k
{
561
57.7k
  if (hd->spec->ops->reset)
562
57.7k
    return hd->spec->ops->reset (hd);
563
564
0
  return 0;
565
57.7k
}
566
567
568
static void
569
mac_close (gcry_mac_hd_t hd)
570
2.26k
{
571
2.26k
  if (hd->spec->ops->close)
572
2.26k
    hd->spec->ops->close (hd);
573
574
2.26k
  wipememory (hd, sizeof (*hd));
575
576
2.26k
  xfree (hd);
577
2.26k
}
578
579
580
static gcry_err_code_t
581
mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
582
2.75k
{
583
2.75k
  if (!hd->spec->ops->setkey)
584
0
    return GPG_ERR_INV_ARG;
585
2.75k
  if (keylen > 0 && !key)
586
0
    return GPG_ERR_INV_ARG;
587
588
2.75k
  return hd->spec->ops->setkey (hd, key, keylen);
589
2.75k
}
590
591
592
static gcry_err_code_t
593
mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
594
0
{
595
0
  if (!hd->spec->ops->setiv)
596
0
    return GPG_ERR_INV_ARG;
597
0
  if (ivlen > 0 && !iv)
598
0
    return GPG_ERR_INV_ARG;
599
600
0
  return hd->spec->ops->setiv (hd, iv, ivlen);
601
0
}
602
603
604
static gcry_err_code_t
605
mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
606
400k
{
607
400k
  if (!hd->spec->ops->write)
608
0
    return GPG_ERR_INV_ARG;
609
400k
  if (inlen > 0 && !inbuf)
610
0
    return GPG_ERR_INV_ARG;
611
612
400k
  return hd->spec->ops->write (hd, inbuf, inlen);
613
400k
}
614
615
616
static gcry_err_code_t
617
mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
618
59.7k
{
619
59.7k
  if (!outbuf || !outlen || *outlen == 0 || !hd->spec->ops->read)
620
0
    return GPG_ERR_INV_ARG;
621
622
59.7k
  return hd->spec->ops->read (hd, outbuf, outlen);
623
59.7k
}
624
625
626
static gcry_err_code_t
627
mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
628
0
{
629
0
  if (!buf || buflen == 0 || !hd->spec->ops->verify)
630
0
    return GPG_ERR_INV_ARG;
631
632
0
  return hd->spec->ops->verify (hd, buf, buflen);
633
0
}
634
635
636
/* Create a MAC object for algorithm ALGO.  FLAGS may be
637
   given as an bitwise OR of the gcry_mac_flags values.
638
   H is guaranteed to be a valid handle or NULL on error.  */
639
gpg_err_code_t
640
_gcry_mac_open (gcry_mac_hd_t * h, int algo, unsigned int flags,
641
                gcry_ctx_t ctx)
642
2.26k
{
643
2.26k
  gcry_err_code_t rc;
644
2.26k
  gcry_mac_hd_t hd = NULL;
645
646
2.26k
  if ((flags & ~GCRY_MAC_FLAG_SECURE))
647
0
    rc = GPG_ERR_INV_ARG;
648
2.26k
  else
649
2.26k
    rc = mac_open (&hd, algo, !!(flags & GCRY_MAC_FLAG_SECURE), ctx);
650
651
2.26k
  *h = rc ? NULL : hd;
652
2.26k
  return rc;
653
2.26k
}
654
655
656
void
657
_gcry_mac_close (gcry_mac_hd_t hd)
658
2.26k
{
659
2.26k
  if (hd)
660
2.26k
    mac_close (hd);
661
2.26k
}
662
663
664
gcry_err_code_t
665
_gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
666
2.75k
{
667
2.75k
  return mac_setkey (hd, key, keylen);
668
2.75k
}
669
670
671
gcry_err_code_t
672
_gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
673
0
{
674
0
  return mac_setiv (hd, iv, ivlen);
675
0
}
676
677
678
gcry_err_code_t
679
_gcry_mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
680
400k
{
681
400k
  return mac_write (hd, inbuf, inlen);
682
400k
}
683
684
685
gcry_err_code_t
686
_gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
687
59.7k
{
688
59.7k
  return mac_read (hd, outbuf, outlen);
689
59.7k
}
690
691
692
gcry_err_code_t
693
_gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
694
0
{
695
0
  return mac_verify (hd, buf, buflen);
696
0
}
697
698
699
int
700
_gcry_mac_get_algo (gcry_mac_hd_t hd)
701
0
{
702
0
  return hd->algo;
703
0
}
704
705
706
unsigned int
707
_gcry_mac_get_algo_maclen (int algo)
708
2.22k
{
709
2.22k
  const gcry_mac_spec_t *spec;
710
711
2.22k
  spec = spec_from_algo (algo);
712
2.22k
  if (!spec || !spec->ops || !spec->ops->get_maclen)
713
0
    return 0;
714
715
2.22k
  return spec->ops->get_maclen (algo);
716
2.22k
}
717
718
719
unsigned int
720
_gcry_mac_get_algo_keylen (int algo)
721
0
{
722
0
  const gcry_mac_spec_t *spec;
723
724
0
  spec = spec_from_algo (algo);
725
0
  if (!spec || !spec->ops || !spec->ops->get_keylen)
726
0
    return 0;
727
728
0
  return spec->ops->get_keylen (algo);
729
0
}
730
731
732
gcry_err_code_t
733
_gcry_mac_ctl (gcry_mac_hd_t hd, int cmd, void *buffer, size_t buflen)
734
57.7k
{
735
57.7k
  gcry_err_code_t rc;
736
737
  /* Currently not used.  */
738
57.7k
  (void) hd;
739
57.7k
  (void) buffer;
740
57.7k
  (void) buflen;
741
742
57.7k
  switch (cmd)
743
57.7k
    {
744
57.7k
    case GCRYCTL_RESET:
745
57.7k
      rc = mac_reset (hd);
746
57.7k
      break;
747
0
    case GCRYCTL_SET_SBOX:
748
0
      if (hd->spec->ops->set_extra_info)
749
0
        rc = hd->spec->ops->set_extra_info
750
0
          (hd, GCRYCTL_SET_SBOX, buffer, buflen);
751
0
      else
752
0
        rc = GPG_ERR_NOT_SUPPORTED;
753
0
      break;
754
0
    default:
755
0
      rc = GPG_ERR_INV_OP;
756
57.7k
    }
757
57.7k
  return rc;
758
57.7k
}
759
760
761
/* Return information about the given MAC algorithm ALGO.
762
763
    GCRYCTL_TEST_ALGO:
764
        Returns 0 if the specified algorithm ALGO is available for use.
765
        BUFFER and NBYTES must be zero.
766
767
   Note: Because this function is in most cases used to return an
768
   integer value, we can make it easier for the caller to just look at
769
   the return value.  The caller will in all cases consult the value
770
   and thereby detecting whether a error occurred or not (i.e. while
771
   checking the block size)
772
 */
773
gcry_err_code_t
774
_gcry_mac_algo_info (int algo, int what, void *buffer, size_t * nbytes)
775
0
{
776
0
  gcry_err_code_t rc = 0;
777
0
  unsigned int ui;
778
779
0
  switch (what)
780
0
    {
781
0
    case GCRYCTL_GET_KEYLEN:
782
0
      if (buffer || (!nbytes))
783
0
        rc = GPG_ERR_INV_ARG;
784
0
      else
785
0
        {
786
0
          ui = _gcry_mac_get_algo_keylen (algo);
787
0
          if (ui > 0)
788
0
            *nbytes = (size_t) ui;
789
0
          else
790
            /* The only reason for an error is an invalid algo.  */
791
0
            rc = GPG_ERR_MAC_ALGO;
792
0
        }
793
0
      break;
794
0
    case GCRYCTL_TEST_ALGO:
795
0
      if (buffer || nbytes)
796
0
        rc = GPG_ERR_INV_ARG;
797
0
      else
798
0
        rc = check_mac_algo (algo);
799
0
      break;
800
801
0
    default:
802
0
      rc = GPG_ERR_INV_OP;
803
0
    }
804
805
0
  return rc;
806
0
}
807
808
809
/* Run the self-tests for the MAC.  */
810
gpg_error_t
811
_gcry_mac_selftest (int algo, int extended, selftest_report_func_t report)
812
0
{
813
0
  gcry_err_code_t ec;
814
0
  const gcry_mac_spec_t *spec;
815
816
0
  spec = spec_from_algo (algo);
817
0
  if (spec && !spec->flags.disabled
818
0
      && (spec->flags.fips || !fips_mode ())
819
0
      && spec->ops && spec->ops->selftest)
820
0
    ec = spec->ops->selftest (algo, extended, report);
821
0
  else
822
0
    {
823
0
      ec = GPG_ERR_MAC_ALGO;
824
0
      if (report)
825
0
        report ("mac", algo, "module",
826
0
                spec && !spec->flags.disabled
827
0
                && (spec->flags.fips || !fips_mode ())?
828
0
                "no selftest available" :
829
0
                spec? "algorithm disabled" :
830
0
                "algorithm not found");
831
0
    }
832
833
0
  return gpg_error (ec);
834
0
}