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