Enable AMD64 SHA512 implementations for WIN64
[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_RMD160:
55       return GCRY_MD_RMD160;
56     case GCRY_MAC_HMAC_TIGER1:
57       return GCRY_MD_TIGER1;
58     case GCRY_MAC_HMAC_WHIRLPOOL:
59       return GCRY_MD_WHIRLPOOL;
60     case GCRY_MAC_HMAC_GOSTR3411_94:
61       return GCRY_MD_GOSTR3411_94;
62     case GCRY_MAC_HMAC_STRIBOG256:
63       return GCRY_MD_STRIBOG256;
64     case GCRY_MAC_HMAC_STRIBOG512:
65       return GCRY_MD_STRIBOG512;
66     }
67 }
68
69
70 static gcry_err_code_t
71 hmac_open (gcry_mac_hd_t h)
72 {
73   gcry_err_code_t err;
74   gcry_md_hd_t hd;
75   int secure = (h->magic == CTX_MAGIC_SECURE);
76   unsigned int flags;
77   int md_algo;
78
79   md_algo = map_mac_algo_to_md (h->spec->algo);
80
81   flags = GCRY_MD_FLAG_HMAC;
82   flags |= (secure ? GCRY_MD_FLAG_SECURE : 0);
83
84   err = _gcry_md_open (&hd, md_algo, flags);
85   if (err)
86     return err;
87
88   h->u.hmac.md_algo = md_algo;
89   h->u.hmac.md_ctx = hd;
90   return 0;
91 }
92
93
94 static void
95 hmac_close (gcry_mac_hd_t h)
96 {
97   _gcry_md_close (h->u.hmac.md_ctx);
98   h->u.hmac.md_ctx = NULL;
99 }
100
101
102 static gcry_err_code_t
103 hmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
104 {
105   return _gcry_md_setkey (h->u.hmac.md_ctx, key, keylen);
106 }
107
108
109 static gcry_err_code_t
110 hmac_reset (gcry_mac_hd_t h)
111 {
112   _gcry_md_reset (h->u.hmac.md_ctx);
113   return 0;
114 }
115
116
117 static gcry_err_code_t
118 hmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
119 {
120   _gcry_md_write (h->u.hmac.md_ctx, buf, buflen);
121   return 0;
122 }
123
124
125 static gcry_err_code_t
126 hmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
127 {
128   unsigned int dlen;
129   const unsigned char *digest;
130
131   dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
132   digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);
133
134   if (*outlen <= dlen)
135     buf_cpy (outbuf, digest, *outlen);
136   else
137     {
138       buf_cpy (outbuf, digest, dlen);
139       *outlen = dlen;
140     }
141
142   return 0;
143 }
144
145
146 static gcry_err_code_t
147 hmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
148 {
149   unsigned int dlen;
150   const unsigned char *digest;
151
152   dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
153   digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);
154
155   if (buflen > dlen)
156     return GPG_ERR_INV_LENGTH;
157
158   return buf_eq_const (buf, digest, buflen) ? 0 : GPG_ERR_CHECKSUM;
159 }
160
161
162 static unsigned int
163 hmac_get_maclen (int algo)
164 {
165   return _gcry_md_get_algo_dlen (map_mac_algo_to_md (algo));
166 }
167
168
169 static unsigned int
170 hmac_get_keylen (int algo)
171 {
172   /* Return blocksize for default key length. */
173   switch (algo)
174     {
175     case GCRY_MAC_HMAC_SHA384:
176     case GCRY_MAC_HMAC_SHA512:
177       return 128;
178     case GCRY_MAC_HMAC_GOSTR3411_94:
179       return 32;
180     default:
181       return 64;
182     }
183 }
184
185
186 static const gcry_mac_spec_ops_t hmac_ops = {
187   hmac_open,
188   hmac_close,
189   hmac_setkey,
190   NULL,
191   hmac_reset,
192   hmac_write,
193   hmac_read,
194   hmac_verify,
195   hmac_get_maclen,
196   hmac_get_keylen
197 };
198
199
200 #if USE_SHA1
201 gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha1 = {
202   GCRY_MAC_HMAC_SHA1, {0, 1}, "HMAC_SHA1",
203   &hmac_ops
204 };
205 #endif
206 #if USE_SHA256
207 gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha256 = {
208   GCRY_MAC_HMAC_SHA256, {0, 1}, "HMAC_SHA256",
209   &hmac_ops
210 };
211
212 gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha224 = {
213   GCRY_MAC_HMAC_SHA224, {0, 1}, "HMAC_SHA224",
214   &hmac_ops
215 };
216 #endif
217 #if USE_SHA512
218 gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512 = {
219   GCRY_MAC_HMAC_SHA512, {0, 1}, "HMAC_SHA512",
220   &hmac_ops
221 };
222
223 gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha384 = {
224   GCRY_MAC_HMAC_SHA384, {0, 1}, "HMAC_SHA384",
225   &hmac_ops
226 };
227 #endif
228 #ifdef USE_GOST_R_3411_94
229 gcry_mac_spec_t _gcry_mac_type_spec_hmac_gost3411_94 = {
230   GCRY_MAC_HMAC_GOSTR3411_94, {0, 0}, "HMAC_GOSTR3411_94",
231   &hmac_ops
232 };
233 #endif
234 #ifdef USE_GOST_R_3411_12
235 gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog256 = {
236   GCRY_MAC_HMAC_STRIBOG256, {0, 0}, "HMAC_STRIBOG256",
237   &hmac_ops
238 };
239
240 gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog512 = {
241   GCRY_MAC_HMAC_STRIBOG512, {0, 0}, "HMAC_STRIBOG512",
242   &hmac_ops
243 };
244 #endif
245 #if USE_WHIRLPOOL
246 gcry_mac_spec_t _gcry_mac_type_spec_hmac_whirlpool = {
247   GCRY_MAC_HMAC_WHIRLPOOL, {0, 0}, "HMAC_WHIRLPOOL",
248   &hmac_ops
249 };
250 #endif
251 #if USE_RMD160
252 gcry_mac_spec_t _gcry_mac_type_spec_hmac_rmd160 = {
253   GCRY_MAC_HMAC_RMD160, {0, 0}, "HMAC_RIPEMD160",
254   &hmac_ops
255 };
256 #endif
257 #if USE_TIGER
258 gcry_mac_spec_t _gcry_mac_type_spec_hmac_tiger1 = {
259   GCRY_MAC_HMAC_TIGER1, {0, 0}, "HMAC_TIGER",
260   &hmac_ops
261 };
262 #endif
263 #if USE_MD5
264 gcry_mac_spec_t _gcry_mac_type_spec_hmac_md5 = {
265   GCRY_MAC_HMAC_MD5, {0, 0}, "HMAC_MD5",
266   &hmac_ops
267 };
268 #endif
269 #if USE_MD4
270 gcry_mac_spec_t _gcry_mac_type_spec_hmac_md4 = {
271   GCRY_MAC_HMAC_MD4, {0, 0}, "HMAC_MD4",
272   &hmac_ops
273 };
274 #endif
275 #if USE_MD2
276 gcry_mac_spec_t _gcry_mac_type_spec_hmac_md2 = {
277   GCRY_MAC_HMAC_MD2, {0, 0}, "HMAC_MD2",
278   &hmac_ops
279 };
280 #endif