Tizen 2.0 Release
[external/libgnutls26.git] / lib / nettle / mac.c
1 /*
2  * Copyright (C) 2008, 2010 Free Software Foundation, Inc.
3  *
4  * Author: Nikos Mavrogiannopoulos
5  *
6  * This file is part of GNUTLS.
7  *
8  * The GNUTLS library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
21  * USA
22  *
23  */
24
25 /* This file provides is the backend hash/mac API for libgcrypt.
26  */
27
28 #include <gnutls_int.h>
29 #include <gnutls_hash_int.h>
30 #include <gnutls_errors.h>
31 #include <nettle/md5.h>
32 #include <nettle/md2.h>
33 #include <nettle/sha.h>
34 #include <nettle/hmac.h>
35
36 typedef void (*update_func) (void *, unsigned, const uint8_t *);
37 typedef void (*digest_func) (void *, unsigned, uint8_t *);
38 typedef void (*set_key_func) (void *, unsigned, const uint8_t *);
39
40 static int wrap_nettle_hash_init (gnutls_mac_algorithm_t algo, void **_ctx);
41
42 struct nettle_hash_ctx
43 {
44   union
45   {
46     struct md5_ctx md5;
47     struct md2_ctx md2;
48     struct sha224_ctx sha224;
49     struct sha256_ctx sha256;
50     struct sha384_ctx sha384;
51     struct sha512_ctx sha512;
52     struct sha1_ctx sha1;
53   } ctx;
54   void *ctx_ptr;
55   gnutls_mac_algorithm_t algo;
56   size_t length;
57   update_func update;
58   digest_func digest;
59 };
60
61 struct nettle_hmac_ctx
62 {
63   union
64   {
65     struct hmac_md5_ctx md5;
66     struct hmac_sha224_ctx sha224;
67     struct hmac_sha256_ctx sha256;
68     struct hmac_sha384_ctx sha384;
69     struct hmac_sha512_ctx sha512;
70     struct hmac_sha1_ctx sha1;
71   } ctx;
72   void *ctx_ptr;
73   gnutls_mac_algorithm_t algo;
74   size_t length;
75   update_func update;
76   digest_func digest;
77   set_key_func setkey;
78 };
79
80 static int
81 wrap_nettle_hmac_init (gnutls_mac_algorithm_t algo, void **_ctx)
82 {
83   struct nettle_hmac_ctx *ctx;
84
85   ctx = gnutls_malloc (sizeof (struct nettle_hmac_ctx));
86   if (ctx == NULL)
87     {
88       gnutls_assert ();
89       return GNUTLS_E_MEMORY_ERROR;
90     }
91
92   ctx->algo = algo;
93
94   switch (algo)
95     {
96     case GNUTLS_MAC_MD5:
97       ctx->update = (update_func) hmac_md5_update;
98       ctx->digest = (digest_func) hmac_md5_digest;
99       ctx->setkey = (set_key_func) hmac_md5_set_key;
100       ctx->ctx_ptr = &ctx->ctx.md5;
101       ctx->length = MD5_DIGEST_SIZE;
102       break;
103     case GNUTLS_MAC_SHA1:
104       ctx->update = (update_func) hmac_sha1_update;
105       ctx->digest = (digest_func) hmac_sha1_digest;
106       ctx->setkey = (set_key_func) hmac_sha1_set_key;
107       ctx->ctx_ptr = &ctx->ctx.sha1;
108       ctx->length = SHA1_DIGEST_SIZE;
109       break;
110     case GNUTLS_MAC_SHA224:
111       ctx->update = (update_func) hmac_sha224_update;
112       ctx->digest = (digest_func) hmac_sha224_digest;
113       ctx->setkey = (set_key_func) hmac_sha224_set_key;
114       ctx->ctx_ptr = &ctx->ctx.sha224;
115       ctx->length = SHA224_DIGEST_SIZE;
116       break;
117     case GNUTLS_MAC_SHA256:
118       ctx->update = (update_func) hmac_sha256_update;
119       ctx->digest = (digest_func) hmac_sha256_digest;
120       ctx->setkey = (set_key_func) hmac_sha256_set_key;
121       ctx->ctx_ptr = &ctx->ctx.sha256;
122       ctx->length = SHA256_DIGEST_SIZE;
123       break;
124     case GNUTLS_MAC_SHA384:
125       ctx->update = (update_func) hmac_sha384_update;
126       ctx->digest = (digest_func) hmac_sha384_digest;
127       ctx->setkey = (set_key_func) hmac_sha384_set_key;
128       ctx->ctx_ptr = &ctx->ctx.sha384;
129       ctx->length = SHA384_DIGEST_SIZE;
130       break;
131     case GNUTLS_MAC_SHA512:
132       ctx->update = (update_func) hmac_sha512_update;
133       ctx->digest = (digest_func) hmac_sha512_digest;
134       ctx->setkey = (set_key_func) hmac_sha512_set_key;
135       ctx->ctx_ptr = &ctx->ctx.sha512;
136       ctx->length = SHA512_DIGEST_SIZE;
137       break;
138     default:
139       gnutls_assert ();
140       return GNUTLS_E_INVALID_REQUEST;
141     }
142
143   *_ctx = ctx;
144
145   return 0;
146 }
147
148 static int
149 wrap_nettle_hmac_setkey (void *_ctx, const void *key, size_t keylen)
150 {
151   struct nettle_hmac_ctx *ctx = _ctx;
152
153   ctx->setkey (ctx->ctx_ptr, keylen, key);
154
155   return GNUTLS_E_SUCCESS;
156 }
157
158 static int
159 wrap_nettle_hmac_update (void *_ctx, const void *text, size_t textsize)
160 {
161   struct nettle_hmac_ctx *ctx = _ctx;
162
163   ctx->update (ctx->ctx_ptr, textsize, text);
164
165   return GNUTLS_E_SUCCESS;
166 }
167
168 static int
169 wrap_nettle_hash_update (void *_ctx, const void *text, size_t textsize)
170 {
171   struct nettle_hash_ctx *ctx = _ctx;
172
173   ctx->update (ctx->ctx_ptr, textsize, text);
174
175   return GNUTLS_E_SUCCESS;
176 }
177
178 static int
179 wrap_nettle_hash_copy (void **bhd, void *ahd)
180 {
181   struct nettle_hash_ctx *ctx = ahd;
182   struct nettle_hash_ctx *dst_ctx;
183   int ret;
184
185   ret = wrap_nettle_hash_init (ctx->algo, bhd);
186   if (ret < 0)
187     {
188       gnutls_assert ();
189       return ret;
190     }
191
192   dst_ctx = *bhd;
193
194   memcpy (&dst_ctx->ctx, &ctx->ctx, sizeof (ctx->ctx));
195
196   return 0;
197 }
198
199 static void
200 wrap_nettle_md_close (void *hd)
201 {
202   gnutls_free (hd);
203 }
204
205 static int
206 wrap_nettle_hash_init (gnutls_mac_algorithm_t algo, void **_ctx)
207 {
208   struct nettle_hash_ctx *ctx;
209
210   ctx = gnutls_malloc (sizeof (struct nettle_hash_ctx));
211   if (ctx == NULL)
212     {
213       gnutls_assert ();
214       return GNUTLS_E_MEMORY_ERROR;
215     }
216
217   ctx->algo = algo;
218
219   switch (algo)
220     {
221     case GNUTLS_DIG_MD5:
222       md5_init (&ctx->ctx.md5);
223       ctx->update = (update_func) md5_update;
224       ctx->digest = (digest_func) md5_digest;
225       ctx->ctx_ptr = &ctx->ctx.md5;
226       ctx->length = MD5_DIGEST_SIZE;
227       break;
228     case GNUTLS_DIG_SHA1:
229       sha1_init (&ctx->ctx.sha1);
230       ctx->update = (update_func) sha1_update;
231       ctx->digest = (digest_func) sha1_digest;
232       ctx->ctx_ptr = &ctx->ctx.sha1;
233       ctx->length = SHA1_DIGEST_SIZE;
234       break;
235     case GNUTLS_DIG_MD2:
236       md2_init (&ctx->ctx.md2);
237       ctx->update = (update_func) md2_update;
238       ctx->digest = (digest_func) md2_digest;
239       ctx->ctx_ptr = &ctx->ctx.md2;
240       ctx->length = MD2_DIGEST_SIZE;
241       break;
242     case GNUTLS_DIG_SHA224:
243       sha224_init (&ctx->ctx.sha224);
244       ctx->update = (update_func) sha224_update;
245       ctx->digest = (digest_func) sha224_digest;
246       ctx->ctx_ptr = &ctx->ctx.sha224;
247       ctx->length = SHA224_DIGEST_SIZE;
248       break;
249     case GNUTLS_DIG_SHA256:
250       sha256_init (&ctx->ctx.sha256);
251       ctx->update = (update_func) sha256_update;
252       ctx->digest = (digest_func) sha256_digest;
253       ctx->ctx_ptr = &ctx->ctx.sha256;
254       ctx->length = SHA256_DIGEST_SIZE;
255       break;
256     case GNUTLS_DIG_SHA384:
257       sha384_init (&ctx->ctx.sha384);
258       ctx->update = (update_func) sha384_update;
259       ctx->digest = (digest_func) sha384_digest;
260       ctx->ctx_ptr = &ctx->ctx.sha384;
261       ctx->length = SHA384_DIGEST_SIZE;
262       break;
263     case GNUTLS_DIG_SHA512:
264       sha512_init (&ctx->ctx.sha512);
265       ctx->update = (update_func) sha512_update;
266       ctx->digest = (digest_func) sha512_digest;
267       ctx->ctx_ptr = &ctx->ctx.sha512;
268       ctx->length = SHA512_DIGEST_SIZE;
269       break;
270     default:
271       gnutls_assert ();
272       return GNUTLS_E_INVALID_REQUEST;
273     }
274
275   *_ctx = ctx;
276
277   return 0;
278 }
279
280 static int
281 wrap_nettle_hash_output (void *src_ctx, void *digest, size_t digestsize)
282 {
283   struct nettle_hash_ctx *ctx;
284   ctx = src_ctx;
285
286   if (digestsize < ctx->length)
287     {
288       gnutls_assert ();
289       return GNUTLS_E_SHORT_MEMORY_BUFFER;
290     }
291
292   ctx->digest (ctx->ctx_ptr, digestsize, digest);
293
294   return 0;
295 }
296
297 static int
298 wrap_nettle_hmac_output (void *src_ctx, void *digest, size_t digestsize)
299 {
300   struct nettle_hmac_ctx *ctx;
301   ctx = src_ctx;
302
303   if (digestsize < ctx->length)
304     {
305       gnutls_assert ();
306       return GNUTLS_E_SHORT_MEMORY_BUFFER;
307     }
308
309   ctx->digest (ctx->ctx_ptr, digestsize, digest);
310
311   return 0;
312 }
313
314 gnutls_crypto_mac_st _gnutls_mac_ops = {
315   .init = wrap_nettle_hmac_init,
316   .setkey = wrap_nettle_hmac_setkey,
317   .hash = wrap_nettle_hmac_update,
318   .output = wrap_nettle_hmac_output,
319   .deinit = wrap_nettle_md_close,
320 };
321
322 gnutls_crypto_digest_st _gnutls_digest_ops = {
323   .init = wrap_nettle_hash_init,
324   .hash = wrap_nettle_hash_update,
325   .copy = wrap_nettle_hash_copy,
326   .output = wrap_nettle_hash_output,
327   .deinit = wrap_nettle_md_close,
328 };