Line data Source code
1 : /* mac-hmac.c - HMAC glue for MAC API
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 : #include "bufhelp.h"
29 :
30 :
31 : static int
32 0 : map_mac_algo_to_md (int mac_algo)
33 : {
34 0 : switch (mac_algo)
35 : {
36 : default:
37 0 : return GCRY_MD_NONE;
38 : case GCRY_MAC_HMAC_MD2:
39 0 : return GCRY_MD_MD2;
40 : case GCRY_MAC_HMAC_MD4:
41 0 : return GCRY_MD_MD4;
42 : case GCRY_MAC_HMAC_MD5:
43 0 : return GCRY_MD_MD5;
44 : case GCRY_MAC_HMAC_SHA1:
45 0 : return GCRY_MD_SHA1;
46 : case GCRY_MAC_HMAC_SHA224:
47 0 : return GCRY_MD_SHA224;
48 : case GCRY_MAC_HMAC_SHA256:
49 0 : return GCRY_MD_SHA256;
50 : case GCRY_MAC_HMAC_SHA384:
51 0 : return GCRY_MD_SHA384;
52 : case GCRY_MAC_HMAC_SHA512:
53 0 : return GCRY_MD_SHA512;
54 : case GCRY_MAC_HMAC_SHA3_224:
55 0 : return GCRY_MD_SHA3_224;
56 : case GCRY_MAC_HMAC_SHA3_256:
57 0 : return GCRY_MD_SHA3_256;
58 : case GCRY_MAC_HMAC_SHA3_384:
59 0 : return GCRY_MD_SHA3_384;
60 : case GCRY_MAC_HMAC_SHA3_512:
61 0 : return GCRY_MD_SHA3_512;
62 : case GCRY_MAC_HMAC_RMD160:
63 0 : return GCRY_MD_RMD160;
64 : case GCRY_MAC_HMAC_TIGER1:
65 0 : return GCRY_MD_TIGER1;
66 : case GCRY_MAC_HMAC_WHIRLPOOL:
67 0 : return GCRY_MD_WHIRLPOOL;
68 : case GCRY_MAC_HMAC_GOSTR3411_94:
69 0 : return GCRY_MD_GOSTR3411_94;
70 : case GCRY_MAC_HMAC_STRIBOG256:
71 0 : return GCRY_MD_STRIBOG256;
72 : case GCRY_MAC_HMAC_STRIBOG512:
73 0 : return GCRY_MD_STRIBOG512;
74 : }
75 : }
76 :
77 :
78 : static gcry_err_code_t
79 0 : hmac_open (gcry_mac_hd_t h)
80 : {
81 : gcry_err_code_t err;
82 : gcry_md_hd_t hd;
83 0 : int secure = (h->magic == CTX_MAGIC_SECURE);
84 : unsigned int flags;
85 : int md_algo;
86 :
87 0 : md_algo = map_mac_algo_to_md (h->spec->algo);
88 :
89 0 : flags = GCRY_MD_FLAG_HMAC;
90 0 : flags |= (secure ? GCRY_MD_FLAG_SECURE : 0);
91 :
92 0 : err = _gcry_md_open (&hd, md_algo, flags);
93 0 : if (err)
94 0 : return err;
95 :
96 0 : h->u.hmac.md_algo = md_algo;
97 0 : h->u.hmac.md_ctx = hd;
98 0 : return 0;
99 : }
100 :
101 :
102 : static void
103 0 : hmac_close (gcry_mac_hd_t h)
104 : {
105 0 : _gcry_md_close (h->u.hmac.md_ctx);
106 0 : h->u.hmac.md_ctx = NULL;
107 0 : }
108 :
109 :
110 : static gcry_err_code_t
111 0 : hmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
112 : {
113 0 : return _gcry_md_setkey (h->u.hmac.md_ctx, key, keylen);
114 : }
115 :
116 :
117 : static gcry_err_code_t
118 0 : hmac_reset (gcry_mac_hd_t h)
119 : {
120 0 : _gcry_md_reset (h->u.hmac.md_ctx);
121 0 : return 0;
122 : }
123 :
124 :
125 : static gcry_err_code_t
126 0 : hmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
127 : {
128 0 : _gcry_md_write (h->u.hmac.md_ctx, buf, buflen);
129 0 : return 0;
130 : }
131 :
132 :
133 : static gcry_err_code_t
134 0 : hmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
135 : {
136 : unsigned int dlen;
137 : const unsigned char *digest;
138 :
139 0 : dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
140 0 : digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);
141 :
142 0 : if (*outlen <= dlen)
143 0 : buf_cpy (outbuf, digest, *outlen);
144 : else
145 : {
146 0 : buf_cpy (outbuf, digest, dlen);
147 0 : *outlen = dlen;
148 : }
149 :
150 0 : return 0;
151 : }
152 :
153 :
154 : static gcry_err_code_t
155 0 : hmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
156 : {
157 : unsigned int dlen;
158 : const unsigned char *digest;
159 :
160 0 : dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
161 0 : digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);
162 :
163 0 : if (buflen > dlen)
164 0 : return GPG_ERR_INV_LENGTH;
165 :
166 0 : return buf_eq_const (buf, digest, buflen) ? 0 : GPG_ERR_CHECKSUM;
167 : }
168 :
169 :
170 : static unsigned int
171 0 : hmac_get_maclen (int algo)
172 : {
173 0 : return _gcry_md_get_algo_dlen (map_mac_algo_to_md (algo));
174 : }
175 :
176 :
177 : static unsigned int
178 0 : hmac_get_keylen (int algo)
179 : {
180 : /* Return blocksize for default key length. */
181 0 : switch (algo)
182 : {
183 : case GCRY_MD_SHA3_224:
184 0 : return 1152 / 8;
185 : case GCRY_MD_SHA3_256:
186 0 : return 1088 / 8;
187 : case GCRY_MD_SHA3_384:
188 0 : return 832 / 8;
189 : case GCRY_MD_SHA3_512:
190 0 : return 576 / 8;
191 : case GCRY_MAC_HMAC_SHA384:
192 : case GCRY_MAC_HMAC_SHA512:
193 0 : return 128;
194 : case GCRY_MAC_HMAC_GOSTR3411_94:
195 0 : return 32;
196 : default:
197 0 : return 64;
198 : }
199 : }
200 :
201 :
202 : static const gcry_mac_spec_ops_t hmac_ops = {
203 : hmac_open,
204 : hmac_close,
205 : hmac_setkey,
206 : NULL,
207 : hmac_reset,
208 : hmac_write,
209 : hmac_read,
210 : hmac_verify,
211 : hmac_get_maclen,
212 : hmac_get_keylen
213 : };
214 :
215 :
216 : #if USE_SHA1
217 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha1 = {
218 : GCRY_MAC_HMAC_SHA1, {0, 1}, "HMAC_SHA1",
219 : &hmac_ops
220 : };
221 : #endif
222 : #if USE_SHA256
223 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha256 = {
224 : GCRY_MAC_HMAC_SHA256, {0, 1}, "HMAC_SHA256",
225 : &hmac_ops
226 : };
227 :
228 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha224 = {
229 : GCRY_MAC_HMAC_SHA224, {0, 1}, "HMAC_SHA224",
230 : &hmac_ops
231 : };
232 : #endif
233 : #if USE_SHA512
234 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512 = {
235 : GCRY_MAC_HMAC_SHA512, {0, 1}, "HMAC_SHA512",
236 : &hmac_ops
237 : };
238 :
239 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha384 = {
240 : GCRY_MAC_HMAC_SHA384, {0, 1}, "HMAC_SHA384",
241 : &hmac_ops
242 : };
243 : #endif
244 : #if USE_SHA3
245 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_224 = {
246 : GCRY_MAC_HMAC_SHA3_224, {0, 1}, "HMAC_SHA3_224",
247 : &hmac_ops
248 : };
249 :
250 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_256 = {
251 : GCRY_MAC_HMAC_SHA3_256, {0, 1}, "HMAC_SHA3_256",
252 : &hmac_ops
253 : };
254 :
255 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_384 = {
256 : GCRY_MAC_HMAC_SHA3_384, {0, 1}, "HMAC_SHA3_384",
257 : &hmac_ops
258 : };
259 :
260 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha3_512 = {
261 : GCRY_MAC_HMAC_SHA3_512, {0, 1}, "HMAC_SHA3_512",
262 : &hmac_ops
263 : };
264 : #endif
265 : #ifdef USE_GOST_R_3411_94
266 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_gost3411_94 = {
267 : GCRY_MAC_HMAC_GOSTR3411_94, {0, 0}, "HMAC_GOSTR3411_94",
268 : &hmac_ops
269 : };
270 : #endif
271 : #ifdef USE_GOST_R_3411_12
272 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog256 = {
273 : GCRY_MAC_HMAC_STRIBOG256, {0, 0}, "HMAC_STRIBOG256",
274 : &hmac_ops
275 : };
276 :
277 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog512 = {
278 : GCRY_MAC_HMAC_STRIBOG512, {0, 0}, "HMAC_STRIBOG512",
279 : &hmac_ops
280 : };
281 : #endif
282 : #if USE_WHIRLPOOL
283 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_whirlpool = {
284 : GCRY_MAC_HMAC_WHIRLPOOL, {0, 0}, "HMAC_WHIRLPOOL",
285 : &hmac_ops
286 : };
287 : #endif
288 : #if USE_RMD160
289 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_rmd160 = {
290 : GCRY_MAC_HMAC_RMD160, {0, 0}, "HMAC_RIPEMD160",
291 : &hmac_ops
292 : };
293 : #endif
294 : #if USE_TIGER
295 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_tiger1 = {
296 : GCRY_MAC_HMAC_TIGER1, {0, 0}, "HMAC_TIGER",
297 : &hmac_ops
298 : };
299 : #endif
300 : #if USE_MD5
301 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_md5 = {
302 : GCRY_MAC_HMAC_MD5, {0, 0}, "HMAC_MD5",
303 : &hmac_ops
304 : };
305 : #endif
306 : #if USE_MD4
307 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_md4 = {
308 : GCRY_MAC_HMAC_MD4, {0, 0}, "HMAC_MD4",
309 : &hmac_ops
310 : };
311 : #endif
312 : #if USE_MD2
313 : gcry_mac_spec_t _gcry_mac_type_spec_hmac_md2 = {
314 : GCRY_MAC_HMAC_MD2, {0, 0}, "HMAC_MD2",
315 : &hmac_ops
316 : };
317 : #endif
|