/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 | | #endif |
136 | | NULL, |
137 | | }; |
138 | | |
139 | | /* HMAC implementations start with index 101 (enum gcry_mac_algos) */ |
140 | | static const gcry_mac_spec_t * const mac_list_algo101[] = |
141 | | { |
142 | | #if USE_SHA256 |
143 | | &_gcry_mac_type_spec_hmac_sha256, |
144 | | &_gcry_mac_type_spec_hmac_sha224, |
145 | | #else |
146 | | NULL, |
147 | | NULL, |
148 | | #endif |
149 | | #if USE_SHA512 |
150 | | &_gcry_mac_type_spec_hmac_sha512, |
151 | | &_gcry_mac_type_spec_hmac_sha384, |
152 | | #else |
153 | | NULL, |
154 | | NULL, |
155 | | #endif |
156 | | #if USE_SHA1 |
157 | | &_gcry_mac_type_spec_hmac_sha1, |
158 | | #else |
159 | | NULL, |
160 | | #endif |
161 | | #if USE_MD5 |
162 | | &_gcry_mac_type_spec_hmac_md5, |
163 | | #else |
164 | | NULL, |
165 | | #endif |
166 | | #if USE_MD4 |
167 | | &_gcry_mac_type_spec_hmac_md4, |
168 | | #else |
169 | | NULL, |
170 | | #endif |
171 | | #if USE_RMD160 |
172 | | &_gcry_mac_type_spec_hmac_rmd160, |
173 | | #else |
174 | | NULL, |
175 | | #endif |
176 | | #if USE_TIGER |
177 | | &_gcry_mac_type_spec_hmac_tiger1, |
178 | | #else |
179 | | NULL, |
180 | | #endif |
181 | | #if USE_WHIRLPOOL |
182 | | &_gcry_mac_type_spec_hmac_whirlpool, |
183 | | #else |
184 | | NULL, |
185 | | #endif |
186 | | #if USE_GOST_R_3411_94 |
187 | | &_gcry_mac_type_spec_hmac_gost3411_94, |
188 | | #else |
189 | | NULL, |
190 | | #endif |
191 | | #if USE_GOST_R_3411_12 |
192 | | &_gcry_mac_type_spec_hmac_stribog256, |
193 | | &_gcry_mac_type_spec_hmac_stribog512, |
194 | | #else |
195 | | NULL, |
196 | | NULL, |
197 | | #endif |
198 | | #if USE_MD2 |
199 | | &_gcry_mac_type_spec_hmac_md2, |
200 | | #else |
201 | | NULL, |
202 | | #endif |
203 | | #if USE_SHA3 |
204 | | &_gcry_mac_type_spec_hmac_sha3_224, |
205 | | &_gcry_mac_type_spec_hmac_sha3_256, |
206 | | &_gcry_mac_type_spec_hmac_sha3_384, |
207 | | &_gcry_mac_type_spec_hmac_sha3_512, |
208 | | #else |
209 | | NULL, |
210 | | NULL, |
211 | | NULL, |
212 | | NULL, |
213 | | #endif |
214 | | #if USE_GOST_R_3411_94 |
215 | | &_gcry_mac_type_spec_hmac_gost3411_cp, |
216 | | #else |
217 | | NULL, |
218 | | #endif |
219 | | #if USE_BLAKE2 |
220 | | &_gcry_mac_type_spec_hmac_blake2b_512, |
221 | | &_gcry_mac_type_spec_hmac_blake2b_384, |
222 | | &_gcry_mac_type_spec_hmac_blake2b_256, |
223 | | &_gcry_mac_type_spec_hmac_blake2b_160, |
224 | | &_gcry_mac_type_spec_hmac_blake2s_256, |
225 | | &_gcry_mac_type_spec_hmac_blake2s_224, |
226 | | &_gcry_mac_type_spec_hmac_blake2s_160, |
227 | | &_gcry_mac_type_spec_hmac_blake2s_128, |
228 | | #else |
229 | | NULL, |
230 | | NULL, |
231 | | NULL, |
232 | | NULL, |
233 | | NULL, |
234 | | NULL, |
235 | | NULL, |
236 | | NULL, |
237 | | #endif |
238 | | #if USE_SM3 |
239 | | &_gcry_mac_type_spec_hmac_sm3, |
240 | | #else |
241 | | NULL, |
242 | | #endif |
243 | | #if USE_SHA512 |
244 | | &_gcry_mac_type_spec_hmac_sha512_256, |
245 | | &_gcry_mac_type_spec_hmac_sha512_224, |
246 | | #else |
247 | | NULL, |
248 | | NULL, |
249 | | #endif |
250 | | }; |
251 | | |
252 | | /* CMAC implementations start with index 201 (enum gcry_mac_algos) */ |
253 | | static const gcry_mac_spec_t * const mac_list_algo201[] = |
254 | | { |
255 | | #if USE_AES |
256 | | &_gcry_mac_type_spec_cmac_aes, |
257 | | #else |
258 | | NULL, |
259 | | #endif |
260 | | #if USE_DES |
261 | | &_gcry_mac_type_spec_cmac_tripledes, |
262 | | #else |
263 | | NULL, |
264 | | #endif |
265 | | #if USE_CAMELLIA |
266 | | &_gcry_mac_type_spec_cmac_camellia, |
267 | | #else |
268 | | NULL, |
269 | | #endif |
270 | | #if USE_CAST5 |
271 | | &_gcry_mac_type_spec_cmac_cast5, |
272 | | #else |
273 | | NULL, |
274 | | #endif |
275 | | #if USE_BLOWFISH |
276 | | &_gcry_mac_type_spec_cmac_blowfish, |
277 | | #else |
278 | | NULL, |
279 | | #endif |
280 | | #if USE_TWOFISH |
281 | | &_gcry_mac_type_spec_cmac_twofish, |
282 | | #else |
283 | | NULL, |
284 | | #endif |
285 | | #if USE_SERPENT |
286 | | &_gcry_mac_type_spec_cmac_serpent, |
287 | | #else |
288 | | NULL, |
289 | | #endif |
290 | | #if USE_SEED |
291 | | &_gcry_mac_type_spec_cmac_seed, |
292 | | #else |
293 | | NULL, |
294 | | #endif |
295 | | #if USE_RFC2268 |
296 | | &_gcry_mac_type_spec_cmac_rfc2268, |
297 | | #else |
298 | | NULL, |
299 | | #endif |
300 | | #if USE_IDEA |
301 | | &_gcry_mac_type_spec_cmac_idea, |
302 | | #else |
303 | | NULL, |
304 | | #endif |
305 | | #if USE_GOST28147 |
306 | | &_gcry_mac_type_spec_cmac_gost28147, |
307 | | #else |
308 | | NULL, |
309 | | #endif |
310 | | #if USE_SM4 |
311 | | &_gcry_mac_type_spec_cmac_sm4 |
312 | | #else |
313 | | NULL |
314 | | #endif |
315 | | }; |
316 | | |
317 | | /* GMAC implementations start with index 401 (enum gcry_mac_algos) */ |
318 | | static const gcry_mac_spec_t * const mac_list_algo401[] = |
319 | | { |
320 | | #if USE_AES |
321 | | &_gcry_mac_type_spec_gmac_aes, |
322 | | #else |
323 | | NULL, |
324 | | #endif |
325 | | #if USE_CAMELLIA |
326 | | &_gcry_mac_type_spec_gmac_camellia, |
327 | | #else |
328 | | NULL, |
329 | | #endif |
330 | | #if USE_TWOFISH |
331 | | &_gcry_mac_type_spec_gmac_twofish, |
332 | | #else |
333 | | NULL, |
334 | | #endif |
335 | | #if USE_SERPENT |
336 | | &_gcry_mac_type_spec_gmac_serpent, |
337 | | #else |
338 | | NULL, |
339 | | #endif |
340 | | #if USE_SEED |
341 | | &_gcry_mac_type_spec_gmac_seed |
342 | | #else |
343 | | NULL |
344 | | #endif |
345 | | }; |
346 | | |
347 | | /* Poly1305-MAC implementations start with index 501 (enum gcry_mac_algos) */ |
348 | | static const gcry_mac_spec_t * const mac_list_algo501[] = |
349 | | { |
350 | | &_gcry_mac_type_spec_poly1305mac, |
351 | | #if USE_AES |
352 | | &_gcry_mac_type_spec_poly1305mac_aes, |
353 | | #else |
354 | | NULL, |
355 | | #endif |
356 | | #if USE_CAMELLIA |
357 | | &_gcry_mac_type_spec_poly1305mac_camellia, |
358 | | #else |
359 | | NULL, |
360 | | #endif |
361 | | #if USE_TWOFISH |
362 | | &_gcry_mac_type_spec_poly1305mac_twofish, |
363 | | #else |
364 | | NULL, |
365 | | #endif |
366 | | #if USE_SERPENT |
367 | | &_gcry_mac_type_spec_poly1305mac_serpent, |
368 | | #else |
369 | | NULL, |
370 | | #endif |
371 | | #if USE_SEED |
372 | | &_gcry_mac_type_spec_poly1305mac_seed |
373 | | #else |
374 | | NULL |
375 | | #endif |
376 | | }; |
377 | | |
378 | | |
379 | | |
380 | | |
381 | | /* Explicitly initialize this module. */ |
382 | | gcry_err_code_t |
383 | | _gcry_mac_init (void) |
384 | 1 | { |
385 | 1 | return 0; |
386 | 1 | } |
387 | | |
388 | | |
389 | | /* Return the spec structure for the MAC algorithm ALGO. For an |
390 | | unknown algorithm NULL is returned. */ |
391 | | static const gcry_mac_spec_t * |
392 | | spec_from_algo (int algo) |
393 | 0 | { |
394 | 0 | const gcry_mac_spec_t *spec = NULL; |
395 | |
|
396 | 0 | if (algo >= 101 && algo < 101 + DIM(mac_list_algo101)) |
397 | 0 | spec = mac_list_algo101[algo - 101]; |
398 | 0 | else if (algo >= 201 && algo < 201 + DIM(mac_list_algo201)) |
399 | 0 | spec = mac_list_algo201[algo - 201]; |
400 | 0 | else if (algo >= 401 && algo < 401 + DIM(mac_list_algo401)) |
401 | 0 | spec = mac_list_algo401[algo - 401]; |
402 | 0 | else if (algo >= 501 && algo < 501 + DIM(mac_list_algo501)) |
403 | 0 | spec = mac_list_algo501[algo - 501]; |
404 | 0 | #if USE_GOST28147 |
405 | 0 | else if (algo == GCRY_MAC_GOST28147_IMIT) |
406 | 0 | spec = &_gcry_mac_type_spec_gost28147_imit; |
407 | 0 | #endif |
408 | |
|
409 | 0 | if (spec) |
410 | 0 | gcry_assert (spec->algo == algo); |
411 | | |
412 | 0 | return spec; |
413 | 0 | } |
414 | | |
415 | | |
416 | | /* Lookup a mac's spec by its name. */ |
417 | | static const gcry_mac_spec_t * |
418 | | spec_from_name (const char *name) |
419 | 0 | { |
420 | 0 | const gcry_mac_spec_t *spec; |
421 | 0 | int idx; |
422 | |
|
423 | 0 | for (idx = 0; (spec = mac_list[idx]); idx++) |
424 | 0 | if (!stricmp (name, spec->name)) |
425 | 0 | return spec; |
426 | | |
427 | 0 | return NULL; |
428 | 0 | } |
429 | | |
430 | | |
431 | | /**************** |
432 | | * Map a string to the mac algo |
433 | | */ |
434 | | int |
435 | | _gcry_mac_map_name (const char *string) |
436 | 0 | { |
437 | 0 | const gcry_mac_spec_t *spec; |
438 | |
|
439 | 0 | if (!string) |
440 | 0 | return 0; |
441 | | |
442 | | /* Not found, search a matching mac name. */ |
443 | 0 | spec = spec_from_name (string); |
444 | 0 | if (spec) |
445 | 0 | return spec->algo; |
446 | | |
447 | 0 | return 0; |
448 | 0 | } |
449 | | |
450 | | |
451 | | /**************** |
452 | | * This function simply returns the name of the algorithm or some constant |
453 | | * string when there is no algo. It will never return NULL. |
454 | | * Use the macro gcry_mac_test_algo() to check whether the algorithm |
455 | | * is valid. |
456 | | */ |
457 | | const char * |
458 | | _gcry_mac_algo_name (int algorithm) |
459 | 0 | { |
460 | 0 | const gcry_mac_spec_t *spec; |
461 | |
|
462 | 0 | spec = spec_from_algo (algorithm); |
463 | 0 | return spec ? spec->name : "?"; |
464 | 0 | } |
465 | | |
466 | | |
467 | | static gcry_err_code_t |
468 | | check_mac_algo (int algorithm) |
469 | 0 | { |
470 | 0 | const gcry_mac_spec_t *spec; |
471 | |
|
472 | 0 | spec = spec_from_algo (algorithm); |
473 | 0 | if (spec && !spec->flags.disabled && (spec->flags.fips || !fips_mode ())) |
474 | 0 | return 0; |
475 | | |
476 | 0 | return GPG_ERR_MAC_ALGO; |
477 | 0 | } |
478 | | |
479 | | |
480 | | /**************** |
481 | | * Open a message digest handle for use with algorithm ALGO. |
482 | | */ |
483 | | static gcry_err_code_t |
484 | | mac_open (gcry_mac_hd_t * hd, int algo, int secure, gcry_ctx_t ctx) |
485 | 0 | { |
486 | 0 | const gcry_mac_spec_t *spec; |
487 | 0 | gcry_err_code_t err; |
488 | 0 | gcry_mac_hd_t h; |
489 | |
|
490 | 0 | spec = spec_from_algo (algo); |
491 | 0 | if (!spec) |
492 | 0 | return GPG_ERR_MAC_ALGO; |
493 | 0 | else if (spec->flags.disabled) |
494 | 0 | return GPG_ERR_MAC_ALGO; |
495 | 0 | else if (!spec->flags.fips && fips_mode ()) |
496 | 0 | return GPG_ERR_MAC_ALGO; |
497 | 0 | else if (!spec->ops) |
498 | 0 | return GPG_ERR_MAC_ALGO; |
499 | 0 | else if (!spec->ops->open || !spec->ops->write || !spec->ops->setkey || |
500 | 0 | !spec->ops->read || !spec->ops->verify || !spec->ops->reset) |
501 | 0 | return GPG_ERR_MAC_ALGO; |
502 | | |
503 | 0 | if (secure) |
504 | 0 | h = xtrycalloc_secure (1, sizeof (*h)); |
505 | 0 | else |
506 | 0 | h = xtrycalloc (1, sizeof (*h)); |
507 | |
|
508 | 0 | if (!h) |
509 | 0 | return gpg_err_code_from_syserror (); |
510 | | |
511 | 0 | h->magic = secure ? CTX_MAC_MAGIC_SECURE : CTX_MAC_MAGIC_NORMAL; |
512 | 0 | h->spec = spec; |
513 | 0 | h->algo = algo; |
514 | 0 | h->gcry_ctx = ctx; |
515 | |
|
516 | 0 | err = h->spec->ops->open (h); |
517 | 0 | if (err) |
518 | 0 | xfree (h); |
519 | 0 | else |
520 | 0 | *hd = h; |
521 | |
|
522 | 0 | return err; |
523 | 0 | } |
524 | | |
525 | | |
526 | | static gcry_err_code_t |
527 | | mac_reset (gcry_mac_hd_t hd) |
528 | 0 | { |
529 | 0 | if (hd->spec->ops->reset) |
530 | 0 | return hd->spec->ops->reset (hd); |
531 | | |
532 | 0 | return 0; |
533 | 0 | } |
534 | | |
535 | | |
536 | | static void |
537 | | mac_close (gcry_mac_hd_t hd) |
538 | 0 | { |
539 | 0 | if (hd->spec->ops->close) |
540 | 0 | hd->spec->ops->close (hd); |
541 | |
|
542 | 0 | wipememory (hd, sizeof (*hd)); |
543 | |
|
544 | 0 | xfree (hd); |
545 | 0 | } |
546 | | |
547 | | |
548 | | static gcry_err_code_t |
549 | | mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen) |
550 | 0 | { |
551 | 0 | if (!hd->spec->ops->setkey) |
552 | 0 | return GPG_ERR_INV_ARG; |
553 | 0 | if (keylen > 0 && !key) |
554 | 0 | return GPG_ERR_INV_ARG; |
555 | | |
556 | 0 | return hd->spec->ops->setkey (hd, key, keylen); |
557 | 0 | } |
558 | | |
559 | | |
560 | | static gcry_err_code_t |
561 | | mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen) |
562 | 0 | { |
563 | 0 | if (!hd->spec->ops->setiv) |
564 | 0 | return GPG_ERR_INV_ARG; |
565 | 0 | if (ivlen > 0 && !iv) |
566 | 0 | return GPG_ERR_INV_ARG; |
567 | | |
568 | 0 | return hd->spec->ops->setiv (hd, iv, ivlen); |
569 | 0 | } |
570 | | |
571 | | |
572 | | static gcry_err_code_t |
573 | | mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen) |
574 | 0 | { |
575 | 0 | if (!hd->spec->ops->write) |
576 | 0 | return GPG_ERR_INV_ARG; |
577 | 0 | if (inlen > 0 && !inbuf) |
578 | 0 | return GPG_ERR_INV_ARG; |
579 | | |
580 | 0 | return hd->spec->ops->write (hd, inbuf, inlen); |
581 | 0 | } |
582 | | |
583 | | |
584 | | static gcry_err_code_t |
585 | | mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen) |
586 | 0 | { |
587 | 0 | if (!outbuf || !outlen || *outlen == 0 || !hd->spec->ops->read) |
588 | 0 | return GPG_ERR_INV_ARG; |
589 | | |
590 | 0 | return hd->spec->ops->read (hd, outbuf, outlen); |
591 | 0 | } |
592 | | |
593 | | |
594 | | static gcry_err_code_t |
595 | | mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen) |
596 | 0 | { |
597 | 0 | if (!buf || buflen == 0 || !hd->spec->ops->verify) |
598 | 0 | return GPG_ERR_INV_ARG; |
599 | | |
600 | 0 | return hd->spec->ops->verify (hd, buf, buflen); |
601 | 0 | } |
602 | | |
603 | | |
604 | | /* Create a MAC object for algorithm ALGO. FLAGS may be |
605 | | given as an bitwise OR of the gcry_mac_flags values. |
606 | | H is guaranteed to be a valid handle or NULL on error. */ |
607 | | gpg_err_code_t |
608 | | _gcry_mac_open (gcry_mac_hd_t * h, int algo, unsigned int flags, |
609 | | gcry_ctx_t ctx) |
610 | 0 | { |
611 | 0 | gcry_err_code_t rc; |
612 | 0 | gcry_mac_hd_t hd = NULL; |
613 | |
|
614 | 0 | if ((flags & ~GCRY_MAC_FLAG_SECURE)) |
615 | 0 | rc = GPG_ERR_INV_ARG; |
616 | 0 | else |
617 | 0 | rc = mac_open (&hd, algo, !!(flags & GCRY_MAC_FLAG_SECURE), ctx); |
618 | |
|
619 | 0 | *h = rc ? NULL : hd; |
620 | 0 | return rc; |
621 | 0 | } |
622 | | |
623 | | |
624 | | void |
625 | | _gcry_mac_close (gcry_mac_hd_t hd) |
626 | 0 | { |
627 | 0 | if (hd) |
628 | 0 | mac_close (hd); |
629 | 0 | } |
630 | | |
631 | | |
632 | | gcry_err_code_t |
633 | | _gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen) |
634 | 0 | { |
635 | 0 | return mac_setkey (hd, key, keylen); |
636 | 0 | } |
637 | | |
638 | | |
639 | | gcry_err_code_t |
640 | | _gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen) |
641 | 0 | { |
642 | 0 | return mac_setiv (hd, iv, ivlen); |
643 | 0 | } |
644 | | |
645 | | |
646 | | gcry_err_code_t |
647 | | _gcry_mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen) |
648 | 0 | { |
649 | 0 | return mac_write (hd, inbuf, inlen); |
650 | 0 | } |
651 | | |
652 | | |
653 | | gcry_err_code_t |
654 | | _gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen) |
655 | 0 | { |
656 | 0 | return mac_read (hd, outbuf, outlen); |
657 | 0 | } |
658 | | |
659 | | |
660 | | gcry_err_code_t |
661 | | _gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen) |
662 | 0 | { |
663 | 0 | return mac_verify (hd, buf, buflen); |
664 | 0 | } |
665 | | |
666 | | |
667 | | int |
668 | | _gcry_mac_get_algo (gcry_mac_hd_t hd) |
669 | 0 | { |
670 | 0 | return hd->algo; |
671 | 0 | } |
672 | | |
673 | | |
674 | | unsigned int |
675 | | _gcry_mac_get_algo_maclen (int algo) |
676 | 0 | { |
677 | 0 | const gcry_mac_spec_t *spec; |
678 | |
|
679 | 0 | spec = spec_from_algo (algo); |
680 | 0 | if (!spec || !spec->ops || !spec->ops->get_maclen) |
681 | 0 | return 0; |
682 | | |
683 | 0 | return spec->ops->get_maclen (algo); |
684 | 0 | } |
685 | | |
686 | | |
687 | | unsigned int |
688 | | _gcry_mac_get_algo_keylen (int algo) |
689 | 0 | { |
690 | 0 | const gcry_mac_spec_t *spec; |
691 | |
|
692 | 0 | spec = spec_from_algo (algo); |
693 | 0 | if (!spec || !spec->ops || !spec->ops->get_keylen) |
694 | 0 | return 0; |
695 | | |
696 | 0 | return spec->ops->get_keylen (algo); |
697 | 0 | } |
698 | | |
699 | | |
700 | | gcry_err_code_t |
701 | | _gcry_mac_ctl (gcry_mac_hd_t hd, int cmd, void *buffer, size_t buflen) |
702 | 0 | { |
703 | 0 | gcry_err_code_t rc; |
704 | | |
705 | | /* Currently not used. */ |
706 | 0 | (void) hd; |
707 | 0 | (void) buffer; |
708 | 0 | (void) buflen; |
709 | |
|
710 | 0 | switch (cmd) |
711 | 0 | { |
712 | 0 | case GCRYCTL_RESET: |
713 | 0 | rc = mac_reset (hd); |
714 | 0 | break; |
715 | 0 | case GCRYCTL_SET_SBOX: |
716 | 0 | if (hd->spec->ops->set_extra_info) |
717 | 0 | rc = hd->spec->ops->set_extra_info |
718 | 0 | (hd, GCRYCTL_SET_SBOX, buffer, buflen); |
719 | 0 | else |
720 | 0 | rc = GPG_ERR_NOT_SUPPORTED; |
721 | 0 | break; |
722 | 0 | default: |
723 | 0 | rc = GPG_ERR_INV_OP; |
724 | 0 | } |
725 | 0 | return rc; |
726 | 0 | } |
727 | | |
728 | | |
729 | | /* Return information about the given MAC algorithm ALGO. |
730 | | |
731 | | GCRYCTL_TEST_ALGO: |
732 | | Returns 0 if the specified algorithm ALGO is available for use. |
733 | | BUFFER and NBYTES must be zero. |
734 | | |
735 | | Note: Because this function is in most cases used to return an |
736 | | integer value, we can make it easier for the caller to just look at |
737 | | the return value. The caller will in all cases consult the value |
738 | | and thereby detecting whether a error occurred or not (i.e. while |
739 | | checking the block size) |
740 | | */ |
741 | | gcry_err_code_t |
742 | | _gcry_mac_algo_info (int algo, int what, void *buffer, size_t * nbytes) |
743 | 0 | { |
744 | 0 | gcry_err_code_t rc = 0; |
745 | 0 | unsigned int ui; |
746 | |
|
747 | 0 | switch (what) |
748 | 0 | { |
749 | 0 | case GCRYCTL_GET_KEYLEN: |
750 | 0 | if (buffer || (!nbytes)) |
751 | 0 | rc = GPG_ERR_INV_ARG; |
752 | 0 | else |
753 | 0 | { |
754 | 0 | ui = _gcry_mac_get_algo_keylen (algo); |
755 | 0 | if (ui > 0) |
756 | 0 | *nbytes = (size_t) ui; |
757 | 0 | else |
758 | | /* The only reason for an error is an invalid algo. */ |
759 | 0 | rc = GPG_ERR_MAC_ALGO; |
760 | 0 | } |
761 | 0 | break; |
762 | 0 | case GCRYCTL_TEST_ALGO: |
763 | 0 | if (buffer || nbytes) |
764 | 0 | rc = GPG_ERR_INV_ARG; |
765 | 0 | else |
766 | 0 | rc = check_mac_algo (algo); |
767 | 0 | break; |
768 | | |
769 | 0 | default: |
770 | 0 | rc = GPG_ERR_INV_OP; |
771 | 0 | } |
772 | | |
773 | 0 | return rc; |
774 | 0 | } |
775 | | |
776 | | |
777 | | /* Run the self-tests for the MAC. */ |
778 | | gpg_error_t |
779 | | _gcry_mac_selftest (int algo, int extended, selftest_report_func_t report) |
780 | 0 | { |
781 | 0 | gcry_err_code_t ec; |
782 | 0 | const gcry_mac_spec_t *spec; |
783 | |
|
784 | 0 | spec = spec_from_algo (algo); |
785 | 0 | if (spec && !spec->flags.disabled |
786 | 0 | && (spec->flags.fips || !fips_mode ()) |
787 | 0 | && spec->ops && spec->ops->selftest) |
788 | 0 | ec = spec->ops->selftest (algo, extended, report); |
789 | 0 | else |
790 | 0 | { |
791 | 0 | ec = GPG_ERR_MAC_ALGO; |
792 | 0 | if (report) |
793 | 0 | report ("mac", algo, "module", |
794 | 0 | spec && !spec->flags.disabled |
795 | 0 | && (spec->flags.fips || !fips_mode ())? |
796 | 0 | "no selftest available" : |
797 | 0 | spec? "algorithm disabled" : |
798 | 0 | "algorithm not found"); |
799 | 0 | } |
800 | |
|
801 | 0 | return gpg_error (ec); |
802 | 0 | } |