Add generic SHA3 implementation
[libgcrypt.git] / cipher / mac-hmac.c
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 map_mac_algo_to_md (int mac_algo)
33 {
34   switch (mac_algo)
35     {
36     default:
37       return GCRY_MD_NONE;
38     case GCRY_MAC_HMAC_MD2:
39       return GCRY_MD_MD2;
40     case GCRY_MAC_HMAC_MD4:
41       return GCRY_MD_MD4;
42     case GCRY_MAC_HMAC_MD5:
43       return GCRY_MD_MD5;
44     case GCRY_MAC_HMAC_SHA1:
45       return GCRY_MD_SHA1;
46     case GCRY_MAC_HMAC_SHA224:
47       return GCRY_MD_SHA224;
48     case GCRY_MAC_HMAC_SHA256:
49       return GCRY_MD_SHA256;
50     case GCRY_MAC_HMAC_SHA384:
51       return GCRY_MD_SHA384;
52     case GCRY_MAC_HMAC_SHA512:
53       return GCRY_MD_SHA512;
54     case GCRY_MAC_HMAC_SHA3_224:
55       return GCRY_MD_SHA3_224;
56     case GCRY_MAC_HMAC_SHA3_256:
57       return GCRY_MD_SHA3_256;
58     case GCRY_MAC_HMAC_SHA3_384:
59       return GCRY_MD_SHA3_384;
60     case GCRY_MAC_HMAC_SHA3_512:
61       return GCRY_MD_SHA3_512;
62     case GCRY_MAC_HMAC_RMD160:
63       return GCRY_MD_RMD160;
64     case GCRY_MAC_HMAC_TIGER1:
65       return GCRY_MD_TIGER1;
66     case GCRY_MAC_HMAC_WHIRLPOOL:
67       return GCRY_MD_WHIRLPOOL;
68     case GCRY_MAC_HMAC_GOSTR3411_94:
69       return GCRY_MD_GOSTR3411_94;
70     case GCRY_MAC_HMAC_STRIBOG256:
71       return GCRY_MD_STRIBOG256;
72     case GCRY_MAC_HMAC_STRIBOG512:
73       return GCRY_MD_STRIBOG512;
74     }
75 }
76
77
78 static gcry_err_code_t
79 hmac_open (gcry_mac_hd_t h)
80 {
81   gcry_err_code_t err;
82   gcry_md_hd_t hd;
83   int secure = (h->magic == CTX_MAGIC_SECURE);
84   unsigned int flags;
85   int md_algo;
86
87   md_algo = map_mac_algo_to_md (h->spec->algo);
88
89   flags = GCRY_MD_FLAG_HMAC;
90   flags |= (secure ? GCRY_MD_FLAG_SECURE : 0);
91
92   err = _gcry_md_open (&hd, md_algo, flags);
93   if (err)
94     return err;
95
96   h->u.hmac.md_algo = md_algo;
97   h->u.hmac.md_ctx = hd;
98   return 0;
99 }
100
101
102 static void
103 hmac_close (gcry_mac_hd_t h)
104 {
105   _gcry_md_close (h->u.hmac.md_ctx);
106   h->u.hmac.md_ctx = NULL;
107 }
108
109
110 static gcry_err_code_t
111 hmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
112 {
113   return _gcry_md_setkey (h->u.hmac.md_ctx, key, keylen);
114 }
115
116
117 static gcry_err_code_t
118 hmac_reset (gcry_mac_hd_t h)
119 {
120   _gcry_md_reset (h->u.hmac.md_ctx);
121   return 0;
122 }
123
124
125 static gcry_err_code_t
126 hmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
127 {
128   _gcry_md_write (h->u.hmac.md_ctx, buf, buflen);
129   return 0;
130 }
131
132
133 static gcry_err_code_t
134 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   dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
140   digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);
141
142   if (*outlen <= dlen)
143     buf_cpy (outbuf, digest, *outlen);
144   else
145     {
146       buf_cpy (outbuf, digest, dlen);
147       *outlen = dlen;
148     }
149
150   return 0;
151 }
152
153
154 static gcry_err_code_t
155 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   dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
161   digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);
162
163   if (buflen > dlen)
164     return GPG_ERR_INV_LENGTH;
165
166   return buf_eq_const (buf, digest, buflen) ? 0 : GPG_ERR_CHECKSUM;
167 }
168
169
170 static unsigned int
171 hmac_get_maclen (int algo)
172 {
173   return _gcry_md_get_algo_dlen (map_mac_algo_to_md (algo));
174 }
175
176
177 static unsigned int
178 hmac_get_keylen (int algo)
179 {
180   /* Return blocksize for default key length. */
181   switch (algo)
182     {
183     case GCRY_MD_SHA3_224:
184       return 1152 / 8;
185     case GCRY_MD_SHA3_256:
186       return 1088 / 8;
187     case GCRY_MD_SHA3_384:
188       return 832 / 8;
189     case GCRY_MD_SHA3_512:
190       return 576 / 8;
191     case GCRY_MAC_HMAC_SHA384:
192     case GCRY_MAC_HMAC_SHA512:
193       return 128;
194     case GCRY_MAC_HMAC_GOSTR3411_94:
195       return 32;
196     default:
197       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